diff options
author | Ramkrishna Vepa <ram.vepa@neterion.com> | 2007-12-17 14:40:15 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:07:24 -0500 |
commit | b7c5678f0b1e6c385b0b308a9e8298edf3c91a20 (patch) | |
tree | b349672013a20ce9a600667aa967cdab6a119219 /drivers | |
parent | 2fda096d188ddae51a0fe8cd5b13cf9c84b03c1e (diff) |
S2io: Fixes to enable multiple transmit fifos
Multiple transmit fifo initialization -
- Assigned equal scheduling priority for all configured FIFO's.
- Modularized transmit traffic interrupt initialization since it is executed in
s2io_card_up and s2io_link. Enable continuous tx interrupt when link is UP
and vice verse.
- Enable transmit interrupts for all configured transmit fifos.
- Fixed typo errors.
Signed-off-by: Surjit Reang <surjit.reang@neterion.com>
Signed-off-by: Sreenivasa Honnur <sreenivasa.honnur@neterion.com>
Signed-off-by: Ramkrishna Vepa <ram.vepa@neterion.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/s2io.c | 193 |
1 files changed, 104 insertions, 89 deletions
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index e2c206c7391b..5fab7d7b5d74 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -84,7 +84,7 @@ | |||
84 | #include "s2io.h" | 84 | #include "s2io.h" |
85 | #include "s2io-regs.h" | 85 | #include "s2io-regs.h" |
86 | 86 | ||
87 | #define DRV_VERSION "2.0.26.15-1" | 87 | #define DRV_VERSION "2.0.26.15-2" |
88 | 88 | ||
89 | /* S2io Driver name & version. */ | 89 | /* S2io Driver name & version. */ |
90 | static char s2io_driver_name[] = "Neterion"; | 90 | static char s2io_driver_name[] = "Neterion"; |
@@ -1079,8 +1079,67 @@ static int s2io_print_pci_mode(struct s2io_nic *nic) | |||
1079 | } | 1079 | } |
1080 | 1080 | ||
1081 | /** | 1081 | /** |
1082 | * init_tti - Initialization transmit traffic interrupt scheme | ||
1083 | * @nic: device private variable | ||
1084 | * @link: link status (UP/DOWN) used to enable/disable continuous | ||
1085 | * transmit interrupts | ||
1086 | * Description: The function configures transmit traffic interrupts | ||
1087 | * Return Value: SUCCESS on success and | ||
1088 | * '-1' on failure | ||
1089 | */ | ||
1090 | |||
1091 | int init_tti(struct s2io_nic *nic, int link) | ||
1092 | { | ||
1093 | struct XENA_dev_config __iomem *bar0 = nic->bar0; | ||
1094 | register u64 val64 = 0; | ||
1095 | int i; | ||
1096 | struct config_param *config; | ||
1097 | |||
1098 | config = &nic->config; | ||
1099 | |||
1100 | for (i = 0; i < config->tx_fifo_num; i++) { | ||
1101 | /* | ||
1102 | * TTI Initialization. Default Tx timer gets us about | ||
1103 | * 250 interrupts per sec. Continuous interrupts are enabled | ||
1104 | * by default. | ||
1105 | */ | ||
1106 | if (nic->device_type == XFRAME_II_DEVICE) { | ||
1107 | int count = (nic->config.bus_speed * 125)/2; | ||
1108 | val64 = TTI_DATA1_MEM_TX_TIMER_VAL(count); | ||
1109 | } else | ||
1110 | val64 = TTI_DATA1_MEM_TX_TIMER_VAL(0x2078); | ||
1111 | |||
1112 | val64 |= TTI_DATA1_MEM_TX_URNG_A(0xA) | | ||
1113 | TTI_DATA1_MEM_TX_URNG_B(0x10) | | ||
1114 | TTI_DATA1_MEM_TX_URNG_C(0x30) | | ||
1115 | TTI_DATA1_MEM_TX_TIMER_AC_EN; | ||
1116 | |||
1117 | if (use_continuous_tx_intrs && (link == LINK_UP)) | ||
1118 | val64 |= TTI_DATA1_MEM_TX_TIMER_CI_EN; | ||
1119 | writeq(val64, &bar0->tti_data1_mem); | ||
1120 | |||
1121 | val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) | | ||
1122 | TTI_DATA2_MEM_TX_UFC_B(0x20) | | ||
1123 | TTI_DATA2_MEM_TX_UFC_C(0x40) | | ||
1124 | TTI_DATA2_MEM_TX_UFC_D(0x80); | ||
1125 | |||
1126 | writeq(val64, &bar0->tti_data2_mem); | ||
1127 | |||
1128 | val64 = TTI_CMD_MEM_WE | TTI_CMD_MEM_STROBE_NEW_CMD | | ||
1129 | TTI_CMD_MEM_OFFSET(i); | ||
1130 | writeq(val64, &bar0->tti_command_mem); | ||
1131 | |||
1132 | if (wait_for_cmd_complete(&bar0->tti_command_mem, | ||
1133 | TTI_CMD_MEM_STROBE_NEW_CMD, S2IO_BIT_RESET) != SUCCESS) | ||
1134 | return FAILURE; | ||
1135 | } | ||
1136 | |||
1137 | return SUCCESS; | ||
1138 | } | ||
1139 | |||
1140 | /** | ||
1082 | * init_nic - Initialization of hardware | 1141 | * init_nic - Initialization of hardware |
1083 | * @nic: device peivate variable | 1142 | * @nic: device private variable |
1084 | * Description: The function sequentially configures every block | 1143 | * Description: The function sequentially configures every block |
1085 | * of the H/W from their reset values. | 1144 | * of the H/W from their reset values. |
1086 | * Return Value: SUCCESS on success and | 1145 | * Return Value: SUCCESS on success and |
@@ -1185,9 +1244,9 @@ static int init_nic(struct s2io_nic *nic) | |||
1185 | 1244 | ||
1186 | for (i = 0, j = 0; i < config->tx_fifo_num; i++) { | 1245 | for (i = 0, j = 0; i < config->tx_fifo_num; i++) { |
1187 | val64 |= | 1246 | val64 |= |
1188 | vBIT(config->tx_cfg[i].fifo_len - 1, ((i * 32) + 19), | 1247 | vBIT(config->tx_cfg[i].fifo_len - 1, ((j * 32) + 19), |
1189 | 13) | vBIT(config->tx_cfg[i].fifo_priority, | 1248 | 13) | vBIT(config->tx_cfg[i].fifo_priority, |
1190 | ((i * 32) + 5), 3); | 1249 | ((j * 32) + 5), 3); |
1191 | 1250 | ||
1192 | if (i == (config->tx_fifo_num - 1)) { | 1251 | if (i == (config->tx_fifo_num - 1)) { |
1193 | if (i % 2 == 0) | 1252 | if (i % 2 == 0) |
@@ -1198,17 +1257,25 @@ static int init_nic(struct s2io_nic *nic) | |||
1198 | case 1: | 1257 | case 1: |
1199 | writeq(val64, &bar0->tx_fifo_partition_0); | 1258 | writeq(val64, &bar0->tx_fifo_partition_0); |
1200 | val64 = 0; | 1259 | val64 = 0; |
1260 | j = 0; | ||
1201 | break; | 1261 | break; |
1202 | case 3: | 1262 | case 3: |
1203 | writeq(val64, &bar0->tx_fifo_partition_1); | 1263 | writeq(val64, &bar0->tx_fifo_partition_1); |
1204 | val64 = 0; | 1264 | val64 = 0; |
1265 | j = 0; | ||
1205 | break; | 1266 | break; |
1206 | case 5: | 1267 | case 5: |
1207 | writeq(val64, &bar0->tx_fifo_partition_2); | 1268 | writeq(val64, &bar0->tx_fifo_partition_2); |
1208 | val64 = 0; | 1269 | val64 = 0; |
1270 | j = 0; | ||
1209 | break; | 1271 | break; |
1210 | case 7: | 1272 | case 7: |
1211 | writeq(val64, &bar0->tx_fifo_partition_3); | 1273 | writeq(val64, &bar0->tx_fifo_partition_3); |
1274 | val64 = 0; | ||
1275 | j = 0; | ||
1276 | break; | ||
1277 | default: | ||
1278 | j++; | ||
1212 | break; | 1279 | break; |
1213 | } | 1280 | } |
1214 | } | 1281 | } |
@@ -1294,11 +1361,11 @@ static int init_nic(struct s2io_nic *nic) | |||
1294 | 1361 | ||
1295 | /* | 1362 | /* |
1296 | * Filling Tx round robin registers | 1363 | * Filling Tx round robin registers |
1297 | * as per the number of FIFOs | 1364 | * as per the number of FIFOs for equal scheduling priority |
1298 | */ | 1365 | */ |
1299 | switch (config->tx_fifo_num) { | 1366 | switch (config->tx_fifo_num) { |
1300 | case 1: | 1367 | case 1: |
1301 | val64 = 0x0000000000000000ULL; | 1368 | val64 = 0x0; |
1302 | writeq(val64, &bar0->tx_w_round_robin_0); | 1369 | writeq(val64, &bar0->tx_w_round_robin_0); |
1303 | writeq(val64, &bar0->tx_w_round_robin_1); | 1370 | writeq(val64, &bar0->tx_w_round_robin_1); |
1304 | writeq(val64, &bar0->tx_w_round_robin_2); | 1371 | writeq(val64, &bar0->tx_w_round_robin_2); |
@@ -1306,87 +1373,78 @@ static int init_nic(struct s2io_nic *nic) | |||
1306 | writeq(val64, &bar0->tx_w_round_robin_4); | 1373 | writeq(val64, &bar0->tx_w_round_robin_4); |
1307 | break; | 1374 | break; |
1308 | case 2: | 1375 | case 2: |
1309 | val64 = 0x0000010000010000ULL; | 1376 | val64 = 0x0001000100010001ULL; |
1310 | writeq(val64, &bar0->tx_w_round_robin_0); | 1377 | writeq(val64, &bar0->tx_w_round_robin_0); |
1311 | val64 = 0x0100000100000100ULL; | ||
1312 | writeq(val64, &bar0->tx_w_round_robin_1); | 1378 | writeq(val64, &bar0->tx_w_round_robin_1); |
1313 | val64 = 0x0001000001000001ULL; | ||
1314 | writeq(val64, &bar0->tx_w_round_robin_2); | 1379 | writeq(val64, &bar0->tx_w_round_robin_2); |
1315 | val64 = 0x0000010000010000ULL; | ||
1316 | writeq(val64, &bar0->tx_w_round_robin_3); | 1380 | writeq(val64, &bar0->tx_w_round_robin_3); |
1317 | val64 = 0x0100000000000000ULL; | 1381 | val64 = 0x0001000100000000ULL; |
1318 | writeq(val64, &bar0->tx_w_round_robin_4); | 1382 | writeq(val64, &bar0->tx_w_round_robin_4); |
1319 | break; | 1383 | break; |
1320 | case 3: | 1384 | case 3: |
1321 | val64 = 0x0001000102000001ULL; | 1385 | val64 = 0x0001020001020001ULL; |
1322 | writeq(val64, &bar0->tx_w_round_robin_0); | 1386 | writeq(val64, &bar0->tx_w_round_robin_0); |
1323 | val64 = 0x0001020000010001ULL; | 1387 | val64 = 0x0200010200010200ULL; |
1324 | writeq(val64, &bar0->tx_w_round_robin_1); | 1388 | writeq(val64, &bar0->tx_w_round_robin_1); |
1325 | val64 = 0x0200000100010200ULL; | 1389 | val64 = 0x0102000102000102ULL; |
1326 | writeq(val64, &bar0->tx_w_round_robin_2); | 1390 | writeq(val64, &bar0->tx_w_round_robin_2); |
1327 | val64 = 0x0001000102000001ULL; | 1391 | val64 = 0x0001020001020001ULL; |
1328 | writeq(val64, &bar0->tx_w_round_robin_3); | 1392 | writeq(val64, &bar0->tx_w_round_robin_3); |
1329 | val64 = 0x0001020000000000ULL; | 1393 | val64 = 0x0200010200000000ULL; |
1330 | writeq(val64, &bar0->tx_w_round_robin_4); | 1394 | writeq(val64, &bar0->tx_w_round_robin_4); |
1331 | break; | 1395 | break; |
1332 | case 4: | 1396 | case 4: |
1333 | val64 = 0x0001020300010200ULL; | 1397 | val64 = 0x0001020300010203ULL; |
1334 | writeq(val64, &bar0->tx_w_round_robin_0); | 1398 | writeq(val64, &bar0->tx_w_round_robin_0); |
1335 | val64 = 0x0100000102030001ULL; | ||
1336 | writeq(val64, &bar0->tx_w_round_robin_1); | 1399 | writeq(val64, &bar0->tx_w_round_robin_1); |
1337 | val64 = 0x0200010000010203ULL; | ||
1338 | writeq(val64, &bar0->tx_w_round_robin_2); | 1400 | writeq(val64, &bar0->tx_w_round_robin_2); |
1339 | val64 = 0x0001020001000001ULL; | ||
1340 | writeq(val64, &bar0->tx_w_round_robin_3); | 1401 | writeq(val64, &bar0->tx_w_round_robin_3); |
1341 | val64 = 0x0203000100000000ULL; | 1402 | val64 = 0x0001020300000000ULL; |
1342 | writeq(val64, &bar0->tx_w_round_robin_4); | 1403 | writeq(val64, &bar0->tx_w_round_robin_4); |
1343 | break; | 1404 | break; |
1344 | case 5: | 1405 | case 5: |
1345 | val64 = 0x0001000203000102ULL; | 1406 | val64 = 0x0001020304000102ULL; |
1346 | writeq(val64, &bar0->tx_w_round_robin_0); | 1407 | writeq(val64, &bar0->tx_w_round_robin_0); |
1347 | val64 = 0x0001020001030004ULL; | 1408 | val64 = 0x0304000102030400ULL; |
1348 | writeq(val64, &bar0->tx_w_round_robin_1); | 1409 | writeq(val64, &bar0->tx_w_round_robin_1); |
1349 | val64 = 0x0001000203000102ULL; | 1410 | val64 = 0x0102030400010203ULL; |
1350 | writeq(val64, &bar0->tx_w_round_robin_2); | 1411 | writeq(val64, &bar0->tx_w_round_robin_2); |
1351 | val64 = 0x0001020001030004ULL; | 1412 | val64 = 0x0400010203040001ULL; |
1352 | writeq(val64, &bar0->tx_w_round_robin_3); | 1413 | writeq(val64, &bar0->tx_w_round_robin_3); |
1353 | val64 = 0x0001000000000000ULL; | 1414 | val64 = 0x0203040000000000ULL; |
1354 | writeq(val64, &bar0->tx_w_round_robin_4); | 1415 | writeq(val64, &bar0->tx_w_round_robin_4); |
1355 | break; | 1416 | break; |
1356 | case 6: | 1417 | case 6: |
1357 | val64 = 0x0001020304000102ULL; | 1418 | val64 = 0x0001020304050001ULL; |
1358 | writeq(val64, &bar0->tx_w_round_robin_0); | 1419 | writeq(val64, &bar0->tx_w_round_robin_0); |
1359 | val64 = 0x0304050001020001ULL; | 1420 | val64 = 0x0203040500010203ULL; |
1360 | writeq(val64, &bar0->tx_w_round_robin_1); | 1421 | writeq(val64, &bar0->tx_w_round_robin_1); |
1361 | val64 = 0x0203000100000102ULL; | 1422 | val64 = 0x0405000102030405ULL; |
1362 | writeq(val64, &bar0->tx_w_round_robin_2); | 1423 | writeq(val64, &bar0->tx_w_round_robin_2); |
1363 | val64 = 0x0304000102030405ULL; | 1424 | val64 = 0x0001020304050001ULL; |
1364 | writeq(val64, &bar0->tx_w_round_robin_3); | 1425 | writeq(val64, &bar0->tx_w_round_robin_3); |
1365 | val64 = 0x0001000200000000ULL; | 1426 | val64 = 0x0203040500000000ULL; |
1366 | writeq(val64, &bar0->tx_w_round_robin_4); | 1427 | writeq(val64, &bar0->tx_w_round_robin_4); |
1367 | break; | 1428 | break; |
1368 | case 7: | 1429 | case 7: |
1369 | val64 = 0x0001020001020300ULL; | 1430 | val64 = 0x0001020304050600ULL; |
1370 | writeq(val64, &bar0->tx_w_round_robin_0); | 1431 | writeq(val64, &bar0->tx_w_round_robin_0); |
1371 | val64 = 0x0102030400010203ULL; | 1432 | val64 = 0x0102030405060001ULL; |
1372 | writeq(val64, &bar0->tx_w_round_robin_1); | 1433 | writeq(val64, &bar0->tx_w_round_robin_1); |
1373 | val64 = 0x0405060001020001ULL; | 1434 | val64 = 0x0203040506000102ULL; |
1374 | writeq(val64, &bar0->tx_w_round_robin_2); | 1435 | writeq(val64, &bar0->tx_w_round_robin_2); |
1375 | val64 = 0x0304050000010200ULL; | 1436 | val64 = 0x0304050600010203ULL; |
1376 | writeq(val64, &bar0->tx_w_round_robin_3); | 1437 | writeq(val64, &bar0->tx_w_round_robin_3); |
1377 | val64 = 0x0102030000000000ULL; | 1438 | val64 = 0x0405060000000000ULL; |
1378 | writeq(val64, &bar0->tx_w_round_robin_4); | 1439 | writeq(val64, &bar0->tx_w_round_robin_4); |
1379 | break; | 1440 | break; |
1380 | case 8: | 1441 | case 8: |
1381 | val64 = 0x0001020300040105ULL; | 1442 | val64 = 0x0001020304050607ULL; |
1382 | writeq(val64, &bar0->tx_w_round_robin_0); | 1443 | writeq(val64, &bar0->tx_w_round_robin_0); |
1383 | val64 = 0x0200030106000204ULL; | ||
1384 | writeq(val64, &bar0->tx_w_round_robin_1); | 1444 | writeq(val64, &bar0->tx_w_round_robin_1); |
1385 | val64 = 0x0103000502010007ULL; | ||
1386 | writeq(val64, &bar0->tx_w_round_robin_2); | 1445 | writeq(val64, &bar0->tx_w_round_robin_2); |
1387 | val64 = 0x0304010002060500ULL; | ||
1388 | writeq(val64, &bar0->tx_w_round_robin_3); | 1446 | writeq(val64, &bar0->tx_w_round_robin_3); |
1389 | val64 = 0x0103020400000000ULL; | 1447 | val64 = 0x0001020300000000ULL; |
1390 | writeq(val64, &bar0->tx_w_round_robin_4); | 1448 | writeq(val64, &bar0->tx_w_round_robin_4); |
1391 | break; | 1449 | break; |
1392 | } | 1450 | } |
@@ -1563,58 +1621,14 @@ static int init_nic(struct s2io_nic *nic) | |||
1563 | MAC_RX_LINK_UTIL_VAL(rmac_util_period); | 1621 | MAC_RX_LINK_UTIL_VAL(rmac_util_period); |
1564 | writeq(val64, &bar0->mac_link_util); | 1622 | writeq(val64, &bar0->mac_link_util); |
1565 | 1623 | ||
1566 | |||
1567 | /* | 1624 | /* |
1568 | * Initializing the Transmit and Receive Traffic Interrupt | 1625 | * Initializing the Transmit and Receive Traffic Interrupt |
1569 | * Scheme. | 1626 | * Scheme. |
1570 | */ | 1627 | */ |
1571 | /* | ||
1572 | * TTI Initialization. Default Tx timer gets us about | ||
1573 | * 250 interrupts per sec. Continuous interrupts are enabled | ||
1574 | * by default. | ||
1575 | */ | ||
1576 | if (nic->device_type == XFRAME_II_DEVICE) { | ||
1577 | int count = (nic->config.bus_speed * 125)/2; | ||
1578 | val64 = TTI_DATA1_MEM_TX_TIMER_VAL(count); | ||
1579 | } else { | ||
1580 | |||
1581 | val64 = TTI_DATA1_MEM_TX_TIMER_VAL(0x2078); | ||
1582 | } | ||
1583 | val64 |= TTI_DATA1_MEM_TX_URNG_A(0xA) | | ||
1584 | TTI_DATA1_MEM_TX_URNG_B(0x10) | | ||
1585 | TTI_DATA1_MEM_TX_URNG_C(0x30) | TTI_DATA1_MEM_TX_TIMER_AC_EN; | ||
1586 | if (use_continuous_tx_intrs) | ||
1587 | val64 |= TTI_DATA1_MEM_TX_TIMER_CI_EN; | ||
1588 | writeq(val64, &bar0->tti_data1_mem); | ||
1589 | |||
1590 | val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) | | ||
1591 | TTI_DATA2_MEM_TX_UFC_B(0x20) | | ||
1592 | TTI_DATA2_MEM_TX_UFC_C(0x40) | TTI_DATA2_MEM_TX_UFC_D(0x80); | ||
1593 | writeq(val64, &bar0->tti_data2_mem); | ||
1594 | 1628 | ||
1595 | val64 = TTI_CMD_MEM_WE | TTI_CMD_MEM_STROBE_NEW_CMD; | 1629 | /* Initialize TTI */ |
1596 | writeq(val64, &bar0->tti_command_mem); | 1630 | if (SUCCESS != init_tti(nic, nic->last_link_state)) |
1597 | 1631 | return -ENODEV; | |
1598 | /* | ||
1599 | * Once the operation completes, the Strobe bit of the command | ||
1600 | * register will be reset. We poll for this particular condition | ||
1601 | * We wait for a maximum of 500ms for the operation to complete, | ||
1602 | * if it's not complete by then we return error. | ||
1603 | */ | ||
1604 | time = 0; | ||
1605 | while (TRUE) { | ||
1606 | val64 = readq(&bar0->tti_command_mem); | ||
1607 | if (!(val64 & TTI_CMD_MEM_STROBE_NEW_CMD)) { | ||
1608 | break; | ||
1609 | } | ||
1610 | if (time > 10) { | ||
1611 | DBG_PRINT(ERR_DBG, "%s: TTI init Failed\n", | ||
1612 | dev->name); | ||
1613 | return -ENODEV; | ||
1614 | } | ||
1615 | msleep(50); | ||
1616 | time++; | ||
1617 | } | ||
1618 | 1632 | ||
1619 | /* RTI Initialization */ | 1633 | /* RTI Initialization */ |
1620 | if (nic->device_type == XFRAME_II_DEVICE) { | 1634 | if (nic->device_type == XFRAME_II_DEVICE) { |
@@ -7443,6 +7457,7 @@ static void s2io_link(struct s2io_nic * sp, int link) | |||
7443 | struct net_device *dev = (struct net_device *) sp->dev; | 7457 | struct net_device *dev = (struct net_device *) sp->dev; |
7444 | 7458 | ||
7445 | if (link != sp->last_link_state) { | 7459 | if (link != sp->last_link_state) { |
7460 | init_tti(sp, link); | ||
7446 | if (link == LINK_DOWN) { | 7461 | if (link == LINK_DOWN) { |
7447 | DBG_PRINT(ERR_DBG, "%s: Link down\n", dev->name); | 7462 | DBG_PRINT(ERR_DBG, "%s: Link down\n", dev->name); |
7448 | netif_carrier_off(dev); | 7463 | netif_carrier_off(dev); |
@@ -7541,7 +7556,7 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type) | |||
7541 | /** | 7556 | /** |
7542 | * rts_ds_steer - Receive traffic steering based on IPv4 or IPv6 TOS | 7557 | * rts_ds_steer - Receive traffic steering based on IPv4 or IPv6 TOS |
7543 | * or Traffic class respectively. | 7558 | * or Traffic class respectively. |
7544 | * @nic: device peivate variable | 7559 | * @nic: device private variable |
7545 | * Description: The function configures the receive steering to | 7560 | * Description: The function configures the receive steering to |
7546 | * desired receive ring. | 7561 | * desired receive ring. |
7547 | * Return Value: SUCCESS on success and | 7562 | * Return Value: SUCCESS on success and |