cxgb_sge.c (4af83c8cff85c89629e629b6becbf9712fa691c0) cxgb_sge.c (25292deb42c1c99213f6d603cf461b950691cc79)
1/**************************************************************************
2
3Copyright (c) 2007, Chelsio Inc.
4All rights reserved.
5
6Redistribution and use in source and binary forms, with or without
7modification, are permitted provided that the following conditions are met:
8

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

190 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
191 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
192#else
193# error "SGE_NUM_GENBITS must be 1 or 2"
194#endif
195};
196
197
1/**************************************************************************
2
3Copyright (c) 2007, Chelsio Inc.
4All rights reserved.
5
6Redistribution and use in source and binary forms, with or without
7modification, are permitted provided that the following conditions are met:
8

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

190 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
191 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
192#else
193# error "SGE_NUM_GENBITS must be 1 or 2"
194#endif
195};
196
197
198static int lro_default = 0;
199int cxgb_debug = 0;
200
201static void sge_timer_cb(void *arg);
202static void sge_timer_reclaim(void *arg, int ncount);
203static void sge_txq_reclaim_handler(void *arg, int ncount);
204
205/**
206 * reclaim_completed_tx - reclaims completed Tx descriptors

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

1764
1765 bus_dmamap_unload(q->rspq.desc_tag, q->rspq.desc_map);
1766 bus_dmamem_free(q->rspq.desc_tag, q->rspq.desc,
1767 q->rspq.desc_map);
1768 bus_dma_tag_destroy(q->rspq.desc_tag);
1769 MTX_DESTROY(&q->rspq.lock);
1770 }
1771
198int cxgb_debug = 0;
199
200static void sge_timer_cb(void *arg);
201static void sge_timer_reclaim(void *arg, int ncount);
202static void sge_txq_reclaim_handler(void *arg, int ncount);
203
204/**
205 * reclaim_completed_tx - reclaims completed Tx descriptors

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

1763
1764 bus_dmamap_unload(q->rspq.desc_tag, q->rspq.desc_map);
1765 bus_dmamem_free(q->rspq.desc_tag, q->rspq.desc,
1766 q->rspq.desc_map);
1767 bus_dma_tag_destroy(q->rspq.desc_tag);
1768 MTX_DESTROY(&q->rspq.lock);
1769 }
1770
1771 tcp_lro_free(&q->lro.ctrl);
1772
1772 bzero(q, sizeof(*q));
1773}
1774
1775/**
1776 * t3_free_sge_resources - free SGE resources
1777 * @sc: the adapter softc
1778 *
1779 * Frees resources used by the SGE queue sets.

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

2376 q->fl[1].zone = zone_jumbo9;
2377 q->fl[1].type = EXT_JUMBO9;
2378 }
2379#else
2380 q->fl[1].buf_size = MJUMPAGESIZE - header_size;
2381 q->fl[1].zone = zone_jumbop;
2382 q->fl[1].type = EXT_JUMBOP;
2383#endif
1773 bzero(q, sizeof(*q));
1774}
1775
1776/**
1777 * t3_free_sge_resources - free SGE resources
1778 * @sc: the adapter softc
1779 *
1780 * Frees resources used by the SGE queue sets.

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

2377 q->fl[1].zone = zone_jumbo9;
2378 q->fl[1].type = EXT_JUMBO9;
2379 }
2380#else
2381 q->fl[1].buf_size = MJUMPAGESIZE - header_size;
2382 q->fl[1].zone = zone_jumbop;
2383 q->fl[1].type = EXT_JUMBOP;
2384#endif
2384 q->lro.enabled = lro_default;
2385
2385
2386 /*
2387 * We allocate and setup the lro_ctrl structure irrespective of whether
2388 * lro is available and/or enabled.
2389 */
2390 q->lro.enabled = !!(pi->ifp->if_capenable & IFCAP_LRO);
2391 ret = tcp_lro_init(&q->lro.ctrl);
2392 if (ret) {
2393 printf("error %d from tcp_lro_init\n", ret);
2394 goto err;
2395 }
2396 q->lro.ctrl.ifp = pi->ifp;
2397
2386 mtx_lock_spin(&sc->sge.reg_lock);
2387 ret = -t3_sge_init_rspcntxt(sc, q->rspq.cntxt_id, irq_vec_idx,
2388 q->rspq.phys_addr, q->rspq.size,
2389 q->fl[0].buf_size, 1, 0);
2390 if (ret) {
2391 printf("error %d from t3_sge_init_rspcntxt\n", ret);
2392 goto err_unlock;
2393 }

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

2455err_unlock:
2456 mtx_unlock_spin(&sc->sge.reg_lock);
2457err:
2458 t3_free_qset(sc, q);
2459
2460 return (ret);
2461}
2462
2398 mtx_lock_spin(&sc->sge.reg_lock);
2399 ret = -t3_sge_init_rspcntxt(sc, q->rspq.cntxt_id, irq_vec_idx,
2400 q->rspq.phys_addr, q->rspq.size,
2401 q->fl[0].buf_size, 1, 0);
2402 if (ret) {
2403 printf("error %d from t3_sge_init_rspcntxt\n", ret);
2404 goto err_unlock;
2405 }

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

2467err_unlock:
2468 mtx_unlock_spin(&sc->sge.reg_lock);
2469err:
2470 t3_free_qset(sc, q);
2471
2472 return (ret);
2473}
2474
2475/*
2476 * Remove CPL_RX_PKT headers from the mbuf and reduce it to a regular mbuf with
2477 * ethernet data. Hardware assistance with various checksums and any vlan tag
2478 * will also be taken into account here.
2479 */
2463void
2464t3_rx_eth(struct adapter *adap, struct sge_rspq *rq, struct mbuf *m, int ethpad)
2465{
2466 struct cpl_rx_pkt *cpl = (struct cpl_rx_pkt *)(mtod(m, uint8_t *) + ethpad);
2467 struct port_info *pi = &adap->port[adap->rxpkt_map[cpl->iff]];
2468 struct ifnet *ifp = pi->ifp;
2469
2470 DPRINTF("rx_eth m=%p m->m_data=%p p->iff=%d\n", m, mtod(m, uint8_t *), cpl->iff);

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

2492 m_explode(m);
2493#endif
2494 /*
2495 * adjust after conversion to mbuf chain
2496 */
2497 m->m_pkthdr.len -= (sizeof(*cpl) + ethpad);
2498 m->m_len -= (sizeof(*cpl) + ethpad);
2499 m->m_data += (sizeof(*cpl) + ethpad);
2480void
2481t3_rx_eth(struct adapter *adap, struct sge_rspq *rq, struct mbuf *m, int ethpad)
2482{
2483 struct cpl_rx_pkt *cpl = (struct cpl_rx_pkt *)(mtod(m, uint8_t *) + ethpad);
2484 struct port_info *pi = &adap->port[adap->rxpkt_map[cpl->iff]];
2485 struct ifnet *ifp = pi->ifp;
2486
2487 DPRINTF("rx_eth m=%p m->m_data=%p p->iff=%d\n", m, mtod(m, uint8_t *), cpl->iff);

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

2509 m_explode(m);
2510#endif
2511 /*
2512 * adjust after conversion to mbuf chain
2513 */
2514 m->m_pkthdr.len -= (sizeof(*cpl) + ethpad);
2515 m->m_len -= (sizeof(*cpl) + ethpad);
2516 m->m_data += (sizeof(*cpl) + ethpad);
2500
2501 (*ifp->if_input)(ifp, m);
2502}
2503
2504static void
2505ext_free_handler(void *arg1, void * arg2)
2506{
2507 uintptr_t type = (uintptr_t)arg2;
2508 uma_zone_t zone;
2509 struct mbuf *m;

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

2779 */
2780int
2781process_responses(adapter_t *adap, struct sge_qset *qs, int budget)
2782{
2783 struct sge_rspq *rspq = &qs->rspq;
2784 struct rsp_desc *r = &rspq->desc[rspq->cidx];
2785 int budget_left = budget;
2786 unsigned int sleeping = 0;
2517}
2518
2519static void
2520ext_free_handler(void *arg1, void * arg2)
2521{
2522 uintptr_t type = (uintptr_t)arg2;
2523 uma_zone_t zone;
2524 struct mbuf *m;

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

2794 */
2795int
2796process_responses(adapter_t *adap, struct sge_qset *qs, int budget)
2797{
2798 struct sge_rspq *rspq = &qs->rspq;
2799 struct rsp_desc *r = &rspq->desc[rspq->cidx];
2800 int budget_left = budget;
2801 unsigned int sleeping = 0;
2787 int lro = qs->lro.enabled;
2802 int lro_enabled = qs->lro.enabled;
2803 struct lro_ctrl *lro_ctrl = &qs->lro.ctrl;
2788 struct mbuf *offload_mbufs[RX_BUNDLE_SIZE];
2789 int ngathered = 0;
2790#ifdef DEBUG
2791 static int last_holdoff = 0;
2792 if (cxgb_debug && rspq->holdoff_tmr != last_holdoff) {
2793 printf("next_holdoff=%d\n", rspq->holdoff_tmr);
2794 last_holdoff = rspq->holdoff_tmr;
2795 }

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

2892
2893
2894 ngathered = rx_offload(&adap->tdev, rspq,
2895 rspq->rspq_mh.mh_head, offload_mbufs, ngathered);
2896 rspq->rspq_mh.mh_head = NULL;
2897 DPRINTF("received offload packet\n");
2898
2899 } else if (eth && eop) {
2804 struct mbuf *offload_mbufs[RX_BUNDLE_SIZE];
2805 int ngathered = 0;
2806#ifdef DEBUG
2807 static int last_holdoff = 0;
2808 if (cxgb_debug && rspq->holdoff_tmr != last_holdoff) {
2809 printf("next_holdoff=%d\n", rspq->holdoff_tmr);
2810 last_holdoff = rspq->holdoff_tmr;
2811 }

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

2908
2909
2910 ngathered = rx_offload(&adap->tdev, rspq,
2911 rspq->rspq_mh.mh_head, offload_mbufs, ngathered);
2912 rspq->rspq_mh.mh_head = NULL;
2913 DPRINTF("received offload packet\n");
2914
2915 } else if (eth && eop) {
2900 prefetch(mtod(rspq->rspq_mh.mh_head, uint8_t *));
2901 prefetch(mtod(rspq->rspq_mh.mh_head, uint8_t *) + L1_CACHE_BYTES);
2916 struct mbuf *m = rspq->rspq_mh.mh_head;
2917 prefetch(mtod(m, uint8_t *));
2918 prefetch(mtod(m, uint8_t *) + L1_CACHE_BYTES);
2902
2919
2903 t3_rx_eth_lro(adap, rspq, rspq->rspq_mh.mh_head, ethpad,
2904 rss_hash, rss_csum, lro);
2920 t3_rx_eth(adap, rspq, m, ethpad);
2921 if (lro_enabled && lro_ctrl->lro_cnt &&
2922 (tcp_lro_rx(lro_ctrl, m, 0) == 0)) {
2923 /* successfully queue'd for LRO */
2924 } else {
2925 /*
2926 * LRO not enabled, packet unsuitable for LRO,
2927 * or unable to queue. Pass it up right now in
2928 * either case.
2929 */
2930 struct ifnet *ifp = m->m_pkthdr.rcvif;
2931 (*ifp->if_input)(ifp, m);
2932 }
2905 DPRINTF("received tunnel packet\n");
2933 DPRINTF("received tunnel packet\n");
2906 rspq->rspq_mh.mh_head = NULL;
2934 rspq->rspq_mh.mh_head = NULL;
2907
2908 }
2909 __refill_fl_lt(adap, &qs->fl[0], 32);
2910 __refill_fl_lt(adap, &qs->fl[1], 32);
2911 --budget_left;
2912 }
2913
2914 deliver_partial_bundle(&adap->tdev, rspq, offload_mbufs, ngathered);
2935
2936 }
2937 __refill_fl_lt(adap, &qs->fl[0], 32);
2938 __refill_fl_lt(adap, &qs->fl[1], 32);
2939 --budget_left;
2940 }
2941
2942 deliver_partial_bundle(&adap->tdev, rspq, offload_mbufs, ngathered);
2915 t3_lro_flush(adap, qs, &qs->lro);
2916
2943
2944 /* Flush LRO */
2945 while (!SLIST_EMPTY(&lro_ctrl->lro_active)) {
2946 struct lro_entry *queued = SLIST_FIRST(&lro_ctrl->lro_active);
2947 SLIST_REMOVE_HEAD(&lro_ctrl->lro_active, next);
2948 tcp_lro_flush(lro_ctrl, queued);
2949 }
2950
2917 if (sleeping)
2918 check_ring_db(adap, qs, sleeping);
2919
2920 smp_mb(); /* commit Tx queue processed updates */
2921 if (__predict_false(qs->txq_stopped > 1)) {
2922 printf("restarting tx on %p\n", qs);
2923
2924 restart_tx(qs);

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

3223 }
3224 sbuf_finish(sb);
3225 err = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1);
3226 sbuf_delete(sb);
3227 return (err);
3228}
3229
3230static int
2951 if (sleeping)
2952 check_ring_db(adap, qs, sleeping);
2953
2954 smp_mb(); /* commit Tx queue processed updates */
2955 if (__predict_false(qs->txq_stopped > 1)) {
2956 printf("restarting tx on %p\n", qs);
2957
2958 restart_tx(qs);

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

3257 }
3258 sbuf_finish(sb);
3259 err = SYSCTL_OUT(req, sbuf_data(sb), sbuf_len(sb) + 1);
3260 sbuf_delete(sb);
3261 return (err);
3262}
3263
3264static int
3231t3_lro_enable(SYSCTL_HANDLER_ARGS)
3232{
3233 adapter_t *sc;
3234 int i, j, enabled, err, nqsets = 0;
3235
3236#ifndef LRO_WORKING
3237 return (0);
3238#endif
3239 sc = arg1;
3240 enabled = sc->sge.qs[0].lro.enabled;
3241 err = sysctl_handle_int(oidp, &enabled, arg2, req);
3242
3243 if (err != 0)
3244 return (err);
3245 if (enabled == sc->sge.qs[0].lro.enabled)
3246 return (0);
3247
3248 for (i = 0; i < sc->params.nports; i++)
3249 for (j = 0; j < sc->port[i].nqsets; j++)
3250 nqsets++;
3251
3252 for (i = 0; i < nqsets; i++)
3253 sc->sge.qs[i].lro.enabled = enabled;
3254
3255 return (0);
3256}
3257
3258static int
3259t3_set_coalesce_usecs(SYSCTL_HANDLER_ARGS)
3260{
3261 adapter_t *sc = arg1;
3262 struct qset_params *qsp = &sc->params.sge.qset[0];
3263 int coalesce_usecs;
3264 struct sge_qset *qs;
3265 int i, j, err, nqsets = 0;
3266 struct mtx *lock;

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

3311 ctx = device_get_sysctl_ctx(sc->dev);
3312 children = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev));
3313
3314 /* random information */
3315 SYSCTL_ADD_STRING(ctx, children, OID_AUTO,
3316 "firmware_version",
3317 CTLFLAG_RD, &sc->fw_version,
3318 0, "firmware version");
3265t3_set_coalesce_usecs(SYSCTL_HANDLER_ARGS)
3266{
3267 adapter_t *sc = arg1;
3268 struct qset_params *qsp = &sc->params.sge.qset[0];
3269 int coalesce_usecs;
3270 struct sge_qset *qs;
3271 int i, j, err, nqsets = 0;
3272 struct mtx *lock;

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

3317 ctx = device_get_sysctl_ctx(sc->dev);
3318 children = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev));
3319
3320 /* random information */
3321 SYSCTL_ADD_STRING(ctx, children, OID_AUTO,
3322 "firmware_version",
3323 CTLFLAG_RD, &sc->fw_version,
3324 0, "firmware version");
3319
3320 SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
3321 "enable_lro",
3322 CTLTYPE_INT|CTLFLAG_RW, sc,
3323 0, t3_lro_enable,
3324 "I", "enable large receive offload");
3325 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
3326 "hw_revision",
3327 CTLFLAG_RD, &sc->params.rev,
3328 0, "chip model");
3329 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
3330 "enable_debug",
3331 CTLFLAG_RW, &cxgb_debug,
3332 0, "enable verbose debugging output");

--- 235 unchanged lines hidden ---
3325 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
3326 "hw_revision",
3327 CTLFLAG_RD, &sc->params.rev,
3328 0, "chip model");
3329 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
3330 "enable_debug",
3331 CTLFLAG_RW, &cxgb_debug,
3332 0, "enable verbose debugging output");

--- 235 unchanged lines hidden ---