aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/sfc/Makefile1
-rw-r--r--drivers/net/ethernet/sfc/efx.c40
-rw-r--r--drivers/net/ethernet/sfc/efx.h107
-rw-r--r--drivers/net/ethernet/sfc/falcon.c31
-rw-r--r--drivers/net/ethernet/sfc/farch.c1108
-rw-r--r--drivers/net/ethernet/sfc/filter.c1244
-rw-r--r--drivers/net/ethernet/sfc/net_driver.h46
-rw-r--r--drivers/net/ethernet/sfc/nic.h28
-rw-r--r--drivers/net/ethernet/sfc/rx.c94
-rw-r--r--drivers/net/ethernet/sfc/siena.c16
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 @@
1sfc-y += efx.o nic.o farch.o falcon.o siena.o tx.o rx.o \ 1sfc-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
1502static 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
1527static 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
1535static 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 */
71extern int efx_probe_filters(struct efx_nic *efx); 71
72extern void efx_restore_filters(struct efx_nic *efx); 72/**
73extern void efx_remove_filters(struct efx_nic *efx); 73 * efx_filter_insert_filter - add or replace a filter
74extern void efx_filter_update_rx_scatter(struct efx_nic *efx); 74 * @efx: NIC in which to insert the filter
75extern 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
78extern 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.
81extern 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
84extern 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
86extern 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
88extern u32 efx_filter_get_rx_id_limit(struct efx_nic *efx); 88 * equal priority.
89extern s32 efx_filter_get_rx_ids(struct efx_nic *efx, 89 */
90 enum efx_filter_priority priority, 90static 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 */
106static 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 */
123static inline int
124efx_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 */
136static 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
142static 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}
147static inline u32 efx_filter_get_rx_id_limit(struct efx_nic *efx)
148{
149 return efx->type->filter_get_rx_id_limit(efx);
150}
151static 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
93extern int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *skb, 158extern int efx_filter_rfs(struct net_device *net_dev, const struct sk_buff *s