/* * 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; }
static int cxgb_offload_ctl(struct t3cdev *tdev, unsigned int req, void *data) { struct adapter *adapter = tdev2adap(tdev); struct tid_range *tid; struct mtutab *mtup; struct iff_mac *iffmacp; struct ddp_params *ddpp; struct adap_ports *ports; struct ofld_page_info *rx_page_info; struct tp_params *tp = &adapter->params.tp; int port; switch (req) { case GET_MAX_OUTSTANDING_WR: *(unsigned int *)data = FW_WR_NUM; break; case GET_WR_LEN: *(unsigned int *)data = WR_FLITS; break; case GET_TX_MAX_CHUNK: *(unsigned int *)data = 1 << 20; /* 1MB */ break; case GET_TID_RANGE: tid = data; tid->num = t3_mc5_size(&adapter->mc5) - adapter->params.mc5.nroutes - adapter->params.mc5.nfilters - adapter->params.mc5.nservers; tid->base = 0; break; case GET_STID_RANGE: tid = data; tid->num = adapter->params.mc5.nservers; tid->base = t3_mc5_size(&adapter->mc5) - tid->num - adapter->params.mc5.nfilters - adapter->params.mc5.nroutes; break; case GET_L2T_CAPACITY: *(unsigned int *)data = 2048; break; case GET_MTUS: mtup = data; mtup->size = NMTUS; mtup->mtus = adapter->params.mtus; break; case GET_IFF_FROM_MAC: iffmacp = data; iffmacp->dev = get_iff_from_mac(adapter, iffmacp->mac_addr, iffmacp->vlan_tag & EVL_VLID_MASK); break; case GET_DDP_PARAMS: ddpp = data; ddpp->llimit = t3_read_reg(adapter, A_ULPRX_TDDP_LLIMIT); ddpp->ulimit = t3_read_reg(adapter, A_ULPRX_TDDP_ULIMIT); ddpp->tag_mask = t3_read_reg(adapter, A_ULPRX_TDDP_TAGMASK); break; case GET_PORTS: ports = data; ports->nports = adapter->params.nports; for_each_port(adapter, port) ports->lldevs[port] = adapter->port[port].ifp; break; case FAILOVER: port = *(int *)data; t3_port_failover(adapter, port); failover_fixup(adapter, port); break; case FAILOVER_DONE: port = *(int *)data; t3_failover_done(adapter, port); break; case FAILOVER_CLEAR: t3_failover_clear(adapter); break; case GET_RX_PAGE_INFO: rx_page_info = data; rx_page_info->page_size = tp->rx_pg_size; rx_page_info->num = tp->rx_num_pgs; break; case ULP_ISCSI_GET_PARAMS: case ULP_ISCSI_SET_PARAMS: if (!offload_running(adapter)) return (EAGAIN); return cxgb_ulp_iscsi_ctl(adapter, req, data); case RDMA_GET_PARAMS: case RDMA_CQ_OP: case RDMA_CQ_SETUP: case RDMA_CQ_DISABLE: case RDMA_CTRL_QP_SETUP: case RDMA_GET_MEM: if (!offload_running(adapter)) return (EAGAIN); return cxgb_rdma_ctl(adapter, req, data); default: return (EOPNOTSUPP); } return 0; }