blob: 2dbf8dc116c66acab2c5fa805442d81dcfd18edd [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
Jeff Garzikb9f2c042007-10-03 18:07:32 -0700442static int get_sset_count(struct net_device *dev, int sset)
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800443{
Jeff Garzikb9f2c042007-10-03 18:07:32 -0700444 switch (sset) {
445 case ETH_SS_STATS:
446 return ARRAY_SIZE(stats_strings);
447 default:
448 return -EOPNOTSUPP;
449 }
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800450}
451
452static void get_strings(struct net_device *dev, u32 stringset, u8 *data)
453{
454 if (stringset == ETH_SS_STATS)
455 memcpy(data, stats_strings, sizeof(stats_strings));
456}
457
458static void get_stats(struct net_device *dev, struct ethtool_stats *stats,
459 u64 *data)
460{
461 struct adapter *adapter = dev->priv;
462 struct cmac *mac = adapter->port[dev->if_port].mac;
463 const struct cmac_statistics *s;
Scott Bardone559fb512005-06-23 01:40:19 -0400464 const struct sge_intr_counts *t;
Stephen Hemminger56f643c2006-12-01 16:36:21 -0800465 struct sge_port_stats ss;
Francois Romieu83432462006-12-12 00:13:48 +0100466 unsigned int len;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800467
468 s = mac->ops->statistics_update(mac, MAC_STATS_UPDATE_FULL);
469
Francois Romieu83432462006-12-12 00:13:48 +0100470 len = sizeof(u64)*(&s->TxFCSErrors + 1 - &s->TxOctetsOK);
471 memcpy(data, &s->TxOctetsOK, len);
472 data += len;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800473
Francois Romieu83432462006-12-12 00:13:48 +0100474 len = sizeof(u64)*(&s->RxFrameTooLongErrors + 1 - &s->RxOctetsOK);
475 memcpy(data, &s->RxOctetsOK, len);
476 data += len;
Scott Bardone559fb512005-06-23 01:40:19 -0400477
Stephen Hemminger56f643c2006-12-01 16:36:21 -0800478 t1_sge_get_port_stats(adapter->sge, dev->if_port, &ss);
Francois Romieu83432462006-12-12 00:13:48 +0100479 memcpy(data, &ss, sizeof(ss));
480 data += sizeof(ss);
Scott Bardone559fb512005-06-23 01:40:19 -0400481
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800482 t = t1_sge_get_intr_counts(adapter->sge);
Stephen Hemminger56f643c2006-12-01 16:36:21 -0800483 *data++ = t->rx_drops;
484 *data++ = t->pure_rsps;
485 *data++ = t->unhandled_irqs;
486 *data++ = t->respQ_empty;
487 *data++ = t->respQ_overflow;
488 *data++ = t->freelistQ_empty;
489 *data++ = t->pkt_too_big;
490 *data++ = t->pkt_mismatch;
491 *data++ = t->cmdQ_full[0];
492 *data++ = t->cmdQ_full[1];
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800493
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800494 if (adapter->espi) {
495 const struct espi_intr_counts *e;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800496
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800497 e = t1_espi_get_intr_counts(adapter->espi);
Stephen Hemminger56f643c2006-12-01 16:36:21 -0800498 *data++ = e->DIP2_parity_err;
499 *data++ = e->DIP4_err;
500 *data++ = e->rx_drops;
501 *data++ = e->tx_drops;
502 *data++ = e->rx_ovflw;
503 *data++ = e->parity_err;
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800504 }
Scott Bardone559fb512005-06-23 01:40:19 -0400505}
506
507static inline void reg_block_dump(struct adapter *ap, void *buf,
508 unsigned int start, unsigned int end)
509{
510 u32 *p = buf + start;
511
512 for ( ; start <= end; start += sizeof(u32))
513 *p++ = readl(ap->regs + start);
514}
515
516static void get_regs(struct net_device *dev, struct ethtool_regs *regs,
517 void *buf)
518{
519 struct adapter *ap = dev->priv;
520
521 /*
522 * Version scheme: bits 0..9: chip version, bits 10..15: chip revision
523 */
524 regs->version = 2;
525
526 memset(buf, 0, T2_REGMAP_SIZE);
527 reg_block_dump(ap, buf, 0, A_SG_RESPACCUTIMER);
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800528 reg_block_dump(ap, buf, A_MC3_CFG, A_MC4_INT_CAUSE);
529 reg_block_dump(ap, buf, A_TPI_ADDR, A_TPI_PAR);
530 reg_block_dump(ap, buf, A_TP_IN_CONFIG, A_TP_TX_DROP_COUNT);
531 reg_block_dump(ap, buf, A_RAT_ROUTE_CONTROL, A_RAT_INTR_CAUSE);
532 reg_block_dump(ap, buf, A_CSPI_RX_AE_WM, A_CSPI_INTR_ENABLE);
533 reg_block_dump(ap, buf, A_ESPI_SCH_TOKEN0, A_ESPI_GOSTAT);
534 reg_block_dump(ap, buf, A_ULP_ULIMIT, A_ULP_PIO_CTRL);
535 reg_block_dump(ap, buf, A_PL_ENABLE, A_PL_CAUSE);
536 reg_block_dump(ap, buf, A_MC5_CONFIG, A_MC5_MASK_WRITE_CMD);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800537}
538
539static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
540{
541 struct adapter *adapter = dev->priv;
542 struct port_info *p = &adapter->port[dev->if_port];
543
544 cmd->supported = p->link_config.supported;
545 cmd->advertising = p->link_config.advertising;
546
547 if (netif_carrier_ok(dev)) {
548 cmd->speed = p->link_config.speed;
549 cmd->duplex = p->link_config.duplex;
550 } else {
551 cmd->speed = -1;
552 cmd->duplex = -1;
553 }
554
Stephen Hemminger20578152006-11-17 11:21:22 -0800555 cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE;
556 cmd->phy_address = p->phy->addr;
557 cmd->transceiver = XCVR_EXTERNAL;
558 cmd->autoneg = p->link_config.autoneg;
559 cmd->maxtxpkt = 0;
560 cmd->maxrxpkt = 0;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800561 return 0;
562}
563
564static int speed_duplex_to_caps(int speed, int duplex)
565{
566 int cap = 0;
567
568 switch (speed) {
569 case SPEED_10:
570 if (duplex == DUPLEX_FULL)
571 cap = SUPPORTED_10baseT_Full;
572 else
573 cap = SUPPORTED_10baseT_Half;
574 break;
575 case SPEED_100:
576 if (duplex == DUPLEX_FULL)
577 cap = SUPPORTED_100baseT_Full;
578 else
579 cap = SUPPORTED_100baseT_Half;
580 break;
581 case SPEED_1000:
582 if (duplex == DUPLEX_FULL)
583 cap = SUPPORTED_1000baseT_Full;
584 else
585 cap = SUPPORTED_1000baseT_Half;
586 break;
587 case SPEED_10000:
588 if (duplex == DUPLEX_FULL)
589 cap = SUPPORTED_10000baseT_Full;
590 }
591 return cap;
592}
593
594#define ADVERTISED_MASK (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | \
595 ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | \
596 ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full | \
597 ADVERTISED_10000baseT_Full)
598
599static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
600{
601 struct adapter *adapter = dev->priv;
602 struct port_info *p = &adapter->port[dev->if_port];
603 struct link_config *lc = &p->link_config;
604
605 if (!(lc->supported & SUPPORTED_Autoneg))
Scott Bardone559fb512005-06-23 01:40:19 -0400606 return -EOPNOTSUPP; /* can't change speed/duplex */
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800607
608 if (cmd->autoneg == AUTONEG_DISABLE) {
609 int cap = speed_duplex_to_caps(cmd->speed, cmd->duplex);
610
611 if (!(lc->supported & cap) || cmd->speed == SPEED_1000)
612 return -EINVAL;
613 lc->requested_speed = cmd->speed;
614 lc->requested_duplex = cmd->duplex;
615 lc->advertising = 0;
616 } else {
617 cmd->advertising &= ADVERTISED_MASK;
618 if (cmd->advertising & (cmd->advertising - 1))
619 cmd->advertising = lc->supported;
620 cmd->advertising &= lc->supported;
621 if (!cmd->advertising)
622 return -EINVAL;
623 lc->requested_speed = SPEED_INVALID;
624 lc->requested_duplex = DUPLEX_INVALID;
625 lc->advertising = cmd->advertising | ADVERTISED_Autoneg;
626 }
627 lc->autoneg = cmd->autoneg;
628 if (netif_running(dev))
629 t1_link_start(p->phy, p->mac, lc);
630 return 0;
631}
632
633static void get_pauseparam(struct net_device *dev,
634 struct ethtool_pauseparam *epause)
635{
636 struct adapter *adapter = dev->priv;
637 struct port_info *p = &adapter->port[dev->if_port];
638
639 epause->autoneg = (p->link_config.requested_fc & PAUSE_AUTONEG) != 0;
640 epause->rx_pause = (p->link_config.fc & PAUSE_RX) != 0;
641 epause->tx_pause = (p->link_config.fc & PAUSE_TX) != 0;
642}
643
644static int set_pauseparam(struct net_device *dev,
645 struct ethtool_pauseparam *epause)
646{
647 struct adapter *adapter = dev->priv;
648 struct port_info *p = &adapter->port[dev->if_port];
649 struct link_config *lc = &p->link_config;
650
651 if (epause->autoneg == AUTONEG_DISABLE)
652 lc->requested_fc = 0;
653 else if (lc->supported & SUPPORTED_Autoneg)
654 lc->requested_fc = PAUSE_AUTONEG;
655 else
656 return -EINVAL;
657
658 if (epause->rx_pause)
659 lc->requested_fc |= PAUSE_RX;
660 if (epause->tx_pause)
661 lc->requested_fc |= PAUSE_TX;
662 if (lc->autoneg == AUTONEG_ENABLE) {
663 if (netif_running(dev))
664 t1_link_start(p->phy, p->mac, lc);
665 } else {
666 lc->fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
667 if (netif_running(dev))
668 p->mac->ops->set_speed_duplex_fc(p->mac, -1, -1,
669 lc->fc);
670 }
671 return 0;
672}
673
674static u32 get_rx_csum(struct net_device *dev)
675{
676 struct adapter *adapter = dev->priv;
677
678 return (adapter->flags & RX_CSUM_ENABLED) != 0;
679}
680
681static int set_rx_csum(struct net_device *dev, u32 data)
682{
683 struct adapter *adapter = dev->priv;
684
685 if (data)
686 adapter->flags |= RX_CSUM_ENABLED;
687 else
688 adapter->flags &= ~RX_CSUM_ENABLED;
689 return 0;
690}
691
692static int set_tso(struct net_device *dev, u32 value)
693{
694 struct adapter *adapter = dev->priv;
695
696 if (!(adapter->flags & TSO_CAPABLE))
697 return value ? -EOPNOTSUPP : 0;
698 return ethtool_op_set_tso(dev, value);
699}
700
701static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
702{
703 struct adapter *adapter = dev->priv;
704 int jumbo_fl = t1_is_T1B(adapter) ? 1 : 0;
705
706 e->rx_max_pending = MAX_RX_BUFFERS;
707 e->rx_mini_max_pending = 0;
708 e->rx_jumbo_max_pending = MAX_RX_JUMBO_BUFFERS;
709 e->tx_max_pending = MAX_CMDQ_ENTRIES;
710
711 e->rx_pending = adapter->params.sge.freelQ_size[!jumbo_fl];
712 e->rx_mini_pending = 0;
713 e->rx_jumbo_pending = adapter->params.sge.freelQ_size[jumbo_fl];
714 e->tx_pending = adapter->params.sge.cmdQ_size[0];
715}
716
717static int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
718{
719 struct adapter *adapter = dev->priv;
720 int jumbo_fl = t1_is_T1B(adapter) ? 1 : 0;
721
722 if (e->rx_pending > MAX_RX_BUFFERS || e->rx_mini_pending ||
723 e->rx_jumbo_pending > MAX_RX_JUMBO_BUFFERS ||
724 e->tx_pending > MAX_CMDQ_ENTRIES ||
725 e->rx_pending < MIN_FL_ENTRIES ||
726 e->rx_jumbo_pending < MIN_FL_ENTRIES ||
727 e->tx_pending < (adapter->params.nports + 1) * (MAX_SKB_FRAGS + 1))
728 return -EINVAL;
729
730 if (adapter->flags & FULL_INIT_DONE)
Francois Romieu356bd142006-12-11 23:47:00 +0100731 return -EBUSY;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800732
733 adapter->params.sge.freelQ_size[!jumbo_fl] = e->rx_pending;
734 adapter->params.sge.freelQ_size[jumbo_fl] = e->rx_jumbo_pending;
735 adapter->params.sge.cmdQ_size[0] = e->tx_pending;
736 adapter->params.sge.cmdQ_size[1] = e->tx_pending > MAX_CMDQ1_ENTRIES ?
737 MAX_CMDQ1_ENTRIES : e->tx_pending;
738 return 0;
739}
740
741static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
742{
743 struct adapter *adapter = dev->priv;
744
Stephen Hemminger7fe26a62006-12-08 11:08:33 -0800745 adapter->params.sge.rx_coalesce_usecs = c->rx_coalesce_usecs;
Francois Romieu356bd142006-12-11 23:47:00 +0100746 adapter->params.sge.coalesce_enable = c->use_adaptive_rx_coalesce;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800747 adapter->params.sge.sample_interval_usecs = c->rate_sample_interval;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800748 t1_sge_set_coalesce_params(adapter->sge, &adapter->params.sge);
749 return 0;
750}
751
752static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
753{
754 struct adapter *adapter = dev->priv;
755
Scott Bardone559fb512005-06-23 01:40:19 -0400756 c->rx_coalesce_usecs = adapter->params.sge.rx_coalesce_usecs;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800757 c->rate_sample_interval = adapter->params.sge.sample_interval_usecs;
758 c->use_adaptive_rx_coalesce = adapter->params.sge.coalesce_enable;
759 return 0;
760}
761
762static int get_eeprom_len(struct net_device *dev)
763{
Francois Romieu356bd142006-12-11 23:47:00 +0100764 struct adapter *adapter = dev->priv;
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800765
Francois Romieu356bd142006-12-11 23:47:00 +0100766 return t1_is_asic(adapter) ? EEPROM_SIZE : 0;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800767}
768
769#define EEPROM_MAGIC(ap) \
770 (PCI_VENDOR_ID_CHELSIO | ((ap)->params.chip_version << 16))
771
772static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *e,
773 u8 *data)
774{
775 int i;
776 u8 buf[EEPROM_SIZE] __attribute__((aligned(4)));
777 struct adapter *adapter = dev->priv;
778
779 e->magic = EEPROM_MAGIC(adapter);
780 for (i = e->offset & ~3; i < e->offset + e->len; i += sizeof(u32))
781 t1_seeprom_read(adapter, i, (u32 *)&buf[i]);
782 memcpy(data, buf + e->offset, e->len);
783 return 0;
784}
785
Jeff Garzik7282d492006-09-13 14:30:00 -0400786static const struct ethtool_ops t1_ethtool_ops = {
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800787 .get_settings = get_settings,
788 .set_settings = set_settings,
789 .get_drvinfo = get_drvinfo,
790 .get_msglevel = get_msglevel,
791 .set_msglevel = set_msglevel,
792 .get_ringparam = get_sge_param,
793 .set_ringparam = set_sge_param,
794 .get_coalesce = get_coalesce,
795 .set_coalesce = set_coalesce,
796 .get_eeprom_len = get_eeprom_len,
797 .get_eeprom = get_eeprom,
798 .get_pauseparam = get_pauseparam,
799 .set_pauseparam = set_pauseparam,
800 .get_rx_csum = get_rx_csum,
801 .set_rx_csum = set_rx_csum,
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800802 .set_tx_csum = ethtool_op_set_tx_csum,
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800803 .set_sg = ethtool_op_set_sg,
804 .get_link = ethtool_op_get_link,
805 .get_strings = get_strings,
Jeff Garzikb9f2c042007-10-03 18:07:32 -0700806 .get_sset_count = get_sset_count,
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800807 .get_ethtool_stats = get_stats,
Scott Bardone559fb512005-06-23 01:40:19 -0400808 .get_regs_len = get_regs_len,
809 .get_regs = get_regs,
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800810 .set_tso = set_tso,
811};
812
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800813static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
814{
Stephen Hemminger20578152006-11-17 11:21:22 -0800815 struct adapter *adapter = dev->priv;
816 struct mii_ioctl_data *data = if_mii(req);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800817
818 switch (cmd) {
Stephen Hemminger20578152006-11-17 11:21:22 -0800819 case SIOCGMIIPHY:
820 data->phy_id = adapter->port[dev->if_port].phy->addr;
821 /* FALLTHRU */
822 case SIOCGMIIREG: {
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800823 struct cphy *phy = adapter->port[dev->if_port].phy;
824 u32 val;
825
Scott Bardone559fb512005-06-23 01:40:19 -0400826 if (!phy->mdio_read)
Francois Romieu356bd142006-12-11 23:47:00 +0100827 return -EOPNOTSUPP;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800828 phy->mdio_read(adapter, data->phy_id, 0, data->reg_num & 0x1f,
829 &val);
Stephen Hemminger20578152006-11-17 11:21:22 -0800830 data->val_out = val;
831 break;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800832 }
Stephen Hemminger20578152006-11-17 11:21:22 -0800833 case SIOCSMIIREG: {
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800834 struct cphy *phy = adapter->port[dev->if_port].phy;
835
Stephen Hemminger20578152006-11-17 11:21:22 -0800836 if (!capable(CAP_NET_ADMIN))
837 return -EPERM;
Scott Bardone559fb512005-06-23 01:40:19 -0400838 if (!phy->mdio_write)
Francois Romieu356bd142006-12-11 23:47:00 +0100839 return -EOPNOTSUPP;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800840 phy->mdio_write(adapter, data->phy_id, 0, data->reg_num & 0x1f,
Scott Bardone559fb512005-06-23 01:40:19 -0400841 data->val_in);
Stephen Hemminger20578152006-11-17 11:21:22 -0800842 break;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800843 }
844
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800845 default:
846 return -EOPNOTSUPP;
847 }
848 return 0;
849}
850
851static int t1_change_mtu(struct net_device *dev, int new_mtu)
852{
853 int ret;
854 struct adapter *adapter = dev->priv;
855 struct cmac *mac = adapter->port[dev->if_port].mac;
856
857 if (!mac->ops->set_mtu)
Francois Romieu356bd142006-12-11 23:47:00 +0100858 return -EOPNOTSUPP;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800859 if (new_mtu < 68)
Francois Romieu356bd142006-12-11 23:47:00 +0100860 return -EINVAL;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800861 if ((ret = mac->ops->set_mtu(mac, new_mtu)))
862 return ret;
863 dev->mtu = new_mtu;
864 return 0;
865}
866
867static int t1_set_mac_addr(struct net_device *dev, void *p)
868{
869 struct adapter *adapter = dev->priv;
870 struct cmac *mac = adapter->port[dev->if_port].mac;
871 struct sockaddr *addr = p;
872
873 if (!mac->ops->macaddress_set)
874 return -EOPNOTSUPP;
875
876 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
877 mac->ops->macaddress_set(mac, dev->dev_addr);
878 return 0;
879}
880
881#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
882static void vlan_rx_register(struct net_device *dev,
883 struct vlan_group *grp)
884{
885 struct adapter *adapter = dev->priv;
886
887 spin_lock_irq(&adapter->async_lock);
888 adapter->vlan_grp = grp;
889 t1_set_vlan_accel(adapter, grp != NULL);
890 spin_unlock_irq(&adapter->async_lock);
891}
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800892#endif
893
894#ifdef CONFIG_NET_POLL_CONTROLLER
895static void t1_netpoll(struct net_device *dev)
896{
Scott Bardone559fb512005-06-23 01:40:19 -0400897 unsigned long flags;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800898 struct adapter *adapter = dev->priv;
899
Scott Bardone559fb512005-06-23 01:40:19 -0400900 local_irq_save(flags);
Stephen Hemminger7fe26a62006-12-08 11:08:33 -0800901 t1_interrupt(adapter->pdev->irq, adapter);
Scott Bardone559fb512005-06-23 01:40:19 -0400902 local_irq_restore(flags);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800903}
904#endif
905
906/*
907 * Periodic accumulation of MAC statistics. This is used only if the MAC
908 * does not have any other way to prevent stats counter overflow.
909 */
David Howellsc4028952006-11-22 14:57:56 +0000910static void mac_stats_task(struct work_struct *work)
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800911{
912 int i;
David Howellsc4028952006-11-22 14:57:56 +0000913 struct adapter *adapter =
914 container_of(work, struct adapter, stats_update_task.work);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800915
916 for_each_port(adapter, i) {
917 struct port_info *p = &adapter->port[i];
918
919 if (netif_running(p->dev))
920 p->mac->ops->statistics_update(p->mac,
921 MAC_STATS_UPDATE_FAST);
922 }
923
924 /* Schedule the next statistics update if any port is active. */
925 spin_lock(&adapter->work_lock);
926 if (adapter->open_device_map & PORT_MASK)
927 schedule_mac_stats_update(adapter,
928 adapter->params.stats_update_period);
929 spin_unlock(&adapter->work_lock);
930}
931
932/*
933 * Processes elmer0 external interrupts in process context.
934 */
David Howellsc4028952006-11-22 14:57:56 +0000935static void ext_intr_task(struct work_struct *work)
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800936{
David Howellsc4028952006-11-22 14:57:56 +0000937 struct adapter *adapter =
938 container_of(work, struct adapter, ext_intr_handler_task);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800939
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800940 t1_elmer0_ext_intr_handler(adapter);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800941
942 /* Now reenable external interrupts */
Scott Bardone559fb512005-06-23 01:40:19 -0400943 spin_lock_irq(&adapter->async_lock);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800944 adapter->slow_intr_mask |= F_PL_INTR_EXT;
Scott Bardone559fb512005-06-23 01:40:19 -0400945 writel(F_PL_INTR_EXT, adapter->regs + A_PL_CAUSE);
946 writel(adapter->slow_intr_mask | F_PL_INTR_SGE_DATA,
Stephen Hemminger20578152006-11-17 11:21:22 -0800947 adapter->regs + A_PL_ENABLE);
Scott Bardone559fb512005-06-23 01:40:19 -0400948 spin_unlock_irq(&adapter->async_lock);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800949}
950
951/*
952 * Interrupt-context handler for elmer0 external interrupts.
953 */
954void t1_elmer0_ext_intr(struct adapter *adapter)
955{
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800956 /*
957 * Schedule a task to handle external interrupts as we require
958 * a process context. We disable EXT interrupts in the interim
959 * and let the task reenable them when it's done.
960 */
961 adapter->slow_intr_mask &= ~F_PL_INTR_EXT;
Scott Bardone559fb512005-06-23 01:40:19 -0400962 writel(adapter->slow_intr_mask | F_PL_INTR_SGE_DATA,
Stephen Hemminger20578152006-11-17 11:21:22 -0800963 adapter->regs + A_PL_ENABLE);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800964 schedule_work(&adapter->ext_intr_handler_task);
965}
966
967void t1_fatal_err(struct adapter *adapter)
968{
969 if (adapter->flags & FULL_INIT_DONE) {
970 t1_sge_stop(adapter->sge);
971 t1_interrupts_disable(adapter);
972 }
973 CH_ALERT("%s: encountered fatal error, operation suspended\n",
974 adapter->name);
975}
976
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800977static int __devinit init_one(struct pci_dev *pdev,
978 const struct pci_device_id *ent)
979{
980 static int version_printed;
981
982 int i, err, pci_using_dac = 0;
983 unsigned long mmio_start, mmio_len;
984 const struct board_info *bi;
985 struct adapter *adapter = NULL;
986 struct port_info *pi;
987
988 if (!version_printed) {
Scott Bardone559fb512005-06-23 01:40:19 -0400989 printk(KERN_INFO "%s - version %s\n", DRV_DESCRIPTION,
990 DRV_VERSION);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800991 ++version_printed;
992 }
993
994 err = pci_enable_device(pdev);
995 if (err)
Stephen Hemminger20578152006-11-17 11:21:22 -0800996 return err;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800997
998 if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
999 CH_ERR("%s: cannot find PCI device memory base address\n",
1000 pci_name(pdev));
1001 err = -ENODEV;
1002 goto out_disable_pdev;
1003 }
1004
Scott Bardone559fb512005-06-23 01:40:19 -04001005 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001006 pci_using_dac = 1;
Scott Bardone559fb512005-06-23 01:40:19 -04001007
1008 if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001009 CH_ERR("%s: unable to obtain 64-bit DMA for"
1010 "consistent allocations\n", pci_name(pdev));
1011 err = -ENODEV;
1012 goto out_disable_pdev;
1013 }
Scott Bardone559fb512005-06-23 01:40:19 -04001014
1015 } else if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) != 0) {
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001016 CH_ERR("%s: no usable DMA configuration\n", pci_name(pdev));
1017 goto out_disable_pdev;
1018 }
1019
Scott Bardone559fb512005-06-23 01:40:19 -04001020 err = pci_request_regions(pdev, DRV_NAME);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001021 if (err) {
1022 CH_ERR("%s: cannot obtain PCI resources\n", pci_name(pdev));
1023 goto out_disable_pdev;
1024 }
1025
1026 pci_set_master(pdev);
1027
Stephen Hemminger20578152006-11-17 11:21:22 -08001028 mmio_start = pci_resource_start(pdev, 0);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001029 mmio_len = pci_resource_len(pdev, 0);
1030 bi = t1_get_board_info(ent->driver_data);
1031
1032 for (i = 0; i < bi->port_number; ++i) {
1033 struct net_device *netdev;
1034
1035 netdev = alloc_etherdev(adapter ? 0 : sizeof(*adapter));
1036 if (!netdev) {
1037 err = -ENOMEM;
1038 goto out_free_dev;
1039 }
1040
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001041 SET_NETDEV_DEV(netdev, &pdev->dev);
1042
1043 if (!adapter) {
1044 adapter = netdev->priv;
1045 adapter->pdev = pdev;
1046 adapter->port[0].dev = netdev; /* so we don't leak it */
1047
1048 adapter->regs = ioremap(mmio_start, mmio_len);
1049 if (!adapter->regs) {
1050 CH_ERR("%s: cannot map device registers\n",
1051 pci_name(pdev));
1052 err = -ENOMEM;
1053 goto out_free_dev;
1054 }
1055
1056 if (t1_get_board_rev(adapter, bi, &adapter->params)) {
1057 err = -ENODEV; /* Can't handle this chip rev */
1058 goto out_free_dev;
1059 }
1060
1061 adapter->name = pci_name(pdev);
1062 adapter->msg_enable = dflt_msg_enable;
1063 adapter->mmio_len = mmio_len;
1064
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001065 spin_lock_init(&adapter->tpi_lock);
1066 spin_lock_init(&adapter->work_lock);
1067 spin_lock_init(&adapter->async_lock);
Stephen Hemminger352c4172006-12-01 16:36:17 -08001068 spin_lock_init(&adapter->mac_lock);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001069
1070 INIT_WORK(&adapter->ext_intr_handler_task,
David Howellsc4028952006-11-22 14:57:56 +00001071 ext_intr_task);
1072 INIT_DELAYED_WORK(&adapter->stats_update_task,
1073 mac_stats_task);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001074
1075 pci_set_drvdata(pdev, netdev);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001076 }
1077
1078 pi = &adapter->port[i];
1079 pi->dev = netdev;
1080 netif_carrier_off(netdev);
1081 netdev->irq = pdev->irq;
1082 netdev->if_port = i;
1083 netdev->mem_start = mmio_start;
1084 netdev->mem_end = mmio_start + mmio_len - 1;
1085 netdev->priv = adapter;
1086 netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
Scott Bardone559fb512005-06-23 01:40:19 -04001087 netdev->features |= NETIF_F_LLTX;
1088
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001089 adapter->flags |= RX_CSUM_ENABLED | TCP_CSUM_CAPABLE;
1090 if (pci_using_dac)
1091 netdev->features |= NETIF_F_HIGHDMA;
1092 if (vlan_tso_capable(adapter)) {
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001093#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
1094 adapter->flags |= VLAN_ACCEL_CAPABLE;
1095 netdev->features |=
1096 NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
1097 netdev->vlan_rx_register = vlan_rx_register;
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001098#endif
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001099
1100 /* T204: disable TSO */
1101 if (!(is_T2(adapter)) || bi->port_number != 4) {
1102 adapter->flags |= TSO_CAPABLE;
1103 netdev->features |= NETIF_F_TSO;
1104 }
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001105 }
1106
1107 netdev->open = cxgb_open;
1108 netdev->stop = cxgb_close;
1109 netdev->hard_start_xmit = t1_start_xmit;
1110 netdev->hard_header_len += (adapter->flags & TSO_CAPABLE) ?
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001111 sizeof(struct cpl_tx_pkt_lso) : sizeof(struct cpl_tx_pkt);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001112 netdev->get_stats = t1_get_stats;
1113 netdev->set_multicast_list = t1_set_rxmode;
1114 netdev->do_ioctl = t1_ioctl;
1115 netdev->change_mtu = t1_change_mtu;
1116 netdev->set_mac_address = t1_set_mac_addr;
1117#ifdef CONFIG_NET_POLL_CONTROLLER
1118 netdev->poll_controller = t1_netpoll;
1119#endif
Stephen Hemminger7fe26a62006-12-08 11:08:33 -08001120#ifdef CONFIG_CHELSIO_T1_NAPI
Stephen Hemmingerbea33482007-10-03 16:41:36 -07001121 netif_napi_add(netdev, &adapter->napi, t1_poll, 64);
Stephen Hemminger7fe26a62006-12-08 11:08:33 -08001122#endif
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001123
Stephen Hemminger20578152006-11-17 11:21:22 -08001124 SET_ETHTOOL_OPS(netdev, &t1_ethtool_ops);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001125 }
1126
1127 if (t1_init_sw_modules(adapter, bi) < 0) {
1128 err = -ENODEV;
1129 goto out_free_dev;
1130 }
1131
1132 /*
1133 * The card is now ready to go. If any errors occur during device
1134 * registration we do not fail the whole card but rather proceed only
1135 * with the ports we manage to register successfully. However we must
1136 * register at least one net device.
1137 */
1138 for (i = 0; i < bi->port_number; ++i) {
1139 err = register_netdev(adapter->port[i].dev);
1140 if (err)
1141 CH_WARN("%s: cannot register net device %s, skipping\n",
1142 pci_name(pdev), adapter->port[i].dev->name);
1143 else {
1144 /*
1145 * Change the name we use for messages to the name of
1146 * the first successfully registered interface.
1147 */
1148 if (!adapter->registered_device_map)
1149 adapter->name = adapter->port[i].dev->name;
1150
Stephen Hemminger20578152006-11-17 11:21:22 -08001151 __set_bit(i, &adapter->registered_device_map);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001152 }
1153 }
1154 if (!adapter->registered_device_map) {
1155 CH_ERR("%s: could not register any net devices\n",
1156 pci_name(pdev));
1157 goto out_release_adapter_res;
1158 }
1159
1160 printk(KERN_INFO "%s: %s (rev %d), %s %dMHz/%d-bit\n", adapter->name,
1161 bi->desc, adapter->params.chip_revision,
1162 adapter->params.pci.is_pcix ? "PCIX" : "PCI",
1163 adapter->params.pci.speed, adapter->params.pci.width);
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001164
1165 /*
1166 * Set the T1B ASIC and memory clocks.
1167 */
1168 if (t1powersave)
1169 adapter->t1powersave = LCLOCK; /* HW default is powersave mode. */
1170 else
1171 adapter->t1powersave = HCLOCK;
1172 if (t1_is_T1B(adapter))
1173 t1_clock(adapter, t1powersave);
1174
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001175 return 0;
1176
Francois Romieu356bd142006-12-11 23:47:00 +01001177out_release_adapter_res:
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001178 t1_free_sw_modules(adapter);
Francois Romieu356bd142006-12-11 23:47:00 +01001179out_free_dev:
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001180 if (adapter) {
Stephen Hemmingere4876472006-11-17 11:25:23 -08001181 if (adapter->regs)
1182 iounmap(adapter->regs);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001183 for (i = bi->port_number - 1; i >= 0; --i)
Stephen Hemmingere4876472006-11-17 11:25:23 -08001184 if (adapter->port[i].dev)
1185 free_netdev(adapter->port[i].dev);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001186 }
1187 pci_release_regions(pdev);
Francois Romieu356bd142006-12-11 23:47:00 +01001188out_disable_pdev:
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001189 pci_disable_device(pdev);
1190 pci_set_drvdata(pdev, NULL);
1191 return err;
1192}
1193
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001194static void bit_bang(struct adapter *adapter, int bitdata, int nbits)
1195{
1196 int data;
1197 int i;
1198 u32 val;
1199
1200 enum {
1201 S_CLOCK = 1 << 3,
1202 S_DATA = 1 << 4
1203 };
1204
1205 for (i = (nbits - 1); i > -1; i--) {
1206
1207 udelay(50);
1208
1209 data = ((bitdata >> i) & 0x1);
1210 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1211
1212 if (data)
1213 val |= S_DATA;
1214 else
1215 val &= ~S_DATA;
1216
1217 udelay(50);
1218
1219 /* Set SCLOCK low */
1220 val &= ~S_CLOCK;
1221 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1222
1223 udelay(50);
1224
1225 /* Write SCLOCK high */
1226 val |= S_CLOCK;
1227 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1228
1229 }
1230}
1231
1232static int t1_clock(struct adapter *adapter, int mode)
1233{
1234 u32 val;
1235 int M_CORE_VAL;
1236 int M_MEM_VAL;
1237
1238 enum {
Francois Romieu356bd142006-12-11 23:47:00 +01001239 M_CORE_BITS = 9,
1240 T_CORE_VAL = 0,
1241 T_CORE_BITS = 2,
1242 N_CORE_VAL = 0,
1243 N_CORE_BITS = 2,
1244 M_MEM_BITS = 9,
1245 T_MEM_VAL = 0,
1246 T_MEM_BITS = 2,
1247 N_MEM_VAL = 0,
1248 N_MEM_BITS = 2,
1249 NP_LOAD = 1 << 17,
1250 S_LOAD_MEM = 1 << 5,
1251 S_LOAD_CORE = 1 << 6,
1252 S_CLOCK = 1 << 3
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001253 };
1254
1255 if (!t1_is_T1B(adapter))
1256 return -ENODEV; /* Can't re-clock this chip. */
1257
Francois Romieud7487422006-12-11 23:49:13 +01001258 if (mode & 2)
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001259 return 0; /* show current mode. */
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001260
1261 if ((adapter->t1powersave & 1) == (mode & 1))
1262 return -EALREADY; /* ASIC already running in mode. */
1263
1264 if ((mode & 1) == HCLOCK) {
1265 M_CORE_VAL = 0x14;
1266 M_MEM_VAL = 0x18;
1267 adapter->t1powersave = HCLOCK; /* overclock */
1268 } else {
1269 M_CORE_VAL = 0xe;
1270 M_MEM_VAL = 0x10;
1271 adapter->t1powersave = LCLOCK; /* underclock */
1272 }
1273
1274 /* Don't interrupt this serial stream! */
1275 spin_lock(&adapter->tpi_lock);
1276
1277 /* Initialize for ASIC core */
1278 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1279 val |= NP_LOAD;
1280 udelay(50);
1281 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1282 udelay(50);
1283 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1284 val &= ~S_LOAD_CORE;
1285 val &= ~S_CLOCK;
1286 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1287 udelay(50);
1288
1289 /* Serial program the ASIC clock synthesizer */
1290 bit_bang(adapter, T_CORE_VAL, T_CORE_BITS);
1291 bit_bang(adapter, N_CORE_VAL, N_CORE_BITS);
1292 bit_bang(adapter, M_CORE_VAL, M_CORE_BITS);
1293 udelay(50);
1294
1295 /* Finish ASIC core */
1296 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1297 val |= S_LOAD_CORE;
1298 udelay(50);
1299 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1300 udelay(50);
1301 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1302 val &= ~S_LOAD_CORE;
1303 udelay(50);
1304 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1305 udelay(50);
1306
1307 /* Initialize for memory */
1308 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1309 val |= NP_LOAD;
1310 udelay(50);
1311 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1312 udelay(50);
1313 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1314 val &= ~S_LOAD_MEM;
1315 val &= ~S_CLOCK;
1316 udelay(50);
1317 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1318 udelay(50);
1319
1320 /* Serial program the memory clock synthesizer */
1321 bit_bang(adapter, T_MEM_VAL, T_MEM_BITS);
1322 bit_bang(adapter, N_MEM_VAL, N_MEM_BITS);
1323 bit_bang(adapter, M_MEM_VAL, M_MEM_BITS);
1324 udelay(50);
1325
1326 /* Finish memory */
1327 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1328 val |= S_LOAD_MEM;
1329 udelay(50);
1330 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1331 udelay(50);
1332 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1333 val &= ~S_LOAD_MEM;
1334 udelay(50);
1335 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1336
1337 spin_unlock(&adapter->tpi_lock);
1338
1339 return 0;
1340}
1341
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001342static inline void t1_sw_reset(struct pci_dev *pdev)
1343{
1344 pci_write_config_dword(pdev, A_PCICFG_PM_CSR, 3);
1345 pci_write_config_dword(pdev, A_PCICFG_PM_CSR, 0);
1346}
1347
1348static void __devexit remove_one(struct pci_dev *pdev)
1349{
1350 struct net_device *dev = pci_get_drvdata(pdev);
Francois Romieu47cbe6f2006-12-05 23:19:06 +01001351 struct adapter *adapter = dev->priv;
1352 int i;
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001353
Francois Romieu47cbe6f2006-12-05 23:19:06 +01001354 for_each_port(adapter, i) {
1355 if (test_bit(i, &adapter->registered_device_map))
1356 unregister_netdev(adapter->port[i].dev);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001357 }
Francois Romieu47cbe6f2006-12-05 23:19:06 +01001358
1359 t1_free_sw_modules(adapter);
1360 iounmap(adapter->regs);
1361
1362 while (--i >= 0) {
1363 if (adapter->port[i].dev)
1364 free_netdev(adapter->port[i].dev);
1365 }
1366
1367 pci_release_regions(pdev);
1368 pci_disable_device(pdev);
1369 pci_set_drvdata(pdev, NULL);
1370 t1_sw_reset(pdev);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001371}
1372
1373static struct pci_driver driver = {
Scott Bardone559fb512005-06-23 01:40:19 -04001374 .name = DRV_NAME,
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001375 .id_table = t1_pci_tbl,
1376 .probe = init_one,
1377 .remove = __devexit_p(remove_one),
1378};
1379
1380static int __init t1_init_module(void)
1381{
Jeff Garzik29917622006-08-19 17:48:59 -04001382 return pci_register_driver(&driver);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001383}
1384
1385static void __exit t1_cleanup_module(void)
1386{
1387 pci_unregister_driver(&driver);
1388}
1389
1390module_init(t1_init_module);
1391module_exit(t1_cleanup_module);