1 /*- 2 * Copyright (c) 2003 3 * Bill Paul <wpaul@windriver.com>. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by Bill Paul. 16 * 4. Neither the name of the author nor the names of any co-contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 * 32 * $FreeBSD$ 33 */ 34 35 #define NDIS_DEFAULT_NODENAME "FreeBSD NDIS node" 36 #define NDIS_NODENAME_LEN 32 37 38 /* For setting/getting OIDs from userspace. */ 39 40 struct ndis_oid_data { 41 uint32_t oid; 42 uint32_t len; 43 #ifdef notdef 44 uint8_t data[1]; 45 #endif 46 }; 47 48 struct ndis_pci_type { 49 uint16_t ndis_vid; 50 uint16_t ndis_did; 51 uint32_t ndis_subsys; 52 char *ndis_name; 53 }; 54 55 struct ndis_pccard_type { 56 const char *ndis_vid; 57 const char *ndis_did; 58 char *ndis_name; 59 }; 60 61 struct ndis_usb_type { 62 uint16_t ndis_vid; 63 uint16_t ndis_did; 64 char *ndis_name; 65 }; 66 67 struct ndis_shmem { 68 list_entry ndis_list; 69 bus_dma_tag_t ndis_stag; 70 bus_dmamap_t ndis_smap; 71 void *ndis_saddr; 72 ndis_physaddr ndis_paddr; 73 }; 74 75 struct ndis_cfglist { 76 ndis_cfg ndis_cfg; 77 struct sysctl_oid *ndis_oid; 78 TAILQ_ENTRY(ndis_cfglist) link; 79 }; 80 81 /* 82 * Helper struct to make parsing information 83 * elements easier. 84 */ 85 struct ndis_ie { 86 uint8_t ni_oui[3]; 87 uint8_t ni_val; 88 }; 89 90 TAILQ_HEAD(nch, ndis_cfglist); 91 92 #define NDIS_INITIALIZED(sc) (sc->ndis_block->nmb_devicectx != NULL) 93 94 #define NDIS_TXPKTS 64 95 #define NDIS_INC(x) \ 96 (x)->ndis_txidx = ((x)->ndis_txidx + 1) % (x)->ndis_maxpkts 97 98 99 #define NDIS_EVENTS 4 100 #define NDIS_EVTINC(x) (x) = ((x) + 1) % NDIS_EVENTS 101 102 struct ndis_evt { 103 uint32_t ne_sts; 104 uint32_t ne_len; 105 char *ne_buf; 106 }; 107 108 struct ndis_vap { 109 struct ieee80211vap vap; 110 111 int (*newstate)(struct ieee80211vap *, 112 enum ieee80211_state, int); 113 }; 114 #define NDIS_VAP(vap) ((struct ndis_vap *)(vap)) 115 116 #define NDISUSB_CONFIG_NO 0 117 #define NDISUSB_IFACE_INDEX 0 118 /* XXX at USB2 there's no USBD_NO_TIMEOUT macro anymore */ 119 #define NDISUSB_NO_TIMEOUT 0 120 #define NDISUSB_INTR_TIMEOUT 1000 121 #define NDISUSB_TX_TIMEOUT 10000 122 struct ndisusb_xfer; 123 struct ndisusb_ep { 124 struct usb_xfer *ne_xfer[1]; 125 list_entry ne_active; 126 list_entry ne_pending; 127 kspin_lock ne_lock; 128 uint8_t ne_dirin; 129 }; 130 struct ndisusb_xfer { 131 struct ndisusb_ep *nx_ep; 132 void *nx_priv; 133 uint8_t *nx_urbbuf; 134 uint32_t nx_urbactlen; 135 uint32_t nx_urblen; 136 uint8_t nx_shortxfer; 137 list_entry nx_next; 138 }; 139 struct ndisusb_xferdone { 140 struct ndisusb_xfer *nd_xfer; 141 usb_error_t nd_status; 142 list_entry nd_donelist; 143 }; 144 145 struct ndisusb_task { 146 unsigned nt_type; 147 #define NDISUSB_TASK_TSTART 0 148 #define NDISUSB_TASK_IRPCANCEL 1 149 #define NDISUSB_TASK_VENDOR 2 150 void *nt_ctx; 151 list_entry nt_tasklist; 152 }; 153 154 struct ndis_softc { 155 u_int ndis_80211:1, 156 ndis_link:1, 157 ndis_running:1; 158 union { 159 struct { /* Ethernet */ 160 struct ifnet *ifp; 161 struct ifmedia ifmedia; 162 int ndis_if_flags; 163 }; 164 struct { /* Wireless */ 165 struct ieee80211com ndis_ic; 166 struct callout ndis_scan_callout; 167 int (*ndis_newstate)(struct ieee80211com *, 168 enum ieee80211_state, int); 169 }; 170 }; 171 u_long ndis_hwassist; 172 uint32_t ndis_v4tx; 173 uint32_t ndis_v4rx; 174 bus_space_handle_t ndis_bhandle; 175 bus_space_tag_t ndis_btag; 176 void *ndis_intrhand; 177 struct resource *ndis_irq; 178 struct resource *ndis_res; 179 struct resource *ndis_res_io; 180 int ndis_io_rid; 181 struct resource *ndis_res_mem; 182 int ndis_mem_rid; 183 struct resource *ndis_res_altmem; 184 int ndis_altmem_rid; 185 struct resource *ndis_res_am; /* attribute mem (pccard) */ 186 int ndis_am_rid; 187 struct resource *ndis_res_cm; /* common mem (pccard) */ 188 struct resource_list ndis_rl; 189 int ndis_rescnt; 190 struct mtx ndis_mtx; 191 uint8_t ndis_irql; 192 device_t ndis_dev; 193 int ndis_unit; 194 ndis_miniport_block *ndis_block; 195 ndis_miniport_characteristics *ndis_chars; 196 interface_type ndis_type; 197 struct callout ndis_stat_callout; 198 int ndis_maxpkts; 199 ndis_oid *ndis_oids; 200 int ndis_oidcnt; 201 int ndis_txidx; 202 int ndis_txpending; 203 ndis_packet **ndis_txarray; 204 ndis_handle ndis_txpool; 205 int ndis_sc; 206 ndis_cfg *ndis_regvals; 207 struct nch ndis_cfglist_head; 208 uint32_t ndis_sts; 209 uint32_t ndis_filter; 210 int ndis_skip; 211 int ndis_devidx; 212 interface_type ndis_iftype; 213 driver_object *ndis_dobj; 214 io_workitem *ndis_tickitem; 215 io_workitem *ndis_startitem; 216 io_workitem *ndis_resetitem; 217 io_workitem *ndis_inputitem; 218 kdpc ndis_rxdpc; 219 bus_dma_tag_t ndis_parent_tag; 220 list_entry ndis_shlist; 221 bus_dma_tag_t ndis_mtag; 222 bus_dma_tag_t ndis_ttag; 223 bus_dmamap_t *ndis_mmaps; 224 bus_dmamap_t *ndis_tmaps; 225 int ndis_mmapcnt; 226 struct ndis_evt ndis_evt[NDIS_EVENTS]; 227 int ndis_evtpidx; 228 int ndis_evtcidx; 229 struct mbufq ndis_rxqueue; 230 kspin_lock ndis_rxlock; 231 232 int ndis_tx_timer; 233 int ndis_hang_timer; 234 235 struct usb_device *ndisusb_dev; 236 struct mtx ndisusb_mtx; 237 struct ndisusb_ep ndisusb_dread_ep; 238 struct ndisusb_ep ndisusb_dwrite_ep; 239 #define NDISUSB_GET_ENDPT(addr) \ 240 ((UE_GET_DIR(addr) >> 7) | (UE_GET_ADDR(addr) << 1)) 241 #define NDISUSB_ENDPT_MAX ((UE_ADDR + 1) * 2) 242 struct ndisusb_ep ndisusb_ep[NDISUSB_ENDPT_MAX]; 243 io_workitem *ndisusb_xferdoneitem; 244 list_entry ndisusb_xferdonelist; 245 kspin_lock ndisusb_xferdonelock; 246 io_workitem *ndisusb_taskitem; 247 list_entry ndisusb_tasklist; 248 kspin_lock ndisusb_tasklock; 249 int ndisusb_status; 250 #define NDISUSB_STATUS_DETACH 0x1 251 #define NDISUSB_STATUS_SETUP_EP 0x2 252 }; 253 254 #define NDIS_LOCK(_sc) mtx_lock(&(_sc)->ndis_mtx) 255 #define NDIS_UNLOCK(_sc) mtx_unlock(&(_sc)->ndis_mtx) 256 #define NDIS_LOCK_ASSERT(_sc, t) mtx_assert(&(_sc)->ndis_mtx, t) 257 #define NDISUSB_LOCK(_sc) mtx_lock(&(_sc)->ndisusb_mtx) 258 #define NDISUSB_UNLOCK(_sc) mtx_unlock(&(_sc)->ndisusb_mtx) 259 #define NDISUSB_LOCK_ASSERT(_sc, t) mtx_assert(&(_sc)->ndisusb_mtx, t) 260 261