@@ -441,17 +441,22 @@ static int bcm_sf2_cfp_ipv4_rule_set(struct bcm_sf2_priv *priv, int port,
441
441
442
442
static void bcm_sf2_cfp_slice_ipv6 (struct bcm_sf2_priv * priv ,
443
443
const __be32 * ip6_addr , const __be16 port ,
444
- unsigned int slice_num )
444
+ unsigned int slice_num ,
445
+ bool mask )
445
446
{
446
- u32 reg , tmp , val ;
447
+ u32 reg , tmp , val , offset ;
447
448
448
449
/* C-Tag [31:24]
449
450
* UDF_n_B8 [23:8] (port)
450
451
* UDF_n_B7 (upper) [7:0] (addr[15:8])
451
452
*/
452
453
reg = be32_to_cpu (ip6_addr [3 ]);
453
454
val = (u32 )be16_to_cpu (port ) << 8 | ((reg >> 8 ) & 0xff );
454
- core_writel (priv , val , CORE_CFP_DATA_PORT (4 ));
455
+ if (mask )
456
+ offset = CORE_CFP_MASK_PORT (4 );
457
+ else
458
+ offset = CORE_CFP_DATA_PORT (4 );
459
+ core_writel (priv , val , offset );
455
460
456
461
/* UDF_n_B7 (lower) [31:24] (addr[7:0])
457
462
* UDF_n_B6 [23:8] (addr[31:16])
@@ -460,7 +465,11 @@ static void bcm_sf2_cfp_slice_ipv6(struct bcm_sf2_priv *priv,
460
465
tmp = be32_to_cpu (ip6_addr [2 ]);
461
466
val = (u32 )(reg & 0xff ) << 24 | (u32 )(reg >> 16 ) << 8 |
462
467
((tmp >> 8 ) & 0xff );
463
- core_writel (priv , val , CORE_CFP_DATA_PORT (3 ));
468
+ if (mask )
469
+ offset = CORE_CFP_MASK_PORT (3 );
470
+ else
471
+ offset = CORE_CFP_DATA_PORT (3 );
472
+ core_writel (priv , val , offset );
464
473
465
474
/* UDF_n_B5 (lower) [31:24] (addr[39:32])
466
475
* UDF_n_B4 [23:8] (addr[63:48])
@@ -469,7 +478,11 @@ static void bcm_sf2_cfp_slice_ipv6(struct bcm_sf2_priv *priv,
469
478
reg = be32_to_cpu (ip6_addr [1 ]);
470
479
val = (u32 )(tmp & 0xff ) << 24 | (u32 )(tmp >> 16 ) << 8 |
471
480
((reg >> 8 ) & 0xff );
472
- core_writel (priv , val , CORE_CFP_DATA_PORT (2 ));
481
+ if (mask )
482
+ offset = CORE_CFP_MASK_PORT (2 );
483
+ else
484
+ offset = CORE_CFP_DATA_PORT (2 );
485
+ core_writel (priv , val , offset );
473
486
474
487
/* UDF_n_B3 (lower) [31:24] (addr[71:64])
475
488
* UDF_n_B2 [23:8] (addr[95:80])
@@ -478,7 +491,11 @@ static void bcm_sf2_cfp_slice_ipv6(struct bcm_sf2_priv *priv,
478
491
tmp = be32_to_cpu (ip6_addr [0 ]);
479
492
val = (u32 )(reg & 0xff ) << 24 | (u32 )(reg >> 16 ) << 8 |
480
493
((tmp >> 8 ) & 0xff );
481
- core_writel (priv , val , CORE_CFP_DATA_PORT (1 ));
494
+ if (mask )
495
+ offset = CORE_CFP_MASK_PORT (1 );
496
+ else
497
+ offset = CORE_CFP_DATA_PORT (1 );
498
+ core_writel (priv , val , offset );
482
499
483
500
/* UDF_n_B1 (lower) [31:24] (addr[103:96])
484
501
* UDF_n_B0 [23:8] (addr[127:112])
@@ -488,23 +505,20 @@ static void bcm_sf2_cfp_slice_ipv6(struct bcm_sf2_priv *priv,
488
505
*/
489
506
reg = (u32 )(tmp & 0xff ) << 24 | (u32 )(tmp >> 16 ) << 8 |
490
507
SLICE_NUM (slice_num ) | SLICE_VALID ;
491
- core_writel (priv , reg , CORE_CFP_DATA_PORT (0 ));
492
-
493
- /* All other UDFs should be matched with the filter */
494
- core_writel (priv , 0x00ffffff , CORE_CFP_MASK_PORT (4 ));
495
- core_writel (priv , 0xffffffff , CORE_CFP_MASK_PORT (3 ));
496
- core_writel (priv , 0xffffffff , CORE_CFP_MASK_PORT (2 ));
497
- core_writel (priv , 0xffffffff , CORE_CFP_MASK_PORT (1 ));
498
- core_writel (priv , 0xffffff0f , CORE_CFP_MASK_PORT (0 ));
508
+ if (mask )
509
+ offset = CORE_CFP_MASK_PORT (0 );
510
+ else
511
+ offset = CORE_CFP_DATA_PORT (0 );
512
+ core_writel (priv , reg , offset );
499
513
}
500
514
501
515
static int bcm_sf2_cfp_ipv6_rule_set (struct bcm_sf2_priv * priv , int port ,
502
516
unsigned int port_num ,
503
517
unsigned int queue_num ,
504
518
struct ethtool_rx_flow_spec * fs )
505
519
{
520
+ struct ethtool_tcpip6_spec * v6_spec , * v6_m_spec ;
506
521
unsigned int slice_num , rule_index [2 ];
507
- struct ethtool_tcpip6_spec * v6_spec ;
508
522
const struct cfp_udf_layout * layout ;
509
523
u8 ip_proto , ip_frag ;
510
524
int ret = 0 ;
@@ -515,10 +529,12 @@ static int bcm_sf2_cfp_ipv6_rule_set(struct bcm_sf2_priv *priv, int port,
515
529
case TCP_V6_FLOW :
516
530
ip_proto = IPPROTO_TCP ;
517
531
v6_spec = & fs -> h_u .tcp_ip6_spec ;
532
+ v6_m_spec = & fs -> m_u .tcp_ip6_spec ;
518
533
break ;
519
534
case UDP_V6_FLOW :
520
535
ip_proto = IPPROTO_UDP ;
521
536
v6_spec = & fs -> h_u .udp_ip6_spec ;
537
+ v6_m_spec = & fs -> m_u .udp_ip6_spec ;
522
538
break ;
523
539
default :
524
540
return - EINVAL ;
@@ -606,7 +622,10 @@ static int bcm_sf2_cfp_ipv6_rule_set(struct bcm_sf2_priv *priv, int port,
606
622
core_writel (priv , udf_lower_bits (num_udf ) << 24 , CORE_CFP_MASK_PORT (5 ));
607
623
608
624
/* Slice the IPv6 source address and port */
609
- bcm_sf2_cfp_slice_ipv6 (priv , v6_spec -> ip6src , v6_spec -> psrc , slice_num );
625
+ bcm_sf2_cfp_slice_ipv6 (priv , v6_spec -> ip6src , v6_spec -> psrc ,
626
+ slice_num , false);
627
+ bcm_sf2_cfp_slice_ipv6 (priv , v6_m_spec -> ip6src , v6_m_spec -> psrc ,
628
+ slice_num , true);
610
629
611
630
/* Insert into TCAM now because we need to insert a second rule */
612
631
bcm_sf2_cfp_rule_addr_set (priv , rule_index [0 ]);
@@ -663,7 +682,10 @@ static int bcm_sf2_cfp_ipv6_rule_set(struct bcm_sf2_priv *priv, int port,
663
682
/* Mask all */
664
683
core_writel (priv , 0 , CORE_CFP_MASK_PORT (5 ));
665
684
666
- bcm_sf2_cfp_slice_ipv6 (priv , v6_spec -> ip6dst , v6_spec -> pdst , slice_num );
685
+ bcm_sf2_cfp_slice_ipv6 (priv , v6_spec -> ip6dst , v6_spec -> pdst , slice_num ,
686
+ false);
687
+ bcm_sf2_cfp_slice_ipv6 (priv , v6_m_spec -> ip6dst , v6_m_spec -> pdst ,
688
+ SLICE_NUM_MASK , true);
667
689
668
690
/* Insert into TCAM now */
669
691
bcm_sf2_cfp_rule_addr_set (priv , rule_index [1 ]);
@@ -932,49 +954,61 @@ static int bcm_sf2_cfp_ipv4_rule_get(struct bcm_sf2_priv *priv, int port,
932
954
933
955
static int bcm_sf2_cfp_unslice_ipv6 (struct bcm_sf2_priv * priv ,
934
956
__be32 * ip6_addr , __be16 * port ,
935
- __be32 * ip6_mask , __be16 * port_mask )
957
+ bool mask )
936
958
{
937
- u32 reg , tmp ;
959
+ u32 reg , tmp , offset ;
938
960
939
961
/* C-Tag [31:24]
940
962
* UDF_n_B8 [23:8] (port)
941
963
* UDF_n_B7 (upper) [7:0] (addr[15:8])
942
964
*/
943
- reg = core_readl (priv , CORE_CFP_DATA_PORT (4 ));
965
+ if (mask )
966
+ offset = CORE_CFP_MASK_PORT (4 );
967
+ else
968
+ offset = CORE_CFP_DATA_PORT (4 );
969
+ reg = core_readl (priv , offset );
944
970
* port = cpu_to_be32 (reg ) >> 8 ;
945
- * port_mask = cpu_to_be16 (~0 );
946
971
tmp = (u32 )(reg & 0xff ) << 8 ;
947
972
948
973
/* UDF_n_B7 (lower) [31:24] (addr[7:0])
949
974
* UDF_n_B6 [23:8] (addr[31:16])
950
975
* UDF_n_B5 (upper) [7:0] (addr[47:40])
951
976
*/
952
- reg = core_readl (priv , CORE_CFP_DATA_PORT (3 ));
977
+ if (mask )
978
+ offset = CORE_CFP_MASK_PORT (3 );
979
+ else
980
+ offset = CORE_CFP_DATA_PORT (3 );
981
+ reg = core_readl (priv , offset );
953
982
tmp |= (reg >> 24 ) & 0xff ;
954
983
tmp |= (u32 )((reg >> 8 ) << 16 );
955
- ip6_mask [3 ] = cpu_to_be32 (~0 );
956
984
ip6_addr [3 ] = cpu_to_be32 (tmp );
957
985
tmp = (u32 )(reg & 0xff ) << 8 ;
958
986
959
987
/* UDF_n_B5 (lower) [31:24] (addr[39:32])
960
988
* UDF_n_B4 [23:8] (addr[63:48])
961
989
* UDF_n_B3 (upper) [7:0] (addr[79:72])
962
990
*/
963
- reg = core_readl (priv , CORE_CFP_DATA_PORT (2 ));
991
+ if (mask )
992
+ offset = CORE_CFP_MASK_PORT (2 );
993
+ else
994
+ offset = CORE_CFP_DATA_PORT (2 );
995
+ reg = core_readl (priv , offset );
964
996
tmp |= (reg >> 24 ) & 0xff ;
965
997
tmp |= (u32 )((reg >> 8 ) << 16 );
966
- ip6_mask [2 ] = cpu_to_be32 (~0 );
967
998
ip6_addr [2 ] = cpu_to_be32 (tmp );
968
999
tmp = (u32 )(reg & 0xff ) << 8 ;
969
1000
970
1001
/* UDF_n_B3 (lower) [31:24] (addr[71:64])
971
1002
* UDF_n_B2 [23:8] (addr[95:80])
972
1003
* UDF_n_B1 (upper) [7:0] (addr[111:104])
973
1004
*/
974
- reg = core_readl (priv , CORE_CFP_DATA_PORT (1 ));
1005
+ if (mask )
1006
+ offset = CORE_CFP_MASK_PORT (1 );
1007
+ else
1008
+ offset = CORE_CFP_DATA_PORT (1 );
1009
+ reg = core_readl (priv , offset );
975
1010
tmp |= (reg >> 24 ) & 0xff ;
976
1011
tmp |= (u32 )((reg >> 8 ) << 16 );
977
- ip6_mask [1 ] = cpu_to_be32 (~0 );
978
1012
ip6_addr [1 ] = cpu_to_be32 (tmp );
979
1013
tmp = (u32 )(reg & 0xff ) << 8 ;
980
1014
@@ -984,13 +1018,16 @@ static int bcm_sf2_cfp_unslice_ipv6(struct bcm_sf2_priv *priv,
984
1018
* Slice ID [3:2]
985
1019
* Slice valid [1:0]
986
1020
*/
987
- reg = core_readl (priv , CORE_CFP_DATA_PORT (0 ));
1021
+ if (mask )
1022
+ offset = CORE_CFP_MASK_PORT (0 );
1023
+ else
1024
+ offset = CORE_CFP_DATA_PORT (0 );
1025
+ reg = core_readl (priv , offset );
988
1026
tmp |= (reg >> 24 ) & 0xff ;
989
1027
tmp |= (u32 )((reg >> 8 ) << 16 );
990
- ip6_mask [0 ] = cpu_to_be32 (~0 );
991
1028
ip6_addr [0 ] = cpu_to_be32 (tmp );
992
1029
993
- if (!(reg & SLICE_VALID ))
1030
+ if (!mask && ! (reg & SLICE_VALID ))
994
1031
return - EINVAL ;
995
1032
996
1033
return 0 ;
@@ -1012,7 +1049,12 @@ static int bcm_sf2_cfp_ipv6_rule_get(struct bcm_sf2_priv *priv, int port,
1012
1049
1013
1050
/* Read the second half first */
1014
1051
ret = bcm_sf2_cfp_unslice_ipv6 (priv , v6_spec -> ip6dst , & v6_spec -> pdst ,
1015
- v6_m_spec -> ip6dst , & v6_m_spec -> pdst );
1052
+ false);
1053
+ if (ret )
1054
+ return ret ;
1055
+
1056
+ ret = bcm_sf2_cfp_unslice_ipv6 (priv , v6_m_spec -> ip6dst ,
1057
+ & v6_m_spec -> pdst , true);
1016
1058
if (ret )
1017
1059
return ret ;
1018
1060
@@ -1043,8 +1085,13 @@ static int bcm_sf2_cfp_ipv6_rule_get(struct bcm_sf2_priv *priv, int port,
1043
1085
return - EINVAL ;
1044
1086
}
1045
1087
1046
- return bcm_sf2_cfp_unslice_ipv6 (priv , v6_spec -> ip6src , & v6_spec -> psrc ,
1047
- v6_m_spec -> ip6src , & v6_m_spec -> psrc );
1088
+ ret = bcm_sf2_cfp_unslice_ipv6 (priv , v6_spec -> ip6src , & v6_spec -> psrc ,
1089
+ false);
1090
+ if (ret )
1091
+ return ret ;
1092
+
1093
+ return bcm_sf2_cfp_unslice_ipv6 (priv , v6_m_spec -> ip6src ,
1094
+ & v6_m_spec -> psrc , true);
1048
1095
}
1049
1096
1050
1097
static int bcm_sf2_cfp_rule_get (struct bcm_sf2_priv * priv , int port ,
0 commit comments