Exemplo n.º 1
0
/*
 * Indicate whether there are frames queued for a station in power-save mode.
 */
static int
ieee80211_set_tim(struct ieee80211_node *ni, int set)
{
	struct ieee80211vap *vap = ni->ni_vap;
	struct ieee80211com *ic = ni->ni_ic;
	uint16_t aid;
	int changed;

	KASSERT(vap->iv_opmode == IEEE80211_M_HOSTAP ||
		vap->iv_opmode == IEEE80211_M_IBSS,
		("operating mode %u", vap->iv_opmode));

	aid = IEEE80211_AID(ni->ni_associd);
	KASSERT(aid < vap->iv_max_aid,
		("bogus aid %u, max %u", aid, vap->iv_max_aid));

	IEEE80211_LOCK(ic);
	changed = (set != (isset(vap->iv_tim_bitmap, aid) != 0));
	if (changed) {
		if (set) {
			setbit(vap->iv_tim_bitmap, aid);
			vap->iv_ps_pending++;
		} else {
			clrbit(vap->iv_tim_bitmap, aid);
			vap->iv_ps_pending--;
		}
		/* NB: we know vap is in RUN state so no need to check */
		vap->iv_update_beacon(vap, IEEE80211_BEACON_TIM);
	}
	IEEE80211_UNLOCK(ic);

	return changed;
}
Exemplo n.º 2
0
/*
 * Indicate whether there are frames queued for a station in power-save mode.
 */
void
ieee80211_set_tim(struct ieee80211_node *ni, int set,bool isr_context)
{
    struct ieee80211vap *vap = ni->ni_vap;
    u_int16_t aid;
    rwlock_state_t lock_state;
    unsigned long flags = 0;

    KASSERT(vap->iv_opmode == IEEE80211_M_HOSTAP 
            || vap->iv_opmode == IEEE80211_M_IBSS ,
            ("operating mode %u", vap->iv_opmode));

    aid = IEEE80211_AID(ni->ni_associd);
    KASSERT(aid < vap->iv_max_aid,
            ("bogus aid %u, max %u", aid, vap->iv_max_aid));

	vap->iv_tim_infor.set = set;
	vap->iv_tim_infor.aid = aid;

	if (!isr_context)
	{
		OS_EXEC_INTSAFE(vap->iv_ic->ic_osdev, ieee80211_protect_set_tim, vap);
	}
	else
	{
        /* avoid the race with beacon update */
        OS_RWLOCK_WRITE_LOCK_IRQSAVE(&vap->iv_tim_update_lock, &lock_state, flags);

	    if (set != (isset(vap->iv_tim_bitmap, aid) != 0)) {
	        if (set) {
	            setbit(vap->iv_tim_bitmap, aid);
	            vap->iv_ps_pending++;
	        } else {
	        	vap->iv_ps_pending--;
	            clrbit(vap->iv_tim_bitmap, aid);
	        }		
	        IEEE80211_VAP_TIMUPDATE_ENABLE(vap);
	    }
		OS_RWLOCK_WRITE_UNLOCK_IRQRESTORE(&vap->iv_tim_update_lock, &lock_state, flags);
	}
}
Exemplo n.º 3
0
/*
 * Indicate whether there are frames queued for a station in power-save mode.
 */
void
ieee80211_set_tim(struct ieee80211_node *ni, int set,bool isr_context)
{
    struct ieee80211vap *vap = ni->ni_vap;
    u_int16_t aid;	

    KASSERT(vap->iv_opmode == IEEE80211_M_HOSTAP 
            || vap->iv_opmode == IEEE80211_M_IBSS ,
            ("operating mode %u", vap->iv_opmode));

    aid = IEEE80211_AID(ni->ni_associd);
    KASSERT(aid < vap->iv_max_aid,
            ("bogus aid %u, max %u", aid, vap->iv_max_aid));

	vap->iv_tim_infor.set = set;
	vap->iv_tim_infor.aid = aid;

	if (!isr_context)
	{
		OS_EXEC_INTSAFE(vap->iv_ic->ic_osdev, ieee80211_protect_set_tim, vap);
	}
	else
	{
	    if (set != (isset(vap->iv_tim_bitmap, aid) != 0)) {

	        if (set) {
	            setbit(vap->iv_tim_bitmap, aid);
	            vap->iv_ps_pending++;
	        } else {
	        	vap->iv_ps_pending--;
	            clrbit(vap->iv_tim_bitmap, aid);
	        }		
	        IEEE80211_VAP_TIMUPDATE_ENABLE(vap);
	    }
	}
}
Exemplo n.º 4
0
/*
 * Fill the specific data for mac context of type station or p2p client
 */
static void
iwm_mvm_mac_ctxt_cmd_fill_sta(struct iwm_softc *sc, struct iwm_node *in,
	struct iwm_mac_data_sta *ctxt_sta, int force_assoc_off)
{
	struct ieee80211_node *ni = &in->in_ni;
	unsigned dtim_period, dtim_count;
	struct ieee80211com *ic = sc->sc_ic;
	struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps);

	/* will this work? */
	dtim_period = vap->iv_dtim_period;
	dtim_count = vap->iv_dtim_count;
	IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_BEACON | IWM_DEBUG_CMD,
	    "%s: force_assoc_off=%d\n", __func__, force_assoc_off);
	IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_BEACON | IWM_DEBUG_CMD,
	    "DTIM: period=%d count=%d\n", dtim_period, dtim_count);
	IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_BEACON | IWM_DEBUG_CMD,
	    "BEACON: tsf: %llu, ni_intval=%d\n",
	    (unsigned long long) le64toh(ni->ni_tstamp.tsf),
	    ni->ni_intval);

	/* We need the dtim_period to set the MAC as associated */
	if (in->in_assoc && dtim_period && !force_assoc_off) {
		uint64_t tsf;
		uint32_t dtim_offs;

		/*
		 * The DTIM count counts down, so when it is N that means N
		 * more beacon intervals happen until the DTIM TBTT. Therefore
		 * add this to the current time. If that ends up being in the
		 * future, the firmware will handle it.
		 *
		 * Also note that the system_timestamp (which we get here as
		 * "sync_device_ts") and TSF timestamp aren't at exactly the
		 * same offset in the frame -- the TSF is at the first symbol
		 * of the TSF, the system timestamp is at signal acquisition
		 * time. This means there's an offset between them of at most
		 * a few hundred microseconds (24 * 8 bits + PLCP time gives
		 * 384us in the longest case), this is currently not relevant
		 * as the firmware wakes up around 2ms before the TBTT.
		 */
		dtim_offs = dtim_count * ni->ni_intval;
		/* convert TU to usecs */
		dtim_offs *= 1024;

		/*
		 * net80211: TSF is in 802.11 order, so convert up to local
		 * ordering before we manipulate things.
		 */
		tsf = le64toh(ni->ni_tstamp.tsf);

		ctxt_sta->dtim_tsf = htole64(tsf + dtim_offs);
		ctxt_sta->dtim_time = htole32(tsf + dtim_offs);

		IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_BEACON | IWM_DEBUG_CMD,
		    "DTIM TBTT is 0x%llx/0x%x, offset %d\n",
		    (long long)le64toh(ctxt_sta->dtim_tsf),
		    le32toh(ctxt_sta->dtim_time), dtim_offs);

		ctxt_sta->is_assoc = htole32(1);
	} else {
		ctxt_sta->is_assoc = htole32(0);
	}

	IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_CMD | IWM_DEBUG_BEACON,
	    "%s: ni_intval: %d, bi_reciprocal: %d, dtim_interval: %d, dtim_reciprocal: %d\n",
	    __func__,
	    ni->ni_intval,
	    iwm_mvm_reciprocal(ni->ni_intval),
	    ni->ni_intval * dtim_period,
	    iwm_mvm_reciprocal(ni->ni_intval * dtim_period));

	ctxt_sta->bi = htole32(ni->ni_intval);
	ctxt_sta->bi_reciprocal = htole32(iwm_mvm_reciprocal(ni->ni_intval));
	ctxt_sta->dtim_interval = htole32(ni->ni_intval * dtim_period);
	ctxt_sta->dtim_reciprocal =
	    htole32(iwm_mvm_reciprocal(ni->ni_intval * dtim_period));

	/* 10 = CONN_MAX_LISTEN_INTERVAL */
	ctxt_sta->listen_interval = htole32(10);
	IWM_DPRINTF(sc, IWM_DEBUG_RESET | IWM_DEBUG_CMD | IWM_DEBUG_BEACON,
	    "%s: associd=%d\n", __func__, IEEE80211_AID(ni->ni_associd));
	ctxt_sta->assoc_id = htole32(IEEE80211_AID(ni->ni_associd));
}
Exemplo n.º 5
0
static void
list_stations(const char *ifname)
{
	uint8_t buf[24*1024];
	struct iwreq iwr;
	uint8_t *cp;
	int s, len;

	s = socket(AF_INET, SOCK_DGRAM, 0);
	if (s < 0)
		err(1, "socket(SOCK_DGRAM)");

	(void) memset(&iwr, 0, sizeof(iwr));
	(void) strncpy(iwr.ifr_name, ifname, sizeof(iwr.ifr_name));
	iwr.u.data.pointer = (void *) buf;
	iwr.u.data.length = sizeof(buf);
	if (ioctl(s, IEEE80211_IOCTL_STA_INFO, &iwr) < 0)
		errx(1, "unable to get station information");
	len = iwr.u.data.length;
	if (len < sizeof(struct ieee80211req_sta_info))
		return;
	close(s);

	printf("%-17.17s %4s %4s %4s %4s %4s %4s %6s %6s %4s %5s %3s %8s %8s\n",
		"ADDR",
		"AID",
		"CHAN",
		"RATE",
		"RSSI",
		"DBM",
		"IDLE",
		"TXSEQ",
		"RXSEQ",
		"CAPS",
		"ACAPS",
		"ERP",
		"STATE",
		"MODE");
	cp = buf;
	do {
		struct ieee80211req_sta_info *si;
		uint8_t *vp;

		si = (struct ieee80211req_sta_info *) cp;
		vp = (u_int8_t *)(si+1);
		printf("%s %4u %4d %3dM %4d %4d %4d %6d %6d %-4.4s %-5.5s %3x %8x %8s",
			ieee80211_ntoa(si->isi_macaddr),
			IEEE80211_AID(si->isi_associd),
			ieee80211_mhz2ieee(si->isi_freq),
			(si->isi_rates[si->isi_txrate] & IEEE80211_RATE_VAL) / 2,
			si->isi_rssi,
			rssi2dbm(si->isi_rssi),
			si->isi_inact,
			si->isi_txseqs[0],
			si->isi_rxseqs[0],
		        getcaps(si->isi_capinfo),
		        getathcaps(si->isi_athflags),
			si->isi_erp,
			si->isi_state,
			getstamode(si->isi_opmode));
		printies(vp, si->isi_ie_len, 24);
		printf("\n");
		if (si->isi_uapsd) {
			printf("                   UAPSD QoSInfo: 0x%02x, ",
				si->isi_uapsd);
			printf("(VO,VI,BE,BK) = (%d,%d,%d,%d), MaxSpLimit = %s\n",
				   WME_UAPSD_AC_ENABLED(WME_AC_VO, si->isi_uapsd) ? 1 : 0,
				   WME_UAPSD_AC_ENABLED(WME_AC_VI, si->isi_uapsd) ? 1 : 0,
				   WME_UAPSD_AC_ENABLED(WME_AC_BE, si->isi_uapsd) ? 1 : 0,
				   WME_UAPSD_AC_ENABLED(WME_AC_BK, si->isi_uapsd) ? 1 : 0,
				   WME_UAPSD_MAXSP(si->isi_uapsd) == 1 ? "2" :
				   WME_UAPSD_MAXSP(si->isi_uapsd) == 2 ? "4" :
				   WME_UAPSD_MAXSP(si->isi_uapsd) == 3 ? "6" : "NoLimit");
		}
		cp += si->isi_len;
		len -= si->isi_len;
	} while (len >= sizeof(struct ieee80211req_sta_info));
}