cxgb4: Initialize RSS mode for all Ports
Implements t4_init_rss_mode() to initialize the rss_mode for all the ports. If Tunnel All Lookup isn't specified in the global RSS Configuration, then we need to specify a default Ingress Queue for any ingress packets which aren't hashed. We'll use our first ingress queue. Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
b2a6c326b2
commit
c035e183eb
3 changed files with 80 additions and 7 deletions
|
@ -1201,12 +1201,15 @@ int t4_init_devlog_params(struct adapter *adapter);
|
||||||
int t4_init_sge_params(struct adapter *adapter);
|
int t4_init_sge_params(struct adapter *adapter);
|
||||||
int t4_init_tp_params(struct adapter *adap);
|
int t4_init_tp_params(struct adapter *adap);
|
||||||
int t4_filter_field_shift(const struct adapter *adap, int filter_sel);
|
int t4_filter_field_shift(const struct adapter *adap, int filter_sel);
|
||||||
|
int t4_init_rss_mode(struct adapter *adap, int mbox);
|
||||||
int t4_port_init(struct adapter *adap, int mbox, int pf, int vf);
|
int t4_port_init(struct adapter *adap, int mbox, int pf, int vf);
|
||||||
void t4_fatal_err(struct adapter *adapter);
|
void t4_fatal_err(struct adapter *adapter);
|
||||||
int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid,
|
int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid,
|
||||||
int start, int n, const u16 *rspq, unsigned int nrspq);
|
int start, int n, const u16 *rspq, unsigned int nrspq);
|
||||||
int t4_config_glbl_rss(struct adapter *adapter, int mbox, unsigned int mode,
|
int t4_config_glbl_rss(struct adapter *adapter, int mbox, unsigned int mode,
|
||||||
unsigned int flags);
|
unsigned int flags);
|
||||||
|
int t4_config_vi_rss(struct adapter *adapter, int mbox, unsigned int viid,
|
||||||
|
unsigned int flags, unsigned int defq);
|
||||||
int t4_read_rss(struct adapter *adapter, u16 *entries);
|
int t4_read_rss(struct adapter *adapter, u16 *entries);
|
||||||
void t4_read_rss_key(struct adapter *adapter, u32 *key);
|
void t4_read_rss_key(struct adapter *adapter, u32 *key);
|
||||||
void t4_write_rss_key(struct adapter *adap, const u32 *key, int idx);
|
void t4_write_rss_key(struct adapter *adap, const u32 *key, int idx);
|
||||||
|
|
|
@ -856,23 +856,39 @@ static void free_msix_queue_irqs(struct adapter *adap)
|
||||||
*
|
*
|
||||||
* Sets up the portion of the HW RSS table for the port's VI to distribute
|
* Sets up the portion of the HW RSS table for the port's VI to distribute
|
||||||
* packets to the Rx queues in @queues.
|
* packets to the Rx queues in @queues.
|
||||||
|
* Should never be called before setting up sge eth rx queues
|
||||||
*/
|
*/
|
||||||
int cxgb4_write_rss(const struct port_info *pi, const u16 *queues)
|
int cxgb4_write_rss(const struct port_info *pi, const u16 *queues)
|
||||||
{
|
{
|
||||||
u16 *rss;
|
u16 *rss;
|
||||||
int i, err;
|
int i, err;
|
||||||
const struct sge_eth_rxq *q = &pi->adapter->sge.ethrxq[pi->first_qset];
|
struct adapter *adapter = pi->adapter;
|
||||||
|
const struct sge_eth_rxq *rxq;
|
||||||
|
|
||||||
|
rxq = &adapter->sge.ethrxq[pi->first_qset];
|
||||||
rss = kmalloc(pi->rss_size * sizeof(u16), GFP_KERNEL);
|
rss = kmalloc(pi->rss_size * sizeof(u16), GFP_KERNEL);
|
||||||
if (!rss)
|
if (!rss)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
/* map the queue indices to queue ids */
|
/* map the queue indices to queue ids */
|
||||||
for (i = 0; i < pi->rss_size; i++, queues++)
|
for (i = 0; i < pi->rss_size; i++, queues++)
|
||||||
rss[i] = q[*queues].rspq.abs_id;
|
rss[i] = rxq[*queues].rspq.abs_id;
|
||||||
|
|
||||||
err = t4_config_rss_range(pi->adapter, pi->adapter->fn, pi->viid, 0,
|
err = t4_config_rss_range(adapter, adapter->fn, pi->viid, 0,
|
||||||
pi->rss_size, rss, pi->rss_size);
|
pi->rss_size, rss, pi->rss_size);
|
||||||
|
/* If Tunnel All Lookup isn't specified in the global RSS
|
||||||
|
* Configuration, then we need to specify a default Ingress
|
||||||
|
* Queue for any ingress packets which aren't hashed. We'll
|
||||||
|
* use our first ingress queue ...
|
||||||
|
*/
|
||||||
|
if (!err)
|
||||||
|
err = t4_config_vi_rss(adapter, adapter->mbox, pi->viid,
|
||||||
|
FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN_F |
|
||||||
|
FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN_F |
|
||||||
|
FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN_F |
|
||||||
|
FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN_F |
|
||||||
|
FW_RSS_VI_CONFIG_CMD_UDPEN_F,
|
||||||
|
rss[0]);
|
||||||
kfree(rss);
|
kfree(rss);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -885,11 +901,15 @@ int cxgb4_write_rss(const struct port_info *pi, const u16 *queues)
|
||||||
*/
|
*/
|
||||||
static int setup_rss(struct adapter *adap)
|
static int setup_rss(struct adapter *adap)
|
||||||
{
|
{
|
||||||
int i, err;
|
int i, j, err;
|
||||||
|
|
||||||
for_each_port(adap, i) {
|
for_each_port(adap, i) {
|
||||||
const struct port_info *pi = adap2pinfo(adap, i);
|
const struct port_info *pi = adap2pinfo(adap, i);
|
||||||
|
|
||||||
|
/* Fill default values with equal distribution */
|
||||||
|
for (j = 0; j < pi->rss_size; j++)
|
||||||
|
pi->rss[j] = j % pi->nqsets;
|
||||||
|
|
||||||
err = cxgb4_write_rss(pi, pi->rss);
|
err = cxgb4_write_rss(pi, pi->rss);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
@ -4343,7 +4363,12 @@ static int enable_msix(struct adapter *adap)
|
||||||
|
|
||||||
static int init_rss(struct adapter *adap)
|
static int init_rss(struct adapter *adap)
|
||||||
{
|
{
|
||||||
unsigned int i, j;
|
unsigned int i;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = t4_init_rss_mode(adap, adap->mbox);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
for_each_port(adap, i) {
|
for_each_port(adap, i) {
|
||||||
struct port_info *pi = adap2pinfo(adap, i);
|
struct port_info *pi = adap2pinfo(adap, i);
|
||||||
|
@ -4351,8 +4376,6 @@ static int init_rss(struct adapter *adap)
|
||||||
pi->rss = kcalloc(pi->rss_size, sizeof(u16), GFP_KERNEL);
|
pi->rss = kcalloc(pi->rss_size, sizeof(u16), GFP_KERNEL);
|
||||||
if (!pi->rss)
|
if (!pi->rss)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
for (j = 0; j < pi->rss_size; j++)
|
|
||||||
pi->rss[j] = ethtool_rxfh_indir_default(j, pi->nqsets);
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3014,6 +3014,31 @@ int t4_config_glbl_rss(struct adapter *adapter, int mbox, unsigned int mode,
|
||||||
return t4_wr_mbox(adapter, mbox, &c, sizeof(c), NULL);
|
return t4_wr_mbox(adapter, mbox, &c, sizeof(c), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* t4_config_vi_rss - configure per VI RSS settings
|
||||||
|
* @adapter: the adapter
|
||||||
|
* @mbox: mbox to use for the FW command
|
||||||
|
* @viid: the VI id
|
||||||
|
* @flags: RSS flags
|
||||||
|
* @defq: id of the default RSS queue for the VI.
|
||||||
|
*
|
||||||
|
* Configures VI-specific RSS properties.
|
||||||
|
*/
|
||||||
|
int t4_config_vi_rss(struct adapter *adapter, int mbox, unsigned int viid,
|
||||||
|
unsigned int flags, unsigned int defq)
|
||||||
|
{
|
||||||
|
struct fw_rss_vi_config_cmd c;
|
||||||
|
|
||||||
|
memset(&c, 0, sizeof(c));
|
||||||
|
c.op_to_viid = cpu_to_be32(FW_CMD_OP_V(FW_RSS_VI_CONFIG_CMD) |
|
||||||
|
FW_CMD_REQUEST_F | FW_CMD_WRITE_F |
|
||||||
|
FW_RSS_VI_CONFIG_CMD_VIID_V(viid));
|
||||||
|
c.retval_len16 = cpu_to_be32(FW_LEN16(c));
|
||||||
|
c.u.basicvirtual.defaultq_to_udpen = cpu_to_be32(flags |
|
||||||
|
FW_RSS_VI_CONFIG_CMD_DEFAULTQ_V(defq));
|
||||||
|
return t4_wr_mbox(adapter, mbox, &c, sizeof(c), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* Read an RSS table row */
|
/* Read an RSS table row */
|
||||||
static int rd_rss_row(struct adapter *adap, int row, u32 *val)
|
static int rd_rss_row(struct adapter *adap, int row, u32 *val)
|
||||||
{
|
{
|
||||||
|
@ -5373,6 +5398,28 @@ int t4_filter_field_shift(const struct adapter *adap, int filter_sel)
|
||||||
return field_shift;
|
return field_shift;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int t4_init_rss_mode(struct adapter *adap, int mbox)
|
||||||
|
{
|
||||||
|
int i, ret;
|
||||||
|
struct fw_rss_vi_config_cmd rvc;
|
||||||
|
|
||||||
|
memset(&rvc, 0, sizeof(rvc));
|
||||||
|
|
||||||
|
for_each_port(adap, i) {
|
||||||
|
struct port_info *p = adap2pinfo(adap, i);
|
||||||
|
|
||||||
|
rvc.op_to_viid = htonl(FW_CMD_OP_V(FW_RSS_VI_CONFIG_CMD) |
|
||||||
|
FW_CMD_REQUEST_F | FW_CMD_READ_F |
|
||||||
|
FW_RSS_VI_CONFIG_CMD_VIID_V(p->viid));
|
||||||
|
rvc.retval_len16 = htonl(FW_LEN16(rvc));
|
||||||
|
ret = t4_wr_mbox(adap, mbox, &rvc, sizeof(rvc), &rvc);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
p->rss_mode = ntohl(rvc.u.basicvirtual.defaultq_to_udpen);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int t4_port_init(struct adapter *adap, int mbox, int pf, int vf)
|
int t4_port_init(struct adapter *adap, int mbox, int pf, int vf)
|
||||||
{
|
{
|
||||||
u8 addr[6];
|
u8 addr[6];
|
||||||
|
|
Loading…
Add table
Reference in a new issue