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 enum efx_filter_table_id {
31 EFX_FILTER_TABLE_RX_IP = 0,
32 EFX_FILTER_TABLE_RX_MAC,
33 EFX_FILTER_TABLE_COUNT,
36 struct efx_filter_table {
37 enum efx_filter_table_id id;
38 u32 offset; /* address of table relative to BAR */
39 unsigned size; /* number of entries */
40 unsigned step; /* step between entries */
41 unsigned used; /* number currently used */
42 unsigned long *used_bitmap;
43 struct efx_filter_spec *spec;
44 unsigned search_depth[EFX_FILTER_TYPE_COUNT];
47 struct efx_filter_state {
49 struct efx_filter_table table[EFX_FILTER_TABLE_COUNT];
52 /* The filter hash function is LFSR polynomial x^16 + x^3 + 1 of a 32-bit
53 * key derived from the n-tuple. The initial LFSR state is 0xffff. */
54 static u16 efx_filter_hash(u32 key)
59 tmp = 0x1fff ^ key >> 16;
60 tmp = tmp ^ tmp >> 3 ^ tmp >> 6;
63 tmp = tmp ^ tmp << 13 ^ key;
64 tmp = tmp ^ tmp >> 3 ^ tmp >> 6;
65 return tmp ^ tmp >> 9;
68 /* To allow for hash collisions, filter search continues at these
69 * increments from the first possible entry selected by the hash. */
70 static u16 efx_filter_increment(u32 key)
75 static enum efx_filter_table_id
76 efx_filter_spec_table_id(const struct efx_filter_spec *spec)
78 BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_TCP_FULL >> 2));
79 BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_TCP_WILD >> 2));
80 BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_UDP_FULL >> 2));
81 BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP != (EFX_FILTER_UDP_WILD >> 2));
82 BUILD_BUG_ON(EFX_FILTER_TABLE_RX_MAC != (EFX_FILTER_MAC_FULL >> 2));
83 BUILD_BUG_ON(EFX_FILTER_TABLE_RX_MAC != (EFX_FILTER_MAC_WILD >> 2));
84 EFX_BUG_ON_PARANOID(spec->type == EFX_FILTER_UNSPEC);
85 return spec->type >> 2;
88 static struct efx_filter_table *
89 efx_filter_spec_table(struct efx_filter_state *state,
90 const struct efx_filter_spec *spec)
92 if (spec->type == EFX_FILTER_UNSPEC)
95 return &state->table[efx_filter_spec_table_id(spec)];
98 static void efx_filter_table_reset_search_depth(struct efx_filter_table *table)
100 memset(table->search_depth, 0, sizeof(table->search_depth));
103 static void efx_filter_push_rx_limits(struct efx_nic *efx)
105 struct efx_filter_state *state = efx->filter_state;
106 struct efx_filter_table *table;
107 efx_oword_t filter_ctl;
109 efx_reado(efx, &filter_ctl, FR_BZ_RX_FILTER_CTL);
111 table = &state->table[EFX_FILTER_TABLE_RX_IP];
112 EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_TCP_FULL_SRCH_LIMIT,
113 table->search_depth[EFX_FILTER_TCP_FULL] +
114 FILTER_CTL_SRCH_FUDGE_FULL);
115 EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_TCP_WILD_SRCH_LIMIT,
116 table->search_depth[EFX_FILTER_TCP_WILD] +
117 FILTER_CTL_SRCH_FUDGE_WILD);
118 EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_UDP_FULL_SRCH_LIMIT,
119 table->search_depth[EFX_FILTER_UDP_FULL] +
120 FILTER_CTL_SRCH_FUDGE_FULL);
121 EFX_SET_OWORD_FIELD(filter_ctl, FRF_BZ_UDP_WILD_SRCH_LIMIT,
122 table->search_depth[EFX_FILTER_UDP_WILD] +
123 FILTER_CTL_SRCH_FUDGE_WILD);
125 table = &state->table[EFX_FILTER_TABLE_RX_MAC];
128 filter_ctl, FRF_CZ_ETHERNET_FULL_SEARCH_LIMIT,
129 table->search_depth[EFX_FILTER_MAC_FULL] +
130 FILTER_CTL_SRCH_FUDGE_FULL);
132 filter_ctl, FRF_CZ_ETHERNET_WILDCARD_SEARCH_LIMIT,
133 table->search_depth[EFX_FILTER_MAC_WILD] +
134 FILTER_CTL_SRCH_FUDGE_WILD);
137 efx_writeo(efx, &filter_ctl, FR_BZ_RX_FILTER_CTL);
140 static inline void __efx_filter_set_ipv4(struct efx_filter_spec *spec,
141 __be32 host1, __be16 port1,
142 __be32 host2, __be16 port2)
144 spec->data[0] = ntohl(host1) << 16 | ntohs(port1);
145 spec->data[1] = ntohs(port2) << 16 | ntohl(host1) >> 16;
146 spec->data[2] = ntohl(host2);
150 * efx_filter_set_ipv4_local - specify IPv4 host, transport protocol and port
151 * @spec: Specification to initialise
152 * @proto: Transport layer protocol number
153 * @host: Local host address (network byte order)
154 * @port: Local port (network byte order)
156 int efx_filter_set_ipv4_local(struct efx_filter_spec *spec, u8 proto,
157 __be32 host, __be16 port)
162 EFX_BUG_ON_PARANOID(!(spec->flags & EFX_FILTER_FLAG_RX));
164 /* This cannot currently be combined with other filtering */
165 if (spec->type != EFX_FILTER_UNSPEC)
166 return -EPROTONOSUPPORT;
173 spec->type = EFX_FILTER_TCP_WILD;
176 spec->type = EFX_FILTER_UDP_WILD;
179 return -EPROTONOSUPPORT;
182 /* Filter is constructed in terms of source and destination,
183 * with the odd wrinkle that the ports are swapped in a UDP
184 * wildcard filter. We need to convert from local and remote
185 * (= zero for wildcard) addresses.
188 if (proto != IPPROTO_UDP) {
195 __efx_filter_set_ipv4(spec, host1, port1, host, port);
200 * efx_filter_set_ipv4_full - specify IPv4 hosts, transport protocol and ports
201 * @spec: Specification to initialise
202 * @proto: Transport layer protocol number
203 * @host: Local host address (network byte order)
204 * @port: Local port (network byte order)
205 * @rhost: Remote host address (network byte order)
206 * @rport: Remote port (network byte order)
208 int efx_filter_set_ipv4_full(struct efx_filter_spec *spec, u8 proto,
209 __be32 host, __be16 port,
210 __be32 rhost, __be16 rport)
212 EFX_BUG_ON_PARANOID(!(spec->flags & EFX_FILTER_FLAG_RX));
214 /* This cannot currently be combined with other filtering */
215 if (spec->type != EFX_FILTER_UNSPEC)
216 return -EPROTONOSUPPORT;
218 if (port == 0 || rport == 0)
223 spec->type = EFX_FILTER_TCP_FULL;
226 spec->type = EFX_FILTER_UDP_FULL;
229 return -EPROTONOSUPPORT;
232 __efx_filter_set_ipv4(spec, rhost, rport, host, port);
237 * efx_filter_set_eth_local - specify local Ethernet address and optional VID
238 * @spec: Specification to initialise
239 * @vid: VLAN ID to match, or %EFX_FILTER_VID_UNSPEC
240 * @addr: Local Ethernet MAC address
242 int efx_filter_set_eth_local(struct efx_filter_spec *spec,
243 u16 vid, const u8 *addr)
245 EFX_BUG_ON_PARANOID(!(spec->flags & EFX_FILTER_FLAG_RX));
247 /* This cannot currently be combined with other filtering */
248 if (spec->type != EFX_FILTER_UNSPEC)
249 return -EPROTONOSUPPORT;
251 if (vid == EFX_FILTER_VID_UNSPEC) {
252 spec->type = EFX_FILTER_MAC_WILD;
255 spec->type = EFX_FILTER_MAC_FULL;
259 spec->data[1] = addr[2] << 24 | addr[3] << 16 | addr[4] << 8 | addr[5];
260 spec->data[2] = addr[0] << 8 | addr[1];
264 /* Build a filter entry and return its n-tuple key. */
265 static u32 efx_filter_build(efx_oword_t *filter, struct efx_filter_spec *spec)
269 switch (efx_filter_spec_table_id(spec)) {
270 case EFX_FILTER_TABLE_RX_IP: {
271 bool is_udp = (spec->type == EFX_FILTER_UDP_FULL ||
272 spec->type == EFX_FILTER_UDP_WILD);
273 EFX_POPULATE_OWORD_7(
276 !!(spec->flags & EFX_FILTER_FLAG_RX_RSS),
278 !!(spec->flags & EFX_FILTER_FLAG_RX_SCATTER),
279 FRF_BZ_TCP_UDP, is_udp,
280 FRF_BZ_RXQ_ID, spec->dmaq_id,
281 EFX_DWORD_2, spec->data[2],
282 EFX_DWORD_1, spec->data[1],
283 EFX_DWORD_0, spec->data[0]);
288 case EFX_FILTER_TABLE_RX_MAC: {
289 bool is_wild = spec->type == EFX_FILTER_MAC_WILD;
290 EFX_POPULATE_OWORD_8(
293 !!(spec->flags & EFX_FILTER_FLAG_RX_RSS),
294 FRF_CZ_RMFT_SCATTER_EN,
295 !!(spec->flags & EFX_FILTER_FLAG_RX_SCATTER),
296 FRF_CZ_RMFT_IP_OVERRIDE,
297 !!(spec->flags & EFX_FILTER_FLAG_RX_OVERRIDE_IP),
298 FRF_CZ_RMFT_RXQ_ID, spec->dmaq_id,
299 FRF_CZ_RMFT_WILDCARD_MATCH, is_wild,
300 FRF_CZ_RMFT_DEST_MAC_HI, spec->data[2],
301 FRF_CZ_RMFT_DEST_MAC_LO, spec->data[1],
302 FRF_CZ_RMFT_VLAN_ID, spec->data[0]);
311 return spec->data[0] ^ spec->data[1] ^ spec->data[2] ^ data3;
314 static bool efx_filter_equal(const struct efx_filter_spec *left,
315 const struct efx_filter_spec *right)
317 if (left->type != right->type ||
318 memcmp(left->data, right->data, sizeof(left->data)))
324 static int efx_filter_search(struct efx_filter_table *table,
325 struct efx_filter_spec *spec, u32 key,
326 bool for_insert, int *depth_required)
328 unsigned hash, incr, filter_idx, depth;
329 struct efx_filter_spec *cmp;
331 hash = efx_filter_hash(key);
332 incr = efx_filter_increment(key);
334 for (depth = 1, filter_idx = hash & (table->size - 1);
335 depth <= FILTER_CTL_SRCH_MAX &&
336 test_bit(filter_idx, table->used_bitmap);
338 cmp = &table->spec[filter_idx];
339 if (efx_filter_equal(spec, cmp))
341 filter_idx = (filter_idx + incr) & (table->size - 1);
345 if (depth > FILTER_CTL_SRCH_MAX)
348 *depth_required = depth;
352 /* Construct/deconstruct external filter IDs */
355 efx_filter_make_id(enum efx_filter_table_id table_id, unsigned index)
357 return table_id << 16 | index;
361 * efx_filter_insert_filter - add or replace a filter
362 * @efx: NIC in which to insert the filter
363 * @spec: Specification for the filter
364 * @replace: Flag for whether the specified filter may replace a filter
365 * with an identical match expression and equal or lower priority
367 * On success, return the filter ID.
368 * On failure, return a negative error code.
370 int efx_filter_insert_filter(struct efx_nic *efx, struct efx_filter_spec *spec,
373 struct efx_filter_state *state = efx->filter_state;
374 struct efx_filter_table *table = efx_filter_spec_table(state, spec);
375 struct efx_filter_spec *saved_spec;
377 int filter_idx, depth;
381 if (!table || table->size == 0)
384 key = efx_filter_build(&filter, spec);
386 netif_vdbg(efx, hw, efx->net_dev,
387 "%s: type %d search_depth=%d", __func__, spec->type,
388 table->search_depth[spec->type]);
390 spin_lock_bh(&state->lock);
392 rc = efx_filter_search(table, spec, key, true, &depth);
396 BUG_ON(filter_idx >= table->size);
397 saved_spec = &table->spec[filter_idx];
399 if (test_bit(filter_idx, table->used_bitmap)) {
400 /* Should we replace the existing filter? */
405 if (spec->priority < saved_spec->priority) {
410 __set_bit(filter_idx, table->used_bitmap);
415 if (table->search_depth[spec->type] < depth) {
416 table->search_depth[spec->type] = depth;
417 efx_filter_push_rx_limits(efx);
420 efx_writeo(efx, &filter, table->offset + table->step * filter_idx);
422 netif_vdbg(efx, hw, efx->net_dev,
423 "%s: filter type %d index %d rxq %u set",
424 __func__, spec->type, filter_idx, spec->dmaq_id);
425 rc = efx_filter_make_id(table->id, filter_idx);
428 spin_unlock_bh(&state->lock);
432 static void efx_filter_table_clear_entry(struct efx_nic *efx,
433 struct efx_filter_table *table,
436 static efx_oword_t filter;
438 if (test_bit(filter_idx, table->used_bitmap)) {
439 __clear_bit(filter_idx, table->used_bitmap);
441 memset(&table->spec[filter_idx], 0, sizeof(table->spec[0]));
443 efx_writeo(efx, &filter,
444 table->offset + table->step * filter_idx);
449 * efx_filter_remove_filter - remove a filter by specification
450 * @efx: NIC from which to remove the filter
451 * @spec: Specification for the filter
453 * On success, return zero.
454 * On failure, return a negative error code.
456 int efx_filter_remove_filter(struct efx_nic *efx, struct efx_filter_spec *spec)
458 struct efx_filter_state *state = efx->filter_state;
459 struct efx_filter_table *table = efx_filter_spec_table(state, spec);
460 struct efx_filter_spec *saved_spec;
462 int filter_idx, depth;
469 key = efx_filter_build(&filter, spec);
471 spin_lock_bh(&state->lock);
473 rc = efx_filter_search(table, spec, key, false, &depth);
477 saved_spec = &table->spec[filter_idx];
479 if (spec->priority < saved_spec->priority) {
484 efx_filter_table_clear_entry(efx, table, filter_idx);
485 if (table->used == 0)
486 efx_filter_table_reset_search_depth(table);
490 spin_unlock_bh(&state->lock);
494 static void efx_filter_table_clear(struct efx_nic *efx,
495 enum efx_filter_table_id table_id,
496 enum efx_filter_priority priority)
498 struct efx_filter_state *state = efx->filter_state;
499 struct efx_filter_table *table = &state->table[table_id];
502 spin_lock_bh(&state->lock);
504 for (filter_idx = 0; filter_idx < table->size; ++filter_idx)
505 if (table->spec[filter_idx].priority <= priority)
506 efx_filter_table_clear_entry(efx, table, filter_idx);
507 if (table->used == 0)
508 efx_filter_table_reset_search_depth(table);
510 spin_unlock_bh(&state->lock);
514 * efx_filter_clear_rx - remove RX filters by priority
515 * @efx: NIC from which to remove the filters
516 * @priority: Maximum priority to remove
518 void efx_filter_clear_rx(struct efx_nic *efx, enum efx_filter_priority priority)
520 efx_filter_table_clear(efx, EFX_FILTER_TABLE_RX_IP, priority);
521 efx_filter_table_clear(efx, EFX_FILTER_TABLE_RX_MAC, priority);
524 /* Restore filter stater after reset */
525 void efx_restore_filters(struct efx_nic *efx)
527 struct efx_filter_state *state = efx->filter_state;
528 enum efx_filter_table_id table_id;
529 struct efx_filter_table *table;
533 spin_lock_bh(&state->lock);
535 for (table_id = 0; table_id < EFX_FILTER_TABLE_COUNT; table_id++) {
536 table = &state->table[table_id];
537 for (filter_idx = 0; filter_idx < table->size; filter_idx++) {
538 if (!test_bit(filter_idx, table->used_bitmap))
540 efx_filter_build(&filter, &table->spec[filter_idx]);
541 efx_writeo(efx, &filter,
542 table->offset + table->step * filter_idx);
546 efx_filter_push_rx_limits(efx);
548 spin_unlock_bh(&state->lock);
551 int efx_probe_filters(struct efx_nic *efx)
553 struct efx_filter_state *state;
554 struct efx_filter_table *table;
557 state = kzalloc(sizeof(*efx->filter_state), GFP_KERNEL);
560 efx->filter_state = state;
562 spin_lock_init(&state->lock);
564 if (efx_nic_rev(efx) >= EFX_REV_FALCON_B0) {
565 table = &state->table[EFX_FILTER_TABLE_RX_IP];
566 table->id = EFX_FILTER_TABLE_RX_IP;
567 table->offset = FR_BZ_RX_FILTER_TBL0;
568 table->size = FR_BZ_RX_FILTER_TBL0_ROWS;
569 table->step = FR_BZ_RX_FILTER_TBL0_STEP;
572 if (efx_nic_rev(efx) >= EFX_REV_SIENA_A0) {
573 table = &state->table[EFX_FILTER_TABLE_RX_MAC];
574 table->id = EFX_FILTER_TABLE_RX_MAC;
575 table->offset = FR_CZ_RX_MAC_FILTER_TBL0;
576 table->size = FR_CZ_RX_MAC_FILTER_TBL0_ROWS;
577 table->step = FR_CZ_RX_MAC_FILTER_TBL0_STEP;
580 for (table_id = 0; table_id < EFX_FILTER_TABLE_COUNT; table_id++) {
581 table = &state->table[table_id];
582 if (table->size == 0)
584 table->used_bitmap = kcalloc(BITS_TO_LONGS(table->size),
585 sizeof(unsigned long),
587 if (!table->used_bitmap)
589 table->spec = vzalloc(table->size * sizeof(*table->spec));
597 efx_remove_filters(efx);
601 void efx_remove_filters(struct efx_nic *efx)
603 struct efx_filter_state *state = efx->filter_state;
604 enum efx_filter_table_id table_id;
606 for (table_id = 0; table_id < EFX_FILTER_TABLE_COUNT; table_id++) {
607 kfree(state->table[table_id].used_bitmap);
608 vfree(state->table[table_id].spec);