Deleted Added
full compact
t4_sge.c (220643) t4_sge.c (220649)
1/*-
2 * Copyright (c) 2011 Chelsio Communications, Inc.
3 * All rights reserved.
4 * Written by: Navdeep Parhar <np@FreeBSD.org>
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 12 unchanged lines hidden (view full) ---

21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2011 Chelsio Communications, Inc.
3 * All rights reserved.
4 * Written by: Navdeep Parhar <np@FreeBSD.org>
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 12 unchanged lines hidden (view full) ---

21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD: head/sys/dev/cxgbe/t4_sge.c 220643 2011-04-14 20:06:23Z np $");
29__FBSDID("$FreeBSD: head/sys/dev/cxgbe/t4_sge.c 220649 2011-04-15 03:09:27Z np $");
30
31#include "opt_inet.h"
32
33#include <sys/types.h>
34#include <sys/mbuf.h>
35#include <sys/socket.h>
36#include <sys/kernel.h>
37#include <sys/malloc.h>

--- 236 unchanged lines hidden (view full) ---

274 if (rc != 0) {
275 device_printf(sc->dev,
276 "failed to create fwd intr queue %d: %d\n",
277 i, rc);
278 return (rc);
279 }
280 }
281
30
31#include "opt_inet.h"
32
33#include <sys/types.h>
34#include <sys/mbuf.h>
35#include <sys/socket.h>
36#include <sys/kernel.h>
37#include <sys/malloc.h>

--- 236 unchanged lines hidden (view full) ---

274 if (rc != 0) {
275 device_printf(sc->dev,
276 "failed to create fwd intr queue %d: %d\n",
277 i, rc);
278 return (rc);
279 }
280 }
281
282 handler = t4_intr_evt;
282 handler = t4_evt_rx;
283 i = 0; /* forward fwq's interrupt to the first fiq */
284 } else {
285 handler = NULL;
286 i = 1; /* fwq should use vector 1 (0 is used by error) */
287 }
288
289 snprintf(name, sizeof(name), "%s fwq", device_get_nameunit(sc->dev));
290 init_iq(fwq, sc, 0, 0, FW_IQ_QSIZE, FW_IQ_ESIZE, handler, name);

--- 49 unchanged lines hidden (view full) ---

340 }
341
342 for_each_rxq(pi, i, rxq) {
343
344 snprintf(name, sizeof(name), "%s rxq%d-iq",
345 device_get_nameunit(pi->dev), i);
346 init_iq(&rxq->iq, sc, pi->tmr_idx, pi->pktc_idx,
347 pi->qsize_rxq, RX_IQ_ESIZE,
283 i = 0; /* forward fwq's interrupt to the first fiq */
284 } else {
285 handler = NULL;
286 i = 1; /* fwq should use vector 1 (0 is used by error) */
287 }
288
289 snprintf(name, sizeof(name), "%s fwq", device_get_nameunit(sc->dev));
290 init_iq(fwq, sc, 0, 0, FW_IQ_QSIZE, FW_IQ_ESIZE, handler, name);

--- 49 unchanged lines hidden (view full) ---

340 }
341
342 for_each_rxq(pi, i, rxq) {
343
344 snprintf(name, sizeof(name), "%s rxq%d-iq",
345 device_get_nameunit(pi->dev), i);
346 init_iq(&rxq->iq, sc, pi->tmr_idx, pi->pktc_idx,
347 pi->qsize_rxq, RX_IQ_ESIZE,
348 sc->flags & INTR_FWD ? t4_intr_data: NULL, name);
348 sc->flags & INTR_FWD ? t4_eth_rx : NULL, name);
349
350 snprintf(name, sizeof(name), "%s rxq%d-fl",
351 device_get_nameunit(pi->dev), i);
352 init_fl(&rxq->fl, pi->qsize_rxq / 8, name);
353
354 if (sc->flags & INTR_FWD)
355 intr_idx = (pi->first_rxq + i) % NFIQ(sc);
356 else

--- 66 unchanged lines hidden (view full) ---

423t4_intr_fwd(void *arg)
424{
425 struct sge_iq *iq = arg, *q;
426 struct adapter *sc = iq->adapter;
427 struct rsp_ctrl *ctrl;
428 int ndesc_pending = 0, ndesc_total = 0;
429 int qid;
430
349
350 snprintf(name, sizeof(name), "%s rxq%d-fl",
351 device_get_nameunit(pi->dev), i);
352 init_fl(&rxq->fl, pi->qsize_rxq / 8, name);
353
354 if (sc->flags & INTR_FWD)
355 intr_idx = (pi->first_rxq + i) % NFIQ(sc);
356 else

--- 66 unchanged lines hidden (view full) ---

423t4_intr_fwd(void *arg)
424{
425 struct sge_iq *iq = arg, *q;
426 struct adapter *sc = iq->adapter;
427 struct rsp_ctrl *ctrl;
428 int ndesc_pending = 0, ndesc_total = 0;
429 int qid;
430
431 if (!atomic_cmpset_32(&iq->state, IQS_IDLE, IQS_BUSY))
432 return;
433
431 while (is_new_response(iq, &ctrl)) {
432
433 rmb();
434
435 /* Only interrupt muxing expected on this queue */
436 KASSERT(G_RSPD_TYPE(ctrl->u.type_gen) == X_RSPD_TYPE_INTR,
437 ("unexpected event on forwarded interrupt queue: %x",
438 G_RSPD_TYPE(ctrl->u.type_gen)));

--- 16 unchanged lines hidden (view full) ---

455 iq_next(iq);
456 }
457
458 if (ndesc_total > 0) {
459 t4_write_reg(sc, MYPF_REG(A_SGE_PF_GTS),
460 V_CIDXINC(ndesc_pending) | V_INGRESSQID((u32)iq->cntxt_id) |
461 V_SEINTARM(iq->intr_params));
462 }
434 while (is_new_response(iq, &ctrl)) {
435
436 rmb();
437
438 /* Only interrupt muxing expected on this queue */
439 KASSERT(G_RSPD_TYPE(ctrl->u.type_gen) == X_RSPD_TYPE_INTR,
440 ("unexpected event on forwarded interrupt queue: %x",
441 G_RSPD_TYPE(ctrl->u.type_gen)));

--- 16 unchanged lines hidden (view full) ---

458 iq_next(iq);
459 }
460
461 if (ndesc_total > 0) {
462 t4_write_reg(sc, MYPF_REG(A_SGE_PF_GTS),
463 V_CIDXINC(ndesc_pending) | V_INGRESSQID((u32)iq->cntxt_id) |
464 V_SEINTARM(iq->intr_params));
465 }
466
467 atomic_cmpset_32(&iq->state, IQS_BUSY, IQS_IDLE);
463}
464
465/* Deals with error interrupts */
466void
467t4_intr_err(void *arg)
468{
469 struct adapter *sc = arg;
470
471 if (sc->intr_type == INTR_INTX)
472 t4_write_reg(sc, MYPF_REG(A_PCIE_PF_CLI), 0);
473
474 t4_slow_intr_handler(sc);
475}
476
477/* Deals with the firmware event queue */
478void
479t4_intr_evt(void *arg)
480{
481 struct sge_iq *iq = arg;
468}
469
470/* Deals with error interrupts */
471void
472t4_intr_err(void *arg)
473{
474 struct adapter *sc = arg;
475
476 if (sc->intr_type == INTR_INTX)
477 t4_write_reg(sc, MYPF_REG(A_PCIE_PF_CLI), 0);
478
479 t4_slow_intr_handler(sc);
480}
481
482/* Deals with the firmware event queue */
483void
484t4_intr_evt(void *arg)
485{
486 struct sge_iq *iq = arg;
487
488 if (!atomic_cmpset_32(&iq->state, IQS_IDLE, IQS_BUSY))
489 return;
490
491 t4_evt_rx(arg);
492
493 atomic_cmpset_32(&iq->state, IQS_BUSY, IQS_IDLE);
494}
495
496void
497t4_intr_data(void *arg)
498{
499 struct sge_iq *iq = arg;
500
501 if (!atomic_cmpset_32(&iq->state, IQS_IDLE, IQS_BUSY))
502 return;
503
504 t4_eth_rx(arg);
505
506 atomic_cmpset_32(&iq->state, IQS_BUSY, IQS_IDLE);
507}
508
509void
510t4_evt_rx(void *arg)
511{
512 struct sge_iq *iq = arg;
482 struct adapter *sc = iq->adapter;
483 struct rsp_ctrl *ctrl;
484 const struct rss_header *rss;
485 int ndesc_pending = 0, ndesc_total = 0;
486
487 KASSERT(iq == &sc->sge.fwq, ("%s: unexpected ingress queue", __func__));
488
489 while (is_new_response(iq, &ctrl)) {

--- 42 unchanged lines hidden (view full) ---

532 if (ndesc_total > 0) {
533 t4_write_reg(sc, MYPF_REG(A_SGE_PF_GTS),
534 V_CIDXINC(ndesc_pending) | V_INGRESSQID(iq->cntxt_id) |
535 V_SEINTARM(iq->intr_params));
536 }
537}
538
539void
513 struct adapter *sc = iq->adapter;
514 struct rsp_ctrl *ctrl;
515 const struct rss_header *rss;
516 int ndesc_pending = 0, ndesc_total = 0;
517
518 KASSERT(iq == &sc->sge.fwq, ("%s: unexpected ingress queue", __func__));
519
520 while (is_new_response(iq, &ctrl)) {

--- 42 unchanged lines hidden (view full) ---

563 if (ndesc_total > 0) {
564 t4_write_reg(sc, MYPF_REG(A_SGE_PF_GTS),
565 V_CIDXINC(ndesc_pending) | V_INGRESSQID(iq->cntxt_id) |
566 V_SEINTARM(iq->intr_params));
567 }
568}
569
570void
540t4_intr_data(void *arg)
571t4_eth_rx(void *arg)
541{
542 struct sge_rxq *rxq = arg;
543 struct sge_iq *iq = arg;
544 struct adapter *sc = iq->adapter;
545 struct rsp_ctrl *ctrl;
546 struct ifnet *ifp = rxq->ifp;
547 struct sge_fl *fl = &rxq->fl;
548 struct fl_sdesc *sd = &fl->sdesc[fl->cidx], *sd_next;

--- 463 unchanged lines hidden (view full) ---

1012 struct fw_iq_cmd c;
1013 struct adapter *sc = iq->adapter;
1014 __be32 v = 0;
1015
1016 /* The adapter queues are nominally allocated in port[0]'s name */
1017 if (pi == NULL)
1018 pi = sc->port[0];
1019
572{
573 struct sge_rxq *rxq = arg;
574 struct sge_iq *iq = arg;
575 struct adapter *sc = iq->adapter;
576 struct rsp_ctrl *ctrl;
577 struct ifnet *ifp = rxq->ifp;
578 struct sge_fl *fl = &rxq->fl;
579 struct fl_sdesc *sd = &fl->sdesc[fl->cidx], *sd_next;

--- 463 unchanged lines hidden (view full) ---

1043 struct fw_iq_cmd c;
1044 struct adapter *sc = iq->adapter;
1045 __be32 v = 0;
1046
1047 /* The adapter queues are nominally allocated in port[0]'s name */
1048 if (pi == NULL)
1049 pi = sc->port[0];
1050
1020 mtx_init(&iq->iq_lock, iq->lockname, NULL, MTX_DEF);
1021
1022 len = iq->qsize * iq->esize;
1023 rc = alloc_ring(sc, len, &iq->desc_tag, &iq->desc_map, &iq->ba,
1024 (void **)&iq->desc);
1025 if (rc != 0)
1026 return (rc);
1027
1028 bzero(&c, sizeof(c));
1029 c.op_to_vfn = htobe32(V_FW_CMD_OP(FW_IQ_CMD) | F_FW_CMD_REQUEST |

--- 113 unchanged lines hidden (view full) ---

1143 FL_LOCK(fl);
1144 refill_fl(fl, -1);
1145 if (fl->pending >= 8)
1146 ring_fl_db(sc, fl);
1147 FL_UNLOCK(fl);
1148 }
1149
1150 /* Enable IQ interrupts */
1051 len = iq->qsize * iq->esize;
1052 rc = alloc_ring(sc, len, &iq->desc_tag, &iq->desc_map, &iq->ba,
1053 (void **)&iq->desc);
1054 if (rc != 0)
1055 return (rc);
1056
1057 bzero(&c, sizeof(c));
1058 c.op_to_vfn = htobe32(V_FW_CMD_OP(FW_IQ_CMD) | F_FW_CMD_REQUEST |

--- 113 unchanged lines hidden (view full) ---

1172 FL_LOCK(fl);
1173 refill_fl(fl, -1);
1174 if (fl->pending >= 8)
1175 ring_fl_db(sc, fl);
1176 FL_UNLOCK(fl);
1177 }
1178
1179 /* Enable IQ interrupts */
1180 atomic_store_rel_32(&iq->state, IQS_IDLE);
1151 t4_write_reg(sc, MYPF_REG(A_SGE_PF_GTS), V_SEINTARM(iq->intr_params) |
1152 V_INGRESSQID(iq->cntxt_id));
1153
1154 return (0);
1155}
1156
1157/*
1158 * This can be called with the iq/fl in any state - fully allocated and

--- 15 unchanged lines hidden (view full) ---

1174 rc = -t4_iq_start_stop(sc, sc->mbox, 0, sc->pf, 0,
1175 iq->cntxt_id, fl ? fl->cntxt_id : 0xffff, 0xffff);
1176 if (rc != 0) {
1177 device_printf(dev,
1178 "failed to stop queue %p: %d\n", iq, rc);
1179 return (rc);
1180 }
1181 iq->flags &= ~IQ_STARTED;
1181 t4_write_reg(sc, MYPF_REG(A_SGE_PF_GTS), V_SEINTARM(iq->intr_params) |
1182 V_INGRESSQID(iq->cntxt_id));
1183
1184 return (0);
1185}
1186
1187/*
1188 * This can be called with the iq/fl in any state - fully allocated and

--- 15 unchanged lines hidden (view full) ---

1204 rc = -t4_iq_start_stop(sc, sc->mbox, 0, sc->pf, 0,
1205 iq->cntxt_id, fl ? fl->cntxt_id : 0xffff, 0xffff);
1206 if (rc != 0) {
1207 device_printf(dev,
1208 "failed to stop queue %p: %d\n", iq, rc);
1209 return (rc);
1210 }
1211 iq->flags &= ~IQ_STARTED;
1212
1213 /* Synchronize with the interrupt handler */
1214 while (!atomic_cmpset_32(&iq->state, IQS_IDLE, IQS_DISABLED))
1215 pause("iqfree", hz / 1000);
1182 }
1183
1184 if (iq->flags & IQ_ALLOCATED) {
1185
1186 rc = -t4_iq_free(sc, sc->mbox, sc->pf, 0,
1187 FW_IQ_TYPE_FL_INT_CAP, iq->cntxt_id,
1188 fl ? fl->cntxt_id : 0xffff, 0xffff);
1189 if (rc != 0) {
1190 device_printf(dev,
1191 "failed to free queue %p: %d\n", iq, rc);
1192 return (rc);
1193 }
1194 iq->flags &= ~IQ_ALLOCATED;
1195 }
1196
1197 free_ring(sc, iq->desc_tag, iq->desc_map, iq->ba, iq->desc);
1198
1216 }
1217
1218 if (iq->flags & IQ_ALLOCATED) {
1219
1220 rc = -t4_iq_free(sc, sc->mbox, sc->pf, 0,
1221 FW_IQ_TYPE_FL_INT_CAP, iq->cntxt_id,
1222 fl ? fl->cntxt_id : 0xffff, 0xffff);
1223 if (rc != 0) {
1224 device_printf(dev,
1225 "failed to free queue %p: %d\n", iq, rc);
1226 return (rc);
1227 }
1228 iq->flags &= ~IQ_ALLOCATED;
1229 }
1230
1231 free_ring(sc, iq->desc_tag, iq->desc_map, iq->ba, iq->desc);
1232
1199 if (mtx_initialized(&iq->iq_lock))
1200 mtx_destroy(&iq->iq_lock);
1201
1202 bzero(iq, sizeof(*iq));
1203
1204 if (fl) {
1205 free_ring(sc, fl->desc_tag, fl->desc_map, fl->ba,
1206 fl->desc);
1207
1208 if (fl->sdesc) {
1209 FL_LOCK(fl);

--- 210 unchanged lines hidden (view full) ---

1420static int
1421free_txq(struct port_info *pi, struct sge_txq *txq)
1422{
1423 int rc;
1424 struct adapter *sc = pi->adapter;
1425 struct sge_eq *eq = &txq->eq;
1426
1427 if (eq->flags & (EQ_ALLOCATED | EQ_STARTED)) {
1233 bzero(iq, sizeof(*iq));
1234
1235 if (fl) {
1236 free_ring(sc, fl->desc_tag, fl->desc_map, fl->ba,
1237 fl->desc);
1238
1239 if (fl->sdesc) {
1240 FL_LOCK(fl);

--- 210 unchanged lines hidden (view full) ---

1451static int
1452free_txq(struct port_info *pi, struct sge_txq *txq)
1453{
1454 int rc;
1455 struct adapter *sc = pi->adapter;
1456 struct sge_eq *eq = &txq->eq;
1457
1458 if (eq->flags & (EQ_ALLOCATED | EQ_STARTED)) {
1459
1460 /*
1461 * Wait for the response to a credit flush if there's one
1462 * pending. Clearing the flag tells handle_sge_egr_update or
1463 * cxgbe_txq_start (depending on how far the response has made
1464 * it) that they should ignore the response and wake up free_txq
1465 * instead.
1466 *
1467 * The interface has been marked down by the time we get here
1468 * (both IFF_UP and IFF_DRV_RUNNING cleared). qflush has
1469 * emptied the tx buf_rings and we know nothing new is being
1470 * queued for tx so we don't have to worry about a new credit
1471 * flush request.
1472 */
1473 TXQ_LOCK(txq);
1474 if (eq->flags & EQ_CRFLUSHED) {
1475 eq->flags &= ~EQ_CRFLUSHED;
1476 msleep(txq, &eq->eq_lock, 0, "crflush", 0);
1477 }
1478 TXQ_UNLOCK(txq);
1479
1428 rc = -t4_eth_eq_free(sc, sc->mbox, sc->pf, 0, eq->cntxt_id);
1429 if (rc != 0) {
1430 device_printf(pi->dev,
1431 "failed to free egress queue %p: %d\n", eq, rc);
1432 return (rc);
1433 }
1434 eq->flags &= ~(EQ_ALLOCATED | EQ_STARTED);
1435 }

--- 1003 unchanged lines hidden (view full) ---

2439handle_sge_egr_update(struct adapter *sc, const struct cpl_sge_egr_update *cpl)
2440{
2441 unsigned int qid = G_EGR_QID(ntohl(cpl->opcode_qid));
2442 struct sge *s = &sc->sge;
2443 struct sge_txq *txq;
2444 struct port_info *pi;
2445
2446 txq = (void *)s->eqmap[qid - s->eq_start];
1480 rc = -t4_eth_eq_free(sc, sc->mbox, sc->pf, 0, eq->cntxt_id);
1481 if (rc != 0) {
1482 device_printf(pi->dev,
1483 "failed to free egress queue %p: %d\n", eq, rc);
1484 return (rc);
1485 }
1486 eq->flags &= ~(EQ_ALLOCATED | EQ_STARTED);
1487 }

--- 1003 unchanged lines hidden (view full) ---

2491handle_sge_egr_update(struct adapter *sc, const struct cpl_sge_egr_update *cpl)
2492{
2493 unsigned int qid = G_EGR_QID(ntohl(cpl->opcode_qid));
2494 struct sge *s = &sc->sge;
2495 struct sge_txq *txq;
2496 struct port_info *pi;
2497
2498 txq = (void *)s->eqmap[qid - s->eq_start];
2499 TXQ_LOCK(txq);
2500 if (txq->eq.flags & EQ_CRFLUSHED) {
2501 pi = txq->ifp->if_softc;
2502 taskqueue_enqueue(pi->tq, &txq->resume_tx);
2503 txq->egr_update++;
2504 } else
2505 wakeup_one(txq); /* txq is going away, wakeup free_txq */
2506 TXQ_UNLOCK(txq);
2447
2507
2448 KASSERT(txq->eq.flags & EQ_CRFLUSHED,
2449 ("%s: tx queue %p not expecting an update.", __func__, txq));
2450
2451 pi = txq->ifp->if_softc;
2452 taskqueue_enqueue(pi->tq, &txq->resume_tx);
2453 txq->egr_update++;
2454
2455 return (0);
2456}
2508 return (0);
2509}