diff options
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r-- | net/mac80211/tx.c | 45 |
1 files changed, 19 insertions, 26 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 3ad053f6de12..943def2b07df 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1051,7 +1051,7 @@ 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 | if ((sdata->vif.type == NL80211_IFTYPE_AP_VLAN) && sdata->use_4addr) | 1054 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) |
1055 | tx->sta = rcu_dereference(sdata->u.vlan.sta); | 1055 | tx->sta = rcu_dereference(sdata->u.vlan.sta); |
1056 | if (!tx->sta) | 1056 | if (!tx->sta) |
1057 | tx->sta = sta_info_get(local, hdr->addr1); | 1057 | tx->sta = sta_info_get(local, hdr->addr1); |
@@ -1219,7 +1219,8 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) | |||
1219 | CALL_TXH(ieee80211_tx_h_ps_buf); | 1219 | CALL_TXH(ieee80211_tx_h_ps_buf); |
1220 | CALL_TXH(ieee80211_tx_h_select_key); | 1220 | CALL_TXH(ieee80211_tx_h_select_key); |
1221 | CALL_TXH(ieee80211_tx_h_michael_mic_add); | 1221 | CALL_TXH(ieee80211_tx_h_michael_mic_add); |
1222 | CALL_TXH(ieee80211_tx_h_rate_ctrl); | 1222 | if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)) |
1223 | CALL_TXH(ieee80211_tx_h_rate_ctrl); | ||
1223 | CALL_TXH(ieee80211_tx_h_misc); | 1224 | CALL_TXH(ieee80211_tx_h_misc); |
1224 | CALL_TXH(ieee80211_tx_h_sequence); | 1225 | CALL_TXH(ieee80211_tx_h_sequence); |
1225 | CALL_TXH(ieee80211_tx_h_fragment); | 1226 | CALL_TXH(ieee80211_tx_h_fragment); |
@@ -1430,8 +1431,6 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1430 | int headroom; | 1431 | int headroom; |
1431 | bool may_encrypt; | 1432 | bool may_encrypt; |
1432 | 1433 | ||
1433 | dev_hold(sdata->dev); | ||
1434 | |||
1435 | if (need_dynamic_ps(local)) { | 1434 | if (need_dynamic_ps(local)) { |
1436 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { | 1435 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { |
1437 | ieee80211_stop_queues_by_reason(&local->hw, | 1436 | ieee80211_stop_queues_by_reason(&local->hw, |
@@ -1444,7 +1443,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1444 | msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout)); | 1443 | msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout)); |
1445 | } | 1444 | } |
1446 | 1445 | ||
1447 | info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; | 1446 | rcu_read_lock(); |
1448 | 1447 | ||
1449 | if (unlikely(sdata->vif.type == NL80211_IFTYPE_MONITOR)) { | 1448 | if (unlikely(sdata->vif.type == NL80211_IFTYPE_MONITOR)) { |
1450 | int hdrlen; | 1449 | int hdrlen; |
@@ -1468,7 +1467,6 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1468 | * support we will need a different mechanism. | 1467 | * support we will need a different mechanism. |
1469 | */ | 1468 | */ |
1470 | 1469 | ||
1471 | rcu_read_lock(); | ||
1472 | list_for_each_entry_rcu(tmp_sdata, &local->interfaces, | 1470 | list_for_each_entry_rcu(tmp_sdata, &local->interfaces, |
1473 | list) { | 1471 | list) { |
1474 | if (!netif_running(tmp_sdata->dev)) | 1472 | if (!netif_running(tmp_sdata->dev)) |
@@ -1477,13 +1475,10 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1477 | continue; | 1475 | continue; |
1478 | if (compare_ether_addr(tmp_sdata->dev->dev_addr, | 1476 | if (compare_ether_addr(tmp_sdata->dev->dev_addr, |
1479 | hdr->addr2) == 0) { | 1477 | hdr->addr2) == 0) { |
1480 | dev_hold(tmp_sdata->dev); | ||
1481 | dev_put(sdata->dev); | ||
1482 | sdata = tmp_sdata; | 1478 | sdata = tmp_sdata; |
1483 | break; | 1479 | break; |
1484 | } | 1480 | } |
1485 | } | 1481 | } |
1486 | rcu_read_unlock(); | ||
1487 | } | 1482 | } |
1488 | } | 1483 | } |
1489 | 1484 | ||
@@ -1497,7 +1492,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1497 | 1492 | ||
1498 | if (ieee80211_skb_resize(local, skb, headroom, may_encrypt)) { | 1493 | if (ieee80211_skb_resize(local, skb, headroom, may_encrypt)) { |
1499 | dev_kfree_skb(skb); | 1494 | dev_kfree_skb(skb); |
1500 | dev_put(sdata->dev); | 1495 | rcu_read_unlock(); |
1501 | return; | 1496 | return; |
1502 | } | 1497 | } |
1503 | 1498 | ||
@@ -1508,13 +1503,13 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1508 | !is_multicast_ether_addr(hdr->addr1)) | 1503 | !is_multicast_ether_addr(hdr->addr1)) |
1509 | if (mesh_nexthop_lookup(skb, sdata)) { | 1504 | if (mesh_nexthop_lookup(skb, sdata)) { |
1510 | /* skb queued: don't free */ | 1505 | /* skb queued: don't free */ |
1511 | dev_put(sdata->dev); | 1506 | rcu_read_unlock(); |
1512 | return; | 1507 | return; |
1513 | } | 1508 | } |
1514 | 1509 | ||
1515 | ieee80211_select_queue(local, skb); | 1510 | ieee80211_select_queue(local, skb); |
1516 | ieee80211_tx(sdata, skb, false); | 1511 | ieee80211_tx(sdata, skb, false); |
1517 | dev_put(sdata->dev); | 1512 | rcu_read_unlock(); |
1518 | } | 1513 | } |
1519 | 1514 | ||
1520 | netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, | 1515 | netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, |
@@ -1578,6 +1573,8 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, | |||
1578 | 1573 | ||
1579 | memset(info, 0, sizeof(*info)); | 1574 | memset(info, 0, sizeof(*info)); |
1580 | 1575 | ||
1576 | info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; | ||
1577 | |||
1581 | /* pass the radiotap header up to xmit */ | 1578 | /* pass the radiotap header up to xmit */ |
1582 | ieee80211_xmit(IEEE80211_DEV_TO_SUB_IF(dev), skb); | 1579 | ieee80211_xmit(IEEE80211_DEV_TO_SUB_IF(dev), skb); |
1583 | return NETDEV_TX_OK; | 1580 | return NETDEV_TX_OK; |
@@ -1635,8 +1632,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1635 | switch (sdata->vif.type) { | 1632 | switch (sdata->vif.type) { |
1636 | case NL80211_IFTYPE_AP_VLAN: | 1633 | case NL80211_IFTYPE_AP_VLAN: |
1637 | rcu_read_lock(); | 1634 | rcu_read_lock(); |
1638 | if (sdata->use_4addr) | 1635 | sta = rcu_dereference(sdata->u.vlan.sta); |
1639 | sta = rcu_dereference(sdata->u.vlan.sta); | ||
1640 | if (sta) { | 1636 | if (sta) { |
1641 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); | 1637 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); |
1642 | /* RA TA DA SA */ | 1638 | /* RA TA DA SA */ |
@@ -1687,21 +1683,25 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1687 | /* packet from other interface */ | 1683 | /* packet from other interface */ |
1688 | struct mesh_path *mppath; | 1684 | struct mesh_path *mppath; |
1689 | int is_mesh_mcast = 1; | 1685 | int is_mesh_mcast = 1; |
1690 | char *mesh_da; | 1686 | const u8 *mesh_da; |
1691 | 1687 | ||
1692 | rcu_read_lock(); | 1688 | rcu_read_lock(); |
1693 | if (is_multicast_ether_addr(skb->data)) | 1689 | if (is_multicast_ether_addr(skb->data)) |
1694 | /* DA TA mSA AE:SA */ | 1690 | /* DA TA mSA AE:SA */ |
1695 | mesh_da = skb->data; | 1691 | mesh_da = skb->data; |
1696 | else { | 1692 | else { |
1693 | static const u8 bcast[ETH_ALEN] = | ||
1694 | { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; | ||
1695 | |||
1697 | mppath = mpp_path_lookup(skb->data, sdata); | 1696 | mppath = mpp_path_lookup(skb->data, sdata); |
1698 | if (mppath) { | 1697 | if (mppath) { |
1699 | /* RA TA mDA mSA AE:DA SA */ | 1698 | /* RA TA mDA mSA AE:DA SA */ |
1700 | mesh_da = mppath->mpp; | 1699 | mesh_da = mppath->mpp; |
1701 | is_mesh_mcast = 0; | 1700 | is_mesh_mcast = 0; |
1702 | } else | 1701 | } else { |
1703 | /* DA TA mSA AE:SA */ | 1702 | /* DA TA mSA AE:SA */ |
1704 | mesh_da = dev->broadcast; | 1703 | mesh_da = bcast; |
1704 | } | ||
1705 | } | 1705 | } |
1706 | hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, | 1706 | hdrlen = ieee80211_fill_mesh_addresses(&hdr, &fc, |
1707 | mesh_da, dev->dev_addr); | 1707 | mesh_da, dev->dev_addr); |
@@ -1726,7 +1726,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1726 | #endif | 1726 | #endif |
1727 | case NL80211_IFTYPE_STATION: | 1727 | case NL80211_IFTYPE_STATION: |
1728 | memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN); | 1728 | memcpy(hdr.addr1, sdata->u.mgd.bssid, ETH_ALEN); |
1729 | if (sdata->use_4addr && ethertype != ETH_P_PAE) { | 1729 | if (sdata->u.mgd.use_4addr && ethertype != ETH_P_PAE) { |
1730 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); | 1730 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); |
1731 | /* RA TA DA SA */ | 1731 | /* RA TA DA SA */ |
1732 | memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); | 1732 | memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); |
@@ -1964,12 +1964,10 @@ void ieee80211_tx_pending(unsigned long data) | |||
1964 | } | 1964 | } |
1965 | 1965 | ||
1966 | sdata = vif_to_sdata(info->control.vif); | 1966 | sdata = vif_to_sdata(info->control.vif); |
1967 | dev_hold(sdata->dev); | ||
1968 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, | 1967 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, |
1969 | flags); | 1968 | flags); |
1970 | 1969 | ||
1971 | txok = ieee80211_tx_pending_skb(local, skb); | 1970 | txok = ieee80211_tx_pending_skb(local, skb); |
1972 | dev_put(sdata->dev); | ||
1973 | if (!txok) | 1971 | if (!txok) |
1974 | __skb_queue_head(&local->pending[i], skb); | 1972 | __skb_queue_head(&local->pending[i], skb); |
1975 | spin_lock_irqsave(&local->queue_stop_reason_lock, | 1973 | spin_lock_irqsave(&local->queue_stop_reason_lock, |
@@ -2282,17 +2280,12 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, | |||
2282 | } | 2280 | } |
2283 | EXPORT_SYMBOL(ieee80211_get_buffered_bc); | 2281 | EXPORT_SYMBOL(ieee80211_get_buffered_bc); |
2284 | 2282 | ||
2285 | void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, | 2283 | void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) |
2286 | int encrypt) | ||
2287 | { | 2284 | { |
2288 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
2289 | skb_set_mac_header(skb, 0); | 2285 | skb_set_mac_header(skb, 0); |
2290 | skb_set_network_header(skb, 0); | 2286 | skb_set_network_header(skb, 0); |
2291 | skb_set_transport_header(skb, 0); | 2287 | skb_set_transport_header(skb, 0); |
2292 | 2288 | ||
2293 | if (!encrypt) | ||
2294 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | ||
2295 | |||
2296 | /* | 2289 | /* |
2297 | * The other path calling ieee80211_xmit is from the tasklet, | 2290 | * The other path calling ieee80211_xmit is from the tasklet, |
2298 | * and while we can handle concurrent transmissions locking | 2291 | * and while we can handle concurrent transmissions locking |