diff options
author | Dimitris Michailidis <dm@chelsio.com> | 2010-08-23 13:20:58 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-08-23 23:38:13 -0400 |
commit | e46dab4d4be87769b09404135bc34f89e2e155d8 (patch) | |
tree | 65f0b0a321939c4b12d40e7674ce93c699c2843e /drivers/net | |
parent | f04b4dd2b1f533cef0507e0410ffc6732d21a272 (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')
-rw-r--r-- | drivers/net/cxgb4/cxgb4.h | 2 | ||||
-rw-r--r-- | drivers/net/cxgb4/cxgb4_main.c | 24 | ||||
-rw-r--r-- | drivers/net/cxgb4/sge.c | 15 | ||||
-rw-r--r-- | drivers/net/cxgb4/t4fw_api.h | 5 |
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 | */ | ||
664 | static 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 | */ |
663 | static void quiesce_rx(struct adapter *adap) | 673 | static 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 | ||
2093 | int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq, | 2096 | int 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 | /* |