diff options
author | Suresh Reddy <suresh.reddy@emulex.com> | 2013-04-25 19:03:20 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-04-26 23:24:11 -0400 |
commit | 594ad54a2c3b215f6fc8873518d59d802f88c10b (patch) | |
tree | 2bfed982f365e8324d37dcbbaa9f09a1e8bff66d | |
parent | 37fe0660981d7a1577409226f77554c2c5123e27 (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.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_cmds.c | 13 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_cmds.h | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_ethtool.c | 155 | ||||
-rw-r--r-- | drivers/net/ethernet/emulex/benet/be_main.c | 14 |
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 | ||
1901 | int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, u16 table_size) | 1901 | int 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 | |||
1093 | struct be_cmd_req_rss_config { | 1096 | struct 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); |
1861 | extern int be_cmd_reset_function(struct be_adapter *adapter); | 1864 | extern int be_cmd_reset_function(struct be_adapter *adapter); |
1862 | extern int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, | 1865 | extern int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, |
1863 | u16 table_size); | 1866 | u32 rss_hash_opts, u16 table_size); |
1864 | extern int be_process_mcc(struct be_adapter *adapter); | 1867 | extern int be_process_mcc(struct be_adapter *adapter); |
1865 | extern int be_cmd_set_beacon_state(struct be_adapter *adapter, | 1868 | extern 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 | ||
937 | static 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 | |||
971 | static 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 | |||
996 | static 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 | |||
1068 | static 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 | |||
937 | const struct ethtool_ops be_ethtool_ops = { | 1090 | const 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 */ |