blob: c8e265c0b225e85510c4d5ad587751d177b9a49b [file] [log] [blame]
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001/*
2 * This file is part of the Chelsio T4 Ethernet driver for Linux.
3 *
Anish Bhattce100b8b2014-06-19 21:37:15 -07004 * Copyright (c) 2003-2014 Chelsio Communications, Inc. All rights reserved.
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00005 *
6 * This software is available to you under a choice of one of two
7 * licenses. You may choose to be licensed under the terms of the GNU
8 * General Public License (GPL) Version 2, available from the file
9 * COPYING in the main directory of this source tree, or the
10 * OpenIB.org BSD license below:
11 *
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
14 * conditions are met:
15 *
16 * - Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer.
19 *
20 * - Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials
23 * provided with the distribution.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 * SOFTWARE.
33 */
34
Dimitris Michailidis56d36be2010-04-01 15:28:23 +000035#include <linux/delay.h>
36#include "cxgb4.h"
37#include "t4_regs.h"
Hariprasad Shenaif612b812015-01-05 16:30:43 +053038#include "t4_values.h"
Dimitris Michailidis56d36be2010-04-01 15:28:23 +000039#include "t4fw_api.h"
40
41/**
42 * t4_wait_op_done_val - wait until an operation is completed
43 * @adapter: the adapter performing the operation
44 * @reg: the register to check for completion
45 * @mask: a single-bit field within @reg that indicates completion
46 * @polarity: the value of the field when the operation is completed
47 * @attempts: number of check iterations
48 * @delay: delay in usecs between iterations
49 * @valp: where to store the value of the register at completion time
50 *
51 * Wait until an operation is completed by checking a bit in a register
52 * up to @attempts times. If @valp is not NULL the value of the register
53 * at the time it indicated completion is stored there. Returns 0 if the
54 * operation completes and -EAGAIN otherwise.
55 */
Roland Dreierde498c82010-04-21 08:59:17 +000056static int t4_wait_op_done_val(struct adapter *adapter, int reg, u32 mask,
57 int polarity, int attempts, int delay, u32 *valp)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +000058{
59 while (1) {
60 u32 val = t4_read_reg(adapter, reg);
61
62 if (!!(val & mask) == polarity) {
63 if (valp)
64 *valp = val;
65 return 0;
66 }
67 if (--attempts == 0)
68 return -EAGAIN;
69 if (delay)
70 udelay(delay);
71 }
72}
73
74static inline int t4_wait_op_done(struct adapter *adapter, int reg, u32 mask,
75 int polarity, int attempts, int delay)
76{
77 return t4_wait_op_done_val(adapter, reg, mask, polarity, attempts,
78 delay, NULL);
79}
80
81/**
82 * t4_set_reg_field - set a register field to a value
83 * @adapter: the adapter to program
84 * @addr: the register address
85 * @mask: specifies the portion of the register to modify
86 * @val: the new value for the register field
87 *
88 * Sets a register field specified by the supplied mask to the
89 * given value.
90 */
91void t4_set_reg_field(struct adapter *adapter, unsigned int addr, u32 mask,
92 u32 val)
93{
94 u32 v = t4_read_reg(adapter, addr) & ~mask;
95
96 t4_write_reg(adapter, addr, v | val);
97 (void) t4_read_reg(adapter, addr); /* flush */
98}
99
100/**
101 * t4_read_indirect - read indirectly addressed registers
102 * @adap: the adapter
103 * @addr_reg: register holding the indirect address
104 * @data_reg: register holding the value of the indirect register
105 * @vals: where the read register values are stored
106 * @nregs: how many indirect registers to read
107 * @start_idx: index of first indirect register to read
108 *
109 * Reads registers that are accessed indirectly through an address/data
110 * register pair.
111 */
Vipul Pandyaf2b7e782012-12-10 09:30:52 +0000112void t4_read_indirect(struct adapter *adap, unsigned int addr_reg,
Roland Dreierde498c82010-04-21 08:59:17 +0000113 unsigned int data_reg, u32 *vals,
114 unsigned int nregs, unsigned int start_idx)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +0000115{
116 while (nregs--) {
117 t4_write_reg(adap, addr_reg, start_idx);
118 *vals++ = t4_read_reg(adap, data_reg);
119 start_idx++;
120 }
121}
122
Vipul Pandya13ee15d2012-09-26 02:39:40 +0000123/**
124 * t4_write_indirect - write indirectly addressed registers
125 * @adap: the adapter
126 * @addr_reg: register holding the indirect addresses
127 * @data_reg: register holding the value for the indirect registers
128 * @vals: values to write
129 * @nregs: how many indirect registers to write
130 * @start_idx: address of first indirect register to write
131 *
132 * Writes a sequential block of registers that are accessed indirectly
133 * through an address/data register pair.
134 */
135void t4_write_indirect(struct adapter *adap, unsigned int addr_reg,
136 unsigned int data_reg, const u32 *vals,
137 unsigned int nregs, unsigned int start_idx)
138{
139 while (nregs--) {
140 t4_write_reg(adap, addr_reg, start_idx++);
141 t4_write_reg(adap, data_reg, *vals++);
142 }
143}
144
Dimitris Michailidis56d36be2010-04-01 15:28:23 +0000145/*
Hariprasad Shenai0abfd152014-06-27 19:23:48 +0530146 * Read a 32-bit PCI Configuration Space register via the PCI-E backdoor
147 * mechanism. This guarantees that we get the real value even if we're
148 * operating within a Virtual Machine and the Hypervisor is trapping our
149 * Configuration Space accesses.
150 */
151void t4_hw_pci_read_cfg4(struct adapter *adap, int reg, u32 *val)
152{
Hariprasad Shenaif061de422015-01-05 16:30:44 +0530153 u32 req = ENABLE_F | FUNCTION_V(adap->fn) | REGISTER_V(reg);
Hariprasad Shenai0abfd152014-06-27 19:23:48 +0530154
155 if (is_t4(adap->params.chip))
Hariprasad Shenaif061de422015-01-05 16:30:44 +0530156 req |= LOCALCFG_F;
Hariprasad Shenai0abfd152014-06-27 19:23:48 +0530157
Hariprasad Shenaif061de422015-01-05 16:30:44 +0530158 t4_write_reg(adap, PCIE_CFG_SPACE_REQ_A, req);
159 *val = t4_read_reg(adap, PCIE_CFG_SPACE_DATA_A);
Hariprasad Shenai0abfd152014-06-27 19:23:48 +0530160
161 /* Reset ENABLE to 0 so reads of PCIE_CFG_SPACE_DATA won't cause a
162 * Configuration Space read. (None of the other fields matter when
163 * ENABLE is 0 so a simple register write is easier than a
164 * read-modify-write via t4_set_reg_field().)
165 */
Hariprasad Shenaif061de422015-01-05 16:30:44 +0530166 t4_write_reg(adap, PCIE_CFG_SPACE_REQ_A, 0);
Hariprasad Shenai0abfd152014-06-27 19:23:48 +0530167}
168
169/*
Hariprasad Shenai31d55c22014-09-01 19:54:58 +0530170 * t4_report_fw_error - report firmware error
171 * @adap: the adapter
172 *
173 * The adapter firmware can indicate error conditions to the host.
174 * If the firmware has indicated an error, print out the reason for
175 * the firmware error.
176 */
177static void t4_report_fw_error(struct adapter *adap)
178{
179 static const char *const reason[] = {
180 "Crash", /* PCIE_FW_EVAL_CRASH */
181 "During Device Preparation", /* PCIE_FW_EVAL_PREP */
182 "During Device Configuration", /* PCIE_FW_EVAL_CONF */
183 "During Device Initialization", /* PCIE_FW_EVAL_INIT */
184 "Unexpected Event", /* PCIE_FW_EVAL_UNEXPECTEDEVENT */
185 "Insufficient Airflow", /* PCIE_FW_EVAL_OVERHEAT */
186 "Device Shutdown", /* PCIE_FW_EVAL_DEVICESHUTDOWN */
187 "Reserved", /* reserved */
188 };
189 u32 pcie_fw;
190
Hariprasad Shenaif061de422015-01-05 16:30:44 +0530191 pcie_fw = t4_read_reg(adap, PCIE_FW_A);
192 if (pcie_fw & PCIE_FW_ERR_F)
Hariprasad Shenai31d55c22014-09-01 19:54:58 +0530193 dev_err(adap->pdev_dev, "Firmware reports adapter error: %s\n",
Hariprasad Shenaib2e1a3f2014-11-21 12:52:05 +0530194 reason[PCIE_FW_EVAL_G(pcie_fw)]);
Hariprasad Shenai31d55c22014-09-01 19:54:58 +0530195}
196
197/*
Dimitris Michailidis56d36be2010-04-01 15:28:23 +0000198 * Get the reply to a mailbox command and store it in @rpl in big-endian order.
199 */
200static void get_mbox_rpl(struct adapter *adap, __be64 *rpl, int nflit,
201 u32 mbox_addr)
202{
203 for ( ; nflit; nflit--, mbox_addr += 8)
204 *rpl++ = cpu_to_be64(t4_read_reg64(adap, mbox_addr));
205}
206
207/*
208 * Handle a FW assertion reported in a mailbox.
209 */
210static void fw_asrt(struct adapter *adap, u32 mbox_addr)
211{
212 struct fw_debug_cmd asrt;
213
214 get_mbox_rpl(adap, (__be64 *)&asrt, sizeof(asrt) / 8, mbox_addr);
215 dev_alert(adap->pdev_dev,
216 "FW assertion at %.16s:%u, val0 %#x, val1 %#x\n",
Hariprasad Shenaif404f802015-05-19 18:20:44 +0530217 asrt.u.assert.filename_0_7, be32_to_cpu(asrt.u.assert.line),
218 be32_to_cpu(asrt.u.assert.x), be32_to_cpu(asrt.u.assert.y));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +0000219}
220
221static void dump_mbox(struct adapter *adap, int mbox, u32 data_reg)
222{
223 dev_err(adap->pdev_dev,
224 "mbox %d: %llx %llx %llx %llx %llx %llx %llx %llx\n", mbox,
225 (unsigned long long)t4_read_reg64(adap, data_reg),
226 (unsigned long long)t4_read_reg64(adap, data_reg + 8),
227 (unsigned long long)t4_read_reg64(adap, data_reg + 16),
228 (unsigned long long)t4_read_reg64(adap, data_reg + 24),
229 (unsigned long long)t4_read_reg64(adap, data_reg + 32),
230 (unsigned long long)t4_read_reg64(adap, data_reg + 40),
231 (unsigned long long)t4_read_reg64(adap, data_reg + 48),
232 (unsigned long long)t4_read_reg64(adap, data_reg + 56));
233}
234
235/**
236 * t4_wr_mbox_meat - send a command to FW through the given mailbox
237 * @adap: the adapter
238 * @mbox: index of the mailbox to use
239 * @cmd: the command to write
240 * @size: command length in bytes
241 * @rpl: where to optionally store the reply
242 * @sleep_ok: if true we may sleep while awaiting command completion
243 *
244 * Sends the given command to FW through the selected mailbox and waits
245 * for the FW to execute the command. If @rpl is not %NULL it is used to
246 * store the FW's reply to the command. The command and its optional
247 * reply are of the same length. FW can take up to %FW_CMD_MAX_TIMEOUT ms
248 * to respond. @sleep_ok determines whether we may sleep while awaiting
249 * the response. If sleeping is allowed we use progressive backoff
250 * otherwise we spin.
251 *
252 * The return value is 0 on success or a negative errno on failure. A
253 * failure can happen either because we are not able to execute the
254 * command or FW executes it but signals an error. In the latter case
255 * the return value is the error code indicated by FW (negated).
256 */
257int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size,
258 void *rpl, bool sleep_ok)
259{
Joe Perches005b5712010-12-14 21:36:53 +0000260 static const int delay[] = {
Dimitris Michailidis56d36be2010-04-01 15:28:23 +0000261 1, 1, 3, 5, 10, 10, 20, 50, 100, 200
262 };
263
264 u32 v;
265 u64 res;
266 int i, ms, delay_idx;
267 const __be64 *p = cmd;
Hariprasad Shenai89c3a862015-01-05 16:30:45 +0530268 u32 data_reg = PF_REG(mbox, CIM_PF_MAILBOX_DATA_A);
269 u32 ctl_reg = PF_REG(mbox, CIM_PF_MAILBOX_CTRL_A);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +0000270
271 if ((size & 15) || size > MBOX_LEN)
272 return -EINVAL;
273
Dimitris Michailidis204dc3c2010-06-18 10:05:29 +0000274 /*
275 * If the device is off-line, as in EEH, commands will time out.
276 * Fail them early so we don't waste time waiting.
277 */
278 if (adap->pdev->error_state != pci_channel_io_normal)
279 return -EIO;
280
Hariprasad Shenai89c3a862015-01-05 16:30:45 +0530281 v = MBOWNER_G(t4_read_reg(adap, ctl_reg));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +0000282 for (i = 0; v == MBOX_OWNER_NONE && i < 3; i++)
Hariprasad Shenai89c3a862015-01-05 16:30:45 +0530283 v = MBOWNER_G(t4_read_reg(adap, ctl_reg));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +0000284
285 if (v != MBOX_OWNER_DRV)
286 return v ? -EBUSY : -ETIMEDOUT;
287
288 for (i = 0; i < size; i += 8)
289 t4_write_reg64(adap, data_reg + i, be64_to_cpu(*p++));
290
Hariprasad Shenai89c3a862015-01-05 16:30:45 +0530291 t4_write_reg(adap, ctl_reg, MBMSGVALID_F | MBOWNER_V(MBOX_OWNER_FW));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +0000292 t4_read_reg(adap, ctl_reg); /* flush write */
293
294 delay_idx = 0;
295 ms = delay[0];
296
297 for (i = 0; i < FW_CMD_MAX_TIMEOUT; i += ms) {
298 if (sleep_ok) {
299 ms = delay[delay_idx]; /* last element may repeat */
300 if (delay_idx < ARRAY_SIZE(delay) - 1)
301 delay_idx++;
302 msleep(ms);
303 } else
304 mdelay(ms);
305
306 v = t4_read_reg(adap, ctl_reg);
Hariprasad Shenai89c3a862015-01-05 16:30:45 +0530307 if (MBOWNER_G(v) == MBOX_OWNER_DRV) {
308 if (!(v & MBMSGVALID_F)) {
Dimitris Michailidis56d36be2010-04-01 15:28:23 +0000309 t4_write_reg(adap, ctl_reg, 0);
310 continue;
311 }
312
313 res = t4_read_reg64(adap, data_reg);
Hariprasad Shenaie2ac9622014-11-07 09:35:25 +0530314 if (FW_CMD_OP_G(res >> 32) == FW_DEBUG_CMD) {
Dimitris Michailidis56d36be2010-04-01 15:28:23 +0000315 fw_asrt(adap, data_reg);
Hariprasad Shenaie2ac9622014-11-07 09:35:25 +0530316 res = FW_CMD_RETVAL_V(EIO);
317 } else if (rpl) {
Dimitris Michailidis56d36be2010-04-01 15:28:23 +0000318 get_mbox_rpl(adap, rpl, size / 8, data_reg);
Hariprasad Shenaie2ac9622014-11-07 09:35:25 +0530319 }
Dimitris Michailidis56d36be2010-04-01 15:28:23 +0000320
Hariprasad Shenaie2ac9622014-11-07 09:35:25 +0530321 if (FW_CMD_RETVAL_G((int)res))
Dimitris Michailidis56d36be2010-04-01 15:28:23 +0000322 dump_mbox(adap, mbox, data_reg);
323 t4_write_reg(adap, ctl_reg, 0);
Hariprasad Shenaie2ac9622014-11-07 09:35:25 +0530324 return -FW_CMD_RETVAL_G((int)res);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +0000325 }
326 }
327
328 dump_mbox(adap, mbox, data_reg);
329 dev_err(adap->pdev_dev, "command %#x in mailbox %d timed out\n",
330 *(const u8 *)cmd, mbox);
Hariprasad Shenai31d55c22014-09-01 19:54:58 +0530331 t4_report_fw_error(adap);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +0000332 return -ETIMEDOUT;
333}
334
335/**
Vipul Pandya5afc8b82012-09-26 02:39:37 +0000336 * t4_memory_rw - read/write EDC 0, EDC 1 or MC via PCIE memory window
337 * @adap: the adapter
Hariprasad Shenaifc5ab022014-06-27 19:23:49 +0530338 * @win: PCI-E Memory Window to use
Vipul Pandya5afc8b82012-09-26 02:39:37 +0000339 * @mtype: memory type: MEM_EDC0, MEM_EDC1 or MEM_MC
340 * @addr: address within indicated memory type
341 * @len: amount of memory to transfer
Hariprasad Shenaif01aa632015-02-25 16:50:04 +0530342 * @hbuf: host memory buffer
Hariprasad Shenaifc5ab022014-06-27 19:23:49 +0530343 * @dir: direction of transfer T4_MEMORY_READ (1) or T4_MEMORY_WRITE (0)
Vipul Pandya5afc8b82012-09-26 02:39:37 +0000344 *
345 * Reads/writes an [almost] arbitrary memory region in the firmware: the
Hariprasad Shenaifc5ab022014-06-27 19:23:49 +0530346 * firmware memory address and host buffer must be aligned on 32-bit
347 * boudaries; the length may be arbitrary. The memory is transferred as
348 * a raw byte sequence from/to the firmware's memory. If this memory
349 * contains data structures which contain multi-byte integers, it's the
350 * caller's responsibility to perform appropriate byte order conversions.
Vipul Pandya5afc8b82012-09-26 02:39:37 +0000351 */
Hariprasad Shenaifc5ab022014-06-27 19:23:49 +0530352int t4_memory_rw(struct adapter *adap, int win, int mtype, u32 addr,
Hariprasad Shenaif01aa632015-02-25 16:50:04 +0530353 u32 len, void *hbuf, int dir)
Vipul Pandya5afc8b82012-09-26 02:39:37 +0000354{
Hariprasad Shenaifc5ab022014-06-27 19:23:49 +0530355 u32 pos, offset, resid, memoffset;
356 u32 edc_size, mc_size, win_pf, mem_reg, mem_aperture, mem_base;
Hariprasad Shenaif01aa632015-02-25 16:50:04 +0530357 u32 *buf;
Vipul Pandya5afc8b82012-09-26 02:39:37 +0000358
Hariprasad Shenaifc5ab022014-06-27 19:23:49 +0530359 /* Argument sanity checks ...
Vipul Pandya5afc8b82012-09-26 02:39:37 +0000360 */
Hariprasad Shenaif01aa632015-02-25 16:50:04 +0530361 if (addr & 0x3 || (uintptr_t)hbuf & 0x3)
Vipul Pandya5afc8b82012-09-26 02:39:37 +0000362 return -EINVAL;
Hariprasad Shenaif01aa632015-02-25 16:50:04 +0530363 buf = (u32 *)hbuf;
Vipul Pandya5afc8b82012-09-26 02:39:37 +0000364
Hariprasad Shenaifc5ab022014-06-27 19:23:49 +0530365 /* It's convenient to be able to handle lengths which aren't a
366 * multiple of 32-bits because we often end up transferring files to
367 * the firmware. So we'll handle that by normalizing the length here
368 * and then handling any residual transfer at the end.
369 */
370 resid = len & 0x3;
371 len -= resid;
Vipul Pandya8c357eb2012-10-03 03:22:32 +0000372
Santosh Rastapur19dd37b2013-03-14 05:08:53 +0000373 /* Offset into the region of memory which is being accessed
Vipul Pandya5afc8b82012-09-26 02:39:37 +0000374 * MEM_EDC0 = 0
375 * MEM_EDC1 = 1
Santosh Rastapur19dd37b2013-03-14 05:08:53 +0000376 * MEM_MC = 2 -- T4
377 * MEM_MC0 = 2 -- For T5
378 * MEM_MC1 = 3 -- For T5
Vipul Pandya5afc8b82012-09-26 02:39:37 +0000379 */
Hariprasad Shenai6559a7e2014-11-07 09:35:24 +0530380 edc_size = EDRAM0_SIZE_G(t4_read_reg(adap, MA_EDRAM0_BAR_A));
Santosh Rastapur19dd37b2013-03-14 05:08:53 +0000381 if (mtype != MEM_MC1)
382 memoffset = (mtype * (edc_size * 1024 * 1024));
383 else {
Hariprasad Shenai6559a7e2014-11-07 09:35:24 +0530384 mc_size = EXT_MEM0_SIZE_G(t4_read_reg(adap,
Hariprasad Shenai7f0b8a52015-04-29 17:19:05 +0530385 MA_EXT_MEMORY0_BAR_A));
Santosh Rastapur19dd37b2013-03-14 05:08:53 +0000386 memoffset = (MEM_MC0 * edc_size + mc_size) * 1024 * 1024;
387 }
Vipul Pandya5afc8b82012-09-26 02:39:37 +0000388
389 /* Determine the PCIE_MEM_ACCESS_OFFSET */
390 addr = addr + memoffset;
391
Hariprasad Shenaifc5ab022014-06-27 19:23:49 +0530392 /* Each PCI-E Memory Window is programmed with a window size -- or
393 * "aperture" -- which controls the granularity of its mapping onto
394 * adapter memory. We need to grab that aperture in order to know
395 * how to use the specified window. The window is also programmed
396 * with the base address of the Memory Window in BAR0's address
397 * space. For T4 this is an absolute PCI-E Bus Address. For T5
398 * the address is relative to BAR0.
Vipul Pandya5afc8b82012-09-26 02:39:37 +0000399 */
Hariprasad Shenaifc5ab022014-06-27 19:23:49 +0530400 mem_reg = t4_read_reg(adap,
Hariprasad Shenaif061de422015-01-05 16:30:44 +0530401 PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN_A,
Hariprasad Shenaifc5ab022014-06-27 19:23:49 +0530402 win));
Hariprasad Shenaif061de422015-01-05 16:30:44 +0530403 mem_aperture = 1 << (WINDOW_G(mem_reg) + WINDOW_SHIFT_X);
404 mem_base = PCIEOFST_G(mem_reg) << PCIEOFST_SHIFT_X;
Hariprasad Shenaifc5ab022014-06-27 19:23:49 +0530405 if (is_t4(adap->params.chip))
406 mem_base -= adap->t4_bar0;
Hariprasad Shenaif061de422015-01-05 16:30:44 +0530407 win_pf = is_t4(adap->params.chip) ? 0 : PFNUM_V(adap->fn);
Vipul Pandya5afc8b82012-09-26 02:39:37 +0000408
Hariprasad Shenaifc5ab022014-06-27 19:23:49 +0530409 /* Calculate our initial PCI-E Memory Window Position and Offset into
410 * that Window.
411 */
412 pos = addr & ~(mem_aperture-1);
413 offset = addr - pos;
Vipul Pandya5afc8b82012-09-26 02:39:37 +0000414
Hariprasad Shenaifc5ab022014-06-27 19:23:49 +0530415 /* Set up initial PCI-E Memory Window to cover the start of our
416 * transfer. (Read it back to ensure that changes propagate before we
417 * attempt to use the new value.)
418 */
419 t4_write_reg(adap,
Hariprasad Shenaif061de422015-01-05 16:30:44 +0530420 PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET_A, win),
Hariprasad Shenaifc5ab022014-06-27 19:23:49 +0530421 pos | win_pf);
422 t4_read_reg(adap,
Hariprasad Shenaif061de422015-01-05 16:30:44 +0530423 PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET_A, win));
Hariprasad Shenaifc5ab022014-06-27 19:23:49 +0530424
425 /* Transfer data to/from the adapter as long as there's an integral
426 * number of 32-bit transfers to complete.
Hariprasad Shenaif01aa632015-02-25 16:50:04 +0530427 *
428 * A note on Endianness issues:
429 *
430 * The "register" reads and writes below from/to the PCI-E Memory
431 * Window invoke the standard adapter Big-Endian to PCI-E Link
432 * Little-Endian "swizzel." As a result, if we have the following
433 * data in adapter memory:
434 *
435 * Memory: ... | b0 | b1 | b2 | b3 | ...
436 * Address: i+0 i+1 i+2 i+3
437 *
438 * Then a read of the adapter memory via the PCI-E Memory Window
439 * will yield:
440 *
441 * x = readl(i)
442 * 31 0
443 * [ b3 | b2 | b1 | b0 ]
444 *
445 * If this value is stored into local memory on a Little-Endian system
446 * it will show up correctly in local memory as:
447 *
448 * ( ..., b0, b1, b2, b3, ... )
449 *
450 * But on a Big-Endian system, the store will show up in memory
451 * incorrectly swizzled as:
452 *
453 * ( ..., b3, b2, b1, b0, ... )
454 *
455 * So we need to account for this in the reads and writes to the
456 * PCI-E Memory Window below by undoing the register read/write
457 * swizzels.
Hariprasad Shenaifc5ab022014-06-27 19:23:49 +0530458 */
459 while (len > 0) {
460 if (dir == T4_MEMORY_READ)
Hariprasad Shenaif01aa632015-02-25 16:50:04 +0530461 *buf++ = le32_to_cpu((__force __le32)t4_read_reg(adap,
462 mem_base + offset));
Hariprasad Shenaifc5ab022014-06-27 19:23:49 +0530463 else
464 t4_write_reg(adap, mem_base + offset,
Hariprasad Shenaif01aa632015-02-25 16:50:04 +0530465 (__force u32)cpu_to_le32(*buf++));
Hariprasad Shenaifc5ab022014-06-27 19:23:49 +0530466 offset += sizeof(__be32);
467 len -= sizeof(__be32);
468
469 /* If we've reached the end of our current window aperture,
470 * move the PCI-E Memory Window on to the next. Note that
471 * doing this here after "len" may be 0 allows us to set up
472 * the PCI-E Memory Window for a possible final residual
473 * transfer below ...
Vipul Pandya5afc8b82012-09-26 02:39:37 +0000474 */
Hariprasad Shenaifc5ab022014-06-27 19:23:49 +0530475 if (offset == mem_aperture) {
476 pos += mem_aperture;
477 offset = 0;
478 t4_write_reg(adap,
Hariprasad Shenaif061de422015-01-05 16:30:44 +0530479 PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET_A,
480 win), pos | win_pf);
Hariprasad Shenaifc5ab022014-06-27 19:23:49 +0530481 t4_read_reg(adap,
Hariprasad Shenaif061de422015-01-05 16:30:44 +0530482 PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_OFFSET_A,
483 win));
Vipul Pandya5afc8b82012-09-26 02:39:37 +0000484 }
Vipul Pandya5afc8b82012-09-26 02:39:37 +0000485 }
486
Hariprasad Shenaifc5ab022014-06-27 19:23:49 +0530487 /* If the original transfer had a length which wasn't a multiple of
488 * 32-bits, now's where we need to finish off the transfer of the
489 * residual amount. The PCI-E Memory Window has already been moved
490 * above (if necessary) to cover this final transfer.
491 */
492 if (resid) {
493 union {
Hariprasad Shenaif01aa632015-02-25 16:50:04 +0530494 u32 word;
Hariprasad Shenaifc5ab022014-06-27 19:23:49 +0530495 char byte[4];
496 } last;
497 unsigned char *bp;
498 int i;
Vipul Pandya5afc8b82012-09-26 02:39:37 +0000499
Hariprasad Shenaic81576c2014-07-24 17:16:30 +0530500 if (dir == T4_MEMORY_READ) {
Hariprasad Shenaif01aa632015-02-25 16:50:04 +0530501 last.word = le32_to_cpu(
502 (__force __le32)t4_read_reg(adap,
503 mem_base + offset));
Hariprasad Shenaifc5ab022014-06-27 19:23:49 +0530504 for (bp = (unsigned char *)buf, i = resid; i < 4; i++)
505 bp[i] = last.byte[i];
506 } else {
507 last.word = *buf;
508 for (i = resid; i < 4; i++)
509 last.byte[i] = 0;
510 t4_write_reg(adap, mem_base + offset,
Hariprasad Shenaif01aa632015-02-25 16:50:04 +0530511 (__force u32)cpu_to_le32(last.word));
Hariprasad Shenaifc5ab022014-06-27 19:23:49 +0530512 }
513 }
514
515 return 0;
Vipul Pandya5afc8b82012-09-26 02:39:37 +0000516}
517
Hariprasad Shenaib562fc32015-05-20 17:53:45 +0530518/* Return the specified PCI-E Configuration Space register from our Physical
519 * Function. We try first via a Firmware LDST Command since we prefer to let
520 * the firmware own all of these registers, but if that fails we go for it
521 * directly ourselves.
522 */
523u32 t4_read_pcie_cfg4(struct adapter *adap, int reg)
524{
525 u32 val, ldst_addrspace;
526
527 /* If fw_attach != 0, construct and send the Firmware LDST Command to
528 * retrieve the specified PCI-E Configuration Space register.
529 */
530 struct fw_ldst_cmd ldst_cmd;
531 int ret;
532
533 memset(&ldst_cmd, 0, sizeof(ldst_cmd));
534 ldst_addrspace = FW_LDST_CMD_ADDRSPACE_V(FW_LDST_ADDRSPC_FUNC_PCIE);
535 ldst_cmd.op_to_addrspace = cpu_to_be32(FW_CMD_OP_V(FW_LDST_CMD) |
536 FW_CMD_REQUEST_F |
537 FW_CMD_READ_F |
538 ldst_addrspace);
539 ldst_cmd.cycles_to_len16 = cpu_to_be32(FW_LEN16(ldst_cmd));
540 ldst_cmd.u.pcie.select_naccess = FW_LDST_CMD_NACCESS_V(1);
541 ldst_cmd.u.pcie.ctrl_to_fn =
542 (FW_LDST_CMD_LC_F | FW_LDST_CMD_FN_V(adap->fn));
543 ldst_cmd.u.pcie.r = reg;
544
545 /* If the LDST Command succeeds, return the result, otherwise
546 * fall through to reading it directly ourselves ...
547 */
548 ret = t4_wr_mbox(adap, adap->mbox, &ldst_cmd, sizeof(ldst_cmd),
549 &ldst_cmd);
550 if (ret == 0)
551 val = be32_to_cpu(ldst_cmd.u.pcie.data[0]);
552 else
553 /* Read the desired Configuration Space register via the PCI-E
554 * Backdoor mechanism.
555 */
556 t4_hw_pci_read_cfg4(adap, reg, &val);
557 return val;
558}
559
560/* Get the window based on base passed to it.
561 * Window aperture is currently unhandled, but there is no use case for it
562 * right now
563 */
564static u32 t4_get_window(struct adapter *adap, u32 pci_base, u64 pci_mask,
565 u32 memwin_base)
566{
567 u32 ret;
568
569 if (is_t4(adap->params.chip)) {
570 u32 bar0;
571
572 /* Truncation intentional: we only read the bottom 32-bits of
573 * the 64-bit BAR0/BAR1 ... We use the hardware backdoor
574 * mechanism to read BAR0 instead of using
575 * pci_resource_start() because we could be operating from
576 * within a Virtual Machine which is trapping our accesses to
577 * our Configuration Space and we need to set up the PCI-E
578 * Memory Window decoders with the actual addresses which will
579 * be coming across the PCI-E link.
580 */
581 bar0 = t4_read_pcie_cfg4(adap, pci_base);
582 bar0 &= pci_mask;
583 adap->t4_bar0 = bar0;
584
585 ret = bar0 + memwin_base;
586 } else {
587 /* For T5, only relative offset inside the PCIe BAR is passed */
588 ret = memwin_base;
589 }
590 return ret;
591}
592
593/* Get the default utility window (win0) used by everyone */
594u32 t4_get_util_window(struct adapter *adap)
595{
596 return t4_get_window(adap, PCI_BASE_ADDRESS_0,
597 PCI_BASE_ADDRESS_MEM_MASK, MEMWIN0_BASE);
598}
599
600/* Set up memory window for accessing adapter memory ranges. (Read
601 * back MA register to ensure that changes propagate before we attempt
602 * to use the new values.)
603 */
604void t4_setup_memwin(struct adapter *adap, u32 memwin_base, u32 window)
605{
606 t4_write_reg(adap,
607 PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN_A, window),
608 memwin_base | BIR_V(0) |
609 WINDOW_V(ilog2(MEMWIN0_APERTURE) - WINDOW_SHIFT_X));
610 t4_read_reg(adap,
611 PCIE_MEM_ACCESS_REG(PCIE_MEM_ACCESS_BASE_WIN_A, window));
612}
613
Hariprasad Shenai812034f2015-04-06 20:23:23 +0530614/**
615 * t4_get_regs_len - return the size of the chips register set
616 * @adapter: the adapter
617 *
618 * Returns the size of the chip's BAR0 register space.
619 */
620unsigned int t4_get_regs_len(struct adapter *adapter)
621{
622 unsigned int chip_version = CHELSIO_CHIP_VERSION(adapter->params.chip);
623
624 switch (chip_version) {
625 case CHELSIO_T4:
626 return T4_REGMAP_SIZE;
627
628 case CHELSIO_T5:
629 return T5_REGMAP_SIZE;
630 }
631
632 dev_err(adapter->pdev_dev,
633 "Unsupported chip version %d\n", chip_version);
634 return 0;
635}
636
637/**
638 * t4_get_regs - read chip registers into provided buffer
639 * @adap: the adapter
640 * @buf: register buffer
641 * @buf_size: size (in bytes) of register buffer
642 *
643 * If the provided register buffer isn't large enough for the chip's
644 * full register range, the register dump will be truncated to the
645 * register buffer's size.
646 */
647void t4_get_regs(struct adapter *adap, void *buf, size_t buf_size)
648{
649 static const unsigned int t4_reg_ranges[] = {
650 0x1008, 0x1108,
651 0x1180, 0x11b4,
652 0x11fc, 0x123c,
653 0x1300, 0x173c,
654 0x1800, 0x18fc,
655 0x3000, 0x30d8,
656 0x30e0, 0x5924,
657 0x5960, 0x59d4,
658 0x5a00, 0x5af8,
659 0x6000, 0x6098,
660 0x6100, 0x6150,
661 0x6200, 0x6208,
662 0x6240, 0x6248,
663 0x6280, 0x6338,
664 0x6370, 0x638c,
665 0x6400, 0x643c,
666 0x6500, 0x6524,
667 0x6a00, 0x6a38,
668 0x6a60, 0x6a78,
669 0x6b00, 0x6b84,
670 0x6bf0, 0x6c84,
671 0x6cf0, 0x6d84,
672 0x6df0, 0x6e84,
673 0x6ef0, 0x6f84,
674 0x6ff0, 0x7084,
675 0x70f0, 0x7184,
676 0x71f0, 0x7284,
677 0x72f0, 0x7384,
678 0x73f0, 0x7450,
679 0x7500, 0x7530,
680 0x7600, 0x761c,
681 0x7680, 0x76cc,
682 0x7700, 0x7798,
683 0x77c0, 0x77fc,
684 0x7900, 0x79fc,
685 0x7b00, 0x7c38,
686 0x7d00, 0x7efc,
687 0x8dc0, 0x8e1c,
688 0x8e30, 0x8e78,
689 0x8ea0, 0x8f6c,
690 0x8fc0, 0x9074,
691 0x90fc, 0x90fc,
692 0x9400, 0x9458,
693 0x9600, 0x96bc,
694 0x9800, 0x9808,
695 0x9820, 0x983c,
696 0x9850, 0x9864,
697 0x9c00, 0x9c6c,
698 0x9c80, 0x9cec,
699 0x9d00, 0x9d6c,
700 0x9d80, 0x9dec,
701 0x9e00, 0x9e6c,
702 0x9e80, 0x9eec,
703 0x9f00, 0x9f6c,
704 0x9f80, 0x9fec,
705 0xd004, 0xd03c,
706 0xdfc0, 0xdfe0,
707 0xe000, 0xea7c,
708 0xf000, 0x11110,
709 0x11118, 0x11190,
710 0x19040, 0x1906c,
711 0x19078, 0x19080,
712 0x1908c, 0x19124,
713 0x19150, 0x191b0,
714 0x191d0, 0x191e8,
715 0x19238, 0x1924c,
716 0x193f8, 0x19474,
717 0x19490, 0x194f8,
718 0x19800, 0x19f30,
719 0x1a000, 0x1a06c,
720 0x1a0b0, 0x1a120,
721 0x1a128, 0x1a138,
722 0x1a190, 0x1a1c4,
723 0x1a1fc, 0x1a1fc,
724 0x1e040, 0x1e04c,
725 0x1e284, 0x1e28c,
726 0x1e2c0, 0x1e2c0,
727 0x1e2e0, 0x1e2e0,
728 0x1e300, 0x1e384,
729 0x1e3c0, 0x1e3c8,
730 0x1e440, 0x1e44c,
731 0x1e684, 0x1e68c,
732 0x1e6c0, 0x1e6c0,
733 0x1e6e0, 0x1e6e0,
734 0x1e700, 0x1e784,
735 0x1e7c0, 0x1e7c8,
736 0x1e840, 0x1e84c,
737 0x1ea84, 0x1ea8c,
738 0x1eac0, 0x1eac0,
739 0x1eae0, 0x1eae0,
740 0x1eb00, 0x1eb84,
741 0x1ebc0, 0x1ebc8,
742 0x1ec40, 0x1ec4c,
743 0x1ee84, 0x1ee8c,
744 0x1eec0, 0x1eec0,
745 0x1eee0, 0x1eee0,
746 0x1ef00, 0x1ef84,
747 0x1efc0, 0x1efc8,
748 0x1f040, 0x1f04c,
749 0x1f284, 0x1f28c,
750 0x1f2c0, 0x1f2c0,
751 0x1f2e0, 0x1f2e0,
752 0x1f300, 0x1f384,
753 0x1f3c0, 0x1f3c8,
754 0x1f440, 0x1f44c,
755 0x1f684, 0x1f68c,
756 0x1f6c0, 0x1f6c0,
757 0x1f6e0, 0x1f6e0,
758 0x1f700, 0x1f784,
759 0x1f7c0, 0x1f7c8,
760 0x1f840, 0x1f84c,
761 0x1fa84, 0x1fa8c,
762 0x1fac0, 0x1fac0,
763 0x1fae0, 0x1fae0,
764 0x1fb00, 0x1fb84,
765 0x1fbc0, 0x1fbc8,
766 0x1fc40, 0x1fc4c,
767 0x1fe84, 0x1fe8c,
768 0x1fec0, 0x1fec0,
769 0x1fee0, 0x1fee0,
770 0x1ff00, 0x1ff84,
771 0x1ffc0, 0x1ffc8,
772 0x20000, 0x2002c,
773 0x20100, 0x2013c,
774 0x20190, 0x201c8,
775 0x20200, 0x20318,
776 0x20400, 0x20528,
777 0x20540, 0x20614,
778 0x21000, 0x21040,
779 0x2104c, 0x21060,
780 0x210c0, 0x210ec,
781 0x21200, 0x21268,
782 0x21270, 0x21284,
783 0x212fc, 0x21388,
784 0x21400, 0x21404,
785 0x21500, 0x21518,
786 0x2152c, 0x2153c,
787 0x21550, 0x21554,
788 0x21600, 0x21600,
789 0x21608, 0x21628,
790 0x21630, 0x2163c,
791 0x21700, 0x2171c,
792 0x21780, 0x2178c,
793 0x21800, 0x21c38,
794 0x21c80, 0x21d7c,
795 0x21e00, 0x21e04,
796 0x22000, 0x2202c,
797 0x22100, 0x2213c,
798 0x22190, 0x221c8,
799 0x22200, 0x22318,
800 0x22400, 0x22528,
801 0x22540, 0x22614,
802 0x23000, 0x23040,
803 0x2304c, 0x23060,
804 0x230c0, 0x230ec,
805 0x23200, 0x23268,
806 0x23270, 0x23284,
807 0x232fc, 0x23388,
808 0x23400, 0x23404,
809 0x23500, 0x23518,
810 0x2352c, 0x2353c,
811 0x23550, 0x23554,
812 0x23600, 0x23600,
813 0x23608, 0x23628,
814 0x23630, 0x2363c,
815 0x23700, 0x2371c,
816 0x23780, 0x2378c,
817 0x23800, 0x23c38,
818 0x23c80, 0x23d7c,
819 0x23e00, 0x23e04,
820 0x24000, 0x2402c,
821 0x24100, 0x2413c,
822 0x24190, 0x241c8,
823 0x24200, 0x24318,
824 0x24400, 0x24528,
825 0x24540, 0x24614,
826 0x25000, 0x25040,
827 0x2504c, 0x25060,
828 0x250c0, 0x250ec,
829 0x25200, 0x25268,
830 0x25270, 0x25284,
831 0x252fc, 0x25388,
832 0x25400, 0x25404,
833 0x25500, 0x25518,
834 0x2552c, 0x2553c,
835 0x25550, 0x25554,
836 0x25600, 0x25600,
837 0x25608, 0x25628,
838 0x25630, 0x2563c,
839 0x25700, 0x2571c,
840 0x25780, 0x2578c,
841 0x25800, 0x25c38,
842 0x25c80, 0x25d7c,
843 0x25e00, 0x25e04,
844 0x26000, 0x2602c,
845 0x26100, 0x2613c,
846 0x26190, 0x261c8,
847 0x26200, 0x26318,
848 0x26400, 0x26528,
849 0x26540, 0x26614,
850 0x27000, 0x27040,
851 0x2704c, 0x27060,
852 0x270c0, 0x270ec,
853 0x27200, 0x27268,
854 0x27270, 0x27284,
855 0x272fc, 0x27388,
856 0x27400, 0x27404,
857 0x27500, 0x27518,
858 0x2752c, 0x2753c,
859 0x27550, 0x27554,
860 0x27600, 0x27600,
861 0x27608, 0x27628,
862 0x27630, 0x2763c,
863 0x27700, 0x2771c,
864 0x27780, 0x2778c,
865 0x27800, 0x27c38,
866 0x27c80, 0x27d7c,
867 0x27e00, 0x27e04
868 };
869
870 static const unsigned int t5_reg_ranges[] = {
871 0x1008, 0x1148,
872 0x1180, 0x11b4,
873 0x11fc, 0x123c,
874 0x1280, 0x173c,
875 0x1800, 0x18fc,
876 0x3000, 0x3028,
877 0x3060, 0x30d8,
878 0x30e0, 0x30fc,
879 0x3140, 0x357c,
880 0x35a8, 0x35cc,
881 0x35ec, 0x35ec,
882 0x3600, 0x5624,
883 0x56cc, 0x575c,
884 0x580c, 0x5814,
885 0x5890, 0x58bc,
886 0x5940, 0x59dc,
887 0x59fc, 0x5a18,
888 0x5a60, 0x5a9c,
889 0x5b9c, 0x5bfc,
890 0x6000, 0x6040,
891 0x6058, 0x614c,
892 0x7700, 0x7798,
893 0x77c0, 0x78fc,
894 0x7b00, 0x7c54,
895 0x7d00, 0x7efc,
896 0x8dc0, 0x8de0,
897 0x8df8, 0x8e84,
898 0x8ea0, 0x8f84,
899 0x8fc0, 0x90f8,
900 0x9400, 0x9470,
901 0x9600, 0x96f4,
902 0x9800, 0x9808,
903 0x9820, 0x983c,
904 0x9850, 0x9864,
905 0x9c00, 0x9c6c,
906 0x9c80, 0x9cec,
907 0x9d00, 0x9d6c,
908 0x9d80, 0x9dec,
909 0x9e00, 0x9e6c,
910 0x9e80, 0x9eec,
911 0x9f00, 0x9f6c,
912 0x9f80, 0xa020,
913 0xd004, 0xd03c,
914 0xdfc0, 0xdfe0,
915 0xe000, 0x11088,
916 0x1109c, 0x11110,
917 0x11118, 0x1117c,
918 0x11190, 0x11204,
919 0x19040, 0x1906c,
920 0x19078, 0x19080,
921 0x1908c, 0x19124,
922 0x19150, 0x191b0,
923 0x191d0, 0x191e8,
924 0x19238, 0x19290,
925 0x193f8, 0x19474,
926 0x19490, 0x194cc,
927 0x194f0, 0x194f8,
928 0x19c00, 0x19c60,
929 0x19c94, 0x19e10,
930 0x19e50, 0x19f34,
931 0x19f40, 0x19f50,
932 0x19f90, 0x19fe4,
933 0x1a000, 0x1a06c,
934 0x1a0b0, 0x1a120,
935 0x1a128, 0x1a138,
936 0x1a190, 0x1a1c4,
937 0x1a1fc, 0x1a1fc,
938 0x1e008, 0x1e00c,
939 0x1e040, 0x1e04c,
940 0x1e284, 0x1e290,
941 0x1e2c0, 0x1e2c0,
942 0x1e2e0, 0x1e2e0,
943 0x1e300, 0x1e384,
944 0x1e3c0, 0x1e3c8,
945 0x1e408, 0x1e40c,
946 0x1e440, 0x1e44c,
947 0x1e684, 0x1e690,
948 0x1e6c0, 0x1e6c0,
949 0x1e6e0, 0x1e6e0,
950 0x1e700, 0x1e784,
951 0x1e7c0, 0x1e7c8,
952 0x1e808, 0x1e80c,
953 0x1e840, 0x1e84c,
954 0x1ea84, 0x1ea90,
955 0x1eac0, 0x1eac0,
956 0x1eae0, 0x1eae0,
957 0x1eb00, 0x1eb84,
958 0x1ebc0, 0x1ebc8,
959 0x1ec08, 0x1ec0c,
960 0x1ec40, 0x1ec4c,
961 0x1ee84, 0x1ee90,
962 0x1eec0, 0x1eec0,
963 0x1eee0, 0x1eee0,
964 0x1ef00, 0x1ef84,
965 0x1efc0, 0x1efc8,
966 0x1f008, 0x1f00c,
967 0x1f040, 0x1f04c,
968 0x1f284, 0x1f290,
969 0x1f2c0, 0x1f2c0,
970 0x1f2e0, 0x1f2e0,
971 0x1f300, 0x1f384,
972 0x1f3c0, 0x1f3c8,
973 0x1f408, 0x1f40c,
974 0x1f440, 0x1f44c,
975 0x1f684, 0x1f690,
976 0x1f6c0, 0x1f6c0,
977 0x1f6e0, 0x1f6e0,
978 0x1f700, 0x1f784,
979 0x1f7c0, 0x1f7c8,
980 0x1f808, 0x1f80c,
981 0x1f840, 0x1f84c,
982 0x1fa84, 0x1fa90,
983 0x1fac0, 0x1fac0,
984 0x1fae0, 0x1fae0,
985 0x1fb00, 0x1fb84,
986 0x1fbc0, 0x1fbc8,
987 0x1fc08, 0x1fc0c,
988 0x1fc40, 0x1fc4c,
989 0x1fe84, 0x1fe90,
990 0x1fec0, 0x1fec0,
991 0x1fee0, 0x1fee0,
992 0x1ff00, 0x1ff84,
993 0x1ffc0, 0x1ffc8,
994 0x30000, 0x30030,
995 0x30100, 0x30144,
996 0x30190, 0x301d0,
997 0x30200, 0x30318,
998 0x30400, 0x3052c,
999 0x30540, 0x3061c,
1000 0x30800, 0x30834,
1001 0x308c0, 0x30908,
1002 0x30910, 0x309ac,
1003 0x30a00, 0x30a04,
1004 0x30a0c, 0x30a2c,
1005 0x30a44, 0x30a50,
1006 0x30a74, 0x30c24,
1007 0x30d08, 0x30d14,
1008 0x30d1c, 0x30d20,
1009 0x30d3c, 0x30d50,
1010 0x31200, 0x3120c,
1011 0x31220, 0x31220,
1012 0x31240, 0x31240,
1013 0x31600, 0x31600,
1014 0x31608, 0x3160c,
1015 0x31a00, 0x31a1c,
1016 0x31e04, 0x31e20,
1017 0x31e38, 0x31e3c,
1018 0x31e80, 0x31e80,
1019 0x31e88, 0x31ea8,
1020 0x31eb0, 0x31eb4,
1021 0x31ec8, 0x31ed4,
1022 0x31fb8, 0x32004,
1023 0x32208, 0x3223c,
1024 0x32600, 0x32630,
1025 0x32a00, 0x32abc,
1026 0x32b00, 0x32b70,
1027 0x33000, 0x33048,
1028 0x33060, 0x3309c,
1029 0x330f0, 0x33148,
1030 0x33160, 0x3319c,
1031 0x331f0, 0x332e4,
1032 0x332f8, 0x333e4,
1033 0x333f8, 0x33448,
1034 0x33460, 0x3349c,
1035 0x334f0, 0x33548,
1036 0x33560, 0x3359c,
1037 0x335f0, 0x336e4,
1038 0x336f8, 0x337e4,
1039 0x337f8, 0x337fc,
1040 0x33814, 0x33814,
1041 0x3382c, 0x3382c,
1042 0x33880, 0x3388c,
1043 0x338e8, 0x338ec,
1044 0x33900, 0x33948,
1045 0x33960, 0x3399c,
1046 0x339f0, 0x33ae4,
1047 0x33af8, 0x33b10,
1048 0x33b28, 0x33b28,
1049 0x33b3c, 0x33b50,
1050 0x33bf0, 0x33c10,
1051 0x33c28, 0x33c28,
1052 0x33c3c, 0x33c50,
1053 0x33cf0, 0x33cfc,
1054 0x34000, 0x34030,
1055 0x34100, 0x34144,
1056 0x34190, 0x341d0,
1057 0x34200, 0x34318,
1058 0x34400, 0x3452c,
1059 0x34540, 0x3461c,
1060 0x34800, 0x34834,
1061 0x348c0, 0x34908,
1062 0x34910, 0x349ac,
1063 0x34a00, 0x34a04,
1064 0x34a0c, 0x34a2c,
1065 0x34a44, 0x34a50,
1066 0x34a74, 0x34c24,
1067 0x34d08, 0x34d14,
1068 0x34d1c, 0x34d20,
1069 0x34d3c, 0x34d50,
1070 0x35200, 0x3520c,
1071 0x35220, 0x35220,
1072 0x35240, 0x35240,
1073 0x35600, 0x35600,
1074 0x35608, 0x3560c,
1075 0x35a00, 0x35a1c,
1076 0x35e04, 0x35e20,
1077 0x35e38, 0x35e3c,
1078 0x35e80, 0x35e80,
1079 0x35e88, 0x35ea8,
1080 0x35eb0, 0x35eb4,
1081 0x35ec8, 0x35ed4,
1082 0x35fb8, 0x36004,
1083 0x36208, 0x3623c,
1084 0x36600, 0x36630,
1085 0x36a00, 0x36abc,
1086 0x36b00, 0x36b70,
1087 0x37000, 0x37048,
1088 0x37060, 0x3709c,
1089 0x370f0, 0x37148,
1090 0x37160, 0x3719c,
1091 0x371f0, 0x372e4,
1092 0x372f8, 0x373e4,
1093 0x373f8, 0x37448,
1094 0x37460, 0x3749c,
1095 0x374f0, 0x37548,
1096 0x37560, 0x3759c,
1097 0x375f0, 0x376e4,
1098 0x376f8, 0x377e4,
1099 0x377f8, 0x377fc,
1100 0x37814, 0x37814,
1101 0x3782c, 0x3782c,
1102 0x37880, 0x3788c,
1103 0x378e8, 0x378ec,
1104 0x37900, 0x37948,
1105 0x37960, 0x3799c,
1106 0x379f0, 0x37ae4,
1107 0x37af8, 0x37b10,
1108 0x37b28, 0x37b28,
1109 0x37b3c, 0x37b50,
1110 0x37bf0, 0x37c10,
1111 0x37c28, 0x37c28,
1112 0x37c3c, 0x37c50,
1113 0x37cf0, 0x37cfc,
1114 0x38000, 0x38030,
1115 0x38100, 0x38144,
1116 0x38190, 0x381d0,
1117 0x38200, 0x38318,
1118 0x38400, 0x3852c,
1119 0x38540, 0x3861c,
1120 0x38800, 0x38834,
1121 0x388c0, 0x38908,
1122 0x38910, 0x389ac,
1123 0x38a00, 0x38a04,
1124 0x38a0c, 0x38a2c,
1125 0x38a44, 0x38a50,
1126 0x38a74, 0x38c24,
1127 0x38d08, 0x38d14,
1128 0x38d1c, 0x38d20,
1129 0x38d3c, 0x38d50,
1130 0x39200, 0x3920c,
1131 0x39220, 0x39220,
1132 0x39240, 0x39240,
1133 0x39600, 0x39600,
1134 0x39608, 0x3960c,
1135 0x39a00, 0x39a1c,
1136 0x39e04, 0x39e20,
1137 0x39e38, 0x39e3c,
1138 0x39e80, 0x39e80,
1139 0x39e88, 0x39ea8,
1140 0x39eb0, 0x39eb4,
1141 0x39ec8, 0x39ed4,
1142 0x39fb8, 0x3a004,
1143 0x3a208, 0x3a23c,
1144 0x3a600, 0x3a630,
1145 0x3aa00, 0x3aabc,
1146 0x3ab00, 0x3ab70,
1147 0x3b000, 0x3b048,
1148 0x3b060, 0x3b09c,
1149 0x3b0f0, 0x3b148,
1150 0x3b160, 0x3b19c,
1151 0x3b1f0, 0x3b2e4,
1152 0x3b2f8, 0x3b3e4,
1153 0x3b3f8, 0x3b448,
1154 0x3b460, 0x3b49c,
1155 0x3b4f0, 0x3b548,
1156 0x3b560, 0x3b59c,
1157 0x3b5f0, 0x3b6e4,
1158 0x3b6f8, 0x3b7e4,
1159 0x3b7f8, 0x3b7fc,
1160 0x3b814, 0x3b814,
1161 0x3b82c, 0x3b82c,
1162 0x3b880, 0x3b88c,
1163 0x3b8e8, 0x3b8ec,
1164 0x3b900, 0x3b948,
1165 0x3b960, 0x3b99c,
1166 0x3b9f0, 0x3bae4,
1167 0x3baf8, 0x3bb10,
1168 0x3bb28, 0x3bb28,
1169 0x3bb3c, 0x3bb50,
1170 0x3bbf0, 0x3bc10,
1171 0x3bc28, 0x3bc28,
1172 0x3bc3c, 0x3bc50,
1173 0x3bcf0, 0x3bcfc,
1174 0x3c000, 0x3c030,
1175 0x3c100, 0x3c144,
1176 0x3c190, 0x3c1d0,
1177 0x3c200, 0x3c318,
1178 0x3c400, 0x3c52c,
1179 0x3c540, 0x3c61c,
1180 0x3c800, 0x3c834,
1181 0x3c8c0, 0x3c908,
1182 0x3c910, 0x3c9ac,
1183 0x3ca00, 0x3ca04,
1184 0x3ca0c, 0x3ca2c,
1185 0x3ca44, 0x3ca50,
1186 0x3ca74, 0x3cc24,
1187 0x3cd08, 0x3cd14,
1188 0x3cd1c, 0x3cd20,
1189 0x3cd3c, 0x3cd50,
1190 0x3d200, 0x3d20c,
1191 0x3d220, 0x3d220,
1192 0x3d240, 0x3d240,
1193 0x3d600, 0x3d600,
1194 0x3d608, 0x3d60c,
1195 0x3da00, 0x3da1c,
1196 0x3de04, 0x3de20,
1197 0x3de38, 0x3de3c,
1198 0x3de80, 0x3de80,
1199 0x3de88, 0x3dea8,
1200 0x3deb0, 0x3deb4,
1201 0x3dec8, 0x3ded4,
1202 0x3dfb8, 0x3e004,
1203 0x3e208, 0x3e23c,
1204 0x3e600, 0x3e630,
1205 0x3ea00, 0x3eabc,
1206 0x3eb00, 0x3eb70,
1207 0x3f000, 0x3f048,
1208 0x3f060, 0x3f09c,
1209 0x3f0f0, 0x3f148,
1210 0x3f160, 0x3f19c,
1211 0x3f1f0, 0x3f2e4,
1212 0x3f2f8, 0x3f3e4,
1213 0x3f3f8, 0x3f448,
1214 0x3f460, 0x3f49c,
1215 0x3f4f0, 0x3f548,
1216 0x3f560, 0x3f59c,
1217 0x3f5f0, 0x3f6e4,
1218 0x3f6f8, 0x3f7e4,
1219 0x3f7f8, 0x3f7fc,
1220 0x3f814, 0x3f814,
1221 0x3f82c, 0x3f82c,
1222 0x3f880, 0x3f88c,
1223 0x3f8e8, 0x3f8ec,
1224 0x3f900, 0x3f948,
1225 0x3f960, 0x3f99c,
1226 0x3f9f0, 0x3fae4,
1227 0x3faf8, 0x3fb10,
1228 0x3fb28, 0x3fb28,
1229 0x3fb3c, 0x3fb50,
1230 0x3fbf0, 0x3fc10,
1231 0x3fc28, 0x3fc28,
1232 0x3fc3c, 0x3fc50,
1233 0x3fcf0, 0x3fcfc,
1234 0x40000, 0x4000c,
1235 0x40040, 0x40068,
1236 0x40080, 0x40144,
1237 0x40180, 0x4018c,
1238 0x40200, 0x40298,
1239 0x402ac, 0x4033c,
1240 0x403f8, 0x403fc,
1241 0x41304, 0x413c4,
1242 0x41400, 0x4141c,
1243 0x41480, 0x414d0,
1244 0x44000, 0x44078,
1245 0x440c0, 0x44278,
1246 0x442c0, 0x44478,
1247 0x444c0, 0x44678,
1248 0x446c0, 0x44878,
1249 0x448c0, 0x449fc,
1250 0x45000, 0x45068,
1251 0x45080, 0x45084,
1252 0x450a0, 0x450b0,
1253 0x45200, 0x45268,
1254 0x45280, 0x45284,
1255 0x452a0, 0x452b0,
1256 0x460c0, 0x460e4,
1257 0x47000, 0x4708c,
1258 0x47200, 0x47250,
1259 0x47400, 0x47420,
1260 0x47600, 0x47618,
1261 0x47800, 0x47814,
1262 0x48000, 0x4800c,
1263 0x48040, 0x48068,
1264 0x48080, 0x48144,
1265 0x48180, 0x4818c,
1266 0x48200, 0x48298,
1267 0x482ac, 0x4833c,
1268 0x483f8, 0x483fc,
1269 0x49304, 0x493c4,
1270 0x49400, 0x4941c,
1271 0x49480, 0x494d0,
1272 0x4c000, 0x4c078,
1273 0x4c0c0, 0x4c278,
1274 0x4c2c0, 0x4c478,
1275 0x4c4c0, 0x4c678,
1276 0x4c6c0, 0x4c878,
1277 0x4c8c0, 0x4c9fc,
1278 0x4d000, 0x4d068,
1279 0x4d080, 0x4d084,
1280 0x4d0a0, 0x4d0b0,
1281 0x4d200, 0x4d268,
1282 0x4d280, 0x4d284,
1283 0x4d2a0, 0x4d2b0,
1284 0x4e0c0, 0x4e0e4,
1285 0x4f000, 0x4f08c,
1286 0x4f200, 0x4f250,
1287 0x4f400, 0x4f420,
1288 0x4f600, 0x4f618,
1289 0x4f800, 0x4f814,
1290 0x50000, 0x500cc,
1291 0x50400, 0x50400,
1292 0x50800, 0x508cc,
1293 0x50c00, 0x50c00,
1294 0x51000, 0x5101c,
1295 0x51300, 0x51308,
1296 };
1297
1298 u32 *buf_end = (u32 *)((char *)buf + buf_size);
1299 const unsigned int *reg_ranges;
1300 int reg_ranges_size, range;
1301 unsigned int chip_version = CHELSIO_CHIP_VERSION(adap->params.chip);
1302
1303 /* Select the right set of register ranges to dump depending on the
1304 * adapter chip type.
1305 */
1306 switch (chip_version) {
1307 case CHELSIO_T4:
1308 reg_ranges = t4_reg_ranges;
1309 reg_ranges_size = ARRAY_SIZE(t4_reg_ranges);
1310 break;
1311
1312 case CHELSIO_T5:
1313 reg_ranges = t5_reg_ranges;
1314 reg_ranges_size = ARRAY_SIZE(t5_reg_ranges);
1315 break;
1316
1317 default:
1318 dev_err(adap->pdev_dev,
1319 "Unsupported chip version %d\n", chip_version);
1320 return;
1321 }
1322
1323 /* Clear the register buffer and insert the appropriate register
1324 * values selected by the above register ranges.
1325 */
1326 memset(buf, 0, buf_size);
1327 for (range = 0; range < reg_ranges_size; range += 2) {
1328 unsigned int reg = reg_ranges[range];
1329 unsigned int last_reg = reg_ranges[range + 1];
1330 u32 *bufp = (u32 *)((char *)buf + reg);
1331
1332 /* Iterate across the register range filling in the register
1333 * buffer but don't write past the end of the register buffer.
1334 */
1335 while (reg <= last_reg && bufp < buf_end) {
1336 *bufp++ = t4_read_reg(adap, reg);
1337 reg += sizeof(u32);
1338 }
1339 }
1340}
1341
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001342#define EEPROM_STAT_ADDR 0x7bfc
Santosh Rastapur47ce9c42013-03-08 03:35:29 +00001343#define VPD_BASE 0x400
1344#define VPD_BASE_OLD 0
Santosh Rastapur0a57a532013-03-14 05:08:49 +00001345#define VPD_LEN 1024
Hariprasad Shenai63a92fe2014-09-01 19:54:56 +05301346#define CHELSIO_VPD_UNIQUE_ID 0x82
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001347
1348/**
1349 * t4_seeprom_wp - enable/disable EEPROM write protection
1350 * @adapter: the adapter
1351 * @enable: whether to enable or disable write protection
1352 *
1353 * Enables or disables write protection on the serial EEPROM.
1354 */
1355int t4_seeprom_wp(struct adapter *adapter, bool enable)
1356{
1357 unsigned int v = enable ? 0xc : 0;
1358 int ret = pci_write_vpd(adapter->pdev, EEPROM_STAT_ADDR, 4, &v);
1359 return ret < 0 ? ret : 0;
1360}
1361
1362/**
1363 * get_vpd_params - read VPD parameters from VPD EEPROM
1364 * @adapter: adapter to read
1365 * @p: where to store the parameters
1366 *
1367 * Reads card parameters stored in VPD EEPROM.
1368 */
Vipul Pandya636f9d32012-09-26 02:39:39 +00001369int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001370{
Vipul Pandya636f9d32012-09-26 02:39:39 +00001371 u32 cclk_param, cclk_val;
Santosh Rastapur47ce9c42013-03-08 03:35:29 +00001372 int i, ret, addr;
Kumar Sanghvia94cd702014-02-18 17:56:09 +05301373 int ec, sn, pn;
Vipul Pandya8c357eb2012-10-03 03:22:32 +00001374 u8 *vpd, csum;
Dimitris Michailidis23d88e12010-12-14 21:36:54 +00001375 unsigned int vpdr_len, kw_offset, id_len;
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001376
Vipul Pandya8c357eb2012-10-03 03:22:32 +00001377 vpd = vmalloc(VPD_LEN);
1378 if (!vpd)
1379 return -ENOMEM;
1380
Santosh Rastapur47ce9c42013-03-08 03:35:29 +00001381 ret = pci_read_vpd(adapter->pdev, VPD_BASE, sizeof(u32), vpd);
1382 if (ret < 0)
1383 goto out;
Hariprasad Shenai63a92fe2014-09-01 19:54:56 +05301384
1385 /* The VPD shall have a unique identifier specified by the PCI SIG.
1386 * For chelsio adapters, the identifier is 0x82. The first byte of a VPD
1387 * shall be CHELSIO_VPD_UNIQUE_ID (0x82). The VPD programming software
1388 * is expected to automatically put this entry at the
1389 * beginning of the VPD.
1390 */
1391 addr = *vpd == CHELSIO_VPD_UNIQUE_ID ? VPD_BASE : VPD_BASE_OLD;
Santosh Rastapur47ce9c42013-03-08 03:35:29 +00001392
1393 ret = pci_read_vpd(adapter->pdev, addr, VPD_LEN, vpd);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001394 if (ret < 0)
Vipul Pandya8c357eb2012-10-03 03:22:32 +00001395 goto out;
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001396
Dimitris Michailidis23d88e12010-12-14 21:36:54 +00001397 if (vpd[0] != PCI_VPD_LRDT_ID_STRING) {
1398 dev_err(adapter->pdev_dev, "missing VPD ID string\n");
Vipul Pandya8c357eb2012-10-03 03:22:32 +00001399 ret = -EINVAL;
1400 goto out;
Dimitris Michailidis23d88e12010-12-14 21:36:54 +00001401 }
1402
1403 id_len = pci_vpd_lrdt_size(vpd);
1404 if (id_len > ID_LEN)
1405 id_len = ID_LEN;
1406
1407 i = pci_vpd_find_tag(vpd, 0, VPD_LEN, PCI_VPD_LRDT_RO_DATA);
1408 if (i < 0) {
1409 dev_err(adapter->pdev_dev, "missing VPD-R section\n");
Vipul Pandya8c357eb2012-10-03 03:22:32 +00001410 ret = -EINVAL;
1411 goto out;
Dimitris Michailidis23d88e12010-12-14 21:36:54 +00001412 }
1413
1414 vpdr_len = pci_vpd_lrdt_size(&vpd[i]);
1415 kw_offset = i + PCI_VPD_LRDT_TAG_SIZE;
1416 if (vpdr_len + kw_offset > VPD_LEN) {
Dimitris Michailidis226ec5f2010-04-27 12:24:15 +00001417 dev_err(adapter->pdev_dev, "bad VPD-R length %u\n", vpdr_len);
Vipul Pandya8c357eb2012-10-03 03:22:32 +00001418 ret = -EINVAL;
1419 goto out;
Dimitris Michailidis226ec5f2010-04-27 12:24:15 +00001420 }
1421
1422#define FIND_VPD_KW(var, name) do { \
Dimitris Michailidis23d88e12010-12-14 21:36:54 +00001423 var = pci_vpd_find_info_keyword(vpd, kw_offset, vpdr_len, name); \
Dimitris Michailidis226ec5f2010-04-27 12:24:15 +00001424 if (var < 0) { \
1425 dev_err(adapter->pdev_dev, "missing VPD keyword " name "\n"); \
Vipul Pandya8c357eb2012-10-03 03:22:32 +00001426 ret = -EINVAL; \
1427 goto out; \
Dimitris Michailidis226ec5f2010-04-27 12:24:15 +00001428 } \
1429 var += PCI_VPD_INFO_FLD_HDR_SIZE; \
1430} while (0)
1431
1432 FIND_VPD_KW(i, "RV");
1433 for (csum = 0; i >= 0; i--)
1434 csum += vpd[i];
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001435
1436 if (csum) {
1437 dev_err(adapter->pdev_dev,
1438 "corrupted VPD EEPROM, actual csum %u\n", csum);
Vipul Pandya8c357eb2012-10-03 03:22:32 +00001439 ret = -EINVAL;
1440 goto out;
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001441 }
1442
Dimitris Michailidis226ec5f2010-04-27 12:24:15 +00001443 FIND_VPD_KW(ec, "EC");
1444 FIND_VPD_KW(sn, "SN");
Kumar Sanghvia94cd702014-02-18 17:56:09 +05301445 FIND_VPD_KW(pn, "PN");
Dimitris Michailidis226ec5f2010-04-27 12:24:15 +00001446#undef FIND_VPD_KW
1447
Dimitris Michailidis23d88e12010-12-14 21:36:54 +00001448 memcpy(p->id, vpd + PCI_VPD_LRDT_TAG_SIZE, id_len);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001449 strim(p->id);
Dimitris Michailidis226ec5f2010-04-27 12:24:15 +00001450 memcpy(p->ec, vpd + ec, EC_LEN);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001451 strim(p->ec);
Dimitris Michailidis226ec5f2010-04-27 12:24:15 +00001452 i = pci_vpd_info_field_size(vpd + sn - PCI_VPD_INFO_FLD_HDR_SIZE);
1453 memcpy(p->sn, vpd + sn, min(i, SERNUM_LEN));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001454 strim(p->sn);
Hariprasad Shenai63a92fe2014-09-01 19:54:56 +05301455 i = pci_vpd_info_field_size(vpd + pn - PCI_VPD_INFO_FLD_HDR_SIZE);
Kumar Sanghvia94cd702014-02-18 17:56:09 +05301456 memcpy(p->pn, vpd + pn, min(i, PN_LEN));
1457 strim(p->pn);
Vipul Pandya636f9d32012-09-26 02:39:39 +00001458
1459 /*
1460 * Ask firmware for the Core Clock since it knows how to translate the
1461 * Reference Clock ('V2') VPD field into a Core Clock value ...
1462 */
Hariprasad Shenai51678652014-11-21 12:52:02 +05301463 cclk_param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) |
1464 FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_CCLK));
Vipul Pandya636f9d32012-09-26 02:39:39 +00001465 ret = t4_query_params(adapter, adapter->mbox, 0, 0,
1466 1, &cclk_param, &cclk_val);
Vipul Pandya8c357eb2012-10-03 03:22:32 +00001467
1468out:
1469 vfree(vpd);
Vipul Pandya636f9d32012-09-26 02:39:39 +00001470 if (ret)
1471 return ret;
1472 p->cclk = cclk_val;
1473
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001474 return 0;
1475}
1476
1477/* serial flash and firmware constants */
1478enum {
1479 SF_ATTEMPTS = 10, /* max retries for SF operations */
1480
1481 /* flash command opcodes */
1482 SF_PROG_PAGE = 2, /* program page */
1483 SF_WR_DISABLE = 4, /* disable writes */
1484 SF_RD_STATUS = 5, /* read status register */
1485 SF_WR_ENABLE = 6, /* enable writes */
1486 SF_RD_DATA_FAST = 0xb, /* read flash */
Dimitris Michailidis900a6592010-06-18 10:05:27 +00001487 SF_RD_ID = 0x9f, /* read ID */
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001488 SF_ERASE_SECTOR = 0xd8, /* erase sector */
1489
Steve Wise6f1d7212014-04-15 14:22:34 -05001490 FW_MAX_SIZE = 16 * SF_SEC_SIZE,
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001491};
1492
1493/**
1494 * sf1_read - read data from the serial flash
1495 * @adapter: the adapter
1496 * @byte_cnt: number of bytes to read
1497 * @cont: whether another operation will be chained
1498 * @lock: whether to lock SF for PL access only
1499 * @valp: where to store the read data
1500 *
1501 * Reads up to 4 bytes of data from the serial flash. The location of
1502 * the read needs to be specified prior to calling this by issuing the
1503 * appropriate commands to the serial flash.
1504 */
1505static int sf1_read(struct adapter *adapter, unsigned int byte_cnt, int cont,
1506 int lock, u32 *valp)
1507{
1508 int ret;
1509
1510 if (!byte_cnt || byte_cnt > 4)
1511 return -EINVAL;
Hariprasad Shenai0d804332015-01-05 16:30:47 +05301512 if (t4_read_reg(adapter, SF_OP_A) & SF_BUSY_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001513 return -EBUSY;
Hariprasad Shenai0d804332015-01-05 16:30:47 +05301514 t4_write_reg(adapter, SF_OP_A, SF_LOCK_V(lock) |
1515 SF_CONT_V(cont) | BYTECNT_V(byte_cnt - 1));
1516 ret = t4_wait_op_done(adapter, SF_OP_A, SF_BUSY_F, 0, SF_ATTEMPTS, 5);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001517 if (!ret)
Hariprasad Shenai0d804332015-01-05 16:30:47 +05301518 *valp = t4_read_reg(adapter, SF_DATA_A);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001519 return ret;
1520}
1521
1522/**
1523 * sf1_write - write data to the serial flash
1524 * @adapter: the adapter
1525 * @byte_cnt: number of bytes to write
1526 * @cont: whether another operation will be chained
1527 * @lock: whether to lock SF for PL access only
1528 * @val: value to write
1529 *
1530 * Writes up to 4 bytes of data to the serial flash. The location of
1531 * the write needs to be specified prior to calling this by issuing the
1532 * appropriate commands to the serial flash.
1533 */
1534static int sf1_write(struct adapter *adapter, unsigned int byte_cnt, int cont,
1535 int lock, u32 val)
1536{
1537 if (!byte_cnt || byte_cnt > 4)
1538 return -EINVAL;
Hariprasad Shenai0d804332015-01-05 16:30:47 +05301539 if (t4_read_reg(adapter, SF_OP_A) & SF_BUSY_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001540 return -EBUSY;
Hariprasad Shenai0d804332015-01-05 16:30:47 +05301541 t4_write_reg(adapter, SF_DATA_A, val);
1542 t4_write_reg(adapter, SF_OP_A, SF_LOCK_V(lock) |
1543 SF_CONT_V(cont) | BYTECNT_V(byte_cnt - 1) | OP_V(1));
1544 return t4_wait_op_done(adapter, SF_OP_A, SF_BUSY_F, 0, SF_ATTEMPTS, 5);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001545}
1546
1547/**
1548 * flash_wait_op - wait for a flash operation to complete
1549 * @adapter: the adapter
1550 * @attempts: max number of polls of the status register
1551 * @delay: delay between polls in ms
1552 *
1553 * Wait for a flash operation to complete by polling the status register.
1554 */
1555static int flash_wait_op(struct adapter *adapter, int attempts, int delay)
1556{
1557 int ret;
1558 u32 status;
1559
1560 while (1) {
1561 if ((ret = sf1_write(adapter, 1, 1, 1, SF_RD_STATUS)) != 0 ||
1562 (ret = sf1_read(adapter, 1, 0, 1, &status)) != 0)
1563 return ret;
1564 if (!(status & 1))
1565 return 0;
1566 if (--attempts == 0)
1567 return -EAGAIN;
1568 if (delay)
1569 msleep(delay);
1570 }
1571}
1572
1573/**
1574 * t4_read_flash - read words from serial flash
1575 * @adapter: the adapter
1576 * @addr: the start address for the read
1577 * @nwords: how many 32-bit words to read
1578 * @data: where to store the read data
1579 * @byte_oriented: whether to store data as bytes or as words
1580 *
1581 * Read the specified number of 32-bit words from the serial flash.
1582 * If @byte_oriented is set the read data is stored as a byte array
1583 * (i.e., big-endian), otherwise as 32-bit words in the platform's
Joe Perchesdbedd442015-03-06 20:49:12 -08001584 * natural endianness.
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001585 */
Hariprasad Shenai49216c12015-01-20 12:02:20 +05301586int t4_read_flash(struct adapter *adapter, unsigned int addr,
1587 unsigned int nwords, u32 *data, int byte_oriented)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001588{
1589 int ret;
1590
Dimitris Michailidis900a6592010-06-18 10:05:27 +00001591 if (addr + nwords * sizeof(u32) > adapter->params.sf_size || (addr & 3))
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001592 return -EINVAL;
1593
1594 addr = swab32(addr) | SF_RD_DATA_FAST;
1595
1596 if ((ret = sf1_write(adapter, 4, 1, 0, addr)) != 0 ||
1597 (ret = sf1_read(adapter, 1, 1, 0, data)) != 0)
1598 return ret;
1599
1600 for ( ; nwords; nwords--, data++) {
1601 ret = sf1_read(adapter, 4, nwords > 1, nwords == 1, data);
1602 if (nwords == 1)
Hariprasad Shenai0d804332015-01-05 16:30:47 +05301603 t4_write_reg(adapter, SF_OP_A, 0); /* unlock SF */
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001604 if (ret)
1605 return ret;
1606 if (byte_oriented)
Hariprasad Shenaif404f802015-05-19 18:20:44 +05301607 *data = (__force __u32)(cpu_to_be32(*data));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001608 }
1609 return 0;
1610}
1611
1612/**
1613 * t4_write_flash - write up to a page of data to the serial flash
1614 * @adapter: the adapter
1615 * @addr: the start address to write
1616 * @n: length of data to write in bytes
1617 * @data: the data to write
1618 *
1619 * Writes up to a page of data (256 bytes) to the serial flash starting
1620 * at the given address. All the data must be written to the same page.
1621 */
1622static int t4_write_flash(struct adapter *adapter, unsigned int addr,
1623 unsigned int n, const u8 *data)
1624{
1625 int ret;
1626 u32 buf[64];
1627 unsigned int i, c, left, val, offset = addr & 0xff;
1628
Dimitris Michailidis900a6592010-06-18 10:05:27 +00001629 if (addr >= adapter->params.sf_size || offset + n > SF_PAGE_SIZE)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001630 return -EINVAL;
1631
1632 val = swab32(addr) | SF_PROG_PAGE;
1633
1634 if ((ret = sf1_write(adapter, 1, 0, 1, SF_WR_ENABLE)) != 0 ||
1635 (ret = sf1_write(adapter, 4, 1, 1, val)) != 0)
1636 goto unlock;
1637
1638 for (left = n; left; left -= c) {
1639 c = min(left, 4U);
1640 for (val = 0, i = 0; i < c; ++i)
1641 val = (val << 8) + *data++;
1642
1643 ret = sf1_write(adapter, c, c != left, 1, val);
1644 if (ret)
1645 goto unlock;
1646 }
Dimitris Michailidis900a6592010-06-18 10:05:27 +00001647 ret = flash_wait_op(adapter, 8, 1);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001648 if (ret)
1649 goto unlock;
1650
Hariprasad Shenai0d804332015-01-05 16:30:47 +05301651 t4_write_reg(adapter, SF_OP_A, 0); /* unlock SF */
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001652
1653 /* Read the page to verify the write succeeded */
1654 ret = t4_read_flash(adapter, addr & ~0xff, ARRAY_SIZE(buf), buf, 1);
1655 if (ret)
1656 return ret;
1657
1658 if (memcmp(data - n, (u8 *)buf + offset, n)) {
1659 dev_err(adapter->pdev_dev,
1660 "failed to correctly write the flash page at %#x\n",
1661 addr);
1662 return -EIO;
1663 }
1664 return 0;
1665
1666unlock:
Hariprasad Shenai0d804332015-01-05 16:30:47 +05301667 t4_write_reg(adapter, SF_OP_A, 0); /* unlock SF */
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001668 return ret;
1669}
1670
1671/**
Hariprasad Shenai16e47622013-12-03 17:05:58 +05301672 * t4_get_fw_version - read the firmware version
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001673 * @adapter: the adapter
1674 * @vers: where to place the version
1675 *
1676 * Reads the FW version from flash.
1677 */
Hariprasad Shenai16e47622013-12-03 17:05:58 +05301678int t4_get_fw_version(struct adapter *adapter, u32 *vers)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001679{
Hariprasad Shenai16e47622013-12-03 17:05:58 +05301680 return t4_read_flash(adapter, FLASH_FW_START +
1681 offsetof(struct fw_hdr, fw_ver), 1,
1682 vers, 0);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001683}
1684
1685/**
Hariprasad Shenai16e47622013-12-03 17:05:58 +05301686 * t4_get_tp_version - read the TP microcode version
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001687 * @adapter: the adapter
1688 * @vers: where to place the version
1689 *
1690 * Reads the TP microcode version from flash.
1691 */
Hariprasad Shenai16e47622013-12-03 17:05:58 +05301692int t4_get_tp_version(struct adapter *adapter, u32 *vers)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001693{
Hariprasad Shenai16e47622013-12-03 17:05:58 +05301694 return t4_read_flash(adapter, FLASH_FW_START +
Dimitris Michailidis900a6592010-06-18 10:05:27 +00001695 offsetof(struct fw_hdr, tp_microcode_ver),
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001696 1, vers, 0);
1697}
1698
Hariprasad Shenaiba3f8cd2015-02-09 12:07:30 +05301699/**
1700 * t4_get_exprom_version - return the Expansion ROM version (if any)
1701 * @adapter: the adapter
1702 * @vers: where to place the version
1703 *
1704 * Reads the Expansion ROM header from FLASH and returns the version
1705 * number (if present) through the @vers return value pointer. We return
1706 * this in the Firmware Version Format since it's convenient. Return
1707 * 0 on success, -ENOENT if no Expansion ROM is present.
1708 */
1709int t4_get_exprom_version(struct adapter *adap, u32 *vers)
1710{
1711 struct exprom_header {
1712 unsigned char hdr_arr[16]; /* must start with 0x55aa */
1713 unsigned char hdr_ver[4]; /* Expansion ROM version */
1714 } *hdr;
1715 u32 exprom_header_buf[DIV_ROUND_UP(sizeof(struct exprom_header),
1716 sizeof(u32))];
1717 int ret;
1718
1719 ret = t4_read_flash(adap, FLASH_EXP_ROM_START,
1720 ARRAY_SIZE(exprom_header_buf), exprom_header_buf,
1721 0);
1722 if (ret)
1723 return ret;
1724
1725 hdr = (struct exprom_header *)exprom_header_buf;
1726 if (hdr->hdr_arr[0] != 0x55 || hdr->hdr_arr[1] != 0xaa)
1727 return -ENOENT;
1728
1729 *vers = (FW_HDR_FW_VER_MAJOR_V(hdr->hdr_ver[0]) |
1730 FW_HDR_FW_VER_MINOR_V(hdr->hdr_ver[1]) |
1731 FW_HDR_FW_VER_MICRO_V(hdr->hdr_ver[2]) |
1732 FW_HDR_FW_VER_BUILD_V(hdr->hdr_ver[3]));
1733 return 0;
1734}
1735
Hariprasad Shenai16e47622013-12-03 17:05:58 +05301736/* Is the given firmware API compatible with the one the driver was compiled
1737 * with?
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001738 */
Hariprasad Shenai16e47622013-12-03 17:05:58 +05301739static int fw_compatible(const struct fw_hdr *hdr1, const struct fw_hdr *hdr2)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001740{
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001741
Hariprasad Shenai16e47622013-12-03 17:05:58 +05301742 /* short circuit if it's the exact same firmware version */
1743 if (hdr1->chip == hdr2->chip && hdr1->fw_ver == hdr2->fw_ver)
1744 return 1;
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001745
Hariprasad Shenai16e47622013-12-03 17:05:58 +05301746#define SAME_INTF(x) (hdr1->intfver_##x == hdr2->intfver_##x)
1747 if (hdr1->chip == hdr2->chip && SAME_INTF(nic) && SAME_INTF(vnic) &&
1748 SAME_INTF(ri) && SAME_INTF(iscsi) && SAME_INTF(fcoe))
1749 return 1;
1750#undef SAME_INTF
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001751
Hariprasad Shenai16e47622013-12-03 17:05:58 +05301752 return 0;
1753}
1754
1755/* The firmware in the filesystem is usable, but should it be installed?
1756 * This routine explains itself in detail if it indicates the filesystem
1757 * firmware should be installed.
1758 */
1759static int should_install_fs_fw(struct adapter *adap, int card_fw_usable,
1760 int k, int c)
1761{
1762 const char *reason;
1763
1764 if (!card_fw_usable) {
1765 reason = "incompatible or unusable";
1766 goto install;
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001767 }
1768
Hariprasad Shenai16e47622013-12-03 17:05:58 +05301769 if (k > c) {
1770 reason = "older than the version supported with this driver";
1771 goto install;
Jay Hernandeze69972f2013-05-30 03:24:14 +00001772 }
1773
Hariprasad Shenai16e47622013-12-03 17:05:58 +05301774 return 0;
Santosh Rastapur0a57a532013-03-14 05:08:49 +00001775
Hariprasad Shenai16e47622013-12-03 17:05:58 +05301776install:
1777 dev_err(adap->pdev_dev, "firmware on card (%u.%u.%u.%u) is %s, "
1778 "installing firmware %u.%u.%u.%u on card.\n",
Hariprasad Shenaib2e1a3f2014-11-21 12:52:05 +05301779 FW_HDR_FW_VER_MAJOR_G(c), FW_HDR_FW_VER_MINOR_G(c),
1780 FW_HDR_FW_VER_MICRO_G(c), FW_HDR_FW_VER_BUILD_G(c), reason,
1781 FW_HDR_FW_VER_MAJOR_G(k), FW_HDR_FW_VER_MINOR_G(k),
1782 FW_HDR_FW_VER_MICRO_G(k), FW_HDR_FW_VER_BUILD_G(k));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001783
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001784 return 1;
1785}
1786
Hariprasad Shenai16e47622013-12-03 17:05:58 +05301787int t4_prep_fw(struct adapter *adap, struct fw_info *fw_info,
1788 const u8 *fw_data, unsigned int fw_size,
1789 struct fw_hdr *card_fw, enum dev_state state,
1790 int *reset)
1791{
1792 int ret, card_fw_usable, fs_fw_usable;
1793 const struct fw_hdr *fs_fw;
1794 const struct fw_hdr *drv_fw;
1795
1796 drv_fw = &fw_info->fw_hdr;
1797
1798 /* Read the header of the firmware on the card */
1799 ret = -t4_read_flash(adap, FLASH_FW_START,
1800 sizeof(*card_fw) / sizeof(uint32_t),
1801 (uint32_t *)card_fw, 1);
1802 if (ret == 0) {
1803 card_fw_usable = fw_compatible(drv_fw, (const void *)card_fw);
1804 } else {
1805 dev_err(adap->pdev_dev,
1806 "Unable to read card's firmware header: %d\n", ret);
1807 card_fw_usable = 0;
1808 }
1809
1810 if (fw_data != NULL) {
1811 fs_fw = (const void *)fw_data;
1812 fs_fw_usable = fw_compatible(drv_fw, fs_fw);
1813 } else {
1814 fs_fw = NULL;
1815 fs_fw_usable = 0;
1816 }
1817
1818 if (card_fw_usable && card_fw->fw_ver == drv_fw->fw_ver &&
1819 (!fs_fw_usable || fs_fw->fw_ver == drv_fw->fw_ver)) {
1820 /* Common case: the firmware on the card is an exact match and
1821 * the filesystem one is an exact match too, or the filesystem
1822 * one is absent/incompatible.
1823 */
1824 } else if (fs_fw_usable && state == DEV_STATE_UNINIT &&
1825 should_install_fs_fw(adap, card_fw_usable,
1826 be32_to_cpu(fs_fw->fw_ver),
1827 be32_to_cpu(card_fw->fw_ver))) {
1828 ret = -t4_fw_upgrade(adap, adap->mbox, fw_data,
1829 fw_size, 0);
1830 if (ret != 0) {
1831 dev_err(adap->pdev_dev,
1832 "failed to install firmware: %d\n", ret);
1833 goto bye;
1834 }
1835
1836 /* Installed successfully, update the cached header too. */
Hariprasad Shenaie3d50732015-03-10 17:44:52 +05301837 *card_fw = *fs_fw;
Hariprasad Shenai16e47622013-12-03 17:05:58 +05301838 card_fw_usable = 1;
1839 *reset = 0; /* already reset as part of load_fw */
1840 }
1841
1842 if (!card_fw_usable) {
1843 uint32_t d, c, k;
1844
1845 d = be32_to_cpu(drv_fw->fw_ver);
1846 c = be32_to_cpu(card_fw->fw_ver);
1847 k = fs_fw ? be32_to_cpu(fs_fw->fw_ver) : 0;
1848
1849 dev_err(adap->pdev_dev, "Cannot find a usable firmware: "
1850 "chip state %d, "
1851 "driver compiled with %d.%d.%d.%d, "
1852 "card has %d.%d.%d.%d, filesystem has %d.%d.%d.%d\n",
1853 state,
Hariprasad Shenaib2e1a3f2014-11-21 12:52:05 +05301854 FW_HDR_FW_VER_MAJOR_G(d), FW_HDR_FW_VER_MINOR_G(d),
1855 FW_HDR_FW_VER_MICRO_G(d), FW_HDR_FW_VER_BUILD_G(d),
1856 FW_HDR_FW_VER_MAJOR_G(c), FW_HDR_FW_VER_MINOR_G(c),
1857 FW_HDR_FW_VER_MICRO_G(c), FW_HDR_FW_VER_BUILD_G(c),
1858 FW_HDR_FW_VER_MAJOR_G(k), FW_HDR_FW_VER_MINOR_G(k),
1859 FW_HDR_FW_VER_MICRO_G(k), FW_HDR_FW_VER_BUILD_G(k));
Hariprasad Shenai16e47622013-12-03 17:05:58 +05301860 ret = EINVAL;
1861 goto bye;
1862 }
1863
1864 /* We're using whatever's on the card and it's known to be good. */
1865 adap->params.fw_vers = be32_to_cpu(card_fw->fw_ver);
1866 adap->params.tp_vers = be32_to_cpu(card_fw->tp_microcode_ver);
1867
1868bye:
1869 return ret;
1870}
1871
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001872/**
1873 * t4_flash_erase_sectors - erase a range of flash sectors
1874 * @adapter: the adapter
1875 * @start: the first sector to erase
1876 * @end: the last sector to erase
1877 *
1878 * Erases the sectors in the given inclusive range.
1879 */
1880static int t4_flash_erase_sectors(struct adapter *adapter, int start, int end)
1881{
1882 int ret = 0;
1883
Hariprasad Shenaic0d5b8c2014-09-10 17:44:29 +05301884 if (end >= adapter->params.sf_nsec)
1885 return -EINVAL;
1886
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001887 while (start <= end) {
1888 if ((ret = sf1_write(adapter, 1, 0, 1, SF_WR_ENABLE)) != 0 ||
1889 (ret = sf1_write(adapter, 4, 0, 1,
1890 SF_ERASE_SECTOR | (start << 8))) != 0 ||
Dimitris Michailidis900a6592010-06-18 10:05:27 +00001891 (ret = flash_wait_op(adapter, 14, 500)) != 0) {
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001892 dev_err(adapter->pdev_dev,
1893 "erase of flash sector %d failed, error %d\n",
1894 start, ret);
1895 break;
1896 }
1897 start++;
1898 }
Hariprasad Shenai0d804332015-01-05 16:30:47 +05301899 t4_write_reg(adapter, SF_OP_A, 0); /* unlock SF */
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001900 return ret;
1901}
1902
1903/**
Vipul Pandya636f9d32012-09-26 02:39:39 +00001904 * t4_flash_cfg_addr - return the address of the flash configuration file
1905 * @adapter: the adapter
1906 *
1907 * Return the address within the flash where the Firmware Configuration
1908 * File is stored.
1909 */
1910unsigned int t4_flash_cfg_addr(struct adapter *adapter)
1911{
1912 if (adapter->params.sf_size == 0x100000)
1913 return FLASH_FPGA_CFG_START;
1914 else
1915 return FLASH_CFG_START;
1916}
1917
Hariprasad Shenai79af2212014-12-03 11:49:50 +05301918/* Return TRUE if the specified firmware matches the adapter. I.e. T4
1919 * firmware for T4 adapters, T5 firmware for T5 adapters, etc. We go ahead
1920 * and emit an error message for mismatched firmware to save our caller the
1921 * effort ...
1922 */
1923static bool t4_fw_matches_chip(const struct adapter *adap,
1924 const struct fw_hdr *hdr)
1925{
1926 /* The expression below will return FALSE for any unsupported adapter
1927 * which will keep us "honest" in the future ...
1928 */
1929 if ((is_t4(adap->params.chip) && hdr->chip == FW_HDR_CHIP_T4) ||
1930 (is_t5(adap->params.chip) && hdr->chip == FW_HDR_CHIP_T5))
1931 return true;
1932
1933 dev_err(adap->pdev_dev,
1934 "FW image (%d) is not suitable for this adapter (%d)\n",
1935 hdr->chip, CHELSIO_CHIP_VERSION(adap->params.chip));
1936 return false;
1937}
1938
Vipul Pandya636f9d32012-09-26 02:39:39 +00001939/**
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001940 * t4_load_fw - download firmware
1941 * @adap: the adapter
1942 * @fw_data: the firmware image to write
1943 * @size: image size
1944 *
1945 * Write the supplied firmware image to the card's serial flash.
1946 */
1947int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size)
1948{
1949 u32 csum;
1950 int ret, addr;
1951 unsigned int i;
1952 u8 first_page[SF_PAGE_SIZE];
Vipul Pandya404d9e32012-10-08 02:59:43 +00001953 const __be32 *p = (const __be32 *)fw_data;
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001954 const struct fw_hdr *hdr = (const struct fw_hdr *)fw_data;
Dimitris Michailidis900a6592010-06-18 10:05:27 +00001955 unsigned int sf_sec_size = adap->params.sf_size / adap->params.sf_nsec;
1956 unsigned int fw_img_start = adap->params.sf_fw_start;
1957 unsigned int fw_start_sec = fw_img_start / sf_sec_size;
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001958
1959 if (!size) {
1960 dev_err(adap->pdev_dev, "FW image has no data\n");
1961 return -EINVAL;
1962 }
1963 if (size & 511) {
1964 dev_err(adap->pdev_dev,
1965 "FW image size not multiple of 512 bytes\n");
1966 return -EINVAL;
1967 }
Hariprasad Shenaif404f802015-05-19 18:20:44 +05301968 if ((unsigned int)be16_to_cpu(hdr->len512) * 512 != size) {
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001969 dev_err(adap->pdev_dev,
1970 "FW image size differs from size in FW header\n");
1971 return -EINVAL;
1972 }
1973 if (size > FW_MAX_SIZE) {
1974 dev_err(adap->pdev_dev, "FW image too large, max is %u bytes\n",
1975 FW_MAX_SIZE);
1976 return -EFBIG;
1977 }
Hariprasad Shenai79af2212014-12-03 11:49:50 +05301978 if (!t4_fw_matches_chip(adap, hdr))
1979 return -EINVAL;
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001980
1981 for (csum = 0, i = 0; i < size / sizeof(csum); i++)
Hariprasad Shenaif404f802015-05-19 18:20:44 +05301982 csum += be32_to_cpu(p[i]);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001983
1984 if (csum != 0xffffffff) {
1985 dev_err(adap->pdev_dev,
1986 "corrupted firmware image, checksum %#x\n", csum);
1987 return -EINVAL;
1988 }
1989
Dimitris Michailidis900a6592010-06-18 10:05:27 +00001990 i = DIV_ROUND_UP(size, sf_sec_size); /* # of sectors spanned */
1991 ret = t4_flash_erase_sectors(adap, fw_start_sec, fw_start_sec + i - 1);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00001992 if (ret)
1993 goto out;
1994
1995 /*
1996 * We write the correct version at the end so the driver can see a bad
1997 * version if the FW write fails. Start by writing a copy of the
1998 * first page with a bad version.
1999 */
2000 memcpy(first_page, fw_data, SF_PAGE_SIZE);
Hariprasad Shenaif404f802015-05-19 18:20:44 +05302001 ((struct fw_hdr *)first_page)->fw_ver = cpu_to_be32(0xffffffff);
Dimitris Michailidis900a6592010-06-18 10:05:27 +00002002 ret = t4_write_flash(adap, fw_img_start, SF_PAGE_SIZE, first_page);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002003 if (ret)
2004 goto out;
2005
Dimitris Michailidis900a6592010-06-18 10:05:27 +00002006 addr = fw_img_start;
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002007 for (size -= SF_PAGE_SIZE; size; size -= SF_PAGE_SIZE) {
2008 addr += SF_PAGE_SIZE;
2009 fw_data += SF_PAGE_SIZE;
2010 ret = t4_write_flash(adap, addr, SF_PAGE_SIZE, fw_data);
2011 if (ret)
2012 goto out;
2013 }
2014
2015 ret = t4_write_flash(adap,
Dimitris Michailidis900a6592010-06-18 10:05:27 +00002016 fw_img_start + offsetof(struct fw_hdr, fw_ver),
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002017 sizeof(hdr->fw_ver), (const u8 *)&hdr->fw_ver);
2018out:
2019 if (ret)
2020 dev_err(adap->pdev_dev, "firmware download failed, error %d\n",
2021 ret);
Hariprasad Shenaidff04bc2014-12-03 19:32:54 +05302022 else
2023 ret = t4_get_fw_version(adap, &adap->params.fw_vers);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002024 return ret;
2025}
2026
Hariprasad Shenai49216c12015-01-20 12:02:20 +05302027/**
2028 * t4_fwcache - firmware cache operation
2029 * @adap: the adapter
2030 * @op : the operation (flush or flush and invalidate)
2031 */
2032int t4_fwcache(struct adapter *adap, enum fw_params_param_dev_fwcache op)
2033{
2034 struct fw_params_cmd c;
2035
2036 memset(&c, 0, sizeof(c));
2037 c.op_to_vfn =
2038 cpu_to_be32(FW_CMD_OP_V(FW_PARAMS_CMD) |
2039 FW_CMD_REQUEST_F | FW_CMD_WRITE_F |
2040 FW_PARAMS_CMD_PFN_V(adap->fn) |
2041 FW_PARAMS_CMD_VFN_V(0));
2042 c.retval_len16 = cpu_to_be32(FW_LEN16(c));
2043 c.param[0].mnem =
2044 cpu_to_be32(FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) |
2045 FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_FWCACHE));
2046 c.param[0].val = (__force __be32)op;
2047
2048 return t4_wr_mbox(adap, adap->mbox, &c, sizeof(c), NULL);
2049}
2050
Hariprasad Shenai797ff0f2015-02-06 19:32:53 +05302051void t4_ulprx_read_la(struct adapter *adap, u32 *la_buf)
2052{
2053 unsigned int i, j;
2054
2055 for (i = 0; i < 8; i++) {
2056 u32 *p = la_buf + i;
2057
2058 t4_write_reg(adap, ULP_RX_LA_CTL_A, i);
2059 j = t4_read_reg(adap, ULP_RX_LA_WRPTR_A);
2060 t4_write_reg(adap, ULP_RX_LA_RDPTR_A, j);
2061 for (j = 0; j < ULPRX_LA_SIZE; j++, p += 8)
2062 *p = t4_read_reg(adap, ULP_RX_LA_RDDATA_A);
2063 }
2064}
2065
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002066#define ADVERT_MASK (FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G |\
Kumar Sanghvi72aca4b2014-02-18 17:56:08 +05302067 FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_SPEED_40G | \
2068 FW_PORT_CAP_ANEG)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002069
2070/**
2071 * t4_link_start - apply link configuration to MAC/PHY
2072 * @phy: the PHY to setup
2073 * @mac: the MAC to setup
2074 * @lc: the requested link configuration
2075 *
2076 * Set up a port's MAC and PHY according to a desired link configuration.
2077 * - If the PHY can auto-negotiate first decide what to advertise, then
2078 * enable/disable auto-negotiation as desired, and reset.
2079 * - If the PHY does not auto-negotiate just reset it.
2080 * - If auto-negotiation is off set the MAC to the proper speed/duplex/FC,
2081 * otherwise do it later based on the outcome of auto-negotiation.
2082 */
2083int t4_link_start(struct adapter *adap, unsigned int mbox, unsigned int port,
2084 struct link_config *lc)
2085{
2086 struct fw_port_cmd c;
Hariprasad Shenai2b5fb1f2014-11-21 12:52:04 +05302087 unsigned int fc = 0, mdi = FW_PORT_CAP_MDI_V(FW_PORT_CAP_MDI_AUTO);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002088
2089 lc->link_ok = 0;
2090 if (lc->requested_fc & PAUSE_RX)
2091 fc |= FW_PORT_CAP_FC_RX;
2092 if (lc->requested_fc & PAUSE_TX)
2093 fc |= FW_PORT_CAP_FC_TX;
2094
2095 memset(&c, 0, sizeof(c));
Hariprasad Shenaif404f802015-05-19 18:20:44 +05302096 c.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) |
2097 FW_CMD_REQUEST_F | FW_CMD_EXEC_F |
2098 FW_PORT_CMD_PORTID_V(port));
2099 c.action_to_len16 =
2100 cpu_to_be32(FW_PORT_CMD_ACTION_V(FW_PORT_ACTION_L1_CFG) |
2101 FW_LEN16(c));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002102
2103 if (!(lc->supported & FW_PORT_CAP_ANEG)) {
Hariprasad Shenaif404f802015-05-19 18:20:44 +05302104 c.u.l1cfg.rcap = cpu_to_be32((lc->supported & ADVERT_MASK) |
2105 fc);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002106 lc->fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
2107 } else if (lc->autoneg == AUTONEG_DISABLE) {
Hariprasad Shenaif404f802015-05-19 18:20:44 +05302108 c.u.l1cfg.rcap = cpu_to_be32(lc->requested_speed | fc | mdi);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002109 lc->fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
2110 } else
Hariprasad Shenaif404f802015-05-19 18:20:44 +05302111 c.u.l1cfg.rcap = cpu_to_be32(lc->advertising | fc | mdi);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002112
2113 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
2114}
2115
2116/**
2117 * t4_restart_aneg - restart autonegotiation
2118 * @adap: the adapter
2119 * @mbox: mbox to use for the FW command
2120 * @port: the port id
2121 *
2122 * Restarts autonegotiation for the selected port.
2123 */
2124int t4_restart_aneg(struct adapter *adap, unsigned int mbox, unsigned int port)
2125{
2126 struct fw_port_cmd c;
2127
2128 memset(&c, 0, sizeof(c));
Hariprasad Shenaif404f802015-05-19 18:20:44 +05302129 c.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) |
2130 FW_CMD_REQUEST_F | FW_CMD_EXEC_F |
2131 FW_PORT_CMD_PORTID_V(port));
2132 c.action_to_len16 =
2133 cpu_to_be32(FW_PORT_CMD_ACTION_V(FW_PORT_ACTION_L1_CFG) |
2134 FW_LEN16(c));
2135 c.u.l1cfg.rcap = cpu_to_be32(FW_PORT_CAP_ANEG);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002136 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
2137}
2138
Vipul Pandya8caa1e82012-05-18 15:29:25 +05302139typedef void (*int_handler_t)(struct adapter *adap);
2140
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002141struct intr_info {
2142 unsigned int mask; /* bits to check in interrupt status */
2143 const char *msg; /* message to print or NULL */
2144 short stat_idx; /* stat counter to increment or -1 */
2145 unsigned short fatal; /* whether the condition reported is fatal */
Vipul Pandya8caa1e82012-05-18 15:29:25 +05302146 int_handler_t int_handler; /* platform-specific int handler */
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002147};
2148
2149/**
2150 * t4_handle_intr_status - table driven interrupt handler
2151 * @adapter: the adapter that generated the interrupt
2152 * @reg: the interrupt status register to process
2153 * @acts: table of interrupt actions
2154 *
2155 * A table driven interrupt handler that applies a set of masks to an
2156 * interrupt status word and performs the corresponding actions if the
Lucas De Marchi25985ed2011-03-30 22:57:33 -03002157 * interrupts described by the mask have occurred. The actions include
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002158 * optionally emitting a warning or alert message. The table is terminated
2159 * by an entry specifying mask 0. Returns the number of fatal interrupt
2160 * conditions.
2161 */
2162static int t4_handle_intr_status(struct adapter *adapter, unsigned int reg,
2163 const struct intr_info *acts)
2164{
2165 int fatal = 0;
2166 unsigned int mask = 0;
2167 unsigned int status = t4_read_reg(adapter, reg);
2168
2169 for ( ; acts->mask; ++acts) {
2170 if (!(status & acts->mask))
2171 continue;
2172 if (acts->fatal) {
2173 fatal++;
2174 dev_alert(adapter->pdev_dev, "%s (0x%x)\n", acts->msg,
2175 status & acts->mask);
2176 } else if (acts->msg && printk_ratelimit())
2177 dev_warn(adapter->pdev_dev, "%s (0x%x)\n", acts->msg,
2178 status & acts->mask);
Vipul Pandya8caa1e82012-05-18 15:29:25 +05302179 if (acts->int_handler)
2180 acts->int_handler(adapter);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002181 mask |= acts->mask;
2182 }
2183 status &= mask;
2184 if (status) /* clear processed interrupts */
2185 t4_write_reg(adapter, reg, status);
2186 return fatal;
2187}
2188
2189/*
2190 * Interrupt handler for the PCIE module.
2191 */
2192static void pcie_intr_handler(struct adapter *adapter)
2193{
Joe Perches005b5712010-12-14 21:36:53 +00002194 static const struct intr_info sysbus_intr_info[] = {
Hariprasad Shenaif061de422015-01-05 16:30:44 +05302195 { RNPP_F, "RXNP array parity error", -1, 1 },
2196 { RPCP_F, "RXPC array parity error", -1, 1 },
2197 { RCIP_F, "RXCIF array parity error", -1, 1 },
2198 { RCCP_F, "Rx completions control array parity error", -1, 1 },
2199 { RFTP_F, "RXFT array parity error", -1, 1 },
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002200 { 0 }
2201 };
Joe Perches005b5712010-12-14 21:36:53 +00002202 static const struct intr_info pcie_port_intr_info[] = {
Hariprasad Shenaif061de422015-01-05 16:30:44 +05302203 { TPCP_F, "TXPC array parity error", -1, 1 },
2204 { TNPP_F, "TXNP array parity error", -1, 1 },
2205 { TFTP_F, "TXFT array parity error", -1, 1 },
2206 { TCAP_F, "TXCA array parity error", -1, 1 },
2207 { TCIP_F, "TXCIF array parity error", -1, 1 },
2208 { RCAP_F, "RXCA array parity error", -1, 1 },
2209 { OTDD_F, "outbound request TLP discarded", -1, 1 },
2210 { RDPE_F, "Rx data parity error", -1, 1 },
2211 { TDUE_F, "Tx uncorrectable data error", -1, 1 },
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002212 { 0 }
2213 };
Joe Perches005b5712010-12-14 21:36:53 +00002214 static const struct intr_info pcie_intr_info[] = {
Hariprasad Shenaif061de422015-01-05 16:30:44 +05302215 { MSIADDRLPERR_F, "MSI AddrL parity error", -1, 1 },
2216 { MSIADDRHPERR_F, "MSI AddrH parity error", -1, 1 },
2217 { MSIDATAPERR_F, "MSI data parity error", -1, 1 },
2218 { MSIXADDRLPERR_F, "MSI-X AddrL parity error", -1, 1 },
2219 { MSIXADDRHPERR_F, "MSI-X AddrH parity error", -1, 1 },
2220 { MSIXDATAPERR_F, "MSI-X data parity error", -1, 1 },
2221 { MSIXDIPERR_F, "MSI-X DI parity error", -1, 1 },
2222 { PIOCPLPERR_F, "PCI PIO completion FIFO parity error", -1, 1 },
2223 { PIOREQPERR_F, "PCI PIO request FIFO parity error", -1, 1 },
2224 { TARTAGPERR_F, "PCI PCI target tag FIFO parity error", -1, 1 },
2225 { CCNTPERR_F, "PCI CMD channel count parity error", -1, 1 },
2226 { CREQPERR_F, "PCI CMD channel request parity error", -1, 1 },
2227 { CRSPPERR_F, "PCI CMD channel response parity error", -1, 1 },
2228 { DCNTPERR_F, "PCI DMA channel count parity error", -1, 1 },
2229 { DREQPERR_F, "PCI DMA channel request parity error", -1, 1 },
2230 { DRSPPERR_F, "PCI DMA channel response parity error", -1, 1 },
2231 { HCNTPERR_F, "PCI HMA channel count parity error", -1, 1 },
2232 { HREQPERR_F, "PCI HMA channel request parity error", -1, 1 },
2233 { HRSPPERR_F, "PCI HMA channel response parity error", -1, 1 },
2234 { CFGSNPPERR_F, "PCI config snoop FIFO parity error", -1, 1 },
2235 { FIDPERR_F, "PCI FID parity error", -1, 1 },
2236 { INTXCLRPERR_F, "PCI INTx clear parity error", -1, 1 },
2237 { MATAGPERR_F, "PCI MA tag parity error", -1, 1 },
2238 { PIOTAGPERR_F, "PCI PIO tag parity error", -1, 1 },
2239 { RXCPLPERR_F, "PCI Rx completion parity error", -1, 1 },
2240 { RXWRPERR_F, "PCI Rx write parity error", -1, 1 },
2241 { RPLPERR_F, "PCI replay buffer parity error", -1, 1 },
2242 { PCIESINT_F, "PCI core secondary fault", -1, 1 },
2243 { PCIEPINT_F, "PCI core primary fault", -1, 1 },
2244 { UNXSPLCPLERR_F, "PCI unexpected split completion error",
2245 -1, 0 },
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002246 { 0 }
2247 };
2248
Santosh Rastapur0a57a532013-03-14 05:08:49 +00002249 static struct intr_info t5_pcie_intr_info[] = {
Hariprasad Shenaif061de422015-01-05 16:30:44 +05302250 { MSTGRPPERR_F, "Master Response Read Queue parity error",
Santosh Rastapur0a57a532013-03-14 05:08:49 +00002251 -1, 1 },
Hariprasad Shenaif061de422015-01-05 16:30:44 +05302252 { MSTTIMEOUTPERR_F, "Master Timeout FIFO parity error", -1, 1 },
2253 { MSIXSTIPERR_F, "MSI-X STI SRAM parity error", -1, 1 },
2254 { MSIXADDRLPERR_F, "MSI-X AddrL parity error", -1, 1 },
2255 { MSIXADDRHPERR_F, "MSI-X AddrH parity error", -1, 1 },
2256 { MSIXDATAPERR_F, "MSI-X data parity error", -1, 1 },
2257 { MSIXDIPERR_F, "MSI-X DI parity error", -1, 1 },
2258 { PIOCPLGRPPERR_F, "PCI PIO completion Group FIFO parity error",
Santosh Rastapur0a57a532013-03-14 05:08:49 +00002259 -1, 1 },
Hariprasad Shenaif061de422015-01-05 16:30:44 +05302260 { PIOREQGRPPERR_F, "PCI PIO request Group FIFO parity error",
Santosh Rastapur0a57a532013-03-14 05:08:49 +00002261 -1, 1 },
Hariprasad Shenaif061de422015-01-05 16:30:44 +05302262 { TARTAGPERR_F, "PCI PCI target tag FIFO parity error", -1, 1 },
2263 { MSTTAGQPERR_F, "PCI master tag queue parity error", -1, 1 },
2264 { CREQPERR_F, "PCI CMD channel request parity error", -1, 1 },
2265 { CRSPPERR_F, "PCI CMD channel response parity error", -1, 1 },
2266 { DREQWRPERR_F, "PCI DMA channel write request parity error",
Santosh Rastapur0a57a532013-03-14 05:08:49 +00002267 -1, 1 },
Hariprasad Shenaif061de422015-01-05 16:30:44 +05302268 { DREQPERR_F, "PCI DMA channel request parity error", -1, 1 },
2269 { DRSPPERR_F, "PCI DMA channel response parity error", -1, 1 },
2270 { HREQWRPERR_F, "PCI HMA channel count parity error", -1, 1 },
2271 { HREQPERR_F, "PCI HMA channel request parity error", -1, 1 },
2272 { HRSPPERR_F, "PCI HMA channel response parity error", -1, 1 },
2273 { CFGSNPPERR_F, "PCI config snoop FIFO parity error", -1, 1 },
2274 { FIDPERR_F, "PCI FID parity error", -1, 1 },
2275 { VFIDPERR_F, "PCI INTx clear parity error", -1, 1 },
2276 { MAGRPPERR_F, "PCI MA group FIFO parity error", -1, 1 },
2277 { PIOTAGPERR_F, "PCI PIO tag parity error", -1, 1 },
2278 { IPRXHDRGRPPERR_F, "PCI IP Rx header group parity error",
Santosh Rastapur0a57a532013-03-14 05:08:49 +00002279 -1, 1 },
Hariprasad Shenaif061de422015-01-05 16:30:44 +05302280 { IPRXDATAGRPPERR_F, "PCI IP Rx data group parity error",
2281 -1, 1 },
2282 { RPLPERR_F, "PCI IP replay buffer parity error", -1, 1 },
2283 { IPSOTPERR_F, "PCI IP SOT buffer parity error", -1, 1 },
2284 { TRGT1GRPPERR_F, "PCI TRGT1 group FIFOs parity error", -1, 1 },
2285 { READRSPERR_F, "Outbound read error", -1, 0 },
Santosh Rastapur0a57a532013-03-14 05:08:49 +00002286 { 0 }
2287 };
2288
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002289 int fat;
2290
Hariprasad Shenai9bb59b92014-09-01 19:54:57 +05302291 if (is_t4(adapter->params.chip))
2292 fat = t4_handle_intr_status(adapter,
Hariprasad Shenaif061de422015-01-05 16:30:44 +05302293 PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS_A,
2294 sysbus_intr_info) +
Hariprasad Shenai9bb59b92014-09-01 19:54:57 +05302295 t4_handle_intr_status(adapter,
Hariprasad Shenaif061de422015-01-05 16:30:44 +05302296 PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS_A,
2297 pcie_port_intr_info) +
2298 t4_handle_intr_status(adapter, PCIE_INT_CAUSE_A,
Hariprasad Shenai9bb59b92014-09-01 19:54:57 +05302299 pcie_intr_info);
2300 else
Hariprasad Shenaif061de422015-01-05 16:30:44 +05302301 fat = t4_handle_intr_status(adapter, PCIE_INT_CAUSE_A,
Hariprasad Shenai9bb59b92014-09-01 19:54:57 +05302302 t5_pcie_intr_info);
Santosh Rastapur0a57a532013-03-14 05:08:49 +00002303
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002304 if (fat)
2305 t4_fatal_err(adapter);
2306}
2307
2308/*
2309 * TP interrupt handler.
2310 */
2311static void tp_intr_handler(struct adapter *adapter)
2312{
Joe Perches005b5712010-12-14 21:36:53 +00002313 static const struct intr_info tp_intr_info[] = {
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002314 { 0x3fffffff, "TP parity error", -1, 1 },
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05302315 { FLMTXFLSTEMPTY_F, "TP out of Tx pages", -1, 1 },
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002316 { 0 }
2317 };
2318
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05302319 if (t4_handle_intr_status(adapter, TP_INT_CAUSE_A, tp_intr_info))
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002320 t4_fatal_err(adapter);
2321}
2322
2323/*
2324 * SGE interrupt handler.
2325 */
2326static void sge_intr_handler(struct adapter *adapter)
2327{
2328 u64 v;
2329
Joe Perches005b5712010-12-14 21:36:53 +00002330 static const struct intr_info sge_intr_info[] = {
Hariprasad Shenaif612b812015-01-05 16:30:43 +05302331 { ERR_CPL_EXCEED_IQE_SIZE_F,
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002332 "SGE received CPL exceeding IQE size", -1, 1 },
Hariprasad Shenaif612b812015-01-05 16:30:43 +05302333 { ERR_INVALID_CIDX_INC_F,
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002334 "SGE GTS CIDX increment too large", -1, 0 },
Hariprasad Shenaif612b812015-01-05 16:30:43 +05302335 { ERR_CPL_OPCODE_0_F, "SGE received 0-length CPL", -1, 0 },
2336 { DBFIFO_LP_INT_F, NULL, -1, 0, t4_db_full },
2337 { DBFIFO_HP_INT_F, NULL, -1, 0, t4_db_full },
2338 { ERR_DROPPED_DB_F, NULL, -1, 0, t4_db_dropped },
2339 { ERR_DATA_CPL_ON_HIGH_QID1_F | ERR_DATA_CPL_ON_HIGH_QID0_F,
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002340 "SGE IQID > 1023 received CPL for FL", -1, 0 },
Hariprasad Shenaif612b812015-01-05 16:30:43 +05302341 { ERR_BAD_DB_PIDX3_F, "SGE DBP 3 pidx increment too large", -1,
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002342 0 },
Hariprasad Shenaif612b812015-01-05 16:30:43 +05302343 { ERR_BAD_DB_PIDX2_F, "SGE DBP 2 pidx increment too large", -1,
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002344 0 },
Hariprasad Shenaif612b812015-01-05 16:30:43 +05302345 { ERR_BAD_DB_PIDX1_F, "SGE DBP 1 pidx increment too large", -1,
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002346 0 },
Hariprasad Shenaif612b812015-01-05 16:30:43 +05302347 { ERR_BAD_DB_PIDX0_F, "SGE DBP 0 pidx increment too large", -1,
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002348 0 },
Hariprasad Shenaif612b812015-01-05 16:30:43 +05302349 { ERR_ING_CTXT_PRIO_F,
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002350 "SGE too many priority ingress contexts", -1, 0 },
Hariprasad Shenaif612b812015-01-05 16:30:43 +05302351 { ERR_EGR_CTXT_PRIO_F,
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002352 "SGE too many priority egress contexts", -1, 0 },
Hariprasad Shenaif612b812015-01-05 16:30:43 +05302353 { INGRESS_SIZE_ERR_F, "SGE illegal ingress QID", -1, 0 },
2354 { EGRESS_SIZE_ERR_F, "SGE illegal egress QID", -1, 0 },
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002355 { 0 }
2356 };
2357
Hariprasad Shenaif612b812015-01-05 16:30:43 +05302358 v = (u64)t4_read_reg(adapter, SGE_INT_CAUSE1_A) |
2359 ((u64)t4_read_reg(adapter, SGE_INT_CAUSE2_A) << 32);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002360 if (v) {
2361 dev_alert(adapter->pdev_dev, "SGE parity error (%#llx)\n",
Vipul Pandya8caa1e82012-05-18 15:29:25 +05302362 (unsigned long long)v);
Hariprasad Shenaif612b812015-01-05 16:30:43 +05302363 t4_write_reg(adapter, SGE_INT_CAUSE1_A, v);
2364 t4_write_reg(adapter, SGE_INT_CAUSE2_A, v >> 32);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002365 }
2366
Hariprasad Shenaif612b812015-01-05 16:30:43 +05302367 if (t4_handle_intr_status(adapter, SGE_INT_CAUSE3_A, sge_intr_info) ||
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002368 v != 0)
2369 t4_fatal_err(adapter);
2370}
2371
Hariprasad Shenai89c3a862015-01-05 16:30:45 +05302372#define CIM_OBQ_INTR (OBQULP0PARERR_F | OBQULP1PARERR_F | OBQULP2PARERR_F |\
2373 OBQULP3PARERR_F | OBQSGEPARERR_F | OBQNCSIPARERR_F)
2374#define CIM_IBQ_INTR (IBQTP0PARERR_F | IBQTP1PARERR_F | IBQULPPARERR_F |\
2375 IBQSGEHIPARERR_F | IBQSGELOPARERR_F | IBQNCSIPARERR_F)
2376
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002377/*
2378 * CIM interrupt handler.
2379 */
2380static void cim_intr_handler(struct adapter *adapter)
2381{
Joe Perches005b5712010-12-14 21:36:53 +00002382 static const struct intr_info cim_intr_info[] = {
Hariprasad Shenai89c3a862015-01-05 16:30:45 +05302383 { PREFDROPINT_F, "CIM control register prefetch drop", -1, 1 },
2384 { CIM_OBQ_INTR, "CIM OBQ parity error", -1, 1 },
2385 { CIM_IBQ_INTR, "CIM IBQ parity error", -1, 1 },
2386 { MBUPPARERR_F, "CIM mailbox uP parity error", -1, 1 },
2387 { MBHOSTPARERR_F, "CIM mailbox host parity error", -1, 1 },
2388 { TIEQINPARERRINT_F, "CIM TIEQ outgoing parity error", -1, 1 },
2389 { TIEQOUTPARERRINT_F, "CIM TIEQ incoming parity error", -1, 1 },
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002390 { 0 }
2391 };
Joe Perches005b5712010-12-14 21:36:53 +00002392 static const struct intr_info cim_upintr_info[] = {
Hariprasad Shenai89c3a862015-01-05 16:30:45 +05302393 { RSVDSPACEINT_F, "CIM reserved space access", -1, 1 },
2394 { ILLTRANSINT_F, "CIM illegal transaction", -1, 1 },
2395 { ILLWRINT_F, "CIM illegal write", -1, 1 },
2396 { ILLRDINT_F, "CIM illegal read", -1, 1 },
2397 { ILLRDBEINT_F, "CIM illegal read BE", -1, 1 },
2398 { ILLWRBEINT_F, "CIM illegal write BE", -1, 1 },
2399 { SGLRDBOOTINT_F, "CIM single read from boot space", -1, 1 },
2400 { SGLWRBOOTINT_F, "CIM single write to boot space", -1, 1 },
2401 { BLKWRBOOTINT_F, "CIM block write to boot space", -1, 1 },
2402 { SGLRDFLASHINT_F, "CIM single read from flash space", -1, 1 },
2403 { SGLWRFLASHINT_F, "CIM single write to flash space", -1, 1 },
2404 { BLKWRFLASHINT_F, "CIM block write to flash space", -1, 1 },
2405 { SGLRDEEPROMINT_F, "CIM single EEPROM read", -1, 1 },
2406 { SGLWREEPROMINT_F, "CIM single EEPROM write", -1, 1 },
2407 { BLKRDEEPROMINT_F, "CIM block EEPROM read", -1, 1 },
2408 { BLKWREEPROMINT_F, "CIM block EEPROM write", -1, 1 },
2409 { SGLRDCTLINT_F, "CIM single read from CTL space", -1, 1 },
2410 { SGLWRCTLINT_F, "CIM single write to CTL space", -1, 1 },
2411 { BLKRDCTLINT_F, "CIM block read from CTL space", -1, 1 },
2412 { BLKWRCTLINT_F, "CIM block write to CTL space", -1, 1 },
2413 { SGLRDPLINT_F, "CIM single read from PL space", -1, 1 },
2414 { SGLWRPLINT_F, "CIM single write to PL space", -1, 1 },
2415 { BLKRDPLINT_F, "CIM block read from PL space", -1, 1 },
2416 { BLKWRPLINT_F, "CIM block write to PL space", -1, 1 },
2417 { REQOVRLOOKUPINT_F, "CIM request FIFO overwrite", -1, 1 },
2418 { RSPOVRLOOKUPINT_F, "CIM response FIFO overwrite", -1, 1 },
2419 { TIMEOUTINT_F, "CIM PIF timeout", -1, 1 },
2420 { TIMEOUTMAINT_F, "CIM PIF MA timeout", -1, 1 },
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002421 { 0 }
2422 };
2423
2424 int fat;
2425
Hariprasad Shenaif061de422015-01-05 16:30:44 +05302426 if (t4_read_reg(adapter, PCIE_FW_A) & PCIE_FW_ERR_F)
Hariprasad Shenai31d55c22014-09-01 19:54:58 +05302427 t4_report_fw_error(adapter);
2428
Hariprasad Shenai89c3a862015-01-05 16:30:45 +05302429 fat = t4_handle_intr_status(adapter, CIM_HOST_INT_CAUSE_A,
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002430 cim_intr_info) +
Hariprasad Shenai89c3a862015-01-05 16:30:45 +05302431 t4_handle_intr_status(adapter, CIM_HOST_UPACC_INT_CAUSE_A,
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002432 cim_upintr_info);
2433 if (fat)
2434 t4_fatal_err(adapter);
2435}
2436
2437/*
2438 * ULP RX interrupt handler.
2439 */
2440static void ulprx_intr_handler(struct adapter *adapter)
2441{
Joe Perches005b5712010-12-14 21:36:53 +00002442 static const struct intr_info ulprx_intr_info[] = {
Dimitris Michailidis91e9a1e2010-06-18 10:05:33 +00002443 { 0x1800000, "ULPRX context error", -1, 1 },
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002444 { 0x7fffff, "ULPRX parity error", -1, 1 },
2445 { 0 }
2446 };
2447
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302448 if (t4_handle_intr_status(adapter, ULP_RX_INT_CAUSE_A, ulprx_intr_info))
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002449 t4_fatal_err(adapter);
2450}
2451
2452/*
2453 * ULP TX interrupt handler.
2454 */
2455static void ulptx_intr_handler(struct adapter *adapter)
2456{
Joe Perches005b5712010-12-14 21:36:53 +00002457 static const struct intr_info ulptx_intr_info[] = {
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05302458 { PBL_BOUND_ERR_CH3_F, "ULPTX channel 3 PBL out of bounds", -1,
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002459 0 },
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05302460 { PBL_BOUND_ERR_CH2_F, "ULPTX channel 2 PBL out of bounds", -1,
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002461 0 },
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05302462 { PBL_BOUND_ERR_CH1_F, "ULPTX channel 1 PBL out of bounds", -1,
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002463 0 },
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05302464 { PBL_BOUND_ERR_CH0_F, "ULPTX channel 0 PBL out of bounds", -1,
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002465 0 },
2466 { 0xfffffff, "ULPTX parity error", -1, 1 },
2467 { 0 }
2468 };
2469
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05302470 if (t4_handle_intr_status(adapter, ULP_TX_INT_CAUSE_A, ulptx_intr_info))
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002471 t4_fatal_err(adapter);
2472}
2473
2474/*
2475 * PM TX interrupt handler.
2476 */
2477static void pmtx_intr_handler(struct adapter *adapter)
2478{
Joe Perches005b5712010-12-14 21:36:53 +00002479 static const struct intr_info pmtx_intr_info[] = {
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05302480 { PCMD_LEN_OVFL0_F, "PMTX channel 0 pcmd too large", -1, 1 },
2481 { PCMD_LEN_OVFL1_F, "PMTX channel 1 pcmd too large", -1, 1 },
2482 { PCMD_LEN_OVFL2_F, "PMTX channel 2 pcmd too large", -1, 1 },
2483 { ZERO_C_CMD_ERROR_F, "PMTX 0-length pcmd", -1, 1 },
2484 { PMTX_FRAMING_ERROR_F, "PMTX framing error", -1, 1 },
2485 { OESPI_PAR_ERROR_F, "PMTX oespi parity error", -1, 1 },
2486 { DB_OPTIONS_PAR_ERROR_F, "PMTX db_options parity error",
2487 -1, 1 },
2488 { ICSPI_PAR_ERROR_F, "PMTX icspi parity error", -1, 1 },
2489 { PMTX_C_PCMD_PAR_ERROR_F, "PMTX c_pcmd parity error", -1, 1},
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002490 { 0 }
2491 };
2492
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05302493 if (t4_handle_intr_status(adapter, PM_TX_INT_CAUSE_A, pmtx_intr_info))
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002494 t4_fatal_err(adapter);
2495}
2496
2497/*
2498 * PM RX interrupt handler.
2499 */
2500static void pmrx_intr_handler(struct adapter *adapter)
2501{
Joe Perches005b5712010-12-14 21:36:53 +00002502 static const struct intr_info pmrx_intr_info[] = {
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05302503 { ZERO_E_CMD_ERROR_F, "PMRX 0-length pcmd", -1, 1 },
2504 { PMRX_FRAMING_ERROR_F, "PMRX framing error", -1, 1 },
2505 { OCSPI_PAR_ERROR_F, "PMRX ocspi parity error", -1, 1 },
2506 { DB_OPTIONS_PAR_ERROR_F, "PMRX db_options parity error",
2507 -1, 1 },
2508 { IESPI_PAR_ERROR_F, "PMRX iespi parity error", -1, 1 },
2509 { PMRX_E_PCMD_PAR_ERROR_F, "PMRX e_pcmd parity error", -1, 1},
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002510 { 0 }
2511 };
2512
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05302513 if (t4_handle_intr_status(adapter, PM_RX_INT_CAUSE_A, pmrx_intr_info))
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002514 t4_fatal_err(adapter);
2515}
2516
2517/*
2518 * CPL switch interrupt handler.
2519 */
2520static void cplsw_intr_handler(struct adapter *adapter)
2521{
Joe Perches005b5712010-12-14 21:36:53 +00002522 static const struct intr_info cplsw_intr_info[] = {
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302523 { CIM_OP_MAP_PERR_F, "CPLSW CIM op_map parity error", -1, 1 },
2524 { CIM_OVFL_ERROR_F, "CPLSW CIM overflow", -1, 1 },
2525 { TP_FRAMING_ERROR_F, "CPLSW TP framing error", -1, 1 },
2526 { SGE_FRAMING_ERROR_F, "CPLSW SGE framing error", -1, 1 },
2527 { CIM_FRAMING_ERROR_F, "CPLSW CIM framing error", -1, 1 },
2528 { ZERO_SWITCH_ERROR_F, "CPLSW no-switch error", -1, 1 },
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002529 { 0 }
2530 };
2531
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302532 if (t4_handle_intr_status(adapter, CPL_INTR_CAUSE_A, cplsw_intr_info))
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002533 t4_fatal_err(adapter);
2534}
2535
2536/*
2537 * LE interrupt handler.
2538 */
2539static void le_intr_handler(struct adapter *adap)
2540{
Joe Perches005b5712010-12-14 21:36:53 +00002541 static const struct intr_info le_intr_info[] = {
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302542 { LIPMISS_F, "LE LIP miss", -1, 0 },
2543 { LIP0_F, "LE 0 LIP error", -1, 0 },
2544 { PARITYERR_F, "LE parity error", -1, 1 },
2545 { UNKNOWNCMD_F, "LE unknown command", -1, 1 },
2546 { REQQPARERR_F, "LE request queue parity error", -1, 1 },
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002547 { 0 }
2548 };
2549
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302550 if (t4_handle_intr_status(adap, LE_DB_INT_CAUSE_A, le_intr_info))
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002551 t4_fatal_err(adap);
2552}
2553
2554/*
2555 * MPS interrupt handler.
2556 */
2557static void mps_intr_handler(struct adapter *adapter)
2558{
Joe Perches005b5712010-12-14 21:36:53 +00002559 static const struct intr_info mps_rx_intr_info[] = {
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002560 { 0xffffff, "MPS Rx parity error", -1, 1 },
2561 { 0 }
2562 };
Joe Perches005b5712010-12-14 21:36:53 +00002563 static const struct intr_info mps_tx_intr_info[] = {
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05302564 { TPFIFO_V(TPFIFO_M), "MPS Tx TP FIFO parity error", -1, 1 },
2565 { NCSIFIFO_F, "MPS Tx NC-SI FIFO parity error", -1, 1 },
2566 { TXDATAFIFO_V(TXDATAFIFO_M), "MPS Tx data FIFO parity error",
2567 -1, 1 },
2568 { TXDESCFIFO_V(TXDESCFIFO_M), "MPS Tx desc FIFO parity error",
2569 -1, 1 },
2570 { BUBBLE_F, "MPS Tx underflow", -1, 1 },
2571 { SECNTERR_F, "MPS Tx SOP/EOP error", -1, 1 },
2572 { FRMERR_F, "MPS Tx framing error", -1, 1 },
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002573 { 0 }
2574 };
Joe Perches005b5712010-12-14 21:36:53 +00002575 static const struct intr_info mps_trc_intr_info[] = {
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05302576 { FILTMEM_V(FILTMEM_M), "MPS TRC filter parity error", -1, 1 },
2577 { PKTFIFO_V(PKTFIFO_M), "MPS TRC packet FIFO parity error",
2578 -1, 1 },
2579 { MISCPERR_F, "MPS TRC misc parity error", -1, 1 },
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002580 { 0 }
2581 };
Joe Perches005b5712010-12-14 21:36:53 +00002582 static const struct intr_info mps_stat_sram_intr_info[] = {
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002583 { 0x1fffff, "MPS statistics SRAM parity error", -1, 1 },
2584 { 0 }
2585 };
Joe Perches005b5712010-12-14 21:36:53 +00002586 static const struct intr_info mps_stat_tx_intr_info[] = {
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002587 { 0xfffff, "MPS statistics Tx FIFO parity error", -1, 1 },
2588 { 0 }
2589 };
Joe Perches005b5712010-12-14 21:36:53 +00002590 static const struct intr_info mps_stat_rx_intr_info[] = {
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002591 { 0xffffff, "MPS statistics Rx FIFO parity error", -1, 1 },
2592 { 0 }
2593 };
Joe Perches005b5712010-12-14 21:36:53 +00002594 static const struct intr_info mps_cls_intr_info[] = {
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05302595 { MATCHSRAM_F, "MPS match SRAM parity error", -1, 1 },
2596 { MATCHTCAM_F, "MPS match TCAM parity error", -1, 1 },
2597 { HASHSRAM_F, "MPS hash SRAM parity error", -1, 1 },
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002598 { 0 }
2599 };
2600
2601 int fat;
2602
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05302603 fat = t4_handle_intr_status(adapter, MPS_RX_PERR_INT_CAUSE_A,
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002604 mps_rx_intr_info) +
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05302605 t4_handle_intr_status(adapter, MPS_TX_INT_CAUSE_A,
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002606 mps_tx_intr_info) +
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05302607 t4_handle_intr_status(adapter, MPS_TRC_INT_CAUSE_A,
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002608 mps_trc_intr_info) +
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05302609 t4_handle_intr_status(adapter, MPS_STAT_PERR_INT_CAUSE_SRAM_A,
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002610 mps_stat_sram_intr_info) +
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05302611 t4_handle_intr_status(adapter, MPS_STAT_PERR_INT_CAUSE_TX_FIFO_A,
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002612 mps_stat_tx_intr_info) +
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05302613 t4_handle_intr_status(adapter, MPS_STAT_PERR_INT_CAUSE_RX_FIFO_A,
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002614 mps_stat_rx_intr_info) +
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05302615 t4_handle_intr_status(adapter, MPS_CLS_INT_CAUSE_A,
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002616 mps_cls_intr_info);
2617
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05302618 t4_write_reg(adapter, MPS_INT_CAUSE_A, 0);
2619 t4_read_reg(adapter, MPS_INT_CAUSE_A); /* flush */
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002620 if (fat)
2621 t4_fatal_err(adapter);
2622}
2623
Hariprasad Shenai89c3a862015-01-05 16:30:45 +05302624#define MEM_INT_MASK (PERR_INT_CAUSE_F | ECC_CE_INT_CAUSE_F | \
2625 ECC_UE_INT_CAUSE_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002626
2627/*
2628 * EDC/MC interrupt handler.
2629 */
2630static void mem_intr_handler(struct adapter *adapter, int idx)
2631{
Hariprasad Shenai822dd8a2014-07-21 20:55:12 +05302632 static const char name[4][7] = { "EDC0", "EDC1", "MC/MC0", "MC1" };
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002633
2634 unsigned int addr, cnt_addr, v;
2635
2636 if (idx <= MEM_EDC1) {
Hariprasad Shenai89c3a862015-01-05 16:30:45 +05302637 addr = EDC_REG(EDC_INT_CAUSE_A, idx);
2638 cnt_addr = EDC_REG(EDC_ECC_STATUS_A, idx);
Hariprasad Shenai822dd8a2014-07-21 20:55:12 +05302639 } else if (idx == MEM_MC) {
2640 if (is_t4(adapter->params.chip)) {
Hariprasad Shenai89c3a862015-01-05 16:30:45 +05302641 addr = MC_INT_CAUSE_A;
2642 cnt_addr = MC_ECC_STATUS_A;
Hariprasad Shenai822dd8a2014-07-21 20:55:12 +05302643 } else {
Hariprasad Shenai89c3a862015-01-05 16:30:45 +05302644 addr = MC_P_INT_CAUSE_A;
2645 cnt_addr = MC_P_ECC_STATUS_A;
Hariprasad Shenai822dd8a2014-07-21 20:55:12 +05302646 }
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002647 } else {
Hariprasad Shenai89c3a862015-01-05 16:30:45 +05302648 addr = MC_REG(MC_P_INT_CAUSE_A, 1);
2649 cnt_addr = MC_REG(MC_P_ECC_STATUS_A, 1);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002650 }
2651
2652 v = t4_read_reg(adapter, addr) & MEM_INT_MASK;
Hariprasad Shenai89c3a862015-01-05 16:30:45 +05302653 if (v & PERR_INT_CAUSE_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002654 dev_alert(adapter->pdev_dev, "%s FIFO parity error\n",
2655 name[idx]);
Hariprasad Shenai89c3a862015-01-05 16:30:45 +05302656 if (v & ECC_CE_INT_CAUSE_F) {
2657 u32 cnt = ECC_CECNT_G(t4_read_reg(adapter, cnt_addr));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002658
Hariprasad Shenai89c3a862015-01-05 16:30:45 +05302659 t4_write_reg(adapter, cnt_addr, ECC_CECNT_V(ECC_CECNT_M));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002660 if (printk_ratelimit())
2661 dev_warn(adapter->pdev_dev,
2662 "%u %s correctable ECC data error%s\n",
2663 cnt, name[idx], cnt > 1 ? "s" : "");
2664 }
Hariprasad Shenai89c3a862015-01-05 16:30:45 +05302665 if (v & ECC_UE_INT_CAUSE_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002666 dev_alert(adapter->pdev_dev,
2667 "%s uncorrectable ECC data error\n", name[idx]);
2668
2669 t4_write_reg(adapter, addr, v);
Hariprasad Shenai89c3a862015-01-05 16:30:45 +05302670 if (v & (PERR_INT_CAUSE_F | ECC_UE_INT_CAUSE_F))
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002671 t4_fatal_err(adapter);
2672}
2673
2674/*
2675 * MA interrupt handler.
2676 */
2677static void ma_intr_handler(struct adapter *adap)
2678{
Hariprasad Shenai89c3a862015-01-05 16:30:45 +05302679 u32 v, status = t4_read_reg(adap, MA_INT_CAUSE_A);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002680
Hariprasad Shenai89c3a862015-01-05 16:30:45 +05302681 if (status & MEM_PERR_INT_CAUSE_F) {
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002682 dev_alert(adap->pdev_dev,
2683 "MA parity error, parity status %#x\n",
Hariprasad Shenai89c3a862015-01-05 16:30:45 +05302684 t4_read_reg(adap, MA_PARITY_ERROR_STATUS1_A));
Hariprasad Shenai9bb59b92014-09-01 19:54:57 +05302685 if (is_t5(adap->params.chip))
2686 dev_alert(adap->pdev_dev,
2687 "MA parity error, parity status %#x\n",
2688 t4_read_reg(adap,
Hariprasad Shenai89c3a862015-01-05 16:30:45 +05302689 MA_PARITY_ERROR_STATUS2_A));
Hariprasad Shenai9bb59b92014-09-01 19:54:57 +05302690 }
Hariprasad Shenai89c3a862015-01-05 16:30:45 +05302691 if (status & MEM_WRAP_INT_CAUSE_F) {
2692 v = t4_read_reg(adap, MA_INT_WRAP_STATUS_A);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002693 dev_alert(adap->pdev_dev, "MA address wrap-around error by "
2694 "client %u to address %#x\n",
Hariprasad Shenai89c3a862015-01-05 16:30:45 +05302695 MEM_WRAP_CLIENT_NUM_G(v),
2696 MEM_WRAP_ADDRESS_G(v) << 4);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002697 }
Hariprasad Shenai89c3a862015-01-05 16:30:45 +05302698 t4_write_reg(adap, MA_INT_CAUSE_A, status);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002699 t4_fatal_err(adap);
2700}
2701
2702/*
2703 * SMB interrupt handler.
2704 */
2705static void smb_intr_handler(struct adapter *adap)
2706{
Joe Perches005b5712010-12-14 21:36:53 +00002707 static const struct intr_info smb_intr_info[] = {
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302708 { MSTTXFIFOPARINT_F, "SMB master Tx FIFO parity error", -1, 1 },
2709 { MSTRXFIFOPARINT_F, "SMB master Rx FIFO parity error", -1, 1 },
2710 { SLVFIFOPARINT_F, "SMB slave FIFO parity error", -1, 1 },
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002711 { 0 }
2712 };
2713
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302714 if (t4_handle_intr_status(adap, SMB_INT_CAUSE_A, smb_intr_info))
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002715 t4_fatal_err(adap);
2716}
2717
2718/*
2719 * NC-SI interrupt handler.
2720 */
2721static void ncsi_intr_handler(struct adapter *adap)
2722{
Joe Perches005b5712010-12-14 21:36:53 +00002723 static const struct intr_info ncsi_intr_info[] = {
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302724 { CIM_DM_PRTY_ERR_F, "NC-SI CIM parity error", -1, 1 },
2725 { MPS_DM_PRTY_ERR_F, "NC-SI MPS parity error", -1, 1 },
2726 { TXFIFO_PRTY_ERR_F, "NC-SI Tx FIFO parity error", -1, 1 },
2727 { RXFIFO_PRTY_ERR_F, "NC-SI Rx FIFO parity error", -1, 1 },
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002728 { 0 }
2729 };
2730
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302731 if (t4_handle_intr_status(adap, NCSI_INT_CAUSE_A, ncsi_intr_info))
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002732 t4_fatal_err(adap);
2733}
2734
2735/*
2736 * XGMAC interrupt handler.
2737 */
2738static void xgmac_intr_handler(struct adapter *adap, int port)
2739{
Santosh Rastapur0a57a532013-03-14 05:08:49 +00002740 u32 v, int_cause_reg;
2741
Hariprasad Shenaid14807d2013-12-03 17:05:56 +05302742 if (is_t4(adap->params.chip))
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302743 int_cause_reg = PORT_REG(port, XGMAC_PORT_INT_CAUSE_A);
Santosh Rastapur0a57a532013-03-14 05:08:49 +00002744 else
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302745 int_cause_reg = T5_PORT_REG(port, MAC_PORT_INT_CAUSE_A);
Santosh Rastapur0a57a532013-03-14 05:08:49 +00002746
2747 v = t4_read_reg(adap, int_cause_reg);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002748
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302749 v &= TXFIFO_PRTY_ERR_F | RXFIFO_PRTY_ERR_F;
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002750 if (!v)
2751 return;
2752
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302753 if (v & TXFIFO_PRTY_ERR_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002754 dev_alert(adap->pdev_dev, "XGMAC %d Tx FIFO parity error\n",
2755 port);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302756 if (v & RXFIFO_PRTY_ERR_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002757 dev_alert(adap->pdev_dev, "XGMAC %d Rx FIFO parity error\n",
2758 port);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302759 t4_write_reg(adap, PORT_REG(port, XGMAC_PORT_INT_CAUSE_A), v);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002760 t4_fatal_err(adap);
2761}
2762
2763/*
2764 * PL interrupt handler.
2765 */
2766static void pl_intr_handler(struct adapter *adap)
2767{
Joe Perches005b5712010-12-14 21:36:53 +00002768 static const struct intr_info pl_intr_info[] = {
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302769 { FATALPERR_F, "T4 fatal parity error", -1, 1 },
2770 { PERRVFID_F, "PL VFID_MAP parity error", -1, 1 },
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002771 { 0 }
2772 };
2773
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302774 if (t4_handle_intr_status(adap, PL_PL_INT_CAUSE_A, pl_intr_info))
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002775 t4_fatal_err(adap);
2776}
2777
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302778#define PF_INTR_MASK (PFSW_F)
2779#define GLBL_INTR_MASK (CIM_F | MPS_F | PL_F | PCIE_F | MC_F | EDC0_F | \
2780 EDC1_F | LE_F | TP_F | MA_F | PM_TX_F | PM_RX_F | ULP_RX_F | \
2781 CPL_SWITCH_F | SGE_F | ULP_TX_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002782
2783/**
2784 * t4_slow_intr_handler - control path interrupt handler
2785 * @adapter: the adapter
2786 *
2787 * T4 interrupt handler for non-data global interrupt events, e.g., errors.
2788 * The designation 'slow' is because it involves register reads, while
2789 * data interrupts typically don't involve any MMIOs.
2790 */
2791int t4_slow_intr_handler(struct adapter *adapter)
2792{
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302793 u32 cause = t4_read_reg(adapter, PL_INT_CAUSE_A);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002794
2795 if (!(cause & GLBL_INTR_MASK))
2796 return 0;
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302797 if (cause & CIM_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002798 cim_intr_handler(adapter);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302799 if (cause & MPS_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002800 mps_intr_handler(adapter);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302801 if (cause & NCSI_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002802 ncsi_intr_handler(adapter);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302803 if (cause & PL_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002804 pl_intr_handler(adapter);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302805 if (cause & SMB_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002806 smb_intr_handler(adapter);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302807 if (cause & XGMAC0_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002808 xgmac_intr_handler(adapter, 0);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302809 if (cause & XGMAC1_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002810 xgmac_intr_handler(adapter, 1);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302811 if (cause & XGMAC_KR0_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002812 xgmac_intr_handler(adapter, 2);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302813 if (cause & XGMAC_KR1_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002814 xgmac_intr_handler(adapter, 3);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302815 if (cause & PCIE_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002816 pcie_intr_handler(adapter);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302817 if (cause & MC_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002818 mem_intr_handler(adapter, MEM_MC);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302819 if (!is_t4(adapter->params.chip) && (cause & MC1_S))
Hariprasad Shenai822dd8a2014-07-21 20:55:12 +05302820 mem_intr_handler(adapter, MEM_MC1);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302821 if (cause & EDC0_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002822 mem_intr_handler(adapter, MEM_EDC0);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302823 if (cause & EDC1_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002824 mem_intr_handler(adapter, MEM_EDC1);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302825 if (cause & LE_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002826 le_intr_handler(adapter);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302827 if (cause & TP_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002828 tp_intr_handler(adapter);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302829 if (cause & MA_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002830 ma_intr_handler(adapter);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302831 if (cause & PM_TX_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002832 pmtx_intr_handler(adapter);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302833 if (cause & PM_RX_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002834 pmrx_intr_handler(adapter);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302835 if (cause & ULP_RX_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002836 ulprx_intr_handler(adapter);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302837 if (cause & CPL_SWITCH_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002838 cplsw_intr_handler(adapter);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302839 if (cause & SGE_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002840 sge_intr_handler(adapter);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302841 if (cause & ULP_TX_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002842 ulptx_intr_handler(adapter);
2843
2844 /* Clear the interrupts just processed for which we are the master. */
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302845 t4_write_reg(adapter, PL_INT_CAUSE_A, cause & GLBL_INTR_MASK);
2846 (void)t4_read_reg(adapter, PL_INT_CAUSE_A); /* flush */
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002847 return 1;
2848}
2849
2850/**
2851 * t4_intr_enable - enable interrupts
2852 * @adapter: the adapter whose interrupts should be enabled
2853 *
2854 * Enable PF-specific interrupts for the calling function and the top-level
2855 * interrupt concentrator for global interrupts. Interrupts are already
2856 * enabled at each module, here we just enable the roots of the interrupt
2857 * hierarchies.
2858 *
2859 * Note: this function should be called only when the driver manages
2860 * non PF-specific interrupts from the various HW modules. Only one PCI
2861 * function at a time should be doing this.
2862 */
2863void t4_intr_enable(struct adapter *adapter)
2864{
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302865 u32 pf = SOURCEPF_G(t4_read_reg(adapter, PL_WHOAMI_A));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002866
Hariprasad Shenaif612b812015-01-05 16:30:43 +05302867 t4_write_reg(adapter, SGE_INT_ENABLE3_A, ERR_CPL_EXCEED_IQE_SIZE_F |
2868 ERR_INVALID_CIDX_INC_F | ERR_CPL_OPCODE_0_F |
2869 ERR_DROPPED_DB_F | ERR_DATA_CPL_ON_HIGH_QID1_F |
2870 ERR_DATA_CPL_ON_HIGH_QID0_F | ERR_BAD_DB_PIDX3_F |
2871 ERR_BAD_DB_PIDX2_F | ERR_BAD_DB_PIDX1_F |
2872 ERR_BAD_DB_PIDX0_F | ERR_ING_CTXT_PRIO_F |
2873 ERR_EGR_CTXT_PRIO_F | INGRESS_SIZE_ERR_F |
2874 DBFIFO_HP_INT_F | DBFIFO_LP_INT_F |
2875 EGRESS_SIZE_ERR_F);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302876 t4_write_reg(adapter, MYPF_REG(PL_PF_INT_ENABLE_A), PF_INTR_MASK);
2877 t4_set_reg_field(adapter, PL_INT_MAP0_A, 0, 1 << pf);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002878}
2879
2880/**
2881 * t4_intr_disable - disable interrupts
2882 * @adapter: the adapter whose interrupts should be disabled
2883 *
2884 * Disable interrupts. We only disable the top-level interrupt
2885 * concentrators. The caller must be a PCI function managing global
2886 * interrupts.
2887 */
2888void t4_intr_disable(struct adapter *adapter)
2889{
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302890 u32 pf = SOURCEPF_G(t4_read_reg(adapter, PL_WHOAMI_A));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002891
Hariprasad Shenai0d804332015-01-05 16:30:47 +05302892 t4_write_reg(adapter, MYPF_REG(PL_PF_INT_ENABLE_A), 0);
2893 t4_set_reg_field(adapter, PL_INT_MAP0_A, 1 << pf, 0);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002894}
2895
2896/**
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002897 * hash_mac_addr - return the hash value of a MAC address
2898 * @addr: the 48-bit Ethernet MAC address
2899 *
2900 * Hashes a MAC address according to the hash function used by HW inexact
2901 * (hash) address matching.
2902 */
2903static int hash_mac_addr(const u8 *addr)
2904{
2905 u32 a = ((u32)addr[0] << 16) | ((u32)addr[1] << 8) | addr[2];
2906 u32 b = ((u32)addr[3] << 16) | ((u32)addr[4] << 8) | addr[5];
2907 a ^= b;
2908 a ^= (a >> 12);
2909 a ^= (a >> 6);
2910 return a & 0x3f;
2911}
2912
2913/**
2914 * t4_config_rss_range - configure a portion of the RSS mapping table
2915 * @adapter: the adapter
2916 * @mbox: mbox to use for the FW command
2917 * @viid: virtual interface whose RSS subtable is to be written
2918 * @start: start entry in the table to write
2919 * @n: how many table entries to write
2920 * @rspq: values for the response queue lookup table
2921 * @nrspq: number of values in @rspq
2922 *
2923 * Programs the selected part of the VI's RSS mapping table with the
2924 * provided values. If @nrspq < @n the supplied values are used repeatedly
2925 * until the full table range is populated.
2926 *
2927 * The caller must ensure the values in @rspq are in the range allowed for
2928 * @viid.
2929 */
2930int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid,
2931 int start, int n, const u16 *rspq, unsigned int nrspq)
2932{
2933 int ret;
2934 const u16 *rsp = rspq;
2935 const u16 *rsp_end = rspq + nrspq;
2936 struct fw_rss_ind_tbl_cmd cmd;
2937
2938 memset(&cmd, 0, sizeof(cmd));
Hariprasad Shenaif404f802015-05-19 18:20:44 +05302939 cmd.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_RSS_IND_TBL_CMD) |
Hariprasad Shenaie2ac9622014-11-07 09:35:25 +05302940 FW_CMD_REQUEST_F | FW_CMD_WRITE_F |
Hariprasad Shenaib2e1a3f2014-11-21 12:52:05 +05302941 FW_RSS_IND_TBL_CMD_VIID_V(viid));
Hariprasad Shenaif404f802015-05-19 18:20:44 +05302942 cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002943
2944 /* each fw_rss_ind_tbl_cmd takes up to 32 entries */
2945 while (n > 0) {
2946 int nq = min(n, 32);
2947 __be32 *qp = &cmd.iq0_to_iq2;
2948
Hariprasad Shenaif404f802015-05-19 18:20:44 +05302949 cmd.niqid = cpu_to_be16(nq);
2950 cmd.startidx = cpu_to_be16(start);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002951
2952 start += nq;
2953 n -= nq;
2954
2955 while (nq > 0) {
2956 unsigned int v;
2957
Hariprasad Shenaib2e1a3f2014-11-21 12:52:05 +05302958 v = FW_RSS_IND_TBL_CMD_IQ0_V(*rsp);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002959 if (++rsp >= rsp_end)
2960 rsp = rspq;
Hariprasad Shenaib2e1a3f2014-11-21 12:52:05 +05302961 v |= FW_RSS_IND_TBL_CMD_IQ1_V(*rsp);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002962 if (++rsp >= rsp_end)
2963 rsp = rspq;
Hariprasad Shenaib2e1a3f2014-11-21 12:52:05 +05302964 v |= FW_RSS_IND_TBL_CMD_IQ2_V(*rsp);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002965 if (++rsp >= rsp_end)
2966 rsp = rspq;
2967
Hariprasad Shenaif404f802015-05-19 18:20:44 +05302968 *qp++ = cpu_to_be32(v);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002969 nq -= 3;
2970 }
2971
2972 ret = t4_wr_mbox(adapter, mbox, &cmd, sizeof(cmd), NULL);
2973 if (ret)
2974 return ret;
2975 }
2976 return 0;
2977}
2978
2979/**
2980 * t4_config_glbl_rss - configure the global RSS mode
2981 * @adapter: the adapter
2982 * @mbox: mbox to use for the FW command
2983 * @mode: global RSS mode
2984 * @flags: mode-specific flags
2985 *
2986 * Sets the global RSS mode.
2987 */
2988int t4_config_glbl_rss(struct adapter *adapter, int mbox, unsigned int mode,
2989 unsigned int flags)
2990{
2991 struct fw_rss_glb_config_cmd c;
2992
2993 memset(&c, 0, sizeof(c));
Hariprasad Shenaif404f802015-05-19 18:20:44 +05302994 c.op_to_write = cpu_to_be32(FW_CMD_OP_V(FW_RSS_GLB_CONFIG_CMD) |
2995 FW_CMD_REQUEST_F | FW_CMD_WRITE_F);
2996 c.retval_len16 = cpu_to_be32(FW_LEN16(c));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00002997 if (mode == FW_RSS_GLB_CONFIG_CMD_MODE_MANUAL) {
Hariprasad Shenaif404f802015-05-19 18:20:44 +05302998 c.u.manual.mode_pkd =
2999 cpu_to_be32(FW_RSS_GLB_CONFIG_CMD_MODE_V(mode));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003000 } else if (mode == FW_RSS_GLB_CONFIG_CMD_MODE_BASICVIRTUAL) {
3001 c.u.basicvirtual.mode_pkd =
Hariprasad Shenaif404f802015-05-19 18:20:44 +05303002 cpu_to_be32(FW_RSS_GLB_CONFIG_CMD_MODE_V(mode));
3003 c.u.basicvirtual.synmapen_to_hashtoeplitz = cpu_to_be32(flags);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003004 } else
3005 return -EINVAL;
3006 return t4_wr_mbox(adapter, mbox, &c, sizeof(c), NULL);
3007}
3008
Hariprasad Shenaic035e182015-05-06 19:48:37 +05303009/**
3010 * t4_config_vi_rss - configure per VI RSS settings
3011 * @adapter: the adapter
3012 * @mbox: mbox to use for the FW command
3013 * @viid: the VI id
3014 * @flags: RSS flags
3015 * @defq: id of the default RSS queue for the VI.
3016 *
3017 * Configures VI-specific RSS properties.
3018 */
3019int t4_config_vi_rss(struct adapter *adapter, int mbox, unsigned int viid,
3020 unsigned int flags, unsigned int defq)
3021{
3022 struct fw_rss_vi_config_cmd c;
3023
3024 memset(&c, 0, sizeof(c));
3025 c.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_RSS_VI_CONFIG_CMD) |
3026 FW_CMD_REQUEST_F | FW_CMD_WRITE_F |
3027 FW_RSS_VI_CONFIG_CMD_VIID_V(viid));
3028 c.retval_len16 = cpu_to_be32(FW_LEN16(c));
3029 c.u.basicvirtual.defaultq_to_udpen = cpu_to_be32(flags |
3030 FW_RSS_VI_CONFIG_CMD_DEFAULTQ_V(defq));
3031 return t4_wr_mbox(adapter, mbox, &c, sizeof(c), NULL);
3032}
3033
Hariprasad Shenai688ea5f2015-01-20 12:02:21 +05303034/* Read an RSS table row */
3035static int rd_rss_row(struct adapter *adap, int row, u32 *val)
3036{
3037 t4_write_reg(adap, TP_RSS_LKP_TABLE_A, 0xfff00000 | row);
3038 return t4_wait_op_done_val(adap, TP_RSS_LKP_TABLE_A, LKPTBLROWVLD_F, 1,
3039 5, 0, val);
3040}
3041
3042/**
3043 * t4_read_rss - read the contents of the RSS mapping table
3044 * @adapter: the adapter
3045 * @map: holds the contents of the RSS mapping table
3046 *
3047 * Reads the contents of the RSS hash->queue mapping table.
3048 */
3049int t4_read_rss(struct adapter *adapter, u16 *map)
3050{
3051 u32 val;
3052 int i, ret;
3053
3054 for (i = 0; i < RSS_NENTRIES / 2; ++i) {
3055 ret = rd_rss_row(adapter, i, &val);
3056 if (ret)
3057 return ret;
3058 *map++ = LKPTBLQUEUE0_G(val);
3059 *map++ = LKPTBLQUEUE1_G(val);
3060 }
3061 return 0;
3062}
3063
3064/**
3065 * t4_read_rss_key - read the global RSS key
3066 * @adap: the adapter
3067 * @key: 10-entry array holding the 320-bit RSS key
3068 *
3069 * Reads the global 320-bit RSS key.
3070 */
3071void t4_read_rss_key(struct adapter *adap, u32 *key)
3072{
3073 t4_read_indirect(adap, TP_PIO_ADDR_A, TP_PIO_DATA_A, key, 10,
3074 TP_RSS_SECRET_KEY0_A);
3075}
3076
3077/**
3078 * t4_write_rss_key - program one of the RSS keys
3079 * @adap: the adapter
3080 * @key: 10-entry array holding the 320-bit RSS key
3081 * @idx: which RSS key to write
3082 *
3083 * Writes one of the RSS keys with the given 320-bit value. If @idx is
3084 * 0..15 the corresponding entry in the RSS key table is written,
3085 * otherwise the global RSS key is written.
3086 */
3087void t4_write_rss_key(struct adapter *adap, const u32 *key, int idx)
3088{
3089 t4_write_indirect(adap, TP_PIO_ADDR_A, TP_PIO_DATA_A, key, 10,
3090 TP_RSS_SECRET_KEY0_A);
3091 if (idx >= 0 && idx < 16)
3092 t4_write_reg(adap, TP_RSS_CONFIG_VRT_A,
3093 KEYWRADDR_V(idx) | KEYWREN_F);
3094}
3095
3096/**
3097 * t4_read_rss_pf_config - read PF RSS Configuration Table
3098 * @adapter: the adapter
3099 * @index: the entry in the PF RSS table to read
3100 * @valp: where to store the returned value
3101 *
3102 * Reads the PF RSS Configuration Table at the specified index and returns
3103 * the value found there.
3104 */
3105void t4_read_rss_pf_config(struct adapter *adapter, unsigned int index,
3106 u32 *valp)
3107{
3108 t4_read_indirect(adapter, TP_PIO_ADDR_A, TP_PIO_DATA_A,
3109 valp, 1, TP_RSS_PF0_CONFIG_A + index);
3110}
3111
3112/**
3113 * t4_read_rss_vf_config - read VF RSS Configuration Table
3114 * @adapter: the adapter
3115 * @index: the entry in the VF RSS table to read
3116 * @vfl: where to store the returned VFL
3117 * @vfh: where to store the returned VFH
3118 *
3119 * Reads the VF RSS Configuration Table at the specified index and returns
3120 * the (VFL, VFH) values found there.
3121 */
3122void t4_read_rss_vf_config(struct adapter *adapter, unsigned int index,
3123 u32 *vfl, u32 *vfh)
3124{
3125 u32 vrt, mask, data;
3126
3127 mask = VFWRADDR_V(VFWRADDR_M);
3128 data = VFWRADDR_V(index);
3129
3130 /* Request that the index'th VF Table values be read into VFL/VFH.
3131 */
3132 vrt = t4_read_reg(adapter, TP_RSS_CONFIG_VRT_A);
3133 vrt &= ~(VFRDRG_F | VFWREN_F | KEYWREN_F | mask);
3134 vrt |= data | VFRDEN_F;
3135 t4_write_reg(adapter, TP_RSS_CONFIG_VRT_A, vrt);
3136
3137 /* Grab the VFL/VFH values ...
3138 */
3139 t4_read_indirect(adapter, TP_PIO_ADDR_A, TP_PIO_DATA_A,
3140 vfl, 1, TP_RSS_VFL_CONFIG_A);
3141 t4_read_indirect(adapter, TP_PIO_ADDR_A, TP_PIO_DATA_A,
3142 vfh, 1, TP_RSS_VFH_CONFIG_A);
3143}
3144
3145/**
3146 * t4_read_rss_pf_map - read PF RSS Map
3147 * @adapter: the adapter
3148 *
3149 * Reads the PF RSS Map register and returns its value.
3150 */
3151u32 t4_read_rss_pf_map(struct adapter *adapter)
3152{
3153 u32 pfmap;
3154
3155 t4_read_indirect(adapter, TP_PIO_ADDR_A, TP_PIO_DATA_A,
3156 &pfmap, 1, TP_RSS_PF_MAP_A);
3157 return pfmap;
3158}
3159
3160/**
3161 * t4_read_rss_pf_mask - read PF RSS Mask
3162 * @adapter: the adapter
3163 *
3164 * Reads the PF RSS Mask register and returns its value.
3165 */
3166u32 t4_read_rss_pf_mask(struct adapter *adapter)
3167{
3168 u32 pfmask;
3169
3170 t4_read_indirect(adapter, TP_PIO_ADDR_A, TP_PIO_DATA_A,
3171 &pfmask, 1, TP_RSS_PF_MSK_A);
3172 return pfmask;
3173}
3174
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003175/**
3176 * t4_tp_get_tcp_stats - read TP's TCP MIB counters
3177 * @adap: the adapter
3178 * @v4: holds the TCP/IP counter values
3179 * @v6: holds the TCP/IPv6 counter values
3180 *
3181 * Returns the values of TP's TCP/IP and TCP/IPv6 MIB counters.
3182 * Either @v4 or @v6 may be %NULL to skip the corresponding stats.
3183 */
3184void t4_tp_get_tcp_stats(struct adapter *adap, struct tp_tcp_stats *v4,
3185 struct tp_tcp_stats *v6)
3186{
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05303187 u32 val[TP_MIB_TCP_RXT_SEG_LO_A - TP_MIB_TCP_OUT_RST_A + 1];
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003188
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05303189#define STAT_IDX(x) ((TP_MIB_TCP_##x##_A) - TP_MIB_TCP_OUT_RST_A)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003190#define STAT(x) val[STAT_IDX(x)]
3191#define STAT64(x) (((u64)STAT(x##_HI) << 32) | STAT(x##_LO))
3192
3193 if (v4) {
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05303194 t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A, val,
3195 ARRAY_SIZE(val), TP_MIB_TCP_OUT_RST_A);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003196 v4->tcpOutRsts = STAT(OUT_RST);
3197 v4->tcpInSegs = STAT64(IN_SEG);
3198 v4->tcpOutSegs = STAT64(OUT_SEG);
3199 v4->tcpRetransSegs = STAT64(RXT_SEG);
3200 }
3201 if (v6) {
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05303202 t4_read_indirect(adap, TP_MIB_INDEX_A, TP_MIB_DATA_A, val,
3203 ARRAY_SIZE(val), TP_MIB_TCP_V6OUT_RST_A);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003204 v6->tcpOutRsts = STAT(OUT_RST);
3205 v6->tcpInSegs = STAT64(IN_SEG);
3206 v6->tcpOutSegs = STAT64(OUT_SEG);
3207 v6->tcpRetransSegs = STAT64(RXT_SEG);
3208 }
3209#undef STAT64
3210#undef STAT
3211#undef STAT_IDX
3212}
3213
3214/**
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003215 * t4_read_mtu_tbl - returns the values in the HW path MTU table
3216 * @adap: the adapter
3217 * @mtus: where to store the MTU values
3218 * @mtu_log: where to store the MTU base-2 log (may be %NULL)
3219 *
3220 * Reads the HW path MTU table.
3221 */
3222void t4_read_mtu_tbl(struct adapter *adap, u16 *mtus, u8 *mtu_log)
3223{
3224 u32 v;
3225 int i;
3226
3227 for (i = 0; i < NMTUS; ++i) {
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05303228 t4_write_reg(adap, TP_MTU_TABLE_A,
3229 MTUINDEX_V(0xff) | MTUVALUE_V(i));
3230 v = t4_read_reg(adap, TP_MTU_TABLE_A);
3231 mtus[i] = MTUVALUE_G(v);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003232 if (mtu_log)
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05303233 mtu_log[i] = MTUWIDTH_G(v);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003234 }
3235}
3236
3237/**
Hariprasad Shenaibad43792015-02-06 19:32:55 +05303238 * t4_read_cong_tbl - reads the congestion control table
3239 * @adap: the adapter
3240 * @incr: where to store the alpha values
3241 *
3242 * Reads the additive increments programmed into the HW congestion
3243 * control table.
3244 */
3245void t4_read_cong_tbl(struct adapter *adap, u16 incr[NMTUS][NCCTRL_WIN])
3246{
3247 unsigned int mtu, w;
3248
3249 for (mtu = 0; mtu < NMTUS; ++mtu)
3250 for (w = 0; w < NCCTRL_WIN; ++w) {
3251 t4_write_reg(adap, TP_CCTRL_TABLE_A,
3252 ROWINDEX_V(0xffff) | (mtu << 5) | w);
3253 incr[mtu][w] = (u16)t4_read_reg(adap,
3254 TP_CCTRL_TABLE_A) & 0x1fff;
3255 }
3256}
3257
3258/**
Vipul Pandya636f9d32012-09-26 02:39:39 +00003259 * t4_tp_wr_bits_indirect - set/clear bits in an indirect TP register
3260 * @adap: the adapter
3261 * @addr: the indirect TP register address
3262 * @mask: specifies the field within the register to modify
3263 * @val: new value for the field
3264 *
3265 * Sets a field of an indirect TP register to the given value.
3266 */
3267void t4_tp_wr_bits_indirect(struct adapter *adap, unsigned int addr,
3268 unsigned int mask, unsigned int val)
3269{
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05303270 t4_write_reg(adap, TP_PIO_ADDR_A, addr);
3271 val |= t4_read_reg(adap, TP_PIO_DATA_A) & ~mask;
3272 t4_write_reg(adap, TP_PIO_DATA_A, val);
Vipul Pandya636f9d32012-09-26 02:39:39 +00003273}
3274
3275/**
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003276 * init_cong_ctrl - initialize congestion control parameters
3277 * @a: the alpha values for congestion control
3278 * @b: the beta values for congestion control
3279 *
3280 * Initialize the congestion control parameters.
3281 */
Bill Pemberton91744942012-12-03 09:23:02 -05003282static void init_cong_ctrl(unsigned short *a, unsigned short *b)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003283{
3284 a[0] = a[1] = a[2] = a[3] = a[4] = a[5] = a[6] = a[7] = a[8] = 1;
3285 a[9] = 2;
3286 a[10] = 3;
3287 a[11] = 4;
3288 a[12] = 5;
3289 a[13] = 6;
3290 a[14] = 7;
3291 a[15] = 8;
3292 a[16] = 9;
3293 a[17] = 10;
3294 a[18] = 14;
3295 a[19] = 17;
3296 a[20] = 21;
3297 a[21] = 25;
3298 a[22] = 30;
3299 a[23] = 35;
3300 a[24] = 45;
3301 a[25] = 60;
3302 a[26] = 80;
3303 a[27] = 100;
3304 a[28] = 200;
3305 a[29] = 300;
3306 a[30] = 400;
3307 a[31] = 500;
3308
3309 b[0] = b[1] = b[2] = b[3] = b[4] = b[5] = b[6] = b[7] = b[8] = 0;
3310 b[9] = b[10] = 1;
3311 b[11] = b[12] = 2;
3312 b[13] = b[14] = b[15] = b[16] = 3;
3313 b[17] = b[18] = b[19] = b[20] = b[21] = 4;
3314 b[22] = b[23] = b[24] = b[25] = b[26] = b[27] = 5;
3315 b[28] = b[29] = 6;
3316 b[30] = b[31] = 7;
3317}
3318
3319/* The minimum additive increment value for the congestion control table */
3320#define CC_MIN_INCR 2U
3321
3322/**
3323 * t4_load_mtus - write the MTU and congestion control HW tables
3324 * @adap: the adapter
3325 * @mtus: the values for the MTU table
3326 * @alpha: the values for the congestion control alpha parameter
3327 * @beta: the values for the congestion control beta parameter
3328 *
3329 * Write the HW MTU table with the supplied MTUs and the high-speed
3330 * congestion control table with the supplied alpha, beta, and MTUs.
3331 * We write the two tables together because the additive increments
3332 * depend on the MTUs.
3333 */
3334void t4_load_mtus(struct adapter *adap, const unsigned short *mtus,
3335 const unsigned short *alpha, const unsigned short *beta)
3336{
3337 static const unsigned int avg_pkts[NCCTRL_WIN] = {
3338 2, 6, 10, 14, 20, 28, 40, 56, 80, 112, 160, 224, 320, 448, 640,
3339 896, 1281, 1792, 2560, 3584, 5120, 7168, 10240, 14336, 20480,
3340 28672, 40960, 57344, 81920, 114688, 163840, 229376
3341 };
3342
3343 unsigned int i, w;
3344
3345 for (i = 0; i < NMTUS; ++i) {
3346 unsigned int mtu = mtus[i];
3347 unsigned int log2 = fls(mtu);
3348
3349 if (!(mtu & ((1 << log2) >> 2))) /* round */
3350 log2--;
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05303351 t4_write_reg(adap, TP_MTU_TABLE_A, MTUINDEX_V(i) |
3352 MTUWIDTH_V(log2) | MTUVALUE_V(mtu));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003353
3354 for (w = 0; w < NCCTRL_WIN; ++w) {
3355 unsigned int inc;
3356
3357 inc = max(((mtu - 40) * alpha[w]) / avg_pkts[w],
3358 CC_MIN_INCR);
3359
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05303360 t4_write_reg(adap, TP_CCTRL_TABLE_A, (i << 21) |
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003361 (w << 16) | (beta[w] << 13) | inc);
3362 }
3363 }
3364}
3365
3366/**
Hariprasad Shenaib3bbe362015-01-27 13:47:48 +05303367 * t4_pmtx_get_stats - returns the HW stats from PMTX
3368 * @adap: the adapter
3369 * @cnt: where to store the count statistics
3370 * @cycles: where to store the cycle statistics
3371 *
3372 * Returns performance statistics from PMTX.
3373 */
3374void t4_pmtx_get_stats(struct adapter *adap, u32 cnt[], u64 cycles[])
3375{
3376 int i;
3377 u32 data[2];
3378
3379 for (i = 0; i < PM_NSTATS; i++) {
3380 t4_write_reg(adap, PM_TX_STAT_CONFIG_A, i + 1);
3381 cnt[i] = t4_read_reg(adap, PM_TX_STAT_COUNT_A);
3382 if (is_t4(adap->params.chip)) {
3383 cycles[i] = t4_read_reg64(adap, PM_TX_STAT_LSB_A);
3384 } else {
3385 t4_read_indirect(adap, PM_TX_DBG_CTRL_A,
3386 PM_TX_DBG_DATA_A, data, 2,
3387 PM_TX_DBG_STAT_MSB_A);
3388 cycles[i] = (((u64)data[0] << 32) | data[1]);
3389 }
3390 }
3391}
3392
3393/**
3394 * t4_pmrx_get_stats - returns the HW stats from PMRX
3395 * @adap: the adapter
3396 * @cnt: where to store the count statistics
3397 * @cycles: where to store the cycle statistics
3398 *
3399 * Returns performance statistics from PMRX.
3400 */
3401void t4_pmrx_get_stats(struct adapter *adap, u32 cnt[], u64 cycles[])
3402{
3403 int i;
3404 u32 data[2];
3405
3406 for (i = 0; i < PM_NSTATS; i++) {
3407 t4_write_reg(adap, PM_RX_STAT_CONFIG_A, i + 1);
3408 cnt[i] = t4_read_reg(adap, PM_RX_STAT_COUNT_A);
3409 if (is_t4(adap->params.chip)) {
3410 cycles[i] = t4_read_reg64(adap, PM_RX_STAT_LSB_A);
3411 } else {
3412 t4_read_indirect(adap, PM_RX_DBG_CTRL_A,
3413 PM_RX_DBG_DATA_A, data, 2,
3414 PM_RX_DBG_STAT_MSB_A);
3415 cycles[i] = (((u64)data[0] << 32) | data[1]);
3416 }
3417 }
3418}
3419
3420/**
Hariprasad Shenai145ef8a2015-05-05 14:59:52 +05303421 * t4_get_mps_bg_map - return the buffer groups associated with a port
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003422 * @adap: the adapter
3423 * @idx: the port index
3424 *
3425 * Returns a bitmap indicating which MPS buffer groups are associated
3426 * with the given port. Bit i is set if buffer group i is used by the
3427 * port.
3428 */
Hariprasad Shenai145ef8a2015-05-05 14:59:52 +05303429unsigned int t4_get_mps_bg_map(struct adapter *adap, int idx)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003430{
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05303431 u32 n = NUMPORTS_G(t4_read_reg(adap, MPS_CMN_CTL_A));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003432
3433 if (n == 0)
3434 return idx == 0 ? 0xf : 0;
3435 if (n == 1)
3436 return idx < 2 ? (3 << (2 * idx)) : 0;
3437 return 1 << idx;
3438}
3439
3440/**
Kumar Sanghvi72aca4b2014-02-18 17:56:08 +05303441 * t4_get_port_type_description - return Port Type string description
3442 * @port_type: firmware Port Type enumeration
3443 */
3444const char *t4_get_port_type_description(enum fw_port_type port_type)
3445{
3446 static const char *const port_type_description[] = {
3447 "R XFI",
3448 "R XAUI",
3449 "T SGMII",
3450 "T XFI",
3451 "T XAUI",
3452 "KX4",
3453 "CX4",
3454 "KX",
3455 "KR",
3456 "R SFP+",
3457 "KR/KX",
3458 "KR/KX/KX4",
3459 "R QSFP_10G",
Hariprasad Shenai5aa80e52014-12-17 17:36:00 +05303460 "R QSA",
Kumar Sanghvi72aca4b2014-02-18 17:56:08 +05303461 "R QSFP",
3462 "R BP40_BA",
3463 };
3464
3465 if (port_type < ARRAY_SIZE(port_type_description))
3466 return port_type_description[port_type];
3467 return "UNKNOWN";
3468}
3469
3470/**
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003471 * t4_get_port_stats - collect port statistics
3472 * @adap: the adapter
3473 * @idx: the port index
3474 * @p: the stats structure to fill
3475 *
3476 * Collect statistics related to the given port from HW.
3477 */
3478void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p)
3479{
Hariprasad Shenai145ef8a2015-05-05 14:59:52 +05303480 u32 bgmap = t4_get_mps_bg_map(adap, idx);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003481
3482#define GET_STAT(name) \
Santosh Rastapur0a57a532013-03-14 05:08:49 +00003483 t4_read_reg64(adap, \
Hariprasad Shenaid14807d2013-12-03 17:05:56 +05303484 (is_t4(adap->params.chip) ? PORT_REG(idx, MPS_PORT_STAT_##name##_L) : \
Santosh Rastapur0a57a532013-03-14 05:08:49 +00003485 T5_PORT_REG(idx, MPS_PORT_STAT_##name##_L)))
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003486#define GET_STAT_COM(name) t4_read_reg64(adap, MPS_STAT_##name##_L)
3487
3488 p->tx_octets = GET_STAT(TX_PORT_BYTES);
3489 p->tx_frames = GET_STAT(TX_PORT_FRAMES);
3490 p->tx_bcast_frames = GET_STAT(TX_PORT_BCAST);
3491 p->tx_mcast_frames = GET_STAT(TX_PORT_MCAST);
3492 p->tx_ucast_frames = GET_STAT(TX_PORT_UCAST);
3493 p->tx_error_frames = GET_STAT(TX_PORT_ERROR);
3494 p->tx_frames_64 = GET_STAT(TX_PORT_64B);
3495 p->tx_frames_65_127 = GET_STAT(TX_PORT_65B_127B);
3496 p->tx_frames_128_255 = GET_STAT(TX_PORT_128B_255B);
3497 p->tx_frames_256_511 = GET_STAT(TX_PORT_256B_511B);
3498 p->tx_frames_512_1023 = GET_STAT(TX_PORT_512B_1023B);
3499 p->tx_frames_1024_1518 = GET_STAT(TX_PORT_1024B_1518B);
3500 p->tx_frames_1519_max = GET_STAT(TX_PORT_1519B_MAX);
3501 p->tx_drop = GET_STAT(TX_PORT_DROP);
3502 p->tx_pause = GET_STAT(TX_PORT_PAUSE);
3503 p->tx_ppp0 = GET_STAT(TX_PORT_PPP0);
3504 p->tx_ppp1 = GET_STAT(TX_PORT_PPP1);
3505 p->tx_ppp2 = GET_STAT(TX_PORT_PPP2);
3506 p->tx_ppp3 = GET_STAT(TX_PORT_PPP3);
3507 p->tx_ppp4 = GET_STAT(TX_PORT_PPP4);
3508 p->tx_ppp5 = GET_STAT(TX_PORT_PPP5);
3509 p->tx_ppp6 = GET_STAT(TX_PORT_PPP6);
3510 p->tx_ppp7 = GET_STAT(TX_PORT_PPP7);
3511
3512 p->rx_octets = GET_STAT(RX_PORT_BYTES);
3513 p->rx_frames = GET_STAT(RX_PORT_FRAMES);
3514 p->rx_bcast_frames = GET_STAT(RX_PORT_BCAST);
3515 p->rx_mcast_frames = GET_STAT(RX_PORT_MCAST);
3516 p->rx_ucast_frames = GET_STAT(RX_PORT_UCAST);
3517 p->rx_too_long = GET_STAT(RX_PORT_MTU_ERROR);
3518 p->rx_jabber = GET_STAT(RX_PORT_MTU_CRC_ERROR);
3519 p->rx_fcs_err = GET_STAT(RX_PORT_CRC_ERROR);
3520 p->rx_len_err = GET_STAT(RX_PORT_LEN_ERROR);
3521 p->rx_symbol_err = GET_STAT(RX_PORT_SYM_ERROR);
3522 p->rx_runt = GET_STAT(RX_PORT_LESS_64B);
3523 p->rx_frames_64 = GET_STAT(RX_PORT_64B);
3524 p->rx_frames_65_127 = GET_STAT(RX_PORT_65B_127B);
3525 p->rx_frames_128_255 = GET_STAT(RX_PORT_128B_255B);
3526 p->rx_frames_256_511 = GET_STAT(RX_PORT_256B_511B);
3527 p->rx_frames_512_1023 = GET_STAT(RX_PORT_512B_1023B);
3528 p->rx_frames_1024_1518 = GET_STAT(RX_PORT_1024B_1518B);
3529 p->rx_frames_1519_max = GET_STAT(RX_PORT_1519B_MAX);
3530 p->rx_pause = GET_STAT(RX_PORT_PAUSE);
3531 p->rx_ppp0 = GET_STAT(RX_PORT_PPP0);
3532 p->rx_ppp1 = GET_STAT(RX_PORT_PPP1);
3533 p->rx_ppp2 = GET_STAT(RX_PORT_PPP2);
3534 p->rx_ppp3 = GET_STAT(RX_PORT_PPP3);
3535 p->rx_ppp4 = GET_STAT(RX_PORT_PPP4);
3536 p->rx_ppp5 = GET_STAT(RX_PORT_PPP5);
3537 p->rx_ppp6 = GET_STAT(RX_PORT_PPP6);
3538 p->rx_ppp7 = GET_STAT(RX_PORT_PPP7);
3539
3540 p->rx_ovflow0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_MAC_DROP_FRAME) : 0;
3541 p->rx_ovflow1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_MAC_DROP_FRAME) : 0;
3542 p->rx_ovflow2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_MAC_DROP_FRAME) : 0;
3543 p->rx_ovflow3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_MAC_DROP_FRAME) : 0;
3544 p->rx_trunc0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_MAC_TRUNC_FRAME) : 0;
3545 p->rx_trunc1 = (bgmap & 2) ? GET_STAT_COM(RX_BG_1_MAC_TRUNC_FRAME) : 0;
3546 p->rx_trunc2 = (bgmap & 4) ? GET_STAT_COM(RX_BG_2_MAC_TRUNC_FRAME) : 0;
3547 p->rx_trunc3 = (bgmap & 8) ? GET_STAT_COM(RX_BG_3_MAC_TRUNC_FRAME) : 0;
3548
3549#undef GET_STAT
3550#undef GET_STAT_COM
3551}
3552
3553/**
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003554 * t4_wol_magic_enable - enable/disable magic packet WoL
3555 * @adap: the adapter
3556 * @port: the physical port index
3557 * @addr: MAC address expected in magic packets, %NULL to disable
3558 *
3559 * Enables/disables magic packet wake-on-LAN for the selected port.
3560 */
3561void t4_wol_magic_enable(struct adapter *adap, unsigned int port,
3562 const u8 *addr)
3563{
Santosh Rastapur0a57a532013-03-14 05:08:49 +00003564 u32 mag_id_reg_l, mag_id_reg_h, port_cfg_reg;
3565
Hariprasad Shenaid14807d2013-12-03 17:05:56 +05303566 if (is_t4(adap->params.chip)) {
Santosh Rastapur0a57a532013-03-14 05:08:49 +00003567 mag_id_reg_l = PORT_REG(port, XGMAC_PORT_MAGIC_MACID_LO);
3568 mag_id_reg_h = PORT_REG(port, XGMAC_PORT_MAGIC_MACID_HI);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05303569 port_cfg_reg = PORT_REG(port, XGMAC_PORT_CFG2_A);
Santosh Rastapur0a57a532013-03-14 05:08:49 +00003570 } else {
3571 mag_id_reg_l = T5_PORT_REG(port, MAC_PORT_MAGIC_MACID_LO);
3572 mag_id_reg_h = T5_PORT_REG(port, MAC_PORT_MAGIC_MACID_HI);
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05303573 port_cfg_reg = T5_PORT_REG(port, MAC_PORT_CFG2_A);
Santosh Rastapur0a57a532013-03-14 05:08:49 +00003574 }
3575
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003576 if (addr) {
Santosh Rastapur0a57a532013-03-14 05:08:49 +00003577 t4_write_reg(adap, mag_id_reg_l,
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003578 (addr[2] << 24) | (addr[3] << 16) |
3579 (addr[4] << 8) | addr[5]);
Santosh Rastapur0a57a532013-03-14 05:08:49 +00003580 t4_write_reg(adap, mag_id_reg_h,
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003581 (addr[0] << 8) | addr[1]);
3582 }
Hariprasad Shenai0d804332015-01-05 16:30:47 +05303583 t4_set_reg_field(adap, port_cfg_reg, MAGICEN_F,
3584 addr ? MAGICEN_F : 0);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003585}
3586
3587/**
3588 * t4_wol_pat_enable - enable/disable pattern-based WoL
3589 * @adap: the adapter
3590 * @port: the physical port index
3591 * @map: bitmap of which HW pattern filters to set
3592 * @mask0: byte mask for bytes 0-63 of a packet
3593 * @mask1: byte mask for bytes 64-127 of a packet
3594 * @crc: Ethernet CRC for selected bytes
3595 * @enable: enable/disable switch
3596 *
3597 * Sets the pattern filters indicated in @map to mask out the bytes
3598 * specified in @mask0/@mask1 in received packets and compare the CRC of
3599 * the resulting packet against @crc. If @enable is %true pattern-based
3600 * WoL is enabled, otherwise disabled.
3601 */
3602int t4_wol_pat_enable(struct adapter *adap, unsigned int port, unsigned int map,
3603 u64 mask0, u64 mask1, unsigned int crc, bool enable)
3604{
3605 int i;
Santosh Rastapur0a57a532013-03-14 05:08:49 +00003606 u32 port_cfg_reg;
3607
Hariprasad Shenaid14807d2013-12-03 17:05:56 +05303608 if (is_t4(adap->params.chip))
Hariprasad Shenai0d804332015-01-05 16:30:47 +05303609 port_cfg_reg = PORT_REG(port, XGMAC_PORT_CFG2_A);
Santosh Rastapur0a57a532013-03-14 05:08:49 +00003610 else
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05303611 port_cfg_reg = T5_PORT_REG(port, MAC_PORT_CFG2_A);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003612
3613 if (!enable) {
Hariprasad Shenai0d804332015-01-05 16:30:47 +05303614 t4_set_reg_field(adap, port_cfg_reg, PATEN_F, 0);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003615 return 0;
3616 }
3617 if (map > 0xff)
3618 return -EINVAL;
3619
Santosh Rastapur0a57a532013-03-14 05:08:49 +00003620#define EPIO_REG(name) \
Hariprasad Shenai0d804332015-01-05 16:30:47 +05303621 (is_t4(adap->params.chip) ? \
3622 PORT_REG(port, XGMAC_PORT_EPIO_##name##_A) : \
3623 T5_PORT_REG(port, MAC_PORT_EPIO_##name##_A))
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003624
3625 t4_write_reg(adap, EPIO_REG(DATA1), mask0 >> 32);
3626 t4_write_reg(adap, EPIO_REG(DATA2), mask1);
3627 t4_write_reg(adap, EPIO_REG(DATA3), mask1 >> 32);
3628
3629 for (i = 0; i < NWOL_PAT; i++, map >>= 1) {
3630 if (!(map & 1))
3631 continue;
3632
3633 /* write byte masks */
3634 t4_write_reg(adap, EPIO_REG(DATA0), mask0);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05303635 t4_write_reg(adap, EPIO_REG(OP), ADDRESS_V(i) | EPIOWR_F);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003636 t4_read_reg(adap, EPIO_REG(OP)); /* flush */
Hariprasad Shenai0d804332015-01-05 16:30:47 +05303637 if (t4_read_reg(adap, EPIO_REG(OP)) & SF_BUSY_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003638 return -ETIMEDOUT;
3639
3640 /* write CRC */
3641 t4_write_reg(adap, EPIO_REG(DATA0), crc);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05303642 t4_write_reg(adap, EPIO_REG(OP), ADDRESS_V(i + 32) | EPIOWR_F);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003643 t4_read_reg(adap, EPIO_REG(OP)); /* flush */
Hariprasad Shenai0d804332015-01-05 16:30:47 +05303644 if (t4_read_reg(adap, EPIO_REG(OP)) & SF_BUSY_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003645 return -ETIMEDOUT;
3646 }
3647#undef EPIO_REG
3648
Hariprasad Shenai0d804332015-01-05 16:30:47 +05303649 t4_set_reg_field(adap, PORT_REG(port, XGMAC_PORT_CFG2_A), 0, PATEN_F);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003650 return 0;
3651}
3652
Vipul Pandyaf2b7e782012-12-10 09:30:52 +00003653/* t4_mk_filtdelwr - create a delete filter WR
3654 * @ftid: the filter ID
3655 * @wr: the filter work request to populate
3656 * @qid: ingress queue to receive the delete notification
3657 *
3658 * Creates a filter work request to delete the supplied filter. If @qid is
3659 * negative the delete notification is suppressed.
3660 */
3661void t4_mk_filtdelwr(unsigned int ftid, struct fw_filter_wr *wr, int qid)
3662{
3663 memset(wr, 0, sizeof(*wr));
Hariprasad Shenaif404f802015-05-19 18:20:44 +05303664 wr->op_pkd = cpu_to_be32(FW_WR_OP_V(FW_FILTER_WR));
3665 wr->len16_pkd = cpu_to_be32(FW_WR_LEN16_V(sizeof(*wr) / 16));
3666 wr->tid_to_iq = cpu_to_be32(FW_FILTER_WR_TID_V(ftid) |
3667 FW_FILTER_WR_NOREPLY_V(qid < 0));
3668 wr->del_filter_to_l2tix = cpu_to_be32(FW_FILTER_WR_DEL_FILTER_F);
Vipul Pandyaf2b7e782012-12-10 09:30:52 +00003669 if (qid >= 0)
Hariprasad Shenaif404f802015-05-19 18:20:44 +05303670 wr->rx_chan_rx_rpl_iq =
3671 cpu_to_be16(FW_FILTER_WR_RX_RPL_IQ_V(qid));
Vipul Pandyaf2b7e782012-12-10 09:30:52 +00003672}
3673
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003674#define INIT_CMD(var, cmd, rd_wr) do { \
Hariprasad Shenaif404f802015-05-19 18:20:44 +05303675 (var).op_to_write = cpu_to_be32(FW_CMD_OP_V(FW_##cmd##_CMD) | \
3676 FW_CMD_REQUEST_F | \
3677 FW_CMD_##rd_wr##_F); \
3678 (var).retval_len16 = cpu_to_be32(FW_LEN16(var)); \
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003679} while (0)
3680
Vipul Pandya8caa1e82012-05-18 15:29:25 +05303681int t4_fwaddrspace_write(struct adapter *adap, unsigned int mbox,
3682 u32 addr, u32 val)
3683{
Hariprasad Shenaif404f802015-05-19 18:20:44 +05303684 u32 ldst_addrspace;
Vipul Pandya8caa1e82012-05-18 15:29:25 +05303685 struct fw_ldst_cmd c;
3686
3687 memset(&c, 0, sizeof(c));
Hariprasad Shenaif404f802015-05-19 18:20:44 +05303688 ldst_addrspace = FW_LDST_CMD_ADDRSPACE_V(FW_LDST_ADDRSPC_FIRMWARE);
3689 c.op_to_addrspace = cpu_to_be32(FW_CMD_OP_V(FW_LDST_CMD) |
3690 FW_CMD_REQUEST_F |
3691 FW_CMD_WRITE_F |
3692 ldst_addrspace);
3693 c.cycles_to_len16 = cpu_to_be32(FW_LEN16(c));
3694 c.u.addrval.addr = cpu_to_be32(addr);
3695 c.u.addrval.val = cpu_to_be32(val);
Vipul Pandya8caa1e82012-05-18 15:29:25 +05303696
3697 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
3698}
3699
Ben Hutchings49ce9c22012-07-10 10:56:00 +00003700/**
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003701 * t4_mdio_rd - read a PHY register through MDIO
3702 * @adap: the adapter
3703 * @mbox: mailbox to use for the FW command
3704 * @phy_addr: the PHY address
3705 * @mmd: the PHY MMD to access (0 for clause 22 PHYs)
3706 * @reg: the register to read
3707 * @valp: where to store the value
3708 *
3709 * Issues a FW command through the given mailbox to read a PHY register.
3710 */
3711int t4_mdio_rd(struct adapter *adap, unsigned int mbox, unsigned int phy_addr,
3712 unsigned int mmd, unsigned int reg, u16 *valp)
3713{
3714 int ret;
Hariprasad Shenaif404f802015-05-19 18:20:44 +05303715 u32 ldst_addrspace;
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003716 struct fw_ldst_cmd c;
3717
3718 memset(&c, 0, sizeof(c));
Hariprasad Shenaif404f802015-05-19 18:20:44 +05303719 ldst_addrspace = FW_LDST_CMD_ADDRSPACE_V(FW_LDST_ADDRSPC_MDIO);
3720 c.op_to_addrspace = cpu_to_be32(FW_CMD_OP_V(FW_LDST_CMD) |
3721 FW_CMD_REQUEST_F | FW_CMD_READ_F |
3722 ldst_addrspace);
3723 c.cycles_to_len16 = cpu_to_be32(FW_LEN16(c));
3724 c.u.mdio.paddr_mmd = cpu_to_be16(FW_LDST_CMD_PADDR_V(phy_addr) |
3725 FW_LDST_CMD_MMD_V(mmd));
3726 c.u.mdio.raddr = cpu_to_be16(reg);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003727
3728 ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
3729 if (ret == 0)
Hariprasad Shenaif404f802015-05-19 18:20:44 +05303730 *valp = be16_to_cpu(c.u.mdio.rval);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003731 return ret;
3732}
3733
3734/**
3735 * t4_mdio_wr - write a PHY register through MDIO
3736 * @adap: the adapter
3737 * @mbox: mailbox to use for the FW command
3738 * @phy_addr: the PHY address
3739 * @mmd: the PHY MMD to access (0 for clause 22 PHYs)
3740 * @reg: the register to write
3741 * @valp: value to write
3742 *
3743 * Issues a FW command through the given mailbox to write a PHY register.
3744 */
3745int t4_mdio_wr(struct adapter *adap, unsigned int mbox, unsigned int phy_addr,
3746 unsigned int mmd, unsigned int reg, u16 val)
3747{
Hariprasad Shenaif404f802015-05-19 18:20:44 +05303748 u32 ldst_addrspace;
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003749 struct fw_ldst_cmd c;
3750
3751 memset(&c, 0, sizeof(c));
Hariprasad Shenaif404f802015-05-19 18:20:44 +05303752 ldst_addrspace = FW_LDST_CMD_ADDRSPACE_V(FW_LDST_ADDRSPC_MDIO);
3753 c.op_to_addrspace = cpu_to_be32(FW_CMD_OP_V(FW_LDST_CMD) |
3754 FW_CMD_REQUEST_F | FW_CMD_WRITE_F |
3755 ldst_addrspace);
3756 c.cycles_to_len16 = cpu_to_be32(FW_LEN16(c));
3757 c.u.mdio.paddr_mmd = cpu_to_be16(FW_LDST_CMD_PADDR_V(phy_addr) |
3758 FW_LDST_CMD_MMD_V(mmd));
3759 c.u.mdio.raddr = cpu_to_be16(reg);
3760 c.u.mdio.rval = cpu_to_be16(val);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003761
3762 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
3763}
3764
3765/**
Kumar Sanghvi68bce1922014-03-13 20:50:47 +05303766 * t4_sge_decode_idma_state - decode the idma state
3767 * @adap: the adapter
3768 * @state: the state idma is stuck in
3769 */
3770void t4_sge_decode_idma_state(struct adapter *adapter, int state)
3771{
3772 static const char * const t4_decode[] = {
3773 "IDMA_IDLE",
3774 "IDMA_PUSH_MORE_CPL_FIFO",
3775 "IDMA_PUSH_CPL_MSG_HEADER_TO_FIFO",
3776 "Not used",
3777 "IDMA_PHYSADDR_SEND_PCIEHDR",
3778 "IDMA_PHYSADDR_SEND_PAYLOAD_FIRST",
3779 "IDMA_PHYSADDR_SEND_PAYLOAD",
3780 "IDMA_SEND_FIFO_TO_IMSG",
3781 "IDMA_FL_REQ_DATA_FL_PREP",
3782 "IDMA_FL_REQ_DATA_FL",
3783 "IDMA_FL_DROP",
3784 "IDMA_FL_H_REQ_HEADER_FL",
3785 "IDMA_FL_H_SEND_PCIEHDR",
3786 "IDMA_FL_H_PUSH_CPL_FIFO",
3787 "IDMA_FL_H_SEND_CPL",
3788 "IDMA_FL_H_SEND_IP_HDR_FIRST",
3789 "IDMA_FL_H_SEND_IP_HDR",
3790 "IDMA_FL_H_REQ_NEXT_HEADER_FL",
3791 "IDMA_FL_H_SEND_NEXT_PCIEHDR",
3792 "IDMA_FL_H_SEND_IP_HDR_PADDING",
3793 "IDMA_FL_D_SEND_PCIEHDR",
3794 "IDMA_FL_D_SEND_CPL_AND_IP_HDR",
3795 "IDMA_FL_D_REQ_NEXT_DATA_FL",
3796 "IDMA_FL_SEND_PCIEHDR",
3797 "IDMA_FL_PUSH_CPL_FIFO",
3798 "IDMA_FL_SEND_CPL",
3799 "IDMA_FL_SEND_PAYLOAD_FIRST",
3800 "IDMA_FL_SEND_PAYLOAD",
3801 "IDMA_FL_REQ_NEXT_DATA_FL",
3802 "IDMA_FL_SEND_NEXT_PCIEHDR",
3803 "IDMA_FL_SEND_PADDING",
3804 "IDMA_FL_SEND_COMPLETION_TO_IMSG",
3805 "IDMA_FL_SEND_FIFO_TO_IMSG",
3806 "IDMA_FL_REQ_DATAFL_DONE",
3807 "IDMA_FL_REQ_HEADERFL_DONE",
3808 };
3809 static const char * const t5_decode[] = {
3810 "IDMA_IDLE",
3811 "IDMA_ALMOST_IDLE",
3812 "IDMA_PUSH_MORE_CPL_FIFO",
3813 "IDMA_PUSH_CPL_MSG_HEADER_TO_FIFO",
3814 "IDMA_SGEFLRFLUSH_SEND_PCIEHDR",
3815 "IDMA_PHYSADDR_SEND_PCIEHDR",
3816 "IDMA_PHYSADDR_SEND_PAYLOAD_FIRST",
3817 "IDMA_PHYSADDR_SEND_PAYLOAD",
3818 "IDMA_SEND_FIFO_TO_IMSG",
3819 "IDMA_FL_REQ_DATA_FL",
3820 "IDMA_FL_DROP",
3821 "IDMA_FL_DROP_SEND_INC",
3822 "IDMA_FL_H_REQ_HEADER_FL",
3823 "IDMA_FL_H_SEND_PCIEHDR",
3824 "IDMA_FL_H_PUSH_CPL_FIFO",
3825 "IDMA_FL_H_SEND_CPL",
3826 "IDMA_FL_H_SEND_IP_HDR_FIRST",
3827 "IDMA_FL_H_SEND_IP_HDR",
3828 "IDMA_FL_H_REQ_NEXT_HEADER_FL",
3829 "IDMA_FL_H_SEND_NEXT_PCIEHDR",
3830 "IDMA_FL_H_SEND_IP_HDR_PADDING",
3831 "IDMA_FL_D_SEND_PCIEHDR",
3832 "IDMA_FL_D_SEND_CPL_AND_IP_HDR",
3833 "IDMA_FL_D_REQ_NEXT_DATA_FL",
3834 "IDMA_FL_SEND_PCIEHDR",
3835 "IDMA_FL_PUSH_CPL_FIFO",
3836 "IDMA_FL_SEND_CPL",
3837 "IDMA_FL_SEND_PAYLOAD_FIRST",
3838 "IDMA_FL_SEND_PAYLOAD",
3839 "IDMA_FL_REQ_NEXT_DATA_FL",
3840 "IDMA_FL_SEND_NEXT_PCIEHDR",
3841 "IDMA_FL_SEND_PADDING",
3842 "IDMA_FL_SEND_COMPLETION_TO_IMSG",
3843 };
3844 static const u32 sge_regs[] = {
Hariprasad Shenaif061de422015-01-05 16:30:44 +05303845 SGE_DEBUG_DATA_LOW_INDEX_2_A,
3846 SGE_DEBUG_DATA_LOW_INDEX_3_A,
3847 SGE_DEBUG_DATA_HIGH_INDEX_10_A,
Kumar Sanghvi68bce1922014-03-13 20:50:47 +05303848 };
3849 const char **sge_idma_decode;
3850 int sge_idma_decode_nstates;
3851 int i;
3852
3853 if (is_t4(adapter->params.chip)) {
3854 sge_idma_decode = (const char **)t4_decode;
3855 sge_idma_decode_nstates = ARRAY_SIZE(t4_decode);
3856 } else {
3857 sge_idma_decode = (const char **)t5_decode;
3858 sge_idma_decode_nstates = ARRAY_SIZE(t5_decode);
3859 }
3860
3861 if (state < sge_idma_decode_nstates)
3862 CH_WARN(adapter, "idma state %s\n", sge_idma_decode[state]);
3863 else
3864 CH_WARN(adapter, "idma state %d unknown\n", state);
3865
3866 for (i = 0; i < ARRAY_SIZE(sge_regs); i++)
3867 CH_WARN(adapter, "SGE register %#x value %#x\n",
3868 sge_regs[i], t4_read_reg(adapter, sge_regs[i]));
3869}
3870
3871/**
Vipul Pandya636f9d32012-09-26 02:39:39 +00003872 * t4_fw_hello - establish communication with FW
3873 * @adap: the adapter
3874 * @mbox: mailbox to use for the FW command
3875 * @evt_mbox: mailbox to receive async FW events
3876 * @master: specifies the caller's willingness to be the device master
3877 * @state: returns the current device state (if non-NULL)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003878 *
Vipul Pandya636f9d32012-09-26 02:39:39 +00003879 * Issues a command to establish communication with FW. Returns either
3880 * an error (negative integer) or the mailbox of the Master PF.
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003881 */
3882int t4_fw_hello(struct adapter *adap, unsigned int mbox, unsigned int evt_mbox,
3883 enum dev_master master, enum dev_state *state)
3884{
3885 int ret;
3886 struct fw_hello_cmd c;
Vipul Pandya636f9d32012-09-26 02:39:39 +00003887 u32 v;
3888 unsigned int master_mbox;
3889 int retries = FW_CMD_HELLO_RETRIES;
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003890
Vipul Pandya636f9d32012-09-26 02:39:39 +00003891retry:
3892 memset(&c, 0, sizeof(c));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003893 INIT_CMD(c, HELLO, WRITE);
Hariprasad Shenaif404f802015-05-19 18:20:44 +05303894 c.err_to_clearinit = cpu_to_be32(
Hariprasad Shenai51678652014-11-21 12:52:02 +05303895 FW_HELLO_CMD_MASTERDIS_V(master == MASTER_CANT) |
3896 FW_HELLO_CMD_MASTERFORCE_V(master == MASTER_MUST) |
Hariprasad Shenaif404f802015-05-19 18:20:44 +05303897 FW_HELLO_CMD_MBMASTER_V(master == MASTER_MUST ?
3898 mbox : FW_HELLO_CMD_MBMASTER_M) |
Hariprasad Shenai51678652014-11-21 12:52:02 +05303899 FW_HELLO_CMD_MBASYNCNOT_V(evt_mbox) |
3900 FW_HELLO_CMD_STAGE_V(fw_hello_cmd_stage_os) |
3901 FW_HELLO_CMD_CLEARINIT_F);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003902
Vipul Pandya636f9d32012-09-26 02:39:39 +00003903 /*
3904 * Issue the HELLO command to the firmware. If it's not successful
3905 * but indicates that we got a "busy" or "timeout" condition, retry
Hariprasad Shenai31d55c22014-09-01 19:54:58 +05303906 * the HELLO until we exhaust our retry limit. If we do exceed our
3907 * retry limit, check to see if the firmware left us any error
3908 * information and report that if so.
Vipul Pandya636f9d32012-09-26 02:39:39 +00003909 */
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003910 ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
Vipul Pandya636f9d32012-09-26 02:39:39 +00003911 if (ret < 0) {
3912 if ((ret == -EBUSY || ret == -ETIMEDOUT) && retries-- > 0)
3913 goto retry;
Hariprasad Shenaif061de422015-01-05 16:30:44 +05303914 if (t4_read_reg(adap, PCIE_FW_A) & PCIE_FW_ERR_F)
Hariprasad Shenai31d55c22014-09-01 19:54:58 +05303915 t4_report_fw_error(adap);
Vipul Pandya636f9d32012-09-26 02:39:39 +00003916 return ret;
3917 }
3918
Hariprasad Shenaif404f802015-05-19 18:20:44 +05303919 v = be32_to_cpu(c.err_to_clearinit);
Hariprasad Shenai51678652014-11-21 12:52:02 +05303920 master_mbox = FW_HELLO_CMD_MBMASTER_G(v);
Vipul Pandya636f9d32012-09-26 02:39:39 +00003921 if (state) {
Hariprasad Shenai51678652014-11-21 12:52:02 +05303922 if (v & FW_HELLO_CMD_ERR_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003923 *state = DEV_STATE_ERR;
Hariprasad Shenai51678652014-11-21 12:52:02 +05303924 else if (v & FW_HELLO_CMD_INIT_F)
Vipul Pandya636f9d32012-09-26 02:39:39 +00003925 *state = DEV_STATE_INIT;
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003926 else
3927 *state = DEV_STATE_UNINIT;
3928 }
Vipul Pandya636f9d32012-09-26 02:39:39 +00003929
3930 /*
3931 * If we're not the Master PF then we need to wait around for the
3932 * Master PF Driver to finish setting up the adapter.
3933 *
3934 * Note that we also do this wait if we're a non-Master-capable PF and
3935 * there is no current Master PF; a Master PF may show up momentarily
3936 * and we wouldn't want to fail pointlessly. (This can happen when an
3937 * OS loads lots of different drivers rapidly at the same time). In
3938 * this case, the Master PF returned by the firmware will be
Hariprasad Shenaib2e1a3f2014-11-21 12:52:05 +05303939 * PCIE_FW_MASTER_M so the test below will work ...
Vipul Pandya636f9d32012-09-26 02:39:39 +00003940 */
Hariprasad Shenai51678652014-11-21 12:52:02 +05303941 if ((v & (FW_HELLO_CMD_ERR_F|FW_HELLO_CMD_INIT_F)) == 0 &&
Vipul Pandya636f9d32012-09-26 02:39:39 +00003942 master_mbox != mbox) {
3943 int waiting = FW_CMD_HELLO_TIMEOUT;
3944
3945 /*
3946 * Wait for the firmware to either indicate an error or
3947 * initialized state. If we see either of these we bail out
3948 * and report the issue to the caller. If we exhaust the
3949 * "hello timeout" and we haven't exhausted our retries, try
3950 * again. Otherwise bail with a timeout error.
3951 */
3952 for (;;) {
3953 u32 pcie_fw;
3954
3955 msleep(50);
3956 waiting -= 50;
3957
3958 /*
3959 * If neither Error nor Initialialized are indicated
3960 * by the firmware keep waiting till we exaust our
3961 * timeout ... and then retry if we haven't exhausted
3962 * our retries ...
3963 */
Hariprasad Shenaif061de422015-01-05 16:30:44 +05303964 pcie_fw = t4_read_reg(adap, PCIE_FW_A);
3965 if (!(pcie_fw & (PCIE_FW_ERR_F|PCIE_FW_INIT_F))) {
Vipul Pandya636f9d32012-09-26 02:39:39 +00003966 if (waiting <= 0) {
3967 if (retries-- > 0)
3968 goto retry;
3969
3970 return -ETIMEDOUT;
3971 }
3972 continue;
3973 }
3974
3975 /*
3976 * We either have an Error or Initialized condition
3977 * report errors preferentially.
3978 */
3979 if (state) {
Hariprasad Shenaif061de422015-01-05 16:30:44 +05303980 if (pcie_fw & PCIE_FW_ERR_F)
Vipul Pandya636f9d32012-09-26 02:39:39 +00003981 *state = DEV_STATE_ERR;
Hariprasad Shenaif061de422015-01-05 16:30:44 +05303982 else if (pcie_fw & PCIE_FW_INIT_F)
Vipul Pandya636f9d32012-09-26 02:39:39 +00003983 *state = DEV_STATE_INIT;
3984 }
3985
3986 /*
3987 * If we arrived before a Master PF was selected and
3988 * there's not a valid Master PF, grab its identity
3989 * for our caller.
3990 */
Hariprasad Shenaib2e1a3f2014-11-21 12:52:05 +05303991 if (master_mbox == PCIE_FW_MASTER_M &&
Hariprasad Shenaif061de422015-01-05 16:30:44 +05303992 (pcie_fw & PCIE_FW_MASTER_VLD_F))
Hariprasad Shenaib2e1a3f2014-11-21 12:52:05 +05303993 master_mbox = PCIE_FW_MASTER_G(pcie_fw);
Vipul Pandya636f9d32012-09-26 02:39:39 +00003994 break;
3995 }
3996 }
3997
3998 return master_mbox;
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00003999}
4000
4001/**
4002 * t4_fw_bye - end communication with FW
4003 * @adap: the adapter
4004 * @mbox: mailbox to use for the FW command
4005 *
4006 * Issues a command to terminate communication with FW.
4007 */
4008int t4_fw_bye(struct adapter *adap, unsigned int mbox)
4009{
4010 struct fw_bye_cmd c;
4011
Vipul Pandya0062b152012-11-06 03:37:09 +00004012 memset(&c, 0, sizeof(c));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004013 INIT_CMD(c, BYE, WRITE);
4014 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
4015}
4016
4017/**
4018 * t4_init_cmd - ask FW to initialize the device
4019 * @adap: the adapter
4020 * @mbox: mailbox to use for the FW command
4021 *
4022 * Issues a command to FW to partially initialize the device. This
4023 * performs initialization that generally doesn't depend on user input.
4024 */
4025int t4_early_init(struct adapter *adap, unsigned int mbox)
4026{
4027 struct fw_initialize_cmd c;
4028
Vipul Pandya0062b152012-11-06 03:37:09 +00004029 memset(&c, 0, sizeof(c));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004030 INIT_CMD(c, INITIALIZE, WRITE);
4031 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
4032}
4033
4034/**
4035 * t4_fw_reset - issue a reset to FW
4036 * @adap: the adapter
4037 * @mbox: mailbox to use for the FW command
4038 * @reset: specifies the type of reset to perform
4039 *
4040 * Issues a reset command of the specified type to FW.
4041 */
4042int t4_fw_reset(struct adapter *adap, unsigned int mbox, int reset)
4043{
4044 struct fw_reset_cmd c;
4045
Vipul Pandya0062b152012-11-06 03:37:09 +00004046 memset(&c, 0, sizeof(c));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004047 INIT_CMD(c, RESET, WRITE);
Hariprasad Shenaif404f802015-05-19 18:20:44 +05304048 c.val = cpu_to_be32(reset);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004049 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
4050}
4051
4052/**
Vipul Pandya26f7cbc2012-09-26 02:39:42 +00004053 * t4_fw_halt - issue a reset/halt to FW and put uP into RESET
4054 * @adap: the adapter
4055 * @mbox: mailbox to use for the FW RESET command (if desired)
4056 * @force: force uP into RESET even if FW RESET command fails
4057 *
4058 * Issues a RESET command to firmware (if desired) with a HALT indication
4059 * and then puts the microprocessor into RESET state. The RESET command
4060 * will only be issued if a legitimate mailbox is provided (mbox <=
Hariprasad Shenaib2e1a3f2014-11-21 12:52:05 +05304061 * PCIE_FW_MASTER_M).
Vipul Pandya26f7cbc2012-09-26 02:39:42 +00004062 *
4063 * This is generally used in order for the host to safely manipulate the
4064 * adapter without fear of conflicting with whatever the firmware might
4065 * be doing. The only way out of this state is to RESTART the firmware
4066 * ...
4067 */
stephen hemmingerde5b8672013-12-18 14:16:47 -08004068static int t4_fw_halt(struct adapter *adap, unsigned int mbox, int force)
Vipul Pandya26f7cbc2012-09-26 02:39:42 +00004069{
4070 int ret = 0;
4071
4072 /*
4073 * If a legitimate mailbox is provided, issue a RESET command
4074 * with a HALT indication.
4075 */
Hariprasad Shenaib2e1a3f2014-11-21 12:52:05 +05304076 if (mbox <= PCIE_FW_MASTER_M) {
Vipul Pandya26f7cbc2012-09-26 02:39:42 +00004077 struct fw_reset_cmd c;
4078
4079 memset(&c, 0, sizeof(c));
4080 INIT_CMD(c, RESET, WRITE);
Hariprasad Shenaif404f802015-05-19 18:20:44 +05304081 c.val = cpu_to_be32(PIORST_F | PIORSTMODE_F);
4082 c.halt_pkd = cpu_to_be32(FW_RESET_CMD_HALT_F);
Vipul Pandya26f7cbc2012-09-26 02:39:42 +00004083 ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
4084 }
4085
4086 /*
4087 * Normally we won't complete the operation if the firmware RESET
4088 * command fails but if our caller insists we'll go ahead and put the
4089 * uP into RESET. This can be useful if the firmware is hung or even
4090 * missing ... We'll have to take the risk of putting the uP into
4091 * RESET without the cooperation of firmware in that case.
4092 *
4093 * We also force the firmware's HALT flag to be on in case we bypassed
4094 * the firmware RESET command above or we're dealing with old firmware
4095 * which doesn't have the HALT capability. This will serve as a flag
4096 * for the incoming firmware to know that it's coming out of a HALT
4097 * rather than a RESET ... if it's new enough to understand that ...
4098 */
4099 if (ret == 0 || force) {
Hariprasad Shenai89c3a862015-01-05 16:30:45 +05304100 t4_set_reg_field(adap, CIM_BOOT_CFG_A, UPCRST_F, UPCRST_F);
Hariprasad Shenaif061de422015-01-05 16:30:44 +05304101 t4_set_reg_field(adap, PCIE_FW_A, PCIE_FW_HALT_F,
Hariprasad Shenaib2e1a3f2014-11-21 12:52:05 +05304102 PCIE_FW_HALT_F);
Vipul Pandya26f7cbc2012-09-26 02:39:42 +00004103 }
4104
4105 /*
4106 * And we always return the result of the firmware RESET command
4107 * even when we force the uP into RESET ...
4108 */
4109 return ret;
4110}
4111
4112/**
4113 * t4_fw_restart - restart the firmware by taking the uP out of RESET
4114 * @adap: the adapter
4115 * @reset: if we want to do a RESET to restart things
4116 *
4117 * Restart firmware previously halted by t4_fw_halt(). On successful
4118 * return the previous PF Master remains as the new PF Master and there
4119 * is no need to issue a new HELLO command, etc.
4120 *
4121 * We do this in two ways:
4122 *
4123 * 1. If we're dealing with newer firmware we'll simply want to take
4124 * the chip's microprocessor out of RESET. This will cause the
4125 * firmware to start up from its start vector. And then we'll loop
4126 * until the firmware indicates it's started again (PCIE_FW.HALT
4127 * reset to 0) or we timeout.
4128 *
4129 * 2. If we're dealing with older firmware then we'll need to RESET
4130 * the chip since older firmware won't recognize the PCIE_FW.HALT
4131 * flag and automatically RESET itself on startup.
4132 */
stephen hemmingerde5b8672013-12-18 14:16:47 -08004133static int t4_fw_restart(struct adapter *adap, unsigned int mbox, int reset)
Vipul Pandya26f7cbc2012-09-26 02:39:42 +00004134{
4135 if (reset) {
4136 /*
4137 * Since we're directing the RESET instead of the firmware
4138 * doing it automatically, we need to clear the PCIE_FW.HALT
4139 * bit.
4140 */
Hariprasad Shenaif061de422015-01-05 16:30:44 +05304141 t4_set_reg_field(adap, PCIE_FW_A, PCIE_FW_HALT_F, 0);
Vipul Pandya26f7cbc2012-09-26 02:39:42 +00004142
4143 /*
4144 * If we've been given a valid mailbox, first try to get the
4145 * firmware to do the RESET. If that works, great and we can
4146 * return success. Otherwise, if we haven't been given a
4147 * valid mailbox or the RESET command failed, fall back to
4148 * hitting the chip with a hammer.
4149 */
Hariprasad Shenaib2e1a3f2014-11-21 12:52:05 +05304150 if (mbox <= PCIE_FW_MASTER_M) {
Hariprasad Shenai89c3a862015-01-05 16:30:45 +05304151 t4_set_reg_field(adap, CIM_BOOT_CFG_A, UPCRST_F, 0);
Vipul Pandya26f7cbc2012-09-26 02:39:42 +00004152 msleep(100);
4153 if (t4_fw_reset(adap, mbox,
Hariprasad Shenai0d804332015-01-05 16:30:47 +05304154 PIORST_F | PIORSTMODE_F) == 0)
Vipul Pandya26f7cbc2012-09-26 02:39:42 +00004155 return 0;
4156 }
4157
Hariprasad Shenai0d804332015-01-05 16:30:47 +05304158 t4_write_reg(adap, PL_RST_A, PIORST_F | PIORSTMODE_F);
Vipul Pandya26f7cbc2012-09-26 02:39:42 +00004159 msleep(2000);
4160 } else {
4161 int ms;
4162
Hariprasad Shenai89c3a862015-01-05 16:30:45 +05304163 t4_set_reg_field(adap, CIM_BOOT_CFG_A, UPCRST_F, 0);
Vipul Pandya26f7cbc2012-09-26 02:39:42 +00004164 for (ms = 0; ms < FW_CMD_MAX_TIMEOUT; ) {
Hariprasad Shenaif061de422015-01-05 16:30:44 +05304165 if (!(t4_read_reg(adap, PCIE_FW_A) & PCIE_FW_HALT_F))
Vipul Pandya26f7cbc2012-09-26 02:39:42 +00004166 return 0;
4167 msleep(100);
4168 ms += 100;
4169 }
4170 return -ETIMEDOUT;
4171 }
4172 return 0;
4173}
4174
4175/**
4176 * t4_fw_upgrade - perform all of the steps necessary to upgrade FW
4177 * @adap: the adapter
4178 * @mbox: mailbox to use for the FW RESET command (if desired)
4179 * @fw_data: the firmware image to write
4180 * @size: image size
4181 * @force: force upgrade even if firmware doesn't cooperate
4182 *
4183 * Perform all of the steps necessary for upgrading an adapter's
4184 * firmware image. Normally this requires the cooperation of the
4185 * existing firmware in order to halt all existing activities
4186 * but if an invalid mailbox token is passed in we skip that step
4187 * (though we'll still put the adapter microprocessor into RESET in
4188 * that case).
4189 *
4190 * On successful return the new firmware will have been loaded and
4191 * the adapter will have been fully RESET losing all previous setup
4192 * state. On unsuccessful return the adapter may be completely hosed ...
4193 * positive errno indicates that the adapter is ~probably~ intact, a
4194 * negative errno indicates that things are looking bad ...
4195 */
Hariprasad Shenai22c0b962014-10-15 01:54:14 +05304196int t4_fw_upgrade(struct adapter *adap, unsigned int mbox,
4197 const u8 *fw_data, unsigned int size, int force)
Vipul Pandya26f7cbc2012-09-26 02:39:42 +00004198{
4199 const struct fw_hdr *fw_hdr = (const struct fw_hdr *)fw_data;
4200 int reset, ret;
4201
Hariprasad Shenai79af2212014-12-03 11:49:50 +05304202 if (!t4_fw_matches_chip(adap, fw_hdr))
4203 return -EINVAL;
4204
Vipul Pandya26f7cbc2012-09-26 02:39:42 +00004205 ret = t4_fw_halt(adap, mbox, force);
4206 if (ret < 0 && !force)
4207 return ret;
4208
4209 ret = t4_load_fw(adap, fw_data, size);
4210 if (ret < 0)
4211 return ret;
4212
4213 /*
4214 * Older versions of the firmware don't understand the new
4215 * PCIE_FW.HALT flag and so won't know to perform a RESET when they
4216 * restart. So for newly loaded older firmware we'll have to do the
4217 * RESET for it so it starts up on a clean slate. We can tell if
4218 * the newly loaded firmware will handle this right by checking
4219 * its header flags to see if it advertises the capability.
4220 */
Hariprasad Shenaif404f802015-05-19 18:20:44 +05304221 reset = ((be32_to_cpu(fw_hdr->flags) & FW_HDR_FLAGS_RESET_HALT) == 0);
Vipul Pandya26f7cbc2012-09-26 02:39:42 +00004222 return t4_fw_restart(adap, mbox, reset);
4223}
4224
Vipul Pandya636f9d32012-09-26 02:39:39 +00004225/**
4226 * t4_fixup_host_params - fix up host-dependent parameters
4227 * @adap: the adapter
4228 * @page_size: the host's Base Page Size
4229 * @cache_line_size: the host's Cache Line Size
4230 *
4231 * Various registers in T4 contain values which are dependent on the
4232 * host's Base Page and Cache Line Sizes. This function will fix all of
4233 * those registers with the appropriate values as passed in ...
4234 */
4235int t4_fixup_host_params(struct adapter *adap, unsigned int page_size,
4236 unsigned int cache_line_size)
4237{
4238 unsigned int page_shift = fls(page_size) - 1;
4239 unsigned int sge_hps = page_shift - 10;
4240 unsigned int stat_len = cache_line_size > 64 ? 128 : 64;
4241 unsigned int fl_align = cache_line_size < 32 ? 32 : cache_line_size;
4242 unsigned int fl_align_log = fls(fl_align) - 1;
4243
Hariprasad Shenaif612b812015-01-05 16:30:43 +05304244 t4_write_reg(adap, SGE_HOST_PAGE_SIZE_A,
4245 HOSTPAGESIZEPF0_V(sge_hps) |
4246 HOSTPAGESIZEPF1_V(sge_hps) |
4247 HOSTPAGESIZEPF2_V(sge_hps) |
4248 HOSTPAGESIZEPF3_V(sge_hps) |
4249 HOSTPAGESIZEPF4_V(sge_hps) |
4250 HOSTPAGESIZEPF5_V(sge_hps) |
4251 HOSTPAGESIZEPF6_V(sge_hps) |
4252 HOSTPAGESIZEPF7_V(sge_hps));
Vipul Pandya636f9d32012-09-26 02:39:39 +00004253
Hariprasad Shenaice8f4072014-11-07 17:06:30 +05304254 if (is_t4(adap->params.chip)) {
Hariprasad Shenaif612b812015-01-05 16:30:43 +05304255 t4_set_reg_field(adap, SGE_CONTROL_A,
4256 INGPADBOUNDARY_V(INGPADBOUNDARY_M) |
4257 EGRSTATUSPAGESIZE_F,
4258 INGPADBOUNDARY_V(fl_align_log -
4259 INGPADBOUNDARY_SHIFT_X) |
4260 EGRSTATUSPAGESIZE_V(stat_len != 64));
Hariprasad Shenaice8f4072014-11-07 17:06:30 +05304261 } else {
4262 /* T5 introduced the separation of the Free List Padding and
4263 * Packing Boundaries. Thus, we can select a smaller Padding
4264 * Boundary to avoid uselessly chewing up PCIe Link and Memory
4265 * Bandwidth, and use a Packing Boundary which is large enough
4266 * to avoid false sharing between CPUs, etc.
4267 *
4268 * For the PCI Link, the smaller the Padding Boundary the
4269 * better. For the Memory Controller, a smaller Padding
4270 * Boundary is better until we cross under the Memory Line
4271 * Size (the minimum unit of transfer to/from Memory). If we
4272 * have a Padding Boundary which is smaller than the Memory
4273 * Line Size, that'll involve a Read-Modify-Write cycle on the
4274 * Memory Controller which is never good. For T5 the smallest
4275 * Padding Boundary which we can select is 32 bytes which is
4276 * larger than any known Memory Controller Line Size so we'll
4277 * use that.
4278 *
4279 * T5 has a different interpretation of the "0" value for the
4280 * Packing Boundary. This corresponds to 16 bytes instead of
4281 * the expected 32 bytes. We never have a Packing Boundary
4282 * less than 32 bytes so we can't use that special value but
4283 * on the other hand, if we wanted 32 bytes, the best we can
4284 * really do is 64 bytes.
4285 */
4286 if (fl_align <= 32) {
4287 fl_align = 64;
4288 fl_align_log = 6;
4289 }
Hariprasad Shenaif612b812015-01-05 16:30:43 +05304290 t4_set_reg_field(adap, SGE_CONTROL_A,
4291 INGPADBOUNDARY_V(INGPADBOUNDARY_M) |
4292 EGRSTATUSPAGESIZE_F,
4293 INGPADBOUNDARY_V(INGPCIEBOUNDARY_32B_X) |
4294 EGRSTATUSPAGESIZE_V(stat_len != 64));
Hariprasad Shenaice8f4072014-11-07 17:06:30 +05304295 t4_set_reg_field(adap, SGE_CONTROL2_A,
4296 INGPACKBOUNDARY_V(INGPACKBOUNDARY_M),
4297 INGPACKBOUNDARY_V(fl_align_log -
Hariprasad Shenaif612b812015-01-05 16:30:43 +05304298 INGPACKBOUNDARY_SHIFT_X));
Hariprasad Shenaice8f4072014-11-07 17:06:30 +05304299 }
Vipul Pandya636f9d32012-09-26 02:39:39 +00004300 /*
4301 * Adjust various SGE Free List Host Buffer Sizes.
4302 *
4303 * This is something of a crock since we're using fixed indices into
4304 * the array which are also known by the sge.c code and the T4
4305 * Firmware Configuration File. We need to come up with a much better
4306 * approach to managing this array. For now, the first four entries
4307 * are:
4308 *
4309 * 0: Host Page Size
4310 * 1: 64KB
4311 * 2: Buffer size corresponding to 1500 byte MTU (unpacked mode)
4312 * 3: Buffer size corresponding to 9000 byte MTU (unpacked mode)
4313 *
4314 * For the single-MTU buffers in unpacked mode we need to include
4315 * space for the SGE Control Packet Shift, 14 byte Ethernet header,
4316 * possible 4 byte VLAN tag, all rounded up to the next Ingress Packet
Joe Perchesdbedd442015-03-06 20:49:12 -08004317 * Padding boundary. All of these are accommodated in the Factory
Vipul Pandya636f9d32012-09-26 02:39:39 +00004318 * Default Firmware Configuration File but we need to adjust it for
4319 * this host's cache line size.
4320 */
Hariprasad Shenaif612b812015-01-05 16:30:43 +05304321 t4_write_reg(adap, SGE_FL_BUFFER_SIZE0_A, page_size);
4322 t4_write_reg(adap, SGE_FL_BUFFER_SIZE2_A,
4323 (t4_read_reg(adap, SGE_FL_BUFFER_SIZE2_A) + fl_align-1)
Vipul Pandya636f9d32012-09-26 02:39:39 +00004324 & ~(fl_align-1));
Hariprasad Shenaif612b812015-01-05 16:30:43 +05304325 t4_write_reg(adap, SGE_FL_BUFFER_SIZE3_A,
4326 (t4_read_reg(adap, SGE_FL_BUFFER_SIZE3_A) + fl_align-1)
Vipul Pandya636f9d32012-09-26 02:39:39 +00004327 & ~(fl_align-1));
4328
Hariprasad Shenai0d804332015-01-05 16:30:47 +05304329 t4_write_reg(adap, ULP_RX_TDDP_PSZ_A, HPZ0_V(page_shift - 12));
Vipul Pandya636f9d32012-09-26 02:39:39 +00004330
4331 return 0;
4332}
4333
4334/**
4335 * t4_fw_initialize - ask FW to initialize the device
4336 * @adap: the adapter
4337 * @mbox: mailbox to use for the FW command
4338 *
4339 * Issues a command to FW to partially initialize the device. This
4340 * performs initialization that generally doesn't depend on user input.
4341 */
4342int t4_fw_initialize(struct adapter *adap, unsigned int mbox)
4343{
4344 struct fw_initialize_cmd c;
4345
4346 memset(&c, 0, sizeof(c));
4347 INIT_CMD(c, INITIALIZE, WRITE);
4348 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
4349}
4350
4351/**
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004352 * t4_query_params - query FW or device parameters
4353 * @adap: the adapter
4354 * @mbox: mailbox to use for the FW command
4355 * @pf: the PF
4356 * @vf: the VF
4357 * @nparams: the number of parameters
4358 * @params: the parameter names
4359 * @val: the parameter values
4360 *
4361 * Reads the value of FW or device parameters. Up to 7 parameters can be
4362 * queried at once.
4363 */
4364int t4_query_params(struct adapter *adap, unsigned int mbox, unsigned int pf,
4365 unsigned int vf, unsigned int nparams, const u32 *params,
4366 u32 *val)
4367{
4368 int i, ret;
4369 struct fw_params_cmd c;
4370 __be32 *p = &c.param[0].mnem;
4371
4372 if (nparams > 7)
4373 return -EINVAL;
4374
4375 memset(&c, 0, sizeof(c));
Hariprasad Shenaif404f802015-05-19 18:20:44 +05304376 c.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_PARAMS_CMD) |
4377 FW_CMD_REQUEST_F | FW_CMD_READ_F |
4378 FW_PARAMS_CMD_PFN_V(pf) |
4379 FW_PARAMS_CMD_VFN_V(vf));
4380 c.retval_len16 = cpu_to_be32(FW_LEN16(c));
4381
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004382 for (i = 0; i < nparams; i++, p += 2)
Hariprasad Shenaif404f802015-05-19 18:20:44 +05304383 *p = cpu_to_be32(*params++);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004384
4385 ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
4386 if (ret == 0)
4387 for (i = 0, p = &c.param[0].val; i < nparams; i++, p += 2)
Hariprasad Shenaif404f802015-05-19 18:20:44 +05304388 *val++ = be32_to_cpu(*p);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004389 return ret;
4390}
4391
4392/**
Anish Bhatt688848b2014-06-19 21:37:13 -07004393 * t4_set_params_nosleep - sets FW or device parameters
4394 * @adap: the adapter
4395 * @mbox: mailbox to use for the FW command
4396 * @pf: the PF
4397 * @vf: the VF
4398 * @nparams: the number of parameters
4399 * @params: the parameter names
4400 * @val: the parameter values
4401 *
4402 * Does not ever sleep
4403 * Sets the value of FW or device parameters. Up to 7 parameters can be
4404 * specified at once.
4405 */
4406int t4_set_params_nosleep(struct adapter *adap, unsigned int mbox,
4407 unsigned int pf, unsigned int vf,
4408 unsigned int nparams, const u32 *params,
4409 const u32 *val)
4410{
4411 struct fw_params_cmd c;
4412 __be32 *p = &c.param[0].mnem;
4413
4414 if (nparams > 7)
4415 return -EINVAL;
4416
4417 memset(&c, 0, sizeof(c));
Hariprasad Shenaie2ac9622014-11-07 09:35:25 +05304418 c.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_PARAMS_CMD) |
4419 FW_CMD_REQUEST_F | FW_CMD_WRITE_F |
Hariprasad Shenai51678652014-11-21 12:52:02 +05304420 FW_PARAMS_CMD_PFN_V(pf) |
4421 FW_PARAMS_CMD_VFN_V(vf));
Anish Bhatt688848b2014-06-19 21:37:13 -07004422 c.retval_len16 = cpu_to_be32(FW_LEN16(c));
4423
4424 while (nparams--) {
4425 *p++ = cpu_to_be32(*params++);
4426 *p++ = cpu_to_be32(*val++);
4427 }
4428
4429 return t4_wr_mbox_ns(adap, mbox, &c, sizeof(c), NULL);
4430}
4431
4432/**
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004433 * t4_set_params - sets FW or device parameters
4434 * @adap: the adapter
4435 * @mbox: mailbox to use for the FW command
4436 * @pf: the PF
4437 * @vf: the VF
4438 * @nparams: the number of parameters
4439 * @params: the parameter names
4440 * @val: the parameter values
4441 *
4442 * Sets the value of FW or device parameters. Up to 7 parameters can be
4443 * specified at once.
4444 */
4445int t4_set_params(struct adapter *adap, unsigned int mbox, unsigned int pf,
4446 unsigned int vf, unsigned int nparams, const u32 *params,
4447 const u32 *val)
4448{
4449 struct fw_params_cmd c;
4450 __be32 *p = &c.param[0].mnem;
4451
4452 if (nparams > 7)
4453 return -EINVAL;
4454
4455 memset(&c, 0, sizeof(c));
Hariprasad Shenaif404f802015-05-19 18:20:44 +05304456 c.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_PARAMS_CMD) |
4457 FW_CMD_REQUEST_F | FW_CMD_WRITE_F |
4458 FW_PARAMS_CMD_PFN_V(pf) |
4459 FW_PARAMS_CMD_VFN_V(vf));
4460 c.retval_len16 = cpu_to_be32(FW_LEN16(c));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004461 while (nparams--) {
Hariprasad Shenaif404f802015-05-19 18:20:44 +05304462 *p++ = cpu_to_be32(*params++);
4463 *p++ = cpu_to_be32(*val++);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004464 }
4465
4466 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
4467}
4468
4469/**
4470 * t4_cfg_pfvf - configure PF/VF resource limits
4471 * @adap: the adapter
4472 * @mbox: mailbox to use for the FW command
4473 * @pf: the PF being configured
4474 * @vf: the VF being configured
4475 * @txq: the max number of egress queues
4476 * @txq_eth_ctrl: the max number of egress Ethernet or control queues
4477 * @rxqi: the max number of interrupt-capable ingress queues
4478 * @rxq: the max number of interruptless ingress queues
4479 * @tc: the PCI traffic class
4480 * @vi: the max number of virtual interfaces
4481 * @cmask: the channel access rights mask for the PF/VF
4482 * @pmask: the port access rights mask for the PF/VF
4483 * @nexact: the maximum number of exact MPS filters
4484 * @rcaps: read capabilities
4485 * @wxcaps: write/execute capabilities
4486 *
4487 * Configures resource limits and capabilities for a physical or virtual
4488 * function.
4489 */
4490int t4_cfg_pfvf(struct adapter *adap, unsigned int mbox, unsigned int pf,
4491 unsigned int vf, unsigned int txq, unsigned int txq_eth_ctrl,
4492 unsigned int rxqi, unsigned int rxq, unsigned int tc,
4493 unsigned int vi, unsigned int cmask, unsigned int pmask,
4494 unsigned int nexact, unsigned int rcaps, unsigned int wxcaps)
4495{
4496 struct fw_pfvf_cmd c;
4497
4498 memset(&c, 0, sizeof(c));
Hariprasad Shenaif404f802015-05-19 18:20:44 +05304499 c.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_PFVF_CMD) | FW_CMD_REQUEST_F |
4500 FW_CMD_WRITE_F | FW_PFVF_CMD_PFN_V(pf) |
4501 FW_PFVF_CMD_VFN_V(vf));
4502 c.retval_len16 = cpu_to_be32(FW_LEN16(c));
4503 c.niqflint_niq = cpu_to_be32(FW_PFVF_CMD_NIQFLINT_V(rxqi) |
4504 FW_PFVF_CMD_NIQ_V(rxq));
4505 c.type_to_neq = cpu_to_be32(FW_PFVF_CMD_CMASK_V(cmask) |
4506 FW_PFVF_CMD_PMASK_V(pmask) |
4507 FW_PFVF_CMD_NEQ_V(txq));
4508 c.tc_to_nexactf = cpu_to_be32(FW_PFVF_CMD_TC_V(tc) |
4509 FW_PFVF_CMD_NVI_V(vi) |
4510 FW_PFVF_CMD_NEXACTF_V(nexact));
4511 c.r_caps_to_nethctrl = cpu_to_be32(FW_PFVF_CMD_R_CAPS_V(rcaps) |
4512 FW_PFVF_CMD_WX_CAPS_V(wxcaps) |
4513 FW_PFVF_CMD_NETHCTRL_V(txq_eth_ctrl));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004514 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
4515}
4516
4517/**
4518 * t4_alloc_vi - allocate a virtual interface
4519 * @adap: the adapter
4520 * @mbox: mailbox to use for the FW command
4521 * @port: physical port associated with the VI
4522 * @pf: the PF owning the VI
4523 * @vf: the VF owning the VI
4524 * @nmac: number of MAC addresses needed (1 to 5)
4525 * @mac: the MAC addresses of the VI
4526 * @rss_size: size of RSS table slice associated with this VI
4527 *
4528 * Allocates a virtual interface for the given physical port. If @mac is
4529 * not %NULL it contains the MAC addresses of the VI as assigned by FW.
4530 * @mac should be large enough to hold @nmac Ethernet addresses, they are
4531 * stored consecutively so the space needed is @nmac * 6 bytes.
4532 * Returns a negative error number or the non-negative VI id.
4533 */
4534int t4_alloc_vi(struct adapter *adap, unsigned int mbox, unsigned int port,
4535 unsigned int pf, unsigned int vf, unsigned int nmac, u8 *mac,
4536 unsigned int *rss_size)
4537{
4538 int ret;
4539 struct fw_vi_cmd c;
4540
4541 memset(&c, 0, sizeof(c));
Hariprasad Shenaif404f802015-05-19 18:20:44 +05304542 c.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_VI_CMD) | FW_CMD_REQUEST_F |
4543 FW_CMD_WRITE_F | FW_CMD_EXEC_F |
4544 FW_VI_CMD_PFN_V(pf) | FW_VI_CMD_VFN_V(vf));
4545 c.alloc_to_len16 = cpu_to_be32(FW_VI_CMD_ALLOC_F | FW_LEN16(c));
Hariprasad Shenai2b5fb1f2014-11-21 12:52:04 +05304546 c.portid_pkd = FW_VI_CMD_PORTID_V(port);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004547 c.nmac = nmac - 1;
4548
4549 ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
4550 if (ret)
4551 return ret;
4552
4553 if (mac) {
4554 memcpy(mac, c.mac, sizeof(c.mac));
4555 switch (nmac) {
4556 case 5:
4557 memcpy(mac + 24, c.nmac3, sizeof(c.nmac3));
4558 case 4:
4559 memcpy(mac + 18, c.nmac2, sizeof(c.nmac2));
4560 case 3:
4561 memcpy(mac + 12, c.nmac1, sizeof(c.nmac1));
4562 case 2:
4563 memcpy(mac + 6, c.nmac0, sizeof(c.nmac0));
4564 }
4565 }
4566 if (rss_size)
Hariprasad Shenaif404f802015-05-19 18:20:44 +05304567 *rss_size = FW_VI_CMD_RSSSIZE_G(be16_to_cpu(c.rsssize_pkd));
4568 return FW_VI_CMD_VIID_G(be16_to_cpu(c.type_viid));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004569}
4570
4571/**
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004572 * t4_set_rxmode - set Rx properties of a virtual interface
4573 * @adap: the adapter
4574 * @mbox: mailbox to use for the FW command
4575 * @viid: the VI id
4576 * @mtu: the new MTU or -1
4577 * @promisc: 1 to enable promiscuous mode, 0 to disable it, -1 no change
4578 * @all_multi: 1 to enable all-multi mode, 0 to disable it, -1 no change
4579 * @bcast: 1 to enable broadcast Rx, 0 to disable it, -1 no change
Dimitris Michailidisf8f5aaf2010-05-10 15:58:07 +00004580 * @vlanex: 1 to enable HW VLAN extraction, 0 to disable it, -1 no change
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004581 * @sleep_ok: if true we may sleep while awaiting command completion
4582 *
4583 * Sets Rx properties of a virtual interface.
4584 */
4585int t4_set_rxmode(struct adapter *adap, unsigned int mbox, unsigned int viid,
Dimitris Michailidisf8f5aaf2010-05-10 15:58:07 +00004586 int mtu, int promisc, int all_multi, int bcast, int vlanex,
4587 bool sleep_ok)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004588{
4589 struct fw_vi_rxmode_cmd c;
4590
4591 /* convert to FW values */
4592 if (mtu < 0)
4593 mtu = FW_RXMODE_MTU_NO_CHG;
4594 if (promisc < 0)
Hariprasad Shenai2b5fb1f2014-11-21 12:52:04 +05304595 promisc = FW_VI_RXMODE_CMD_PROMISCEN_M;
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004596 if (all_multi < 0)
Hariprasad Shenai2b5fb1f2014-11-21 12:52:04 +05304597 all_multi = FW_VI_RXMODE_CMD_ALLMULTIEN_M;
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004598 if (bcast < 0)
Hariprasad Shenai2b5fb1f2014-11-21 12:52:04 +05304599 bcast = FW_VI_RXMODE_CMD_BROADCASTEN_M;
Dimitris Michailidisf8f5aaf2010-05-10 15:58:07 +00004600 if (vlanex < 0)
Hariprasad Shenai2b5fb1f2014-11-21 12:52:04 +05304601 vlanex = FW_VI_RXMODE_CMD_VLANEXEN_M;
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004602
4603 memset(&c, 0, sizeof(c));
Hariprasad Shenaif404f802015-05-19 18:20:44 +05304604 c.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_RXMODE_CMD) |
4605 FW_CMD_REQUEST_F | FW_CMD_WRITE_F |
4606 FW_VI_RXMODE_CMD_VIID_V(viid));
4607 c.retval_len16 = cpu_to_be32(FW_LEN16(c));
4608 c.mtu_to_vlanexen =
4609 cpu_to_be32(FW_VI_RXMODE_CMD_MTU_V(mtu) |
4610 FW_VI_RXMODE_CMD_PROMISCEN_V(promisc) |
4611 FW_VI_RXMODE_CMD_ALLMULTIEN_V(all_multi) |
4612 FW_VI_RXMODE_CMD_BROADCASTEN_V(bcast) |
4613 FW_VI_RXMODE_CMD_VLANEXEN_V(vlanex));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004614 return t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), NULL, sleep_ok);
4615}
4616
4617/**
4618 * t4_alloc_mac_filt - allocates exact-match filters for MAC addresses
4619 * @adap: the adapter
4620 * @mbox: mailbox to use for the FW command
4621 * @viid: the VI id
4622 * @free: if true any existing filters for this VI id are first removed
4623 * @naddr: the number of MAC addresses to allocate filters for (up to 7)
4624 * @addr: the MAC address(es)
4625 * @idx: where to store the index of each allocated filter
4626 * @hash: pointer to hash address filter bitmap
4627 * @sleep_ok: call is allowed to sleep
4628 *
4629 * Allocates an exact-match filter for each of the supplied addresses and
4630 * sets it to the corresponding address. If @idx is not %NULL it should
4631 * have at least @naddr entries, each of which will be set to the index of
4632 * the filter allocated for the corresponding MAC address. If a filter
4633 * could not be allocated for an address its index is set to 0xffff.
4634 * If @hash is not %NULL addresses that fail to allocate an exact filter
4635 * are hashed and update the hash filter bitmap pointed at by @hash.
4636 *
4637 * Returns a negative error number or the number of filters allocated.
4638 */
4639int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox,
4640 unsigned int viid, bool free, unsigned int naddr,
4641 const u8 **addr, u16 *idx, u64 *hash, bool sleep_ok)
4642{
4643 int i, ret;
4644 struct fw_vi_mac_cmd c;
4645 struct fw_vi_mac_exact *p;
Hariprasad Shenaid14807d2013-12-03 17:05:56 +05304646 unsigned int max_naddr = is_t4(adap->params.chip) ?
Santosh Rastapur0a57a532013-03-14 05:08:49 +00004647 NUM_MPS_CLS_SRAM_L_INSTANCES :
4648 NUM_MPS_T5_CLS_SRAM_L_INSTANCES;
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004649
4650 if (naddr > 7)
4651 return -EINVAL;
4652
4653 memset(&c, 0, sizeof(c));
Hariprasad Shenaif404f802015-05-19 18:20:44 +05304654 c.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_MAC_CMD) |
4655 FW_CMD_REQUEST_F | FW_CMD_WRITE_F |
4656 (free ? FW_CMD_EXEC_F : 0) |
4657 FW_VI_MAC_CMD_VIID_V(viid));
4658 c.freemacs_to_len16 = cpu_to_be32(FW_VI_MAC_CMD_FREEMACS_V(free) |
4659 FW_CMD_LEN16_V((naddr + 2) / 2));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004660
4661 for (i = 0, p = c.u.exact; i < naddr; i++, p++) {
Hariprasad Shenaif404f802015-05-19 18:20:44 +05304662 p->valid_to_idx =
4663 cpu_to_be16(FW_VI_MAC_CMD_VALID_F |
4664 FW_VI_MAC_CMD_IDX_V(FW_VI_MAC_ADD_MAC));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004665 memcpy(p->macaddr, addr[i], sizeof(p->macaddr));
4666 }
4667
4668 ret = t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), &c, sleep_ok);
4669 if (ret)
4670 return ret;
4671
4672 for (i = 0, p = c.u.exact; i < naddr; i++, p++) {
Hariprasad Shenaif404f802015-05-19 18:20:44 +05304673 u16 index = FW_VI_MAC_CMD_IDX_G(be16_to_cpu(p->valid_to_idx));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004674
4675 if (idx)
Santosh Rastapur0a57a532013-03-14 05:08:49 +00004676 idx[i] = index >= max_naddr ? 0xffff : index;
4677 if (index < max_naddr)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004678 ret++;
4679 else if (hash)
Dimitris Michailidisce9aeb52010-12-03 10:39:04 +00004680 *hash |= (1ULL << hash_mac_addr(addr[i]));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004681 }
4682 return ret;
4683}
4684
4685/**
4686 * t4_change_mac - modifies the exact-match filter for a MAC address
4687 * @adap: the adapter
4688 * @mbox: mailbox to use for the FW command
4689 * @viid: the VI id
4690 * @idx: index of existing filter for old value of MAC address, or -1
4691 * @addr: the new MAC address value
4692 * @persist: whether a new MAC allocation should be persistent
4693 * @add_smt: if true also add the address to the HW SMT
4694 *
4695 * Modifies an exact-match filter and sets it to the new MAC address.
4696 * Note that in general it is not possible to modify the value of a given
4697 * filter so the generic way to modify an address filter is to free the one
4698 * being used by the old address value and allocate a new filter for the
4699 * new address value. @idx can be -1 if the address is a new addition.
4700 *
4701 * Returns a negative error number or the index of the filter with the new
4702 * MAC value.
4703 */
4704int t4_change_mac(struct adapter *adap, unsigned int mbox, unsigned int viid,
4705 int idx, const u8 *addr, bool persist, bool add_smt)
4706{
4707 int ret, mode;
4708 struct fw_vi_mac_cmd c;
4709 struct fw_vi_mac_exact *p = c.u.exact;
Hariprasad Shenaid14807d2013-12-03 17:05:56 +05304710 unsigned int max_mac_addr = is_t4(adap->params.chip) ?
Santosh Rastapur0a57a532013-03-14 05:08:49 +00004711 NUM_MPS_CLS_SRAM_L_INSTANCES :
4712 NUM_MPS_T5_CLS_SRAM_L_INSTANCES;
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004713
4714 if (idx < 0) /* new allocation */
4715 idx = persist ? FW_VI_MAC_ADD_PERSIST_MAC : FW_VI_MAC_ADD_MAC;
4716 mode = add_smt ? FW_VI_MAC_SMT_AND_MPSTCAM : FW_VI_MAC_MPS_TCAM_ENTRY;
4717
4718 memset(&c, 0, sizeof(c));
Hariprasad Shenaif404f802015-05-19 18:20:44 +05304719 c.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_MAC_CMD) |
4720 FW_CMD_REQUEST_F | FW_CMD_WRITE_F |
4721 FW_VI_MAC_CMD_VIID_V(viid));
4722 c.freemacs_to_len16 = cpu_to_be32(FW_CMD_LEN16_V(1));
4723 p->valid_to_idx = cpu_to_be16(FW_VI_MAC_CMD_VALID_F |
4724 FW_VI_MAC_CMD_SMAC_RESULT_V(mode) |
4725 FW_VI_MAC_CMD_IDX_V(idx));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004726 memcpy(p->macaddr, addr, sizeof(p->macaddr));
4727
4728 ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
4729 if (ret == 0) {
Hariprasad Shenaif404f802015-05-19 18:20:44 +05304730 ret = FW_VI_MAC_CMD_IDX_G(be16_to_cpu(p->valid_to_idx));
Santosh Rastapur0a57a532013-03-14 05:08:49 +00004731 if (ret >= max_mac_addr)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004732 ret = -ENOMEM;
4733 }
4734 return ret;
4735}
4736
4737/**
4738 * t4_set_addr_hash - program the MAC inexact-match hash filter
4739 * @adap: the adapter
4740 * @mbox: mailbox to use for the FW command
4741 * @viid: the VI id
4742 * @ucast: whether the hash filter should also match unicast addresses
4743 * @vec: the value to be written to the hash filter
4744 * @sleep_ok: call is allowed to sleep
4745 *
4746 * Sets the 64-bit inexact-match hash filter for a virtual interface.
4747 */
4748int t4_set_addr_hash(struct adapter *adap, unsigned int mbox, unsigned int viid,
4749 bool ucast, u64 vec, bool sleep_ok)
4750{
4751 struct fw_vi_mac_cmd c;
4752
4753 memset(&c, 0, sizeof(c));
Hariprasad Shenaif404f802015-05-19 18:20:44 +05304754 c.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_MAC_CMD) |
4755 FW_CMD_REQUEST_F | FW_CMD_WRITE_F |
4756 FW_VI_ENABLE_CMD_VIID_V(viid));
4757 c.freemacs_to_len16 = cpu_to_be32(FW_VI_MAC_CMD_HASHVECEN_F |
4758 FW_VI_MAC_CMD_HASHUNIEN_V(ucast) |
4759 FW_CMD_LEN16_V(1));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004760 c.u.hash.hashvec = cpu_to_be64(vec);
4761 return t4_wr_mbox_meat(adap, mbox, &c, sizeof(c), NULL, sleep_ok);
4762}
4763
4764/**
Anish Bhatt688848b2014-06-19 21:37:13 -07004765 * t4_enable_vi_params - enable/disable a virtual interface
4766 * @adap: the adapter
4767 * @mbox: mailbox to use for the FW command
4768 * @viid: the VI id
4769 * @rx_en: 1=enable Rx, 0=disable Rx
4770 * @tx_en: 1=enable Tx, 0=disable Tx
4771 * @dcb_en: 1=enable delivery of Data Center Bridging messages.
4772 *
4773 * Enables/disables a virtual interface. Note that setting DCB Enable
4774 * only makes sense when enabling a Virtual Interface ...
4775 */
4776int t4_enable_vi_params(struct adapter *adap, unsigned int mbox,
4777 unsigned int viid, bool rx_en, bool tx_en, bool dcb_en)
4778{
4779 struct fw_vi_enable_cmd c;
4780
4781 memset(&c, 0, sizeof(c));
Hariprasad Shenaif404f802015-05-19 18:20:44 +05304782 c.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_ENABLE_CMD) |
4783 FW_CMD_REQUEST_F | FW_CMD_EXEC_F |
4784 FW_VI_ENABLE_CMD_VIID_V(viid));
4785 c.ien_to_len16 = cpu_to_be32(FW_VI_ENABLE_CMD_IEN_V(rx_en) |
4786 FW_VI_ENABLE_CMD_EEN_V(tx_en) |
4787 FW_VI_ENABLE_CMD_DCB_INFO_V(dcb_en) |
4788 FW_LEN16(c));
Anish Bhatt30f00842014-08-05 16:05:23 -07004789 return t4_wr_mbox_ns(adap, mbox, &c, sizeof(c), NULL);
Anish Bhatt688848b2014-06-19 21:37:13 -07004790}
4791
4792/**
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004793 * t4_enable_vi - enable/disable a virtual interface
4794 * @adap: the adapter
4795 * @mbox: mailbox to use for the FW command
4796 * @viid: the VI id
4797 * @rx_en: 1=enable Rx, 0=disable Rx
4798 * @tx_en: 1=enable Tx, 0=disable Tx
4799 *
4800 * Enables/disables a virtual interface.
4801 */
4802int t4_enable_vi(struct adapter *adap, unsigned int mbox, unsigned int viid,
4803 bool rx_en, bool tx_en)
4804{
Anish Bhatt688848b2014-06-19 21:37:13 -07004805 return t4_enable_vi_params(adap, mbox, viid, rx_en, tx_en, 0);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004806}
4807
4808/**
4809 * t4_identify_port - identify a VI's port by blinking its LED
4810 * @adap: the adapter
4811 * @mbox: mailbox to use for the FW command
4812 * @viid: the VI id
4813 * @nblinks: how many times to blink LED at 2.5 Hz
4814 *
4815 * Identifies a VI's port by blinking its LED.
4816 */
4817int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid,
4818 unsigned int nblinks)
4819{
4820 struct fw_vi_enable_cmd c;
4821
Vipul Pandya0062b152012-11-06 03:37:09 +00004822 memset(&c, 0, sizeof(c));
Hariprasad Shenaif404f802015-05-19 18:20:44 +05304823 c.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_VI_ENABLE_CMD) |
4824 FW_CMD_REQUEST_F | FW_CMD_EXEC_F |
4825 FW_VI_ENABLE_CMD_VIID_V(viid));
4826 c.ien_to_len16 = cpu_to_be32(FW_VI_ENABLE_CMD_LED_F | FW_LEN16(c));
4827 c.blinkdur = cpu_to_be16(nblinks);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004828 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
4829}
4830
4831/**
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004832 * t4_iq_free - free an ingress queue and its FLs
4833 * @adap: the adapter
4834 * @mbox: mailbox to use for the FW command
4835 * @pf: the PF owning the queues
4836 * @vf: the VF owning the queues
4837 * @iqtype: the ingress queue type
4838 * @iqid: ingress queue id
4839 * @fl0id: FL0 queue id or 0xffff if no attached FL0
4840 * @fl1id: FL1 queue id or 0xffff if no attached FL1
4841 *
4842 * Frees an ingress queue and its associated FLs, if any.
4843 */
4844int t4_iq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
4845 unsigned int vf, unsigned int iqtype, unsigned int iqid,
4846 unsigned int fl0id, unsigned int fl1id)
4847{
4848 struct fw_iq_cmd c;
4849
4850 memset(&c, 0, sizeof(c));
Hariprasad Shenaif404f802015-05-19 18:20:44 +05304851 c.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_IQ_CMD) | FW_CMD_REQUEST_F |
4852 FW_CMD_EXEC_F | FW_IQ_CMD_PFN_V(pf) |
4853 FW_IQ_CMD_VFN_V(vf));
4854 c.alloc_to_len16 = cpu_to_be32(FW_IQ_CMD_FREE_F | FW_LEN16(c));
4855 c.type_to_iqandstindex = cpu_to_be32(FW_IQ_CMD_TYPE_V(iqtype));
4856 c.iqid = cpu_to_be16(iqid);
4857 c.fl0id = cpu_to_be16(fl0id);
4858 c.fl1id = cpu_to_be16(fl1id);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004859 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
4860}
4861
4862/**
4863 * t4_eth_eq_free - free an Ethernet egress queue
4864 * @adap: the adapter
4865 * @mbox: mailbox to use for the FW command
4866 * @pf: the PF owning the queue
4867 * @vf: the VF owning the queue
4868 * @eqid: egress queue id
4869 *
4870 * Frees an Ethernet egress queue.
4871 */
4872int t4_eth_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
4873 unsigned int vf, unsigned int eqid)
4874{
4875 struct fw_eq_eth_cmd c;
4876
4877 memset(&c, 0, sizeof(c));
Hariprasad Shenaif404f802015-05-19 18:20:44 +05304878 c.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_EQ_ETH_CMD) |
4879 FW_CMD_REQUEST_F | FW_CMD_EXEC_F |
4880 FW_EQ_ETH_CMD_PFN_V(pf) |
4881 FW_EQ_ETH_CMD_VFN_V(vf));
4882 c.alloc_to_len16 = cpu_to_be32(FW_EQ_ETH_CMD_FREE_F | FW_LEN16(c));
4883 c.eqid_pkd = cpu_to_be32(FW_EQ_ETH_CMD_EQID_V(eqid));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004884 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
4885}
4886
4887/**
4888 * t4_ctrl_eq_free - free a control egress queue
4889 * @adap: the adapter
4890 * @mbox: mailbox to use for the FW command
4891 * @pf: the PF owning the queue
4892 * @vf: the VF owning the queue
4893 * @eqid: egress queue id
4894 *
4895 * Frees a control egress queue.
4896 */
4897int t4_ctrl_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
4898 unsigned int vf, unsigned int eqid)
4899{
4900 struct fw_eq_ctrl_cmd c;
4901
4902 memset(&c, 0, sizeof(c));
Hariprasad Shenaif404f802015-05-19 18:20:44 +05304903 c.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_EQ_CTRL_CMD) |
4904 FW_CMD_REQUEST_F | FW_CMD_EXEC_F |
4905 FW_EQ_CTRL_CMD_PFN_V(pf) |
4906 FW_EQ_CTRL_CMD_VFN_V(vf));
4907 c.alloc_to_len16 = cpu_to_be32(FW_EQ_CTRL_CMD_FREE_F | FW_LEN16(c));
4908 c.cmpliqid_eqid = cpu_to_be32(FW_EQ_CTRL_CMD_EQID_V(eqid));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004909 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
4910}
4911
4912/**
4913 * t4_ofld_eq_free - free an offload egress queue
4914 * @adap: the adapter
4915 * @mbox: mailbox to use for the FW command
4916 * @pf: the PF owning the queue
4917 * @vf: the VF owning the queue
4918 * @eqid: egress queue id
4919 *
4920 * Frees a control egress queue.
4921 */
4922int t4_ofld_eq_free(struct adapter *adap, unsigned int mbox, unsigned int pf,
4923 unsigned int vf, unsigned int eqid)
4924{
4925 struct fw_eq_ofld_cmd c;
4926
4927 memset(&c, 0, sizeof(c));
Hariprasad Shenaif404f802015-05-19 18:20:44 +05304928 c.op_to_vfn = cpu_to_be32(FW_CMD_OP_V(FW_EQ_OFLD_CMD) |
4929 FW_CMD_REQUEST_F | FW_CMD_EXEC_F |
4930 FW_EQ_OFLD_CMD_PFN_V(pf) |
4931 FW_EQ_OFLD_CMD_VFN_V(vf));
4932 c.alloc_to_len16 = cpu_to_be32(FW_EQ_OFLD_CMD_FREE_F | FW_LEN16(c));
4933 c.eqid_pkd = cpu_to_be32(FW_EQ_OFLD_CMD_EQID_V(eqid));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004934 return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
4935}
4936
4937/**
4938 * t4_handle_fw_rpl - process a FW reply message
4939 * @adap: the adapter
4940 * @rpl: start of the FW message
4941 *
4942 * Processes a FW message, such as link state change messages.
4943 */
4944int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
4945{
4946 u8 opcode = *(const u8 *)rpl;
4947
4948 if (opcode == FW_PORT_CMD) { /* link/module state change message */
4949 int speed = 0, fc = 0;
4950 const struct fw_port_cmd *p = (void *)rpl;
Hariprasad Shenaif404f802015-05-19 18:20:44 +05304951 int chan = FW_PORT_CMD_PORTID_G(be32_to_cpu(p->op_to_portid));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004952 int port = adap->chan_map[chan];
4953 struct port_info *pi = adap2pinfo(adap, port);
4954 struct link_config *lc = &pi->link_cfg;
Hariprasad Shenaif404f802015-05-19 18:20:44 +05304955 u32 stat = be32_to_cpu(p->u.info.lstatus_to_modtype);
Hariprasad Shenai2b5fb1f2014-11-21 12:52:04 +05304956 int link_ok = (stat & FW_PORT_CMD_LSTATUS_F) != 0;
4957 u32 mod = FW_PORT_CMD_MODTYPE_G(stat);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004958
Hariprasad Shenai2b5fb1f2014-11-21 12:52:04 +05304959 if (stat & FW_PORT_CMD_RXPAUSE_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004960 fc |= PAUSE_RX;
Hariprasad Shenai2b5fb1f2014-11-21 12:52:04 +05304961 if (stat & FW_PORT_CMD_TXPAUSE_F)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004962 fc |= PAUSE_TX;
Hariprasad Shenai2b5fb1f2014-11-21 12:52:04 +05304963 if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100M))
Ben Hutchingse8b39012014-02-23 00:03:24 +00004964 speed = 100;
Hariprasad Shenai2b5fb1f2014-11-21 12:52:04 +05304965 else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_1G))
Ben Hutchingse8b39012014-02-23 00:03:24 +00004966 speed = 1000;
Hariprasad Shenai2b5fb1f2014-11-21 12:52:04 +05304967 else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G))
Ben Hutchingse8b39012014-02-23 00:03:24 +00004968 speed = 10000;
Hariprasad Shenai2b5fb1f2014-11-21 12:52:04 +05304969 else if (stat & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G))
Ben Hutchingse8b39012014-02-23 00:03:24 +00004970 speed = 40000;
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004971
4972 if (link_ok != lc->link_ok || speed != lc->speed ||
4973 fc != lc->fc) { /* something changed */
4974 lc->link_ok = link_ok;
4975 lc->speed = speed;
4976 lc->fc = fc;
Hariprasad Shenai444018a2014-09-01 19:54:55 +05304977 lc->supported = be16_to_cpu(p->u.info.pcap);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004978 t4_os_link_changed(adap, port, link_ok);
4979 }
4980 if (mod != pi->mod_type) {
4981 pi->mod_type = mod;
4982 t4_os_portmod_changed(adap, port);
4983 }
4984 }
4985 return 0;
4986}
4987
Greg Kroah-Hartman1dd06ae2012-12-06 14:30:56 +00004988static void get_pci_mode(struct adapter *adapter, struct pci_params *p)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004989{
4990 u16 val;
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004991
Jiang Liue5c8ae52012-08-20 13:53:19 -06004992 if (pci_is_pcie(adapter->pdev)) {
4993 pcie_capability_read_word(adapter->pdev, PCI_EXP_LNKSTA, &val);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00004994 p->speed = val & PCI_EXP_LNKSTA_CLS;
4995 p->width = (val & PCI_EXP_LNKSTA_NLW) >> 4;
4996 }
4997}
4998
4999/**
5000 * init_link_config - initialize a link's SW state
5001 * @lc: structure holding the link state
5002 * @caps: link capabilities
5003 *
5004 * Initializes the SW state maintained for each link, including the link's
5005 * capabilities and default speed/flow-control/autonegotiation settings.
5006 */
Greg Kroah-Hartman1dd06ae2012-12-06 14:30:56 +00005007static void init_link_config(struct link_config *lc, unsigned int caps)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00005008{
5009 lc->supported = caps;
5010 lc->requested_speed = 0;
5011 lc->speed = 0;
5012 lc->requested_fc = lc->fc = PAUSE_RX | PAUSE_TX;
5013 if (lc->supported & FW_PORT_CAP_ANEG) {
5014 lc->advertising = lc->supported & ADVERT_MASK;
5015 lc->autoneg = AUTONEG_ENABLE;
5016 lc->requested_fc |= PAUSE_AUTONEG;
5017 } else {
5018 lc->advertising = 0;
5019 lc->autoneg = AUTONEG_DISABLE;
5020 }
5021}
5022
Hariprasad Shenai8203b502014-10-09 05:48:47 +05305023#define CIM_PF_NOACCESS 0xeeeeeeee
5024
5025int t4_wait_dev_ready(void __iomem *regs)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00005026{
Hariprasad Shenai8203b502014-10-09 05:48:47 +05305027 u32 whoami;
5028
Hariprasad Shenai0d804332015-01-05 16:30:47 +05305029 whoami = readl(regs + PL_WHOAMI_A);
Hariprasad Shenai8203b502014-10-09 05:48:47 +05305030 if (whoami != 0xffffffff && whoami != CIM_PF_NOACCESS)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00005031 return 0;
Hariprasad Shenai8203b502014-10-09 05:48:47 +05305032
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00005033 msleep(500);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05305034 whoami = readl(regs + PL_WHOAMI_A);
Hariprasad Shenai8203b502014-10-09 05:48:47 +05305035 return (whoami != 0xffffffff && whoami != CIM_PF_NOACCESS ? 0 : -EIO);
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00005036}
5037
Hariprasad Shenaife2ee132014-09-10 17:44:28 +05305038struct flash_desc {
5039 u32 vendor_and_model_id;
5040 u32 size_mb;
5041};
5042
Bill Pemberton91744942012-12-03 09:23:02 -05005043static int get_flash_params(struct adapter *adap)
Dimitris Michailidis900a6592010-06-18 10:05:27 +00005044{
Hariprasad Shenaife2ee132014-09-10 17:44:28 +05305045 /* Table for non-Numonix supported flash parts. Numonix parts are left
5046 * to the preexisting code. All flash parts have 64KB sectors.
5047 */
5048 static struct flash_desc supported_flash[] = {
5049 { 0x150201, 4 << 20 }, /* Spansion 4MB S25FL032P */
5050 };
5051
Dimitris Michailidis900a6592010-06-18 10:05:27 +00005052 int ret;
5053 u32 info;
5054
5055 ret = sf1_write(adap, 1, 1, 0, SF_RD_ID);
5056 if (!ret)
5057 ret = sf1_read(adap, 3, 0, 1, &info);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05305058 t4_write_reg(adap, SF_OP_A, 0); /* unlock SF */
Dimitris Michailidis900a6592010-06-18 10:05:27 +00005059 if (ret)
5060 return ret;
5061
Hariprasad Shenaife2ee132014-09-10 17:44:28 +05305062 for (ret = 0; ret < ARRAY_SIZE(supported_flash); ++ret)
5063 if (supported_flash[ret].vendor_and_model_id == info) {
5064 adap->params.sf_size = supported_flash[ret].size_mb;
5065 adap->params.sf_nsec =
5066 adap->params.sf_size / SF_SEC_SIZE;
5067 return 0;
5068 }
5069
Dimitris Michailidis900a6592010-06-18 10:05:27 +00005070 if ((info & 0xff) != 0x20) /* not a Numonix flash */
5071 return -EINVAL;
5072 info >>= 16; /* log2 of size */
5073 if (info >= 0x14 && info < 0x18)
5074 adap->params.sf_nsec = 1 << (info - 16);
5075 else if (info == 0x18)
5076 adap->params.sf_nsec = 64;
5077 else
5078 return -EINVAL;
5079 adap->params.sf_size = 1 << info;
5080 adap->params.sf_fw_start =
Hariprasad Shenai89c3a862015-01-05 16:30:45 +05305081 t4_read_reg(adap, CIM_BOOT_CFG_A) & BOOTADDR_M;
Hariprasad Shenaic2906072014-09-10 17:44:30 +05305082
5083 if (adap->params.sf_size < FLASH_MIN_SIZE)
5084 dev_warn(adap->pdev_dev, "WARNING!!! FLASH size %#x < %#x!!!\n",
5085 adap->params.sf_size, FLASH_MIN_SIZE);
Dimitris Michailidis900a6592010-06-18 10:05:27 +00005086 return 0;
5087}
5088
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00005089/**
5090 * t4_prep_adapter - prepare SW and HW for operation
5091 * @adapter: the adapter
5092 * @reset: if true perform a HW reset
5093 *
5094 * Initialize adapter SW state for the various HW modules, set initial
5095 * values for some adapter tunables, take PHYs out of reset, and
5096 * initialize the MDIO interface.
5097 */
Bill Pemberton91744942012-12-03 09:23:02 -05005098int t4_prep_adapter(struct adapter *adapter)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00005099{
Santosh Rastapur0a57a532013-03-14 05:08:49 +00005100 int ret, ver;
5101 uint16_t device_id;
Hariprasad Shenaid14807d2013-12-03 17:05:56 +05305102 u32 pl_rev;
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00005103
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00005104 get_pci_mode(adapter, &adapter->params.pci);
Hariprasad Shenai0d804332015-01-05 16:30:47 +05305105 pl_rev = REV_G(t4_read_reg(adapter, PL_REV_A));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00005106
Dimitris Michailidis900a6592010-06-18 10:05:27 +00005107 ret = get_flash_params(adapter);
5108 if (ret < 0) {
5109 dev_err(adapter->pdev_dev, "error %d identifying flash\n", ret);
5110 return ret;
5111 }
5112
Santosh Rastapur0a57a532013-03-14 05:08:49 +00005113 /* Retrieve adapter's device ID
5114 */
5115 pci_read_config_word(adapter->pdev, PCI_DEVICE_ID, &device_id);
5116 ver = device_id >> 12;
Hariprasad Shenaid14807d2013-12-03 17:05:56 +05305117 adapter->params.chip = 0;
Santosh Rastapur0a57a532013-03-14 05:08:49 +00005118 switch (ver) {
5119 case CHELSIO_T4:
Hariprasad Shenaid14807d2013-12-03 17:05:56 +05305120 adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T4, pl_rev);
Santosh Rastapur0a57a532013-03-14 05:08:49 +00005121 break;
5122 case CHELSIO_T5:
Hariprasad Shenaid14807d2013-12-03 17:05:56 +05305123 adapter->params.chip |= CHELSIO_CHIP_CODE(CHELSIO_T5, pl_rev);
Santosh Rastapur0a57a532013-03-14 05:08:49 +00005124 break;
5125 default:
5126 dev_err(adapter->pdev_dev, "Device %d is not supported\n",
5127 device_id);
5128 return -EINVAL;
5129 }
5130
Hariprasad Shenaif1ff24a2015-01-07 08:48:01 +05305131 adapter->params.cim_la_size = CIMLA_SIZE;
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00005132 init_cong_ctrl(adapter->params.a_wnd, adapter->params.b_wnd);
5133
5134 /*
5135 * Default port for debugging in case we can't reach FW.
5136 */
5137 adapter->params.nports = 1;
5138 adapter->params.portvec = 1;
Vipul Pandya636f9d32012-09-26 02:39:39 +00005139 adapter->params.vpd.cclk = 50000;
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00005140 return 0;
5141}
5142
Kumar Sanghvidcf7b6f2013-12-18 16:38:23 +05305143/**
Stephen Rothwelldd0bcc02014-12-10 19:48:02 +11005144 * cxgb4_t4_bar2_sge_qregs - return BAR2 SGE Queue register information
Hariprasad Shenaie85c9a72014-12-03 19:32:52 +05305145 * @adapter: the adapter
5146 * @qid: the Queue ID
5147 * @qtype: the Ingress or Egress type for @qid
5148 * @pbar2_qoffset: BAR2 Queue Offset
5149 * @pbar2_qid: BAR2 Queue ID or 0 for Queue ID inferred SGE Queues
5150 *
5151 * Returns the BAR2 SGE Queue Registers information associated with the
5152 * indicated Absolute Queue ID. These are passed back in return value
5153 * pointers. @qtype should be T4_BAR2_QTYPE_EGRESS for Egress Queue
5154 * and T4_BAR2_QTYPE_INGRESS for Ingress Queues.
5155 *
5156 * This may return an error which indicates that BAR2 SGE Queue
5157 * registers aren't available. If an error is not returned, then the
5158 * following values are returned:
5159 *
5160 * *@pbar2_qoffset: the BAR2 Offset of the @qid Registers
5161 * *@pbar2_qid: the BAR2 SGE Queue ID or 0 of @qid
5162 *
5163 * If the returned BAR2 Queue ID is 0, then BAR2 SGE registers which
5164 * require the "Inferred Queue ID" ability may be used. E.g. the
5165 * Write Combining Doorbell Buffer. If the BAR2 Queue ID is not 0,
5166 * then these "Inferred Queue ID" register may not be used.
5167 */
Stephen Rothwelldd0bcc02014-12-10 19:48:02 +11005168int cxgb4_t4_bar2_sge_qregs(struct adapter *adapter,
Hariprasad Shenaie85c9a72014-12-03 19:32:52 +05305169 unsigned int qid,
5170 enum t4_bar2_qtype qtype,
5171 u64 *pbar2_qoffset,
5172 unsigned int *pbar2_qid)
5173{
5174 unsigned int page_shift, page_size, qpp_shift, qpp_mask;
5175 u64 bar2_page_offset, bar2_qoffset;
5176 unsigned int bar2_qid, bar2_qid_offset, bar2_qinferred;
5177
5178 /* T4 doesn't support BAR2 SGE Queue registers.
5179 */
5180 if (is_t4(adapter->params.chip))
5181 return -EINVAL;
5182
5183 /* Get our SGE Page Size parameters.
5184 */
5185 page_shift = adapter->params.sge.hps + 10;
5186 page_size = 1 << page_shift;
5187
5188 /* Get the right Queues per Page parameters for our Queue.
5189 */
5190 qpp_shift = (qtype == T4_BAR2_QTYPE_EGRESS
5191 ? adapter->params.sge.eq_qpp
5192 : adapter->params.sge.iq_qpp);
5193 qpp_mask = (1 << qpp_shift) - 1;
5194
5195 /* Calculate the basics of the BAR2 SGE Queue register area:
5196 * o The BAR2 page the Queue registers will be in.
5197 * o The BAR2 Queue ID.
5198 * o The BAR2 Queue ID Offset into the BAR2 page.
5199 */
5200 bar2_page_offset = ((qid >> qpp_shift) << page_shift);
5201 bar2_qid = qid & qpp_mask;
5202 bar2_qid_offset = bar2_qid * SGE_UDB_SIZE;
5203
5204 /* If the BAR2 Queue ID Offset is less than the Page Size, then the
5205 * hardware will infer the Absolute Queue ID simply from the writes to
5206 * the BAR2 Queue ID Offset within the BAR2 Page (and we need to use a
5207 * BAR2 Queue ID of 0 for those writes). Otherwise, we'll simply
5208 * write to the first BAR2 SGE Queue Area within the BAR2 Page with
5209 * the BAR2 Queue ID and the hardware will infer the Absolute Queue ID
5210 * from the BAR2 Page and BAR2 Queue ID.
5211 *
5212 * One important censequence of this is that some BAR2 SGE registers
5213 * have a "Queue ID" field and we can write the BAR2 SGE Queue ID
5214 * there. But other registers synthesize the SGE Queue ID purely
5215 * from the writes to the registers -- the Write Combined Doorbell
5216 * Buffer is a good example. These BAR2 SGE Registers are only
5217 * available for those BAR2 SGE Register areas where the SGE Absolute
5218 * Queue ID can be inferred from simple writes.
5219 */
5220 bar2_qoffset = bar2_page_offset;
5221 bar2_qinferred = (bar2_qid_offset < page_size);
5222 if (bar2_qinferred) {
5223 bar2_qoffset += bar2_qid_offset;
5224 bar2_qid = 0;
5225 }
5226
5227 *pbar2_qoffset = bar2_qoffset;
5228 *pbar2_qid = bar2_qid;
5229 return 0;
5230}
5231
5232/**
Hariprasad Shenaiae469b62015-04-01 21:41:16 +05305233 * t4_init_devlog_params - initialize adapter->params.devlog
5234 * @adap: the adapter
5235 *
5236 * Initialize various fields of the adapter's Firmware Device Log
5237 * Parameters structure.
5238 */
5239int t4_init_devlog_params(struct adapter *adap)
5240{
5241 struct devlog_params *dparams = &adap->params.devlog;
5242 u32 pf_dparams;
5243 unsigned int devlog_meminfo;
5244 struct fw_devlog_cmd devlog_cmd;
5245 int ret;
5246
5247 /* If we're dealing with newer firmware, the Device Log Paramerters
5248 * are stored in a designated register which allows us to access the
5249 * Device Log even if we can't talk to the firmware.
5250 */
5251 pf_dparams =
5252 t4_read_reg(adap, PCIE_FW_REG(PCIE_FW_PF_A, PCIE_FW_PF_DEVLOG));
5253 if (pf_dparams) {
5254 unsigned int nentries, nentries128;
5255
5256 dparams->memtype = PCIE_FW_PF_DEVLOG_MEMTYPE_G(pf_dparams);
5257 dparams->start = PCIE_FW_PF_DEVLOG_ADDR16_G(pf_dparams) << 4;
5258
5259 nentries128 = PCIE_FW_PF_DEVLOG_NENTRIES128_G(pf_dparams);
5260 nentries = (nentries128 + 1) * 128;
5261 dparams->size = nentries * sizeof(struct fw_devlog_e);
5262
5263 return 0;
5264 }
5265
5266 /* Otherwise, ask the firmware for it's Device Log Parameters.
5267 */
5268 memset(&devlog_cmd, 0, sizeof(devlog_cmd));
Hariprasad Shenaif404f802015-05-19 18:20:44 +05305269 devlog_cmd.op_to_write = cpu_to_be32(FW_CMD_OP_V(FW_DEVLOG_CMD) |
5270 FW_CMD_REQUEST_F | FW_CMD_READ_F);
5271 devlog_cmd.retval_len16 = cpu_to_be32(FW_LEN16(devlog_cmd));
Hariprasad Shenaiae469b62015-04-01 21:41:16 +05305272 ret = t4_wr_mbox(adap, adap->mbox, &devlog_cmd, sizeof(devlog_cmd),
5273 &devlog_cmd);
5274 if (ret)
5275 return ret;
5276
Hariprasad Shenaif404f802015-05-19 18:20:44 +05305277 devlog_meminfo =
5278 be32_to_cpu(devlog_cmd.memtype_devlog_memaddr16_devlog);
Hariprasad Shenaiae469b62015-04-01 21:41:16 +05305279 dparams->memtype = FW_DEVLOG_CMD_MEMTYPE_DEVLOG_G(devlog_meminfo);
5280 dparams->start = FW_DEVLOG_CMD_MEMADDR16_DEVLOG_G(devlog_meminfo) << 4;
Hariprasad Shenaif404f802015-05-19 18:20:44 +05305281 dparams->size = be32_to_cpu(devlog_cmd.memsize_devlog);
Hariprasad Shenaiae469b62015-04-01 21:41:16 +05305282
5283 return 0;
5284}
5285
5286/**
Hariprasad Shenaie85c9a72014-12-03 19:32:52 +05305287 * t4_init_sge_params - initialize adap->params.sge
5288 * @adapter: the adapter
5289 *
5290 * Initialize various fields of the adapter's SGE Parameters structure.
5291 */
5292int t4_init_sge_params(struct adapter *adapter)
5293{
5294 struct sge_params *sge_params = &adapter->params.sge;
5295 u32 hps, qpp;
5296 unsigned int s_hps, s_qpp;
5297
5298 /* Extract the SGE Page Size for our PF.
5299 */
Hariprasad Shenaif612b812015-01-05 16:30:43 +05305300 hps = t4_read_reg(adapter, SGE_HOST_PAGE_SIZE_A);
Hariprasad Shenaie85c9a72014-12-03 19:32:52 +05305301 s_hps = (HOSTPAGESIZEPF0_S +
5302 (HOSTPAGESIZEPF1_S - HOSTPAGESIZEPF0_S) * adapter->fn);
5303 sge_params->hps = ((hps >> s_hps) & HOSTPAGESIZEPF0_M);
5304
5305 /* Extract the SGE Egress and Ingess Queues Per Page for our PF.
5306 */
5307 s_qpp = (QUEUESPERPAGEPF0_S +
5308 (QUEUESPERPAGEPF1_S - QUEUESPERPAGEPF0_S) * adapter->fn);
Hariprasad Shenaif612b812015-01-05 16:30:43 +05305309 qpp = t4_read_reg(adapter, SGE_EGRESS_QUEUES_PER_PAGE_PF_A);
5310 sge_params->eq_qpp = ((qpp >> s_qpp) & QUEUESPERPAGEPF0_M);
Hariprasad Shenaif061de422015-01-05 16:30:44 +05305311 qpp = t4_read_reg(adapter, SGE_INGRESS_QUEUES_PER_PAGE_PF_A);
Hariprasad Shenaif612b812015-01-05 16:30:43 +05305312 sge_params->iq_qpp = ((qpp >> s_qpp) & QUEUESPERPAGEPF0_M);
Hariprasad Shenaie85c9a72014-12-03 19:32:52 +05305313
5314 return 0;
5315}
5316
5317/**
Kumar Sanghvidcf7b6f2013-12-18 16:38:23 +05305318 * t4_init_tp_params - initialize adap->params.tp
5319 * @adap: the adapter
5320 *
5321 * Initialize various fields of the adapter's TP Parameters structure.
5322 */
5323int t4_init_tp_params(struct adapter *adap)
5324{
5325 int chan;
5326 u32 v;
5327
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05305328 v = t4_read_reg(adap, TP_TIMER_RESOLUTION_A);
5329 adap->params.tp.tre = TIMERRESOLUTION_G(v);
5330 adap->params.tp.dack_re = DELAYEDACKRESOLUTION_G(v);
Kumar Sanghvidcf7b6f2013-12-18 16:38:23 +05305331
5332 /* MODQ_REQ_MAP defaults to setting queues 0-3 to chan 0-3 */
5333 for (chan = 0; chan < NCHAN; chan++)
5334 adap->params.tp.tx_modq[chan] = chan;
5335
5336 /* Cache the adapter's Compressed Filter Mode and global Incress
5337 * Configuration.
5338 */
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05305339 t4_read_indirect(adap, TP_PIO_ADDR_A, TP_PIO_DATA_A,
Kumar Sanghvidcf7b6f2013-12-18 16:38:23 +05305340 &adap->params.tp.vlan_pri_map, 1,
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05305341 TP_VLAN_PRI_MAP_A);
5342 t4_read_indirect(adap, TP_PIO_ADDR_A, TP_PIO_DATA_A,
Kumar Sanghvidcf7b6f2013-12-18 16:38:23 +05305343 &adap->params.tp.ingress_config, 1,
Hariprasad Shenai837e4a42015-01-05 16:30:46 +05305344 TP_INGRESS_CONFIG_A);
Kumar Sanghvidcf7b6f2013-12-18 16:38:23 +05305345
5346 /* Now that we have TP_VLAN_PRI_MAP cached, we can calculate the field
5347 * shift positions of several elements of the Compressed Filter Tuple
5348 * for this adapter which we need frequently ...
5349 */
Hariprasad Shenai0d804332015-01-05 16:30:47 +05305350 adap->params.tp.vlan_shift = t4_filter_field_shift(adap, VLAN_F);
5351 adap->params.tp.vnic_shift = t4_filter_field_shift(adap, VNIC_ID_F);
5352 adap->params.tp.port_shift = t4_filter_field_shift(adap, PORT_F);
Kumar Sanghvidcf7b6f2013-12-18 16:38:23 +05305353 adap->params.tp.protocol_shift = t4_filter_field_shift(adap,
Hariprasad Shenai0d804332015-01-05 16:30:47 +05305354 PROTOCOL_F);
Kumar Sanghvidcf7b6f2013-12-18 16:38:23 +05305355
5356 /* If TP_INGRESS_CONFIG.VNID == 0, then TP_VLAN_PRI_MAP.VNIC_ID
Joe Perchesdbedd442015-03-06 20:49:12 -08005357 * represents the presence of an Outer VLAN instead of a VNIC ID.
Kumar Sanghvidcf7b6f2013-12-18 16:38:23 +05305358 */
Hariprasad Shenai0d804332015-01-05 16:30:47 +05305359 if ((adap->params.tp.ingress_config & VNIC_F) == 0)
Kumar Sanghvidcf7b6f2013-12-18 16:38:23 +05305360 adap->params.tp.vnic_shift = -1;
5361
5362 return 0;
5363}
5364
5365/**
5366 * t4_filter_field_shift - calculate filter field shift
5367 * @adap: the adapter
5368 * @filter_sel: the desired field (from TP_VLAN_PRI_MAP bits)
5369 *
5370 * Return the shift position of a filter field within the Compressed
5371 * Filter Tuple. The filter field is specified via its selection bit
5372 * within TP_VLAN_PRI_MAL (filter mode). E.g. F_VLAN.
5373 */
5374int t4_filter_field_shift(const struct adapter *adap, int filter_sel)
5375{
5376 unsigned int filter_mode = adap->params.tp.vlan_pri_map;
5377 unsigned int sel;
5378 int field_shift;
5379
5380 if ((filter_mode & filter_sel) == 0)
5381 return -1;
5382
5383 for (sel = 1, field_shift = 0; sel < filter_sel; sel <<= 1) {
5384 switch (filter_mode & sel) {
Hariprasad Shenai0d804332015-01-05 16:30:47 +05305385 case FCOE_F:
5386 field_shift += FT_FCOE_W;
Kumar Sanghvidcf7b6f2013-12-18 16:38:23 +05305387 break;
Hariprasad Shenai0d804332015-01-05 16:30:47 +05305388 case PORT_F:
5389 field_shift += FT_PORT_W;
Kumar Sanghvidcf7b6f2013-12-18 16:38:23 +05305390 break;
Hariprasad Shenai0d804332015-01-05 16:30:47 +05305391 case VNIC_ID_F:
5392 field_shift += FT_VNIC_ID_W;
Kumar Sanghvidcf7b6f2013-12-18 16:38:23 +05305393 break;
Hariprasad Shenai0d804332015-01-05 16:30:47 +05305394 case VLAN_F:
5395 field_shift += FT_VLAN_W;
Kumar Sanghvidcf7b6f2013-12-18 16:38:23 +05305396 break;
Hariprasad Shenai0d804332015-01-05 16:30:47 +05305397 case TOS_F:
5398 field_shift += FT_TOS_W;
Kumar Sanghvidcf7b6f2013-12-18 16:38:23 +05305399 break;
Hariprasad Shenai0d804332015-01-05 16:30:47 +05305400 case PROTOCOL_F:
5401 field_shift += FT_PROTOCOL_W;
Kumar Sanghvidcf7b6f2013-12-18 16:38:23 +05305402 break;
Hariprasad Shenai0d804332015-01-05 16:30:47 +05305403 case ETHERTYPE_F:
5404 field_shift += FT_ETHERTYPE_W;
Kumar Sanghvidcf7b6f2013-12-18 16:38:23 +05305405 break;
Hariprasad Shenai0d804332015-01-05 16:30:47 +05305406 case MACMATCH_F:
5407 field_shift += FT_MACMATCH_W;
Kumar Sanghvidcf7b6f2013-12-18 16:38:23 +05305408 break;
Hariprasad Shenai0d804332015-01-05 16:30:47 +05305409 case MPSHITTYPE_F:
5410 field_shift += FT_MPSHITTYPE_W;
Kumar Sanghvidcf7b6f2013-12-18 16:38:23 +05305411 break;
Hariprasad Shenai0d804332015-01-05 16:30:47 +05305412 case FRAGMENTATION_F:
5413 field_shift += FT_FRAGMENTATION_W;
Kumar Sanghvidcf7b6f2013-12-18 16:38:23 +05305414 break;
5415 }
5416 }
5417 return field_shift;
5418}
5419
Hariprasad Shenaic035e182015-05-06 19:48:37 +05305420int t4_init_rss_mode(struct adapter *adap, int mbox)
5421{
5422 int i, ret;
5423 struct fw_rss_vi_config_cmd rvc;
5424
5425 memset(&rvc, 0, sizeof(rvc));
5426
5427 for_each_port(adap, i) {
5428 struct port_info *p = adap2pinfo(adap, i);
5429
Hariprasad Shenaif404f802015-05-19 18:20:44 +05305430 rvc.op_to_viid =
5431 cpu_to_be32(FW_CMD_OP_V(FW_RSS_VI_CONFIG_CMD) |
5432 FW_CMD_REQUEST_F | FW_CMD_READ_F |
5433 FW_RSS_VI_CONFIG_CMD_VIID_V(p->viid));
5434 rvc.retval_len16 = cpu_to_be32(FW_LEN16(rvc));
Hariprasad Shenaic035e182015-05-06 19:48:37 +05305435 ret = t4_wr_mbox(adap, mbox, &rvc, sizeof(rvc), &rvc);
5436 if (ret)
5437 return ret;
Hariprasad Shenaif404f802015-05-19 18:20:44 +05305438 p->rss_mode = be32_to_cpu(rvc.u.basicvirtual.defaultq_to_udpen);
Hariprasad Shenaic035e182015-05-06 19:48:37 +05305439 }
5440 return 0;
5441}
5442
Bill Pemberton91744942012-12-03 09:23:02 -05005443int t4_port_init(struct adapter *adap, int mbox, int pf, int vf)
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00005444{
5445 u8 addr[6];
5446 int ret, i, j = 0;
5447 struct fw_port_cmd c;
Dimitris Michailidisf7965642010-07-11 12:01:18 +00005448 struct fw_rss_vi_config_cmd rvc;
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00005449
5450 memset(&c, 0, sizeof(c));
Dimitris Michailidisf7965642010-07-11 12:01:18 +00005451 memset(&rvc, 0, sizeof(rvc));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00005452
5453 for_each_port(adap, i) {
5454 unsigned int rss_size;
5455 struct port_info *p = adap2pinfo(adap, i);
5456
5457 while ((adap->params.portvec & (1 << j)) == 0)
5458 j++;
5459
Hariprasad Shenaif404f802015-05-19 18:20:44 +05305460 c.op_to_portid = cpu_to_be32(FW_CMD_OP_V(FW_PORT_CMD) |
5461 FW_CMD_REQUEST_F | FW_CMD_READ_F |
5462 FW_PORT_CMD_PORTID_V(j));
5463 c.action_to_len16 = cpu_to_be32(
Hariprasad Shenai2b5fb1f2014-11-21 12:52:04 +05305464 FW_PORT_CMD_ACTION_V(FW_PORT_ACTION_GET_PORT_INFO) |
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00005465 FW_LEN16(c));
5466 ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
5467 if (ret)
5468 return ret;
5469
5470 ret = t4_alloc_vi(adap, mbox, j, pf, vf, 1, addr, &rss_size);
5471 if (ret < 0)
5472 return ret;
5473
5474 p->viid = ret;
5475 p->tx_chan = j;
5476 p->lport = j;
5477 p->rss_size = rss_size;
5478 memcpy(adap->port[i]->dev_addr, addr, ETH_ALEN);
Thadeu Lima de Souza Cascardo40c9f8a2014-06-21 09:48:08 -03005479 adap->port[i]->dev_port = j;
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00005480
Hariprasad Shenaif404f802015-05-19 18:20:44 +05305481 ret = be32_to_cpu(c.u.info.lstatus_to_modtype);
Hariprasad Shenai2b5fb1f2014-11-21 12:52:04 +05305482 p->mdio_addr = (ret & FW_PORT_CMD_MDIOCAP_F) ?
5483 FW_PORT_CMD_MDIOADDR_G(ret) : -1;
5484 p->port_type = FW_PORT_CMD_PTYPE_G(ret);
Dimitris Michailidisa0881ca2010-06-18 10:05:34 +00005485 p->mod_type = FW_PORT_MOD_TYPE_NA;
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00005486
Hariprasad Shenaif404f802015-05-19 18:20:44 +05305487 rvc.op_to_viid =
5488 cpu_to_be32(FW_CMD_OP_V(FW_RSS_VI_CONFIG_CMD) |
5489 FW_CMD_REQUEST_F | FW_CMD_READ_F |
5490 FW_RSS_VI_CONFIG_CMD_VIID(p->viid));
5491 rvc.retval_len16 = cpu_to_be32(FW_LEN16(rvc));
Dimitris Michailidisf7965642010-07-11 12:01:18 +00005492 ret = t4_wr_mbox(adap, mbox, &rvc, sizeof(rvc), &rvc);
5493 if (ret)
5494 return ret;
Hariprasad Shenaif404f802015-05-19 18:20:44 +05305495 p->rss_mode = be32_to_cpu(rvc.u.basicvirtual.defaultq_to_udpen);
Dimitris Michailidisf7965642010-07-11 12:01:18 +00005496
Hariprasad Shenaif404f802015-05-19 18:20:44 +05305497 init_link_config(&p->link_cfg, be16_to_cpu(c.u.info.pcap));
Dimitris Michailidis56d36be2010-04-01 15:28:23 +00005498 j++;
5499 }
5500 return 0;
5501}
Hariprasad Shenaif1ff24a2015-01-07 08:48:01 +05305502
5503/**
Hariprasad Shenai74b30922015-01-07 08:48:02 +05305504 * t4_read_cimq_cfg - read CIM queue configuration
5505 * @adap: the adapter
5506 * @base: holds the queue base addresses in bytes
5507 * @size: holds the queue sizes in bytes
5508 * @thres: holds the queue full thresholds in bytes
5509 *
5510 * Returns the current configuration of the CIM queues, starting with
5511 * the IBQs, then the OBQs.
5512 */
5513void t4_read_cimq_cfg(struct adapter *adap, u16 *base, u16 *size, u16 *thres)
5514{
5515 unsigned int i, v;
5516 int cim_num_obq = is_t4(adap->params.chip) ?
5517 CIM_NUM_OBQ : CIM_NUM_OBQ_T5;
5518
5519 for (i = 0; i < CIM_NUM_IBQ; i++) {
5520 t4_write_reg(adap, CIM_QUEUE_CONFIG_REF_A, IBQSELECT_F |
5521 QUENUMSELECT_V(i));
5522 v = t4_read_reg(adap, CIM_QUEUE_CONFIG_CTRL_A);
5523 /* value is in 256-byte units */
5524 *base++ = CIMQBASE_G(v) * 256;
5525 *size++ = CIMQSIZE_G(v) * 256;
5526 *thres++ = QUEFULLTHRSH_G(v) * 8; /* 8-byte unit */
5527 }
5528 for (i = 0; i < cim_num_obq; i++) {
5529 t4_write_reg(adap, CIM_QUEUE_CONFIG_REF_A, OBQSELECT_F |
5530 QUENUMSELECT_V(i));
5531 v = t4_read_reg(adap, CIM_QUEUE_CONFIG_CTRL_A);
5532 /* value is in 256-byte units */
5533 *base++ = CIMQBASE_G(v) * 256;
5534 *size++ = CIMQSIZE_G(v) * 256;
5535 }
5536}
5537
5538/**
Hariprasad Shenaie5f0e432015-01-27 13:47:46 +05305539 * t4_read_cim_ibq - read the contents of a CIM inbound queue
5540 * @adap: the adapter
5541 * @qid: the queue index
5542 * @data: where to store the queue contents
5543 * @n: capacity of @data in 32-bit words
5544 *
5545 * Reads the contents of the selected CIM queue starting at address 0 up
5546 * to the capacity of @data. @n must be a multiple of 4. Returns < 0 on
5547 * error and the number of 32-bit words actually read on success.
5548 */
5549int t4_read_cim_ibq(struct adapter *adap, unsigned int qid, u32 *data, size_t n)
5550{
5551 int i, err, attempts;
5552 unsigned int addr;
5553 const unsigned int nwords = CIM_IBQ_SIZE * 4;
5554
5555 if (qid > 5 || (n & 3))
5556 return -EINVAL;
5557
5558 addr = qid * nwords;
5559 if (n > nwords)
5560 n = nwords;
5561
5562 /* It might take 3-10ms before the IBQ debug read access is allowed.
5563 * Wait for 1 Sec with a delay of 1 usec.
5564 */
5565 attempts = 1000000;
5566
5567 for (i = 0; i < n; i++, addr++) {
5568 t4_write_reg(adap, CIM_IBQ_DBG_CFG_A, IBQDBGADDR_V(addr) |
5569 IBQDBGEN_F);
5570 err = t4_wait_op_done(adap, CIM_IBQ_DBG_CFG_A, IBQDBGBUSY_F, 0,
5571 attempts, 1);
5572 if (err)
5573 return err;
5574 *data++ = t4_read_reg(adap, CIM_IBQ_DBG_DATA_A);
5575 }
5576 t4_write_reg(adap, CIM_IBQ_DBG_CFG_A, 0);
5577 return i;
5578}
5579
5580/**
Hariprasad Shenaic778af72015-01-27 13:47:47 +05305581 * t4_read_cim_obq - read the contents of a CIM outbound queue
5582 * @adap: the adapter
5583 * @qid: the queue index
5584 * @data: where to store the queue contents
5585 * @n: capacity of @data in 32-bit words
5586 *
5587 * Reads the contents of the selected CIM queue starting at address 0 up
5588 * to the capacity of @data. @n must be a multiple of 4. Returns < 0 on
5589 * error and the number of 32-bit words actually read on success.
5590 */
5591int t4_read_cim_obq(struct adapter *adap, unsigned int qid, u32 *data, size_t n)
5592{
5593 int i, err;
5594 unsigned int addr, v, nwords;
5595 int cim_num_obq = is_t4(adap->params.chip) ?
5596 CIM_NUM_OBQ : CIM_NUM_OBQ_T5;
5597
5598 if ((qid > (cim_num_obq - 1)) || (n & 3))
5599 return -EINVAL;
5600
5601 t4_write_reg(adap, CIM_QUEUE_CONFIG_REF_A, OBQSELECT_F |
5602 QUENUMSELECT_V(qid));
5603 v = t4_read_reg(adap, CIM_QUEUE_CONFIG_CTRL_A);
5604
5605 addr = CIMQBASE_G(v) * 64; /* muliple of 256 -> muliple of 4 */
5606 nwords = CIMQSIZE_G(v) * 64; /* same */
5607 if (n > nwords)
5608 n = nwords;
5609
5610 for (i = 0; i < n; i++, addr++) {
5611 t4_write_reg(adap, CIM_OBQ_DBG_CFG_A, OBQDBGADDR_V(addr) |
5612 OBQDBGEN_F);
5613 err = t4_wait_op_done(adap, CIM_OBQ_DBG_CFG_A, OBQDBGBUSY_F, 0,
5614 2, 1);
5615 if (err)
5616 return err;
5617 *data++ = t4_read_reg(adap, CIM_OBQ_DBG_DATA_A);
5618 }
5619 t4_write_reg(adap, CIM_OBQ_DBG_CFG_A, 0);
5620 return i;
5621}
5622
5623/**
Hariprasad Shenaif1ff24a2015-01-07 08:48:01 +05305624 * t4_cim_read - read a block from CIM internal address space
5625 * @adap: the adapter
5626 * @addr: the start address within the CIM address space
5627 * @n: number of words to read
5628 * @valp: where to store the result
5629 *
5630 * Reads a block of 4-byte words from the CIM intenal address space.
5631 */
5632int t4_cim_read(struct adapter *adap, unsigned int addr, unsigned int n,
5633 unsigned int *valp)
5634{
5635 int ret = 0;
5636
5637 if (t4_read_reg(adap, CIM_HOST_ACC_CTRL_A) & HOSTBUSY_F)
5638 return -EBUSY;
5639
5640 for ( ; !ret && n--; addr += 4) {
5641 t4_write_reg(adap, CIM_HOST_ACC_CTRL_A, addr);
5642 ret = t4_wait_op_done(adap, CIM_HOST_ACC_CTRL_A, HOSTBUSY_F,
5643 0, 5, 2);
5644 if (!ret)
5645 *valp++ = t4_read_reg(adap, CIM_HOST_ACC_DATA_A);
5646 }
5647 return ret;
5648}
5649
5650/**
5651 * t4_cim_write - write a block into CIM internal address space
5652 * @adap: the adapter
5653 * @addr: the start address within the CIM address space
5654 * @n: number of words to write
5655 * @valp: set of values to write
5656 *
5657 * Writes a block of 4-byte words into the CIM intenal address space.
5658 */
5659int t4_cim_write(struct adapter *adap, unsigned int addr, unsigned int n,
5660 const unsigned int *valp)
5661{
5662 int ret = 0;
5663
5664 if (t4_read_reg(adap, CIM_HOST_ACC_CTRL_A) & HOSTBUSY_F)
5665 return -EBUSY;
5666
5667 for ( ; !ret && n--; addr += 4) {
5668 t4_write_reg(adap, CIM_HOST_ACC_DATA_A, *valp++);
5669 t4_write_reg(adap, CIM_HOST_ACC_CTRL_A, addr | HOSTWRITE_F);
5670 ret = t4_wait_op_done(adap, CIM_HOST_ACC_CTRL_A, HOSTBUSY_F,
5671 0, 5, 2);
5672 }
5673 return ret;
5674}
5675
5676static int t4_cim_write1(struct adapter *adap, unsigned int addr,
5677 unsigned int val)
5678{
5679 return t4_cim_write(adap, addr, 1, &val);
5680}
5681
5682/**
5683 * t4_cim_read_la - read CIM LA capture buffer
5684 * @adap: the adapter
5685 * @la_buf: where to store the LA data
5686 * @wrptr: the HW write pointer within the capture buffer
5687 *
5688 * Reads the contents of the CIM LA buffer with the most recent entry at
5689 * the end of the returned data and with the entry at @wrptr first.
5690 * We try to leave the LA in the running state we find it in.
5691 */
5692int t4_cim_read_la(struct adapter *adap, u32 *la_buf, unsigned int *wrptr)
5693{
5694 int i, ret;
5695 unsigned int cfg, val, idx;
5696
5697 ret = t4_cim_read(adap, UP_UP_DBG_LA_CFG_A, 1, &cfg);
5698 if (ret)
5699 return ret;
5700
5701 if (cfg & UPDBGLAEN_F) { /* LA is running, freeze it */
5702 ret = t4_cim_write1(adap, UP_UP_DBG_LA_CFG_A, 0);
5703 if (ret)
5704 return ret;
5705 }
5706
5707 ret = t4_cim_read(adap, UP_UP_DBG_LA_CFG_A, 1, &val);
5708 if (ret)
5709 goto restart;
5710
5711 idx = UPDBGLAWRPTR_G(val);
5712 if (wrptr)
5713 *wrptr = idx;
5714
5715 for (i = 0; i < adap->params.cim_la_size; i++) {
5716 ret = t4_cim_write1(adap, UP_UP_DBG_LA_CFG_A,
5717 UPDBGLARDPTR_V(idx) | UPDBGLARDEN_F);
5718 if (ret)
5719 break;
5720 ret = t4_cim_read(adap, UP_UP_DBG_LA_CFG_A, 1, &val);
5721 if (ret)
5722 break;
5723 if (val & UPDBGLARDEN_F) {
5724 ret = -ETIMEDOUT;
5725 break;
5726 }
5727 ret = t4_cim_read(adap, UP_UP_DBG_LA_DATA_A, 1, &la_buf[i]);
5728 if (ret)
5729 break;
5730 idx = (idx + 1) & UPDBGLARDPTR_M;
5731 }
5732restart:
5733 if (cfg & UPDBGLAEN_F) {
5734 int r = t4_cim_write1(adap, UP_UP_DBG_LA_CFG_A,
5735 cfg & ~UPDBGLARDEN_F);
5736 if (!ret)
5737 ret = r;
5738 }
5739 return ret;
5740}
Hariprasad Shenai2d277b32015-02-06 19:32:52 +05305741
5742/**
5743 * t4_tp_read_la - read TP LA capture buffer
5744 * @adap: the adapter
5745 * @la_buf: where to store the LA data
5746 * @wrptr: the HW write pointer within the capture buffer
5747 *
5748 * Reads the contents of the TP LA buffer with the most recent entry at
5749 * the end of the returned data and with the entry at @wrptr first.
5750 * We leave the LA in the running state we find it in.
5751 */
5752void t4_tp_read_la(struct adapter *adap, u64 *la_buf, unsigned int *wrptr)
5753{
5754 bool last_incomplete;
5755 unsigned int i, cfg, val, idx;
5756
5757 cfg = t4_read_reg(adap, TP_DBG_LA_CONFIG_A) & 0xffff;
5758 if (cfg & DBGLAENABLE_F) /* freeze LA */
5759 t4_write_reg(adap, TP_DBG_LA_CONFIG_A,
5760 adap->params.tp.la_mask | (cfg ^ DBGLAENABLE_F));
5761
5762 val = t4_read_reg(adap, TP_DBG_LA_CONFIG_A);
5763 idx = DBGLAWPTR_G(val);
5764 last_incomplete = DBGLAMODE_G(val) >= 2 && (val & DBGLAWHLF_F) == 0;
5765 if (last_incomplete)
5766 idx = (idx + 1) & DBGLARPTR_M;
5767 if (wrptr)
5768 *wrptr = idx;
5769
5770 val &= 0xffff;
5771 val &= ~DBGLARPTR_V(DBGLARPTR_M);
5772 val |= adap->params.tp.la_mask;
5773
5774 for (i = 0; i < TPLA_SIZE; i++) {
5775 t4_write_reg(adap, TP_DBG_LA_CONFIG_A, DBGLARPTR_V(idx) | val);
5776 la_buf[i] = t4_read_reg64(adap, TP_DBG_LA_DATAL_A);
5777 idx = (idx + 1) & DBGLARPTR_M;
5778 }
5779
5780 /* Wipe out last entry if it isn't valid */
5781 if (last_incomplete)
5782 la_buf[TPLA_SIZE - 1] = ~0ULL;
5783
5784 if (cfg & DBGLAENABLE_F) /* restore running state */
5785 t4_write_reg(adap, TP_DBG_LA_CONFIG_A,
5786 cfg | adap->params.tp.la_mask);
5787}
Hariprasad Shenaia3bfb612015-05-05 14:59:55 +05305788
5789/* SGE Hung Ingress DMA Warning Threshold time and Warning Repeat Rate (in
5790 * seconds). If we find one of the SGE Ingress DMA State Machines in the same
5791 * state for more than the Warning Threshold then we'll issue a warning about
5792 * a potential hang. We'll repeat the warning as the SGE Ingress DMA Channel
5793 * appears to be hung every Warning Repeat second till the situation clears.
5794 * If the situation clears, we'll note that as well.
5795 */
5796#define SGE_IDMA_WARN_THRESH 1
5797#define SGE_IDMA_WARN_REPEAT 300
5798
5799/**
5800 * t4_idma_monitor_init - initialize SGE Ingress DMA Monitor
5801 * @adapter: the adapter
5802 * @idma: the adapter IDMA Monitor state
5803 *
5804 * Initialize the state of an SGE Ingress DMA Monitor.
5805 */
5806void t4_idma_monitor_init(struct adapter *adapter,
5807 struct sge_idma_monitor_state *idma)
5808{
5809 /* Initialize the state variables for detecting an SGE Ingress DMA
5810 * hang. The SGE has internal counters which count up on each clock
5811 * tick whenever the SGE finds its Ingress DMA State Engines in the
5812 * same state they were on the previous clock tick. The clock used is
5813 * the Core Clock so we have a limit on the maximum "time" they can
5814 * record; typically a very small number of seconds. For instance,
5815 * with a 600MHz Core Clock, we can only count up to a bit more than
5816 * 7s. So we'll synthesize a larger counter in order to not run the
5817 * risk of having the "timers" overflow and give us the flexibility to
5818 * maintain a Hung SGE State Machine of our own which operates across
5819 * a longer time frame.
5820 */
5821 idma->idma_1s_thresh = core_ticks_per_usec(adapter) * 1000000; /* 1s */
5822 idma->idma_stalled[0] = 0;
5823 idma->idma_stalled[1] = 0;
5824}
5825
5826/**
5827 * t4_idma_monitor - monitor SGE Ingress DMA state
5828 * @adapter: the adapter
5829 * @idma: the adapter IDMA Monitor state
5830 * @hz: number of ticks/second
5831 * @ticks: number of ticks since the last IDMA Monitor call
5832 */
5833void t4_idma_monitor(struct adapter *adapter,
5834 struct sge_idma_monitor_state *idma,
5835 int hz, int ticks)
5836{
5837 int i, idma_same_state_cnt[2];
5838
5839 /* Read the SGE Debug Ingress DMA Same State Count registers. These
5840 * are counters inside the SGE which count up on each clock when the
5841 * SGE finds its Ingress DMA State Engines in the same states they
5842 * were in the previous clock. The counters will peg out at
5843 * 0xffffffff without wrapping around so once they pass the 1s
5844 * threshold they'll stay above that till the IDMA state changes.
5845 */
5846 t4_write_reg(adapter, SGE_DEBUG_INDEX_A, 13);
5847 idma_same_state_cnt[0] = t4_read_reg(adapter, SGE_DEBUG_DATA_HIGH_A);
5848 idma_same_state_cnt[1] = t4_read_reg(adapter, SGE_DEBUG_DATA_LOW_A);
5849
5850 for (i = 0; i < 2; i++) {
5851 u32 debug0, debug11;
5852
5853 /* If the Ingress DMA Same State Counter ("timer") is less
5854 * than 1s, then we can reset our synthesized Stall Timer and
5855 * continue. If we have previously emitted warnings about a
5856 * potential stalled Ingress Queue, issue a note indicating
5857 * that the Ingress Queue has resumed forward progress.
5858 */
5859 if (idma_same_state_cnt[i] < idma->idma_1s_thresh) {
5860 if (idma->idma_stalled[i] >= SGE_IDMA_WARN_THRESH * hz)
5861 dev_warn(adapter->pdev_dev, "SGE idma%d, queue %u, "
5862 "resumed after %d seconds\n",
5863 i, idma->idma_qid[i],
5864 idma->idma_stalled[i] / hz);
5865 idma->idma_stalled[i] = 0;
5866 continue;
5867 }
5868
5869 /* Synthesize an SGE Ingress DMA Same State Timer in the Hz
5870 * domain. The first time we get here it'll be because we
5871 * passed the 1s Threshold; each additional time it'll be
5872 * because the RX Timer Callback is being fired on its regular
5873 * schedule.
5874 *
5875 * If the stall is below our Potential Hung Ingress Queue
5876 * Warning Threshold, continue.
5877 */
5878 if (idma->idma_stalled[i] == 0) {
5879 idma->idma_stalled[i] = hz;
5880 idma->idma_warn[i] = 0;
5881 } else {
5882 idma->idma_stalled[i] += ticks;
5883 idma->idma_warn[i] -= ticks;
5884 }
5885
5886 if (idma->idma_stalled[i] < SGE_IDMA_WARN_THRESH * hz)
5887 continue;
5888
5889 /* We'll issue a warning every SGE_IDMA_WARN_REPEAT seconds.
5890 */
5891 if (idma->idma_warn[i] > 0)
5892 continue;
5893 idma->idma_warn[i] = SGE_IDMA_WARN_REPEAT * hz;
5894
5895 /* Read and save the SGE IDMA State and Queue ID information.
5896 * We do this every time in case it changes across time ...
5897 * can't be too careful ...
5898 */
5899 t4_write_reg(adapter, SGE_DEBUG_INDEX_A, 0);
5900 debug0 = t4_read_reg(adapter, SGE_DEBUG_DATA_LOW_A);
5901 idma->idma_state[i] = (debug0 >> (i * 9)) & 0x3f;
5902
5903 t4_write_reg(adapter, SGE_DEBUG_INDEX_A, 11);
5904 debug11 = t4_read_reg(adapter, SGE_DEBUG_DATA_LOW_A);
5905 idma->idma_qid[i] = (debug11 >> (i * 16)) & 0xffff;
5906
5907 dev_warn(adapter->pdev_dev, "SGE idma%u, queue %u, potentially stuck in "
5908 "state %u for %d seconds (debug0=%#x, debug11=%#x)\n",
5909 i, idma->idma_qid[i], idma->idma_state[i],
5910 idma->idma_stalled[i] / hz,
5911 debug0, debug11);
5912 t4_sge_decode_idma_state(adapter, idma->idma_state[i]);
5913 }
5914}