aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/nes/nes_hw.c
diff options
context:
space:
mode:
authorEric Schneider <eric.schneider@neteffect.com>2008-04-29 16:46:54 -0400
committerRoland Dreier <rolandd@cisco.com>2008-04-29 16:46:54 -0400
commit0e1de5d62e751ca9c589d8dfabfc1e5074e62724 (patch)
tree164536558179b7741fe2659f11c19b26a3f185a7 /drivers/infiniband/hw/nes/nes_hw.c
parent37dab4112d7b53c3574426ef7bdd92a78d32ac3e (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>
Diffstat (limited to 'drivers/infiniband/hw/nes/nes_hw.c')
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.c231
1 files changed, 202 insertions, 29 deletions
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;