Commit c035e183 authored by Hariprasad Shenai's avatar Hariprasad Shenai Committed by David S. Miller

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: default avatarHariprasad Shenai <hariprasad@chelsio.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b2a6c326
...@@ -1201,12 +1201,15 @@ int t4_init_devlog_params(struct adapter *adapter); ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment