aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/tx.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r--net/mac80211/tx.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index c54db966926b..9d5af5dd0d98 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1694,7 +1694,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1694{ 1694{
1695 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1695 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1696 struct ieee80211_local *local = sdata->local; 1696 struct ieee80211_local *local = sdata->local;
1697 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1697 struct ieee80211_tx_info *info;
1698 int ret = NETDEV_TX_BUSY, head_need; 1698 int ret = NETDEV_TX_BUSY, head_need;
1699 u16 ethertype, hdrlen, meshhdrlen = 0; 1699 u16 ethertype, hdrlen, meshhdrlen = 0;
1700 __le16 fc; 1700 __le16 fc;
@@ -1705,15 +1705,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1705 int nh_pos, h_pos; 1705 int nh_pos, h_pos;
1706 struct sta_info *sta = NULL; 1706 struct sta_info *sta = NULL;
1707 u32 sta_flags = 0; 1707 u32 sta_flags = 0;
1708 struct sk_buff *tmp_skb;
1708 1709
1709 if (unlikely(skb->len < ETH_HLEN)) { 1710 if (unlikely(skb->len < ETH_HLEN)) {
1710 ret = NETDEV_TX_OK; 1711 ret = NETDEV_TX_OK;
1711 goto fail; 1712 goto fail;
1712 } 1713 }
1713 1714
1714 nh_pos = skb_network_header(skb) - skb->data;
1715 h_pos = skb_transport_header(skb) - skb->data;
1716
1717 /* convert Ethernet header to proper 802.11 header (based on 1715 /* convert Ethernet header to proper 802.11 header (based on
1718 * operation mode) */ 1716 * operation mode) */
1719 ethertype = (skb->data[12] << 8) | skb->data[13]; 1717 ethertype = (skb->data[12] << 8) | skb->data[13];
@@ -1885,6 +1883,20 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1885 goto fail; 1883 goto fail;
1886 } 1884 }
1887 1885
1886 /*
1887 * If the skb is shared we need to obtain our own copy.
1888 */
1889 if (skb_shared(skb)) {
1890 tmp_skb = skb;
1891 skb = skb_copy(skb, GFP_ATOMIC);
1892 kfree_skb(tmp_skb);
1893
1894 if (!skb) {
1895 ret = NETDEV_TX_OK;
1896 goto fail;
1897 }
1898 }
1899
1888 hdr.frame_control = fc; 1900 hdr.frame_control = fc;
1889 hdr.duration_id = 0; 1901 hdr.duration_id = 0;
1890 hdr.seq_ctrl = 0; 1902 hdr.seq_ctrl = 0;
@@ -1903,6 +1915,9 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1903 encaps_len = 0; 1915 encaps_len = 0;
1904 } 1916 }
1905 1917
1918 nh_pos = skb_network_header(skb) - skb->data;
1919 h_pos = skb_transport_header(skb) - skb->data;
1920
1906 skb_pull(skb, skip_header_bytes); 1921 skb_pull(skb, skip_header_bytes);
1907 nh_pos -= skip_header_bytes; 1922 nh_pos -= skip_header_bytes;
1908 h_pos -= skip_header_bytes; 1923 h_pos -= skip_header_bytes;
@@ -1969,6 +1984,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1969 skb_set_network_header(skb, nh_pos); 1984 skb_set_network_header(skb, nh_pos);
1970 skb_set_transport_header(skb, h_pos); 1985 skb_set_transport_header(skb, h_pos);
1971 1986
1987 info = IEEE80211_SKB_CB(skb);
1972 memset(info, 0, sizeof(*info)); 1988 memset(info, 0, sizeof(*info));
1973 1989
1974 dev->trans_start = jiffies; 1990 dev->trans_start = jiffies;
@@ -2160,6 +2176,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
2160 2176
2161 sdata = vif_to_sdata(vif); 2177 sdata = vif_to_sdata(vif);
2162 2178
2179 if (!ieee80211_sdata_running(sdata))
2180 goto out;
2181
2163 if (tim_offset) 2182 if (tim_offset)
2164 *tim_offset = 0; 2183 *tim_offset = 0;
2165 if (tim_length) 2184 if (tim_length)