blob: 5f82c9c349780aaee490c0b6028f7fd112aa3534 [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{
Wang Chenc3ccc122008-11-16 23:06:39 -0800123 struct adapter *adapter = dev->ml_priv;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800124 struct cmac *mac = adapter->port[dev->if_port].mac;
125 struct t1_rx_mode rm;
126
127 rm.dev = dev;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800128 mac->ops->set_rx_mode(mac, &rm);
129}
130
131static void link_report(struct port_info *p)
132{
133 if (!netif_carrier_ok(p->dev))
Stephen Hemminger20578152006-11-17 11:21:22 -0800134 printk(KERN_INFO "%s: link down\n", p->dev->name);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800135 else {
Scott Bardone559fb512005-06-23 01:40:19 -0400136 const char *s = "10Mbps";
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800137
138 switch (p->link_config.speed) {
Scott Bardone559fb512005-06-23 01:40:19 -0400139 case SPEED_10000: s = "10Gbps"; break;
140 case SPEED_1000: s = "1000Mbps"; break;
141 case SPEED_100: s = "100Mbps"; break;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800142 }
143
Francois Romieu356bd142006-12-11 23:47:00 +0100144 printk(KERN_INFO "%s: link up, %s, %s-duplex\n",
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800145 p->dev->name, s,
146 p->link_config.duplex == DUPLEX_FULL ? "full" : "half");
147 }
148}
149
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800150void t1_link_negotiated(struct adapter *adapter, int port_id, int link_stat,
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800151 int speed, int duplex, int pause)
152{
153 struct port_info *p = &adapter->port[port_id];
154
155 if (link_stat != netif_carrier_ok(p->dev)) {
156 if (link_stat)
157 netif_carrier_on(p->dev);
158 else
159 netif_carrier_off(p->dev);
160 link_report(p);
161
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800162 /* multi-ports: inform toe */
163 if ((speed > 0) && (adapter->params.nports > 1)) {
164 unsigned int sched_speed = 10;
165 switch (speed) {
166 case SPEED_1000:
167 sched_speed = 1000;
168 break;
169 case SPEED_100:
170 sched_speed = 100;
171 break;
172 case SPEED_10:
173 sched_speed = 10;
174 break;
175 }
176 t1_sched_update_parms(adapter->sge, port_id, 0, sched_speed);
177 }
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800178 }
179}
180
181static void link_start(struct port_info *p)
182{
183 struct cmac *mac = p->mac;
184
185 mac->ops->reset(mac);
186 if (mac->ops->macaddress_set)
187 mac->ops->macaddress_set(mac, p->dev->dev_addr);
188 t1_set_rxmode(p->dev);
189 t1_link_start(p->phy, mac, &p->link_config);
190 mac->ops->enable(mac, MAC_DIRECTION_RX | MAC_DIRECTION_TX);
191}
192
193static void enable_hw_csum(struct adapter *adapter)
194{
Michał Mirosław30f554f2011-04-18 13:31:20 +0000195 if (adapter->port[0].dev->hw_features & NETIF_F_TSO)
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800196 t1_tp_set_ip_checksum_offload(adapter->tp, 1); /* for TSO only */
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800197 t1_tp_set_tcp_checksum_offload(adapter->tp, 1);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800198}
199
200/*
201 * Things to do upon first use of a card.
202 * This must run with the rtnl lock held.
203 */
204static int cxgb_up(struct adapter *adapter)
205{
206 int err = 0;
207
208 if (!(adapter->flags & FULL_INIT_DONE)) {
209 err = t1_init_hw_modules(adapter);
210 if (err)
211 goto out_err;
212
213 enable_hw_csum(adapter);
214 adapter->flags |= FULL_INIT_DONE;
215 }
216
217 t1_interrupts_clear(adapter);
Stephen Hemminger325dde42006-12-01 16:36:20 -0800218
Stephen Hemminger7fe26a62006-12-08 11:08:33 -0800219 adapter->params.has_msi = !disable_msi && !pci_enable_msi(adapter->pdev);
220 err = request_irq(adapter->pdev->irq, t1_interrupt,
Stephen Hemminger325dde42006-12-01 16:36:20 -0800221 adapter->params.has_msi ? 0 : IRQF_SHARED,
222 adapter->name, adapter);
223 if (err) {
224 if (adapter->params.has_msi)
225 pci_disable_msi(adapter->pdev);
226
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800227 goto out_err;
Scott Bardone559fb512005-06-23 01:40:19 -0400228 }
Stephen Hemminger325dde42006-12-01 16:36:20 -0800229
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800230 t1_sge_start(adapter->sge);
231 t1_interrupts_enable(adapter);
Francois Romieu356bd142006-12-11 23:47:00 +0100232out_err:
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800233 return err;
234}
235
236/*
237 * Release resources when all the ports have been stopped.
238 */
239static void cxgb_down(struct adapter *adapter)
240{
241 t1_sge_stop(adapter->sge);
242 t1_interrupts_disable(adapter);
243 free_irq(adapter->pdev->irq, adapter);
Stephen Hemminger325dde42006-12-01 16:36:20 -0800244 if (adapter->params.has_msi)
245 pci_disable_msi(adapter->pdev);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800246}
247
248static int cxgb_open(struct net_device *dev)
249{
250 int err;
Wang Chenc3ccc122008-11-16 23:06:39 -0800251 struct adapter *adapter = dev->ml_priv;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800252 int other_ports = adapter->open_device_map & PORT_MASK;
253
Stephen Hemmingerbea33482007-10-03 16:41:36 -0700254 napi_enable(&adapter->napi);
255 if (!adapter->open_device_map && (err = cxgb_up(adapter)) < 0) {
256 napi_disable(&adapter->napi);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800257 return err;
Stephen Hemmingerbea33482007-10-03 16:41:36 -0700258 }
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800259
260 __set_bit(dev->if_port, &adapter->open_device_map);
261 link_start(&adapter->port[dev->if_port]);
262 netif_start_queue(dev);
263 if (!other_ports && adapter->params.stats_update_period)
264 schedule_mac_stats_update(adapter,
265 adapter->params.stats_update_period);
266 return 0;
267}
268
269static int cxgb_close(struct net_device *dev)
270{
Wang Chenc3ccc122008-11-16 23:06:39 -0800271 struct adapter *adapter = dev->ml_priv;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800272 struct port_info *p = &adapter->port[dev->if_port];
273 struct cmac *mac = p->mac;
274
275 netif_stop_queue(dev);
Stephen Hemmingerbea33482007-10-03 16:41:36 -0700276 napi_disable(&adapter->napi);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800277 mac->ops->disable(mac, MAC_DIRECTION_TX | MAC_DIRECTION_RX);
278 netif_carrier_off(dev);
279
280 clear_bit(dev->if_port, &adapter->open_device_map);
281 if (adapter->params.stats_update_period &&
282 !(adapter->open_device_map & PORT_MASK)) {
283 /* Stop statistics accumulation. */
284 smp_mb__after_clear_bit();
285 spin_lock(&adapter->work_lock); /* sync with update task */
286 spin_unlock(&adapter->work_lock);
287 cancel_mac_stats_update(adapter);
288 }
289
290 if (!adapter->open_device_map)
291 cxgb_down(adapter);
292 return 0;
293}
294
295static struct net_device_stats *t1_get_stats(struct net_device *dev)
296{
Wang Chenc3ccc122008-11-16 23:06:39 -0800297 struct adapter *adapter = dev->ml_priv;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800298 struct port_info *p = &adapter->port[dev->if_port];
299 struct net_device_stats *ns = &p->netstats;
300 const struct cmac_statistics *pstats;
301
302 /* Do a full update of the MAC stats */
303 pstats = p->mac->ops->statistics_update(p->mac,
Stephen Hemminger20578152006-11-17 11:21:22 -0800304 MAC_STATS_UPDATE_FULL);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800305
306 ns->tx_packets = pstats->TxUnicastFramesOK +
307 pstats->TxMulticastFramesOK + pstats->TxBroadcastFramesOK;
308
309 ns->rx_packets = pstats->RxUnicastFramesOK +
310 pstats->RxMulticastFramesOK + pstats->RxBroadcastFramesOK;
311
312 ns->tx_bytes = pstats->TxOctetsOK;
313 ns->rx_bytes = pstats->RxOctetsOK;
314
315 ns->tx_errors = pstats->TxLateCollisions + pstats->TxLengthErrors +
316 pstats->TxUnderrun + pstats->TxFramesAbortedDueToXSCollisions;
317 ns->rx_errors = pstats->RxDataErrors + pstats->RxJabberErrors +
318 pstats->RxFCSErrors + pstats->RxAlignErrors +
319 pstats->RxSequenceErrors + pstats->RxFrameTooLongErrors +
320 pstats->RxSymbolErrors + pstats->RxRuntErrors;
321
322 ns->multicast = pstats->RxMulticastFramesOK;
323 ns->collisions = pstats->TxTotalCollisions;
324
325 /* detailed rx_errors */
326 ns->rx_length_errors = pstats->RxFrameTooLongErrors +
327 pstats->RxJabberErrors;
328 ns->rx_over_errors = 0;
329 ns->rx_crc_errors = pstats->RxFCSErrors;
330 ns->rx_frame_errors = pstats->RxAlignErrors;
331 ns->rx_fifo_errors = 0;
332 ns->rx_missed_errors = 0;
333
334 /* detailed tx_errors */
335 ns->tx_aborted_errors = pstats->TxFramesAbortedDueToXSCollisions;
336 ns->tx_carrier_errors = 0;
337 ns->tx_fifo_errors = pstats->TxUnderrun;
338 ns->tx_heartbeat_errors = 0;
339 ns->tx_window_errors = pstats->TxLateCollisions;
340 return ns;
341}
342
343static u32 get_msglevel(struct net_device *dev)
344{
Wang Chenc3ccc122008-11-16 23:06:39 -0800345 struct adapter *adapter = dev->ml_priv;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800346
347 return adapter->msg_enable;
348}
349
350static void set_msglevel(struct net_device *dev, u32 val)
351{
Wang Chenc3ccc122008-11-16 23:06:39 -0800352 struct adapter *adapter = dev->ml_priv;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800353
354 adapter->msg_enable = val;
355}
356
357static char stats_strings[][ETH_GSTRING_LEN] = {
Stephen Hemminger20578152006-11-17 11:21:22 -0800358 "TxOctetsOK",
359 "TxOctetsBad",
360 "TxUnicastFramesOK",
361 "TxMulticastFramesOK",
362 "TxBroadcastFramesOK",
363 "TxPauseFrames",
364 "TxFramesWithDeferredXmissions",
365 "TxLateCollisions",
366 "TxTotalCollisions",
367 "TxFramesAbortedDueToXSCollisions",
368 "TxUnderrun",
369 "TxLengthErrors",
370 "TxInternalMACXmitError",
371 "TxFramesWithExcessiveDeferral",
372 "TxFCSErrors",
Divy Le Raye0348b92007-11-27 13:30:20 -0800373 "TxJumboFramesOk",
374 "TxJumboOctetsOk",
375
Stephen Hemminger20578152006-11-17 11:21:22 -0800376 "RxOctetsOK",
377 "RxOctetsBad",
378 "RxUnicastFramesOK",
379 "RxMulticastFramesOK",
380 "RxBroadcastFramesOK",
381 "RxPauseFrames",
382 "RxFCSErrors",
383 "RxAlignErrors",
384 "RxSymbolErrors",
385 "RxDataErrors",
386 "RxSequenceErrors",
387 "RxRuntErrors",
388 "RxJabberErrors",
389 "RxInternalMACRcvError",
390 "RxInRangeLengthErrors",
391 "RxOutOfRangeLengthField",
392 "RxFrameTooLongErrors",
Divy Le Raye0348b92007-11-27 13:30:20 -0800393 "RxJumboFramesOk",
394 "RxJumboOctetsOk",
Scott Bardone559fb512005-06-23 01:40:19 -0400395
Stephen Hemminger56f643c2006-12-01 16:36:21 -0800396 /* Port stats */
Scott Bardone559fb512005-06-23 01:40:19 -0400397 "RxCsumGood",
398 "TxCsumOffload",
Stephen Hemminger56f643c2006-12-01 16:36:21 -0800399 "TxTso",
400 "RxVlan",
401 "TxVlan",
Divy Le Ray7832ee02007-11-27 13:30:09 -0800402 "TxNeedHeadroom",
403
Stephen Hemminger56f643c2006-12-01 16:36:21 -0800404 /* Interrupt stats */
405 "rx drops",
406 "pure_rsps",
407 "unhandled irqs",
Scott Bardone559fb512005-06-23 01:40:19 -0400408 "respQ_empty",
409 "respQ_overflow",
410 "freelistQ_empty",
411 "pkt_too_big",
412 "pkt_mismatch",
413 "cmdQ_full0",
414 "cmdQ_full1",
Stephen Hemminger20578152006-11-17 11:21:22 -0800415
Scott Bardone559fb512005-06-23 01:40:19 -0400416 "espi_DIP2ParityErr",
417 "espi_DIP4Err",
418 "espi_RxDrops",
419 "espi_TxDrops",
420 "espi_RxOvfl",
421 "espi_ParityErr"
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800422};
Stephen Hemminger20578152006-11-17 11:21:22 -0800423
Scott Bardone559fb512005-06-23 01:40:19 -0400424#define T2_REGMAP_SIZE (3 * 1024)
425
426static int get_regs_len(struct net_device *dev)
427{
428 return T2_REGMAP_SIZE;
429}
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800430
431static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
432{
Wang Chenc3ccc122008-11-16 23:06:39 -0800433 struct adapter *adapter = dev->ml_priv;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800434
Scott Bardone559fb512005-06-23 01:40:19 -0400435 strcpy(info->driver, DRV_NAME);
436 strcpy(info->version, DRV_VERSION);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800437 strcpy(info->fw_version, "N/A");
438 strcpy(info->bus_info, pci_name(adapter->pdev));
439}
440
Jeff Garzikb9f2c042007-10-03 18:07:32 -0700441static int get_sset_count(struct net_device *dev, int sset)
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800442{
Jeff Garzikb9f2c042007-10-03 18:07:32 -0700443 switch (sset) {
444 case ETH_SS_STATS:
445 return ARRAY_SIZE(stats_strings);
446 default:
447 return -EOPNOTSUPP;
448 }
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800449}
450
451static void get_strings(struct net_device *dev, u32 stringset, u8 *data)
452{
453 if (stringset == ETH_SS_STATS)
454 memcpy(data, stats_strings, sizeof(stats_strings));
455}
456
457static void get_stats(struct net_device *dev, struct ethtool_stats *stats,
458 u64 *data)
459{
Wang Chenc3ccc122008-11-16 23:06:39 -0800460 struct adapter *adapter = dev->ml_priv;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800461 struct cmac *mac = adapter->port[dev->if_port].mac;
462 const struct cmac_statistics *s;
Scott Bardone559fb512005-06-23 01:40:19 -0400463 const struct sge_intr_counts *t;
Stephen Hemminger56f643c2006-12-01 16:36:21 -0800464 struct sge_port_stats ss;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800465
466 s = mac->ops->statistics_update(mac, MAC_STATS_UPDATE_FULL);
Scott Bardone559fb512005-06-23 01:40:19 -0400467 t = t1_sge_get_intr_counts(adapter->sge);
Divy Le Raye0348b92007-11-27 13:30:20 -0800468 t1_sge_get_port_stats(adapter->sge, dev->if_port, &ss);
469
470 *data++ = s->TxOctetsOK;
471 *data++ = s->TxOctetsBad;
472 *data++ = s->TxUnicastFramesOK;
473 *data++ = s->TxMulticastFramesOK;
474 *data++ = s->TxBroadcastFramesOK;
475 *data++ = s->TxPauseFrames;
476 *data++ = s->TxFramesWithDeferredXmissions;
477 *data++ = s->TxLateCollisions;
478 *data++ = s->TxTotalCollisions;
479 *data++ = s->TxFramesAbortedDueToXSCollisions;
480 *data++ = s->TxUnderrun;
481 *data++ = s->TxLengthErrors;
482 *data++ = s->TxInternalMACXmitError;
483 *data++ = s->TxFramesWithExcessiveDeferral;
484 *data++ = s->TxFCSErrors;
485 *data++ = s->TxJumboFramesOK;
486 *data++ = s->TxJumboOctetsOK;
487
488 *data++ = s->RxOctetsOK;
489 *data++ = s->RxOctetsBad;
490 *data++ = s->RxUnicastFramesOK;
491 *data++ = s->RxMulticastFramesOK;
492 *data++ = s->RxBroadcastFramesOK;
493 *data++ = s->RxPauseFrames;
494 *data++ = s->RxFCSErrors;
495 *data++ = s->RxAlignErrors;
496 *data++ = s->RxSymbolErrors;
497 *data++ = s->RxDataErrors;
498 *data++ = s->RxSequenceErrors;
499 *data++ = s->RxRuntErrors;
500 *data++ = s->RxJabberErrors;
501 *data++ = s->RxInternalMACRcvError;
502 *data++ = s->RxInRangeLengthErrors;
503 *data++ = s->RxOutOfRangeLengthField;
504 *data++ = s->RxFrameTooLongErrors;
505 *data++ = s->RxJumboFramesOK;
506 *data++ = s->RxJumboOctetsOK;
507
508 *data++ = ss.rx_cso_good;
509 *data++ = ss.tx_cso;
510 *data++ = ss.tx_tso;
511 *data++ = ss.vlan_xtract;
512 *data++ = ss.vlan_insert;
513 *data++ = ss.tx_need_hdrroom;
514
Stephen Hemminger56f643c2006-12-01 16:36:21 -0800515 *data++ = t->rx_drops;
516 *data++ = t->pure_rsps;
517 *data++ = t->unhandled_irqs;
518 *data++ = t->respQ_empty;
519 *data++ = t->respQ_overflow;
520 *data++ = t->freelistQ_empty;
521 *data++ = t->pkt_too_big;
522 *data++ = t->pkt_mismatch;
523 *data++ = t->cmdQ_full[0];
524 *data++ = t->cmdQ_full[1];
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800525
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800526 if (adapter->espi) {
527 const struct espi_intr_counts *e;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800528
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800529 e = t1_espi_get_intr_counts(adapter->espi);
Stephen Hemminger56f643c2006-12-01 16:36:21 -0800530 *data++ = e->DIP2_parity_err;
531 *data++ = e->DIP4_err;
532 *data++ = e->rx_drops;
533 *data++ = e->tx_drops;
534 *data++ = e->rx_ovflw;
535 *data++ = e->parity_err;
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800536 }
Scott Bardone559fb512005-06-23 01:40:19 -0400537}
538
539static inline void reg_block_dump(struct adapter *ap, void *buf,
540 unsigned int start, unsigned int end)
541{
542 u32 *p = buf + start;
543
544 for ( ; start <= end; start += sizeof(u32))
545 *p++ = readl(ap->regs + start);
546}
547
548static void get_regs(struct net_device *dev, struct ethtool_regs *regs,
549 void *buf)
550{
Wang Chenc3ccc122008-11-16 23:06:39 -0800551 struct adapter *ap = dev->ml_priv;
Scott Bardone559fb512005-06-23 01:40:19 -0400552
553 /*
554 * Version scheme: bits 0..9: chip version, bits 10..15: chip revision
555 */
556 regs->version = 2;
557
558 memset(buf, 0, T2_REGMAP_SIZE);
559 reg_block_dump(ap, buf, 0, A_SG_RESPACCUTIMER);
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800560 reg_block_dump(ap, buf, A_MC3_CFG, A_MC4_INT_CAUSE);
561 reg_block_dump(ap, buf, A_TPI_ADDR, A_TPI_PAR);
562 reg_block_dump(ap, buf, A_TP_IN_CONFIG, A_TP_TX_DROP_COUNT);
563 reg_block_dump(ap, buf, A_RAT_ROUTE_CONTROL, A_RAT_INTR_CAUSE);
564 reg_block_dump(ap, buf, A_CSPI_RX_AE_WM, A_CSPI_INTR_ENABLE);
565 reg_block_dump(ap, buf, A_ESPI_SCH_TOKEN0, A_ESPI_GOSTAT);
566 reg_block_dump(ap, buf, A_ULP_ULIMIT, A_ULP_PIO_CTRL);
567 reg_block_dump(ap, buf, A_PL_ENABLE, A_PL_CAUSE);
568 reg_block_dump(ap, buf, A_MC5_CONFIG, A_MC5_MASK_WRITE_CMD);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800569}
570
571static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
572{
Wang Chenc3ccc122008-11-16 23:06:39 -0800573 struct adapter *adapter = dev->ml_priv;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800574 struct port_info *p = &adapter->port[dev->if_port];
575
576 cmd->supported = p->link_config.supported;
577 cmd->advertising = p->link_config.advertising;
578
579 if (netif_carrier_ok(dev)) {
580 cmd->speed = p->link_config.speed;
581 cmd->duplex = p->link_config.duplex;
582 } else {
583 cmd->speed = -1;
584 cmd->duplex = -1;
585 }
586
Stephen Hemminger20578152006-11-17 11:21:22 -0800587 cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE;
Ben Hutchings23c33202009-04-29 08:06:34 +0000588 cmd->phy_address = p->phy->mdio.prtad;
Stephen Hemminger20578152006-11-17 11:21:22 -0800589 cmd->transceiver = XCVR_EXTERNAL;
590 cmd->autoneg = p->link_config.autoneg;
591 cmd->maxtxpkt = 0;
592 cmd->maxrxpkt = 0;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800593 return 0;
594}
595
596static int speed_duplex_to_caps(int speed, int duplex)
597{
598 int cap = 0;
599
600 switch (speed) {
601 case SPEED_10:
602 if (duplex == DUPLEX_FULL)
603 cap = SUPPORTED_10baseT_Full;
604 else
605 cap = SUPPORTED_10baseT_Half;
606 break;
607 case SPEED_100:
608 if (duplex == DUPLEX_FULL)
609 cap = SUPPORTED_100baseT_Full;
610 else
611 cap = SUPPORTED_100baseT_Half;
612 break;
613 case SPEED_1000:
614 if (duplex == DUPLEX_FULL)
615 cap = SUPPORTED_1000baseT_Full;
616 else
617 cap = SUPPORTED_1000baseT_Half;
618 break;
619 case SPEED_10000:
620 if (duplex == DUPLEX_FULL)
621 cap = SUPPORTED_10000baseT_Full;
622 }
623 return cap;
624}
625
626#define ADVERTISED_MASK (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | \
627 ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | \
628 ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full | \
629 ADVERTISED_10000baseT_Full)
630
631static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
632{
Wang Chenc3ccc122008-11-16 23:06:39 -0800633 struct adapter *adapter = dev->ml_priv;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800634 struct port_info *p = &adapter->port[dev->if_port];
635 struct link_config *lc = &p->link_config;
636
637 if (!(lc->supported & SUPPORTED_Autoneg))
Scott Bardone559fb512005-06-23 01:40:19 -0400638 return -EOPNOTSUPP; /* can't change speed/duplex */
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800639
640 if (cmd->autoneg == AUTONEG_DISABLE) {
641 int cap = speed_duplex_to_caps(cmd->speed, cmd->duplex);
642
643 if (!(lc->supported & cap) || cmd->speed == SPEED_1000)
644 return -EINVAL;
645 lc->requested_speed = cmd->speed;
646 lc->requested_duplex = cmd->duplex;
647 lc->advertising = 0;
648 } else {
649 cmd->advertising &= ADVERTISED_MASK;
650 if (cmd->advertising & (cmd->advertising - 1))
651 cmd->advertising = lc->supported;
652 cmd->advertising &= lc->supported;
653 if (!cmd->advertising)
654 return -EINVAL;
655 lc->requested_speed = SPEED_INVALID;
656 lc->requested_duplex = DUPLEX_INVALID;
657 lc->advertising = cmd->advertising | ADVERTISED_Autoneg;
658 }
659 lc->autoneg = cmd->autoneg;
660 if (netif_running(dev))
661 t1_link_start(p->phy, p->mac, lc);
662 return 0;
663}
664
665static void get_pauseparam(struct net_device *dev,
666 struct ethtool_pauseparam *epause)
667{
Wang Chenc3ccc122008-11-16 23:06:39 -0800668 struct adapter *adapter = dev->ml_priv;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800669 struct port_info *p = &adapter->port[dev->if_port];
670
671 epause->autoneg = (p->link_config.requested_fc & PAUSE_AUTONEG) != 0;
672 epause->rx_pause = (p->link_config.fc & PAUSE_RX) != 0;
673 epause->tx_pause = (p->link_config.fc & PAUSE_TX) != 0;
674}
675
676static int set_pauseparam(struct net_device *dev,
677 struct ethtool_pauseparam *epause)
678{
Wang Chenc3ccc122008-11-16 23:06:39 -0800679 struct adapter *adapter = dev->ml_priv;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800680 struct port_info *p = &adapter->port[dev->if_port];
681 struct link_config *lc = &p->link_config;
682
683 if (epause->autoneg == AUTONEG_DISABLE)
684 lc->requested_fc = 0;
685 else if (lc->supported & SUPPORTED_Autoneg)
686 lc->requested_fc = PAUSE_AUTONEG;
687 else
688 return -EINVAL;
689
690 if (epause->rx_pause)
691 lc->requested_fc |= PAUSE_RX;
692 if (epause->tx_pause)
693 lc->requested_fc |= PAUSE_TX;
694 if (lc->autoneg == AUTONEG_ENABLE) {
695 if (netif_running(dev))
696 t1_link_start(p->phy, p->mac, lc);
697 } else {
698 lc->fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX);
699 if (netif_running(dev))
700 p->mac->ops->set_speed_duplex_fc(p->mac, -1, -1,
701 lc->fc);
702 }
703 return 0;
704}
705
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800706static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
707{
Wang Chenc3ccc122008-11-16 23:06:39 -0800708 struct adapter *adapter = dev->ml_priv;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800709 int jumbo_fl = t1_is_T1B(adapter) ? 1 : 0;
710
711 e->rx_max_pending = MAX_RX_BUFFERS;
712 e->rx_mini_max_pending = 0;
713 e->rx_jumbo_max_pending = MAX_RX_JUMBO_BUFFERS;
714 e->tx_max_pending = MAX_CMDQ_ENTRIES;
715
716 e->rx_pending = adapter->params.sge.freelQ_size[!jumbo_fl];
717 e->rx_mini_pending = 0;
718 e->rx_jumbo_pending = adapter->params.sge.freelQ_size[jumbo_fl];
719 e->tx_pending = adapter->params.sge.cmdQ_size[0];
720}
721
722static int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
723{
Wang Chenc3ccc122008-11-16 23:06:39 -0800724 struct adapter *adapter = dev->ml_priv;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800725 int jumbo_fl = t1_is_T1B(adapter) ? 1 : 0;
726
727 if (e->rx_pending > MAX_RX_BUFFERS || e->rx_mini_pending ||
728 e->rx_jumbo_pending > MAX_RX_JUMBO_BUFFERS ||
729 e->tx_pending > MAX_CMDQ_ENTRIES ||
730 e->rx_pending < MIN_FL_ENTRIES ||
731 e->rx_jumbo_pending < MIN_FL_ENTRIES ||
732 e->tx_pending < (adapter->params.nports + 1) * (MAX_SKB_FRAGS + 1))
733 return -EINVAL;
734
735 if (adapter->flags & FULL_INIT_DONE)
Francois Romieu356bd142006-12-11 23:47:00 +0100736 return -EBUSY;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800737
738 adapter->params.sge.freelQ_size[!jumbo_fl] = e->rx_pending;
739 adapter->params.sge.freelQ_size[jumbo_fl] = e->rx_jumbo_pending;
740 adapter->params.sge.cmdQ_size[0] = e->tx_pending;
741 adapter->params.sge.cmdQ_size[1] = e->tx_pending > MAX_CMDQ1_ENTRIES ?
742 MAX_CMDQ1_ENTRIES : e->tx_pending;
743 return 0;
744}
745
746static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
747{
Wang Chenc3ccc122008-11-16 23:06:39 -0800748 struct adapter *adapter = dev->ml_priv;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800749
Stephen Hemminger7fe26a62006-12-08 11:08:33 -0800750 adapter->params.sge.rx_coalesce_usecs = c->rx_coalesce_usecs;
Francois Romieu356bd142006-12-11 23:47:00 +0100751 adapter->params.sge.coalesce_enable = c->use_adaptive_rx_coalesce;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800752 adapter->params.sge.sample_interval_usecs = c->rate_sample_interval;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800753 t1_sge_set_coalesce_params(adapter->sge, &adapter->params.sge);
754 return 0;
755}
756
757static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
758{
Wang Chenc3ccc122008-11-16 23:06:39 -0800759 struct adapter *adapter = dev->ml_priv;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800760
Scott Bardone559fb512005-06-23 01:40:19 -0400761 c->rx_coalesce_usecs = adapter->params.sge.rx_coalesce_usecs;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800762 c->rate_sample_interval = adapter->params.sge.sample_interval_usecs;
763 c->use_adaptive_rx_coalesce = adapter->params.sge.coalesce_enable;
764 return 0;
765}
766
767static int get_eeprom_len(struct net_device *dev)
768{
Wang Chenc3ccc122008-11-16 23:06:39 -0800769 struct adapter *adapter = dev->ml_priv;
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800770
Francois Romieu356bd142006-12-11 23:47:00 +0100771 return t1_is_asic(adapter) ? EEPROM_SIZE : 0;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800772}
773
774#define EEPROM_MAGIC(ap) \
775 (PCI_VENDOR_ID_CHELSIO | ((ap)->params.chip_version << 16))
776
777static int get_eeprom(struct net_device *dev, struct ethtool_eeprom *e,
778 u8 *data)
779{
780 int i;
781 u8 buf[EEPROM_SIZE] __attribute__((aligned(4)));
Wang Chenc3ccc122008-11-16 23:06:39 -0800782 struct adapter *adapter = dev->ml_priv;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800783
784 e->magic = EEPROM_MAGIC(adapter);
785 for (i = e->offset & ~3; i < e->offset + e->len; i += sizeof(u32))
Al Viroac390c602007-12-22 18:56:33 +0000786 t1_seeprom_read(adapter, i, (__le32 *)&buf[i]);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800787 memcpy(data, buf + e->offset, e->len);
788 return 0;
789}
790
Jeff Garzik7282d492006-09-13 14:30:00 -0400791static const struct ethtool_ops t1_ethtool_ops = {
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800792 .get_settings = get_settings,
793 .set_settings = set_settings,
794 .get_drvinfo = get_drvinfo,
795 .get_msglevel = get_msglevel,
796 .set_msglevel = set_msglevel,
797 .get_ringparam = get_sge_param,
798 .set_ringparam = set_sge_param,
799 .get_coalesce = get_coalesce,
800 .set_coalesce = set_coalesce,
801 .get_eeprom_len = get_eeprom_len,
802 .get_eeprom = get_eeprom,
803 .get_pauseparam = get_pauseparam,
804 .set_pauseparam = set_pauseparam,
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800805 .get_link = ethtool_op_get_link,
806 .get_strings = get_strings,
Jeff Garzikb9f2c042007-10-03 18:07:32 -0700807 .get_sset_count = get_sset_count,
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800808 .get_ethtool_stats = get_stats,
Scott Bardone559fb512005-06-23 01:40:19 -0400809 .get_regs_len = get_regs_len,
810 .get_regs = get_regs,
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800811};
812
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800813static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
814{
Wang Chenc3ccc122008-11-16 23:06:39 -0800815 struct adapter *adapter = dev->ml_priv;
Ben Hutchings23c33202009-04-29 08:06:34 +0000816 struct mdio_if_info *mdio = &adapter->port[dev->if_port].phy->mdio;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800817
Ben Hutchings23c33202009-04-29 08:06:34 +0000818 return mdio_mii_ioctl(mdio, if_mii(req), cmd);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800819}
820
821static int t1_change_mtu(struct net_device *dev, int new_mtu)
822{
823 int ret;
Wang Chenc3ccc122008-11-16 23:06:39 -0800824 struct adapter *adapter = dev->ml_priv;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800825 struct cmac *mac = adapter->port[dev->if_port].mac;
826
827 if (!mac->ops->set_mtu)
Francois Romieu356bd142006-12-11 23:47:00 +0100828 return -EOPNOTSUPP;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800829 if (new_mtu < 68)
Francois Romieu356bd142006-12-11 23:47:00 +0100830 return -EINVAL;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800831 if ((ret = mac->ops->set_mtu(mac, new_mtu)))
832 return ret;
833 dev->mtu = new_mtu;
834 return 0;
835}
836
837static int t1_set_mac_addr(struct net_device *dev, void *p)
838{
Wang Chenc3ccc122008-11-16 23:06:39 -0800839 struct adapter *adapter = dev->ml_priv;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800840 struct cmac *mac = adapter->port[dev->if_port].mac;
841 struct sockaddr *addr = p;
842
843 if (!mac->ops->macaddress_set)
844 return -EOPNOTSUPP;
845
846 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
847 mac->ops->macaddress_set(mac, dev->dev_addr);
848 return 0;
849}
850
851#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
Stephen Hemminger00829822008-11-20 20:14:53 -0800852static void t1_vlan_rx_register(struct net_device *dev,
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800853 struct vlan_group *grp)
854{
Wang Chenc3ccc122008-11-16 23:06:39 -0800855 struct adapter *adapter = dev->ml_priv;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800856
857 spin_lock_irq(&adapter->async_lock);
858 adapter->vlan_grp = grp;
859 t1_set_vlan_accel(adapter, grp != NULL);
860 spin_unlock_irq(&adapter->async_lock);
861}
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800862#endif
863
864#ifdef CONFIG_NET_POLL_CONTROLLER
865static void t1_netpoll(struct net_device *dev)
866{
Scott Bardone559fb512005-06-23 01:40:19 -0400867 unsigned long flags;
Wang Chenc3ccc122008-11-16 23:06:39 -0800868 struct adapter *adapter = dev->ml_priv;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800869
Scott Bardone559fb512005-06-23 01:40:19 -0400870 local_irq_save(flags);
Stephen Hemminger7fe26a62006-12-08 11:08:33 -0800871 t1_interrupt(adapter->pdev->irq, adapter);
Scott Bardone559fb512005-06-23 01:40:19 -0400872 local_irq_restore(flags);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800873}
874#endif
875
876/*
877 * Periodic accumulation of MAC statistics. This is used only if the MAC
878 * does not have any other way to prevent stats counter overflow.
879 */
David Howellsc4028952006-11-22 14:57:56 +0000880static void mac_stats_task(struct work_struct *work)
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800881{
882 int i;
David Howellsc4028952006-11-22 14:57:56 +0000883 struct adapter *adapter =
884 container_of(work, struct adapter, stats_update_task.work);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800885
886 for_each_port(adapter, i) {
887 struct port_info *p = &adapter->port[i];
888
889 if (netif_running(p->dev))
890 p->mac->ops->statistics_update(p->mac,
891 MAC_STATS_UPDATE_FAST);
892 }
893
894 /* Schedule the next statistics update if any port is active. */
895 spin_lock(&adapter->work_lock);
896 if (adapter->open_device_map & PORT_MASK)
897 schedule_mac_stats_update(adapter,
898 adapter->params.stats_update_period);
899 spin_unlock(&adapter->work_lock);
900}
901
902/*
903 * Processes elmer0 external interrupts in process context.
904 */
David Howellsc4028952006-11-22 14:57:56 +0000905static void ext_intr_task(struct work_struct *work)
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800906{
David Howellsc4028952006-11-22 14:57:56 +0000907 struct adapter *adapter =
908 container_of(work, struct adapter, ext_intr_handler_task);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800909
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -0800910 t1_elmer0_ext_intr_handler(adapter);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800911
912 /* Now reenable external interrupts */
Scott Bardone559fb512005-06-23 01:40:19 -0400913 spin_lock_irq(&adapter->async_lock);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800914 adapter->slow_intr_mask |= F_PL_INTR_EXT;
Scott Bardone559fb512005-06-23 01:40:19 -0400915 writel(F_PL_INTR_EXT, adapter->regs + A_PL_CAUSE);
916 writel(adapter->slow_intr_mask | F_PL_INTR_SGE_DATA,
Stephen Hemminger20578152006-11-17 11:21:22 -0800917 adapter->regs + A_PL_ENABLE);
Scott Bardone559fb512005-06-23 01:40:19 -0400918 spin_unlock_irq(&adapter->async_lock);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800919}
920
921/*
922 * Interrupt-context handler for elmer0 external interrupts.
923 */
924void t1_elmer0_ext_intr(struct adapter *adapter)
925{
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800926 /*
927 * Schedule a task to handle external interrupts as we require
928 * a process context. We disable EXT interrupts in the interim
929 * and let the task reenable them when it's done.
930 */
931 adapter->slow_intr_mask &= ~F_PL_INTR_EXT;
Scott Bardone559fb512005-06-23 01:40:19 -0400932 writel(adapter->slow_intr_mask | F_PL_INTR_SGE_DATA,
Stephen Hemminger20578152006-11-17 11:21:22 -0800933 adapter->regs + A_PL_ENABLE);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800934 schedule_work(&adapter->ext_intr_handler_task);
935}
936
937void t1_fatal_err(struct adapter *adapter)
938{
939 if (adapter->flags & FULL_INIT_DONE) {
940 t1_sge_stop(adapter->sge);
941 t1_interrupts_disable(adapter);
942 }
Joe Perchesc1f51212010-02-22 16:56:57 +0000943 pr_alert("%s: encountered fatal error, operation suspended\n",
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800944 adapter->name);
945}
946
Stephen Hemminger80ff32b2008-11-19 22:17:06 -0800947static const struct net_device_ops cxgb_netdev_ops = {
948 .ndo_open = cxgb_open,
949 .ndo_stop = cxgb_close,
Stephen Hemminger00829822008-11-20 20:14:53 -0800950 .ndo_start_xmit = t1_start_xmit,
Stephen Hemminger80ff32b2008-11-19 22:17:06 -0800951 .ndo_get_stats = t1_get_stats,
952 .ndo_validate_addr = eth_validate_addr,
953 .ndo_set_multicast_list = t1_set_rxmode,
954 .ndo_do_ioctl = t1_ioctl,
955 .ndo_change_mtu = t1_change_mtu,
956 .ndo_set_mac_address = t1_set_mac_addr,
957#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
Stephen Hemminger00829822008-11-20 20:14:53 -0800958 .ndo_vlan_rx_register = t1_vlan_rx_register,
Stephen Hemminger80ff32b2008-11-19 22:17:06 -0800959#endif
960#ifdef CONFIG_NET_POLL_CONTROLLER
961 .ndo_poll_controller = t1_netpoll,
962#endif
963};
964
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800965static int __devinit init_one(struct pci_dev *pdev,
966 const struct pci_device_id *ent)
967{
968 static int version_printed;
969
970 int i, err, pci_using_dac = 0;
971 unsigned long mmio_start, mmio_len;
972 const struct board_info *bi;
973 struct adapter *adapter = NULL;
974 struct port_info *pi;
975
976 if (!version_printed) {
Scott Bardone559fb512005-06-23 01:40:19 -0400977 printk(KERN_INFO "%s - version %s\n", DRV_DESCRIPTION,
978 DRV_VERSION);
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800979 ++version_printed;
980 }
981
982 err = pci_enable_device(pdev);
983 if (err)
Stephen Hemminger20578152006-11-17 11:21:22 -0800984 return err;
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800985
986 if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
Joe Perchesc1f51212010-02-22 16:56:57 +0000987 pr_err("%s: cannot find PCI device memory base address\n",
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800988 pci_name(pdev));
989 err = -ENODEV;
990 goto out_disable_pdev;
991 }
992
Yang Hongyang6a355282009-04-06 19:01:13 -0700993 if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800994 pci_using_dac = 1;
Scott Bardone559fb512005-06-23 01:40:19 -0400995
Yang Hongyang6a355282009-04-06 19:01:13 -0700996 if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64))) {
Joe Perchesc1f51212010-02-22 16:56:57 +0000997 pr_err("%s: unable to obtain 64-bit DMA for "
Christoph Lameter8199d3a2005-03-30 13:34:31 -0800998 "consistent allocations\n", pci_name(pdev));
999 err = -ENODEV;
1000 goto out_disable_pdev;
1001 }
Scott Bardone559fb512005-06-23 01:40:19 -04001002
Yang Hongyang284901a2009-04-06 19:01:15 -07001003 } else if ((err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) != 0) {
Joe Perchesc1f51212010-02-22 16:56:57 +00001004 pr_err("%s: no usable DMA configuration\n", pci_name(pdev));
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001005 goto out_disable_pdev;
1006 }
1007
Scott Bardone559fb512005-06-23 01:40:19 -04001008 err = pci_request_regions(pdev, DRV_NAME);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001009 if (err) {
Joe Perchesc1f51212010-02-22 16:56:57 +00001010 pr_err("%s: cannot obtain PCI resources\n", pci_name(pdev));
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001011 goto out_disable_pdev;
1012 }
1013
1014 pci_set_master(pdev);
1015
Stephen Hemminger20578152006-11-17 11:21:22 -08001016 mmio_start = pci_resource_start(pdev, 0);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001017 mmio_len = pci_resource_len(pdev, 0);
1018 bi = t1_get_board_info(ent->driver_data);
1019
1020 for (i = 0; i < bi->port_number; ++i) {
1021 struct net_device *netdev;
1022
1023 netdev = alloc_etherdev(adapter ? 0 : sizeof(*adapter));
1024 if (!netdev) {
1025 err = -ENOMEM;
1026 goto out_free_dev;
1027 }
1028
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001029 SET_NETDEV_DEV(netdev, &pdev->dev);
1030
1031 if (!adapter) {
Wang Chenc3ccc122008-11-16 23:06:39 -08001032 adapter = netdev_priv(netdev);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001033 adapter->pdev = pdev;
1034 adapter->port[0].dev = netdev; /* so we don't leak it */
1035
1036 adapter->regs = ioremap(mmio_start, mmio_len);
1037 if (!adapter->regs) {
Joe Perchesc1f51212010-02-22 16:56:57 +00001038 pr_err("%s: cannot map device registers\n",
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001039 pci_name(pdev));
1040 err = -ENOMEM;
1041 goto out_free_dev;
1042 }
1043
1044 if (t1_get_board_rev(adapter, bi, &adapter->params)) {
1045 err = -ENODEV; /* Can't handle this chip rev */
1046 goto out_free_dev;
1047 }
1048
1049 adapter->name = pci_name(pdev);
1050 adapter->msg_enable = dflt_msg_enable;
1051 adapter->mmio_len = mmio_len;
1052
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001053 spin_lock_init(&adapter->tpi_lock);
1054 spin_lock_init(&adapter->work_lock);
1055 spin_lock_init(&adapter->async_lock);
Stephen Hemminger352c4172006-12-01 16:36:17 -08001056 spin_lock_init(&adapter->mac_lock);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001057
1058 INIT_WORK(&adapter->ext_intr_handler_task,
David Howellsc4028952006-11-22 14:57:56 +00001059 ext_intr_task);
1060 INIT_DELAYED_WORK(&adapter->stats_update_task,
1061 mac_stats_task);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001062
1063 pci_set_drvdata(pdev, netdev);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001064 }
1065
1066 pi = &adapter->port[i];
1067 pi->dev = netdev;
1068 netif_carrier_off(netdev);
1069 netdev->irq = pdev->irq;
1070 netdev->if_port = i;
1071 netdev->mem_start = mmio_start;
1072 netdev->mem_end = mmio_start + mmio_len - 1;
Wang Chenc3ccc122008-11-16 23:06:39 -08001073 netdev->ml_priv = adapter;
Michał Mirosław30f554f2011-04-18 13:31:20 +00001074 netdev->hw_features |= NETIF_F_SG | NETIF_F_IP_CSUM |
1075 NETIF_F_RXCSUM;
1076 netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM |
1077 NETIF_F_RXCSUM | NETIF_F_LLTX;
Scott Bardone559fb512005-06-23 01:40:19 -04001078
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001079 if (pci_using_dac)
1080 netdev->features |= NETIF_F_HIGHDMA;
1081 if (vlan_tso_capable(adapter)) {
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001082#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001083 netdev->features |=
1084 NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001085#endif
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001086
1087 /* T204: disable TSO */
1088 if (!(is_T2(adapter)) || bi->port_number != 4) {
Michał Mirosław30f554f2011-04-18 13:31:20 +00001089 netdev->hw_features |= NETIF_F_TSO;
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001090 netdev->features |= NETIF_F_TSO;
1091 }
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001092 }
1093
Stephen Hemminger80ff32b2008-11-19 22:17:06 -08001094 netdev->netdev_ops = &cxgb_netdev_ops;
Michał Mirosław30f554f2011-04-18 13:31:20 +00001095 netdev->hard_header_len += (netdev->hw_features & NETIF_F_TSO) ?
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001096 sizeof(struct cpl_tx_pkt_lso) : sizeof(struct cpl_tx_pkt);
Stephen Hemminger80ff32b2008-11-19 22:17:06 -08001097
Stephen Hemmingerbea33482007-10-03 16:41:36 -07001098 netif_napi_add(netdev, &adapter->napi, t1_poll, 64);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001099
Stephen Hemminger20578152006-11-17 11:21:22 -08001100 SET_ETHTOOL_OPS(netdev, &t1_ethtool_ops);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001101 }
1102
1103 if (t1_init_sw_modules(adapter, bi) < 0) {
1104 err = -ENODEV;
1105 goto out_free_dev;
1106 }
1107
1108 /*
1109 * The card is now ready to go. If any errors occur during device
1110 * registration we do not fail the whole card but rather proceed only
1111 * with the ports we manage to register successfully. However we must
1112 * register at least one net device.
1113 */
1114 for (i = 0; i < bi->port_number; ++i) {
1115 err = register_netdev(adapter->port[i].dev);
1116 if (err)
Joe Perchesc1f51212010-02-22 16:56:57 +00001117 pr_warning("%s: cannot register net device %s, skipping\n",
1118 pci_name(pdev), adapter->port[i].dev->name);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001119 else {
1120 /*
1121 * Change the name we use for messages to the name of
1122 * the first successfully registered interface.
1123 */
1124 if (!adapter->registered_device_map)
1125 adapter->name = adapter->port[i].dev->name;
1126
Stephen Hemminger20578152006-11-17 11:21:22 -08001127 __set_bit(i, &adapter->registered_device_map);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001128 }
1129 }
1130 if (!adapter->registered_device_map) {
Joe Perchesc1f51212010-02-22 16:56:57 +00001131 pr_err("%s: could not register any net devices\n",
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001132 pci_name(pdev));
1133 goto out_release_adapter_res;
1134 }
1135
1136 printk(KERN_INFO "%s: %s (rev %d), %s %dMHz/%d-bit\n", adapter->name,
1137 bi->desc, adapter->params.chip_revision,
1138 adapter->params.pci.is_pcix ? "PCIX" : "PCI",
1139 adapter->params.pci.speed, adapter->params.pci.width);
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001140
1141 /*
1142 * Set the T1B ASIC and memory clocks.
1143 */
1144 if (t1powersave)
1145 adapter->t1powersave = LCLOCK; /* HW default is powersave mode. */
1146 else
1147 adapter->t1powersave = HCLOCK;
1148 if (t1_is_T1B(adapter))
1149 t1_clock(adapter, t1powersave);
1150
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001151 return 0;
1152
Francois Romieu356bd142006-12-11 23:47:00 +01001153out_release_adapter_res:
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001154 t1_free_sw_modules(adapter);
Francois Romieu356bd142006-12-11 23:47:00 +01001155out_free_dev:
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001156 if (adapter) {
Stephen Hemmingere4876472006-11-17 11:25:23 -08001157 if (adapter->regs)
1158 iounmap(adapter->regs);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001159 for (i = bi->port_number - 1; i >= 0; --i)
Stephen Hemmingere4876472006-11-17 11:25:23 -08001160 if (adapter->port[i].dev)
1161 free_netdev(adapter->port[i].dev);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001162 }
1163 pci_release_regions(pdev);
Francois Romieu356bd142006-12-11 23:47:00 +01001164out_disable_pdev:
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001165 pci_disable_device(pdev);
1166 pci_set_drvdata(pdev, NULL);
1167 return err;
1168}
1169
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001170static void bit_bang(struct adapter *adapter, int bitdata, int nbits)
1171{
1172 int data;
1173 int i;
1174 u32 val;
1175
1176 enum {
1177 S_CLOCK = 1 << 3,
1178 S_DATA = 1 << 4
1179 };
1180
1181 for (i = (nbits - 1); i > -1; i--) {
1182
1183 udelay(50);
1184
1185 data = ((bitdata >> i) & 0x1);
1186 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1187
1188 if (data)
1189 val |= S_DATA;
1190 else
1191 val &= ~S_DATA;
1192
1193 udelay(50);
1194
1195 /* Set SCLOCK low */
1196 val &= ~S_CLOCK;
1197 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1198
1199 udelay(50);
1200
1201 /* Write SCLOCK high */
1202 val |= S_CLOCK;
1203 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1204
1205 }
1206}
1207
1208static int t1_clock(struct adapter *adapter, int mode)
1209{
1210 u32 val;
1211 int M_CORE_VAL;
1212 int M_MEM_VAL;
1213
1214 enum {
Francois Romieu356bd142006-12-11 23:47:00 +01001215 M_CORE_BITS = 9,
1216 T_CORE_VAL = 0,
1217 T_CORE_BITS = 2,
1218 N_CORE_VAL = 0,
1219 N_CORE_BITS = 2,
1220 M_MEM_BITS = 9,
1221 T_MEM_VAL = 0,
1222 T_MEM_BITS = 2,
1223 N_MEM_VAL = 0,
1224 N_MEM_BITS = 2,
1225 NP_LOAD = 1 << 17,
1226 S_LOAD_MEM = 1 << 5,
1227 S_LOAD_CORE = 1 << 6,
1228 S_CLOCK = 1 << 3
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001229 };
1230
1231 if (!t1_is_T1B(adapter))
1232 return -ENODEV; /* Can't re-clock this chip. */
1233
Francois Romieud7487422006-12-11 23:49:13 +01001234 if (mode & 2)
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001235 return 0; /* show current mode. */
Stephen Hemmingerf1d3d382006-12-01 16:36:16 -08001236
1237 if ((adapter->t1powersave & 1) == (mode & 1))
1238 return -EALREADY; /* ASIC already running in mode. */
1239
1240 if ((mode & 1) == HCLOCK) {
1241 M_CORE_VAL = 0x14;
1242 M_MEM_VAL = 0x18;
1243 adapter->t1powersave = HCLOCK; /* overclock */
1244 } else {
1245 M_CORE_VAL = 0xe;
1246 M_MEM_VAL = 0x10;
1247 adapter->t1powersave = LCLOCK; /* underclock */
1248 }
1249
1250 /* Don't interrupt this serial stream! */
1251 spin_lock(&adapter->tpi_lock);
1252
1253 /* Initialize for ASIC core */
1254 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1255 val |= NP_LOAD;
1256 udelay(50);
1257 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1258 udelay(50);
1259 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1260 val &= ~S_LOAD_CORE;
1261 val &= ~S_CLOCK;
1262 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1263 udelay(50);
1264
1265 /* Serial program the ASIC clock synthesizer */
1266 bit_bang(adapter, T_CORE_VAL, T_CORE_BITS);
1267 bit_bang(adapter, N_CORE_VAL, N_CORE_BITS);
1268 bit_bang(adapter, M_CORE_VAL, M_CORE_BITS);
1269 udelay(50);
1270
1271 /* Finish ASIC core */
1272 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1273 val |= S_LOAD_CORE;
1274 udelay(50);
1275 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1276 udelay(50);
1277 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1278 val &= ~S_LOAD_CORE;
1279 udelay(50);
1280 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1281 udelay(50);
1282
1283 /* Initialize for memory */
1284 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1285 val |= NP_LOAD;
1286 udelay(50);
1287 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1288 udelay(50);
1289 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1290 val &= ~S_LOAD_MEM;
1291 val &= ~S_CLOCK;
1292 udelay(50);
1293 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1294 udelay(50);
1295
1296 /* Serial program the memory clock synthesizer */
1297 bit_bang(adapter, T_MEM_VAL, T_MEM_BITS);
1298 bit_bang(adapter, N_MEM_VAL, N_MEM_BITS);
1299 bit_bang(adapter, M_MEM_VAL, M_MEM_BITS);
1300 udelay(50);
1301
1302 /* Finish memory */
1303 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1304 val |= S_LOAD_MEM;
1305 udelay(50);
1306 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1307 udelay(50);
1308 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1309 val &= ~S_LOAD_MEM;
1310 udelay(50);
1311 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1312
1313 spin_unlock(&adapter->tpi_lock);
1314
1315 return 0;
1316}
1317
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001318static inline void t1_sw_reset(struct pci_dev *pdev)
1319{
1320 pci_write_config_dword(pdev, A_PCICFG_PM_CSR, 3);
1321 pci_write_config_dword(pdev, A_PCICFG_PM_CSR, 0);
1322}
1323
1324static void __devexit remove_one(struct pci_dev *pdev)
1325{
1326 struct net_device *dev = pci_get_drvdata(pdev);
Wang Chenc3ccc122008-11-16 23:06:39 -08001327 struct adapter *adapter = dev->ml_priv;
Francois Romieu47cbe6f2006-12-05 23:19:06 +01001328 int i;
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001329
Francois Romieu47cbe6f2006-12-05 23:19:06 +01001330 for_each_port(adapter, i) {
1331 if (test_bit(i, &adapter->registered_device_map))
1332 unregister_netdev(adapter->port[i].dev);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001333 }
Francois Romieu47cbe6f2006-12-05 23:19:06 +01001334
1335 t1_free_sw_modules(adapter);
1336 iounmap(adapter->regs);
1337
1338 while (--i >= 0) {
1339 if (adapter->port[i].dev)
1340 free_netdev(adapter->port[i].dev);
1341 }
1342
1343 pci_release_regions(pdev);
1344 pci_disable_device(pdev);
1345 pci_set_drvdata(pdev, NULL);
1346 t1_sw_reset(pdev);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001347}
1348
1349static struct pci_driver driver = {
Scott Bardone559fb512005-06-23 01:40:19 -04001350 .name = DRV_NAME,
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001351 .id_table = t1_pci_tbl,
1352 .probe = init_one,
1353 .remove = __devexit_p(remove_one),
1354};
1355
1356static int __init t1_init_module(void)
1357{
Jeff Garzik29917622006-08-19 17:48:59 -04001358 return pci_register_driver(&driver);
Christoph Lameter8199d3a2005-03-30 13:34:31 -08001359}
1360
1361static void __exit t1_cleanup_module(void)
1362{
1363 pci_unregister_driver(&driver);
1364}
1365
1366module_init(t1_init_module);
1367module_exit(t1_cleanup_module);