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
);