kernel: Remove newlines from the panic messages that have one.
[dragonfly.git] / sys / dev / netif / iwl / if_iwl.c
1 /*
2  * Copyright (c) 2008 The DragonFly Project.  All rights reserved.
3  * 
4  * This code is derived from software contributed to The DragonFly Project
5  * by Sepherosa Ziehau <sepherosa@gmail.com>
6  * 
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name of The DragonFly Project nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific, prior written permission.
20  * 
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  * 
34  */
35
36 #include <sys/param.h>
37 #include <sys/bus.h>
38 #include <sys/endian.h>
39 #include <sys/kernel.h>
40 #include <sys/mbuf.h>
41 #include <sys/module.h>
42 #include <sys/msgport2.h>
43 #include <sys/sysctl.h>
44 #include <sys/socket.h>
45 #include <sys/sockio.h>
46 #include <sys/rman.h>
47
48 #include <net/bpf.h>
49 #include <net/if.h>
50 #include <net/if_arp.h>
51 #include <net/ethernet.h>
52 #include <net/if_dl.h>
53 #include <net/if_media.h>
54 #include <net/netmsg2.h>
55
56 #include <netproto/802_11/ieee80211_var.h>
57 #include <netproto/802_11/ieee80211_radiotap.h>
58
59 #include <bus/pci/pcidevs.h>
60 #include <bus/pci/pcireg.h>
61 #include <bus/pci/pcivar.h>
62
63 #include "if_iwlreg.h"
64 #include "if_iwlvar.h"
65 #include "iwl2100var.h"
66
67 struct iwl_devinfo {
68         const char      *desc;
69         int             bar;
70         int             (*attach)(device_t);
71         void            (*detach)(device_t);
72         int             (*shutdown)(device_t);
73 };
74
75 struct iwl_softc {
76         union {
77                 struct iwlcom common;
78                 struct iwl2100_softc sc2100;
79         } u;
80         const struct iwl_devinfo *sc_info;
81 };
82
83 static int      iwl_probe(device_t);
84 static int      iwl_attach(device_t);
85 static int      iwl_detach(device_t);
86 static int      iwl_shutdown(device_t);
87
88 static void     iwl_dma_ring_addr(void *, bus_dma_segment_t *, int, int);
89 static void     iwl_service_loop(void *);
90 static int      iwl_put_port(struct lwkt_port *, struct lwkt_msg *);
91 static void     iwl_destroy_thread_dispatch(struct netmsg *);
92
93 static const struct iwl_devinfo iwl2100_devinfo = {
94         .desc =         IWL2100_DESC,
95         .bar =          IWL2100_PCIR_BAR,
96         .attach =       iwl2100_attach,
97         .detach =       iwl2100_detach,
98         .shutdown =     iwl2100_shutdown
99 };
100
101 static const struct iwl_dev {
102         uint16_t        vid;
103         uint16_t        did;
104         const struct iwl_devinfo *info;
105 } iwl_devices[] = {
106         { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PRO_WL_2100, &iwl2100_devinfo },
107         { 0, 0, NULL }
108 };
109
110 static device_method_t iwl_methods[] = {
111         /* Device interface */
112         DEVMETHOD(device_probe,         iwl_probe),
113         DEVMETHOD(device_attach,        iwl_attach),
114         DEVMETHOD(device_detach,        iwl_detach),
115         DEVMETHOD(device_shutdown,      iwl_shutdown),
116
117         { 0, 0 }
118 };
119
120 static driver_t iwl_driver = {
121         "iwl",
122         iwl_methods,
123         sizeof(struct iwl_softc)
124 };
125
126 static devclass_t iwl_devclass;
127
128 DRIVER_MODULE(iwl, pci, iwl_driver, iwl_devclass, NULL, NULL);
129
130 MODULE_DEPEND(iwl, wlan, 1, 1, 1);
131 MODULE_DEPEND(iwl, pci, 1, 1, 1);
132
133 const struct ieee80211_rateset iwl_rateset_11b = { 4, { 2, 4, 11, 22 } };
134
135 static int
136 iwl_probe(device_t dev)
137 {
138         const struct iwl_dev *d;
139         uint16_t did, vid;
140
141         vid = pci_get_vendor(dev);
142         did = pci_get_device(dev);
143
144         for (d = iwl_devices; d->info != NULL; ++d) {
145                 if (d->did == did && d->vid == vid) {
146                         struct iwl_softc *sc = device_get_softc(dev);
147
148                         device_set_desc(dev, d->info->desc);
149                         sc->sc_info = d->info;
150                         return 0;
151                 }
152         }
153         return ENXIO;
154 }
155
156 static int
157 iwl_attach(device_t dev)
158 {
159         struct iwl_softc *sc = device_get_softc(dev);
160         struct iwlcom *iwl = &sc->u.common;
161         struct ifnet *ifp = &iwl->iwl_ic.ic_if;
162         int error, bar;
163
164         if_initname(ifp, device_get_name(dev), device_get_unit(dev));
165         bar = sc->sc_info->bar;
166
167 #ifndef BURN_BRIDGES
168         if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) {
169                 uint32_t irq, mem;
170
171                 irq = pci_read_config(dev, PCIR_INTLINE, 4);
172                 mem = pci_read_config(dev, bar, 4);
173
174                 device_printf(dev, "chip is in D%d power mode "
175                     "-- setting to D0\n", pci_get_powerstate(dev));
176
177                 pci_set_powerstate(dev, PCI_POWERSTATE_D0);
178
179                 pci_write_config(dev, PCIR_INTLINE, irq, 4);
180                 pci_write_config(dev, bar, mem, 4);
181         }
182 #endif  /* !BURN_BRIDGES */
183
184         /* Enable bus mastering */
185         pci_enable_busmaster(dev);
186
187         /*
188          * Allocate IO memory
189          */
190         iwl->iwl_mem_rid = bar;
191         iwl->iwl_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
192                                                   &iwl->iwl_mem_rid, RF_ACTIVE);
193         if (iwl->iwl_mem_res == NULL) {
194                 device_printf(dev, "can't allocate IO memory\n");
195                 return ENXIO;
196         }
197         iwl->iwl_mem_bt = rman_get_bustag(iwl->iwl_mem_res);
198         iwl->iwl_mem_bh = rman_get_bushandle(iwl->iwl_mem_res);
199
200         /*
201          * Allocate IRQ
202          */
203         iwl->iwl_irq_rid = 0;
204         iwl->iwl_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
205                                                   &iwl->iwl_irq_rid,
206                                                   RF_SHAREABLE | RF_ACTIVE);
207         if (iwl->iwl_irq_res == NULL) {
208                 device_printf(dev, "can't allocate irq\n");
209                 error = ENXIO;
210                 goto back;
211         }
212
213         /*
214          * Create sysctl tree
215          */
216         sysctl_ctx_init(&iwl->iwl_sysctl_ctx);
217         iwl->iwl_sysctl_tree = SYSCTL_ADD_NODE(&iwl->iwl_sysctl_ctx,
218                                                SYSCTL_STATIC_CHILDREN(_hw),
219                                                OID_AUTO,
220                                                device_get_nameunit(dev),
221                                                CTLFLAG_RD, 0, "");
222         if (iwl->iwl_sysctl_tree == NULL) {
223                 device_printf(dev, "can't add sysctl node\n");
224                 error = ENXIO;
225                 goto back;
226         }
227
228         /*
229          * Device specific attach
230          */
231         error = sc->sc_info->attach(dev);
232 back:
233         if (error)
234                 iwl_detach(dev);
235         return error;
236 }
237
238 static int
239 iwl_detach(device_t dev)
240 {
241         struct iwl_softc *sc = device_get_softc(dev);
242         struct iwlcom *iwl = &sc->u.common;
243
244         sc->sc_info->detach(dev);
245
246         if (iwl->iwl_sysctl_tree != NULL)
247                 sysctl_ctx_free(&iwl->iwl_sysctl_ctx);
248
249         if (iwl->iwl_irq_res != NULL) {
250                 bus_release_resource(dev, SYS_RES_IRQ, iwl->iwl_irq_rid,
251                                      iwl->iwl_irq_res);
252         }
253
254         if (iwl->iwl_mem_res != NULL) {
255                 bus_release_resource(dev, SYS_RES_MEMORY, iwl->iwl_mem_rid,
256                                      iwl->iwl_mem_res);
257         }
258         return 0;
259 }
260
261 static int
262 iwl_shutdown(device_t dev)
263 {
264         struct iwl_softc *sc = device_get_softc(dev);
265
266         return sc->sc_info->shutdown(dev);
267 }
268
269 void
270 iwl_ind_write_4(struct iwlcom *iwl, uint32_t addr, uint32_t data)
271 {
272         IWL_WRITE_4(iwl, IWL_IND_ADDR, addr);
273         IWL_WRITE_4(iwl, IWL_IND_DATA, data);
274 }
275
276 void
277 iwl_ind_write_2(struct iwlcom *iwl, uint32_t addr, uint16_t data)
278 {
279         IWL_WRITE_4(iwl, IWL_IND_ADDR, addr);
280         IWL_WRITE_2(iwl, IWL_IND_DATA, data);
281 }
282
283 void
284 iwl_ind_write_1(struct iwlcom *iwl, uint32_t addr, uint8_t data)
285 {
286         IWL_WRITE_4(iwl, IWL_IND_ADDR, addr);
287         IWL_WRITE_1(iwl, IWL_IND_DATA, data);
288 }
289
290 uint32_t
291 iwl_ind_read_4(struct iwlcom *iwl, uint32_t addr)
292 {
293         IWL_WRITE_4(iwl, IWL_IND_ADDR, addr);
294         return IWL_READ_4(iwl, IWL_IND_DATA);
295 }
296
297 uint16_t
298 iwl_ind_read_2(struct iwlcom *iwl, uint32_t addr)
299 {
300         IWL_WRITE_4(iwl, IWL_IND_ADDR, addr);
301         return IWL_READ_2(iwl, IWL_IND_DATA);
302 }
303
304 uint8_t
305 iwl_ind_read_1(struct iwlcom *iwl, uint32_t addr)
306 {
307         IWL_WRITE_4(iwl, IWL_IND_ADDR, addr);
308         return IWL_READ_1(iwl, IWL_IND_DATA);
309 }
310
311 #define EEPROM_WRITE(iwl, data) \
312 do { \
313         iwl_ind_write_4((iwl), IWL_EEPROM_IND_CSR, (data)); \
314         DELAY(1); \
315 } while (0)
316
317 #define EEPROM_SET_BIT(iwl) \
318 do { \
319         EEPROM_WRITE((iwl), IWL_EEBIT_CS | IWL_EEBIT_DI); \
320         EEPROM_WRITE((iwl), IWL_EEBIT_CS | IWL_EEBIT_DI | IWL_EEBIT_SK); \
321 } while (0)
322
323 #define EEPROM_CLR_BIT(iwl) \
324 do { \
325         EEPROM_WRITE((iwl), IWL_EEBIT_CS); \
326         EEPROM_WRITE((iwl), IWL_EEBIT_CS | IWL_EEBIT_SK); \
327 } while (0)
328
329 uint16_t
330 iwl_read_eeprom(struct iwlcom *iwl, uint8_t ofs)
331 {
332         uint16_t ret;
333         int i;
334
335         /* Chip select */
336         EEPROM_WRITE(iwl, 0);
337         EEPROM_WRITE(iwl, IWL_EEBIT_CS);
338         EEPROM_WRITE(iwl, IWL_EEBIT_CS | IWL_EEBIT_SK);
339         EEPROM_WRITE(iwl, IWL_EEBIT_CS);
340
341         /* Send READ opcode (0x2) */
342         EEPROM_SET_BIT(iwl);
343         EEPROM_SET_BIT(iwl); /* READ opcode */
344         EEPROM_CLR_BIT(iwl); /* READ opcode */
345
346         /* Send offset */
347         for (i = NBBY - 1; i >= 0; --i) {
348                 if (ofs & (1 << i))
349                         EEPROM_SET_BIT(iwl);
350                 else
351                         EEPROM_CLR_BIT(iwl);
352         }
353
354         /* Kick start */
355         EEPROM_WRITE(iwl, IWL_EEBIT_CS);
356
357         /* Read data */
358         ret = 0;
359         for (i = 0; i < (sizeof(ret) * NBBY); ++i) {
360                 EEPROM_WRITE(iwl, IWL_EEBIT_CS | IWL_EEBIT_SK);
361                 EEPROM_WRITE(iwl, IWL_EEBIT_CS);
362
363                 ret <<= 1;
364                 if (iwl_ind_read_4(iwl, IWL_EEPROM_IND_CSR) & IWL_EEBIT_DO)
365                         ret |= 1;
366         }
367
368         /* Stop */
369         EEPROM_WRITE(iwl, 0);
370
371         /* Chip de-select */
372         EEPROM_WRITE(iwl, IWL_EEBIT_CS);
373         EEPROM_WRITE(iwl, 0);
374         EEPROM_WRITE(iwl, IWL_EEBIT_SK);
375
376         return le16toh(ret);
377 }
378
379 static void
380 iwl_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error)
381 {
382         KASSERT(nseg == 1, ("too many segments"));
383         *((bus_addr_t *)arg) = seg->ds_addr;
384 }
385
386 int
387 iwl_dma_mem_create(device_t dev, bus_dma_tag_t parent, bus_size_t size,
388                    bus_dma_tag_t *dtag, void **addr, bus_addr_t *paddr,
389                    bus_dmamap_t *dmap)
390 {
391         int error;
392
393         error = bus_dma_tag_create(parent, IWL_ALIGN, 0,
394                                    BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,
395                                    NULL, NULL,
396                                    size, 1, BUS_SPACE_MAXSIZE_32BIT,
397                                    0, dtag);
398         if (error) {
399                 device_printf(dev, "can't create DMA tag\n");
400                 return error;
401         }
402
403         error = bus_dmamem_alloc(*dtag, addr, BUS_DMA_WAITOK | BUS_DMA_ZERO,
404                                  dmap);
405         if (error) {
406                 device_printf(dev, "can't allocate DMA mem\n");
407                 bus_dma_tag_destroy(*dtag);
408                 *dtag = NULL;
409                 return error;
410         }
411
412         error = bus_dmamap_load(*dtag, *dmap, *addr, size,
413                                 iwl_dma_ring_addr, paddr, BUS_DMA_WAITOK);
414         if (error) {
415                 device_printf(dev, "can't load DMA mem\n");
416                 bus_dmamem_free(*dtag, *addr, *dmap);
417                 bus_dma_tag_destroy(*dtag);
418                 *dtag = NULL;
419                 return error;
420         }
421         return 0;
422 }
423
424 void
425 iwl_dma_mem_destroy(bus_dma_tag_t dtag, void *addr, bus_dmamap_t dmap)
426 {
427         if (dtag != NULL) {
428                 bus_dmamap_unload(dtag, dmap);
429                 bus_dmamem_free(dtag, addr, dmap);
430                 bus_dma_tag_destroy(dtag);
431         }
432 }
433
434 void
435 iwl_dma_buf_addr(void *xctx, bus_dma_segment_t *segs, int nsegs,
436                  bus_size_t mapsz __unused, int error)
437 {
438         struct iwl_dmamap_ctx *ctx = xctx;
439         int i;
440
441         if (error)
442                 return;
443
444         if (nsegs > ctx->nsegs) {
445                 ctx->nsegs = 0;
446                 return;
447         }
448
449         ctx->nsegs = nsegs;
450         for (i = 0; i < nsegs; ++i)
451                 ctx->segs[i] = segs[i];
452 }
453
454 static int
455 iwl_put_port(struct lwkt_port *port, struct lwkt_msg *lmsg)
456 {
457         struct iwlmsg *msg = (struct iwlmsg *)lmsg;
458         struct iwlcom *iwl = msg->iwlm_softc;
459
460         ASSERT_SERIALIZED(port->mpu_serialize);
461
462         if ((lmsg->ms_flags & MSGF_SYNC) && curthread == &iwl->iwl_thread) {
463                 msg->iwlm_nmsg.nm_dispatch(&msg->iwlm_nmsg);
464                 if ((lmsg->ms_flags & MSGF_DONE) == 0) {
465                         panic("%s: self-referential deadlock on "
466                               "iwl thread port\n", __func__);
467                 }
468                 return EASYNC;
469         } else {
470                 return iwl->iwl_fwd_port(port, lmsg);
471         }
472 }
473
474 static void
475 iwl_service_loop(void *arg)
476 {
477         struct iwlcom *iwl = arg;
478         struct ifnet *ifp = &iwl->iwl_ic.ic_if;
479         struct netmsg *nmsg;
480
481         get_mplock();
482         lwkt_serialize_enter(ifp->if_serializer);
483         while ((nmsg = lwkt_waitport(&iwl->iwl_thread_port, 0))) {
484                 nmsg->nm_dispatch(nmsg);
485                 if (iwl->iwl_end)
486                         break;
487         }
488         lwkt_serialize_exit(ifp->if_serializer);
489         rel_mplock();
490 }
491
492 void
493 iwl_create_thread(struct iwlcom *iwl, int unit)
494 {
495         struct ifnet *ifp = &iwl->iwl_ic.ic_if;
496
497         lwkt_initport_serialize(&iwl->iwl_reply_port, ifp->if_serializer);
498         lwkt_initport_serialize(&iwl->iwl_thread_port, ifp->if_serializer);
499
500         /* NB: avoid self-reference domsg */
501         iwl->iwl_fwd_port = iwl->iwl_thread_port.mp_putport;
502         iwl->iwl_thread_port.mp_putport = iwl_put_port;
503
504         lwkt_create(iwl_service_loop, iwl, NULL, &iwl->iwl_thread,
505                     0, unit % ncpus, "iwl%d", unit);
506 }
507
508 static void
509 iwl_destroy_thread_dispatch(struct netmsg *nmsg)
510 {
511         struct iwlmsg *msg = (struct iwlmsg *)nmsg;
512         struct iwlcom *iwl = msg->iwlm_softc;
513
514         ASSERT_SERIALIZED(iwl->iwl_ic.ic_if.if_serializer);
515
516         iwl->iwl_end = 1;
517         lwkt_replymsg(&nmsg->nm_lmsg, 0);
518 }
519
520 void
521 iwl_destroy_thread(struct iwlcom *iwl)
522 {
523         struct iwlmsg msg;
524
525         ASSERT_SERIALIZED(iwl->iwl_ic.ic_if.if_serializer);
526
527         iwlmsg_init(&msg, &iwl->iwl_reply_port,
528                     iwl_destroy_thread_dispatch, iwl);
529         lwkt_domsg(&iwl->iwl_thread_port, &msg.iwlm_nmsg.nm_lmsg, 0);
530 }
531
532 void
533 iwlmsg_init(struct iwlmsg *msg, struct lwkt_port *rport, netisr_fn_t dispatch,
534             void *sc)
535 {
536         netmsg_init(&msg->iwlm_nmsg, NULL, rport, 0, dispatch);
537         msg->iwlm_softc = sc;
538 }
539
540 void
541 iwlmsg_send(struct iwlmsg *msg, struct lwkt_port *port)
542 {
543         struct lwkt_msg *lmsg;
544
545         lmsg = &msg->iwlm_nmsg.nm_lmsg;
546         if (lmsg->ms_flags & MSGF_DONE)
547                 lwkt_sendmsg(port, lmsg);
548 }