aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/chelsio/cxgb2.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/chelsio/cxgb2.c')
-rw-r--r--drivers/net/chelsio/cxgb2.c537
1 files changed, 281 insertions, 256 deletions
diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c
index 48c4d5acfcd1..28ae478b386d 100644
--- a/drivers/net/chelsio/cxgb2.c
+++ b/drivers/net/chelsio/cxgb2.c
@@ -1,8 +1,8 @@
1/***************************************************************************** 1/*****************************************************************************
2 * * 2 * *
3 * File: cxgb2.c * 3 * File: cxgb2.c *
4 * $Revision: 1.11 $ * 4 * $Revision: 1.25 $ *
5 * $Date: 2005/03/23 07:41:27 $ * 5 * $Date: 2005/06/22 00:43:25 $ *
6 * Description: * 6 * Description: *
7 * Chelsio 10Gb Ethernet Driver. * 7 * Chelsio 10Gb Ethernet Driver. *
8 * * 8 * *
@@ -37,7 +37,6 @@
37 ****************************************************************************/ 37 ****************************************************************************/
38 38
39#include "common.h" 39#include "common.h"
40
41#include <linux/config.h> 40#include <linux/config.h>
42#include <linux/module.h> 41#include <linux/module.h>
43#include <linux/init.h> 42#include <linux/init.h>
@@ -48,44 +47,56 @@
48#include <linux/mii.h> 47#include <linux/mii.h>
49#include <linux/sockios.h> 48#include <linux/sockios.h>
50#include <linux/proc_fs.h> 49#include <linux/proc_fs.h>
51#include <linux/version.h> 50#include <linux/dma-mapping.h>
52#include <linux/workqueue.h>
53#include <asm/uaccess.h> 51#include <asm/uaccess.h>
54 52
55#include "ch_ethtool.h"
56#include "cpl5_cmd.h" 53#include "cpl5_cmd.h"
57#include "regs.h" 54#include "regs.h"
58#include "gmac.h" 55#include "gmac.h"
59#include "cphy.h" 56#include "cphy.h"
60#include "sge.h" 57#include "sge.h"
61#include "tp.h"
62#include "espi.h" 58#include "espi.h"
63 59
60#ifdef work_struct
61#include <linux/tqueue.h>
62#define INIT_WORK INIT_TQUEUE
63#define schedule_work schedule_task
64#define flush_scheduled_work flush_scheduled_tasks
65
64static inline void schedule_mac_stats_update(struct adapter *ap, int secs) 66static inline void schedule_mac_stats_update(struct adapter *ap, int secs)
65{ 67{
66 schedule_delayed_work(&ap->stats_update_task, secs * HZ); 68 mod_timer(&ap->stats_update_timer, jiffies + secs * HZ);
67} 69}
68 70
69static inline void cancel_mac_stats_update(struct adapter *ap) 71static inline void cancel_mac_stats_update(struct adapter *ap)
70{ 72{
71 cancel_delayed_work(&ap->stats_update_task); 73 del_timer_sync(&ap->stats_update_timer);
74 flush_scheduled_tasks();
72} 75}
73 76
74#if BITS_PER_LONG == 64 && !defined(CONFIG_X86_64) 77/*
75# define FMT64 "l" 78 * Stats update timer for 2.4. It schedules a task to do the actual update as
76#else 79 * we need to access MAC statistics in process context.
77# define FMT64 "ll" 80 */
78#endif 81static void mac_stats_timer(unsigned long data)
82{
83 struct adapter *ap = (struct adapter *)data;
79 84
80# define DRV_TYPE "" 85 schedule_task(&ap->stats_update_task);
81# define MODULE_DESC "Chelsio Network Driver" 86}
87#else
88#include <linux/workqueue.h>
82 89
83static char driver_name[] = DRV_NAME; 90static inline void schedule_mac_stats_update(struct adapter *ap, int secs)
84static char driver_string[] = "Chelsio " DRV_TYPE "Network Driver"; 91{
85static char driver_version[] = "2.1.0"; 92 schedule_delayed_work(&ap->stats_update_task, secs * HZ);
93}
86 94
87#define PCI_DMA_64BIT ~0ULL 95static inline void cancel_mac_stats_update(struct adapter *ap)
88#define PCI_DMA_32BIT 0xffffffffULL 96{
97 cancel_delayed_work(&ap->stats_update_task);
98}
99#endif
89 100
90#define MAX_CMDQ_ENTRIES 16384 101#define MAX_CMDQ_ENTRIES 16384
91#define MAX_CMDQ1_ENTRIES 1024 102#define MAX_CMDQ1_ENTRIES 1024
@@ -107,10 +118,9 @@ static char driver_version[] = "2.1.0";
107 */ 118 */
108#define EEPROM_SIZE 32 119#define EEPROM_SIZE 32
109 120
110MODULE_DESCRIPTION(MODULE_DESC); 121MODULE_DESCRIPTION(DRV_DESCRIPTION);
111MODULE_AUTHOR("Chelsio Communications"); 122MODULE_AUTHOR("Chelsio Communications");
112MODULE_LICENSE("GPL"); 123MODULE_LICENSE("GPL");
113MODULE_DEVICE_TABLE(pci, t1_pci_tbl);
114 124
115static int dflt_msg_enable = DFLT_MSG_ENABLE; 125static int dflt_msg_enable = DFLT_MSG_ENABLE;
116 126
@@ -140,17 +150,17 @@ static void t1_set_rxmode(struct net_device *dev)
140static void link_report(struct port_info *p) 150static void link_report(struct port_info *p)
141{ 151{
142 if (!netif_carrier_ok(p->dev)) 152 if (!netif_carrier_ok(p->dev))
143 printk(KERN_INFO "%s: link is down\n", p->dev->name); 153 printk(KERN_INFO "%s: link down\n", p->dev->name);
144 else { 154 else {
145 const char *s = "10 Mbps"; 155 const char *s = "10Mbps";
146 156
147 switch (p->link_config.speed) { 157 switch (p->link_config.speed) {
148 case SPEED_10000: s = "10 Gbps"; break; 158 case SPEED_10000: s = "10Gbps"; break;
149 case SPEED_1000: s = "1000 Mbps"; break; 159 case SPEED_1000: s = "1000Mbps"; break;
150 case SPEED_100: s = "100 Mbps"; break; 160 case SPEED_100: s = "100Mbps"; break;
151 } 161 }
152 162
153 printk(KERN_INFO "%s: link is up at %s, %s duplex\n", 163 printk(KERN_INFO "%s: link up, %s, %s-duplex\n",
154 p->dev->name, s, 164 p->dev->name, s,
155 p->link_config.duplex == DUPLEX_FULL ? "full" : "half"); 165 p->link_config.duplex == DUPLEX_FULL ? "full" : "half");
156 } 166 }
@@ -186,10 +196,8 @@ static void link_start(struct port_info *p)
186static void enable_hw_csum(struct adapter *adapter) 196static void enable_hw_csum(struct adapter *adapter)
187{ 197{
188 if (adapter->flags & TSO_CAPABLE) 198 if (adapter->flags & TSO_CAPABLE)
189 t1_tp_set_ip_checksum_offload(adapter->tp, 1); /* for TSO only */ 199 t1_tp_set_ip_checksum_offload(adapter, 1); /* for TSO only */
190 if (adapter->flags & UDP_CSUM_CAPABLE) 200 t1_tp_set_tcp_checksum_offload(adapter, 1);
191 t1_tp_set_udp_checksum_offload(adapter->tp, 1);
192 t1_tp_set_tcp_checksum_offload(adapter->tp, 1);
193} 201}
194 202
195/* 203/*
@@ -210,15 +218,13 @@ static int cxgb_up(struct adapter *adapter)
210 } 218 }
211 219
212 t1_interrupts_clear(adapter); 220 t1_interrupts_clear(adapter);
213 221 if ((err = request_irq(adapter->pdev->irq,
214 if ((err = request_irq(adapter->pdev->irq, &t1_interrupt, SA_SHIRQ, 222 t1_select_intr_handler(adapter), SA_SHIRQ,
215 adapter->name, adapter))) 223 adapter->name, adapter))) {
216 goto out_err; 224 goto out_err;
217 225 }
218 t1_sge_start(adapter->sge); 226 t1_sge_start(adapter->sge);
219 t1_interrupts_enable(adapter); 227 t1_interrupts_enable(adapter);
220
221 err = 0;
222 out_err: 228 out_err:
223 return err; 229 return err;
224} 230}
@@ -339,47 +345,80 @@ static void set_msglevel(struct net_device *dev, u32 val)
339} 345}
340 346
341static char stats_strings[][ETH_GSTRING_LEN] = { 347static char stats_strings[][ETH_GSTRING_LEN] = {
342 "TxOctetsOK", 348 "TxOctetsOK",
343 "TxOctetsBad", 349 "TxOctetsBad",
344 "TxUnicastFramesOK", 350 "TxUnicastFramesOK",
345 "TxMulticastFramesOK", 351 "TxMulticastFramesOK",
346 "TxBroadcastFramesOK", 352 "TxBroadcastFramesOK",
347 "TxPauseFrames", 353 "TxPauseFrames",
348 "TxFramesWithDeferredXmissions", 354 "TxFramesWithDeferredXmissions",
349 "TxLateCollisions", 355 "TxLateCollisions",
350 "TxTotalCollisions", 356 "TxTotalCollisions",
351 "TxFramesAbortedDueToXSCollisions", 357 "TxFramesAbortedDueToXSCollisions",
352 "TxUnderrun", 358 "TxUnderrun",
353 "TxLengthErrors", 359 "TxLengthErrors",
354 "TxInternalMACXmitError", 360 "TxInternalMACXmitError",
355 "TxFramesWithExcessiveDeferral", 361 "TxFramesWithExcessiveDeferral",
356 "TxFCSErrors", 362 "TxFCSErrors",
357 363
358 "RxOctetsOK", 364 "RxOctetsOK",
359 "RxOctetsBad", 365 "RxOctetsBad",
360 "RxUnicastFramesOK", 366 "RxUnicastFramesOK",
361 "RxMulticastFramesOK", 367 "RxMulticastFramesOK",
362 "RxBroadcastFramesOK", 368 "RxBroadcastFramesOK",
363 "RxPauseFrames", 369 "RxPauseFrames",
364 "RxFCSErrors", 370 "RxFCSErrors",
365 "RxAlignErrors", 371 "RxAlignErrors",
366 "RxSymbolErrors", 372 "RxSymbolErrors",
367 "RxDataErrors", 373 "RxDataErrors",
368 "RxSequenceErrors", 374 "RxSequenceErrors",
369 "RxRuntErrors", 375 "RxRuntErrors",
370 "RxJabberErrors", 376 "RxJabberErrors",
371 "RxInternalMACRcvError", 377 "RxInternalMACRcvError",
372 "RxInRangeLengthErrors", 378 "RxInRangeLengthErrors",
373 "RxOutOfRangeLengthField", 379 "RxOutOfRangeLengthField",
374 "RxFrameTooLongErrors" 380 "RxFrameTooLongErrors",
381
382 "TSO",
383 "VLANextractions",
384 "VLANinsertions",
385 "RxCsumGood",
386 "TxCsumOffload",
387 "RxDrops"
388
389 "respQ_empty",
390 "respQ_overflow",
391 "freelistQ_empty",
392 "pkt_too_big",
393 "pkt_mismatch",
394 "cmdQ_full0",
395 "cmdQ_full1",
396 "tx_ipfrags",
397 "tx_reg_pkts",
398 "tx_lso_pkts",
399 "tx_do_cksum",
400
401 "espi_DIP2ParityErr",
402 "espi_DIP4Err",
403 "espi_RxDrops",
404 "espi_TxDrops",
405 "espi_RxOvfl",
406 "espi_ParityErr"
375}; 407};
408
409#define T2_REGMAP_SIZE (3 * 1024)
410
411static int get_regs_len(struct net_device *dev)
412{
413 return T2_REGMAP_SIZE;
414}
376 415
377static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) 416static void get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
378{ 417{
379 struct adapter *adapter = dev->priv; 418 struct adapter *adapter = dev->priv;
380 419
381 strcpy(info->driver, driver_name); 420 strcpy(info->driver, DRV_NAME);
382 strcpy(info->version, driver_version); 421 strcpy(info->version, DRV_VERSION);
383 strcpy(info->fw_version, "N/A"); 422 strcpy(info->fw_version, "N/A");
384 strcpy(info->bus_info, pci_name(adapter->pdev)); 423 strcpy(info->bus_info, pci_name(adapter->pdev));
385} 424}
@@ -401,42 +440,88 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats,
401 struct adapter *adapter = dev->priv; 440 struct adapter *adapter = dev->priv;
402 struct cmac *mac = adapter->port[dev->if_port].mac; 441 struct cmac *mac = adapter->port[dev->if_port].mac;
403 const struct cmac_statistics *s; 442 const struct cmac_statistics *s;
443 const struct sge_port_stats *ss;
444 const struct sge_intr_counts *t;
404 445
405 s = mac->ops->statistics_update(mac, MAC_STATS_UPDATE_FULL); 446 s = mac->ops->statistics_update(mac, MAC_STATS_UPDATE_FULL);
447 ss = t1_sge_get_port_stats(adapter->sge, dev->if_port);
448 t = t1_sge_get_intr_counts(adapter->sge);
449
450 *data++ = s->TxOctetsOK;
451 *data++ = s->TxOctetsBad;
452 *data++ = s->TxUnicastFramesOK;
453 *data++ = s->TxMulticastFramesOK;
454 *data++ = s->TxBroadcastFramesOK;
455 *data++ = s->TxPauseFrames;
456 *data++ = s->TxFramesWithDeferredXmissions;
457 *data++ = s->TxLateCollisions;
458 *data++ = s->TxTotalCollisions;
459 *data++ = s->TxFramesAbortedDueToXSCollisions;
460 *data++ = s->TxUnderrun;
461 *data++ = s->TxLengthErrors;
462 *data++ = s->TxInternalMACXmitError;
463 *data++ = s->TxFramesWithExcessiveDeferral;
464 *data++ = s->TxFCSErrors;
465
466 *data++ = s->RxOctetsOK;
467 *data++ = s->RxOctetsBad;
468 *data++ = s->RxUnicastFramesOK;
469 *data++ = s->RxMulticastFramesOK;
470 *data++ = s->RxBroadcastFramesOK;
471 *data++ = s->RxPauseFrames;
472 *data++ = s->RxFCSErrors;
473 *data++ = s->RxAlignErrors;
474 *data++ = s->RxSymbolErrors;
475 *data++ = s->RxDataErrors;
476 *data++ = s->RxSequenceErrors;
477 *data++ = s->RxRuntErrors;
478 *data++ = s->RxJabberErrors;
479 *data++ = s->RxInternalMACRcvError;
480 *data++ = s->RxInRangeLengthErrors;
481 *data++ = s->RxOutOfRangeLengthField;
482 *data++ = s->RxFrameTooLongErrors;
483
484 *data++ = ss->tso;
485 *data++ = ss->vlan_xtract;
486 *data++ = ss->vlan_insert;
487 *data++ = ss->rx_cso_good;
488 *data++ = ss->tx_cso;
489 *data++ = ss->rx_drops;
490
491 *data++ = (u64)t->respQ_empty;
492 *data++ = (u64)t->respQ_overflow;
493 *data++ = (u64)t->freelistQ_empty;
494 *data++ = (u64)t->pkt_too_big;
495 *data++ = (u64)t->pkt_mismatch;
496 *data++ = (u64)t->cmdQ_full[0];
497 *data++ = (u64)t->cmdQ_full[1];
498 *data++ = (u64)t->tx_ipfrags;
499 *data++ = (u64)t->tx_reg_pkts;
500 *data++ = (u64)t->tx_lso_pkts;
501 *data++ = (u64)t->tx_do_cksum;
502}
503
504static inline void reg_block_dump(struct adapter *ap, void *buf,
505 unsigned int start, unsigned int end)
506{
507 u32 *p = buf + start;
508
509 for ( ; start <= end; start += sizeof(u32))
510 *p++ = readl(ap->regs + start);
511}
406 512
407 *data++ = s->TxOctetsOK; 513static void get_regs(struct net_device *dev, struct ethtool_regs *regs,
408 *data++ = s->TxOctetsBad; 514 void *buf)
409 *data++ = s->TxUnicastFramesOK; 515{
410 *data++ = s->TxMulticastFramesOK; 516 struct adapter *ap = dev->priv;
411 *data++ = s->TxBroadcastFramesOK; 517
412 *data++ = s->TxPauseFrames; 518 /*
413 *data++ = s->TxFramesWithDeferredXmissions; 519 * Version scheme: bits 0..9: chip version, bits 10..15: chip revision
414 *data++ = s->TxLateCollisions; 520 */
415 *data++ = s->TxTotalCollisions; 521 regs->version = 2;
416 *data++ = s->TxFramesAbortedDueToXSCollisions; 522
417 *data++ = s->TxUnderrun; 523 memset(buf, 0, T2_REGMAP_SIZE);
418 *data++ = s->TxLengthErrors; 524 reg_block_dump(ap, buf, 0, A_SG_RESPACCUTIMER);
419 *data++ = s->TxInternalMACXmitError;
420 *data++ = s->TxFramesWithExcessiveDeferral;
421 *data++ = s->TxFCSErrors;
422
423 *data++ = s->RxOctetsOK;
424 *data++ = s->RxOctetsBad;
425 *data++ = s->RxUnicastFramesOK;
426 *data++ = s->RxMulticastFramesOK;
427 *data++ = s->RxBroadcastFramesOK;
428 *data++ = s->RxPauseFrames;
429 *data++ = s->RxFCSErrors;
430 *data++ = s->RxAlignErrors;
431 *data++ = s->RxSymbolErrors;
432 *data++ = s->RxDataErrors;
433 *data++ = s->RxSequenceErrors;
434 *data++ = s->RxRuntErrors;
435 *data++ = s->RxJabberErrors;
436 *data++ = s->RxInternalMACRcvError;
437 *data++ = s->RxInRangeLengthErrors;
438 *data++ = s->RxOutOfRangeLengthField;
439 *data++ = s->RxFrameTooLongErrors;
440} 525}
441 526
442static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd) 527static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
@@ -455,12 +540,12 @@ static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
455 cmd->duplex = -1; 540 cmd->duplex = -1;
456 } 541 }
457 542
458 cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE; 543 cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE;
459 cmd->phy_address = p->phy->addr; 544 cmd->phy_address = p->phy->addr;
460 cmd->transceiver = XCVR_EXTERNAL; 545 cmd->transceiver = XCVR_EXTERNAL;
461 cmd->autoneg = p->link_config.autoneg; 546 cmd->autoneg = p->link_config.autoneg;
462 cmd->maxtxpkt = 0; 547 cmd->maxtxpkt = 0;
463 cmd->maxrxpkt = 0; 548 cmd->maxrxpkt = 0;
464 return 0; 549 return 0;
465} 550}
466 551
@@ -506,7 +591,7 @@ static int set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
506 struct link_config *lc = &p->link_config; 591 struct link_config *lc = &p->link_config;
507 592
508 if (!(lc->supported & SUPPORTED_Autoneg)) 593 if (!(lc->supported & SUPPORTED_Autoneg))
509 return -EOPNOTSUPP; /* can't change speed/duplex */ 594 return -EOPNOTSUPP; /* can't change speed/duplex */
510 595
511 if (cmd->autoneg == AUTONEG_DISABLE) { 596 if (cmd->autoneg == AUTONEG_DISABLE) {
512 int cap = speed_duplex_to_caps(cmd->speed, cmd->duplex); 597 int cap = speed_duplex_to_caps(cmd->speed, cmd->duplex);
@@ -631,7 +716,7 @@ static int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
631 return -EINVAL; 716 return -EINVAL;
632 717
633 if (adapter->flags & FULL_INIT_DONE) 718 if (adapter->flags & FULL_INIT_DONE)
634 return -EBUSY; 719 return -EBUSY;
635 720
636 adapter->params.sge.freelQ_size[!jumbo_fl] = e->rx_pending; 721 adapter->params.sge.freelQ_size[!jumbo_fl] = e->rx_pending;
637 adapter->params.sge.freelQ_size[jumbo_fl] = e->rx_jumbo_pending; 722 adapter->params.sge.freelQ_size[jumbo_fl] = e->rx_jumbo_pending;
@@ -645,22 +730,20 @@ static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
645{ 730{
646 struct adapter *adapter = dev->priv; 731 struct adapter *adapter = dev->priv;
647 732
648 unsigned int sge_coalesce_usecs = 0; 733 /*
734 * If RX coalescing is requested we use NAPI, otherwise interrupts.
735 * This choice can be made only when all ports and the TOE are off.
736 */
737 if (adapter->open_device_map == 0)
738 adapter->params.sge.polling = c->use_adaptive_rx_coalesce;
649 739
650 sge_coalesce_usecs = adapter->params.sge.last_rx_coalesce_raw; 740 if (adapter->params.sge.polling) {
651 sge_coalesce_usecs /= board_info(adapter)->clock_core / 1000000; 741 adapter->params.sge.rx_coalesce_usecs = 0;
652 if ( (adapter->params.sge.coalesce_enable && !c->use_adaptive_rx_coalesce) &&
653 (c->rx_coalesce_usecs == sge_coalesce_usecs) ) {
654 adapter->params.sge.rx_coalesce_usecs =
655 adapter->params.sge.default_rx_coalesce_usecs;
656 } else { 742 } else {
657 adapter->params.sge.rx_coalesce_usecs = c->rx_coalesce_usecs; 743 adapter->params.sge.rx_coalesce_usecs = c->rx_coalesce_usecs;
658 } 744 }
659 745 adapter->params.sge.coalesce_enable = c->use_adaptive_rx_coalesce;
660 adapter->params.sge.last_rx_coalesce_raw = adapter->params.sge.rx_coalesce_usecs;
661 adapter->params.sge.last_rx_coalesce_raw *= (board_info(adapter)->clock_core / 1000000);
662 adapter->params.sge.sample_interval_usecs = c->rate_sample_interval; 746 adapter->params.sge.sample_interval_usecs = c->rate_sample_interval;
663 adapter->params.sge.coalesce_enable = c->use_adaptive_rx_coalesce;
664 t1_sge_set_coalesce_params(adapter->sge, &adapter->params.sge); 747 t1_sge_set_coalesce_params(adapter->sge, &adapter->params.sge);
665 return 0; 748 return 0;
666} 749}
@@ -669,12 +752,7 @@ static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
669{ 752{
670 struct adapter *adapter = dev->priv; 753 struct adapter *adapter = dev->priv;
671 754
672 if (adapter->params.sge.coalesce_enable) { /* Adaptive algorithm on */ 755 c->rx_coalesce_usecs = adapter->params.sge.rx_coalesce_usecs;
673 c->rx_coalesce_usecs = adapter->params.sge.last_rx_coalesce_raw;
674 c->rx_coalesce_usecs /= board_info(adapter)->clock_core / 1000000;
675 } else {
676 c->rx_coalesce_usecs = adapter->params.sge.rx_coalesce_usecs;
677 }
678 c->rate_sample_interval = adapter->params.sge.sample_interval_usecs; 756 c->rate_sample_interval = adapter->params.sge.sample_interval_usecs;
679 c->use_adaptive_rx_coalesce = adapter->params.sge.coalesce_enable; 757 c->use_adaptive_rx_coalesce = adapter->params.sge.coalesce_enable;
680 return 0; 758 return 0;
@@ -682,9 +760,7 @@ static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
682 760
683static int get_eeprom_len(struct net_device *dev) 761static int get_eeprom_len(struct net_device *dev)
684{ 762{
685 struct adapter *adapter = dev->priv; 763 return EEPROM_SIZE;
686
687 return t1_is_asic(adapter) ? EEPROM_SIZE : 0;
688} 764}
689 765
690#define EEPROM_MAGIC(ap) \ 766#define EEPROM_MAGIC(ap) \
@@ -728,118 +804,55 @@ static struct ethtool_ops t1_ethtool_ops = {
728 .get_strings = get_strings, 804 .get_strings = get_strings,
729 .get_stats_count = get_stats_count, 805 .get_stats_count = get_stats_count,
730 .get_ethtool_stats = get_stats, 806 .get_ethtool_stats = get_stats,
807 .get_regs_len = get_regs_len,
808 .get_regs = get_regs,
731 .get_tso = ethtool_op_get_tso, 809 .get_tso = ethtool_op_get_tso,
732 .set_tso = set_tso, 810 .set_tso = set_tso,
733}; 811};
734 812
735static int ethtool_ioctl(struct net_device *dev, void *useraddr) 813static void cxgb_proc_cleanup(struct adapter *adapter,
814 struct proc_dir_entry *dir)
736{ 815{
737 u32 cmd; 816 const char *name;
738 struct adapter *adapter = dev->priv; 817 name = adapter->name;
739 818 remove_proc_entry(name, dir);
740 if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
741 return -EFAULT;
742
743 switch (cmd) {
744 case ETHTOOL_SETREG: {
745 struct ethtool_reg edata;
746
747 if (!capable(CAP_NET_ADMIN))
748 return -EPERM;
749 if (copy_from_user(&edata, useraddr, sizeof(edata)))
750 return -EFAULT;
751 if ((edata.addr & 3) != 0 || edata.addr >= adapter->mmio_len)
752 return -EINVAL;
753 if (edata.addr == A_ESPI_MISC_CONTROL)
754 t1_espi_set_misc_ctrl(adapter, edata.val);
755 else {
756 if (edata.addr == 0x950)
757 t1_sge_set_ptimeout(adapter, edata.val);
758 else
759 writel(edata.val, adapter->regs + edata.addr);
760 }
761 break;
762 }
763 case ETHTOOL_GETREG: {
764 struct ethtool_reg edata;
765
766 if (copy_from_user(&edata, useraddr, sizeof(edata)))
767 return -EFAULT;
768 if ((edata.addr & 3) != 0 || edata.addr >= adapter->mmio_len)
769 return -EINVAL;
770 if (edata.addr >= 0x900 && edata.addr <= 0x93c)
771 edata.val = t1_espi_get_mon(adapter, edata.addr, 1);
772 else {
773 if (edata.addr == 0x950)
774 edata.val = t1_sge_get_ptimeout(adapter);
775 else
776 edata.val = readl(adapter->regs + edata.addr);
777 }
778 if (copy_to_user(useraddr, &edata, sizeof(edata)))
779 return -EFAULT;
780 break;
781 }
782 case ETHTOOL_SETTPI: {
783 struct ethtool_reg edata;
784
785 if (!capable(CAP_NET_ADMIN))
786 return -EPERM;
787 if (copy_from_user(&edata, useraddr, sizeof(edata)))
788 return -EFAULT;
789 if ((edata.addr & 3) != 0)
790 return -EINVAL;
791 t1_tpi_write(adapter, edata.addr, edata.val);
792 break;
793 }
794 case ETHTOOL_GETTPI: {
795 struct ethtool_reg edata;
796
797 if (copy_from_user(&edata, useraddr, sizeof(edata)))
798 return -EFAULT;
799 if ((edata.addr & 3) != 0)
800 return -EINVAL;
801 t1_tpi_read(adapter, edata.addr, &edata.val);
802 if (copy_to_user(useraddr, &edata, sizeof(edata)))
803 return -EFAULT;
804 break;
805 }
806 default:
807 return -EOPNOTSUPP;
808 }
809 return 0;
810} 819}
820//#define chtoe_setup_toedev(adapter) NULL
821#define update_mtu_tab(adapter)
822#define write_smt_entry(adapter, idx)
811 823
812static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd) 824static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
813{ 825{
814 struct adapter *adapter = dev->priv; 826 struct adapter *adapter = dev->priv;
815 struct mii_ioctl_data *data = (struct mii_ioctl_data *)&req->ifr_data; 827 struct mii_ioctl_data *data = (struct mii_ioctl_data *)&req->ifr_data;
816 828
817 switch (cmd) { 829 switch (cmd) {
818 case SIOCGMIIPHY: 830 case SIOCGMIIPHY:
819 data->phy_id = adapter->port[dev->if_port].phy->addr; 831 data->phy_id = adapter->port[dev->if_port].phy->addr;
820 /* FALLTHRU */ 832 /* FALLTHRU */
821 case SIOCGMIIREG: { 833 case SIOCGMIIREG: {
822 struct cphy *phy = adapter->port[dev->if_port].phy; 834 struct cphy *phy = adapter->port[dev->if_port].phy;
823 u32 val; 835 u32 val;
824 836
825 if (!phy->mdio_read) return -EOPNOTSUPP; 837 if (!phy->mdio_read)
838 return -EOPNOTSUPP;
826 phy->mdio_read(adapter, data->phy_id, 0, data->reg_num & 0x1f, 839 phy->mdio_read(adapter, data->phy_id, 0, data->reg_num & 0x1f,
827 &val); 840 &val);
828 data->val_out = val; 841 data->val_out = val;
829 break; 842 break;
830 } 843 }
831 case SIOCSMIIREG: { 844 case SIOCSMIIREG: {
832 struct cphy *phy = adapter->port[dev->if_port].phy; 845 struct cphy *phy = adapter->port[dev->if_port].phy;
833 846
834 if (!capable(CAP_NET_ADMIN)) return -EPERM; 847 if (!capable(CAP_NET_ADMIN))
835 if (!phy->mdio_write) return -EOPNOTSUPP; 848 return -EPERM;
849 if (!phy->mdio_write)
850 return -EOPNOTSUPP;
836 phy->mdio_write(adapter, data->phy_id, 0, data->reg_num & 0x1f, 851 phy->mdio_write(adapter, data->phy_id, 0, data->reg_num & 0x1f,
837 data->val_in); 852 data->val_in);
838 break; 853 break;
839 } 854 }
840 855
841 case SIOCCHETHTOOL:
842 return ethtool_ioctl(dev, (void *)req->ifr_data);
843 default: 856 default:
844 return -EOPNOTSUPP; 857 return -EOPNOTSUPP;
845 } 858 }
@@ -853,9 +866,9 @@ static int t1_change_mtu(struct net_device *dev, int new_mtu)
853 struct cmac *mac = adapter->port[dev->if_port].mac; 866 struct cmac *mac = adapter->port[dev->if_port].mac;
854 867
855 if (!mac->ops->set_mtu) 868 if (!mac->ops->set_mtu)
856 return -EOPNOTSUPP; 869 return -EOPNOTSUPP;
857 if (new_mtu < 68) 870 if (new_mtu < 68)
858 return -EINVAL; 871 return -EINVAL;
859 if ((ret = mac->ops->set_mtu(mac, new_mtu))) 872 if ((ret = mac->ops->set_mtu(mac, new_mtu)))
860 return ret; 873 return ret;
861 dev->mtu = new_mtu; 874 dev->mtu = new_mtu;
@@ -902,9 +915,12 @@ static void vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
902#ifdef CONFIG_NET_POLL_CONTROLLER 915#ifdef CONFIG_NET_POLL_CONTROLLER
903static void t1_netpoll(struct net_device *dev) 916static void t1_netpoll(struct net_device *dev)
904{ 917{
918 unsigned long flags;
905 struct adapter *adapter = dev->priv; 919 struct adapter *adapter = dev->priv;
906 920
907 t1_interrupt(adapter->pdev->irq, adapter, NULL); 921 local_irq_save(flags);
922 t1_select_intr_handler(adapter)(adapter->pdev->irq, adapter, NULL);
923 local_irq_restore(flags);
908} 924}
909#endif 925#endif
910 926
@@ -938,16 +954,17 @@ static void mac_stats_task(void *data)
938 */ 954 */
939static void ext_intr_task(void *data) 955static void ext_intr_task(void *data)
940{ 956{
941 u32 enable;
942 struct adapter *adapter = data; 957 struct adapter *adapter = data;
943 958
944 elmer0_ext_intr_handler(adapter); 959 elmer0_ext_intr_handler(adapter);
945 960
946 /* Now reenable external interrupts */ 961 /* Now reenable external interrupts */
947 t1_write_reg_4(adapter, A_PL_CAUSE, F_PL_INTR_EXT); 962 spin_lock_irq(&adapter->async_lock);
948 enable = t1_read_reg_4(adapter, A_PL_ENABLE);
949 t1_write_reg_4(adapter, A_PL_ENABLE, enable | F_PL_INTR_EXT);
950 adapter->slow_intr_mask |= F_PL_INTR_EXT; 963 adapter->slow_intr_mask |= F_PL_INTR_EXT;
964 writel(F_PL_INTR_EXT, adapter->regs + A_PL_CAUSE);
965 writel(adapter->slow_intr_mask | F_PL_INTR_SGE_DATA,
966 adapter->regs + A_PL_ENABLE);
967 spin_unlock_irq(&adapter->async_lock);
951} 968}
952 969
953/* 970/*
@@ -955,15 +972,14 @@ static void ext_intr_task(void *data)
955 */ 972 */
956void t1_elmer0_ext_intr(struct adapter *adapter) 973void t1_elmer0_ext_intr(struct adapter *adapter)
957{ 974{
958 u32 enable = t1_read_reg_4(adapter, A_PL_ENABLE);
959
960 /* 975 /*
961 * Schedule a task to handle external interrupts as we require 976 * Schedule a task to handle external interrupts as we require
962 * a process context. We disable EXT interrupts in the interim 977 * a process context. We disable EXT interrupts in the interim
963 * and let the task reenable them when it's done. 978 * and let the task reenable them when it's done.
964 */ 979 */
965 adapter->slow_intr_mask &= ~F_PL_INTR_EXT; 980 adapter->slow_intr_mask &= ~F_PL_INTR_EXT;
966 t1_write_reg_4(adapter, A_PL_ENABLE, enable & ~F_PL_INTR_EXT); 981 writel(adapter->slow_intr_mask | F_PL_INTR_SGE_DATA,
982 adapter->regs + A_PL_ENABLE);
967 schedule_work(&adapter->ext_intr_handler_task); 983 schedule_work(&adapter->ext_intr_handler_task);
968} 984}
969 985
@@ -977,7 +993,6 @@ void t1_fatal_err(struct adapter *adapter)
977 adapter->name); 993 adapter->name);
978} 994}
979 995
980
981static int __devinit init_one(struct pci_dev *pdev, 996static int __devinit init_one(struct pci_dev *pdev,
982 const struct pci_device_id *ent) 997 const struct pci_device_id *ent)
983{ 998{
@@ -990,14 +1005,14 @@ static int __devinit init_one(struct pci_dev *pdev,
990 struct port_info *pi; 1005 struct port_info *pi;
991 1006
992 if (!version_printed) { 1007 if (!version_printed) {
993 printk(KERN_INFO "%s - version %s\n", driver_string, 1008 printk(KERN_INFO "%s - version %s\n", DRV_DESCRIPTION,
994 driver_version); 1009 DRV_VERSION);
995 ++version_printed; 1010 ++version_printed;
996 } 1011 }
997 1012
998 err = pci_enable_device(pdev); 1013 err = pci_enable_device(pdev);
999 if (err) 1014 if (err)
1000 return err; 1015 return err;
1001 1016
1002 if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { 1017 if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
1003 CH_ERR("%s: cannot find PCI device memory base address\n", 1018 CH_ERR("%s: cannot find PCI device memory base address\n",
@@ -1006,20 +1021,22 @@ static int __devinit init_one(struct pci_dev *pdev,
1006 goto out_disable_pdev; 1021 goto out_disable_pdev;
1007 } 1022 }
1008 1023
1009 if (!pci_set_dma_mask(pdev, PCI_DMA_64BIT)) { 1024 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
1010 pci_using_dac = 1; 1025 pci_using_dac = 1;
1011 if (pci_set_consistent_dma_mask(pdev, PCI_DMA_64BIT)) { 1026
1027 if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
1012 CH_ERR("%s: unable to obtain 64-bit DMA for" 1028 CH_ERR("%s: unable to obtain 64-bit DMA for"
1013 "consistent allocations\n", pci_name(pdev)); 1029 "consistent allocations\n", pci_name(pdev));
1014 err = -ENODEV; 1030 err = -ENODEV;
1015 goto out_disable_pdev; 1031 goto out_disable_pdev;
1016 } 1032 }
1017 } else if ((err = pci_set_dma_mask(pdev, PCI_DMA_32BIT)) != 0) { 1033
1034 } else if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) != 0) {
1018 CH_ERR("%s: no usable DMA configuration\n", pci_name(pdev)); 1035 CH_ERR("%s: no usable DMA configuration\n", pci_name(pdev));
1019 goto out_disable_pdev; 1036 goto out_disable_pdev;
1020 } 1037 }
1021 1038
1022 err = pci_request_regions(pdev, driver_name); 1039 err = pci_request_regions(pdev, DRV_NAME);
1023 if (err) { 1040 if (err) {
1024 CH_ERR("%s: cannot obtain PCI resources\n", pci_name(pdev)); 1041 CH_ERR("%s: cannot obtain PCI resources\n", pci_name(pdev));
1025 goto out_disable_pdev; 1042 goto out_disable_pdev;
@@ -1027,7 +1044,7 @@ static int __devinit init_one(struct pci_dev *pdev,
1027 1044
1028 pci_set_master(pdev); 1045 pci_set_master(pdev);
1029 1046
1030 mmio_start = pci_resource_start(pdev, 0); 1047 mmio_start = pci_resource_start(pdev, 0);
1031 mmio_len = pci_resource_len(pdev, 0); 1048 mmio_len = pci_resource_len(pdev, 0);
1032 bi = t1_get_board_info(ent->driver_data); 1049 bi = t1_get_board_info(ent->driver_data);
1033 1050
@@ -1074,9 +1091,14 @@ static int __devinit init_one(struct pci_dev *pdev,
1074 ext_intr_task, adapter); 1091 ext_intr_task, adapter);
1075 INIT_WORK(&adapter->stats_update_task, mac_stats_task, 1092 INIT_WORK(&adapter->stats_update_task, mac_stats_task,
1076 adapter); 1093 adapter);
1094#ifdef work_struct
1095 init_timer(&adapter->stats_update_timer);
1096 adapter->stats_update_timer.function = mac_stats_timer;
1097 adapter->stats_update_timer.data =
1098 (unsigned long)adapter;
1099#endif
1077 1100
1078 pci_set_drvdata(pdev, netdev); 1101 pci_set_drvdata(pdev, netdev);
1079
1080 } 1102 }
1081 1103
1082 pi = &adapter->port[i]; 1104 pi = &adapter->port[i];
@@ -1088,11 +1110,12 @@ static int __devinit init_one(struct pci_dev *pdev,
1088 netdev->mem_end = mmio_start + mmio_len - 1; 1110 netdev->mem_end = mmio_start + mmio_len - 1;
1089 netdev->priv = adapter; 1111 netdev->priv = adapter;
1090 netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; 1112 netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
1113 netdev->features |= NETIF_F_LLTX;
1114
1091 adapter->flags |= RX_CSUM_ENABLED | TCP_CSUM_CAPABLE; 1115 adapter->flags |= RX_CSUM_ENABLED | TCP_CSUM_CAPABLE;
1092 if (pci_using_dac) 1116 if (pci_using_dac)
1093 netdev->features |= NETIF_F_HIGHDMA; 1117 netdev->features |= NETIF_F_HIGHDMA;
1094 if (vlan_tso_capable(adapter)) { 1118 if (vlan_tso_capable(adapter)) {
1095 adapter->flags |= UDP_CSUM_CAPABLE;
1096#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) 1119#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
1097 adapter->flags |= VLAN_ACCEL_CAPABLE; 1120 adapter->flags |= VLAN_ACCEL_CAPABLE;
1098 netdev->features |= 1121 netdev->features |=
@@ -1120,7 +1143,7 @@ static int __devinit init_one(struct pci_dev *pdev,
1120#endif 1143#endif
1121 netdev->weight = 64; 1144 netdev->weight = 64;
1122 1145
1123 SET_ETHTOOL_OPS(netdev, &t1_ethtool_ops); 1146 SET_ETHTOOL_OPS(netdev, &t1_ethtool_ops);
1124 } 1147 }
1125 1148
1126 if (t1_init_sw_modules(adapter, bi) < 0) { 1149 if (t1_init_sw_modules(adapter, bi) < 0) {
@@ -1147,7 +1170,7 @@ static int __devinit init_one(struct pci_dev *pdev,
1147 if (!adapter->registered_device_map) 1170 if (!adapter->registered_device_map)
1148 adapter->name = adapter->port[i].dev->name; 1171 adapter->name = adapter->port[i].dev->name;
1149 1172
1150 __set_bit(i, &adapter->registered_device_map); 1173 __set_bit(i, &adapter->registered_device_map);
1151 } 1174 }
1152 } 1175 }
1153 if (!adapter->registered_device_map) { 1176 if (!adapter->registered_device_map) {
@@ -1166,11 +1189,12 @@ static int __devinit init_one(struct pci_dev *pdev,
1166 t1_free_sw_modules(adapter); 1189 t1_free_sw_modules(adapter);
1167 out_free_dev: 1190 out_free_dev:
1168 if (adapter) { 1191 if (adapter) {
1169 if (adapter->regs) 1192 if (adapter->regs) iounmap(adapter->regs);
1170 iounmap(adapter->regs);
1171 for (i = bi->port_number - 1; i >= 0; --i) 1193 for (i = bi->port_number - 1; i >= 0; --i)
1172 if (adapter->port[i].dev) 1194 if (adapter->port[i].dev) {
1173 free_netdev(adapter->port[i].dev); 1195 cxgb_proc_cleanup(adapter, proc_root_driver);
1196 kfree(adapter->port[i].dev);
1197 }
1174 } 1198 }
1175 pci_release_regions(pdev); 1199 pci_release_regions(pdev);
1176 out_disable_pdev: 1200 out_disable_pdev:
@@ -1200,8 +1224,10 @@ static void __devexit remove_one(struct pci_dev *pdev)
1200 t1_free_sw_modules(adapter); 1224 t1_free_sw_modules(adapter);
1201 iounmap(adapter->regs); 1225 iounmap(adapter->regs);
1202 while (--i >= 0) 1226 while (--i >= 0)
1203 if (adapter->port[i].dev) 1227 if (adapter->port[i].dev) {
1204 free_netdev(adapter->port[i].dev); 1228 cxgb_proc_cleanup(adapter, proc_root_driver);
1229 kfree(adapter->port[i].dev);
1230 }
1205 pci_release_regions(pdev); 1231 pci_release_regions(pdev);
1206 pci_disable_device(pdev); 1232 pci_disable_device(pdev);
1207 pci_set_drvdata(pdev, NULL); 1233 pci_set_drvdata(pdev, NULL);
@@ -1210,7 +1236,7 @@ static void __devexit remove_one(struct pci_dev *pdev)
1210} 1236}
1211 1237
1212static struct pci_driver driver = { 1238static struct pci_driver driver = {
1213 .name = driver_name, 1239 .name = DRV_NAME,
1214 .id_table = t1_pci_tbl, 1240 .id_table = t1_pci_tbl,
1215 .probe = init_one, 1241 .probe = init_one,
1216 .remove = __devexit_p(remove_one), 1242 .remove = __devexit_p(remove_one),
@@ -1228,4 +1254,3 @@ static void __exit t1_cleanup_module(void)
1228 1254
1229module_init(t1_init_module); 1255module_init(t1_init_module);
1230module_exit(t1_cleanup_module); 1256module_exit(t1_cleanup_module);
1231