iw_cxgb.c revision 183289
1178786Skmacy/**************************************************************************
2178786Skmacy
3178786SkmacyCopyright (c) 2007, Chelsio Inc.
4178786SkmacyAll rights reserved.
5178786Skmacy
6178786SkmacyRedistribution and use in source and binary forms, with or without
7178786Skmacymodification, are permitted provided that the following conditions are met:
8178786Skmacy
9178786Skmacy 1. Redistributions of source code must retain the above copyright notice,
10178786Skmacy    this list of conditions and the following disclaimer.
11178786Skmacy
12178786Skmacy 2. Neither the name of the Chelsio Corporation nor the names of its
13178786Skmacy    contributors may be used to endorse or promote products derived from
14178786Skmacy    this software without specific prior written permission.
15178786Skmacy
16178786SkmacyTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17178786SkmacyAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18178786SkmacyIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19178786SkmacyARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20178786SkmacyLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21178786SkmacyCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22178786SkmacySUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23178786SkmacyINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24178786SkmacyCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25178786SkmacyARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26178786SkmacyPOSSIBILITY OF SUCH DAMAGE.
27178786Skmacy
28178786Skmacy***************************************************************************/
29178786Skmacy#include <sys/cdefs.h>
30178786Skmacy__FBSDID("$FreeBSD: head/sys/dev/cxgb/ulp/iw_cxgb/iw_cxgb.c 183289 2008-09-23 02:22:24Z kmacy $");
31178786Skmacy
32178786Skmacy#include <sys/param.h>
33178786Skmacy#include <sys/systm.h>
34178786Skmacy#include <sys/kernel.h>
35178786Skmacy#include <sys/bus.h>
36178786Skmacy#include <sys/module.h>
37178786Skmacy#include <sys/pciio.h>
38178786Skmacy#include <sys/conf.h>
39178786Skmacy#include <machine/bus.h>
40178786Skmacy#include <machine/resource.h>
41178786Skmacy#include <sys/bus_dma.h>
42178786Skmacy#include <sys/rman.h>
43178786Skmacy#include <sys/ioccom.h>
44178786Skmacy#include <sys/mbuf.h>
45178786Skmacy#include <sys/rwlock.h>
46178786Skmacy#include <sys/linker.h>
47178786Skmacy#include <sys/firmware.h>
48178786Skmacy#include <sys/socket.h>
49178786Skmacy#include <sys/sockio.h>
50178786Skmacy#include <sys/smp.h>
51178786Skmacy#include <sys/sysctl.h>
52178786Skmacy#include <sys/queue.h>
53178786Skmacy#include <sys/taskqueue.h>
54178786Skmacy#include <sys/proc.h>
55178786Skmacy#include <sys/eventhandler.h>
56183289Skmacy
57183289Skmacy#if __FreeBSD_version >= 800044
58182741Sjulian#include <sys/vimage.h>
59183289Skmacy#else
60183289Skmacy#define V_ifnet ifnet
61183289Skmacy#endif
62178786Skmacy
63178786Skmacy#include <net/if.h>
64178786Skmacy#include <net/if_var.h>
65178786Skmacy
66178786Skmacy#include <netinet/in.h>
67178786Skmacy
68178786Skmacy#include <contrib/rdma/ib_verbs.h>
69178786Skmacy
70178786Skmacy
71178786Skmacy#ifdef CONFIG_DEFINED
72178786Skmacy#include <cxgb_include.h>
73178786Skmacy#include <ulp/iw_cxgb/iw_cxgb_wr.h>
74178786Skmacy#include <ulp/iw_cxgb/iw_cxgb_hal.h>
75178786Skmacy#include <ulp/iw_cxgb/iw_cxgb_provider.h>
76178786Skmacy#include <ulp/iw_cxgb/iw_cxgb_cm.h>
77178786Skmacy#include <ulp/iw_cxgb/iw_cxgb.h>
78178786Skmacy#else
79178786Skmacy#include <dev/cxgb/cxgb_include.h>
80178786Skmacy#include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_wr.h>
81178786Skmacy#include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_hal.h>
82178786Skmacy#include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_provider.h>
83178786Skmacy#include <dev/cxgb/ulp/iw_cxgb/iw_cxgb_cm.h>
84178786Skmacy#include <dev/cxgb/ulp/iw_cxgb/iw_cxgb.h>
85178786Skmacy#endif
86178786Skmacy
87178786Skmacy/*
88178786Skmacy * XXX :-/
89178786Skmacy *
90178786Skmacy */
91178786Skmacy
92178786Skmacy#define idr_init(x)
93178786Skmacy
94178786Skmacycxgb_cpl_handler_func t3c_handlers[NUM_CPL_CMDS];
95178786Skmacy
96178786Skmacystatic void open_rnic_dev(struct t3cdev *);
97178786Skmacystatic void close_rnic_dev(struct t3cdev *);
98178786Skmacy
99178786Skmacystatic TAILQ_HEAD( ,iwch_dev) dev_list;
100178786Skmacystatic struct mtx dev_mutex;
101178786Skmacystatic eventhandler_tag event_tag;
102178786Skmacy
103178786Skmacystatic void
104178786Skmacyrnic_init(struct iwch_dev *rnicp)
105178786Skmacy{
106178786Skmacy	CTR2(KTR_IW_CXGB, "%s iwch_dev %p", __FUNCTION__,  rnicp);
107178786Skmacy	idr_init(&rnicp->cqidr);
108178786Skmacy	idr_init(&rnicp->qpidr);
109178786Skmacy	idr_init(&rnicp->mmidr);
110178786Skmacy	mtx_init(&rnicp->lock, "iwch rnic lock", NULL, MTX_DEF|MTX_DUPOK);
111178786Skmacy
112178786Skmacy	rnicp->attr.vendor_id = 0x168;
113178786Skmacy	rnicp->attr.vendor_part_id = 7;
114178786Skmacy	rnicp->attr.max_qps = T3_MAX_NUM_QP - 32;
115178786Skmacy	rnicp->attr.max_wrs = (1UL << 24) - 1;
116178786Skmacy	rnicp->attr.max_sge_per_wr = T3_MAX_SGE;
117178786Skmacy	rnicp->attr.max_sge_per_rdma_write_wr = T3_MAX_SGE;
118178786Skmacy	rnicp->attr.max_cqs = T3_MAX_NUM_CQ - 1;
119178786Skmacy	rnicp->attr.max_cqes_per_cq = (1UL << 24) - 1;
120178786Skmacy	rnicp->attr.max_mem_regs = cxio_num_stags(&rnicp->rdev);
121178786Skmacy	rnicp->attr.max_phys_buf_entries = T3_MAX_PBL_SIZE;
122178786Skmacy	rnicp->attr.max_pds = T3_MAX_NUM_PD - 1;
123178786Skmacy	rnicp->attr.mem_pgsizes_bitmask = 0x7FFF;	/* 4KB-128MB */
124178786Skmacy	rnicp->attr.can_resize_wq = 0;
125178786Skmacy	rnicp->attr.max_rdma_reads_per_qp = 8;
126178786Skmacy	rnicp->attr.max_rdma_read_resources =
127178786Skmacy	    rnicp->attr.max_rdma_reads_per_qp * rnicp->attr.max_qps;
128178786Skmacy	rnicp->attr.max_rdma_read_qp_depth = 8;	/* IRD */
129178786Skmacy	rnicp->attr.max_rdma_read_depth =
130178786Skmacy	    rnicp->attr.max_rdma_read_qp_depth * rnicp->attr.max_qps;
131178786Skmacy	rnicp->attr.rq_overflow_handled = 0;
132178786Skmacy	rnicp->attr.can_modify_ird = 0;
133178786Skmacy	rnicp->attr.can_modify_ord = 0;
134178786Skmacy	rnicp->attr.max_mem_windows = rnicp->attr.max_mem_regs - 1;
135178786Skmacy	rnicp->attr.stag0_value = 1;
136178786Skmacy	rnicp->attr.zbva_support = 1;
137178786Skmacy	rnicp->attr.local_invalidate_fence = 1;
138178786Skmacy	rnicp->attr.cq_overflow_detection = 1;
139178786Skmacy	return;
140178786Skmacy}
141178786Skmacy
142178786Skmacystatic void
143178786Skmacyopen_rnic_dev(struct t3cdev *tdev)
144178786Skmacy{
145178786Skmacy	struct iwch_dev *rnicp;
146178786Skmacy	static int vers_printed;
147178786Skmacy
148178786Skmacy	CTR2(KTR_IW_CXGB, "%s t3cdev %p", __FUNCTION__,  tdev);
149178786Skmacy	if (!vers_printed++)
150178786Skmacy		printf("Chelsio T3 RDMA Driver - version %s\n",
151178786Skmacy		       DRV_VERSION);
152178786Skmacy	rnicp = (struct iwch_dev *)ib_alloc_device(sizeof(*rnicp));
153178786Skmacy	if (!rnicp) {
154178786Skmacy		printf("Cannot allocate ib device\n");
155178786Skmacy		return;
156178786Skmacy	}
157178786Skmacy	rnicp->rdev.ulp = rnicp;
158178786Skmacy	rnicp->rdev.t3cdev_p = tdev;
159178786Skmacy
160178786Skmacy	mtx_lock(&dev_mutex);
161178786Skmacy
162178786Skmacy	if (cxio_rdev_open(&rnicp->rdev)) {
163178786Skmacy		mtx_unlock(&dev_mutex);
164178786Skmacy		printf("Unable to open CXIO rdev\n");
165178786Skmacy		ib_dealloc_device(&rnicp->ibdev);
166178786Skmacy		return;
167178786Skmacy	}
168178786Skmacy
169178786Skmacy	rnic_init(rnicp);
170178786Skmacy
171178786Skmacy	TAILQ_INSERT_TAIL(&dev_list, rnicp, entry);
172178786Skmacy	mtx_unlock(&dev_mutex);
173178786Skmacy
174178786Skmacy	if (iwch_register_device(rnicp)) {
175178786Skmacy		printf("Unable to register device\n");
176178786Skmacy		close_rnic_dev(tdev);
177178786Skmacy	}
178178786Skmacy#ifdef notyet
179178786Skmacy	printf("Initialized device %s\n",
180178786Skmacy	       pci_name(rnicp->rdev.rnic_info.pdev));
181178786Skmacy#endif
182178786Skmacy	return;
183178786Skmacy}
184178786Skmacy
185178786Skmacystatic void
186178786Skmacyclose_rnic_dev(struct t3cdev *tdev)
187178786Skmacy{
188178786Skmacy	struct iwch_dev *dev, *tmp;
189178786Skmacy	CTR2(KTR_IW_CXGB, "%s t3cdev %p", __FUNCTION__,  tdev);
190178786Skmacy	mtx_lock(&dev_mutex);
191178786Skmacy
192178786Skmacy	TAILQ_FOREACH_SAFE(dev, &dev_list, entry, tmp) {
193178786Skmacy		if (dev->rdev.t3cdev_p == tdev) {
194178786Skmacy#ifdef notyet
195178786Skmacy			list_del(&dev->entry);
196178786Skmacy			iwch_unregister_device(dev);
197178786Skmacy			cxio_rdev_close(&dev->rdev);
198178786Skmacy			idr_destroy(&dev->cqidr);
199178786Skmacy			idr_destroy(&dev->qpidr);
200178786Skmacy			idr_destroy(&dev->mmidr);
201178786Skmacy			ib_dealloc_device(&dev->ibdev);
202178786Skmacy#endif
203178786Skmacy			break;
204178786Skmacy		}
205178786Skmacy	}
206178786Skmacy	mtx_unlock(&dev_mutex);
207178786Skmacy}
208178786Skmacy
209178786Skmacystatic ifaddr_event_handler_t
210178786Skmacyifaddr_event_handler(void *arg, struct ifnet *ifp)
211178786Skmacy{
212178786Skmacy	printf("%s if name %s \n", __FUNCTION__, ifp->if_xname);
213178786Skmacy	if (ifp->if_capabilities & IFCAP_TOE4) {
214178786Skmacy		KASSERT(T3CDEV(ifp) != NULL, ("null t3cdev ptr!"));
215178786Skmacy		if (cxio_hal_find_rdev_by_t3cdev(T3CDEV(ifp)) == NULL)
216178786Skmacy			open_rnic_dev(T3CDEV(ifp));
217178786Skmacy	}
218178786Skmacy	return 0;
219178786Skmacy}
220178786Skmacy
221178786Skmacy
222178786Skmacystatic int
223178786Skmacyiwch_init_module(void)
224178786Skmacy{
225178786Skmacy	int err;
226178786Skmacy	struct ifnet *ifp;
227178786Skmacy
228178786Skmacy	printf("%s enter\n", __FUNCTION__);
229178786Skmacy	TAILQ_INIT(&dev_list);
230178786Skmacy	mtx_init(&dev_mutex, "iwch dev_list lock", NULL, MTX_DEF);
231178786Skmacy
232178786Skmacy	err = cxio_hal_init();
233178786Skmacy	if (err)
234178786Skmacy		return err;
235178786Skmacy	err = iwch_cm_init();
236178786Skmacy	if (err)
237178786Skmacy		return err;
238178786Skmacy	cxio_register_ev_cb(iwch_ev_dispatch);
239178786Skmacy
240178786Skmacy	/* Register for ifaddr events to dynamically add TOE devs */
241178786Skmacy	event_tag = EVENTHANDLER_REGISTER(ifaddr_event, ifaddr_event_handler,
242178786Skmacy			NULL, EVENTHANDLER_PRI_ANY);
243178786Skmacy
244178786Skmacy	/* Register existing TOE interfaces by walking the ifnet chain */
245178786Skmacy	IFNET_RLOCK();
246182741Sjulian	TAILQ_FOREACH(ifp, &V_ifnet, if_link) {
247178786Skmacy		(void)ifaddr_event_handler(NULL, ifp);
248178786Skmacy	}
249178786Skmacy	IFNET_RUNLOCK();
250178786Skmacy	return 0;
251178786Skmacy}
252178786Skmacy
253178786Skmacystatic void
254178786Skmacyiwch_exit_module(void)
255178786Skmacy{
256178786Skmacy	EVENTHANDLER_DEREGISTER(ifaddr_event, event_tag);
257178786Skmacy	cxio_unregister_ev_cb(iwch_ev_dispatch);
258178786Skmacy	iwch_cm_term();
259178786Skmacy	cxio_hal_exit();
260178786Skmacy}
261178786Skmacy
262178786Skmacystatic int
263178786Skmacyiwch_load(module_t mod, int cmd, void *arg)
264178786Skmacy{
265178786Skmacy        int err = 0;
266178786Skmacy
267178786Skmacy        switch (cmd) {
268178786Skmacy        case MOD_LOAD:
269178786Skmacy                printf("Loading iw_cxgb.\n");
270178786Skmacy
271178786Skmacy                iwch_init_module();
272178786Skmacy                break;
273178786Skmacy        case MOD_QUIESCE:
274178786Skmacy                break;
275178786Skmacy        case MOD_UNLOAD:
276178786Skmacy                printf("Unloading iw_cxgb.\n");
277178786Skmacy		iwch_exit_module();
278178786Skmacy                break;
279178786Skmacy        case MOD_SHUTDOWN:
280178786Skmacy                break;
281178786Skmacy        default:
282178786Skmacy                err = EOPNOTSUPP;
283178786Skmacy                break;
284178786Skmacy        }
285178786Skmacy
286178786Skmacy        return (err);
287178786Skmacy}
288178786Skmacy
289178786Skmacystatic moduledata_t mod_data = {
290178786Skmacy	"iw_cxgb",
291178786Skmacy	iwch_load,
292178786Skmacy	0
293178786Skmacy};
294178786Skmacy
295178786SkmacyMODULE_VERSION(iw_cxgb, 1);
296178786SkmacyDECLARE_MODULE(iw_cxgb, mod_data, SI_SUB_EXEC, SI_ORDER_ANY);
297178786SkmacyMODULE_DEPEND(iw_cxgb, rdma_core, 1, 1, 1);
298178786SkmacyMODULE_DEPEND(iw_cxgb, if_cxgb, 1, 1, 1);
299178786SkmacyMODULE_DEPEND(iw_cxgb, t3_tom, 1, 1, 1);
300178786Skmacy
301