Commit b7c5678f authored by Ramkrishna Vepa's avatar Ramkrishna Vepa Committed by David S. Miller

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: default avatarSurjit Reang <surjit.reang@neterion.com>
Signed-off-by: default avatarSreenivasa Honnur <sreenivasa.honnur@neterion.com>
Signed-off-by: default avatarRamkrishna Vepa <ram.vepa@neterion.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 2fda096d
...@@ -84,7 +84,7 @@ ...@@ -84,7 +84,7 @@
#include "s2io.h" #include "s2io.h"
#include "s2io-regs.h" #include "s2io-regs.h"
#define DRV_VERSION "2.0.26.15-1" #define DRV_VERSION "2.0.26.15-2"
/* S2io Driver name & version. */ /* S2io Driver name & version. */
static char s2io_driver_name[] = "Neterion"; static char s2io_driver_name[] = "Neterion";
...@@ -1078,9 +1078,68 @@ static int s2io_print_pci_mode(struct s2io_nic *nic) ...@@ -1078,9 +1078,68 @@ static int s2io_print_pci_mode(struct s2io_nic *nic)
return mode; return mode;
} }
/**
* init_tti - Initialization transmit traffic interrupt scheme
* @nic: device private variable
* @link: link status (UP/DOWN) used to enable/disable continuous
* transmit interrupts
* Description: The function configures transmit traffic interrupts
* Return Value: SUCCESS on success and
* '-1' on failure
*/
int init_tti(struct s2io_nic *nic, int link)
{
struct XENA_dev_config __iomem *bar0 = nic->bar0;
register u64 val64 = 0;
int i;
struct config_param *config;
config = &nic->config;
for (i = 0; i < config->tx_fifo_num; i++) {
/*
* TTI Initialization. Default Tx timer gets us about
* 250 interrupts per sec. Continuous interrupts are enabled
* by default.
*/
if (nic->device_type == XFRAME_II_DEVICE) {
int count = (nic->config.bus_speed * 125)/2;
val64 = TTI_DATA1_MEM_TX_TIMER_VAL(count);
} else
val64 = TTI_DATA1_MEM_TX_TIMER_VAL(0x2078);
val64 |= TTI_DATA1_MEM_TX_URNG_A(0xA) |
TTI_DATA1_MEM_TX_URNG_B(0x10) |
TTI_DATA1_MEM_TX_URNG_C(0x30) |
TTI_DATA1_MEM_TX_TIMER_AC_EN;
if (use_continuous_tx_intrs && (link == LINK_UP))
val64 |= TTI_DATA1_MEM_TX_TIMER_CI_EN;
writeq(val64, &bar0->tti_data1_mem);
val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) |
TTI_DATA2_MEM_TX_UFC_B(0x20) |
TTI_DATA2_MEM_TX_UFC_C(0x40) |
TTI_DATA2_MEM_TX_UFC_D(0x80);
writeq(val64, &bar0->tti_data2_mem);
val64 = TTI_CMD_MEM_WE | TTI_CMD_MEM_STROBE_NEW_CMD |
TTI_CMD_MEM_OFFSET(i);
writeq(val64, &bar0->tti_command_mem);
if (wait_for_cmd_complete(&bar0->tti_command_mem,
TTI_CMD_MEM_STROBE_NEW_CMD, S2IO_BIT_RESET) != SUCCESS)
return FAILURE;
}
return SUCCESS;
}
/** /**
* init_nic - Initialization of hardware * init_nic - Initialization of hardware
* @nic: device peivate variable * @nic: device private variable
* Description: The function sequentially configures every block * Description: The function sequentially configures every block
* of the H/W from their reset values. * of the H/W from their reset values.
* Return Value: SUCCESS on success and * Return Value: SUCCESS on success and
...@@ -1185,9 +1244,9 @@ static int init_nic(struct s2io_nic *nic) ...@@ -1185,9 +1244,9 @@ static int init_nic(struct s2io_nic *nic)
for (i = 0, j = 0; i < config->tx_fifo_num; i++) { for (i = 0, j = 0; i < config->tx_fifo_num; i++) {
val64 |= val64 |=
vBIT(config->tx_cfg[i].fifo_len - 1, ((i * 32) + 19), vBIT(config->tx_cfg[i].fifo_len - 1, ((j * 32) + 19),
13) | vBIT(config->tx_cfg[i].fifo_priority, 13) | vBIT(config->tx_cfg[i].fifo_priority,
((i * 32) + 5), 3); ((j * 32) + 5), 3);
if (i == (config->tx_fifo_num - 1)) { if (i == (config->tx_fifo_num - 1)) {
if (i % 2 == 0) if (i % 2 == 0)
...@@ -1198,17 +1257,25 @@ static int init_nic(struct s2io_nic *nic) ...@@ -1198,17 +1257,25 @@ static int init_nic(struct s2io_nic *nic)
case 1: case 1:
writeq(val64, &bar0->tx_fifo_partition_0); writeq(val64, &bar0->tx_fifo_partition_0);
val64 = 0; val64 = 0;
j = 0;
break; break;
case 3: case 3:
writeq(val64, &bar0->tx_fifo_partition_1); writeq(val64, &bar0->tx_fifo_partition_1);
val64 = 0; val64 = 0;
j = 0;
break; break;
case 5: case 5:
writeq(val64, &bar0->tx_fifo_partition_2); writeq(val64, &bar0->tx_fifo_partition_2);
val64 = 0; val64 = 0;
j = 0;
break; break;
case 7: case 7:
writeq(val64, &bar0->tx_fifo_partition_3); writeq(val64, &bar0->tx_fifo_partition_3);
val64 = 0;
j = 0;
break;
default:
j++;
break; break;
} }
} }
...@@ -1294,11 +1361,11 @@ static int init_nic(struct s2io_nic *nic) ...@@ -1294,11 +1361,11 @@ static int init_nic(struct s2io_nic *nic)
/* /*
* Filling Tx round robin registers * Filling Tx round robin registers
* as per the number of FIFOs * as per the number of FIFOs for equal scheduling priority
*/ */
switch (config->tx_fifo_num) { switch (config->tx_fifo_num) {
case 1: case 1:
val64 = 0x0000000000000000ULL; val64 = 0x0;
writeq(val64, &bar0->tx_w_round_robin_0); writeq(val64, &bar0->tx_w_round_robin_0);
writeq(val64, &bar0->tx_w_round_robin_1); writeq(val64, &bar0->tx_w_round_robin_1);
writeq(val64, &bar0->tx_w_round_robin_2); writeq(val64, &bar0->tx_w_round_robin_2);
...@@ -1306,87 +1373,78 @@ static int init_nic(struct s2io_nic *nic) ...@@ -1306,87 +1373,78 @@ static int init_nic(struct s2io_nic *nic)
writeq(val64, &bar0->tx_w_round_robin_4); writeq(val64, &bar0->tx_w_round_robin_4);
break; break;
case 2: case 2:
val64 = 0x0000010000010000ULL; val64 = 0x0001000100010001ULL;
writeq(val64, &bar0->tx_w_round_robin_0); writeq(val64, &bar0->tx_w_round_robin_0);
val64 = 0x0100000100000100ULL;
writeq(val64, &bar0->tx_w_round_robin_1); writeq(val64, &bar0->tx_w_round_robin_1);
val64 = 0x0001000001000001ULL;
writeq(val64, &bar0->tx_w_round_robin_2); writeq(val64, &bar0->tx_w_round_robin_2);
val64 = 0x0000010000010000ULL;
writeq(val64, &bar0->tx_w_round_robin_3); writeq(val64, &bar0->tx_w_round_robin_3);
val64 = 0x0100000000000000ULL; val64 = 0x0001000100000000ULL;
writeq(val64, &bar0->tx_w_round_robin_4); writeq(val64, &bar0->tx_w_round_robin_4);
break; break;
case 3: case 3:
val64 = 0x0001000102000001ULL; val64 = 0x0001020001020001ULL;
writeq(val64, &bar0->tx_w_round_robin_0); writeq(val64, &bar0->tx_w_round_robin_0);
val64 = 0x0001020000010001ULL; val64 = 0x0200010200010200ULL;
writeq(val64, &bar0->tx_w_round_robin_1); writeq(val64, &bar0->tx_w_round_robin_1);
val64 = 0x0200000100010200ULL; val64 = 0x0102000102000102ULL;
writeq(val64, &bar0->tx_w_round_robin_2); writeq(val64, &bar0->tx_w_round_robin_2);
val64 = 0x0001000102000001ULL; val64 = 0x0001020001020001ULL;
writeq(val64, &bar0->tx_w_round_robin_3); writeq(val64, &bar0->tx_w_round_robin_3);
val64 = 0x0001020000000000ULL; val64 = 0x0200010200000000ULL;
writeq(val64, &bar0->tx_w_round_robin_4); writeq(val64, &bar0->tx_w_round_robin_4);
break; break;
case 4: case 4:
val64 = 0x0001020300010200ULL; val64 = 0x0001020300010203ULL;
writeq(val64, &bar0->tx_w_round_robin_0); writeq(val64, &bar0->tx_w_round_robin_0);
val64 = 0x0100000102030001ULL;
writeq(val64, &bar0->tx_w_round_robin_1); writeq(val64, &bar0->tx_w_round_robin_1);
val64 = 0x0200010000010203ULL;
writeq(val64, &bar0->tx_w_round_robin_2); writeq(val64, &bar0->tx_w_round_robin_2);
val64 = 0x0001020001000001ULL;
writeq(val64, &bar0->tx_w_round_robin_3); writeq(val64, &bar0->tx_w_round_robin_3);
val64 = 0x0203000100000000ULL; val64 = 0x0001020300000000ULL;
writeq(val64, &bar0->tx_w_round_robin_4); writeq(val64, &bar0->tx_w_round_robin_4);
break; break;
case 5: case 5:
val64 = 0x0001000203000102ULL; val64 = 0x0001020304000102ULL;
writeq(val64, &bar0->tx_w_round_robin_0); writeq(val64, &bar0->tx_w_round_robin_0);
val64 = 0x0001020001030004ULL; val64 = 0x0304000102030400ULL;
writeq(val64, &bar0->tx_w_round_robin_1); writeq(val64, &bar0->tx_w_round_robin_1);
val64 = 0x0001000203000102ULL; val64 = 0x0102030400010203ULL;
writeq(val64, &bar0->tx_w_round_robin_2); writeq(val64, &bar0->tx_w_round_robin_2);
val64 = 0x0001020001030004ULL; val64 = 0x0400010203040001ULL;
writeq(val64, &bar0->tx_w_round_robin_3); writeq(val64, &bar0->tx_w_round_robin_3);
val64 = 0x0001000000000000ULL; val64 = 0x0203040000000000ULL;
writeq(val64, &bar0->tx_w_round_robin_4); writeq(val64, &bar0->tx_w_round_robin_4);
break; break;
case 6: case 6:
val64 = 0x0001020304000102ULL; val64 = 0x0001020304050001ULL;
writeq(val64, &bar0->tx_w_round_robin_0); writeq(val64, &bar0->tx_w_round_robin_0);
val64 = 0x0304050001020001ULL; val64 = 0x0203040500010203ULL;
writeq(val64, &bar0->tx_w_round_robin_1); writeq(val64, &bar0->tx_w_round_robin_1);
val64 = 0x0203000100000102ULL; val64 = 0x0405000102030405ULL;
writeq(val64, &bar0->tx_w_round_robin_2); writeq(val64, &bar0->tx_w_round_robin_2);
val64 = 0x0304000102030405ULL; val64 = 0x0001020304050001ULL;
writeq(val64, &bar0->tx_w_round_robin_3); writeq(val64, &bar0->tx_w_round_robin_3);
val64 = 0x0001000200000000ULL; val64 = 0x0203040500000000ULL;
writeq(val64, &bar0->tx_w_round_robin_4); writeq(val64, &bar0->tx_w_round_robin_4);
break; break;
case 7: case 7:
val64 = 0x0001020001020300ULL; val64 = 0x0001020304050600ULL;
writeq(val64, &bar0->tx_w_round_robin_0); writeq(val64, &bar0->tx_w_round_robin_0);
val64 = 0x0102030400010203ULL; val64 = 0x0102030405060001ULL;
writeq(val64, &bar0->tx_w_round_robin_1); writeq(val64, &bar0->tx_w_round_robin_1);
val64 = 0x0405060001020001ULL; val64 = 0x0203040506000102ULL;
writeq(val64, &bar0->tx_w_round_robin_2); writeq(val64, &bar0->tx_w_round_robin_2);
val64 = 0x0304050000010200ULL; val64 = 0x0304050600010203ULL;
writeq(val64, &bar0->tx_w_round_robin_3); writeq(val64, &bar0->tx_w_round_robin_3);
val64 = 0x0102030000000000ULL; val64 = 0x0405060000000000ULL;
writeq(val64, &bar0->tx_w_round_robin_4); writeq(val64, &bar0->tx_w_round_robin_4);
break; break;
case 8: case 8:
val64 = 0x0001020300040105ULL; val64 = 0x0001020304050607ULL;
writeq(val64, &bar0->tx_w_round_robin_0); writeq(val64, &bar0->tx_w_round_robin_0);
val64 = 0x0200030106000204ULL;
writeq(val64, &bar0->tx_w_round_robin_1); writeq(val64, &bar0->tx_w_round_robin_1);
val64 = 0x0103000502010007ULL;
writeq(val64, &bar0->tx_w_round_robin_2); writeq(val64, &bar0->tx_w_round_robin_2);
val64 = 0x0304010002060500ULL;
writeq(val64, &bar0->tx_w_round_robin_3); writeq(val64, &bar0->tx_w_round_robin_3);
val64 = 0x0103020400000000ULL; val64 = 0x0001020300000000ULL;
writeq(val64, &bar0->tx_w_round_robin_4); writeq(val64, &bar0->tx_w_round_robin_4);
break; break;
} }
...@@ -1563,58 +1621,14 @@ static int init_nic(struct s2io_nic *nic) ...@@ -1563,58 +1621,14 @@ static int init_nic(struct s2io_nic *nic)
MAC_RX_LINK_UTIL_VAL(rmac_util_period); MAC_RX_LINK_UTIL_VAL(rmac_util_period);
writeq(val64, &bar0->mac_link_util); writeq(val64, &bar0->mac_link_util);
/* /*
* Initializing the Transmit and Receive Traffic Interrupt * Initializing the Transmit and Receive Traffic Interrupt
* Scheme. * Scheme.
*/ */
/*
* TTI Initialization. Default Tx timer gets us about
* 250 interrupts per sec. Continuous interrupts are enabled
* by default.
*/
if (nic->device_type == XFRAME_II_DEVICE) {
int count = (nic->config.bus_speed * 125)/2;
val64 = TTI_DATA1_MEM_TX_TIMER_VAL(count);
} else {
val64 = TTI_DATA1_MEM_TX_TIMER_VAL(0x2078);
}
val64 |= TTI_DATA1_MEM_TX_URNG_A(0xA) |
TTI_DATA1_MEM_TX_URNG_B(0x10) |
TTI_DATA1_MEM_TX_URNG_C(0x30) | TTI_DATA1_MEM_TX_TIMER_AC_EN;
if (use_continuous_tx_intrs)
val64 |= TTI_DATA1_MEM_TX_TIMER_CI_EN;
writeq(val64, &bar0->tti_data1_mem);
val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) |
TTI_DATA2_MEM_TX_UFC_B(0x20) |
TTI_DATA2_MEM_TX_UFC_C(0x40) | TTI_DATA2_MEM_TX_UFC_D(0x80);
writeq(val64, &bar0->tti_data2_mem);
val64 = TTI_CMD_MEM_WE | TTI_CMD_MEM_STROBE_NEW_CMD; /* Initialize TTI */
writeq(val64, &bar0->tti_command_mem); if (SUCCESS != init_tti(nic, nic->last_link_state))
/*
* Once the operation completes, the Strobe bit of the command
* register will be reset. We poll for this particular condition
* We wait for a maximum of 500ms for the operation to complete,
* if it's not complete by then we return error.
*/
time = 0;
while (TRUE) {
val64 = readq(&bar0->tti_command_mem);
if (!(val64 & TTI_CMD_MEM_STROBE_NEW_CMD)) {
break;
}
if (time > 10) {
DBG_PRINT(ERR_DBG, "%s: TTI init Failed\n",
dev->name);
return -ENODEV; return -ENODEV;
}
msleep(50);
time++;
}
/* RTI Initialization */ /* RTI Initialization */
if (nic->device_type == XFRAME_II_DEVICE) { if (nic->device_type == XFRAME_II_DEVICE) {
...@@ -7443,6 +7457,7 @@ static void s2io_link(struct s2io_nic * sp, int link) ...@@ -7443,6 +7457,7 @@ static void s2io_link(struct s2io_nic * sp, int link)
struct net_device *dev = (struct net_device *) sp->dev; struct net_device *dev = (struct net_device *) sp->dev;
if (link != sp->last_link_state) { if (link != sp->last_link_state) {
init_tti(sp, link);
if (link == LINK_DOWN) { if (link == LINK_DOWN) {
DBG_PRINT(ERR_DBG, "%s: Link down\n", dev->name); DBG_PRINT(ERR_DBG, "%s: Link down\n", dev->name);
netif_carrier_off(dev); netif_carrier_off(dev);
...@@ -7541,7 +7556,7 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type) ...@@ -7541,7 +7556,7 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type)
/** /**
* rts_ds_steer - Receive traffic steering based on IPv4 or IPv6 TOS * rts_ds_steer - Receive traffic steering based on IPv4 or IPv6 TOS
* or Traffic class respectively. * or Traffic class respectively.
* @nic: device peivate variable * @nic: device private variable
* Description: The function configures the receive steering to * Description: The function configures the receive steering to
* desired receive ring. * desired receive ring.
* Return Value: SUCCESS on success and * Return Value: SUCCESS on success and
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment