Home | History | Annotate | Line # | Download | only in usb
if_upgt.c revision 1.12.4.11
      1  1.12.4.11     skrll /*	$NetBSD: if_upgt.c,v 1.12.4.11 2016/04/30 08:48:09 skrll Exp $	*/
      2        1.1   tsutsui /*	$OpenBSD: if_upgt.c,v 1.49 2010/04/20 22:05:43 tedu Exp $ */
      3        1.1   tsutsui 
      4        1.1   tsutsui /*
      5        1.1   tsutsui  * Copyright (c) 2007 Marcus Glocker <mglocker (at) openbsd.org>
      6        1.1   tsutsui  *
      7        1.1   tsutsui  * Permission to use, copy, modify, and distribute this software for any
      8        1.1   tsutsui  * purpose with or without fee is hereby granted, provided that the above
      9        1.1   tsutsui  * copyright notice and this permission notice appear in all copies.
     10        1.1   tsutsui  *
     11        1.1   tsutsui  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     12        1.1   tsutsui  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     13        1.1   tsutsui  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     14        1.1   tsutsui  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     15        1.1   tsutsui  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     16        1.1   tsutsui  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     17        1.1   tsutsui  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     18        1.1   tsutsui  */
     19        1.1   tsutsui 
     20        1.1   tsutsui #include <sys/cdefs.h>
     21  1.12.4.11     skrll __KERNEL_RCSID(0, "$NetBSD: if_upgt.c,v 1.12.4.11 2016/04/30 08:48:09 skrll Exp $");
     22        1.1   tsutsui 
     23        1.1   tsutsui #include <sys/param.h>
     24        1.1   tsutsui #include <sys/callout.h>
     25        1.1   tsutsui #include <sys/device.h>
     26        1.1   tsutsui #include <sys/errno.h>
     27        1.1   tsutsui #include <sys/kernel.h>
     28        1.1   tsutsui #include <sys/kthread.h>
     29        1.1   tsutsui #include <sys/mbuf.h>
     30        1.1   tsutsui #include <sys/proc.h>
     31        1.1   tsutsui #include <sys/sockio.h>
     32        1.1   tsutsui #include <sys/systm.h>
     33        1.1   tsutsui #include <sys/vnode.h>
     34        1.1   tsutsui #include <sys/bus.h>
     35        1.1   tsutsui #include <sys/endian.h>
     36        1.1   tsutsui #include <sys/intr.h>
     37        1.1   tsutsui 
     38        1.1   tsutsui #include <net/bpf.h>
     39        1.1   tsutsui #include <net/if.h>
     40        1.1   tsutsui #include <net/if_arp.h>
     41        1.1   tsutsui #include <net/if_dl.h>
     42        1.1   tsutsui #include <net/if_ether.h>
     43        1.1   tsutsui #include <net/if_media.h>
     44        1.1   tsutsui #include <net/if_types.h>
     45        1.1   tsutsui 
     46        1.1   tsutsui #include <net80211/ieee80211_var.h>
     47        1.1   tsutsui #include <net80211/ieee80211_radiotap.h>
     48        1.1   tsutsui 
     49        1.1   tsutsui #include <dev/firmload.h>
     50        1.1   tsutsui 
     51        1.1   tsutsui #include <dev/usb/usb.h>
     52        1.1   tsutsui #include <dev/usb/usbdi.h>
     53        1.1   tsutsui #include <dev/usb/usbdi_util.h>
     54        1.6       mrg #include <dev/usb/usbdivar.h>
     55        1.1   tsutsui #include <dev/usb/usbdevs.h>
     56        1.1   tsutsui 
     57        1.1   tsutsui #include <dev/usb/if_upgtvar.h>
     58        1.1   tsutsui 
     59        1.1   tsutsui /*
     60        1.1   tsutsui  * Driver for the USB PrismGT devices.
     61        1.1   tsutsui  *
     62        1.1   tsutsui  * For now just USB 2.0 devices with the GW3887 chipset are supported.
     63        1.1   tsutsui  * The driver has been written based on the firmware version 2.13.1.0_LM87.
     64        1.1   tsutsui  *
     65        1.1   tsutsui  * TODO's:
     66        1.1   tsutsui  * - Fix MONITOR mode (MAC filter).
     67        1.1   tsutsui  * - Add HOSTAP mode.
     68        1.1   tsutsui  * - Add IBSS mode.
     69        1.1   tsutsui  * - Support the USB 1.0 devices (NET2280, ISL3880, ISL3886 chipsets).
     70        1.1   tsutsui  *
     71        1.1   tsutsui  * Parts of this driver has been influenced by reading the p54u driver
     72        1.1   tsutsui  * written by Jean-Baptiste Note <jean-baptiste.note (at) m4x.org> and
     73        1.1   tsutsui  * Sebastien Bourdeauducq <lekernel (at) prism54.org>.
     74        1.1   tsutsui  */
     75        1.1   tsutsui 
     76        1.1   tsutsui #ifdef UPGT_DEBUG
     77        1.1   tsutsui int upgt_debug = 2;
     78        1.1   tsutsui #define DPRINTF(l, x...) do { if ((l) <= upgt_debug) printf(x); } while (0)
     79        1.1   tsutsui #else
     80        1.1   tsutsui #define DPRINTF(l, x...)
     81        1.1   tsutsui #endif
     82        1.1   tsutsui 
     83        1.1   tsutsui /*
     84        1.1   tsutsui  * Prototypes.
     85        1.1   tsutsui  */
     86        1.1   tsutsui static int	upgt_match(device_t, cfdata_t, void *);
     87        1.1   tsutsui static void	upgt_attach(device_t, device_t, void *);
     88        1.1   tsutsui static int	upgt_detach(device_t, int);
     89        1.1   tsutsui static int	upgt_activate(device_t, devact_t);
     90        1.1   tsutsui 
     91        1.1   tsutsui static void	upgt_attach_hook(device_t);
     92        1.1   tsutsui static int	upgt_device_type(struct upgt_softc *, uint16_t, uint16_t);
     93        1.1   tsutsui static int	upgt_device_init(struct upgt_softc *);
     94        1.1   tsutsui static int	upgt_mem_init(struct upgt_softc *);
     95        1.1   tsutsui static uint32_t	upgt_mem_alloc(struct upgt_softc *);
     96        1.1   tsutsui static void	upgt_mem_free(struct upgt_softc *, uint32_t);
     97        1.1   tsutsui static int	upgt_fw_alloc(struct upgt_softc *);
     98        1.1   tsutsui static void	upgt_fw_free(struct upgt_softc *);
     99        1.1   tsutsui static int	upgt_fw_verify(struct upgt_softc *);
    100        1.1   tsutsui static int	upgt_fw_load(struct upgt_softc *);
    101        1.1   tsutsui static int	upgt_fw_copy(char *, char *, int);
    102        1.1   tsutsui static int	upgt_eeprom_read(struct upgt_softc *);
    103        1.1   tsutsui static int	upgt_eeprom_parse(struct upgt_softc *);
    104        1.1   tsutsui static void	upgt_eeprom_parse_hwrx(struct upgt_softc *, uint8_t *);
    105        1.1   tsutsui static void	upgt_eeprom_parse_freq3(struct upgt_softc *, uint8_t *, int);
    106        1.1   tsutsui static void	upgt_eeprom_parse_freq4(struct upgt_softc *, uint8_t *, int);
    107        1.1   tsutsui static void	upgt_eeprom_parse_freq6(struct upgt_softc *, uint8_t *, int);
    108        1.1   tsutsui 
    109        1.1   tsutsui static int	upgt_ioctl(struct ifnet *, u_long, void *);
    110        1.1   tsutsui static int	upgt_init(struct ifnet *);
    111        1.1   tsutsui static void	upgt_stop(struct upgt_softc *);
    112        1.1   tsutsui static int	upgt_media_change(struct ifnet *);
    113        1.1   tsutsui static void	upgt_newassoc(struct ieee80211_node *, int);
    114        1.1   tsutsui static int	upgt_newstate(struct ieee80211com *, enum ieee80211_state,
    115        1.1   tsutsui 		    int);
    116        1.1   tsutsui static void	upgt_newstate_task(void *);
    117        1.1   tsutsui static void	upgt_next_scan(void *);
    118        1.1   tsutsui static void	upgt_start(struct ifnet *);
    119        1.1   tsutsui static void	upgt_watchdog(struct ifnet *);
    120        1.1   tsutsui static void	upgt_tx_task(void *);
    121        1.1   tsutsui static void	upgt_tx_done(struct upgt_softc *, uint8_t *);
    122   1.12.4.4     skrll static void	upgt_rx_cb(struct usbd_xfer *, void *, usbd_status);
    123        1.1   tsutsui static void	upgt_rx(struct upgt_softc *, uint8_t *, int);
    124        1.1   tsutsui static void	upgt_setup_rates(struct upgt_softc *);
    125        1.1   tsutsui static uint8_t	upgt_rx_rate(struct upgt_softc *, const int);
    126   1.12.4.3     skrll static int	upgt_set_macfilter(struct upgt_softc *, uint8_t);
    127        1.1   tsutsui static int	upgt_set_channel(struct upgt_softc *, unsigned);
    128        1.1   tsutsui static void	upgt_set_led(struct upgt_softc *, int);
    129        1.1   tsutsui static void	upgt_set_led_blink(void *);
    130        1.1   tsutsui static int	upgt_get_stats(struct upgt_softc *);
    131        1.1   tsutsui 
    132        1.1   tsutsui static int	upgt_alloc_tx(struct upgt_softc *);
    133        1.1   tsutsui static int	upgt_alloc_rx(struct upgt_softc *);
    134        1.1   tsutsui static int	upgt_alloc_cmd(struct upgt_softc *);
    135        1.1   tsutsui static void	upgt_free_tx(struct upgt_softc *);
    136        1.1   tsutsui static void	upgt_free_rx(struct upgt_softc *);
    137        1.1   tsutsui static void	upgt_free_cmd(struct upgt_softc *);
    138        1.1   tsutsui static int	upgt_bulk_xmit(struct upgt_softc *, struct upgt_data *,
    139   1.12.4.4     skrll 		    struct usbd_pipe *, uint32_t *, int);
    140        1.1   tsutsui 
    141        1.1   tsutsui #if 0
    142        1.1   tsutsui static void	upgt_hexdump(void *, int);
    143        1.1   tsutsui #endif
    144        1.1   tsutsui static uint32_t	upgt_crc32_le(const void *, size_t);
    145        1.1   tsutsui static uint32_t	upgt_chksum_le(const uint32_t *, size_t);
    146        1.1   tsutsui 
    147        1.1   tsutsui CFATTACH_DECL_NEW(upgt, sizeof(struct upgt_softc),
    148        1.1   tsutsui 	upgt_match, upgt_attach, upgt_detach, upgt_activate);
    149        1.1   tsutsui 
    150        1.1   tsutsui static const struct usb_devno upgt_devs_1[] = {
    151        1.1   tsutsui 	/* version 1 devices */
    152       1.11     zafer 	{ USB_VENDOR_ALCATELT,		USB_PRODUCT_ALCATELT_ST120G },
    153       1.11     zafer 	{ USB_VENDOR_SMC,		USB_PRODUCT_SMC_2862WG_V1 }
    154        1.1   tsutsui };
    155        1.1   tsutsui 
    156        1.1   tsutsui static const struct usb_devno upgt_devs_2[] = {
    157        1.1   tsutsui 	/* version 2 devices */
    158        1.1   tsutsui 	{ USB_VENDOR_ACCTON,		USB_PRODUCT_ACCTON_PRISM_GT },
    159        1.1   tsutsui 	{ USB_VENDOR_ALCATELT,		USB_PRODUCT_ALCATELT_ST121G },
    160        1.1   tsutsui 	{ USB_VENDOR_BELKIN,		USB_PRODUCT_BELKIN_F5D7050 },
    161        1.1   tsutsui 	{ USB_VENDOR_CISCOLINKSYS,	USB_PRODUCT_CISCOLINKSYS_WUSB54AG },
    162        1.1   tsutsui 	{ USB_VENDOR_CISCOLINKSYS,	USB_PRODUCT_CISCOLINKSYS_WUSB54GV2 },
    163        1.1   tsutsui 	{ USB_VENDOR_CONCEPTRONIC2,	USB_PRODUCT_CONCEPTRONIC2_PRISM_GT },
    164        1.1   tsutsui 	{ USB_VENDOR_COREGA,		USB_PRODUCT_COREGA_CGWLUSB2GTST },
    165        1.1   tsutsui 	{ USB_VENDOR_DELL,		USB_PRODUCT_DELL_PRISM_GT_1 },
    166        1.1   tsutsui 	{ USB_VENDOR_DELL,		USB_PRODUCT_DELL_PRISM_GT_2 },
    167        1.1   tsutsui 	{ USB_VENDOR_DLINK,		USB_PRODUCT_DLINK_DWLG122A2 },
    168        1.1   tsutsui 	{ USB_VENDOR_FSC,		USB_PRODUCT_FSC_E5400 },
    169        1.1   tsutsui 	{ USB_VENDOR_GLOBESPAN,		USB_PRODUCT_GLOBESPAN_PRISM_GT_1 },
    170        1.1   tsutsui 	{ USB_VENDOR_GLOBESPAN,		USB_PRODUCT_GLOBESPAN_PRISM_GT_2 },
    171        1.1   tsutsui 	{ USB_VENDOR_INTERSIL,		USB_PRODUCT_INTERSIL_PRISM_GT },
    172        1.1   tsutsui 	{ USB_VENDOR_PHEENET,		USB_PRODUCT_PHEENET_GWU513 },
    173        1.1   tsutsui 	{ USB_VENDOR_PHILIPS,		USB_PRODUCT_PHILIPS_CPWUA054 },
    174        1.1   tsutsui 	{ USB_VENDOR_SHARP,		USB_PRODUCT_SHARP_RUITZ1016YCZZ },
    175        1.1   tsutsui 	{ USB_VENDOR_SMC,		USB_PRODUCT_SMC_2862WG },
    176        1.1   tsutsui 	{ USB_VENDOR_USR,		USB_PRODUCT_USR_USR5422 },
    177        1.1   tsutsui 	{ USB_VENDOR_WISTRONNEWEB,	USB_PRODUCT_WISTRONNEWEB_UR045G },
    178       1.12     ryoon 	{ USB_VENDOR_CONEXANT,		USB_PRODUCT_CONEXANT_PRISM_GT_1 },
    179       1.12     ryoon 	{ USB_VENDOR_CONEXANT,		USB_PRODUCT_CONEXANT_PRISM_GT_2 },
    180        1.1   tsutsui 	{ USB_VENDOR_ZCOM,		USB_PRODUCT_ZCOM_MD40900 },
    181        1.1   tsutsui 	{ USB_VENDOR_ZCOM,		USB_PRODUCT_ZCOM_XG703A }
    182        1.1   tsutsui };
    183        1.1   tsutsui 
    184        1.1   tsutsui static int
    185        1.1   tsutsui firmware_load(const char *dname, const char *iname, uint8_t **ucodep,
    186        1.1   tsutsui     size_t *sizep)
    187        1.1   tsutsui {
    188        1.1   tsutsui 	firmware_handle_t fh;
    189        1.1   tsutsui 	int error;
    190        1.1   tsutsui 
    191        1.1   tsutsui 	if ((error = firmware_open(dname, iname, &fh)) != 0)
    192        1.1   tsutsui 		return error;
    193        1.1   tsutsui 	*sizep = firmware_get_size(fh);
    194        1.1   tsutsui 	if ((*ucodep = firmware_malloc(*sizep)) == NULL) {
    195        1.1   tsutsui 		firmware_close(fh);
    196        1.1   tsutsui 		return ENOMEM;
    197        1.1   tsutsui 	}
    198        1.1   tsutsui 	if ((error = firmware_read(fh, 0, *ucodep, *sizep)) != 0)
    199        1.1   tsutsui 		firmware_free(*ucodep, *sizep);
    200        1.1   tsutsui 	firmware_close(fh);
    201        1.1   tsutsui 
    202        1.1   tsutsui 	return error;
    203        1.1   tsutsui }
    204        1.1   tsutsui 
    205        1.1   tsutsui static int
    206        1.1   tsutsui upgt_match(device_t parent, cfdata_t match, void *aux)
    207        1.1   tsutsui {
    208        1.1   tsutsui 	struct usb_attach_arg *uaa = aux;
    209        1.1   tsutsui 
    210   1.12.4.5     skrll 	if (usb_lookup(upgt_devs_1, uaa->uaa_vendor, uaa->uaa_product) != NULL)
    211        1.1   tsutsui 		return UMATCH_VENDOR_PRODUCT;
    212        1.1   tsutsui 
    213   1.12.4.5     skrll 	if (usb_lookup(upgt_devs_2, uaa->uaa_vendor, uaa->uaa_product) != NULL)
    214        1.1   tsutsui 		return UMATCH_VENDOR_PRODUCT;
    215        1.1   tsutsui 
    216        1.1   tsutsui 	return UMATCH_NONE;
    217        1.1   tsutsui }
    218        1.1   tsutsui 
    219        1.1   tsutsui static void
    220        1.1   tsutsui upgt_attach(device_t parent, device_t self, void *aux)
    221        1.1   tsutsui {
    222        1.1   tsutsui 	struct upgt_softc *sc = device_private(self);
    223        1.1   tsutsui 	struct usb_attach_arg *uaa = aux;
    224        1.1   tsutsui 	usb_interface_descriptor_t *id;
    225        1.1   tsutsui 	usb_endpoint_descriptor_t *ed;
    226        1.1   tsutsui 	usbd_status error;
    227        1.1   tsutsui 	char *devinfop;
    228        1.1   tsutsui 	int i;
    229        1.1   tsutsui 
    230        1.1   tsutsui 	aprint_naive("\n");
    231        1.1   tsutsui 	aprint_normal("\n");
    232        1.1   tsutsui 
    233        1.1   tsutsui 	/*
    234        1.1   tsutsui 	 * Attach USB device.
    235        1.1   tsutsui 	 */
    236        1.1   tsutsui 	sc->sc_dev = self;
    237   1.12.4.5     skrll 	sc->sc_udev = uaa->uaa_device;
    238        1.1   tsutsui 
    239        1.1   tsutsui 	devinfop = usbd_devinfo_alloc(sc->sc_udev, 0);
    240        1.1   tsutsui 	aprint_normal_dev(sc->sc_dev, "%s\n", devinfop);
    241        1.1   tsutsui 	usbd_devinfo_free(devinfop);
    242        1.1   tsutsui 
    243        1.1   tsutsui 	/* check device type */
    244   1.12.4.5     skrll 	if (upgt_device_type(sc, uaa->uaa_vendor, uaa->uaa_product) != 0)
    245        1.1   tsutsui 		return;
    246        1.1   tsutsui 
    247        1.1   tsutsui 	/* set configuration number */
    248        1.7     skrll 	error = usbd_set_config_no(sc->sc_udev, UPGT_CONFIG_NO, 0);
    249        1.7     skrll 	if (error != 0) {
    250        1.7     skrll 		aprint_error_dev(sc->sc_dev, "failed to set configuration"
    251        1.7     skrll 		    ", err=%s\n", usbd_errstr(error));
    252        1.1   tsutsui 		return;
    253        1.1   tsutsui 	}
    254        1.1   tsutsui 
    255        1.1   tsutsui 	/* get the first interface handle */
    256        1.1   tsutsui 	error = usbd_device2interface_handle(sc->sc_udev, UPGT_IFACE_INDEX,
    257        1.1   tsutsui 	    &sc->sc_iface);
    258        1.1   tsutsui 	if (error != 0) {
    259        1.1   tsutsui 		aprint_error_dev(sc->sc_dev,
    260        1.1   tsutsui 		    "could not get interface handle\n");
    261        1.1   tsutsui 		return;
    262        1.1   tsutsui 	}
    263        1.1   tsutsui 
    264        1.1   tsutsui 	/* find endpoints */
    265        1.1   tsutsui 	id = usbd_get_interface_descriptor(sc->sc_iface);
    266        1.1   tsutsui 	sc->sc_rx_no = sc->sc_tx_no = -1;
    267        1.1   tsutsui 	for (i = 0; i < id->bNumEndpoints; i++) {
    268        1.1   tsutsui 		ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
    269        1.1   tsutsui 		if (ed == NULL) {
    270        1.1   tsutsui 			aprint_error_dev(sc->sc_dev,
    271        1.1   tsutsui 			    "no endpoint descriptor for iface %d\n", i);
    272        1.1   tsutsui 			return;
    273        1.1   tsutsui 		}
    274        1.1   tsutsui 
    275        1.1   tsutsui 		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
    276        1.1   tsutsui 		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
    277        1.1   tsutsui 			sc->sc_tx_no = ed->bEndpointAddress;
    278        1.1   tsutsui 		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
    279        1.1   tsutsui 		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
    280        1.1   tsutsui 			sc->sc_rx_no = ed->bEndpointAddress;
    281        1.1   tsutsui 
    282        1.1   tsutsui 		/*
    283        1.1   tsutsui 		 * 0x01 TX pipe
    284        1.1   tsutsui 		 * 0x81 RX pipe
    285        1.1   tsutsui 		 *
    286        1.1   tsutsui 		 * Deprecated scheme (not used with fw version >2.5.6.x):
    287        1.1   tsutsui 		 * 0x02 TX MGMT pipe
    288        1.1   tsutsui 		 * 0x82 TX MGMT pipe
    289        1.1   tsutsui 		 */
    290        1.1   tsutsui 		if (sc->sc_tx_no != -1 && sc->sc_rx_no != -1)
    291        1.1   tsutsui 			break;
    292        1.1   tsutsui 	}
    293        1.1   tsutsui 	if (sc->sc_rx_no == -1 || sc->sc_tx_no == -1) {
    294        1.1   tsutsui 		aprint_error_dev(sc->sc_dev, "missing endpoint\n");
    295        1.1   tsutsui 		return;
    296        1.1   tsutsui 	}
    297        1.1   tsutsui 
    298        1.1   tsutsui 	/* setup tasks and timeouts */
    299        1.8  jmcneill 	usb_init_task(&sc->sc_task_newstate, upgt_newstate_task, sc, 0);
    300        1.8  jmcneill 	usb_init_task(&sc->sc_task_tx, upgt_tx_task, sc, 0);
    301        1.1   tsutsui 	callout_init(&sc->scan_to, 0);
    302        1.1   tsutsui 	callout_setfunc(&sc->scan_to, upgt_next_scan, sc);
    303        1.1   tsutsui 	callout_init(&sc->led_to, 0);
    304        1.1   tsutsui 	callout_setfunc(&sc->led_to, upgt_set_led_blink, sc);
    305        1.1   tsutsui 
    306        1.1   tsutsui 	/*
    307        1.1   tsutsui 	 * Open TX and RX USB bulk pipes.
    308        1.1   tsutsui 	 */
    309        1.1   tsutsui 	error = usbd_open_pipe(sc->sc_iface, sc->sc_tx_no, USBD_EXCLUSIVE_USE,
    310        1.1   tsutsui 	    &sc->sc_tx_pipeh);
    311        1.1   tsutsui 	if (error != 0) {
    312        1.1   tsutsui 		aprint_error_dev(sc->sc_dev,
    313        1.1   tsutsui 		    "could not open TX pipe: %s\n", usbd_errstr(error));
    314        1.1   tsutsui 		goto fail;
    315        1.1   tsutsui 	}
    316        1.1   tsutsui 	error = usbd_open_pipe(sc->sc_iface, sc->sc_rx_no, USBD_EXCLUSIVE_USE,
    317        1.1   tsutsui 	    &sc->sc_rx_pipeh);
    318        1.1   tsutsui 	if (error != 0) {
    319        1.1   tsutsui 		aprint_error_dev(sc->sc_dev, "could not open RX pipe: %s\n",
    320        1.1   tsutsui 		    usbd_errstr(error));
    321        1.1   tsutsui 		goto fail;
    322        1.1   tsutsui 	}
    323        1.1   tsutsui 
    324        1.1   tsutsui 	/*
    325        1.1   tsutsui 	 * Allocate TX, RX, and CMD xfers.
    326        1.1   tsutsui 	 */
    327        1.1   tsutsui 	if (upgt_alloc_tx(sc) != 0)
    328        1.1   tsutsui 		goto fail;
    329        1.1   tsutsui 	if (upgt_alloc_rx(sc) != 0)
    330        1.1   tsutsui 		goto fail;
    331        1.1   tsutsui 	if (upgt_alloc_cmd(sc) != 0)
    332        1.1   tsutsui 		goto fail;
    333        1.1   tsutsui 
    334        1.1   tsutsui 	/*
    335        1.1   tsutsui 	 * We need the firmware loaded from file system to complete the attach.
    336        1.1   tsutsui 	 */
    337        1.1   tsutsui 	config_mountroot(self, upgt_attach_hook);
    338        1.1   tsutsui 
    339        1.1   tsutsui 	return;
    340        1.1   tsutsui fail:
    341        1.1   tsutsui 	aprint_error_dev(sc->sc_dev, "%s failed\n", __func__);
    342        1.1   tsutsui }
    343        1.1   tsutsui 
    344        1.1   tsutsui static void
    345        1.1   tsutsui upgt_attach_hook(device_t arg)
    346        1.1   tsutsui {
    347        1.1   tsutsui 	struct upgt_softc *sc = device_private(arg);
    348        1.1   tsutsui 	struct ieee80211com *ic = &sc->sc_ic;
    349        1.1   tsutsui 	struct ifnet *ifp = &sc->sc_if;
    350        1.1   tsutsui 	usbd_status error;
    351        1.1   tsutsui 	int i;
    352        1.1   tsutsui 
    353        1.1   tsutsui 	/*
    354        1.1   tsutsui 	 * Load firmware file into memory.
    355        1.1   tsutsui 	 */
    356        1.1   tsutsui 	if (upgt_fw_alloc(sc) != 0)
    357        1.1   tsutsui 		goto fail;
    358        1.1   tsutsui 
    359        1.1   tsutsui 	/*
    360        1.1   tsutsui 	 * Initialize the device.
    361        1.1   tsutsui 	 */
    362        1.1   tsutsui 	if (upgt_device_init(sc) != 0)
    363        1.1   tsutsui 		goto fail;
    364        1.1   tsutsui 
    365        1.1   tsutsui 	/*
    366        1.1   tsutsui 	 * Verify the firmware.
    367        1.1   tsutsui 	 */
    368        1.1   tsutsui 	if (upgt_fw_verify(sc) != 0)
    369        1.1   tsutsui 		goto fail;
    370        1.1   tsutsui 
    371        1.1   tsutsui 	/*
    372        1.1   tsutsui 	 * Calculate device memory space.
    373        1.1   tsutsui 	 */
    374        1.1   tsutsui 	if (sc->sc_memaddr_frame_start == 0 || sc->sc_memaddr_frame_end == 0) {
    375        1.1   tsutsui 		aprint_error_dev(sc->sc_dev,
    376        1.1   tsutsui 		    "could not find memory space addresses on FW\n");
    377        1.1   tsutsui 		goto fail;
    378        1.1   tsutsui 	}
    379        1.1   tsutsui 	sc->sc_memaddr_frame_end -= UPGT_MEMSIZE_RX + 1;
    380        1.1   tsutsui 	sc->sc_memaddr_rx_start = sc->sc_memaddr_frame_end + 1;
    381        1.1   tsutsui 
    382        1.1   tsutsui 	DPRINTF(1, "%s: memory address frame start=0x%08x\n",
    383        1.1   tsutsui 	    device_xname(sc->sc_dev), sc->sc_memaddr_frame_start);
    384        1.1   tsutsui 	DPRINTF(1, "%s: memory address frame end=0x%08x\n",
    385        1.1   tsutsui 	    device_xname(sc->sc_dev), sc->sc_memaddr_frame_end);
    386        1.1   tsutsui 	DPRINTF(1, "%s: memory address rx start=0x%08x\n",
    387        1.1   tsutsui 	    device_xname(sc->sc_dev), sc->sc_memaddr_rx_start);
    388        1.1   tsutsui 
    389        1.1   tsutsui 	upgt_mem_init(sc);
    390        1.1   tsutsui 
    391        1.1   tsutsui 	/*
    392        1.1   tsutsui 	 * Load the firmware.
    393        1.1   tsutsui 	 */
    394        1.1   tsutsui 	if (upgt_fw_load(sc) != 0)
    395        1.1   tsutsui 		goto fail;
    396        1.1   tsutsui 
    397        1.1   tsutsui 	/*
    398        1.1   tsutsui 	 * Startup the RX pipe.
    399        1.1   tsutsui 	 */
    400        1.1   tsutsui 	struct upgt_data *data_rx = &sc->rx_data;
    401        1.1   tsutsui 
    402   1.12.4.7     skrll 	usbd_setup_xfer(data_rx->xfer, data_rx, data_rx->buf,
    403        1.1   tsutsui 	    MCLBYTES, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, upgt_rx_cb);
    404        1.1   tsutsui 	error = usbd_transfer(data_rx->xfer);
    405        1.1   tsutsui 	if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) {
    406        1.1   tsutsui 		aprint_error_dev(sc->sc_dev,
    407        1.1   tsutsui 		    "could not queue RX transfer\n");
    408        1.1   tsutsui 		goto fail;
    409        1.1   tsutsui 	}
    410        1.1   tsutsui 	usbd_delay_ms(sc->sc_udev, 100);
    411        1.1   tsutsui 
    412        1.1   tsutsui 	/*
    413        1.1   tsutsui 	 * Read the whole EEPROM content and parse it.
    414        1.1   tsutsui 	 */
    415        1.1   tsutsui 	if (upgt_eeprom_read(sc) != 0)
    416        1.1   tsutsui 		goto fail;
    417        1.1   tsutsui 	if (upgt_eeprom_parse(sc) != 0)
    418        1.1   tsutsui 		goto fail;
    419        1.1   tsutsui 
    420        1.1   tsutsui 	/*
    421        1.1   tsutsui 	 * Setup the 802.11 device.
    422        1.1   tsutsui 	 */
    423        1.1   tsutsui 	ic->ic_ifp = ifp;
    424        1.1   tsutsui 	ic->ic_phytype = IEEE80211_T_OFDM;
    425        1.1   tsutsui 	ic->ic_opmode = IEEE80211_M_STA;
    426        1.1   tsutsui 	ic->ic_state = IEEE80211_S_INIT;
    427        1.1   tsutsui 	ic->ic_caps =
    428        1.1   tsutsui 	    IEEE80211_C_MONITOR |
    429        1.1   tsutsui 	    IEEE80211_C_SHPREAMBLE |
    430        1.1   tsutsui 	    IEEE80211_C_SHSLOT;
    431        1.1   tsutsui 
    432        1.1   tsutsui 	ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
    433        1.1   tsutsui 	ic->ic_sup_rates[IEEE80211_MODE_11G] = ieee80211_std_rateset_11g;
    434        1.1   tsutsui 
    435        1.1   tsutsui 	for (i = 1; i <= 14; i++) {
    436        1.1   tsutsui 		ic->ic_channels[i].ic_freq =
    437        1.1   tsutsui 		    ieee80211_ieee2mhz(i, IEEE80211_CHAN_2GHZ);
    438        1.1   tsutsui 		ic->ic_channels[i].ic_flags =
    439        1.1   tsutsui 		    IEEE80211_CHAN_CCK | IEEE80211_CHAN_OFDM |
    440        1.1   tsutsui 		    IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
    441        1.1   tsutsui 	}
    442        1.1   tsutsui 
    443        1.1   tsutsui 	ifp->if_softc = sc;
    444        1.1   tsutsui 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
    445        1.1   tsutsui 	ifp->if_init = upgt_init;
    446        1.1   tsutsui 	ifp->if_ioctl = upgt_ioctl;
    447        1.1   tsutsui 	ifp->if_start = upgt_start;
    448        1.1   tsutsui 	ifp->if_watchdog = upgt_watchdog;
    449        1.1   tsutsui 	IFQ_SET_READY(&ifp->if_snd);
    450        1.1   tsutsui 	memcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ);
    451        1.1   tsutsui 
    452        1.1   tsutsui 	if_attach(ifp);
    453        1.1   tsutsui 	ieee80211_ifattach(ic);
    454        1.1   tsutsui 	ic->ic_newassoc = upgt_newassoc;
    455        1.1   tsutsui 
    456        1.1   tsutsui 	sc->sc_newstate = ic->ic_newstate;
    457        1.1   tsutsui 	ic->ic_newstate = upgt_newstate;
    458        1.1   tsutsui 	ieee80211_media_init(ic, upgt_media_change, ieee80211_media_status);
    459        1.1   tsutsui 
    460        1.1   tsutsui 	bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
    461        1.1   tsutsui 	    sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN,
    462        1.1   tsutsui 	    &sc->sc_drvbpf);
    463        1.1   tsutsui 
    464        1.1   tsutsui 	sc->sc_rxtap_len = sizeof(sc->sc_rxtapu);
    465        1.1   tsutsui 	sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
    466        1.1   tsutsui 	sc->sc_rxtap.wr_ihdr.it_present = htole32(UPGT_RX_RADIOTAP_PRESENT);
    467        1.1   tsutsui 
    468        1.1   tsutsui 	sc->sc_txtap_len = sizeof(sc->sc_txtapu);
    469        1.1   tsutsui 	sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
    470        1.1   tsutsui 	sc->sc_txtap.wt_ihdr.it_present = htole32(UPGT_TX_RADIOTAP_PRESENT);
    471        1.1   tsutsui 
    472        1.1   tsutsui 	aprint_normal_dev(sc->sc_dev, "address %s\n",
    473        1.1   tsutsui 	    ether_sprintf(ic->ic_myaddr));
    474        1.1   tsutsui 
    475        1.1   tsutsui 	ieee80211_announce(ic);
    476        1.1   tsutsui 
    477        1.1   tsutsui 	usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev);
    478        1.1   tsutsui 
    479        1.1   tsutsui 	/* device attached */
    480        1.1   tsutsui 	sc->sc_flags |= UPGT_DEVICE_ATTACHED;
    481        1.1   tsutsui 
    482        1.1   tsutsui 	return;
    483        1.1   tsutsui fail:
    484        1.1   tsutsui 	aprint_error_dev(sc->sc_dev, "%s failed\n", __func__);
    485        1.1   tsutsui }
    486        1.1   tsutsui 
    487        1.1   tsutsui static int
    488        1.1   tsutsui upgt_detach(device_t self, int flags)
    489        1.1   tsutsui {
    490        1.1   tsutsui 	struct upgt_softc *sc = device_private(self);
    491        1.1   tsutsui 	struct ifnet *ifp = &sc->sc_if;
    492        1.1   tsutsui 	struct ieee80211com *ic = &sc->sc_ic;
    493        1.1   tsutsui 	int s;
    494        1.1   tsutsui 
    495        1.1   tsutsui 	DPRINTF(1, "%s: %s\n", device_xname(sc->sc_dev), __func__);
    496        1.1   tsutsui 
    497        1.1   tsutsui 	s = splnet();
    498        1.1   tsutsui 
    499        1.1   tsutsui 	if (ifp->if_flags & IFF_RUNNING)
    500        1.1   tsutsui 		upgt_stop(sc);
    501        1.1   tsutsui 
    502        1.1   tsutsui 	/* remove tasks and timeouts */
    503        1.1   tsutsui 	usb_rem_task(sc->sc_udev, &sc->sc_task_newstate);
    504        1.1   tsutsui 	usb_rem_task(sc->sc_udev, &sc->sc_task_tx);
    505        1.1   tsutsui 	callout_destroy(&sc->scan_to);
    506        1.1   tsutsui 	callout_destroy(&sc->led_to);
    507        1.1   tsutsui 
    508        1.1   tsutsui 	/* abort and close TX / RX pipes */
    509        1.1   tsutsui 	if (sc->sc_tx_pipeh != NULL) {
    510        1.1   tsutsui 		usbd_abort_pipe(sc->sc_tx_pipeh);
    511        1.1   tsutsui 	}
    512        1.1   tsutsui 	if (sc->sc_rx_pipeh != NULL) {
    513        1.1   tsutsui 		usbd_abort_pipe(sc->sc_rx_pipeh);
    514        1.1   tsutsui 	}
    515        1.1   tsutsui 
    516        1.1   tsutsui 	/* free xfers */
    517        1.1   tsutsui 	upgt_free_tx(sc);
    518        1.1   tsutsui 	upgt_free_rx(sc);
    519        1.1   tsutsui 	upgt_free_cmd(sc);
    520        1.1   tsutsui 
    521   1.12.4.9     skrll 	/* Close TX / RX pipes */
    522   1.12.4.9     skrll 	if (sc->sc_tx_pipeh != NULL) {
    523   1.12.4.9     skrll 		usbd_close_pipe(sc->sc_tx_pipeh);
    524   1.12.4.9     skrll 	}
    525   1.12.4.9     skrll 	if (sc->sc_rx_pipeh != NULL) {
    526   1.12.4.9     skrll 		usbd_close_pipe(sc->sc_rx_pipeh);
    527   1.12.4.9     skrll 	}
    528   1.12.4.9     skrll 
    529        1.1   tsutsui 	/* free firmware */
    530        1.1   tsutsui 	upgt_fw_free(sc);
    531        1.1   tsutsui 
    532        1.1   tsutsui 	if (sc->sc_flags & UPGT_DEVICE_ATTACHED) {
    533        1.1   tsutsui 		/* detach interface */
    534        1.1   tsutsui 		bpf_detach(ifp);
    535        1.1   tsutsui 		ieee80211_ifdetach(ic);
    536        1.1   tsutsui 		if_detach(ifp);
    537        1.1   tsutsui 	}
    538        1.1   tsutsui 
    539        1.1   tsutsui 	splx(s);
    540        1.1   tsutsui 
    541        1.1   tsutsui 	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
    542        1.1   tsutsui 
    543        1.1   tsutsui 	return 0;
    544        1.1   tsutsui }
    545        1.1   tsutsui 
    546        1.1   tsutsui static int
    547        1.1   tsutsui upgt_activate(device_t self, devact_t act)
    548        1.1   tsutsui {
    549        1.1   tsutsui 	struct upgt_softc *sc = device_private(self);
    550        1.1   tsutsui 
    551        1.1   tsutsui 	switch (act) {
    552        1.1   tsutsui 	case DVACT_DEACTIVATE:
    553        1.1   tsutsui 		if_deactivate(&sc->sc_if);
    554        1.1   tsutsui 		return 0;
    555        1.1   tsutsui 	default:
    556        1.1   tsutsui 		return EOPNOTSUPP;
    557        1.1   tsutsui 	}
    558        1.1   tsutsui }
    559        1.1   tsutsui 
    560        1.1   tsutsui static int
    561        1.1   tsutsui upgt_device_type(struct upgt_softc *sc, uint16_t vendor, uint16_t product)
    562        1.1   tsutsui {
    563        1.1   tsutsui 
    564        1.1   tsutsui 	if (usb_lookup(upgt_devs_1, vendor, product) != NULL) {
    565        1.1   tsutsui 		sc->sc_device_type = 1;
    566        1.1   tsutsui 		/* XXX */
    567        1.1   tsutsui 		aprint_error_dev(sc->sc_dev,
    568        1.1   tsutsui 		    "version 1 devices not supported yet\n");
    569        1.1   tsutsui 		return 1;
    570        1.1   tsutsui 	} else
    571        1.1   tsutsui 		sc->sc_device_type = 2;
    572        1.1   tsutsui 
    573        1.1   tsutsui 	return 0;
    574        1.1   tsutsui }
    575        1.1   tsutsui 
    576        1.1   tsutsui static int
    577        1.1   tsutsui upgt_device_init(struct upgt_softc *sc)
    578        1.1   tsutsui {
    579        1.1   tsutsui 	struct upgt_data *data_cmd = &sc->cmd_data;
    580        1.1   tsutsui 	const uint8_t init_cmd[] = { 0x7e, 0x7e, 0x7e, 0x7e };
    581        1.1   tsutsui 	int len;
    582        1.1   tsutsui 
    583        1.1   tsutsui 	len = sizeof(init_cmd);
    584        1.1   tsutsui 	memcpy(data_cmd->buf, init_cmd, len);
    585        1.1   tsutsui 	if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) {
    586        1.1   tsutsui 		aprint_error_dev(sc->sc_dev,
    587        1.1   tsutsui 		    "could not send device init string\n");
    588        1.1   tsutsui 		return EIO;
    589        1.1   tsutsui 	}
    590        1.1   tsutsui 	usbd_delay_ms(sc->sc_udev, 100);
    591        1.1   tsutsui 
    592        1.1   tsutsui 	DPRINTF(1, "%s: device initialized\n", device_xname(sc->sc_dev));
    593        1.1   tsutsui 
    594        1.1   tsutsui 	return 0;
    595        1.1   tsutsui }
    596        1.1   tsutsui 
    597        1.1   tsutsui static int
    598        1.1   tsutsui upgt_mem_init(struct upgt_softc *sc)
    599        1.1   tsutsui {
    600        1.1   tsutsui 	int i;
    601        1.1   tsutsui 
    602        1.1   tsutsui 	for (i = 0; i < UPGT_MEMORY_MAX_PAGES; i++) {
    603        1.1   tsutsui 		sc->sc_memory.page[i].used = 0;
    604        1.1   tsutsui 
    605        1.1   tsutsui 		if (i == 0) {
    606        1.1   tsutsui 			/*
    607        1.1   tsutsui 			 * The first memory page is always reserved for
    608        1.1   tsutsui 			 * command data.
    609        1.1   tsutsui 			 */
    610        1.1   tsutsui 			sc->sc_memory.page[i].addr =
    611        1.1   tsutsui 			    sc->sc_memaddr_frame_start + MCLBYTES;
    612        1.1   tsutsui 		} else {
    613        1.1   tsutsui 			sc->sc_memory.page[i].addr =
    614        1.1   tsutsui 			    sc->sc_memory.page[i - 1].addr + MCLBYTES;
    615        1.1   tsutsui 		}
    616        1.1   tsutsui 
    617        1.1   tsutsui 		if (sc->sc_memory.page[i].addr + MCLBYTES >=
    618        1.1   tsutsui 		    sc->sc_memaddr_frame_end)
    619        1.1   tsutsui 			break;
    620        1.1   tsutsui 
    621        1.1   tsutsui 		DPRINTF(2, "%s: memory address page %d=0x%08x\n",
    622        1.1   tsutsui 		    device_xname(sc->sc_dev), i, sc->sc_memory.page[i].addr);
    623        1.1   tsutsui 	}
    624        1.1   tsutsui 
    625        1.1   tsutsui 	sc->sc_memory.pages = i;
    626        1.1   tsutsui 
    627        1.1   tsutsui 	DPRINTF(2, "%s: memory pages=%d\n",
    628        1.1   tsutsui 	    device_xname(sc->sc_dev), sc->sc_memory.pages);
    629        1.1   tsutsui 
    630        1.1   tsutsui 	return 0;
    631        1.1   tsutsui }
    632        1.1   tsutsui 
    633        1.1   tsutsui static uint32_t
    634        1.1   tsutsui upgt_mem_alloc(struct upgt_softc *sc)
    635        1.1   tsutsui {
    636        1.1   tsutsui 	int i;
    637        1.1   tsutsui 
    638        1.1   tsutsui 	for (i = 0; i < sc->sc_memory.pages; i++) {
    639        1.1   tsutsui 		if (sc->sc_memory.page[i].used == 0) {
    640        1.1   tsutsui 			sc->sc_memory.page[i].used = 1;
    641        1.1   tsutsui 			return sc->sc_memory.page[i].addr;
    642        1.1   tsutsui 		}
    643        1.1   tsutsui 	}
    644        1.1   tsutsui 
    645        1.1   tsutsui 	return 0;
    646        1.1   tsutsui }
    647        1.1   tsutsui 
    648        1.1   tsutsui static void
    649        1.1   tsutsui upgt_mem_free(struct upgt_softc *sc, uint32_t addr)
    650        1.1   tsutsui {
    651        1.1   tsutsui 	int i;
    652        1.1   tsutsui 
    653        1.1   tsutsui 	for (i = 0; i < sc->sc_memory.pages; i++) {
    654        1.1   tsutsui 		if (sc->sc_memory.page[i].addr == addr) {
    655        1.1   tsutsui 			sc->sc_memory.page[i].used = 0;
    656        1.1   tsutsui 			return;
    657        1.1   tsutsui 		}
    658        1.1   tsutsui 	}
    659        1.1   tsutsui 
    660        1.1   tsutsui 	aprint_error_dev(sc->sc_dev, "could not free memory address 0x%08x\n",
    661        1.1   tsutsui 	    addr);
    662        1.1   tsutsui }
    663        1.1   tsutsui 
    664        1.1   tsutsui 
    665        1.1   tsutsui static int
    666        1.1   tsutsui upgt_fw_alloc(struct upgt_softc *sc)
    667        1.1   tsutsui {
    668        1.1   tsutsui 	const char *name = "upgt-gw3887";
    669        1.1   tsutsui 	int error;
    670        1.1   tsutsui 
    671        1.1   tsutsui 	if (sc->sc_fw == NULL) {
    672        1.1   tsutsui 		error = firmware_load("upgt", name, &sc->sc_fw,
    673        1.1   tsutsui 		    &sc->sc_fw_size);
    674        1.1   tsutsui 		if (error != 0) {
    675        1.3   tsutsui 			if (error == ENOENT) {
    676        1.3   tsutsui 				/*
    677        1.3   tsutsui 				 * The firmware file for upgt(4) is not in
    678        1.3   tsutsui 				 * the default distribution due to its lisence
    679        1.3   tsutsui 				 * so explicitly notify it if the firmware file
    680        1.3   tsutsui 				 * is not found.
    681        1.3   tsutsui 				 */
    682        1.3   tsutsui 				aprint_error_dev(sc->sc_dev,
    683        1.3   tsutsui 				    "firmware file %s is not installed\n",
    684        1.3   tsutsui 				    name);
    685        1.3   tsutsui 				aprint_error_dev(sc->sc_dev,
    686        1.3   tsutsui 				    "(it is not included in the default"
    687        1.3   tsutsui 				    " distribution)\n");
    688        1.3   tsutsui 				aprint_error_dev(sc->sc_dev,
    689        1.3   tsutsui 				    "see upgt(4) man page for details about "
    690        1.3   tsutsui 				    "firmware installation\n");
    691        1.3   tsutsui 			} else {
    692        1.3   tsutsui 				aprint_error_dev(sc->sc_dev,
    693        1.3   tsutsui 				    "could not read firmware %s\n", name);
    694        1.3   tsutsui 			}
    695        1.1   tsutsui 			return EIO;
    696        1.1   tsutsui 		}
    697        1.1   tsutsui 	}
    698        1.1   tsutsui 
    699        1.1   tsutsui 	DPRINTF(1, "%s: firmware %s allocated\n", device_xname(sc->sc_dev),
    700        1.1   tsutsui 	    name);
    701        1.1   tsutsui 
    702        1.1   tsutsui 	return 0;
    703        1.1   tsutsui }
    704        1.1   tsutsui 
    705        1.1   tsutsui static void
    706        1.1   tsutsui upgt_fw_free(struct upgt_softc *sc)
    707        1.1   tsutsui {
    708        1.1   tsutsui 
    709        1.1   tsutsui 	if (sc->sc_fw != NULL) {
    710        1.1   tsutsui 		firmware_free(sc->sc_fw, sc->sc_fw_size);
    711        1.1   tsutsui 		sc->sc_fw = NULL;
    712        1.1   tsutsui 		DPRINTF(1, "%s: firmware freed\n", device_xname(sc->sc_dev));
    713        1.1   tsutsui 	}
    714        1.1   tsutsui }
    715        1.1   tsutsui 
    716        1.1   tsutsui static int
    717        1.1   tsutsui upgt_fw_verify(struct upgt_softc *sc)
    718        1.1   tsutsui {
    719        1.1   tsutsui 	struct upgt_fw_bra_option *bra_option;
    720        1.1   tsutsui 	uint32_t bra_option_type, bra_option_len;
    721        1.1   tsutsui 	uint32_t *uc;
    722        1.1   tsutsui 	int offset, bra_end = 0;
    723        1.1   tsutsui 
    724        1.1   tsutsui 	/*
    725        1.1   tsutsui 	 * Seek to beginning of Boot Record Area (BRA).
    726        1.1   tsutsui 	 */
    727        1.1   tsutsui 	for (offset = 0; offset < sc->sc_fw_size; offset += sizeof(*uc)) {
    728        1.1   tsutsui 		uc = (uint32_t *)(sc->sc_fw + offset);
    729        1.1   tsutsui 		if (*uc == 0)
    730        1.1   tsutsui 			break;
    731        1.1   tsutsui 	}
    732        1.1   tsutsui 	for (; offset < sc->sc_fw_size; offset += sizeof(*uc)) {
    733        1.1   tsutsui 		uc = (uint32_t *)(sc->sc_fw + offset);
    734        1.1   tsutsui 		if (*uc != 0)
    735        1.1   tsutsui 			break;
    736        1.1   tsutsui 	}
    737        1.9  christos 	if (offset == sc->sc_fw_size) {
    738        1.1   tsutsui 		aprint_error_dev(sc->sc_dev,
    739        1.1   tsutsui 		    "firmware Boot Record Area not found\n");
    740        1.1   tsutsui 		return EIO;
    741        1.1   tsutsui 	}
    742        1.1   tsutsui 	DPRINTF(1, "%s: firmware Boot Record Area found at offset %d\n",
    743        1.1   tsutsui 	    device_xname(sc->sc_dev), offset);
    744        1.1   tsutsui 
    745        1.1   tsutsui 	/*
    746        1.1   tsutsui 	 * Parse Boot Record Area (BRA) options.
    747        1.1   tsutsui 	 */
    748        1.1   tsutsui 	while (offset < sc->sc_fw_size && bra_end == 0) {
    749        1.1   tsutsui 		/* get current BRA option */
    750        1.1   tsutsui 		bra_option = (struct upgt_fw_bra_option *)(sc->sc_fw + offset);
    751        1.1   tsutsui 		bra_option_type = le32toh(bra_option->type);
    752        1.1   tsutsui 		bra_option_len = le32toh(bra_option->len) * sizeof(*uc);
    753        1.1   tsutsui 
    754        1.1   tsutsui 		switch (bra_option_type) {
    755        1.1   tsutsui 		case UPGT_BRA_TYPE_FW:
    756        1.1   tsutsui 			DPRINTF(1, "%s: UPGT_BRA_TYPE_FW len=%d\n",
    757        1.1   tsutsui 			    device_xname(sc->sc_dev), bra_option_len);
    758        1.1   tsutsui 
    759        1.1   tsutsui 			if (bra_option_len != UPGT_BRA_FWTYPE_SIZE) {
    760        1.1   tsutsui 				aprint_error_dev(sc->sc_dev,
    761        1.1   tsutsui 				    "wrong UPGT_BRA_TYPE_FW len\n");
    762        1.1   tsutsui 				return EIO;
    763        1.1   tsutsui 			}
    764        1.1   tsutsui 			if (memcmp(UPGT_BRA_FWTYPE_LM86, bra_option->data,
    765        1.1   tsutsui 			    bra_option_len) == 0) {
    766        1.1   tsutsui 				sc->sc_fw_type = UPGT_FWTYPE_LM86;
    767        1.1   tsutsui 				break;
    768        1.1   tsutsui 			}
    769        1.1   tsutsui 			if (memcmp(UPGT_BRA_FWTYPE_LM87, bra_option->data,
    770        1.1   tsutsui 			    bra_option_len) == 0) {
    771        1.1   tsutsui 				sc->sc_fw_type = UPGT_FWTYPE_LM87;
    772        1.1   tsutsui 				break;
    773        1.1   tsutsui 			}
    774        1.1   tsutsui 			if (memcmp(UPGT_BRA_FWTYPE_FMAC, bra_option->data,
    775        1.1   tsutsui 			    bra_option_len) == 0) {
    776        1.1   tsutsui 				sc->sc_fw_type = UPGT_FWTYPE_FMAC;
    777        1.1   tsutsui 				break;
    778        1.1   tsutsui 			}
    779        1.1   tsutsui 			aprint_error_dev(sc->sc_dev,
    780        1.1   tsutsui 			    "unsupported firmware type\n");
    781        1.1   tsutsui 			return EIO;
    782        1.1   tsutsui 		case UPGT_BRA_TYPE_VERSION:
    783        1.1   tsutsui 			DPRINTF(1, "%s: UPGT_BRA_TYPE_VERSION len=%d\n",
    784        1.1   tsutsui 			    device_xname(sc->sc_dev), bra_option_len);
    785        1.1   tsutsui 			break;
    786        1.1   tsutsui 		case UPGT_BRA_TYPE_DEPIF:
    787        1.1   tsutsui 			DPRINTF(1, "%s: UPGT_BRA_TYPE_DEPIF len=%d\n",
    788        1.1   tsutsui 			    device_xname(sc->sc_dev), bra_option_len);
    789        1.1   tsutsui 			break;
    790        1.1   tsutsui 		case UPGT_BRA_TYPE_EXPIF:
    791        1.1   tsutsui 			DPRINTF(1, "%s: UPGT_BRA_TYPE_EXPIF len=%d\n",
    792        1.1   tsutsui 			    device_xname(sc->sc_dev), bra_option_len);
    793        1.1   tsutsui 			break;
    794        1.1   tsutsui 		case UPGT_BRA_TYPE_DESCR:
    795        1.1   tsutsui 			DPRINTF(1, "%s: UPGT_BRA_TYPE_DESCR len=%d\n",
    796        1.1   tsutsui 			    device_xname(sc->sc_dev), bra_option_len);
    797        1.1   tsutsui 
    798        1.1   tsutsui 			struct upgt_fw_bra_descr *descr =
    799        1.1   tsutsui 				(struct upgt_fw_bra_descr *)bra_option->data;
    800        1.1   tsutsui 
    801        1.1   tsutsui 			sc->sc_memaddr_frame_start =
    802        1.1   tsutsui 			    le32toh(descr->memaddr_space_start);
    803        1.1   tsutsui 			sc->sc_memaddr_frame_end =
    804        1.1   tsutsui 			    le32toh(descr->memaddr_space_end);
    805        1.1   tsutsui 
    806        1.1   tsutsui 			DPRINTF(2, "%s: memory address space start=0x%08x\n",
    807        1.1   tsutsui 			    device_xname(sc->sc_dev),
    808        1.1   tsutsui 			    sc->sc_memaddr_frame_start);
    809        1.1   tsutsui 			DPRINTF(2, "%s: memory address space end=0x%08x\n",
    810        1.1   tsutsui 			    device_xname(sc->sc_dev),
    811        1.1   tsutsui 			    sc->sc_memaddr_frame_end);
    812        1.1   tsutsui 			break;
    813        1.1   tsutsui 		case UPGT_BRA_TYPE_END:
    814        1.1   tsutsui 			DPRINTF(1, "%s: UPGT_BRA_TYPE_END len=%d\n",
    815        1.1   tsutsui 			    device_xname(sc->sc_dev), bra_option_len);
    816        1.1   tsutsui 			bra_end = 1;
    817        1.1   tsutsui 			break;
    818        1.1   tsutsui 		default:
    819        1.1   tsutsui 			DPRINTF(1, "%s: unknown BRA option len=%d\n",
    820        1.1   tsutsui 			    device_xname(sc->sc_dev), bra_option_len);
    821        1.1   tsutsui 			return EIO;
    822        1.1   tsutsui 		}
    823        1.1   tsutsui 
    824        1.1   tsutsui 		/* jump to next BRA option */
    825        1.1   tsutsui 		offset += sizeof(struct upgt_fw_bra_option) + bra_option_len;
    826        1.1   tsutsui 	}
    827        1.1   tsutsui 
    828        1.1   tsutsui 	DPRINTF(1, "%s: firmware verified\n", device_xname(sc->sc_dev));
    829        1.1   tsutsui 
    830        1.1   tsutsui 	return 0;
    831        1.1   tsutsui }
    832        1.1   tsutsui 
    833        1.1   tsutsui static int
    834        1.1   tsutsui upgt_fw_load(struct upgt_softc *sc)
    835        1.1   tsutsui {
    836        1.1   tsutsui 	struct upgt_data *data_cmd = &sc->cmd_data;
    837        1.1   tsutsui 	struct upgt_data *data_rx = &sc->rx_data;
    838        1.1   tsutsui 	struct upgt_fw_x2_header *x2;
    839        1.1   tsutsui 	const uint8_t start_fwload_cmd[] = { 0x3c, 0x0d };
    840        1.1   tsutsui 	int offset, bsize, n, i, len;
    841        1.1   tsutsui 	uint32_t crc;
    842        1.1   tsutsui 
    843        1.1   tsutsui 	/* send firmware start load command */
    844        1.1   tsutsui 	len = sizeof(start_fwload_cmd);
    845        1.1   tsutsui 	memcpy(data_cmd->buf, start_fwload_cmd, len);
    846        1.1   tsutsui 	if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) {
    847        1.1   tsutsui 		aprint_error_dev(sc->sc_dev,
    848        1.1   tsutsui 		    "could not send start_firmware_load command\n");
    849        1.1   tsutsui 		return EIO;
    850        1.1   tsutsui 	}
    851        1.1   tsutsui 
    852        1.1   tsutsui 	/* send X2 header */
    853        1.1   tsutsui 	len = sizeof(struct upgt_fw_x2_header);
    854        1.1   tsutsui 	x2 = (struct upgt_fw_x2_header *)data_cmd->buf;
    855        1.1   tsutsui 	memcpy(x2->signature, UPGT_X2_SIGNATURE, UPGT_X2_SIGNATURE_SIZE);
    856        1.1   tsutsui 	x2->startaddr = htole32(UPGT_MEMADDR_FIRMWARE_START);
    857        1.1   tsutsui 	x2->len = htole32(sc->sc_fw_size);
    858        1.1   tsutsui 	x2->crc = upgt_crc32_le(data_cmd->buf + UPGT_X2_SIGNATURE_SIZE,
    859        1.1   tsutsui 	    sizeof(struct upgt_fw_x2_header) - UPGT_X2_SIGNATURE_SIZE -
    860        1.1   tsutsui 	    sizeof(uint32_t));
    861        1.1   tsutsui 	if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) {
    862        1.1   tsutsui 		aprint_error_dev(sc->sc_dev,
    863        1.1   tsutsui 		    "could not send firmware X2 header\n");
    864        1.1   tsutsui 		return EIO;
    865        1.1   tsutsui 	}
    866        1.1   tsutsui 
    867        1.1   tsutsui 	/* download firmware */
    868        1.1   tsutsui 	for (offset = 0; offset < sc->sc_fw_size; offset += bsize) {
    869        1.1   tsutsui 		if (sc->sc_fw_size - offset > UPGT_FW_BLOCK_SIZE)
    870        1.1   tsutsui 			bsize = UPGT_FW_BLOCK_SIZE;
    871        1.1   tsutsui 		else
    872        1.1   tsutsui 			bsize = sc->sc_fw_size - offset;
    873        1.1   tsutsui 
    874        1.1   tsutsui 		n = upgt_fw_copy(sc->sc_fw + offset, data_cmd->buf, bsize);
    875        1.1   tsutsui 
    876        1.1   tsutsui 		DPRINTF(1, "%s: FW offset=%d, read=%d, sent=%d\n",
    877        1.1   tsutsui 		    device_xname(sc->sc_dev), offset, n, bsize);
    878        1.1   tsutsui 
    879        1.1   tsutsui 		if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &bsize, 0)
    880        1.1   tsutsui 		    != 0) {
    881        1.1   tsutsui 			aprint_error_dev(sc->sc_dev,
    882        1.1   tsutsui 			    "error while downloading firmware block\n");
    883        1.1   tsutsui 			return EIO;
    884        1.1   tsutsui 		}
    885        1.1   tsutsui 
    886        1.1   tsutsui 		bsize = n;
    887        1.1   tsutsui 	}
    888        1.1   tsutsui 	DPRINTF(1, "%s: firmware downloaded\n", device_xname(sc->sc_dev));
    889        1.1   tsutsui 
    890        1.1   tsutsui 	/* load firmware */
    891        1.1   tsutsui 	crc = upgt_crc32_le(sc->sc_fw, sc->sc_fw_size);
    892        1.1   tsutsui 	*((uint32_t *)(data_cmd->buf)    ) = crc;
    893        1.1   tsutsui 	*((uint8_t  *)(data_cmd->buf) + 4) = 'g';
    894        1.1   tsutsui 	*((uint8_t  *)(data_cmd->buf) + 5) = '\r';
    895        1.1   tsutsui 	len = 6;
    896        1.1   tsutsui 	if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) {
    897        1.1   tsutsui 		aprint_error_dev(sc->sc_dev,
    898        1.1   tsutsui 		    "could not send load_firmware command\n");
    899        1.1   tsutsui 		return EIO;
    900        1.1   tsutsui 	}
    901        1.1   tsutsui 
    902        1.1   tsutsui 	for (i = 0; i < UPGT_FIRMWARE_TIMEOUT; i++) {
    903        1.1   tsutsui 		len = UPGT_FW_BLOCK_SIZE;
    904        1.1   tsutsui 		memset(data_rx->buf, 0, 2);
    905        1.1   tsutsui 		if (upgt_bulk_xmit(sc, data_rx, sc->sc_rx_pipeh, &len,
    906        1.1   tsutsui 		    USBD_SHORT_XFER_OK) != 0) {
    907        1.1   tsutsui 			aprint_error_dev(sc->sc_dev,
    908        1.1   tsutsui 			    "could not read firmware response\n");
    909        1.1   tsutsui 			return EIO;
    910        1.1   tsutsui 		}
    911        1.1   tsutsui 
    912        1.1   tsutsui 		if (memcmp(data_rx->buf, "OK", 2) == 0)
    913        1.1   tsutsui 			break;	/* firmware load was successful */
    914        1.1   tsutsui 	}
    915        1.1   tsutsui 	if (i == UPGT_FIRMWARE_TIMEOUT) {
    916        1.1   tsutsui 		aprint_error_dev(sc->sc_dev, "firmware load failed\n");
    917        1.1   tsutsui 		return EIO;
    918        1.1   tsutsui 	}
    919        1.1   tsutsui 	DPRINTF(1, "%s: firmware loaded\n", device_xname(sc->sc_dev));
    920        1.1   tsutsui 
    921        1.1   tsutsui 	return 0;
    922        1.1   tsutsui }
    923        1.1   tsutsui 
    924        1.1   tsutsui /*
    925        1.1   tsutsui  * While copying the version 2 firmware, we need to replace two characters:
    926        1.1   tsutsui  *
    927        1.1   tsutsui  * 0x7e -> 0x7d 0x5e
    928        1.1   tsutsui  * 0x7d -> 0x7d 0x5d
    929        1.1   tsutsui  */
    930        1.1   tsutsui static int
    931        1.1   tsutsui upgt_fw_copy(char *src, char *dst, int size)
    932        1.1   tsutsui {
    933        1.1   tsutsui 	int i, j;
    934        1.1   tsutsui 
    935        1.1   tsutsui 	for (i = 0, j = 0; i < size && j < size; i++) {
    936        1.1   tsutsui 		switch (src[i]) {
    937        1.1   tsutsui 		case 0x7e:
    938        1.1   tsutsui 			dst[j] = 0x7d;
    939        1.1   tsutsui 			j++;
    940        1.1   tsutsui 			dst[j] = 0x5e;
    941        1.1   tsutsui 			j++;
    942        1.1   tsutsui 			break;
    943        1.1   tsutsui 		case 0x7d:
    944        1.1   tsutsui 			dst[j] = 0x7d;
    945        1.1   tsutsui 			j++;
    946        1.1   tsutsui 			dst[j] = 0x5d;
    947        1.1   tsutsui 			j++;
    948        1.1   tsutsui 			break;
    949        1.1   tsutsui 		default:
    950        1.1   tsutsui 			dst[j] = src[i];
    951        1.1   tsutsui 			j++;
    952        1.1   tsutsui 			break;
    953        1.1   tsutsui 		}
    954        1.1   tsutsui 	}
    955        1.1   tsutsui 
    956        1.1   tsutsui 	return i;
    957        1.1   tsutsui }
    958        1.1   tsutsui 
    959        1.1   tsutsui static int
    960        1.1   tsutsui upgt_eeprom_read(struct upgt_softc *sc)
    961        1.1   tsutsui {
    962        1.1   tsutsui 	struct upgt_data *data_cmd = &sc->cmd_data;
    963        1.1   tsutsui 	struct upgt_lmac_mem *mem;
    964        1.1   tsutsui 	struct upgt_lmac_eeprom	*eeprom;
    965        1.1   tsutsui 	int offset, block, len;
    966        1.1   tsutsui 
    967        1.1   tsutsui 	offset = 0;
    968        1.1   tsutsui 	block = UPGT_EEPROM_BLOCK_SIZE;
    969        1.1   tsutsui 	while (offset < UPGT_EEPROM_SIZE) {
    970        1.1   tsutsui 		DPRINTF(1, "%s: request EEPROM block (offset=%d, len=%d)\n",
    971        1.1   tsutsui 		    device_xname(sc->sc_dev), offset, block);
    972        1.1   tsutsui 
    973        1.1   tsutsui 		/*
    974        1.1   tsutsui 		 * Transmit the URB containing the CMD data.
    975        1.1   tsutsui 		 */
    976        1.1   tsutsui 		len = sizeof(*mem) + sizeof(*eeprom) + block;
    977        1.1   tsutsui 
    978        1.1   tsutsui 		memset(data_cmd->buf, 0, len);
    979        1.1   tsutsui 
    980        1.1   tsutsui 		mem = (struct upgt_lmac_mem *)data_cmd->buf;
    981        1.1   tsutsui 		mem->addr = htole32(sc->sc_memaddr_frame_start +
    982        1.1   tsutsui 		    UPGT_MEMSIZE_FRAME_HEAD);
    983        1.1   tsutsui 
    984        1.1   tsutsui 		eeprom = (struct upgt_lmac_eeprom *)(mem + 1);
    985        1.1   tsutsui 		eeprom->header1.flags = 0;
    986        1.1   tsutsui 		eeprom->header1.type = UPGT_H1_TYPE_CTRL;
    987        1.1   tsutsui 		eeprom->header1.len = htole16((
    988        1.1   tsutsui 		    sizeof(struct upgt_lmac_eeprom) -
    989        1.1   tsutsui 		    sizeof(struct upgt_lmac_header)) + block);
    990        1.1   tsutsui 
    991        1.1   tsutsui 		eeprom->header2.reqid = htole32(sc->sc_memaddr_frame_start);
    992        1.1   tsutsui 		eeprom->header2.type = htole16(UPGT_H2_TYPE_EEPROM);
    993        1.1   tsutsui 		eeprom->header2.flags = 0;
    994        1.1   tsutsui 
    995        1.1   tsutsui 		eeprom->offset = htole16(offset);
    996        1.1   tsutsui 		eeprom->len = htole16(block);
    997        1.1   tsutsui 
    998        1.1   tsutsui 		mem->chksum = upgt_chksum_le((uint32_t *)eeprom,
    999        1.1   tsutsui 		    len - sizeof(*mem));
   1000        1.1   tsutsui 
   1001        1.1   tsutsui 		if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len,
   1002        1.1   tsutsui 		    USBD_FORCE_SHORT_XFER) != 0) {
   1003        1.1   tsutsui 			aprint_error_dev(sc->sc_dev,
   1004        1.1   tsutsui 			    "could not transmit EEPROM data URB\n");
   1005        1.1   tsutsui 			return EIO;
   1006        1.1   tsutsui 		}
   1007  1.12.4.11     skrll 
   1008  1.12.4.11     skrll 		mutex_enter(&sc->sc_mtx);
   1009  1.12.4.11     skrll 		int res = cv_timedwait(&sc->sc_cv, &sc->sc_mtx, UPGT_USB_TIMEOUT);
   1010  1.12.4.11     skrll 		mutex_exit(&sc->sc_mtx);
   1011  1.12.4.11     skrll 		if (res) {
   1012        1.1   tsutsui 			aprint_error_dev(sc->sc_dev,
   1013        1.1   tsutsui 			    "timeout while waiting for EEPROM data\n");
   1014        1.1   tsutsui 			return EIO;
   1015        1.1   tsutsui 		}
   1016        1.1   tsutsui 
   1017        1.1   tsutsui 		offset += block;
   1018        1.1   tsutsui 		if (UPGT_EEPROM_SIZE - offset < block)
   1019        1.1   tsutsui 			block = UPGT_EEPROM_SIZE - offset;
   1020        1.1   tsutsui 	}
   1021        1.1   tsutsui 
   1022        1.1   tsutsui 	return 0;
   1023        1.1   tsutsui }
   1024        1.1   tsutsui 
   1025        1.1   tsutsui static int
   1026        1.1   tsutsui upgt_eeprom_parse(struct upgt_softc *sc)
   1027        1.1   tsutsui {
   1028        1.1   tsutsui 	struct ieee80211com *ic = &sc->sc_ic;
   1029        1.1   tsutsui 	struct upgt_eeprom_header *eeprom_header;
   1030        1.1   tsutsui 	struct upgt_eeprom_option *eeprom_option;
   1031        1.1   tsutsui 	uint16_t option_len;
   1032        1.1   tsutsui 	uint16_t option_type;
   1033        1.1   tsutsui 	uint16_t preamble_len;
   1034        1.1   tsutsui 	int option_end = 0;
   1035        1.1   tsutsui 
   1036        1.1   tsutsui 	/* calculate eeprom options start offset */
   1037        1.1   tsutsui 	eeprom_header = (struct upgt_eeprom_header *)sc->sc_eeprom;
   1038        1.1   tsutsui 	preamble_len = le16toh(eeprom_header->preamble_len);
   1039        1.1   tsutsui 	eeprom_option = (struct upgt_eeprom_option *)(sc->sc_eeprom +
   1040        1.1   tsutsui 	    (sizeof(struct upgt_eeprom_header) + preamble_len));
   1041        1.1   tsutsui 
   1042        1.1   tsutsui 	while (!option_end) {
   1043        1.1   tsutsui 		/* the eeprom option length is stored in words */
   1044        1.1   tsutsui 		option_len =
   1045        1.1   tsutsui 		    (le16toh(eeprom_option->len) - 1) * sizeof(uint16_t);
   1046        1.1   tsutsui 		option_type =
   1047        1.1   tsutsui 		    le16toh(eeprom_option->type);
   1048        1.1   tsutsui 
   1049        1.1   tsutsui 		switch (option_type) {
   1050        1.1   tsutsui 		case UPGT_EEPROM_TYPE_NAME:
   1051        1.1   tsutsui 			DPRINTF(1, "%s: EEPROM name len=%d\n",
   1052        1.1   tsutsui 			    device_xname(sc->sc_dev), option_len);
   1053        1.1   tsutsui 			break;
   1054        1.1   tsutsui 		case UPGT_EEPROM_TYPE_SERIAL:
   1055        1.1   tsutsui 			DPRINTF(1, "%s: EEPROM serial len=%d\n",
   1056        1.1   tsutsui 			    device_xname(sc->sc_dev), option_len);
   1057        1.1   tsutsui 			break;
   1058        1.1   tsutsui 		case UPGT_EEPROM_TYPE_MAC:
   1059        1.1   tsutsui 			DPRINTF(1, "%s: EEPROM mac len=%d\n",
   1060        1.1   tsutsui 			    device_xname(sc->sc_dev), option_len);
   1061        1.1   tsutsui 
   1062        1.1   tsutsui 			IEEE80211_ADDR_COPY(ic->ic_myaddr, eeprom_option->data);
   1063        1.1   tsutsui 			break;
   1064        1.1   tsutsui 		case UPGT_EEPROM_TYPE_HWRX:
   1065        1.1   tsutsui 			DPRINTF(1, "%s: EEPROM hwrx len=%d\n",
   1066        1.1   tsutsui 			    device_xname(sc->sc_dev), option_len);
   1067        1.1   tsutsui 
   1068        1.1   tsutsui 			upgt_eeprom_parse_hwrx(sc, eeprom_option->data);
   1069        1.1   tsutsui 			break;
   1070        1.1   tsutsui 		case UPGT_EEPROM_TYPE_CHIP:
   1071        1.1   tsutsui 			DPRINTF(1, "%s: EEPROM chip len=%d\n",
   1072        1.1   tsutsui 			    device_xname(sc->sc_dev), option_len);
   1073        1.1   tsutsui 			break;
   1074        1.1   tsutsui 		case UPGT_EEPROM_TYPE_FREQ3:
   1075        1.1   tsutsui 			DPRINTF(1, "%s: EEPROM freq3 len=%d\n",
   1076        1.1   tsutsui 			    device_xname(sc->sc_dev), option_len);
   1077        1.1   tsutsui 
   1078        1.1   tsutsui 			upgt_eeprom_parse_freq3(sc, eeprom_option->data,
   1079        1.1   tsutsui 			    option_len);
   1080        1.1   tsutsui 			break;
   1081        1.1   tsutsui 		case UPGT_EEPROM_TYPE_FREQ4:
   1082        1.1   tsutsui 			DPRINTF(1, "%s: EEPROM freq4 len=%d\n",
   1083        1.1   tsutsui 			    device_xname(sc->sc_dev), option_len);
   1084        1.1   tsutsui 
   1085        1.1   tsutsui 			upgt_eeprom_parse_freq4(sc, eeprom_option->data,
   1086        1.1   tsutsui 			    option_len);
   1087        1.1   tsutsui 			break;
   1088        1.1   tsutsui 		case UPGT_EEPROM_TYPE_FREQ5:
   1089        1.1   tsutsui 			DPRINTF(1, "%s: EEPROM freq5 len=%d\n",
   1090        1.1   tsutsui 			    device_xname(sc->sc_dev), option_len);
   1091        1.1   tsutsui 			break;
   1092        1.1   tsutsui 		case UPGT_EEPROM_TYPE_FREQ6:
   1093        1.1   tsutsui 			DPRINTF(1, "%s: EEPROM freq6 len=%d\n",
   1094        1.1   tsutsui 			    device_xname(sc->sc_dev), option_len);
   1095        1.1   tsutsui 
   1096        1.1   tsutsui 			upgt_eeprom_parse_freq6(sc, eeprom_option->data,
   1097        1.1   tsutsui 			    option_len);
   1098        1.1   tsutsui 			break;
   1099        1.1   tsutsui 		case UPGT_EEPROM_TYPE_END:
   1100        1.1   tsutsui 			DPRINTF(1, "%s: EEPROM end len=%d\n",
   1101        1.1   tsutsui 			    device_xname(sc->sc_dev), option_len);
   1102        1.1   tsutsui 			option_end = 1;
   1103        1.1   tsutsui 			break;
   1104        1.1   tsutsui 		case UPGT_EEPROM_TYPE_OFF:
   1105        1.1   tsutsui 			DPRINTF(1, "%s: EEPROM off without end option\n",
   1106        1.1   tsutsui 			    device_xname(sc->sc_dev));
   1107        1.1   tsutsui 			return EIO;
   1108        1.1   tsutsui 		default:
   1109        1.1   tsutsui 			DPRINTF(1, "%s: EEPROM unknown type 0x%04x len=%d\n",
   1110        1.1   tsutsui 			    device_xname(sc->sc_dev), option_type, option_len);
   1111        1.1   tsutsui 			break;
   1112        1.1   tsutsui 		}
   1113        1.1   tsutsui 
   1114        1.1   tsutsui 		/* jump to next EEPROM option */
   1115        1.1   tsutsui 		eeprom_option = (struct upgt_eeprom_option *)
   1116        1.1   tsutsui 		    (eeprom_option->data + option_len);
   1117        1.1   tsutsui 	}
   1118        1.1   tsutsui 
   1119        1.1   tsutsui 	return 0;
   1120        1.1   tsutsui }
   1121        1.1   tsutsui 
   1122        1.1   tsutsui static void
   1123        1.1   tsutsui upgt_eeprom_parse_hwrx(struct upgt_softc *sc, uint8_t *data)
   1124        1.1   tsutsui {
   1125        1.1   tsutsui 	struct upgt_eeprom_option_hwrx *option_hwrx;
   1126        1.1   tsutsui 
   1127        1.1   tsutsui 	option_hwrx = (struct upgt_eeprom_option_hwrx *)data;
   1128        1.1   tsutsui 
   1129        1.1   tsutsui 	sc->sc_eeprom_hwrx = option_hwrx->rxfilter - UPGT_EEPROM_RX_CONST;
   1130        1.1   tsutsui 
   1131        1.1   tsutsui 	DPRINTF(2, "%s: hwrx option value=0x%04x\n",
   1132        1.1   tsutsui 	    device_xname(sc->sc_dev), sc->sc_eeprom_hwrx);
   1133        1.1   tsutsui }
   1134        1.1   tsutsui 
   1135        1.1   tsutsui static void
   1136        1.1   tsutsui upgt_eeprom_parse_freq3(struct upgt_softc *sc, uint8_t *data, int len)
   1137        1.1   tsutsui {
   1138        1.1   tsutsui 	struct upgt_eeprom_freq3_header *freq3_header;
   1139        1.1   tsutsui 	struct upgt_lmac_freq3 *freq3;
   1140        1.1   tsutsui 	int i, elements, flags;
   1141        1.1   tsutsui 	unsigned channel;
   1142        1.1   tsutsui 
   1143        1.1   tsutsui 	freq3_header = (struct upgt_eeprom_freq3_header *)data;
   1144        1.1   tsutsui 	freq3 = (struct upgt_lmac_freq3 *)(freq3_header + 1);
   1145        1.1   tsutsui 
   1146        1.1   tsutsui 	flags = freq3_header->flags;
   1147        1.1   tsutsui 	elements = freq3_header->elements;
   1148        1.1   tsutsui 
   1149        1.1   tsutsui 	DPRINTF(2, "%s: flags=0x%02x\n", device_xname(sc->sc_dev), flags);
   1150        1.1   tsutsui 	DPRINTF(2, "%s: elements=%d\n", device_xname(sc->sc_dev), elements);
   1151       1.10  christos 	__USE(flags);
   1152        1.1   tsutsui 
   1153        1.1   tsutsui 	for (i = 0; i < elements; i++) {
   1154        1.1   tsutsui 		channel = ieee80211_mhz2ieee(le16toh(freq3[i].freq), 0);
   1155        1.1   tsutsui 
   1156        1.1   tsutsui 		sc->sc_eeprom_freq3[channel] = freq3[i];
   1157        1.1   tsutsui 
   1158        1.1   tsutsui 		DPRINTF(2, "%s: frequence=%d, channel=%d\n",
   1159        1.1   tsutsui 		    device_xname(sc->sc_dev),
   1160        1.1   tsutsui 		    le16toh(sc->sc_eeprom_freq3[channel].freq), channel);
   1161        1.1   tsutsui 	}
   1162        1.1   tsutsui }
   1163        1.1   tsutsui 
   1164        1.1   tsutsui static void
   1165        1.1   tsutsui upgt_eeprom_parse_freq4(struct upgt_softc *sc, uint8_t *data, int len)
   1166        1.1   tsutsui {
   1167        1.1   tsutsui 	struct upgt_eeprom_freq4_header *freq4_header;
   1168        1.1   tsutsui 	struct upgt_eeprom_freq4_1 *freq4_1;
   1169        1.1   tsutsui 	struct upgt_eeprom_freq4_2 *freq4_2;
   1170        1.1   tsutsui 	int i, j, elements, settings, flags;
   1171        1.1   tsutsui 	unsigned channel;
   1172        1.1   tsutsui 
   1173        1.1   tsutsui 	freq4_header = (struct upgt_eeprom_freq4_header *)data;
   1174        1.1   tsutsui 	freq4_1 = (struct upgt_eeprom_freq4_1 *)(freq4_header + 1);
   1175        1.1   tsutsui 
   1176        1.1   tsutsui 	flags = freq4_header->flags;
   1177        1.1   tsutsui 	elements = freq4_header->elements;
   1178        1.1   tsutsui 	settings = freq4_header->settings;
   1179        1.1   tsutsui 
   1180        1.1   tsutsui 	/* we need this value later */
   1181        1.1   tsutsui 	sc->sc_eeprom_freq6_settings = freq4_header->settings;
   1182        1.1   tsutsui 
   1183        1.1   tsutsui 	DPRINTF(2, "%s: flags=0x%02x\n", device_xname(sc->sc_dev), flags);
   1184        1.1   tsutsui 	DPRINTF(2, "%s: elements=%d\n", device_xname(sc->sc_dev), elements);
   1185        1.1   tsutsui 	DPRINTF(2, "%s: settings=%d\n", device_xname(sc->sc_dev), settings);
   1186       1.10  christos 	__USE(flags);
   1187        1.1   tsutsui 
   1188        1.1   tsutsui 	for (i = 0; i < elements; i++) {
   1189        1.1   tsutsui 		channel = ieee80211_mhz2ieee(le16toh(freq4_1[i].freq), 0);
   1190        1.1   tsutsui 
   1191        1.1   tsutsui 		freq4_2 = (struct upgt_eeprom_freq4_2 *)freq4_1[i].data;
   1192        1.1   tsutsui 
   1193        1.1   tsutsui 		for (j = 0; j < settings; j++) {
   1194        1.1   tsutsui 			sc->sc_eeprom_freq4[channel][j].cmd = freq4_2[j];
   1195        1.1   tsutsui 			sc->sc_eeprom_freq4[channel][j].pad = 0;
   1196        1.1   tsutsui 		}
   1197        1.1   tsutsui 
   1198        1.1   tsutsui 		DPRINTF(2, "%s: frequence=%d, channel=%d\n",
   1199        1.1   tsutsui 		    device_xname(sc->sc_dev),
   1200        1.1   tsutsui 		    le16toh(freq4_1[i].freq), channel);
   1201        1.1   tsutsui 	}
   1202        1.1   tsutsui }
   1203        1.1   tsutsui 
   1204        1.1   tsutsui static void
   1205        1.1   tsutsui upgt_eeprom_parse_freq6(struct upgt_softc *sc, uint8_t *data, int len)
   1206        1.1   tsutsui {
   1207        1.1   tsutsui 	struct upgt_lmac_freq6 *freq6;
   1208        1.1   tsutsui 	int i, elements;
   1209        1.1   tsutsui 	unsigned channel;
   1210        1.1   tsutsui 
   1211        1.1   tsutsui 	freq6 = (struct upgt_lmac_freq6 *)data;
   1212        1.1   tsutsui 
   1213        1.1   tsutsui 	elements = len / sizeof(struct upgt_lmac_freq6);
   1214        1.1   tsutsui 
   1215        1.1   tsutsui 	DPRINTF(2, "%s: elements=%d\n", device_xname(sc->sc_dev), elements);
   1216        1.1   tsutsui 
   1217        1.1   tsutsui 	for (i = 0; i < elements; i++) {
   1218        1.1   tsutsui 		channel = ieee80211_mhz2ieee(le16toh(freq6[i].freq), 0);
   1219        1.1   tsutsui 
   1220        1.1   tsutsui 		sc->sc_eeprom_freq6[channel] = freq6[i];
   1221        1.1   tsutsui 
   1222        1.1   tsutsui 		DPRINTF(2, "%s: frequence=%d, channel=%d\n",
   1223        1.1   tsutsui 		    device_xname(sc->sc_dev),
   1224        1.1   tsutsui 		    le16toh(sc->sc_eeprom_freq6[channel].freq), channel);
   1225        1.1   tsutsui 	}
   1226        1.1   tsutsui }
   1227        1.1   tsutsui 
   1228        1.1   tsutsui static int
   1229        1.1   tsutsui upgt_ioctl(struct ifnet *ifp, u_long cmd, void *data)
   1230        1.1   tsutsui {
   1231        1.1   tsutsui 	struct upgt_softc *sc = ifp->if_softc;
   1232        1.1   tsutsui 	struct ieee80211com *ic = &sc->sc_ic;
   1233        1.1   tsutsui 	int s, error = 0;
   1234        1.1   tsutsui 
   1235        1.1   tsutsui 	s = splnet();
   1236        1.1   tsutsui 
   1237        1.1   tsutsui 	switch (cmd) {
   1238        1.1   tsutsui 	case SIOCSIFFLAGS:
   1239        1.1   tsutsui 		if ((error = ifioctl_common(ifp, cmd, data)) != 0)
   1240        1.1   tsutsui 			break;
   1241        1.1   tsutsui 		if (ifp->if_flags & IFF_UP) {
   1242        1.1   tsutsui 			if ((ifp->if_flags & IFF_RUNNING) == 0)
   1243        1.1   tsutsui 				upgt_init(ifp);
   1244        1.1   tsutsui 		} else {
   1245        1.1   tsutsui 			if (ifp->if_flags & IFF_RUNNING)
   1246        1.1   tsutsui 				upgt_stop(sc);
   1247        1.1   tsutsui 		}
   1248        1.1   tsutsui 		break;
   1249        1.1   tsutsui 	case SIOCADDMULTI:
   1250        1.1   tsutsui 	case SIOCDELMULTI:
   1251        1.1   tsutsui 		if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) {
   1252        1.1   tsutsui 			/* setup multicast filter, etc */
   1253        1.1   tsutsui 			error = 0;
   1254        1.1   tsutsui 		}
   1255        1.1   tsutsui 		break;
   1256        1.1   tsutsui 	default:
   1257        1.1   tsutsui 		error = ieee80211_ioctl(ic, cmd, data);
   1258        1.1   tsutsui 		break;
   1259        1.1   tsutsui 	}
   1260        1.1   tsutsui 
   1261        1.1   tsutsui 	if (error == ENETRESET) {
   1262        1.1   tsutsui 		if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
   1263        1.1   tsutsui 		    (IFF_UP | IFF_RUNNING))
   1264        1.1   tsutsui 			upgt_init(ifp);
   1265        1.1   tsutsui 		error = 0;
   1266        1.1   tsutsui 	}
   1267        1.1   tsutsui 
   1268        1.1   tsutsui 	splx(s);
   1269        1.1   tsutsui 
   1270        1.1   tsutsui 	return error;
   1271        1.1   tsutsui }
   1272        1.1   tsutsui 
   1273        1.1   tsutsui static int
   1274        1.1   tsutsui upgt_init(struct ifnet *ifp)
   1275        1.1   tsutsui {
   1276        1.1   tsutsui 	struct upgt_softc *sc = ifp->if_softc;
   1277        1.1   tsutsui 	struct ieee80211com *ic = &sc->sc_ic;
   1278        1.1   tsutsui 
   1279        1.1   tsutsui 	DPRINTF(1, "%s: %s\n", device_xname(sc->sc_dev), __func__);
   1280        1.1   tsutsui 
   1281        1.1   tsutsui 	if (ifp->if_flags & IFF_RUNNING)
   1282        1.1   tsutsui 		upgt_stop(sc);
   1283        1.1   tsutsui 
   1284        1.1   tsutsui 	ifp->if_flags |= IFF_RUNNING;
   1285        1.1   tsutsui 	ifp->if_flags &= ~IFF_OACTIVE;
   1286        1.1   tsutsui 
   1287        1.1   tsutsui 	IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl));
   1288        1.1   tsutsui 
   1289        1.1   tsutsui 	/* setup device rates */
   1290        1.1   tsutsui 	upgt_setup_rates(sc);
   1291        1.1   tsutsui 
   1292        1.1   tsutsui 	if (ic->ic_opmode == IEEE80211_M_MONITOR)
   1293        1.1   tsutsui 		ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
   1294        1.1   tsutsui 	else
   1295        1.1   tsutsui 		ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
   1296        1.1   tsutsui 
   1297        1.1   tsutsui 	return 0;
   1298        1.1   tsutsui }
   1299        1.1   tsutsui 
   1300        1.1   tsutsui static void
   1301        1.1   tsutsui upgt_stop(struct upgt_softc *sc)
   1302        1.1   tsutsui {
   1303        1.1   tsutsui 	struct ieee80211com *ic = &sc->sc_ic;
   1304        1.1   tsutsui 	struct ifnet *ifp = &sc->sc_if;
   1305        1.1   tsutsui 
   1306        1.1   tsutsui 	DPRINTF(1, "%s: %s\n", device_xname(sc->sc_dev), __func__);
   1307        1.1   tsutsui 
   1308        1.1   tsutsui 	/* device down */
   1309        1.1   tsutsui 	ifp->if_timer = 0;
   1310        1.1   tsutsui 	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
   1311        1.1   tsutsui 
   1312        1.1   tsutsui 	/* change device back to initial state */
   1313        1.1   tsutsui 	ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
   1314        1.1   tsutsui }
   1315        1.1   tsutsui 
   1316        1.1   tsutsui static int
   1317        1.1   tsutsui upgt_media_change(struct ifnet *ifp)
   1318        1.1   tsutsui {
   1319        1.1   tsutsui 	struct upgt_softc *sc = ifp->if_softc;
   1320        1.1   tsutsui 	int error;
   1321        1.1   tsutsui 
   1322        1.1   tsutsui 	DPRINTF(1, "%s: %s\n", device_xname(sc->sc_dev), __func__);
   1323        1.1   tsutsui 
   1324  1.12.4.10     skrll 	if ((error = ieee80211_media_change(ifp)) != ENETRESET)
   1325        1.1   tsutsui 		return error;
   1326        1.1   tsutsui 
   1327        1.1   tsutsui 	if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
   1328        1.1   tsutsui 	    (IFF_UP | IFF_RUNNING)) {
   1329        1.1   tsutsui 		/* give pending USB transfers a chance to finish */
   1330        1.1   tsutsui 		usbd_delay_ms(sc->sc_udev, 100);
   1331        1.1   tsutsui 		upgt_init(ifp);
   1332        1.1   tsutsui 	}
   1333        1.1   tsutsui 
   1334        1.1   tsutsui 	return 0;
   1335        1.1   tsutsui }
   1336        1.1   tsutsui 
   1337        1.1   tsutsui static void
   1338        1.1   tsutsui upgt_newassoc(struct ieee80211_node *ni, int isnew)
   1339        1.1   tsutsui {
   1340        1.1   tsutsui 
   1341        1.1   tsutsui 	ni->ni_txrate = 0;
   1342        1.1   tsutsui }
   1343        1.1   tsutsui 
   1344        1.1   tsutsui static int
   1345        1.1   tsutsui upgt_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
   1346        1.1   tsutsui {
   1347        1.1   tsutsui 	struct upgt_softc *sc = ic->ic_ifp->if_softc;
   1348        1.1   tsutsui 
   1349        1.1   tsutsui 	usb_rem_task(sc->sc_udev, &sc->sc_task_newstate);
   1350        1.1   tsutsui 	callout_stop(&sc->scan_to);
   1351        1.1   tsutsui 
   1352        1.1   tsutsui 	/* do it in a process context */
   1353        1.1   tsutsui 	sc->sc_state = nstate;
   1354        1.1   tsutsui 	sc->sc_arg = arg;
   1355        1.1   tsutsui 	usb_add_task(sc->sc_udev, &sc->sc_task_newstate, USB_TASKQ_DRIVER);
   1356        1.1   tsutsui 
   1357        1.1   tsutsui 	return 0;
   1358        1.1   tsutsui }
   1359        1.1   tsutsui 
   1360        1.1   tsutsui static void
   1361        1.1   tsutsui upgt_newstate_task(void *arg)
   1362        1.1   tsutsui {
   1363        1.1   tsutsui 	struct upgt_softc *sc = arg;
   1364        1.1   tsutsui 	struct ieee80211com *ic = &sc->sc_ic;
   1365        1.1   tsutsui 	struct ieee80211_node *ni;
   1366        1.1   tsutsui 	unsigned channel;
   1367        1.1   tsutsui 
   1368        1.1   tsutsui 	mutex_enter(&sc->sc_mtx);
   1369        1.1   tsutsui 
   1370        1.1   tsutsui 	switch (sc->sc_state) {
   1371        1.1   tsutsui 	case IEEE80211_S_INIT:
   1372        1.1   tsutsui 		DPRINTF(1, "%s: newstate is IEEE80211_S_INIT\n",
   1373        1.1   tsutsui 		    device_xname(sc->sc_dev));
   1374        1.1   tsutsui 
   1375        1.1   tsutsui 		/* do not accept any frames if the device is down */
   1376        1.1   tsutsui 		upgt_set_macfilter(sc, IEEE80211_S_INIT);
   1377        1.1   tsutsui 		upgt_set_led(sc, UPGT_LED_OFF);
   1378        1.1   tsutsui 		break;
   1379        1.1   tsutsui 	case IEEE80211_S_SCAN:
   1380        1.1   tsutsui 		DPRINTF(1, "%s: newstate is IEEE80211_S_SCAN\n",
   1381        1.1   tsutsui 		    device_xname(sc->sc_dev));
   1382        1.1   tsutsui 
   1383        1.1   tsutsui 		channel = ieee80211_chan2ieee(ic, ic->ic_curchan);
   1384        1.1   tsutsui 		upgt_set_channel(sc, channel);
   1385        1.1   tsutsui 		upgt_set_macfilter(sc, IEEE80211_S_SCAN);
   1386        1.1   tsutsui 		callout_schedule(&sc->scan_to, hz / 5);
   1387        1.1   tsutsui 		break;
   1388        1.1   tsutsui 	case IEEE80211_S_AUTH:
   1389        1.1   tsutsui 		DPRINTF(1, "%s: newstate is IEEE80211_S_AUTH\n",
   1390        1.1   tsutsui 		    device_xname(sc->sc_dev));
   1391        1.1   tsutsui 
   1392        1.1   tsutsui 		channel = ieee80211_chan2ieee(ic, ic->ic_curchan);
   1393        1.1   tsutsui 		upgt_set_channel(sc, channel);
   1394        1.1   tsutsui 		break;
   1395        1.1   tsutsui 	case IEEE80211_S_ASSOC:
   1396        1.1   tsutsui 		DPRINTF(1, "%s: newstate is IEEE80211_S_ASSOC\n",
   1397        1.1   tsutsui 		    device_xname(sc->sc_dev));
   1398        1.1   tsutsui 
   1399        1.1   tsutsui 		channel = ieee80211_chan2ieee(ic, ic->ic_curchan);
   1400        1.1   tsutsui 		upgt_set_channel(sc, channel);
   1401        1.1   tsutsui 		break;
   1402        1.1   tsutsui 	case IEEE80211_S_RUN:
   1403        1.1   tsutsui 		DPRINTF(1, "%s: newstate is IEEE80211_S_RUN\n",
   1404        1.1   tsutsui 		    device_xname(sc->sc_dev));
   1405        1.1   tsutsui 
   1406        1.1   tsutsui 		channel = ieee80211_chan2ieee(ic, ic->ic_curchan);
   1407        1.1   tsutsui 		upgt_set_channel(sc, channel);
   1408        1.1   tsutsui 
   1409        1.1   tsutsui 		ni = ic->ic_bss;
   1410        1.1   tsutsui 
   1411        1.1   tsutsui 		/*
   1412        1.1   tsutsui 		 * TX rate control is done by the firmware.
   1413        1.1   tsutsui 		 * Report the maximum rate which is available therefore.
   1414        1.1   tsutsui 		 */
   1415        1.1   tsutsui 		ni->ni_txrate = ni->ni_rates.rs_nrates - 1;
   1416        1.1   tsutsui 
   1417        1.1   tsutsui 		if (ic->ic_opmode != IEEE80211_M_MONITOR)
   1418        1.1   tsutsui 			upgt_set_macfilter(sc, IEEE80211_S_RUN);
   1419        1.1   tsutsui 		upgt_set_led(sc, UPGT_LED_ON);
   1420        1.1   tsutsui 		break;
   1421        1.1   tsutsui 	}
   1422        1.1   tsutsui 
   1423        1.1   tsutsui 	mutex_exit(&sc->sc_mtx);
   1424        1.1   tsutsui 
   1425        1.1   tsutsui 	sc->sc_newstate(ic, sc->sc_state, sc->sc_arg);
   1426        1.1   tsutsui }
   1427        1.1   tsutsui 
   1428        1.1   tsutsui static void
   1429        1.1   tsutsui upgt_next_scan(void *arg)
   1430        1.1   tsutsui {
   1431        1.1   tsutsui 	struct upgt_softc *sc = arg;
   1432        1.1   tsutsui 	struct ieee80211com *ic = &sc->sc_ic;
   1433        1.1   tsutsui 
   1434        1.1   tsutsui 	DPRINTF(2, "%s: %s\n", device_xname(sc->sc_dev), __func__);
   1435        1.1   tsutsui 
   1436        1.1   tsutsui 	if (ic->ic_state == IEEE80211_S_SCAN)
   1437        1.1   tsutsui 		ieee80211_next_scan(ic);
   1438        1.1   tsutsui }
   1439        1.1   tsutsui 
   1440        1.1   tsutsui static void
   1441        1.1   tsutsui upgt_start(struct ifnet *ifp)
   1442        1.1   tsutsui {
   1443        1.1   tsutsui 	struct upgt_softc *sc = ifp->if_softc;
   1444        1.1   tsutsui 	struct ieee80211com *ic = &sc->sc_ic;
   1445        1.1   tsutsui 	struct ether_header *eh;
   1446        1.1   tsutsui 	struct ieee80211_node *ni;
   1447        1.1   tsutsui 	struct mbuf *m;
   1448        1.1   tsutsui 	int i;
   1449        1.1   tsutsui 
   1450        1.1   tsutsui 	/* don't transmit packets if interface is busy or down */
   1451        1.1   tsutsui 	if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
   1452        1.1   tsutsui 		return;
   1453        1.1   tsutsui 
   1454        1.1   tsutsui 	DPRINTF(2, "%s: %s\n", device_xname(sc->sc_dev), __func__);
   1455        1.1   tsutsui 
   1456        1.1   tsutsui 	for (i = 0; i < UPGT_TX_COUNT; i++) {
   1457        1.1   tsutsui 		struct upgt_data *data_tx = &sc->tx_data[i];
   1458        1.1   tsutsui 
   1459        1.1   tsutsui 		if (data_tx->m != NULL)
   1460        1.1   tsutsui 			continue;
   1461        1.1   tsutsui 
   1462        1.1   tsutsui 		IF_POLL(&ic->ic_mgtq, m);
   1463        1.1   tsutsui 		if (m != NULL) {
   1464        1.1   tsutsui 			/* management frame */
   1465        1.1   tsutsui 			IF_DEQUEUE(&ic->ic_mgtq, m);
   1466        1.1   tsutsui 
   1467        1.1   tsutsui 			ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
   1468        1.1   tsutsui 			m->m_pkthdr.rcvif = NULL;
   1469        1.1   tsutsui 
   1470        1.1   tsutsui 			bpf_mtap3(ic->ic_rawbpf, m);
   1471        1.1   tsutsui 
   1472        1.1   tsutsui 			if ((data_tx->addr = upgt_mem_alloc(sc)) == 0) {
   1473        1.1   tsutsui 				aprint_error_dev(sc->sc_dev,
   1474        1.1   tsutsui 				    "no free prism memory\n");
   1475        1.1   tsutsui 				m_freem(m);
   1476        1.1   tsutsui 				ifp->if_oerrors++;
   1477        1.1   tsutsui 				break;
   1478        1.1   tsutsui 			}
   1479        1.1   tsutsui 			data_tx->ni = ni;
   1480        1.1   tsutsui 			data_tx->m = m;
   1481        1.1   tsutsui 			sc->tx_queued++;
   1482        1.1   tsutsui 		} else {
   1483        1.1   tsutsui 			/* data frame */
   1484        1.1   tsutsui 			if (ic->ic_state != IEEE80211_S_RUN)
   1485        1.1   tsutsui 				break;
   1486        1.1   tsutsui 
   1487        1.1   tsutsui 			IFQ_POLL(&ifp->if_snd, m);
   1488        1.1   tsutsui 			if (m == NULL)
   1489        1.1   tsutsui 				break;
   1490        1.1   tsutsui 
   1491        1.1   tsutsui 			IFQ_DEQUEUE(&ifp->if_snd, m);
   1492        1.1   tsutsui 			if (m->m_len < sizeof(struct ether_header) &&
   1493        1.1   tsutsui 			    !(m = m_pullup(m, sizeof(struct ether_header))))
   1494        1.1   tsutsui 				continue;
   1495        1.1   tsutsui 
   1496        1.1   tsutsui 			eh = mtod(m, struct ether_header *);
   1497        1.1   tsutsui 			ni = ieee80211_find_txnode(ic, eh->ether_dhost);
   1498        1.1   tsutsui 			if (ni == NULL) {
   1499        1.1   tsutsui 				m_freem(m);
   1500        1.1   tsutsui 				continue;
   1501        1.1   tsutsui 			}
   1502        1.1   tsutsui 
   1503        1.1   tsutsui 			bpf_mtap(ifp, m);
   1504        1.1   tsutsui 
   1505        1.1   tsutsui 			m = ieee80211_encap(ic, m, ni);
   1506        1.1   tsutsui 			if (m == NULL) {
   1507        1.1   tsutsui 				ieee80211_free_node(ni);
   1508        1.1   tsutsui 				continue;
   1509        1.1   tsutsui 			}
   1510        1.1   tsutsui 
   1511        1.1   tsutsui 			bpf_mtap3(ic->ic_rawbpf, m);
   1512        1.1   tsutsui 
   1513        1.1   tsutsui 			if ((data_tx->addr = upgt_mem_alloc(sc)) == 0) {
   1514        1.1   tsutsui 				aprint_error_dev(sc->sc_dev,
   1515        1.1   tsutsui 				    "no free prism memory\n");
   1516        1.1   tsutsui 				m_freem(m);
   1517        1.1   tsutsui 				ieee80211_free_node(ni);
   1518        1.1   tsutsui 				ifp->if_oerrors++;
   1519        1.1   tsutsui 				break;
   1520        1.1   tsutsui 			}
   1521        1.1   tsutsui 			data_tx->ni = ni;
   1522        1.1   tsutsui 			data_tx->m = m;
   1523        1.1   tsutsui 			sc->tx_queued++;
   1524        1.1   tsutsui 		}
   1525        1.1   tsutsui 	}
   1526        1.1   tsutsui 
   1527        1.1   tsutsui 	if (sc->tx_queued > 0) {
   1528        1.1   tsutsui 		DPRINTF(2, "%s: tx_queued=%d\n",
   1529        1.1   tsutsui 		    device_xname(sc->sc_dev), sc->tx_queued);
   1530        1.1   tsutsui 		/* process the TX queue in process context */
   1531        1.1   tsutsui 		ifp->if_timer = 5;
   1532        1.1   tsutsui 		ifp->if_flags |= IFF_OACTIVE;
   1533        1.1   tsutsui 		usb_rem_task(sc->sc_udev, &sc->sc_task_tx);
   1534        1.1   tsutsui 		usb_add_task(sc->sc_udev, &sc->sc_task_tx, USB_TASKQ_DRIVER);
   1535        1.1   tsutsui 	}
   1536        1.1   tsutsui }
   1537        1.1   tsutsui 
   1538        1.1   tsutsui static void
   1539        1.1   tsutsui upgt_watchdog(struct ifnet *ifp)
   1540        1.1   tsutsui {
   1541        1.1   tsutsui 	struct upgt_softc *sc = ifp->if_softc;
   1542        1.1   tsutsui 	struct ieee80211com *ic = &sc->sc_ic;
   1543        1.1   tsutsui 
   1544        1.1   tsutsui 	if (ic->ic_state == IEEE80211_S_INIT)
   1545        1.1   tsutsui 		return;
   1546        1.1   tsutsui 
   1547        1.1   tsutsui 	aprint_error_dev(sc->sc_dev, "watchdog timeout\n");
   1548        1.1   tsutsui 
   1549        1.1   tsutsui 	/* TODO: what shall we do on TX timeout? */
   1550        1.1   tsutsui 
   1551        1.1   tsutsui 	ieee80211_watchdog(ic);
   1552        1.1   tsutsui }
   1553        1.1   tsutsui 
   1554        1.1   tsutsui static void
   1555        1.1   tsutsui upgt_tx_task(void *arg)
   1556        1.1   tsutsui {
   1557        1.1   tsutsui 	struct upgt_softc *sc = arg;
   1558        1.1   tsutsui 	struct ieee80211com *ic = &sc->sc_ic;
   1559        1.1   tsutsui 	struct ieee80211_frame *wh;
   1560        1.1   tsutsui 	struct ieee80211_key *k;
   1561        1.1   tsutsui 	struct ifnet *ifp = &sc->sc_if;
   1562        1.1   tsutsui 	struct upgt_lmac_mem *mem;
   1563        1.1   tsutsui 	struct upgt_lmac_tx_desc *txdesc;
   1564        1.1   tsutsui 	struct mbuf *m;
   1565        1.1   tsutsui 	uint32_t addr;
   1566        1.1   tsutsui 	int i, len, pad, s;
   1567        1.1   tsutsui 	usbd_status error;
   1568        1.1   tsutsui 
   1569        1.1   tsutsui 	mutex_enter(&sc->sc_mtx);
   1570        1.1   tsutsui 	upgt_set_led(sc, UPGT_LED_BLINK);
   1571        1.1   tsutsui 	mutex_exit(&sc->sc_mtx);
   1572        1.1   tsutsui 
   1573        1.1   tsutsui 	s = splnet();
   1574        1.1   tsutsui 
   1575        1.1   tsutsui 	for (i = 0; i < UPGT_TX_COUNT; i++) {
   1576        1.1   tsutsui 		struct upgt_data *data_tx = &sc->tx_data[i];
   1577        1.1   tsutsui 
   1578        1.1   tsutsui 		if (data_tx->m == NULL)
   1579        1.1   tsutsui 			continue;
   1580        1.1   tsutsui 
   1581        1.1   tsutsui 		m = data_tx->m;
   1582        1.1   tsutsui 		addr = data_tx->addr + UPGT_MEMSIZE_FRAME_HEAD;
   1583        1.1   tsutsui 
   1584        1.1   tsutsui 		/*
   1585        1.1   tsutsui 		 * Software crypto.
   1586        1.1   tsutsui 		 */
   1587        1.1   tsutsui 		wh = mtod(m, struct ieee80211_frame *);
   1588        1.1   tsutsui 
   1589        1.1   tsutsui 		if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
   1590        1.1   tsutsui 			k = ieee80211_crypto_encap(ic, data_tx->ni, m);
   1591        1.1   tsutsui 			if (k == NULL) {
   1592        1.1   tsutsui 				m_freem(m);
   1593        1.1   tsutsui 				data_tx->m = NULL;
   1594        1.1   tsutsui 				ieee80211_free_node(data_tx->ni);
   1595        1.1   tsutsui 				data_tx->ni = NULL;
   1596        1.1   tsutsui 				ifp->if_oerrors++;
   1597        1.1   tsutsui 				break;
   1598        1.1   tsutsui 			}
   1599        1.1   tsutsui 
   1600        1.1   tsutsui 			/* in case packet header moved, reset pointer */
   1601        1.1   tsutsui 			wh = mtod(m, struct ieee80211_frame *);
   1602        1.1   tsutsui 		}
   1603        1.1   tsutsui 
   1604        1.1   tsutsui 		/*
   1605        1.1   tsutsui 		 * Transmit the URB containing the TX data.
   1606        1.1   tsutsui 		 */
   1607        1.1   tsutsui 		memset(data_tx->buf, 0, sizeof(*mem) + sizeof(*txdesc));
   1608        1.1   tsutsui 
   1609        1.1   tsutsui 		mem = (struct upgt_lmac_mem *)data_tx->buf;
   1610        1.1   tsutsui 		mem->addr = htole32(addr);
   1611        1.1   tsutsui 
   1612        1.1   tsutsui 		txdesc = (struct upgt_lmac_tx_desc *)(mem + 1);
   1613        1.1   tsutsui 
   1614        1.1   tsutsui 		/* XXX differ between data and mgmt frames? */
   1615        1.1   tsutsui 		txdesc->header1.flags = UPGT_H1_FLAGS_TX_DATA;
   1616        1.1   tsutsui 		txdesc->header1.type = UPGT_H1_TYPE_TX_DATA;
   1617        1.1   tsutsui 		txdesc->header1.len = htole16(m->m_pkthdr.len);
   1618        1.1   tsutsui 
   1619        1.1   tsutsui 		txdesc->header2.reqid = htole32(data_tx->addr);
   1620        1.1   tsutsui 		txdesc->header2.type = htole16(UPGT_H2_TYPE_TX_ACK_YES);
   1621        1.1   tsutsui 		txdesc->header2.flags = htole16(UPGT_H2_FLAGS_TX_ACK_YES);
   1622        1.1   tsutsui 
   1623        1.1   tsutsui 		if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
   1624        1.1   tsutsui 		    IEEE80211_FC0_TYPE_MGT) {
   1625        1.1   tsutsui 			/* always send mgmt frames at lowest rate (DS1) */
   1626        1.1   tsutsui 			memset(txdesc->rates, 0x10, sizeof(txdesc->rates));
   1627        1.1   tsutsui 		} else {
   1628        1.1   tsutsui 			memcpy(txdesc->rates, sc->sc_cur_rateset,
   1629        1.1   tsutsui 			    sizeof(txdesc->rates));
   1630        1.1   tsutsui 		}
   1631        1.1   tsutsui 		txdesc->type = htole32(UPGT_TX_DESC_TYPE_DATA);
   1632        1.1   tsutsui 		txdesc->pad3[0] = UPGT_TX_DESC_PAD3_SIZE;
   1633        1.1   tsutsui 
   1634        1.1   tsutsui 		if (sc->sc_drvbpf != NULL) {
   1635        1.1   tsutsui 			struct upgt_tx_radiotap_header *tap = &sc->sc_txtap;
   1636        1.1   tsutsui 
   1637        1.1   tsutsui 			tap->wt_flags = 0;
   1638        1.1   tsutsui 			tap->wt_rate = 0;	/* TODO: where to get from? */
   1639        1.1   tsutsui 			tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
   1640        1.1   tsutsui 			tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
   1641        1.1   tsutsui 
   1642        1.1   tsutsui 			bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m);
   1643        1.1   tsutsui 		}
   1644        1.1   tsutsui 
   1645        1.1   tsutsui 		/* copy frame below our TX descriptor header */
   1646        1.1   tsutsui 		m_copydata(m, 0, m->m_pkthdr.len,
   1647        1.1   tsutsui 		    data_tx->buf + sizeof(*mem) + sizeof(*txdesc));
   1648        1.1   tsutsui 
   1649        1.1   tsutsui 		/* calculate frame size */
   1650        1.1   tsutsui 		len = sizeof(*mem) + sizeof(*txdesc) + m->m_pkthdr.len;
   1651        1.1   tsutsui 
   1652        1.1   tsutsui 		if (len & 3) {
   1653        1.1   tsutsui 			/* we need to align the frame to a 4 byte boundary */
   1654        1.1   tsutsui 			pad = 4 - (len & 3);
   1655        1.1   tsutsui 			memset(data_tx->buf + len, 0, pad);
   1656        1.1   tsutsui 			len += pad;
   1657        1.1   tsutsui 		}
   1658        1.1   tsutsui 
   1659        1.1   tsutsui 		/* calculate frame checksum */
   1660        1.1   tsutsui 		mem->chksum = upgt_chksum_le((uint32_t *)txdesc,
   1661        1.1   tsutsui 		    len - sizeof(*mem));
   1662        1.1   tsutsui 
   1663        1.1   tsutsui 		/* we do not need the mbuf anymore */
   1664        1.1   tsutsui 		m_freem(m);
   1665        1.1   tsutsui 		data_tx->m = NULL;
   1666        1.1   tsutsui 
   1667        1.1   tsutsui 		ieee80211_free_node(data_tx->ni);
   1668        1.1   tsutsui 		data_tx->ni = NULL;
   1669        1.1   tsutsui 
   1670        1.1   tsutsui 		DPRINTF(2, "%s: TX start data sending\n",
   1671        1.1   tsutsui 		    device_xname(sc->sc_dev));
   1672        1.1   tsutsui 
   1673   1.12.4.7     skrll 		usbd_setup_xfer(data_tx->xfer, data_tx, data_tx->buf, len,
   1674   1.12.4.7     skrll 		    USBD_FORCE_SHORT_XFER, UPGT_USB_TIMEOUT, NULL);
   1675        1.1   tsutsui 		error = usbd_transfer(data_tx->xfer);
   1676        1.1   tsutsui 		if (error != USBD_NORMAL_COMPLETION &&
   1677        1.1   tsutsui 		    error != USBD_IN_PROGRESS) {
   1678        1.1   tsutsui 			aprint_error_dev(sc->sc_dev,
   1679        1.1   tsutsui 			    "could not transmit TX data URB\n");
   1680        1.1   tsutsui 			ifp->if_oerrors++;
   1681        1.1   tsutsui 			break;
   1682        1.1   tsutsui 		}
   1683        1.1   tsutsui 
   1684        1.1   tsutsui 		DPRINTF(2, "%s: TX sent (%d bytes)\n",
   1685        1.1   tsutsui 		    device_xname(sc->sc_dev), len);
   1686        1.1   tsutsui 	}
   1687        1.1   tsutsui 
   1688        1.1   tsutsui 	splx(s);
   1689        1.1   tsutsui 
   1690        1.1   tsutsui 	/*
   1691        1.1   tsutsui 	 * If we don't regulary read the device statistics, the RX queue
   1692        1.1   tsutsui 	 * will stall.  It's strange, but it works, so we keep reading
   1693        1.1   tsutsui 	 * the statistics here.  *shrug*
   1694        1.1   tsutsui 	 */
   1695        1.1   tsutsui 	mutex_enter(&sc->sc_mtx);
   1696        1.1   tsutsui 	upgt_get_stats(sc);
   1697        1.1   tsutsui 	mutex_exit(&sc->sc_mtx);
   1698        1.1   tsutsui }
   1699        1.1   tsutsui 
   1700        1.1   tsutsui static void
   1701        1.1   tsutsui upgt_tx_done(struct upgt_softc *sc, uint8_t *data)
   1702        1.1   tsutsui {
   1703        1.1   tsutsui 	struct ifnet *ifp = &sc->sc_if;
   1704        1.1   tsutsui 	struct upgt_lmac_tx_done_desc *desc;
   1705        1.1   tsutsui 	int i, s;
   1706        1.1   tsutsui 
   1707        1.1   tsutsui 	s = splnet();
   1708        1.1   tsutsui 
   1709        1.1   tsutsui 	desc = (struct upgt_lmac_tx_done_desc *)data;
   1710        1.1   tsutsui 
   1711        1.1   tsutsui 	for (i = 0; i < UPGT_TX_COUNT; i++) {
   1712        1.1   tsutsui 		struct upgt_data *data_tx = &sc->tx_data[i];
   1713        1.1   tsutsui 
   1714        1.1   tsutsui 		if (data_tx->addr == le32toh(desc->header2.reqid)) {
   1715        1.1   tsutsui 			upgt_mem_free(sc, data_tx->addr);
   1716        1.1   tsutsui 			data_tx->addr = 0;
   1717        1.1   tsutsui 
   1718        1.1   tsutsui 			sc->tx_queued--;
   1719        1.1   tsutsui 			ifp->if_opackets++;
   1720        1.1   tsutsui 
   1721        1.1   tsutsui 			DPRINTF(2, "%s: TX done: ", device_xname(sc->sc_dev));
   1722        1.1   tsutsui 			DPRINTF(2, "memaddr=0x%08x, status=0x%04x, rssi=%d, ",
   1723        1.1   tsutsui 			    le32toh(desc->header2.reqid),
   1724        1.1   tsutsui 			    le16toh(desc->status),
   1725        1.1   tsutsui 			    le16toh(desc->rssi));
   1726        1.1   tsutsui 			DPRINTF(2, "seq=%d\n", le16toh(desc->seq));
   1727        1.1   tsutsui 			break;
   1728        1.1   tsutsui 		}
   1729        1.1   tsutsui 	}
   1730        1.1   tsutsui 
   1731        1.1   tsutsui 	if (sc->tx_queued == 0) {
   1732        1.1   tsutsui 		/* TX queued was processed, continue */
   1733        1.1   tsutsui 		ifp->if_timer = 0;
   1734        1.1   tsutsui 		ifp->if_flags &= ~IFF_OACTIVE;
   1735        1.1   tsutsui 		upgt_start(ifp);
   1736        1.1   tsutsui 	}
   1737        1.1   tsutsui 
   1738        1.1   tsutsui 	splx(s);
   1739        1.1   tsutsui }
   1740        1.1   tsutsui 
   1741        1.1   tsutsui static void
   1742   1.12.4.4     skrll upgt_rx_cb(struct usbd_xfer *xfer, void * priv, usbd_status status)
   1743        1.1   tsutsui {
   1744        1.1   tsutsui 	struct upgt_data *data_rx = priv;
   1745        1.1   tsutsui 	struct upgt_softc *sc = data_rx->sc;
   1746        1.1   tsutsui 	int len;
   1747        1.1   tsutsui 	struct upgt_lmac_header *header;
   1748        1.1   tsutsui 	struct upgt_lmac_eeprom *eeprom;
   1749        1.1   tsutsui 	uint8_t h1_type;
   1750        1.1   tsutsui 	uint16_t h2_type;
   1751        1.1   tsutsui 
   1752        1.1   tsutsui 	DPRINTF(3, "%s: %s\n", device_xname(sc->sc_dev), __func__);
   1753        1.1   tsutsui 
   1754        1.1   tsutsui 	if (status != USBD_NORMAL_COMPLETION) {
   1755        1.1   tsutsui 		if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
   1756        1.1   tsutsui 			return;
   1757        1.1   tsutsui 		if (status == USBD_STALLED)
   1758        1.1   tsutsui 			usbd_clear_endpoint_stall_async(sc->sc_rx_pipeh);
   1759        1.1   tsutsui 		goto skip;
   1760        1.1   tsutsui 	}
   1761        1.1   tsutsui 	usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
   1762        1.1   tsutsui 
   1763        1.1   tsutsui 	/*
   1764        1.1   tsutsui 	 * Check what type of frame came in.
   1765        1.1   tsutsui 	 */
   1766        1.1   tsutsui 	header = (struct upgt_lmac_header *)(data_rx->buf + 4);
   1767        1.1   tsutsui 
   1768        1.1   tsutsui 	h1_type = header->header1.type;
   1769        1.1   tsutsui 	h2_type = le16toh(header->header2.type);
   1770        1.1   tsutsui 
   1771        1.1   tsutsui 	if (h1_type == UPGT_H1_TYPE_CTRL &&
   1772        1.1   tsutsui 	    h2_type == UPGT_H2_TYPE_EEPROM) {
   1773        1.1   tsutsui 		eeprom = (struct upgt_lmac_eeprom *)(data_rx->buf + 4);
   1774        1.1   tsutsui 		uint16_t eeprom_offset = le16toh(eeprom->offset);
   1775        1.1   tsutsui 		uint16_t eeprom_len = le16toh(eeprom->len);
   1776        1.1   tsutsui 
   1777        1.1   tsutsui 		DPRINTF(2, "%s: received EEPROM block (offset=%d, len=%d)\n",
   1778        1.1   tsutsui 			device_xname(sc->sc_dev), eeprom_offset, eeprom_len);
   1779        1.1   tsutsui 
   1780  1.12.4.11     skrll 		mutex_enter(&sc->sc_mtx);
   1781        1.1   tsutsui 		memcpy(sc->sc_eeprom + eeprom_offset,
   1782        1.1   tsutsui 		    data_rx->buf + sizeof(struct upgt_lmac_eeprom) + 4,
   1783        1.1   tsutsui 		    eeprom_len);
   1784        1.1   tsutsui 
   1785  1.12.4.11     skrll 		/* EEPROM data has arrived in time, wakeup upgt_eeprom_read */
   1786  1.12.4.11     skrll 		/* Note eeprom data arrived */
   1787  1.12.4.11     skrll 		cv_broadcast(&sc->sc_cv);
   1788  1.12.4.11     skrll 		mutex_exit(&sc->sc_mtx);
   1789        1.1   tsutsui 	} else
   1790        1.1   tsutsui 	if (h1_type == UPGT_H1_TYPE_CTRL &&
   1791        1.1   tsutsui 	    h2_type == UPGT_H2_TYPE_TX_DONE) {
   1792        1.1   tsutsui 		DPRINTF(2, "%s: received 802.11 TX done\n",
   1793        1.1   tsutsui 		    device_xname(sc->sc_dev));
   1794        1.1   tsutsui 
   1795        1.1   tsutsui 		upgt_tx_done(sc, data_rx->buf + 4);
   1796        1.1   tsutsui 	} else
   1797        1.1   tsutsui 	if (h1_type == UPGT_H1_TYPE_RX_DATA ||
   1798        1.1   tsutsui 	    h1_type == UPGT_H1_TYPE_RX_DATA_MGMT) {
   1799        1.1   tsutsui 		DPRINTF(3, "%s: received 802.11 RX data\n",
   1800        1.1   tsutsui 		    device_xname(sc->sc_dev));
   1801        1.1   tsutsui 
   1802        1.1   tsutsui 		upgt_rx(sc, data_rx->buf + 4, le16toh(header->header1.len));
   1803        1.1   tsutsui 	} else
   1804        1.1   tsutsui 	if (h1_type == UPGT_H1_TYPE_CTRL &&
   1805        1.1   tsutsui 	    h2_type == UPGT_H2_TYPE_STATS) {
   1806        1.1   tsutsui 		DPRINTF(2, "%s: received statistic data\n",
   1807        1.1   tsutsui 		    device_xname(sc->sc_dev));
   1808        1.1   tsutsui 
   1809        1.1   tsutsui 		/* TODO: what could we do with the statistic data? */
   1810        1.1   tsutsui 	} else {
   1811        1.1   tsutsui 		/* ignore unknown frame types */
   1812        1.1   tsutsui 		DPRINTF(1, "%s: received unknown frame type 0x%02x\n",
   1813        1.1   tsutsui 		    device_xname(sc->sc_dev), header->header1.type);
   1814        1.1   tsutsui 	}
   1815        1.1   tsutsui 
   1816        1.1   tsutsui skip:	/* setup new transfer */
   1817   1.12.4.7     skrll 	usbd_setup_xfer(xfer, data_rx, data_rx->buf, MCLBYTES,
   1818        1.1   tsutsui 	    USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, upgt_rx_cb);
   1819        1.1   tsutsui 	(void)usbd_transfer(xfer);
   1820        1.1   tsutsui }
   1821        1.1   tsutsui 
   1822        1.1   tsutsui static void
   1823        1.1   tsutsui upgt_rx(struct upgt_softc *sc, uint8_t *data, int pkglen)
   1824        1.1   tsutsui {
   1825        1.1   tsutsui 	struct ieee80211com *ic = &sc->sc_ic;
   1826        1.1   tsutsui 	struct ifnet *ifp = &sc->sc_if;
   1827        1.1   tsutsui 	struct upgt_lmac_rx_desc *rxdesc;
   1828        1.1   tsutsui 	struct ieee80211_frame *wh;
   1829        1.1   tsutsui 	struct ieee80211_node *ni;
   1830        1.1   tsutsui 	struct mbuf *m;
   1831        1.1   tsutsui 	int s;
   1832        1.1   tsutsui 
   1833        1.1   tsutsui 	/* access RX packet descriptor */
   1834        1.1   tsutsui 	rxdesc = (struct upgt_lmac_rx_desc *)data;
   1835        1.1   tsutsui 
   1836        1.1   tsutsui 	/* create mbuf which is suitable for strict alignment archs */
   1837        1.1   tsutsui #define ETHER_ALIGN	0
   1838        1.1   tsutsui 	m = m_devget(rxdesc->data, pkglen, ETHER_ALIGN, ifp, NULL);
   1839        1.1   tsutsui 	if (m == NULL) {
   1840        1.1   tsutsui 		DPRINTF(1, "%s: could not create RX mbuf\n",
   1841        1.1   tsutsui 		   device_xname(sc->sc_dev));
   1842        1.1   tsutsui 		ifp->if_ierrors++;
   1843        1.1   tsutsui 		return;
   1844        1.1   tsutsui 	}
   1845        1.1   tsutsui 
   1846        1.1   tsutsui 	s = splnet();
   1847        1.1   tsutsui 
   1848        1.1   tsutsui 	if (sc->sc_drvbpf != NULL) {
   1849        1.1   tsutsui 		struct upgt_rx_radiotap_header *tap = &sc->sc_rxtap;
   1850        1.1   tsutsui 
   1851        1.1   tsutsui 		tap->wr_flags = IEEE80211_RADIOTAP_F_FCS;
   1852        1.1   tsutsui 		tap->wr_rate = upgt_rx_rate(sc, rxdesc->rate);
   1853        1.1   tsutsui 		tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
   1854        1.1   tsutsui 		tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
   1855        1.1   tsutsui 		tap->wr_antsignal = rxdesc->rssi;
   1856        1.1   tsutsui 
   1857        1.1   tsutsui 		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m);
   1858        1.1   tsutsui 	}
   1859        1.1   tsutsui 
   1860        1.1   tsutsui 	/* trim FCS */
   1861        1.1   tsutsui 	m_adj(m, -IEEE80211_CRC_LEN);
   1862        1.1   tsutsui 
   1863        1.1   tsutsui 	wh = mtod(m, struct ieee80211_frame *);
   1864        1.1   tsutsui 	ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
   1865        1.1   tsutsui 
   1866        1.1   tsutsui 	/* push the frame up to the 802.11 stack */
   1867        1.1   tsutsui 	ieee80211_input(ic, m, ni, rxdesc->rssi, 0);
   1868        1.1   tsutsui 
   1869        1.1   tsutsui 	/* node is no longer needed */
   1870        1.1   tsutsui 	ieee80211_free_node(ni);
   1871        1.1   tsutsui 
   1872        1.1   tsutsui 	splx(s);
   1873        1.1   tsutsui 
   1874        1.1   tsutsui 	DPRINTF(3, "%s: RX done\n", device_xname(sc->sc_dev));
   1875        1.1   tsutsui }
   1876        1.1   tsutsui 
   1877        1.1   tsutsui static void
   1878        1.1   tsutsui upgt_setup_rates(struct upgt_softc *sc)
   1879        1.1   tsutsui {
   1880        1.1   tsutsui 	struct ieee80211com *ic = &sc->sc_ic;
   1881        1.1   tsutsui 
   1882        1.1   tsutsui 	/*
   1883        1.1   tsutsui 	 * 0x01 = OFMD6   0x10 = DS1
   1884        1.1   tsutsui 	 * 0x04 = OFDM9   0x11 = DS2
   1885        1.1   tsutsui 	 * 0x06 = OFDM12  0x12 = DS5
   1886        1.1   tsutsui 	 * 0x07 = OFDM18  0x13 = DS11
   1887        1.1   tsutsui 	 * 0x08 = OFDM24
   1888        1.1   tsutsui 	 * 0x09 = OFDM36
   1889        1.1   tsutsui 	 * 0x0a = OFDM48
   1890        1.1   tsutsui 	 * 0x0b = OFDM54
   1891        1.1   tsutsui 	 */
   1892        1.1   tsutsui 	const uint8_t rateset_auto_11b[] =
   1893        1.1   tsutsui 	    { 0x13, 0x13, 0x12, 0x11, 0x11, 0x10, 0x10, 0x10 };
   1894        1.1   tsutsui 	const uint8_t rateset_auto_11g[] =
   1895        1.1   tsutsui 	    { 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x04, 0x01 };
   1896        1.1   tsutsui 	const uint8_t rateset_fix_11bg[] =
   1897        1.1   tsutsui 	    { 0x10, 0x11, 0x12, 0x13, 0x01, 0x04, 0x06, 0x07,
   1898        1.1   tsutsui 	      0x08, 0x09, 0x0a, 0x0b };
   1899        1.1   tsutsui 
   1900        1.1   tsutsui 	if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) {
   1901        1.1   tsutsui 		/*
   1902        1.1   tsutsui 		 * Automatic rate control is done by the device.
   1903        1.1   tsutsui 		 * We just pass the rateset from which the device
   1904        1.1   tsutsui 		 * will pickup a rate.
   1905        1.1   tsutsui 		 */
   1906        1.1   tsutsui 		if (ic->ic_curmode == IEEE80211_MODE_11B)
   1907        1.1   tsutsui 			memcpy(sc->sc_cur_rateset, rateset_auto_11b,
   1908        1.1   tsutsui 			    sizeof(sc->sc_cur_rateset));
   1909        1.1   tsutsui 		if (ic->ic_curmode == IEEE80211_MODE_11G ||
   1910        1.1   tsutsui 		    ic->ic_curmode == IEEE80211_MODE_AUTO)
   1911        1.1   tsutsui 			memcpy(sc->sc_cur_rateset, rateset_auto_11g,
   1912        1.1   tsutsui 			    sizeof(sc->sc_cur_rateset));
   1913        1.1   tsutsui 	} else {
   1914        1.1   tsutsui 		/* set a fixed rate */
   1915        1.1   tsutsui 		memset(sc->sc_cur_rateset, rateset_fix_11bg[ic->ic_fixed_rate],
   1916        1.1   tsutsui 		    sizeof(sc->sc_cur_rateset));
   1917        1.1   tsutsui 	}
   1918        1.1   tsutsui }
   1919        1.1   tsutsui 
   1920        1.1   tsutsui static uint8_t
   1921        1.1   tsutsui upgt_rx_rate(struct upgt_softc *sc, const int rate)
   1922        1.1   tsutsui {
   1923        1.1   tsutsui 	struct ieee80211com *ic = &sc->sc_ic;
   1924        1.1   tsutsui 
   1925        1.1   tsutsui 	if (ic->ic_curmode == IEEE80211_MODE_11B) {
   1926        1.1   tsutsui 		if (rate < 0 || rate > 3)
   1927        1.1   tsutsui 			/* invalid rate */
   1928        1.1   tsutsui 			return 0;
   1929        1.1   tsutsui 
   1930        1.1   tsutsui 		switch (rate) {
   1931        1.1   tsutsui 		case 0:
   1932        1.1   tsutsui 			return 2;
   1933        1.1   tsutsui 		case 1:
   1934        1.1   tsutsui 			return 4;
   1935        1.1   tsutsui 		case 2:
   1936        1.1   tsutsui 			return 11;
   1937        1.1   tsutsui 		case 3:
   1938        1.1   tsutsui 			return 22;
   1939        1.1   tsutsui 		default:
   1940        1.1   tsutsui 			return 0;
   1941        1.1   tsutsui 		}
   1942        1.1   tsutsui 	}
   1943        1.1   tsutsui 
   1944        1.1   tsutsui 	if (ic->ic_curmode == IEEE80211_MODE_11G) {
   1945        1.1   tsutsui 		if (rate < 0 || rate > 11)
   1946        1.1   tsutsui 			/* invalid rate */
   1947        1.1   tsutsui 			return 0;
   1948        1.1   tsutsui 
   1949        1.1   tsutsui 		switch (rate) {
   1950        1.1   tsutsui 		case 0:
   1951        1.1   tsutsui 			return 2;
   1952        1.1   tsutsui 		case 1:
   1953        1.1   tsutsui 			return 4;
   1954        1.1   tsutsui 		case 2:
   1955        1.1   tsutsui 			return 11;
   1956        1.1   tsutsui 		case 3:
   1957        1.1   tsutsui 			return 22;
   1958        1.1   tsutsui 		case 4:
   1959        1.1   tsutsui 			return 12;
   1960        1.1   tsutsui 		case 5:
   1961        1.1   tsutsui 			return 18;
   1962        1.1   tsutsui 		case 6:
   1963        1.1   tsutsui 			return 24;
   1964        1.1   tsutsui 		case 7:
   1965        1.1   tsutsui 			return 36;
   1966        1.1   tsutsui 		case 8:
   1967        1.1   tsutsui 			return 48;
   1968        1.1   tsutsui 		case 9:
   1969        1.1   tsutsui 			return 72;
   1970        1.1   tsutsui 		case 10:
   1971        1.1   tsutsui 			return 96;
   1972        1.1   tsutsui 		case 11:
   1973        1.1   tsutsui 			return 108;
   1974        1.1   tsutsui 		default:
   1975        1.1   tsutsui 			return 0;
   1976        1.1   tsutsui 		}
   1977        1.1   tsutsui 	}
   1978        1.1   tsutsui 
   1979        1.1   tsutsui 	return 0;
   1980        1.1   tsutsui }
   1981        1.1   tsutsui 
   1982        1.1   tsutsui static int
   1983        1.1   tsutsui upgt_set_macfilter(struct upgt_softc *sc, uint8_t state)
   1984        1.1   tsutsui {
   1985        1.1   tsutsui 	struct ieee80211com *ic = &sc->sc_ic;
   1986        1.1   tsutsui 	struct ieee80211_node *ni = ic->ic_bss;
   1987        1.1   tsutsui 	struct upgt_data *data_cmd = &sc->cmd_data;
   1988        1.1   tsutsui 	struct upgt_lmac_mem *mem;
   1989        1.1   tsutsui 	struct upgt_lmac_filter *filter;
   1990        1.1   tsutsui 	int len;
   1991        1.1   tsutsui 	const uint8_t broadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
   1992        1.1   tsutsui 
   1993        1.1   tsutsui 	/*
   1994        1.1   tsutsui 	 * Transmit the URB containing the CMD data.
   1995        1.1   tsutsui 	 */
   1996        1.1   tsutsui 	len = sizeof(*mem) + sizeof(*filter);
   1997        1.1   tsutsui 
   1998        1.1   tsutsui 	memset(data_cmd->buf, 0, len);
   1999        1.1   tsutsui 
   2000        1.1   tsutsui 	mem = (struct upgt_lmac_mem *)data_cmd->buf;
   2001        1.1   tsutsui 	mem->addr = htole32(sc->sc_memaddr_frame_start +
   2002        1.1   tsutsui 	    UPGT_MEMSIZE_FRAME_HEAD);
   2003        1.1   tsutsui 
   2004        1.1   tsutsui 	filter = (struct upgt_lmac_filter *)(mem + 1);
   2005        1.1   tsutsui 
   2006        1.1   tsutsui 	filter->header1.flags = UPGT_H1_FLAGS_TX_NO_CALLBACK;
   2007        1.1   tsutsui 	filter->header1.type = UPGT_H1_TYPE_CTRL;
   2008        1.1   tsutsui 	filter->header1.len = htole16(
   2009        1.1   tsutsui 	    sizeof(struct upgt_lmac_filter) -
   2010        1.1   tsutsui 	    sizeof(struct upgt_lmac_header));
   2011        1.1   tsutsui 
   2012        1.1   tsutsui 	filter->header2.reqid = htole32(sc->sc_memaddr_frame_start);
   2013        1.1   tsutsui 	filter->header2.type = htole16(UPGT_H2_TYPE_MACFILTER);
   2014        1.1   tsutsui 	filter->header2.flags = 0;
   2015        1.1   tsutsui 
   2016        1.1   tsutsui 	switch (state) {
   2017        1.1   tsutsui 	case IEEE80211_S_INIT:
   2018        1.1   tsutsui 		DPRINTF(1, "%s: set MAC filter to INIT\n",
   2019        1.1   tsutsui 		    device_xname(sc->sc_dev));
   2020        1.1   tsutsui 
   2021        1.1   tsutsui 		filter->type = htole16(UPGT_FILTER_TYPE_RESET);
   2022        1.1   tsutsui 		break;
   2023        1.1   tsutsui 	case IEEE80211_S_SCAN:
   2024        1.1   tsutsui 		DPRINTF(1, "%s: set MAC filter to SCAN (bssid %s)\n",
   2025        1.1   tsutsui 		    device_xname(sc->sc_dev), ether_sprintf(broadcast));
   2026        1.1   tsutsui 
   2027        1.1   tsutsui 		filter->type = htole16(UPGT_FILTER_TYPE_NONE);
   2028        1.1   tsutsui 		IEEE80211_ADDR_COPY(filter->dst, ic->ic_myaddr);
   2029        1.1   tsutsui 		IEEE80211_ADDR_COPY(filter->src, broadcast);
   2030        1.1   tsutsui 		filter->unknown1 = htole16(UPGT_FILTER_UNKNOWN1);
   2031        1.1   tsutsui 		filter->rxaddr = htole32(sc->sc_memaddr_rx_start);
   2032        1.1   tsutsui 		filter->unknown2 = htole16(UPGT_FILTER_UNKNOWN2);
   2033        1.1   tsutsui 		filter->rxhw = htole32(sc->sc_eeprom_hwrx);
   2034        1.1   tsutsui 		filter->unknown3 = htole16(UPGT_FILTER_UNKNOWN3);
   2035        1.1   tsutsui 		break;
   2036        1.1   tsutsui 	case IEEE80211_S_RUN:
   2037        1.1   tsutsui 		DPRINTF(1, "%s: set MAC filter to RUN (bssid %s)\n",
   2038        1.1   tsutsui 		    device_xname(sc->sc_dev), ether_sprintf(ni->ni_bssid));
   2039        1.1   tsutsui 
   2040        1.1   tsutsui 		filter->type = htole16(UPGT_FILTER_TYPE_STA);
   2041        1.1   tsutsui 		IEEE80211_ADDR_COPY(filter->dst, ic->ic_myaddr);
   2042        1.1   tsutsui 		IEEE80211_ADDR_COPY(filter->src, ni->ni_bssid);
   2043        1.1   tsutsui 		filter->unknown1 = htole16(UPGT_FILTER_UNKNOWN1);
   2044        1.1   tsutsui 		filter->rxaddr = htole32(sc->sc_memaddr_rx_start);
   2045        1.1   tsutsui 		filter->unknown2 = htole16(UPGT_FILTER_UNKNOWN2);
   2046        1.1   tsutsui 		filter->rxhw = htole32(sc->sc_eeprom_hwrx);
   2047        1.1   tsutsui 		filter->unknown3 = htole16(UPGT_FILTER_UNKNOWN3);
   2048        1.1   tsutsui 		break;
   2049        1.1   tsutsui 	default:
   2050        1.1   tsutsui 		aprint_error_dev(sc->sc_dev,
   2051        1.1   tsutsui 		    "MAC filter does not know that state\n");
   2052        1.1   tsutsui 		break;
   2053        1.1   tsutsui 	}
   2054        1.1   tsutsui 
   2055        1.1   tsutsui 	mem->chksum = upgt_chksum_le((uint32_t *)filter, sizeof(*filter));
   2056        1.1   tsutsui 
   2057        1.1   tsutsui 	if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) {
   2058        1.1   tsutsui 		aprint_error_dev(sc->sc_dev,
   2059        1.1   tsutsui 		    "could not transmit macfilter CMD data URB\n");
   2060        1.1   tsutsui 		return EIO;
   2061        1.1   tsutsui 	}
   2062        1.1   tsutsui 
   2063        1.1   tsutsui 	return 0;
   2064        1.1   tsutsui }
   2065        1.1   tsutsui 
   2066        1.1   tsutsui static int
   2067        1.1   tsutsui upgt_set_channel(struct upgt_softc *sc, unsigned channel)
   2068        1.1   tsutsui {
   2069        1.1   tsutsui 	struct upgt_data *data_cmd = &sc->cmd_data;
   2070        1.1   tsutsui 	struct upgt_lmac_mem *mem;
   2071        1.1   tsutsui 	struct upgt_lmac_channel *chan;
   2072        1.1   tsutsui 	int len;
   2073        1.1   tsutsui 
   2074        1.1   tsutsui 	DPRINTF(1, "%s: %s: %d\n", device_xname(sc->sc_dev), __func__,
   2075        1.1   tsutsui 	    channel);
   2076        1.1   tsutsui 
   2077        1.1   tsutsui 	/*
   2078        1.1   tsutsui 	 * Transmit the URB containing the CMD data.
   2079        1.1   tsutsui 	 */
   2080        1.1   tsutsui 	len = sizeof(*mem) + sizeof(*chan);
   2081        1.1   tsutsui 
   2082        1.1   tsutsui 	memset(data_cmd->buf, 0, len);
   2083        1.1   tsutsui 
   2084        1.1   tsutsui 	mem = (struct upgt_lmac_mem *)data_cmd->buf;
   2085        1.1   tsutsui 	mem->addr = htole32(sc->sc_memaddr_frame_start +
   2086        1.1   tsutsui 	    UPGT_MEMSIZE_FRAME_HEAD);
   2087        1.1   tsutsui 
   2088        1.1   tsutsui 	chan = (struct upgt_lmac_channel *)(mem + 1);
   2089        1.1   tsutsui 
   2090        1.1   tsutsui 	chan->header1.flags = UPGT_H1_FLAGS_TX_NO_CALLBACK;
   2091        1.1   tsutsui 	chan->header1.type = UPGT_H1_TYPE_CTRL;
   2092        1.1   tsutsui 	chan->header1.len = htole16(
   2093        1.1   tsutsui 	    sizeof(struct upgt_lmac_channel) -
   2094        1.1   tsutsui 	    sizeof(struct upgt_lmac_header));
   2095        1.1   tsutsui 
   2096        1.1   tsutsui 	chan->header2.reqid = htole32(sc->sc_memaddr_frame_start);
   2097        1.1   tsutsui 	chan->header2.type = htole16(UPGT_H2_TYPE_CHANNEL);
   2098        1.1   tsutsui 	chan->header2.flags = 0;
   2099        1.1   tsutsui 
   2100        1.1   tsutsui 	chan->unknown1 = htole16(UPGT_CHANNEL_UNKNOWN1);
   2101        1.1   tsutsui 	chan->unknown2 = htole16(UPGT_CHANNEL_UNKNOWN2);
   2102        1.1   tsutsui 	chan->freq6 = sc->sc_eeprom_freq6[channel];
   2103        1.1   tsutsui 	chan->settings = sc->sc_eeprom_freq6_settings;
   2104        1.1   tsutsui 	chan->unknown3 = UPGT_CHANNEL_UNKNOWN3;
   2105        1.1   tsutsui 
   2106        1.1   tsutsui 	memcpy(chan->freq3_1, &sc->sc_eeprom_freq3[channel].data,
   2107        1.1   tsutsui 	    sizeof(chan->freq3_1));
   2108        1.1   tsutsui 
   2109        1.1   tsutsui 	memcpy(chan->freq4, &sc->sc_eeprom_freq4[channel],
   2110        1.1   tsutsui 	    sizeof(sc->sc_eeprom_freq4[channel]));
   2111        1.1   tsutsui 
   2112        1.1   tsutsui 	memcpy(chan->freq3_2, &sc->sc_eeprom_freq3[channel].data,
   2113        1.1   tsutsui 	    sizeof(chan->freq3_2));
   2114        1.1   tsutsui 
   2115        1.1   tsutsui 	mem->chksum = upgt_chksum_le((uint32_t *)chan, sizeof(*chan));
   2116        1.1   tsutsui 
   2117        1.1   tsutsui 	if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) {
   2118        1.1   tsutsui 		aprint_error_dev(sc->sc_dev,
   2119        1.1   tsutsui 		    "could not transmit channel CMD data URB\n");
   2120        1.1   tsutsui 		return EIO;
   2121        1.1   tsutsui 	}
   2122        1.1   tsutsui 
   2123        1.1   tsutsui 	return 0;
   2124        1.1   tsutsui }
   2125        1.1   tsutsui 
   2126        1.1   tsutsui static void
   2127        1.1   tsutsui upgt_set_led(struct upgt_softc *sc, int action)
   2128        1.1   tsutsui {
   2129        1.1   tsutsui 	struct ieee80211com *ic = &sc->sc_ic;
   2130        1.1   tsutsui 	struct upgt_data *data_cmd = &sc->cmd_data;
   2131        1.1   tsutsui 	struct upgt_lmac_mem *mem;
   2132        1.1   tsutsui 	struct upgt_lmac_led *led;
   2133        1.1   tsutsui 	struct timeval t;
   2134        1.1   tsutsui 	int len;
   2135        1.1   tsutsui 
   2136        1.1   tsutsui 	/*
   2137        1.1   tsutsui 	 * Transmit the URB containing the CMD data.
   2138        1.1   tsutsui 	 */
   2139        1.1   tsutsui 	len = sizeof(*mem) + sizeof(*led);
   2140        1.1   tsutsui 
   2141        1.1   tsutsui 	memset(data_cmd->buf, 0, len);
   2142        1.1   tsutsui 
   2143        1.1   tsutsui 	mem = (struct upgt_lmac_mem *)data_cmd->buf;
   2144        1.1   tsutsui 	mem->addr = htole32(sc->sc_memaddr_frame_start +
   2145        1.1   tsutsui 	    UPGT_MEMSIZE_FRAME_HEAD);
   2146        1.1   tsutsui 
   2147        1.1   tsutsui 	led = (struct upgt_lmac_led *)(mem + 1);
   2148        1.1   tsutsui 
   2149        1.1   tsutsui 	led->header1.flags = UPGT_H1_FLAGS_TX_NO_CALLBACK;
   2150        1.1   tsutsui 	led->header1.type = UPGT_H1_TYPE_CTRL;
   2151        1.1   tsutsui 	led->header1.len = htole16(
   2152        1.1   tsutsui 	    sizeof(struct upgt_lmac_led) -
   2153        1.1   tsutsui 	    sizeof(struct upgt_lmac_header));
   2154        1.1   tsutsui 
   2155        1.1   tsutsui 	led->header2.reqid = htole32(sc->sc_memaddr_frame_start);
   2156        1.1   tsutsui 	led->header2.type = htole16(UPGT_H2_TYPE_LED);
   2157        1.1   tsutsui 	led->header2.flags = 0;
   2158        1.1   tsutsui 
   2159        1.1   tsutsui 	switch (action) {
   2160        1.1   tsutsui 	case UPGT_LED_OFF:
   2161        1.1   tsutsui 		led->mode = htole16(UPGT_LED_MODE_SET);
   2162        1.1   tsutsui 		led->action_fix = 0;
   2163        1.1   tsutsui 		led->action_tmp = htole16(UPGT_LED_ACTION_OFF);
   2164        1.1   tsutsui 		led->action_tmp_dur = 0;
   2165        1.1   tsutsui 		break;
   2166        1.1   tsutsui 	case UPGT_LED_ON:
   2167        1.1   tsutsui 		led->mode = htole16(UPGT_LED_MODE_SET);
   2168        1.1   tsutsui 		led->action_fix = 0;
   2169        1.1   tsutsui 		led->action_tmp = htole16(UPGT_LED_ACTION_ON);
   2170        1.1   tsutsui 		led->action_tmp_dur = 0;
   2171        1.1   tsutsui 		break;
   2172        1.1   tsutsui 	case UPGT_LED_BLINK:
   2173        1.1   tsutsui 		if (ic->ic_state != IEEE80211_S_RUN)
   2174        1.1   tsutsui 			return;
   2175        1.1   tsutsui 		if (sc->sc_led_blink)
   2176        1.1   tsutsui 			/* previous blink was not finished */
   2177        1.1   tsutsui 			return;
   2178        1.1   tsutsui 		led->mode = htole16(UPGT_LED_MODE_SET);
   2179        1.1   tsutsui 		led->action_fix = htole16(UPGT_LED_ACTION_OFF);
   2180        1.1   tsutsui 		led->action_tmp = htole16(UPGT_LED_ACTION_ON);
   2181        1.1   tsutsui 		led->action_tmp_dur = htole16(UPGT_LED_ACTION_TMP_DUR);
   2182        1.1   tsutsui 		/* lock blink */
   2183        1.1   tsutsui 		sc->sc_led_blink = 1;
   2184        1.1   tsutsui 		t.tv_sec = 0;
   2185        1.1   tsutsui 		t.tv_usec = UPGT_LED_ACTION_TMP_DUR * 1000L;
   2186        1.1   tsutsui 		callout_schedule(&sc->led_to, tvtohz(&t));
   2187        1.1   tsutsui 		break;
   2188        1.1   tsutsui 	default:
   2189        1.1   tsutsui 		return;
   2190        1.1   tsutsui 	}
   2191        1.1   tsutsui 
   2192        1.1   tsutsui 	mem->chksum = upgt_chksum_le((uint32_t *)led, sizeof(*led));
   2193        1.1   tsutsui 
   2194        1.1   tsutsui 	if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) {
   2195        1.1   tsutsui 		aprint_error_dev(sc->sc_dev,
   2196        1.1   tsutsui 		    "could not transmit led CMD URB\n");
   2197        1.1   tsutsui 	}
   2198        1.1   tsutsui }
   2199        1.1   tsutsui 
   2200        1.1   tsutsui static void
   2201        1.1   tsutsui upgt_set_led_blink(void *arg)
   2202        1.1   tsutsui {
   2203        1.1   tsutsui 	struct upgt_softc *sc = arg;
   2204        1.1   tsutsui 
   2205        1.1   tsutsui 	/* blink finished, we are ready for a next one */
   2206        1.1   tsutsui 	sc->sc_led_blink = 0;
   2207        1.1   tsutsui 	callout_stop(&sc->led_to);
   2208        1.1   tsutsui }
   2209        1.1   tsutsui 
   2210        1.1   tsutsui static int
   2211        1.1   tsutsui upgt_get_stats(struct upgt_softc *sc)
   2212        1.1   tsutsui {
   2213        1.1   tsutsui 	struct upgt_data *data_cmd = &sc->cmd_data;
   2214        1.1   tsutsui 	struct upgt_lmac_mem *mem;
   2215        1.1   tsutsui 	struct upgt_lmac_stats *stats;
   2216        1.1   tsutsui 	int len;
   2217        1.1   tsutsui 
   2218        1.1   tsutsui 	/*
   2219        1.1   tsutsui 	 * Transmit the URB containing the CMD data.
   2220        1.1   tsutsui 	 */
   2221        1.1   tsutsui 	len = sizeof(*mem) + sizeof(*stats);
   2222        1.1   tsutsui 
   2223        1.1   tsutsui 	memset(data_cmd->buf, 0, len);
   2224        1.1   tsutsui 
   2225        1.1   tsutsui 	mem = (struct upgt_lmac_mem *)data_cmd->buf;
   2226        1.1   tsutsui 	mem->addr = htole32(sc->sc_memaddr_frame_start +
   2227        1.1   tsutsui 	    UPGT_MEMSIZE_FRAME_HEAD);
   2228        1.1   tsutsui 
   2229        1.1   tsutsui 	stats = (struct upgt_lmac_stats *)(mem + 1);
   2230        1.1   tsutsui 
   2231        1.1   tsutsui 	stats->header1.flags = 0;
   2232        1.1   tsutsui 	stats->header1.type = UPGT_H1_TYPE_CTRL;
   2233        1.1   tsutsui 	stats->header1.len = htole16(
   2234        1.1   tsutsui 	    sizeof(struct upgt_lmac_stats) -
   2235        1.1   tsutsui 	    sizeof(struct upgt_lmac_header));
   2236        1.1   tsutsui 
   2237        1.1   tsutsui 	stats->header2.reqid = htole32(sc->sc_memaddr_frame_start);
   2238        1.1   tsutsui 	stats->header2.type = htole16(UPGT_H2_TYPE_STATS);
   2239        1.1   tsutsui 	stats->header2.flags = 0;
   2240        1.1   tsutsui 
   2241        1.1   tsutsui 	mem->chksum = upgt_chksum_le((uint32_t *)stats, sizeof(*stats));
   2242        1.1   tsutsui 
   2243        1.1   tsutsui 	if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) {
   2244        1.1   tsutsui 		aprint_error_dev(sc->sc_dev,
   2245        1.1   tsutsui 		    "could not transmit statistics CMD data URB\n");
   2246        1.1   tsutsui 		return EIO;
   2247        1.1   tsutsui 	}
   2248        1.1   tsutsui 
   2249        1.1   tsutsui 	return 0;
   2250        1.1   tsutsui 
   2251        1.1   tsutsui }
   2252        1.1   tsutsui 
   2253        1.1   tsutsui static int
   2254        1.1   tsutsui upgt_alloc_tx(struct upgt_softc *sc)
   2255        1.1   tsutsui {
   2256        1.1   tsutsui 	int i;
   2257        1.1   tsutsui 
   2258        1.1   tsutsui 	sc->tx_queued = 0;
   2259        1.1   tsutsui 
   2260        1.1   tsutsui 	for (i = 0; i < UPGT_TX_COUNT; i++) {
   2261        1.1   tsutsui 		struct upgt_data *data_tx = &sc->tx_data[i];
   2262        1.1   tsutsui 
   2263        1.1   tsutsui 		data_tx->sc = sc;
   2264        1.1   tsutsui 
   2265   1.12.4.7     skrll 		int err = usbd_create_xfer(sc->sc_tx_pipeh, MCLBYTES, 0, 0,
   2266   1.12.4.7     skrll 		    &data_tx->xfer);
   2267   1.12.4.7     skrll 		if (err) {
   2268        1.1   tsutsui 			aprint_error_dev(sc->sc_dev,
   2269        1.1   tsutsui 			    "could not allocate TX xfer\n");
   2270   1.12.4.7     skrll 			return err;
   2271        1.1   tsutsui 		}
   2272        1.1   tsutsui 
   2273   1.12.4.7     skrll 		data_tx->buf = usbd_get_buffer(data_tx->xfer);
   2274        1.1   tsutsui 	}
   2275        1.1   tsutsui 
   2276        1.1   tsutsui 	return 0;
   2277        1.1   tsutsui }
   2278        1.1   tsutsui 
   2279        1.1   tsutsui static int
   2280        1.1   tsutsui upgt_alloc_rx(struct upgt_softc *sc)
   2281        1.1   tsutsui {
   2282        1.1   tsutsui 	struct upgt_data *data_rx = &sc->rx_data;
   2283        1.1   tsutsui 
   2284        1.1   tsutsui 	data_rx->sc = sc;
   2285        1.1   tsutsui 
   2286   1.12.4.7     skrll 	int err = usbd_create_xfer(sc->sc_rx_pipeh, MCLBYTES,
   2287   1.12.4.7     skrll 	    USBD_SHORT_XFER_OK, 0, &data_rx->xfer);
   2288   1.12.4.7     skrll 	if (err) {
   2289        1.1   tsutsui 		aprint_error_dev(sc->sc_dev, "could not allocate RX xfer\n");
   2290   1.12.4.7     skrll 		return err;
   2291        1.1   tsutsui 	}
   2292        1.1   tsutsui 
   2293   1.12.4.7     skrll 	data_rx->buf = usbd_get_buffer(data_rx->xfer);
   2294        1.1   tsutsui 
   2295        1.1   tsutsui 	return 0;
   2296        1.1   tsutsui }
   2297        1.1   tsutsui 
   2298        1.1   tsutsui static int
   2299        1.1   tsutsui upgt_alloc_cmd(struct upgt_softc *sc)
   2300        1.1   tsutsui {
   2301        1.1   tsutsui 	struct upgt_data *data_cmd = &sc->cmd_data;
   2302        1.1   tsutsui 
   2303        1.1   tsutsui 	data_cmd->sc = sc;
   2304        1.1   tsutsui 
   2305   1.12.4.7     skrll 	int err = usbd_create_xfer(sc->sc_tx_pipeh, MCLBYTES,
   2306   1.12.4.7     skrll 	    USBD_FORCE_SHORT_XFER, 0, &data_cmd->xfer);
   2307   1.12.4.7     skrll 	if (err) {
   2308        1.1   tsutsui 		aprint_error_dev(sc->sc_dev, "could not allocate RX xfer\n");
   2309   1.12.4.7     skrll 		return err;
   2310        1.1   tsutsui 	}
   2311        1.1   tsutsui 
   2312   1.12.4.7     skrll 	data_cmd->buf = usbd_get_buffer(data_cmd->xfer);
   2313        1.1   tsutsui 
   2314  1.12.4.11     skrll 	cv_init(&sc->sc_cv, "upgteeprom");
   2315   1.12.4.8     skrll 	mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_NONE);
   2316        1.1   tsutsui 
   2317        1.1   tsutsui 	return 0;
   2318        1.1   tsutsui }
   2319        1.1   tsutsui 
   2320        1.1   tsutsui static void
   2321        1.1   tsutsui upgt_free_tx(struct upgt_softc *sc)
   2322        1.1   tsutsui {
   2323        1.1   tsutsui 	int i;
   2324        1.1   tsutsui 
   2325        1.1   tsutsui 	for (i = 0; i < UPGT_TX_COUNT; i++) {
   2326        1.1   tsutsui 		struct upgt_data *data_tx = &sc->tx_data[i];
   2327        1.1   tsutsui 
   2328        1.1   tsutsui 		if (data_tx->xfer != NULL) {
   2329   1.12.4.7     skrll 			usbd_destroy_xfer(data_tx->xfer);
   2330        1.1   tsutsui 			data_tx->xfer = NULL;
   2331        1.1   tsutsui 		}
   2332        1.1   tsutsui 
   2333        1.1   tsutsui 		data_tx->ni = NULL;
   2334        1.1   tsutsui 	}
   2335        1.1   tsutsui }
   2336        1.1   tsutsui 
   2337        1.1   tsutsui static void
   2338        1.1   tsutsui upgt_free_rx(struct upgt_softc *sc)
   2339        1.1   tsutsui {
   2340        1.1   tsutsui 	struct upgt_data *data_rx = &sc->rx_data;
   2341        1.1   tsutsui 
   2342        1.1   tsutsui 	if (data_rx->xfer != NULL) {
   2343   1.12.4.7     skrll 		usbd_destroy_xfer(data_rx->xfer);
   2344        1.1   tsutsui 		data_rx->xfer = NULL;
   2345        1.1   tsutsui 	}
   2346        1.1   tsutsui 
   2347        1.1   tsutsui 	data_rx->ni = NULL;
   2348        1.1   tsutsui }
   2349        1.1   tsutsui 
   2350        1.1   tsutsui static void
   2351        1.1   tsutsui upgt_free_cmd(struct upgt_softc *sc)
   2352        1.1   tsutsui {
   2353        1.1   tsutsui 	struct upgt_data *data_cmd = &sc->cmd_data;
   2354        1.1   tsutsui 
   2355        1.1   tsutsui 	if (data_cmd->xfer != NULL) {
   2356   1.12.4.7     skrll 		usbd_destroy_xfer(data_cmd->xfer);
   2357        1.1   tsutsui 		data_cmd->xfer = NULL;
   2358        1.1   tsutsui 	}
   2359        1.1   tsutsui 
   2360        1.1   tsutsui 	mutex_destroy(&sc->sc_mtx);
   2361  1.12.4.11     skrll 	cv_destroy(&sc->sc_cv);
   2362        1.1   tsutsui }
   2363        1.1   tsutsui 
   2364        1.1   tsutsui static int
   2365        1.1   tsutsui upgt_bulk_xmit(struct upgt_softc *sc, struct upgt_data *data,
   2366   1.12.4.6     skrll     struct usbd_pipe *pipeh, uint32_t *size, int flags)
   2367        1.1   tsutsui {
   2368        1.1   tsutsui         usbd_status status;
   2369        1.1   tsutsui 
   2370   1.12.4.7     skrll 	status = usbd_bulk_transfer(data->xfer, pipeh, flags, UPGT_USB_TIMEOUT,
   2371   1.12.4.7     skrll 	    data->buf, size);
   2372        1.1   tsutsui 	if (status != USBD_NORMAL_COMPLETION) {
   2373        1.1   tsutsui 		aprint_error_dev(sc->sc_dev, "%s: error %s\n", __func__,
   2374        1.1   tsutsui 		    usbd_errstr(status));
   2375        1.1   tsutsui 		return EIO;
   2376        1.1   tsutsui 	}
   2377        1.1   tsutsui 
   2378        1.1   tsutsui 	return 0;
   2379        1.1   tsutsui }
   2380        1.1   tsutsui 
   2381        1.1   tsutsui #if 0
   2382        1.1   tsutsui static void
   2383        1.1   tsutsui upgt_hexdump(void *buf, int len)
   2384        1.1   tsutsui {
   2385        1.1   tsutsui 	int i;
   2386        1.1   tsutsui 
   2387        1.1   tsutsui 	for (i = 0; i < len; i++) {
   2388        1.1   tsutsui 		if (i % 16 == 0)
   2389        1.1   tsutsui 			printf("%s%5i:", i ? "\n" : "", i);
   2390        1.1   tsutsui 		if (i % 4 == 0)
   2391        1.1   tsutsui 			printf(" ");
   2392        1.1   tsutsui 		printf("%02x", (int)*((uint8_t *)buf + i));
   2393        1.1   tsutsui 	}
   2394        1.1   tsutsui 	printf("\n");
   2395        1.1   tsutsui }
   2396        1.1   tsutsui #endif
   2397        1.1   tsutsui 
   2398        1.1   tsutsui static uint32_t
   2399        1.1   tsutsui upgt_crc32_le(const void *buf, size_t size)
   2400        1.1   tsutsui {
   2401        1.1   tsutsui 	uint32_t crc;
   2402        1.1   tsutsui 
   2403        1.1   tsutsui 	crc = ether_crc32_le(buf, size);
   2404        1.1   tsutsui 
   2405        1.1   tsutsui 	/* apply final XOR value as common for CRC-32 */
   2406        1.1   tsutsui 	crc = htole32(crc ^ 0xffffffffU);
   2407        1.1   tsutsui 
   2408        1.1   tsutsui 	return crc;
   2409        1.1   tsutsui }
   2410        1.1   tsutsui 
   2411        1.1   tsutsui /*
   2412        1.1   tsutsui  * The firmware awaits a checksum for each frame we send to it.
   2413        1.1   tsutsui  * The algorithm used therefor is uncommon but somehow similar to CRC32.
   2414        1.1   tsutsui  */
   2415        1.1   tsutsui static uint32_t
   2416        1.1   tsutsui upgt_chksum_le(const uint32_t *buf, size_t size)
   2417        1.1   tsutsui {
   2418        1.1   tsutsui 	int i;
   2419        1.1   tsutsui 	uint32_t crc = 0;
   2420        1.1   tsutsui 
   2421        1.1   tsutsui 	for (i = 0; i < size; i += sizeof(uint32_t)) {
   2422        1.1   tsutsui 		crc = htole32(crc ^ *buf++);
   2423        1.1   tsutsui 		crc = htole32((crc >> 5) ^ (crc << 3));
   2424        1.1   tsutsui 	}
   2425        1.1   tsutsui 
   2426        1.1   tsutsui 	return crc;
   2427        1.1   tsutsui }
   2428