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:
Hariprasad Shenai 2015-05-06 19:48:37 +05:30 committed by David S. Miller
parent b2a6c326b2
commit c035e183eb
3 changed files with 80 additions and 7 deletions

View File

@ -1201,12 +1201,15 @@ int t4_init_devlog_params(struct adapter *adapter);
int t4_init_sge_params(struct adapter *adapter);
int t4_init_tp_params(struct adapter *adap);
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);
void t4_fatal_err(struct adapter *adapter);
int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid,
int start, int n, const u16 *rspq, unsigned int nrspq);
int t4_config_glbl_rss(struct adapter *adapter, int mbox, unsigned int mode,
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);
void t4_read_rss_key(struct adapter *adapter, u32 *key);
void t4_write_rss_key(struct adapter *adap, const u32 *key, int idx);

View File

@ -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
* 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)
{
u16 *rss;
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);
if (!rss)
return -ENOMEM;
/* map the queue indices to queue ids */
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);
/* 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);
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)
{
int i, err;
int i, j, err;
for_each_port(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);
if (err)
return err;
@ -4343,7 +4363,12 @@ static int enable_msix(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) {
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);
if (!pi->rss)
return -ENOMEM;
for (j = 0; j < pi->rss_size; j++)
pi->rss[j] = ethtool_rxfh_indir_default(j, pi->nqsets);
}
return 0;
}

View File

@ -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);
}
/**
* 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 */
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;
}
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)
{
u8 addr[6];