diff options
| -rw-r--r-- | drivers/net/ethernet/sfc/Makefile | 1 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/efx.c | 40 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/efx.h | 107 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/falcon.c | 31 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/farch.c | 1108 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/filter.c | 1244 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/net_driver.h | 46 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/nic.h | 28 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/rx.c | 94 | ||||
| -rw-r--r-- | drivers/net/ethernet/sfc/siena.c | 16 |
10 files changed, 1448 insertions, 1267 deletions
diff --git a/drivers/net/ethernet/sfc/Makefile b/drivers/net/ethernet/sfc/Makefile index ef7410f014d6..a61272661a73 100644 --- a/drivers/net/ethernet/sfc/Makefile +++ b/drivers/net/ethernet/sfc/Makefile | |||
| @@ -1,5 +1,4 @@ | |||
| 1 | sfc-y += efx.o nic.o farch.o falcon.o siena.o tx.o rx.o \ | 1 | sfc-y += efx.o nic.o farch.o falcon.o siena.o tx.o rx.o \ |
| 2 | filter.o \ | ||
| 3 | selftest.o ethtool.o qt202x_phy.o mdio_10g.o \ | 2 | selftest.o ethtool.o qt202x_phy.o mdio_10g.o \ |
| 4 | tenxpress.o txc43128_phy.o falcon_boards.o \ | 3 | tenxpress.o txc43128_phy.o falcon_boards.o \ |
| 5 | mcdi.o mcdi_port.o mcdi_mon.o ptp.o | 4 | mcdi.o mcdi_port.o mcdi_mon.o ptp.o |
diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 49d06ca79d7d..a2daaae266d7 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c | |||
| @@ -611,7 +611,7 @@ static void efx_start_datapath(struct efx_nic *efx) | |||
| 611 | 611 | ||
| 612 | /* RX filters also have scatter-enabled flags */ | 612 | /* RX filters also have scatter-enabled flags */ |
| 613 | if (efx->rx_scatter != old_rx_scatter) | 613 | if (efx->rx_scatter != old_rx_scatter) |
| 614 | efx_filter_update_rx_scatter(efx); | 614 | efx->type->filter_update_rx_scatter(efx); |
| 615 | 615 | ||
| 616 | /* We must keep at least one descriptor in a TX ring empty. | 616 | /* We must keep at least one descriptor in a TX ring empty. |
| 617 | * We could avoid this when the queue size does not exactly | 617 | * We could avoid this when the queue size does not exactly |
| @@ -1499,6 +1499,44 @@ static void efx_remove_nic(struct efx_nic *efx) | |||
| 1499 | efx->type->remove(efx); | 1499 | efx->type->remove(efx); |
| 1500 | } | 1500 | } |
| 1501 | 1501 | ||
| 1502 | static int efx_probe_filters(struct efx_nic *efx) | ||
| 1503 | { | ||
| 1504 | int rc; | ||
| 1505 | |||
| 1506 | spin_lock_init(&efx->filter_lock); | ||
| 1507 | |||
| 1508 | rc = efx->type->filter_table_probe(efx); | ||
| 1509 | if (rc) | ||
| 1510 | return rc; | ||
| 1511 | |||
| 1512 | #ifdef CONFIG_RFS_ACCEL | ||
| 1513 | if (efx->type->offload_features & NETIF_F_NTUPLE) { | ||
| 1514 | efx->rps_flow_id = kcalloc(efx->type->max_rx_ip_filters, | ||
| 1515 | sizeof(*efx->rps_flow_id), | ||
| 1516 | GFP_KERNEL); | ||
| 1517 | if (!efx->rps_flow_id) { | ||
| 1518 | efx->type->filter_table_remove(efx); | ||
| 1519 | return -ENOMEM; | ||
| 1520 | } | ||
| 1521 | } | ||
| 1522 | #endif | ||
| 1523 | |||
| 1524 | return 0; | ||
| 1525 | } | ||
| 1526 | |||
| 1527 | static void efx_remove_filters(struct efx_nic *efx) | ||
| 1528 | { | ||
| 1529 | #ifdef CONFIG_RFS_ACCEL | ||
| 1530 | kfree(efx->rps_flow_id); | ||
| 1531 | #endif | ||
| 1532 | efx->type->filter_table_remove(efx); | ||
| 1533 | } | ||
| 1534 | |||
| 1535 | static void efx_restore_filters(struct efx_nic *efx) | ||
| 1536 | { | ||
| 1537 | efx->type->filter_table_restore(efx); | ||
| 1538 | } | ||
| 1539 | |||
| 1502 | /************************************************************************** | 1540 | /************************************************************************** |
| 1503 | * | 1541 | * |
| 1504 | * NIC startup/shutdown | 1542 | * NIC startup/shutdown |
diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h index 45de5b9fedbe..9e3573872e57 100644 --- a/drivers/net/ethernet/sfc/efx.h +++ b/drivers/net/ethernet/sfc/efx.h | |||
| @@ -68,27 +68,92 @@ extern void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue); | |||
| 68 | #define EFX_TXQ_MIN_ENT(efx) (2 * efx_tx_max_skb_descs(efx)) | 68 | #define EFX_TXQ_MIN_ENT(efx) (2 * efx_tx_max_skb_descs(efx)) |
| 69 | 69 | ||
| 70 | /* Filters */ | 70 | /* Filters */ |
| 71 | extern int efx_probe_filters(struct efx_nic *efx); | 71 | |
| 72 | extern void efx_restore_filters(struct efx_nic *efx); | 72 | /** |
| 73 | extern void efx_remove_filters(struct efx_nic *efx); | 73 | * efx_filter_insert_filter - add or replace a filter |
| 74 | extern void efx_filter_update_rx_scatter(struct efx_nic *efx); | 74 | * @efx: NIC in which to insert the filter |
| 75 | extern s32 efx_filter_insert_filter(struct efx_nic *efx, | 75 | * @spec: Specification for the filter |
| 76 | struct efx_filter_spec *spec, | 76 | * @replace_equal: Flag for whether the specified filter may replace an |
| 77 | bool replace); | 77 | * existing filter with equal priority |
| 78 | extern int efx_filter_remove_id_safe(struct efx_nic *efx, | 78 | * |
| 79 | enum efx_filter_priority priority, | 79 | * On success, return the filter ID. |
| 80 | u32 filter_id); | 80 | * On failure, return a negative error code. |
| 81 | extern int efx_filter_get_filter_safe(struct efx_nic *efx, | 81 | * |
| 82 | enum efx_filter_priority priority, | 82 | * If an existing filter has equal match values to the new filter |
| 83 | u32 filter_id, struct efx_filter_spec *); | 83 | * spec, then the new filter might replace it, depending on the |
| 84 | extern void efx_filter_clear_rx(struct efx_nic *efx, | 84 | * relative priorities. If the existing filter has lower priority, or |
| 85 | enum efx_filter_priority priority); | 85 | * if @replace_equal is set and it has equal priority, then it is |
| 86 | extern u32 efx_filter_count_rx_used(struct efx_nic *efx, | 86 | * replaced. Otherwise the function fails, returning -%EPERM if |
| 87 | enum efx_filter_priority priority); | 87 | * the existing filter has higher priority or -%EEXIST if it has |
| 88 | extern u32 efx_filter_get_rx_id_limit(struct efx_nic *efx); | 88 | * equal priority. |
| 89 | extern s32 efx_filter_get_rx_ids(struct efx_nic *efx, | 89 | */ |
| 90 | enum efx_filter_priority priority, | 90 | static inline s32 efx_filter_insert_filter(struct efx_nic *efx, |
| 91 | u32 *buf, u32 size); | 91 | struct efx_filter_spec *spec, |
| 92 | bool replace_equal) | ||
| 93 | { | ||
| 94 | return efx->type->filter_insert(efx, spec, replace_equal); | ||
| 95 | } | ||
| 96 | |||
| 97 | /** | ||
| 98 | * efx_filter_remove_id_safe - remove a filter by ID, carefully | ||
| 99 | * @efx: NIC from which to remove the filter | ||
| 100 | * @priority: Priority of filter, as passed to @efx_filter_insert_filter | ||
| 101 | * @filter_id: ID of filter, as returned by @efx_filter_insert_filter | ||
| 102 | * | ||
| 103 | * This function will range-check @filter_id, so it is safe to call | ||
| 104 | * with a value passed from userland. | ||
| 105 | */ | ||
| 106 | static inline int efx_filter_remove_id_safe(struct efx_nic *efx, | ||
| 107 | enum efx_filter_priority priority, | ||
| 108 | u32 filter_id) | ||
| 109 | { | ||
| 110 | return efx->type->filter_remove_safe(efx, priority, filter_id); | ||
| 111 | } | ||
| 112 | |||
| 113 | /** | ||
| 114 | * efx_filter_get_filter_safe - retrieve a filter by ID, carefully | ||
| 115 | * @efx: NIC from which to remove the filter | ||
| 116 | * @priority: Priority of filter, as passed to @efx_filter_insert_filter | ||
| 117 | * @filter_id: ID of filter, as returned by @efx_filter_insert_filter | ||
| 118 | * @spec: Buffer in which to store filter specification | ||
| 119 | * | ||
| 120 | * This function will range-check @filter_id, so it is safe to call | ||
| 121 | * with a value passed from userland. | ||
| 122 | */ | ||
| 123 | static inline int | ||
| 124 | efx_filter_get_filter_safe(struct efx_nic *efx, | ||
| 125 | enum efx_filter_priority priority, | ||
| 126 | u32 filter_id, struct efx_filter_spec *spec) | ||
| 127 | { | ||
| 128 | return efx->type->filter_get_safe(efx, priority, filter_id, spec); | ||
| 129 | } | ||
| 130 | |||
| 131 | /** | ||
| 132 | * efx_farch_filter_clear_rx - remove RX filters by priority | ||
| 133 | * @efx: NIC from which to remove the filters | ||
| 134 | * @priority: Maximum priority to remove | ||
| 135 | */ | ||
| 136 | static inline void efx_filter_clear_rx(struct efx_nic *efx, | ||
| 137 | enum efx_filter_priority priority) | ||
| 138 | { | ||
| 139 | return efx->type->filter_clear_rx(efx, priority); | ||
| 140 | } | ||
| 141 | |||
| 142 | static inline u32 efx_filter_count_rx_used(struct efx_nic *efx, | ||
| 143 | enum efx_filter_priority priority) | ||
| 144 | { | ||
| 145 | return efx->type->filter_count_rx_used(efx, priority); | ||
| 146 | } | ||
| 147 | static inline u32 efx_filter_get_rx_id_limit(struct efx_nic *efx) | ||
| 148 | { | ||
| 149 | return efx->type->filter_get_rx_id_limit(efx); | ||
| 150 | } | ||
| 151 | static inline s32 efx_filter_get_rx_ids(struct efx_nic *efx, | ||
| 152 | enum efx_filter_priority priority, | ||
| 153 | u32 *buf, u32 size) | ||
| 154 | { | ||
| 155 | return efx->type->filter_get_rx_ids(efx, priority, buf, size); | ||
| 156 | } | ||
| 92 | #ifdef CONFIG_RFS_ACCEL | 157 | #ifdef CONFIG_RFS_ACCEL |
| 93 | extern int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb, | 158 | extern int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *s |
