Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 203247
b: refs/heads/master
c: 765c9f4
h: refs/heads/master
i:
  203245: d26dd4f
  203243: 7a715c4
  203239: 30cfe99
  203231: 052cf30
v: v3
  • Loading branch information
Ben Hutchings authored and David S. Miller committed Jun 30, 2010
1 parent 6d92a6a commit eef3cec
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 11 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a5b6ee291e39e285e021cf251dbcf770c83cd74e
refs/heads/master: 765c9f46867c3253c02275cbb7a453f2eb56eda1
3 changes: 3 additions & 0 deletions trunk/drivers/net/sfc/efx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1121,6 +1121,7 @@ static void efx_set_channels(struct efx_nic *efx)

static int efx_probe_nic(struct efx_nic *efx)
{
size_t i;
int rc;

netif_dbg(efx, probe, efx->net_dev, "creating NIC\n");
Expand All @@ -1136,6 +1137,8 @@ static int efx_probe_nic(struct efx_nic *efx)

if (efx->n_channels > 1)
get_random_bytes(&efx->rx_hash_key, sizeof(efx->rx_hash_key));
for (i = 0; i < ARRAY_SIZE(efx->rx_indir_table); i++)
efx->rx_indir_table[i] = i % efx->n_rx_channels;

efx_set_channels(efx);
efx->net_dev->real_num_tx_queues = efx->n_tx_channels;
Expand Down
90 changes: 90 additions & 0 deletions trunk/drivers/net/sfc/ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,93 @@ extern int efx_ethtool_reset(struct net_device *net_dev, u32 *flags)
return efx_reset(efx, method);
}

static int
efx_ethtool_get_rxnfc(struct net_device *net_dev,
struct ethtool_rxnfc *info, void *rules __always_unused)
{
struct efx_nic *efx = netdev_priv(net_dev);

switch (info->cmd) {
case ETHTOOL_GRXRINGS:
info->data = efx->n_rx_channels;
return 0;

case ETHTOOL_GRXFH: {
unsigned min_revision = 0;

info->data = 0;
switch (info->flow_type) {
case TCP_V4_FLOW:
info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
/* fall through */
case UDP_V4_FLOW:
case SCTP_V4_FLOW:
case AH_ESP_V4_FLOW:
case IPV4_FLOW:
info->data |= RXH_IP_SRC | RXH_IP_DST;
min_revision = EFX_REV_FALCON_B0;
break;
case TCP_V6_FLOW:
info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
/* fall through */
case UDP_V6_FLOW:
case SCTP_V6_FLOW:
case AH_ESP_V6_FLOW:
case IPV6_FLOW:
info->data |= RXH_IP_SRC | RXH_IP_DST;
min_revision = EFX_REV_SIENA_A0;
break;
default:
break;
}
if (efx_nic_rev(efx) < min_revision)
info->data = 0;
return 0;
}

default:
return -EOPNOTSUPP;
}
}

static int efx_ethtool_get_rxfh_indir(struct net_device *net_dev,
struct ethtool_rxfh_indir *indir)
{
struct efx_nic *efx = netdev_priv(net_dev);
size_t copy_size =
min_t(size_t, indir->size, ARRAY_SIZE(efx->rx_indir_table));

if (efx_nic_rev(efx) < EFX_REV_FALCON_B0)
return -EOPNOTSUPP;

indir->size = ARRAY_SIZE(efx->rx_indir_table);
memcpy(indir->ring_index, efx->rx_indir_table,
copy_size * sizeof(indir->ring_index[0]));
return 0;
}

static int efx_ethtool_set_rxfh_indir(struct net_device *net_dev,
const struct ethtool_rxfh_indir *indir)
{
struct efx_nic *efx = netdev_priv(net_dev);
size_t i;

if (efx_nic_rev(efx) < EFX_REV_FALCON_B0)
return -EOPNOTSUPP;

/* Validate size and indices */
if (indir->size != ARRAY_SIZE(efx->rx_indir_table))
return -EINVAL;
for (i = 0; i < ARRAY_SIZE(efx->rx_indir_table); i++)
if (indir->ring_index[i] >= efx->n_rx_channels)
return -EINVAL;

memcpy(efx->rx_indir_table, indir->ring_index,
sizeof(efx->rx_indir_table));
efx_nic_push_rx_indir_table(efx);
return 0;
}

const struct ethtool_ops efx_ethtool_ops = {
.get_settings = efx_ethtool_get_settings,
.set_settings = efx_ethtool_set_settings,
Expand Down Expand Up @@ -905,4 +992,7 @@ const struct ethtool_ops efx_ethtool_ops = {
.get_wol = efx_ethtool_get_wol,
.set_wol = efx_ethtool_set_wol,
.reset = efx_ethtool_reset,
.get_rxnfc = efx_ethtool_get_rxnfc,
.get_rxfh_indir = efx_ethtool_get_rxfh_indir,
.set_rxfh_indir = efx_ethtool_set_rxfh_indir,
};
2 changes: 2 additions & 0 deletions trunk/drivers/net/sfc/net_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,7 @@ union efx_multicast_hash {
* @n_tx_channels: Number of channels used for TX
* @rx_buffer_len: RX buffer length
* @rx_buffer_order: Order (log2) of number of pages for each RX buffer
* @rx_indir_table: Indirection table for RSS
* @int_error_count: Number of internal errors seen recently
* @int_error_expire: Time at which error count will be expired
* @irq_status: Interrupt status buffer
Expand Down Expand Up @@ -736,6 +737,7 @@ struct efx_nic {
unsigned int rx_buffer_len;
unsigned int rx_buffer_order;
u8 rx_hash_key[40];
u32 rx_indir_table[128];

unsigned int_error_count;
unsigned long int_error_expire;
Expand Down
19 changes: 9 additions & 10 deletions trunk/drivers/net/sfc/nic.c
Original file line number Diff line number Diff line change
Expand Up @@ -1484,22 +1484,21 @@ static irqreturn_t efx_msi_interrupt(int irq, void *dev_id)
/* Setup RSS indirection table.
* This maps from the hash value of the packet to RXQ
*/
static void efx_setup_rss_indir_table(struct efx_nic *efx)
void efx_nic_push_rx_indir_table(struct efx_nic *efx)
{
int i = 0;
unsigned long offset;
size_t i = 0;
efx_dword_t dword;

if (efx_nic_rev(efx) < EFX_REV_FALCON_B0)
return;

for (offset = FR_BZ_RX_INDIRECTION_TBL;
offset < FR_BZ_RX_INDIRECTION_TBL + 0x800;
offset += 0x10) {
BUILD_BUG_ON(ARRAY_SIZE(efx->rx_indir_table) !=
FR_BZ_RX_INDIRECTION_TBL_ROWS);

for (i = 0; i < FR_BZ_RX_INDIRECTION_TBL_ROWS; i++) {
EFX_POPULATE_DWORD_1(dword, FRF_BZ_IT_QUEUE,
i % efx->n_rx_channels);
efx_writed(efx, &dword, offset);
i++;
efx->rx_indir_table[i]);
efx_writed_table(efx, &dword, FR_BZ_RX_INDIRECTION_TBL, i);
}
}

Expand Down Expand Up @@ -1634,7 +1633,7 @@ void efx_nic_init_common(struct efx_nic *efx)
EFX_INVERT_OWORD(temp);
efx_writeo(efx, &temp, FR_AZ_FATAL_INTR_KER);

efx_setup_rss_indir_table(efx);
efx_nic_push_rx_indir_table(efx);

/* Disable the ugly timer-based TX DMA backoff and allow TX DMA to be
* controlled by the RX FIFO fill level. Set arbitration to one pkt/Q.
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/net/sfc/nic.h
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ extern void falcon_stop_nic_stats(struct efx_nic *efx);
extern void falcon_setup_xaui(struct efx_nic *efx);
extern int falcon_reset_xaui(struct efx_nic *efx);
extern void efx_nic_init_common(struct efx_nic *efx);
extern void efx_nic_push_rx_indir_table(struct efx_nic *efx);

int efx_nic_alloc_buffer(struct efx_nic *efx, struct efx_buffer *buffer,
unsigned int len);
Expand Down

0 comments on commit eef3cec

Please sign in to comment.