aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/cxgb4
diff options
context:
space:
mode:
authorDimitris Michailidis <dm@chelsio.com>2010-08-23 13:20:58 -0400
committerDavid S. Miller <davem@davemloft.net>2010-08-23 23:38:13 -0400
commite46dab4d4be87769b09404135bc34f89e2e155d8 (patch)
tree65f0b0a321939c4b12d40e7674ce93c699c2843e /drivers/net/cxgb4
parentf04b4dd2b1f533cef0507e0410ffc6732d21a272 (diff)
cxgb4: handle Rx/Tx queue ranges not starting at 0
Currently the driver assumes that queue IDs start at 0 but that's true only for function 0. To support operation on other functions get the start of the queue ranges from FW and offset accordingly. Signed-off-by: Dimitris Michailidis <dm@chelsio.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/cxgb4')
-rw-r--r--drivers/net/cxgb4/cxgb4.h2
-rw-r--r--drivers/net/cxgb4/cxgb4_main.c24
-rw-r--r--drivers/net/cxgb4/sge.c15
-rw-r--r--drivers/net/cxgb4/t4fw_api.h5
4 files changed, 35 insertions, 11 deletions
diff --git a/drivers/net/cxgb4/cxgb4.h b/drivers/net/cxgb4/cxgb4.h
index 6e562c0dad7d..3ece9f5069fa 100644
--- a/drivers/net/cxgb4/cxgb4.h
+++ b/drivers/net/cxgb4/cxgb4.h
@@ -463,6 +463,8 @@ struct sge {
463 u8 counter_val[SGE_NCOUNTERS]; 463 u8 counter_val[SGE_NCOUNTERS];
464 unsigned int starve_thres; 464 unsigned int starve_thres;
465 u8 idma_state[2]; 465 u8 idma_state[2];
466 unsigned int egr_start;
467 unsigned int ingr_start;
466 void *egr_map[MAX_EGRQ]; /* qid->queue egress queue map */ 468 void *egr_map[MAX_EGRQ]; /* qid->queue egress queue map */
467 struct sge_rspq *ingr_map[MAX_INGQ]; /* qid->queue ingress queue map */ 469 struct sge_rspq *ingr_map[MAX_INGQ]; /* qid->queue ingress queue map */
468 DECLARE_BITMAP(starving_fl, MAX_EGRQ); 470 DECLARE_BITMAP(starving_fl, MAX_EGRQ);
diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c
index c327527fbbc8..6e08e2d8eb3e 100644
--- a/drivers/net/cxgb4/cxgb4_main.c
+++ b/drivers/net/cxgb4/cxgb4_main.c
@@ -423,10 +423,11 @@ static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp,
423 if (likely(opcode == CPL_SGE_EGR_UPDATE)) { 423 if (likely(opcode == CPL_SGE_EGR_UPDATE)) {
424 const struct cpl_sge_egr_update *p = (void *)rsp; 424 const struct cpl_sge_egr_update *p = (void *)rsp;
425 unsigned int qid = EGR_QID(ntohl(p->opcode_qid)); 425 unsigned int qid = EGR_QID(ntohl(p->opcode_qid));
426 struct sge_txq *txq = q->adap->sge.egr_map[qid]; 426 struct sge_txq *txq;
427 427
428 txq = q->adap->sge.egr_map[qid - q->adap->sge.egr_start];
428 txq->restarts++; 429 txq->restarts++;
429 if ((u8 *)txq < (u8 *)q->adap->sge.ethrxq) { 430 if ((u8 *)txq < (u8 *)q->adap->sge.ofldtxq) {
430 struct sge_eth_txq *eq; 431 struct sge_eth_txq *eq;
431 432
432 eq = container_of(txq, struct sge_eth_txq, q); 433 eq = container_of(txq, struct sge_eth_txq, q);
@@ -658,6 +659,15 @@ static int setup_rss(struct adapter *adap)
658} 659}
659 660
660/* 661/*
662 * Return the channel of the ingress queue with the given qid.
663 */
664static unsigned int rxq_to_chan(const struct sge *p, unsigned int qid)
665{
666 qid -= p->ingr_start;
667 return netdev2pinfo(p->ingr_map[qid]->netdev)->tx_chan;
668}
669
670/*
661 * Wait until all NAPI handlers are descheduled. 671 * Wait until all NAPI handlers are descheduled.
662 */ 672 */
663static void quiesce_rx(struct adapter *adap) 673static void quiesce_rx(struct adapter *adap)
@@ -2304,7 +2314,7 @@ int cxgb4_create_server(const struct net_device *dev, unsigned int stid,
2304 req->peer_port = htons(0); 2314 req->peer_port = htons(0);
2305 req->local_ip = sip; 2315 req->local_ip = sip;
2306 req->peer_ip = htonl(0); 2316 req->peer_ip = htonl(0);
2307 chan = netdev2pinfo(adap->sge.ingr_map[queue]->netdev)->tx_chan; 2317 chan = rxq_to_chan(&adap->sge, queue);
2308 req->opt0 = cpu_to_be64(TX_CHAN(chan)); 2318 req->opt0 = cpu_to_be64(TX_CHAN(chan));
2309 req->opt1 = cpu_to_be64(CONN_POLICY_ASK | 2319 req->opt1 = cpu_to_be64(CONN_POLICY_ASK |
2310 SYN_RSS_ENABLE | SYN_RSS_QUEUE(queue)); 2320 SYN_RSS_ENABLE | SYN_RSS_QUEUE(queue));
@@ -2346,7 +2356,7 @@ int cxgb4_create_server6(const struct net_device *dev, unsigned int stid,
2346 req->local_ip_lo = *(__be64 *)(sip->s6_addr + 8); 2356 req->local_ip_lo = *(__be64 *)(sip->s6_addr + 8);
2347 req->peer_ip_hi = cpu_to_be64(0); 2357 req->peer_ip_hi = cpu_to_be64(0);
2348 req->peer_ip_lo = cpu_to_be64(0); 2358 req->peer_ip_lo = cpu_to_be64(0);
2349 chan = netdev2pinfo(adap->sge.ingr_map[queue]->netdev)->tx_chan; 2359 chan = rxq_to_chan(&adap->sge, queue);
2350 req->opt0 = cpu_to_be64(TX_CHAN(chan)); 2360 req->opt0 = cpu_to_be64(TX_CHAN(chan));
2351 req->opt1 = cpu_to_be64(CONN_POLICY_ASK | 2361 req->opt1 = cpu_to_be64(CONN_POLICY_ASK |
2352 SYN_RSS_ENABLE | SYN_RSS_QUEUE(queue)); 2362 SYN_RSS_ENABLE | SYN_RSS_QUEUE(queue));
@@ -3061,12 +3071,16 @@ static int adap_init0(struct adapter *adap)
3061 params[2] = FW_PARAM_PFVF(L2T_END); 3071 params[2] = FW_PARAM_PFVF(L2T_END);
3062 params[3] = FW_PARAM_PFVF(FILTER_START); 3072 params[3] = FW_PARAM_PFVF(FILTER_START);
3063 params[4] = FW_PARAM_PFVF(FILTER_END); 3073 params[4] = FW_PARAM_PFVF(FILTER_END);
3064 ret = t4_query_params(adap, adap->fn, adap->fn, 0, 5, params, val); 3074 params[5] = FW_PARAM_PFVF(IQFLINT_START);
3075 params[6] = FW_PARAM_PFVF(EQ_START);
3076 ret = t4_query_params(adap, adap->fn, adap->fn, 0, 7, params, val);
3065 if (ret < 0) 3077 if (ret < 0)
3066 goto bye; 3078 goto bye;
3067 port_vec = val[0]; 3079 port_vec = val[0];
3068 adap->tids.ftid_base = val[3]; 3080 adap->tids.ftid_base = val[3];
3069 adap->tids.nftids = val[4] - val[3] + 1; 3081 adap->tids.nftids = val[4] - val[3] + 1;
3082 adap->sge.ingr_start = val[5];
3083 adap->sge.egr_start = val[6];
3070 3084
3071 if (c.ofldcaps) { 3085 if (c.ofldcaps) {
3072 /* query offload-related parameters */ 3086 /* query offload-related parameters */
diff --git a/drivers/net/cxgb4/sge.c b/drivers/net/cxgb4/sge.c
index bf38cfc57565..44c2e6c9f073 100644
--- a/drivers/net/cxgb4/sge.c
+++ b/drivers/net/cxgb4/sge.c
@@ -557,7 +557,8 @@ out: cred = q->avail - cred;
557 557
558 if (unlikely(fl_starving(q))) { 558 if (unlikely(fl_starving(q))) {
559 smp_wmb(); 559 smp_wmb();
560 set_bit(q->cntxt_id, adap->sge.starving_fl); 560 set_bit(q->cntxt_id - adap->sge.egr_start,
561 adap->sge.starving_fl);
561 } 562 }
562 563
563 return cred; 564 return cred;
@@ -1213,7 +1214,8 @@ static void txq_stop_maperr(struct sge_ofld_txq *q)
1213{ 1214{
1214 q->mapping_err++; 1215 q->mapping_err++;
1215 q->q.stops++; 1216 q->q.stops++;
1216 set_bit(q->q.cntxt_id, q->adap->sge.txq_maperr); 1217 set_bit(q->q.cntxt_id - q->adap->sge.egr_start,
1218 q->adap->sge.txq_maperr);
1217} 1219}
1218 1220
1219/** 1221/**
@@ -1835,6 +1837,7 @@ static unsigned int process_intrq(struct adapter *adap)
1835 if (RSPD_TYPE(rc->type_gen) == RSP_TYPE_INTR) { 1837 if (RSPD_TYPE(rc->type_gen) == RSP_TYPE_INTR) {
1836 unsigned int qid = ntohl(rc->pldbuflen_qid); 1838 unsigned int qid = ntohl(rc->pldbuflen_qid);
1837 1839
1840 qid -= adap->sge.ingr_start;
1838 napi_schedule(&adap->sge.ingr_map[qid]->napi); 1841 napi_schedule(&adap->sge.ingr_map[qid]->napi);
1839 } 1842 }
1840 1843
@@ -2050,14 +2053,14 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,
2050 /* set offset to -1 to distinguish ingress queues without FL */ 2053 /* set offset to -1 to distinguish ingress queues without FL */
2051 iq->offset = fl ? 0 : -1; 2054 iq->offset = fl ? 0 : -1;
2052 2055
2053 adap->sge.ingr_map[iq->cntxt_id] = iq; 2056 adap->sge.ingr_map[iq->cntxt_id - adap->sge.ingr_start] = iq;
2054 2057
2055 if (fl) { 2058 if (fl) {
2056 fl->cntxt_id = ntohs(c.fl0id); 2059 fl->cntxt_id = ntohs(c.fl0id);
2057 fl->avail = fl->pend_cred = 0; 2060 fl->avail = fl->pend_cred = 0;
2058 fl->pidx = fl->cidx = 0; 2061 fl->pidx = fl->cidx = 0;
2059 fl->alloc_failed = fl->large_alloc_failed = fl->starving = 0; 2062 fl->alloc_failed = fl->large_alloc_failed = fl->starving = 0;
2060 adap->sge.egr_map[fl->cntxt_id] = fl; 2063 adap->sge.egr_map[fl->cntxt_id - adap->sge.egr_start] = fl;
2061 refill_fl(adap, fl, fl_cap(fl), GFP_KERNEL); 2064 refill_fl(adap, fl, fl_cap(fl), GFP_KERNEL);
2062 } 2065 }
2063 return 0; 2066 return 0;
@@ -2087,7 +2090,7 @@ static void init_txq(struct adapter *adap, struct sge_txq *q, unsigned int id)
2087 q->stops = q->restarts = 0; 2090 q->stops = q->restarts = 0;
2088 q->stat = (void *)&q->desc[q->size]; 2091 q->stat = (void *)&q->desc[q->size];
2089 q->cntxt_id = id; 2092 q->cntxt_id = id;
2090 adap->sge.egr_map[id] = q; 2093 adap->sge.egr_map[id - adap->sge.egr_start] = q;
2091} 2094}
2092 2095
2093int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq, 2096int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq,
@@ -2259,7 +2262,7 @@ static void free_rspq_fl(struct adapter *adap, struct sge_rspq *rq,
2259{ 2262{
2260 unsigned int fl_id = fl ? fl->cntxt_id : 0xffff; 2263 unsigned int fl_id = fl ? fl->cntxt_id : 0xffff;
2261 2264
2262 adap->sge.ingr_map[rq->cntxt_id] = NULL; 2265 adap->sge.ingr_map[rq->cntxt_id - adap->sge.ingr_start] = NULL;
2263 t4_iq_free(adap, adap->fn, adap->fn, 0, FW_IQ_TYPE_FL_INT_CAP, 2266 t4_iq_free(adap, adap->fn, adap->fn, 0, FW_IQ_TYPE_FL_INT_CAP,
2264 rq->cntxt_id, fl_id, 0xffff); 2267 rq->cntxt_id, fl_id, 0xffff);
2265 dma_free_coherent(adap->pdev_dev, (rq->size + 1) * rq->iqe_len, 2268 dma_free_coherent(adap->pdev_dev, (rq->size + 1) * rq->iqe_len,
diff --git a/drivers/net/cxgb4/t4fw_api.h b/drivers/net/cxgb4/t4fw_api.h
index 0969f2fbc1b0..940584a8a640 100644
--- a/drivers/net/cxgb4/t4fw_api.h
+++ b/drivers/net/cxgb4/t4fw_api.h
@@ -487,6 +487,11 @@ enum fw_params_param_pfvf {
487 FW_PARAMS_PARAM_PFVF_CPMASK = 0x25, 487 FW_PARAMS_PARAM_PFVF_CPMASK = 0x25,
488 FW_PARAMS_PARAM_PFVF_OCQ_START = 0x26, 488 FW_PARAMS_PARAM_PFVF_OCQ_START = 0x26,
489 FW_PARAMS_PARAM_PFVF_OCQ_END = 0x27, 489 FW_PARAMS_PARAM_PFVF_OCQ_END = 0x27,
490 FW_PARAMS_PARAM_PFVF_CONM_MAP = 0x28,
491 FW_PARAMS_PARAM_PFVF_IQFLINT_START = 0x29,
492 FW_PARAMS_PARAM_PFVF_IQFLINT_END = 0x2A,
493 FW_PARAMS_PARAM_PFVF_EQ_START = 0x2B,
494 FW_PARAMS_PARAM_PFVF_EQ_END = 0x2C,
490}; 495};
491 496
492/* 497/*