if_malo.c (283540) | if_malo.c (286410) |
---|---|
1/*- 2 * Copyright (c) 2008 Weongyo Jeong <weongyo@freebsd.org> 3 * Copyright (c) 2007 Marvell Semiconductor, Inc. 4 * Copyright (c) 2007 Sam Leffler, Errno Consulting 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 17 unchanged lines hidden (view full) --- 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 27 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 29 * THE POSSIBILITY OF SUCH DAMAGES. 30 */ 31 32#include <sys/cdefs.h> 33#ifdef __FreeBSD__ | 1/*- 2 * Copyright (c) 2008 Weongyo Jeong <weongyo@freebsd.org> 3 * Copyright (c) 2007 Marvell Semiconductor, Inc. 4 * Copyright (c) 2007 Sam Leffler, Errno Consulting 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions --- 17 unchanged lines hidden (view full) --- 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 27 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 29 * THE POSSIBILITY OF SUCH DAMAGES. 30 */ 31 32#include <sys/cdefs.h> 33#ifdef __FreeBSD__ |
34__FBSDID("$FreeBSD: head/sys/dev/malo/if_malo.c 283540 2015-05-25 19:53:29Z glebius $"); | 34__FBSDID("$FreeBSD: head/sys/dev/malo/if_malo.c 286410 2015-08-07 11:43:14Z glebius $"); |
35#endif 36 37#include "opt_malo.h" 38 39#include <sys/param.h> 40#include <sys/endian.h> 41#include <sys/kernel.h> 42#include <sys/socket.h> --- 54 unchanged lines hidden (view full) --- 97 MALO_DEBUG_ANY = 0xffffffff 98}; 99#define IS_BEACON(wh) \ 100 ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK | \ 101 IEEE80211_FC0_SUBTYPE_MASK)) == \ 102 (IEEE80211_FC0_TYPE_MGT|IEEE80211_FC0_SUBTYPE_BEACON)) 103#define IFF_DUMPPKTS_RECV(sc, wh) \ 104 (((sc->malo_debug & MALO_DEBUG_RECV) && \ | 35#endif 36 37#include "opt_malo.h" 38 39#include <sys/param.h> 40#include <sys/endian.h> 41#include <sys/kernel.h> 42#include <sys/socket.h> --- 54 unchanged lines hidden (view full) --- 97 MALO_DEBUG_ANY = 0xffffffff 98}; 99#define IS_BEACON(wh) \ 100 ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK | \ 101 IEEE80211_FC0_SUBTYPE_MASK)) == \ 102 (IEEE80211_FC0_TYPE_MGT|IEEE80211_FC0_SUBTYPE_BEACON)) 103#define IFF_DUMPPKTS_RECV(sc, wh) \ 104 (((sc->malo_debug & MALO_DEBUG_RECV) && \ |
105 ((sc->malo_debug & MALO_DEBUG_RECV_ALL) || !IS_BEACON(wh))) || \ 106 (sc->malo_ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) == \ 107 (IFF_DEBUG|IFF_LINK2)) | 105 ((sc->malo_debug & MALO_DEBUG_RECV_ALL) || !IS_BEACON(wh)))) |
108#define IFF_DUMPPKTS_XMIT(sc) \ | 106#define IFF_DUMPPKTS_XMIT(sc) \ |
109 ((sc->malo_debug & MALO_DEBUG_XMIT) || \ 110 (sc->malo_ifp->if_flags & (IFF_DEBUG | IFF_LINK2)) == \ 111 (IFF_DEBUG | IFF_LINK2)) | 107 (sc->malo_debug & MALO_DEBUG_XMIT) |
112#define DPRINTF(sc, m, fmt, ...) do { \ 113 if (sc->malo_debug & (m)) \ 114 printf(fmt, __VA_ARGS__); \ 115} while (0) 116#else 117#define DPRINTF(sc, m, fmt, ...) do { \ 118 (void) sc; \ 119} while (0) --- 5 unchanged lines hidden (view full) --- 125 const char [IFNAMSIZ], int, enum ieee80211_opmode, int, 126 const uint8_t [IEEE80211_ADDR_LEN], 127 const uint8_t [IEEE80211_ADDR_LEN]); 128static void malo_vap_delete(struct ieee80211vap *); 129static int malo_dma_setup(struct malo_softc *); 130static int malo_setup_hwdma(struct malo_softc *); 131static void malo_txq_init(struct malo_softc *, struct malo_txq *, int); 132static void malo_tx_cleanupq(struct malo_softc *, struct malo_txq *); | 108#define DPRINTF(sc, m, fmt, ...) do { \ 109 if (sc->malo_debug & (m)) \ 110 printf(fmt, __VA_ARGS__); \ 111} while (0) 112#else 113#define DPRINTF(sc, m, fmt, ...) do { \ 114 (void) sc; \ 115} while (0) --- 5 unchanged lines hidden (view full) --- 121 const char [IFNAMSIZ], int, enum ieee80211_opmode, int, 122 const uint8_t [IEEE80211_ADDR_LEN], 123 const uint8_t [IEEE80211_ADDR_LEN]); 124static void malo_vap_delete(struct ieee80211vap *); 125static int malo_dma_setup(struct malo_softc *); 126static int malo_setup_hwdma(struct malo_softc *); 127static void malo_txq_init(struct malo_softc *, struct malo_txq *, int); 128static void malo_tx_cleanupq(struct malo_softc *, struct malo_txq *); |
133static void malo_start(struct ifnet *); | 129static void malo_parent(struct ieee80211com *); 130static int malo_transmit(struct ieee80211com *, struct mbuf *); 131static void malo_start(struct malo_softc *); |
134static void malo_watchdog(void *); | 132static void malo_watchdog(void *); |
135static int malo_ioctl(struct ifnet *, u_long, caddr_t); | |
136static void malo_updateslot(struct ieee80211com *); 137static int malo_newstate(struct ieee80211vap *, enum ieee80211_state, int); 138static void malo_scan_start(struct ieee80211com *); 139static void malo_scan_end(struct ieee80211com *); 140static void malo_set_channel(struct ieee80211com *); 141static int malo_raw_xmit(struct ieee80211_node *, struct mbuf *, 142 const struct ieee80211_bpf_params *); 143static void malo_sysctlattach(struct malo_softc *); 144static void malo_announce(struct malo_softc *); 145static void malo_dma_cleanup(struct malo_softc *); | 133static void malo_updateslot(struct ieee80211com *); 134static int malo_newstate(struct ieee80211vap *, enum ieee80211_state, int); 135static void malo_scan_start(struct ieee80211com *); 136static void malo_scan_end(struct ieee80211com *); 137static void malo_set_channel(struct ieee80211com *); 138static int malo_raw_xmit(struct ieee80211_node *, struct mbuf *, 139 const struct ieee80211_bpf_params *); 140static void malo_sysctlattach(struct malo_softc *); 141static void malo_announce(struct malo_softc *); 142static void malo_dma_cleanup(struct malo_softc *); |
146static void malo_stop_locked(struct ifnet *, int); | 143static void malo_stop(struct malo_softc *); |
147static int malo_chan_set(struct malo_softc *, struct ieee80211_channel *); 148static int malo_mode_init(struct malo_softc *); 149static void malo_tx_proc(void *, int); 150static void malo_rx_proc(void *, int); 151static void malo_init(void *); 152 153/* 154 * Read/Write shorthands for accesses to BAR 0. Note that all BAR 1 --- 13 unchanged lines hidden (view full) --- 168 __func__, (uintmax_t)off, val); 169 170 bus_space_write_4(sc->malo_io0t, sc->malo_io0h, off, val); 171} 172 173int 174malo_attach(uint16_t devid, struct malo_softc *sc) 175{ | 144static int malo_chan_set(struct malo_softc *, struct ieee80211_channel *); 145static int malo_mode_init(struct malo_softc *); 146static void malo_tx_proc(void *, int); 147static void malo_rx_proc(void *, int); 148static void malo_init(void *); 149 150/* 151 * Read/Write shorthands for accesses to BAR 0. Note that all BAR 1 --- 13 unchanged lines hidden (view full) --- 165 __func__, (uintmax_t)off, val); 166 167 bus_space_write_4(sc->malo_io0t, sc->malo_io0h, off, val); 168} 169 170int 171malo_attach(uint16_t devid, struct malo_softc *sc) 172{ |
176 int error; 177 struct ieee80211com *ic; 178 struct ifnet *ifp; | 173 struct ieee80211com *ic = &sc->malo_ic; |
179 struct malo_hal *mh; | 174 struct malo_hal *mh; |
175 int error; |
|
180 uint8_t bands; 181 | 176 uint8_t bands; 177 |
182 ifp = sc->malo_ifp = if_alloc(IFT_IEEE80211); 183 if (ifp == NULL) { 184 device_printf(sc->malo_dev, "can not if_alloc()\n"); 185 return ENOSPC; 186 } 187 ic = ifp->if_l2com; 188 | |
189 MALO_LOCK_INIT(sc); 190 callout_init_mtx(&sc->malo_watchdog_timer, &sc->malo_mtx, 0); | 178 MALO_LOCK_INIT(sc); 179 callout_init_mtx(&sc->malo_watchdog_timer, &sc->malo_mtx, 0); |
180 mbufq_init(&sc->malo_snd, ifqmaxlen); |
|
191 | 181 |
192 /* set these up early for if_printf use */ 193 if_initname(ifp, device_get_name(sc->malo_dev), 194 device_get_unit(sc->malo_dev)); 195 | |
196 mh = malo_hal_attach(sc->malo_dev, devid, 197 sc->malo_io1h, sc->malo_io1t, sc->malo_dmat); 198 if (mh == NULL) { | 182 mh = malo_hal_attach(sc->malo_dev, devid, 183 sc->malo_io1h, sc->malo_io1t, sc->malo_dmat); 184 if (mh == NULL) { |
199 if_printf(ifp, "unable to attach HAL\n"); | 185 device_printf(sc->malo_dev, "unable to attach HAL\n"); |
200 error = EIO; 201 goto bad; 202 } 203 sc->malo_mh = mh; 204 205 /* 206 * Load firmware so we can get setup. We arbitrarily pick station 207 * firmware; we'll re-load firmware as needed so setting up 208 * the wrong mode isn't a big deal. 209 */ 210 error = malo_hal_fwload(mh, "malo8335-h", "malo8335-m"); 211 if (error != 0) { | 186 error = EIO; 187 goto bad; 188 } 189 sc->malo_mh = mh; 190 191 /* 192 * Load firmware so we can get setup. We arbitrarily pick station 193 * firmware; we'll re-load firmware as needed so setting up 194 * the wrong mode isn't a big deal. 195 */ 196 error = malo_hal_fwload(mh, "malo8335-h", "malo8335-m"); 197 if (error != 0) { |
212 if_printf(ifp, "unable to setup firmware\n"); | 198 device_printf(sc->malo_dev, "unable to setup firmware\n"); |
213 goto bad1; 214 } 215 /* XXX gethwspecs() extracts correct informations? not maybe! */ 216 error = malo_hal_gethwspecs(mh, &sc->malo_hwspecs); 217 if (error != 0) { | 199 goto bad1; 200 } 201 /* XXX gethwspecs() extracts correct informations? not maybe! */ 202 error = malo_hal_gethwspecs(mh, &sc->malo_hwspecs); 203 if (error != 0) { |
218 if_printf(ifp, "unable to fetch h/w specs\n"); | 204 device_printf(sc->malo_dev, "unable to fetch h/w specs\n"); |
219 goto bad1; 220 } 221 222 DPRINTF(sc, MALO_DEBUG_FW, 223 "malo_hal_gethwspecs: hwversion 0x%x hostif 0x%x" 224 "maxnum_wcb 0x%x maxnum_mcaddr 0x%x maxnum_tx_wcb 0x%x" 225 "regioncode 0x%x num_antenna 0x%x fw_releasenum 0x%x" 226 "wcbbase0 0x%x rxdesc_read 0x%x rxdesc_write 0x%x" --- 19 unchanged lines hidden (view full) --- 246 247 /* 248 * Allocate tx + rx descriptors and populate the lists. 249 * We immediately push the information to the firmware 250 * as otherwise it gets upset. 251 */ 252 error = malo_dma_setup(sc); 253 if (error != 0) { | 205 goto bad1; 206 } 207 208 DPRINTF(sc, MALO_DEBUG_FW, 209 "malo_hal_gethwspecs: hwversion 0x%x hostif 0x%x" 210 "maxnum_wcb 0x%x maxnum_mcaddr 0x%x maxnum_tx_wcb 0x%x" 211 "regioncode 0x%x num_antenna 0x%x fw_releasenum 0x%x" 212 "wcbbase0 0x%x rxdesc_read 0x%x rxdesc_write 0x%x" --- 19 unchanged lines hidden (view full) --- 232 233 /* 234 * Allocate tx + rx descriptors and populate the lists. 235 * We immediately push the information to the firmware 236 * as otherwise it gets upset. 237 */ 238 error = malo_dma_setup(sc); 239 if (error != 0) { |
254 if_printf(ifp, "failed to setup descriptors: %d\n", error); | 240 device_printf(sc->malo_dev, 241 "failed to setup descriptors: %d\n", error); |
255 goto bad1; 256 } 257 error = malo_setup_hwdma(sc); /* push to firmware */ 258 if (error != 0) /* NB: malo_setupdma prints msg */ 259 goto bad2; 260 261 sc->malo_tq = taskqueue_create_fast("malo_taskq", M_NOWAIT, 262 taskqueue_thread_enqueue, &sc->malo_tq); 263 taskqueue_start_threads(&sc->malo_tq, 1, PI_NET, | 242 goto bad1; 243 } 244 error = malo_setup_hwdma(sc); /* push to firmware */ 245 if (error != 0) /* NB: malo_setupdma prints msg */ 246 goto bad2; 247 248 sc->malo_tq = taskqueue_create_fast("malo_taskq", M_NOWAIT, 249 taskqueue_thread_enqueue, &sc->malo_tq); 250 taskqueue_start_threads(&sc->malo_tq, 1, PI_NET, |
264 "%s taskq", ifp->if_xname); | 251 "%s taskq", device_get_nameunit(sc->malo_dev)); |
265 266 TASK_INIT(&sc->malo_rxtask, 0, malo_rx_proc, sc); 267 TASK_INIT(&sc->malo_txtask, 0, malo_tx_proc, sc); 268 | 252 253 TASK_INIT(&sc->malo_rxtask, 0, malo_rx_proc, sc); 254 TASK_INIT(&sc->malo_txtask, 0, malo_tx_proc, sc); 255 |
269 ifp->if_softc = sc; 270 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; 271 ifp->if_start = malo_start; 272 ifp->if_ioctl = malo_ioctl; 273 ifp->if_init = malo_init; 274 IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); 275 ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; 276 IFQ_SET_READY(&ifp->if_snd); 277 278 ic->ic_ifp = ifp; | |
279 ic->ic_softc = sc; 280 ic->ic_name = device_get_nameunit(sc->malo_dev); 281 /* XXX not right but it's not used anywhere important */ 282 ic->ic_phytype = IEEE80211_T_OFDM; 283 ic->ic_opmode = IEEE80211_M_STA; 284 ic->ic_caps = 285 IEEE80211_C_STA /* station mode supported */ 286 | IEEE80211_C_BGSCAN /* capable of bg scanning */ 287 | IEEE80211_C_MONITOR /* monitor mode */ 288 | IEEE80211_C_SHPREAMBLE /* short preamble supported */ 289 | IEEE80211_C_SHSLOT /* short slot time supported */ 290 | IEEE80211_C_TXPMGT /* capable of txpow mgt */ 291 | IEEE80211_C_WPA /* capable of WPA1+WPA2 */ 292 ; | 256 ic->ic_softc = sc; 257 ic->ic_name = device_get_nameunit(sc->malo_dev); 258 /* XXX not right but it's not used anywhere important */ 259 ic->ic_phytype = IEEE80211_T_OFDM; 260 ic->ic_opmode = IEEE80211_M_STA; 261 ic->ic_caps = 262 IEEE80211_C_STA /* station mode supported */ 263 | IEEE80211_C_BGSCAN /* capable of bg scanning */ 264 | IEEE80211_C_MONITOR /* monitor mode */ 265 | IEEE80211_C_SHPREAMBLE /* short preamble supported */ 266 | IEEE80211_C_SHSLOT /* short slot time supported */ 267 | IEEE80211_C_TXPMGT /* capable of txpow mgt */ 268 | IEEE80211_C_WPA /* capable of WPA1+WPA2 */ 269 ; |
270 IEEE80211_ADDR_COPY(ic->ic_macaddr, sc->malo_hwspecs.macaddr); |
|
293 294 /* 295 * Transmit requires space in the packet for a special format transmit 296 * record and optional padding between this record and the payload. 297 * Ask the net80211 layer to arrange this when encapsulating 298 * packets so we can add it efficiently. 299 */ 300 ic->ic_headroom = sizeof(struct malo_txrec) - 301 sizeof(struct ieee80211_frame); 302 303 /* call MI attach routine. */ | 271 272 /* 273 * Transmit requires space in the packet for a special format transmit 274 * record and optional padding between this record and the payload. 275 * Ask the net80211 layer to arrange this when encapsulating 276 * packets so we can add it efficiently. 277 */ 278 ic->ic_headroom = sizeof(struct malo_txrec) - 279 sizeof(struct ieee80211_frame); 280 281 /* call MI attach routine. */ |
304 ieee80211_ifattach(ic, sc->malo_hwspecs.macaddr); | 282 ieee80211_ifattach(ic); |
305 /* override default methods */ 306 ic->ic_vap_create = malo_vap_create; 307 ic->ic_vap_delete = malo_vap_delete; 308 ic->ic_raw_xmit = malo_raw_xmit; 309 ic->ic_updateslot = malo_updateslot; | 283 /* override default methods */ 284 ic->ic_vap_create = malo_vap_create; 285 ic->ic_vap_delete = malo_vap_delete; 286 ic->ic_raw_xmit = malo_raw_xmit; 287 ic->ic_updateslot = malo_updateslot; |
310 | |
311 ic->ic_scan_start = malo_scan_start; 312 ic->ic_scan_end = malo_scan_end; 313 ic->ic_set_channel = malo_set_channel; | 288 ic->ic_scan_start = malo_scan_start; 289 ic->ic_scan_end = malo_scan_end; 290 ic->ic_set_channel = malo_set_channel; |
291 ic->ic_parent = malo_parent; 292 ic->ic_transmit = malo_transmit; |
|
314 315 sc->malo_invalid = 0; /* ready to go, enable int handling */ 316 317 ieee80211_radiotap_attach(ic, 318 &sc->malo_tx_th.wt_ihdr, sizeof(sc->malo_tx_th), 319 MALO_TX_RADIOTAP_PRESENT, 320 &sc->malo_rx_th.wr_ihdr, sizeof(sc->malo_rx_th), 321 MALO_RX_RADIOTAP_PRESENT); --- 8 unchanged lines hidden (view full) --- 330 malo_announce(sc); 331 332 return 0; 333bad2: 334 malo_dma_cleanup(sc); 335bad1: 336 malo_hal_detach(mh); 337bad: | 293 294 sc->malo_invalid = 0; /* ready to go, enable int handling */ 295 296 ieee80211_radiotap_attach(ic, 297 &sc->malo_tx_th.wt_ihdr, sizeof(sc->malo_tx_th), 298 MALO_TX_RADIOTAP_PRESENT, 299 &sc->malo_rx_th.wr_ihdr, sizeof(sc->malo_rx_th), 300 MALO_RX_RADIOTAP_PRESENT); --- 8 unchanged lines hidden (view full) --- 309 malo_announce(sc); 310 311 return 0; 312bad2: 313 malo_dma_cleanup(sc); 314bad1: 315 malo_hal_detach(mh); 316bad: |
338 if_free(ifp); | |
339 sc->malo_invalid = 1; 340 341 return error; 342} 343 344static struct ieee80211vap * 345malo_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, 346 enum ieee80211_opmode opmode, int flags, 347 const uint8_t bssid[IEEE80211_ADDR_LEN], 348 const uint8_t mac[IEEE80211_ADDR_LEN]) 349{ | 317 sc->malo_invalid = 1; 318 319 return error; 320} 321 322static struct ieee80211vap * 323malo_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit, 324 enum ieee80211_opmode opmode, int flags, 325 const uint8_t bssid[IEEE80211_ADDR_LEN], 326 const uint8_t mac[IEEE80211_ADDR_LEN]) 327{ |
350 struct ifnet *ifp = ic->ic_ifp; | 328 struct malo_softc *sc = ic->ic_softc; |
351 struct malo_vap *mvp; 352 struct ieee80211vap *vap; 353 354 if (!TAILQ_EMPTY(&ic->ic_vaps)) { | 329 struct malo_vap *mvp; 330 struct ieee80211vap *vap; 331 332 if (!TAILQ_EMPTY(&ic->ic_vaps)) { |
355 if_printf(ifp, "multiple vaps not supported\n"); | 333 device_printf(sc->malo_dev, "multiple vaps not supported\n"); |
356 return NULL; 357 } 358 switch (opmode) { 359 case IEEE80211_M_STA: 360 if (opmode == IEEE80211_M_STA) 361 flags |= IEEE80211_CLONE_NOBEACONS; 362 /* fall thru... */ 363 case IEEE80211_M_MONITOR: 364 break; 365 default: | 334 return NULL; 335 } 336 switch (opmode) { 337 case IEEE80211_M_STA: 338 if (opmode == IEEE80211_M_STA) 339 flags |= IEEE80211_CLONE_NOBEACONS; 340 /* fall thru... */ 341 case IEEE80211_M_MONITOR: 342 break; 343 default: |
366 if_printf(ifp, "%s mode not supported\n", | 344 device_printf(sc->malo_dev, "%s mode not supported\n", |
367 ieee80211_opmode_name[opmode]); 368 return NULL; /* unsupported */ 369 } | 345 ieee80211_opmode_name[opmode]); 346 return NULL; /* unsupported */ 347 } |
370 mvp = (struct malo_vap *) malloc(sizeof(struct malo_vap), 371 M_80211_VAP, M_NOWAIT | M_ZERO); 372 if (mvp == NULL) { 373 if_printf(ifp, "cannot allocate vap state block\n"); 374 return NULL; 375 } | 348 mvp = malloc(sizeof(struct malo_vap), M_80211_VAP, M_WAITOK | M_ZERO); |
376 vap = &mvp->malo_vap; | 349 vap = &mvp->malo_vap; |
377 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); | 350 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid); |
378 379 /* override state transition machine */ 380 mvp->malo_newstate = vap->iv_newstate; 381 vap->iv_newstate = malo_newstate; 382 383 /* complete setup */ 384 ieee80211_vap_attach(vap, | 351 352 /* override state transition machine */ 353 mvp->malo_newstate = vap->iv_newstate; 354 vap->iv_newstate = malo_newstate; 355 356 /* complete setup */ 357 ieee80211_vap_attach(vap, |
385 ieee80211_media_change, ieee80211_media_status); | 358 ieee80211_media_change, ieee80211_media_status, mac); |
386 ic->ic_opmode = opmode; 387 return vap; 388} 389 390static void 391malo_vap_delete(struct ieee80211vap *vap) 392{ 393 struct malo_vap *mvp = MALO_VAP(vap); --- 62 unchanged lines hidden (view full) --- 456} 457 458static int 459malo_desc_setup(struct malo_softc *sc, const char *name, 460 struct malo_descdma *dd, 461 int nbuf, size_t bufsize, int ndesc, size_t descsize) 462{ 463 int error; | 359 ic->ic_opmode = opmode; 360 return vap; 361} 362 363static void 364malo_vap_delete(struct ieee80211vap *vap) 365{ 366 struct malo_vap *mvp = MALO_VAP(vap); --- 62 unchanged lines hidden (view full) --- 429} 430 431static int 432malo_desc_setup(struct malo_softc *sc, const char *name, 433 struct malo_descdma *dd, 434 int nbuf, size_t bufsize, int ndesc, size_t descsize) 435{ 436 int error; |
464 struct ifnet *ifp = sc->malo_ifp; | |
465 uint8_t *ds; 466 467 DPRINTF(sc, MALO_DEBUG_RESET, 468 "%s: %s DMA: %u bufs (%ju) %u desc/buf (%ju)\n", 469 __func__, name, nbuf, (uintmax_t) bufsize, 470 ndesc, (uintmax_t) descsize); 471 472 dd->dd_name = name; --- 10 unchanged lines hidden (view full) --- 483 dd->dd_desc_len, /* maxsize */ 484 1, /* nsegments */ 485 dd->dd_desc_len, /* maxsegsize */ 486 BUS_DMA_ALLOCNOW, /* flags */ 487 NULL, /* lockfunc */ 488 NULL, /* lockarg */ 489 &dd->dd_dmat); 490 if (error != 0) { | 437 uint8_t *ds; 438 439 DPRINTF(sc, MALO_DEBUG_RESET, 440 "%s: %s DMA: %u bufs (%ju) %u desc/buf (%ju)\n", 441 __func__, name, nbuf, (uintmax_t) bufsize, 442 ndesc, (uintmax_t) descsize); 443 444 dd->dd_name = name; --- 10 unchanged lines hidden (view full) --- 455 dd->dd_desc_len, /* maxsize */ 456 1, /* nsegments */ 457 dd->dd_desc_len, /* maxsegsize */ 458 BUS_DMA_ALLOCNOW, /* flags */ 459 NULL, /* lockfunc */ 460 NULL, /* lockarg */ 461 &dd->dd_dmat); 462 if (error != 0) { |
491 if_printf(ifp, "cannot allocate %s DMA tag\n", dd->dd_name); | 463 device_printf(sc->malo_dev, "cannot allocate %s DMA tag\n", 464 dd->dd_name); |
492 return error; 493 } 494 495 /* allocate descriptors */ 496 error = bus_dmamem_alloc(dd->dd_dmat, (void**) &dd->dd_desc, 497 BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &dd->dd_dmamap); 498 if (error != 0) { | 465 return error; 466 } 467 468 /* allocate descriptors */ 469 error = bus_dmamem_alloc(dd->dd_dmat, (void**) &dd->dd_desc, 470 BUS_DMA_NOWAIT | BUS_DMA_COHERENT, &dd->dd_dmamap); 471 if (error != 0) { |
499 if_printf(ifp, "unable to alloc memory for %u %s descriptors, " | 472 device_printf(sc->malo_dev, 473 "unable to alloc memory for %u %s descriptors, " |
500 "error %u\n", nbuf * ndesc, dd->dd_name, error); 501 goto fail1; 502 } 503 504 error = bus_dmamap_load(dd->dd_dmat, dd->dd_dmamap, 505 dd->dd_desc, dd->dd_desc_len, 506 malo_load_cb, &dd->dd_desc_paddr, BUS_DMA_NOWAIT); 507 if (error != 0) { | 474 "error %u\n", nbuf * ndesc, dd->dd_name, error); 475 goto fail1; 476 } 477 478 error = bus_dmamap_load(dd->dd_dmat, dd->dd_dmamap, 479 dd->dd_desc, dd->dd_desc_len, 480 malo_load_cb, &dd->dd_desc_paddr, BUS_DMA_NOWAIT); 481 if (error != 0) { |
508 if_printf(ifp, "unable to map %s descriptors, error %u\n", | 482 device_printf(sc->malo_dev, 483 "unable to map %s descriptors, error %u\n", |
509 dd->dd_name, error); 510 goto fail2; 511 } 512 513 ds = dd->dd_desc; 514 memset(ds, 0, dd->dd_desc_len); 515 DPRINTF(sc, MALO_DEBUG_RESET, 516 "%s: %s DMA map: %p (%lu) -> 0x%jx (%lu)\n", --- 10 unchanged lines hidden (view full) --- 527} 528 529#define DS2PHYS(_dd, _ds) \ 530 ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc)) 531 532static int 533malo_rxdma_setup(struct malo_softc *sc) 534{ | 484 dd->dd_name, error); 485 goto fail2; 486 } 487 488 ds = dd->dd_desc; 489 memset(ds, 0, dd->dd_desc_len); 490 DPRINTF(sc, MALO_DEBUG_RESET, 491 "%s: %s DMA map: %p (%lu) -> 0x%jx (%lu)\n", --- 10 unchanged lines hidden (view full) --- 502} 503 504#define DS2PHYS(_dd, _ds) \ 505 ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc)) 506 507static int 508malo_rxdma_setup(struct malo_softc *sc) 509{ |
535 struct ifnet *ifp = sc->malo_ifp; | |
536 int error, bsize, i; 537 struct malo_rxbuf *bf; 538 struct malo_rxdesc *ds; 539 540 error = malo_desc_setup(sc, "rx", &sc->malo_rxdma, 541 malo_rxbuf, sizeof(struct malo_rxbuf), 542 1, sizeof(struct malo_rxdesc)); 543 if (error != 0) 544 return error; 545 546 /* 547 * Allocate rx buffers and set them up. 548 */ 549 bsize = malo_rxbuf * sizeof(struct malo_rxbuf); 550 bf = malloc(bsize, M_MALODEV, M_NOWAIT | M_ZERO); 551 if (bf == NULL) { | 510 int error, bsize, i; 511 struct malo_rxbuf *bf; 512 struct malo_rxdesc *ds; 513 514 error = malo_desc_setup(sc, "rx", &sc->malo_rxdma, 515 malo_rxbuf, sizeof(struct malo_rxbuf), 516 1, sizeof(struct malo_rxdesc)); 517 if (error != 0) 518 return error; 519 520 /* 521 * Allocate rx buffers and set them up. 522 */ 523 bsize = malo_rxbuf * sizeof(struct malo_rxbuf); 524 bf = malloc(bsize, M_MALODEV, M_NOWAIT | M_ZERO); 525 if (bf == NULL) { |
552 if_printf(ifp, "malloc of %u rx buffers failed\n", bsize); | 526 device_printf(sc->malo_dev, 527 "malloc of %u rx buffers failed\n", bsize); |
553 return error; 554 } 555 sc->malo_rxdma.dd_bufptr = bf; 556 557 STAILQ_INIT(&sc->malo_rxbuf); 558 ds = sc->malo_rxdma.dd_desc; 559 for (i = 0; i < malo_rxbuf; i++, bf++, ds++) { 560 bf->bf_desc = ds; 561 bf->bf_daddr = DS2PHYS(&sc->malo_rxdma, ds); 562 error = bus_dmamap_create(sc->malo_dmat, BUS_DMA_NOWAIT, 563 &bf->bf_dmamap); 564 if (error != 0) { | 528 return error; 529 } 530 sc->malo_rxdma.dd_bufptr = bf; 531 532 STAILQ_INIT(&sc->malo_rxbuf); 533 ds = sc->malo_rxdma.dd_desc; 534 for (i = 0; i < malo_rxbuf; i++, bf++, ds++) { 535 bf->bf_desc = ds; 536 bf->bf_daddr = DS2PHYS(&sc->malo_rxdma, ds); 537 error = bus_dmamap_create(sc->malo_dmat, BUS_DMA_NOWAIT, 538 &bf->bf_dmamap); 539 if (error != 0) { |
565 if_printf(ifp, "%s: unable to dmamap for rx buffer, " 566 "error %d\n", __func__, error); | 540 device_printf(sc->malo_dev, 541 "%s: unable to dmamap for rx buffer, error %d\n", 542 __func__, error); |
567 return error; 568 } 569 /* NB: tail is intentional to preserve descriptor order */ 570 STAILQ_INSERT_TAIL(&sc->malo_rxbuf, bf, bf_list); 571 } 572 return 0; 573} 574 575static int 576malo_txdma_setup(struct malo_softc *sc, struct malo_txq *txq) 577{ | 543 return error; 544 } 545 /* NB: tail is intentional to preserve descriptor order */ 546 STAILQ_INSERT_TAIL(&sc->malo_rxbuf, bf, bf_list); 547 } 548 return 0; 549} 550 551static int 552malo_txdma_setup(struct malo_softc *sc, struct malo_txq *txq) 553{ |
578 struct ifnet *ifp = sc->malo_ifp; | |
579 int error, bsize, i; 580 struct malo_txbuf *bf; 581 struct malo_txdesc *ds; 582 583 error = malo_desc_setup(sc, "tx", &txq->dma, 584 malo_txbuf, sizeof(struct malo_txbuf), 585 MALO_TXDESC, sizeof(struct malo_txdesc)); 586 if (error != 0) 587 return error; 588 589 /* allocate and setup tx buffers */ 590 bsize = malo_txbuf * sizeof(struct malo_txbuf); 591 bf = malloc(bsize, M_MALODEV, M_NOWAIT | M_ZERO); 592 if (bf == NULL) { | 554 int error, bsize, i; 555 struct malo_txbuf *bf; 556 struct malo_txdesc *ds; 557 558 error = malo_desc_setup(sc, "tx", &txq->dma, 559 malo_txbuf, sizeof(struct malo_txbuf), 560 MALO_TXDESC, sizeof(struct malo_txdesc)); 561 if (error != 0) 562 return error; 563 564 /* allocate and setup tx buffers */ 565 bsize = malo_txbuf * sizeof(struct malo_txbuf); 566 bf = malloc(bsize, M_MALODEV, M_NOWAIT | M_ZERO); 567 if (bf == NULL) { |
593 if_printf(ifp, "malloc of %u tx buffers failed\n", | 568 device_printf(sc->malo_dev, "malloc of %u tx buffers failed\n", |
594 malo_txbuf); 595 return ENOMEM; 596 } 597 txq->dma.dd_bufptr = bf; 598 599 STAILQ_INIT(&txq->free); 600 txq->nfree = 0; 601 ds = txq->dma.dd_desc; 602 for (i = 0; i < malo_txbuf; i++, bf++, ds += MALO_TXDESC) { 603 bf->bf_desc = ds; 604 bf->bf_daddr = DS2PHYS(&txq->dma, ds); 605 error = bus_dmamap_create(sc->malo_dmat, BUS_DMA_NOWAIT, 606 &bf->bf_dmamap); 607 if (error != 0) { | 569 malo_txbuf); 570 return ENOMEM; 571 } 572 txq->dma.dd_bufptr = bf; 573 574 STAILQ_INIT(&txq->free); 575 txq->nfree = 0; 576 ds = txq->dma.dd_desc; 577 for (i = 0; i < malo_txbuf; i++, bf++, ds += MALO_TXDESC) { 578 bf->bf_desc = ds; 579 bf->bf_daddr = DS2PHYS(&txq->dma, ds); 580 error = bus_dmamap_create(sc->malo_dmat, BUS_DMA_NOWAIT, 581 &bf->bf_dmamap); 582 if (error != 0) { |
608 if_printf(ifp, "unable to create dmamap for tx " | 583 device_printf(sc->malo_dev, 584 "unable to create dmamap for tx " |
609 "buffer %u, error %u\n", i, error); 610 return error; 611 } 612 STAILQ_INSERT_TAIL(&txq->free, bf, bf_list); 613 txq->nfree++; 614 } 615 616 return 0; --- 382 unchanged lines hidden (view full) --- 999 } else { 1000 if (status & MALO_TXD_STATUS_FAILED_LINK_ERROR) 1001 sc->malo_stats.mst_tx_linkerror++; 1002 if (status & MALO_TXD_STATUS_FAILED_XRETRY) 1003 sc->malo_stats.mst_tx_xretries++; 1004 if (status & MALO_TXD_STATUS_FAILED_AGING) 1005 sc->malo_stats.mst_tx_aging++; 1006 } | 585 "buffer %u, error %u\n", i, error); 586 return error; 587 } 588 STAILQ_INSERT_TAIL(&txq->free, bf, bf_list); 589 txq->nfree++; 590 } 591 592 return 0; --- 382 unchanged lines hidden (view full) --- 975 } else { 976 if (status & MALO_TXD_STATUS_FAILED_LINK_ERROR) 977 sc->malo_stats.mst_tx_linkerror++; 978 if (status & MALO_TXD_STATUS_FAILED_XRETRY) 979 sc->malo_stats.mst_tx_xretries++; 980 if (status & MALO_TXD_STATUS_FAILED_AGING) 981 sc->malo_stats.mst_tx_aging++; 982 } |
1007 /* 1008 * Do any tx complete callback. Note this must 1009 * be done before releasing the node reference. 1010 * XXX no way to figure out if frame was ACK'd 1011 */ 1012 if (bf->bf_m->m_flags & M_TXCB) { 1013 /* XXX strip fw len in case header inspected */ 1014 m_adj(bf->bf_m, sizeof(uint16_t)); 1015 ieee80211_process_callback(ni, bf->bf_m, 1016 (status & MALO_TXD_STATUS_OK) == 0); 1017 } 1018 /* 1019 * Reclaim reference to node. 1020 * 1021 * NB: the node may be reclaimed here if, for example 1022 * this is a DEAUTH message that was sent and the 1023 * node was timed out due to inactivity. 1024 */ 1025 ieee80211_free_node(ni); 1026 } | 983 /* XXX strip fw len in case header inspected */ 984 m_adj(bf->bf_m, sizeof(uint16_t)); 985 ieee80211_tx_complete(ni, bf->bf_m, 986 (status & MALO_TXD_STATUS_OK) == 0); 987 } else 988 m_freem(bf->bf_m); 989 |
1027 ds->status = htole32(MALO_TXD_STATUS_IDLE); 1028 ds->pktlen = htole32(0); 1029 1030 bus_dmamap_sync(sc->malo_dmat, bf->bf_dmamap, 1031 BUS_DMASYNC_POSTWRITE); 1032 bus_dmamap_unload(sc->malo_dmat, bf->bf_dmamap); | 990 ds->status = htole32(MALO_TXD_STATUS_IDLE); 991 ds->pktlen = htole32(0); 992 993 bus_dmamap_sync(sc->malo_dmat, bf->bf_dmamap, 994 BUS_DMASYNC_POSTWRITE); 995 bus_dmamap_unload(sc->malo_dmat, bf->bf_dmamap); |
1033 m_freem(bf->bf_m); | |
1034 bf->bf_m = NULL; 1035 bf->bf_node = NULL; 1036 1037 MALO_TXQ_LOCK(txq); 1038 STAILQ_INSERT_TAIL(&txq->free, bf, bf_list); 1039 txq->nfree++; 1040 MALO_TXQ_UNLOCK(txq); 1041 } 1042 return nreaped; 1043} 1044 1045/* 1046 * Deferred processing of transmit interrupt. 1047 */ 1048static void 1049malo_tx_proc(void *arg, int npending) 1050{ 1051 struct malo_softc *sc = arg; | 996 bf->bf_m = NULL; 997 bf->bf_node = NULL; 998 999 MALO_TXQ_LOCK(txq); 1000 STAILQ_INSERT_TAIL(&txq->free, bf, bf_list); 1001 txq->nfree++; 1002 MALO_TXQ_UNLOCK(txq); 1003 } 1004 return nreaped; 1005} 1006 1007/* 1008 * Deferred processing of transmit interrupt. 1009 */ 1010static void 1011malo_tx_proc(void *arg, int npending) 1012{ 1013 struct malo_softc *sc = arg; |
1052 struct ifnet *ifp = sc->malo_ifp; | |
1053 int i, nreaped; 1054 1055 /* 1056 * Process each active queue. 1057 */ 1058 nreaped = 0; | 1014 int i, nreaped; 1015 1016 /* 1017 * Process each active queue. 1018 */ 1019 nreaped = 0; |
1020 MALO_LOCK(sc); |
|
1059 for (i = 0; i < MALO_NUM_TX_QUEUES; i++) { 1060 if (!STAILQ_EMPTY(&sc->malo_txq[i].active)) 1061 nreaped += malo_tx_processq(sc, &sc->malo_txq[i]); 1062 } 1063 1064 if (nreaped != 0) { | 1021 for (i = 0; i < MALO_NUM_TX_QUEUES; i++) { 1022 if (!STAILQ_EMPTY(&sc->malo_txq[i].active)) 1023 nreaped += malo_tx_processq(sc, &sc->malo_txq[i]); 1024 } 1025 1026 if (nreaped != 0) { |
1065 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; | |
1066 sc->malo_timer = 0; | 1027 sc->malo_timer = 0; |
1067 malo_start(ifp); | 1028 malo_start(sc); |
1068 } | 1029 } |
1030 MALO_UNLOCK(sc); |
|
1069} 1070 1071static int 1072malo_tx_start(struct malo_softc *sc, struct ieee80211_node *ni, 1073 struct malo_txbuf *bf, struct mbuf *m0) 1074{ 1075#define IEEE80211_DIR_DSTODS(wh) \ 1076 ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS) 1077#define IS_DATA_FRAME(wh) \ 1078 ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK)) == IEEE80211_FC0_TYPE_DATA) 1079 int error, ismcast, iswep; 1080 int copyhdrlen, hdrlen, pktlen; 1081 struct ieee80211_frame *wh; | 1031} 1032 1033static int 1034malo_tx_start(struct malo_softc *sc, struct ieee80211_node *ni, 1035 struct malo_txbuf *bf, struct mbuf *m0) 1036{ 1037#define IEEE80211_DIR_DSTODS(wh) \ 1038 ((wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS) 1039#define IS_DATA_FRAME(wh) \ 1040 ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK)) == IEEE80211_FC0_TYPE_DATA) 1041 int error, ismcast, iswep; 1042 int copyhdrlen, hdrlen, pktlen; 1043 struct ieee80211_frame *wh; |
1082 struct ifnet *ifp = sc->malo_ifp; 1083 struct ieee80211com *ic = ifp->if_l2com; | 1044 struct ieee80211com *ic = &sc->malo_ic; |
1084 struct ieee80211vap *vap = ni->ni_vap; 1085 struct malo_txdesc *ds; 1086 struct malo_txrec *tr; 1087 struct malo_txq *txq; 1088 uint16_t qos; 1089 1090 wh = mtod(m0, struct ieee80211_frame *); 1091 iswep = wh->i_fc[1] & IEEE80211_FC1_PROTECTED; --- 128 unchanged lines hidden (view full) --- 1220 /* fall thru... */ 1221 case IEEE80211_FC0_TYPE_CTL: 1222 ds->txpriority = 1; 1223 break; 1224 case IEEE80211_FC0_TYPE_DATA: 1225 ds->txpriority = txq->qnum; 1226 break; 1227 default: | 1045 struct ieee80211vap *vap = ni->ni_vap; 1046 struct malo_txdesc *ds; 1047 struct malo_txrec *tr; 1048 struct malo_txq *txq; 1049 uint16_t qos; 1050 1051 wh = mtod(m0, struct ieee80211_frame *); 1052 iswep = wh->i_fc[1] & IEEE80211_FC1_PROTECTED; --- 128 unchanged lines hidden (view full) --- 1181 /* fall thru... */ 1182 case IEEE80211_FC0_TYPE_CTL: 1183 ds->txpriority = 1; 1184 break; 1185 case IEEE80211_FC0_TYPE_DATA: 1186 ds->txpriority = txq->qnum; 1187 break; 1188 default: |
1228 if_printf(ifp, "bogus frame type 0x%x (%s)\n", | 1189 device_printf(sc->malo_dev, "bogus frame type 0x%x (%s)\n", |
1229 wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK, __func__); 1230 /* XXX statistic */ 1231 m_freem(m0); 1232 return EIO; 1233 } 1234 1235#ifdef MALO_DEBUG 1236 if (IFF_DUMPPKTS_XMIT(sc)) --- 4 unchanged lines hidden (view full) --- 1241 1242 MALO_TXQ_LOCK(txq); 1243 if (!IS_DATA_FRAME(wh)) 1244 ds->status |= htole32(1); 1245 ds->status |= htole32(MALO_TXD_STATUS_FW_OWNED); 1246 STAILQ_INSERT_TAIL(&txq->active, bf, bf_list); 1247 MALO_TXDESC_SYNC(txq, ds, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1248 | 1190 wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK, __func__); 1191 /* XXX statistic */ 1192 m_freem(m0); 1193 return EIO; 1194 } 1195 1196#ifdef MALO_DEBUG 1197 if (IFF_DUMPPKTS_XMIT(sc)) --- 4 unchanged lines hidden (view full) --- 1202 1203 MALO_TXQ_LOCK(txq); 1204 if (!IS_DATA_FRAME(wh)) 1205 ds->status |= htole32(1); 1206 ds->status |= htole32(MALO_TXD_STATUS_FW_OWNED); 1207 STAILQ_INSERT_TAIL(&txq->active, bf, bf_list); 1208 MALO_TXDESC_SYNC(txq, ds, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1209 |
1249 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); | |
1250 sc->malo_timer = 5; 1251 MALO_TXQ_UNLOCK(txq); 1252 return 0; 1253#undef IEEE80211_DIR_DSTODS 1254} 1255 | 1210 sc->malo_timer = 5; 1211 MALO_TXQ_UNLOCK(txq); 1212 return 0; 1213#undef IEEE80211_DIR_DSTODS 1214} 1215 |
1216static int 1217malo_transmit(struct ieee80211com *ic, struct mbuf *m) 1218{ 1219 struct malo_softc *sc = ic->ic_softc; 1220 int error; 1221 1222 MALO_LOCK(sc); 1223 if (!sc->malo_running) { 1224 MALO_UNLOCK(sc); 1225 return (ENXIO); 1226 } 1227 error = mbufq_enqueue(&sc->malo_snd, m); 1228 if (error) { 1229 MALO_UNLOCK(sc); 1230 return (error); 1231 } 1232 malo_start(sc); 1233 MALO_UNLOCK(sc); 1234 return (0); 1235} 1236 |
|
1256static void | 1237static void |
1257malo_start(struct ifnet *ifp) | 1238malo_start(struct malo_softc *sc) |
1258{ | 1239{ |
1259 struct malo_softc *sc = ifp->if_softc; | |
1260 struct ieee80211_node *ni; 1261 struct malo_txq *txq = &sc->malo_txq[0]; 1262 struct malo_txbuf *bf = NULL; 1263 struct mbuf *m; 1264 int nqueued = 0; 1265 | 1240 struct ieee80211_node *ni; 1241 struct malo_txq *txq = &sc->malo_txq[0]; 1242 struct malo_txbuf *bf = NULL; 1243 struct mbuf *m; 1244 int nqueued = 0; 1245 |
1266 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->malo_invalid) | 1246 MALO_LOCK_ASSERT(sc); 1247 1248 if (!sc->malo_running || sc->malo_invalid) |
1267 return; 1268 | 1249 return; 1250 |
1269 for (;;) { 1270 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); 1271 if (m == NULL) 1272 break; | 1251 while ((m = mbufq_dequeue(&sc->malo_snd)) != NULL) { |
1273 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; 1274 bf = malo_getbuf(sc, txq); 1275 if (bf == NULL) { | 1252 ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; 1253 bf = malo_getbuf(sc, txq); 1254 if (bf == NULL) { |
1276 IFQ_DRV_PREPEND(&ifp->if_snd, m); 1277 1278 /* XXX blocks other traffic */ 1279 ifp->if_drv_flags |= IFF_DRV_OACTIVE; | 1255 mbufq_prepend(&sc->malo_snd, m); |
1280 sc->malo_stats.mst_tx_qstop++; 1281 break; 1282 } 1283 /* 1284 * Pass the frame to the h/w for transmission. 1285 */ 1286 if (malo_tx_start(sc, ni, bf, m)) { | 1256 sc->malo_stats.mst_tx_qstop++; 1257 break; 1258 } 1259 /* 1260 * Pass the frame to the h/w for transmission. 1261 */ 1262 if (malo_tx_start(sc, ni, bf, m)) { |
1287 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); | 1263 if_inc_counter(ni->ni_vap->iv_ifp, 1264 IFCOUNTER_OERRORS, 1); |
1288 if (bf != NULL) { 1289 bf->bf_m = NULL; 1290 bf->bf_node = NULL; 1291 MALO_TXQ_LOCK(txq); 1292 STAILQ_INSERT_HEAD(&txq->free, bf, bf_list); 1293 MALO_TXQ_UNLOCK(txq); 1294 } 1295 ieee80211_free_node(ni); --- 27 unchanged lines hidden (view full) --- 1323 */ 1324 malo_hal_txstart(sc->malo_mh, 0/*XXX*/); 1325 } 1326} 1327 1328static void 1329malo_watchdog(void *arg) 1330{ | 1265 if (bf != NULL) { 1266 bf->bf_m = NULL; 1267 bf->bf_node = NULL; 1268 MALO_TXQ_LOCK(txq); 1269 STAILQ_INSERT_HEAD(&txq->free, bf, bf_list); 1270 MALO_TXQ_UNLOCK(txq); 1271 } 1272 ieee80211_free_node(ni); --- 27 unchanged lines hidden (view full) --- 1300 */ 1301 malo_hal_txstart(sc->malo_mh, 0/*XXX*/); 1302 } 1303} 1304 1305static void 1306malo_watchdog(void *arg) 1307{ |
1331 struct malo_softc *sc; 1332 struct ifnet *ifp; | 1308 struct malo_softc *sc = arg; |
1333 | 1309 |
1334 sc = arg; | |
1335 callout_reset(&sc->malo_watchdog_timer, hz, malo_watchdog, sc); 1336 if (sc->malo_timer == 0 || --sc->malo_timer > 0) 1337 return; 1338 | 1310 callout_reset(&sc->malo_watchdog_timer, hz, malo_watchdog, sc); 1311 if (sc->malo_timer == 0 || --sc->malo_timer > 0) 1312 return; 1313 |
1339 ifp = sc->malo_ifp; 1340 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) && !sc->malo_invalid) { 1341 if_printf(ifp, "watchdog timeout\n"); | 1314 if (sc->malo_running && !sc->malo_invalid) { 1315 device_printf(sc->malo_dev, "watchdog timeout\n"); |
1342 1343 /* XXX no way to reset h/w. now */ 1344 | 1316 1317 /* XXX no way to reset h/w. now */ 1318 |
1345 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); | 1319 counter_u64_add(sc->malo_ic.ic_oerrors, 1); |
1346 sc->malo_stats.mst_watchdog++; 1347 } 1348} 1349 1350static int 1351malo_hal_reset(struct malo_softc *sc) 1352{ 1353 static int first = 0; | 1320 sc->malo_stats.mst_watchdog++; 1321 } 1322} 1323 1324static int 1325malo_hal_reset(struct malo_softc *sc) 1326{ 1327 static int first = 0; |
1354 struct ifnet *ifp = sc->malo_ifp; 1355 struct ieee80211com *ic = ifp->if_l2com; | 1328 struct ieee80211com *ic = &sc->malo_ic; |
1356 struct malo_hal *mh = sc->malo_mh; 1357 1358 if (first == 0) { 1359 /* 1360 * NB: when the device firstly is initialized, sometimes 1361 * firmware could override rx/tx dma registers so we re-set 1362 * these values once. 1363 */ --- 23 unchanged lines hidden (view full) --- 1387 if (m == NULL) { 1388 sc->malo_stats.mst_rx_nombuf++; /* XXX */ 1389 return NULL; 1390 } 1391 error = bus_dmamap_load(sc->malo_dmat, bf->bf_dmamap, 1392 mtod(m, caddr_t), MJUMPAGESIZE, 1393 malo_load_cb, &paddr, BUS_DMA_NOWAIT); 1394 if (error != 0) { | 1329 struct malo_hal *mh = sc->malo_mh; 1330 1331 if (first == 0) { 1332 /* 1333 * NB: when the device firstly is initialized, sometimes 1334 * firmware could override rx/tx dma registers so we re-set 1335 * these values once. 1336 */ --- 23 unchanged lines hidden (view full) --- 1360 if (m == NULL) { 1361 sc->malo_stats.mst_rx_nombuf++; /* XXX */ 1362 return NULL; 1363 } 1364 error = bus_dmamap_load(sc->malo_dmat, bf->bf_dmamap, 1365 mtod(m, caddr_t), MJUMPAGESIZE, 1366 malo_load_cb, &paddr, BUS_DMA_NOWAIT); 1367 if (error != 0) { |
1395 if_printf(sc->malo_ifp, | 1368 device_printf(sc->malo_dev, |
1396 "%s: bus_dmamap_load failed, error %d\n", __func__, error); 1397 m_freem(m); 1398 return NULL; 1399 } 1400 bf->bf_data = paddr; 1401 bus_dmamap_sync(sc->malo_dmat, bf->bf_dmamap, BUS_DMASYNC_PREWRITE); 1402 1403 return m; --- 74 unchanged lines hidden (view full) --- 1478 malo_mode_init(sc); /* set filters, etc. */ 1479 1480 return 0; 1481} 1482 1483static void 1484malo_init_locked(struct malo_softc *sc) 1485{ | 1369 "%s: bus_dmamap_load failed, error %d\n", __func__, error); 1370 m_freem(m); 1371 return NULL; 1372 } 1373 bf->bf_data = paddr; 1374 bus_dmamap_sync(sc->malo_dmat, bf->bf_dmamap, BUS_DMASYNC_PREWRITE); 1375 1376 return m; --- 74 unchanged lines hidden (view full) --- 1451 malo_mode_init(sc); /* set filters, etc. */ 1452 1453 return 0; 1454} 1455 1456static void 1457malo_init_locked(struct malo_softc *sc) 1458{ |
1486 struct ifnet *ifp = sc->malo_ifp; | |
1487 struct malo_hal *mh = sc->malo_mh; 1488 int error; 1489 | 1459 struct malo_hal *mh = sc->malo_mh; 1460 int error; 1461 |
1490 DPRINTF(sc, MALO_DEBUG_ANY, "%s: if_flags 0x%x\n", 1491 __func__, ifp->if_flags); 1492 | |
1493 MALO_LOCK_ASSERT(sc); 1494 1495 /* 1496 * Stop anything previously setup. This is safe whether this is 1497 * the first time through or not. 1498 */ | 1462 MALO_LOCK_ASSERT(sc); 1463 1464 /* 1465 * Stop anything previously setup. This is safe whether this is 1466 * the first time through or not. 1467 */ |
1499 malo_stop_locked(ifp, 0); | 1468 malo_stop(sc); |
1500 1501 /* 1502 * Push state to the firmware. 1503 */ 1504 if (!malo_hal_reset(sc)) { | 1469 1470 /* 1471 * Push state to the firmware. 1472 */ 1473 if (!malo_hal_reset(sc)) { |
1505 if_printf(ifp, "%s: unable to reset hardware\n", __func__); | 1474 device_printf(sc->malo_dev, 1475 "%s: unable to reset hardware\n", __func__); |
1506 return; 1507 } 1508 1509 /* 1510 * Setup recv (once); transmit is already good to go. 1511 */ 1512 error = malo_startrecv(sc); 1513 if (error != 0) { | 1476 return; 1477 } 1478 1479 /* 1480 * Setup recv (once); transmit is already good to go. 1481 */ 1482 error = malo_startrecv(sc); 1483 if (error != 0) { |
1514 if_printf(ifp, "%s: unable to start recv logic, error %d\n", | 1484 device_printf(sc->malo_dev, 1485 "%s: unable to start recv logic, error %d\n", |
1515 __func__, error); 1516 return; 1517 } 1518 1519 /* 1520 * Enable interrupts. 1521 */ 1522 sc->malo_imask = MALO_A2HRIC_BIT_RX_RDY 1523 | MALO_A2HRIC_BIT_TX_DONE 1524 | MALO_A2HRIC_BIT_OPC_DONE 1525 | MALO_A2HRIC_BIT_MAC_EVENT 1526 | MALO_A2HRIC_BIT_RX_PROBLEM 1527 | MALO_A2HRIC_BIT_ICV_ERROR 1528 | MALO_A2HRIC_BIT_RADAR_DETECT 1529 | MALO_A2HRIC_BIT_CHAN_SWITCH; 1530 | 1486 __func__, error); 1487 return; 1488 } 1489 1490 /* 1491 * Enable interrupts. 1492 */ 1493 sc->malo_imask = MALO_A2HRIC_BIT_RX_RDY 1494 | MALO_A2HRIC_BIT_TX_DONE 1495 | MALO_A2HRIC_BIT_OPC_DONE 1496 | MALO_A2HRIC_BIT_MAC_EVENT 1497 | MALO_A2HRIC_BIT_RX_PROBLEM 1498 | MALO_A2HRIC_BIT_ICV_ERROR 1499 | MALO_A2HRIC_BIT_RADAR_DETECT 1500 | MALO_A2HRIC_BIT_CHAN_SWITCH; 1501 |
1531 ifp->if_drv_flags |= IFF_DRV_RUNNING; | 1502 sc->malo_running = 1; |
1532 malo_hal_intrset(mh, sc->malo_imask); 1533 callout_reset(&sc->malo_watchdog_timer, hz, malo_watchdog, sc); 1534} 1535 1536static void 1537malo_init(void *arg) 1538{ 1539 struct malo_softc *sc = (struct malo_softc *) arg; | 1503 malo_hal_intrset(mh, sc->malo_imask); 1504 callout_reset(&sc->malo_watchdog_timer, hz, malo_watchdog, sc); 1505} 1506 1507static void 1508malo_init(void *arg) 1509{ 1510 struct malo_softc *sc = (struct malo_softc *) arg; |
1540 struct ifnet *ifp = sc->malo_ifp; 1541 struct ieee80211com *ic = ifp->if_l2com; | 1511 struct ieee80211com *ic = &sc->malo_ic; |
1542 | 1512 |
1543 DPRINTF(sc, MALO_DEBUG_ANY, "%s: if_flags 0x%x\n", 1544 __func__, ifp->if_flags); 1545 | |
1546 MALO_LOCK(sc); 1547 malo_init_locked(sc); | 1513 MALO_LOCK(sc); 1514 malo_init_locked(sc); |
1548 | |
1549 MALO_UNLOCK(sc); 1550 | 1515 MALO_UNLOCK(sc); 1516 |
1551 if (ifp->if_drv_flags & IFF_DRV_RUNNING) | 1517 if (sc->malo_running) |
1552 ieee80211_start_all(ic); /* start all vap's */ 1553} 1554 1555/* 1556 * Set the multicast filter contents into the hardware. 1557 */ 1558static void 1559malo_setmcastfilter(struct malo_softc *sc) 1560{ | 1518 ieee80211_start_all(ic); /* start all vap's */ 1519} 1520 1521/* 1522 * Set the multicast filter contents into the hardware. 1523 */ 1524static void 1525malo_setmcastfilter(struct malo_softc *sc) 1526{ |
1561 struct ifnet *ifp = sc->malo_ifp; 1562 struct ieee80211com *ic = ifp->if_l2com; 1563 struct ifmultiaddr *ifma; | 1527 struct ieee80211com *ic = &sc->malo_ic; 1528 struct ieee80211vap *vap; |
1564 uint8_t macs[IEEE80211_ADDR_LEN * MALO_HAL_MCAST_MAX]; 1565 uint8_t *mp; 1566 int nmc; 1567 1568 mp = macs; 1569 nmc = 0; 1570 | 1529 uint8_t macs[IEEE80211_ADDR_LEN * MALO_HAL_MCAST_MAX]; 1530 uint8_t *mp; 1531 int nmc; 1532 1533 mp = macs; 1534 nmc = 0; 1535 |
1571 if (ic->ic_opmode == IEEE80211_M_MONITOR || 1572 (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC))) | 1536 if (ic->ic_opmode == IEEE80211_M_MONITOR || ic->ic_allmulti > 0 || 1537 ic->ic_promisc > 0) |
1573 goto all; | 1538 goto all; |
1574 1575 if_maddr_rlock(ifp); 1576 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 1577 if (ifma->ifma_addr->sa_family != AF_LINK) 1578 continue; | |
1579 | 1539 |
1580 if (nmc == MALO_HAL_MCAST_MAX) { 1581 ifp->if_flags |= IFF_ALLMULTI; 1582 if_maddr_runlock(ifp); 1583 goto all; 1584 } 1585 IEEE80211_ADDR_COPY(mp, 1586 LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); | 1540 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { 1541 struct ifnet *ifp; 1542 struct ifmultiaddr *ifma; |
1587 | 1543 |
1588 mp += IEEE80211_ADDR_LEN, nmc++; | 1544 ifp = vap->iv_ifp; 1545 if_maddr_rlock(ifp); 1546 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 1547 if (ifma->ifma_addr->sa_family != AF_LINK) 1548 continue; 1549 1550 if (nmc == MALO_HAL_MCAST_MAX) { 1551 ifp->if_flags |= IFF_ALLMULTI; 1552 if_maddr_runlock(ifp); 1553 goto all; 1554 } 1555 IEEE80211_ADDR_COPY(mp, 1556 LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); 1557 1558 mp += IEEE80211_ADDR_LEN, nmc++; 1559 } 1560 if_maddr_runlock(ifp); |
1589 } | 1561 } |
1590 if_maddr_runlock(ifp); | |
1591 1592 malo_hal_setmcast(sc->malo_mh, nmc, macs); 1593 1594all: 1595 /* 1596 * XXX we don't know how to set the f/w for supporting 1597 * IFF_ALLMULTI | IFF_PROMISC cases 1598 */ 1599 return; 1600} 1601 1602static int 1603malo_mode_init(struct malo_softc *sc) 1604{ | 1562 1563 malo_hal_setmcast(sc->malo_mh, nmc, macs); 1564 1565all: 1566 /* 1567 * XXX we don't know how to set the f/w for supporting 1568 * IFF_ALLMULTI | IFF_PROMISC cases 1569 */ 1570 return; 1571} 1572 1573static int 1574malo_mode_init(struct malo_softc *sc) 1575{ |
1605 struct ifnet *ifp = sc->malo_ifp; 1606 struct ieee80211com *ic = ifp->if_l2com; | 1576 struct ieee80211com *ic = &sc->malo_ic; |
1607 struct malo_hal *mh = sc->malo_mh; 1608 1609 /* 1610 * NB: Ignore promisc in hostap mode; it's set by the 1611 * bridge. This is wrong but we have no way to 1612 * identify internal requests (from the bridge) 1613 * versus external requests such as for tcpdump. 1614 */ | 1577 struct malo_hal *mh = sc->malo_mh; 1578 1579 /* 1580 * NB: Ignore promisc in hostap mode; it's set by the 1581 * bridge. This is wrong but we have no way to 1582 * identify internal requests (from the bridge) 1583 * versus external requests such as for tcpdump. 1584 */ |
1615 malo_hal_setpromisc(mh, (ifp->if_flags & IFF_PROMISC) && | 1585 malo_hal_setpromisc(mh, ic->ic_promisc > 0 && |
1616 ic->ic_opmode != IEEE80211_M_HOSTAP); 1617 malo_setmcastfilter(sc); 1618 1619 return ENXIO; 1620} 1621 1622static void 1623malo_tx_draintxq(struct malo_softc *sc, struct malo_txq *txq) --- 12 unchanged lines hidden (view full) --- 1636 if (bf == NULL) { 1637 MALO_TXQ_UNLOCK(txq); 1638 break; 1639 } 1640 STAILQ_REMOVE_HEAD(&txq->active, bf_list); 1641 MALO_TXQ_UNLOCK(txq); 1642#ifdef MALO_DEBUG 1643 if (sc->malo_debug & MALO_DEBUG_RESET) { | 1586 ic->ic_opmode != IEEE80211_M_HOSTAP); 1587 malo_setmcastfilter(sc); 1588 1589 return ENXIO; 1590} 1591 1592static void 1593malo_tx_draintxq(struct malo_softc *sc, struct malo_txq *txq) --- 12 unchanged lines hidden (view full) --- 1606 if (bf == NULL) { 1607 MALO_TXQ_UNLOCK(txq); 1608 break; 1609 } 1610 STAILQ_REMOVE_HEAD(&txq->active, bf_list); 1611 MALO_TXQ_UNLOCK(txq); 1612#ifdef MALO_DEBUG 1613 if (sc->malo_debug & MALO_DEBUG_RESET) { |
1644 struct ifnet *ifp = sc->malo_ifp; 1645 struct ieee80211com *ic = ifp->if_l2com; | 1614 struct ieee80211com *ic = &sc->malo_ic; |
1646 const struct malo_txrec *tr = 1647 mtod(bf->bf_m, const struct malo_txrec *); 1648 malo_printtxbuf(bf, txq->qnum, ix); 1649 ieee80211_dump_pkt(ic, (const uint8_t *)&tr->wh, 1650 bf->bf_m->m_len - sizeof(tr->fwlen), 0, -1); 1651 } 1652#endif /* MALO_DEBUG */ 1653 bus_dmamap_unload(sc->malo_dmat, bf->bf_dmamap); --- 11 unchanged lines hidden (view full) --- 1665 MALO_TXQ_LOCK(txq); 1666 STAILQ_INSERT_TAIL(&txq->free, bf, bf_list); 1667 txq->nfree++; 1668 MALO_TXQ_UNLOCK(txq); 1669 } 1670} 1671 1672static void | 1615 const struct malo_txrec *tr = 1616 mtod(bf->bf_m, const struct malo_txrec *); 1617 malo_printtxbuf(bf, txq->qnum, ix); 1618 ieee80211_dump_pkt(ic, (const uint8_t *)&tr->wh, 1619 bf->bf_m->m_len - sizeof(tr->fwlen), 0, -1); 1620 } 1621#endif /* MALO_DEBUG */ 1622 bus_dmamap_unload(sc->malo_dmat, bf->bf_dmamap); --- 11 unchanged lines hidden (view full) --- 1634 MALO_TXQ_LOCK(txq); 1635 STAILQ_INSERT_TAIL(&txq->free, bf, bf_list); 1636 txq->nfree++; 1637 MALO_TXQ_UNLOCK(txq); 1638 } 1639} 1640 1641static void |
1673malo_stop_locked(struct ifnet *ifp, int disable) | 1642malo_stop(struct malo_softc *sc) |
1674{ | 1643{ |
1675 struct malo_softc *sc = ifp->if_softc; | |
1676 struct malo_hal *mh = sc->malo_mh; 1677 int i; 1678 | 1644 struct malo_hal *mh = sc->malo_mh; 1645 int i; 1646 |
1679 DPRINTF(sc, MALO_DEBUG_ANY, "%s: invalid %u if_flags 0x%x\n", 1680 __func__, sc->malo_invalid, ifp->if_flags); | 1647 DPRINTF(sc, MALO_DEBUG_ANY, "%s: invalid %u running %u\n", 1648 __func__, sc->malo_invalid, sc->malo_running); |
1681 1682 MALO_LOCK_ASSERT(sc); 1683 | 1649 1650 MALO_LOCK_ASSERT(sc); 1651 |
1684 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) | 1652 if (!sc->malo_running) |
1685 return; 1686 1687 /* 1688 * Shutdown the hardware and driver: 1689 * disable interrupts 1690 * turn off the radio 1691 * drain and release tx queues 1692 * 1693 * Note that some of this work is not possible if the hardware 1694 * is gone (invalid). 1695 */ | 1653 return; 1654 1655 /* 1656 * Shutdown the hardware and driver: 1657 * disable interrupts 1658 * turn off the radio 1659 * drain and release tx queues 1660 * 1661 * Note that some of this work is not possible if the hardware 1662 * is gone (invalid). 1663 */ |
1696 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; | 1664 sc->malo_running = 0; |
1697 callout_stop(&sc->malo_watchdog_timer); 1698 sc->malo_timer = 0; | 1665 callout_stop(&sc->malo_watchdog_timer); 1666 sc->malo_timer = 0; |
1699 /* diable interrupt. */ | 1667 /* disable interrupt. */ |
1700 malo_hal_intrset(mh, 0); 1701 /* turn off the radio. */ 1702 malo_hal_setradio(mh, 0, MHP_AUTO_PREAMBLE); 1703 1704 /* drain and release tx queues. */ 1705 for (i = 0; i < MALO_NUM_TX_QUEUES; i++) 1706 malo_tx_draintxq(sc, &sc->malo_txq[i]); 1707} 1708 | 1668 malo_hal_intrset(mh, 0); 1669 /* turn off the radio. */ 1670 malo_hal_setradio(mh, 0, MHP_AUTO_PREAMBLE); 1671 1672 /* drain and release tx queues. */ 1673 for (i = 0; i < MALO_NUM_TX_QUEUES; i++) 1674 malo_tx_draintxq(sc, &sc->malo_txq[i]); 1675} 1676 |
1709static int 1710malo_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) | 1677static void 1678malo_parent(struct ieee80211com *ic) |
1711{ | 1679{ |
1712#define MALO_IS_RUNNING(ifp) \ 1713 ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) 1714 struct malo_softc *sc = ifp->if_softc; 1715 struct ieee80211com *ic = ifp->if_l2com; 1716 struct ifreq *ifr = (struct ifreq *) data; 1717 int error = 0, startall = 0; | 1680 struct malo_softc *sc = ic->ic_softc; 1681 int startall = 0; |
1718 1719 MALO_LOCK(sc); | 1682 1683 MALO_LOCK(sc); |
1720 switch (cmd) { 1721 case SIOCSIFFLAGS: 1722 if (MALO_IS_RUNNING(ifp)) { 1723 /* 1724 * To avoid rescanning another access point, 1725 * do not call malo_init() here. Instead, 1726 * only reflect promisc mode settings. 1727 */ 1728 malo_mode_init(sc); 1729 } else if (ifp->if_flags & IFF_UP) { 1730 /* 1731 * Beware of being called during attach/detach 1732 * to reset promiscuous mode. In that case we 1733 * will still be marked UP but not RUNNING. 1734 * However trying to re-init the interface 1735 * is the wrong thing to do as we've already 1736 * torn down much of our state. There's 1737 * probably a better way to deal with this. 1738 */ 1739 if (!sc->malo_invalid) { 1740 malo_init_locked(sc); 1741 startall = 1; 1742 } 1743 } else 1744 malo_stop_locked(ifp, 1); 1745 break; 1746 case SIOCGIFMEDIA: 1747 case SIOCSIFMEDIA: 1748 error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); 1749 break; 1750 default: 1751 error = ether_ioctl(ifp, cmd, data); 1752 break; 1753 } | 1684 if (ic->ic_nrunning > 0) { 1685 /* 1686 * Beware of being called during attach/detach 1687 * to reset promiscuous mode. In that case we 1688 * will still be marked UP but not RUNNING. 1689 * However trying to re-init the interface 1690 * is the wrong thing to do as we've already 1691 * torn down much of our state. There's 1692 * probably a better way to deal with this. 1693 */ 1694 if (!sc->malo_running && !sc->malo_invalid) { 1695 malo_init(sc); 1696 startall = 1; 1697 } 1698 /* 1699 * To avoid rescanning another access point, 1700 * do not call malo_init() here. Instead, 1701 * only reflect promisc mode settings. 1702 */ 1703 malo_mode_init(sc); 1704 } else if (sc->malo_running) 1705 malo_stop(sc); |
1754 MALO_UNLOCK(sc); | 1706 MALO_UNLOCK(sc); |
1755 | |
1756 if (startall) 1757 ieee80211_start_all(ic); | 1707 if (startall) 1708 ieee80211_start_all(ic); |
1758 return error; 1759#undef MALO_IS_RUNNING | |
1760} 1761 1762/* 1763 * Callback from the 802.11 layer to update the slot time 1764 * based on the current setting. We use it to notify the 1765 * firmware of ERP changes and the f/w takes care of things 1766 * like slot time and preamble. 1767 */ 1768static void 1769malo_updateslot(struct ieee80211com *ic) 1770{ 1771 struct malo_softc *sc = ic->ic_softc; 1772 struct malo_hal *mh = sc->malo_mh; 1773 int error; 1774 1775 /* NB: can be called early; suppress needless cmds */ | 1709} 1710 1711/* 1712 * Callback from the 802.11 layer to update the slot time 1713 * based on the current setting. We use it to notify the 1714 * firmware of ERP changes and the f/w takes care of things 1715 * like slot time and preamble. 1716 */ 1717static void 1718malo_updateslot(struct ieee80211com *ic) 1719{ 1720 struct malo_softc *sc = ic->ic_softc; 1721 struct malo_hal *mh = sc->malo_mh; 1722 int error; 1723 1724 /* NB: can be called early; suppress needless cmds */ |
1776 if ((ic->ic_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) | 1725 if (!sc->malo_running) |
1777 return; 1778 1779 DPRINTF(sc, MALO_DEBUG_RESET, 1780 "%s: chan %u MHz/flags 0x%x %s slot, (ic_flags 0x%x)\n", 1781 __func__, ic->ic_curchan->ic_freq, ic->ic_curchan->ic_flags, 1782 ic->ic_flags & IEEE80211_F_SHSLOT ? "short" : "long", ic->ic_flags); 1783 1784 if (ic->ic_flags & IEEE80211_F_SHSLOT) --- 5 unchanged lines hidden (view full) --- 1790 device_printf(sc->malo_dev, "setting %s slot failed\n", 1791 ic->ic_flags & IEEE80211_F_SHSLOT ? "short" : "long"); 1792} 1793 1794static int 1795malo_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1796{ 1797 struct ieee80211com *ic = vap->iv_ic; | 1726 return; 1727 1728 DPRINTF(sc, MALO_DEBUG_RESET, 1729 "%s: chan %u MHz/flags 0x%x %s slot, (ic_flags 0x%x)\n", 1730 __func__, ic->ic_curchan->ic_freq, ic->ic_curchan->ic_flags, 1731 ic->ic_flags & IEEE80211_F_SHSLOT ? "short" : "long", ic->ic_flags); 1732 1733 if (ic->ic_flags & IEEE80211_F_SHSLOT) --- 5 unchanged lines hidden (view full) --- 1739 device_printf(sc->malo_dev, "setting %s slot failed\n", 1740 ic->ic_flags & IEEE80211_F_SHSLOT ? "short" : "long"); 1741} 1742 1743static int 1744malo_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) 1745{ 1746 struct ieee80211com *ic = vap->iv_ic; |
1798 struct malo_softc *sc = ic->ic_ifp->if_softc; | 1747 struct malo_softc *sc = ic->ic_softc; |
1799 struct malo_hal *mh = sc->malo_mh; 1800 int error; 1801 1802 DPRINTF(sc, MALO_DEBUG_STATE, "%s: %s -> %s\n", __func__, 1803 ieee80211_state_name[vap->iv_state], 1804 ieee80211_state_name[nstate]); 1805 1806 /* --- 27 unchanged lines hidden (view full) --- 1834 return 0; 1835} 1836 1837static int 1838malo_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 1839 const struct ieee80211_bpf_params *params) 1840{ 1841 struct ieee80211com *ic = ni->ni_ic; | 1748 struct malo_hal *mh = sc->malo_mh; 1749 int error; 1750 1751 DPRINTF(sc, MALO_DEBUG_STATE, "%s: %s -> %s\n", __func__, 1752 ieee80211_state_name[vap->iv_state], 1753 ieee80211_state_name[nstate]); 1754 1755 /* --- 27 unchanged lines hidden (view full) --- 1783 return 0; 1784} 1785 1786static int 1787malo_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, 1788 const struct ieee80211_bpf_params *params) 1789{ 1790 struct ieee80211com *ic = ni->ni_ic; |
1842 struct ifnet *ifp = ic->ic_ifp; 1843 struct malo_softc *sc = ifp->if_softc; | 1791 struct malo_softc *sc = ic->ic_softc; |
1844 struct malo_txbuf *bf; 1845 struct malo_txq *txq; 1846 | 1792 struct malo_txbuf *bf; 1793 struct malo_txq *txq; 1794 |
1847 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->malo_invalid) { | 1795 if (!sc->malo_running || sc->malo_invalid) { |
1848 ieee80211_free_node(ni); 1849 m_freem(m); 1850 return ENETDOWN; 1851 } 1852 1853 /* 1854 * Grab a TX buffer and associated resources. Note that we depend 1855 * on the classification by the 802.11 layer to get to the right h/w 1856 * queue. Management frames must ALWAYS go on queue 1 but we 1857 * cannot just force that here because we may receive non-mgt frames. 1858 */ 1859 txq = &sc->malo_txq[0]; 1860 bf = malo_getbuf(sc, txq); 1861 if (bf == NULL) { | 1796 ieee80211_free_node(ni); 1797 m_freem(m); 1798 return ENETDOWN; 1799 } 1800 1801 /* 1802 * Grab a TX buffer and associated resources. Note that we depend 1803 * on the classification by the 802.11 layer to get to the right h/w 1804 * queue. Management frames must ALWAYS go on queue 1 but we 1805 * cannot just force that here because we may receive non-mgt frames. 1806 */ 1807 txq = &sc->malo_txq[0]; 1808 bf = malo_getbuf(sc, txq); 1809 if (bf == NULL) { |
1862 /* XXX blocks other traffic */ 1863 ifp->if_drv_flags |= IFF_DRV_OACTIVE; | |
1864 ieee80211_free_node(ni); 1865 m_freem(m); 1866 return ENOBUFS; 1867 } 1868 1869 /* 1870 * Pass the frame to the h/w for transmission. 1871 */ 1872 if (malo_tx_start(sc, ni, bf, m) != 0) { | 1810 ieee80211_free_node(ni); 1811 m_freem(m); 1812 return ENOBUFS; 1813 } 1814 1815 /* 1816 * Pass the frame to the h/w for transmission. 1817 */ 1818 if (malo_tx_start(sc, ni, bf, m) != 0) { |
1873 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); | |
1874 bf->bf_m = NULL; 1875 bf->bf_node = NULL; 1876 MALO_TXQ_LOCK(txq); 1877 STAILQ_INSERT_HEAD(&txq->free, bf, bf_list); 1878 txq->nfree++; 1879 MALO_TXQ_UNLOCK(txq); 1880 1881 ieee80211_free_node(ni); --- 28 unchanged lines hidden (view full) --- 1910 "debug", CTLFLAG_RW, &sc->malo_debug, 0, 1911 "control debugging printfs"); 1912#endif 1913} 1914 1915static void 1916malo_announce(struct malo_softc *sc) 1917{ | 1819 bf->bf_m = NULL; 1820 bf->bf_node = NULL; 1821 MALO_TXQ_LOCK(txq); 1822 STAILQ_INSERT_HEAD(&txq->free, bf, bf_list); 1823 txq->nfree++; 1824 MALO_TXQ_UNLOCK(txq); 1825 1826 ieee80211_free_node(ni); --- 28 unchanged lines hidden (view full) --- 1855 "debug", CTLFLAG_RW, &sc->malo_debug, 0, 1856 "control debugging printfs"); 1857#endif 1858} 1859 1860static void 1861malo_announce(struct malo_softc *sc) 1862{ |
1918 struct ifnet *ifp = sc->malo_ifp; | |
1919 | 1863 |
1920 if_printf(ifp, "versions [hw %d fw %d.%d.%d.%d] (regioncode %d)\n", | 1864 device_printf(sc->malo_dev, 1865 "versions [hw %d fw %d.%d.%d.%d] (regioncode %d)\n", |
1921 sc->malo_hwspecs.hwversion, 1922 (sc->malo_hwspecs.fw_releasenum >> 24) & 0xff, 1923 (sc->malo_hwspecs.fw_releasenum >> 16) & 0xff, 1924 (sc->malo_hwspecs.fw_releasenum >> 8) & 0xff, 1925 (sc->malo_hwspecs.fw_releasenum >> 0) & 0xff, 1926 sc->malo_hwspecs.regioncode); 1927 1928 if (bootverbose || malo_rxbuf != MALO_RXBUF) | 1866 sc->malo_hwspecs.hwversion, 1867 (sc->malo_hwspecs.fw_releasenum >> 24) & 0xff, 1868 (sc->malo_hwspecs.fw_releasenum >> 16) & 0xff, 1869 (sc->malo_hwspecs.fw_releasenum >> 8) & 0xff, 1870 (sc->malo_hwspecs.fw_releasenum >> 0) & 0xff, 1871 sc->malo_hwspecs.regioncode); 1872 1873 if (bootverbose || malo_rxbuf != MALO_RXBUF) |
1929 if_printf(ifp, "using %u rx buffers\n", malo_rxbuf); | 1874 device_printf(sc->malo_dev, 1875 "using %u rx buffers\n", malo_rxbuf); |
1930 if (bootverbose || malo_txbuf != MALO_TXBUF) | 1876 if (bootverbose || malo_txbuf != MALO_TXBUF) |
1931 if_printf(ifp, "using %u tx buffers\n", malo_txbuf); | 1877 device_printf(sc->malo_dev, 1878 "using %u tx buffers\n", malo_txbuf); |
1932} 1933 1934/* 1935 * Convert net80211 channel to a HAL channel. 1936 */ 1937static void 1938malo_mapchan(struct malo_hal_channel *hc, const struct ieee80211_channel *chan) 1939{ --- 44 unchanged lines hidden (view full) --- 1984 malo_hal_intrset(mh, sc->malo_imask); 1985 1986 return 0; 1987} 1988 1989static void 1990malo_scan_start(struct ieee80211com *ic) 1991{ | 1879} 1880 1881/* 1882 * Convert net80211 channel to a HAL channel. 1883 */ 1884static void 1885malo_mapchan(struct malo_hal_channel *hc, const struct ieee80211_channel *chan) 1886{ --- 44 unchanged lines hidden (view full) --- 1931 malo_hal_intrset(mh, sc->malo_imask); 1932 1933 return 0; 1934} 1935 1936static void 1937malo_scan_start(struct ieee80211com *ic) 1938{ |
1992 struct ifnet *ifp = ic->ic_ifp; 1993 struct malo_softc *sc = ifp->if_softc; | 1939 struct malo_softc *sc = ic->ic_softc; |
1994 1995 DPRINTF(sc, MALO_DEBUG_STATE, "%s\n", __func__); 1996} 1997 1998static void 1999malo_scan_end(struct ieee80211com *ic) 2000{ | 1940 1941 DPRINTF(sc, MALO_DEBUG_STATE, "%s\n", __func__); 1942} 1943 1944static void 1945malo_scan_end(struct ieee80211com *ic) 1946{ |
2001 struct ifnet *ifp = ic->ic_ifp; 2002 struct malo_softc *sc = ifp->if_softc; | 1947 struct malo_softc *sc = ic->ic_softc; |
2003 2004 DPRINTF(sc, MALO_DEBUG_STATE, "%s\n", __func__); 2005} 2006 2007static void 2008malo_set_channel(struct ieee80211com *ic) 2009{ | 1948 1949 DPRINTF(sc, MALO_DEBUG_STATE, "%s\n", __func__); 1950} 1951 1952static void 1953malo_set_channel(struct ieee80211com *ic) 1954{ |
2010 struct ifnet *ifp = ic->ic_ifp; 2011 struct malo_softc *sc = ifp->if_softc; | 1955 struct malo_softc *sc = ic->ic_softc; |
2012 2013 (void) malo_chan_set(sc, ic->ic_curchan); 2014} 2015 2016static void 2017malo_rx_proc(void *arg, int npending) 2018{ 2019#define IEEE80211_DIR_DSTODS(wh) \ 2020 ((((const struct ieee80211_frame *)wh)->i_fc[1] & \ 2021 IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS) 2022 struct malo_softc *sc = arg; | 1956 1957 (void) malo_chan_set(sc, ic->ic_curchan); 1958} 1959 1960static void 1961malo_rx_proc(void *arg, int npending) 1962{ 1963#define IEEE80211_DIR_DSTODS(wh) \ 1964 ((((const struct ieee80211_frame *)wh)->i_fc[1] & \ 1965 IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS) 1966 struct malo_softc *sc = arg; |
2023 struct ifnet *ifp = sc->malo_ifp; 2024 struct ieee80211com *ic = ifp->if_l2com; | 1967 struct ieee80211com *ic = &sc->malo_ic; |
2025 struct malo_rxbuf *bf; 2026 struct malo_rxdesc *ds; 2027 struct mbuf *m, *mnew; 2028 struct ieee80211_qosframe *wh; 2029 struct ieee80211_qosframe_addr4 *wh4; 2030 struct ieee80211_node *ni; 2031 int off, len, hdrlen, pktlen, rssi, ntodo; 2032 uint8_t *data, status; --- 40 unchanged lines hidden (view full) --- 2073 readptr = le32toh(ds->physnext); 2074 2075#ifdef MALO_DEBUG 2076 if (sc->malo_debug & MALO_DEBUG_RECV_DESC) 2077 malo_printrxbuf(bf, 0); 2078#endif 2079 status = ds->status; 2080 if (status & MALO_RXD_STATUS_DECRYPT_ERR_MASK) { | 1968 struct malo_rxbuf *bf; 1969 struct malo_rxdesc *ds; 1970 struct mbuf *m, *mnew; 1971 struct ieee80211_qosframe *wh; 1972 struct ieee80211_qosframe_addr4 *wh4; 1973 struct ieee80211_node *ni; 1974 int off, len, hdrlen, pktlen, rssi, ntodo; 1975 uint8_t *data, status; --- 40 unchanged lines hidden (view full) --- 2016 readptr = le32toh(ds->physnext); 2017 2018#ifdef MALO_DEBUG 2019 if (sc->malo_debug & MALO_DEBUG_RECV_DESC) 2020 malo_printrxbuf(bf, 0); 2021#endif 2022 status = ds->status; 2023 if (status & MALO_RXD_STATUS_DECRYPT_ERR_MASK) { |
2081 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); | 2024 counter_u64_add(ic->ic_ierrors, 1); |
2082 goto rx_next; 2083 } 2084 /* 2085 * Sync the data buffer. 2086 */ 2087 len = le16toh(ds->pktlen); 2088 bus_dmamap_sync(sc->malo_dmat, bf->bf_dmamap, 2089 BUS_DMASYNC_POSTREAD); --- 22 unchanged lines hidden (view full) --- 2112 * the front. Hence there's no need to vet the packet length. 2113 * If the frame in fact is too small it should be discarded 2114 * at the net80211 layer. 2115 */ 2116 2117 /* XXX don't need mbuf, just dma buffer */ 2118 mnew = malo_getrxmbuf(sc, bf); 2119 if (mnew == NULL) { | 2025 goto rx_next; 2026 } 2027 /* 2028 * Sync the data buffer. 2029 */ 2030 len = le16toh(ds->pktlen); 2031 bus_dmamap_sync(sc->malo_dmat, bf->bf_dmamap, 2032 BUS_DMASYNC_POSTREAD); --- 22 unchanged lines hidden (view full) --- 2055 * the front. Hence there's no need to vet the packet length. 2056 * If the frame in fact is too small it should be discarded 2057 * at the net80211 layer. 2058 */ 2059 2060 /* XXX don't need mbuf, just dma buffer */ 2061 mnew = malo_getrxmbuf(sc, bf); 2062 if (mnew == NULL) { |
2120 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); | 2063 counter_u64_add(ic->ic_ierrors, 1); |
2121 goto rx_next; 2122 } 2123 /* 2124 * Attach the dma buffer to the mbuf; malo_rxbuf_init will 2125 * re-setup the rx descriptor using the replacement dma 2126 * buffer we just installed above. 2127 */ 2128 bf->bf_m = mnew; 2129 m->m_data += off - hdrlen; 2130 m->m_pkthdr.len = m->m_len = pktlen; | 2064 goto rx_next; 2065 } 2066 /* 2067 * Attach the dma buffer to the mbuf; malo_rxbuf_init will 2068 * re-setup the rx descriptor using the replacement dma 2069 * buffer we just installed above. 2070 */ 2071 bf->bf_m = mnew; 2072 m->m_data += off - hdrlen; 2073 m->m_pkthdr.len = m->m_len = pktlen; |
2131 m->m_pkthdr.rcvif = ifp; | |
2132 2133 /* 2134 * Piece 802.11 header together. 2135 */ 2136 wh = mtod(m, struct ieee80211_qosframe *); 2137 /* NB: don't need to do this sometimes but ... */ 2138 /* XXX special case so we can memcpy after m_devget? */ 2139 ovbcopy(data + sizeof(uint16_t), wh, hdrlen); --- 13 unchanged lines hidden (view full) --- 2153 sc->malo_rx_th.wr_antnoise = ds->nf; 2154 } 2155#ifdef MALO_DEBUG 2156 if (IFF_DUMPPKTS_RECV(sc, wh)) { 2157 ieee80211_dump_pkt(ic, mtod(m, caddr_t), 2158 len, ds->rate, rssi); 2159 } 2160#endif | 2074 2075 /* 2076 * Piece 802.11 header together. 2077 */ 2078 wh = mtod(m, struct ieee80211_qosframe *); 2079 /* NB: don't need to do this sometimes but ... */ 2080 /* XXX special case so we can memcpy after m_devget? */ 2081 ovbcopy(data + sizeof(uint16_t), wh, hdrlen); --- 13 unchanged lines hidden (view full) --- 2095 sc->malo_rx_th.wr_antnoise = ds->nf; 2096 } 2097#ifdef MALO_DEBUG 2098 if (IFF_DUMPPKTS_RECV(sc, wh)) { 2099 ieee80211_dump_pkt(ic, mtod(m, caddr_t), 2100 len, ds->rate, rssi); 2101 } 2102#endif |
2161 if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); 2162 | |
2163 /* dispatch */ 2164 ni = ieee80211_find_rxnode(ic, 2165 (struct ieee80211_frame_min *)wh); 2166 if (ni != NULL) { 2167 (void) ieee80211_input(ni, m, rssi, ds->nf); 2168 ieee80211_free_node(ni); 2169 } else 2170 (void) ieee80211_input_all(ic, m, rssi, ds->nf); 2171rx_next: 2172 /* NB: ignore ENOMEM so we process more descriptors */ 2173 (void) malo_rxbuf_init(sc, bf); 2174 bf = STAILQ_NEXT(bf, bf_list); 2175 } 2176 2177 malo_bar0_write4(sc, sc->malo_hwspecs.rxdesc_read, readptr); 2178 sc->malo_rxnext = bf; 2179 | 2103 /* dispatch */ 2104 ni = ieee80211_find_rxnode(ic, 2105 (struct ieee80211_frame_min *)wh); 2106 if (ni != NULL) { 2107 (void) ieee80211_input(ni, m, rssi, ds->nf); 2108 ieee80211_free_node(ni); 2109 } else 2110 (void) ieee80211_input_all(ic, m, rssi, ds->nf); 2111rx_next: 2112 /* NB: ignore ENOMEM so we process more descriptors */ 2113 (void) malo_rxbuf_init(sc, bf); 2114 bf = STAILQ_NEXT(bf, bf_list); 2115 } 2116 2117 malo_bar0_write4(sc, sc->malo_hwspecs.rxdesc_read, readptr); 2118 sc->malo_rxnext = bf; 2119 |
2180 if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 && 2181 !IFQ_IS_EMPTY(&ifp->if_snd)) 2182 malo_start(ifp); | 2120 if (mbufq_first(&sc->malo_snd) != NULL) 2121 malo_start(sc); |
2183#undef IEEE80211_DIR_DSTODS 2184} 2185 | 2122#undef IEEE80211_DIR_DSTODS 2123} 2124 |
2186static void 2187malo_stop(struct ifnet *ifp, int disable) 2188{ 2189 struct malo_softc *sc = ifp->if_softc; 2190 2191 MALO_LOCK(sc); 2192 malo_stop_locked(ifp, disable); 2193 MALO_UNLOCK(sc); 2194} 2195 | |
2196/* 2197 * Reclaim all tx queue resources. 2198 */ 2199static void 2200malo_tx_cleanup(struct malo_softc *sc) 2201{ 2202 int i; 2203 2204 for (i = 0; i < MALO_NUM_TX_QUEUES; i++) 2205 malo_tx_cleanupq(sc, &sc->malo_txq[i]); 2206} 2207 2208int 2209malo_detach(struct malo_softc *sc) 2210{ | 2125/* 2126 * Reclaim all tx queue resources. 2127 */ 2128static void 2129malo_tx_cleanup(struct malo_softc *sc) 2130{ 2131 int i; 2132 2133 for (i = 0; i < MALO_NUM_TX_QUEUES; i++) 2134 malo_tx_cleanupq(sc, &sc->malo_txq[i]); 2135} 2136 2137int 2138malo_detach(struct malo_softc *sc) 2139{ |
2211 struct ifnet *ifp = sc->malo_ifp; 2212 struct ieee80211com *ic = ifp->if_l2com; | 2140 struct ieee80211com *ic = &sc->malo_ic; |
2213 | 2141 |
2214 DPRINTF(sc, MALO_DEBUG_ANY, "%s: if_flags %x\n", 2215 __func__, ifp->if_flags); | 2142 malo_stop(sc); |
2216 | 2143 |
2217 malo_stop(ifp, 1); 2218 | |
2219 if (sc->malo_tq != NULL) { 2220 taskqueue_drain(sc->malo_tq, &sc->malo_rxtask); 2221 taskqueue_drain(sc->malo_tq, &sc->malo_txtask); 2222 taskqueue_free(sc->malo_tq); 2223 sc->malo_tq = NULL; 2224 } 2225 2226 /* --- 8 unchanged lines hidden (view full) --- 2235 * it last 2236 * Other than that, it's straightforward... 2237 */ 2238 ieee80211_ifdetach(ic); 2239 callout_drain(&sc->malo_watchdog_timer); 2240 malo_dma_cleanup(sc); 2241 malo_tx_cleanup(sc); 2242 malo_hal_detach(sc->malo_mh); | 2144 if (sc->malo_tq != NULL) { 2145 taskqueue_drain(sc->malo_tq, &sc->malo_rxtask); 2146 taskqueue_drain(sc->malo_tq, &sc->malo_txtask); 2147 taskqueue_free(sc->malo_tq); 2148 sc->malo_tq = NULL; 2149 } 2150 2151 /* --- 8 unchanged lines hidden (view full) --- 2160 * it last 2161 * Other than that, it's straightforward... 2162 */ 2163 ieee80211_ifdetach(ic); 2164 callout_drain(&sc->malo_watchdog_timer); 2165 malo_dma_cleanup(sc); 2166 malo_tx_cleanup(sc); 2167 malo_hal_detach(sc->malo_mh); |
2243 if_free(ifp); 2244 | 2168 mbufq_drain(&sc->malo_snd); |
2245 MALO_LOCK_DESTROY(sc); 2246 2247 return 0; 2248} 2249 2250void 2251malo_shutdown(struct malo_softc *sc) 2252{ | 2169 MALO_LOCK_DESTROY(sc); 2170 2171 return 0; 2172} 2173 2174void 2175malo_shutdown(struct malo_softc *sc) 2176{ |
2253 malo_stop(sc->malo_ifp, 1); | 2177 2178 malo_stop(sc); |
2254} 2255 2256void 2257malo_suspend(struct malo_softc *sc) 2258{ | 2179} 2180 2181void 2182malo_suspend(struct malo_softc *sc) 2183{ |
2259 struct ifnet *ifp = sc->malo_ifp; | |
2260 | 2184 |
2261 DPRINTF(sc, MALO_DEBUG_ANY, "%s: if_flags %x\n", 2262 __func__, ifp->if_flags); 2263 2264 malo_stop(ifp, 1); | 2185 malo_stop(sc); |
2265} 2266 2267void 2268malo_resume(struct malo_softc *sc) 2269{ | 2186} 2187 2188void 2189malo_resume(struct malo_softc *sc) 2190{ |
2270 struct ifnet *ifp = sc->malo_ifp; | |
2271 | 2191 |
2272 DPRINTF(sc, MALO_DEBUG_ANY, "%s: if_flags %x\n", 2273 __func__, ifp->if_flags); 2274 2275 if (ifp->if_flags & IFF_UP) | 2192 if (sc->malo_ic.ic_nrunning > 0) |
2276 malo_init(sc); 2277} | 2193 malo_init(sc); 2194} |