blob: 593736c7550d1cb089c70be822cf192436d9f874 [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
Stephen Hemmingerbea33482007-10-03 16:41:36 -0700258 napi_enable(&adapter->napi);
259 if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0) {
260 napi_disable(&adapter->napi);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800261 return err;
Stephen Hemmingerbea33482007-10-03 16:41:36 -0700262 }
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800263
264 __set_bit(dev->if_port, &adapter->open_device_map);
265 link_start(&adapter->port[dev->if_port]);
266 netif_start_queue(dev);
267 if (!other_ports && adapter->params.stats_update_period)
268 schedule_mac_stats_update(adapter,
269 adapter->params.stats_update_period);
270 return 0;
271}
272
273static int cxgb_close(struct net_device *dev)
274{
275 struct adapter *adapter = dev->priv;
276 struct port_info *p = &adapter->port[dev->if_port];
277 struct cmac *mac = p->mac;
278
279 netif_stop_queue(dev);
Stephen Hemmingerbea33482007-10-03 16:41:36 -0700280 napi_disable(&adapter->napi);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800281 mac->ops->disable(mac, MAC_DIRECTION_TX | MAC_DIRECTION_RX);
282 netif_carrier_off(dev);
283
284 clear_bit(dev->if_port, &adapter->open_device_map);
285 if (adapter->params.stats_update_period &&
286 !(adapter->open_device_map & PORT_MASK)) {
287 /* Stop statistics accumulation. */
288 smp_mb__after_clear_bit();
289 spin_lock(&adapter->work_lock); /* sync with update task */
290 spin_unlock(&adapter->work_lock);
291 cancel_mac_stats_update(adapter);
292 }
293
294 if (!adapter->open_device_map)
295 cxgb_down(adapter);
296 return 0;
297}
298
299static struct net_device_stats *t1_get_stats(struct net_device *dev)
300{
301 struct adapter *adapter = dev->priv;
302 struct port_info *p = &adapter->port[dev->if_port];
303 struct net_device_stats *ns = &p->netstats;
304 const struct cmac_statistics *pstats;
305
306 /* Do a full update of the MAC stats */
307 pstats = p->mac->ops->statistics_update(p->mac,
Stephen Hemminger20578152006-11-17 11:21:22 -0800308 MAC_STATS_UPDATE_FULL);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800309
310 ns->tx_packets = pstats->TxUnicastFramesOK +
311 pstats->TxMulticastFramesOK + pstats->TxBroadcastFramesOK;
312
313 ns->rx_packets = pstats->RxUnicastFramesOK +
314 pstats->RxMulticastFramesOK + pstats->RxBroadcastFramesOK;
315
316 ns->tx_bytes = pstats->TxOctetsOK;
317 ns->rx_bytes = pstats->RxOctetsOK;
318
319 ns->tx_errors = pstats->TxLateCollisions + pstats->TxLengthErrors +
320 pstats->TxUnderrun + pstats->TxFramesAbortedDueToXSCollisions;
321 ns->rx_errors = pstats->RxDataErrors + pstats->RxJabberErrors +
322 pstats->RxFCSErrors + pstats->RxAlignErrors +
323 pstats->RxSequenceErrors + pstats->RxFrameTooLongErrors +
324 pstats->RxSymbolErrors + pstats->RxRuntErrors;
325
326 ns->multicast = pstats->RxMulticastFramesOK;
327 ns->collisions = pstats->TxTotalCollisions;
328
329 /* detailed rx_errors */
330 ns->rx_length_errors = pstats->RxFrameTooLongErrors +
331 pstats->RxJabberErrors;
332 ns->rx_over_errors = 0;
333 ns->rx_crc_errors = pstats->RxFCSErrors;
334 ns->rx_frame_errors = pstats->RxAlignErrors;
335 ns->rx_fifo_errors = 0;
336 ns->rx_missed_errors = 0;
337
338 /* detailed tx_errors */
339 ns->tx_aborted_errors = pstats->TxFramesAbortedDueToXSCollisions;
340 ns->tx_carrier_errors = 0;
341 ns->tx_fifo_errors = pstats->TxUnderrun;
342 ns->tx_heartbeat_errors = 0;
343 ns->tx_window_errors = pstats->TxLateCollisions;
344 return ns;
345}
346
347static u32 get_msglevel(struct net_device *dev)
348{
349 struct adapter *adapter = dev->priv;
350
351 return adapter->msg_enable;
352}
353
354static void set_msglevel(struct net_device *dev, u32 val)
355{
356 struct adapter *adapter = dev->priv;
357
358 adapter->msg_enable = val;
359}
360
361static char stats_strings[][ETH_GSTRING_LEN] = {
Stephen Hemminger20578152006-11-17 11:21:22 -0800362 "TxOctetsOK",
363 "TxOctetsBad",
364 "TxUnicastFramesOK",
365 "TxMulticastFramesOK",
366 "TxBroadcastFramesOK",
367 "TxPauseFrames",
368 "TxFramesWithDeferredXmissions",
369 "TxLateCollisions",
370 "TxTotalCollisions",
371 "TxFramesAbortedDueToXSCollisions",
372 "TxUnderrun",
373 "TxLengthErrors",
374 "TxInternalMACXmitError",
375 "TxFramesWithExcessiveDeferral",
376 "TxFCSErrors",
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800377
Stephen Hemminger20578152006-11-17 11:21:22 -0800378 "RxOctetsOK",
379 "RxOctetsBad",
380 "RxUnicastFramesOK",
381 "RxMulticastFramesOK",
382 "RxBroadcastFramesOK",
383 "RxPauseFrames",
384 "RxFCSErrors",
385 "RxAlignErrors",
386 "RxSymbolErrors",
387 "RxDataErrors",
388 "RxSequenceErrors",
389 "RxRuntErrors",
390 "RxJabberErrors",
391 "RxInternalMACRcvError",
392 "RxInRangeLengthErrors",
393 "RxOutOfRangeLengthField",
394 "RxFrameTooLongErrors",
Scott Bardone559fb512005-06-23 01:40:19 -0400395
Stephen Hemminger56f643c2006-12-01 16:36:21 -0800396 /* Port stats */
397 "RxPackets",
Scott Bardone559fb512005-06-23 01:40:19 -0400398 "RxCsumGood",
Stephen Hemminger56f643c2006-12-01 16:36:21 -0800399 "TxPackets",
Scott Bardone559fb512005-06-23 01:40:19 -0400400 "TxCsumOffload",
Stephen Hemminger56f643c2006-12-01 16:36:21 -0800401 "TxTso",
402 "RxVlan",
403 "TxVlan",
Scott Bardone559fb512005-06-23 01:40:19 -0400404
Stephen Hemminger56f643c2006-12-01 16:36:21 -0800405 /* Interrupt stats */
406 "rx drops",
407 "pure_rsps",
408 "unhandled irqs",
Scott Bardone559fb512005-06-23 01:40:19 -0400409 "respQ_empty",
410 "respQ_overflow",
411 "freelistQ_empty",
412 "pkt_too_big",
413 "pkt_mismatch",
414 "cmdQ_full0",
415 "cmdQ_full1",
Stephen Hemminger20578152006-11-17 11:21:22 -0800416
Scott Bardone559fb512005-06-23 01:40:19 -0400417 "espi_DIP2ParityErr",
418 "espi_DIP4Err",
419 "espi_RxDrops",
420 "espi_TxDrops",
421 "espi_RxOvfl",
422 "espi_ParityErr"
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800423};
Stephen Hemminger20578152006-11-17 11:21:22 -0800424
Scott Bardone559fb512005-06-23 01:40:19 -0400425#define T2_REGMAP_SIZE (3 * 1024)
426
427static int get_regs_len(struct net_device *dev)
428{
429 return T2_REGMAP_SIZE;
430}
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800431
432static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
433{
434 struct adapter *adapter = dev->priv;
435
Scott Bardone559fb512005-06-23 01:40:19 -0400436 strcpy(info->driver, DRV_NAME);
437 strcpy(info->version, DRV_VERSION);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800438 strcpy(info->fw_version, "N/A");
439 strcpy(info->bus_info, pci_name(adapter->pdev));
440}
441
442static int get_stats_count(struct net_device *dev)
443{
444 return ARRAY_SIZE(stats_strings);
445}
446
447static void get_strings(struct net_device *dev, u32 stringset, u8 *data)
448{
449 if (stringset == ETH_SS_STATS)
450 memcpy(data, stats_strings, sizeof(stats_strings));
451}
452
453static void get_stats(struct net_device *dev, struct ethtool_stats *stats,
454 u64 *data)
455{
456 struct adapter *adapter = dev->priv;
457 struct cmac *mac = adapter->port[dev->if_port].mac;
458 const struct cmac_statistics *s;
Scott Bardone559fb512005-06-23 01:40:19 -0400459 const struct sge_intr_counts *t;
Stephen Hemminger56f643c2006-12-01 16:36:21 -0800460 struct sge_port_stats ss;
Francois Romieu83432462006-12-12 00:13:48 +0100461 unsigned int len;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800462
463 s = mac->ops->statistics_update(mac, MAC_STATS_UPDATE_FULL);
464
Francois Romieu83432462006-12-12 00:13:48 +0100465 len = sizeof(u64)*(&s->TxFCSErrors + 1 - &s->TxOctetsOK);
466 memcpy(data, &s->TxOctetsOK, len);
467 data += len;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800468
Francois Romieu83432462006-12-12 00:13:48 +0100469 len = sizeof(u64)*(&s->RxFrameTooLongErrors + 1 - &s->RxOctetsOK);
470 memcpy(data, &s->RxOctetsOK, len);
471 data += len;
Scott Bardone559fb512005-06-23 01:40:19 -0400472
Stephen Hemminger56f643c2006-12-01 16:36:21 -0800473 t1_sge_get_port_stats(adapter->sge, dev->if_port, &ss);
Francois Romieu83432462006-12-12 00:13:48 +0100474 memcpy(data, &ss, sizeof(ss));
475 data += sizeof(ss);
Scott Bardone559fb512005-06-23 01:40:19 -0400476
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800477 t = t1_sge_get_intr_counts(adapter->sge);
Stephen Hemminger56f643c2006-12-01 16:36:21 -0800478 *data++ = t->rx_drops;
479 *data++ = t->pure_rsps;
480 *data++ = t->unhandled_irqs;
481 *data++ = t->respQ_empty;
482 *data++ = t->respQ_overflow;
483 *data++ = t->freelistQ_empty;
484 *data++ = t->pkt_too_big;
485 *data++ = t->pkt_mismatch;
486 *data++ = t->cmdQ_full[0];
487 *data++ = t->cmdQ_full[1];
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800488
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800489 if (adapter->espi) {
490 const struct espi_intr_counts *e;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800491
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800492 e = t1_espi_get_intr_counts(adapter->espi);
Stephen Hemminger56f643c2006-12-01 16:36:21 -0800493 *data++ = e->DIP2_parity_err;
494 *data++ = e->DIP4_err;
495 *data++ = e->rx_drops;
496 *data++ = e->tx_drops;
497 *data++ = e->rx_ovflw;
498 *data++ = e->parity_err;
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800499 }
Scott Bardone559fb512005-06-23 01:40:19 -0400500}
501
502static inline void reg_block_dump(struct adapter *ap, void *buf,
503 unsigned int start, unsigned int end)
504{
505 u32 *p = buf + start;
506
507 for ( ; start <= end; start += sizeof(u32))
508 *p++ = readl(ap->regs + start);
509}
510
511static void get_regs(struct net_device *dev, struct ethtool_regs *regs,
512 void *buf)
513{
514 struct adapter *ap = dev->priv;
515
516 /*
517 * Version scheme: bits 0..9: chip version, bits 10..15: chip revision
518 */
519 regs->version = 2;
520
521 memset(buf, 0, T2_REGMAP_SIZE);
522 reg_block_dump(ap, buf, 0, A_SG_RESPACCUTIMER);
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800523 reg_block_dump(ap, buf, A_MC3_CFG, A_MC4_INT_CAUSE);
524 reg_block_dump(ap, buf, A_TPI_ADDR, A_TPI_PAR);
525 reg_block_dump(ap, buf, A_TP_IN_CONFIG, A_TP_TX_DROP_COUNT);
526 reg_block_dump(ap, buf, A_RAT_ROUTE_CONTROL, A_RAT_INTR_CAUSE);
527 reg_block_dump(ap, buf, A_CSPI_RX_AE_WM, A_CSPI_INTR_ENABLE);
528 reg_block_dump(ap, buf, A_ESPI_SCH_TOKEN0, A_ESPI_GOSTAT);
529 reg_block_dump(ap, buf, A_ULP_ULIMIT, A_ULP_PIO_CTRL);
530 reg_block_dump(ap, buf, A_PL_ENABLE, A_PL_CAUSE);
531 reg_block_dump(ap, buf, A_MC5_CONFIG, A_MC5_MASK_WRITE_CMD);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800532}
533
534static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
535{
536 struct adapter *adapter = dev->priv;
537 struct port_info *p = &adapter->port[dev->if_port];
538
539 cmd->supported = p->link_config.supported;
540 cmd->advertising = p->link_config.advertising;
541
542 if (netif_carrier_ok(dev)) {
543 cmd->speed = p->link_config.speed;
544 cmd->duplex = p->link_config.duplex;
545 } else {
546 cmd->speed = -1;
547 cmd->duplex = -1;
548 }
549
Stephen Hemminger20578152006-11-17 11:21:22 -0800550 cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE;
551 cmd->phy_address = p->phy->addr;
552 cmd->transceiver = XCVR_EXTERNAL;
553 cmd->autoneg = p->link_config.autoneg;
554 cmd->maxtxpkt = 0;
555 cmd->maxrxpkt = 0;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800556 return 0;
557}
558
559static int speed_duplex_to_caps(int speed, int duplex)
560{
561 int cap = 0;
562
563 switch (speed) {
564 case SPEED_10:
565 if (duplex == DUPLEX_FULL)
566 cap = SUPPORTED_10baseT_Full;
567 else
568 cap = SUPPORTED_10baseT_Half;
569 break;
570 case SPEED_100:
571 if (duplex == DUPLEX_FULL)
572 cap = SUPPORTED_100baseT_Full;
573 else
574 cap = SUPPORTED_100baseT_Half;
575 break;
576 case SPEED_1000:
577 if (duplex == DUPLEX_FULL)
578 cap = SUPPORTED_1000baseT_Full;
579 else
580 cap = SUPPORTED_1000baseT_Half;
581 break;
582 case SPEED_10000:
583 if (duplex == DUPLEX_FULL)
584 cap = SUPPORTED_10000baseT_Full;
585 }
586 return cap;
587}
588
589#define ADVERTISED_MASK (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | \
590 ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | \
591 ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full | \
592 ADVERTISED_10000baseT_Full)
593
594static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
595{
596 struct adapter *adapter = dev->priv;
597 struct port_info *p = &adapter->port[dev->if_port];
598 struct link_config *lc = &p->link_config;
599
600 if (!(lc->supported & SUPPORTED_Autoneg))
Scott Bardone559fb512005-06-23 01:40:19 -0400601 return -EOPNOTSUPP; /* can't change speed/duplex */
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800602
603 if (cmd->autoneg == AUTONEG_DISABLE) {
604 int cap = speed_duplex_to_caps(cmd->speed, cmd->duplex);
605
606 if (!(lc->supported & cap) || cmd->speed == SPEED_1000)
607 return -EINVAL;
608 lc->requested_speed = cmd->speed;
609 lc->requested_duplex = cmd->duplex;
610 lc->advertising = 0;
611 } else {
612 cmd->advertising &= ADVERTISED_MASK;
613 if (cmd->advertising & (cmd->advertising - 1))
614 cmd->advertising = lc->supported;
615 cmd->advertising &= lc->supported;
616 if (!cmd->advertising)
617 return -EINVAL;
618 lc->requested_speed = SPEED_INVALID;
619 lc->requested_duplex = DUPLEX_INVALID;
620 lc->advertising = cmd->advertising | ADVERTISED_Autoneg;
621 }
622 lc->autoneg = cmd->autoneg;
623 if (netif_running(dev))
624 t1_link_start(p->phy, p->mac, lc);
625 return 0;
626}
627
628static void get_pauseparam(struct net_device *dev,
629 struct ethtool_pauseparam *epause)
630{
631 struct adapter *adapter = dev->priv;
632 struct port_info *p = &adapter->port[dev->if_port];
633
634 epause->autoneg = (p->link_config.requested_fc & PAUSE_AUTONEG) != 0;
635 epause->rx_pause = (p->link_config.fc & PAUSE_RX) != 0;
636 epause->tx_pause = (p->link_config.fc & PAUSE_TX) != 0;
637}
638
639static int set_pauseparam(struct net_device *dev,
640 struct ethtool_pauseparam *epause)
641{
642 struct adapter *adapter = dev->priv;
643 struct port_info *p = &adapter->port[dev->if_port];
644 struct link_config *lc = &p->link_config;
645
646 if (epause->autoneg == AUTONEG_DISABLE)
647 lc->requested_fc = 0;
648 else if (lc->supported & SUPPORTED_Autoneg)
649 lc->requested_fc = PAUSE_AUTONEG;
650 else
651 return -EINVAL;
652
653 if (epause->rx_pause)
654 lc->requested_fc |= PAUSE_RX;
655 if (epause->tx_pause)
656 lc->requested_fc |= PAUSE_TX;
657 if (lc->autoneg == AUTONEG_ENABLE) {
658 if (netif_running(dev))
659 t1_link_start(p->phy, p->mac, lc);
660 } else {
661 lc->fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
662 if (netif_running(dev))
663 p->mac->ops->set_speed_duplex_fc(p->mac, -1, -1,
664 lc->fc);
665 }
666 return 0;
667}
668
669static u32 get_rx_csum(struct net_device *dev)
670{
671 struct adapter *adapter = dev->priv;
672
673 return (adapter->flags & RX_CSUM_ENABLED) != 0;
674}
675
676static int set_rx_csum(struct net_device *dev, u32 data)
677{
678 struct adapter *adapter = dev->priv;
679
680 if (data)
681 adapter->flags |= RX_CSUM_ENABLED;
682 else
683 adapter->flags &= ~RX_CSUM_ENABLED;
684 return 0;
685}
686
687static int set_tso(struct net_device *dev, u32 value)
688{
689 struct adapter *adapter = dev->priv;
690
691 if (!(adapter->flags & TSO_CAPABLE))
692 return value ? -EOPNOTSUPP : 0;
693 return ethtool_op_set_tso(dev, value);
694}
695
696static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
697{
698 struct adapter *adapter = dev->priv;
699 int jumbo_fl = t1_is_T1B(adapter) ? 1 : 0;
700
701 e->rx_max_pending = MAX_RX_BUFFERS;
702 e->rx_mini_max_pending = 0;
703 e->rx_jumbo_max_pending = MAX_RX_JUMBO_BUFFERS;
704 e->tx_max_pending = MAX_CMDQ_ENTRIES;
705
706 e->rx_pending = adapter->params.sge.freelQ_size[!jumbo_fl];
707 e->rx_mini_pending = 0;
708 e->rx_jumbo_pending = adapter->params.sge.freelQ_size[jumbo_fl];
709 e->tx_pending = adapter->params.sge.cmdQ_size[0];
710}
711
712static int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
713{
714 struct adapter *adapter = dev->priv;
715 int jumbo_fl = t1_is_T1B(adapter) ? 1 : 0;
716
717 if (e->rx_pending > MAX_RX_BUFFERS || e->rx_mini_pending ||
718 e->rx_jumbo_pending > MAX_RX_JUMBO_BUFFERS ||
719 e->tx_pending > MAX_CMDQ_ENTRIES ||
720 e->rx_pending < MIN_FL_ENTRIES ||
721 e->rx_jumbo_pending < MIN_FL_ENTRIES ||
722 e->tx_pending < (adapter->params.nports + 1) * (MAX_SKB_FRAGS + 1))
723 return -EINVAL;
724
725 if (adapter->flags & FULL_INIT_DONE)
Francois Romieu356bd142006-12-11 23:47:00 +0100726 return -EBUSY;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800727
728 adapter->params.sge.freelQ_size[!jumbo_fl] = e->rx_pending;
729 adapter->params.sge.freelQ_size[jumbo_fl] = e->rx_jumbo_pending;
730 adapter->params.sge.cmdQ_size[0] = e->tx_pending;
731 adapter->params.sge.cmdQ_size[1] = e->tx_pending > MAX_CMDQ1_ENTRIES ?
732 MAX_CMDQ1_ENTRIES : e->tx_pending;
733 return 0;
734}
735
736static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
737{
738 struct adapter *adapter = dev->priv;
739
Stephen Hemminger7fe26a62006-12-08 11:08:33 -0800740 adapter->params.sge.rx_coalesce_usecs = c->rx_coalesce_usecs;
Francois Romieu356bd142006-12-11 23:47:00 +0100741 adapter->params.sge.coalesce_enable = c->use_adaptive_rx_coalesce;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800742 adapter->params.sge.sample_interval_usecs = c->rate_sample_interval;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800743 t1_sge_set_coalesce_params(adapter->sge, &adapter->params.sge);
744 return 0;
745}
746
747static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
748{
749 struct adapter *adapter = dev->priv;
750
Scott Bardone559fb512005-06-23 01:40:19 -0400751 c->rx_coalesce_usecs = adapter->params.sge.rx_coalesce_usecs;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800752 c->rate_sample_interval = adapter->params.sge.sample_interval_usecs;
753 c->use_adaptive_rx_coalesce = adapter->params.sge.coalesce_enable;
754 return 0;
755}
756
757static int get_eeprom_len(struct net_device *dev)
758{
Francois Romieu356bd142006-12-11 23:47:00 +0100759 struct adapter *adapter = dev->priv;
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800760
Francois Romieu356bd142006-12-11 23:47:00 +0100761 return t1_is_asic(adapter) ? EEPROM_SIZE : 0;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800762}
763
764#define EEPROM_MAGIC(ap) \
765 (PCI_VENDOR_ID_CHELSIO | ((ap)->params.chip_version << 16))
766
767static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *e,
768 u8 *data)
769{
770 int i;
771 u8 buf[EEPROM_SIZE] __attribute__((aligned(4)));
772 struct adapter *adapter = dev->priv;
773
774 e->magic = EEPROM_MAGIC(adapter);
775 for (i = e->offset & ~3; i < e->offset + e->len; i += sizeof(u32))
776 t1_seeprom_read(adapter, i, (u32 *)&buf[i]);
777 memcpy(data, buf + e->offset, e->len);
778 return 0;
779}
780
Jeff Garzik7282d492006-09-13 14:30:00 -0400781static const struct ethtool_ops t1_ethtool_ops = {
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800782 .get_settings = get_settings,
783 .set_settings = set_settings,
784 .get_drvinfo = get_drvinfo,
785 .get_msglevel = get_msglevel,
786 .set_msglevel = set_msglevel,
787 .get_ringparam = get_sge_param,
788 .set_ringparam = set_sge_param,
789 .get_coalesce = get_coalesce,
790 .set_coalesce = set_coalesce,
791 .get_eeprom_len = get_eeprom_len,
792 .get_eeprom = get_eeprom,
793 .get_pauseparam = get_pauseparam,
794 .set_pauseparam = set_pauseparam,
795 .get_rx_csum = get_rx_csum,
796 .set_rx_csum = set_rx_csum,
797 .get_tx_csum = ethtool_op_get_tx_csum,
798 .set_tx_csum = ethtool_op_set_tx_csum,
799 .get_sg = ethtool_op_get_sg,
800 .set_sg = ethtool_op_set_sg,
801 .get_link = ethtool_op_get_link,
802 .get_strings = get_strings,
803 .get_stats_count = get_stats_count,
804 .get_ethtool_stats = get_stats,
Scott Bardone559fb512005-06-23 01:40:19 -0400805 .get_regs_len = get_regs_len,
806 .get_regs = get_regs,
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800807 .get_tso = ethtool_op_get_tso,
808 .set_tso = set_tso,
809};
810
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800811static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
812{
Stephen Hemminger20578152006-11-17 11:21:22 -0800813 struct adapter *adapter = dev->priv;
814 struct mii_ioctl_data *data = if_mii(req);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800815
816 switch (cmd) {
Stephen Hemminger20578152006-11-17 11:21:22 -0800817 case SIOCGMIIPHY:
818 data->phy_id = adapter->port[dev->if_port].phy->addr;
819 /* FALLTHRU */
820 case SIOCGMIIREG: {
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800821 struct cphy *phy = adapter->port[dev->if_port].phy;
822 u32 val;
823
Scott Bardone559fb512005-06-23 01:40:19 -0400824 if (!phy->mdio_read)
Francois Romieu356bd142006-12-11 23:47:00 +0100825 return -EOPNOTSUPP;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800826 phy->mdio_read(adapter, data->phy_id, 0, data->reg_num & 0x1f,
827 &val);
Stephen Hemminger20578152006-11-17 11:21:22 -0800828 data->val_out = val;
829 break;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800830 }
Stephen Hemminger20578152006-11-17 11:21:22 -0800831 case SIOCSMIIREG: {
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800832 struct cphy *phy = adapter->port[dev->if_port].phy;
833
Stephen Hemminger20578152006-11-17 11:21:22 -0800834 if (!capable(CAP_NET_ADMIN))
835 return -EPERM;
Scott Bardone559fb512005-06-23 01:40:19 -0400836 if (!phy->mdio_write)
Francois Romieu356bd142006-12-11 23:47:00 +0100837 return -EOPNOTSUPP;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800838 phy->mdio_write(adapter, data->phy_id, 0, data->reg_num & 0x1f,
Scott Bardone559fb512005-06-23 01:40:19 -0400839 data->val_in);
Stephen Hemminger20578152006-11-17 11:21:22 -0800840 break;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800841 }
842
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800843 default:
844 return -EOPNOTSUPP;
845 }
846 return 0;
847}
848
849static int t1_change_mtu(struct net_device *dev, int new_mtu)
850{
851 int ret;
852 struct adapter *adapter = dev->priv;
853 struct cmac *mac = adapter->port[dev->if_port].mac;
854
855 if (!mac->ops->set_mtu)
Francois Romieu356bd142006-12-11 23:47:00 +0100856 return -EOPNOTSUPP;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800857 if (new_mtu < 68)
Francois Romieu356bd142006-12-11 23:47:00 +0100858 return -EINVAL;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800859 if ((ret = mac->ops->set_mtu(mac, new_mtu)))
860 return ret;
861 dev->mtu = new_mtu;
862 return 0;
863}
864
865static int t1_set_mac_addr(struct net_device *dev, void *p)
866{
867 struct adapter *adapter = dev->priv;
868 struct cmac *mac = adapter->port[dev->if_port].mac;
869 struct sockaddr *addr = p;
870
871 if (!mac->ops->macaddress_set)
872 return -EOPNOTSUPP;
873
874 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
875 mac->ops->macaddress_set(mac, dev->dev_addr);
876 return 0;
877}
878
879#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
880static void vlan_rx_register(struct net_device *dev,
881 struct vlan_group *grp)
882{
883 struct adapter *adapter = dev->priv;
884
885 spin_lock_irq(&adapter->async_lock);
886 adapter->vlan_grp = grp;
887 t1_set_vlan_accel(adapter, grp != NULL);
888 spin_unlock_irq(&adapter->async_lock);
889}
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800890#endif
891
892#ifdef CONFIG_NET_POLL_CONTROLLER
893static void t1_netpoll(struct net_device *dev)
894{
Scott Bardone559fb512005-06-23 01:40:19 -0400895 unsigned long flags;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800896 struct adapter *adapter = dev->priv;
897
Scott Bardone559fb512005-06-23 01:40:19 -0400898 local_irq_save(flags);
Stephen Hemminger7fe26a62006-12-08 11:08:33 -0800899 t1_interrupt(adapter->pdev->irq, adapter);
Scott Bardone559fb512005-06-23 01:40:19 -0400900 local_irq_restore(flags);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800901}
902#endif
903
904/*
905 * Periodic accumulation of MAC statistics. This is used only if the MAC
906 * does not have any other way to prevent stats counter overflow.
907 */
David Howellsc4028952006-11-22 14:57:56 +0000908static void mac_stats_task(struct work_struct *work)
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800909{
910 int i;
David Howellsc4028952006-11-22 14:57:56 +0000911 struct adapter *adapter =
912 container_of(work, struct adapter, stats_update_task.work);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800913
914 for_each_port(adapter, i) {
915 struct port_info *p = &adapter->port[i];
916
917 if (netif_running(p->dev))
918 p->mac->ops->statistics_update(p->mac,
919 MAC_STATS_UPDATE_FAST);
920 }
921
922 /* Schedule the next statistics update if any port is active. */
923 spin_lock(&adapter->work_lock);
924 if (adapter->open_device_map & PORT_MASK)
925 schedule_mac_stats_update(adapter,
926 adapter->params.stats_update_period);
927 spin_unlock(&adapter->work_lock);
928}
929
930/*
931 * Processes elmer0 external interrupts in process context.
932 */
David Howellsc4028952006-11-22 14:57:56 +0000933static void ext_intr_task(struct work_struct *work)
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800934{
David Howellsc4028952006-11-22 14:57:56 +0000935 struct adapter *adapter =
936 container_of(work, struct adapter, ext_intr_handler_task);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800937
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800938 t1_elmer0_ext_intr_handler(adapter);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800939
940 /* Now reenable external interrupts */
Scott Bardone559fb512005-06-23 01:40:19 -0400941 spin_lock_irq(&adapter->async_lock);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800942 adapter->slow_intr_mask |= F_PL_INTR_EXT;
Scott Bardone559fb512005-06-23 01:40:19 -0400943 writel(F_PL_INTR_EXT, adapter->regs + A_PL_CAUSE);
944 writel(adapter->slow_intr_mask | F_PL_INTR_SGE_DATA,
Stephen Hemminger20578152006-11-17 11:21:22 -0800945 adapter->regs + A_PL_ENABLE);
Scott Bardone559fb512005-06-23 01:40:19 -0400946 spin_unlock_irq(&adapter->async_lock);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800947}
948
949/*
950 * Interrupt-context handler for elmer0 external interrupts.
951 */
952void t1_elmer0_ext_intr(struct adapter *adapter)
953{
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800954 /*
955 * Schedule a task to handle external interrupts as we require
956 * a process context. We disable EXT interrupts in the interim
957 * and let the task reenable them when it's done.
958 */
959 adapter->slow_intr_mask &= ~F_PL_INTR_EXT;
Scott Bardone559fb512005-06-23 01:40:19 -0400960 writel(adapter->slow_intr_mask | F_PL_INTR_SGE_DATA,
Stephen Hemminger20578152006-11-17 11:21:22 -0800961 adapter->regs + A_PL_ENABLE);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800962 schedule_work(&adapter->ext_intr_handler_task);
963}
964
965void t1_fatal_err(struct adapter *adapter)
966{
967 if (adapter->flags & FULL_INIT_DONE) {
968 t1_sge_stop(adapter->sge);
969 t1_interrupts_disable(adapter);
970 }
971 CH_ALERT("%s: encountered fatal error, operation suspended\n",
972 adapter->name);
973}
974
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800975static int __devinit init_one(struct pci_dev *pdev,
976 const struct pci_device_id *ent)
977{
978 static int version_printed;
979
980 int i, err, pci_using_dac = 0;
981 unsigned long mmio_start, mmio_len;
982 const struct board_info *bi;
983 struct adapter *adapter = NULL;
984 struct port_info *pi;
985
986 if (!version_printed) {
Scott Bardone559fb512005-06-23 01:40:19 -0400987 printk(KERN_INFO "%s - version %s\n", DRV_DESCRIPTION,
988 DRV_VERSION);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800989 ++version_printed;
990 }
991
992 err = pci_enable_device(pdev);
993 if (err)
Stephen Hemminger20578152006-11-17 11:21:22 -0800994 return err;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800995
996 if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
997 CH_ERR("%s: cannot find PCI device memory base address\n",
998 pci_name(pdev));
999 err = -ENODEV;
1000 goto out_disable_pdev;
1001 }
1002
Scott Bardone559fb512005-06-23 01:40:19 -04001003 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001004 pci_using_dac = 1;
Scott Bardone559fb512005-06-23 01:40:19 -04001005
1006 if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001007 CH_ERR("%s: unable to obtain 64-bit DMA for"
1008 "consistent allocations\n", pci_name(pdev));
1009 err = -ENODEV;
1010 goto out_disable_pdev;
1011 }
Scott Bardone559fb512005-06-23 01:40:19 -04001012
1013 } else if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) != 0) {
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001014 CH_ERR("%s: no usable DMA configuration\n", pci_name(pdev));
1015 goto out_disable_pdev;
1016 }
1017
Scott Bardone559fb512005-06-23 01:40:19 -04001018 err = pci_request_regions(pdev, DRV_NAME);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001019 if (err) {
1020 CH_ERR("%s: cannot obtain PCI resources\n", pci_name(pdev));
1021 goto out_disable_pdev;
1022 }
1023
1024 pci_set_master(pdev);
1025
Stephen Hemminger20578152006-11-17 11:21:22 -08001026 mmio_start = pci_resource_start(pdev, 0);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001027 mmio_len = pci_resource_len(pdev, 0);
1028 bi = t1_get_board_info(ent->driver_data);
1029
1030 for (i = 0; i < bi->port_number; ++i) {
1031 struct net_device *netdev;
1032
1033 netdev = alloc_etherdev(adapter ? 0 : sizeof(*adapter));
1034 if (!netdev) {
1035 err = -ENOMEM;
1036 goto out_free_dev;
1037 }
1038
1039 SET_MODULE_OWNER(netdev);
1040 SET_NETDEV_DEV(netdev, &pdev->dev);
1041
1042 if (!adapter) {
1043 adapter = netdev->priv;
1044 adapter->pdev = pdev;
1045 adapter->port[0].dev = netdev; /* so we don't leak it */
1046
1047 adapter->regs = ioremap(mmio_start, mmio_len);
1048 if (!adapter->regs) {
1049 CH_ERR("%s: cannot map device registers\n",
1050 pci_name(pdev));
1051 err = -ENOMEM;
1052 goto out_free_dev;
1053 }
1054
1055 if (t1_get_board_rev(adapter, bi, &adapter->params)) {
1056 err = -ENODEV; /* Can't handle this chip rev */
1057 goto out_free_dev;
1058 }
1059
1060 adapter->name = pci_name(pdev);
1061 adapter->msg_enable = dflt_msg_enable;
1062 adapter->mmio_len = mmio_len;
1063
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001064 spin_lock_init(&adapter->tpi_lock);
1065 spin_lock_init(&adapter->work_lock);
1066 spin_lock_init(&adapter->async_lock);
Stephen Hemminger352c4172006-12-01 16:36:17 -08001067 spin_lock_init(&adapter->mac_lock);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001068
1069 INIT_WORK(&adapter->ext_intr_handler_task,
David Howellsc4028952006-11-22 14:57:56 +00001070 ext_intr_task);
1071 INIT_DELAYED_WORK(&adapter->stats_update_task,
1072 mac_stats_task);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001073
1074 pci_set_drvdata(pdev, netdev);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001075 }
1076
1077 pi = &adapter->port[i];
1078 pi->dev = netdev;
1079 netif_carrier_off(netdev);
1080 netdev->irq = pdev->irq;
1081 netdev->if_port = i;
1082 netdev->mem_start = mmio_start;
1083 netdev->mem_end = mmio_start + mmio_len - 1;
1084 netdev->priv = adapter;
1085 netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
Scott Bardone559fb512005-06-23 01:40:19 -04001086 netdev->features |= NETIF_F_LLTX;
1087
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001088 adapter->flags |= RX_CSUM_ENABLED | TCP_CSUM_CAPABLE;
1089 if (pci_using_dac)
1090 netdev->features |= NETIF_F_HIGHDMA;
1091 if (vlan_tso_capable(adapter)) {
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001092#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
1093 adapter->flags |= VLAN_ACCEL_CAPABLE;
1094 netdev->features |=
1095 NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
1096 netdev->vlan_rx_register = vlan_rx_register;
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001097#endif
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001098
1099 /* T204: disable TSO */
1100 if (!(is_T2(adapter)) || bi->port_number != 4) {
1101 adapter->flags |= TSO_CAPABLE;
1102 netdev->features |= NETIF_F_TSO;
1103 }
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001104 }
1105
1106 netdev->open = cxgb_open;
1107 netdev->stop = cxgb_close;
1108 netdev->hard_start_xmit = t1_start_xmit;
1109 netdev->hard_header_len += (adapter->flags & TSO_CAPABLE) ?
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001110 sizeof(struct cpl_tx_pkt_lso) : sizeof(struct cpl_tx_pkt);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001111 netdev->get_stats = t1_get_stats;
1112 netdev->set_multicast_list = t1_set_rxmode;
1113 netdev->do_ioctl = t1_ioctl;
1114 netdev->change_mtu = t1_change_mtu;
1115 netdev->set_mac_address = t1_set_mac_addr;
1116#ifdef CONFIG_NET_POLL_CONTROLLER
1117 netdev->poll_controller = t1_netpoll;
1118#endif
Stephen Hemminger7fe26a62006-12-08 11:08:33 -08001119#ifdef CONFIG_CHELSIO_T1_NAPI
Stephen Hemmingerbea33482007-10-03 16:41:36 -07001120 netif_napi_add(netdev, &adapter->napi, t1_poll, 64);
Stephen Hemminger7fe26a62006-12-08 11:08:33 -08001121#endif
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001122
Stephen Hemminger20578152006-11-17 11:21:22 -08001123 SET_ETHTOOL_OPS(netdev, &t1_ethtool_ops);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001124 }
1125
1126 if (t1_init_sw_modules(adapter, bi) < 0) {
1127 err = -ENODEV;
1128 goto out_free_dev;
1129 }
1130
1131 /*
1132 * The card is now ready to go. If any errors occur during device
1133 * registration we do not fail the whole card but rather proceed only
1134 * with the ports we manage to register successfully. However we must
1135 * register at least one net device.
1136 */
1137 for (i = 0; i < bi->port_number; ++i) {
1138 err = register_netdev(adapter->port[i].dev);
1139 if (err)
1140 CH_WARN("%s: cannot register net device %s, skipping\n",
1141 pci_name(pdev), adapter->port[i].dev->name);
1142 else {
1143 /*
1144 * Change the name we use for messages to the name of
1145 * the first successfully registered interface.
1146 */
1147 if (!adapter->registered_device_map)
1148 adapter->name = adapter->port[i].dev->name;
1149
Stephen Hemminger20578152006-11-17 11:21:22 -08001150 __set_bit(i, &adapter->registered_device_map);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001151 }
1152 }
1153 if (!adapter->registered_device_map) {
1154 CH_ERR("%s: could not register any net devices\n",
1155 pci_name(pdev));
1156 goto out_release_adapter_res;
1157 }
1158
1159 printk(KERN_INFO "%s: %s (rev %d), %s %dMHz/%d-bit\n", adapter->name,
1160 bi->desc, adapter->params.chip_revision,
1161 adapter->params.pci.is_pcix ? "PCIX" : "PCI",
1162 adapter->params.pci.speed, adapter->params.pci.width);
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001163
1164 /*
1165 * Set the T1B ASIC and memory clocks.
1166 */
1167 if (t1powersave)
1168 adapter->t1powersave = LCLOCK; /* HW default is powersave mode. */
1169 else
1170 adapter->t1powersave = HCLOCK;
1171 if (t1_is_T1B(adapter))
1172 t1_clock(adapter, t1powersave);
1173
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001174 return 0;
1175
Francois Romieu356bd142006-12-11 23:47:00 +01001176out_release_adapter_res:
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001177 t1_free_sw_modules(adapter);
Francois Romieu356bd142006-12-11 23:47:00 +01001178out_free_dev:
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001179 if (adapter) {
Stephen Hemmingere4876472006-11-17 11:25:23 -08001180 if (adapter->regs)
1181 iounmap(adapter->regs);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001182 for (i = bi->port_number - 1; i >= 0; --i)
Stephen Hemmingere4876472006-11-17 11:25:23 -08001183 if (adapter->port[i].dev)
1184 free_netdev(adapter->port[i].dev);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001185 }
1186 pci_release_regions(pdev);
Francois Romieu356bd142006-12-11 23:47:00 +01001187out_disable_pdev:
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001188 pci_disable_device(pdev);
1189 pci_set_drvdata(pdev, NULL);
1190 return err;
1191}
1192
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001193static void bit_bang(struct adapter *adapter, int bitdata, int nbits)
1194{
1195 int data;
1196 int i;
1197 u32 val;
1198
1199 enum {
1200 S_CLOCK = 1 << 3,
1201 S_DATA = 1 << 4
1202 };
1203
1204 for (i = (nbits - 1); i > -1; i--) {
1205
1206 udelay(50);
1207
1208 data = ((bitdata >> i) & 0x1);
1209 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1210
1211 if (data)
1212 val |= S_DATA;
1213 else
1214 val &= ~S_DATA;
1215
1216 udelay(50);
1217
1218 /* Set SCLOCK low */
1219 val &= ~S_CLOCK;
1220 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1221
1222 udelay(50);
1223
1224 /* Write SCLOCK high */
1225 val |= S_CLOCK;
1226 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1227
1228 }
1229}
1230
1231static int t1_clock(struct adapter *adapter, int mode)
1232{
1233 u32 val;
1234 int M_CORE_VAL;
1235 int M_MEM_VAL;
1236
1237 enum {
Francois Romieu356bd142006-12-11 23:47:00 +01001238 M_CORE_BITS = 9,
1239 T_CORE_VAL = 0,
1240 T_CORE_BITS = 2,
1241 N_CORE_VAL = 0,
1242 N_CORE_BITS = 2,
1243 M_MEM_BITS = 9,
1244 T_MEM_VAL = 0,
1245 T_MEM_BITS = 2,
1246 N_MEM_VAL = 0,
1247 N_MEM_BITS = 2,
1248 NP_LOAD = 1 << 17,
1249 S_LOAD_MEM = 1 << 5,
1250 S_LOAD_CORE = 1 << 6,
1251 S_CLOCK = 1 << 3
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001252 };
1253
1254 if (!t1_is_T1B(adapter))
1255 return -ENODEV; /* Can't re-clock this chip. */
1256
Francois Romieud7487422006-12-11 23:49:13 +01001257 if (mode & 2)
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001258 return 0; /* show current mode. */
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001259
1260 if ((adapter->t1powersave & 1) == (mode & 1))
1261 return -EALREADY; /* ASIC already running in mode. */
1262
1263 if ((mode & 1) == HCLOCK) {
1264 M_CORE_VAL = 0x14;
1265 M_MEM_VAL = 0x18;
1266 adapter->t1powersave = HCLOCK; /* overclock */
1267 } else {
1268 M_CORE_VAL = 0xe;
1269 M_MEM_VAL = 0x10;
1270 adapter->t1powersave = LCLOCK; /* underclock */
1271 }
1272
1273 /* Don't interrupt this serial stream! */
1274 spin_lock(&adapter->tpi_lock);
1275
1276 /* Initialize for ASIC core */
1277 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1278 val |= NP_LOAD;
1279 udelay(50);
1280 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1281 udelay(50);
1282 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1283 val &= ~S_LOAD_CORE;
1284 val &= ~S_CLOCK;
1285 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1286 udelay(50);
1287
1288 /* Serial program the ASIC clock synthesizer */
1289 bit_bang(adapter, T_CORE_VAL, T_CORE_BITS);
1290 bit_bang(adapter, N_CORE_VAL, N_CORE_BITS);
1291 bit_bang(adapter, M_CORE_VAL, M_CORE_BITS);
1292 udelay(50);
1293
1294 /* Finish ASIC core */
1295 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1296 val |= S_LOAD_CORE;
1297 udelay(50);
1298 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1299 udelay(50);
1300 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1301 val &= ~S_LOAD_CORE;
1302 udelay(50);
1303 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1304 udelay(50);
1305
1306 /* Initialize for memory */
1307 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1308 val |= NP_LOAD;
1309 udelay(50);
1310 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1311 udelay(50);
1312 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1313 val &= ~S_LOAD_MEM;
1314 val &= ~S_CLOCK;
1315 udelay(50);
1316 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1317 udelay(50);
1318
1319 /* Serial program the memory clock synthesizer */
1320 bit_bang(adapter, T_MEM_VAL, T_MEM_BITS);
1321 bit_bang(adapter, N_MEM_VAL, N_MEM_BITS);
1322 bit_bang(adapter, M_MEM_VAL, M_MEM_BITS);
1323 udelay(50);
1324
1325 /* Finish memory */
1326 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1327 val |= S_LOAD_MEM;
1328 udelay(50);
1329 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1330 udelay(50);
1331 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1332 val &= ~S_LOAD_MEM;
1333 udelay(50);
1334 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1335
1336 spin_unlock(&adapter->tpi_lock);
1337
1338 return 0;
1339}
1340
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001341static inline void t1_sw_reset(struct pci_dev *pdev)
1342{
1343 pci_write_config_dword(pdev, A_PCICFG_PM_CSR, 3);
1344 pci_write_config_dword(pdev, A_PCICFG_PM_CSR, 0);
1345}
1346
1347static void __devexit remove_one(struct pci_dev *pdev)
1348{
1349 struct net_device *dev = pci_get_drvdata(pdev);
Francois Romieu47cbe6f2006-12-05 23:19:06 +01001350 struct adapter *adapter = dev->priv;
1351 int i;
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001352
Francois Romieu47cbe6f2006-12-05 23:19:06 +01001353 for_each_port(adapter, i) {
1354 if (test_bit(i, &adapter->registered_device_map))
1355 unregister_netdev(adapter->port[i].dev);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001356 }
Francois Romieu47cbe6f2006-12-05 23:19:06 +01001357
1358 t1_free_sw_modules(adapter);
1359 iounmap(adapter->regs);
1360
1361 while (--i >= 0) {
1362 if (adapter->port[i].dev)
1363 free_netdev(adapter->port[i].dev);
1364 }
1365
1366 pci_release_regions(pdev);
1367 pci_disable_device(pdev);
1368 pci_set_drvdata(pdev, NULL);
1369 t1_sw_reset(pdev);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001370}
1371
1372static struct pci_driver driver = {
Scott Bardone559fb512005-06-23 01:40:19 -04001373 .name = DRV_NAME,
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001374 .id_table = t1_pci_tbl,
1375 .probe = init_one,
1376 .remove = __devexit_p(remove_one),
1377};
1378
1379static int __init t1_init_module(void)
1380{
Jeff Garzik29917622006-08-19 17:48:59 -04001381 return pci_register_driver(&driver);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001382}
1383
1384static void __exit t1_cleanup_module(void)
1385{
1386 pci_unregister_driver(&driver);
1387}
1388
1389module_init(t1_init_module);
1390module_exit(t1_cleanup_module);