diff options
Diffstat (limited to 'drivers/net/chelsio/cxgb2.c')
-rw-r--r-- | drivers/net/chelsio/cxgb2.c | 591 |
1 files changed, 386 insertions, 205 deletions
diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c index f607cc6a276b..de48eadddbc4 100644 --- a/drivers/net/chelsio/cxgb2.c +++ b/drivers/net/chelsio/cxgb2.c | |||
@@ -45,7 +45,6 @@ | |||
45 | #include <linux/if_vlan.h> | 45 | #include <linux/if_vlan.h> |
46 | #include <linux/mii.h> | 46 | #include <linux/mii.h> |
47 | #include <linux/sockios.h> | 47 | #include <linux/sockios.h> |
48 | #include <linux/proc_fs.h> | ||
49 | #include <linux/dma-mapping.h> | 48 | #include <linux/dma-mapping.h> |
50 | #include <asm/uaccess.h> | 49 | #include <asm/uaccess.h> |
51 | 50 | ||
@@ -54,36 +53,10 @@ | |||
54 | #include "gmac.h" | 53 | #include "gmac.h" |
55 | #include "cphy.h" | 54 | #include "cphy.h" |
56 | #include "sge.h" | 55 | #include "sge.h" |
56 | #include "tp.h" | ||
57 | #include "espi.h" | 57 | #include "espi.h" |
58 | #include "elmer0.h" | ||
58 | 59 | ||
59 | #ifdef work_struct | ||
60 | #include <linux/tqueue.h> | ||
61 | #define INIT_WORK INIT_TQUEUE | ||
62 | #define schedule_work schedule_task | ||
63 | #define flush_scheduled_work flush_scheduled_tasks | ||
64 | |||
65 | static inline void schedule_mac_stats_update(struct adapter *ap, int secs) | ||
66 | { | ||
67 | mod_timer(&ap->stats_update_timer, jiffies + secs * HZ); | ||
68 | } | ||
69 | |||
70 | static inline void cancel_mac_stats_update(struct adapter *ap) | ||
71 | { | ||
72 | del_timer_sync(&ap->stats_update_timer); | ||
73 | flush_scheduled_tasks(); | ||
74 | } | ||
75 | |||
76 | /* | ||
77 | * Stats update timer for 2.4. It schedules a task to do the actual update as | ||
78 | * we need to access MAC statistics in process context. | ||
79 | */ | ||
80 | static void mac_stats_timer(unsigned long data) | ||
81 | { | ||
82 | struct adapter *ap = (struct adapter *)data; | ||
83 | |||
84 | schedule_task(&ap->stats_update_task); | ||
85 | } | ||
86 | #else | ||
87 | #include <linux/workqueue.h> | 60 | #include <linux/workqueue.h> |
88 | 61 | ||
89 | static inline void schedule_mac_stats_update(struct adapter *ap, int secs) | 62 | static inline void schedule_mac_stats_update(struct adapter *ap, int secs) |
@@ -95,7 +68,6 @@ static inline void cancel_mac_stats_update(struct adapter *ap) | |||
95 | { | 68 | { |
96 | cancel_delayed_work(&ap->stats_update_task); | 69 | cancel_delayed_work(&ap->stats_update_task); |
97 | } | 70 | } |
98 | #endif | ||
99 | 71 | ||
100 | #define MAX_CMDQ_ENTRIES 16384 | 72 | #define MAX_CMDQ_ENTRIES 16384 |
101 | #define MAX_CMDQ1_ENTRIES 1024 | 73 | #define MAX_CMDQ1_ENTRIES 1024 |
@@ -103,10 +75,9 @@ static inline void cancel_mac_stats_update(struct adapter *ap) | |||
103 | #define MAX_RX_JUMBO_BUFFERS 16384 | 75 | #define MAX_RX_JUMBO_BUFFERS 16384 |
104 | #define MAX_TX_BUFFERS_HIGH 16384U | 76 | #define MAX_TX_BUFFERS_HIGH 16384U |
105 | #define MAX_TX_BUFFERS_LOW 1536U | 77 | #define MAX_TX_BUFFERS_LOW 1536U |
78 | #define MAX_TX_BUFFERS 1460U | ||
106 | #define MIN_FL_ENTRIES 32 | 79 | #define MIN_FL_ENTRIES 32 |
107 | 80 | ||
108 | #define PORT_MASK ((1 << MAX_NPORTS) - 1) | ||
109 | |||
110 | #define DFLT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | \ | 81 | #define DFLT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | \ |
111 | NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP |\ | 82 | NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP |\ |
112 | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) | 83 | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) |
@@ -124,8 +95,21 @@ MODULE_LICENSE("GPL"); | |||
124 | static int dflt_msg_enable = DFLT_MSG_ENABLE; | 95 | static int dflt_msg_enable = DFLT_MSG_ENABLE; |
125 | 96 | ||
126 | module_param(dflt_msg_enable, int, 0); | 97 | module_param(dflt_msg_enable, int, 0); |
127 | MODULE_PARM_DESC(dflt_msg_enable, "Chelsio T1 message enable bitmap"); | 98 | MODULE_PARM_DESC(dflt_msg_enable, "Chelsio T1 default message enable bitmap"); |
99 | |||
100 | #define HCLOCK 0x0 | ||
101 | #define LCLOCK 0x1 | ||
102 | |||
103 | /* T1 cards powersave mode */ | ||
104 | static int t1_clock(struct adapter *adapter, int mode); | ||
105 | static int t1powersave = 1; /* HW default is powersave mode. */ | ||
128 | 106 | ||
107 | module_param(t1powersave, int, 0); | ||
108 | MODULE_PARM_DESC(t1powersave, "Enable/Disable T1 powersaving mode"); | ||
109 | |||
110 | static int disable_msi = 0; | ||
111 | module_param(disable_msi, int, 0); | ||
112 | MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)"); | ||
129 | 113 | ||
130 | static const char pci_speed[][4] = { | 114 | static const char pci_speed[][4] = { |
131 | "33", "66", "100", "133" | 115 | "33", "66", "100", "133" |
@@ -149,7 +133,7 @@ static void t1_set_rxmode(struct net_device *dev) | |||
149 | static void link_report(struct port_info *p) | 133 | static void link_report(struct port_info *p) |
150 | { | 134 | { |
151 | if (!netif_carrier_ok(p->dev)) | 135 | if (!netif_carrier_ok(p->dev)) |
152 | printk(KERN_INFO "%s: link down\n", p->dev->name); | 136 | printk(KERN_INFO "%s: link down\n", p->dev->name); |
153 | else { | 137 | else { |
154 | const char *s = "10Mbps"; | 138 | const char *s = "10Mbps"; |
155 | 139 | ||
@@ -159,13 +143,13 @@ static void link_report(struct port_info *p) | |||
159 | case SPEED_100: s = "100Mbps"; break; | 143 | case SPEED_100: s = "100Mbps"; break; |
160 | } | 144 | } |
161 | 145 | ||
162 | printk(KERN_INFO "%s: link up, %s, %s-duplex\n", | 146 | printk(KERN_INFO "%s: link up, %s, %s-duplex\n", |
163 | p->dev->name, s, | 147 | p->dev->name, s, |
164 | p->link_config.duplex == DUPLEX_FULL ? "full" : "half"); | 148 | p->link_config.duplex == DUPLEX_FULL ? "full" : "half"); |
165 | } | 149 | } |
166 | } | 150 | } |
167 | 151 | ||
168 | void t1_link_changed(struct adapter *adapter, int port_id, int link_stat, | 152 | void t1_link_negotiated(struct adapter *adapter, int port_id, int link_stat, |
169 | int speed, int duplex, int pause) | 153 | int speed, int duplex, int pause) |
170 | { | 154 | { |
171 | struct port_info *p = &adapter->port[port_id]; | 155 | struct port_info *p = &adapter->port[port_id]; |
@@ -177,6 +161,22 @@ void t1_link_changed(struct adapter *adapter, int port_id, int link_stat, | |||
177 | netif_carrier_off(p->dev); | 161 | netif_carrier_off(p->dev); |
178 | link_report(p); | 162 | link_report(p); |
179 | 163 | ||
164 | /* 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 | } | ||
180 | } | 180 | } |
181 | } | 181 | } |
182 | 182 | ||
@@ -195,8 +195,10 @@ static void link_start(struct port_info *p) | |||
195 | static void enable_hw_csum(struct adapter *adapter) | 195 | static void enable_hw_csum(struct adapter *adapter) |
196 | { | 196 | { |
197 | if (adapter->flags & TSO_CAPABLE) | 197 | if (adapter->flags & TSO_CAPABLE) |
198 | t1_tp_set_ip_checksum_offload(adapter, 1); /* for TSO only */ | 198 | t1_tp_set_ip_checksum_offload(adapter->tp, 1); /* for TSO only */ |
199 | t1_tp_set_tcp_checksum_offload(adapter, 1); | 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); | ||
200 | } | 202 | } |
201 | 203 | ||
202 | /* | 204 | /* |
@@ -217,11 +219,19 @@ static int cxgb_up(struct adapter *adapter) | |||
217 | } | 219 | } |
218 | 220 | ||
219 | t1_interrupts_clear(adapter); | 221 | t1_interrupts_clear(adapter); |
220 | if ((err = request_irq(adapter->pdev->irq, | 222 | |
221 | t1_select_intr_handler(adapter), IRQF_SHARED, | 223 | adapter->params.has_msi = !disable_msi && pci_enable_msi(adapter->pdev) == 0; |
222 | adapter->name, adapter))) { | 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 | |||
223 | goto out_err; | 232 | goto out_err; |
224 | } | 233 | } |
234 | |||
225 | t1_sge_start(adapter->sge); | 235 | t1_sge_start(adapter->sge); |
226 | t1_interrupts_enable(adapter); | 236 | t1_interrupts_enable(adapter); |
227 | out_err: | 237 | out_err: |
@@ -236,6 +246,8 @@ static void cxgb_down(struct adapter *adapter) | |||
236 | t1_sge_stop(adapter->sge); | 246 | t1_sge_stop(adapter->sge); |
237 | t1_interrupts_disable(adapter); | 247 | t1_interrupts_disable(adapter); |
238 | free_irq(adapter->pdev->irq, adapter); | 248 | free_irq(adapter->pdev->irq, adapter); |
249 | if (adapter->params.has_msi) | ||
250 | pci_disable_msi(adapter->pdev); | ||
239 | } | 251 | } |
240 | 252 | ||
241 | static int cxgb_open(struct net_device *dev) | 253 | static int cxgb_open(struct net_device *dev) |
@@ -290,7 +302,7 @@ static struct net_device_stats *t1_get_stats(struct net_device *dev) | |||
290 | 302 | ||
291 | /* Do a full update of the MAC stats */ | 303 | /* Do a full update of the MAC stats */ |
292 | pstats = p->mac->ops->statistics_update(p->mac, | 304 | pstats = p->mac->ops->statistics_update(p->mac, |
293 | MAC_STATS_UPDATE_FULL); | 305 | MAC_STATS_UPDATE_FULL); |
294 | 306 | ||
295 | ns->tx_packets = pstats->TxUnicastFramesOK + | 307 | ns->tx_packets = pstats->TxUnicastFramesOK + |
296 | pstats->TxMulticastFramesOK + pstats->TxBroadcastFramesOK; | 308 | pstats->TxMulticastFramesOK + pstats->TxBroadcastFramesOK; |
@@ -344,47 +356,53 @@ static void set_msglevel(struct net_device *dev, u32 val) | |||
344 | } | 356 | } |
345 | 357 | ||
346 | static char stats_strings[][ETH_GSTRING_LEN] = { | 358 | static char stats_strings[][ETH_GSTRING_LEN] = { |
347 | "TxOctetsOK", | 359 | "TxOctetsOK", |
348 | "TxOctetsBad", | 360 | "TxOctetsBad", |
349 | "TxUnicastFramesOK", | 361 | "TxUnicastFramesOK", |
350 | "TxMulticastFramesOK", | 362 | "TxMulticastFramesOK", |
351 | "TxBroadcastFramesOK", | 363 | "TxBroadcastFramesOK", |
352 | "TxPauseFrames", | 364 | "TxPauseFrames", |
353 | "TxFramesWithDeferredXmissions", | 365 | "TxFramesWithDeferredXmissions", |
354 | "TxLateCollisions", | 366 | "TxLateCollisions", |
355 | "TxTotalCollisions", | 367 | "TxTotalCollisions", |
356 | "TxFramesAbortedDueToXSCollisions", | 368 | "TxFramesAbortedDueToXSCollisions", |
357 | "TxUnderrun", | 369 | "TxUnderrun", |
358 | "TxLengthErrors", | 370 | "TxLengthErrors", |
359 | "TxInternalMACXmitError", | 371 | "TxInternalMACXmitError", |
360 | "TxFramesWithExcessiveDeferral", | 372 | "TxFramesWithExcessiveDeferral", |
361 | "TxFCSErrors", | 373 | "TxFCSErrors", |
362 | 374 | ||
363 | "RxOctetsOK", | 375 | "RxOctetsOK", |
364 | "RxOctetsBad", | 376 | "RxOctetsBad", |
365 | "RxUnicastFramesOK", | 377 | "RxUnicastFramesOK", |
366 | "RxMulticastFramesOK", | 378 | "RxMulticastFramesOK", |
367 | "RxBroadcastFramesOK", | 379 | "RxBroadcastFramesOK", |
368 | "RxPauseFrames", | 380 | "RxPauseFrames", |
369 | "RxFCSErrors", | 381 | "RxFCSErrors", |
370 | "RxAlignErrors", | 382 | "RxAlignErrors", |
371 | "RxSymbolErrors", | 383 | "RxSymbolErrors", |
372 | "RxDataErrors", | 384 | "RxDataErrors", |
373 | "RxSequenceErrors", | 385 | "RxSequenceErrors", |
374 | "RxRuntErrors", | 386 | "RxRuntErrors", |
375 | "RxJabberErrors", | 387 | "RxJabberErrors", |
376 | "RxInternalMACRcvError", | 388 | "RxInternalMACRcvError", |
377 | "RxInRangeLengthErrors", | 389 | "RxInRangeLengthErrors", |
378 | "RxOutOfRangeLengthField", | 390 | "RxOutOfRangeLengthField", |
379 | "RxFrameTooLongErrors", | 391 | "RxFrameTooLongErrors", |
380 | 392 | ||
381 | "TSO", | 393 | /* Port stats */ |
382 | "VLANextractions", | 394 | "RxPackets", |
383 | "VLANinsertions", | ||
384 | "RxCsumGood", | 395 | "RxCsumGood", |
396 | "TxPackets", | ||
385 | "TxCsumOffload", | 397 | "TxCsumOffload", |
386 | "RxDrops" | 398 | "TxTso", |
387 | 399 | "RxVlan", | |
400 | "TxVlan", | ||
401 | |||
402 | /* Interrupt stats */ | ||
403 | "rx drops", | ||
404 | "pure_rsps", | ||
405 | "unhandled irqs", | ||
388 | "respQ_empty", | 406 | "respQ_empty", |
389 | "respQ_overflow", | 407 | "respQ_overflow", |
390 | "freelistQ_empty", | 408 | "freelistQ_empty", |
@@ -392,11 +410,7 @@ static char stats_strings[][ETH_GSTRING_LEN] = { | |||
392 | "pkt_mismatch", | 410 | "pkt_mismatch", |
393 | "cmdQ_full0", | 411 | "cmdQ_full0", |
394 | "cmdQ_full1", | 412 | "cmdQ_full1", |
395 | "tx_ipfrags", | 413 | |
396 | "tx_reg_pkts", | ||
397 | "tx_lso_pkts", | ||
398 | "tx_do_cksum", | ||
399 | |||
400 | "espi_DIP2ParityErr", | 414 | "espi_DIP2ParityErr", |
401 | "espi_DIP4Err", | 415 | "espi_DIP4Err", |
402 | "espi_RxDrops", | 416 | "espi_RxDrops", |
@@ -404,7 +418,7 @@ static char stats_strings[][ETH_GSTRING_LEN] = { | |||
404 | "espi_RxOvfl", | 418 | "espi_RxOvfl", |
405 | "espi_ParityErr" | 419 | "espi_ParityErr" |
406 | }; | 420 | }; |
407 | 421 | ||
408 | #define T2_REGMAP_SIZE (3 * 1024) | 422 | #define T2_REGMAP_SIZE (3 * 1024) |
409 | 423 | ||
410 | static int get_regs_len(struct net_device *dev) | 424 | static int get_regs_len(struct net_device *dev) |
@@ -439,65 +453,77 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats, | |||
439 | struct adapter *adapter = dev->priv; | 453 | struct adapter *adapter = dev->priv; |
440 | struct cmac *mac = adapter->port[dev->if_port].mac; | 454 | struct cmac *mac = adapter->port[dev->if_port].mac; |
441 | const struct cmac_statistics *s; | 455 | const struct cmac_statistics *s; |
442 | const struct sge_port_stats *ss; | ||
443 | const struct sge_intr_counts *t; | 456 | const struct sge_intr_counts *t; |
457 | struct sge_port_stats ss; | ||
444 | 458 | ||
445 | s = mac->ops->statistics_update(mac, MAC_STATS_UPDATE_FULL); | 459 | s = mac->ops->statistics_update(mac, MAC_STATS_UPDATE_FULL); |
446 | ss = t1_sge_get_port_stats(adapter->sge, dev->if_port); | ||
447 | t = t1_sge_get_intr_counts(adapter->sge); | ||
448 | 460 | ||
449 | *data++ = s->TxOctetsOK; | 461 | *data++ = s->TxOctetsOK; |
450 | *data++ = s->TxOctetsBad; | 462 | *data++ = s->TxOctetsBad; |
451 | *data++ = s->TxUnicastFramesOK; | 463 | *data++ = s->TxUnicastFramesOK; |
452 | *data++ = s->TxMulticastFramesOK; | 464 | *data++ = s->TxMulticastFramesOK; |
453 | *data++ = s->TxBroadcastFramesOK; | 465 | *data++ = s->TxBroadcastFramesOK; |
454 | *data++ = s->TxPauseFrames; | 466 | *data++ = s->TxPauseFrames; |
455 | *data++ = s->TxFramesWithDeferredXmissions; | 467 | *data++ = s->TxFramesWithDeferredXmissions; |
456 | *data++ = s->TxLateCollisions; | 468 | *data++ = s->TxLateCollisions; |
457 | *data++ = s->TxTotalCollisions; | 469 | *data++ = s->TxTotalCollisions; |
458 | *data++ = s->TxFramesAbortedDueToXSCollisions; | 470 | *data++ = s->TxFramesAbortedDueToXSCollisions; |
459 | *data++ = s->TxUnderrun; | 471 | *data++ = s->TxUnderrun; |
460 | *data++ = s->TxLengthErrors; | 472 | *data++ = s->TxLengthErrors; |
461 | *data++ = s->TxInternalMACXmitError; | 473 | *data++ = s->TxInternalMACXmitError; |
462 | *data++ = s->TxFramesWithExcessiveDeferral; | 474 | *data++ = s->TxFramesWithExcessiveDeferral; |
463 | *data++ = s->TxFCSErrors; | 475 | *data++ = s->TxFCSErrors; |
464 | 476 | ||
465 | *data++ = s->RxOctetsOK; | 477 | *data++ = s->RxOctetsOK; |
466 | *data++ = s->RxOctetsBad; | 478 | *data++ = s->RxOctetsBad; |
467 | *data++ = s->RxUnicastFramesOK; | 479 | *data++ = s->RxUnicastFramesOK; |
468 | *data++ = s->RxMulticastFramesOK; | 480 | *data++ = s->RxMulticastFramesOK; |
469 | *data++ = s->RxBroadcastFramesOK; | 481 | *data++ = s->RxBroadcastFramesOK; |
470 | *data++ = s->RxPauseFrames; | 482 | *data++ = s->RxPauseFrames; |
471 | *data++ = s->RxFCSErrors; | 483 | *data++ = s->RxFCSErrors; |
472 | *data++ = s->RxAlignErrors; | 484 | *data++ = s->RxAlignErrors; |
473 | *data++ = s->RxSymbolErrors; | 485 | *data++ = s->RxSymbolErrors; |
474 | *data++ = s->RxDataErrors; | 486 | *data++ = s->RxDataErrors; |
475 | *data++ = s->RxSequenceErrors; | 487 | *data++ = s->RxSequenceErrors; |
476 | *data++ = s->RxRuntErrors; | 488 | *data++ = s->RxRuntErrors; |
477 | *data++ = s->RxJabberErrors; | 489 | *data++ = s->RxJabberErrors; |
478 | *data++ = s->RxInternalMACRcvError; | 490 | *data++ = s->RxInternalMACRcvError; |
479 | *data++ = s->RxInRangeLengthErrors; | 491 | *data++ = s->RxInRangeLengthErrors; |
480 | *data++ = s->RxOutOfRangeLengthField; | 492 | *data++ = s->RxOutOfRangeLengthField; |
481 | *data++ = s->RxFrameTooLongErrors; | 493 | *data++ = s->RxFrameTooLongErrors; |
482 | 494 | ||
483 | *data++ = ss->tso; | 495 | t1_sge_get_port_stats(adapter->sge, dev->if_port, &ss); |
484 | *data++ = ss->vlan_xtract; | 496 | *data++ = ss.rx_packets; |
485 | *data++ = ss->vlan_insert; | 497 | *data++ = ss.rx_cso_good; |
486 | *data++ = ss->rx_cso_good; | 498 | *data++ = ss.tx_packets; |
487 | *data++ = ss->tx_cso; | 499 | *data++ = ss.tx_cso; |
488 | *data++ = ss->rx_drops; | 500 | *data++ = ss.tx_tso; |
489 | 501 | *data++ = ss.vlan_xtract; | |
490 | *data++ = (u64)t->respQ_empty; | 502 | *data++ = ss.vlan_insert; |
491 | *data++ = (u64)t->respQ_overflow; | 503 | |
492 | *data++ = (u64)t->freelistQ_empty; | 504 | t = t1_sge_get_intr_counts(adapter->sge); |
493 | *data++ = (u64)t->pkt_too_big; | 505 | *data++ = t->rx_drops; |
494 | *data++ = (u64)t->pkt_mismatch; | 506 | *data++ = t->pure_rsps; |
495 | *data++ = (u64)t->cmdQ_full[0]; | 507 | *data++ = t->unhandled_irqs; |
496 | *data++ = (u64)t->cmdQ_full[1]; | 508 | *data++ = t->respQ_empty; |
497 | *data++ = (u64)t->tx_ipfrags; | 509 | *data++ = t->respQ_overflow; |
498 | *data++ = (u64)t->tx_reg_pkts; | 510 | *data++ = t->freelistQ_empty; |
499 | *data++ = (u64)t->tx_lso_pkts; | 511 | *data++ = t->pkt_too_big; |
500 | *data++ = (u64)t->tx_do_cksum; | 512 | *data++ = t->pkt_mismatch; |
513 | *data++ = t->cmdQ_full[0]; | ||
514 | *data++ = t->cmdQ_full[1]; | ||
515 | |||
516 | if (adapter->espi) { | ||
517 | const struct espi_intr_counts *e; | ||
518 | |||
519 | e = t1_espi_get_intr_counts(adapter->espi); | ||
520 | *data++ = e->DIP2_parity_err; | ||
521 | *data++ = e->DIP4_err; | ||
522 | *data++ = e->rx_drops; | ||
523 | *data++ = e->tx_drops; | ||
524 | *data++ = e->rx_ovflw; | ||
525 | *data++ = e->parity_err; | ||
526 | } | ||
501 | } | 527 | } |
502 | 528 | ||
503 | static inline void reg_block_dump(struct adapter *ap, void *buf, | 529 | static inline void reg_block_dump(struct adapter *ap, void *buf, |
@@ -521,6 +547,15 @@ static void get_regs(struct net_device *dev, struct ethtool_regs *regs, | |||
521 | 547 | ||
522 | memset(buf, 0, T2_REGMAP_SIZE); | 548 | memset(buf, 0, T2_REGMAP_SIZE); |
523 | reg_block_dump(ap, buf, 0, A_SG_RESPACCUTIMER); | 549 | reg_block_dump(ap, buf, 0, A_SG_RESPACCUTIMER); |
550 | reg_block_dump(ap, buf, A_MC3_CFG, A_MC4_INT_CAUSE); | ||
551 | reg_block_dump(ap, buf, A_TPI_ADDR, A_TPI_PAR); | ||
552 | reg_block_dump(ap, buf, A_TP_IN_CONFIG, A_TP_TX_DROP_COUNT); | ||
553 | reg_block_dump(ap, buf, A_RAT_ROUTE_CONTROL, A_RAT_INTR_CAUSE); | ||
554 | reg_block_dump(ap, buf, A_CSPI_RX_AE_WM, A_CSPI_INTR_ENABLE); | ||
555 | reg_block_dump(ap, buf, A_ESPI_SCH_TOKEN0, A_ESPI_GOSTAT); | ||
556 | reg_block_dump(ap, buf, A_ULP_ULIMIT, A_ULP_PIO_CTRL); | ||
557 | reg_block_dump(ap, buf, A_PL_ENABLE, A_PL_CAUSE); | ||
558 | reg_block_dump(ap, buf, A_MC5_CONFIG, A_MC5_MASK_WRITE_CMD); | ||
524 | } | 559 | } |
525 | 560 | ||
526 | static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | 561 | static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd) |
@@ -539,12 +574,12 @@ static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
539 | cmd->duplex = -1; | 574 | cmd->duplex = -1; |
540 | } | 575 | } |
541 | 576 | ||
542 | cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE; | 577 | cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE; |
543 | cmd->phy_address = p->phy->addr; | 578 | cmd->phy_address = p->phy->addr; |
544 | cmd->transceiver = XCVR_EXTERNAL; | 579 | cmd->transceiver = XCVR_EXTERNAL; |
545 | cmd->autoneg = p->link_config.autoneg; | 580 | cmd->autoneg = p->link_config.autoneg; |
546 | cmd->maxtxpkt = 0; | 581 | cmd->maxtxpkt = 0; |
547 | cmd->maxrxpkt = 0; | 582 | cmd->maxrxpkt = 0; |
548 | return 0; | 583 | return 0; |
549 | } | 584 | } |
550 | 585 | ||
@@ -715,7 +750,7 @@ static int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e) | |||
715 | return -EINVAL; | 750 | return -EINVAL; |
716 | 751 | ||
717 | if (adapter->flags & FULL_INIT_DONE) | 752 | if (adapter->flags & FULL_INIT_DONE) |
718 | return -EBUSY; | 753 | return -EBUSY; |
719 | 754 | ||
720 | adapter->params.sge.freelQ_size[!jumbo_fl] = e->rx_pending; | 755 | adapter->params.sge.freelQ_size[!jumbo_fl] = e->rx_pending; |
721 | adapter->params.sge.freelQ_size[jumbo_fl] = e->rx_jumbo_pending; | 756 | adapter->params.sge.freelQ_size[jumbo_fl] = e->rx_jumbo_pending; |
@@ -759,7 +794,9 @@ static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c) | |||
759 | 794 | ||
760 | static int get_eeprom_len(struct net_device *dev) | 795 | static int get_eeprom_len(struct net_device *dev) |
761 | { | 796 | { |
762 | return EEPROM_SIZE; | 797 | struct adapter *adapter = dev->priv; |
798 | |||
799 | return t1_is_asic(adapter) ? EEPROM_SIZE : 0; | ||
763 | } | 800 | } |
764 | 801 | ||
765 | #define EEPROM_MAGIC(ap) \ | 802 | #define EEPROM_MAGIC(ap) \ |
@@ -809,47 +846,36 @@ static const struct ethtool_ops t1_ethtool_ops = { | |||
809 | .set_tso = set_tso, | 846 | .set_tso = set_tso, |
810 | }; | 847 | }; |
811 | 848 | ||
812 | static void cxgb_proc_cleanup(struct adapter *adapter, | ||
813 | struct proc_dir_entry *dir) | ||
814 | { | ||
815 | const char *name; | ||
816 | name = adapter->name; | ||
817 | remove_proc_entry(name, dir); | ||
818 | } | ||
819 | //#define chtoe_setup_toedev(adapter) NULL | ||
820 | #define update_mtu_tab(adapter) | ||
821 | #define write_smt_entry(adapter, idx) | ||
822 | |||
823 | static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd) | 849 | static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd) |
824 | { | 850 | { |
825 | struct adapter *adapter = dev->priv; | 851 | struct adapter *adapter = dev->priv; |
826 | struct mii_ioctl_data *data = if_mii(req); | 852 | struct mii_ioctl_data *data = if_mii(req); |
827 | 853 | ||
828 | switch (cmd) { | 854 | switch (cmd) { |
829 | case SIOCGMIIPHY: | 855 | case SIOCGMIIPHY: |
830 | data->phy_id = adapter->port[dev->if_port].phy->addr; | 856 | data->phy_id = adapter->port[dev->if_port].phy->addr; |
831 | /* FALLTHRU */ | 857 | /* FALLTHRU */ |
832 | case SIOCGMIIREG: { | 858 | case SIOCGMIIREG: { |
833 | struct cphy *phy = adapter->port[dev->if_port].phy; | 859 | struct cphy *phy = adapter->port[dev->if_port].phy; |
834 | u32 val; | 860 | u32 val; |
835 | 861 | ||
836 | if (!phy->mdio_read) | 862 | if (!phy->mdio_read) |
837 | return -EOPNOTSUPP; | 863 | return -EOPNOTSUPP; |
838 | phy->mdio_read(adapter, data->phy_id, 0, data->reg_num & 0x1f, | 864 | phy->mdio_read(adapter, data->phy_id, 0, data->reg_num & 0x1f, |
839 | &val); | 865 | &val); |
840 | data->val_out = val; | 866 | data->val_out = val; |
841 | break; | 867 | break; |
842 | } | 868 | } |
843 | case SIOCSMIIREG: { | 869 | case SIOCSMIIREG: { |
844 | struct cphy *phy = adapter->port[dev->if_port].phy; | 870 | struct cphy *phy = adapter->port[dev->if_port].phy; |
845 | 871 | ||
846 | if (!capable(CAP_NET_ADMIN)) | 872 | if (!capable(CAP_NET_ADMIN)) |
847 | return -EPERM; | 873 | return -EPERM; |
848 | if (!phy->mdio_write) | 874 | if (!phy->mdio_write) |
849 | return -EOPNOTSUPP; | 875 | return -EOPNOTSUPP; |
850 | phy->mdio_write(adapter, data->phy_id, 0, data->reg_num & 0x1f, | 876 | phy->mdio_write(adapter, data->phy_id, 0, data->reg_num & 0x1f, |
851 | data->val_in); | 877 | data->val_in); |
852 | break; | 878 | break; |
853 | } | 879 | } |
854 | 880 | ||
855 | default: | 881 | default: |
@@ -865,9 +891,9 @@ static int t1_change_mtu(struct net_device *dev, int new_mtu) | |||
865 | struct cmac *mac = adapter->port[dev->if_port].mac; | 891 | struct cmac *mac = adapter->port[dev->if_port].mac; |
866 | 892 | ||
867 | if (!mac->ops->set_mtu) | 893 | if (!mac->ops->set_mtu) |
868 | return -EOPNOTSUPP; | 894 | return -EOPNOTSUPP; |
869 | if (new_mtu < 68) | 895 | if (new_mtu < 68) |
870 | return -EINVAL; | 896 | return -EINVAL; |
871 | if ((ret = mac->ops->set_mtu(mac, new_mtu))) | 897 | if ((ret = mac->ops->set_mtu(mac, new_mtu))) |
872 | return ret; | 898 | return ret; |
873 | dev->mtu = new_mtu; | 899 | dev->mtu = new_mtu; |
@@ -918,7 +944,7 @@ static void t1_netpoll(struct net_device *dev) | |||
918 | struct adapter *adapter = dev->priv; | 944 | struct adapter *adapter = dev->priv; |
919 | 945 | ||
920 | local_irq_save(flags); | 946 | local_irq_save(flags); |
921 | t1_select_intr_handler(adapter)(adapter->pdev->irq, adapter); | 947 | t1_select_intr_handler(adapter)(adapter->pdev->irq, adapter); |
922 | local_irq_restore(flags); | 948 | local_irq_restore(flags); |
923 | } | 949 | } |
924 | #endif | 950 | #endif |
@@ -957,14 +983,14 @@ static void ext_intr_task(struct work_struct *work) | |||
957 | struct adapter *adapter = | 983 | struct adapter *adapter = |
958 | container_of(work, struct adapter, ext_intr_handler_task); | 984 | container_of(work, struct adapter, ext_intr_handler_task); |
959 | 985 | ||
960 | elmer0_ext_intr_handler(adapter); | 986 | t1_elmer0_ext_intr_handler(adapter); |
961 | 987 | ||
962 | /* Now reenable external interrupts */ | 988 | /* Now reenable external interrupts */ |
963 | spin_lock_irq(&adapter->async_lock); | 989 | spin_lock_irq(&adapter->async_lock); |
964 | adapter->slow_intr_mask |= F_PL_INTR_EXT; | 990 | adapter->slow_intr_mask |= F_PL_INTR_EXT; |
965 | writel(F_PL_INTR_EXT, adapter->regs + A_PL_CAUSE); | 991 | writel(F_PL_INTR_EXT, adapter->regs + A_PL_CAUSE); |
966 | writel(adapter->slow_intr_mask | F_PL_INTR_SGE_DATA, | 992 | writel(adapter->slow_intr_mask | F_PL_INTR_SGE_DATA, |
967 | adapter->regs + A_PL_ENABLE); | 993 | adapter->regs + A_PL_ENABLE); |
968 | spin_unlock_irq(&adapter->async_lock); | 994 | spin_unlock_irq(&adapter->async_lock); |
969 | } | 995 | } |
970 | 996 | ||
@@ -980,7 +1006,7 @@ void t1_elmer0_ext_intr(struct adapter *adapter) | |||
980 | */ | 1006 | */ |
981 | adapter->slow_intr_mask &= ~F_PL_INTR_EXT; | 1007 | adapter->slow_intr_mask &= ~F_PL_INTR_EXT; |
982 | writel(adapter->slow_intr_mask | F_PL_INTR_SGE_DATA, | 1008 | writel(adapter->slow_intr_mask | F_PL_INTR_SGE_DATA, |
983 | adapter->regs + A_PL_ENABLE); | 1009 | adapter->regs + A_PL_ENABLE); |
984 | schedule_work(&adapter->ext_intr_handler_task); | 1010 | schedule_work(&adapter->ext_intr_handler_task); |
985 | } | 1011 | } |
986 | 1012 | ||
@@ -1013,7 +1039,7 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
1013 | 1039 | ||
1014 | err = pci_enable_device(pdev); | 1040 | err = pci_enable_device(pdev); |
1015 | if (err) | 1041 | if (err) |
1016 | return err; | 1042 | return err; |
1017 | 1043 | ||
1018 | if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { | 1044 | if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { |
1019 | CH_ERR("%s: cannot find PCI device memory base address\n", | 1045 | CH_ERR("%s: cannot find PCI device memory base address\n", |
@@ -1045,7 +1071,7 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
1045 | 1071 | ||
1046 | pci_set_master(pdev); | 1072 | pci_set_master(pdev); |
1047 | 1073 | ||
1048 | mmio_start = pci_resource_start(pdev, 0); | 1074 | mmio_start = pci_resource_start(pdev, 0); |
1049 | mmio_len = pci_resource_len(pdev, 0); | 1075 | mmio_len = pci_resource_len(pdev, 0); |
1050 | bi = t1_get_board_info(ent->driver_data); | 1076 | bi = t1_get_board_info(ent->driver_data); |
1051 | 1077 | ||
@@ -1083,21 +1109,15 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
1083 | adapter->msg_enable = dflt_msg_enable; | 1109 | adapter->msg_enable = dflt_msg_enable; |
1084 | adapter->mmio_len = mmio_len; | 1110 | adapter->mmio_len = mmio_len; |
1085 | 1111 | ||
1086 | init_MUTEX(&adapter->mib_mutex); | ||
1087 | spin_lock_init(&adapter->tpi_lock); | 1112 | spin_lock_init(&adapter->tpi_lock); |
1088 | spin_lock_init(&adapter->work_lock); | 1113 | spin_lock_init(&adapter->work_lock); |
1089 | spin_lock_init(&adapter->async_lock); | 1114 | spin_lock_init(&adapter->async_lock); |
1115 | spin_lock_init(&adapter->mac_lock); | ||
1090 | 1116 | ||
1091 | INIT_WORK(&adapter->ext_intr_handler_task, | 1117 | INIT_WORK(&adapter->ext_intr_handler_task, |
1092 | ext_intr_task); | 1118 | ext_intr_task); |
1093 | INIT_DELAYED_WORK(&adapter->stats_update_task, | 1119 | INIT_DELAYED_WORK(&adapter->stats_update_task, |
1094 | mac_stats_task); | 1120 | mac_stats_task); |
1095 | #ifdef work_struct | ||
1096 | init_timer(&adapter->stats_update_timer); | ||
1097 | adapter->stats_update_timer.function = mac_stats_timer; | ||
1098 | adapter->stats_update_timer.data = | ||
1099 | (unsigned long)adapter; | ||
1100 | #endif | ||
1101 | 1121 | ||
1102 | pci_set_drvdata(pdev, netdev); | 1122 | pci_set_drvdata(pdev, netdev); |
1103 | } | 1123 | } |
@@ -1124,16 +1144,19 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
1124 | netdev->vlan_rx_register = vlan_rx_register; | 1144 | netdev->vlan_rx_register = vlan_rx_register; |
1125 | netdev->vlan_rx_kill_vid = vlan_rx_kill_vid; | 1145 | netdev->vlan_rx_kill_vid = vlan_rx_kill_vid; |
1126 | #endif | 1146 | #endif |
1127 | adapter->flags |= TSO_CAPABLE; | 1147 | |
1128 | netdev->features |= NETIF_F_TSO; | 1148 | /* T204: disable TSO */ |
1149 | if (!(is_T2(adapter)) || bi->port_number != 4) { | ||
1150 | adapter->flags |= TSO_CAPABLE; | ||
1151 | netdev->features |= NETIF_F_TSO; | ||
1152 | } | ||
1129 | } | 1153 | } |
1130 | 1154 | ||
1131 | netdev->open = cxgb_open; | 1155 | netdev->open = cxgb_open; |
1132 | netdev->stop = cxgb_close; | 1156 | netdev->stop = cxgb_close; |
1133 | netdev->hard_start_xmit = t1_start_xmit; | 1157 | netdev->hard_start_xmit = t1_start_xmit; |
1134 | netdev->hard_header_len += (adapter->flags & TSO_CAPABLE) ? | 1158 | netdev->hard_header_len += (adapter->flags & TSO_CAPABLE) ? |
1135 | sizeof(struct cpl_tx_pkt_lso) : | 1159 | sizeof(struct cpl_tx_pkt_lso) : sizeof(struct cpl_tx_pkt); |
1136 | sizeof(struct cpl_tx_pkt); | ||
1137 | netdev->get_stats = t1_get_stats; | 1160 | netdev->get_stats = t1_get_stats; |
1138 | netdev->set_multicast_list = t1_set_rxmode; | 1161 | netdev->set_multicast_list = t1_set_rxmode; |
1139 | netdev->do_ioctl = t1_ioctl; | 1162 | netdev->do_ioctl = t1_ioctl; |
@@ -1144,7 +1167,7 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
1144 | #endif | 1167 | #endif |
1145 | netdev->weight = 64; | 1168 | netdev->weight = 64; |
1146 | 1169 | ||
1147 | SET_ETHTOOL_OPS(netdev, &t1_ethtool_ops); | 1170 | SET_ETHTOOL_OPS(netdev, &t1_ethtool_ops); |
1148 | } | 1171 | } |
1149 | 1172 | ||
1150 | if (t1_init_sw_modules(adapter, bi) < 0) { | 1173 | if (t1_init_sw_modules(adapter, bi) < 0) { |
@@ -1171,7 +1194,7 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
1171 | if (!adapter->registered_device_map) | 1194 | if (!adapter->registered_device_map) |
1172 | adapter->name = adapter->port[i].dev->name; | 1195 | adapter->name = adapter->port[i].dev->name; |
1173 | 1196 | ||
1174 | __set_bit(i, &adapter->registered_device_map); | 1197 | __set_bit(i, &adapter->registered_device_map); |
1175 | } | 1198 | } |
1176 | } | 1199 | } |
1177 | if (!adapter->registered_device_map) { | 1200 | if (!adapter->registered_device_map) { |
@@ -1184,18 +1207,28 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
1184 | bi->desc, adapter->params.chip_revision, | 1207 | bi->desc, adapter->params.chip_revision, |
1185 | adapter->params.pci.is_pcix ? "PCIX" : "PCI", | 1208 | adapter->params.pci.is_pcix ? "PCIX" : "PCI", |
1186 | adapter->params.pci.speed, adapter->params.pci.width); | 1209 | adapter->params.pci.speed, adapter->params.pci.width); |
1210 | |||
1211 | /* | ||
1212 | * Set the T1B ASIC and memory clocks. | ||
1213 | */ | ||
1214 | if (t1powersave) | ||
1215 | adapter->t1powersave = LCLOCK; /* HW default is powersave mode. */ | ||
1216 | else | ||
1217 | adapter->t1powersave = HCLOCK; | ||
1218 | if (t1_is_T1B(adapter)) | ||
1219 | t1_clock(adapter, t1powersave); | ||
1220 | |||
1187 | return 0; | 1221 | return 0; |
1188 | 1222 | ||
1189 | out_release_adapter_res: | 1223 | out_release_adapter_res: |
1190 | t1_free_sw_modules(adapter); | 1224 | t1_free_sw_modules(adapter); |
1191 | out_free_dev: | 1225 | out_free_dev: |
1192 | if (adapter) { | 1226 | if (adapter) { |
1193 | if (adapter->regs) iounmap(adapter->regs); | 1227 | if (adapter->regs) |
1228 | iounmap(adapter->regs); | ||
1194 | for (i = bi->port_number - 1; i >= 0; --i) | 1229 | for (i = bi->port_number - 1; i >= 0; --i) |
1195 | if (adapter->port[i].dev) { | 1230 | if (adapter->port[i].dev) |
1196 | cxgb_proc_cleanup(adapter, proc_root_driver); | 1231 | free_netdev(adapter->port[i].dev); |
1197 | kfree(adapter->port[i].dev); | ||
1198 | } | ||
1199 | } | 1232 | } |
1200 | pci_release_regions(pdev); | 1233 | pci_release_regions(pdev); |
1201 | out_disable_pdev: | 1234 | out_disable_pdev: |
@@ -1204,6 +1237,155 @@ static int __devinit init_one(struct pci_dev *pdev, | |||
1204 | return err; | 1237 | return err; |
1205 | } | 1238 | } |
1206 | 1239 | ||
1240 | static void bit_bang(struct adapter *adapter, int bitdata, int nbits) | ||
1241 | { | ||
1242 | int data; | ||
1243 | int i; | ||
1244 | u32 val; | ||
1245 | |||
1246 | enum { | ||
1247 | S_CLOCK = 1 << 3, | ||
1248 | S_DATA = 1 << 4 | ||
1249 | }; | ||
1250 | |||
1251 | for (i = (nbits - 1); i > -1; i--) { | ||
1252 | |||
1253 | udelay(50); | ||
1254 | |||
1255 | data = ((bitdata >> i) & 0x1); | ||
1256 | __t1_tpi_read(adapter, A_ELMER0_GPO, &val); | ||
1257 | |||
1258 | if (data) | ||
1259 | val |= S_DATA; | ||
1260 | else | ||
1261 | val &= ~S_DATA; | ||
1262 | |||
1263 | udelay(50); | ||
1264 | |||
1265 | /* Set SCLOCK low */ | ||
1266 | val &= ~S_CLOCK; | ||
1267 | __t1_tpi_write(adapter, A_ELMER0_GPO, val); | ||
1268 | |||
1269 | udelay(50); | ||
1270 | |||
1271 | /* Write SCLOCK high */ | ||
1272 | val |= S_CLOCK; | ||
1273 | __t1_tpi_write(adapter, A_ELMER0_GPO, val); | ||
1274 | |||
1275 | } | ||
1276 | } | ||
1277 | |||
1278 | static int t1_clock(struct adapter *adapter, int mode) | ||
1279 | { | ||
1280 | u32 val; | ||
1281 | int M_CORE_VAL; | ||
1282 | int M_MEM_VAL; | ||
1283 | |||
1284 | enum { | ||
1285 | M_CORE_BITS = 9, | ||
1286 | T_CORE_VAL = 0, | ||
1287 | T_CORE_BITS = 2, | ||
1288 | N_CORE_VAL = 0, | ||
1289 | N_CORE_BITS = 2, | ||
1290 | M_MEM_BITS = 9, | ||
1291 | T_MEM_VAL = 0, | ||
1292 | T_MEM_BITS = 2, | ||
1293 | N_MEM_VAL = 0, | ||
1294 | N_MEM_BITS = 2, | ||
1295 | NP_LOAD = 1 << 17, | ||
1296 | S_LOAD_MEM = 1 << 5, | ||
1297 | S_LOAD_CORE = 1 << 6, | ||
1298 | S_CLOCK = 1 << 3 | ||
1299 | }; | ||
1300 | |||
1301 | if (!t1_is_T1B(adapter)) | ||
1302 | return -ENODEV; /* Can't re-clock this chip. */ | ||
1303 | |||
1304 | if (mode & 2) { | ||
1305 | return 0; /* show current mode. */ | ||
1306 | } | ||
1307 | |||
1308 | if ((adapter->t1powersave & 1) == (mode & 1)) | ||
1309 | return -EALREADY; /* ASIC already running in mode. */ | ||
1310 | |||
1311 | if ((mode & 1) == HCLOCK) { | ||
1312 | M_CORE_VAL = 0x14; | ||
1313 | M_MEM_VAL = 0x18; | ||
1314 | adapter->t1powersave = HCLOCK; /* overclock */ | ||
1315 | } else { | ||
1316 | M_CORE_VAL = 0xe; | ||
1317 | M_MEM_VAL = 0x10; | ||
1318 | adapter->t1powersave = LCLOCK; /* underclock */ | ||
1319 | } | ||
1320 | |||
1321 | /* Don't interrupt this serial stream! */ | ||
1322 | spin_lock(&adapter->tpi_lock); | ||
1323 | |||
1324 | /* Initialize for ASIC core */ | ||
1325 | __t1_tpi_read(adapter, A_ELMER0_GPO, &val); | ||
1326 | val |= NP_LOAD; | ||
1327 | udelay(50); | ||
1328 | __t1_tpi_write(adapter, A_ELMER0_GPO, val); | ||
1329 | udelay(50); | ||
1330 | __t1_tpi_read(adapter, A_ELMER0_GPO, &val); | ||
1331 | val &= ~S_LOAD_CORE; | ||
1332 | val &= ~S_CLOCK; | ||
1333 | __t1_tpi_write(adapter, A_ELMER0_GPO, val); | ||
1334 | udelay(50); | ||
1335 | |||
1336 | /* Serial program the ASIC clock synthesizer */ | ||
1337 | bit_bang(adapter, T_CORE_VAL, T_CORE_BITS); | ||
1338 | bit_bang(adapter, N_CORE_VAL, N_CORE_BITS); | ||
1339 | bit_bang(adapter, M_CORE_VAL, M_CORE_BITS); | ||
1340 | udelay(50); | ||
1341 | |||
1342 | /* Finish ASIC core */ | ||
1343 | __t1_tpi_read(adapter, A_ELMER0_GPO, &val); | ||
1344 | val |= S_LOAD_CORE; | ||
1345 | udelay(50); | ||
1346 | __t1_tpi_write(adapter, A_ELMER0_GPO, val); | ||
1347 | udelay(50); | ||
1348 | __t1_tpi_read(adapter, A_ELMER0_GPO, &val); | ||
1349 | val &= ~S_LOAD_CORE; | ||
1350 | udelay(50); | ||
1351 | __t1_tpi_write(adapter, A_ELMER0_GPO, val); | ||
1352 | udelay(50); | ||
1353 | |||
1354 | /* Initialize for memory */ | ||
1355 | __t1_tpi_read(adapter, A_ELMER0_GPO, &val); | ||
1356 | val |= NP_LOAD; | ||
1357 | udelay(50); | ||
1358 | __t1_tpi_write(adapter, A_ELMER0_GPO, val); | ||
1359 | udelay(50); | ||
1360 | __t1_tpi_read(adapter, A_ELMER0_GPO, &val); | ||
1361 | val &= ~S_LOAD_MEM; | ||
1362 | val &= ~S_CLOCK; | ||
1363 | udelay(50); | ||
1364 | __t1_tpi_write(adapter, A_ELMER0_GPO, val); | ||
1365 | udelay(50); | ||
1366 | |||
1367 | /* Serial program the memory clock synthesizer */ | ||
1368 | bit_bang(adapter, T_MEM_VAL, T_MEM_BITS); | ||
1369 | bit_bang(adapter, N_MEM_VAL, N_MEM_BITS); | ||
1370 | bit_bang(adapter, M_MEM_VAL, M_MEM_BITS); | ||
1371 | udelay(50); | ||
1372 | |||
1373 | /* Finish memory */ | ||
1374 | __t1_tpi_read(adapter, A_ELMER0_GPO, &val); | ||
1375 | val |= S_LOAD_MEM; | ||
1376 | udelay(50); | ||
1377 | __t1_tpi_write(adapter, A_ELMER0_GPO, val); | ||
1378 | udelay(50); | ||
1379 | __t1_tpi_read(adapter, A_ELMER0_GPO, &val); | ||
1380 | val &= ~S_LOAD_MEM; | ||
1381 | udelay(50); | ||
1382 | __t1_tpi_write(adapter, A_ELMER0_GPO, val); | ||
1383 | |||
1384 | spin_unlock(&adapter->tpi_lock); | ||
1385 | |||
1386 | return 0; | ||
1387 | } | ||
1388 | |||
1207 | static inline void t1_sw_reset(struct pci_dev *pdev) | 1389 | static inline void t1_sw_reset(struct pci_dev *pdev) |
1208 | { | 1390 | { |
1209 | pci_write_config_dword(pdev, A_PCICFG_PM_CSR, 3); | 1391 | pci_write_config_dword(pdev, A_PCICFG_PM_CSR, 3); |
@@ -1225,10 +1407,9 @@ static void __devexit remove_one(struct pci_dev *pdev) | |||
1225 | t1_free_sw_modules(adapter); | 1407 | t1_free_sw_modules(adapter); |
1226 | iounmap(adapter->regs); | 1408 | iounmap(adapter->regs); |
1227 | while (--i >= 0) | 1409 | while (--i >= 0) |
1228 | if (adapter->port[i].dev) { | 1410 | if (adapter->port[i].dev) |
1229 | cxgb_proc_cleanup(adapter, proc_root_driver); | 1411 | free_netdev(adapter->port[i].dev); |
1230 | kfree(adapter->port[i].dev); | 1412 | |
1231 | } | ||
1232 | pci_release_regions(pdev); | 1413 | pci_release_regions(pdev); |
1233 | pci_disable_device(pdev); | 1414 | pci_disable_device(pdev); |
1234 | pci_set_drvdata(pdev, NULL); | 1415 | pci_set_drvdata(pdev, NULL); |