diff options
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r-- | net/mac80211/tx.c | 45 |
1 files changed, 37 insertions, 8 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index bfaa43e096d2..2f3345c5f7cf 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1051,7 +1051,10 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata, | |||
1051 | 1051 | ||
1052 | hdr = (struct ieee80211_hdr *) skb->data; | 1052 | hdr = (struct ieee80211_hdr *) skb->data; |
1053 | 1053 | ||
1054 | tx->sta = sta_info_get(local, hdr->addr1); | 1054 | if ((sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && sdata->use_4addr) |
1055 | tx->sta = rcu_dereference(sdata->u.vlan.sta); | ||
1056 | if (!tx->sta) | ||
1057 | tx->sta = sta_info_get(local, hdr->addr1); | ||
1055 | 1058 | ||
1056 | if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) && | 1059 | if (tx->sta && ieee80211_is_data_qos(hdr->frame_control) && |
1057 | (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)) { | 1060 | (local->hw.flags & IEEE80211_HW_AMPDU_AGGREGATION)) { |
@@ -1613,7 +1616,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1613 | const u8 *encaps_data; | 1616 | const u8 *encaps_data; |
1614 | int encaps_len, skip_header_bytes; | 1617 | int encaps_len, skip_header_bytes; |
1615 | int nh_pos, h_pos; | 1618 | int nh_pos, h_pos; |
1616 | struct sta_info *sta; | 1619 | struct sta_info *sta = NULL; |
1617 | u32 sta_flags = 0; | 1620 | u32 sta_flags = 0; |
1618 | 1621 | ||
1619 | if (unlikely(skb->len < ETH_HLEN)) { | 1622 | if (unlikely(skb->len < ETH_HLEN)) { |
@@ -1630,8 +1633,25 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1630 | fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA); | 1633 | fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA); |
1631 | 1634 | ||
1632 | switch (sdata->vif.type) { | 1635 | switch (sdata->vif.type) { |
1633 | case NL80211_IFTYPE_AP: | ||
1634 | case NL80211_IFTYPE_AP_VLAN: | 1636 | case NL80211_IFTYPE_AP_VLAN: |
1637 | rcu_read_lock(); | ||
1638 | if (sdata->use_4addr) | ||
1639 | sta = rcu_dereference(sdata->u.vlan.sta); | ||
1640 | if (sta) { | ||
1641 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); | ||
1642 | /* RA TA DA SA */ | ||
1643 | memcpy(hdr.addr1, sta->sta.addr, ETH_ALEN); | ||
1644 | memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); | ||
1645 | memcpy(hdr.addr3, skb->data, ETH_ALEN); | ||
1646 | memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); | ||
1647 | hdrlen = 30; | ||
1648 | sta_flags = get_sta_flags(sta); | ||
1649 | } | ||
1650 | rcu_read_unlock(); | ||
1651 | if (sta) | ||
1652 | break; | ||
1653 | /* fall through */ | ||
1654 | case NL80211_IFTYPE_AP: | ||
1635 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS); | 1655 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS); |
1636 | /* DA BSSID SA */ | 1656 | /* DA BSSID SA */ |
1637 | memcpy(hdr.addr1, skb->data, ETH_ALEN); | 1657 | memcpy(hdr.addr1, skb->data, ETH_ALEN); |
@@ -1705,12 +1725,21 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1705 | break; | 1725 | break; |
1706 | #endif | 1726 | #endif |
1707 | case NL80211_IFTYPE_STATION: | 1727 | case NL80211_IFTYPE_STATION: |
1708 | fc |= cpu_to_le16(IEEE80211_FCTL_TODS); | ||
1709 | /* BSSID SA DA */ | ||
1710 | memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN); | 1728 | memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN); |
1711 | memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); | 1729 | if (sdata->use_4addr && ethertype != ETH_P_PAE) { |
1712 | memcpy(hdr.addr3, skb->data, ETH_ALEN); | 1730 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); |
1713 | hdrlen = 24; | 1731 | /* RA TA DA SA */ |
1732 | memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); | ||
1733 | memcpy(hdr.addr3, skb->data, ETH_ALEN); | ||
1734 | memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); | ||
1735 | hdrlen = 30; | ||
1736 | } else { | ||
1737 | fc |= cpu_to_le16(IEEE80211_FCTL_TODS); | ||
1738 | /* BSSID SA DA */ | ||
1739 | memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); | ||
1740 | memcpy(hdr.addr3, skb->data, ETH_ALEN); | ||
1741 | hdrlen = 24; | ||
1742 | } | ||
1714 | break; | 1743 | break; |
1715 | case NL80211_IFTYPE_ADHOC: | 1744 | case NL80211_IFTYPE_ADHOC: |
1716 | /* DA SA BSSID */ | 1745 | /* DA SA BSSID */ |