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.c75
1 files changed, 54 insertions, 21 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 20d683641b42..0cc2e23f082c 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -165,11 +165,10 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr,
165 return cpu_to_le16(dur); 165 return cpu_to_le16(dur);
166} 166}
167 167
168static int inline is_ieee80211_device(struct net_device *dev, 168static int inline is_ieee80211_device(struct ieee80211_local *local,
169 struct net_device *master) 169 struct net_device *dev)
170{ 170{
171 return (wdev_priv(dev->ieee80211_ptr) == 171 return local == wdev_priv(dev->ieee80211_ptr);
172 wdev_priv(master->ieee80211_ptr));
173} 172}
174 173
175/* tx handlers */ 174/* tx handlers */
@@ -447,7 +446,8 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
447 sband = tx->local->hw.wiphy->bands[tx->channel->band]; 446 sband = tx->local->hw.wiphy->bands[tx->channel->band];
448 447
449 if (likely(tx->rate_idx < 0)) { 448 if (likely(tx->rate_idx < 0)) {
450 rate_control_get_rate(tx->dev, sband, tx->skb, &rsel); 449 rate_control_get_rate(tx->sdata, sband, tx->sta,
450 tx->skb, &rsel);
451 if (tx->sta) 451 if (tx->sta)
452 tx->sta->last_txrate_idx = rsel.rate_idx; 452 tx->sta->last_txrate_idx = rsel.rate_idx;
453 tx->rate_idx = rsel.rate_idx; 453 tx->rate_idx = rsel.rate_idx;
@@ -1001,14 +1001,14 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
1001/* 1001/*
1002 * NB: @tx is uninitialised when passed in here 1002 * NB: @tx is uninitialised when passed in here
1003 */ 1003 */
1004static int ieee80211_tx_prepare(struct ieee80211_tx_data *tx, 1004static int ieee80211_tx_prepare(struct ieee80211_local *local,
1005 struct sk_buff *skb, 1005 struct ieee80211_tx_data *tx,
1006 struct net_device *mdev) 1006 struct sk_buff *skb)
1007{ 1007{
1008 struct net_device *dev; 1008 struct net_device *dev;
1009 1009
1010 dev = dev_get_by_index(&init_net, skb->iif); 1010 dev = dev_get_by_index(&init_net, skb->iif);
1011 if (unlikely(dev && !is_ieee80211_device(dev, mdev))) { 1011 if (unlikely(dev && !is_ieee80211_device(local, dev))) {
1012 dev_put(dev); 1012 dev_put(dev);
1013 dev = NULL; 1013 dev = NULL;
1014 } 1014 }
@@ -1258,6 +1258,8 @@ static int ieee80211_skb_resize(struct ieee80211_local *local,
1258int ieee80211_master_start_xmit(struct sk_buff *skb, 1258int ieee80211_master_start_xmit(struct sk_buff *skb,
1259 struct net_device *dev) 1259 struct net_device *dev)
1260{ 1260{
1261 struct ieee80211_master_priv *mpriv = netdev_priv(dev);
1262 struct ieee80211_local *local = mpriv->local;
1261 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1263 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1262 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 1264 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1263 struct net_device *odev = NULL; 1265 struct net_device *odev = NULL;
@@ -1273,7 +1275,7 @@ int ieee80211_master_start_xmit(struct sk_buff *skb,
1273 1275
1274 if (skb->iif) 1276 if (skb->iif)
1275 odev = dev_get_by_index(&init_net, skb->iif); 1277 odev = dev_get_by_index(&init_net, skb->iif);
1276 if (unlikely(odev && !is_ieee80211_device(odev, dev))) { 1278 if (unlikely(odev && !is_ieee80211_device(local, odev))) {
1277 dev_put(odev); 1279 dev_put(odev);
1278 odev = NULL; 1280 odev = NULL;
1279 } 1281 }
@@ -1449,8 +1451,8 @@ fail:
1449int ieee80211_subif_start_xmit(struct sk_buff *skb, 1451int ieee80211_subif_start_xmit(struct sk_buff *skb,
1450 struct net_device *dev) 1452 struct net_device *dev)
1451{ 1453{
1452 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1454 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1453 struct ieee80211_sub_if_data *sdata; 1455 struct ieee80211_local *local = sdata->local;
1454 int ret = 1, head_need; 1456 int ret = 1, head_need;
1455 u16 ethertype, hdrlen, meshhdrlen = 0; 1457 u16 ethertype, hdrlen, meshhdrlen = 0;
1456 __le16 fc; 1458 __le16 fc;
@@ -1462,7 +1464,6 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1462 struct sta_info *sta; 1464 struct sta_info *sta;
1463 u32 sta_flags = 0; 1465 u32 sta_flags = 0;
1464 1466
1465 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1466 if (unlikely(skb->len < ETH_HLEN)) { 1467 if (unlikely(skb->len < ETH_HLEN)) {
1467 ret = 0; 1468 ret = 0;
1468 goto fail; 1469 goto fail;
@@ -1498,18 +1499,50 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1498#ifdef CONFIG_MAC80211_MESH 1499#ifdef CONFIG_MAC80211_MESH
1499 case NL80211_IFTYPE_MESH_POINT: 1500 case NL80211_IFTYPE_MESH_POINT:
1500 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); 1501 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS);
1501 /* RA TA DA SA */
1502 memset(hdr.addr1, 0, ETH_ALEN);
1503 memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN);
1504 memcpy(hdr.addr3, skb->data, ETH_ALEN);
1505 memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
1506 if (!sdata->u.mesh.mshcfg.dot11MeshTTL) { 1502 if (!sdata->u.mesh.mshcfg.dot11MeshTTL) {
1507 /* Do not send frames with mesh_ttl == 0 */ 1503 /* Do not send frames with mesh_ttl == 0 */
1508 sdata->u.mesh.mshstats.dropped_frames_ttl++; 1504 sdata->u.mesh.mshstats.dropped_frames_ttl++;
1509 ret = 0; 1505 ret = 0;
1510 goto fail; 1506 goto fail;
1511 } 1507 }
1512 meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, sdata); 1508 memset(&mesh_hdr, 0, sizeof(mesh_hdr));
1509
1510 if (compare_ether_addr(dev->dev_addr,
1511 skb->data + ETH_ALEN) == 0) {
1512 /* RA TA DA SA */
1513 memset(hdr.addr1, 0, ETH_ALEN);
1514 memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN);
1515 memcpy(hdr.addr3, skb->data, ETH_ALEN);
1516 memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
1517 meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, sdata);
1518 } else {
1519 /* packet from other interface */
1520 struct mesh_path *mppath;
1521
1522 memset(hdr.addr1, 0, ETH_ALEN);
1523 memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN);
1524 memcpy(hdr.addr4, dev->dev_addr, ETH_ALEN);
1525
1526 if (is_multicast_ether_addr(skb->data))
1527 memcpy(hdr.addr3, skb->data, ETH_ALEN);
1528 else {
1529 rcu_read_lock();
1530 mppath = mpp_path_lookup(skb->data, sdata);
1531 if (mppath)
1532 memcpy(hdr.addr3, mppath->mpp, ETH_ALEN);
1533 else
1534 memset(hdr.addr3, 0xff, ETH_ALEN);
1535 rcu_read_unlock();
1536 }
1537
1538 mesh_hdr.flags |= MESH_FLAGS_AE_A5_A6;
1539 mesh_hdr.ttl = sdata->u.mesh.mshcfg.dot11MeshTTL;
1540 put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &mesh_hdr.seqnum);
1541 memcpy(mesh_hdr.eaddr1, skb->data, ETH_ALEN);
1542 memcpy(mesh_hdr.eaddr2, skb->data + ETH_ALEN, ETH_ALEN);
1543 sdata->u.mesh.mesh_seqnum++;
1544 meshhdrlen = 18;
1545 }
1513 hdrlen = 30; 1546 hdrlen = 30;
1514 break; 1547 break;
1515#endif 1548#endif
@@ -1923,7 +1956,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
1923 skb->do_not_encrypt = 1; 1956 skb->do_not_encrypt = 1;
1924 1957
1925 info->band = band; 1958 info->band = band;
1926 rate_control_get_rate(local->mdev, sband, skb, &rsel); 1959 rate_control_get_rate(sdata, sband, NULL, skb, &rsel);
1927 1960
1928 if (unlikely(rsel.rate_idx < 0)) { 1961 if (unlikely(rsel.rate_idx < 0)) {
1929 if (net_ratelimit()) { 1962 if (net_ratelimit()) {
@@ -2032,7 +2065,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
2032 cpu_to_le16(IEEE80211_FCTL_MOREDATA); 2065 cpu_to_le16(IEEE80211_FCTL_MOREDATA);
2033 } 2066 }
2034 2067
2035 if (!ieee80211_tx_prepare(&tx, skb, local->mdev)) 2068 if (!ieee80211_tx_prepare(local, &tx, skb))
2036 break; 2069 break;
2037 dev_kfree_skb_any(skb); 2070 dev_kfree_skb_any(skb);
2038 } 2071 }