.. | .. |
---|
9 | 9 | #include "item.h" |
---|
10 | 10 | #include "core_acl_flex_keys.h" |
---|
11 | 11 | |
---|
| 12 | +/* For the purpose of the driver, define an internal storage scratchpad |
---|
| 13 | + * that will be used to store key/mask values. For each defined element type |
---|
| 14 | + * define an internal storage geometry. |
---|
| 15 | + * |
---|
| 16 | + * When adding new elements, MLXSW_AFK_ELEMENT_STORAGE_SIZE must be increased |
---|
| 17 | + * accordingly. |
---|
| 18 | + */ |
---|
| 19 | +static const struct mlxsw_afk_element_info mlxsw_afk_element_infos[] = { |
---|
| 20 | + MLXSW_AFK_ELEMENT_INFO_U32(SRC_SYS_PORT, 0x00, 16, 16), |
---|
| 21 | + MLXSW_AFK_ELEMENT_INFO_BUF(DMAC_32_47, 0x04, 2), |
---|
| 22 | + MLXSW_AFK_ELEMENT_INFO_BUF(DMAC_0_31, 0x06, 4), |
---|
| 23 | + MLXSW_AFK_ELEMENT_INFO_BUF(SMAC_32_47, 0x0A, 2), |
---|
| 24 | + MLXSW_AFK_ELEMENT_INFO_BUF(SMAC_0_31, 0x0C, 4), |
---|
| 25 | + MLXSW_AFK_ELEMENT_INFO_U32(ETHERTYPE, 0x00, 0, 16), |
---|
| 26 | + MLXSW_AFK_ELEMENT_INFO_U32(IP_PROTO, 0x10, 0, 8), |
---|
| 27 | + MLXSW_AFK_ELEMENT_INFO_U32(VID, 0x10, 8, 12), |
---|
| 28 | + MLXSW_AFK_ELEMENT_INFO_U32(PCP, 0x10, 20, 3), |
---|
| 29 | + MLXSW_AFK_ELEMENT_INFO_U32(TCP_FLAGS, 0x10, 23, 9), |
---|
| 30 | + MLXSW_AFK_ELEMENT_INFO_U32(DST_L4_PORT, 0x14, 0, 16), |
---|
| 31 | + MLXSW_AFK_ELEMENT_INFO_U32(SRC_L4_PORT, 0x14, 16, 16), |
---|
| 32 | + MLXSW_AFK_ELEMENT_INFO_U32(IP_TTL_, 0x18, 0, 8), |
---|
| 33 | + MLXSW_AFK_ELEMENT_INFO_U32(IP_ECN, 0x18, 9, 2), |
---|
| 34 | + MLXSW_AFK_ELEMENT_INFO_U32(IP_DSCP, 0x18, 11, 6), |
---|
| 35 | + MLXSW_AFK_ELEMENT_INFO_U32(VIRT_ROUTER_8_10, 0x18, 17, 3), |
---|
| 36 | + MLXSW_AFK_ELEMENT_INFO_U32(VIRT_ROUTER_0_7, 0x18, 20, 8), |
---|
| 37 | + MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_96_127, 0x20, 4), |
---|
| 38 | + MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_64_95, 0x24, 4), |
---|
| 39 | + MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_32_63, 0x28, 4), |
---|
| 40 | + MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_0_31, 0x2C, 4), |
---|
| 41 | + MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_96_127, 0x30, 4), |
---|
| 42 | + MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_64_95, 0x34, 4), |
---|
| 43 | + MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_32_63, 0x38, 4), |
---|
| 44 | + MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_0_31, 0x3C, 4), |
---|
| 45 | +}; |
---|
| 46 | + |
---|
12 | 47 | struct mlxsw_afk { |
---|
13 | 48 | struct list_head key_info_list; |
---|
14 | 49 | unsigned int max_blocks; |
---|
.. | .. |
---|
26 | 61 | const struct mlxsw_afk_block *block = &mlxsw_afk->blocks[i]; |
---|
27 | 62 | |
---|
28 | 63 | for (j = 0; j < block->instances_count; j++) { |
---|
| 64 | + const struct mlxsw_afk_element_info *elinfo; |
---|
29 | 65 | struct mlxsw_afk_element_inst *elinst; |
---|
30 | 66 | |
---|
31 | 67 | elinst = &block->instances[j]; |
---|
32 | | - if (elinst->type != elinst->info->type || |
---|
33 | | - elinst->item.size.bits != |
---|
34 | | - elinst->info->item.size.bits) |
---|
| 68 | + elinfo = &mlxsw_afk_element_infos[elinst->element]; |
---|
| 69 | + if (elinst->type != elinfo->type || |
---|
| 70 | + (!elinst->avoid_size_check && |
---|
| 71 | + elinst->item.size.bits != |
---|
| 72 | + elinfo->item.size.bits)) |
---|
35 | 73 | return false; |
---|
36 | 74 | } |
---|
37 | 75 | } |
---|
.. | .. |
---|
71 | 109 | * is index inside "blocks" |
---|
72 | 110 | */ |
---|
73 | 111 | struct mlxsw_afk_element_usage elusage; |
---|
74 | | - const struct mlxsw_afk_block *blocks[0]; |
---|
| 112 | + const struct mlxsw_afk_block *blocks[]; |
---|
75 | 113 | }; |
---|
76 | 114 | |
---|
77 | 115 | static bool |
---|
.. | .. |
---|
115 | 153 | struct mlxsw_afk_element_inst *elinst; |
---|
116 | 154 | |
---|
117 | 155 | elinst = &block->instances[j]; |
---|
118 | | - if (elinst->info->element == element) { |
---|
| 156 | + if (elinst->element == element) { |
---|
119 | 157 | __set_bit(element, picker->hits[i].element); |
---|
120 | 158 | picker->hits[i].total++; |
---|
121 | 159 | } |
---|
.. | .. |
---|
236 | 274 | struct mlxsw_afk_element_usage *elusage) |
---|
237 | 275 | { |
---|
238 | 276 | struct mlxsw_afk_key_info *key_info; |
---|
239 | | - size_t alloc_size; |
---|
240 | 277 | int err; |
---|
241 | 278 | |
---|
242 | | - alloc_size = sizeof(*key_info) + |
---|
243 | | - sizeof(key_info->blocks[0]) * mlxsw_afk->max_blocks; |
---|
244 | | - key_info = kzalloc(alloc_size, GFP_KERNEL); |
---|
| 279 | + key_info = kzalloc(struct_size(key_info, blocks, mlxsw_afk->max_blocks), |
---|
| 280 | + GFP_KERNEL); |
---|
245 | 281 | if (!key_info) |
---|
246 | 282 | return ERR_PTR(-ENOMEM); |
---|
247 | 283 | err = mlxsw_afk_picker(mlxsw_afk, key_info, elusage); |
---|
.. | .. |
---|
302 | 338 | struct mlxsw_afk_element_inst *elinst; |
---|
303 | 339 | |
---|
304 | 340 | elinst = &block->instances[i]; |
---|
305 | | - if (elinst->info->element == element) |
---|
| 341 | + if (elinst->element == element) |
---|
306 | 342 | return elinst; |
---|
307 | 343 | } |
---|
308 | 344 | return NULL; |
---|
.. | .. |
---|
387 | 423 | |
---|
388 | 424 | static void mlxsw_sp_afk_encode_u32(const struct mlxsw_item *storage_item, |
---|
389 | 425 | const struct mlxsw_item *output_item, |
---|
390 | | - char *storage, char *output) |
---|
| 426 | + char *storage, char *output, int diff) |
---|
391 | 427 | { |
---|
392 | 428 | u32 value; |
---|
393 | 429 | |
---|
394 | 430 | value = __mlxsw_item_get32(storage, storage_item, 0); |
---|
395 | | - __mlxsw_item_set32(output, output_item, 0, value); |
---|
| 431 | + __mlxsw_item_set32(output, output_item, 0, value + diff); |
---|
396 | 432 | } |
---|
397 | 433 | |
---|
398 | 434 | static void mlxsw_sp_afk_encode_buf(const struct mlxsw_item *storage_item, |
---|
.. | .. |
---|
408 | 444 | |
---|
409 | 445 | static void |
---|
410 | 446 | mlxsw_sp_afk_encode_one(const struct mlxsw_afk_element_inst *elinst, |
---|
411 | | - char *output, char *storage) |
---|
| 447 | + char *output, char *storage, int u32_diff) |
---|
412 | 448 | { |
---|
413 | | - const struct mlxsw_item *storage_item = &elinst->info->item; |
---|
414 | 449 | const struct mlxsw_item *output_item = &elinst->item; |
---|
| 450 | + const struct mlxsw_afk_element_info *elinfo; |
---|
| 451 | + const struct mlxsw_item *storage_item; |
---|
415 | 452 | |
---|
| 453 | + elinfo = &mlxsw_afk_element_infos[elinst->element]; |
---|
| 454 | + storage_item = &elinfo->item; |
---|
416 | 455 | if (elinst->type == MLXSW_AFK_ELEMENT_TYPE_U32) |
---|
417 | 456 | mlxsw_sp_afk_encode_u32(storage_item, output_item, |
---|
418 | | - storage, output); |
---|
| 457 | + storage, output, u32_diff); |
---|
419 | 458 | else if (elinst->type == MLXSW_AFK_ELEMENT_TYPE_BUF) |
---|
420 | 459 | mlxsw_sp_afk_encode_buf(storage_item, output_item, |
---|
421 | 460 | storage, output); |
---|
.. | .. |
---|
426 | 465 | void mlxsw_afk_encode(struct mlxsw_afk *mlxsw_afk, |
---|
427 | 466 | struct mlxsw_afk_key_info *key_info, |
---|
428 | 467 | struct mlxsw_afk_element_values *values, |
---|
429 | | - char *key, char *mask, int block_start, int block_end) |
---|
| 468 | + char *key, char *mask) |
---|
430 | 469 | { |
---|
| 470 | + unsigned int blocks_count = |
---|
| 471 | + mlxsw_afk_key_info_blocks_count_get(key_info); |
---|
431 | 472 | char block_mask[MLXSW_SP_AFK_KEY_BLOCK_MAX_SIZE]; |
---|
432 | 473 | char block_key[MLXSW_SP_AFK_KEY_BLOCK_MAX_SIZE]; |
---|
433 | 474 | const struct mlxsw_afk_element_inst *elinst; |
---|
434 | 475 | enum mlxsw_afk_element element; |
---|
435 | 476 | int block_index, i; |
---|
436 | 477 | |
---|
437 | | - for (i = block_start; i <= block_end; i++) { |
---|
| 478 | + for (i = 0; i < blocks_count; i++) { |
---|
438 | 479 | memset(block_key, 0, MLXSW_SP_AFK_KEY_BLOCK_MAX_SIZE); |
---|
439 | 480 | memset(block_mask, 0, MLXSW_SP_AFK_KEY_BLOCK_MAX_SIZE); |
---|
440 | 481 | |
---|
.. | .. |
---|
446 | 487 | continue; |
---|
447 | 488 | |
---|
448 | 489 | mlxsw_sp_afk_encode_one(elinst, block_key, |
---|
449 | | - values->storage.key); |
---|
| 490 | + values->storage.key, |
---|
| 491 | + elinst->u32_key_diff); |
---|
450 | 492 | mlxsw_sp_afk_encode_one(elinst, block_mask, |
---|
451 | | - values->storage.mask); |
---|
| 493 | + values->storage.mask, 0); |
---|
452 | 494 | } |
---|
453 | 495 | |
---|
454 | | - if (key) |
---|
455 | | - mlxsw_afk->ops->encode_block(block_key, i, key); |
---|
456 | | - if (mask) |
---|
457 | | - mlxsw_afk->ops->encode_block(block_mask, i, mask); |
---|
| 496 | + mlxsw_afk->ops->encode_block(key, i, block_key); |
---|
| 497 | + mlxsw_afk->ops->encode_block(mask, i, block_mask); |
---|
458 | 498 | } |
---|
459 | 499 | } |
---|
460 | 500 | EXPORT_SYMBOL(mlxsw_afk_encode); |
---|
| 501 | + |
---|
| 502 | +void mlxsw_afk_clear(struct mlxsw_afk *mlxsw_afk, char *key, |
---|
| 503 | + int block_start, int block_end) |
---|
| 504 | +{ |
---|
| 505 | + int i; |
---|
| 506 | + |
---|
| 507 | + for (i = block_start; i <= block_end; i++) |
---|
| 508 | + mlxsw_afk->ops->clear_block(key, i); |
---|
| 509 | +} |
---|
| 510 | +EXPORT_SYMBOL(mlxsw_afk_clear); |
---|