@@ -6385,6 +6385,162 @@ static int niu_get_eeprom(struct net_device *dev,
63856385 return 0 ;
63866386}
63876387
6388+ static int niu_ethflow_to_class (int flow_type , u64 * class )
6389+ {
6390+ switch (flow_type ) {
6391+ case TCP_V4_FLOW :
6392+ * class = CLASS_CODE_TCP_IPV4 ;
6393+ break ;
6394+ case UDP_V4_FLOW :
6395+ * class = CLASS_CODE_UDP_IPV4 ;
6396+ break ;
6397+ case AH_ESP_V4_FLOW :
6398+ * class = CLASS_CODE_AH_ESP_IPV4 ;
6399+ break ;
6400+ case SCTP_V4_FLOW :
6401+ * class = CLASS_CODE_SCTP_IPV4 ;
6402+ break ;
6403+ case TCP_V6_FLOW :
6404+ * class = CLASS_CODE_TCP_IPV6 ;
6405+ break ;
6406+ case UDP_V6_FLOW :
6407+ * class = CLASS_CODE_UDP_IPV6 ;
6408+ break ;
6409+ case AH_ESP_V6_FLOW :
6410+ * class = CLASS_CODE_AH_ESP_IPV6 ;
6411+ break ;
6412+ case SCTP_V6_FLOW :
6413+ * class = CLASS_CODE_SCTP_IPV6 ;
6414+ break ;
6415+ default :
6416+ return -1 ;
6417+ }
6418+
6419+ return 1 ;
6420+ }
6421+
6422+ static u64 niu_flowkey_to_ethflow (u64 flow_key )
6423+ {
6424+ u64 ethflow = 0 ;
6425+
6426+ if (flow_key & FLOW_KEY_PORT )
6427+ ethflow |= RXH_DEV_PORT ;
6428+ if (flow_key & FLOW_KEY_L2DA )
6429+ ethflow |= RXH_L2DA ;
6430+ if (flow_key & FLOW_KEY_VLAN )
6431+ ethflow |= RXH_VLAN ;
6432+ if (flow_key & FLOW_KEY_IPSA )
6433+ ethflow |= RXH_IP_SRC ;
6434+ if (flow_key & FLOW_KEY_IPDA )
6435+ ethflow |= RXH_IP_DST ;
6436+ if (flow_key & FLOW_KEY_PROTO )
6437+ ethflow |= RXH_L3_PROTO ;
6438+ if (flow_key & (FLOW_KEY_L4_BYTE12 << FLOW_KEY_L4_0_SHIFT ))
6439+ ethflow |= RXH_L4_B_0_1 ;
6440+ if (flow_key & (FLOW_KEY_L4_BYTE12 << FLOW_KEY_L4_1_SHIFT ))
6441+ ethflow |= RXH_L4_B_2_3 ;
6442+
6443+ return ethflow ;
6444+
6445+ }
6446+
6447+ static int niu_ethflow_to_flowkey (u64 ethflow , u64 * flow_key )
6448+ {
6449+ u64 key = 0 ;
6450+
6451+ if (ethflow & RXH_DEV_PORT )
6452+ key |= FLOW_KEY_PORT ;
6453+ if (ethflow & RXH_L2DA )
6454+ key |= FLOW_KEY_L2DA ;
6455+ if (ethflow & RXH_VLAN )
6456+ key |= FLOW_KEY_VLAN ;
6457+ if (ethflow & RXH_IP_SRC )
6458+ key |= FLOW_KEY_IPSA ;
6459+ if (ethflow & RXH_IP_DST )
6460+ key |= FLOW_KEY_IPDA ;
6461+ if (ethflow & RXH_L3_PROTO )
6462+ key |= FLOW_KEY_PROTO ;
6463+ if (ethflow & RXH_L4_B_0_1 )
6464+ key |= (FLOW_KEY_L4_BYTE12 << FLOW_KEY_L4_0_SHIFT );
6465+ if (ethflow & RXH_L4_B_2_3 )
6466+ key |= (FLOW_KEY_L4_BYTE12 << FLOW_KEY_L4_1_SHIFT );
6467+
6468+ * flow_key = key ;
6469+
6470+ return 1 ;
6471+
6472+ }
6473+
6474+ static int niu_get_hash_opts (struct net_device * dev , struct ethtool_rxnfc * cmd )
6475+ {
6476+ struct niu * np = netdev_priv (dev );
6477+ u64 class ;
6478+
6479+ cmd -> data = 0 ;
6480+
6481+ if (!niu_ethflow_to_class (cmd -> flow_type , & class ))
6482+ return - EINVAL ;
6483+
6484+ if (np -> parent -> tcam_key [class - CLASS_CODE_USER_PROG1 ] &
6485+ TCAM_KEY_DISC )
6486+ cmd -> data = RXH_DISCARD ;
6487+ else
6488+
6489+ cmd -> data = niu_flowkey_to_ethflow (np -> parent -> flow_key [class -
6490+ CLASS_CODE_USER_PROG1 ]);
6491+ return 0 ;
6492+ }
6493+
6494+ static int niu_set_hash_opts (struct net_device * dev , struct ethtool_rxnfc * cmd )
6495+ {
6496+ struct niu * np = netdev_priv (dev );
6497+ u64 class ;
6498+ u64 flow_key = 0 ;
6499+ unsigned long flags ;
6500+
6501+ if (!niu_ethflow_to_class (cmd -> flow_type , & class ))
6502+ return - EINVAL ;
6503+
6504+ if (class < CLASS_CODE_USER_PROG1 ||
6505+ class > CLASS_CODE_SCTP_IPV6 )
6506+ return - EINVAL ;
6507+
6508+ if (cmd -> data & RXH_DISCARD ) {
6509+ niu_lock_parent (np , flags );
6510+ flow_key = np -> parent -> tcam_key [class -
6511+ CLASS_CODE_USER_PROG1 ];
6512+ flow_key |= TCAM_KEY_DISC ;
6513+ nw64 (TCAM_KEY (class - CLASS_CODE_USER_PROG1 ), flow_key );
6514+ np -> parent -> tcam_key [class - CLASS_CODE_USER_PROG1 ] = flow_key ;
6515+ niu_unlock_parent (np , flags );
6516+ return 0 ;
6517+ } else {
6518+ /* Discard was set before, but is not set now */
6519+ if (np -> parent -> tcam_key [class - CLASS_CODE_USER_PROG1 ] &
6520+ TCAM_KEY_DISC ) {
6521+ niu_lock_parent (np , flags );
6522+ flow_key = np -> parent -> tcam_key [class -
6523+ CLASS_CODE_USER_PROG1 ];
6524+ flow_key &= ~TCAM_KEY_DISC ;
6525+ nw64 (TCAM_KEY (class - CLASS_CODE_USER_PROG1 ),
6526+ flow_key );
6527+ np -> parent -> tcam_key [class - CLASS_CODE_USER_PROG1 ] =
6528+ flow_key ;
6529+ niu_unlock_parent (np , flags );
6530+ }
6531+ }
6532+
6533+ if (!niu_ethflow_to_flowkey (cmd -> data , & flow_key ))
6534+ return - EINVAL ;
6535+
6536+ niu_lock_parent (np , flags );
6537+ nw64 (FLOW_KEY (class - CLASS_CODE_USER_PROG1 ), flow_key );
6538+ np -> parent -> flow_key [class - CLASS_CODE_USER_PROG1 ] = flow_key ;
6539+ niu_unlock_parent (np , flags );
6540+
6541+ return 0 ;
6542+ }
6543+
63886544static const struct {
63896545 const char string [ETH_GSTRING_LEN ];
63906546} niu_xmac_stat_keys [] = {
@@ -6615,6 +6771,8 @@ static const struct ethtool_ops niu_ethtool_ops = {
66156771 .get_stats_count = niu_get_stats_count ,
66166772 .get_ethtool_stats = niu_get_ethtool_stats ,
66176773 .phys_id = niu_phys_id ,
6774+ .get_rxhash = niu_get_hash_opts ,
6775+ .set_rxhash = niu_set_hash_opts ,
66186776};
66196777
66206778static int niu_ldg_assign_ldn (struct niu * np , struct niu_parent * parent ,
0 commit comments