Loading...
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (c) 2021, Intel Corporation. */
3
4/* advanced RSS configuration ethtool support for iavf */
5
6#include "iavf.h"
7
8/**
9 * iavf_fill_adv_rss_ip4_hdr - fill the IPv4 RSS protocol header
10 * @hdr: the virtchnl message protocol header data structure
11 * @hash_flds: the RSS configuration protocol hash fields
12 */
13static void
14iavf_fill_adv_rss_ip4_hdr(struct virtchnl_proto_hdr *hdr, u64 hash_flds)
15{
16 VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, IPV4);
17
18 if (hash_flds & IAVF_ADV_RSS_HASH_FLD_IPV4_SA)
19 VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV4, SRC);
20
21 if (hash_flds & IAVF_ADV_RSS_HASH_FLD_IPV4_DA)
22 VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV4, DST);
23}
24
25/**
26 * iavf_fill_adv_rss_ip6_hdr - fill the IPv6 RSS protocol header
27 * @hdr: the virtchnl message protocol header data structure
28 * @hash_flds: the RSS configuration protocol hash fields
29 */
30static void
31iavf_fill_adv_rss_ip6_hdr(struct virtchnl_proto_hdr *hdr, u64 hash_flds)
32{
33 VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, IPV6);
34
35 if (hash_flds & IAVF_ADV_RSS_HASH_FLD_IPV6_SA)
36 VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV6, SRC);
37
38 if (hash_flds & IAVF_ADV_RSS_HASH_FLD_IPV6_DA)
39 VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV6, DST);
40}
41
42/**
43 * iavf_fill_adv_rss_tcp_hdr - fill the TCP RSS protocol header
44 * @hdr: the virtchnl message protocol header data structure
45 * @hash_flds: the RSS configuration protocol hash fields
46 */
47static void
48iavf_fill_adv_rss_tcp_hdr(struct virtchnl_proto_hdr *hdr, u64 hash_flds)
49{
50 VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, TCP);
51
52 if (hash_flds & IAVF_ADV_RSS_HASH_FLD_TCP_SRC_PORT)
53 VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, TCP, SRC_PORT);
54
55 if (hash_flds & IAVF_ADV_RSS_HASH_FLD_TCP_DST_PORT)
56 VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, TCP, DST_PORT);
57}
58
59/**
60 * iavf_fill_adv_rss_udp_hdr - fill the UDP RSS protocol header
61 * @hdr: the virtchnl message protocol header data structure
62 * @hash_flds: the RSS configuration protocol hash fields
63 */
64static void
65iavf_fill_adv_rss_udp_hdr(struct virtchnl_proto_hdr *hdr, u64 hash_flds)
66{
67 VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, UDP);
68
69 if (hash_flds & IAVF_ADV_RSS_HASH_FLD_UDP_SRC_PORT)
70 VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, UDP, SRC_PORT);
71
72 if (hash_flds & IAVF_ADV_RSS_HASH_FLD_UDP_DST_PORT)
73 VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, UDP, DST_PORT);
74}
75
76/**
77 * iavf_fill_adv_rss_sctp_hdr - fill the SCTP RSS protocol header
78 * @hdr: the virtchnl message protocol header data structure
79 * @hash_flds: the RSS configuration protocol hash fields
80 */
81static void
82iavf_fill_adv_rss_sctp_hdr(struct virtchnl_proto_hdr *hdr, u64 hash_flds)
83{
84 VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, SCTP);
85
86 if (hash_flds & IAVF_ADV_RSS_HASH_FLD_SCTP_SRC_PORT)
87 VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, SCTP, SRC_PORT);
88
89 if (hash_flds & IAVF_ADV_RSS_HASH_FLD_SCTP_DST_PORT)
90 VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, SCTP, DST_PORT);
91}
92
93/**
94 * iavf_fill_adv_rss_cfg_msg - fill the RSS configuration into virtchnl message
95 * @rss_cfg: the virtchnl message to be filled with RSS configuration setting
96 * @packet_hdrs: the RSS configuration protocol header types
97 * @hash_flds: the RSS configuration protocol hash fields
98 * @symm: if true, symmetric hash is required
99 *
100 * Returns 0 if the RSS configuration virtchnl message is filled successfully
101 */
102int
103iavf_fill_adv_rss_cfg_msg(struct virtchnl_rss_cfg *rss_cfg,
104 u32 packet_hdrs, u64 hash_flds, bool symm)
105{
106 struct virtchnl_proto_hdrs *proto_hdrs = &rss_cfg->proto_hdrs;
107 struct virtchnl_proto_hdr *hdr;
108
109 if (symm)
110 rss_cfg->rss_algorithm = VIRTCHNL_RSS_ALG_TOEPLITZ_SYMMETRIC;
111 else
112 rss_cfg->rss_algorithm = VIRTCHNL_RSS_ALG_TOEPLITZ_ASYMMETRIC;
113
114 proto_hdrs->tunnel_level = 0; /* always outer layer */
115
116 hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++];
117 switch (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_L3) {
118 case IAVF_ADV_RSS_FLOW_SEG_HDR_IPV4:
119 iavf_fill_adv_rss_ip4_hdr(hdr, hash_flds);
120 break;
121 case IAVF_ADV_RSS_FLOW_SEG_HDR_IPV6:
122 iavf_fill_adv_rss_ip6_hdr(hdr, hash_flds);
123 break;
124 default:
125 return -EINVAL;
126 }
127
128 hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++];
129 switch (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_L4) {
130 case IAVF_ADV_RSS_FLOW_SEG_HDR_TCP:
131 iavf_fill_adv_rss_tcp_hdr(hdr, hash_flds);
132 break;
133 case IAVF_ADV_RSS_FLOW_SEG_HDR_UDP:
134 iavf_fill_adv_rss_udp_hdr(hdr, hash_flds);
135 break;
136 case IAVF_ADV_RSS_FLOW_SEG_HDR_SCTP:
137 iavf_fill_adv_rss_sctp_hdr(hdr, hash_flds);
138 break;
139 default:
140 return -EINVAL;
141 }
142
143 return 0;
144}
145
146/**
147 * iavf_find_adv_rss_cfg_by_hdrs - find RSS configuration with header type
148 * @adapter: pointer to the VF adapter structure
149 * @packet_hdrs: protocol header type to find.
150 *
151 * Returns pointer to advance RSS configuration if found or null
152 */
153struct iavf_adv_rss *
154iavf_find_adv_rss_cfg_by_hdrs(struct iavf_adapter *adapter, u32 packet_hdrs)
155{
156 struct iavf_adv_rss *rss;
157
158 list_for_each_entry(rss, &adapter->adv_rss_list_head, list)
159 if (rss->packet_hdrs == packet_hdrs)
160 return rss;
161
162 return NULL;
163}
164
165/**
166 * iavf_print_adv_rss_cfg
167 * @adapter: pointer to the VF adapter structure
168 * @rss: pointer to the advance RSS configuration to print
169 * @action: the string description about how to handle the RSS
170 * @result: the string description about the virtchnl result
171 *
172 * Print the advance RSS configuration
173 **/
174void
175iavf_print_adv_rss_cfg(struct iavf_adapter *adapter, struct iavf_adv_rss *rss,
176 const char *action, const char *result)
177{
178 u32 packet_hdrs = rss->packet_hdrs;
179 u64 hash_flds = rss->hash_flds;
180 static char hash_opt[300];
181 const char *proto;
182
183 if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_TCP)
184 proto = "TCP";
185 else if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_UDP)
186 proto = "UDP";
187 else if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_SCTP)
188 proto = "SCTP";
189 else
190 return;
191
192 memset(hash_opt, 0, sizeof(hash_opt));
193
194 strcat(hash_opt, proto);
195 if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_IPV4)
196 strcat(hash_opt, "v4 ");
197 else
198 strcat(hash_opt, "v6 ");
199
200 if (hash_flds & (IAVF_ADV_RSS_HASH_FLD_IPV4_SA |
201 IAVF_ADV_RSS_HASH_FLD_IPV6_SA))
202 strcat(hash_opt, "IP SA,");
203 if (hash_flds & (IAVF_ADV_RSS_HASH_FLD_IPV4_DA |
204 IAVF_ADV_RSS_HASH_FLD_IPV6_DA))
205 strcat(hash_opt, "IP DA,");
206 if (hash_flds & (IAVF_ADV_RSS_HASH_FLD_TCP_SRC_PORT |
207 IAVF_ADV_RSS_HASH_FLD_UDP_SRC_PORT |
208 IAVF_ADV_RSS_HASH_FLD_SCTP_SRC_PORT))
209 strcat(hash_opt, "src port,");
210 if (hash_flds & (IAVF_ADV_RSS_HASH_FLD_TCP_DST_PORT |
211 IAVF_ADV_RSS_HASH_FLD_UDP_DST_PORT |
212 IAVF_ADV_RSS_HASH_FLD_SCTP_DST_PORT))
213 strcat(hash_opt, "dst port,");
214
215 if (!action)
216 action = "";
217
218 if (!result)
219 result = "";
220
221 dev_info(&adapter->pdev->dev, "%s %s %s\n", action, hash_opt, result);
222}
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (c) 2021, Intel Corporation. */
3
4/* advanced RSS configuration ethtool support for iavf */
5
6#include "iavf.h"
7
8/**
9 * iavf_fill_adv_rss_ip4_hdr - fill the IPv4 RSS protocol header
10 * @hdr: the virtchnl message protocol header data structure
11 * @hash_flds: the RSS configuration protocol hash fields
12 */
13static void
14iavf_fill_adv_rss_ip4_hdr(struct virtchnl_proto_hdr *hdr, u64 hash_flds)
15{
16 VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, IPV4);
17
18 if (hash_flds & IAVF_ADV_RSS_HASH_FLD_IPV4_SA)
19 VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV4, SRC);
20
21 if (hash_flds & IAVF_ADV_RSS_HASH_FLD_IPV4_DA)
22 VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV4, DST);
23}
24
25/**
26 * iavf_fill_adv_rss_ip6_hdr - fill the IPv6 RSS protocol header
27 * @hdr: the virtchnl message protocol header data structure
28 * @hash_flds: the RSS configuration protocol hash fields
29 */
30static void
31iavf_fill_adv_rss_ip6_hdr(struct virtchnl_proto_hdr *hdr, u64 hash_flds)
32{
33 VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, IPV6);
34
35 if (hash_flds & IAVF_ADV_RSS_HASH_FLD_IPV6_SA)
36 VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV6, SRC);
37
38 if (hash_flds & IAVF_ADV_RSS_HASH_FLD_IPV6_DA)
39 VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV6, DST);
40}
41
42/**
43 * iavf_fill_adv_rss_tcp_hdr - fill the TCP RSS protocol header
44 * @hdr: the virtchnl message protocol header data structure
45 * @hash_flds: the RSS configuration protocol hash fields
46 */
47static void
48iavf_fill_adv_rss_tcp_hdr(struct virtchnl_proto_hdr *hdr, u64 hash_flds)
49{
50 VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, TCP);
51
52 if (hash_flds & IAVF_ADV_RSS_HASH_FLD_TCP_SRC_PORT)
53 VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, TCP, SRC_PORT);
54
55 if (hash_flds & IAVF_ADV_RSS_HASH_FLD_TCP_DST_PORT)
56 VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, TCP, DST_PORT);
57}
58
59/**
60 * iavf_fill_adv_rss_udp_hdr - fill the UDP RSS protocol header
61 * @hdr: the virtchnl message protocol header data structure
62 * @hash_flds: the RSS configuration protocol hash fields
63 */
64static void
65iavf_fill_adv_rss_udp_hdr(struct virtchnl_proto_hdr *hdr, u64 hash_flds)
66{
67 VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, UDP);
68
69 if (hash_flds & IAVF_ADV_RSS_HASH_FLD_UDP_SRC_PORT)
70 VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, UDP, SRC_PORT);
71
72 if (hash_flds & IAVF_ADV_RSS_HASH_FLD_UDP_DST_PORT)
73 VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, UDP, DST_PORT);
74}
75
76/**
77 * iavf_fill_adv_rss_sctp_hdr - fill the SCTP RSS protocol header
78 * @hdr: the virtchnl message protocol header data structure
79 * @hash_flds: the RSS configuration protocol hash fields
80 */
81static void
82iavf_fill_adv_rss_sctp_hdr(struct virtchnl_proto_hdr *hdr, u64 hash_flds)
83{
84 VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, SCTP);
85
86 if (hash_flds & IAVF_ADV_RSS_HASH_FLD_SCTP_SRC_PORT)
87 VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, SCTP, SRC_PORT);
88
89 if (hash_flds & IAVF_ADV_RSS_HASH_FLD_SCTP_DST_PORT)
90 VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, SCTP, DST_PORT);
91}
92
93/**
94 * iavf_fill_adv_rss_cfg_msg - fill the RSS configuration into virtchnl message
95 * @rss_cfg: the virtchnl message to be filled with RSS configuration setting
96 * @packet_hdrs: the RSS configuration protocol header types
97 * @hash_flds: the RSS configuration protocol hash fields
98 *
99 * Returns 0 if the RSS configuration virtchnl message is filled successfully
100 */
101int
102iavf_fill_adv_rss_cfg_msg(struct virtchnl_rss_cfg *rss_cfg,
103 u32 packet_hdrs, u64 hash_flds)
104{
105 struct virtchnl_proto_hdrs *proto_hdrs = &rss_cfg->proto_hdrs;
106 struct virtchnl_proto_hdr *hdr;
107
108 rss_cfg->rss_algorithm = VIRTCHNL_RSS_ALG_TOEPLITZ_ASYMMETRIC;
109
110 proto_hdrs->tunnel_level = 0; /* always outer layer */
111
112 hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++];
113 switch (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_L3) {
114 case IAVF_ADV_RSS_FLOW_SEG_HDR_IPV4:
115 iavf_fill_adv_rss_ip4_hdr(hdr, hash_flds);
116 break;
117 case IAVF_ADV_RSS_FLOW_SEG_HDR_IPV6:
118 iavf_fill_adv_rss_ip6_hdr(hdr, hash_flds);
119 break;
120 default:
121 return -EINVAL;
122 }
123
124 hdr = &proto_hdrs->proto_hdr[proto_hdrs->count++];
125 switch (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_L4) {
126 case IAVF_ADV_RSS_FLOW_SEG_HDR_TCP:
127 iavf_fill_adv_rss_tcp_hdr(hdr, hash_flds);
128 break;
129 case IAVF_ADV_RSS_FLOW_SEG_HDR_UDP:
130 iavf_fill_adv_rss_udp_hdr(hdr, hash_flds);
131 break;
132 case IAVF_ADV_RSS_FLOW_SEG_HDR_SCTP:
133 iavf_fill_adv_rss_sctp_hdr(hdr, hash_flds);
134 break;
135 default:
136 return -EINVAL;
137 }
138
139 return 0;
140}
141
142/**
143 * iavf_find_adv_rss_cfg_by_hdrs - find RSS configuration with header type
144 * @adapter: pointer to the VF adapter structure
145 * @packet_hdrs: protocol header type to find.
146 *
147 * Returns pointer to advance RSS configuration if found or null
148 */
149struct iavf_adv_rss *
150iavf_find_adv_rss_cfg_by_hdrs(struct iavf_adapter *adapter, u32 packet_hdrs)
151{
152 struct iavf_adv_rss *rss;
153
154 list_for_each_entry(rss, &adapter->adv_rss_list_head, list)
155 if (rss->packet_hdrs == packet_hdrs)
156 return rss;
157
158 return NULL;
159}
160
161/**
162 * iavf_print_adv_rss_cfg
163 * @adapter: pointer to the VF adapter structure
164 * @rss: pointer to the advance RSS configuration to print
165 * @action: the string description about how to handle the RSS
166 * @result: the string description about the virtchnl result
167 *
168 * Print the advance RSS configuration
169 **/
170void
171iavf_print_adv_rss_cfg(struct iavf_adapter *adapter, struct iavf_adv_rss *rss,
172 const char *action, const char *result)
173{
174 u32 packet_hdrs = rss->packet_hdrs;
175 u64 hash_flds = rss->hash_flds;
176 static char hash_opt[300];
177 const char *proto;
178
179 if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_TCP)
180 proto = "TCP";
181 else if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_UDP)
182 proto = "UDP";
183 else if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_SCTP)
184 proto = "SCTP";
185 else
186 return;
187
188 memset(hash_opt, 0, sizeof(hash_opt));
189
190 strcat(hash_opt, proto);
191 if (packet_hdrs & IAVF_ADV_RSS_FLOW_SEG_HDR_IPV4)
192 strcat(hash_opt, "v4 ");
193 else
194 strcat(hash_opt, "v6 ");
195
196 if (hash_flds & (IAVF_ADV_RSS_HASH_FLD_IPV4_SA |
197 IAVF_ADV_RSS_HASH_FLD_IPV6_SA))
198 strcat(hash_opt, "IP SA,");
199 if (hash_flds & (IAVF_ADV_RSS_HASH_FLD_IPV4_DA |
200 IAVF_ADV_RSS_HASH_FLD_IPV6_DA))
201 strcat(hash_opt, "IP DA,");
202 if (hash_flds & (IAVF_ADV_RSS_HASH_FLD_TCP_SRC_PORT |
203 IAVF_ADV_RSS_HASH_FLD_UDP_SRC_PORT |
204 IAVF_ADV_RSS_HASH_FLD_SCTP_SRC_PORT))
205 strcat(hash_opt, "src port,");
206 if (hash_flds & (IAVF_ADV_RSS_HASH_FLD_TCP_DST_PORT |
207 IAVF_ADV_RSS_HASH_FLD_UDP_DST_PORT |
208 IAVF_ADV_RSS_HASH_FLD_SCTP_DST_PORT))
209 strcat(hash_opt, "dst port,");
210
211 if (!action)
212 action = "";
213
214 if (!result)
215 result = "";
216
217 dev_info(&adapter->pdev->dev, "%s %s %s\n", action, hash_opt, result);
218}