예제 #1
0
wmi_buf_t
wmi_buf_alloc(wmi_unified_t wmi_handle, int len)
{
    wmi_buf_t wmi_buf;
    /* NOTE: For now the wbuf type is used as WBUF_TX_CTL
     * But this need to be changed appropriately to reserve
     * proper headroom for wmi_buffers
     */
    wmi_buf = wbuf_alloc(wmi_handle->osdev, WBUF_TX_CTL, len);
    if( NULL == wmi_buf )
    {
        /* wbuf_alloc returns NULL if the internel pool in wmi_handle->osdev
         * is empty
         */
        return NULL;
    }

    
    /* Clear the wmi buffer */
    OS_MEMZERO(wbuf_header(wmi_buf), len);
	
    /*
     * Set the length of the buffer to match the allocation size.
     */
    wbuf_set_pktlen(wmi_buf, len);
    return wmi_buf;
}
예제 #2
0
/* TODO: only support linux for now */
void wlan_offchan_send_data_frame(struct ieee80211_node *ni, struct net_device *netdev)
{
#if defined(LINUX) || defined(__linux__)
    struct ieee80211vap *vap = ni->ni_vap;
    struct ieee80211com *ic = ni->ni_ic;
    wbuf_t wbuf;
    struct ieee80211_qosframe *qwh;
    const u_int8_t dst[6] = {0x00, 0x02, 0x03, 0x04, 0x05, 0x06};
    struct sk_buff *skb;

    wbuf = wbuf_alloc(ic->ic_osdev, WBUF_TX_DATA, 1000);
    if (wbuf == NULL)
    {
        return ;
    }
    ieee80211_prepare_qosnulldata(ni, wbuf, WME_AC_VO);

    qwh = (struct ieee80211_qosframe *)wbuf_header(wbuf);
    ieee80211_send_setup(vap, ni, (struct ieee80211_frame *)qwh,
        IEEE80211_FC0_TYPE_DATA,
        vap->iv_myaddr, /* SA */
        dst,            /* DA */
        ni->ni_bssid);

    wbuf_set_pktlen(wbuf, 1000);
    /* force with NONPAUSE_TID */
    wbuf_set_tid(wbuf, OFFCHAN_EXT_TID_NONPAUSE);

    skb = (struct sk_buff *)wbuf;
    skb->dev = netdev;

    dev_queue_xmit(skb);
#endif
}
예제 #3
0
wbuf_t
ath_net80211_uapsd_allocqosnullframe(ieee80211_handle_t ieee)
{
    wbuf_t wbuf;
    struct ieee80211com *ic = NET80211_HANDLE(ieee);

    wbuf = wbuf_alloc(ic->ic_osdev, WBUF_TX_MGMT, sizeof(struct ieee80211_qosframe));
    if (wbuf != NULL)
        wbuf_push(wbuf, sizeof(struct ieee80211_qosframe));

    return wbuf;
}
예제 #4
0
/*zhaoyang1 add start for interfere ap*/
wbuf_t
autelan_beacon_alloc(struct ieee80211_node *ni,
                       struct ieee80211_beacon_offsets *bo, u_int8_t *ap_mac, u_int8_t chan)
{
    struct ieee80211vap *vap = ni->ni_vap;
    struct ieee80211com *ic = ni->ni_ic;
    wbuf_t wbuf;
    struct ieee80211_frame *wh;
    u_int8_t *frm;
	
    wbuf = wbuf_alloc(ic->ic_osdev, WBUF_TX_BEACON, MAX_TX_RX_PACKET_SIZE);
    if (wbuf == NULL)
        return NULL;

    wh = (struct ieee80211_frame *)wbuf_header(wbuf);
    wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
        IEEE80211_FC0_SUBTYPE_BEACON;
    wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
    *(u_int16_t *)wh->i_dur = 0;
    IEEE80211_ADDR_COPY(wh->i_addr1, IEEE80211_GET_BCAST_ADDR(ic));
    IEEE80211_ADDR_COPY(wh->i_addr2, ap_mac);
    IEEE80211_ADDR_COPY(wh->i_addr3, ap_mac);
    *(u_int16_t *)wh->i_seq = 0;

    frm = (u_int8_t *)&wh[1];
    frm = autelan_beacon_init(ni, bo, frm, chan);
    if (ieee80211_vap_copy_beacon_is_set(vap)) {
        store_beacon_frame(vap, (u_int8_t *)wh, (frm - (u_int8_t *)wh));
    }

    wbuf_set_pktlen(wbuf, (frm - (u_int8_t *) wbuf_header(wbuf)));
    wbuf_set_node(wbuf, ieee80211_ref_node(ni));

    IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MLME, vap->iv_myaddr,
                       "%s \n", __func__);
    return wbuf;
}
예제 #5
0
/*
 * Send a probe response frame.
 * NB: for probe response, the node may not represent the peer STA.
 * We could use BSS node to reduce the memory usage from temporary node.
 */
int
ieee80211_send_proberesp(struct ieee80211_node *ni, u_int8_t *macaddr,
                         const void *optie, const size_t  optielen)
{
    struct ieee80211vap *vap = ni->ni_vap;
    struct ieee80211com *ic = ni->ni_ic;
    struct ieee80211_rsnparms *rsn = &vap->iv_rsn;
    wbuf_t wbuf;
    struct ieee80211_frame *wh;
    u_int8_t *frm;
    u_int16_t capinfo;
    int enable_htrates;
    bool add_wpa_ie = true;

    ASSERT(vap->iv_opmode == IEEE80211_M_HOSTAP || vap->iv_opmode == IEEE80211_M_IBSS ||
           vap->iv_opmode == IEEE80211_M_BTAMP);
    
    wbuf = wbuf_alloc(ic->ic_osdev, WBUF_TX_MGMT, MAX_TX_RX_PACKET_SIZE);
    if (wbuf == NULL)
        return -ENOMEM;

#ifdef IEEE80211_DEBUG_REFCNT
    printk("%s ,line %u: increase node %p <%s> refcnt to %d\n",
           __func__, __LINE__, ni, ether_sprintf(ni->ni_macaddr),
           ieee80211_node_refcnt(ni));
#endif
    
    /* setup the wireless header */
    wh = (struct ieee80211_frame *)wbuf_header(wbuf);
    ieee80211_send_setup(vap, ni, wh,
                         IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP,
                         vap->iv_myaddr, macaddr,
                         ieee80211_node_get_bssid(ni));
    frm = (u_int8_t *)&wh[1];

    /*
     * probe response frame format
     *  [8] time stamp
     *  [2] beacon interval
     *  [2] cabability information
     *  [tlv] ssid
     *  [tlv] supported rates
     *  [tlv] parameter set (FH/DS)
     *  [tlv] parameter set (IBSS)
     *  [tlv] extended rate phy (ERP)
     *  [tlv] extended supported rates
     *  [tlv] country (if present)
     *  [3] power constraint
     *  [tlv] WPA
     *  [tlv] WME
     *  [tlv] HT Capabilities
     *  [tlv] HT Information
     *      [tlv] Atheros Advanced Capabilities
     */
    OS_MEMZERO(frm, 8);  /* timestamp should be filled later */
    frm += 8;
    *(u_int16_t *)frm = htole16(vap->iv_bss->ni_intval);
    frm += 2;
    if (vap->iv_opmode == IEEE80211_M_IBSS)
        capinfo = IEEE80211_CAPINFO_IBSS;
    else
        capinfo = IEEE80211_CAPINFO_ESS;
    if (IEEE80211_VAP_IS_PRIVACY_ENABLED(vap))
        capinfo |= IEEE80211_CAPINFO_PRIVACY;
    if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
        IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
        capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
    if (ic->ic_flags & IEEE80211_F_SHSLOT)
        capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME;
    if (ieee80211_ic_doth_is_set(ic) && ieee80211_vap_doth_is_set(vap))
        capinfo |= IEEE80211_CAPINFO_SPECTRUM_MGMT;
    *(u_int16_t *)frm = htole16(capinfo);
    frm += 2;
    
    frm = ieee80211_add_ssid(frm, vap->iv_bss->ni_essid,
                             vap->iv_bss->ni_esslen);
    
    frm = ieee80211_add_rates(frm, &vap->iv_bss->ni_rates, ic);

    if (!IEEE80211_IS_CHAN_FHSS(vap->iv_bsschan)) {
        *frm++ = IEEE80211_ELEMID_DSPARMS;
        *frm++ = 1;
        *frm++ = ieee80211_chan2ieee(ic, ic->ic_curchan);
    }
    
    if (vap->iv_opmode == IEEE80211_M_IBSS) {
        *frm++ = IEEE80211_ELEMID_IBSSPARMS;
        *frm++ = 2;
        *frm++ = 0; *frm++ = 0;     /* TODO: ATIM window */
    }

    if (IEEE80211_IS_COUNTRYIE_ENABLED(ic)) {
        frm = ieee80211_add_country(frm, vap);
    }

    if (ieee80211_ic_doth_is_set(ic) && ieee80211_vap_doth_is_set(vap)) {
        *frm++ = IEEE80211_ELEMID_PWRCNSTR;
        *frm++ = 1;
        *frm++ = IEEE80211_PWRCONSTRAINT_VAL(vap);
    }
   
#if ATH_SUPPORT_IBSS_DFS
    if (vap->iv_opmode == IEEE80211_M_IBSS) {
         frm =  ieee80211_add_ibss_dfs(frm,vap);
    }
#endif

    if (IEEE80211_IS_CHAN_ANYG(ic->ic_curchan) || 
        IEEE80211_IS_CHAN_11NG(ic->ic_curchan)) {
        frm = ieee80211_add_erp(frm, ic);
    }

    /*
     * check if os shim has setup RSN IE it self.
     */
    IEEE80211_VAP_LOCK(vap);
    if (vap->iv_app_ie[IEEE80211_FRAME_TYPE_PROBERESP].length) {
        add_wpa_ie = ieee80211_check_wpaie(vap, vap->iv_app_ie[IEEE80211_FRAME_TYPE_PROBERESP].ie,
                                           vap->iv_app_ie[IEEE80211_FRAME_TYPE_PROBERESP].length);
    }
    if (vap->iv_opt_ie.length) {
        add_wpa_ie = ieee80211_check_wpaie(vap, vap->iv_opt_ie.ie,
                                           vap->iv_opt_ie.length);
    }
    IEEE80211_VAP_UNLOCK(vap);

    if (add_wpa_ie) {
        if (RSN_AUTH_IS_RSNA(rsn))
            frm = ieee80211_setup_rsn_ie(vap, frm);
    }

#if ATH_SUPPORT_WAPI
    if (RSN_AUTH_IS_WAI(rsn))
        frm = ieee80211_setup_wapi_ie(vap, frm);
#endif

    frm = ieee80211_add_xrates(frm, &vap->iv_bss->ni_rates, ic);

    enable_htrates = ieee80211vap_htallowed(vap);
    
    if (IEEE80211_IS_CHAN_11N(ic->ic_curchan) && enable_htrates) {
        frm = ieee80211_add_htcap(frm, ni, IEEE80211_FC0_SUBTYPE_PROBE_RESP);

        if (!IEEE80211_IS_HTVIE_ENABLED(ic))
            frm = ieee80211_add_htcap_pre_ana(frm, ni, IEEE80211_FC0_SUBTYPE_PROBE_RESP);

        frm = ieee80211_add_htinfo(frm, ni);

        if (!IEEE80211_IS_HTVIE_ENABLED(ic))
            frm = ieee80211_add_htinfo_pre_ana(frm, ni);

        if (!(ic->ic_flags & IEEE80211_F_COEXT_DISABLE)) {
            frm = ieee80211_add_obss_scan(frm, ni);
            frm = ieee80211_add_extcap(frm, ni);
        }
    }

    if (add_wpa_ie) {
        if (RSN_AUTH_IS_WPA(rsn))
            frm = ieee80211_setup_wpa_ie(vap, frm);
    }
    
    if (ieee80211_vap_wme_is_set(vap) &&
        (vap->iv_opmode == IEEE80211_M_HOSTAP || vap->iv_opmode == IEEE80211_M_BTAMP)) /* don't support WMM in ad-hoc for now */
        frm = ieee80211_add_wme_param(frm, &ic->ic_wme, IEEE80211_VAP_IS_UAPSD_ENABLED(vap));

    if ((IEEE80211_IS_CHAN_11N(ic->ic_curchan)) && (IEEE80211_IS_HTVIE_ENABLED(ic)) && enable_htrates) {
        frm = ieee80211_add_htcap_vendor_specific(frm, ni, IEEE80211_FC0_SUBTYPE_PROBE_RESP);
        frm = ieee80211_add_htinfo_vendor_specific(frm, ni);
    }

    if (vap->iv_bss->ni_ath_flags) {
        frm = ieee80211_add_athAdvCap(frm, vap->iv_bss->ni_ath_flags,
                                      vap->iv_bss->ni_ath_defkeyindex);
    } else {
        frm = ieee80211_add_athAdvCap(frm, 0, IEEE80211_INVAL_DEFKEY);
    }

    /* Insert ieee80211_ie_ath_extcap IE to beacon */
    if (ic->ic_ath_extcap)
        frm = ieee80211_add_athextcap(frm, ic->ic_ath_extcap, ic->ic_weptkipaggr_rxdelim);

#ifdef notyet
    if (ni->ni_ath_ie != NULL)    /* XXX */
        frm = ieee80211_add_ath(frm, ni);
#endif
    
    IEEE80211_VAP_LOCK(vap);
    if (vap->iv_opt_ie.length) {
        OS_MEMCPY(frm, vap->iv_opt_ie.ie,
                  vap->iv_opt_ie.length);
        frm += vap->iv_opt_ie.length;
    }

    if (vap->iv_app_ie[IEEE80211_FRAME_TYPE_PROBERESP].length) {
        OS_MEMCPY(frm, vap->iv_app_ie[IEEE80211_FRAME_TYPE_PROBERESP].ie,
                  vap->iv_app_ie[IEEE80211_FRAME_TYPE_PROBERESP].length);
        frm += vap->iv_app_ie[IEEE80211_FRAME_TYPE_PROBERESP].length;
    }

    /* Add the Application IE's */
    frm = ieee80211_mlme_app_ie_append(vap, IEEE80211_FRAME_TYPE_PROBERESP, frm);
    IEEE80211_VAP_UNLOCK(vap);
    
    if (optie != NULL && optielen != 0) {
        OS_MEMCPY(frm, optie, optielen);
        frm += optielen;
    }

    wbuf_set_pktlen(wbuf, (frm - (u_int8_t *)wbuf_header(wbuf)));

    return ieee80211_send_mgmt(vap,ni, wbuf,true);
}
예제 #6
0
파일: ath_tx99.c 프로젝트: KHATEEBNSIT/AP
/*
 * Start continuous transmit operation.
 */
static int
tx99_start(struct ath_softc *sc)
{
    static struct ath_tx99_tgt tx99_tgt;
    struct ath_tx99 *tx99 = sc->sc_tx99;
    struct ath_hal *ah = sc->sc_ah;
    int is2GHz = 0;
    wbuf_t 	wbuf;
    HAL_CHANNEL *chan = NULL;
	
    if(tx99->recv)
    {
        ath_hal_phydisable(ah);
        DPRINTF(sc, ATH_DEBUG_TX99, "%s: tx99 continuous receive mode, return!\n", __func__);
        return 0;
    }

    /* check tx99 running state */
    if(tx99->tx99_state){		/* already active */
        DPRINTF(sc, ATH_DEBUG_TX99, "%s: already running, return!\n", __func__);
        return 0;
    }

    OS_DELAY(10000);
	
    /* set tx99 state active */
    tx99->tx99_state = 1;
    /* allocate diag packet buffer */
    if (tx99->wbuf == NULL) {
        tx99->wbuf = wbuf_alloc(sc->sc_osdev, WBUF_TX_DATA, 2000);
        if (tx99->wbuf == NULL) {
            DPRINTF(sc, ATH_DEBUG_TX99, "%s: unable to allocate wbuf!\n", __func__);
            tx99->tx99_state = 0;
            return -ENOMEM;
        }
    } else {
        DPRINTF(sc, ATH_DEBUG_TX99, "%s: wbuf was allocated before!\n", __func__);
    }
    wbuf = tx99->wbuf;
    /* drain all tx queue */
    ath_drain_txq(sc);
    /*
     * Setup channel using configured frequency+flags.
     */
    if (tx99_channel_setup(sc)) {
        DPRINTF(sc, ATH_DEBUG_TX99, "%s: unable to setup channel!\n", __func__);
		/* recover the default channel and mode */
        tx99->txfreq = 2412;/* ieee channel frequecy */
        tx99->htmode = 0;
        tx99->htext = 0;
		
        goto bad;
    }
    /*
     * Setup tx power limit
     */ 
    chan = &sc->sc_curchan; 
    is2GHz = TX99_IS_CHAN_2GHZ(chan);
    ath_hal_settxpowlimit(ah,tx99->txpower,0,is2GHz);
    /* set tx99 enable */
    tx99_tgt.txrate = htonl(tx99->txrate);
    tx99_tgt.txrc = htonl(tx99->txrc);
    tx99_tgt.txpower = htonl(tx99->txpower);
    tx99_tgt.txchain = htonl(tx99->chanmask);
    tx99_tgt.htmode = htonl(tx99->htmode);
    tx99_tgt.type = htonl(tx99->type);
    tx99_tgt.chtype = htonl(TX99_IS_CHAN_5GHZ(chan));
    tx99_tgt.txantenna = htonl(0);
	
    if( tx99->txpower < 60 ) /* only update channel pwr if not default MAX power */
        ath_hal_tx99_channel_pwr_update(ah, chan, tx99->txpower);
	
#ifdef ATH_SUPPORT_HTC
    ah_tx99_start(ah, (u_int8_t *)&tx99_tgt);
	
    /* send diag packet */
    {
        struct  ath_txep *txep;
        A_STATUS ret;
		
        adf_nbuf_put_tail(skb, 1500);
        txep = sc->sc_ac2ep[WME_AC_VO];
        /* send packet to target */
        ret = HTCSendPkt(sc->sc_host_htc_handle, NULL ,skb, sc->sc_data_VO_ep);
        if(ret)
        {
            DPRINTF(sc, ATH_DEBUG_TX99, "%s: tx99 fail!\n", __func__);
            tx99_stop(sc, 0);
        }	
    }
#else
    if (ath_tx99_tgt_start(sc, tx99_tgt.chtype) != EOK) {
        goto bad;
    }
#endif
	
    /* wait a while to make sure target setting ready */
    OS_DELAY(50000);
    DPRINTF(sc, ATH_DEBUG_TX99, "%s: continuous transmit started!\n", __func__);
    return 0;
bad:
    tx99_stop(sc, 0);
    return -EIO;
}