1 /****************************************************************************
2 * Driver for Solarflare Solarstorm network controllers and boards
3 * Copyright 2005-2010 Solarflare Communications Inc.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published
7 * by the Free Software Foundation, incorporated herein by reference.
17 /* "Fudge factors" - difference between programmed value and actual depth.
18 * Due to pipelined implementation we need to program H/W with a value that
19 * is larger than the hop limit we want.
21 #define FILTER_CTL_SRCH_FUDGE_WILD 3
22 #define FILTER_CTL_SRCH_FUDGE_FULL 1
24 /* Hard maximum hop limit. Hardware will time-out beyond 200-something.
25 * We also need to avoid infinite loops in efx_filter_search() when the
28 #define FILTER_CTL_SRCH_MAX 200
30 /* Don't try very hard to find space for performance hints, as this is
31 * counter-productive. */
32 #define FILTER_CTL_SRCH_HINT_MAX 5
34 enum efx_filter_table_id {
35 EFX_FILTER_TABLE_RX_IP = 0,
36 EFX_FILTER_TABLE_RX_MAC,
37 EFX_FILTER_TABLE_COUNT,
40 struct efx_filter_table {
41 enum efx_filter_table_id id;
42 u32 offset; /* address of table relative to BAR */
43 unsigned size; /* number of entries */
44 unsigned step; /* step between entries */
45 unsigned used; /* number currently used */
46 unsigned long *used_bitmap;
47 struct efx_filter_spec *spec;
48 unsigned search_depth[EFX_FILTER_TYPE_COUNT];
51 struct efx_filter_state {
53 struct efx_filter_table table[EFX_FILTER_TABLE_COUNT];
56 /* The filter hash function is LFSR polynomial x^16 + x^3 + 1 of a 32-bit
57 * key derived from the n-tuple. The initial LFSR state is 0xffff. */
58 static u16 efx_filter_hash(u32 key)
63 tmp = 0x1fff ^ key >> 16;
64 tmp = tmp ^ tmp >> 3 ^ tmp >> 6;
67 tmp = tmp ^ tmp << 13 ^ key;
68 tmp = tmp ^ tmp >> 3 ^ tmp >> 6;
69 return tmp ^ tmp >> 9;
72 /* To allow for hash collisions, filter search continues at these
73 * increments from the first possible entry selected by the hash. */
74 static u16 efx_filter_increment(u32 key)
79 static enum efx_filter_table_id
80 efx_filter_spec_table_id(const struct efx_filter_spec *spec)
82 BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_TCP_FULL >> 2));
83 BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_TCP_WILD >> 2));
84 BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_UDP_FULL >> 2));
85 BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_UDP_WILD >> 2));
86 BUILD_BUG_ON(EFX_FILTER_TABLE_RX_MAC != (EFX_FILTER_MAC_FULL >> 2));
87 BUILD_BUG_ON(EFX_FILTER_TABLE_RX_MAC != (EFX_FILTER_MAC_WILD >> 2));
88 EFX_BUG_ON_PARANOID(spec->type == EFX_FILTER_UNSPEC);
89 return spec->type >> 2;
92 static struct efx_filter_table *
93 efx_filter_spec_table(struct efx_filter_state *state,
94 const struct efx_filter_spec *spec)
96 if (spec->type == EFX_FILTER_UNSPEC)
99 return &state->table[efx_filter_spec_table_id(spec)];
102 static void efx_filter_table_reset_search_depth(struct efx_filter_table *table)
104 memset(table->search_depth, 0, sizeof(table->search_depth));
107 static void efx_filter_push_rx_limits(struct efx_nic *efx)
109 struct efx_filter_state *state = efx->filter_state;
110 struct efx_filter_table *table;
111 efx_oword_t filter_ctl;
113 efx_reado(efx, &filter_ctl, FR_BZ_RX_FILTER_CTL);
115 table = &state->table[EFX_FILTER_TABLE_RX_IP];
116 EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_TCP_FULL_SRCH_LIMIT,
117 table->search_depth[EFX_FILTER_TCP_FULL] +
118 FILTER_CTL_SRCH_FUDGE_FULL);
119 EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_TCP_WILD_SRCH_LIMIT,
120 table->search_depth[EFX_FILTER_TCP_WILD] +
121 FILTER_CTL_SRCH_FUDGE_WILD);
122 EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_UDP_FULL_SRCH_LIMIT,
123 table->search_depth[EFX_FILTER_UDP_FULL] +
124 FILTER_CTL_SRCH_FUDGE_FULL);
125 EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_UDP_WILD_SRCH_LIMIT,
126 table->search_depth[EFX_FILTER_UDP_WILD] +
127 FILTER_CTL_SRCH_FUDGE_WILD);
129 table = &state->table[EFX_FILTER_TABLE_RX_MAC];
132 filter_ctl, FRF_CZ_ETHERNET_FULL_SEARCH_LIMIT,
133 table->search_depth[EFX_FILTER_MAC_FULL] +
134 FILTER_CTL_SRCH_FUDGE_FULL);
136 filter_ctl, FRF_CZ_ETHERNET_WILDCARD_SEARCH_LIMIT,
137 table->search_depth[EFX_FILTER_MAC_WILD] +
138 FILTER_CTL_SRCH_FUDGE_WILD);
141 efx_writeo(efx, &filter_ctl, FR_BZ_RX_FILTER_CTL);
144 static inline void __efx_filter_set_ipv4(struct efx_filter_spec *spec,
145 __be32 host1, __be16 port1,
146 __be32 host2, __be16 port2)
148 spec->data[0] = ntohl(host1) << 16 | ntohs(port1);
149 spec->data[1] = ntohs(port2) << 16 | ntohl(host1) >> 16;
150 spec->data[2] = ntohl(host2);
154 * efx_filter_set_ipv4_local - specify IPv4 host, transport protocol and port
155 * @spec: Specification to initialise
156 * @proto: Transport layer protocol number
157 * @host: Local host address (network byte order)
158 * @port: Local port (network byte order)
160 int efx_filter_set_ipv4_local(struct efx_filter_spec *spec, u8 proto,
161 __be32 host, __be16 port)
166 EFX_BUG_ON_PARANOID(!(spec->flags & EFX_FILTER_FLAG_RX));
168 /* This cannot currently be combined with other filtering */
169 if (spec->type != EFX_FILTER_UNSPEC)
170 return -EPROTONOSUPPORT;
177 spec->type = EFX_FILTER_TCP_WILD;
180 spec->type = EFX_FILTER_UDP_WILD;
183 return -EPROTONOSUPPORT;
186 /* Filter is constructed in terms of source and destination,
187 * with the odd wrinkle that the ports are swapped in a UDP
188 * wildcard filter. We need to convert from local and remote
189 * (= zero for wildcard) addresses.
192 if (proto != IPPROTO_UDP) {
199 __efx_filter_set_ipv4(spec, host1, port1, host, port);
204 * efx_filter_set_ipv4_full - specify IPv4 hosts, transport protocol and ports
205 * @spec: Specification to initialise
206 * @proto: Transport layer protocol number
207 * @host: Local host address (network byte order)
208 * @port: Local port (network byte order)
209 * @rhost: Remote host address (network byte order)
210 * @rport: Remote port (network byte order)
212 int efx_filter_set_ipv4_full(struct efx_filter_spec *spec, u8 proto,
213 __be32 host, __be16 port,
214 __be32 rhost, __be16 rport)
216 EFX_BUG_ON_PARANOID(!(spec->flags & EFX_FILTER_FLAG_RX));
218 /* This cannot currently be combined with other filtering */
219 if (spec->type != EFX_FILTER_UNSPEC)
220 return -EPROTONOSUPPORT;
222 if (port == 0 || rport == 0)
227 spec->type = EFX_FILTER_TCP_FULL;
230 spec->type = EFX_FILTER_UDP_FULL;
233 return -EPROTONOSUPPORT;
236 __efx_filter_set_ipv4(spec, rhost, rport, host, port);
241 * efx_filter_set_eth_local - specify local Ethernet address and optional VID
242 * @spec: Specification to initialise
243 * @vid: VLAN ID to match, or %EFX_FILTER_VID_UNSPEC
244 * @addr: Local Ethernet MAC address
246 int efx_filter_set_eth_local(struct efx_filter_spec *spec,
247 u16 vid, const u8 *addr)
249 EFX_BUG_ON_PARANOID(!(spec->flags & EFX_FILTER_FLAG_RX));
251 /* This cannot currently be combined with other filtering */
252 if (spec->type != EFX_FILTER_UNSPEC)
253 return -EPROTONOSUPPORT;
255 if (vid == EFX_FILTER_VID_UNSPEC) {
256 spec->type = EFX_FILTER_MAC_WILD;
259 spec->type = EFX_FILTER_MAC_FULL;
263 spec->data[1] = addr[2] << 24 | addr[3] << 16 | addr[4] << 8 | addr[5];
264 spec->data[2] = addr[0] << 8 | addr[1];
268 /* Build a filter entry and return its n-tuple key. */
269 static u32 efx_filter_build(efx_oword_t *filter, struct efx_filter_spec *spec)
273 switch (efx_filter_spec_table_id(spec)) {
274 case EFX_FILTER_TABLE_RX_IP: {
275 bool is_udp = (spec->type == EFX_FILTER_UDP_FULL ||
276 spec->type == EFX_FILTER_UDP_WILD);
277 EFX_POPULATE_OWORD_7(
280 !!(spec->flags & EFX_FILTER_FLAG_RX_RSS),
282 !!(spec->flags & EFX_FILTER_FLAG_RX_SCATTER),
283 FRF_BZ_TCP_UDP, is_udp,
284 FRF_BZ_RXQ_ID, spec->dmaq_id,
285 EFX_DWORD_2, spec->data[2],
286 EFX_DWORD_1, spec->data[1],
287 EFX_DWORD_0, spec->data[0]);
292 case EFX_FILTER_TABLE_RX_MAC: {
293 bool is_wild = spec->type == EFX_FILTER_MAC_WILD;
294 EFX_POPULATE_OWORD_8(
297 !!(spec->flags & EFX_FILTER_FLAG_RX_RSS),
298 FRF_CZ_RMFT_SCATTER_EN,
299 !!(spec->flags & EFX_FILTER_FLAG_RX_SCATTER),
300 FRF_CZ_RMFT_IP_OVERRIDE,
301 !!(spec->flags & EFX_FILTER_FLAG_RX_OVERRIDE_IP),
302 FRF_CZ_RMFT_RXQ_ID, spec->dmaq_id,
303 FRF_CZ_RMFT_WILDCARD_MATCH, is_wild,
304 FRF_CZ_RMFT_DEST_MAC_HI, spec->data[2],
305 FRF_CZ_RMFT_DEST_MAC_LO, spec->data[1],
306 FRF_CZ_RMFT_VLAN_ID, spec->data[0]);
315 return spec->data[0] ^ spec->data[1] ^ spec->data[2] ^ data3;
318 static bool efx_filter_equal(const struct efx_filter_spec *left,
319 const struct efx_filter_spec *right)
321 if (left->type != right->type ||
322 memcmp(left->data, right->data, sizeof(left->data)))
328 static int efx_filter_search(struct efx_filter_table *table,
329 struct efx_filter_spec *spec, u32 key,
330 bool for_insert, int *depth_required)
332 unsigned hash, incr, filter_idx, depth, depth_max;
333 struct efx_filter_spec *cmp;
335 hash = efx_filter_hash(key);
336 incr = efx_filter_increment(key);
337 depth_max = (spec->priority <= EFX_FILTER_PRI_HINT ?
338 FILTER_CTL_SRCH_HINT_MAX : FILTER_CTL_SRCH_MAX);
340 for (depth = 1, filter_idx = hash & (table->size - 1);
341 depth <= depth_max && test_bit(filter_idx, table->used_bitmap);
343 cmp = &table->spec[filter_idx];
344 if (efx_filter_equal(spec, cmp))
346 filter_idx = (filter_idx + incr) & (table->size - 1);
350 if (depth > depth_max)
353 *depth_required = depth;
357 /* Construct/deconstruct external filter IDs */
360 efx_filter_make_id(enum efx_filter_table_id table_id, unsigned index)
362 return table_id << 16 | index;
366 * efx_filter_insert_filter - add or replace a filter
367 * @efx: NIC in which to insert the filter
368 * @spec: Specification for the filter
369 * @replace: Flag for whether the specified filter may replace a filter
370 * with an identical match expression and equal or lower priority
372 * On success, return the filter ID.
373 * On failure, return a negative error code.
375 int efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec,
378 struct efx_filter_state *state = efx->filter_state;
379 struct efx_filter_table *table = efx_filter_spec_table(state, spec);
380 struct efx_filter_spec *saved_spec;
382 int filter_idx, depth;
386 if (!table || table->size == 0)
389 key = efx_filter_build(&filter, spec);
391 netif_vdbg(efx, hw, efx->net_dev,
392 "%s: type %d search_depth=%d", __func__, spec->type,
393 table->search_depth[spec->type]);
395 spin_lock_bh(&state->lock);
397 rc = efx_filter_search(table, spec, key, true, &depth);
401 BUG_ON(filter_idx >= table->size);
402 saved_spec = &table->spec[filter_idx];
404 if (test_bit(filter_idx, table->used_bitmap)) {
405 /* Should we replace the existing filter? */
410 if (spec->priority < saved_spec->priority) {
415 __set_bit(filter_idx, table->used_bitmap);
420 if (table->search_depth[spec->type] < depth) {
421 table->search_depth[spec->type] = depth;
422 efx_filter_push_rx_limits(efx);
425 efx_writeo(efx, &filter, table->offset + table->step * filter_idx);
427 netif_vdbg(efx, hw, efx->net_dev,
428 "%s: filter type %d index %d rxq %u set",
429 __func__, spec->type, filter_idx, spec->dmaq_id);
430 rc = efx_filter_make_id(table->id, filter_idx);
433 spin_unlock_bh(&state->lock);
437 static void efx_filter_table_clear_entry(struct efx_nic *efx,
438 struct efx_filter_table *table,
441 static efx_oword_t filter;
443 if (test_bit(filter_idx, table->used_bitmap)) {
444 __clear_bit(filter_idx, table->used_bitmap);
446 memset(&table->spec[filter_idx], 0, sizeof(table->spec[0]));
448 efx_writeo(efx, &filter,
449 table->offset + table->step * filter_idx);
454 * efx_filter_remove_filter - remove a filter by specification
455 * @efx: NIC from which to remove the filter
456 * @spec: Specification for the filter
458 * On success, return zero.
459 * On failure, return a negative error code.
461 int efx_filter_remove_filter(struct efx_nic *efx, struct efx_filter_spec *spec)
463 struct efx_filter_state *state = efx->filter_state;
464 struct efx_filter_table *table = efx_filter_spec_table(state, spec);
465 struct efx_filter_spec *saved_spec;
467 int filter_idx, depth;
474 key = efx_filter_build(&filter, spec);
476 spin_lock_bh(&state->lock);
478 rc = efx_filter_search(table, spec, key, false, &depth);
482 saved_spec = &table->spec[filter_idx];
484 if (spec->priority < saved_spec->priority) {
489 efx_filter_table_clear_entry(efx, table, filter_idx);
490 if (table->used == 0)
491 efx_filter_table_reset_search_depth(table);
495 spin_unlock_bh(&state->lock);
499 static void efx_filter_table_clear(struct efx_nic *efx,
500 enum efx_filter_table_id table_id,
501 enum efx_filter_priority priority)
503 struct efx_filter_state *state = efx->filter_state;
504 struct efx_filter_table *table = &state->table[table_id];
507 spin_lock_bh(&state->lock);
509 for (filter_idx = 0; filter_idx < table->size; ++filter_idx)
510 if (table->spec[filter_idx].priority <= priority)
511 efx_filter_table_clear_entry(efx, table, filter_idx);
512 if (table->used == 0)
513 efx_filter_table_reset_search_depth(table);
515 spin_unlock_bh(&state->lock);
519 * efx_filter_clear_rx - remove RX filters by priority
520 * @efx: NIC from which to remove the filters
521 * @priority: Maximum priority to remove
523 void efx_filter_clear_rx(struct efx_nic *efx, enum efx_filter_priority priority)
525 efx_filter_table_clear(efx, EFX_FILTER_TABLE_RX_IP, priority);
526 efx_filter_table_clear(efx, EFX_FILTER_TABLE_RX_MAC, priority);
529 /* Restore filter stater after reset */
530 void efx_restore_filters(struct efx_nic *efx)
532 struct efx_filter_state *state = efx->filter_state;
533 enum efx_filter_table_id table_id;
534 struct efx_filter_table *table;
538 spin_lock_bh(&state->lock);
540 for (table_id = 0; table_id < EFX_FILTER_TABLE_COUNT; table_id++) {
541 table = &state->table[table_id];
542 for (filter_idx = 0; filter_idx < table->size; filter_idx++) {
543 if (!test_bit(filter_idx, table->used_bitmap))
545 efx_filter_build(&filter, &table->spec[filter_idx]);
546 efx_writeo(efx, &filter,
547 table->offset + table->step * filter_idx);
551 efx_filter_push_rx_limits(efx);
553 spin_unlock_bh(&state->lock);
556 int efx_probe_filters(struct efx_nic *efx)
558 struct efx_filter_state *state;
559 struct efx_filter_table *table;
562 state = kzalloc(sizeof(*efx->filter_state), GFP_KERNEL);
565 efx->filter_state = state;
567 spin_lock_init(&state->lock);
569 if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) {
570 table = &state->table[EFX_FILTER_TABLE_RX_IP];
571 table->id = EFX_FILTER_TABLE_RX_IP;
572 table->offset = FR_BZ_RX_FILTER_TBL0;
573 table->size = FR_BZ_RX_FILTER_TBL0_ROWS;
574 table->step = FR_BZ_RX_FILTER_TBL0_STEP;
577 if (efx_nic_rev(efx) >= EFX_REV_SIENA_A0) {
578 table = &state->table[EFX_FILTER_TABLE_RX_MAC];
579 table->id = EFX_FILTER_TABLE_RX_MAC;
580 table->offset = FR_CZ_RX_MAC_FILTER_TBL0;
581 table->size = FR_CZ_RX_MAC_FILTER_TBL0_ROWS;
582 table->step = FR_CZ_RX_MAC_FILTER_TBL0_STEP;
585 for (table_id = 0; table_id < EFX_FILTER_TABLE_COUNT; table_id++) {
586 table = &state->table[table_id];
587 if (table->size == 0)
589 table->used_bitmap = kcalloc(BITS_TO_LONGS(table->size),
590 sizeof(unsigned long),
592 if (!table->used_bitmap)
594 table->spec = vzalloc(table->size * sizeof(*table->spec));
602 efx_remove_filters(efx);
606 void efx_remove_filters(struct efx_nic *efx)
608 struct efx_filter_state *state = efx->filter_state;
609 enum efx_filter_table_id table_id;
611 for (table_id = 0; table_id < EFX_FILTER_TABLE_COUNT; table_id++) {
612 kfree(state->table[table_id].used_bitmap);
613 vfree(state->table[table_id].spec);