📄 if_ath.c.svn-base
字号:
ath_hal_gpioset(ah, sc->sc_ledpin, !sc->sc_ledon); } /* NB: ether_setup is done by bus-specific code */ dev->open = ath_init; dev->stop = ath_stop; dev->hard_start_xmit = ath_hardstart; dev->tx_timeout = ath_tx_timeout; dev->watchdog_timeo = 5 * HZ; dev->set_multicast_list = ath_mode_init; dev->do_ioctl = ath_ioctl; dev->get_stats = ath_getstats; dev->set_mac_address = ath_set_mac_address; dev->change_mtu = ath_change_mtu; dev->tx_queue_len = ATH_TXBUF - ATH_TXBUF_MGT_RESERVED;#ifdef USE_HEADERLEN_RESV dev->hard_header_len += sizeof(struct ieee80211_qosframe) + sizeof(struct llc) + IEEE80211_ADDR_LEN + IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN;#ifdef ATH_SUPERG_FF dev->hard_header_len += ATH_FF_MAX_HDR;#endif#endif dev->type = ARPHRD_IEEE80211; ic->ic_dev = dev; ic->ic_mgtstart = ath_mgtstart; ic->ic_init = ath_init; ic->ic_reset = ath_reset; ic->ic_newassoc = ath_newassoc; ic->ic_updateslot = ath_updateslot; atomic_set(&ic->ic_node_counter, 0); ic->ic_debug = 0; sc->sc_debug = (ath_debug & ~ATH_DEBUG_GLOBAL); sc->sc_default_ieee80211_debug = ieee80211_debug; ic->ic_wme.wme_update = ath_wme_update; ic->ic_uapsd_flush = ath_uapsd_flush; /* XXX not right but it's not used anywhere important */ ic->ic_phytype = IEEE80211_T_OFDM; ic->ic_opmode = IEEE80211_M_STA; sc->sc_opmode = HAL_M_STA; /* * Set the Atheros Advanced Capabilities from station config before * starting 802.11 state machine. Currently, set only fast-frames * capability. */ ic->ic_ath_cap = 0; sc->sc_fftxqmin = ATH_FF_TXQMIN;#ifdef ATH_SUPERG_FF ic->ic_ath_cap |= (ath_hal_fastframesupported(ah) ? IEEE80211_ATHC_FF : 0);#endif ic->ic_ath_cap |= (ath_hal_burstsupported(ah) ? IEEE80211_ATHC_BURST : 0);#ifdef ATH_SUPERG_COMP ic->ic_ath_cap |= (ath_hal_compressionsupported(ah) ? IEEE80211_ATHC_COMP : 0);#endif#ifdef ATH_SUPERG_DYNTURBO ic->ic_ath_cap |= (ath_hal_turboagsupported(ah, ath_countrycode) ? (IEEE80211_ATHC_TURBOP | IEEE80211_ATHC_AR) : 0);#endif#ifdef ATH_SUPERG_XR ic->ic_ath_cap |= (ath_hal_xrsupported(ah) ? IEEE80211_ATHC_XR : 0);#endif ic->ic_caps |= IEEE80211_C_IBSS | /* ibss, nee adhoc, mode */ IEEE80211_C_HOSTAP | /* hostap mode */ IEEE80211_C_MONITOR | /* monitor mode */ IEEE80211_C_AHDEMO | /* adhoc demo mode */ IEEE80211_C_SHPREAMBLE | /* short preamble supported */ IEEE80211_C_SHSLOT | /* short slot time supported */ IEEE80211_C_WPA | /* capable of WPA1+WPA2 */ IEEE80211_C_BGSCAN; /* capable of bg scanning */ /* Query the HAL to figure out HW crypto. support. */ if (ath_hal_ciphersupported(ah, HAL_CIPHER_WEP)) ic->ic_caps |= IEEE80211_C_WEP; if (ath_hal_ciphersupported(ah, HAL_CIPHER_AES_OCB)) ic->ic_caps |= IEEE80211_C_AES; if (ath_hal_ciphersupported(ah, HAL_CIPHER_AES_CCM)) ic->ic_caps |= IEEE80211_C_AES_CCM; if (ath_hal_ciphersupported(ah, HAL_CIPHER_CKIP)) ic->ic_caps |= IEEE80211_C_CKIP; if (ath_hal_ciphersupported(ah, HAL_CIPHER_TKIP)) { ic->ic_caps |= IEEE80211_C_TKIP; /* * Check if h/w does the MIC and/or whether the * separate key cache entries are required to * handle both tx+rx MIC keys. */ if (ath_hal_ciphersupported(ah, HAL_CIPHER_MIC)) { ic->ic_caps |= IEEE80211_C_TKIPMIC; /* * Check if h/w does MIC correctly when * WMM is turned on. */ if (ath_hal_wmetkipmic(ah)) ic->ic_caps |= IEEE80211_C_WME_TKIPMIC; } /* * If the h/w supports storing tx+rx MIC keys * in one cache slot automatically enable use. */ if (ath_hal_hastkipsplit(ah) || !ath_hal_settkipsplit(ah, AH_FALSE)) sc->sc_splitmic = 1; } sc->sc_hasclrkey = ath_hal_ciphersupported(ah, HAL_CIPHER_CLR); /* If hardware has multicast key search capabilities, disable it. It * is not currently supported by the driver. It seems we can properly * enable things in the HAL, however multicast packets are still * decoded using keys located at index 0..3, so current code is no * longer working */ if (ath_hal_hasmcastkeysearch(ah)) { ath_hal_setmcastkeysearch(ah, AH_FALSE); } sc->sc_mcastkey = ath_hal_getmcastkeysearch(ah); /* * Mark key cache slots associated with global keys * as in use. If we knew TKIP was not to be used we * could leave the +32, +64, and +32+64 slots free. */ for (i = 0; i < IEEE80211_WEP_NKID; i++) { setbit(sc->sc_keymap, i); setbit(sc->sc_keymap, i+64); if (sc->sc_splitmic) { setbit(sc->sc_keymap, i+32); setbit(sc->sc_keymap, i+32+64); } } /* * Default 11.h to start enabled. */ ic->ic_flags |= IEEE80211_F_DOTH; /* * Check for misc other capabilities. */ if (ath_hal_hasbursting(ah)) ic->ic_caps |= IEEE80211_C_BURST; sc->sc_hasbmask = ath_hal_hasbssidmask(ah); sc->sc_hastsfadd = ath_hal_hastsfadjust(ah); /* * Indicate we need the 802.11 header padded to a * 32-bit boundary for 4-address and QoS frames. */ ic->ic_flags |= IEEE80211_F_DATAPAD; /* Query the HAL about antenna support * Enable RX fast diversity if HAL has support. */ sc->sc_hasdiversity = sc->sc_diversity = !!ath_hal_hasdiversity(ah); ath_hal_setdiversity(ah, sc->sc_diversity); sc->sc_rxantenna = ath_hal_getdefantenna(ah); sc->sc_txantenna = 0; /* default to auto-selection */ /* * Not all chips have the VEOL support we want to * use with IBSS beacons; check here for it. */ sc->sc_hasveol = ath_hal_hasveol(ah); sc->sc_txintrperiod = ATH_TXQ_INTR_PERIOD; /* get mac address from hardware */ ath_hal_getmac(ah, ic->ic_myaddr); if (sc->sc_hasbmask) { ath_hal_getbssidmask(ah, sc->sc_bssidmask); ATH_SET_VAP_BSSID_MASK(sc->sc_bssidmask); ath_hal_setbssidmask(ah, sc->sc_bssidmask); } IEEE80211_ADDR_COPY(dev->dev_addr, ic->ic_myaddr); /* call MI attach routine. */ ieee80211_ifattach(ic); /* override default methods */ ic->ic_node_alloc = ath_node_alloc; sc->sc_node_free = ic->ic_node_free; ic->ic_node_free = ath_node_free; sc->sc_node_cleanup = ic->ic_node_cleanup; ic->ic_node_cleanup = ath_node_cleanup; ic->ic_node_getrssi = ath_node_getrssi;#ifdef ATH_SUPERG_XR ic->ic_node_move_data = ath_node_move_data;#endif sc->sc_recv_mgmt = ic->ic_recv_mgmt; ic->ic_recv_mgmt = ath_recv_mgmt; ic->ic_vap_create = ath_vap_create; ic->ic_vap_delete = ath_vap_delete; ic->ic_test_radar = ath_test_radar; ic->ic_dump_hal_map = ath_dump_hal_map; ic->ic_set_dfs_testmode = ath_set_dfs_testmode; ic->ic_get_dfs_testmode = ath_get_dfs_testmode; ic->ic_set_txcont = ath_set_txcont; ic->ic_get_txcont = ath_get_txcont; ic->ic_set_txcont_power = ath_set_txcont_power; ic->ic_get_txcont_power = ath_get_txcont_power; ic->ic_set_txcont_rate = ath_set_txcont_rate; ic->ic_get_txcont_rate = ath_get_txcont_rate; ic->ic_scan_start = ath_scan_start; ic->ic_scan_end = ath_scan_end; ic->ic_set_channel = ath_set_channel;#ifdef ATH_REVERSE_ENGINEERING ic->ic_read_register = ath_read_register; ic->ic_write_register = ath_write_register; ic->ic_registers_dump = ath_registers_dump; ic->ic_registers_dump_delta = ath_registers_dump_delta; ic->ic_registers_mark = ath_registers_mark;#endif /* #ifdef ATH_REVERSE_ENGINEERING */ ic->ic_debug_ath_iwpriv = ath_debug_iwpriv; ic->ic_set_coverageclass = ath_set_coverageclass; ic->ic_mhz2ieee = ath_mhz2ieee; /* DFS radar avoidance channel availability check time (in seconds) */ ic->ic_set_dfs_cac_time = ath_set_dfs_cac_time; ic->ic_get_dfs_cac_time = ath_get_dfs_cac_time; /* DFS radar avoidance channel use delay */ ic->ic_set_dfs_excl_period = ath_set_dfs_excl_period; ic->ic_get_dfs_excl_period = ath_get_dfs_excl_period; if (register_netdev(dev)) { EPRINTF(sc, "Unable to register device\n"); goto bad3; } /* * Attach dynamic MIB vars and announce support * now that we have a device name with unit number. */ ath_dynamic_sysctl_register(sc); ieee80211_announce(ic); ath_announce(dev);#ifdef ATH_TX99_DIAG IPRINTF(sc, "TX99 support enabled\n");#endif sc->sc_invalid = 0; if (autocreate) { if (!strcmp(autocreate, "none") || !strlen(autocreate)) autocreatemode = -1; else if (!strcmp(autocreate, "sta")) autocreatemode = IEEE80211_M_STA; else if (!strcmp(autocreate, "ap")) autocreatemode = IEEE80211_M_HOSTAP; else if (!strcmp(autocreate, "adhoc")) autocreatemode = IEEE80211_M_IBSS; else if (!strcmp(autocreate, "ahdemo")) autocreatemode = IEEE80211_M_AHDEMO; else if (!strcmp(autocreate, "wds")) autocreatemode = IEEE80211_M_WDS; else if (!strcmp(autocreate, "monitor")) autocreatemode = IEEE80211_M_MONITOR; else { DPRINTF(sc, ATH_DEBUG_ANY, "Unknown autocreate mode: %s\n", autocreate); autocreatemode = -1; } } if (autocreatemode != -1) { rtnl_lock(); vap = ieee80211_create_vap(ic, "ath%d", dev, autocreatemode, 0); rtnl_unlock(); if (vap == NULL) EPRINTF(sc, "Autocreation of %s VAP failed.", autocreate); } sc->sc_rp_lasttsf = 0; sc->sc_last_tsf = 0; return 0;bad3: ieee80211_ifdetach(ic); ieee80211_rate_detach(sc->sc_rc);bad2: ath_tx_cleanup(sc); ath_desc_free(sc);bad: if (ah) _ath_hal_detach(ah); ATH_TXBUF_LOCK_DESTROY(sc); ATH_RXBUF_LOCK_DESTROY(sc); ATH_BBUF_LOCK_DESTROY(sc); ATH_GBUF_LOCK_DESTROY(sc); ATH_LOCK_DESTROY(sc); ATH_HAL_LOCK_DESTROY(sc); sc->sc_invalid = 1; return error;}intath_detach(struct net_device *dev){ struct ath_softc *sc = netdev_priv(dev); struct ath_hal *ah = sc->sc_ah; HAL_INT tmp; DPRINTF(sc, ATH_DEBUG_ANY, "flags=%x\n", dev->flags); ath_stop(dev); ath_hal_setpower(sc->sc_ah, HAL_PM_AWAKE, AH_TRUE); /* Flush the radar task if it's scheduled */ if (sc->sc_dfs_cac) flush_scheduled_work(); sc->sc_invalid = 1; /* * NB: the order of these is important: * o call the 802.11 layer before detaching the HAL to * ensure callbacks into the driver to delete global * key cache entries can be handled * o reclaim the tx queue data structures after calling * the 802.11 layer as we'll get called back to reclaim * node state and potentially want to use them * o to cleanup the tx queues the HAL is called, so detach * it last * Other than that, it's straightforward... */ ieee80211_ifdetach(&sc->sc_ic); ath_hal_intrset(ah, 0); /* disable further intr's */ ath_hal_getisr(ah, &tmp); /* clear ISR */ if (dev->irq) { free_irq(dev->irq, dev); dev->irq = 0; }#ifdef ATH_TX99_DIAG if (sc->sc_tx99 != NULL) sc->sc_tx99->detach(sc->sc_tx99);#endif ieee80211_rate_detach(sc->sc_rc); ath_desc_free(sc); ath_tx_cleanup(sc); _ath_hal_detach(ah); kfree(sc->sc_bslot); sc->sc_bslot = NULL; /* free radar pulse stuff */ ath_rp_done(sc); ath_dynamic_sysctl_unregister(sc); ATH_LOCK_DESTROY(sc); ATH_TXBUF_LOCK_DESTROY(sc); ATH_RXBUF_LOCK_DESTROY(sc); ATH_BBUF_LOCK_DESTROY(sc); ATH_GBUF_LOCK_DESTROY(sc); ATH_HAL_LOCK_DESTROY(sc); dev->stop = NULL; /* prevent calling ath_stop again */ unregister_netdev(dev); return 0;}static struct ieee80211vap *ath_vap_create(struct ieee80211com *ic, const char *name, int opmode, int flags, struct net_device *mdev){ struct ath_softc *sc = netdev_priv(ic->ic_dev); struct ath_hal *ah = sc->sc_ah; struct net_device *dev; struct ath_vap *avp; struct ieee80211vap *vap; int ic_opmode; if (ic->ic_dev->flags & IFF_RUNNING) { /* needs to disable hardware too */ ath_hal_intrset(ah, 0); /* disable interrupts */ ath_draintxq(sc); /* stop xmit side */ ath_stoprecv(sc); /* stop recv side */ } /* XXX ic unlocked and race against add */ switch (opmode) { case IEEE80211_M_STA: /* ap+sta for repeater application */ if (sc->sc_nstavaps != 0) /* only one sta regardless */ return NULL; /* If we already have an AP VAP, we can still add a station VAP * but we must not attempt to re-use the hardware beacon timers * since the AP is already using them, and we must stay in AP * opmode. */ if (sc->sc_nvaps != 0) { flags |= IEEE80211_USE_SW_BEACON_TIMERS; sc->sc_nostabeacons = 1; ic_opmode = IEEE80211_M_HOSTAP; /* Run with chip in AP mode */ } else { ic_opmode = opmode; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -