blob: 0ca5b07c1a6ba691f989d8d6f058449e8ec3e3ff [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
Christoph Lameter8199d3a2005-03-30 13:34:31 -080072#define MAX_CMDQ_ENTRIES 16384
73#define MAX_CMDQ1_ENTRIES 1024
74#define MAX_RX_BUFFERS 16384
75#define MAX_RX_JUMBO_BUFFERS 16384
76#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
Christoph Lameter8199d3a2005-03-30 13:34:31 -080079#define MIN_FL_ENTRIES 32
80
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)");
113
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800114static 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
Stephen Hemminger20578152006-11-17 11:21:22 -0800146 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
223 adapter->params.has_msi = !disable_msi && pci_enable_msi(adapter->pdev) == 0;
224 err = request_irq(adapter->pdev->irq,
225 t1_select_intr_handler(adapter),
226 adapter->params.has_msi ? 0 : IRQF_SHARED,
227 adapter->name, adapter);
228 if (err) {
229 if (adapter->params.has_msi)
230 pci_disable_msi(adapter->pdev);
231
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800232 goto out_err;
Scott Bardone559fb512005-06-23 01:40:19 -0400233 }
Stephen Hemminger325dde42006-12-01 16:36:20 -0800234
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800235 t1_sge_start(adapter->sge);
236 t1_interrupts_enable(adapter);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800237 out_err:
238 return err;
239}
240
241/*
242 * Release resources when all the ports have been stopped.
243 */
244static void cxgb_down(struct adapter *adapter)
245{
246 t1_sge_stop(adapter->sge);
247 t1_interrupts_disable(adapter);
248 free_irq(adapter->pdev->irq, adapter);
Stephen Hemminger325dde42006-12-01 16:36:20 -0800249 if (adapter->params.has_msi)
250 pci_disable_msi(adapter->pdev);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800251}
252
253static int cxgb_open(struct net_device *dev)
254{
255 int err;
256 struct adapter *adapter = dev->priv;
257 int other_ports = adapter->open_device_map & PORT_MASK;
258
259 if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0)
260 return err;
261
262 __set_bit(dev->if_port, &adapter->open_device_map);
263 link_start(&adapter->port[dev->if_port]);
264 netif_start_queue(dev);
265 if (!other_ports && adapter->params.stats_update_period)
266 schedule_mac_stats_update(adapter,
267 adapter->params.stats_update_period);
268 return 0;
269}
270
271static int cxgb_close(struct net_device *dev)
272{
273 struct adapter *adapter = dev->priv;
274 struct port_info *p = &adapter->port[dev->if_port];
275 struct cmac *mac = p->mac;
276
277 netif_stop_queue(dev);
278 mac->ops->disable(mac, MAC_DIRECTION_TX | MAC_DIRECTION_RX);
279 netif_carrier_off(dev);
280
281 clear_bit(dev->if_port, &adapter->open_device_map);
282 if (adapter->params.stats_update_period &&
283 !(adapter->open_device_map & PORT_MASK)) {
284 /* Stop statistics accumulation. */
285 smp_mb__after_clear_bit();
286 spin_lock(&adapter->work_lock); /* sync with update task */
287 spin_unlock(&adapter->work_lock);
288 cancel_mac_stats_update(adapter);
289 }
290
291 if (!adapter->open_device_map)
292 cxgb_down(adapter);
293 return 0;
294}
295
296static struct net_device_stats *t1_get_stats(struct net_device *dev)
297{
298 struct adapter *adapter = dev->priv;
299 struct port_info *p = &adapter->port[dev->if_port];
300 struct net_device_stats *ns = &p->netstats;
301 const struct cmac_statistics *pstats;
302
303 /* Do a full update of the MAC stats */
304 pstats = p->mac->ops->statistics_update(p->mac,
Stephen Hemminger20578152006-11-17 11:21:22 -0800305 MAC_STATS_UPDATE_FULL);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800306
307 ns->tx_packets = pstats->TxUnicastFramesOK +
308 pstats->TxMulticastFramesOK + pstats->TxBroadcastFramesOK;
309
310 ns->rx_packets = pstats->RxUnicastFramesOK +
311 pstats->RxMulticastFramesOK + pstats->RxBroadcastFramesOK;
312
313 ns->tx_bytes = pstats->TxOctetsOK;
314 ns->rx_bytes = pstats->RxOctetsOK;
315
316 ns->tx_errors = pstats->TxLateCollisions + pstats->TxLengthErrors +
317 pstats->TxUnderrun + pstats->TxFramesAbortedDueToXSCollisions;
318 ns->rx_errors = pstats->RxDataErrors + pstats->RxJabberErrors +
319 pstats->RxFCSErrors + pstats->RxAlignErrors +
320 pstats->RxSequenceErrors + pstats->RxFrameTooLongErrors +
321 pstats->RxSymbolErrors + pstats->RxRuntErrors;
322
323 ns->multicast = pstats->RxMulticastFramesOK;
324 ns->collisions = pstats->TxTotalCollisions;
325
326 /* detailed rx_errors */
327 ns->rx_length_errors = pstats->RxFrameTooLongErrors +
328 pstats->RxJabberErrors;
329 ns->rx_over_errors = 0;
330 ns->rx_crc_errors = pstats->RxFCSErrors;
331 ns->rx_frame_errors = pstats->RxAlignErrors;
332 ns->rx_fifo_errors = 0;
333 ns->rx_missed_errors = 0;
334
335 /* detailed tx_errors */
336 ns->tx_aborted_errors = pstats->TxFramesAbortedDueToXSCollisions;
337 ns->tx_carrier_errors = 0;
338 ns->tx_fifo_errors = pstats->TxUnderrun;
339 ns->tx_heartbeat_errors = 0;
340 ns->tx_window_errors = pstats->TxLateCollisions;
341 return ns;
342}
343
344static u32 get_msglevel(struct net_device *dev)
345{
346 struct adapter *adapter = dev->priv;
347
348 return adapter->msg_enable;
349}
350
351static void set_msglevel(struct net_device *dev, u32 val)
352{
353 struct adapter *adapter = dev->priv;
354
355 adapter->msg_enable = val;
356}
357
358static char stats_strings[][ETH_GSTRING_LEN] = {
Stephen Hemminger20578152006-11-17 11:21:22 -0800359 "TxOctetsOK",
360 "TxOctetsBad",
361 "TxUnicastFramesOK",
362 "TxMulticastFramesOK",
363 "TxBroadcastFramesOK",
364 "TxPauseFrames",
365 "TxFramesWithDeferredXmissions",
366 "TxLateCollisions",
367 "TxTotalCollisions",
368 "TxFramesAbortedDueToXSCollisions",
369 "TxUnderrun",
370 "TxLengthErrors",
371 "TxInternalMACXmitError",
372 "TxFramesWithExcessiveDeferral",
373 "TxFCSErrors",
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800374
Stephen Hemminger20578152006-11-17 11:21:22 -0800375 "RxOctetsOK",
376 "RxOctetsBad",
377 "RxUnicastFramesOK",
378 "RxMulticastFramesOK",
379 "RxBroadcastFramesOK",
380 "RxPauseFrames",
381 "RxFCSErrors",
382 "RxAlignErrors",
383 "RxSymbolErrors",
384 "RxDataErrors",
385 "RxSequenceErrors",
386 "RxRuntErrors",
387 "RxJabberErrors",
388 "RxInternalMACRcvError",
389 "RxInRangeLengthErrors",
390 "RxOutOfRangeLengthField",
391 "RxFrameTooLongErrors",
Scott Bardone559fb512005-06-23 01:40:19 -0400392
393 "TSO",
394 "VLANextractions",
395 "VLANinsertions",
396 "RxCsumGood",
397 "TxCsumOffload",
398 "RxDrops"
399
400 "respQ_empty",
401 "respQ_overflow",
402 "freelistQ_empty",
403 "pkt_too_big",
404 "pkt_mismatch",
405 "cmdQ_full0",
406 "cmdQ_full1",
407 "tx_ipfrags",
408 "tx_reg_pkts",
409 "tx_lso_pkts",
410 "tx_do_cksum",
Stephen Hemminger20578152006-11-17 11:21:22 -0800411
Scott Bardone559fb512005-06-23 01:40:19 -0400412 "espi_DIP2ParityErr",
413 "espi_DIP4Err",
414 "espi_RxDrops",
415 "espi_TxDrops",
416 "espi_RxOvfl",
417 "espi_ParityErr"
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800418};
Stephen Hemminger20578152006-11-17 11:21:22 -0800419
Scott Bardone559fb512005-06-23 01:40:19 -0400420#define T2_REGMAP_SIZE (3 * 1024)
421
422static int get_regs_len(struct net_device *dev)
423{
424 return T2_REGMAP_SIZE;
425}
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800426
427static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
428{
429 struct adapter *adapter = dev->priv;
430
Scott Bardone559fb512005-06-23 01:40:19 -0400431 strcpy(info->driver, DRV_NAME);
432 strcpy(info->version, DRV_VERSION);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800433 strcpy(info->fw_version, "N/A");
434 strcpy(info->bus_info, pci_name(adapter->pdev));
435}
436
437static int get_stats_count(struct net_device *dev)
438{
439 return ARRAY_SIZE(stats_strings);
440}
441
442static void get_strings(struct net_device *dev, u32 stringset, u8 *data)
443{
444 if (stringset == ETH_SS_STATS)
445 memcpy(data, stats_strings, sizeof(stats_strings));
446}
447
448static void get_stats(struct net_device *dev, struct ethtool_stats *stats,
449 u64 *data)
450{
451 struct adapter *adapter = dev->priv;
452 struct cmac *mac = adapter->port[dev->if_port].mac;
453 const struct cmac_statistics *s;
Scott Bardone559fb512005-06-23 01:40:19 -0400454 const struct sge_port_stats *ss;
455 const struct sge_intr_counts *t;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800456
457 s = mac->ops->statistics_update(mac, MAC_STATS_UPDATE_FULL);
Scott Bardone559fb512005-06-23 01:40:19 -0400458 ss = t1_sge_get_port_stats(adapter->sge, dev->if_port);
459 t = t1_sge_get_intr_counts(adapter->sge);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800460
Stephen Hemminger20578152006-11-17 11:21:22 -0800461 *data++ = s->TxOctetsOK;
462 *data++ = s->TxOctetsBad;
463 *data++ = s->TxUnicastFramesOK;
464 *data++ = s->TxMulticastFramesOK;
465 *data++ = s->TxBroadcastFramesOK;
466 *data++ = s->TxPauseFrames;
467 *data++ = s->TxFramesWithDeferredXmissions;
468 *data++ = s->TxLateCollisions;
469 *data++ = s->TxTotalCollisions;
470 *data++ = s->TxFramesAbortedDueToXSCollisions;
471 *data++ = s->TxUnderrun;
472 *data++ = s->TxLengthErrors;
473 *data++ = s->TxInternalMACXmitError;
474 *data++ = s->TxFramesWithExcessiveDeferral;
475 *data++ = s->TxFCSErrors;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800476
Stephen Hemminger20578152006-11-17 11:21:22 -0800477 *data++ = s->RxOctetsOK;
478 *data++ = s->RxOctetsBad;
479 *data++ = s->RxUnicastFramesOK;
480 *data++ = s->RxMulticastFramesOK;
481 *data++ = s->RxBroadcastFramesOK;
482 *data++ = s->RxPauseFrames;
483 *data++ = s->RxFCSErrors;
484 *data++ = s->RxAlignErrors;
485 *data++ = s->RxSymbolErrors;
486 *data++ = s->RxDataErrors;
487 *data++ = s->RxSequenceErrors;
488 *data++ = s->RxRuntErrors;
489 *data++ = s->RxJabberErrors;
490 *data++ = s->RxInternalMACRcvError;
491 *data++ = s->RxInRangeLengthErrors;
492 *data++ = s->RxOutOfRangeLengthField;
493 *data++ = s->RxFrameTooLongErrors;
Scott Bardone559fb512005-06-23 01:40:19 -0400494
495 *data++ = ss->tso;
496 *data++ = ss->vlan_xtract;
497 *data++ = ss->vlan_insert;
498 *data++ = ss->rx_cso_good;
499 *data++ = ss->tx_cso;
500 *data++ = ss->rx_drops;
501
502 *data++ = (u64)t->respQ_empty;
503 *data++ = (u64)t->respQ_overflow;
504 *data++ = (u64)t->freelistQ_empty;
505 *data++ = (u64)t->pkt_too_big;
506 *data++ = (u64)t->pkt_mismatch;
507 *data++ = (u64)t->cmdQ_full[0];
508 *data++ = (u64)t->cmdQ_full[1];
509 *data++ = (u64)t->tx_ipfrags;
510 *data++ = (u64)t->tx_reg_pkts;
511 *data++ = (u64)t->tx_lso_pkts;
512 *data++ = (u64)t->tx_do_cksum;
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800513
514 if (adapter->espi) {
515 const struct espi_intr_counts *e;
516
517 e = t1_espi_get_intr_counts(adapter->espi);
518 *data++ = (u64) e->DIP2_parity_err;
519 *data++ = (u64) e->DIP4_err;
520 *data++ = (u64) e->rx_drops;
521 *data++ = (u64) e->tx_drops;
522 *data++ = (u64) e->rx_ovflw;
523 *data++ = (u64) e->parity_err;
524 }
Scott Bardone559fb512005-06-23 01:40:19 -0400525}
526
527static inline void reg_block_dump(struct adapter *ap, void *buf,
528 unsigned int start, unsigned int end)
529{
530 u32 *p = buf + start;
531
532 for ( ; start <= end; start += sizeof(u32))
533 *p++ = readl(ap->regs + start);
534}
535
536static void get_regs(struct net_device *dev, struct ethtool_regs *regs,
537 void *buf)
538{
539 struct adapter *ap = dev->priv;
540
541 /*
542 * Version scheme: bits 0..9: chip version, bits 10..15: chip revision
543 */
544 regs->version = 2;
545
546 memset(buf, 0, T2_REGMAP_SIZE);
547 reg_block_dump(ap, buf, 0, A_SG_RESPACCUTIMER);
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800548 reg_block_dump(ap, buf, A_MC3_CFG, A_MC4_INT_CAUSE);
549 reg_block_dump(ap, buf, A_TPI_ADDR, A_TPI_PAR);
550 reg_block_dump(ap, buf, A_TP_IN_CONFIG, A_TP_TX_DROP_COUNT);
551 reg_block_dump(ap, buf, A_RAT_ROUTE_CONTROL, A_RAT_INTR_CAUSE);
552 reg_block_dump(ap, buf, A_CSPI_RX_AE_WM, A_CSPI_INTR_ENABLE);
553 reg_block_dump(ap, buf, A_ESPI_SCH_TOKEN0, A_ESPI_GOSTAT);
554 reg_block_dump(ap, buf, A_ULP_ULIMIT, A_ULP_PIO_CTRL);
555 reg_block_dump(ap, buf, A_PL_ENABLE, A_PL_CAUSE);
556 reg_block_dump(ap, buf, A_MC5_CONFIG, A_MC5_MASK_WRITE_CMD);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800557}
558
559static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
560{
561 struct adapter *adapter = dev->priv;
562 struct port_info *p = &adapter->port[dev->if_port];
563
564 cmd->supported = p->link_config.supported;
565 cmd->advertising = p->link_config.advertising;
566
567 if (netif_carrier_ok(dev)) {
568 cmd->speed = p->link_config.speed;
569 cmd->duplex = p->link_config.duplex;
570 } else {
571 cmd->speed = -1;
572 cmd->duplex = -1;
573 }
574
Stephen Hemminger20578152006-11-17 11:21:22 -0800575 cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE;
576 cmd->phy_address = p->phy->addr;
577 cmd->transceiver = XCVR_EXTERNAL;
578 cmd->autoneg = p->link_config.autoneg;
579 cmd->maxtxpkt = 0;
580 cmd->maxrxpkt = 0;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800581 return 0;
582}
583
584static int speed_duplex_to_caps(int speed, int duplex)
585{
586 int cap = 0;
587
588 switch (speed) {
589 case SPEED_10:
590 if (duplex == DUPLEX_FULL)
591 cap = SUPPORTED_10baseT_Full;
592 else
593 cap = SUPPORTED_10baseT_Half;
594 break;
595 case SPEED_100:
596 if (duplex == DUPLEX_FULL)
597 cap = SUPPORTED_100baseT_Full;
598 else
599 cap = SUPPORTED_100baseT_Half;
600 break;
601 case SPEED_1000:
602 if (duplex == DUPLEX_FULL)
603 cap = SUPPORTED_1000baseT_Full;
604 else
605 cap = SUPPORTED_1000baseT_Half;
606 break;
607 case SPEED_10000:
608 if (duplex == DUPLEX_FULL)
609 cap = SUPPORTED_10000baseT_Full;
610 }
611 return cap;
612}
613
614#define ADVERTISED_MASK (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | \
615 ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | \
616 ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full | \
617 ADVERTISED_10000baseT_Full)
618
619static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
620{
621 struct adapter *adapter = dev->priv;
622 struct port_info *p = &adapter->port[dev->if_port];
623 struct link_config *lc = &p->link_config;
624
625 if (!(lc->supported & SUPPORTED_Autoneg))
Scott Bardone559fb512005-06-23 01:40:19 -0400626 return -EOPNOTSUPP; /* can't change speed/duplex */
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800627
628 if (cmd->autoneg == AUTONEG_DISABLE) {
629 int cap = speed_duplex_to_caps(cmd->speed, cmd->duplex);
630
631 if (!(lc->supported & cap) || cmd->speed == SPEED_1000)
632 return -EINVAL;
633 lc->requested_speed = cmd->speed;
634 lc->requested_duplex = cmd->duplex;
635 lc->advertising = 0;
636 } else {
637 cmd->advertising &= ADVERTISED_MASK;
638 if (cmd->advertising & (cmd->advertising - 1))
639 cmd->advertising = lc->supported;
640 cmd->advertising &= lc->supported;
641 if (!cmd->advertising)
642 return -EINVAL;
643 lc->requested_speed = SPEED_INVALID;
644 lc->requested_duplex = DUPLEX_INVALID;
645 lc->advertising = cmd->advertising | ADVERTISED_Autoneg;
646 }
647 lc->autoneg = cmd->autoneg;
648 if (netif_running(dev))
649 t1_link_start(p->phy, p->mac, lc);
650 return 0;
651}
652
653static void get_pauseparam(struct net_device *dev,
654 struct ethtool_pauseparam *epause)
655{
656 struct adapter *adapter = dev->priv;
657 struct port_info *p = &adapter->port[dev->if_port];
658
659 epause->autoneg = (p->link_config.requested_fc & PAUSE_AUTONEG) != 0;
660 epause->rx_pause = (p->link_config.fc & PAUSE_RX) != 0;
661 epause->tx_pause = (p->link_config.fc & PAUSE_TX) != 0;
662}
663
664static int set_pauseparam(struct net_device *dev,
665 struct ethtool_pauseparam *epause)
666{
667 struct adapter *adapter = dev->priv;
668 struct port_info *p = &adapter->port[dev->if_port];
669 struct link_config *lc = &p->link_config;
670
671 if (epause->autoneg == AUTONEG_DISABLE)
672 lc->requested_fc = 0;
673 else if (lc->supported & SUPPORTED_Autoneg)
674 lc->requested_fc = PAUSE_AUTONEG;
675 else
676 return -EINVAL;
677
678 if (epause->rx_pause)
679 lc->requested_fc |= PAUSE_RX;
680 if (epause->tx_pause)
681 lc->requested_fc |= PAUSE_TX;
682 if (lc->autoneg == AUTONEG_ENABLE) {
683 if (netif_running(dev))
684 t1_link_start(p->phy, p->mac, lc);
685 } else {
686 lc->fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
687 if (netif_running(dev))
688 p->mac->ops->set_speed_duplex_fc(p->mac, -1, -1,
689 lc->fc);
690 }
691 return 0;
692}
693
694static u32 get_rx_csum(struct net_device *dev)
695{
696 struct adapter *adapter = dev->priv;
697
698 return (adapter->flags & RX_CSUM_ENABLED) != 0;
699}
700
701static int set_rx_csum(struct net_device *dev, u32 data)
702{
703 struct adapter *adapter = dev->priv;
704
705 if (data)
706 adapter->flags |= RX_CSUM_ENABLED;
707 else
708 adapter->flags &= ~RX_CSUM_ENABLED;
709 return 0;
710}
711
712static int set_tso(struct net_device *dev, u32 value)
713{
714 struct adapter *adapter = dev->priv;
715
716 if (!(adapter->flags & TSO_CAPABLE))
717 return value ? -EOPNOTSUPP : 0;
718 return ethtool_op_set_tso(dev, value);
719}
720
721static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
722{
723 struct adapter *adapter = dev->priv;
724 int jumbo_fl = t1_is_T1B(adapter) ? 1 : 0;
725
726 e->rx_max_pending = MAX_RX_BUFFERS;
727 e->rx_mini_max_pending = 0;
728 e->rx_jumbo_max_pending = MAX_RX_JUMBO_BUFFERS;
729 e->tx_max_pending = MAX_CMDQ_ENTRIES;
730
731 e->rx_pending = adapter->params.sge.freelQ_size[!jumbo_fl];
732 e->rx_mini_pending = 0;
733 e->rx_jumbo_pending = adapter->params.sge.freelQ_size[jumbo_fl];
734 e->tx_pending = adapter->params.sge.cmdQ_size[0];
735}
736
737static int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
738{
739 struct adapter *adapter = dev->priv;
740 int jumbo_fl = t1_is_T1B(adapter) ? 1 : 0;
741
742 if (e->rx_pending > MAX_RX_BUFFERS || e->rx_mini_pending ||
743 e->rx_jumbo_pending > MAX_RX_JUMBO_BUFFERS ||
744 e->tx_pending > MAX_CMDQ_ENTRIES ||
745 e->rx_pending < MIN_FL_ENTRIES ||
746 e->rx_jumbo_pending < MIN_FL_ENTRIES ||
747 e->tx_pending < (adapter->params.nports + 1) * (MAX_SKB_FRAGS + 1))
748 return -EINVAL;
749
750 if (adapter->flags & FULL_INIT_DONE)
Stephen Hemminger20578152006-11-17 11:21:22 -0800751 return -EBUSY;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800752
753 adapter->params.sge.freelQ_size[!jumbo_fl] = e->rx_pending;
754 adapter->params.sge.freelQ_size[jumbo_fl] = e->rx_jumbo_pending;
755 adapter->params.sge.cmdQ_size[0] = e->tx_pending;
756 adapter->params.sge.cmdQ_size[1] = e->tx_pending > MAX_CMDQ1_ENTRIES ?
757 MAX_CMDQ1_ENTRIES : e->tx_pending;
758 return 0;
759}
760
761static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
762{
763 struct adapter *adapter = dev->priv;
764
Scott Bardone559fb512005-06-23 01:40:19 -0400765 /*
766 * If RX coalescing is requested we use NAPI, otherwise interrupts.
767 * This choice can be made only when all ports and the TOE are off.
768 */
769 if (adapter->open_device_map == 0)
770 adapter->params.sge.polling = c->use_adaptive_rx_coalesce;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800771
Scott Bardone559fb512005-06-23 01:40:19 -0400772 if (adapter->params.sge.polling) {
773 adapter->params.sge.rx_coalesce_usecs = 0;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800774 } else {
775 adapter->params.sge.rx_coalesce_usecs = c->rx_coalesce_usecs;
776 }
Scott Bardone559fb512005-06-23 01:40:19 -0400777 adapter->params.sge.coalesce_enable = c->use_adaptive_rx_coalesce;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800778 adapter->params.sge.sample_interval_usecs = c->rate_sample_interval;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800779 t1_sge_set_coalesce_params(adapter->sge, &adapter->params.sge);
780 return 0;
781}
782
783static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
784{
785 struct adapter *adapter = dev->priv;
786
Scott Bardone559fb512005-06-23 01:40:19 -0400787 c->rx_coalesce_usecs = adapter->params.sge.rx_coalesce_usecs;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800788 c->rate_sample_interval = adapter->params.sge.sample_interval_usecs;
789 c->use_adaptive_rx_coalesce = adapter->params.sge.coalesce_enable;
790 return 0;
791}
792
793static int get_eeprom_len(struct net_device *dev)
794{
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800795 struct adapter *adapter = dev->priv;
796
797 return t1_is_asic(adapter) ? EEPROM_SIZE : 0;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800798}
799
800#define EEPROM_MAGIC(ap) \
801 (PCI_VENDOR_ID_CHELSIO | ((ap)->params.chip_version << 16))
802
803static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *e,
804 u8 *data)
805{
806 int i;
807 u8 buf[EEPROM_SIZE] __attribute__((aligned(4)));
808 struct adapter *adapter = dev->priv;
809
810 e->magic = EEPROM_MAGIC(adapter);
811 for (i = e->offset & ~3; i < e->offset + e->len; i += sizeof(u32))
812 t1_seeprom_read(adapter, i, (u32 *)&buf[i]);
813 memcpy(data, buf + e->offset, e->len);
814 return 0;
815}
816
Jeff Garzik7282d492006-09-13 14:30:00 -0400817static const struct ethtool_ops t1_ethtool_ops = {
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800818 .get_settings = get_settings,
819 .set_settings = set_settings,
820 .get_drvinfo = get_drvinfo,
821 .get_msglevel = get_msglevel,
822 .set_msglevel = set_msglevel,
823 .get_ringparam = get_sge_param,
824 .set_ringparam = set_sge_param,
825 .get_coalesce = get_coalesce,
826 .set_coalesce = set_coalesce,
827 .get_eeprom_len = get_eeprom_len,
828 .get_eeprom = get_eeprom,
829 .get_pauseparam = get_pauseparam,
830 .set_pauseparam = set_pauseparam,
831 .get_rx_csum = get_rx_csum,
832 .set_rx_csum = set_rx_csum,
833 .get_tx_csum = ethtool_op_get_tx_csum,
834 .set_tx_csum = ethtool_op_set_tx_csum,
835 .get_sg = ethtool_op_get_sg,
836 .set_sg = ethtool_op_set_sg,
837 .get_link = ethtool_op_get_link,
838 .get_strings = get_strings,
839 .get_stats_count = get_stats_count,
840 .get_ethtool_stats = get_stats,
Scott Bardone559fb512005-06-23 01:40:19 -0400841 .get_regs_len = get_regs_len,
842 .get_regs = get_regs,
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800843 .get_tso = ethtool_op_get_tso,
844 .set_tso = set_tso,
845};
846
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800847static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
848{
Stephen Hemminger20578152006-11-17 11:21:22 -0800849 struct adapter *adapter = dev->priv;
850 struct mii_ioctl_data *data = if_mii(req);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800851
852 switch (cmd) {
Stephen Hemminger20578152006-11-17 11:21:22 -0800853 case SIOCGMIIPHY:
854 data->phy_id = adapter->port[dev->if_port].phy->addr;
855 /* FALLTHRU */
856 case SIOCGMIIREG: {
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800857 struct cphy *phy = adapter->port[dev->if_port].phy;
858 u32 val;
859
Scott Bardone559fb512005-06-23 01:40:19 -0400860 if (!phy->mdio_read)
Stephen Hemminger20578152006-11-17 11:21:22 -0800861 return -EOPNOTSUPP;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800862 phy->mdio_read(adapter, data->phy_id, 0, data->reg_num & 0x1f,
863 &val);
Stephen Hemminger20578152006-11-17 11:21:22 -0800864 data->val_out = val;
865 break;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800866 }
Stephen Hemminger20578152006-11-17 11:21:22 -0800867 case SIOCSMIIREG: {
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800868 struct cphy *phy = adapter->port[dev->if_port].phy;
869
Stephen Hemminger20578152006-11-17 11:21:22 -0800870 if (!capable(CAP_NET_ADMIN))
871 return -EPERM;
Scott Bardone559fb512005-06-23 01:40:19 -0400872 if (!phy->mdio_write)
Stephen Hemminger20578152006-11-17 11:21:22 -0800873 return -EOPNOTSUPP;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800874 phy->mdio_write(adapter, data->phy_id, 0, data->reg_num & 0x1f,
Scott Bardone559fb512005-06-23 01:40:19 -0400875 data->val_in);
Stephen Hemminger20578152006-11-17 11:21:22 -0800876 break;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800877 }
878
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800879 default:
880 return -EOPNOTSUPP;
881 }
882 return 0;
883}
884
885static int t1_change_mtu(struct net_device *dev, int new_mtu)
886{
887 int ret;
888 struct adapter *adapter = dev->priv;
889 struct cmac *mac = adapter->port[dev->if_port].mac;
890
891 if (!mac->ops->set_mtu)
Stephen Hemminger20578152006-11-17 11:21:22 -0800892 return -EOPNOTSUPP;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800893 if (new_mtu < 68)
Stephen Hemminger20578152006-11-17 11:21:22 -0800894 return -EINVAL;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800895 if ((ret = mac->ops->set_mtu(mac, new_mtu)))
896 return ret;
897 dev->mtu = new_mtu;
898 return 0;
899}
900
901static int t1_set_mac_addr(struct net_device *dev, void *p)
902{
903 struct adapter *adapter = dev->priv;
904 struct cmac *mac = adapter->port[dev->if_port].mac;
905 struct sockaddr *addr = p;
906
907 if (!mac->ops->macaddress_set)
908 return -EOPNOTSUPP;
909
910 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
911 mac->ops->macaddress_set(mac, dev->dev_addr);
912 return 0;
913}
914
915#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
916static void vlan_rx_register(struct net_device *dev,
917 struct vlan_group *grp)
918{
919 struct adapter *adapter = dev->priv;
920
921 spin_lock_irq(&adapter->async_lock);
922 adapter->vlan_grp = grp;
923 t1_set_vlan_accel(adapter, grp != NULL);
924 spin_unlock_irq(&adapter->async_lock);
925}
926
927static void vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
928{
929 struct adapter *adapter = dev->priv;
930
931 spin_lock_irq(&adapter->async_lock);
932 if (adapter->vlan_grp)
933 adapter->vlan_grp->vlan_devices[vid] = NULL;
934 spin_unlock_irq(&adapter->async_lock);
935}
936#endif
937
938#ifdef CONFIG_NET_POLL_CONTROLLER
939static void t1_netpoll(struct net_device *dev)
940{
Scott Bardone559fb512005-06-23 01:40:19 -0400941 unsigned long flags;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800942 struct adapter *adapter = dev->priv;
943
Scott Bardone559fb512005-06-23 01:40:19 -0400944 local_irq_save(flags);
Stephen Hemminger20578152006-11-17 11:21:22 -0800945 t1_select_intr_handler(adapter)(adapter->pdev->irq, adapter);
Scott Bardone559fb512005-06-23 01:40:19 -0400946 local_irq_restore(flags);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800947}
948#endif
949
950/*
951 * Periodic accumulation of MAC statistics. This is used only if the MAC
952 * does not have any other way to prevent stats counter overflow.
953 */
954static void mac_stats_task(void *data)
955{
956 int i;
957 struct adapter *adapter = data;
958
959 for_each_port(adapter, i) {
960 struct port_info *p = &adapter->port[i];
961
962 if (netif_running(p->dev))
963 p->mac->ops->statistics_update(p->mac,
964 MAC_STATS_UPDATE_FAST);
965 }
966
967 /* Schedule the next statistics update if any port is active. */
968 spin_lock(&adapter->work_lock);
969 if (adapter->open_device_map & PORT_MASK)
970 schedule_mac_stats_update(adapter,
971 adapter->params.stats_update_period);
972 spin_unlock(&adapter->work_lock);
973}
974
975/*
976 * Processes elmer0 external interrupts in process context.
977 */
978static void ext_intr_task(void *data)
979{
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800980 struct adapter *adapter = data;
981
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800982 t1_elmer0_ext_intr_handler(adapter);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800983
984 /* Now reenable external interrupts */
Scott Bardone559fb512005-06-23 01:40:19 -0400985 spin_lock_irq(&adapter->async_lock);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800986 adapter->slow_intr_mask |= F_PL_INTR_EXT;
Scott Bardone559fb512005-06-23 01:40:19 -0400987 writel(F_PL_INTR_EXT, adapter->regs + A_PL_CAUSE);
988 writel(adapter->slow_intr_mask | F_PL_INTR_SGE_DATA,
Stephen Hemminger20578152006-11-17 11:21:22 -0800989 adapter->regs + A_PL_ENABLE);
Scott Bardone559fb512005-06-23 01:40:19 -0400990 spin_unlock_irq(&adapter->async_lock);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800991}
992
993/*
994 * Interrupt-context handler for elmer0 external interrupts.
995 */
996void t1_elmer0_ext_intr(struct adapter *adapter)
997{
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800998 /*
999 * Schedule a task to handle external interrupts as we require
1000 * a process context. We disable EXT interrupts in the interim
1001 * and let the task reenable them when it's done.
1002 */
1003 adapter->slow_intr_mask &= ~F_PL_INTR_EXT;
Scott Bardone559fb512005-06-23 01:40:19 -04001004 writel(adapter->slow_intr_mask | F_PL_INTR_SGE_DATA,
Stephen Hemminger20578152006-11-17 11:21:22 -08001005 adapter->regs + A_PL_ENABLE);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001006 schedule_work(&adapter->ext_intr_handler_task);
1007}
1008
1009void t1_fatal_err(struct adapter *adapter)
1010{
1011 if (adapter->flags & FULL_INIT_DONE) {
1012 t1_sge_stop(adapter->sge);
1013 t1_interrupts_disable(adapter);
1014 }
1015 CH_ALERT("%s: encountered fatal error, operation suspended\n",
1016 adapter->name);
1017}
1018
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001019static int __devinit init_one(struct pci_dev *pdev,
1020 const struct pci_device_id *ent)
1021{
1022 static int version_printed;
1023
1024 int i, err, pci_using_dac = 0;
1025 unsigned long mmio_start, mmio_len;
1026 const struct board_info *bi;
1027 struct adapter *adapter = NULL;
1028 struct port_info *pi;
1029
1030 if (!version_printed) {
Scott Bardone559fb512005-06-23 01:40:19 -04001031 printk(KERN_INFO "%s - version %s\n", DRV_DESCRIPTION,
1032 DRV_VERSION);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001033 ++version_printed;
1034 }
1035
1036 err = pci_enable_device(pdev);
1037 if (err)
Stephen Hemminger20578152006-11-17 11:21:22 -08001038 return err;
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001039
1040 if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
1041 CH_ERR("%s: cannot find PCI device memory base address\n",
1042 pci_name(pdev));
1043 err = -ENODEV;
1044 goto out_disable_pdev;
1045 }
1046
Scott Bardone559fb512005-06-23 01:40:19 -04001047 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001048 pci_using_dac = 1;
Scott Bardone559fb512005-06-23 01:40:19 -04001049
1050 if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001051 CH_ERR("%s: unable to obtain 64-bit DMA for"
1052 "consistent allocations\n", pci_name(pdev));
1053 err = -ENODEV;
1054 goto out_disable_pdev;
1055 }
Scott Bardone559fb512005-06-23 01:40:19 -04001056
1057 } else if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) != 0) {
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001058 CH_ERR("%s: no usable DMA configuration\n", pci_name(pdev));
1059 goto out_disable_pdev;
1060 }
1061
Scott Bardone559fb512005-06-23 01:40:19 -04001062 err = pci_request_regions(pdev, DRV_NAME);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001063 if (err) {
1064 CH_ERR("%s: cannot obtain PCI resources\n", pci_name(pdev));
1065 goto out_disable_pdev;
1066 }
1067
1068 pci_set_master(pdev);
1069
Stephen Hemminger20578152006-11-17 11:21:22 -08001070 mmio_start = pci_resource_start(pdev, 0);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001071 mmio_len = pci_resource_len(pdev, 0);
1072 bi = t1_get_board_info(ent->driver_data);
1073
1074 for (i = 0; i < bi->port_number; ++i) {
1075 struct net_device *netdev;
1076
1077 netdev = alloc_etherdev(adapter ? 0 : sizeof(*adapter));
1078 if (!netdev) {
1079 err = -ENOMEM;
1080 goto out_free_dev;
1081 }
1082
1083 SET_MODULE_OWNER(netdev);
1084 SET_NETDEV_DEV(netdev, &pdev->dev);
1085
1086 if (!adapter) {
1087 adapter = netdev->priv;
1088 adapter->pdev = pdev;
1089 adapter->port[0].dev = netdev; /* so we don't leak it */
1090
1091 adapter->regs = ioremap(mmio_start, mmio_len);
1092 if (!adapter->regs) {
1093 CH_ERR("%s: cannot map device registers\n",
1094 pci_name(pdev));
1095 err = -ENOMEM;
1096 goto out_free_dev;
1097 }
1098
1099 if (t1_get_board_rev(adapter, bi, &adapter->params)) {
1100 err = -ENODEV; /* Can't handle this chip rev */
1101 goto out_free_dev;
1102 }
1103
1104 adapter->name = pci_name(pdev);
1105 adapter->msg_enable = dflt_msg_enable;
1106 adapter->mmio_len = mmio_len;
1107
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001108 spin_lock_init(&adapter->tpi_lock);
1109 spin_lock_init(&adapter->work_lock);
1110 spin_lock_init(&adapter->async_lock);
Stephen Hemminger352c4172006-12-01 16:36:17 -08001111 spin_lock_init(&adapter->mac_lock);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001112
1113 INIT_WORK(&adapter->ext_intr_handler_task,
1114 ext_intr_task, adapter);
1115 INIT_WORK(&adapter->stats_update_task, mac_stats_task,
1116 adapter);
1117
1118 pci_set_drvdata(pdev, netdev);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001119 }
1120
1121 pi = &adapter->port[i];
1122 pi->dev = netdev;
1123 netif_carrier_off(netdev);
1124 netdev->irq = pdev->irq;
1125 netdev->if_port = i;
1126 netdev->mem_start = mmio_start;
1127 netdev->mem_end = mmio_start + mmio_len - 1;
1128 netdev->priv = adapter;
1129 netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
Scott Bardone559fb512005-06-23 01:40:19 -04001130 netdev->features |= NETIF_F_LLTX;
1131
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001132 adapter->flags |= RX_CSUM_ENABLED | TCP_CSUM_CAPABLE;
1133 if (pci_using_dac)
1134 netdev->features |= NETIF_F_HIGHDMA;
1135 if (vlan_tso_capable(adapter)) {
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001136#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
1137 adapter->flags |= VLAN_ACCEL_CAPABLE;
1138 netdev->features |=
1139 NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
1140 netdev->vlan_rx_register = vlan_rx_register;
1141 netdev->vlan_rx_kill_vid = vlan_rx_kill_vid;
1142#endif
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001143
1144 /* T204: disable TSO */
1145 if (!(is_T2(adapter)) || bi->port_number != 4) {
1146 adapter->flags |= TSO_CAPABLE;
1147 netdev->features |= NETIF_F_TSO;
1148 }
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001149 }
1150
1151 netdev->open = cxgb_open;
1152 netdev->stop = cxgb_close;
1153 netdev->hard_start_xmit = t1_start_xmit;
1154 netdev->hard_header_len += (adapter->flags & TSO_CAPABLE) ?
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001155 sizeof(struct cpl_tx_pkt_lso) : sizeof(struct cpl_tx_pkt);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001156 netdev->get_stats = t1_get_stats;
1157 netdev->set_multicast_list = t1_set_rxmode;
1158 netdev->do_ioctl = t1_ioctl;
1159 netdev->change_mtu = t1_change_mtu;
1160 netdev->set_mac_address = t1_set_mac_addr;
1161#ifdef CONFIG_NET_POLL_CONTROLLER
1162 netdev->poll_controller = t1_netpoll;
1163#endif
1164 netdev->weight = 64;
1165
Stephen Hemminger20578152006-11-17 11:21:22 -08001166 SET_ETHTOOL_OPS(netdev, &t1_ethtool_ops);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001167 }
1168
1169 if (t1_init_sw_modules(adapter, bi) < 0) {
1170 err = -ENODEV;
1171 goto out_free_dev;
1172 }
1173
1174 /*
1175 * The card is now ready to go. If any errors occur during device
1176 * registration we do not fail the whole card but rather proceed only
1177 * with the ports we manage to register successfully. However we must
1178 * register at least one net device.
1179 */
1180 for (i = 0; i < bi->port_number; ++i) {
1181 err = register_netdev(adapter->port[i].dev);
1182 if (err)
1183 CH_WARN("%s: cannot register net device %s, skipping\n",
1184 pci_name(pdev), adapter->port[i].dev->name);
1185 else {
1186 /*
1187 * Change the name we use for messages to the name of
1188 * the first successfully registered interface.
1189 */
1190 if (!adapter->registered_device_map)
1191 adapter->name = adapter->port[i].dev->name;
1192
Stephen Hemminger20578152006-11-17 11:21:22 -08001193 __set_bit(i, &adapter->registered_device_map);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001194 }
1195 }
1196 if (!adapter->registered_device_map) {
1197 CH_ERR("%s: could not register any net devices\n",
1198 pci_name(pdev));
1199 goto out_release_adapter_res;
1200 }
1201
1202 printk(KERN_INFO "%s: %s (rev %d), %s %dMHz/%d-bit\n", adapter->name,
1203 bi->desc, adapter->params.chip_revision,
1204 adapter->params.pci.is_pcix ? "PCIX" : "PCI",
1205 adapter->params.pci.speed, adapter->params.pci.width);
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001206
1207 /*
1208 * Set the T1B ASIC and memory clocks.
1209 */
1210 if (t1powersave)
1211 adapter->t1powersave = LCLOCK; /* HW default is powersave mode. */
1212 else
1213 adapter->t1powersave = HCLOCK;
1214 if (t1_is_T1B(adapter))
1215 t1_clock(adapter, t1powersave);
1216
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001217 return 0;
1218
1219 out_release_adapter_res:
1220 t1_free_sw_modules(adapter);
1221 out_free_dev:
1222 if (adapter) {
Stephen Hemmingere4876472006-11-17 11:25:23 -08001223 if (adapter->regs)
1224 iounmap(adapter->regs);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001225 for (i = bi->port_number - 1; i >= 0; --i)
Stephen Hemmingere4876472006-11-17 11:25:23 -08001226 if (adapter->port[i].dev)
1227 free_netdev(adapter->port[i].dev);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001228 }
1229 pci_release_regions(pdev);
1230 out_disable_pdev:
1231 pci_disable_device(pdev);
1232 pci_set_drvdata(pdev, NULL);
1233 return err;
1234}
1235
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001236static void bit_bang(struct adapter *adapter, int bitdata, int nbits)
1237{
1238 int data;
1239 int i;
1240 u32 val;
1241
1242 enum {
1243 S_CLOCK = 1 << 3,
1244 S_DATA = 1 << 4
1245 };
1246
1247 for (i = (nbits - 1); i > -1; i--) {
1248
1249 udelay(50);
1250
1251 data = ((bitdata >> i) & 0x1);
1252 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1253
1254 if (data)
1255 val |= S_DATA;
1256 else
1257 val &= ~S_DATA;
1258
1259 udelay(50);
1260
1261 /* Set SCLOCK low */
1262 val &= ~S_CLOCK;
1263 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1264
1265 udelay(50);
1266
1267 /* Write SCLOCK high */
1268 val |= S_CLOCK;
1269 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1270
1271 }
1272}
1273
1274static int t1_clock(struct adapter *adapter, int mode)
1275{
1276 u32 val;
1277 int M_CORE_VAL;
1278 int M_MEM_VAL;
1279
1280 enum {
1281 M_CORE_BITS = 9,
1282 T_CORE_VAL = 0,
1283 T_CORE_BITS = 2,
1284 N_CORE_VAL = 0,
1285 N_CORE_BITS = 2,
1286 M_MEM_BITS = 9,
1287 T_MEM_VAL = 0,
1288 T_MEM_BITS = 2,
1289 N_MEM_VAL = 0,
1290 N_MEM_BITS = 2,
1291 NP_LOAD = 1 << 17,
1292 S_LOAD_MEM = 1 << 5,
1293 S_LOAD_CORE = 1 << 6,
1294 S_CLOCK = 1 << 3
1295 };
1296
1297 if (!t1_is_T1B(adapter))
1298 return -ENODEV; /* Can't re-clock this chip. */
1299
1300 if (mode & 2) {
1301 return 0; /* show current mode. */
1302 }
1303
1304 if ((adapter->t1powersave & 1) == (mode & 1))
1305 return -EALREADY; /* ASIC already running in mode. */
1306
1307 if ((mode & 1) == HCLOCK) {
1308 M_CORE_VAL = 0x14;
1309 M_MEM_VAL = 0x18;
1310 adapter->t1powersave = HCLOCK; /* overclock */
1311 } else {
1312 M_CORE_VAL = 0xe;
1313 M_MEM_VAL = 0x10;
1314 adapter->t1powersave = LCLOCK; /* underclock */
1315 }
1316
1317 /* Don't interrupt this serial stream! */
1318 spin_lock(&adapter->tpi_lock);
1319
1320 /* Initialize for ASIC core */
1321 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1322 val |= NP_LOAD;
1323 udelay(50);
1324 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1325 udelay(50);
1326 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1327 val &= ~S_LOAD_CORE;
1328 val &= ~S_CLOCK;
1329 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1330 udelay(50);
1331
1332 /* Serial program the ASIC clock synthesizer */
1333 bit_bang(adapter, T_CORE_VAL, T_CORE_BITS);
1334 bit_bang(adapter, N_CORE_VAL, N_CORE_BITS);
1335 bit_bang(adapter, M_CORE_VAL, M_CORE_BITS);
1336 udelay(50);
1337
1338 /* Finish ASIC core */
1339 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1340 val |= S_LOAD_CORE;
1341 udelay(50);
1342 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1343 udelay(50);
1344 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1345 val &= ~S_LOAD_CORE;
1346 udelay(50);
1347 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1348 udelay(50);
1349
1350 /* Initialize for memory */
1351 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1352 val |= NP_LOAD;
1353 udelay(50);
1354 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1355 udelay(50);
1356 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1357 val &= ~S_LOAD_MEM;
1358 val &= ~S_CLOCK;
1359 udelay(50);
1360 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1361 udelay(50);
1362
1363 /* Serial program the memory clock synthesizer */
1364 bit_bang(adapter, T_MEM_VAL, T_MEM_BITS);
1365 bit_bang(adapter, N_MEM_VAL, N_MEM_BITS);
1366 bit_bang(adapter, M_MEM_VAL, M_MEM_BITS);
1367 udelay(50);
1368
1369 /* Finish memory */
1370 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1371 val |= S_LOAD_MEM;
1372 udelay(50);
1373 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1374 udelay(50);
1375 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1376 val &= ~S_LOAD_MEM;
1377 udelay(50);
1378 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1379
1380 spin_unlock(&adapter->tpi_lock);
1381
1382 return 0;
1383}
1384
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001385static inline void t1_sw_reset(struct pci_dev *pdev)
1386{
1387 pci_write_config_dword(pdev, A_PCICFG_PM_CSR, 3);
1388 pci_write_config_dword(pdev, A_PCICFG_PM_CSR, 0);
1389}
1390
1391static void __devexit remove_one(struct pci_dev *pdev)
1392{
1393 struct net_device *dev = pci_get_drvdata(pdev);
1394
1395 if (dev) {
1396 int i;
1397 struct adapter *adapter = dev->priv;
1398
1399 for_each_port(adapter, i)
1400 if (test_bit(i, &adapter->registered_device_map))
1401 unregister_netdev(adapter->port[i].dev);
1402
1403 t1_free_sw_modules(adapter);
1404 iounmap(adapter->regs);
1405 while (--i >= 0)
Stephen Hemmingere4876472006-11-17 11:25:23 -08001406 if (adapter->port[i].dev)
1407 free_netdev(adapter->port[i].dev);
1408
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001409 pci_release_regions(pdev);
1410 pci_disable_device(pdev);
1411 pci_set_drvdata(pdev, NULL);
1412 t1_sw_reset(pdev);
1413 }
1414}
1415
1416static struct pci_driver driver = {
Scott Bardone559fb512005-06-23 01:40:19 -04001417 .name = DRV_NAME,
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001418 .id_table = t1_pci_tbl,
1419 .probe = init_one,
1420 .remove = __devexit_p(remove_one),
1421};
1422
1423static int __init t1_init_module(void)
1424{
Jeff Garzik29917622006-08-19 17:48:59 -04001425 return pci_register_driver(&driver);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001426}
1427
1428static void __exit t1_cleanup_module(void)
1429{
1430 pci_unregister_driver(&driver);
1431}
1432
1433module_init(t1_init_module);
1434module_exit(t1_cleanup_module);