diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/Makefile | 2 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 6 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 4 | ||||
-rw-r--r-- | net/mac80211/main.c | 26 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 10 | ||||
-rw-r--r-- | net/mac80211/rx.c | 17 | ||||
-rw-r--r-- | net/mac80211/tx.c | 1 | ||||
-rw-r--r-- | net/mac80211/wext.c | 11 | ||||
-rw-r--r-- | net/rfkill/rfkill.c | 83 | ||||
-rw-r--r-- | net/wireless/Makefile | 2 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 40 |
11 files changed, 71 insertions, 131 deletions
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile index 31cfd1f..7d4971a 100644 --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile @@ -46,3 +46,5 @@ rc80211_minstrel-$(CONFIG_MAC80211_DEBUGFS) += rc80211_minstrel_debugfs.o mac80211-$(CONFIG_MAC80211_RC_PID) += $(rc80211_pid-y) mac80211-$(CONFIG_MAC80211_RC_MINSTREL) += $(rc80211_minstrel-y) + +ccflags-y += -D__CHECK_ENDIAN__ diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 7a7a6c1..7912eb1 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -396,8 +396,10 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata, */ if (params->interval) { sdata->local->hw.conf.beacon_int = params->interval; - ieee80211_hw_config(sdata->local, - IEEE80211_CONF_CHANGE_BEACON_INTERVAL); + err = ieee80211_hw_config(sdata->local, + IEEE80211_CONF_CHANGE_BEACON_INTERVAL); + if (err < 0) + return err; /* * We updated some parameter so if below bails out * it's not an error. diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 527205f..6f59e11 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -187,7 +187,6 @@ struct ieee80211_rx_data { struct ieee80211_rx_status *status; struct ieee80211_rate *rate; - u16 ethertype; unsigned int flags; int sent_ps_buffered; int queue; @@ -864,8 +863,7 @@ int ieee80211_sta_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid); void ieee80211_sta_req_auth(struct ieee80211_sub_if_data *sdata, struct ieee80211_if_sta *ifsta); struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, - struct sk_buff *skb, u8 *bssid, - u8 *addr, u64 supp_rates); + u8 *bssid, u8 *addr, u64 supp_rates); int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason); int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason); u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata); diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 29c3ecf..6d87103 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -243,10 +243,20 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) if (changed && local->open_count) { ret = local->ops->config(local_to_hw(local), changed); /* + * Goal: * HW reconfiguration should never fail, the driver has told * us what it can support so it should live up to that promise. + * + * Current status: + * rfkill is not integrated with mac80211 and a + * configuration command can thus fail if hardware rfkill + * is enabled + * + * FIXME: integrate rfkill with mac80211 and then add this + * WARN_ON() back + * */ - WARN_ON(ret); + /* WARN_ON(ret); */ } return ret; @@ -876,12 +886,14 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) local->mdev->select_queue = ieee80211_select_queue; - /* add one default STA interface */ - result = ieee80211_if_add(local, "wlan%d", NULL, - NL80211_IFTYPE_STATION, NULL); - if (result) - printk(KERN_WARNING "%s: Failed to add default virtual iface\n", - wiphy_name(local->hw.wiphy)); + /* add one default STA interface if supported */ + if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) { + result = ieee80211_if_add(local, "wlan%d", NULL, + NL80211_IFTYPE_STATION, NULL); + if (result) + printk(KERN_WARNING "%s: Failed to add default virtual iface\n", + wiphy_name(local->hw.wiphy)); + } rtnl_unlock(); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 87b2ac8..290b001 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1565,8 +1565,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, (unsigned long long) sta->sta.supp_rates[band]); #endif } else { - ieee80211_ibss_add_sta(sdata, NULL, mgmt->bssid, - mgmt->sa, supp_rates); + ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, supp_rates); } rcu_read_unlock(); @@ -1638,9 +1637,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, sdata->dev->name, mgmt->bssid); #endif ieee80211_sta_join_ibss(sdata, &sdata->u.sta, bss); - ieee80211_ibss_add_sta(sdata, NULL, - mgmt->bssid, mgmt->sa, - supp_rates); + ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, supp_rates); } } @@ -2373,8 +2370,7 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) * must be callable in atomic context. */ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, - struct sk_buff *skb, u8 *bssid, - u8 *addr, u64 supp_rates) + u8 *bssid,u8 *addr, u64 supp_rates) { struct ieee80211_local *local = sdata->local; struct sta_info *sta; diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 14be095..73cf126 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -658,9 +658,9 @@ static void ap_sta_ps_start(struct sta_info *sta) atomic_inc(&sdata->bss->num_sta_ps); set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL); - if (local->ops->sta_notify_ps) - local->ops->sta_notify_ps(local_to_hw(local), STA_NOTIFY_SLEEP, - &sta->sta); + if (local->ops->sta_notify) + local->ops->sta_notify(local_to_hw(local), &sdata->vif, + STA_NOTIFY_SLEEP, &sta->sta); #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n", sdata->dev->name, sta->sta.addr, sta->sta.aid); @@ -677,9 +677,9 @@ static int ap_sta_ps_end(struct sta_info *sta) atomic_dec(&sdata->bss->num_sta_ps); clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL); - if (local->ops->sta_notify_ps) - local->ops->sta_notify_ps(local_to_hw(local), STA_NOTIFY_AWAKE, - &sta->sta); + if (local->ops->sta_notify) + local->ops->sta_notify(local_to_hw(local), &sdata->vif, + STA_NOTIFY_AWAKE, &sta->sta); if (!skb_queue_empty(&sta->ps_tx_buf)) sta_info_clear_tim_bit(sta); @@ -1850,9 +1850,8 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, return 0; rx->flags &= ~IEEE80211_RX_RA_MATCH; } else if (!rx->sta) - rx->sta = ieee80211_ibss_add_sta(sdata, rx->skb, - bssid, hdr->addr2, - BIT(rx->status->rate_idx)); + rx->sta = ieee80211_ibss_add_sta(sdata, bssid, hdr->addr2, + BIT(rx->status->rate_idx)); break; case NL80211_IFTYPE_MESH_POINT: if (!multicast && diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index d7761e9..b098c58 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1001,7 +1001,6 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx, if (tx->flags & IEEE80211_TX_FRAGMENTED) { if ((tx->flags & IEEE80211_TX_UNICAST) && skb->len + FCS_LEN > local->fragmentation_threshold && - !local->ops->set_frag_threshold && !(info->flags & IEEE80211_TX_CTL_AMPDU)) tx->flags |= IEEE80211_TX_FRAGMENTED; else diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index 4e1fdcf..1542804 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c @@ -418,8 +418,7 @@ static int ieee80211_ioctl_siwscan(struct net_device *dev, if (sdata->vif.type != NL80211_IFTYPE_STATION && sdata->vif.type != NL80211_IFTYPE_ADHOC && - sdata->vif.type != NL80211_IFTYPE_MESH_POINT && - sdata->vif.type != NL80211_IFTYPE_AP) + sdata->vif.type != NL80211_IFTYPE_MESH_POINT) return -EOPNOTSUPP; /* if SSID was specified explicitly then use that */ @@ -639,14 +638,6 @@ static int ieee80211_ioctl_siwfrag(struct net_device *dev, local->fragmentation_threshold = frag->value & ~0x1; } - /* If the wlan card performs fragmentation in hardware/firmware, - * configure it here */ - - if (local->ops->set_frag_threshold) - return local->ops->set_frag_threshold( - local_to_hw(local), - local->fragmentation_threshold); - return 0; } diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c index 051d2c9..3c94f76 100644 --- a/net/rfkill/rfkill.c +++ b/net/rfkill/rfkill.c @@ -53,51 +53,6 @@ static struct rfkill_gsw_state rfkill_global_states[RFKILL_TYPE_MAX]; static unsigned long rfkill_states_lockdflt[BITS_TO_LONGS(RFKILL_TYPE_MAX)]; static bool rfkill_epo_lock_active; -static BLOCKING_NOTIFIER_HEAD(rfkill_notifier_list); - - -/** - * register_rfkill_notifier - Add notifier to rfkill notifier chain - * @nb: pointer to the new entry to add to the chain - * - * See blocking_notifier_chain_register() for return value and further - * observations. - * - * Adds a notifier to the rfkill notifier chain. The chain will be - * called with a pointer to the relevant rfkill structure as a parameter, - * refer to include/linux/rfkill.h for the possible events. - * - * Notifiers added to this chain are to always return NOTIFY_DONE. This - * chain is a blocking notifier chain: notifiers can sleep. - * - * Calls to this chain may have been done through a workqueue. One must - * assume unordered asynchronous behaviour, there is no way to know if - * actions related to the event that generated the notification have been - * carried out already. - */ -int register_rfkill_notifier(struct notifier_block *nb) -{ - BUG_ON(!nb); - return blocking_notifier_chain_register(&rfkill_notifier_list, nb); -} -EXPORT_SYMBOL_GPL(register_rfkill_notifier); - -/** - * unregister_rfkill_notifier - remove notifier from rfkill notifier chain - * @nb: pointer to the entry to remove from the chain - * - * See blocking_notifier_chain_unregister() for return value and further - * observations. - * - * Removes a notifier from the rfkill notifier chain. - */ -int unregister_rfkill_notifier(struct notifier_block *nb) -{ - BUG_ON(!nb); - return blocking_notifier_chain_unregister(&rfkill_notifier_list, nb); -} -EXPORT_SYMBOL_GPL(unregister_rfkill_notifier); - static void rfkill_led_trigger(struct rfkill *rfkill, enum rfkill_state state) @@ -124,12 +79,9 @@ static void rfkill_led_trigger_activate(struct led_classdev *led) } #endif /* CONFIG_RFKILL_LEDS */ -static void notify_rfkill_state_change(struct rfkill *rfkill) +static void rfkill_uevent(struct rfkill *rfkill) { - rfkill_led_trigger(rfkill, rfkill->state); - blocking_notifier_call_chain(&rfkill_notifier_list, - RFKILL_STATE_CHANGED, - rfkill); + kobject_uevent(&rfkill->dev.kobj, KOBJ_CHANGE); } static void update_rfkill_state(struct rfkill *rfkill) @@ -142,7 +94,7 @@ static void update_rfkill_state(struct rfkill *rfkill) oldstate = rfkill->state; rfkill->state = newstate; if (oldstate != newstate) - notify_rfkill_state_change(rfkill); + rfkill_uevent(rfkill); } mutex_unlock(&rfkill->mutex); } @@ -220,7 +172,7 @@ static int rfkill_toggle_radio(struct rfkill *rfkill, } if (force || rfkill->state != oldstate) - notify_rfkill_state_change(rfkill); + rfkill_uevent(rfkill); return retval; } @@ -405,7 +357,7 @@ int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state) rfkill->state = state; if (state != oldstate) - notify_rfkill_state_change(rfkill); + rfkill_uevent(rfkill); mutex_unlock(&rfkill->mutex); @@ -618,28 +570,6 @@ static int rfkill_resume(struct device *dev) #define rfkill_resume NULL #endif -static int rfkill_blocking_uevent_notifier(struct notifier_block *nb, - unsigned long eventid, - void *data) -{ - struct rfkill *rfkill = (struct rfkill *)data; - - switch (eventid) { - case RFKILL_STATE_CHANGED: - kobject_uevent(&rfkill->dev.kobj, KOBJ_CHANGE); - break; - default: - break; - } - - return NOTIFY_DONE; -} - -static struct notifier_block rfkill_blocking_uevent_nb = { - .notifier_call = rfkill_blocking_uevent_notifier, - .priority = 0, -}; - static int rfkill_dev_uevent(struct device *dev, struct kobj_uevent_env *env) { struct rfkill *rfkill = to_rfkill(dev); @@ -942,14 +872,11 @@ static int __init rfkill_init(void) return error; } - register_rfkill_notifier(&rfkill_blocking_uevent_nb); - return 0; } static void __exit rfkill_exit(void) { - unregister_rfkill_notifier(&rfkill_blocking_uevent_nb); class_unregister(&rfkill_class); } diff --git a/net/wireless/Makefile b/net/wireless/Makefile index 9bc412c..938a334 100644 --- a/net/wireless/Makefile +++ b/net/wireless/Makefile @@ -8,3 +8,5 @@ obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o cfg80211-$(CONFIG_WIRELESS_EXT) += wext-compat.o cfg80211-$(CONFIG_NL80211) += nl80211.o + +ccflags-y += -D__CHECK_ENDIAN__ diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 9caee60..4335f76 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -365,6 +365,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) enum nl80211_sec_chan_offset sec_chan_offset = NL80211_SEC_CHAN_NO_HT; struct ieee80211_channel *chan; + struct ieee80211_sta_ht_cap *ht_cap; u32 freq, sec_freq; if (!rdev->ops->set_channel) { @@ -372,26 +373,25 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) goto bad_res; } + result = -EINVAL; + if (info->attrs[NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET]) { - sec_chan_offset = nla_get_u32( - info->attrs[ + sec_chan_offset = nla_get_u32(info->attrs[ NL80211_ATTR_WIPHY_SEC_CHAN_OFFSET]); if (sec_chan_offset != NL80211_SEC_CHAN_NO_HT && sec_chan_offset != NL80211_SEC_CHAN_DISABLED && sec_chan_offset != NL80211_SEC_CHAN_BELOW && - sec_chan_offset != NL80211_SEC_CHAN_ABOVE) { - result = -EINVAL; + sec_chan_offset != NL80211_SEC_CHAN_ABOVE) goto bad_res; - } } freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); chan = ieee80211_get_channel(&rdev->wiphy, freq); - if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) { - /* Primary channel not allowed */ - result = -EINVAL; + + /* Primary channel not allowed */ + if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) goto bad_res; - } + if (sec_chan_offset == NL80211_SEC_CHAN_BELOW) sec_freq = freq - 20; else if (sec_chan_offset == NL80211_SEC_CHAN_ABOVE) @@ -399,14 +399,26 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) else sec_freq = 0; + ht_cap = &rdev->wiphy.bands[chan->band]->ht_cap; + + /* no HT capabilities */ + if (sec_chan_offset != NL80211_SEC_CHAN_NO_HT && + !ht_cap->ht_supported) + goto bad_res; + if (sec_freq) { struct ieee80211_channel *schan; + + /* no 40 MHz capabilities */ + if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) || + (ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT)) + goto bad_res; + schan = ieee80211_get_channel(&rdev->wiphy, sec_freq); - if (!schan || schan->flags & IEEE80211_CHAN_DISABLED) { - /* Secondary channel not allowed */ - result = -EINVAL; + + /* Secondary channel not allowed */ + if (!schan || schan->flags & IEEE80211_CHAN_DISABLED) goto bad_res; - } } result = rdev->ops->set_channel(&rdev->wiphy, chan, @@ -416,7 +428,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) } -bad_res: + bad_res: cfg80211_put_dev(rdev); return result; } |