diff options
author | Eric Schneider <eric.schneider@neteffect.com> | 2008-04-29 16:46:54 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2008-04-29 16:46:54 -0400 |
commit | 0e1de5d62e751ca9c589d8dfabfc1e5074e62724 (patch) | |
tree | 164536558179b7741fe2659f11c19b26a3f185a7 | |
parent | 37dab4112d7b53c3574426ef7bdd92a78d32ac3e (diff) |
RDMA/nes: Add support for SFP+ PHY
This patch enables the iw_nes module for NetEffect RNICs to support
additional PHYs including SFP+ (referred to as ARGUS in the code).
Signed-off-by: Eric Schneider <eric.schneider@neteffect.com>
Signed-off-by: Glenn Streiff <gstreiff@neteffect.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
-rw-r--r-- | drivers/infiniband/hw/nes/nes.h | 4 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_hw.c | 231 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_hw.h | 6 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_nic.c | 72 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_utils.c | 10 |
5 files changed, 259 insertions, 64 deletions
diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h index 484b5e30badd..1f9f7bf73862 100644 --- a/drivers/infiniband/hw/nes/nes.h +++ b/drivers/infiniband/hw/nes/nes.h | |||
@@ -536,8 +536,8 @@ int nes_register_ofa_device(struct nes_ib_device *); | |||
536 | int nes_read_eeprom_values(struct nes_device *, struct nes_adapter *); | 536 | int nes_read_eeprom_values(struct nes_device *, struct nes_adapter *); |
537 | void nes_write_1G_phy_reg(struct nes_device *, u8, u8, u16); | 537 | void nes_write_1G_phy_reg(struct nes_device *, u8, u8, u16); |
538 | void nes_read_1G_phy_reg(struct nes_device *, u8, u8, u16 *); | 538 | void nes_read_1G_phy_reg(struct nes_device *, u8, u8, u16 *); |
539 | void nes_write_10G_phy_reg(struct nes_device *, u16, u8, u16); | 539 | void nes_write_10G_phy_reg(struct nes_device *, u16, u8, u16, u16); |
540 | void nes_read_10G_phy_reg(struct nes_device *, u16, u8); | 540 | void nes_read_10G_phy_reg(struct nes_device *, u8, u8, u16); |
541 | struct nes_cqp_request *nes_get_cqp_request(struct nes_device *); | 541 | struct nes_cqp_request *nes_get_cqp_request(struct nes_device *); |
542 | void nes_post_cqp_request(struct nes_device *, struct nes_cqp_request *, int); | 542 | void nes_post_cqp_request(struct nes_device *, struct nes_cqp_request *, int); |
543 | int nes_arp_table(struct nes_device *, u32, u8 *, u32); | 543 | int nes_arp_table(struct nes_device *, u32, u8 *, u32); |
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index f824ecb9f879..e9db6ef04ad8 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c | |||
@@ -1208,11 +1208,16 @@ int nes_init_phy(struct nes_device *nesdev) | |||
1208 | { | 1208 | { |
1209 | struct nes_adapter *nesadapter = nesdev->nesadapter; | 1209 | struct nes_adapter *nesadapter = nesdev->nesadapter; |
1210 | u32 counter = 0; | 1210 | u32 counter = 0; |
1211 | u32 sds_common_control0; | ||
1211 | u32 mac_index = nesdev->mac_index; | 1212 | u32 mac_index = nesdev->mac_index; |
1212 | u32 tx_config; | 1213 | u32 tx_config = 0; |
1213 | u16 phy_data; | 1214 | u16 phy_data; |
1215 | u32 temp_phy_data = 0; | ||
1216 | u32 temp_phy_data2 = 0; | ||
1217 | u32 i = 0; | ||
1214 | 1218 | ||
1215 | if (nesadapter->OneG_Mode) { | 1219 | if ((nesadapter->OneG_Mode) && |
1220 | (nesadapter->phy_type[mac_index] != NES_PHY_TYPE_PUMA_1G)) { | ||
1216 | nes_debug(NES_DBG_PHY, "1G PHY, mac_index = %d.\n", mac_index); | 1221 | nes_debug(NES_DBG_PHY, "1G PHY, mac_index = %d.\n", mac_index); |
1217 | if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_1G) { | 1222 | if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_1G) { |
1218 | printk(PFX "%s: Programming mdc config for 1G\n", __func__); | 1223 | printk(PFX "%s: Programming mdc config for 1G\n", __func__); |
@@ -1278,12 +1283,126 @@ int nes_init_phy(struct nes_device *nesdev) | |||
1278 | nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data); | 1283 | nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], &phy_data); |
1279 | nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], phy_data | 0x0300); | 1284 | nes_write_1G_phy_reg(nesdev, 0, nesadapter->phy_index[mac_index], phy_data | 0x0300); |
1280 | } else { | 1285 | } else { |
1281 | if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_IRIS) { | 1286 | if ((nesadapter->phy_type[mac_index] == NES_PHY_TYPE_IRIS) || |
1287 | (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_ARGUS)) { | ||
1282 | /* setup 10G MDIO operation */ | 1288 | /* setup 10G MDIO operation */ |
1283 | tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG); | 1289 | tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG); |
1284 | tx_config |= 0x14; | 1290 | tx_config |= 0x14; |
1285 | nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config); | 1291 | nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config); |
1286 | } | 1292 | } |
1293 | if ((nesadapter->phy_type[mac_index] == NES_PHY_TYPE_ARGUS)) { | ||
1294 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee); | ||
1295 | |||
1296 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
1297 | mdelay(10); | ||
1298 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee); | ||
1299 | temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
1300 | |||
1301 | /* | ||
1302 | * if firmware is already running (like from a | ||
1303 | * driver un-load/load, don't do anything. | ||
1304 | */ | ||
1305 | if (temp_phy_data == temp_phy_data2) { | ||
1306 | /* configure QT2505 AMCC PHY */ | ||
1307 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0x0000, 0x8000); | ||
1308 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc300, 0x0000); | ||
1309 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc302, 0x0044); | ||
1310 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc318, 0x0052); | ||
1311 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc319, 0x0008); | ||
1312 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc31a, 0x0098); | ||
1313 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0026, 0x0E00); | ||
1314 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0027, 0x0000); | ||
1315 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0x0028, 0xA528); | ||
1316 | |||
1317 | /* | ||
1318 | * remove micro from reset; chip boots from ROM, | ||
1319 | * uploads EEPROM f/w image, uC executes f/w | ||
1320 | */ | ||
1321 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc300, 0x0002); | ||
1322 | |||
1323 | /* | ||
1324 | * wait for heart beat to start to | ||
1325 | * know loading is done | ||
1326 | */ | ||
1327 | counter = 0; | ||
1328 | do { | ||
1329 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee); | ||
1330 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
1331 | if (counter++ > 1000) { | ||
1332 | nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from heartbeat check <this is bad!!!> \n"); | ||
1333 | break; | ||
1334 | } | ||
1335 | mdelay(100); | ||
1336 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7ee); | ||
1337 | temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
1338 | } while ((temp_phy_data2 == temp_phy_data)); | ||
1339 | |||
1340 | /* | ||
1341 | * wait for tracking to start to know | ||
1342 | * f/w is good to go | ||
1343 | */ | ||
1344 | counter = 0; | ||
1345 | do { | ||
1346 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x3, 0xd7fd); | ||
1347 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
1348 | if (counter++ > 1000) { | ||
1349 | nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from status check <this is bad!!!> \n"); | ||
1350 | break; | ||
1351 | } | ||
1352 | mdelay(1000); | ||
1353 | /* | ||
1354 | * nes_debug(NES_DBG_PHY, "AMCC PHY- phy_status not ready yet = 0x%02X\n", | ||
1355 | * temp_phy_data); | ||
1356 | */ | ||
1357 | } while (((temp_phy_data & 0xff) != 0x50) && ((temp_phy_data & 0xff) != 0x70)); | ||
1358 | |||
1359 | /* set LOS Control invert RXLOSB_I_PADINV */ | ||
1360 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd003, 0x0000); | ||
1361 | /* set LOS Control to mask of RXLOSB_I */ | ||
1362 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xc314, 0x0042); | ||
1363 | /* set LED1 to input mode (LED1 and LED2 share same LED) */ | ||
1364 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd006, 0x0007); | ||
1365 | /* set LED2 to RX link_status and activity */ | ||
1366 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd007, 0x000A); | ||
1367 | /* set LED3 to RX link_status */ | ||
1368 | nes_write_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 0x1, 0xd008, 0x0009); | ||
1369 | |||
1370 | /* | ||
1371 | * reset the res-calibration on t2 | ||
1372 | * serdes; ensures it is stable after | ||
1373 | * the amcc phy is stable | ||
1374 | */ | ||
1375 | |||
1376 | sds_common_control0 = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0); | ||
1377 | sds_common_control0 |= 0x1; | ||
1378 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds_common_control0); | ||
1379 | |||
1380 | /* release the res-calibration reset */ | ||
1381 | sds_common_control0 &= 0xfffffffe; | ||
1382 | nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds_common_control0); | ||
1383 | |||
1384 | i = 0; | ||
1385 | while (((nes_read32(nesdev->regs+NES_SOFTWARE_RESET) & 0x00000040) != 0x00000040) | ||
1386 | && (i++ < 5000)) { | ||
1387 | /* mdelay(1); */ | ||
1388 | } | ||
1389 | |||
1390 | /* | ||
1391 | * wait for link train done before moving on, | ||
1392 | * or will get an interupt storm | ||
1393 | */ | ||
1394 | counter = 0; | ||
1395 | do { | ||
1396 | temp_phy_data = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + | ||
1397 | (0x200 * (nesdev->mac_index & 1))); | ||
1398 | if (counter++ > 1000) { | ||
1399 | nes_debug(NES_DBG_PHY, "AMCC PHY- breaking from link train wait <this is bad, link didnt train!!!>\n"); | ||
1400 | break; | ||
1401 | } | ||
1402 | mdelay(1); | ||
1403 | } while (((temp_phy_data & 0x0f1f0000) != 0x0f0f0000)); | ||
1404 | } | ||
1405 | } | ||
1287 | } | 1406 | } |
1288 | return 0; | 1407 | return 0; |
1289 | } | 1408 | } |
@@ -2107,6 +2226,8 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
2107 | u32 u32temp; | 2226 | u32 u32temp; |
2108 | u16 phy_data; | 2227 | u16 phy_data; |
2109 | u16 temp_phy_data; | 2228 | u16 temp_phy_data; |
2229 | u32 pcs_val = 0x0f0f0000; | ||
2230 | u32 pcs_mask = 0x0f1f0000; | ||
2110 | 2231 | ||
2111 | spin_lock_irqsave(&nesadapter->phy_lock, flags); | 2232 | spin_lock_irqsave(&nesadapter->phy_lock, flags); |
2112 | if (nesadapter->mac_sw_state[mac_number] != NES_MAC_SW_IDLE) { | 2233 | if (nesadapter->mac_sw_state[mac_number] != NES_MAC_SW_IDLE) { |
@@ -2170,13 +2291,30 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
2170 | nes_debug(NES_DBG_PHY, "Eth SERDES Common Status: 0=0x%08X, 1=0x%08X\n", | 2291 | nes_debug(NES_DBG_PHY, "Eth SERDES Common Status: 0=0x%08X, 1=0x%08X\n", |
2171 | nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0), | 2292 | nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0), |
2172 | nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0+0x200)); | 2293 | nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_STATUS0+0x200)); |
2173 | pcs_control_status = nes_read_indexed(nesdev, | 2294 | |
2174 | NES_IDX_PHY_PCS_CONTROL_STATUS0 + ((mac_index&1)*0x200)); | 2295 | if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_PUMA_1G) { |
2175 | pcs_control_status = nes_read_indexed(nesdev, | 2296 | switch (mac_index) { |
2176 | NES_IDX_PHY_PCS_CONTROL_STATUS0 + ((mac_index&1)*0x200)); | 2297 | case 1: |
2298 | case 3: | ||
2299 | pcs_control_status = nes_read_indexed(nesdev, | ||
2300 | NES_IDX_PHY_PCS_CONTROL_STATUS0 + 0x200); | ||
2301 | break; | ||
2302 | default: | ||
2303 | pcs_control_status = nes_read_indexed(nesdev, | ||
2304 | NES_IDX_PHY_PCS_CONTROL_STATUS0); | ||
2305 | break; | ||
2306 | } | ||
2307 | } else { | ||
2308 | pcs_control_status = nes_read_indexed(nesdev, | ||
2309 | NES_IDX_PHY_PCS_CONTROL_STATUS0 + ((mac_index & 1) * 0x200)); | ||
2310 | pcs_control_status = nes_read_indexed(nesdev, | ||
2311 | NES_IDX_PHY_PCS_CONTROL_STATUS0 + ((mac_index & 1) * 0x200)); | ||
2312 | } | ||
2313 | |||
2177 | nes_debug(NES_DBG_PHY, "PCS PHY Control/Status%u: 0x%08X\n", | 2314 | nes_debug(NES_DBG_PHY, "PCS PHY Control/Status%u: 0x%08X\n", |
2178 | mac_index, pcs_control_status); | 2315 | mac_index, pcs_control_status); |
2179 | if (nesadapter->OneG_Mode) { | 2316 | if ((nesadapter->OneG_Mode) && |
2317 | (nesadapter->phy_type[mac_index] != NES_PHY_TYPE_PUMA_1G)) { | ||
2180 | u32temp = 0x01010000; | 2318 | u32temp = 0x01010000; |
2181 | if (nesadapter->port_count > 2) { | 2319 | if (nesadapter->port_count > 2) { |
2182 | u32temp |= 0x02020000; | 2320 | u32temp |= 0x02020000; |
@@ -2185,24 +2323,59 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
2185 | phy_data = 0; | 2323 | phy_data = 0; |
2186 | nes_debug(NES_DBG_PHY, "PCS says the link is down\n"); | 2324 | nes_debug(NES_DBG_PHY, "PCS says the link is down\n"); |
2187 | } | 2325 | } |
2188 | } else if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_IRIS) { | ||
2189 | nes_read_10G_phy_reg(nesdev, 1, nesadapter->phy_index[mac_index]); | ||
2190 | temp_phy_data = (u16)nes_read_indexed(nesdev, | ||
2191 | NES_IDX_MAC_MDIO_CONTROL); | ||
2192 | u32temp = 20; | ||
2193 | do { | ||
2194 | nes_read_10G_phy_reg(nesdev, 1, nesadapter->phy_index[mac_index]); | ||
2195 | phy_data = (u16)nes_read_indexed(nesdev, | ||
2196 | NES_IDX_MAC_MDIO_CONTROL); | ||
2197 | if ((phy_data == temp_phy_data) || (!(--u32temp))) | ||
2198 | break; | ||
2199 | temp_phy_data = phy_data; | ||
2200 | } while (1); | ||
2201 | nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n", | ||
2202 | __func__, phy_data, nesadapter->mac_link_down ? "DOWN" : "UP"); | ||
2203 | |||
2204 | } else { | 2326 | } else { |
2205 | phy_data = (0x0f0f0000 == (pcs_control_status & 0x0f1f0000)) ? 4 : 0; | 2327 | switch (nesadapter->phy_type[mac_index]) { |
2328 | case NES_PHY_TYPE_IRIS: | ||
2329 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1); | ||
2330 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
2331 | u32temp = 20; | ||
2332 | do { | ||
2333 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1); | ||
2334 | phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
2335 | if ((phy_data == temp_phy_data) || (!(--u32temp))) | ||
2336 | break; | ||
2337 | temp_phy_data = phy_data; | ||
2338 | } while (1); | ||
2339 | nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n", | ||
2340 | __func__, phy_data, nesadapter->mac_link_down[mac_index] ? "DOWN" : "UP"); | ||
2341 | break; | ||
2342 | |||
2343 | case NES_PHY_TYPE_ARGUS: | ||
2344 | /* clear the alarms */ | ||
2345 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0x0008); | ||
2346 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc001); | ||
2347 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc002); | ||
2348 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc005); | ||
2349 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc006); | ||
2350 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9003); | ||
2351 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9004); | ||
2352 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9005); | ||
2353 | /* check link status */ | ||
2354 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1); | ||
2355 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
2356 | u32temp = 100; | ||
2357 | do { | ||
2358 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1); | ||
2359 | |||
2360 | phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
2361 | if ((phy_data == temp_phy_data) || (!(--u32temp))) | ||
2362 | break; | ||
2363 | temp_phy_data = phy_data; | ||
2364 | } while (1); | ||
2365 | nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n", | ||
2366 | __func__, phy_data, nesadapter->mac_link_down ? "DOWN" : "UP"); | ||
2367 | break; | ||
2368 | |||
2369 | case NES_PHY_TYPE_PUMA_1G: | ||
2370 | if (mac_index < 2) | ||
2371 | pcs_val = pcs_mask = 0x01010000; | ||
2372 | else | ||
2373 | pcs_val = pcs_mask = 0x02020000; | ||
2374 | /* fall through */ | ||
2375 | default: | ||
2376 | phy_data = (pcs_val == (pcs_control_status & pcs_mask)) ? 0x4 : 0x0; | ||
2377 | break; | ||
2378 | } | ||
2206 | } | 2379 | } |
2207 | 2380 | ||
2208 | if (phy_data & 0x0004) { | 2381 | if (phy_data & 0x0004) { |
@@ -2211,8 +2384,8 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
2211 | nes_debug(NES_DBG_PHY, "The Link is UP!!. linkup was %d\n", | 2384 | nes_debug(NES_DBG_PHY, "The Link is UP!!. linkup was %d\n", |
2212 | nesvnic->linkup); | 2385 | nesvnic->linkup); |
2213 | if (nesvnic->linkup == 0) { | 2386 | if (nesvnic->linkup == 0) { |
2214 | printk(PFX "The Link is now up for port %u, netdev %p.\n", | 2387 | printk(PFX "The Link is now up for port %s, netdev %p.\n", |
2215 | mac_index, nesvnic->netdev); | 2388 | nesvnic->netdev->name, nesvnic->netdev); |
2216 | if (netif_queue_stopped(nesvnic->netdev)) | 2389 | if (netif_queue_stopped(nesvnic->netdev)) |
2217 | netif_start_queue(nesvnic->netdev); | 2390 | netif_start_queue(nesvnic->netdev); |
2218 | nesvnic->linkup = 1; | 2391 | nesvnic->linkup = 1; |
@@ -2225,8 +2398,8 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
2225 | nes_debug(NES_DBG_PHY, "The Link is Down!!. linkup was %d\n", | 2398 | nes_debug(NES_DBG_PHY, "The Link is Down!!. linkup was %d\n", |
2226 | nesvnic->linkup); | 2399 | nesvnic->linkup); |
2227 | if (nesvnic->linkup == 1) { | 2400 | if (nesvnic->linkup == 1) { |
2228 | printk(PFX "The Link is now down for port %u, netdev %p.\n", | 2401 | printk(PFX "The Link is now down for port %s, netdev %p.\n", |
2229 | mac_index, nesvnic->netdev); | 2402 | nesvnic->netdev->name, nesvnic->netdev); |
2230 | if (!(netif_queue_stopped(nesvnic->netdev))) | 2403 | if (!(netif_queue_stopped(nesvnic->netdev))) |
2231 | netif_stop_queue(nesvnic->netdev); | 2404 | netif_stop_queue(nesvnic->netdev); |
2232 | nesvnic->linkup = 0; | 2405 | nesvnic->linkup = 0; |
diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h index 6a0f94cc9f0c..405b32ec3127 100644 --- a/drivers/infiniband/hw/nes/nes_hw.h +++ b/drivers/infiniband/hw/nes/nes_hw.h | |||
@@ -35,8 +35,10 @@ | |||
35 | 35 | ||
36 | #include <linux/inet_lro.h> | 36 | #include <linux/inet_lro.h> |
37 | 37 | ||
38 | #define NES_PHY_TYPE_1G 2 | 38 | #define NES_PHY_TYPE_1G 2 |
39 | #define NES_PHY_TYPE_IRIS 3 | 39 | #define NES_PHY_TYPE_IRIS 3 |
40 | #define NES_PHY_TYPE_ARGUS 4 | ||
41 | #define NES_PHY_TYPE_PUMA_1G 5 | ||
40 | #define NES_PHY_TYPE_PUMA_10G 6 | 42 | #define NES_PHY_TYPE_PUMA_10G 6 |
41 | 43 | ||
42 | #define NES_MULTICAST_PF_MAX 8 | 44 | #define NES_MULTICAST_PF_MAX 8 |
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c index 6998af0172ab..d65a846f04be 100644 --- a/drivers/infiniband/hw/nes/nes_nic.c +++ b/drivers/infiniband/hw/nes/nes_nic.c | |||
@@ -1377,21 +1377,29 @@ static int nes_netdev_get_settings(struct net_device *netdev, struct ethtool_cmd | |||
1377 | 1377 | ||
1378 | et_cmd->duplex = DUPLEX_FULL; | 1378 | et_cmd->duplex = DUPLEX_FULL; |
1379 | et_cmd->port = PORT_MII; | 1379 | et_cmd->port = PORT_MII; |
1380 | |||
1380 | if (nesadapter->OneG_Mode) { | 1381 | if (nesadapter->OneG_Mode) { |
1381 | et_cmd->supported = SUPPORTED_1000baseT_Full|SUPPORTED_Autoneg; | ||
1382 | et_cmd->advertising = ADVERTISED_1000baseT_Full|ADVERTISED_Autoneg; | ||
1383 | et_cmd->speed = SPEED_1000; | 1382 | et_cmd->speed = SPEED_1000; |
1384 | nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], | 1383 | if (nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_PUMA_1G) { |
1385 | &phy_data); | 1384 | et_cmd->supported = SUPPORTED_1000baseT_Full; |
1386 | if (phy_data&0x1000) { | 1385 | et_cmd->advertising = ADVERTISED_1000baseT_Full; |
1387 | et_cmd->autoneg = AUTONEG_ENABLE; | 1386 | et_cmd->autoneg = AUTONEG_DISABLE; |
1387 | et_cmd->transceiver = XCVR_INTERNAL; | ||
1388 | et_cmd->phy_address = nesdev->mac_index; | ||
1388 | } else { | 1389 | } else { |
1389 | et_cmd->autoneg = AUTONEG_DISABLE; | 1390 | et_cmd->supported = SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg; |
1391 | et_cmd->advertising = ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg; | ||
1392 | nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], &phy_data); | ||
1393 | if (phy_data & 0x1000) | ||
1394 | et_cmd->autoneg = AUTONEG_ENABLE; | ||
1395 | else | ||
1396 | et_cmd->autoneg = AUTONEG_DISABLE; | ||
1397 | et_cmd->transceiver = XCVR_EXTERNAL; | ||
1398 | et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index]; | ||
1390 | } | 1399 | } |
1391 | et_cmd->transceiver = XCVR_EXTERNAL; | ||
1392 | et_cmd->phy_address = nesadapter->phy_index[nesdev->mac_index]; | ||
1393 | } else { | 1400 | } else { |
1394 | if (nesadapter->phy_type[nesvnic->logical_port] == NES_PHY_TYPE_IRIS) { | 1401 | if ((nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_IRIS) || |
1402 | (nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_ARGUS)) { | ||
1395 | et_cmd->transceiver = XCVR_EXTERNAL; | 1403 | et_cmd->transceiver = XCVR_EXTERNAL; |
1396 | et_cmd->port = PORT_FIBRE; | 1404 | et_cmd->port = PORT_FIBRE; |
1397 | et_cmd->supported = SUPPORTED_FIBRE; | 1405 | et_cmd->supported = SUPPORTED_FIBRE; |
@@ -1422,7 +1430,8 @@ static int nes_netdev_set_settings(struct net_device *netdev, struct ethtool_cmd | |||
1422 | struct nes_adapter *nesadapter = nesdev->nesadapter; | 1430 | struct nes_adapter *nesadapter = nesdev->nesadapter; |
1423 | u16 phy_data; | 1431 | u16 phy_data; |
1424 | 1432 | ||
1425 | if (nesadapter->OneG_Mode) { | 1433 | if ((nesadapter->OneG_Mode) && |
1434 | (nesadapter->phy_type[nesdev->mac_index] != NES_PHY_TYPE_PUMA_1G)) { | ||
1426 | nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], | 1435 | nes_read_1G_phy_reg(nesdev, 0, nesadapter->phy_index[nesdev->mac_index], |
1427 | &phy_data); | 1436 | &phy_data); |
1428 | if (et_cmd->autoneg) { | 1437 | if (et_cmd->autoneg) { |
@@ -1615,27 +1624,34 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, | |||
1615 | list_add_tail(&nesvnic->list, &nesdev->nesadapter->nesvnic_list[nesdev->mac_index]); | 1624 | list_add_tail(&nesvnic->list, &nesdev->nesadapter->nesvnic_list[nesdev->mac_index]); |
1616 | 1625 | ||
1617 | if ((nesdev->netdev_count == 0) && | 1626 | if ((nesdev->netdev_count == 0) && |
1618 | (PCI_FUNC(nesdev->pcidev->devfn) == nesdev->mac_index)) { | 1627 | ((PCI_FUNC(nesdev->pcidev->devfn) == nesdev->mac_index) || |
1619 | nes_debug(NES_DBG_INIT, "Setting up PHY interrupt mask. Using register index 0x%04X\n", | 1628 | ((nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_PUMA_1G) && |
1620 | NES_IDX_PHY_PCS_CONTROL_STATUS0+(0x200*(nesvnic->logical_port&1))); | 1629 | (((PCI_FUNC(nesdev->pcidev->devfn) == 1) && (nesdev->mac_index == 2)) || |
1630 | ((PCI_FUNC(nesdev->pcidev->devfn) == 2) && (nesdev->mac_index == 1)))))) { | ||
1631 | /* | ||
1632 | * nes_debug(NES_DBG_INIT, "Setting up PHY interrupt mask. Using register index 0x%04X\n", | ||
1633 | * NES_IDX_PHY_PCS_CONTROL_STATUS0 + (0x200 * (nesvnic->logical_port & 1))); | ||
1634 | */ | ||
1621 | u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + | 1635 | u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + |
1622 | (0x200*(nesvnic->logical_port&1))); | 1636 | (0x200 * (nesdev->mac_index & 1))); |
1623 | u32temp |= 0x00200000; | 1637 | if (nesdev->nesadapter->phy_type[nesdev->mac_index] != NES_PHY_TYPE_PUMA_1G) { |
1624 | nes_write_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + | 1638 | u32temp |= 0x00200000; |
1625 | (0x200*(nesvnic->logical_port&1)), u32temp); | 1639 | nes_write_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + |
1640 | (0x200 * (nesdev->mac_index & 1)), u32temp); | ||
1641 | } | ||
1642 | |||
1626 | u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + | 1643 | u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + |
1627 | (0x200*(nesvnic->logical_port&1)) ); | 1644 | (0x200 * (nesdev->mac_index & 1))); |
1645 | |||
1628 | if ((u32temp&0x0f1f0000) == 0x0f0f0000) { | 1646 | if ((u32temp&0x0f1f0000) == 0x0f0f0000) { |
1629 | if (nesdev->nesadapter->phy_type[nesvnic->logical_port] == NES_PHY_TYPE_IRIS) { | 1647 | if (nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_IRIS) { |
1630 | nes_init_phy(nesdev); | 1648 | nes_init_phy(nesdev); |
1631 | nes_read_10G_phy_reg(nesdev, 1, | 1649 | nes_read_10G_phy_reg(nesdev, nesdev->nesadapter->phy_index[nesdev->mac_index], 1, 1); |
1632 | nesdev->nesadapter->phy_index[nesvnic->logical_port]); | ||
1633 | temp_phy_data = (u16)nes_read_indexed(nesdev, | 1650 | temp_phy_data = (u16)nes_read_indexed(nesdev, |
1634 | NES_IDX_MAC_MDIO_CONTROL); | 1651 | NES_IDX_MAC_MDIO_CONTROL); |
1635 | u32temp = 20; | 1652 | u32temp = 20; |
1636 | do { | 1653 | do { |
1637 | nes_read_10G_phy_reg(nesdev, 1, | 1654 | nes_read_10G_phy_reg(nesdev, nesdev->nesadapter->phy_index[nesdev->mac_index], 1, 1); |
1638 | nesdev->nesadapter->phy_index[nesvnic->logical_port]); | ||
1639 | phy_data = (u16)nes_read_indexed(nesdev, | 1655 | phy_data = (u16)nes_read_indexed(nesdev, |
1640 | NES_IDX_MAC_MDIO_CONTROL); | 1656 | NES_IDX_MAC_MDIO_CONTROL); |
1641 | if ((phy_data == temp_phy_data) || (!(--u32temp))) | 1657 | if ((phy_data == temp_phy_data) || (!(--u32temp))) |
@@ -1652,6 +1668,14 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, | |||
1652 | nes_debug(NES_DBG_INIT, "The Link is UP!!.\n"); | 1668 | nes_debug(NES_DBG_INIT, "The Link is UP!!.\n"); |
1653 | nesvnic->linkup = 1; | 1669 | nesvnic->linkup = 1; |
1654 | } | 1670 | } |
1671 | } else if (nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_PUMA_1G) { | ||
1672 | nes_debug(NES_DBG_INIT, "mac_index=%d, logical_port=%d, u32temp=0x%04X, PCI_FUNC=%d\n", | ||
1673 | nesdev->mac_index, nesvnic->logical_port, u32temp, PCI_FUNC(nesdev->pcidev->devfn)); | ||
1674 | if (((nesdev->mac_index < 2) && ((u32temp&0x01010000) == 0x01010000)) || | ||
1675 | ((nesdev->mac_index > 1) && ((u32temp&0x02020000) == 0x02020000))) { | ||
1676 | nes_debug(NES_DBG_INIT, "The Link is UP!!.\n"); | ||
1677 | nesvnic->linkup = 1; | ||
1678 | } | ||
1655 | } | 1679 | } |
1656 | /* clear the MAC interrupt status, assumes direct logical to physical mapping */ | 1680 | /* clear the MAC interrupt status, assumes direct logical to physical mapping */ |
1657 | u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index)); | 1681 | u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index)); |
diff --git a/drivers/infiniband/hw/nes/nes_utils.c b/drivers/infiniband/hw/nes/nes_utils.c index c6d5631a6995..fe83d1b2b177 100644 --- a/drivers/infiniband/hw/nes/nes_utils.c +++ b/drivers/infiniband/hw/nes/nes_utils.c | |||
@@ -444,15 +444,13 @@ void nes_read_1G_phy_reg(struct nes_device *nesdev, u8 phy_reg, u8 phy_addr, u16 | |||
444 | /** | 444 | /** |
445 | * nes_write_10G_phy_reg | 445 | * nes_write_10G_phy_reg |
446 | */ | 446 | */ |
447 | void nes_write_10G_phy_reg(struct nes_device *nesdev, u16 phy_reg, | 447 | void nes_write_10G_phy_reg(struct nes_device *nesdev, u16 phy_addr, u8 dev_addr, u16 phy_reg, |
448 | u8 phy_addr, u16 data) | 448 | u16 data) |
449 | { | 449 | { |
450 | u32 dev_addr; | ||
451 | u32 port_addr; | 450 | u32 port_addr; |
452 | u32 u32temp; | 451 | u32 u32temp; |
453 | u32 counter; | 452 | u32 counter; |
454 | 453 | ||
455 | dev_addr = 1; | ||
456 | port_addr = phy_addr; | 454 | port_addr = phy_addr; |
457 | 455 | ||
458 | /* set address */ | 456 | /* set address */ |
@@ -492,14 +490,12 @@ void nes_write_10G_phy_reg(struct nes_device *nesdev, u16 phy_reg, | |||
492 | * This routine only issues the read, the data must be read | 490 | * This routine only issues the read, the data must be read |
493 | * separately. | 491 | * separately. |
494 | */ | 492 | */ |
495 | void nes_read_10G_phy_reg(struct nes_device *nesdev, u16 phy_reg, u8 phy_addr) | 493 | void nes_read_10G_phy_reg(struct nes_device *nesdev, u8 phy_addr, u8 dev_addr, u16 phy_reg) |
496 | { | 494 | { |
497 | u32 dev_addr; | ||
498 | u32 port_addr; | 495 | u32 port_addr; |
499 | u32 u32temp; | 496 | u32 u32temp; |
500 | u32 counter; | 497 | u32 counter; |
501 | 498 | ||
502 | dev_addr = 1; | ||
503 | port_addr = phy_addr; | 499 | port_addr = phy_addr; |
504 | 500 | ||
505 | /* set address */ | 501 | /* set address */ |