1f7917c00SJeff Kirsher /*
2f7917c00SJeff Kirsher  * This file is part of the Chelsio T4 Ethernet driver for Linux.
3f7917c00SJeff Kirsher  *
4b72a32daSRahul Lakkireddy  * Copyright (c) 2003-2016 Chelsio Communications, Inc. All rights reserved.
5f7917c00SJeff Kirsher  *
6f7917c00SJeff Kirsher  * This software is available to you under a choice of one of two
7f7917c00SJeff Kirsher  * licenses.  You may choose to be licensed under the terms of the GNU
8f7917c00SJeff Kirsher  * General Public License (GPL) Version 2, available from the file
9f7917c00SJeff Kirsher  * COPYING in the main directory of this source tree, or the
10f7917c00SJeff Kirsher  * OpenIB.org BSD license below:
11f7917c00SJeff Kirsher  *
12f7917c00SJeff Kirsher  *     Redistribution and use in source and binary forms, with or
13f7917c00SJeff Kirsher  *     without modification, are permitted provided that the following
14f7917c00SJeff Kirsher  *     conditions are met:
15f7917c00SJeff Kirsher  *
16f7917c00SJeff Kirsher  *      - Redistributions of source code must retain the above
17f7917c00SJeff Kirsher  *        copyright notice, this list of conditions and the following
18f7917c00SJeff Kirsher  *        disclaimer.
19f7917c00SJeff Kirsher  *
20f7917c00SJeff Kirsher  *      - Redistributions in binary form must reproduce the above
21f7917c00SJeff Kirsher  *        copyright notice, this list of conditions and the following
22f7917c00SJeff Kirsher  *        disclaimer in the documentation and/or other materials
23f7917c00SJeff Kirsher  *        provided with the distribution.
24f7917c00SJeff Kirsher  *
25f7917c00SJeff Kirsher  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26f7917c00SJeff Kirsher  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27f7917c00SJeff Kirsher  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28f7917c00SJeff Kirsher  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29f7917c00SJeff Kirsher  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30f7917c00SJeff Kirsher  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31f7917c00SJeff Kirsher  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32f7917c00SJeff Kirsher  * SOFTWARE.
33f7917c00SJeff Kirsher  */
34f7917c00SJeff Kirsher 
35f7917c00SJeff Kirsher #include <linux/delay.h>
36f7917c00SJeff Kirsher #include "cxgb4.h"
37f7917c00SJeff Kirsher #include "t4_regs.h"
38f612b815SHariprasad Shenai #include "t4_values.h"
39f7917c00SJeff Kirsher #include "t4fw_api.h"
40a69265e9SHariprasad Shenai #include "t4fw_version.h"
41f7917c00SJeff Kirsher 
42f7917c00SJeff Kirsher /**
43f7917c00SJeff Kirsher  *	t4_wait_op_done_val - wait until an operation is completed
44f7917c00SJeff Kirsher  *	@adapter: the adapter performing the operation
45f7917c00SJeff Kirsher  *	@reg: the register to check for completion
46f7917c00SJeff Kirsher  *	@mask: a single-bit field within @reg that indicates completion
47f7917c00SJeff Kirsher  *	@polarity: the value of the field when the operation is completed
48f7917c00SJeff Kirsher  *	@attempts: number of check iterations
49f7917c00SJeff Kirsher  *	@delay: delay in usecs between iterations
50f7917c00SJeff Kirsher  *	@valp: where to store the value of the register at completion time
51f7917c00SJeff Kirsher  *
52f7917c00SJeff Kirsher  *	Wait until an operation is completed by checking a bit in a register
53f7917c00SJeff Kirsher  *	up to @attempts times.  If @valp is not NULL the value of the register
54f7917c00SJeff Kirsher  *	at the time it indicated completion is stored there.  Returns 0 if the
55f7917c00SJeff Kirsher  *	operation completes and	-EAGAIN	otherwise.
56f7917c00SJeff Kirsher  */
t4_wait_op_done_val(struct adapter * adapter,int reg,u32 mask,int polarity,int attempts,int delay,u32 * valp)57f7917c00SJeff Kirsher static int t4_wait_op_done_val(struct adapter *adapter, int reg, u32 mask,
58f7917c00SJeff Kirsher 			       int polarity, int attempts, int delay, u32 *valp)
59f7917c00SJeff Kirsher {
60f7917c00SJeff Kirsher 	while (1) {
61f7917c00SJeff Kirsher 		u32 val = t4_read_reg(adapter, reg);
62f7917c00SJeff Kirsher 
63f7917c00SJeff Kirsher 		if (!!(val & mask) == polarity) {
64f7917c00SJeff Kirsher 			if (valp)
65f7917c00SJeff Kirsher 				*valp = val;
66f7917c00SJeff Kirsher 			return 0;
67f7917c00SJeff Kirsher 		}
68f7917c00SJeff Kirsher 		if (--attempts == 0)
69f7917c00SJeff Kirsher 			return -EAGAIN;
70f7917c00SJeff Kirsher 		if (delay)
71f7917c00SJeff Kirsher 			udelay(delay);
72f7917c00SJeff Kirsher 	}
73f7917c00SJeff Kirsher }
74f7917c00SJeff Kirsher 
t4_wait_op_done(struct adapter * adapter,int reg,u32 mask,int polarity,int attempts,int delay)75f7917c00SJeff Kirsher static inline int t4_wait_op_done(struct adapter *adapter, int reg, u32 mask,
76f7917c00SJeff Kirsher 				  int polarity, int attempts, int delay)
77f7917c00SJeff Kirsher {
78f7917c00SJeff Kirsher 	return t4_wait_op_done_val(adapter, reg, mask, polarity, attempts,
79f7917c00SJeff Kirsher 				   delay, NULL);
80f7917c00SJeff Kirsher }
81f7917c00SJeff Kirsher 
82f7917c00SJeff Kirsher /**
83f7917c00SJeff Kirsher  *	t4_set_reg_field - set a register field to a value
84f7917c00SJeff Kirsher  *	@adapter: the adapter to program
85f7917c00SJeff Kirsher  *	@addr: the register address
86f7917c00SJeff Kirsher  *	@mask: specifies the portion of the register to modify
87f7917c00SJeff Kirsher  *	@val: the new value for the register field
88f7917c00SJeff Kirsher  *
89f7917c00SJeff Kirsher  *	Sets a register field specified by the supplied mask to the
90f7917c00SJeff Kirsher  *	given value.
91f7917c00SJeff Kirsher  */
t4_set_reg_field(struct adapter * adapter,unsigned int addr,u32 mask,u32 val)92f7917c00SJeff Kirsher void t4_set_reg_field(struct adapter *adapter, unsigned int addr, u32 mask,
93f7917c00SJeff Kirsher 		      u32 val)
94f7917c00SJeff Kirsher {
95f7917c00SJeff Kirsher 	u32 v = t4_read_reg(adapter, addr) & ~mask;
96f7917c00SJeff Kirsher 
97f7917c00SJeff Kirsher 	t4_write_reg(adapter, addr, v | val);
98f7917c00SJeff Kirsher 	(void) t4_read_reg(adapter, addr);      /* flush */
99f7917c00SJeff Kirsher }
100f7917c00SJeff Kirsher 
101f7917c00SJeff Kirsher /**
102f7917c00SJeff Kirsher  *	t4_read_indirect - read indirectly addressed registers
103f7917c00SJeff Kirsher  *	@adap: the adapter
104f7917c00SJeff Kirsher  *	@addr_reg: register holding the indirect address
105f7917c00SJeff Kirsher  *	@data_reg: register holding the value of the indirect register
106f7917c00SJeff Kirsher  *	@vals: where the read register values are stored
107f7917c00SJeff Kirsher  *	@nregs: how many indirect registers to read
108f7917c00SJeff Kirsher  *	@start_idx: index of first indirect register to read
109f7917c00SJeff Kirsher  *
110f7917c00SJeff Kirsher  *	Reads registers that are accessed indirectly through an address/data
111f7917c00SJeff Kirsher  *	register pair.
112f7917c00SJeff Kirsher  */
t4_read_indirect(struct adapter * adap,unsigned int addr_reg,unsigned int data_reg,u32 * vals,unsigned int nregs,unsigned int start_idx)113f2b7e78dSVipul Pandya void t4_read_indirect(struct adapter *adap, unsigned int addr_reg,
114f7917c00SJeff Kirsher 			     unsigned int data_reg, u32 *vals,
115f7917c00SJeff Kirsher 			     unsigned int nregs, unsigned int start_idx)
116f7917c00SJeff Kirsher {
117f7917c00SJeff Kirsher 	while (nregs--) {
118f7917c00SJeff Kirsher 		t4_write_reg(adap, addr_reg, start_idx);
119f7917c00SJeff Kirsher 		*vals++ = t4_read_reg(adap, data_reg);
120f7917c00SJeff Kirsher 		start_idx++;
121f7917c00SJeff Kirsher 	}
122f7917c00SJeff Kirsher }
123f7917c00SJeff Kirsher 
12413ee15d3SVipul Pandya /**
12513ee15d3SVipul Pandya  *	t4_write_indirect - write indirectly addressed registers
12613ee15d3SVipul Pandya  *	@adap: the adapter
12713ee15d3SVipul Pandya  *	@addr_reg: register holding the indirect addresses
12813ee15d3SVipul Pandya  *	@data_reg: register holding the value for the indirect registers
12913ee15d3SVipul Pandya  *	@vals: values to write
13013ee15d3SVipul Pandya  *	@nregs: how many indirect registers to write
13113ee15d3SVipul Pandya  *	@start_idx: address of first indirect register to write
13213ee15d3SVipul Pandya  *
13313ee15d3SVipul Pandya  *	Writes a sequential block of registers that are accessed indirectly
13413ee15d3SVipul Pandya  *	through an address/data register pair.
13513ee15d3SVipul Pandya  */
t4_write_indirect(struct adapter * adap,unsigned int addr_reg,unsigned int data_reg,const u32 * vals,unsigned int nregs,unsigned int start_idx)13613ee15d3SVipul Pandya void t4_write_indirect(struct adapter *adap, unsigned int addr_reg,
13713ee15d3SVipul Pandya 		       unsigned int data_reg, const u32 *vals,
13813ee15d3SVipul Pandya 		       unsigned int nregs, unsigned int start_idx)
13913ee15d3SVipul Pandya {
14013ee15d3SVipul Pandya 	while (nregs--) {
14113ee15d3SVipul Pandya 		t4_write_reg(adap, addr_reg, start_idx++);
14213ee15d3SVipul Pandya 		t4_write_reg(adap, data_reg, *vals++);
14313ee15d3SVipul Pandya 	}
14413ee15d3SVipul Pandya }
14513ee15d3SVipul Pandya 
146f7917c00SJeff Kirsher /*
1470abfd152SHariprasad Shenai  * Read a 32-bit PCI Configuration Space register via the PCI-E backdoor
1480abfd152SHariprasad Shenai  * mechanism.  This guarantees that we get the real value even if we're
1490abfd152SHariprasad Shenai  * operating within a Virtual Machine and the Hypervisor is trapping our
1500abfd152SHariprasad Shenai  * Configuration Space accesses.
1510abfd152SHariprasad Shenai  */
t4_hw_pci_read_cfg4(struct adapter * adap,int reg,u32 * val)1520abfd152SHariprasad Shenai void t4_hw_pci_read_cfg4(struct adapter *adap, int reg, u32 *val)
1530abfd152SHariprasad Shenai {
1543ccc6cf7SHariprasad Shenai 	u32 req = FUNCTION_V(adap->pf) | REGISTER_V(reg);
1553ccc6cf7SHariprasad Shenai 
1563ccc6cf7SHariprasad Shenai 	if (CHELSIO_CHIP_VERSION(adap->params.chip) <= CHELSIO_T5)
1573ccc6cf7SHariprasad Shenai 		req |= ENABLE_F;
1583ccc6cf7SHariprasad Shenai 	else
1593ccc6cf7SHariprasad Shenai 		req |= T6_ENABLE_F;
1600abfd152SHariprasad Shenai 
1610abfd152SHariprasad Shenai 	if (is_t4(adap->params.chip))
162f061de42SHariprasad Shenai 		req |= LOCALCFG_F;
1630abfd152SHariprasad Shenai 
164f061de42SHariprasad Shenai 	t4_write_reg(adap, PCIE_CFG_SPACE_REQ_A, req);
165f061de42SHariprasad Shenai 	*val = t4_read_reg(adap, PCIE_CFG_SPACE_DATA_A);
1660abfd152SHariprasad Shenai 
1670abfd152SHariprasad Shenai 	/* Reset ENABLE to 0 so reads of PCIE_CFG_SPACE_DATA won't cause a
1680abfd152SHariprasad Shenai 	 * Configuration Space read.  (None of the other fields matter when
1690abfd152SHariprasad Shenai 	 * ENABLE is 0 so a simple register write is easier than a
1700abfd152SHariprasad Shenai 	 * read-modify-write via t4_set_reg_field().)
1710abfd152SHariprasad Shenai 	 */
172f061de42SHariprasad Shenai 	t4_write_reg(adap, PCIE_CFG_SPACE_REQ_A, 0);
1730abfd152SHariprasad Shenai }
1740abfd152SHariprasad Shenai 
1750abfd152SHariprasad Shenai /*
17631d55c2dSHariprasad Shenai  * t4_report_fw_error - report firmware error
17731d55c2dSHariprasad Shenai  * @adap: the adapter
17831d55c2dSHariprasad Shenai  *
17931d55c2dSHariprasad Shenai  * The adapter firmware can indicate error conditions to the host.
18031d55c2dSHariprasad Shenai  * If the firmware has indicated an error, print out the reason for
18131d55c2dSHariprasad Shenai  * the firmware error.
18231d55c2dSHariprasad Shenai  */
t4_report_fw_error(struct adapter * adap)18331d55c2dSHariprasad Shenai static void t4_report_fw_error(struct adapter *adap)
18431d55c2dSHariprasad Shenai {
18531d55c2dSHariprasad Shenai 	static const char *const reason[] = {
18631d55c2dSHariprasad Shenai 		"Crash",                        /* PCIE_FW_EVAL_CRASH */
18731d55c2dSHariprasad Shenai 		"During Device Preparation",    /* PCIE_FW_EVAL_PREP */
18831d55c2dSHariprasad Shenai 		"During Device Configuration",  /* PCIE_FW_EVAL_CONF */
18931d55c2dSHariprasad Shenai 		"During Device Initialization", /* PCIE_FW_EVAL_INIT */
19031d55c2dSHariprasad Shenai 		"Unexpected Event",             /* PCIE_FW_EVAL_UNEXPECTEDEVENT */
19131d55c2dSHariprasad Shenai 		"Insufficient Airflow",         /* PCIE_FW_EVAL_OVERHEAT */
19231d55c2dSHariprasad Shenai 		"Device Shutdown",              /* PCIE_FW_EVAL_DEVICESHUTDOWN */
19331d55c2dSHariprasad Shenai 		"Reserved",                     /* reserved */
19431d55c2dSHariprasad Shenai 	};
19531d55c2dSHariprasad Shenai 	u32 pcie_fw;
19631d55c2dSHariprasad Shenai 
197f061de42SHariprasad Shenai 	pcie_fw = t4_read_reg(adap, PCIE_FW_A);
198825b2b6fSRahul Lakkireddy 	if (pcie_fw & PCIE_FW_ERR_F) {
19931d55c2dSHariprasad Shenai 		dev_err(adap->pdev_dev, "Firmware reports adapter error: %s\n",
200b2e1a3f0SHariprasad Shenai 			reason[PCIE_FW_EVAL_G(pcie_fw)]);
20180f61f19SArjun Vynipadath 		adap->flags &= ~CXGB4_FW_OK;
202825b2b6fSRahul Lakkireddy 	}
20331d55c2dSHariprasad Shenai }
20431d55c2dSHariprasad Shenai 
20531d55c2dSHariprasad Shenai /*
206f7917c00SJeff Kirsher  * Get the reply to a mailbox command and store it in @rpl in big-endian order.
207f7917c00SJeff Kirsher  */
get_mbox_rpl(struct adapter * adap,__be64 * rpl,int nflit,u32 mbox_addr)208f7917c00SJeff Kirsher static void get_mbox_rpl(struct adapter *adap, __be64 *rpl, int nflit,
209f7917c00SJeff Kirsher 			 u32 mbox_addr)
210f7917c00SJeff Kirsher {
211f7917c00SJeff Kirsher 	for ( ; nflit; nflit--, mbox_addr += 8)
212f7917c00SJeff Kirsher 		*rpl++ = cpu_to_be64(t4_read_reg64(adap, mbox_addr));
213f7917c00SJeff Kirsher }
214f7917c00SJeff Kirsher 
215f7917c00SJeff Kirsher /*
216f7917c00SJeff Kirsher  * Handle a FW assertion reported in a mailbox.
217f7917c00SJeff Kirsher  */
fw_asrt(struct adapter * adap,u32 mbox_addr)218f7917c00SJeff Kirsher static void fw_asrt(struct adapter *adap, u32 mbox_addr)
219f7917c00SJeff Kirsher {
220f7917c00SJeff Kirsher 	struct fw_debug_cmd asrt;
221f7917c00SJeff Kirsher 
222f7917c00SJeff Kirsher 	get_mbox_rpl(adap, (__be64 *)&asrt, sizeof(asrt) / 8, mbox_addr);
223f7917c00SJeff Kirsher 	dev_alert(adap->pdev_dev,
224f7917c00SJeff Kirsher 		  "FW assertion at %.16s:%u, val0 %#x, val1 %#x\n",
225f404f80cSHariprasad Shenai 		  asrt.u.assert.filename_0_7, be32_to_cpu(asrt.u.assert.line),
226f404f80cSHariprasad Shenai 		  be32_to_cpu(asrt.u.assert.x), be32_to_cpu(asrt.u.assert.y));
227f7917c00SJeff Kirsher }
228f7917c00SJeff Kirsher 
2297f080c3fSHariprasad Shenai /**
2307f080c3fSHariprasad Shenai  *	t4_record_mbox - record a Firmware Mailbox Command/Reply in the log
2317f080c3fSHariprasad Shenai  *	@adapter: the adapter
2327f080c3fSHariprasad Shenai  *	@cmd: the Firmware Mailbox Command or Reply
2337f080c3fSHariprasad Shenai  *	@size: command length in bytes
2347f080c3fSHariprasad Shenai  *	@access: the time (ms) needed to access the Firmware Mailbox
2357f080c3fSHariprasad Shenai  *	@execute: the time (ms) the command spent being executed
2367f080c3fSHariprasad Shenai  */
t4_record_mbox(struct adapter * adapter,const __be64 * cmd,unsigned int size,int access,int execute)2377f080c3fSHariprasad Shenai static void t4_record_mbox(struct adapter *adapter,
2387f080c3fSHariprasad Shenai 			   const __be64 *cmd, unsigned int size,
2397f080c3fSHariprasad Shenai 			   int access, int execute)
240f7917c00SJeff Kirsher {
2417f080c3fSHariprasad Shenai 	struct mbox_cmd_log *log = adapter->mbox_log;
2427f080c3fSHariprasad Shenai 	struct mbox_cmd *entry;
2437f080c3fSHariprasad Shenai 	int i;
2447f080c3fSHariprasad Shenai 
2457f080c3fSHariprasad Shenai 	entry = mbox_cmd_log_entry(log, log->cursor++);
2467f080c3fSHariprasad Shenai 	if (log->cursor == log->size)
2477f080c3fSHariprasad Shenai 		log->cursor = 0;
2487f080c3fSHariprasad Shenai 
2497f080c3fSHariprasad Shenai 	for (i = 0; i < size / 8; i++)
2507f080c3fSHariprasad Shenai 		entry->cmd[i] = be64_to_cpu(cmd[i]);
2517f080c3fSHariprasad Shenai 	while (i < MBOX_LEN / 8)
2527f080c3fSHariprasad Shenai 		entry->cmd[i++] = 0;
2537f080c3fSHariprasad Shenai 	entry->timestamp = jiffies;
2547f080c3fSHariprasad Shenai 	entry->seqno = log->seqno++;
2557f080c3fSHariprasad Shenai 	entry->access = access;
2567f080c3fSHariprasad Shenai 	entry->execute = execute;
257f7917c00SJeff Kirsher }
258f7917c00SJeff Kirsher 
259f7917c00SJeff Kirsher /**
26001b69614SHariprasad Shenai  *	t4_wr_mbox_meat_timeout - send a command to FW through the given mailbox
261f7917c00SJeff Kirsher  *	@adap: the adapter
262f7917c00SJeff Kirsher  *	@mbox: index of the mailbox to use
263f7917c00SJeff Kirsher  *	@cmd: the command to write
264f7917c00SJeff Kirsher  *	@size: command length in bytes
265f7917c00SJeff Kirsher  *	@rpl: where to optionally store the reply
266f7917c00SJeff Kirsher  *	@sleep_ok: if true we may sleep while awaiting command completion
26701b69614SHariprasad Shenai  *	@timeout: time to wait for command to finish before timing out
268f7917c00SJeff Kirsher  *
269f7917c00SJeff Kirsher  *	Sends the given command to FW through the selected mailbox and waits
270f7917c00SJeff Kirsher  *	for the FW to execute the command.  If @rpl is not %NULL it is used to
271f7917c00SJeff Kirsher  *	store the FW's reply to the command.  The command and its optional
272f7917c00SJeff Kirsher  *	reply are of the same length.  FW can take up to %FW_CMD_MAX_TIMEOUT ms
273f7917c00SJeff Kirsher  *	to respond.  @sleep_ok determines whether we may sleep while awaiting
274f7917c00SJeff Kirsher  *	the response.  If sleeping is allowed we use progressive backoff
275f7917c00SJeff Kirsher  *	otherwise we spin.
276f7917c00SJeff Kirsher  *
277f7917c00SJeff Kirsher  *	The return value is 0 on success or a negative errno on failure.  A
278f7917c00SJeff Kirsher  *	failure can happen either because we are not able to execute the
279f7917c00SJeff Kirsher  *	command or FW executes it but signals an error.  In the latter case
280f7917c00SJeff Kirsher  *	the return value is the error code indicated by FW (negated).
281f7917c00SJeff Kirsher  */
t4_wr_mbox_meat_timeout(struct adapter * adap,int mbox,const void * cmd,int size,void * rpl,bool sleep_ok,int timeout)28201b69614SHariprasad Shenai int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd,
28301b69614SHariprasad Shenai 			    int size, void *rpl, bool sleep_ok, int timeout)
284f7917c00SJeff Kirsher {
285f7917c00SJeff Kirsher 	static const int delay[] = {
286f7917c00SJeff Kirsher 		1, 1, 3, 5, 10, 10, 20, 50, 100, 200
287f7917c00SJeff Kirsher 	};
288f7917c00SJeff Kirsher 
2894055ae5eSHariprasad Shenai 	struct mbox_list entry;
2907f080c3fSHariprasad Shenai 	u16 access = 0;
2917f080c3fSHariprasad Shenai 	u16 execute = 0;
292f7917c00SJeff Kirsher 	u32 v;
293f7917c00SJeff Kirsher 	u64 res;
2947f080c3fSHariprasad Shenai 	int i, ms, delay_idx, ret;
295f7917c00SJeff Kirsher 	const __be64 *p = cmd;
29689c3a86cSHariprasad Shenai 	u32 data_reg = PF_REG(mbox, CIM_PF_MAILBOX_DATA_A);
29789c3a86cSHariprasad Shenai 	u32 ctl_reg = PF_REG(mbox, CIM_PF_MAILBOX_CTRL_A);
2987f080c3fSHariprasad Shenai 	__be64 cmd_rpl[MBOX_LEN / 8];
299f358738bSHariprasad Shenai 	u32 pcie_fw;
300f7917c00SJeff Kirsher 
301f7917c00SJeff Kirsher 	if ((size & 15) || size > MBOX_LEN)
302f7917c00SJeff Kirsher 		return -EINVAL;
303f7917c00SJeff Kirsher 
304f7917c00SJeff Kirsher 	/*
305f7917c00SJeff Kirsher 	 * If the device is off-line, as in EEH, commands will time out.
306f7917c00SJeff Kirsher 	 * Fail them early so we don't waste time waiting.
307f7917c00SJeff Kirsher 	 */
308f7917c00SJeff Kirsher 	if (adap->pdev->error_state != pci_channel_io_normal)
309f7917c00SJeff Kirsher 		return -EIO;
310f7917c00SJeff Kirsher 
3115a20f5cfSHariprasad Shenai 	/* If we have a negative timeout, that implies that we can't sleep. */
3125a20f5cfSHariprasad Shenai 	if (timeout < 0) {
3135a20f5cfSHariprasad Shenai 		sleep_ok = false;
3145a20f5cfSHariprasad Shenai 		timeout = -timeout;
3155a20f5cfSHariprasad Shenai 	}
3165a20f5cfSHariprasad Shenai 
3174055ae5eSHariprasad Shenai 	/* Queue ourselves onto the mailbox access list.  When our entry is at
3184055ae5eSHariprasad Shenai 	 * the front of the list, we have rights to access the mailbox.  So we
3194055ae5eSHariprasad Shenai 	 * wait [for a while] till we're at the front [or bail out with an
3204055ae5eSHariprasad Shenai 	 * EBUSY] ...
3214055ae5eSHariprasad Shenai 	 */
322d9ac2d99SGanesh Goudar 	spin_lock_bh(&adap->mbox_lock);
3234055ae5eSHariprasad Shenai 	list_add_tail(&entry.list, &adap->mlist.list);
324d9ac2d99SGanesh Goudar 	spin_unlock_bh(&adap->mbox_lock);
3254055ae5eSHariprasad Shenai 
3264055ae5eSHariprasad Shenai 	delay_idx = 0;
3274055ae5eSHariprasad Shenai 	ms = delay[0];
3284055ae5eSHariprasad Shenai 
3294055ae5eSHariprasad Shenai 	for (i = 0; ; i += ms) {
3304055ae5eSHariprasad Shenai 		/* If we've waited too long, return a busy indication.  This
3314055ae5eSHariprasad Shenai 		 * really ought to be based on our initial position in the
332172ca830SArkadiusz Drabczyk 		 * mailbox access list but this is a start.  We very rarely
3334055ae5eSHariprasad Shenai 		 * contend on access to the mailbox ...
3344055ae5eSHariprasad Shenai 		 */
3353be0679bSHariprasad Shenai 		pcie_fw = t4_read_reg(adap, PCIE_FW_A);
3363be0679bSHariprasad Shenai 		if (i > FW_CMD_MAX_TIMEOUT || (pcie_fw & PCIE_FW_ERR_F)) {
337d9ac2d99SGanesh Goudar 			spin_lock_bh(&adap->mbox_lock);
3384055ae5eSHariprasad Shenai 			list_del(&entry.list);
339d9ac2d99SGanesh Goudar 			spin_unlock_bh(&adap->mbox_lock);
3403be0679bSHariprasad Shenai 			ret = (pcie_fw & PCIE_FW_ERR_F) ? -ENXIO : -EBUSY;
3414055ae5eSHariprasad Shenai 			t4_record_mbox(adap, cmd, size, access, ret);
3424055ae5eSHariprasad Shenai 			return ret;
3434055ae5eSHariprasad Shenai 		}
3444055ae5eSHariprasad Shenai 
3454055ae5eSHariprasad Shenai 		/* If we're at the head, break out and start the mailbox
3464055ae5eSHariprasad Shenai 		 * protocol.
3474055ae5eSHariprasad Shenai 		 */
3484055ae5eSHariprasad Shenai 		if (list_first_entry(&adap->mlist.list, struct mbox_list,
3494055ae5eSHariprasad Shenai 				     list) == &entry)
3504055ae5eSHariprasad Shenai 			break;
3514055ae5eSHariprasad Shenai 
3524055ae5eSHariprasad Shenai 		/* Delay for a bit before checking again ... */
3534055ae5eSHariprasad Shenai 		if (sleep_ok) {
3544055ae5eSHariprasad Shenai 			ms = delay[delay_idx];  /* last element may repeat */
3554055ae5eSHariprasad Shenai 			if (delay_idx < ARRAY_SIZE(delay) - 1)
3564055ae5eSHariprasad Shenai 				delay_idx++;
3574055ae5eSHariprasad Shenai 			msleep(ms);
3584055ae5eSHariprasad Shenai 		} else {
3594055ae5eSHariprasad Shenai 			mdelay(ms);
3604055ae5eSHariprasad Shenai 		}
3614055ae5eSHariprasad Shenai 	}
3624055ae5eSHariprasad Shenai 
3634055ae5eSHariprasad Shenai 	/* Loop trying to get ownership of the mailbox.  Return an error
3644055ae5eSHariprasad Shenai 	 * if we can't gain ownership.
3654055ae5eSHariprasad Shenai 	 */
36689c3a86cSHariprasad Shenai 	v = MBOWNER_G(t4_read_reg(adap, ctl_reg));
367f7917c00SJeff Kirsher 	for (i = 0; v == MBOX_OWNER_NONE && i < 3; i++)
36889c3a86cSHariprasad Shenai 		v = MBOWNER_G(t4_read_reg(adap, ctl_reg));
3697f080c3fSHariprasad Shenai 	if (v != MBOX_OWNER_DRV) {
370d9ac2d99SGanesh Goudar 		spin_lock_bh(&adap->mbox_lock);
3714055ae5eSHariprasad Shenai 		list_del(&entry.list);
372d9ac2d99SGanesh Goudar 		spin_unlock_bh(&adap->mbox_lock);
3737f080c3fSHariprasad Shenai 		ret = (v == MBOX_OWNER_FW) ? -EBUSY : -ETIMEDOUT;
3740f308686SStefano Brivio 		t4_record_mbox(adap, cmd, size, access, ret);
3757f080c3fSHariprasad Shenai 		return ret;
3767f080c3fSHariprasad Shenai 	}
377f7917c00SJeff Kirsher 
3787f080c3fSHariprasad Shenai 	/* Copy in the new mailbox command and send it on its way ... */
3790f308686SStefano Brivio 	t4_record_mbox(adap, cmd, size, access, 0);
380f7917c00SJeff Kirsher 	for (i = 0; i < size; i += 8)
381f7917c00SJeff Kirsher 		t4_write_reg64(adap, data_reg + i, be64_to_cpu(*p++));
382f7917c00SJeff Kirsher 
38389c3a86cSHariprasad Shenai 	t4_write_reg(adap, ctl_reg, MBMSGVALID_F | MBOWNER_V(MBOX_OWNER_FW));
384f7917c00SJeff Kirsher 	t4_read_reg(adap, ctl_reg);          /* flush write */
385f7917c00SJeff Kirsher 
386f7917c00SJeff Kirsher 	delay_idx = 0;
387f7917c00SJeff Kirsher 	ms = delay[0];
388f7917c00SJeff Kirsher 
389f358738bSHariprasad Shenai 	for (i = 0;
390f358738bSHariprasad Shenai 	     !((pcie_fw = t4_read_reg(adap, PCIE_FW_A)) & PCIE_FW_ERR_F) &&
391f358738bSHariprasad Shenai 	     i < timeout;
392f358738bSHariprasad Shenai 	     i += ms) {
393f7917c00SJeff Kirsher 		if (sleep_ok) {
394f7917c00SJeff Kirsher 			ms = delay[delay_idx];  /* last element may repeat */
395f7917c00SJeff Kirsher 			if (delay_idx < ARRAY_SIZE(delay) - 1)
396f7917c00SJeff Kirsher 				delay_idx++;
397f7917c00SJeff Kirsher 			msleep(ms);
398f7917c00SJeff Kirsher 		} else
399f7917c00SJeff Kirsher 			mdelay(ms);
400f7917c00SJeff Kirsher 
401f7917c00SJeff Kirsher 		v = t4_read_reg(adap, ctl_reg);
40289c3a86cSHariprasad Shenai 		if (MBOWNER_G(v) == MBOX_OWNER_DRV) {
40389c3a86cSHariprasad Shenai 			if (!(v & MBMSGVALID_F)) {
404f7917c00SJeff Kirsher 				t4_write_reg(adap, ctl_reg, 0);
405f7917c00SJeff Kirsher 				continue;
406f7917c00SJeff Kirsher 			}
407f7917c00SJeff Kirsher 
4087f080c3fSHariprasad Shenai 			get_mbox_rpl(adap, cmd_rpl, MBOX_LEN / 8, data_reg);
4097f080c3fSHariprasad Shenai 			res = be64_to_cpu(cmd_rpl[0]);
4107f080c3fSHariprasad Shenai 
411e2ac9628SHariprasad Shenai 			if (FW_CMD_OP_G(res >> 32) == FW_DEBUG_CMD) {
412f7917c00SJeff Kirsher 				fw_asrt(adap, data_reg);
413e2ac9628SHariprasad Shenai 				res = FW_CMD_RETVAL_V(EIO);
414e2ac9628SHariprasad Shenai 			} else if (rpl) {
4157f080c3fSHariprasad Shenai 				memcpy(rpl, cmd_rpl, size);
416e2ac9628SHariprasad Shenai 			}
417f7917c00SJeff Kirsher 
418f7917c00SJeff Kirsher 			t4_write_reg(adap, ctl_reg, 0);
4197f080c3fSHariprasad Shenai 
4207f080c3fSHariprasad Shenai 			execute = i + ms;
4217f080c3fSHariprasad Shenai 			t4_record_mbox(adap, cmd_rpl,
4227f080c3fSHariprasad Shenai 				       MBOX_LEN, access, execute);
423d9ac2d99SGanesh Goudar 			spin_lock_bh(&adap->mbox_lock);
4244055ae5eSHariprasad Shenai 			list_del(&entry.list);
425d9ac2d99SGanesh Goudar 			spin_unlock_bh(&adap->mbox_lock);
426e2ac9628SHariprasad Shenai 			return -FW_CMD_RETVAL_G((int)res);
427f7917c00SJeff Kirsher 		}
428f7917c00SJeff Kirsher 	}
429f7917c00SJeff Kirsher 
430f358738bSHariprasad Shenai 	ret = (pcie_fw & PCIE_FW_ERR_F) ? -ENXIO : -ETIMEDOUT;
4310f308686SStefano Brivio 	t4_record_mbox(adap, cmd, size, access, ret);
432f7917c00SJeff Kirsher 	dev_err(adap->pdev_dev, "command %#x in mailbox %d timed out\n",
433f7917c00SJeff Kirsher 		*(const u8 *)cmd, mbox);
43431d55c2dSHariprasad Shenai 	t4_report_fw_error(adap);
435d9ac2d99SGanesh Goudar 	spin_lock_bh(&adap->mbox_lock);
4364055ae5eSHariprasad Shenai 	list_del(&entry.list);
437d9ac2d99SGanesh Goudar 	spin_unlock_bh(&adap->mbox_lock);
4383be0679bSHariprasad Shenai 	t4_fatal_err(adap);
4397f080c3fSHariprasad Shenai 	return ret;
440f7917c00SJeff Kirsher }
441f7917c00SJeff Kirsher 
t4_wr_mbox_meat(struct adapter * adap,int mbox,const void * cmd,int size,void * rpl,bool sleep_ok)44201b69614SHariprasad Shenai int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size,
44301b69614SHariprasad Shenai 		    void *rpl, bool sleep_ok)
444f7917c00SJeff Kirsher {
44501b69614SHariprasad Shenai 	return t4_wr_mbox_meat_timeout(adap, mbox, cmd, size, rpl, sleep_ok,
44601b69614SHariprasad Shenai 				       FW_CMD_MAX_TIMEOUT);
447f7917c00SJeff Kirsher }
448f7917c00SJeff Kirsher 
t4_edc_err_read(struct adapter * adap,int idx)449bf8ebb67SHariprasad Shenai static int t4_edc_err_read(struct adapter *adap, int idx)
450bf8ebb67SHariprasad Shenai {
451bf8ebb67SHariprasad Shenai 	u32 edc_ecc_err_addr_reg;
452bf8ebb67SHariprasad Shenai 	u32 rdata_reg;
453bf8ebb67SHariprasad Shenai 
454bf8ebb67SHariprasad Shenai 	if (is_t4(adap->params.chip)) {
455bf8ebb67SHariprasad Shenai 		CH_WARN(adap, "%s: T4 NOT supported.\n", __func__);
456bf8ebb67SHariprasad Shenai 		return 0;
457bf8ebb67SHariprasad Shenai 	}
458bf8ebb67SHariprasad Shenai 	if (idx != 0 && idx != 1) {
459bf8ebb67SHariprasad Shenai 		CH_WARN(adap, "%s: idx %d NOT supported.\n", __func__, idx);
460bf8ebb67SHariprasad Shenai 		return 0;
461bf8ebb67SHariprasad Shenai 	}
462bf8ebb67SHariprasad Shenai 
463bf8ebb67SHariprasad Shenai 	edc_ecc_err_addr_reg = EDC_T5_REG(EDC_H_ECC_ERR_ADDR_A, idx);
464bf8ebb67SHariprasad Shenai 	rdata_reg = EDC_T5_REG(EDC_H_BIST_STATUS_RDATA_A, idx);
465bf8ebb67SHariprasad Shenai 
466bf8ebb67SHariprasad Shenai 	CH_WARN(adap,
467bf8ebb67SHariprasad Shenai 		"edc%d err addr 0x%x: 0x%x.\n",
468bf8ebb67SHariprasad Shenai 		idx, edc_ecc_err_addr_reg,
469bf8ebb67SHariprasad Shenai 		t4_read_reg(adap, edc_ecc_err_addr_reg));
470bf8ebb67SHariprasad Shenai 	CH_WARN(adap,
471bf8ebb67SHariprasad Shenai 		"bist: 0x%x, status %llx %llx %llx %llx %llx %llx %llx %llx %llx.\n",
472bf8ebb67SHariprasad Shenai 		rdata_reg,
473bf8ebb67SHariprasad Shenai 		(unsigned long long)t4_read_reg64(adap, rdata_reg),
474bf8ebb67SHariprasad Shenai 		(unsigned long long)t4_read_reg64(adap, rdata_reg + 8),
475bf8ebb67SHariprasad Shenai 		(unsigned long long)t4_read_reg64(adap, rdata_reg + 16),
476bf8ebb67SHariprasad Shenai 		(unsigned long long)t4_read_reg64(adap, rdata_reg + 24),
477bf8ebb67SHariprasad Shenai 		(unsigned long long)t4_read_reg64(adap, rdata_reg + 32),
478bf8ebb67SHariprasad Shenai 		(unsigned long long)t4_read_reg64(adap, rdata_reg + 40),
479bf8ebb67SHariprasad Shenai 		(unsigned long long)t4_read_reg64(adap, rdata_reg + 48),
480bf8ebb67SHariprasad Shenai 		(unsigned long long)t4_read_reg64(adap, rdata_reg + 56),
481bf8ebb67SHariprasad Shenai 		(unsigned long long)t4_read_reg64(adap, rdata_reg + 64));
482bf8ebb67SHariprasad Shenai 
483bf8ebb67SHariprasad Shenai 	return 0;
484bf8ebb67SHariprasad Shenai }
485bf8ebb67SHariprasad Shenai 
4865afc8b84SVipul Pandya /**
4871a4330cdSRahul Lakkireddy  * t4_memory_rw_init - Get memory window relative offset, base, and size.
4881a4330cdSRahul Lakkireddy  * @adap: the adapter
4891a4330cdSRahul Lakkireddy  * @win: PCI-E Memory Window to use
4908b4e6b3cSArjun Vynipadath  * @mtype: memory type: MEM_EDC0, MEM_EDC1, MEM_HMA or MEM_MC
4911a4330cdSRahul Lakkireddy  * @mem_off: memory relative offset with respect to @mtype.
4921a4330cdSRahul Lakkireddy  * @mem_base: configured memory base address.
4931a4330cdSRahul Lakkireddy  * @mem_aperture: configured memory window aperture.
4941a4330cdSRahul Lakkireddy  *
4951a4330cdSRahul Lakkireddy  * Get the configured memory window's relative offset, base, and size.
4961a4330cdSRahul Lakkireddy  */
t4_memory_rw_init(struct adapter * adap,int win,int mtype,u32 * mem_off,u32 * mem_base,u32 * mem_aperture)4971a4330cdSRahul Lakkireddy int t4_memory_rw_init(struct adapter *adap, int win, int mtype, u32 *mem_off,
4981a4330cdSRahul Lakkireddy 		      u32 *mem_base, u32 *mem_aperture)
4991a4330cdSRahul Lakkireddy {
5001a4330cdSRahul Lakkireddy 	u32 edc_size, mc_size, mem_reg;
5011a4330cdSRahul Lakkireddy 
5021a4330cdSRahul Lakkireddy 	/* Offset into the region of memory which is being accessed
5031a4330cdSRahul Lakkireddy 	 * MEM_EDC0 = 0
5041a4330cdSRahul Lakkireddy 	 * MEM_EDC1 = 1
5051a4330cdSRahul Lakkireddy 	 * MEM_MC   = 2 -- MEM_MC for chips with only 1 memory controller
5061a4330cdSRahul Lakkireddy 	 * MEM_MC1  = 3 -- for chips with 2 memory controllers (e.g. T5)
5071a4330cdSRahul Lakkireddy 	 * MEM_HMA  = 4
5081a4330cdSRahul Lakkireddy 	 */
5091a4330cdSRahul Lakkireddy 	edc_size  = EDRAM0_SIZE_G(t4_read_reg(adap, MA_EDRAM0_BAR_A));
5101a4330cdSRahul Lakkireddy 	if (mtype == MEM_HMA) {
5111a4330cdSRahul Lakkireddy 		*mem_off = 2 * (edc_size * 1024 * 1024);
5121a4330cdSRahul Lakkireddy 	} else if (mtype != MEM_MC1) {
5131a4330cdSRahul Lakkireddy 		*mem_off = (mtype * (edc_size * 1024 * 1024));
5141a4330cdSRahul Lakkireddy 	} else {
5151a4330cdSRahul Lakkireddy 		mc_size = EXT_MEM0_SIZE_G(t4_read_reg(adap,
5161a4330cdSRahul Lakkireddy 						      MA_EXT_MEMORY0_BAR_A));
5171a4330cdSRahul Lakkireddy 		*mem_off = (MEM_MC0 * edc_size + mc_size) * 1024 * 1024;
5181a4330cdSRahul Lakkireddy 	}
5191a4330cdSRahul Lakkireddy 
5201a4330cdSRahul Lakkireddy 	/* Each PCI-E Memory Window is programmed with a window size -- or
5211a4330cdSRahul Lakkireddy 	 * "aperture" -- which controls the granularity of its mapping onto
5221a4330cdSRahul Lakkireddy 	 * adapter memory.  We need to grab that aperture in order to know
5231a4330cdSRahul Lakkireddy 	 * how to use the specified window.  The window is also programmed
5241a4330cdSRahul Lakkireddy 	 * with the base address of the Memory Window in BAR0's address
5251a4330cdSRahul Lakkireddy 	 * space.  For T4 this is an absolute PCI-E Bus Address.  For T5
5261a4330cdSRahul Lakkireddy 	 * the address is relative to BAR0.
5271a4330cdSRahul Lakkireddy 	 */
5281a4330cdSRahul Lakkireddy 	mem_reg = t4_read_reg(adap,
5291a4330cdSRahul Lakkireddy 			      PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN_A,
5301a4330cdSRahul Lakkireddy 						  win));
5311a4330cdSRahul Lakkireddy 	/* a dead adapter will return 0xffffffff for PIO reads */
5321a4330cdSRahul Lakkireddy 	if (mem_reg == 0xffffffff)
5331a4330cdSRahul Lakkireddy 		return -ENXIO;
5341a4330cdSRahul Lakkireddy 
5351a4330cdSRahul Lakkireddy 	*mem_aperture = 1 << (WINDOW_G(mem_reg) + WINDOW_SHIFT_X);
5361a4330cdSRahul Lakkireddy 	*mem_base = PCIEOFST_G(mem_reg) << PCIEOFST_SHIFT_X;
5371a4330cdSRahul Lakkireddy 	if (is_t4(adap->params.chip))
5381a4330cdSRahul Lakkireddy 		*mem_base -= adap->t4_bar0;
5391a4330cdSRahul Lakkireddy 
5401a4330cdSRahul Lakkireddy 	return 0;
5411a4330cdSRahul Lakkireddy }
5421a4330cdSRahul Lakkireddy 
5431a4330cdSRahul Lakkireddy /**
5441a4330cdSRahul Lakkireddy  * t4_memory_update_win - Move memory window to specified address.
5451a4330cdSRahul Lakkireddy  * @adap: the adapter
5461a4330cdSRahul Lakkireddy  * @win: PCI-E Memory Window to use
5471a4330cdSRahul Lakkireddy  * @addr: location to move.
5481a4330cdSRahul Lakkireddy  *
5491a4330cdSRahul Lakkireddy  * Move memory window to specified address.
5501a4330cdSRahul Lakkireddy  */
t4_memory_update_win(struct adapter * adap,int win,u32 addr)5511a4330cdSRahul Lakkireddy void t4_memory_update_win(struct adapter *adap, int win, u32 addr)
5521a4330cdSRahul Lakkireddy {
5531a4330cdSRahul Lakkireddy 	t4_write_reg(adap,
5541a4330cdSRahul Lakkireddy 		     PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET_A, win),
5551a4330cdSRahul Lakkireddy 		     addr);
5561a4330cdSRahul Lakkireddy 	/* Read it back to ensure that changes propagate before we
5571a4330cdSRahul Lakkireddy 	 * attempt to use the new value.
5581a4330cdSRahul Lakkireddy 	 */
5591a4330cdSRahul Lakkireddy 	t4_read_reg(adap,
5601a4330cdSRahul Lakkireddy 		    PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET_A, win));
5611a4330cdSRahul Lakkireddy }
5621a4330cdSRahul Lakkireddy 
5631a4330cdSRahul Lakkireddy /**
5641a4330cdSRahul Lakkireddy  * t4_memory_rw_residual - Read/Write residual data.
5651a4330cdSRahul Lakkireddy  * @adap: the adapter
5661a4330cdSRahul Lakkireddy  * @off: relative offset within residual to start read/write.
5671a4330cdSRahul Lakkireddy  * @addr: address within indicated memory type.
5681a4330cdSRahul Lakkireddy  * @buf: host memory buffer
5691a4330cdSRahul Lakkireddy  * @dir: direction of transfer T4_MEMORY_READ (1) or T4_MEMORY_WRITE (0)
5701a4330cdSRahul Lakkireddy  *
5711a4330cdSRahul Lakkireddy  * Read/Write residual data less than 32-bits.
5721a4330cdSRahul Lakkireddy  */
t4_memory_rw_residual(struct adapter * adap,u32 off,u32 addr,u8 * buf,int dir)5731a4330cdSRahul Lakkireddy void t4_memory_rw_residual(struct adapter *adap, u32 off, u32 addr, u8 *buf,
5741a4330cdSRahul Lakkireddy 			   int dir)
5751a4330cdSRahul Lakkireddy {
5761a4330cdSRahul Lakkireddy 	union {
5771a4330cdSRahul Lakkireddy 		u32 word;
5781a4330cdSRahul Lakkireddy 		char byte[4];
5791a4330cdSRahul Lakkireddy 	} last;
5801a4330cdSRahul Lakkireddy 	unsigned char *bp;
5811a4330cdSRahul Lakkireddy 	int i;
5821a4330cdSRahul Lakkireddy 
5831a4330cdSRahul Lakkireddy 	if (dir == T4_MEMORY_READ) {
5841a4330cdSRahul Lakkireddy 		last.word = le32_to_cpu((__force __le32)
5851a4330cdSRahul Lakkireddy 					t4_read_reg(adap, addr));
5861a4330cdSRahul Lakkireddy 		for (bp = (unsigned char *)buf, i = off; i < 4; i++)
5871a4330cdSRahul Lakkireddy 			bp[i] = last.byte[i];
5881a4330cdSRahul Lakkireddy 	} else {
5891a4330cdSRahul Lakkireddy 		last.word = *buf;
5901a4330cdSRahul Lakkireddy 		for (i = off; i < 4; i++)
5911a4330cdSRahul Lakkireddy 			last.byte[i] = 0;
5921a4330cdSRahul Lakkireddy 		t4_write_reg(adap, addr,
5931a4330cdSRahul Lakkireddy 			     (__force u32)cpu_to_le32(last.word));
5941a4330cdSRahul Lakkireddy 	}
5951a4330cdSRahul Lakkireddy }
5961a4330cdSRahul Lakkireddy 
5971a4330cdSRahul Lakkireddy /**
5985afc8b84SVipul Pandya  *	t4_memory_rw - read/write EDC 0, EDC 1 or MC via PCIE memory window
5995afc8b84SVipul Pandya  *	@adap: the adapter
600fc5ab020SHariprasad Shenai  *	@win: PCI-E Memory Window to use
6015afc8b84SVipul Pandya  *	@mtype: memory type: MEM_EDC0, MEM_EDC1 or MEM_MC
6025afc8b84SVipul Pandya  *	@addr: address within indicated memory type
6035afc8b84SVipul Pandya  *	@len: amount of memory to transfer
604f01aa633SHariprasad Shenai  *	@hbuf: host memory buffer
605fc5ab020SHariprasad Shenai  *	@dir: direction of transfer T4_MEMORY_READ (1) or T4_MEMORY_WRITE (0)
6065afc8b84SVipul Pandya  *
6075afc8b84SVipul Pandya  *	Reads/writes an [almost] arbitrary memory region in the firmware: the
608fc5ab020SHariprasad Shenai  *	firmware memory address and host buffer must be aligned on 32-bit
609172ca830SArkadiusz Drabczyk  *	boundaries; the length may be arbitrary.  The memory is transferred as
610fc5ab020SHariprasad Shenai  *	a raw byte sequence from/to the firmware's memory.  If this memory
611fc5ab020SHariprasad Shenai  *	contains data structures which contain multi-byte integers, it's the
612fc5ab020SHariprasad Shenai  *	caller's responsibility to perform appropriate byte order conversions.
6135afc8b84SVipul Pandya  */
t4_memory_rw(struct adapter * adap,int win,int mtype,u32 addr,u32 len,void * hbuf,int dir)614fc5ab020SHariprasad Shenai int t4_memory_rw(struct adapter *adap, int win, int mtype, u32 addr,
615f01aa633SHariprasad Shenai 		 u32 len, void *hbuf, int dir)
6165afc8b84SVipul Pandya {
617fc5ab020SHariprasad Shenai 	u32 pos, offset, resid, memoffset;
6181a4330cdSRahul Lakkireddy 	u32 win_pf, mem_aperture, mem_base;
619f01aa633SHariprasad Shenai 	u32 *buf;
6201a4330cdSRahul Lakkireddy 	int ret;
6215afc8b84SVipul Pandya 
622fc5ab020SHariprasad Shenai 	/* Argument sanity checks ...
6235afc8b84SVipul Pandya 	 */
624f01aa633SHariprasad Shenai 	if (addr & 0x3 || (uintptr_t)hbuf & 0x3)
6255afc8b84SVipul Pandya 		return -EINVAL;
626f01aa633SHariprasad Shenai 	buf = (u32 *)hbuf;
6275afc8b84SVipul Pandya 
628fc5ab020SHariprasad Shenai 	/* It's convenient to be able to handle lengths which aren't a
629fc5ab020SHariprasad Shenai 	 * multiple of 32-bits because we often end up transferring files to
630fc5ab020SHariprasad Shenai 	 * the firmware.  So we'll handle that by normalizing the length here
631fc5ab020SHariprasad Shenai 	 * and then handling any residual transfer at the end.
632fc5ab020SHariprasad Shenai 	 */
633fc5ab020SHariprasad Shenai 	resid = len & 0x3;
634fc5ab020SHariprasad Shenai 	len -= resid;
6358c357ebdSVipul Pandya 
6361a4330cdSRahul Lakkireddy 	ret = t4_memory_rw_init(adap, win, mtype, &memoffset, &mem_base,
6371a4330cdSRahul Lakkireddy 				&mem_aperture);
6381a4330cdSRahul Lakkireddy 	if (ret)
6391a4330cdSRahul Lakkireddy 		return ret;
6405afc8b84SVipul Pandya 
6415afc8b84SVipul Pandya 	/* Determine the PCIE_MEM_ACCESS_OFFSET */
6425afc8b84SVipul Pandya 	addr = addr + memoffset;
6435afc8b84SVipul Pandya 
644b2612722SHariprasad Shenai 	win_pf = is_t4(adap->params.chip) ? 0 : PFNUM_V(adap->pf);
6455afc8b84SVipul Pandya 
646fc5ab020SHariprasad Shenai 	/* Calculate our initial PCI-E Memory Window Position and Offset into
647fc5ab020SHariprasad Shenai 	 * that Window.
648fc5ab020SHariprasad Shenai 	 */
649fc5ab020SHariprasad Shenai 	pos = addr & ~(mem_aperture - 1);
650fc5ab020SHariprasad Shenai 	offset = addr - pos;
6515afc8b84SVipul Pandya 
652fc5ab020SHariprasad Shenai 	/* Set up initial PCI-E Memory Window to cover the start of our
6531a4330cdSRahul Lakkireddy 	 * transfer.
6545afc8b84SVipul Pandya 	 */
6551a4330cdSRahul Lakkireddy 	t4_memory_update_win(adap, win, pos | win_pf);
656fc5ab020SHariprasad Shenai 
657fc5ab020SHariprasad Shenai 	/* Transfer data to/from the adapter as long as there's an integral
658fc5ab020SHariprasad Shenai 	 * number of 32-bit transfers to complete.
659f01aa633SHariprasad Shenai 	 *
660f01aa633SHariprasad Shenai 	 * A note on Endianness issues:
661f01aa633SHariprasad Shenai 	 *
662f01aa633SHariprasad Shenai 	 * The "register" reads and writes below from/to the PCI-E Memory
663f01aa633SHariprasad Shenai 	 * Window invoke the standard adapter Big-Endian to PCI-E Link
664f01aa633SHariprasad Shenai 	 * Little-Endian "swizzel."  As a result, if we have the following
665f01aa633SHariprasad Shenai 	 * data in adapter memory:
666f01aa633SHariprasad Shenai 	 *
667f01aa633SHariprasad Shenai 	 *     Memory:  ... | b0 | b1 | b2 | b3 | ...
668f01aa633SHariprasad Shenai 	 *     Address:      i+0  i+1  i+2  i+3
669f01aa633SHariprasad Shenai 	 *
670f01aa633SHariprasad Shenai 	 * Then a read of the adapter memory via the PCI-E Memory Window
671f01aa633SHariprasad Shenai 	 * will yield:
672f01aa633SHariprasad Shenai 	 *
673f01aa633SHariprasad Shenai 	 *     x = readl(i)
674f01aa633SHariprasad Shenai 	 *         31                  0
675f01aa633SHariprasad Shenai 	 *         [ b3 | b2 | b1 | b0 ]
676f01aa633SHariprasad Shenai 	 *
677f01aa633SHariprasad Shenai 	 * If this value is stored into local memory on a Little-Endian system
678f01aa633SHariprasad Shenai 	 * it will show up correctly in local memory as:
679f01aa633SHariprasad Shenai 	 *
680f01aa633SHariprasad Shenai 	 *     ( ..., b0, b1, b2, b3, ... )
681f01aa633SHariprasad Shenai 	 *
682f01aa633SHariprasad Shenai 	 * But on a Big-Endian system, the store will show up in memory
683f01aa633SHariprasad Shenai 	 * incorrectly swizzled as:
684f01aa633SHariprasad Shenai 	 *
685f01aa633SHariprasad Shenai 	 *     ( ..., b3, b2, b1, b0, ... )
686f01aa633SHariprasad Shenai 	 *
687f01aa633SHariprasad Shenai 	 * So we need to account for this in the reads and writes to the
688f01aa633SHariprasad Shenai 	 * PCI-E Memory Window below by undoing the register read/write
689f01aa633SHariprasad Shenai 	 * swizzels.
6905afc8b84SVipul Pandya 	 */
691fc5ab020SHariprasad Shenai 	while (len > 0) {
692fc5ab020SHariprasad Shenai 		if (dir == T4_MEMORY_READ)
693f01aa633SHariprasad Shenai 			*buf++ = le32_to_cpu((__force __le32)t4_read_reg(adap,
694f01aa633SHariprasad Shenai 						mem_base + offset));
695fc5ab020SHariprasad Shenai 		else
696fc5ab020SHariprasad Shenai 			t4_write_reg(adap, mem_base + offset,
697f01aa633SHariprasad Shenai 				     (__force u32)cpu_to_le32(*buf++));
698fc5ab020SHariprasad Shenai 		offset += sizeof(__be32);
6995afc8b84SVipul Pandya 		len -= sizeof(__be32);
7005afc8b84SVipul Pandya 
701fc5ab020SHariprasad Shenai 		/* If we've reached the end of our current window aperture,
702fc5ab020SHariprasad Shenai 		 * move the PCI-E Memory Window on to the next.  Note that
703fc5ab020SHariprasad Shenai 		 * doing this here after "len" may be 0 allows us to set up
704fc5ab020SHariprasad Shenai 		 * the PCI-E Memory Window for a possible final residual
705fc5ab020SHariprasad Shenai 		 * transfer below ...
7065afc8b84SVipul Pandya 		 */
707fc5ab020SHariprasad Shenai 		if (offset == mem_aperture) {
708fc5ab020SHariprasad Shenai 			pos += mem_aperture;
709fc5ab020SHariprasad Shenai 			offset = 0;
7101a4330cdSRahul Lakkireddy 			t4_memory_update_win(adap, win, pos | win_pf);
711fc5ab020SHariprasad Shenai 		}
712fc5ab020SHariprasad Shenai 	}
7135afc8b84SVipul Pandya 
714fc5ab020SHariprasad Shenai 	/* If the original transfer had a length which wasn't a multiple of
715fc5ab020SHariprasad Shenai 	 * 32-bits, now's where we need to finish off the transfer of the
716fc5ab020SHariprasad Shenai 	 * residual amount.  The PCI-E Memory Window has already been moved
717fc5ab020SHariprasad Shenai 	 * above (if necessary) to cover this final transfer.
7185afc8b84SVipul Pandya 	 */
7191a4330cdSRahul Lakkireddy 	if (resid)
7201a4330cdSRahul Lakkireddy 		t4_memory_rw_residual(adap, resid, mem_base + offset,
7211a4330cdSRahul Lakkireddy 				      (u8 *)buf, dir);
7225afc8b84SVipul Pandya 
723fc5ab020SHariprasad Shenai 	return 0;
7245afc8b84SVipul Pandya }
7255afc8b84SVipul Pandya 
726b562fc37SHariprasad Shenai /* Return the specified PCI-E Configuration Space register from our Physical
727b562fc37SHariprasad Shenai  * Function.  We try first via a Firmware LDST Command since we prefer to let
728b562fc37SHariprasad Shenai  * the firmware own all of these registers, but if that fails we go for it
729b562fc37SHariprasad Shenai  * directly ourselves.
730b562fc37SHariprasad Shenai  */
t4_read_pcie_cfg4(struct adapter * adap,int reg)731b562fc37SHariprasad Shenai u32 t4_read_pcie_cfg4(struct adapter *adap, int reg)
732b562fc37SHariprasad Shenai {
733b562fc37SHariprasad Shenai 	u32 val, ldst_addrspace;
734b562fc37SHariprasad Shenai 
735b562fc37SHariprasad Shenai 	/* If fw_attach != 0, construct and send the Firmware LDST Command to
736b562fc37SHariprasad Shenai 	 * retrieve the specified PCI-E Configuration Space register.
737b562fc37SHariprasad Shenai 	 */
738b562fc37SHariprasad Shenai 	struct fw_ldst_cmd ldst_cmd;
739b562fc37SHariprasad Shenai 	int ret;
740b562fc37SHariprasad Shenai 
741b562fc37SHariprasad Shenai 	memset(&ldst_cmd, 0, sizeof(ldst_cmd));
742b562fc37SHariprasad Shenai 	ldst_addrspace = FW_LDST_CMD_ADDRSPACE_V(FW_LDST_ADDRSPC_FUNC_PCIE);
743b562fc37SHariprasad Shenai 	ldst_cmd.op_to_addrspace = cpu_to_be32(FW_CMD_OP_V(FW_LDST_CMD) |
744b562fc37SHariprasad Shenai 					       FW_CMD_REQUEST_F |
745b562fc37SHariprasad Shenai 					       FW_CMD_READ_F |
746b562fc37SHariprasad Shenai 					       ldst_addrspace);
747b562fc37SHariprasad Shenai 	ldst_cmd.cycles_to_len16 = cpu_to_be32(FW_LEN16(ldst_cmd));
748b562fc37SHariprasad Shenai 	ldst_cmd.u.pcie.select_naccess = FW_LDST_CMD_NACCESS_V(1);
749b562fc37SHariprasad Shenai 	ldst_cmd.u.pcie.ctrl_to_fn =
750b2612722SHariprasad Shenai 		(FW_LDST_CMD_LC_F | FW_LDST_CMD_FN_V(adap->pf));
751b562fc37SHariprasad Shenai 	ldst_cmd.u.pcie.r = reg;
752b562fc37SHariprasad Shenai 
753b562fc37SHariprasad Shenai 	/* If the LDST Command succeeds, return the result, otherwise
754b562fc37SHariprasad Shenai 	 * fall through to reading it directly ourselves ...
755b562fc37SHariprasad Shenai 	 */
756b562fc37SHariprasad Shenai 	ret = t4_wr_mbox(adap, adap->mbox, &ldst_cmd, sizeof(ldst_cmd),
757b562fc37SHariprasad Shenai 			 &ldst_cmd);
758b562fc37SHariprasad Shenai 	if (ret == 0)
759b562fc37SHariprasad Shenai 		val = be32_to_cpu(ldst_cmd.u.pcie.data[0]);
760b562fc37SHariprasad Shenai 	else
761b562fc37SHariprasad Shenai 		/* Read the desired Configuration Space register via the PCI-E
762b562fc37SHariprasad Shenai 		 * Backdoor mechanism.
763b562fc37SHariprasad Shenai 		 */
764b562fc37SHariprasad Shenai 		t4_hw_pci_read_cfg4(adap, reg, &val);
765b562fc37SHariprasad Shenai 	return val;
766b562fc37SHariprasad Shenai }
767b562fc37SHariprasad Shenai 
768b562fc37SHariprasad Shenai /* Get the window based on base passed to it.
769b562fc37SHariprasad Shenai  * Window aperture is currently unhandled, but there is no use case for it
770b562fc37SHariprasad Shenai  * right now
771b562fc37SHariprasad Shenai  */
t4_get_window(struct adapter * adap,u32 pci_base,u64 pci_mask,u32 memwin_base)772b562fc37SHariprasad Shenai static u32 t4_get_window(struct adapter *adap, u32 pci_base, u64 pci_mask,
773b562fc37SHariprasad Shenai 			 u32 memwin_base)
774b562fc37SHariprasad Shenai {
775b562fc37SHariprasad Shenai 	u32 ret;
776b562fc37SHariprasad Shenai 
777b562fc37SHariprasad Shenai 	if (is_t4(adap->params.chip)) {
778b562fc37SHariprasad Shenai 		u32 bar0;
779b562fc37SHariprasad Shenai 
780b562fc37SHariprasad Shenai 		/* Truncation intentional: we only read the bottom 32-bits of
781b562fc37SHariprasad Shenai 		 * the 64-bit BAR0/BAR1 ...  We use the hardware backdoor
782b562fc37SHariprasad Shenai 		 * mechanism to read BAR0 instead of using
783b562fc37SHariprasad Shenai 		 * pci_resource_start() because we could be operating from
784b562fc37SHariprasad Shenai 		 * within a Virtual Machine which is trapping our accesses to
785b562fc37SHariprasad Shenai 		 * our Configuration Space and we need to set up the PCI-E
786b562fc37SHariprasad Shenai 		 * Memory Window decoders with the actual addresses which will
787b562fc37SHariprasad Shenai 		 * be coming across the PCI-E link.
788b562fc37SHariprasad Shenai 		 */
789b562fc37SHariprasad Shenai 		bar0 = t4_read_pcie_cfg4(adap, pci_base);
790b562fc37SHariprasad Shenai 		bar0 &= pci_mask;
791b562fc37SHariprasad Shenai 		adap->t4_bar0 = bar0;
792b562fc37SHariprasad Shenai 
793b562fc37SHariprasad Shenai 		ret = bar0 + memwin_base;
794b562fc37SHariprasad Shenai 	} else {
795b562fc37SHariprasad Shenai 		/* For T5, only relative offset inside the PCIe BAR is passed */
796b562fc37SHariprasad Shenai 		ret = memwin_base;
797b562fc37SHariprasad Shenai 	}
798b562fc37SHariprasad Shenai 	return ret;
799b562fc37SHariprasad Shenai }
800b562fc37SHariprasad Shenai 
801b562fc37SHariprasad Shenai /* Get the default utility window (win0) used by everyone */
t4_get_util_window(struct adapter * adap)802b562fc37SHariprasad Shenai u32 t4_get_util_window(struct adapter *adap)
803b562fc37SHariprasad Shenai {
804b562fc37SHariprasad Shenai 	return t4_get_window(adap, PCI_BASE_ADDRESS_0,
805b562fc37SHariprasad Shenai 			     PCI_BASE_ADDRESS_MEM_MASK, MEMWIN0_BASE);
806b562fc37SHariprasad Shenai }
807b562fc37SHariprasad Shenai 
808b562fc37SHariprasad Shenai /* Set up memory window for accessing adapter memory ranges.  (Read
809b562fc37SHariprasad Shenai  * back MA register to ensure that changes propagate before we attempt
810b562fc37SHariprasad Shenai  * to use the new values.)
811b562fc37SHariprasad Shenai  */
t4_setup_memwin(struct adapter * adap,u32 memwin_base,u32 window)812b562fc37SHariprasad Shenai void t4_setup_memwin(struct adapter *adap, u32 memwin_base, u32 window)
813b562fc37SHariprasad Shenai {
814b562fc37SHariprasad Shenai 	t4_write_reg(adap,
815b562fc37SHariprasad Shenai 		     PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN_A, window),
816b562fc37SHariprasad Shenai 		     memwin_base | BIR_V(0) |
817b562fc37SHariprasad Shenai 		     WINDOW_V(ilog2(MEMWIN0_APERTURE) - WINDOW_SHIFT_X));
818b562fc37SHariprasad Shenai 	t4_read_reg(adap,
819b562fc37SHariprasad Shenai 		    PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN_A, window));
820b562fc37SHariprasad Shenai }
821b562fc37SHariprasad Shenai 
822812034f1SHariprasad Shenai /**
823812034f1SHariprasad Shenai  *	t4_get_regs_len - return the size of the chips register set
824812034f1SHariprasad Shenai  *	@adapter: the adapter
825812034f1SHariprasad Shenai  *
826812034f1SHariprasad Shenai  *	Returns the size of the chip's BAR0 register space.
827812034f1SHariprasad Shenai  */
t4_get_regs_len(struct adapter * adapter)828812034f1SHariprasad Shenai unsigned int t4_get_regs_len(struct adapter *adapter)
829812034f1SHariprasad Shenai {
830812034f1SHariprasad Shenai 	unsigned int chip_version = CHELSIO_CHIP_VERSION(adapter->params.chip);
831812034f1SHariprasad Shenai 
832812034f1SHariprasad Shenai 	switch (chip_version) {
833812034f1SHariprasad Shenai 	case CHELSIO_T4:
834812034f1SHariprasad Shenai 		return T4_REGMAP_SIZE;
835812034f1SHariprasad Shenai 
836812034f1SHariprasad Shenai 	case CHELSIO_T5:
837ab4b583bSHariprasad Shenai 	case CHELSIO_T6:
838812034f1SHariprasad Shenai 		return T5_REGMAP_SIZE;
839812034f1SHariprasad Shenai 	}
840812034f1SHariprasad Shenai 
841812034f1SHariprasad Shenai 	dev_err(adapter->pdev_dev,
842812034f1SHariprasad Shenai 		"Unsupported chip version %d\n", chip_version);
843812034f1SHariprasad Shenai 	return 0;
844812034f1SHariprasad Shenai }
845812034f1SHariprasad Shenai 
846812034f1SHariprasad Shenai /**
847812034f1SHariprasad Shenai  *	t4_get_regs - read chip registers into provided buffer
848812034f1SHariprasad Shenai  *	@adap: the adapter
849812034f1SHariprasad Shenai  *	@buf: register buffer
850812034f1SHariprasad Shenai  *	@buf_size: size (in bytes) of register buffer
851812034f1SHariprasad Shenai  *
852812034f1SHariprasad Shenai  *	If the provided register buffer isn't large enough for the chip's
853812034f1SHariprasad Shenai  *	full register range, the register dump will be truncated to the
854812034f1SHariprasad Shenai  *	register buffer's size.
855812034f1SHariprasad Shenai  */
t4_get_regs(struct adapter * adap,void * buf,size_t buf_size)856812034f1SHariprasad Shenai void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size)
857812034f1SHariprasad Shenai {
858812034f1SHariprasad Shenai 	static const unsigned int t4_reg_ranges[] = {
859812034f1SHariprasad Shenai 		0x1008, 0x1108,
8608119c018SHariprasad Shenai 		0x1180, 0x1184,
8618119c018SHariprasad Shenai 		0x1190, 0x1194,
8628119c018SHariprasad Shenai 		0x11a0, 0x11a4,
8638119c018SHariprasad Shenai 		0x11b0, 0x11b4,
864812034f1SHariprasad Shenai 		0x11fc, 0x123c,
865812034f1SHariprasad Shenai 		0x1300, 0x173c,
866812034f1SHariprasad Shenai 		0x1800, 0x18fc,
8678119c018SHariprasad Shenai 		0x3000, 0x30d8,
8688119c018SHariprasad Shenai 		0x30e0, 0x30e4,
8698119c018SHariprasad Shenai 		0x30ec, 0x5910,
8708119c018SHariprasad Shenai 		0x5920, 0x5924,
8718119c018SHariprasad Shenai 		0x5960, 0x5960,
8728119c018SHariprasad Shenai 		0x5968, 0x5968,
8738119c018SHariprasad Shenai 		0x5970, 0x5970,
8748119c018SHariprasad Shenai 		0x5978, 0x5978,
8758119c018SHariprasad Shenai 		0x5980, 0x5980,
8768119c018SHariprasad Shenai 		0x5988, 0x5988,
8778119c018SHariprasad Shenai 		0x5990, 0x5990,
8788119c018SHariprasad Shenai 		0x5998, 0x5998,
8798119c018SHariprasad Shenai 		0x59a0, 0x59d4,
8808119c018SHariprasad Shenai 		0x5a00, 0x5ae0,
8818119c018SHariprasad Shenai 		0x5ae8, 0x5ae8,
8828119c018SHariprasad Shenai 		0x5af0, 0x5af0,
8838119c018SHariprasad Shenai 		0x5af8, 0x5af8,
884812034f1SHariprasad Shenai 		0x6000, 0x6098,
885812034f1SHariprasad Shenai 		0x6100, 0x6150,
886812034f1SHariprasad Shenai 		0x6200, 0x6208,
887812034f1SHariprasad Shenai 		0x6240, 0x6248,
8888119c018SHariprasad Shenai 		0x6280, 0x62b0,
8898119c018SHariprasad Shenai 		0x62c0, 0x6338,
890812034f1SHariprasad Shenai 		0x6370, 0x638c,
891812034f1SHariprasad Shenai 		0x6400, 0x643c,
892812034f1SHariprasad Shenai 		0x6500, 0x6524,
8938119c018SHariprasad Shenai 		0x6a00, 0x6a04,
8948119c018SHariprasad Shenai 		0x6a14, 0x6a38,
8958119c018SHariprasad Shenai 		0x6a60, 0x6a70,
8968119c018SHariprasad Shenai 		0x6a78, 0x6a78,
8978119c018SHariprasad Shenai 		0x6b00, 0x6b0c,
8988119c018SHariprasad Shenai 		0x6b1c, 0x6b84,
8998119c018SHariprasad Shenai 		0x6bf0, 0x6bf8,
9008119c018SHariprasad Shenai 		0x6c00, 0x6c0c,
9018119c018SHariprasad Shenai 		0x6c1c, 0x6c84,
9028119c018SHariprasad Shenai 		0x6cf0, 0x6cf8,
9038119c018SHariprasad Shenai 		0x6d00, 0x6d0c,
9048119c018SHariprasad Shenai 		0x6d1c, 0x6d84,
9058119c018SHariprasad Shenai 		0x6df0, 0x6df8,
9068119c018SHariprasad Shenai 		0x6e00, 0x6e0c,
9078119c018SHariprasad Shenai 		0x6e1c, 0x6e84,
9088119c018SHariprasad Shenai 		0x6ef0, 0x6ef8,
9098119c018SHariprasad Shenai 		0x6f00, 0x6f0c,
9108119c018SHariprasad Shenai 		0x6f1c, 0x6f84,
9118119c018SHariprasad Shenai 		0x6ff0, 0x6ff8,
9128119c018SHariprasad Shenai 		0x7000, 0x700c,
9138119c018SHariprasad Shenai 		0x701c, 0x7084,
9148119c018SHariprasad Shenai 		0x70f0, 0x70f8,
9158119c018SHariprasad Shenai 		0x7100, 0x710c,
9168119c018SHariprasad Shenai 		0x711c, 0x7184,
9178119c018SHariprasad Shenai 		0x71f0, 0x71f8,
9188119c018SHariprasad Shenai 		0x7200, 0x720c,
9198119c018SHariprasad Shenai 		0x721c, 0x7284,
9208119c018SHariprasad Shenai 		0x72f0, 0x72f8,
9218119c018SHariprasad Shenai 		0x7300, 0x730c,
9228119c018SHariprasad Shenai 		0x731c, 0x7384,
9238119c018SHariprasad Shenai 		0x73f0, 0x73f8,
9248119c018SHariprasad Shenai 		0x7400, 0x7450,
925812034f1SHariprasad Shenai 		0x7500, 0x7530,
9268119c018SHariprasad Shenai 		0x7600, 0x760c,
9278119c018SHariprasad Shenai 		0x7614, 0x761c,
928812034f1SHariprasad Shenai 		0x7680, 0x76cc,
929812034f1SHariprasad Shenai 		0x7700, 0x7798,
930812034f1SHariprasad Shenai 		0x77c0, 0x77fc,
931812034f1SHariprasad Shenai 		0x7900, 0x79fc,
9328119c018SHariprasad Shenai 		0x7b00, 0x7b58,
9338119c018SHariprasad Shenai 		0x7b60, 0x7b84,
9348119c018SHariprasad Shenai 		0x7b8c, 0x7c38,
9358119c018SHariprasad Shenai 		0x7d00, 0x7d38,
9368119c018SHariprasad Shenai 		0x7d40, 0x7d80,
9378119c018SHariprasad Shenai 		0x7d8c, 0x7ddc,
9388119c018SHariprasad Shenai 		0x7de4, 0x7e04,
9398119c018SHariprasad Shenai 		0x7e10, 0x7e1c,
9408119c018SHariprasad Shenai 		0x7e24, 0x7e38,
9418119c018SHariprasad Shenai 		0x7e40, 0x7e44,
9428119c018SHariprasad Shenai 		0x7e4c, 0x7e78,
9438119c018SHariprasad Shenai 		0x7e80, 0x7ea4,
9448119c018SHariprasad Shenai 		0x7eac, 0x7edc,
9458119c018SHariprasad Shenai 		0x7ee8, 0x7efc,
9468119c018SHariprasad Shenai 		0x8dc0, 0x8e04,
9478119c018SHariprasad Shenai 		0x8e10, 0x8e1c,
948812034f1SHariprasad Shenai 		0x8e30, 0x8e78,
9498119c018SHariprasad Shenai 		0x8ea0, 0x8eb8,
9508119c018SHariprasad Shenai 		0x8ec0, 0x8f6c,
9518119c018SHariprasad Shenai 		0x8fc0, 0x9008,
9528119c018SHariprasad Shenai 		0x9010, 0x9058,
9538119c018SHariprasad Shenai 		0x9060, 0x9060,
9548119c018SHariprasad Shenai 		0x9068, 0x9074,
955812034f1SHariprasad Shenai 		0x90fc, 0x90fc,
9568119c018SHariprasad Shenai 		0x9400, 0x9408,
9578119c018SHariprasad Shenai 		0x9410, 0x9458,
9588119c018SHariprasad Shenai 		0x9600, 0x9600,
9598119c018SHariprasad Shenai 		0x9608, 0x9638,
9608119c018SHariprasad Shenai 		0x9640, 0x96bc,
961812034f1SHariprasad Shenai 		0x9800, 0x9808,
962812034f1SHariprasad Shenai 		0x9820, 0x983c,
963812034f1SHariprasad Shenai 		0x9850, 0x9864,
964812034f1SHariprasad Shenai 		0x9c00, 0x9c6c,
965812034f1SHariprasad Shenai 		0x9c80, 0x9cec,
966812034f1SHariprasad Shenai 		0x9d00, 0x9d6c,
967812034f1SHariprasad Shenai 		0x9d80, 0x9dec,
968812034f1SHariprasad Shenai 		0x9e00, 0x9e6c,
969812034f1SHariprasad Shenai 		0x9e80, 0x9eec,
970812034f1SHariprasad Shenai 		0x9f00, 0x9f6c,
971812034f1SHariprasad Shenai 		0x9f80, 0x9fec,
9728119c018SHariprasad Shenai 		0xd004, 0xd004,
9738119c018SHariprasad Shenai 		0xd010, 0xd03c,
974812034f1SHariprasad Shenai 		0xdfc0, 0xdfe0,
975812034f1SHariprasad Shenai 		0xe000, 0xea7c,
97604d8980bSArjun Vynipadath 		0xf000, 0x11110,
97704d8980bSArjun Vynipadath 		0x11118, 0x11190,
978812034f1SHariprasad Shenai 		0x19040, 0x1906c,
979812034f1SHariprasad Shenai 		0x19078, 0x19080,
9808119c018SHariprasad Shenai 		0x1908c, 0x190e4,
9818119c018SHariprasad Shenai 		0x190f0, 0x190f8,
9828119c018SHariprasad Shenai 		0x19100, 0x19110,
9838119c018SHariprasad Shenai 		0x19120, 0x19124,
9848119c018SHariprasad Shenai 		0x19150, 0x19194,
9858119c018SHariprasad Shenai 		0x1919c, 0x191b0,
986812034f1SHariprasad Shenai 		0x191d0, 0x191e8,
987812034f1SHariprasad Shenai 		0x19238, 0x1924c,
9888119c018SHariprasad Shenai 		0x193f8, 0x1943c,
9898119c018SHariprasad Shenai 		0x1944c, 0x19474,
9908119c018SHariprasad Shenai 		0x19490, 0x194e0,
9918119c018SHariprasad Shenai 		0x194f0, 0x194f8,
9928119c018SHariprasad Shenai 		0x19800, 0x19c08,
9938119c018SHariprasad Shenai 		0x19c10, 0x19c90,
9948119c018SHariprasad Shenai 		0x19ca0, 0x19ce4,
9958119c018SHariprasad Shenai 		0x19cf0, 0x19d40,
9968119c018SHariprasad Shenai 		0x19d50, 0x19d94,
9978119c018SHariprasad Shenai 		0x19da0, 0x19de8,
9988119c018SHariprasad Shenai 		0x19df0, 0x19e40,
9998119c018SHariprasad Shenai 		0x19e50, 0x19e90,
10008119c018SHariprasad Shenai 		0x19ea0, 0x19f4c,
10018119c018SHariprasad Shenai 		0x1a000, 0x1a004,
10028119c018SHariprasad Shenai 		0x1a010, 0x1a06c,
10038119c018SHariprasad Shenai 		0x1a0b0, 0x1a0e4,
10048119c018SHariprasad Shenai 		0x1a0ec, 0x1a0f4,
10058119c018SHariprasad Shenai 		0x1a100, 0x1a108,
10068119c018SHariprasad Shenai 		0x1a114, 0x1a120,
10078119c018SHariprasad Shenai 		0x1a128, 0x1a130,
10088119c018SHariprasad Shenai 		0x1a138, 0x1a138,
1009812034f1SHariprasad Shenai 		0x1a190, 0x1a1c4,
1010812034f1SHariprasad Shenai 		0x1a1fc, 0x1a1fc,
1011812034f1SHariprasad Shenai 		0x1e040, 0x1e04c,
1012812034f1SHariprasad Shenai 		0x1e284, 0x1e28c,
1013812034f1SHariprasad Shenai 		0x1e2c0, 0x1e2c0,
1014812034f1SHariprasad Shenai 		0x1e2e0, 0x1e2e0,
1015812034f1SHariprasad Shenai 		0x1e300, 0x1e384,
1016812034f1SHariprasad Shenai 		0x1e3c0, 0x1e3c8,
1017812034f1SHariprasad Shenai 		0x1e440, 0x1e44c,
1018812034f1SHariprasad Shenai 		0x1e684, 0x1e68c,
1019812034f1SHariprasad Shenai 		0x1e6c0, 0x1e6c0,
1020812034f1SHariprasad Shenai 		0x1e6e0, 0x1e6e0,
1021812034f1SHariprasad Shenai 		0x1e700, 0x1e784,
1022812034f1SHariprasad Shenai 		0x1e7c0, 0x1e7c8,
1023812034f1SHariprasad Shenai 		0x1e840, 0x1e84c,
1024812034f1SHariprasad Shenai 		0x1ea84, 0x1ea8c,
1025812034f1SHariprasad Shenai 		0x1eac0, 0x1eac0,
1026812034f1SHariprasad Shenai 		0x1eae0, 0x1eae0,
1027812034f1SHariprasad Shenai 		0x1eb00, 0x1eb84,
1028812034f1SHariprasad Shenai 		0x1ebc0, 0x1ebc8,
1029812034f1SHariprasad Shenai 		0x1ec40, 0x1ec4c,
1030812034f1SHariprasad Shenai 		0x1ee84, 0x1ee8c,
1031812034f1SHariprasad Shenai 		0x1eec0, 0x1eec0,
1032812034f1SHariprasad Shenai 		0x1eee0, 0x1eee0,
1033812034f1SHariprasad Shenai 		0x1ef00, 0x1ef84,
1034812034f1SHariprasad Shenai 		0x1efc0, 0x1efc8,
1035812034f1SHariprasad Shenai 		0x1f040, 0x1f04c,
1036812034f1SHariprasad Shenai 		0x1f284, 0x1f28c,
1037812034f1SHariprasad Shenai 		0x1f2c0, 0x1f2c0,
1038812034f1SHariprasad Shenai 		0x1f2e0, 0x1f2e0,
1039812034f1SHariprasad Shenai 		0x1f300, 0x1f384,
1040812034f1SHariprasad Shenai 		0x1f3c0, 0x1f3c8,
1041812034f1SHariprasad Shenai 		0x1f440, 0x1f44c,
1042812034f1SHariprasad Shenai 		0x1f684, 0x1f68c,
1043812034f1SHariprasad Shenai 		0x1f6c0, 0x1f6c0,
1044812034f1SHariprasad Shenai 		0x1f6e0, 0x1f6e0,
1045812034f1SHariprasad Shenai 		0x1f700, 0x1f784,
1046812034f1SHariprasad Shenai 		0x1f7c0, 0x1f7c8,
1047812034f1SHariprasad Shenai 		0x1f840, 0x1f84c,
1048812034f1SHariprasad Shenai 		0x1fa84, 0x1fa8c,
1049812034f1SHariprasad Shenai 		0x1fac0, 0x1fac0,
1050812034f1SHariprasad Shenai 		0x1fae0, 0x1fae0,
1051812034f1SHariprasad Shenai 		0x1fb00, 0x1fb84,
1052812034f1SHariprasad Shenai 		0x1fbc0, 0x1fbc8,
1053812034f1SHariprasad Shenai 		0x1fc40, 0x1fc4c,
1054812034f1SHariprasad Shenai 		0x1fe84, 0x1fe8c,
1055812034f1SHariprasad Shenai 		0x1fec0, 0x1fec0,
1056812034f1SHariprasad Shenai 		0x1fee0, 0x1fee0,
1057812034f1SHariprasad Shenai 		0x1ff00, 0x1ff84,
1058812034f1SHariprasad Shenai 		0x1ffc0, 0x1ffc8,
1059812034f1SHariprasad Shenai 		0x20000, 0x2002c,
1060812034f1SHariprasad Shenai 		0x20100, 0x2013c,
10618119c018SHariprasad Shenai 		0x20190, 0x201a0,
10628119c018SHariprasad Shenai 		0x201a8, 0x201b8,
10638119c018SHariprasad Shenai 		0x201c4, 0x201c8,
1064812034f1SHariprasad Shenai 		0x20200, 0x20318,
10658119c018SHariprasad Shenai 		0x20400, 0x204b4,
10668119c018SHariprasad Shenai 		0x204c0, 0x20528,
1067812034f1SHariprasad Shenai 		0x20540, 0x20614,
1068812034f1SHariprasad Shenai 		0x21000, 0x21040,
1069812034f1SHariprasad Shenai 		0x2104c, 0x21060,
1070812034f1SHariprasad Shenai 		0x210c0, 0x210ec,
1071812034f1SHariprasad Shenai 		0x21200, 0x21268,
1072812034f1SHariprasad Shenai 		0x21270, 0x21284,
1073812034f1SHariprasad Shenai 		0x212fc, 0x21388,
1074812034f1SHariprasad Shenai 		0x21400, 0x21404,
10758119c018SHariprasad Shenai 		0x21500, 0x21500,
10768119c018SHariprasad Shenai 		0x21510, 0x21518,
10778119c018SHariprasad Shenai 		0x2152c, 0x21530,
10788119c018SHariprasad Shenai 		0x2153c, 0x2153c,
1079812034f1SHariprasad Shenai 		0x21550, 0x21554,
1080812034f1SHariprasad Shenai 		0x21600, 0x21600,
10818119c018SHariprasad Shenai 		0x21608, 0x2161c,
10828119c018SHariprasad Shenai 		0x21624, 0x21628,
10838119c018SHariprasad Shenai 		0x21630, 0x21634,
10848119c018SHariprasad Shenai 		0x2163c, 0x2163c,
1085812034f1SHariprasad Shenai 		0x21700, 0x2171c,
1086812034f1SHariprasad Shenai 		0x21780, 0x2178c,
10878119c018SHariprasad Shenai 		0x21800, 0x21818,
10888119c018SHariprasad Shenai 		0x21820, 0x21828,
10898119c018SHariprasad Shenai 		0x21830, 0x21848,
10908119c018SHariprasad Shenai 		0x21850, 0x21854,
10918119c018SHariprasad Shenai 		0x21860, 0x21868,
10928119c018SHariprasad Shenai 		0x21870, 0x21870,
10938119c018SHariprasad Shenai 		0x21878, 0x21898,
10948119c018SHariprasad Shenai 		0x218a0, 0x218a8,
10958119c018SHariprasad Shenai 		0x218b0, 0x218c8,
10968119c018SHariprasad Shenai 		0x218d0, 0x218d4,
10978119c018SHariprasad Shenai 		0x218e0, 0x218e8,
10988119c018SHariprasad Shenai 		0x218f0, 0x218f0,
10998119c018SHariprasad Shenai 		0x218f8, 0x21a18,
11008119c018SHariprasad Shenai 		0x21a20, 0x21a28,
11018119c018SHariprasad Shenai 		0x21a30, 0x21a48,
11028119c018SHariprasad Shenai 		0x21a50, 0x21a54,
11038119c018SHariprasad Shenai 		0x21a60, 0x21a68,
11048119c018SHariprasad Shenai 		0x21a70, 0x21a70,
11058119c018SHariprasad Shenai 		0x21a78, 0x21a98,
11068119c018SHariprasad Shenai 		0x21aa0, 0x21aa8,
11078119c018SHariprasad Shenai 		0x21ab0, 0x21ac8,
11088119c018SHariprasad Shenai 		0x21ad0, 0x21ad4,
11098119c018SHariprasad Shenai 		0x21ae0, 0x21ae8,
11108119c018SHariprasad Shenai 		0x21af0, 0x21af0,
11118119c018SHariprasad Shenai 		0x21af8, 0x21c18,
11128119c018SHariprasad Shenai 		0x21c20, 0x21c20,
11138119c018SHariprasad Shenai 		0x21c28, 0x21c30,
11148119c018SHariprasad Shenai 		0x21c38, 0x21c38,
11158119c018SHariprasad Shenai 		0x21c80, 0x21c98,
11168119c018SHariprasad Shenai 		0x21ca0, 0x21ca8,
11178119c018SHariprasad Shenai 		0x21cb0, 0x21cc8,
11188119c018SHariprasad Shenai 		0x21cd0, 0x21cd4,
11198119c018SHariprasad Shenai 		0x21ce0, 0x21ce8,
11208119c018SHariprasad Shenai 		0x21cf0, 0x21cf0,
11218119c018SHariprasad Shenai 		0x21cf8, 0x21d7c,
1122812034f1SHariprasad Shenai 		0x21e00, 0x21e04,
1123812034f1SHariprasad Shenai 		0x22000, 0x2202c,
1124812034f1SHariprasad Shenai 		0x22100, 0x2213c,
11258119c018SHariprasad Shenai 		0x22190, 0x221a0,
11268119c018SHariprasad Shenai 		0x221a8, 0x221b8,
11278119c018SHariprasad Shenai 		0x221c4, 0x221c8,
1128812034f1SHariprasad Shenai 		0x22200, 0x22318,
11298119c018SHariprasad Shenai 		0x22400, 0x224b4,
11308119c018SHariprasad Shenai 		0x224c0, 0x22528,
1131812034f1SHariprasad Shenai 		0x22540, 0x22614,
1132812034f1SHariprasad Shenai 		0x23000, 0x23040,
1133812034f1SHariprasad Shenai 		0x2304c, 0x23060,
1134812034f1SHariprasad Shenai 		0x230c0, 0x230ec,
1135812034f1SHariprasad Shenai 		0x23200, 0x23268,
1136812034f1SHariprasad Shenai 		0x23270, 0x23284,
1137812034f1SHariprasad Shenai 		0x232fc, 0x23388,
1138812034f1SHariprasad Shenai 		0x23400, 0x23404,
11398119c018SHariprasad Shenai 		0x23500, 0x23500,
11408119c018SHariprasad Shenai 		0x23510, 0x23518,
11418119c018SHariprasad Shenai 		0x2352c, 0x23530,
11428119c018SHariprasad Shenai 		0x2353c, 0x2353c,
1143812034f1SHariprasad Shenai 		0x23550, 0x23554,
1144812034f1SHariprasad Shenai 		0x23600, 0x23600,
11458119c018SHariprasad Shenai 		0x23608, 0x2361c,
11468119c018SHariprasad Shenai 		0x23624, 0x23628,
11478119c018SHariprasad Shenai 		0x23630, 0x23634,
11488119c018SHariprasad Shenai 		0x2363c, 0x2363c,
1149812034f1SHariprasad Shenai 		0x23700, 0x2371c,
1150812034f1SHariprasad Shenai 		0x23780, 0x2378c,
11518119c018SHariprasad Shenai 		0x23800, 0x23818,
11528119c018SHariprasad Shenai 		0x23820, 0x23828,
11538119c018SHariprasad Shenai 		0x23830, 0x23848,
11548119c018SHariprasad Shenai 		0x23850, 0x23854,
11558119c018SHariprasad Shenai 		0x23860, 0x23868,
11568119c018SHariprasad Shenai 		0x23870, 0x23870,
11578119c018SHariprasad Shenai 		0x23878, 0x23898,
11588119c018SHariprasad Shenai 		0x238a0, 0x238a8,
11598119c018SHariprasad Shenai 		0x238b0, 0x238c8,
11608119c018SHariprasad Shenai 		0x238d0, 0x238d4,
11618119c018SHariprasad Shenai 		0x238e0, 0x238e8,
11628119c018SHariprasad Shenai 		0x238f0, 0x238f0,
11638119c018SHariprasad Shenai 		0x238f8, 0x23a18,
11648119c018SHariprasad Shenai 		0x23a20, 0x23a28,
11658119c018SHariprasad Shenai 		0x23a30, 0x23a48,
11668119c018SHariprasad Shenai 		0x23a50, 0x23a54,
11678119c018SHariprasad Shenai 		0x23a60, 0x23a68,
11688119c018SHariprasad Shenai 		0x23a70, 0x23a70,
11698119c018SHariprasad Shenai 		0x23a78, 0x23a98,
11708119c018SHariprasad Shenai 		0x23aa0, 0x23aa8,
11718119c018SHariprasad Shenai 		0x23ab0, 0x23ac8,
11728119c018SHariprasad Shenai 		0x23ad0, 0x23ad4,
11738119c018SHariprasad Shenai 		0x23ae0, 0x23ae8,
11748119c018SHariprasad Shenai 		0x23af0, 0x23af0,
11758119c018SHariprasad Shenai 		0x23af8, 0x23c18,
11768119c018SHariprasad Shenai 		0x23c20, 0x23c20,
11778119c018SHariprasad Shenai 		0x23c28, 0x23c30,
11788119c018SHariprasad Shenai 		0x23c38, 0x23c38,
11798119c018SHariprasad Shenai 		0x23c80, 0x23c98,
11808119c018SHariprasad Shenai 		0x23ca0, 0x23ca8,
11818119c018SHariprasad Shenai 		0x23cb0, 0x23cc8,
11828119c018SHariprasad Shenai 		0x23cd0, 0x23cd4,
11838119c018SHariprasad Shenai 		0x23ce0, 0x23ce8,
11848119c018SHariprasad Shenai 		0x23cf0, 0x23cf0,
11858119c018SHariprasad Shenai 		0x23cf8, 0x23d7c,
1186812034f1SHariprasad Shenai 		0x23e00, 0x23e04,
1187812034f1SHariprasad Shenai 		0x24000, 0x2402c,
1188812034f1SHariprasad Shenai 		0x24100, 0x2413c,
11898119c018SHariprasad Shenai 		0x24190, 0x241a0,
11908119c018SHariprasad Shenai 		0x241a8, 0x241b8,
11918119c018SHariprasad Shenai 		0x241c4, 0x241c8,
1192812034f1SHariprasad Shenai 		0x24200, 0x24318,
11938119c018SHariprasad Shenai 		0x24400, 0x244b4,
11948119c018SHariprasad Shenai 		0x244c0, 0x24528,
1195812034f1SHariprasad Shenai 		0x24540, 0x24614,
1196812034f1SHariprasad Shenai 		0x25000, 0x25040,
1197812034f1SHariprasad Shenai 		0x2504c, 0x25060,
1198812034f1SHariprasad Shenai 		0x250c0, 0x250ec,
1199812034f1SHariprasad Shenai 		0x25200, 0x25268,
1200812034f1SHariprasad Shenai 		0x25270, 0x25284,
1201812034f1SHariprasad Shenai 		0x252fc, 0x25388,
1202812034f1SHariprasad Shenai 		0x25400, 0x25404,
12038119c018SHariprasad Shenai 		0x25500, 0x25500,
12048119c018SHariprasad Shenai 		0x25510, 0x25518,
12058119c018SHariprasad Shenai 		0x2552c, 0x25530,
12068119c018SHariprasad Shenai 		0x2553c, 0x2553c,
1207812034f1SHariprasad Shenai 		0x25550, 0x25554,
1208812034f1SHariprasad Shenai 		0x25600, 0x25600,
12098119c018SHariprasad Shenai 		0x25608, 0x2561c,
12108119c018SHariprasad Shenai 		0x25624, 0x25628,
12118119c018SHariprasad Shenai 		0x25630, 0x25634,
12128119c018SHariprasad Shenai 		0x2563c, 0x2563c,
1213812034f1SHariprasad Shenai 		0x25700, 0x2571c,
1214812034f1SHariprasad Shenai 		0x25780, 0x2578c,
12158119c018SHariprasad Shenai 		0x25800, 0x25818,
12168119c018SHariprasad Shenai 		0x25820, 0x25828,
12178119c018SHariprasad Shenai 		0x25830, 0x25848,
12188119c018SHariprasad Shenai 		0x25850, 0x25854,
12198119c018SHariprasad Shenai 		0x25860, 0x25868,
12208119c018SHariprasad Shenai 		0x25870, 0x25870,
12218119c018SHariprasad Shenai 		0x25878, 0x25898,
12228119c018SHariprasad Shenai 		0x258a0, 0x258a8,
12238119c018SHariprasad Shenai 		0x258b0, 0x258c8,
12248119c018SHariprasad Shenai 		0x258d0, 0x258d4,
12258119c018SHariprasad Shenai 		0x258e0, 0x258e8,
12268119c018SHariprasad Shenai 		0x258f0, 0x258f0,
12278119c018SHariprasad Shenai 		0x258f8, 0x25a18,
12288119c018SHariprasad Shenai 		0x25a20, 0x25a28,
12298119c018SHariprasad Shenai 		0x25a30, 0x25a48,
12308119c018SHariprasad Shenai 		0x25a50, 0x25a54,
12318119c018SHariprasad Shenai 		0x25a60, 0x25a68,
12328119c018SHariprasad Shenai 		0x25a70, 0x25a70,
12338119c018SHariprasad Shenai 		0x25a78, 0x25a98,
12348119c018SHariprasad Shenai 		0x25aa0, 0x25aa8,
12358119c018SHariprasad Shenai 		0x25ab0, 0x25ac8,
12368119c018SHariprasad Shenai 		0x25ad0, 0x25ad4,
12378119c018SHariprasad Shenai 		0x25ae0, 0x25ae8,
12388119c018SHariprasad Shenai 		0x25af0, 0x25af0,
12398119c018SHariprasad Shenai 		0x25af8, 0x25c18,
12408119c018SHariprasad Shenai 		0x25c20, 0x25c20,
12418119c018SHariprasad Shenai 		0x25c28, 0x25c30,
12428119c018SHariprasad Shenai 		0x25c38, 0x25c38,
12438119c018SHariprasad Shenai 		0x25c80, 0x25c98,
12448119c018SHariprasad Shenai 		0x25ca0, 0x25ca8,
12458119c018SHariprasad Shenai 		0x25cb0, 0x25cc8,
12468119c018SHariprasad Shenai 		0x25cd0, 0x25cd4,
12478119c018SHariprasad Shenai 		0x25ce0, 0x25ce8,
12488119c018SHariprasad Shenai 		0x25cf0, 0x25cf0,
12498119c018SHariprasad Shenai 		0x25cf8, 0x25d7c,
1250812034f1SHariprasad Shenai 		0x25e00, 0x25e04,
1251812034f1SHariprasad Shenai 		0x26000, 0x2602c,
1252812034f1SHariprasad Shenai 		0x26100, 0x2613c,
12538119c018SHariprasad Shenai 		0x26190, 0x261a0,
12548119c018SHariprasad Shenai 		0x261a8, 0x261b8,
12558119c018SHariprasad Shenai 		0x261c4, 0x261c8,
1256812034f1SHariprasad Shenai 		0x26200, 0x26318,
12578119c018SHariprasad Shenai 		0x26400, 0x264b4,
12588119c018SHariprasad Shenai 		0x264c0, 0x26528,
1259812034f1SHariprasad Shenai 		0x26540, 0x26614,
1260812034f1SHariprasad Shenai 		0x27000, 0x27040,
1261812034f1SHariprasad Shenai 		0x2704c, 0x27060,
1262812034f1SHariprasad Shenai 		0x270c0, 0x270ec,
1263812034f1SHariprasad Shenai 		0x27200, 0x27268,
1264812034f1SHariprasad Shenai 		0x27270, 0x27284,
1265812034f1SHariprasad Shenai 		0x272fc, 0x27388,
1266812034f1SHariprasad Shenai 		0x27400, 0x27404,
12678119c018SHariprasad Shenai 		0x27500, 0x27500,
12688119c018SHariprasad Shenai 		0x27510, 0x27518,
12698119c018SHariprasad Shenai 		0x2752c, 0x27530,
12708119c018SHariprasad Shenai 		0x2753c, 0x2753c,
1271812034f1SHariprasad Shenai 		0x27550, 0x27554,
1272812034f1SHariprasad Shenai 		0x27600, 0x27600,
12738119c018SHariprasad Shenai 		0x27608, 0x2761c,
12748119c018SHariprasad Shenai 		0x27624, 0x27628,
12758119c018SHariprasad Shenai 		0x27630, 0x27634,
12768119c018SHariprasad Shenai 		0x2763c, 0x2763c,
1277812034f1SHariprasad Shenai 		0x27700, 0x2771c,
1278812034f1SHariprasad Shenai 		0x27780, 0x2778c,
12798119c018SHariprasad Shenai 		0x27800, 0x27818,
12808119c018SHariprasad Shenai 		0x27820, 0x27828,
12818119c018SHariprasad Shenai 		0x27830, 0x27848,
12828119c018SHariprasad Shenai 		0x27850, 0x27854,
12838119c018SHariprasad Shenai 		0x27860, 0x27868,
12848119c018SHariprasad Shenai 		0x27870, 0x27870,
12858119c018SHariprasad Shenai 		0x27878, 0x27898,
12868119c018SHariprasad Shenai 		0x278a0, 0x278a8,
12878119c018SHariprasad Shenai 		0x278b0, 0x278c8,
12888119c018SHariprasad Shenai 		0x278d0, 0x278d4,
12898119c018SHariprasad Shenai 		0x278e0, 0x278e8,
12908119c018SHariprasad Shenai 		0x278f0, 0x278f0,
12918119c018SHariprasad Shenai 		0x278f8, 0x27a18,
12928119c018SHariprasad Shenai 		0x27a20, 0x27a28,
12938119c018SHariprasad Shenai 		0x27a30, 0x27a48,
12948119c018SHariprasad Shenai 		0x27a50, 0x27a54,
12958119c018SHariprasad Shenai 		0x27a60, 0x27a68,
12968119c018SHariprasad Shenai 		0x27a70, 0x27a70,
12978119c018SHariprasad Shenai 		0x27a78, 0x27a98,
12988119c018SHariprasad Shenai 		0x27aa0, 0x27aa8,
12998119c018SHariprasad Shenai 		0x27ab0, 0x27ac8,
13008119c018SHariprasad Shenai 		0x27ad0, 0x27ad4,
13018119c018SHariprasad Shenai 		0x27ae0, 0x27ae8,
13028119c018SHariprasad Shenai 		0x27af0, 0x27af0,
13038119c018SHariprasad Shenai 		0x27af8, 0x27c18,
13048119c018SHariprasad Shenai 		0x27c20, 0x27c20,
13058119c018SHariprasad Shenai 		0x27c28, 0x27c30,
13068119c018SHariprasad Shenai 		0x27c38, 0x27c38,
13078119c018SHariprasad Shenai 		0x27c80, 0x27c98,
13088119c018SHariprasad Shenai 		0x27ca0, 0x27ca8,
13098119c018SHariprasad Shenai 		0x27cb0, 0x27cc8,
13108119c018SHariprasad Shenai 		0x27cd0, 0x27cd4,
13118119c018SHariprasad Shenai 		0x27ce0, 0x27ce8,
13128119c018SHariprasad Shenai 		0x27cf0, 0x27cf0,
13138119c018SHariprasad Shenai 		0x27cf8, 0x27d7c,
13149f5ac48dSHariprasad Shenai 		0x27e00, 0x27e04,
1315812034f1SHariprasad Shenai 	};
1316812034f1SHariprasad Shenai 
1317812034f1SHariprasad Shenai 	static const unsigned int t5_reg_ranges[] = {
13188119c018SHariprasad Shenai 		0x1008, 0x10c0,
13198119c018SHariprasad Shenai 		0x10cc, 0x10f8,
13208119c018SHariprasad Shenai 		0x1100, 0x1100,
13218119c018SHariprasad Shenai 		0x110c, 0x1148,
13228119c018SHariprasad Shenai 		0x1180, 0x1184,
13238119c018SHariprasad Shenai 		0x1190, 0x1194,
13248119c018SHariprasad Shenai 		0x11a0, 0x11a4,
13258119c018SHariprasad Shenai 		0x11b0, 0x11b4,
1326812034f1SHariprasad Shenai 		0x11fc, 0x123c,
1327812034f1SHariprasad Shenai 		0x1280, 0x173c,
1328812034f1SHariprasad Shenai 		0x1800, 0x18fc,
1329812034f1SHariprasad Shenai 		0x3000, 0x3028,
13308119c018SHariprasad Shenai 		0x3060, 0x30b0,
13318119c018SHariprasad Shenai 		0x30b8, 0x30d8,
1332812034f1SHariprasad Shenai 		0x30e0, 0x30fc,
1333812034f1SHariprasad Shenai 		0x3140, 0x357c,
1334812034f1SHariprasad Shenai 		0x35a8, 0x35cc,
1335812034f1SHariprasad Shenai 		0x35ec, 0x35ec,
1336812034f1SHariprasad Shenai 		0x3600, 0x5624,
13378119c018SHariprasad Shenai 		0x56cc, 0x56ec,
13388119c018SHariprasad Shenai 		0x56f4, 0x5720,
13398119c018SHariprasad Shenai 		0x5728, 0x575c,
1340812034f1SHariprasad Shenai 		0x580c, 0x5814,
13418119c018SHariprasad Shenai 		0x5890, 0x589c,
13428119c018SHariprasad Shenai 		0x58a4, 0x58ac,
13438119c018SHariprasad Shenai 		0x58b8, 0x58bc,
13448119c018SHariprasad Shenai 		0x5940, 0x59c8,
13458119c018SHariprasad Shenai 		0x59d0, 0x59dc,
1346812034f1SHariprasad Shenai 		0x59fc, 0x5a18,
13478119c018SHariprasad Shenai 		0x5a60, 0x5a70,
13488119c018SHariprasad Shenai 		0x5a80, 0x5a9c,
13499f5ac48dSHariprasad Shenai 		0x5b94, 0x5bfc,
13508119c018SHariprasad Shenai 		0x6000, 0x6020,
13518119c018SHariprasad Shenai 		0x6028, 0x6040,
13528119c018SHariprasad Shenai 		0x6058, 0x609c,
13538119c018SHariprasad Shenai 		0x60a8, 0x614c,
1354812034f1SHariprasad Shenai 		0x7700, 0x7798,
1355812034f1SHariprasad Shenai 		0x77c0, 0x78fc,
13568119c018SHariprasad Shenai 		0x7b00, 0x7b58,
13578119c018SHariprasad Shenai 		0x7b60, 0x7b84,
13588119c018SHariprasad Shenai 		0x7b8c, 0x7c54,
13598119c018SHariprasad Shenai 		0x7d00, 0x7d38,
13608119c018SHariprasad Shenai 		0x7d40, 0x7d80,
13618119c018SHariprasad Shenai 		0x7d8c, 0x7ddc,
13628119c018SHariprasad Shenai 		0x7de4, 0x7e04,
13638119c018SHariprasad Shenai 		0x7e10, 0x7e1c,
13648119c018SHariprasad Shenai 		0x7e24, 0x7e38,
13658119c018SHariprasad Shenai 		0x7e40, 0x7e44,
13668119c018SHariprasad Shenai 		0x7e4c, 0x7e78,
13678119c018SHariprasad Shenai 		0x7e80, 0x7edc,
13688119c018SHariprasad Shenai 		0x7ee8, 0x7efc,
1369812034f1SHariprasad Shenai 		0x8dc0, 0x8de0,
13708119c018SHariprasad Shenai 		0x8df8, 0x8e04,
13718119c018SHariprasad Shenai 		0x8e10, 0x8e84,
1372812034f1SHariprasad Shenai 		0x8ea0, 0x8f84,
13738119c018SHariprasad Shenai 		0x8fc0, 0x9058,
13748119c018SHariprasad Shenai 		0x9060, 0x9060,
13758119c018SHariprasad Shenai 		0x9068, 0x90f8,
13768119c018SHariprasad Shenai 		0x9400, 0x9408,
13778119c018SHariprasad Shenai 		0x9410, 0x9470,
13788119c018SHariprasad Shenai 		0x9600, 0x9600,
13798119c018SHariprasad Shenai 		0x9608, 0x9638,
13808119c018SHariprasad Shenai 		0x9640, 0x96f4,
1381812034f1SHariprasad Shenai 		0x9800, 0x9808,
1382724d0215SShahjada Abul Husain 		0x9810, 0x9864,
1383812034f1SHariprasad Shenai 		0x9c00, 0x9c6c,
1384812034f1SHariprasad Shenai 		0x9c80, 0x9cec,
1385812034f1SHariprasad Shenai 		0x9d00, 0x9d6c,
1386812034f1SHariprasad Shenai 		0x9d80, 0x9dec,
1387812034f1SHariprasad Shenai 		0x9e00, 0x9e6c,
1388812034f1SHariprasad Shenai 		0x9e80, 0x9eec,
1389812034f1SHariprasad Shenai 		0x9f00, 0x9f6c,
1390812034f1SHariprasad Shenai 		0x9f80, 0xa020,
1391724d0215SShahjada Abul Husain 		0xd000, 0xd004,
13928119c018SHariprasad Shenai 		0xd010, 0xd03c,
1393812034f1SHariprasad Shenai 		0xdfc0, 0xdfe0,
13948119c018SHariprasad Shenai 		0xe000, 0x1106c,
13958119c018SHariprasad Shenai 		0x11074, 0x11088,
13968119c018SHariprasad Shenai 		0x1109c, 0x1117c,
1397812034f1SHariprasad Shenai 		0x11190, 0x11204,
1398812034f1SHariprasad Shenai 		0x19040, 0x1906c,
1399812034f1SHariprasad Shenai 		0x19078, 0x19080,
14008119c018SHariprasad Shenai 		0x1908c, 0x190e8,
14018119c018SHariprasad Shenai 		0x190f0, 0x190f8,
14028119c018SHariprasad Shenai 		0x19100, 0x19110,
14038119c018SHariprasad Shenai 		0x19120, 0x19124,
14048119c018SHariprasad Shenai 		0x19150, 0x19194,
14058119c018SHariprasad Shenai 		0x1919c, 0x191b0,
1406812034f1SHariprasad Shenai 		0x191d0, 0x191e8,
1407812034f1SHariprasad Shenai 		0x19238, 0x19290,
14088119c018SHariprasad Shenai 		0x193f8, 0x19428,
14098119c018SHariprasad Shenai 		0x19430, 0x19444,
14108119c018SHariprasad Shenai 		0x1944c, 0x1946c,
14118119c018SHariprasad Shenai 		0x19474, 0x19474,
1412812034f1SHariprasad Shenai 		0x19490, 0x194cc,
1413812034f1SHariprasad Shenai 		0x194f0, 0x194f8,
14148119c018SHariprasad Shenai 		0x19c00, 0x19c08,
14158119c018SHariprasad Shenai 		0x19c10, 0x19c60,
14168119c018SHariprasad Shenai 		0x19c94, 0x19ce4,
14178119c018SHariprasad Shenai 		0x19cf0, 0x19d40,
14188119c018SHariprasad Shenai 		0x19d50, 0x19d94,
14198119c018SHariprasad Shenai 		0x19da0, 0x19de8,
14208119c018SHariprasad Shenai 		0x19df0, 0x19e10,
14218119c018SHariprasad Shenai 		0x19e50, 0x19e90,
14228119c018SHariprasad Shenai 		0x19ea0, 0x19f24,
14238119c018SHariprasad Shenai 		0x19f34, 0x19f34,
1424812034f1SHariprasad Shenai 		0x19f40, 0x19f50,
14258119c018SHariprasad Shenai 		0x19f90, 0x19fb4,
14268119c018SHariprasad Shenai 		0x19fc4, 0x19fe4,
14278119c018SHariprasad Shenai 		0x1a000, 0x1a004,
14288119c018SHariprasad Shenai 		0x1a010, 0x1a06c,
14298119c018SHariprasad Shenai 		0x1a0b0, 0x1a0e4,
14308119c018SHariprasad Shenai 		0x1a0ec, 0x1a0f8,
14318119c018SHariprasad Shenai 		0x1a100, 0x1a108,
1432724d0215SShahjada Abul Husain 		0x1a114, 0x1a130,
1433724d0215SShahjada Abul Husain 		0x1a138, 0x1a1c4,
1434812034f1SHariprasad Shenai 		0x1a1fc, 0x1a1fc,
1435812034f1SHariprasad Shenai 		0x1e008, 0x1e00c,
14368119c018SHariprasad Shenai 		0x1e040, 0x1e044,
14378119c018SHariprasad Shenai 		0x1e04c, 0x1e04c,
1438812034f1SHariprasad Shenai 		0x1e284, 0x1e290,
1439812034f1SHariprasad Shenai 		0x1e2c0, 0x1e2c0,
1440812034f1SHariprasad Shenai 		0x1e2e0, 0x1e2e0,
1441812034f1SHariprasad Shenai 		0x1e300, 0x1e384,
1442812034f1SHariprasad Shenai 		0x1e3c0, 0x1e3c8,
1443812034f1SHariprasad Shenai 		0x1e408, 0x1e40c,
14448119c018SHariprasad Shenai 		0x1e440, 0x1e444,
14458119c018SHariprasad Shenai 		0x1e44c, 0x1e44c,
1446812034f1SHariprasad Shenai 		0x1e684, 0x1e690,
1447812034f1SHariprasad Shenai 		0x1e6c0, 0x1e6c0,
1448812034f1SHariprasad Shenai 		0x1e6e0, 0x1e6e0,
1449812034f1SHariprasad Shenai 		0x1e700, 0x1e784,
1450812034f1SHariprasad Shenai 		0x1e7c0, 0x1e7c8,
1451812034f1SHariprasad Shenai 		0x1e808, 0x1e80c,
14528119c018SHariprasad Shenai 		0x1e840, 0x1e844,
14538119c018SHariprasad Shenai 		0x1e84c, 0x1e84c,
1454812034f1SHariprasad Shenai 		0x1ea84, 0x1ea90,
1455812034f1SHariprasad Shenai 		0x1eac0, 0x1eac0,
1456812034f1SHariprasad Shenai 		0x1eae0, 0x1eae0,
1457812034f1SHariprasad Shenai 		0x1eb00, 0x1eb84,
1458812034f1SHariprasad Shenai 		0x1ebc0, 0x1ebc8,
1459812034f1SHariprasad Shenai 		0x1ec08, 0x1ec0c,
14608119c018SHariprasad Shenai 		0x1ec40, 0x1ec44,
14618119c018SHariprasad Shenai 		0x1ec4c, 0x1ec4c,
1462812034f1SHariprasad Shenai 		0x1ee84, 0x1ee90,
1463812034f1SHariprasad Shenai 		0x1eec0, 0x1eec0,
1464812034f1SHariprasad Shenai 		0x1eee0, 0x1eee0,
1465812034f1SHariprasad Shenai 		0x1ef00, 0x1ef84,
1466812034f1SHariprasad Shenai 		0x1efc0, 0x1efc8,
1467812034f1SHariprasad Shenai 		0x1f008, 0x1f00c,
14688119c018SHariprasad Shenai 		0x1f040, 0x1f044,
14698119c018SHariprasad Shenai 		0x1f04c, 0x1f04c,
1470812034f1SHariprasad Shenai 		0x1f284, 0x1f290,
1471812034f1SHariprasad Shenai 		0x1f2c0, 0x1f2c0,
1472812034f1SHariprasad Shenai 		0x1f2e0, 0x1f2e0,
1473812034f1SHariprasad Shenai 		0x1f300, 0x1f384,
1474812034f1SHariprasad Shenai 		0x1f3c0, 0x1f3c8,
1475812034f1SHariprasad Shenai 		0x1f408, 0x1f40c,
14768119c018SHariprasad Shenai 		0x1f440, 0x1f444,
14778119c018SHariprasad Shenai 		0x1f44c, 0x1f44c,
1478812034f1SHariprasad Shenai 		0x1f684, 0x1f690,
1479812034f1SHariprasad Shenai 		0x1f6c0, 0x1f6c0,
1480812034f1SHariprasad Shenai 		0x1f6e0, 0x1f6e0,
1481812034f1SHariprasad Shenai 		0x1f700, 0x1f784,
1482812034f1SHariprasad Shenai 		0x1f7c0, 0x1f7c8,
1483812034f1SHariprasad Shenai 		0x1f808, 0x1f80c,
14848119c018SHariprasad Shenai 		0x1f840, 0x1f844,
14858119c018SHariprasad Shenai 		0x1f84c, 0x1f84c,
1486812034f1SHariprasad Shenai 		0x1fa84, 0x1fa90,
1487812034f1SHariprasad Shenai 		0x1fac0, 0x1fac0,
1488812034f1SHariprasad Shenai 		0x1fae0, 0x1fae0,
1489812034f1SHariprasad Shenai 		0x1fb00, 0x1fb84,
1490812034f1SHariprasad Shenai 		0x1fbc0, 0x1fbc8,
1491812034f1SHariprasad Shenai 		0x1fc08, 0x1fc0c,
14928119c018SHariprasad Shenai 		0x1fc40, 0x1fc44,
14938119c018SHariprasad Shenai 		0x1fc4c, 0x1fc4c,
1494812034f1SHariprasad Shenai 		0x1fe84, 0x1fe90,
1495812034f1SHariprasad Shenai 		0x1fec0, 0x1fec0,
1496812034f1SHariprasad Shenai 		0x1fee0, 0x1fee0,
1497812034f1SHariprasad Shenai 		0x1ff00, 0x1ff84,
1498812034f1SHariprasad Shenai 		0x1ffc0, 0x1ffc8,
1499812034f1SHariprasad Shenai 		0x30000, 0x30030,
1500812034f1SHariprasad Shenai 		0x30100, 0x30144,
15018119c018SHariprasad Shenai 		0x30190, 0x301a0,
15028119c018SHariprasad Shenai 		0x301a8, 0x301b8,
15038119c018SHariprasad Shenai 		0x301c4, 0x301c8,
15048119c018SHariprasad Shenai 		0x301d0, 0x301d0,
1505812034f1SHariprasad Shenai 		0x30200, 0x30318,
15068119c018SHariprasad Shenai 		0x30400, 0x304b4,
15078119c018SHariprasad Shenai 		0x304c0, 0x3052c,
1508812034f1SHariprasad Shenai 		0x30540, 0x3061c,
15098119c018SHariprasad Shenai 		0x30800, 0x30828,
15108119c018SHariprasad Shenai 		0x30834, 0x30834,
1511812034f1SHariprasad Shenai 		0x308c0, 0x30908,
1512812034f1SHariprasad Shenai 		0x30910, 0x309ac,
15138119c018SHariprasad Shenai 		0x30a00, 0x30a14,
15148119c018SHariprasad Shenai 		0x30a1c, 0x30a2c,
1515812034f1SHariprasad Shenai 		0x30a44, 0x30a50,
15168119c018SHariprasad Shenai 		0x30a74, 0x30a74,
15178119c018SHariprasad Shenai 		0x30a7c, 0x30afc,
15188119c018SHariprasad Shenai 		0x30b08, 0x30c24,
15199f5ac48dSHariprasad Shenai 		0x30d00, 0x30d00,
1520812034f1SHariprasad Shenai 		0x30d08, 0x30d14,
1521812034f1SHariprasad Shenai 		0x30d1c, 0x30d20,
15228119c018SHariprasad Shenai 		0x30d3c, 0x30d3c,
15238119c018SHariprasad Shenai 		0x30d48, 0x30d50,
1524812034f1SHariprasad Shenai 		0x31200, 0x3120c,
1525812034f1SHariprasad Shenai 		0x31220, 0x31220,
1526812034f1SHariprasad Shenai 		0x31240, 0x31240,
15279f5ac48dSHariprasad Shenai 		0x31600, 0x3160c,
1528812034f1SHariprasad Shenai 		0x31a00, 0x31a1c,
15299f5ac48dSHariprasad Shenai 		0x31e00, 0x31e20,
1530812034f1SHariprasad Shenai 		0x31e38, 0x31e3c,
1531812034f1SHariprasad Shenai 		0x31e80, 0x31e80,
1532812034f1SHariprasad Shenai 		0x31e88, 0x31ea8,
1533812034f1SHariprasad Shenai 		0x31eb0, 0x31eb4,
1534812034f1SHariprasad Shenai 		0x31ec8, 0x31ed4,
1535812034f1SHariprasad Shenai 		0x31fb8, 0x32004,
15369f5ac48dSHariprasad Shenai 		0x32200, 0x32200,
15379f5ac48dSHariprasad Shenai 		0x32208, 0x32240,
15389f5ac48dSHariprasad Shenai 		0x32248, 0x32280,
15399f5ac48dSHariprasad Shenai 		0x32288, 0x322c0,
15409f5ac48dSHariprasad Shenai 		0x322c8, 0x322fc,
1541812034f1SHariprasad Shenai 		0x32600, 0x32630,
1542812034f1SHariprasad Shenai 		0x32a00, 0x32abc,
15438119c018SHariprasad Shenai 		0x32b00, 0x32b10,
15448119c018SHariprasad Shenai 		0x32b20, 0x32b30,
15458119c018SHariprasad Shenai 		0x32b40, 0x32b50,
15468119c018SHariprasad Shenai 		0x32b60, 0x32b70,
15478119c018SHariprasad Shenai 		0x33000, 0x33028,
15488119c018SHariprasad Shenai 		0x33030, 0x33048,
15498119c018SHariprasad Shenai 		0x33060, 0x33068,
15508119c018SHariprasad Shenai 		0x33070, 0x3309c,
15518119c018SHariprasad Shenai 		0x330f0, 0x33128,
15528119c018SHariprasad Shenai 		0x33130, 0x33148,
15538119c018SHariprasad Shenai 		0x33160, 0x33168,
15548119c018SHariprasad Shenai 		0x33170, 0x3319c,
15558119c018SHariprasad Shenai 		0x331f0, 0x33238,
15568119c018SHariprasad Shenai 		0x33240, 0x33240,
15578119c018SHariprasad Shenai 		0x33248, 0x33250,
15588119c018SHariprasad Shenai 		0x3325c, 0x33264,
15598119c018SHariprasad Shenai 		0x33270, 0x332b8,
15608119c018SHariprasad Shenai 		0x332c0, 0x332e4,
15618119c018SHariprasad Shenai 		0x332f8, 0x33338,
15628119c018SHariprasad Shenai 		0x33340, 0x33340,
15638119c018SHariprasad Shenai 		0x33348, 0x33350,
15648119c018SHariprasad Shenai 		0x3335c, 0x33364,
15658119c018SHariprasad Shenai 		0x33370, 0x333b8,
15668119c018SHariprasad Shenai 		0x333c0, 0x333e4,
15678119c018SHariprasad Shenai 		0x333f8, 0x33428,
15688119c018SHariprasad Shenai 		0x33430, 0x33448,
15698119c018SHariprasad Shenai 		0x33460, 0x33468,
15708119c018SHariprasad Shenai 		0x33470, 0x3349c,
15718119c018SHariprasad Shenai 		0x334f0, 0x33528,
15728119c018SHariprasad Shenai 		0x33530, 0x33548,
15738119c018SHariprasad Shenai 		0x33560, 0x33568,
15748119c018SHariprasad Shenai 		0x33570, 0x3359c,
15758119c018SHariprasad Shenai 		0x335f0, 0x33638,
15768119c018SHariprasad Shenai 		0x33640, 0x33640,
15778119c018SHariprasad Shenai 		0x33648, 0x33650,
15788119c018SHariprasad Shenai 		0x3365c, 0x33664,
15798119c018SHariprasad Shenai 		0x33670, 0x336b8,
15808119c018SHariprasad Shenai 		0x336c0, 0x336e4,
15818119c018SHariprasad Shenai 		0x336f8, 0x33738,
15828119c018SHariprasad Shenai 		0x33740, 0x33740,
15838119c018SHariprasad Shenai 		0x33748, 0x33750,
15848119c018SHariprasad Shenai 		0x3375c, 0x33764,
15858119c018SHariprasad Shenai 		0x33770, 0x337b8,
15868119c018SHariprasad Shenai 		0x337c0, 0x337e4,
1587812034f1SHariprasad Shenai 		0x337f8, 0x337fc,
1588812034f1SHariprasad Shenai 		0x33814, 0x33814,
1589812034f1SHariprasad Shenai 		0x3382c, 0x3382c,
1590812034f1SHariprasad Shenai 		0x33880, 0x3388c,
1591812034f1SHariprasad Shenai 		0x338e8, 0x338ec,
15928119c018SHariprasad Shenai 		0x33900, 0x33928,
15938119c018SHariprasad Shenai 		0x33930, 0x33948,
15948119c018SHariprasad Shenai 		0x33960, 0x33968,
15958119c018SHariprasad Shenai 		0x33970, 0x3399c,
15968119c018SHariprasad Shenai 		0x339f0, 0x33a38,
15978119c018SHariprasad Shenai 		0x33a40, 0x33a40,
15988119c018SHariprasad Shenai 		0x33a48, 0x33a50,
15998119c018SHariprasad Shenai 		0x33a5c, 0x33a64,
16008119c018SHariprasad Shenai 		0x33a70, 0x33ab8,
16018119c018SHariprasad Shenai 		0x33ac0, 0x33ae4,
1602812034f1SHariprasad Shenai 		0x33af8, 0x33b10,
1603812034f1SHariprasad Shenai 		0x33b28, 0x33b28,
1604812034f1SHariprasad Shenai 		0x33b3c, 0x33b50,
1605812034f1SHariprasad Shenai 		0x33bf0, 0x33c10,
1606812034f1SHariprasad Shenai 		0x33c28, 0x33c28,
1607812034f1SHariprasad Shenai 		0x33c3c, 0x33c50,
1608812034f1SHariprasad Shenai 		0x33cf0, 0x33cfc,
1609812034f1SHariprasad Shenai 		0x34000, 0x34030,
1610812034f1SHariprasad Shenai 		0x34100, 0x34144,
16118119c018SHariprasad Shenai 		0x34190, 0x341a0,
16128119c018SHariprasad Shenai 		0x341a8, 0x341b8,
16138119c018SHariprasad Shenai 		0x341c4, 0x341c8,
16148119c018SHariprasad Shenai 		0x341d0, 0x341d0,
1615812034f1SHariprasad Shenai 		0x34200, 0x34318,
16168119c018SHariprasad Shenai 		0x34400, 0x344b4,
16178119c018SHariprasad Shenai 		0x344c0, 0x3452c,
1618812034f1SHariprasad Shenai 		0x34540, 0x3461c,
16198119c018SHariprasad Shenai 		0x34800, 0x34828,
16208119c018SHariprasad Shenai 		0x34834, 0x34834,
1621812034f1SHariprasad Shenai 		0x348c0, 0x34908,
1622812034f1SHariprasad Shenai 		0x34910, 0x349ac,
16238119c018SHariprasad Shenai 		0x34a00, 0x34a14,
16248119c018SHariprasad Shenai 		0x34a1c, 0x34a2c,
1625812034f1SHariprasad Shenai 		0x34a44, 0x34a50,
16268119c018SHariprasad Shenai 		0x34a74, 0x34a74,
16278119c018SHariprasad Shenai 		0x34a7c, 0x34afc,
16288119c018SHariprasad Shenai 		0x34b08, 0x34c24,
16299f5ac48dSHariprasad Shenai 		0x34d00, 0x34d00,
1630812034f1SHariprasad Shenai 		0x34d08, 0x34d14,
1631812034f1SHariprasad Shenai 		0x34d1c, 0x34d20,
16328119c018SHariprasad Shenai 		0x34d3c, 0x34d3c,
16338119c018SHariprasad Shenai 		0x34d48, 0x34d50,
1634812034f1SHariprasad Shenai 		0x35200, 0x3520c,
1635812034f1SHariprasad Shenai 		0x35220, 0x35220,
1636812034f1SHariprasad Shenai 		0x35240, 0x35240,
16379f5ac48dSHariprasad Shenai 		0x35600, 0x3560c,
1638812034f1SHariprasad Shenai 		0x35a00, 0x35a1c,
16399f5ac48dSHariprasad Shenai 		0x35e00, 0x35e20,
1640812034f1SHariprasad Shenai 		0x35e38, 0x35e3c,
1641812034f1SHariprasad Shenai 		0x35e80, 0x35e80,
1642812034f1SHariprasad Shenai 		0x35e88, 0x35ea8,
1643812034f1SHariprasad Shenai 		0x35eb0, 0x35eb4,
1644812034f1SHariprasad Shenai 		0x35ec8, 0x35ed4,
1645812034f1SHariprasad Shenai 		0x35fb8, 0x36004,
16469f5ac48dSHariprasad Shenai 		0x36200, 0x36200,
16479f5ac48dSHariprasad Shenai 		0x36208, 0x36240,
16489f5ac48dSHariprasad Shenai 		0x36248, 0x36280,
16499f5ac48dSHariprasad Shenai 		0x36288, 0x362c0,
16509f5ac48dSHariprasad Shenai 		0x362c8, 0x362fc,
1651812034f1SHariprasad Shenai 		0x36600, 0x36630,
1652812034f1SHariprasad Shenai 		0x36a00, 0x36abc,
16538119c018SHariprasad Shenai 		0x36b00, 0x36b10,
16548119c018SHariprasad Shenai 		0x36b20, 0x36b30,
16558119c018SHariprasad Shenai 		0x36b40, 0x36b50,
16568119c018SHariprasad Shenai 		0x36b60, 0x36b70,
16578119c018SHariprasad Shenai 		0x37000, 0x37028,
16588119c018SHariprasad Shenai 		0x37030, 0x37048,
16598119c018SHariprasad Shenai 		0x37060, 0x37068,
16608119c018SHariprasad Shenai 		0x37070, 0x3709c,
16618119c018SHariprasad Shenai 		0x370f0, 0x37128,
16628119c018SHariprasad Shenai 		0x37130, 0x37148,
16638119c018SHariprasad Shenai 		0x37160, 0x37168,
16648119c018SHariprasad Shenai 		0x37170, 0x3719c,
16658119c018SHariprasad Shenai 		0x371f0, 0x37238,
16668119c018SHariprasad Shenai 		0x37240, 0x37240,
16678119c018SHariprasad Shenai 		0x37248, 0x37250,
16688119c018SHariprasad Shenai 		0x3725c, 0x37264,
16698119c018SHariprasad Shenai 		0x37270, 0x372b8,
16708119c018SHariprasad Shenai 		0x372c0, 0x372e4,
16718119c018SHariprasad Shenai 		0x372f8, 0x37338,
16728119c018SHariprasad Shenai 		0x37340, 0x37340,
16738119c018SHariprasad Shenai 		0x37348, 0x37350,
16748119c018SHariprasad Shenai 		0x3735c, 0x37364,
16758119c018SHariprasad Shenai 		0x37370, 0x373b8,
16768119c018SHariprasad Shenai 		0x373c0, 0x373e4,
16778119c018SHariprasad Shenai 		0x373f8, 0x37428,
16788119c018SHariprasad Shenai 		0x37430, 0x37448,
16798119c018SHariprasad Shenai 		0x37460, 0x37468,
16808119c018SHariprasad Shenai 		0x37470, 0x3749c,
16818119c018SHariprasad Shenai 		0x374f0, 0x37528,
16828119c018SHariprasad Shenai 		0x37530, 0x37548,
16838119c018SHariprasad Shenai 		0x37560, 0x37568,
16848119c018SHariprasad Shenai 		0x37570, 0x3759c,
16858119c018SHariprasad Shenai 		0x375f0, 0x37638,
16868119c018SHariprasad Shenai 		0x37640, 0x37640,
16878119c018SHariprasad Shenai 		0x37648, 0x37650,
16888119c018SHariprasad Shenai 		0x3765c, 0x37664,
16898119c018SHariprasad Shenai 		0x37670, 0x376b8,
16908119c018SHariprasad Shenai 		0x376c0, 0x376e4,
16918119c018SHariprasad Shenai 		0x376f8, 0x37738,
16928119c018SHariprasad Shenai 		0x37740, 0x37740,
16938119c018SHariprasad Shenai 		0x37748, 0x37750,
16948119c018SHariprasad Shenai 		0x3775c, 0x37764,
16958119c018SHariprasad Shenai 		0x37770, 0x377b8,
16968119c018SHariprasad Shenai 		0x377c0, 0x377e4,
1697812034f1SHariprasad Shenai 		0x377f8, 0x377fc,
1698812034f1SHariprasad Shenai 		0x37814, 0x37814,
1699812034f1SHariprasad Shenai 		0x3782c, 0x3782c,
1700812034f1SHariprasad Shenai 		0x37880, 0x3788c,
1701812034f1SHariprasad Shenai 		0x378e8, 0x378ec,
17028119c018SHariprasad Shenai 		0x37900, 0x37928,
17038119c018SHariprasad Shenai 		0x37930, 0x37948,
17048119c018SHariprasad Shenai 		0x37960, 0x37968,
17058119c018SHariprasad Shenai 		0x37970, 0x3799c,
17068119c018SHariprasad Shenai 		0x379f0, 0x37a38,
17078119c018SHariprasad Shenai 		0x37a40, 0x37a40,
17088119c018SHariprasad Shenai 		0x37a48, 0x37a50,
17098119c018SHariprasad Shenai 		0x37a5c, 0x37a64,
17108119c018SHariprasad Shenai 		0x37a70, 0x37ab8,
17118119c018SHariprasad Shenai 		0x37ac0, 0x37ae4,
1712812034f1SHariprasad Shenai 		0x37af8, 0x37b10,
1713812034f1SHariprasad Shenai 		0x37b28, 0x37b28,
1714812034f1SHariprasad Shenai 		0x37b3c, 0x37b50,
1715812034f1SHariprasad Shenai 		0x37bf0, 0x37c10,
1716812034f1SHariprasad Shenai 		0x37c28, 0x37c28,
1717812034f1SHariprasad Shenai 		0x37c3c, 0x37c50,
1718812034f1SHariprasad Shenai 		0x37cf0, 0x37cfc,
1719812034f1SHariprasad Shenai 		0x38000, 0x38030,
1720812034f1SHariprasad Shenai 		0x38100, 0x38144,
17218119c018SHariprasad Shenai 		0x38190, 0x381a0,
17228119c018SHariprasad Shenai 		0x381a8, 0x381b8,
17238119c018SHariprasad Shenai 		0x381c4, 0x381c8,
17248119c018SHariprasad Shenai 		0x381d0, 0x381d0,
1725812034f1SHariprasad Shenai 		0x38200, 0x38318,
17268119c018SHariprasad Shenai 		0x38400, 0x384b4,
17278119c018SHariprasad Shenai 		0x384c0, 0x3852c,
1728812034f1SHariprasad Shenai 		0x38540, 0x3861c,
17298119c018SHariprasad Shenai 		0x38800, 0x38828,
17308119c018SHariprasad Shenai 		0x38834, 0x38834,
1731812034f1SHariprasad Shenai 		0x388c0, 0x38908,
1732812034f1SHariprasad Shenai 		0x38910, 0x389ac,
17338119c018SHariprasad Shenai 		0x38a00, 0x38a14,
17348119c018SHariprasad Shenai 		0x38a1c, 0x38a2c,
1735812034f1SHariprasad Shenai 		0x38a44, 0x38a50,
17368119c018SHariprasad Shenai 		0x38a74, 0x38a74,
17378119c018SHariprasad Shenai 		0x38a7c, 0x38afc,
17388119c018SHariprasad Shenai 		0x38b08, 0x38c24,
17399f5ac48dSHariprasad Shenai 		0x38d00, 0x38d00,
1740812034f1SHariprasad Shenai 		0x38d08, 0x38d14,
1741812034f1SHariprasad Shenai 		0x38d1c, 0x38d20,
17428119c018SHariprasad Shenai 		0x38d3c, 0x38d3c,
17438119c018SHariprasad Shenai 		0x38d48, 0x38d50,
1744812034f1SHariprasad Shenai 		0x39200, 0x3920c,
1745812034f1SHariprasad Shenai 		0x39220, 0x39220,
1746812034f1SHariprasad Shenai 		0x39240, 0x39240,
17479f5ac48dSHariprasad Shenai 		0x39600, 0x3960c,
1748812034f1SHariprasad Shenai 		0x39a00, 0x39a1c,
17499f5ac48dSHariprasad Shenai 		0x39e00, 0x39e20,
1750812034f1SHariprasad Shenai 		0x39e38, 0x39e3c,
1751812034f1SHariprasad Shenai 		0x39e80, 0x39e80,
1752812034f1SHariprasad Shenai 		0x39e88, 0x39ea8,
1753812034f1SHariprasad Shenai 		0x39eb0, 0x39eb4,
1754812034f1SHariprasad Shenai 		0x39ec8, 0x39ed4,
1755812034f1SHariprasad Shenai 		0x39fb8, 0x3a004,
17569f5ac48dSHariprasad Shenai 		0x3a200, 0x3a200,
17579f5ac48dSHariprasad Shenai 		0x3a208, 0x3a240,
17589f5ac48dSHariprasad Shenai 		0x3a248, 0x3a280,
17599f5ac48dSHariprasad Shenai 		0x3a288, 0x3a2c0,
17609f5ac48dSHariprasad Shenai 		0x3a2c8, 0x3a2fc,
1761812034f1SHariprasad Shenai 		0x3a600, 0x3a630,
1762812034f1SHariprasad Shenai 		0x3aa00, 0x3aabc,
17638119c018SHariprasad Shenai 		0x3ab00, 0x3ab10,
17648119c018SHariprasad Shenai 		0x3ab20, 0x3ab30,
17658119c018SHariprasad Shenai 		0x3ab40, 0x3ab50,
17668119c018SHariprasad Shenai 		0x3ab60, 0x3ab70,
17678119c018SHariprasad Shenai 		0x3b000, 0x3b028,
17688119c018SHariprasad Shenai 		0x3b030, 0x3b048,
17698119c018SHariprasad Shenai 		0x3b060, 0x3b068,
17708119c018SHariprasad Shenai 		0x3b070, 0x3b09c,
17718119c018SHariprasad Shenai 		0x3b0f0, 0x3b128,
17728119c018SHariprasad Shenai 		0x3b130, 0x3b148,
17738119c018SHariprasad Shenai 		0x3b160, 0x3b168,
17748119c018SHariprasad Shenai 		0x3b170, 0x3b19c,
17758119c018SHariprasad Shenai 		0x3b1f0, 0x3b238,
17768119c018SHariprasad Shenai 		0x3b240, 0x3b240,
17778119c018SHariprasad Shenai 		0x3b248, 0x3b250,
17788119c018SHariprasad Shenai 		0x3b25c, 0x3b264,
17798119c018SHariprasad Shenai 		0x3b270, 0x3b2b8,
17808119c018SHariprasad Shenai 		0x3b2c0, 0x3b2e4,
17818119c018SHariprasad Shenai 		0x3b2f8, 0x3b338,
17828119c018SHariprasad Shenai 		0x3b340, 0x3b340,
17838119c018SHariprasad Shenai 		0x3b348, 0x3b350,
17848119c018SHariprasad Shenai 		0x3b35c, 0x3b364,
17858119c018SHariprasad Shenai 		0x3b370, 0x3b3b8,
17868119c018SHariprasad Shenai 		0x3b3c0, 0x3b3e4,
17878119c018SHariprasad Shenai 		0x3b3f8, 0x3b428,
17888119c018SHariprasad Shenai 		0x3b430, 0x3b448,
17898119c018SHariprasad Shenai 		0x3b460, 0x3b468,
17908119c018SHariprasad Shenai 		0x3b470, 0x3b49c,
17918119c018SHariprasad Shenai 		0x3b4f0, 0x3b528,
17928119c018SHariprasad Shenai 		0x3b530, 0x3b548,
17938119c018SHariprasad Shenai 		0x3b560, 0x3b568,
17948119c018SHariprasad Shenai 		0x3b570, 0x3b59c,
17958119c018SHariprasad Shenai 		0x3b5f0, 0x3b638,
17968119c018SHariprasad Shenai 		0x3b640, 0x3b640,
17978119c018SHariprasad Shenai 		0x3b648, 0x3b650,
17988119c018SHariprasad Shenai 		0x3b65c, 0x3b664,
17998119c018SHariprasad Shenai 		0x3b670, 0x3b6b8,
18008119c018SHariprasad Shenai 		0x3b6c0, 0x3b6e4,
18018119c018SHariprasad Shenai 		0x3b6f8, 0x3b738,
18028119c018SHariprasad Shenai 		0x3b740, 0x3b740,
18038119c018SHariprasad Shenai 		0x3b748, 0x3b750,
18048119c018SHariprasad Shenai 		0x3b75c, 0x3b764,
18058119c018SHariprasad Shenai 		0x3b770, 0x3b7b8,
18068119c018SHariprasad Shenai 		0x3b7c0, 0x3b7e4,
1807812034f1SHariprasad Shenai 		0x3b7f8, 0x3b7fc,
1808812034f1SHariprasad Shenai 		0x3b814, 0x3b814,
1809812034f1SHariprasad Shenai 		0x3b82c, 0x3b82c,
1810812034f1SHariprasad Shenai 		0x3b880, 0x3b88c,
1811812034f1SHariprasad Shenai 		0x3b8e8, 0x3b8ec,
18128119c018SHariprasad Shenai 		0x3b900, 0x3b928,
18138119c018SHariprasad Shenai 		0x3b930, 0x3b948,
18148119c018SHariprasad Shenai 		0x3b960, 0x3b968,
18158119c018SHariprasad Shenai 		0x3b970, 0x3b99c,
18168119c018SHariprasad Shenai 		0x3b9f0, 0x3ba38,
18178119c018SHariprasad Shenai 		0x3ba40, 0x3ba40,
18188119c018SHariprasad Shenai 		0x3ba48, 0x3ba50,
18198119c018SHariprasad Shenai 		0x3ba5c, 0x3ba64,
18208119c018SHariprasad Shenai 		0x3ba70, 0x3bab8,
18218119c018SHariprasad Shenai 		0x3bac0, 0x3bae4,
1822812034f1SHariprasad Shenai 		0x3baf8, 0x3bb10,
1823812034f1SHariprasad Shenai 		0x3bb28, 0x3bb28,
1824812034f1SHariprasad Shenai 		0x3bb3c, 0x3bb50,
1825812034f1SHariprasad Shenai 		0x3bbf0, 0x3bc10,
1826812034f1SHariprasad Shenai 		0x3bc28, 0x3bc28,
1827812034f1SHariprasad Shenai 		0x3bc3c, 0x3bc50,
1828812034f1SHariprasad Shenai 		0x3bcf0, 0x3bcfc,
1829812034f1SHariprasad Shenai 		0x3c000, 0x3c030,
1830812034f1SHariprasad Shenai 		0x3c100, 0x3c144,
18318119c018SHariprasad Shenai 		0x3c190, 0x3c1a0,
18328119c018SHariprasad Shenai 		0x3c1a8, 0x3c1b8,
18338119c018SHariprasad Shenai 		0x3c1c4, 0x3c1c8,
18348119c018SHariprasad Shenai 		0x3c1d0, 0x3c1d0,
1835812034f1SHariprasad Shenai 		0x3c200, 0x3c318,
18368119c018SHariprasad Shenai 		0x3c400, 0x3c4b4,
18378119c018SHariprasad Shenai 		0x3c4c0, 0x3c52c,
1838812034f1SHariprasad Shenai 		0x3c540, 0x3c61c,
18398119c018SHariprasad Shenai 		0x3c800, 0x3c828,
18408119c018SHariprasad Shenai 		0x3c834, 0x3c834,
1841812034f1SHariprasad Shenai 		0x3c8c0, 0x3c908,
1842812034f1SHariprasad Shenai 		0x3c910, 0x3c9ac,
18438119c018SHariprasad Shenai 		0x3ca00, 0x3ca14,
18448119c018SHariprasad Shenai 		0x3ca1c, 0x3ca2c,
1845812034f1SHariprasad Shenai 		0x3ca44, 0x3ca50,
18468119c018SHariprasad Shenai 		0x3ca74, 0x3ca74,
18478119c018SHariprasad Shenai 		0x3ca7c, 0x3cafc,
18488119c018SHariprasad Shenai 		0x3cb08, 0x3cc24,
18499f5ac48dSHariprasad Shenai 		0x3cd00, 0x3cd00,
1850812034f1SHariprasad Shenai 		0x3cd08, 0x3cd14,
1851812034f1SHariprasad Shenai 		0x3cd1c, 0x3cd20,
18528119c018SHariprasad Shenai 		0x3cd3c, 0x3cd3c,
18538119c018SHariprasad Shenai 		0x3cd48, 0x3cd50,
1854812034f1SHariprasad Shenai 		0x3d200, 0x3d20c,
1855812034f1SHariprasad Shenai 		0x3d220, 0x3d220,
1856812034f1SHariprasad Shenai 		0x3d240, 0x3d240,
18579f5ac48dSHariprasad Shenai 		0x3d600, 0x3d60c,
1858812034f1SHariprasad Shenai 		0x3da00, 0x3da1c,
18599f5ac48dSHariprasad Shenai 		0x3de00, 0x3de20,
1860812034f1SHariprasad Shenai 		0x3de38, 0x3de3c,
1861812034f1SHariprasad Shenai 		0x3de80, 0x3de80,
1862812034f1SHariprasad Shenai 		0x3de88, 0x3dea8,
1863812034f1SHariprasad Shenai 		0x3deb0, 0x3deb4,
1864812034f1SHariprasad Shenai 		0x3dec8, 0x3ded4,
1865812034f1SHariprasad Shenai 		0x3dfb8, 0x3e004,
18669f5ac48dSHariprasad Shenai 		0x3e200, 0x3e200,
18679f5ac48dSHariprasad Shenai 		0x3e208, 0x3e240,
18689f5ac48dSHariprasad Shenai 		0x3e248, 0x3e280,
18699f5ac48dSHariprasad Shenai 		0x3e288, 0x3e2c0,
18709f5ac48dSHariprasad Shenai 		0x3e2c8, 0x3e2fc,
1871812034f1SHariprasad Shenai 		0x3e600, 0x3e630,
1872812034f1SHariprasad Shenai 		0x3ea00, 0x3eabc,
18738119c018SHariprasad Shenai 		0x3eb00, 0x3eb10,
18748119c018SHariprasad Shenai 		0x3eb20, 0x3eb30,
18758119c018SHariprasad Shenai 		0x3eb40, 0x3eb50,
18768119c018SHariprasad Shenai 		0x3eb60, 0x3eb70,
18778119c018SHariprasad Shenai 		0x3f000, 0x3f028,
18788119c018SHariprasad Shenai 		0x3f030, 0x3f048,
18798119c018SHariprasad Shenai 		0x3f060, 0x3f068,
18808119c018SHariprasad Shenai 		0x3f070, 0x3f09c,
18818119c018SHariprasad Shenai 		0x3f0f0, 0x3f128,
18828119c018SHariprasad Shenai 		0x3f130, 0x3f148,
18838119c018SHariprasad Shenai 		0x3f160, 0x3f168,
18848119c018SHariprasad Shenai 		0x3f170, 0x3f19c,
18858119c018SHariprasad Shenai 		0x3f1f0, 0x3f238,
18868119c018SHariprasad Shenai 		0x3f240, 0x3f240,
18878119c018SHariprasad Shenai 		0x3f248, 0x3f250,
18888119c018SHariprasad Shenai 		0x3f25c, 0x3f264,
18898119c018SHariprasad Shenai 		0x3f270, 0x3f2b8,
18908119c018SHariprasad Shenai 		0x3f2c0, 0x3f2e4,
18918119c018SHariprasad Shenai 		0x3f2f8, 0x3f338,
18928119c018SHariprasad Shenai 		0x3f340, 0x3f340,
18938119c018SHariprasad Shenai 		0x3f348, 0x3f350,
18948119c018SHariprasad Shenai 		0x3f35c, 0x3f364,
18958119c018SHariprasad Shenai 		0x3f370, 0x3f3b8,
18968119c018SHariprasad Shenai 		0x3f3c0, 0x3f3e4,
18978119c018SHariprasad Shenai 		0x3f3f8, 0x3f428,
18988119c018SHariprasad Shenai 		0x3f430, 0x3f448,
18998119c018SHariprasad Shenai 		0x3f460, 0x3f468,
19008119c018SHariprasad Shenai 		0x3f470, 0x3f49c,
19018119c018SHariprasad Shenai 		0x3f4f0, 0x3f528,
19028119c018SHariprasad Shenai 		0x3f530, 0x3f548,
19038119c018SHariprasad Shenai 		0x3f560, 0x3f568,
19048119c018SHariprasad Shenai 		0x3f570, 0x3f59c,
19058119c018SHariprasad Shenai 		0x3f5f0, 0x3f638,
19068119c018SHariprasad Shenai 		0x3f640, 0x3f640,
19078119c018SHariprasad Shenai 		0x3f648, 0x3f650,
19088119c018SHariprasad Shenai 		0x3f65c, 0x3f664,
19098119c018SHariprasad Shenai 		0x3f670, 0x3f6b8,
19108119c018SHariprasad Shenai 		0x3f6c0, 0x3f6e4,
19118119c018SHariprasad Shenai 		0x3f6f8, 0x3f738,
19128119c018SHariprasad Shenai 		0x3f740, 0x3f740,
19138119c018SHariprasad Shenai 		0x3f748, 0x3f750,
19148119c018SHariprasad Shenai 		0x3f75c, 0x3f764,
19158119c018SHariprasad Shenai 		0x3f770, 0x3f7b8,
19168119c018SHariprasad Shenai 		0x3f7c0, 0x3f7e4,
1917812034f1SHariprasad Shenai 		0x3f7f8, 0x3f7fc,
1918812034f1SHariprasad Shenai 		0x3f814, 0x3f814,
1919812034f1SHariprasad Shenai 		0x3f82c, 0x3f82c,
1920812034f1SHariprasad Shenai 		0x3f880, 0x3f88c,
1921812034f1SHariprasad Shenai 		0x3f8e8, 0x3f8ec,
19228119c018SHariprasad Shenai 		0x3f900, 0x3f928,
19238119c018SHariprasad Shenai 		0x3f930, 0x3f948,
19248119c018SHariprasad Shenai 		0x3f960, 0x3f968,
19258119c018SHariprasad Shenai 		0x3f970, 0x3f99c,
19268119c018SHariprasad Shenai 		0x3f9f0, 0x3fa38,
19278119c018SHariprasad Shenai 		0x3fa40, 0x3fa40,
19288119c018SHariprasad Shenai 		0x3fa48, 0x3fa50,
19298119c018SHariprasad Shenai 		0x3fa5c, 0x3fa64,
19308119c018SHariprasad Shenai 		0x3fa70, 0x3fab8,
19318119c018SHariprasad Shenai 		0x3fac0, 0x3fae4,
1932812034f1SHariprasad Shenai 		0x3faf8, 0x3fb10,
1933812034f1SHariprasad Shenai 		0x3fb28, 0x3fb28,
1934812034f1SHariprasad Shenai 		0x3fb3c, 0x3fb50,
1935812034f1SHariprasad Shenai 		0x3fbf0, 0x3fc10,
1936812034f1SHariprasad Shenai 		0x3fc28, 0x3fc28,
1937812034f1SHariprasad Shenai 		0x3fc3c, 0x3fc50,
1938812034f1SHariprasad Shenai 		0x3fcf0, 0x3fcfc,
1939812034f1SHariprasad Shenai 		0x40000, 0x4000c,
19408119c018SHariprasad Shenai 		0x40040, 0x40050,
19418119c018SHariprasad Shenai 		0x40060, 0x40068,
19428119c018SHariprasad Shenai 		0x4007c, 0x4008c,
19438119c018SHariprasad Shenai 		0x40094, 0x400b0,
19448119c018SHariprasad Shenai 		0x400c0, 0x40144,
1945812034f1SHariprasad Shenai 		0x40180, 0x4018c,
19468119c018SHariprasad Shenai 		0x40200, 0x40254,
19478119c018SHariprasad Shenai 		0x40260, 0x40264,
19488119c018SHariprasad Shenai 		0x40270, 0x40288,
19498119c018SHariprasad Shenai 		0x40290, 0x40298,
19508119c018SHariprasad Shenai 		0x402ac, 0x402c8,
19518119c018SHariprasad Shenai 		0x402d0, 0x402e0,
19528119c018SHariprasad Shenai 		0x402f0, 0x402f0,
19538119c018SHariprasad Shenai 		0x40300, 0x4033c,
1954812034f1SHariprasad Shenai 		0x403f8, 0x403fc,
1955812034f1SHariprasad Shenai 		0x41304, 0x413c4,
19568119c018SHariprasad Shenai 		0x41400, 0x4140c,
19578119c018SHariprasad Shenai 		0x41414, 0x4141c,
1958812034f1SHariprasad Shenai 		0x41480, 0x414d0,
19598119c018SHariprasad Shenai 		0x44000, 0x44054,
19608119c018SHariprasad Shenai 		0x4405c, 0x44078,
19618119c018SHariprasad Shenai 		0x440c0, 0x44174,
19628119c018SHariprasad Shenai 		0x44180, 0x441ac,
19638119c018SHariprasad Shenai 		0x441b4, 0x441b8,
19648119c018SHariprasad Shenai 		0x441c0, 0x44254,
19658119c018SHariprasad Shenai 		0x4425c, 0x44278,
19668119c018SHariprasad Shenai 		0x442c0, 0x44374,
19678119c018SHariprasad Shenai 		0x44380, 0x443ac,
19688119c018SHariprasad Shenai 		0x443b4, 0x443b8,
19698119c018SHariprasad Shenai 		0x443c0, 0x44454,
19708119c018SHariprasad Shenai 		0x4445c, 0x44478,
19718119c018SHariprasad Shenai 		0x444c0, 0x44574,
19728119c018SHariprasad Shenai 		0x44580, 0x445ac,
19738119c018SHariprasad Shenai 		0x445b4, 0x445b8,
19748119c018SHariprasad Shenai 		0x445c0, 0x44654,
19758119c018SHariprasad Shenai 		0x4465c, 0x44678,
19768119c018SHariprasad Shenai 		0x446c0, 0x44774,
19778119c018SHariprasad Shenai 		0x44780, 0x447ac,
19788119c018SHariprasad Shenai 		0x447b4, 0x447b8,
19798119c018SHariprasad Shenai 		0x447c0, 0x44854,
19808119c018SHariprasad Shenai 		0x4485c, 0x44878,
19818119c018SHariprasad Shenai 		0x448c0, 0x44974,
19828119c018SHariprasad Shenai 		0x44980, 0x449ac,
19838119c018SHariprasad Shenai 		0x449b4, 0x449b8,
19848119c018SHariprasad Shenai 		0x449c0, 0x449fc,
19858119c018SHariprasad Shenai 		0x45000, 0x45004,
19868119c018SHariprasad Shenai 		0x45010, 0x45030,
19878119c018SHariprasad Shenai 		0x45040, 0x45060,
19888119c018SHariprasad Shenai 		0x45068, 0x45068,
1989812034f1SHariprasad Shenai 		0x45080, 0x45084,
1990812034f1SHariprasad Shenai 		0x450a0, 0x450b0,
19918119c018SHariprasad Shenai 		0x45200, 0x45204,
19928119c018SHariprasad Shenai 		0x45210, 0x45230,
19938119c018SHariprasad Shenai 		0x45240, 0x45260,
19948119c018SHariprasad Shenai 		0x45268, 0x45268,
1995812034f1SHariprasad Shenai 		0x45280, 0x45284,
1996812034f1SHariprasad Shenai 		0x452a0, 0x452b0,
1997812034f1SHariprasad Shenai 		0x460c0, 0x460e4,
19988119c018SHariprasad Shenai 		0x47000, 0x4703c,
19998119c018SHariprasad Shenai 		0x47044, 0x4708c,
2000812034f1SHariprasad Shenai 		0x47200, 0x47250,
20018119c018SHariprasad Shenai 		0x47400, 0x47408,
20028119c018SHariprasad Shenai 		0x47414, 0x47420,
2003812034f1SHariprasad Shenai 		0x47600, 0x47618,
2004812034f1SHariprasad Shenai 		0x47800, 0x47814,
2005812034f1SHariprasad Shenai 		0x48000, 0x4800c,
20068119c018SHariprasad Shenai 		0x48040, 0x48050,
20078119c018SHariprasad Shenai 		0x48060, 0x48068,
20088119c018SHariprasad Shenai 		0x4807c, 0x4808c,
20098119c018SHariprasad Shenai 		0x48094, 0x480b0,
20108119c018SHariprasad Shenai 		0x480c0, 0x48144,
2011812034f1SHariprasad Shenai 		0x48180, 0x4818c,
20128119c018SHariprasad Shenai 		0x48200, 0x48254,
20138119c018SHariprasad Shenai 		0x48260, 0x48264,
20148119c018SHariprasad Shenai 		0x48270, 0x48288,
20158119c018SHariprasad Shenai 		0x48290, 0x48298,
20168119c018SHariprasad Shenai 		0x482ac, 0x482c8,
20178119c018SHariprasad Shenai 		0x482d0, 0x482e0,
20188119c018SHariprasad Shenai 		0x482f0, 0x482f0,
20198119c018SHariprasad Shenai 		0x48300, 0x4833c,
2020812034f1SHariprasad Shenai 		0x483f8, 0x483fc,
2021812034f1SHariprasad Shenai 		0x49304, 0x493c4,
20228119c018SHariprasad Shenai 		0x49400, 0x4940c,
20238119c018SHariprasad Shenai 		0x49414, 0x4941c,
2024812034f1SHariprasad Shenai 		0x49480, 0x494d0,
20258119c018SHariprasad Shenai 		0x4c000, 0x4c054,
20268119c018SHariprasad Shenai 		0x4c05c, 0x4c078,
20278119c018SHariprasad Shenai 		0x4c0c0, 0x4c174,
20288119c018SHariprasad Shenai 		0x4c180, 0x4c1ac,
20298119c018SHariprasad Shenai 		0x4c1b4, 0x4c1b8,
20308119c018SHariprasad Shenai 		0x4c1c0, 0x4c254,
20318119c018SHariprasad Shenai 		0x4c25c, 0x4c278,
20328119c018SHariprasad Shenai 		0x4c2c0, 0x4c374,
20338119c018SHariprasad Shenai 		0x4c380, 0x4c3ac,
20348119c018SHariprasad Shenai 		0x4c3b4, 0x4c3b8,
20358119c018SHariprasad Shenai 		0x4c3c0, 0x4c454,
20368119c018SHariprasad Shenai 		0x4c45c, 0x4c478,
20378119c018SHariprasad Shenai 		0x4c4c0, 0x4c574,
20388119c018SHariprasad Shenai 		0x4c580, 0x4c5ac,
20398119c018SHariprasad Shenai 		0x4c5b4, 0x4c5b8,
20408119c018SHariprasad Shenai 		0x4c5c0, 0x4c654,
20418119c018SHariprasad Shenai 		0x4c65c, 0x4c678,
20428119c018SHariprasad Shenai 		0x4c6c0, 0x4c774,
20438119c018SHariprasad Shenai 		0x4c780, 0x4c7ac,
20448119c018SHariprasad Shenai 		0x4c7b4, 0x4c7b8,
20458119c018SHariprasad Shenai 		0x4c7c0, 0x4c854,
20468119c018SHariprasad Shenai 		0x4c85c, 0x4c878,
20478119c018SHariprasad Shenai 		0x4c8c0, 0x4c974,
20488119c018SHariprasad Shenai 		0x4c980, 0x4c9ac,
20498119c018SHariprasad Shenai 		0x4c9b4, 0x4c9b8,
20508119c018SHariprasad Shenai 		0x4c9c0, 0x4c9fc,
20518119c018SHariprasad Shenai 		0x4d000, 0x4d004,
20528119c018SHariprasad Shenai 		0x4d010, 0x4d030,
20538119c018SHariprasad Shenai 		0x4d040, 0x4d060,
20548119c018SHariprasad Shenai 		0x4d068, 0x4d068,
2055812034f1SHariprasad Shenai 		0x4d080, 0x4d084,
2056812034f1SHariprasad Shenai 		0x4d0a0, 0x4d0b0,
20578119c018SHariprasad Shenai 		0x4d200, 0x4d204,
20588119c018SHariprasad Shenai 		0x4d210, 0x4d230,
20598119c018SHariprasad Shenai 		0x4d240, 0x4d260,
20608119c018SHariprasad Shenai 		0x4d268, 0x4d268,
2061812034f1SHariprasad Shenai 		0x4d280, 0x4d284,
2062812034f1SHariprasad Shenai 		0x4d2a0, 0x4d2b0,
2063812034f1SHariprasad Shenai 		0x4e0c0, 0x4e0e4,
20648119c018SHariprasad Shenai 		0x4f000, 0x4f03c,
20658119c018SHariprasad Shenai 		0x4f044, 0x4f08c,
2066812034f1SHariprasad Shenai 		0x4f200, 0x4f250,
20678119c018SHariprasad Shenai 		0x4f400, 0x4f408,
20688119c018SHariprasad Shenai 		0x4f414, 0x4f420,
2069812034f1SHariprasad Shenai 		0x4f600, 0x4f618,
2070812034f1SHariprasad Shenai 		0x4f800, 0x4f814,
20718119c018SHariprasad Shenai 		0x50000, 0x50084,
20728119c018SHariprasad Shenai 		0x50090, 0x500cc,
2073812034f1SHariprasad Shenai 		0x50400, 0x50400,
20748119c018SHariprasad Shenai 		0x50800, 0x50884,
20758119c018SHariprasad Shenai 		0x50890, 0x508cc,
2076812034f1SHariprasad Shenai 		0x50c00, 0x50c00,
2077812034f1SHariprasad Shenai 		0x51000, 0x5101c,
2078812034f1SHariprasad Shenai 		0x51300, 0x51308,
2079812034f1SHariprasad Shenai 	};
2080812034f1SHariprasad Shenai 
2081ab4b583bSHariprasad Shenai 	static const unsigned int t6_reg_ranges[] = {
20828119c018SHariprasad Shenai 		0x1008, 0x101c,
20838119c018SHariprasad Shenai 		0x1024, 0x10a8,
20848119c018SHariprasad Shenai 		0x10b4, 0x10f8,
20858119c018SHariprasad Shenai 		0x1100, 0x1114,
20868119c018SHariprasad Shenai 		0x111c, 0x112c,
20878119c018SHariprasad Shenai 		0x1138, 0x113c,
20888119c018SHariprasad Shenai 		0x1144, 0x114c,
20898119c018SHariprasad Shenai 		0x1180, 0x1184,
20908119c018SHariprasad Shenai 		0x1190, 0x1194,
20918119c018SHariprasad Shenai 		0x11a0, 0x11a4,
20928119c018SHariprasad Shenai 		0x11b0, 0x11b4,
20931bfb3deaSRahul Lakkireddy 		0x11fc, 0x123c,
20941bfb3deaSRahul Lakkireddy 		0x1254, 0x1274,
209504d8980bSArjun Vynipadath 		0x1280, 0x133c,
2096ab4b583bSHariprasad Shenai 		0x1800, 0x18fc,
2097ab4b583bSHariprasad Shenai 		0x3000, 0x302c,
20988119c018SHariprasad Shenai 		0x3060, 0x30b0,
20998119c018SHariprasad Shenai 		0x30b8, 0x30d8,
2100ab4b583bSHariprasad Shenai 		0x30e0, 0x30fc,
2101ab4b583bSHariprasad Shenai 		0x3140, 0x357c,
2102ab4b583bSHariprasad Shenai 		0x35a8, 0x35cc,
2103ab4b583bSHariprasad Shenai 		0x35ec, 0x35ec,
2104ab4b583bSHariprasad Shenai 		0x3600, 0x5624,
21058119c018SHariprasad Shenai 		0x56cc, 0x56ec,
21068119c018SHariprasad Shenai 		0x56f4, 0x5720,
21078119c018SHariprasad Shenai 		0x5728, 0x575c,
2108ab4b583bSHariprasad Shenai 		0x580c, 0x5814,
21098119c018SHariprasad Shenai 		0x5890, 0x589c,
21108119c018SHariprasad Shenai 		0x58a4, 0x58ac,
21118119c018SHariprasad Shenai 		0x58b8, 0x58bc,
2112ab4b583bSHariprasad Shenai 		0x5940, 0x595c,
2113ab4b583bSHariprasad Shenai 		0x5980, 0x598c,
21148119c018SHariprasad Shenai 		0x59b0, 0x59c8,
21158119c018SHariprasad Shenai 		0x59d0, 0x59dc,
2116ab4b583bSHariprasad Shenai 		0x59fc, 0x5a18,
2117ab4b583bSHariprasad Shenai 		0x5a60, 0x5a6c,
21188119c018SHariprasad Shenai 		0x5a80, 0x5a8c,
21198119c018SHariprasad Shenai 		0x5a94, 0x5a9c,
2120ab4b583bSHariprasad Shenai 		0x5b94, 0x5bfc,
21218119c018SHariprasad Shenai 		0x5c10, 0x5e48,
21228119c018SHariprasad Shenai 		0x5e50, 0x5e94,
21238119c018SHariprasad Shenai 		0x5ea0, 0x5eb0,
21248119c018SHariprasad Shenai 		0x5ec0, 0x5ec0,
2125676d6a75SHariprasad Shenai 		0x5ec8, 0x5ed0,
212604d8980bSArjun Vynipadath 		0x5ee0, 0x5ee0,
212704d8980bSArjun Vynipadath 		0x5ef0, 0x5ef0,
212804d8980bSArjun Vynipadath 		0x5f00, 0x5f00,
21298119c018SHariprasad Shenai 		0x6000, 0x6020,
21308119c018SHariprasad Shenai 		0x6028, 0x6040,
21318119c018SHariprasad Shenai 		0x6058, 0x609c,
21328119c018SHariprasad Shenai 		0x60a8, 0x619c,
2133ab4b583bSHariprasad Shenai 		0x7700, 0x7798,
2134ab4b583bSHariprasad Shenai 		0x77c0, 0x7880,
2135ab4b583bSHariprasad Shenai 		0x78cc, 0x78fc,
21368119c018SHariprasad Shenai 		0x7b00, 0x7b58,
21378119c018SHariprasad Shenai 		0x7b60, 0x7b84,
21388119c018SHariprasad Shenai 		0x7b8c, 0x7c54,
21398119c018SHariprasad Shenai 		0x7d00, 0x7d38,
21408119c018SHariprasad Shenai 		0x7d40, 0x7d84,
21418119c018SHariprasad Shenai 		0x7d8c, 0x7ddc,
21428119c018SHariprasad Shenai 		0x7de4, 0x7e04,
21438119c018SHariprasad Shenai 		0x7e10, 0x7e1c,
21448119c018SHariprasad Shenai 		0x7e24, 0x7e38,
21458119c018SHariprasad Shenai 		0x7e40, 0x7e44,
21468119c018SHariprasad Shenai 		0x7e4c, 0x7e78,
21478119c018SHariprasad Shenai 		0x7e80, 0x7edc,
21488119c018SHariprasad Shenai 		0x7ee8, 0x7efc,
2149f109ff11SHariprasad Shenai 		0x8dc0, 0x8de4,
21508119c018SHariprasad Shenai 		0x8df8, 0x8e04,
21518119c018SHariprasad Shenai 		0x8e10, 0x8e84,
2152ab4b583bSHariprasad Shenai 		0x8ea0, 0x8f88,
21538119c018SHariprasad Shenai 		0x8fb8, 0x9058,
21548119c018SHariprasad Shenai 		0x9060, 0x9060,
21558119c018SHariprasad Shenai 		0x9068, 0x90f8,
21568119c018SHariprasad Shenai 		0x9100, 0x9124,
2157ab4b583bSHariprasad Shenai 		0x9400, 0x9470,
21588119c018SHariprasad Shenai 		0x9600, 0x9600,
21598119c018SHariprasad Shenai 		0x9608, 0x9638,
21608119c018SHariprasad Shenai 		0x9640, 0x9704,
21618119c018SHariprasad Shenai 		0x9710, 0x971c,
2162ab4b583bSHariprasad Shenai 		0x9800, 0x9808,
2163724d0215SShahjada Abul Husain 		0x9810, 0x9864,
2164ab4b583bSHariprasad Shenai 		0x9c00, 0x9c6c,
2165ab4b583bSHariprasad Shenai 		0x9c80, 0x9cec,
2166ab4b583bSHariprasad Shenai 		0x9d00, 0x9d6c,
2167ab4b583bSHariprasad Shenai 		0x9d80, 0x9dec,
2168ab4b583bSHariprasad Shenai 		0x9e00, 0x9e6c,
2169ab4b583bSHariprasad Shenai 		0x9e80, 0x9eec,
2170ab4b583bSHariprasad Shenai 		0x9f00, 0x9f6c,
2171ab4b583bSHariprasad Shenai 		0x9f80, 0xa020,
2172724d0215SShahjada Abul Husain 		0xd000, 0xd03c,
21735b4e83e1SHariprasad Shenai 		0xd100, 0xd118,
21748119c018SHariprasad Shenai 		0xd200, 0xd214,
21758119c018SHariprasad Shenai 		0xd220, 0xd234,
21768119c018SHariprasad Shenai 		0xd240, 0xd254,
21778119c018SHariprasad Shenai 		0xd260, 0xd274,
21788119c018SHariprasad Shenai 		0xd280, 0xd294,
21798119c018SHariprasad Shenai 		0xd2a0, 0xd2b4,
21808119c018SHariprasad Shenai 		0xd2c0, 0xd2d4,
21818119c018SHariprasad Shenai 		0xd2e0, 0xd2f4,
21828119c018SHariprasad Shenai 		0xd300, 0xd31c,
2183ab4b583bSHariprasad Shenai 		0xdfc0, 0xdfe0,
2184ab4b583bSHariprasad Shenai 		0xe000, 0xf008,
218504d8980bSArjun Vynipadath 		0xf010, 0xf018,
218604d8980bSArjun Vynipadath 		0xf020, 0xf028,
2187ab4b583bSHariprasad Shenai 		0x11000, 0x11014,
21888119c018SHariprasad Shenai 		0x11048, 0x1106c,
21898119c018SHariprasad Shenai 		0x11074, 0x11088,
21908119c018SHariprasad Shenai 		0x11098, 0x11120,
21918119c018SHariprasad Shenai 		0x1112c, 0x1117c,
21928119c018SHariprasad Shenai 		0x11190, 0x112e0,
2193ab4b583bSHariprasad Shenai 		0x11300, 0x1130c,
21945b4e83e1SHariprasad Shenai 		0x12000, 0x1206c,
2195ab4b583bSHariprasad Shenai 		0x19040, 0x1906c,
2196ab4b583bSHariprasad Shenai 		0x19078, 0x19080,
21978119c018SHariprasad Shenai 		0x1908c, 0x190e8,
21988119c018SHariprasad Shenai 		0x190f0, 0x190f8,
21998119c018SHariprasad Shenai 		0x19100, 0x19110,
22008119c018SHariprasad Shenai 		0x19120, 0x19124,
22018119c018SHariprasad Shenai 		0x19150, 0x19194,
22028119c018SHariprasad Shenai 		0x1919c, 0x191b0,
2203ab4b583bSHariprasad Shenai 		0x191d0, 0x191e8,
2204676d6a75SHariprasad Shenai 		0x19238, 0x19290,
2205676d6a75SHariprasad Shenai 		0x192a4, 0x192b0,
22068119c018SHariprasad Shenai 		0x192bc, 0x192bc,
22078119c018SHariprasad Shenai 		0x19348, 0x1934c,
22088119c018SHariprasad Shenai 		0x193f8, 0x19418,
22098119c018SHariprasad Shenai 		0x19420, 0x19428,
22108119c018SHariprasad Shenai 		0x19430, 0x19444,
22118119c018SHariprasad Shenai 		0x1944c, 0x1946c,
22128119c018SHariprasad Shenai 		0x19474, 0x19474,
2213ab4b583bSHariprasad Shenai 		0x19490, 0x194cc,
2214ab4b583bSHariprasad Shenai 		0x194f0, 0x194f8,
22158119c018SHariprasad Shenai 		0x19c00, 0x19c48,
22168119c018SHariprasad Shenai 		0x19c50, 0x19c80,
22178119c018SHariprasad Shenai 		0x19c94, 0x19c98,
22188119c018SHariprasad Shenai 		0x19ca0, 0x19cbc,
22198119c018SHariprasad Shenai 		0x19ce4, 0x19ce4,
22208119c018SHariprasad Shenai 		0x19cf0, 0x19cf8,
22218119c018SHariprasad Shenai 		0x19d00, 0x19d28,
2222ab4b583bSHariprasad Shenai 		0x19d50, 0x19d78,
22238119c018SHariprasad Shenai 		0x19d94, 0x19d98,
22248119c018SHariprasad Shenai 		0x19da0, 0x19dc8,
2225ab4b583bSHariprasad Shenai 		0x19df0, 0x19e10,
2226ab4b583bSHariprasad Shenai 		0x19e50, 0x19e6c,
22278119c018SHariprasad Shenai 		0x19ea0, 0x19ebc,
22288119c018SHariprasad Shenai 		0x19ec4, 0x19ef4,
22298119c018SHariprasad Shenai 		0x19f04, 0x19f2c,
22308119c018SHariprasad Shenai 		0x19f34, 0x19f34,
2231ab4b583bSHariprasad Shenai 		0x19f40, 0x19f50,
2232ab4b583bSHariprasad Shenai 		0x19f90, 0x19fac,
22338119c018SHariprasad Shenai 		0x19fc4, 0x19fc8,
22348119c018SHariprasad Shenai 		0x19fd0, 0x19fe4,
22358119c018SHariprasad Shenai 		0x1a000, 0x1a004,
22368119c018SHariprasad Shenai 		0x1a010, 0x1a06c,
22378119c018SHariprasad Shenai 		0x1a0b0, 0x1a0e4,
22388119c018SHariprasad Shenai 		0x1a0ec, 0x1a0f8,
22398119c018SHariprasad Shenai 		0x1a100, 0x1a108,
2240724d0215SShahjada Abul Husain 		0x1a114, 0x1a130,
2241724d0215SShahjada Abul Husain 		0x1a138, 0x1a1c4,
2242ab4b583bSHariprasad Shenai 		0x1a1fc, 0x1a1fc,
2243ab4b583bSHariprasad Shenai 		0x1e008, 0x1e00c,
22448119c018SHariprasad Shenai 		0x1e040, 0x1e044,
22458119c018SHariprasad Shenai 		0x1e04c, 0x1e04c,
2246ab4b583bSHariprasad Shenai 		0x1e284, 0x1e290,
2247ab4b583bSHariprasad Shenai 		0x1e2c0, 0x1e2c0,
2248ab4b583bSHariprasad Shenai 		0x1e2e0, 0x1e2e0,
2249ab4b583bSHariprasad Shenai 		0x1e300, 0x1e384,
2250ab4b583bSHariprasad Shenai 		0x1e3c0, 0x1e3c8,
2251ab4b583bSHariprasad Shenai 		0x1e408, 0x1e40c,
22528119c018SHariprasad Shenai 		0x1e440, 0x1e444,
22538119c018SHariprasad Shenai 		0x1e44c, 0x1e44c,
2254ab4b583bSHariprasad Shenai 		0x1e684, 0x1e690,
2255ab4b583bSHariprasad Shenai 		0x1e6c0, 0x1e6c0,
2256ab4b583bSHariprasad Shenai 		0x1e6e0, 0x1e6e0,
2257ab4b583bSHariprasad Shenai 		0x1e700, 0x1e784,
2258ab4b583bSHariprasad Shenai 		0x1e7c0, 0x1e7c8,
2259ab4b583bSHariprasad Shenai 		0x1e808, 0x1e80c,
22608119c018SHariprasad Shenai 		0x1e840, 0x1e844,
22618119c018SHariprasad Shenai 		0x1e84c, 0x1e84c,
2262ab4b583bSHariprasad Shenai 		0x1ea84, 0x1ea90,
2263ab4b583bSHariprasad Shenai 		0x1eac0, 0x1eac0,
2264ab4b583bSHariprasad Shenai 		0x1eae0, 0x1eae0,
2265ab4b583bSHariprasad Shenai 		0x1eb00, 0x1eb84,
2266ab4b583bSHariprasad Shenai 		0x1ebc0, 0x1ebc8,
2267ab4b583bSHariprasad Shenai 		0x1ec08, 0x1ec0c,
22688119c018SHariprasad Shenai 		0x1ec40, 0x1ec44,
22698119c018SHariprasad Shenai 		0x1ec4c, 0x1ec4c,
2270ab4b583bSHariprasad Shenai 		0x1ee84, 0x1ee90,
2271ab4b583bSHariprasad Shenai 		0x1eec0, 0x1eec0,
2272ab4b583bSHariprasad Shenai 		0x1eee0, 0x1eee0,
2273ab4b583bSHariprasad Shenai 		0x1ef00, 0x1ef84,
2274ab4b583bSHariprasad Shenai 		0x1efc0, 0x1efc8,
2275ab4b583bSHariprasad Shenai 		0x1f008, 0x1f00c,
22768119c018SHariprasad Shenai 		0x1f040, 0x1f044,
22778119c018SHariprasad Shenai 		0x1f04c, 0x1f04c,
2278ab4b583bSHariprasad Shenai 		0x1f284, 0x1f290,
2279ab4b583bSHariprasad Shenai 		0x1f2c0, 0x1f2c0,
2280ab4b583bSHariprasad Shenai 		0x1f2e0, 0x1f2e0,
2281ab4b583bSHariprasad Shenai 		0x1f300, 0x1f384,
2282ab4b583bSHariprasad Shenai 		0x1f3c0, 0x1f3c8,
2283ab4b583bSHariprasad Shenai 		0x1f408, 0x1f40c,
22848119c018SHariprasad Shenai 		0x1f440, 0x1f444,
22858119c018SHariprasad Shenai 		0x1f44c, 0x1f44c,
2286ab4b583bSHariprasad Shenai 		0x1f684, 0x1f690,
2287ab4b583bSHariprasad Shenai 		0x1f6c0, 0x1f6c0,
2288ab4b583bSHariprasad Shenai 		0x1f6e0, 0x1f6e0,
2289ab4b583bSHariprasad Shenai 		0x1f700, 0x1f784,
2290ab4b583bSHariprasad Shenai 		0x1f7c0, 0x1f7c8,
2291ab4b583bSHariprasad Shenai 		0x1f808, 0x1f80c,
22928119c018SHariprasad Shenai 		0x1f840, 0x1f844,
22938119c018SHariprasad Shenai 		0x1f84c, 0x1f84c,
2294ab4b583bSHariprasad Shenai 		0x1fa84, 0x1fa90,
2295ab4b583bSHariprasad Shenai 		0x1fac0, 0x1fac0,
2296ab4b583bSHariprasad Shenai 		0x1fae0, 0x1fae0,
2297ab4b583bSHariprasad Shenai 		0x1fb00, 0x1fb84,
2298ab4b583bSHariprasad Shenai 		0x1fbc0, 0x1fbc8,
2299ab4b583bSHariprasad Shenai 		0x1fc08, 0x1fc0c,
23008119c018SHariprasad Shenai 		0x1fc40, 0x1fc44,
23018119c018SHariprasad Shenai 		0x1fc4c, 0x1fc4c,
2302ab4b583bSHariprasad Shenai 		0x1fe84, 0x1fe90,
2303ab4b583bSHariprasad Shenai 		0x1fec0, 0x1fec0,
2304ab4b583bSHariprasad Shenai 		0x1fee0, 0x1fee0,
2305ab4b583bSHariprasad Shenai 		0x1ff00, 0x1ff84,
2306ab4b583bSHariprasad Shenai 		0x1ffc0, 0x1ffc8,
23078119c018SHariprasad Shenai 		0x30000, 0x30030,
23088119c018SHariprasad Shenai 		0x30100, 0x30168,
23098119c018SHariprasad Shenai 		0x30190, 0x301a0,
23108119c018SHariprasad Shenai 		0x301a8, 0x301b8,
23118119c018SHariprasad Shenai 		0x301c4, 0x301c8,
23128119c018SHariprasad Shenai 		0x301d0, 0x301d0,
2313f109ff11SHariprasad Shenai 		0x30200, 0x30320,
23148119c018SHariprasad Shenai 		0x30400, 0x304b4,
23158119c018SHariprasad Shenai 		0x304c0, 0x3052c,
2316ab4b583bSHariprasad Shenai 		0x30540, 0x3061c,
23178119c018SHariprasad Shenai 		0x30800, 0x308a0,
2318ab4b583bSHariprasad Shenai 		0x308c0, 0x30908,
2319ab4b583bSHariprasad Shenai 		0x30910, 0x309b8,
2320ab4b583bSHariprasad Shenai 		0x30a00, 0x30a04,
23218119c018SHariprasad Shenai 		0x30a0c, 0x30a14,
23228119c018SHariprasad Shenai 		0x30a1c, 0x30a2c,
2323ab4b583bSHariprasad Shenai 		0x30a44, 0x30a50,
23248119c018SHariprasad Shenai 		0x30a74, 0x30a74,
23258119c018SHariprasad Shenai 		0x30a7c, 0x30afc,
23268119c018SHariprasad Shenai 		0x30b08, 0x30c24,
23278119c018SHariprasad Shenai 		0x30d00, 0x30d14,
23288119c018SHariprasad Shenai 		0x30d1c, 0x30d3c,
23298119c018SHariprasad Shenai 		0x30d44, 0x30d4c,
23308119c018SHariprasad Shenai 		0x30d54, 0x30d74,
23318119c018SHariprasad Shenai 		0x30d7c, 0x30d7c,
2332ab4b583bSHariprasad Shenai 		0x30de0, 0x30de0,
2333ab4b583bSHariprasad Shenai 		0x30e00, 0x30ed4,
2334ab4b583bSHariprasad Shenai 		0x30f00, 0x30fa4,
2335ab4b583bSHariprasad Shenai 		0x30fc0, 0x30fc4,
2336ab4b583bSHariprasad Shenai 		0x31000, 0x31004,
2337ab4b583bSHariprasad Shenai 		0x31080, 0x310fc,
2338ab4b583bSHariprasad Shenai 		0x31208, 0x31220,
2339ab4b583bSHariprasad Shenai 		0x3123c, 0x31254,
2340ab4b583bSHariprasad Shenai 		0x31300, 0x31300,
2341ab4b583bSHariprasad Shenai 		0x31308, 0x3131c,
2342ab4b583bSHariprasad Shenai 		0x31338, 0x3133c,
2343ab4b583bSHariprasad Shenai 		0x31380, 0x31380,
2344ab4b583bSHariprasad Shenai 		0x31388, 0x313a8,
2345ab4b583bSHariprasad Shenai 		0x313b4, 0x313b4,
2346ab4b583bSHariprasad Shenai 		0x31400, 0x31420,
2347ab4b583bSHariprasad Shenai 		0x31438, 0x3143c,
2348ab4b583bSHariprasad Shenai 		0x31480, 0x31480,
2349ab4b583bSHariprasad Shenai 		0x314a8, 0x314a8,
2350ab4b583bSHariprasad Shenai 		0x314b0, 0x314b4,
2351ab4b583bSHariprasad Shenai 		0x314c8, 0x314d4,
2352ab4b583bSHariprasad Shenai 		0x31a40, 0x31a4c,
2353ab4b583bSHariprasad Shenai 		0x31af0, 0x31b20,
2354ab4b583bSHariprasad Shenai 		0x31b38, 0x31b3c,
2355ab4b583bSHariprasad Shenai 		0x31b80, 0x31b80,
2356ab4b583bSHariprasad Shenai 		0x31ba8, 0x31ba8,
2357ab4b583bSHariprasad Shenai 		0x31bb0, 0x31bb4,
2358ab4b583bSHariprasad Shenai 		0x31bc8, 0x31bd4,
2359ab4b583bSHariprasad Shenai 		0x32140, 0x3218c,
23608119c018SHariprasad Shenai 		0x321f0, 0x321f4,
23618119c018SHariprasad Shenai 		0x32200, 0x32200,
2362ab4b583bSHariprasad Shenai 		0x32218, 0x32218,
2363ab4b583bSHariprasad Shenai 		0x32400, 0x32400,
2364ab4b583bSHariprasad Shenai 		0x32408, 0x3241c,
2365ab4b583bSHariprasad Shenai 		0x32618, 0x32620,
2366ab4b583bSHariprasad Shenai 		0x32664, 0x32664,
2367ab4b583bSHariprasad Shenai 		0x326a8, 0x326a8,
2368ab4b583bSHariprasad Shenai 		0x326ec, 0x326ec,
2369ab4b583bSHariprasad Shenai 		0x32a00, 0x32abc,
237004d8980bSArjun Vynipadath 		0x32b00, 0x32b18,
237104d8980bSArjun Vynipadath 		0x32b20, 0x32b38,
23728119c018SHariprasad Shenai 		0x32b40, 0x32b58,
23738119c018SHariprasad Shenai 		0x32b60, 0x32b78,
2374ab4b583bSHariprasad Shenai 		0x32c00, 0x32c00,
2375ab4b583bSHariprasad Shenai 		0x32c08, 0x32c3c,
23768119c018SHariprasad Shenai 		0x33000, 0x3302c,
23778119c018SHariprasad Shenai 		0x33034, 0x33050,
23788119c018SHariprasad Shenai 		0x33058, 0x33058,
23798119c018SHariprasad Shenai 		0x33060, 0x3308c,
23808119c018SHariprasad Shenai 		0x3309c, 0x330ac,
23818119c018SHariprasad Shenai 		0x330c0, 0x330c0,
23828119c018SHariprasad Shenai 		0x330c8, 0x330d0,
23838119c018SHariprasad Shenai 		0x330d8, 0x330e0,
23848119c018SHariprasad Shenai 		0x330ec, 0x3312c,
23858119c018SHariprasad Shenai 		0x33134, 0x33150,
23868119c018SHariprasad Shenai 		0x33158, 0x33158,
23878119c018SHariprasad Shenai 		0x33160, 0x3318c,
23888119c018SHariprasad Shenai 		0x3319c, 0x331ac,
23898119c018SHariprasad Shenai 		0x331c0, 0x331c0,
23908119c018SHariprasad Shenai 		0x331c8, 0x331d0,
23918119c018SHariprasad Shenai 		0x331d8, 0x331e0,
23928119c018SHariprasad Shenai 		0x331ec, 0x33290,
23938119c018SHariprasad Shenai 		0x33298, 0x332c4,
23948119c018SHariprasad Shenai 		0x332e4, 0x33390,
23958119c018SHariprasad Shenai 		0x33398, 0x333c4,
23968119c018SHariprasad Shenai 		0x333e4, 0x3342c,
23978119c018SHariprasad Shenai 		0x33434, 0x33450,
23988119c018SHariprasad Shenai 		0x33458, 0x33458,
23998119c018SHariprasad Shenai 		0x33460, 0x3348c,
24008119c018SHariprasad Shenai 		0x3349c, 0x334ac,
24018119c018SHariprasad Shenai 		0x334c0, 0x334c0,
24028119c018SHariprasad Shenai 		0x334c8, 0x334d0,
24038119c018SHariprasad Shenai 		0x334d8, 0x334e0,
24048119c018SHariprasad Shenai 		0x334ec, 0x3352c,
24058119c018SHariprasad Shenai 		0x33534, 0x33550,
24068119c018SHariprasad Shenai 		0x33558, 0x33558,
24078119c018SHariprasad Shenai 		0x33560, 0x3358c,
24088119c018SHariprasad Shenai 		0x3359c, 0x335ac,
24098119c018SHariprasad Shenai 		0x335c0, 0x335c0,
24108119c018SHariprasad Shenai 		0x335c8, 0x335d0,
24118119c018SHariprasad Shenai 		0x335d8, 0x335e0,
24128119c018SHariprasad Shenai 		0x335ec, 0x33690,
24138119c018SHariprasad Shenai 		0x33698, 0x336c4,
24148119c018SHariprasad Shenai 		0x336e4, 0x33790,
24158119c018SHariprasad Shenai 		0x33798, 0x337c4,
2416ab4b583bSHariprasad Shenai 		0x337e4, 0x337fc,
2417ab4b583bSHariprasad Shenai 		0x33814, 0x33814,
2418ab4b583bSHariprasad Shenai 		0x33854, 0x33868,
2419ab4b583bSHariprasad Shenai 		0x33880, 0x3388c,
2420ab4b583bSHariprasad Shenai 		0x338c0, 0x338d0,
2421ab4b583bSHariprasad Shenai 		0x338e8, 0x338ec,
24228119c018SHariprasad Shenai 		0x33900, 0x3392c,
24238119c018SHariprasad Shenai 		0x33934, 0x33950,
24248119c018SHariprasad Shenai 		0x33958, 0x33958,
24258119c018SHariprasad Shenai 		0x33960, 0x3398c,
24268119c018SHariprasad Shenai 		0x3399c, 0x339ac,
24278119c018SHariprasad Shenai 		0x339c0, 0x339c0,
24288119c018SHariprasad Shenai 		0x339c8, 0x339d0,
24298119c018SHariprasad Shenai 		0x339d8, 0x339e0,
24308119c018SHariprasad Shenai 		0x339ec, 0x33a90,
24318119c018SHariprasad Shenai 		0x33a98, 0x33ac4,
2432ab4b583bSHariprasad Shenai 		0x33ae4, 0x33b10,
24338119c018SHariprasad Shenai 		0x33b24, 0x33b28,
24348119c018SHariprasad Shenai 		0x33b38, 0x33b50,
2435ab4b583bSHariprasad Shenai 		0x33bf0, 0x33c10,
24368119c018SHariprasad Shenai 		0x33c24, 0x33c28,
24378119c018SHariprasad Shenai 		0x33c38, 0x33c50,
2438ab4b583bSHariprasad Shenai 		0x33cf0, 0x33cfc,
24398119c018SHariprasad Shenai 		0x34000, 0x34030,
24408119c018SHariprasad Shenai 		0x34100, 0x34168,
24418119c018SHariprasad Shenai 		0x34190, 0x341a0,
24428119c018SHariprasad Shenai 		0x341a8, 0x341b8,
24438119c018SHariprasad Shenai 		0x341c4, 0x341c8,
24448119c018SHariprasad Shenai 		0x341d0, 0x341d0,
2445f109ff11SHariprasad Shenai 		0x34200, 0x34320,
24468119c018SHariprasad Shenai 		0x34400, 0x344b4,
24478119c018SHariprasad Shenai 		0x344c0, 0x3452c,
2448ab4b583bSHariprasad Shenai 		0x34540, 0x3461c,
24498119c018SHariprasad Shenai 		0x34800, 0x348a0,
2450ab4b583bSHariprasad Shenai 		0x348c0, 0x34908,
2451ab4b583bSHariprasad Shenai 		0x34910, 0x349b8,
2452ab4b583bSHariprasad Shenai 		0x34a00, 0x34a04,
24538119c018SHariprasad Shenai 		0x34a0c, 0x34a14,
24548119c018SHariprasad Shenai 		0x34a1c, 0x34a2c,
2455ab4b583bSHariprasad Shenai 		0x34a44, 0x34a50,
24568119c018SHariprasad Shenai 		0x34a74, 0x34a74,
24578119c018SHariprasad Shenai 		0x34a7c, 0x34afc,
24588119c018SHariprasad Shenai 		0x34b08, 0x34c24,
24598119c018SHariprasad Shenai 		0x34d00, 0x34d14,
24608119c018SHariprasad Shenai 		0x34d1c, 0x34d3c,
24618119c018SHariprasad Shenai 		0x34d44, 0x34d4c,
24628119c018SHariprasad Shenai 		0x34d54, 0x34d74,
24638119c018SHariprasad Shenai 		0x34d7c, 0x34d7c,
2464ab4b583bSHariprasad Shenai 		0x34de0, 0x34de0,
2465ab4b583bSHariprasad Shenai 		0x34e00, 0x34ed4,
2466ab4b583bSHariprasad Shenai 		0x34f00, 0x34fa4,
2467ab4b583bSHariprasad Shenai 		0x34fc0, 0x34fc4,
2468ab4b583bSHariprasad Shenai 		0x35000, 0x35004,
2469ab4b583bSHariprasad Shenai 		0x35080, 0x350fc,
2470ab4b583bSHariprasad Shenai 		0x35208, 0x35220,
2471ab4b583bSHariprasad Shenai 		0x3523c, 0x35254,
2472ab4b583bSHariprasad Shenai 		0x35300, 0x35300,
2473ab4b583bSHariprasad Shenai 		0x35308, 0x3531c,
2474ab4b583bSHariprasad Shenai 		0x35338, 0x3533c,
2475ab4b583bSHariprasad Shenai 		0x35380, 0x35380,
2476ab4b583bSHariprasad Shenai 		0x35388, 0x353a8,
2477ab4b583bSHariprasad Shenai 		0x353b4, 0x353b4,
2478ab4b583bSHariprasad Shenai 		0x35400, 0x35420,
2479ab4b583bSHariprasad Shenai 		0x35438, 0x3543c,
2480ab4b583bSHariprasad Shenai 		0x35480, 0x35480,
2481ab4b583bSHariprasad Shenai 		0x354a8, 0x354a8,
2482ab4b583bSHariprasad Shenai 		0x354b0, 0x354b4,
2483ab4b583bSHariprasad Shenai 		0x354c8, 0x354d4,
2484ab4b583bSHariprasad Shenai 		0x35a40, 0x35a4c,
2485ab4b583bSHariprasad Shenai 		0x35af0, 0x35b20,
2486ab4b583bSHariprasad Shenai 		0x35b38, 0x35b3c,
2487ab4b583bSHariprasad Shenai 		0x35b80, 0x35b80,
2488ab4b583bSHariprasad Shenai 		0x35ba8, 0x35ba8,
2489ab4b583bSHariprasad Shenai 		0x35bb0, 0x35bb4,
2490ab4b583bSHariprasad Shenai 		0x35bc8, 0x35bd4,
2491ab4b583bSHariprasad Shenai 		0x36140, 0x3618c,
24928119c018SHariprasad Shenai 		0x361f0, 0x361f4,
24938119c018SHariprasad Shenai 		0x36200, 0x36200,
2494ab4b583bSHariprasad Shenai 		0x36218, 0x36218,
2495ab4b583bSHariprasad Shenai 		0x36400, 0x36400,
2496ab4b583bSHariprasad Shenai 		0x36408, 0x3641c,
2497ab4b583bSHariprasad Shenai 		0x36618, 0x36620,
2498ab4b583bSHariprasad Shenai 		0x36664, 0x36664,
2499ab4b583bSHariprasad Shenai 		0x366a8, 0x366a8,
2500ab4b583bSHariprasad Shenai 		0x366ec, 0x366ec,
2501ab4b583bSHariprasad Shenai 		0x36a00, 0x36abc,
250204d8980bSArjun Vynipadath 		0x36b00, 0x36b18,
250304d8980bSArjun Vynipadath 		0x36b20, 0x36b38,
25048119c018SHariprasad Shenai 		0x36b40, 0x36b58,
25058119c018SHariprasad Shenai 		0x36b60, 0x36b78,
2506ab4b583bSHariprasad Shenai 		0x36c00, 0x36c00,
2507ab4b583bSHariprasad Shenai 		0x36c08, 0x36c3c,
25088119c018SHariprasad Shenai 		0x37000, 0x3702c,
25098119c018SHariprasad Shenai 		0x37034, 0x37050,
25108119c018SHariprasad Shenai 		0x37058, 0x37058,
25118119c018SHariprasad Shenai 		0x37060, 0x3708c,
25128119c018SHariprasad Shenai 		0x3709c, 0x370ac,
25138119c018SHariprasad Shenai 		0x370c0, 0x370c0,
25148119c018SHariprasad Shenai 		0x370c8, 0x370d0,
25158119c018SHariprasad Shenai 		0x370d8, 0x370e0,
25168119c018SHariprasad Shenai 		0x370ec, 0x3712c,
25178119c018SHariprasad Shenai 		0x37134, 0x37150,
25188119c018SHariprasad Shenai 		0x37158, 0x37158,
25198119c018SHariprasad Shenai 		0x37160, 0x3718c,
25208119c018SHariprasad Shenai 		0x3719c, 0x371ac,
25218119c018SHariprasad Shenai 		0x371c0, 0x371c0,
25228119c018SHariprasad Shenai 		0x371c8, 0x371d0,
25238119c018SHariprasad Shenai 		0x371d8, 0x371e0,
25248119c018SHariprasad Shenai 		0x371ec, 0x37290,
25258119c018SHariprasad Shenai 		0x37298, 0x372c4,
25268119c018SHariprasad Shenai 		0x372e4, 0x37390,
25278119c018SHariprasad Shenai 		0x37398, 0x373c4,
25288119c018SHariprasad Shenai 		0x373e4, 0x3742c,
25298119c018SHariprasad Shenai 		0x37434, 0x37450,
25308119c018SHariprasad Shenai 		0x37458, 0x37458,
25318119c018SHariprasad Shenai 		0x37460, 0x3748c,
25328119c018SHariprasad Shenai 		0x3749c, 0x374ac,
25338119c018SHariprasad Shenai 		0x374c0, 0x374c0,
25348119c018SHariprasad Shenai 		0x374c8, 0x374d0,
25358119c018SHariprasad Shenai 		0x374d8, 0x374e0,
25368119c018SHariprasad Shenai 		0x374ec, 0x3752c,
25378119c018SHariprasad Shenai 		0x37534, 0x37550,
25388119c018SHariprasad Shenai 		0x37558, 0x37558,
25398119c018SHariprasad Shenai 		0x37560, 0x3758c,
25408119c018SHariprasad Shenai 		0x3759c, 0x375ac,
25418119c018SHariprasad Shenai 		0x375c0, 0x375c0,
25428119c018SHariprasad Shenai 		0x375c8, 0x375d0,
25438119c018SHariprasad Shenai 		0x375d8, 0x375e0,
25448119c018SHariprasad Shenai 		0x375ec, 0x37690,
25458119c018SHariprasad Shenai 		0x37698, 0x376c4,
25468119c018SHariprasad Shenai 		0x376e4, 0x37790,
25478119c018SHariprasad Shenai 		0x37798, 0x377c4,
2548ab4b583bSHariprasad Shenai 		0x377e4, 0x377fc,
2549ab4b583bSHariprasad Shenai 		0x37814, 0x37814,
2550ab4b583bSHariprasad Shenai 		0x37854, 0x37868,
2551ab4b583bSHariprasad Shenai 		0x37880, 0x3788c,
2552ab4b583bSHariprasad Shenai 		0x378c0, 0x378d0,
2553ab4b583bSHariprasad Shenai 		0x378e8, 0x378ec,
25548119c018SHariprasad Shenai 		0x37900, 0x3792c,
25558119c018SHariprasad Shenai 		0x37934, 0x37950,
25568119c018SHariprasad Shenai 		0x37958, 0x37958,
25578119c018SHariprasad Shenai 		0x37960, 0x3798c,
25588119c018SHariprasad Shenai 		0x3799c, 0x379ac,
25598119c018SHariprasad Shenai 		0x379c0, 0x379c0,
25608119c018SHariprasad Shenai 		0x379c8, 0x379d0,
25618119c018SHariprasad Shenai 		0x379d8, 0x379e0,
25628119c018SHariprasad Shenai 		0x379ec, 0x37a90,
25638119c018SHariprasad Shenai 		0x37a98, 0x37ac4,
2564ab4b583bSHariprasad Shenai 		0x37ae4, 0x37b10,
25658119c018SHariprasad Shenai 		0x37b24, 0x37b28,
25668119c018SHariprasad Shenai 		0x37b38, 0x37b50,
2567ab4b583bSHariprasad Shenai 		0x37bf0, 0x37c10,
25688119c018SHariprasad Shenai 		0x37c24, 0x37c28,
25698119c018SHariprasad Shenai 		0x37c38, 0x37c50,
2570ab4b583bSHariprasad Shenai 		0x37cf0, 0x37cfc,
2571ab4b583bSHariprasad Shenai 		0x40040, 0x40040,
2572ab4b583bSHariprasad Shenai 		0x40080, 0x40084,
2573ab4b583bSHariprasad Shenai 		0x40100, 0x40100,
2574ab4b583bSHariprasad Shenai 		0x40140, 0x401bc,
2575ab4b583bSHariprasad Shenai 		0x40200, 0x40214,
2576ab4b583bSHariprasad Shenai 		0x40228, 0x40228,
2577ab4b583bSHariprasad Shenai 		0x40240, 0x40258,
2578ab4b583bSHariprasad Shenai 		0x40280, 0x40280,
2579ab4b583bSHariprasad Shenai 		0x40304, 0x40304,
2580ab4b583bSHariprasad Shenai 		0x40330, 0x4033c,
258104d8980bSArjun Vynipadath 		0x41304, 0x413c8,
25828119c018SHariprasad Shenai 		0x413d0, 0x413dc,
25838119c018SHariprasad Shenai 		0x413f0, 0x413f0,
25848119c018SHariprasad Shenai 		0x41400, 0x4140c,
25858119c018SHariprasad Shenai 		0x41414, 0x4141c,
2586ab4b583bSHariprasad Shenai 		0x41480, 0x414d0,
2587ab4b583bSHariprasad Shenai 		0x44000, 0x4407c,
25888119c018SHariprasad Shenai 		0x440c0, 0x441ac,
25898119c018SHariprasad Shenai 		0x441b4, 0x4427c,
25908119c018SHariprasad Shenai 		0x442c0, 0x443ac,
25918119c018SHariprasad Shenai 		0x443b4, 0x4447c,
25928119c018SHariprasad Shenai 		0x444c0, 0x445ac,
25938119c018SHariprasad Shenai 		0x445b4, 0x4467c,
25948119c018SHariprasad Shenai 		0x446c0, 0x447ac,
25958119c018SHariprasad Shenai 		0x447b4, 0x4487c,
25968119c018SHariprasad Shenai 		0x448c0, 0x449ac,
25978119c018SHariprasad Shenai 		0x449b4, 0x44a7c,
25988119c018SHariprasad Shenai 		0x44ac0, 0x44bac,
25998119c018SHariprasad Shenai 		0x44bb4, 0x44c7c,
26008119c018SHariprasad Shenai 		0x44cc0, 0x44dac,
26018119c018SHariprasad Shenai 		0x44db4, 0x44e7c,
26028119c018SHariprasad Shenai 		0x44ec0, 0x44fac,
26038119c018SHariprasad Shenai 		0x44fb4, 0x4507c,
26048119c018SHariprasad Shenai 		0x450c0, 0x451ac,
26058119c018SHariprasad Shenai 		0x451b4, 0x451fc,
26068119c018SHariprasad Shenai 		0x45800, 0x45804,
26078119c018SHariprasad Shenai 		0x45810, 0x45830,
26088119c018SHariprasad Shenai 		0x45840, 0x45860,
26098119c018SHariprasad Shenai 		0x45868, 0x45868,
2610ab4b583bSHariprasad Shenai 		0x45880, 0x45884,
2611ab4b583bSHariprasad Shenai 		0x458a0, 0x458b0,
26128119c018SHariprasad Shenai 		0x45a00, 0x45a04,
26138119c018SHariprasad Shenai 		0x45a10, 0x45a30,
26148119c018SHariprasad Shenai 		0x45a40, 0x45a60,
26158119c018SHariprasad Shenai 		0x45a68, 0x45a68,
2616ab4b583bSHariprasad Shenai 		0x45a80, 0x45a84,
2617ab4b583bSHariprasad Shenai 		0x45aa0, 0x45ab0,
2618ab4b583bSHariprasad Shenai 		0x460c0, 0x460e4,
26198119c018SHariprasad Shenai 		0x47000, 0x4703c,
26208119c018SHariprasad Shenai 		0x47044, 0x4708c,
2621ab4b583bSHariprasad Shenai 		0x47200, 0x47250,
26228119c018SHariprasad Shenai 		0x47400, 0x47408,
26238119c018SHariprasad Shenai 		0x47414, 0x47420,
2624ab4b583bSHariprasad Shenai 		0x47600, 0x47618,
26258119c018SHariprasad Shenai 		0x47800, 0x47814,
26268119c018SHariprasad Shenai 		0x47820, 0x4782c,
26278119c018SHariprasad Shenai 		0x50000, 0x50084,
26288119c018SHariprasad Shenai 		0x50090, 0x500cc,
26298119c018SHariprasad Shenai 		0x50300, 0x50384,
2630ab4b583bSHariprasad Shenai 		0x50400, 0x50400,
26318119c018SHariprasad Shenai 		0x50800, 0x50884,
26328119c018SHariprasad Shenai 		0x50890, 0x508cc,
26338119c018SHariprasad Shenai 		0x50b00, 0x50b84,
2634ab4b583bSHariprasad Shenai 		0x50c00, 0x50c00,
26358119c018SHariprasad Shenai 		0x51000, 0x51020,
26368119c018SHariprasad Shenai 		0x51028, 0x510b0,
2637ab4b583bSHariprasad Shenai 		0x51300, 0x51324,
2638ab4b583bSHariprasad Shenai 	};
2639ab4b583bSHariprasad Shenai 
2640812034f1SHariprasad Shenai 	u32 *buf_end = (u32 *)((char *)buf + buf_size);
2641812034f1SHariprasad Shenai 	const unsigned int *reg_ranges;
2642812034f1SHariprasad Shenai 	int reg_ranges_size, range;
2643812034f1SHariprasad Shenai 	unsigned int chip_version = CHELSIO_CHIP_VERSION(adap->params.chip);
2644812034f1SHariprasad Shenai 
2645812034f1SHariprasad Shenai 	/* Select the right set of register ranges to dump depending on the
2646812034f1SHariprasad Shenai 	 * adapter chip type.
2647812034f1SHariprasad Shenai 	 */
2648812034f1SHariprasad Shenai 	switch (chip_version) {
2649812034f1SHariprasad Shenai 	case CHELSIO_T4:
2650812034f1SHariprasad Shenai 		reg_ranges = t4_reg_ranges;
2651812034f1SHariprasad Shenai 		reg_ranges_size = ARRAY_SIZE(t4_reg_ranges);
2652812034f1SHariprasad Shenai 		break;
2653812034f1SHariprasad Shenai 
2654812034f1SHariprasad Shenai 	case CHELSIO_T5:
2655812034f1SHariprasad Shenai 		reg_ranges = t5_reg_ranges;
2656812034f1SHariprasad Shenai 		reg_ranges_size = ARRAY_SIZE(t5_reg_ranges);
2657812034f1SHariprasad Shenai 		break;
2658812034f1SHariprasad Shenai 
2659ab4b583bSHariprasad Shenai 	case CHELSIO_T6:
2660ab4b583bSHariprasad Shenai 		reg_ranges = t6_reg_ranges;
2661ab4b583bSHariprasad Shenai 		reg_ranges_size = ARRAY_SIZE(t6_reg_ranges);
2662ab4b583bSHariprasad Shenai 		break;
2663ab4b583bSHariprasad Shenai 
2664812034f1SHariprasad Shenai 	default:
2665812034f1SHariprasad Shenai 		dev_err(adap->pdev_dev,
2666812034f1SHariprasad Shenai 			"Unsupported chip version %d\n", chip_version);
2667812034f1SHariprasad Shenai 		return;
2668812034f1SHariprasad Shenai 	}
2669812034f1SHariprasad Shenai 
2670812034f1SHariprasad Shenai 	/* Clear the register buffer and insert the appropriate register
2671812034f1SHariprasad Shenai 	 * values selected by the above register ranges.
2672812034f1SHariprasad Shenai 	 */
2673812034f1SHariprasad Shenai 	memset(buf, 0, buf_size);
2674812034f1SHariprasad Shenai 	for (range = 0; range < reg_ranges_size; range += 2) {
2675812034f1SHariprasad Shenai 		unsigned int reg = reg_ranges[range];
2676812034f1SHariprasad Shenai 		unsigned int last_reg = reg_ranges[range + 1];
2677812034f1SHariprasad Shenai 		u32 *bufp = (u32 *)((char *)buf + reg);
2678812034f1SHariprasad Shenai 
2679812034f1SHariprasad Shenai 		/* Iterate across the register range filling in the register
2680812034f1SHariprasad Shenai 		 * buffer but don't write past the end of the register buffer.
2681812034f1SHariprasad Shenai 		 */
2682812034f1SHariprasad Shenai 		while (reg <= last_reg && bufp < buf_end) {
2683812034f1SHariprasad Shenai 			*bufp++ = t4_read_reg(adap, reg);
2684812034f1SHariprasad Shenai 			reg += sizeof(u32);
2685812034f1SHariprasad Shenai 		}
2686812034f1SHariprasad Shenai 	}
2687812034f1SHariprasad Shenai }
2688812034f1SHariprasad Shenai 
2689f7917c00SJeff Kirsher #define EEPROM_STAT_ADDR   0x7bfc
269047ce9c48SSantosh Rastapur #define VPD_BASE           0x400
269147ce9c48SSantosh Rastapur #define VPD_BASE_OLD       0
26920a57a536SSantosh Rastapur #define VPD_LEN            1024
2693f7917c00SJeff Kirsher 
2694f7917c00SJeff Kirsher /**
2695940c9c45SRahul Lakkireddy  * t4_eeprom_ptov - translate a physical EEPROM address to virtual
2696940c9c45SRahul Lakkireddy  * @phys_addr: the physical EEPROM address
2697940c9c45SRahul Lakkireddy  * @fn: the PCI function number
2698940c9c45SRahul Lakkireddy  * @sz: size of function-specific area
2699940c9c45SRahul Lakkireddy  *
2700940c9c45SRahul Lakkireddy  * Translate a physical EEPROM address to virtual.  The first 1K is
2701940c9c45SRahul Lakkireddy  * accessed through virtual addresses starting at 31K, the rest is
2702940c9c45SRahul Lakkireddy  * accessed through virtual addresses starting at 0.
2703940c9c45SRahul Lakkireddy  *
2704940c9c45SRahul Lakkireddy  * The mapping is as follows:
2705940c9c45SRahul Lakkireddy  * [0..1K) -> [31K..32K)
2706940c9c45SRahul Lakkireddy  * [1K..1K+A) -> [31K-A..31K)
2707940c9c45SRahul Lakkireddy  * [1K+A..ES) -> [0..ES-A-1K)
2708940c9c45SRahul Lakkireddy  *
2709940c9c45SRahul Lakkireddy  * where A = @fn * @sz, and ES = EEPROM size.
2710940c9c45SRahul Lakkireddy  */
t4_eeprom_ptov(unsigned int phys_addr,unsigned int fn,unsigned int sz)2711940c9c45SRahul Lakkireddy int t4_eeprom_ptov(unsigned int phys_addr, unsigned int fn, unsigned int sz)
2712940c9c45SRahul Lakkireddy {
2713940c9c45SRahul Lakkireddy 	fn *= sz;
2714940c9c45SRahul Lakkireddy 	if (phys_addr < 1024)
2715940c9c45SRahul Lakkireddy 		return phys_addr + (31 << 10);
2716940c9c45SRahul Lakkireddy 	if (phys_addr < 1024 + fn)
2717940c9c45SRahul Lakkireddy 		return 31744 - fn + phys_addr - 1024;
2718940c9c45SRahul Lakkireddy 	if (phys_addr < EEPROMSIZE)
2719940c9c45SRahul Lakkireddy 		return phys_addr - 1024 - fn;
2720940c9c45SRahul Lakkireddy 	return -EINVAL;
2721940c9c45SRahul Lakkireddy }
2722940c9c45SRahul Lakkireddy 
2723940c9c45SRahul Lakkireddy /**
2724f7917c00SJeff Kirsher  *	t4_seeprom_wp - enable/disable EEPROM write protection
2725f7917c00SJeff Kirsher  *	@adapter: the adapter
2726f7917c00SJeff Kirsher  *	@enable: whether to enable or disable write protection
2727f7917c00SJeff Kirsher  *
2728f7917c00SJeff Kirsher  *	Enables or disables write protection on the serial EEPROM.
2729f7917c00SJeff Kirsher  */
t4_seeprom_wp(struct adapter * adapter,bool enable)2730f7917c00SJeff Kirsher int t4_seeprom_wp(struct adapter *adapter, bool enable)
2731f7917c00SJeff Kirsher {
2732f7917c00SJeff Kirsher 	unsigned int v = enable ? 0xc : 0;
2733f7917c00SJeff Kirsher 	int ret = pci_write_vpd(adapter->pdev, EEPROM_STAT_ADDR, 4, &v);
2734f7917c00SJeff Kirsher 	return ret < 0 ? ret : 0;
2735f7917c00SJeff Kirsher }
2736f7917c00SJeff Kirsher 
2737f7917c00SJeff Kirsher /**
2738098ef6c2SHariprasad Shenai  *	t4_get_raw_vpd_params - read VPD parameters from VPD EEPROM
2739f7917c00SJeff Kirsher  *	@adapter: adapter to read
2740f7917c00SJeff Kirsher  *	@p: where to store the parameters
2741f7917c00SJeff Kirsher  *
2742f7917c00SJeff Kirsher  *	Reads card parameters stored in VPD EEPROM.
2743f7917c00SJeff Kirsher  */
t4_get_raw_vpd_params(struct adapter * adapter,struct vpd_params * p)2744098ef6c2SHariprasad Shenai int t4_get_raw_vpd_params(struct adapter *adapter, struct vpd_params *p)
2745f7917c00SJeff Kirsher {
2746fc927929SHeiner Kallweit 	unsigned int id_len, pn_len, sn_len, na_len;
274724c521f8SHeiner Kallweit 	int id, sn, pn, na, addr, ret = 0;
274852f0a1e0SHeiner Kallweit 	u8 *vpd, base_val = 0;
2749f7917c00SJeff Kirsher 
27508c357ebdSVipul Pandya 	vpd = vmalloc(VPD_LEN);
27518c357ebdSVipul Pandya 	if (!vpd)
27528c357ebdSVipul Pandya 		return -ENOMEM;
27538c357ebdSVipul Pandya 
2754098ef6c2SHariprasad Shenai 	/* Card information normally starts at VPD_BASE but early cards had
2755098ef6c2SHariprasad Shenai 	 * it at 0.
2756098ef6c2SHariprasad Shenai 	 */
275705fcc256SHeiner Kallweit 	ret = pci_read_vpd(adapter->pdev, VPD_BASE, 1, &base_val);
275847ce9c48SSantosh Rastapur 	if (ret < 0)
275947ce9c48SSantosh Rastapur 		goto out;
276063a92fe6SHariprasad Shenai 
276105fcc256SHeiner Kallweit 	addr = base_val == PCI_VPD_LRDT_ID_STRING ? VPD_BASE : VPD_BASE_OLD;
276247ce9c48SSantosh Rastapur 
276347ce9c48SSantosh Rastapur 	ret = pci_read_vpd(adapter->pdev, addr, VPD_LEN, vpd);
2764f7917c00SJeff Kirsher 	if (ret < 0)
27658c357ebdSVipul Pandya 		goto out;
2766f7917c00SJeff Kirsher 
276724c521f8SHeiner Kallweit 	ret = pci_vpd_find_id_string(vpd, VPD_LEN, &id_len);
276824c521f8SHeiner Kallweit 	if (ret < 0)
27698c357ebdSVipul Pandya 		goto out;
277024c521f8SHeiner Kallweit 	id = ret;
2771f7917c00SJeff Kirsher 
277252f0a1e0SHeiner Kallweit 	ret = pci_vpd_check_csum(vpd, VPD_LEN);
277352f0a1e0SHeiner Kallweit 	if (ret) {
277452f0a1e0SHeiner Kallweit 		dev_err(adapter->pdev_dev, "VPD checksum incorrect or missing\n");
27758c357ebdSVipul Pandya 		ret = -EINVAL;
27768c357ebdSVipul Pandya 		goto out;
2777f7917c00SJeff Kirsher 	}
2778f7917c00SJeff Kirsher 
2779fc927929SHeiner Kallweit 	ret = pci_vpd_find_ro_info_keyword(vpd, VPD_LEN,
2780fc927929SHeiner Kallweit 					   PCI_VPD_RO_KEYWORD_SERIALNO, &sn_len);
2781fc927929SHeiner Kallweit 	if (ret < 0)
2782fc927929SHeiner Kallweit 		goto out;
2783fc927929SHeiner Kallweit 	sn = ret;
2784f7917c00SJeff Kirsher 
2785fc927929SHeiner Kallweit 	ret = pci_vpd_find_ro_info_keyword(vpd, VPD_LEN,
2786fc927929SHeiner Kallweit 					   PCI_VPD_RO_KEYWORD_PARTNO, &pn_len);
2787fc927929SHeiner Kallweit 	if (ret < 0)
2788fc927929SHeiner Kallweit 		goto out;
2789fc927929SHeiner Kallweit 	pn = ret;
2790fc927929SHeiner Kallweit 
2791fc927929SHeiner Kallweit 	ret = pci_vpd_find_ro_info_keyword(vpd, VPD_LEN, "NA", &na_len);
2792fc927929SHeiner Kallweit 	if (ret < 0)
2793fc927929SHeiner Kallweit 		goto out;
2794fc927929SHeiner Kallweit 	na = ret;
2795fc927929SHeiner Kallweit 
27961c7ab9cdSKees Cook 	memcpy(p->id, vpd + id, min_t(unsigned int, id_len, ID_LEN));
2797f7917c00SJeff Kirsher 	strim(p->id);
27981c7ab9cdSKees Cook 	memcpy(p->sn, vpd + sn, min_t(unsigned int, sn_len, SERNUM_LEN));
2799f7917c00SJeff Kirsher 	strim(p->sn);
28001c7ab9cdSKees Cook 	memcpy(p->pn, vpd + pn, min_t(unsigned int, pn_len, PN_LEN));
2801a94cd705SKumar Sanghvi 	strim(p->pn);
28021c7ab9cdSKees Cook 	memcpy(p->na, vpd + na, min_t(unsigned int, na_len, MACADDR_LEN));
28031c7ab9cdSKees Cook 	strim(p->na);
2804636f9d37SVipul Pandya 
2805098ef6c2SHariprasad Shenai out:
2806098ef6c2SHariprasad Shenai 	vfree(vpd);
2807fc927929SHeiner Kallweit 	if (ret < 0) {
2808fc927929SHeiner Kallweit 		dev_err(adapter->pdev_dev, "error reading VPD\n");
2809fc927929SHeiner Kallweit 		return ret;
2810fc927929SHeiner Kallweit 	}
2811fc927929SHeiner Kallweit 
2812fc927929SHeiner Kallweit 	return 0;
2813098ef6c2SHariprasad Shenai }
2814098ef6c2SHariprasad Shenai 
2815098ef6c2SHariprasad Shenai /**
2816098ef6c2SHariprasad Shenai  *	t4_get_vpd_params - read VPD parameters & retrieve Core Clock
2817098ef6c2SHariprasad Shenai  *	@adapter: adapter to read
2818098ef6c2SHariprasad Shenai  *	@p: where to store the parameters
2819098ef6c2SHariprasad Shenai  *
2820098ef6c2SHariprasad Shenai  *	Reads card parameters stored in VPD EEPROM and retrieves the Core
2821098ef6c2SHariprasad Shenai  *	Clock.  This can only be called after a connection to the firmware
2822098ef6c2SHariprasad Shenai  *	is established.
2823098ef6c2SHariprasad Shenai  */
t4_get_vpd_params(struct adapter * adapter,struct vpd_params * p)2824098ef6c2SHariprasad Shenai int t4_get_vpd_params(struct adapter *adapter, struct vpd_params *p)
2825098ef6c2SHariprasad Shenai {
2826098ef6c2SHariprasad Shenai 	u32 cclk_param, cclk_val;
2827098ef6c2SHariprasad Shenai 	int ret;
2828098ef6c2SHariprasad Shenai 
2829098ef6c2SHariprasad Shenai 	/* Grab the raw VPD parameters.
2830098ef6c2SHariprasad Shenai 	 */
2831098ef6c2SHariprasad Shenai 	ret = t4_get_raw_vpd_params(adapter, p);
2832098ef6c2SHariprasad Shenai 	if (ret)
2833098ef6c2SHariprasad Shenai 		return ret;
2834098ef6c2SHariprasad Shenai 
2835098ef6c2SHariprasad Shenai 	/* Ask firmware for the Core Clock since it knows how to translate the
2836636f9d37SVipul Pandya 	 * Reference Clock ('V2') VPD field into a Core Clock value ...
2837636f9d37SVipul Pandya 	 */
28385167865aSHariprasad Shenai 	cclk_param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) |
28395167865aSHariprasad Shenai 		      FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_CCLK));
2840098ef6c2SHariprasad Shenai 	ret = t4_query_params(adapter, adapter->mbox, adapter->pf, 0,
2841636f9d37SVipul Pandya 			      1, &cclk_param, &cclk_val);
28428c357ebdSVipul Pandya 
2843636f9d37SVipul Pandya 	if (ret)
2844636f9d37SVipul Pandya 		return ret;
2845636f9d37SVipul Pandya 	p->cclk = cclk_val;
2846636f9d37SVipul Pandya 
2847f7917c00SJeff Kirsher 	return 0;
2848f7917c00SJeff Kirsher }
2849f7917c00SJeff Kirsher 
28500eaec62aSCasey Leedom /**
28510eaec62aSCasey Leedom  *	t4_get_pfres - retrieve VF resource limits
28520eaec62aSCasey Leedom  *	@adapter: the adapter
28530eaec62aSCasey Leedom  *
28540eaec62aSCasey Leedom  *	Retrieves configured resource limits and capabilities for a physical
28550eaec62aSCasey Leedom  *	function.  The results are stored in @adapter->pfres.
28560eaec62aSCasey Leedom  */
t4_get_pfres(struct adapter * adapter)28570eaec62aSCasey Leedom int t4_get_pfres(struct adapter *adapter)
28580eaec62aSCasey Leedom {
28590eaec62aSCasey Leedom 	struct pf_resources *pfres = &adapter->params.pfres;
28600eaec62aSCasey Leedom 	struct fw_pfvf_cmd cmd, rpl;
28610eaec62aSCasey Leedom 	int v;
28620eaec62aSCasey Leedom 	u32 word;
28630eaec62aSCasey Leedom 
28640eaec62aSCasey Leedom 	/* Execute PFVF Read command to get VF resource limits; bail out early
28650eaec62aSCasey Leedom 	 * with error on command failure.
28660eaec62aSCasey Leedom 	 */
28670eaec62aSCasey Leedom 	memset(&cmd, 0, sizeof(cmd));
28680eaec62aSCasey Leedom 	cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_PFVF_CMD) |
28690eaec62aSCasey Leedom 				    FW_CMD_REQUEST_F |
28700eaec62aSCasey Leedom 				    FW_CMD_READ_F |
28710eaec62aSCasey Leedom 				    FW_PFVF_CMD_PFN_V(adapter->pf) |
28720eaec62aSCasey Leedom 				    FW_PFVF_CMD_VFN_V(0));
28730eaec62aSCasey Leedom 	cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
28740eaec62aSCasey Leedom 	v = t4_wr_mbox(adapter, adapter->mbox, &cmd, sizeof(cmd), &rpl);
28750eaec62aSCasey Leedom 	if (v != FW_SUCCESS)
28760eaec62aSCasey Leedom 		return v;
28770eaec62aSCasey Leedom 
28780eaec62aSCasey Leedom 	/* Extract PF resource limits and return success.
28790eaec62aSCasey Leedom 	 */
28800eaec62aSCasey Leedom 	word = be32_to_cpu(rpl.niqflint_niq);
28810eaec62aSCasey Leedom 	pfres->niqflint = FW_PFVF_CMD_NIQFLINT_G(word);
28820eaec62aSCasey Leedom 	pfres->niq = FW_PFVF_CMD_NIQ_G(word);
28830eaec62aSCasey Leedom 
28840eaec62aSCasey Leedom 	word = be32_to_cpu(rpl.type_to_neq);
28850eaec62aSCasey Leedom 	pfres->neq = FW_PFVF_CMD_NEQ_G(word);
28860eaec62aSCasey Leedom 	pfres->pmask = FW_PFVF_CMD_PMASK_G(word);
28870eaec62aSCasey Leedom 
28880eaec62aSCasey Leedom 	word = be32_to_cpu(rpl.tc_to_nexactf);
28890eaec62aSCasey Leedom 	pfres->tc = FW_PFVF_CMD_TC_G(word);
28900eaec62aSCasey Leedom 	pfres->nvi = FW_PFVF_CMD_NVI_G(word);
28910eaec62aSCasey Leedom 	pfres->nexactf = FW_PFVF_CMD_NEXACTF_G(word);
28920eaec62aSCasey Leedom 
28930eaec62aSCasey Leedom 	word = be32_to_cpu(rpl.r_caps_to_nethctrl);
28940eaec62aSCasey Leedom 	pfres->r_caps = FW_PFVF_CMD_R_CAPS_G(word);
28950eaec62aSCasey Leedom 	pfres->wx_caps = FW_PFVF_CMD_WX_CAPS_G(word);
28960eaec62aSCasey Leedom 	pfres->nethctrl = FW_PFVF_CMD_NETHCTRL_G(word);
28970eaec62aSCasey Leedom 
28980eaec62aSCasey Leedom 	return 0;
28990eaec62aSCasey Leedom }
29000eaec62aSCasey Leedom 
2901f7917c00SJeff Kirsher /* serial flash and firmware constants */
2902f7917c00SJeff Kirsher enum {
2903f7917c00SJeff Kirsher 	SF_ATTEMPTS = 10,             /* max retries for SF operations */
2904f7917c00SJeff Kirsher 
2905f7917c00SJeff Kirsher 	/* flash command opcodes */
2906f7917c00SJeff Kirsher 	SF_PROG_PAGE    = 2,          /* program page */
2907f7917c00SJeff Kirsher 	SF_WR_DISABLE   = 4,          /* disable writes */
2908f7917c00SJeff Kirsher 	SF_RD_STATUS    = 5,          /* read status register */
2909f7917c00SJeff Kirsher 	SF_WR_ENABLE    = 6,          /* enable writes */
2910f7917c00SJeff Kirsher 	SF_RD_DATA_FAST = 0xb,        /* read flash */
2911f7917c00SJeff Kirsher 	SF_RD_ID        = 0x9f,       /* read ID */
2912f7917c00SJeff Kirsher 	SF_ERASE_SECTOR = 0xd8,       /* erase sector */
2913f7917c00SJeff Kirsher };
2914f7917c00SJeff Kirsher 
2915f7917c00SJeff Kirsher /**
2916f7917c00SJeff Kirsher  *	sf1_read - read data from the serial flash
2917f7917c00SJeff Kirsher  *	@adapter: the adapter
2918f7917c00SJeff Kirsher  *	@byte_cnt: number of bytes to read
2919f7917c00SJeff Kirsher  *	@cont: whether another operation will be chained
2920f7917c00SJeff Kirsher  *	@lock: whether to lock SF for PL access only
2921f7917c00SJeff Kirsher  *	@valp: where to store the read data
2922f7917c00SJeff Kirsher  *
2923f7917c00SJeff Kirsher  *	Reads up to 4 bytes of data from the serial flash.  The location of
2924f7917c00SJeff Kirsher  *	the read needs to be specified prior to calling this by issuing the
2925f7917c00SJeff Kirsher  *	appropriate commands to the serial flash.
2926f7917c00SJeff Kirsher  */
sf1_read(struct adapter * adapter,unsigned int byte_cnt,int cont,int lock,u32 * valp)2927f7917c00SJeff Kirsher static int sf1_read(struct adapter *adapter, unsigned int byte_cnt, int cont,
2928f7917c00SJeff Kirsher 		    int lock, u32 *valp)
2929f7917c00SJeff Kirsher {
2930f7917c00SJeff Kirsher 	int ret;
2931f7917c00SJeff Kirsher 
2932f7917c00SJeff Kirsher 	if (!byte_cnt || byte_cnt > 4)
2933f7917c00SJeff Kirsher 		return -EINVAL;
29340d804338SHariprasad Shenai 	if (t4_read_reg(adapter, SF_OP_A) & SF_BUSY_F)
2935f7917c00SJeff Kirsher 		return -EBUSY;
29360d804338SHariprasad Shenai 	t4_write_reg(adapter, SF_OP_A, SF_LOCK_V(lock) |
29370d804338SHariprasad Shenai 		     SF_CONT_V(cont) | BYTECNT_V(byte_cnt - 1));
29380d804338SHariprasad Shenai 	ret = t4_wait_op_done(adapter, SF_OP_A, SF_BUSY_F, 0, SF_ATTEMPTS, 5);
2939f7917c00SJeff Kirsher 	if (!ret)
29400d804338SHariprasad Shenai 		*valp = t4_read_reg(adapter, SF_DATA_A);
2941f7917c00SJeff Kirsher 	return ret;
2942f7917c00SJeff Kirsher }
2943f7917c00SJeff Kirsher 
2944f7917c00SJeff Kirsher /**
2945f7917c00SJeff Kirsher  *	sf1_write - write data to the serial flash
2946f7917c00SJeff Kirsher  *	@adapter: the adapter
2947f7917c00SJeff Kirsher  *	@byte_cnt: number of bytes to write
2948f7917c00SJeff Kirsher  *	@cont: whether another operation will be chained
2949f7917c00SJeff Kirsher  *	@lock: whether to lock SF for PL access only
2950f7917c00SJeff Kirsher  *	@val: value to write
2951f7917c00SJeff Kirsher  *
2952f7917c00SJeff Kirsher  *	Writes up to 4 bytes of data to the serial flash.  The location of
2953f7917c00SJeff Kirsher  *	the write needs to be specified prior to calling this by issuing the
2954f7917c00SJeff Kirsher  *	appropriate commands to the serial flash.
2955f7917c00SJeff Kirsher  */
sf1_write(struct adapter * adapter,unsigned int byte_cnt,int cont,int lock,u32 val)2956f7917c00SJeff Kirsher static int sf1_write(struct adapter *adapter, unsigned int byte_cnt, int cont,
2957f7917c00SJeff Kirsher 		     int lock, u32 val)
2958f7917c00SJeff Kirsher {
2959f7917c00SJeff Kirsher 	if (!byte_cnt || byte_cnt > 4)
2960f7917c00SJeff Kirsher 		return -EINVAL;
29610d804338SHariprasad Shenai 	if (t4_read_reg(adapter, SF_OP_A) & SF_BUSY_F)
2962f7917c00SJeff Kirsher 		return -EBUSY;
29630d804338SHariprasad Shenai 	t4_write_reg(adapter, SF_DATA_A, val);
29640d804338SHariprasad Shenai 	t4_write_reg(adapter, SF_OP_A, SF_LOCK_V(lock) |
29650d804338SHariprasad Shenai 		     SF_CONT_V(cont) | BYTECNT_V(byte_cnt - 1) | OP_V(1));
29660d804338SHariprasad Shenai 	return t4_wait_op_done(adapter, SF_OP_A, SF_BUSY_F, 0, SF_ATTEMPTS, 5);
2967f7917c00SJeff Kirsher }
2968f7917c00SJeff Kirsher 
2969f7917c00SJeff Kirsher /**
2970f7917c00SJeff Kirsher  *	flash_wait_op - wait for a flash operation to complete
2971f7917c00SJeff Kirsher  *	@adapter: the adapter
2972f7917c00SJeff Kirsher  *	@attempts: max number of polls of the status register
2973f7917c00SJeff Kirsher  *	@delay: delay between polls in ms
2974f7917c00SJeff Kirsher  *
2975f7917c00SJeff Kirsher  *	Wait for a flash operation to complete by polling the status register.
2976f7917c00SJeff Kirsher  */
flash_wait_op(struct adapter * adapter,int attempts,int delay)2977f7917c00SJeff Kirsher static int flash_wait_op(struct adapter *adapter, int attempts, int delay)
2978f7917c00SJeff Kirsher {
2979f7917c00SJeff Kirsher 	int ret;
2980f7917c00SJeff Kirsher 	u32 status;
2981f7917c00SJeff Kirsher 
2982f7917c00SJeff Kirsher 	while (1) {
2983f7917c00SJeff Kirsher 		if ((ret = sf1_write(adapter, 1, 1, 1, SF_RD_STATUS)) != 0 ||
2984f7917c00SJeff Kirsher 		    (ret = sf1_read(adapter, 1, 0, 1, &status)) != 0)
2985f7917c00SJeff Kirsher 			return ret;
2986f7917c00SJeff Kirsher 		if (!(status & 1))
2987f7917c00SJeff Kirsher 			return 0;
2988f7917c00SJeff Kirsher 		if (--attempts == 0)
2989f7917c00SJeff Kirsher 			return -EAGAIN;
2990f7917c00SJeff Kirsher 		if (delay)
2991f7917c00SJeff Kirsher 			msleep(delay);
2992f7917c00SJeff Kirsher 	}
2993f7917c00SJeff Kirsher }
2994f7917c00SJeff Kirsher 
2995f7917c00SJeff Kirsher /**
2996f7917c00SJeff Kirsher  *	t4_read_flash - read words from serial flash
2997f7917c00SJeff Kirsher  *	@adapter: the adapter
2998f7917c00SJeff Kirsher  *	@addr: the start address for the read
2999f7917c00SJeff Kirsher  *	@nwords: how many 32-bit words to read
3000f7917c00SJeff Kirsher  *	@data: where to store the read data
3001f7917c00SJeff Kirsher  *	@byte_oriented: whether to store data as bytes or as words
3002f7917c00SJeff Kirsher  *
3003f7917c00SJeff Kirsher  *	Read the specified number of 32-bit words from the serial flash.
3004f7917c00SJeff Kirsher  *	If @byte_oriented is set the read data is stored as a byte array
3005f7917c00SJeff Kirsher  *	(i.e., big-endian), otherwise as 32-bit words in the platform's
3006dbedd44eSJoe Perches  *	natural endianness.
3007f7917c00SJeff Kirsher  */
t4_read_flash(struct adapter * adapter,unsigned int addr,unsigned int nwords,u32 * data,int byte_oriented)300849216c1cSHariprasad Shenai int t4_read_flash(struct adapter *adapter, unsigned int addr,
3009f7917c00SJeff Kirsher 		  unsigned int nwords, u32 *data, int byte_oriented)
3010f7917c00SJeff Kirsher {
3011f7917c00SJeff Kirsher 	int ret;
3012f7917c00SJeff Kirsher 
3013f7917c00SJeff Kirsher 	if (addr + nwords * sizeof(u32) > adapter->params.sf_size || (addr & 3))
3014f7917c00SJeff Kirsher 		return -EINVAL;
3015f7917c00SJeff Kirsher 
3016f7917c00SJeff Kirsher 	addr = swab32(addr) | SF_RD_DATA_FAST;
3017f7917c00SJeff Kirsher 
3018f7917c00SJeff Kirsher 	if ((ret = sf1_write(adapter, 4, 1, 0, addr)) != 0 ||
3019f7917c00SJeff Kirsher 	    (ret = sf1_read(adapter, 1, 1, 0, data)) != 0)
3020f7917c00SJeff Kirsher 		return ret;
3021f7917c00SJeff Kirsher 
3022f7917c00SJeff Kirsher 	for ( ; nwords; nwords--, data++) {
3023f7917c00SJeff Kirsher 		ret = sf1_read(adapter, 4, nwords > 1, nwords == 1, data);
3024f7917c00SJeff Kirsher 		if (nwords == 1)
30250d804338SHariprasad Shenai 			t4_write_reg(adapter, SF_OP_A, 0);    /* unlock SF */
3026f7917c00SJeff Kirsher 		if (ret)
3027f7917c00SJeff Kirsher 			return ret;
3028f7917c00SJeff Kirsher 		if (byte_oriented)
3029f404f80cSHariprasad Shenai 			*data = (__force __u32)(cpu_to_be32(*data));
3030f7917c00SJeff Kirsher 	}
3031f7917c00SJeff Kirsher 	return 0;
3032f7917c00SJeff Kirsher }
3033f7917c00SJeff Kirsher 
3034f7917c00SJeff Kirsher /**
3035f7917c00SJeff Kirsher  *	t4_write_flash - write up to a page of data to the serial flash
3036f7917c00SJeff Kirsher  *	@adapter: the adapter
3037f7917c00SJeff Kirsher  *	@addr: the start address to write
3038f7917c00SJeff Kirsher  *	@n: length of data to write in bytes
3039f7917c00SJeff Kirsher  *	@data: the data to write
304042a20397SRahul Lakkireddy  *	@byte_oriented: whether to store data as bytes or as words
3041f7917c00SJeff Kirsher  *
3042f7917c00SJeff Kirsher  *	Writes up to a page of data (256 bytes) to the serial flash starting
3043f7917c00SJeff Kirsher  *	at the given address.  All the data must be written to the same page.
304442a20397SRahul Lakkireddy  *	If @byte_oriented is set the write data is stored as byte stream
304542a20397SRahul Lakkireddy  *	(i.e. matches what on disk), otherwise in big-endian.
3046f7917c00SJeff Kirsher  */
t4_write_flash(struct adapter * adapter,unsigned int addr,unsigned int n,const u8 * data,bool byte_oriented)3047f7917c00SJeff Kirsher static int t4_write_flash(struct adapter *adapter, unsigned int addr,
304842a20397SRahul Lakkireddy 			  unsigned int n, const u8 *data, bool byte_oriented)
3049f7917c00SJeff Kirsher {
3050f7917c00SJeff Kirsher 	unsigned int i, c, left, val, offset = addr & 0xff;
305142a20397SRahul Lakkireddy 	u32 buf[64];
305242a20397SRahul Lakkireddy 	int ret;
3053f7917c00SJeff Kirsher 
3054f7917c00SJeff Kirsher 	if (addr >= adapter->params.sf_size || offset + n > SF_PAGE_SIZE)
3055f7917c00SJeff Kirsher 		return -EINVAL;
3056f7917c00SJeff Kirsher 
3057f7917c00SJeff Kirsher 	val = swab32(addr) | SF_PROG_PAGE;
3058f7917c00SJeff Kirsher 
3059f7917c00SJeff Kirsher 	if ((ret = sf1_write(adapter, 1, 0, 1, SF_WR_ENABLE)) != 0 ||
3060f7917c00SJeff Kirsher 	    (ret = sf1_write(adapter, 4, 1, 1, val)) != 0)
3061f7917c00SJeff Kirsher 		goto unlock;
3062f7917c00SJeff Kirsher 
306342a20397SRahul Lakkireddy 	for (left = n; left; left -= c, data += c) {
3064f7917c00SJeff Kirsher 		c = min(left, 4U);
306542a20397SRahul Lakkireddy 		for (val = 0, i = 0; i < c; ++i) {
306642a20397SRahul Lakkireddy 			if (byte_oriented)
306742a20397SRahul Lakkireddy 				val = (val << 8) + data[i];
306842a20397SRahul Lakkireddy 			else
306942a20397SRahul Lakkireddy 				val = (val << 8) + data[c - i - 1];
307042a20397SRahul Lakkireddy 		}
3071f7917c00SJeff Kirsher 
3072f7917c00SJeff Kirsher 		ret = sf1_write(adapter, c, c != left, 1, val);
3073f7917c00SJeff Kirsher 		if (ret)
3074f7917c00SJeff Kirsher 			goto unlock;
3075f7917c00SJeff Kirsher 	}
3076f7917c00SJeff Kirsher 	ret = flash_wait_op(adapter, 8, 1);
3077f7917c00SJeff Kirsher 	if (ret)
3078f7917c00SJeff Kirsher 		goto unlock;
3079f7917c00SJeff Kirsher 
30800d804338SHariprasad Shenai 	t4_write_reg(adapter, SF_OP_A, 0);    /* unlock SF */
3081f7917c00SJeff Kirsher 
3082f7917c00SJeff Kirsher 	/* Read the page to verify the write succeeded */
308342a20397SRahul Lakkireddy 	ret = t4_read_flash(adapter, addr & ~0xff, ARRAY_SIZE(buf), buf,
308442a20397SRahul Lakkireddy 			    byte_oriented);
3085f7917c00SJeff Kirsher 	if (ret)
3086f7917c00SJeff Kirsher 		return ret;
3087f7917c00SJeff Kirsher 
3088f7917c00SJeff Kirsher 	if (memcmp(data - n, (u8 *)buf + offset, n)) {
3089f7917c00SJeff Kirsher 		dev_err(adapter->pdev_dev,
3090f7917c00SJeff Kirsher 			"failed to correctly write the flash page at %#x\n",
3091f7917c00SJeff Kirsher 			addr);
3092f7917c00SJeff Kirsher 		return -EIO;
3093f7917c00SJeff Kirsher 	}
3094f7917c00SJeff Kirsher 	return 0;
3095f7917c00SJeff Kirsher 
3096f7917c00SJeff Kirsher unlock:
30970d804338SHariprasad Shenai 	t4_write_reg(adapter, SF_OP_A, 0);    /* unlock SF */
3098f7917c00SJeff Kirsher 	return ret;
3099f7917c00SJeff Kirsher }
3100f7917c00SJeff Kirsher 
3101f7917c00SJeff Kirsher /**
310216e47624SHariprasad Shenai  *	t4_get_fw_version - read the firmware version
3103f7917c00SJeff Kirsher  *	@adapter: the adapter
3104f7917c00SJeff Kirsher  *	@vers: where to place the version
3105f7917c00SJeff Kirsher  *
3106f7917c00SJeff Kirsher  *	Reads the FW version from flash.
3107f7917c00SJeff Kirsher  */
t4_get_fw_version(struct adapter * adapter,u32 * vers)310816e47624SHariprasad Shenai int t4_get_fw_version(struct adapter *adapter, u32 *vers)
3109f7917c00SJeff Kirsher {
311016e47624SHariprasad Shenai 	return t4_read_flash(adapter, FLASH_FW_START +
311116e47624SHariprasad Shenai 			     offsetof(struct fw_hdr, fw_ver), 1,
311216e47624SHariprasad Shenai 			     vers, 0);
3113f7917c00SJeff Kirsher }
3114f7917c00SJeff Kirsher 
3115f7917c00SJeff Kirsher /**
31160de72738SHariprasad Shenai  *	t4_get_bs_version - read the firmware bootstrap version
31170de72738SHariprasad Shenai  *	@adapter: the adapter
31180de72738SHariprasad Shenai  *	@vers: where to place the version
31190de72738SHariprasad Shenai  *
31200de72738SHariprasad Shenai  *	Reads the FW Bootstrap version from flash.
31210de72738SHariprasad Shenai  */
t4_get_bs_version(struct adapter * adapter,u32 * vers)31220de72738SHariprasad Shenai int t4_get_bs_version(struct adapter *adapter, u32 *vers)
31230de72738SHariprasad Shenai {
31240de72738SHariprasad Shenai 	return t4_read_flash(adapter, FLASH_FWBOOTSTRAP_START +
31250de72738SHariprasad Shenai 			     offsetof(struct fw_hdr, fw_ver), 1,
31260de72738SHariprasad Shenai 			     vers, 0);
31270de72738SHariprasad Shenai }
31280de72738SHariprasad Shenai 
31290de72738SHariprasad Shenai /**
313016e47624SHariprasad Shenai  *	t4_get_tp_version - read the TP microcode version
3131f7917c00SJeff Kirsher  *	@adapter: the adapter
3132f7917c00SJeff Kirsher  *	@vers: where to place the version
3133f7917c00SJeff Kirsher  *
3134f7917c00SJeff Kirsher  *	Reads the TP microcode version from flash.
3135f7917c00SJeff Kirsher  */
t4_get_tp_version(struct adapter * adapter,u32 * vers)313616e47624SHariprasad Shenai int t4_get_tp_version(struct adapter *adapter, u32 *vers)
3137f7917c00SJeff Kirsher {
313816e47624SHariprasad Shenai 	return t4_read_flash(adapter, FLASH_FW_START +
3139f7917c00SJeff Kirsher 			     offsetof(struct fw_hdr, tp_microcode_ver),
3140f7917c00SJeff Kirsher 			     1, vers, 0);
3141f7917c00SJeff Kirsher }
3142f7917c00SJeff Kirsher 
3143ba3f8cd5SHariprasad Shenai /**
3144ba3f8cd5SHariprasad Shenai  *	t4_get_exprom_version - return the Expansion ROM version (if any)
314529bbf5d7SRahul Lakkireddy  *	@adap: the adapter
3146ba3f8cd5SHariprasad Shenai  *	@vers: where to place the version
3147ba3f8cd5SHariprasad Shenai  *
3148ba3f8cd5SHariprasad Shenai  *	Reads the Expansion ROM header from FLASH and returns the version
3149ba3f8cd5SHariprasad Shenai  *	number (if present) through the @vers return value pointer.  We return
3150ba3f8cd5SHariprasad Shenai  *	this in the Firmware Version Format since it's convenient.  Return
3151ba3f8cd5SHariprasad Shenai  *	0 on success, -ENOENT if no Expansion ROM is present.
3152ba3f8cd5SHariprasad Shenai  */
t4_get_exprom_version(struct adapter * adap,u32 * vers)3153ba3f8cd5SHariprasad Shenai int t4_get_exprom_version(struct adapter *adap, u32 *vers)
3154ba3f8cd5SHariprasad Shenai {
3155ba3f8cd5SHariprasad Shenai 	struct exprom_header {
3156ba3f8cd5SHariprasad Shenai 		unsigned char hdr_arr[16];	/* must start with 0x55aa */
3157ba3f8cd5SHariprasad Shenai 		unsigned char hdr_ver[4];	/* Expansion ROM version */
3158ba3f8cd5SHariprasad Shenai 	} *hdr;
3159ba3f8cd5SHariprasad Shenai 	u32 exprom_header_buf[DIV_ROUND_UP(sizeof(struct exprom_header),
3160ba3f8cd5SHariprasad Shenai 					   sizeof(u32))];
3161ba3f8cd5SHariprasad Shenai 	int ret;
3162ba3f8cd5SHariprasad Shenai 
3163ba3f8cd5SHariprasad Shenai 	ret = t4_read_flash(adap, FLASH_EXP_ROM_START,
3164ba3f8cd5SHariprasad Shenai 			    ARRAY_SIZE(exprom_header_buf), exprom_header_buf,
3165ba3f8cd5SHariprasad Shenai 			    0);
3166ba3f8cd5SHariprasad Shenai 	if (ret)
3167ba3f8cd5SHariprasad Shenai 		return ret;
3168ba3f8cd5SHariprasad Shenai 
3169ba3f8cd5SHariprasad Shenai 	hdr = (struct exprom_header *)exprom_header_buf;
3170ba3f8cd5SHariprasad Shenai 	if (hdr->hdr_arr[0] != 0x55 || hdr->hdr_arr[1] != 0xaa)
3171ba3f8cd5SHariprasad Shenai 		return -ENOENT;
3172ba3f8cd5SHariprasad Shenai 
3173ba3f8cd5SHariprasad Shenai 	*vers = (FW_HDR_FW_VER_MAJOR_V(hdr->hdr_ver[0]) |
3174ba3f8cd5SHariprasad Shenai 		 FW_HDR_FW_VER_MINOR_V(hdr->hdr_ver[1]) |
3175ba3f8cd5SHariprasad Shenai 		 FW_HDR_FW_VER_MICRO_V(hdr->hdr_ver[2]) |
3176ba3f8cd5SHariprasad Shenai 		 FW_HDR_FW_VER_BUILD_V(hdr->hdr_ver[3]));
3177ba3f8cd5SHariprasad Shenai 	return 0;
3178ba3f8cd5SHariprasad Shenai }
3179ba3f8cd5SHariprasad Shenai 
3180a69265e9SHariprasad Shenai /**
3181760446f9SGanesh Goudar  *      t4_get_vpd_version - return the VPD version
3182760446f9SGanesh Goudar  *      @adapter: the adapter
3183760446f9SGanesh Goudar  *      @vers: where to place the version
3184760446f9SGanesh Goudar  *
3185760446f9SGanesh Goudar  *      Reads the VPD via the Firmware interface (thus this can only be called
3186760446f9SGanesh Goudar  *      once we're ready to issue Firmware commands).  The format of the
3187760446f9SGanesh Goudar  *      VPD version is adapter specific.  Returns 0 on success, an error on
3188760446f9SGanesh Goudar  *      failure.
3189760446f9SGanesh Goudar  *
3190760446f9SGanesh Goudar  *      Note that early versions of the Firmware didn't include the ability
3191760446f9SGanesh Goudar  *      to retrieve the VPD version, so we zero-out the return-value parameter
3192760446f9SGanesh Goudar  *      in that case to avoid leaving it with garbage in it.
3193760446f9SGanesh Goudar  *
3194760446f9SGanesh Goudar  *      Also note that the Firmware will return its cached copy of the VPD
3195760446f9SGanesh Goudar  *      Revision ID, not the actual Revision ID as written in the Serial
3196760446f9SGanesh Goudar  *      EEPROM.  This is only an issue if a new VPD has been written and the
3197760446f9SGanesh Goudar  *      Firmware/Chip haven't yet gone through a RESET sequence.  So it's best
3198760446f9SGanesh Goudar  *      to defer calling this routine till after a FW_RESET_CMD has been issued
3199760446f9SGanesh Goudar  *      if the Host Driver will be performing a full adapter initialization.
3200760446f9SGanesh Goudar  */
t4_get_vpd_version(struct adapter * adapter,u32 * vers)3201760446f9SGanesh Goudar int t4_get_vpd_version(struct adapter *adapter, u32 *vers)
3202760446f9SGanesh Goudar {
3203760446f9SGanesh Goudar 	u32 vpdrev_param;
3204760446f9SGanesh Goudar 	int ret;
3205760446f9SGanesh Goudar 
3206760446f9SGanesh Goudar 	vpdrev_param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) |
3207760446f9SGanesh Goudar 			FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_VPDREV));
3208760446f9SGanesh Goudar 	ret = t4_query_params(adapter, adapter->mbox, adapter->pf, 0,
3209760446f9SGanesh Goudar 			      1, &vpdrev_param, vers);
3210760446f9SGanesh Goudar 	if (ret)
3211760446f9SGanesh Goudar 		*vers = 0;
3212760446f9SGanesh Goudar 	return ret;
3213760446f9SGanesh Goudar }
3214760446f9SGanesh Goudar 
3215760446f9SGanesh Goudar /**
3216760446f9SGanesh Goudar  *      t4_get_scfg_version - return the Serial Configuration version
3217760446f9SGanesh Goudar  *      @adapter: the adapter
3218760446f9SGanesh Goudar  *      @vers: where to place the version
3219760446f9SGanesh Goudar  *
3220760446f9SGanesh Goudar  *      Reads the Serial Configuration Version via the Firmware interface
3221760446f9SGanesh Goudar  *      (thus this can only be called once we're ready to issue Firmware
3222760446f9SGanesh Goudar  *      commands).  The format of the Serial Configuration version is
3223760446f9SGanesh Goudar  *      adapter specific.  Returns 0 on success, an error on failure.
3224760446f9SGanesh Goudar  *
3225760446f9SGanesh Goudar  *      Note that early versions of the Firmware didn't include the ability
3226760446f9SGanesh Goudar  *      to retrieve the Serial Configuration version, so we zero-out the
3227760446f9SGanesh Goudar  *      return-value parameter in that case to avoid leaving it with
3228760446f9SGanesh Goudar  *      garbage in it.
3229760446f9SGanesh Goudar  *
3230760446f9SGanesh Goudar  *      Also note that the Firmware will return its cached copy of the Serial
3231760446f9SGanesh Goudar  *      Initialization Revision ID, not the actual Revision ID as written in
3232760446f9SGanesh Goudar  *      the Serial EEPROM.  This is only an issue if a new VPD has been written
3233760446f9SGanesh Goudar  *      and the Firmware/Chip haven't yet gone through a RESET sequence.  So
3234760446f9SGanesh Goudar  *      it's best to defer calling this routine till after a FW_RESET_CMD has
3235760446f9SGanesh Goudar  *      been issued if the Host Driver will be performing a full adapter
3236760446f9SGanesh Goudar  *      initialization.
3237760446f9SGanesh Goudar  */
t4_get_scfg_version(struct adapter * adapter,u32 * vers)3238760446f9SGanesh Goudar int t4_get_scfg_version(struct adapter *adapter, u32 *vers)
3239760446f9SGanesh Goudar {
3240760446f9SGanesh Goudar 	u32 scfgrev_param;
3241760446f9SGanesh Goudar 	int ret;
3242760446f9SGanesh Goudar 
3243760446f9SGanesh Goudar 	scfgrev_param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) |
3244760446f9SGanesh Goudar 			 FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_SCFGREV));
3245760446f9SGanesh Goudar 	ret = t4_query_params(adapter, adapter->mbox, adapter->pf, 0,
3246760446f9SGanesh Goudar 			      1, &scfgrev_param, vers);
3247760446f9SGanesh Goudar 	if (ret)
3248760446f9SGanesh Goudar 		*vers = 0;
3249760446f9SGanesh Goudar 	return ret;
3250760446f9SGanesh Goudar }
3251760446f9SGanesh Goudar 
3252760446f9SGanesh Goudar /**
3253760446f9SGanesh Goudar  *      t4_get_version_info - extract various chip/firmware version information
3254760446f9SGanesh Goudar  *      @adapter: the adapter
3255760446f9SGanesh Goudar  *
3256760446f9SGanesh Goudar  *      Reads various chip/firmware version numbers and stores them into the
3257760446f9SGanesh Goudar  *      adapter Adapter Parameters structure.  If any of the efforts fails
3258760446f9SGanesh Goudar  *      the first failure will be returned, but all of the version numbers
3259760446f9SGanesh Goudar  *      will be read.
3260760446f9SGanesh Goudar  */
t4_get_version_info(struct adapter * adapter)3261760446f9SGanesh Goudar int t4_get_version_info(struct adapter *adapter)
3262760446f9SGanesh Goudar {
3263760446f9SGanesh Goudar 	int ret = 0;
3264760446f9SGanesh Goudar 
3265760446f9SGanesh Goudar 	#define FIRST_RET(__getvinfo) \
3266760446f9SGanesh Goudar 	do { \
3267760446f9SGanesh Goudar 		int __ret = __getvinfo; \
3268760446f9SGanesh Goudar 		if (__ret && !ret) \
3269760446f9SGanesh Goudar 			ret = __ret; \
3270760446f9SGanesh Goudar 	} while (0)
3271760446f9SGanesh Goudar 
3272760446f9SGanesh Goudar 	FIRST_RET(t4_get_fw_version(adapter, &adapter->params.fw_vers));
3273760446f9SGanesh Goudar 	FIRST_RET(t4_get_bs_version(adapter, &adapter->params.bs_vers));
3274760446f9SGanesh Goudar 	FIRST_RET(t4_get_tp_version(adapter, &adapter->params.tp_vers));
3275760446f9SGanesh Goudar 	FIRST_RET(t4_get_exprom_version(adapter, &adapter->params.er_vers));
3276760446f9SGanesh Goudar 	FIRST_RET(t4_get_scfg_version(adapter, &adapter->params.scfg_vers));
3277760446f9SGanesh Goudar 	FIRST_RET(t4_get_vpd_version(adapter, &adapter->params.vpd_vers));
3278760446f9SGanesh Goudar 
3279760446f9SGanesh Goudar 	#undef FIRST_RET
3280760446f9SGanesh Goudar 	return ret;
3281760446f9SGanesh Goudar }
3282760446f9SGanesh Goudar 
3283760446f9SGanesh Goudar /**
3284760446f9SGanesh Goudar  *      t4_dump_version_info - dump all of the adapter configuration IDs
3285760446f9SGanesh Goudar  *      @adapter: the adapter
3286760446f9SGanesh Goudar  *
3287760446f9SGanesh Goudar  *      Dumps all of the various bits of adapter configuration version/revision
3288760446f9SGanesh Goudar  *      IDs information.  This is typically called at some point after
3289760446f9SGanesh Goudar  *      t4_get_version_info() has been called.
3290760446f9SGanesh Goudar  */
t4_dump_version_info(struct adapter * adapter)3291760446f9SGanesh Goudar void t4_dump_version_info(struct adapter *adapter)
3292760446f9SGanesh Goudar {
3293760446f9SGanesh Goudar 	/* Device information */
3294760446f9SGanesh Goudar 	dev_info(adapter->pdev_dev, "Chelsio %s rev %d\n",
3295760446f9SGanesh Goudar 		 adapter->params.vpd.id,
3296760446f9SGanesh Goudar 		 CHELSIO_CHIP_RELEASE(adapter->params.chip));
3297760446f9SGanesh Goudar 	dev_info(adapter->pdev_dev, "S/N: %s, P/N: %s\n",
3298760446f9SGanesh Goudar 		 adapter->params.vpd.sn, adapter->params.vpd.pn);
3299760446f9SGanesh Goudar 
3300760446f9SGanesh Goudar 	/* Firmware Version */
3301760446f9SGanesh Goudar 	if (!adapter->params.fw_vers)
3302760446f9SGanesh Goudar 		dev_warn(adapter->pdev_dev, "No firmware loaded\n");
3303760446f9SGanesh Goudar 	else
3304760446f9SGanesh Goudar 		dev_info(adapter->pdev_dev, "Firmware version: %u.%u.%u.%u\n",
3305760446f9SGanesh Goudar 			 FW_HDR_FW_VER_MAJOR_G(adapter->params.fw_vers),
3306760446f9SGanesh Goudar 			 FW_HDR_FW_VER_MINOR_G(adapter->params.fw_vers),
3307760446f9SGanesh Goudar 			 FW_HDR_FW_VER_MICRO_G(adapter->params.fw_vers),
3308760446f9SGanesh Goudar 			 FW_HDR_FW_VER_BUILD_G(adapter->params.fw_vers));
3309760446f9SGanesh Goudar 
3310760446f9SGanesh Goudar 	/* Bootstrap Firmware Version. (Some adapters don't have Bootstrap
3311760446f9SGanesh Goudar 	 * Firmware, so dev_info() is more appropriate here.)
3312760446f9SGanesh Goudar 	 */
3313760446f9SGanesh Goudar 	if (!adapter->params.bs_vers)
3314760446f9SGanesh Goudar 		dev_info(adapter->pdev_dev, "No bootstrap loaded\n");
3315760446f9SGanesh Goudar 	else
3316760446f9SGanesh Goudar 		dev_info(adapter->pdev_dev, "Bootstrap version: %u.%u.%u.%u\n",
3317760446f9SGanesh Goudar 			 FW_HDR_FW_VER_MAJOR_G(adapter->params.bs_vers),
3318760446f9SGanesh Goudar 			 FW_HDR_FW_VER_MINOR_G(adapter->params.bs_vers),
3319760446f9SGanesh Goudar 			 FW_HDR_FW_VER_MICRO_G(adapter->params.bs_vers),
3320760446f9SGanesh Goudar 			 FW_HDR_FW_VER_BUILD_G(adapter->params.bs_vers));
3321760446f9SGanesh Goudar 
3322760446f9SGanesh Goudar 	/* TP Microcode Version */
3323760446f9SGanesh Goudar 	if (!adapter->params.tp_vers)
3324760446f9SGanesh Goudar 		dev_warn(adapter->pdev_dev, "No TP Microcode loaded\n");
3325760446f9SGanesh Goudar 	else
3326760446f9SGanesh Goudar 		dev_info(adapter->pdev_dev,
3327760446f9SGanesh Goudar 			 "TP Microcode version: %u.%u.%u.%u\n",
3328760446f9SGanesh Goudar 			 FW_HDR_FW_VER_MAJOR_G(adapter->params.tp_vers),
3329760446f9SGanesh Goudar 			 FW_HDR_FW_VER_MINOR_G(adapter->params.tp_vers),
3330760446f9SGanesh Goudar 			 FW_HDR_FW_VER_MICRO_G(adapter->params.tp_vers),
3331760446f9SGanesh Goudar 			 FW_HDR_FW_VER_BUILD_G(adapter->params.tp_vers));
3332760446f9SGanesh Goudar 
3333760446f9SGanesh Goudar 	/* Expansion ROM version */
3334760446f9SGanesh Goudar 	if (!adapter->params.er_vers)
3335760446f9SGanesh Goudar 		dev_info(adapter->pdev_dev, "No Expansion ROM loaded\n");
3336760446f9SGanesh Goudar 	else
3337760446f9SGanesh Goudar 		dev_info(adapter->pdev_dev,
3338760446f9SGanesh Goudar 			 "Expansion ROM version: %u.%u.%u.%u\n",
3339760446f9SGanesh Goudar 			 FW_HDR_FW_VER_MAJOR_G(adapter->params.er_vers),
3340760446f9SGanesh Goudar 			 FW_HDR_FW_VER_MINOR_G(adapter->params.er_vers),
3341760446f9SGanesh Goudar 			 FW_HDR_FW_VER_MICRO_G(adapter->params.er_vers),
3342760446f9SGanesh Goudar 			 FW_HDR_FW_VER_BUILD_G(adapter->params.er_vers));
3343760446f9SGanesh Goudar 
3344760446f9SGanesh Goudar 	/* Serial Configuration version */
3345760446f9SGanesh Goudar 	dev_info(adapter->pdev_dev, "Serial Configuration version: %#x\n",
3346760446f9SGanesh Goudar 		 adapter->params.scfg_vers);
3347760446f9SGanesh Goudar 
3348760446f9SGanesh Goudar 	/* VPD Version */
3349760446f9SGanesh Goudar 	dev_info(adapter->pdev_dev, "VPD version: %#x\n",
3350760446f9SGanesh Goudar 		 adapter->params.vpd_vers);
3351760446f9SGanesh Goudar }
3352760446f9SGanesh Goudar 
3353760446f9SGanesh Goudar /**
3354a69265e9SHariprasad Shenai  *	t4_check_fw_version - check if the FW is supported with this driver
3355a69265e9SHariprasad Shenai  *	@adap: the adapter
3356a69265e9SHariprasad Shenai  *
3357a69265e9SHariprasad Shenai  *	Checks if an adapter's FW is compatible with the driver.  Returns 0
3358a69265e9SHariprasad Shenai  *	if there's exact match, a negative error if the version could not be
3359a69265e9SHariprasad Shenai  *	read or there's a major version mismatch
3360a69265e9SHariprasad Shenai  */
t4_check_fw_version(struct adapter * adap)3361a69265e9SHariprasad Shenai int t4_check_fw_version(struct adapter *adap)
3362a69265e9SHariprasad Shenai {
336321d11bd6SHariprasad Shenai 	int i, ret, major, minor, micro;
3364a69265e9SHariprasad Shenai 	int exp_major, exp_minor, exp_micro;
3365a69265e9SHariprasad Shenai 	unsigned int chip_version = CHELSIO_CHIP_VERSION(adap->params.chip);
3366a69265e9SHariprasad Shenai 
3367a69265e9SHariprasad Shenai 	ret = t4_get_fw_version(adap, &adap->params.fw_vers);
336821d11bd6SHariprasad Shenai 	/* Try multiple times before returning error */
336921d11bd6SHariprasad Shenai 	for (i = 0; (ret == -EBUSY || ret == -EAGAIN) && i < 3; i++)
337021d11bd6SHariprasad Shenai 		ret = t4_get_fw_version(adap, &adap->params.fw_vers);
337121d11bd6SHariprasad Shenai 
3372a69265e9SHariprasad Shenai 	if (ret)
3373a69265e9SHariprasad Shenai 		return ret;
3374a69265e9SHariprasad Shenai 
3375a69265e9SHariprasad Shenai 	major = FW_HDR_FW_VER_MAJOR_G(adap->params.fw_vers);
3376a69265e9SHariprasad Shenai 	minor = FW_HDR_FW_VER_MINOR_G(adap->params.fw_vers);
3377a69265e9SHariprasad Shenai 	micro = FW_HDR_FW_VER_MICRO_G(adap->params.fw_vers);
3378a69265e9SHariprasad Shenai 
3379a69265e9SHariprasad Shenai 	switch (chip_version) {
3380a69265e9SHariprasad Shenai 	case CHELSIO_T4:
3381a69265e9SHariprasad Shenai 		exp_major = T4FW_MIN_VERSION_MAJOR;
3382a69265e9SHariprasad Shenai 		exp_minor = T4FW_MIN_VERSION_MINOR;
3383a69265e9SHariprasad Shenai 		exp_micro = T4FW_MIN_VERSION_MICRO;
3384a69265e9SHariprasad Shenai 		break;
3385a69265e9SHariprasad Shenai 	case CHELSIO_T5:
3386a69265e9SHariprasad Shenai 		exp_major = T5FW_MIN_VERSION_MAJOR;
3387a69265e9SHariprasad Shenai 		exp_minor = T5FW_MIN_VERSION_MINOR;
3388a69265e9SHariprasad Shenai 		exp_micro = T5FW_MIN_VERSION_MICRO;
3389a69265e9SHariprasad Shenai 		break;
3390a69265e9SHariprasad Shenai 	case CHELSIO_T6:
3391a69265e9SHariprasad Shenai 		exp_major = T6FW_MIN_VERSION_MAJOR;
3392a69265e9SHariprasad Shenai 		exp_minor = T6FW_MIN_VERSION_MINOR;
3393a69265e9SHariprasad Shenai 		exp_micro = T6FW_MIN_VERSION_MICRO;
3394a69265e9SHariprasad Shenai 		break;
3395a69265e9SHariprasad Shenai 	default:
3396a69265e9SHariprasad Shenai 		dev_err(adap->pdev_dev, "Unsupported chip type, %x\n",
3397a69265e9SHariprasad Shenai 			adap->chip);
3398a69265e9SHariprasad Shenai 		return -EINVAL;
3399a69265e9SHariprasad Shenai 	}
3400a69265e9SHariprasad Shenai 
3401a69265e9SHariprasad Shenai 	if (major < exp_major || (major == exp_major && minor < exp_minor) ||
3402a69265e9SHariprasad Shenai 	    (major == exp_major && minor == exp_minor && micro < exp_micro)) {
3403a69265e9SHariprasad Shenai 		dev_err(adap->pdev_dev,
3404a69265e9SHariprasad Shenai 			"Card has firmware version %u.%u.%u, minimum "
3405a69265e9SHariprasad Shenai 			"supported firmware is %u.%u.%u.\n", major, minor,
3406a69265e9SHariprasad Shenai 			micro, exp_major, exp_minor, exp_micro);
3407a69265e9SHariprasad Shenai 		return -EFAULT;
3408a69265e9SHariprasad Shenai 	}
3409a69265e9SHariprasad Shenai 	return 0;
3410a69265e9SHariprasad Shenai }
3411a69265e9SHariprasad Shenai 
341216e47624SHariprasad Shenai /* Is the given firmware API compatible with the one the driver was compiled
341316e47624SHariprasad Shenai  * with?
3414f7917c00SJeff Kirsher  */
fw_compatible(const struct fw_hdr * hdr1,const struct fw_hdr * hdr2)341516e47624SHariprasad Shenai static int fw_compatible(const struct fw_hdr *hdr1, const struct fw_hdr *hdr2)
3416f7917c00SJeff Kirsher {
3417f7917c00SJeff Kirsher 
341816e47624SHariprasad Shenai 	/* short circuit if it's the exact same firmware version */
341916e47624SHariprasad Shenai 	if (hdr1->chip == hdr2->chip && hdr1->fw_ver == hdr2->fw_ver)
3420f7917c00SJeff Kirsher 		return 1;
342116e47624SHariprasad Shenai 
342216e47624SHariprasad Shenai #define SAME_INTF(x) (hdr1->intfver_##x == hdr2->intfver_##x)
342316e47624SHariprasad Shenai 	if (hdr1->chip == hdr2->chip && SAME_INTF(nic) && SAME_INTF(vnic) &&
342416e47624SHariprasad Shenai 	    SAME_INTF(ri) && SAME_INTF(iscsi) && SAME_INTF(fcoe))
342516e47624SHariprasad Shenai 		return 1;
342616e47624SHariprasad Shenai #undef SAME_INTF
342716e47624SHariprasad Shenai 
342816e47624SHariprasad Shenai 	return 0;
342916e47624SHariprasad Shenai }
343016e47624SHariprasad Shenai 
343116e47624SHariprasad Shenai /* The firmware in the filesystem is usable, but should it be installed?
343216e47624SHariprasad Shenai  * This routine explains itself in detail if it indicates the filesystem
343316e47624SHariprasad Shenai  * firmware should be installed.
343416e47624SHariprasad Shenai  */
should_install_fs_fw(struct adapter * adap,int card_fw_usable,int k,int c)343516e47624SHariprasad Shenai static int should_install_fs_fw(struct adapter *adap, int card_fw_usable,
343616e47624SHariprasad Shenai 				int k, int c)
343716e47624SHariprasad Shenai {
343816e47624SHariprasad Shenai 	const char *reason;
343916e47624SHariprasad Shenai 
344016e47624SHariprasad Shenai 	if (!card_fw_usable) {
344116e47624SHariprasad Shenai 		reason = "incompatible or unusable";
344216e47624SHariprasad Shenai 		goto install;
344316e47624SHariprasad Shenai 	}
344416e47624SHariprasad Shenai 
344516e47624SHariprasad Shenai 	if (k > c) {
344616e47624SHariprasad Shenai 		reason = "older than the version supported with this driver";
344716e47624SHariprasad Shenai 		goto install;
344816e47624SHariprasad Shenai 	}
344916e47624SHariprasad Shenai 
345016e47624SHariprasad Shenai 	return 0;
345116e47624SHariprasad Shenai 
345216e47624SHariprasad Shenai install:
345316e47624SHariprasad Shenai 	dev_err(adap->pdev_dev, "firmware on card (%u.%u.%u.%u) is %s, "
345416e47624SHariprasad Shenai 		"installing firmware %u.%u.%u.%u on card.\n",
3455b2e1a3f0SHariprasad Shenai 		FW_HDR_FW_VER_MAJOR_G(c), FW_HDR_FW_VER_MINOR_G(c),
3456b2e1a3f0SHariprasad Shenai 		FW_HDR_FW_VER_MICRO_G(c), FW_HDR_FW_VER_BUILD_G(c), reason,
3457b2e1a3f0SHariprasad Shenai 		FW_HDR_FW_VER_MAJOR_G(k), FW_HDR_FW_VER_MINOR_G(k),
3458b2e1a3f0SHariprasad Shenai 		FW_HDR_FW_VER_MICRO_G(k), FW_HDR_FW_VER_BUILD_G(k));
345916e47624SHariprasad Shenai 
346016e47624SHariprasad Shenai 	return 1;
346116e47624SHariprasad Shenai }
346216e47624SHariprasad Shenai 
t4_prep_fw(struct adapter * adap,struct fw_info * fw_info,const u8 * fw_data,unsigned int fw_size,struct fw_hdr * card_fw,enum dev_state state,int * reset)346316e47624SHariprasad Shenai int t4_prep_fw(struct adapter *adap, struct fw_info *fw_info,
346416e47624SHariprasad Shenai 	       const u8 *fw_data, unsigned int fw_size,
346516e47624SHariprasad Shenai 	       struct fw_hdr *card_fw, enum dev_state state,
346616e47624SHariprasad Shenai 	       int *reset)
346716e47624SHariprasad Shenai {
346816e47624SHariprasad Shenai 	int ret, card_fw_usable, fs_fw_usable;
346916e47624SHariprasad Shenai 	const struct fw_hdr *fs_fw;
347016e47624SHariprasad Shenai 	const struct fw_hdr *drv_fw;
347116e47624SHariprasad Shenai 
347216e47624SHariprasad Shenai 	drv_fw = &fw_info->fw_hdr;
347316e47624SHariprasad Shenai 
347416e47624SHariprasad Shenai 	/* Read the header of the firmware on the card */
34758a259e6bSLi Heng 	ret = t4_read_flash(adap, FLASH_FW_START,
347616e47624SHariprasad Shenai 			    sizeof(*card_fw) / sizeof(uint32_t),
347716e47624SHariprasad Shenai 			    (uint32_t *)card_fw, 1);
347816e47624SHariprasad Shenai 	if (ret == 0) {
347916e47624SHariprasad Shenai 		card_fw_usable = fw_compatible(drv_fw, (const void *)card_fw);
348016e47624SHariprasad Shenai 	} else {
348116e47624SHariprasad Shenai 		dev_err(adap->pdev_dev,
348216e47624SHariprasad Shenai 			"Unable to read card's firmware header: %d\n", ret);
348316e47624SHariprasad Shenai 		card_fw_usable = 0;
348416e47624SHariprasad Shenai 	}
348516e47624SHariprasad Shenai 
348616e47624SHariprasad Shenai 	if (fw_data != NULL) {
348716e47624SHariprasad Shenai 		fs_fw = (const void *)fw_data;
348816e47624SHariprasad Shenai 		fs_fw_usable = fw_compatible(drv_fw, fs_fw);
348916e47624SHariprasad Shenai 	} else {
349016e47624SHariprasad Shenai 		fs_fw = NULL;
349116e47624SHariprasad Shenai 		fs_fw_usable = 0;
349216e47624SHariprasad Shenai 	}
349316e47624SHariprasad Shenai 
349416e47624SHariprasad Shenai 	if (card_fw_usable && card_fw->fw_ver == drv_fw->fw_ver &&
349516e47624SHariprasad Shenai 	    (!fs_fw_usable || fs_fw->fw_ver == drv_fw->fw_ver)) {
349616e47624SHariprasad Shenai 		/* Common case: the firmware on the card is an exact match and
349716e47624SHariprasad Shenai 		 * the filesystem one is an exact match too, or the filesystem
349816e47624SHariprasad Shenai 		 * one is absent/incompatible.
349916e47624SHariprasad Shenai 		 */
350016e47624SHariprasad Shenai 	} else if (fs_fw_usable && state == DEV_STATE_UNINIT &&
350116e47624SHariprasad Shenai 		   should_install_fs_fw(adap, card_fw_usable,
350216e47624SHariprasad Shenai 					be32_to_cpu(fs_fw->fw_ver),
350316e47624SHariprasad Shenai 					be32_to_cpu(card_fw->fw_ver))) {
35048a259e6bSLi Heng 		ret = t4_fw_upgrade(adap, adap->mbox, fw_data,
350516e47624SHariprasad Shenai 				    fw_size, 0);
350616e47624SHariprasad Shenai 		if (ret != 0) {
350716e47624SHariprasad Shenai 			dev_err(adap->pdev_dev,
350816e47624SHariprasad Shenai 				"failed to install firmware: %d\n", ret);
350916e47624SHariprasad Shenai 			goto bye;
351016e47624SHariprasad Shenai 		}
351116e47624SHariprasad Shenai 
351216e47624SHariprasad Shenai 		/* Installed successfully, update the cached header too. */
3513e3d50738SHariprasad Shenai 		*card_fw = *fs_fw;
351416e47624SHariprasad Shenai 		card_fw_usable = 1;
351516e47624SHariprasad Shenai 		*reset = 0;	/* already reset as part of load_fw */
351616e47624SHariprasad Shenai 	}
351716e47624SHariprasad Shenai 
351816e47624SHariprasad Shenai 	if (!card_fw_usable) {
351916e47624SHariprasad Shenai 		uint32_t d, c, k;
352016e47624SHariprasad Shenai 
352116e47624SHariprasad Shenai 		d = be32_to_cpu(drv_fw->fw_ver);
352216e47624SHariprasad Shenai 		c = be32_to_cpu(card_fw->fw_ver);
352316e47624SHariprasad Shenai 		k = fs_fw ? be32_to_cpu(fs_fw->fw_ver) : 0;
352416e47624SHariprasad Shenai 
352516e47624SHariprasad Shenai 		dev_err(adap->pdev_dev, "Cannot find a usable firmware: "
352616e47624SHariprasad Shenai 			"chip state %d, "
352716e47624SHariprasad Shenai 			"driver compiled with %d.%d.%d.%d, "
352816e47624SHariprasad Shenai 			"card has %d.%d.%d.%d, filesystem has %d.%d.%d.%d\n",
352916e47624SHariprasad Shenai 			state,
3530b2e1a3f0SHariprasad Shenai 			FW_HDR_FW_VER_MAJOR_G(d), FW_HDR_FW_VER_MINOR_G(d),
3531b2e1a3f0SHariprasad Shenai 			FW_HDR_FW_VER_MICRO_G(d), FW_HDR_FW_VER_BUILD_G(d),
3532b2e1a3f0SHariprasad Shenai 			FW_HDR_FW_VER_MAJOR_G(c), FW_HDR_FW_VER_MINOR_G(c),
3533b2e1a3f0SHariprasad Shenai 			FW_HDR_FW_VER_MICRO_G(c), FW_HDR_FW_VER_BUILD_G(c),
3534b2e1a3f0SHariprasad Shenai 			FW_HDR_FW_VER_MAJOR_G(k), FW_HDR_FW_VER_MINOR_G(k),
3535b2e1a3f0SHariprasad Shenai 			FW_HDR_FW_VER_MICRO_G(k), FW_HDR_FW_VER_BUILD_G(k));
35368a259e6bSLi Heng 		ret = -EINVAL;
353716e47624SHariprasad Shenai 		goto bye;
353816e47624SHariprasad Shenai 	}
353916e47624SHariprasad Shenai 
354016e47624SHariprasad Shenai 	/* We're using whatever's on the card and it's known to be good. */
354116e47624SHariprasad Shenai 	adap->params.fw_vers = be32_to_cpu(card_fw->fw_ver);
354216e47624SHariprasad Shenai 	adap->params.tp_vers = be32_to_cpu(card_fw->tp_microcode_ver);
354316e47624SHariprasad Shenai 
354416e47624SHariprasad Shenai bye:
354516e47624SHariprasad Shenai 	return ret;
3546f7917c00SJeff Kirsher }
3547f7917c00SJeff Kirsher 
3548f7917c00SJeff Kirsher /**
3549f7917c00SJeff Kirsher  *	t4_flash_erase_sectors - erase a range of flash sectors
3550f7917c00SJeff Kirsher  *	@adapter: the adapter
3551f7917c00SJeff Kirsher  *	@start: the first sector to erase
3552f7917c00SJeff Kirsher  *	@end: the last sector to erase
3553f7917c00SJeff Kirsher  *
3554f7917c00SJeff Kirsher  *	Erases the sectors in the given inclusive range.
3555f7917c00SJeff Kirsher  */
t4_flash_erase_sectors(struct adapter * adapter,int start,int end)3556f7917c00SJeff Kirsher static int t4_flash_erase_sectors(struct adapter *adapter, int start, int end)
3557f7917c00SJeff Kirsher {
3558f7917c00SJeff Kirsher 	int ret = 0;
3559f7917c00SJeff Kirsher 
3560c0d5b8cfSHariprasad Shenai 	if (end >= adapter->params.sf_nsec)
3561c0d5b8cfSHariprasad Shenai 		return -EINVAL;
3562c0d5b8cfSHariprasad Shenai 
3563f7917c00SJeff Kirsher 	while (start <= end) {
3564f7917c00SJeff Kirsher 		if ((ret = sf1_write(adapter, 1, 0, 1, SF_WR_ENABLE)) != 0 ||
3565f7917c00SJeff Kirsher 		    (ret = sf1_write(adapter, 4, 0, 1,
3566f7917c00SJeff Kirsher 				     SF_ERASE_SECTOR | (start << 8))) != 0 ||
3567f7917c00SJeff Kirsher 		    (ret = flash_wait_op(adapter, 14, 500)) != 0) {
3568f7917c00SJeff Kirsher 			dev_err(adapter->pdev_dev,
3569f7917c00SJeff Kirsher 				"erase of flash sector %d failed, error %d\n",
3570f7917c00SJeff Kirsher 				start, ret);
3571f7917c00SJeff Kirsher 			break;
3572f7917c00SJeff Kirsher 		}
3573f7917c00SJeff Kirsher 		start++;
3574f7917c00SJeff Kirsher 	}
35750d804338SHariprasad Shenai 	t4_write_reg(adapter, SF_OP_A, 0);    /* unlock SF */
3576f7917c00SJeff Kirsher 	return ret;
3577f7917c00SJeff Kirsher }
3578f7917c00SJeff Kirsher 
3579f7917c00SJeff Kirsher /**
3580636f9d37SVipul Pandya  *	t4_flash_cfg_addr - return the address of the flash configuration file
3581636f9d37SVipul Pandya  *	@adapter: the adapter
3582636f9d37SVipul Pandya  *
3583636f9d37SVipul Pandya  *	Return the address within the flash where the Firmware Configuration
3584636f9d37SVipul Pandya  *	File is stored.
3585636f9d37SVipul Pandya  */
t4_flash_cfg_addr(struct adapter * adapter)3586636f9d37SVipul Pandya unsigned int t4_flash_cfg_addr(struct adapter *adapter)
3587636f9d37SVipul Pandya {
3588636f9d37SVipul Pandya 	if (adapter->params.sf_size == 0x100000)
3589636f9d37SVipul Pandya 		return FLASH_FPGA_CFG_START;
3590636f9d37SVipul Pandya 	else
3591636f9d37SVipul Pandya 		return FLASH_CFG_START;
3592636f9d37SVipul Pandya }
3593636f9d37SVipul Pandya 
359479af221dSHariprasad Shenai /* Return TRUE if the specified firmware matches the adapter.  I.e. T4
359579af221dSHariprasad Shenai  * firmware for T4 adapters, T5 firmware for T5 adapters, etc.  We go ahead
359679af221dSHariprasad Shenai  * and emit an error message for mismatched firmware to save our caller the
359779af221dSHariprasad Shenai  * effort ...
359879af221dSHariprasad Shenai  */
t4_fw_matches_chip(const struct adapter * adap,const struct fw_hdr * hdr)359979af221dSHariprasad Shenai static bool t4_fw_matches_chip(const struct adapter *adap,
360079af221dSHariprasad Shenai 			       const struct fw_hdr *hdr)
360179af221dSHariprasad Shenai {
360279af221dSHariprasad Shenai 	/* The expression below will return FALSE for any unsupported adapter
360379af221dSHariprasad Shenai 	 * which will keep us "honest" in the future ...
360479af221dSHariprasad Shenai 	 */
360579af221dSHariprasad Shenai 	if ((is_t4(adap->params.chip) && hdr->chip == FW_HDR_CHIP_T4) ||
36063ccc6cf7SHariprasad Shenai 	    (is_t5(adap->params.chip) && hdr->chip == FW_HDR_CHIP_T5) ||
36073ccc6cf7SHariprasad Shenai 	    (is_t6(adap->params.chip) && hdr->chip == FW_HDR_CHIP_T6))
360879af221dSHariprasad Shenai 		return true;
360979af221dSHariprasad Shenai 
361079af221dSHariprasad Shenai 	dev_err(adap->pdev_dev,
361179af221dSHariprasad Shenai 		"FW image (%d) is not suitable for this adapter (%d)\n",
361279af221dSHariprasad Shenai 		hdr->chip, CHELSIO_CHIP_VERSION(adap->params.chip));
361379af221dSHariprasad Shenai 	return false;
361479af221dSHariprasad Shenai }
361579af221dSHariprasad Shenai 
3616636f9d37SVipul Pandya /**
3617f7917c00SJeff Kirsher  *	t4_load_fw - download firmware
3618f7917c00SJeff Kirsher  *	@adap: the adapter
3619f7917c00SJeff Kirsher  *	@fw_data: the firmware image to write
3620f7917c00SJeff Kirsher  *	@size: image size
3621f7917c00SJeff Kirsher  *
3622f7917c00SJeff Kirsher  *	Write the supplied firmware image to the card's serial flash.
3623f7917c00SJeff Kirsher  */
t4_load_fw(struct adapter * adap,const u8 * fw_data,unsigned int size)3624f7917c00SJeff Kirsher int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size)
3625f7917c00SJeff Kirsher {
3626f7917c00SJeff Kirsher 	u32 csum;
3627f7917c00SJeff Kirsher 	int ret, addr;
3628f7917c00SJeff Kirsher 	unsigned int i;
3629f7917c00SJeff Kirsher 	u8 first_page[SF_PAGE_SIZE];
3630404d9e3fSVipul Pandya 	const __be32 *p = (const __be32 *)fw_data;
3631f7917c00SJeff Kirsher 	const struct fw_hdr *hdr = (const struct fw_hdr *)fw_data;
3632f7917c00SJeff Kirsher 	unsigned int sf_sec_size = adap->params.sf_size / adap->params.sf_nsec;
363315962a18SArjun Vynipadath 	unsigned int fw_start_sec = FLASH_FW_START_SEC;
363415962a18SArjun Vynipadath 	unsigned int fw_size = FLASH_FW_MAX_SIZE;
363515962a18SArjun Vynipadath 	unsigned int fw_start = FLASH_FW_START;
3636f7917c00SJeff Kirsher 
3637f7917c00SJeff Kirsher 	if (!size) {
3638f7917c00SJeff Kirsher 		dev_err(adap->pdev_dev, "FW image has no data\n");
3639f7917c00SJeff Kirsher 		return -EINVAL;
3640f7917c00SJeff Kirsher 	}
3641f7917c00SJeff Kirsher 	if (size & 511) {
3642f7917c00SJeff Kirsher 		dev_err(adap->pdev_dev,
3643f7917c00SJeff Kirsher 			"FW image size not multiple of 512 bytes\n");
3644f7917c00SJeff Kirsher 		return -EINVAL;
3645f7917c00SJeff Kirsher 	}
3646f404f80cSHariprasad Shenai 	if ((unsigned int)be16_to_cpu(hdr->len512) * 512 != size) {
3647f7917c00SJeff Kirsher 		dev_err(adap->pdev_dev,
3648f7917c00SJeff Kirsher 			"FW image size differs from size in FW header\n");
3649f7917c00SJeff Kirsher 		return -EINVAL;
3650f7917c00SJeff Kirsher 	}
365115962a18SArjun Vynipadath 	if (size > fw_size) {
3652f7917c00SJeff Kirsher 		dev_err(adap->pdev_dev, "FW image too large, max is %u bytes\n",
365315962a18SArjun Vynipadath 			fw_size);
3654f7917c00SJeff Kirsher 		return -EFBIG;
3655f7917c00SJeff Kirsher 	}
365679af221dSHariprasad Shenai 	if (!t4_fw_matches_chip(adap, hdr))
365779af221dSHariprasad Shenai 		return -EINVAL;
3658f7917c00SJeff Kirsher 
3659f7917c00SJeff Kirsher 	for (csum = 0, i = 0; i < size / sizeof(csum); i++)
3660f404f80cSHariprasad Shenai 		csum += be32_to_cpu(p[i]);
3661f7917c00SJeff Kirsher 
3662f7917c00SJeff Kirsher 	if (csum != 0xffffffff) {
3663f7917c00SJeff Kirsher 		dev_err(adap->pdev_dev,
3664f7917c00SJeff Kirsher 			"corrupted firmware image, checksum %#x\n", csum);
3665f7917c00SJeff Kirsher 		return -EINVAL;
3666f7917c00SJeff Kirsher 	}
3667f7917c00SJeff Kirsher 
3668f7917c00SJeff Kirsher 	i = DIV_ROUND_UP(size, sf_sec_size);        /* # of sectors spanned */
3669f7917c00SJeff Kirsher 	ret = t4_flash_erase_sectors(adap, fw_start_sec, fw_start_sec + i - 1);
3670f7917c00SJeff Kirsher 	if (ret)
3671f7917c00SJeff Kirsher 		goto out;
3672f7917c00SJeff Kirsher 
3673f7917c00SJeff Kirsher 	/*
3674f7917c00SJeff Kirsher 	 * We write the correct version at the end so the driver can see a bad
3675f7917c00SJeff Kirsher 	 * version if the FW write fails.  Start by writing a copy of the
3676f7917c00SJeff Kirsher 	 * first page with a bad version.
3677f7917c00SJeff Kirsher 	 */
3678f7917c00SJeff Kirsher 	memcpy(first_page, fw_data, SF_PAGE_SIZE);
3679f404f80cSHariprasad Shenai 	((struct fw_hdr *)first_page)->fw_ver = cpu_to_be32(0xffffffff);
368042a20397SRahul Lakkireddy 	ret = t4_write_flash(adap, fw_start, SF_PAGE_SIZE, first_page, true);
3681f7917c00SJeff Kirsher 	if (ret)
3682f7917c00SJeff Kirsher 		goto out;
3683f7917c00SJeff Kirsher 
368415962a18SArjun Vynipadath 	addr = fw_start;
3685f7917c00SJeff Kirsher 	for (size -= SF_PAGE_SIZE; size; size -= SF_PAGE_SIZE) {
3686f7917c00SJeff Kirsher 		addr += SF_PAGE_SIZE;
3687f7917c00SJeff Kirsher 		fw_data += SF_PAGE_SIZE;
368842a20397SRahul Lakkireddy 		ret = t4_write_flash(adap, addr, SF_PAGE_SIZE, fw_data, true);
3689f7917c00SJeff Kirsher 		if (ret)
3690f7917c00SJeff Kirsher 			goto out;
3691f7917c00SJeff Kirsher 	}
3692f7917c00SJeff Kirsher 
369342a20397SRahul Lakkireddy 	ret = t4_write_flash(adap, fw_start + offsetof(struct fw_hdr, fw_ver),
369442a20397SRahul Lakkireddy 			     sizeof(hdr->fw_ver), (const u8 *)&hdr->fw_ver,
369542a20397SRahul Lakkireddy 			     true);
3696f7917c00SJeff Kirsher out:
3697f7917c00SJeff Kirsher 	if (ret)
3698f7917c00SJeff Kirsher 		dev_err(adap->pdev_dev, "firmware download failed, error %d\n",
3699f7917c00SJeff Kirsher 			ret);
3700dff04bceSHariprasad Shenai 	else
3701dff04bceSHariprasad Shenai 		ret = t4_get_fw_version(adap, &adap->params.fw_vers);
3702f7917c00SJeff Kirsher 	return ret;
3703f7917c00SJeff Kirsher }
3704f7917c00SJeff Kirsher 
370549216c1cSHariprasad Shenai /**
370601b69614SHariprasad Shenai  *	t4_phy_fw_ver - return current PHY firmware version
370701b69614SHariprasad Shenai  *	@adap: the adapter
370801b69614SHariprasad Shenai  *	@phy_fw_ver: return value buffer for PHY firmware version
370901b69614SHariprasad Shenai  *
371001b69614SHariprasad Shenai  *	Returns the current version of external PHY firmware on the
371101b69614SHariprasad Shenai  *	adapter.
371201b69614SHariprasad Shenai  */
t4_phy_fw_ver(struct adapter * adap,int * phy_fw_ver)371301b69614SHariprasad Shenai int t4_phy_fw_ver(struct adapter *adap, int *phy_fw_ver)
371401b69614SHariprasad Shenai {
371501b69614SHariprasad Shenai 	u32 param, val;
371601b69614SHariprasad Shenai 	int ret;
371701b69614SHariprasad Shenai 
371801b69614SHariprasad Shenai 	param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) |
371901b69614SHariprasad Shenai 		 FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_PHYFW) |
372001b69614SHariprasad Shenai 		 FW_PARAMS_PARAM_Y_V(adap->params.portvec) |
372101b69614SHariprasad Shenai 		 FW_PARAMS_PARAM_Z_V(FW_PARAMS_PARAM_DEV_PHYFW_VERSION));
3722b2612722SHariprasad Shenai 	ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1,
372301b69614SHariprasad Shenai 			      &param, &val);
3724c799fca8SJason Gunthorpe 	if (ret)
372501b69614SHariprasad Shenai 		return ret;
372601b69614SHariprasad Shenai 	*phy_fw_ver = val;
372701b69614SHariprasad Shenai 	return 0;
372801b69614SHariprasad Shenai }
372901b69614SHariprasad Shenai 
373001b69614SHariprasad Shenai /**
373101b69614SHariprasad Shenai  *	t4_load_phy_fw - download port PHY firmware
373201b69614SHariprasad Shenai  *	@adap: the adapter
373301b69614SHariprasad Shenai  *	@win: the PCI-E Memory Window index to use for t4_memory_rw()
373401b69614SHariprasad Shenai  *	@phy_fw_version: function to check PHY firmware versions
373501b69614SHariprasad Shenai  *	@phy_fw_data: the PHY firmware image to write
373601b69614SHariprasad Shenai  *	@phy_fw_size: image size
373701b69614SHariprasad Shenai  *
373801b69614SHariprasad Shenai  *	Transfer the specified PHY firmware to the adapter.  If a non-NULL
373901b69614SHariprasad Shenai  *	@phy_fw_version is supplied, then it will be used to determine if
374001b69614SHariprasad Shenai  *	it's necessary to perform the transfer by comparing the version
374101b69614SHariprasad Shenai  *	of any existing adapter PHY firmware with that of the passed in
37425fff701cSRahul Lakkireddy  *	PHY firmware image.
374301b69614SHariprasad Shenai  *
374401b69614SHariprasad Shenai  *	A negative error number will be returned if an error occurs.  If
374501b69614SHariprasad Shenai  *	version number support is available and there's no need to upgrade
374601b69614SHariprasad Shenai  *	the firmware, 0 will be returned.  If firmware is successfully
3747172ca830SArkadiusz Drabczyk  *	transferred to the adapter, 1 will be returned.
374801b69614SHariprasad Shenai  *
374901b69614SHariprasad Shenai  *	NOTE: some adapters only have local RAM to store the PHY firmware.  As
375001b69614SHariprasad Shenai  *	a result, a RESET of the adapter would cause that RAM to lose its
375101b69614SHariprasad Shenai  *	contents.  Thus, loading PHY firmware on such adapters must happen
375201b69614SHariprasad Shenai  *	after any FW_RESET_CMDs ...
375301b69614SHariprasad Shenai  */
t4_load_phy_fw(struct adapter * adap,int win,int (* phy_fw_version)(const u8 *,size_t),const u8 * phy_fw_data,size_t phy_fw_size)37545fff701cSRahul Lakkireddy int t4_load_phy_fw(struct adapter *adap, int win,
375501b69614SHariprasad Shenai 		   int (*phy_fw_version)(const u8 *, size_t),
375601b69614SHariprasad Shenai 		   const u8 *phy_fw_data, size_t phy_fw_size)
375701b69614SHariprasad Shenai {
37585fff701cSRahul Lakkireddy 	int cur_phy_fw_ver = 0, new_phy_fw_vers = 0;
375901b69614SHariprasad Shenai 	unsigned long mtype = 0, maddr = 0;
376001b69614SHariprasad Shenai 	u32 param, val;
376101b69614SHariprasad Shenai 	int ret;
376201b69614SHariprasad Shenai 
376301b69614SHariprasad Shenai 	/* If we have version number support, then check to see if the adapter
376401b69614SHariprasad Shenai 	 * already has up-to-date PHY firmware loaded.
376501b69614SHariprasad Shenai 	 */
376601b69614SHariprasad Shenai 	if (phy_fw_version) {
376701b69614SHariprasad Shenai 		new_phy_fw_vers = phy_fw_version(phy_fw_data, phy_fw_size);
376801b69614SHariprasad Shenai 		ret = t4_phy_fw_ver(adap, &cur_phy_fw_ver);
376901b69614SHariprasad Shenai 		if (ret < 0)
377001b69614SHariprasad Shenai 			return ret;
377101b69614SHariprasad Shenai 
377201b69614SHariprasad Shenai 		if (cur_phy_fw_ver >= new_phy_fw_vers) {
377301b69614SHariprasad Shenai 			CH_WARN(adap, "PHY Firmware already up-to-date, "
377401b69614SHariprasad Shenai 				"version %#x\n", cur_phy_fw_ver);
377501b69614SHariprasad Shenai 			return 0;
377601b69614SHariprasad Shenai 		}
377701b69614SHariprasad Shenai 	}
377801b69614SHariprasad Shenai 
377901b69614SHariprasad Shenai 	/* Ask the firmware where it wants us to copy the PHY firmware image.
3780172ca830SArkadiusz Drabczyk 	 * The size of the file requires a special version of the READ command
378101b69614SHariprasad Shenai 	 * which will pass the file size via the values field in PARAMS_CMD and
378201b69614SHariprasad Shenai 	 * retrieve the return value from firmware and place it in the same
378301b69614SHariprasad Shenai 	 * buffer values
378401b69614SHariprasad Shenai 	 */
378501b69614SHariprasad Shenai 	param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) |
378601b69614SHariprasad Shenai 		 FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_PHYFW) |
378701b69614SHariprasad Shenai 		 FW_PARAMS_PARAM_Y_V(adap->params.portvec) |
378801b69614SHariprasad Shenai 		 FW_PARAMS_PARAM_Z_V(FW_PARAMS_PARAM_DEV_PHYFW_DOWNLOAD));
378901b69614SHariprasad Shenai 	val = phy_fw_size;
3790b2612722SHariprasad Shenai 	ret = t4_query_params_rw(adap, adap->mbox, adap->pf, 0, 1,
37918f46d467SArjun Vynipadath 				 &param, &val, 1, true);
379201b69614SHariprasad Shenai 	if (ret < 0)
379301b69614SHariprasad Shenai 		return ret;
379401b69614SHariprasad Shenai 	mtype = val >> 8;
379501b69614SHariprasad Shenai 	maddr = (val & 0xff) << 16;
379601b69614SHariprasad Shenai 
379701b69614SHariprasad Shenai 	/* Copy the supplied PHY Firmware image to the adapter memory location
379801b69614SHariprasad Shenai 	 * allocated by the adapter firmware.
379901b69614SHariprasad Shenai 	 */
3800f046bd0aSRahul Lakkireddy 	spin_lock_bh(&adap->win0_lock);
380101b69614SHariprasad Shenai 	ret = t4_memory_rw(adap, win, mtype, maddr,
380201b69614SHariprasad Shenai 			   phy_fw_size, (__be32 *)phy_fw_data,
380301b69614SHariprasad Shenai 			   T4_MEMORY_WRITE);
3804f046bd0aSRahul Lakkireddy 	spin_unlock_bh(&adap->win0_lock);
380501b69614SHariprasad Shenai 	if (ret)
380601b69614SHariprasad Shenai 		return ret;
380701b69614SHariprasad Shenai 
380801b69614SHariprasad Shenai 	/* Tell the firmware that the PHY firmware image has been written to
380901b69614SHariprasad Shenai 	 * RAM and it can now start copying it over to the PHYs.  The chip
381001b69614SHariprasad Shenai 	 * firmware will RESET the affected PHYs as part of this operation
381101b69614SHariprasad Shenai 	 * leaving them running the new PHY firmware image.
381201b69614SHariprasad Shenai 	 */
381301b69614SHariprasad Shenai 	param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) |
381401b69614SHariprasad Shenai 		 FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_PHYFW) |
381501b69614SHariprasad Shenai 		 FW_PARAMS_PARAM_Y_V(adap->params.portvec) |
381601b69614SHariprasad Shenai 		 FW_PARAMS_PARAM_Z_V(FW_PARAMS_PARAM_DEV_PHYFW_DOWNLOAD));
3817b2612722SHariprasad Shenai 	ret = t4_set_params_timeout(adap, adap->mbox, adap->pf, 0, 1,
381801b69614SHariprasad Shenai 				    &param, &val, 30000);
3819*9f771493SSu Hui 	if (ret)
3820*9f771493SSu Hui 		return ret;
382101b69614SHariprasad Shenai 
382201b69614SHariprasad Shenai 	/* If we have version number support, then check to see that the new
382301b69614SHariprasad Shenai 	 * firmware got loaded properly.
382401b69614SHariprasad Shenai 	 */
382501b69614SHariprasad Shenai 	if (phy_fw_version) {
382601b69614SHariprasad Shenai 		ret = t4_phy_fw_ver(adap, &cur_phy_fw_ver);
382701b69614SHariprasad Shenai 		if (ret < 0)
382801b69614SHariprasad Shenai 			return ret;
382901b69614SHariprasad Shenai 
383001b69614SHariprasad Shenai 		if (cur_phy_fw_ver != new_phy_fw_vers) {
383101b69614SHariprasad Shenai 			CH_WARN(adap, "PHY Firmware did not update: "
383201b69614SHariprasad Shenai 				"version on adapter %#x, "
383301b69614SHariprasad Shenai 				"version flashed %#x\n",
383401b69614SHariprasad Shenai 				cur_phy_fw_ver, new_phy_fw_vers);
383501b69614SHariprasad Shenai 			return -ENXIO;
383601b69614SHariprasad Shenai 		}
383701b69614SHariprasad Shenai 	}
383801b69614SHariprasad Shenai 
383901b69614SHariprasad Shenai 	return 1;
384001b69614SHariprasad Shenai }
384101b69614SHariprasad Shenai 
384201b69614SHariprasad Shenai /**
384349216c1cSHariprasad Shenai  *	t4_fwcache - firmware cache operation
384449216c1cSHariprasad Shenai  *	@adap: the adapter
384549216c1cSHariprasad Shenai  *	@op  : the operation (flush or flush and invalidate)
384649216c1cSHariprasad Shenai  */
t4_fwcache(struct adapter * adap,enum fw_params_param_dev_fwcache op)384749216c1cSHariprasad Shenai int t4_fwcache(struct adapter *adap, enum fw_params_param_dev_fwcache op)
384849216c1cSHariprasad Shenai {
384949216c1cSHariprasad Shenai 	struct fw_params_cmd c;
385049216c1cSHariprasad Shenai 
385149216c1cSHariprasad Shenai 	memset(&c, 0, sizeof(c));
385249216c1cSHariprasad Shenai 	c.op_to_vfn =
385349216c1cSHariprasad Shenai 		cpu_to_be32(FW_CMD_OP_V(FW_PARAMS_CMD) |
385449216c1cSHariprasad Shenai 			    FW_CMD_REQUEST_F | FW_CMD_WRITE_F |
3855b2612722SHariprasad Shenai 			    FW_PARAMS_CMD_PFN_V(adap->pf) |
385649216c1cSHariprasad Shenai 			    FW_PARAMS_CMD_VFN_V(0));
385749216c1cSHariprasad Shenai 	c.retval_len16 = cpu_to_be32(FW_LEN16(c));
385849216c1cSHariprasad Shenai 	c.param[0].mnem =
385949216c1cSHariprasad Shenai 		cpu_to_be32(FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) |
386049216c1cSHariprasad Shenai 			    FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_FWCACHE));
38610dc235afSGanesh Goudar 	c.param[0].val = cpu_to_be32(op);
386249216c1cSHariprasad Shenai 
386349216c1cSHariprasad Shenai 	return t4_wr_mbox(adap, adap->mbox, &c, sizeof(c), NULL);
386449216c1cSHariprasad Shenai }
386549216c1cSHariprasad Shenai 
t4_cim_read_pif_la(struct adapter * adap,u32 * pif_req,u32 * pif_rsp,unsigned int * pif_req_wrptr,unsigned int * pif_rsp_wrptr)386619689609SHariprasad Shenai void t4_cim_read_pif_la(struct adapter *adap, u32 *pif_req, u32 *pif_rsp,
386719689609SHariprasad Shenai 			unsigned int *pif_req_wrptr,
386819689609SHariprasad Shenai 			unsigned int *pif_rsp_wrptr)
386919689609SHariprasad Shenai {
387019689609SHariprasad Shenai 	int i, j;
387119689609SHariprasad Shenai 	u32 cfg, val, req, rsp;
387219689609SHariprasad Shenai 
387319689609SHariprasad Shenai 	cfg = t4_read_reg(adap, CIM_DEBUGCFG_A);
387419689609SHariprasad Shenai 	if (cfg & LADBGEN_F)
387519689609SHariprasad Shenai 		t4_write_reg(adap, CIM_DEBUGCFG_A, cfg ^ LADBGEN_F);
387619689609SHariprasad Shenai 
387719689609SHariprasad Shenai 	val = t4_read_reg(adap, CIM_DEBUGSTS_A);
387819689609SHariprasad Shenai 	req = POLADBGWRPTR_G(val);
387919689609SHariprasad Shenai 	rsp = PILADBGWRPTR_G(val);
388019689609SHariprasad Shenai 	if (pif_req_wrptr)
388119689609SHariprasad Shenai 		*pif_req_wrptr = req;
388219689609SHariprasad Shenai 	if (pif_rsp_wrptr)
388319689609SHariprasad Shenai 		*pif_rsp_wrptr = rsp;
388419689609SHariprasad Shenai 
388519689609SHariprasad Shenai 	for (i = 0; i < CIM_PIFLA_SIZE; i++) {
388619689609SHariprasad Shenai 		for (j = 0; j < 6; j++) {
388719689609SHariprasad Shenai 			t4_write_reg(adap, CIM_DEBUGCFG_A, POLADBGRDPTR_V(req) |
388819689609SHariprasad Shenai 				     PILADBGRDPTR_V(rsp));
388919689609SHariprasad Shenai 			*pif_req++ = t4_read_reg(adap, CIM_PO_LA_DEBUGDATA_A);
389019689609SHariprasad Shenai 			*pif_rsp++ = t4_read_reg(adap, CIM_PI_LA_DEBUGDATA_A);
389119689609SHariprasad Shenai 			req++;
389219689609SHariprasad Shenai 			rsp++;
389319689609SHariprasad Shenai 		}
389419689609SHariprasad Shenai 		req = (req + 2) & POLADBGRDPTR_M;
389519689609SHariprasad Shenai 		rsp = (rsp + 2) & PILADBGRDPTR_M;
389619689609SHariprasad Shenai 	}
389719689609SHariprasad Shenai 	t4_write_reg(adap, CIM_DEBUGCFG_A, cfg);
389819689609SHariprasad Shenai }
389919689609SHariprasad Shenai 
t4_cim_read_ma_la(struct adapter * adap,u32 * ma_req,u32 * ma_rsp)390026fae93fSHariprasad Shenai void t4_cim_read_ma_la(struct adapter *adap, u32 *ma_req, u32 *ma_rsp)
390126fae93fSHariprasad Shenai {
390226fae93fSHariprasad Shenai 	u32 cfg;
390326fae93fSHariprasad Shenai 	int i, j, idx;
390426fae93fSHariprasad Shenai 
390526fae93fSHariprasad Shenai 	cfg = t4_read_reg(adap, CIM_DEBUGCFG_A);
390626fae93fSHariprasad Shenai 	if (cfg & LADBGEN_F)
390726fae93fSHariprasad Shenai 		t4_write_reg(adap, CIM_DEBUGCFG_A, cfg ^ LADBGEN_F);
390826fae93fSHariprasad Shenai 
390926fae93fSHariprasad Shenai 	for (i = 0; i < CIM_MALA_SIZE; i++) {
391026fae93fSHariprasad Shenai 		for (j = 0; j < 5; j++) {
391126fae93fSHariprasad Shenai 			idx = 8 * i + j;
391226fae93fSHariprasad Shenai 			t4_write_reg(adap, CIM_DEBUGCFG_A, POLADBGRDPTR_V(idx) |
391326fae93fSHariprasad Shenai 				     PILADBGRDPTR_V(idx));
391426fae93fSHariprasad Shenai 			*ma_req++ = t4_read_reg(adap, CIM_PO_LA_MADEBUGDATA_A);
391526fae93fSHariprasad Shenai 			*ma_rsp++ = t4_read_reg(adap, CIM_PI_LA_MADEBUGDATA_A);
391626fae93fSHariprasad Shenai 		}
391726fae93fSHariprasad Shenai 	}
391826fae93fSHariprasad Shenai 	t4_write_reg(adap, CIM_DEBUGCFG_A, cfg);
391926fae93fSHariprasad Shenai }
392026fae93fSHariprasad Shenai 
t4_ulprx_read_la(struct adapter * adap,u32 * la_buf)3921797ff0f5SHariprasad Shenai void t4_ulprx_read_la(struct adapter *adap, u32 *la_buf)
3922797ff0f5SHariprasad Shenai {
3923797ff0f5SHariprasad Shenai 	unsigned int i, j;
3924797ff0f5SHariprasad Shenai 
3925797ff0f5SHariprasad Shenai 	for (i = 0; i < 8; i++) {
3926797ff0f5SHariprasad Shenai 		u32 *p = la_buf + i;
3927797ff0f5SHariprasad Shenai 
3928797ff0f5SHariprasad Shenai 		t4_write_reg(adap, ULP_RX_LA_CTL_A, i);
3929797ff0f5SHariprasad Shenai 		j = t4_read_reg(adap, ULP_RX_LA_WRPTR_A);
3930797ff0f5SHariprasad Shenai 		t4_write_reg(adap, ULP_RX_LA_RDPTR_A, j);
3931797ff0f5SHariprasad Shenai 		for (j = 0; j < ULPRX_LA_SIZE; j++, p += 8)
3932797ff0f5SHariprasad Shenai 			*p = t4_read_reg(adap, ULP_RX_LA_RDDATA_A);
3933797ff0f5SHariprasad Shenai 	}
3934797ff0f5SHariprasad Shenai }
3935797ff0f5SHariprasad Shenai 
39369f764898SVishal Kulkarni /* The ADVERT_MASK is used to mask out all of the Advertised Firmware Port
39379f764898SVishal Kulkarni  * Capabilities which we control with separate controls -- see, for instance,
39389f764898SVishal Kulkarni  * Pause Frames and Forward Error Correction.  In order to determine what the
39399f764898SVishal Kulkarni  * full set of Advertised Port Capabilities are, the base Advertised Port
39409f764898SVishal Kulkarni  * Capabilities (masked by ADVERT_MASK) must be combined with the Advertised
39419f764898SVishal Kulkarni  * Port Capabilities associated with those other controls.  See
39429f764898SVishal Kulkarni  * t4_link_acaps() for how this is done.
39439f764898SVishal Kulkarni  */
3944c3168cabSGanesh Goudar #define ADVERT_MASK (FW_PORT_CAP32_SPEED_V(FW_PORT_CAP32_SPEED_M) | \
3945c3168cabSGanesh Goudar 		     FW_PORT_CAP32_ANEG)
3946c3168cabSGanesh Goudar 
3947c3168cabSGanesh Goudar /**
3948c3168cabSGanesh Goudar  *	fwcaps16_to_caps32 - convert 16-bit Port Capabilities to 32-bits
3949c3168cabSGanesh Goudar  *	@caps16: a 16-bit Port Capabilities value
3950c3168cabSGanesh Goudar  *
3951c3168cabSGanesh Goudar  *	Returns the equivalent 32-bit Port Capabilities value.
3952c3168cabSGanesh Goudar  */
fwcaps16_to_caps32(fw_port_cap16_t caps16)3953c3168cabSGanesh Goudar static fw_port_cap32_t fwcaps16_to_caps32(fw_port_cap16_t caps16)
3954c3168cabSGanesh Goudar {
3955c3168cabSGanesh Goudar 	fw_port_cap32_t caps32 = 0;
3956c3168cabSGanesh Goudar 
3957c3168cabSGanesh Goudar 	#define CAP16_TO_CAP32(__cap) \
3958c3168cabSGanesh Goudar 		do { \
3959c3168cabSGanesh Goudar 			if (caps16 & FW_PORT_CAP_##__cap) \
3960c3168cabSGanesh Goudar 				caps32 |= FW_PORT_CAP32_##__cap; \
3961c3168cabSGanesh Goudar 		} while (0)
3962c3168cabSGanesh Goudar 
3963c3168cabSGanesh Goudar 	CAP16_TO_CAP32(SPEED_100M);
3964c3168cabSGanesh Goudar 	CAP16_TO_CAP32(SPEED_1G);
3965c3168cabSGanesh Goudar 	CAP16_TO_CAP32(SPEED_25G);
3966c3168cabSGanesh Goudar 	CAP16_TO_CAP32(SPEED_10G);
3967c3168cabSGanesh Goudar 	CAP16_TO_CAP32(SPEED_40G);
3968c3168cabSGanesh Goudar 	CAP16_TO_CAP32(SPEED_100G);
3969c3168cabSGanesh Goudar 	CAP16_TO_CAP32(FC_RX);
3970c3168cabSGanesh Goudar 	CAP16_TO_CAP32(FC_TX);
3971c3168cabSGanesh Goudar 	CAP16_TO_CAP32(ANEG);
3972c5f732d7SGanesh Goudar 	CAP16_TO_CAP32(FORCE_PAUSE);
3973c3168cabSGanesh Goudar 	CAP16_TO_CAP32(MDIAUTO);
39741d19023fSGanesh Goudar 	CAP16_TO_CAP32(MDISTRAIGHT);
3975c3168cabSGanesh Goudar 	CAP16_TO_CAP32(FEC_RS);
3976c3168cabSGanesh Goudar 	CAP16_TO_CAP32(FEC_BASER_RS);
3977c3168cabSGanesh Goudar 	CAP16_TO_CAP32(802_3_PAUSE);
3978c3168cabSGanesh Goudar 	CAP16_TO_CAP32(802_3_ASM_DIR);
3979c3168cabSGanesh Goudar 
3980c3168cabSGanesh Goudar 	#undef CAP16_TO_CAP32
3981c3168cabSGanesh Goudar 
3982c3168cabSGanesh Goudar 	return caps32;
3983c3168cabSGanesh Goudar }
3984c3168cabSGanesh Goudar 
3985c3168cabSGanesh Goudar /**
3986c3168cabSGanesh Goudar  *	fwcaps32_to_caps16 - convert 32-bit Port Capabilities to 16-bits
3987c3168cabSGanesh Goudar  *	@caps32: a 32-bit Port Capabilities value
3988c3168cabSGanesh Goudar  *
3989c3168cabSGanesh Goudar  *	Returns the equivalent 16-bit Port Capabilities value.  Note that
3990c3168cabSGanesh Goudar  *	not all 32-bit Port Capabilities can be represented in the 16-bit
3991c3168cabSGanesh Goudar  *	Port Capabilities and some fields/values may not make it.
3992c3168cabSGanesh Goudar  */
fwcaps32_to_caps16(fw_port_cap32_t caps32)3993c3168cabSGanesh Goudar static fw_port_cap16_t fwcaps32_to_caps16(fw_port_cap32_t caps32)
3994c3168cabSGanesh Goudar {
3995c3168cabSGanesh Goudar 	fw_port_cap16_t caps16 = 0;
3996c3168cabSGanesh Goudar 
3997c3168cabSGanesh Goudar 	#define CAP32_TO_CAP16(__cap) \
3998c3168cabSGanesh Goudar 		do { \
3999c3168cabSGanesh Goudar 			if (caps32 & FW_PORT_CAP32_##__cap) \
4000c3168cabSGanesh Goudar 				caps16 |= FW_PORT_CAP_##__cap; \
4001c3168cabSGanesh Goudar 		} while (0)
4002c3168cabSGanesh Goudar 
4003c3168cabSGanesh Goudar 	CAP32_TO_CAP16(SPEED_100M);
4004c3168cabSGanesh Goudar 	CAP32_TO_CAP16(SPEED_1G);
4005c3168cabSGanesh Goudar 	CAP32_TO_CAP16(SPEED_10G);
4006c3168cabSGanesh Goudar 	CAP32_TO_CAP16(SPEED_25G);
4007c3168cabSGanesh Goudar 	CAP32_TO_CAP16(SPEED_40G);
4008c3168cabSGanesh Goudar 	CAP32_TO_CAP16(SPEED_100G);
4009c3168cabSGanesh Goudar 	CAP32_TO_CAP16(FC_RX);
4010c3168cabSGanesh Goudar 	CAP32_TO_CAP16(FC_TX);
4011c3168cabSGanesh Goudar 	CAP32_TO_CAP16(802_3_PAUSE);
4012c3168cabSGanesh Goudar 	CAP32_TO_CAP16(802_3_ASM_DIR);
4013c3168cabSGanesh Goudar 	CAP32_TO_CAP16(ANEG);
4014c5f732d7SGanesh Goudar 	CAP32_TO_CAP16(FORCE_PAUSE);
4015c3168cabSGanesh Goudar 	CAP32_TO_CAP16(MDIAUTO);
40161d19023fSGanesh Goudar 	CAP32_TO_CAP16(MDISTRAIGHT);
4017c3168cabSGanesh Goudar 	CAP32_TO_CAP16(FEC_RS);
4018c3168cabSGanesh Goudar 	CAP32_TO_CAP16(FEC_BASER_RS);
4019c3168cabSGanesh Goudar 
4020c3168cabSGanesh Goudar 	#undef CAP32_TO_CAP16
4021c3168cabSGanesh Goudar 
4022c3168cabSGanesh Goudar 	return caps16;
4023c3168cabSGanesh Goudar }
4024f7917c00SJeff Kirsher 
4025158a5c0aSCasey Leedom /* Translate Firmware Port Capabilities Pause specification to Common Code */
fwcap_to_cc_pause(fw_port_cap32_t fw_pause)4026c3168cabSGanesh Goudar static inline enum cc_pause fwcap_to_cc_pause(fw_port_cap32_t fw_pause)
4027158a5c0aSCasey Leedom {
4028c3168cabSGanesh Goudar 	enum cc_pause cc_pause = 0;
4029158a5c0aSCasey Leedom 
4030c3168cabSGanesh Goudar 	if (fw_pause & FW_PORT_CAP32_FC_RX)
4031158a5c0aSCasey Leedom 		cc_pause |= PAUSE_RX;
4032c3168cabSGanesh Goudar 	if (fw_pause & FW_PORT_CAP32_FC_TX)
4033158a5c0aSCasey Leedom 		cc_pause |= PAUSE_TX;
4034158a5c0aSCasey Leedom 
4035158a5c0aSCasey Leedom 	return cc_pause;
4036158a5c0aSCasey Leedom }
4037158a5c0aSCasey Leedom 
4038158a5c0aSCasey Leedom /* Translate Common Code Pause specification into Firmware Port Capabilities */
cc_to_fwcap_pause(enum cc_pause cc_pause)4039c3168cabSGanesh Goudar static inline fw_port_cap32_t cc_to_fwcap_pause(enum cc_pause cc_pause)
4040158a5c0aSCasey Leedom {
40419f764898SVishal Kulkarni 	/* Translate orthogonal RX/TX Pause Controls for L1 Configure
40429f764898SVishal Kulkarni 	 * commands, etc.
40439f764898SVishal Kulkarni 	 */
4044c3168cabSGanesh Goudar 	fw_port_cap32_t fw_pause = 0;
4045158a5c0aSCasey Leedom 
4046158a5c0aSCasey Leedom 	if (cc_pause & PAUSE_RX)
4047c3168cabSGanesh Goudar 		fw_pause |= FW_PORT_CAP32_FC_RX;
4048158a5c0aSCasey Leedom 	if (cc_pause & PAUSE_TX)
4049c3168cabSGanesh Goudar 		fw_pause |= FW_PORT_CAP32_FC_TX;
4050c5f732d7SGanesh Goudar 	if (!(cc_pause & PAUSE_AUTONEG))
4051c5f732d7SGanesh Goudar 		fw_pause |= FW_PORT_CAP32_FORCE_PAUSE;
4052158a5c0aSCasey Leedom 
40539f764898SVishal Kulkarni 	/* Translate orthogonal Pause controls into IEEE 802.3 Pause,
4054172ca830SArkadiusz Drabczyk 	 * Asymmetrical Pause for use in reporting to upper layer OS code, etc.
40559f764898SVishal Kulkarni 	 * Note that these bits are ignored in L1 Configure commands.
40569f764898SVishal Kulkarni 	 */
40579f764898SVishal Kulkarni 	if (cc_pause & PAUSE_RX) {
40589f764898SVishal Kulkarni 		if (cc_pause & PAUSE_TX)
40599f764898SVishal Kulkarni 			fw_pause |= FW_PORT_CAP32_802_3_PAUSE;
40609f764898SVishal Kulkarni 		else
40610caeaf6aSRahul Lakkireddy 			fw_pause |= FW_PORT_CAP32_802_3_ASM_DIR |
40620caeaf6aSRahul Lakkireddy 				    FW_PORT_CAP32_802_3_PAUSE;
40639f764898SVishal Kulkarni 	} else if (cc_pause & PAUSE_TX) {
40649f764898SVishal Kulkarni 		fw_pause |= FW_PORT_CAP32_802_3_ASM_DIR;
40659f764898SVishal Kulkarni 	}
40669f764898SVishal Kulkarni 
4067158a5c0aSCasey Leedom 	return fw_pause;
4068158a5c0aSCasey Leedom }
4069158a5c0aSCasey Leedom 
4070158a5c0aSCasey Leedom /* Translate Firmware Forward Error Correction specification to Common Code */
fwcap_to_cc_fec(fw_port_cap32_t fw_fec)4071c3168cabSGanesh Goudar static inline enum cc_fec fwcap_to_cc_fec(fw_port_cap32_t fw_fec)
4072158a5c0aSCasey Leedom {
4073c3168cabSGanesh Goudar 	enum cc_fec cc_fec = 0;
4074158a5c0aSCasey Leedom 
4075c3168cabSGanesh Goudar 	if (fw_fec & FW_PORT_CAP32_FEC_RS)
4076158a5c0aSCasey Leedom 		cc_fec |= FEC_RS;
4077c3168cabSGanesh Goudar 	if (fw_fec & FW_PORT_CAP32_FEC_BASER_RS)
4078158a5c0aSCasey Leedom 		cc_fec |= FEC_BASER_RS;
4079158a5c0aSCasey Leedom 
4080158a5c0aSCasey Leedom 	return cc_fec;
4081158a5c0aSCasey Leedom }
4082158a5c0aSCasey Leedom 
4083158a5c0aSCasey Leedom /* Translate Common Code Forward Error Correction specification to Firmware */
cc_to_fwcap_fec(enum cc_fec cc_fec)4084c3168cabSGanesh Goudar static inline fw_port_cap32_t cc_to_fwcap_fec(enum cc_fec cc_fec)
4085158a5c0aSCasey Leedom {
4086c3168cabSGanesh Goudar 	fw_port_cap32_t fw_fec = 0;
4087158a5c0aSCasey Leedom 
4088158a5c0aSCasey Leedom 	if (cc_fec & FEC_RS)
4089c3168cabSGanesh Goudar 		fw_fec |= FW_PORT_CAP32_FEC_RS;
4090158a5c0aSCasey Leedom 	if (cc_fec & FEC_BASER_RS)
4091c3168cabSGanesh Goudar 		fw_fec |= FW_PORT_CAP32_FEC_BASER_RS;
4092158a5c0aSCasey Leedom 
4093158a5c0aSCasey Leedom 	return fw_fec;
4094158a5c0aSCasey Leedom }
4095158a5c0aSCasey Leedom 
4096f7917c00SJeff Kirsher /**
40979f764898SVishal Kulkarni  *	t4_link_acaps - compute Link Advertised Port Capabilities
4098158a5c0aSCasey Leedom  *	@adapter: the adapter
4099158a5c0aSCasey Leedom  *	@port: the Port ID
4100158a5c0aSCasey Leedom  *	@lc: the Port's Link Configuration
4101f7917c00SJeff Kirsher  *
41029f764898SVishal Kulkarni  *	Synthesize the Advertised Port Capabilities we'll be using based on
41039f764898SVishal Kulkarni  *	the base Advertised Port Capabilities (which have been filtered by
41049f764898SVishal Kulkarni  *	ADVERT_MASK) plus the individual controls for things like Pause
41059f764898SVishal Kulkarni  *	Frames, Forward Error Correction, MDI, etc.
4106f7917c00SJeff Kirsher  */
t4_link_acaps(struct adapter * adapter,unsigned int port,struct link_config * lc)41079f764898SVishal Kulkarni fw_port_cap32_t t4_link_acaps(struct adapter *adapter, unsigned int port,
41089f764898SVishal Kulkarni 			      struct link_config *lc)
4109f7917c00SJeff Kirsher {
41109f764898SVishal Kulkarni 	fw_port_cap32_t fw_fc, fw_fec, acaps;
41118156b0baSGanesh Goudar 	unsigned int fw_mdi;
41129f764898SVishal Kulkarni 	char cc_fec;
4113f7917c00SJeff Kirsher 
41148156b0baSGanesh Goudar 	fw_mdi = (FW_PORT_CAP32_MDI_V(FW_PORT_CAP32_MDI_AUTO) & lc->pcaps);
411595eb7882SVishal Kulkarni 
4116158a5c0aSCasey Leedom 	/* Convert driver coding of Pause Frame Flow Control settings into the
4117158a5c0aSCasey Leedom 	 * Firmware's API.
4118158a5c0aSCasey Leedom 	 */
4119158a5c0aSCasey Leedom 	fw_fc = cc_to_fwcap_pause(lc->requested_fc);
41203bb4858fSGanesh Goudar 
4121158a5c0aSCasey Leedom 	/* Convert Common Code Forward Error Control settings into the
4122158a5c0aSCasey Leedom 	 * Firmware's API.  If the current Requested FEC has "Automatic"
4123158a5c0aSCasey Leedom 	 * (IEEE 802.3) specified, then we use whatever the Firmware
4124172ca830SArkadiusz Drabczyk 	 * sent us as part of its IEEE 802.3-based interpretation of
4125158a5c0aSCasey Leedom 	 * the Transceiver Module EPROM FEC parameters.  Otherwise we
4126158a5c0aSCasey Leedom 	 * use whatever is in the current Requested FEC settings.
4127158a5c0aSCasey Leedom 	 */
4128158a5c0aSCasey Leedom 	if (lc->requested_fec & FEC_AUTO)
4129c3168cabSGanesh Goudar 		cc_fec = fwcap_to_cc_fec(lc->def_acaps);
4130158a5c0aSCasey Leedom 	else
4131158a5c0aSCasey Leedom 		cc_fec = lc->requested_fec;
4132158a5c0aSCasey Leedom 	fw_fec = cc_to_fwcap_fec(cc_fec);
41333bb4858fSGanesh Goudar 
4134158a5c0aSCasey Leedom 	/* Figure out what our Requested Port Capabilities are going to be.
413595eb7882SVishal Kulkarni 	 * Note parallel structure in t4_handle_get_port_info() and
413695eb7882SVishal Kulkarni 	 * init_link_config().
4137158a5c0aSCasey Leedom 	 */
4138c3168cabSGanesh Goudar 	if (!(lc->pcaps & FW_PORT_CAP32_ANEG)) {
41399f764898SVishal Kulkarni 		acaps = lc->acaps | fw_fc | fw_fec;
4140c3168cabSGanesh Goudar 		lc->fc = lc->requested_fc & ~PAUSE_AUTONEG;
4141158a5c0aSCasey Leedom 		lc->fec = cc_fec;
4142158a5c0aSCasey Leedom 	} else if (lc->autoneg == AUTONEG_DISABLE) {
41439f764898SVishal Kulkarni 		acaps = lc->speed_caps | fw_fc | fw_fec | fw_mdi;
4144c3168cabSGanesh Goudar 		lc->fc = lc->requested_fc & ~PAUSE_AUTONEG;
4145158a5c0aSCasey Leedom 		lc->fec = cc_fec;
4146158a5c0aSCasey Leedom 	} else {
41479f764898SVishal Kulkarni 		acaps = lc->acaps | fw_fc | fw_fec | fw_mdi;
4148158a5c0aSCasey Leedom 	}
4149158a5c0aSCasey Leedom 
415095eb7882SVishal Kulkarni 	/* Some Requested Port Capabilities are trivially wrong if they exceed
415195eb7882SVishal Kulkarni 	 * the Physical Port Capabilities.  We can check that here and provide
415295eb7882SVishal Kulkarni 	 * moderately useful feedback in the system log.
415395eb7882SVishal Kulkarni 	 *
415495eb7882SVishal Kulkarni 	 * Note that older Firmware doesn't have FW_PORT_CAP32_FORCE_PAUSE, so
4155c5f732d7SGanesh Goudar 	 * we need to exclude this from this check in order to maintain
4156c5f732d7SGanesh Goudar 	 * compatibility ...
4157c5f732d7SGanesh Goudar 	 */
41589f764898SVishal Kulkarni 	if ((acaps & ~lc->pcaps) & ~FW_PORT_CAP32_FORCE_PAUSE) {
41599f764898SVishal Kulkarni 		dev_err(adapter->pdev_dev, "Requested Port Capabilities %#x exceed Physical Port Capabilities %#x\n",
41609f764898SVishal Kulkarni 			acaps, lc->pcaps);
416157ccaedbSGanesh Goudar 		return -EINVAL;
416257ccaedbSGanesh Goudar 	}
416357ccaedbSGanesh Goudar 
41649f764898SVishal Kulkarni 	return acaps;
41659f764898SVishal Kulkarni }
41669f764898SVishal Kulkarni 
41679f764898SVishal Kulkarni /**
41689f764898SVishal Kulkarni  *	t4_link_l1cfg_core - apply link configuration to MAC/PHY
41699f764898SVishal Kulkarni  *	@adapter: the adapter
41709f764898SVishal Kulkarni  *	@mbox: the Firmware Mailbox to use
41719f764898SVishal Kulkarni  *	@port: the Port ID
41729f764898SVishal Kulkarni  *	@lc: the Port's Link Configuration
41739f764898SVishal Kulkarni  *	@sleep_ok: if true we may sleep while awaiting command completion
41749f764898SVishal Kulkarni  *	@timeout: time to wait for command to finish before timing out
41759f764898SVishal Kulkarni  *		(negative implies @sleep_ok=false)
41769f764898SVishal Kulkarni  *
41779f764898SVishal Kulkarni  *	Set up a port's MAC and PHY according to a desired link configuration.
41789f764898SVishal Kulkarni  *	- If the PHY can auto-negotiate first decide what to advertise, then
41799f764898SVishal Kulkarni  *	  enable/disable auto-negotiation as desired, and reset.
41809f764898SVishal Kulkarni  *	- If the PHY does not auto-negotiate just reset it.
41819f764898SVishal Kulkarni  *	- If auto-negotiation is off set the MAC to the proper speed/duplex/FC,
41829f764898SVishal Kulkarni  *	  otherwise do it later based on the outcome of auto-negotiation.
4183158a5c0aSCasey Leedom  */
t4_link_l1cfg_core(struct adapter * adapter,unsigned int mbox,unsigned int port,struct link_config * lc,u8 sleep_ok,int timeout)41849f764898SVishal Kulkarni int t4_link_l1cfg_core(struct adapter *adapter, unsigned int mbox,
41859f764898SVishal Kulkarni 		       unsigned int port, struct link_config *lc,
41869f764898SVishal Kulkarni 		       u8 sleep_ok, int timeout)
41879f764898SVishal Kulkarni {
41889f764898SVishal Kulkarni 	unsigned int fw_caps = adapter->params.fw_caps_support;
41899f764898SVishal Kulkarni 	struct fw_port_cmd cmd;
41909f764898SVishal Kulkarni 	fw_port_cap32_t rcap;
41919f764898SVishal Kulkarni 	int ret;
41929f764898SVishal Kulkarni 
41939f764898SVishal Kulkarni 	if (!(lc->pcaps & FW_PORT_CAP32_ANEG) &&
41949f764898SVishal Kulkarni 	    lc->autoneg == AUTONEG_ENABLE) {
41959f764898SVishal Kulkarni 		return -EINVAL;
41969f764898SVishal Kulkarni 	}
41979f764898SVishal Kulkarni 
41989f764898SVishal Kulkarni 	/* Compute our Requested Port Capabilities and send that on to the
41999f764898SVishal Kulkarni 	 * Firmware.
42009f764898SVishal Kulkarni 	 */
42019f764898SVishal Kulkarni 	rcap = t4_link_acaps(adapter, port, lc);
4202c3168cabSGanesh Goudar 	memset(&cmd, 0, sizeof(cmd));
4203c3168cabSGanesh Goudar 	cmd.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) |
4204f404f80cSHariprasad Shenai 				       FW_CMD_REQUEST_F | FW_CMD_EXEC_F |
4205f404f80cSHariprasad Shenai 				       FW_PORT_CMD_PORTID_V(port));
4206c3168cabSGanesh Goudar 	cmd.action_to_len16 =
4207c3168cabSGanesh Goudar 		cpu_to_be32(FW_PORT_CMD_ACTION_V(fw_caps == FW_CAPS16
4208c3168cabSGanesh Goudar 						 ? FW_PORT_ACTION_L1_CFG
4209c3168cabSGanesh Goudar 						 : FW_PORT_ACTION_L1_CFG32) |
4210c3168cabSGanesh Goudar 						 FW_LEN16(cmd));
4211c3168cabSGanesh Goudar 	if (fw_caps == FW_CAPS16)
4212c3168cabSGanesh Goudar 		cmd.u.l1cfg.rcap = cpu_to_be32(fwcaps32_to_caps16(rcap));
4213c3168cabSGanesh Goudar 	else
4214c3168cabSGanesh Goudar 		cmd.u.l1cfg32.rcap32 = cpu_to_be32(rcap);
421557ccaedbSGanesh Goudar 
421657ccaedbSGanesh Goudar 	ret = t4_wr_mbox_meat_timeout(adapter, mbox, &cmd, sizeof(cmd), NULL,
42178156b0baSGanesh Goudar 				      sleep_ok, timeout);
421895eb7882SVishal Kulkarni 
421995eb7882SVishal Kulkarni 	/* Unfortunately, even if the Requested Port Capabilities "fit" within
422095eb7882SVishal Kulkarni 	 * the Physical Port Capabilities, some combinations of features may
4221172ca830SArkadiusz Drabczyk 	 * still not be legal.  For example, 40Gb/s and Reed-Solomon Forward
422295eb7882SVishal Kulkarni 	 * Error Correction.  So if the Firmware rejects the L1 Configure
422395eb7882SVishal Kulkarni 	 * request, flag that here.
422495eb7882SVishal Kulkarni 	 */
422557ccaedbSGanesh Goudar 	if (ret) {
422657ccaedbSGanesh Goudar 		dev_err(adapter->pdev_dev,
422757ccaedbSGanesh Goudar 			"Requested Port Capabilities %#x rejected, error %d\n",
422857ccaedbSGanesh Goudar 			rcap, -ret);
422957ccaedbSGanesh Goudar 		return ret;
423057ccaedbSGanesh Goudar 	}
42319f764898SVishal Kulkarni 	return 0;
4232f7917c00SJeff Kirsher }
4233f7917c00SJeff Kirsher 
4234f7917c00SJeff Kirsher /**
4235f7917c00SJeff Kirsher  *	t4_restart_aneg - restart autonegotiation
4236f7917c00SJeff Kirsher  *	@adap: the adapter
4237f7917c00SJeff Kirsher  *	@mbox: mbox to use for the FW command
4238f7917c00SJeff Kirsher  *	@port: the port id
4239f7917c00SJeff Kirsher  *
4240f7917c00SJeff Kirsher  *	Restarts autonegotiation for the selected port.
4241f7917c00SJeff Kirsher  */
t4_restart_aneg(struct adapter * adap,unsigned int mbox,unsigned int port)4242f7917c00SJeff Kirsher int t4_restart_aneg(struct adapter *adap, unsigned int mbox, unsigned int port)
4243f7917c00SJeff Kirsher {
4244a657dbf6SGanesh Goudar 	unsigned int fw_caps = adap->params.fw_caps_support;
4245f7917c00SJeff Kirsher 	struct fw_port_cmd c;
4246f7917c00SJeff Kirsher 
4247f7917c00SJeff Kirsher 	memset(&c, 0, sizeof(c));
4248f404f80cSHariprasad Shenai 	c.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) |
4249f404f80cSHariprasad Shenai 				     FW_CMD_REQUEST_F | FW_CMD_EXEC_F |
4250f404f80cSHariprasad Shenai 				     FW_PORT_CMD_PORTID_V(port));
4251f404f80cSHariprasad Shenai 	c.action_to_len16 =
4252a657dbf6SGanesh Goudar 		cpu_to_be32(FW_PORT_CMD_ACTION_V(fw_caps == FW_CAPS16
4253a657dbf6SGanesh Goudar 						 ? FW_PORT_ACTION_L1_CFG
4254a657dbf6SGanesh Goudar 						 : FW_PORT_ACTION_L1_CFG32) |
4255f7917c00SJeff Kirsher 			    FW_LEN16(c));
4256a657dbf6SGanesh Goudar 	if (fw_caps == FW_CAPS16)
4257a657dbf6SGanesh Goudar 		c.u.l1cfg.rcap = cpu_to_be32(FW_PORT_CAP_ANEG);
4258a657dbf6SGanesh Goudar 	else
4259a657dbf6SGanesh Goudar 		c.u.l1cfg32.rcap32 = cpu_to_be32(FW_PORT_CAP32_ANEG);
4260f7917c00SJeff Kirsher 	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
4261f7917c00SJeff Kirsher }
4262f7917c00SJeff Kirsher 
42638caa1e84SVipul Pandya typedef void (*int_handler_t)(struct adapter *adap);
42648caa1e84SVipul Pandya 
4265f7917c00SJeff Kirsher struct intr_info {
4266f7917c00SJeff Kirsher 	unsigned int mask;       /* bits to check in interrupt status */
4267f7917c00SJeff Kirsher 	const char *msg;         /* message to print or NULL */
4268f7917c00SJeff Kirsher 	short stat_idx;          /* stat counter to increment or -1 */
4269f7917c00SJeff Kirsher 	unsigned short fatal;    /* whether the condition reported is fatal */
42708caa1e84SVipul Pandya 	int_handler_t int_handler; /* platform-specific int handler */
4271f7917c00SJeff Kirsher };
4272f7917c00SJeff Kirsher 
4273f7917c00SJeff Kirsher /**
4274f7917c00SJeff Kirsher  *	t4_handle_intr_status - table driven interrupt handler
4275f7917c00SJeff Kirsher  *	@adapter: the adapter that generated the interrupt
4276f7917c00SJeff Kirsher  *	@reg: the interrupt status register to process
4277f7917c00SJeff Kirsher  *	@acts: table of interrupt actions
4278f7917c00SJeff Kirsher  *
4279f7917c00SJeff Kirsher  *	A table driven interrupt handler that applies a set of masks to an
4280f7917c00SJeff Kirsher  *	interrupt status word and performs the corresponding actions if the
4281f7917c00SJeff Kirsher  *	interrupts described by the mask have occurred.  The actions include
4282f7917c00SJeff Kirsher  *	optionally emitting a warning or alert message.  The table is terminated
4283f7917c00SJeff Kirsher  *	by an entry specifying mask 0.  Returns the number of fatal interrupt
4284f7917c00SJeff Kirsher  *	conditions.
4285f7917c00SJeff Kirsher  */
t4_handle_intr_status(struct adapter * adapter,unsigned int reg,const struct intr_info * acts)4286f7917c00SJeff Kirsher static int t4_handle_intr_status(struct adapter *adapter, unsigned int reg,
4287f7917c00SJeff Kirsher 				 const struct intr_info *acts)
4288f7917c00SJeff Kirsher {
4289f7917c00SJeff Kirsher 	int fatal = 0;
4290f7917c00SJeff Kirsher 	unsigned int mask = 0;
4291f7917c00SJeff Kirsher 	unsigned int status = t4_read_reg(adapter, reg);
4292f7917c00SJeff Kirsher 
4293f7917c00SJeff Kirsher 	for ( ; acts->mask; ++acts) {
4294f7917c00SJeff Kirsher 		if (!(status & acts->mask))
4295f7917c00SJeff Kirsher 			continue;
4296f7917c00SJeff Kirsher 		if (acts->fatal) {
4297f7917c00SJeff Kirsher 			fatal++;
4298f7917c00SJeff Kirsher 			dev_alert(adapter->pdev_dev, "%s (0x%x)\n", acts->msg,
4299f7917c00SJeff Kirsher 				  status & acts->mask);
4300f7917c00SJeff Kirsher 		} else if (acts->msg && printk_ratelimit())
4301f7917c00SJeff Kirsher 			dev_warn(adapter->pdev_dev, "%s (0x%x)\n", acts->msg,
4302f7917c00SJeff Kirsher 				 status & acts->mask);
43038caa1e84SVipul Pandya 		if (acts->int_handler)
43048caa1e84SVipul Pandya 			acts->int_handler(adapter);
4305f7917c00SJeff Kirsher 		mask |= acts->mask;
4306f7917c00SJeff Kirsher 	}
4307f7917c00SJeff Kirsher 	status &= mask;
4308f7917c00SJeff Kirsher 	if (status)                           /* clear processed interrupts */
4309f7917c00SJeff Kirsher 		t4_write_reg(adapter, reg, status);
4310f7917c00SJeff Kirsher 	return fatal;
4311f7917c00SJeff Kirsher }
4312f7917c00SJeff Kirsher 
4313f7917c00SJeff Kirsher /*
4314f7917c00SJeff Kirsher  * Interrupt handler for the PCIE module.
4315f7917c00SJeff Kirsher  */
pcie_intr_handler(struct adapter * adapter)4316f7917c00SJeff Kirsher static void pcie_intr_handler(struct adapter *adapter)
4317f7917c00SJeff Kirsher {
4318f7917c00SJeff Kirsher 	static const struct intr_info sysbus_intr_info[] = {
4319f061de42SHariprasad Shenai 		{ RNPP_F, "RXNP array parity error", -1, 1 },
4320f061de42SHariprasad Shenai 		{ RPCP_F, "RXPC array parity error", -1, 1 },
4321f061de42SHariprasad Shenai 		{ RCIP_F, "RXCIF array parity error", -1, 1 },
4322f061de42SHariprasad Shenai 		{ RCCP_F, "Rx completions control array parity error", -1, 1 },
4323f061de42SHariprasad Shenai 		{ RFTP_F, "RXFT array parity error", -1, 1 },
4324f7917c00SJeff Kirsher 		{ 0 }
4325f7917c00SJeff Kirsher 	};
4326f7917c00SJeff Kirsher 	static const struct intr_info pcie_port_intr_info[] = {
4327f061de42SHariprasad Shenai 		{ TPCP_F, "TXPC array parity error", -1, 1 },
4328f061de42SHariprasad Shenai 		{ TNPP_F, "TXNP array parity error", -1, 1 },
4329f061de42SHariprasad Shenai 		{ TFTP_F, "TXFT array parity error", -1, 1 },
4330f061de42SHariprasad Shenai 		{ TCAP_F, "TXCA array parity error", -1, 1 },
4331f061de42SHariprasad Shenai 		{ TCIP_F, "TXCIF array parity error", -1, 1 },
4332f061de42SHariprasad Shenai 		{ RCAP_F, "RXCA array parity error", -1, 1 },
4333f061de42SHariprasad Shenai 		{ OTDD_F, "outbound request TLP discarded", -1, 1 },
4334f061de42SHariprasad Shenai 		{ RDPE_F, "Rx data parity error", -1, 1 },
4335f061de42SHariprasad Shenai 		{ TDUE_F, "Tx uncorrectable data error", -1, 1 },
4336f7917c00SJeff Kirsher 		{ 0 }
4337f7917c00SJeff Kirsher 	};
4338f7917c00SJeff Kirsher 	static const struct intr_info pcie_intr_info[] = {
4339f061de42SHariprasad Shenai 		{ MSIADDRLPERR_F, "MSI AddrL parity error", -1, 1 },
4340f061de42SHariprasad Shenai 		{ MSIADDRHPERR_F, "MSI AddrH parity error", -1, 1 },
4341f061de42SHariprasad Shenai 		{ MSIDATAPERR_F, "MSI data parity error", -1, 1 },
4342f061de42SHariprasad Shenai 		{ MSIXADDRLPERR_F, "MSI-X AddrL parity error", -1, 1 },
4343f061de42SHariprasad Shenai 		{ MSIXADDRHPERR_F, "MSI-X AddrH parity error", -1, 1 },
4344f061de42SHariprasad Shenai 		{ MSIXDATAPERR_F, "MSI-X data parity error", -1, 1 },
4345f061de42SHariprasad Shenai 		{ MSIXDIPERR_F, "MSI-X DI parity error", -1, 1 },
4346f061de42SHariprasad Shenai 		{ PIOCPLPERR_F, "PCI PIO completion FIFO parity error", -1, 1 },
4347f061de42SHariprasad Shenai 		{ PIOREQPERR_F, "PCI PIO request FIFO parity error", -1, 1 },
4348f061de42SHariprasad Shenai 		{ TARTAGPERR_F, "PCI PCI target tag FIFO parity error", -1, 1 },
4349f061de42SHariprasad Shenai 		{ CCNTPERR_F, "PCI CMD channel count parity error", -1, 1 },
4350f061de42SHariprasad Shenai 		{ CREQPERR_F, "PCI CMD channel request parity error", -1, 1 },
4351f061de42SHariprasad Shenai 		{ CRSPPERR_F, "PCI CMD channel response parity error", -1, 1 },
4352f061de42SHariprasad Shenai 		{ DCNTPERR_F, "PCI DMA channel count parity error", -1, 1 },
4353f061de42SHariprasad Shenai 		{ DREQPERR_F, "PCI DMA channel request parity error", -1, 1 },
4354f061de42SHariprasad Shenai 		{ DRSPPERR_F, "PCI DMA channel response parity error", -1, 1 },
4355f061de42SHariprasad Shenai 		{ HCNTPERR_F, "PCI HMA channel count parity error", -1, 1 },
4356f061de42SHariprasad Shenai 		{ HREQPERR_F, "PCI HMA channel request parity error", -1, 1 },
4357f061de42SHariprasad Shenai 		{ HRSPPERR_F, "PCI HMA channel response parity error", -1, 1 },
4358f061de42SHariprasad Shenai 		{ CFGSNPPERR_F, "PCI config snoop FIFO parity error", -1, 1 },
4359f061de42SHariprasad Shenai 		{ FIDPERR_F, "PCI FID parity error", -1, 1 },
4360f061de42SHariprasad Shenai 		{ INTXCLRPERR_F, "PCI INTx clear parity error", -1, 1 },
4361f061de42SHariprasad Shenai 		{ MATAGPERR_F, "PCI MA tag parity error", -1, 1 },
4362f061de42SHariprasad Shenai 		{ PIOTAGPERR_F, "PCI PIO tag parity error", -1, 1 },
4363f061de42SHariprasad Shenai 		{ RXCPLPERR_F, "PCI Rx completion parity error", -1, 1 },
4364f061de42SHariprasad Shenai 		{ RXWRPERR_F, "PCI Rx write parity error", -1, 1 },
4365f061de42SHariprasad Shenai 		{ RPLPERR_F, "PCI replay buffer parity error", -1, 1 },
4366f061de42SHariprasad Shenai 		{ PCIESINT_F, "PCI core secondary fault", -1, 1 },
4367f061de42SHariprasad Shenai 		{ PCIEPINT_F, "PCI core primary fault", -1, 1 },
4368f061de42SHariprasad Shenai 		{ UNXSPLCPLERR_F, "PCI unexpected split completion error",
4369f061de42SHariprasad Shenai 		  -1, 0 },
4370f7917c00SJeff Kirsher 		{ 0 }
4371f7917c00SJeff Kirsher 	};
4372f7917c00SJeff Kirsher 
43730a57a536SSantosh Rastapur 	static struct intr_info t5_pcie_intr_info[] = {
4374f061de42SHariprasad Shenai 		{ MSTGRPPERR_F, "Master Response Read Queue parity error",
43750a57a536SSantosh Rastapur 		  -1, 1 },
4376f061de42SHariprasad Shenai 		{ MSTTIMEOUTPERR_F, "Master Timeout FIFO parity error", -1, 1 },
4377f061de42SHariprasad Shenai 		{ MSIXSTIPERR_F, "MSI-X STI SRAM parity error", -1, 1 },
4378f061de42SHariprasad Shenai 		{ MSIXADDRLPERR_F, "MSI-X AddrL parity error", -1, 1 },
4379f061de42SHariprasad Shenai 		{ MSIXADDRHPERR_F, "MSI-X AddrH parity error", -1, 1 },
4380f061de42SHariprasad Shenai 		{ MSIXDATAPERR_F, "MSI-X data parity error", -1, 1 },
4381f061de42SHariprasad Shenai 		{ MSIXDIPERR_F, "MSI-X DI parity error", -1, 1 },
4382f061de42SHariprasad Shenai 		{ PIOCPLGRPPERR_F, "PCI PIO completion Group FIFO parity error",
43830a57a536SSantosh Rastapur 		  -1, 1 },
4384f061de42SHariprasad Shenai 		{ PIOREQGRPPERR_F, "PCI PIO request Group FIFO parity error",
43850a57a536SSantosh Rastapur 		  -1, 1 },
4386f061de42SHariprasad Shenai 		{ TARTAGPERR_F, "PCI PCI target tag FIFO parity error", -1, 1 },
4387f061de42SHariprasad Shenai 		{ MSTTAGQPERR_F, "PCI master tag queue parity error", -1, 1 },
4388f061de42SHariprasad Shenai 		{ CREQPERR_F, "PCI CMD channel request parity error", -1, 1 },
4389f061de42SHariprasad Shenai 		{ CRSPPERR_F, "PCI CMD channel response parity error", -1, 1 },
4390f061de42SHariprasad Shenai 		{ DREQWRPERR_F, "PCI DMA channel write request parity error",
43910a57a536SSantosh Rastapur 		  -1, 1 },
4392f061de42SHariprasad Shenai 		{ DREQPERR_F, "PCI DMA channel request parity error", -1, 1 },
4393f061de42SHariprasad Shenai 		{ DRSPPERR_F, "PCI DMA channel response parity error", -1, 1 },
4394f061de42SHariprasad Shenai 		{ HREQWRPERR_F, "PCI HMA channel count parity error", -1, 1 },
4395f061de42SHariprasad Shenai 		{ HREQPERR_F, "PCI HMA channel request parity error", -1, 1 },
4396f061de42SHariprasad Shenai 		{ HRSPPERR_F, "PCI HMA channel response parity error", -1, 1 },
4397f061de42SHariprasad Shenai 		{ CFGSNPPERR_F, "PCI config snoop FIFO parity error", -1, 1 },
4398f061de42SHariprasad Shenai 		{ FIDPERR_F, "PCI FID parity error", -1, 1 },
4399f061de42SHariprasad Shenai 		{ VFIDPERR_F, "PCI INTx clear parity error", -1, 1 },
4400f061de42SHariprasad Shenai 		{ MAGRPPERR_F, "PCI MA group FIFO parity error", -1, 1 },
4401f061de42SHariprasad Shenai 		{ PIOTAGPERR_F, "PCI PIO tag parity error", -1, 1 },
4402f061de42SHariprasad Shenai 		{ IPRXHDRGRPPERR_F, "PCI IP Rx header group parity error",
44030a57a536SSantosh Rastapur 		  -1, 1 },
4404f061de42SHariprasad Shenai 		{ IPRXDATAGRPPERR_F, "PCI IP Rx data group parity error",
4405f061de42SHariprasad Shenai 		  -1, 1 },
4406f061de42SHariprasad Shenai 		{ RPLPERR_F, "PCI IP replay buffer parity error", -1, 1 },
4407f061de42SHariprasad Shenai 		{ IPSOTPERR_F, "PCI IP SOT buffer parity error", -1, 1 },
4408f061de42SHariprasad Shenai 		{ TRGT1GRPPERR_F, "PCI TRGT1 group FIFOs parity error", -1, 1 },
4409f061de42SHariprasad Shenai 		{ READRSPERR_F, "Outbound read error", -1, 0 },
44100a57a536SSantosh Rastapur 		{ 0 }
44110a57a536SSantosh Rastapur 	};
44120a57a536SSantosh Rastapur 
4413f7917c00SJeff Kirsher 	int fat;
4414f7917c00SJeff Kirsher 
44159bb59b96SHariprasad Shenai 	if (is_t4(adapter->params.chip))
4416f7917c00SJeff Kirsher 		fat = t4_handle_intr_status(adapter,
4417f061de42SHariprasad Shenai 				PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS_A,
4418f7917c00SJeff Kirsher 				sysbus_intr_info) +
4419f7917c00SJeff Kirsher 			t4_handle_intr_status(adapter,
4420f061de42SHariprasad Shenai 					PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS_A,
4421f7917c00SJeff Kirsher 					pcie_port_intr_info) +
4422f061de42SHariprasad Shenai 			t4_handle_intr_status(adapter, PCIE_INT_CAUSE_A,
44239bb59b96SHariprasad Shenai 					      pcie_intr_info);
44249bb59b96SHariprasad Shenai 	else
4425f061de42SHariprasad Shenai 		fat = t4_handle_intr_status(adapter, PCIE_INT_CAUSE_A,
44269bb59b96SHariprasad Shenai 					    t5_pcie_intr_info);
44270a57a536SSantosh Rastapur 
4428f7917c00SJeff Kirsher 	if (fat)
4429f7917c00SJeff Kirsher 		t4_fatal_err(adapter);
4430f7917c00SJeff Kirsher }
4431f7917c00SJeff Kirsher 
4432f7917c00SJeff Kirsher /*
4433f7917c00SJeff Kirsher  * TP interrupt handler.
4434f7917c00SJeff Kirsher  */
tp_intr_handler(struct adapter * adapter)4435f7917c00SJeff Kirsher static void tp_intr_handler(struct adapter *adapter)
4436f7917c00SJeff Kirsher {
4437f7917c00SJeff Kirsher 	static const struct intr_info tp_intr_info[] = {
4438f7917c00SJeff Kirsher 		{ 0x3fffffff, "TP parity error", -1, 1 },
4439837e4a42SHariprasad Shenai 		{ FLMTXFLSTEMPTY_F, "TP out of Tx pages", -1, 1 },
4440f7917c00SJeff Kirsher 		{ 0 }
4441f7917c00SJeff Kirsher 	};
4442f7917c00SJeff Kirsher 
4443837e4a42SHariprasad Shenai 	if (t4_handle_intr_status(adapter, TP_INT_CAUSE_A, tp_intr_info))
4444f7917c00SJeff Kirsher 		t4_fatal_err(adapter);
4445f7917c00SJeff Kirsher }
4446f7917c00SJeff Kirsher 
4447f7917c00SJeff Kirsher /*
4448f7917c00SJeff Kirsher  * SGE interrupt handler.
4449f7917c00SJeff Kirsher  */
sge_intr_handler(struct adapter * adapter)4450f7917c00SJeff Kirsher static void sge_intr_handler(struct adapter *adapter)
4451f7917c00SJeff Kirsher {
44521f074e67SRahul Kundu 	u32 v = 0, perr;
44533ccc6cf7SHariprasad Shenai 	u32 err;
4454f7917c00SJeff Kirsher 
4455f7917c00SJeff Kirsher 	static const struct intr_info sge_intr_info[] = {
4456f612b815SHariprasad Shenai 		{ ERR_CPL_EXCEED_IQE_SIZE_F,
4457f7917c00SJeff Kirsher 		  "SGE received CPL exceeding IQE size", -1, 1 },
4458f612b815SHariprasad Shenai 		{ ERR_INVALID_CIDX_INC_F,
4459f7917c00SJeff Kirsher 		  "SGE GTS CIDX increment too large", -1, 0 },
4460f612b815SHariprasad Shenai 		{ ERR_CPL_OPCODE_0_F, "SGE received 0-length CPL", -1, 0 },
4461f612b815SHariprasad Shenai 		{ DBFIFO_LP_INT_F, NULL, -1, 0, t4_db_full },
4462f612b815SHariprasad Shenai 		{ ERR_DATA_CPL_ON_HIGH_QID1_F | ERR_DATA_CPL_ON_HIGH_QID0_F,
4463f7917c00SJeff Kirsher 		  "SGE IQID > 1023 received CPL for FL", -1, 0 },
4464f612b815SHariprasad Shenai 		{ ERR_BAD_DB_PIDX3_F, "SGE DBP 3 pidx increment too large", -1,
4465f7917c00SJeff Kirsher 		  0 },
4466f612b815SHariprasad Shenai 		{ ERR_BAD_DB_PIDX2_F, "SGE DBP 2 pidx increment too large", -1,
4467f7917c00SJeff Kirsher 		  0 },
4468f612b815SHariprasad Shenai 		{ ERR_BAD_DB_PIDX1_F, "SGE DBP 1 pidx increment too large", -1,
4469f7917c00SJeff Kirsher 		  0 },
4470f612b815SHariprasad Shenai 		{ ERR_BAD_DB_PIDX0_F, "SGE DBP 0 pidx increment too large", -1,
4471f7917c00SJeff Kirsher 		  0 },
4472f612b815SHariprasad Shenai 		{ ERR_ING_CTXT_PRIO_F,
4473f7917c00SJeff Kirsher 		  "SGE too many priority ingress contexts", -1, 0 },
4474f612b815SHariprasad Shenai 		{ INGRESS_SIZE_ERR_F, "SGE illegal ingress QID", -1, 0 },
4475f612b815SHariprasad Shenai 		{ EGRESS_SIZE_ERR_F, "SGE illegal egress QID", -1, 0 },
4476f7917c00SJeff Kirsher 		{ 0 }
4477f7917c00SJeff Kirsher 	};
4478f7917c00SJeff Kirsher 
44793ccc6cf7SHariprasad Shenai 	static struct intr_info t4t5_sge_intr_info[] = {
44803ccc6cf7SHariprasad Shenai 		{ ERR_DROPPED_DB_F, NULL, -1, 0, t4_db_dropped },
44813ccc6cf7SHariprasad Shenai 		{ DBFIFO_HP_INT_F, NULL, -1, 0, t4_db_full },
44823ccc6cf7SHariprasad Shenai 		{ ERR_EGR_CTXT_PRIO_F,
44833ccc6cf7SHariprasad Shenai 		  "SGE too many priority egress contexts", -1, 0 },
44843ccc6cf7SHariprasad Shenai 		{ 0 }
44853ccc6cf7SHariprasad Shenai 	};
44863ccc6cf7SHariprasad Shenai 
44871f074e67SRahul Kundu 	perr = t4_read_reg(adapter, SGE_INT_CAUSE1_A);
44881f074e67SRahul Kundu 	if (perr) {
44891f074e67SRahul Kundu 		v |= perr;
44901f074e67SRahul Kundu 		dev_alert(adapter->pdev_dev, "SGE Cause1 Parity Error %#x\n",
44911f074e67SRahul Kundu 			  perr);
44921f074e67SRahul Kundu 	}
44931f074e67SRahul Kundu 
44941f074e67SRahul Kundu 	perr = t4_read_reg(adapter, SGE_INT_CAUSE2_A);
44951f074e67SRahul Kundu 	if (perr) {
44961f074e67SRahul Kundu 		v |= perr;
44971f074e67SRahul Kundu 		dev_alert(adapter->pdev_dev, "SGE Cause2 Parity Error %#x\n",
44981f074e67SRahul Kundu 			  perr);
44991f074e67SRahul Kundu 	}
45001f074e67SRahul Kundu 
45011f074e67SRahul Kundu 	if (CHELSIO_CHIP_VERSION(adapter->params.chip) >= CHELSIO_T5) {
45021f074e67SRahul Kundu 		perr = t4_read_reg(adapter, SGE_INT_CAUSE5_A);
45031f074e67SRahul Kundu 		/* Parity error (CRC) for err_T_RxCRC is trivial, ignore it */
45041f074e67SRahul Kundu 		perr &= ~ERR_T_RXCRC_F;
45051f074e67SRahul Kundu 		if (perr) {
45061f074e67SRahul Kundu 			v |= perr;
45071f074e67SRahul Kundu 			dev_alert(adapter->pdev_dev,
45081f074e67SRahul Kundu 				  "SGE Cause5 Parity Error %#x\n", perr);
45091f074e67SRahul Kundu 		}
4510f7917c00SJeff Kirsher 	}
4511f7917c00SJeff Kirsher 
45123ccc6cf7SHariprasad Shenai 	v |= t4_handle_intr_status(adapter, SGE_INT_CAUSE3_A, sge_intr_info);
45133ccc6cf7SHariprasad Shenai 	if (CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5)
45143ccc6cf7SHariprasad Shenai 		v |= t4_handle_intr_status(adapter, SGE_INT_CAUSE3_A,
45153ccc6cf7SHariprasad Shenai 					   t4t5_sge_intr_info);
45163ccc6cf7SHariprasad Shenai 
45173ccc6cf7SHariprasad Shenai 	err = t4_read_reg(adapter, SGE_ERROR_STATS_A);
45183ccc6cf7SHariprasad Shenai 	if (err & ERROR_QID_VALID_F) {
45193ccc6cf7SHariprasad Shenai 		dev_err(adapter->pdev_dev, "SGE error for queue %u\n",
45203ccc6cf7SHariprasad Shenai 			ERROR_QID_G(err));
45213ccc6cf7SHariprasad Shenai 		if (err & UNCAPTURED_ERROR_F)
45223ccc6cf7SHariprasad Shenai 			dev_err(adapter->pdev_dev,
45233ccc6cf7SHariprasad Shenai 				"SGE UNCAPTURED_ERROR set (clearing)\n");
45243ccc6cf7SHariprasad Shenai 		t4_write_reg(adapter, SGE_ERROR_STATS_A, ERROR_QID_VALID_F |
45253ccc6cf7SHariprasad Shenai 			     UNCAPTURED_ERROR_F);
45263ccc6cf7SHariprasad Shenai 	}
45273ccc6cf7SHariprasad Shenai 
45283ccc6cf7SHariprasad Shenai 	if (v != 0)
4529f7917c00SJeff Kirsher 		t4_fatal_err(adapter);
4530f7917c00SJeff Kirsher }
4531f7917c00SJeff Kirsher 
453289c3a86cSHariprasad Shenai #define CIM_OBQ_INTR (OBQULP0PARERR_F | OBQULP1PARERR_F | OBQULP2PARERR_F |\
453389c3a86cSHariprasad Shenai 		      OBQULP3PARERR_F | OBQSGEPARERR_F | OBQNCSIPARERR_F)
453489c3a86cSHariprasad Shenai #define CIM_IBQ_INTR (IBQTP0PARERR_F | IBQTP1PARERR_F | IBQULPPARERR_F |\
453589c3a86cSHariprasad Shenai 		      IBQSGEHIPARERR_F | IBQSGELOPARERR_F | IBQNCSIPARERR_F)
453689c3a86cSHariprasad Shenai 
4537f7917c00SJeff Kirsher /*
4538f7917c00SJeff Kirsher  * CIM interrupt handler.
4539f7917c00SJeff Kirsher  */
cim_intr_handler(struct adapter * adapter)4540f7917c00SJeff Kirsher static void cim_intr_handler(struct adapter *adapter)
4541f7917c00SJeff Kirsher {
4542f7917c00SJeff Kirsher 	static const struct intr_info cim_intr_info[] = {
454389c3a86cSHariprasad Shenai 		{ PREFDROPINT_F, "CIM control register prefetch drop", -1, 1 },
454489c3a86cSHariprasad Shenai 		{ CIM_OBQ_INTR, "CIM OBQ parity error", -1, 1 },
454589c3a86cSHariprasad Shenai 		{ CIM_IBQ_INTR, "CIM IBQ parity error", -1, 1 },
454689c3a86cSHariprasad Shenai 		{ MBUPPARERR_F, "CIM mailbox uP parity error", -1, 1 },
454789c3a86cSHariprasad Shenai 		{ MBHOSTPARERR_F, "CIM mailbox host parity error", -1, 1 },
454889c3a86cSHariprasad Shenai 		{ TIEQINPARERRINT_F, "CIM TIEQ outgoing parity error", -1, 1 },
454989c3a86cSHariprasad Shenai 		{ TIEQOUTPARERRINT_F, "CIM TIEQ incoming parity error", -1, 1 },
4550d86cc04eSRahul Lakkireddy 		{ TIMER0INT_F, "CIM TIMER0 interrupt", -1, 1 },
4551f7917c00SJeff Kirsher 		{ 0 }
4552f7917c00SJeff Kirsher 	};
4553f7917c00SJeff Kirsher 	static const struct intr_info cim_upintr_info[] = {
455489c3a86cSHariprasad Shenai 		{ RSVDSPACEINT_F, "CIM reserved space access", -1, 1 },
455589c3a86cSHariprasad Shenai 		{ ILLTRANSINT_F, "CIM illegal transaction", -1, 1 },
455689c3a86cSHariprasad Shenai 		{ ILLWRINT_F, "CIM illegal write", -1, 1 },
455789c3a86cSHariprasad Shenai 		{ ILLRDINT_F, "CIM illegal read", -1, 1 },
455889c3a86cSHariprasad Shenai 		{ ILLRDBEINT_F, "CIM illegal read BE", -1, 1 },
455989c3a86cSHariprasad Shenai 		{ ILLWRBEINT_F, "CIM illegal write BE", -1, 1 },
456089c3a86cSHariprasad Shenai 		{ SGLRDBOOTINT_F, "CIM single read from boot space", -1, 1 },
456189c3a86cSHariprasad Shenai 		{ SGLWRBOOTINT_F, "CIM single write to boot space", -1, 1 },
456289c3a86cSHariprasad Shenai 		{ BLKWRBOOTINT_F, "CIM block write to boot space", -1, 1 },
456389c3a86cSHariprasad Shenai 		{ SGLRDFLASHINT_F, "CIM single read from flash space", -1, 1 },
456489c3a86cSHariprasad Shenai 		{ SGLWRFLASHINT_F, "CIM single write to flash space", -1, 1 },
456589c3a86cSHariprasad Shenai 		{ BLKWRFLASHINT_F, "CIM block write to flash space", -1, 1 },
456689c3a86cSHariprasad Shenai 		{ SGLRDEEPROMINT_F, "CIM single EEPROM read", -1, 1 },
456789c3a86cSHariprasad Shenai 		{ SGLWREEPROMINT_F, "CIM single EEPROM write", -1, 1 },
456889c3a86cSHariprasad Shenai 		{ BLKRDEEPROMINT_F, "CIM block EEPROM read", -1, 1 },
456989c3a86cSHariprasad Shenai 		{ BLKWREEPROMINT_F, "CIM block EEPROM write", -1, 1 },
457089c3a86cSHariprasad Shenai 		{ SGLRDCTLINT_F, "CIM single read from CTL space", -1, 1 },
457189c3a86cSHariprasad Shenai 		{ SGLWRCTLINT_F, "CIM single write to CTL space", -1, 1 },
457289c3a86cSHariprasad Shenai 		{ BLKRDCTLINT_F, "CIM block read from CTL space", -1, 1 },
457389c3a86cSHariprasad Shenai 		{ BLKWRCTLINT_F, "CIM block write to CTL space", -1, 1 },
457489c3a86cSHariprasad Shenai 		{ SGLRDPLINT_F, "CIM single read from PL space", -1, 1 },
457589c3a86cSHariprasad Shenai 		{ SGLWRPLINT_F, "CIM single write to PL space", -1, 1 },
457689c3a86cSHariprasad Shenai 		{ BLKRDPLINT_F, "CIM block read from PL space", -1, 1 },
457789c3a86cSHariprasad Shenai 		{ BLKWRPLINT_F, "CIM block write to PL space", -1, 1 },
457889c3a86cSHariprasad Shenai 		{ REQOVRLOOKUPINT_F, "CIM request FIFO overwrite", -1, 1 },
457989c3a86cSHariprasad Shenai 		{ RSPOVRLOOKUPINT_F, "CIM response FIFO overwrite", -1, 1 },
458089c3a86cSHariprasad Shenai 		{ TIMEOUTINT_F, "CIM PIF timeout", -1, 1 },
458189c3a86cSHariprasad Shenai 		{ TIMEOUTMAINT_F, "CIM PIF MA timeout", -1, 1 },
4582f7917c00SJeff Kirsher 		{ 0 }
4583f7917c00SJeff Kirsher 	};
4584f7917c00SJeff Kirsher 
4585d86cc04eSRahul Lakkireddy 	u32 val, fw_err;
4586f7917c00SJeff Kirsher 	int fat;
4587f7917c00SJeff Kirsher 
4588d86cc04eSRahul Lakkireddy 	fw_err = t4_read_reg(adapter, PCIE_FW_A);
4589d86cc04eSRahul Lakkireddy 	if (fw_err & PCIE_FW_ERR_F)
459031d55c2dSHariprasad Shenai 		t4_report_fw_error(adapter);
459131d55c2dSHariprasad Shenai 
4592d86cc04eSRahul Lakkireddy 	/* When the Firmware detects an internal error which normally
4593d86cc04eSRahul Lakkireddy 	 * wouldn't raise a Host Interrupt, it forces a CIM Timer0 interrupt
4594d86cc04eSRahul Lakkireddy 	 * in order to make sure the Host sees the Firmware Crash.  So
4595d86cc04eSRahul Lakkireddy 	 * if we have a Timer0 interrupt and don't see a Firmware Crash,
4596d86cc04eSRahul Lakkireddy 	 * ignore the Timer0 interrupt.
4597d86cc04eSRahul Lakkireddy 	 */
4598d86cc04eSRahul Lakkireddy 
4599d86cc04eSRahul Lakkireddy 	val = t4_read_reg(adapter, CIM_HOST_INT_CAUSE_A);
4600d86cc04eSRahul Lakkireddy 	if (val & TIMER0INT_F)
4601d86cc04eSRahul Lakkireddy 		if (!(fw_err & PCIE_FW_ERR_F) ||
4602d86cc04eSRahul Lakkireddy 		    (PCIE_FW_EVAL_G(fw_err) != PCIE_FW_EVAL_CRASH))
4603d86cc04eSRahul Lakkireddy 			t4_write_reg(adapter, CIM_HOST_INT_CAUSE_A,
4604d86cc04eSRahul Lakkireddy 				     TIMER0INT_F);
4605d86cc04eSRahul Lakkireddy 
460689c3a86cSHariprasad Shenai 	fat = t4_handle_intr_status(adapter, CIM_HOST_INT_CAUSE_A,
4607f7917c00SJeff Kirsher 				    cim_intr_info) +
460889c3a86cSHariprasad Shenai 	      t4_handle_intr_status(adapter, CIM_HOST_UPACC_INT_CAUSE_A,
4609f7917c00SJeff Kirsher 				    cim_upintr_info);
4610f7917c00SJeff Kirsher 	if (fat)
4611f7917c00SJeff Kirsher 		t4_fatal_err(adapter);
4612f7917c00SJeff Kirsher }
4613f7917c00SJeff Kirsher 
4614f7917c00SJeff Kirsher /*
4615f7917c00SJeff Kirsher  * ULP RX interrupt handler.
4616f7917c00SJeff Kirsher  */
ulprx_intr_handler(struct adapter * adapter)4617f7917c00SJeff Kirsher static void ulprx_intr_handler(struct adapter *adapter)
4618f7917c00SJeff Kirsher {
4619f7917c00SJeff Kirsher 	static const struct intr_info ulprx_intr_info[] = {
4620f7917c00SJeff Kirsher 		{ 0x1800000, "ULPRX context error", -1, 1 },
4621f7917c00SJeff Kirsher 		{ 0x7fffff, "ULPRX parity error", -1, 1 },
4622f7917c00SJeff Kirsher 		{ 0 }
4623f7917c00SJeff Kirsher 	};
4624f7917c00SJeff Kirsher 
46250d804338SHariprasad Shenai 	if (t4_handle_intr_status(adapter, ULP_RX_INT_CAUSE_A, ulprx_intr_info))
4626f7917c00SJeff Kirsher 		t4_fatal_err(adapter);
4627f7917c00SJeff Kirsher }
4628f7917c00SJeff Kirsher 
4629f7917c00SJeff Kirsher /*
4630f7917c00SJeff Kirsher  * ULP TX interrupt handler.
4631f7917c00SJeff Kirsher  */
ulptx_intr_handler(struct adapter * adapter)4632f7917c00SJeff Kirsher static void ulptx_intr_handler(struct adapter *adapter)
4633f7917c00SJeff Kirsher {
4634f7917c00SJeff Kirsher 	static const struct intr_info ulptx_intr_info[] = {
4635837e4a42SHariprasad Shenai 		{ PBL_BOUND_ERR_CH3_F, "ULPTX channel 3 PBL out of bounds", -1,
4636f7917c00SJeff Kirsher 		  0 },
4637837e4a42SHariprasad Shenai 		{ PBL_BOUND_ERR_CH2_F, "ULPTX channel 2 PBL out of bounds", -1,
4638f7917c00SJeff Kirsher 		  0 },
4639837e4a42SHariprasad Shenai 		{ PBL_BOUND_ERR_CH1_F, "ULPTX channel 1 PBL out of bounds", -1,
4640f7917c00SJeff Kirsher 		  0 },
4641837e4a42SHariprasad Shenai 		{ PBL_BOUND_ERR_CH0_F, "ULPTX channel 0 PBL out of bounds", -1,
4642f7917c00SJeff Kirsher 		  0 },
4643f7917c00SJeff Kirsher 		{ 0xfffffff, "ULPTX parity error", -1, 1 },
4644f7917c00SJeff Kirsher 		{ 0 }
4645f7917c00SJeff Kirsher 	};
4646f7917c00SJeff Kirsher 
4647837e4a42SHariprasad Shenai 	if (t4_handle_intr_status(adapter, ULP_TX_INT_CAUSE_A, ulptx_intr_info))
4648f7917c00SJeff Kirsher 		t4_fatal_err(adapter);
4649f7917c00SJeff Kirsher }
4650f7917c00SJeff Kirsher 
4651f7917c00SJeff Kirsher /*
4652f7917c00SJeff Kirsher  * PM TX interrupt handler.
4653f7917c00SJeff Kirsher  */
pmtx_intr_handler(struct adapter * adapter)4654f7917c00SJeff Kirsher static void pmtx_intr_handler(struct adapter *adapter)
4655f7917c00SJeff Kirsher {
4656f7917c00SJeff Kirsher 	static const struct intr_info pmtx_intr_info[] = {
4657837e4a42SHariprasad Shenai 		{ PCMD_LEN_OVFL0_F, "PMTX channel 0 pcmd too large", -1, 1 },
4658837e4a42SHariprasad Shenai 		{ PCMD_LEN_OVFL1_F, "PMTX channel 1 pcmd too large", -1, 1 },
4659837e4a42SHariprasad Shenai 		{ PCMD_LEN_OVFL2_F, "PMTX channel 2 pcmd too large", -1, 1 },
4660837e4a42SHariprasad Shenai 		{ ZERO_C_CMD_ERROR_F, "PMTX 0-length pcmd", -1, 1 },
4661837e4a42SHariprasad Shenai 		{ PMTX_FRAMING_ERROR_F, "PMTX framing error", -1, 1 },
4662837e4a42SHariprasad Shenai 		{ OESPI_PAR_ERROR_F, "PMTX oespi parity error", -1, 1 },
4663837e4a42SHariprasad Shenai 		{ DB_OPTIONS_PAR_ERROR_F, "PMTX db_options parity error",
4664837e4a42SHariprasad Shenai 		  -1, 1 },
4665837e4a42SHariprasad Shenai 		{ ICSPI_PAR_ERROR_F, "PMTX icspi parity error", -1, 1 },
4666837e4a42SHariprasad Shenai 		{ PMTX_C_PCMD_PAR_ERROR_F, "PMTX c_pcmd parity error", -1, 1},
4667f7917c00SJeff Kirsher 		{ 0 }
4668f7917c00SJeff Kirsher 	};
4669f7917c00SJeff Kirsher 
4670837e4a42SHariprasad Shenai 	if (t4_handle_intr_status(adapter, PM_TX_INT_CAUSE_A, pmtx_intr_info))
4671f7917c00SJeff Kirsher 		t4_fatal_err(adapter);
4672f7917c00SJeff Kirsher }
4673f7917c00SJeff Kirsher 
4674f7917c00SJeff Kirsher /*
4675f7917c00SJeff Kirsher  * PM RX interrupt handler.
4676f7917c00SJeff Kirsher  */
pmrx_intr_handler(struct adapter * adapter)4677f7917c00SJeff Kirsher static void pmrx_intr_handler(struct adapter *adapter)
4678f7917c00SJeff Kirsher {
4679f7917c00SJeff Kirsher 	static const struct intr_info pmrx_intr_info[] = {
4680837e4a42SHariprasad Shenai 		{ ZERO_E_CMD_ERROR_F, "PMRX 0-length pcmd", -1, 1 },
4681837e4a42SHariprasad Shenai 		{ PMRX_FRAMING_ERROR_F, "PMRX framing error", -1, 1 },
4682837e4a42SHariprasad Shenai 		{ OCSPI_PAR_ERROR_F, "PMRX ocspi parity error", -1, 1 },
4683837e4a42SHariprasad Shenai 		{ DB_OPTIONS_PAR_ERROR_F, "PMRX db_options parity error",
4684837e4a42SHariprasad Shenai 		  -1, 1 },
4685837e4a42SHariprasad Shenai 		{ IESPI_PAR_ERROR_F, "PMRX iespi parity error", -1, 1 },
4686837e4a42SHariprasad Shenai 		{ PMRX_E_PCMD_PAR_ERROR_F, "PMRX e_pcmd parity error", -1, 1},
4687f7917c00SJeff Kirsher 		{ 0 }
4688f7917c00SJeff Kirsher 	};
4689f7917c00SJeff Kirsher 
4690837e4a42SHariprasad Shenai 	if (t4_handle_intr_status(adapter, PM_RX_INT_CAUSE_A, pmrx_intr_info))
4691f7917c00SJeff Kirsher 		t4_fatal_err(adapter);
4692f7917c00SJeff Kirsher }
4693f7917c00SJeff Kirsher 
4694f7917c00SJeff Kirsher /*
4695f7917c00SJeff Kirsher  * CPL switch interrupt handler.
4696f7917c00SJeff Kirsher  */
cplsw_intr_handler(struct adapter * adapter)4697f7917c00SJeff Kirsher static void cplsw_intr_handler(struct adapter *adapter)
4698f7917c00SJeff Kirsher {
4699f7917c00SJeff Kirsher 	static const struct intr_info cplsw_intr_info[] = {
47000d804338SHariprasad Shenai 		{ CIM_OP_MAP_PERR_F, "CPLSW CIM op_map parity error", -1, 1 },
47010d804338SHariprasad Shenai 		{ CIM_OVFL_ERROR_F, "CPLSW CIM overflow", -1, 1 },
47020d804338SHariprasad Shenai 		{ TP_FRAMING_ERROR_F, "CPLSW TP framing error", -1, 1 },
47030d804338SHariprasad Shenai 		{ SGE_FRAMING_ERROR_F, "CPLSW SGE framing error", -1, 1 },
47040d804338SHariprasad Shenai 		{ CIM_FRAMING_ERROR_F, "CPLSW CIM framing error", -1, 1 },
47050d804338SHariprasad Shenai 		{ ZERO_SWITCH_ERROR_F, "CPLSW no-switch error", -1, 1 },
4706f7917c00SJeff Kirsher 		{ 0 }
4707f7917c00SJeff Kirsher 	};
4708f7917c00SJeff Kirsher 
47090d804338SHariprasad Shenai 	if (t4_handle_intr_status(adapter, CPL_INTR_CAUSE_A, cplsw_intr_info))
4710f7917c00SJeff Kirsher 		t4_fatal_err(adapter);
4711f7917c00SJeff Kirsher }
4712f7917c00SJeff Kirsher 
4713f7917c00SJeff Kirsher /*
4714f7917c00SJeff Kirsher  * LE interrupt handler.
4715f7917c00SJeff Kirsher  */
le_intr_handler(struct adapter * adap)4716f7917c00SJeff Kirsher static void le_intr_handler(struct adapter *adap)
4717f7917c00SJeff Kirsher {
47183ccc6cf7SHariprasad Shenai 	enum chip_type chip = CHELSIO_CHIP_VERSION(adap->params.chip);
4719f7917c00SJeff Kirsher 	static const struct intr_info le_intr_info[] = {
47200d804338SHariprasad Shenai 		{ LIPMISS_F, "LE LIP miss", -1, 0 },
47210d804338SHariprasad Shenai 		{ LIP0_F, "LE 0 LIP error", -1, 0 },
47220d804338SHariprasad Shenai 		{ PARITYERR_F, "LE parity error", -1, 1 },
47230d804338SHariprasad Shenai 		{ UNKNOWNCMD_F, "LE unknown command", -1, 1 },
47240d804338SHariprasad Shenai 		{ REQQPARERR_F, "LE request queue parity error", -1, 1 },
4725f7917c00SJeff Kirsher 		{ 0 }
4726f7917c00SJeff Kirsher 	};
4727f7917c00SJeff Kirsher 
47283ccc6cf7SHariprasad Shenai 	static struct intr_info t6_le_intr_info[] = {
47293ccc6cf7SHariprasad Shenai 		{ T6_LIPMISS_F, "LE LIP miss", -1, 0 },
47303ccc6cf7SHariprasad Shenai 		{ T6_LIP0_F, "LE 0 LIP error", -1, 0 },
4731cca85283SRaju Rangoju 		{ CMDTIDERR_F, "LE cmd tid error", -1, 1 },
47323ccc6cf7SHariprasad Shenai 		{ TCAMINTPERR_F, "LE parity error", -1, 1 },
47333ccc6cf7SHariprasad Shenai 		{ T6_UNKNOWNCMD_F, "LE unknown command", -1, 1 },
47343ccc6cf7SHariprasad Shenai 		{ SSRAMINTPERR_F, "LE request queue parity error", -1, 1 },
4735cca85283SRaju Rangoju 		{ HASHTBLMEMCRCERR_F, "LE hash table mem crc error", -1, 0 },
47363ccc6cf7SHariprasad Shenai 		{ 0 }
47373ccc6cf7SHariprasad Shenai 	};
47383ccc6cf7SHariprasad Shenai 
47393ccc6cf7SHariprasad Shenai 	if (t4_handle_intr_status(adap, LE_DB_INT_CAUSE_A,
47403ccc6cf7SHariprasad Shenai 				  (chip <= CHELSIO_T5) ?
47413ccc6cf7SHariprasad Shenai 				  le_intr_info : t6_le_intr_info))
4742f7917c00SJeff Kirsher 		t4_fatal_err(adap);
4743f7917c00SJeff Kirsher }
4744f7917c00SJeff Kirsher 
4745f7917c00SJeff Kirsher /*
4746f7917c00SJeff Kirsher  * MPS interrupt handler.
4747f7917c00SJeff Kirsher  */
mps_intr_handler(struct adapter * adapter)4748f7917c00SJeff Kirsher static void mps_intr_handler(struct adapter *adapter)
4749f7917c00SJeff Kirsher {
4750f7917c00SJeff Kirsher 	static const struct intr_info mps_rx_intr_info[] = {
4751f7917c00SJeff Kirsher 		{ 0xffffff, "MPS Rx parity error", -1, 1 },
4752f7917c00SJeff Kirsher 		{ 0 }
4753f7917c00SJeff Kirsher 	};
4754f7917c00SJeff Kirsher 	static const struct intr_info mps_tx_intr_info[] = {
4755837e4a42SHariprasad Shenai 		{ TPFIFO_V(TPFIFO_M), "MPS Tx TP FIFO parity error", -1, 1 },
4756837e4a42SHariprasad Shenai 		{ NCSIFIFO_F, "MPS Tx NC-SI FIFO parity error", -1, 1 },
4757837e4a42SHariprasad Shenai 		{ TXDATAFIFO_V(TXDATAFIFO_M), "MPS Tx data FIFO parity error",
4758837e4a42SHariprasad Shenai 		  -1, 1 },
4759837e4a42SHariprasad Shenai 		{ TXDESCFIFO_V(TXDESCFIFO_M), "MPS Tx desc FIFO parity error",
4760837e4a42SHariprasad Shenai 		  -1, 1 },
4761837e4a42SHariprasad Shenai 		{ BUBBLE_F, "MPS Tx underflow", -1, 1 },
4762837e4a42SHariprasad Shenai 		{ SECNTERR_F, "MPS Tx SOP/EOP error", -1, 1 },
4763837e4a42SHariprasad Shenai 		{ FRMERR_F, "MPS Tx framing error", -1, 1 },
4764f7917c00SJeff Kirsher 		{ 0 }
4765f7917c00SJeff Kirsher 	};
4766ef18e3b9SGanesh Goudar 	static const struct intr_info t6_mps_tx_intr_info[] = {
4767ef18e3b9SGanesh Goudar 		{ TPFIFO_V(TPFIFO_M), "MPS Tx TP FIFO parity error", -1, 1 },
4768ef18e3b9SGanesh Goudar 		{ NCSIFIFO_F, "MPS Tx NC-SI FIFO parity error", -1, 1 },
4769ef18e3b9SGanesh Goudar 		{ TXDATAFIFO_V(TXDATAFIFO_M), "MPS Tx data FIFO parity error",
4770ef18e3b9SGanesh Goudar 		  -1, 1 },
4771ef18e3b9SGanesh Goudar 		{ TXDESCFIFO_V(TXDESCFIFO_M), "MPS Tx desc FIFO parity error",
4772ef18e3b9SGanesh Goudar 		  -1, 1 },
4773ef18e3b9SGanesh Goudar 		/* MPS Tx Bubble is normal for T6 */
4774ef18e3b9SGanesh Goudar 		{ SECNTERR_F, "MPS Tx SOP/EOP error", -1, 1 },
4775ef18e3b9SGanesh Goudar 		{ FRMERR_F, "MPS Tx framing error", -1, 1 },
4776ef18e3b9SGanesh Goudar 		{ 0 }
4777ef18e3b9SGanesh Goudar 	};
4778f7917c00SJeff Kirsher 	static const struct intr_info mps_trc_intr_info[] = {
4779837e4a42SHariprasad Shenai 		{ FILTMEM_V(FILTMEM_M), "MPS TRC filter parity error", -1, 1 },
4780837e4a42SHariprasad Shenai 		{ PKTFIFO_V(PKTFIFO_M), "MPS TRC packet FIFO parity error",
4781837e4a42SHariprasad Shenai 		  -1, 1 },
4782837e4a42SHariprasad Shenai 		{ MISCPERR_F, "MPS TRC misc parity error", -1, 1 },
4783f7917c00SJeff Kirsher 		{ 0 }
4784f7917c00SJeff Kirsher 	};
4785f7917c00SJeff Kirsher 	static const struct intr_info mps_stat_sram_intr_info[] = {
4786f7917c00SJeff Kirsher 		{ 0x1fffff, "MPS statistics SRAM parity error", -1, 1 },
4787f7917c00SJeff Kirsher 		{ 0 }
4788f7917c00SJeff Kirsher 	};
4789f7917c00SJeff Kirsher 	static const struct intr_info mps_stat_tx_intr_info[] = {
4790f7917c00SJeff Kirsher 		{ 0xfffff, "MPS statistics Tx FIFO parity error", -1, 1 },
4791f7917c00SJeff Kirsher 		{ 0 }
4792f7917c00SJeff Kirsher 	};
4793f7917c00SJeff Kirsher 	static const struct intr_info mps_stat_rx_intr_info[] = {
4794f7917c00SJeff Kirsher 		{ 0xffffff, "MPS statistics Rx FIFO parity error", -1, 1 },
4795f7917c00SJeff Kirsher 		{ 0 }
4796f7917c00SJeff Kirsher 	};
4797f7917c00SJeff Kirsher 	static const struct intr_info mps_cls_intr_info[] = {
4798837e4a42SHariprasad Shenai 		{ MATCHSRAM_F, "MPS match SRAM parity error", -1, 1 },
4799837e4a42SHariprasad Shenai 		{ MATCHTCAM_F, "MPS match TCAM parity error", -1, 1 },
4800837e4a42SHariprasad Shenai 		{ HASHSRAM_F, "MPS hash SRAM parity error", -1, 1 },
4801f7917c00SJeff Kirsher 		{ 0 }
4802f7917c00SJeff Kirsher 	};
4803f7917c00SJeff Kirsher 
4804f7917c00SJeff Kirsher 	int fat;
4805f7917c00SJeff Kirsher 
4806837e4a42SHariprasad Shenai 	fat = t4_handle_intr_status(adapter, MPS_RX_PERR_INT_CAUSE_A,
4807f7917c00SJeff Kirsher 				    mps_rx_intr_info) +
4808837e4a42SHariprasad Shenai 	      t4_handle_intr_status(adapter, MPS_TX_INT_CAUSE_A,
4809ef18e3b9SGanesh Goudar 				    is_t6(adapter->params.chip)
4810ef18e3b9SGanesh Goudar 				    ? t6_mps_tx_intr_info
4811ef18e3b9SGanesh Goudar 				    : mps_tx_intr_info) +
4812837e4a42SHariprasad Shenai 	      t4_handle_intr_status(adapter, MPS_TRC_INT_CAUSE_A,
4813f7917c00SJeff Kirsher 				    mps_trc_intr_info) +
4814837e4a42SHariprasad Shenai 	      t4_handle_intr_status(adapter, MPS_STAT_PERR_INT_CAUSE_SRAM_A,
4815f7917c00SJeff Kirsher 				    mps_stat_sram_intr_info) +
4816837e4a42SHariprasad Shenai 	      t4_handle_intr_status(adapter, MPS_STAT_PERR_INT_CAUSE_TX_FIFO_A,
4817f7917c00SJeff Kirsher 				    mps_stat_tx_intr_info) +
4818837e4a42SHariprasad Shenai 	      t4_handle_intr_status(adapter, MPS_STAT_PERR_INT_CAUSE_RX_FIFO_A,
4819f7917c00SJeff Kirsher 				    mps_stat_rx_intr_info) +
4820837e4a42SHariprasad Shenai 	      t4_handle_intr_status(adapter, MPS_CLS_INT_CAUSE_A,
4821f7917c00SJeff Kirsher 				    mps_cls_intr_info);
4822f7917c00SJeff Kirsher 
4823837e4a42SHariprasad Shenai 	t4_write_reg(adapter, MPS_INT_CAUSE_A, 0);
4824837e4a42SHariprasad Shenai 	t4_read_reg(adapter, MPS_INT_CAUSE_A);                    /* flush */
4825f7917c00SJeff Kirsher 	if (fat)
4826f7917c00SJeff Kirsher 		t4_fatal_err(adapter);
4827f7917c00SJeff Kirsher }
4828f7917c00SJeff Kirsher 
482989c3a86cSHariprasad Shenai #define MEM_INT_MASK (PERR_INT_CAUSE_F | ECC_CE_INT_CAUSE_F | \
483089c3a86cSHariprasad Shenai 		      ECC_UE_INT_CAUSE_F)
4831f7917c00SJeff Kirsher 
4832f7917c00SJeff Kirsher /*
4833f7917c00SJeff Kirsher  * EDC/MC interrupt handler.
4834f7917c00SJeff Kirsher  */
mem_intr_handler(struct adapter * adapter,int idx)4835f7917c00SJeff Kirsher static void mem_intr_handler(struct adapter *adapter, int idx)
4836f7917c00SJeff Kirsher {
4837822dd8a8SHariprasad Shenai 	static const char name[4][7] = { "EDC0", "EDC1", "MC/MC0", "MC1" };
4838f7917c00SJeff Kirsher 
4839f7917c00SJeff Kirsher 	unsigned int addr, cnt_addr, v;
4840f7917c00SJeff Kirsher 
4841f7917c00SJeff Kirsher 	if (idx <= MEM_EDC1) {
484289c3a86cSHariprasad Shenai 		addr = EDC_REG(EDC_INT_CAUSE_A, idx);
484389c3a86cSHariprasad Shenai 		cnt_addr = EDC_REG(EDC_ECC_STATUS_A, idx);
4844822dd8a8SHariprasad Shenai 	} else if (idx == MEM_MC) {
4845822dd8a8SHariprasad Shenai 		if (is_t4(adapter->params.chip)) {
484689c3a86cSHariprasad Shenai 			addr = MC_INT_CAUSE_A;
484789c3a86cSHariprasad Shenai 			cnt_addr = MC_ECC_STATUS_A;
4848822dd8a8SHariprasad Shenai 		} else {
484989c3a86cSHariprasad Shenai 			addr = MC_P_INT_CAUSE_A;
485089c3a86cSHariprasad Shenai 			cnt_addr = MC_P_ECC_STATUS_A;
4851822dd8a8SHariprasad Shenai 		}
4852822dd8a8SHariprasad Shenai 	} else {
485389c3a86cSHariprasad Shenai 		addr = MC_REG(MC_P_INT_CAUSE_A, 1);
485489c3a86cSHariprasad Shenai 		cnt_addr = MC_REG(MC_P_ECC_STATUS_A, 1);
4855f7917c00SJeff Kirsher 	}
4856f7917c00SJeff Kirsher 
4857f7917c00SJeff Kirsher 	v = t4_read_reg(adapter, addr) & MEM_INT_MASK;
485889c3a86cSHariprasad Shenai 	if (v & PERR_INT_CAUSE_F)
4859f7917c00SJeff Kirsher 		dev_alert(adapter->pdev_dev, "%s FIFO parity error\n",
4860f7917c00SJeff Kirsher 			  name[idx]);
486189c3a86cSHariprasad Shenai 	if (v & ECC_CE_INT_CAUSE_F) {
486289c3a86cSHariprasad Shenai 		u32 cnt = ECC_CECNT_G(t4_read_reg(adapter, cnt_addr));
4863f7917c00SJeff Kirsher 
4864bf8ebb67SHariprasad Shenai 		t4_edc_err_read(adapter, idx);
4865bf8ebb67SHariprasad Shenai 
486689c3a86cSHariprasad Shenai 		t4_write_reg(adapter, cnt_addr, ECC_CECNT_V(ECC_CECNT_M));
4867f7917c00SJeff Kirsher 		if (printk_ratelimit())
4868f7917c00SJeff Kirsher 			dev_warn(adapter->pdev_dev,
4869f7917c00SJeff Kirsher 				 "%u %s correctable ECC data error%s\n",
4870f7917c00SJeff Kirsher 				 cnt, name[idx], cnt > 1 ? "s" : "");
4871f7917c00SJeff Kirsher 	}
487289c3a86cSHariprasad Shenai 	if (v & ECC_UE_INT_CAUSE_F)
4873f7917c00SJeff Kirsher 		dev_alert(adapter->pdev_dev,
4874f7917c00SJeff Kirsher 			  "%s uncorrectable ECC data error\n", name[idx]);
4875f7917c00SJeff Kirsher 
4876f7917c00SJeff Kirsher 	t4_write_reg(adapter, addr, v);
487789c3a86cSHariprasad Shenai 	if (v & (PERR_INT_CAUSE_F | ECC_UE_INT_CAUSE_F))
4878f7917c00SJeff Kirsher 		t4_fatal_err(adapter);
4879f7917c00SJeff Kirsher }
4880f7917c00SJeff Kirsher 
4881f7917c00SJeff Kirsher /*
4882f7917c00SJeff Kirsher  * MA interrupt handler.
4883f7917c00SJeff Kirsher  */
ma_intr_handler(struct adapter * adap)4884f7917c00SJeff Kirsher static void ma_intr_handler(struct adapter *adap)
4885f7917c00SJeff Kirsher {
488689c3a86cSHariprasad Shenai 	u32 v, status = t4_read_reg(adap, MA_INT_CAUSE_A);
4887f7917c00SJeff Kirsher 
488889c3a86cSHariprasad Shenai 	if (status & MEM_PERR_INT_CAUSE_F) {
4889f7917c00SJeff Kirsher 		dev_alert(adap->pdev_dev,
4890f7917c00SJeff Kirsher 			  "MA parity error, parity status %#x\n",
489189c3a86cSHariprasad Shenai 			  t4_read_reg(adap, MA_PARITY_ERROR_STATUS1_A));
48929bb59b96SHariprasad Shenai 		if (is_t5(adap->params.chip))
48939bb59b96SHariprasad Shenai 			dev_alert(adap->pdev_dev,
48949bb59b96SHariprasad Shenai 				  "MA parity error, parity status %#x\n",
48959bb59b96SHariprasad Shenai 				  t4_read_reg(adap,
489689c3a86cSHariprasad Shenai 					      MA_PARITY_ERROR_STATUS2_A));
48979bb59b96SHariprasad Shenai 	}
489889c3a86cSHariprasad Shenai 	if (status & MEM_WRAP_INT_CAUSE_F) {
489989c3a86cSHariprasad Shenai 		v = t4_read_reg(adap, MA_INT_WRAP_STATUS_A);
4900f7917c00SJeff Kirsher 		dev_alert(adap->pdev_dev, "MA address wrap-around error by "
4901f7917c00SJeff Kirsher 			  "client %u to address %#x\n",
490289c3a86cSHariprasad Shenai 			  MEM_WRAP_CLIENT_NUM_G(v),
490389c3a86cSHariprasad Shenai 			  MEM_WRAP_ADDRESS_G(v) << 4);
4904f7917c00SJeff Kirsher 	}
490589c3a86cSHariprasad Shenai 	t4_write_reg(adap, MA_INT_CAUSE_A, status);
4906f7917c00SJeff Kirsher 	t4_fatal_err(adap);
4907f7917c00SJeff Kirsher }
4908f7917c00SJeff Kirsher 
4909f7917c00SJeff Kirsher /*
4910f7917c00SJeff Kirsher  * SMB interrupt handler.
4911f7917c00SJeff Kirsher  */
smb_intr_handler(struct adapter * adap)4912f7917c00SJeff Kirsher static void smb_intr_handler(struct adapter *adap)
4913f7917c00SJeff Kirsher {
4914f7917c00SJeff Kirsher 	static const struct intr_info smb_intr_info[] = {
49150d804338SHariprasad Shenai 		{ MSTTXFIFOPARINT_F, "SMB master Tx FIFO parity error", -1, 1 },
49160d804338SHariprasad Shenai 		{ MSTRXFIFOPARINT_F, "SMB master Rx FIFO parity error", -1, 1 },
49170d804338SHariprasad Shenai 		{ SLVFIFOPARINT_F, "SMB slave FIFO parity error", -1, 1 },
4918f7917c00SJeff Kirsher 		{ 0 }
4919f7917c00SJeff Kirsher 	};
4920f7917c00SJeff Kirsher 
49210d804338SHariprasad Shenai 	if (t4_handle_intr_status(adap, SMB_INT_CAUSE_A, smb_intr_info))
4922f7917c00SJeff Kirsher 		t4_fatal_err(adap);
4923f7917c00SJeff Kirsher }
4924f7917c00SJeff Kirsher 
4925f7917c00SJeff Kirsher /*
4926f7917c00SJeff Kirsher  * NC-SI interrupt handler.
4927f7917c00SJeff Kirsher  */
ncsi_intr_handler(struct adapter * adap)4928f7917c00SJeff Kirsher static void ncsi_intr_handler(struct adapter *adap)
4929f7917c00SJeff Kirsher {
4930f7917c00SJeff Kirsher 	static const struct intr_info ncsi_intr_info[] = {
49310d804338SHariprasad Shenai 		{ CIM_DM_PRTY_ERR_F, "NC-SI CIM parity error", -1, 1 },
49320d804338SHariprasad Shenai 		{ MPS_DM_PRTY_ERR_F, "NC-SI MPS parity error", -1, 1 },
49330d804338SHariprasad Shenai 		{ TXFIFO_PRTY_ERR_F, "NC-SI Tx FIFO parity error", -1, 1 },
49340d804338SHariprasad Shenai 		{ RXFIFO_PRTY_ERR_F, "NC-SI Rx FIFO parity error", -1, 1 },
4935f7917c00SJeff Kirsher 		{ 0 }
4936f7917c00SJeff Kirsher 	};
4937f7917c00SJeff Kirsher 
49380d804338SHariprasad Shenai 	if (t4_handle_intr_status(adap, NCSI_INT_CAUSE_A, ncsi_intr_info))
4939f7917c00SJeff Kirsher 		t4_fatal_err(adap);
4940f7917c00SJeff Kirsher }
4941f7917c00SJeff Kirsher 
4942f7917c00SJeff Kirsher /*
4943f7917c00SJeff Kirsher  * XGMAC interrupt handler.
4944f7917c00SJeff Kirsher  */
xgmac_intr_handler(struct adapter * adap,int port)4945f7917c00SJeff Kirsher static void xgmac_intr_handler(struct adapter *adap, int port)
4946f7917c00SJeff Kirsher {
49470a57a536SSantosh Rastapur 	u32 v, int_cause_reg;
49480a57a536SSantosh Rastapur 
4949d14807ddSHariprasad Shenai 	if (is_t4(adap->params.chip))
49500d804338SHariprasad Shenai 		int_cause_reg = PORT_REG(port, XGMAC_PORT_INT_CAUSE_A);
49510a57a536SSantosh Rastapur 	else
49520d804338SHariprasad Shenai 		int_cause_reg = T5_PORT_REG(port, MAC_PORT_INT_CAUSE_A);
49530a57a536SSantosh Rastapur 
49540a57a536SSantosh Rastapur 	v = t4_read_reg(adap, int_cause_reg);
4955f7917c00SJeff Kirsher 
49560d804338SHariprasad Shenai 	v &= TXFIFO_PRTY_ERR_F | RXFIFO_PRTY_ERR_F;
4957f7917c00SJeff Kirsher 	if (!v)
4958f7917c00SJeff Kirsher 		return;
4959f7917c00SJeff Kirsher 
49600d804338SHariprasad Shenai 	if (v & TXFIFO_PRTY_ERR_F)
4961f7917c00SJeff Kirsher 		dev_alert(adap->pdev_dev, "XGMAC %d Tx FIFO parity error\n",
4962f7917c00SJeff Kirsher 			  port);
49630d804338SHariprasad Shenai 	if (v & RXFIFO_PRTY_ERR_F)
4964f7917c00SJeff Kirsher 		dev_alert(adap->pdev_dev, "XGMAC %d Rx FIFO parity error\n",
4965f7917c00SJeff Kirsher 			  port);
49660d804338SHariprasad Shenai 	t4_write_reg(adap, PORT_REG(port, XGMAC_PORT_INT_CAUSE_A), v);
4967f7917c00SJeff Kirsher 	t4_fatal_err(adap);
4968f7917c00SJeff Kirsher }
4969f7917c00SJeff Kirsher 
4970f7917c00SJeff Kirsher /*
4971f7917c00SJeff Kirsher  * PL interrupt handler.
4972f7917c00SJeff Kirsher  */
pl_intr_handler(struct adapter * adap)4973f7917c00SJeff Kirsher static void pl_intr_handler(struct adapter *adap)
4974f7917c00SJeff Kirsher {
4975f7917c00SJeff Kirsher 	static const struct intr_info pl_intr_info[] = {
49760d804338SHariprasad Shenai 		{ FATALPERR_F, "T4 fatal parity error", -1, 1 },
49770d804338SHariprasad Shenai 		{ PERRVFID_F, "PL VFID_MAP parity error", -1, 1 },
4978f7917c00SJeff Kirsher 		{ 0 }
4979f7917c00SJeff Kirsher 	};
4980f7917c00SJeff Kirsher 
49810d804338SHariprasad Shenai 	if (t4_handle_intr_status(adap, PL_PL_INT_CAUSE_A, pl_intr_info))
4982f7917c00SJeff Kirsher 		t4_fatal_err(adap);
4983f7917c00SJeff Kirsher }
4984f7917c00SJeff Kirsher 
49850d804338SHariprasad Shenai #define PF_INTR_MASK (PFSW_F)
49860d804338SHariprasad Shenai #define GLBL_INTR_MASK (CIM_F | MPS_F | PL_F | PCIE_F | MC_F | EDC0_F | \
49870d804338SHariprasad Shenai 		EDC1_F | LE_F | TP_F | MA_F | PM_TX_F | PM_RX_F | ULP_RX_F | \
498838b6ec50SGanesh Goudar 		CPL_SWITCH_F | SGE_F | ULP_TX_F | SF_F)
4989f7917c00SJeff Kirsher 
4990f7917c00SJeff Kirsher /**
4991f7917c00SJeff Kirsher  *	t4_slow_intr_handler - control path interrupt handler
4992f7917c00SJeff Kirsher  *	@adapter: the adapter
4993f7917c00SJeff Kirsher  *
4994f7917c00SJeff Kirsher  *	T4 interrupt handler for non-data global interrupt events, e.g., errors.
4995f7917c00SJeff Kirsher  *	The designation 'slow' is because it involves register reads, while
4996f7917c00SJeff Kirsher  *	data interrupts typically don't involve any MMIOs.
4997f7917c00SJeff Kirsher  */
t4_slow_intr_handler(struct adapter * adapter)4998f7917c00SJeff Kirsher int t4_slow_intr_handler(struct adapter *adapter)
4999f7917c00SJeff Kirsher {
500064ccfd2dSVishal Kulkarni 	/* There are rare cases where a PL_INT_CAUSE bit may end up getting
500164ccfd2dSVishal Kulkarni 	 * set when the corresponding PL_INT_ENABLE bit isn't set.  It's
500264ccfd2dSVishal Kulkarni 	 * easiest just to mask that case here.
500364ccfd2dSVishal Kulkarni 	 */
500464ccfd2dSVishal Kulkarni 	u32 raw_cause = t4_read_reg(adapter, PL_INT_CAUSE_A);
500564ccfd2dSVishal Kulkarni 	u32 enable = t4_read_reg(adapter, PL_INT_ENABLE_A);
500664ccfd2dSVishal Kulkarni 	u32 cause = raw_cause & enable;
5007f7917c00SJeff Kirsher 
5008f7917c00SJeff Kirsher 	if (!(cause & GLBL_INTR_MASK))
5009f7917c00SJeff Kirsher 		return 0;
50100d804338SHariprasad Shenai 	if (cause & CIM_F)
5011f7917c00SJeff Kirsher 		cim_intr_handler(adapter);
50120d804338SHariprasad Shenai 	if (cause & MPS_F)
5013f7917c00SJeff Kirsher 		mps_intr_handler(adapter);
50140d804338SHariprasad Shenai 	if (cause & NCSI_F)
5015f7917c00SJeff Kirsher 		ncsi_intr_handler(adapter);
50160d804338SHariprasad Shenai 	if (cause & PL_F)
5017f7917c00SJeff Kirsher 		pl_intr_handler(adapter);
50180d804338SHariprasad Shenai 	if (cause & SMB_F)
5019f7917c00SJeff Kirsher 		smb_intr_handler(adapter);
50200d804338SHariprasad Shenai 	if (cause & XGMAC0_F)
5021f7917c00SJeff Kirsher 		xgmac_intr_handler(adapter, 0);
50220d804338SHariprasad Shenai 	if (cause & XGMAC1_F)
5023f7917c00SJeff Kirsher 		xgmac_intr_handler(adapter, 1);
50240d804338SHariprasad Shenai 	if (cause & XGMAC_KR0_F)
5025f7917c00SJeff Kirsher 		xgmac_intr_handler(adapter, 2);
50260d804338SHariprasad Shenai 	if (cause & XGMAC_KR1_F)
5027f7917c00SJeff Kirsher 		xgmac_intr_handler(adapter, 3);
50280d804338SHariprasad Shenai 	if (cause & PCIE_F)
5029f7917c00SJeff Kirsher 		pcie_intr_handler(adapter);
50300d804338SHariprasad Shenai 	if (cause & MC_F)
5031f7917c00SJeff Kirsher 		mem_intr_handler(adapter, MEM_MC);
50323ccc6cf7SHariprasad Shenai 	if (is_t5(adapter->params.chip) && (cause & MC1_F))
5033822dd8a8SHariprasad Shenai 		mem_intr_handler(adapter, MEM_MC1);
50340d804338SHariprasad Shenai 	if (cause & EDC0_F)
5035f7917c00SJeff Kirsher 		mem_intr_handler(adapter, MEM_EDC0);
50360d804338SHariprasad Shenai 	if (cause & EDC1_F)
5037f7917c00SJeff Kirsher 		mem_intr_handler(adapter, MEM_EDC1);
50380d804338SHariprasad Shenai 	if (cause & LE_F)
5039f7917c00SJeff Kirsher 		le_intr_handler(adapter);
50400d804338SHariprasad Shenai 	if (cause & TP_F)
5041f7917c00SJeff Kirsher 		tp_intr_handler(adapter);
50420d804338SHariprasad Shenai 	if (cause & MA_F)
5043f7917c00SJeff Kirsher 		ma_intr_handler(adapter);
50440d804338SHariprasad Shenai 	if (cause & PM_TX_F)
5045f7917c00SJeff Kirsher 		pmtx_intr_handler(adapter);
50460d804338SHariprasad Shenai 	if (cause & PM_RX_F)
5047f7917c00SJeff Kirsher 		pmrx_intr_handler(adapter);
50480d804338SHariprasad Shenai 	if (cause & ULP_RX_F)
5049f7917c00SJeff Kirsher 		ulprx_intr_handler(adapter);
50500d804338SHariprasad Shenai 	if (cause & CPL_SWITCH_F)
5051f7917c00SJeff Kirsher 		cplsw_intr_handler(adapter);
50520d804338SHariprasad Shenai 	if (cause & SGE_F)
5053f7917c00SJeff Kirsher 		sge_intr_handler(adapter);
50540d804338SHariprasad Shenai 	if (cause & ULP_TX_F)
5055f7917c00SJeff Kirsher 		ulptx_intr_handler(adapter);
5056f7917c00SJeff Kirsher 
5057f7917c00SJeff Kirsher 	/* Clear the interrupts just processed for which we are the master. */
505864ccfd2dSVishal Kulkarni 	t4_write_reg(adapter, PL_INT_CAUSE_A, raw_cause & GLBL_INTR_MASK);
50590d804338SHariprasad Shenai 	(void)t4_read_reg(adapter, PL_INT_CAUSE_A); /* flush */
5060f7917c00SJeff Kirsher 	return 1;
5061f7917c00SJeff Kirsher }
5062f7917c00SJeff Kirsher 
5063f7917c00SJeff Kirsher /**
5064f7917c00SJeff Kirsher  *	t4_intr_enable - enable interrupts
5065f7917c00SJeff Kirsher  *	@adapter: the adapter whose interrupts should be enabled
5066f7917c00SJeff Kirsher  *
5067f7917c00SJeff Kirsher  *	Enable PF-specific interrupts for the calling function and the top-level
5068f7917c00SJeff Kirsher  *	interrupt concentrator for global interrupts.  Interrupts are already
5069f7917c00SJeff Kirsher  *	enabled at each module,	here we just enable the roots of the interrupt
5070f7917c00SJeff Kirsher  *	hierarchies.
5071f7917c00SJeff Kirsher  *
5072f7917c00SJeff Kirsher  *	Note: this function should be called only when the driver manages
5073f7917c00SJeff Kirsher  *	non PF-specific interrupts from the various HW modules.  Only one PCI
5074f7917c00SJeff Kirsher  *	function at a time should be doing this.
5075f7917c00SJeff Kirsher  */
t4_intr_enable(struct adapter * adapter)5076f7917c00SJeff Kirsher void t4_intr_enable(struct adapter *adapter)
5077f7917c00SJeff Kirsher {
50783ccc6cf7SHariprasad Shenai 	u32 val = 0;
5079d86bd29eSHariprasad Shenai 	u32 whoami = t4_read_reg(adapter, PL_WHOAMI_A);
5080d86bd29eSHariprasad Shenai 	u32 pf = CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5 ?
5081d86bd29eSHariprasad Shenai 			SOURCEPF_G(whoami) : T6_SOURCEPF_G(whoami);
5082f7917c00SJeff Kirsher 
50833ccc6cf7SHariprasad Shenai 	if (CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5)
50843ccc6cf7SHariprasad Shenai 		val = ERR_DROPPED_DB_F | ERR_EGR_CTXT_PRIO_F | DBFIFO_HP_INT_F;
5085f612b815SHariprasad Shenai 	t4_write_reg(adapter, SGE_INT_ENABLE3_A, ERR_CPL_EXCEED_IQE_SIZE_F |
5086f612b815SHariprasad Shenai 		     ERR_INVALID_CIDX_INC_F | ERR_CPL_OPCODE_0_F |
50873ccc6cf7SHariprasad Shenai 		     ERR_DATA_CPL_ON_HIGH_QID1_F | INGRESS_SIZE_ERR_F |
5088f612b815SHariprasad Shenai 		     ERR_DATA_CPL_ON_HIGH_QID0_F | ERR_BAD_DB_PIDX3_F |
5089f612b815SHariprasad Shenai 		     ERR_BAD_DB_PIDX2_F | ERR_BAD_DB_PIDX1_F |
5090f612b815SHariprasad Shenai 		     ERR_BAD_DB_PIDX0_F | ERR_ING_CTXT_PRIO_F |
50913ccc6cf7SHariprasad Shenai 		     DBFIFO_LP_INT_F | EGRESS_SIZE_ERR_F | val);
50920d804338SHariprasad Shenai 	t4_write_reg(adapter, MYPF_REG(PL_PF_INT_ENABLE_A), PF_INTR_MASK);
50930d804338SHariprasad Shenai 	t4_set_reg_field(adapter, PL_INT_MAP0_A, 0, 1 << pf);
5094f7917c00SJeff Kirsher }
5095f7917c00SJeff Kirsher 
5096f7917c00SJeff Kirsher /**
5097f7917c00SJeff Kirsher  *	t4_intr_disable - disable interrupts
5098f7917c00SJeff Kirsher  *	@adapter: the adapter whose interrupts should be disabled
5099f7917c00SJeff Kirsher  *
5100f7917c00SJeff Kirsher  *	Disable interrupts.  We only disable the top-level interrupt
5101f7917c00SJeff Kirsher  *	concentrators.  The caller must be a PCI function managing global
5102f7917c00SJeff Kirsher  *	interrupts.
5103f7917c00SJeff Kirsher  */
t4_intr_disable(struct adapter * adapter)5104f7917c00SJeff Kirsher void t4_intr_disable(struct adapter *adapter)
5105f7917c00SJeff Kirsher {
5106025d0973SGuilherme G. Piccoli 	u32 whoami, pf;
5107025d0973SGuilherme G. Piccoli 
5108025d0973SGuilherme G. Piccoli 	if (pci_channel_offline(adapter->pdev))
5109025d0973SGuilherme G. Piccoli 		return;
5110025d0973SGuilherme G. Piccoli 
5111025d0973SGuilherme G. Piccoli 	whoami = t4_read_reg(adapter, PL_WHOAMI_A);
5112025d0973SGuilherme G. Piccoli 	pf = CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5 ?
5113d86bd29eSHariprasad Shenai 			SOURCEPF_G(whoami) : T6_SOURCEPF_G(whoami);
5114f7917c00SJeff Kirsher 
51150d804338SHariprasad Shenai 	t4_write_reg(adapter, MYPF_REG(PL_PF_INT_ENABLE_A), 0);
51160d804338SHariprasad Shenai 	t4_set_reg_field(adapter, PL_INT_MAP0_A, 1 << pf, 0);
5117f7917c00SJeff Kirsher }
5118f7917c00SJeff Kirsher 
t4_chip_rss_size(struct adapter * adap)5119f988008aSGanesh Goudar unsigned int t4_chip_rss_size(struct adapter *adap)
5120f988008aSGanesh Goudar {
5121f988008aSGanesh Goudar 	if (CHELSIO_CHIP_VERSION(adap->params.chip) <= CHELSIO_T5)
5122f988008aSGanesh Goudar 		return RSS_NENTRIES;
5123f988008aSGanesh Goudar 	else
5124f988008aSGanesh Goudar 		return T6_RSS_NENTRIES;
5125f988008aSGanesh Goudar }
5126f988008aSGanesh Goudar 
5127f7917c00SJeff Kirsher /**
5128f7917c00SJeff Kirsher  *	t4_config_rss_range - configure a portion of the RSS mapping table
5129f7917c00SJeff Kirsher  *	@adapter: the adapter
5130f7917c00SJeff Kirsher  *	@mbox: mbox to use for the FW command
5131f7917c00SJeff Kirsher  *	@viid: virtual interface whose RSS subtable is to be written
5132f7917c00SJeff Kirsher  *	@start: start entry in the table to write
5133f7917c00SJeff Kirsher  *	@n: how many table entries to write
5134f7917c00SJeff Kirsher  *	@rspq: values for the response queue lookup table
5135f7917c00SJeff Kirsher  *	@nrspq: number of values in @rspq
5136f7917c00SJeff Kirsher  *
5137f7917c00SJeff Kirsher  *	Programs the selected part of the VI's RSS mapping table with the
5138f7917c00SJeff Kirsher  *	provided values.  If @nrspq < @n the supplied values are used repeatedly
5139f7917c00SJeff Kirsher  *	until the full table range is populated.
5140f7917c00SJeff Kirsher  *
5141f7917c00SJeff Kirsher  *	The caller must ensure the values in @rspq are in the range allowed for
5142f7917c00SJeff Kirsher  *	@viid.
5143f7917c00SJeff Kirsher  */
t4_config_rss_range(struct adapter * adapter,int mbox,unsigned int viid,int start,int n,const u16 * rspq,unsigned int nrspq)5144f7917c00SJeff Kirsher int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid,
5145f7917c00SJeff Kirsher 			int start, int n, const u16 *rspq, unsigned int nrspq)
5146f7917c00SJeff Kirsher {
5147f7917c00SJeff Kirsher 	int ret;
5148f7917c00SJeff Kirsher 	const u16 *rsp = rspq;
5149f7917c00SJeff Kirsher 	const u16 *rsp_end = rspq + nrspq;
5150f7917c00SJeff Kirsher 	struct fw_rss_ind_tbl_cmd cmd;
5151f7917c00SJeff Kirsher 
5152f7917c00SJeff Kirsher 	memset(&cmd, 0, sizeof(cmd));
5153f404f80cSHariprasad Shenai 	cmd.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_RSS_IND_TBL_CMD) |
5154e2ac9628SHariprasad Shenai 			       FW_CMD_REQUEST_F | FW_CMD_WRITE_F |
5155b2e1a3f0SHariprasad Shenai 			       FW_RSS_IND_TBL_CMD_VIID_V(viid));
5156f404f80cSHariprasad Shenai 	cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
5157f7917c00SJeff Kirsher 
5158f7917c00SJeff Kirsher 	/* each fw_rss_ind_tbl_cmd takes up to 32 entries */
5159f7917c00SJeff Kirsher 	while (n > 0) {
5160f7917c00SJeff Kirsher 		int nq = min(n, 32);
5161f7917c00SJeff Kirsher 		__be32 *qp = &cmd.iq0_to_iq2;
5162f7917c00SJeff Kirsher 
5163f404f80cSHariprasad Shenai 		cmd.niqid = cpu_to_be16(nq);
5164f404f80cSHariprasad Shenai 		cmd.startidx = cpu_to_be16(start);
5165f7917c00SJeff Kirsher 
5166f7917c00SJeff Kirsher 		start += nq;
5167f7917c00SJeff Kirsher 		n -= nq;
5168f7917c00SJeff Kirsher 
5169f7917c00SJeff Kirsher 		while (nq > 0) {
5170f7917c00SJeff Kirsher 			unsigned int v;
5171f7917c00SJeff Kirsher 
5172b2e1a3f0SHariprasad Shenai 			v = FW_RSS_IND_TBL_CMD_IQ0_V(*rsp);
5173f7917c00SJeff Kirsher 			if (++rsp >= rsp_end)
5174f7917c00SJeff Kirsher 				rsp = rspq;
5175b2e1a3f0SHariprasad Shenai 			v |= FW_RSS_IND_TBL_CMD_IQ1_V(*rsp);
5176f7917c00SJeff Kirsher 			if (++rsp >= rsp_end)
5177f7917c00SJeff Kirsher 				rsp = rspq;
5178b2e1a3f0SHariprasad Shenai 			v |= FW_RSS_IND_TBL_CMD_IQ2_V(*rsp);
5179f7917c00SJeff Kirsher 			if (++rsp >= rsp_end)
5180f7917c00SJeff Kirsher 				rsp = rspq;
5181f7917c00SJeff Kirsher 
5182f404f80cSHariprasad Shenai 			*qp++ = cpu_to_be32(v);
5183f7917c00SJeff Kirsher 			nq -= 3;
5184f7917c00SJeff Kirsher 		}
5185f7917c00SJeff Kirsher 
5186f7917c00SJeff Kirsher 		ret = t4_wr_mbox(adapter, mbox, &cmd, sizeof(cmd), NULL);
5187f7917c00SJeff Kirsher 		if (ret)
5188f7917c00SJeff Kirsher 			return ret;
5189f7917c00SJeff Kirsher 	}
5190f7917c00SJeff Kirsher 	return 0;
5191f7917c00SJeff Kirsher }
5192f7917c00SJeff Kirsher 
5193f7917c00SJeff Kirsher /**
5194f7917c00SJeff Kirsher  *	t4_config_glbl_rss - configure the global RSS mode
5195f7917c00SJeff Kirsher  *	@adapter: the adapter
5196f7917c00SJeff Kirsher  *	@mbox: mbox to use for the FW command
5197f7917c00SJeff Kirsher  *	@mode: global RSS mode
5198f7917c00SJeff Kirsher  *	@flags: mode-specific flags
5199f7917c00SJeff Kirsher  *
5200f7917c00SJeff Kirsher  *	Sets the global RSS mode.
5201f7917c00SJeff Kirsher  */
t4_config_glbl_rss(struct adapter * adapter,int mbox,unsigned int mode,unsigned int flags)5202f7917c00SJeff Kirsher int t4_config_glbl_rss(struct adapter *adapter, int mbox, unsigned int mode,
5203f7917c00SJeff Kirsher 		       unsigned int flags)
5204f7917c00SJeff Kirsher {
5205f7917c00SJeff Kirsher 	struct fw_rss_glb_config_cmd c;
5206f7917c00SJeff Kirsher 
5207f7917c00SJeff Kirsher 	memset(&c, 0, sizeof(c));
5208f404f80cSHariprasad Shenai 	c.op_to_write = cpu_to_be32(FW_CMD_OP_V(FW_RSS_GLB_CONFIG_CMD) |
5209e2ac9628SHariprasad Shenai 				    FW_CMD_REQUEST_F | FW_CMD_WRITE_F);
5210f404f80cSHariprasad Shenai 	c.retval_len16 = cpu_to_be32(FW_LEN16(c));
5211f7917c00SJeff Kirsher 	if (mode == FW_RSS_GLB_CONFIG_CMD_MODE_MANUAL) {
5212f404f80cSHariprasad Shenai 		c.u.manual.mode_pkd =
5213f404f80cSHariprasad Shenai 			cpu_to_be32(FW_RSS_GLB_CONFIG_CMD_MODE_V(mode));
5214f7917c00SJeff Kirsher 	} else if (mode == FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL) {
5215f7917c00SJeff Kirsher 		c.u.basicvirtual.mode_pkd =
5216f404f80cSHariprasad Shenai 			cpu_to_be32(FW_RSS_GLB_CONFIG_CMD_MODE_V(mode));
5217f404f80cSHariprasad Shenai 		c.u.basicvirtual.synmapen_to_hashtoeplitz = cpu_to_be32(flags);
5218f7917c00SJeff Kirsher 	} else
5219f7917c00SJeff Kirsher 		return -EINVAL;
5220f7917c00SJeff Kirsher 	return t4_wr_mbox(adapter, mbox, &c, sizeof(c), NULL);
5221f7917c00SJeff Kirsher }
5222f7917c00SJeff Kirsher 
5223c035e183SHariprasad Shenai /**
5224c035e183SHariprasad Shenai  *	t4_config_vi_rss - configure per VI RSS settings
5225c035e183SHariprasad Shenai  *	@adapter: the adapter
5226c035e183SHariprasad Shenai  *	@mbox: mbox to use for the FW command
5227c035e183SHariprasad Shenai  *	@viid: the VI id
5228c035e183SHariprasad Shenai  *	@flags: RSS flags
5229c035e183SHariprasad Shenai  *	@defq: id of the default RSS queue for the VI.
5230c035e183SHariprasad Shenai  *
5231c035e183SHariprasad Shenai  *	Configures VI-specific RSS properties.
5232c035e183SHariprasad Shenai  */
t4_config_vi_rss(struct adapter * adapter,int mbox,unsigned int viid,unsigned int flags,unsigned int defq)5233c035e183SHariprasad Shenai int t4_config_vi_rss(struct adapter *adapter, int mbox, unsigned int viid,
5234c035e183SHariprasad Shenai 		     unsigned int flags, unsigned int defq)
5235c035e183SHariprasad Shenai {
5236c035e183SHariprasad Shenai 	struct fw_rss_vi_config_cmd c;
5237c035e183SHariprasad Shenai 
5238c035e183SHariprasad Shenai 	memset(&c, 0, sizeof(c));
5239c035e183SHariprasad Shenai 	c.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_RSS_VI_CONFIG_CMD) |
5240c035e183SHariprasad Shenai 				   FW_CMD_REQUEST_F | FW_CMD_WRITE_F |
5241c035e183SHariprasad Shenai 				   FW_RSS_VI_CONFIG_CMD_VIID_V(viid));
5242c035e183SHariprasad Shenai 	c.retval_len16 = cpu_to_be32(FW_LEN16(c));
5243c035e183SHariprasad Shenai 	c.u.basicvirtual.defaultq_to_udpen = cpu_to_be32(flags |
5244c035e183SHariprasad Shenai 					FW_RSS_VI_CONFIG_CMD_DEFAULTQ_V(defq));
5245c035e183SHariprasad Shenai 	return t4_wr_mbox(adapter, mbox, &c, sizeof(c), NULL);
5246c035e183SHariprasad Shenai }
5247c035e183SHariprasad Shenai 
5248688ea5feSHariprasad Shenai /* Read an RSS table row */
rd_rss_row(struct adapter * adap,int row,u32 * val)5249688ea5feSHariprasad Shenai static int rd_rss_row(struct adapter *adap, int row, u32 *val)
5250688ea5feSHariprasad Shenai {
5251688ea5feSHariprasad Shenai 	t4_write_reg(adap, TP_RSS_LKP_TABLE_A, 0xfff00000 | row);
5252688ea5feSHariprasad Shenai 	return t4_wait_op_done_val(adap, TP_RSS_LKP_TABLE_A, LKPTBLROWVLD_F, 1,
5253688ea5feSHariprasad Shenai 				   5, 0, val);
5254688ea5feSHariprasad Shenai }
5255688ea5feSHariprasad Shenai 
5256688ea5feSHariprasad Shenai /**
5257688ea5feSHariprasad Shenai  *	t4_read_rss - read the contents of the RSS mapping table
5258688ea5feSHariprasad Shenai  *	@adapter: the adapter
5259688ea5feSHariprasad Shenai  *	@map: holds the contents of the RSS mapping table
5260688ea5feSHariprasad Shenai  *
5261688ea5feSHariprasad Shenai  *	Reads the contents of the RSS hash->queue mapping table.
5262688ea5feSHariprasad Shenai  */
t4_read_rss(struct adapter * adapter,u16 * map)5263688ea5feSHariprasad Shenai int t4_read_rss(struct adapter *adapter, u16 *map)
5264688ea5feSHariprasad Shenai {
5265f988008aSGanesh Goudar 	int i, ret, nentries;
5266688ea5feSHariprasad Shenai 	u32 val;
5267688ea5feSHariprasad Shenai 
5268f988008aSGanesh Goudar 	nentries = t4_chip_rss_size(adapter);
5269f988008aSGanesh Goudar 	for (i = 0; i < nentries / 2; ++i) {
5270688ea5feSHariprasad Shenai 		ret = rd_rss_row(adapter, i, &val);
5271688ea5feSHariprasad Shenai 		if (ret)
5272688ea5feSHariprasad Shenai 			return ret;
5273688ea5feSHariprasad Shenai 		*map++ = LKPTBLQUEUE0_G(val);
5274688ea5feSHariprasad Shenai 		*map++ = LKPTBLQUEUE1_G(val);
5275688ea5feSHariprasad Shenai 	}
5276688ea5feSHariprasad Shenai 	return 0;
5277688ea5feSHariprasad Shenai }
5278688ea5feSHariprasad Shenai 
t4_use_ldst(struct adapter * adap)52790b2c2a93SHariprasad Shenai static unsigned int t4_use_ldst(struct adapter *adap)
52800b2c2a93SHariprasad Shenai {
528180f61f19SArjun Vynipadath 	return (adap->flags & CXGB4_FW_OK) && !adap->use_bd;
52820b2c2a93SHariprasad Shenai }
52830b2c2a93SHariprasad Shenai 
5284688ea5feSHariprasad Shenai /**
52855ccf9d04SRahul Lakkireddy  * t4_tp_fw_ldst_rw - Access TP indirect register through LDST
5286c1e9af0cSHariprasad Shenai  * @adap: the adapter
52875ccf9d04SRahul Lakkireddy  * @cmd: TP fw ldst address space type
5288c1e9af0cSHariprasad Shenai  * @vals: where the indirect register values are stored/written
5289c1e9af0cSHariprasad Shenai  * @nregs: how many indirect registers to read/write
529029bbf5d7SRahul Lakkireddy  * @start_index: index of first indirect register to read/write
5291c1e9af0cSHariprasad Shenai  * @rw: Read (1) or Write (0)
52925ccf9d04SRahul Lakkireddy  * @sleep_ok: if true we may sleep while awaiting command completion
5293c1e9af0cSHariprasad Shenai  *
52945ccf9d04SRahul Lakkireddy  * Access TP indirect registers through LDST
5295c1e9af0cSHariprasad Shenai  */
t4_tp_fw_ldst_rw(struct adapter * adap,int cmd,u32 * vals,unsigned int nregs,unsigned int start_index,unsigned int rw,bool sleep_ok)52965ccf9d04SRahul Lakkireddy static int t4_tp_fw_ldst_rw(struct adapter *adap, int cmd, u32 *vals,
52975ccf9d04SRahul Lakkireddy 			    unsigned int nregs, unsigned int start_index,
52985ccf9d04SRahul Lakkireddy 			    unsigned int rw, bool sleep_ok)
5299c1e9af0cSHariprasad Shenai {
53005ccf9d04SRahul Lakkireddy 	int ret = 0;
53015ccf9d04SRahul Lakkireddy 	unsigned int i;
5302c1e9af0cSHariprasad Shenai 	struct fw_ldst_cmd c;
5303c1e9af0cSHariprasad Shenai 
5304c1e9af0cSHariprasad Shenai 	for (i = 0; i < nregs; i++) {
5305c1e9af0cSHariprasad Shenai 		memset(&c, 0, sizeof(c));
5306c1e9af0cSHariprasad Shenai 		c.op_to_addrspace = cpu_to_be32(FW_CMD_OP_V(FW_LDST_CMD) |
5307c1e9af0cSHariprasad Shenai 						FW_CMD_REQUEST_F |
5308c1e9af0cSHariprasad Shenai 						(rw ? FW_CMD_READ_F :
5309c1e9af0cSHariprasad Shenai 						      FW_CMD_WRITE_F) |
5310c1e9af0cSHariprasad Shenai 						FW_LDST_CMD_ADDRSPACE_V(cmd));
5311c1e9af0cSHariprasad Shenai 		c.cycles_to_len16 = cpu_to_be32(FW_LEN16(c));
5312c1e9af0cSHariprasad Shenai 
5313c1e9af0cSHariprasad Shenai 		c.u.addrval.addr = cpu_to_be32(start_index + i);
5314c1e9af0cSHariprasad Shenai 		c.u.addrval.val  = rw ? 0 : cpu_to_be32(vals[i]);
53155ccf9d04SRahul Lakkireddy 		ret = t4_wr_mbox_meat(adap, adap->mbox, &c, sizeof(c), &c,
53165ccf9d04SRahul Lakkireddy 				      sleep_ok);
53175ccf9d04SRahul Lakkireddy 		if (ret)
53185ccf9d04SRahul Lakkireddy 			return ret;
53195ccf9d04SRahul Lakkireddy 
53205ccf9d04SRahul Lakkireddy 		if (rw)
5321c1e9af0cSHariprasad Shenai 			vals[i] = be32_to_cpu(c.u.addrval.val);
5322c1e9af0cSHariprasad Shenai 	}
53235ccf9d04SRahul Lakkireddy 	return 0;
53245ccf9d04SRahul Lakkireddy }
53255ccf9d04SRahul Lakkireddy 
53265ccf9d04SRahul Lakkireddy /**
53275ccf9d04SRahul Lakkireddy  * t4_tp_indirect_rw - Read/Write TP indirect register through LDST or backdoor
53285ccf9d04SRahul Lakkireddy  * @adap: the adapter
53295ccf9d04SRahul Lakkireddy  * @reg_addr: Address Register
53305ccf9d04SRahul Lakkireddy  * @reg_data: Data register
53315ccf9d04SRahul Lakkireddy  * @buff: where the indirect register values are stored/written
53325ccf9d04SRahul Lakkireddy  * @nregs: how many indirect registers to read/write
53335ccf9d04SRahul Lakkireddy  * @start_index: index of first indirect register to read/write
53345ccf9d04SRahul Lakkireddy  * @rw: READ(1) or WRITE(0)
53355ccf9d04SRahul Lakkireddy  * @sleep_ok: if true we may sleep while awaiting command completion
53365ccf9d04SRahul Lakkireddy  *
53375ccf9d04SRahul Lakkireddy  * Read/Write TP indirect registers through LDST if possible.
53385ccf9d04SRahul Lakkireddy  * Else, use backdoor access
53395ccf9d04SRahul Lakkireddy  **/
t4_tp_indirect_rw(struct adapter * adap,u32 reg_addr,u32 reg_data,u32 * buff,u32 nregs,u32 start_index,int rw,bool sleep_ok)53405ccf9d04SRahul Lakkireddy static void t4_tp_indirect_rw(struct adapter *adap, u32 reg_addr, u32 reg_data,
53415ccf9d04SRahul Lakkireddy 			      u32 *buff, u32 nregs, u32 start_index, int rw,
53425ccf9d04SRahul Lakkireddy 			      bool sleep_ok)
53435ccf9d04SRahul Lakkireddy {
53445ccf9d04SRahul Lakkireddy 	int rc = -EINVAL;
53455ccf9d04SRahul Lakkireddy 	int cmd;
53465ccf9d04SRahul Lakkireddy 
53475ccf9d04SRahul Lakkireddy 	switch (reg_addr) {
53485ccf9d04SRahul Lakkireddy 	case TP_PIO_ADDR_A:
53495ccf9d04SRahul Lakkireddy 		cmd = FW_LDST_ADDRSPC_TP_PIO;
53505ccf9d04SRahul Lakkireddy 		break;
53514359cf33SRahul Lakkireddy 	case TP_TM_PIO_ADDR_A:
53524359cf33SRahul Lakkireddy 		cmd = FW_LDST_ADDRSPC_TP_TM_PIO;
53534359cf33SRahul Lakkireddy 		break;
53545ccf9d04SRahul Lakkireddy 	case TP_MIB_INDEX_A:
53555ccf9d04SRahul Lakkireddy 		cmd = FW_LDST_ADDRSPC_TP_MIB;
53565ccf9d04SRahul Lakkireddy 		break;
53575ccf9d04SRahul Lakkireddy 	default:
53585ccf9d04SRahul Lakkireddy 		goto indirect_access;
53595ccf9d04SRahul Lakkireddy 	}
53605ccf9d04SRahul Lakkireddy 
53615ccf9d04SRahul Lakkireddy 	if (t4_use_ldst(adap))
53625ccf9d04SRahul Lakkireddy 		rc = t4_tp_fw_ldst_rw(adap, cmd, buff, nregs, start_index, rw,
53635ccf9d04SRahul Lakkireddy 				      sleep_ok);
53645ccf9d04SRahul Lakkireddy 
53655ccf9d04SRahul Lakkireddy indirect_access:
53665ccf9d04SRahul Lakkireddy 
53675ccf9d04SRahul Lakkireddy 	if (rc) {
53685ccf9d04SRahul Lakkireddy 		if (rw)
53695ccf9d04SRahul Lakkireddy 			t4_read_indirect(adap, reg_addr, reg_data, buff, nregs,
53705ccf9d04SRahul Lakkireddy 					 start_index);
53715ccf9d04SRahul Lakkireddy 		else
53725ccf9d04SRahul Lakkireddy 			t4_write_indirect(adap, reg_addr, reg_data, buff, nregs,
53735ccf9d04SRahul Lakkireddy 					  start_index);
53745ccf9d04SRahul Lakkireddy 	}
53755ccf9d04SRahul Lakkireddy }
53765ccf9d04SRahul Lakkireddy 
53775ccf9d04SRahul Lakkireddy /**
53785ccf9d04SRahul Lakkireddy  * t4_tp_pio_read - Read TP PIO registers
53795ccf9d04SRahul Lakkireddy  * @adap: the adapter
53805ccf9d04SRahul Lakkireddy  * @buff: where the indirect register values are written
53815ccf9d04SRahul Lakkireddy  * @nregs: how many indirect registers to read
53825ccf9d04SRahul Lakkireddy  * @start_index: index of first indirect register to read
53835ccf9d04SRahul Lakkireddy  * @sleep_ok: if true we may sleep while awaiting command completion
53845ccf9d04SRahul Lakkireddy  *
53855ccf9d04SRahul Lakkireddy  * Read TP PIO Registers
53865ccf9d04SRahul Lakkireddy  **/
t4_tp_pio_read(struct adapter * adap,u32 * buff,u32 nregs,u32 start_index,bool sleep_ok)53875ccf9d04SRahul Lakkireddy void t4_tp_pio_read(struct adapter *adap, u32 *buff, u32 nregs,
53885ccf9d04SRahul Lakkireddy 		    u32 start_index, bool sleep_ok)
53895ccf9d04SRahul Lakkireddy {
53905ccf9d04SRahul Lakkireddy 	t4_tp_indirect_rw(adap, TP_PIO_ADDR_A, TP_PIO_DATA_A, buff, nregs,
53915ccf9d04SRahul Lakkireddy 			  start_index, 1, sleep_ok);
53925ccf9d04SRahul Lakkireddy }
53935ccf9d04SRahul Lakkireddy 
53945ccf9d04SRahul Lakkireddy /**
53955ccf9d04SRahul Lakkireddy  * t4_tp_pio_write - Write TP PIO registers
53965ccf9d04SRahul Lakkireddy  * @adap: the adapter
53975ccf9d04SRahul Lakkireddy  * @buff: where the indirect register values are stored
53985ccf9d04SRahul Lakkireddy  * @nregs: how many indirect registers to write
53995ccf9d04SRahul Lakkireddy  * @start_index: index of first indirect register to write
54005ccf9d04SRahul Lakkireddy  * @sleep_ok: if true we may sleep while awaiting command completion
54015ccf9d04SRahul Lakkireddy  *
54025ccf9d04SRahul Lakkireddy  * Write TP PIO Registers
54035ccf9d04SRahul Lakkireddy  **/
t4_tp_pio_write(struct adapter * adap,u32 * buff,u32 nregs,u32 start_index,bool sleep_ok)54045ccf9d04SRahul Lakkireddy static void t4_tp_pio_write(struct adapter *adap, u32 *buff, u32 nregs,
54055ccf9d04SRahul Lakkireddy 			    u32 start_index, bool sleep_ok)
54065ccf9d04SRahul Lakkireddy {
54075ccf9d04SRahul Lakkireddy 	t4_tp_indirect_rw(adap, TP_PIO_ADDR_A, TP_PIO_DATA_A, buff, nregs,
54085ccf9d04SRahul Lakkireddy 			  start_index, 0, sleep_ok);
54095ccf9d04SRahul Lakkireddy }
54105ccf9d04SRahul Lakkireddy 
54115ccf9d04SRahul Lakkireddy /**
54124359cf33SRahul Lakkireddy  * t4_tp_tm_pio_read - Read TP TM PIO registers
54134359cf33SRahul Lakkireddy  * @adap: the adapter
54144359cf33SRahul Lakkireddy  * @buff: where the indirect register values are written
54154359cf33SRahul Lakkireddy  * @nregs: how many indirect registers to read
54164359cf33SRahul Lakkireddy  * @start_index: index of first indirect register to read
54174359cf33SRahul Lakkireddy  * @sleep_ok: if true we may sleep while awaiting command completion
54184359cf33SRahul Lakkireddy  *
54194359cf33SRahul Lakkireddy  * Read TP TM PIO Registers
54204359cf33SRahul Lakkireddy  **/
t4_tp_tm_pio_read(struct adapter * adap,u32 * buff,u32 nregs,u32 start_index,bool sleep_ok)54214359cf33SRahul Lakkireddy void t4_tp_tm_pio_read(struct adapter *adap, u32 *buff, u32 nregs,
54224359cf33SRahul Lakkireddy 		       u32 start_index, bool sleep_ok)
54234359cf33SRahul Lakkireddy {
54244359cf33SRahul Lakkireddy 	t4_tp_indirect_rw(adap, TP_TM_PIO_ADDR_A, TP_TM_PIO_DATA_A, buff,
54254359cf33SRahul Lakkireddy 			  nregs, start_index, 1, sleep_ok);
54264359cf33SRahul Lakkireddy }
54274359cf33SRahul Lakkireddy 
54284359cf33SRahul Lakkireddy /**
54295ccf9d04SRahul Lakkireddy  * t4_tp_mib_read - Read TP MIB registers
54305ccf9d04SRahul Lakkireddy  * @adap: the adapter
54315ccf9d04SRahul Lakkireddy  * @buff: where the indirect register values are written
54325ccf9d04SRahul Lakkireddy  * @nregs: how many indirect registers to read
54335ccf9d04SRahul Lakkireddy  * @start_index: index of first indirect register to read
54345ccf9d04SRahul Lakkireddy  * @sleep_ok: if true we may sleep while awaiting command completion
54355ccf9d04SRahul Lakkireddy  *
54365ccf9d04SRahul Lakkireddy  * Read TP MIB Registers
54375ccf9d04SRahul Lakkireddy  **/
t4_tp_mib_read(struct adapter * adap,u32 * buff,u32 nregs,u32 start_index,bool sleep_ok)54385ccf9d04SRahul Lakkireddy void t4_tp_mib_read(struct adapter *adap, u32 *buff, u32 nregs, u32 start_index,
54395ccf9d04SRahul Lakkireddy 		    bool sleep_ok)
54405ccf9d04SRahul Lakkireddy {
54415ccf9d04SRahul Lakkireddy 	t4_tp_indirect_rw(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A, buff, nregs,
54425ccf9d04SRahul Lakkireddy 			  start_index, 1, sleep_ok);
5443c1e9af0cSHariprasad Shenai }
5444c1e9af0cSHariprasad Shenai 
5445c1e9af0cSHariprasad Shenai /**
5446688ea5feSHariprasad Shenai  *	t4_read_rss_key - read the global RSS key
5447688ea5feSHariprasad Shenai  *	@adap: the adapter
5448688ea5feSHariprasad Shenai  *	@key: 10-entry array holding the 320-bit RSS key
54495ccf9d04SRahul Lakkireddy  *      @sleep_ok: if true we may sleep while awaiting command completion
5450688ea5feSHariprasad Shenai  *
5451688ea5feSHariprasad Shenai  *	Reads the global 320-bit RSS key.
5452688ea5feSHariprasad Shenai  */
t4_read_rss_key(struct adapter * adap,u32 * key,bool sleep_ok)54535ccf9d04SRahul Lakkireddy void t4_read_rss_key(struct adapter *adap, u32 *key, bool sleep_ok)
5454688ea5feSHariprasad Shenai {
54555ccf9d04SRahul Lakkireddy 	t4_tp_pio_read(adap, key, 10, TP_RSS_SECRET_KEY0_A, sleep_ok);
5456688ea5feSHariprasad Shenai }
5457688ea5feSHariprasad Shenai 
5458688ea5feSHariprasad Shenai /**
5459688ea5feSHariprasad Shenai  *	t4_write_rss_key - program one of the RSS keys
5460688ea5feSHariprasad Shenai  *	@adap: the adapter
5461688ea5feSHariprasad Shenai  *	@key: 10-entry array holding the 320-bit RSS key
5462688ea5feSHariprasad Shenai  *	@idx: which RSS key to write
54635ccf9d04SRahul Lakkireddy  *      @sleep_ok: if true we may sleep while awaiting command completion
5464688ea5feSHariprasad Shenai  *
5465688ea5feSHariprasad Shenai  *	Writes one of the RSS keys with the given 320-bit value.  If @idx is
5466688ea5feSHariprasad Shenai  *	0..15 the corresponding entry in the RSS key table is written,
5467688ea5feSHariprasad Shenai  *	otherwise the global RSS key is written.
5468688ea5feSHariprasad Shenai  */
t4_write_rss_key(struct adapter * adap,const u32 * key,int idx,bool sleep_ok)54695ccf9d04SRahul Lakkireddy void t4_write_rss_key(struct adapter *adap, const u32 *key, int idx,
54705ccf9d04SRahul Lakkireddy 		      bool sleep_ok)
5471688ea5feSHariprasad Shenai {
54723ccc6cf7SHariprasad Shenai 	u8 rss_key_addr_cnt = 16;
54733ccc6cf7SHariprasad Shenai 	u32 vrt = t4_read_reg(adap, TP_RSS_CONFIG_VRT_A);
54743ccc6cf7SHariprasad Shenai 
54753ccc6cf7SHariprasad Shenai 	/* T6 and later: for KeyMode 3 (per-vf and per-vf scramble),
54763ccc6cf7SHariprasad Shenai 	 * allows access to key addresses 16-63 by using KeyWrAddrX
54773ccc6cf7SHariprasad Shenai 	 * as index[5:4](upper 2) into key table
54783ccc6cf7SHariprasad Shenai 	 */
54793ccc6cf7SHariprasad Shenai 	if ((CHELSIO_CHIP_VERSION(adap->params.chip) > CHELSIO_T5) &&
54803ccc6cf7SHariprasad Shenai 	    (vrt & KEYEXTEND_F) && (KEYMODE_G(vrt) == 3))
54813ccc6cf7SHariprasad Shenai 		rss_key_addr_cnt = 32;
54823ccc6cf7SHariprasad Shenai 
54835ccf9d04SRahul Lakkireddy 	t4_tp_pio_write(adap, (void *)key, 10, TP_RSS_SECRET_KEY0_A, sleep_ok);
54843ccc6cf7SHariprasad Shenai 
54853ccc6cf7SHariprasad Shenai 	if (idx >= 0 && idx < rss_key_addr_cnt) {
54863ccc6cf7SHariprasad Shenai 		if (rss_key_addr_cnt > 16)
54873ccc6cf7SHariprasad Shenai 			t4_write_reg(adap, TP_RSS_CONFIG_VRT_A,
54883ccc6cf7SHariprasad Shenai 				     KEYWRADDRX_V(idx >> 4) |
54893ccc6cf7SHariprasad Shenai 				     T6_VFWRADDR_V(idx) | KEYWREN_F);
54903ccc6cf7SHariprasad Shenai 		else
5491688ea5feSHariprasad Shenai 			t4_write_reg(adap, TP_RSS_CONFIG_VRT_A,
5492688ea5feSHariprasad Shenai 				     KEYWRADDR_V(idx) | KEYWREN_F);
5493688ea5feSHariprasad Shenai 	}
54943ccc6cf7SHariprasad Shenai }
5495688ea5feSHariprasad Shenai 
5496688ea5feSHariprasad Shenai /**
5497688ea5feSHariprasad Shenai  *	t4_read_rss_pf_config - read PF RSS Configuration Table
5498688ea5feSHariprasad Shenai  *	@adapter: the adapter
5499688ea5feSHariprasad Shenai  *	@index: the entry in the PF RSS table to read
5500688ea5feSHariprasad Shenai  *	@valp: where to store the returned value
55015ccf9d04SRahul Lakkireddy  *      @sleep_ok: if true we may sleep while awaiting command completion
5502688ea5feSHariprasad Shenai  *
5503688ea5feSHariprasad Shenai  *	Reads the PF RSS Configuration Table at the specified index and returns
5504688ea5feSHariprasad Shenai  *	the value found there.
5505688ea5feSHariprasad Shenai  */
t4_read_rss_pf_config(struct adapter * adapter,unsigned int index,u32 * valp,bool sleep_ok)5506688ea5feSHariprasad Shenai void t4_read_rss_pf_config(struct adapter *adapter, unsigned int index,
55075ccf9d04SRahul Lakkireddy 			   u32 *valp, bool sleep_ok)
5508688ea5feSHariprasad Shenai {
55095ccf9d04SRahul Lakkireddy 	t4_tp_pio_read(adapter, valp, 1, TP_RSS_PF0_CONFIG_A + index, sleep_ok);
5510688ea5feSHariprasad Shenai }
5511688ea5feSHariprasad Shenai 
5512688ea5feSHariprasad Shenai /**
5513688ea5feSHariprasad Shenai  *	t4_read_rss_vf_config - read VF RSS Configuration Table
5514688ea5feSHariprasad Shenai  *	@adapter: the adapter
5515688ea5feSHariprasad Shenai  *	@index: the entry in the VF RSS table to read
5516688ea5feSHariprasad Shenai  *	@vfl: where to store the returned VFL
5517688ea5feSHariprasad Shenai  *	@vfh: where to store the returned VFH
55185ccf9d04SRahul Lakkireddy  *      @sleep_ok: if true we may sleep while awaiting command completion
5519688ea5feSHariprasad Shenai  *
5520688ea5feSHariprasad Shenai  *	Reads the VF RSS Configuration Table at the specified index and returns
5521688ea5feSHariprasad Shenai  *	the (VFL, VFH) values found there.
5522688ea5feSHariprasad Shenai  */
t4_read_rss_vf_config(struct adapter * adapter,unsigned int index,u32 * vfl,u32 * vfh,bool sleep_ok)5523688ea5feSHariprasad Shenai void t4_read_rss_vf_config(struct adapter *adapter, unsigned int index,
55245ccf9d04SRahul Lakkireddy 			   u32 *vfl, u32 *vfh, bool sleep_ok)
5525688ea5feSHariprasad Shenai {
5526688ea5feSHariprasad Shenai 	u32 vrt, mask, data;
5527688ea5feSHariprasad Shenai 
55283ccc6cf7SHariprasad Shenai 	if (CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5) {
5529688ea5feSHariprasad Shenai 		mask = VFWRADDR_V(VFWRADDR_M);
5530688ea5feSHariprasad Shenai 		data = VFWRADDR_V(index);
55313ccc6cf7SHariprasad Shenai 	} else {
55323ccc6cf7SHariprasad Shenai 		 mask =  T6_VFWRADDR_V(T6_VFWRADDR_M);
55333ccc6cf7SHariprasad Shenai 		 data = T6_VFWRADDR_V(index);
55343ccc6cf7SHariprasad Shenai 	}
5535688ea5feSHariprasad Shenai 
5536688ea5feSHariprasad Shenai 	/* Request that the index'th VF Table values be read into VFL/VFH.
5537688ea5feSHariprasad Shenai 	 */
5538688ea5feSHariprasad Shenai 	vrt = t4_read_reg(adapter, TP_RSS_CONFIG_VRT_A);
5539688ea5feSHariprasad Shenai 	vrt &= ~(VFRDRG_F | VFWREN_F | KEYWREN_F | mask);
5540688ea5feSHariprasad Shenai 	vrt |= data | VFRDEN_F;
5541688ea5feSHariprasad Shenai 	t4_write_reg(adapter, TP_RSS_CONFIG_VRT_A, vrt);
5542688ea5feSHariprasad Shenai 
5543688ea5feSHariprasad Shenai 	/* Grab the VFL/VFH values ...
5544688ea5feSHariprasad Shenai 	 */
55455ccf9d04SRahul Lakkireddy 	t4_tp_pio_read(adapter, vfl, 1, TP_RSS_VFL_CONFIG_A, sleep_ok);
55465ccf9d04SRahul Lakkireddy 	t4_tp_pio_read(adapter, vfh, 1, TP_RSS_VFH_CONFIG_A, sleep_ok);
5547c1e9af0cSHariprasad Shenai }
5548688ea5feSHariprasad Shenai 
5549688ea5feSHariprasad Shenai /**
5550688ea5feSHariprasad Shenai  *	t4_read_rss_pf_map - read PF RSS Map
5551688ea5feSHariprasad Shenai  *	@adapter: the adapter
55525ccf9d04SRahul Lakkireddy  *      @sleep_ok: if true we may sleep while awaiting command completion
5553688ea5feSHariprasad Shenai  *
5554688ea5feSHariprasad Shenai  *	Reads the PF RSS Map register and returns its value.
5555688ea5feSHariprasad Shenai  */
t4_read_rss_pf_map(struct adapter * adapter,bool sleep_ok)55565ccf9d04SRahul Lakkireddy u32 t4_read_rss_pf_map(struct adapter *adapter, bool sleep_ok)
5557688ea5feSHariprasad Shenai {
5558688ea5feSHariprasad Shenai 	u32 pfmap;
5559688ea5feSHariprasad Shenai 
55605ccf9d04SRahul Lakkireddy 	t4_tp_pio_read(adapter, &pfmap, 1, TP_RSS_PF_MAP_A, sleep_ok);
5561688ea5feSHariprasad Shenai 	return pfmap;
5562688ea5feSHariprasad Shenai }
5563688ea5feSHariprasad Shenai 
5564688ea5feSHariprasad Shenai /**
5565688ea5feSHariprasad Shenai  *	t4_read_rss_pf_mask - read PF RSS Mask
5566688ea5feSHariprasad Shenai  *	@adapter: the adapter
55675ccf9d04SRahul Lakkireddy  *      @sleep_ok: if true we may sleep while awaiting command completion
5568688ea5feSHariprasad Shenai  *
5569688ea5feSHariprasad Shenai  *	Reads the PF RSS Mask register and returns its value.
5570688ea5feSHariprasad Shenai  */
t4_read_rss_pf_mask(struct adapter * adapter,bool sleep_ok)55715ccf9d04SRahul Lakkireddy u32 t4_read_rss_pf_mask(struct adapter *adapter, bool sleep_ok)
5572688ea5feSHariprasad Shenai {
5573688ea5feSHariprasad Shenai 	u32 pfmask;
5574688ea5feSHariprasad Shenai 
55755ccf9d04SRahul Lakkireddy 	t4_tp_pio_read(adapter, &pfmask, 1, TP_RSS_PF_MSK_A, sleep_ok);
5576688ea5feSHariprasad Shenai 	return pfmask;
5577688ea5feSHariprasad Shenai }
5578688ea5feSHariprasad Shenai 
5579f7917c00SJeff Kirsher /**
5580f7917c00SJeff Kirsher  *	t4_tp_get_tcp_stats - read TP's TCP MIB counters
5581f7917c00SJeff Kirsher  *	@adap: the adapter
5582f7917c00SJeff Kirsher  *	@v4: holds the TCP/IP counter values
5583f7917c00SJeff Kirsher  *	@v6: holds the TCP/IPv6 counter values
55845ccf9d04SRahul Lakkireddy  *      @sleep_ok: if true we may sleep while awaiting command completion
5585f7917c00SJeff Kirsher  *
5586f7917c00SJeff Kirsher  *	Returns the values of TP's TCP/IP and TCP/IPv6 MIB counters.
5587f7917c00SJeff Kirsher  *	Either @v4 or @v6 may be %NULL to skip the corresponding stats.
5588f7917c00SJeff Kirsher  */
t4_tp_get_tcp_stats(struct adapter * adap,struct tp_tcp_stats * v4,struct tp_tcp_stats * v6,bool sleep_ok)5589f7917c00SJeff Kirsher void t4_tp_get_tcp_stats(struct adapter *adap, struct tp_tcp_stats *v4,
55905ccf9d04SRahul Lakkireddy 			 struct tp_tcp_stats *v6, bool sleep_ok)
5591f7917c00SJeff Kirsher {
5592837e4a42SHariprasad Shenai 	u32 val[TP_MIB_TCP_RXT_SEG_LO_A - TP_MIB_TCP_OUT_RST_A + 1];
5593f7917c00SJeff Kirsher 
5594837e4a42SHariprasad Shenai #define STAT_IDX(x) ((TP_MIB_TCP_##x##_A) - TP_MIB_TCP_OUT_RST_A)
5595f7917c00SJeff Kirsher #define STAT(x)     val[STAT_IDX(x)]
5596f7917c00SJeff Kirsher #define STAT64(x)   (((u64)STAT(x##_HI) << 32) | STAT(x##_LO))
5597f7917c00SJeff Kirsher 
5598f7917c00SJeff Kirsher 	if (v4) {
55995ccf9d04SRahul Lakkireddy 		t4_tp_mib_read(adap, val, ARRAY_SIZE(val),
56005ccf9d04SRahul Lakkireddy 			       TP_MIB_TCP_OUT_RST_A, sleep_ok);
5601a4cfd929SHariprasad Shenai 		v4->tcp_out_rsts = STAT(OUT_RST);
5602a4cfd929SHariprasad Shenai 		v4->tcp_in_segs  = STAT64(IN_SEG);
5603a4cfd929SHariprasad Shenai 		v4->tcp_out_segs = STAT64(OUT_SEG);
5604a4cfd929SHariprasad Shenai 		v4->tcp_retrans_segs = STAT64(RXT_SEG);
5605f7917c00SJeff Kirsher 	}
5606f7917c00SJeff Kirsher 	if (v6) {
56075ccf9d04SRahul Lakkireddy 		t4_tp_mib_read(adap, val, ARRAY_SIZE(val),
56085ccf9d04SRahul Lakkireddy 			       TP_MIB_TCP_V6OUT_RST_A, sleep_ok);
5609a4cfd929SHariprasad Shenai 		v6->tcp_out_rsts = STAT(OUT_RST);
5610a4cfd929SHariprasad Shenai 		v6->tcp_in_segs  = STAT64(IN_SEG);
5611a4cfd929SHariprasad Shenai 		v6->tcp_out_segs = STAT64(OUT_SEG);
5612a4cfd929SHariprasad Shenai 		v6->tcp_retrans_segs = STAT64(RXT_SEG);
5613f7917c00SJeff Kirsher 	}
5614f7917c00SJeff Kirsher #undef STAT64
5615f7917c00SJeff Kirsher #undef STAT
5616f7917c00SJeff Kirsher #undef STAT_IDX
5617f7917c00SJeff Kirsher }
5618f7917c00SJeff Kirsher 
5619f7917c00SJeff Kirsher /**
5620a4cfd929SHariprasad Shenai  *	t4_tp_get_err_stats - read TP's error MIB counters
5621a4cfd929SHariprasad Shenai  *	@adap: the adapter
5622a4cfd929SHariprasad Shenai  *	@st: holds the counter values
56235ccf9d04SRahul Lakkireddy  *      @sleep_ok: if true we may sleep while awaiting command completion
5624a4cfd929SHariprasad Shenai  *
5625a4cfd929SHariprasad Shenai  *	Returns the values of TP's error counters.
5626a4cfd929SHariprasad Shenai  */
t4_tp_get_err_stats(struct adapter * adap,struct tp_err_stats * st,bool sleep_ok)56275ccf9d04SRahul Lakkireddy void t4_tp_get_err_stats(struct adapter *adap, struct tp_err_stats *st,
56285ccf9d04SRahul Lakkireddy 			 bool sleep_ok)
5629a4cfd929SHariprasad Shenai {
5630df459ebcSHariprasad Shenai 	int nchan = adap->params.arch.nchan;
5631df459ebcSHariprasad Shenai 
56325ccf9d04SRahul Lakkireddy 	t4_tp_mib_read(adap, st->mac_in_errs, nchan, TP_MIB_MAC_IN_ERR_0_A,
56335ccf9d04SRahul Lakkireddy 		       sleep_ok);
56345ccf9d04SRahul Lakkireddy 	t4_tp_mib_read(adap, st->hdr_in_errs, nchan, TP_MIB_HDR_IN_ERR_0_A,
56355ccf9d04SRahul Lakkireddy 		       sleep_ok);
56365ccf9d04SRahul Lakkireddy 	t4_tp_mib_read(adap, st->tcp_in_errs, nchan, TP_MIB_TCP_IN_ERR_0_A,
56375ccf9d04SRahul Lakkireddy 		       sleep_ok);
56385ccf9d04SRahul Lakkireddy 	t4_tp_mib_read(adap, st->tnl_cong_drops, nchan,
56395ccf9d04SRahul Lakkireddy 		       TP_MIB_TNL_CNG_DROP_0_A, sleep_ok);
56405ccf9d04SRahul Lakkireddy 	t4_tp_mib_read(adap, st->ofld_chan_drops, nchan,
56415ccf9d04SRahul Lakkireddy 		       TP_MIB_OFD_CHN_DROP_0_A, sleep_ok);
56425ccf9d04SRahul Lakkireddy 	t4_tp_mib_read(adap, st->tnl_tx_drops, nchan, TP_MIB_TNL_DROP_0_A,
56435ccf9d04SRahul Lakkireddy 		       sleep_ok);
56445ccf9d04SRahul Lakkireddy 	t4_tp_mib_read(adap, st->ofld_vlan_drops, nchan,
56455ccf9d04SRahul Lakkireddy 		       TP_MIB_OFD_VLN_DROP_0_A, sleep_ok);
56465ccf9d04SRahul Lakkireddy 	t4_tp_mib_read(adap, st->tcp6_in_errs, nchan,
56475ccf9d04SRahul Lakkireddy 		       TP_MIB_TCP_V6IN_ERR_0_A, sleep_ok);
56485ccf9d04SRahul Lakkireddy 	t4_tp_mib_read(adap, &st->ofld_no_neigh, 2, TP_MIB_OFD_ARP_DROP_A,
56495ccf9d04SRahul Lakkireddy 		       sleep_ok);
5650a4cfd929SHariprasad Shenai }
5651a4cfd929SHariprasad Shenai 
5652a4cfd929SHariprasad Shenai /**
5653a6222975SHariprasad Shenai  *	t4_tp_get_cpl_stats - read TP's CPL MIB counters
5654a6222975SHariprasad Shenai  *	@adap: the adapter
5655a6222975SHariprasad Shenai  *	@st: holds the counter values
56565ccf9d04SRahul Lakkireddy  *      @sleep_ok: if true we may sleep while awaiting command completion
5657a6222975SHariprasad Shenai  *
5658a6222975SHariprasad Shenai  *	Returns the values of TP's CPL counters.
5659a6222975SHariprasad Shenai  */
t4_tp_get_cpl_stats(struct adapter * adap,struct tp_cpl_stats * st,bool sleep_ok)56605ccf9d04SRahul Lakkireddy void t4_tp_get_cpl_stats(struct adapter *adap, struct tp_cpl_stats *st,
56615ccf9d04SRahul Lakkireddy 			 bool sleep_ok)
5662a6222975SHariprasad Shenai {
5663df459ebcSHariprasad Shenai 	int nchan = adap->params.arch.nchan;
5664df459ebcSHariprasad Shenai 
56655ccf9d04SRahul Lakkireddy 	t4_tp_mib_read(adap, st->req, nchan, TP_MIB_CPL_IN_REQ_0_A, sleep_ok);
5666df459ebcSHariprasad Shenai 
56675ccf9d04SRahul Lakkireddy 	t4_tp_mib_read(adap, st->rsp, nchan, TP_MIB_CPL_OUT_RSP_0_A, sleep_ok);
5668a6222975SHariprasad Shenai }
5669a6222975SHariprasad Shenai 
5670a6222975SHariprasad Shenai /**
5671a4cfd929SHariprasad Shenai  *	t4_tp_get_rdma_stats - read TP's RDMA MIB counters
5672a4cfd929SHariprasad Shenai  *	@adap: the adapter
5673a4cfd929SHariprasad Shenai  *	@st: holds the counter values
56745ccf9d04SRahul Lakkireddy  *      @sleep_ok: if true we may sleep while awaiting command completion
5675a4cfd929SHariprasad Shenai  *
5676a4cfd929SHariprasad Shenai  *	Returns the values of TP's RDMA counters.
5677a4cfd929SHariprasad Shenai  */
t4_tp_get_rdma_stats(struct adapter * adap,struct tp_rdma_stats * st,bool sleep_ok)56785ccf9d04SRahul Lakkireddy void t4_tp_get_rdma_stats(struct adapter *adap, struct tp_rdma_stats *st,
56795ccf9d04SRahul Lakkireddy 			  bool sleep_ok)
5680a4cfd929SHariprasad Shenai {
56815ccf9d04SRahul Lakkireddy 	t4_tp_mib_read(adap, &st->rqe_dfr_pkt, 2, TP_MIB_RQE_DFR_PKT_A,
56825ccf9d04SRahul Lakkireddy 		       sleep_ok);
5683a4cfd929SHariprasad Shenai }
5684a4cfd929SHariprasad Shenai 
5685a4cfd929SHariprasad Shenai /**
5686a6222975SHariprasad Shenai  *	t4_get_fcoe_stats - read TP's FCoE MIB counters for a port
5687a6222975SHariprasad Shenai  *	@adap: the adapter
5688a6222975SHariprasad Shenai  *	@idx: the port index
5689a6222975SHariprasad Shenai  *	@st: holds the counter values
56905ccf9d04SRahul Lakkireddy  *      @sleep_ok: if true we may sleep while awaiting command completion
5691a6222975SHariprasad Shenai  *
5692a6222975SHariprasad Shenai  *	Returns the values of TP's FCoE counters for the selected port.
5693a6222975SHariprasad Shenai  */
t4_get_fcoe_stats(struct adapter * adap,unsigned int idx,struct tp_fcoe_stats * st,bool sleep_ok)5694a6222975SHariprasad Shenai void t4_get_fcoe_stats(struct adapter *adap, unsigned int idx,
56955ccf9d04SRahul Lakkireddy 		       struct tp_fcoe_stats *st, bool sleep_ok)
5696a6222975SHariprasad Shenai {
5697a6222975SHariprasad Shenai 	u32 val[2];
5698a6222975SHariprasad Shenai 
56995ccf9d04SRahul Lakkireddy 	t4_tp_mib_read(adap, &st->frames_ddp, 1, TP_MIB_FCOE_DDP_0_A + idx,
57005ccf9d04SRahul Lakkireddy 		       sleep_ok);
57015ccf9d04SRahul Lakkireddy 
57025ccf9d04SRahul Lakkireddy 	t4_tp_mib_read(adap, &st->frames_drop, 1,
57035ccf9d04SRahul Lakkireddy 		       TP_MIB_FCOE_DROP_0_A + idx, sleep_ok);
57045ccf9d04SRahul Lakkireddy 
57055ccf9d04SRahul Lakkireddy 	t4_tp_mib_read(adap, val, 2, TP_MIB_FCOE_BYTE_0_HI_A + 2 * idx,
57065ccf9d04SRahul Lakkireddy 		       sleep_ok);
57075ccf9d04SRahul Lakkireddy 
5708a6222975SHariprasad Shenai 	st->octets_ddp = ((u64)val[0] << 32) | val[1];
5709a6222975SHariprasad Shenai }
5710a6222975SHariprasad Shenai 
5711a6222975SHariprasad Shenai /**
5712a4cfd929SHariprasad Shenai  *	t4_get_usm_stats - read TP's non-TCP DDP MIB counters
5713a4cfd929SHariprasad Shenai  *	@adap: the adapter
5714a4cfd929SHariprasad Shenai  *	@st: holds the counter values
57155ccf9d04SRahul Lakkireddy  *      @sleep_ok: if true we may sleep while awaiting command completion
5716a4cfd929SHariprasad Shenai  *
5717a4cfd929SHariprasad Shenai  *	Returns the values of TP's counters for non-TCP directly-placed packets.
5718a4cfd929SHariprasad Shenai  */
t4_get_usm_stats(struct adapter * adap,struct tp_usm_stats * st,bool sleep_ok)57195ccf9d04SRahul Lakkireddy void t4_get_usm_stats(struct adapter *adap, struct tp_usm_stats *st,
57205ccf9d04SRahul Lakkireddy 		      bool sleep_ok)
5721a4cfd929SHariprasad Shenai {
5722a4cfd929SHariprasad Shenai 	u32 val[4];
5723a4cfd929SHariprasad Shenai 
57245ccf9d04SRahul Lakkireddy 	t4_tp_mib_read(adap, val, 4, TP_MIB_USM_PKTS_A, sleep_ok);
5725a4cfd929SHariprasad Shenai 	st->frames = val[0];
5726a4cfd929SHariprasad Shenai 	st->drops = val[1];
5727a4cfd929SHariprasad Shenai 	st->octets = ((u64)val[2] << 32) | val[3];
5728a4cfd929SHariprasad Shenai }
5729a4cfd929SHariprasad Shenai 
5730a4cfd929SHariprasad Shenai /**
5731f7917c00SJeff Kirsher  *	t4_read_mtu_tbl - returns the values in the HW path MTU table
5732f7917c00SJeff Kirsher  *	@adap: the adapter
5733f7917c00SJeff Kirsher  *	@mtus: where to store the MTU values
5734f7917c00SJeff Kirsher  *	@mtu_log: where to store the MTU base-2 log (may be %NULL)
5735f7917c00SJeff Kirsher  *
5736f7917c00SJeff Kirsher  *	Reads the HW path MTU table.
5737f7917c00SJeff Kirsher  */
t4_read_mtu_tbl(struct adapter * adap,u16 * mtus,u8 * mtu_log)5738f7917c00SJeff Kirsher void t4_read_mtu_tbl(struct adapter *adap, u16 *mtus, u8 *mtu_log)
5739f7917c00SJeff Kirsher {
5740f7917c00SJeff Kirsher 	u32 v;
5741f7917c00SJeff Kirsher 	int i;
5742f7917c00SJeff Kirsher 
5743f7917c00SJeff Kirsher 	for (i = 0; i < NMTUS; ++i) {
5744837e4a42SHariprasad Shenai 		t4_write_reg(adap, TP_MTU_TABLE_A,
5745837e4a42SHariprasad Shenai 			     MTUINDEX_V(0xff) | MTUVALUE_V(i));
5746837e4a42SHariprasad Shenai 		v = t4_read_reg(adap, TP_MTU_TABLE_A);
5747837e4a42SHariprasad Shenai 		mtus[i] = MTUVALUE_G(v);
5748f7917c00SJeff Kirsher 		if (mtu_log)
5749837e4a42SHariprasad Shenai 			mtu_log[i] = MTUWIDTH_G(v);
5750f7917c00SJeff Kirsher 	}
5751f7917c00SJeff Kirsher }
5752f7917c00SJeff Kirsher 
5753f7917c00SJeff Kirsher /**
5754bad43792SHariprasad Shenai  *	t4_read_cong_tbl - reads the congestion control table
5755bad43792SHariprasad Shenai  *	@adap: the adapter
5756bad43792SHariprasad Shenai  *	@incr: where to store the alpha values
5757bad43792SHariprasad Shenai  *
5758bad43792SHariprasad Shenai  *	Reads the additive increments programmed into the HW congestion
5759bad43792SHariprasad Shenai  *	control table.
5760bad43792SHariprasad Shenai  */
t4_read_cong_tbl(struct adapter * adap,u16 incr[NMTUS][NCCTRL_WIN])5761bad43792SHariprasad Shenai void t4_read_cong_tbl(struct adapter *adap, u16 incr[NMTUS][NCCTRL_WIN])
5762bad43792SHariprasad Shenai {
5763bad43792SHariprasad Shenai 	unsigned int mtu, w;
5764bad43792SHariprasad Shenai 
5765bad43792SHariprasad Shenai 	for (mtu = 0; mtu < NMTUS; ++mtu)
5766bad43792SHariprasad Shenai 		for (w = 0; w < NCCTRL_WIN; ++w) {
5767bad43792SHariprasad Shenai 			t4_write_reg(adap, TP_CCTRL_TABLE_A,
5768bad43792SHariprasad Shenai 				     ROWINDEX_V(0xffff) | (mtu << 5) | w);
5769bad43792SHariprasad Shenai 			incr[mtu][w] = (u16)t4_read_reg(adap,
5770bad43792SHariprasad Shenai 						TP_CCTRL_TABLE_A) & 0x1fff;
5771bad43792SHariprasad Shenai 		}
5772bad43792SHariprasad Shenai }
5773bad43792SHariprasad Shenai 
5774bad43792SHariprasad Shenai /**
5775636f9d37SVipul Pandya  *	t4_tp_wr_bits_indirect - set/clear bits in an indirect TP register
5776636f9d37SVipul Pandya  *	@adap: the adapter
5777636f9d37SVipul Pandya  *	@addr: the indirect TP register address
5778636f9d37SVipul Pandya  *	@mask: specifies the field within the register to modify
5779636f9d37SVipul Pandya  *	@val: new value for the field
5780636f9d37SVipul Pandya  *
5781636f9d37SVipul Pandya  *	Sets a field of an indirect TP register to the given value.
5782636f9d37SVipul Pandya  */
t4_tp_wr_bits_indirect(struct adapter * adap,unsigned int addr,unsigned int mask,unsigned int val)5783636f9d37SVipul Pandya void t4_tp_wr_bits_indirect(struct adapter *adap, unsigned int addr,
5784636f9d37SVipul Pandya 			    unsigned int mask, unsigned int val)
5785636f9d37SVipul Pandya {
5786837e4a42SHariprasad Shenai 	t4_write_reg(adap, TP_PIO_ADDR_A, addr);
5787837e4a42SHariprasad Shenai 	val |= t4_read_reg(adap, TP_PIO_DATA_A) & ~mask;
5788837e4a42SHariprasad Shenai 	t4_write_reg(adap, TP_PIO_DATA_A, val);
5789636f9d37SVipul Pandya }
5790636f9d37SVipul Pandya 
5791636f9d37SVipul Pandya /**
5792f7917c00SJeff Kirsher  *	init_cong_ctrl - initialize congestion control parameters
5793f7917c00SJeff Kirsher  *	@a: the alpha values for congestion control
5794f7917c00SJeff Kirsher  *	@b: the beta values for congestion control
5795f7917c00SJeff Kirsher  *
5796f7917c00SJeff Kirsher  *	Initialize the congestion control parameters.
5797f7917c00SJeff Kirsher  */
init_cong_ctrl(unsigned short * a,unsigned short * b)579891744948SBill Pemberton static void init_cong_ctrl(unsigned short *a, unsigned short *b)
5799f7917c00SJeff Kirsher {
5800f7917c00SJeff Kirsher 	a[0] = a[1] = a[2] = a[3] = a[4] = a[5] = a[6] = a[7] = a[8] = 1;
5801f7917c00SJeff Kirsher 	a[9] = 2;
5802f7917c00SJeff Kirsher 	a[10] = 3;
5803f7917c00SJeff Kirsher 	a[11] = 4;
5804f7917c00SJeff Kirsher 	a[12] = 5;
5805f7917c00SJeff Kirsher 	a[13] = 6;
5806f7917c00SJeff Kirsher 	a[14] = 7;
5807f7917c00SJeff Kirsher 	a[15] = 8;
5808f7917c00SJeff Kirsher 	a[16] = 9;
5809f7917c00SJeff Kirsher 	a[17] = 10;
5810f7917c00SJeff Kirsher 	a[18] = 14;
5811f7917c00SJeff Kirsher 	a[19] = 17;
5812f7917c00SJeff Kirsher 	a[20] = 21;
5813f7917c00SJeff Kirsher 	a[21] = 25;
5814f7917c00SJeff Kirsher 	a[22] = 30;
5815f7917c00SJeff Kirsher 	a[23] = 35;
5816f7917c00SJeff Kirsher 	a[24] = 45;
5817f7917c00SJeff Kirsher 	a[25] = 60;
5818f7917c00SJeff Kirsher 	a[26] = 80;
5819f7917c00SJeff Kirsher 	a[27] = 100;
5820f7917c00SJeff Kirsher 	a[28] = 200;
5821f7917c00SJeff Kirsher 	a[29] = 300;
5822f7917c00SJeff Kirsher 	a[30] = 400;
5823f7917c00SJeff Kirsher 	a[31] = 500;
5824f7917c00SJeff Kirsher 
5825f7917c00SJeff Kirsher 	b[0] = b[1] = b[2] = b[3] = b[4] = b[5] = b[6] = b[7] = b[8] = 0;
5826f7917c00SJeff Kirsher 	b[9] = b[10] = 1;
5827f7917c00SJeff Kirsher 	b[11] = b[12] = 2;
5828f7917c00SJeff Kirsher 	b[13] = b[14] = b[15] = b[16] = 3;
5829f7917c00SJeff Kirsher 	b[17] = b[18] = b[19] = b[20] = b[21] = 4;
5830f7917c00SJeff Kirsher 	b[22] = b[23] = b[24] = b[25] = b[26] = b[27] = 5;
5831f7917c00SJeff Kirsher 	b[28] = b[29] = 6;
5832f7917c00SJeff Kirsher 	b[30] = b[31] = 7;
5833f7917c00SJeff Kirsher }
5834f7917c00SJeff Kirsher 
5835f7917c00SJeff Kirsher /* The minimum additive increment value for the congestion control table */
5836f7917c00SJeff Kirsher #define CC_MIN_INCR 2U
5837f7917c00SJeff Kirsher 
5838f7917c00SJeff Kirsher /**
5839f7917c00SJeff Kirsher  *	t4_load_mtus - write the MTU and congestion control HW tables
5840f7917c00SJeff Kirsher  *	@adap: the adapter
5841f7917c00SJeff Kirsher  *	@mtus: the values for the MTU table
5842f7917c00SJeff Kirsher  *	@alpha: the values for the congestion control alpha parameter
5843f7917c00SJeff Kirsher  *	@beta: the values for the congestion control beta parameter
5844f7917c00SJeff Kirsher  *
5845f7917c00SJeff Kirsher  *	Write the HW MTU table with the supplied MTUs and the high-speed
5846f7917c00SJeff Kirsher  *	congestion control table with the supplied alpha, beta, and MTUs.
5847f7917c00SJeff Kirsher  *	We write the two tables together because the additive increments
5848f7917c00SJeff Kirsher  *	depend on the MTUs.
5849f7917c00SJeff Kirsher  */
t4_load_mtus(struct adapter * adap,const unsigned short * mtus,const unsigned short * alpha,const unsigned short * beta)5850f7917c00SJeff Kirsher void t4_load_mtus(struct adapter *adap, const unsigned short *mtus,
5851f7917c00SJeff Kirsher 		  const unsigned short *alpha, const unsigned short *beta)
5852f7917c00SJeff Kirsher {
5853f7917c00SJeff Kirsher 	static const unsigned int avg_pkts[NCCTRL_WIN] = {
5854f7917c00SJeff Kirsher 		2, 6, 10, 14, 20, 28, 40, 56, 80, 112, 160, 224, 320, 448, 640,
5855f7917c00SJeff Kirsher 		896, 1281, 1792, 2560, 3584, 5120, 7168, 10240, 14336, 20480,
5856f7917c00SJeff Kirsher 		28672, 40960, 57344, 81920, 114688, 163840, 229376
5857f7917c00SJeff Kirsher 	};
5858f7917c00SJeff Kirsher 
5859f7917c00SJeff Kirsher 	unsigned int i, w;
5860f7917c00SJeff Kirsher 
5861f7917c00SJeff Kirsher 	for (i = 0; i < NMTUS; ++i) {
5862f7917c00SJeff Kirsher 		unsigned int mtu = mtus[i];
5863f7917c00SJeff Kirsher 		unsigned int log2 = fls(mtu);
5864f7917c00SJeff Kirsher 
5865f7917c00SJeff Kirsher 		if (!(mtu & ((1 << log2) >> 2)))     /* round */
5866f7917c00SJeff Kirsher 			log2--;
5867837e4a42SHariprasad Shenai 		t4_write_reg(adap, TP_MTU_TABLE_A, MTUINDEX_V(i) |
5868837e4a42SHariprasad Shenai 			     MTUWIDTH_V(log2) | MTUVALUE_V(mtu));
5869f7917c00SJeff Kirsher 
5870f7917c00SJeff Kirsher 		for (w = 0; w < NCCTRL_WIN; ++w) {
5871f7917c00SJeff Kirsher 			unsigned int inc;
5872f7917c00SJeff Kirsher 
5873f7917c00SJeff Kirsher 			inc = max(((mtu - 40) * alpha[w]) / avg_pkts[w],
5874f7917c00SJeff Kirsher 				  CC_MIN_INCR);
5875f7917c00SJeff Kirsher 
5876837e4a42SHariprasad Shenai 			t4_write_reg(adap, TP_CCTRL_TABLE_A, (i << 21) |
5877f7917c00SJeff Kirsher 				     (w << 16) | (beta[w] << 13) | inc);
5878f7917c00SJeff Kirsher 		}
5879f7917c00SJeff Kirsher 	}
5880f7917c00SJeff Kirsher }
5881f7917c00SJeff Kirsher 
58827864026bSHariprasad Shenai /* Calculates a rate in bytes/s given the number of 256-byte units per 4K core
58837864026bSHariprasad Shenai  * clocks.  The formula is
58847864026bSHariprasad Shenai  *
58857864026bSHariprasad Shenai  * bytes/s = bytes256 * 256 * ClkFreq / 4096
58867864026bSHariprasad Shenai  *
58877864026bSHariprasad Shenai  * which is equivalent to
58887864026bSHariprasad Shenai  *
58897864026bSHariprasad Shenai  * bytes/s = 62.5 * bytes256 * ClkFreq_ms
58907864026bSHariprasad Shenai  */
chan_rate(struct adapter * adap,unsigned int bytes256)58917864026bSHariprasad Shenai static u64 chan_rate(struct adapter *adap, unsigned int bytes256)
58927864026bSHariprasad Shenai {
58937864026bSHariprasad Shenai 	u64 v = bytes256 * adap->params.vpd.cclk;
58947864026bSHariprasad Shenai 
58957864026bSHariprasad Shenai 	return v * 62 + v / 2;
58967864026bSHariprasad Shenai }
58977864026bSHariprasad Shenai 
58987864026bSHariprasad Shenai /**
58997864026bSHariprasad Shenai  *	t4_get_chan_txrate - get the current per channel Tx rates
59007864026bSHariprasad Shenai  *	@adap: the adapter
59017864026bSHariprasad Shenai  *	@nic_rate: rates for NIC traffic
59027864026bSHariprasad Shenai  *	@ofld_rate: rates for offloaded traffic
59037864026bSHariprasad Shenai  *
59047864026bSHariprasad Shenai  *	Return the current Tx rates in bytes/s for NIC and offloaded traffic
59057864026bSHariprasad Shenai  *	for each channel.
59067864026bSHariprasad Shenai  */
t4_get_chan_txrate(struct adapter * adap,u64 * nic_rate,u64 * ofld_rate)59077864026bSHariprasad Shenai void t4_get_chan_txrate(struct adapter *adap, u64 *nic_rate, u64 *ofld_rate)
59087864026bSHariprasad Shenai {
59097864026bSHariprasad Shenai 	u32 v;
59107864026bSHariprasad Shenai 
59117864026bSHariprasad Shenai 	v = t4_read_reg(adap, TP_TX_TRATE_A);
59127864026bSHariprasad Shenai 	nic_rate[0] = chan_rate(adap, TNLRATE0_G(v));
59137864026bSHariprasad Shenai 	nic_rate[1] = chan_rate(adap, TNLRATE1_G(v));
59147864026bSHariprasad Shenai 	if (adap->params.arch.nchan == NCHAN) {
59157864026bSHariprasad Shenai 		nic_rate[2] = chan_rate(adap, TNLRATE2_G(v));
59167864026bSHariprasad Shenai 		nic_rate[3] = chan_rate(adap, TNLRATE3_G(v));
59177864026bSHariprasad Shenai 	}
59187864026bSHariprasad Shenai 
59197864026bSHariprasad Shenai 	v = t4_read_reg(adap, TP_TX_ORATE_A);
59207864026bSHariprasad Shenai 	ofld_rate[0] = chan_rate(adap, OFDRATE0_G(v));
59217864026bSHariprasad Shenai 	ofld_rate[1] = chan_rate(adap, OFDRATE1_G(v));
59227864026bSHariprasad Shenai 	if (adap->params.arch.nchan == NCHAN) {
59237864026bSHariprasad Shenai 		ofld_rate[2] = chan_rate(adap, OFDRATE2_G(v));
59247864026bSHariprasad Shenai 		ofld_rate[3] = chan_rate(adap, OFDRATE3_G(v));
59257864026bSHariprasad Shenai 	}
59267864026bSHariprasad Shenai }
59277864026bSHariprasad Shenai 
5928f7917c00SJeff Kirsher /**
59298e3d04fdSHariprasad Shenai  *	t4_set_trace_filter - configure one of the tracing filters
59308e3d04fdSHariprasad Shenai  *	@adap: the adapter
59318e3d04fdSHariprasad Shenai  *	@tp: the desired trace filter parameters
59328e3d04fdSHariprasad Shenai  *	@idx: which filter to configure
59338e3d04fdSHariprasad Shenai  *	@enable: whether to enable or disable the filter
59348e3d04fdSHariprasad Shenai  *
59358e3d04fdSHariprasad Shenai  *	Configures one of the tracing filters available in HW.  If @enable is
59368e3d04fdSHariprasad Shenai  *	%0 @tp is not examined and may be %NULL. The user is responsible to
59378e3d04fdSHariprasad Shenai  *	set the single/multiple trace mode by writing to MPS_TRC_CFG_A register
59388e3d04fdSHariprasad Shenai  */
t4_set_trace_filter(struct adapter * adap,const struct trace_params * tp,int idx,int enable)59398e3d04fdSHariprasad Shenai int t4_set_trace_filter(struct adapter *adap, const struct trace_params *tp,
59408e3d04fdSHariprasad Shenai 			int idx, int enable)
59418e3d04fdSHariprasad Shenai {
59428e3d04fdSHariprasad Shenai 	int i, ofst = idx * 4;
59438e3d04fdSHariprasad Shenai 	u32 data_reg, mask_reg, cfg;
59448e3d04fdSHariprasad Shenai 
59458e3d04fdSHariprasad Shenai 	if (!enable) {
59468e3d04fdSHariprasad Shenai 		t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A_A + ofst, 0);
59478e3d04fdSHariprasad Shenai 		return 0;
59488e3d04fdSHariprasad Shenai 	}
59498e3d04fdSHariprasad Shenai 
59508e3d04fdSHariprasad Shenai 	cfg = t4_read_reg(adap, MPS_TRC_CFG_A);
59518e3d04fdSHariprasad Shenai 	if (cfg & TRCMULTIFILTER_F) {
59528e3d04fdSHariprasad Shenai 		/* If multiple tracers are enabled, then maximum
59538e3d04fdSHariprasad Shenai 		 * capture size is 2.5KB (FIFO size of a single channel)
59548e3d04fdSHariprasad Shenai 		 * minus 2 flits for CPL_TRACE_PKT header.
59558e3d04fdSHariprasad Shenai 		 */
59568e3d04fdSHariprasad Shenai 		if (tp->snap_len > ((10 * 1024 / 4) - (2 * 8)))
59578e3d04fdSHariprasad Shenai 			return -EINVAL;
59588e3d04fdSHariprasad Shenai 	} else {
59598e3d04fdSHariprasad Shenai 		/* If multiple tracers are disabled, to avoid deadlocks
59608e3d04fdSHariprasad Shenai 		 * maximum packet capture size of 9600 bytes is recommended.
59618e3d04fdSHariprasad Shenai 		 * Also in this mode, only trace0 can be enabled and running.
59628e3d04fdSHariprasad Shenai 		 */
59638e3d04fdSHariprasad Shenai 		if (tp->snap_len > 9600 || idx)
59648e3d04fdSHariprasad Shenai 			return -EINVAL;
59658e3d04fdSHariprasad Shenai 	}
59668e3d04fdSHariprasad Shenai 
59678e3d04fdSHariprasad Shenai 	if (tp->port > (is_t4(adap->params.chip) ? 11 : 19) || tp->invert > 1 ||
59688e3d04fdSHariprasad Shenai 	    tp->skip_len > TFLENGTH_M || tp->skip_ofst > TFOFFSET_M ||
59698e3d04fdSHariprasad Shenai 	    tp->min_len > TFMINPKTSIZE_M)
59708e3d04fdSHariprasad Shenai 		return -EINVAL;
59718e3d04fdSHariprasad Shenai 
59728e3d04fdSHariprasad Shenai 	/* stop the tracer we'll be changing */
59738e3d04fdSHariprasad Shenai 	t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A_A + ofst, 0);
59748e3d04fdSHariprasad Shenai 
59758e3d04fdSHariprasad Shenai 	idx *= (MPS_TRC_FILTER1_MATCH_A - MPS_TRC_FILTER0_MATCH_A);
59768e3d04fdSHariprasad Shenai 	data_reg = MPS_TRC_FILTER0_MATCH_A + idx;
59778e3d04fdSHariprasad Shenai 	mask_reg = MPS_TRC_FILTER0_DONT_CARE_A + idx;
59788e3d04fdSHariprasad Shenai 
59798e3d04fdSHariprasad Shenai 	for (i = 0; i < TRACE_LEN / 4; i++, data_reg += 4, mask_reg += 4) {
59808e3d04fdSHariprasad Shenai 		t4_write_reg(adap, data_reg, tp->data[i]);
59818e3d04fdSHariprasad Shenai 		t4_write_reg(adap, mask_reg, ~tp->mask[i]);
59828e3d04fdSHariprasad Shenai 	}
59838e3d04fdSHariprasad Shenai 	t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_B_A + ofst,
59848e3d04fdSHariprasad Shenai 		     TFCAPTUREMAX_V(tp->snap_len) |
59858e3d04fdSHariprasad Shenai 		     TFMINPKTSIZE_V(tp->min_len));
59868e3d04fdSHariprasad Shenai 	t4_write_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A_A + ofst,
59878e3d04fdSHariprasad Shenai 		     TFOFFSET_V(tp->skip_ofst) | TFLENGTH_V(tp->skip_len) |
59888e3d04fdSHariprasad Shenai 		     (is_t4(adap->params.chip) ?
59898e3d04fdSHariprasad Shenai 		     TFPORT_V(tp->port) | TFEN_F | TFINVERTMATCH_V(tp->invert) :
59908e3d04fdSHariprasad Shenai 		     T5_TFPORT_V(tp->port) | T5_TFEN_F |
59918e3d04fdSHariprasad Shenai 		     T5_TFINVERTMATCH_V(tp->invert)));
59928e3d04fdSHariprasad Shenai 
59938e3d04fdSHariprasad Shenai 	return 0;
59948e3d04fdSHariprasad Shenai }
59958e3d04fdSHariprasad Shenai 
59968e3d04fdSHariprasad Shenai /**
59978e3d04fdSHariprasad Shenai  *	t4_get_trace_filter - query one of the tracing filters
59988e3d04fdSHariprasad Shenai  *	@adap: the adapter
59998e3d04fdSHariprasad Shenai  *	@tp: the current trace filter parameters
60008e3d04fdSHariprasad Shenai  *	@idx: which trace filter to query
60018e3d04fdSHariprasad Shenai  *	@enabled: non-zero if the filter is enabled
60028e3d04fdSHariprasad Shenai  *
60038e3d04fdSHariprasad Shenai  *	Returns the current settings of one of the HW tracing filters.
60048e3d04fdSHariprasad Shenai  */
t4_get_trace_filter(struct adapter * adap,struct trace_params * tp,int idx,int * enabled)60058e3d04fdSHariprasad Shenai void t4_get_trace_filter(struct adapter *adap, struct trace_params *tp, int idx,
60068e3d04fdSHariprasad Shenai 			 int *enabled)
60078e3d04fdSHariprasad Shenai {
60088e3d04fdSHariprasad Shenai 	u32 ctla, ctlb;
60098e3d04fdSHariprasad Shenai 	int i, ofst = idx * 4;
60108e3d04fdSHariprasad Shenai 	u32 data_reg, mask_reg;
60118e3d04fdSHariprasad Shenai 
60128e3d04fdSHariprasad Shenai 	ctla = t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_A_A + ofst);
60138e3d04fdSHariprasad Shenai 	ctlb = t4_read_reg(adap, MPS_TRC_FILTER_MATCH_CTL_B_A + ofst);
60148e3d04fdSHariprasad Shenai 
60158e3d04fdSHariprasad Shenai 	if (is_t4(adap->params.chip)) {
60168e3d04fdSHariprasad Shenai 		*enabled = !!(ctla & TFEN_F);
60178e3d04fdSHariprasad Shenai 		tp->port =  TFPORT_G(ctla);
60188e3d04fdSHariprasad Shenai 		tp->invert = !!(ctla & TFINVERTMATCH_F);
60198e3d04fdSHariprasad Shenai 	} else {
60208e3d04fdSHariprasad Shenai 		*enabled = !!(ctla & T5_TFEN_F);
60218e3d04fdSHariprasad Shenai 		tp->port = T5_TFPORT_G(ctla);
60228e3d04fdSHariprasad Shenai 		tp->invert = !!(ctla & T5_TFINVERTMATCH_F);
60238e3d04fdSHariprasad Shenai 	}
60248e3d04fdSHariprasad Shenai 	tp->snap_len = TFCAPTUREMAX_G(ctlb);
60258e3d04fdSHariprasad Shenai 	tp->min_len = TFMINPKTSIZE_G(ctlb);
60268e3d04fdSHariprasad Shenai 	tp->skip_ofst = TFOFFSET_G(ctla);
60278e3d04fdSHariprasad Shenai 	tp->skip_len = TFLENGTH_G(ctla);
60288e3d04fdSHariprasad Shenai 
60298e3d04fdSHariprasad Shenai 	ofst = (MPS_TRC_FILTER1_MATCH_A - MPS_TRC_FILTER0_MATCH_A) * idx;
60308e3d04fdSHariprasad Shenai 	data_reg = MPS_TRC_FILTER0_MATCH_A + ofst;
60318e3d04fdSHariprasad Shenai 	mask_reg = MPS_TRC_FILTER0_DONT_CARE_A + ofst;
60328e3d04fdSHariprasad Shenai 
60338e3d04fdSHariprasad Shenai 	for (i = 0; i < TRACE_LEN / 4; i++, data_reg += 4, mask_reg += 4) {
60348e3d04fdSHariprasad Shenai 		tp->mask[i] = ~t4_read_reg(adap, mask_reg);
60358e3d04fdSHariprasad Shenai 		tp->data[i] = t4_read_reg(adap, data_reg) & tp->mask[i];
60368e3d04fdSHariprasad Shenai 	}
60378e3d04fdSHariprasad Shenai }
60388e3d04fdSHariprasad Shenai 
60398e3d04fdSHariprasad Shenai /**
6040b3bbe36aSHariprasad Shenai  *	t4_pmtx_get_stats - returns the HW stats from PMTX
6041b3bbe36aSHariprasad Shenai  *	@adap: the adapter
6042b3bbe36aSHariprasad Shenai  *	@cnt: where to store the count statistics
6043b3bbe36aSHariprasad Shenai  *	@cycles: where to store the cycle statistics
6044b3bbe36aSHariprasad Shenai  *
6045b3bbe36aSHariprasad Shenai  *	Returns performance statistics from PMTX.
6046b3bbe36aSHariprasad Shenai  */
t4_pmtx_get_stats(struct adapter * adap,u32 cnt[],u64 cycles[])6047b3bbe36aSHariprasad Shenai void t4_pmtx_get_stats(struct adapter *adap, u32 cnt[], u64 cycles[])
6048b3bbe36aSHariprasad Shenai {
6049b3bbe36aSHariprasad Shenai 	int i;
6050b3bbe36aSHariprasad Shenai 	u32 data[2];
6051b3bbe36aSHariprasad Shenai 
605244588560SHariprasad Shenai 	for (i = 0; i < adap->params.arch.pm_stats_cnt; i++) {
6053b3bbe36aSHariprasad Shenai 		t4_write_reg(adap, PM_TX_STAT_CONFIG_A, i + 1);
6054b3bbe36aSHariprasad Shenai 		cnt[i] = t4_read_reg(adap, PM_TX_STAT_COUNT_A);
6055b3bbe36aSHariprasad Shenai 		if (is_t4(adap->params.chip)) {
6056b3bbe36aSHariprasad Shenai 			cycles[i] = t4_read_reg64(adap, PM_TX_STAT_LSB_A);
6057b3bbe36aSHariprasad Shenai 		} else {
6058b3bbe36aSHariprasad Shenai 			t4_read_indirect(adap, PM_TX_DBG_CTRL_A,
6059b3bbe36aSHariprasad Shenai 					 PM_TX_DBG_DATA_A, data, 2,
6060b3bbe36aSHariprasad Shenai 					 PM_TX_DBG_STAT_MSB_A);
6061b3bbe36aSHariprasad Shenai 			cycles[i] = (((u64)data[0] << 32) | data[1]);
6062b3bbe36aSHariprasad Shenai 		}
6063b3bbe36aSHariprasad Shenai 	}
6064b3bbe36aSHariprasad Shenai }
6065b3bbe36aSHariprasad Shenai 
6066b3bbe36aSHariprasad Shenai /**
6067b3bbe36aSHariprasad Shenai  *	t4_pmrx_get_stats - returns the HW stats from PMRX
6068b3bbe36aSHariprasad Shenai  *	@adap: the adapter
6069b3bbe36aSHariprasad Shenai  *	@cnt: where to store the count statistics
6070b3bbe36aSHariprasad Shenai  *	@cycles: where to store the cycle statistics
6071b3bbe36aSHariprasad Shenai  *
6072b3bbe36aSHariprasad Shenai  *	Returns performance statistics from PMRX.
6073b3bbe36aSHariprasad Shenai  */
t4_pmrx_get_stats(struct adapter * adap,u32 cnt[],u64 cycles[])6074b3bbe36aSHariprasad Shenai void t4_pmrx_get_stats(struct adapter *adap, u32 cnt[], u64 cycles[])
6075b3bbe36aSHariprasad Shenai {
6076b3bbe36aSHariprasad Shenai 	int i;
6077b3bbe36aSHariprasad Shenai 	u32 data[2];
6078b3bbe36aSHariprasad Shenai 
607944588560SHariprasad Shenai 	for (i = 0; i < adap->params.arch.pm_stats_cnt; i++) {
6080b3bbe36aSHariprasad Shenai 		t4_write_reg(adap, PM_RX_STAT_CONFIG_A, i + 1);
6081b3bbe36aSHariprasad Shenai 		cnt[i] = t4_read_reg(adap, PM_RX_STAT_COUNT_A);
6082b3bbe36aSHariprasad Shenai 		if (is_t4(adap->params.chip)) {
6083b3bbe36aSHariprasad Shenai 			cycles[i] = t4_read_reg64(adap, PM_RX_STAT_LSB_A);
6084b3bbe36aSHariprasad Shenai 		} else {
6085b3bbe36aSHariprasad Shenai 			t4_read_indirect(adap, PM_RX_DBG_CTRL_A,
6086b3bbe36aSHariprasad Shenai 					 PM_RX_DBG_DATA_A, data, 2,
6087b3bbe36aSHariprasad Shenai 					 PM_RX_DBG_STAT_MSB_A);
6088b3bbe36aSHariprasad Shenai 			cycles[i] = (((u64)data[0] << 32) | data[1]);
6089b3bbe36aSHariprasad Shenai 		}
6090b3bbe36aSHariprasad Shenai 	}
6091b3bbe36aSHariprasad Shenai }
6092b3bbe36aSHariprasad Shenai 
6093b3bbe36aSHariprasad Shenai /**
60948f46d467SArjun Vynipadath  *	compute_mps_bg_map - compute the MPS Buffer Group Map for a Port
609529bbf5d7SRahul Lakkireddy  *	@adapter: the adapter
6096193c4c28SArjun Vynipadath  *	@pidx: the port index
6097f7917c00SJeff Kirsher  *
60988f46d467SArjun Vynipadath  *	Computes and returns a bitmap indicating which MPS buffer groups are
60998f46d467SArjun Vynipadath  *	associated with the given Port.  Bit i is set if buffer group i is
61008f46d467SArjun Vynipadath  *	used by the Port.
6101f7917c00SJeff Kirsher  */
compute_mps_bg_map(struct adapter * adapter,int pidx)61028f46d467SArjun Vynipadath static inline unsigned int compute_mps_bg_map(struct adapter *adapter,
61038f46d467SArjun Vynipadath 					      int pidx)
6104f7917c00SJeff Kirsher {
61058f46d467SArjun Vynipadath 	unsigned int chip_version, nports;
6106f7917c00SJeff Kirsher 
61078f46d467SArjun Vynipadath 	chip_version = CHELSIO_CHIP_VERSION(adapter->params.chip);
61088f46d467SArjun Vynipadath 	nports = 1 << NUMPORTS_G(t4_read_reg(adapter, MPS_CMN_CTL_A));
6109193c4c28SArjun Vynipadath 
6110193c4c28SArjun Vynipadath 	switch (chip_version) {
6111193c4c28SArjun Vynipadath 	case CHELSIO_T4:
6112193c4c28SArjun Vynipadath 	case CHELSIO_T5:
6113193c4c28SArjun Vynipadath 		switch (nports) {
6114193c4c28SArjun Vynipadath 		case 1: return 0xf;
6115193c4c28SArjun Vynipadath 		case 2: return 3 << (2 * pidx);
6116193c4c28SArjun Vynipadath 		case 4: return 1 << pidx;
6117193c4c28SArjun Vynipadath 		}
6118193c4c28SArjun Vynipadath 		break;
6119193c4c28SArjun Vynipadath 
6120193c4c28SArjun Vynipadath 	case CHELSIO_T6:
6121193c4c28SArjun Vynipadath 		switch (nports) {
6122193c4c28SArjun Vynipadath 		case 2: return 1 << (2 * pidx);
6123193c4c28SArjun Vynipadath 		}
6124193c4c28SArjun Vynipadath 		break;
6125193c4c28SArjun Vynipadath 	}
6126193c4c28SArjun Vynipadath 
61278f46d467SArjun Vynipadath 	dev_err(adapter->pdev_dev, "Need MPS Buffer Group Map for Chip %0x, Nports %d\n",
6128193c4c28SArjun Vynipadath 		chip_version, nports);
61298f46d467SArjun Vynipadath 
6130193c4c28SArjun Vynipadath 	return 0;
6131193c4c28SArjun Vynipadath }
6132193c4c28SArjun Vynipadath 
6133193c4c28SArjun Vynipadath /**
61348f46d467SArjun Vynipadath  *	t4_get_mps_bg_map - return the buffer groups associated with a port
61358f46d467SArjun Vynipadath  *	@adapter: the adapter
61368f46d467SArjun Vynipadath  *	@pidx: the port index
61378f46d467SArjun Vynipadath  *
61388f46d467SArjun Vynipadath  *	Returns a bitmap indicating which MPS buffer groups are associated
61398f46d467SArjun Vynipadath  *	with the given Port.  Bit i is set if buffer group i is used by the
61408f46d467SArjun Vynipadath  *	Port.
61418f46d467SArjun Vynipadath  */
t4_get_mps_bg_map(struct adapter * adapter,int pidx)61428f46d467SArjun Vynipadath unsigned int t4_get_mps_bg_map(struct adapter *adapter, int pidx)
61438f46d467SArjun Vynipadath {
61448f46d467SArjun Vynipadath 	u8 *mps_bg_map;
61458f46d467SArjun Vynipadath 	unsigned int nports;
61468f46d467SArjun Vynipadath 
61478f46d467SArjun Vynipadath 	nports = 1 << NUMPORTS_G(t4_read_reg(adapter, MPS_CMN_CTL_A));
61488f46d467SArjun Vynipadath 	if (pidx >= nports) {
61498f46d467SArjun Vynipadath 		CH_WARN(adapter, "MPS Port Index %d >= Nports %d\n",
61508f46d467SArjun Vynipadath 			pidx, nports);
61518f46d467SArjun Vynipadath 		return 0;
61528f46d467SArjun Vynipadath 	}
61538f46d467SArjun Vynipadath 
61548f46d467SArjun Vynipadath 	/* If we've already retrieved/computed this, just return the result.
61558f46d467SArjun Vynipadath 	 */
61568f46d467SArjun Vynipadath 	mps_bg_map = adapter->params.mps_bg_map;
61578f46d467SArjun Vynipadath 	if (mps_bg_map[pidx])
61588f46d467SArjun Vynipadath 		return mps_bg_map[pidx];
61598f46d467SArjun Vynipadath 
61608f46d467SArjun Vynipadath 	/* Newer Firmware can tell us what the MPS Buffer Group Map is.
61618f46d467SArjun Vynipadath 	 * If we're talking to such Firmware, let it tell us.  If the new
61628f46d467SArjun Vynipadath 	 * API isn't supported, revert back to old hardcoded way.  The value
61638f46d467SArjun Vynipadath 	 * obtained from Firmware is encoded in below format:
61648f46d467SArjun Vynipadath 	 *
61658f46d467SArjun Vynipadath 	 * val = (( MPSBGMAP[Port 3] << 24 ) |
61668f46d467SArjun Vynipadath 	 *        ( MPSBGMAP[Port 2] << 16 ) |
61678f46d467SArjun Vynipadath 	 *        ( MPSBGMAP[Port 1] <<  8 ) |
61688f46d467SArjun Vynipadath 	 *        ( MPSBGMAP[Port 0] <<  0 ))
61698f46d467SArjun Vynipadath 	 */
617080f61f19SArjun Vynipadath 	if (adapter->flags & CXGB4_FW_OK) {
61718f46d467SArjun Vynipadath 		u32 param, val;
61728f46d467SArjun Vynipadath 		int ret;
61738f46d467SArjun Vynipadath 
61748f46d467SArjun Vynipadath 		param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) |
61758f46d467SArjun Vynipadath 			 FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_MPSBGMAP));
61768f46d467SArjun Vynipadath 		ret = t4_query_params_ns(adapter, adapter->mbox, adapter->pf,
61778f46d467SArjun Vynipadath 					 0, 1, &param, &val);
61788f46d467SArjun Vynipadath 		if (!ret) {
61798f46d467SArjun Vynipadath 			int p;
61808f46d467SArjun Vynipadath 
61818f46d467SArjun Vynipadath 			/* Store the BG Map for all of the Ports in order to
61828f46d467SArjun Vynipadath 			 * avoid more calls to the Firmware in the future.
61838f46d467SArjun Vynipadath 			 */
61848f46d467SArjun Vynipadath 			for (p = 0; p < MAX_NPORTS; p++, val >>= 8)
61858f46d467SArjun Vynipadath 				mps_bg_map[p] = val & 0xff;
61868f46d467SArjun Vynipadath 
61878f46d467SArjun Vynipadath 			return mps_bg_map[pidx];
61888f46d467SArjun Vynipadath 		}
61898f46d467SArjun Vynipadath 	}
61908f46d467SArjun Vynipadath 
61918f46d467SArjun Vynipadath 	/* Either we're not talking to the Firmware or we're dealing with
61928f46d467SArjun Vynipadath 	 * older Firmware which doesn't support the new API to get the MPS
61938f46d467SArjun Vynipadath 	 * Buffer Group Map.  Fall back to computing it ourselves.
61948f46d467SArjun Vynipadath 	 */
61958f46d467SArjun Vynipadath 	mps_bg_map[pidx] = compute_mps_bg_map(adapter, pidx);
61968f46d467SArjun Vynipadath 	return mps_bg_map[pidx];
61978f46d467SArjun Vynipadath }
61988f46d467SArjun Vynipadath 
61998f46d467SArjun Vynipadath /**
620074dd5aa1SVishal Kulkarni  *      t4_get_tp_e2c_map - return the E2C channel map associated with a port
620174dd5aa1SVishal Kulkarni  *      @adapter: the adapter
620274dd5aa1SVishal Kulkarni  *      @pidx: the port index
620374dd5aa1SVishal Kulkarni  */
t4_get_tp_e2c_map(struct adapter * adapter,int pidx)6204f4aa8012SYueHaibing static unsigned int t4_get_tp_e2c_map(struct adapter *adapter, int pidx)
620574dd5aa1SVishal Kulkarni {
620674dd5aa1SVishal Kulkarni 	unsigned int nports;
620774dd5aa1SVishal Kulkarni 	u32 param, val = 0;
620874dd5aa1SVishal Kulkarni 	int ret;
620974dd5aa1SVishal Kulkarni 
621074dd5aa1SVishal Kulkarni 	nports = 1 << NUMPORTS_G(t4_read_reg(adapter, MPS_CMN_CTL_A));
621174dd5aa1SVishal Kulkarni 	if (pidx >= nports) {
621274dd5aa1SVishal Kulkarni 		CH_WARN(adapter, "TP E2C Channel Port Index %d >= Nports %d\n",
621374dd5aa1SVishal Kulkarni 			pidx, nports);
621474dd5aa1SVishal Kulkarni 		return 0;
621574dd5aa1SVishal Kulkarni 	}
621674dd5aa1SVishal Kulkarni 
621774dd5aa1SVishal Kulkarni 	/* FW version >= 1.16.44.0 can determine E2C channel map using
621874dd5aa1SVishal Kulkarni 	 * FW_PARAMS_PARAM_DEV_TPCHMAP API.
621974dd5aa1SVishal Kulkarni 	 */
622074dd5aa1SVishal Kulkarni 	param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) |
622174dd5aa1SVishal Kulkarni 		 FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_TPCHMAP));
622274dd5aa1SVishal Kulkarni 	ret = t4_query_params_ns(adapter, adapter->mbox, adapter->pf,
622374dd5aa1SVishal Kulkarni 				 0, 1, &param, &val);
622474dd5aa1SVishal Kulkarni 	if (!ret)
622574dd5aa1SVishal Kulkarni 		return (val >> (8 * pidx)) & 0xff;
622674dd5aa1SVishal Kulkarni 
622774dd5aa1SVishal Kulkarni 	return 0;
622874dd5aa1SVishal Kulkarni }
622974dd5aa1SVishal Kulkarni 
623074dd5aa1SVishal Kulkarni /**
6231193c4c28SArjun Vynipadath  *	t4_get_tp_ch_map - return TP ingress channels associated with a port
623229bbf5d7SRahul Lakkireddy  *	@adap: the adapter
6233193c4c28SArjun Vynipadath  *	@pidx: the port index
6234193c4c28SArjun Vynipadath  *
6235193c4c28SArjun Vynipadath  *	Returns a bitmap indicating which TP Ingress Channels are associated
6236193c4c28SArjun Vynipadath  *	with a given Port.  Bit i is set if TP Ingress Channel i is used by
6237193c4c28SArjun Vynipadath  *	the Port.
6238e9faeab8SHariprasad Shenai  */
t4_get_tp_ch_map(struct adapter * adap,int pidx)6239193c4c28SArjun Vynipadath unsigned int t4_get_tp_ch_map(struct adapter *adap, int pidx)
6240193c4c28SArjun Vynipadath {
6241193c4c28SArjun Vynipadath 	unsigned int chip_version = CHELSIO_CHIP_VERSION(adap->params.chip);
6242193c4c28SArjun Vynipadath 	unsigned int nports = 1 << NUMPORTS_G(t4_read_reg(adap, MPS_CMN_CTL_A));
6243193c4c28SArjun Vynipadath 
6244193c4c28SArjun Vynipadath 	if (pidx >= nports) {
6245193c4c28SArjun Vynipadath 		dev_warn(adap->pdev_dev, "TP Port Index %d >= Nports %d\n",
6246193c4c28SArjun Vynipadath 			 pidx, nports);
6247193c4c28SArjun Vynipadath 		return 0;
6248193c4c28SArjun Vynipadath 	}
6249193c4c28SArjun Vynipadath 
6250193c4c28SArjun Vynipadath 	switch (chip_version) {
6251193c4c28SArjun Vynipadath 	case CHELSIO_T4:
6252193c4c28SArjun Vynipadath 	case CHELSIO_T5:
6253193c4c28SArjun Vynipadath 		/* Note that this happens to be the same values as the MPS
6254193c4c28SArjun Vynipadath 		 * Buffer Group Map for these Chips.  But we replicate the code
6255193c4c28SArjun Vynipadath 		 * here because they're really separate concepts.
6256193c4c28SArjun Vynipadath 		 */
6257193c4c28SArjun Vynipadath 		switch (nports) {
6258193c4c28SArjun Vynipadath 		case 1: return 0xf;
6259193c4c28SArjun Vynipadath 		case 2: return 3 << (2 * pidx);
6260193c4c28SArjun Vynipadath 		case 4: return 1 << pidx;
6261193c4c28SArjun Vynipadath 		}
6262193c4c28SArjun Vynipadath 		break;
6263193c4c28SArjun Vynipadath 
6264193c4c28SArjun Vynipadath 	case CHELSIO_T6:
6265193c4c28SArjun Vynipadath 		switch (nports) {
62663c34cb9dSGanesh Goudar 		case 1:
6267193c4c28SArjun Vynipadath 		case 2: return 1 << pidx;
6268193c4c28SArjun Vynipadath 		}
6269193c4c28SArjun Vynipadath 		break;
6270193c4c28SArjun Vynipadath 	}
6271193c4c28SArjun Vynipadath 
6272193c4c28SArjun Vynipadath 	dev_err(adap->pdev_dev, "Need TP Channel Map for Chip %0x, Nports %d\n",
6273193c4c28SArjun Vynipadath 		chip_version, nports);
6274193c4c28SArjun Vynipadath 	return 0;
6275f7917c00SJeff Kirsher }
6276f7917c00SJeff Kirsher 
6277f7917c00SJeff Kirsher /**
627872aca4bfSKumar Sanghvi  *      t4_get_port_type_description - return Port Type string description
627972aca4bfSKumar Sanghvi  *      @port_type: firmware Port Type enumeration
628072aca4bfSKumar Sanghvi  */
t4_get_port_type_description(enum fw_port_type port_type)628172aca4bfSKumar Sanghvi const char *t4_get_port_type_description(enum fw_port_type port_type)
628272aca4bfSKumar Sanghvi {
628372aca4bfSKumar Sanghvi 	static const char *const port_type_description[] = {
628489eb9835SGanesh Goudar 		"Fiber_XFI",
628589eb9835SGanesh Goudar 		"Fiber_XAUI",
628689eb9835SGanesh Goudar 		"BT_SGMII",
628789eb9835SGanesh Goudar 		"BT_XFI",
628889eb9835SGanesh Goudar 		"BT_XAUI",
628972aca4bfSKumar Sanghvi 		"KX4",
629072aca4bfSKumar Sanghvi 		"CX4",
629172aca4bfSKumar Sanghvi 		"KX",
629272aca4bfSKumar Sanghvi 		"KR",
629389eb9835SGanesh Goudar 		"SFP",
629489eb9835SGanesh Goudar 		"BP_AP",
629589eb9835SGanesh Goudar 		"BP4_AP",
629689eb9835SGanesh Goudar 		"QSFP_10G",
629789eb9835SGanesh Goudar 		"QSA",
629889eb9835SGanesh Goudar 		"QSFP",
629989eb9835SGanesh Goudar 		"BP40_BA",
630089eb9835SGanesh Goudar 		"KR4_100G",
630189eb9835SGanesh Goudar 		"CR4_QSFP",
630289eb9835SGanesh Goudar 		"CR_QSFP",
630389eb9835SGanesh Goudar 		"CR2_QSFP",
630489eb9835SGanesh Goudar 		"SFP28",
630589eb9835SGanesh Goudar 		"KR_SFP28",
6306b39ab140SGanesh Goudar 		"KR_XLAUI"
630772aca4bfSKumar Sanghvi 	};
630872aca4bfSKumar Sanghvi 
630972aca4bfSKumar Sanghvi 	if (port_type < ARRAY_SIZE(port_type_description))
631072aca4bfSKumar Sanghvi 		return port_type_description[port_type];
631172aca4bfSKumar Sanghvi 	return "UNKNOWN";
631272aca4bfSKumar Sanghvi }
631372aca4bfSKumar Sanghvi 
631472aca4bfSKumar Sanghvi /**
6315a4cfd929SHariprasad Shenai  *      t4_get_port_stats_offset - collect port stats relative to a previous
6316a4cfd929SHariprasad Shenai  *                                 snapshot
6317a4cfd929SHariprasad Shenai  *      @adap: The adapter
6318a4cfd929SHariprasad Shenai  *      @idx: The port
6319a4cfd929SHariprasad Shenai  *      @stats: Current stats to fill
6320a4cfd929SHariprasad Shenai  *      @offset: Previous stats snapshot
6321a4cfd929SHariprasad Shenai  */
t4_get_port_stats_offset(struct adapter * adap,int idx,struct port_stats * stats,struct port_stats * offset)6322a4cfd929SHariprasad Shenai void t4_get_port_stats_offset(struct adapter *adap, int idx,
6323a4cfd929SHariprasad Shenai 			      struct port_stats *stats,
6324a4cfd929SHariprasad Shenai 			      struct port_stats *offset)
6325a4cfd929SHariprasad Shenai {
6326a4cfd929SHariprasad Shenai 	u64 *s, *o;
6327a4cfd929SHariprasad Shenai 	int i;
6328a4cfd929SHariprasad Shenai 
6329a4cfd929SHariprasad Shenai 	t4_get_port_stats(adap, idx, stats);
6330a4cfd929SHariprasad Shenai 	for (i = 0, s = (u64 *)stats, o = (u64 *)offset;
6331a4cfd929SHariprasad Shenai 			i < (sizeof(struct port_stats) / sizeof(u64));
6332a4cfd929SHariprasad Shenai 			i++, s++, o++)
6333a4cfd929SHariprasad Shenai 		*s -= *o;
6334a4cfd929SHariprasad Shenai }
6335a4cfd929SHariprasad Shenai 
6336a4cfd929SHariprasad Shenai /**
6337f7917c00SJeff Kirsher  *	t4_get_port_stats - collect port statistics
6338f7917c00SJeff Kirsher  *	@adap: the adapter
6339f7917c00SJeff Kirsher  *	@idx: the port index
6340f7917c00SJeff Kirsher  *	@p: the stats structure to fill
6341f7917c00SJeff Kirsher  *
6342f7917c00SJeff Kirsher  *	Collect statistics related to the given port from HW.
6343f7917c00SJeff Kirsher  */
t4_get_port_stats(struct adapter * adap,int idx,struct port_stats * p)6344f7917c00SJeff Kirsher void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p)
6345f7917c00SJeff Kirsher {
6346145ef8a5SHariprasad Shenai 	u32 bgmap = t4_get_mps_bg_map(adap, idx);
6347f750e82eSGanesh Goudar 	u32 stat_ctl = t4_read_reg(adap, MPS_STAT_CTL_A);
6348f7917c00SJeff Kirsher 
6349f7917c00SJeff Kirsher #define GET_STAT(name) \
63500a57a536SSantosh Rastapur 	t4_read_reg64(adap, \
6351d14807ddSHariprasad Shenai 	(is_t4(adap->params.chip) ? PORT_REG(idx, MPS_PORT_STAT_##name##_L) : \
63520a57a536SSantosh Rastapur 	T5_PORT_REG(idx, MPS_PORT_STAT_##name##_L)))
6353f7917c00SJeff Kirsher #define GET_STAT_COM(name) t4_read_reg64(adap, MPS_STAT_##name##_L)
6354f7917c00SJeff Kirsher 
6355f7917c00SJeff Kirsher 	p->tx_octets           = GET_STAT(TX_PORT_BYTES);
6356f7917c00SJeff Kirsher 	p->tx_frames           = GET_STAT(TX_PORT_FRAMES);
6357f7917c00SJeff Kirsher 	p->tx_bcast_frames     = GET_STAT(TX_PORT_BCAST);
6358f7917c00SJeff Kirsher 	p->tx_mcast_frames     = GET_STAT(TX_PORT_MCAST);
6359f7917c00SJeff Kirsher 	p->tx_ucast_frames     = GET_STAT(TX_PORT_UCAST);
6360f7917c00SJeff Kirsher 	p->tx_error_frames     = GET_STAT(TX_PORT_ERROR);
6361f7917c00SJeff Kirsher 	p->tx_frames_64        = GET_STAT(TX_PORT_64B);
6362f7917c00SJeff Kirsher 	p->tx_frames_65_127    = GET_STAT(TX_PORT_65B_127B);
6363f7917c00SJeff Kirsher 	p->tx_frames_128_255   = GET_STAT(TX_PORT_128B_255B);
6364f7917c00SJeff Kirsher 	p->tx_frames_256_511   = GET_STAT(TX_PORT_256B_511B);
6365f7917c00SJeff Kirsher 	p->tx_frames_512_1023  = GET_STAT(TX_PORT_512B_1023B);
6366f7917c00SJeff Kirsher 	p->tx_frames_1024_1518 = GET_STAT(TX_PORT_1024B_1518B);
6367f7917c00SJeff Kirsher 	p->tx_frames_1519_max  = GET_STAT(TX_PORT_1519B_MAX);
6368f7917c00SJeff Kirsher 	p->tx_drop             = GET_STAT(TX_PORT_DROP);
6369f7917c00SJeff Kirsher 	p->tx_pause            = GET_STAT(TX_PORT_PAUSE);
6370f7917c00SJeff Kirsher 	p->tx_ppp0             = GET_STAT(TX_PORT_PPP0);
6371f7917c00SJeff Kirsher 	p->tx_ppp1             = GET_STAT(TX_PORT_PPP1);
6372f7917c00SJeff Kirsher 	p->tx_ppp2             = GET_STAT(TX_PORT_PPP2);
6373f7917c00SJeff Kirsher 	p->tx_ppp3             = GET_STAT(TX_PORT_PPP3);
6374f7917c00SJeff Kirsher 	p->tx_ppp4             = GET_STAT(TX_PORT_PPP4);
6375f7917c00SJeff Kirsher 	p->tx_ppp5             = GET_STAT(TX_PORT_PPP5);
6376f7917c00SJeff Kirsher 	p->tx_ppp6             = GET_STAT(TX_PORT_PPP6);
6377f7917c00SJeff Kirsher 	p->tx_ppp7             = GET_STAT(TX_PORT_PPP7);
6378f7917c00SJeff Kirsher 
6379f750e82eSGanesh Goudar 	if (CHELSIO_CHIP_VERSION(adap->params.chip) >= CHELSIO_T5) {
63802de489f4SGanesh Goudar 		if (stat_ctl & COUNTPAUSESTATTX_F)
63812de489f4SGanesh Goudar 			p->tx_frames_64 -= p->tx_pause;
6382f750e82eSGanesh Goudar 		if (stat_ctl & COUNTPAUSEMCTX_F)
6383f750e82eSGanesh Goudar 			p->tx_mcast_frames -= p->tx_pause;
6384f750e82eSGanesh Goudar 	}
6385f7917c00SJeff Kirsher 	p->rx_octets           = GET_STAT(RX_PORT_BYTES);
6386f7917c00SJeff Kirsher 	p->rx_frames           = GET_STAT(RX_PORT_FRAMES);
6387f7917c00SJeff Kirsher 	p->rx_bcast_frames     = GET_STAT(RX_PORT_BCAST);
6388f7917c00SJeff Kirsher 	p->rx_mcast_frames     = GET_STAT(RX_PORT_MCAST);
6389f7917c00SJeff Kirsher 	p->rx_ucast_frames     = GET_STAT(RX_PORT_UCAST);
6390f7917c00SJeff Kirsher 	p->rx_too_long         = GET_STAT(RX_PORT_MTU_ERROR);
6391f7917c00SJeff Kirsher 	p->rx_jabber           = GET_STAT(RX_PORT_MTU_CRC_ERROR);
6392f7917c00SJeff Kirsher 	p->rx_fcs_err          = GET_STAT(RX_PORT_CRC_ERROR);
6393f7917c00SJeff Kirsher 	p->rx_len_err          = GET_STAT(RX_PORT_LEN_ERROR);
6394f7917c00SJeff Kirsher 	p->rx_symbol_err       = GET_STAT(RX_PORT_SYM_ERROR);
6395f7917c00SJeff Kirsher 	p->rx_runt             = GET_STAT(RX_PORT_LESS_64B);
6396f7917c00SJeff Kirsher 	p->rx_frames_64        = GET_STAT(RX_PORT_64B);
6397f7917c00SJeff Kirsher 	p->rx_frames_65_127    = GET_STAT(RX_PORT_65B_127B);
6398f7917c00SJeff Kirsher 	p->rx_frames_128_255   = GET_STAT(RX_PORT_128B_255B);
6399f7917c00SJeff Kirsher 	p->rx_frames_256_511   = GET_STAT(RX_PORT_256B_511B);
6400f7917c00SJeff Kirsher 	p->rx_frames_512_1023  = GET_STAT(RX_PORT_512B_1023B);
6401f7917c00SJeff Kirsher 	p->rx_frames_1024_1518 = GET_STAT(RX_PORT_1024B_1518B);
6402f7917c00SJeff Kirsher 	p->rx_frames_1519_max  = GET_STAT(RX_PORT_1519B_MAX);
6403f7917c00SJeff Kirsher 	p->rx_pause            = GET_STAT(RX_PORT_PAUSE);
6404f7917c00SJeff Kirsher 	p->rx_ppp0             = GET_STAT(RX_PORT_PPP0);
6405f7917c00SJeff Kirsher 	p->rx_ppp1             = GET_STAT(RX_PORT_PPP1);
6406f7917c00SJeff Kirsher 	p->rx_ppp2             = GET_STAT(RX_PORT_PPP2);
6407f7917c00SJeff Kirsher 	p->rx_ppp3             = GET_STAT(RX_PORT_PPP3);
6408f7917c00SJeff Kirsher 	p->rx_ppp4             = GET_STAT(RX_PORT_PPP4);
6409f7917c00SJeff Kirsher 	p->rx_ppp5             = GET_STAT(RX_PORT_PPP5);
6410f7917c00SJeff Kirsher 	p->rx_ppp6             = GET_STAT(RX_PORT_PPP6);
6411f7917c00SJeff Kirsher 	p->rx_ppp7             = GET_STAT(RX_PORT_PPP7);
6412f7917c00SJeff Kirsher 
6413f750e82eSGanesh Goudar 	if (CHELSIO_CHIP_VERSION(adap->params.chip) >= CHELSIO_T5) {
64142de489f4SGanesh Goudar 		if (stat_ctl & COUNTPAUSESTATRX_F)
64152de489f4SGanesh Goudar 			p->rx_frames_64 -= p->rx_pause;
6416f750e82eSGanesh Goudar 		if (stat_ctl & COUNTPAUSEMCRX_F)
6417f750e82eSGanesh Goudar 			p->rx_mcast_frames -= p->rx_pause;
6418f750e82eSGanesh Goudar 	}
6419f750e82eSGanesh Goudar 
6420f7917c00SJeff Kirsher 	p->rx_ovflow0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_MAC_DROP_FRAME) : 0;
6421f7917c00SJeff Kirsher 	p->rx_ovflow1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_MAC_DROP_FRAME) : 0;
6422f7917c00SJeff Kirsher 	p->rx_ovflow2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_MAC_DROP_FRAME) : 0;
6423f7917c00SJeff Kirsher 	p->rx_ovflow3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_MAC_DROP_FRAME) : 0;
6424f7917c00SJeff Kirsher 	p->rx_trunc0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_MAC_TRUNC_FRAME) : 0;
6425f7917c00SJeff Kirsher 	p->rx_trunc1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_MAC_TRUNC_FRAME) : 0;
6426f7917c00SJeff Kirsher 	p->rx_trunc2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_MAC_TRUNC_FRAME) : 0;
6427f7917c00SJeff Kirsher 	p->rx_trunc3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_MAC_TRUNC_FRAME) : 0;
6428f7917c00SJeff Kirsher 
6429f7917c00SJeff Kirsher #undef GET_STAT
6430f7917c00SJeff Kirsher #undef GET_STAT_COM
6431f7917c00SJeff Kirsher }
6432f7917c00SJeff Kirsher 
6433f7917c00SJeff Kirsher /**
643465046e84SHariprasad Shenai  *	t4_get_lb_stats - collect loopback port statistics
6435f7917c00SJeff Kirsher  *	@adap: the adapter
643665046e84SHariprasad Shenai  *	@idx: the loopback port index
643765046e84SHariprasad Shenai  *	@p: the stats structure to fill
6438f7917c00SJeff Kirsher  *
643965046e84SHariprasad Shenai  *	Return HW statistics for the given loopback port.
6440f7917c00SJeff Kirsher  */
t4_get_lb_stats(struct adapter * adap,int idx,struct lb_port_stats * p)644165046e84SHariprasad Shenai void t4_get_lb_stats(struct adapter *adap, int idx, struct lb_port_stats *p)
6442f7917c00SJeff Kirsher {
644365046e84SHariprasad Shenai 	u32 bgmap = t4_get_mps_bg_map(adap, idx);
64440a57a536SSantosh Rastapur 
644565046e84SHariprasad Shenai #define GET_STAT(name) \
644665046e84SHariprasad Shenai 	t4_read_reg64(adap, \
64470d804338SHariprasad Shenai 	(is_t4(adap->params.chip) ? \
644865046e84SHariprasad Shenai 	PORT_REG(idx, MPS_PORT_STAT_LB_PORT_##name##_L) : \
644965046e84SHariprasad Shenai 	T5_PORT_REG(idx, MPS_PORT_STAT_LB_PORT_##name##_L)))
645065046e84SHariprasad Shenai #define GET_STAT_COM(name) t4_read_reg64(adap, MPS_STAT_##name##_L)
6451f7917c00SJeff Kirsher 
645265046e84SHariprasad Shenai 	p->octets           = GET_STAT(BYTES);
645365046e84SHariprasad Shenai 	p->frames           = GET_STAT(FRAMES);
645465046e84SHariprasad Shenai 	p->bcast_frames     = GET_STAT(BCAST);
645565046e84SHariprasad Shenai 	p->mcast_frames     = GET_STAT(MCAST);
645665046e84SHariprasad Shenai 	p->ucast_frames     = GET_STAT(UCAST);
645765046e84SHariprasad Shenai 	p->error_frames     = GET_STAT(ERROR);
6458f7917c00SJeff Kirsher 
645965046e84SHariprasad Shenai 	p->frames_64        = GET_STAT(64B);
646065046e84SHariprasad Shenai 	p->frames_65_127    = GET_STAT(65B_127B);
646165046e84SHariprasad Shenai 	p->frames_128_255   = GET_STAT(128B_255B);
646265046e84SHariprasad Shenai 	p->frames_256_511   = GET_STAT(256B_511B);
646365046e84SHariprasad Shenai 	p->frames_512_1023  = GET_STAT(512B_1023B);
646465046e84SHariprasad Shenai 	p->frames_1024_1518 = GET_STAT(1024B_1518B);
646565046e84SHariprasad Shenai 	p->frames_1519_max  = GET_STAT(1519B_MAX);
646665046e84SHariprasad Shenai 	p->drop             = GET_STAT(DROP_FRAMES);
6467f7917c00SJeff Kirsher 
646865046e84SHariprasad Shenai 	p->ovflow0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_LB_DROP_FRAME) : 0;
646965046e84SHariprasad Shenai 	p->ovflow1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_LB_DROP_FRAME) : 0;
647065046e84SHariprasad Shenai 	p->ovflow2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_LB_DROP_FRAME) : 0;
647165046e84SHariprasad Shenai 	p->ovflow3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_LB_DROP_FRAME) : 0;
647265046e84SHariprasad Shenai 	p->trunc0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_LB_TRUNC_FRAME) : 0;
647365046e84SHariprasad Shenai 	p->trunc1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_LB_TRUNC_FRAME) : 0;
647465046e84SHariprasad Shenai 	p->trunc2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_LB_TRUNC_FRAME) : 0;
647565046e84SHariprasad Shenai 	p->trunc3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_LB_TRUNC_FRAME) : 0;
6476f7917c00SJeff Kirsher 
647765046e84SHariprasad Shenai #undef GET_STAT
647865046e84SHariprasad Shenai #undef GET_STAT_COM
6479f7917c00SJeff Kirsher }
6480f7917c00SJeff Kirsher 
6481f2b7e78dSVipul Pandya /*     t4_mk_filtdelwr - create a delete filter WR
6482f2b7e78dSVipul Pandya  *     @ftid: the filter ID
6483f2b7e78dSVipul Pandya  *     @wr: the filter work request to populate
6484f2b7e78dSVipul Pandya  *     @qid: ingress queue to receive the delete notification
6485f2b7e78dSVipul Pandya  *
6486f2b7e78dSVipul Pandya  *     Creates a filter work request to delete the supplied filter.  If @qid is
6487f2b7e78dSVipul Pandya  *     negative the delete notification is suppressed.
6488f2b7e78dSVipul Pandya  */
t4_mk_filtdelwr(unsigned int ftid,struct fw_filter_wr * wr,int qid)6489f2b7e78dSVipul Pandya void t4_mk_filtdelwr(unsigned int ftid, struct fw_filter_wr *wr, int qid)
6490f2b7e78dSVipul Pandya {
6491f2b7e78dSVipul Pandya 	memset(wr, 0, sizeof(*wr));
6492f404f80cSHariprasad Shenai 	wr->op_pkd = cpu_to_be32(FW_WR_OP_V(FW_FILTER_WR));
6493f404f80cSHariprasad Shenai 	wr->len16_pkd = cpu_to_be32(FW_WR_LEN16_V(sizeof(*wr) / 16));
6494f404f80cSHariprasad Shenai 	wr->tid_to_iq = cpu_to_be32(FW_FILTER_WR_TID_V(ftid) |
649577a80e23SHariprasad Shenai 				    FW_FILTER_WR_NOREPLY_V(qid < 0));
6496f404f80cSHariprasad Shenai 	wr->del_filter_to_l2tix = cpu_to_be32(FW_FILTER_WR_DEL_FILTER_F);
6497f2b7e78dSVipul Pandya 	if (qid >= 0)
6498f404f80cSHariprasad Shenai 		wr->rx_chan_rx_rpl_iq =
6499f404f80cSHariprasad Shenai 			cpu_to_be16(FW_FILTER_WR_RX_RPL_IQ_V(qid));
6500f2b7e78dSVipul Pandya }
6501f2b7e78dSVipul Pandya 
6502f7917c00SJeff Kirsher #define INIT_CMD(var, cmd, rd_wr) do { \
6503f404f80cSHariprasad Shenai 	(var).op_to_write = cpu_to_be32(FW_CMD_OP_V(FW_##cmd##_CMD) | \
6504f404f80cSHariprasad Shenai 					FW_CMD_REQUEST_F | \
6505f404f80cSHariprasad Shenai 					FW_CMD_##rd_wr##_F); \
6506f404f80cSHariprasad Shenai 	(var).retval_len16 = cpu_to_be32(FW_LEN16(var)); \
6507f7917c00SJeff Kirsher } while (0)
6508f7917c00SJeff Kirsher 
t4_fwaddrspace_write(struct adapter * adap,unsigned int mbox,u32 addr,u32 val)65098caa1e84SVipul Pandya int t4_fwaddrspace_write(struct adapter *adap, unsigned int mbox,
65108caa1e84SVipul Pandya 			  u32 addr, u32 val)
65118caa1e84SVipul Pandya {
6512f404f80cSHariprasad Shenai 	u32 ldst_addrspace;
65138caa1e84SVipul Pandya 	struct fw_ldst_cmd c;
65148caa1e84SVipul Pandya 
65158caa1e84SVipul Pandya 	memset(&c, 0, sizeof(c));
6516f404f80cSHariprasad Shenai 	ldst_addrspace = FW_LDST_CMD_ADDRSPACE_V(FW_LDST_ADDRSPC_FIRMWARE);
6517f404f80cSHariprasad Shenai 	c.op_to_addrspace = cpu_to_be32(FW_CMD_OP_V(FW_LDST_CMD) |
6518f404f80cSHariprasad Shenai 					FW_CMD_REQUEST_F |
6519e2ac9628SHariprasad Shenai 					FW_CMD_WRITE_F |
6520f404f80cSHariprasad Shenai 					ldst_addrspace);
6521f404f80cSHariprasad Shenai 	c.cycles_to_len16 = cpu_to_be32(FW_LEN16(c));
6522f404f80cSHariprasad Shenai 	c.u.addrval.addr = cpu_to_be32(addr);
6523f404f80cSHariprasad Shenai 	c.u.addrval.val = cpu_to_be32(val);
65248caa1e84SVipul Pandya 
65258caa1e84SVipul Pandya 	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
65268caa1e84SVipul Pandya }
65278caa1e84SVipul Pandya 
652849ce9c2cSBen Hutchings /**
6529f7917c00SJeff Kirsher  *	t4_mdio_rd - read a PHY register through MDIO
6530f7917c00SJeff Kirsher  *	@adap: the adapter
6531f7917c00SJeff Kirsher  *	@mbox: mailbox to use for the FW command
6532f7917c00SJeff Kirsher  *	@phy_addr: the PHY address
6533f7917c00SJeff Kirsher  *	@mmd: the PHY MMD to access (0 for clause 22 PHYs)
6534f7917c00SJeff Kirsher  *	@reg: the register to read
6535f7917c00SJeff Kirsher  *	@valp: where to store the value
6536f7917c00SJeff Kirsher  *
6537f7917c00SJeff Kirsher  *	Issues a FW command through the given mailbox to read a PHY register.
6538f7917c00SJeff Kirsher  */
t4_mdio_rd(struct adapter * adap,unsigned int mbox,unsigned int phy_addr,unsigned int mmd,unsigned int reg,u16 * valp)6539f7917c00SJeff Kirsher int t4_mdio_rd(struct adapter *adap, unsigned int mbox, unsigned int phy_addr,
6540f7917c00SJeff Kirsher 	       unsigned int mmd, unsigned int reg, u16 *valp)
6541f7917c00SJeff Kirsher {
6542f7917c00SJeff Kirsher 	int ret;
6543f404f80cSHariprasad Shenai 	u32 ldst_addrspace;
6544f7917c00SJeff Kirsher 	struct fw_ldst_cmd c;
6545f7917c00SJeff Kirsher 
6546f7917c00SJeff Kirsher 	memset(&c, 0, sizeof(c));
6547f404f80cSHariprasad Shenai 	ldst_addrspace = FW_LDST_CMD_ADDRSPACE_V(FW_LDST_ADDRSPC_MDIO);
6548f404f80cSHariprasad Shenai 	c.op_to_addrspace = cpu_to_be32(FW_CMD_OP_V(FW_LDST_CMD) |
6549f404f80cSHariprasad Shenai 					FW_CMD_REQUEST_F | FW_CMD_READ_F |
6550f404f80cSHariprasad Shenai 					ldst_addrspace);
6551f404f80cSHariprasad Shenai 	c.cycles_to_len16 = cpu_to_be32(FW_LEN16(c));
6552f404f80cSHariprasad Shenai 	c.u.mdio.paddr_mmd = cpu_to_be16(FW_LDST_CMD_PADDR_V(phy_addr) |
65535167865aSHariprasad Shenai 					 FW_LDST_CMD_MMD_V(mmd));
6554f404f80cSHariprasad Shenai 	c.u.mdio.raddr = cpu_to_be16(reg);
6555f7917c00SJeff Kirsher 
6556f7917c00SJeff Kirsher 	ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
6557f7917c00SJeff Kirsher 	if (ret == 0)
6558f404f80cSHariprasad Shenai 		*valp = be16_to_cpu(c.u.mdio.rval);
6559f7917c00SJeff Kirsher 	return ret;
6560f7917c00SJeff Kirsher }
6561f7917c00SJeff Kirsher 
6562f7917c00SJeff Kirsher /**
6563f7917c00SJeff Kirsher  *	t4_mdio_wr - write a PHY register through MDIO
6564f7917c00SJeff Kirsher  *	@adap: the adapter
6565f7917c00SJeff Kirsher  *	@mbox: mailbox to use for the FW command
6566f7917c00SJeff Kirsher  *	@phy_addr: the PHY address
6567f7917c00SJeff Kirsher  *	@mmd: the PHY MMD to access (0 for clause 22 PHYs)
6568f7917c00SJeff Kirsher  *	@reg: the register to write
656929bbf5d7SRahul Lakkireddy  *	@val: value to write
6570f7917c00SJeff Kirsher  *
6571f7917c00SJeff Kirsher  *	Issues a FW command through the given mailbox to write a PHY register.
6572f7917c00SJeff Kirsher  */
t4_mdio_wr(struct adapter * adap,unsigned int mbox,unsigned int phy_addr,unsigned int mmd,unsigned int reg,u16 val)6573f7917c00SJeff Kirsher int t4_mdio_wr(struct adapter *adap, unsigned int mbox, unsigned int phy_addr,
6574f7917c00SJeff Kirsher 	       unsigned int mmd, unsigned int reg, u16 val)
6575f7917c00SJeff Kirsher {
6576f404f80cSHariprasad Shenai 	u32 ldst_addrspace;
6577f7917c00SJeff Kirsher 	struct fw_ldst_cmd c;
6578f7917c00SJeff Kirsher 
6579f7917c00SJeff Kirsher 	memset(&c, 0, sizeof(c));
6580f404f80cSHariprasad Shenai 	ldst_addrspace = FW_LDST_CMD_ADDRSPACE_V(FW_LDST_ADDRSPC_MDIO);
6581f404f80cSHariprasad Shenai 	c.op_to_addrspace = cpu_to_be32(FW_CMD_OP_V(FW_LDST_CMD) |
6582f404f80cSHariprasad Shenai 					FW_CMD_REQUEST_F | FW_CMD_WRITE_F |
6583f404f80cSHariprasad Shenai 					ldst_addrspace);
6584f404f80cSHariprasad Shenai 	c.cycles_to_len16 = cpu_to_be32(FW_LEN16(c));
6585f404f80cSHariprasad Shenai 	c.u.mdio.paddr_mmd = cpu_to_be16(FW_LDST_CMD_PADDR_V(phy_addr) |
65865167865aSHariprasad Shenai 					 FW_LDST_CMD_MMD_V(mmd));
6587f404f80cSHariprasad Shenai 	c.u.mdio.raddr = cpu_to_be16(reg);
6588f404f80cSHariprasad Shenai 	c.u.mdio.rval = cpu_to_be16(val);
6589f7917c00SJeff Kirsher 
6590f7917c00SJeff Kirsher 	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
6591f7917c00SJeff Kirsher }
6592f7917c00SJeff Kirsher 
6593f7917c00SJeff Kirsher /**
659468bce192SKumar Sanghvi  *	t4_sge_decode_idma_state - decode the idma state
659529bbf5d7SRahul Lakkireddy  *	@adapter: the adapter
659668bce192SKumar Sanghvi  *	@state: the state idma is stuck in
659768bce192SKumar Sanghvi  */
t4_sge_decode_idma_state(struct adapter * adapter,int state)659868bce192SKumar Sanghvi void t4_sge_decode_idma_state(struct adapter *adapter, int state)
659968bce192SKumar Sanghvi {
660068bce192SKumar Sanghvi 	static const char * const t4_decode[] = {
660168bce192SKumar Sanghvi 		"IDMA_IDLE",
660268bce192SKumar Sanghvi 		"IDMA_PUSH_MORE_CPL_FIFO",
660368bce192SKumar Sanghvi 		"IDMA_PUSH_CPL_MSG_HEADER_TO_FIFO",
660468bce192SKumar Sanghvi 		"Not used",
660568bce192SKumar Sanghvi 		"IDMA_PHYSADDR_SEND_PCIEHDR",
660668bce192SKumar Sanghvi 		"IDMA_PHYSADDR_SEND_PAYLOAD_FIRST",
660768bce192SKumar Sanghvi 		"IDMA_PHYSADDR_SEND_PAYLOAD",
660868bce192SKumar Sanghvi 		"IDMA_SEND_FIFO_TO_IMSG",
660968bce192SKumar Sanghvi 		"IDMA_FL_REQ_DATA_FL_PREP",
661068bce192SKumar Sanghvi 		"IDMA_FL_REQ_DATA_FL",
661168bce192SKumar Sanghvi 		"IDMA_FL_DROP",
661268bce192SKumar Sanghvi 		"IDMA_FL_H_REQ_HEADER_FL",
661368bce192SKumar Sanghvi 		"IDMA_FL_H_SEND_PCIEHDR",
661468bce192SKumar Sanghvi 		"IDMA_FL_H_PUSH_CPL_FIFO",
661568bce192SKumar Sanghvi 		"IDMA_FL_H_SEND_CPL",
661668bce192SKumar Sanghvi 		"IDMA_FL_H_SEND_IP_HDR_FIRST",
661768bce192SKumar Sanghvi 		"IDMA_FL_H_SEND_IP_HDR",
661868bce192SKumar Sanghvi 		"IDMA_FL_H_REQ_NEXT_HEADER_FL",
661968bce192SKumar Sanghvi 		"IDMA_FL_H_SEND_NEXT_PCIEHDR",
662068bce192SKumar Sanghvi 		"IDMA_FL_H_SEND_IP_HDR_PADDING",
662168bce192SKumar Sanghvi 		"IDMA_FL_D_SEND_PCIEHDR",
662268bce192SKumar Sanghvi 		"IDMA_FL_D_SEND_CPL_AND_IP_HDR",
662368bce192SKumar Sanghvi 		"IDMA_FL_D_REQ_NEXT_DATA_FL",
662468bce192SKumar Sanghvi 		"IDMA_FL_SEND_PCIEHDR",
662568bce192SKumar Sanghvi 		"IDMA_FL_PUSH_CPL_FIFO",
662668bce192SKumar Sanghvi 		"IDMA_FL_SEND_CPL",
662768bce192SKumar Sanghvi 		"IDMA_FL_SEND_PAYLOAD_FIRST",
662868bce192SKumar Sanghvi 		"IDMA_FL_SEND_PAYLOAD",
662968bce192SKumar Sanghvi 		"IDMA_FL_REQ_NEXT_DATA_FL",
663068bce192SKumar Sanghvi 		"IDMA_FL_SEND_NEXT_PCIEHDR",
663168bce192SKumar Sanghvi 		"IDMA_FL_SEND_PADDING",
663268bce192SKumar Sanghvi 		"IDMA_FL_SEND_COMPLETION_TO_IMSG",
663368bce192SKumar Sanghvi 		"IDMA_FL_SEND_FIFO_TO_IMSG",
663468bce192SKumar Sanghvi 		"IDMA_FL_REQ_DATAFL_DONE",
663568bce192SKumar Sanghvi 		"IDMA_FL_REQ_HEADERFL_DONE",
663668bce192SKumar Sanghvi 	};
663768bce192SKumar Sanghvi 	static const char * const t5_decode[] = {
663868bce192SKumar Sanghvi 		"IDMA_IDLE",
663968bce192SKumar Sanghvi 		"IDMA_ALMOST_IDLE",
664068bce192SKumar Sanghvi 		"IDMA_PUSH_MORE_CPL_FIFO",
664168bce192SKumar Sanghvi 		"IDMA_PUSH_CPL_MSG_HEADER_TO_FIFO",
664268bce192SKumar Sanghvi 		"IDMA_SGEFLRFLUSH_SEND_PCIEHDR",
664368bce192SKumar Sanghvi 		"IDMA_PHYSADDR_SEND_PCIEHDR",
664468bce192SKumar Sanghvi 		"IDMA_PHYSADDR_SEND_PAYLOAD_FIRST",
664568bce192SKumar Sanghvi 		"IDMA_PHYSADDR_SEND_PAYLOAD",
664668bce192SKumar Sanghvi 		"IDMA_SEND_FIFO_TO_IMSG",
664768bce192SKumar Sanghvi 		"IDMA_FL_REQ_DATA_FL",
664868bce192SKumar Sanghvi 		"IDMA_FL_DROP",
664968bce192SKumar Sanghvi 		"IDMA_FL_DROP_SEND_INC",
665068bce192SKumar Sanghvi 		"IDMA_FL_H_REQ_HEADER_FL",
665168bce192SKumar Sanghvi 		"IDMA_FL_H_SEND_PCIEHDR",
665268bce192SKumar Sanghvi 		"IDMA_FL_H_PUSH_CPL_FIFO",
665368bce192SKumar Sanghvi 		"IDMA_FL_H_SEND_CPL",
665468bce192SKumar Sanghvi 		"IDMA_FL_H_SEND_IP_HDR_FIRST",
665568bce192SKumar Sanghvi 		"IDMA_FL_H_SEND_IP_HDR",
665668bce192SKumar Sanghvi 		"IDMA_FL_H_REQ_NEXT_HEADER_FL",
665768bce192SKumar Sanghvi 		"IDMA_FL_H_SEND_NEXT_PCIEHDR",
665868bce192SKumar Sanghvi 		"IDMA_FL_H_SEND_IP_HDR_PADDING",
665968bce192SKumar Sanghvi 		"IDMA_FL_D_SEND_PCIEHDR",
666068bce192SKumar Sanghvi 		"IDMA_FL_D_SEND_CPL_AND_IP_HDR",
666168bce192SKumar Sanghvi 		"IDMA_FL_D_REQ_NEXT_DATA_FL",
666268bce192SKumar Sanghvi 		"IDMA_FL_SEND_PCIEHDR",
666368bce192SKumar Sanghvi 		"IDMA_FL_PUSH_CPL_FIFO",
666468bce192SKumar Sanghvi 		"IDMA_FL_SEND_CPL",
666568bce192SKumar Sanghvi 		"IDMA_FL_SEND_PAYLOAD_FIRST",
666668bce192SKumar Sanghvi 		"IDMA_FL_SEND_PAYLOAD",
666768bce192SKumar Sanghvi 		"IDMA_FL_REQ_NEXT_DATA_FL",
666868bce192SKumar Sanghvi 		"IDMA_FL_SEND_NEXT_PCIEHDR",
666968bce192SKumar Sanghvi 		"IDMA_FL_SEND_PADDING",
667068bce192SKumar Sanghvi 		"IDMA_FL_SEND_COMPLETION_TO_IMSG",
667168bce192SKumar Sanghvi 	};
66726df39753SHariprasad Shenai 	static const char * const t6_decode[] = {
66736df39753SHariprasad Shenai 		"IDMA_IDLE",
66746df39753SHariprasad Shenai 		"IDMA_PUSH_MORE_CPL_FIFO",
66756df39753SHariprasad Shenai 		"IDMA_PUSH_CPL_MSG_HEADER_TO_FIFO",
66766df39753SHariprasad Shenai 		"IDMA_SGEFLRFLUSH_SEND_PCIEHDR",
66776df39753SHariprasad Shenai 		"IDMA_PHYSADDR_SEND_PCIEHDR",
66786df39753SHariprasad Shenai 		"IDMA_PHYSADDR_SEND_PAYLOAD_FIRST",
66796df39753SHariprasad Shenai 		"IDMA_PHYSADDR_SEND_PAYLOAD",
66806df39753SHariprasad Shenai 		"IDMA_FL_REQ_DATA_FL",
66816df39753SHariprasad Shenai 		"IDMA_FL_DROP",
66826df39753SHariprasad Shenai 		"IDMA_FL_DROP_SEND_INC",
66836df39753SHariprasad Shenai 		"IDMA_FL_H_REQ_HEADER_FL",
66846df39753SHariprasad Shenai 		"IDMA_FL_H_SEND_PCIEHDR",
66856df39753SHariprasad Shenai 		"IDMA_FL_H_PUSH_CPL_FIFO",
66866df39753SHariprasad Shenai 		"IDMA_FL_H_SEND_CPL",
66876df39753SHariprasad Shenai 		"IDMA_FL_H_SEND_IP_HDR_FIRST",
66886df39753SHariprasad Shenai 		"IDMA_FL_H_SEND_IP_HDR",
66896df39753SHariprasad Shenai 		"IDMA_FL_H_REQ_NEXT_HEADER_FL",
66906df39753SHariprasad Shenai 		"IDMA_FL_H_SEND_NEXT_PCIEHDR",
66916df39753SHariprasad Shenai 		"IDMA_FL_H_SEND_IP_HDR_PADDING",
66926df39753SHariprasad Shenai 		"IDMA_FL_D_SEND_PCIEHDR",
66936df39753SHariprasad Shenai 		"IDMA_FL_D_SEND_CPL_AND_IP_HDR",
66946df39753SHariprasad Shenai 		"IDMA_FL_D_REQ_NEXT_DATA_FL",
66956df39753SHariprasad Shenai 		"IDMA_FL_SEND_PCIEHDR",
66966df39753SHariprasad Shenai 		"IDMA_FL_PUSH_CPL_FIFO",
66976df39753SHariprasad Shenai 		"IDMA_FL_SEND_CPL",
66986df39753SHariprasad Shenai 		"IDMA_FL_SEND_PAYLOAD_FIRST",
66996df39753SHariprasad Shenai 		"IDMA_FL_SEND_PAYLOAD",
67006df39753SHariprasad Shenai 		"IDMA_FL_REQ_NEXT_DATA_FL",
67016df39753SHariprasad Shenai 		"IDMA_FL_SEND_NEXT_PCIEHDR",
67026df39753SHariprasad Shenai 		"IDMA_FL_SEND_PADDING",
67036df39753SHariprasad Shenai 		"IDMA_FL_SEND_COMPLETION_TO_IMSG",
67046df39753SHariprasad Shenai 	};
670568bce192SKumar Sanghvi 	static const u32 sge_regs[] = {
6706f061de42SHariprasad Shenai 		SGE_DEBUG_DATA_LOW_INDEX_2_A,
6707f061de42SHariprasad Shenai 		SGE_DEBUG_DATA_LOW_INDEX_3_A,
6708f061de42SHariprasad Shenai 		SGE_DEBUG_DATA_HIGH_INDEX_10_A,
670968bce192SKumar Sanghvi 	};
671068bce192SKumar Sanghvi 	const char **sge_idma_decode;
671168bce192SKumar Sanghvi 	int sge_idma_decode_nstates;
671268bce192SKumar Sanghvi 	int i;
67136df39753SHariprasad Shenai 	unsigned int chip_version = CHELSIO_CHIP_VERSION(adapter->params.chip);
67146df39753SHariprasad Shenai 
67156df39753SHariprasad Shenai 	/* Select the right set of decode strings to dump depending on the
67166df39753SHariprasad Shenai 	 * adapter chip type.
67176df39753SHariprasad Shenai 	 */
67186df39753SHariprasad Shenai 	switch (chip_version) {
67196df39753SHariprasad Shenai 	case CHELSIO_T4:
67206df39753SHariprasad Shenai 		sge_idma_decode = (const char **)t4_decode;
67216df39753SHariprasad Shenai 		sge_idma_decode_nstates = ARRAY_SIZE(t4_decode);
67226df39753SHariprasad Shenai 		break;
67236df39753SHariprasad Shenai 
67246df39753SHariprasad Shenai 	case CHELSIO_T5:
67256df39753SHariprasad Shenai 		sge_idma_decode = (const char **)t5_decode;
67266df39753SHariprasad Shenai 		sge_idma_decode_nstates = ARRAY_SIZE(t5_decode);
67276df39753SHariprasad Shenai 		break;
67286df39753SHariprasad Shenai 
67296df39753SHariprasad Shenai 	case CHELSIO_T6:
67306df39753SHariprasad Shenai 		sge_idma_decode = (const char **)t6_decode;
67316df39753SHariprasad Shenai 		sge_idma_decode_nstates = ARRAY_SIZE(t6_decode);
67326df39753SHariprasad Shenai 		break;
67336df39753SHariprasad Shenai 
67346df39753SHariprasad Shenai 	default:
67356df39753SHariprasad Shenai 		dev_err(adapter->pdev_dev,
67366df39753SHariprasad Shenai 			"Unsupported chip version %d\n", chip_version);
67376df39753SHariprasad Shenai 		return;
67386df39753SHariprasad Shenai 	}
673968bce192SKumar Sanghvi 
674068bce192SKumar Sanghvi 	if (is_t4(adapter->params.chip)) {
674168bce192SKumar Sanghvi 		sge_idma_decode = (const char **)t4_decode;
674268bce192SKumar Sanghvi 		sge_idma_decode_nstates = ARRAY_SIZE(t4_decode);
674368bce192SKumar Sanghvi 	} else {
674468bce192SKumar Sanghvi 		sge_idma_decode = (const char **)t5_decode;
674568bce192SKumar Sanghvi 		sge_idma_decode_nstates = ARRAY_SIZE(t5_decode);
674668bce192SKumar Sanghvi 	}
674768bce192SKumar Sanghvi 
674868bce192SKumar Sanghvi 	if (state < sge_idma_decode_nstates)
674968bce192SKumar Sanghvi 		CH_WARN(adapter, "idma state %s\n", sge_idma_decode[state]);
675068bce192SKumar Sanghvi 	else
675168bce192SKumar Sanghvi 		CH_WARN(adapter, "idma state %d unknown\n", state);
675268bce192SKumar Sanghvi 
675368bce192SKumar Sanghvi 	for (i = 0; i < ARRAY_SIZE(sge_regs); i++)
675468bce192SKumar Sanghvi 		CH_WARN(adapter, "SGE register %#x value %#x\n",
675568bce192SKumar Sanghvi 			sge_regs[i], t4_read_reg(adapter, sge_regs[i]));
675668bce192SKumar Sanghvi }
675768bce192SKumar Sanghvi 
675868bce192SKumar Sanghvi /**
67595d700ecbSHariprasad Shenai  *      t4_sge_ctxt_flush - flush the SGE context cache
67605d700ecbSHariprasad Shenai  *      @adap: the adapter
67615d700ecbSHariprasad Shenai  *      @mbox: mailbox to use for the FW command
676229bbf5d7SRahul Lakkireddy  *      @ctxt_type: Egress or Ingress
67635d700ecbSHariprasad Shenai  *
67645d700ecbSHariprasad Shenai  *      Issues a FW command through the given mailbox to flush the
67655d700ecbSHariprasad Shenai  *      SGE context cache.
67665d700ecbSHariprasad Shenai  */
t4_sge_ctxt_flush(struct adapter * adap,unsigned int mbox,int ctxt_type)6767736c3b94SRahul Lakkireddy int t4_sge_ctxt_flush(struct adapter *adap, unsigned int mbox, int ctxt_type)
67685d700ecbSHariprasad Shenai {
67695d700ecbSHariprasad Shenai 	int ret;
67705d700ecbSHariprasad Shenai 	u32 ldst_addrspace;
67715d700ecbSHariprasad Shenai 	struct fw_ldst_cmd c;
67725d700ecbSHariprasad Shenai 
67735d700ecbSHariprasad Shenai 	memset(&c, 0, sizeof(c));
6774736c3b94SRahul Lakkireddy 	ldst_addrspace = FW_LDST_CMD_ADDRSPACE_V(ctxt_type == CTXT_EGRESS ?
6775736c3b94SRahul Lakkireddy 						 FW_LDST_ADDRSPC_SGE_EGRC :
6776736c3b94SRahul Lakkireddy 						 FW_LDST_ADDRSPC_SGE_INGC);
67775d700ecbSHariprasad Shenai 	c.op_to_addrspace = cpu_to_be32(FW_CMD_OP_V(FW_LDST_CMD) |
67785d700ecbSHariprasad Shenai 					FW_CMD_REQUEST_F | FW_CMD_READ_F |
67795d700ecbSHariprasad Shenai 					ldst_addrspace);
67805d700ecbSHariprasad Shenai 	c.cycles_to_len16 = cpu_to_be32(FW_LEN16(c));
67815d700ecbSHariprasad Shenai 	c.u.idctxt.msg_ctxtflush = cpu_to_be32(FW_LDST_CMD_CTXTFLUSH_F);
67825d700ecbSHariprasad Shenai 
67835d700ecbSHariprasad Shenai 	ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
67845d700ecbSHariprasad Shenai 	return ret;
67855d700ecbSHariprasad Shenai }
67865d700ecbSHariprasad Shenai 
67875d700ecbSHariprasad Shenai /**
6788172ca830SArkadiusz Drabczyk  *	t4_read_sge_dbqtimers - read SGE Doorbell Queue Timer values
678929bbf5d7SRahul Lakkireddy  *	@adap: the adapter
6790d429005fSVishal Kulkarni  *	@ndbqtimers: size of the provided SGE Doorbell Queue Timer table
6791d429005fSVishal Kulkarni  *	@dbqtimers: SGE Doorbell Queue Timer table
6792d429005fSVishal Kulkarni  *
6793d429005fSVishal Kulkarni  *	Reads the SGE Doorbell Queue Timer values into the provided table.
6794d429005fSVishal Kulkarni  *	Returns 0 on success (Firmware and Hardware support this feature),
6795d429005fSVishal Kulkarni  *	an error on failure.
6796d429005fSVishal Kulkarni  */
t4_read_sge_dbqtimers(struct adapter * adap,unsigned int ndbqtimers,u16 * dbqtimers)6797d429005fSVishal Kulkarni int t4_read_sge_dbqtimers(struct adapter *adap, unsigned int ndbqtimers,
6798d429005fSVishal Kulkarni 			  u16 *dbqtimers)
6799d429005fSVishal Kulkarni {
6800d429005fSVishal Kulkarni 	int ret, dbqtimerix;
6801d429005fSVishal Kulkarni 
6802d429005fSVishal Kulkarni 	ret = 0;
6803d429005fSVishal Kulkarni 	dbqtimerix = 0;
6804d429005fSVishal Kulkarni 	while (dbqtimerix < ndbqtimers) {
6805d429005fSVishal Kulkarni 		int nparams, param;
6806d429005fSVishal Kulkarni 		u32 params[7], vals[7];
6807d429005fSVishal Kulkarni 
6808d429005fSVishal Kulkarni 		nparams = ndbqtimers - dbqtimerix;
6809d429005fSVishal Kulkarni 		if (nparams > ARRAY_SIZE(params))
6810d429005fSVishal Kulkarni 			nparams = ARRAY_SIZE(params);
6811d429005fSVishal Kulkarni 
6812d429005fSVishal Kulkarni 		for (param = 0; param < nparams; param++)
6813d429005fSVishal Kulkarni 			params[param] =
6814d429005fSVishal Kulkarni 			  (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) |
6815d429005fSVishal Kulkarni 			   FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_DBQ_TIMER) |
6816d429005fSVishal Kulkarni 			   FW_PARAMS_PARAM_Y_V(dbqtimerix + param));
6817d429005fSVishal Kulkarni 		ret = t4_query_params(adap, adap->mbox, adap->pf, 0,
6818d429005fSVishal Kulkarni 				      nparams, params, vals);
6819d429005fSVishal Kulkarni 		if (ret)
6820d429005fSVishal Kulkarni 			break;
6821d429005fSVishal Kulkarni 
6822d429005fSVishal Kulkarni 		for (param = 0; param < nparams; param++)
6823d429005fSVishal Kulkarni 			dbqtimers[dbqtimerix++] = vals[param];
6824d429005fSVishal Kulkarni 	}
6825d429005fSVishal Kulkarni 	return ret;
6826d429005fSVishal Kulkarni }
6827d429005fSVishal Kulkarni 
6828d429005fSVishal Kulkarni /**
6829f7917c00SJeff Kirsher  *      t4_fw_hello - establish communication with FW
6830f7917c00SJeff Kirsher  *      @adap: the adapter
6831f7917c00SJeff Kirsher  *      @mbox: mailbox to use for the FW command
6832f7917c00SJeff Kirsher  *      @evt_mbox: mailbox to receive async FW events
6833f7917c00SJeff Kirsher  *      @master: specifies the caller's willingness to be the device master
6834636f9d37SVipul Pandya  *	@state: returns the current device state (if non-NULL)
6835f7917c00SJeff Kirsher  *
6836636f9d37SVipul Pandya  *	Issues a command to establish communication with FW.  Returns either
6837636f9d37SVipul Pandya  *	an error (negative integer) or the mailbox of the Master PF.
6838f7917c00SJeff Kirsher  */
t4_fw_hello(struct adapter * adap,unsigned int mbox,unsigned int evt_mbox,enum dev_master master,enum dev_state * state)6839f7917c00SJeff Kirsher int t4_fw_hello(struct adapter *adap, unsigned int mbox, unsigned int evt_mbox,
6840f7917c00SJeff Kirsher 		enum dev_master master, enum dev_state *state)
6841f7917c00SJeff Kirsher {
6842f7917c00SJeff Kirsher 	int ret;
6843f7917c00SJeff Kirsher 	struct fw_hello_cmd c;
6844636f9d37SVipul Pandya 	u32 v;
6845636f9d37SVipul Pandya 	unsigned int master_mbox;
6846636f9d37SVipul Pandya 	int retries = FW_CMD_HELLO_RETRIES;
6847f7917c00SJeff Kirsher 
6848636f9d37SVipul Pandya retry:
6849636f9d37SVipul Pandya 	memset(&c, 0, sizeof(c));
6850f7917c00SJeff Kirsher 	INIT_CMD(c, HELLO, WRITE);
6851f404f80cSHariprasad Shenai 	c.err_to_clearinit = cpu_to_be32(
68525167865aSHariprasad Shenai 		FW_HELLO_CMD_MASTERDIS_V(master == MASTER_CANT) |
68535167865aSHariprasad Shenai 		FW_HELLO_CMD_MASTERFORCE_V(master == MASTER_MUST) |
6854f404f80cSHariprasad Shenai 		FW_HELLO_CMD_MBMASTER_V(master == MASTER_MUST ?
6855f404f80cSHariprasad Shenai 					mbox : FW_HELLO_CMD_MBMASTER_M) |
68565167865aSHariprasad Shenai 		FW_HELLO_CMD_MBASYNCNOT_V(evt_mbox) |
68575167865aSHariprasad Shenai 		FW_HELLO_CMD_STAGE_V(fw_hello_cmd_stage_os) |
68585167865aSHariprasad Shenai 		FW_HELLO_CMD_CLEARINIT_F);
6859f7917c00SJeff Kirsher 
6860636f9d37SVipul Pandya 	/*
6861636f9d37SVipul Pandya 	 * Issue the HELLO command to the firmware.  If it's not successful
6862636f9d37SVipul Pandya 	 * but indicates that we got a "busy" or "timeout" condition, retry
686331d55c2dSHariprasad Shenai 	 * the HELLO until we exhaust our retry limit.  If we do exceed our
686431d55c2dSHariprasad Shenai 	 * retry limit, check to see if the firmware left us any error
686531d55c2dSHariprasad Shenai 	 * information and report that if so.
6866636f9d37SVipul Pandya 	 */
6867f7917c00SJeff Kirsher 	ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
6868636f9d37SVipul Pandya 	if (ret < 0) {
6869636f9d37SVipul Pandya 		if ((ret == -EBUSY || ret == -ETIMEDOUT) && retries-- > 0)
6870636f9d37SVipul Pandya 			goto retry;
6871f061de42SHariprasad Shenai 		if (t4_read_reg(adap, PCIE_FW_A) & PCIE_FW_ERR_F)
687231d55c2dSHariprasad Shenai 			t4_report_fw_error(adap);
6873636f9d37SVipul Pandya 		return ret;
6874636f9d37SVipul Pandya 	}
6875636f9d37SVipul Pandya 
6876f404f80cSHariprasad Shenai 	v = be32_to_cpu(c.err_to_clearinit);
68775167865aSHariprasad Shenai 	master_mbox = FW_HELLO_CMD_MBMASTER_G(v);
6878636f9d37SVipul Pandya 	if (state) {
68795167865aSHariprasad Shenai 		if (v & FW_HELLO_CMD_ERR_F)
6880f7917c00SJeff Kirsher 			*state = DEV_STATE_ERR;
68815167865aSHariprasad Shenai 		else if (v & FW_HELLO_CMD_INIT_F)
6882636f9d37SVipul Pandya 			*state = DEV_STATE_INIT;
6883f7917c00SJeff Kirsher 		else
6884f7917c00SJeff Kirsher 			*state = DEV_STATE_UNINIT;
6885f7917c00SJeff Kirsher 	}
6886636f9d37SVipul Pandya 
6887636f9d37SVipul Pandya 	/*
6888636f9d37SVipul Pandya 	 * If we're not the Master PF then we need to wait around for the
6889636f9d37SVipul Pandya 	 * Master PF Driver to finish setting up the adapter.
6890636f9d37SVipul Pandya 	 *
6891636f9d37SVipul Pandya 	 * Note that we also do this wait if we're a non-Master-capable PF and
6892636f9d37SVipul Pandya 	 * there is no current Master PF; a Master PF may show up momentarily
6893636f9d37SVipul Pandya 	 * and we wouldn't want to fail pointlessly.  (This can happen when an
6894636f9d37SVipul Pandya 	 * OS loads lots of different drivers rapidly at the same time).  In
6895636f9d37SVipul Pandya 	 * this case, the Master PF returned by the firmware will be
6896b2e1a3f0SHariprasad Shenai 	 * PCIE_FW_MASTER_M so the test below will work ...
6897636f9d37SVipul Pandya 	 */
68985167865aSHariprasad Shenai 	if ((v & (FW_HELLO_CMD_ERR_F|FW_HELLO_CMD_INIT_F)) == 0 &&
6899636f9d37SVipul Pandya 	    master_mbox != mbox) {
6900636f9d37SVipul Pandya 		int waiting = FW_CMD_HELLO_TIMEOUT;
6901636f9d37SVipul Pandya 
6902636f9d37SVipul Pandya 		/*
6903636f9d37SVipul Pandya 		 * Wait for the firmware to either indicate an error or
6904636f9d37SVipul Pandya 		 * initialized state.  If we see either of these we bail out
6905636f9d37SVipul Pandya 		 * and report the issue to the caller.  If we exhaust the
6906636f9d37SVipul Pandya 		 * "hello timeout" and we haven't exhausted our retries, try
6907636f9d37SVipul Pandya 		 * again.  Otherwise bail with a timeout error.
6908636f9d37SVipul Pandya 		 */
6909636f9d37SVipul Pandya 		for (;;) {
6910636f9d37SVipul Pandya 			u32 pcie_fw;
6911636f9d37SVipul Pandya 
6912636f9d37SVipul Pandya 			msleep(50);
6913636f9d37SVipul Pandya 			waiting -= 50;
6914636f9d37SVipul Pandya 
6915636f9d37SVipul Pandya 			/*
6916172ca830SArkadiusz Drabczyk 			 * If neither Error nor Initialized are indicated
6917172ca830SArkadiusz Drabczyk 			 * by the firmware keep waiting till we exhaust our
6918636f9d37SVipul Pandya 			 * timeout ... and then retry if we haven't exhausted
6919636f9d37SVipul Pandya 			 * our retries ...
6920636f9d37SVipul Pandya 			 */
6921f061de42SHariprasad Shenai 			pcie_fw = t4_read_reg(adap, PCIE_FW_A);
6922f061de42SHariprasad Shenai 			if (!(pcie_fw & (PCIE_FW_ERR_F|PCIE_FW_INIT_F))) {
6923636f9d37SVipul Pandya 				if (waiting <= 0) {
6924636f9d37SVipul Pandya 					if (retries-- > 0)
6925636f9d37SVipul Pandya 						goto retry;
6926636f9d37SVipul Pandya 
6927636f9d37SVipul Pandya 					return -ETIMEDOUT;
6928636f9d37SVipul Pandya 				}
6929636f9d37SVipul Pandya 				continue;
6930636f9d37SVipul Pandya 			}
6931636f9d37SVipul Pandya 
6932636f9d37SVipul Pandya 			/*
6933636f9d37SVipul Pandya 			 * We either have an Error or Initialized condition
6934636f9d37SVipul Pandya 			 * report errors preferentially.
6935636f9d37SVipul Pandya 			 */
6936636f9d37SVipul Pandya 			if (state) {
6937f061de42SHariprasad Shenai 				if (pcie_fw & PCIE_FW_ERR_F)
6938636f9d37SVipul Pandya 					*state = DEV_STATE_ERR;
6939f061de42SHariprasad Shenai 				else if (pcie_fw & PCIE_FW_INIT_F)
6940636f9d37SVipul Pandya 					*state = DEV_STATE_INIT;
6941636f9d37SVipul Pandya 			}
6942636f9d37SVipul Pandya 
6943636f9d37SVipul Pandya 			/*
6944636f9d37SVipul Pandya 			 * If we arrived before a Master PF was selected and
6945636f9d37SVipul Pandya 			 * there's not a valid Master PF, grab its identity
6946636f9d37SVipul Pandya 			 * for our caller.
6947636f9d37SVipul Pandya 			 */
6948b2e1a3f0SHariprasad Shenai 			if (master_mbox == PCIE_FW_MASTER_M &&
6949f061de42SHariprasad Shenai 			    (pcie_fw & PCIE_FW_MASTER_VLD_F))
6950b2e1a3f0SHariprasad Shenai 				master_mbox = PCIE_FW_MASTER_G(pcie_fw);
6951636f9d37SVipul Pandya 			break;
6952636f9d37SVipul Pandya 		}
6953636f9d37SVipul Pandya 	}
6954636f9d37SVipul Pandya 
6955636f9d37SVipul Pandya 	return master_mbox;
6956f7917c00SJeff Kirsher }
6957f7917c00SJeff Kirsher 
6958f7917c00SJeff Kirsher /**
6959f7917c00SJeff Kirsher  *	t4_fw_bye - end communication with FW
6960f7917c00SJeff Kirsher  *	@adap: the adapter
6961f7917c00SJeff Kirsher  *	@mbox: mailbox to use for the FW command
6962f7917c00SJeff Kirsher  *
6963f7917c00SJeff Kirsher  *	Issues a command to terminate communication with FW.
6964f7917c00SJeff Kirsher  */
t4_fw_bye(struct adapter * adap,unsigned int mbox)6965f7917c00SJeff Kirsher int t4_fw_bye(struct adapter *adap, unsigned int mbox)
6966f7917c00SJeff Kirsher {
6967f7917c00SJeff Kirsher 	struct fw_bye_cmd c;
6968f7917c00SJeff Kirsher 
69690062b15cSVipul Pandya 	memset(&c, 0, sizeof(c));
6970f7917c00SJeff Kirsher 	INIT_CMD(c, BYE, WRITE);
6971f7917c00SJeff Kirsher 	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
6972f7917c00SJeff Kirsher }
6973f7917c00SJeff Kirsher 
6974f7917c00SJeff Kirsher /**
6975e0333b1bSYang Shen  *	t4_early_init - ask FW to initialize the device
6976f7917c00SJeff Kirsher  *	@adap: the adapter
6977f7917c00SJeff Kirsher  *	@mbox: mailbox to use for the FW command
6978f7917c00SJeff Kirsher  *
6979f7917c00SJeff Kirsher  *	Issues a command to FW to partially initialize the device.  This
6980f7917c00SJeff Kirsher  *	performs initialization that generally doesn't depend on user input.
6981f7917c00SJeff Kirsher  */
t4_early_init(struct adapter * adap,unsigned int mbox)6982f7917c00SJeff Kirsher int t4_early_init(struct adapter *adap, unsigned int mbox)
6983f7917c00SJeff Kirsher {
6984f7917c00SJeff Kirsher 	struct fw_initialize_cmd c;
6985f7917c00SJeff Kirsher 
69860062b15cSVipul Pandya 	memset(&c, 0, sizeof(c));
6987f7917c00SJeff Kirsher 	INIT_CMD(c, INITIALIZE, WRITE);
6988f7917c00SJeff Kirsher 	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
6989f7917c00SJeff Kirsher }
6990f7917c00SJeff Kirsher 
6991f7917c00SJeff Kirsher /**
6992f7917c00SJeff Kirsher  *	t4_fw_reset - issue a reset to FW
6993f7917c00SJeff Kirsher  *	@adap: the adapter
6994f7917c00SJeff Kirsher  *	@mbox: mailbox to use for the FW command
6995f7917c00SJeff Kirsher  *	@reset: specifies the type of reset to perform
6996f7917c00SJeff Kirsher  *
6997f7917c00SJeff Kirsher  *	Issues a reset command of the specified type to FW.
6998f7917c00SJeff Kirsher  */
t4_fw_reset(struct adapter * adap,unsigned int mbox,int reset)6999f7917c00SJeff Kirsher int t4_fw_reset(struct adapter *adap, unsigned int mbox, int reset)
7000f7917c00SJeff Kirsher {
7001f7917c00SJeff Kirsher 	struct fw_reset_cmd c;
7002f7917c00SJeff Kirsher 
70030062b15cSVipul Pandya 	memset(&c, 0, sizeof(c));
7004f7917c00SJeff Kirsher 	INIT_CMD(c, RESET, WRITE);
7005f404f80cSHariprasad Shenai 	c.val = cpu_to_be32(reset);
7006f7917c00SJeff Kirsher 	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
7007f7917c00SJeff Kirsher }
7008f7917c00SJeff Kirsher 
7009f7917c00SJeff Kirsher /**
701026f7cbc0SVipul Pandya  *	t4_fw_halt - issue a reset/halt to FW and put uP into RESET
701126f7cbc0SVipul Pandya  *	@adap: the adapter
701226f7cbc0SVipul Pandya  *	@mbox: mailbox to use for the FW RESET command (if desired)
701326f7cbc0SVipul Pandya  *	@force: force uP into RESET even if FW RESET command fails
701426f7cbc0SVipul Pandya  *
701526f7cbc0SVipul Pandya  *	Issues a RESET command to firmware (if desired) with a HALT indication
701626f7cbc0SVipul Pandya  *	and then puts the microprocessor into RESET state.  The RESET command
701726f7cbc0SVipul Pandya  *	will only be issued if a legitimate mailbox is provided (mbox <=
7018b2e1a3f0SHariprasad Shenai  *	PCIE_FW_MASTER_M).
701926f7cbc0SVipul Pandya  *
702026f7cbc0SVipul Pandya  *	This is generally used in order for the host to safely manipulate the
702126f7cbc0SVipul Pandya  *	adapter without fear of conflicting with whatever the firmware might
702226f7cbc0SVipul Pandya  *	be doing.  The only way out of this state is to RESTART the firmware
702326f7cbc0SVipul Pandya  *	...
702426f7cbc0SVipul Pandya  */
t4_fw_halt(struct adapter * adap,unsigned int mbox,int force)7025de5b8677Sstephen hemminger static int t4_fw_halt(struct adapter *adap, unsigned int mbox, int force)
702626f7cbc0SVipul Pandya {
702726f7cbc0SVipul Pandya 	int ret = 0;
702826f7cbc0SVipul Pandya 
702926f7cbc0SVipul Pandya 	/*
703026f7cbc0SVipul Pandya 	 * If a legitimate mailbox is provided, issue a RESET command
703126f7cbc0SVipul Pandya 	 * with a HALT indication.
703226f7cbc0SVipul Pandya 	 */
7033b2e1a3f0SHariprasad Shenai 	if (mbox <= PCIE_FW_MASTER_M) {
703426f7cbc0SVipul Pandya 		struct fw_reset_cmd c;
703526f7cbc0SVipul Pandya 
703626f7cbc0SVipul Pandya 		memset(&c, 0, sizeof(c));
703726f7cbc0SVipul Pandya 		INIT_CMD(c, RESET, WRITE);
7038f404f80cSHariprasad Shenai 		c.val = cpu_to_be32(PIORST_F | PIORSTMODE_F);
7039f404f80cSHariprasad Shenai 		c.halt_pkd = cpu_to_be32(FW_RESET_CMD_HALT_F);
704026f7cbc0SVipul Pandya 		ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
704126f7cbc0SVipul Pandya 	}
704226f7cbc0SVipul Pandya 
704326f7cbc0SVipul Pandya 	/*
704426f7cbc0SVipul Pandya 	 * Normally we won't complete the operation if the firmware RESET
704526f7cbc0SVipul Pandya 	 * command fails but if our caller insists we'll go ahead and put the
704626f7cbc0SVipul Pandya 	 * uP into RESET.  This can be useful if the firmware is hung or even
704726f7cbc0SVipul Pandya 	 * missing ...  We'll have to take the risk of putting the uP into
704826f7cbc0SVipul Pandya 	 * RESET without the cooperation of firmware in that case.
704926f7cbc0SVipul Pandya 	 *
705026f7cbc0SVipul Pandya 	 * We also force the firmware's HALT flag to be on in case we bypassed
705126f7cbc0SVipul Pandya 	 * the firmware RESET command above or we're dealing with old firmware
705226f7cbc0SVipul Pandya 	 * which doesn't have the HALT capability.  This will serve as a flag
705326f7cbc0SVipul Pandya 	 * for the incoming firmware to know that it's coming out of a HALT
705426f7cbc0SVipul Pandya 	 * rather than a RESET ... if it's new enough to understand that ...
705526f7cbc0SVipul Pandya 	 */
705626f7cbc0SVipul Pandya 	if (ret == 0 || force) {
705789c3a86cSHariprasad Shenai 		t4_set_reg_field(adap, CIM_BOOT_CFG_A, UPCRST_F, UPCRST_F);
7058f061de42SHariprasad Shenai 		t4_set_reg_field(adap, PCIE_FW_A, PCIE_FW_HALT_F,
7059b2e1a3f0SHariprasad Shenai 				 PCIE_FW_HALT_F);
706026f7cbc0SVipul Pandya 	}
706126f7cbc0SVipul Pandya 
706226f7cbc0SVipul Pandya 	/*
706326f7cbc0SVipul Pandya 	 * And we always return the result of the firmware RESET command
706426f7cbc0SVipul Pandya 	 * even when we force the uP into RESET ...
706526f7cbc0SVipul Pandya 	 */
706626f7cbc0SVipul Pandya 	return ret;
706726f7cbc0SVipul Pandya }
706826f7cbc0SVipul Pandya 
706926f7cbc0SVipul Pandya /**
707026f7cbc0SVipul Pandya  *	t4_fw_restart - restart the firmware by taking the uP out of RESET
707126f7cbc0SVipul Pandya  *	@adap: the adapter
707229bbf5d7SRahul Lakkireddy  *	@mbox: mailbox to use for the FW command
707326f7cbc0SVipul Pandya  *	@reset: if we want to do a RESET to restart things
707426f7cbc0SVipul Pandya  *
707526f7cbc0SVipul Pandya  *	Restart firmware previously halted by t4_fw_halt().  On successful
707626f7cbc0SVipul Pandya  *	return the previous PF Master remains as the new PF Master and there
707726f7cbc0SVipul Pandya  *	is no need to issue a new HELLO command, etc.
707826f7cbc0SVipul Pandya  *
707926f7cbc0SVipul Pandya  *	We do this in two ways:
708026f7cbc0SVipul Pandya  *
708126f7cbc0SVipul Pandya  *	 1. If we're dealing with newer firmware we'll simply want to take
708226f7cbc0SVipul Pandya  *	    the chip's microprocessor out of RESET.  This will cause the
708326f7cbc0SVipul Pandya  *	    firmware to start up from its start vector.  And then we'll loop
708426f7cbc0SVipul Pandya  *	    until the firmware indicates it's started again (PCIE_FW.HALT
708526f7cbc0SVipul Pandya  *	    reset to 0) or we timeout.
708626f7cbc0SVipul Pandya  *
708726f7cbc0SVipul Pandya  *	 2. If we're dealing with older firmware then we'll need to RESET
708826f7cbc0SVipul Pandya  *	    the chip since older firmware won't recognize the PCIE_FW.HALT
708926f7cbc0SVipul Pandya  *	    flag and automatically RESET itself on startup.
709026f7cbc0SVipul Pandya  */
t4_fw_restart(struct adapter * adap,unsigned int mbox,int reset)7091de5b8677Sstephen hemminger static int t4_fw_restart(struct adapter *adap, unsigned int mbox, int reset)
709226f7cbc0SVipul Pandya {
709326f7cbc0SVipul Pandya 	if (reset) {
709426f7cbc0SVipul Pandya 		/*
709526f7cbc0SVipul Pandya 		 * Since we're directing the RESET instead of the firmware
709626f7cbc0SVipul Pandya 		 * doing it automatically, we need to clear the PCIE_FW.HALT
709726f7cbc0SVipul Pandya 		 * bit.
709826f7cbc0SVipul Pandya 		 */
7099f061de42SHariprasad Shenai 		t4_set_reg_field(adap, PCIE_FW_A, PCIE_FW_HALT_F, 0);
710026f7cbc0SVipul Pandya 
710126f7cbc0SVipul Pandya 		/*
710226f7cbc0SVipul Pandya 		 * If we've been given a valid mailbox, first try to get the
710326f7cbc0SVipul Pandya 		 * firmware to do the RESET.  If that works, great and we can
710426f7cbc0SVipul Pandya 		 * return success.  Otherwise, if we haven't been given a
710526f7cbc0SVipul Pandya 		 * valid mailbox or the RESET command failed, fall back to
710626f7cbc0SVipul Pandya 		 * hitting the chip with a hammer.
710726f7cbc0SVipul Pandya 		 */
7108b2e1a3f0SHariprasad Shenai 		if (mbox <= PCIE_FW_MASTER_M) {
710989c3a86cSHariprasad Shenai 			t4_set_reg_field(adap, CIM_BOOT_CFG_A, UPCRST_F, 0);
711026f7cbc0SVipul Pandya 			msleep(100);
711126f7cbc0SVipul Pandya 			if (t4_fw_reset(adap, mbox,
71120d804338SHariprasad Shenai 					PIORST_F | PIORSTMODE_F) == 0)
711326f7cbc0SVipul Pandya 				return 0;
711426f7cbc0SVipul Pandya 		}
711526f7cbc0SVipul Pandya 
71160d804338SHariprasad Shenai 		t4_write_reg(adap, PL_RST_A, PIORST_F | PIORSTMODE_F);
711726f7cbc0SVipul Pandya 		msleep(2000);
711826f7cbc0SVipul Pandya 	} else {
711926f7cbc0SVipul Pandya 		int ms;
712026f7cbc0SVipul Pandya 
712189c3a86cSHariprasad Shenai 		t4_set_reg_field(adap, CIM_BOOT_CFG_A, UPCRST_F, 0);
712226f7cbc0SVipul Pandya 		for (ms = 0; ms < FW_CMD_MAX_TIMEOUT; ) {
7123f061de42SHariprasad Shenai 			if (!(t4_read_reg(adap, PCIE_FW_A) & PCIE_FW_HALT_F))
712426f7cbc0SVipul Pandya 				return 0;
712526f7cbc0SVipul Pandya 			msleep(100);
712626f7cbc0SVipul Pandya 			ms += 100;
712726f7cbc0SVipul Pandya 		}
712826f7cbc0SVipul Pandya 		return -ETIMEDOUT;
712926f7cbc0SVipul Pandya 	}
713026f7cbc0SVipul Pandya 	return 0;
713126f7cbc0SVipul Pandya }
713226f7cbc0SVipul Pandya 
713326f7cbc0SVipul Pandya /**
713426f7cbc0SVipul Pandya  *	t4_fw_upgrade - perform all of the steps necessary to upgrade FW
713526f7cbc0SVipul Pandya  *	@adap: the adapter
713626f7cbc0SVipul Pandya  *	@mbox: mailbox to use for the FW RESET command (if desired)
713726f7cbc0SVipul Pandya  *	@fw_data: the firmware image to write
713826f7cbc0SVipul Pandya  *	@size: image size
713926f7cbc0SVipul Pandya  *	@force: force upgrade even if firmware doesn't cooperate
714026f7cbc0SVipul Pandya  *
714126f7cbc0SVipul Pandya  *	Perform all of the steps necessary for upgrading an adapter's
714226f7cbc0SVipul Pandya  *	firmware image.  Normally this requires the cooperation of the
714326f7cbc0SVipul Pandya  *	existing firmware in order to halt all existing activities
714426f7cbc0SVipul Pandya  *	but if an invalid mailbox token is passed in we skip that step
714526f7cbc0SVipul Pandya  *	(though we'll still put the adapter microprocessor into RESET in
714626f7cbc0SVipul Pandya  *	that case).
714726f7cbc0SVipul Pandya  *
714826f7cbc0SVipul Pandya  *	On successful return the new firmware will have been loaded and
714926f7cbc0SVipul Pandya  *	the adapter will have been fully RESET losing all previous setup
715026f7cbc0SVipul Pandya  *	state.  On unsuccessful return the adapter may be completely hosed ...
715126f7cbc0SVipul Pandya  *	positive errno indicates that the adapter is ~probably~ intact, a
715226f7cbc0SVipul Pandya  *	negative errno indicates that things are looking bad ...
715326f7cbc0SVipul Pandya  */
t4_fw_upgrade(struct adapter * adap,unsigned int mbox,const u8 * fw_data,unsigned int size,int force)715422c0b963SHariprasad Shenai int t4_fw_upgrade(struct adapter *adap, unsigned int mbox,
715526f7cbc0SVipul Pandya 		  const u8 *fw_data, unsigned int size, int force)
715626f7cbc0SVipul Pandya {
715726f7cbc0SVipul Pandya 	const struct fw_hdr *fw_hdr = (const struct fw_hdr *)fw_data;
715826f7cbc0SVipul Pandya 	int reset, ret;
715926f7cbc0SVipul Pandya 
716079af221dSHariprasad Shenai 	if (!t4_fw_matches_chip(adap, fw_hdr))
716179af221dSHariprasad Shenai 		return -EINVAL;
716279af221dSHariprasad Shenai 
716380f61f19SArjun Vynipadath 	/* Disable CXGB4_FW_OK flag so that mbox commands with CXGB4_FW_OK flag
716480f61f19SArjun Vynipadath 	 * set wont be sent when we are flashing FW.
716526747211SArjun Vynipadath 	 */
716680f61f19SArjun Vynipadath 	adap->flags &= ~CXGB4_FW_OK;
716726747211SArjun Vynipadath 
716826f7cbc0SVipul Pandya 	ret = t4_fw_halt(adap, mbox, force);
716926f7cbc0SVipul Pandya 	if (ret < 0 && !force)
717026747211SArjun Vynipadath 		goto out;
717126f7cbc0SVipul Pandya 
717226f7cbc0SVipul Pandya 	ret = t4_load_fw(adap, fw_data, size);
717326f7cbc0SVipul Pandya 	if (ret < 0)
717426747211SArjun Vynipadath 		goto out;
717526f7cbc0SVipul Pandya 
717626f7cbc0SVipul Pandya 	/*
71774da18741SArjun Vynipadath 	 * If there was a Firmware Configuration File stored in FLASH,
71784da18741SArjun Vynipadath 	 * there's a good chance that it won't be compatible with the new
71794da18741SArjun Vynipadath 	 * Firmware.  In order to prevent difficult to diagnose adapter
71804da18741SArjun Vynipadath 	 * initialization issues, we clear out the Firmware Configuration File
71814da18741SArjun Vynipadath 	 * portion of the FLASH .  The user will need to re-FLASH a new
71824da18741SArjun Vynipadath 	 * Firmware Configuration File which is compatible with the new
71834da18741SArjun Vynipadath 	 * Firmware if that's desired.
71844da18741SArjun Vynipadath 	 */
71854da18741SArjun Vynipadath 	(void)t4_load_cfg(adap, NULL, 0);
71864da18741SArjun Vynipadath 
71874da18741SArjun Vynipadath 	/*
718826f7cbc0SVipul Pandya 	 * Older versions of the firmware don't understand the new
718926f7cbc0SVipul Pandya 	 * PCIE_FW.HALT flag and so won't know to perform a RESET when they
719026f7cbc0SVipul Pandya 	 * restart.  So for newly loaded older firmware we'll have to do the
719126f7cbc0SVipul Pandya 	 * RESET for it so it starts up on a clean slate.  We can tell if
719226f7cbc0SVipul Pandya 	 * the newly loaded firmware will handle this right by checking
719326f7cbc0SVipul Pandya 	 * its header flags to see if it advertises the capability.
719426f7cbc0SVipul Pandya 	 */
7195f404f80cSHariprasad Shenai 	reset = ((be32_to_cpu(fw_hdr->flags) & FW_HDR_FLAGS_RESET_HALT) == 0);
719626747211SArjun Vynipadath 	ret = t4_fw_restart(adap, mbox, reset);
719726747211SArjun Vynipadath 
719826747211SArjun Vynipadath 	/* Grab potentially new Firmware Device Log parameters so we can see
719926747211SArjun Vynipadath 	 * how healthy the new Firmware is.  It's okay to contact the new
720026747211SArjun Vynipadath 	 * Firmware for these parameters even though, as far as it's
720126747211SArjun Vynipadath 	 * concerned, we've never said "HELLO" to it ...
720226747211SArjun Vynipadath 	 */
720326747211SArjun Vynipadath 	(void)t4_init_devlog_params(adap);
720426747211SArjun Vynipadath out:
720580f61f19SArjun Vynipadath 	adap->flags |= CXGB4_FW_OK;
720626747211SArjun Vynipadath 	return ret;
720726f7cbc0SVipul Pandya }
720826f7cbc0SVipul Pandya 
7209636f9d37SVipul Pandya /**
7210acac5962SHariprasad Shenai  *	t4_fl_pkt_align - return the fl packet alignment
7211acac5962SHariprasad Shenai  *	@adap: the adapter
7212acac5962SHariprasad Shenai  *
7213acac5962SHariprasad Shenai  *	T4 has a single field to specify the packing and padding boundary.
7214acac5962SHariprasad Shenai  *	T5 onwards has separate fields for this and hence the alignment for
7215acac5962SHariprasad Shenai  *	next packet offset is maximum of these two.
7216acac5962SHariprasad Shenai  *
7217acac5962SHariprasad Shenai  */
t4_fl_pkt_align(struct adapter * adap)7218acac5962SHariprasad Shenai int t4_fl_pkt_align(struct adapter *adap)
7219acac5962SHariprasad Shenai {
7220acac5962SHariprasad Shenai 	u32 sge_control, sge_control2;
7221acac5962SHariprasad Shenai 	unsigned int ingpadboundary, ingpackboundary, fl_align, ingpad_shift;
7222acac5962SHariprasad Shenai 
7223acac5962SHariprasad Shenai 	sge_control = t4_read_reg(adap, SGE_CONTROL_A);
7224acac5962SHariprasad Shenai 
7225acac5962SHariprasad Shenai 	/* T4 uses a single control field to specify both the PCIe Padding and
7226acac5962SHariprasad Shenai 	 * Packing Boundary.  T5 introduced the ability to specify these
7227acac5962SHariprasad Shenai 	 * separately.  The actual Ingress Packet Data alignment boundary
7228acac5962SHariprasad Shenai 	 * within Packed Buffer Mode is the maximum of these two
7229acac5962SHariprasad Shenai 	 * specifications.  (Note that it makes no real practical sense to
7230172ca830SArkadiusz Drabczyk 	 * have the Padding Boundary be larger than the Packing Boundary but you
7231acac5962SHariprasad Shenai 	 * could set the chip up that way and, in fact, legacy T4 code would
7232acac5962SHariprasad Shenai 	 * end doing this because it would initialize the Padding Boundary and
7233acac5962SHariprasad Shenai 	 * leave the Packing Boundary initialized to 0 (16 bytes).)
7234acac5962SHariprasad Shenai 	 * Padding Boundary values in T6 starts from 8B,
7235acac5962SHariprasad Shenai 	 * where as it is 32B for T4 and T5.
7236acac5962SHariprasad Shenai 	 */
7237acac5962SHariprasad Shenai 	if (CHELSIO_CHIP_VERSION(adap->params.chip) <= CHELSIO_T5)
7238acac5962SHariprasad Shenai 		ingpad_shift = INGPADBOUNDARY_SHIFT_X;
7239acac5962SHariprasad Shenai 	else
7240acac5962SHariprasad Shenai 		ingpad_shift = T6_INGPADBOUNDARY_SHIFT_X;
7241acac5962SHariprasad Shenai 
7242acac5962SHariprasad Shenai 	ingpadboundary = 1 << (INGPADBOUNDARY_G(sge_control) + ingpad_shift);
7243acac5962SHariprasad Shenai 
7244acac5962SHariprasad Shenai 	fl_align = ingpadboundary;
7245acac5962SHariprasad Shenai 	if (!is_t4(adap->params.chip)) {
7246acac5962SHariprasad Shenai 		/* T5 has a weird interpretation of one of the PCIe Packing
7247acac5962SHariprasad Shenai 		 * Boundary values.  No idea why ...
7248acac5962SHariprasad Shenai 		 */
7249acac5962SHariprasad Shenai 		sge_control2 = t4_read_reg(adap, SGE_CONTROL2_A);
7250acac5962SHariprasad Shenai 		ingpackboundary = INGPACKBOUNDARY_G(sge_control2);
7251acac5962SHariprasad Shenai 		if (ingpackboundary == INGPACKBOUNDARY_16B_X)
7252acac5962SHariprasad Shenai 			ingpackboundary = 16;
7253acac5962SHariprasad Shenai 		else
7254acac5962SHariprasad Shenai 			ingpackboundary = 1 << (ingpackboundary +
7255acac5962SHariprasad Shenai 						INGPACKBOUNDARY_SHIFT_X);
7256acac5962SHariprasad Shenai 
7257acac5962SHariprasad Shenai 		fl_align = max(ingpadboundary, ingpackboundary);
7258acac5962SHariprasad Shenai 	}
7259acac5962SHariprasad Shenai 	return fl_align;
7260acac5962SHariprasad Shenai }
7261acac5962SHariprasad Shenai 
7262acac5962SHariprasad Shenai /**
7263636f9d37SVipul Pandya  *	t4_fixup_host_params - fix up host-dependent parameters
7264636f9d37SVipul Pandya  *	@adap: the adapter
7265636f9d37SVipul Pandya  *	@page_size: the host's Base Page Size
7266636f9d37SVipul Pandya  *	@cache_line_size: the host's Cache Line Size
7267636f9d37SVipul Pandya  *
7268636f9d37SVipul Pandya  *	Various registers in T4 contain values which are dependent on the
7269636f9d37SVipul Pandya  *	host's Base Page and Cache Line Sizes.  This function will fix all of
7270636f9d37SVipul Pandya  *	those registers with the appropriate values as passed in ...
7271636f9d37SVipul Pandya  */
t4_fixup_host_params(struct adapter * adap,unsigned int page_size,unsigned int cache_line_size)7272636f9d37SVipul Pandya int t4_fixup_host_params(struct adapter *adap, unsigned int page_size,
7273636f9d37SVipul Pandya 			 unsigned int cache_line_size)
7274636f9d37SVipul Pandya {
7275636f9d37SVipul Pandya 	unsigned int page_shift = fls(page_size) - 1;
7276ab0610efSVishal Kulkarni 	unsigned int sge_hps = page_shift - 10;
7277636f9d37SVipul Pandya 	unsigned int stat_len = cache_line_size > 64 ? 128 : 64;
7278636f9d37SVipul Pandya 	unsigned int fl_align = cache_line_size < 32 ? 32 : cache_line_size;
7279636f9d37SVipul Pandya 	unsigned int fl_align_log = fls(fl_align) - 1;
7280636f9d37SVipul Pandya 
7281ab0610efSVishal Kulkarni 	t4_write_reg(adap, SGE_HOST_PAGE_SIZE_A,
7282ab0610efSVishal Kulkarni 		     HOSTPAGESIZEPF0_V(sge_hps) |
7283ab0610efSVishal Kulkarni 		     HOSTPAGESIZEPF1_V(sge_hps) |
7284ab0610efSVishal Kulkarni 		     HOSTPAGESIZEPF2_V(sge_hps) |
7285ab0610efSVishal Kulkarni 		     HOSTPAGESIZEPF3_V(sge_hps) |
7286ab0610efSVishal Kulkarni 		     HOSTPAGESIZEPF4_V(sge_hps) |
7287ab0610efSVishal Kulkarni 		     HOSTPAGESIZEPF5_V(sge_hps) |
7288ab0610efSVishal Kulkarni 		     HOSTPAGESIZEPF6_V(sge_hps) |
7289ab0610efSVishal Kulkarni 		     HOSTPAGESIZEPF7_V(sge_hps));
7290ab0610efSVishal Kulkarni 
7291ce8f407aSHariprasad Shenai 	if (is_t4(adap->params.chip)) {
7292f612b815SHariprasad Shenai 		t4_set_reg_field(adap, SGE_CONTROL_A,
7293f612b815SHariprasad Shenai 				 INGPADBOUNDARY_V(INGPADBOUNDARY_M) |
7294f612b815SHariprasad Shenai 				 EGRSTATUSPAGESIZE_F,
7295f612b815SHariprasad Shenai 				 INGPADBOUNDARY_V(fl_align_log -
7296f612b815SHariprasad Shenai 						  INGPADBOUNDARY_SHIFT_X) |
7297f612b815SHariprasad Shenai 				 EGRSTATUSPAGESIZE_V(stat_len != 64));
7298ce8f407aSHariprasad Shenai 	} else {
7299bb58d079SArjun Vynipadath 		unsigned int pack_align;
7300bb58d079SArjun Vynipadath 		unsigned int ingpad, ingpack;
7301bb58d079SArjun Vynipadath 
7302ce8f407aSHariprasad Shenai 		/* T5 introduced the separation of the Free List Padding and
7303ce8f407aSHariprasad Shenai 		 * Packing Boundaries.  Thus, we can select a smaller Padding
7304ce8f407aSHariprasad Shenai 		 * Boundary to avoid uselessly chewing up PCIe Link and Memory
7305ce8f407aSHariprasad Shenai 		 * Bandwidth, and use a Packing Boundary which is large enough
7306ce8f407aSHariprasad Shenai 		 * to avoid false sharing between CPUs, etc.
7307ce8f407aSHariprasad Shenai 		 *
7308ce8f407aSHariprasad Shenai 		 * For the PCI Link, the smaller the Padding Boundary the
7309ce8f407aSHariprasad Shenai 		 * better.  For the Memory Controller, a smaller Padding
7310ce8f407aSHariprasad Shenai 		 * Boundary is better until we cross under the Memory Line
7311ce8f407aSHariprasad Shenai 		 * Size (the minimum unit of transfer to/from Memory).  If we
7312ce8f407aSHariprasad Shenai 		 * have a Padding Boundary which is smaller than the Memory
7313ce8f407aSHariprasad Shenai 		 * Line Size, that'll involve a Read-Modify-Write cycle on the
7314bb58d079SArjun Vynipadath 		 * Memory Controller which is never good.
7315ce8f407aSHariprasad Shenai 		 */
7316bb58d079SArjun Vynipadath 
7317bb58d079SArjun Vynipadath 		/* We want the Packing Boundary to be based on the Cache Line
7318bb58d079SArjun Vynipadath 		 * Size in order to help avoid False Sharing performance
7319bb58d079SArjun Vynipadath 		 * issues between CPUs, etc.  We also want the Packing
7320bb58d079SArjun Vynipadath 		 * Boundary to incorporate the PCI-E Maximum Payload Size.  We
7321bb58d079SArjun Vynipadath 		 * get best performance when the Packing Boundary is a
7322bb58d079SArjun Vynipadath 		 * multiple of the Maximum Payload Size.
7323bb58d079SArjun Vynipadath 		 */
7324bb58d079SArjun Vynipadath 		pack_align = fl_align;
73256133b920SFrederick Lawler 		if (pci_is_pcie(adap->pdev)) {
7326bb58d079SArjun Vynipadath 			unsigned int mps, mps_log;
7327bb58d079SArjun Vynipadath 			u16 devctl;
7328bb58d079SArjun Vynipadath 
7329bb58d079SArjun Vynipadath 			/* The PCIe Device Control Maximum Payload Size field
7330bb58d079SArjun Vynipadath 			 * [bits 7:5] encodes sizes as powers of 2 starting at
7331bb58d079SArjun Vynipadath 			 * 128 bytes.
7332bb58d079SArjun Vynipadath 			 */
73336133b920SFrederick Lawler 			pcie_capability_read_word(adap->pdev, PCI_EXP_DEVCTL,
7334bb58d079SArjun Vynipadath 						  &devctl);
7335bb58d079SArjun Vynipadath 			mps_log = ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5) + 7;
7336bb58d079SArjun Vynipadath 			mps = 1 << mps_log;
7337bb58d079SArjun Vynipadath 			if (mps > pack_align)
7338bb58d079SArjun Vynipadath 				pack_align = mps;
7339ce8f407aSHariprasad Shenai 		}
7340acac5962SHariprasad Shenai 
7341bb58d079SArjun Vynipadath 		/* N.B. T5/T6 have a crazy special interpretation of the "0"
7342bb58d079SArjun Vynipadath 		 * value for the Packing Boundary.  This corresponds to 16
7343bb58d079SArjun Vynipadath 		 * bytes instead of the expected 32 bytes.  So if we want 32
7344bb58d079SArjun Vynipadath 		 * bytes, the best we can really do is 64 bytes ...
7345bb58d079SArjun Vynipadath 		 */
7346bb58d079SArjun Vynipadath 		if (pack_align <= 16) {
7347bb58d079SArjun Vynipadath 			ingpack = INGPACKBOUNDARY_16B_X;
7348bb58d079SArjun Vynipadath 			fl_align = 16;
7349bb58d079SArjun Vynipadath 		} else if (pack_align == 32) {
7350bb58d079SArjun Vynipadath 			ingpack = INGPACKBOUNDARY_64B_X;
7351bb58d079SArjun Vynipadath 			fl_align = 64;
7352bb58d079SArjun Vynipadath 		} else {
7353bb58d079SArjun Vynipadath 			unsigned int pack_align_log = fls(pack_align) - 1;
7354bb58d079SArjun Vynipadath 
7355bb58d079SArjun Vynipadath 			ingpack = pack_align_log - INGPACKBOUNDARY_SHIFT_X;
7356bb58d079SArjun Vynipadath 			fl_align = pack_align;
7357bb58d079SArjun Vynipadath 		}
7358bb58d079SArjun Vynipadath 
7359bb58d079SArjun Vynipadath 		/* Use the smallest Ingress Padding which isn't smaller than
7360bb58d079SArjun Vynipadath 		 * the Memory Controller Read/Write Size.  We'll take that as
7361bb58d079SArjun Vynipadath 		 * being 8 bytes since we don't know of any system with a
7362bb58d079SArjun Vynipadath 		 * wider Memory Controller Bus Width.
7363bb58d079SArjun Vynipadath 		 */
7364acac5962SHariprasad Shenai 		if (is_t5(adap->params.chip))
7365bb58d079SArjun Vynipadath 			ingpad = INGPADBOUNDARY_32B_X;
7366acac5962SHariprasad Shenai 		else
7367bb58d079SArjun Vynipadath 			ingpad = T6_INGPADBOUNDARY_8B_X;
7368acac5962SHariprasad Shenai 
7369f612b815SHariprasad Shenai 		t4_set_reg_field(adap, SGE_CONTROL_A,
7370f612b815SHariprasad Shenai 				 INGPADBOUNDARY_V(INGPADBOUNDARY_M) |
7371f612b815SHariprasad Shenai 				 EGRSTATUSPAGESIZE_F,
7372acac5962SHariprasad Shenai 				 INGPADBOUNDARY_V(ingpad) |
7373f612b815SHariprasad Shenai 				 EGRSTATUSPAGESIZE_V(stat_len != 64));
7374ce8f407aSHariprasad Shenai 		t4_set_reg_field(adap, SGE_CONTROL2_A,
7375ce8f407aSHariprasad Shenai 				 INGPACKBOUNDARY_V(INGPACKBOUNDARY_M),
7376bb58d079SArjun Vynipadath 				 INGPACKBOUNDARY_V(ingpack));
7377ce8f407aSHariprasad Shenai 	}
7378636f9d37SVipul Pandya 	/*
7379636f9d37SVipul Pandya 	 * Adjust various SGE Free List Host Buffer Sizes.
7380636f9d37SVipul Pandya 	 *
7381636f9d37SVipul Pandya 	 * This is something of a crock since we're using fixed indices into
7382636f9d37SVipul Pandya 	 * the array which are also known by the sge.c code and the T4
7383636f9d37SVipul Pandya 	 * Firmware Configuration File.  We need to come up with a much better
7384636f9d37SVipul Pandya 	 * approach to managing this array.  For now, the first four entries
7385636f9d37SVipul Pandya 	 * are:
7386636f9d37SVipul Pandya 	 *
7387636f9d37SVipul Pandya 	 *   0: Host Page Size
7388636f9d37SVipul Pandya 	 *   1: 64KB
7389636f9d37SVipul Pandya 	 *   2: Buffer size corresponding to 1500 byte MTU (unpacked mode)
7390636f9d37SVipul Pandya 	 *   3: Buffer size corresponding to 9000 byte MTU (unpacked mode)
7391636f9d37SVipul Pandya 	 *
7392636f9d37SVipul Pandya 	 * For the single-MTU buffers in unpacked mode we need to include
7393636f9d37SVipul Pandya 	 * space for the SGE Control Packet Shift, 14 byte Ethernet header,
7394636f9d37SVipul Pandya 	 * possible 4 byte VLAN tag, all rounded up to the next Ingress Packet
7395dbedd44eSJoe Perches 	 * Padding boundary.  All of these are accommodated in the Factory
7396636f9d37SVipul Pandya 	 * Default Firmware Configuration File but we need to adjust it for
7397636f9d37SVipul Pandya 	 * this host's cache line size.
7398636f9d37SVipul Pandya 	 */
7399f612b815SHariprasad Shenai 	t4_write_reg(adap, SGE_FL_BUFFER_SIZE0_A, page_size);
7400f612b815SHariprasad Shenai 	t4_write_reg(adap, SGE_FL_BUFFER_SIZE2_A,
7401f612b815SHariprasad Shenai 		     (t4_read_reg(adap, SGE_FL_BUFFER_SIZE2_A) + fl_align-1)
7402636f9d37SVipul Pandya 		     & ~(fl_align-1));
7403f612b815SHariprasad Shenai 	t4_write_reg(adap, SGE_FL_BUFFER_SIZE3_A,
7404f612b815SHariprasad Shenai 		     (t4_read_reg(adap, SGE_FL_BUFFER_SIZE3_A) + fl_align-1)
7405636f9d37SVipul Pandya 		     & ~(fl_align-1));
7406636f9d37SVipul Pandya 
74070d804338SHariprasad Shenai 	t4_write_reg(adap, ULP_RX_TDDP_PSZ_A, HPZ0_V(page_shift - 12));
7408636f9d37SVipul Pandya 
7409636f9d37SVipul Pandya 	return 0;
7410636f9d37SVipul Pandya }
7411636f9d37SVipul Pandya 
7412636f9d37SVipul Pandya /**
7413636f9d37SVipul Pandya  *	t4_fw_initialize - ask FW to initialize the device
7414636f9d37SVipul Pandya  *	@adap: the adapter
7415636f9d37SVipul Pandya  *	@mbox: mailbox to use for the FW command
7416636f9d37SVipul Pandya  *
7417636f9d37SVipul Pandya  *	Issues a command to FW to partially initialize the device.  This
7418636f9d37SVipul Pandya  *	performs initialization that generally doesn't depend on user input.
7419636f9d37SVipul Pandya  */
t4_fw_initialize(struct adapter * adap,unsigned int mbox)7420636f9d37SVipul Pandya int t4_fw_initialize(struct adapter *adap, unsigned int mbox)
7421636f9d37SVipul Pandya {
7422636f9d37SVipul Pandya 	struct fw_initialize_cmd c;
7423636f9d37SVipul Pandya 
7424636f9d37SVipul Pandya 	memset(&c, 0, sizeof(c));
7425636f9d37SVipul Pandya 	INIT_CMD(c, INITIALIZE, WRITE);
7426636f9d37SVipul Pandya 	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
7427636f9d37SVipul Pandya }
7428636f9d37SVipul Pandya 
7429636f9d37SVipul Pandya /**
743001b69614SHariprasad Shenai  *	t4_query_params_rw - query FW or device parameters
7431f7917c00SJeff Kirsher  *	@adap: the adapter
7432f7917c00SJeff Kirsher  *	@mbox: mailbox to use for the FW command
7433f7917c00SJeff Kirsher  *	@pf: the PF
7434f7917c00SJeff Kirsher  *	@vf: the VF
7435f7917c00SJeff Kirsher  *	@nparams: the number of parameters
7436f7917c00SJeff Kirsher  *	@params: the parameter names
7437f7917c00SJeff Kirsher  *	@val: the parameter values
743801b69614SHariprasad Shenai  *	@rw: Write and read flag
74398f46d467SArjun Vynipadath  *	@sleep_ok: if true, we may sleep awaiting mbox cmd completion
7440f7917c00SJeff Kirsher  *
7441f7917c00SJeff Kirsher  *	Reads the value of FW or device parameters.  Up to 7 parameters can be
7442f7917c00SJeff Kirsher  *	queried at once.
7443f7917c00SJeff Kirsher  */
t4_query_params_rw(struct adapter * adap,unsigned int mbox,unsigned int pf,unsigned int vf,unsigned int nparams,const u32 * params,u32 * val,int rw,bool sleep_ok)744401b69614SHariprasad Shenai int t4_query_params_rw(struct adapter *adap, unsigned int mbox, unsigned int pf,
7445f7917c00SJeff Kirsher 		       unsigned int vf, unsigned int nparams, const u32 *params,
74468f46d467SArjun Vynipadath 		       u32 *val, int rw, bool sleep_ok)
7447f7917c00SJeff Kirsher {
7448f7917c00SJeff Kirsher 	int i, ret;
7449f7917c00SJeff Kirsher 	struct fw_params_cmd c;
7450f7917c00SJeff Kirsher 	__be32 *p = &c.param[0].mnem;
7451f7917c00SJeff Kirsher 
7452f7917c00SJeff Kirsher 	if (nparams > 7)
7453f7917c00SJeff Kirsher 		return -EINVAL;
7454f7917c00SJeff Kirsher 
7455f7917c00SJeff Kirsher 	memset(&c, 0, sizeof(c));
7456f404f80cSHariprasad Shenai 	c.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_PARAMS_CMD) |
7457f404f80cSHariprasad Shenai 				  FW_CMD_REQUEST_F | FW_CMD_READ_F |
7458f404f80cSHariprasad Shenai 				  FW_PARAMS_CMD_PFN_V(pf) |
74595167865aSHariprasad Shenai 				  FW_PARAMS_CMD_VFN_V(vf));
7460f404f80cSHariprasad Shenai 	c.retval_len16 = cpu_to_be32(FW_LEN16(c));
7461f404f80cSHariprasad Shenai 
746201b69614SHariprasad Shenai 	for (i = 0; i < nparams; i++) {
746301b69614SHariprasad Shenai 		*p++ = cpu_to_be32(*params++);
746401b69614SHariprasad Shenai 		if (rw)
746501b69614SHariprasad Shenai 			*p = cpu_to_be32(*(val + i));
746601b69614SHariprasad Shenai 		p++;
746701b69614SHariprasad Shenai 	}
7468f7917c00SJeff Kirsher 
74698f46d467SArjun Vynipadath 	ret = t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), &c, sleep_ok);
7470f7917c00SJeff Kirsher 	if (ret == 0)
7471f7917c00SJeff Kirsher 		for (i = 0, p = &c.param[0].val; i < nparams; i++, p += 2)
7472f404f80cSHariprasad Shenai 			*val++ = be32_to_cpu(*p);
7473f7917c00SJeff Kirsher 	return ret;
7474f7917c00SJeff Kirsher }
7475f7917c00SJeff Kirsher 
t4_query_params(struct adapter * adap,unsigned int mbox,unsigned int pf,unsigned int vf,unsigned int nparams,const u32 * params,u32 * val)747601b69614SHariprasad Shenai int t4_query_params(struct adapter *adap, unsigned int mbox, unsigned int pf,
747701b69614SHariprasad Shenai 		    unsigned int vf, unsigned int nparams, const u32 *params,
747801b69614SHariprasad Shenai 		    u32 *val)
747901b69614SHariprasad Shenai {
74808f46d467SArjun Vynipadath 	return t4_query_params_rw(adap, mbox, pf, vf, nparams, params, val, 0,
74818f46d467SArjun Vynipadath 				  true);
74828f46d467SArjun Vynipadath }
74838f46d467SArjun Vynipadath 
t4_query_params_ns(struct adapter * adap,unsigned int mbox,unsigned int pf,unsigned int vf,unsigned int nparams,const u32 * params,u32 * val)74848f46d467SArjun Vynipadath int t4_query_params_ns(struct adapter *adap, unsigned int mbox, unsigned int pf,
74858f46d467SArjun Vynipadath 		       unsigned int vf, unsigned int nparams, const u32 *params,
74868f46d467SArjun Vynipadath 		       u32 *val)
74878f46d467SArjun Vynipadath {
74888f46d467SArjun Vynipadath 	return t4_query_params_rw(adap, mbox, pf, vf, nparams, params, val, 0,
74898f46d467SArjun Vynipadath 				  false);
749001b69614SHariprasad Shenai }
749101b69614SHariprasad Shenai 
7492f7917c00SJeff Kirsher /**
749301b69614SHariprasad Shenai  *      t4_set_params_timeout - sets FW or device parameters
7494688848b1SAnish Bhatt  *      @adap: the adapter
7495688848b1SAnish Bhatt  *      @mbox: mailbox to use for the FW command
7496688848b1SAnish Bhatt  *      @pf: the PF
7497688848b1SAnish Bhatt  *      @vf: the VF
7498688848b1SAnish Bhatt  *      @nparams: the number of parameters
7499688848b1SAnish Bhatt  *      @params: the parameter names
7500688848b1SAnish Bhatt  *      @val: the parameter values
750101b69614SHariprasad Shenai  *      @timeout: the timeout time
7502688848b1SAnish Bhatt  *
7503688848b1SAnish Bhatt  *      Sets the value of FW or device parameters.  Up to 7 parameters can be
7504688848b1SAnish Bhatt  *      specified at once.
7505688848b1SAnish Bhatt  */
t4_set_params_timeout(struct adapter * adap,unsigned int mbox,unsigned int pf,unsigned int vf,unsigned int nparams,const u32 * params,const u32 * val,int timeout)750601b69614SHariprasad Shenai int t4_set_params_timeout(struct adapter *adap, unsigned int mbox,
7507688848b1SAnish Bhatt 			  unsigned int pf, unsigned int vf,
7508688848b1SAnish Bhatt 			  unsigned int nparams, const u32 *params,
750901b69614SHariprasad Shenai 			  const u32 *val, int timeout)
7510688848b1SAnish Bhatt {
7511688848b1SAnish Bhatt 	struct fw_params_cmd c;
7512688848b1SAnish Bhatt 	__be32 *p = &c.param[0].mnem;
7513688848b1SAnish Bhatt 
7514688848b1SAnish Bhatt 	if (nparams > 7)
7515688848b1SAnish Bhatt 		return -EINVAL;
7516688848b1SAnish Bhatt 
7517688848b1SAnish Bhatt 	memset(&c, 0, sizeof(c));
7518e2ac9628SHariprasad Shenai 	c.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_PARAMS_CMD) |
7519e2ac9628SHariprasad Shenai 				  FW_CMD_REQUEST_F | FW_CMD_WRITE_F |
75205167865aSHariprasad Shenai 				  FW_PARAMS_CMD_PFN_V(pf) |
75215167865aSHariprasad Shenai 				  FW_PARAMS_CMD_VFN_V(vf));
7522688848b1SAnish Bhatt 	c.retval_len16 = cpu_to_be32(FW_LEN16(c));
7523688848b1SAnish Bhatt 
7524688848b1SAnish Bhatt 	while (nparams--) {
7525688848b1SAnish Bhatt 		*p++ = cpu_to_be32(*params++);
7526688848b1SAnish Bhatt 		*p++ = cpu_to_be32(*val++);
7527688848b1SAnish Bhatt 	}
7528688848b1SAnish Bhatt 
752901b69614SHariprasad Shenai 	return t4_wr_mbox_timeout(adap, mbox, &c, sizeof(c), NULL, timeout);
7530688848b1SAnish Bhatt }
7531688848b1SAnish Bhatt 
7532688848b1SAnish Bhatt /**
7533f7917c00SJeff Kirsher  *	t4_set_params - sets FW or device parameters
7534f7917c00SJeff Kirsher  *	@adap: the adapter
7535f7917c00SJeff Kirsher  *	@mbox: mailbox to use for the FW command
7536f7917c00SJeff Kirsher  *	@pf: the PF
7537f7917c00SJeff Kirsher  *	@vf: the VF
7538f7917c00SJeff Kirsher  *	@nparams: the number of parameters
7539f7917c00SJeff Kirsher  *	@params: the parameter names
7540f7917c00SJeff Kirsher  *	@val: the parameter values
7541f7917c00SJeff Kirsher  *
7542f7917c00SJeff Kirsher  *	Sets the value of FW or device parameters.  Up to 7 parameters can be
7543f7917c00SJeff Kirsher  *	specified at once.
7544f7917c00SJeff Kirsher  */
t4_set_params(struct adapter * adap,unsigned int mbox,unsigned int pf,unsigned int vf,unsigned int nparams,const u32 * params,const u32 * val)7545f7917c00SJeff Kirsher int t4_set_params(struct adapter *adap, unsigned int mbox, unsigned int pf,
7546f7917c00SJeff Kirsher 		  unsigned int vf, unsigned int nparams, const u32 *params,
7547f7917c00SJeff Kirsher 		  const u32 *val)
7548f7917c00SJeff Kirsher {
754901b69614SHariprasad Shenai 	return t4_set_params_timeout(adap, mbox, pf, vf, nparams, params, val,
755001b69614SHariprasad Shenai 				     FW_CMD_MAX_TIMEOUT);
7551f7917c00SJeff Kirsher }
7552f7917c00SJeff Kirsher 
7553f7917c00SJeff Kirsher /**
7554f7917c00SJeff Kirsher  *	t4_cfg_pfvf - configure PF/VF resource limits
7555f7917c00SJeff Kirsher  *	@adap: the adapter
7556f7917c00SJeff Kirsher  *	@mbox: mailbox to use for the FW command
7557f7917c00SJeff Kirsher  *	@pf: the PF being configured
7558f7917c00SJeff Kirsher  *	@vf: the VF being configured
7559f7917c00SJeff Kirsher  *	@txq: the max number of egress queues
7560f7917c00SJeff Kirsher  *	@txq_eth_ctrl: the max number of egress Ethernet or control queues
7561f7917c00SJeff Kirsher  *	@rxqi: the max number of interrupt-capable ingress queues
7562f7917c00SJeff Kirsher  *	@rxq: the max number of interruptless ingress queues
7563f7917c00SJeff Kirsher  *	@tc: the PCI traffic class
7564f7917c00SJeff Kirsher  *	@vi: the max number of virtual interfaces
7565f7917c00SJeff Kirsher  *	@cmask: the channel access rights mask for the PF/VF
7566f7917c00SJeff Kirsher  *	@pmask: the port access rights mask for the PF/VF
7567f7917c00SJeff Kirsher  *	@nexact: the maximum number of exact MPS filters
7568f7917c00SJeff Kirsher  *	@rcaps: read capabilities
7569f7917c00SJeff Kirsher  *	@wxcaps: write/execute capabilities
7570f7917c00SJeff Kirsher  *
7571f7917c00SJeff Kirsher  *	Configures resource limits and capabilities for a physical or virtual
7572f7917c00SJeff Kirsher  *	function.
7573f7917c00SJeff Kirsher  */
t4_cfg_pfvf(struct adapter * adap,unsigned int mbox,unsigned int pf,unsigned int vf,unsigned int txq,unsigned int txq_eth_ctrl,unsigned int rxqi,unsigned int rxq,unsigned int tc,unsigned int vi,unsigned int cmask,unsigned int pmask,unsigned int nexact,unsigned int rcaps,unsigned int wxcaps)7574f7917c00SJeff Kirsher int t4_cfg_pfvf(struct adapter *adap, unsigned int mbox, unsigned int pf,
7575f7917c00SJeff Kirsher 		unsigned int vf, unsigned int txq, unsigned int txq_eth_ctrl,
7576f7917c00SJeff Kirsher 		unsigned int rxqi, unsigned int rxq, unsigned int tc,
7577f7917c00SJeff Kirsher 		unsigned int vi, unsigned int cmask, unsigned int pmask,
7578f7917c00SJeff Kirsher 		unsigned int nexact, unsigned int rcaps, unsigned int wxcaps)
7579f7917c00SJeff Kirsher {
7580f7917c00SJeff Kirsher 	struct fw_pfvf_cmd c;
7581f7917c00SJeff Kirsher 
7582f7917c00SJeff Kirsher 	memset(&c, 0, sizeof(c));
7583f404f80cSHariprasad Shenai 	c.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_PFVF_CMD) | FW_CMD_REQUEST_F |
75845167865aSHariprasad Shenai 				  FW_CMD_WRITE_F | FW_PFVF_CMD_PFN_V(pf) |
75855167865aSHariprasad Shenai 				  FW_PFVF_CMD_VFN_V(vf));
7586f404f80cSHariprasad Shenai 	c.retval_len16 = cpu_to_be32(FW_LEN16(c));
7587f404f80cSHariprasad Shenai 	c.niqflint_niq = cpu_to_be32(FW_PFVF_CMD_NIQFLINT_V(rxqi) |
75885167865aSHariprasad Shenai 				     FW_PFVF_CMD_NIQ_V(rxq));
7589f404f80cSHariprasad Shenai 	c.type_to_neq = cpu_to_be32(FW_PFVF_CMD_CMASK_V(cmask) |
75905167865aSHariprasad Shenai 				    FW_PFVF_CMD_PMASK_V(pmask) |
75915167865aSHariprasad Shenai 				    FW_PFVF_CMD_NEQ_V(txq));
7592f404f80cSHariprasad Shenai 	c.tc_to_nexactf = cpu_to_be32(FW_PFVF_CMD_TC_V(tc) |
7593f404f80cSHariprasad Shenai 				      FW_PFVF_CMD_NVI_V(vi) |
75945167865aSHariprasad Shenai 				      FW_PFVF_CMD_NEXACTF_V(nexact));
7595f404f80cSHariprasad Shenai 	c.r_caps_to_nethctrl = cpu_to_be32(FW_PFVF_CMD_R_CAPS_V(rcaps) |
75965167865aSHariprasad Shenai 					FW_PFVF_CMD_WX_CAPS_V(wxcaps) |
75975167865aSHariprasad Shenai 					FW_PFVF_CMD_NETHCTRL_V(txq_eth_ctrl));
7598f7917c00SJeff Kirsher 	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
7599f7917c00SJeff Kirsher }
7600f7917c00SJeff Kirsher 
7601f7917c00SJeff Kirsher /**
7602f7917c00SJeff Kirsher  *	t4_alloc_vi - allocate a virtual interface
7603f7917c00SJeff Kirsher  *	@adap: the adapter
7604f7917c00SJeff Kirsher  *	@mbox: mailbox to use for the FW command
7605f7917c00SJeff Kirsher  *	@port: physical port associated with the VI
7606f7917c00SJeff Kirsher  *	@pf: the PF owning the VI
7607f7917c00SJeff Kirsher  *	@vf: the VF owning the VI
7608f7917c00SJeff Kirsher  *	@nmac: number of MAC addresses needed (1 to 5)
7609f7917c00SJeff Kirsher  *	@mac: the MAC addresses of the VI
7610f7917c00SJeff Kirsher  *	@rss_size: size of RSS table slice associated with this VI
761129bbf5d7SRahul Lakkireddy  *	@vivld: the destination to store the VI Valid value.
761229bbf5d7SRahul Lakkireddy  *	@vin: the destination to store the VIN value.
7613f7917c00SJeff Kirsher  *
7614f7917c00SJeff Kirsher  *	Allocates a virtual interface for the given physical port.  If @mac is
7615f7917c00SJeff Kirsher  *	not %NULL it contains the MAC addresses of the VI as assigned by FW.
7616f7917c00SJeff Kirsher  *	@mac should be large enough to hold @nmac Ethernet addresses, they are
7617f7917c00SJeff Kirsher  *	stored consecutively so the space needed is @nmac * 6 bytes.
7618f7917c00SJeff Kirsher  *	Returns a negative error number or the non-negative VI id.
7619f7917c00SJeff Kirsher  */
t4_alloc_vi(struct adapter * adap,unsigned int mbox,unsigned int port,unsigned int pf,unsigned int vf,unsigned int nmac,u8 * mac,unsigned int * rss_size,u8 * vivld,u8 * vin)7620f7917c00SJeff Kirsher int t4_alloc_vi(struct adapter *adap, unsigned int mbox, unsigned int port,
7621f7917c00SJeff Kirsher 		unsigned int pf, unsigned int vf, unsigned int nmac, u8 *mac,
762202d805dcSSantosh Rastapur 		unsigned int *rss_size, u8 *vivld, u8 *vin)
7623f7917c00SJeff Kirsher {
7624f7917c00SJeff Kirsher 	int ret;
7625f7917c00SJeff Kirsher 	struct fw_vi_cmd c;
7626f7917c00SJeff Kirsher 
7627f7917c00SJeff Kirsher 	memset(&c, 0, sizeof(c));
7628f404f80cSHariprasad Shenai 	c.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_VI_CMD) | FW_CMD_REQUEST_F |
7629e2ac9628SHariprasad Shenai 				  FW_CMD_WRITE_F | FW_CMD_EXEC_F |
76302b5fb1f2SHariprasad Shenai 				  FW_VI_CMD_PFN_V(pf) | FW_VI_CMD_VFN_V(vf));
7631f404f80cSHariprasad Shenai 	c.alloc_to_len16 = cpu_to_be32(FW_VI_CMD_ALLOC_F | FW_LEN16(c));
76322b5fb1f2SHariprasad Shenai 	c.portid_pkd = FW_VI_CMD_PORTID_V(port);
7633f7917c00SJeff Kirsher 	c.nmac = nmac - 1;
7634f7917c00SJeff Kirsher 
7635f7917c00SJeff Kirsher 	ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
7636f7917c00SJeff Kirsher 	if (ret)
7637f7917c00SJeff Kirsher 		return ret;
7638f7917c00SJeff Kirsher 
7639f7917c00SJeff Kirsher 	if (mac) {
7640f7917c00SJeff Kirsher 		memcpy(mac, c.mac, sizeof(c.mac));
7641f7917c00SJeff Kirsher 		switch (nmac) {
7642f7917c00SJeff Kirsher 		case 5:
7643f7917c00SJeff Kirsher 			memcpy(mac + 24, c.nmac3, sizeof(c.nmac3));
7644df561f66SGustavo A. R. Silva 			fallthrough;
7645f7917c00SJeff Kirsher 		case 4:
7646f7917c00SJeff Kirsher 			memcpy(mac + 18, c.nmac2, sizeof(c.nmac2));
7647df561f66SGustavo A. R. Silva 			fallthrough;
7648f7917c00SJeff Kirsher 		case 3:
7649f7917c00SJeff Kirsher 			memcpy(mac + 12, c.nmac1, sizeof(c.nmac1));
7650df561f66SGustavo A. R. Silva 			fallthrough;
7651f7917c00SJeff Kirsher 		case 2:
7652f7917c00SJeff Kirsher 			memcpy(mac + 6,  c.nmac0, sizeof(c.nmac0));
7653f7917c00SJeff Kirsher 		}
7654f7917c00SJeff Kirsher 	}
7655f7917c00SJeff Kirsher 	if (rss_size)
7656f404f80cSHariprasad Shenai 		*rss_size = FW_VI_CMD_RSSSIZE_G(be16_to_cpu(c.rsssize_pkd));
765702d805dcSSantosh Rastapur 
765802d805dcSSantosh Rastapur 	if (vivld)
765902d805dcSSantosh Rastapur 		*vivld = FW_VI_CMD_VFVLD_G(be32_to_cpu(c.alloc_to_len16));
766002d805dcSSantosh Rastapur 
766102d805dcSSantosh Rastapur 	if (vin)
766202d805dcSSantosh Rastapur 		*vin = FW_VI_CMD_VIN_G(be32_to_cpu(c.alloc_to_len16));
766302d805dcSSantosh Rastapur 
7664f404f80cSHariprasad Shenai 	return FW_VI_CMD_VIID_G(be16_to_cpu(c.type_viid));
7665f7917c00SJeff Kirsher }
7666f7917c00SJeff Kirsher 
7667f7917c00SJeff Kirsher /**
76684f3a0fcfSHariprasad Shenai  *	t4_free_vi - free a virtual interface
76694f3a0fcfSHariprasad Shenai  *	@adap: the adapter
76704f3a0fcfSHariprasad Shenai  *	@mbox: mailbox to use for the FW command
76714f3a0fcfSHariprasad Shenai  *	@pf: the PF owning the VI
76724f3a0fcfSHariprasad Shenai  *	@vf: the VF owning the VI
76734f3a0fcfSHariprasad Shenai  *	@viid: virtual interface identifiler
76744f3a0fcfSHariprasad Shenai  *
76754f3a0fcfSHariprasad Shenai  *	Free a previously allocated virtual interface.
76764f3a0fcfSHariprasad Shenai  */
t4_free_vi(struct adapter * adap,unsigned int mbox,unsigned int pf,unsigned int vf,unsigned int viid)76774f3a0fcfSHariprasad Shenai int t4_free_vi(struct adapter *adap, unsigned int mbox, unsigned int pf,
76784f3a0fcfSHariprasad Shenai 	       unsigned int vf, unsigned int viid)
76794f3a0fcfSHariprasad Shenai {
76804f3a0fcfSHariprasad Shenai 	struct fw_vi_cmd c;
76814f3a0fcfSHariprasad Shenai 
76824f3a0fcfSHariprasad Shenai 	memset(&c, 0, sizeof(c));
76834f3a0fcfSHariprasad Shenai 	c.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_VI_CMD) |
76844f3a0fcfSHariprasad Shenai 				  FW_CMD_REQUEST_F |
76854f3a0fcfSHariprasad Shenai 				  FW_CMD_EXEC_F |
76864f3a0fcfSHariprasad Shenai 				  FW_VI_CMD_PFN_V(pf) |
76874f3a0fcfSHariprasad Shenai 				  FW_VI_CMD_VFN_V(vf));
76884f3a0fcfSHariprasad Shenai 	c.alloc_to_len16 = cpu_to_be32(FW_VI_CMD_FREE_F | FW_LEN16(c));
76894f3a0fcfSHariprasad Shenai 	c.type_viid = cpu_to_be16(FW_VI_CMD_VIID_V(viid));
76904f3a0fcfSHariprasad Shenai 
76914f3a0fcfSHariprasad Shenai 	return t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
7692f7917c00SJeff Kirsher }
7693f7917c00SJeff Kirsher 
7694f7917c00SJeff Kirsher /**
7695f7917c00SJeff Kirsher  *	t4_set_rxmode - set Rx properties of a virtual interface
7696f7917c00SJeff Kirsher  *	@adap: the adapter
7697f7917c00SJeff Kirsher  *	@mbox: mailbox to use for the FW command
7698f7917c00SJeff Kirsher  *	@viid: the VI id
7699696c278fSRahul Lakkireddy  *	@viid_mirror: the mirror VI id
7700f7917c00SJeff Kirsher  *	@mtu: the new MTU or -1
7701f7917c00SJeff Kirsher  *	@promisc: 1 to enable promiscuous mode, 0 to disable it, -1 no change
7702f7917c00SJeff Kirsher  *	@all_multi: 1 to enable all-multi mode, 0 to disable it, -1 no change
7703f7917c00SJeff Kirsher  *	@bcast: 1 to enable broadcast Rx, 0 to disable it, -1 no change
7704f7917c00SJeff Kirsher  *	@vlanex: 1 to enable HW VLAN extraction, 0 to disable it, -1 no change
7705f7917c00SJeff Kirsher  *	@sleep_ok: if true we may sleep while awaiting command completion
7706f7917c00SJeff Kirsher  *
7707f7917c00SJeff Kirsher  *	Sets Rx properties of a virtual interface.
7708f7917c00SJeff Kirsher  */
t4_set_rxmode(struct adapter * adap,unsigned int mbox,unsigned int viid,unsigned int viid_mirror,int mtu,int promisc,int all_multi,int bcast,int vlanex,bool sleep_ok)7709f7917c00SJeff Kirsher int t4_set_rxmode(struct adapter *adap, unsigned int mbox, unsigned int viid,
7710696c278fSRahul Lakkireddy 		  unsigned int viid_mirror, int mtu, int promisc, int all_multi,
7711696c278fSRahul Lakkireddy 		  int bcast, int vlanex, bool sleep_ok)
7712f7917c00SJeff Kirsher {
7713696c278fSRahul Lakkireddy 	struct fw_vi_rxmode_cmd c, c_mirror;
7714696c278fSRahul Lakkireddy 	int ret;
7715f7917c00SJeff Kirsher 
7716f7917c00SJeff Kirsher 	/* convert to FW values */
7717f7917c00SJeff Kirsher 	if (mtu < 0)
7718f7917c00SJeff Kirsher 		mtu = FW_RXMODE_MTU_NO_CHG;
7719f7917c00SJeff Kirsher 	if (promisc < 0)
77202b5fb1f2SHariprasad Shenai 		promisc = FW_VI_RXMODE_CMD_PROMISCEN_M;
7721f7917c00SJeff Kirsher 	if (all_multi < 0)
77222b5fb1f2SHariprasad Shenai 		all_multi = FW_VI_RXMODE_CMD_ALLMULTIEN_M;
7723f7917c00SJeff Kirsher 	if (bcast < 0)
77242b5fb1f2SHariprasad Shenai 		bcast = FW_VI_RXMODE_CMD_BROADCASTEN_M;
7725f7917c00SJeff Kirsher 	if (vlanex < 0)
77262b5fb1f2SHariprasad Shenai 		vlanex = FW_VI_RXMODE_CMD_VLANEXEN_M;
7727f7917c00SJeff Kirsher 
7728f7917c00SJeff Kirsher 	memset(&c, 0, sizeof(c));
7729f404f80cSHariprasad Shenai 	c.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_RXMODE_CMD) |
7730f404f80cSHariprasad Shenai 				   FW_CMD_REQUEST_F | FW_CMD_WRITE_F |
7731f404f80cSHariprasad Shenai 				   FW_VI_RXMODE_CMD_VIID_V(viid));
7732f404f80cSHariprasad Shenai 	c.retval_len16 = cpu_to_be32(FW_LEN16(c));
7733f404f80cSHariprasad Shenai 	c.mtu_to_vlanexen =
7734f404f80cSHariprasad Shenai 		cpu_to_be32(FW_VI_RXMODE_CMD_MTU_V(mtu) |
77352b5fb1f2SHariprasad Shenai 			    FW_VI_RXMODE_CMD_PROMISCEN_V(promisc) |
77362b5fb1f2SHariprasad Shenai 			    FW_VI_RXMODE_CMD_ALLMULTIEN_V(all_multi) |
77372b5fb1f2SHariprasad Shenai 			    FW_VI_RXMODE_CMD_BROADCASTEN_V(bcast) |
77382b5fb1f2SHariprasad Shenai 			    FW_VI_RXMODE_CMD_VLANEXEN_V(vlanex));
7739696c278fSRahul Lakkireddy 
7740696c278fSRahul Lakkireddy 	if (viid_mirror) {
7741696c278fSRahul Lakkireddy 		memcpy(&c_mirror, &c, sizeof(c_mirror));
7742696c278fSRahul Lakkireddy 		c_mirror.op_to_viid =
7743696c278fSRahul Lakkireddy 			cpu_to_be32(FW_CMD_OP_V(FW_VI_RXMODE_CMD) |
7744696c278fSRahul Lakkireddy 				    FW_CMD_REQUEST_F | FW_CMD_WRITE_F |
7745696c278fSRahul Lakkireddy 				    FW_VI_RXMODE_CMD_VIID_V(viid_mirror));
7746696c278fSRahul Lakkireddy 	}
7747696c278fSRahul Lakkireddy 
7748696c278fSRahul Lakkireddy 	ret = t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), NULL, sleep_ok);
7749696c278fSRahul Lakkireddy 	if (ret)
7750696c278fSRahul Lakkireddy 		return ret;
7751696c278fSRahul Lakkireddy 
7752696c278fSRahul Lakkireddy 	if (viid_mirror)
7753696c278fSRahul Lakkireddy 		ret = t4_wr_mbox_meat(adap, mbox, &c_mirror, sizeof(c_mirror),
7754696c278fSRahul Lakkireddy 				      NULL, sleep_ok);
7755696c278fSRahul Lakkireddy 
7756696c278fSRahul Lakkireddy 	return ret;
7757f7917c00SJeff Kirsher }
7758f7917c00SJeff Kirsher 
7759f7917c00SJeff Kirsher /**
776098f3697fSKumar Sanghvi  *      t4_free_encap_mac_filt - frees MPS entry at given index
776198f3697fSKumar Sanghvi  *      @adap: the adapter
776298f3697fSKumar Sanghvi  *      @viid: the VI id
776398f3697fSKumar Sanghvi  *      @idx: index of MPS entry to be freed
776498f3697fSKumar Sanghvi  *      @sleep_ok: call is allowed to sleep
776598f3697fSKumar Sanghvi  *
776698f3697fSKumar Sanghvi  *      Frees the MPS entry at supplied index
776798f3697fSKumar Sanghvi  *
776898f3697fSKumar Sanghvi  *      Returns a negative error number or zero on success
776998f3697fSKumar Sanghvi  */
t4_free_encap_mac_filt(struct adapter * adap,unsigned int viid,int idx,bool sleep_ok)777098f3697fSKumar Sanghvi int t4_free_encap_mac_filt(struct adapter *adap, unsigned int viid,
777198f3697fSKumar Sanghvi 			   int idx, bool sleep_ok)
777298f3697fSKumar Sanghvi {
777398f3697fSKumar Sanghvi 	struct fw_vi_mac_exact *p;
777498f3697fSKumar Sanghvi 	struct fw_vi_mac_cmd c;
777598f3697fSKumar Sanghvi 	int ret = 0;
777698f3697fSKumar Sanghvi 	u32 exact;
777798f3697fSKumar Sanghvi 
777898f3697fSKumar Sanghvi 	memset(&c, 0, sizeof(c));
777998f3697fSKumar Sanghvi 	c.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_MAC_CMD) |
778098f3697fSKumar Sanghvi 				   FW_CMD_REQUEST_F | FW_CMD_WRITE_F |
778198f3697fSKumar Sanghvi 				   FW_CMD_EXEC_V(0) |
778298f3697fSKumar Sanghvi 				   FW_VI_MAC_CMD_VIID_V(viid));
778398f3697fSKumar Sanghvi 	exact = FW_VI_MAC_CMD_ENTRY_TYPE_V(FW_VI_MAC_TYPE_EXACTMAC);
778498f3697fSKumar Sanghvi 	c.freemacs_to_len16 = cpu_to_be32(FW_VI_MAC_CMD_FREEMACS_V(0) |
778598f3697fSKumar Sanghvi 					  exact |
778698f3697fSKumar Sanghvi 					  FW_CMD_LEN16_V(1));
778798f3697fSKumar Sanghvi 	p = c.u.exact;
778898f3697fSKumar Sanghvi 	p->valid_to_idx = cpu_to_be16(FW_VI_MAC_CMD_VALID_F |
778998f3697fSKumar Sanghvi 				      FW_VI_MAC_CMD_IDX_V(idx));
7790c7654495SYang Yingliang 	eth_zero_addr(p->macaddr);
779198f3697fSKumar Sanghvi 	ret = t4_wr_mbox_meat(adap, adap->mbox, &c, sizeof(c), &c, sleep_ok);
779298f3697fSKumar Sanghvi 	return ret;
779398f3697fSKumar Sanghvi }
779498f3697fSKumar Sanghvi 
779598f3697fSKumar Sanghvi /**
7796846eac3fSGanesh Goudar  *	t4_free_raw_mac_filt - Frees a raw mac entry in mps tcam
7797846eac3fSGanesh Goudar  *	@adap: the adapter
7798846eac3fSGanesh Goudar  *	@viid: the VI id
7799846eac3fSGanesh Goudar  *	@addr: the MAC address
7800846eac3fSGanesh Goudar  *	@mask: the mask
7801846eac3fSGanesh Goudar  *	@idx: index of the entry in mps tcam
7802846eac3fSGanesh Goudar  *	@lookup_type: MAC address for inner (1) or outer (0) header
7803846eac3fSGanesh Goudar  *	@port_id: the port index
7804846eac3fSGanesh Goudar  *	@sleep_ok: call is allowed to sleep
7805846eac3fSGanesh Goudar  *
7806846eac3fSGanesh Goudar  *	Removes the mac entry at the specified index using raw mac interface.
7807846eac3fSGanesh Goudar  *
7808846eac3fSGanesh Goudar  *	Returns a negative error number on failure.
7809846eac3fSGanesh Goudar  */
t4_free_raw_mac_filt(struct adapter * adap,unsigned int viid,const u8 * addr,const u8 * mask,unsigned int idx,u8 lookup_type,u8 port_id,bool sleep_ok)7810846eac3fSGanesh Goudar int t4_free_raw_mac_filt(struct adapter *adap, unsigned int viid,
7811846eac3fSGanesh Goudar 			 const u8 *addr, const u8 *mask, unsigned int idx,
7812846eac3fSGanesh Goudar 			 u8 lookup_type, u8 port_id, bool sleep_ok)
7813846eac3fSGanesh Goudar {
7814846eac3fSGanesh Goudar 	struct fw_vi_mac_cmd c;
7815846eac3fSGanesh Goudar 	struct fw_vi_mac_raw *p = &c.u.raw;
7816846eac3fSGanesh Goudar 	u32 val;
7817846eac3fSGanesh Goudar 
7818846eac3fSGanesh Goudar 	memset(&c, 0, sizeof(c));
7819846eac3fSGanesh Goudar 	c.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_MAC_CMD) |
7820846eac3fSGanesh Goudar 				   FW_CMD_REQUEST_F | FW_CMD_WRITE_F |
7821846eac3fSGanesh Goudar 				   FW_CMD_EXEC_V(0) |
7822846eac3fSGanesh Goudar 				   FW_VI_MAC_CMD_VIID_V(viid));
7823846eac3fSGanesh Goudar 	val = FW_CMD_LEN16_V(1) |
7824846eac3fSGanesh Goudar 	      FW_VI_MAC_CMD_ENTRY_TYPE_V(FW_VI_MAC_TYPE_RAW);
7825846eac3fSGanesh Goudar 	c.freemacs_to_len16 = cpu_to_be32(FW_VI_MAC_CMD_FREEMACS_V(0) |
7826846eac3fSGanesh Goudar 					  FW_CMD_LEN16_V(val));
7827846eac3fSGanesh Goudar 
7828846eac3fSGanesh Goudar 	p->raw_idx_pkd = cpu_to_be32(FW_VI_MAC_CMD_RAW_IDX_V(idx) |
7829846eac3fSGanesh Goudar 				     FW_VI_MAC_ID_BASED_FREE);
7830846eac3fSGanesh Goudar 
7831846eac3fSGanesh Goudar 	/* Lookup Type. Outer header: 0, Inner header: 1 */
7832846eac3fSGanesh Goudar 	p->data0_pkd = cpu_to_be32(DATALKPTYPE_V(lookup_type) |
7833846eac3fSGanesh Goudar 				   DATAPORTNUM_V(port_id));
7834846eac3fSGanesh Goudar 	/* Lookup mask and port mask */
7835846eac3fSGanesh Goudar 	p->data0m_pkd = cpu_to_be64(DATALKPTYPE_V(DATALKPTYPE_M) |
7836846eac3fSGanesh Goudar 				    DATAPORTNUM_V(DATAPORTNUM_M));
7837846eac3fSGanesh Goudar 
7838846eac3fSGanesh Goudar 	/* Copy the address and the mask */
7839846eac3fSGanesh Goudar 	memcpy((u8 *)&p->data1[0] + 2, addr, ETH_ALEN);
7840846eac3fSGanesh Goudar 	memcpy((u8 *)&p->data1m[0] + 2, mask, ETH_ALEN);
7841846eac3fSGanesh Goudar 
7842846eac3fSGanesh Goudar 	return t4_wr_mbox_meat(adap, adap->mbox, &c, sizeof(c), &c, sleep_ok);
7843846eac3fSGanesh Goudar }
7844846eac3fSGanesh Goudar 
7845846eac3fSGanesh Goudar /**
784698f3697fSKumar Sanghvi  *      t4_alloc_encap_mac_filt - Adds a mac entry in mps tcam with VNI support
784798f3697fSKumar Sanghvi  *      @adap: the adapter
784898f3697fSKumar Sanghvi  *      @viid: the VI id
784929bbf5d7SRahul Lakkireddy  *      @addr: the MAC address
785098f3697fSKumar Sanghvi  *      @mask: the mask
785198f3697fSKumar Sanghvi  *      @vni: the VNI id for the tunnel protocol
785298f3697fSKumar Sanghvi  *      @vni_mask: mask for the VNI id
785398f3697fSKumar Sanghvi  *      @dip_hit: to enable DIP match for the MPS entry
785498f3697fSKumar Sanghvi  *      @lookup_type: MAC address for inner (1) or outer (0) header
785598f3697fSKumar Sanghvi  *      @sleep_ok: call is allowed to sleep
785698f3697fSKumar Sanghvi  *
785798f3697fSKumar Sanghvi  *      Allocates an MPS entry with specified MAC address and VNI value.
785898f3697fSKumar Sanghvi  *
785998f3697fSKumar Sanghvi  *      Returns a negative error number or the allocated index for this mac.
786098f3697fSKumar Sanghvi  */
t4_alloc_encap_mac_filt(struct adapter * adap,unsigned int viid,const u8 * addr,const u8 * mask,unsigned int vni,unsigned int vni_mask,u8 dip_hit,u8 lookup_type,bool sleep_ok)786198f3697fSKumar Sanghvi int t4_alloc_encap_mac_filt(struct adapter *adap, unsigned int viid,
786298f3697fSKumar Sanghvi 			    const u8 *addr, const u8 *mask, unsigned int vni,
786398f3697fSKumar Sanghvi 			    unsigned int vni_mask, u8 dip_hit, u8 lookup_type,
786498f3697fSKumar Sanghvi 			    bool sleep_ok)
786598f3697fSKumar Sanghvi {
786698f3697fSKumar Sanghvi 	struct fw_vi_mac_cmd c;
786798f3697fSKumar Sanghvi 	struct fw_vi_mac_vni *p = c.u.exact_vni;
786898f3697fSKumar Sanghvi 	int ret = 0;
786998f3697fSKumar Sanghvi 	u32 val;
787098f3697fSKumar Sanghvi 
787198f3697fSKumar Sanghvi 	memset(&c, 0, sizeof(c));
787298f3697fSKumar Sanghvi 	c.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_MAC_CMD) |
787398f3697fSKumar Sanghvi 				   FW_CMD_REQUEST_F | FW_CMD_WRITE_F |
787498f3697fSKumar Sanghvi 				   FW_VI_MAC_CMD_VIID_V(viid));
787598f3697fSKumar Sanghvi 	val = FW_CMD_LEN16_V(1) |
787698f3697fSKumar Sanghvi 	      FW_VI_MAC_CMD_ENTRY_TYPE_V(FW_VI_MAC_TYPE_EXACTMAC_VNI);
787798f3697fSKumar Sanghvi 	c.freemacs_to_len16 = cpu_to_be32(val);
787898f3697fSKumar Sanghvi 	p->valid_to_idx = cpu_to_be16(FW_VI_MAC_CMD_VALID_F |
787998f3697fSKumar Sanghvi 				      FW_VI_MAC_CMD_IDX_V(FW_VI_MAC_ADD_MAC));
788098f3697fSKumar Sanghvi 	memcpy(p->macaddr, addr, sizeof(p->macaddr));
788198f3697fSKumar Sanghvi 	memcpy(p->macaddr_mask, mask, sizeof(p->macaddr_mask));
788298f3697fSKumar Sanghvi 
788398f3697fSKumar Sanghvi 	p->lookup_type_to_vni =
788498f3697fSKumar Sanghvi 		cpu_to_be32(FW_VI_MAC_CMD_VNI_V(vni) |
788598f3697fSKumar Sanghvi 			    FW_VI_MAC_CMD_DIP_HIT_V(dip_hit) |
788698f3697fSKumar Sanghvi 			    FW_VI_MAC_CMD_LOOKUP_TYPE_V(lookup_type));
788798f3697fSKumar Sanghvi 	p->vni_mask_pkd = cpu_to_be32(FW_VI_MAC_CMD_VNI_MASK_V(vni_mask));
788898f3697fSKumar Sanghvi 	ret = t4_wr_mbox_meat(adap, adap->mbox, &c, sizeof(c), &c, sleep_ok);
788998f3697fSKumar Sanghvi 	if (ret == 0)
789098f3697fSKumar Sanghvi 		ret = FW_VI_MAC_CMD_IDX_G(be16_to_cpu(p->valid_to_idx));
789198f3697fSKumar Sanghvi 	return ret;
789298f3697fSKumar Sanghvi }
789398f3697fSKumar Sanghvi 
789498f3697fSKumar Sanghvi /**
7895846eac3fSGanesh Goudar  *	t4_alloc_raw_mac_filt - Adds a mac entry in mps tcam
7896846eac3fSGanesh Goudar  *	@adap: the adapter
7897846eac3fSGanesh Goudar  *	@viid: the VI id
789829bbf5d7SRahul Lakkireddy  *	@addr: the MAC address
7899846eac3fSGanesh Goudar  *	@mask: the mask
7900846eac3fSGanesh Goudar  *	@idx: index at which to add this entry
7901846eac3fSGanesh Goudar  *	@lookup_type: MAC address for inner (1) or outer (0) header
790229bbf5d7SRahul Lakkireddy  *	@port_id: the port index
7903846eac3fSGanesh Goudar  *	@sleep_ok: call is allowed to sleep
7904846eac3fSGanesh Goudar  *
7905846eac3fSGanesh Goudar  *	Adds the mac entry at the specified index using raw mac interface.
7906846eac3fSGanesh Goudar  *
7907846eac3fSGanesh Goudar  *	Returns a negative error number or the allocated index for this mac.
7908846eac3fSGanesh Goudar  */
t4_alloc_raw_mac_filt(struct adapter * adap,unsigned int viid,const u8 * addr,const u8 * mask,unsigned int idx,u8 lookup_type,u8 port_id,bool sleep_ok)7909846eac3fSGanesh Goudar int t4_alloc_raw_mac_filt(struct adapter *adap, unsigned int viid,
7910846eac3fSGanesh Goudar 			  const u8 *addr, const u8 *mask, unsigned int idx,
7911846eac3fSGanesh Goudar 			  u8 lookup_type, u8 port_id, bool sleep_ok)
7912846eac3fSGanesh Goudar {
7913846eac3fSGanesh Goudar 	int ret = 0;
7914846eac3fSGanesh Goudar 	struct fw_vi_mac_cmd c;
7915846eac3fSGanesh Goudar 	struct fw_vi_mac_raw *p = &c.u.raw;
7916846eac3fSGanesh Goudar 	u32 val;
7917846eac3fSGanesh Goudar 
7918846eac3fSGanesh Goudar 	memset(&c, 0, sizeof(c));
7919846eac3fSGanesh Goudar 	c.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_MAC_CMD) |
7920846eac3fSGanesh Goudar 				   FW_CMD_REQUEST_F | FW_CMD_WRITE_F |
7921846eac3fSGanesh Goudar 				   FW_VI_MAC_CMD_VIID_V(viid));
7922846eac3fSGanesh Goudar 	val = FW_CMD_LEN16_V(1) |
7923846eac3fSGanesh Goudar 	      FW_VI_MAC_CMD_ENTRY_TYPE_V(FW_VI_MAC_TYPE_RAW);
7924846eac3fSGanesh Goudar 	c.freemacs_to_len16 = cpu_to_be32(val);
7925846eac3fSGanesh Goudar 
7926846eac3fSGanesh Goudar 	/* Specify that this is an inner mac address */
7927846eac3fSGanesh Goudar 	p->raw_idx_pkd = cpu_to_be32(FW_VI_MAC_CMD_RAW_IDX_V(idx));
7928846eac3fSGanesh Goudar 
7929846eac3fSGanesh Goudar 	/* Lookup Type. Outer header: 0, Inner header: 1 */
7930846eac3fSGanesh Goudar 	p->data0_pkd = cpu_to_be32(DATALKPTYPE_V(lookup_type) |
7931846eac3fSGanesh Goudar 				   DATAPORTNUM_V(port_id));
7932846eac3fSGanesh Goudar 	/* Lookup mask and port mask */
7933846eac3fSGanesh Goudar 	p->data0m_pkd = cpu_to_be64(DATALKPTYPE_V(DATALKPTYPE_M) |
7934846eac3fSGanesh Goudar 				    DATAPORTNUM_V(DATAPORTNUM_M));
7935846eac3fSGanesh Goudar 
7936846eac3fSGanesh Goudar 	/* Copy the address and the mask */
7937846eac3fSGanesh Goudar 	memcpy((u8 *)&p->data1[0] + 2, addr, ETH_ALEN);
7938846eac3fSGanesh Goudar 	memcpy((u8 *)&p->data1m[0] + 2, mask, ETH_ALEN);
7939846eac3fSGanesh Goudar 
7940846eac3fSGanesh Goudar 	ret = t4_wr_mbox_meat(adap, adap->mbox, &c, sizeof(c), &c, sleep_ok);
7941846eac3fSGanesh Goudar 	if (ret == 0) {
7942846eac3fSGanesh Goudar 		ret = FW_VI_MAC_CMD_RAW_IDX_G(be32_to_cpu(p->raw_idx_pkd));
7943846eac3fSGanesh Goudar 		if (ret != idx)
7944846eac3fSGanesh Goudar 			ret = -ENOMEM;
7945846eac3fSGanesh Goudar 	}
7946846eac3fSGanesh Goudar 
7947846eac3fSGanesh Goudar 	return ret;
7948846eac3fSGanesh Goudar }
7949846eac3fSGanesh Goudar 
7950846eac3fSGanesh Goudar /**
7951f7917c00SJeff Kirsher  *	t4_alloc_mac_filt - allocates exact-match filters for MAC addresses
7952f7917c00SJeff Kirsher  *	@adap: the adapter
7953f7917c00SJeff Kirsher  *	@mbox: mailbox to use for the FW command
7954f7917c00SJeff Kirsher  *	@viid: the VI id
7955f7917c00SJeff Kirsher  *	@free: if true any existing filters for this VI id are first removed
7956f7917c00SJeff Kirsher  *	@naddr: the number of MAC addresses to allocate filters for (up to 7)
7957f7917c00SJeff Kirsher  *	@addr: the MAC address(es)
7958f7917c00SJeff Kirsher  *	@idx: where to store the index of each allocated filter
7959f7917c00SJeff Kirsher  *	@hash: pointer to hash address filter bitmap
7960f7917c00SJeff Kirsher  *	@sleep_ok: call is allowed to sleep
7961f7917c00SJeff Kirsher  *
7962f7917c00SJeff Kirsher  *	Allocates an exact-match filter for each of the supplied addresses and
7963f7917c00SJeff Kirsher  *	sets it to the corresponding address.  If @idx is not %NULL it should
7964f7917c00SJeff Kirsher  *	have at least @naddr entries, each of which will be set to the index of
7965f7917c00SJeff Kirsher  *	the filter allocated for the corresponding MAC address.  If a filter
7966f7917c00SJeff Kirsher  *	could not be allocated for an address its index is set to 0xffff.
7967f7917c00SJeff Kirsher  *	If @hash is not %NULL addresses that fail to allocate an exact filter
7968f7917c00SJeff Kirsher  *	are hashed and update the hash filter bitmap pointed at by @hash.
7969f7917c00SJeff Kirsher  *
7970f7917c00SJeff Kirsher  *	Returns a negative error number or the number of filters allocated.
7971f7917c00SJeff Kirsher  */
t4_alloc_mac_filt(struct adapter * adap,unsigned int mbox,unsigned int viid,bool free,unsigned int naddr,const u8 ** addr,u16 * idx,u64 * hash,bool sleep_ok)7972f7917c00SJeff Kirsher int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox,
7973f7917c00SJeff Kirsher 		      unsigned int viid, bool free, unsigned int naddr,
7974f7917c00SJeff Kirsher 		      const u8 **addr, u16 *idx, u64 *hash, bool sleep_ok)
7975f7917c00SJeff Kirsher {
79763ccc6cf7SHariprasad Shenai 	int offset, ret = 0;
7977f7917c00SJeff Kirsher 	struct fw_vi_mac_cmd c;
79783ccc6cf7SHariprasad Shenai 	unsigned int nfilters = 0;
79793ccc6cf7SHariprasad Shenai 	unsigned int max_naddr = adap->params.arch.mps_tcam_size;
79803ccc6cf7SHariprasad Shenai 	unsigned int rem = naddr;
7981f7917c00SJeff Kirsher 
79823ccc6cf7SHariprasad Shenai 	if (naddr > max_naddr)
7983f7917c00SJeff Kirsher 		return -EINVAL;
7984f7917c00SJeff Kirsher 
79853ccc6cf7SHariprasad Shenai 	for (offset = 0; offset < naddr ; /**/) {
79863ccc6cf7SHariprasad Shenai 		unsigned int fw_naddr = (rem < ARRAY_SIZE(c.u.exact) ?
79873ccc6cf7SHariprasad Shenai 					 rem : ARRAY_SIZE(c.u.exact));
79883ccc6cf7SHariprasad Shenai 		size_t len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd,
79893ccc6cf7SHariprasad Shenai 						     u.exact[fw_naddr]), 16);
79903ccc6cf7SHariprasad Shenai 		struct fw_vi_mac_exact *p;
79913ccc6cf7SHariprasad Shenai 		int i;
7992f7917c00SJeff Kirsher 
7993f7917c00SJeff Kirsher 		memset(&c, 0, sizeof(c));
7994f404f80cSHariprasad Shenai 		c.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_MAC_CMD) |
79953ccc6cf7SHariprasad Shenai 					   FW_CMD_REQUEST_F |
79963ccc6cf7SHariprasad Shenai 					   FW_CMD_WRITE_F |
79973ccc6cf7SHariprasad Shenai 					   FW_CMD_EXEC_V(free) |
7998f7917c00SJeff Kirsher 					   FW_VI_MAC_CMD_VIID_V(viid));
79993ccc6cf7SHariprasad Shenai 		c.freemacs_to_len16 =
80003ccc6cf7SHariprasad Shenai 			cpu_to_be32(FW_VI_MAC_CMD_FREEMACS_V(free) |
80013ccc6cf7SHariprasad Shenai 				    FW_CMD_LEN16_V(len16));
8002f7917c00SJeff Kirsher 
80033ccc6cf7SHariprasad Shenai 		for (i = 0, p = c.u.exact; i < fw_naddr; i++, p++) {
8004f404f80cSHariprasad Shenai 			p->valid_to_idx =
8005f404f80cSHariprasad Shenai 				cpu_to_be16(FW_VI_MAC_CMD_VALID_F |
80063ccc6cf7SHariprasad Shenai 					    FW_VI_MAC_CMD_IDX_V(
80073ccc6cf7SHariprasad Shenai 						    FW_VI_MAC_ADD_MAC));
80083ccc6cf7SHariprasad Shenai 			memcpy(p->macaddr, addr[offset + i],
80093ccc6cf7SHariprasad Shenai 			       sizeof(p->macaddr));
8010f7917c00SJeff Kirsher 		}
8011f7917c00SJeff Kirsher 
80123ccc6cf7SHariprasad Shenai 		/* It's okay if we run out of space in our MAC address arena.
80133ccc6cf7SHariprasad Shenai 		 * Some of the addresses we submit may get stored so we need
80143ccc6cf7SHariprasad Shenai 		 * to run through the reply to see what the results were ...
80153ccc6cf7SHariprasad Shenai 		 */
8016f7917c00SJeff Kirsher 		ret = t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), &c, sleep_ok);
80173ccc6cf7SHariprasad Shenai 		if (ret && ret != -FW_ENOMEM)
80183ccc6cf7SHariprasad Shenai 			break;
8019f7917c00SJeff Kirsher 
80203ccc6cf7SHariprasad Shenai 		for (i = 0, p = c.u.exact; i < fw_naddr; i++, p++) {
80213ccc6cf7SHariprasad Shenai 			u16 index = FW_VI_MAC_CMD_IDX_G(
80223ccc6cf7SHariprasad Shenai 					be16_to_cpu(p->valid_to_idx));
8023f7917c00SJeff Kirsher 
8024f7917c00SJeff Kirsher 			if (idx)
80253ccc6cf7SHariprasad Shenai 				idx[offset + i] = (index >= max_naddr ?
80263ccc6cf7SHariprasad Shenai 						   0xffff : index);
80270a57a536SSantosh Rastapur 			if (index < max_naddr)
80283ccc6cf7SHariprasad Shenai 				nfilters++;
8029f7917c00SJeff Kirsher 			else if (hash)
80303ccc6cf7SHariprasad Shenai 				*hash |= (1ULL <<
80313ccc6cf7SHariprasad Shenai 					  hash_mac_addr(addr[offset + i]));
8032f7917c00SJeff Kirsher 		}
80333ccc6cf7SHariprasad Shenai 
80343ccc6cf7SHariprasad Shenai 		free = false;
80353ccc6cf7SHariprasad Shenai 		offset += fw_naddr;
80363ccc6cf7SHariprasad Shenai 		rem -= fw_naddr;
80373ccc6cf7SHariprasad Shenai 	}
80383ccc6cf7SHariprasad Shenai 
80393ccc6cf7SHariprasad Shenai 	if (ret == 0 || ret == -FW_ENOMEM)
80403ccc6cf7SHariprasad Shenai 		ret = nfilters;
8041f7917c00SJeff Kirsher 	return ret;
8042f7917c00SJeff Kirsher }
8043f7917c00SJeff Kirsher 
8044f7917c00SJeff Kirsher /**
8045fc08a01aSHariprasad Shenai  *	t4_free_mac_filt - frees exact-match filters of given MAC addresses
8046fc08a01aSHariprasad Shenai  *	@adap: the adapter
8047fc08a01aSHariprasad Shenai  *	@mbox: mailbox to use for the FW command
8048fc08a01aSHariprasad Shenai  *	@viid: the VI id
8049fc08a01aSHariprasad Shenai  *	@naddr: the number of MAC addresses to allocate filters for (up to 7)
8050fc08a01aSHariprasad Shenai  *	@addr: the MAC address(es)
8051fc08a01aSHariprasad Shenai  *	@sleep_ok: call is allowed to sleep
8052fc08a01aSHariprasad Shenai  *
8053fc08a01aSHariprasad Shenai  *	Frees the exact-match filter for each of the supplied addresses
8054fc08a01aSHariprasad Shenai  *
8055fc08a01aSHariprasad Shenai  *	Returns a negative error number or the number of filters freed.
8056fc08a01aSHariprasad Shenai  */
t4_free_mac_filt(struct adapter * adap,unsigned int mbox,unsigned int viid,unsigned int naddr,const u8 ** addr,bool sleep_ok)8057fc08a01aSHariprasad Shenai int t4_free_mac_filt(struct adapter *adap, unsigned int mbox,
8058fc08a01aSHariprasad Shenai 		     unsigned int viid, unsigned int naddr,
8059fc08a01aSHariprasad Shenai 		     const u8 **addr, bool sleep_ok)
8060fc08a01aSHariprasad Shenai {
8061fc08a01aSHariprasad Shenai 	int offset, ret = 0;
8062fc08a01aSHariprasad Shenai 	struct fw_vi_mac_cmd c;
8063fc08a01aSHariprasad Shenai 	unsigned int nfilters = 0;
8064fc08a01aSHariprasad Shenai 	unsigned int max_naddr = is_t4(adap->params.chip) ?
8065fc08a01aSHariprasad Shenai 				       NUM_MPS_CLS_SRAM_L_INSTANCES :
8066fc08a01aSHariprasad Shenai 				       NUM_MPS_T5_CLS_SRAM_L_INSTANCES;
8067fc08a01aSHariprasad Shenai 	unsigned int rem = naddr;
8068fc08a01aSHariprasad Shenai 
8069fc08a01aSHariprasad Shenai 	if (naddr > max_naddr)
8070fc08a01aSHariprasad Shenai 		return -EINVAL;
8071fc08a01aSHariprasad Shenai 
8072fc08a01aSHariprasad Shenai 	for (offset = 0; offset < (int)naddr ; /**/) {
8073fc08a01aSHariprasad Shenai 		unsigned int fw_naddr = (rem < ARRAY_SIZE(c.u.exact)
8074fc08a01aSHariprasad Shenai 					 ? rem
8075fc08a01aSHariprasad Shenai 					 : ARRAY_SIZE(c.u.exact));
8076fc08a01aSHariprasad Shenai 		size_t len16 = DIV_ROUND_UP(offsetof(struct fw_vi_mac_cmd,
8077fc08a01aSHariprasad Shenai 						     u.exact[fw_naddr]), 16);
8078fc08a01aSHariprasad Shenai 		struct fw_vi_mac_exact *p;
8079fc08a01aSHariprasad Shenai 		int i;
8080fc08a01aSHariprasad Shenai 
8081fc08a01aSHariprasad Shenai 		memset(&c, 0, sizeof(c));
8082fc08a01aSHariprasad Shenai 		c.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_MAC_CMD) |
8083fc08a01aSHariprasad Shenai 				     FW_CMD_REQUEST_F |
8084fc08a01aSHariprasad Shenai 				     FW_CMD_WRITE_F |
8085fc08a01aSHariprasad Shenai 				     FW_CMD_EXEC_V(0) |
8086fc08a01aSHariprasad Shenai 				     FW_VI_MAC_CMD_VIID_V(viid));
8087fc08a01aSHariprasad Shenai 		c.freemacs_to_len16 =
8088fc08a01aSHariprasad Shenai 				cpu_to_be32(FW_VI_MAC_CMD_FREEMACS_V(0) |
8089fc08a01aSHariprasad Shenai 					    FW_CMD_LEN16_V(len16));
8090fc08a01aSHariprasad Shenai 
8091fc08a01aSHariprasad Shenai 		for (i = 0, p = c.u.exact; i < (int)fw_naddr; i++, p++) {
8092fc08a01aSHariprasad Shenai 			p->valid_to_idx = cpu_to_be16(
8093fc08a01aSHariprasad Shenai 				FW_VI_MAC_CMD_VALID_F |
8094fc08a01aSHariprasad Shenai 				FW_VI_MAC_CMD_IDX_V(FW_VI_MAC_MAC_BASED_FREE));
8095fc08a01aSHariprasad Shenai 			memcpy(p->macaddr, addr[offset+i], sizeof(p->macaddr));
8096fc08a01aSHariprasad Shenai 		}
8097fc08a01aSHariprasad Shenai 
8098fc08a01aSHariprasad Shenai 		ret = t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), &c, sleep_ok);
8099fc08a01aSHariprasad Shenai 		if (ret)
8100fc08a01aSHariprasad Shenai 			break;
8101fc08a01aSHariprasad Shenai 
8102fc08a01aSHariprasad Shenai 		for (i = 0, p = c.u.exact; i < fw_naddr; i++, p++) {
8103fc08a01aSHariprasad Shenai 			u16 index = FW_VI_MAC_CMD_IDX_G(
8104fc08a01aSHariprasad Shenai 						be16_to_cpu(p->valid_to_idx));
8105fc08a01aSHariprasad Shenai 
8106fc08a01aSHariprasad Shenai 			if (index < max_naddr)
8107fc08a01aSHariprasad Shenai 				nfilters++;
8108fc08a01aSHariprasad Shenai 		}
8109fc08a01aSHariprasad Shenai 
8110fc08a01aSHariprasad Shenai 		offset += fw_naddr;
8111fc08a01aSHariprasad Shenai 		rem -= fw_naddr;
8112fc08a01aSHariprasad Shenai 	}
8113fc08a01aSHariprasad Shenai 
8114fc08a01aSHariprasad Shenai 	if (ret == 0)
8115fc08a01aSHariprasad Shenai 		ret = nfilters;
8116fc08a01aSHariprasad Shenai 	return ret;
8117fc08a01aSHariprasad Shenai }
8118fc08a01aSHariprasad Shenai 
8119fc08a01aSHariprasad Shenai /**
8120f7917c00SJeff Kirsher  *	t4_change_mac - modifies the exact-match filter for a MAC address
8121f7917c00SJeff Kirsher  *	@adap: the adapter
8122f7917c00SJeff Kirsher  *	@mbox: mailbox to use for the FW command
8123f7917c00SJeff Kirsher  *	@viid: the VI id
8124f7917c00SJeff Kirsher  *	@idx: index of existing filter for old value of MAC address, or -1
8125f7917c00SJeff Kirsher  *	@addr: the new MAC address value
8126f7917c00SJeff Kirsher  *	@persist: whether a new MAC allocation should be persistent
812729bbf5d7SRahul Lakkireddy  *	@smt_idx: the destination to store the new SMT index.
8128f7917c00SJeff Kirsher  *
8129f7917c00SJeff Kirsher  *	Modifies an exact-match filter and sets it to the new MAC address.
8130f7917c00SJeff Kirsher  *	Note that in general it is not possible to modify the value of a given
8131f7917c00SJeff Kirsher  *	filter so the generic way to modify an address filter is to free the one
8132f7917c00SJeff Kirsher  *	being used by the old address value and allocate a new filter for the
8133f7917c00SJeff Kirsher  *	new address value.  @idx can be -1 if the address is a new addition.
8134f7917c00SJeff Kirsher  *
8135f7917c00SJeff Kirsher  *	Returns a negative error number or the index of the filter with the new
8136f7917c00SJeff Kirsher  *	MAC value.
8137f7917c00SJeff Kirsher  */
t4_change_mac(struct adapter * adap,unsigned int mbox,unsigned int viid,int idx,const u8 * addr,bool persist,u8 * smt_idx)8138f7917c00SJeff Kirsher int t4_change_mac(struct adapter *adap, unsigned int mbox, unsigned int viid,
813902d805dcSSantosh Rastapur 		  int idx, const u8 *addr, bool persist, u8 *smt_idx)
8140f7917c00SJeff Kirsher {
8141f7917c00SJeff Kirsher 	int ret, mode;
8142f7917c00SJeff Kirsher 	struct fw_vi_mac_cmd c;
8143f7917c00SJeff Kirsher 	struct fw_vi_mac_exact *p = c.u.exact;
81443ccc6cf7SHariprasad Shenai 	unsigned int max_mac_addr = adap->params.arch.mps_tcam_size;
8145f7917c00SJeff Kirsher 
8146f7917c00SJeff Kirsher 	if (idx < 0)                             /* new allocation */
8147f7917c00SJeff Kirsher 		idx = persist ? FW_VI_MAC_ADD_PERSIST_MAC : FW_VI_MAC_ADD_MAC;
814802d805dcSSantosh Rastapur 	mode = smt_idx ? FW_VI_MAC_SMT_AND_MPSTCAM : FW_VI_MAC_MPS_TCAM_ENTRY;
8149f7917c00SJeff Kirsher 
8150f7917c00SJeff Kirsher 	memset(&c, 0, sizeof(c));
8151f404f80cSHariprasad Shenai 	c.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_MAC_CMD) |
8152f404f80cSHariprasad Shenai 				   FW_CMD_REQUEST_F | FW_CMD_WRITE_F |
8153f404f80cSHariprasad Shenai 				   FW_VI_MAC_CMD_VIID_V(viid));
8154f404f80cSHariprasad Shenai 	c.freemacs_to_len16 = cpu_to_be32(FW_CMD_LEN16_V(1));
8155f404f80cSHariprasad Shenai 	p->valid_to_idx = cpu_to_be16(FW_VI_MAC_CMD_VALID_F |
81562b5fb1f2SHariprasad Shenai 				      FW_VI_MAC_CMD_SMAC_RESULT_V(mode) |
81572b5fb1f2SHariprasad Shenai 				      FW_VI_MAC_CMD_IDX_V(idx));
8158f7917c00SJeff Kirsher 	memcpy(p->macaddr, addr, sizeof(p->macaddr));
8159f7917c00SJeff Kirsher 
8160f7917c00SJeff Kirsher 	ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
8161f7917c00SJeff Kirsher 	if (ret == 0) {
8162f404f80cSHariprasad Shenai 		ret = FW_VI_MAC_CMD_IDX_G(be16_to_cpu(p->valid_to_idx));
81630a57a536SSantosh Rastapur 		if (ret >= max_mac_addr)
8164f7917c00SJeff Kirsher 			ret = -ENOMEM;
816502d805dcSSantosh Rastapur 		if (smt_idx) {
816602d805dcSSantosh Rastapur 			if (adap->params.viid_smt_extn_support) {
816702d805dcSSantosh Rastapur 				*smt_idx = FW_VI_MAC_CMD_SMTID_G
816802d805dcSSantosh Rastapur 						    (be32_to_cpu(c.op_to_viid));
816902d805dcSSantosh Rastapur 			} else {
817002d805dcSSantosh Rastapur 				/* In T4/T5, SMT contains 256 SMAC entries
817102d805dcSSantosh Rastapur 				 * organized in 128 rows of 2 entries each.
817202d805dcSSantosh Rastapur 				 * In T6, SMT contains 256 SMAC entries in
817302d805dcSSantosh Rastapur 				 * 256 rows.
817402d805dcSSantosh Rastapur 				 */
817502d805dcSSantosh Rastapur 				if (CHELSIO_CHIP_VERSION(adap->params.chip) <=
817602d805dcSSantosh Rastapur 								     CHELSIO_T5)
817702d805dcSSantosh Rastapur 					*smt_idx = (viid & FW_VIID_VIN_M) << 1;
817802d805dcSSantosh Rastapur 				else
817902d805dcSSantosh Rastapur 					*smt_idx = (viid & FW_VIID_VIN_M);
818002d805dcSSantosh Rastapur 			}
818102d805dcSSantosh Rastapur 		}
8182f7917c00SJeff Kirsher 	}
8183f7917c00SJeff Kirsher 	return ret;
8184f7917c00SJeff Kirsher }
8185f7917c00SJeff Kirsher 
8186f7917c00SJeff Kirsher /**
8187f7917c00SJeff Kirsher  *	t4_set_addr_hash - program the MAC inexact-match hash filter
8188f7917c00SJeff Kirsher  *	@adap: the adapter
8189f7917c00SJeff Kirsher  *	@mbox: mailbox to use for the FW command
8190f7917c00SJeff Kirsher  *	@viid: the VI id
8191f7917c00SJeff Kirsher  *	@ucast: whether the hash filter should also match unicast addresses
8192f7917c00SJeff Kirsher  *	@vec: the value to be written to the hash filter
8193f7917c00SJeff Kirsher  *	@sleep_ok: call is allowed to sleep
8194f7917c00SJeff Kirsher  *
8195f7917c00SJeff Kirsher  *	Sets the 64-bit inexact-match hash filter for a virtual interface.
8196f7917c00SJeff Kirsher  */
t4_set_addr_hash(struct adapter * adap,unsigned int mbox,unsigned int viid,bool ucast,u64 vec,bool sleep_ok)8197f7917c00SJeff Kirsher int t4_set_addr_hash(struct adapter *adap, unsigned int mbox, unsigned int viid,
8198f7917c00SJeff Kirsher 		     bool ucast, u64 vec, bool sleep_ok)
8199f7917c00SJeff Kirsher {
8200f7917c00SJeff Kirsher 	struct fw_vi_mac_cmd c;
8201f7917c00SJeff Kirsher 
8202f7917c00SJeff Kirsher 	memset(&c, 0, sizeof(c));
8203f404f80cSHariprasad Shenai 	c.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_MAC_CMD) |
8204f404f80cSHariprasad Shenai 				   FW_CMD_REQUEST_F | FW_CMD_WRITE_F |
8205f404f80cSHariprasad Shenai 				   FW_VI_ENABLE_CMD_VIID_V(viid));
8206f404f80cSHariprasad Shenai 	c.freemacs_to_len16 = cpu_to_be32(FW_VI_MAC_CMD_HASHVECEN_F |
82072b5fb1f2SHariprasad Shenai 					  FW_VI_MAC_CMD_HASHUNIEN_V(ucast) |
8208e2ac9628SHariprasad Shenai 					  FW_CMD_LEN16_V(1));
8209f7917c00SJeff Kirsher 	c.u.hash.hashvec = cpu_to_be64(vec);
8210f7917c00SJeff Kirsher 	return t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), NULL, sleep_ok);
8211f7917c00SJeff Kirsher }
8212f7917c00SJeff Kirsher 
8213f7917c00SJeff Kirsher /**
8214688848b1SAnish Bhatt  *      t4_enable_vi_params - enable/disable a virtual interface
8215688848b1SAnish Bhatt  *      @adap: the adapter
8216688848b1SAnish Bhatt  *      @mbox: mailbox to use for the FW command
8217688848b1SAnish Bhatt  *      @viid: the VI id
8218688848b1SAnish Bhatt  *      @rx_en: 1=enable Rx, 0=disable Rx
8219688848b1SAnish Bhatt  *      @tx_en: 1=enable Tx, 0=disable Tx
8220688848b1SAnish Bhatt  *      @dcb_en: 1=enable delivery of Data Center Bridging messages.
8221688848b1SAnish Bhatt  *
8222688848b1SAnish Bhatt  *      Enables/disables a virtual interface.  Note that setting DCB Enable
8223688848b1SAnish Bhatt  *      only makes sense when enabling a Virtual Interface ...
8224688848b1SAnish Bhatt  */
t4_enable_vi_params(struct adapter * adap,unsigned int mbox,unsigned int viid,bool rx_en,bool tx_en,bool dcb_en)8225688848b1SAnish Bhatt int t4_enable_vi_params(struct adapter *adap, unsigned int mbox,
8226688848b1SAnish Bhatt 			unsigned int viid, bool rx_en, bool tx_en, bool dcb_en)
8227688848b1SAnish Bhatt {
8228688848b1SAnish Bhatt 	struct fw_vi_enable_cmd c;
8229688848b1SAnish Bhatt 
8230688848b1SAnish Bhatt 	memset(&c, 0, sizeof(c));
8231f404f80cSHariprasad Shenai 	c.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_ENABLE_CMD) |
8232f404f80cSHariprasad Shenai 				   FW_CMD_REQUEST_F | FW_CMD_EXEC_F |
8233f404f80cSHariprasad Shenai 				   FW_VI_ENABLE_CMD_VIID_V(viid));
8234f404f80cSHariprasad Shenai 	c.ien_to_len16 = cpu_to_be32(FW_VI_ENABLE_CMD_IEN_V(rx_en) |
8235f404f80cSHariprasad Shenai 				     FW_VI_ENABLE_CMD_EEN_V(tx_en) |
8236f404f80cSHariprasad Shenai 				     FW_VI_ENABLE_CMD_DCB_INFO_V(dcb_en) |
8237f404f80cSHariprasad Shenai 				     FW_LEN16(c));
823830f00847SAnish Bhatt 	return t4_wr_mbox_ns(adap, mbox, &c, sizeof(c), NULL);
8239688848b1SAnish Bhatt }
8240688848b1SAnish Bhatt 
8241688848b1SAnish Bhatt /**
8242f7917c00SJeff Kirsher  *	t4_enable_vi - enable/disable a virtual interface
8243f7917c00SJeff Kirsher  *	@adap: the adapter
8244f7917c00SJeff Kirsher  *	@mbox: mailbox to use for the FW command
8245f7917c00SJeff Kirsher  *	@viid: the VI id
8246f7917c00SJeff Kirsher  *	@rx_en: 1=enable Rx, 0=disable Rx
8247f7917c00SJeff Kirsher  *	@tx_en: 1=enable Tx, 0=disable Tx
8248f7917c00SJeff Kirsher  *
8249f7917c00SJeff Kirsher  *	Enables/disables a virtual interface.
8250f7917c00SJeff Kirsher  */
t4_enable_vi(struct adapter * adap,unsigned int mbox,unsigned int viid,bool rx_en,bool tx_en)8251f7917c00SJeff Kirsher int t4_enable_vi(struct adapter *adap, unsigned int mbox, unsigned int viid,
8252f7917c00SJeff Kirsher 		 bool rx_en, bool tx_en)
8253f7917c00SJeff Kirsher {
8254688848b1SAnish Bhatt 	return t4_enable_vi_params(adap, mbox, viid, rx_en, tx_en, 0);
8255f7917c00SJeff Kirsher }
8256f7917c00SJeff Kirsher 
8257f7917c00SJeff Kirsher /**
8258e2f4f4e9SArjun Vynipadath  *	t4_enable_pi_params - enable/disable a Port's Virtual Interface
8259e2f4f4e9SArjun Vynipadath  *      @adap: the adapter
8260e2f4f4e9SArjun Vynipadath  *      @mbox: mailbox to use for the FW command
8261e2f4f4e9SArjun Vynipadath  *      @pi: the Port Information structure
8262e2f4f4e9SArjun Vynipadath  *      @rx_en: 1=enable Rx, 0=disable Rx
8263e2f4f4e9SArjun Vynipadath  *      @tx_en: 1=enable Tx, 0=disable Tx
8264e2f4f4e9SArjun Vynipadath  *      @dcb_en: 1=enable delivery of Data Center Bridging messages.
8265e2f4f4e9SArjun Vynipadath  *
8266e2f4f4e9SArjun Vynipadath  *      Enables/disables a Port's Virtual Interface.  Note that setting DCB
8267e2f4f4e9SArjun Vynipadath  *	Enable only makes sense when enabling a Virtual Interface ...
8268e2f4f4e9SArjun Vynipadath  *	If the Virtual Interface enable/disable operation is successful,
8269e2f4f4e9SArjun Vynipadath  *	we notify the OS-specific code of a potential Link Status change
8270e2f4f4e9SArjun Vynipadath  *	via the OS Contract API t4_os_link_changed().
8271e2f4f4e9SArjun Vynipadath  */
t4_enable_pi_params(struct adapter * adap,unsigned int mbox,struct port_info * pi,bool rx_en,bool tx_en,bool dcb_en)8272e2f4f4e9SArjun Vynipadath int t4_enable_pi_params(struct adapter *adap, unsigned int mbox,
8273e2f4f4e9SArjun Vynipadath 			struct port_info *pi,
8274e2f4f4e9SArjun Vynipadath 			bool rx_en, bool tx_en, bool dcb_en)
8275e2f4f4e9SArjun Vynipadath {
8276e2f4f4e9SArjun Vynipadath 	int ret = t4_enable_vi_params(adap, mbox, pi->viid,
8277e2f4f4e9SArjun Vynipadath 				      rx_en, tx_en, dcb_en);
8278e2f4f4e9SArjun Vynipadath 	if (ret)
8279e2f4f4e9SArjun Vynipadath 		return ret;
8280e2f4f4e9SArjun Vynipadath 	t4_os_link_changed(adap, pi->port_id,
8281e2f4f4e9SArjun Vynipadath 			   rx_en && tx_en && pi->link_cfg.link_ok);
8282e2f4f4e9SArjun Vynipadath 	return 0;
8283e2f4f4e9SArjun Vynipadath }
8284e2f4f4e9SArjun Vynipadath 
8285e2f4f4e9SArjun Vynipadath /**
8286f7917c00SJeff Kirsher  *	t4_identify_port - identify a VI's port by blinking its LED
8287f7917c00SJeff Kirsher  *	@adap: the adapter
8288f7917c00SJeff Kirsher  *	@mbox: mailbox to use for the FW command
8289f7917c00SJeff Kirsher  *	@viid: the VI id
8290f7917c00SJeff Kirsher  *	@nblinks: how many times to blink LED at 2.5 Hz
8291f7917c00SJeff Kirsher  *
8292f7917c00SJeff Kirsher  *	Identifies a VI's port by blinking its LED.
8293f7917c00SJeff Kirsher  */
t4_identify_port(struct adapter * adap,unsigned int mbox,unsigned int viid,unsigned int nblinks)8294f7917c00SJeff Kirsher int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid,
8295f7917c00SJeff Kirsher 		     unsigned int nblinks)
8296f7917c00SJeff Kirsher {
8297f7917c00SJeff Kirsher 	struct fw_vi_enable_cmd c;
8298f7917c00SJeff Kirsher 
82990062b15cSVipul Pandya 	memset(&c, 0, sizeof(c));
8300f404f80cSHariprasad Shenai 	c.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_ENABLE_CMD) |
8301f404f80cSHariprasad Shenai 				   FW_CMD_REQUEST_F | FW_CMD_EXEC_F |
8302f404f80cSHariprasad Shenai 				   FW_VI_ENABLE_CMD_VIID_V(viid));
8303f404f80cSHariprasad Shenai 	c.ien_to_len16 = cpu_to_be32(FW_VI_ENABLE_CMD_LED_F | FW_LEN16(c));
8304f404f80cSHariprasad Shenai 	c.blinkdur = cpu_to_be16(nblinks);
8305f7917c00SJeff Kirsher 	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
8306f7917c00SJeff Kirsher }
8307f7917c00SJeff Kirsher 
8308f7917c00SJeff Kirsher /**
8309ebf4dc2bSHariprasad Shenai  *	t4_iq_stop - stop an ingress queue and its FLs
8310ebf4dc2bSHariprasad Shenai  *	@adap: the adapter
8311ebf4dc2bSHariprasad Shenai  *	@mbox: mailbox to use for the FW command
8312ebf4dc2bSHariprasad Shenai  *	@pf: the PF owning the queues
8313ebf4dc2bSHariprasad Shenai  *	@vf: the VF owning the queues
8314ebf4dc2bSHariprasad Shenai  *	@iqtype: the ingress queue type (FW_IQ_TYPE_FL_INT_CAP, etc.)
8315ebf4dc2bSHariprasad Shenai  *	@iqid: ingress queue id
8316ebf4dc2bSHariprasad Shenai  *	@fl0id: FL0 queue id or 0xffff if no attached FL0
8317ebf4dc2bSHariprasad Shenai  *	@fl1id: FL1 queue id or 0xffff if no attached FL1
8318ebf4dc2bSHariprasad Shenai  *
8319ebf4dc2bSHariprasad Shenai  *	Stops an ingress queue and its associated FLs, if any.  This causes
8320ebf4dc2bSHariprasad Shenai  *	any current or future data/messages destined for these queues to be
8321ebf4dc2bSHariprasad Shenai  *	tossed.
8322ebf4dc2bSHariprasad Shenai  */
t4_iq_stop(struct adapter * adap,unsigned int mbox,unsigned int pf,unsigned int vf,unsigned int iqtype,unsigned int iqid,unsigned int fl0id,unsigned int fl1id)8323ebf4dc2bSHariprasad Shenai int t4_iq_stop(struct adapter *adap, unsigned int mbox, unsigned int pf,
8324ebf4dc2bSHariprasad Shenai 	       unsigned int vf, unsigned int iqtype, unsigned int iqid,
8325ebf4dc2bSHariprasad Shenai 	       unsigned int fl0id, unsigned int fl1id)
8326ebf4dc2bSHariprasad Shenai {
8327ebf4dc2bSHariprasad Shenai 	struct fw_iq_cmd c;
8328ebf4dc2bSHariprasad Shenai 
8329ebf4dc2bSHariprasad Shenai 	memset(&c, 0, sizeof(c));
8330ebf4dc2bSHariprasad Shenai 	c.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_IQ_CMD) | FW_CMD_REQUEST_F |
8331ebf4dc2bSHariprasad Shenai 				  FW_CMD_EXEC_F | FW_IQ_CMD_PFN_V(pf) |
8332ebf4dc2bSHariprasad Shenai 				  FW_IQ_CMD_VFN_V(vf));
8333ebf4dc2bSHariprasad Shenai 	c.alloc_to_len16 = cpu_to_be32(FW_IQ_CMD_IQSTOP_F | FW_LEN16(c));
8334ebf4dc2bSHariprasad Shenai 	c.type_to_iqandstindex = cpu_to_be32(FW_IQ_CMD_TYPE_V(iqtype));
8335ebf4dc2bSHariprasad Shenai 	c.iqid = cpu_to_be16(iqid);
8336ebf4dc2bSHariprasad Shenai 	c.fl0id = cpu_to_be16(fl0id);
8337ebf4dc2bSHariprasad Shenai 	c.fl1id = cpu_to_be16(fl1id);
8338ebf4dc2bSHariprasad Shenai 	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
8339ebf4dc2bSHariprasad Shenai }
8340ebf4dc2bSHariprasad Shenai 
8341ebf4dc2bSHariprasad Shenai /**
8342f7917c00SJeff Kirsher  *	t4_iq_free - free an ingress queue and its FLs
8343f7917c00SJeff Kirsher  *	@adap: the adapter
8344f7917c00SJeff Kirsher  *	@mbox: mailbox to use for the FW command
8345f7917c00SJeff Kirsher  *	@pf: the PF owning the queues
8346f7917c00SJeff Kirsher  *	@vf: the VF owning the queues
8347f7917c00SJeff Kirsher  *	@iqtype: the ingress queue type
8348f7917c00SJeff Kirsher  *	@iqid: ingress queue id
8349f7917c00SJeff Kirsher  *	@fl0id: FL0 queue id or 0xffff if no attached FL0
8350f7917c00SJeff Kirsher  *	@fl1id: FL1 queue id or 0xffff if no attached FL1
8351f7917c00SJeff Kirsher  *
8352f7917c00SJeff Kirsher  *	Frees an ingress queue and its associated FLs, if any.
8353f7917c00SJeff Kirsher  */
t4_iq_free(struct adapter * adap,unsigned int mbox,unsigned int pf,unsigned int vf,unsigned int iqtype,unsigned int iqid,unsigned int fl0id,unsigned int fl1id)8354f7917c00SJeff Kirsher int t4_iq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
8355f7917c00SJeff Kirsher 	       unsigned int vf, unsigned int iqtype, unsigned int iqid,
8356f7917c00SJeff Kirsher 	       unsigned int fl0id, unsigned int fl1id)
8357f7917c00SJeff Kirsher {
8358f7917c00SJeff Kirsher 	struct fw_iq_cmd c;
8359f7917c00SJeff Kirsher 
8360f7917c00SJeff Kirsher 	memset(&c, 0, sizeof(c));
8361f404f80cSHariprasad Shenai 	c.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_IQ_CMD) | FW_CMD_REQUEST_F |
83626e4b51a6SHariprasad Shenai 				  FW_CMD_EXEC_F | FW_IQ_CMD_PFN_V(pf) |
83636e4b51a6SHariprasad Shenai 				  FW_IQ_CMD_VFN_V(vf));
8364f404f80cSHariprasad Shenai 	c.alloc_to_len16 = cpu_to_be32(FW_IQ_CMD_FREE_F | FW_LEN16(c));
8365f404f80cSHariprasad Shenai 	c.type_to_iqandstindex = cpu_to_be32(FW_IQ_CMD_TYPE_V(iqtype));
8366f404f80cSHariprasad Shenai 	c.iqid = cpu_to_be16(iqid);
8367f404f80cSHariprasad Shenai 	c.fl0id = cpu_to_be16(fl0id);
8368f404f80cSHariprasad Shenai 	c.fl1id = cpu_to_be16(fl1id);
8369f7917c00SJeff Kirsher 	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
8370f7917c00SJeff Kirsher }
8371f7917c00SJeff Kirsher 
8372f7917c00SJeff Kirsher /**
8373f7917c00SJeff Kirsher  *	t4_eth_eq_free - free an Ethernet egress queue
8374f7917c00SJeff Kirsher  *	@adap: the adapter
8375f7917c00SJeff Kirsher  *	@mbox: mailbox to use for the FW command
8376f7917c00SJeff Kirsher  *	@pf: the PF owning the queue
8377f7917c00SJeff Kirsher  *	@vf: the VF owning the queue
8378f7917c00SJeff Kirsher  *	@eqid: egress queue id
8379f7917c00SJeff Kirsher  *
8380f7917c00SJeff Kirsher  *	Frees an Ethernet egress queue.
8381f7917c00SJeff Kirsher  */
t4_eth_eq_free(struct adapter * adap,unsigned int mbox,unsigned int pf,unsigned int vf,unsigned int eqid)8382f7917c00SJeff Kirsher int t4_eth_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
8383f7917c00SJeff Kirsher 		   unsigned int vf, unsigned int eqid)
8384f7917c00SJeff Kirsher {
8385f7917c00SJeff Kirsher 	struct fw_eq_eth_cmd c;
8386f7917c00SJeff Kirsher 
8387f7917c00SJeff Kirsher 	memset(&c, 0, sizeof(c));
8388f404f80cSHariprasad Shenai 	c.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_EQ_ETH_CMD) |
8389f404f80cSHariprasad Shenai 				  FW_CMD_REQUEST_F | FW_CMD_EXEC_F |
8390f404f80cSHariprasad Shenai 				  FW_EQ_ETH_CMD_PFN_V(pf) |
83916e4b51a6SHariprasad Shenai 				  FW_EQ_ETH_CMD_VFN_V(vf));
8392f404f80cSHariprasad Shenai 	c.alloc_to_len16 = cpu_to_be32(FW_EQ_ETH_CMD_FREE_F | FW_LEN16(c));
8393f404f80cSHariprasad Shenai 	c.eqid_pkd = cpu_to_be32(FW_EQ_ETH_CMD_EQID_V(eqid));
8394f7917c00SJeff Kirsher 	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
8395f7917c00SJeff Kirsher }
8396f7917c00SJeff Kirsher 
8397f7917c00SJeff Kirsher /**
8398f7917c00SJeff Kirsher  *	t4_ctrl_eq_free - free a control egress queue
8399f7917c00SJeff Kirsher  *	@adap: the adapter
8400f7917c00SJeff Kirsher  *	@mbox: mailbox to use for the FW command
8401f7917c00SJeff Kirsher  *	@pf: the PF owning the queue
8402f7917c00SJeff Kirsher  *	@vf: the VF owning the queue
8403f7917c00SJeff Kirsher  *	@eqid: egress queue id
8404f7917c00SJeff Kirsher  *
8405f7917c00SJeff Kirsher  *	Frees a control egress queue.
8406f7917c00SJeff Kirsher  */
t4_ctrl_eq_free(struct adapter * adap,unsigned int mbox,unsigned int pf,unsigned int vf,unsigned int eqid)8407f7917c00SJeff Kirsher int t4_ctrl_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
8408f7917c00SJeff Kirsher 		    unsigned int vf, unsigned int eqid)
8409f7917c00SJeff Kirsher {
8410f7917c00SJeff Kirsher 	struct fw_eq_ctrl_cmd c;
8411f7917c00SJeff Kirsher 
8412f7917c00SJeff Kirsher 	memset(&c, 0, sizeof(c));
8413f404f80cSHariprasad Shenai 	c.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_EQ_CTRL_CMD) |
8414f404f80cSHariprasad Shenai 				  FW_CMD_REQUEST_F | FW_CMD_EXEC_F |
8415f404f80cSHariprasad Shenai 				  FW_EQ_CTRL_CMD_PFN_V(pf) |
84166e4b51a6SHariprasad Shenai 				  FW_EQ_CTRL_CMD_VFN_V(vf));
8417f404f80cSHariprasad Shenai 	c.alloc_to_len16 = cpu_to_be32(FW_EQ_CTRL_CMD_FREE_F | FW_LEN16(c));
8418f404f80cSHariprasad Shenai 	c.cmpliqid_eqid = cpu_to_be32(FW_EQ_CTRL_CMD_EQID_V(eqid));
8419f7917c00SJeff Kirsher 	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
8420f7917c00SJeff Kirsher }
8421f7917c00SJeff Kirsher 
8422f7917c00SJeff Kirsher /**
8423f7917c00SJeff Kirsher  *	t4_ofld_eq_free - free an offload egress queue
8424f7917c00SJeff Kirsher  *	@adap: the adapter
8425f7917c00SJeff Kirsher  *	@mbox: mailbox to use for the FW command
8426f7917c00SJeff Kirsher  *	@pf: the PF owning the queue
8427f7917c00SJeff Kirsher  *	@vf: the VF owning the queue
8428f7917c00SJeff Kirsher  *	@eqid: egress queue id
8429f7917c00SJeff Kirsher  *
8430f7917c00SJeff Kirsher  *	Frees a control egress queue.
8431f7917c00SJeff Kirsher  */
t4_ofld_eq_free(struct adapter * adap,unsigned int mbox,unsigned int pf,unsigned int vf,unsigned int eqid)8432f7917c00SJeff Kirsher int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
8433f7917c00SJeff Kirsher 		    unsigned int vf, unsigned int eqid)
8434f7917c00SJeff Kirsher {
8435f7917c00SJeff Kirsher 	struct fw_eq_ofld_cmd c;
8436f7917c00SJeff Kirsher 
8437f7917c00SJeff Kirsher 	memset(&c, 0, sizeof(c));
8438f404f80cSHariprasad Shenai 	c.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_EQ_OFLD_CMD) |
8439f404f80cSHariprasad Shenai 				  FW_CMD_REQUEST_F | FW_CMD_EXEC_F |
8440f404f80cSHariprasad Shenai 				  FW_EQ_OFLD_CMD_PFN_V(pf) |
84416e4b51a6SHariprasad Shenai 				  FW_EQ_OFLD_CMD_VFN_V(vf));
8442f404f80cSHariprasad Shenai 	c.alloc_to_len16 = cpu_to_be32(FW_EQ_OFLD_CMD_FREE_F | FW_LEN16(c));
8443f404f80cSHariprasad Shenai 	c.eqid_pkd = cpu_to_be32(FW_EQ_OFLD_CMD_EQID_V(eqid));
8444f7917c00SJeff Kirsher 	return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
8445f7917c00SJeff Kirsher }
8446f7917c00SJeff Kirsher 
8447f7917c00SJeff Kirsher /**
8448ddc7740dSHariprasad Shenai  *	t4_link_down_rc_str - return a string for a Link Down Reason Code
8449ddc7740dSHariprasad Shenai  *	@link_down_rc: Link Down Reason Code
8450ddc7740dSHariprasad Shenai  *
8451ddc7740dSHariprasad Shenai  *	Returns a string representation of the Link Down Reason Code.
8452ddc7740dSHariprasad Shenai  */
t4_link_down_rc_str(unsigned char link_down_rc)8453ddc7740dSHariprasad Shenai static const char *t4_link_down_rc_str(unsigned char link_down_rc)
8454ddc7740dSHariprasad Shenai {
8455ddc7740dSHariprasad Shenai 	static const char * const reason[] = {
8456ddc7740dSHariprasad Shenai 		"Link Down",
8457ddc7740dSHariprasad Shenai 		"Remote Fault",
8458ddc7740dSHariprasad Shenai 		"Auto-negotiation Failure",
8459ddc7740dSHariprasad Shenai 		"Reserved",
8460ddc7740dSHariprasad Shenai 		"Insufficient Airflow",
8461ddc7740dSHariprasad Shenai 		"Unable To Determine Reason",
8462ddc7740dSHariprasad Shenai 		"No RX Signal Detected",
8463ddc7740dSHariprasad Shenai 		"Reserved",
8464ddc7740dSHariprasad Shenai 	};
8465ddc7740dSHariprasad Shenai 
8466ddc7740dSHariprasad Shenai 	if (link_down_rc >= ARRAY_SIZE(reason))
8467ddc7740dSHariprasad Shenai 		return "Bad Reason Code";
8468ddc7740dSHariprasad Shenai 
8469ddc7740dSHariprasad Shenai 	return reason[link_down_rc];
8470ddc7740dSHariprasad Shenai }
8471ddc7740dSHariprasad Shenai 
847229bbf5d7SRahul Lakkireddy /* Return the highest speed set in the port capabilities, in Mb/s. */
fwcap_to_speed(fw_port_cap32_t caps)8473c3168cabSGanesh Goudar static unsigned int fwcap_to_speed(fw_port_cap32_t caps)
8474c3168cabSGanesh Goudar {
8475c3168cabSGanesh Goudar 	#define TEST_SPEED_RETURN(__caps_speed, __speed) \
8476c3168cabSGanesh Goudar 		do { \
8477c3168cabSGanesh Goudar 			if (caps & FW_PORT_CAP32_SPEED_##__caps_speed) \
8478c3168cabSGanesh Goudar 				return __speed; \
8479c3168cabSGanesh Goudar 		} while (0)
8480c3168cabSGanesh Goudar 
8481c3168cabSGanesh Goudar 	TEST_SPEED_RETURN(400G, 400000);
8482c3168cabSGanesh Goudar 	TEST_SPEED_RETURN(200G, 200000);
8483c3168cabSGanesh Goudar 	TEST_SPEED_RETURN(100G, 100000);
8484c3168cabSGanesh Goudar 	TEST_SPEED_RETURN(50G,   50000);
8485c3168cabSGanesh Goudar 	TEST_SPEED_RETURN(40G,   40000);
8486c3168cabSGanesh Goudar 	TEST_SPEED_RETURN(25G,   25000);
8487c3168cabSGanesh Goudar 	TEST_SPEED_RETURN(10G,   10000);
8488c3168cabSGanesh Goudar 	TEST_SPEED_RETURN(1G,     1000);
8489c3168cabSGanesh Goudar 	TEST_SPEED_RETURN(100M,    100);
8490c3168cabSGanesh Goudar 
8491c3168cabSGanesh Goudar 	#undef TEST_SPEED_RETURN
8492c3168cabSGanesh Goudar 
8493c3168cabSGanesh Goudar 	return 0;
8494c3168cabSGanesh Goudar }
8495c3168cabSGanesh Goudar 
8496c3168cabSGanesh Goudar /**
8497c3168cabSGanesh Goudar  *	fwcap_to_fwspeed - return highest speed in Port Capabilities
8498c3168cabSGanesh Goudar  *	@acaps: advertised Port Capabilities
8499c3168cabSGanesh Goudar  *
8500c3168cabSGanesh Goudar  *	Get the highest speed for the port from the advertised Port
8501c3168cabSGanesh Goudar  *	Capabilities.  It will be either the highest speed from the list of
8502c3168cabSGanesh Goudar  *	speeds or whatever user has set using ethtool.
8503c3168cabSGanesh Goudar  */
fwcap_to_fwspeed(fw_port_cap32_t acaps)8504c3168cabSGanesh Goudar static fw_port_cap32_t fwcap_to_fwspeed(fw_port_cap32_t acaps)
8505c3168cabSGanesh Goudar {
8506c3168cabSGanesh Goudar 	#define TEST_SPEED_RETURN(__caps_speed) \
8507c3168cabSGanesh Goudar 		do { \
8508c3168cabSGanesh Goudar 			if (acaps & FW_PORT_CAP32_SPEED_##__caps_speed) \
8509c3168cabSGanesh Goudar 				return FW_PORT_CAP32_SPEED_##__caps_speed; \
8510c3168cabSGanesh Goudar 		} while (0)
8511c3168cabSGanesh Goudar 
8512c3168cabSGanesh Goudar 	TEST_SPEED_RETURN(400G);
8513c3168cabSGanesh Goudar 	TEST_SPEED_RETURN(200G);
8514c3168cabSGanesh Goudar 	TEST_SPEED_RETURN(100G);
8515c3168cabSGanesh Goudar 	TEST_SPEED_RETURN(50G);
8516c3168cabSGanesh Goudar 	TEST_SPEED_RETURN(40G);
8517c3168cabSGanesh Goudar 	TEST_SPEED_RETURN(25G);
8518c3168cabSGanesh Goudar 	TEST_SPEED_RETURN(10G);
8519c3168cabSGanesh Goudar 	TEST_SPEED_RETURN(1G);
8520c3168cabSGanesh Goudar 	TEST_SPEED_RETURN(100M);
8521c3168cabSGanesh Goudar 
8522c3168cabSGanesh Goudar 	#undef TEST_SPEED_RETURN
8523c3168cabSGanesh Goudar 
8524c3168cabSGanesh Goudar 	return 0;
8525c3168cabSGanesh Goudar }
8526c3168cabSGanesh Goudar 
8527c3168cabSGanesh Goudar /**
8528c3168cabSGanesh Goudar  *	lstatus_to_fwcap - translate old lstatus to 32-bit Port Capabilities
8529c3168cabSGanesh Goudar  *	@lstatus: old FW_PORT_ACTION_GET_PORT_INFO lstatus value
8530c3168cabSGanesh Goudar  *
8531c3168cabSGanesh Goudar  *	Translates old FW_PORT_ACTION_GET_PORT_INFO lstatus field into new
8532c3168cabSGanesh Goudar  *	32-bit Port Capabilities value.
8533c3168cabSGanesh Goudar  */
lstatus_to_fwcap(u32 lstatus)8534c3168cabSGanesh Goudar static fw_port_cap32_t lstatus_to_fwcap(u32 lstatus)
8535c3168cabSGanesh Goudar {
8536c3168cabSGanesh Goudar 	fw_port_cap32_t linkattr = 0;
8537c3168cabSGanesh Goudar 
8538c3168cabSGanesh Goudar 	/* Unfortunately the format of the Link Status in the old
8539c3168cabSGanesh Goudar 	 * 16-bit Port Information message isn't the same as the
8540c3168cabSGanesh Goudar 	 * 16-bit Port Capabilities bitfield used everywhere else ...
8541c3168cabSGanesh Goudar 	 */
8542c3168cabSGanesh Goudar 	if (lstatus & FW_PORT_CMD_RXPAUSE_F)
8543c3168cabSGanesh Goudar 		linkattr |= FW_PORT_CAP32_FC_RX;
8544c3168cabSGanesh Goudar 	if (lstatus & FW_PORT_CMD_TXPAUSE_F)
8545c3168cabSGanesh Goudar 		linkattr |= FW_PORT_CAP32_FC_TX;
8546c3168cabSGanesh Goudar 	if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100M))
8547c3168cabSGanesh Goudar 		linkattr |= FW_PORT_CAP32_SPEED_100M;
8548c3168cabSGanesh Goudar 	if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_1G))
8549c3168cabSGanesh Goudar 		linkattr |= FW_PORT_CAP32_SPEED_1G;
8550c3168cabSGanesh Goudar 	if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G))
8551c3168cabSGanesh Goudar 		linkattr |= FW_PORT_CAP32_SPEED_10G;
8552c3168cabSGanesh Goudar 	if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_25G))
8553c3168cabSGanesh Goudar 		linkattr |= FW_PORT_CAP32_SPEED_25G;
8554c3168cabSGanesh Goudar 	if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G))
8555c3168cabSGanesh Goudar 		linkattr |= FW_PORT_CAP32_SPEED_40G;
8556c3168cabSGanesh Goudar 	if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100G))
8557c3168cabSGanesh Goudar 		linkattr |= FW_PORT_CAP32_SPEED_100G;
8558c3168cabSGanesh Goudar 
8559c3168cabSGanesh Goudar 	return linkattr;
8560c3168cabSGanesh Goudar }
8561c3168cabSGanesh Goudar 
8562c3168cabSGanesh Goudar /**
856323853a0aSHariprasad Shenai  *	t4_handle_get_port_info - process a FW reply message
856423853a0aSHariprasad Shenai  *	@pi: the port info
8565f7917c00SJeff Kirsher  *	@rpl: start of the FW message
8566f7917c00SJeff Kirsher  *
856723853a0aSHariprasad Shenai  *	Processes a GET_PORT_INFO FW reply message.
8568f7917c00SJeff Kirsher  */
t4_handle_get_port_info(struct port_info * pi,const __be64 * rpl)856923853a0aSHariprasad Shenai void t4_handle_get_port_info(struct port_info *pi, const __be64 *rpl)
8570f7917c00SJeff Kirsher {
8571c3168cabSGanesh Goudar 	const struct fw_port_cmd *cmd = (const void *)rpl;
8572c3168cabSGanesh Goudar 	fw_port_cap32_t pcaps, acaps, lpacaps, linkattr;
85730caeaf6aSRahul Lakkireddy 	struct link_config *lc = &pi->link_cfg;
85740caeaf6aSRahul Lakkireddy 	struct adapter *adapter = pi->adapter;
85750caeaf6aSRahul Lakkireddy 	unsigned int speed, fc, fec, adv_fc;
85760caeaf6aSRahul Lakkireddy 	enum fw_port_module_type mod_type;
85770caeaf6aSRahul Lakkireddy 	int action, link_ok, linkdnrc;
85780caeaf6aSRahul Lakkireddy 	enum fw_port_type port_type;
8579f7917c00SJeff Kirsher 
8580c3168cabSGanesh Goudar 	/* Extract the various fields from the Port Information message.
8581158a5c0aSCasey Leedom 	 */
85820caeaf6aSRahul Lakkireddy 	action = FW_PORT_CMD_ACTION_G(be32_to_cpu(cmd->action_to_len16));
8583c3168cabSGanesh Goudar 	switch (action) {
8584c3168cabSGanesh Goudar 	case FW_PORT_ACTION_GET_PORT_INFO: {
8585c3168cabSGanesh Goudar 		u32 lstatus = be32_to_cpu(cmd->u.info.lstatus_to_modtype);
8586c3168cabSGanesh Goudar 
8587c3168cabSGanesh Goudar 		link_ok = (lstatus & FW_PORT_CMD_LSTATUS_F) != 0;
8588c3168cabSGanesh Goudar 		linkdnrc = FW_PORT_CMD_LINKDNRC_G(lstatus);
8589c3168cabSGanesh Goudar 		port_type = FW_PORT_CMD_PTYPE_G(lstatus);
8590c3168cabSGanesh Goudar 		mod_type = FW_PORT_CMD_MODTYPE_G(lstatus);
8591c3168cabSGanesh Goudar 		pcaps = fwcaps16_to_caps32(be16_to_cpu(cmd->u.info.pcap));
8592c3168cabSGanesh Goudar 		acaps = fwcaps16_to_caps32(be16_to_cpu(cmd->u.info.acap));
8593c3168cabSGanesh Goudar 		lpacaps = fwcaps16_to_caps32(be16_to_cpu(cmd->u.info.lpacap));
8594c3168cabSGanesh Goudar 		linkattr = lstatus_to_fwcap(lstatus);
8595c3168cabSGanesh Goudar 		break;
8596c3168cabSGanesh Goudar 	}
8597c3168cabSGanesh Goudar 
8598c3168cabSGanesh Goudar 	case FW_PORT_ACTION_GET_PORT_INFO32: {
8599c3168cabSGanesh Goudar 		u32 lstatus32;
8600c3168cabSGanesh Goudar 
8601c3168cabSGanesh Goudar 		lstatus32 = be32_to_cpu(cmd->u.info32.lstatus32_to_cbllen32);
8602c3168cabSGanesh Goudar 		link_ok = (lstatus32 & FW_PORT_CMD_LSTATUS32_F) != 0;
8603c3168cabSGanesh Goudar 		linkdnrc = FW_PORT_CMD_LINKDNRC32_G(lstatus32);
8604c3168cabSGanesh Goudar 		port_type = FW_PORT_CMD_PORTTYPE32_G(lstatus32);
8605c3168cabSGanesh Goudar 		mod_type = FW_PORT_CMD_MODTYPE32_G(lstatus32);
8606c3168cabSGanesh Goudar 		pcaps = be32_to_cpu(cmd->u.info32.pcaps32);
8607c3168cabSGanesh Goudar 		acaps = be32_to_cpu(cmd->u.info32.acaps32);
8608c3168cabSGanesh Goudar 		lpacaps = be32_to_cpu(cmd->u.info32.lpacaps32);
8609c3168cabSGanesh Goudar 		linkattr = be32_to_cpu(cmd->u.info32.linkattr32);
8610c3168cabSGanesh Goudar 		break;
8611c3168cabSGanesh Goudar 	}
8612c3168cabSGanesh Goudar 
8613c3168cabSGanesh Goudar 	default:
8614c3168cabSGanesh Goudar 		dev_err(adapter->pdev_dev, "Handle Port Information: Bad Command/Action %#x\n",
8615c3168cabSGanesh Goudar 			be32_to_cpu(cmd->action_to_len16));
8616c3168cabSGanesh Goudar 		return;
8617c3168cabSGanesh Goudar 	}
8618158a5c0aSCasey Leedom 
8619158a5c0aSCasey Leedom 	fec = fwcap_to_cc_fec(acaps);
86200caeaf6aSRahul Lakkireddy 	adv_fc = fwcap_to_cc_pause(acaps);
8621c3168cabSGanesh Goudar 	fc = fwcap_to_cc_pause(linkattr);
8622c3168cabSGanesh Goudar 	speed = fwcap_to_speed(linkattr);
8623158a5c0aSCasey Leedom 
862495eb7882SVishal Kulkarni 	/* Reset state for communicating new Transceiver Module status and
862595eb7882SVishal Kulkarni 	 * whether the OS-dependent layer wants us to redo the current
862695eb7882SVishal Kulkarni 	 * "sticky" L1 Configure Link Parameters.
862795eb7882SVishal Kulkarni 	 */
86288156b0baSGanesh Goudar 	lc->new_module = false;
86298156b0baSGanesh Goudar 	lc->redo_l1cfg = false;
86308156b0baSGanesh Goudar 
8631c3168cabSGanesh Goudar 	if (mod_type != pi->mod_type) {
8632c3168cabSGanesh Goudar 		/* With the newer SFP28 and QSFP28 Transceiver Module Types,
8633c3168cabSGanesh Goudar 		 * various fundamental Port Capabilities which used to be
8634c3168cabSGanesh Goudar 		 * immutable can now change radically.  We can now have
8635c3168cabSGanesh Goudar 		 * Speeds, Auto-Negotiation, Forward Error Correction, etc.
8636c3168cabSGanesh Goudar 		 * all change based on what Transceiver Module is inserted.
8637c3168cabSGanesh Goudar 		 * So we need to record the Physical "Port" Capabilities on
8638c3168cabSGanesh Goudar 		 * every Transceiver Module change.
8639158a5c0aSCasey Leedom 		 */
8640c3168cabSGanesh Goudar 		lc->pcaps = pcaps;
8641158a5c0aSCasey Leedom 
8642c3168cabSGanesh Goudar 		/* When a new Transceiver Module is inserted, the Firmware
8643c3168cabSGanesh Goudar 		 * will examine its i2c EPROM to determine its type and
8644c3168cabSGanesh Goudar 		 * general operating parameters including things like Forward
8645c3168cabSGanesh Goudar 		 * Error Control, etc.  Various IEEE 802.3 standards dictate
8646c3168cabSGanesh Goudar 		 * how to interpret these i2c values to determine default
8647c3168cabSGanesh Goudar 		 * "sutomatic" settings.  We record these for future use when
8648c3168cabSGanesh Goudar 		 * the user explicitly requests these standards-based values.
8649c3168cabSGanesh Goudar 		 */
8650c3168cabSGanesh Goudar 		lc->def_acaps = acaps;
8651c3168cabSGanesh Goudar 
8652c3168cabSGanesh Goudar 		/* Some versions of the early T6 Firmware "cheated" when
8653c3168cabSGanesh Goudar 		 * handling different Transceiver Modules by changing the
8654c3168cabSGanesh Goudar 		 * underlaying Port Type reported to the Host Drivers.  As
8655c3168cabSGanesh Goudar 		 * such we need to capture whatever Port Type the Firmware
8656c3168cabSGanesh Goudar 		 * sends us and record it in case it's different from what we
8657c3168cabSGanesh Goudar 		 * were told earlier.  Unfortunately, since Firmware is
8658c3168cabSGanesh Goudar 		 * forever, we'll need to keep this code here forever, but in
8659c3168cabSGanesh Goudar 		 * later T6 Firmware it should just be an assignment of the
8660c3168cabSGanesh Goudar 		 * same value already recorded.
8661c3168cabSGanesh Goudar 		 */
8662c3168cabSGanesh Goudar 		pi->port_type = port_type;
8663c3168cabSGanesh Goudar 
866495eb7882SVishal Kulkarni 		/* Record new Module Type information.
866595eb7882SVishal Kulkarni 		 */
8666c3168cabSGanesh Goudar 		pi->mod_type = mod_type;
86678156b0baSGanesh Goudar 
866895eb7882SVishal Kulkarni 		/* Let the OS-dependent layer know if we have a new
866995eb7882SVishal Kulkarni 		 * Transceiver Module inserted.
867095eb7882SVishal Kulkarni 		 */
86718156b0baSGanesh Goudar 		lc->new_module = t4_is_inserted_mod_type(mod_type);
867295eb7882SVishal Kulkarni 
8673c3168cabSGanesh Goudar 		t4_os_portmod_changed(adapter, pi->port_id);
867423853a0aSHariprasad Shenai 	}
8675c3168cabSGanesh Goudar 
8676f7917c00SJeff Kirsher 	if (link_ok != lc->link_ok || speed != lc->speed ||
86770caeaf6aSRahul Lakkireddy 	    fc != lc->fc || adv_fc != lc->advertised_fc ||
86780caeaf6aSRahul Lakkireddy 	    fec != lc->fec) {
86790caeaf6aSRahul Lakkireddy 		/* something changed */
8680ddc7740dSHariprasad Shenai 		if (!link_ok && lc->link_ok) {
8681c3168cabSGanesh Goudar 			lc->link_down_rc = linkdnrc;
868295eb7882SVishal Kulkarni 			dev_warn_ratelimited(adapter->pdev_dev,
868395eb7882SVishal Kulkarni 					     "Port %d link down, reason: %s\n",
868495eb7882SVishal Kulkarni 					     pi->tx_chan,
868595eb7882SVishal Kulkarni 					     t4_link_down_rc_str(linkdnrc));
8686ddc7740dSHariprasad Shenai 		}
8687f7917c00SJeff Kirsher 		lc->link_ok = link_ok;
8688f7917c00SJeff Kirsher 		lc->speed = speed;
86890caeaf6aSRahul Lakkireddy 		lc->advertised_fc = adv_fc;
8690f7917c00SJeff Kirsher 		lc->fc = fc;
8691158a5c0aSCasey Leedom 		lc->fec = fec;
8692158a5c0aSCasey Leedom 
8693c3168cabSGanesh Goudar 		lc->lpacaps = lpacaps;
8694c3168cabSGanesh Goudar 		lc->acaps = acaps & ADVERT_MASK;
86952061ec3fSGanesh Goudar 
869695eb7882SVishal Kulkarni 		/* If we're not physically capable of Auto-Negotiation, note
869795eb7882SVishal Kulkarni 		 * this as Auto-Negotiation disabled.  Otherwise, we track
869895eb7882SVishal Kulkarni 		 * what Auto-Negotiation settings we have.  Note parallel
869995eb7882SVishal Kulkarni 		 * structure in t4_link_l1cfg_core() and init_link_config().
870095eb7882SVishal Kulkarni 		 */
870157ccaedbSGanesh Goudar 		if (!(lc->acaps & FW_PORT_CAP32_ANEG)) {
870257ccaedbSGanesh Goudar 			lc->autoneg = AUTONEG_DISABLE;
870357ccaedbSGanesh Goudar 		} else if (lc->acaps & FW_PORT_CAP32_ANEG) {
8704c3168cabSGanesh Goudar 			lc->autoneg = AUTONEG_ENABLE;
8705c3168cabSGanesh Goudar 		} else {
8706c3168cabSGanesh Goudar 			/* When Autoneg is disabled, user needs to set
8707c3168cabSGanesh Goudar 			 * single speed.
8708c3168cabSGanesh Goudar 			 * Similar to cxgb4_ethtool.c: set_link_ksettings
8709c3168cabSGanesh Goudar 			 */
8710c3168cabSGanesh Goudar 			lc->acaps = 0;
8711c3168cabSGanesh Goudar 			lc->speed_caps = fwcap_to_fwspeed(acaps);
8712c3168cabSGanesh Goudar 			lc->autoneg = AUTONEG_DISABLE;
8713c3168cabSGanesh Goudar 		}
8714c3168cabSGanesh Goudar 
8715c3168cabSGanesh Goudar 		t4_os_link_changed(adapter, pi->port_id, link_ok);
8716f7917c00SJeff Kirsher 	}
87178156b0baSGanesh Goudar 
871895eb7882SVishal Kulkarni 	/* If we have a new Transceiver Module and the OS-dependent code has
871995eb7882SVishal Kulkarni 	 * told us that it wants us to redo whatever "sticky" L1 Configuration
872095eb7882SVishal Kulkarni 	 * Link Parameters are set, do that now.
872195eb7882SVishal Kulkarni 	 */
87228156b0baSGanesh Goudar 	if (lc->new_module && lc->redo_l1cfg) {
87238156b0baSGanesh Goudar 		struct link_config old_lc;
87248156b0baSGanesh Goudar 		int ret;
87258156b0baSGanesh Goudar 
87268156b0baSGanesh Goudar 		/* Save the current L1 Configuration and restore it if an
87278156b0baSGanesh Goudar 		 * error occurs.  We probably should fix the l1_cfg*()
87288156b0baSGanesh Goudar 		 * routines not to change the link_config when an error
87298156b0baSGanesh Goudar 		 * occurs ...
87308156b0baSGanesh Goudar 		 */
87318156b0baSGanesh Goudar 		old_lc = *lc;
87328156b0baSGanesh Goudar 		ret = t4_link_l1cfg_ns(adapter, adapter->mbox, pi->lport, lc);
87338156b0baSGanesh Goudar 		if (ret) {
87348156b0baSGanesh Goudar 			*lc = old_lc;
87358156b0baSGanesh Goudar 			dev_warn(adapter->pdev_dev,
87368156b0baSGanesh Goudar 				 "Attempt to update new Transceiver Module settings failed\n");
87378156b0baSGanesh Goudar 		}
87388156b0baSGanesh Goudar 	}
87398156b0baSGanesh Goudar 	lc->new_module = false;
87408156b0baSGanesh Goudar 	lc->redo_l1cfg = false;
8741f7917c00SJeff Kirsher }
874223853a0aSHariprasad Shenai 
874323853a0aSHariprasad Shenai /**
87442061ec3fSGanesh Goudar  *	t4_update_port_info - retrieve and update port information if changed
87452061ec3fSGanesh Goudar  *	@pi: the port_info
87462061ec3fSGanesh Goudar  *
87472061ec3fSGanesh Goudar  *	We issue a Get Port Information Command to the Firmware and, if
87482061ec3fSGanesh Goudar  *	successful, we check to see if anything is different from what we
87492061ec3fSGanesh Goudar  *	last recorded and update things accordingly.
87502061ec3fSGanesh Goudar  */
t4_update_port_info(struct port_info * pi)87512061ec3fSGanesh Goudar int t4_update_port_info(struct port_info *pi)
87522061ec3fSGanesh Goudar {
8753c3168cabSGanesh Goudar 	unsigned int fw_caps = pi->adapter->params.fw_caps_support;
87542061ec3fSGanesh Goudar 	struct fw_port_cmd port_cmd;
87552061ec3fSGanesh Goudar 	int ret;
87562061ec3fSGanesh Goudar 
87572061ec3fSGanesh Goudar 	memset(&port_cmd, 0, sizeof(port_cmd));
87582061ec3fSGanesh Goudar 	port_cmd.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) |
87592061ec3fSGanesh Goudar 					    FW_CMD_REQUEST_F | FW_CMD_READ_F |
8760c3168cabSGanesh Goudar 					    FW_PORT_CMD_PORTID_V(pi->tx_chan));
87612061ec3fSGanesh Goudar 	port_cmd.action_to_len16 = cpu_to_be32(
8762c3168cabSGanesh Goudar 		FW_PORT_CMD_ACTION_V(fw_caps == FW_CAPS16
8763c3168cabSGanesh Goudar 				     ? FW_PORT_ACTION_GET_PORT_INFO
8764c3168cabSGanesh Goudar 				     : FW_PORT_ACTION_GET_PORT_INFO32) |
87652061ec3fSGanesh Goudar 		FW_LEN16(port_cmd));
87662061ec3fSGanesh Goudar 	ret = t4_wr_mbox(pi->adapter, pi->adapter->mbox,
87672061ec3fSGanesh Goudar 			 &port_cmd, sizeof(port_cmd), &port_cmd);
87682061ec3fSGanesh Goudar 	if (ret)
87692061ec3fSGanesh Goudar 		return ret;
87702061ec3fSGanesh Goudar 
87712061ec3fSGanesh Goudar 	t4_handle_get_port_info(pi, (__be64 *)&port_cmd);
87722061ec3fSGanesh Goudar 	return 0;
87732061ec3fSGanesh Goudar }
87742061ec3fSGanesh Goudar 
87752061ec3fSGanesh Goudar /**
8776c3168cabSGanesh Goudar  *	t4_get_link_params - retrieve basic link parameters for given port
8777c3168cabSGanesh Goudar  *	@pi: the port
8778c3168cabSGanesh Goudar  *	@link_okp: value return pointer for link up/down
8779c3168cabSGanesh Goudar  *	@speedp: value return pointer for speed (Mb/s)
8780c3168cabSGanesh Goudar  *	@mtup: value return pointer for mtu
8781c3168cabSGanesh Goudar  *
8782c3168cabSGanesh Goudar  *	Retrieves basic link parameters for a port: link up/down, speed (Mb/s),
8783c3168cabSGanesh Goudar  *	and MTU for a specified port.  A negative error is returned on
8784c3168cabSGanesh Goudar  *	failure; 0 on success.
8785c3168cabSGanesh Goudar  */
t4_get_link_params(struct port_info * pi,unsigned int * link_okp,unsigned int * speedp,unsigned int * mtup)8786c3168cabSGanesh Goudar int t4_get_link_params(struct port_info *pi, unsigned int *link_okp,
8787c3168cabSGanesh Goudar 		       unsigned int *speedp, unsigned int *mtup)
8788c3168cabSGanesh Goudar {
8789c3168cabSGanesh Goudar 	unsigned int fw_caps = pi->adapter->params.fw_caps_support;
879021ab664aSYueHaibing 	unsigned int action, link_ok, mtu;
87914ec4762dSRahul Lakkireddy 	struct fw_port_cmd port_cmd;
8792c3168cabSGanesh Goudar 	fw_port_cap32_t linkattr;
8793c3168cabSGanesh Goudar 	int ret;
8794c3168cabSGanesh Goudar 
8795c3168cabSGanesh Goudar 	memset(&port_cmd, 0, sizeof(port_cmd));
8796c3168cabSGanesh Goudar 	port_cmd.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) |
8797c3168cabSGanesh Goudar 					    FW_CMD_REQUEST_F | FW_CMD_READ_F |
8798c3168cabSGanesh Goudar 					    FW_PORT_CMD_PORTID_V(pi->tx_chan));
8799c3168cabSGanesh Goudar 	action = (fw_caps == FW_CAPS16
8800c3168cabSGanesh Goudar 		  ? FW_PORT_ACTION_GET_PORT_INFO
8801c3168cabSGanesh Goudar 		  : FW_PORT_ACTION_GET_PORT_INFO32);
8802c3168cabSGanesh Goudar 	port_cmd.action_to_len16 = cpu_to_be32(
8803c3168cabSGanesh Goudar 		FW_PORT_CMD_ACTION_V(action) |
8804c3168cabSGanesh Goudar 		FW_LEN16(port_cmd));
8805c3168cabSGanesh Goudar 	ret = t4_wr_mbox(pi->adapter, pi->adapter->mbox,
8806c3168cabSGanesh Goudar 			 &port_cmd, sizeof(port_cmd), &port_cmd);
8807c3168cabSGanesh Goudar 	if (ret)
8808c3168cabSGanesh Goudar 		return ret;
8809c3168cabSGanesh Goudar 
8810c3168cabSGanesh Goudar 	if (action == FW_PORT_ACTION_GET_PORT_INFO) {
8811c3168cabSGanesh Goudar 		u32 lstatus = be32_to_cpu(port_cmd.u.info.lstatus_to_modtype);
8812c3168cabSGanesh Goudar 
8813c3168cabSGanesh Goudar 		link_ok = !!(lstatus & FW_PORT_CMD_LSTATUS_F);
8814c3168cabSGanesh Goudar 		linkattr = lstatus_to_fwcap(lstatus);
8815c3168cabSGanesh Goudar 		mtu = be16_to_cpu(port_cmd.u.info.mtu);
8816c3168cabSGanesh Goudar 	} else {
8817c3168cabSGanesh Goudar 		u32 lstatus32 =
8818c3168cabSGanesh Goudar 			   be32_to_cpu(port_cmd.u.info32.lstatus32_to_cbllen32);
8819c3168cabSGanesh Goudar 
8820c3168cabSGanesh Goudar 		link_ok = !!(lstatus32 & FW_PORT_CMD_LSTATUS32_F);
8821c3168cabSGanesh Goudar 		linkattr = be32_to_cpu(port_cmd.u.info32.linkattr32);
8822c3168cabSGanesh Goudar 		mtu = FW_PORT_CMD_MTU32_G(
8823c3168cabSGanesh Goudar 			be32_to_cpu(port_cmd.u.info32.auxlinfo32_mtu32));
8824c3168cabSGanesh Goudar 	}
8825c3168cabSGanesh Goudar 
88264ec4762dSRahul Lakkireddy 	if (link_okp)
8827c3168cabSGanesh Goudar 		*link_okp = link_ok;
88284ec4762dSRahul Lakkireddy 	if (speedp)
8829c3168cabSGanesh Goudar 		*speedp = fwcap_to_speed(linkattr);
88304ec4762dSRahul Lakkireddy 	if (mtup)
8831c3168cabSGanesh Goudar 		*mtup = mtu;
8832c3168cabSGanesh Goudar 
8833c3168cabSGanesh Goudar 	return 0;
8834c3168cabSGanesh Goudar }
8835c3168cabSGanesh Goudar 
8836c3168cabSGanesh Goudar /**
883723853a0aSHariprasad Shenai  *      t4_handle_fw_rpl - process a FW reply message
883823853a0aSHariprasad Shenai  *      @adap: the adapter
883923853a0aSHariprasad Shenai  *      @rpl: start of the FW message
884023853a0aSHariprasad Shenai  *
884123853a0aSHariprasad Shenai  *      Processes a FW message, such as link state change messages.
884223853a0aSHariprasad Shenai  */
t4_handle_fw_rpl(struct adapter * adap,const __be64 * rpl)884323853a0aSHariprasad Shenai int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
884423853a0aSHariprasad Shenai {
884523853a0aSHariprasad Shenai 	u8 opcode = *(const u8 *)rpl;
884623853a0aSHariprasad Shenai 
884723853a0aSHariprasad Shenai 	/* This might be a port command ... this simplifies the following
884823853a0aSHariprasad Shenai 	 * conditionals ...  We can get away with pre-dereferencing
884923853a0aSHariprasad Shenai 	 * action_to_len16 because it's in the first 16 bytes and all messages
885023853a0aSHariprasad Shenai 	 * will be at least that long.
885123853a0aSHariprasad Shenai 	 */
885223853a0aSHariprasad Shenai 	const struct fw_port_cmd *p = (const void *)rpl;
885323853a0aSHariprasad Shenai 	unsigned int action =
885423853a0aSHariprasad Shenai 		FW_PORT_CMD_ACTION_G(be32_to_cpu(p->action_to_len16));
885523853a0aSHariprasad Shenai 
8856c3168cabSGanesh Goudar 	if (opcode == FW_PORT_CMD &&
8857c3168cabSGanesh Goudar 	    (action == FW_PORT_ACTION_GET_PORT_INFO ||
8858c3168cabSGanesh Goudar 	     action == FW_PORT_ACTION_GET_PORT_INFO32)) {
885923853a0aSHariprasad Shenai 		int i;
886023853a0aSHariprasad Shenai 		int chan = FW_PORT_CMD_PORTID_G(be32_to_cpu(p->op_to_portid));
886123853a0aSHariprasad Shenai 		struct port_info *pi = NULL;
886223853a0aSHariprasad Shenai 
886323853a0aSHariprasad Shenai 		for_each_port(adap, i) {
886423853a0aSHariprasad Shenai 			pi = adap2pinfo(adap, i);
886523853a0aSHariprasad Shenai 			if (pi->tx_chan == chan)
886623853a0aSHariprasad Shenai 				break;
886723853a0aSHariprasad Shenai 		}
886823853a0aSHariprasad Shenai 
886923853a0aSHariprasad Shenai 		t4_handle_get_port_info(pi, rpl);
887023853a0aSHariprasad Shenai 	} else {
8871c3168cabSGanesh Goudar 		dev_warn(adap->pdev_dev, "Unknown firmware reply %d\n",
8872c3168cabSGanesh Goudar 			 opcode);
887323853a0aSHariprasad Shenai 		return -EINVAL;
8874f7917c00SJeff Kirsher 	}
8875f7917c00SJeff Kirsher 	return 0;
8876f7917c00SJeff Kirsher }
8877f7917c00SJeff Kirsher 
get_pci_mode(struct adapter * adapter,struct pci_params * p)88781dd06ae8SGreg Kroah-Hartman static void get_pci_mode(struct adapter *adapter, struct pci_params *p)
8879f7917c00SJeff Kirsher {
8880f7917c00SJeff Kirsher 	u16 val;
8881f7917c00SJeff Kirsher 
8882e5c8ae5fSJiang Liu 	if (pci_is_pcie(adapter->pdev)) {
8883e5c8ae5fSJiang Liu 		pcie_capability_read_word(adapter->pdev, PCI_EXP_LNKSTA, &val);
8884f7917c00SJeff Kirsher 		p->speed = val & PCI_EXP_LNKSTA_CLS;
8885f7917c00SJeff Kirsher 		p->width = (val & PCI_EXP_LNKSTA_NLW) >> 4;
8886f7917c00SJeff Kirsher 	}
8887f7917c00SJeff Kirsher }
8888f7917c00SJeff Kirsher 
8889f7917c00SJeff Kirsher /**
8890f7917c00SJeff Kirsher  *	init_link_config - initialize a link's SW state
8891c3168cabSGanesh Goudar  *	@lc: pointer to structure holding the link state
8892158a5c0aSCasey Leedom  *	@pcaps: link Port Capabilities
8893158a5c0aSCasey Leedom  *	@acaps: link current Advertised Port Capabilities
8894f7917c00SJeff Kirsher  *
8895f7917c00SJeff Kirsher  *	Initializes the SW state maintained for each link, including the link's
8896f7917c00SJeff Kirsher  *	capabilities and default speed/flow-control/autonegotiation settings.
8897f7917c00SJeff Kirsher  */
init_link_config(struct link_config * lc,fw_port_cap32_t pcaps,fw_port_cap32_t acaps)8898c3168cabSGanesh Goudar static void init_link_config(struct link_config *lc, fw_port_cap32_t pcaps,
8899c3168cabSGanesh Goudar 			     fw_port_cap32_t acaps)
8900f7917c00SJeff Kirsher {
8901c3168cabSGanesh Goudar 	lc->pcaps = pcaps;
8902c3168cabSGanesh Goudar 	lc->def_acaps = acaps;
8903c3168cabSGanesh Goudar 	lc->lpacaps = 0;
8904c3168cabSGanesh Goudar 	lc->speed_caps = 0;
8905f7917c00SJeff Kirsher 	lc->speed = 0;
8906f7917c00SJeff Kirsher 	lc->requested_fc = lc->fc = PAUSE_RX | PAUSE_TX;
89073bb4858fSGanesh Goudar 
89083bb4858fSGanesh Goudar 	/* For Forward Error Control, we default to whatever the Firmware
89093bb4858fSGanesh Goudar 	 * tells us the Link is currently advertising.
89103bb4858fSGanesh Goudar 	 */
89113bb4858fSGanesh Goudar 	lc->requested_fec = FEC_AUTO;
8912c3168cabSGanesh Goudar 	lc->fec = fwcap_to_cc_fec(lc->def_acaps);
89133bb4858fSGanesh Goudar 
891457ccaedbSGanesh Goudar 	/* If the Port is capable of Auto-Negtotiation, initialize it as
891557ccaedbSGanesh Goudar 	 * "enabled" and copy over all of the Physical Port Capabilities
891657ccaedbSGanesh Goudar 	 * to the Advertised Port Capabilities.  Otherwise mark it as
891757ccaedbSGanesh Goudar 	 * Auto-Negotiate disabled and select the highest supported speed
891857ccaedbSGanesh Goudar 	 * for the link.  Note parallel structure in t4_link_l1cfg_core()
891957ccaedbSGanesh Goudar 	 * and t4_handle_get_port_info().
892057ccaedbSGanesh Goudar 	 */
8921c3168cabSGanesh Goudar 	if (lc->pcaps & FW_PORT_CAP32_ANEG) {
8922c3168cabSGanesh Goudar 		lc->acaps = lc->pcaps & ADVERT_MASK;
8923f7917c00SJeff Kirsher 		lc->autoneg = AUTONEG_ENABLE;
8924f7917c00SJeff Kirsher 		lc->requested_fc |= PAUSE_AUTONEG;
8925f7917c00SJeff Kirsher 	} else {
8926c3168cabSGanesh Goudar 		lc->acaps = 0;
8927f7917c00SJeff Kirsher 		lc->autoneg = AUTONEG_DISABLE;
892857ccaedbSGanesh Goudar 		lc->speed_caps = fwcap_to_fwspeed(acaps);
8929f7917c00SJeff Kirsher 	}
8930f7917c00SJeff Kirsher }
8931f7917c00SJeff Kirsher 
89328203b509SHariprasad Shenai #define CIM_PF_NOACCESS 0xeeeeeeee
89338203b509SHariprasad Shenai 
t4_wait_dev_ready(void __iomem * regs)89348203b509SHariprasad Shenai int t4_wait_dev_ready(void __iomem *regs)
8935f7917c00SJeff Kirsher {
89368203b509SHariprasad Shenai 	u32 whoami;
89378203b509SHariprasad Shenai 
89380d804338SHariprasad Shenai 	whoami = readl(regs + PL_WHOAMI_A);
89398203b509SHariprasad Shenai 	if (whoami != 0xffffffff && whoami != CIM_PF_NOACCESS)
8940f7917c00SJeff Kirsher 		return 0;
89418203b509SHariprasad Shenai 
8942f7917c00SJeff Kirsher 	msleep(500);
89430d804338SHariprasad Shenai 	whoami = readl(regs + PL_WHOAMI_A);
89448203b509SHariprasad Shenai 	return (whoami != 0xffffffff && whoami != CIM_PF_NOACCESS ? 0 : -EIO);
8945f7917c00SJeff Kirsher }
8946f7917c00SJeff Kirsher 
8947fe2ee139SHariprasad Shenai struct flash_desc {
8948fe2ee139SHariprasad Shenai 	u32 vendor_and_model_id;
8949fe2ee139SHariprasad Shenai 	u32 size_mb;
8950fe2ee139SHariprasad Shenai };
8951fe2ee139SHariprasad Shenai 
t4_get_flash_params(struct adapter * adap)895296ac18f1SGanesh Goudar static int t4_get_flash_params(struct adapter *adap)
8953f7917c00SJeff Kirsher {
8954fe2ee139SHariprasad Shenai 	/* Table for non-Numonix supported flash parts.  Numonix parts are left
8955fe2ee139SHariprasad Shenai 	 * to the preexisting code.  All flash parts have 64KB sectors.
8956fe2ee139SHariprasad Shenai 	 */
8957fe2ee139SHariprasad Shenai 	static struct flash_desc supported_flash[] = {
8958fe2ee139SHariprasad Shenai 		{ 0x150201, 4 << 20 },       /* Spansion 4MB S25FL032P */
8959fe2ee139SHariprasad Shenai 	};
8960fe2ee139SHariprasad Shenai 
896196ac18f1SGanesh Goudar 	unsigned int part, manufacturer;
8962843789f6SCasey Leedom 	unsigned int density, size = 0;
896396ac18f1SGanesh Goudar 	u32 flashid = 0;
8964f7917c00SJeff Kirsher 	int ret;
896596ac18f1SGanesh Goudar 
896696ac18f1SGanesh Goudar 	/* Issue a Read ID Command to the Flash part.  We decode supported
896796ac18f1SGanesh Goudar 	 * Flash parts and their sizes from this.  There's a newer Query
896896ac18f1SGanesh Goudar 	 * Command which can retrieve detailed geometry information but many
896996ac18f1SGanesh Goudar 	 * Flash parts don't support it.
897096ac18f1SGanesh Goudar 	 */
8971f7917c00SJeff Kirsher 
8972f7917c00SJeff Kirsher 	ret = sf1_write(adap, 1, 1, 0, SF_RD_ID);
8973f7917c00SJeff Kirsher 	if (!ret)
897496ac18f1SGanesh Goudar 		ret = sf1_read(adap, 3, 0, 1, &flashid);
89750d804338SHariprasad Shenai 	t4_write_reg(adap, SF_OP_A, 0);                    /* unlock SF */
8976f7917c00SJeff Kirsher 	if (ret)
8977f7917c00SJeff Kirsher 		return ret;
8978f7917c00SJeff Kirsher 
897996ac18f1SGanesh Goudar 	/* Check to see if it's one of our non-standard supported Flash parts.
898096ac18f1SGanesh Goudar 	 */
898196ac18f1SGanesh Goudar 	for (part = 0; part < ARRAY_SIZE(supported_flash); part++)
898296ac18f1SGanesh Goudar 		if (supported_flash[part].vendor_and_model_id == flashid) {
898396ac18f1SGanesh Goudar 			adap->params.sf_size = supported_flash[part].size_mb;
8984fe2ee139SHariprasad Shenai 			adap->params.sf_nsec =
8985fe2ee139SHariprasad Shenai 				adap->params.sf_size / SF_SEC_SIZE;
898696ac18f1SGanesh Goudar 			goto found;
8987fe2ee139SHariprasad Shenai 		}
8988fe2ee139SHariprasad Shenai 
8989172ca830SArkadiusz Drabczyk 	/* Decode Flash part size.  The code below looks repetitive with
899096ac18f1SGanesh Goudar 	 * common encodings, but that's not guaranteed in the JEDEC
8991172ca830SArkadiusz Drabczyk 	 * specification for the Read JEDEC ID command.  The only thing that
8992172ca830SArkadiusz Drabczyk 	 * we're guaranteed by the JEDEC specification is where the
899396ac18f1SGanesh Goudar 	 * Manufacturer ID is in the returned result.  After that each
899496ac18f1SGanesh Goudar 	 * Manufacturer ~could~ encode things completely differently.
899596ac18f1SGanesh Goudar 	 * Note, all Flash parts must have 64KB sectors.
899696ac18f1SGanesh Goudar 	 */
899796ac18f1SGanesh Goudar 	manufacturer = flashid & 0xff;
899896ac18f1SGanesh Goudar 	switch (manufacturer) {
899996ac18f1SGanesh Goudar 	case 0x20: { /* Micron/Numonix */
900096ac18f1SGanesh Goudar 		/* This Density -> Size decoding table is taken from Micron
900196ac18f1SGanesh Goudar 		 * Data Sheets.
900296ac18f1SGanesh Goudar 		 */
900396ac18f1SGanesh Goudar 		density = (flashid >> 16) & 0xff;
900496ac18f1SGanesh Goudar 		switch (density) {
900596ac18f1SGanesh Goudar 		case 0x14: /* 1MB */
900696ac18f1SGanesh Goudar 			size = 1 << 20;
900796ac18f1SGanesh Goudar 			break;
900896ac18f1SGanesh Goudar 		case 0x15: /* 2MB */
900996ac18f1SGanesh Goudar 			size = 1 << 21;
901096ac18f1SGanesh Goudar 			break;
901196ac18f1SGanesh Goudar 		case 0x16: /* 4MB */
901296ac18f1SGanesh Goudar 			size = 1 << 22;
901396ac18f1SGanesh Goudar 			break;
901496ac18f1SGanesh Goudar 		case 0x17: /* 8MB */
901596ac18f1SGanesh Goudar 			size = 1 << 23;
901696ac18f1SGanesh Goudar 			break;
901796ac18f1SGanesh Goudar 		case 0x18: /* 16MB */
901896ac18f1SGanesh Goudar 			size = 1 << 24;
901996ac18f1SGanesh Goudar 			break;
902096ac18f1SGanesh Goudar 		case 0x19: /* 32MB */
902196ac18f1SGanesh Goudar 			size = 1 << 25;
902296ac18f1SGanesh Goudar 			break;
902396ac18f1SGanesh Goudar 		case 0x20: /* 64MB */
902496ac18f1SGanesh Goudar 			size = 1 << 26;
902596ac18f1SGanesh Goudar 			break;
902696ac18f1SGanesh Goudar 		case 0x21: /* 128MB */
902796ac18f1SGanesh Goudar 			size = 1 << 27;
902896ac18f1SGanesh Goudar 			break;
902996ac18f1SGanesh Goudar 		case 0x22: /* 256MB */
903096ac18f1SGanesh Goudar 			size = 1 << 28;
903196ac18f1SGanesh Goudar 			break;
903296ac18f1SGanesh Goudar 		}
903396ac18f1SGanesh Goudar 		break;
903496ac18f1SGanesh Goudar 	}
90350f1417f9SGanesh Goudar 	case 0x9d: { /* ISSI -- Integrated Silicon Solution, Inc. */
90360f1417f9SGanesh Goudar 		/* This Density -> Size decoding table is taken from ISSI
90370f1417f9SGanesh Goudar 		 * Data Sheets.
90380f1417f9SGanesh Goudar 		 */
90390f1417f9SGanesh Goudar 		density = (flashid >> 16) & 0xff;
90400f1417f9SGanesh Goudar 		switch (density) {
90410f1417f9SGanesh Goudar 		case 0x16: /* 32 MB */
90420f1417f9SGanesh Goudar 			size = 1 << 25;
90430f1417f9SGanesh Goudar 			break;
90440f1417f9SGanesh Goudar 		case 0x17: /* 64MB */
90450f1417f9SGanesh Goudar 			size = 1 << 26;
90460f1417f9SGanesh Goudar 			break;
90470f1417f9SGanesh Goudar 		}
90480f1417f9SGanesh Goudar 		break;
90490f1417f9SGanesh Goudar 	}
905096ac18f1SGanesh Goudar 	case 0xc2: { /* Macronix */
905196ac18f1SGanesh Goudar 		/* This Density -> Size decoding table is taken from Macronix
905296ac18f1SGanesh Goudar 		 * Data Sheets.
905396ac18f1SGanesh Goudar 		 */
905496ac18f1SGanesh Goudar 		density = (flashid >> 16) & 0xff;
905596ac18f1SGanesh Goudar 		switch (density) {
905696ac18f1SGanesh Goudar 		case 0x17: /* 8MB */
905796ac18f1SGanesh Goudar 			size = 1 << 23;
905896ac18f1SGanesh Goudar 			break;
905996ac18f1SGanesh Goudar 		case 0x18: /* 16MB */
906096ac18f1SGanesh Goudar 			size = 1 << 24;
906196ac18f1SGanesh Goudar 			break;
906296ac18f1SGanesh Goudar 		}
90635dc87425SColin Ian King 		break;
906496ac18f1SGanesh Goudar 	}
906596ac18f1SGanesh Goudar 	case 0xef: { /* Winbond */
906696ac18f1SGanesh Goudar 		/* This Density -> Size decoding table is taken from Winbond
906796ac18f1SGanesh Goudar 		 * Data Sheets.
906896ac18f1SGanesh Goudar 		 */
906996ac18f1SGanesh Goudar 		density = (flashid >> 16) & 0xff;
907096ac18f1SGanesh Goudar 		switch (density) {
907196ac18f1SGanesh Goudar 		case 0x17: /* 8MB */
907296ac18f1SGanesh Goudar 			size = 1 << 23;
907396ac18f1SGanesh Goudar 			break;
907496ac18f1SGanesh Goudar 		case 0x18: /* 16MB */
907596ac18f1SGanesh Goudar 			size = 1 << 24;
907696ac18f1SGanesh Goudar 			break;
907796ac18f1SGanesh Goudar 		}
907896ac18f1SGanesh Goudar 		break;
907996ac18f1SGanesh Goudar 	}
9080843789f6SCasey Leedom 	}
9081843789f6SCasey Leedom 
9082843789f6SCasey Leedom 	/* If we didn't recognize the FLASH part, that's no real issue: the
9083843789f6SCasey Leedom 	 * Hardware/Software contract says that Hardware will _*ALWAYS*_
9084843789f6SCasey Leedom 	 * use a FLASH part which is at least 4MB in size and has 64KB
9085843789f6SCasey Leedom 	 * sectors.  The unrecognized FLASH part is likely to be much larger
9086843789f6SCasey Leedom 	 * than 4MB, but that's all we really need.
9087843789f6SCasey Leedom 	 */
9088843789f6SCasey Leedom 	if (size == 0) {
9089843789f6SCasey Leedom 		dev_warn(adap->pdev_dev, "Unknown Flash Part, ID = %#x, assuming 4MB\n",
909096ac18f1SGanesh Goudar 			 flashid);
9091843789f6SCasey Leedom 		size = 1 << 22;
909296ac18f1SGanesh Goudar 	}
909396ac18f1SGanesh Goudar 
909496ac18f1SGanesh Goudar 	/* Store decoded Flash size and fall through into vetting code. */
909596ac18f1SGanesh Goudar 	adap->params.sf_size = size;
909696ac18f1SGanesh Goudar 	adap->params.sf_nsec = size / SF_SEC_SIZE;
909796ac18f1SGanesh Goudar 
909896ac18f1SGanesh Goudar found:
9099c290607eSHariprasad Shenai 	if (adap->params.sf_size < FLASH_MIN_SIZE)
910096ac18f1SGanesh Goudar 		dev_warn(adap->pdev_dev, "WARNING: Flash Part ID %#x, size %#x < %#x\n",
910196ac18f1SGanesh Goudar 			 flashid, adap->params.sf_size, FLASH_MIN_SIZE);
9102f7917c00SJeff Kirsher 	return 0;
9103f7917c00SJeff Kirsher }
9104f7917c00SJeff Kirsher 
9105f7917c00SJeff Kirsher /**
9106f7917c00SJeff Kirsher  *	t4_prep_adapter - prepare SW and HW for operation
9107f7917c00SJeff Kirsher  *	@adapter: the adapter
9108f7917c00SJeff Kirsher  *
9109f7917c00SJeff Kirsher  *	Initialize adapter SW state for the various HW modules, set initial
9110f7917c00SJeff Kirsher  *	values for some adapter tunables, take PHYs out of reset, and
9111f7917c00SJeff Kirsher  *	initialize the MDIO interface.
9112f7917c00SJeff Kirsher  */
t4_prep_adapter(struct adapter * adapter)911391744948SBill Pemberton int t4_prep_adapter(struct adapter *adapter)
9114f7917c00SJeff Kirsher {
91150a57a536SSantosh Rastapur 	int ret, ver;
91160a57a536SSantosh Rastapur 	uint16_t device_id;
9117d14807ddSHariprasad Shenai 	u32 pl_rev;
9118f7917c00SJeff Kirsher 
9119f7917c00SJeff Kirsher 	get_pci_mode(adapter, &adapter->params.pci);
91200d804338SHariprasad Shenai 	pl_rev = REV_G(t4_read_reg(adapter, PL_REV_A));
9121f7917c00SJeff Kirsher 
912296ac18f1SGanesh Goudar 	ret = t4_get_flash_params(adapter);
9123f7917c00SJeff Kirsher 	if (ret < 0) {
9124f7917c00SJeff Kirsher 		dev_err(adapter->pdev_dev, "error %d identifying flash\n", ret);
9125f7917c00SJeff Kirsher 		return ret;
9126f7917c00SJeff Kirsher 	}
9127f7917c00SJeff Kirsher 
91280a57a536SSantosh Rastapur 	/* Retrieve adapter's device ID
91290a57a536SSantosh Rastapur 	 */
91300a57a536SSantosh Rastapur 	pci_read_config_word(adapter->pdev, PCI_DEVICE_ID, &device_id);
91310a57a536SSantosh Rastapur 	ver = device_id >> 12;
9132d14807ddSHariprasad Shenai 	adapter->params.chip = 0;
91330a57a536SSantosh Rastapur 	switch (ver) {
91340a57a536SSantosh Rastapur 	case CHELSIO_T4:
9135d14807ddSHariprasad Shenai 		adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T4, pl_rev);
91363ccc6cf7SHariprasad Shenai 		adapter->params.arch.sge_fl_db = DBPRIO_F;
91373ccc6cf7SHariprasad Shenai 		adapter->params.arch.mps_tcam_size =
91383ccc6cf7SHariprasad Shenai 				 NUM_MPS_CLS_SRAM_L_INSTANCES;
91393ccc6cf7SHariprasad Shenai 		adapter->params.arch.mps_rplc_size = 128;
91403ccc6cf7SHariprasad Shenai 		adapter->params.arch.nchan = NCHAN;
914144588560SHariprasad Shenai 		adapter->params.arch.pm_stats_cnt = PM_NSTATS;
91423ccc6cf7SHariprasad Shenai 		adapter->params.arch.vfcount = 128;
91432216d014SHariprasad Shenai 		/* Congestion map is for 4 channels so that
91442216d014SHariprasad Shenai 		 * MPS can have 4 priority per port.
91452216d014SHariprasad Shenai 		 */
91462216d014SHariprasad Shenai 		adapter->params.arch.cng_ch_bits_log = 2;
91470a57a536SSantosh Rastapur 		break;
91480a57a536SSantosh Rastapur 	case CHELSIO_T5:
9149d14807ddSHariprasad Shenai 		adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T5, pl_rev);
91503ccc6cf7SHariprasad Shenai 		adapter->params.arch.sge_fl_db = DBPRIO_F | DBTYPE_F;
91513ccc6cf7SHariprasad Shenai 		adapter->params.arch.mps_tcam_size =
91523ccc6cf7SHariprasad Shenai 				 NUM_MPS_T5_CLS_SRAM_L_INSTANCES;
91533ccc6cf7SHariprasad Shenai 		adapter->params.arch.mps_rplc_size = 128;
91543ccc6cf7SHariprasad Shenai 		adapter->params.arch.nchan = NCHAN;
915544588560SHariprasad Shenai 		adapter->params.arch.pm_stats_cnt = PM_NSTATS;
91563ccc6cf7SHariprasad Shenai 		adapter->params.arch.vfcount = 128;
91572216d014SHariprasad Shenai 		adapter->params.arch.cng_ch_bits_log = 2;
91583ccc6cf7SHariprasad Shenai 		break;
91593ccc6cf7SHariprasad Shenai 	case CHELSIO_T6:
91603ccc6cf7SHariprasad Shenai 		adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T6, pl_rev);
91613ccc6cf7SHariprasad Shenai 		adapter->params.arch.sge_fl_db = 0;
91623ccc6cf7SHariprasad Shenai 		adapter->params.arch.mps_tcam_size =
91633ccc6cf7SHariprasad Shenai 				 NUM_MPS_T5_CLS_SRAM_L_INSTANCES;
91643ccc6cf7SHariprasad Shenai 		adapter->params.arch.mps_rplc_size = 256;
91653ccc6cf7SHariprasad Shenai 		adapter->params.arch.nchan = 2;
916644588560SHariprasad Shenai 		adapter->params.arch.pm_stats_cnt = T6_PM_NSTATS;
91673ccc6cf7SHariprasad Shenai 		adapter->params.arch.vfcount = 256;
91682216d014SHariprasad Shenai 		/* Congestion map will be for 2 channels so that
91692216d014SHariprasad Shenai 		 * MPS can have 8 priority per port.
91702216d014SHariprasad Shenai 		 */
91712216d014SHariprasad Shenai 		adapter->params.arch.cng_ch_bits_log = 3;
91720a57a536SSantosh Rastapur 		break;
91730a57a536SSantosh Rastapur 	default:
91740a57a536SSantosh Rastapur 		dev_err(adapter->pdev_dev, "Device %d is not supported\n",
91750a57a536SSantosh Rastapur 			device_id);
91760a57a536SSantosh Rastapur 		return -EINVAL;
91770a57a536SSantosh Rastapur 	}
91780a57a536SSantosh Rastapur 
9179f1ff24aaSHariprasad Shenai 	adapter->params.cim_la_size = CIMLA_SIZE;
9180f7917c00SJeff Kirsher 	init_cong_ctrl(adapter->params.a_wnd, adapter->params.b_wnd);
9181f7917c00SJeff Kirsher 
9182f7917c00SJeff Kirsher 	/*
9183f7917c00SJeff Kirsher 	 * Default port for debugging in case we can't reach FW.
9184f7917c00SJeff Kirsher 	 */
9185f7917c00SJeff Kirsher 	adapter->params.nports = 1;
9186f7917c00SJeff Kirsher 	adapter->params.portvec = 1;
9187636f9d37SVipul Pandya 	adapter->params.vpd.cclk = 50000;
9188eca0f6eeSHariprasad Shenai 
9189962b5827SBjorn Helgaas 	/* Set PCIe completion timeout to 4 seconds. */
9190962b5827SBjorn Helgaas 	pcie_capability_clear_and_set_word(adapter->pdev, PCI_EXP_DEVCTL2,
9191962b5827SBjorn Helgaas 					   PCI_EXP_DEVCTL2_COMP_TIMEOUT, 0xd);
9192f7917c00SJeff Kirsher 	return 0;
9193f7917c00SJeff Kirsher }
9194f7917c00SJeff Kirsher 
9195dcf7b6f5SKumar Sanghvi /**
91963be0679bSHariprasad Shenai  *	t4_shutdown_adapter - shut down adapter, host & wire
91973be0679bSHariprasad Shenai  *	@adapter: the adapter
91983be0679bSHariprasad Shenai  *
91993be0679bSHariprasad Shenai  *	Perform an emergency shutdown of the adapter and stop it from
92003be0679bSHariprasad Shenai  *	continuing any further communication on the ports or DMA to the
92013be0679bSHariprasad Shenai  *	host.  This is typically used when the adapter and/or firmware
92023be0679bSHariprasad Shenai  *	have crashed and we want to prevent any further accidental
92033be0679bSHariprasad Shenai  *	communication with the rest of the world.  This will also force
92043be0679bSHariprasad Shenai  *	the port Link Status to go down -- if register writes work --
92053be0679bSHariprasad Shenai  *	which should help our peers figure out that we're down.
92063be0679bSHariprasad Shenai  */
t4_shutdown_adapter(struct adapter * adapter)92073be0679bSHariprasad Shenai int t4_shutdown_adapter(struct adapter *adapter)
92083be0679bSHariprasad Shenai {
92093be0679bSHariprasad Shenai 	int port;
92103be0679bSHariprasad Shenai 
92113be0679bSHariprasad Shenai 	t4_intr_disable(adapter);
92123be0679bSHariprasad Shenai 	t4_write_reg(adapter, DBG_GPIO_EN_A, 0);
92133be0679bSHariprasad Shenai 	for_each_port(adapter, port) {
9214b3fd8220SRahul Lakkireddy 		u32 a_port_cfg = is_t4(adapter->params.chip) ?
9215b3fd8220SRahul Lakkireddy 				       PORT_REG(port, XGMAC_PORT_CFG_A) :
9216b3fd8220SRahul Lakkireddy 				       T5_PORT_REG(port, MAC_PORT_CFG_A);
92173be0679bSHariprasad Shenai 
92183be0679bSHariprasad Shenai 		t4_write_reg(adapter, a_port_cfg,
92193be0679bSHariprasad Shenai 			     t4_read_reg(adapter, a_port_cfg)
92203be0679bSHariprasad Shenai 			     & ~SIGNAL_DET_V(1));
92213be0679bSHariprasad Shenai 	}
92223be0679bSHariprasad Shenai 	t4_set_reg_field(adapter, SGE_CONTROL_A, GLOBALENABLE_F, 0);
92233be0679bSHariprasad Shenai 
92243be0679bSHariprasad Shenai 	return 0;
92253be0679bSHariprasad Shenai }
92263be0679bSHariprasad Shenai 
92273be0679bSHariprasad Shenai /**
9228b2612722SHariprasad Shenai  *	t4_bar2_sge_qregs - return BAR2 SGE Queue register information
9229e85c9a7aSHariprasad Shenai  *	@adapter: the adapter
9230e85c9a7aSHariprasad Shenai  *	@qid: the Queue ID
9231e85c9a7aSHariprasad Shenai  *	@qtype: the Ingress or Egress type for @qid
923266cf188eSHariprasad S  *	@user: true if this request is for a user mode queue
9233e85c9a7aSHariprasad Shenai  *	@pbar2_qoffset: BAR2 Queue Offset
9234e85c9a7aSHariprasad Shenai  *	@pbar2_qid: BAR2 Queue ID or 0 for Queue ID inferred SGE Queues
9235e85c9a7aSHariprasad Shenai  *
9236e85c9a7aSHariprasad Shenai  *	Returns the BAR2 SGE Queue Registers information associated with the
9237e85c9a7aSHariprasad Shenai  *	indicated Absolute Queue ID.  These are passed back in return value
9238e85c9a7aSHariprasad Shenai  *	pointers.  @qtype should be T4_BAR2_QTYPE_EGRESS for Egress Queue
9239e85c9a7aSHariprasad Shenai  *	and T4_BAR2_QTYPE_INGRESS for Ingress Queues.
9240e85c9a7aSHariprasad Shenai  *
9241e85c9a7aSHariprasad Shenai  *	This may return an error which indicates that BAR2 SGE Queue
9242e85c9a7aSHariprasad Shenai  *	registers aren't available.  If an error is not returned, then the
9243e85c9a7aSHariprasad Shenai  *	following values are returned:
9244e85c9a7aSHariprasad Shenai  *
9245e85c9a7aSHariprasad Shenai  *	  *@pbar2_qoffset: the BAR2 Offset of the @qid Registers
9246e85c9a7aSHariprasad Shenai  *	  *@pbar2_qid: the BAR2 SGE Queue ID or 0 of @qid
9247e85c9a7aSHariprasad Shenai  *
9248e85c9a7aSHariprasad Shenai  *	If the returned BAR2 Queue ID is 0, then BAR2 SGE registers which
9249e85c9a7aSHariprasad Shenai  *	require the "Inferred Queue ID" ability may be used.  E.g. the
9250e85c9a7aSHariprasad Shenai  *	Write Combining Doorbell Buffer. If the BAR2 Queue ID is not 0,
9251e85c9a7aSHariprasad Shenai  *	then these "Inferred Queue ID" register may not be used.
9252e85c9a7aSHariprasad Shenai  */
t4_bar2_sge_qregs(struct adapter * adapter,unsigned int qid,enum t4_bar2_qtype qtype,int user,u64 * pbar2_qoffset,unsigned int * pbar2_qid)9253b2612722SHariprasad Shenai int t4_bar2_sge_qregs(struct adapter *adapter,
9254e85c9a7aSHariprasad Shenai 		      unsigned int qid,
9255e85c9a7aSHariprasad Shenai 		      enum t4_bar2_qtype qtype,
925666cf188eSHariprasad S 		      int user,
9257e85c9a7aSHariprasad Shenai 		      u64 *pbar2_qoffset,
9258e85c9a7aSHariprasad Shenai 		      unsigned int *pbar2_qid)
9259e85c9a7aSHariprasad Shenai {
9260e85c9a7aSHariprasad Shenai 	unsigned int page_shift, page_size, qpp_shift, qpp_mask;
9261e85c9a7aSHariprasad Shenai 	u64 bar2_page_offset, bar2_qoffset;
9262e85c9a7aSHariprasad Shenai 	unsigned int bar2_qid, bar2_qid_offset, bar2_qinferred;
9263e85c9a7aSHariprasad Shenai 
926466cf188eSHariprasad S 	/* T4 doesn't support BAR2 SGE Queue registers for kernel mode queues */
926566cf188eSHariprasad S 	if (!user && is_t4(adapter->params.chip))
9266e85c9a7aSHariprasad Shenai 		return -EINVAL;
9267e85c9a7aSHariprasad Shenai 
9268e85c9a7aSHariprasad Shenai 	/* Get our SGE Page Size parameters.
9269e85c9a7aSHariprasad Shenai 	 */
9270e85c9a7aSHariprasad Shenai 	page_shift = adapter->params.sge.hps + 10;
9271e85c9a7aSHariprasad Shenai 	page_size = 1 << page_shift;
9272e85c9a7aSHariprasad Shenai 
9273e85c9a7aSHariprasad Shenai 	/* Get the right Queues per Page parameters for our Queue.
9274e85c9a7aSHariprasad Shenai 	 */
9275e85c9a7aSHariprasad Shenai 	qpp_shift = (qtype == T4_BAR2_QTYPE_EGRESS
9276e85c9a7aSHariprasad Shenai 		     ? adapter->params.sge.eq_qpp
9277e85c9a7aSHariprasad Shenai 		     : adapter->params.sge.iq_qpp);
9278e85c9a7aSHariprasad Shenai 	qpp_mask = (1 << qpp_shift) - 1;
9279e85c9a7aSHariprasad Shenai 
9280e85c9a7aSHariprasad Shenai 	/*  Calculate the basics of the BAR2 SGE Queue register area:
9281e85c9a7aSHariprasad Shenai 	 *  o The BAR2 page the Queue registers will be in.
9282e85c9a7aSHariprasad Shenai 	 *  o The BAR2 Queue ID.
9283e85c9a7aSHariprasad Shenai 	 *  o The BAR2 Queue ID Offset into the BAR2 page.
9284e85c9a7aSHariprasad Shenai 	 */
9285513d1a1dSHariprasad Shenai 	bar2_page_offset = ((u64)(qid >> qpp_shift) << page_shift);
9286e85c9a7aSHariprasad Shenai 	bar2_qid = qid & qpp_mask;
9287e85c9a7aSHariprasad Shenai 	bar2_qid_offset = bar2_qid * SGE_UDB_SIZE;
9288e85c9a7aSHariprasad Shenai 
9289e85c9a7aSHariprasad Shenai 	/* If the BAR2 Queue ID Offset is less than the Page Size, then the
9290e85c9a7aSHariprasad Shenai 	 * hardware will infer the Absolute Queue ID simply from the writes to
9291e85c9a7aSHariprasad Shenai 	 * the BAR2 Queue ID Offset within the BAR2 Page (and we need to use a
9292e85c9a7aSHariprasad Shenai 	 * BAR2 Queue ID of 0 for those writes).  Otherwise, we'll simply
9293e85c9a7aSHariprasad Shenai 	 * write to the first BAR2 SGE Queue Area within the BAR2 Page with
9294e85c9a7aSHariprasad Shenai 	 * the BAR2 Queue ID and the hardware will infer the Absolute Queue ID
9295e85c9a7aSHariprasad Shenai 	 * from the BAR2 Page and BAR2 Queue ID.
9296e85c9a7aSHariprasad Shenai 	 *
9297e85c9a7aSHariprasad Shenai 	 * One important censequence of this is that some BAR2 SGE registers
9298e85c9a7aSHariprasad Shenai 	 * have a "Queue ID" field and we can write the BAR2 SGE Queue ID
9299e85c9a7aSHariprasad Shenai 	 * there.  But other registers synthesize the SGE Queue ID purely
9300e85c9a7aSHariprasad Shenai 	 * from the writes to the registers -- the Write Combined Doorbell
9301e85c9a7aSHariprasad Shenai 	 * Buffer is a good example.  These BAR2 SGE Registers are only
9302e85c9a7aSHariprasad Shenai 	 * available for those BAR2 SGE Register areas where the SGE Absolute
9303e85c9a7aSHariprasad Shenai 	 * Queue ID can be inferred from simple writes.
9304e85c9a7aSHariprasad Shenai 	 */
9305e85c9a7aSHariprasad Shenai 	bar2_qoffset = bar2_page_offset;
9306e85c9a7aSHariprasad Shenai 	bar2_qinferred = (bar2_qid_offset < page_size);
9307e85c9a7aSHariprasad Shenai 	if (bar2_qinferred) {
9308e85c9a7aSHariprasad Shenai 		bar2_qoffset += bar2_qid_offset;
9309e85c9a7aSHariprasad Shenai 		bar2_qid = 0;
9310e85c9a7aSHariprasad Shenai 	}
9311e85c9a7aSHariprasad Shenai 
9312e85c9a7aSHariprasad Shenai 	*pbar2_qoffset = bar2_qoffset;
9313e85c9a7aSHariprasad Shenai 	*pbar2_qid = bar2_qid;
9314e85c9a7aSHariprasad Shenai 	return 0;
9315e85c9a7aSHariprasad Shenai }
9316e85c9a7aSHariprasad Shenai 
9317e85c9a7aSHariprasad Shenai /**
9318ae469b68SHariprasad Shenai  *	t4_init_devlog_params - initialize adapter->params.devlog
9319ae469b68SHariprasad Shenai  *	@adap: the adapter
9320ae469b68SHariprasad Shenai  *
9321ae469b68SHariprasad Shenai  *	Initialize various fields of the adapter's Firmware Device Log
9322ae469b68SHariprasad Shenai  *	Parameters structure.
9323ae469b68SHariprasad Shenai  */
t4_init_devlog_params(struct adapter * adap)9324ae469b68SHariprasad Shenai int t4_init_devlog_params(struct adapter *adap)
9325ae469b68SHariprasad Shenai {
9326ae469b68SHariprasad Shenai 	struct devlog_params *dparams = &adap->params.devlog;
9327ae469b68SHariprasad Shenai 	u32 pf_dparams;
9328ae469b68SHariprasad Shenai 	unsigned int devlog_meminfo;
9329ae469b68SHariprasad Shenai 	struct fw_devlog_cmd devlog_cmd;
9330ae469b68SHariprasad Shenai 	int ret;
9331ae469b68SHariprasad Shenai 
9332172ca830SArkadiusz Drabczyk 	/* If we're dealing with newer firmware, the Device Log Parameters
9333ae469b68SHariprasad Shenai 	 * are stored in a designated register which allows us to access the
9334ae469b68SHariprasad Shenai 	 * Device Log even if we can't talk to the firmware.
9335ae469b68SHariprasad Shenai 	 */
9336ae469b68SHariprasad Shenai 	pf_dparams =
9337ae469b68SHariprasad Shenai 		t4_read_reg(adap, PCIE_FW_REG(PCIE_FW_PF_A, PCIE_FW_PF_DEVLOG));
9338ae469b68SHariprasad Shenai 	if (pf_dparams) {
9339ae469b68SHariprasad Shenai 		unsigned int nentries, nentries128;
9340ae469b68SHariprasad Shenai 
9341ae469b68SHariprasad Shenai 		dparams->memtype = PCIE_FW_PF_DEVLOG_MEMTYPE_G(pf_dparams);
9342ae469b68SHariprasad Shenai 		dparams->start = PCIE_FW_PF_DEVLOG_ADDR16_G(pf_dparams) << 4;
9343ae469b68SHariprasad Shenai 
9344ae469b68SHariprasad Shenai 		nentries128 = PCIE_FW_PF_DEVLOG_NENTRIES128_G(pf_dparams);
9345ae469b68SHariprasad Shenai 		nentries = (nentries128 + 1) * 128;
9346ae469b68SHariprasad Shenai 		dparams->size = nentries * sizeof(struct fw_devlog_e);
9347ae469b68SHariprasad Shenai 
9348ae469b68SHariprasad Shenai 		return 0;
9349ae469b68SHariprasad Shenai 	}
9350ae469b68SHariprasad Shenai 
9351ae469b68SHariprasad Shenai 	/* Otherwise, ask the firmware for it's Device Log Parameters.
9352ae469b68SHariprasad Shenai 	 */
9353ae469b68SHariprasad Shenai 	memset(&devlog_cmd, 0, sizeof(devlog_cmd));
9354f404f80cSHariprasad Shenai 	devlog_cmd.op_to_write = cpu_to_be32(FW_CMD_OP_V(FW_DEVLOG_CMD) |
9355ae469b68SHariprasad Shenai 					     FW_CMD_REQUEST_F | FW_CMD_READ_F);
9356f404f80cSHariprasad Shenai 	devlog_cmd.retval_len16 = cpu_to_be32(FW_LEN16(devlog_cmd));
9357ae469b68SHariprasad Shenai 	ret = t4_wr_mbox(adap, adap->mbox, &devlog_cmd, sizeof(devlog_cmd),
9358ae469b68SHariprasad Shenai 			 &devlog_cmd);
9359ae469b68SHariprasad Shenai 	if (ret)
9360ae469b68SHariprasad Shenai 		return ret;
9361ae469b68SHariprasad Shenai 
9362f404f80cSHariprasad Shenai 	devlog_meminfo =
9363f404f80cSHariprasad Shenai 		be32_to_cpu(devlog_cmd.memtype_devlog_memaddr16_devlog);
9364ae469b68SHariprasad Shenai 	dparams->memtype = FW_DEVLOG_CMD_MEMTYPE_DEVLOG_G(devlog_meminfo);
9365ae469b68SHariprasad Shenai 	dparams->start = FW_DEVLOG_CMD_MEMADDR16_DEVLOG_G(devlog_meminfo) << 4;
9366f404f80cSHariprasad Shenai 	dparams->size = be32_to_cpu(devlog_cmd.memsize_devlog);
9367ae469b68SHariprasad Shenai 
9368ae469b68SHariprasad Shenai 	return 0;
9369ae469b68SHariprasad Shenai }
9370ae469b68SHariprasad Shenai 
9371ae469b68SHariprasad Shenai /**
9372e85c9a7aSHariprasad Shenai  *	t4_init_sge_params - initialize adap->params.sge
9373e85c9a7aSHariprasad Shenai  *	@adapter: the adapter
9374e85c9a7aSHariprasad Shenai  *
9375e85c9a7aSHariprasad Shenai  *	Initialize various fields of the adapter's SGE Parameters structure.
9376e85c9a7aSHariprasad Shenai  */
t4_init_sge_params(struct adapter * adapter)9377e85c9a7aSHariprasad Shenai int t4_init_sge_params(struct adapter *adapter)
9378e85c9a7aSHariprasad Shenai {
9379e85c9a7aSHariprasad Shenai 	struct sge_params *sge_params = &adapter->params.sge;
9380e85c9a7aSHariprasad Shenai 	u32 hps, qpp;
9381e85c9a7aSHariprasad Shenai 	unsigned int s_hps, s_qpp;
9382e85c9a7aSHariprasad Shenai 
9383e85c9a7aSHariprasad Shenai 	/* Extract the SGE Page Size for our PF.
9384e85c9a7aSHariprasad Shenai 	 */
9385f612b815SHariprasad Shenai 	hps = t4_read_reg(adapter, SGE_HOST_PAGE_SIZE_A);
9386e85c9a7aSHariprasad Shenai 	s_hps = (HOSTPAGESIZEPF0_S +
9387b2612722SHariprasad Shenai 		 (HOSTPAGESIZEPF1_S - HOSTPAGESIZEPF0_S) * adapter->pf);
9388e85c9a7aSHariprasad Shenai 	sge_params->hps = ((hps >> s_hps) & HOSTPAGESIZEPF0_M);
9389e85c9a7aSHariprasad Shenai 
9390e85c9a7aSHariprasad Shenai 	/* Extract the SGE Egress and Ingess Queues Per Page for our PF.
9391e85c9a7aSHariprasad Shenai 	 */
9392e85c9a7aSHariprasad Shenai 	s_qpp = (QUEUESPERPAGEPF0_S +
9393b2612722SHariprasad Shenai 		(QUEUESPERPAGEPF1_S - QUEUESPERPAGEPF0_S) * adapter->pf);
9394f612b815SHariprasad Shenai 	qpp = t4_read_reg(adapter, SGE_EGRESS_QUEUES_PER_PAGE_PF_A);
9395f612b815SHariprasad Shenai 	sge_params->eq_qpp = ((qpp >> s_qpp) & QUEUESPERPAGEPF0_M);
9396f061de42SHariprasad Shenai 	qpp = t4_read_reg(adapter, SGE_INGRESS_QUEUES_PER_PAGE_PF_A);
9397f612b815SHariprasad Shenai 	sge_params->iq_qpp = ((qpp >> s_qpp) & QUEUESPERPAGEPF0_M);
9398e85c9a7aSHariprasad Shenai 
9399e85c9a7aSHariprasad Shenai 	return 0;
9400e85c9a7aSHariprasad Shenai }
9401e85c9a7aSHariprasad Shenai 
9402e85c9a7aSHariprasad Shenai /**
9403dcf7b6f5SKumar Sanghvi  *      t4_init_tp_params - initialize adap->params.tp
9404dcf7b6f5SKumar Sanghvi  *      @adap: the adapter
94055ccf9d04SRahul Lakkireddy  *      @sleep_ok: if true we may sleep while awaiting command completion
9406dcf7b6f5SKumar Sanghvi  *
9407dcf7b6f5SKumar Sanghvi  *      Initialize various fields of the adapter's TP Parameters structure.
9408dcf7b6f5SKumar Sanghvi  */
t4_init_tp_params(struct adapter * adap,bool sleep_ok)94095ccf9d04SRahul Lakkireddy int t4_init_tp_params(struct adapter *adap, bool sleep_ok)
9410dcf7b6f5SKumar Sanghvi {
9411dcf10ec7SRaju Rangoju 	u32 param, val, v;
9412dcf10ec7SRaju Rangoju 	int chan, ret;
9413dcf10ec7SRaju Rangoju 
9414dcf7b6f5SKumar Sanghvi 
9415837e4a42SHariprasad Shenai 	v = t4_read_reg(adap, TP_TIMER_RESOLUTION_A);
9416837e4a42SHariprasad Shenai 	adap->params.tp.tre = TIMERRESOLUTION_G(v);
9417837e4a42SHariprasad Shenai 	adap->params.tp.dack_re = DELAYEDACKRESOLUTION_G(v);
9418dcf7b6f5SKumar Sanghvi 
9419dcf7b6f5SKumar Sanghvi 	/* MODQ_REQ_MAP defaults to setting queues 0-3 to chan 0-3 */
9420dcf7b6f5SKumar Sanghvi 	for (chan = 0; chan < NCHAN; chan++)
9421dcf7b6f5SKumar Sanghvi 		adap->params.tp.tx_modq[chan] = chan;
9422dcf7b6f5SKumar Sanghvi 
9423dcf10ec7SRaju Rangoju 	/* Cache the adapter's Compressed Filter Mode/Mask and global Ingress
9424dcf7b6f5SKumar Sanghvi 	 * Configuration.
9425dcf7b6f5SKumar Sanghvi 	 */
9426dcf10ec7SRaju Rangoju 	param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) |
9427dcf10ec7SRaju Rangoju 		 FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_FILTER) |
9428dcf10ec7SRaju Rangoju 		 FW_PARAMS_PARAM_Y_V(FW_PARAM_DEV_FILTER_MODE_MASK));
9429dcf10ec7SRaju Rangoju 
9430dcf10ec7SRaju Rangoju 	/* Read current value */
9431dcf10ec7SRaju Rangoju 	ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1,
9432dcf10ec7SRaju Rangoju 			      &param, &val);
9433dcf10ec7SRaju Rangoju 	if (ret == 0) {
9434dcf10ec7SRaju Rangoju 		dev_info(adap->pdev_dev,
9435dcf10ec7SRaju Rangoju 			 "Current filter mode/mask 0x%x:0x%x\n",
9436dcf10ec7SRaju Rangoju 			 FW_PARAMS_PARAM_FILTER_MODE_G(val),
9437dcf10ec7SRaju Rangoju 			 FW_PARAMS_PARAM_FILTER_MASK_G(val));
9438dcf10ec7SRaju Rangoju 		adap->params.tp.vlan_pri_map =
9439dcf10ec7SRaju Rangoju 			FW_PARAMS_PARAM_FILTER_MODE_G(val);
9440dcf10ec7SRaju Rangoju 		adap->params.tp.filter_mask =
9441dcf10ec7SRaju Rangoju 			FW_PARAMS_PARAM_FILTER_MASK_G(val);
9442dcf10ec7SRaju Rangoju 	} else {
9443dcf10ec7SRaju Rangoju 		dev_info(adap->pdev_dev,
9444dcf10ec7SRaju Rangoju 			 "Failed to read filter mode/mask via fw api, using indirect-reg-read\n");
9445dcf10ec7SRaju Rangoju 
9446dcf10ec7SRaju Rangoju 		/* Incase of older-fw (which doesn't expose the api
9447dcf10ec7SRaju Rangoju 		 * FW_PARAM_DEV_FILTER_MODE_MASK) and newer-driver (which uses
9448dcf10ec7SRaju Rangoju 		 * the fw api) combination, fall-back to older method of reading
9449dcf10ec7SRaju Rangoju 		 * the filter mode from indirect-register
9450dcf10ec7SRaju Rangoju 		 */
94515ccf9d04SRahul Lakkireddy 		t4_tp_pio_read(adap, &adap->params.tp.vlan_pri_map, 1,
94525ccf9d04SRahul Lakkireddy 			       TP_VLAN_PRI_MAP_A, sleep_ok);
9453dcf10ec7SRaju Rangoju 
9454dcf10ec7SRaju Rangoju 		/* With the older-fw and newer-driver combination we might run
9455dcf10ec7SRaju Rangoju 		 * into an issue when user wants to use hash filter region but
9456dcf10ec7SRaju Rangoju 		 * the filter_mask is zero, in this case filter_mask validation
9457dcf10ec7SRaju Rangoju 		 * is tough. To avoid that we set the filter_mask same as filter
9458dcf10ec7SRaju Rangoju 		 * mode, which will behave exactly as the older way of ignoring
9459dcf10ec7SRaju Rangoju 		 * the filter mask validation.
9460dcf10ec7SRaju Rangoju 		 */
9461dcf10ec7SRaju Rangoju 		adap->params.tp.filter_mask = adap->params.tp.vlan_pri_map;
9462dcf10ec7SRaju Rangoju 	}
9463dcf10ec7SRaju Rangoju 
94645ccf9d04SRahul Lakkireddy 	t4_tp_pio_read(adap, &adap->params.tp.ingress_config, 1,
94655ccf9d04SRahul Lakkireddy 		       TP_INGRESS_CONFIG_A, sleep_ok);
94665ccf9d04SRahul Lakkireddy 
94678eb9f2f9SArjun V 	/* For T6, cache the adapter's compressed error vector
94688eb9f2f9SArjun V 	 * and passing outer header info for encapsulated packets.
94698eb9f2f9SArjun V 	 */
94708eb9f2f9SArjun V 	if (CHELSIO_CHIP_VERSION(adap->params.chip) > CHELSIO_T5) {
94718eb9f2f9SArjun V 		v = t4_read_reg(adap, TP_OUT_CONFIG_A);
94728eb9f2f9SArjun V 		adap->params.tp.rx_pkt_encap = (v & CRXPKTENC_F) ? 1 : 0;
94738eb9f2f9SArjun V 	}
9474dcf7b6f5SKumar Sanghvi 
9475dcf7b6f5SKumar Sanghvi 	/* Now that we have TP_VLAN_PRI_MAP cached, we can calculate the field
9476dcf7b6f5SKumar Sanghvi 	 * shift positions of several elements of the Compressed Filter Tuple
9477dcf7b6f5SKumar Sanghvi 	 * for this adapter which we need frequently ...
9478dcf7b6f5SKumar Sanghvi 	 */
94790ba9a3b6SKumar Sanghvi 	adap->params.tp.fcoe_shift = t4_filter_field_shift(adap, FCOE_F);
94800d804338SHariprasad Shenai 	adap->params.tp.port_shift = t4_filter_field_shift(adap, PORT_F);
94810ba9a3b6SKumar Sanghvi 	adap->params.tp.vnic_shift = t4_filter_field_shift(adap, VNIC_ID_F);
94820ba9a3b6SKumar Sanghvi 	adap->params.tp.vlan_shift = t4_filter_field_shift(adap, VLAN_F);
94830ba9a3b6SKumar Sanghvi 	adap->params.tp.tos_shift = t4_filter_field_shift(adap, TOS_F);
9484dcf7b6f5SKumar Sanghvi 	adap->params.tp.protocol_shift = t4_filter_field_shift(adap,
94850d804338SHariprasad Shenai 							       PROTOCOL_F);
94860ba9a3b6SKumar Sanghvi 	adap->params.tp.ethertype_shift = t4_filter_field_shift(adap,
94870ba9a3b6SKumar Sanghvi 								ETHERTYPE_F);
94880ba9a3b6SKumar Sanghvi 	adap->params.tp.macmatch_shift = t4_filter_field_shift(adap,
94890ba9a3b6SKumar Sanghvi 							       MACMATCH_F);
94900ba9a3b6SKumar Sanghvi 	adap->params.tp.matchtype_shift = t4_filter_field_shift(adap,
94910ba9a3b6SKumar Sanghvi 								MPSHITTYPE_F);
94920ba9a3b6SKumar Sanghvi 	adap->params.tp.frag_shift = t4_filter_field_shift(adap,
94930ba9a3b6SKumar Sanghvi 							   FRAGMENTATION_F);
9494dcf7b6f5SKumar Sanghvi 
9495dcf7b6f5SKumar Sanghvi 	/* If TP_INGRESS_CONFIG.VNID == 0, then TP_VLAN_PRI_MAP.VNIC_ID
9496dbedd44eSJoe Perches 	 * represents the presence of an Outer VLAN instead of a VNIC ID.
9497dcf7b6f5SKumar Sanghvi 	 */
94980d804338SHariprasad Shenai 	if ((adap->params.tp.ingress_config & VNIC_F) == 0)
9499dcf7b6f5SKumar Sanghvi 		adap->params.tp.vnic_shift = -1;
9500dcf7b6f5SKumar Sanghvi 
95010ba9a3b6SKumar Sanghvi 	v = t4_read_reg(adap, LE_3_DB_HASH_MASK_GEN_IPV4_T6_A);
95020ba9a3b6SKumar Sanghvi 	adap->params.tp.hash_filter_mask = v;
95030ba9a3b6SKumar Sanghvi 	v = t4_read_reg(adap, LE_4_DB_HASH_MASK_GEN_IPV4_T6_A);
95040ba9a3b6SKumar Sanghvi 	adap->params.tp.hash_filter_mask |= ((u64)v << 32);
9505dcf7b6f5SKumar Sanghvi 	return 0;
9506dcf7b6f5SKumar Sanghvi }
9507dcf7b6f5SKumar Sanghvi 
9508dcf7b6f5SKumar Sanghvi /**
9509dcf7b6f5SKumar Sanghvi  *      t4_filter_field_shift - calculate filter field shift
9510dcf7b6f5SKumar Sanghvi  *      @adap: the adapter
9511dcf7b6f5SKumar Sanghvi  *      @filter_sel: the desired field (from TP_VLAN_PRI_MAP bits)
9512dcf7b6f5SKumar Sanghvi  *
9513dcf7b6f5SKumar Sanghvi  *      Return the shift position of a filter field within the Compressed
9514dcf7b6f5SKumar Sanghvi  *      Filter Tuple.  The filter field is specified via its selection bit
9515dcf7b6f5SKumar Sanghvi  *      within TP_VLAN_PRI_MAL (filter mode).  E.g. F_VLAN.
9516dcf7b6f5SKumar Sanghvi  */
t4_filter_field_shift(const struct adapter * adap,int filter_sel)9517dcf7b6f5SKumar Sanghvi int t4_filter_field_shift(const struct adapter *adap, int filter_sel)
9518dcf7b6f5SKumar Sanghvi {
9519dcf7b6f5SKumar Sanghvi 	unsigned int filter_mode = adap->params.tp.vlan_pri_map;
9520dcf7b6f5SKumar Sanghvi 	unsigned int sel;
9521dcf7b6f5SKumar Sanghvi 	int field_shift;
9522dcf7b6f5SKumar Sanghvi 
9523dcf7b6f5SKumar Sanghvi 	if ((filter_mode & filter_sel) == 0)
9524dcf7b6f5SKumar Sanghvi 		return -1;
9525dcf7b6f5SKumar Sanghvi 
9526dcf7b6f5SKumar Sanghvi 	for (sel = 1, field_shift = 0; sel < filter_sel; sel <<= 1) {
9527dcf7b6f5SKumar Sanghvi 		switch (filter_mode & sel) {
95280d804338SHariprasad Shenai 		case FCOE_F:
95290d804338SHariprasad Shenai 			field_shift += FT_FCOE_W;
9530dcf7b6f5SKumar Sanghvi 			break;
95310d804338SHariprasad Shenai 		case PORT_F:
95320d804338SHariprasad Shenai 			field_shift += FT_PORT_W;
9533dcf7b6f5SKumar Sanghvi 			break;
95340d804338SHariprasad Shenai 		case VNIC_ID_F:
95350d804338SHariprasad Shenai 			field_shift += FT_VNIC_ID_W;
9536dcf7b6f5SKumar Sanghvi 			break;
95370d804338SHariprasad Shenai 		case VLAN_F:
95380d804338SHariprasad Shenai 			field_shift += FT_VLAN_W;
9539dcf7b6f5SKumar Sanghvi 			break;
95400d804338SHariprasad Shenai 		case TOS_F:
95410d804338SHariprasad Shenai 			field_shift += FT_TOS_W;
9542dcf7b6f5SKumar Sanghvi 			break;
95430d804338SHariprasad Shenai 		case PROTOCOL_F:
95440d804338SHariprasad Shenai 			field_shift += FT_PROTOCOL_W;
9545dcf7b6f5SKumar Sanghvi 			break;
95460d804338SHariprasad Shenai 		case ETHERTYPE_F:
95470d804338SHariprasad Shenai 			field_shift += FT_ETHERTYPE_W;
9548dcf7b6f5SKumar Sanghvi 			break;
95490d804338SHariprasad Shenai 		case MACMATCH_F:
95500d804338SHariprasad Shenai 			field_shift += FT_MACMATCH_W;
9551dcf7b6f5SKumar Sanghvi 			break;
95520d804338SHariprasad Shenai 		case MPSHITTYPE_F:
95530d804338SHariprasad Shenai 			field_shift += FT_MPSHITTYPE_W;
9554dcf7b6f5SKumar Sanghvi 			break;
95550d804338SHariprasad Shenai 		case FRAGMENTATION_F:
95560d804338SHariprasad Shenai 			field_shift += FT_FRAGMENTATION_W;
9557dcf7b6f5SKumar Sanghvi 			break;
9558dcf7b6f5SKumar Sanghvi 		}
9559dcf7b6f5SKumar Sanghvi 	}
9560dcf7b6f5SKumar Sanghvi 	return field_shift;
9561dcf7b6f5SKumar Sanghvi }
9562dcf7b6f5SKumar Sanghvi 
t4_init_rss_mode(struct adapter * adap,int mbox)9563c035e183SHariprasad Shenai int t4_init_rss_mode(struct adapter *adap, int mbox)
9564c035e183SHariprasad Shenai {
9565c035e183SHariprasad Shenai 	int i, ret;
9566c035e183SHariprasad Shenai 	struct fw_rss_vi_config_cmd rvc;
9567c035e183SHariprasad Shenai 
9568c035e183SHariprasad Shenai 	memset(&rvc, 0, sizeof(rvc));
9569c035e183SHariprasad Shenai 
9570c035e183SHariprasad Shenai 	for_each_port(adap, i) {
9571c035e183SHariprasad Shenai 		struct port_info *p = adap2pinfo(adap, i);
9572c035e183SHariprasad Shenai 
9573f404f80cSHariprasad Shenai 		rvc.op_to_viid =
9574f404f80cSHariprasad Shenai 			cpu_to_be32(FW_CMD_OP_V(FW_RSS_VI_CONFIG_CMD) |
9575c035e183SHariprasad Shenai 				    FW_CMD_REQUEST_F | FW_CMD_READ_F |
9576c035e183SHariprasad Shenai 				    FW_RSS_VI_CONFIG_CMD_VIID_V(p->viid));
9577f404f80cSHariprasad Shenai 		rvc.retval_len16 = cpu_to_be32(FW_LEN16(rvc));
9578c035e183SHariprasad Shenai 		ret = t4_wr_mbox(adap, mbox, &rvc, sizeof(rvc), &rvc);
9579c035e183SHariprasad Shenai 		if (ret)
9580c035e183SHariprasad Shenai 			return ret;
9581f404f80cSHariprasad Shenai 		p->rss_mode = be32_to_cpu(rvc.u.basicvirtual.defaultq_to_udpen);
9582c035e183SHariprasad Shenai 	}
9583c035e183SHariprasad Shenai 	return 0;
9584c035e183SHariprasad Shenai }
9585c035e183SHariprasad Shenai 
9586c3e324e3SHariprasad Shenai /**
9587c3168cabSGanesh Goudar  *	t4_init_portinfo - allocate a virtual interface and initialize port_info
9588c3e324e3SHariprasad Shenai  *	@pi: the port_info
9589c3e324e3SHariprasad Shenai  *	@mbox: mailbox to use for the FW command
9590c3e324e3SHariprasad Shenai  *	@port: physical port associated with the VI
9591c3e324e3SHariprasad Shenai  *	@pf: the PF owning the VI
9592c3e324e3SHariprasad Shenai  *	@vf: the VF owning the VI
9593c3e324e3SHariprasad Shenai  *	@mac: the MAC address of the VI
9594c3e324e3SHariprasad Shenai  *
9595c3e324e3SHariprasad Shenai  *	Allocates a virtual interface for the given physical port.  If @mac is
9596c3e324e3SHariprasad Shenai  *	not %NULL it contains the MAC address of the VI as assigned by FW.
9597c3e324e3SHariprasad Shenai  *	@mac should be large enough to hold an Ethernet address.
9598c3e324e3SHariprasad Shenai  *	Returns < 0 on error.
9599c3e324e3SHariprasad Shenai  */
t4_init_portinfo(struct port_info * pi,int mbox,int port,int pf,int vf,u8 mac[])9600c3e324e3SHariprasad Shenai int t4_init_portinfo(struct port_info *pi, int mbox,
9601c3e324e3SHariprasad Shenai 		     int port, int pf, int vf, u8 mac[])
9602c3e324e3SHariprasad Shenai {
9603c3168cabSGanesh Goudar 	struct adapter *adapter = pi->adapter;
9604c3168cabSGanesh Goudar 	unsigned int fw_caps = adapter->params.fw_caps_support;
9605c3168cabSGanesh Goudar 	struct fw_port_cmd cmd;
9606c3e324e3SHariprasad Shenai 	unsigned int rss_size;
9607c3168cabSGanesh Goudar 	enum fw_port_type port_type;
9608c3168cabSGanesh Goudar 	int mdio_addr;
9609c3168cabSGanesh Goudar 	fw_port_cap32_t pcaps, acaps;
961002d805dcSSantosh Rastapur 	u8 vivld = 0, vin = 0;
9611c3168cabSGanesh Goudar 	int ret;
9612c3e324e3SHariprasad Shenai 
9613c3168cabSGanesh Goudar 	/* If we haven't yet determined whether we're talking to Firmware
9614c3168cabSGanesh Goudar 	 * which knows the new 32-bit Port Capabilities, it's time to find
9615c3168cabSGanesh Goudar 	 * out now.  This will also tell new Firmware to send us Port Status
9616c3168cabSGanesh Goudar 	 * Updates using the new 32-bit Port Capabilities version of the
9617c3168cabSGanesh Goudar 	 * Port Information message.
9618c3168cabSGanesh Goudar 	 */
9619c3168cabSGanesh Goudar 	if (fw_caps == FW_CAPS_UNKNOWN) {
9620c3168cabSGanesh Goudar 		u32 param, val;
9621c3168cabSGanesh Goudar 
9622c3168cabSGanesh Goudar 		param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_PFVF) |
9623c3168cabSGanesh Goudar 			 FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_PFVF_PORT_CAPS32));
9624c3168cabSGanesh Goudar 		val = 1;
9625c3168cabSGanesh Goudar 		ret = t4_set_params(adapter, mbox, pf, vf, 1, &param, &val);
9626c3168cabSGanesh Goudar 		fw_caps = (ret == 0 ? FW_CAPS32 : FW_CAPS16);
9627c3168cabSGanesh Goudar 		adapter->params.fw_caps_support = fw_caps;
9628c3168cabSGanesh Goudar 	}
9629c3168cabSGanesh Goudar 
9630c3168cabSGanesh Goudar 	memset(&cmd, 0, sizeof(cmd));
9631c3168cabSGanesh Goudar 	cmd.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) |
9632c3e324e3SHariprasad Shenai 				       FW_CMD_REQUEST_F | FW_CMD_READ_F |
9633c3e324e3SHariprasad Shenai 				       FW_PORT_CMD_PORTID_V(port));
9634c3168cabSGanesh Goudar 	cmd.action_to_len16 = cpu_to_be32(
9635c3168cabSGanesh Goudar 		FW_PORT_CMD_ACTION_V(fw_caps == FW_CAPS16
9636c3168cabSGanesh Goudar 				     ? FW_PORT_ACTION_GET_PORT_INFO
9637c3168cabSGanesh Goudar 				     : FW_PORT_ACTION_GET_PORT_INFO32) |
9638c3168cabSGanesh Goudar 		FW_LEN16(cmd));
9639c3168cabSGanesh Goudar 	ret = t4_wr_mbox(pi->adapter, mbox, &cmd, sizeof(cmd), &cmd);
9640c3e324e3SHariprasad Shenai 	if (ret)
9641c3e324e3SHariprasad Shenai 		return ret;
9642c3e324e3SHariprasad Shenai 
9643c3168cabSGanesh Goudar 	/* Extract the various fields from the Port Information message.
9644c3168cabSGanesh Goudar 	 */
9645c3168cabSGanesh Goudar 	if (fw_caps == FW_CAPS16) {
9646c3168cabSGanesh Goudar 		u32 lstatus = be32_to_cpu(cmd.u.info.lstatus_to_modtype);
9647c3168cabSGanesh Goudar 
9648c3168cabSGanesh Goudar 		port_type = FW_PORT_CMD_PTYPE_G(lstatus);
9649c3168cabSGanesh Goudar 		mdio_addr = ((lstatus & FW_PORT_CMD_MDIOCAP_F)
9650c3168cabSGanesh Goudar 			     ? FW_PORT_CMD_MDIOADDR_G(lstatus)
9651c3168cabSGanesh Goudar 			     : -1);
9652c3168cabSGanesh Goudar 		pcaps = fwcaps16_to_caps32(be16_to_cpu(cmd.u.info.pcap));
9653c3168cabSGanesh Goudar 		acaps = fwcaps16_to_caps32(be16_to_cpu(cmd.u.info.acap));
9654c3168cabSGanesh Goudar 	} else {
9655c3168cabSGanesh Goudar 		u32 lstatus32 = be32_to_cpu(cmd.u.info32.lstatus32_to_cbllen32);
9656c3168cabSGanesh Goudar 
9657c3168cabSGanesh Goudar 		port_type = FW_PORT_CMD_PORTTYPE32_G(lstatus32);
9658c3168cabSGanesh Goudar 		mdio_addr = ((lstatus32 & FW_PORT_CMD_MDIOCAP32_F)
9659c3168cabSGanesh Goudar 			     ? FW_PORT_CMD_MDIOADDR32_G(lstatus32)
9660c3168cabSGanesh Goudar 			     : -1);
9661c3168cabSGanesh Goudar 		pcaps = be32_to_cpu(cmd.u.info32.pcaps32);
9662c3168cabSGanesh Goudar 		acaps = be32_to_cpu(cmd.u.info32.acaps32);
9663c3168cabSGanesh Goudar 	}
9664c3168cabSGanesh Goudar 
966502d805dcSSantosh Rastapur 	ret = t4_alloc_vi(pi->adapter, mbox, port, pf, vf, 1, mac, &rss_size,
966602d805dcSSantosh Rastapur 			  &vivld, &vin);
9667c3e324e3SHariprasad Shenai 	if (ret < 0)
9668c3e324e3SHariprasad Shenai 		return ret;
9669c3e324e3SHariprasad Shenai 
9670c3e324e3SHariprasad Shenai 	pi->viid = ret;
9671c3e324e3SHariprasad Shenai 	pi->tx_chan = port;
9672c3e324e3SHariprasad Shenai 	pi->lport = port;
9673c3e324e3SHariprasad Shenai 	pi->rss_size = rss_size;
967474dd5aa1SVishal Kulkarni 	pi->rx_cchan = t4_get_tp_e2c_map(pi->adapter, port);
9675c3e324e3SHariprasad Shenai 
967602d805dcSSantosh Rastapur 	/* If fw supports returning the VIN as part of FW_VI_CMD,
967702d805dcSSantosh Rastapur 	 * save the returned values.
967802d805dcSSantosh Rastapur 	 */
967902d805dcSSantosh Rastapur 	if (adapter->params.viid_smt_extn_support) {
968002d805dcSSantosh Rastapur 		pi->vivld = vivld;
968102d805dcSSantosh Rastapur 		pi->vin = vin;
968202d805dcSSantosh Rastapur 	} else {
968302d805dcSSantosh Rastapur 		/* Retrieve the values from VIID */
968402d805dcSSantosh Rastapur 		pi->vivld = FW_VIID_VIVLD_G(pi->viid);
968502d805dcSSantosh Rastapur 		pi->vin =  FW_VIID_VIN_G(pi->viid);
968602d805dcSSantosh Rastapur 	}
968702d805dcSSantosh Rastapur 
9688c3168cabSGanesh Goudar 	pi->port_type = port_type;
9689c3168cabSGanesh Goudar 	pi->mdio_addr = mdio_addr;
9690c3e324e3SHariprasad Shenai 	pi->mod_type = FW_PORT_MOD_TYPE_NA;
9691c3e324e3SHariprasad Shenai 
9692c3168cabSGanesh Goudar 	init_link_config(&pi->link_cfg, pcaps, acaps);
9693c3e324e3SHariprasad Shenai 	return 0;
9694c3e324e3SHariprasad Shenai }
9695c3e324e3SHariprasad Shenai 
t4_port_init(struct adapter * adap,int mbox,int pf,int vf)969691744948SBill Pemberton int t4_port_init(struct adapter *adap, int mbox, int pf, int vf)
9697f7917c00SJeff Kirsher {
9698f7917c00SJeff Kirsher 	u8 addr[6];
9699f7917c00SJeff Kirsher 	int ret, i, j = 0;
9700f7917c00SJeff Kirsher 
9701f7917c00SJeff Kirsher 	for_each_port(adap, i) {
9702c3e324e3SHariprasad Shenai 		struct port_info *pi = adap2pinfo(adap, i);
9703f7917c00SJeff Kirsher 
9704f7917c00SJeff Kirsher 		while ((adap->params.portvec & (1 << j)) == 0)
9705f7917c00SJeff Kirsher 			j++;
9706f7917c00SJeff Kirsher 
9707c3e324e3SHariprasad Shenai 		ret = t4_init_portinfo(pi, mbox, j, pf, vf, addr);
9708f7917c00SJeff Kirsher 		if (ret)
9709f7917c00SJeff Kirsher 			return ret;
9710f7917c00SJeff Kirsher 
971147d71f45SJakub Kicinski 		eth_hw_addr_set(adap->port[i], addr);
9712f7917c00SJeff Kirsher 		j++;
9713f7917c00SJeff Kirsher 	}
9714f7917c00SJeff Kirsher 	return 0;
9715f7917c00SJeff Kirsher }
9716f1ff24aaSHariprasad Shenai 
t4_init_port_mirror(struct port_info * pi,u8 mbox,u8 port,u8 pf,u8 vf,u16 * mirror_viid)9717fd2261d8SRahul Lakkireddy int t4_init_port_mirror(struct port_info *pi, u8 mbox, u8 port, u8 pf, u8 vf,
9718fd2261d8SRahul Lakkireddy 			u16 *mirror_viid)
9719fd2261d8SRahul Lakkireddy {
9720fd2261d8SRahul Lakkireddy 	int ret;
9721fd2261d8SRahul Lakkireddy 
9722fd2261d8SRahul Lakkireddy 	ret = t4_alloc_vi(pi->adapter, mbox, port, pf, vf, 1, NULL, NULL,
9723fd2261d8SRahul Lakkireddy 			  NULL, NULL);
9724fd2261d8SRahul Lakkireddy 	if (ret < 0)
9725fd2261d8SRahul Lakkireddy 		return ret;
9726fd2261d8SRahul Lakkireddy 
9727fd2261d8SRahul Lakkireddy 	if (mirror_viid)
9728fd2261d8SRahul Lakkireddy 		*mirror_viid = ret;
9729fd2261d8SRahul Lakkireddy 
9730fd2261d8SRahul Lakkireddy 	return 0;
9731fd2261d8SRahul Lakkireddy }
9732fd2261d8SRahul Lakkireddy 
9733f1ff24aaSHariprasad Shenai /**
973474b3092cSHariprasad Shenai  *	t4_read_cimq_cfg - read CIM queue configuration
973574b3092cSHariprasad Shenai  *	@adap: the adapter
973674b3092cSHariprasad Shenai  *	@base: holds the queue base addresses in bytes
973774b3092cSHariprasad Shenai  *	@size: holds the queue sizes in bytes
973874b3092cSHariprasad Shenai  *	@thres: holds the queue full thresholds in bytes
973974b3092cSHariprasad Shenai  *
974074b3092cSHariprasad Shenai  *	Returns the current configuration of the CIM queues, starting with
974174b3092cSHariprasad Shenai  *	the IBQs, then the OBQs.
974274b3092cSHariprasad Shenai  */
t4_read_cimq_cfg(struct adapter * adap,u16 * base,u16 * size,u16 * thres)974374b3092cSHariprasad Shenai void t4_read_cimq_cfg(struct adapter *adap, u16 *base, u16 *size, u16 *thres)
974474b3092cSHariprasad Shenai {
974574b3092cSHariprasad Shenai 	unsigned int i, v;
974674b3092cSHariprasad Shenai 	int cim_num_obq = is_t4(adap->params.chip) ?
974774b3092cSHariprasad Shenai 				CIM_NUM_OBQ : CIM_NUM_OBQ_T5;
974874b3092cSHariprasad Shenai 
974974b3092cSHariprasad Shenai 	for (i = 0; i < CIM_NUM_IBQ; i++) {
975074b3092cSHariprasad Shenai 		t4_write_reg(adap, CIM_QUEUE_CONFIG_REF_A, IBQSELECT_F |
975174b3092cSHariprasad Shenai 			     QUENUMSELECT_V(i));
975274b3092cSHariprasad Shenai 		v = t4_read_reg(adap, CIM_QUEUE_CONFIG_CTRL_A);
975374b3092cSHariprasad Shenai 		/* value is in 256-byte units */
975474b3092cSHariprasad Shenai 		*base++ = CIMQBASE_G(v) * 256;
975574b3092cSHariprasad Shenai 		*size++ = CIMQSIZE_G(v) * 256;
975674b3092cSHariprasad Shenai 		*thres++ = QUEFULLTHRSH_G(v) * 8; /* 8-byte unit */
975774b3092cSHariprasad Shenai 	}
975874b3092cSHariprasad Shenai 	for (i = 0; i < cim_num_obq; i++) {
975974b3092cSHariprasad Shenai 		t4_write_reg(adap, CIM_QUEUE_CONFIG_REF_A, OBQSELECT_F |
976074b3092cSHariprasad Shenai 			     QUENUMSELECT_V(i));
976174b3092cSHariprasad Shenai 		v = t4_read_reg(adap, CIM_QUEUE_CONFIG_CTRL_A);
976274b3092cSHariprasad Shenai 		/* value is in 256-byte units */
976374b3092cSHariprasad Shenai 		*base++ = CIMQBASE_G(v) * 256;
976474b3092cSHariprasad Shenai 		*size++ = CIMQSIZE_G(v) * 256;
976574b3092cSHariprasad Shenai 	}
976674b3092cSHariprasad Shenai }
976774b3092cSHariprasad Shenai 
976874b3092cSHariprasad Shenai /**
9769e5f0e43bSHariprasad Shenai  *	t4_read_cim_ibq - read the contents of a CIM inbound queue
9770e5f0e43bSHariprasad Shenai  *	@adap: the adapter
9771e5f0e43bSHariprasad Shenai  *	@qid: the queue index
9772e5f0e43bSHariprasad Shenai  *	@data: where to store the queue contents
9773e5f0e43bSHariprasad Shenai  *	@n: capacity of @data in 32-bit words
9774e5f0e43bSHariprasad Shenai  *
9775e5f0e43bSHariprasad Shenai  *	Reads the contents of the selected CIM queue starting at address 0 up
9776e5f0e43bSHariprasad Shenai  *	to the capacity of @data.  @n must be a multiple of 4.  Returns < 0 on
9777e5f0e43bSHariprasad Shenai  *	error and the number of 32-bit words actually read on success.
9778e5f0e43bSHariprasad Shenai  */
t4_read_cim_ibq(struct adapter * adap,unsigned int qid,u32 * data,size_t n)9779e5f0e43bSHariprasad Shenai int t4_read_cim_ibq(struct adapter *adap, unsigned int qid, u32 *data, size_t n)
9780e5f0e43bSHariprasad Shenai {
9781e5f0e43bSHariprasad Shenai 	int i, err, attempts;
9782e5f0e43bSHariprasad Shenai 	unsigned int addr;
9783e5f0e43bSHariprasad Shenai 	const unsigned int nwords = CIM_IBQ_SIZE * 4;
9784e5f0e43bSHariprasad Shenai 
9785e5f0e43bSHariprasad Shenai 	if (qid > 5 || (n & 3))
9786e5f0e43bSHariprasad Shenai 		return -EINVAL;
9787e5f0e43bSHariprasad Shenai 
9788e5f0e43bSHariprasad Shenai 	addr = qid * nwords;
9789e5f0e43bSHariprasad Shenai 	if (n > nwords)
9790e5f0e43bSHariprasad Shenai 		n = nwords;
9791e5f0e43bSHariprasad Shenai 
9792e5f0e43bSHariprasad Shenai 	/* It might take 3-10ms before the IBQ debug read access is allowed.
9793e5f0e43bSHariprasad Shenai 	 * Wait for 1 Sec with a delay of 1 usec.
9794e5f0e43bSHariprasad Shenai 	 */
9795e5f0e43bSHariprasad Shenai 	attempts = 1000000;
9796e5f0e43bSHariprasad Shenai 
9797e5f0e43bSHariprasad Shenai 	for (i = 0; i < n; i++, addr++) {
9798e5f0e43bSHariprasad Shenai 		t4_write_reg(adap, CIM_IBQ_DBG_CFG_A, IBQDBGADDR_V(addr) |
9799e5f0e43bSHariprasad Shenai 			     IBQDBGEN_F);
9800e5f0e43bSHariprasad Shenai 		err = t4_wait_op_done(adap, CIM_IBQ_DBG_CFG_A, IBQDBGBUSY_F, 0,
9801e5f0e43bSHariprasad Shenai 				      attempts, 1);
9802e5f0e43bSHariprasad Shenai 		if (err)
9803e5f0e43bSHariprasad Shenai 			return err;
9804e5f0e43bSHariprasad Shenai 		*data++ = t4_read_reg(adap, CIM_IBQ_DBG_DATA_A);
9805e5f0e43bSHariprasad Shenai 	}
9806e5f0e43bSHariprasad Shenai 	t4_write_reg(adap, CIM_IBQ_DBG_CFG_A, 0);
9807e5f0e43bSHariprasad Shenai 	return i;
9808e5f0e43bSHariprasad Shenai }
9809e5f0e43bSHariprasad Shenai 
9810e5f0e43bSHariprasad Shenai /**
9811c778af7dSHariprasad Shenai  *	t4_read_cim_obq - read the contents of a CIM outbound queue
9812c778af7dSHariprasad Shenai  *	@adap: the adapter
9813c778af7dSHariprasad Shenai  *	@qid: the queue index
9814c778af7dSHariprasad Shenai  *	@data: where to store the queue contents
9815c778af7dSHariprasad Shenai  *	@n: capacity of @data in 32-bit words
9816c778af7dSHariprasad Shenai  *
9817c778af7dSHariprasad Shenai  *	Reads the contents of the selected CIM queue starting at address 0 up
9818c778af7dSHariprasad Shenai  *	to the capacity of @data.  @n must be a multiple of 4.  Returns < 0 on
9819c778af7dSHariprasad Shenai  *	error and the number of 32-bit words actually read on success.
9820c778af7dSHariprasad Shenai  */
t4_read_cim_obq(struct adapter * adap,unsigned int qid,u32 * data,size_t n)9821c778af7dSHariprasad Shenai int t4_read_cim_obq(struct adapter *adap, unsigned int qid, u32 *data, size_t n)
9822c778af7dSHariprasad Shenai {
9823c778af7dSHariprasad Shenai 	int i, err;
9824c778af7dSHariprasad Shenai 	unsigned int addr, v, nwords;
9825c778af7dSHariprasad Shenai 	int cim_num_obq = is_t4(adap->params.chip) ?
9826c778af7dSHariprasad Shenai 				CIM_NUM_OBQ : CIM_NUM_OBQ_T5;
9827c778af7dSHariprasad Shenai 
9828c778af7dSHariprasad Shenai 	if ((qid > (cim_num_obq - 1)) || (n & 3))
9829c778af7dSHariprasad Shenai 		return -EINVAL;
9830c778af7dSHariprasad Shenai 
9831c778af7dSHariprasad Shenai 	t4_write_reg(adap, CIM_QUEUE_CONFIG_REF_A, OBQSELECT_F |
9832c778af7dSHariprasad Shenai 		     QUENUMSELECT_V(qid));
9833c778af7dSHariprasad Shenai 	v = t4_read_reg(adap, CIM_QUEUE_CONFIG_CTRL_A);
9834c778af7dSHariprasad Shenai 
9835c778af7dSHariprasad Shenai 	addr = CIMQBASE_G(v) * 64;    /* muliple of 256 -> muliple of 4 */
9836c778af7dSHariprasad Shenai 	nwords = CIMQSIZE_G(v) * 64;  /* same */
9837c778af7dSHariprasad Shenai 	if (n > nwords)
9838c778af7dSHariprasad Shenai 		n = nwords;
9839c778af7dSHariprasad Shenai 
9840c778af7dSHariprasad Shenai 	for (i = 0; i < n; i++, addr++) {
9841c778af7dSHariprasad Shenai 		t4_write_reg(adap, CIM_OBQ_DBG_CFG_A, OBQDBGADDR_V(addr) |
9842c778af7dSHariprasad Shenai 			     OBQDBGEN_F);
9843c778af7dSHariprasad Shenai 		err = t4_wait_op_done(adap, CIM_OBQ_DBG_CFG_A, OBQDBGBUSY_F, 0,
9844c778af7dSHariprasad Shenai 				      2, 1);
9845c778af7dSHariprasad Shenai 		if (err)
9846c778af7dSHariprasad Shenai 			return err;
9847c778af7dSHariprasad Shenai 		*data++ = t4_read_reg(adap, CIM_OBQ_DBG_DATA_A);
9848c778af7dSHariprasad Shenai 	}
9849c778af7dSHariprasad Shenai 	t4_write_reg(adap, CIM_OBQ_DBG_CFG_A, 0);
9850c778af7dSHariprasad Shenai 	return i;
9851c778af7dSHariprasad Shenai }
9852c778af7dSHariprasad Shenai 
9853c778af7dSHariprasad Shenai /**
9854f1ff24aaSHariprasad Shenai  *	t4_cim_read - read a block from CIM internal address space
9855f1ff24aaSHariprasad Shenai  *	@adap: the adapter
9856f1ff24aaSHariprasad Shenai  *	@addr: the start address within the CIM address space
9857f1ff24aaSHariprasad Shenai  *	@n: number of words to read
9858f1ff24aaSHariprasad Shenai  *	@valp: where to store the result
9859f1ff24aaSHariprasad Shenai  *
9860f1ff24aaSHariprasad Shenai  *	Reads a block of 4-byte words from the CIM intenal address space.
9861f1ff24aaSHariprasad Shenai  */
t4_cim_read(struct adapter * adap,unsigned int addr,unsigned int n,unsigned int * valp)9862f1ff24aaSHariprasad Shenai int t4_cim_read(struct adapter *adap, unsigned int addr, unsigned int n,
9863f1ff24aaSHariprasad Shenai 		unsigned int *valp)
9864f1ff24aaSHariprasad Shenai {
9865f1ff24aaSHariprasad Shenai 	int ret = 0;
9866f1ff24aaSHariprasad Shenai 
9867f1ff24aaSHariprasad Shenai 	if (t4_read_reg(adap, CIM_HOST_ACC_CTRL_A) & HOSTBUSY_F)
9868f1ff24aaSHariprasad Shenai 		return -EBUSY;
9869f1ff24aaSHariprasad Shenai 
9870f1ff24aaSHariprasad Shenai 	for ( ; !ret && n--; addr += 4) {
9871f1ff24aaSHariprasad Shenai 		t4_write_reg(adap, CIM_HOST_ACC_CTRL_A, addr);
9872f1ff24aaSHariprasad Shenai 		ret = t4_wait_op_done(adap, CIM_HOST_ACC_CTRL_A, HOSTBUSY_F,
9873f1ff24aaSHariprasad Shenai 				      0, 5, 2);
9874f1ff24aaSHariprasad Shenai 		if (!ret)
9875f1ff24aaSHariprasad Shenai 			*valp++ = t4_read_reg(adap, CIM_HOST_ACC_DATA_A);
9876f1ff24aaSHariprasad Shenai 	}
9877f1ff24aaSHariprasad Shenai 	return ret;
9878f1ff24aaSHariprasad Shenai }
9879f1ff24aaSHariprasad Shenai 
9880f1ff24aaSHariprasad Shenai /**
9881f1ff24aaSHariprasad Shenai  *	t4_cim_write - write a block into CIM internal address space
9882f1ff24aaSHariprasad Shenai  *	@adap: the adapter
9883f1ff24aaSHariprasad Shenai  *	@addr: the start address within the CIM address space
9884f1ff24aaSHariprasad Shenai  *	@n: number of words to write
9885f1ff24aaSHariprasad Shenai  *	@valp: set of values to write
9886f1ff24aaSHariprasad Shenai  *
9887f1ff24aaSHariprasad Shenai  *	Writes a block of 4-byte words into the CIM intenal address space.
9888f1ff24aaSHariprasad Shenai  */
t4_cim_write(struct adapter * adap,unsigned int addr,unsigned int n,const unsigned int * valp)9889f1ff24aaSHariprasad Shenai int t4_cim_write(struct adapter *adap, unsigned int addr, unsigned int n,
9890f1ff24aaSHariprasad Shenai 		 const unsigned int *valp)
9891f1ff24aaSHariprasad Shenai {
9892f1ff24aaSHariprasad Shenai 	int ret = 0;
9893f1ff24aaSHariprasad Shenai 
9894f1ff24aaSHariprasad Shenai 	if (t4_read_reg(adap, CIM_HOST_ACC_CTRL_A) & HOSTBUSY_F)
9895f1ff24aaSHariprasad Shenai 		return -EBUSY;
9896f1ff24aaSHariprasad Shenai 
9897f1ff24aaSHariprasad Shenai 	for ( ; !ret && n--; addr += 4) {
9898f1ff24aaSHariprasad Shenai 		t4_write_reg(adap, CIM_HOST_ACC_DATA_A, *valp++);
9899f1ff24aaSHariprasad Shenai 		t4_write_reg(adap, CIM_HOST_ACC_CTRL_A, addr | HOSTWRITE_F);
9900f1ff24aaSHariprasad Shenai 		ret = t4_wait_op_done(adap, CIM_HOST_ACC_CTRL_A, HOSTBUSY_F,
9901f1ff24aaSHariprasad Shenai 				      0, 5, 2);
9902f1ff24aaSHariprasad Shenai 	}
9903f1ff24aaSHariprasad Shenai 	return ret;
9904f1ff24aaSHariprasad Shenai }
9905f1ff24aaSHariprasad Shenai 
t4_cim_write1(struct adapter * adap,unsigned int addr,unsigned int val)9906f1ff24aaSHariprasad Shenai static int t4_cim_write1(struct adapter *adap, unsigned int addr,
9907f1ff24aaSHariprasad Shenai 			 unsigned int val)
9908f1ff24aaSHariprasad Shenai {
9909f1ff24aaSHariprasad Shenai 	return t4_cim_write(adap, addr, 1, &val);
9910f1ff24aaSHariprasad Shenai }
9911f1ff24aaSHariprasad Shenai 
9912f1ff24aaSHariprasad Shenai /**
9913f1ff24aaSHariprasad Shenai  *	t4_cim_read_la - read CIM LA capture buffer
9914f1ff24aaSHariprasad Shenai  *	@adap: the adapter
9915f1ff24aaSHariprasad Shenai  *	@la_buf: where to store the LA data
9916f1ff24aaSHariprasad Shenai  *	@wrptr: the HW write pointer within the capture buffer
9917f1ff24aaSHariprasad Shenai  *
9918f1ff24aaSHariprasad Shenai  *	Reads the contents of the CIM LA buffer with the most recent entry at
9919f1ff24aaSHariprasad Shenai  *	the end	of the returned data and with the entry at @wrptr first.
9920f1ff24aaSHariprasad Shenai  *	We try to leave the LA in the running state we find it in.
9921f1ff24aaSHariprasad Shenai  */
t4_cim_read_la(struct adapter * adap,u32 * la_buf,unsigned int * wrptr)9922f1ff24aaSHariprasad Shenai int t4_cim_read_la(struct adapter *adap, u32 *la_buf, unsigned int *wrptr)
9923f1ff24aaSHariprasad Shenai {
9924f1ff24aaSHariprasad Shenai 	int i, ret;
9925f1ff24aaSHariprasad Shenai 	unsigned int cfg, val, idx;
9926f1ff24aaSHariprasad Shenai 
9927f1ff24aaSHariprasad Shenai 	ret = t4_cim_read(adap, UP_UP_DBG_LA_CFG_A, 1, &cfg);
9928f1ff24aaSHariprasad Shenai 	if (ret)
9929f1ff24aaSHariprasad Shenai 		return ret;
9930f1ff24aaSHariprasad Shenai 
9931f1ff24aaSHariprasad Shenai 	if (cfg & UPDBGLAEN_F) {	/* LA is running, freeze it */
9932f1ff24aaSHariprasad Shenai 		ret = t4_cim_write1(adap, UP_UP_DBG_LA_CFG_A, 0);
9933f1ff24aaSHariprasad Shenai 		if (ret)
9934f1ff24aaSHariprasad Shenai 			return ret;
9935f1ff24aaSHariprasad Shenai 	}
9936f1ff24aaSHariprasad Shenai 
9937f1ff24aaSHariprasad Shenai 	ret = t4_cim_read(adap, UP_UP_DBG_LA_CFG_A, 1, &val);
9938f1ff24aaSHariprasad Shenai 	if (ret)
9939f1ff24aaSHariprasad Shenai 		goto restart;
9940f1ff24aaSHariprasad Shenai 
9941f1ff24aaSHariprasad Shenai 	idx = UPDBGLAWRPTR_G(val);
9942f1ff24aaSHariprasad Shenai 	if (wrptr)
9943f1ff24aaSHariprasad Shenai 		*wrptr = idx;
9944f1ff24aaSHariprasad Shenai 
9945f1ff24aaSHariprasad Shenai 	for (i = 0; i < adap->params.cim_la_size; i++) {
9946f1ff24aaSHariprasad Shenai 		ret = t4_cim_write1(adap, UP_UP_DBG_LA_CFG_A,
9947f1ff24aaSHariprasad Shenai 				    UPDBGLARDPTR_V(idx) | UPDBGLARDEN_F);
9948f1ff24aaSHariprasad Shenai 		if (ret)
9949f1ff24aaSHariprasad Shenai 			break;
9950f1ff24aaSHariprasad Shenai 		ret = t4_cim_read(adap, UP_UP_DBG_LA_CFG_A, 1, &val);
9951f1ff24aaSHariprasad Shenai 		if (ret)
9952f1ff24aaSHariprasad Shenai 			break;
9953f1ff24aaSHariprasad Shenai 		if (val & UPDBGLARDEN_F) {
9954f1ff24aaSHariprasad Shenai 			ret = -ETIMEDOUT;
9955f1ff24aaSHariprasad Shenai 			break;
9956f1ff24aaSHariprasad Shenai 		}
9957f1ff24aaSHariprasad Shenai 		ret = t4_cim_read(adap, UP_UP_DBG_LA_DATA_A, 1, &la_buf[i]);
9958f1ff24aaSHariprasad Shenai 		if (ret)
9959f1ff24aaSHariprasad Shenai 			break;
9960a97051f4SGanesh Goudar 
9961a97051f4SGanesh Goudar 		/* Bits 0-3 of UpDbgLaRdPtr can be between 0000 to 1001 to
9962a97051f4SGanesh Goudar 		 * identify the 32-bit portion of the full 312-bit data
9963a97051f4SGanesh Goudar 		 */
9964a97051f4SGanesh Goudar 		if (is_t6(adap->params.chip) && (idx & 0xf) >= 9)
9965a97051f4SGanesh Goudar 			idx = (idx & 0xff0) + 0x10;
9966a97051f4SGanesh Goudar 		else
9967a97051f4SGanesh Goudar 			idx++;
9968a97051f4SGanesh Goudar 		/* address can't exceed 0xfff */
9969a97051f4SGanesh Goudar 		idx &= UPDBGLARDPTR_M;
9970f1ff24aaSHariprasad Shenai 	}
9971f1ff24aaSHariprasad Shenai restart:
9972f1ff24aaSHariprasad Shenai 	if (cfg & UPDBGLAEN_F) {
9973f1ff24aaSHariprasad Shenai 		int r = t4_cim_write1(adap, UP_UP_DBG_LA_CFG_A,
9974f1ff24aaSHariprasad Shenai 				      cfg & ~UPDBGLARDEN_F);
9975f1ff24aaSHariprasad Shenai 		if (!ret)
9976f1ff24aaSHariprasad Shenai 			ret = r;
9977f1ff24aaSHariprasad Shenai 	}
9978f1ff24aaSHariprasad Shenai 	return ret;
9979f1ff24aaSHariprasad Shenai }
99802d277b3bSHariprasad Shenai 
99812d277b3bSHariprasad Shenai /**
99822d277b3bSHariprasad Shenai  *	t4_tp_read_la - read TP LA capture buffer
99832d277b3bSHariprasad Shenai  *	@adap: the adapter
99842d277b3bSHariprasad Shenai  *	@la_buf: where to store the LA data
99852d277b3bSHariprasad Shenai  *	@wrptr: the HW write pointer within the capture buffer
99862d277b3bSHariprasad Shenai  *
99872d277b3bSHariprasad Shenai  *	Reads the contents of the TP LA buffer with the most recent entry at
99882d277b3bSHariprasad Shenai  *	the end	of the returned data and with the entry at @wrptr first.
99892d277b3bSHariprasad Shenai  *	We leave the LA in the running state we find it in.
99902d277b3bSHariprasad Shenai  */
t4_tp_read_la(struct adapter * adap,u64 * la_buf,unsigned int * wrptr)99912d277b3bSHariprasad Shenai void t4_tp_read_la(struct adapter *adap, u64 *la_buf, unsigned int *wrptr)
99922d277b3bSHariprasad Shenai {
99932d277b3bSHariprasad Shenai 	bool last_incomplete;
99942d277b3bSHariprasad Shenai 	unsigned int i, cfg, val, idx;
99952d277b3bSHariprasad Shenai 
99962d277b3bSHariprasad Shenai 	cfg = t4_read_reg(adap, TP_DBG_LA_CONFIG_A) & 0xffff;
99972d277b3bSHariprasad Shenai 	if (cfg & DBGLAENABLE_F)			/* freeze LA */
99982d277b3bSHariprasad Shenai 		t4_write_reg(adap, TP_DBG_LA_CONFIG_A,
99992d277b3bSHariprasad Shenai 			     adap->params.tp.la_mask | (cfg ^ DBGLAENABLE_F));
100002d277b3bSHariprasad Shenai 
100012d277b3bSHariprasad Shenai 	val = t4_read_reg(adap, TP_DBG_LA_CONFIG_A);
100022d277b3bSHariprasad Shenai 	idx = DBGLAWPTR_G(val);
100032d277b3bSHariprasad Shenai 	last_incomplete = DBGLAMODE_G(val) >= 2 && (val & DBGLAWHLF_F) == 0;
100042d277b3bSHariprasad Shenai 	if (last_incomplete)
100052d277b3bSHariprasad Shenai 		idx = (idx + 1) & DBGLARPTR_M;
100062d277b3bSHariprasad Shenai 	if (wrptr)
100072d277b3bSHariprasad Shenai 		*wrptr = idx;
100082d277b3bSHariprasad Shenai 
100092d277b3bSHariprasad Shenai 	val &= 0xffff;
100102d277b3bSHariprasad Shenai 	val &= ~DBGLARPTR_V(DBGLARPTR_M);
100112d277b3bSHariprasad Shenai 	val |= adap->params.tp.la_mask;
100122d277b3bSHariprasad Shenai 
100132d277b3bSHariprasad Shenai 	for (i = 0; i < TPLA_SIZE; i++) {
100142d277b3bSHariprasad Shenai 		t4_write_reg(adap, TP_DBG_LA_CONFIG_A, DBGLARPTR_V(idx) | val);
100152d277b3bSHariprasad Shenai 		la_buf[i] = t4_read_reg64(adap, TP_DBG_LA_DATAL_A);
100162d277b3bSHariprasad Shenai 		idx = (idx + 1) & DBGLARPTR_M;
100172d277b3bSHariprasad Shenai 	}
100182d277b3bSHariprasad Shenai 
100192d277b3bSHariprasad Shenai 	/* Wipe out last entry if it isn't valid */
100202d277b3bSHariprasad Shenai 	if (last_incomplete)
100212d277b3bSHariprasad Shenai 		la_buf[TPLA_SIZE - 1] = ~0ULL;
100222d277b3bSHariprasad Shenai 
100232d277b3bSHariprasad Shenai 	if (cfg & DBGLAENABLE_F)                    /* restore running state */
100242d277b3bSHariprasad Shenai 		t4_write_reg(adap, TP_DBG_LA_CONFIG_A,
100252d277b3bSHariprasad Shenai 			     cfg | adap->params.tp.la_mask);
100262d277b3bSHariprasad Shenai }
10027a3bfb617SHariprasad Shenai 
10028a3bfb617SHariprasad Shenai /* SGE Hung Ingress DMA Warning Threshold time and Warning Repeat Rate (in
10029a3bfb617SHariprasad Shenai  * seconds).  If we find one of the SGE Ingress DMA State Machines in the same
10030a3bfb617SHariprasad Shenai  * state for more than the Warning Threshold then we'll issue a warning about
10031a3bfb617SHariprasad Shenai  * a potential hang.  We'll repeat the warning as the SGE Ingress DMA Channel
10032a3bfb617SHariprasad Shenai  * appears to be hung every Warning Repeat second till the situation clears.
10033a3bfb617SHariprasad Shenai  * If the situation clears, we'll note that as well.
10034a3bfb617SHariprasad Shenai  */
10035a3bfb617SHariprasad Shenai #define SGE_IDMA_WARN_THRESH 1
10036a3bfb617SHariprasad Shenai #define SGE_IDMA_WARN_REPEAT 300
10037a3bfb617SHariprasad Shenai 
10038a3bfb617SHariprasad Shenai /**
10039a3bfb617SHariprasad Shenai  *	t4_idma_monitor_init - initialize SGE Ingress DMA Monitor
10040a3bfb617SHariprasad Shenai  *	@adapter: the adapter
10041a3bfb617SHariprasad Shenai  *	@idma: the adapter IDMA Monitor state
10042a3bfb617SHariprasad Shenai  *
10043a3bfb617SHariprasad Shenai  *	Initialize the state of an SGE Ingress DMA Monitor.
10044a3bfb617SHariprasad Shenai  */
t4_idma_monitor_init(struct adapter * adapter,struct sge_idma_monitor_state * idma)10045a3bfb617SHariprasad Shenai void t4_idma_monitor_init(struct adapter *adapter,
10046a3bfb617SHariprasad Shenai 			  struct sge_idma_monitor_state *idma)
10047a3bfb617SHariprasad Shenai {
10048a3bfb617SHariprasad Shenai 	/* Initialize the state variables for detecting an SGE Ingress DMA
10049a3bfb617SHariprasad Shenai 	 * hang.  The SGE has internal counters which count up on each clock
10050a3bfb617SHariprasad Shenai 	 * tick whenever the SGE finds its Ingress DMA State Engines in the
10051a3bfb617SHariprasad Shenai 	 * same state they were on the previous clock tick.  The clock used is
10052a3bfb617SHariprasad Shenai 	 * the Core Clock so we have a limit on the maximum "time" they can
10053a3bfb617SHariprasad Shenai 	 * record; typically a very small number of seconds.  For instance,
10054a3bfb617SHariprasad Shenai 	 * with a 600MHz Core Clock, we can only count up to a bit more than
10055a3bfb617SHariprasad Shenai 	 * 7s.  So we'll synthesize a larger counter in order to not run the
10056a3bfb617SHariprasad Shenai 	 * risk of having the "timers" overflow and give us the flexibility to
10057a3bfb617SHariprasad Shenai 	 * maintain a Hung SGE State Machine of our own which operates across
10058a3bfb617SHariprasad Shenai 	 * a longer time frame.
10059a3bfb617SHariprasad Shenai 	 */
10060a3bfb617SHariprasad Shenai 	idma->idma_1s_thresh = core_ticks_per_usec(adapter) * 1000000; /* 1s */
10061a3bfb617SHariprasad Shenai 	idma->idma_stalled[0] = 0;
10062a3bfb617SHariprasad Shenai 	idma->idma_stalled[1] = 0;
10063a3bfb617SHariprasad Shenai }
10064a3bfb617SHariprasad Shenai 
10065a3bfb617SHariprasad Shenai /**
10066a3bfb617SHariprasad Shenai  *	t4_idma_monitor - monitor SGE Ingress DMA state
10067a3bfb617SHariprasad Shenai  *	@adapter: the adapter
10068a3bfb617SHariprasad Shenai  *	@idma: the adapter IDMA Monitor state
10069a3bfb617SHariprasad Shenai  *	@hz: number of ticks/second
10070a3bfb617SHariprasad Shenai  *	@ticks: number of ticks since the last IDMA Monitor call
10071a3bfb617SHariprasad Shenai  */
t4_idma_monitor(struct adapter * adapter,struct sge_idma_monitor_state * idma,int hz,int ticks)10072a3bfb617SHariprasad Shenai void t4_idma_monitor(struct adapter *adapter,
10073a3bfb617SHariprasad Shenai 		     struct sge_idma_monitor_state *idma,
10074a3bfb617SHariprasad Shenai 		     int hz, int ticks)
10075a3bfb617SHariprasad Shenai {
10076a3bfb617SHariprasad Shenai 	int i, idma_same_state_cnt[2];
10077a3bfb617SHariprasad Shenai 
10078a3bfb617SHariprasad Shenai 	 /* Read the SGE Debug Ingress DMA Same State Count registers.  These
10079a3bfb617SHariprasad Shenai 	  * are counters inside the SGE which count up on each clock when the
10080a3bfb617SHariprasad Shenai 	  * SGE finds its Ingress DMA State Engines in the same states they
10081a3bfb617SHariprasad Shenai 	  * were in the previous clock.  The counters will peg out at
10082a3bfb617SHariprasad Shenai 	  * 0xffffffff without wrapping around so once they pass the 1s
10083a3bfb617SHariprasad Shenai 	  * threshold they'll stay above that till the IDMA state changes.
10084a3bfb617SHariprasad Shenai 	  */
10085a3bfb617SHariprasad Shenai 	t4_write_reg(adapter, SGE_DEBUG_INDEX_A, 13);
10086a3bfb617SHariprasad Shenai 	idma_same_state_cnt[0] = t4_read_reg(adapter, SGE_DEBUG_DATA_HIGH_A);
10087a3bfb617SHariprasad Shenai 	idma_same_state_cnt[1] = t4_read_reg(adapter, SGE_DEBUG_DATA_LOW_A);
10088a3bfb617SHariprasad Shenai 
10089a3bfb617SHariprasad Shenai 	for (i = 0; i < 2; i++) {
10090a3bfb617SHariprasad Shenai 		u32 debug0, debug11;
10091a3bfb617SHariprasad Shenai 
10092a3bfb617SHariprasad Shenai 		/* If the Ingress DMA Same State Counter ("timer") is less
10093a3bfb617SHariprasad Shenai 		 * than 1s, then we can reset our synthesized Stall Timer and
10094a3bfb617SHariprasad Shenai 		 * continue.  If we have previously emitted warnings about a
10095a3bfb617SHariprasad Shenai 		 * potential stalled Ingress Queue, issue a note indicating
10096a3bfb617SHariprasad Shenai 		 * that the Ingress Queue has resumed forward progress.
10097a3bfb617SHariprasad Shenai 		 */
10098a3bfb617SHariprasad Shenai 		if (idma_same_state_cnt[i] < idma->idma_1s_thresh) {
10099a3bfb617SHariprasad Shenai 			if (idma->idma_stalled[i] >= SGE_IDMA_WARN_THRESH * hz)
10100a3bfb617SHariprasad Shenai 				dev_warn(adapter->pdev_dev, "SGE idma%d, queue %u, "
10101a3bfb617SHariprasad Shenai 					 "resumed after %d seconds\n",
10102a3bfb617SHariprasad Shenai 					 i, idma->idma_qid[i],
10103a3bfb617SHariprasad Shenai 					 idma->idma_stalled[i] / hz);
10104a3bfb617SHariprasad Shenai 			idma->idma_stalled[i] = 0;
10105a3bfb617SHariprasad Shenai 			continue;
10106a3bfb617SHariprasad Shenai 		}
10107a3bfb617SHariprasad Shenai 
10108a3bfb617SHariprasad Shenai 		/* Synthesize an SGE Ingress DMA Same State Timer in the Hz
10109a3bfb617SHariprasad Shenai 		 * domain.  The first time we get here it'll be because we
10110a3bfb617SHariprasad Shenai 		 * passed the 1s Threshold; each additional time it'll be
10111a3bfb617SHariprasad Shenai 		 * because the RX Timer Callback is being fired on its regular
10112a3bfb617SHariprasad Shenai 		 * schedule.
10113a3bfb617SHariprasad Shenai 		 *
10114a3bfb617SHariprasad Shenai 		 * If the stall is below our Potential Hung Ingress Queue
10115a3bfb617SHariprasad Shenai 		 * Warning Threshold, continue.
10116a3bfb617SHariprasad Shenai 		 */
10117a3bfb617SHariprasad Shenai 		if (idma->idma_stalled[i] == 0) {
10118a3bfb617SHariprasad Shenai 			idma->idma_stalled[i] = hz;
10119a3bfb617SHariprasad Shenai 			idma->idma_warn[i] = 0;
10120a3bfb617SHariprasad Shenai 		} else {
10121a3bfb617SHariprasad Shenai 			idma->idma_stalled[i] += ticks;
10122a3bfb617SHariprasad Shenai 			idma->idma_warn[i] -= ticks;
10123a3bfb617SHariprasad Shenai 		}
10124a3bfb617SHariprasad Shenai 
10125a3bfb617SHariprasad Shenai 		if (idma->idma_stalled[i] < SGE_IDMA_WARN_THRESH * hz)
10126a3bfb617SHariprasad Shenai 			continue;
10127a3bfb617SHariprasad Shenai 
10128a3bfb617SHariprasad Shenai 		/* We'll issue a warning every SGE_IDMA_WARN_REPEAT seconds.
10129a3bfb617SHariprasad Shenai 		 */
10130a3bfb617SHariprasad Shenai 		if (idma->idma_warn[i] > 0)
10131a3bfb617SHariprasad Shenai 			continue;
10132a3bfb617SHariprasad Shenai 		idma->idma_warn[i] = SGE_IDMA_WARN_REPEAT * hz;
10133a3bfb617SHariprasad Shenai 
10134a3bfb617SHariprasad Shenai 		/* Read and save the SGE IDMA State and Queue ID information.
10135a3bfb617SHariprasad Shenai 		 * We do this every time in case it changes across time ...
10136a3bfb617SHariprasad Shenai 		 * can't be too careful ...
10137a3bfb617SHariprasad Shenai 		 */
10138a3bfb617SHariprasad Shenai 		t4_write_reg(adapter, SGE_DEBUG_INDEX_A, 0);
10139a3bfb617SHariprasad Shenai 		debug0 = t4_read_reg(adapter, SGE_DEBUG_DATA_LOW_A);
10140a3bfb617SHariprasad Shenai 		idma->idma_state[i] = (debug0 >> (i * 9)) & 0x3f;
10141a3bfb617SHariprasad Shenai 
10142a3bfb617SHariprasad Shenai 		t4_write_reg(adapter, SGE_DEBUG_INDEX_A, 11);
10143a3bfb617SHariprasad Shenai 		debug11 = t4_read_reg(adapter, SGE_DEBUG_DATA_LOW_A);
10144a3bfb617SHariprasad Shenai 		idma->idma_qid[i] = (debug11 >> (i * 16)) & 0xffff;
10145a3bfb617SHariprasad Shenai 
10146a3bfb617SHariprasad Shenai 		dev_warn(adapter->pdev_dev, "SGE idma%u, queue %u, potentially stuck in "
10147a3bfb617SHariprasad Shenai 			 "state %u for %d seconds (debug0=%#x, debug11=%#x)\n",
10148a3bfb617SHariprasad Shenai 			 i, idma->idma_qid[i], idma->idma_state[i],
10149a3bfb617SHariprasad Shenai 			 idma->idma_stalled[i] / hz,
10150a3bfb617SHariprasad Shenai 			 debug0, debug11);
10151a3bfb617SHariprasad Shenai 		t4_sge_decode_idma_state(adapter, idma->idma_state[i]);
10152a3bfb617SHariprasad Shenai 	}
10153a3bfb617SHariprasad Shenai }
10154858aa65cSHariprasad Shenai 
10155858aa65cSHariprasad Shenai /**
101564da18741SArjun Vynipadath  *	t4_load_cfg - download config file
101574da18741SArjun Vynipadath  *	@adap: the adapter
101584da18741SArjun Vynipadath  *	@cfg_data: the cfg text file to write
101594da18741SArjun Vynipadath  *	@size: text file size
101604da18741SArjun Vynipadath  *
101614da18741SArjun Vynipadath  *	Write the supplied config text file to the card's serial flash.
101624da18741SArjun Vynipadath  */
t4_load_cfg(struct adapter * adap,const u8 * cfg_data,unsigned int size)101634da18741SArjun Vynipadath int t4_load_cfg(struct adapter *adap, const u8 *cfg_data, unsigned int size)
101644da18741SArjun Vynipadath {
101654da18741SArjun Vynipadath 	int ret, i, n, cfg_addr;
101664da18741SArjun Vynipadath 	unsigned int addr;
101674da18741SArjun Vynipadath 	unsigned int flash_cfg_start_sec;
101684da18741SArjun Vynipadath 	unsigned int sf_sec_size = adap->params.sf_size / adap->params.sf_nsec;
101694da18741SArjun Vynipadath 
101704da18741SArjun Vynipadath 	cfg_addr = t4_flash_cfg_addr(adap);
101714da18741SArjun Vynipadath 	if (cfg_addr < 0)
101724da18741SArjun Vynipadath 		return cfg_addr;
101734da18741SArjun Vynipadath 
101744da18741SArjun Vynipadath 	addr = cfg_addr;
101754da18741SArjun Vynipadath 	flash_cfg_start_sec = addr / SF_SEC_SIZE;
101764da18741SArjun Vynipadath 
101774da18741SArjun Vynipadath 	if (size > FLASH_CFG_MAX_SIZE) {
101784da18741SArjun Vynipadath 		dev_err(adap->pdev_dev, "cfg file too large, max is %u bytes\n",
101794da18741SArjun Vynipadath 			FLASH_CFG_MAX_SIZE);
101804da18741SArjun Vynipadath 		return -EFBIG;
101814da18741SArjun Vynipadath 	}
101824da18741SArjun Vynipadath 
101834da18741SArjun Vynipadath 	i = DIV_ROUND_UP(FLASH_CFG_MAX_SIZE,	/* # of sectors spanned */
101844da18741SArjun Vynipadath 			 sf_sec_size);
101854da18741SArjun Vynipadath 	ret = t4_flash_erase_sectors(adap, flash_cfg_start_sec,
101864da18741SArjun Vynipadath 				     flash_cfg_start_sec + i - 1);
101874da18741SArjun Vynipadath 	/* If size == 0 then we're simply erasing the FLASH sectors associated
101884da18741SArjun Vynipadath 	 * with the on-adapter Firmware Configuration File.
101894da18741SArjun Vynipadath 	 */
101904da18741SArjun Vynipadath 	if (ret || size == 0)
101914da18741SArjun Vynipadath 		goto out;
101924da18741SArjun Vynipadath 
101934da18741SArjun Vynipadath 	/* this will write to the flash up to SF_PAGE_SIZE at a time */
101944da18741SArjun Vynipadath 	for (i = 0; i < size; i += SF_PAGE_SIZE) {
101954da18741SArjun Vynipadath 		if ((size - i) <  SF_PAGE_SIZE)
101964da18741SArjun Vynipadath 			n = size - i;
101974da18741SArjun Vynipadath 		else
101984da18741SArjun Vynipadath 			n = SF_PAGE_SIZE;
1019942a20397SRahul Lakkireddy 		ret = t4_write_flash(adap, addr, n, cfg_data, true);
102004da18741SArjun Vynipadath 		if (ret)
102014da18741SArjun Vynipadath 			goto out;
102024da18741SArjun Vynipadath 
102034da18741SArjun Vynipadath 		addr += SF_PAGE_SIZE;
102044da18741SArjun Vynipadath 		cfg_data += SF_PAGE_SIZE;
102054da18741SArjun Vynipadath 	}
102064da18741SArjun Vynipadath 
102074da18741SArjun Vynipadath out:
102084da18741SArjun Vynipadath 	if (ret)
102094da18741SArjun Vynipadath 		dev_err(adap->pdev_dev, "config file %s failed %d\n",
102104da18741SArjun Vynipadath 			(size == 0 ? "clear" : "download"), ret);
102114da18741SArjun Vynipadath 	return ret;
102124da18741SArjun Vynipadath }
102134da18741SArjun Vynipadath 
102144da18741SArjun Vynipadath /**
10215e0333b1bSYang Shen  *	t4_set_vf_mac_acl - Set MAC address for the specified VF
10216858aa65cSHariprasad Shenai  *	@adapter: The adapter
10217858aa65cSHariprasad Shenai  *	@vf: one of the VFs instantiated by the specified PF
10218858aa65cSHariprasad Shenai  *	@naddr: the number of MAC addresses
10219858aa65cSHariprasad Shenai  *	@addr: the MAC address(es) to be set to the specified VF
10220858aa65cSHariprasad Shenai  */
t4_set_vf_mac_acl(struct adapter * adapter,unsigned int vf,unsigned int naddr,u8 * addr)10221858aa65cSHariprasad Shenai int t4_set_vf_mac_acl(struct adapter *adapter, unsigned int vf,
10222858aa65cSHariprasad Shenai 		      unsigned int naddr, u8 *addr)
10223858aa65cSHariprasad Shenai {
10224858aa65cSHariprasad Shenai 	struct fw_acl_mac_cmd cmd;
10225858aa65cSHariprasad Shenai 
10226858aa65cSHariprasad Shenai 	memset(&cmd, 0, sizeof(cmd));
10227858aa65cSHariprasad Shenai 	cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_ACL_MAC_CMD) |
10228858aa65cSHariprasad Shenai 				    FW_CMD_REQUEST_F |
10229858aa65cSHariprasad Shenai 				    FW_CMD_WRITE_F |
10230858aa65cSHariprasad Shenai 				    FW_ACL_MAC_CMD_PFN_V(adapter->pf) |
10231858aa65cSHariprasad Shenai 				    FW_ACL_MAC_CMD_VFN_V(vf));
10232858aa65cSHariprasad Shenai 
10233858aa65cSHariprasad Shenai 	/* Note: Do not enable the ACL */
10234858aa65cSHariprasad Shenai 	cmd.en_to_len16 = cpu_to_be32((unsigned int)FW_LEN16(cmd));
10235858aa65cSHariprasad Shenai 	cmd.nmac = naddr;
10236858aa65cSHariprasad Shenai 
10237858aa65cSHariprasad Shenai 	switch (adapter->pf) {
10238858aa65cSHariprasad Shenai 	case 3:
10239858aa65cSHariprasad Shenai 		memcpy(cmd.macaddr3, addr, sizeof(cmd.macaddr3));
10240858aa65cSHariprasad Shenai 		break;
10241858aa65cSHariprasad Shenai 	case 2:
10242858aa65cSHariprasad Shenai 		memcpy(cmd.macaddr2, addr, sizeof(cmd.macaddr2));
10243858aa65cSHariprasad Shenai 		break;
10244858aa65cSHariprasad Shenai 	case 1:
10245858aa65cSHariprasad Shenai 		memcpy(cmd.macaddr1, addr, sizeof(cmd.macaddr1));
10246858aa65cSHariprasad Shenai 		break;
10247858aa65cSHariprasad Shenai 	case 0:
10248858aa65cSHariprasad Shenai 		memcpy(cmd.macaddr0, addr, sizeof(cmd.macaddr0));
10249858aa65cSHariprasad Shenai 		break;
10250858aa65cSHariprasad Shenai 	}
10251858aa65cSHariprasad Shenai 
10252858aa65cSHariprasad Shenai 	return t4_wr_mbox(adapter, adapter->mbox, &cmd, sizeof(cmd), &cmd);
10253858aa65cSHariprasad Shenai }
10254b72a32daSRahul Lakkireddy 
1025508c4901bSRahul Lakkireddy /**
1025608c4901bSRahul Lakkireddy  * t4_read_pace_tbl - read the pace table
1025708c4901bSRahul Lakkireddy  * @adap: the adapter
1025808c4901bSRahul Lakkireddy  * @pace_vals: holds the returned values
1025908c4901bSRahul Lakkireddy  *
1026008c4901bSRahul Lakkireddy  * Returns the values of TP's pace table in microseconds.
1026108c4901bSRahul Lakkireddy  */
t4_read_pace_tbl(struct adapter * adap,unsigned int pace_vals[NTX_SCHED])1026208c4901bSRahul Lakkireddy void t4_read_pace_tbl(struct adapter *adap, unsigned int pace_vals[NTX_SCHED])
1026308c4901bSRahul Lakkireddy {
1026408c4901bSRahul Lakkireddy 	unsigned int i, v;
1026508c4901bSRahul Lakkireddy 
1026608c4901bSRahul Lakkireddy 	for (i = 0; i < NTX_SCHED; i++) {
1026708c4901bSRahul Lakkireddy 		t4_write_reg(adap, TP_PACE_TABLE_A, 0xffff0000 + i);
1026808c4901bSRahul Lakkireddy 		v = t4_read_reg(adap, TP_PACE_TABLE_A);
1026908c4901bSRahul Lakkireddy 		pace_vals[i] = dack_ticks_to_usec(adap, v);
1027008c4901bSRahul Lakkireddy 	}
1027108c4901bSRahul Lakkireddy }
1027208c4901bSRahul Lakkireddy 
1027308c4901bSRahul Lakkireddy /**
1027408c4901bSRahul Lakkireddy  * t4_get_tx_sched - get the configuration of a Tx HW traffic scheduler
1027508c4901bSRahul Lakkireddy  * @adap: the adapter
1027608c4901bSRahul Lakkireddy  * @sched: the scheduler index
1027708c4901bSRahul Lakkireddy  * @kbps: the byte rate in Kbps
1027808c4901bSRahul Lakkireddy  * @ipg: the interpacket delay in tenths of nanoseconds
1027908c4901bSRahul Lakkireddy  * @sleep_ok: if true we may sleep while awaiting command completion
1028008c4901bSRahul Lakkireddy  *
1028108c4901bSRahul Lakkireddy  * Return the current configuration of a HW Tx scheduler.
1028208c4901bSRahul Lakkireddy  */
t4_get_tx_sched(struct adapter * adap,unsigned int sched,unsigned int * kbps,unsigned int * ipg,bool sleep_ok)1028308c4901bSRahul Lakkireddy void t4_get_tx_sched(struct adapter *adap, unsigned int sched,
1028408c4901bSRahul Lakkireddy 		     unsigned int *kbps, unsigned int *ipg, bool sleep_ok)
1028508c4901bSRahul Lakkireddy {
1028608c4901bSRahul Lakkireddy 	unsigned int v, addr, bpt, cpt;
1028708c4901bSRahul Lakkireddy 
1028808c4901bSRahul Lakkireddy 	if (kbps) {
1028908c4901bSRahul Lakkireddy 		addr = TP_TX_MOD_Q1_Q0_RATE_LIMIT_A - sched / 2;
1029008c4901bSRahul Lakkireddy 		t4_tp_tm_pio_read(adap, &v, 1, addr, sleep_ok);
1029108c4901bSRahul Lakkireddy 		if (sched & 1)
1029208c4901bSRahul Lakkireddy 			v >>= 16;
1029308c4901bSRahul Lakkireddy 		bpt = (v >> 8) & 0xff;
1029408c4901bSRahul Lakkireddy 		cpt = v & 0xff;
1029508c4901bSRahul Lakkireddy 		if (!cpt) {
1029608c4901bSRahul Lakkireddy 			*kbps = 0;	/* scheduler disabled */
1029708c4901bSRahul Lakkireddy 		} else {
1029808c4901bSRahul Lakkireddy 			v = (adap->params.vpd.cclk * 1000) / cpt; /* ticks/s */
1029908c4901bSRahul Lakkireddy 			*kbps = (v * bpt) / 125;
1030008c4901bSRahul Lakkireddy 		}
1030108c4901bSRahul Lakkireddy 	}
1030208c4901bSRahul Lakkireddy 	if (ipg) {
1030308c4901bSRahul Lakkireddy 		addr = TP_TX_MOD_Q1_Q0_TIMER_SEPARATOR_A - sched / 2;
1030408c4901bSRahul Lakkireddy 		t4_tp_tm_pio_read(adap, &v, 1, addr, sleep_ok);
1030508c4901bSRahul Lakkireddy 		if (sched & 1)
1030608c4901bSRahul Lakkireddy 			v >>= 16;
1030708c4901bSRahul Lakkireddy 		v &= 0xffff;
1030808c4901bSRahul Lakkireddy 		*ipg = (10000 * v) / core_ticks_per_usec(adap);
1030908c4901bSRahul Lakkireddy 	}
1031008c4901bSRahul Lakkireddy }
1031108c4901bSRahul Lakkireddy 
103129e5c598cSRahul Lakkireddy /* t4_sge_ctxt_rd - read an SGE context through FW
103139e5c598cSRahul Lakkireddy  * @adap: the adapter
103149e5c598cSRahul Lakkireddy  * @mbox: mailbox to use for the FW command
103159e5c598cSRahul Lakkireddy  * @cid: the context id
103169e5c598cSRahul Lakkireddy  * @ctype: the context type
103179e5c598cSRahul Lakkireddy  * @data: where to store the context data
103189e5c598cSRahul Lakkireddy  *
103199e5c598cSRahul Lakkireddy  * Issues a FW command through the given mailbox to read an SGE context.
103209e5c598cSRahul Lakkireddy  */
t4_sge_ctxt_rd(struct adapter * adap,unsigned int mbox,unsigned int cid,enum ctxt_type ctype,u32 * data)103219e5c598cSRahul Lakkireddy int t4_sge_ctxt_rd(struct adapter *adap, unsigned int mbox, unsigned int cid,
103229e5c598cSRahul Lakkireddy 		   enum ctxt_type ctype, u32 *data)
103239e5c598cSRahul Lakkireddy {
103249e5c598cSRahul Lakkireddy 	struct fw_ldst_cmd c;
103259e5c598cSRahul Lakkireddy 	int ret;
103269e5c598cSRahul Lakkireddy 
103279e5c598cSRahul Lakkireddy 	if (ctype == CTXT_FLM)
103289e5c598cSRahul Lakkireddy 		ret = FW_LDST_ADDRSPC_SGE_FLMC;
103299e5c598cSRahul Lakkireddy 	else
103309e5c598cSRahul Lakkireddy 		ret = FW_LDST_ADDRSPC_SGE_CONMC;
103319e5c598cSRahul Lakkireddy 
103329e5c598cSRahul Lakkireddy 	memset(&c, 0, sizeof(c));
103339e5c598cSRahul Lakkireddy 	c.op_to_addrspace = cpu_to_be32(FW_CMD_OP_V(FW_LDST_CMD) |
103349e5c598cSRahul Lakkireddy 					FW_CMD_REQUEST_F | FW_CMD_READ_F |
103359e5c598cSRahul Lakkireddy 					FW_LDST_CMD_ADDRSPACE_V(ret));
103369e5c598cSRahul Lakkireddy 	c.cycles_to_len16 = cpu_to_be32(FW_LEN16(c));
103379e5c598cSRahul Lakkireddy 	c.u.idctxt.physid = cpu_to_be32(cid);
103389e5c598cSRahul Lakkireddy 
103399e5c598cSRahul Lakkireddy 	ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
103409e5c598cSRahul Lakkireddy 	if (ret == 0) {
103419e5c598cSRahul Lakkireddy 		data[0] = be32_to_cpu(c.u.idctxt.ctxt_data0);
103429e5c598cSRahul Lakkireddy 		data[1] = be32_to_cpu(c.u.idctxt.ctxt_data1);
103439e5c598cSRahul Lakkireddy 		data[2] = be32_to_cpu(c.u.idctxt.ctxt_data2);
103449e5c598cSRahul Lakkireddy 		data[3] = be32_to_cpu(c.u.idctxt.ctxt_data3);
103459e5c598cSRahul Lakkireddy 		data[4] = be32_to_cpu(c.u.idctxt.ctxt_data4);
103469e5c598cSRahul Lakkireddy 		data[5] = be32_to_cpu(c.u.idctxt.ctxt_data5);
103479e5c598cSRahul Lakkireddy 	}
103489e5c598cSRahul Lakkireddy 	return ret;
103499e5c598cSRahul Lakkireddy }
103509e5c598cSRahul Lakkireddy 
103519e5c598cSRahul Lakkireddy /**
103529e5c598cSRahul Lakkireddy  * t4_sge_ctxt_rd_bd - read an SGE context bypassing FW
103539e5c598cSRahul Lakkireddy  * @adap: the adapter
103549e5c598cSRahul Lakkireddy  * @cid: the context id
103559e5c598cSRahul Lakkireddy  * @ctype: the context type
103569e5c598cSRahul Lakkireddy  * @data: where to store the context data
103579e5c598cSRahul Lakkireddy  *
103589e5c598cSRahul Lakkireddy  * Reads an SGE context directly, bypassing FW.  This is only for
103599e5c598cSRahul Lakkireddy  * debugging when FW is unavailable.
103609e5c598cSRahul Lakkireddy  */
t4_sge_ctxt_rd_bd(struct adapter * adap,unsigned int cid,enum ctxt_type ctype,u32 * data)103619e5c598cSRahul Lakkireddy int t4_sge_ctxt_rd_bd(struct adapter *adap, unsigned int cid,
103629e5c598cSRahul Lakkireddy 		      enum ctxt_type ctype, u32 *data)
103639e5c598cSRahul Lakkireddy {
103649e5c598cSRahul Lakkireddy 	int i, ret;
103659e5c598cSRahul Lakkireddy 
103669e5c598cSRahul Lakkireddy 	t4_write_reg(adap, SGE_CTXT_CMD_A, CTXTQID_V(cid) | CTXTTYPE_V(ctype));
103679e5c598cSRahul Lakkireddy 	ret = t4_wait_op_done(adap, SGE_CTXT_CMD_A, BUSY_F, 0, 3, 1);
103689e5c598cSRahul Lakkireddy 	if (!ret)
103699e5c598cSRahul Lakkireddy 		for (i = SGE_CTXT_DATA0_A; i <= SGE_CTXT_DATA5_A; i += 4)
103709e5c598cSRahul Lakkireddy 			*data++ = t4_read_reg(adap, i);
103719e5c598cSRahul Lakkireddy 	return ret;
103729e5c598cSRahul Lakkireddy }
103739e5c598cSRahul Lakkireddy 
t4_sched_params(struct adapter * adapter,u8 type,u8 level,u8 mode,u8 rateunit,u8 ratemode,u8 channel,u8 class,u32 minrate,u32 maxrate,u16 weight,u16 pktsize,u16 burstsize)103744bccfc03SRahul Lakkireddy int t4_sched_params(struct adapter *adapter, u8 type, u8 level, u8 mode,
103754bccfc03SRahul Lakkireddy 		    u8 rateunit, u8 ratemode, u8 channel, u8 class,
103764bccfc03SRahul Lakkireddy 		    u32 minrate, u32 maxrate, u16 weight, u16 pktsize,
103774bccfc03SRahul Lakkireddy 		    u16 burstsize)
10378b72a32daSRahul Lakkireddy {
10379b72a32daSRahul Lakkireddy 	struct fw_sched_cmd cmd;
10380b72a32daSRahul Lakkireddy 
10381b72a32daSRahul Lakkireddy 	memset(&cmd, 0, sizeof(cmd));
10382b72a32daSRahul Lakkireddy 	cmd.op_to_write = cpu_to_be32(FW_CMD_OP_V(FW_SCHED_CMD) |
10383b72a32daSRahul Lakkireddy 				      FW_CMD_REQUEST_F |
10384b72a32daSRahul Lakkireddy 				      FW_CMD_WRITE_F);
10385b72a32daSRahul Lakkireddy 	cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
10386b72a32daSRahul Lakkireddy 
10387b72a32daSRahul Lakkireddy 	cmd.u.params.sc = FW_SCHED_SC_PARAMS;
10388b72a32daSRahul Lakkireddy 	cmd.u.params.type = type;
10389b72a32daSRahul Lakkireddy 	cmd.u.params.level = level;
10390b72a32daSRahul Lakkireddy 	cmd.u.params.mode = mode;
10391b72a32daSRahul Lakkireddy 	cmd.u.params.ch = channel;
10392b72a32daSRahul Lakkireddy 	cmd.u.params.cl = class;
10393b72a32daSRahul Lakkireddy 	cmd.u.params.unit = rateunit;
10394b72a32daSRahul Lakkireddy 	cmd.u.params.rate = ratemode;
10395b72a32daSRahul Lakkireddy 	cmd.u.params.min = cpu_to_be32(minrate);
10396b72a32daSRahul Lakkireddy 	cmd.u.params.max = cpu_to_be32(maxrate);
10397b72a32daSRahul Lakkireddy 	cmd.u.params.weight = cpu_to_be16(weight);
10398b72a32daSRahul Lakkireddy 	cmd.u.params.pktsize = cpu_to_be16(pktsize);
103994bccfc03SRahul Lakkireddy 	cmd.u.params.burstsize = cpu_to_be16(burstsize);
10400b72a32daSRahul Lakkireddy 
10401b72a32daSRahul Lakkireddy 	return t4_wr_mbox_meat(adapter, adapter->mbox, &cmd, sizeof(cmd),
10402b72a32daSRahul Lakkireddy 			       NULL, 1);
10403b72a32daSRahul Lakkireddy }
10404f56ec676SArjun Vynipadath 
10405f56ec676SArjun Vynipadath /**
10406f56ec676SArjun Vynipadath  *	t4_i2c_rd - read I2C data from adapter
10407f56ec676SArjun Vynipadath  *	@adap: the adapter
1040829bbf5d7SRahul Lakkireddy  *	@mbox: mailbox to use for the FW command
10409f56ec676SArjun Vynipadath  *	@port: Port number if per-port device; <0 if not
10410f56ec676SArjun Vynipadath  *	@devid: per-port device ID or absolute device ID
10411f56ec676SArjun Vynipadath  *	@offset: byte offset into device I2C space
10412f56ec676SArjun Vynipadath  *	@len: byte length of I2C space data
10413f56ec676SArjun Vynipadath  *	@buf: buffer in which to return I2C data
10414f56ec676SArjun Vynipadath  *
10415f56ec676SArjun Vynipadath  *	Reads the I2C data from the indicated device and location.
10416f56ec676SArjun Vynipadath  */
t4_i2c_rd(struct adapter * adap,unsigned int mbox,int port,unsigned int devid,unsigned int offset,unsigned int len,u8 * buf)10417f56ec676SArjun Vynipadath int t4_i2c_rd(struct adapter *adap, unsigned int mbox, int port,
10418f56ec676SArjun Vynipadath 	      unsigned int devid, unsigned int offset,
10419f56ec676SArjun Vynipadath 	      unsigned int len, u8 *buf)
10420f56ec676SArjun Vynipadath {
10421f56ec676SArjun Vynipadath 	struct fw_ldst_cmd ldst_cmd, ldst_rpl;
10422f56ec676SArjun Vynipadath 	unsigned int i2c_max = sizeof(ldst_cmd.u.i2c.data);
10423f56ec676SArjun Vynipadath 	int ret = 0;
10424f56ec676SArjun Vynipadath 
10425f56ec676SArjun Vynipadath 	if (len > I2C_PAGE_SIZE)
10426f56ec676SArjun Vynipadath 		return -EINVAL;
10427f56ec676SArjun Vynipadath 
10428f56ec676SArjun Vynipadath 	/* Dont allow reads that spans multiple pages */
10429f56ec676SArjun Vynipadath 	if (offset < I2C_PAGE_SIZE && offset + len > I2C_PAGE_SIZE)
10430f56ec676SArjun Vynipadath 		return -EINVAL;
10431f56ec676SArjun Vynipadath 
10432f56ec676SArjun Vynipadath 	memset(&ldst_cmd, 0, sizeof(ldst_cmd));
10433f56ec676SArjun Vynipadath 	ldst_cmd.op_to_addrspace =
10434f56ec676SArjun Vynipadath 		cpu_to_be32(FW_CMD_OP_V(FW_LDST_CMD) |
10435f56ec676SArjun Vynipadath 			    FW_CMD_REQUEST_F |
10436f56ec676SArjun Vynipadath 			    FW_CMD_READ_F |
10437f56ec676SArjun Vynipadath 			    FW_LDST_CMD_ADDRSPACE_V(FW_LDST_ADDRSPC_I2C));
10438f56ec676SArjun Vynipadath 	ldst_cmd.cycles_to_len16 = cpu_to_be32(FW_LEN16(ldst_cmd));
10439f56ec676SArjun Vynipadath 	ldst_cmd.u.i2c.pid = (port < 0 ? 0xff : port);
10440f56ec676SArjun Vynipadath 	ldst_cmd.u.i2c.did = devid;
10441f56ec676SArjun Vynipadath 
10442f56ec676SArjun Vynipadath 	while (len > 0) {
10443f56ec676SArjun Vynipadath 		unsigned int i2c_len = (len < i2c_max) ? len : i2c_max;
10444f56ec676SArjun Vynipadath 
10445f56ec676SArjun Vynipadath 		ldst_cmd.u.i2c.boffset = offset;
10446f56ec676SArjun Vynipadath 		ldst_cmd.u.i2c.blen = i2c_len;
10447f56ec676SArjun Vynipadath 
10448f56ec676SArjun Vynipadath 		ret = t4_wr_mbox(adap, mbox, &ldst_cmd, sizeof(ldst_cmd),
10449f56ec676SArjun Vynipadath 				 &ldst_rpl);
10450f56ec676SArjun Vynipadath 		if (ret)
10451f56ec676SArjun Vynipadath 			break;
10452f56ec676SArjun Vynipadath 
10453f56ec676SArjun Vynipadath 		memcpy(buf, ldst_rpl.u.i2c.data, i2c_len);
10454f56ec676SArjun Vynipadath 		offset += i2c_len;
10455f56ec676SArjun Vynipadath 		buf += i2c_len;
10456f56ec676SArjun Vynipadath 		len -= i2c_len;
10457f56ec676SArjun Vynipadath 	}
10458f56ec676SArjun Vynipadath 
10459f56ec676SArjun Vynipadath 	return ret;
10460f56ec676SArjun Vynipadath }
104619d5fd927SGanesh Goudar 
104629d5fd927SGanesh Goudar /**
104639d5fd927SGanesh Goudar  *      t4_set_vlan_acl - Set a VLAN id for the specified VF
1046429bbf5d7SRahul Lakkireddy  *      @adap: the adapter
104659d5fd927SGanesh Goudar  *      @mbox: mailbox to use for the FW command
104669d5fd927SGanesh Goudar  *      @vf: one of the VFs instantiated by the specified PF
104679d5fd927SGanesh Goudar  *      @vlan: The vlanid to be set
104689d5fd927SGanesh Goudar  */
t4_set_vlan_acl(struct adapter * adap,unsigned int mbox,unsigned int vf,u16 vlan)104699d5fd927SGanesh Goudar int t4_set_vlan_acl(struct adapter *adap, unsigned int mbox, unsigned int vf,
104709d5fd927SGanesh Goudar 		    u16 vlan)
104719d5fd927SGanesh Goudar {
104729d5fd927SGanesh Goudar 	struct fw_acl_vlan_cmd vlan_cmd;
104739d5fd927SGanesh Goudar 	unsigned int enable;
104749d5fd927SGanesh Goudar 
104759d5fd927SGanesh Goudar 	enable = (vlan ? FW_ACL_VLAN_CMD_EN_F : 0);
104769d5fd927SGanesh Goudar 	memset(&vlan_cmd, 0, sizeof(vlan_cmd));
104779d5fd927SGanesh Goudar 	vlan_cmd.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_ACL_VLAN_CMD) |
104789d5fd927SGanesh Goudar 					 FW_CMD_REQUEST_F |
104799d5fd927SGanesh Goudar 					 FW_CMD_WRITE_F |
104809d5fd927SGanesh Goudar 					 FW_CMD_EXEC_F |
104819d5fd927SGanesh Goudar 					 FW_ACL_VLAN_CMD_PFN_V(adap->pf) |
104829d5fd927SGanesh Goudar 					 FW_ACL_VLAN_CMD_VFN_V(vf));
104839d5fd927SGanesh Goudar 	vlan_cmd.en_to_len16 = cpu_to_be32(enable | FW_LEN16(vlan_cmd));
104849d5fd927SGanesh Goudar 	/* Drop all packets that donot match vlan id */
10485a89cdd8eSCasey Leedom 	vlan_cmd.dropnovlan_fm = (enable
10486a89cdd8eSCasey Leedom 				  ? (FW_ACL_VLAN_CMD_DROPNOVLAN_F |
10487a89cdd8eSCasey Leedom 				     FW_ACL_VLAN_CMD_FM_F) : 0);
104889d5fd927SGanesh Goudar 	if (enable != 0) {
104899d5fd927SGanesh Goudar 		vlan_cmd.nvlan = 1;
104909d5fd927SGanesh Goudar 		vlan_cmd.vlanid[0] = cpu_to_be16(vlan);
104919d5fd927SGanesh Goudar 	}
104929d5fd927SGanesh Goudar 
104939d5fd927SGanesh Goudar 	return t4_wr_mbox(adap, adap->mbox, &vlan_cmd, sizeof(vlan_cmd), NULL);
104949d5fd927SGanesh Goudar }
1049555088355SVishal Kulkarni 
1049655088355SVishal Kulkarni /**
1049755088355SVishal Kulkarni  *	modify_device_id - Modifies the device ID of the Boot BIOS image
1049855088355SVishal Kulkarni  *	@device_id: the device ID to write.
1049955088355SVishal Kulkarni  *	@boot_data: the boot image to modify.
1050055088355SVishal Kulkarni  *
1050155088355SVishal Kulkarni  *	Write the supplied device ID to the boot BIOS image.
1050255088355SVishal Kulkarni  */
modify_device_id(int device_id,u8 * boot_data)1050355088355SVishal Kulkarni static void modify_device_id(int device_id, u8 *boot_data)
1050455088355SVishal Kulkarni {
1050555088355SVishal Kulkarni 	struct cxgb4_pcir_data *pcir_header;
1050655088355SVishal Kulkarni 	struct legacy_pci_rom_hdr *header;
1050755088355SVishal Kulkarni 	u8 *cur_header = boot_data;
1050855088355SVishal Kulkarni 	u16 pcir_offset;
1050955088355SVishal Kulkarni 
1051055088355SVishal Kulkarni 	 /* Loop through all chained images and change the device ID's */
1051155088355SVishal Kulkarni 	do {
1051255088355SVishal Kulkarni 		header = (struct legacy_pci_rom_hdr *)cur_header;
1051355088355SVishal Kulkarni 		pcir_offset = le16_to_cpu(header->pcir_offset);
1051455088355SVishal Kulkarni 		pcir_header = (struct cxgb4_pcir_data *)(cur_header +
1051555088355SVishal Kulkarni 			      pcir_offset);
1051655088355SVishal Kulkarni 
1051755088355SVishal Kulkarni 		/**
1051855088355SVishal Kulkarni 		 * Only modify the Device ID if code type is Legacy or HP.
1051955088355SVishal Kulkarni 		 * 0x00: Okay to modify
1052055088355SVishal Kulkarni 		 * 0x01: FCODE. Do not modify
1052155088355SVishal Kulkarni 		 * 0x03: Okay to modify
1052255088355SVishal Kulkarni 		 * 0x04-0xFF: Do not modify
1052355088355SVishal Kulkarni 		 */
1052455088355SVishal Kulkarni 		if (pcir_header->code_type == CXGB4_HDR_CODE1) {
1052555088355SVishal Kulkarni 			u8 csum = 0;
1052655088355SVishal Kulkarni 			int i;
1052755088355SVishal Kulkarni 
1052855088355SVishal Kulkarni 			/**
1052955088355SVishal Kulkarni 			 * Modify Device ID to match current adatper
1053055088355SVishal Kulkarni 			 */
1053155088355SVishal Kulkarni 			pcir_header->device_id = cpu_to_le16(device_id);
1053255088355SVishal Kulkarni 
1053355088355SVishal Kulkarni 			/**
1053455088355SVishal Kulkarni 			 * Set checksum temporarily to 0.
1053555088355SVishal Kulkarni 			 * We will recalculate it later.
1053655088355SVishal Kulkarni 			 */
1053755088355SVishal Kulkarni 			header->cksum = 0x0;
1053855088355SVishal Kulkarni 
1053955088355SVishal Kulkarni 			/**
1054055088355SVishal Kulkarni 			 * Calculate and update checksum
1054155088355SVishal Kulkarni 			 */
1054255088355SVishal Kulkarni 			for (i = 0; i < (header->size512 * 512); i++)
1054355088355SVishal Kulkarni 				csum += cur_header[i];
1054455088355SVishal Kulkarni 
1054555088355SVishal Kulkarni 			/**
1054655088355SVishal Kulkarni 			 * Invert summed value to create the checksum
1054755088355SVishal Kulkarni 			 * Writing new checksum value directly to the boot data
1054855088355SVishal Kulkarni 			 */
1054955088355SVishal Kulkarni 			cur_header[7] = -csum;
1055055088355SVishal Kulkarni 
1055155088355SVishal Kulkarni 		} else if (pcir_header->code_type == CXGB4_HDR_CODE2) {
1055255088355SVishal Kulkarni 			/**
1055355088355SVishal Kulkarni 			 * Modify Device ID to match current adatper
1055455088355SVishal Kulkarni 			 */
1055555088355SVishal Kulkarni 			pcir_header->device_id = cpu_to_le16(device_id);
1055655088355SVishal Kulkarni 		}
1055755088355SVishal Kulkarni 
1055855088355SVishal Kulkarni 		/**
1055955088355SVishal Kulkarni 		 * Move header pointer up to the next image in the ROM.
1056055088355SVishal Kulkarni 		 */
1056155088355SVishal Kulkarni 		cur_header += header->size512 * 512;
1056255088355SVishal Kulkarni 	} while (!(pcir_header->indicator & CXGB4_HDR_INDI));
1056355088355SVishal Kulkarni }
1056455088355SVishal Kulkarni 
1056555088355SVishal Kulkarni /**
1056655088355SVishal Kulkarni  *	t4_load_boot - download boot flash
1056755088355SVishal Kulkarni  *	@adap: the adapter
1056855088355SVishal Kulkarni  *	@boot_data: the boot image to write
1056955088355SVishal Kulkarni  *	@boot_addr: offset in flash to write boot_data
1057055088355SVishal Kulkarni  *	@size: image size
1057155088355SVishal Kulkarni  *
1057255088355SVishal Kulkarni  *	Write the supplied boot image to the card's serial flash.
1057355088355SVishal Kulkarni  *	The boot image has the following sections: a 28-byte header and the
1057455088355SVishal Kulkarni  *	boot image.
1057555088355SVishal Kulkarni  */
t4_load_boot(struct adapter * adap,u8 * boot_data,unsigned int boot_addr,unsigned int size)1057655088355SVishal Kulkarni int t4_load_boot(struct adapter *adap, u8 *boot_data,
1057755088355SVishal Kulkarni 		 unsigned int boot_addr, unsigned int size)
1057855088355SVishal Kulkarni {
1057955088355SVishal Kulkarni 	unsigned int sf_sec_size = adap->params.sf_size / adap->params.sf_nsec;
1058055088355SVishal Kulkarni 	unsigned int boot_sector = (boot_addr * 1024);
1058155088355SVishal Kulkarni 	struct cxgb4_pci_exp_rom_header *header;
1058255088355SVishal Kulkarni 	struct cxgb4_pcir_data *pcir_header;
1058355088355SVishal Kulkarni 	int pcir_offset;
1058455088355SVishal Kulkarni 	unsigned int i;
1058555088355SVishal Kulkarni 	u16 device_id;
1058655088355SVishal Kulkarni 	int ret, addr;
1058755088355SVishal Kulkarni 
1058855088355SVishal Kulkarni 	/**
1058955088355SVishal Kulkarni 	 * Make sure the boot image does not encroach on the firmware region
1059055088355SVishal Kulkarni 	 */
1059155088355SVishal Kulkarni 	if ((boot_sector + size) >> 16 > FLASH_FW_START_SEC) {
1059255088355SVishal Kulkarni 		dev_err(adap->pdev_dev, "boot image encroaching on firmware region\n");
1059355088355SVishal Kulkarni 		return -EFBIG;
1059455088355SVishal Kulkarni 	}
1059555088355SVishal Kulkarni 
1059655088355SVishal Kulkarni 	/* Get boot header */
1059755088355SVishal Kulkarni 	header = (struct cxgb4_pci_exp_rom_header *)boot_data;
1059855088355SVishal Kulkarni 	pcir_offset = le16_to_cpu(header->pcir_offset);
1059955088355SVishal Kulkarni 	/* PCIR Data Structure */
1060055088355SVishal Kulkarni 	pcir_header = (struct cxgb4_pcir_data *)&boot_data[pcir_offset];
1060155088355SVishal Kulkarni 
1060255088355SVishal Kulkarni 	/**
1060355088355SVishal Kulkarni 	 * Perform some primitive sanity testing to avoid accidentally
1060455088355SVishal Kulkarni 	 * writing garbage over the boot sectors.  We ought to check for
1060555088355SVishal Kulkarni 	 * more but it's not worth it for now ...
1060655088355SVishal Kulkarni 	 */
1060755088355SVishal Kulkarni 	if (size < BOOT_MIN_SIZE || size > BOOT_MAX_SIZE) {
1060855088355SVishal Kulkarni 		dev_err(adap->pdev_dev, "boot image too small/large\n");
1060955088355SVishal Kulkarni 		return -EFBIG;
1061055088355SVishal Kulkarni 	}
1061155088355SVishal Kulkarni 
1061255088355SVishal Kulkarni 	if (le16_to_cpu(header->signature) != BOOT_SIGNATURE) {
1061355088355SVishal Kulkarni 		dev_err(adap->pdev_dev, "Boot image missing signature\n");
1061455088355SVishal Kulkarni 		return -EINVAL;
1061555088355SVishal Kulkarni 	}
1061655088355SVishal Kulkarni 
1061755088355SVishal Kulkarni 	/* Check PCI header signature */
1061855088355SVishal Kulkarni 	if (le32_to_cpu(pcir_header->signature) != PCIR_SIGNATURE) {
1061955088355SVishal Kulkarni 		dev_err(adap->pdev_dev, "PCI header missing signature\n");
1062055088355SVishal Kulkarni 		return -EINVAL;
1062155088355SVishal Kulkarni 	}
1062255088355SVishal Kulkarni 
1062355088355SVishal Kulkarni 	/* Check Vendor ID matches Chelsio ID*/
1062455088355SVishal Kulkarni 	if (le16_to_cpu(pcir_header->vendor_id) != PCI_VENDOR_ID_CHELSIO) {
1062555088355SVishal Kulkarni 		dev_err(adap->pdev_dev, "Vendor ID missing signature\n");
1062655088355SVishal Kulkarni 		return -EINVAL;
1062755088355SVishal Kulkarni 	}
1062855088355SVishal Kulkarni 
1062955088355SVishal Kulkarni 	/**
1063055088355SVishal Kulkarni 	 * The boot sector is comprised of the Expansion-ROM boot, iSCSI boot,
1063155088355SVishal Kulkarni 	 * and Boot configuration data sections. These 3 boot sections span
1063255088355SVishal Kulkarni 	 * sectors 0 to 7 in flash and live right before the FW image location.
1063355088355SVishal Kulkarni 	 */
1063455088355SVishal Kulkarni 	i = DIV_ROUND_UP(size ? size : FLASH_FW_START,  sf_sec_size);
1063555088355SVishal Kulkarni 	ret = t4_flash_erase_sectors(adap, boot_sector >> 16,
1063655088355SVishal Kulkarni 				     (boot_sector >> 16) + i - 1);
1063755088355SVishal Kulkarni 
1063855088355SVishal Kulkarni 	/**
1063955088355SVishal Kulkarni 	 * If size == 0 then we're simply erasing the FLASH sectors associated
1064055088355SVishal Kulkarni 	 * with the on-adapter option ROM file
1064155088355SVishal Kulkarni 	 */
1064255088355SVishal Kulkarni 	if (ret || size == 0)
1064355088355SVishal Kulkarni 		goto out;
1064455088355SVishal Kulkarni 	/* Retrieve adapter's device ID */
1064555088355SVishal Kulkarni 	pci_read_config_word(adap->pdev, PCI_DEVICE_ID, &device_id);
1064655088355SVishal Kulkarni        /* Want to deal with PF 0 so I strip off PF 4 indicator */
1064755088355SVishal Kulkarni 	device_id = device_id & 0xf0ff;
1064855088355SVishal Kulkarni 
1064955088355SVishal Kulkarni 	 /* Check PCIE Device ID */
1065055088355SVishal Kulkarni 	if (le16_to_cpu(pcir_header->device_id) != device_id) {
1065155088355SVishal Kulkarni 		/**
1065255088355SVishal Kulkarni 		 * Change the device ID in the Boot BIOS image to match
1065355088355SVishal Kulkarni 		 * the Device ID of the current adapter.
1065455088355SVishal Kulkarni 		 */
1065555088355SVishal Kulkarni 		modify_device_id(device_id, boot_data);
1065655088355SVishal Kulkarni 	}
1065755088355SVishal Kulkarni 
1065855088355SVishal Kulkarni 	/**
1065955088355SVishal Kulkarni 	 * Skip over the first SF_PAGE_SIZE worth of data and write it after
1066055088355SVishal Kulkarni 	 * we finish copying the rest of the boot image. This will ensure
1066155088355SVishal Kulkarni 	 * that the BIOS boot header will only be written if the boot image
1066255088355SVishal Kulkarni 	 * was written in full.
1066355088355SVishal Kulkarni 	 */
1066455088355SVishal Kulkarni 	addr = boot_sector;
1066555088355SVishal Kulkarni 	for (size -= SF_PAGE_SIZE; size; size -= SF_PAGE_SIZE) {
1066655088355SVishal Kulkarni 		addr += SF_PAGE_SIZE;
1066755088355SVishal Kulkarni 		boot_data += SF_PAGE_SIZE;
1066842a20397SRahul Lakkireddy 		ret = t4_write_flash(adap, addr, SF_PAGE_SIZE, boot_data,
1066942a20397SRahul Lakkireddy 				     false);
1067055088355SVishal Kulkarni 		if (ret)
1067155088355SVishal Kulkarni 			goto out;
1067255088355SVishal Kulkarni 	}
1067355088355SVishal Kulkarni 
1067455088355SVishal Kulkarni 	ret = t4_write_flash(adap, boot_sector, SF_PAGE_SIZE,
1067542a20397SRahul Lakkireddy 			     (const u8 *)header, false);
1067655088355SVishal Kulkarni 
1067755088355SVishal Kulkarni out:
1067855088355SVishal Kulkarni 	if (ret)
1067955088355SVishal Kulkarni 		dev_err(adap->pdev_dev, "boot image load failed, error %d\n",
1068055088355SVishal Kulkarni 			ret);
1068155088355SVishal Kulkarni 	return ret;
1068255088355SVishal Kulkarni }
10683d5002c9aSVishal Kulkarni 
10684d5002c9aSVishal Kulkarni /**
10685d5002c9aSVishal Kulkarni  *	t4_flash_bootcfg_addr - return the address of the flash
10686d5002c9aSVishal Kulkarni  *	optionrom configuration
10687d5002c9aSVishal Kulkarni  *	@adapter: the adapter
10688d5002c9aSVishal Kulkarni  *
10689d5002c9aSVishal Kulkarni  *	Return the address within the flash where the OptionROM Configuration
10690d5002c9aSVishal Kulkarni  *	is stored, or an error if the device FLASH is too small to contain
10691d5002c9aSVishal Kulkarni  *	a OptionROM Configuration.
10692d5002c9aSVishal Kulkarni  */
t4_flash_bootcfg_addr(struct adapter * adapter)10693d5002c9aSVishal Kulkarni static int t4_flash_bootcfg_addr(struct adapter *adapter)
10694d5002c9aSVishal Kulkarni {
10695d5002c9aSVishal Kulkarni 	/**
10696d5002c9aSVishal Kulkarni 	 * If the device FLASH isn't large enough to hold a Firmware
10697d5002c9aSVishal Kulkarni 	 * Configuration File, return an error.
10698d5002c9aSVishal Kulkarni 	 */
10699d5002c9aSVishal Kulkarni 	if (adapter->params.sf_size <
10700d5002c9aSVishal Kulkarni 	    FLASH_BOOTCFG_START + FLASH_BOOTCFG_MAX_SIZE)
10701d5002c9aSVishal Kulkarni 		return -ENOSPC;
10702d5002c9aSVishal Kulkarni 
10703d5002c9aSVishal Kulkarni 	return FLASH_BOOTCFG_START;
10704d5002c9aSVishal Kulkarni }
10705d5002c9aSVishal Kulkarni 
t4_load_bootcfg(struct adapter * adap,const u8 * cfg_data,unsigned int size)10706d5002c9aSVishal Kulkarni int t4_load_bootcfg(struct adapter *adap, const u8 *cfg_data, unsigned int size)
10707d5002c9aSVishal Kulkarni {
10708d5002c9aSVishal Kulkarni 	unsigned int sf_sec_size = adap->params.sf_size / adap->params.sf_nsec;
10709d5002c9aSVishal Kulkarni 	struct cxgb4_bootcfg_data *header;
10710d5002c9aSVishal Kulkarni 	unsigned int flash_cfg_start_sec;
10711d5002c9aSVishal Kulkarni 	unsigned int addr, npad;
10712d5002c9aSVishal Kulkarni 	int ret, i, n, cfg_addr;
10713d5002c9aSVishal Kulkarni 
10714d5002c9aSVishal Kulkarni 	cfg_addr = t4_flash_bootcfg_addr(adap);
10715d5002c9aSVishal Kulkarni 	if (cfg_addr < 0)
10716d5002c9aSVishal Kulkarni 		return cfg_addr;
10717d5002c9aSVishal Kulkarni 
10718d5002c9aSVishal Kulkarni 	addr = cfg_addr;
10719d5002c9aSVishal Kulkarni 	flash_cfg_start_sec = addr / SF_SEC_SIZE;
10720d5002c9aSVishal Kulkarni 
10721d5002c9aSVishal Kulkarni 	if (size > FLASH_BOOTCFG_MAX_SIZE) {
10722d5002c9aSVishal Kulkarni 		dev_err(adap->pdev_dev, "bootcfg file too large, max is %u bytes\n",
10723d5002c9aSVishal Kulkarni 			FLASH_BOOTCFG_MAX_SIZE);
10724d5002c9aSVishal Kulkarni 		return -EFBIG;
10725d5002c9aSVishal Kulkarni 	}
10726d5002c9aSVishal Kulkarni 
10727d5002c9aSVishal Kulkarni 	header = (struct cxgb4_bootcfg_data *)cfg_data;
10728d5002c9aSVishal Kulkarni 	if (le16_to_cpu(header->signature) != BOOT_CFG_SIG) {
10729d5002c9aSVishal Kulkarni 		dev_err(adap->pdev_dev, "Wrong bootcfg signature\n");
10730d5002c9aSVishal Kulkarni 		ret = -EINVAL;
10731d5002c9aSVishal Kulkarni 		goto out;
10732d5002c9aSVishal Kulkarni 	}
10733d5002c9aSVishal Kulkarni 
10734d5002c9aSVishal Kulkarni 	i = DIV_ROUND_UP(FLASH_BOOTCFG_MAX_SIZE,
10735d5002c9aSVishal Kulkarni 			 sf_sec_size);
10736d5002c9aSVishal Kulkarni 	ret = t4_flash_erase_sectors(adap, flash_cfg_start_sec,
10737d5002c9aSVishal Kulkarni 				     flash_cfg_start_sec + i - 1);
10738d5002c9aSVishal Kulkarni 
10739d5002c9aSVishal Kulkarni 	/**
10740d5002c9aSVishal Kulkarni 	 * If size == 0 then we're simply erasing the FLASH sectors associated
10741d5002c9aSVishal Kulkarni 	 * with the on-adapter OptionROM Configuration File.
10742d5002c9aSVishal Kulkarni 	 */
10743d5002c9aSVishal Kulkarni 	if (ret || size == 0)
10744d5002c9aSVishal Kulkarni 		goto out;
10745d5002c9aSVishal Kulkarni 
10746d5002c9aSVishal Kulkarni 	/* this will write to the flash up to SF_PAGE_SIZE at a time */
10747d5002c9aSVishal Kulkarni 	for (i = 0; i < size; i += SF_PAGE_SIZE) {
10748d5002c9aSVishal Kulkarni 		n = min_t(u32, size - i, SF_PAGE_SIZE);
10749d5002c9aSVishal Kulkarni 
1075042a20397SRahul Lakkireddy 		ret = t4_write_flash(adap, addr, n, cfg_data, false);
10751d5002c9aSVishal Kulkarni 		if (ret)
10752d5002c9aSVishal Kulkarni 			goto out;
10753d5002c9aSVishal Kulkarni 
10754d5002c9aSVishal Kulkarni 		addr += SF_PAGE_SIZE;
10755d5002c9aSVishal Kulkarni 		cfg_data += SF_PAGE_SIZE;
10756d5002c9aSVishal Kulkarni 	}
10757d5002c9aSVishal Kulkarni 
10758d5002c9aSVishal Kulkarni 	npad = ((size + 4 - 1) & ~3) - size;
10759d5002c9aSVishal Kulkarni 	for (i = 0; i < npad; i++) {
10760d5002c9aSVishal Kulkarni 		u8 data = 0;
10761d5002c9aSVishal Kulkarni 
1076242a20397SRahul Lakkireddy 		ret = t4_write_flash(adap, cfg_addr + size + i, 1, &data,
1076342a20397SRahul Lakkireddy 				     false);
10764d5002c9aSVishal Kulkarni 		if (ret)
10765d5002c9aSVishal Kulkarni 			goto out;
10766d5002c9aSVishal Kulkarni 	}
10767d5002c9aSVishal Kulkarni 
10768d5002c9aSVishal Kulkarni out:
10769d5002c9aSVishal Kulkarni 	if (ret)
10770d5002c9aSVishal Kulkarni 		dev_err(adap->pdev_dev, "boot config data %s failed %d\n",
10771d5002c9aSVishal Kulkarni 			(size == 0 ? "clear" : "download"), ret);
10772d5002c9aSVishal Kulkarni 	return ret;
10773d5002c9aSVishal Kulkarni }
10774