aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2007-07-10 13:32:08 -0400
committerJohn W. Linville <linville@tuxdriver.com>2007-07-12 16:07:25 -0400
commit40f7cac9f8dd662c1dd02334afdceef0be03e34f (patch)
tree6c8cedbfa99b67305d1b845d7a140a0a185981a6 /net/mac80211
parent333af2f0715c8d4d38cb657d8f4fb7c4e3ceba9f (diff)
[PATCH] mac80211: separate monitor/subif_start_xmit
This patch separates the monitor interface start_xmit from the subif start xmit (those other devices have 802.3 framing, monitor interfaces have radiotap framing) Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Jiri Benc <jbenc@suse.cz> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/ieee80211.c101
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/ieee80211_iface.c3
3 files changed, 58 insertions, 48 deletions
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index 4bcf18097e53..e91698308f31 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -1673,6 +1673,56 @@ static int ieee80211_master_start_xmit(struct sk_buff *skb,
1673} 1673}
1674 1674
1675 1675
1676int ieee80211_monitor_start_xmit(struct sk_buff *skb,
1677 struct net_device *dev)
1678{
1679 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1680 struct ieee80211_tx_packet_data *pkt_data;
1681 struct ieee80211_radiotap_header *prthdr =
1682 (struct ieee80211_radiotap_header *)skb->data;
1683 u16 len;
1684
1685 /*
1686 * there must be a radiotap header at the
1687 * start in this case
1688 */
1689 if (unlikely(prthdr->it_version)) {
1690 /* only version 0 is supported */
1691 dev_kfree_skb(skb);
1692 return NETDEV_TX_OK;
1693 }
1694
1695 skb->dev = local->mdev;
1696
1697 pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
1698 memset(pkt_data, 0, sizeof(*pkt_data));
1699 pkt_data->ifindex = dev->ifindex;
1700 pkt_data->mgmt_iface = 0;
1701 pkt_data->do_not_encrypt = 1;
1702
1703 /* above needed because we set skb device to master */
1704
1705 /*
1706 * fix up the pointers accounting for the radiotap
1707 * header still being in there. We are being given
1708 * a precooked IEEE80211 header so no need for
1709 * normal processing
1710 */
1711 len = le16_to_cpu(get_unaligned(&prthdr->it_len));
1712 skb_set_mac_header(skb, len);
1713 skb_set_network_header(skb, len + sizeof(struct ieee80211_hdr));
1714 skb_set_transport_header(skb, len + sizeof(struct ieee80211_hdr));
1715
1716 /*
1717 * pass the radiotap header up to
1718 * the next stage intact
1719 */
1720 dev_queue_xmit(skb);
1721
1722 return NETDEV_TX_OK;
1723}
1724
1725
1676/** 1726/**
1677 * ieee80211_subif_start_xmit - netif start_xmit function for Ethernet-type 1727 * ieee80211_subif_start_xmit - netif start_xmit function for Ethernet-type
1678 * subinterfaces (wlan#, WDS, and VLAN interfaces) 1728 * subinterfaces (wlan#, WDS, and VLAN interfaces)
@@ -1688,8 +1738,8 @@ static int ieee80211_master_start_xmit(struct sk_buff *skb,
1688 * encapsulated packet will then be passed to master interface, wlan#.11, for 1738 * encapsulated packet will then be passed to master interface, wlan#.11, for
1689 * transmission (through low-level driver). 1739 * transmission (through low-level driver).
1690 */ 1740 */
1691static int ieee80211_subif_start_xmit(struct sk_buff *skb, 1741int ieee80211_subif_start_xmit(struct sk_buff *skb,
1692 struct net_device *dev) 1742 struct net_device *dev)
1693{ 1743{
1694 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1744 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1695 struct ieee80211_tx_packet_data *pkt_data; 1745 struct ieee80211_tx_packet_data *pkt_data;
@@ -1710,51 +1760,6 @@ static int ieee80211_subif_start_xmit(struct sk_buff *skb,
1710 goto fail; 1760 goto fail;
1711 } 1761 }
1712 1762
1713 if (unlikely(sdata->type == IEEE80211_IF_TYPE_MNTR)) {
1714 struct ieee80211_radiotap_header *prthdr =
1715 (struct ieee80211_radiotap_header *)skb->data;
1716 u16 len;
1717
1718 /*
1719 * there must be a radiotap header at the
1720 * start in this case
1721 */
1722 if (unlikely(prthdr->it_version)) {
1723 /* only version 0 is supported */
1724 ret = 0;
1725 goto fail;
1726 }
1727
1728 skb->dev = local->mdev;
1729
1730 pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
1731 memset(pkt_data, 0, sizeof(*pkt_data));
1732 pkt_data->ifindex = sdata->dev->ifindex;
1733 pkt_data->mgmt_iface = 0;
1734 pkt_data->do_not_encrypt = 1;
1735
1736 /* above needed because we set skb device to master */
1737
1738 /*
1739 * fix up the pointers accounting for the radiotap
1740 * header still being in there. We are being given
1741 * a precooked IEEE80211 header so no need for
1742 * normal processing
1743 */
1744 len = le16_to_cpu(get_unaligned(&prthdr->it_len));
1745 skb_set_mac_header(skb, len);
1746 skb_set_network_header(skb, len + sizeof(hdr));
1747 skb_set_transport_header(skb, len + sizeof(hdr));
1748
1749 /*
1750 * pass the radiotap header up to
1751 * the next stage intact
1752 */
1753 dev_queue_xmit(skb);
1754
1755 return 0;
1756 }
1757
1758 nh_pos = skb_network_header(skb) - skb->data; 1763 nh_pos = skb_network_header(skb) - skb->data;
1759 h_pos = skb_transport_header(skb) - skb->data; 1764 h_pos = skb_transport_header(skb) - skb->data;
1760 1765
@@ -1882,7 +1887,7 @@ static int ieee80211_subif_start_xmit(struct sk_buff *skb,
1882 1887
1883 pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; 1888 pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
1884 memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data)); 1889 memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data));
1885 pkt_data->ifindex = sdata->dev->ifindex; 1890 pkt_data->ifindex = dev->ifindex;
1886 pkt_data->mgmt_iface = (sdata->type == IEEE80211_IF_TYPE_MGMT); 1891 pkt_data->mgmt_iface = (sdata->type == IEEE80211_IF_TYPE_MGMT);
1887 pkt_data->do_not_encrypt = no_encrypt; 1892 pkt_data->do_not_encrypt = no_encrypt;
1888 1893
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 5a91e179efa0..fadcbccc0da2 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -720,6 +720,8 @@ void ieee80211_prepare_rates(struct ieee80211_local *local,
720 struct ieee80211_hw_mode *mode); 720 struct ieee80211_hw_mode *mode);
721void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx); 721void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx);
722int ieee80211_if_update_wds(struct net_device *dev, u8 *remote_addr); 722int ieee80211_if_update_wds(struct net_device *dev, u8 *remote_addr);
723int ieee80211_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev);
724int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev);
723void ieee80211_if_setup(struct net_device *dev); 725void ieee80211_if_setup(struct net_device *dev);
724void ieee80211_if_mgmt_setup(struct net_device *dev); 726void ieee80211_if_mgmt_setup(struct net_device *dev);
725int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local, 727int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local,
diff --git a/net/mac80211/ieee80211_iface.c b/net/mac80211/ieee80211_iface.c
index cf0f32e8c2a2..8532a5ccdd1e 100644
--- a/net/mac80211/ieee80211_iface.c
+++ b/net/mac80211/ieee80211_iface.c
@@ -157,6 +157,8 @@ void ieee80211_if_set_type(struct net_device *dev, int type)
157 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 157 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
158 int oldtype = sdata->type; 158 int oldtype = sdata->type;
159 159
160 dev->hard_start_xmit = ieee80211_subif_start_xmit;
161
160 sdata->type = type; 162 sdata->type = type;
161 switch (type) { 163 switch (type) {
162 case IEEE80211_IF_TYPE_WDS: 164 case IEEE80211_IF_TYPE_WDS:
@@ -196,6 +198,7 @@ void ieee80211_if_set_type(struct net_device *dev, int type)
196 } 198 }
197 case IEEE80211_IF_TYPE_MNTR: 199 case IEEE80211_IF_TYPE_MNTR:
198 dev->type = ARPHRD_IEEE80211_RADIOTAP; 200 dev->type = ARPHRD_IEEE80211_RADIOTAP;
201 dev->hard_start_xmit = ieee80211_monitor_start_xmit;
199 break; 202 break;
200 default: 203 default:
201 printk(KERN_WARNING "%s: %s: Unknown interface type 0x%x", 204 printk(KERN_WARNING "%s: %s: Unknown interface type 0x%x",