@@ -2600,6 +2600,12 @@ struct bnx2x_mcast_mac_elem {
2600
2600
u8 pad [2 ]; /* For a natural alignment of the following buffer */
2601
2601
};
2602
2602
2603
+ struct bnx2x_mcast_bin_elem {
2604
+ struct list_head link ;
2605
+ int bin ;
2606
+ int type ; /* BNX2X_MCAST_CMD_SET_{ADD, DEL} */
2607
+ };
2608
+
2603
2609
struct bnx2x_pending_mcast_cmd {
2604
2610
struct list_head link ;
2605
2611
int type ; /* BNX2X_MCAST_CMD_X */
@@ -2609,6 +2615,11 @@ struct bnx2x_pending_mcast_cmd {
2609
2615
int next_bin ; /* Needed for RESTORE flow with aprox match */
2610
2616
} data ;
2611
2617
2618
+ bool set_convert ; /* in case type == BNX2X_MCAST_CMD_SET, this is set
2619
+ * when macs_head had been converted to a list of
2620
+ * bnx2x_mcast_bin_elem.
2621
+ */
2622
+
2612
2623
bool done ; /* set to true, when the command has been handled,
2613
2624
* practically used in 57712 handling only, where one pending
2614
2625
* command may be handled in a few operations. As long as for
@@ -2636,15 +2647,30 @@ static int bnx2x_mcast_enqueue_cmd(struct bnx2x *bp,
2636
2647
struct bnx2x_pending_mcast_cmd * new_cmd ;
2637
2648
struct bnx2x_mcast_mac_elem * cur_mac = NULL ;
2638
2649
struct bnx2x_mcast_list_elem * pos ;
2639
- int macs_list_len = ((cmd == BNX2X_MCAST_CMD_ADD ) ?
2640
- p -> mcast_list_len : 0 );
2650
+ int macs_list_len = 0 , macs_list_len_size ;
2651
+
2652
+ /* When adding MACs we'll need to store their values */
2653
+ if (cmd == BNX2X_MCAST_CMD_ADD || cmd == BNX2X_MCAST_CMD_SET )
2654
+ macs_list_len = p -> mcast_list_len ;
2641
2655
2642
2656
/* If the command is empty ("handle pending commands only"), break */
2643
2657
if (!p -> mcast_list_len )
2644
2658
return 0 ;
2645
2659
2646
- total_sz = sizeof (* new_cmd ) +
2647
- macs_list_len * sizeof (struct bnx2x_mcast_mac_elem );
2660
+ /* For a set command, we need to allocate sufficient memory for all
2661
+ * the bins, since we can't analyze at this point how much memory would
2662
+ * be required.
2663
+ */
2664
+ macs_list_len_size = macs_list_len *
2665
+ sizeof (struct bnx2x_mcast_mac_elem );
2666
+ if (cmd == BNX2X_MCAST_CMD_SET ) {
2667
+ int bin_size = BNX2X_MCAST_BINS_NUM *
2668
+ sizeof (struct bnx2x_mcast_bin_elem );
2669
+
2670
+ if (bin_size > macs_list_len_size )
2671
+ macs_list_len_size = bin_size ;
2672
+ }
2673
+ total_sz = sizeof (* new_cmd ) + macs_list_len_size ;
2648
2674
2649
2675
/* Add mcast is called under spin_lock, thus calling with GFP_ATOMIC */
2650
2676
new_cmd = kzalloc (total_sz , GFP_ATOMIC );
@@ -2662,6 +2688,7 @@ static int bnx2x_mcast_enqueue_cmd(struct bnx2x *bp,
2662
2688
2663
2689
switch (cmd ) {
2664
2690
case BNX2X_MCAST_CMD_ADD :
2691
+ case BNX2X_MCAST_CMD_SET :
2665
2692
cur_mac = (struct bnx2x_mcast_mac_elem * )
2666
2693
((u8 * )new_cmd + sizeof (* new_cmd ));
2667
2694
@@ -2771,7 +2798,8 @@ static void bnx2x_mcast_set_one_rule_e2(struct bnx2x *bp,
2771
2798
u8 rx_tx_add_flag = bnx2x_mcast_get_rx_tx_flag (o );
2772
2799
int bin ;
2773
2800
2774
- if ((cmd == BNX2X_MCAST_CMD_ADD ) || (cmd == BNX2X_MCAST_CMD_RESTORE ))
2801
+ if ((cmd == BNX2X_MCAST_CMD_ADD ) || (cmd == BNX2X_MCAST_CMD_RESTORE ) ||
2802
+ (cmd == BNX2X_MCAST_CMD_SET_ADD ))
2775
2803
rx_tx_add_flag |= ETH_MULTICAST_RULES_CMD_IS_ADD ;
2776
2804
2777
2805
data -> rules [idx ].cmd_general_data |= rx_tx_add_flag ;
@@ -2797,6 +2825,16 @@ static void bnx2x_mcast_set_one_rule_e2(struct bnx2x *bp,
2797
2825
bin = cfg_data -> bin ;
2798
2826
break ;
2799
2827
2828
+ case BNX2X_MCAST_CMD_SET_ADD :
2829
+ bin = cfg_data -> bin ;
2830
+ BIT_VEC64_SET_BIT (o -> registry .aprox_match .vec , bin );
2831
+ break ;
2832
+
2833
+ case BNX2X_MCAST_CMD_SET_DEL :
2834
+ bin = cfg_data -> bin ;
2835
+ BIT_VEC64_CLEAR_BIT (o -> registry .aprox_match .vec , bin );
2836
+ break ;
2837
+
2800
2838
default :
2801
2839
BNX2X_ERR ("Unknown command: %d\n" , cmd );
2802
2840
return ;
@@ -2932,6 +2970,102 @@ static inline void bnx2x_mcast_hdl_pending_restore_e2(struct bnx2x *bp,
2932
2970
cmd_pos -> data .next_bin ++ ;
2933
2971
}
2934
2972
2973
+ static void
2974
+ bnx2x_mcast_hdl_pending_set_e2_convert (struct bnx2x * bp ,
2975
+ struct bnx2x_mcast_obj * o ,
2976
+ struct bnx2x_pending_mcast_cmd * cmd_pos )
2977
+ {
2978
+ u64 cur [BNX2X_MCAST_VEC_SZ ], req [BNX2X_MCAST_VEC_SZ ];
2979
+ struct bnx2x_mcast_mac_elem * pmac_pos , * pmac_pos_n ;
2980
+ struct bnx2x_mcast_bin_elem * p_item ;
2981
+ int i , cnt = 0 , mac_cnt = 0 ;
2982
+
2983
+ memset (req , 0 , sizeof (u64 ) * BNX2X_MCAST_VEC_SZ );
2984
+ memcpy (cur , o -> registry .aprox_match .vec ,
2985
+ sizeof (u64 ) * BNX2X_MCAST_VEC_SZ );
2986
+
2987
+ /* Fill `current' with the required set of bins to configure */
2988
+ list_for_each_entry_safe (pmac_pos , pmac_pos_n , & cmd_pos -> data .macs_head ,
2989
+ link ) {
2990
+ int bin = bnx2x_mcast_bin_from_mac (pmac_pos -> mac );
2991
+
2992
+ DP (BNX2X_MSG_SP , "Set contains %pM mcast MAC\n" ,
2993
+ pmac_pos -> mac );
2994
+
2995
+ BIT_VEC64_SET_BIT (req , bin );
2996
+ list_del (& pmac_pos -> link );
2997
+ mac_cnt ++ ;
2998
+ }
2999
+
3000
+ /* We no longer have use for the MACs; Need to re-use memory for
3001
+ * a list that will be used to configure bins.
3002
+ */
3003
+ cmd_pos -> set_convert = true;
3004
+ p_item = (struct bnx2x_mcast_bin_elem * )(cmd_pos + 1 );
3005
+ INIT_LIST_HEAD (& cmd_pos -> data .macs_head );
3006
+
3007
+ for (i = 0 ; i < BNX2X_MCAST_BINS_NUM ; i ++ ) {
3008
+ bool b_current = !!BIT_VEC64_TEST_BIT (cur , i );
3009
+ bool b_required = !!BIT_VEC64_TEST_BIT (req , i );
3010
+
3011
+ if (b_current == b_required )
3012
+ continue ;
3013
+
3014
+ p_item -> bin = i ;
3015
+ p_item -> type = b_required ? BNX2X_MCAST_CMD_SET_ADD
3016
+ : BNX2X_MCAST_CMD_SET_DEL ;
3017
+ list_add_tail (& p_item -> link , & cmd_pos -> data .macs_head );
3018
+ p_item ++ ;
3019
+ cnt ++ ;
3020
+ }
3021
+
3022
+ /* We now definitely know how many commands are hiding here.
3023
+ * Also need to correct the disruption we've added to guarantee this
3024
+ * would be enqueued.
3025
+ */
3026
+ o -> total_pending_num -= (o -> max_cmd_len + mac_cnt );
3027
+ o -> total_pending_num += cnt ;
3028
+
3029
+ DP (BNX2X_MSG_SP , "o->total_pending_num=%d\n" , o -> total_pending_num );
3030
+ }
3031
+
3032
+ static void
3033
+ bnx2x_mcast_hdl_pending_set_e2 (struct bnx2x * bp ,
3034
+ struct bnx2x_mcast_obj * o ,
3035
+ struct bnx2x_pending_mcast_cmd * cmd_pos ,
3036
+ int * cnt )
3037
+ {
3038
+ union bnx2x_mcast_config_data cfg_data = {NULL };
3039
+ struct bnx2x_mcast_bin_elem * p_item , * p_item_n ;
3040
+
3041
+ /* This is actually a 2-part scheme - it starts by converting the MACs
3042
+ * into a list of bins to be added/removed, and correcting the numbers
3043
+ * on the object. this is now allowed, as we're now sure that all
3044
+ * previous configured requests have already applied.
3045
+ * The second part is actually adding rules for the newly introduced
3046
+ * entries [like all the rest of the hdl_pending functions].
3047
+ */
3048
+ if (!cmd_pos -> set_convert )
3049
+ bnx2x_mcast_hdl_pending_set_e2_convert (bp , o , cmd_pos );
3050
+
3051
+ list_for_each_entry_safe (p_item , p_item_n , & cmd_pos -> data .macs_head ,
3052
+ link ) {
3053
+ cfg_data .bin = (u8 )p_item -> bin ;
3054
+ o -> set_one_rule (bp , o , * cnt , & cfg_data , p_item -> type );
3055
+ (* cnt )++ ;
3056
+
3057
+ list_del (& p_item -> link );
3058
+
3059
+ /* Break if we reached the maximum number of rules. */
3060
+ if (* cnt >= o -> max_cmd_len )
3061
+ break ;
3062
+ }
3063
+
3064
+ /* if no more MACs to configure - we are done */
3065
+ if (list_empty (& cmd_pos -> data .macs_head ))
3066
+ cmd_pos -> done = true;
3067
+ }
3068
+
2935
3069
static inline int bnx2x_mcast_handle_pending_cmds_e2 (struct bnx2x * bp ,
2936
3070
struct bnx2x_mcast_ramrod_params * p )
2937
3071
{
@@ -2955,6 +3089,10 @@ static inline int bnx2x_mcast_handle_pending_cmds_e2(struct bnx2x *bp,
2955
3089
& cnt );
2956
3090
break ;
2957
3091
3092
+ case BNX2X_MCAST_CMD_SET :
3093
+ bnx2x_mcast_hdl_pending_set_e2 (bp , o , cmd_pos , & cnt );
3094
+ break ;
3095
+
2958
3096
default :
2959
3097
BNX2X_ERR ("Unknown command: %d\n" , cmd_pos -> type );
2960
3098
return - EINVAL ;
@@ -3095,6 +3233,19 @@ static int bnx2x_mcast_validate_e2(struct bnx2x *bp,
3095
3233
o -> set_registry_size (o , reg_sz + p -> mcast_list_len );
3096
3234
break ;
3097
3235
3236
+ case BNX2X_MCAST_CMD_SET :
3237
+ /* We can only learn how many commands would actually be used
3238
+ * when this is being configured. So for now, simply guarantee
3239
+ * the command will be enqueued [to refrain from adding logic
3240
+ * that handles this and THEN learns it needs several ramrods].
3241
+ * Just like for ADD/Cont, the mcast_list_len might be an over
3242
+ * estimation; or even more so, since we don't take into
3243
+ * account the possibility of removal of existing bins.
3244
+ */
3245
+ o -> set_registry_size (o , reg_sz + p -> mcast_list_len );
3246
+ o -> total_pending_num += o -> max_cmd_len ;
3247
+ break ;
3248
+
3098
3249
default :
3099
3250
BNX2X_ERR ("Unknown command: %d\n" , cmd );
3100
3251
return - EINVAL ;
@@ -3108,12 +3259,16 @@ static int bnx2x_mcast_validate_e2(struct bnx2x *bp,
3108
3259
3109
3260
static void bnx2x_mcast_revert_e2 (struct bnx2x * bp ,
3110
3261
struct bnx2x_mcast_ramrod_params * p ,
3111
- int old_num_bins )
3262
+ int old_num_bins ,
3263
+ enum bnx2x_mcast_cmd cmd )
3112
3264
{
3113
3265
struct bnx2x_mcast_obj * o = p -> mcast_obj ;
3114
3266
3115
3267
o -> set_registry_size (o , old_num_bins );
3116
3268
o -> total_pending_num -= p -> mcast_list_len ;
3269
+
3270
+ if (cmd == BNX2X_MCAST_CMD_SET )
3271
+ o -> total_pending_num -= o -> max_cmd_len ;
3117
3272
}
3118
3273
3119
3274
/**
@@ -3223,9 +3378,11 @@ static int bnx2x_mcast_setup_e2(struct bnx2x *bp,
3223
3378
bnx2x_mcast_refresh_registry_e2 (bp , o );
3224
3379
3225
3380
/* If CLEAR_ONLY was requested - don't send a ramrod and clear
3226
- * RAMROD_PENDING status immediately.
3381
+ * RAMROD_PENDING status immediately. due to the SET option, it's also
3382
+ * possible that after evaluating the differences there's no need for
3383
+ * a ramrod. In that case, we can skip it as well.
3227
3384
*/
3228
- if (test_bit (RAMROD_DRV_CLR_ONLY , & p -> ramrod_flags )) {
3385
+ if (test_bit (RAMROD_DRV_CLR_ONLY , & p -> ramrod_flags ) || ! cnt ) {
3229
3386
raw -> clear_pending (raw );
3230
3387
return 0 ;
3231
3388
} else {
@@ -3253,6 +3410,11 @@ static int bnx2x_mcast_validate_e1h(struct bnx2x *bp,
3253
3410
struct bnx2x_mcast_ramrod_params * p ,
3254
3411
enum bnx2x_mcast_cmd cmd )
3255
3412
{
3413
+ if (cmd == BNX2X_MCAST_CMD_SET ) {
3414
+ BNX2X_ERR ("Can't use `set' command on e1h!\n" );
3415
+ return - EINVAL ;
3416
+ }
3417
+
3256
3418
/* Mark, that there is a work to do */
3257
3419
if ((cmd == BNX2X_MCAST_CMD_DEL ) || (cmd == BNX2X_MCAST_CMD_RESTORE ))
3258
3420
p -> mcast_list_len = 1 ;
@@ -3262,7 +3424,8 @@ static int bnx2x_mcast_validate_e1h(struct bnx2x *bp,
3262
3424
3263
3425
static void bnx2x_mcast_revert_e1h (struct bnx2x * bp ,
3264
3426
struct bnx2x_mcast_ramrod_params * p ,
3265
- int old_num_bins )
3427
+ int old_num_bins ,
3428
+ enum bnx2x_mcast_cmd cmd )
3266
3429
{
3267
3430
/* Do nothing */
3268
3431
}
@@ -3372,6 +3535,11 @@ static int bnx2x_mcast_validate_e1(struct bnx2x *bp,
3372
3535
struct bnx2x_mcast_obj * o = p -> mcast_obj ;
3373
3536
int reg_sz = o -> get_registry_size (o );
3374
3537
3538
+ if (cmd == BNX2X_MCAST_CMD_SET ) {
3539
+ BNX2X_ERR ("Can't use `set' command on e1!\n" );
3540
+ return - EINVAL ;
3541
+ }
3542
+
3375
3543
switch (cmd ) {
3376
3544
/* DEL command deletes all currently configured MACs */
3377
3545
case BNX2X_MCAST_CMD_DEL :
@@ -3422,7 +3590,8 @@ static int bnx2x_mcast_validate_e1(struct bnx2x *bp,
3422
3590
3423
3591
static void bnx2x_mcast_revert_e1 (struct bnx2x * bp ,
3424
3592
struct bnx2x_mcast_ramrod_params * p ,
3425
- int old_num_macs )
3593
+ int old_num_macs ,
3594
+ enum bnx2x_mcast_cmd cmd )
3426
3595
{
3427
3596
struct bnx2x_mcast_obj * o = p -> mcast_obj ;
3428
3597
@@ -3816,7 +3985,7 @@ int bnx2x_config_mcast(struct bnx2x *bp,
3816
3985
r -> clear_pending (r );
3817
3986
3818
3987
error_exit1 :
3819
- o -> revert (bp , p , old_reg_size );
3988
+ o -> revert (bp , p , old_reg_size , cmd );
3820
3989
3821
3990
return rc ;
3822
3991
}
0 commit comments