diff options
author | raghavendra.koushik@neterion.com <raghavendra.koushik@neterion.com> | 2005-08-03 15:38:01 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-08-11 00:10:45 -0400 |
commit | b6e3f9828b9dc188cfe80364365cc68bf45df949 (patch) | |
tree | 37b0669386484455f6a2fea10acc63d44bcf1d04 /drivers | |
parent | 541ae68f6ddf1c27aa6879935ce541f110484202 (diff) |
[PATCH] S2io: Support for bimodal interrupts
Hi,
This is a patch to provide bimodal interrupt moderation support for
Xframe II adapter. Basically, in this moderation scheme, the adapter
raises a traffic interrupt if the no. of packets transmitted and/or
received reaches a programmable threshold.
Signed-off-by: Ravinandan Arakali <ravinandan.arakali@neterion.com>
Signed-off-by: Raghavendra Koushik <raghavendra.koushik@neterion.com>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/s2io.c | 122 | ||||
-rw-r--r-- | drivers/net/s2io.h | 3 |
2 files changed, 85 insertions, 40 deletions
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 15e2ee9f9703..f430ffe7d6f8 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -297,6 +297,7 @@ static unsigned int mc_pause_threshold_q4q7 = 187; | |||
297 | static unsigned int shared_splits; | 297 | static unsigned int shared_splits; |
298 | static unsigned int tmac_util_period = 5; | 298 | static unsigned int tmac_util_period = 5; |
299 | static unsigned int rmac_util_period = 5; | 299 | static unsigned int rmac_util_period = 5; |
300 | static unsigned int bimodal = 0; | ||
300 | #ifndef CONFIG_S2IO_NAPI | 301 | #ifndef CONFIG_S2IO_NAPI |
301 | static unsigned int indicate_max_pkts; | 302 | static unsigned int indicate_max_pkts; |
302 | #endif | 303 | #endif |
@@ -1306,52 +1307,86 @@ static int init_nic(struct s2io_nic *nic) | |||
1306 | time++; | 1307 | time++; |
1307 | } | 1308 | } |
1308 | 1309 | ||
1310 | if (nic->config.bimodal) { | ||
1311 | int k = 0; | ||
1312 | for (k = 0; k < config->rx_ring_num; k++) { | ||
1313 | val64 = TTI_CMD_MEM_WE | TTI_CMD_MEM_STROBE_NEW_CMD; | ||
1314 | val64 |= TTI_CMD_MEM_OFFSET(0x38+k); | ||
1315 | writeq(val64, &bar0->tti_command_mem); | ||
1309 | 1316 | ||
1310 | /* RTI Initialization */ | ||
1311 | if (nic->device_type == XFRAME_II_DEVICE) { | ||
1312 | /* | 1317 | /* |
1313 | * Programmed to generate Apprx 500 Intrs per | 1318 | * Once the operation completes, the Strobe bit of the command |
1314 | * second | 1319 | * register will be reset. We poll for this particular condition |
1315 | */ | 1320 | * We wait for a maximum of 500ms for the operation to complete, |
1316 | int count = (nic->config.bus_speed * 125)/4; | 1321 | * if it's not complete by then we return error. |
1317 | val64 = RTI_DATA1_MEM_RX_TIMER_VAL(count); | 1322 | */ |
1323 | time = 0; | ||
1324 | while (TRUE) { | ||
1325 | val64 = readq(&bar0->tti_command_mem); | ||
1326 | if (!(val64 & TTI_CMD_MEM_STROBE_NEW_CMD)) { | ||
1327 | break; | ||
1328 | } | ||
1329 | if (time > 10) { | ||
1330 | DBG_PRINT(ERR_DBG, | ||
1331 | "%s: TTI init Failed\n", | ||
1332 | dev->name); | ||
1333 | return -1; | ||
1334 | } | ||
1335 | time++; | ||
1336 | msleep(50); | ||
1337 | } | ||
1338 | } | ||
1318 | } else { | 1339 | } else { |
1319 | val64 = RTI_DATA1_MEM_RX_TIMER_VAL(0xFFF); | ||
1320 | } | ||
1321 | val64 |= RTI_DATA1_MEM_RX_URNG_A(0xA) | | ||
1322 | RTI_DATA1_MEM_RX_URNG_B(0x10) | | ||
1323 | RTI_DATA1_MEM_RX_URNG_C(0x30) | RTI_DATA1_MEM_RX_TIMER_AC_EN; | ||
1324 | 1340 | ||
1325 | writeq(val64, &bar0->rti_data1_mem); | 1341 | /* RTI Initialization */ |
1342 | if (nic->device_type == XFRAME_II_DEVICE) { | ||
1343 | /* | ||
1344 | * Programmed to generate Apprx 500 Intrs per | ||
1345 | * second | ||
1346 | */ | ||
1347 | int count = (nic->config.bus_speed * 125)/4; | ||
1348 | val64 = RTI_DATA1_MEM_RX_TIMER_VAL(count); | ||
1349 | } else { | ||
1350 | val64 = RTI_DATA1_MEM_RX_TIMER_VAL(0xFFF); | ||
1351 | } | ||
1352 | val64 |= RTI_DATA1_MEM_RX_URNG_A(0xA) | | ||
1353 | RTI_DATA1_MEM_RX_URNG_B(0x10) | | ||
1354 | RTI_DATA1_MEM_RX_URNG_C(0x30) | RTI_DATA1_MEM_RX_TIMER_AC_EN; | ||
1326 | 1355 | ||
1327 | val64 = RTI_DATA2_MEM_RX_UFC_A(0x1) | | 1356 | writeq(val64, &bar0->rti_data1_mem); |
1328 | RTI_DATA2_MEM_RX_UFC_B(0x2) | | ||
1329 | RTI_DATA2_MEM_RX_UFC_C(0x40) | RTI_DATA2_MEM_RX_UFC_D(0x80); | ||
1330 | writeq(val64, &bar0->rti_data2_mem); | ||
1331 | 1357 | ||
1332 | val64 = RTI_CMD_MEM_WE | RTI_CMD_MEM_STROBE_NEW_CMD; | 1358 | val64 = RTI_DATA2_MEM_RX_UFC_A(0x1) | |
1333 | writeq(val64, &bar0->rti_command_mem); | 1359 | RTI_DATA2_MEM_RX_UFC_B(0x2) | |
1360 | RTI_DATA2_MEM_RX_UFC_C(0x40) | RTI_DATA2_MEM_RX_UFC_D(0x80); | ||
1361 | writeq(val64, &bar0->rti_data2_mem); | ||
1334 | 1362 | ||
1335 | /* | 1363 | for (i = 0; i < config->rx_ring_num; i++) { |
1336 | * Once the operation completes, the Strobe bit of the | 1364 | val64 = RTI_CMD_MEM_WE | RTI_CMD_MEM_STROBE_NEW_CMD |
1337 | * command register will be reset. We poll for this | 1365 | | RTI_CMD_MEM_OFFSET(i); |
1338 | * particular condition. We wait for a maximum of 500ms | 1366 | writeq(val64, &bar0->rti_command_mem); |
1339 | * for the operation to complete, if it's not complete | 1367 | |
1340 | * by then we return error. | 1368 | /* |
1341 | */ | 1369 | * Once the operation completes, the Strobe bit of the |
1342 | time = 0; | 1370 | * command register will be reset. We poll for this |
1343 | while (TRUE) { | 1371 | * particular condition. We wait for a maximum of 500ms |
1344 | val64 = readq(&bar0->rti_command_mem); | 1372 | * for the operation to complete, if it's not complete |
1345 | if (!(val64 & RTI_CMD_MEM_STROBE_NEW_CMD)) { | 1373 | * by then we return error. |
1346 | break; | 1374 | */ |
1347 | } | 1375 | time = 0; |
1348 | if (time > 10) { | 1376 | while (TRUE) { |
1349 | DBG_PRINT(ERR_DBG, "%s: RTI init Failed\n", | 1377 | val64 = readq(&bar0->rti_command_mem); |
1350 | dev->name); | 1378 | if (!(val64 & RTI_CMD_MEM_STROBE_NEW_CMD)) { |
1351 | return -1; | 1379 | break; |
1380 | } | ||
1381 | if (time > 10) { | ||
1382 | DBG_PRINT(ERR_DBG, "%s: RTI init Failed\n", | ||
1383 | dev->name); | ||
1384 | return -1; | ||
1385 | } | ||
1386 | time++; | ||
1387 | msleep(50); | ||
1388 | } | ||
1352 | } | 1389 | } |
1353 | time++; | ||
1354 | msleep(50); | ||
1355 | } | 1390 | } |
1356 | 1391 | ||
1357 | /* | 1392 | /* |
@@ -1789,6 +1824,8 @@ static int start_nic(struct s2io_nic *nic) | |||
1789 | &bar0->prc_rxd0_n[i]); | 1824 | &bar0->prc_rxd0_n[i]); |
1790 | 1825 | ||
1791 | val64 = readq(&bar0->prc_ctrl_n[i]); | 1826 | val64 = readq(&bar0->prc_ctrl_n[i]); |
1827 | if (nic->config.bimodal) | ||
1828 | val64 |= PRC_CTRL_BIMODAL_INTERRUPT; | ||
1792 | #ifndef CONFIG_2BUFF_MODE | 1829 | #ifndef CONFIG_2BUFF_MODE |
1793 | val64 |= PRC_CTRL_RC_ENABLED; | 1830 | val64 |= PRC_CTRL_RC_ENABLED; |
1794 | #else | 1831 | #else |
@@ -5030,6 +5067,7 @@ module_param(mc_pause_threshold_q4q7, int, 0); | |||
5030 | module_param(shared_splits, int, 0); | 5067 | module_param(shared_splits, int, 0); |
5031 | module_param(tmac_util_period, int, 0); | 5068 | module_param(tmac_util_period, int, 0); |
5032 | module_param(rmac_util_period, int, 0); | 5069 | module_param(rmac_util_period, int, 0); |
5070 | module_param(bimodal, bool, 0); | ||
5033 | #ifndef CONFIG_S2IO_NAPI | 5071 | #ifndef CONFIG_S2IO_NAPI |
5034 | module_param(indicate_max_pkts, int, 0); | 5072 | module_param(indicate_max_pkts, int, 0); |
5035 | #endif | 5073 | #endif |
@@ -5397,6 +5435,14 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
5397 | else | 5435 | else |
5398 | strcat(sp->name, ": Neterion Xframe I 10GbE adapter"); | 5436 | strcat(sp->name, ": Neterion Xframe I 10GbE adapter"); |
5399 | 5437 | ||
5438 | /* Initialize bimodal Interrupts */ | ||
5439 | sp->config.bimodal = bimodal; | ||
5440 | if (!(sp->device_type & XFRAME_II_DEVICE) && bimodal) { | ||
5441 | sp->config.bimodal = 0; | ||
5442 | DBG_PRINT(ERR_DBG,"%s:Bimodal intr not supported by Xframe I\n", | ||
5443 | dev->name); | ||
5444 | } | ||
5445 | |||
5400 | /* | 5446 | /* |
5401 | * Make Link state as off at this point, when the Link change | 5447 | * Make Link state as off at this point, when the Link change |
5402 | * interrupt comes the state will be automatically changed to | 5448 | * interrupt comes the state will be automatically changed to |
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index df8cfd0475be..946314503daa 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h | |||
@@ -261,8 +261,6 @@ typedef struct stat_block { | |||
261 | u32 rmac_accepted_ip_oflow; | 261 | u32 rmac_accepted_ip_oflow; |
262 | u32 reserved_14; | 262 | u32 reserved_14; |
263 | u32 link_fault_cnt; | 263 | u32 link_fault_cnt; |
264 | |||
265 | /* Software statistics maintained by driver */ | ||
266 | swStat_t sw_stat; | 264 | swStat_t sw_stat; |
267 | } StatInfo_t; | 265 | } StatInfo_t; |
268 | 266 | ||
@@ -349,6 +347,7 @@ struct config_param { | |||
349 | #define MAX_RX_BLOCKS_PER_RING 150 | 347 | #define MAX_RX_BLOCKS_PER_RING 150 |
350 | 348 | ||
351 | rx_ring_config_t rx_cfg[MAX_RX_RINGS]; /*Per-Rx Ring config */ | 349 | rx_ring_config_t rx_cfg[MAX_RX_RINGS]; /*Per-Rx Ring config */ |
350 | u8 bimodal; /*Flag for setting bimodal interrupts*/ | ||
352 | 351 | ||
353 | #define HEADER_ETHERNET_II_802_3_SIZE 14 | 352 | #define HEADER_ETHERNET_II_802_3_SIZE 14 |
354 | #define HEADER_802_2_SIZE 3 | 353 | #define HEADER_802_2_SIZE 3 |