Skip to content

Commit b4653e9

Browse files
Santwona Beheradavem330
authored andcommitted
niu: Add support for rx flow hash configuration.
Implemented ethtool callback functions for configuring receive flow hashing in the niu driver. Signed-off-by: Santwona Behera <santwona.behera@sun.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 0853ad6 commit b4653e9

File tree

1 file changed

+158
-0
lines changed

1 file changed

+158
-0
lines changed

drivers/net/niu.c

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
63886544
static 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

66206778
static int niu_ldg_assign_ldn(struct niu *np, struct niu_parent *parent,

0 commit comments

Comments
 (0)