Example #1
0
/*
 * Ground control to Major TOM
 * Commencing countdown, engines on
 */
static int
t3_tom_activate(struct adapter *sc)
{
	struct tom_data *td;
	struct toedev *tod;
	int i, rc = 0;
	struct mc5_params *mc5 = &sc->params.mc5;
	u_int ntids, natids, mtus;

	ADAPTER_LOCK_ASSERT_OWNED(sc);	/* for sc->flags */

	/* per-adapter softc for TOM */
	td = malloc(sizeof(*td), M_CXGB, M_ZERO | M_NOWAIT);
	if (td == NULL)
		return (ENOMEM);

	/* List of TOE PCBs and associated lock */
	mtx_init(&td->toep_list_lock, "PCB list lock", NULL, MTX_DEF);
	TAILQ_INIT(&td->toep_list);

	/* Listen context */
	mtx_init(&td->lctx_hash_lock, "lctx hash lock", NULL, MTX_DEF);
	td->listen_hash = hashinit_flags(LISTEN_HASH_SIZE, M_CXGB,
	    &td->listen_mask, HASH_NOWAIT);

	/* TID release task */
	TASK_INIT(&td->tid_release_task, 0 , t3_process_tid_release_list, td);
	mtx_init(&td->tid_release_lock, "tid release", NULL, MTX_DEF);

	/* L2 table */
	td->l2t = t3_init_l2t(L2T_SIZE);
	if (td->l2t == NULL) {
		rc = ENOMEM;
		goto done;
	}

	/* TID tables */
	ntids = t3_mc5_size(&sc->mc5) - mc5->nroutes - mc5->nfilters -
	    mc5->nservers;
	natids = min(ntids / 2, 64 * 1024);
	rc = alloc_tid_tabs(&td->tid_maps, ntids, natids, mc5->nservers,
	    0x100000 /* ATID_BASE */, ntids);
	if (rc != 0)
		goto done;

	/* CPL handlers */
	t3_init_listen_cpl_handlers(sc);
	t3_init_l2t_cpl_handlers(sc);
	t3_init_cpl_io(sc);

	/* toedev ops */
	tod = &td->tod;
	init_toedev(tod);
	tod->tod_softc = sc;
	tod->tod_connect = t3_connect;
	tod->tod_listen_start = t3_listen_start;
	tod->tod_listen_stop = t3_listen_stop;
	tod->tod_rcvd = t3_rcvd;
	tod->tod_output = t3_tod_output;
	tod->tod_send_rst = t3_send_rst;
	tod->tod_send_fin = t3_send_fin;
	tod->tod_pcb_detach = t3_pcb_detach;
	tod->tod_l2_update = t3_l2_update;
	tod->tod_syncache_added = t3_syncache_added;
	tod->tod_syncache_removed = t3_syncache_removed;
	tod->tod_syncache_respond = t3_syncache_respond;
	tod->tod_offload_socket = t3_offload_socket;

	/* port MTUs */
	mtus = sc->port[0].ifp->if_mtu;
	if (sc->params.nports > 1)
		mtus |= sc->port[1].ifp->if_mtu << 16;
	t3_write_reg(sc, A_TP_MTU_PORT_TABLE, mtus);
	t3_load_mtus(sc, sc->params.mtus, sc->params.a_wnd, sc->params.b_wnd,
	    sc->params.rev == 0 ? sc->port[0].ifp->if_mtu : 0xffff);

	/* SMT entry for each port */
	for_each_port(sc, i) {
		write_smt_entry(sc, i);
		TOEDEV(sc->port[i].ifp) = &td->tod;
	}
Example #2
0
int
cxgb_offload_activate(struct adapter *adapter)
{
	struct t3cdev *dev = &adapter->tdev;
	int natids, err;
	struct t3c_data *t;
	struct tid_range stid_range, tid_range;
	struct mtutab mtutab;
	unsigned int l2t_capacity;

	t = malloc(sizeof(*t), M_CXGB, M_NOWAIT|M_ZERO);
	if (!t)
		return (ENOMEM);
	dev->adapter = adapter;

	err = (EOPNOTSUPP);
	if (dev->ctl(dev, GET_TX_MAX_CHUNK, &t->tx_max_chunk) < 0 ||
	    dev->ctl(dev, GET_MAX_OUTSTANDING_WR, &t->max_wrs) < 0 ||
	    dev->ctl(dev, GET_L2T_CAPACITY, &l2t_capacity) < 0 ||
	    dev->ctl(dev, GET_MTUS, &mtutab) < 0 ||
	    dev->ctl(dev, GET_TID_RANGE, &tid_range) < 0 ||
	    dev->ctl(dev, GET_STID_RANGE, &stid_range) < 0) {
		device_printf(adapter->dev, "%s: dev->ctl check failed\n", __FUNCTION__);
		goto out_free;
	}
      
	err = (ENOMEM);
	L2DATA(dev) = t3_init_l2t(l2t_capacity);
	if (!L2DATA(dev)) {
		device_printf(adapter->dev, "%s: t3_init_l2t failed\n", __FUNCTION__);
		goto out_free;
	}
	natids = min(tid_range.num / 2, MAX_ATIDS);
	err = init_tid_tabs(&t->tid_maps, tid_range.num, natids,
			    stid_range.num, ATID_BASE, stid_range.base);
	if (err) {	
		device_printf(adapter->dev, "%s: init_tid_tabs failed\n", __FUNCTION__);
		goto out_free_l2t;
	}
	
	t->mtus = mtutab.mtus;
	t->nmtus = mtutab.size;

	TASK_INIT(&t->tid_release_task, 0 /* XXX? */, t3_process_tid_release_list, dev);
	mtx_init(&t->tid_release_lock, "tid release", NULL, MTX_DUPOK|MTX_DEF);
	t->dev = dev;

	T3C_DATA (dev) = t;
	dev->recv = process_rx;
	dev->arp_update = t3_l2t_update;
	/* Register netevent handler once */
	if (TAILQ_EMPTY(&adapter_list)) {
#if defined(CONFIG_CHELSIO_T3_MODULE)
		if (prepare_arp_with_t3core())
			log(LOG_ERR, "Unable to set offload capabilities\n");
#endif
	}
	CTR1(KTR_CXGB, "adding adapter %p", adapter); 
	add_adapter(adapter);
	device_printf(adapter->dev, "offload started\n");
	adapter->flags |= CXGB_OFLD_INIT;
	return (0);

out_free_l2t:
	t3_free_l2t(L2DATA(dev));
	L2DATA(dev) = NULL;
out_free:
	free(t, M_CXGB);
	return (err);
}