@@ -17,16 +17,18 @@ struct mlxsw_sp_acl_bf {
1717};
1818
1919/* Bloom filter uses a crc-16 hash over chunks of data which contain 4 key
20- * blocks, eRP ID and region ID. In Spectrum-2, region key is combined of up to
21- * 12 key blocks, so there can be up to 3 chunks in the Bloom filter key,
22- * depending on the actual number of key blocks used in the region.
20+ * blocks, eRP ID and region ID. In Spectrum-2 and above , region key is combined
21+ * of up to 12 key blocks, so there can be up to 3 chunks in the Bloom filter
22+ * key, depending on the actual number of key blocks used in the region.
2323 * The layout of the Bloom filter key is as follows:
2424 *
2525 * +-------------------------+------------------------+------------------------+
2626 * | Chunk 2 Key blocks 11-8 | Chunk 1 Key blocks 7-4 | Chunk 0 Key blocks 3-0 |
2727 * +-------------------------+------------------------+------------------------+
2828 */
2929#define MLXSW_BLOOM_KEY_CHUNKS 3
30+
31+ /* Spectrum-2 and Spectrum-3 chunks */
3032#define MLXSW_SP2_BLOOM_KEY_LEN 69
3133
3234/* Each chunk size is 23 bytes. 18 bytes of it contain 4 key blocks, each is
@@ -51,19 +53,9 @@ struct mlxsw_sp_acl_bf {
5153 */
5254#define MLXSW_SP2_BLOOM_CHUNK_KEY_OFFSET 5
5355
54- /* Each chunk contains 4 key blocks. Chunk 2 uses key blocks 11-8,
55- * and we need to populate it with 4 key blocks copied from the entry encoded
56- * key. Since the encoded key contains a padding, key block 11 starts at offset
57- * 2. block 7 that is used in chunk 1 starts at offset 20 as 4 key blocks take
58- * 18 bytes.
59- * This array defines key offsets for easy access when copying key blocks from
60- * entry key to Bloom filter chunk.
61- */
62- static const u8 chunk_key_offsets [MLXSW_BLOOM_KEY_CHUNKS ] = {2 , 20 , 38 };
63-
64- /* This table is just the CRC of each possible byte. It is
65- * computed, Msbit first, for the Bloom filter polynomial
66- * which is 0x8529 (1 + x^3 + x^5 + x^8 + x^10 + x^15 and
56+ /* This table is just the CRC of each possible byte which is used for
57+ * Spectrum-{2-3}. It is computed, Msbit first, for the Bloom filter
58+ * polynomial which is 0x8529 (1 + x^3 + x^5 + x^8 + x^10 + x^15 and
6759 * the implicit x^16).
6860 */
6961static const u16 mlxsw_sp2_acl_bf_crc16_tab [256 ] = {
@@ -101,6 +93,127 @@ static const u16 mlxsw_sp2_acl_bf_crc16_tab[256] = {
101930x0c4c , 0x8965 , 0x8337 , 0x061e , 0x9793 , 0x12ba , 0x18e8 , 0x9dc1 ,
10294};
10395
96+ /* Spectrum-4 chunks */
97+ #define MLXSW_SP4_BLOOM_KEY_LEN 60
98+
99+ /* In Spectrum-4, there is no padding. Each chunk size is 20 bytes.
100+ * 18 bytes of it contain 4 key blocks, each is 36 bits, and 2 bytes which hold
101+ * eRP ID and region ID.
102+ * The layout of each chunk is as follows:
103+ *
104+ * +----------------------+-----------------------------------+
105+ * | 2 bytes | 18 bytes |
106+ * +-----------+----------+-----------------------------------+
107+ * | 157:148 | 147:144 | 143:0 |
108+ * +---------+-----------+----------+-------------------------+
109+ * | region ID | eRP ID | 4 Key blocks (18 Bytes) |
110+ * +-----------+----------+-----------------------------------+
111+ */
112+
113+ #define MLXSW_SP4_BLOOM_CHUNK_PAD_BYTES 0
114+ #define MLXSW_SP4_BLOOM_CHUNK_KEY_BYTES 18
115+ #define MLXSW_SP4_BLOOM_KEY_CHUNK_BYTES 20
116+
117+ /* The offset of the key block within a chunk is 2 bytes as it comes after
118+ * 16 bits of region ID and eRP ID.
119+ */
120+ #define MLXSW_SP4_BLOOM_CHUNK_KEY_OFFSET 2
121+
122+ /* For Spectrum-4, two hash functions are used, CRC-10 and CRC-6 based.
123+ * The result is combination of the two calculations -
124+ * 6 bit column are MSB (result of CRC-6),
125+ * 10 bit row are LSB (result of CRC-10).
126+ */
127+
128+ /* This table is just the CRC of each possible byte which is used for
129+ * Spectrum-4. It is computed, Msbit first, for the Bloom filter
130+ * polynomial which is 0x1b (1 + x^1 + x^3 + x^4 and the implicit x^10).
131+ */
132+ static const u16 mlxsw_sp4_acl_bf_crc10_tab [256 ] = {
133+ 0x0000 , 0x001b , 0x0036 , 0x002d , 0x006c , 0x0077 , 0x005a , 0x0041 ,
134+ 0x00d8 , 0x00c3 , 0x00ee , 0x00f5 , 0x00b4 , 0x00af , 0x0082 , 0x0099 ,
135+ 0x01b0 , 0x01ab , 0x0186 , 0x019d , 0x01dc , 0x01c7 , 0x01ea , 0x01f1 ,
136+ 0x0168 , 0x0173 , 0x015e , 0x0145 , 0x0104 , 0x011f , 0x0132 , 0x0129 ,
137+ 0x0360 , 0x037b , 0x0356 , 0x034d , 0x030c , 0x0317 , 0x033a , 0x0321 ,
138+ 0x03b8 , 0x03a3 , 0x038e , 0x0395 , 0x03d4 , 0x03cf , 0x03e2 , 0x03f9 ,
139+ 0x02d0 , 0x02cb , 0x02e6 , 0x02fd , 0x02bc , 0x02a7 , 0x028a , 0x0291 ,
140+ 0x0208 , 0x0213 , 0x023e , 0x0225 , 0x0264 , 0x027f , 0x0252 , 0x0249 ,
141+ 0x02db , 0x02c0 , 0x02ed , 0x02f6 , 0x02b7 , 0x02ac , 0x0281 , 0x029a ,
142+ 0x0203 , 0x0218 , 0x0235 , 0x022e , 0x026f , 0x0274 , 0x0259 , 0x0242 ,
143+ 0x036b , 0x0370 , 0x035d , 0x0346 , 0x0307 , 0x031c , 0x0331 , 0x032a ,
144+ 0x03b3 , 0x03a8 , 0x0385 , 0x039e , 0x03df , 0x03c4 , 0x03e9 , 0x03f2 ,
145+ 0x01bb , 0x01a0 , 0x018d , 0x0196 , 0x01d7 , 0x01cc , 0x01e1 , 0x01fa ,
146+ 0x0163 , 0x0178 , 0x0155 , 0x014e , 0x010f , 0x0114 , 0x0139 , 0x0122 ,
147+ 0x000b , 0x0010 , 0x003d , 0x0026 , 0x0067 , 0x007c , 0x0051 , 0x004a ,
148+ 0x00d3 , 0x00c8 , 0x00e5 , 0x00fe , 0x00bf , 0x00a4 , 0x0089 , 0x0092 ,
149+ 0x01ad , 0x01b6 , 0x019b , 0x0180 , 0x01c1 , 0x01da , 0x01f7 , 0x01ec ,
150+ 0x0175 , 0x016e , 0x0143 , 0x0158 , 0x0119 , 0x0102 , 0x012f , 0x0134 ,
151+ 0x001d , 0x0006 , 0x002b , 0x0030 , 0x0071 , 0x006a , 0x0047 , 0x005c ,
152+ 0x00c5 , 0x00de , 0x00f3 , 0x00e8 , 0x00a9 , 0x00b2 , 0x009f , 0x0084 ,
153+ 0x02cd , 0x02d6 , 0x02fb , 0x02e0 , 0x02a1 , 0x02ba , 0x0297 , 0x028c ,
154+ 0x0215 , 0x020e , 0x0223 , 0x0238 , 0x0279 , 0x0262 , 0x024f , 0x0254 ,
155+ 0x037d , 0x0366 , 0x034b , 0x0350 , 0x0311 , 0x030a , 0x0327 , 0x033c ,
156+ 0x03a5 , 0x03be , 0x0393 , 0x0388 , 0x03c9 , 0x03d2 , 0x03ff , 0x03e4 ,
157+ 0x0376 , 0x036d , 0x0340 , 0x035b , 0x031a , 0x0301 , 0x032c , 0x0337 ,
158+ 0x03ae , 0x03b5 , 0x0398 , 0x0383 , 0x03c2 , 0x03d9 , 0x03f4 , 0x03ef ,
159+ 0x02c6 , 0x02dd , 0x02f0 , 0x02eb , 0x02aa , 0x02b1 , 0x029c , 0x0287 ,
160+ 0x021e , 0x0205 , 0x0228 , 0x0233 , 0x0272 , 0x0269 , 0x0244 , 0x025f ,
161+ 0x0016 , 0x000d , 0x0020 , 0x003b , 0x007a , 0x0061 , 0x004c , 0x0057 ,
162+ 0x00ce , 0x00d5 , 0x00f8 , 0x00e3 , 0x00a2 , 0x00b9 , 0x0094 , 0x008f ,
163+ 0x01a6 , 0x01bd , 0x0190 , 0x018b , 0x01ca , 0x01d1 , 0x01fc , 0x01e7 ,
164+ 0x017e , 0x0165 , 0x0148 , 0x0153 , 0x0112 , 0x0109 , 0x0124 , 0x013f ,
165+ };
166+
167+ /* This table is just the CRC of each possible byte which is used for
168+ * Spectrum-4. It is computed, Msbit first, for the Bloom filter
169+ * polynomial which is 0x2d (1 + x^2+ x^3 + x^5 and the implicit x^6).
170+ */
171+ static const u8 mlxsw_sp4_acl_bf_crc6_tab [256 ] = {
172+ 0x00 , 0x2d , 0x37 , 0x1a , 0x03 , 0x2e , 0x34 , 0x19 ,
173+ 0x06 , 0x2b , 0x31 , 0x1c , 0x05 , 0x28 , 0x32 , 0x1f ,
174+ 0x0c , 0x21 , 0x3b , 0x16 , 0x0f , 0x22 , 0x38 , 0x15 ,
175+ 0x0a , 0x27 , 0x3d , 0x10 , 0x09 , 0x24 , 0x3e , 0x13 ,
176+ 0x18 , 0x35 , 0x2f , 0x02 , 0x1b , 0x36 , 0x2c , 0x01 ,
177+ 0x1e , 0x33 , 0x29 , 0x04 , 0x1d , 0x30 , 0x2a , 0x07 ,
178+ 0x14 , 0x39 , 0x23 , 0x0e , 0x17 , 0x3a , 0x20 , 0x0d ,
179+ 0x12 , 0x3f , 0x25 , 0x08 , 0x11 , 0x3c , 0x26 , 0x0b ,
180+ 0x30 , 0x1d , 0x07 , 0x2a , 0x33 , 0x1e , 0x04 , 0x29 ,
181+ 0x36 , 0x1b , 0x01 , 0x2c , 0x35 , 0x18 , 0x02 , 0x2f ,
182+ 0x3c , 0x11 , 0x0b , 0x26 , 0x3f , 0x12 , 0x08 , 0x25 ,
183+ 0x3a , 0x17 , 0x0d , 0x20 , 0x39 , 0x14 , 0x0e , 0x23 ,
184+ 0x28 , 0x05 , 0x1f , 0x32 , 0x2b , 0x06 , 0x1c , 0x31 ,
185+ 0x2e , 0x03 , 0x19 , 0x34 , 0x2d , 0x00 , 0x1a , 0x37 ,
186+ 0x24 , 0x09 , 0x13 , 0x3e , 0x27 , 0x0a , 0x10 , 0x3d ,
187+ 0x22 , 0x0f , 0x15 , 0x38 , 0x21 , 0x0c , 0x16 , 0x3b ,
188+ 0x0d , 0x20 , 0x3a , 0x17 , 0x0e , 0x23 , 0x39 , 0x14 ,
189+ 0x0b , 0x26 , 0x3c , 0x11 , 0x08 , 0x25 , 0x3f , 0x12 ,
190+ 0x01 , 0x2c , 0x36 , 0x1b , 0x02 , 0x2f , 0x35 , 0x18 ,
191+ 0x07 , 0x2a , 0x30 , 0x1d , 0x04 , 0x29 , 0x33 , 0x1e ,
192+ 0x15 , 0x38 , 0x22 , 0x0f , 0x16 , 0x3b , 0x21 , 0x0c ,
193+ 0x13 , 0x3e , 0x24 , 0x09 , 0x10 , 0x3d , 0x27 , 0x0a ,
194+ 0x19 , 0x34 , 0x2e , 0x03 , 0x1a , 0x37 , 0x2d , 0x00 ,
195+ 0x1f , 0x32 , 0x28 , 0x05 , 0x1c , 0x31 , 0x2b , 0x06 ,
196+ 0x3d , 0x10 , 0x0a , 0x27 , 0x3e , 0x13 , 0x09 , 0x24 ,
197+ 0x3b , 0x16 , 0x0c , 0x21 , 0x38 , 0x15 , 0x0f , 0x22 ,
198+ 0x31 , 0x1c , 0x06 , 0x2b , 0x32 , 0x1f , 0x05 , 0x28 ,
199+ 0x37 , 0x1a , 0x00 , 0x2d , 0x34 , 0x19 , 0x03 , 0x2e ,
200+ 0x25 , 0x08 , 0x12 , 0x3f , 0x26 , 0x0b , 0x11 , 0x3c ,
201+ 0x23 , 0x0e , 0x14 , 0x39 , 0x20 , 0x0d , 0x17 , 0x3a ,
202+ 0x29 , 0x04 , 0x1e , 0x33 , 0x2a , 0x07 , 0x1d , 0x30 ,
203+ 0x2f , 0x02 , 0x18 , 0x35 , 0x2c , 0x01 , 0x1b , 0x36 ,
204+ };
205+
206+ /* Each chunk contains 4 key blocks. Chunk 2 uses key blocks 11-8,
207+ * and we need to populate it with 4 key blocks copied from the entry encoded
208+ * key. The original keys layout is same for Spectrum-{2,3,4}.
209+ * Since the encoded key contains a 2 bytes padding, key block 11 starts at
210+ * offset 2. block 7 that is used in chunk 1 starts at offset 20 as 4 key blocks
211+ * take 18 bytes. See 'MLXSW_SP2_AFK_BLOCK_LAYOUT' for more details.
212+ * This array defines key offsets for easy access when copying key blocks from
213+ * entry key to Bloom filter chunk.
214+ */
215+ static const u8 chunk_key_offsets [MLXSW_BLOOM_KEY_CHUNKS ] = {2 , 20 , 38 };
216+
104217static u16 mlxsw_sp2_acl_bf_crc16_byte (u16 crc , u8 c )
105218{
106219 return (crc << 8 ) ^ mlxsw_sp2_acl_bf_crc16_tab [(crc >> 8 ) ^ c ];
@@ -168,6 +281,124 @@ mlxsw_sp2_acl_bf_index_get(struct mlxsw_sp_acl_bf *bf,
168281 return mlxsw_sp2_acl_bf_crc (bf_key , bf_size );
169282}
170283
284+ static u16 mlxsw_sp4_acl_bf_crc10_byte (u16 crc , u8 c )
285+ {
286+ u8 index = ((crc >> 2 ) ^ c ) & 0xff ;
287+
288+ return ((crc << 8 ) ^ mlxsw_sp4_acl_bf_crc10_tab [index ]) & 0x3ff ;
289+ }
290+
291+ static u16 mlxsw_sp4_acl_bf_crc6_byte (u16 crc , u8 c )
292+ {
293+ u8 index = (crc ^ c ) & 0xff ;
294+
295+ return ((crc << 6 ) ^ (mlxsw_sp4_acl_bf_crc6_tab [index ] << 2 )) & 0xfc ;
296+ }
297+
298+ static u16 mlxsw_sp4_acl_bf_crc (const u8 * buffer , size_t len )
299+ {
300+ u16 crc_row = 0 , crc_col = 0 ;
301+
302+ while (len -- ) {
303+ crc_row = mlxsw_sp4_acl_bf_crc10_byte (crc_row , * buffer );
304+ crc_col = mlxsw_sp4_acl_bf_crc6_byte (crc_col , * buffer );
305+ buffer ++ ;
306+ }
307+
308+ crc_col >>= 2 ;
309+
310+ /* 6 bit column are MSB, 10 bit row are LSB */
311+ return (crc_col << 10 ) | crc_row ;
312+ }
313+
314+ static void right_shift_array (char * arr , u8 len , u8 shift_bits )
315+ {
316+ u8 byte_mask = 0xff >> shift_bits ;
317+ int i ;
318+
319+ if (WARN_ON (!shift_bits || shift_bits >= 8 ))
320+ return ;
321+
322+ for (i = len - 1 ; i >= 0 ; i -- ) {
323+ /* The first iteration looks like out-of-bounds access,
324+ * but actually references a buffer that the array is shifted
325+ * into. This move is legal as we never send the last chunk to
326+ * this function.
327+ */
328+ arr [i + 1 ] &= byte_mask ;
329+ arr [i + 1 ] |= arr [i ] << (8 - shift_bits );
330+ arr [i ] = arr [i ] >> shift_bits ;
331+ }
332+ }
333+
334+ static void mlxsw_sp4_bf_key_shift_chunks (u8 chunk_count , char * output )
335+ {
336+ /* The chunks are suppoosed to be continuous, with no padding.
337+ * Since region ID and eRP ID use 14 bits, and not fully 2 bytes,
338+ * and in Spectrum-4 there is no padding, it is necessary to shift some
339+ * chunks 2 bits right.
340+ */
341+ switch (chunk_count ) {
342+ case 2 :
343+ /* The chunks are copied as follow:
344+ * +-------------+-----------------+
345+ * | Chunk 0 | Chunk 1 |
346+ * | IDs | keys |(**) IDs | keys |
347+ * +-------------+-----------------+
348+ * In (**), there are two unused bits, therefore, chunk 0 needs
349+ * to be shifted two bits right.
350+ */
351+ right_shift_array (output , MLXSW_SP4_BLOOM_KEY_CHUNK_BYTES , 2 );
352+ break ;
353+ case 3 :
354+ /* The chunks are copied as follow:
355+ * +-------------+-----------------+-----------------+
356+ * | Chunk 0 | Chunk 1 | Chunk 2 |
357+ * | IDs | keys |(**) IDs | keys |(**) IDs | keys |
358+ * +-------------+-----------------+-----------------+
359+ * In (**), there are two unused bits, therefore, chunk 1 needs
360+ * to be shifted two bits right and chunk 0 needs to be shifted
361+ * four bits right.
362+ */
363+ right_shift_array (output + MLXSW_SP4_BLOOM_KEY_CHUNK_BYTES ,
364+ MLXSW_SP4_BLOOM_KEY_CHUNK_BYTES , 2 );
365+ right_shift_array (output , MLXSW_SP4_BLOOM_KEY_CHUNK_BYTES , 4 );
366+ break ;
367+ default :
368+ WARN_ON (chunk_count > MLXSW_BLOOM_KEY_CHUNKS );
369+ }
370+ }
371+
372+ static void
373+ mlxsw_sp4_acl_bf_key_encode (struct mlxsw_sp_acl_atcam_region * aregion ,
374+ struct mlxsw_sp_acl_atcam_entry * aentry ,
375+ char * output , u8 * len )
376+ {
377+ struct mlxsw_afk_key_info * key_info = aregion -> region -> key_info ;
378+ u8 block_count = mlxsw_afk_key_info_blocks_count_get (key_info );
379+ u8 chunk_count = 1 + ((block_count - 1 ) >> 2 );
380+
381+ __mlxsw_sp_acl_bf_key_encode (aregion , aentry , output , len ,
382+ MLXSW_BLOOM_KEY_CHUNKS ,
383+ MLXSW_SP4_BLOOM_CHUNK_PAD_BYTES ,
384+ MLXSW_SP4_BLOOM_CHUNK_KEY_OFFSET ,
385+ MLXSW_SP4_BLOOM_CHUNK_KEY_BYTES ,
386+ MLXSW_SP4_BLOOM_KEY_CHUNK_BYTES );
387+ mlxsw_sp4_bf_key_shift_chunks (chunk_count , output );
388+ }
389+
390+ static unsigned int
391+ mlxsw_sp4_acl_bf_index_get (struct mlxsw_sp_acl_bf * bf ,
392+ struct mlxsw_sp_acl_atcam_region * aregion ,
393+ struct mlxsw_sp_acl_atcam_entry * aentry )
394+ {
395+ char bf_key [MLXSW_SP4_BLOOM_KEY_LEN ] = {};
396+ u8 bf_size ;
397+
398+ mlxsw_sp4_acl_bf_key_encode (aregion , aentry , bf_key , & bf_size );
399+ return mlxsw_sp4_acl_bf_crc (bf_key , bf_size );
400+ }
401+
171402static unsigned int
172403mlxsw_sp_acl_bf_rule_count_index_get (struct mlxsw_sp_acl_bf * bf ,
173404 unsigned int erp_bank ,
@@ -285,3 +516,7 @@ void mlxsw_sp_acl_bf_fini(struct mlxsw_sp_acl_bf *bf)
285516const struct mlxsw_sp_acl_bf_ops mlxsw_sp2_acl_bf_ops = {
286517 .index_get = mlxsw_sp2_acl_bf_index_get ,
287518};
519+
520+ const struct mlxsw_sp_acl_bf_ops mlxsw_sp4_acl_bf_ops = {
521+ .index_get = mlxsw_sp4_acl_bf_index_get ,
522+ };
0 commit comments