diff options
author | Arik Nemtsov <arik@wizery.com> | 2014-11-09 11:50:16 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2014-11-19 12:45:07 -0500 |
commit | c2733905692589cc73928ffd65d26107536e80fe (patch) | |
tree | 42d0b2f51cd3c46096b85d2bb322b5297b075ec7 | |
parent | 9041c1fa5722250025be9a7450622c9108088c5a (diff) |
mac80211: prepare TDLS mgmt code for channel-switch templates
Split the data-generating from the Tx-sending functionality, as we do
not want to send templates to the lower driver. Also add an optional
chandef argument to the data-generating portion. It will be used for
channel-switch templates.
Signed-off-by: Arik Nemtsov <arikx.nemtsov@intel.com>
Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r-- | net/mac80211/tdls.c | 82 |
1 files changed, 57 insertions, 25 deletions
diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c index 4554bdc72c91..fa141aecd986 100644 --- a/net/mac80211/tdls.c +++ b/net/mac80211/tdls.c | |||
@@ -453,7 +453,8 @@ static void ieee80211_tdls_add_ies(struct ieee80211_sub_if_data *sdata, | |||
453 | struct sk_buff *skb, const u8 *peer, | 453 | struct sk_buff *skb, const u8 *peer, |
454 | u8 action_code, u16 status_code, | 454 | u8 action_code, u16 status_code, |
455 | bool initiator, const u8 *extra_ies, | 455 | bool initiator, const u8 *extra_ies, |
456 | size_t extra_ies_len) | 456 | size_t extra_ies_len, u8 oper_class, |
457 | struct cfg80211_chan_def *chandef) | ||
457 | { | 458 | { |
458 | switch (action_code) { | 459 | switch (action_code) { |
459 | case WLAN_TDLS_SETUP_REQUEST: | 460 | case WLAN_TDLS_SETUP_REQUEST: |
@@ -589,22 +590,19 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev, | |||
589 | return 0; | 590 | return 0; |
590 | } | 591 | } |
591 | 592 | ||
592 | static int | 593 | static struct sk_buff * |
593 | ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, | 594 | ieee80211_tdls_build_mgmt_packet_data(struct ieee80211_sub_if_data *sdata, |
594 | const u8 *peer, u8 action_code, | 595 | const u8 *peer, u8 action_code, |
595 | u8 dialog_token, u16 status_code, | 596 | u8 dialog_token, u16 status_code, |
596 | u32 peer_capability, bool initiator, | 597 | bool initiator, const u8 *extra_ies, |
597 | const u8 *extra_ies, size_t extra_ies_len) | 598 | size_t extra_ies_len, u8 oper_class, |
599 | struct cfg80211_chan_def *chandef) | ||
598 | { | 600 | { |
599 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
600 | struct ieee80211_local *local = sdata->local; | 601 | struct ieee80211_local *local = sdata->local; |
601 | struct sk_buff *skb = NULL; | 602 | struct sk_buff *skb; |
602 | u32 flags = 0; | ||
603 | bool send_direct; | ||
604 | struct sta_info *sta; | ||
605 | int ret; | 603 | int ret; |
606 | 604 | ||
607 | skb = netdev_alloc_skb(dev, | 605 | skb = netdev_alloc_skb(sdata->dev, |
608 | local->hw.extra_tx_headroom + | 606 | local->hw.extra_tx_headroom + |
609 | max(sizeof(struct ieee80211_mgmt), | 607 | max(sizeof(struct ieee80211_mgmt), |
610 | sizeof(struct ieee80211_tdls_data)) + | 608 | sizeof(struct ieee80211_tdls_data)) + |
@@ -618,7 +616,7 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, | |||
618 | extra_ies_len + | 616 | extra_ies_len + |
619 | sizeof(struct ieee80211_tdls_lnkie)); | 617 | sizeof(struct ieee80211_tdls_lnkie)); |
620 | if (!skb) | 618 | if (!skb) |
621 | return -ENOMEM; | 619 | return NULL; |
622 | 620 | ||
623 | skb_reserve(skb, local->hw.extra_tx_headroom); | 621 | skb_reserve(skb, local->hw.extra_tx_headroom); |
624 | 622 | ||
@@ -628,16 +626,16 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, | |||
628 | case WLAN_TDLS_SETUP_CONFIRM: | 626 | case WLAN_TDLS_SETUP_CONFIRM: |
629 | case WLAN_TDLS_TEARDOWN: | 627 | case WLAN_TDLS_TEARDOWN: |
630 | case WLAN_TDLS_DISCOVERY_REQUEST: | 628 | case WLAN_TDLS_DISCOVERY_REQUEST: |
631 | ret = ieee80211_prep_tdls_encap_data(wiphy, dev, peer, | 629 | ret = ieee80211_prep_tdls_encap_data(local->hw.wiphy, |
630 | sdata->dev, peer, | ||
632 | action_code, dialog_token, | 631 | action_code, dialog_token, |
633 | status_code, skb); | 632 | status_code, skb); |
634 | send_direct = false; | ||
635 | break; | 633 | break; |
636 | case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: | 634 | case WLAN_PUB_ACTION_TDLS_DISCOVER_RES: |
637 | ret = ieee80211_prep_tdls_direct(wiphy, dev, peer, action_code, | 635 | ret = ieee80211_prep_tdls_direct(local->hw.wiphy, sdata->dev, |
636 | peer, action_code, | ||
638 | dialog_token, status_code, | 637 | dialog_token, status_code, |
639 | skb); | 638 | skb); |
640 | send_direct = true; | ||
641 | break; | 639 | break; |
642 | default: | 640 | default: |
643 | ret = -ENOTSUPP; | 641 | ret = -ENOTSUPP; |
@@ -647,6 +645,30 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, | |||
647 | if (ret < 0) | 645 | if (ret < 0) |
648 | goto fail; | 646 | goto fail; |
649 | 647 | ||
648 | ieee80211_tdls_add_ies(sdata, skb, peer, action_code, status_code, | ||
649 | initiator, extra_ies, extra_ies_len, oper_class, | ||
650 | chandef); | ||
651 | return skb; | ||
652 | |||
653 | fail: | ||
654 | dev_kfree_skb(skb); | ||
655 | return NULL; | ||
656 | } | ||
657 | |||
658 | static int | ||
659 | ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, | ||
660 | const u8 *peer, u8 action_code, u8 dialog_token, | ||
661 | u16 status_code, u32 peer_capability, | ||
662 | bool initiator, const u8 *extra_ies, | ||
663 | size_t extra_ies_len, u8 oper_class, | ||
664 | struct cfg80211_chan_def *chandef) | ||
665 | { | ||
666 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
667 | struct sk_buff *skb = NULL; | ||
668 | struct sta_info *sta; | ||
669 | u32 flags = 0; | ||
670 | int ret = 0; | ||
671 | |||
650 | rcu_read_lock(); | 672 | rcu_read_lock(); |
651 | sta = sta_info_get(sdata, peer); | 673 | sta = sta_info_get(sdata, peer); |
652 | 674 | ||
@@ -691,9 +713,17 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, | |||
691 | if (ret < 0) | 713 | if (ret < 0) |
692 | goto fail; | 714 | goto fail; |
693 | 715 | ||
694 | ieee80211_tdls_add_ies(sdata, skb, peer, action_code, status_code, | 716 | skb = ieee80211_tdls_build_mgmt_packet_data(sdata, peer, action_code, |
695 | initiator, extra_ies, extra_ies_len); | 717 | dialog_token, status_code, |
696 | if (send_direct) { | 718 | initiator, extra_ies, |
719 | extra_ies_len, oper_class, | ||
720 | chandef); | ||
721 | if (!skb) { | ||
722 | ret = -EINVAL; | ||
723 | goto fail; | ||
724 | } | ||
725 | |||
726 | if (action_code == WLAN_PUB_ACTION_TDLS_DISCOVER_RES) { | ||
697 | ieee80211_tx_skb(sdata, skb); | 727 | ieee80211_tx_skb(sdata, skb); |
698 | return 0; | 728 | return 0; |
699 | } | 729 | } |
@@ -720,7 +750,7 @@ ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev, | |||
720 | * packet through the AP. | 750 | * packet through the AP. |
721 | */ | 751 | */ |
722 | if ((action_code == WLAN_TDLS_TEARDOWN) && | 752 | if ((action_code == WLAN_TDLS_TEARDOWN) && |
723 | (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) { | 753 | (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) { |
724 | struct sta_info *sta = NULL; | 754 | struct sta_info *sta = NULL; |
725 | bool try_resend; /* Should we keep skb for possible resend */ | 755 | bool try_resend; /* Should we keep skb for possible resend */ |
726 | 756 | ||
@@ -802,7 +832,8 @@ ieee80211_tdls_mgmt_setup(struct wiphy *wiphy, struct net_device *dev, | |||
802 | ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code, | 832 | ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code, |
803 | dialog_token, status_code, | 833 | dialog_token, status_code, |
804 | peer_capability, initiator, | 834 | peer_capability, initiator, |
805 | extra_ies, extra_ies_len); | 835 | extra_ies, extra_ies_len, 0, |
836 | NULL); | ||
806 | if (ret < 0) | 837 | if (ret < 0) |
807 | goto exit; | 838 | goto exit; |
808 | 839 | ||
@@ -841,7 +872,8 @@ ieee80211_tdls_mgmt_teardown(struct wiphy *wiphy, struct net_device *dev, | |||
841 | ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code, | 872 | ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code, |
842 | dialog_token, status_code, | 873 | dialog_token, status_code, |
843 | peer_capability, initiator, | 874 | peer_capability, initiator, |
844 | extra_ies, extra_ies_len); | 875 | extra_ies, extra_ies_len, 0, |
876 | NULL); | ||
845 | if (ret < 0) | 877 | if (ret < 0) |
846 | sdata_err(sdata, "Failed sending TDLS teardown packet %d\n", | 878 | sdata_err(sdata, "Failed sending TDLS teardown packet %d\n", |
847 | ret); | 879 | ret); |
@@ -911,7 +943,7 @@ int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, | |||
911 | status_code, | 943 | status_code, |
912 | peer_capability, | 944 | peer_capability, |
913 | initiator, extra_ies, | 945 | initiator, extra_ies, |
914 | extra_ies_len); | 946 | extra_ies_len, 0, NULL); |
915 | break; | 947 | break; |
916 | default: | 948 | default: |
917 | ret = -EOPNOTSUPP; | 949 | ret = -EOPNOTSUPP; |