Skip to content

Commit f29ffdb

Browse files
Mintz, Yuvaldavem330
authored andcommitted
qed*: RSS indirection based on queue-handles
A step toward having qede agnostic to the queue configurations in firmware/hardware - let the RSS indirections use queue handles instead of actual queue indices. Signed-off-by: Yuval Mintz <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 04e0fd0 commit f29ffdb

File tree

9 files changed

+392
-265
lines changed

9 files changed

+392
-265
lines changed

drivers/net/ethernet/qlogic/qed/qed_l2.c

Lines changed: 143 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ _qed_eth_queue_to_cid(struct qed_hwfn *p_hwfn,
9898
p_cid->cid = cid;
9999
p_cid->vf_qid = vf_qid;
100100
p_cid->rel = *p_params;
101+
p_cid->p_owner = p_hwfn;
101102

102103
/* Don't try calculating the absolute indices for VFs */
103104
if (IS_VF(p_hwfn->cdev)) {
@@ -272,76 +273,103 @@ static int qed_sp_vport_start(struct qed_hwfn *p_hwfn,
272273
static int
273274
qed_sp_vport_update_rss(struct qed_hwfn *p_hwfn,
274275
struct vport_update_ramrod_data *p_ramrod,
275-
struct qed_rss_params *p_params)
276+
struct qed_rss_params *p_rss)
276277
{
277-
struct eth_vport_rss_config *rss = &p_ramrod->rss_config;
278-
u16 abs_l2_queue = 0, capabilities = 0;
279-
int rc = 0, i;
278+
struct eth_vport_rss_config *p_config;
279+
u16 capabilities = 0;
280+
int i, table_size;
281+
int rc = 0;
280282

281-
if (!p_params) {
283+
if (!p_rss) {
282284
p_ramrod->common.update_rss_flg = 0;
283285
return rc;
284286
}
287+
p_config = &p_ramrod->rss_config;
285288

286-
BUILD_BUG_ON(QED_RSS_IND_TABLE_SIZE !=
287-
ETH_RSS_IND_TABLE_ENTRIES_NUM);
289+
BUILD_BUG_ON(QED_RSS_IND_TABLE_SIZE != ETH_RSS_IND_TABLE_ENTRIES_NUM);
288290

289-
rc = qed_fw_rss_eng(p_hwfn, p_params->rss_eng_id, &rss->rss_id);
291+
rc = qed_fw_rss_eng(p_hwfn, p_rss->rss_eng_id, &p_config->rss_id);
290292
if (rc)
291293
return rc;
292294

293-
p_ramrod->common.update_rss_flg = p_params->update_rss_config;
294-
rss->update_rss_capabilities = p_params->update_rss_capabilities;
295-
rss->update_rss_ind_table = p_params->update_rss_ind_table;
296-
rss->update_rss_key = p_params->update_rss_key;
295+
p_ramrod->common.update_rss_flg = p_rss->update_rss_config;
296+
p_config->update_rss_capabilities = p_rss->update_rss_capabilities;
297+
p_config->update_rss_ind_table = p_rss->update_rss_ind_table;
298+
p_config->update_rss_key = p_rss->update_rss_key;
297299

298-
rss->rss_mode = p_params->rss_enable ?
299-
ETH_VPORT_RSS_MODE_REGULAR :
300-
ETH_VPORT_RSS_MODE_DISABLED;
300+
p_config->rss_mode = p_rss->rss_enable ?
301+
ETH_VPORT_RSS_MODE_REGULAR :
302+
ETH_VPORT_RSS_MODE_DISABLED;
301303

302304
SET_FIELD(capabilities,
303305
ETH_VPORT_RSS_CONFIG_IPV4_CAPABILITY,
304-
!!(p_params->rss_caps & QED_RSS_IPV4));
306+
!!(p_rss->rss_caps & QED_RSS_IPV4));
305307
SET_FIELD(capabilities,
306308
ETH_VPORT_RSS_CONFIG_IPV6_CAPABILITY,
307-
!!(p_params->rss_caps & QED_RSS_IPV6));
309+
!!(p_rss->rss_caps & QED_RSS_IPV6));
308310
SET_FIELD(capabilities,
309311
ETH_VPORT_RSS_CONFIG_IPV4_TCP_CAPABILITY,
310-
!!(p_params->rss_caps & QED_RSS_IPV4_TCP));
312+
!!(p_rss->rss_caps & QED_RSS_IPV4_TCP));
311313
SET_FIELD(capabilities,
312314
ETH_VPORT_RSS_CONFIG_IPV6_TCP_CAPABILITY,
313-
!!(p_params->rss_caps & QED_RSS_IPV6_TCP));
315+
!!(p_rss->rss_caps & QED_RSS_IPV6_TCP));
314316
SET_FIELD(capabilities,
315317
ETH_VPORT_RSS_CONFIG_IPV4_UDP_CAPABILITY,
316-
!!(p_params->rss_caps & QED_RSS_IPV4_UDP));
318+
!!(p_rss->rss_caps & QED_RSS_IPV4_UDP));
317319
SET_FIELD(capabilities,
318320
ETH_VPORT_RSS_CONFIG_IPV6_UDP_CAPABILITY,
319-
!!(p_params->rss_caps & QED_RSS_IPV6_UDP));
320-
rss->tbl_size = p_params->rss_table_size_log;
321+
!!(p_rss->rss_caps & QED_RSS_IPV6_UDP));
322+
p_config->tbl_size = p_rss->rss_table_size_log;
321323

322-
rss->capabilities = cpu_to_le16(capabilities);
324+
p_config->capabilities = cpu_to_le16(capabilities);
323325

324326
DP_VERBOSE(p_hwfn, NETIF_MSG_IFUP,
325327
"update rss flag %d, rss_mode = %d, update_caps = %d, capabilities = %d, update_ind = %d, update_rss_key = %d\n",
326328
p_ramrod->common.update_rss_flg,
327-
rss->rss_mode, rss->update_rss_capabilities,
328-
capabilities, rss->update_rss_ind_table,
329-
rss->update_rss_key);
329+
p_config->rss_mode,
330+
p_config->update_rss_capabilities,
331+
p_config->capabilities,
332+
p_config->update_rss_ind_table, p_config->update_rss_key);
330333

331-
for (i = 0; i < QED_RSS_IND_TABLE_SIZE; i++) {
332-
rc = qed_fw_l2_queue(p_hwfn,
333-
(u8)p_params->rss_ind_table[i],
334-
&abs_l2_queue);
335-
if (rc)
336-
return rc;
334+
table_size = min_t(int, QED_RSS_IND_TABLE_SIZE,
335+
1 << p_config->tbl_size);
336+
for (i = 0; i < table_size; i++) {
337+
struct qed_queue_cid *p_queue = p_rss->rss_ind_table[i];
337338

338-
rss->indirection_table[i] = cpu_to_le16(abs_l2_queue);
339-
DP_VERBOSE(p_hwfn, NETIF_MSG_IFUP, "i= %d, queue = %d\n",
340-
i, rss->indirection_table[i]);
339+
if (!p_queue)
340+
return -EINVAL;
341+
342+
p_config->indirection_table[i] =
343+
cpu_to_le16(p_queue->abs.queue_id);
344+
}
345+
346+
DP_VERBOSE(p_hwfn, NETIF_MSG_IFUP,
347+
"Configured RSS indirection table [%d entries]:\n",
348+
table_size);
349+
for (i = 0; i < QED_RSS_IND_TABLE_SIZE; i += 0x10) {
350+
DP_VERBOSE(p_hwfn,
351+
NETIF_MSG_IFUP,
352+
"%04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x %04x\n",
353+
le16_to_cpu(p_config->indirection_table[i]),
354+
le16_to_cpu(p_config->indirection_table[i + 1]),
355+
le16_to_cpu(p_config->indirection_table[i + 2]),
356+
le16_to_cpu(p_config->indirection_table[i + 3]),
357+
le16_to_cpu(p_config->indirection_table[i + 4]),
358+
le16_to_cpu(p_config->indirection_table[i + 5]),
359+
le16_to_cpu(p_config->indirection_table[i + 6]),
360+
le16_to_cpu(p_config->indirection_table[i + 7]),
361+
le16_to_cpu(p_config->indirection_table[i + 8]),
362+
le16_to_cpu(p_config->indirection_table[i + 9]),
363+
le16_to_cpu(p_config->indirection_table[i + 10]),
364+
le16_to_cpu(p_config->indirection_table[i + 11]),
365+
le16_to_cpu(p_config->indirection_table[i + 12]),
366+
le16_to_cpu(p_config->indirection_table[i + 13]),
367+
le16_to_cpu(p_config->indirection_table[i + 14]),
368+
le16_to_cpu(p_config->indirection_table[i + 15]));
341369
}
342370

343371
for (i = 0; i < 10; i++)
344-
rss->rss_key[i] = cpu_to_le32(p_params->rss_key[i]);
372+
p_config->rss_key[i] = cpu_to_le32(p_rss->rss_key[i]);
345373

346374
return rc;
347375
}
@@ -1899,18 +1927,84 @@ static int qed_stop_vport(struct qed_dev *cdev, u8 vport_id)
18991927
return 0;
19001928
}
19011929

1930+
static int qed_update_vport_rss(struct qed_dev *cdev,
1931+
struct qed_update_vport_rss_params *input,
1932+
struct qed_rss_params *rss)
1933+
{
1934+
int i, fn;
1935+
1936+
/* Update configuration with what's correct regardless of CMT */
1937+
rss->update_rss_config = 1;
1938+
rss->rss_enable = 1;
1939+
rss->update_rss_capabilities = 1;
1940+
rss->update_rss_ind_table = 1;
1941+
rss->update_rss_key = 1;
1942+
rss->rss_caps = input->rss_caps;
1943+
memcpy(rss->rss_key, input->rss_key, QED_RSS_KEY_SIZE * sizeof(u32));
1944+
1945+
/* In regular scenario, we'd simply need to take input handlers.
1946+
* But in CMT, we'd have to split the handlers according to the
1947+
* engine they were configured on. We'd then have to understand
1948+
* whether RSS is really required, since 2-queues on CMT doesn't
1949+
* require RSS.
1950+
*/
1951+
if (cdev->num_hwfns == 1) {
1952+
memcpy(rss->rss_ind_table,
1953+
input->rss_ind_table,
1954+
QED_RSS_IND_TABLE_SIZE * sizeof(void *));
1955+
rss->rss_table_size_log = 7;
1956+
return 0;
1957+
}
1958+
1959+
/* Start by copying the non-spcific information to the 2nd copy */
1960+
memcpy(&rss[1], &rss[0], sizeof(struct qed_rss_params));
1961+
1962+
/* CMT should be round-robin */
1963+
for (i = 0; i < QED_RSS_IND_TABLE_SIZE; i++) {
1964+
struct qed_queue_cid *cid = input->rss_ind_table[i];
1965+
struct qed_rss_params *t_rss;
1966+
1967+
if (cid->p_owner == QED_LEADING_HWFN(cdev))
1968+
t_rss = &rss[0];
1969+
else
1970+
t_rss = &rss[1];
1971+
1972+
t_rss->rss_ind_table[i / cdev->num_hwfns] = cid;
1973+
}
1974+
1975+
/* Make sure RSS is actually required */
1976+
for_each_hwfn(cdev, fn) {
1977+
for (i = 1; i < QED_RSS_IND_TABLE_SIZE / cdev->num_hwfns; i++) {
1978+
if (rss[fn].rss_ind_table[i] !=
1979+
rss[fn].rss_ind_table[0])
1980+
break;
1981+
}
1982+
if (i == QED_RSS_IND_TABLE_SIZE / cdev->num_hwfns) {
1983+
DP_VERBOSE(cdev, NETIF_MSG_IFUP,
1984+
"CMT - 1 queue per-hwfn; Disabling RSS\n");
1985+
return -EINVAL;
1986+
}
1987+
rss[fn].rss_table_size_log = 6;
1988+
}
1989+
1990+
return 0;
1991+
}
1992+
19021993
static int qed_update_vport(struct qed_dev *cdev,
19031994
struct qed_update_vport_params *params)
19041995
{
19051996
struct qed_sp_vport_update_params sp_params;
1906-
struct qed_rss_params sp_rss_params;
1907-
int rc, i;
1997+
struct qed_rss_params *rss;
1998+
int rc = 0, i;
19081999

19092000
if (!cdev)
19102001
return -ENODEV;
19112002

2003+
rss = vzalloc(sizeof(*rss) * cdev->num_hwfns);
2004+
if (!rss)
2005+
return -ENOMEM;
2006+
19122007
memset(&sp_params, 0, sizeof(sp_params));
1913-
memset(&sp_rss_params, 0, sizeof(sp_rss_params));
19142008

19152009
/* Translate protocol params into sp params */
19162010
sp_params.vport_id = params->vport_id;
@@ -1924,66 +2018,24 @@ static int qed_update_vport(struct qed_dev *cdev,
19242018
sp_params.update_accept_any_vlan_flg =
19252019
params->update_accept_any_vlan_flg;
19262020

1927-
/* RSS - is a bit tricky, since upper-layer isn't familiar with hwfns.
1928-
* We need to re-fix the rss values per engine for CMT.
1929-
*/
1930-
if (cdev->num_hwfns > 1 && params->update_rss_flg) {
1931-
struct qed_update_vport_rss_params *rss = &params->rss_params;
1932-
int k, max = 0;
1933-
1934-
/* Find largest entry, since it's possible RSS needs to
1935-
* be disabled [in case only 1 queue per-hwfn]
1936-
*/
1937-
for (k = 0; k < QED_RSS_IND_TABLE_SIZE; k++)
1938-
max = (max > rss->rss_ind_table[k]) ?
1939-
max : rss->rss_ind_table[k];
1940-
1941-
/* Either fix RSS values or disable RSS */
1942-
if (cdev->num_hwfns < max + 1) {
1943-
int divisor = (max + cdev->num_hwfns - 1) /
1944-
cdev->num_hwfns;
1945-
1946-
DP_VERBOSE(cdev, (QED_MSG_SPQ | NETIF_MSG_IFUP),
1947-
"CMT - fixing RSS values (modulo %02x)\n",
1948-
divisor);
1949-
1950-
for (k = 0; k < QED_RSS_IND_TABLE_SIZE; k++)
1951-
rss->rss_ind_table[k] =
1952-
rss->rss_ind_table[k] % divisor;
1953-
} else {
1954-
DP_VERBOSE(cdev, (QED_MSG_SPQ | NETIF_MSG_IFUP),
1955-
"CMT - 1 queue per-hwfn; Disabling RSS\n");
2021+
/* Prepare the RSS configuration */
2022+
if (params->update_rss_flg)
2023+
if (qed_update_vport_rss(cdev, &params->rss_params, rss))
19562024
params->update_rss_flg = 0;
1957-
}
1958-
}
1959-
1960-
/* Now, update the RSS configuration for actual configuration */
1961-
if (params->update_rss_flg) {
1962-
sp_rss_params.update_rss_config = 1;
1963-
sp_rss_params.rss_enable = 1;
1964-
sp_rss_params.update_rss_capabilities = 1;
1965-
sp_rss_params.update_rss_ind_table = 1;
1966-
sp_rss_params.update_rss_key = 1;
1967-
sp_rss_params.rss_caps = params->rss_params.rss_caps;
1968-
sp_rss_params.rss_table_size_log = 7; /* 2^7 = 128 */
1969-
memcpy(sp_rss_params.rss_ind_table,
1970-
params->rss_params.rss_ind_table,
1971-
QED_RSS_IND_TABLE_SIZE * sizeof(u16));
1972-
memcpy(sp_rss_params.rss_key, params->rss_params.rss_key,
1973-
QED_RSS_KEY_SIZE * sizeof(u32));
1974-
sp_params.rss_params = &sp_rss_params;
1975-
}
19762025

19772026
for_each_hwfn(cdev, i) {
19782027
struct qed_hwfn *p_hwfn = &cdev->hwfns[i];
19792028

2029+
if (params->update_rss_flg)
2030+
sp_params.rss_params = &rss[i];
2031+
19802032
sp_params.opaque_fid = p_hwfn->hw_info.opaque_fid;
19812033
rc = qed_sp_vport_update(p_hwfn, &sp_params,
19822034
QED_SPQ_MODE_EBLOCK,
19832035
NULL);
19842036
if (rc) {
19852037
DP_ERR(cdev, "Failed to update VPORT\n");
1986-
return rc;
2038+
goto out;
19872039
}
19882040

19892041
DP_VERBOSE(cdev, (QED_MSG_SPQ | NETIF_MSG_IFUP),
@@ -1992,7 +2044,9 @@ static int qed_update_vport(struct qed_dev *cdev,
19922044
params->update_vport_active_flg);
19932045
}
19942046

1995-
return 0;
2047+
out:
2048+
vfree(rss);
2049+
return rc;
19962050
}
19972051

19982052
static int qed_start_rxq(struct qed_dev *cdev,

drivers/net/ethernet/qlogic/qed/qed_l2.h

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,20 @@
3939
#include "qed.h"
4040
#include "qed_hw.h"
4141
#include "qed_sp.h"
42+
struct qed_rss_params {
43+
u8 update_rss_config;
44+
u8 rss_enable;
45+
u8 rss_eng_id;
46+
u8 update_rss_capabilities;
47+
u8 update_rss_ind_table;
48+
u8 update_rss_key;
49+
u8 rss_caps;
50+
u8 rss_table_size_log;
51+
52+
/* Indirection table consist of rx queue handles */
53+
void *rss_ind_table[QED_RSS_IND_TABLE_SIZE];
54+
u32 rss_key[QED_RSS_KEY_SIZE];
55+
};
4256

4357
struct qed_sge_tpa_params {
4458
u8 max_buffers_per_cqe;
@@ -156,18 +170,6 @@ struct qed_sp_vport_start_params {
156170
int qed_sp_eth_vport_start(struct qed_hwfn *p_hwfn,
157171
struct qed_sp_vport_start_params *p_params);
158172

159-
struct qed_rss_params {
160-
u8 update_rss_config;
161-
u8 rss_enable;
162-
u8 rss_eng_id;
163-
u8 update_rss_capabilities;
164-
u8 update_rss_ind_table;
165-
u8 update_rss_key;
166-
u8 rss_caps;
167-
u8 rss_table_size_log;
168-
u16 rss_ind_table[QED_RSS_IND_TABLE_SIZE];
169-
u32 rss_key[QED_RSS_KEY_SIZE];
170-
};
171173

172174
struct qed_filter_accept_flags {
173175
u8 update_rx_mode_config;
@@ -287,6 +289,8 @@ struct qed_queue_cid {
287289

288290
/* Legacy VFs might have Rx producer located elsewhere */
289291
bool b_legacy_vf;
292+
293+
struct qed_hwfn *p_owner;
290294
};
291295

292296
void qed_eth_queue_cid_release(struct qed_hwfn *p_hwfn,

0 commit comments

Comments
 (0)