Loading drivers/net/wireless/ath/ath9k/xmit.c +8 −2 Original line number Diff line number Diff line Loading @@ -312,6 +312,7 @@ static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc) } bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list); bf->bf_next = NULL; list_del(&bf->list); spin_unlock_bh(&sc->tx.txbuflock); Loading Loading @@ -393,7 +394,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0, seq_first; u32 ba[WME_BA_BMP_SIZE >> 5]; int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; bool rc_update = true; bool rc_update = true, isba; struct ieee80211_tx_rate rates[4]; struct ath_frame_info *fi; int nframes; Loading Loading @@ -437,13 +438,17 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; tid = ATH_AN_2_TID(an, tidno); seq_first = tid->seq_start; isba = ts->ts_flags & ATH9K_TX_BA; /* * The hardware occasionally sends a tx status for the wrong TID. * In this case, the BA status cannot be considered valid and all * subframes need to be retransmitted * * Only BlockAcks have a TID and therefore normal Acks cannot be * checked */ if (tidno != ts->tid) if (isba && tidno != ts->tid) txok = false; isaggr = bf_isaggr(bf); Loading Loading @@ -1774,6 +1779,7 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, list_add_tail(&bf->list, &bf_head); bf->bf_state.bf_type = 0; bf->bf_next = NULL; bf->bf_lastbf = bf; ath_tx_fill_desc(sc, bf, txq, fi->framelen); ath_tx_txqaddbuf(sc, txq, &bf_head, false); Loading drivers/net/wireless/rt2x00/rt2800lib.c +1 −1 Original line number Diff line number Diff line Loading @@ -2449,7 +2449,7 @@ static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev) /* * Check if temperature compensation is supported. */ if (tssi_bounds[4] == 0xff) if (tssi_bounds[4] == 0xff || step == 0xff) return 0; /* Loading include/net/cfg80211.h +9 −0 Original line number Diff line number Diff line Loading @@ -2651,6 +2651,15 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb); */ unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc); /** * ieee80211_get_mesh_hdrlen - get mesh extension header length * @meshhdr: the mesh extension header, only the flags field * (first byte) will be accessed * Returns the length of the extension header, which is always at * least 6 bytes and at most 18 if address 5 and 6 are present. */ unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr); /** * DOC: Data path helpers * Loading net/mac80211/ibss.c +1 −1 Original line number Diff line number Diff line Loading @@ -1108,7 +1108,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; sdata->u.ibss.ibss_join_req = jiffies; memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN); memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len); sdata->u.ibss.ssid_len = params->ssid_len; mutex_unlock(&sdata->u.ibss.mtx); Loading net/mac80211/rx.c +56 −18 Original line number Diff line number Diff line Loading @@ -531,6 +531,11 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) if (ieee80211_is_action(hdr->frame_control)) { u8 category; /* make sure category field is present */ if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE) return RX_DROP_MONITOR; mgmt = (struct ieee80211_mgmt *)hdr; category = mgmt->u.action.category; if (category != WLAN_CATEGORY_MESH_ACTION && Loading Loading @@ -883,14 +888,16 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) */ if (rx->sta && rx->sdata->vif.type == NL80211_IFTYPE_STATION && ieee80211_is_data_present(hdr->frame_control)) { u16 ethertype; u8 *payload; payload = rx->skb->data + ieee80211_hdrlen(hdr->frame_control); ethertype = (payload[6] << 8) | payload[7]; if (cpu_to_be16(ethertype) == rx->sdata->control_port_protocol) unsigned int hdrlen; __be16 ethertype; hdrlen = ieee80211_hdrlen(hdr->frame_control); if (rx->skb->len < hdrlen + 8) return RX_DROP_MONITOR; skb_copy_bits(rx->skb, hdrlen + 6, ðertype, 2); if (ethertype == rx->sdata->control_port_protocol) return RX_CONTINUE; } Loading Loading @@ -1462,11 +1469,14 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) hdr = (struct ieee80211_hdr *)rx->skb->data; fc = hdr->frame_control; if (ieee80211_is_ctl(fc)) return RX_CONTINUE; sc = le16_to_cpu(hdr->seq_ctrl); frag = sc & IEEE80211_SCTL_FRAG; if (likely((!ieee80211_has_morefrags(fc) && frag == 0) || (rx->skb)->len < 24 || is_multicast_ether_addr(hdr->addr1))) { /* not fragmented */ goto out; Loading Loading @@ -1889,6 +1899,20 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) hdr = (struct ieee80211_hdr *) skb->data; hdrlen = ieee80211_hdrlen(hdr->frame_control); /* make sure fixed part of mesh header is there, also checks skb len */ if (!pskb_may_pull(rx->skb, hdrlen + 6)) return RX_DROP_MONITOR; mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); /* make sure full mesh header is there, also checks skb len */ if (!pskb_may_pull(rx->skb, hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr))) return RX_DROP_MONITOR; /* reload pointers */ hdr = (struct ieee80211_hdr *) skb->data; mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); /* frame is in RMC, don't forward */ Loading @@ -1897,7 +1921,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) mesh_rmc_check(hdr->addr3, mesh_hdr, rx->sdata)) return RX_DROP_MONITOR; if (!ieee80211_is_data(hdr->frame_control)) if (!ieee80211_is_data(hdr->frame_control) || !(status->rx_flags & IEEE80211_RX_RA_MATCH)) return RX_CONTINUE; if (!mesh_hdr->ttl) Loading @@ -1911,9 +1936,12 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) if (is_multicast_ether_addr(hdr->addr1)) { mpp_addr = hdr->addr3; proxied_addr = mesh_hdr->eaddr1; } else { } else if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6) { /* has_a4 already checked in ieee80211_rx_mesh_check */ mpp_addr = hdr->addr4; proxied_addr = mesh_hdr->eaddr2; } else { return RX_DROP_MONITOR; } rcu_read_lock(); Loading Loading @@ -1941,12 +1969,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) } skb_set_queue_mapping(skb, q); if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) goto out; if (!--mesh_hdr->ttl) { IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl); return RX_DROP_MONITOR; goto out; } if (!ifmsh->mshcfg.dot11MeshForwarding) Loading Loading @@ -2353,6 +2378,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) } break; case WLAN_CATEGORY_SELF_PROTECTED: if (len < (IEEE80211_MIN_ACTION_SIZE + sizeof(mgmt->u.action.u.self_prot.action_code))) break; switch (mgmt->u.action.u.self_prot.action_code) { case WLAN_SP_MESH_PEERING_OPEN: case WLAN_SP_MESH_PEERING_CLOSE: Loading @@ -2371,6 +2400,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) } break; case WLAN_CATEGORY_MESH_ACTION: if (len < (IEEE80211_MIN_ACTION_SIZE + sizeof(mgmt->u.action.u.mesh_action.action_code))) break; if (!ieee80211_vif_is_mesh(&sdata->vif)) break; if (mesh_action_is_path_sel(mgmt) && Loading Loading @@ -2913,10 +2946,15 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc)) local->dot11ReceivedFragmentCount++; if (ieee80211_is_mgmt(fc)) err = skb_linearize(skb); if (ieee80211_is_mgmt(fc)) { /* drop frame if too short for header */ if (skb->len < ieee80211_hdrlen(fc)) err = -ENOBUFS; else err = skb_linearize(skb); } else { err = !pskb_may_pull(skb, ieee80211_hdrlen(fc)); } if (err) { dev_kfree_skb(skb); Loading Loading
drivers/net/wireless/ath/ath9k/xmit.c +8 −2 Original line number Diff line number Diff line Loading @@ -312,6 +312,7 @@ static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc) } bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list); bf->bf_next = NULL; list_del(&bf->list); spin_unlock_bh(&sc->tx.txbuflock); Loading Loading @@ -393,7 +394,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0, seq_first; u32 ba[WME_BA_BMP_SIZE >> 5]; int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; bool rc_update = true; bool rc_update = true, isba; struct ieee80211_tx_rate rates[4]; struct ath_frame_info *fi; int nframes; Loading Loading @@ -437,13 +438,17 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; tid = ATH_AN_2_TID(an, tidno); seq_first = tid->seq_start; isba = ts->ts_flags & ATH9K_TX_BA; /* * The hardware occasionally sends a tx status for the wrong TID. * In this case, the BA status cannot be considered valid and all * subframes need to be retransmitted * * Only BlockAcks have a TID and therefore normal Acks cannot be * checked */ if (tidno != ts->tid) if (isba && tidno != ts->tid) txok = false; isaggr = bf_isaggr(bf); Loading Loading @@ -1774,6 +1779,7 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, list_add_tail(&bf->list, &bf_head); bf->bf_state.bf_type = 0; bf->bf_next = NULL; bf->bf_lastbf = bf; ath_tx_fill_desc(sc, bf, txq, fi->framelen); ath_tx_txqaddbuf(sc, txq, &bf_head, false); Loading
drivers/net/wireless/rt2x00/rt2800lib.c +1 −1 Original line number Diff line number Diff line Loading @@ -2449,7 +2449,7 @@ static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev) /* * Check if temperature compensation is supported. */ if (tssi_bounds[4] == 0xff) if (tssi_bounds[4] == 0xff || step == 0xff) return 0; /* Loading
include/net/cfg80211.h +9 −0 Original line number Diff line number Diff line Loading @@ -2651,6 +2651,15 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb); */ unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc); /** * ieee80211_get_mesh_hdrlen - get mesh extension header length * @meshhdr: the mesh extension header, only the flags field * (first byte) will be accessed * Returns the length of the extension header, which is always at * least 6 bytes and at most 18 if address 5 and 6 are present. */ unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr); /** * DOC: Data path helpers * Loading
net/mac80211/ibss.c +1 −1 Original line number Diff line number Diff line Loading @@ -1108,7 +1108,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; sdata->u.ibss.ibss_join_req = jiffies; memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN); memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len); sdata->u.ibss.ssid_len = params->ssid_len; mutex_unlock(&sdata->u.ibss.mtx); Loading
net/mac80211/rx.c +56 −18 Original line number Diff line number Diff line Loading @@ -531,6 +531,11 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) if (ieee80211_is_action(hdr->frame_control)) { u8 category; /* make sure category field is present */ if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE) return RX_DROP_MONITOR; mgmt = (struct ieee80211_mgmt *)hdr; category = mgmt->u.action.category; if (category != WLAN_CATEGORY_MESH_ACTION && Loading Loading @@ -883,14 +888,16 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) */ if (rx->sta && rx->sdata->vif.type == NL80211_IFTYPE_STATION && ieee80211_is_data_present(hdr->frame_control)) { u16 ethertype; u8 *payload; payload = rx->skb->data + ieee80211_hdrlen(hdr->frame_control); ethertype = (payload[6] << 8) | payload[7]; if (cpu_to_be16(ethertype) == rx->sdata->control_port_protocol) unsigned int hdrlen; __be16 ethertype; hdrlen = ieee80211_hdrlen(hdr->frame_control); if (rx->skb->len < hdrlen + 8) return RX_DROP_MONITOR; skb_copy_bits(rx->skb, hdrlen + 6, ðertype, 2); if (ethertype == rx->sdata->control_port_protocol) return RX_CONTINUE; } Loading Loading @@ -1462,11 +1469,14 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) hdr = (struct ieee80211_hdr *)rx->skb->data; fc = hdr->frame_control; if (ieee80211_is_ctl(fc)) return RX_CONTINUE; sc = le16_to_cpu(hdr->seq_ctrl); frag = sc & IEEE80211_SCTL_FRAG; if (likely((!ieee80211_has_morefrags(fc) && frag == 0) || (rx->skb)->len < 24 || is_multicast_ether_addr(hdr->addr1))) { /* not fragmented */ goto out; Loading Loading @@ -1889,6 +1899,20 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) hdr = (struct ieee80211_hdr *) skb->data; hdrlen = ieee80211_hdrlen(hdr->frame_control); /* make sure fixed part of mesh header is there, also checks skb len */ if (!pskb_may_pull(rx->skb, hdrlen + 6)) return RX_DROP_MONITOR; mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); /* make sure full mesh header is there, also checks skb len */ if (!pskb_may_pull(rx->skb, hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr))) return RX_DROP_MONITOR; /* reload pointers */ hdr = (struct ieee80211_hdr *) skb->data; mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); /* frame is in RMC, don't forward */ Loading @@ -1897,7 +1921,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) mesh_rmc_check(hdr->addr3, mesh_hdr, rx->sdata)) return RX_DROP_MONITOR; if (!ieee80211_is_data(hdr->frame_control)) if (!ieee80211_is_data(hdr->frame_control) || !(status->rx_flags & IEEE80211_RX_RA_MATCH)) return RX_CONTINUE; if (!mesh_hdr->ttl) Loading @@ -1911,9 +1936,12 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) if (is_multicast_ether_addr(hdr->addr1)) { mpp_addr = hdr->addr3; proxied_addr = mesh_hdr->eaddr1; } else { } else if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6) { /* has_a4 already checked in ieee80211_rx_mesh_check */ mpp_addr = hdr->addr4; proxied_addr = mesh_hdr->eaddr2; } else { return RX_DROP_MONITOR; } rcu_read_lock(); Loading Loading @@ -1941,12 +1969,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) } skb_set_queue_mapping(skb, q); if (!(status->rx_flags & IEEE80211_RX_RA_MATCH)) goto out; if (!--mesh_hdr->ttl) { IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl); return RX_DROP_MONITOR; goto out; } if (!ifmsh->mshcfg.dot11MeshForwarding) Loading Loading @@ -2353,6 +2378,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) } break; case WLAN_CATEGORY_SELF_PROTECTED: if (len < (IEEE80211_MIN_ACTION_SIZE + sizeof(mgmt->u.action.u.self_prot.action_code))) break; switch (mgmt->u.action.u.self_prot.action_code) { case WLAN_SP_MESH_PEERING_OPEN: case WLAN_SP_MESH_PEERING_CLOSE: Loading @@ -2371,6 +2400,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) } break; case WLAN_CATEGORY_MESH_ACTION: if (len < (IEEE80211_MIN_ACTION_SIZE + sizeof(mgmt->u.action.u.mesh_action.action_code))) break; if (!ieee80211_vif_is_mesh(&sdata->vif)) break; if (mesh_action_is_path_sel(mgmt) && Loading Loading @@ -2913,10 +2946,15 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc)) local->dot11ReceivedFragmentCount++; if (ieee80211_is_mgmt(fc)) err = skb_linearize(skb); if (ieee80211_is_mgmt(fc)) { /* drop frame if too short for header */ if (skb->len < ieee80211_hdrlen(fc)) err = -ENOBUFS; else err = skb_linearize(skb); } else { err = !pskb_may_pull(skb, ieee80211_hdrlen(fc)); } if (err) { dev_kfree_skb(skb); Loading