blob: e958bbe30623f6f86b5964a7a19e370e968475dd [file] [log] [blame]
Divy Le Ray4d22de32007-01-18 22:04:14 -05001/*
Divy Le Ray1d68e932007-01-30 19:44:35 -08002 * Copyright (c) 2003-2007 Chelsio, Inc. All rights reserved.
Divy Le Ray4d22de32007-01-18 22:04:14 -05003 *
Divy Le Ray1d68e932007-01-30 19:44:35 -08004 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
Divy Le Ray4d22de32007-01-18 22:04:14 -05009 *
Divy Le Ray1d68e932007-01-30 19:44:35 -080010 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
Divy Le Ray4d22de32007-01-18 22:04:14 -050031 */
Divy Le Ray4d22de32007-01-18 22:04:14 -050032#include "common.h"
33#include "regs.h"
34#include "sge_defs.h"
35#include "firmware_exports.h"
36
Divy Le Rayf2c68792007-01-30 19:44:13 -080037/**
38 * t3_wait_op_done_val - wait until an operation is completed
39 * @adapter: the adapter performing the operation
40 * @reg: the register to check for completion
41 * @mask: a single-bit field within @reg that indicates completion
42 * @polarity: the value of the field when the operation is completed
43 * @attempts: number of check iterations
44 * @delay: delay in usecs between iterations
45 * @valp: where to store the value of the register at completion time
46 *
47 * Wait until an operation is completed by checking a bit in a register
48 * up to @attempts times. If @valp is not NULL the value of the register
49 * at the time it indicated completion is stored there. Returns 0 if the
50 * operation completes and -EAGAIN otherwise.
51 */
Divy Le Ray4d22de32007-01-18 22:04:14 -050052
53int t3_wait_op_done_val(struct adapter *adapter, int reg, u32 mask,
54 int polarity, int attempts, int delay, u32 *valp)
55{
56 while (1) {
57 u32 val = t3_read_reg(adapter, reg);
58
59 if (!!(val & mask) == polarity) {
60 if (valp)
61 *valp = val;
62 return 0;
63 }
64 if (--attempts == 0)
65 return -EAGAIN;
66 if (delay)
67 udelay(delay);
68 }
69}
70
71/**
72 * t3_write_regs - write a bunch of registers
73 * @adapter: the adapter to program
74 * @p: an array of register address/register value pairs
75 * @n: the number of address/value pairs
76 * @offset: register address offset
77 *
78 * Takes an array of register address/register value pairs and writes each
79 * value to the corresponding register. Register addresses are adjusted
80 * by the supplied offset.
81 */
82void t3_write_regs(struct adapter *adapter, const struct addr_val_pair *p,
83 int n, unsigned int offset)
84{
85 while (n--) {
86 t3_write_reg(adapter, p->reg_addr + offset, p->val);
87 p++;
88 }
89}
90
91/**
92 * t3_set_reg_field - set a register field to a value
93 * @adapter: the adapter to program
94 * @addr: the register address
95 * @mask: specifies the portion of the register to modify
96 * @val: the new value for the register field
97 *
98 * Sets a register field specified by the supplied mask to the
99 * given value.
100 */
101void t3_set_reg_field(struct adapter *adapter, unsigned int addr, u32 mask,
102 u32 val)
103{
104 u32 v = t3_read_reg(adapter, addr) & ~mask;
105
106 t3_write_reg(adapter, addr, v | val);
107 t3_read_reg(adapter, addr); /* flush */
108}
109
110/**
111 * t3_read_indirect - read indirectly addressed registers
112 * @adap: the adapter
113 * @addr_reg: register holding the indirect address
114 * @data_reg: register holding the value of the indirect register
115 * @vals: where the read register values are stored
116 * @start_idx: index of first indirect register to read
117 * @nregs: how many indirect registers to read
118 *
119 * Reads registers that are accessed indirectly through an address/data
120 * register pair.
121 */
122void t3_read_indirect(struct adapter *adap, unsigned int addr_reg,
123 unsigned int data_reg, u32 *vals, unsigned int nregs,
124 unsigned int start_idx)
125{
126 while (nregs--) {
127 t3_write_reg(adap, addr_reg, start_idx);
128 *vals++ = t3_read_reg(adap, data_reg);
129 start_idx++;
130 }
131}
132
133/**
134 * t3_mc7_bd_read - read from MC7 through backdoor accesses
135 * @mc7: identifies MC7 to read from
136 * @start: index of first 64-bit word to read
137 * @n: number of 64-bit words to read
138 * @buf: where to store the read result
139 *
140 * Read n 64-bit words from MC7 starting at word start, using backdoor
141 * accesses.
142 */
143int t3_mc7_bd_read(struct mc7 *mc7, unsigned int start, unsigned int n,
144 u64 *buf)
145{
146 static const int shift[] = { 0, 0, 16, 24 };
147 static const int step[] = { 0, 32, 16, 8 };
148
149 unsigned int size64 = mc7->size / 8; /* # of 64-bit words */
150 struct adapter *adap = mc7->adapter;
151
152 if (start >= size64 || start + n > size64)
153 return -EINVAL;
154
155 start *= (8 << mc7->width);
156 while (n--) {
157 int i;
158 u64 val64 = 0;
159
160 for (i = (1 << mc7->width) - 1; i >= 0; --i) {
161 int attempts = 10;
162 u32 val;
163
164 t3_write_reg(adap, mc7->offset + A_MC7_BD_ADDR, start);
165 t3_write_reg(adap, mc7->offset + A_MC7_BD_OP, 0);
166 val = t3_read_reg(adap, mc7->offset + A_MC7_BD_OP);
167 while ((val & F_BUSY) && attempts--)
168 val = t3_read_reg(adap,
169 mc7->offset + A_MC7_BD_OP);
170 if (val & F_BUSY)
171 return -EIO;
172
173 val = t3_read_reg(adap, mc7->offset + A_MC7_BD_DATA1);
174 if (mc7->width == 0) {
175 val64 = t3_read_reg(adap,
176 mc7->offset +
177 A_MC7_BD_DATA0);
178 val64 |= (u64) val << 32;
179 } else {
180 if (mc7->width > 1)
181 val >>= shift[mc7->width];
182 val64 |= (u64) val << (step[mc7->width] * i);
183 }
184 start += 8;
185 }
186 *buf++ = val64;
187 }
188 return 0;
189}
190
191/*
192 * Initialize MI1.
193 */
194static void mi1_init(struct adapter *adap, const struct adapter_info *ai)
195{
196 u32 clkdiv = adap->params.vpd.cclk / (2 * adap->params.vpd.mdc) - 1;
197 u32 val = F_PREEN | V_MDIINV(ai->mdiinv) | V_MDIEN(ai->mdien) |
198 V_CLKDIV(clkdiv);
199
200 if (!(ai->caps & SUPPORTED_10000baseT_Full))
201 val |= V_ST(1);
202 t3_write_reg(adap, A_MI1_CFG, val);
203}
204
205#define MDIO_ATTEMPTS 10
206
207/*
208 * MI1 read/write operations for direct-addressed PHYs.
209 */
210static int mi1_read(struct adapter *adapter, int phy_addr, int mmd_addr,
211 int reg_addr, unsigned int *valp)
212{
213 int ret;
214 u32 addr = V_REGADDR(reg_addr) | V_PHYADDR(phy_addr);
215
216 if (mmd_addr)
217 return -EINVAL;
218
219 mutex_lock(&adapter->mdio_lock);
220 t3_write_reg(adapter, A_MI1_ADDR, addr);
221 t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(2));
222 ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 20);
223 if (!ret)
224 *valp = t3_read_reg(adapter, A_MI1_DATA);
225 mutex_unlock(&adapter->mdio_lock);
226 return ret;
227}
228
229static int mi1_write(struct adapter *adapter, int phy_addr, int mmd_addr,
230 int reg_addr, unsigned int val)
231{
232 int ret;
233 u32 addr = V_REGADDR(reg_addr) | V_PHYADDR(phy_addr);
234
235 if (mmd_addr)
236 return -EINVAL;
237
238 mutex_lock(&adapter->mdio_lock);
239 t3_write_reg(adapter, A_MI1_ADDR, addr);
240 t3_write_reg(adapter, A_MI1_DATA, val);
241 t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(1));
242 ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 20);
243 mutex_unlock(&adapter->mdio_lock);
244 return ret;
245}
246
247static const struct mdio_ops mi1_mdio_ops = {
248 mi1_read,
249 mi1_write
250};
251
252/*
253 * MI1 read/write operations for indirect-addressed PHYs.
254 */
255static int mi1_ext_read(struct adapter *adapter, int phy_addr, int mmd_addr,
256 int reg_addr, unsigned int *valp)
257{
258 int ret;
259 u32 addr = V_REGADDR(mmd_addr) | V_PHYADDR(phy_addr);
260
261 mutex_lock(&adapter->mdio_lock);
262 t3_write_reg(adapter, A_MI1_ADDR, addr);
263 t3_write_reg(adapter, A_MI1_DATA, reg_addr);
264 t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(0));
265 ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 20);
266 if (!ret) {
267 t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(3));
268 ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0,
269 MDIO_ATTEMPTS, 20);
270 if (!ret)
271 *valp = t3_read_reg(adapter, A_MI1_DATA);
272 }
273 mutex_unlock(&adapter->mdio_lock);
274 return ret;
275}
276
277static int mi1_ext_write(struct adapter *adapter, int phy_addr, int mmd_addr,
278 int reg_addr, unsigned int val)
279{
280 int ret;
281 u32 addr = V_REGADDR(mmd_addr) | V_PHYADDR(phy_addr);
282
283 mutex_lock(&adapter->mdio_lock);
284 t3_write_reg(adapter, A_MI1_ADDR, addr);
285 t3_write_reg(adapter, A_MI1_DATA, reg_addr);
286 t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(0));
287 ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 20);
288 if (!ret) {
289 t3_write_reg(adapter, A_MI1_DATA, val);
290 t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(1));
291 ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0,
292 MDIO_ATTEMPTS, 20);
293 }
294 mutex_unlock(&adapter->mdio_lock);
295 return ret;
296}
297
298static const struct mdio_ops mi1_mdio_ext_ops = {
299 mi1_ext_read,
300 mi1_ext_write
301};
302
303/**
304 * t3_mdio_change_bits - modify the value of a PHY register
305 * @phy: the PHY to operate on
306 * @mmd: the device address
307 * @reg: the register address
308 * @clear: what part of the register value to mask off
309 * @set: what part of the register value to set
310 *
311 * Changes the value of a PHY register by applying a mask to its current
312 * value and ORing the result with a new value.
313 */
314int t3_mdio_change_bits(struct cphy *phy, int mmd, int reg, unsigned int clear,
315 unsigned int set)
316{
317 int ret;
318 unsigned int val;
319
320 ret = mdio_read(phy, mmd, reg, &val);
321 if (!ret) {
322 val &= ~clear;
323 ret = mdio_write(phy, mmd, reg, val | set);
324 }
325 return ret;
326}
327
328/**
329 * t3_phy_reset - reset a PHY block
330 * @phy: the PHY to operate on
331 * @mmd: the device address of the PHY block to reset
332 * @wait: how long to wait for the reset to complete in 1ms increments
333 *
334 * Resets a PHY block and optionally waits for the reset to complete.
335 * @mmd should be 0 for 10/100/1000 PHYs and the device address to reset
336 * for 10G PHYs.
337 */
338int t3_phy_reset(struct cphy *phy, int mmd, int wait)
339{
340 int err;
341 unsigned int ctl;
342
343 err = t3_mdio_change_bits(phy, mmd, MII_BMCR, BMCR_PDOWN, BMCR_RESET);
344 if (err || !wait)
345 return err;
346
347 do {
348 err = mdio_read(phy, mmd, MII_BMCR, &ctl);
349 if (err)
350 return err;
351 ctl &= BMCR_RESET;
352 if (ctl)
353 msleep(1);
354 } while (ctl && --wait);
355
356 return ctl ? -1 : 0;
357}
358
359/**
360 * t3_phy_advertise - set the PHY advertisement registers for autoneg
361 * @phy: the PHY to operate on
362 * @advert: bitmap of capabilities the PHY should advertise
363 *
364 * Sets a 10/100/1000 PHY's advertisement registers to advertise the
365 * requested capabilities.
366 */
367int t3_phy_advertise(struct cphy *phy, unsigned int advert)
368{
369 int err;
370 unsigned int val = 0;
371
372 err = mdio_read(phy, 0, MII_CTRL1000, &val);
373 if (err)
374 return err;
375
376 val &= ~(ADVERTISE_1000HALF | ADVERTISE_1000FULL);
377 if (advert & ADVERTISED_1000baseT_Half)
378 val |= ADVERTISE_1000HALF;
379 if (advert & ADVERTISED_1000baseT_Full)
380 val |= ADVERTISE_1000FULL;
381
382 err = mdio_write(phy, 0, MII_CTRL1000, val);
383 if (err)
384 return err;
385
386 val = 1;
387 if (advert & ADVERTISED_10baseT_Half)
388 val |= ADVERTISE_10HALF;
389 if (advert & ADVERTISED_10baseT_Full)
390 val |= ADVERTISE_10FULL;
391 if (advert & ADVERTISED_100baseT_Half)
392 val |= ADVERTISE_100HALF;
393 if (advert & ADVERTISED_100baseT_Full)
394 val |= ADVERTISE_100FULL;
395 if (advert & ADVERTISED_Pause)
396 val |= ADVERTISE_PAUSE_CAP;
397 if (advert & ADVERTISED_Asym_Pause)
398 val |= ADVERTISE_PAUSE_ASYM;
399 return mdio_write(phy, 0, MII_ADVERTISE, val);
400}
401
402/**
403 * t3_set_phy_speed_duplex - force PHY speed and duplex
404 * @phy: the PHY to operate on
405 * @speed: requested PHY speed
406 * @duplex: requested PHY duplex
407 *
408 * Force a 10/100/1000 PHY's speed and duplex. This also disables
409 * auto-negotiation except for GigE, where auto-negotiation is mandatory.
410 */
411int t3_set_phy_speed_duplex(struct cphy *phy, int speed, int duplex)
412{
413 int err;
414 unsigned int ctl;
415
416 err = mdio_read(phy, 0, MII_BMCR, &ctl);
417 if (err)
418 return err;
419
420 if (speed >= 0) {
421 ctl &= ~(BMCR_SPEED100 | BMCR_SPEED1000 | BMCR_ANENABLE);
422 if (speed == SPEED_100)
423 ctl |= BMCR_SPEED100;
424 else if (speed == SPEED_1000)
425 ctl |= BMCR_SPEED1000;
426 }
427 if (duplex >= 0) {
428 ctl &= ~(BMCR_FULLDPLX | BMCR_ANENABLE);
429 if (duplex == DUPLEX_FULL)
430 ctl |= BMCR_FULLDPLX;
431 }
432 if (ctl & BMCR_SPEED1000) /* auto-negotiation required for GigE */
433 ctl |= BMCR_ANENABLE;
434 return mdio_write(phy, 0, MII_BMCR, ctl);
435}
436
437static const struct adapter_info t3_adap_info[] = {
438 {2, 0, 0, 0,
439 F_GPIO2_OEN | F_GPIO4_OEN |
440 F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, F_GPIO3 | F_GPIO5,
Divy Le Ray8ac3ba62007-03-31 00:23:19 -0700441 0,
Divy Le Ray4d22de32007-01-18 22:04:14 -0500442 &mi1_mdio_ops, "Chelsio PE9000"},
443 {2, 0, 0, 0,
444 F_GPIO2_OEN | F_GPIO4_OEN |
445 F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, F_GPIO3 | F_GPIO5,
Divy Le Ray8ac3ba62007-03-31 00:23:19 -0700446 0,
Divy Le Ray4d22de32007-01-18 22:04:14 -0500447 &mi1_mdio_ops, "Chelsio T302"},
448 {1, 0, 0, 0,
449 F_GPIO1_OEN | F_GPIO6_OEN | F_GPIO7_OEN | F_GPIO10_OEN |
450 F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL, 0,
Divy Le Ray8ac3ba62007-03-31 00:23:19 -0700451 SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
Divy Le Ray4d22de32007-01-18 22:04:14 -0500452 &mi1_mdio_ext_ops, "Chelsio T310"},
453 {2, 0, 0, 0,
454 F_GPIO1_OEN | F_GPIO2_OEN | F_GPIO4_OEN | F_GPIO5_OEN | F_GPIO6_OEN |
455 F_GPIO7_OEN | F_GPIO10_OEN | F_GPIO11_OEN | F_GPIO1_OUT_VAL |
456 F_GPIO5_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL, 0,
Divy Le Ray8ac3ba62007-03-31 00:23:19 -0700457 SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
Divy Le Ray4d22de32007-01-18 22:04:14 -0500458 &mi1_mdio_ext_ops, "Chelsio T320"},
459};
460
461/*
462 * Return the adapter_info structure with a given index. Out-of-range indices
463 * return NULL.
464 */
465const struct adapter_info *t3_get_adapter_info(unsigned int id)
466{
467 return id < ARRAY_SIZE(t3_adap_info) ? &t3_adap_info[id] : NULL;
468}
469
470#define CAPS_1G (SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Full | \
471 SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_MII)
472#define CAPS_10G (SUPPORTED_10000baseT_Full | SUPPORTED_AUI)
473
474static const struct port_type_info port_types[] = {
475 {NULL},
476 {t3_ael1002_phy_prep, CAPS_10G | SUPPORTED_FIBRE,
477 "10GBASE-XR"},
478 {t3_vsc8211_phy_prep, CAPS_1G | SUPPORTED_TP | SUPPORTED_IRQ,
479 "10/100/1000BASE-T"},
480 {NULL, CAPS_1G | SUPPORTED_TP | SUPPORTED_IRQ,
481 "10/100/1000BASE-T"},
482 {t3_xaui_direct_phy_prep, CAPS_10G | SUPPORTED_TP, "10GBASE-CX4"},
483 {NULL, CAPS_10G, "10GBASE-KX4"},
484 {t3_qt2045_phy_prep, CAPS_10G | SUPPORTED_TP, "10GBASE-CX4"},
485 {t3_ael1006_phy_prep, CAPS_10G | SUPPORTED_FIBRE,
486 "10GBASE-SR"},
487 {NULL, CAPS_10G | SUPPORTED_TP, "10GBASE-CX4"},
488};
489
490#undef CAPS_1G
491#undef CAPS_10G
492
493#define VPD_ENTRY(name, len) \
494 u8 name##_kword[2]; u8 name##_len; u8 name##_data[len]
495
496/*
497 * Partial EEPROM Vital Product Data structure. Includes only the ID and
498 * VPD-R sections.
499 */
500struct t3_vpd {
501 u8 id_tag;
502 u8 id_len[2];
503 u8 id_data[16];
504 u8 vpdr_tag;
505 u8 vpdr_len[2];
506 VPD_ENTRY(pn, 16); /* part number */
507 VPD_ENTRY(ec, 16); /* EC level */
Divy Le Ray167cdf52007-08-21 20:49:36 -0700508 VPD_ENTRY(sn, SERNUM_LEN); /* serial number */
Divy Le Ray4d22de32007-01-18 22:04:14 -0500509 VPD_ENTRY(na, 12); /* MAC address base */
510 VPD_ENTRY(cclk, 6); /* core clock */
511 VPD_ENTRY(mclk, 6); /* mem clock */
512 VPD_ENTRY(uclk, 6); /* uP clk */
513 VPD_ENTRY(mdc, 6); /* MDIO clk */
514 VPD_ENTRY(mt, 2); /* mem timing */
515 VPD_ENTRY(xaui0cfg, 6); /* XAUI0 config */
516 VPD_ENTRY(xaui1cfg, 6); /* XAUI1 config */
517 VPD_ENTRY(port0, 2); /* PHY0 complex */
518 VPD_ENTRY(port1, 2); /* PHY1 complex */
519 VPD_ENTRY(port2, 2); /* PHY2 complex */
520 VPD_ENTRY(port3, 2); /* PHY3 complex */
521 VPD_ENTRY(rv, 1); /* csum */
522 u32 pad; /* for multiple-of-4 sizing and alignment */
523};
524
525#define EEPROM_MAX_POLL 4
526#define EEPROM_STAT_ADDR 0x4000
527#define VPD_BASE 0xc00
528
529/**
530 * t3_seeprom_read - read a VPD EEPROM location
531 * @adapter: adapter to read
532 * @addr: EEPROM address
533 * @data: where to store the read data
534 *
535 * Read a 32-bit word from a location in VPD EEPROM using the card's PCI
536 * VPD ROM capability. A zero is written to the flag bit when the
537 * addres is written to the control register. The hardware device will
538 * set the flag to 1 when 4 bytes have been read into the data register.
539 */
540int t3_seeprom_read(struct adapter *adapter, u32 addr, u32 *data)
541{
542 u16 val;
543 int attempts = EEPROM_MAX_POLL;
544 unsigned int base = adapter->params.pci.vpd_cap_addr;
545
546 if ((addr >= EEPROMSIZE && addr != EEPROM_STAT_ADDR) || (addr & 3))
547 return -EINVAL;
548
549 pci_write_config_word(adapter->pdev, base + PCI_VPD_ADDR, addr);
550 do {
551 udelay(10);
552 pci_read_config_word(adapter->pdev, base + PCI_VPD_ADDR, &val);
553 } while (!(val & PCI_VPD_ADDR_F) && --attempts);
554
555 if (!(val & PCI_VPD_ADDR_F)) {
556 CH_ERR(adapter, "reading EEPROM address 0x%x failed\n", addr);
557 return -EIO;
558 }
559 pci_read_config_dword(adapter->pdev, base + PCI_VPD_DATA, data);
560 *data = le32_to_cpu(*data);
561 return 0;
562}
563
564/**
565 * t3_seeprom_write - write a VPD EEPROM location
566 * @adapter: adapter to write
567 * @addr: EEPROM address
568 * @data: value to write
569 *
570 * Write a 32-bit word to a location in VPD EEPROM using the card's PCI
571 * VPD ROM capability.
572 */
573int t3_seeprom_write(struct adapter *adapter, u32 addr, u32 data)
574{
575 u16 val;
576 int attempts = EEPROM_MAX_POLL;
577 unsigned int base = adapter->params.pci.vpd_cap_addr;
578
579 if ((addr >= EEPROMSIZE && addr != EEPROM_STAT_ADDR) || (addr & 3))
580 return -EINVAL;
581
582 pci_write_config_dword(adapter->pdev, base + PCI_VPD_DATA,
583 cpu_to_le32(data));
584 pci_write_config_word(adapter->pdev,base + PCI_VPD_ADDR,
585 addr | PCI_VPD_ADDR_F);
586 do {
587 msleep(1);
588 pci_read_config_word(adapter->pdev, base + PCI_VPD_ADDR, &val);
589 } while ((val & PCI_VPD_ADDR_F) && --attempts);
590
591 if (val & PCI_VPD_ADDR_F) {
592 CH_ERR(adapter, "write to EEPROM address 0x%x failed\n", addr);
593 return -EIO;
594 }
595 return 0;
596}
597
598/**
599 * t3_seeprom_wp - enable/disable EEPROM write protection
600 * @adapter: the adapter
601 * @enable: 1 to enable write protection, 0 to disable it
602 *
603 * Enables or disables write protection on the serial EEPROM.
604 */
605int t3_seeprom_wp(struct adapter *adapter, int enable)
606{
607 return t3_seeprom_write(adapter, EEPROM_STAT_ADDR, enable ? 0xc : 0);
608}
609
610/*
611 * Convert a character holding a hex digit to a number.
612 */
613static unsigned int hex2int(unsigned char c)
614{
615 return isdigit(c) ? c - '0' : toupper(c) - 'A' + 10;
616}
617
618/**
619 * get_vpd_params - read VPD parameters from VPD EEPROM
620 * @adapter: adapter to read
621 * @p: where to store the parameters
622 *
623 * Reads card parameters stored in VPD EEPROM.
624 */
625static int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
626{
627 int i, addr, ret;
628 struct t3_vpd vpd;
629
630 /*
631 * Card information is normally at VPD_BASE but some early cards had
632 * it at 0.
633 */
634 ret = t3_seeprom_read(adapter, VPD_BASE, (u32 *)&vpd);
635 if (ret)
636 return ret;
637 addr = vpd.id_tag == 0x82 ? VPD_BASE : 0;
638
639 for (i = 0; i < sizeof(vpd); i += 4) {
640 ret = t3_seeprom_read(adapter, addr + i,
641 (u32 *)((u8 *)&vpd + i));
642 if (ret)
643 return ret;
644 }
645
646 p->cclk = simple_strtoul(vpd.cclk_data, NULL, 10);
647 p->mclk = simple_strtoul(vpd.mclk_data, NULL, 10);
648 p->uclk = simple_strtoul(vpd.uclk_data, NULL, 10);
649 p->mdc = simple_strtoul(vpd.mdc_data, NULL, 10);
650 p->mem_timing = simple_strtoul(vpd.mt_data, NULL, 10);
Divy Le Ray167cdf52007-08-21 20:49:36 -0700651 memcpy(p->sn, vpd.sn_data, SERNUM_LEN);
Divy Le Ray4d22de32007-01-18 22:04:14 -0500652
653 /* Old eeproms didn't have port information */
654 if (adapter->params.rev == 0 && !vpd.port0_data[0]) {
655 p->port_type[0] = uses_xaui(adapter) ? 1 : 2;
656 p->port_type[1] = uses_xaui(adapter) ? 6 : 2;
657 } else {
658 p->port_type[0] = hex2int(vpd.port0_data[0]);
659 p->port_type[1] = hex2int(vpd.port1_data[0]);
660 p->xauicfg[0] = simple_strtoul(vpd.xaui0cfg_data, NULL, 16);
661 p->xauicfg[1] = simple_strtoul(vpd.xaui1cfg_data, NULL, 16);
662 }
663
664 for (i = 0; i < 6; i++)
665 p->eth_base[i] = hex2int(vpd.na_data[2 * i]) * 16 +
666 hex2int(vpd.na_data[2 * i + 1]);
667 return 0;
668}
669
670/* serial flash and firmware constants */
671enum {
672 SF_ATTEMPTS = 5, /* max retries for SF1 operations */
673 SF_SEC_SIZE = 64 * 1024, /* serial flash sector size */
674 SF_SIZE = SF_SEC_SIZE * 8, /* serial flash size */
675
676 /* flash command opcodes */
677 SF_PROG_PAGE = 2, /* program page */
678 SF_WR_DISABLE = 4, /* disable writes */
679 SF_RD_STATUS = 5, /* read status register */
680 SF_WR_ENABLE = 6, /* enable writes */
681 SF_RD_DATA_FAST = 0xb, /* read flash */
682 SF_ERASE_SECTOR = 0xd8, /* erase sector */
683
684 FW_FLASH_BOOT_ADDR = 0x70000, /* start address of FW in flash */
Divy Le Ray2e283962007-03-18 13:10:06 -0700685 FW_VERS_ADDR = 0x77ffc, /* flash address holding FW version */
686 FW_MIN_SIZE = 8 /* at least version and csum */
Divy Le Ray4d22de32007-01-18 22:04:14 -0500687};
688
689/**
690 * sf1_read - read data from the serial flash
691 * @adapter: the adapter
692 * @byte_cnt: number of bytes to read
693 * @cont: whether another operation will be chained
694 * @valp: where to store the read data
695 *
696 * Reads up to 4 bytes of data from the serial flash. The location of
697 * the read needs to be specified prior to calling this by issuing the
698 * appropriate commands to the serial flash.
699 */
700static int sf1_read(struct adapter *adapter, unsigned int byte_cnt, int cont,
701 u32 *valp)
702{
703 int ret;
704
705 if (!byte_cnt || byte_cnt > 4)
706 return -EINVAL;
707 if (t3_read_reg(adapter, A_SF_OP) & F_BUSY)
708 return -EBUSY;
709 t3_write_reg(adapter, A_SF_OP, V_CONT(cont) | V_BYTECNT(byte_cnt - 1));
710 ret = t3_wait_op_done(adapter, A_SF_OP, F_BUSY, 0, SF_ATTEMPTS, 10);
711 if (!ret)
712 *valp = t3_read_reg(adapter, A_SF_DATA);
713 return ret;
714}
715
716/**
717 * sf1_write - write data to the serial flash
718 * @adapter: the adapter
719 * @byte_cnt: number of bytes to write
720 * @cont: whether another operation will be chained
721 * @val: value to write
722 *
723 * Writes up to 4 bytes of data to the serial flash. The location of
724 * the write needs to be specified prior to calling this by issuing the
725 * appropriate commands to the serial flash.
726 */
727static int sf1_write(struct adapter *adapter, unsigned int byte_cnt, int cont,
728 u32 val)
729{
730 if (!byte_cnt || byte_cnt > 4)
731 return -EINVAL;
732 if (t3_read_reg(adapter, A_SF_OP) & F_BUSY)
733 return -EBUSY;
734 t3_write_reg(adapter, A_SF_DATA, val);
735 t3_write_reg(adapter, A_SF_OP,
736 V_CONT(cont) | V_BYTECNT(byte_cnt - 1) | V_OP(1));
737 return t3_wait_op_done(adapter, A_SF_OP, F_BUSY, 0, SF_ATTEMPTS, 10);
738}
739
740/**
741 * flash_wait_op - wait for a flash operation to complete
742 * @adapter: the adapter
743 * @attempts: max number of polls of the status register
744 * @delay: delay between polls in ms
745 *
746 * Wait for a flash operation to complete by polling the status register.
747 */
748static int flash_wait_op(struct adapter *adapter, int attempts, int delay)
749{
750 int ret;
751 u32 status;
752
753 while (1) {
754 if ((ret = sf1_write(adapter, 1, 1, SF_RD_STATUS)) != 0 ||
755 (ret = sf1_read(adapter, 1, 0, &status)) != 0)
756 return ret;
757 if (!(status & 1))
758 return 0;
759 if (--attempts == 0)
760 return -EAGAIN;
761 if (delay)
762 msleep(delay);
763 }
764}
765
766/**
767 * t3_read_flash - read words from serial flash
768 * @adapter: the adapter
769 * @addr: the start address for the read
770 * @nwords: how many 32-bit words to read
771 * @data: where to store the read data
772 * @byte_oriented: whether to store data as bytes or as words
773 *
774 * Read the specified number of 32-bit words from the serial flash.
775 * If @byte_oriented is set the read data is stored as a byte array
776 * (i.e., big-endian), otherwise as 32-bit words in the platform's
777 * natural endianess.
778 */
779int t3_read_flash(struct adapter *adapter, unsigned int addr,
780 unsigned int nwords, u32 *data, int byte_oriented)
781{
782 int ret;
783
784 if (addr + nwords * sizeof(u32) > SF_SIZE || (addr & 3))
785 return -EINVAL;
786
787 addr = swab32(addr) | SF_RD_DATA_FAST;
788
789 if ((ret = sf1_write(adapter, 4, 1, addr)) != 0 ||
790 (ret = sf1_read(adapter, 1, 1, data)) != 0)
791 return ret;
792
793 for (; nwords; nwords--, data++) {
794 ret = sf1_read(adapter, 4, nwords > 1, data);
795 if (ret)
796 return ret;
797 if (byte_oriented)
798 *data = htonl(*data);
799 }
800 return 0;
801}
802
803/**
804 * t3_write_flash - write up to a page of data to the serial flash
805 * @adapter: the adapter
806 * @addr: the start address to write
807 * @n: length of data to write
808 * @data: the data to write
809 *
810 * Writes up to a page of data (256 bytes) to the serial flash starting
811 * at the given address.
812 */
813static int t3_write_flash(struct adapter *adapter, unsigned int addr,
814 unsigned int n, const u8 *data)
815{
816 int ret;
817 u32 buf[64];
818 unsigned int i, c, left, val, offset = addr & 0xff;
819
820 if (addr + n > SF_SIZE || offset + n > 256)
821 return -EINVAL;
822
823 val = swab32(addr) | SF_PROG_PAGE;
824
825 if ((ret = sf1_write(adapter, 1, 0, SF_WR_ENABLE)) != 0 ||
826 (ret = sf1_write(adapter, 4, 1, val)) != 0)
827 return ret;
828
829 for (left = n; left; left -= c) {
830 c = min(left, 4U);
831 for (val = 0, i = 0; i < c; ++i)
832 val = (val << 8) + *data++;
833
834 ret = sf1_write(adapter, c, c != left, val);
835 if (ret)
836 return ret;
837 }
838 if ((ret = flash_wait_op(adapter, 5, 1)) != 0)
839 return ret;
840
841 /* Read the page to verify the write succeeded */
842 ret = t3_read_flash(adapter, addr & ~0xff, ARRAY_SIZE(buf), buf, 1);
843 if (ret)
844 return ret;
845
846 if (memcmp(data - n, (u8 *) buf + offset, n))
847 return -EIO;
848 return 0;
849}
850
Divy Le Ray480fe1a2007-05-30 21:10:58 -0700851/**
Divy Le Ray47330072007-08-29 19:15:52 -0700852 * t3_get_tp_version - read the tp sram version
Divy Le Ray480fe1a2007-05-30 21:10:58 -0700853 * @adapter: the adapter
Divy Le Ray47330072007-08-29 19:15:52 -0700854 * @vers: where to place the version
Divy Le Ray480fe1a2007-05-30 21:10:58 -0700855 *
Divy Le Ray47330072007-08-29 19:15:52 -0700856 * Reads the protocol sram version from sram.
Divy Le Ray480fe1a2007-05-30 21:10:58 -0700857 */
Divy Le Ray47330072007-08-29 19:15:52 -0700858int t3_get_tp_version(struct adapter *adapter, u32 *vers)
Divy Le Ray480fe1a2007-05-30 21:10:58 -0700859{
860 int ret;
Divy Le Ray480fe1a2007-05-30 21:10:58 -0700861
862 /* Get version loaded in SRAM */
863 t3_write_reg(adapter, A_TP_EMBED_OP_FIELD0, 0);
864 ret = t3_wait_op_done(adapter, A_TP_EMBED_OP_FIELD0,
865 1, 1, 5, 1);
866 if (ret)
867 return ret;
868
Divy Le Ray47330072007-08-29 19:15:52 -0700869 *vers = t3_read_reg(adapter, A_TP_EMBED_OP_FIELD1);
870
871 return 0;
872}
873
874/**
875 * t3_check_tpsram_version - read the tp sram version
876 * @adapter: the adapter
877 * @must_load: set to 1 if loading a new microcode image is required
878 *
879 * Reads the protocol sram version from flash.
880 */
881int t3_check_tpsram_version(struct adapter *adapter, int *must_load)
882{
883 int ret;
884 u32 vers;
885 unsigned int major, minor;
886
887 if (adapter->params.rev == T3_REV_A)
888 return 0;
889
890 *must_load = 1;
891
892 ret = t3_get_tp_version(adapter, &vers);
893 if (ret)
894 return ret;
Divy Le Ray480fe1a2007-05-30 21:10:58 -0700895
896 major = G_TP_VERSION_MAJOR(vers);
897 minor = G_TP_VERSION_MINOR(vers);
898
899 if (major == TP_VERSION_MAJOR && minor == TP_VERSION_MINOR)
900 return 0;
901
Divy Le Ray47330072007-08-29 19:15:52 -0700902 if (major != TP_VERSION_MAJOR)
903 CH_ERR(adapter, "found wrong TP version (%u.%u), "
904 "driver needs version %d.%d\n", major, minor,
905 TP_VERSION_MAJOR, TP_VERSION_MINOR);
906 else {
907 *must_load = 0;
908 CH_ERR(adapter, "found wrong TP version (%u.%u), "
909 "driver compiled for version %d.%d\n", major, minor,
910 TP_VERSION_MAJOR, TP_VERSION_MINOR);
911 }
Divy Le Ray480fe1a2007-05-30 21:10:58 -0700912 return -EINVAL;
913}
914
915/**
916 * t3_check_tpsram - check if provided protocol SRAM
917 * is compatible with this driver
918 * @adapter: the adapter
919 * @tp_sram: the firmware image to write
920 * @size: image size
921 *
922 * Checks if an adapter's tp sram is compatible with the driver.
923 * Returns 0 if the versions are compatible, a negative error otherwise.
924 */
925int t3_check_tpsram(struct adapter *adapter, u8 *tp_sram, unsigned int size)
926{
927 u32 csum;
928 unsigned int i;
929 const u32 *p = (const u32 *)tp_sram;
930
931 /* Verify checksum */
932 for (csum = 0, i = 0; i < size / sizeof(csum); i++)
933 csum += ntohl(p[i]);
934 if (csum != 0xffffffff) {
935 CH_ERR(adapter, "corrupted protocol SRAM image, checksum %u\n",
936 csum);
937 return -EINVAL;
938 }
939
940 return 0;
941}
942
Divy Le Ray4aac3892007-01-30 19:43:45 -0800943enum fw_version_type {
944 FW_VERSION_N3,
945 FW_VERSION_T3
946};
947
Divy Le Ray4d22de32007-01-18 22:04:14 -0500948/**
949 * t3_get_fw_version - read the firmware version
950 * @adapter: the adapter
951 * @vers: where to place the version
952 *
953 * Reads the FW version from flash.
954 */
955int t3_get_fw_version(struct adapter *adapter, u32 *vers)
956{
957 return t3_read_flash(adapter, FW_VERS_ADDR, 1, vers, 0);
958}
959
960/**
961 * t3_check_fw_version - check if the FW is compatible with this driver
962 * @adapter: the adapter
963 *
964 * Checks if an adapter's FW is compatible with the driver. Returns 0
965 * if the versions are compatible, a negative error otherwise.
966 */
967int t3_check_fw_version(struct adapter *adapter)
968{
969 int ret;
970 u32 vers;
Divy Le Ray4aac3892007-01-30 19:43:45 -0800971 unsigned int type, major, minor;
Divy Le Ray4d22de32007-01-18 22:04:14 -0500972
973 ret = t3_get_fw_version(adapter, &vers);
974 if (ret)
975 return ret;
976
Divy Le Ray4aac3892007-01-30 19:43:45 -0800977 type = G_FW_VERSION_TYPE(vers);
978 major = G_FW_VERSION_MAJOR(vers);
979 minor = G_FW_VERSION_MINOR(vers);
980
Divy Le Ray75d86262007-02-25 16:32:37 -0800981 if (type == FW_VERSION_T3 && major == FW_VERSION_MAJOR &&
982 minor == FW_VERSION_MINOR)
Divy Le Ray4d22de32007-01-18 22:04:14 -0500983 return 0;
984
Divy Le Ray4aac3892007-01-30 19:43:45 -0800985 CH_ERR(adapter, "found wrong FW version(%u.%u), "
Divy Le Ray75d86262007-02-25 16:32:37 -0800986 "driver needs version %u.%u\n", major, minor,
987 FW_VERSION_MAJOR, FW_VERSION_MINOR);
Divy Le Ray4d22de32007-01-18 22:04:14 -0500988 return -EINVAL;
989}
990
991/**
992 * t3_flash_erase_sectors - erase a range of flash sectors
993 * @adapter: the adapter
994 * @start: the first sector to erase
995 * @end: the last sector to erase
996 *
997 * Erases the sectors in the given range.
998 */
999static int t3_flash_erase_sectors(struct adapter *adapter, int start, int end)
1000{
1001 while (start <= end) {
1002 int ret;
1003
1004 if ((ret = sf1_write(adapter, 1, 0, SF_WR_ENABLE)) != 0 ||
1005 (ret = sf1_write(adapter, 4, 0,
1006 SF_ERASE_SECTOR | (start << 8))) != 0 ||
1007 (ret = flash_wait_op(adapter, 5, 500)) != 0)
1008 return ret;
1009 start++;
1010 }
1011 return 0;
1012}
1013
1014/*
1015 * t3_load_fw - download firmware
1016 * @adapter: the adapter
Divy Le Ray8a9fab22007-05-30 21:10:52 -07001017 * @fw_data: the firmware image to write
Divy Le Ray4d22de32007-01-18 22:04:14 -05001018 * @size: image size
1019 *
1020 * Write the supplied firmware image to the card's serial flash.
1021 * The FW image has the following sections: @size - 8 bytes of code and
1022 * data, followed by 4 bytes of FW version, followed by the 32-bit
1023 * 1's complement checksum of the whole image.
1024 */
1025int t3_load_fw(struct adapter *adapter, const u8 *fw_data, unsigned int size)
1026{
1027 u32 csum;
1028 unsigned int i;
1029 const u32 *p = (const u32 *)fw_data;
1030 int ret, addr, fw_sector = FW_FLASH_BOOT_ADDR >> 16;
1031
Divy Le Ray2e283962007-03-18 13:10:06 -07001032 if ((size & 3) || size < FW_MIN_SIZE)
Divy Le Ray4d22de32007-01-18 22:04:14 -05001033 return -EINVAL;
1034 if (size > FW_VERS_ADDR + 8 - FW_FLASH_BOOT_ADDR)
1035 return -EFBIG;
1036
1037 for (csum = 0, i = 0; i < size / sizeof(csum); i++)
1038 csum += ntohl(p[i]);
1039 if (csum != 0xffffffff) {
1040 CH_ERR(adapter, "corrupted firmware image, checksum %u\n",
1041 csum);
1042 return -EINVAL;
1043 }
1044
1045 ret = t3_flash_erase_sectors(adapter, fw_sector, fw_sector);
1046 if (ret)
1047 goto out;
1048
1049 size -= 8; /* trim off version and checksum */
1050 for (addr = FW_FLASH_BOOT_ADDR; size;) {
1051 unsigned int chunk_size = min(size, 256U);
1052
1053 ret = t3_write_flash(adapter, addr, chunk_size, fw_data);
1054 if (ret)
1055 goto out;
1056
1057 addr += chunk_size;
1058 fw_data += chunk_size;
1059 size -= chunk_size;
1060 }
1061
1062 ret = t3_write_flash(adapter, FW_VERS_ADDR, 4, fw_data);
1063out:
1064 if (ret)
1065 CH_ERR(adapter, "firmware download failed, error %d\n", ret);
1066 return ret;
1067}
1068
1069#define CIM_CTL_BASE 0x2000
1070
1071/**
1072 * t3_cim_ctl_blk_read - read a block from CIM control region
1073 *
1074 * @adap: the adapter
1075 * @addr: the start address within the CIM control region
1076 * @n: number of words to read
1077 * @valp: where to store the result
1078 *
1079 * Reads a block of 4-byte words from the CIM control region.
1080 */
1081int t3_cim_ctl_blk_read(struct adapter *adap, unsigned int addr,
1082 unsigned int n, unsigned int *valp)
1083{
1084 int ret = 0;
1085
1086 if (t3_read_reg(adap, A_CIM_HOST_ACC_CTRL) & F_HOSTBUSY)
1087 return -EBUSY;
1088
1089 for ( ; !ret && n--; addr += 4) {
1090 t3_write_reg(adap, A_CIM_HOST_ACC_CTRL, CIM_CTL_BASE + addr);
1091 ret = t3_wait_op_done(adap, A_CIM_HOST_ACC_CTRL, F_HOSTBUSY,
1092 0, 5, 2);
1093 if (!ret)
1094 *valp++ = t3_read_reg(adap, A_CIM_HOST_ACC_DATA);
1095 }
1096 return ret;
1097}
1098
1099
1100/**
1101 * t3_link_changed - handle interface link changes
1102 * @adapter: the adapter
1103 * @port_id: the port index that changed link state
1104 *
1105 * Called when a port's link settings change to propagate the new values
1106 * to the associated PHY and MAC. After performing the common tasks it
1107 * invokes an OS-specific handler.
1108 */
1109void t3_link_changed(struct adapter *adapter, int port_id)
1110{
1111 int link_ok, speed, duplex, fc;
1112 struct port_info *pi = adap2pinfo(adapter, port_id);
1113 struct cphy *phy = &pi->phy;
1114 struct cmac *mac = &pi->mac;
1115 struct link_config *lc = &pi->link_config;
1116
1117 phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc);
1118
1119 if (link_ok != lc->link_ok && adapter->params.rev > 0 &&
1120 uses_xaui(adapter)) {
1121 if (link_ok)
1122 t3b_pcs_reset(mac);
1123 t3_write_reg(adapter, A_XGM_XAUI_ACT_CTRL + mac->offset,
1124 link_ok ? F_TXACTENABLE | F_RXEN : 0);
1125 }
1126 lc->link_ok = link_ok;
1127 lc->speed = speed < 0 ? SPEED_INVALID : speed;
1128 lc->duplex = duplex < 0 ? DUPLEX_INVALID : duplex;
1129 if (lc->requested_fc & PAUSE_AUTONEG)
1130 fc &= lc->requested_fc;
1131 else
1132 fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
1133
1134 if (link_ok && speed >= 0 && lc->autoneg == AUTONEG_ENABLE) {
1135 /* Set MAC speed, duplex, and flow control to match PHY. */
1136 t3_mac_set_speed_duplex_fc(mac, speed, duplex, fc);
1137 lc->fc = fc;
1138 }
1139
1140 t3_os_link_changed(adapter, port_id, link_ok, speed, duplex, fc);
1141}
1142
1143/**
1144 * t3_link_start - apply link configuration to MAC/PHY
1145 * @phy: the PHY to setup
1146 * @mac: the MAC to setup
1147 * @lc: the requested link configuration
1148 *
1149 * Set up a port's MAC and PHY according to a desired link configuration.
1150 * - If the PHY can auto-negotiate first decide what to advertise, then
1151 * enable/disable auto-negotiation as desired, and reset.
1152 * - If the PHY does not auto-negotiate just reset it.
1153 * - If auto-negotiation is off set the MAC to the proper speed/duplex/FC,
1154 * otherwise do it later based on the outcome of auto-negotiation.
1155 */
1156int t3_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc)
1157{
1158 unsigned int fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
1159
1160 lc->link_ok = 0;
1161 if (lc->supported & SUPPORTED_Autoneg) {
1162 lc->advertising &= ~(ADVERTISED_Asym_Pause | ADVERTISED_Pause);
1163 if (fc) {
1164 lc->advertising |= ADVERTISED_Asym_Pause;
1165 if (fc & PAUSE_RX)
1166 lc->advertising |= ADVERTISED_Pause;
1167 }
1168 phy->ops->advertise(phy, lc->advertising);
1169
1170 if (lc->autoneg == AUTONEG_DISABLE) {
1171 lc->speed = lc->requested_speed;
1172 lc->duplex = lc->requested_duplex;
1173 lc->fc = (unsigned char)fc;
1174 t3_mac_set_speed_duplex_fc(mac, lc->speed, lc->duplex,
1175 fc);
1176 /* Also disables autoneg */
1177 phy->ops->set_speed_duplex(phy, lc->speed, lc->duplex);
1178 phy->ops->reset(phy, 0);
1179 } else
1180 phy->ops->autoneg_enable(phy);
1181 } else {
1182 t3_mac_set_speed_duplex_fc(mac, -1, -1, fc);
1183 lc->fc = (unsigned char)fc;
1184 phy->ops->reset(phy, 0);
1185 }
1186 return 0;
1187}
1188
1189/**
1190 * t3_set_vlan_accel - control HW VLAN extraction
1191 * @adapter: the adapter
1192 * @ports: bitmap of adapter ports to operate on
1193 * @on: enable (1) or disable (0) HW VLAN extraction
1194 *
1195 * Enables or disables HW extraction of VLAN tags for the given port.
1196 */
1197void t3_set_vlan_accel(struct adapter *adapter, unsigned int ports, int on)
1198{
1199 t3_set_reg_field(adapter, A_TP_OUT_CONFIG,
1200 ports << S_VLANEXTRACTIONENABLE,
1201 on ? (ports << S_VLANEXTRACTIONENABLE) : 0);
1202}
1203
1204struct intr_info {
1205 unsigned int mask; /* bits to check in interrupt status */
1206 const char *msg; /* message to print or NULL */
1207 short stat_idx; /* stat counter to increment or -1 */
1208 unsigned short fatal:1; /* whether the condition reported is fatal */
1209};
1210
1211/**
1212 * t3_handle_intr_status - table driven interrupt handler
1213 * @adapter: the adapter that generated the interrupt
1214 * @reg: the interrupt status register to process
1215 * @mask: a mask to apply to the interrupt status
1216 * @acts: table of interrupt actions
1217 * @stats: statistics counters tracking interrupt occurences
1218 *
1219 * A table driven interrupt handler that applies a set of masks to an
1220 * interrupt status word and performs the corresponding actions if the
1221 * interrupts described by the mask have occured. The actions include
1222 * optionally printing a warning or alert message, and optionally
1223 * incrementing a stat counter. The table is terminated by an entry
1224 * specifying mask 0. Returns the number of fatal interrupt conditions.
1225 */
1226static int t3_handle_intr_status(struct adapter *adapter, unsigned int reg,
1227 unsigned int mask,
1228 const struct intr_info *acts,
1229 unsigned long *stats)
1230{
1231 int fatal = 0;
1232 unsigned int status = t3_read_reg(adapter, reg) & mask;
1233
1234 for (; acts->mask; ++acts) {
1235 if (!(status & acts->mask))
1236 continue;
1237 if (acts->fatal) {
1238 fatal++;
1239 CH_ALERT(adapter, "%s (0x%x)\n",
1240 acts->msg, status & acts->mask);
1241 } else if (acts->msg)
1242 CH_WARN(adapter, "%s (0x%x)\n",
1243 acts->msg, status & acts->mask);
1244 if (acts->stat_idx >= 0)
1245 stats[acts->stat_idx]++;
1246 }
1247 if (status) /* clear processed interrupts */
1248 t3_write_reg(adapter, reg, status);
1249 return fatal;
1250}
1251
1252#define SGE_INTR_MASK (F_RSPQDISABLED)
1253#define MC5_INTR_MASK (F_PARITYERR | F_ACTRGNFULL | F_UNKNOWNCMD | \
1254 F_REQQPARERR | F_DISPQPARERR | F_DELACTEMPTY | \
1255 F_NFASRCHFAIL)
1256#define MC7_INTR_MASK (F_AE | F_UE | F_CE | V_PE(M_PE))
1257#define XGM_INTR_MASK (V_TXFIFO_PRTY_ERR(M_TXFIFO_PRTY_ERR) | \
1258 V_RXFIFO_PRTY_ERR(M_RXFIFO_PRTY_ERR) | \
1259 F_TXFIFO_UNDERRUN | F_RXFIFO_OVERFLOW)
1260#define PCIX_INTR_MASK (F_MSTDETPARERR | F_SIGTARABT | F_RCVTARABT | \
1261 F_RCVMSTABT | F_SIGSYSERR | F_DETPARERR | \
1262 F_SPLCMPDIS | F_UNXSPLCMP | F_RCVSPLCMPERR | \
1263 F_DETCORECCERR | F_DETUNCECCERR | F_PIOPARERR | \
1264 V_WFPARERR(M_WFPARERR) | V_RFPARERR(M_RFPARERR) | \
1265 V_CFPARERR(M_CFPARERR) /* | V_MSIXPARERR(M_MSIXPARERR) */)
1266#define PCIE_INTR_MASK (F_UNXSPLCPLERRR | F_UNXSPLCPLERRC | F_PCIE_PIOPARERR |\
1267 F_PCIE_WFPARERR | F_PCIE_RFPARERR | F_PCIE_CFPARERR | \
1268 /* V_PCIE_MSIXPARERR(M_PCIE_MSIXPARERR) | */ \
1269 V_BISTERR(M_BISTERR) | F_PEXERR)
1270#define ULPRX_INTR_MASK F_PARERR
1271#define ULPTX_INTR_MASK 0
1272#define CPLSW_INTR_MASK (F_TP_FRAMING_ERROR | \
1273 F_SGE_FRAMING_ERROR | F_CIM_FRAMING_ERROR | \
1274 F_ZERO_SWITCH_ERROR)
1275#define CIM_INTR_MASK (F_BLKWRPLINT | F_BLKRDPLINT | F_BLKWRCTLINT | \
1276 F_BLKRDCTLINT | F_BLKWRFLASHINT | F_BLKRDFLASHINT | \
1277 F_SGLWRFLASHINT | F_WRBLKFLASHINT | F_BLKWRBOOTINT | \
1278 F_FLASHRANGEINT | F_SDRAMRANGEINT | F_RSVDSPACEINT)
1279#define PMTX_INTR_MASK (F_ZERO_C_CMD_ERROR | ICSPI_FRM_ERR | OESPI_FRM_ERR | \
1280 V_ICSPI_PAR_ERROR(M_ICSPI_PAR_ERROR) | \
1281 V_OESPI_PAR_ERROR(M_OESPI_PAR_ERROR))
1282#define PMRX_INTR_MASK (F_ZERO_E_CMD_ERROR | IESPI_FRM_ERR | OCSPI_FRM_ERR | \
1283 V_IESPI_PAR_ERROR(M_IESPI_PAR_ERROR) | \
1284 V_OCSPI_PAR_ERROR(M_OCSPI_PAR_ERROR))
1285#define MPS_INTR_MASK (V_TX0TPPARERRENB(M_TX0TPPARERRENB) | \
1286 V_TX1TPPARERRENB(M_TX1TPPARERRENB) | \
1287 V_RXTPPARERRENB(M_RXTPPARERRENB) | \
1288 V_MCAPARERRENB(M_MCAPARERRENB))
1289#define PL_INTR_MASK (F_T3DBG | F_XGMAC0_0 | F_XGMAC0_1 | F_MC5A | F_PM1_TX | \
1290 F_PM1_RX | F_ULP2_TX | F_ULP2_RX | F_TP1 | F_CIM | \
1291 F_MC7_CM | F_MC7_PMTX | F_MC7_PMRX | F_SGE3 | F_PCIM0 | \
1292 F_MPS0 | F_CPL_SWITCH)
1293
1294/*
1295 * Interrupt handler for the PCIX1 module.
1296 */
1297static void pci_intr_handler(struct adapter *adapter)
1298{
1299 static const struct intr_info pcix1_intr_info[] = {
Divy Le Ray4d22de32007-01-18 22:04:14 -05001300 {F_MSTDETPARERR, "PCI master detected parity error", -1, 1},
1301 {F_SIGTARABT, "PCI signaled target abort", -1, 1},
1302 {F_RCVTARABT, "PCI received target abort", -1, 1},
1303 {F_RCVMSTABT, "PCI received master abort", -1, 1},
1304 {F_SIGSYSERR, "PCI signaled system error", -1, 1},
1305 {F_DETPARERR, "PCI detected parity error", -1, 1},
1306 {F_SPLCMPDIS, "PCI split completion discarded", -1, 1},
1307 {F_UNXSPLCMP, "PCI unexpected split completion error", -1, 1},
1308 {F_RCVSPLCMPERR, "PCI received split completion error", -1,
1309 1},
1310 {F_DETCORECCERR, "PCI correctable ECC error",
1311 STAT_PCI_CORR_ECC, 0},
1312 {F_DETUNCECCERR, "PCI uncorrectable ECC error", -1, 1},
1313 {F_PIOPARERR, "PCI PIO FIFO parity error", -1, 1},
1314 {V_WFPARERR(M_WFPARERR), "PCI write FIFO parity error", -1,
1315 1},
1316 {V_RFPARERR(M_RFPARERR), "PCI read FIFO parity error", -1,
1317 1},
1318 {V_CFPARERR(M_CFPARERR), "PCI command FIFO parity error", -1,
1319 1},
1320 {V_MSIXPARERR(M_MSIXPARERR), "PCI MSI-X table/PBA parity "
1321 "error", -1, 1},
1322 {0}
1323 };
1324
1325 if (t3_handle_intr_status(adapter, A_PCIX_INT_CAUSE, PCIX_INTR_MASK,
1326 pcix1_intr_info, adapter->irq_stats))
1327 t3_fatal_err(adapter);
1328}
1329
1330/*
1331 * Interrupt handler for the PCIE module.
1332 */
1333static void pcie_intr_handler(struct adapter *adapter)
1334{
1335 static const struct intr_info pcie_intr_info[] = {
Divy Le Rayb5a44bc2007-01-30 19:44:01 -08001336 {F_PEXERR, "PCI PEX error", -1, 1},
Divy Le Ray4d22de32007-01-18 22:04:14 -05001337 {F_UNXSPLCPLERRR,
1338 "PCI unexpected split completion DMA read error", -1, 1},
1339 {F_UNXSPLCPLERRC,
1340 "PCI unexpected split completion DMA command error", -1, 1},
1341 {F_PCIE_PIOPARERR, "PCI PIO FIFO parity error", -1, 1},
1342 {F_PCIE_WFPARERR, "PCI write FIFO parity error", -1, 1},
1343 {F_PCIE_RFPARERR, "PCI read FIFO parity error", -1, 1},
1344 {F_PCIE_CFPARERR, "PCI command FIFO parity error", -1, 1},
1345 {V_PCIE_MSIXPARERR(M_PCIE_MSIXPARERR),
1346 "PCI MSI-X table/PBA parity error", -1, 1},
1347 {V_BISTERR(M_BISTERR), "PCI BIST error", -1, 1},
1348 {0}
1349 };
1350
1351 if (t3_handle_intr_status(adapter, A_PCIE_INT_CAUSE, PCIE_INTR_MASK,
1352 pcie_intr_info, adapter->irq_stats))
1353 t3_fatal_err(adapter);
1354}
1355
1356/*
1357 * TP interrupt handler.
1358 */
1359static void tp_intr_handler(struct adapter *adapter)
1360{
1361 static const struct intr_info tp_intr_info[] = {
1362 {0xffffff, "TP parity error", -1, 1},
1363 {0x1000000, "TP out of Rx pages", -1, 1},
1364 {0x2000000, "TP out of Tx pages", -1, 1},
1365 {0}
1366 };
1367
1368 if (t3_handle_intr_status(adapter, A_TP_INT_CAUSE, 0xffffffff,
1369 tp_intr_info, NULL))
1370 t3_fatal_err(adapter);
1371}
1372
1373/*
1374 * CIM interrupt handler.
1375 */
1376static void cim_intr_handler(struct adapter *adapter)
1377{
1378 static const struct intr_info cim_intr_info[] = {
1379 {F_RSVDSPACEINT, "CIM reserved space write", -1, 1},
1380 {F_SDRAMRANGEINT, "CIM SDRAM address out of range", -1, 1},
1381 {F_FLASHRANGEINT, "CIM flash address out of range", -1, 1},
1382 {F_BLKWRBOOTINT, "CIM block write to boot space", -1, 1},
1383 {F_WRBLKFLASHINT, "CIM write to cached flash space", -1, 1},
1384 {F_SGLWRFLASHINT, "CIM single write to flash space", -1, 1},
1385 {F_BLKRDFLASHINT, "CIM block read from flash space", -1, 1},
1386 {F_BLKWRFLASHINT, "CIM block write to flash space", -1, 1},
1387 {F_BLKRDCTLINT, "CIM block read from CTL space", -1, 1},
1388 {F_BLKWRCTLINT, "CIM block write to CTL space", -1, 1},
1389 {F_BLKRDPLINT, "CIM block read from PL space", -1, 1},
1390 {F_BLKWRPLINT, "CIM block write to PL space", -1, 1},
1391 {0}
1392 };
1393
1394 if (t3_handle_intr_status(adapter, A_CIM_HOST_INT_CAUSE, 0xffffffff,
1395 cim_intr_info, NULL))
1396 t3_fatal_err(adapter);
1397}
1398
1399/*
1400 * ULP RX interrupt handler.
1401 */
1402static void ulprx_intr_handler(struct adapter *adapter)
1403{
1404 static const struct intr_info ulprx_intr_info[] = {
1405 {F_PARERR, "ULP RX parity error", -1, 1},
1406 {0}
1407 };
1408
1409 if (t3_handle_intr_status(adapter, A_ULPRX_INT_CAUSE, 0xffffffff,
1410 ulprx_intr_info, NULL))
1411 t3_fatal_err(adapter);
1412}
1413
1414/*
1415 * ULP TX interrupt handler.
1416 */
1417static void ulptx_intr_handler(struct adapter *adapter)
1418{
1419 static const struct intr_info ulptx_intr_info[] = {
1420 {F_PBL_BOUND_ERR_CH0, "ULP TX channel 0 PBL out of bounds",
1421 STAT_ULP_CH0_PBL_OOB, 0},
1422 {F_PBL_BOUND_ERR_CH1, "ULP TX channel 1 PBL out of bounds",
1423 STAT_ULP_CH1_PBL_OOB, 0},
1424 {0}
1425 };
1426
1427 if (t3_handle_intr_status(adapter, A_ULPTX_INT_CAUSE, 0xffffffff,
1428 ulptx_intr_info, adapter->irq_stats))
1429 t3_fatal_err(adapter);
1430}
1431
1432#define ICSPI_FRM_ERR (F_ICSPI0_FIFO2X_RX_FRAMING_ERROR | \
1433 F_ICSPI1_FIFO2X_RX_FRAMING_ERROR | F_ICSPI0_RX_FRAMING_ERROR | \
1434 F_ICSPI1_RX_FRAMING_ERROR | F_ICSPI0_TX_FRAMING_ERROR | \
1435 F_ICSPI1_TX_FRAMING_ERROR)
1436#define OESPI_FRM_ERR (F_OESPI0_RX_FRAMING_ERROR | \
1437 F_OESPI1_RX_FRAMING_ERROR | F_OESPI0_TX_FRAMING_ERROR | \
1438 F_OESPI1_TX_FRAMING_ERROR | F_OESPI0_OFIFO2X_TX_FRAMING_ERROR | \
1439 F_OESPI1_OFIFO2X_TX_FRAMING_ERROR)
1440
1441/*
1442 * PM TX interrupt handler.
1443 */
1444static void pmtx_intr_handler(struct adapter *adapter)
1445{
1446 static const struct intr_info pmtx_intr_info[] = {
1447 {F_ZERO_C_CMD_ERROR, "PMTX 0-length pcmd", -1, 1},
1448 {ICSPI_FRM_ERR, "PMTX ispi framing error", -1, 1},
1449 {OESPI_FRM_ERR, "PMTX ospi framing error", -1, 1},
1450 {V_ICSPI_PAR_ERROR(M_ICSPI_PAR_ERROR),
1451 "PMTX ispi parity error", -1, 1},
1452 {V_OESPI_PAR_ERROR(M_OESPI_PAR_ERROR),
1453 "PMTX ospi parity error", -1, 1},
1454 {0}
1455 };
1456
1457 if (t3_handle_intr_status(adapter, A_PM1_TX_INT_CAUSE, 0xffffffff,
1458 pmtx_intr_info, NULL))
1459 t3_fatal_err(adapter);
1460}
1461
1462#define IESPI_FRM_ERR (F_IESPI0_FIFO2X_RX_FRAMING_ERROR | \
1463 F_IESPI1_FIFO2X_RX_FRAMING_ERROR | F_IESPI0_RX_FRAMING_ERROR | \
1464 F_IESPI1_RX_FRAMING_ERROR | F_IESPI0_TX_FRAMING_ERROR | \
1465 F_IESPI1_TX_FRAMING_ERROR)
1466#define OCSPI_FRM_ERR (F_OCSPI0_RX_FRAMING_ERROR | \
1467 F_OCSPI1_RX_FRAMING_ERROR | F_OCSPI0_TX_FRAMING_ERROR | \
1468 F_OCSPI1_TX_FRAMING_ERROR | F_OCSPI0_OFIFO2X_TX_FRAMING_ERROR | \
1469 F_OCSPI1_OFIFO2X_TX_FRAMING_ERROR)
1470
1471/*
1472 * PM RX interrupt handler.
1473 */
1474static void pmrx_intr_handler(struct adapter *adapter)
1475{
1476 static const struct intr_info pmrx_intr_info[] = {
1477 {F_ZERO_E_CMD_ERROR, "PMRX 0-length pcmd", -1, 1},
1478 {IESPI_FRM_ERR, "PMRX ispi framing error", -1, 1},
1479 {OCSPI_FRM_ERR, "PMRX ospi framing error", -1, 1},
1480 {V_IESPI_PAR_ERROR(M_IESPI_PAR_ERROR),
1481 "PMRX ispi parity error", -1, 1},
1482 {V_OCSPI_PAR_ERROR(M_OCSPI_PAR_ERROR),
1483 "PMRX ospi parity error", -1, 1},
1484 {0}
1485 };
1486
1487 if (t3_handle_intr_status(adapter, A_PM1_RX_INT_CAUSE, 0xffffffff,
1488 pmrx_intr_info, NULL))
1489 t3_fatal_err(adapter);
1490}
1491
1492/*
1493 * CPL switch interrupt handler.
1494 */
1495static void cplsw_intr_handler(struct adapter *adapter)
1496{
1497 static const struct intr_info cplsw_intr_info[] = {
1498/* { F_CIM_OVFL_ERROR, "CPL switch CIM overflow", -1, 1 }, */
1499 {F_TP_FRAMING_ERROR, "CPL switch TP framing error", -1, 1},
1500 {F_SGE_FRAMING_ERROR, "CPL switch SGE framing error", -1, 1},
1501 {F_CIM_FRAMING_ERROR, "CPL switch CIM framing error", -1, 1},
1502 {F_ZERO_SWITCH_ERROR, "CPL switch no-switch error", -1, 1},
1503 {0}
1504 };
1505
1506 if (t3_handle_intr_status(adapter, A_CPL_INTR_CAUSE, 0xffffffff,
1507 cplsw_intr_info, NULL))
1508 t3_fatal_err(adapter);
1509}
1510
1511/*
1512 * MPS interrupt handler.
1513 */
1514static void mps_intr_handler(struct adapter *adapter)
1515{
1516 static const struct intr_info mps_intr_info[] = {
1517 {0x1ff, "MPS parity error", -1, 1},
1518 {0}
1519 };
1520
1521 if (t3_handle_intr_status(adapter, A_MPS_INT_CAUSE, 0xffffffff,
1522 mps_intr_info, NULL))
1523 t3_fatal_err(adapter);
1524}
1525
1526#define MC7_INTR_FATAL (F_UE | V_PE(M_PE) | F_AE)
1527
1528/*
1529 * MC7 interrupt handler.
1530 */
1531static void mc7_intr_handler(struct mc7 *mc7)
1532{
1533 struct adapter *adapter = mc7->adapter;
1534 u32 cause = t3_read_reg(adapter, mc7->offset + A_MC7_INT_CAUSE);
1535
1536 if (cause & F_CE) {
1537 mc7->stats.corr_err++;
1538 CH_WARN(adapter, "%s MC7 correctable error at addr 0x%x, "
1539 "data 0x%x 0x%x 0x%x\n", mc7->name,
1540 t3_read_reg(adapter, mc7->offset + A_MC7_CE_ADDR),
1541 t3_read_reg(adapter, mc7->offset + A_MC7_CE_DATA0),
1542 t3_read_reg(adapter, mc7->offset + A_MC7_CE_DATA1),
1543 t3_read_reg(adapter, mc7->offset + A_MC7_CE_DATA2));
1544 }
1545
1546 if (cause & F_UE) {
1547 mc7->stats.uncorr_err++;
1548 CH_ALERT(adapter, "%s MC7 uncorrectable error at addr 0x%x, "
1549 "data 0x%x 0x%x 0x%x\n", mc7->name,
1550 t3_read_reg(adapter, mc7->offset + A_MC7_UE_ADDR),
1551 t3_read_reg(adapter, mc7->offset + A_MC7_UE_DATA0),
1552 t3_read_reg(adapter, mc7->offset + A_MC7_UE_DATA1),
1553 t3_read_reg(adapter, mc7->offset + A_MC7_UE_DATA2));
1554 }
1555
1556 if (G_PE(cause)) {
1557 mc7->stats.parity_err++;
1558 CH_ALERT(adapter, "%s MC7 parity error 0x%x\n",
1559 mc7->name, G_PE(cause));
1560 }
1561
1562 if (cause & F_AE) {
1563 u32 addr = 0;
1564
1565 if (adapter->params.rev > 0)
1566 addr = t3_read_reg(adapter,
1567 mc7->offset + A_MC7_ERR_ADDR);
1568 mc7->stats.addr_err++;
1569 CH_ALERT(adapter, "%s MC7 address error: 0x%x\n",
1570 mc7->name, addr);
1571 }
1572
1573 if (cause & MC7_INTR_FATAL)
1574 t3_fatal_err(adapter);
1575
1576 t3_write_reg(adapter, mc7->offset + A_MC7_INT_CAUSE, cause);
1577}
1578
1579#define XGM_INTR_FATAL (V_TXFIFO_PRTY_ERR(M_TXFIFO_PRTY_ERR) | \
1580 V_RXFIFO_PRTY_ERR(M_RXFIFO_PRTY_ERR))
1581/*
1582 * XGMAC interrupt handler.
1583 */
1584static int mac_intr_handler(struct adapter *adap, unsigned int idx)
1585{
1586 struct cmac *mac = &adap2pinfo(adap, idx)->mac;
1587 u32 cause = t3_read_reg(adap, A_XGM_INT_CAUSE + mac->offset);
1588
1589 if (cause & V_TXFIFO_PRTY_ERR(M_TXFIFO_PRTY_ERR)) {
1590 mac->stats.tx_fifo_parity_err++;
1591 CH_ALERT(adap, "port%d: MAC TX FIFO parity error\n", idx);
1592 }
1593 if (cause & V_RXFIFO_PRTY_ERR(M_RXFIFO_PRTY_ERR)) {
1594 mac->stats.rx_fifo_parity_err++;
1595 CH_ALERT(adap, "port%d: MAC RX FIFO parity error\n", idx);
1596 }
1597 if (cause & F_TXFIFO_UNDERRUN)
1598 mac->stats.tx_fifo_urun++;
1599 if (cause & F_RXFIFO_OVERFLOW)
1600 mac->stats.rx_fifo_ovfl++;
1601 if (cause & V_SERDES_LOS(M_SERDES_LOS))
1602 mac->stats.serdes_signal_loss++;
1603 if (cause & F_XAUIPCSCTCERR)
1604 mac->stats.xaui_pcs_ctc_err++;
1605 if (cause & F_XAUIPCSALIGNCHANGE)
1606 mac->stats.xaui_pcs_align_change++;
1607
1608 t3_write_reg(adap, A_XGM_INT_CAUSE + mac->offset, cause);
1609 if (cause & XGM_INTR_FATAL)
1610 t3_fatal_err(adap);
1611 return cause != 0;
1612}
1613
1614/*
1615 * Interrupt handler for PHY events.
1616 */
1617int t3_phy_intr_handler(struct adapter *adapter)
1618{
Divy Le Ray1ca03cb2007-04-17 11:06:36 -07001619 u32 mask, gpi = adapter_info(adapter)->gpio_intr;
Divy Le Ray4d22de32007-01-18 22:04:14 -05001620 u32 i, cause = t3_read_reg(adapter, A_T3DBG_INT_CAUSE);
1621
1622 for_each_port(adapter, i) {
Divy Le Ray1ca03cb2007-04-17 11:06:36 -07001623 struct port_info *p = adap2pinfo(adapter, i);
1624
1625 mask = gpi - (gpi & (gpi - 1));
1626 gpi -= mask;
1627
1628 if (!(p->port_type->caps & SUPPORTED_IRQ))
1629 continue;
1630
1631 if (cause & mask) {
1632 int phy_cause = p->phy.ops->intr_handler(&p->phy);
Divy Le Ray4d22de32007-01-18 22:04:14 -05001633
1634 if (phy_cause & cphy_cause_link_change)
1635 t3_link_changed(adapter, i);
1636 if (phy_cause & cphy_cause_fifo_error)
Divy Le Ray1ca03cb2007-04-17 11:06:36 -07001637 p->phy.fifo_errors++;
Divy Le Ray4d22de32007-01-18 22:04:14 -05001638 }
1639 }
1640
1641 t3_write_reg(adapter, A_T3DBG_INT_CAUSE, cause);
1642 return 0;
1643}
1644
1645/*
1646 * T3 slow path (non-data) interrupt handler.
1647 */
1648int t3_slow_intr_handler(struct adapter *adapter)
1649{
1650 u32 cause = t3_read_reg(adapter, A_PL_INT_CAUSE0);
1651
1652 cause &= adapter->slow_intr_mask;
1653 if (!cause)
1654 return 0;
1655 if (cause & F_PCIM0) {
1656 if (is_pcie(adapter))
1657 pcie_intr_handler(adapter);
1658 else
1659 pci_intr_handler(adapter);
1660 }
1661 if (cause & F_SGE3)
1662 t3_sge_err_intr_handler(adapter);
1663 if (cause & F_MC7_PMRX)
1664 mc7_intr_handler(&adapter->pmrx);
1665 if (cause & F_MC7_PMTX)
1666 mc7_intr_handler(&adapter->pmtx);
1667 if (cause & F_MC7_CM)
1668 mc7_intr_handler(&adapter->cm);
1669 if (cause & F_CIM)
1670 cim_intr_handler(adapter);
1671 if (cause & F_TP1)
1672 tp_intr_handler(adapter);
1673 if (cause & F_ULP2_RX)
1674 ulprx_intr_handler(adapter);
1675 if (cause & F_ULP2_TX)
1676 ulptx_intr_handler(adapter);
1677 if (cause & F_PM1_RX)
1678 pmrx_intr_handler(adapter);
1679 if (cause & F_PM1_TX)
1680 pmtx_intr_handler(adapter);
1681 if (cause & F_CPL_SWITCH)
1682 cplsw_intr_handler(adapter);
1683 if (cause & F_MPS0)
1684 mps_intr_handler(adapter);
1685 if (cause & F_MC5A)
1686 t3_mc5_intr_handler(&adapter->mc5);
1687 if (cause & F_XGMAC0_0)
1688 mac_intr_handler(adapter, 0);
1689 if (cause & F_XGMAC0_1)
1690 mac_intr_handler(adapter, 1);
1691 if (cause & F_T3DBG)
1692 t3_os_ext_intr_handler(adapter);
1693
1694 /* Clear the interrupts just processed. */
1695 t3_write_reg(adapter, A_PL_INT_CAUSE0, cause);
1696 t3_read_reg(adapter, A_PL_INT_CAUSE0); /* flush */
1697 return 1;
1698}
1699
1700/**
1701 * t3_intr_enable - enable interrupts
1702 * @adapter: the adapter whose interrupts should be enabled
1703 *
1704 * Enable interrupts by setting the interrupt enable registers of the
1705 * various HW modules and then enabling the top-level interrupt
1706 * concentrator.
1707 */
1708void t3_intr_enable(struct adapter *adapter)
1709{
1710 static const struct addr_val_pair intr_en_avp[] = {
1711 {A_SG_INT_ENABLE, SGE_INTR_MASK},
1712 {A_MC7_INT_ENABLE, MC7_INTR_MASK},
1713 {A_MC7_INT_ENABLE - MC7_PMRX_BASE_ADDR + MC7_PMTX_BASE_ADDR,
1714 MC7_INTR_MASK},
1715 {A_MC7_INT_ENABLE - MC7_PMRX_BASE_ADDR + MC7_CM_BASE_ADDR,
1716 MC7_INTR_MASK},
1717 {A_MC5_DB_INT_ENABLE, MC5_INTR_MASK},
1718 {A_ULPRX_INT_ENABLE, ULPRX_INTR_MASK},
1719 {A_TP_INT_ENABLE, 0x3bfffff},
1720 {A_PM1_TX_INT_ENABLE, PMTX_INTR_MASK},
1721 {A_PM1_RX_INT_ENABLE, PMRX_INTR_MASK},
1722 {A_CIM_HOST_INT_ENABLE, CIM_INTR_MASK},
1723 {A_MPS_INT_ENABLE, MPS_INTR_MASK},
1724 };
1725
1726 adapter->slow_intr_mask = PL_INTR_MASK;
1727
1728 t3_write_regs(adapter, intr_en_avp, ARRAY_SIZE(intr_en_avp), 0);
1729
1730 if (adapter->params.rev > 0) {
1731 t3_write_reg(adapter, A_CPL_INTR_ENABLE,
1732 CPLSW_INTR_MASK | F_CIM_OVFL_ERROR);
1733 t3_write_reg(adapter, A_ULPTX_INT_ENABLE,
1734 ULPTX_INTR_MASK | F_PBL_BOUND_ERR_CH0 |
1735 F_PBL_BOUND_ERR_CH1);
1736 } else {
1737 t3_write_reg(adapter, A_CPL_INTR_ENABLE, CPLSW_INTR_MASK);
1738 t3_write_reg(adapter, A_ULPTX_INT_ENABLE, ULPTX_INTR_MASK);
1739 }
1740
1741 t3_write_reg(adapter, A_T3DBG_GPIO_ACT_LOW,
1742 adapter_info(adapter)->gpio_intr);
1743 t3_write_reg(adapter, A_T3DBG_INT_ENABLE,
1744 adapter_info(adapter)->gpio_intr);
1745 if (is_pcie(adapter))
1746 t3_write_reg(adapter, A_PCIE_INT_ENABLE, PCIE_INTR_MASK);
1747 else
1748 t3_write_reg(adapter, A_PCIX_INT_ENABLE, PCIX_INTR_MASK);
1749 t3_write_reg(adapter, A_PL_INT_ENABLE0, adapter->slow_intr_mask);
1750 t3_read_reg(adapter, A_PL_INT_ENABLE0); /* flush */
1751}
1752
1753/**
1754 * t3_intr_disable - disable a card's interrupts
1755 * @adapter: the adapter whose interrupts should be disabled
1756 *
1757 * Disable interrupts. We only disable the top-level interrupt
1758 * concentrator and the SGE data interrupts.
1759 */
1760void t3_intr_disable(struct adapter *adapter)
1761{
1762 t3_write_reg(adapter, A_PL_INT_ENABLE0, 0);
1763 t3_read_reg(adapter, A_PL_INT_ENABLE0); /* flush */
1764 adapter->slow_intr_mask = 0;
1765}
1766
1767/**
1768 * t3_intr_clear - clear all interrupts
1769 * @adapter: the adapter whose interrupts should be cleared
1770 *
1771 * Clears all interrupts.
1772 */
1773void t3_intr_clear(struct adapter *adapter)
1774{
1775 static const unsigned int cause_reg_addr[] = {
1776 A_SG_INT_CAUSE,
1777 A_SG_RSPQ_FL_STATUS,
1778 A_PCIX_INT_CAUSE,
1779 A_MC7_INT_CAUSE,
1780 A_MC7_INT_CAUSE - MC7_PMRX_BASE_ADDR + MC7_PMTX_BASE_ADDR,
1781 A_MC7_INT_CAUSE - MC7_PMRX_BASE_ADDR + MC7_CM_BASE_ADDR,
1782 A_CIM_HOST_INT_CAUSE,
1783 A_TP_INT_CAUSE,
1784 A_MC5_DB_INT_CAUSE,
1785 A_ULPRX_INT_CAUSE,
1786 A_ULPTX_INT_CAUSE,
1787 A_CPL_INTR_CAUSE,
1788 A_PM1_TX_INT_CAUSE,
1789 A_PM1_RX_INT_CAUSE,
1790 A_MPS_INT_CAUSE,
1791 A_T3DBG_INT_CAUSE,
1792 };
1793 unsigned int i;
1794
1795 /* Clear PHY and MAC interrupts for each port. */
1796 for_each_port(adapter, i)
1797 t3_port_intr_clear(adapter, i);
1798
1799 for (i = 0; i < ARRAY_SIZE(cause_reg_addr); ++i)
1800 t3_write_reg(adapter, cause_reg_addr[i], 0xffffffff);
1801
1802 t3_write_reg(adapter, A_PL_INT_CAUSE0, 0xffffffff);
1803 t3_read_reg(adapter, A_PL_INT_CAUSE0); /* flush */
1804}
1805
1806/**
1807 * t3_port_intr_enable - enable port-specific interrupts
1808 * @adapter: associated adapter
1809 * @idx: index of port whose interrupts should be enabled
1810 *
1811 * Enable port-specific (i.e., MAC and PHY) interrupts for the given
1812 * adapter port.
1813 */
1814void t3_port_intr_enable(struct adapter *adapter, int idx)
1815{
1816 struct cphy *phy = &adap2pinfo(adapter, idx)->phy;
1817
1818 t3_write_reg(adapter, XGM_REG(A_XGM_INT_ENABLE, idx), XGM_INTR_MASK);
1819 t3_read_reg(adapter, XGM_REG(A_XGM_INT_ENABLE, idx)); /* flush */
1820 phy->ops->intr_enable(phy);
1821}
1822
1823/**
1824 * t3_port_intr_disable - disable port-specific interrupts
1825 * @adapter: associated adapter
1826 * @idx: index of port whose interrupts should be disabled
1827 *
1828 * Disable port-specific (i.e., MAC and PHY) interrupts for the given
1829 * adapter port.
1830 */
1831void t3_port_intr_disable(struct adapter *adapter, int idx)
1832{
1833 struct cphy *phy = &adap2pinfo(adapter, idx)->phy;
1834
1835 t3_write_reg(adapter, XGM_REG(A_XGM_INT_ENABLE, idx), 0);
1836 t3_read_reg(adapter, XGM_REG(A_XGM_INT_ENABLE, idx)); /* flush */
1837 phy->ops->intr_disable(phy);
1838}
1839
1840/**
1841 * t3_port_intr_clear - clear port-specific interrupts
1842 * @adapter: associated adapter
1843 * @idx: index of port whose interrupts to clear
1844 *
1845 * Clear port-specific (i.e., MAC and PHY) interrupts for the given
1846 * adapter port.
1847 */
1848void t3_port_intr_clear(struct adapter *adapter, int idx)
1849{
1850 struct cphy *phy = &adap2pinfo(adapter, idx)->phy;
1851
1852 t3_write_reg(adapter, XGM_REG(A_XGM_INT_CAUSE, idx), 0xffffffff);
1853 t3_read_reg(adapter, XGM_REG(A_XGM_INT_CAUSE, idx)); /* flush */
1854 phy->ops->intr_clear(phy);
1855}
1856
1857/**
1858 * t3_sge_write_context - write an SGE context
1859 * @adapter: the adapter
1860 * @id: the context id
1861 * @type: the context type
1862 *
1863 * Program an SGE context with the values already loaded in the
1864 * CONTEXT_DATA? registers.
1865 */
1866static int t3_sge_write_context(struct adapter *adapter, unsigned int id,
1867 unsigned int type)
1868{
1869 t3_write_reg(adapter, A_SG_CONTEXT_MASK0, 0xffffffff);
1870 t3_write_reg(adapter, A_SG_CONTEXT_MASK1, 0xffffffff);
1871 t3_write_reg(adapter, A_SG_CONTEXT_MASK2, 0xffffffff);
1872 t3_write_reg(adapter, A_SG_CONTEXT_MASK3, 0xffffffff);
1873 t3_write_reg(adapter, A_SG_CONTEXT_CMD,
1874 V_CONTEXT_CMD_OPCODE(1) | type | V_CONTEXT(id));
1875 return t3_wait_op_done(adapter, A_SG_CONTEXT_CMD, F_CONTEXT_CMD_BUSY,
1876 0, 5, 1);
1877}
1878
1879/**
1880 * t3_sge_init_ecntxt - initialize an SGE egress context
1881 * @adapter: the adapter to configure
1882 * @id: the context id
1883 * @gts_enable: whether to enable GTS for the context
1884 * @type: the egress context type
1885 * @respq: associated response queue
1886 * @base_addr: base address of queue
1887 * @size: number of queue entries
1888 * @token: uP token
1889 * @gen: initial generation value for the context
1890 * @cidx: consumer pointer
1891 *
1892 * Initialize an SGE egress context and make it ready for use. If the
1893 * platform allows concurrent context operations, the caller is
1894 * responsible for appropriate locking.
1895 */
1896int t3_sge_init_ecntxt(struct adapter *adapter, unsigned int id, int gts_enable,
1897 enum sge_context_type type, int respq, u64 base_addr,
1898 unsigned int size, unsigned int token, int gen,
1899 unsigned int cidx)
1900{
1901 unsigned int credits = type == SGE_CNTXT_OFLD ? 0 : FW_WR_NUM;
1902
1903 if (base_addr & 0xfff) /* must be 4K aligned */
1904 return -EINVAL;
1905 if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY)
1906 return -EBUSY;
1907
1908 base_addr >>= 12;
1909 t3_write_reg(adapter, A_SG_CONTEXT_DATA0, V_EC_INDEX(cidx) |
1910 V_EC_CREDITS(credits) | V_EC_GTS(gts_enable));
1911 t3_write_reg(adapter, A_SG_CONTEXT_DATA1, V_EC_SIZE(size) |
1912 V_EC_BASE_LO(base_addr & 0xffff));
1913 base_addr >>= 16;
1914 t3_write_reg(adapter, A_SG_CONTEXT_DATA2, base_addr);
1915 base_addr >>= 32;
1916 t3_write_reg(adapter, A_SG_CONTEXT_DATA3,
1917 V_EC_BASE_HI(base_addr & 0xf) | V_EC_RESPQ(respq) |
1918 V_EC_TYPE(type) | V_EC_GEN(gen) | V_EC_UP_TOKEN(token) |
1919 F_EC_VALID);
1920 return t3_sge_write_context(adapter, id, F_EGRESS);
1921}
1922
1923/**
1924 * t3_sge_init_flcntxt - initialize an SGE free-buffer list context
1925 * @adapter: the adapter to configure
1926 * @id: the context id
1927 * @gts_enable: whether to enable GTS for the context
1928 * @base_addr: base address of queue
1929 * @size: number of queue entries
1930 * @bsize: size of each buffer for this queue
1931 * @cong_thres: threshold to signal congestion to upstream producers
1932 * @gen: initial generation value for the context
1933 * @cidx: consumer pointer
1934 *
1935 * Initialize an SGE free list context and make it ready for use. The
1936 * caller is responsible for ensuring only one context operation occurs
1937 * at a time.
1938 */
1939int t3_sge_init_flcntxt(struct adapter *adapter, unsigned int id,
1940 int gts_enable, u64 base_addr, unsigned int size,
1941 unsigned int bsize, unsigned int cong_thres, int gen,
1942 unsigned int cidx)
1943{
1944 if (base_addr & 0xfff) /* must be 4K aligned */
1945 return -EINVAL;
1946 if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY)
1947 return -EBUSY;
1948
1949 base_addr >>= 12;
1950 t3_write_reg(adapter, A_SG_CONTEXT_DATA0, base_addr);
1951 base_addr >>= 32;
1952 t3_write_reg(adapter, A_SG_CONTEXT_DATA1,
1953 V_FL_BASE_HI((u32) base_addr) |
1954 V_FL_INDEX_LO(cidx & M_FL_INDEX_LO));
1955 t3_write_reg(adapter, A_SG_CONTEXT_DATA2, V_FL_SIZE(size) |
1956 V_FL_GEN(gen) | V_FL_INDEX_HI(cidx >> 12) |
1957 V_FL_ENTRY_SIZE_LO(bsize & M_FL_ENTRY_SIZE_LO));
1958 t3_write_reg(adapter, A_SG_CONTEXT_DATA3,
1959 V_FL_ENTRY_SIZE_HI(bsize >> (32 - S_FL_ENTRY_SIZE_LO)) |
1960 V_FL_CONG_THRES(cong_thres) | V_FL_GTS(gts_enable));
1961 return t3_sge_write_context(adapter, id, F_FREELIST);
1962}
1963
1964/**
1965 * t3_sge_init_rspcntxt - initialize an SGE response queue context
1966 * @adapter: the adapter to configure
1967 * @id: the context id
1968 * @irq_vec_idx: MSI-X interrupt vector index, 0 if no MSI-X, -1 if no IRQ
1969 * @base_addr: base address of queue
1970 * @size: number of queue entries
1971 * @fl_thres: threshold for selecting the normal or jumbo free list
1972 * @gen: initial generation value for the context
1973 * @cidx: consumer pointer
1974 *
1975 * Initialize an SGE response queue context and make it ready for use.
1976 * The caller is responsible for ensuring only one context operation
1977 * occurs at a time.
1978 */
1979int t3_sge_init_rspcntxt(struct adapter *adapter, unsigned int id,
1980 int irq_vec_idx, u64 base_addr, unsigned int size,
1981 unsigned int fl_thres, int gen, unsigned int cidx)
1982{
1983 unsigned int intr = 0;
1984
1985 if (base_addr & 0xfff) /* must be 4K aligned */
1986 return -EINVAL;
1987 if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY)
1988 return -EBUSY;
1989
1990 base_addr >>= 12;
1991 t3_write_reg(adapter, A_SG_CONTEXT_DATA0, V_CQ_SIZE(size) |
1992 V_CQ_INDEX(cidx));
1993 t3_write_reg(adapter, A_SG_CONTEXT_DATA1, base_addr);
1994 base_addr >>= 32;
1995 if (irq_vec_idx >= 0)
1996 intr = V_RQ_MSI_VEC(irq_vec_idx) | F_RQ_INTR_EN;
1997 t3_write_reg(adapter, A_SG_CONTEXT_DATA2,
1998 V_CQ_BASE_HI((u32) base_addr) | intr | V_RQ_GEN(gen));
1999 t3_write_reg(adapter, A_SG_CONTEXT_DATA3, fl_thres);
2000 return t3_sge_write_context(adapter, id, F_RESPONSEQ);
2001}
2002
2003/**
2004 * t3_sge_init_cqcntxt - initialize an SGE completion queue context
2005 * @adapter: the adapter to configure
2006 * @id: the context id
2007 * @base_addr: base address of queue
2008 * @size: number of queue entries
2009 * @rspq: response queue for async notifications
2010 * @ovfl_mode: CQ overflow mode
2011 * @credits: completion queue credits
2012 * @credit_thres: the credit threshold
2013 *
2014 * Initialize an SGE completion queue context and make it ready for use.
2015 * The caller is responsible for ensuring only one context operation
2016 * occurs at a time.
2017 */
2018int t3_sge_init_cqcntxt(struct adapter *adapter, unsigned int id, u64 base_addr,
2019 unsigned int size, int rspq, int ovfl_mode,
2020 unsigned int credits, unsigned int credit_thres)
2021{
2022 if (base_addr & 0xfff) /* must be 4K aligned */
2023 return -EINVAL;
2024 if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY)
2025 return -EBUSY;
2026
2027 base_addr >>= 12;
2028 t3_write_reg(adapter, A_SG_CONTEXT_DATA0, V_CQ_SIZE(size));
2029 t3_write_reg(adapter, A_SG_CONTEXT_DATA1, base_addr);
2030 base_addr >>= 32;
2031 t3_write_reg(adapter, A_SG_CONTEXT_DATA2,
2032 V_CQ_BASE_HI((u32) base_addr) | V_CQ_RSPQ(rspq) |
2033 V_CQ_GEN(1) | V_CQ_OVERFLOW_MODE(ovfl_mode));
2034 t3_write_reg(adapter, A_SG_CONTEXT_DATA3, V_CQ_CREDITS(credits) |
2035 V_CQ_CREDIT_THRES(credit_thres));
2036 return t3_sge_write_context(adapter, id, F_CQ);
2037}
2038
2039/**
2040 * t3_sge_enable_ecntxt - enable/disable an SGE egress context
2041 * @adapter: the adapter
2042 * @id: the egress context id
2043 * @enable: enable (1) or disable (0) the context
2044 *
2045 * Enable or disable an SGE egress context. The caller is responsible for
2046 * ensuring only one context operation occurs at a time.
2047 */
2048int t3_sge_enable_ecntxt(struct adapter *adapter, unsigned int id, int enable)
2049{
2050 if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY)
2051 return -EBUSY;
2052
2053 t3_write_reg(adapter, A_SG_CONTEXT_MASK0, 0);
2054 t3_write_reg(adapter, A_SG_CONTEXT_MASK1, 0);
2055 t3_write_reg(adapter, A_SG_CONTEXT_MASK2, 0);
2056 t3_write_reg(adapter, A_SG_CONTEXT_MASK3, F_EC_VALID);
2057 t3_write_reg(adapter, A_SG_CONTEXT_DATA3, V_EC_VALID(enable));
2058 t3_write_reg(adapter, A_SG_CONTEXT_CMD,
2059 V_CONTEXT_CMD_OPCODE(1) | F_EGRESS | V_CONTEXT(id));
2060 return t3_wait_op_done(adapter, A_SG_CONTEXT_CMD, F_CONTEXT_CMD_BUSY,
2061 0, 5, 1);
2062}
2063
2064/**
2065 * t3_sge_disable_fl - disable an SGE free-buffer list
2066 * @adapter: the adapter
2067 * @id: the free list context id
2068 *
2069 * Disable an SGE free-buffer list. The caller is responsible for
2070 * ensuring only one context operation occurs at a time.
2071 */
2072int t3_sge_disable_fl(struct adapter *adapter, unsigned int id)
2073{
2074 if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY)
2075 return -EBUSY;
2076
2077 t3_write_reg(adapter, A_SG_CONTEXT_MASK0, 0);
2078 t3_write_reg(adapter, A_SG_CONTEXT_MASK1, 0);
2079 t3_write_reg(adapter, A_SG_CONTEXT_MASK2, V_FL_SIZE(M_FL_SIZE));
2080 t3_write_reg(adapter, A_SG_CONTEXT_MASK3, 0);
2081 t3_write_reg(adapter, A_SG_CONTEXT_DATA2, 0);
2082 t3_write_reg(adapter, A_SG_CONTEXT_CMD,
2083 V_CONTEXT_CMD_OPCODE(1) | F_FREELIST | V_CONTEXT(id));
2084 return t3_wait_op_done(adapter, A_SG_CONTEXT_CMD, F_CONTEXT_CMD_BUSY,
2085 0, 5, 1);
2086}
2087
2088/**
2089 * t3_sge_disable_rspcntxt - disable an SGE response queue
2090 * @adapter: the adapter
2091 * @id: the response queue context id
2092 *
2093 * Disable an SGE response queue. The caller is responsible for
2094 * ensuring only one context operation occurs at a time.
2095 */
2096int t3_sge_disable_rspcntxt(struct adapter *adapter, unsigned int id)
2097{
2098 if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY)
2099 return -EBUSY;
2100
2101 t3_write_reg(adapter, A_SG_CONTEXT_MASK0, V_CQ_SIZE(M_CQ_SIZE));
2102 t3_write_reg(adapter, A_SG_CONTEXT_MASK1, 0);
2103 t3_write_reg(adapter, A_SG_CONTEXT_MASK2, 0);
2104 t3_write_reg(adapter, A_SG_CONTEXT_MASK3, 0);
2105 t3_write_reg(adapter, A_SG_CONTEXT_DATA0, 0);
2106 t3_write_reg(adapter, A_SG_CONTEXT_CMD,
2107 V_CONTEXT_CMD_OPCODE(1) | F_RESPONSEQ | V_CONTEXT(id));
2108 return t3_wait_op_done(adapter, A_SG_CONTEXT_CMD, F_CONTEXT_CMD_BUSY,
2109 0, 5, 1);
2110}
2111
2112/**
2113 * t3_sge_disable_cqcntxt - disable an SGE completion queue
2114 * @adapter: the adapter
2115 * @id: the completion queue context id
2116 *
2117 * Disable an SGE completion queue. The caller is responsible for
2118 * ensuring only one context operation occurs at a time.
2119 */
2120int t3_sge_disable_cqcntxt(struct adapter *adapter, unsigned int id)
2121{
2122 if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY)
2123 return -EBUSY;
2124
2125 t3_write_reg(adapter, A_SG_CONTEXT_MASK0, V_CQ_SIZE(M_CQ_SIZE));
2126 t3_write_reg(adapter, A_SG_CONTEXT_MASK1, 0);
2127 t3_write_reg(adapter, A_SG_CONTEXT_MASK2, 0);
2128 t3_write_reg(adapter, A_SG_CONTEXT_MASK3, 0);
2129 t3_write_reg(adapter, A_SG_CONTEXT_DATA0, 0);
2130 t3_write_reg(adapter, A_SG_CONTEXT_CMD,
2131 V_CONTEXT_CMD_OPCODE(1) | F_CQ | V_CONTEXT(id));
2132 return t3_wait_op_done(adapter, A_SG_CONTEXT_CMD, F_CONTEXT_CMD_BUSY,
2133 0, 5, 1);
2134}
2135
2136/**
2137 * t3_sge_cqcntxt_op - perform an operation on a completion queue context
2138 * @adapter: the adapter
2139 * @id: the context id
2140 * @op: the operation to perform
2141 *
2142 * Perform the selected operation on an SGE completion queue context.
2143 * The caller is responsible for ensuring only one context operation
2144 * occurs at a time.
2145 */
2146int t3_sge_cqcntxt_op(struct adapter *adapter, unsigned int id, unsigned int op,
2147 unsigned int credits)
2148{
2149 u32 val;
2150
2151 if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY)
2152 return -EBUSY;
2153
2154 t3_write_reg(adapter, A_SG_CONTEXT_DATA0, credits << 16);
2155 t3_write_reg(adapter, A_SG_CONTEXT_CMD, V_CONTEXT_CMD_OPCODE(op) |
2156 V_CONTEXT(id) | F_CQ);
2157 if (t3_wait_op_done_val(adapter, A_SG_CONTEXT_CMD, F_CONTEXT_CMD_BUSY,
2158 0, 5, 1, &val))
2159 return -EIO;
2160
2161 if (op >= 2 && op < 7) {
2162 if (adapter->params.rev > 0)
2163 return G_CQ_INDEX(val);
2164
2165 t3_write_reg(adapter, A_SG_CONTEXT_CMD,
2166 V_CONTEXT_CMD_OPCODE(0) | F_CQ | V_CONTEXT(id));
2167 if (t3_wait_op_done(adapter, A_SG_CONTEXT_CMD,
2168 F_CONTEXT_CMD_BUSY, 0, 5, 1))
2169 return -EIO;
2170 return G_CQ_INDEX(t3_read_reg(adapter, A_SG_CONTEXT_DATA0));
2171 }
2172 return 0;
2173}
2174
2175/**
2176 * t3_sge_read_context - read an SGE context
2177 * @type: the context type
2178 * @adapter: the adapter
2179 * @id: the context id
2180 * @data: holds the retrieved context
2181 *
2182 * Read an SGE egress context. The caller is responsible for ensuring
2183 * only one context operation occurs at a time.
2184 */
2185static int t3_sge_read_context(unsigned int type, struct adapter *adapter,
2186 unsigned int id, u32 data[4])
2187{
2188 if (t3_read_reg(adapter, A_SG_CONTEXT_CMD) & F_CONTEXT_CMD_BUSY)
2189 return -EBUSY;
2190
2191 t3_write_reg(adapter, A_SG_CONTEXT_CMD,
2192 V_CONTEXT_CMD_OPCODE(0) | type | V_CONTEXT(id));
2193 if (t3_wait_op_done(adapter, A_SG_CONTEXT_CMD, F_CONTEXT_CMD_BUSY, 0,
2194 5, 1))
2195 return -EIO;
2196 data[0] = t3_read_reg(adapter, A_SG_CONTEXT_DATA0);
2197 data[1] = t3_read_reg(adapter, A_SG_CONTEXT_DATA1);
2198 data[2] = t3_read_reg(adapter, A_SG_CONTEXT_DATA2);
2199 data[3] = t3_read_reg(adapter, A_SG_CONTEXT_DATA3);
2200 return 0;
2201}
2202
2203/**
2204 * t3_sge_read_ecntxt - read an SGE egress context
2205 * @adapter: the adapter
2206 * @id: the context id
2207 * @data: holds the retrieved context
2208 *
2209 * Read an SGE egress context. The caller is responsible for ensuring
2210 * only one context operation occurs at a time.
2211 */
2212int t3_sge_read_ecntxt(struct adapter *adapter, unsigned int id, u32 data[4])
2213{
2214 if (id >= 65536)
2215 return -EINVAL;
2216 return t3_sge_read_context(F_EGRESS, adapter, id, data);
2217}
2218
2219/**
2220 * t3_sge_read_cq - read an SGE CQ context
2221 * @adapter: the adapter
2222 * @id: the context id
2223 * @data: holds the retrieved context
2224 *
2225 * Read an SGE CQ context. The caller is responsible for ensuring
2226 * only one context operation occurs at a time.
2227 */
2228int t3_sge_read_cq(struct adapter *adapter, unsigned int id, u32 data[4])
2229{
2230 if (id >= 65536)
2231 return -EINVAL;
2232 return t3_sge_read_context(F_CQ, adapter, id, data);
2233}
2234
2235/**
2236 * t3_sge_read_fl - read an SGE free-list context
2237 * @adapter: the adapter
2238 * @id: the context id
2239 * @data: holds the retrieved context
2240 *
2241 * Read an SGE free-list context. The caller is responsible for ensuring
2242 * only one context operation occurs at a time.
2243 */
2244int t3_sge_read_fl(struct adapter *adapter, unsigned int id, u32 data[4])
2245{
2246 if (id >= SGE_QSETS * 2)
2247 return -EINVAL;
2248 return t3_sge_read_context(F_FREELIST, adapter, id, data);
2249}
2250
2251/**
2252 * t3_sge_read_rspq - read an SGE response queue context
2253 * @adapter: the adapter
2254 * @id: the context id
2255 * @data: holds the retrieved context
2256 *
2257 * Read an SGE response queue context. The caller is responsible for
2258 * ensuring only one context operation occurs at a time.
2259 */
2260int t3_sge_read_rspq(struct adapter *adapter, unsigned int id, u32 data[4])
2261{
2262 if (id >= SGE_QSETS)
2263 return -EINVAL;
2264 return t3_sge_read_context(F_RESPONSEQ, adapter, id, data);
2265}
2266
2267/**
2268 * t3_config_rss - configure Rx packet steering
2269 * @adapter: the adapter
2270 * @rss_config: RSS settings (written to TP_RSS_CONFIG)
2271 * @cpus: values for the CPU lookup table (0xff terminated)
2272 * @rspq: values for the response queue lookup table (0xffff terminated)
2273 *
2274 * Programs the receive packet steering logic. @cpus and @rspq provide
2275 * the values for the CPU and response queue lookup tables. If they
2276 * provide fewer values than the size of the tables the supplied values
2277 * are used repeatedly until the tables are fully populated.
2278 */
2279void t3_config_rss(struct adapter *adapter, unsigned int rss_config,
2280 const u8 * cpus, const u16 *rspq)
2281{
2282 int i, j, cpu_idx = 0, q_idx = 0;
2283
2284 if (cpus)
2285 for (i = 0; i < RSS_TABLE_SIZE; ++i) {
2286 u32 val = i << 16;
2287
2288 for (j = 0; j < 2; ++j) {
2289 val |= (cpus[cpu_idx++] & 0x3f) << (8 * j);
2290 if (cpus[cpu_idx] == 0xff)
2291 cpu_idx = 0;
2292 }
2293 t3_write_reg(adapter, A_TP_RSS_LKP_TABLE, val);
2294 }
2295
2296 if (rspq)
2297 for (i = 0; i < RSS_TABLE_SIZE; ++i) {
2298 t3_write_reg(adapter, A_TP_RSS_MAP_TABLE,
2299 (i << 16) | rspq[q_idx++]);
2300 if (rspq[q_idx] == 0xffff)
2301 q_idx = 0;
2302 }
2303
2304 t3_write_reg(adapter, A_TP_RSS_CONFIG, rss_config);
2305}
2306
2307/**
2308 * t3_read_rss - read the contents of the RSS tables
2309 * @adapter: the adapter
2310 * @lkup: holds the contents of the RSS lookup table
2311 * @map: holds the contents of the RSS map table
2312 *
2313 * Reads the contents of the receive packet steering tables.
2314 */
2315int t3_read_rss(struct adapter *adapter, u8 * lkup, u16 *map)
2316{
2317 int i;
2318 u32 val;
2319
2320 if (lkup)
2321 for (i = 0; i < RSS_TABLE_SIZE; ++i) {
2322 t3_write_reg(adapter, A_TP_RSS_LKP_TABLE,
2323 0xffff0000 | i);
2324 val = t3_read_reg(adapter, A_TP_RSS_LKP_TABLE);
2325 if (!(val & 0x80000000))
2326 return -EAGAIN;
2327 *lkup++ = val;
2328 *lkup++ = (val >> 8);
2329 }
2330
2331 if (map)
2332 for (i = 0; i < RSS_TABLE_SIZE; ++i) {
2333 t3_write_reg(adapter, A_TP_RSS_MAP_TABLE,
2334 0xffff0000 | i);
2335 val = t3_read_reg(adapter, A_TP_RSS_MAP_TABLE);
2336 if (!(val & 0x80000000))
2337 return -EAGAIN;
2338 *map++ = val;
2339 }
2340 return 0;
2341}
2342
2343/**
2344 * t3_tp_set_offload_mode - put TP in NIC/offload mode
2345 * @adap: the adapter
2346 * @enable: 1 to select offload mode, 0 for regular NIC
2347 *
2348 * Switches TP to NIC/offload mode.
2349 */
2350void t3_tp_set_offload_mode(struct adapter *adap, int enable)
2351{
2352 if (is_offload(adap) || !enable)
2353 t3_set_reg_field(adap, A_TP_IN_CONFIG, F_NICMODE,
2354 V_NICMODE(!enable));
2355}
2356
2357/**
2358 * pm_num_pages - calculate the number of pages of the payload memory
2359 * @mem_size: the size of the payload memory
2360 * @pg_size: the size of each payload memory page
2361 *
2362 * Calculate the number of pages, each of the given size, that fit in a
2363 * memory of the specified size, respecting the HW requirement that the
2364 * number of pages must be a multiple of 24.
2365 */
2366static inline unsigned int pm_num_pages(unsigned int mem_size,
2367 unsigned int pg_size)
2368{
2369 unsigned int n = mem_size / pg_size;
2370
2371 return n - n % 24;
2372}
2373
2374#define mem_region(adap, start, size, reg) \
2375 t3_write_reg((adap), A_ ## reg, (start)); \
2376 start += size
2377
2378/*
2379 * partition_mem - partition memory and configure TP memory settings
2380 * @adap: the adapter
2381 * @p: the TP parameters
2382 *
2383 * Partitions context and payload memory and configures TP's memory
2384 * registers.
2385 */
2386static void partition_mem(struct adapter *adap, const struct tp_params *p)
2387{
2388 unsigned int m, pstructs, tids = t3_mc5_size(&adap->mc5);
2389 unsigned int timers = 0, timers_shift = 22;
2390
2391 if (adap->params.rev > 0) {
2392 if (tids <= 16 * 1024) {
2393 timers = 1;
2394 timers_shift = 16;
2395 } else if (tids <= 64 * 1024) {
2396 timers = 2;
2397 timers_shift = 18;
2398 } else if (tids <= 256 * 1024) {
2399 timers = 3;
2400 timers_shift = 20;
2401 }
2402 }
2403
2404 t3_write_reg(adap, A_TP_PMM_SIZE,
2405 p->chan_rx_size | (p->chan_tx_size >> 16));
2406
2407 t3_write_reg(adap, A_TP_PMM_TX_BASE, 0);
2408 t3_write_reg(adap, A_TP_PMM_TX_PAGE_SIZE, p->tx_pg_size);
2409 t3_write_reg(adap, A_TP_PMM_TX_MAX_PAGE, p->tx_num_pgs);
2410 t3_set_reg_field(adap, A_TP_PARA_REG3, V_TXDATAACKIDX(M_TXDATAACKIDX),
2411 V_TXDATAACKIDX(fls(p->tx_pg_size) - 12));
2412
2413 t3_write_reg(adap, A_TP_PMM_RX_BASE, 0);
2414 t3_write_reg(adap, A_TP_PMM_RX_PAGE_SIZE, p->rx_pg_size);
2415 t3_write_reg(adap, A_TP_PMM_RX_MAX_PAGE, p->rx_num_pgs);
2416
2417 pstructs = p->rx_num_pgs + p->tx_num_pgs;
2418 /* Add a bit of headroom and make multiple of 24 */
2419 pstructs += 48;
2420 pstructs -= pstructs % 24;
2421 t3_write_reg(adap, A_TP_CMM_MM_MAX_PSTRUCT, pstructs);
2422
2423 m = tids * TCB_SIZE;
2424 mem_region(adap, m, (64 << 10) * 64, SG_EGR_CNTX_BADDR);
2425 mem_region(adap, m, (64 << 10) * 64, SG_CQ_CONTEXT_BADDR);
2426 t3_write_reg(adap, A_TP_CMM_TIMER_BASE, V_CMTIMERMAXNUM(timers) | m);
2427 m += ((p->ntimer_qs - 1) << timers_shift) + (1 << 22);
2428 mem_region(adap, m, pstructs * 64, TP_CMM_MM_BASE);
2429 mem_region(adap, m, 64 * (pstructs / 24), TP_CMM_MM_PS_FLST_BASE);
2430 mem_region(adap, m, 64 * (p->rx_num_pgs / 24), TP_CMM_MM_RX_FLST_BASE);
2431 mem_region(adap, m, 64 * (p->tx_num_pgs / 24), TP_CMM_MM_TX_FLST_BASE);
2432
2433 m = (m + 4095) & ~0xfff;
2434 t3_write_reg(adap, A_CIM_SDRAM_BASE_ADDR, m);
2435 t3_write_reg(adap, A_CIM_SDRAM_ADDR_SIZE, p->cm_size - m);
2436
2437 tids = (p->cm_size - m - (3 << 20)) / 3072 - 32;
2438 m = t3_mc5_size(&adap->mc5) - adap->params.mc5.nservers -
2439 adap->params.mc5.nfilters - adap->params.mc5.nroutes;
2440 if (tids < m)
2441 adap->params.mc5.nservers += m - tids;
2442}
2443
2444static inline void tp_wr_indirect(struct adapter *adap, unsigned int addr,
2445 u32 val)
2446{
2447 t3_write_reg(adap, A_TP_PIO_ADDR, addr);
2448 t3_write_reg(adap, A_TP_PIO_DATA, val);
2449}
2450
2451static void tp_config(struct adapter *adap, const struct tp_params *p)
2452{
Divy Le Ray4d22de32007-01-18 22:04:14 -05002453 t3_write_reg(adap, A_TP_GLOBAL_CONFIG, F_TXPACINGENABLE | F_PATHMTU |
2454 F_IPCHECKSUMOFFLOAD | F_UDPCHECKSUMOFFLOAD |
2455 F_TCPCHECKSUMOFFLOAD | V_IPTTL(64));
2456 t3_write_reg(adap, A_TP_TCP_OPTIONS, V_MTUDEFAULT(576) |
2457 F_MTUENABLE | V_WINDOWSCALEMODE(1) |
Divy Le Ray8a9fab22007-05-30 21:10:52 -07002458 V_TIMESTAMPSMODE(0) | V_SACKMODE(1) | V_SACKRX(1));
Divy Le Ray4d22de32007-01-18 22:04:14 -05002459 t3_write_reg(adap, A_TP_DACK_CONFIG, V_AUTOSTATE3(1) |
2460 V_AUTOSTATE2(1) | V_AUTOSTATE1(0) |
2461 V_BYTETHRESHOLD(16384) | V_MSSTHRESHOLD(2) |
2462 F_AUTOCAREFUL | F_AUTOENABLE | V_DACK_MODE(1));
2463 t3_set_reg_field(adap, A_TP_IN_CONFIG, F_IPV6ENABLE | F_NICMODE,
2464 F_IPV6ENABLE | F_NICMODE);
2465 t3_write_reg(adap, A_TP_TX_RESOURCE_LIMIT, 0x18141814);
2466 t3_write_reg(adap, A_TP_PARA_REG4, 0x5050105);
Divy Le Ray8a9fab22007-05-30 21:10:52 -07002467 t3_set_reg_field(adap, A_TP_PARA_REG6, 0,
2468 adap->params.rev > 0 ? F_ENABLEESND :
2469 F_T3A_ENABLEESND);
Divy Le Ray4d22de32007-01-18 22:04:14 -05002470
Divy Le Ray3b1d3072007-01-30 19:44:07 -08002471 t3_set_reg_field(adap, A_TP_PC_CONFIG,
Divy Le Ray8a9fab22007-05-30 21:10:52 -07002472 F_ENABLEEPCMDAFULL,
2473 F_ENABLEOCSPIFULL |F_TXDEFERENABLE | F_HEARBEATDACK |
2474 F_TXCONGESTIONMODE | F_RXCONGESTIONMODE);
Divy Le Ray3b1d3072007-01-30 19:44:07 -08002475 t3_set_reg_field(adap, A_TP_PC_CONFIG2, F_CHDRAFULL, 0);
Divy Le Ray8a9fab22007-05-30 21:10:52 -07002476 t3_write_reg(adap, A_TP_PROXY_FLOW_CNTL, 1080);
2477 t3_write_reg(adap, A_TP_PROXY_FLOW_CNTL, 1000);
2478
Divy Le Ray4d22de32007-01-18 22:04:14 -05002479 if (adap->params.rev > 0) {
2480 tp_wr_indirect(adap, A_TP_EGRESS_CONFIG, F_REWRITEFORCETOSIZE);
2481 t3_set_reg_field(adap, A_TP_PARA_REG3, F_TXPACEAUTO,
2482 F_TXPACEAUTO);
2483 t3_set_reg_field(adap, A_TP_PC_CONFIG, F_LOCKTID, F_LOCKTID);
2484 t3_set_reg_field(adap, A_TP_PARA_REG3, 0, F_TXPACEAUTOSTRICT);
2485 } else
2486 t3_set_reg_field(adap, A_TP_PARA_REG3, 0, F_TXPACEFIXED);
2487
Divy Le Ray8a9fab22007-05-30 21:10:52 -07002488 t3_write_reg(adap, A_TP_TX_MOD_QUEUE_WEIGHT1, 0);
2489 t3_write_reg(adap, A_TP_TX_MOD_QUEUE_WEIGHT0, 0);
2490 t3_write_reg(adap, A_TP_MOD_CHANNEL_WEIGHT, 0);
2491 t3_write_reg(adap, A_TP_MOD_RATE_LIMIT, 0xf2200000);
Divy Le Ray4d22de32007-01-18 22:04:14 -05002492}
2493
2494/* Desired TP timer resolution in usec */
2495#define TP_TMR_RES 50
2496
2497/* TCP timer values in ms */
2498#define TP_DACK_TIMER 50
2499#define TP_RTO_MIN 250
2500
2501/**
2502 * tp_set_timers - set TP timing parameters
2503 * @adap: the adapter to set
2504 * @core_clk: the core clock frequency in Hz
2505 *
2506 * Set TP's timing parameters, such as the various timer resolutions and
2507 * the TCP timer values.
2508 */
2509static void tp_set_timers(struct adapter *adap, unsigned int core_clk)
2510{
2511 unsigned int tre = fls(core_clk / (1000000 / TP_TMR_RES)) - 1;
2512 unsigned int dack_re = fls(core_clk / 5000) - 1; /* 200us */
2513 unsigned int tstamp_re = fls(core_clk / 1000); /* 1ms, at least */
2514 unsigned int tps = core_clk >> tre;
2515
2516 t3_write_reg(adap, A_TP_TIMER_RESOLUTION, V_TIMERRESOLUTION(tre) |
2517 V_DELAYEDACKRESOLUTION(dack_re) |
2518 V_TIMESTAMPRESOLUTION(tstamp_re));
2519 t3_write_reg(adap, A_TP_DACK_TIMER,
2520 (core_clk >> dack_re) / (1000 / TP_DACK_TIMER));
2521 t3_write_reg(adap, A_TP_TCP_BACKOFF_REG0, 0x3020100);
2522 t3_write_reg(adap, A_TP_TCP_BACKOFF_REG1, 0x7060504);
2523 t3_write_reg(adap, A_TP_TCP_BACKOFF_REG2, 0xb0a0908);
2524 t3_write_reg(adap, A_TP_TCP_BACKOFF_REG3, 0xf0e0d0c);
2525 t3_write_reg(adap, A_TP_SHIFT_CNT, V_SYNSHIFTMAX(6) |
2526 V_RXTSHIFTMAXR1(4) | V_RXTSHIFTMAXR2(15) |
2527 V_PERSHIFTBACKOFFMAX(8) | V_PERSHIFTMAX(8) |
2528 V_KEEPALIVEMAX(9));
2529
2530#define SECONDS * tps
2531
2532 t3_write_reg(adap, A_TP_MSL, adap->params.rev > 0 ? 0 : 2 SECONDS);
2533 t3_write_reg(adap, A_TP_RXT_MIN, tps / (1000 / TP_RTO_MIN));
2534 t3_write_reg(adap, A_TP_RXT_MAX, 64 SECONDS);
2535 t3_write_reg(adap, A_TP_PERS_MIN, 5 SECONDS);
2536 t3_write_reg(adap, A_TP_PERS_MAX, 64 SECONDS);
2537 t3_write_reg(adap, A_TP_KEEP_IDLE, 7200 SECONDS);
2538 t3_write_reg(adap, A_TP_KEEP_INTVL, 75 SECONDS);
2539 t3_write_reg(adap, A_TP_INIT_SRTT, 3 SECONDS);
2540 t3_write_reg(adap, A_TP_FINWAIT2_TIMER, 600 SECONDS);
2541
2542#undef SECONDS
2543}
2544
2545/**
2546 * t3_tp_set_coalescing_size - set receive coalescing size
2547 * @adap: the adapter
2548 * @size: the receive coalescing size
2549 * @psh: whether a set PSH bit should deliver coalesced data
2550 *
2551 * Set the receive coalescing size and PSH bit handling.
2552 */
2553int t3_tp_set_coalescing_size(struct adapter *adap, unsigned int size, int psh)
2554{
2555 u32 val;
2556
2557 if (size > MAX_RX_COALESCING_LEN)
2558 return -EINVAL;
2559
2560 val = t3_read_reg(adap, A_TP_PARA_REG3);
2561 val &= ~(F_RXCOALESCEENABLE | F_RXCOALESCEPSHEN);
2562
2563 if (size) {
2564 val |= F_RXCOALESCEENABLE;
2565 if (psh)
2566 val |= F_RXCOALESCEPSHEN;
Divy Le Ray8a9fab22007-05-30 21:10:52 -07002567 size = min(MAX_RX_COALESCING_LEN, size);
Divy Le Ray4d22de32007-01-18 22:04:14 -05002568 t3_write_reg(adap, A_TP_PARA_REG2, V_RXCOALESCESIZE(size) |
2569 V_MAXRXDATA(MAX_RX_COALESCING_LEN));
2570 }
2571 t3_write_reg(adap, A_TP_PARA_REG3, val);
2572 return 0;
2573}
2574
2575/**
2576 * t3_tp_set_max_rxsize - set the max receive size
2577 * @adap: the adapter
2578 * @size: the max receive size
2579 *
2580 * Set TP's max receive size. This is the limit that applies when
2581 * receive coalescing is disabled.
2582 */
2583void t3_tp_set_max_rxsize(struct adapter *adap, unsigned int size)
2584{
2585 t3_write_reg(adap, A_TP_PARA_REG7,
2586 V_PMMAXXFERLEN0(size) | V_PMMAXXFERLEN1(size));
2587}
2588
2589static void __devinit init_mtus(unsigned short mtus[])
2590{
2591 /*
2592 * See draft-mathis-plpmtud-00.txt for the values. The min is 88 so
2593 * it can accomodate max size TCP/IP headers when SACK and timestamps
2594 * are enabled and still have at least 8 bytes of payload.
2595 */
Divy Le Ray8a9fab22007-05-30 21:10:52 -07002596 mtus[1] = 88;
2597 mtus[1] = 88;
2598 mtus[2] = 256;
2599 mtus[3] = 512;
2600 mtus[4] = 576;
Divy Le Ray4d22de32007-01-18 22:04:14 -05002601 mtus[5] = 1024;
2602 mtus[6] = 1280;
2603 mtus[7] = 1492;
2604 mtus[8] = 1500;
2605 mtus[9] = 2002;
2606 mtus[10] = 2048;
2607 mtus[11] = 4096;
2608 mtus[12] = 4352;
2609 mtus[13] = 8192;
2610 mtus[14] = 9000;
2611 mtus[15] = 9600;
2612}
2613
2614/*
2615 * Initial congestion control parameters.
2616 */
2617static void __devinit init_cong_ctrl(unsigned short *a, unsigned short *b)
2618{
2619 a[0] = a[1] = a[2] = a[3] = a[4] = a[5] = a[6] = a[7] = a[8] = 1;
2620 a[9] = 2;
2621 a[10] = 3;
2622 a[11] = 4;
2623 a[12] = 5;
2624 a[13] = 6;
2625 a[14] = 7;
2626 a[15] = 8;
2627 a[16] = 9;
2628 a[17] = 10;
2629 a[18] = 14;
2630 a[19] = 17;
2631 a[20] = 21;
2632 a[21] = 25;
2633 a[22] = 30;
2634 a[23] = 35;
2635 a[24] = 45;
2636 a[25] = 60;
2637 a[26] = 80;
2638 a[27] = 100;
2639 a[28] = 200;
2640 a[29] = 300;
2641 a[30] = 400;
2642 a[31] = 500;
2643
2644 b[0] = b[1] = b[2] = b[3] = b[4] = b[5] = b[6] = b[7] = b[8] = 0;
2645 b[9] = b[10] = 1;
2646 b[11] = b[12] = 2;
2647 b[13] = b[14] = b[15] = b[16] = 3;
2648 b[17] = b[18] = b[19] = b[20] = b[21] = 4;
2649 b[22] = b[23] = b[24] = b[25] = b[26] = b[27] = 5;
2650 b[28] = b[29] = 6;
2651 b[30] = b[31] = 7;
2652}
2653
2654/* The minimum additive increment value for the congestion control table */
2655#define CC_MIN_INCR 2U
2656
2657/**
2658 * t3_load_mtus - write the MTU and congestion control HW tables
2659 * @adap: the adapter
2660 * @mtus: the unrestricted values for the MTU table
2661 * @alphs: the values for the congestion control alpha parameter
2662 * @beta: the values for the congestion control beta parameter
2663 * @mtu_cap: the maximum permitted effective MTU
2664 *
2665 * Write the MTU table with the supplied MTUs capping each at &mtu_cap.
2666 * Update the high-speed congestion control table with the supplied alpha,
2667 * beta, and MTUs.
2668 */
2669void t3_load_mtus(struct adapter *adap, unsigned short mtus[NMTUS],
2670 unsigned short alpha[NCCTRL_WIN],
2671 unsigned short beta[NCCTRL_WIN], unsigned short mtu_cap)
2672{
2673 static const unsigned int avg_pkts[NCCTRL_WIN] = {
2674 2, 6, 10, 14, 20, 28, 40, 56, 80, 112, 160, 224, 320, 448, 640,
2675 896, 1281, 1792, 2560, 3584, 5120, 7168, 10240, 14336, 20480,
2676 28672, 40960, 57344, 81920, 114688, 163840, 229376
2677 };
2678
2679 unsigned int i, w;
2680
2681 for (i = 0; i < NMTUS; ++i) {
2682 unsigned int mtu = min(mtus[i], mtu_cap);
2683 unsigned int log2 = fls(mtu);
2684
2685 if (!(mtu & ((1 << log2) >> 2))) /* round */
2686 log2--;
2687 t3_write_reg(adap, A_TP_MTU_TABLE,
2688 (i << 24) | (log2 << 16) | mtu);
2689
2690 for (w = 0; w < NCCTRL_WIN; ++w) {
2691 unsigned int inc;
2692
2693 inc = max(((mtu - 40) * alpha[w]) / avg_pkts[w],
2694 CC_MIN_INCR);
2695
2696 t3_write_reg(adap, A_TP_CCTRL_TABLE, (i << 21) |
2697 (w << 16) | (beta[w] << 13) | inc);
2698 }
2699 }
2700}
2701
2702/**
2703 * t3_read_hw_mtus - returns the values in the HW MTU table
2704 * @adap: the adapter
2705 * @mtus: where to store the HW MTU values
2706 *
2707 * Reads the HW MTU table.
2708 */
2709void t3_read_hw_mtus(struct adapter *adap, unsigned short mtus[NMTUS])
2710{
2711 int i;
2712
2713 for (i = 0; i < NMTUS; ++i) {
2714 unsigned int val;
2715
2716 t3_write_reg(adap, A_TP_MTU_TABLE, 0xff000000 | i);
2717 val = t3_read_reg(adap, A_TP_MTU_TABLE);
2718 mtus[i] = val & 0x3fff;
2719 }
2720}
2721
2722/**
2723 * t3_get_cong_cntl_tab - reads the congestion control table
2724 * @adap: the adapter
2725 * @incr: where to store the alpha values
2726 *
2727 * Reads the additive increments programmed into the HW congestion
2728 * control table.
2729 */
2730void t3_get_cong_cntl_tab(struct adapter *adap,
2731 unsigned short incr[NMTUS][NCCTRL_WIN])
2732{
2733 unsigned int mtu, w;
2734
2735 for (mtu = 0; mtu < NMTUS; ++mtu)
2736 for (w = 0; w < NCCTRL_WIN; ++w) {
2737 t3_write_reg(adap, A_TP_CCTRL_TABLE,
2738 0xffff0000 | (mtu << 5) | w);
2739 incr[mtu][w] = t3_read_reg(adap, A_TP_CCTRL_TABLE) &
2740 0x1fff;
2741 }
2742}
2743
2744/**
2745 * t3_tp_get_mib_stats - read TP's MIB counters
2746 * @adap: the adapter
2747 * @tps: holds the returned counter values
2748 *
2749 * Returns the values of TP's MIB counters.
2750 */
2751void t3_tp_get_mib_stats(struct adapter *adap, struct tp_mib_stats *tps)
2752{
2753 t3_read_indirect(adap, A_TP_MIB_INDEX, A_TP_MIB_RDATA, (u32 *) tps,
2754 sizeof(*tps) / sizeof(u32), 0);
2755}
2756
2757#define ulp_region(adap, name, start, len) \
2758 t3_write_reg((adap), A_ULPRX_ ## name ## _LLIMIT, (start)); \
2759 t3_write_reg((adap), A_ULPRX_ ## name ## _ULIMIT, \
2760 (start) + (len) - 1); \
2761 start += len
2762
2763#define ulptx_region(adap, name, start, len) \
2764 t3_write_reg((adap), A_ULPTX_ ## name ## _LLIMIT, (start)); \
2765 t3_write_reg((adap), A_ULPTX_ ## name ## _ULIMIT, \
2766 (start) + (len) - 1)
2767
2768static void ulp_config(struct adapter *adap, const struct tp_params *p)
2769{
2770 unsigned int m = p->chan_rx_size;
2771
2772 ulp_region(adap, ISCSI, m, p->chan_rx_size / 8);
2773 ulp_region(adap, TDDP, m, p->chan_rx_size / 8);
2774 ulptx_region(adap, TPT, m, p->chan_rx_size / 4);
2775 ulp_region(adap, STAG, m, p->chan_rx_size / 4);
2776 ulp_region(adap, RQ, m, p->chan_rx_size / 4);
2777 ulptx_region(adap, PBL, m, p->chan_rx_size / 4);
2778 ulp_region(adap, PBL, m, p->chan_rx_size / 4);
2779 t3_write_reg(adap, A_ULPRX_TDDP_TAGMASK, 0xffffffff);
2780}
2781
Divy Le Ray480fe1a2007-05-30 21:10:58 -07002782/**
2783 * t3_set_proto_sram - set the contents of the protocol sram
2784 * @adapter: the adapter
2785 * @data: the protocol image
2786 *
2787 * Write the contents of the protocol SRAM.
2788 */
2789int t3_set_proto_sram(struct adapter *adap, u8 *data)
2790{
2791 int i;
2792 u32 *buf = (u32 *)data;
2793
2794 for (i = 0; i < PROTO_SRAM_LINES; i++) {
2795 t3_write_reg(adap, A_TP_EMBED_OP_FIELD5, cpu_to_be32(*buf++));
2796 t3_write_reg(adap, A_TP_EMBED_OP_FIELD4, cpu_to_be32(*buf++));
2797 t3_write_reg(adap, A_TP_EMBED_OP_FIELD3, cpu_to_be32(*buf++));
2798 t3_write_reg(adap, A_TP_EMBED_OP_FIELD2, cpu_to_be32(*buf++));
2799 t3_write_reg(adap, A_TP_EMBED_OP_FIELD1, cpu_to_be32(*buf++));
2800
2801 t3_write_reg(adap, A_TP_EMBED_OP_FIELD0, i << 1 | 1 << 31);
2802 if (t3_wait_op_done(adap, A_TP_EMBED_OP_FIELD0, 1, 1, 5, 1))
2803 return -EIO;
2804 }
2805 t3_write_reg(adap, A_TP_EMBED_OP_FIELD0, 0);
2806
2807 return 0;
2808}
2809
Divy Le Ray4d22de32007-01-18 22:04:14 -05002810void t3_config_trace_filter(struct adapter *adapter,
2811 const struct trace_params *tp, int filter_index,
2812 int invert, int enable)
2813{
2814 u32 addr, key[4], mask[4];
2815
2816 key[0] = tp->sport | (tp->sip << 16);
2817 key[1] = (tp->sip >> 16) | (tp->dport << 16);
2818 key[2] = tp->dip;
2819 key[3] = tp->proto | (tp->vlan << 8) | (tp->intf << 20);
2820
2821 mask[0] = tp->sport_mask | (tp->sip_mask << 16);
2822 mask[1] = (tp->sip_mask >> 16) | (tp->dport_mask << 16);
2823 mask[2] = tp->dip_mask;
2824 mask[3] = tp->proto_mask | (tp->vlan_mask << 8) | (tp->intf_mask << 20);
2825
2826 if (invert)
2827 key[3] |= (1 << 29);
2828 if (enable)
2829 key[3] |= (1 << 28);
2830
2831 addr = filter_index ? A_TP_RX_TRC_KEY0 : A_TP_TX_TRC_KEY0;
2832 tp_wr_indirect(adapter, addr++, key[0]);
2833 tp_wr_indirect(adapter, addr++, mask[0]);
2834 tp_wr_indirect(adapter, addr++, key[1]);
2835 tp_wr_indirect(adapter, addr++, mask[1]);
2836 tp_wr_indirect(adapter, addr++, key[2]);
2837 tp_wr_indirect(adapter, addr++, mask[2]);
2838 tp_wr_indirect(adapter, addr++, key[3]);
2839 tp_wr_indirect(adapter, addr, mask[3]);
2840 t3_read_reg(adapter, A_TP_PIO_DATA);
2841}
2842
2843/**
2844 * t3_config_sched - configure a HW traffic scheduler
2845 * @adap: the adapter
2846 * @kbps: target rate in Kbps
2847 * @sched: the scheduler index
2848 *
2849 * Configure a HW scheduler for the target rate
2850 */
2851int t3_config_sched(struct adapter *adap, unsigned int kbps, int sched)
2852{
2853 unsigned int v, tps, cpt, bpt, delta, mindelta = ~0;
2854 unsigned int clk = adap->params.vpd.cclk * 1000;
2855 unsigned int selected_cpt = 0, selected_bpt = 0;
2856
2857 if (kbps > 0) {
2858 kbps *= 125; /* -> bytes */
2859 for (cpt = 1; cpt <= 255; cpt++) {
2860 tps = clk / cpt;
2861 bpt = (kbps + tps / 2) / tps;
2862 if (bpt > 0 && bpt <= 255) {
2863 v = bpt * tps;
2864 delta = v >= kbps ? v - kbps : kbps - v;
2865 if (delta <= mindelta) {
2866 mindelta = delta;
2867 selected_cpt = cpt;
2868 selected_bpt = bpt;
2869 }
2870 } else if (selected_cpt)
2871 break;
2872 }
2873 if (!selected_cpt)
2874 return -EINVAL;
2875 }
2876 t3_write_reg(adap, A_TP_TM_PIO_ADDR,
2877 A_TP_TX_MOD_Q1_Q0_RATE_LIMIT - sched / 2);
2878 v = t3_read_reg(adap, A_TP_TM_PIO_DATA);
2879 if (sched & 1)
2880 v = (v & 0xffff) | (selected_cpt << 16) | (selected_bpt << 24);
2881 else
2882 v = (v & 0xffff0000) | selected_cpt | (selected_bpt << 8);
2883 t3_write_reg(adap, A_TP_TM_PIO_DATA, v);
2884 return 0;
2885}
2886
2887static int tp_init(struct adapter *adap, const struct tp_params *p)
2888{
2889 int busy = 0;
2890
2891 tp_config(adap, p);
2892 t3_set_vlan_accel(adap, 3, 0);
2893
2894 if (is_offload(adap)) {
2895 tp_set_timers(adap, adap->params.vpd.cclk * 1000);
2896 t3_write_reg(adap, A_TP_RESET, F_FLSTINITENABLE);
2897 busy = t3_wait_op_done(adap, A_TP_RESET, F_FLSTINITENABLE,
2898 0, 1000, 5);
2899 if (busy)
2900 CH_ERR(adap, "TP initialization timed out\n");
2901 }
2902
2903 if (!busy)
2904 t3_write_reg(adap, A_TP_RESET, F_TPRESET);
2905 return busy;
2906}
2907
2908int t3_mps_set_active_ports(struct adapter *adap, unsigned int port_mask)
2909{
2910 if (port_mask & ~((1 << adap->params.nports) - 1))
2911 return -EINVAL;
2912 t3_set_reg_field(adap, A_MPS_CFG, F_PORT1ACTIVE | F_PORT0ACTIVE,
2913 port_mask << S_PORT0ACTIVE);
2914 return 0;
2915}
2916
2917/*
2918 * Perform the bits of HW initialization that are dependent on the number
2919 * of available ports.
2920 */
2921static void init_hw_for_avail_ports(struct adapter *adap, int nports)
2922{
2923 int i;
2924
2925 if (nports == 1) {
2926 t3_set_reg_field(adap, A_ULPRX_CTL, F_ROUND_ROBIN, 0);
2927 t3_set_reg_field(adap, A_ULPTX_CONFIG, F_CFG_RR_ARB, 0);
2928 t3_write_reg(adap, A_MPS_CFG, F_TPRXPORTEN | F_TPTXPORT0EN |
2929 F_PORT0ACTIVE | F_ENFORCEPKT);
Divy Le Ray8a9fab22007-05-30 21:10:52 -07002930 t3_write_reg(adap, A_PM1_TX_CFG, 0xffffffff);
Divy Le Ray4d22de32007-01-18 22:04:14 -05002931 } else {
2932 t3_set_reg_field(adap, A_ULPRX_CTL, 0, F_ROUND_ROBIN);
2933 t3_set_reg_field(adap, A_ULPTX_CONFIG, 0, F_CFG_RR_ARB);
2934 t3_write_reg(adap, A_ULPTX_DMA_WEIGHT,
2935 V_D1_WEIGHT(16) | V_D0_WEIGHT(16));
2936 t3_write_reg(adap, A_MPS_CFG, F_TPTXPORT0EN | F_TPTXPORT1EN |
2937 F_TPRXPORTEN | F_PORT0ACTIVE | F_PORT1ACTIVE |
2938 F_ENFORCEPKT);
2939 t3_write_reg(adap, A_PM1_TX_CFG, 0x80008000);
2940 t3_set_reg_field(adap, A_TP_PC_CONFIG, 0, F_TXTOSQUEUEMAPMODE);
2941 t3_write_reg(adap, A_TP_TX_MOD_QUEUE_REQ_MAP,
2942 V_TX_MOD_QUEUE_REQ_MAP(0xaa));
2943 for (i = 0; i < 16; i++)
2944 t3_write_reg(adap, A_TP_TX_MOD_QUE_TABLE,
2945 (i << 16) | 0x1010);
2946 }
2947}
2948
2949static int calibrate_xgm(struct adapter *adapter)
2950{
2951 if (uses_xaui(adapter)) {
2952 unsigned int v, i;
2953
2954 for (i = 0; i < 5; ++i) {
2955 t3_write_reg(adapter, A_XGM_XAUI_IMP, 0);
2956 t3_read_reg(adapter, A_XGM_XAUI_IMP);
2957 msleep(1);
2958 v = t3_read_reg(adapter, A_XGM_XAUI_IMP);
2959 if (!(v & (F_XGM_CALFAULT | F_CALBUSY))) {
2960 t3_write_reg(adapter, A_XGM_XAUI_IMP,
2961 V_XAUIIMP(G_CALIMP(v) >> 2));
2962 return 0;
2963 }
2964 }
2965 CH_ERR(adapter, "MAC calibration failed\n");
2966 return -1;
2967 } else {
2968 t3_write_reg(adapter, A_XGM_RGMII_IMP,
2969 V_RGMIIIMPPD(2) | V_RGMIIIMPPU(3));
2970 t3_set_reg_field(adapter, A_XGM_RGMII_IMP, F_XGM_IMPSETUPDATE,
2971 F_XGM_IMPSETUPDATE);
2972 }
2973 return 0;
2974}
2975
2976static void calibrate_xgm_t3b(struct adapter *adapter)
2977{
2978 if (!uses_xaui(adapter)) {
2979 t3_write_reg(adapter, A_XGM_RGMII_IMP, F_CALRESET |
2980 F_CALUPDATE | V_RGMIIIMPPD(2) | V_RGMIIIMPPU(3));
2981 t3_set_reg_field(adapter, A_XGM_RGMII_IMP, F_CALRESET, 0);
2982 t3_set_reg_field(adapter, A_XGM_RGMII_IMP, 0,
2983 F_XGM_IMPSETUPDATE);
2984 t3_set_reg_field(adapter, A_XGM_RGMII_IMP, F_XGM_IMPSETUPDATE,
2985 0);
2986 t3_set_reg_field(adapter, A_XGM_RGMII_IMP, F_CALUPDATE, 0);
2987 t3_set_reg_field(adapter, A_XGM_RGMII_IMP, 0, F_CALUPDATE);
2988 }
2989}
2990
2991struct mc7_timing_params {
2992 unsigned char ActToPreDly;
2993 unsigned char ActToRdWrDly;
2994 unsigned char PreCyc;
2995 unsigned char RefCyc[5];
2996 unsigned char BkCyc;
2997 unsigned char WrToRdDly;
2998 unsigned char RdToWrDly;
2999};
3000
3001/*
3002 * Write a value to a register and check that the write completed. These
3003 * writes normally complete in a cycle or two, so one read should suffice.
3004 * The very first read exists to flush the posted write to the device.
3005 */
3006static int wrreg_wait(struct adapter *adapter, unsigned int addr, u32 val)
3007{
3008 t3_write_reg(adapter, addr, val);
3009 t3_read_reg(adapter, addr); /* flush */
3010 if (!(t3_read_reg(adapter, addr) & F_BUSY))
3011 return 0;
3012 CH_ERR(adapter, "write to MC7 register 0x%x timed out\n", addr);
3013 return -EIO;
3014}
3015
3016static int mc7_init(struct mc7 *mc7, unsigned int mc7_clock, int mem_type)
3017{
3018 static const unsigned int mc7_mode[] = {
3019 0x632, 0x642, 0x652, 0x432, 0x442
3020 };
3021 static const struct mc7_timing_params mc7_timings[] = {
3022 {12, 3, 4, {20, 28, 34, 52, 0}, 15, 6, 4},
3023 {12, 4, 5, {20, 28, 34, 52, 0}, 16, 7, 4},
3024 {12, 5, 6, {20, 28, 34, 52, 0}, 17, 8, 4},
3025 {9, 3, 4, {15, 21, 26, 39, 0}, 12, 6, 4},
3026 {9, 4, 5, {15, 21, 26, 39, 0}, 13, 7, 4}
3027 };
3028
3029 u32 val;
3030 unsigned int width, density, slow, attempts;
3031 struct adapter *adapter = mc7->adapter;
3032 const struct mc7_timing_params *p = &mc7_timings[mem_type];
3033
Divy Le Ray8ac3ba62007-03-31 00:23:19 -07003034 if (!mc7->size)
3035 return 0;
3036
Divy Le Ray4d22de32007-01-18 22:04:14 -05003037 val = t3_read_reg(adapter, mc7->offset + A_MC7_CFG);
3038 slow = val & F_SLOW;
3039 width = G_WIDTH(val);
3040 density = G_DEN(val);
3041
3042 t3_write_reg(adapter, mc7->offset + A_MC7_CFG, val | F_IFEN);
3043 val = t3_read_reg(adapter, mc7->offset + A_MC7_CFG); /* flush */
3044 msleep(1);
3045
3046 if (!slow) {
3047 t3_write_reg(adapter, mc7->offset + A_MC7_CAL, F_SGL_CAL_EN);
3048 t3_read_reg(adapter, mc7->offset + A_MC7_CAL);
3049 msleep(1);
3050 if (t3_read_reg(adapter, mc7->offset + A_MC7_CAL) &
3051 (F_BUSY | F_SGL_CAL_EN | F_CAL_FAULT)) {
3052 CH_ERR(adapter, "%s MC7 calibration timed out\n",
3053 mc7->name);
3054 goto out_fail;
3055 }
3056 }
3057
3058 t3_write_reg(adapter, mc7->offset + A_MC7_PARM,
3059 V_ACTTOPREDLY(p->ActToPreDly) |
3060 V_ACTTORDWRDLY(p->ActToRdWrDly) | V_PRECYC(p->PreCyc) |
3061 V_REFCYC(p->RefCyc[density]) | V_BKCYC(p->BkCyc) |
3062 V_WRTORDDLY(p->WrToRdDly) | V_RDTOWRDLY(p->RdToWrDly));
3063
3064 t3_write_reg(adapter, mc7->offset + A_MC7_CFG,
3065 val | F_CLKEN | F_TERM150);
3066 t3_read_reg(adapter, mc7->offset + A_MC7_CFG); /* flush */
3067
3068 if (!slow)
3069 t3_set_reg_field(adapter, mc7->offset + A_MC7_DLL, F_DLLENB,
3070 F_DLLENB);
3071 udelay(1);
3072
3073 val = slow ? 3 : 6;
3074 if (wrreg_wait(adapter, mc7->offset + A_MC7_PRE, 0) ||
3075 wrreg_wait(adapter, mc7->offset + A_MC7_EXT_MODE2, 0) ||
3076 wrreg_wait(adapter, mc7->offset + A_MC7_EXT_MODE3, 0) ||
3077 wrreg_wait(adapter, mc7->offset + A_MC7_EXT_MODE1, val))
3078 goto out_fail;
3079
3080 if (!slow) {
3081 t3_write_reg(adapter, mc7->offset + A_MC7_MODE, 0x100);
3082 t3_set_reg_field(adapter, mc7->offset + A_MC7_DLL, F_DLLRST, 0);
3083 udelay(5);
3084 }
3085
3086 if (wrreg_wait(adapter, mc7->offset + A_MC7_PRE, 0) ||
3087 wrreg_wait(adapter, mc7->offset + A_MC7_REF, 0) ||
3088 wrreg_wait(adapter, mc7->offset + A_MC7_REF, 0) ||
3089 wrreg_wait(adapter, mc7->offset + A_MC7_MODE,
3090 mc7_mode[mem_type]) ||
3091 wrreg_wait(adapter, mc7->offset + A_MC7_EXT_MODE1, val | 0x380) ||
3092 wrreg_wait(adapter, mc7->offset + A_MC7_EXT_MODE1, val))
3093 goto out_fail;
3094
3095 /* clock value is in KHz */
3096 mc7_clock = mc7_clock * 7812 + mc7_clock / 2; /* ns */
3097 mc7_clock /= 1000000; /* KHz->MHz, ns->us */
3098
3099 t3_write_reg(adapter, mc7->offset + A_MC7_REF,
3100 F_PERREFEN | V_PREREFDIV(mc7_clock));
3101 t3_read_reg(adapter, mc7->offset + A_MC7_REF); /* flush */
3102
3103 t3_write_reg(adapter, mc7->offset + A_MC7_ECC, F_ECCGENEN | F_ECCCHKEN);
3104 t3_write_reg(adapter, mc7->offset + A_MC7_BIST_DATA, 0);
3105 t3_write_reg(adapter, mc7->offset + A_MC7_BIST_ADDR_BEG, 0);
3106 t3_write_reg(adapter, mc7->offset + A_MC7_BIST_ADDR_END,
3107 (mc7->size << width) - 1);
3108 t3_write_reg(adapter, mc7->offset + A_MC7_BIST_OP, V_OP(1));
3109 t3_read_reg(adapter, mc7->offset + A_MC7_BIST_OP); /* flush */
3110
3111 attempts = 50;
3112 do {
3113 msleep(250);
3114 val = t3_read_reg(adapter, mc7->offset + A_MC7_BIST_OP);
3115 } while ((val & F_BUSY) && --attempts);
3116 if (val & F_BUSY) {
3117 CH_ERR(adapter, "%s MC7 BIST timed out\n", mc7->name);
3118 goto out_fail;
3119 }
3120
3121 /* Enable normal memory accesses. */
3122 t3_set_reg_field(adapter, mc7->offset + A_MC7_CFG, 0, F_RDY);
3123 return 0;
3124
3125out_fail:
3126 return -1;
3127}
3128
3129static void config_pcie(struct adapter *adap)
3130{
3131 static const u16 ack_lat[4][6] = {
3132 {237, 416, 559, 1071, 2095, 4143},
3133 {128, 217, 289, 545, 1057, 2081},
3134 {73, 118, 154, 282, 538, 1050},
3135 {67, 107, 86, 150, 278, 534}
3136 };
3137 static const u16 rpl_tmr[4][6] = {
3138 {711, 1248, 1677, 3213, 6285, 12429},
3139 {384, 651, 867, 1635, 3171, 6243},
3140 {219, 354, 462, 846, 1614, 3150},
3141 {201, 321, 258, 450, 834, 1602}
3142 };
3143
3144 u16 val;
3145 unsigned int log2_width, pldsize;
3146 unsigned int fst_trn_rx, fst_trn_tx, acklat, rpllmt;
3147
3148 pci_read_config_word(adap->pdev,
3149 adap->params.pci.pcie_cap_addr + PCI_EXP_DEVCTL,
3150 &val);
3151 pldsize = (val & PCI_EXP_DEVCTL_PAYLOAD) >> 5;
3152 pci_read_config_word(adap->pdev,
3153 adap->params.pci.pcie_cap_addr + PCI_EXP_LNKCTL,
3154 &val);
3155
3156 fst_trn_tx = G_NUMFSTTRNSEQ(t3_read_reg(adap, A_PCIE_PEX_CTRL0));
3157 fst_trn_rx = adap->params.rev == 0 ? fst_trn_tx :
3158 G_NUMFSTTRNSEQRX(t3_read_reg(adap, A_PCIE_MODE));
3159 log2_width = fls(adap->params.pci.width) - 1;
3160 acklat = ack_lat[log2_width][pldsize];
3161 if (val & 1) /* check LOsEnable */
3162 acklat += fst_trn_tx * 4;
3163 rpllmt = rpl_tmr[log2_width][pldsize] + fst_trn_rx * 4;
3164
3165 if (adap->params.rev == 0)
3166 t3_set_reg_field(adap, A_PCIE_PEX_CTRL1,
3167 V_T3A_ACKLAT(M_T3A_ACKLAT),
3168 V_T3A_ACKLAT(acklat));
3169 else
3170 t3_set_reg_field(adap, A_PCIE_PEX_CTRL1, V_ACKLAT(M_ACKLAT),
3171 V_ACKLAT(acklat));
3172
3173 t3_set_reg_field(adap, A_PCIE_PEX_CTRL0, V_REPLAYLMT(M_REPLAYLMT),
3174 V_REPLAYLMT(rpllmt));
3175
3176 t3_write_reg(adap, A_PCIE_PEX_ERR, 0xffffffff);
3177 t3_set_reg_field(adap, A_PCIE_CFG, F_PCIE_CLIDECEN, F_PCIE_CLIDECEN);
3178}
3179
3180/*
3181 * Initialize and configure T3 HW modules. This performs the
3182 * initialization steps that need to be done once after a card is reset.
3183 * MAC and PHY initialization is handled separarely whenever a port is enabled.
3184 *
3185 * fw_params are passed to FW and their value is platform dependent. Only the
3186 * top 8 bits are available for use, the rest must be 0.
3187 */
3188int t3_init_hw(struct adapter *adapter, u32 fw_params)
3189{
3190 int err = -EIO, attempts = 100;
3191 const struct vpd_params *vpd = &adapter->params.vpd;
3192
3193 if (adapter->params.rev > 0)
3194 calibrate_xgm_t3b(adapter);
3195 else if (calibrate_xgm(adapter))
3196 goto out_err;
3197
3198 if (vpd->mclk) {
3199 partition_mem(adapter, &adapter->params.tp);
3200
3201 if (mc7_init(&adapter->pmrx, vpd->mclk, vpd->mem_timing) ||
3202 mc7_init(&adapter->pmtx, vpd->mclk, vpd->mem_timing) ||
3203 mc7_init(&adapter->cm, vpd->mclk, vpd->mem_timing) ||
3204 t3_mc5_init(&adapter->mc5, adapter->params.mc5.nservers,
3205 adapter->params.mc5.nfilters,
3206 adapter->params.mc5.nroutes))
3207 goto out_err;
3208 }
3209
3210 if (tp_init(adapter, &adapter->params.tp))
3211 goto out_err;
3212
3213 t3_tp_set_coalescing_size(adapter,
3214 min(adapter->params.sge.max_pkt_size,
3215 MAX_RX_COALESCING_LEN), 1);
3216 t3_tp_set_max_rxsize(adapter,
3217 min(adapter->params.sge.max_pkt_size, 16384U));
3218 ulp_config(adapter, &adapter->params.tp);
3219
3220 if (is_pcie(adapter))
3221 config_pcie(adapter);
3222 else
3223 t3_set_reg_field(adapter, A_PCIX_CFG, 0, F_CLIDECEN);
3224
Divy Le Ray8a9fab22007-05-30 21:10:52 -07003225 t3_write_reg(adapter, A_PM1_RX_CFG, 0xffffffff);
Divy Le Ray3f61e422007-08-21 20:49:41 -07003226 t3_write_reg(adapter, A_PM1_RX_MODE, 0);
3227 t3_write_reg(adapter, A_PM1_TX_MODE, 0);
Divy Le Ray4d22de32007-01-18 22:04:14 -05003228 init_hw_for_avail_ports(adapter, adapter->params.nports);
3229 t3_sge_init(adapter, &adapter->params.sge);
3230
3231 t3_write_reg(adapter, A_CIM_HOST_ACC_DATA, vpd->uclk | fw_params);
3232 t3_write_reg(adapter, A_CIM_BOOT_CFG,
3233 V_BOOTADDR(FW_FLASH_BOOT_ADDR >> 2));
3234 t3_read_reg(adapter, A_CIM_BOOT_CFG); /* flush */
3235
3236 do { /* wait for uP to initialize */
3237 msleep(20);
3238 } while (t3_read_reg(adapter, A_CIM_HOST_ACC_DATA) && --attempts);
Divy Le Ray8ac3ba62007-03-31 00:23:19 -07003239 if (!attempts) {
3240 CH_ERR(adapter, "uP initialization timed out\n");
Divy Le Ray4d22de32007-01-18 22:04:14 -05003241 goto out_err;
Divy Le Ray8ac3ba62007-03-31 00:23:19 -07003242 }
Divy Le Ray4d22de32007-01-18 22:04:14 -05003243
3244 err = 0;
3245out_err:
3246 return err;
3247}
3248
3249/**
3250 * get_pci_mode - determine a card's PCI mode
3251 * @adapter: the adapter
3252 * @p: where to store the PCI settings
3253 *
3254 * Determines a card's PCI mode and associated parameters, such as speed
3255 * and width.
3256 */
3257static void __devinit get_pci_mode(struct adapter *adapter,
3258 struct pci_params *p)
3259{
3260 static unsigned short speed_map[] = { 33, 66, 100, 133 };
3261 u32 pci_mode, pcie_cap;
3262
3263 pcie_cap = pci_find_capability(adapter->pdev, PCI_CAP_ID_EXP);
3264 if (pcie_cap) {
3265 u16 val;
3266
3267 p->variant = PCI_VARIANT_PCIE;
3268 p->pcie_cap_addr = pcie_cap;
3269 pci_read_config_word(adapter->pdev, pcie_cap + PCI_EXP_LNKSTA,
3270 &val);
3271 p->width = (val >> 4) & 0x3f;
3272 return;
3273 }
3274
3275 pci_mode = t3_read_reg(adapter, A_PCIX_MODE);
3276 p->speed = speed_map[G_PCLKRANGE(pci_mode)];
3277 p->width = (pci_mode & F_64BIT) ? 64 : 32;
3278 pci_mode = G_PCIXINITPAT(pci_mode);
3279 if (pci_mode == 0)
3280 p->variant = PCI_VARIANT_PCI;
3281 else if (pci_mode < 4)
3282 p->variant = PCI_VARIANT_PCIX_MODE1_PARITY;
3283 else if (pci_mode < 8)
3284 p->variant = PCI_VARIANT_PCIX_MODE1_ECC;
3285 else
3286 p->variant = PCI_VARIANT_PCIX_266_MODE2;
3287}
3288
3289/**
3290 * init_link_config - initialize a link's SW state
3291 * @lc: structure holding the link state
3292 * @ai: information about the current card
3293 *
3294 * Initializes the SW state maintained for each link, including the link's
3295 * capabilities and default speed/duplex/flow-control/autonegotiation
3296 * settings.
3297 */
3298static void __devinit init_link_config(struct link_config *lc,
3299 unsigned int caps)
3300{
3301 lc->supported = caps;
3302 lc->requested_speed = lc->speed = SPEED_INVALID;
3303 lc->requested_duplex = lc->duplex = DUPLEX_INVALID;
3304 lc->requested_fc = lc->fc = PAUSE_RX | PAUSE_TX;
3305 if (lc->supported & SUPPORTED_Autoneg) {
3306 lc->advertising = lc->supported;
3307 lc->autoneg = AUTONEG_ENABLE;
3308 lc->requested_fc |= PAUSE_AUTONEG;
3309 } else {
3310 lc->advertising = 0;
3311 lc->autoneg = AUTONEG_DISABLE;
3312 }
3313}
3314
3315/**
3316 * mc7_calc_size - calculate MC7 memory size
3317 * @cfg: the MC7 configuration
3318 *
3319 * Calculates the size of an MC7 memory in bytes from the value of its
3320 * configuration register.
3321 */
3322static unsigned int __devinit mc7_calc_size(u32 cfg)
3323{
3324 unsigned int width = G_WIDTH(cfg);
3325 unsigned int banks = !!(cfg & F_BKS) + 1;
3326 unsigned int org = !!(cfg & F_ORG) + 1;
3327 unsigned int density = G_DEN(cfg);
3328 unsigned int MBs = ((256 << density) * banks) / (org << width);
3329
3330 return MBs << 20;
3331}
3332
3333static void __devinit mc7_prep(struct adapter *adapter, struct mc7 *mc7,
3334 unsigned int base_addr, const char *name)
3335{
3336 u32 cfg;
3337
3338 mc7->adapter = adapter;
3339 mc7->name = name;
3340 mc7->offset = base_addr - MC7_PMRX_BASE_ADDR;
3341 cfg = t3_read_reg(adapter, mc7->offset + A_MC7_CFG);
Divy Le Ray8ac3ba62007-03-31 00:23:19 -07003342 mc7->size = mc7->size = G_DEN(cfg) == M_DEN ? 0 : mc7_calc_size(cfg);
Divy Le Ray4d22de32007-01-18 22:04:14 -05003343 mc7->width = G_WIDTH(cfg);
3344}
3345
3346void mac_prep(struct cmac *mac, struct adapter *adapter, int index)
3347{
3348 mac->adapter = adapter;
3349 mac->offset = (XGMAC0_1_BASE_ADDR - XGMAC0_0_BASE_ADDR) * index;
3350 mac->nucast = 1;
3351
3352 if (adapter->params.rev == 0 && uses_xaui(adapter)) {
3353 t3_write_reg(adapter, A_XGM_SERDES_CTRL + mac->offset,
3354 is_10G(adapter) ? 0x2901c04 : 0x2301c04);
3355 t3_set_reg_field(adapter, A_XGM_PORT_CFG + mac->offset,
3356 F_ENRGMII, 0);
3357 }
3358}
3359
3360void early_hw_init(struct adapter *adapter, const struct adapter_info *ai)
3361{
3362 u32 val = V_PORTSPEED(is_10G(adapter) ? 3 : 2);
3363
3364 mi1_init(adapter, ai);
3365 t3_write_reg(adapter, A_I2C_CFG, /* set for 80KHz */
3366 V_I2C_CLKDIV(adapter->params.vpd.cclk / 80 - 1));
3367 t3_write_reg(adapter, A_T3DBG_GPIO_EN,
3368 ai->gpio_out | F_GPIO0_OEN | F_GPIO0_OUT_VAL);
Divy Le Ray8ac3ba62007-03-31 00:23:19 -07003369 t3_write_reg(adapter, A_MC5_DB_SERVER_INDEX, 0);
Divy Le Ray4d22de32007-01-18 22:04:14 -05003370
3371 if (adapter->params.rev == 0 || !uses_xaui(adapter))
3372 val |= F_ENRGMII;
3373
3374 /* Enable MAC clocks so we can access the registers */
3375 t3_write_reg(adapter, A_XGM_PORT_CFG, val);
3376 t3_read_reg(adapter, A_XGM_PORT_CFG);
3377
3378 val |= F_CLKDIVRESET_;
3379 t3_write_reg(adapter, A_XGM_PORT_CFG, val);
3380 t3_read_reg(adapter, A_XGM_PORT_CFG);
3381 t3_write_reg(adapter, XGM_REG(A_XGM_PORT_CFG, 1), val);
3382 t3_read_reg(adapter, A_XGM_PORT_CFG);
3383}
3384
3385/*
Divy Le Raye4d08352007-03-18 13:10:17 -07003386 * Reset the adapter.
3387 * Older PCIe cards lose their config space during reset, PCI-X
Divy Le Ray4d22de32007-01-18 22:04:14 -05003388 * ones don't.
3389 */
3390int t3_reset_adapter(struct adapter *adapter)
3391{
Divy Le Raye4d08352007-03-18 13:10:17 -07003392 int i, save_and_restore_pcie =
3393 adapter->params.rev < T3_REV_B2 && is_pcie(adapter);
Divy Le Ray4d22de32007-01-18 22:04:14 -05003394 uint16_t devid = 0;
3395
Divy Le Raye4d08352007-03-18 13:10:17 -07003396 if (save_and_restore_pcie)
Divy Le Ray4d22de32007-01-18 22:04:14 -05003397 pci_save_state(adapter->pdev);
3398 t3_write_reg(adapter, A_PL_RST, F_CRSTWRM | F_CRSTWRMMODE);
3399
3400 /*
3401 * Delay. Give Some time to device to reset fully.
3402 * XXX The delay time should be modified.
3403 */
3404 for (i = 0; i < 10; i++) {
3405 msleep(50);
3406 pci_read_config_word(adapter->pdev, 0x00, &devid);
3407 if (devid == 0x1425)
3408 break;
3409 }
3410
3411 if (devid != 0x1425)
3412 return -1;
3413
Divy Le Raye4d08352007-03-18 13:10:17 -07003414 if (save_and_restore_pcie)
Divy Le Ray4d22de32007-01-18 22:04:14 -05003415 pci_restore_state(adapter->pdev);
3416 return 0;
3417}
3418
3419/*
3420 * Initialize adapter SW state for the various HW modules, set initial values
3421 * for some adapter tunables, take PHYs out of reset, and initialize the MDIO
3422 * interface.
3423 */
3424int __devinit t3_prep_adapter(struct adapter *adapter,
3425 const struct adapter_info *ai, int reset)
3426{
3427 int ret;
3428 unsigned int i, j = 0;
3429
3430 get_pci_mode(adapter, &adapter->params.pci);
3431
3432 adapter->params.info = ai;
3433 adapter->params.nports = ai->nports;
3434 adapter->params.rev = t3_read_reg(adapter, A_PL_REV);
3435 adapter->params.linkpoll_period = 0;
3436 adapter->params.stats_update_period = is_10G(adapter) ?
3437 MAC_STATS_ACCUM_SECS : (MAC_STATS_ACCUM_SECS * 10);
3438 adapter->params.pci.vpd_cap_addr =
3439 pci_find_capability(adapter->pdev, PCI_CAP_ID_VPD);
3440 ret = get_vpd_params(adapter, &adapter->params.vpd);
3441 if (ret < 0)
3442 return ret;
3443
3444 if (reset && t3_reset_adapter(adapter))
3445 return -1;
3446
3447 t3_sge_prep(adapter, &adapter->params.sge);
3448
3449 if (adapter->params.vpd.mclk) {
3450 struct tp_params *p = &adapter->params.tp;
3451
3452 mc7_prep(adapter, &adapter->pmrx, MC7_PMRX_BASE_ADDR, "PMRX");
3453 mc7_prep(adapter, &adapter->pmtx, MC7_PMTX_BASE_ADDR, "PMTX");
3454 mc7_prep(adapter, &adapter->cm, MC7_CM_BASE_ADDR, "CM");
3455
3456 p->nchan = ai->nports;
3457 p->pmrx_size = t3_mc7_size(&adapter->pmrx);
3458 p->pmtx_size = t3_mc7_size(&adapter->pmtx);
3459 p->cm_size = t3_mc7_size(&adapter->cm);
3460 p->chan_rx_size = p->pmrx_size / 2; /* only 1 Rx channel */
3461 p->chan_tx_size = p->pmtx_size / p->nchan;
3462 p->rx_pg_size = 64 * 1024;
3463 p->tx_pg_size = is_10G(adapter) ? 64 * 1024 : 16 * 1024;
3464 p->rx_num_pgs = pm_num_pages(p->chan_rx_size, p->rx_pg_size);
3465 p->tx_num_pgs = pm_num_pages(p->chan_tx_size, p->tx_pg_size);
3466 p->ntimer_qs = p->cm_size >= (128 << 20) ||
3467 adapter->params.rev > 0 ? 12 : 6;
Divy Le Ray8ac3ba62007-03-31 00:23:19 -07003468 }
Divy Le Ray4d22de32007-01-18 22:04:14 -05003469
Divy Le Ray8ac3ba62007-03-31 00:23:19 -07003470 adapter->params.offload = t3_mc7_size(&adapter->pmrx) &&
3471 t3_mc7_size(&adapter->pmtx) &&
3472 t3_mc7_size(&adapter->cm);
3473
3474 if (is_offload(adapter)) {
Divy Le Ray4d22de32007-01-18 22:04:14 -05003475 adapter->params.mc5.nservers = DEFAULT_NSERVERS;
3476 adapter->params.mc5.nfilters = adapter->params.rev > 0 ?
3477 DEFAULT_NFILTERS : 0;
3478 adapter->params.mc5.nroutes = 0;
3479 t3_mc5_prep(adapter, &adapter->mc5, MC5_MODE_144_BIT);
3480
3481 init_mtus(adapter->params.mtus);
3482 init_cong_ctrl(adapter->params.a_wnd, adapter->params.b_wnd);
3483 }
3484
3485 early_hw_init(adapter, ai);
3486
3487 for_each_port(adapter, i) {
3488 u8 hw_addr[6];
3489 struct port_info *p = adap2pinfo(adapter, i);
3490
3491 while (!adapter->params.vpd.port_type[j])
3492 ++j;
3493
3494 p->port_type = &port_types[adapter->params.vpd.port_type[j]];
3495 p->port_type->phy_prep(&p->phy, adapter, ai->phy_base_addr + j,
3496 ai->mdio_ops);
3497 mac_prep(&p->mac, adapter, j);
3498 ++j;
3499
3500 /*
3501 * The VPD EEPROM stores the base Ethernet address for the
3502 * card. A port's address is derived from the base by adding
3503 * the port's index to the base's low octet.
3504 */
3505 memcpy(hw_addr, adapter->params.vpd.eth_base, 5);
3506 hw_addr[5] = adapter->params.vpd.eth_base[5] + i;
3507
3508 memcpy(adapter->port[i]->dev_addr, hw_addr,
3509 ETH_ALEN);
3510 memcpy(adapter->port[i]->perm_addr, hw_addr,
3511 ETH_ALEN);
3512 init_link_config(&p->link_config, p->port_type->caps);
3513 p->phy.ops->power_down(&p->phy, 1);
3514 if (!(p->port_type->caps & SUPPORTED_IRQ))
3515 adapter->params.linkpoll_period = 10;
3516 }
3517
3518 return 0;
3519}
3520
3521void t3_led_ready(struct adapter *adapter)
3522{
3523 t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, F_GPIO0_OUT_VAL,
3524 F_GPIO0_OUT_VAL);
3525}