示例#1
0
static void
brcms_ops_bss_info_changed(struct ieee80211_hw *hw,
			struct ieee80211_vif *vif,
			struct ieee80211_bss_conf *info, u32 changed)
{
	struct brcms_info *wl = hw->priv;
	struct bcma_device *core = wl->wlc->hw->d11core;

	if (changed & BSS_CHANGED_ASSOC) {
		/* association status changed (associated/disassociated)
		 * also implies a change in the AID.
		 */
		brcms_err(core, "%s: %s: %sassociated\n", KBUILD_MODNAME,
			  __func__, info->assoc ? "" : "dis");
		spin_lock_bh(&wl->lock);
		brcms_c_associate_upd(wl->wlc, info->assoc);
		spin_unlock_bh(&wl->lock);
	}
	if (changed & BSS_CHANGED_ERP_SLOT) {
		s8 val;

		/* slot timing changed */
		if (info->use_short_slot)
			val = 1;
		else
			val = 0;
		spin_lock_bh(&wl->lock);
		brcms_c_set_shortslot_override(wl->wlc, val);
		spin_unlock_bh(&wl->lock);
	}

	if (changed & BSS_CHANGED_HT) {
		/* 802.11n parameters changed */
		u16 mode = info->ht_operation_mode;

		spin_lock_bh(&wl->lock);
		brcms_c_protection_upd(wl->wlc, BRCMS_PROT_N_CFG,
			mode & IEEE80211_HT_OP_MODE_PROTECTION);
		brcms_c_protection_upd(wl->wlc, BRCMS_PROT_N_NONGF,
			mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
		brcms_c_protection_upd(wl->wlc, BRCMS_PROT_N_OBSS,
			mode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT);
		spin_unlock_bh(&wl->lock);
	}
	if (changed & BSS_CHANGED_BASIC_RATES) {
		struct ieee80211_supported_band *bi;
		u32 br_mask, i;
		u16 rate;
		struct brcm_rateset rs;
		int error;

		/* retrieve the current rates */
		spin_lock_bh(&wl->lock);
		brcms_c_get_current_rateset(wl->wlc, &rs);
		spin_unlock_bh(&wl->lock);

		br_mask = info->basic_rates;
		bi = hw->wiphy->bands[brcms_c_get_curband(wl->wlc)];
		for (i = 0; i < bi->n_bitrates; i++) {
			/* convert to internal rate value */
			rate = (bi->bitrates[i].bitrate << 1) / 10;

			/* set/clear basic rate flag */
			brcms_set_basic_rate(&rs, rate, br_mask & 1);
			br_mask >>= 1;
		}

		/* update the rate set */
		spin_lock_bh(&wl->lock);
		error = brcms_c_set_rateset(wl->wlc, &rs);
		spin_unlock_bh(&wl->lock);
		if (error)
			brcms_err(core, "changing basic rates failed: %d\n",
				  error);
	}
	if (changed & BSS_CHANGED_BEACON_INT) {
		/* Beacon interval changed */
		spin_lock_bh(&wl->lock);
		brcms_c_set_beacon_period(wl->wlc, info->beacon_int);
		spin_unlock_bh(&wl->lock);
	}
	if (changed & BSS_CHANGED_BSSID) {
		/* BSSID changed, for whatever reason (IBSS and managed mode) */
		spin_lock_bh(&wl->lock);
		brcms_c_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET, info->bssid);
		spin_unlock_bh(&wl->lock);
	}
	if (changed & BSS_CHANGED_SSID) {
		/* BSSID changed, for whatever reason (IBSS and managed mode) */
		spin_lock_bh(&wl->lock);
		brcms_c_set_ssid(wl->wlc, info->ssid, info->ssid_len);
		spin_unlock_bh(&wl->lock);
	}
	if (changed & BSS_CHANGED_BEACON) {
		/* Beacon data changed, retrieve new beacon (beaconing modes) */
		struct sk_buff *beacon;
		u16 tim_offset = 0;

		spin_lock_bh(&wl->lock);
		beacon = ieee80211_beacon_get_tim(hw, vif, &tim_offset, NULL);
		brcms_c_set_new_beacon(wl->wlc, beacon, tim_offset,
				       info->dtim_period);
		spin_unlock_bh(&wl->lock);
	}

	if (changed & BSS_CHANGED_AP_PROBE_RESP) {
		struct sk_buff *probe_resp;

		spin_lock_bh(&wl->lock);
		probe_resp = ieee80211_proberesp_get(hw, vif);
		brcms_c_set_new_probe_resp(wl->wlc, probe_resp);
		spin_unlock_bh(&wl->lock);
	}

	if (changed & BSS_CHANGED_BEACON_ENABLED) {
		/* Beaconing should be enabled/disabled (beaconing modes) */
		brcms_err(core, "%s: Beacon enabled: %s\n", __func__,
			  info->enable_beacon ? "true" : "false");
		if (info->enable_beacon &&
		    hw->wiphy->flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) {
			brcms_c_enable_probe_resp(wl->wlc, true);
		} else {
			brcms_c_enable_probe_resp(wl->wlc, false);
		}
	}

	if (changed & BSS_CHANGED_CQM) {
		/* Connection quality monitor config changed */
		brcms_err(core, "%s: cqm change: threshold %d, hys %d "
			  " (implement)\n", __func__, info->cqm_rssi_thold,
			  info->cqm_rssi_hyst);
	}

	if (changed & BSS_CHANGED_IBSS) {
		/* IBSS join status changed */
		brcms_err(core, "%s: IBSS joined: %s (implement)\n",
			  __func__, info->ibss_joined ? "true" : "false");
	}

	if (changed & BSS_CHANGED_ARP_FILTER) {
		/* Hardware ARP filter address list or state changed */
		brcms_err(core, "%s: arp filtering: %d addresses"
			  " (implement)\n", __func__, info->arp_addr_cnt);
	}

	if (changed & BSS_CHANGED_QOS) {
		/*
		 * QoS for this association was enabled/disabled.
		 * Note that it is only ever disabled for station mode.
		 */
		brcms_err(core, "%s: qos enabled: %s (implement)\n",
			  __func__, info->qos ? "true" : "false");
	}
	return;
}
示例#2
0
static void
brcms_ops_bss_info_changed(struct ieee80211_hw *hw,
			struct ieee80211_vif *vif,
			struct ieee80211_bss_conf *info, u32 changed)
{
	struct brcms_info *wl = HW_TO_WL(hw);
	struct wiphy *wiphy = hw->wiphy;
	int val;

	if (changed & BSS_CHANGED_ASSOC) {
		/* association status changed (associated/disassociated)
		 * also implies a change in the AID.
		 */
		wiphy_err(wiphy, "%s: %s: %sassociated\n", KBUILD_MODNAME,
			  __func__, info->assoc ? "" : "dis");
		LOCK(wl);
		brcms_c_associate_upd(wl->wlc, info->assoc);
		UNLOCK(wl);
	}
	if (changed & BSS_CHANGED_ERP_SLOT) {
		/* slot timing changed */
		if (info->use_short_slot)
			val = 1;
		else
			val = 0;
		LOCK(wl);
		brcms_c_set(wl->wlc, BRCMS_SET_SHORTSLOT_OVERRIDE, val);
		UNLOCK(wl);
	}

	if (changed & BSS_CHANGED_HT) {
		/* 802.11n parameters changed */
		u16 mode = info->ht_operation_mode;

		LOCK(wl);
		brcms_c_protection_upd(wl->wlc, BRCMS_PROT_N_CFG,
			mode & IEEE80211_HT_OP_MODE_PROTECTION);
		brcms_c_protection_upd(wl->wlc, BRCMS_PROT_N_NONGF,
			mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
		brcms_c_protection_upd(wl->wlc, BRCMS_PROT_N_OBSS,
			mode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT);
		UNLOCK(wl);
	}
	if (changed & BSS_CHANGED_BASIC_RATES) {
		struct ieee80211_supported_band *bi;
		u32 br_mask, i;
		u16 rate;
		struct wl_rateset rs;
		int error;

		/* retrieve the current rates */
		LOCK(wl);
		error = brcms_c_ioctl(wl->wlc, BRCM_GET_CURR_RATESET,
				  &rs, sizeof(rs), NULL);
		UNLOCK(wl);
		if (error) {
			wiphy_err(wiphy, "%s: retrieve rateset failed: %d\n",
				  __func__, error);
			return;
		}
		br_mask = info->basic_rates;
		bi = hw->wiphy->bands[brcms_c_get_curband(wl->wlc)];
		for (i = 0; i < bi->n_bitrates; i++) {
			/* convert to internal rate value */
			rate = (bi->bitrates[i].bitrate << 1) / 10;

			/* set/clear basic rate flag */
			brcms_set_basic_rate(&rs, rate, br_mask & 1);
			br_mask >>= 1;
		}

		/* update the rate set */
		LOCK(wl);
		brcms_c_ioctl(wl->wlc, BRCM_SET_RATESET, &rs, sizeof(rs), NULL);
		UNLOCK(wl);
	}
	if (changed & BSS_CHANGED_BEACON_INT) {
		/* Beacon interval changed */
		LOCK(wl);
		brcms_c_set(wl->wlc, BRCM_SET_BCNPRD, info->beacon_int);
		UNLOCK(wl);
	}
	if (changed & BSS_CHANGED_BSSID) {
		/* BSSID changed, for whatever reason (IBSS and managed mode) */
		LOCK(wl);
		brcms_c_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET,
				  info->bssid);
		UNLOCK(wl);
	}
	if (changed & BSS_CHANGED_BEACON) {
		/* Beacon data changed, retrieve new beacon (beaconing modes) */
		wiphy_err(wiphy, "%s: beacon changed\n", __func__);
	}
	if (changed & BSS_CHANGED_BEACON_ENABLED) {
		/* Beaconing should be enabled/disabled (beaconing modes) */
		wiphy_err(wiphy, "%s: Beacon enabled: %s\n", __func__,
			  info->enable_beacon ? "true" : "false");
	}
	if (changed & BSS_CHANGED_CQM) {
		/* Connection quality monitor config changed */
		wiphy_err(wiphy, "%s: cqm change: threshold %d, hys %d "
			  " (implement)\n", __func__, info->cqm_rssi_thold,
			  info->cqm_rssi_hyst);
	}
	if (changed & BSS_CHANGED_IBSS) {
		/* IBSS join status changed */
		wiphy_err(wiphy, "%s: IBSS joined: %s (implement)\n", __func__,
			  info->ibss_joined ? "true" : "false");
	}
	if (changed & BSS_CHANGED_ARP_FILTER) {
		/* Hardware ARP filter address list or state changed */
		wiphy_err(wiphy, "%s: arp filtering: enabled %s, count %d"
			  " (implement)\n", __func__, info->arp_filter_enabled ?
			  "true" : "false", info->arp_addr_cnt);
	}
	if (changed & BSS_CHANGED_QOS) {
		/*
		 * QoS for this association was enabled/disabled.
		 * Note that it is only ever disabled for station mode.
		 */
		wiphy_err(wiphy, "%s: qos enabled: %s (implement)\n", __func__,
			  info->qos ? "true" : "false");
	}
	return;
}