diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 37783cdd301..dfa4bdd5597 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -737,6 +737,7 @@ struct b43_wl { struct ieee80211_tx_control beacon_txctl; bool beacon0_uploaded; bool beacon1_uploaded; + bool beacon_templates_virgin; /* Never wrote the templates? */ struct work_struct beacon_update_trigger; /* The current QOS parameters for the 4 queues. diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 8fdba9415c0..6c3d9ea0a9f 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -1544,6 +1544,30 @@ static void b43_write_probe_resp_template(struct b43_wldev *dev, kfree(probe_resp_data); } +static void b43_upload_beacon0(struct b43_wldev *dev) +{ + struct b43_wl *wl = dev->wl; + + if (wl->beacon0_uploaded) + return; + b43_write_beacon_template(dev, 0x68, 0x18); + /* FIXME: Probe resp upload doesn't really belong here, + * but we don't use that feature anyway. */ + b43_write_probe_resp_template(dev, 0x268, 0x4A, + &__b43_ratetable[3]); + wl->beacon0_uploaded = 1; +} + +static void b43_upload_beacon1(struct b43_wldev *dev) +{ + struct b43_wl *wl = dev->wl; + + if (wl->beacon1_uploaded) + return; + b43_write_beacon_template(dev, 0x468, 0x1A); + wl->beacon1_uploaded = 1; +} + static void handle_irq_beacon(struct b43_wldev *dev) { struct b43_wl *wl = dev->wl; @@ -1568,24 +1592,27 @@ static void handle_irq_beacon(struct b43_wldev *dev) return; } - if (!beacon0_valid) { - if (!wl->beacon0_uploaded) { - b43_write_beacon_template(dev, 0x68, 0x18); - b43_write_probe_resp_template(dev, 0x268, 0x4A, - &__b43_ratetable[3]); - wl->beacon0_uploaded = 1; - } + if (unlikely(wl->beacon_templates_virgin)) { + /* We never uploaded a beacon before. + * Upload both templates now, but only mark one valid. */ + wl->beacon_templates_virgin = 0; + b43_upload_beacon0(dev); + b43_upload_beacon1(dev); cmd = b43_read32(dev, B43_MMIO_MACCMD); cmd |= B43_MACCMD_BEACON0_VALID; b43_write32(dev, B43_MMIO_MACCMD, cmd); - } else if (!beacon1_valid) { - if (!wl->beacon1_uploaded) { - b43_write_beacon_template(dev, 0x468, 0x1A); - wl->beacon1_uploaded = 1; + } else { + if (!beacon0_valid) { + b43_upload_beacon0(dev); + cmd = b43_read32(dev, B43_MMIO_MACCMD); + cmd |= B43_MACCMD_BEACON0_VALID; + b43_write32(dev, B43_MMIO_MACCMD, cmd); + } else if (!beacon1_valid) { + b43_upload_beacon1(dev); + cmd = b43_read32(dev, B43_MMIO_MACCMD); + cmd |= B43_MACCMD_BEACON1_VALID; + b43_write32(dev, B43_MMIO_MACCMD, cmd); } - cmd = b43_read32(dev, B43_MMIO_MACCMD); - cmd |= B43_MACCMD_BEACON1_VALID; - b43_write32(dev, B43_MMIO_MACCMD, cmd); } } @@ -4073,6 +4100,9 @@ static int b43_op_start(struct ieee80211_hw *hw) wl->filter_flags = 0; wl->radiotap_enabled = 0; b43_qos_clear(wl); + wl->beacon0_uploaded = 0; + wl->beacon1_uploaded = 0; + wl->beacon_templates_virgin = 1; /* First register RFkill. * LEDs that are registered later depend on it. */ @@ -4241,7 +4271,9 @@ static void b43_chip_reset(struct work_struct *work) goto out; } } - out: +out: + if (err) + wl->current_dev = NULL; /* Failed to init the dev. */ mutex_unlock(&wl->mutex); if (err) b43err(wl, "Controller restart FAILED\n"); @@ -4382,9 +4414,11 @@ static void b43_one_core_detach(struct ssb_device *dev) struct b43_wldev *wldev; struct b43_wl *wl; + /* Do not cancel ieee80211-workqueue based work here. + * See comment in b43_remove(). */ + wldev = ssb_get_drvdata(dev); wl = wldev->wl; - cancel_work_sync(&wldev->restart_work); b43_debugfs_remove_device(wldev); b43_wireless_core_detach(wldev); list_del(&wldev->list); @@ -4569,6 +4603,10 @@ static void b43_remove(struct ssb_device *dev) struct b43_wl *wl = ssb_get_devtypedata(dev); struct b43_wldev *wldev = ssb_get_drvdata(dev); + /* We must cancel any work here before unregistering from ieee80211, + * as the ieee80211 unreg will destroy the workqueue. */ + cancel_work_sync(&wldev->restart_work); + B43_WARN_ON(!wl); if (wl->current_dev == wldev) ieee80211_unregister_hw(wl->hw); diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c index c9847b1a67f..3a7f0cb710e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c @@ -1162,7 +1162,6 @@ static s32 rs_get_best_rate(struct iwl_priv *priv, /* Higher rate not available, use the original */ } else { - new_rate = rate; break; } } @@ -2009,7 +2008,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, * 2) Not just finishing up a search * 3) Allowing a new search */ - if (!update_lq && !done_search && !lq_sta->stay_in_tbl) { + if (!update_lq && !done_search && !lq_sta->stay_in_tbl && window->counter) { /* Save current throughput to compare with "search" throughput*/ lq_sta->last_tpt = current_tpt; diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index d0b1fb15c70..18c9931e326 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -116,6 +116,7 @@ MODULE_PARM_DESC(workaround_interval, #define OID_802_11_ENCRYPTION_STATUS ccpu2(0x0d01011b) #define OID_802_11_ADD_KEY ccpu2(0x0d01011d) #define OID_802_11_REMOVE_KEY ccpu2(0x0d01011e) +#define OID_802_11_ASSOCIATION_INFORMATION ccpu2(0x0d01011f) #define OID_802_11_PMKID ccpu2(0x0d010123) #define OID_802_11_NETWORK_TYPES_SUPPORTED ccpu2(0x0d010203) #define OID_802_11_NETWORK_TYPE_IN_USE ccpu2(0x0d010204) @@ -271,6 +272,26 @@ struct ndis_config_param { __le32 value_length; } __attribute__((packed)); +struct ndis_80211_assoc_info { + __le32 length; + __le16 req_ies; + struct req_ie { + __le16 capa; + __le16 listen_interval; + u8 cur_ap_address[6]; + } req_ie; + __le32 req_ie_length; + __le32 offset_req_ies; + __le16 resp_ies; + struct resp_ie { + __le16 capa; + __le16 status_code; + __le16 assoc_id; + } resp_ie; + __le32 resp_ie_length; + __le32 offset_resp_ies; +} __attribute__((packed)); + /* these have to match what is in wpa_supplicant */ enum wpa_alg { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP }; enum wpa_cipher { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP, @@ -674,6 +695,12 @@ static int get_bssid(struct usbnet *usbdev, u8 bssid[ETH_ALEN]) return ret; } +static int get_association_info(struct usbnet *usbdev, + struct ndis_80211_assoc_info *info, int len) +{ + return rndis_query_oid(usbdev, OID_802_11_ASSOCIATION_INFORMATION, + info, &len); +} static int is_associated(struct usbnet *usbdev) { @@ -2182,11 +2209,40 @@ static void rndis_wext_worker(struct work_struct *work) struct usbnet *usbdev = priv->usbdev; union iwreq_data evt; unsigned char bssid[ETH_ALEN]; - int ret; + struct ndis_80211_assoc_info *info; + int assoc_size = sizeof(*info) + IW_CUSTOM_MAX + 32; + int ret, offset; if (test_and_clear_bit(WORK_CONNECTION_EVENT, &priv->work_pending)) { - ret = get_bssid(usbdev, bssid); + info = kzalloc(assoc_size, GFP_KERNEL); + if (!info) + goto get_bssid; + /* Get association info IEs from device and send them back to + * userspace. */ + ret = get_association_info(usbdev, info, assoc_size); + if (!ret) { + evt.data.length = le32_to_cpu(info->req_ie_length); + if (evt.data.length > 0) { + offset = le32_to_cpu(info->offset_req_ies); + wireless_send_event(usbdev->net, + IWEVASSOCREQIE, &evt, + (char *)info + offset); + } + + evt.data.length = le32_to_cpu(info->resp_ie_length); + if (evt.data.length > 0) { + offset = le32_to_cpu(info->offset_resp_ies); + wireless_send_event(usbdev->net, + IWEVASSOCRESPIE, &evt, + (char *)info + offset); + } + } + + kfree(info); + +get_bssid: + ret = get_bssid(usbdev, bssid); if (!ret) { evt.data.flags = 0; evt.data.length = 0; @@ -2414,6 +2470,11 @@ static int bcm4320_early_init(struct usbnet *dev) else if (priv->param_power_save > 2) priv->param_power_save = 2; + if (priv->param_power_output < 0) + priv->param_power_output = 0; + else if (priv->param_power_output > 3) + priv->param_power_output = 3; + if (priv->param_roamtrigger < -80) priv->param_roamtrigger = -80; else if (priv->param_roamtrigger > -60) diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 57bdc153952..611d9832059 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h @@ -328,6 +328,11 @@ static inline int rt2x00_get_link_ant_rssi(struct link *link) return DEFAULT_RSSI; } +static inline void rt2x00_reset_link_ant_rssi(struct link *link) +{ + link->ant.rssi_ant = 0; +} + static inline int rt2x00_get_link_ant_rssi_history(struct link *link, enum antenna ant) { diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index a9930a03f45..48608e8cc8b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c @@ -129,6 +129,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, */ rt2x00dev->ops->lib->config(rt2x00dev, &libconf, CONFIG_UPDATE_ANTENNA); rt2x00lib_reset_link_tuner(rt2x00dev); + rt2x00_reset_link_ant_rssi(&rt2x00dev->link); rt2x00dev->link.ant.active.rx = libconf.ant.rx; rt2x00dev->link.ant.active.tx = libconf.ant.tx; diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index b22c0273718..2673d568bca 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -483,9 +483,9 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) return; - ieee80211_iterate_active_interfaces(rt2x00dev->hw, - rt2x00lib_beacondone_iter, - rt2x00dev); + ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw, + rt2x00lib_beacondone_iter, + rt2x00dev); queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work); } @@ -507,7 +507,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, * Update TX statistics. */ rt2x00dev->link.qual.tx_success += success; - rt2x00dev->link.qual.tx_failed += txdesc->retry + fail; + rt2x00dev->link.qual.tx_failed += fail; /* * Initialize TX status diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index c206b509207..87e280a2197 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -93,6 +93,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, */ if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) { ieee80211_stop_queues(hw); + dev_kfree_skb_any(skb); return NETDEV_TX_OK; } diff --git a/drivers/net/wireless/rtl8180_grf5101.c b/drivers/net/wireless/rtl8180_grf5101.c index 5d47935dbac..947ee55f18b 100644 --- a/drivers/net/wireless/rtl8180_grf5101.c +++ b/drivers/net/wireless/rtl8180_grf5101.c @@ -88,7 +88,7 @@ static void grf5101_rf_set_channel(struct ieee80211_hw *dev, write_grf5101(dev, 0x0B, chan); write_grf5101(dev, 0x07, 0x1000); - grf5101_write_phy_antenna(dev, chan); + grf5101_write_phy_antenna(dev, channel); } static void grf5101_rf_stop(struct ieee80211_hw *dev) diff --git a/drivers/net/wireless/rtl8180_max2820.c b/drivers/net/wireless/rtl8180_max2820.c index a34dfd382b6..6c825fd7f3b 100644 --- a/drivers/net/wireless/rtl8180_max2820.c +++ b/drivers/net/wireless/rtl8180_max2820.c @@ -78,7 +78,8 @@ static void max2820_rf_set_channel(struct ieee80211_hw *dev, struct ieee80211_conf *conf) { struct rtl8180_priv *priv = dev->priv; - int channel = ieee80211_frequency_to_channel(conf->channel->center_freq); + int channel = conf ? + ieee80211_frequency_to_channel(conf->channel->center_freq) : 1; unsigned int chan_idx = channel - 1; u32 txpw = priv->channels[chan_idx].hw_value & 0xFF; u32 chan = max2820_chan[chan_idx]; @@ -87,7 +88,7 @@ static void max2820_rf_set_channel(struct ieee80211_hw *dev, * sa2400, for MAXIM we do this directly from BB */ rtl8180_write_phy(dev, 3, txpw); - max2820_write_phy_antenna(dev, chan); + max2820_write_phy_antenna(dev, channel); write_max2820(dev, 3, chan); } diff --git a/drivers/net/wireless/rtl8180_sa2400.c b/drivers/net/wireless/rtl8180_sa2400.c index 0311b4ea124..cea4e0ccb92 100644 --- a/drivers/net/wireless/rtl8180_sa2400.c +++ b/drivers/net/wireless/rtl8180_sa2400.c @@ -86,7 +86,7 @@ static void sa2400_rf_set_channel(struct ieee80211_hw *dev, write_sa2400(dev, 7, txpw); - sa2400_write_phy_antenna(dev, chan); + sa2400_write_phy_antenna(dev, channel); write_sa2400(dev, 0, chan); write_sa2400(dev, 1, 0xbb50); diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index eb62558e9b0..0c2c93735e9 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -423,8 +423,8 @@ static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err) rfcomm_dlc_lock(d); d->state = BT_CLOSED; - rfcomm_dlc_unlock(d); d->state_change(d, err); + rfcomm_dlc_unlock(d); skb_queue_purge(&d->tx_queue); rfcomm_dlc_unlink(d); diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index cd61dea2eea..f813077234b 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c @@ -193,22 +193,17 @@ static inline void ccid3_hc_tx_update_s(struct ccid3_hc_tx_sock *hctx, int len) /* * Update Window Counter using the algorithm from [RFC 4342, 8.1]. - * The algorithm is not applicable if RTT < 4 microseconds. + * As elsewhere, RTT > 0 is assumed by using dccp_sample_rtt(). */ static inline void ccid3_hc_tx_update_win_count(struct ccid3_hc_tx_sock *hctx, ktime_t now) { - u32 quarter_rtts; - - if (unlikely(hctx->ccid3hctx_rtt < 4)) /* avoid divide-by-zero */ - return; - - quarter_rtts = ktime_us_delta(now, hctx->ccid3hctx_t_last_win_count); - quarter_rtts /= hctx->ccid3hctx_rtt / 4; + u32 delta = ktime_us_delta(now, hctx->ccid3hctx_t_last_win_count), + quarter_rtts = (4 * delta) / hctx->ccid3hctx_rtt; if (quarter_rtts > 0) { hctx->ccid3hctx_t_last_win_count = now; - hctx->ccid3hctx_last_win_count += min_t(u32, quarter_rtts, 5); + hctx->ccid3hctx_last_win_count += min(quarter_rtts, 5U); hctx->ccid3hctx_last_win_count &= 0xF; /* mod 16 */ } } diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index b348dd70c68..c22a3780c14 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c @@ -739,8 +739,8 @@ int dccp_invalid_packet(struct sk_buff *skb) * If P.type is not Data, Ack, or DataAck and P.X == 0 (the packet * has short sequence numbers), drop packet and return */ - if (dh->dccph_type >= DCCP_PKT_DATA && - dh->dccph_type <= DCCP_PKT_DATAACK && dh->dccph_x == 0) { + if ((dh->dccph_type < DCCP_PKT_DATA || + dh->dccph_type > DCCP_PKT_DATAACK) && dh->dccph_x == 0) { DCCP_WARN("P.type (%s) not Data || [Data]Ack, while P.X == 0\n", dccp_packet_name(dh->dccph_type)); return 1; diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c index e2ddde75501..008de1fc42c 100644 --- a/net/llc/llc_sap.c +++ b/net/llc/llc_sap.c @@ -286,12 +286,14 @@ void llc_build_and_send_xid_pkt(struct llc_sap *sap, struct sk_buff *skb, * * Sends received pdus to the sap state machine. */ -static void llc_sap_rcv(struct llc_sap *sap, struct sk_buff *skb) +static void llc_sap_rcv(struct llc_sap *sap, struct sk_buff *skb, + struct sock *sk) { struct llc_sap_state_ev *ev = llc_sap_ev(skb); ev->type = LLC_SAP_EV_TYPE_PDU; ev->reason = 0; + skb->sk = sk; llc_sap_state_process(sap, skb); } @@ -360,8 +362,7 @@ static void llc_sap_mcast(struct llc_sap *sap, break; sock_hold(sk); - skb_set_owner_r(skb1, sk); - llc_sap_rcv(sap, skb1); + llc_sap_rcv(sap, skb1, sk); sock_put(sk); } read_unlock_bh(&sap->sk_list.lock); @@ -381,8 +382,7 @@ void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb) } else { struct sock *sk = llc_lookup_dgram(sap, &laddr); if (sk) { - skb_set_owner_r(skb, sk); - llc_sap_rcv(sap, skb); + llc_sap_rcv(sap, skb, sk); sock_put(sk); } else kfree_skb(skb); diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 699d97b8de5..a9fce4afdf2 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -672,7 +672,7 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, if (params->vlan) { sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); - if (sdata->vif.type != IEEE80211_IF_TYPE_VLAN || + if (sdata->vif.type != IEEE80211_IF_TYPE_VLAN && sdata->vif.type != IEEE80211_IF_TYPE_AP) return -EINVAL; } else @@ -760,7 +760,7 @@ static int ieee80211_change_station(struct wiphy *wiphy, if (params->vlan && params->vlan != sta->sdata->dev) { vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); - if (vlansdata->vif.type != IEEE80211_IF_TYPE_VLAN || + if (vlansdata->vif.type != IEEE80211_IF_TYPE_VLAN && vlansdata->vif.type != IEEE80211_IF_TYPE_AP) { rcu_read_unlock(); return -EINVAL; diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 915afadb060..5c876450b14 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -1313,7 +1313,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, /* * Clear the TX filter mask for this STA when sending the next * packet. If the STA went to power save mode, this will happen - * happen when it wakes up for the next time. + * when it wakes up for the next time. */ sta->flags |= WLAN_STA_CLEAR_PS_FILT; diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 7cfd12e0d1e..841278f1df8 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1325,7 +1325,7 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev, /* prepare reordering buffer */ tid_agg_rx->reorder_buf = - kmalloc(buf_size * sizeof(struct sk_buf *), GFP_ATOMIC); + kmalloc(buf_size * sizeof(struct sk_buff *), GFP_ATOMIC); if (!tid_agg_rx->reorder_buf) { if (net_ratelimit()) printk(KERN_ERR "can not allocate reordering buffer " @@ -1334,7 +1334,7 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev, goto end; } memset(tid_agg_rx->reorder_buf, 0, - buf_size * sizeof(struct sk_buf *)); + buf_size * sizeof(struct sk_buff *)); if (local->ops->ampdu_action) ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_START, @@ -1614,7 +1614,7 @@ void sta_addba_resp_timer_expired(unsigned long data) * only one argument, and both sta_info and TID are needed, so init * flow in sta_info_create gives the TID as data, while the timer_to_id * array gives the sta through container_of */ - u16 tid = *(int *)data; + u16 tid = *(u8 *)data; struct sta_info *temp_sta = container_of((void *)data, struct sta_info, timer_to_tid[tid]); @@ -1662,7 +1662,7 @@ timer_expired_exit: void sta_rx_agg_session_timer_expired(unsigned long data) { /* not an elegant detour, but there is no choice as the timer passes - * only one argument, and verious sta_info are needed here, so init + * only one argument, and various sta_info are needed here, so init * flow in sta_info_create gives the TID as data, while the timer_to_id * array gives the sta through container_of */ u8 *ptid = (u8 *)data; @@ -2479,8 +2479,6 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, ifsta->state = IEEE80211_IBSS_JOINED; mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); - ieee80211_rx_bss_put(dev, bss); - return res; } @@ -3523,6 +3521,7 @@ static int ieee80211_sta_create_ibss(struct net_device *dev, struct ieee80211_supported_band *sband; u8 bssid[ETH_ALEN], *pos; int i; + int ret; DECLARE_MAC_BUF(mac); #if 0 @@ -3567,7 +3566,9 @@ static int ieee80211_sta_create_ibss(struct net_device *dev, *pos++ = (u8) (rate / 5); } - return ieee80211_sta_join_ibss(dev, ifsta, bss); + ret = ieee80211_sta_join_ibss(dev, ifsta, bss); + ieee80211_rx_bss_put(dev, bss); + return ret; } @@ -3615,10 +3616,13 @@ static int ieee80211_sta_find_ibss(struct net_device *dev, (bss = ieee80211_rx_bss_get(dev, bssid, local->hw.conf.channel->center_freq, ifsta->ssid, ifsta->ssid_len))) { + int ret; printk(KERN_DEBUG "%s: Selected IBSS BSSID %s" " based on configured SSID\n", dev->name, print_mac(mac, bssid)); - return ieee80211_sta_join_ibss(dev, ifsta, bss); + ret = ieee80211_sta_join_ibss(dev, ifsta, bss); + ieee80211_rx_bss_put(dev, bss); + return ret; } #ifdef CONFIG_MAC80211_IBSS_DEBUG printk(KERN_DEBUG " did not try to join ibss\n"); @@ -4093,13 +4097,6 @@ ieee80211_sta_scan_result(struct net_device *dev, IW_EV_UINT_LEN); } - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWFREQ; - iwe.u.freq.m = bss->freq; - iwe.u.freq.e = 6; - current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, - IW_EV_FREQ_LEN); - memset(&iwe, 0, sizeof(iwe)); iwe.cmd = SIOCGIWFREQ; iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq); @@ -4108,6 +4105,12 @@ ieee80211_sta_scan_result(struct net_device *dev, IW_EV_FREQ_LEN); memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWFREQ; + iwe.u.freq.m = bss->freq; + iwe.u.freq.e = 6; + current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, + IW_EV_FREQ_LEN); + memset(&iwe, 0, sizeof(iwe)); iwe.cmd = IWEVQUAL; iwe.u.qual.qual = bss->signal; iwe.u.qual.level = bss->rssi; diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 1958bfb361c..0941e5d6a52 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1091,7 +1091,7 @@ ieee80211_data_to_8023(struct ieee80211_rx_data *rx) u16 fc, hdrlen, ethertype; u8 *payload; u8 dst[ETH_ALEN]; - u8 src[ETH_ALEN]; + u8 src[ETH_ALEN] __aligned(2); struct sk_buff *skb = rx->skb; struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); DECLARE_MAC_BUF(mac); @@ -1234,7 +1234,7 @@ ieee80211_data_to_8023(struct ieee80211_rx_data *rx) */ static bool ieee80211_frame_allowed(struct ieee80211_rx_data *rx) { - static const u8 pae_group_addr[ETH_ALEN] + static const u8 pae_group_addr[ETH_ALEN] __aligned(2) = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x03 }; struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data; diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 131e9e6c8a3..4e97b266f90 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -34,11 +34,11 @@ void *mac80211_wiphy_privid = &mac80211_wiphy_privid; /* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */ /* Ethernet-II snap header (RFC1042 for most EtherTypes) */ -const unsigned char rfc1042_header[] = +const unsigned char rfc1042_header[] __aligned(2) = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; /* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */ -const unsigned char bridge_tunnel_header[] = +const unsigned char bridge_tunnel_header[] __aligned(2) = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index 457ebf9e85a..8311bb24f9f 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c @@ -489,9 +489,14 @@ static int ieee80211_ioctl_giwap(struct net_device *dev, sdata = IEEE80211_DEV_TO_SUB_IF(dev); if (sdata->vif.type == IEEE80211_IF_TYPE_STA || sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { - ap_addr->sa_family = ARPHRD_ETHER; - memcpy(&ap_addr->sa_data, sdata->u.sta.bssid, ETH_ALEN); - return 0; + if (sdata->u.sta.state == IEEE80211_ASSOCIATED) { + ap_addr->sa_family = ARPHRD_ETHER; + memcpy(&ap_addr->sa_data, sdata->u.sta.bssid, ETH_ALEN); + return 0; + } else { + memset(&ap_addr->sa_data, 0, ETH_ALEN); + return 0; + } } else if (sdata->vif.type == IEEE80211_IF_TYPE_WDS) { ap_addr->sa_family = ARPHRD_ETHER; memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN); diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c index e31beeb33b2..e8f0dead267 100644 --- a/net/netfilter/nf_conntrack_expect.c +++ b/net/netfilter/nf_conntrack_expect.c @@ -587,10 +587,10 @@ int __init nf_conntrack_expect_init(void) return 0; err3: + kmem_cache_destroy(nf_ct_expect_cachep); +err2: nf_ct_free_hashtable(nf_ct_expect_hash, nf_ct_expect_vmalloc, nf_ct_expect_hsize); -err2: - kmem_cache_destroy(nf_ct_expect_cachep); err1: return err; }