aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/cxgb3
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/cxgb3')
-rw-r--r--drivers/net/cxgb3/adapter.h9
-rw-r--r--drivers/net/cxgb3/ael1002.c1074
-rw-r--r--drivers/net/cxgb3/common.h87
-rw-r--r--drivers/net/cxgb3/cxgb3_ctl_defs.h2
-rw-r--r--drivers/net/cxgb3/cxgb3_defs.h2
-rw-r--r--drivers/net/cxgb3/cxgb3_ioctl.h4
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c390
-rw-r--r--drivers/net/cxgb3/cxgb3_offload.c10
-rw-r--r--drivers/net/cxgb3/cxgb3_offload.h2
-rw-r--r--drivers/net/cxgb3/firmware_exports.h2
-rw-r--r--drivers/net/cxgb3/l2t.c41
-rw-r--r--drivers/net/cxgb3/l2t.h5
-rw-r--r--drivers/net/cxgb3/mc5.c2
-rw-r--r--drivers/net/cxgb3/regs.h4
-rw-r--r--drivers/net/cxgb3/sge.c112
-rw-r--r--drivers/net/cxgb3/t3_cpl.h2
-rw-r--r--drivers/net/cxgb3/t3_hw.c243
-rw-r--r--drivers/net/cxgb3/t3cdev.h2
-rw-r--r--drivers/net/cxgb3/version.h4
-rw-r--r--drivers/net/cxgb3/vsc8211.c208
-rw-r--r--drivers/net/cxgb3/xgmac.c2
21 files changed, 1813 insertions, 394 deletions
diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h
index 271140433b09..bc8e2413abd2 100644
--- a/drivers/net/cxgb3/adapter.h
+++ b/drivers/net/cxgb3/adapter.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2003-2007 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2003-2008 Chelsio, Inc. All rights reserved.
3 * 3 *
4 * This software is available to you under a choice of one of two 4 * 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 5 * licenses. You may choose to be licensed under the terms of the GNU
@@ -54,7 +54,6 @@ struct port_info {
54 struct adapter *adapter; 54 struct adapter *adapter;
55 struct vlan_group *vlan_grp; 55 struct vlan_group *vlan_grp;
56 struct sge_qset *qs; 56 struct sge_qset *qs;
57 const struct port_type_info *port_type;
58 u8 port_id; 57 u8 port_id;
59 u8 rx_csum_offload; 58 u8 rx_csum_offload;
60 u8 nqsets; 59 u8 nqsets;
@@ -124,8 +123,7 @@ struct sge_rspq { /* state for an SGE response queue */
124 dma_addr_t phys_addr; /* physical address of the ring */ 123 dma_addr_t phys_addr; /* physical address of the ring */
125 unsigned int cntxt_id; /* SGE context id for the response q */ 124 unsigned int cntxt_id; /* SGE context id for the response q */
126 spinlock_t lock; /* guards response processing */ 125 spinlock_t lock; /* guards response processing */
127 struct sk_buff *rx_head; /* offload packet receive queue head */ 126 struct sk_buff_head rx_queue; /* offload packet receive queue */
128 struct sk_buff *rx_tail; /* offload packet receive queue tail */
129 struct sk_buff *pg_skb; /* used to build frag list in napi handler */ 127 struct sk_buff *pg_skb; /* used to build frag list in napi handler */
130 128
131 unsigned long offload_pkts; 129 unsigned long offload_pkts;
@@ -241,6 +239,7 @@ struct adapter {
241 unsigned int check_task_cnt; 239 unsigned int check_task_cnt;
242 struct delayed_work adap_check_task; 240 struct delayed_work adap_check_task;
243 struct work_struct ext_intr_handler_task; 241 struct work_struct ext_intr_handler_task;
242 struct work_struct fatal_error_handler_task;
244 243
245 struct dentry *debugfs_root; 244 struct dentry *debugfs_root;
246 245
@@ -282,9 +281,11 @@ int t3_offload_tx(struct t3cdev *tdev, struct sk_buff *skb);
282void t3_os_ext_intr_handler(struct adapter *adapter); 281void t3_os_ext_intr_handler(struct adapter *adapter);
283void t3_os_link_changed(struct adapter *adapter, int port_id, int link_status, 282void t3_os_link_changed(struct adapter *adapter, int port_id, int link_status,
284 int speed, int duplex, int fc); 283 int speed, int duplex, int fc);
284void t3_os_phymod_changed(struct adapter *adap, int port_id);
285 285
286void t3_sge_start(struct adapter *adap); 286void t3_sge_start(struct adapter *adap);
287void t3_sge_stop(struct adapter *adap); 287void t3_sge_stop(struct adapter *adap);
288void t3_stop_sge_timers(struct adapter *adap);
288void t3_free_sge_resources(struct adapter *adap); 289void t3_free_sge_resources(struct adapter *adap);
289void t3_sge_err_intr_handler(struct adapter *adapter); 290void t3_sge_err_intr_handler(struct adapter *adapter);
290irq_handler_t t3_intr_handler(struct adapter *adap, int polling); 291irq_handler_t t3_intr_handler(struct adapter *adap, int polling);
diff --git a/drivers/net/cxgb3/ael1002.c b/drivers/net/cxgb3/ael1002.c
index ee140e63ddc5..5c3c05da4d96 100644
--- a/drivers/net/cxgb3/ael1002.c
+++ b/drivers/net/cxgb3/ael1002.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2005-2007 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2005-2008 Chelsio, Inc. All rights reserved.
3 * 3 *
4 * This software is available to you under a choice of one of two 4 * 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 5 * licenses. You may choose to be licensed under the terms of the GNU
@@ -33,17 +33,57 @@
33#include "regs.h" 33#include "regs.h"
34 34
35enum { 35enum {
36 PMD_RSD = 10, /* PMA/PMD receive signal detect register */
37 PCS_STAT1_X = 24, /* 10GBASE-X PCS status 1 register */
38 PCS_STAT1_R = 32, /* 10GBASE-R PCS status 1 register */
39 XS_LN_STAT = 24 /* XS lane status register */
40};
41
42enum {
36 AEL100X_TX_DISABLE = 9, 43 AEL100X_TX_DISABLE = 9,
37 AEL100X_TX_CONFIG1 = 0xc002, 44 AEL100X_TX_CONFIG1 = 0xc002,
38 AEL1002_PWR_DOWN_HI = 0xc011, 45 AEL1002_PWR_DOWN_HI = 0xc011,
39 AEL1002_PWR_DOWN_LO = 0xc012, 46 AEL1002_PWR_DOWN_LO = 0xc012,
40 AEL1002_XFI_EQL = 0xc015, 47 AEL1002_XFI_EQL = 0xc015,
41 AEL1002_LB_EN = 0xc017, 48 AEL1002_LB_EN = 0xc017,
49 AEL_OPT_SETTINGS = 0xc017,
50 AEL_I2C_CTRL = 0xc30a,
51 AEL_I2C_DATA = 0xc30b,
52 AEL_I2C_STAT = 0xc30c,
53 AEL2005_GPIO_CTRL = 0xc214,
54 AEL2005_GPIO_STAT = 0xc215,
55};
56
57enum { edc_none, edc_sr, edc_twinax };
42 58
43 LASI_CTRL = 0x9002, 59/* PHY module I2C device address */
44 LASI_STAT = 0x9005 60#define MODULE_DEV_ADDR 0xa0
61
62#define AEL2005_MODDET_IRQ 4
63
64struct reg_val {
65 unsigned short mmd_addr;
66 unsigned short reg_addr;
67 unsigned short clear_bits;
68 unsigned short set_bits;
45}; 69};
46 70
71static int set_phy_regs(struct cphy *phy, const struct reg_val *rv)
72{
73 int err;
74
75 for (err = 0; rv->mmd_addr && !err; rv++) {
76 if (rv->clear_bits == 0xffff)
77 err = mdio_write(phy, rv->mmd_addr, rv->reg_addr,
78 rv->set_bits);
79 else
80 err = t3_mdio_change_bits(phy, rv->mmd_addr,
81 rv->reg_addr, rv->clear_bits,
82 rv->set_bits);
83 }
84 return err;
85}
86
47static void ael100x_txon(struct cphy *phy) 87static void ael100x_txon(struct cphy *phy)
48{ 88{
49 int tx_on_gpio = phy->addr == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL; 89 int tx_on_gpio = phy->addr == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL;
@@ -84,23 +124,23 @@ static int ael1002_intr_noop(struct cphy *phy)
84 return 0; 124 return 0;
85} 125}
86 126
87static int ael100x_get_link_status(struct cphy *phy, int *link_ok, 127/*
88 int *speed, int *duplex, int *fc) 128 * Get link status for a 10GBASE-R device.
129 */
130static int get_link_status_r(struct cphy *phy, int *link_ok, int *speed,
131 int *duplex, int *fc)
89{ 132{
90 if (link_ok) { 133 if (link_ok) {
91 unsigned int status; 134 unsigned int stat0, stat1, stat2;
92 int err = mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &status); 135 int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0);
93 136
94 /* 137 if (!err)
95 * BMSR_LSTATUS is latch-low, so if it is 0 we need to read it 138 err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_R, &stat1);
96 * once more to get the current link state. 139 if (!err)
97 */ 140 err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2);
98 if (!err && !(status & BMSR_LSTATUS))
99 err = mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR,
100 &status);
101 if (err) 141 if (err)
102 return err; 142 return err;
103 *link_ok = !!(status & BMSR_LSTATUS); 143 *link_ok = (stat0 & stat1 & (stat2 >> 12)) & 1;
104 } 144 }
105 if (speed) 145 if (speed)
106 *speed = SPEED_10000; 146 *speed = SPEED_10000;
@@ -115,15 +155,18 @@ static struct cphy_ops ael1002_ops = {
115 .intr_disable = ael1002_intr_noop, 155 .intr_disable = ael1002_intr_noop,
116 .intr_clear = ael1002_intr_noop, 156 .intr_clear = ael1002_intr_noop,
117 .intr_handler = ael1002_intr_noop, 157 .intr_handler = ael1002_intr_noop,
118 .get_link_status = ael100x_get_link_status, 158 .get_link_status = get_link_status_r,
119 .power_down = ael1002_power_down, 159 .power_down = ael1002_power_down,
120}; 160};
121 161
122void t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter, 162int t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter,
123 int phy_addr, const struct mdio_ops *mdio_ops) 163 int phy_addr, const struct mdio_ops *mdio_ops)
124{ 164{
125 cphy_init(phy, adapter, phy_addr, &ael1002_ops, mdio_ops); 165 cphy_init(phy, adapter, phy_addr, &ael1002_ops, mdio_ops,
166 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE,
167 "10GBASE-R");
126 ael100x_txon(phy); 168 ael100x_txon(phy);
169 return 0;
127} 170}
128 171
129static int ael1006_reset(struct cphy *phy, int wait) 172static int ael1006_reset(struct cphy *phy, int wait)
@@ -131,72 +174,985 @@ static int ael1006_reset(struct cphy *phy, int wait)
131 return t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait); 174 return t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait);
132} 175}
133 176
134static int ael1006_intr_enable(struct cphy *phy) 177static int ael1006_power_down(struct cphy *phy, int enable)
135{ 178{
136 return mdio_write(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, 1); 179 return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR,
180 BMCR_PDOWN, enable ? BMCR_PDOWN : 0);
137} 181}
138 182
139static int ael1006_intr_disable(struct cphy *phy) 183static struct cphy_ops ael1006_ops = {
184 .reset = ael1006_reset,
185 .intr_enable = t3_phy_lasi_intr_enable,
186 .intr_disable = t3_phy_lasi_intr_disable,
187 .intr_clear = t3_phy_lasi_intr_clear,
188 .intr_handler = t3_phy_lasi_intr_handler,
189 .get_link_status = get_link_status_r,
190 .power_down = ael1006_power_down,
191};
192
193int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter,
194 int phy_addr, const struct mdio_ops *mdio_ops)
140{ 195{
141 return mdio_write(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, 0); 196 cphy_init(phy, adapter, phy_addr, &ael1006_ops, mdio_ops,
197 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE,
198 "10GBASE-SR");
199 ael100x_txon(phy);
200 return 0;
142} 201}
143 202
144static int ael1006_intr_clear(struct cphy *phy) 203static int ael2005_setup_sr_edc(struct cphy *phy)
145{ 204{
146 u32 val; 205 static struct reg_val regs[] = {
206 { MDIO_DEV_PMA_PMD, 0xc003, 0xffff, 0x181 },
207 { MDIO_DEV_PMA_PMD, 0xc010, 0xffff, 0x448a },
208 { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5200 },
209 { 0, 0, 0, 0 }
210 };
211 static u16 sr_edc[] = {
212 0xcc00, 0x2ff4,
213 0xcc01, 0x3cd4,
214 0xcc02, 0x2015,
215 0xcc03, 0x3105,
216 0xcc04, 0x6524,
217 0xcc05, 0x27ff,
218 0xcc06, 0x300f,
219 0xcc07, 0x2c8b,
220 0xcc08, 0x300b,
221 0xcc09, 0x4009,
222 0xcc0a, 0x400e,
223 0xcc0b, 0x2f72,
224 0xcc0c, 0x3002,
225 0xcc0d, 0x1002,
226 0xcc0e, 0x2172,
227 0xcc0f, 0x3012,
228 0xcc10, 0x1002,
229 0xcc11, 0x25d2,
230 0xcc12, 0x3012,
231 0xcc13, 0x1002,
232 0xcc14, 0xd01e,
233 0xcc15, 0x27d2,
234 0xcc16, 0x3012,
235 0xcc17, 0x1002,
236 0xcc18, 0x2004,
237 0xcc19, 0x3c84,
238 0xcc1a, 0x6436,
239 0xcc1b, 0x2007,
240 0xcc1c, 0x3f87,
241 0xcc1d, 0x8676,
242 0xcc1e, 0x40b7,
243 0xcc1f, 0xa746,
244 0xcc20, 0x4047,
245 0xcc21, 0x5673,
246 0xcc22, 0x2982,
247 0xcc23, 0x3002,
248 0xcc24, 0x13d2,
249 0xcc25, 0x8bbd,
250 0xcc26, 0x2862,
251 0xcc27, 0x3012,
252 0xcc28, 0x1002,
253 0xcc29, 0x2092,
254 0xcc2a, 0x3012,
255 0xcc2b, 0x1002,
256 0xcc2c, 0x5cc3,
257 0xcc2d, 0x314,
258 0xcc2e, 0x2942,
259 0xcc2f, 0x3002,
260 0xcc30, 0x1002,
261 0xcc31, 0xd019,
262 0xcc32, 0x2032,
263 0xcc33, 0x3012,
264 0xcc34, 0x1002,
265 0xcc35, 0x2a04,
266 0xcc36, 0x3c74,
267 0xcc37, 0x6435,
268 0xcc38, 0x2fa4,
269 0xcc39, 0x3cd4,
270 0xcc3a, 0x6624,
271 0xcc3b, 0x5563,
272 0xcc3c, 0x2d42,
273 0xcc3d, 0x3002,
274 0xcc3e, 0x13d2,
275 0xcc3f, 0x464d,
276 0xcc40, 0x2862,
277 0xcc41, 0x3012,
278 0xcc42, 0x1002,
279 0xcc43, 0x2032,
280 0xcc44, 0x3012,
281 0xcc45, 0x1002,
282 0xcc46, 0x2fb4,
283 0xcc47, 0x3cd4,
284 0xcc48, 0x6624,
285 0xcc49, 0x5563,
286 0xcc4a, 0x2d42,
287 0xcc4b, 0x3002,
288 0xcc4c, 0x13d2,
289 0xcc4d, 0x2ed2,
290 0xcc4e, 0x3002,
291 0xcc4f, 0x1002,
292 0xcc50, 0x2fd2,
293 0xcc51, 0x3002,
294 0xcc52, 0x1002,
295 0xcc53, 0x004,
296 0xcc54, 0x2942,
297 0xcc55, 0x3002,
298 0xcc56, 0x1002,
299 0xcc57, 0x2092,
300 0xcc58, 0x3012,
301 0xcc59, 0x1002,
302 0xcc5a, 0x5cc3,
303 0xcc5b, 0x317,
304 0xcc5c, 0x2f72,
305 0xcc5d, 0x3002,
306 0xcc5e, 0x1002,
307 0xcc5f, 0x2942,
308 0xcc60, 0x3002,
309 0xcc61, 0x1002,
310 0xcc62, 0x22cd,
311 0xcc63, 0x301d,
312 0xcc64, 0x2862,
313 0xcc65, 0x3012,
314 0xcc66, 0x1002,
315 0xcc67, 0x2ed2,
316 0xcc68, 0x3002,
317 0xcc69, 0x1002,
318 0xcc6a, 0x2d72,
319 0xcc6b, 0x3002,
320 0xcc6c, 0x1002,
321 0xcc6d, 0x628f,
322 0xcc6e, 0x2112,
323 0xcc6f, 0x3012,
324 0xcc70, 0x1002,
325 0xcc71, 0x5aa3,
326 0xcc72, 0x2dc2,
327 0xcc73, 0x3002,
328 0xcc74, 0x1312,
329 0xcc75, 0x6f72,
330 0xcc76, 0x1002,
331 0xcc77, 0x2807,
332 0xcc78, 0x31a7,
333 0xcc79, 0x20c4,
334 0xcc7a, 0x3c24,
335 0xcc7b, 0x6724,
336 0xcc7c, 0x1002,
337 0xcc7d, 0x2807,
338 0xcc7e, 0x3187,
339 0xcc7f, 0x20c4,
340 0xcc80, 0x3c24,
341 0xcc81, 0x6724,
342 0xcc82, 0x1002,
343 0xcc83, 0x2514,
344 0xcc84, 0x3c64,
345 0xcc85, 0x6436,
346 0xcc86, 0xdff4,
347 0xcc87, 0x6436,
348 0xcc88, 0x1002,
349 0xcc89, 0x40a4,
350 0xcc8a, 0x643c,
351 0xcc8b, 0x4016,
352 0xcc8c, 0x8c6c,
353 0xcc8d, 0x2b24,
354 0xcc8e, 0x3c24,
355 0xcc8f, 0x6435,
356 0xcc90, 0x1002,
357 0xcc91, 0x2b24,
358 0xcc92, 0x3c24,
359 0xcc93, 0x643a,
360 0xcc94, 0x4025,
361 0xcc95, 0x8a5a,
362 0xcc96, 0x1002,
363 0xcc97, 0x2731,
364 0xcc98, 0x3011,
365 0xcc99, 0x1001,
366 0xcc9a, 0xc7a0,
367 0xcc9b, 0x100,
368 0xcc9c, 0xc502,
369 0xcc9d, 0x53ac,
370 0xcc9e, 0xc503,
371 0xcc9f, 0xd5d5,
372 0xcca0, 0xc600,
373 0xcca1, 0x2a6d,
374 0xcca2, 0xc601,
375 0xcca3, 0x2a4c,
376 0xcca4, 0xc602,
377 0xcca5, 0x111,
378 0xcca6, 0xc60c,
379 0xcca7, 0x5900,
380 0xcca8, 0xc710,
381 0xcca9, 0x700,
382 0xccaa, 0xc718,
383 0xccab, 0x700,
384 0xccac, 0xc720,
385 0xccad, 0x4700,
386 0xccae, 0xc801,
387 0xccaf, 0x7f50,
388 0xccb0, 0xc802,
389 0xccb1, 0x7760,
390 0xccb2, 0xc803,
391 0xccb3, 0x7fce,
392 0xccb4, 0xc804,
393 0xccb5, 0x5700,
394 0xccb6, 0xc805,
395 0xccb7, 0x5f11,
396 0xccb8, 0xc806,
397 0xccb9, 0x4751,
398 0xccba, 0xc807,
399 0xccbb, 0x57e1,
400 0xccbc, 0xc808,
401 0xccbd, 0x2700,
402 0xccbe, 0xc809,
403 0xccbf, 0x000,
404 0xccc0, 0xc821,
405 0xccc1, 0x002,
406 0xccc2, 0xc822,
407 0xccc3, 0x014,
408 0xccc4, 0xc832,
409 0xccc5, 0x1186,
410 0xccc6, 0xc847,
411 0xccc7, 0x1e02,
412 0xccc8, 0xc013,
413 0xccc9, 0xf341,
414 0xccca, 0xc01a,
415 0xcccb, 0x446,
416 0xcccc, 0xc024,
417 0xcccd, 0x1000,
418 0xccce, 0xc025,
419 0xcccf, 0xa00,
420 0xccd0, 0xc026,
421 0xccd1, 0xc0c,
422 0xccd2, 0xc027,
423 0xccd3, 0xc0c,
424 0xccd4, 0xc029,
425 0xccd5, 0x0a0,
426 0xccd6, 0xc030,
427 0xccd7, 0xa00,
428 0xccd8, 0xc03c,
429 0xccd9, 0x01c,
430 0xccda, 0xc005,
431 0xccdb, 0x7a06,
432 0xccdc, 0x000,
433 0xccdd, 0x2731,
434 0xccde, 0x3011,
435 0xccdf, 0x1001,
436 0xcce0, 0xc620,
437 0xcce1, 0x000,
438 0xcce2, 0xc621,
439 0xcce3, 0x03f,
440 0xcce4, 0xc622,
441 0xcce5, 0x000,
442 0xcce6, 0xc623,
443 0xcce7, 0x000,
444 0xcce8, 0xc624,
445 0xcce9, 0x000,
446 0xccea, 0xc625,
447 0xcceb, 0x000,
448 0xccec, 0xc627,
449 0xcced, 0x000,
450 0xccee, 0xc628,
451 0xccef, 0x000,
452 0xccf0, 0xc62c,
453 0xccf1, 0x000,
454 0xccf2, 0x000,
455 0xccf3, 0x2806,
456 0xccf4, 0x3cb6,
457 0xccf5, 0xc161,
458 0xccf6, 0x6134,
459 0xccf7, 0x6135,
460 0xccf8, 0x5443,
461 0xccf9, 0x303,
462 0xccfa, 0x6524,
463 0xccfb, 0x00b,
464 0xccfc, 0x1002,
465 0xccfd, 0x2104,
466 0xccfe, 0x3c24,
467 0xccff, 0x2105,
468 0xcd00, 0x3805,
469 0xcd01, 0x6524,
470 0xcd02, 0xdff4,
471 0xcd03, 0x4005,
472 0xcd04, 0x6524,
473 0xcd05, 0x1002,
474 0xcd06, 0x5dd3,
475 0xcd07, 0x306,
476 0xcd08, 0x2ff7,
477 0xcd09, 0x38f7,
478 0xcd0a, 0x60b7,
479 0xcd0b, 0xdffd,
480 0xcd0c, 0x00a,
481 0xcd0d, 0x1002,
482 0xcd0e, 0
483 };
484 int i, err;
485
486 err = set_phy_regs(phy, regs);
487 if (err)
488 return err;
147 489
148 return mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_STAT, &val); 490 msleep(50);
491
492 for (i = 0; i < ARRAY_SIZE(sr_edc) && !err; i += 2)
493 err = mdio_write(phy, MDIO_DEV_PMA_PMD, sr_edc[i],
494 sr_edc[i + 1]);
495 if (!err)
496 phy->priv = edc_sr;
497 return err;
149} 498}
150 499
151static int ael1006_intr_handler(struct cphy *phy) 500static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype)
152{ 501{
153 unsigned int status; 502 static struct reg_val regs[] = {
154 int err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_STAT, &status); 503 { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5a00 },
504 { 0, 0, 0, 0 }
505 };
506 static struct reg_val preemphasis[] = {
507 { MDIO_DEV_PMA_PMD, 0xc014, 0xffff, 0xfe16 },
508 { MDIO_DEV_PMA_PMD, 0xc015, 0xffff, 0xa000 },
509 { 0, 0, 0, 0 }
510 };
511 static u16 twinax_edc[] = {
512 0xcc00, 0x4009,
513 0xcc01, 0x27ff,
514 0xcc02, 0x300f,
515 0xcc03, 0x40aa,
516 0xcc04, 0x401c,
517 0xcc05, 0x401e,
518 0xcc06, 0x2ff4,
519 0xcc07, 0x3cd4,
520 0xcc08, 0x2035,
521 0xcc09, 0x3145,
522 0xcc0a, 0x6524,
523 0xcc0b, 0x26a2,
524 0xcc0c, 0x3012,
525 0xcc0d, 0x1002,
526 0xcc0e, 0x29c2,
527 0xcc0f, 0x3002,
528 0xcc10, 0x1002,
529 0xcc11, 0x2072,
530 0xcc12, 0x3012,
531 0xcc13, 0x1002,
532 0xcc14, 0x22cd,
533 0xcc15, 0x301d,
534 0xcc16, 0x2e52,
535 0xcc17, 0x3012,
536 0xcc18, 0x1002,
537 0xcc19, 0x28e2,
538 0xcc1a, 0x3002,
539 0xcc1b, 0x1002,
540 0xcc1c, 0x628f,
541 0xcc1d, 0x2ac2,
542 0xcc1e, 0x3012,
543 0xcc1f, 0x1002,
544 0xcc20, 0x5553,
545 0xcc21, 0x2ae2,
546 0xcc22, 0x3002,
547 0xcc23, 0x1302,
548 0xcc24, 0x401e,
549 0xcc25, 0x2be2,
550 0xcc26, 0x3012,
551 0xcc27, 0x1002,
552 0xcc28, 0x2da2,
553 0xcc29, 0x3012,
554 0xcc2a, 0x1002,
555 0xcc2b, 0x2ba2,
556 0xcc2c, 0x3002,
557 0xcc2d, 0x1002,
558 0xcc2e, 0x5ee3,
559 0xcc2f, 0x305,
560 0xcc30, 0x400e,
561 0xcc31, 0x2bc2,
562 0xcc32, 0x3002,
563 0xcc33, 0x1002,
564 0xcc34, 0x2b82,
565 0xcc35, 0x3012,
566 0xcc36, 0x1002,
567 0xcc37, 0x5663,
568 0xcc38, 0x302,
569 0xcc39, 0x401e,
570 0xcc3a, 0x6f72,
571 0xcc3b, 0x1002,
572 0xcc3c, 0x628f,
573 0xcc3d, 0x2be2,
574 0xcc3e, 0x3012,
575 0xcc3f, 0x1002,
576 0xcc40, 0x22cd,
577 0xcc41, 0x301d,
578 0xcc42, 0x2e52,
579 0xcc43, 0x3012,
580 0xcc44, 0x1002,
581 0xcc45, 0x2522,
582 0xcc46, 0x3012,
583 0xcc47, 0x1002,
584 0xcc48, 0x2da2,
585 0xcc49, 0x3012,
586 0xcc4a, 0x1002,
587 0xcc4b, 0x2ca2,
588 0xcc4c, 0x3012,
589 0xcc4d, 0x1002,
590 0xcc4e, 0x2fa4,
591 0xcc4f, 0x3cd4,
592 0xcc50, 0x6624,
593 0xcc51, 0x410b,
594 0xcc52, 0x56b3,
595 0xcc53, 0x3c4,
596 0xcc54, 0x2fb2,
597 0xcc55, 0x3002,
598 0xcc56, 0x1002,
599 0xcc57, 0x220b,
600 0xcc58, 0x303b,
601 0xcc59, 0x56b3,
602 0xcc5a, 0x3c3,
603 0xcc5b, 0x866b,
604 0xcc5c, 0x400c,
605 0xcc5d, 0x23a2,
606 0xcc5e, 0x3012,
607 0xcc5f, 0x1002,
608 0xcc60, 0x2da2,
609 0xcc61, 0x3012,
610 0xcc62, 0x1002,
611 0xcc63, 0x2ca2,
612 0xcc64, 0x3012,
613 0xcc65, 0x1002,
614 0xcc66, 0x2fb4,
615 0xcc67, 0x3cd4,
616 0xcc68, 0x6624,
617 0xcc69, 0x56b3,
618 0xcc6a, 0x3c3,
619 0xcc6b, 0x866b,
620 0xcc6c, 0x401c,
621 0xcc6d, 0x2205,
622 0xcc6e, 0x3035,
623 0xcc6f, 0x5b53,
624 0xcc70, 0x2c52,
625 0xcc71, 0x3002,
626 0xcc72, 0x13c2,
627 0xcc73, 0x5cc3,
628 0xcc74, 0x317,
629 0xcc75, 0x2522,
630 0xcc76, 0x3012,
631 0xcc77, 0x1002,
632 0xcc78, 0x2da2,
633 0xcc79, 0x3012,
634 0xcc7a, 0x1002,
635 0xcc7b, 0x2b82,
636 0xcc7c, 0x3012,
637 0xcc7d, 0x1002,
638 0xcc7e, 0x5663,
639 0xcc7f, 0x303,
640 0xcc80, 0x401e,
641 0xcc81, 0x004,
642 0xcc82, 0x2c42,
643 0xcc83, 0x3012,
644 0xcc84, 0x1002,
645 0xcc85, 0x6f72,
646 0xcc86, 0x1002,
647 0xcc87, 0x628f,
648 0xcc88, 0x2304,
649 0xcc89, 0x3c84,
650 0xcc8a, 0x6436,
651 0xcc8b, 0xdff4,
652 0xcc8c, 0x6436,
653 0xcc8d, 0x2ff5,
654 0xcc8e, 0x3005,
655 0xcc8f, 0x8656,
656 0xcc90, 0xdfba,
657 0xcc91, 0x56a3,
658 0xcc92, 0xd05a,
659 0xcc93, 0x21c2,
660 0xcc94, 0x3012,
661 0xcc95, 0x1392,
662 0xcc96, 0xd05a,
663 0xcc97, 0x56a3,
664 0xcc98, 0xdfba,
665 0xcc99, 0x383,
666 0xcc9a, 0x6f72,
667 0xcc9b, 0x1002,
668 0xcc9c, 0x28c5,
669 0xcc9d, 0x3005,
670 0xcc9e, 0x4178,
671 0xcc9f, 0x5653,
672 0xcca0, 0x384,
673 0xcca1, 0x22b2,
674 0xcca2, 0x3012,
675 0xcca3, 0x1002,
676 0xcca4, 0x2be5,
677 0xcca5, 0x3005,
678 0xcca6, 0x41e8,
679 0xcca7, 0x5653,
680 0xcca8, 0x382,
681 0xcca9, 0x002,
682 0xccaa, 0x4258,
683 0xccab, 0x2474,
684 0xccac, 0x3c84,
685 0xccad, 0x6437,
686 0xccae, 0xdff4,
687 0xccaf, 0x6437,
688 0xccb0, 0x2ff5,
689 0xccb1, 0x3c05,
690 0xccb2, 0x8757,
691 0xccb3, 0xb888,
692 0xccb4, 0x9787,
693 0xccb5, 0xdff4,
694 0xccb6, 0x6724,
695 0xccb7, 0x866a,
696 0xccb8, 0x6f72,
697 0xccb9, 0x1002,
698 0xccba, 0x2d01,
699 0xccbb, 0x3011,
700 0xccbc, 0x1001,
701 0xccbd, 0xc620,
702 0xccbe, 0x14e5,
703 0xccbf, 0xc621,
704 0xccc0, 0xc53d,
705 0xccc1, 0xc622,
706 0xccc2, 0x3cbe,
707 0xccc3, 0xc623,
708 0xccc4, 0x4452,
709 0xccc5, 0xc624,
710 0xccc6, 0xc5c5,
711 0xccc7, 0xc625,
712 0xccc8, 0xe01e,
713 0xccc9, 0xc627,
714 0xccca, 0x000,
715 0xcccb, 0xc628,
716 0xcccc, 0x000,
717 0xcccd, 0xc62b,
718 0xccce, 0x000,
719 0xcccf, 0xc62c,
720 0xccd0, 0x000,
721 0xccd1, 0x000,
722 0xccd2, 0x2d01,
723 0xccd3, 0x3011,
724 0xccd4, 0x1001,
725 0xccd5, 0xc620,
726 0xccd6, 0x000,
727 0xccd7, 0xc621,
728 0xccd8, 0x000,
729 0xccd9, 0xc622,
730 0xccda, 0x0ce,
731 0xccdb, 0xc623,
732 0xccdc, 0x07f,
733 0xccdd, 0xc624,
734 0xccde, 0x032,
735 0xccdf, 0xc625,
736 0xcce0, 0x000,
737 0xcce1, 0xc627,
738 0xcce2, 0x000,
739 0xcce3, 0xc628,
740 0xcce4, 0x000,
741 0xcce5, 0xc62b,
742 0xcce6, 0x000,
743 0xcce7, 0xc62c,
744 0xcce8, 0x000,
745 0xcce9, 0x000,
746 0xccea, 0x2d01,
747 0xcceb, 0x3011,
748 0xccec, 0x1001,
749 0xcced, 0xc502,
750 0xccee, 0x609f,
751 0xccef, 0xc600,
752 0xccf0, 0x2a6e,
753 0xccf1, 0xc601,
754 0xccf2, 0x2a2c,
755 0xccf3, 0xc60c,
756 0xccf4, 0x5400,
757 0xccf5, 0xc710,
758 0xccf6, 0x700,
759 0xccf7, 0xc718,
760 0xccf8, 0x700,
761 0xccf9, 0xc720,
762 0xccfa, 0x4700,
763 0xccfb, 0xc728,
764 0xccfc, 0x700,
765 0xccfd, 0xc729,
766 0xccfe, 0x1207,
767 0xccff, 0xc801,
768 0xcd00, 0x7f50,
769 0xcd01, 0xc802,
770 0xcd02, 0x7760,
771 0xcd03, 0xc803,
772 0xcd04, 0x7fce,
773 0xcd05, 0xc804,
774 0xcd06, 0x520e,
775 0xcd07, 0xc805,
776 0xcd08, 0x5c11,
777 0xcd09, 0xc806,
778 0xcd0a, 0x3c51,
779 0xcd0b, 0xc807,
780 0xcd0c, 0x4061,
781 0xcd0d, 0xc808,
782 0xcd0e, 0x49c1,
783 0xcd0f, 0xc809,
784 0xcd10, 0x3840,
785 0xcd11, 0xc80a,
786 0xcd12, 0x000,
787 0xcd13, 0xc821,
788 0xcd14, 0x002,
789 0xcd15, 0xc822,
790 0xcd16, 0x046,
791 0xcd17, 0xc844,
792 0xcd18, 0x182f,
793 0xcd19, 0xc013,
794 0xcd1a, 0xf341,
795 0xcd1b, 0xc01a,
796 0xcd1c, 0x446,
797 0xcd1d, 0xc024,
798 0xcd1e, 0x1000,
799 0xcd1f, 0xc025,
800 0xcd20, 0xa00,
801 0xcd21, 0xc026,
802 0xcd22, 0xc0c,
803 0xcd23, 0xc027,
804 0xcd24, 0xc0c,
805 0xcd25, 0xc029,
806 0xcd26, 0x0a0,
807 0xcd27, 0xc030,
808 0xcd28, 0xa00,
809 0xcd29, 0xc03c,
810 0xcd2a, 0x01c,
811 0xcd2b, 0x000,
812 0xcd2c, 0x2b84,
813 0xcd2d, 0x3c74,
814 0xcd2e, 0x6435,
815 0xcd2f, 0xdff4,
816 0xcd30, 0x6435,
817 0xcd31, 0x2806,
818 0xcd32, 0x3006,
819 0xcd33, 0x8565,
820 0xcd34, 0x2b24,
821 0xcd35, 0x3c24,
822 0xcd36, 0x6436,
823 0xcd37, 0x1002,
824 0xcd38, 0x2b24,
825 0xcd39, 0x3c24,
826 0xcd3a, 0x6436,
827 0xcd3b, 0x4045,
828 0xcd3c, 0x8656,
829 0xcd3d, 0x1002,
830 0xcd3e, 0x2807,
831 0xcd3f, 0x31a7,
832 0xcd40, 0x20c4,
833 0xcd41, 0x3c24,
834 0xcd42, 0x6724,
835 0xcd43, 0x1002,
836 0xcd44, 0x2807,
837 0xcd45, 0x3187,
838 0xcd46, 0x20c4,
839 0xcd47, 0x3c24,
840 0xcd48, 0x6724,
841 0xcd49, 0x1002,
842 0xcd4a, 0x2514,
843 0xcd4b, 0x3c64,
844 0xcd4c, 0x6436,
845 0xcd4d, 0xdff4,
846 0xcd4e, 0x6436,
847 0xcd4f, 0x1002,
848 0xcd50, 0x2806,
849 0xcd51, 0x3cb6,
850 0xcd52, 0xc161,
851 0xcd53, 0x6134,
852 0xcd54, 0x6135,
853 0xcd55, 0x5443,
854 0xcd56, 0x303,
855 0xcd57, 0x6524,
856 0xcd58, 0x00b,
857 0xcd59, 0x1002,
858 0xcd5a, 0xd019,
859 0xcd5b, 0x2104,
860 0xcd5c, 0x3c24,
861 0xcd5d, 0x2105,
862 0xcd5e, 0x3805,
863 0xcd5f, 0x6524,
864 0xcd60, 0xdff4,
865 0xcd61, 0x4005,
866 0xcd62, 0x6524,
867 0xcd63, 0x2e8d,
868 0xcd64, 0x303d,
869 0xcd65, 0x5dd3,
870 0xcd66, 0x306,
871 0xcd67, 0x2ff7,
872 0xcd68, 0x38f7,
873 0xcd69, 0x60b7,
874 0xcd6a, 0xdffd,
875 0xcd6b, 0x00a,
876 0xcd6c, 0x1002,
877 0xcd6d, 0
878 };
879 int i, err;
155 880
881 err = set_phy_regs(phy, regs);
882 if (!err && modtype == phy_modtype_twinax_long)
883 err = set_phy_regs(phy, preemphasis);
156 if (err) 884 if (err)
157 return err; 885 return err;
158 return (status & 1) ? cphy_cause_link_change : 0; 886
887 msleep(50);
888
889 for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2)
890 err = mdio_write(phy, MDIO_DEV_PMA_PMD, twinax_edc[i],
891 twinax_edc[i + 1]);
892 if (!err)
893 phy->priv = edc_twinax;
894 return err;
159} 895}
160 896
161static int ael1006_power_down(struct cphy *phy, int enable) 897static int ael2005_i2c_rd(struct cphy *phy, int dev_addr, int word_addr)
162{ 898{
163 return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, 899 int i, err;
164 BMCR_PDOWN, enable ? BMCR_PDOWN : 0); 900 unsigned int stat, data;
901
902 err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_CTRL,
903 (dev_addr << 8) | (1 << 8) | word_addr);
904 if (err)
905 return err;
906
907 for (i = 0; i < 5; i++) {
908 msleep(1);
909 err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_STAT, &stat);
910 if (err)
911 return err;
912 if ((stat & 3) == 1) {
913 err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_DATA,
914 &data);
915 if (err)
916 return err;
917 return data >> 8;
918 }
919 }
920 CH_WARN(phy->adapter, "PHY %u I2C read of addr %u timed out\n",
921 phy->addr, word_addr);
922 return -ETIMEDOUT;
165} 923}
166 924
167static struct cphy_ops ael1006_ops = { 925static int get_module_type(struct cphy *phy, int delay_ms)
168 .reset = ael1006_reset, 926{
169 .intr_enable = ael1006_intr_enable, 927 int v;
170 .intr_disable = ael1006_intr_disable, 928 unsigned int stat;
171 .intr_clear = ael1006_intr_clear, 929
172 .intr_handler = ael1006_intr_handler, 930 v = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, &stat);
173 .get_link_status = ael100x_get_link_status, 931 if (v)
174 .power_down = ael1006_power_down, 932 return v;
933
934 if (stat & (1 << 8)) /* module absent */
935 return phy_modtype_none;
936
937 if (delay_ms)
938 msleep(delay_ms);
939
940 /* see SFF-8472 for below */
941 v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 3);
942 if (v < 0)
943 return v;
944
945 if (v == 0x10)
946 return phy_modtype_sr;
947 if (v == 0x20)
948 return phy_modtype_lr;
949 if (v == 0x40)
950 return phy_modtype_lrm;
951
952 v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 6);
953 if (v < 0)
954 return v;
955 if (v != 4)
956 goto unknown;
957
958 v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 10);
959 if (v < 0)
960 return v;
961
962 if (v & 0x80) {
963 v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 0x12);
964 if (v < 0)
965 return v;
966 return v > 10 ? phy_modtype_twinax_long : phy_modtype_twinax;
967 }
968unknown:
969 return phy_modtype_unknown;
970}
971
972static int ael2005_intr_enable(struct cphy *phy)
973{
974 int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x200);
975 return err ? err : t3_phy_lasi_intr_enable(phy);
976}
977
978static int ael2005_intr_disable(struct cphy *phy)
979{
980 int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x100);
981 return err ? err : t3_phy_lasi_intr_disable(phy);
982}
983
984static int ael2005_intr_clear(struct cphy *phy)
985{
986 int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0xd00);
987 return err ? err : t3_phy_lasi_intr_clear(phy);
988}
989
990static int ael2005_reset(struct cphy *phy, int wait)
991{
992 static struct reg_val regs0[] = {
993 { MDIO_DEV_PMA_PMD, 0xc001, 0, 1 << 5 },
994 { MDIO_DEV_PMA_PMD, 0xc017, 0, 1 << 5 },
995 { MDIO_DEV_PMA_PMD, 0xc013, 0xffff, 0xf341 },
996 { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 },
997 { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8100 },
998 { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 },
999 { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0 },
1000 { 0, 0, 0, 0 }
1001 };
1002 static struct reg_val regs1[] = {
1003 { MDIO_DEV_PMA_PMD, 0xca00, 0xffff, 0x0080 },
1004 { MDIO_DEV_PMA_PMD, 0xca12, 0xffff, 0 },
1005 { 0, 0, 0, 0 }
1006 };
1007
1008 int err, lasi_ctrl;
1009
1010 err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, &lasi_ctrl);
1011 if (err)
1012 return err;
1013
1014 err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, 0);
1015 if (err)
1016 return err;
1017
1018 msleep(125);
1019 phy->priv = edc_none;
1020 err = set_phy_regs(phy, regs0);
1021 if (err)
1022 return err;
1023
1024 msleep(50);
1025
1026 err = get_module_type(phy, 0);
1027 if (err < 0)
1028 return err;
1029 phy->modtype = err;
1030
1031 if (err == phy_modtype_twinax || err == phy_modtype_twinax_long)
1032 err = ael2005_setup_twinax_edc(phy, err);
1033 else
1034 err = ael2005_setup_sr_edc(phy);
1035 if (err)
1036 return err;
1037
1038 err = set_phy_regs(phy, regs1);
1039 if (err)
1040 return err;
1041
1042 /* reset wipes out interrupts, reenable them if they were on */
1043 if (lasi_ctrl & 1)
1044 err = ael2005_intr_enable(phy);
1045 return err;
1046}
1047
1048static int ael2005_intr_handler(struct cphy *phy)
1049{
1050 unsigned int stat;
1051 int ret, edc_needed, cause = 0;
1052
1053 ret = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_STAT, &stat);
1054 if (ret)
1055 return ret;
1056
1057 if (stat & AEL2005_MODDET_IRQ) {
1058 ret = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL,
1059 0xd00);
1060 if (ret)
1061 return ret;
1062
1063 /* modules have max 300 ms init time after hot plug */
1064 ret = get_module_type(phy, 300);
1065 if (ret < 0)
1066 return ret;
1067
1068 phy->modtype = ret;
1069 if (ret == phy_modtype_none)
1070 edc_needed = phy->priv; /* on unplug retain EDC */
1071 else if (ret == phy_modtype_twinax ||
1072 ret == phy_modtype_twinax_long)
1073 edc_needed = edc_twinax;
1074 else
1075 edc_needed = edc_sr;
1076
1077 if (edc_needed != phy->priv) {
1078 ret = ael2005_reset(phy, 0);
1079 return ret ? ret : cphy_cause_module_change;
1080 }
1081 cause = cphy_cause_module_change;
1082 }
1083
1084 ret = t3_phy_lasi_intr_handler(phy);
1085 if (ret < 0)
1086 return ret;
1087
1088 ret |= cause;
1089 return ret ? ret : cphy_cause_link_change;
1090}
1091
1092static struct cphy_ops ael2005_ops = {
1093 .reset = ael2005_reset,
1094 .intr_enable = ael2005_intr_enable,
1095 .intr_disable = ael2005_intr_disable,
1096 .intr_clear = ael2005_intr_clear,
1097 .intr_handler = ael2005_intr_handler,
1098 .get_link_status = get_link_status_r,
1099 .power_down = ael1002_power_down,
175}; 1100};
176 1101
177void t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter, 1102int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter,
178 int phy_addr, const struct mdio_ops *mdio_ops) 1103 int phy_addr, const struct mdio_ops *mdio_ops)
179{ 1104{
180 cphy_init(phy, adapter, phy_addr, &ael1006_ops, mdio_ops); 1105 cphy_init(phy, adapter, phy_addr, &ael2005_ops, mdio_ops,
181 ael100x_txon(phy); 1106 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE |
1107 SUPPORTED_IRQ, "10GBASE-R");
1108 msleep(125);
1109 return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL_OPT_SETTINGS, 0,
1110 1 << 5);
1111}
1112
1113/*
1114 * Get link status for a 10GBASE-X device.
1115 */
1116static int get_link_status_x(struct cphy *phy, int *link_ok, int *speed,
1117 int *duplex, int *fc)
1118{
1119 if (link_ok) {
1120 unsigned int stat0, stat1, stat2;
1121 int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0);
1122
1123 if (!err)
1124 err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_X, &stat1);
1125 if (!err)
1126 err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2);
1127 if (err)
1128 return err;
1129 *link_ok = (stat0 & (stat1 >> 12) & (stat2 >> 12)) & 1;
1130 }
1131 if (speed)
1132 *speed = SPEED_10000;
1133 if (duplex)
1134 *duplex = DUPLEX_FULL;
1135 return 0;
182} 1136}
183 1137
184static struct cphy_ops qt2045_ops = { 1138static struct cphy_ops qt2045_ops = {
185 .reset = ael1006_reset, 1139 .reset = ael1006_reset,
186 .intr_enable = ael1006_intr_enable, 1140 .intr_enable = t3_phy_lasi_intr_enable,
187 .intr_disable = ael1006_intr_disable, 1141 .intr_disable = t3_phy_lasi_intr_disable,
188 .intr_clear = ael1006_intr_clear, 1142 .intr_clear = t3_phy_lasi_intr_clear,
189 .intr_handler = ael1006_intr_handler, 1143 .intr_handler = t3_phy_lasi_intr_handler,
190 .get_link_status = ael100x_get_link_status, 1144 .get_link_status = get_link_status_x,
191 .power_down = ael1006_power_down, 1145 .power_down = ael1006_power_down,
192}; 1146};
193 1147
194void t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter, 1148int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter,
195 int phy_addr, const struct mdio_ops *mdio_ops) 1149 int phy_addr, const struct mdio_ops *mdio_ops)
196{ 1150{
197 unsigned int stat; 1151 unsigned int stat;
198 1152
199 cphy_init(phy, adapter, phy_addr, &qt2045_ops, mdio_ops); 1153 cphy_init(phy, adapter, phy_addr, &qt2045_ops, mdio_ops,
1154 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP,
1155 "10GBASE-CX4");
200 1156
201 /* 1157 /*
202 * Some cards where the PHY is supposed to be at address 0 actually 1158 * Some cards where the PHY is supposed to be at address 0 actually
@@ -205,6 +1161,7 @@ void t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter,
205 if (!phy_addr && !mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &stat) && 1161 if (!phy_addr && !mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &stat) &&
206 stat == 0xffff) 1162 stat == 0xffff)
207 phy->addr = 1; 1163 phy->addr = 1;
1164 return 0;
208} 1165}
209 1166
210static int xaui_direct_reset(struct cphy *phy, int wait) 1167static int xaui_direct_reset(struct cphy *phy, int wait)
@@ -250,8 +1207,11 @@ static struct cphy_ops xaui_direct_ops = {
250 .power_down = xaui_direct_power_down, 1207 .power_down = xaui_direct_power_down,
251}; 1208};
252 1209
253void t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter, 1210int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter,
254 int phy_addr, const struct mdio_ops *mdio_ops) 1211 int phy_addr, const struct mdio_ops *mdio_ops)
255{ 1212{
256 cphy_init(phy, adapter, phy_addr, &xaui_direct_ops, mdio_ops); 1213 cphy_init(phy, adapter, phy_addr, &xaui_direct_ops, mdio_ops,
1214 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP,
1215 "10GBASE-CX4");
1216 return 0;
257} 1217}
diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h
index 9ecf8a6dc97f..e312d315a42d 100644
--- a/drivers/net/cxgb3/common.h
+++ b/drivers/net/cxgb3/common.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2005-2007 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2005-2008 Chelsio, Inc. All rights reserved.
3 * 3 *
4 * This software is available to you under a choice of one of two 4 * 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 5 * licenses. You may choose to be licensed under the terms of the GNU
@@ -193,22 +193,13 @@ struct mdio_ops {
193struct adapter_info { 193struct adapter_info {
194 unsigned char nports; /* # of ports */ 194 unsigned char nports; /* # of ports */
195 unsigned char phy_base_addr; /* MDIO PHY base address */ 195 unsigned char phy_base_addr; /* MDIO PHY base address */
196 unsigned char mdien;
197 unsigned char mdiinv;
198 unsigned int gpio_out; /* GPIO output settings */ 196 unsigned int gpio_out; /* GPIO output settings */
199 unsigned int gpio_intr; /* GPIO IRQ enable mask */ 197 unsigned char gpio_intr[MAX_NPORTS]; /* GPIO PHY IRQ pins */
200 unsigned long caps; /* adapter capabilities */ 198 unsigned long caps; /* adapter capabilities */
201 const struct mdio_ops *mdio_ops; /* MDIO operations */ 199 const struct mdio_ops *mdio_ops; /* MDIO operations */
202 const char *desc; /* product description */ 200 const char *desc; /* product description */
203}; 201};
204 202
205struct port_type_info {
206 void (*phy_prep)(struct cphy *phy, struct adapter *adapter,
207 int phy_addr, const struct mdio_ops *ops);
208 unsigned int caps;
209 const char *desc;
210};
211
212struct mc5_stats { 203struct mc5_stats {
213 unsigned long parity_err; 204 unsigned long parity_err;
214 unsigned long active_rgn_full; 205 unsigned long active_rgn_full;
@@ -358,6 +349,7 @@ struct qset_params { /* SGE queue set parameters */
358 unsigned int jumbo_size; /* # of entries in jumbo free list */ 349 unsigned int jumbo_size; /* # of entries in jumbo free list */
359 unsigned int txq_size[SGE_TXQ_PER_SET]; /* Tx queue sizes */ 350 unsigned int txq_size[SGE_TXQ_PER_SET]; /* Tx queue sizes */
360 unsigned int cong_thres; /* FL congestion threshold */ 351 unsigned int cong_thres; /* FL congestion threshold */
352 unsigned int vector; /* Interrupt (line or vector) number */
361}; 353};
362 354
363struct sge_params { 355struct sge_params {
@@ -525,12 +517,25 @@ enum {
525 MAC_RXFIFO_SIZE = 32768 517 MAC_RXFIFO_SIZE = 32768
526}; 518};
527 519
528/* IEEE 802.3ae specified MDIO devices */ 520/* IEEE 802.3 specified MDIO devices */
529enum { 521enum {
530 MDIO_DEV_PMA_PMD = 1, 522 MDIO_DEV_PMA_PMD = 1,
531 MDIO_DEV_WIS = 2, 523 MDIO_DEV_WIS = 2,
532 MDIO_DEV_PCS = 3, 524 MDIO_DEV_PCS = 3,
533 MDIO_DEV_XGXS = 4 525 MDIO_DEV_XGXS = 4,
526 MDIO_DEV_ANEG = 7,
527 MDIO_DEV_VEND1 = 30,
528 MDIO_DEV_VEND2 = 31
529};
530
531/* LASI control and status registers */
532enum {
533 RX_ALARM_CTRL = 0x9000,
534 TX_ALARM_CTRL = 0x9001,
535 LASI_CTRL = 0x9002,
536 RX_ALARM_STAT = 0x9003,
537 TX_ALARM_STAT = 0x9004,
538 LASI_STAT = 0x9005
534}; 539};
535 540
536/* PHY loopback direction */ 541/* PHY loopback direction */
@@ -542,12 +547,23 @@ enum {
542/* PHY interrupt types */ 547/* PHY interrupt types */
543enum { 548enum {
544 cphy_cause_link_change = 1, 549 cphy_cause_link_change = 1,
545 cphy_cause_fifo_error = 2 550 cphy_cause_fifo_error = 2,
551 cphy_cause_module_change = 4,
552};
553
554/* PHY module types */
555enum {
556 phy_modtype_none,
557 phy_modtype_sr,
558 phy_modtype_lr,
559 phy_modtype_lrm,
560 phy_modtype_twinax,
561 phy_modtype_twinax_long,
562 phy_modtype_unknown
546}; 563};
547 564
548/* PHY operations */ 565/* PHY operations */
549struct cphy_ops { 566struct cphy_ops {
550 void (*destroy)(struct cphy *phy);
551 int (*reset)(struct cphy *phy, int wait); 567 int (*reset)(struct cphy *phy, int wait);
552 568
553 int (*intr_enable)(struct cphy *phy); 569 int (*intr_enable)(struct cphy *phy);
@@ -568,8 +584,12 @@ struct cphy_ops {
568 584
569/* A PHY instance */ 585/* A PHY instance */
570struct cphy { 586struct cphy {
571 int addr; /* PHY address */ 587 u8 addr; /* PHY address */
588 u8 modtype; /* PHY module type */
589 short priv; /* scratch pad */
590 unsigned int caps; /* PHY capabilities */
572 struct adapter *adapter; /* associated adapter */ 591 struct adapter *adapter; /* associated adapter */
592 const char *desc; /* PHY description */
573 unsigned long fifo_errors; /* FIFO over/under-flows */ 593 unsigned long fifo_errors; /* FIFO over/under-flows */
574 const struct cphy_ops *ops; /* PHY operations */ 594 const struct cphy_ops *ops; /* PHY operations */
575 int (*mdio_read)(struct adapter *adapter, int phy_addr, int mmd_addr, 595 int (*mdio_read)(struct adapter *adapter, int phy_addr, int mmd_addr,
@@ -594,10 +614,13 @@ static inline int mdio_write(struct cphy *phy, int mmd, int reg,
594/* Convenience initializer */ 614/* Convenience initializer */
595static inline void cphy_init(struct cphy *phy, struct adapter *adapter, 615static inline void cphy_init(struct cphy *phy, struct adapter *adapter,
596 int phy_addr, struct cphy_ops *phy_ops, 616 int phy_addr, struct cphy_ops *phy_ops,
597 const struct mdio_ops *mdio_ops) 617 const struct mdio_ops *mdio_ops,
618 unsigned int caps, const char *desc)
598{ 619{
599 phy->adapter = adapter;
600 phy->addr = phy_addr; 620 phy->addr = phy_addr;
621 phy->caps = caps;
622 phy->adapter = adapter;
623 phy->desc = desc;
601 phy->ops = phy_ops; 624 phy->ops = phy_ops;
602 if (mdio_ops) { 625 if (mdio_ops) {
603 phy->mdio_read = mdio_ops->read; 626 phy->mdio_read = mdio_ops->read;
@@ -668,7 +691,12 @@ int t3_mdio_change_bits(struct cphy *phy, int mmd, int reg, unsigned int clear,
668 unsigned int set); 691 unsigned int set);
669int t3_phy_reset(struct cphy *phy, int mmd, int wait); 692int t3_phy_reset(struct cphy *phy, int mmd, int wait);
670int t3_phy_advertise(struct cphy *phy, unsigned int advert); 693int t3_phy_advertise(struct cphy *phy, unsigned int advert);
694int t3_phy_advertise_fiber(struct cphy *phy, unsigned int advert);
671int t3_set_phy_speed_duplex(struct cphy *phy, int speed, int duplex); 695int t3_set_phy_speed_duplex(struct cphy *phy, int speed, int duplex);
696int t3_phy_lasi_intr_enable(struct cphy *phy);
697int t3_phy_lasi_intr_disable(struct cphy *phy);
698int t3_phy_lasi_intr_clear(struct cphy *phy);
699int t3_phy_lasi_intr_handler(struct cphy *phy);
672 700
673void t3_intr_enable(struct adapter *adapter); 701void t3_intr_enable(struct adapter *adapter);
674void t3_intr_disable(struct adapter *adapter); 702void t3_intr_disable(struct adapter *adapter);
@@ -698,6 +726,7 @@ int t3_check_fw_version(struct adapter *adapter, int *must_load);
698int t3_init_hw(struct adapter *adapter, u32 fw_params); 726int t3_init_hw(struct adapter *adapter, u32 fw_params);
699void mac_prep(struct cmac *mac, struct adapter *adapter, int index); 727void mac_prep(struct cmac *mac, struct adapter *adapter, int index);
700void early_hw_init(struct adapter *adapter, const struct adapter_info *ai); 728void early_hw_init(struct adapter *adapter, const struct adapter_info *ai);
729int t3_reset_adapter(struct adapter *adapter);
701int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai, 730int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai,
702 int reset); 731 int reset);
703int t3_replay_prep_adapter(struct adapter *adapter); 732int t3_replay_prep_adapter(struct adapter *adapter);
@@ -774,14 +803,16 @@ int t3_sge_read_rspq(struct adapter *adapter, unsigned int id, u32 data[4]);
774int t3_sge_cqcntxt_op(struct adapter *adapter, unsigned int id, unsigned int op, 803int t3_sge_cqcntxt_op(struct adapter *adapter, unsigned int id, unsigned int op,
775 unsigned int credits); 804 unsigned int credits);
776 805
777void t3_vsc8211_phy_prep(struct cphy *phy, struct adapter *adapter, 806int t3_vsc8211_phy_prep(struct cphy *phy, struct adapter *adapter,
778 int phy_addr, const struct mdio_ops *mdio_ops); 807 int phy_addr, const struct mdio_ops *mdio_ops);
779void t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter, 808int t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter,
780 int phy_addr, const struct mdio_ops *mdio_ops); 809 int phy_addr, const struct mdio_ops *mdio_ops);
781void t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter, 810int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter,
782 int phy_addr, const struct mdio_ops *mdio_ops); 811 int phy_addr, const struct mdio_ops *mdio_ops);
783void t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, 812int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter,
784 const struct mdio_ops *mdio_ops); 813 int phy_addr, const struct mdio_ops *mdio_ops);
785void t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter, 814int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr,
786 int phy_addr, const struct mdio_ops *mdio_ops); 815 const struct mdio_ops *mdio_ops);
816int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter,
817 int phy_addr, const struct mdio_ops *mdio_ops);
787#endif /* __CHELSIO_COMMON_H */ 818#endif /* __CHELSIO_COMMON_H */
diff --git a/drivers/net/cxgb3/cxgb3_ctl_defs.h b/drivers/net/cxgb3/cxgb3_ctl_defs.h
index 6ad92405d9a0..1d8d46eb3c96 100644
--- a/drivers/net/cxgb3/cxgb3_ctl_defs.h
+++ b/drivers/net/cxgb3/cxgb3_ctl_defs.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2003-2007 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2003-2008 Chelsio, Inc. All rights reserved.
3 * 3 *
4 * This software is available to you under a choice of one of two 4 * 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 5 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/net/cxgb3/cxgb3_defs.h b/drivers/net/cxgb3/cxgb3_defs.h
index 45e92164c260..47e53769af5b 100644
--- a/drivers/net/cxgb3/cxgb3_defs.h
+++ b/drivers/net/cxgb3/cxgb3_defs.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2006-2007 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2006-2008 Chelsio, Inc. All rights reserved.
3 * 3 *
4 * This software is available to you under a choice of one of two 4 * 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 5 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/net/cxgb3/cxgb3_ioctl.h b/drivers/net/cxgb3/cxgb3_ioctl.h
index 68200a14065e..b19e4376ba76 100644
--- a/drivers/net/cxgb3/cxgb3_ioctl.h
+++ b/drivers/net/cxgb3/cxgb3_ioctl.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2003-2007 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2003-2008 Chelsio, Inc. All rights reserved.
3 * 3 *
4 * This software is available to you under a choice of one of two 4 * 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 5 * licenses. You may choose to be licensed under the terms of the GNU
@@ -92,6 +92,8 @@ struct ch_qset_params {
92 int32_t polling; 92 int32_t polling;
93 int32_t lro; 93 int32_t lro;
94 int32_t cong_thres; 94 int32_t cong_thres;
95 int32_t vector;
96 int32_t qnum;
95}; 97};
96 98
97struct ch_pktsched_params { 99struct ch_pktsched_params {
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 5447f3e60f07..1ace41a13ac3 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2003-2007 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2003-2008 Chelsio, Inc. All rights reserved.
3 * 3 *
4 * This software is available to you under a choice of one of two 4 * 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 5 * licenses. You may choose to be licensed under the terms of the GNU
@@ -208,6 +208,31 @@ void t3_os_link_changed(struct adapter *adapter, int port_id, int link_stat,
208 } 208 }
209} 209}
210 210
211/**
212 * t3_os_phymod_changed - handle PHY module changes
213 * @phy: the PHY reporting the module change
214 * @mod_type: new module type
215 *
216 * This is the OS-dependent handler for PHY module changes. It is
217 * invoked when a PHY module is removed or inserted for any OS-specific
218 * processing.
219 */
220void t3_os_phymod_changed(struct adapter *adap, int port_id)
221{
222 static const char *mod_str[] = {
223 NULL, "SR", "LR", "LRM", "TWINAX", "TWINAX", "unknown"
224 };
225
226 const struct net_device *dev = adap->port[port_id];
227 const struct port_info *pi = netdev_priv(dev);
228
229 if (pi->phy.modtype == phy_modtype_none)
230 printk(KERN_INFO "%s: PHY module unplugged\n", dev->name);
231 else
232 printk(KERN_INFO "%s: %s PHY module inserted\n", dev->name,
233 mod_str[pi->phy.modtype]);
234}
235
211static void cxgb_set_rxmode(struct net_device *dev) 236static void cxgb_set_rxmode(struct net_device *dev)
212{ 237{
213 struct t3_rx_mode rm; 238 struct t3_rx_mode rm;
@@ -274,10 +299,10 @@ static void name_msix_vecs(struct adapter *adap)
274 299
275 for (i = 0; i < pi->nqsets; i++, msi_idx++) { 300 for (i = 0; i < pi->nqsets; i++, msi_idx++) {
276 snprintf(adap->msix_info[msi_idx].desc, n, 301 snprintf(adap->msix_info[msi_idx].desc, n,
277 "%s (queue %d)", d->name, i); 302 "%s-%d", d->name, pi->first_qset + i);
278 adap->msix_info[msi_idx].desc[n] = 0; 303 adap->msix_info[msi_idx].desc[n] = 0;
279 } 304 }
280 } 305 }
281} 306}
282 307
283static int request_msix_data_irqs(struct adapter *adap) 308static int request_msix_data_irqs(struct adapter *adap)
@@ -306,6 +331,22 @@ static int request_msix_data_irqs(struct adapter *adap)
306 return 0; 331 return 0;
307} 332}
308 333
334static void free_irq_resources(struct adapter *adapter)
335{
336 if (adapter->flags & USING_MSIX) {
337 int i, n = 0;
338
339 free_irq(adapter->msix_info[0].vec, adapter);
340 for_each_port(adapter, i)
341 n += adap2pinfo(adapter, i)->nqsets;
342
343 for (i = 0; i < n; ++i)
344 free_irq(adapter->msix_info[i + 1].vec,
345 &adapter->sge.qs[i]);
346 } else
347 free_irq(adapter->pdev->irq, adapter);
348}
349
309static int await_mgmt_replies(struct adapter *adap, unsigned long init_cnt, 350static int await_mgmt_replies(struct adapter *adap, unsigned long init_cnt,
310 unsigned long n) 351 unsigned long n)
311{ 352{
@@ -473,12 +514,16 @@ static int setup_sge_qsets(struct adapter *adap)
473 struct port_info *pi = netdev_priv(dev); 514 struct port_info *pi = netdev_priv(dev);
474 515
475 pi->qs = &adap->sge.qs[pi->first_qset]; 516 pi->qs = &adap->sge.qs[pi->first_qset];
476 for (j = 0; j < pi->nqsets; ++j, ++qset_idx) { 517 for (j = pi->first_qset; j < pi->first_qset + pi->nqsets;
518 ++j, ++qset_idx) {
519 if (!pi->rx_csum_offload)
520 adap->params.sge.qset[qset_idx].lro = 0;
477 err = t3_sge_alloc_qset(adap, qset_idx, 1, 521 err = t3_sge_alloc_qset(adap, qset_idx, 1,
478 (adap->flags & USING_MSIX) ? qset_idx + 1 : 522 (adap->flags & USING_MSIX) ? qset_idx + 1 :
479 irq_idx, 523 irq_idx,
480 &adap->params.sge.qset[qset_idx], ntxq, dev); 524 &adap->params.sge.qset[qset_idx], ntxq, dev);
481 if (err) { 525 if (err) {
526 t3_stop_sge_timers(adap);
482 t3_free_sge_resources(adap); 527 t3_free_sge_resources(adap);
483 return err; 528 return err;
484 } 529 }
@@ -739,11 +784,12 @@ static void init_port_mtus(struct adapter *adapter)
739 t3_write_reg(adapter, A_TP_MTU_PORT_TABLE, mtus); 784 t3_write_reg(adapter, A_TP_MTU_PORT_TABLE, mtus);
740} 785}
741 786
742static void send_pktsched_cmd(struct adapter *adap, int sched, int qidx, int lo, 787static int send_pktsched_cmd(struct adapter *adap, int sched, int qidx, int lo,
743 int hi, int port) 788 int hi, int port)
744{ 789{
745 struct sk_buff *skb; 790 struct sk_buff *skb;
746 struct mngt_pktsched_wr *req; 791 struct mngt_pktsched_wr *req;
792 int ret;
747 793
748 skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL); 794 skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL);
749 req = (struct mngt_pktsched_wr *)skb_put(skb, sizeof(*req)); 795 req = (struct mngt_pktsched_wr *)skb_put(skb, sizeof(*req));
@@ -754,20 +800,28 @@ static void send_pktsched_cmd(struct adapter *adap, int sched, int qidx, int lo,
754 req->min = lo; 800 req->min = lo;
755 req->max = hi; 801 req->max = hi;
756 req->binding = port; 802 req->binding = port;
757 t3_mgmt_tx(adap, skb); 803 ret = t3_mgmt_tx(adap, skb);
804
805 return ret;
758} 806}
759 807
760static void bind_qsets(struct adapter *adap) 808static int bind_qsets(struct adapter *adap)
761{ 809{
762 int i, j; 810 int i, j, err = 0;
763 811
764 for_each_port(adap, i) { 812 for_each_port(adap, i) {
765 const struct port_info *pi = adap2pinfo(adap, i); 813 const struct port_info *pi = adap2pinfo(adap, i);
766 814
767 for (j = 0; j < pi->nqsets; ++j) 815 for (j = 0; j < pi->nqsets; ++j) {
768 send_pktsched_cmd(adap, 1, pi->first_qset + j, -1, 816 int ret = send_pktsched_cmd(adap, 1,
769 -1, i); 817 pi->first_qset + j, -1,
818 -1, i);
819 if (ret)
820 err = ret;
821 }
770 } 822 }
823
824 return err;
771} 825}
772 826
773#define FW_FNAME "t3fw-%d.%d.%d.bin" 827#define FW_FNAME "t3fw-%d.%d.%d.bin"
@@ -891,6 +945,13 @@ static int cxgb_up(struct adapter *adap)
891 goto out; 945 goto out;
892 } 946 }
893 947
948 /*
949 * Clear interrupts now to catch errors if t3_init_hw fails.
950 * We clear them again later as initialization may trigger
951 * conditions that can interrupt.
952 */
953 t3_intr_clear(adap);
954
894 err = t3_init_hw(adap, 0); 955 err = t3_init_hw(adap, 0);
895 if (err) 956 if (err)
896 goto out; 957 goto out;
@@ -946,9 +1007,16 @@ static int cxgb_up(struct adapter *adap)
946 t3_write_reg(adap, A_TP_INT_ENABLE, 0x7fbfffff); 1007 t3_write_reg(adap, A_TP_INT_ENABLE, 0x7fbfffff);
947 } 1008 }
948 1009
949 if ((adap->flags & (USING_MSIX | QUEUES_BOUND)) == USING_MSIX) 1010 if (!(adap->flags & QUEUES_BOUND)) {
950 bind_qsets(adap); 1011 err = bind_qsets(adap);
951 adap->flags |= QUEUES_BOUND; 1012 if (err) {
1013 CH_ERR(adap, "failed to bind qsets, err %d\n", err);
1014 t3_intr_disable(adap);
1015 free_irq_resources(adap);
1016 goto out;
1017 }
1018 adap->flags |= QUEUES_BOUND;
1019 }
952 1020
953out: 1021out:
954 return err; 1022 return err;
@@ -967,19 +1035,7 @@ static void cxgb_down(struct adapter *adapter)
967 t3_intr_disable(adapter); 1035 t3_intr_disable(adapter);
968 spin_unlock_irq(&adapter->work_lock); 1036 spin_unlock_irq(&adapter->work_lock);
969 1037
970 if (adapter->flags & USING_MSIX) { 1038 free_irq_resources(adapter);
971 int i, n = 0;
972
973 free_irq(adapter->msix_info[0].vec, adapter);
974 for_each_port(adapter, i)
975 n += adap2pinfo(adapter, i)->nqsets;
976
977 for (i = 0; i < n; ++i)
978 free_irq(adapter->msix_info[i + 1].vec,
979 &adapter->sge.qs[i]);
980 } else
981 free_irq(adapter->pdev->irq, adapter);
982
983 flush_workqueue(cxgb3_wq); /* wait for external IRQ handler */ 1039 flush_workqueue(cxgb3_wq); /* wait for external IRQ handler */
984 quiesce_rx(adapter); 1040 quiesce_rx(adapter);
985} 1041}
@@ -1100,9 +1156,9 @@ static int cxgb_close(struct net_device *dev)
1100 netif_carrier_off(dev); 1156 netif_carrier_off(dev);
1101 t3_mac_disable(&pi->mac, MAC_DIRECTION_TX | MAC_DIRECTION_RX); 1157 t3_mac_disable(&pi->mac, MAC_DIRECTION_TX | MAC_DIRECTION_RX);
1102 1158
1103 spin_lock(&adapter->work_lock); /* sync with update task */ 1159 spin_lock_irq(&adapter->work_lock); /* sync with update task */
1104 clear_bit(pi->port_id, &adapter->open_device_map); 1160 clear_bit(pi->port_id, &adapter->open_device_map);
1105 spin_unlock(&adapter->work_lock); 1161 spin_unlock_irq(&adapter->work_lock);
1106 1162
1107 if (!(adapter->open_device_map & PORT_MASK)) 1163 if (!(adapter->open_device_map & PORT_MASK))
1108 cancel_rearming_delayed_workqueue(cxgb3_wq, 1164 cancel_rearming_delayed_workqueue(cxgb3_wq,
@@ -1284,8 +1340,8 @@ static unsigned long collect_sge_port_stats(struct adapter *adapter,
1284 int i; 1340 int i;
1285 unsigned long tot = 0; 1341 unsigned long tot = 0;
1286 1342
1287 for (i = 0; i < p->nqsets; ++i) 1343 for (i = p->first_qset; i < p->first_qset + p->nqsets; ++i)
1288 tot += adapter->sge.qs[i + p->first_qset].port_stats[idx]; 1344 tot += adapter->sge.qs[i].port_stats[idx];
1289 return tot; 1345 return tot;
1290} 1346}
1291 1347
@@ -1485,11 +1541,22 @@ static int speed_duplex_to_caps(int speed, int duplex)
1485 1541
1486static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd) 1542static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
1487{ 1543{
1544 int cap;
1488 struct port_info *p = netdev_priv(dev); 1545 struct port_info *p = netdev_priv(dev);
1489 struct link_config *lc = &p->link_config; 1546 struct link_config *lc = &p->link_config;
1490 1547
1491 if (!(lc->supported & SUPPORTED_Autoneg)) 1548 if (!(lc->supported & SUPPORTED_Autoneg)) {
1492 return -EOPNOTSUPP; /* can't change speed/duplex */ 1549 /*
1550 * PHY offers a single speed/duplex. See if that's what's
1551 * being requested.
1552 */
1553 if (cmd->autoneg == AUTONEG_DISABLE) {
1554 cap = speed_duplex_to_caps(cmd->speed, cmd->duplex);
1555 if (lc->supported & cap)
1556 return 0;
1557 }
1558 return -EINVAL;
1559 }
1493 1560
1494 if (cmd->autoneg == AUTONEG_DISABLE) { 1561 if (cmd->autoneg == AUTONEG_DISABLE) {
1495 int cap = speed_duplex_to_caps(cmd->speed, cmd->duplex); 1562 int cap = speed_duplex_to_caps(cmd->speed, cmd->duplex);
@@ -1568,8 +1635,10 @@ static int set_rx_csum(struct net_device *dev, u32 data)
1568 struct adapter *adap = p->adapter; 1635 struct adapter *adap = p->adapter;
1569 int i; 1636 int i;
1570 1637
1571 for (i = p->first_qset; i < p->first_qset + p->nqsets; i++) 1638 for (i = p->first_qset; i < p->first_qset + p->nqsets; i++) {
1639 adap->params.sge.qset[i].lro = 0;
1572 adap->sge.qs[i].lro_enabled = 0; 1640 adap->sge.qs[i].lro_enabled = 0;
1641 }
1573 } 1642 }
1574 return 0; 1643 return 0;
1575} 1644}
@@ -1775,6 +1844,8 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
1775 int i; 1844 int i;
1776 struct qset_params *q; 1845 struct qset_params *q;
1777 struct ch_qset_params t; 1846 struct ch_qset_params t;
1847 int q1 = pi->first_qset;
1848 int nqsets = pi->nqsets;
1778 1849
1779 if (!capable(CAP_NET_ADMIN)) 1850 if (!capable(CAP_NET_ADMIN))
1780 return -EPERM; 1851 return -EPERM;
@@ -1797,6 +1868,16 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
1797 || !in_range(t.rspq_size, MIN_RSPQ_ENTRIES, 1868 || !in_range(t.rspq_size, MIN_RSPQ_ENTRIES,
1798 MAX_RSPQ_ENTRIES)) 1869 MAX_RSPQ_ENTRIES))
1799 return -EINVAL; 1870 return -EINVAL;
1871
1872 if ((adapter->flags & FULL_INIT_DONE) && t.lro > 0)
1873 for_each_port(adapter, i) {
1874 pi = adap2pinfo(adapter, i);
1875 if (t.qset_idx >= pi->first_qset &&
1876 t.qset_idx < pi->first_qset + pi->nqsets &&
1877 !pi->rx_csum_offload)
1878 return -EINVAL;
1879 }
1880
1800 if ((adapter->flags & FULL_INIT_DONE) && 1881 if ((adapter->flags & FULL_INIT_DONE) &&
1801 (t.rspq_size >= 0 || t.fl_size[0] >= 0 || 1882 (t.rspq_size >= 0 || t.fl_size[0] >= 0 ||
1802 t.fl_size[1] >= 0 || t.txq_size[0] >= 0 || 1883 t.fl_size[1] >= 0 || t.txq_size[0] >= 0 ||
@@ -1804,6 +1885,20 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
1804 t.polling >= 0 || t.cong_thres >= 0)) 1885 t.polling >= 0 || t.cong_thres >= 0))
1805 return -EBUSY; 1886 return -EBUSY;
1806 1887
1888 /* Allow setting of any available qset when offload enabled */
1889 if (test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map)) {
1890 q1 = 0;
1891 for_each_port(adapter, i) {
1892 pi = adap2pinfo(adapter, i);
1893 nqsets += pi->first_qset + pi->nqsets;
1894 }
1895 }
1896
1897 if (t.qset_idx < q1)
1898 return -EINVAL;
1899 if (t.qset_idx > q1 + nqsets - 1)
1900 return -EINVAL;
1901
1807 q = &adapter->params.sge.qset[t.qset_idx]; 1902 q = &adapter->params.sge.qset[t.qset_idx];
1808 1903
1809 if (t.rspq_size >= 0) 1904 if (t.rspq_size >= 0)
@@ -1853,13 +1948,26 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
1853 case CHELSIO_GET_QSET_PARAMS:{ 1948 case CHELSIO_GET_QSET_PARAMS:{
1854 struct qset_params *q; 1949 struct qset_params *q;
1855 struct ch_qset_params t; 1950 struct ch_qset_params t;
1951 int q1 = pi->first_qset;
1952 int nqsets = pi->nqsets;
1953 int i;
1856 1954
1857 if (copy_from_user(&t, useraddr, sizeof(t))) 1955 if (copy_from_user(&t, useraddr, sizeof(t)))
1858 return -EFAULT; 1956 return -EFAULT;
1859 if (t.qset_idx >= SGE_QSETS) 1957
1958 /* Display qsets for all ports when offload enabled */
1959 if (test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map)) {
1960 q1 = 0;
1961 for_each_port(adapter, i) {
1962 pi = adap2pinfo(adapter, i);
1963 nqsets = pi->first_qset + pi->nqsets;
1964 }
1965 }
1966
1967 if (t.qset_idx >= nqsets)
1860 return -EINVAL; 1968 return -EINVAL;
1861 1969
1862 q = &adapter->params.sge.qset[t.qset_idx]; 1970 q = &adapter->params.sge.qset[q1 + t.qset_idx];
1863 t.rspq_size = q->rspq_size; 1971 t.rspq_size = q->rspq_size;
1864 t.txq_size[0] = q->txq_size[0]; 1972 t.txq_size[0] = q->txq_size[0];
1865 t.txq_size[1] = q->txq_size[1]; 1973 t.txq_size[1] = q->txq_size[1];
@@ -1870,6 +1978,12 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
1870 t.lro = q->lro; 1978 t.lro = q->lro;
1871 t.intr_lat = q->coalesce_usecs; 1979 t.intr_lat = q->coalesce_usecs;
1872 t.cong_thres = q->cong_thres; 1980 t.cong_thres = q->cong_thres;
1981 t.qnum = q1;
1982
1983 if (adapter->flags & USING_MSIX)
1984 t.vector = adapter->msix_info[q1 + t.qset_idx + 1].vec;
1985 else
1986 t.vector = adapter->pdev->irq;
1873 1987
1874 if (copy_to_user(useraddr, &t, sizeof(t))) 1988 if (copy_to_user(useraddr, &t, sizeof(t)))
1875 return -EFAULT; 1989 return -EFAULT;
@@ -2117,7 +2231,7 @@ static int cxgb_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
2117 mmd = data->phy_id >> 8; 2231 mmd = data->phy_id >> 8;
2118 if (!mmd) 2232 if (!mmd)
2119 mmd = MDIO_DEV_PCS; 2233 mmd = MDIO_DEV_PCS;
2120 else if (mmd > MDIO_DEV_XGXS) 2234 else if (mmd > MDIO_DEV_VEND2)
2121 return -EINVAL; 2235 return -EINVAL;
2122 2236
2123 ret = 2237 ret =
@@ -2143,7 +2257,7 @@ static int cxgb_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
2143 mmd = data->phy_id >> 8; 2257 mmd = data->phy_id >> 8;
2144 if (!mmd) 2258 if (!mmd)
2145 mmd = MDIO_DEV_PCS; 2259 mmd = MDIO_DEV_PCS;
2146 else if (mmd > MDIO_DEV_XGXS) 2260 else if (mmd > MDIO_DEV_VEND2)
2147 return -EINVAL; 2261 return -EINVAL;
2148 2262
2149 ret = 2263 ret =
@@ -2215,8 +2329,8 @@ static void t3_synchronize_rx(struct adapter *adap, const struct port_info *p)
2215{ 2329{
2216 int i; 2330 int i;
2217 2331
2218 for (i = 0; i < p->nqsets; i++) { 2332 for (i = p->first_qset; i < p->first_qset + p->nqsets; i++) {
2219 struct sge_rspq *q = &adap->sge.qs[i + p->first_qset].rspq; 2333 struct sge_rspq *q = &adap->sge.qs[i].rspq;
2220 2334
2221 spin_lock_irq(&q->lock); 2335 spin_lock_irq(&q->lock);
2222 spin_unlock_irq(&q->lock); 2336 spin_unlock_irq(&q->lock);
@@ -2290,7 +2404,7 @@ static void check_link_status(struct adapter *adapter)
2290 struct net_device *dev = adapter->port[i]; 2404 struct net_device *dev = adapter->port[i];
2291 struct port_info *p = netdev_priv(dev); 2405 struct port_info *p = netdev_priv(dev);
2292 2406
2293 if (!(p->port_type->caps & SUPPORTED_IRQ) && netif_running(dev)) 2407 if (!(p->phy.caps & SUPPORTED_IRQ) && netif_running(dev))
2294 t3_link_changed(adapter, i); 2408 t3_link_changed(adapter, i);
2295 } 2409 }
2296} 2410}
@@ -2355,10 +2469,10 @@ static void t3_adap_check_task(struct work_struct *work)
2355 check_t3b2_mac(adapter); 2469 check_t3b2_mac(adapter);
2356 2470
2357 /* Schedule the next check update if any port is active. */ 2471 /* Schedule the next check update if any port is active. */
2358 spin_lock(&adapter->work_lock); 2472 spin_lock_irq(&adapter->work_lock);
2359 if (adapter->open_device_map & PORT_MASK) 2473 if (adapter->open_device_map & PORT_MASK)
2360 schedule_chk_task(adapter); 2474 schedule_chk_task(adapter);
2361 spin_unlock(&adapter->work_lock); 2475 spin_unlock_irq(&adapter->work_lock);
2362} 2476}
2363 2477
2364/* 2478/*
@@ -2403,6 +2517,96 @@ void t3_os_ext_intr_handler(struct adapter *adapter)
2403 spin_unlock(&adapter->work_lock); 2517 spin_unlock(&adapter->work_lock);
2404} 2518}
2405 2519
2520static int t3_adapter_error(struct adapter *adapter, int reset)
2521{
2522 int i, ret = 0;
2523
2524 /* Stop all ports */
2525 for_each_port(adapter, i) {
2526 struct net_device *netdev = adapter->port[i];
2527
2528 if (netif_running(netdev))
2529 cxgb_close(netdev);
2530 }
2531
2532 if (is_offload(adapter) &&
2533 test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map))
2534 offload_close(&adapter->tdev);
2535
2536 /* Stop SGE timers */
2537 t3_stop_sge_timers(adapter);
2538
2539 adapter->flags &= ~FULL_INIT_DONE;
2540
2541 if (reset)
2542 ret = t3_reset_adapter(adapter);
2543
2544 pci_disable_device(adapter->pdev);
2545
2546 return ret;
2547}
2548
2549static int t3_reenable_adapter(struct adapter *adapter)
2550{
2551 if (pci_enable_device(adapter->pdev)) {
2552 dev_err(&adapter->pdev->dev,
2553 "Cannot re-enable PCI device after reset.\n");
2554 goto err;
2555 }
2556 pci_set_master(adapter->pdev);
2557 pci_restore_state(adapter->pdev);
2558
2559 /* Free sge resources */
2560 t3_free_sge_resources(adapter);
2561
2562 if (t3_replay_prep_adapter(adapter))
2563 goto err;
2564
2565 return 0;
2566err:
2567 return -1;
2568}
2569
2570static void t3_resume_ports(struct adapter *adapter)
2571{
2572 int i;
2573
2574 /* Restart the ports */
2575 for_each_port(adapter, i) {
2576 struct net_device *netdev = adapter->port[i];
2577
2578 if (netif_running(netdev)) {
2579 if (cxgb_open(netdev)) {
2580 dev_err(&adapter->pdev->dev,
2581 "can't bring device back up"
2582 " after reset\n");
2583 continue;
2584 }
2585 }
2586 }
2587}
2588
2589/*
2590 * processes a fatal error.
2591 * Bring the ports down, reset the chip, bring the ports back up.
2592 */
2593static void fatal_error_task(struct work_struct *work)
2594{
2595 struct adapter *adapter = container_of(work, struct adapter,
2596 fatal_error_handler_task);
2597 int err = 0;
2598
2599 rtnl_lock();
2600 err = t3_adapter_error(adapter, 1);
2601 if (!err)
2602 err = t3_reenable_adapter(adapter);
2603 if (!err)
2604 t3_resume_ports(adapter);
2605
2606 CH_ALERT(adapter, "adapter reset %s\n", err ? "failed" : "succeeded");
2607 rtnl_unlock();
2608}
2609
2406void t3_fatal_err(struct adapter *adapter) 2610void t3_fatal_err(struct adapter *adapter)
2407{ 2611{
2408 unsigned int fw_status[4]; 2612 unsigned int fw_status[4];
@@ -2413,7 +2617,11 @@ void t3_fatal_err(struct adapter *adapter)
2413 t3_write_reg(adapter, A_XGM_RX_CTRL, 0); 2617 t3_write_reg(adapter, A_XGM_RX_CTRL, 0);
2414 t3_write_reg(adapter, XGM_REG(A_XGM_TX_CTRL, 1), 0); 2618 t3_write_reg(adapter, XGM_REG(A_XGM_TX_CTRL, 1), 0);
2415 t3_write_reg(adapter, XGM_REG(A_XGM_RX_CTRL, 1), 0); 2619 t3_write_reg(adapter, XGM_REG(A_XGM_RX_CTRL, 1), 0);
2620
2621 spin_lock(&adapter->work_lock);
2416 t3_intr_disable(adapter); 2622 t3_intr_disable(adapter);
2623 queue_work(cxgb3_wq, &adapter->fatal_error_handler_task);
2624 spin_unlock(&adapter->work_lock);
2417 } 2625 }
2418 CH_ALERT(adapter, "encountered fatal error, operation suspended\n"); 2626 CH_ALERT(adapter, "encountered fatal error, operation suspended\n");
2419 if (!t3_cim_ctl_blk_read(adapter, 0xa0, 4, fw_status)) 2627 if (!t3_cim_ctl_blk_read(adapter, 0xa0, 4, fw_status))
@@ -2435,23 +2643,9 @@ static pci_ers_result_t t3_io_error_detected(struct pci_dev *pdev,
2435 pci_channel_state_t state) 2643 pci_channel_state_t state)
2436{ 2644{
2437 struct adapter *adapter = pci_get_drvdata(pdev); 2645 struct adapter *adapter = pci_get_drvdata(pdev);
2438 int i; 2646 int ret;
2439
2440 /* Stop all ports */
2441 for_each_port(adapter, i) {
2442 struct net_device *netdev = adapter->port[i];
2443
2444 if (netif_running(netdev))
2445 cxgb_close(netdev);
2446 }
2447
2448 if (is_offload(adapter) &&
2449 test_bit(OFFLOAD_DEVMAP_BIT, &adapter->open_device_map))
2450 offload_close(&adapter->tdev);
2451
2452 adapter->flags &= ~FULL_INIT_DONE;
2453 2647
2454 pci_disable_device(pdev); 2648 ret = t3_adapter_error(adapter, 0);
2455 2649
2456 /* Request a slot reset. */ 2650 /* Request a slot reset. */
2457 return PCI_ERS_RESULT_NEED_RESET; 2651 return PCI_ERS_RESULT_NEED_RESET;
@@ -2467,22 +2661,9 @@ static pci_ers_result_t t3_io_slot_reset(struct pci_dev *pdev)
2467{ 2661{
2468 struct adapter *adapter = pci_get_drvdata(pdev); 2662 struct adapter *adapter = pci_get_drvdata(pdev);
2469 2663
2470 if (pci_enable_device(pdev)) { 2664 if (!t3_reenable_adapter(adapter))
2471 dev_err(&pdev->dev, 2665 return PCI_ERS_RESULT_RECOVERED;
2472 "Cannot re-enable PCI device after reset.\n");
2473 goto err;
2474 }
2475 pci_set_master(pdev);
2476 pci_restore_state(pdev);
2477
2478 /* Free sge resources */
2479 t3_free_sge_resources(adapter);
2480
2481 if (t3_replay_prep_adapter(adapter))
2482 goto err;
2483 2666
2484 return PCI_ERS_RESULT_RECOVERED;
2485err:
2486 return PCI_ERS_RESULT_DISCONNECT; 2667 return PCI_ERS_RESULT_DISCONNECT;
2487} 2668}
2488 2669
@@ -2496,22 +2677,8 @@ err:
2496static void t3_io_resume(struct pci_dev *pdev) 2677static void t3_io_resume(struct pci_dev *pdev)
2497{ 2678{
2498 struct adapter *adapter = pci_get_drvdata(pdev); 2679 struct adapter *adapter = pci_get_drvdata(pdev);
2499 int i;
2500 2680
2501 /* Restart the ports */ 2681 t3_resume_ports(adapter);
2502 for_each_port(adapter, i) {
2503 struct net_device *netdev = adapter->port[i];
2504
2505 if (netif_running(netdev)) {
2506 if (cxgb_open(netdev)) {
2507 dev_err(&pdev->dev,
2508 "can't bring device back up"
2509 " after reset\n");
2510 continue;
2511 }
2512 netif_device_attach(netdev);
2513 }
2514 }
2515} 2682}
2516 2683
2517static struct pci_error_handlers t3_err_handler = { 2684static struct pci_error_handlers t3_err_handler = {
@@ -2520,6 +2687,42 @@ static struct pci_error_handlers t3_err_handler = {
2520 .resume = t3_io_resume, 2687 .resume = t3_io_resume,
2521}; 2688};
2522 2689
2690/*
2691 * Set the number of qsets based on the number of CPUs and the number of ports,
2692 * not to exceed the number of available qsets, assuming there are enough qsets
2693 * per port in HW.
2694 */
2695static void set_nqsets(struct adapter *adap)
2696{
2697 int i, j = 0;
2698 int num_cpus = num_online_cpus();
2699 int hwports = adap->params.nports;
2700 int nqsets = SGE_QSETS;
2701
2702 if (adap->params.rev > 0) {
2703 if (hwports == 2 &&
2704 (hwports * nqsets > SGE_QSETS ||
2705 num_cpus >= nqsets / hwports))
2706 nqsets /= hwports;
2707 if (nqsets > num_cpus)
2708 nqsets = num_cpus;
2709 if (nqsets < 1 || hwports == 4)
2710 nqsets = 1;
2711 } else
2712 nqsets = 1;
2713
2714 for_each_port(adap, i) {
2715 struct port_info *pi = adap2pinfo(adap, i);
2716
2717 pi->first_qset = j;
2718 pi->nqsets = nqsets;
2719 j = pi->first_qset + nqsets;
2720
2721 dev_info(&adap->pdev->dev,
2722 "Port %d using %d queue sets.\n", i, nqsets);
2723 }
2724}
2725
2523static int __devinit cxgb_enable_msix(struct adapter *adap) 2726static int __devinit cxgb_enable_msix(struct adapter *adap)
2524{ 2727{
2525 struct msix_entry entries[SGE_QSETS + 1]; 2728 struct msix_entry entries[SGE_QSETS + 1];
@@ -2564,7 +2767,7 @@ static void __devinit print_port_info(struct adapter *adap,
2564 if (!test_bit(i, &adap->registered_device_map)) 2767 if (!test_bit(i, &adap->registered_device_map))
2565 continue; 2768 continue;
2566 printk(KERN_INFO "%s: %s %s %sNIC (rev %d) %s%s\n", 2769 printk(KERN_INFO "%s: %s %s %sNIC (rev %d) %s%s\n",
2567 dev->name, ai->desc, pi->port_type->desc, 2770 dev->name, ai->desc, pi->phy.desc,
2568 is_offload(adap) ? "R" : "", adap->params.rev, buf, 2771 is_offload(adap) ? "R" : "", adap->params.rev, buf,
2569 (adap->flags & USING_MSIX) ? " MSI-X" : 2772 (adap->flags & USING_MSIX) ? " MSI-X" :
2570 (adap->flags & USING_MSI) ? " MSI" : ""); 2773 (adap->flags & USING_MSI) ? " MSI" : "");
@@ -2660,6 +2863,7 @@ static int __devinit init_one(struct pci_dev *pdev,
2660 2863
2661 INIT_LIST_HEAD(&adapter->adapter_list); 2864 INIT_LIST_HEAD(&adapter->adapter_list);
2662 INIT_WORK(&adapter->ext_intr_handler_task, ext_intr_task); 2865 INIT_WORK(&adapter->ext_intr_handler_task, ext_intr_task);
2866 INIT_WORK(&adapter->fatal_error_handler_task, fatal_error_task);
2663 INIT_DELAYED_WORK(&adapter->adap_check_task, t3_adap_check_task); 2867 INIT_DELAYED_WORK(&adapter->adap_check_task, t3_adap_check_task);
2664 2868
2665 for (i = 0; i < ai->nports; ++i) { 2869 for (i = 0; i < ai->nports; ++i) {
@@ -2677,9 +2881,6 @@ static int __devinit init_one(struct pci_dev *pdev,
2677 pi = netdev_priv(netdev); 2881 pi = netdev_priv(netdev);
2678 pi->adapter = adapter; 2882 pi->adapter = adapter;
2679 pi->rx_csum_offload = 1; 2883 pi->rx_csum_offload = 1;
2680 pi->nqsets = 1;
2681 pi->first_qset = i;
2682 pi->activity = 0;
2683 pi->port_id = i; 2884 pi->port_id = i;
2684 netif_carrier_off(netdev); 2885 netif_carrier_off(netdev);
2685 netdev->irq = pdev->irq; 2886 netdev->irq = pdev->irq;
@@ -2756,6 +2957,8 @@ static int __devinit init_one(struct pci_dev *pdev,
2756 else if (msi > 0 && pci_enable_msi(pdev) == 0) 2957 else if (msi > 0 && pci_enable_msi(pdev) == 0)
2757 adapter->flags |= USING_MSI; 2958 adapter->flags |= USING_MSI;
2758 2959
2960 set_nqsets(adapter);
2961
2759 err = sysfs_create_group(&adapter->port[0]->dev.kobj, 2962 err = sysfs_create_group(&adapter->port[0]->dev.kobj,
2760 &cxgb3_attr_group); 2963 &cxgb3_attr_group);
2761 2964
@@ -2801,6 +3004,7 @@ static void __devexit remove_one(struct pci_dev *pdev)
2801 if (test_bit(i, &adapter->registered_device_map)) 3004 if (test_bit(i, &adapter->registered_device_map))
2802 unregister_netdev(adapter->port[i]); 3005 unregister_netdev(adapter->port[i]);
2803 3006
3007 t3_stop_sge_timers(adapter);
2804 t3_free_sge_resources(adapter); 3008 t3_free_sge_resources(adapter);
2805 cxgb_disable_msi(adapter); 3009 cxgb_disable_msi(adapter);
2806 3010
diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c
index c5b3de1bb456..265aa8a15afa 100644
--- a/drivers/net/cxgb3/cxgb3_offload.c
+++ b/drivers/net/cxgb3/cxgb3_offload.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2006-2007 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2006-2008 Chelsio, Inc. All rights reserved.
3 * 3 *
4 * This software is available to you under a choice of one of two 4 * 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 5 * licenses. You may choose to be licensed under the terms of the GNU
@@ -1018,7 +1018,7 @@ static void set_l2t_ix(struct t3cdev *tdev, u32 tid, struct l2t_entry *e)
1018 1018
1019 skb = alloc_skb(sizeof(*req), GFP_ATOMIC); 1019 skb = alloc_skb(sizeof(*req), GFP_ATOMIC);
1020 if (!skb) { 1020 if (!skb) {
1021 printk(KERN_ERR "%s: cannot allocate skb!\n", __FUNCTION__); 1021 printk(KERN_ERR "%s: cannot allocate skb!\n", __func__);
1022 return; 1022 return;
1023 } 1023 }
1024 skb->priority = CPL_PRIORITY_CONTROL; 1024 skb->priority = CPL_PRIORITY_CONTROL;
@@ -1049,14 +1049,14 @@ void cxgb_redirect(struct dst_entry *old, struct dst_entry *new)
1049 return; 1049 return;
1050 if (!is_offloading(newdev)) { 1050 if (!is_offloading(newdev)) {
1051 printk(KERN_WARNING "%s: Redirect to non-offload " 1051 printk(KERN_WARNING "%s: Redirect to non-offload "
1052 "device ignored.\n", __FUNCTION__); 1052 "device ignored.\n", __func__);
1053 return; 1053 return;
1054 } 1054 }
1055 tdev = dev2t3cdev(olddev); 1055 tdev = dev2t3cdev(olddev);
1056 BUG_ON(!tdev); 1056 BUG_ON(!tdev);
1057 if (tdev != dev2t3cdev(newdev)) { 1057 if (tdev != dev2t3cdev(newdev)) {
1058 printk(KERN_WARNING "%s: Redirect to different " 1058 printk(KERN_WARNING "%s: Redirect to different "
1059 "offload device ignored.\n", __FUNCTION__); 1059 "offload device ignored.\n", __func__);
1060 return; 1060 return;
1061 } 1061 }
1062 1062
@@ -1064,7 +1064,7 @@ void cxgb_redirect(struct dst_entry *old, struct dst_entry *new)
1064 e = t3_l2t_get(tdev, new->neighbour, newdev); 1064 e = t3_l2t_get(tdev, new->neighbour, newdev);
1065 if (!e) { 1065 if (!e) {
1066 printk(KERN_ERR "%s: couldn't allocate new l2t entry!\n", 1066 printk(KERN_ERR "%s: couldn't allocate new l2t entry!\n",
1067 __FUNCTION__); 1067 __func__);
1068 return; 1068 return;
1069 } 1069 }
1070 1070
diff --git a/drivers/net/cxgb3/cxgb3_offload.h b/drivers/net/cxgb3/cxgb3_offload.h
index 7a379138b5a6..d514e5019dfc 100644
--- a/drivers/net/cxgb3/cxgb3_offload.h
+++ b/drivers/net/cxgb3/cxgb3_offload.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2006-2007 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2006-2008 Chelsio, Inc. All rights reserved.
3 * 3 *
4 * This software is available to you under a choice of one of two 4 * 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 5 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/net/cxgb3/firmware_exports.h b/drivers/net/cxgb3/firmware_exports.h
index b75ddd8777fe..0d9b0e6dccff 100644
--- a/drivers/net/cxgb3/firmware_exports.h
+++ b/drivers/net/cxgb3/firmware_exports.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2004-2007 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2004-2008 Chelsio, Inc. All rights reserved.
3 * 3 *
4 * This software is available to you under a choice of one of two 4 * 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 5 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/net/cxgb3/l2t.c b/drivers/net/cxgb3/l2t.c
index 825e510bd9ed..4407ac9bb555 100644
--- a/drivers/net/cxgb3/l2t.c
+++ b/drivers/net/cxgb3/l2t.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2003-2007 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2003-2008 Chelsio, Inc. All rights reserved.
3 * 3 *
4 * This software is available to you under a choice of one of two 4 * 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 5 * licenses. You may choose to be licensed under the terms of the GNU
@@ -86,6 +86,7 @@ static int setup_l2e_send_pending(struct t3cdev *dev, struct sk_buff *skb,
86 struct l2t_entry *e) 86 struct l2t_entry *e)
87{ 87{
88 struct cpl_l2t_write_req *req; 88 struct cpl_l2t_write_req *req;
89 struct sk_buff *tmp;
89 90
90 if (!skb) { 91 if (!skb) {
91 skb = alloc_skb(sizeof(*req), GFP_ATOMIC); 92 skb = alloc_skb(sizeof(*req), GFP_ATOMIC);
@@ -103,13 +104,11 @@ static int setup_l2e_send_pending(struct t3cdev *dev, struct sk_buff *skb,
103 memcpy(req->dst_mac, e->dmac, sizeof(req->dst_mac)); 104 memcpy(req->dst_mac, e->dmac, sizeof(req->dst_mac));
104 skb->priority = CPL_PRIORITY_CONTROL; 105 skb->priority = CPL_PRIORITY_CONTROL;
105 cxgb3_ofld_send(dev, skb); 106 cxgb3_ofld_send(dev, skb);
106 while (e->arpq_head) { 107
107 skb = e->arpq_head; 108 skb_queue_walk_safe(&e->arpq, skb, tmp) {
108 e->arpq_head = skb->next; 109 __skb_unlink(skb, &e->arpq);
109 skb->next = NULL;
110 cxgb3_ofld_send(dev, skb); 110 cxgb3_ofld_send(dev, skb);
111 } 111 }
112 e->arpq_tail = NULL;
113 e->state = L2T_STATE_VALID; 112 e->state = L2T_STATE_VALID;
114 113
115 return 0; 114 return 0;
@@ -121,12 +120,7 @@ static int setup_l2e_send_pending(struct t3cdev *dev, struct sk_buff *skb,
121 */ 120 */
122static inline void arpq_enqueue(struct l2t_entry *e, struct sk_buff *skb) 121static inline void arpq_enqueue(struct l2t_entry *e, struct sk_buff *skb)
123{ 122{
124 skb->next = NULL; 123 __skb_queue_tail(&e->arpq, skb);
125 if (e->arpq_head)
126 e->arpq_tail->next = skb;
127 else
128 e->arpq_head = skb;
129 e->arpq_tail = skb;
130} 124}
131 125
132int t3_l2t_send_slow(struct t3cdev *dev, struct sk_buff *skb, 126int t3_l2t_send_slow(struct t3cdev *dev, struct sk_buff *skb,
@@ -167,7 +161,7 @@ again:
167 break; 161 break;
168 162
169 spin_lock_bh(&e->lock); 163 spin_lock_bh(&e->lock);
170 if (e->arpq_head) 164 if (!skb_queue_empty(&e->arpq))
171 setup_l2e_send_pending(dev, skb, e); 165 setup_l2e_send_pending(dev, skb, e);
172 else /* we lost the race */ 166 else /* we lost the race */
173 __kfree_skb(skb); 167 __kfree_skb(skb);
@@ -357,14 +351,14 @@ EXPORT_SYMBOL(t3_l2t_get);
357 * XXX: maybe we should abandon the latter behavior and just require a failure 351 * XXX: maybe we should abandon the latter behavior and just require a failure
358 * handler. 352 * handler.
359 */ 353 */
360static void handle_failed_resolution(struct t3cdev *dev, struct sk_buff *arpq) 354static void handle_failed_resolution(struct t3cdev *dev, struct sk_buff_head *arpq)
361{ 355{
362 while (arpq) { 356 struct sk_buff *skb, *tmp;
363 struct sk_buff *skb = arpq; 357
358 skb_queue_walk_safe(arpq, skb, tmp) {
364 struct l2t_skb_cb *cb = L2T_SKB_CB(skb); 359 struct l2t_skb_cb *cb = L2T_SKB_CB(skb);
365 360
366 arpq = skb->next; 361 __skb_unlink(skb, arpq);
367 skb->next = NULL;
368 if (cb->arp_failure_handler) 362 if (cb->arp_failure_handler)
369 cb->arp_failure_handler(dev, skb); 363 cb->arp_failure_handler(dev, skb);
370 else 364 else
@@ -378,8 +372,8 @@ static void handle_failed_resolution(struct t3cdev *dev, struct sk_buff *arpq)
378 */ 372 */
379void t3_l2t_update(struct t3cdev *dev, struct neighbour *neigh) 373void t3_l2t_update(struct t3cdev *dev, struct neighbour *neigh)
380{ 374{
375 struct sk_buff_head arpq;
381 struct l2t_entry *e; 376 struct l2t_entry *e;
382 struct sk_buff *arpq = NULL;
383 struct l2t_data *d = L2DATA(dev); 377 struct l2t_data *d = L2DATA(dev);
384 u32 addr = *(u32 *) neigh->primary_key; 378 u32 addr = *(u32 *) neigh->primary_key;
385 int ifidx = neigh->dev->ifindex; 379 int ifidx = neigh->dev->ifindex;
@@ -395,6 +389,8 @@ void t3_l2t_update(struct t3cdev *dev, struct neighbour *neigh)
395 return; 389 return;
396 390
397found: 391found:
392 __skb_queue_head_init(&arpq);
393
398 read_unlock(&d->lock); 394 read_unlock(&d->lock);
399 if (atomic_read(&e->refcnt)) { 395 if (atomic_read(&e->refcnt)) {
400 if (neigh != e->neigh) 396 if (neigh != e->neigh)
@@ -402,8 +398,7 @@ found:
402 398
403 if (e->state == L2T_STATE_RESOLVING) { 399 if (e->state == L2T_STATE_RESOLVING) {
404 if (neigh->nud_state & NUD_FAILED) { 400 if (neigh->nud_state & NUD_FAILED) {
405 arpq = e->arpq_head; 401 skb_queue_splice_init(&e->arpq, &arpq);
406 e->arpq_head = e->arpq_tail = NULL;
407 } else if (neigh->nud_state & (NUD_CONNECTED|NUD_STALE)) 402 } else if (neigh->nud_state & (NUD_CONNECTED|NUD_STALE))
408 setup_l2e_send_pending(dev, NULL, e); 403 setup_l2e_send_pending(dev, NULL, e);
409 } else { 404 } else {
@@ -415,8 +410,8 @@ found:
415 } 410 }
416 spin_unlock_bh(&e->lock); 411 spin_unlock_bh(&e->lock);
417 412
418 if (arpq) 413 if (!skb_queue_empty(&arpq))
419 handle_failed_resolution(dev, arpq); 414 handle_failed_resolution(dev, &arpq);
420} 415}
421 416
422struct l2t_data *t3_init_l2t(unsigned int l2t_capacity) 417struct l2t_data *t3_init_l2t(unsigned int l2t_capacity)
diff --git a/drivers/net/cxgb3/l2t.h b/drivers/net/cxgb3/l2t.h
index d79001336cfd..fd3eb07e3f40 100644
--- a/drivers/net/cxgb3/l2t.h
+++ b/drivers/net/cxgb3/l2t.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2003-2007 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2003-2008 Chelsio, Inc. All rights reserved.
3 * 3 *
4 * This software is available to you under a choice of one of two 4 * 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 5 * licenses. You may choose to be licensed under the terms of the GNU
@@ -64,8 +64,7 @@ struct l2t_entry {
64 struct neighbour *neigh; /* associated neighbour */ 64 struct neighbour *neigh; /* associated neighbour */
65 struct l2t_entry *first; /* start of hash chain */ 65 struct l2t_entry *first; /* start of hash chain */
66 struct l2t_entry *next; /* next l2t_entry on chain */ 66 struct l2t_entry *next; /* next l2t_entry on chain */
67 struct sk_buff *arpq_head; /* queue of packets awaiting resolution */ 67 struct sk_buff_head arpq; /* queue of packets awaiting resolution */
68 struct sk_buff *arpq_tail;
69 spinlock_t lock; 68 spinlock_t lock;
70 atomic_t refcnt; /* entry reference count */ 69 atomic_t refcnt; /* entry reference count */
71 u8 dmac[6]; /* neighbour's MAC address */ 70 u8 dmac[6]; /* neighbour's MAC address */
diff --git a/drivers/net/cxgb3/mc5.c b/drivers/net/cxgb3/mc5.c
index 4c4d6e877ea6..3b5517b8fbde 100644
--- a/drivers/net/cxgb3/mc5.c
+++ b/drivers/net/cxgb3/mc5.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2003-2007 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2003-2008 Chelsio, Inc. All rights reserved.
3 * 3 *
4 * This software is available to you under a choice of one of two 4 * 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 5 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/net/cxgb3/regs.h b/drivers/net/cxgb3/regs.h
index 4bda27c551c9..a035d5c24442 100644
--- a/drivers/net/cxgb3/regs.h
+++ b/drivers/net/cxgb3/regs.h
@@ -573,6 +573,10 @@
573#define V_GPIO10(x) ((x) << S_GPIO10) 573#define V_GPIO10(x) ((x) << S_GPIO10)
574#define F_GPIO10 V_GPIO10(1U) 574#define F_GPIO10 V_GPIO10(1U)
575 575
576#define S_GPIO9 9
577#define V_GPIO9(x) ((x) << S_GPIO9)
578#define F_GPIO9 V_GPIO9(1U)
579
576#define S_GPIO7 7 580#define S_GPIO7 7
577#define V_GPIO7(x) ((x) << S_GPIO7) 581#define V_GPIO7(x) ((x) << S_GPIO7)
578#define F_GPIO7 V_GPIO7(1U) 582#define F_GPIO7 V_GPIO7(1U)
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index 1b0861d73ab7..c6480be0bc1f 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2005-2007 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2005-2008 Chelsio, Inc. All rights reserved.
3 * 3 *
4 * This software is available to you under a choice of one of two 4 * 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 5 * licenses. You may choose to be licensed under the terms of the GNU
@@ -351,7 +351,8 @@ static void free_rx_bufs(struct pci_dev *pdev, struct sge_fl *q)
351 pci_unmap_single(pdev, pci_unmap_addr(d, dma_addr), 351 pci_unmap_single(pdev, pci_unmap_addr(d, dma_addr),
352 q->buf_size, PCI_DMA_FROMDEVICE); 352 q->buf_size, PCI_DMA_FROMDEVICE);
353 if (q->use_pages) { 353 if (q->use_pages) {
354 put_page(d->pg_chunk.page); 354 if (d->pg_chunk.page)
355 put_page(d->pg_chunk.page);
355 d->pg_chunk.page = NULL; 356 d->pg_chunk.page = NULL;
356 } else { 357 } else {
357 kfree_skb(d->skb); 358 kfree_skb(d->skb);
@@ -583,7 +584,7 @@ static void t3_reset_qset(struct sge_qset *q)
583 memset(q->fl, 0, sizeof(struct sge_fl) * SGE_RXQ_PER_SET); 584 memset(q->fl, 0, sizeof(struct sge_fl) * SGE_RXQ_PER_SET);
584 memset(q->txq, 0, sizeof(struct sge_txq) * SGE_TXQ_PER_SET); 585 memset(q->txq, 0, sizeof(struct sge_txq) * SGE_TXQ_PER_SET);
585 q->txq_stopped = 0; 586 q->txq_stopped = 0;
586 memset(&q->tx_reclaim_timer, 0, sizeof(q->tx_reclaim_timer)); 587 q->tx_reclaim_timer.function = NULL; /* for t3_stop_sge_timers() */
587 kfree(q->lro_frag_tbl); 588 kfree(q->lro_frag_tbl);
588 q->lro_nfrags = q->lro_frag_len = 0; 589 q->lro_nfrags = q->lro_frag_len = 0;
589} 590}
@@ -603,9 +604,6 @@ static void t3_free_qset(struct adapter *adapter, struct sge_qset *q)
603 int i; 604 int i;
604 struct pci_dev *pdev = adapter->pdev; 605 struct pci_dev *pdev = adapter->pdev;
605 606
606 if (q->tx_reclaim_timer.function)
607 del_timer_sync(&q->tx_reclaim_timer);
608
609 for (i = 0; i < SGE_RXQ_PER_SET; ++i) 607 for (i = 0; i < SGE_RXQ_PER_SET; ++i)
610 if (q->fl[i].desc) { 608 if (q->fl[i].desc) {
611 spin_lock_irq(&adapter->sge.reg_lock); 609 spin_lock_irq(&adapter->sge.reg_lock);
@@ -1704,16 +1702,15 @@ int t3_offload_tx(struct t3cdev *tdev, struct sk_buff *skb)
1704 */ 1702 */
1705static inline void offload_enqueue(struct sge_rspq *q, struct sk_buff *skb) 1703static inline void offload_enqueue(struct sge_rspq *q, struct sk_buff *skb)
1706{ 1704{
1707 skb->next = skb->prev = NULL; 1705 int was_empty = skb_queue_empty(&q->rx_queue);
1708 if (q->rx_tail) 1706
1709 q->rx_tail->next = skb; 1707 __skb_queue_tail(&q->rx_queue, skb);
1710 else { 1708
1709 if (was_empty) {
1711 struct sge_qset *qs = rspq_to_qset(q); 1710 struct sge_qset *qs = rspq_to_qset(q);
1712 1711
1713 napi_schedule(&qs->napi); 1712 napi_schedule(&qs->napi);
1714 q->rx_head = skb;
1715 } 1713 }
1716 q->rx_tail = skb;
1717} 1714}
1718 1715
1719/** 1716/**
@@ -1754,26 +1751,29 @@ static int ofld_poll(struct napi_struct *napi, int budget)
1754 int work_done = 0; 1751 int work_done = 0;
1755 1752
1756 while (work_done < budget) { 1753 while (work_done < budget) {
1757 struct sk_buff *head, *tail, *skbs[RX_BUNDLE_SIZE]; 1754 struct sk_buff *skb, *tmp, *skbs[RX_BUNDLE_SIZE];
1755 struct sk_buff_head queue;
1758 int ngathered; 1756 int ngathered;
1759 1757
1760 spin_lock_irq(&q->lock); 1758 spin_lock_irq(&q->lock);
1761 head = q->rx_head; 1759 __skb_queue_head_init(&queue);
1762 if (!head) { 1760 skb_queue_splice_init(&q->rx_queue, &queue);
1761 if (skb_queue_empty(&queue)) {
1763 napi_complete(napi); 1762 napi_complete(napi);
1764 spin_unlock_irq(&q->lock); 1763 spin_unlock_irq(&q->lock);
1765 return work_done; 1764 return work_done;
1766 } 1765 }
1767
1768 tail = q->rx_tail;
1769 q->rx_head = q->rx_tail = NULL;
1770 spin_unlock_irq(&q->lock); 1766 spin_unlock_irq(&q->lock);
1771 1767
1772 for (ngathered = 0; work_done < budget && head; work_done++) { 1768 ngathered = 0;
1773 prefetch(head->data); 1769 skb_queue_walk_safe(&queue, skb, tmp) {
1774 skbs[ngathered] = head; 1770 if (work_done >= budget)
1775 head = head->next; 1771 break;
1776 skbs[ngathered]->next = NULL; 1772 work_done++;
1773
1774 __skb_unlink(skb, &queue);
1775 prefetch(skb->data);
1776 skbs[ngathered] = skb;
1777 if (++ngathered == RX_BUNDLE_SIZE) { 1777 if (++ngathered == RX_BUNDLE_SIZE) {
1778 q->offload_bundles++; 1778 q->offload_bundles++;
1779 adapter->tdev.recv(&adapter->tdev, skbs, 1779 adapter->tdev.recv(&adapter->tdev, skbs,
@@ -1781,12 +1781,10 @@ static int ofld_poll(struct napi_struct *napi, int budget)
1781 ngathered = 0; 1781 ngathered = 0;
1782 } 1782 }
1783 } 1783 }
1784 if (head) { /* splice remaining packets back onto Rx queue */ 1784 if (!skb_queue_empty(&queue)) {
1785 /* splice remaining packets back onto Rx queue */
1785 spin_lock_irq(&q->lock); 1786 spin_lock_irq(&q->lock);
1786 tail->next = q->rx_head; 1787 skb_queue_splice(&queue, &q->rx_queue);
1787 if (!q->rx_head)
1788 q->rx_tail = tail;
1789 q->rx_head = head;
1790 spin_unlock_irq(&q->lock); 1788 spin_unlock_irq(&q->lock);
1791 } 1789 }
1792 deliver_partial_bundle(&adapter->tdev, q, skbs, ngathered); 1790 deliver_partial_bundle(&adapter->tdev, q, skbs, ngathered);
@@ -1937,38 +1935,6 @@ static inline int lro_frame_ok(const struct cpl_rx_pkt *p)
1937 eh->h_proto == htons(ETH_P_IP) && ih->ihl == (sizeof(*ih) >> 2); 1935 eh->h_proto == htons(ETH_P_IP) && ih->ihl == (sizeof(*ih) >> 2);
1938} 1936}
1939 1937
1940#define TCP_FLAG_MASK (TCP_FLAG_CWR | TCP_FLAG_ECE | TCP_FLAG_URG |\
1941 TCP_FLAG_ACK | TCP_FLAG_PSH | TCP_FLAG_RST |\
1942 TCP_FLAG_SYN | TCP_FLAG_FIN)
1943#define TSTAMP_WORD ((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |\
1944 (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)
1945
1946/**
1947 * lro_segment_ok - check if a TCP segment is eligible for LRO
1948 * @tcph: the TCP header of the packet
1949 *
1950 * Returns true if a TCP packet is eligible for LRO. This requires that
1951 * the packet have only the ACK flag set and no TCP options besides
1952 * time stamps.
1953 */
1954static inline int lro_segment_ok(const struct tcphdr *tcph)
1955{
1956 int optlen;
1957
1958 if (unlikely((tcp_flag_word(tcph) & TCP_FLAG_MASK) != TCP_FLAG_ACK))
1959 return 0;
1960
1961 optlen = (tcph->doff << 2) - sizeof(*tcph);
1962 if (optlen) {
1963 const u32 *opt = (const u32 *)(tcph + 1);
1964
1965 if (optlen != TCPOLEN_TSTAMP_ALIGNED ||
1966 *opt != htonl(TSTAMP_WORD) || !opt[2])
1967 return 0;
1968 }
1969 return 1;
1970}
1971
1972static int t3_get_lro_header(void **eh, void **iph, void **tcph, 1938static int t3_get_lro_header(void **eh, void **iph, void **tcph,
1973 u64 *hdr_flags, void *priv) 1939 u64 *hdr_flags, void *priv)
1974{ 1940{
@@ -1981,9 +1947,6 @@ static int t3_get_lro_header(void **eh, void **iph, void **tcph,
1981 *iph = (struct iphdr *)((struct ethhdr *)*eh + 1); 1947 *iph = (struct iphdr *)((struct ethhdr *)*eh + 1);
1982 *tcph = (struct tcphdr *)((struct iphdr *)*iph + 1); 1948 *tcph = (struct tcphdr *)((struct iphdr *)*iph + 1);
1983 1949
1984 if (!lro_segment_ok(*tcph))
1985 return -1;
1986
1987 *hdr_flags = LRO_IPV4 | LRO_TCP; 1950 *hdr_flags = LRO_IPV4 | LRO_TCP;
1988 return 0; 1951 return 0;
1989} 1952}
@@ -2878,9 +2841,7 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
2878 struct net_lro_mgr *lro_mgr = &q->lro_mgr; 2841 struct net_lro_mgr *lro_mgr = &q->lro_mgr;
2879 2842
2880 init_qset_cntxt(q, id); 2843 init_qset_cntxt(q, id);
2881 init_timer(&q->tx_reclaim_timer); 2844 setup_timer(&q->tx_reclaim_timer, sge_timer_cb, (unsigned long)q);
2882 q->tx_reclaim_timer.data = (unsigned long)q;
2883 q->tx_reclaim_timer.function = sge_timer_cb;
2884 2845
2885 q->fl[0].desc = alloc_ring(adapter->pdev, p->fl_size, 2846 q->fl[0].desc = alloc_ring(adapter->pdev, p->fl_size,
2886 sizeof(struct rx_desc), 2847 sizeof(struct rx_desc),
@@ -2934,6 +2895,7 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
2934 q->rspq.gen = 1; 2895 q->rspq.gen = 1;
2935 q->rspq.size = p->rspq_size; 2896 q->rspq.size = p->rspq_size;
2936 spin_lock_init(&q->rspq.lock); 2897 spin_lock_init(&q->rspq.lock);
2898 skb_queue_head_init(&q->rspq.rx_queue);
2937 2899
2938 q->txq[TXQ_ETH].stop_thres = nports * 2900 q->txq[TXQ_ETH].stop_thres = nports *
2939 flits_to_desc(sgl_len(MAX_SKB_FRAGS + 1) + 3); 2901 flits_to_desc(sgl_len(MAX_SKB_FRAGS + 1) + 3);
@@ -3043,6 +3005,24 @@ err:
3043} 3005}
3044 3006
3045/** 3007/**
3008 * t3_stop_sge_timers - stop SGE timer call backs
3009 * @adap: the adapter
3010 *
3011 * Stops each SGE queue set's timer call back
3012 */
3013void t3_stop_sge_timers(struct adapter *adap)
3014{
3015 int i;
3016
3017 for (i = 0; i < SGE_QSETS; ++i) {
3018 struct sge_qset *q = &adap->sge.qs[i];
3019
3020 if (q->tx_reclaim_timer.function)
3021 del_timer_sync(&q->tx_reclaim_timer);
3022 }
3023}
3024
3025/**
3046 * t3_free_sge_resources - free SGE resources 3026 * t3_free_sge_resources - free SGE resources
3047 * @adap: the adapter 3027 * @adap: the adapter
3048 * 3028 *
diff --git a/drivers/net/cxgb3/t3_cpl.h b/drivers/net/cxgb3/t3_cpl.h
index 917970ed24a1..852c399a8b0a 100644
--- a/drivers/net/cxgb3/t3_cpl.h
+++ b/drivers/net/cxgb3/t3_cpl.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2004-2007 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2004-2008 Chelsio, Inc. All rights reserved.
3 * 3 *
4 * This software is available to you under a choice of one of two 4 * 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 5 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
index 04c0e90119af..968f64be3743 100644
--- a/drivers/net/cxgb3/t3_hw.c
+++ b/drivers/net/cxgb3/t3_hw.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2003-2007 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2003-2008 Chelsio, Inc. All rights reserved.
3 * 3 *
4 * This software is available to you under a choice of one of two 4 * 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 5 * licenses. You may choose to be licensed under the terms of the GNU
@@ -194,21 +194,18 @@ int t3_mc7_bd_read(struct mc7 *mc7, unsigned int start, unsigned int n,
194static void mi1_init(struct adapter *adap, const struct adapter_info *ai) 194static void mi1_init(struct adapter *adap, const struct adapter_info *ai)
195{ 195{
196 u32 clkdiv = adap->params.vpd.cclk / (2 * adap->params.vpd.mdc) - 1; 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) | 197 u32 val = F_PREEN | V_CLKDIV(clkdiv);
198 V_CLKDIV(clkdiv);
199 198
200 if (!(ai->caps & SUPPORTED_10000baseT_Full))
201 val |= V_ST(1);
202 t3_write_reg(adap, A_MI1_CFG, val); 199 t3_write_reg(adap, A_MI1_CFG, val);
203} 200}
204 201
205#define MDIO_ATTEMPTS 10 202#define MDIO_ATTEMPTS 20
206 203
207/* 204/*
208 * MI1 read/write operations for direct-addressed PHYs. 205 * MI1 read/write operations for clause 22 PHYs.
209 */ 206 */
210static int mi1_read(struct adapter *adapter, int phy_addr, int mmd_addr, 207static int t3_mi1_read(struct adapter *adapter, int phy_addr, int mmd_addr,
211 int reg_addr, unsigned int *valp) 208 int reg_addr, unsigned int *valp)
212{ 209{
213 int ret; 210 int ret;
214 u32 addr = V_REGADDR(reg_addr) | V_PHYADDR(phy_addr); 211 u32 addr = V_REGADDR(reg_addr) | V_PHYADDR(phy_addr);
@@ -217,16 +214,17 @@ static int mi1_read(struct adapter *adapter, int phy_addr, int mmd_addr,
217 return -EINVAL; 214 return -EINVAL;
218 215
219 mutex_lock(&adapter->mdio_lock); 216 mutex_lock(&adapter->mdio_lock);
217 t3_set_reg_field(adapter, A_MI1_CFG, V_ST(M_ST), V_ST(1));
220 t3_write_reg(adapter, A_MI1_ADDR, addr); 218 t3_write_reg(adapter, A_MI1_ADDR, addr);
221 t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(2)); 219 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); 220 ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 10);
223 if (!ret) 221 if (!ret)
224 *valp = t3_read_reg(adapter, A_MI1_DATA); 222 *valp = t3_read_reg(adapter, A_MI1_DATA);
225 mutex_unlock(&adapter->mdio_lock); 223 mutex_unlock(&adapter->mdio_lock);
226 return ret; 224 return ret;
227} 225}
228 226
229static int mi1_write(struct adapter *adapter, int phy_addr, int mmd_addr, 227static int t3_mi1_write(struct adapter *adapter, int phy_addr, int mmd_addr,
230 int reg_addr, unsigned int val) 228 int reg_addr, unsigned int val)
231{ 229{
232 int ret; 230 int ret;
@@ -236,37 +234,51 @@ static int mi1_write(struct adapter *adapter, int phy_addr, int mmd_addr,
236 return -EINVAL; 234 return -EINVAL;
237 235
238 mutex_lock(&adapter->mdio_lock); 236 mutex_lock(&adapter->mdio_lock);
237 t3_set_reg_field(adapter, A_MI1_CFG, V_ST(M_ST), V_ST(1));
239 t3_write_reg(adapter, A_MI1_ADDR, addr); 238 t3_write_reg(adapter, A_MI1_ADDR, addr);
240 t3_write_reg(adapter, A_MI1_DATA, val); 239 t3_write_reg(adapter, A_MI1_DATA, val);
241 t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(1)); 240 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); 241 ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 10);
243 mutex_unlock(&adapter->mdio_lock); 242 mutex_unlock(&adapter->mdio_lock);
244 return ret; 243 return ret;
245} 244}
246 245
247static const struct mdio_ops mi1_mdio_ops = { 246static const struct mdio_ops mi1_mdio_ops = {
248 mi1_read, 247 t3_mi1_read,
249 mi1_write 248 t3_mi1_write
250}; 249};
251 250
252/* 251/*
252 * Performs the address cycle for clause 45 PHYs.
253 * Must be called with the MDIO_LOCK held.
254 */
255static int mi1_wr_addr(struct adapter *adapter, int phy_addr, int mmd_addr,
256 int reg_addr)
257{
258 u32 addr = V_REGADDR(mmd_addr) | V_PHYADDR(phy_addr);
259
260 t3_set_reg_field(adapter, A_MI1_CFG, V_ST(M_ST), 0);
261 t3_write_reg(adapter, A_MI1_ADDR, addr);
262 t3_write_reg(adapter, A_MI1_DATA, reg_addr);
263 t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(0));
264 return t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0,
265 MDIO_ATTEMPTS, 10);
266}
267
268/*
253 * MI1 read/write operations for indirect-addressed PHYs. 269 * MI1 read/write operations for indirect-addressed PHYs.
254 */ 270 */
255static int mi1_ext_read(struct adapter *adapter, int phy_addr, int mmd_addr, 271static int mi1_ext_read(struct adapter *adapter, int phy_addr, int mmd_addr,
256 int reg_addr, unsigned int *valp) 272 int reg_addr, unsigned int *valp)
257{ 273{
258 int ret; 274 int ret;
259 u32 addr = V_REGADDR(mmd_addr) | V_PHYADDR(phy_addr);
260 275
261 mutex_lock(&adapter->mdio_lock); 276 mutex_lock(&adapter->mdio_lock);
262 t3_write_reg(adapter, A_MI1_ADDR, addr); 277 ret = mi1_wr_addr(adapter, phy_addr, mmd_addr, reg_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) { 278 if (!ret) {
267 t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(3)); 279 t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(3));
268 ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, 280 ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0,
269 MDIO_ATTEMPTS, 20); 281 MDIO_ATTEMPTS, 10);
270 if (!ret) 282 if (!ret)
271 *valp = t3_read_reg(adapter, A_MI1_DATA); 283 *valp = t3_read_reg(adapter, A_MI1_DATA);
272 } 284 }
@@ -278,18 +290,14 @@ static int mi1_ext_write(struct adapter *adapter, int phy_addr, int mmd_addr,
278 int reg_addr, unsigned int val) 290 int reg_addr, unsigned int val)
279{ 291{
280 int ret; 292 int ret;
281 u32 addr = V_REGADDR(mmd_addr) | V_PHYADDR(phy_addr);
282 293
283 mutex_lock(&adapter->mdio_lock); 294 mutex_lock(&adapter->mdio_lock);
284 t3_write_reg(adapter, A_MI1_ADDR, addr); 295 ret = mi1_wr_addr(adapter, phy_addr, mmd_addr, reg_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) { 296 if (!ret) {
289 t3_write_reg(adapter, A_MI1_DATA, val); 297 t3_write_reg(adapter, A_MI1_DATA, val);
290 t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(1)); 298 t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(1));
291 ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, 299 ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0,
292 MDIO_ATTEMPTS, 20); 300 MDIO_ATTEMPTS, 10);
293 } 301 }
294 mutex_unlock(&adapter->mdio_lock); 302 mutex_unlock(&adapter->mdio_lock);
295 return ret; 303 return ret;
@@ -400,6 +408,29 @@ int t3_phy_advertise(struct cphy *phy, unsigned int advert)
400} 408}
401 409
402/** 410/**
411 * t3_phy_advertise_fiber - set fiber PHY advertisement register
412 * @phy: the PHY to operate on
413 * @advert: bitmap of capabilities the PHY should advertise
414 *
415 * Sets a fiber PHY's advertisement register to advertise the
416 * requested capabilities.
417 */
418int t3_phy_advertise_fiber(struct cphy *phy, unsigned int advert)
419{
420 unsigned int val = 0;
421
422 if (advert & ADVERTISED_1000baseT_Half)
423 val |= ADVERTISE_1000XHALF;
424 if (advert & ADVERTISED_1000baseT_Full)
425 val |= ADVERTISE_1000XFULL;
426 if (advert & ADVERTISED_Pause)
427 val |= ADVERTISE_1000XPAUSE;
428 if (advert & ADVERTISED_Asym_Pause)
429 val |= ADVERTISE_1000XPSE_ASYM;
430 return mdio_write(phy, 0, MII_ADVERTISE, val);
431}
432
433/**
403 * t3_set_phy_speed_duplex - force PHY speed and duplex 434 * t3_set_phy_speed_duplex - force PHY speed and duplex
404 * @phy: the PHY to operate on 435 * @phy: the PHY to operate on
405 * @speed: requested PHY speed 436 * @speed: requested PHY speed
@@ -434,27 +465,52 @@ int t3_set_phy_speed_duplex(struct cphy *phy, int speed, int duplex)
434 return mdio_write(phy, 0, MII_BMCR, ctl); 465 return mdio_write(phy, 0, MII_BMCR, ctl);
435} 466}
436 467
468int t3_phy_lasi_intr_enable(struct cphy *phy)
469{
470 return mdio_write(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, 1);
471}
472
473int t3_phy_lasi_intr_disable(struct cphy *phy)
474{
475 return mdio_write(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, 0);
476}
477
478int t3_phy_lasi_intr_clear(struct cphy *phy)
479{
480 u32 val;
481
482 return mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_STAT, &val);
483}
484
485int t3_phy_lasi_intr_handler(struct cphy *phy)
486{
487 unsigned int status;
488 int err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_STAT, &status);
489
490 if (err)
491 return err;
492 return (status & 1) ? cphy_cause_link_change : 0;
493}
494
437static const struct adapter_info t3_adap_info[] = { 495static const struct adapter_info t3_adap_info[] = {
438 {2, 0, 0, 0, 496 {2, 0,
439 F_GPIO2_OEN | F_GPIO4_OEN | 497 F_GPIO2_OEN | F_GPIO4_OEN |
440 F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, F_GPIO3 | F_GPIO5, 498 F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, { S_GPIO3, S_GPIO5 }, 0,
441 0,
442 &mi1_mdio_ops, "Chelsio PE9000"}, 499 &mi1_mdio_ops, "Chelsio PE9000"},
443 {2, 0, 0, 0, 500 {2, 0,
444 F_GPIO2_OEN | F_GPIO4_OEN | 501 F_GPIO2_OEN | F_GPIO4_OEN |
445 F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, F_GPIO3 | F_GPIO5, 502 F_GPIO2_OUT_VAL | F_GPIO4_OUT_VAL, { S_GPIO3, S_GPIO5 }, 0,
446 0,
447 &mi1_mdio_ops, "Chelsio T302"}, 503 &mi1_mdio_ops, "Chelsio T302"},
448 {1, 0, 0, 0, 504 {1, 0,
449 F_GPIO1_OEN | F_GPIO6_OEN | F_GPIO7_OEN | F_GPIO10_OEN | 505 F_GPIO1_OEN | F_GPIO6_OEN | F_GPIO7_OEN | F_GPIO10_OEN |
450 F_GPIO11_OEN | F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL, 506 F_GPIO11_OEN | F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL,
451 0, SUPPORTED_10000baseT_Full | SUPPORTED_AUI, 507 { 0 }, SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
452 &mi1_mdio_ext_ops, "Chelsio T310"}, 508 &mi1_mdio_ext_ops, "Chelsio T310"},
453 {2, 0, 0, 0, 509 {2, 0,
454 F_GPIO1_OEN | F_GPIO2_OEN | F_GPIO4_OEN | F_GPIO5_OEN | F_GPIO6_OEN | 510 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 | 511 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, 512 F_GPIO5_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL,
457 SUPPORTED_10000baseT_Full | SUPPORTED_AUI, 513 { S_GPIO9, S_GPIO3 }, SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
458 &mi1_mdio_ext_ops, "Chelsio T320"}, 514 &mi1_mdio_ext_ops, "Chelsio T320"},
459}; 515};
460 516
@@ -467,29 +523,23 @@ const struct adapter_info *t3_get_adapter_info(unsigned int id)
467 return id < ARRAY_SIZE(t3_adap_info) ? &t3_adap_info[id] : NULL; 523 return id < ARRAY_SIZE(t3_adap_info) ? &t3_adap_info[id] : NULL;
468} 524}
469 525
470#define CAPS_1G (SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Full | \ 526struct port_type_info {
471 SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_MII) 527 int (*phy_prep)(struct cphy *phy, struct adapter *adapter,
472#define CAPS_10G (SUPPORTED_10000baseT_Full | SUPPORTED_AUI) 528 int phy_addr, const struct mdio_ops *ops);
529};
473 530
474static const struct port_type_info port_types[] = { 531static const struct port_type_info port_types[] = {
475 {NULL}, 532 { NULL },
476 {t3_ael1002_phy_prep, CAPS_10G | SUPPORTED_FIBRE, 533 { t3_ael1002_phy_prep },
477 "10GBASE-XR"}, 534 { t3_vsc8211_phy_prep },
478 {t3_vsc8211_phy_prep, CAPS_1G | SUPPORTED_TP | SUPPORTED_IRQ, 535 { NULL},
479 "10/100/1000BASE-T"}, 536 { t3_xaui_direct_phy_prep },
480 {NULL, CAPS_1G | SUPPORTED_TP | SUPPORTED_IRQ, 537 { t3_ael2005_phy_prep },
481 "10/100/1000BASE-T"}, 538 { t3_qt2045_phy_prep },
482 {t3_xaui_direct_phy_prep, CAPS_10G | SUPPORTED_TP, "10GBASE-CX4"}, 539 { t3_ael1006_phy_prep },
483 {NULL, CAPS_10G, "10GBASE-KX4"}, 540 { NULL },
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}; 541};
489 542
490#undef CAPS_1G
491#undef CAPS_10G
492
493#define VPD_ENTRY(name, len) \ 543#define VPD_ENTRY(name, len) \
494 u8 name##_kword[2]; u8 name##_len; u8 name##_data[len] 544 u8 name##_kword[2]; u8 name##_len; u8 name##_data[len]
495 545
@@ -1132,6 +1182,15 @@ void t3_link_changed(struct adapter *adapter, int port_id)
1132 1182
1133 phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc); 1183 phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc);
1134 1184
1185 if (lc->requested_fc & PAUSE_AUTONEG)
1186 fc &= lc->requested_fc;
1187 else
1188 fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
1189
1190 if (link_ok == lc->link_ok && speed == lc->speed &&
1191 duplex == lc->duplex && fc == lc->fc)
1192 return; /* nothing changed */
1193
1135 if (link_ok != lc->link_ok && adapter->params.rev > 0 && 1194 if (link_ok != lc->link_ok && adapter->params.rev > 0 &&
1136 uses_xaui(adapter)) { 1195 uses_xaui(adapter)) {
1137 if (link_ok) 1196 if (link_ok)
@@ -1142,10 +1201,6 @@ void t3_link_changed(struct adapter *adapter, int port_id)
1142 lc->link_ok = link_ok; 1201 lc->link_ok = link_ok;
1143 lc->speed = speed < 0 ? SPEED_INVALID : speed; 1202 lc->speed = speed < 0 ? SPEED_INVALID : speed;
1144 lc->duplex = duplex < 0 ? DUPLEX_INVALID : duplex; 1203 lc->duplex = duplex < 0 ? DUPLEX_INVALID : duplex;
1145 if (lc->requested_fc & PAUSE_AUTONEG)
1146 fc &= lc->requested_fc;
1147 else
1148 fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
1149 1204
1150 if (link_ok && speed >= 0 && lc->autoneg == AUTONEG_ENABLE) { 1205 if (link_ok && speed >= 0 && lc->autoneg == AUTONEG_ENABLE) {
1151 /* Set MAC speed, duplex, and flow control to match PHY. */ 1206 /* Set MAC speed, duplex, and flow control to match PHY. */
@@ -1191,7 +1246,6 @@ int t3_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc)
1191 fc); 1246 fc);
1192 /* Also disables autoneg */ 1247 /* Also disables autoneg */
1193 phy->ops->set_speed_duplex(phy, lc->speed, lc->duplex); 1248 phy->ops->set_speed_duplex(phy, lc->speed, lc->duplex);
1194 phy->ops->reset(phy, 0);
1195 } else 1249 } else
1196 phy->ops->autoneg_enable(phy); 1250 phy->ops->autoneg_enable(phy);
1197 } else { 1251 } else {
@@ -1221,7 +1275,7 @@ struct intr_info {
1221 unsigned int mask; /* bits to check in interrupt status */ 1275 unsigned int mask; /* bits to check in interrupt status */
1222 const char *msg; /* message to print or NULL */ 1276 const char *msg; /* message to print or NULL */
1223 short stat_idx; /* stat counter to increment or -1 */ 1277 short stat_idx; /* stat counter to increment or -1 */
1224 unsigned short fatal:1; /* whether the condition reported is fatal */ 1278 unsigned short fatal; /* whether the condition reported is fatal */
1225}; 1279};
1226 1280
1227/** 1281/**
@@ -1682,25 +1736,23 @@ static int mac_intr_handler(struct adapter *adap, unsigned int idx)
1682 */ 1736 */
1683int t3_phy_intr_handler(struct adapter *adapter) 1737int t3_phy_intr_handler(struct adapter *adapter)
1684{ 1738{
1685 u32 mask, gpi = adapter_info(adapter)->gpio_intr;
1686 u32 i, cause = t3_read_reg(adapter, A_T3DBG_INT_CAUSE); 1739 u32 i, cause = t3_read_reg(adapter, A_T3DBG_INT_CAUSE);
1687 1740
1688 for_each_port(adapter, i) { 1741 for_each_port(adapter, i) {
1689 struct port_info *p = adap2pinfo(adapter, i); 1742 struct port_info *p = adap2pinfo(adapter, i);
1690 1743
1691 mask = gpi - (gpi & (gpi - 1)); 1744 if (!(p->phy.caps & SUPPORTED_IRQ))
1692 gpi -= mask;
1693
1694 if (!(p->port_type->caps & SUPPORTED_IRQ))
1695 continue; 1745 continue;
1696 1746
1697 if (cause & mask) { 1747 if (cause & (1 << adapter_info(adapter)->gpio_intr[i])) {
1698 int phy_cause = p->phy.ops->intr_handler(&p->phy); 1748 int phy_cause = p->phy.ops->intr_handler(&p->phy);
1699 1749
1700 if (phy_cause & cphy_cause_link_change) 1750 if (phy_cause & cphy_cause_link_change)
1701 t3_link_changed(adapter, i); 1751 t3_link_changed(adapter, i);
1702 if (phy_cause & cphy_cause_fifo_error) 1752 if (phy_cause & cphy_cause_fifo_error)
1703 p->phy.fifo_errors++; 1753 p->phy.fifo_errors++;
1754 if (phy_cause & cphy_cause_module_change)
1755 t3_os_phymod_changed(adapter, i);
1704 } 1756 }
1705 } 1757 }
1706 1758
@@ -1763,6 +1815,17 @@ int t3_slow_intr_handler(struct adapter *adapter)
1763 return 1; 1815 return 1;
1764} 1816}
1765 1817
1818static unsigned int calc_gpio_intr(struct adapter *adap)
1819{
1820 unsigned int i, gpi_intr = 0;
1821
1822 for_each_port(adap, i)
1823 if ((adap2pinfo(adap, i)->phy.caps & SUPPORTED_IRQ) &&
1824 adapter_info(adap)->gpio_intr[i])
1825 gpi_intr |= 1 << adapter_info(adap)->gpio_intr[i];
1826 return gpi_intr;
1827}
1828
1766/** 1829/**
1767 * t3_intr_enable - enable interrupts 1830 * t3_intr_enable - enable interrupts
1768 * @adapter: the adapter whose interrupts should be enabled 1831 * @adapter: the adapter whose interrupts should be enabled
@@ -1805,10 +1868,8 @@ void t3_intr_enable(struct adapter *adapter)
1805 t3_write_reg(adapter, A_ULPTX_INT_ENABLE, ULPTX_INTR_MASK); 1868 t3_write_reg(adapter, A_ULPTX_INT_ENABLE, ULPTX_INTR_MASK);
1806 } 1869 }
1807 1870
1808 t3_write_reg(adapter, A_T3DBG_GPIO_ACT_LOW, 1871 t3_write_reg(adapter, A_T3DBG_INT_ENABLE, calc_gpio_intr(adapter));
1809 adapter_info(adapter)->gpio_intr); 1872
1810 t3_write_reg(adapter, A_T3DBG_INT_ENABLE,
1811 adapter_info(adapter)->gpio_intr);
1812 if (is_pcie(adapter)) 1873 if (is_pcie(adapter))
1813 t3_write_reg(adapter, A_PCIE_INT_ENABLE, PCIE_INTR_MASK); 1874 t3_write_reg(adapter, A_PCIE_INT_ENABLE, PCIE_INTR_MASK);
1814 else 1875 else
@@ -3329,6 +3390,8 @@ int t3_init_hw(struct adapter *adapter, u32 fw_params)
3329 init_hw_for_avail_ports(adapter, adapter->params.nports); 3390 init_hw_for_avail_ports(adapter, adapter->params.nports);
3330 t3_sge_init(adapter, &adapter->params.sge); 3391 t3_sge_init(adapter, &adapter->params.sge);
3331 3392
3393 t3_write_reg(adapter, A_T3DBG_GPIO_ACT_LOW, calc_gpio_intr(adapter));
3394
3332 t3_write_reg(adapter, A_CIM_HOST_ACC_DATA, vpd->uclk | fw_params); 3395 t3_write_reg(adapter, A_CIM_HOST_ACC_DATA, vpd->uclk | fw_params);
3333 t3_write_reg(adapter, A_CIM_BOOT_CFG, 3396 t3_write_reg(adapter, A_CIM_BOOT_CFG,
3334 V_BOOTADDR(FW_FLASH_BOOT_ADDR >> 2)); 3397 V_BOOTADDR(FW_FLASH_BOOT_ADDR >> 2));
@@ -3488,7 +3551,7 @@ void early_hw_init(struct adapter *adapter, const struct adapter_info *ai)
3488 * Older PCIe cards lose their config space during reset, PCI-X 3551 * Older PCIe cards lose their config space during reset, PCI-X
3489 * ones don't. 3552 * ones don't.
3490 */ 3553 */
3491static int t3_reset_adapter(struct adapter *adapter) 3554int t3_reset_adapter(struct adapter *adapter)
3492{ 3555{
3493 int i, save_and_restore_pcie = 3556 int i, save_and_restore_pcie =
3494 adapter->params.rev < T3_REV_B2 && is_pcie(adapter); 3557 adapter->params.rev < T3_REV_B2 && is_pcie(adapter);
@@ -3556,7 +3619,7 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai,
3556 int reset) 3619 int reset)
3557{ 3620{
3558 int ret; 3621 int ret;
3559 unsigned int i, j = 0; 3622 unsigned int i, j = -1;
3560 3623
3561 get_pci_mode(adapter, &adapter->params.pci); 3624 get_pci_mode(adapter, &adapter->params.pci);
3562 3625
@@ -3620,16 +3683,18 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai,
3620 3683
3621 for_each_port(adapter, i) { 3684 for_each_port(adapter, i) {
3622 u8 hw_addr[6]; 3685 u8 hw_addr[6];
3686 const struct port_type_info *pti;
3623 struct port_info *p = adap2pinfo(adapter, i); 3687 struct port_info *p = adap2pinfo(adapter, i);
3624 3688
3625 while (!adapter->params.vpd.port_type[j]) 3689 while (!adapter->params.vpd.port_type[++j])
3626 ++j; 3690 ;
3627 3691
3628 p->port_type = &port_types[adapter->params.vpd.port_type[j]]; 3692 pti = &port_types[adapter->params.vpd.port_type[j]];
3629 p->port_type->phy_prep(&p->phy, adapter, ai->phy_base_addr + j, 3693 ret = pti->phy_prep(&p->phy, adapter, ai->phy_base_addr + j,
3630 ai->mdio_ops); 3694 ai->mdio_ops);
3695 if (ret)
3696 return ret;
3631 mac_prep(&p->mac, adapter, j); 3697 mac_prep(&p->mac, adapter, j);
3632 ++j;
3633 3698
3634 /* 3699 /*
3635 * The VPD EEPROM stores the base Ethernet address for the 3700 * The VPD EEPROM stores the base Ethernet address for the
@@ -3643,9 +3708,9 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai,
3643 ETH_ALEN); 3708 ETH_ALEN);
3644 memcpy(adapter->port[i]->perm_addr, hw_addr, 3709 memcpy(adapter->port[i]->perm_addr, hw_addr,
3645 ETH_ALEN); 3710 ETH_ALEN);
3646 init_link_config(&p->link_config, p->port_type->caps); 3711 init_link_config(&p->link_config, p->phy.caps);
3647 p->phy.ops->power_down(&p->phy, 1); 3712 p->phy.ops->power_down(&p->phy, 1);
3648 if (!(p->port_type->caps & SUPPORTED_IRQ)) 3713 if (!(p->phy.caps & SUPPORTED_IRQ))
3649 adapter->params.linkpoll_period = 10; 3714 adapter->params.linkpoll_period = 10;
3650 } 3715 }
3651 3716
@@ -3661,7 +3726,7 @@ void t3_led_ready(struct adapter *adapter)
3661int t3_replay_prep_adapter(struct adapter *adapter) 3726int t3_replay_prep_adapter(struct adapter *adapter)
3662{ 3727{
3663 const struct adapter_info *ai = adapter->params.info; 3728 const struct adapter_info *ai = adapter->params.info;
3664 unsigned int i, j = 0; 3729 unsigned int i, j = -1;
3665 int ret; 3730 int ret;
3666 3731
3667 early_hw_init(adapter, ai); 3732 early_hw_init(adapter, ai);
@@ -3670,15 +3735,17 @@ int t3_replay_prep_adapter(struct adapter *adapter)
3670 return ret; 3735 return ret;
3671 3736
3672 for_each_port(adapter, i) { 3737 for_each_port(adapter, i) {
3738 const struct port_type_info *pti;
3673 struct port_info *p = adap2pinfo(adapter, i); 3739 struct port_info *p = adap2pinfo(adapter, i);
3674 while (!adapter->params.vpd.port_type[j])
3675 ++j;
3676 3740
3677 p->port_type->phy_prep(&p->phy, adapter, ai->phy_base_addr + j, 3741 while (!adapter->params.vpd.port_type[++j])
3678 ai->mdio_ops); 3742 ;
3679 3743
3744 pti = &port_types[adapter->params.vpd.port_type[j]];
3745 ret = pti->phy_prep(&p->phy, adapter, p->phy.addr, NULL);
3746 if (ret)
3747 return ret;
3680 p->phy.ops->power_down(&p->phy, 1); 3748 p->phy.ops->power_down(&p->phy, 1);
3681 ++j;
3682 } 3749 }
3683 3750
3684return 0; 3751return 0;
diff --git a/drivers/net/cxgb3/t3cdev.h b/drivers/net/cxgb3/t3cdev.h
index 0a21cfbd2b21..be55e9ae74d1 100644
--- a/drivers/net/cxgb3/t3cdev.h
+++ b/drivers/net/cxgb3/t3cdev.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2006-2007 Chelsio Communications. All rights reserved. 2 * Copyright (C) 2006-2008 Chelsio Communications. All rights reserved.
3 * 3 *
4 * This software is available to you under a choice of one of two 4 * 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 5 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/net/cxgb3/version.h b/drivers/net/cxgb3/version.h
index 29db711303b9..bb8698a86754 100644
--- a/drivers/net/cxgb3/version.h
+++ b/drivers/net/cxgb3/version.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2003-2007 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2003-2008 Chelsio, Inc. All rights reserved.
3 * 3 *
4 * This software is available to you under a choice of one of two 4 * 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 5 * licenses. You may choose to be licensed under the terms of the GNU
@@ -35,7 +35,7 @@
35#define DRV_DESC "Chelsio T3 Network Driver" 35#define DRV_DESC "Chelsio T3 Network Driver"
36#define DRV_NAME "cxgb3" 36#define DRV_NAME "cxgb3"
37/* Driver version */ 37/* Driver version */
38#define DRV_VERSION "1.0-ko" 38#define DRV_VERSION "1.1.0-ko"
39 39
40/* Firmware version */ 40/* Firmware version */
41#define FW_VERSION_MAJOR 7 41#define FW_VERSION_MAJOR 7
diff --git a/drivers/net/cxgb3/vsc8211.c b/drivers/net/cxgb3/vsc8211.c
index eee4285b31be..33f956bd6b59 100644
--- a/drivers/net/cxgb3/vsc8211.c
+++ b/drivers/net/cxgb3/vsc8211.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2005-2007 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2005-2008 Chelsio, Inc. All rights reserved.
3 * 3 *
4 * This software is available to you under a choice of one of two 4 * 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 5 * licenses. You may choose to be licensed under the terms of the GNU
@@ -33,28 +33,40 @@
33 33
34/* VSC8211 PHY specific registers. */ 34/* VSC8211 PHY specific registers. */
35enum { 35enum {
36 VSC8211_SIGDET_CTRL = 19,
37 VSC8211_EXT_CTRL = 23,
36 VSC8211_INTR_ENABLE = 25, 38 VSC8211_INTR_ENABLE = 25,
37 VSC8211_INTR_STATUS = 26, 39 VSC8211_INTR_STATUS = 26,
40 VSC8211_LED_CTRL = 27,
38 VSC8211_AUX_CTRL_STAT = 28, 41 VSC8211_AUX_CTRL_STAT = 28,
42 VSC8211_EXT_PAGE_AXS = 31,
39}; 43};
40 44
41enum { 45enum {
42 VSC_INTR_RX_ERR = 1 << 0, 46 VSC_INTR_RX_ERR = 1 << 0,
43 VSC_INTR_MS_ERR = 1 << 1, /* master/slave resolution error */ 47 VSC_INTR_MS_ERR = 1 << 1, /* master/slave resolution error */
44 VSC_INTR_CABLE = 1 << 2, /* cable impairment */ 48 VSC_INTR_CABLE = 1 << 2, /* cable impairment */
45 VSC_INTR_FALSE_CARR = 1 << 3, /* false carrier */ 49 VSC_INTR_FALSE_CARR = 1 << 3, /* false carrier */
46 VSC_INTR_MEDIA_CHG = 1 << 4, /* AMS media change */ 50 VSC_INTR_MEDIA_CHG = 1 << 4, /* AMS media change */
47 VSC_INTR_RX_FIFO = 1 << 5, /* Rx FIFO over/underflow */ 51 VSC_INTR_RX_FIFO = 1 << 5, /* Rx FIFO over/underflow */
48 VSC_INTR_TX_FIFO = 1 << 6, /* Tx FIFO over/underflow */ 52 VSC_INTR_TX_FIFO = 1 << 6, /* Tx FIFO over/underflow */
49 VSC_INTR_DESCRAMBL = 1 << 7, /* descrambler lock-lost */ 53 VSC_INTR_DESCRAMBL = 1 << 7, /* descrambler lock-lost */
50 VSC_INTR_SYMBOL_ERR = 1 << 8, /* symbol error */ 54 VSC_INTR_SYMBOL_ERR = 1 << 8, /* symbol error */
51 VSC_INTR_NEG_DONE = 1 << 10, /* autoneg done */ 55 VSC_INTR_NEG_DONE = 1 << 10, /* autoneg done */
52 VSC_INTR_NEG_ERR = 1 << 11, /* autoneg error */ 56 VSC_INTR_NEG_ERR = 1 << 11, /* autoneg error */
53 VSC_INTR_LINK_CHG = 1 << 13, /* link change */ 57 VSC_INTR_DPLX_CHG = 1 << 12, /* duplex change */
54 VSC_INTR_ENABLE = 1 << 15, /* interrupt enable */ 58 VSC_INTR_LINK_CHG = 1 << 13, /* link change */
59 VSC_INTR_SPD_CHG = 1 << 14, /* speed change */
60 VSC_INTR_ENABLE = 1 << 15, /* interrupt enable */
61};
62
63enum {
64 VSC_CTRL_CLAUSE37_VIEW = 1 << 4, /* Switch to Clause 37 view */
65 VSC_CTRL_MEDIA_MODE_HI = 0xf000 /* High part of media mode select */
55}; 66};
56 67
57#define CFG_CHG_INTR_MASK (VSC_INTR_LINK_CHG | VSC_INTR_NEG_ERR | \ 68#define CFG_CHG_INTR_MASK (VSC_INTR_LINK_CHG | VSC_INTR_NEG_ERR | \
69 VSC_INTR_DPLX_CHG | VSC_INTR_SPD_CHG | \
58 VSC_INTR_NEG_DONE) 70 VSC_INTR_NEG_DONE)
59#define INTR_MASK (CFG_CHG_INTR_MASK | VSC_INTR_TX_FIFO | VSC_INTR_RX_FIFO | \ 71#define INTR_MASK (CFG_CHG_INTR_MASK | VSC_INTR_TX_FIFO | VSC_INTR_RX_FIFO | \
60 VSC_INTR_ENABLE) 72 VSC_INTR_ENABLE)
@@ -184,6 +196,112 @@ static int vsc8211_get_link_status(struct cphy *cphy, int *link_ok,
184 return 0; 196 return 0;
185} 197}
186 198
199static int vsc8211_get_link_status_fiber(struct cphy *cphy, int *link_ok,
200 int *speed, int *duplex, int *fc)
201{
202 unsigned int bmcr, status, lpa, adv;
203 int err, sp = -1, dplx = -1, pause = 0;
204
205 err = mdio_read(cphy, 0, MII_BMCR, &bmcr);
206 if (!err)
207 err = mdio_read(cphy, 0, MII_BMSR, &status);
208 if (err)
209 return err;
210
211 if (link_ok) {
212 /*
213 * BMSR_LSTATUS is latch-low, so if it is 0 we need to read it
214 * once more to get the current link state.
215 */
216 if (!(status & BMSR_LSTATUS))
217 err = mdio_read(cphy, 0, MII_BMSR, &status);
218 if (err)
219 return err;
220 *link_ok = (status & BMSR_LSTATUS) != 0;
221 }
222 if (!(bmcr & BMCR_ANENABLE)) {
223 dplx = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF;
224 if (bmcr & BMCR_SPEED1000)
225 sp = SPEED_1000;
226 else if (bmcr & BMCR_SPEED100)
227 sp = SPEED_100;
228 else
229 sp = SPEED_10;
230 } else if (status & BMSR_ANEGCOMPLETE) {
231 err = mdio_read(cphy, 0, MII_LPA, &lpa);
232 if (!err)
233 err = mdio_read(cphy, 0, MII_ADVERTISE, &adv);
234 if (err)
235 return err;
236
237 if (adv & lpa & ADVERTISE_1000XFULL) {
238 dplx = DUPLEX_FULL;
239 sp = SPEED_1000;
240 } else if (adv & lpa & ADVERTISE_1000XHALF) {
241 dplx = DUPLEX_HALF;
242 sp = SPEED_1000;
243 }
244
245 if (fc && dplx == DUPLEX_FULL) {
246 if (lpa & adv & ADVERTISE_1000XPAUSE)
247 pause = PAUSE_RX | PAUSE_TX;
248 else if ((lpa & ADVERTISE_1000XPAUSE) &&
249 (adv & lpa & ADVERTISE_1000XPSE_ASYM))
250 pause = PAUSE_TX;
251 else if ((lpa & ADVERTISE_1000XPSE_ASYM) &&
252 (adv & ADVERTISE_1000XPAUSE))
253 pause = PAUSE_RX;
254 }
255 }
256 if (speed)
257 *speed = sp;
258 if (duplex)
259 *duplex = dplx;
260 if (fc)
261 *fc = pause;
262 return 0;
263}
264
265/*
266 * Enable/disable auto MDI/MDI-X in forced link speed mode.
267 */
268static int vsc8211_set_automdi(struct cphy *phy, int enable)
269{
270 int err;
271
272 err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 0x52b5);
273 if (err)
274 return err;
275
276 err = mdio_write(phy, 0, 18, 0x12);
277 if (err)
278 return err;
279
280 err = mdio_write(phy, 0, 17, enable ? 0x2803 : 0x3003);
281 if (err)
282 return err;
283
284 err = mdio_write(phy, 0, 16, 0x87fa);
285 if (err)
286 return err;
287
288 err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 0);
289 if (err)
290 return err;
291
292 return 0;
293}
294
295int vsc8211_set_speed_duplex(struct cphy *phy, int speed, int duplex)
296{
297 int err;
298
299 err = t3_set_phy_speed_duplex(phy, speed, duplex);
300 if (!err)
301 err = vsc8211_set_automdi(phy, 1);
302 return err;
303}
304
187static int vsc8211_power_down(struct cphy *cphy, int enable) 305static int vsc8211_power_down(struct cphy *cphy, int enable)
188{ 306{
189 return t3_mdio_change_bits(cphy, 0, MII_BMCR, BMCR_PDOWN, 307 return t3_mdio_change_bits(cphy, 0, MII_BMCR, BMCR_PDOWN,
@@ -221,8 +339,66 @@ static struct cphy_ops vsc8211_ops = {
221 .power_down = vsc8211_power_down, 339 .power_down = vsc8211_power_down,
222}; 340};
223 341
224void t3_vsc8211_phy_prep(struct cphy *phy, struct adapter *adapter, 342static struct cphy_ops vsc8211_fiber_ops = {
225 int phy_addr, const struct mdio_ops *mdio_ops) 343 .reset = vsc8211_reset,
344 .intr_enable = vsc8211_intr_enable,
345 .intr_disable = vsc8211_intr_disable,
346 .intr_clear = vsc8211_intr_clear,
347 .intr_handler = vsc8211_intr_handler,
348 .autoneg_enable = vsc8211_autoneg_enable,
349 .autoneg_restart = vsc8211_autoneg_restart,
350 .advertise = t3_phy_advertise_fiber,
351 .set_speed_duplex = t3_set_phy_speed_duplex,
352 .get_link_status = vsc8211_get_link_status_fiber,
353 .power_down = vsc8211_power_down,
354};
355
356int t3_vsc8211_phy_prep(struct cphy *phy, struct adapter *adapter,
357 int phy_addr, const struct mdio_ops *mdio_ops)
226{ 358{
227 cphy_init(phy, adapter, phy_addr, &vsc8211_ops, mdio_ops); 359 int err;
360 unsigned int val;
361
362 cphy_init(phy, adapter, phy_addr, &vsc8211_ops, mdio_ops,
363 SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Full |
364 SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_MII |
365 SUPPORTED_TP | SUPPORTED_IRQ, "10/100/1000BASE-T");
366 msleep(20); /* PHY needs ~10ms to start responding to MDIO */
367
368 err = mdio_read(phy, 0, VSC8211_EXT_CTRL, &val);
369 if (err)
370 return err;
371 if (val & VSC_CTRL_MEDIA_MODE_HI) {
372 /* copper interface, just need to configure the LEDs */
373 return mdio_write(phy, 0, VSC8211_LED_CTRL, 0x100);
374 }
375
376 phy->caps = SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg |
377 SUPPORTED_MII | SUPPORTED_FIBRE | SUPPORTED_IRQ;
378 phy->desc = "1000BASE-X";
379 phy->ops = &vsc8211_fiber_ops;
380
381 err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 1);
382 if (err)
383 return err;
384
385 err = mdio_write(phy, 0, VSC8211_SIGDET_CTRL, 1);
386 if (err)
387 return err;
388
389 err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 0);
390 if (err)
391 return err;
392
393 err = mdio_write(phy, 0, VSC8211_EXT_CTRL,
394 val | VSC_CTRL_CLAUSE37_VIEW);
395 if (err)
396 return err;
397
398 err = vsc8211_reset(phy, 0);
399 if (err)
400 return err;
401
402 udelay(5); /* delay after reset before next SMI */
403 return 0;
228} 404}
diff --git a/drivers/net/cxgb3/xgmac.c b/drivers/net/cxgb3/xgmac.c
index ffdc0a1892bd..9d7786937aad 100644
--- a/drivers/net/cxgb3/xgmac.c
+++ b/drivers/net/cxgb3/xgmac.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2005-2007 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2005-2008 Chelsio, Inc. All rights reserved.
3 * 3 *
4 * This software is available to you under a choice of one of two 4 * 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 5 * licenses. You may choose to be licensed under the terms of the GNU