blob: c3b1648618c883e745fc990268b5f890a2e5953a [file] [log] [blame]
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001/*****************************************************************************
2 * *
3 * File: cxgb2.c *
Scott Bardone559fb512005-06-23 01:40:19 -04004 * $Revision: 1.25 $ *
5 * $Date: 2005/06/22 00:43:25 $ *
Christoph Lameter8199d3a2005-03-30 13:34:31 -08006 * Description: *
7 * Chelsio 10Gb Ethernet Driver. *
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License, version 2, as *
11 * published by the Free Software Foundation. *
12 * *
13 * You should have received a copy of the GNU General Public License along *
14 * with this program; if not, write to the Free Software Foundation, Inc., *
15 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
16 * *
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED *
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF *
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *
20 * *
21 * http://www.chelsio.com *
22 * *
23 * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. *
24 * All rights reserved. *
25 * *
26 * Maintainers: maintainers@chelsio.com *
27 * *
28 * Authors: Dimitrios Michailidis <dm@chelsio.com> *
29 * Tina Yang <tainay@chelsio.com> *
30 * Felix Marti <felix@chelsio.com> *
31 * Scott Bardone <sbardone@chelsio.com> *
32 * Kurt Ottaway <kottaway@chelsio.com> *
33 * Frank DiMambro <frank@chelsio.com> *
34 * *
35 * History: *
36 * *
37 ****************************************************************************/
38
39#include "common.h"
Christoph Lameter8199d3a2005-03-30 13:34:31 -080040#include <linux/module.h>
41#include <linux/init.h>
42#include <linux/pci.h>
43#include <linux/netdevice.h>
44#include <linux/etherdevice.h>
45#include <linux/if_vlan.h>
46#include <linux/mii.h>
47#include <linux/sockios.h>
Scott Bardone559fb512005-06-23 01:40:19 -040048#include <linux/dma-mapping.h>
Christoph Lameter8199d3a2005-03-30 13:34:31 -080049#include <asm/uaccess.h>
50
Christoph Lameter8199d3a2005-03-30 13:34:31 -080051#include "cpl5_cmd.h"
52#include "regs.h"
53#include "gmac.h"
54#include "cphy.h"
55#include "sge.h"
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -080056#include "tp.h"
Christoph Lameter8199d3a2005-03-30 13:34:31 -080057#include "espi.h"
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -080058#include "elmer0.h"
Christoph Lameter8199d3a2005-03-30 13:34:31 -080059
Scott Bardone559fb512005-06-23 01:40:19 -040060#include <linux/workqueue.h>
61
Christoph Lameter8199d3a2005-03-30 13:34:31 -080062static inline void schedule_mac_stats_update(struct adapter *ap, int secs)
63{
64 schedule_delayed_work(&ap->stats_update_task, secs * HZ);
65}
66
67static inline void cancel_mac_stats_update(struct adapter *ap)
68{
69 cancel_delayed_work(&ap->stats_update_task);
70}
Christoph Lameter8199d3a2005-03-30 13:34:31 -080071
Francois Romieu356bd142006-12-11 23:47:00 +010072#define MAX_CMDQ_ENTRIES 16384
73#define MAX_CMDQ1_ENTRIES 1024
74#define MAX_RX_BUFFERS 16384
75#define MAX_RX_JUMBO_BUFFERS 16384
Christoph Lameter8199d3a2005-03-30 13:34:31 -080076#define MAX_TX_BUFFERS_HIGH 16384U
77#define MAX_TX_BUFFERS_LOW 1536U
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -080078#define MAX_TX_BUFFERS 1460U
Francois Romieu356bd142006-12-11 23:47:00 +010079#define MIN_FL_ENTRIES 32
Christoph Lameter8199d3a2005-03-30 13:34:31 -080080
Christoph Lameter8199d3a2005-03-30 13:34:31 -080081#define DFLT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | \
82 NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP |\
83 NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
84
85/*
86 * The EEPROM is actually bigger but only the first few bytes are used so we
87 * only report those.
88 */
89#define EEPROM_SIZE 32
90
Scott Bardone559fb512005-06-23 01:40:19 -040091MODULE_DESCRIPTION(DRV_DESCRIPTION);
Christoph Lameter8199d3a2005-03-30 13:34:31 -080092MODULE_AUTHOR("Chelsio Communications");
93MODULE_LICENSE("GPL");
Christoph Lameter8199d3a2005-03-30 13:34:31 -080094
95static int dflt_msg_enable = DFLT_MSG_ENABLE;
96
Rusty Russell8d3b33f2006-03-25 03:07:05 -080097module_param(dflt_msg_enable, int, 0);
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -080098MODULE_PARM_DESC(dflt_msg_enable, "Chelsio T1 default message enable bitmap");
Christoph Lameter8199d3a2005-03-30 13:34:31 -080099
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800100#define HCLOCK 0x0
101#define LCLOCK 0x1
102
103/* T1 cards powersave mode */
104static int t1_clock(struct adapter *adapter, int mode);
105static int t1powersave = 1; /* HW default is powersave mode. */
106
107module_param(t1powersave, int, 0);
108MODULE_PARM_DESC(t1powersave, "Enable/Disable T1 powersaving mode");
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800109
Stephen Hemminger325dde42006-12-01 16:36:20 -0800110static int disable_msi = 0;
111module_param(disable_msi, int, 0);
112MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)");
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800113
114static const char pci_speed[][4] = {
115 "33", "66", "100", "133"
116};
117
118/*
119 * Setup MAC to receive the types of packets we want.
120 */
121static void t1_set_rxmode(struct net_device *dev)
122{
123 struct adapter *adapter = dev->priv;
124 struct cmac *mac = adapter->port[dev->if_port].mac;
125 struct t1_rx_mode rm;
126
127 rm.dev = dev;
128 rm.idx = 0;
129 rm.list = dev->mc_list;
130 mac->ops->set_rx_mode(mac, &rm);
131}
132
133static void link_report(struct port_info *p)
134{
135 if (!netif_carrier_ok(p->dev))
Stephen Hemminger20578152006-11-17 11:21:22 -0800136 printk(KERN_INFO "%s: link down\n", p->dev->name);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800137 else {
Scott Bardone559fb512005-06-23 01:40:19 -0400138 const char *s = "10Mbps";
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800139
140 switch (p->link_config.speed) {
Scott Bardone559fb512005-06-23 01:40:19 -0400141 case SPEED_10000: s = "10Gbps"; break;
142 case SPEED_1000: s = "1000Mbps"; break;
143 case SPEED_100: s = "100Mbps"; break;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800144 }
145
Francois Romieu356bd142006-12-11 23:47:00 +0100146 printk(KERN_INFO "%s: link up, %s, %s-duplex\n",
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800147 p->dev->name, s,
148 p->link_config.duplex == DUPLEX_FULL ? "full" : "half");
149 }
150}
151
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800152void t1_link_negotiated(struct adapter *adapter, int port_id, int link_stat,
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800153 int speed, int duplex, int pause)
154{
155 struct port_info *p = &adapter->port[port_id];
156
157 if (link_stat != netif_carrier_ok(p->dev)) {
158 if (link_stat)
159 netif_carrier_on(p->dev);
160 else
161 netif_carrier_off(p->dev);
162 link_report(p);
163
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800164 /* multi-ports: inform toe */
165 if ((speed > 0) && (adapter->params.nports > 1)) {
166 unsigned int sched_speed = 10;
167 switch (speed) {
168 case SPEED_1000:
169 sched_speed = 1000;
170 break;
171 case SPEED_100:
172 sched_speed = 100;
173 break;
174 case SPEED_10:
175 sched_speed = 10;
176 break;
177 }
178 t1_sched_update_parms(adapter->sge, port_id, 0, sched_speed);
179 }
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800180 }
181}
182
183static void link_start(struct port_info *p)
184{
185 struct cmac *mac = p->mac;
186
187 mac->ops->reset(mac);
188 if (mac->ops->macaddress_set)
189 mac->ops->macaddress_set(mac, p->dev->dev_addr);
190 t1_set_rxmode(p->dev);
191 t1_link_start(p->phy, mac, &p->link_config);
192 mac->ops->enable(mac, MAC_DIRECTION_RX | MAC_DIRECTION_TX);
193}
194
195static void enable_hw_csum(struct adapter *adapter)
196{
197 if (adapter->flags & TSO_CAPABLE)
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800198 t1_tp_set_ip_checksum_offload(adapter->tp, 1); /* for TSO only */
199 if (adapter->flags & UDP_CSUM_CAPABLE)
200 t1_tp_set_udp_checksum_offload(adapter->tp, 1);
201 t1_tp_set_tcp_checksum_offload(adapter->tp, 1);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800202}
203
204/*
205 * Things to do upon first use of a card.
206 * This must run with the rtnl lock held.
207 */
208static int cxgb_up(struct adapter *adapter)
209{
210 int err = 0;
211
212 if (!(adapter->flags & FULL_INIT_DONE)) {
213 err = t1_init_hw_modules(adapter);
214 if (err)
215 goto out_err;
216
217 enable_hw_csum(adapter);
218 adapter->flags |= FULL_INIT_DONE;
219 }
220
221 t1_interrupts_clear(adapter);
Stephen Hemminger325dde42006-12-01 16:36:20 -0800222
Stephen Hemminger7fe26a62006-12-08 11:08:33 -0800223 adapter->params.has_msi = !disable_msi && !pci_enable_msi(adapter->pdev);
224 err = request_irq(adapter->pdev->irq, t1_interrupt,
Stephen Hemminger325dde42006-12-01 16:36:20 -0800225 adapter->params.has_msi ? 0 : IRQF_SHARED,
226 adapter->name, adapter);
227 if (err) {
228 if (adapter->params.has_msi)
229 pci_disable_msi(adapter->pdev);
230
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800231 goto out_err;
Scott Bardone559fb512005-06-23 01:40:19 -0400232 }
Stephen Hemminger325dde42006-12-01 16:36:20 -0800233
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800234 t1_sge_start(adapter->sge);
235 t1_interrupts_enable(adapter);
Francois Romieu356bd142006-12-11 23:47:00 +0100236out_err:
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800237 return err;
238}
239
240/*
241 * Release resources when all the ports have been stopped.
242 */
243static void cxgb_down(struct adapter *adapter)
244{
245 t1_sge_stop(adapter->sge);
246 t1_interrupts_disable(adapter);
247 free_irq(adapter->pdev->irq, adapter);
Stephen Hemminger325dde42006-12-01 16:36:20 -0800248 if (adapter->params.has_msi)
249 pci_disable_msi(adapter->pdev);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800250}
251
252static int cxgb_open(struct net_device *dev)
253{
254 int err;
255 struct adapter *adapter = dev->priv;
256 int other_ports = adapter->open_device_map & PORT_MASK;
257
258 if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0)
259 return err;
260
261 __set_bit(dev->if_port, &adapter->open_device_map);
262 link_start(&adapter->port[dev->if_port]);
263 netif_start_queue(dev);
264 if (!other_ports && adapter->params.stats_update_period)
265 schedule_mac_stats_update(adapter,
266 adapter->params.stats_update_period);
267 return 0;
268}
269
270static int cxgb_close(struct net_device *dev)
271{
272 struct adapter *adapter = dev->priv;
273 struct port_info *p = &adapter->port[dev->if_port];
274 struct cmac *mac = p->mac;
275
276 netif_stop_queue(dev);
277 mac->ops->disable(mac, MAC_DIRECTION_TX | MAC_DIRECTION_RX);
278 netif_carrier_off(dev);
279
280 clear_bit(dev->if_port, &adapter->open_device_map);
281 if (adapter->params.stats_update_period &&
282 !(adapter->open_device_map & PORT_MASK)) {
283 /* Stop statistics accumulation. */
284 smp_mb__after_clear_bit();
285 spin_lock(&adapter->work_lock); /* sync with update task */
286 spin_unlock(&adapter->work_lock);
287 cancel_mac_stats_update(adapter);
288 }
289
290 if (!adapter->open_device_map)
291 cxgb_down(adapter);
292 return 0;
293}
294
295static struct net_device_stats *t1_get_stats(struct net_device *dev)
296{
297 struct adapter *adapter = dev->priv;
298 struct port_info *p = &adapter->port[dev->if_port];
299 struct net_device_stats *ns = &p->netstats;
300 const struct cmac_statistics *pstats;
301
302 /* Do a full update of the MAC stats */
303 pstats = p->mac->ops->statistics_update(p->mac,
Stephen Hemminger20578152006-11-17 11:21:22 -0800304 MAC_STATS_UPDATE_FULL);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800305
306 ns->tx_packets = pstats->TxUnicastFramesOK +
307 pstats->TxMulticastFramesOK + pstats->TxBroadcastFramesOK;
308
309 ns->rx_packets = pstats->RxUnicastFramesOK +
310 pstats->RxMulticastFramesOK + pstats->RxBroadcastFramesOK;
311
312 ns->tx_bytes = pstats->TxOctetsOK;
313 ns->rx_bytes = pstats->RxOctetsOK;
314
315 ns->tx_errors = pstats->TxLateCollisions + pstats->TxLengthErrors +
316 pstats->TxUnderrun + pstats->TxFramesAbortedDueToXSCollisions;
317 ns->rx_errors = pstats->RxDataErrors + pstats->RxJabberErrors +
318 pstats->RxFCSErrors + pstats->RxAlignErrors +
319 pstats->RxSequenceErrors + pstats->RxFrameTooLongErrors +
320 pstats->RxSymbolErrors + pstats->RxRuntErrors;
321
322 ns->multicast = pstats->RxMulticastFramesOK;
323 ns->collisions = pstats->TxTotalCollisions;
324
325 /* detailed rx_errors */
326 ns->rx_length_errors = pstats->RxFrameTooLongErrors +
327 pstats->RxJabberErrors;
328 ns->rx_over_errors = 0;
329 ns->rx_crc_errors = pstats->RxFCSErrors;
330 ns->rx_frame_errors = pstats->RxAlignErrors;
331 ns->rx_fifo_errors = 0;
332 ns->rx_missed_errors = 0;
333
334 /* detailed tx_errors */
335 ns->tx_aborted_errors = pstats->TxFramesAbortedDueToXSCollisions;
336 ns->tx_carrier_errors = 0;
337 ns->tx_fifo_errors = pstats->TxUnderrun;
338 ns->tx_heartbeat_errors = 0;
339 ns->tx_window_errors = pstats->TxLateCollisions;
340 return ns;
341}
342
343static u32 get_msglevel(struct net_device *dev)
344{
345 struct adapter *adapter = dev->priv;
346
347 return adapter->msg_enable;
348}
349
350static void set_msglevel(struct net_device *dev, u32 val)
351{
352 struct adapter *adapter = dev->priv;
353
354 adapter->msg_enable = val;
355}
356
357static char stats_strings[][ETH_GSTRING_LEN] = {
Stephen Hemminger20578152006-11-17 11:21:22 -0800358 "TxOctetsOK",
359 "TxOctetsBad",
360 "TxUnicastFramesOK",
361 "TxMulticastFramesOK",
362 "TxBroadcastFramesOK",
363 "TxPauseFrames",
364 "TxFramesWithDeferredXmissions",
365 "TxLateCollisions",
366 "TxTotalCollisions",
367 "TxFramesAbortedDueToXSCollisions",
368 "TxUnderrun",
369 "TxLengthErrors",
370 "TxInternalMACXmitError",
371 "TxFramesWithExcessiveDeferral",
372 "TxFCSErrors",
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800373
Stephen Hemminger20578152006-11-17 11:21:22 -0800374 "RxOctetsOK",
375 "RxOctetsBad",
376 "RxUnicastFramesOK",
377 "RxMulticastFramesOK",
378 "RxBroadcastFramesOK",
379 "RxPauseFrames",
380 "RxFCSErrors",
381 "RxAlignErrors",
382 "RxSymbolErrors",
383 "RxDataErrors",
384 "RxSequenceErrors",
385 "RxRuntErrors",
386 "RxJabberErrors",
387 "RxInternalMACRcvError",
388 "RxInRangeLengthErrors",
389 "RxOutOfRangeLengthField",
390 "RxFrameTooLongErrors",
Scott Bardone559fb512005-06-23 01:40:19 -0400391
Stephen Hemminger56f643c2006-12-01 16:36:21 -0800392 /* Port stats */
393 "RxPackets",
Scott Bardone559fb512005-06-23 01:40:19 -0400394 "RxCsumGood",
Stephen Hemminger56f643c2006-12-01 16:36:21 -0800395 "TxPackets",
Scott Bardone559fb512005-06-23 01:40:19 -0400396 "TxCsumOffload",
Stephen Hemminger56f643c2006-12-01 16:36:21 -0800397 "TxTso",
398 "RxVlan",
399 "TxVlan",
Scott Bardone559fb512005-06-23 01:40:19 -0400400
Stephen Hemminger56f643c2006-12-01 16:36:21 -0800401 /* Interrupt stats */
402 "rx drops",
403 "pure_rsps",
404 "unhandled irqs",
Scott Bardone559fb512005-06-23 01:40:19 -0400405 "respQ_empty",
406 "respQ_overflow",
407 "freelistQ_empty",
408 "pkt_too_big",
409 "pkt_mismatch",
410 "cmdQ_full0",
411 "cmdQ_full1",
Stephen Hemminger20578152006-11-17 11:21:22 -0800412
Scott Bardone559fb512005-06-23 01:40:19 -0400413 "espi_DIP2ParityErr",
414 "espi_DIP4Err",
415 "espi_RxDrops",
416 "espi_TxDrops",
417 "espi_RxOvfl",
418 "espi_ParityErr"
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800419};
Stephen Hemminger20578152006-11-17 11:21:22 -0800420
Scott Bardone559fb512005-06-23 01:40:19 -0400421#define T2_REGMAP_SIZE (3 * 1024)
422
423static int get_regs_len(struct net_device *dev)
424{
425 return T2_REGMAP_SIZE;
426}
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800427
428static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
429{
430 struct adapter *adapter = dev->priv;
431
Scott Bardone559fb512005-06-23 01:40:19 -0400432 strcpy(info->driver, DRV_NAME);
433 strcpy(info->version, DRV_VERSION);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800434 strcpy(info->fw_version, "N/A");
435 strcpy(info->bus_info, pci_name(adapter->pdev));
436}
437
438static int get_stats_count(struct net_device *dev)
439{
440 return ARRAY_SIZE(stats_strings);
441}
442
443static void get_strings(struct net_device *dev, u32 stringset, u8 *data)
444{
445 if (stringset == ETH_SS_STATS)
446 memcpy(data, stats_strings, sizeof(stats_strings));
447}
448
449static void get_stats(struct net_device *dev, struct ethtool_stats *stats,
450 u64 *data)
451{
452 struct adapter *adapter = dev->priv;
453 struct cmac *mac = adapter->port[dev->if_port].mac;
454 const struct cmac_statistics *s;
Scott Bardone559fb512005-06-23 01:40:19 -0400455 const struct sge_intr_counts *t;
Stephen Hemminger56f643c2006-12-01 16:36:21 -0800456 struct sge_port_stats ss;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800457
458 s = mac->ops->statistics_update(mac, MAC_STATS_UPDATE_FULL);
459
Stephen Hemminger20578152006-11-17 11:21:22 -0800460 *data++ = s->TxOctetsOK;
461 *data++ = s->TxOctetsBad;
462 *data++ = s->TxUnicastFramesOK;
463 *data++ = s->TxMulticastFramesOK;
464 *data++ = s->TxBroadcastFramesOK;
465 *data++ = s->TxPauseFrames;
466 *data++ = s->TxFramesWithDeferredXmissions;
467 *data++ = s->TxLateCollisions;
468 *data++ = s->TxTotalCollisions;
469 *data++ = s->TxFramesAbortedDueToXSCollisions;
470 *data++ = s->TxUnderrun;
471 *data++ = s->TxLengthErrors;
472 *data++ = s->TxInternalMACXmitError;
473 *data++ = s->TxFramesWithExcessiveDeferral;
474 *data++ = s->TxFCSErrors;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800475
Stephen Hemminger20578152006-11-17 11:21:22 -0800476 *data++ = s->RxOctetsOK;
477 *data++ = s->RxOctetsBad;
478 *data++ = s->RxUnicastFramesOK;
479 *data++ = s->RxMulticastFramesOK;
480 *data++ = s->RxBroadcastFramesOK;
481 *data++ = s->RxPauseFrames;
482 *data++ = s->RxFCSErrors;
483 *data++ = s->RxAlignErrors;
484 *data++ = s->RxSymbolErrors;
485 *data++ = s->RxDataErrors;
486 *data++ = s->RxSequenceErrors;
487 *data++ = s->RxRuntErrors;
488 *data++ = s->RxJabberErrors;
489 *data++ = s->RxInternalMACRcvError;
490 *data++ = s->RxInRangeLengthErrors;
491 *data++ = s->RxOutOfRangeLengthField;
492 *data++ = s->RxFrameTooLongErrors;
Scott Bardone559fb512005-06-23 01:40:19 -0400493
Stephen Hemminger56f643c2006-12-01 16:36:21 -0800494 t1_sge_get_port_stats(adapter->sge, dev->if_port, &ss);
495 *data++ = ss.rx_packets;
496 *data++ = ss.rx_cso_good;
497 *data++ = ss.tx_packets;
498 *data++ = ss.tx_cso;
499 *data++ = ss.tx_tso;
500 *data++ = ss.vlan_xtract;
501 *data++ = ss.vlan_insert;
Scott Bardone559fb512005-06-23 01:40:19 -0400502
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800503 t = t1_sge_get_intr_counts(adapter->sge);
Stephen Hemminger56f643c2006-12-01 16:36:21 -0800504 *data++ = t->rx_drops;
505 *data++ = t->pure_rsps;
506 *data++ = t->unhandled_irqs;
507 *data++ = t->respQ_empty;
508 *data++ = t->respQ_overflow;
509 *data++ = t->freelistQ_empty;
510 *data++ = t->pkt_too_big;
511 *data++ = t->pkt_mismatch;
512 *data++ = t->cmdQ_full[0];
513 *data++ = t->cmdQ_full[1];
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800514
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800515 if (adapter->espi) {
516 const struct espi_intr_counts *e;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800517
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800518 e = t1_espi_get_intr_counts(adapter->espi);
Stephen Hemminger56f643c2006-12-01 16:36:21 -0800519 *data++ = e->DIP2_parity_err;
520 *data++ = e->DIP4_err;
521 *data++ = e->rx_drops;
522 *data++ = e->tx_drops;
523 *data++ = e->rx_ovflw;
524 *data++ = e->parity_err;
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800525 }
Scott Bardone559fb512005-06-23 01:40:19 -0400526}
527
528static inline void reg_block_dump(struct adapter *ap, void *buf,
529 unsigned int start, unsigned int end)
530{
531 u32 *p = buf + start;
532
533 for ( ; start <= end; start += sizeof(u32))
534 *p++ = readl(ap->regs + start);
535}
536
537static void get_regs(struct net_device *dev, struct ethtool_regs *regs,
538 void *buf)
539{
540 struct adapter *ap = dev->priv;
541
542 /*
543 * Version scheme: bits 0..9: chip version, bits 10..15: chip revision
544 */
545 regs->version = 2;
546
547 memset(buf, 0, T2_REGMAP_SIZE);
548 reg_block_dump(ap, buf, 0, A_SG_RESPACCUTIMER);
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800549 reg_block_dump(ap, buf, A_MC3_CFG, A_MC4_INT_CAUSE);
550 reg_block_dump(ap, buf, A_TPI_ADDR, A_TPI_PAR);
551 reg_block_dump(ap, buf, A_TP_IN_CONFIG, A_TP_TX_DROP_COUNT);
552 reg_block_dump(ap, buf, A_RAT_ROUTE_CONTROL, A_RAT_INTR_CAUSE);
553 reg_block_dump(ap, buf, A_CSPI_RX_AE_WM, A_CSPI_INTR_ENABLE);
554 reg_block_dump(ap, buf, A_ESPI_SCH_TOKEN0, A_ESPI_GOSTAT);
555 reg_block_dump(ap, buf, A_ULP_ULIMIT, A_ULP_PIO_CTRL);
556 reg_block_dump(ap, buf, A_PL_ENABLE, A_PL_CAUSE);
557 reg_block_dump(ap, buf, A_MC5_CONFIG, A_MC5_MASK_WRITE_CMD);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800558}
559
560static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
561{
562 struct adapter *adapter = dev->priv;
563 struct port_info *p = &adapter->port[dev->if_port];
564
565 cmd->supported = p->link_config.supported;
566 cmd->advertising = p->link_config.advertising;
567
568 if (netif_carrier_ok(dev)) {
569 cmd->speed = p->link_config.speed;
570 cmd->duplex = p->link_config.duplex;
571 } else {
572 cmd->speed = -1;
573 cmd->duplex = -1;
574 }
575
Stephen Hemminger20578152006-11-17 11:21:22 -0800576 cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE;
577 cmd->phy_address = p->phy->addr;
578 cmd->transceiver = XCVR_EXTERNAL;
579 cmd->autoneg = p->link_config.autoneg;
580 cmd->maxtxpkt = 0;
581 cmd->maxrxpkt = 0;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800582 return 0;
583}
584
585static int speed_duplex_to_caps(int speed, int duplex)
586{
587 int cap = 0;
588
589 switch (speed) {
590 case SPEED_10:
591 if (duplex == DUPLEX_FULL)
592 cap = SUPPORTED_10baseT_Full;
593 else
594 cap = SUPPORTED_10baseT_Half;
595 break;
596 case SPEED_100:
597 if (duplex == DUPLEX_FULL)
598 cap = SUPPORTED_100baseT_Full;
599 else
600 cap = SUPPORTED_100baseT_Half;
601 break;
602 case SPEED_1000:
603 if (duplex == DUPLEX_FULL)
604 cap = SUPPORTED_1000baseT_Full;
605 else
606 cap = SUPPORTED_1000baseT_Half;
607 break;
608 case SPEED_10000:
609 if (duplex == DUPLEX_FULL)
610 cap = SUPPORTED_10000baseT_Full;
611 }
612 return cap;
613}
614
615#define ADVERTISED_MASK (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | \
616 ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | \
617 ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full | \
618 ADVERTISED_10000baseT_Full)
619
620static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
621{
622 struct adapter *adapter = dev->priv;
623 struct port_info *p = &adapter->port[dev->if_port];
624 struct link_config *lc = &p->link_config;
625
626 if (!(lc->supported & SUPPORTED_Autoneg))
Scott Bardone559fb512005-06-23 01:40:19 -0400627 return -EOPNOTSUPP; /* can't change speed/duplex */
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800628
629 if (cmd->autoneg == AUTONEG_DISABLE) {
630 int cap = speed_duplex_to_caps(cmd->speed, cmd->duplex);
631
632 if (!(lc->supported & cap) || cmd->speed == SPEED_1000)
633 return -EINVAL;
634 lc->requested_speed = cmd->speed;
635 lc->requested_duplex = cmd->duplex;
636 lc->advertising = 0;
637 } else {
638 cmd->advertising &= ADVERTISED_MASK;
639 if (cmd->advertising & (cmd->advertising - 1))
640 cmd->advertising = lc->supported;
641 cmd->advertising &= lc->supported;
642 if (!cmd->advertising)
643 return -EINVAL;
644 lc->requested_speed = SPEED_INVALID;
645 lc->requested_duplex = DUPLEX_INVALID;
646 lc->advertising = cmd->advertising | ADVERTISED_Autoneg;
647 }
648 lc->autoneg = cmd->autoneg;
649 if (netif_running(dev))
650 t1_link_start(p->phy, p->mac, lc);
651 return 0;
652}
653
654static void get_pauseparam(struct net_device *dev,
655 struct ethtool_pauseparam *epause)
656{
657 struct adapter *adapter = dev->priv;
658 struct port_info *p = &adapter->port[dev->if_port];
659
660 epause->autoneg = (p->link_config.requested_fc & PAUSE_AUTONEG) != 0;
661 epause->rx_pause = (p->link_config.fc & PAUSE_RX) != 0;
662 epause->tx_pause = (p->link_config.fc & PAUSE_TX) != 0;
663}
664
665static int set_pauseparam(struct net_device *dev,
666 struct ethtool_pauseparam *epause)
667{
668 struct adapter *adapter = dev->priv;
669 struct port_info *p = &adapter->port[dev->if_port];
670 struct link_config *lc = &p->link_config;
671
672 if (epause->autoneg == AUTONEG_DISABLE)
673 lc->requested_fc = 0;
674 else if (lc->supported & SUPPORTED_Autoneg)
675 lc->requested_fc = PAUSE_AUTONEG;
676 else
677 return -EINVAL;
678
679 if (epause->rx_pause)
680 lc->requested_fc |= PAUSE_RX;
681 if (epause->tx_pause)
682 lc->requested_fc |= PAUSE_TX;
683 if (lc->autoneg == AUTONEG_ENABLE) {
684 if (netif_running(dev))
685 t1_link_start(p->phy, p->mac, lc);
686 } else {
687 lc->fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
688 if (netif_running(dev))
689 p->mac->ops->set_speed_duplex_fc(p->mac, -1, -1,
690 lc->fc);
691 }
692 return 0;
693}
694
695static u32 get_rx_csum(struct net_device *dev)
696{
697 struct adapter *adapter = dev->priv;
698
699 return (adapter->flags & RX_CSUM_ENABLED) != 0;
700}
701
702static int set_rx_csum(struct net_device *dev, u32 data)
703{
704 struct adapter *adapter = dev->priv;
705
706 if (data)
707 adapter->flags |= RX_CSUM_ENABLED;
708 else
709 adapter->flags &= ~RX_CSUM_ENABLED;
710 return 0;
711}
712
713static int set_tso(struct net_device *dev, u32 value)
714{
715 struct adapter *adapter = dev->priv;
716
717 if (!(adapter->flags & TSO_CAPABLE))
718 return value ? -EOPNOTSUPP : 0;
719 return ethtool_op_set_tso(dev, value);
720}
721
722static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
723{
724 struct adapter *adapter = dev->priv;
725 int jumbo_fl = t1_is_T1B(adapter) ? 1 : 0;
726
727 e->rx_max_pending = MAX_RX_BUFFERS;
728 e->rx_mini_max_pending = 0;
729 e->rx_jumbo_max_pending = MAX_RX_JUMBO_BUFFERS;
730 e->tx_max_pending = MAX_CMDQ_ENTRIES;
731
732 e->rx_pending = adapter->params.sge.freelQ_size[!jumbo_fl];
733 e->rx_mini_pending = 0;
734 e->rx_jumbo_pending = adapter->params.sge.freelQ_size[jumbo_fl];
735 e->tx_pending = adapter->params.sge.cmdQ_size[0];
736}
737
738static int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
739{
740 struct adapter *adapter = dev->priv;
741 int jumbo_fl = t1_is_T1B(adapter) ? 1 : 0;
742
743 if (e->rx_pending > MAX_RX_BUFFERS || e->rx_mini_pending ||
744 e->rx_jumbo_pending > MAX_RX_JUMBO_BUFFERS ||
745 e->tx_pending > MAX_CMDQ_ENTRIES ||
746 e->rx_pending < MIN_FL_ENTRIES ||
747 e->rx_jumbo_pending < MIN_FL_ENTRIES ||
748 e->tx_pending < (adapter->params.nports + 1) * (MAX_SKB_FRAGS + 1))
749 return -EINVAL;
750
751 if (adapter->flags & FULL_INIT_DONE)
Francois Romieu356bd142006-12-11 23:47:00 +0100752 return -EBUSY;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800753
754 adapter->params.sge.freelQ_size[!jumbo_fl] = e->rx_pending;
755 adapter->params.sge.freelQ_size[jumbo_fl] = e->rx_jumbo_pending;
756 adapter->params.sge.cmdQ_size[0] = e->tx_pending;
757 adapter->params.sge.cmdQ_size[1] = e->tx_pending > MAX_CMDQ1_ENTRIES ?
758 MAX_CMDQ1_ENTRIES : e->tx_pending;
759 return 0;
760}
761
762static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
763{
764 struct adapter *adapter = dev->priv;
765
Stephen Hemminger7fe26a62006-12-08 11:08:33 -0800766 adapter->params.sge.rx_coalesce_usecs = c->rx_coalesce_usecs;
Francois Romieu356bd142006-12-11 23:47:00 +0100767 adapter->params.sge.coalesce_enable = c->use_adaptive_rx_coalesce;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800768 adapter->params.sge.sample_interval_usecs = c->rate_sample_interval;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800769 t1_sge_set_coalesce_params(adapter->sge, &adapter->params.sge);
770 return 0;
771}
772
773static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
774{
775 struct adapter *adapter = dev->priv;
776
Scott Bardone559fb512005-06-23 01:40:19 -0400777 c->rx_coalesce_usecs = adapter->params.sge.rx_coalesce_usecs;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800778 c->rate_sample_interval = adapter->params.sge.sample_interval_usecs;
779 c->use_adaptive_rx_coalesce = adapter->params.sge.coalesce_enable;
780 return 0;
781}
782
783static int get_eeprom_len(struct net_device *dev)
784{
Francois Romieu356bd142006-12-11 23:47:00 +0100785 struct adapter *adapter = dev->priv;
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800786
Francois Romieu356bd142006-12-11 23:47:00 +0100787 return t1_is_asic(adapter) ? EEPROM_SIZE : 0;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800788}
789
790#define EEPROM_MAGIC(ap) \
791 (PCI_VENDOR_ID_CHELSIO | ((ap)->params.chip_version << 16))
792
793static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *e,
794 u8 *data)
795{
796 int i;
797 u8 buf[EEPROM_SIZE] __attribute__((aligned(4)));
798 struct adapter *adapter = dev->priv;
799
800 e->magic = EEPROM_MAGIC(adapter);
801 for (i = e->offset & ~3; i < e->offset + e->len; i += sizeof(u32))
802 t1_seeprom_read(adapter, i, (u32 *)&buf[i]);
803 memcpy(data, buf + e->offset, e->len);
804 return 0;
805}
806
Jeff Garzik7282d492006-09-13 14:30:00 -0400807static const struct ethtool_ops t1_ethtool_ops = {
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800808 .get_settings = get_settings,
809 .set_settings = set_settings,
810 .get_drvinfo = get_drvinfo,
811 .get_msglevel = get_msglevel,
812 .set_msglevel = set_msglevel,
813 .get_ringparam = get_sge_param,
814 .set_ringparam = set_sge_param,
815 .get_coalesce = get_coalesce,
816 .set_coalesce = set_coalesce,
817 .get_eeprom_len = get_eeprom_len,
818 .get_eeprom = get_eeprom,
819 .get_pauseparam = get_pauseparam,
820 .set_pauseparam = set_pauseparam,
821 .get_rx_csum = get_rx_csum,
822 .set_rx_csum = set_rx_csum,
823 .get_tx_csum = ethtool_op_get_tx_csum,
824 .set_tx_csum = ethtool_op_set_tx_csum,
825 .get_sg = ethtool_op_get_sg,
826 .set_sg = ethtool_op_set_sg,
827 .get_link = ethtool_op_get_link,
828 .get_strings = get_strings,
829 .get_stats_count = get_stats_count,
830 .get_ethtool_stats = get_stats,
Scott Bardone559fb512005-06-23 01:40:19 -0400831 .get_regs_len = get_regs_len,
832 .get_regs = get_regs,
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800833 .get_tso = ethtool_op_get_tso,
834 .set_tso = set_tso,
835};
836
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800837static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
838{
Stephen Hemminger20578152006-11-17 11:21:22 -0800839 struct adapter *adapter = dev->priv;
840 struct mii_ioctl_data *data = if_mii(req);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800841
842 switch (cmd) {
Stephen Hemminger20578152006-11-17 11:21:22 -0800843 case SIOCGMIIPHY:
844 data->phy_id = adapter->port[dev->if_port].phy->addr;
845 /* FALLTHRU */
846 case SIOCGMIIREG: {
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800847 struct cphy *phy = adapter->port[dev->if_port].phy;
848 u32 val;
849
Scott Bardone559fb512005-06-23 01:40:19 -0400850 if (!phy->mdio_read)
Francois Romieu356bd142006-12-11 23:47:00 +0100851 return -EOPNOTSUPP;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800852 phy->mdio_read(adapter, data->phy_id, 0, data->reg_num & 0x1f,
853 &val);
Stephen Hemminger20578152006-11-17 11:21:22 -0800854 data->val_out = val;
855 break;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800856 }
Stephen Hemminger20578152006-11-17 11:21:22 -0800857 case SIOCSMIIREG: {
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800858 struct cphy *phy = adapter->port[dev->if_port].phy;
859
Stephen Hemminger20578152006-11-17 11:21:22 -0800860 if (!capable(CAP_NET_ADMIN))
861 return -EPERM;
Scott Bardone559fb512005-06-23 01:40:19 -0400862 if (!phy->mdio_write)
Francois Romieu356bd142006-12-11 23:47:00 +0100863 return -EOPNOTSUPP;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800864 phy->mdio_write(adapter, data->phy_id, 0, data->reg_num & 0x1f,
Scott Bardone559fb512005-06-23 01:40:19 -0400865 data->val_in);
Stephen Hemminger20578152006-11-17 11:21:22 -0800866 break;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800867 }
868
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800869 default:
870 return -EOPNOTSUPP;
871 }
872 return 0;
873}
874
875static int t1_change_mtu(struct net_device *dev, int new_mtu)
876{
877 int ret;
878 struct adapter *adapter = dev->priv;
879 struct cmac *mac = adapter->port[dev->if_port].mac;
880
881 if (!mac->ops->set_mtu)
Francois Romieu356bd142006-12-11 23:47:00 +0100882 return -EOPNOTSUPP;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800883 if (new_mtu < 68)
Francois Romieu356bd142006-12-11 23:47:00 +0100884 return -EINVAL;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800885 if ((ret = mac->ops->set_mtu(mac, new_mtu)))
886 return ret;
887 dev->mtu = new_mtu;
888 return 0;
889}
890
891static int t1_set_mac_addr(struct net_device *dev, void *p)
892{
893 struct adapter *adapter = dev->priv;
894 struct cmac *mac = adapter->port[dev->if_port].mac;
895 struct sockaddr *addr = p;
896
897 if (!mac->ops->macaddress_set)
898 return -EOPNOTSUPP;
899
900 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
901 mac->ops->macaddress_set(mac, dev->dev_addr);
902 return 0;
903}
904
905#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
906static void vlan_rx_register(struct net_device *dev,
907 struct vlan_group *grp)
908{
909 struct adapter *adapter = dev->priv;
910
911 spin_lock_irq(&adapter->async_lock);
912 adapter->vlan_grp = grp;
913 t1_set_vlan_accel(adapter, grp != NULL);
914 spin_unlock_irq(&adapter->async_lock);
915}
916
917static void vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
918{
919 struct adapter *adapter = dev->priv;
920
921 spin_lock_irq(&adapter->async_lock);
922 if (adapter->vlan_grp)
923 adapter->vlan_grp->vlan_devices[vid] = NULL;
924 spin_unlock_irq(&adapter->async_lock);
925}
926#endif
927
928#ifdef CONFIG_NET_POLL_CONTROLLER
929static void t1_netpoll(struct net_device *dev)
930{
Scott Bardone559fb512005-06-23 01:40:19 -0400931 unsigned long flags;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800932 struct adapter *adapter = dev->priv;
933
Scott Bardone559fb512005-06-23 01:40:19 -0400934 local_irq_save(flags);
Stephen Hemminger7fe26a62006-12-08 11:08:33 -0800935 t1_interrupt(adapter->pdev->irq, adapter);
Scott Bardone559fb512005-06-23 01:40:19 -0400936 local_irq_restore(flags);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800937}
938#endif
939
940/*
941 * Periodic accumulation of MAC statistics. This is used only if the MAC
942 * does not have any other way to prevent stats counter overflow.
943 */
David Howellsc4028952006-11-22 14:57:56 +0000944static void mac_stats_task(struct work_struct *work)
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800945{
946 int i;
David Howellsc4028952006-11-22 14:57:56 +0000947 struct adapter *adapter =
948 container_of(work, struct adapter, stats_update_task.work);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800949
950 for_each_port(adapter, i) {
951 struct port_info *p = &adapter->port[i];
952
953 if (netif_running(p->dev))
954 p->mac->ops->statistics_update(p->mac,
955 MAC_STATS_UPDATE_FAST);
956 }
957
958 /* Schedule the next statistics update if any port is active. */
959 spin_lock(&adapter->work_lock);
960 if (adapter->open_device_map & PORT_MASK)
961 schedule_mac_stats_update(adapter,
962 adapter->params.stats_update_period);
963 spin_unlock(&adapter->work_lock);
964}
965
966/*
967 * Processes elmer0 external interrupts in process context.
968 */
David Howellsc4028952006-11-22 14:57:56 +0000969static void ext_intr_task(struct work_struct *work)
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800970{
David Howellsc4028952006-11-22 14:57:56 +0000971 struct adapter *adapter =
972 container_of(work, struct adapter, ext_intr_handler_task);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800973
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800974 t1_elmer0_ext_intr_handler(adapter);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800975
976 /* Now reenable external interrupts */
Scott Bardone559fb512005-06-23 01:40:19 -0400977 spin_lock_irq(&adapter->async_lock);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800978 adapter->slow_intr_mask |= F_PL_INTR_EXT;
Scott Bardone559fb512005-06-23 01:40:19 -0400979 writel(F_PL_INTR_EXT, adapter->regs + A_PL_CAUSE);
980 writel(adapter->slow_intr_mask | F_PL_INTR_SGE_DATA,
Stephen Hemminger20578152006-11-17 11:21:22 -0800981 adapter->regs + A_PL_ENABLE);
Scott Bardone559fb512005-06-23 01:40:19 -0400982 spin_unlock_irq(&adapter->async_lock);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800983}
984
985/*
986 * Interrupt-context handler for elmer0 external interrupts.
987 */
988void t1_elmer0_ext_intr(struct adapter *adapter)
989{
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800990 /*
991 * Schedule a task to handle external interrupts as we require
992 * a process context. We disable EXT interrupts in the interim
993 * and let the task reenable them when it's done.
994 */
995 adapter->slow_intr_mask &= ~F_PL_INTR_EXT;
Scott Bardone559fb512005-06-23 01:40:19 -0400996 writel(adapter->slow_intr_mask | F_PL_INTR_SGE_DATA,
Stephen Hemminger20578152006-11-17 11:21:22 -0800997 adapter->regs + A_PL_ENABLE);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800998 schedule_work(&adapter->ext_intr_handler_task);
999}
1000
1001void t1_fatal_err(struct adapter *adapter)
1002{
1003 if (adapter->flags & FULL_INIT_DONE) {
1004 t1_sge_stop(adapter->sge);
1005 t1_interrupts_disable(adapter);
1006 }
1007 CH_ALERT("%s: encountered fatal error, operation suspended\n",
1008 adapter->name);
1009}
1010
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001011static int __devinit init_one(struct pci_dev *pdev,
1012 const struct pci_device_id *ent)
1013{
1014 static int version_printed;
1015
1016 int i, err, pci_using_dac = 0;
1017 unsigned long mmio_start, mmio_len;
1018 const struct board_info *bi;
1019 struct adapter *adapter = NULL;
1020 struct port_info *pi;
1021
1022 if (!version_printed) {
Scott Bardone559fb512005-06-23 01:40:19 -04001023 printk(KERN_INFO "%s - version %s\n", DRV_DESCRIPTION,
1024 DRV_VERSION);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001025 ++version_printed;
1026 }
1027
1028 err = pci_enable_device(pdev);
1029 if (err)
Stephen Hemminger20578152006-11-17 11:21:22 -08001030 return err;
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001031
1032 if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
1033 CH_ERR("%s: cannot find PCI device memory base address\n",
1034 pci_name(pdev));
1035 err = -ENODEV;
1036 goto out_disable_pdev;
1037 }
1038
Scott Bardone559fb512005-06-23 01:40:19 -04001039 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001040 pci_using_dac = 1;
Scott Bardone559fb512005-06-23 01:40:19 -04001041
1042 if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001043 CH_ERR("%s: unable to obtain 64-bit DMA for"
1044 "consistent allocations\n", pci_name(pdev));
1045 err = -ENODEV;
1046 goto out_disable_pdev;
1047 }
Scott Bardone559fb512005-06-23 01:40:19 -04001048
1049 } else if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) != 0) {
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001050 CH_ERR("%s: no usable DMA configuration\n", pci_name(pdev));
1051 goto out_disable_pdev;
1052 }
1053
Scott Bardone559fb512005-06-23 01:40:19 -04001054 err = pci_request_regions(pdev, DRV_NAME);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001055 if (err) {
1056 CH_ERR("%s: cannot obtain PCI resources\n", pci_name(pdev));
1057 goto out_disable_pdev;
1058 }
1059
1060 pci_set_master(pdev);
1061
Stephen Hemminger20578152006-11-17 11:21:22 -08001062 mmio_start = pci_resource_start(pdev, 0);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001063 mmio_len = pci_resource_len(pdev, 0);
1064 bi = t1_get_board_info(ent->driver_data);
1065
1066 for (i = 0; i < bi->port_number; ++i) {
1067 struct net_device *netdev;
1068
1069 netdev = alloc_etherdev(adapter ? 0 : sizeof(*adapter));
1070 if (!netdev) {
1071 err = -ENOMEM;
1072 goto out_free_dev;
1073 }
1074
1075 SET_MODULE_OWNER(netdev);
1076 SET_NETDEV_DEV(netdev, &pdev->dev);
1077
1078 if (!adapter) {
1079 adapter = netdev->priv;
1080 adapter->pdev = pdev;
1081 adapter->port[0].dev = netdev; /* so we don't leak it */
1082
1083 adapter->regs = ioremap(mmio_start, mmio_len);
1084 if (!adapter->regs) {
1085 CH_ERR("%s: cannot map device registers\n",
1086 pci_name(pdev));
1087 err = -ENOMEM;
1088 goto out_free_dev;
1089 }
1090
1091 if (t1_get_board_rev(adapter, bi, &adapter->params)) {
1092 err = -ENODEV; /* Can't handle this chip rev */
1093 goto out_free_dev;
1094 }
1095
1096 adapter->name = pci_name(pdev);
1097 adapter->msg_enable = dflt_msg_enable;
1098 adapter->mmio_len = mmio_len;
1099
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001100 spin_lock_init(&adapter->tpi_lock);
1101 spin_lock_init(&adapter->work_lock);
1102 spin_lock_init(&adapter->async_lock);
Stephen Hemminger352c4172006-12-01 16:36:17 -08001103 spin_lock_init(&adapter->mac_lock);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001104
1105 INIT_WORK(&adapter->ext_intr_handler_task,
David Howellsc4028952006-11-22 14:57:56 +00001106 ext_intr_task);
1107 INIT_DELAYED_WORK(&adapter->stats_update_task,
1108 mac_stats_task);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001109
1110 pci_set_drvdata(pdev, netdev);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001111 }
1112
1113 pi = &adapter->port[i];
1114 pi->dev = netdev;
1115 netif_carrier_off(netdev);
1116 netdev->irq = pdev->irq;
1117 netdev->if_port = i;
1118 netdev->mem_start = mmio_start;
1119 netdev->mem_end = mmio_start + mmio_len - 1;
1120 netdev->priv = adapter;
1121 netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
Scott Bardone559fb512005-06-23 01:40:19 -04001122 netdev->features |= NETIF_F_LLTX;
1123
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001124 adapter->flags |= RX_CSUM_ENABLED | TCP_CSUM_CAPABLE;
1125 if (pci_using_dac)
1126 netdev->features |= NETIF_F_HIGHDMA;
1127 if (vlan_tso_capable(adapter)) {
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001128#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
1129 adapter->flags |= VLAN_ACCEL_CAPABLE;
1130 netdev->features |=
1131 NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
1132 netdev->vlan_rx_register = vlan_rx_register;
1133 netdev->vlan_rx_kill_vid = vlan_rx_kill_vid;
1134#endif
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001135
1136 /* T204: disable TSO */
1137 if (!(is_T2(adapter)) || bi->port_number != 4) {
1138 adapter->flags |= TSO_CAPABLE;
1139 netdev->features |= NETIF_F_TSO;
1140 }
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001141 }
1142
1143 netdev->open = cxgb_open;
1144 netdev->stop = cxgb_close;
1145 netdev->hard_start_xmit = t1_start_xmit;
1146 netdev->hard_header_len += (adapter->flags & TSO_CAPABLE) ?
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001147 sizeof(struct cpl_tx_pkt_lso) : sizeof(struct cpl_tx_pkt);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001148 netdev->get_stats = t1_get_stats;
1149 netdev->set_multicast_list = t1_set_rxmode;
1150 netdev->do_ioctl = t1_ioctl;
1151 netdev->change_mtu = t1_change_mtu;
1152 netdev->set_mac_address = t1_set_mac_addr;
1153#ifdef CONFIG_NET_POLL_CONTROLLER
1154 netdev->poll_controller = t1_netpoll;
1155#endif
Stephen Hemminger7fe26a62006-12-08 11:08:33 -08001156#ifdef CONFIG_CHELSIO_T1_NAPI
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001157 netdev->weight = 64;
Stephen Hemminger7fe26a62006-12-08 11:08:33 -08001158 netdev->poll = t1_poll;
1159#endif
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001160
Stephen Hemminger20578152006-11-17 11:21:22 -08001161 SET_ETHTOOL_OPS(netdev, &t1_ethtool_ops);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001162 }
1163
1164 if (t1_init_sw_modules(adapter, bi) < 0) {
1165 err = -ENODEV;
1166 goto out_free_dev;
1167 }
1168
1169 /*
1170 * The card is now ready to go. If any errors occur during device
1171 * registration we do not fail the whole card but rather proceed only
1172 * with the ports we manage to register successfully. However we must
1173 * register at least one net device.
1174 */
1175 for (i = 0; i < bi->port_number; ++i) {
1176 err = register_netdev(adapter->port[i].dev);
1177 if (err)
1178 CH_WARN("%s: cannot register net device %s, skipping\n",
1179 pci_name(pdev), adapter->port[i].dev->name);
1180 else {
1181 /*
1182 * Change the name we use for messages to the name of
1183 * the first successfully registered interface.
1184 */
1185 if (!adapter->registered_device_map)
1186 adapter->name = adapter->port[i].dev->name;
1187
Stephen Hemminger20578152006-11-17 11:21:22 -08001188 __set_bit(i, &adapter->registered_device_map);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001189 }
1190 }
1191 if (!adapter->registered_device_map) {
1192 CH_ERR("%s: could not register any net devices\n",
1193 pci_name(pdev));
1194 goto out_release_adapter_res;
1195 }
1196
1197 printk(KERN_INFO "%s: %s (rev %d), %s %dMHz/%d-bit\n", adapter->name,
1198 bi->desc, adapter->params.chip_revision,
1199 adapter->params.pci.is_pcix ? "PCIX" : "PCI",
1200 adapter->params.pci.speed, adapter->params.pci.width);
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001201
1202 /*
1203 * Set the T1B ASIC and memory clocks.
1204 */
1205 if (t1powersave)
1206 adapter->t1powersave = LCLOCK; /* HW default is powersave mode. */
1207 else
1208 adapter->t1powersave = HCLOCK;
1209 if (t1_is_T1B(adapter))
1210 t1_clock(adapter, t1powersave);
1211
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001212 return 0;
1213
Francois Romieu356bd142006-12-11 23:47:00 +01001214out_release_adapter_res:
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001215 t1_free_sw_modules(adapter);
Francois Romieu356bd142006-12-11 23:47:00 +01001216out_free_dev:
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001217 if (adapter) {
Stephen Hemmingere4876472006-11-17 11:25:23 -08001218 if (adapter->regs)
1219 iounmap(adapter->regs);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001220 for (i = bi->port_number - 1; i >= 0; --i)
Stephen Hemmingere4876472006-11-17 11:25:23 -08001221 if (adapter->port[i].dev)
1222 free_netdev(adapter->port[i].dev);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001223 }
1224 pci_release_regions(pdev);
Francois Romieu356bd142006-12-11 23:47:00 +01001225out_disable_pdev:
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001226 pci_disable_device(pdev);
1227 pci_set_drvdata(pdev, NULL);
1228 return err;
1229}
1230
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001231static void bit_bang(struct adapter *adapter, int bitdata, int nbits)
1232{
1233 int data;
1234 int i;
1235 u32 val;
1236
1237 enum {
1238 S_CLOCK = 1 << 3,
1239 S_DATA = 1 << 4
1240 };
1241
1242 for (i = (nbits - 1); i > -1; i--) {
1243
1244 udelay(50);
1245
1246 data = ((bitdata >> i) & 0x1);
1247 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1248
1249 if (data)
1250 val |= S_DATA;
1251 else
1252 val &= ~S_DATA;
1253
1254 udelay(50);
1255
1256 /* Set SCLOCK low */
1257 val &= ~S_CLOCK;
1258 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1259
1260 udelay(50);
1261
1262 /* Write SCLOCK high */
1263 val |= S_CLOCK;
1264 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1265
1266 }
1267}
1268
1269static int t1_clock(struct adapter *adapter, int mode)
1270{
1271 u32 val;
1272 int M_CORE_VAL;
1273 int M_MEM_VAL;
1274
1275 enum {
Francois Romieu356bd142006-12-11 23:47:00 +01001276 M_CORE_BITS = 9,
1277 T_CORE_VAL = 0,
1278 T_CORE_BITS = 2,
1279 N_CORE_VAL = 0,
1280 N_CORE_BITS = 2,
1281 M_MEM_BITS = 9,
1282 T_MEM_VAL = 0,
1283 T_MEM_BITS = 2,
1284 N_MEM_VAL = 0,
1285 N_MEM_BITS = 2,
1286 NP_LOAD = 1 << 17,
1287 S_LOAD_MEM = 1 << 5,
1288 S_LOAD_CORE = 1 << 6,
1289 S_CLOCK = 1 << 3
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001290 };
1291
1292 if (!t1_is_T1B(adapter))
1293 return -ENODEV; /* Can't re-clock this chip. */
1294
Francois Romieud7487422006-12-11 23:49:13 +01001295 if (mode & 2)
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001296 return 0; /* show current mode. */
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001297
1298 if ((adapter->t1powersave & 1) == (mode & 1))
1299 return -EALREADY; /* ASIC already running in mode. */
1300
1301 if ((mode & 1) == HCLOCK) {
1302 M_CORE_VAL = 0x14;
1303 M_MEM_VAL = 0x18;
1304 adapter->t1powersave = HCLOCK; /* overclock */
1305 } else {
1306 M_CORE_VAL = 0xe;
1307 M_MEM_VAL = 0x10;
1308 adapter->t1powersave = LCLOCK; /* underclock */
1309 }
1310
1311 /* Don't interrupt this serial stream! */
1312 spin_lock(&adapter->tpi_lock);
1313
1314 /* Initialize for ASIC core */
1315 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1316 val |= NP_LOAD;
1317 udelay(50);
1318 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1319 udelay(50);
1320 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1321 val &= ~S_LOAD_CORE;
1322 val &= ~S_CLOCK;
1323 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1324 udelay(50);
1325
1326 /* Serial program the ASIC clock synthesizer */
1327 bit_bang(adapter, T_CORE_VAL, T_CORE_BITS);
1328 bit_bang(adapter, N_CORE_VAL, N_CORE_BITS);
1329 bit_bang(adapter, M_CORE_VAL, M_CORE_BITS);
1330 udelay(50);
1331
1332 /* Finish ASIC core */
1333 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1334 val |= S_LOAD_CORE;
1335 udelay(50);
1336 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1337 udelay(50);
1338 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1339 val &= ~S_LOAD_CORE;
1340 udelay(50);
1341 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1342 udelay(50);
1343
1344 /* Initialize for memory */
1345 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1346 val |= NP_LOAD;
1347 udelay(50);
1348 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1349 udelay(50);
1350 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1351 val &= ~S_LOAD_MEM;
1352 val &= ~S_CLOCK;
1353 udelay(50);
1354 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1355 udelay(50);
1356
1357 /* Serial program the memory clock synthesizer */
1358 bit_bang(adapter, T_MEM_VAL, T_MEM_BITS);
1359 bit_bang(adapter, N_MEM_VAL, N_MEM_BITS);
1360 bit_bang(adapter, M_MEM_VAL, M_MEM_BITS);
1361 udelay(50);
1362
1363 /* Finish memory */
1364 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1365 val |= S_LOAD_MEM;
1366 udelay(50);
1367 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1368 udelay(50);
1369 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1370 val &= ~S_LOAD_MEM;
1371 udelay(50);
1372 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1373
1374 spin_unlock(&adapter->tpi_lock);
1375
1376 return 0;
1377}
1378
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001379static inline void t1_sw_reset(struct pci_dev *pdev)
1380{
1381 pci_write_config_dword(pdev, A_PCICFG_PM_CSR, 3);
1382 pci_write_config_dword(pdev, A_PCICFG_PM_CSR, 0);
1383}
1384
1385static void __devexit remove_one(struct pci_dev *pdev)
1386{
1387 struct net_device *dev = pci_get_drvdata(pdev);
Francois Romieu47cbe6f2006-12-05 23:19:06 +01001388 struct adapter *adapter = dev->priv;
1389 int i;
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001390
Francois Romieu47cbe6f2006-12-05 23:19:06 +01001391 for_each_port(adapter, i) {
1392 if (test_bit(i, &adapter->registered_device_map))
1393 unregister_netdev(adapter->port[i].dev);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001394 }
Francois Romieu47cbe6f2006-12-05 23:19:06 +01001395
1396 t1_free_sw_modules(adapter);
1397 iounmap(adapter->regs);
1398
1399 while (--i >= 0) {
1400 if (adapter->port[i].dev)
1401 free_netdev(adapter->port[i].dev);
1402 }
1403
1404 pci_release_regions(pdev);
1405 pci_disable_device(pdev);
1406 pci_set_drvdata(pdev, NULL);
1407 t1_sw_reset(pdev);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001408}
1409
1410static struct pci_driver driver = {
Scott Bardone559fb512005-06-23 01:40:19 -04001411 .name = DRV_NAME,
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001412 .id_table = t1_pci_tbl,
1413 .probe = init_one,
1414 .remove = __devexit_p(remove_one),
1415};
1416
1417static int __init t1_init_module(void)
1418{
Jeff Garzik29917622006-08-19 17:48:59 -04001419 return pci_register_driver(&driver);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001420}
1421
1422static void __exit t1_cleanup_module(void)
1423{
1424 pci_unregister_driver(&driver);
1425}
1426
1427module_init(t1_init_module);
1428module_exit(t1_cleanup_module);