diff options
Diffstat (limited to 'drivers/net/chelsio/subr.c')
-rw-r--r-- | drivers/net/chelsio/subr.c | 494 |
1 files changed, 390 insertions, 104 deletions
diff --git a/drivers/net/chelsio/subr.c b/drivers/net/chelsio/subr.c index 12e4e96dba2d..22ed9a383c08 100644 --- a/drivers/net/chelsio/subr.c +++ b/drivers/net/chelsio/subr.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include "gmac.h" | 43 | #include "gmac.h" |
44 | #include "cphy.h" | 44 | #include "cphy.h" |
45 | #include "sge.h" | 45 | #include "sge.h" |
46 | #include "tp.h" | ||
46 | #include "espi.h" | 47 | #include "espi.h" |
47 | 48 | ||
48 | /** | 49 | /** |
@@ -59,7 +60,7 @@ | |||
59 | * otherwise. | 60 | * otherwise. |
60 | */ | 61 | */ |
61 | static int t1_wait_op_done(adapter_t *adapter, int reg, u32 mask, int polarity, | 62 | static int t1_wait_op_done(adapter_t *adapter, int reg, u32 mask, int polarity, |
62 | int attempts, int delay) | 63 | int attempts, int delay) |
63 | { | 64 | { |
64 | while (1) { | 65 | while (1) { |
65 | u32 val = readl(adapter->regs + reg) & mask; | 66 | u32 val = readl(adapter->regs + reg) & mask; |
@@ -78,7 +79,7 @@ static int t1_wait_op_done(adapter_t *adapter, int reg, u32 mask, int polarity, | |||
78 | /* | 79 | /* |
79 | * Write a register over the TPI interface (unlocked and locked versions). | 80 | * Write a register over the TPI interface (unlocked and locked versions). |
80 | */ | 81 | */ |
81 | static int __t1_tpi_write(adapter_t *adapter, u32 addr, u32 value) | 82 | int __t1_tpi_write(adapter_t *adapter, u32 addr, u32 value) |
82 | { | 83 | { |
83 | int tpi_busy; | 84 | int tpi_busy; |
84 | 85 | ||
@@ -98,16 +99,16 @@ int t1_tpi_write(adapter_t *adapter, u32 addr, u32 value) | |||
98 | { | 99 | { |
99 | int ret; | 100 | int ret; |
100 | 101 | ||
101 | spin_lock(&(adapter)->tpi_lock); | 102 | spin_lock(&adapter->tpi_lock); |
102 | ret = __t1_tpi_write(adapter, addr, value); | 103 | ret = __t1_tpi_write(adapter, addr, value); |
103 | spin_unlock(&(adapter)->tpi_lock); | 104 | spin_unlock(&adapter->tpi_lock); |
104 | return ret; | 105 | return ret; |
105 | } | 106 | } |
106 | 107 | ||
107 | /* | 108 | /* |
108 | * Read a register over the TPI interface (unlocked and locked versions). | 109 | * Read a register over the TPI interface (unlocked and locked versions). |
109 | */ | 110 | */ |
110 | static int __t1_tpi_read(adapter_t *adapter, u32 addr, u32 *valp) | 111 | int __t1_tpi_read(adapter_t *adapter, u32 addr, u32 *valp) |
111 | { | 112 | { |
112 | int tpi_busy; | 113 | int tpi_busy; |
113 | 114 | ||
@@ -128,18 +129,26 @@ int t1_tpi_read(adapter_t *adapter, u32 addr, u32 *valp) | |||
128 | { | 129 | { |
129 | int ret; | 130 | int ret; |
130 | 131 | ||
131 | spin_lock(&(adapter)->tpi_lock); | 132 | spin_lock(&adapter->tpi_lock); |
132 | ret = __t1_tpi_read(adapter, addr, valp); | 133 | ret = __t1_tpi_read(adapter, addr, valp); |
133 | spin_unlock(&(adapter)->tpi_lock); | 134 | spin_unlock(&adapter->tpi_lock); |
134 | return ret; | 135 | return ret; |
135 | } | 136 | } |
136 | 137 | ||
137 | /* | 138 | /* |
139 | * Set a TPI parameter. | ||
140 | */ | ||
141 | static void t1_tpi_par(adapter_t *adapter, u32 value) | ||
142 | { | ||
143 | writel(V_TPIPAR(value), adapter->regs + A_TPI_PAR); | ||
144 | } | ||
145 | |||
146 | /* | ||
138 | * Called when a port's link settings change to propagate the new values to the | 147 | * Called when a port's link settings change to propagate the new values to the |
139 | * associated PHY and MAC. After performing the common tasks it invokes an | 148 | * associated PHY and MAC. After performing the common tasks it invokes an |
140 | * OS-specific handler. | 149 | * OS-specific handler. |
141 | */ | 150 | */ |
142 | /* static */ void link_changed(adapter_t *adapter, int port_id) | 151 | void t1_link_changed(adapter_t *adapter, int port_id) |
143 | { | 152 | { |
144 | int link_ok, speed, duplex, fc; | 153 | int link_ok, speed, duplex, fc; |
145 | struct cphy *phy = adapter->port[port_id].phy; | 154 | struct cphy *phy = adapter->port[port_id].phy; |
@@ -159,23 +168,83 @@ int t1_tpi_read(adapter_t *adapter, u32 addr, u32 *valp) | |||
159 | mac->ops->set_speed_duplex_fc(mac, speed, duplex, fc); | 168 | mac->ops->set_speed_duplex_fc(mac, speed, duplex, fc); |
160 | lc->fc = (unsigned char)fc; | 169 | lc->fc = (unsigned char)fc; |
161 | } | 170 | } |
162 | t1_link_changed(adapter, port_id, link_ok, speed, duplex, fc); | 171 | t1_link_negotiated(adapter, port_id, link_ok, speed, duplex, fc); |
163 | } | 172 | } |
164 | 173 | ||
165 | static int t1_pci_intr_handler(adapter_t *adapter) | 174 | static int t1_pci_intr_handler(adapter_t *adapter) |
166 | { | 175 | { |
167 | u32 pcix_cause; | 176 | u32 pcix_cause; |
168 | 177 | ||
169 | pci_read_config_dword(adapter->pdev, A_PCICFG_INTR_CAUSE, &pcix_cause); | 178 | pci_read_config_dword(adapter->pdev, A_PCICFG_INTR_CAUSE, &pcix_cause); |
170 | 179 | ||
171 | if (pcix_cause) { | 180 | if (pcix_cause) { |
172 | pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_CAUSE, | 181 | pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_CAUSE, |
173 | pcix_cause); | 182 | pcix_cause); |
174 | t1_fatal_err(adapter); /* PCI errors are fatal */ | 183 | t1_fatal_err(adapter); /* PCI errors are fatal */ |
175 | } | 184 | } |
176 | return 0; | 185 | return 0; |
177 | } | 186 | } |
178 | 187 | ||
188 | #ifdef CONFIG_CHELSIO_T1_COUGAR | ||
189 | #include "cspi.h" | ||
190 | #endif | ||
191 | #ifdef CONFIG_CHELSIO_T1_1G | ||
192 | #include "fpga_defs.h" | ||
193 | |||
194 | /* | ||
195 | * PHY interrupt handler for FPGA boards. | ||
196 | */ | ||
197 | static int fpga_phy_intr_handler(adapter_t *adapter) | ||
198 | { | ||
199 | int p; | ||
200 | u32 cause = readl(adapter->regs + FPGA_GMAC_ADDR_INTERRUPT_CAUSE); | ||
201 | |||
202 | for_each_port(adapter, p) | ||
203 | if (cause & (1 << p)) { | ||
204 | struct cphy *phy = adapter->port[p].phy; | ||
205 | int phy_cause = phy->ops->interrupt_handler(phy); | ||
206 | |||
207 | if (phy_cause & cphy_cause_link_change) | ||
208 | t1_link_changed(adapter, p); | ||
209 | } | ||
210 | writel(cause, adapter->regs + FPGA_GMAC_ADDR_INTERRUPT_CAUSE); | ||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | /* | ||
215 | * Slow path interrupt handler for FPGAs. | ||
216 | */ | ||
217 | static int fpga_slow_intr(adapter_t *adapter) | ||
218 | { | ||
219 | u32 cause = readl(adapter->regs + A_PL_CAUSE); | ||
220 | |||
221 | cause &= ~F_PL_INTR_SGE_DATA; | ||
222 | if (cause & F_PL_INTR_SGE_ERR) | ||
223 | t1_sge_intr_error_handler(adapter->sge); | ||
224 | |||
225 | if (cause & FPGA_PCIX_INTERRUPT_GMAC) | ||
226 | fpga_phy_intr_handler(adapter); | ||
227 | |||
228 | if (cause & FPGA_PCIX_INTERRUPT_TP) { | ||
229 | /* | ||
230 | * FPGA doesn't support MC4 interrupts and it requires | ||
231 | * this odd layer of indirection for MC5. | ||
232 | */ | ||
233 | u32 tp_cause = readl(adapter->regs + FPGA_TP_ADDR_INTERRUPT_CAUSE); | ||
234 | |||
235 | /* Clear TP interrupt */ | ||
236 | writel(tp_cause, adapter->regs + FPGA_TP_ADDR_INTERRUPT_CAUSE); | ||
237 | } | ||
238 | if (cause & FPGA_PCIX_INTERRUPT_PCIX) | ||
239 | t1_pci_intr_handler(adapter); | ||
240 | |||
241 | /* Clear the interrupts just processed. */ | ||
242 | if (cause) | ||
243 | writel(cause, adapter->regs + A_PL_CAUSE); | ||
244 | |||
245 | return cause != 0; | ||
246 | } | ||
247 | #endif | ||
179 | 248 | ||
180 | /* | 249 | /* |
181 | * Wait until Elmer's MI1 interface is ready for new operations. | 250 | * Wait until Elmer's MI1 interface is ready for new operations. |
@@ -212,12 +281,62 @@ static void mi1_mdio_init(adapter_t *adapter, const struct board_info *bi) | |||
212 | t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_CFG, val); | 281 | t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_CFG, val); |
213 | } | 282 | } |
214 | 283 | ||
284 | #if defined(CONFIG_CHELSIO_T1_1G) || defined(CONFIG_CHELSIO_T1_COUGAR) | ||
285 | /* | ||
286 | * Elmer MI1 MDIO read/write operations. | ||
287 | */ | ||
288 | static int mi1_mdio_read(adapter_t *adapter, int phy_addr, int mmd_addr, | ||
289 | int reg_addr, unsigned int *valp) | ||
290 | { | ||
291 | u32 addr = V_MI1_REG_ADDR(reg_addr) | V_MI1_PHY_ADDR(phy_addr); | ||
292 | |||
293 | if (mmd_addr) | ||
294 | return -EINVAL; | ||
295 | |||
296 | spin_lock(&adapter->tpi_lock); | ||
297 | __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr); | ||
298 | __t1_tpi_write(adapter, | ||
299 | A_ELMER0_PORT0_MI1_OP, MI1_OP_DIRECT_READ); | ||
300 | mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); | ||
301 | __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, valp); | ||
302 | spin_unlock(&adapter->tpi_lock); | ||
303 | return 0; | ||
304 | } | ||
305 | |||
306 | static int mi1_mdio_write(adapter_t *adapter, int phy_addr, int mmd_addr, | ||
307 | int reg_addr, unsigned int val) | ||
308 | { | ||
309 | u32 addr = V_MI1_REG_ADDR(reg_addr) | V_MI1_PHY_ADDR(phy_addr); | ||
310 | |||
311 | if (mmd_addr) | ||
312 | return -EINVAL; | ||
313 | |||
314 | spin_lock(&adapter->tpi_lock); | ||
315 | __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr); | ||
316 | __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, val); | ||
317 | __t1_tpi_write(adapter, | ||
318 | A_ELMER0_PORT0_MI1_OP, MI1_OP_DIRECT_WRITE); | ||
319 | mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); | ||
320 | spin_unlock(&adapter->tpi_lock); | ||
321 | return 0; | ||
322 | } | ||
323 | |||
324 | #if defined(CONFIG_CHELSIO_T1_1G) || defined(CONFIG_CHELSIO_T1_COUGAR) | ||
325 | static struct mdio_ops mi1_mdio_ops = { | ||
326 | mi1_mdio_init, | ||
327 | mi1_mdio_read, | ||
328 | mi1_mdio_write | ||
329 | }; | ||
330 | #endif | ||
331 | |||
332 | #endif | ||
333 | |||
215 | static int mi1_mdio_ext_read(adapter_t *adapter, int phy_addr, int mmd_addr, | 334 | static int mi1_mdio_ext_read(adapter_t *adapter, int phy_addr, int mmd_addr, |
216 | int reg_addr, unsigned int *valp) | 335 | int reg_addr, unsigned int *valp) |
217 | { | 336 | { |
218 | u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr); | 337 | u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr); |
219 | 338 | ||
220 | spin_lock(&(adapter)->tpi_lock); | 339 | spin_lock(&adapter->tpi_lock); |
221 | 340 | ||
222 | /* Write the address we want. */ | 341 | /* Write the address we want. */ |
223 | __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr); | 342 | __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr); |
@@ -227,12 +346,13 @@ static int mi1_mdio_ext_read(adapter_t *adapter, int phy_addr, int mmd_addr, | |||
227 | mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); | 346 | mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); |
228 | 347 | ||
229 | /* Write the operation we want. */ | 348 | /* Write the operation we want. */ |
230 | __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP, MI1_OP_INDIRECT_READ); | 349 | __t1_tpi_write(adapter, |
350 | A_ELMER0_PORT0_MI1_OP, MI1_OP_INDIRECT_READ); | ||
231 | mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); | 351 | mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); |
232 | 352 | ||
233 | /* Read the data. */ | 353 | /* Read the data. */ |
234 | __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, valp); | 354 | __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, valp); |
235 | spin_unlock(&(adapter)->tpi_lock); | 355 | spin_unlock(&adapter->tpi_lock); |
236 | return 0; | 356 | return 0; |
237 | } | 357 | } |
238 | 358 | ||
@@ -241,7 +361,7 @@ static int mi1_mdio_ext_write(adapter_t *adapter, int phy_addr, int mmd_addr, | |||
241 | { | 361 | { |
242 | u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr); | 362 | u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr); |
243 | 363 | ||
244 | spin_lock(&(adapter)->tpi_lock); | 364 | spin_lock(&adapter->tpi_lock); |
245 | 365 | ||
246 | /* Write the address we want. */ | 366 | /* Write the address we want. */ |
247 | __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr); | 367 | __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr); |
@@ -254,7 +374,7 @@ static int mi1_mdio_ext_write(adapter_t *adapter, int phy_addr, int mmd_addr, | |||
254 | __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, val); | 374 | __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, val); |
255 | __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP, MI1_OP_INDIRECT_WRITE); | 375 | __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP, MI1_OP_INDIRECT_WRITE); |
256 | mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); | 376 | mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); |
257 | spin_unlock(&(adapter)->tpi_lock); | 377 | spin_unlock(&adapter->tpi_lock); |
258 | return 0; | 378 | return 0; |
259 | } | 379 | } |
260 | 380 | ||
@@ -265,12 +385,25 @@ static struct mdio_ops mi1_mdio_ext_ops = { | |||
265 | }; | 385 | }; |
266 | 386 | ||
267 | enum { | 387 | enum { |
388 | CH_BRD_T110_1CU, | ||
268 | CH_BRD_N110_1F, | 389 | CH_BRD_N110_1F, |
269 | CH_BRD_N210_1F, | 390 | CH_BRD_N210_1F, |
391 | CH_BRD_T210_1F, | ||
392 | CH_BRD_T210_1CU, | ||
393 | CH_BRD_N204_4CU, | ||
270 | }; | 394 | }; |
271 | 395 | ||
272 | static struct board_info t1_board[] = { | 396 | static struct board_info t1_board[] = { |
273 | 397 | ||
398 | { CHBT_BOARD_CHT110, 1/*ports#*/, | ||
399 | SUPPORTED_10000baseT_Full /*caps*/, CHBT_TERM_T1, | ||
400 | CHBT_MAC_PM3393, CHBT_PHY_MY3126, | ||
401 | 125000000/*clk-core*/, 150000000/*clk-mc3*/, 125000000/*clk-mc4*/, | ||
402 | 1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 1/*mdien*/, | ||
403 | 1/*mdiinv*/, 1/*mdc*/, 1/*phybaseaddr*/, &t1_pm3393_ops, | ||
404 | &t1_my3126_ops, &mi1_mdio_ext_ops, | ||
405 | "Chelsio T110 1x10GBase-CX4 TOE" }, | ||
406 | |||
274 | { CHBT_BOARD_N110, 1/*ports#*/, | 407 | { CHBT_BOARD_N110, 1/*ports#*/, |
275 | SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE /*caps*/, CHBT_TERM_T1, | 408 | SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE /*caps*/, CHBT_TERM_T1, |
276 | CHBT_MAC_PM3393, CHBT_PHY_88X2010, | 409 | CHBT_MAC_PM3393, CHBT_PHY_88X2010, |
@@ -289,12 +422,47 @@ static struct board_info t1_board[] = { | |||
289 | &t1_mv88x201x_ops, &mi1_mdio_ext_ops, | 422 | &t1_mv88x201x_ops, &mi1_mdio_ext_ops, |
290 | "Chelsio N210 1x10GBaseX NIC" }, | 423 | "Chelsio N210 1x10GBaseX NIC" }, |
291 | 424 | ||
425 | { CHBT_BOARD_CHT210, 1/*ports#*/, | ||
426 | SUPPORTED_10000baseT_Full /*caps*/, CHBT_TERM_T2, | ||
427 | CHBT_MAC_PM3393, CHBT_PHY_88X2010, | ||
428 | 125000000/*clk-core*/, 133000000/*clk-mc3*/, 125000000/*clk-mc4*/, | ||
429 | 1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 0/*mdien*/, | ||
430 | 0/*mdiinv*/, 1/*mdc*/, 0/*phybaseaddr*/, &t1_pm3393_ops, | ||
431 | &t1_mv88x201x_ops, &mi1_mdio_ext_ops, | ||
432 | "Chelsio T210 1x10GBaseX TOE" }, | ||
433 | |||
434 | { CHBT_BOARD_CHT210, 1/*ports#*/, | ||
435 | SUPPORTED_10000baseT_Full /*caps*/, CHBT_TERM_T2, | ||
436 | CHBT_MAC_PM3393, CHBT_PHY_MY3126, | ||
437 | 125000000/*clk-core*/, 133000000/*clk-mc3*/, 125000000/*clk-mc4*/, | ||
438 | 1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 1/*mdien*/, | ||
439 | 1/*mdiinv*/, 1/*mdc*/, 1/*phybaseaddr*/, &t1_pm3393_ops, | ||
440 | &t1_my3126_ops, &mi1_mdio_ext_ops, | ||
441 | "Chelsio T210 1x10GBase-CX4 TOE" }, | ||
442 | |||
443 | #ifdef CONFIG_CHELSIO_T1_1G | ||
444 | { CHBT_BOARD_CHN204, 4/*ports#*/, | ||
445 | SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | | ||
446 | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | | ||
447 | SUPPORTED_PAUSE | SUPPORTED_TP /*caps*/, CHBT_TERM_T2, CHBT_MAC_VSC7321, CHBT_PHY_88E1111, | ||
448 | 100000000/*clk-core*/, 0/*clk-mc3*/, 0/*clk-mc4*/, | ||
449 | 4/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 0/*mdien*/, | ||
450 | 0/*mdiinv*/, 1/*mdc*/, 4/*phybaseaddr*/, &t1_vsc7326_ops, | ||
451 | &t1_mv88e1xxx_ops, &mi1_mdio_ops, | ||
452 | "Chelsio N204 4x100/1000BaseT NIC" }, | ||
453 | #endif | ||
454 | |||
292 | }; | 455 | }; |
293 | 456 | ||
294 | struct pci_device_id t1_pci_tbl[] = { | 457 | struct pci_device_id t1_pci_tbl[] = { |
458 | CH_DEVICE(8, 0, CH_BRD_T110_1CU), | ||
459 | CH_DEVICE(8, 1, CH_BRD_T110_1CU), | ||
295 | CH_DEVICE(7, 0, CH_BRD_N110_1F), | 460 | CH_DEVICE(7, 0, CH_BRD_N110_1F), |
296 | CH_DEVICE(10, 1, CH_BRD_N210_1F), | 461 | CH_DEVICE(10, 1, CH_BRD_N210_1F), |
297 | { 0, } | 462 | CH_DEVICE(11, 1, CH_BRD_T210_1F), |
463 | CH_DEVICE(14, 1, CH_BRD_T210_1CU), | ||
464 | CH_DEVICE(16, 1, CH_BRD_N204_4CU), | ||
465 | { 0 } | ||
298 | }; | 466 | }; |
299 | 467 | ||
300 | MODULE_DEVICE_TABLE(pci, t1_pci_tbl); | 468 | MODULE_DEVICE_TABLE(pci, t1_pci_tbl); |
@@ -390,9 +558,14 @@ int t1_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc) | |||
390 | if (lc->supported & SUPPORTED_Autoneg) { | 558 | if (lc->supported & SUPPORTED_Autoneg) { |
391 | lc->advertising &= ~(ADVERTISED_ASYM_PAUSE | ADVERTISED_PAUSE); | 559 | lc->advertising &= ~(ADVERTISED_ASYM_PAUSE | ADVERTISED_PAUSE); |
392 | if (fc) { | 560 | if (fc) { |
393 | lc->advertising |= ADVERTISED_ASYM_PAUSE; | 561 | if (fc == ((PAUSE_RX | PAUSE_TX) & |
394 | if (fc == (PAUSE_RX | PAUSE_TX)) | 562 | (mac->adapter->params.nports < 2))) |
395 | lc->advertising |= ADVERTISED_PAUSE; | 563 | lc->advertising |= ADVERTISED_PAUSE; |
564 | else { | ||
565 | lc->advertising |= ADVERTISED_ASYM_PAUSE; | ||
566 | if (fc == PAUSE_RX) | ||
567 | lc->advertising |= ADVERTISED_PAUSE; | ||
568 | } | ||
396 | } | 569 | } |
397 | phy->ops->advertise(phy, lc->advertising); | 570 | phy->ops->advertise(phy, lc->advertising); |
398 | 571 | ||
@@ -403,11 +576,15 @@ int t1_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc) | |||
403 | mac->ops->set_speed_duplex_fc(mac, lc->speed, | 576 | mac->ops->set_speed_duplex_fc(mac, lc->speed, |
404 | lc->duplex, fc); | 577 | lc->duplex, fc); |
405 | /* Also disables autoneg */ | 578 | /* Also disables autoneg */ |
579 | phy->state = PHY_AUTONEG_RDY; | ||
406 | phy->ops->set_speed_duplex(phy, lc->speed, lc->duplex); | 580 | phy->ops->set_speed_duplex(phy, lc->speed, lc->duplex); |
407 | phy->ops->reset(phy, 0); | 581 | phy->ops->reset(phy, 0); |
408 | } else | 582 | } else { |
583 | phy->state = PHY_AUTONEG_EN; | ||
409 | phy->ops->autoneg_enable(phy); /* also resets PHY */ | 584 | phy->ops->autoneg_enable(phy); /* also resets PHY */ |
585 | } | ||
410 | } else { | 586 | } else { |
587 | phy->state = PHY_AUTONEG_RDY; | ||
411 | mac->ops->set_speed_duplex_fc(mac, -1, -1, fc); | 588 | mac->ops->set_speed_duplex_fc(mac, -1, -1, fc); |
412 | lc->fc = (unsigned char)fc; | 589 | lc->fc = (unsigned char)fc; |
413 | phy->ops->reset(phy, 0); | 590 | phy->ops->reset(phy, 0); |
@@ -418,24 +595,109 @@ int t1_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc) | |||
418 | /* | 595 | /* |
419 | * External interrupt handler for boards using elmer0. | 596 | * External interrupt handler for boards using elmer0. |
420 | */ | 597 | */ |
421 | int elmer0_ext_intr_handler(adapter_t *adapter) | 598 | int t1_elmer0_ext_intr_handler(adapter_t *adapter) |
422 | { | 599 | { |
423 | struct cphy *phy; | 600 | struct cphy *phy; |
424 | int phy_cause; | 601 | int phy_cause; |
425 | u32 cause; | 602 | u32 cause; |
426 | 603 | ||
427 | t1_tpi_read(adapter, A_ELMER0_INT_CAUSE, &cause); | 604 | t1_tpi_read(adapter, A_ELMER0_INT_CAUSE, &cause); |
428 | 605 | ||
429 | switch (board_info(adapter)->board) { | 606 | switch (board_info(adapter)->board) { |
607 | #ifdef CONFIG_CHELSIO_T1_1G | ||
608 | case CHBT_BOARD_CHT204: | ||
609 | case CHBT_BOARD_CHT204E: | ||
610 | case CHBT_BOARD_CHN204: | ||
611 | case CHBT_BOARD_CHT204V: { | ||
612 | int i, port_bit; | ||
613 | for_each_port(adapter, i) { | ||
614 | port_bit = i + 1; | ||
615 | if (!(cause & (1 << port_bit))) continue; | ||
616 | |||
617 | phy = adapter->port[i].phy; | ||
618 | phy_cause = phy->ops->interrupt_handler(phy); | ||
619 | if (phy_cause & cphy_cause_link_change) | ||
620 | t1_link_changed(adapter, i); | ||
621 | } | ||
622 | break; | ||
623 | } | ||
624 | case CHBT_BOARD_CHT101: | ||
625 | if (cause & ELMER0_GP_BIT1) { /* Marvell 88E1111 interrupt */ | ||
626 | phy = adapter->port[0].phy; | ||
627 | phy_cause = phy->ops->interrupt_handler(phy); | ||
628 | if (phy_cause & cphy_cause_link_change) | ||
629 | t1_link_changed(adapter, 0); | ||
630 | } | ||
631 | break; | ||
632 | case CHBT_BOARD_7500: { | ||
633 | int p; | ||
634 | /* | ||
635 | * Elmer0's interrupt cause isn't useful here because there is | ||
636 | * only one bit that can be set for all 4 ports. This means | ||
637 | * we are forced to check every PHY's interrupt status | ||
638 | * register to see who initiated the interrupt. | ||
639 | */ | ||
640 | for_each_port(adapter, p) { | ||
641 | phy = adapter->port[p].phy; | ||
642 | phy_cause = phy->ops->interrupt_handler(phy); | ||
643 | if (phy_cause & cphy_cause_link_change) | ||
644 | t1_link_changed(adapter, p); | ||
645 | } | ||
646 | break; | ||
647 | } | ||
648 | #endif | ||
649 | case CHBT_BOARD_CHT210: | ||
430 | case CHBT_BOARD_N210: | 650 | case CHBT_BOARD_N210: |
431 | case CHBT_BOARD_N110: | 651 | case CHBT_BOARD_N110: |
432 | if (cause & ELMER0_GP_BIT6) { /* Marvell 88x2010 interrupt */ | 652 | if (cause & ELMER0_GP_BIT6) { /* Marvell 88x2010 interrupt */ |
433 | phy = adapter->port[0].phy; | 653 | phy = adapter->port[0].phy; |
434 | phy_cause = phy->ops->interrupt_handler(phy); | 654 | phy_cause = phy->ops->interrupt_handler(phy); |
435 | if (phy_cause & cphy_cause_link_change) | 655 | if (phy_cause & cphy_cause_link_change) |
436 | link_changed(adapter, 0); | 656 | t1_link_changed(adapter, 0); |
657 | } | ||
658 | break; | ||
659 | case CHBT_BOARD_8000: | ||
660 | case CHBT_BOARD_CHT110: | ||
661 | CH_DBG(adapter, INTR, "External interrupt cause 0x%x\n", | ||
662 | cause); | ||
663 | if (cause & ELMER0_GP_BIT1) { /* PMC3393 INTB */ | ||
664 | struct cmac *mac = adapter->port[0].mac; | ||
665 | |||
666 | mac->ops->interrupt_handler(mac); | ||
437 | } | 667 | } |
668 | if (cause & ELMER0_GP_BIT5) { /* XPAK MOD_DETECT */ | ||
669 | u32 mod_detect; | ||
670 | |||
671 | t1_tpi_read(adapter, | ||
672 | A_ELMER0_GPI_STAT, &mod_detect); | ||
673 | CH_MSG(adapter, INFO, LINK, "XPAK %s\n", | ||
674 | mod_detect ? "removed" : "inserted"); | ||
675 | } | ||
438 | break; | 676 | break; |
677 | #ifdef CONFIG_CHELSIO_T1_COUGAR | ||
678 | case CHBT_BOARD_COUGAR: | ||
679 | if (adapter->params.nports == 1) { | ||
680 | if (cause & ELMER0_GP_BIT1) { /* Vitesse MAC */ | ||
681 | struct cmac *mac = adapter->port[0].mac; | ||
682 | mac->ops->interrupt_handler(mac); | ||
683 | } | ||
684 | if (cause & ELMER0_GP_BIT5) { /* XPAK MOD_DETECT */ | ||
685 | } | ||
686 | } else { | ||
687 | int i, port_bit; | ||
688 | |||
689 | for_each_port(adapter, i) { | ||
690 | port_bit = i ? i + 1 : 0; | ||
691 | if (!(cause & (1 << port_bit))) continue; | ||
692 | |||
693 | phy = adapter->port[i].phy; | ||
694 | phy_cause = phy->ops->interrupt_handler(phy); | ||
695 | if (phy_cause & cphy_cause_link_change) | ||
696 | t1_link_changed(adapter, i); | ||
697 | } | ||
698 | } | ||
699 | break; | ||
700 | #endif | ||
439 | } | 701 | } |
440 | t1_tpi_write(adapter, A_ELMER0_INT_CAUSE, cause); | 702 | t1_tpi_write(adapter, A_ELMER0_INT_CAUSE, cause); |
441 | return 0; | 703 | return 0; |
@@ -445,11 +707,11 @@ int elmer0_ext_intr_handler(adapter_t *adapter) | |||
445 | void t1_interrupts_enable(adapter_t *adapter) | 707 | void t1_interrupts_enable(adapter_t *adapter) |
446 | { | 708 | { |
447 | unsigned int i; | 709 | unsigned int i; |
448 | u32 pl_intr; | ||
449 | 710 | ||
450 | adapter->slow_intr_mask = F_PL_INTR_SGE_ERR; | 711 | adapter->slow_intr_mask = F_PL_INTR_SGE_ERR | F_PL_INTR_TP; |
451 | 712 | ||
452 | t1_sge_intr_enable(adapter->sge); | 713 | t1_sge_intr_enable(adapter->sge); |
714 | t1_tp_intr_enable(adapter->tp); | ||
453 | if (adapter->espi) { | 715 | if (adapter->espi) { |
454 | adapter->slow_intr_mask |= F_PL_INTR_ESPI; | 716 | adapter->slow_intr_mask |= F_PL_INTR_ESPI; |
455 | t1_espi_intr_enable(adapter->espi); | 717 | t1_espi_intr_enable(adapter->espi); |
@@ -462,15 +724,17 @@ void t1_interrupts_enable(adapter_t *adapter) | |||
462 | } | 724 | } |
463 | 725 | ||
464 | /* Enable PCIX & external chip interrupts on ASIC boards. */ | 726 | /* Enable PCIX & external chip interrupts on ASIC boards. */ |
465 | pl_intr = readl(adapter->regs + A_PL_ENABLE); | 727 | if (t1_is_asic(adapter)) { |
728 | u32 pl_intr = readl(adapter->regs + A_PL_ENABLE); | ||
466 | 729 | ||
467 | /* PCI-X interrupts */ | 730 | /* PCI-X interrupts */ |
468 | pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_ENABLE, | 731 | pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_ENABLE, |
469 | 0xffffffff); | 732 | 0xffffffff); |
470 | 733 | ||
471 | adapter->slow_intr_mask |= F_PL_INTR_EXT | F_PL_INTR_PCIX; | 734 | adapter->slow_intr_mask |= F_PL_INTR_EXT | F_PL_INTR_PCIX; |
472 | pl_intr |= F_PL_INTR_EXT | F_PL_INTR_PCIX; | 735 | pl_intr |= F_PL_INTR_EXT | F_PL_INTR_PCIX; |
473 | writel(pl_intr, adapter->regs + A_PL_ENABLE); | 736 | writel(pl_intr, adapter->regs + A_PL_ENABLE); |
737 | } | ||
474 | } | 738 | } |
475 | 739 | ||
476 | /* Disables all interrupts. */ | 740 | /* Disables all interrupts. */ |
@@ -479,6 +743,7 @@ void t1_interrupts_disable(adapter_t* adapter) | |||
479 | unsigned int i; | 743 | unsigned int i; |
480 | 744 | ||
481 | t1_sge_intr_disable(adapter->sge); | 745 | t1_sge_intr_disable(adapter->sge); |
746 | t1_tp_intr_disable(adapter->tp); | ||
482 | if (adapter->espi) | 747 | if (adapter->espi) |
483 | t1_espi_intr_disable(adapter->espi); | 748 | t1_espi_intr_disable(adapter->espi); |
484 | 749 | ||
@@ -489,7 +754,8 @@ void t1_interrupts_disable(adapter_t* adapter) | |||
489 | } | 754 | } |
490 | 755 | ||
491 | /* Disable PCIX & external chip interrupts. */ | 756 | /* Disable PCIX & external chip interrupts. */ |
492 | writel(0, adapter->regs + A_PL_ENABLE); | 757 | if (t1_is_asic(adapter)) |
758 | writel(0, adapter->regs + A_PL_ENABLE); | ||
493 | 759 | ||
494 | /* PCI-X interrupts */ | 760 | /* PCI-X interrupts */ |
495 | pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_ENABLE, 0); | 761 | pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_ENABLE, 0); |
@@ -501,10 +767,9 @@ void t1_interrupts_disable(adapter_t* adapter) | |||
501 | void t1_interrupts_clear(adapter_t* adapter) | 767 | void t1_interrupts_clear(adapter_t* adapter) |
502 | { | 768 | { |
503 | unsigned int i; | 769 | unsigned int i; |
504 | u32 pl_intr; | ||
505 | |||
506 | 770 | ||
507 | t1_sge_intr_clear(adapter->sge); | 771 | t1_sge_intr_clear(adapter->sge); |
772 | t1_tp_intr_clear(adapter->tp); | ||
508 | if (adapter->espi) | 773 | if (adapter->espi) |
509 | t1_espi_intr_clear(adapter->espi); | 774 | t1_espi_intr_clear(adapter->espi); |
510 | 775 | ||
@@ -515,10 +780,12 @@ void t1_interrupts_clear(adapter_t* adapter) | |||
515 | } | 780 | } |
516 | 781 | ||
517 | /* Enable interrupts for external devices. */ | 782 | /* Enable interrupts for external devices. */ |
518 | pl_intr = readl(adapter->regs + A_PL_CAUSE); | 783 | if (t1_is_asic(adapter)) { |
784 | u32 pl_intr = readl(adapter->regs + A_PL_CAUSE); | ||
519 | 785 | ||
520 | writel(pl_intr | F_PL_INTR_EXT | F_PL_INTR_PCIX, | 786 | writel(pl_intr | F_PL_INTR_EXT | F_PL_INTR_PCIX, |
521 | adapter->regs + A_PL_CAUSE); | 787 | adapter->regs + A_PL_CAUSE); |
788 | } | ||
522 | 789 | ||
523 | /* PCI-X interrupts */ | 790 | /* PCI-X interrupts */ |
524 | pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_CAUSE, 0xffffffff); | 791 | pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_CAUSE, 0xffffffff); |
@@ -527,7 +794,7 @@ void t1_interrupts_clear(adapter_t* adapter) | |||
527 | /* | 794 | /* |
528 | * Slow path interrupt handler for ASICs. | 795 | * Slow path interrupt handler for ASICs. |
529 | */ | 796 | */ |
530 | int t1_slow_intr_handler(adapter_t *adapter) | 797 | static int asic_slow_intr(adapter_t *adapter) |
531 | { | 798 | { |
532 | u32 cause = readl(adapter->regs + A_PL_CAUSE); | 799 | u32 cause = readl(adapter->regs + A_PL_CAUSE); |
533 | 800 | ||
@@ -536,89 +803,54 @@ int t1_slow_intr_handler(adapter_t *adapter) | |||
536 | return 0; | 803 | return 0; |
537 | if (cause & F_PL_INTR_SGE_ERR) | 804 | if (cause & F_PL_INTR_SGE_ERR) |
538 | t1_sge_intr_error_handler(adapter->sge); | 805 | t1_sge_intr_error_handler(adapter->sge); |
806 | if (cause & F_PL_INTR_TP) | ||
807 | t1_tp_intr_handler(adapter->tp); | ||
539 | if (cause & F_PL_INTR_ESPI) | 808 | if (cause & F_PL_INTR_ESPI) |
540 | t1_espi_intr_handler(adapter->espi); | 809 | t1_espi_intr_handler(adapter->espi); |
541 | if (cause & F_PL_INTR_PCIX) | 810 | if (cause & F_PL_INTR_PCIX) |
542 | t1_pci_intr_handler(adapter); | 811 | t1_pci_intr_handler(adapter); |
543 | if (cause & F_PL_INTR_EXT) | 812 | if (cause & F_PL_INTR_EXT) |
544 | t1_elmer0_ext_intr(adapter); | 813 | t1_elmer0_ext_intr_handler(adapter); |
545 | 814 | ||
546 | /* Clear the interrupts just processed. */ | 815 | /* Clear the interrupts just processed. */ |
547 | writel(cause, adapter->regs + A_PL_CAUSE); | 816 | writel(cause, adapter->regs + A_PL_CAUSE); |
548 | (void)readl(adapter->regs + A_PL_CAUSE); /* flush writes */ | 817 | readl(adapter->regs + A_PL_CAUSE); /* flush writes */ |
549 | return 1; | 818 | return 1; |
550 | } | 819 | } |
551 | 820 | ||
552 | /* Pause deadlock avoidance parameters */ | 821 | int t1_slow_intr_handler(adapter_t *adapter) |
553 | #define DROP_MSEC 16 | ||
554 | #define DROP_PKTS_CNT 1 | ||
555 | |||
556 | static void set_csum_offload(adapter_t *adapter, u32 csum_bit, int enable) | ||
557 | { | ||
558 | u32 val = readl(adapter->regs + A_TP_GLOBAL_CONFIG); | ||
559 | |||
560 | if (enable) | ||
561 | val |= csum_bit; | ||
562 | else | ||
563 | val &= ~csum_bit; | ||
564 | writel(val, adapter->regs + A_TP_GLOBAL_CONFIG); | ||
565 | } | ||
566 | |||
567 | void t1_tp_set_ip_checksum_offload(adapter_t *adapter, int enable) | ||
568 | { | ||
569 | set_csum_offload(adapter, F_IP_CSUM, enable); | ||
570 | } | ||
571 | |||
572 | void t1_tp_set_udp_checksum_offload(adapter_t *adapter, int enable) | ||
573 | { | ||
574 | set_csum_offload(adapter, F_UDP_CSUM, enable); | ||
575 | } | ||
576 | |||
577 | void t1_tp_set_tcp_checksum_offload(adapter_t *adapter, int enable) | ||
578 | { | 822 | { |
579 | set_csum_offload(adapter, F_TCP_CSUM, enable); | 823 | #ifdef CONFIG_CHELSIO_T1_1G |
824 | if (!t1_is_asic(adapter)) | ||
825 | return fpga_slow_intr(adapter); | ||
826 | #endif | ||
827 | return asic_slow_intr(adapter); | ||
580 | } | 828 | } |
581 | 829 | ||
582 | static void t1_tp_reset(adapter_t *adapter, unsigned int tp_clk) | 830 | /* Power sequencing is a work-around for Intel's XPAKs. */ |
831 | static void power_sequence_xpak(adapter_t* adapter) | ||
583 | { | 832 | { |
584 | u32 val; | 833 | u32 mod_detect; |
585 | 834 | u32 gpo; | |
586 | val = F_TP_IN_CSPI_CPL | F_TP_IN_CSPI_CHECK_IP_CSUM | | 835 | |
587 | F_TP_IN_CSPI_CHECK_TCP_CSUM | F_TP_IN_ESPI_ETHERNET; | 836 | /* Check for XPAK */ |
588 | val |= F_TP_IN_ESPI_CHECK_IP_CSUM | | 837 | t1_tpi_read(adapter, A_ELMER0_GPI_STAT, &mod_detect); |
589 | F_TP_IN_ESPI_CHECK_TCP_CSUM; | 838 | if (!(ELMER0_GP_BIT5 & mod_detect)) { |
590 | writel(val, adapter->regs + A_TP_IN_CONFIG); | 839 | /* XPAK is present */ |
591 | writel(F_TP_OUT_CSPI_CPL | | 840 | t1_tpi_read(adapter, A_ELMER0_GPO, &gpo); |
592 | F_TP_OUT_ESPI_ETHERNET | | 841 | gpo |= ELMER0_GP_BIT18; |
593 | F_TP_OUT_ESPI_GENERATE_IP_CSUM | | 842 | t1_tpi_write(adapter, A_ELMER0_GPO, gpo); |
594 | F_TP_OUT_ESPI_GENERATE_TCP_CSUM, | ||
595 | adapter->regs + A_TP_OUT_CONFIG); | ||
596 | |||
597 | val = readl(adapter->regs + A_TP_GLOBAL_CONFIG); | ||
598 | val &= ~(F_IP_CSUM | F_UDP_CSUM | F_TCP_CSUM); | ||
599 | writel(val, adapter->regs + A_TP_GLOBAL_CONFIG); | ||
600 | |||
601 | /* | ||
602 | * Enable pause frame deadlock prevention. | ||
603 | */ | ||
604 | if (is_T2(adapter)) { | ||
605 | u32 drop_ticks = DROP_MSEC * (tp_clk / 1000); | ||
606 | |||
607 | writel(F_ENABLE_TX_DROP | F_ENABLE_TX_ERROR | | ||
608 | V_DROP_TICKS_CNT(drop_ticks) | | ||
609 | V_NUM_PKTS_DROPPED(DROP_PKTS_CNT), | ||
610 | adapter->regs + A_TP_TX_DROP_CONFIG); | ||
611 | } | 843 | } |
612 | |||
613 | writel(F_TP_RESET, adapter->regs + A_TP_RESET); | ||
614 | } | 844 | } |
615 | 845 | ||
616 | int __devinit t1_get_board_rev(adapter_t *adapter, const struct board_info *bi, | 846 | int __devinit t1_get_board_rev(adapter_t *adapter, const struct board_info *bi, |
617 | struct adapter_params *p) | 847 | struct adapter_params *p) |
618 | { | 848 | { |
619 | p->chip_version = bi->chip_term; | 849 | p->chip_version = bi->chip_term; |
850 | p->is_asic = (p->chip_version != CHBT_TERM_FPGA); | ||
620 | if (p->chip_version == CHBT_TERM_T1 || | 851 | if (p->chip_version == CHBT_TERM_T1 || |
621 | p->chip_version == CHBT_TERM_T2) { | 852 | p->chip_version == CHBT_TERM_T2 || |
853 | p->chip_version == CHBT_TERM_FPGA) { | ||
622 | u32 val = readl(adapter->regs + A_TP_PC_CONFIG); | 854 | u32 val = readl(adapter->regs + A_TP_PC_CONFIG); |
623 | 855 | ||
624 | val = G_TP_PC_REV(val); | 856 | val = G_TP_PC_REV(val); |
@@ -640,11 +872,38 @@ int __devinit t1_get_board_rev(adapter_t *adapter, const struct board_info *bi, | |||
640 | static int board_init(adapter_t *adapter, const struct board_info *bi) | 872 | static int board_init(adapter_t *adapter, const struct board_info *bi) |
641 | { | 873 | { |
642 | switch (bi->board) { | 874 | switch (bi->board) { |
875 | case CHBT_BOARD_8000: | ||
643 | case CHBT_BOARD_N110: | 876 | case CHBT_BOARD_N110: |
644 | case CHBT_BOARD_N210: | 877 | case CHBT_BOARD_N210: |
645 | writel(V_TPIPAR(0xf), adapter->regs + A_TPI_PAR); | 878 | case CHBT_BOARD_CHT210: |
879 | case CHBT_BOARD_COUGAR: | ||
880 | t1_tpi_par(adapter, 0xf); | ||
646 | t1_tpi_write(adapter, A_ELMER0_GPO, 0x800); | 881 | t1_tpi_write(adapter, A_ELMER0_GPO, 0x800); |
647 | break; | 882 | break; |
883 | case CHBT_BOARD_CHT110: | ||
884 | t1_tpi_par(adapter, 0xf); | ||
885 | t1_tpi_write(adapter, A_ELMER0_GPO, 0x1800); | ||
886 | |||
887 | /* TBD XXX Might not need. This fixes a problem | ||
888 | * described in the Intel SR XPAK errata. | ||
889 | */ | ||
890 | power_sequence_xpak(adapter); | ||
891 | break; | ||
892 | #ifdef CONFIG_CHELSIO_T1_1G | ||
893 | case CHBT_BOARD_CHT204E: | ||
894 | /* add config space write here */ | ||
895 | case CHBT_BOARD_CHT204: | ||
896 | case CHBT_BOARD_CHT204V: | ||
897 | case CHBT_BOARD_CHN204: | ||
898 | t1_tpi_par(adapter, 0xf); | ||
899 | t1_tpi_write(adapter, A_ELMER0_GPO, 0x804); | ||
900 | break; | ||
901 | case CHBT_BOARD_CHT101: | ||
902 | case CHBT_BOARD_7500: | ||
903 | t1_tpi_par(adapter, 0xf); | ||
904 | t1_tpi_write(adapter, A_ELMER0_GPO, 0x1804); | ||
905 | break; | ||
906 | #endif | ||
648 | } | 907 | } |
649 | return 0; | 908 | return 0; |
650 | } | 909 | } |
@@ -666,11 +925,16 @@ int t1_init_hw_modules(adapter_t *adapter) | |||
666 | adapter->regs + A_MC5_CONFIG); | 925 | adapter->regs + A_MC5_CONFIG); |
667 | } | 926 | } |
668 | 927 | ||
928 | #ifdef CONFIG_CHELSIO_T1_COUGAR | ||
929 | if (adapter->cspi && t1_cspi_init(adapter->cspi)) | ||
930 | goto out_err; | ||
931 | #endif | ||
669 | if (adapter->espi && t1_espi_init(adapter->espi, bi->chip_mac, | 932 | if (adapter->espi && t1_espi_init(adapter->espi, bi->chip_mac, |
670 | bi->espi_nports)) | 933 | bi->espi_nports)) |
671 | goto out_err; | 934 | goto out_err; |
672 | 935 | ||
673 | t1_tp_reset(adapter, bi->clock_core); | 936 | if (t1_tp_reset(adapter->tp, &adapter->params.tp, bi->clock_core)) |
937 | goto out_err; | ||
674 | 938 | ||
675 | err = t1_sge_configure(adapter->sge, &adapter->params.sge); | 939 | err = t1_sge_configure(adapter->sge, &adapter->params.sge); |
676 | if (err) | 940 | if (err) |
@@ -714,8 +978,14 @@ void t1_free_sw_modules(adapter_t *adapter) | |||
714 | 978 | ||
715 | if (adapter->sge) | 979 | if (adapter->sge) |
716 | t1_sge_destroy(adapter->sge); | 980 | t1_sge_destroy(adapter->sge); |
981 | if (adapter->tp) | ||
982 | t1_tp_destroy(adapter->tp); | ||
717 | if (adapter->espi) | 983 | if (adapter->espi) |
718 | t1_espi_destroy(adapter->espi); | 984 | t1_espi_destroy(adapter->espi); |
985 | #ifdef CONFIG_CHELSIO_T1_COUGAR | ||
986 | if (adapter->cspi) | ||
987 | t1_cspi_destroy(adapter->cspi); | ||
988 | #endif | ||
719 | } | 989 | } |
720 | 990 | ||
721 | static void __devinit init_link_config(struct link_config *lc, | 991 | static void __devinit init_link_config(struct link_config *lc, |
@@ -735,6 +1005,13 @@ static void __devinit init_link_config(struct link_config *lc, | |||
735 | } | 1005 | } |
736 | } | 1006 | } |
737 | 1007 | ||
1008 | #ifdef CONFIG_CHELSIO_T1_COUGAR | ||
1009 | if (bi->clock_cspi && !(adapter->cspi = t1_cspi_create(adapter))) { | ||
1010 | CH_ERR("%s: CSPI initialization failed\n", | ||
1011 | adapter->name); | ||
1012 | goto error; | ||
1013 | } | ||
1014 | #endif | ||
738 | 1015 | ||
739 | /* | 1016 | /* |
740 | * Allocate and initialize the data structures that hold the SW state of | 1017 | * Allocate and initialize the data structures that hold the SW state of |
@@ -762,6 +1039,13 @@ int __devinit t1_init_sw_modules(adapter_t *adapter, | |||
762 | goto error; | 1039 | goto error; |
763 | } | 1040 | } |
764 | 1041 | ||
1042 | adapter->tp = t1_tp_create(adapter, &adapter->params.tp); | ||
1043 | if (!adapter->tp) { | ||
1044 | CH_ERR("%s: TP initialization failed\n", | ||
1045 | adapter->name); | ||
1046 | goto error; | ||
1047 | } | ||
1048 | |||
765 | board_init(adapter, bi); | 1049 | board_init(adapter, bi); |
766 | bi->mdio_ops->init(adapter, bi); | 1050 | bi->mdio_ops->init(adapter, bi); |
767 | if (bi->gphy->reset) | 1051 | if (bi->gphy->reset) |
@@ -793,7 +1077,9 @@ int __devinit t1_init_sw_modules(adapter_t *adapter, | |||
793 | * Get the port's MAC addresses either from the EEPROM if one | 1077 | * Get the port's MAC addresses either from the EEPROM if one |
794 | * exists or the one hardcoded in the MAC. | 1078 | * exists or the one hardcoded in the MAC. |
795 | */ | 1079 | */ |
796 | if (vpd_macaddress_get(adapter, i, hw_addr)) { | 1080 | if (!t1_is_asic(adapter) || bi->chip_mac == CHBT_MAC_DUMMY) |
1081 | mac->ops->macaddress_get(mac, hw_addr); | ||
1082 | else if (vpd_macaddress_get(adapter, i, hw_addr)) { | ||
797 | CH_ERR("%s: could not read MAC address from VPD ROM\n", | 1083 | CH_ERR("%s: could not read MAC address from VPD ROM\n", |
798 | adapter->port[i].dev->name); | 1084 | adapter->port[i].dev->name); |
799 | goto error; | 1085 | goto error; |
@@ -806,7 +1092,7 @@ int __devinit t1_init_sw_modules(adapter_t *adapter, | |||
806 | t1_interrupts_clear(adapter); | 1092 | t1_interrupts_clear(adapter); |
807 | return 0; | 1093 | return 0; |
808 | 1094 | ||
809 | error: | 1095 | error: |
810 | t1_free_sw_modules(adapter); | 1096 | t1_free_sw_modules(adapter); |
811 | return -1; | 1097 | return -1; |
812 | } | 1098 | } |