static OS_TIMER_FUNC(dfs_remove_from_nol) { struct dfs_nol_timer_arg *nol_arg; struct ath_dfs *dfs; struct ieee80211com *ic; u_int16_t delfreq; u_int16_t delchwidth; OS_GET_TIMER_ARG(nol_arg, struct dfs_nol_timer_arg *); dfs = nol_arg->dfs; ic = dfs->ic; delfreq = nol_arg->delfreq; delchwidth = nol_arg->delchwidth; /* Only operate in HOSTAP/IBSS */ if (ic->ic_opmode != IEEE80211_M_HOSTAP && ic->ic_opmode != IEEE80211_M_IBSS) goto done; /* Delete the given NOL entry */ dfs_nol_delete(dfs, delfreq, delchwidth); /* Update the wireless stack with the new NOL */ dfs_nol_update(dfs); done: OS_FREE(nol_arg); return; }
void dfs_set_nol(struct ath_dfs *dfs, struct dfsreq_nolelem *dfs_nol, int nchan) { #define TIME_IN_MS 1000 u_int32_t nol_time_left_ms; struct ieee80211_channel chan; int i; if (dfs == NULL) { DFS_DPRINTK(dfs, ATH_DEBUG_DFS_NOL, "%s: sc_dfs is NULL\n", __func__); return; } for (i = 0; i < nchan; i++) { nol_time_left_ms = adf_os_ticks_to_msecs(adf_os_ticks() - dfs_nol[i].nol_start_ticks); if (nol_time_left_ms < dfs_nol[i].nol_timeout_ms) { chan.ic_freq = dfs_nol[i].nol_freq; chan.ic_flags= 0; chan.ic_flagext = 0; nol_time_left_ms = (dfs_nol[i].nol_timeout_ms - nol_time_left_ms); dfs_nol_addchan(dfs, &chan, (nol_time_left_ms / TIME_IN_MS)); } } #undef TIME_IN_MS dfs_nol_update(dfs); }
/* * Mark a channel as having interference detected upon it. * * This adds the interference marker to both the primary and * extension channel. * * XXX TODO: make the NOL and channel interference logic a bit smarter * so only the channel with the radar event is marked, rather than * both the primary and extension. */ static void dfs_channel_mark_radar(struct ath_dfs *dfs, struct ieee80211_channel *chan) { struct ieee80211_channel_list chan_info; int i; //chan->ic_flagext |= CHANNEL_INTERFERENCE; /* * If radar is detected in 40MHz mode, add both the primary and the * extension channels to the NOL. chan is the channel data we return * to the ath_dev layer which passes it on to the 80211 layer. * As we want the AP to change channels and send out a CSA, * we always pass back the primary channel data to the ath_dev layer. */ if ((dfs->dfs_rinfo.rn_use_nol == 1) && (dfs->ic->ic_opmode == IEEE80211_M_HOSTAP || #if ATH_SUPPORT_DFS && ATH_SUPPORT_STA_DFS dfs->ic->ic_opmode == IEEE80211_M_IBSS || ((dfs->ic->ic_opmode == IEEE80211_M_STA) && (ieee80211com_has_cap_ext(dfs->ic,IEEE80211_CEXT_STADFS))))) { #else dfs->ic->ic_opmode == IEEE80211_M_IBSS)) { #endif chan_info.cl_nchans= 0; dfs->ic->ic_get_ext_chan_info (dfs->ic, &chan_info); for (i = 0; i < chan_info.cl_nchans; i++) { if (chan_info.cl_channels[i] == NULL) { DFS_PRINTK("%s: NULL channel\n", __func__); } else { chan_info.cl_channels[i]->ic_flagext |= CHANNEL_INTERFERENCE; dfs_nol_addchan(dfs, chan_info.cl_channels[i], dfs->ath_dfs_nol_timeout); } } /* * Update the umac/driver channels with the new NOL information. */ dfs_nol_update(dfs); } }