From 1cdc2cfc8af6d1045c844b9e24a7910b57232065 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 10 Sep 2010 06:41:00 +0000 Subject: sfc: Use MCDI RX_BAD_FCS_PKTS count as MAC rx_bad count Calculating rx_bad as rx_packets - rx_good is unnecessary and incorrect, since rx_good does not include control frames (e.g. pause frames) and rx_packets does. Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/siena.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/sfc/siena.c') diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c index 3fab030f8ab..9f536804969 100644 --- a/drivers/net/sfc/siena.c +++ b/drivers/net/sfc/siena.c @@ -450,7 +450,7 @@ static int siena_try_update_nic_stats(struct efx_nic *efx) mac_stats->rx_bad_bytes); MAC_STAT(rx_packets, RX_PKTS); MAC_STAT(rx_good, RX_GOOD_PKTS); - mac_stats->rx_bad = mac_stats->rx_packets - mac_stats->rx_good; + MAC_STAT(rx_bad, RX_BAD_FCS_PKTS); MAC_STAT(rx_pause, RX_PAUSE_PKTS); MAC_STAT(rx_control, RX_CONTROL_PKTS); MAC_STAT(rx_unicast, RX_UNICAST_PKTS); -- cgit v1.2.3-70-g09d2 From b4187e4277b13d7bc4acc3c953b3cab0137b14b2 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 20 Sep 2010 08:43:42 +0000 Subject: sfc: Implement the ethtool RX n-tuple control functions Signed-off-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/ethtool.c | 118 +++++++++++++++++++++++++++++++++++++++++++++- drivers/net/sfc/falcon.c | 2 +- drivers/net/sfc/siena.c | 2 +- 3 files changed, 118 insertions(+), 4 deletions(-) (limited to 'drivers/net/sfc/siena.c') diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index 7f735d80480..c95328fa3ee 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -15,6 +15,7 @@ #include "workarounds.h" #include "selftest.h" #include "efx.h" +#include "filter.h" #include "nic.h" #include "spi.h" #include "mdio_10g.h" @@ -551,9 +552,22 @@ static u32 efx_ethtool_get_rx_csum(struct net_device *net_dev) static int efx_ethtool_set_flags(struct net_device *net_dev, u32 data) { struct efx_nic *efx = netdev_priv(net_dev); - u32 supported = efx->type->offload_features & ETH_FLAG_RXHASH; + u32 supported = (efx->type->offload_features & + (ETH_FLAG_RXHASH | ETH_FLAG_NTUPLE)); + int rc; + + rc = ethtool_op_set_flags(net_dev, data, supported); + if (rc) + return rc; + + if (!(data & ETH_FLAG_NTUPLE)) { + efx_filter_table_clear(efx, EFX_FILTER_TABLE_RX_IP, + EFX_FILTER_PRI_MANUAL); + efx_filter_table_clear(efx, EFX_FILTER_TABLE_RX_MAC, + EFX_FILTER_PRI_MANUAL); + } - return ethtool_op_set_flags(net_dev, data, supported); + return 0; } static void efx_ethtool_self_test(struct net_device *net_dev, @@ -955,6 +969,105 @@ efx_ethtool_get_rxnfc(struct net_device *net_dev, } } +static int efx_ethtool_set_rx_ntuple(struct net_device *net_dev, + struct ethtool_rx_ntuple *ntuple) +{ + struct efx_nic *efx = netdev_priv(net_dev); + struct ethtool_tcpip4_spec *ip_entry = &ntuple->fs.h_u.tcp_ip4_spec; + struct ethtool_tcpip4_spec *ip_mask = &ntuple->fs.m_u.tcp_ip4_spec; + struct ethhdr *mac_entry = &ntuple->fs.h_u.ether_spec; + struct ethhdr *mac_mask = &ntuple->fs.m_u.ether_spec; + struct efx_filter_spec filter; + + /* Range-check action */ + if (ntuple->fs.action < ETHTOOL_RXNTUPLE_ACTION_CLEAR || + ntuple->fs.action >= (s32)efx->n_rx_channels) + return -EINVAL; + + if (~ntuple->fs.data_mask) + return -EINVAL; + + switch (ntuple->fs.flow_type) { + case TCP_V4_FLOW: + case UDP_V4_FLOW: + /* Must match all of destination, */ + if (ip_mask->ip4dst | ip_mask->pdst) + return -EINVAL; + /* all or none of source, */ + if ((ip_mask->ip4src | ip_mask->psrc) && + ((__force u32)~ip_mask->ip4src | + (__force u16)~ip_mask->psrc)) + return -EINVAL; + /* and nothing else */ + if ((u8)~ip_mask->tos | (u16)~ntuple->fs.vlan_tag_mask) + return -EINVAL; + break; + case ETHER_FLOW: + /* Must match all of destination, */ + if (!is_zero_ether_addr(mac_mask->h_dest)) + return -EINVAL; + /* all or none of VID, */ + if (ntuple->fs.vlan_tag_mask != 0xf000 && + ntuple->fs.vlan_tag_mask != 0xffff) + return -EINVAL; + /* and nothing else */ + if (!is_broadcast_ether_addr(mac_mask->h_source) || + mac_mask->h_proto != htons(0xffff)) + return -EINVAL; + break; + default: + return -EINVAL; + } + + filter.priority = EFX_FILTER_PRI_MANUAL; + filter.flags = 0; + + switch (ntuple->fs.flow_type) { + case TCP_V4_FLOW: + if (!ip_mask->ip4src) + efx_filter_set_rx_tcp_full(&filter, + htonl(ip_entry->ip4src), + htons(ip_entry->psrc), + htonl(ip_entry->ip4dst), + htons(ip_entry->pdst)); + else + efx_filter_set_rx_tcp_wild(&filter, + htonl(ip_entry->ip4dst), + htons(ip_entry->pdst)); + break; + case UDP_V4_FLOW: + if (!ip_mask->ip4src) + efx_filter_set_rx_udp_full(&filter, + htonl(ip_entry->ip4src), + htons(ip_entry->psrc), + htonl(ip_entry->ip4dst), + htons(ip_entry->pdst)); + else + efx_filter_set_rx_udp_wild(&filter, + htonl(ip_entry->ip4dst), + htons(ip_entry->pdst)); + break; + case ETHER_FLOW: + if (ntuple->fs.vlan_tag_mask == 0xf000) + efx_filter_set_rx_mac_full(&filter, + ntuple->fs.vlan_tag & 0xfff, + mac_entry->h_dest); + else + efx_filter_set_rx_mac_wild(&filter, mac_entry->h_dest); + break; + } + + if (ntuple->fs.action == ETHTOOL_RXNTUPLE_ACTION_CLEAR) { + return efx_filter_remove_filter(efx, &filter); + } else { + if (ntuple->fs.action == ETHTOOL_RXNTUPLE_ACTION_DROP) + filter.dmaq_id = 0xfff; + else + filter.dmaq_id = ntuple->fs.action; + return efx_filter_insert_filter(efx, &filter, true); + } +} + static int efx_ethtool_get_rxfh_indir(struct net_device *net_dev, struct ethtool_rxfh_indir *indir) { @@ -1033,6 +1146,7 @@ const struct ethtool_ops efx_ethtool_ops = { .set_wol = efx_ethtool_set_wol, .reset = efx_ethtool_reset, .get_rxnfc = efx_ethtool_get_rxnfc, + .set_rx_ntuple = efx_ethtool_set_rx_ntuple, .get_rxfh_indir = efx_ethtool_get_rxfh_indir, .set_rxfh_indir = efx_ethtool_set_rxfh_indir, }; diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index b4d8efe6777..b398a419804 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -1874,7 +1874,7 @@ struct efx_nic_type falcon_b0_nic_type = { * channels */ .tx_dc_base = 0x130000, .rx_dc_base = 0x100000, - .offload_features = NETIF_F_IP_CSUM | NETIF_F_RXHASH, + .offload_features = NETIF_F_IP_CSUM | NETIF_F_RXHASH | NETIF_F_NTUPLE, .reset_world_flags = ETH_RESET_IRQ, }; diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c index 9f536804969..2115f95ddc8 100644 --- a/drivers/net/sfc/siena.c +++ b/drivers/net/sfc/siena.c @@ -651,6 +651,6 @@ struct efx_nic_type siena_a0_nic_type = { .tx_dc_base = 0x88000, .rx_dc_base = 0x68000, .offload_features = (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | - NETIF_F_RXHASH), + NETIF_F_RXHASH | NETIF_F_NTUPLE), .reset_world_flags = ETH_RESET_MGMT << ETH_RESET_SHARED_SHIFT, }; -- cgit v1.2.3-70-g09d2 From d215697fe14a0c5a96765c6279b4751e632587a5 Mon Sep 17 00:00:00 2001 From: stephen hemminger Date: Mon, 18 Oct 2010 05:27:31 +0000 Subject: sfc: make functions static Make local functions and variable static. Do some rearrangement of the string table stuff to put it where it gets used. Signed-off-by: Stephen Hemminger Acked-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/sfc/efx.c | 16 +++------------- drivers/net/sfc/efx.h | 10 +--------- drivers/net/sfc/ethtool.c | 10 +++++----- drivers/net/sfc/falcon_xmac.c | 2 +- drivers/net/sfc/mac.h | 1 - drivers/net/sfc/mcdi.c | 4 ++-- drivers/net/sfc/mcdi.h | 2 -- drivers/net/sfc/mcdi_phy.c | 3 ++- drivers/net/sfc/net_driver.h | 5 ----- drivers/net/sfc/nic.c | 2 +- drivers/net/sfc/selftest.c | 10 ++++++++++ drivers/net/sfc/siena.c | 2 +- 12 files changed, 26 insertions(+), 41 deletions(-) (limited to 'drivers/net/sfc/siena.c') diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index fa6e0207de1..05df20e4797 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -68,14 +68,6 @@ const char *efx_loopback_mode_names[] = { [LOOPBACK_PHYXS_WS] = "PHYXS_WS", }; -/* Interrupt mode names (see INT_MODE())) */ -const unsigned int efx_interrupt_mode_max = EFX_INT_MODE_MAX; -const char *efx_interrupt_mode_names[] = { - [EFX_INT_MODE_MSIX] = "MSI-X", - [EFX_INT_MODE_MSI] = "MSI", - [EFX_INT_MODE_LEGACY] = "legacy", -}; - const unsigned int efx_reset_type_max = RESET_TYPE_MAX; const char *efx_reset_type_names[] = { [RESET_TYPE_INVISIBLE] = "INVISIBLE", @@ -128,7 +120,7 @@ static int napi_weight = 64; * - Check the on-board hardware monitor; * - Poll the link state and reconfigure the hardware as necessary. */ -unsigned int efx_monitor_interval = 1 * HZ; +static unsigned int efx_monitor_interval = 1 * HZ; /* This controls whether or not the driver will initialise devices * with invalid MAC addresses stored in the EEPROM or flash. If true, @@ -2180,10 +2172,8 @@ int efx_port_dummy_op_int(struct efx_nic *efx) return 0; } void efx_port_dummy_op_void(struct efx_nic *efx) {} -void efx_port_dummy_op_set_id_led(struct efx_nic *efx, enum efx_led_mode mode) -{ -} -bool efx_port_dummy_op_poll(struct efx_nic *efx) + +static bool efx_port_dummy_op_poll(struct efx_nic *efx) { return false; } diff --git a/drivers/net/sfc/efx.h b/drivers/net/sfc/efx.h index f502b14eb22..10a1bf40da9 100644 --- a/drivers/net/sfc/efx.h +++ b/drivers/net/sfc/efx.h @@ -88,10 +88,6 @@ extern int efx_reconfigure_port(struct efx_nic *efx); extern int __efx_reconfigure_port(struct efx_nic *efx); /* Ethtool support */ -extern int efx_ethtool_get_settings(struct net_device *net_dev, - struct ethtool_cmd *ecmd); -extern int efx_ethtool_set_settings(struct net_device *net_dev, - struct ethtool_cmd *ecmd); extern const struct ethtool_ops efx_ethtool_ops; /* Reset handling */ @@ -107,9 +103,7 @@ extern void efx_init_irq_moderation(struct efx_nic *efx, int tx_usecs, /* Dummy PHY ops for PHY drivers */ extern int efx_port_dummy_op_int(struct efx_nic *efx); extern void efx_port_dummy_op_void(struct efx_nic *efx); -extern void -efx_port_dummy_op_set_id_led(struct efx_nic *efx, enum efx_led_mode mode); -extern bool efx_port_dummy_op_poll(struct efx_nic *efx); + /* MTD */ #ifdef CONFIG_SFC_MTD @@ -122,8 +116,6 @@ static inline void efx_mtd_rename(struct efx_nic *efx) {} static inline void efx_mtd_remove(struct efx_nic *efx) {} #endif -extern unsigned int efx_monitor_interval; - static inline void efx_schedule_channel(struct efx_channel *channel) { netif_vdbg(channel->efx, intr, channel->efx->net_dev, diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c index c95328fa3ee..edb9d16b8b4 100644 --- a/drivers/net/sfc/ethtool.c +++ b/drivers/net/sfc/ethtool.c @@ -187,8 +187,8 @@ static int efx_ethtool_phys_id(struct net_device *net_dev, u32 count) } /* This must be called with rtnl_lock held. */ -int efx_ethtool_get_settings(struct net_device *net_dev, - struct ethtool_cmd *ecmd) +static int efx_ethtool_get_settings(struct net_device *net_dev, + struct ethtool_cmd *ecmd) { struct efx_nic *efx = netdev_priv(net_dev); struct efx_link_state *link_state = &efx->link_state; @@ -211,8 +211,8 @@ int efx_ethtool_get_settings(struct net_device *net_dev, } /* This must be called with rtnl_lock held. */ -int efx_ethtool_set_settings(struct net_device *net_dev, - struct ethtool_cmd *ecmd) +static int efx_ethtool_set_settings(struct net_device *net_dev, + struct ethtool_cmd *ecmd) { struct efx_nic *efx = netdev_priv(net_dev); int rc; @@ -891,7 +891,7 @@ static int efx_ethtool_set_wol(struct net_device *net_dev, return efx->type->set_wol(efx, wol->wolopts); } -extern int efx_ethtool_reset(struct net_device *net_dev, u32 *flags) +static int efx_ethtool_reset(struct net_device *net_dev, u32 *flags) { struct efx_nic *efx = netdev_priv(net_dev); enum reset_type method; diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c index bae656dd2c4..b31f595ebb5 100644 --- a/drivers/net/sfc/falcon_xmac.c +++ b/drivers/net/sfc/falcon_xmac.c @@ -143,7 +143,7 @@ static bool falcon_xmac_link_ok(struct efx_nic *efx) efx_mdio_phyxgxs_lane_sync(efx)); } -void falcon_reconfigure_xmac_core(struct efx_nic *efx) +static void falcon_reconfigure_xmac_core(struct efx_nic *efx) { unsigned int max_frame_len; efx_oword_t reg; diff --git a/drivers/net/sfc/mac.h b/drivers/net/sfc/mac.h index 7a6e5ca0290..6886cdf87c1 100644 --- a/drivers/net/sfc/mac.h +++ b/drivers/net/sfc/mac.h @@ -15,7 +15,6 @@ extern struct efx_mac_operations falcon_xmac_operations; extern struct efx_mac_operations efx_mcdi_mac_operations; -extern void falcon_reconfigure_xmac_core(struct efx_nic *efx); extern int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr, u32 dma_len, int enable, int clear); diff --git a/drivers/net/sfc/mcdi.c b/drivers/net/sfc/mcdi.c index 3912b8fed91..12cf910c2ce 100644 --- a/drivers/net/sfc/mcdi.c +++ b/drivers/net/sfc/mcdi.c @@ -1093,8 +1093,8 @@ int efx_mcdi_reset_mc(struct efx_nic *efx) return rc; } -int efx_mcdi_wol_filter_set(struct efx_nic *efx, u32 type, - const u8 *mac, int *id_out) +static int efx_mcdi_wol_filter_set(struct efx_nic *efx, u32 type, + const u8 *mac, int *id_out) { u8 inbuf[MC_CMD_WOL_FILTER_SET_IN_LEN]; u8 outbuf[MC_CMD_WOL_FILTER_SET_OUT_LEN]; diff --git a/drivers/net/sfc/mcdi.h b/drivers/net/sfc/mcdi.h index f1f89ad4075..c792f1d65e4 100644 --- a/drivers/net/sfc/mcdi.h +++ b/drivers/net/sfc/mcdi.h @@ -121,8 +121,6 @@ extern int efx_mcdi_handle_assertion(struct efx_nic *efx); extern void efx_mcdi_set_id_led(struct efx_nic *efx, enum efx_led_mode mode); extern int efx_mcdi_reset_port(struct efx_nic *efx); extern int efx_mcdi_reset_mc(struct efx_nic *efx); -extern int efx_mcdi_wol_filter_set(struct efx_nic *efx, u32 type, - const u8 *mac, int *id_out); extern int efx_mcdi_wol_filter_set_magic(struct efx_nic *efx, const u8 *mac, int *id_out); extern int efx_mcdi_wol_filter_get_magic(struct efx_nic *efx, int *id_out); diff --git a/drivers/net/sfc/mcdi_phy.c b/drivers/net/sfc/mcdi_phy.c index 0121e71702b..c992742446b 100644 --- a/drivers/net/sfc/mcdi_phy.c +++ b/drivers/net/sfc/mcdi_phy.c @@ -713,7 +713,8 @@ static int efx_mcdi_phy_run_tests(struct efx_nic *efx, int *results, return 0; } -const char *efx_mcdi_phy_test_name(struct efx_nic *efx, unsigned int index) +static const char *efx_mcdi_phy_test_name(struct efx_nic *efx, + unsigned int index) { struct efx_mcdi_phy_data *phy_cfg = efx->phy_data; diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 44f4d58a39a..0a7e26d73b5 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -387,11 +387,6 @@ extern const unsigned int efx_loopback_mode_max; #define LOOPBACK_MODE(efx) \ STRING_TABLE_LOOKUP((efx)->loopback_mode, efx_loopback_mode) -extern const char *efx_interrupt_mode_names[]; -extern const unsigned int efx_interrupt_mode_max; -#define INT_MODE(efx) \ - STRING_TABLE_LOOKUP(efx->interrupt_mode, efx_interrupt_mode) - extern const char *efx_reset_type_names[]; extern const unsigned int efx_reset_type_max; #define RESET_TYPE(type) \ diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index 394dd929fee..41c36b9a424 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c @@ -653,7 +653,7 @@ void efx_nic_eventq_read_ack(struct efx_channel *channel) } /* Use HW to insert a SW defined event */ -void efx_generate_event(struct efx_channel *channel, efx_qword_t *event) +static void efx_generate_event(struct efx_channel *channel, efx_qword_t *event) { efx_oword_t drv_ev_reg; diff --git a/drivers/net/sfc/selftest.c b/drivers/net/sfc/selftest.c index da4473b7105..0ebfb99f129 100644 --- a/drivers/net/sfc/selftest.c +++ b/drivers/net/sfc/selftest.c @@ -48,6 +48,16 @@ static const unsigned char payload_source[ETH_ALEN] = { static const char payload_msg[] = "Hello world! This is an Efx loopback test in progress!"; +/* Interrupt mode names */ +static const unsigned int efx_interrupt_mode_max = EFX_INT_MODE_MAX; +static const char *efx_interrupt_mode_names[] = { + [EFX_INT_MODE_MSIX] = "MSI-X", + [EFX_INT_MODE_MSI] = "MSI", + [EFX_INT_MODE_LEGACY] = "legacy", +}; +#define INT_MODE(efx) \ + STRING_TABLE_LOOKUP(efx->interrupt_mode, efx_interrupt_mode) + /** * efx_loopback_state - persistent state during a loopback selftest * @flush: Drop all packets in efx_loopback_rx_packet diff --git a/drivers/net/sfc/siena.c b/drivers/net/sfc/siena.c index 2115f95ddc8..45236f58a25 100644 --- a/drivers/net/sfc/siena.c +++ b/drivers/net/sfc/siena.c @@ -129,7 +129,7 @@ static int siena_probe_port(struct efx_nic *efx) return 0; } -void siena_remove_port(struct efx_nic *efx) +static void siena_remove_port(struct efx_nic *efx) { efx->phy_op->remove(efx); efx_nic_free_buffer(efx, &efx->stats_buffer); -- cgit v1.2.3-70-g09d2