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.
16 /* "Fudge factors" - difference between programmed value and actual depth.
17 * Due to pipelined implementation we need to program H/W with a value that
18 * is larger than the hop limit we want.
20 #define FILTER_CTL_SRCH_FUDGE_WILD 3
21 #define FILTER_CTL_SRCH_FUDGE_FULL 1
23 /* Hard maximum hop limit. Hardware will time-out beyond 200-something.
24 * We also need to avoid infinite loops in efx_filter_search() when the
27 #define FILTER_CTL_SRCH_MAX 200
29 struct efx_filter_table
{
30 u32 offset
; /* address of table relative to BAR */
31 unsigned size
; /* number of entries */
32 unsigned step
; /* step between entries */
33 unsigned used
; /* number currently used */
34 unsigned long *used_bitmap
;
35 struct efx_filter_spec
*spec
;
38 struct efx_filter_state
{
40 struct efx_filter_table table
[EFX_FILTER_TABLE_COUNT
];
41 unsigned search_depth
[EFX_FILTER_TYPE_COUNT
];
44 /* The filter hash function is LFSR polynomial x^16 + x^3 + 1 of a 32-bit
45 * key derived from the n-tuple. The initial LFSR state is 0xffff. */
46 static u16
efx_filter_hash(u32 key
)
51 tmp
= 0x1fff ^ key
>> 16;
52 tmp
= tmp
^ tmp
>> 3 ^ tmp
>> 6;
55 tmp
= tmp
^ tmp
<< 13 ^ key
;
56 tmp
= tmp
^ tmp
>> 3 ^ tmp
>> 6;
57 return tmp
^ tmp
>> 9;
60 /* To allow for hash collisions, filter search continues at these
61 * increments from the first possible entry selected by the hash. */
62 static u16
efx_filter_increment(u32 key
)
67 static enum efx_filter_table_id
68 efx_filter_type_table_id(enum efx_filter_type type
)
70 BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP
!= (EFX_FILTER_RX_TCP_FULL
>> 2));
71 BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP
!= (EFX_FILTER_RX_TCP_WILD
>> 2));
72 BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP
!= (EFX_FILTER_RX_UDP_FULL
>> 2));
73 BUILD_BUG_ON(EFX_FILTER_TABLE_RX_IP
!= (EFX_FILTER_RX_UDP_WILD
>> 2));
74 BUILD_BUG_ON(EFX_FILTER_TABLE_RX_MAC
!= (EFX_FILTER_RX_MAC_FULL
>> 2));
75 BUILD_BUG_ON(EFX_FILTER_TABLE_RX_MAC
!= (EFX_FILTER_RX_MAC_WILD
>> 2));
80 efx_filter_table_reset_search_depth(struct efx_filter_state
*state
,
81 enum efx_filter_table_id table_id
)
83 memset(state
->search_depth
+ (table_id
<< 2), 0,
84 sizeof(state
->search_depth
[0]) << 2);
87 static void efx_filter_push_rx_limits(struct efx_nic
*efx
)
89 struct efx_filter_state
*state
= efx
->filter_state
;
90 efx_oword_t filter_ctl
;
92 efx_reado(efx
, &filter_ctl
, FR_BZ_RX_FILTER_CTL
);
94 EFX_SET_OWORD_FIELD(filter_ctl
, FRF_BZ_TCP_FULL_SRCH_LIMIT
,
95 state
->search_depth
[EFX_FILTER_RX_TCP_FULL
] +
96 FILTER_CTL_SRCH_FUDGE_FULL
);
97 EFX_SET_OWORD_FIELD(filter_ctl
, FRF_BZ_TCP_WILD_SRCH_LIMIT
,
98 state
->search_depth
[EFX_FILTER_RX_TCP_WILD
] +
99 FILTER_CTL_SRCH_FUDGE_WILD
);
100 EFX_SET_OWORD_FIELD(filter_ctl
, FRF_BZ_UDP_FULL_SRCH_LIMIT
,
101 state
->search_depth
[EFX_FILTER_RX_UDP_FULL
] +
102 FILTER_CTL_SRCH_FUDGE_FULL
);
103 EFX_SET_OWORD_FIELD(filter_ctl
, FRF_BZ_UDP_WILD_SRCH_LIMIT
,
104 state
->search_depth
[EFX_FILTER_RX_UDP_WILD
] +
105 FILTER_CTL_SRCH_FUDGE_WILD
);
107 if (state
->table
[EFX_FILTER_TABLE_RX_MAC
].size
) {
109 filter_ctl
, FRF_CZ_ETHERNET_FULL_SEARCH_LIMIT
,
110 state
->search_depth
[EFX_FILTER_RX_MAC_FULL
] +
111 FILTER_CTL_SRCH_FUDGE_FULL
);
113 filter_ctl
, FRF_CZ_ETHERNET_WILDCARD_SEARCH_LIMIT
,
114 state
->search_depth
[EFX_FILTER_RX_MAC_WILD
] +
115 FILTER_CTL_SRCH_FUDGE_WILD
);
118 efx_writeo(efx
, &filter_ctl
, FR_BZ_RX_FILTER_CTL
);
121 /* Build a filter entry and return its n-tuple key. */
122 static u32
efx_filter_build(efx_oword_t
*filter
, struct efx_filter_spec
*spec
)
126 switch (efx_filter_type_table_id(spec
->type
)) {
127 case EFX_FILTER_TABLE_RX_IP
: {
128 bool is_udp
= (spec
->type
== EFX_FILTER_RX_UDP_FULL
||
129 spec
->type
== EFX_FILTER_RX_UDP_WILD
);
130 EFX_POPULATE_OWORD_7(
133 !!(spec
->flags
& EFX_FILTER_FLAG_RX_RSS
),
135 !!(spec
->flags
& EFX_FILTER_FLAG_RX_SCATTER
),
136 FRF_BZ_TCP_UDP
, is_udp
,
137 FRF_BZ_RXQ_ID
, spec
->dmaq_id
,
138 EFX_DWORD_2
, spec
->data
[2],
139 EFX_DWORD_1
, spec
->data
[1],
140 EFX_DWORD_0
, spec
->data
[0]);
145 case EFX_FILTER_TABLE_RX_MAC
: {
146 bool is_wild
= spec
->type
== EFX_FILTER_RX_MAC_WILD
;
147 EFX_POPULATE_OWORD_8(
150 !!(spec
->flags
& EFX_FILTER_FLAG_RX_RSS
),
151 FRF_CZ_RMFT_SCATTER_EN
,
152 !!(spec
->flags
& EFX_FILTER_FLAG_RX_SCATTER
),
153 FRF_CZ_RMFT_IP_OVERRIDE
,
154 !!(spec
->flags
& EFX_FILTER_FLAG_RX_OVERRIDE_IP
),
155 FRF_CZ_RMFT_RXQ_ID
, spec
->dmaq_id
,
156 FRF_CZ_RMFT_WILDCARD_MATCH
, is_wild
,
157 FRF_CZ_RMFT_DEST_MAC_HI
, spec
->data
[2],
158 FRF_CZ_RMFT_DEST_MAC_LO
, spec
->data
[1],
159 FRF_CZ_RMFT_VLAN_ID
, spec
->data
[0]);
168 return spec
->data
[0] ^ spec
->data
[1] ^ spec
->data
[2] ^ data3
;
171 static bool efx_filter_equal(const struct efx_filter_spec
*left
,
172 const struct efx_filter_spec
*right
)
174 if (left
->type
!= right
->type
||
175 memcmp(left
->data
, right
->data
, sizeof(left
->data
)))
181 static int efx_filter_search(struct efx_filter_table
*table
,
182 struct efx_filter_spec
*spec
, u32 key
,
183 bool for_insert
, int *depth_required
)
185 unsigned hash
, incr
, filter_idx
, depth
;
186 struct efx_filter_spec
*cmp
;
188 hash
= efx_filter_hash(key
);
189 incr
= efx_filter_increment(key
);
191 for (depth
= 1, filter_idx
= hash
& (table
->size
- 1);
192 depth
<= FILTER_CTL_SRCH_MAX
&&
193 test_bit(filter_idx
, table
->used_bitmap
);
195 cmp
= &table
->spec
[filter_idx
];
196 if (efx_filter_equal(spec
, cmp
))
198 filter_idx
= (filter_idx
+ incr
) & (table
->size
- 1);
202 if (depth
> FILTER_CTL_SRCH_MAX
)
205 *depth_required
= depth
;
210 * efx_filter_insert_filter - add or replace a filter
211 * @efx: NIC in which to insert the filter
212 * @spec: Specification for the filter
213 * @replace: Flag for whether the specified filter may replace a filter
214 * with an identical match expression and equal or lower priority
216 * On success, return the filter index within its table.
217 * On failure, return a negative error code.
219 int efx_filter_insert_filter(struct efx_nic
*efx
, struct efx_filter_spec
*spec
,
222 struct efx_filter_state
*state
= efx
->filter_state
;
223 enum efx_filter_table_id table_id
=
224 efx_filter_type_table_id(spec
->type
);
225 struct efx_filter_table
*table
= &state
->table
[table_id
];
226 struct efx_filter_spec
*saved_spec
;
228 int filter_idx
, depth
;
232 if (table
->size
== 0)
235 key
= efx_filter_build(&filter
, spec
);
237 netif_vdbg(efx
, hw
, efx
->net_dev
,
238 "%s: type %d search_depth=%d", __func__
, spec
->type
,
239 state
->search_depth
[spec
->type
]);
241 spin_lock_bh(&state
->lock
);
243 rc
= efx_filter_search(table
, spec
, key
, true, &depth
);
247 BUG_ON(filter_idx
>= table
->size
);
248 saved_spec
= &table
->spec
[filter_idx
];
250 if (test_bit(filter_idx
, table
->used_bitmap
)) {
251 /* Should we replace the existing filter? */
256 if (spec
->priority
< saved_spec
->priority
) {
261 __set_bit(filter_idx
, table
->used_bitmap
);
266 if (state
->search_depth
[spec
->type
] < depth
) {
267 state
->search_depth
[spec
->type
] = depth
;
268 efx_filter_push_rx_limits(efx
);
271 efx_writeo(efx
, &filter
, table
->offset
+ table
->step
* filter_idx
);
273 netif_vdbg(efx
, hw
, efx
->net_dev
,
274 "%s: filter type %d index %d rxq %u set",
275 __func__
, spec
->type
, filter_idx
, spec
->dmaq_id
);
278 spin_unlock_bh(&state
->lock
);
282 static void efx_filter_table_clear_entry(struct efx_nic
*efx
,
283 struct efx_filter_table
*table
,
286 static efx_oword_t filter
;
288 if (test_bit(filter_idx
, table
->used_bitmap
)) {
289 __clear_bit(filter_idx
, table
->used_bitmap
);
291 memset(&table
->spec
[filter_idx
], 0, sizeof(table
->spec
[0]));
293 efx_writeo(efx
, &filter
,
294 table
->offset
+ table
->step
* filter_idx
);
299 * efx_filter_remove_filter - remove a filter by specification
300 * @efx: NIC from which to remove the filter
301 * @spec: Specification for the filter
303 * On success, return zero.
304 * On failure, return a negative error code.
306 int efx_filter_remove_filter(struct efx_nic
*efx
, struct efx_filter_spec
*spec
)
308 struct efx_filter_state
*state
= efx
->filter_state
;
309 enum efx_filter_table_id table_id
=
310 efx_filter_type_table_id(spec
->type
);
311 struct efx_filter_table
*table
= &state
->table
[table_id
];
312 struct efx_filter_spec
*saved_spec
;
314 int filter_idx
, depth
;
318 key
= efx_filter_build(&filter
, spec
);
320 spin_lock_bh(&state
->lock
);
322 rc
= efx_filter_search(table
, spec
, key
, false, &depth
);
326 saved_spec
= &table
->spec
[filter_idx
];
328 if (spec
->priority
< saved_spec
->priority
) {
333 efx_filter_table_clear_entry(efx
, table
, filter_idx
);
334 if (table
->used
== 0)
335 efx_filter_table_reset_search_depth(state
, table_id
);
339 spin_unlock_bh(&state
->lock
);
344 * efx_filter_table_clear - remove filters from a table by priority
345 * @efx: NIC from which to remove the filters
346 * @table_id: Table from which to remove the filters
347 * @priority: Maximum priority to remove
349 void efx_filter_table_clear(struct efx_nic
*efx
,
350 enum efx_filter_table_id table_id
,
351 enum efx_filter_priority priority
)
353 struct efx_filter_state
*state
= efx
->filter_state
;
354 struct efx_filter_table
*table
= &state
->table
[table_id
];
357 spin_lock_bh(&state
->lock
);
359 for (filter_idx
= 0; filter_idx
< table
->size
; ++filter_idx
)
360 if (table
->spec
[filter_idx
].priority
<= priority
)
361 efx_filter_table_clear_entry(efx
, table
, filter_idx
);
362 if (table
->used
== 0)
363 efx_filter_table_reset_search_depth(state
, table_id
);
365 spin_unlock_bh(&state
->lock
);
368 /* Restore filter stater after reset */
369 void efx_restore_filters(struct efx_nic
*efx
)
371 struct efx_filter_state
*state
= efx
->filter_state
;
372 enum efx_filter_table_id table_id
;
373 struct efx_filter_table
*table
;
377 spin_lock_bh(&state
->lock
);
379 for (table_id
= 0; table_id
< EFX_FILTER_TABLE_COUNT
; table_id
++) {
380 table
= &state
->table
[table_id
];
381 for (filter_idx
= 0; filter_idx
< table
->size
; filter_idx
++) {
382 if (!test_bit(filter_idx
, table
->used_bitmap
))
384 efx_filter_build(&filter
, &table
->spec
[filter_idx
]);
385 efx_writeo(efx
, &filter
,
386 table
->offset
+ table
->step
* filter_idx
);
390 efx_filter_push_rx_limits(efx
);
392 spin_unlock_bh(&state
->lock
);
395 int efx_probe_filters(struct efx_nic
*efx
)
397 struct efx_filter_state
*state
;
398 struct efx_filter_table
*table
;
401 state
= kzalloc(sizeof(*efx
->filter_state
), GFP_KERNEL
);
404 efx
->filter_state
= state
;
406 spin_lock_init(&state
->lock
);
408 if (efx_nic_rev(efx
) >= EFX_REV_FALCON_B0
) {
409 table
= &state
->table
[EFX_FILTER_TABLE_RX_IP
];
410 table
->offset
= FR_BZ_RX_FILTER_TBL0
;
411 table
->size
= FR_BZ_RX_FILTER_TBL0_ROWS
;
412 table
->step
= FR_BZ_RX_FILTER_TBL0_STEP
;
415 if (efx_nic_rev(efx
) >= EFX_REV_SIENA_A0
) {
416 table
= &state
->table
[EFX_FILTER_TABLE_RX_MAC
];
417 table
->offset
= FR_CZ_RX_MAC_FILTER_TBL0
;
418 table
->size
= FR_CZ_RX_MAC_FILTER_TBL0_ROWS
;
419 table
->step
= FR_CZ_RX_MAC_FILTER_TBL0_STEP
;
422 for (table_id
= 0; table_id
< EFX_FILTER_TABLE_COUNT
; table_id
++) {
423 table
= &state
->table
[table_id
];
424 if (table
->size
== 0)
426 table
->used_bitmap
= kcalloc(BITS_TO_LONGS(table
->size
),
427 sizeof(unsigned long),
429 if (!table
->used_bitmap
)
431 table
->spec
= vmalloc(table
->size
* sizeof(*table
->spec
));
434 memset(table
->spec
, 0, table
->size
* sizeof(*table
->spec
));
440 efx_remove_filters(efx
);
444 void efx_remove_filters(struct efx_nic
*efx
)
446 struct efx_filter_state
*state
= efx
->filter_state
;
447 enum efx_filter_table_id table_id
;
449 for (table_id
= 0; table_id
< EFX_FILTER_TABLE_COUNT
; table_id
++) {
450 kfree(state
->table
[table_id
].used_bitmap
);
451 vfree(state
->table
[table_id
].spec
);