aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuresh Reddy <suresh.reddy@emulex.com>2013-04-25 19:03:20 -0400
committerDavid S. Miller <davem@davemloft.net>2013-04-26 23:24:11 -0400
commit594ad54a2c3b215f6fc8873518d59d802f88c10b (patch)
tree2bfed982f365e8324d37dcbbaa9f09a1e8bff66d
parent37fe0660981d7a1577409226f77554c2c5123e27 (diff)
be2net: Add support for setting and getting rx flow hash options
Signed-off-by: Suresh Reddy <suresh.reddy@emulex.com> Signed-off-by: Sarveshwar Bandi <sarveshwar.bandi@emulex.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/emulex/benet/be.h1
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.c13
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.h5
-rw-r--r--drivers/net/ethernet/emulex/benet/be_ethtool.c155
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c14
5 files changed, 177 insertions, 11 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index e2d5ced7e733..4b62e7f1143c 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -447,6 +447,7 @@ struct be_adapter {
447 u16 max_event_queues; 447 u16 max_event_queues;
448 u32 if_cap_flags; 448 u32 if_cap_flags;
449 u8 pf_number; 449 u8 pf_number;
450 u64 rss_flags;
450}; 451};
451 452
452#define be_physfn(adapter) (!adapter->virtfn) 453#define be_physfn(adapter) (!adapter->virtfn)
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index d6291aba2524..d837e4c7ae8b 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -1898,7 +1898,8 @@ int be_cmd_reset_function(struct be_adapter *adapter)
1898 return status; 1898 return status;
1899} 1899}
1900 1900
1901int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, u16 table_size) 1901int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable,
1902 u32 rss_hash_opts, u16 table_size)
1902{ 1903{
1903 struct be_mcc_wrb *wrb; 1904 struct be_mcc_wrb *wrb;
1904 struct be_cmd_req_rss_config *req; 1905 struct be_cmd_req_rss_config *req;
@@ -1917,16 +1918,12 @@ int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, u16 table_size)
1917 OPCODE_ETH_RSS_CONFIG, sizeof(*req), wrb, NULL); 1918 OPCODE_ETH_RSS_CONFIG, sizeof(*req), wrb, NULL);
1918 1919
1919 req->if_id = cpu_to_le32(adapter->if_handle); 1920 req->if_id = cpu_to_le32(adapter->if_handle);
1920 req->enable_rss = cpu_to_le16(RSS_ENABLE_TCP_IPV4 | RSS_ENABLE_IPV4 | 1921 req->enable_rss = cpu_to_le16(rss_hash_opts);
1921 RSS_ENABLE_TCP_IPV6 | RSS_ENABLE_IPV6); 1922 req->cpu_table_size_log2 = cpu_to_le16(fls(table_size) - 1);
1922 1923
1923 if (lancer_chip(adapter) || skyhawk_chip(adapter)) { 1924 if (lancer_chip(adapter) || skyhawk_chip(adapter))
1924 req->hdr.version = 1; 1925 req->hdr.version = 1;
1925 req->enable_rss |= cpu_to_le16(RSS_ENABLE_UDP_IPV4 |
1926 RSS_ENABLE_UDP_IPV6);
1927 }
1928 1926
1929 req->cpu_table_size_log2 = cpu_to_le16(fls(table_size) - 1);
1930 memcpy(req->cpu_table, rsstable, table_size); 1927 memcpy(req->cpu_table, rsstable, table_size);
1931 memcpy(req->hash, myhash, sizeof(myhash)); 1928 memcpy(req->hash, myhash, sizeof(myhash));
1932 be_dws_cpu_to_le(req->hash, sizeof(req->hash)); 1929 be_dws_cpu_to_le(req->hash, sizeof(req->hash));
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
index 460332021590..4d03789119ab 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
@@ -1090,6 +1090,9 @@ struct be_cmd_resp_query_fw_cfg {
1090#define RSS_ENABLE_UDP_IPV4 0x10 1090#define RSS_ENABLE_UDP_IPV4 0x10
1091#define RSS_ENABLE_UDP_IPV6 0x20 1091#define RSS_ENABLE_UDP_IPV6 0x20
1092 1092
1093#define L3_RSS_FLAGS (RXH_IP_DST | RXH_IP_SRC)
1094#define L4_RSS_FLAGS (RXH_L4_B_0_1 | RXH_L4_B_2_3)
1095
1093struct be_cmd_req_rss_config { 1096struct be_cmd_req_rss_config {
1094 struct be_cmd_req_hdr hdr; 1097 struct be_cmd_req_hdr hdr;
1095 u32 if_id; 1098 u32 if_id;
@@ -1860,7 +1863,7 @@ extern int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num,
1860 u32 *function_mode, u32 *function_caps, u16 *asic_rev); 1863 u32 *function_mode, u32 *function_caps, u16 *asic_rev);
1861extern int be_cmd_reset_function(struct be_adapter *adapter); 1864extern int be_cmd_reset_function(struct be_adapter *adapter);
1862extern int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, 1865extern int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable,
1863 u16 table_size); 1866 u32 rss_hash_opts, u16 table_size);
1864extern int be_process_mcc(struct be_adapter *adapter); 1867extern int be_process_mcc(struct be_adapter *adapter);
1865extern int be_cmd_set_beacon_state(struct be_adapter *adapter, 1868extern int be_cmd_set_beacon_state(struct be_adapter *adapter,
1866 u8 port_num, u8 beacon, u8 status, u8 state); 1869 u8 port_num, u8 beacon, u8 status, u8 state);
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
index 07b7f27cb0b9..ac05bbeef9f4 100644
--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
+++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
@@ -934,6 +934,159 @@ static void be_set_msg_level(struct net_device *netdev, u32 level)
934 return; 934 return;
935} 935}
936 936
937static u64 be_get_rss_hash_opts(struct be_adapter *adapter, u64 flow_type)
938{
939 u64 data = 0;
940
941 switch (flow_type) {
942 case TCP_V4_FLOW:
943 if (adapter->rss_flags & RSS_ENABLE_IPV4)
944 data |= RXH_IP_DST | RXH_IP_SRC;
945 if (adapter->rss_flags & RSS_ENABLE_TCP_IPV4)
946 data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
947 break;
948 case UDP_V4_FLOW:
949 if (adapter->rss_flags & RSS_ENABLE_IPV4)
950 data |= RXH_IP_DST | RXH_IP_SRC;
951 if (adapter->rss_flags & RSS_ENABLE_UDP_IPV4)
952 data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
953 break;
954 case TCP_V6_FLOW:
955 if (adapter->rss_flags & RSS_ENABLE_IPV6)
956 data |= RXH_IP_DST | RXH_IP_SRC;
957 if (adapter->rss_flags & RSS_ENABLE_TCP_IPV6)
958 data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
959 break;
960 case UDP_V6_FLOW:
961 if (adapter->rss_flags & RSS_ENABLE_IPV6)
962 data |= RXH_IP_DST | RXH_IP_SRC;
963 if (adapter->rss_flags & RSS_ENABLE_UDP_IPV6)
964 data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
965 break;
966 }
967
968 return data;
969}
970
971static int be_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd,
972 u32 *rule_locs)
973{
974 struct be_adapter *adapter = netdev_priv(netdev);
975
976 if (!be_multi_rxq(adapter)) {
977 dev_info(&adapter->pdev->dev,
978 "ethtool::get_rxnfc: RX flow hashing is disabled\n");
979 return -EINVAL;
980 }
981
982 switch (cmd->cmd) {
983 case ETHTOOL_GRXFH:
984 cmd->data = be_get_rss_hash_opts(adapter, cmd->flow_type);
985 break;
986 case ETHTOOL_GRXRINGS:
987 cmd->data = adapter->num_rx_qs - 1;
988 break;
989 default:
990 return -EINVAL;
991 }
992
993 return 0;
994}
995
996static int be_set_rss_hash_opts(struct be_adapter *adapter,
997 struct ethtool_rxnfc *cmd)
998{
999 struct be_rx_obj *rxo;
1000 int status = 0, i, j;
1001 u8 rsstable[128];
1002 u32 rss_flags = adapter->rss_flags;
1003
1004 if (cmd->data != L3_RSS_FLAGS &&
1005 cmd->data != (L3_RSS_FLAGS | L4_RSS_FLAGS))
1006 return -EINVAL;
1007
1008 switch (cmd->flow_type) {
1009 case TCP_V4_FLOW:
1010 if (cmd->data == L3_RSS_FLAGS)
1011 rss_flags &= ~RSS_ENABLE_TCP_IPV4;
1012 else if (cmd->data == (L3_RSS_FLAGS | L4_RSS_FLAGS))
1013 rss_flags |= RSS_ENABLE_IPV4 |
1014 RSS_ENABLE_TCP_IPV4;
1015 break;
1016 case TCP_V6_FLOW:
1017 if (cmd->data == L3_RSS_FLAGS)
1018 rss_flags &= ~RSS_ENABLE_TCP_IPV6;
1019 else if (cmd->data == (L3_RSS_FLAGS | L4_RSS_FLAGS))
1020 rss_flags |= RSS_ENABLE_IPV6 |
1021 RSS_ENABLE_TCP_IPV6;
1022 break;
1023 case UDP_V4_FLOW:
1024 if ((cmd->data == (L3_RSS_FLAGS | L4_RSS_FLAGS)) &&
1025 BEx_chip(adapter))
1026 return -EINVAL;
1027
1028 if (cmd->data == L3_RSS_FLAGS)
1029 rss_flags &= ~RSS_ENABLE_UDP_IPV4;
1030 else if (cmd->data == (L3_RSS_FLAGS | L4_RSS_FLAGS))
1031 rss_flags |= RSS_ENABLE_IPV4 |
1032 RSS_ENABLE_UDP_IPV4;
1033 break;
1034 case UDP_V6_FLOW:
1035 if ((cmd->data == (L3_RSS_FLAGS | L4_RSS_FLAGS)) &&
1036 BEx_chip(adapter))
1037 return -EINVAL;
1038
1039 if (cmd->data == L3_RSS_FLAGS)
1040 rss_flags &= ~RSS_ENABLE_UDP_IPV6;
1041 else if (cmd->data == (L3_RSS_FLAGS | L4_RSS_FLAGS))
1042 rss_flags |= RSS_ENABLE_IPV6 |
1043 RSS_ENABLE_UDP_IPV6;
1044 break;
1045 default:
1046 return -EINVAL;
1047 }
1048
1049 if (rss_flags == adapter->rss_flags)
1050 return status;
1051
1052 if (be_multi_rxq(adapter)) {
1053 for (j = 0; j < 128; j += adapter->num_rx_qs - 1) {
1054 for_all_rss_queues(adapter, rxo, i) {
1055 if ((j + i) >= 128)
1056 break;
1057 rsstable[j + i] = rxo->rss_id;
1058 }
1059 }
1060 }
1061 status = be_cmd_rss_config(adapter, rsstable, rss_flags, 128);
1062 if (!status)
1063 adapter->rss_flags = rss_flags;
1064
1065 return status;
1066}
1067
1068static int be_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd)
1069{
1070 struct be_adapter *adapter = netdev_priv(netdev);
1071 int status = 0;
1072
1073 if (!be_multi_rxq(adapter)) {
1074 dev_err(&adapter->pdev->dev,
1075 "ethtool::set_rxnfc: RX flow hashing is disabled\n");
1076 return -EINVAL;
1077 }
1078
1079 switch (cmd->cmd) {
1080 case ETHTOOL_SRXFH:
1081 status = be_set_rss_hash_opts(adapter, cmd);
1082 break;
1083 default:
1084 return -EINVAL;
1085 }
1086
1087 return status;
1088}
1089
937const struct ethtool_ops be_ethtool_ops = { 1090const struct ethtool_ops be_ethtool_ops = {
938 .get_settings = be_get_settings, 1091 .get_settings = be_get_settings,
939 .get_drvinfo = be_get_drvinfo, 1092 .get_drvinfo = be_get_drvinfo,
@@ -957,4 +1110,6 @@ const struct ethtool_ops be_ethtool_ops = {
957 .get_regs = be_get_regs, 1110 .get_regs = be_get_regs,
958 .flash_device = be_do_flash, 1111 .flash_device = be_do_flash,
959 .self_test = be_self_test, 1112 .self_test = be_self_test,
1113 .get_rxnfc = be_get_rxnfc,
1114 .set_rxnfc = be_set_rxnfc,
960}; 1115};
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 654e7820daa0..a8926eb48b6d 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -2510,9 +2510,19 @@ static int be_rx_qs_create(struct be_adapter *adapter)
2510 rsstable[j + i] = rxo->rss_id; 2510 rsstable[j + i] = rxo->rss_id;
2511 } 2511 }
2512 } 2512 }
2513 rc = be_cmd_rss_config(adapter, rsstable, 128); 2513 adapter->rss_flags = RSS_ENABLE_TCP_IPV4 | RSS_ENABLE_IPV4 |
2514 if (rc) 2514 RSS_ENABLE_TCP_IPV6 | RSS_ENABLE_IPV6;
2515
2516 if (!BEx_chip(adapter))
2517 adapter->rss_flags |= RSS_ENABLE_UDP_IPV4 |
2518 RSS_ENABLE_UDP_IPV6;
2519
2520 rc = be_cmd_rss_config(adapter, rsstable, adapter->rss_flags,
2521 128);
2522 if (rc) {
2523 adapter->rss_flags = 0;
2515 return rc; 2524 return rc;
2525 }
2516 } 2526 }
2517 2527
2518 /* First time posting */ 2528 /* First time posting */