aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/chelsio/cxgb2.c
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2006-12-01 19:36:16 -0500
committerJeff Garzik <jeff@garzik.org>2006-12-02 00:24:49 -0500
commitf1d3d38af75789f1b82969b83b69cab540609789 (patch)
tree47d31e8a55fb65cf33797197b92a332630cfc3ef /drivers/net/chelsio/cxgb2.c
parent415294ecbb32ddbd0a7a2b7bae0b60fedfa09cc4 (diff)
[PATCH] chelsio: add support for other 10G boards
Add support for other versions of the 10G Chelsio boards. This is basically a port of the vendor driver with the TOE features removed. Signed-off-by: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/chelsio/cxgb2.c')
-rw-r--r--drivers/net/chelsio/cxgb2.c238
1 files changed, 226 insertions, 12 deletions
diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c
index 42ad9cfd670a..a8c873b0af54 100644
--- a/drivers/net/chelsio/cxgb2.c
+++ b/drivers/net/chelsio/cxgb2.c
@@ -53,7 +53,9 @@
53#include "gmac.h" 53#include "gmac.h"
54#include "cphy.h" 54#include "cphy.h"
55#include "sge.h" 55#include "sge.h"
56#include "tp.h"
56#include "espi.h" 57#include "espi.h"
58#include "elmer0.h"
57 59
58#include <linux/workqueue.h> 60#include <linux/workqueue.h>
59 61
@@ -73,10 +75,9 @@ static inline void cancel_mac_stats_update(struct adapter *ap)
73#define MAX_RX_JUMBO_BUFFERS 16384 75#define MAX_RX_JUMBO_BUFFERS 16384
74#define MAX_TX_BUFFERS_HIGH 16384U 76#define MAX_TX_BUFFERS_HIGH 16384U
75#define MAX_TX_BUFFERS_LOW 1536U 77#define MAX_TX_BUFFERS_LOW 1536U
78#define MAX_TX_BUFFERS 1460U
76#define MIN_FL_ENTRIES 32 79#define MIN_FL_ENTRIES 32
77 80
78#define PORT_MASK ((1 << MAX_NPORTS) - 1)
79
80#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 | \
81 NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP |\ 82 NETIF_MSG_TIMER | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP |\
82 NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) 83 NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
@@ -94,8 +95,17 @@ MODULE_LICENSE("GPL");
94static int dflt_msg_enable = DFLT_MSG_ENABLE; 95static int dflt_msg_enable = DFLT_MSG_ENABLE;
95 96
96module_param(dflt_msg_enable, int, 0); 97module_param(dflt_msg_enable, int, 0);
97MODULE_PARM_DESC(dflt_msg_enable, "Chelsio T1 message enable bitmap"); 98MODULE_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 */
104static int t1_clock(struct adapter *adapter, int mode);
105static int t1powersave = 1; /* HW default is powersave mode. */
98 106
107module_param(t1powersave, int, 0);
108MODULE_PARM_DESC(t1powersave, "Enable/Disable T1 powersaving mode");
99 109
100static const char pci_speed[][4] = { 110static const char pci_speed[][4] = {
101 "33", "66", "100", "133" 111 "33", "66", "100", "133"
@@ -135,7 +145,7 @@ static void link_report(struct port_info *p)
135 } 145 }
136} 146}
137 147
138void t1_link_changed(struct adapter *adapter, int port_id, int link_stat, 148void t1_link_negotiated(struct adapter *adapter, int port_id, int link_stat,
139 int speed, int duplex, int pause) 149 int speed, int duplex, int pause)
140{ 150{
141 struct port_info *p = &adapter->port[port_id]; 151 struct port_info *p = &adapter->port[port_id];
@@ -147,6 +157,22 @@ void t1_link_changed(struct adapter *adapter, int port_id, int link_stat,
147 netif_carrier_off(p->dev); 157 netif_carrier_off(p->dev);
148 link_report(p); 158 link_report(p);
149 159
160 /* multi-ports: inform toe */
161 if ((speed > 0) && (adapter->params.nports > 1)) {
162 unsigned int sched_speed = 10;
163 switch (speed) {
164 case SPEED_1000:
165 sched_speed = 1000;
166 break;
167 case SPEED_100:
168 sched_speed = 100;
169 break;
170 case SPEED_10:
171 sched_speed = 10;
172 break;
173 }
174 t1_sched_update_parms(adapter->sge, port_id, 0, sched_speed);
175 }
150 } 176 }
151} 177}
152 178
@@ -165,8 +191,10 @@ static void link_start(struct port_info *p)
165static void enable_hw_csum(struct adapter *adapter) 191static void enable_hw_csum(struct adapter *adapter)
166{ 192{
167 if (adapter->flags & TSO_CAPABLE) 193 if (adapter->flags & TSO_CAPABLE)
168 t1_tp_set_ip_checksum_offload(adapter, 1); /* for TSO only */ 194 t1_tp_set_ip_checksum_offload(adapter->tp, 1); /* for TSO only */
169 t1_tp_set_tcp_checksum_offload(adapter, 1); 195 if (adapter->flags & UDP_CSUM_CAPABLE)
196 t1_tp_set_udp_checksum_offload(adapter->tp, 1);
197 t1_tp_set_tcp_checksum_offload(adapter->tp, 1);
170} 198}
171 199
172/* 200/*
@@ -468,6 +496,18 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats,
468 *data++ = (u64)t->tx_reg_pkts; 496 *data++ = (u64)t->tx_reg_pkts;
469 *data++ = (u64)t->tx_lso_pkts; 497 *data++ = (u64)t->tx_lso_pkts;
470 *data++ = (u64)t->tx_do_cksum; 498 *data++ = (u64)t->tx_do_cksum;
499
500 if (adapter->espi) {
501 const struct espi_intr_counts *e;
502
503 e = t1_espi_get_intr_counts(adapter->espi);
504 *data++ = (u64) e->DIP2_parity_err;
505 *data++ = (u64) e->DIP4_err;
506 *data++ = (u64) e->rx_drops;
507 *data++ = (u64) e->tx_drops;
508 *data++ = (u64) e->rx_ovflw;
509 *data++ = (u64) e->parity_err;
510 }
471} 511}
472 512
473static inline void reg_block_dump(struct adapter *ap, void *buf, 513static inline void reg_block_dump(struct adapter *ap, void *buf,
@@ -491,6 +531,15 @@ static void get_regs(struct net_device *dev, struct ethtool_regs *regs,
491 531
492 memset(buf, 0, T2_REGMAP_SIZE); 532 memset(buf, 0, T2_REGMAP_SIZE);
493 reg_block_dump(ap, buf, 0, A_SG_RESPACCUTIMER); 533 reg_block_dump(ap, buf, 0, A_SG_RESPACCUTIMER);
534 reg_block_dump(ap, buf, A_MC3_CFG, A_MC4_INT_CAUSE);
535 reg_block_dump(ap, buf, A_TPI_ADDR, A_TPI_PAR);
536 reg_block_dump(ap, buf, A_TP_IN_CONFIG, A_TP_TX_DROP_COUNT);
537 reg_block_dump(ap, buf, A_RAT_ROUTE_CONTROL, A_RAT_INTR_CAUSE);
538 reg_block_dump(ap, buf, A_CSPI_RX_AE_WM, A_CSPI_INTR_ENABLE);
539 reg_block_dump(ap, buf, A_ESPI_SCH_TOKEN0, A_ESPI_GOSTAT);
540 reg_block_dump(ap, buf, A_ULP_ULIMIT, A_ULP_PIO_CTRL);
541 reg_block_dump(ap, buf, A_PL_ENABLE, A_PL_CAUSE);
542 reg_block_dump(ap, buf, A_MC5_CONFIG, A_MC5_MASK_WRITE_CMD);
494} 543}
495 544
496static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd) 545static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
@@ -729,7 +778,9 @@ static int get_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
729 778
730static int get_eeprom_len(struct net_device *dev) 779static int get_eeprom_len(struct net_device *dev)
731{ 780{
732 return EEPROM_SIZE; 781 struct adapter *adapter = dev->priv;
782
783 return t1_is_asic(adapter) ? EEPROM_SIZE : 0;
733} 784}
734 785
735#define EEPROM_MAGIC(ap) \ 786#define EEPROM_MAGIC(ap) \
@@ -914,7 +965,7 @@ static void ext_intr_task(void *data)
914{ 965{
915 struct adapter *adapter = data; 966 struct adapter *adapter = data;
916 967
917 elmer0_ext_intr_handler(adapter); 968 t1_elmer0_ext_intr_handler(adapter);
918 969
919 /* Now reenable external interrupts */ 970 /* Now reenable external interrupts */
920 spin_lock_irq(&adapter->async_lock); 971 spin_lock_irq(&adapter->async_lock);
@@ -1074,16 +1125,19 @@ static int __devinit init_one(struct pci_dev *pdev,
1074 netdev->vlan_rx_register = vlan_rx_register; 1125 netdev->vlan_rx_register = vlan_rx_register;
1075 netdev->vlan_rx_kill_vid = vlan_rx_kill_vid; 1126 netdev->vlan_rx_kill_vid = vlan_rx_kill_vid;
1076#endif 1127#endif
1077 adapter->flags |= TSO_CAPABLE; 1128
1078 netdev->features |= NETIF_F_TSO; 1129 /* T204: disable TSO */
1130 if (!(is_T2(adapter)) || bi->port_number != 4) {
1131 adapter->flags |= TSO_CAPABLE;
1132 netdev->features |= NETIF_F_TSO;
1133 }
1079 } 1134 }
1080 1135
1081 netdev->open = cxgb_open; 1136 netdev->open = cxgb_open;
1082 netdev->stop = cxgb_close; 1137 netdev->stop = cxgb_close;
1083 netdev->hard_start_xmit = t1_start_xmit; 1138 netdev->hard_start_xmit = t1_start_xmit;
1084 netdev->hard_header_len += (adapter->flags & TSO_CAPABLE) ? 1139 netdev->hard_header_len += (adapter->flags & TSO_CAPABLE) ?
1085 sizeof(struct cpl_tx_pkt_lso) : 1140 sizeof(struct cpl_tx_pkt_lso) : sizeof(struct cpl_tx_pkt);
1086 sizeof(struct cpl_tx_pkt);
1087 netdev->get_stats = t1_get_stats; 1141 netdev->get_stats = t1_get_stats;
1088 netdev->set_multicast_list = t1_set_rxmode; 1142 netdev->set_multicast_list = t1_set_rxmode;
1089 netdev->do_ioctl = t1_ioctl; 1143 netdev->do_ioctl = t1_ioctl;
@@ -1134,6 +1188,17 @@ static int __devinit init_one(struct pci_dev *pdev,
1134 bi->desc, adapter->params.chip_revision, 1188 bi->desc, adapter->params.chip_revision,
1135 adapter->params.pci.is_pcix ? "PCIX" : "PCI", 1189 adapter->params.pci.is_pcix ? "PCIX" : "PCI",
1136 adapter->params.pci.speed, adapter->params.pci.width); 1190 adapter->params.pci.speed, adapter->params.pci.width);
1191
1192 /*
1193 * Set the T1B ASIC and memory clocks.
1194 */
1195 if (t1powersave)
1196 adapter->t1powersave = LCLOCK; /* HW default is powersave mode. */
1197 else
1198 adapter->t1powersave = HCLOCK;
1199 if (t1_is_T1B(adapter))
1200 t1_clock(adapter, t1powersave);
1201
1137 return 0; 1202 return 0;
1138 1203
1139 out_release_adapter_res: 1204 out_release_adapter_res:
@@ -1153,6 +1218,155 @@ static int __devinit init_one(struct pci_dev *pdev,
1153 return err; 1218 return err;
1154} 1219}
1155 1220
1221static void bit_bang(struct adapter *adapter, int bitdata, int nbits)
1222{
1223 int data;
1224 int i;
1225 u32 val;
1226
1227 enum {
1228 S_CLOCK = 1 << 3,
1229 S_DATA = 1 << 4
1230 };
1231
1232 for (i = (nbits - 1); i > -1; i--) {
1233
1234 udelay(50);
1235
1236 data = ((bitdata >> i) & 0x1);
1237 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1238
1239 if (data)
1240 val |= S_DATA;
1241 else
1242 val &= ~S_DATA;
1243
1244 udelay(50);
1245
1246 /* Set SCLOCK low */
1247 val &= ~S_CLOCK;
1248 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1249
1250 udelay(50);
1251
1252 /* Write SCLOCK high */
1253 val |= S_CLOCK;
1254 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1255
1256 }
1257}
1258
1259static int t1_clock(struct adapter *adapter, int mode)
1260{
1261 u32 val;
1262 int M_CORE_VAL;
1263 int M_MEM_VAL;
1264
1265 enum {
1266 M_CORE_BITS = 9,
1267 T_CORE_VAL = 0,
1268 T_CORE_BITS = 2,
1269 N_CORE_VAL = 0,
1270 N_CORE_BITS = 2,
1271 M_MEM_BITS = 9,
1272 T_MEM_VAL = 0,
1273 T_MEM_BITS = 2,
1274 N_MEM_VAL = 0,
1275 N_MEM_BITS = 2,
1276 NP_LOAD = 1 << 17,
1277 S_LOAD_MEM = 1 << 5,
1278 S_LOAD_CORE = 1 << 6,
1279 S_CLOCK = 1 << 3
1280 };
1281
1282 if (!t1_is_T1B(adapter))
1283 return -ENODEV; /* Can't re-clock this chip. */
1284
1285 if (mode & 2) {
1286 return 0; /* show current mode. */
1287 }
1288
1289 if ((adapter->t1powersave & 1) == (mode & 1))
1290 return -EALREADY; /* ASIC already running in mode. */
1291
1292 if ((mode & 1) == HCLOCK) {
1293 M_CORE_VAL = 0x14;
1294 M_MEM_VAL = 0x18;
1295 adapter->t1powersave = HCLOCK; /* overclock */
1296 } else {
1297 M_CORE_VAL = 0xe;
1298 M_MEM_VAL = 0x10;
1299 adapter->t1powersave = LCLOCK; /* underclock */
1300 }
1301
1302 /* Don't interrupt this serial stream! */
1303 spin_lock(&adapter->tpi_lock);
1304
1305 /* Initialize for ASIC core */
1306 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1307 val |= NP_LOAD;
1308 udelay(50);
1309 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1310 udelay(50);
1311 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1312 val &= ~S_LOAD_CORE;
1313 val &= ~S_CLOCK;
1314 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1315 udelay(50);
1316
1317 /* Serial program the ASIC clock synthesizer */
1318 bit_bang(adapter, T_CORE_VAL, T_CORE_BITS);
1319 bit_bang(adapter, N_CORE_VAL, N_CORE_BITS);
1320 bit_bang(adapter, M_CORE_VAL, M_CORE_BITS);
1321 udelay(50);
1322
1323 /* Finish ASIC core */
1324 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1325 val |= S_LOAD_CORE;
1326 udelay(50);
1327 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1328 udelay(50);
1329 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1330 val &= ~S_LOAD_CORE;
1331 udelay(50);
1332 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1333 udelay(50);
1334
1335 /* Initialize for memory */
1336 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1337 val |= NP_LOAD;
1338 udelay(50);
1339 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1340 udelay(50);
1341 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1342 val &= ~S_LOAD_MEM;
1343 val &= ~S_CLOCK;
1344 udelay(50);
1345 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1346 udelay(50);
1347
1348 /* Serial program the memory clock synthesizer */
1349 bit_bang(adapter, T_MEM_VAL, T_MEM_BITS);
1350 bit_bang(adapter, N_MEM_VAL, N_MEM_BITS);
1351 bit_bang(adapter, M_MEM_VAL, M_MEM_BITS);
1352 udelay(50);
1353
1354 /* Finish memory */
1355 __t1_tpi_read(adapter, A_ELMER0_GPO, &val);
1356 val |= S_LOAD_MEM;
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 udelay(50);
1363 __t1_tpi_write(adapter, A_ELMER0_GPO, val);
1364
1365 spin_unlock(&adapter->tpi_lock);
1366
1367 return 0;
1368}
1369
1156static inline void t1_sw_reset(struct pci_dev *pdev) 1370static inline void t1_sw_reset(struct pci_dev *pdev)
1157{ 1371{
1158 pci_write_config_dword(pdev, A_PCICFG_PM_CSR, 3); 1372 pci_write_config_dword(pdev, A_PCICFG_PM_CSR, 3);