aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex/cfg80211.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/mwifiex/cfg80211.c')
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c816
1 files changed, 609 insertions, 207 deletions
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 7be1e9b83fd0..41c8e25df954 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -590,77 +590,62 @@ mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
590 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); 590 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
591 struct mwifiex_private *priv; 591 struct mwifiex_private *priv;
592 struct mwifiex_uap_bss_param *bss_cfg; 592 struct mwifiex_uap_bss_param *bss_cfg;
593 int ret, bss_started, i; 593 int ret;
594
595 for (i = 0; i < adapter->priv_num; i++) {
596 priv = adapter->priv[i];
597
598 switch (priv->bss_role) {
599 case MWIFIEX_BSS_ROLE_UAP:
600 bss_cfg = kzalloc(sizeof(struct mwifiex_uap_bss_param),
601 GFP_KERNEL);
602 if (!bss_cfg)
603 return -ENOMEM;
604
605 mwifiex_set_sys_config_invalid_data(bss_cfg);
606
607 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
608 bss_cfg->rts_threshold = wiphy->rts_threshold;
609 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
610 bss_cfg->frag_threshold = wiphy->frag_threshold;
611 if (changed & WIPHY_PARAM_RETRY_LONG)
612 bss_cfg->retry_limit = wiphy->retry_long;
613
614 bss_started = priv->bss_started;
615
616 ret = mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP,
617 HostCmd_ACT_GEN_SET, 0,
618 NULL, true);
619 if (ret) {
620 wiphy_err(wiphy, "Failed to stop the BSS\n");
621 kfree(bss_cfg);
622 return ret;
623 }
624 594
625 ret = mwifiex_send_cmd(priv, HostCmd_CMD_UAP_SYS_CONFIG, 595 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
626 HostCmd_ACT_GEN_SET,
627 UAP_BSS_PARAMS_I, bss_cfg,
628 false);
629 596
630 kfree(bss_cfg); 597 switch (priv->bss_role) {
598 case MWIFIEX_BSS_ROLE_UAP:
599 if (priv->bss_started) {
600 dev_err(adapter->dev,
601 "cannot change wiphy params when bss started");
602 return -EINVAL;
603 }
631 604
632 if (ret) { 605 bss_cfg = kzalloc(sizeof(*bss_cfg), GFP_KERNEL);
633 wiphy_err(wiphy, "Failed to set bss config\n"); 606 if (!bss_cfg)
634 return ret; 607 return -ENOMEM;
635 }
636 608
637 if (!bss_started) 609 mwifiex_set_sys_config_invalid_data(bss_cfg);
638 break;
639 610
640 ret = mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_START, 611 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
641 HostCmd_ACT_GEN_SET, 0, 612 bss_cfg->rts_threshold = wiphy->rts_threshold;
642 NULL, false); 613 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
643 if (ret) { 614 bss_cfg->frag_threshold = wiphy->frag_threshold;
644 wiphy_err(wiphy, "Failed to start BSS\n"); 615 if (changed & WIPHY_PARAM_RETRY_LONG)
645 return ret; 616 bss_cfg->retry_limit = wiphy->retry_long;
646 } 617
618 ret = mwifiex_send_cmd(priv, HostCmd_CMD_UAP_SYS_CONFIG,
619 HostCmd_ACT_GEN_SET,
620 UAP_BSS_PARAMS_I, bss_cfg,
621 false);
622
623 kfree(bss_cfg);
624 if (ret) {
625 wiphy_err(wiphy, "Failed to set wiphy phy params\n");
626 return ret;
627 }
628 break;
647 629
648 break;
649 case MWIFIEX_BSS_ROLE_STA: 630 case MWIFIEX_BSS_ROLE_STA:
650 if (changed & WIPHY_PARAM_RTS_THRESHOLD) { 631 if (priv->media_connected) {
651 ret = mwifiex_set_rts(priv, 632 dev_err(adapter->dev,
652 wiphy->rts_threshold); 633 "cannot change wiphy params when connected");
653 if (ret) 634 return -EINVAL;
654 return ret; 635 }
655 } 636 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
656 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) { 637 ret = mwifiex_set_rts(priv,
657 ret = mwifiex_set_frag(priv, 638 wiphy->rts_threshold);
658 wiphy->frag_threshold); 639 if (ret)
659 if (ret) 640 return ret;
660 return ret; 641 }
661 } 642 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
662 break; 643 ret = mwifiex_set_frag(priv,
644 wiphy->frag_threshold);
645 if (ret)
646 return ret;
663 } 647 }
648 break;
664 } 649 }
665 650
666 return 0; 651 return 0;
@@ -671,9 +656,6 @@ mwifiex_cfg80211_deinit_p2p(struct mwifiex_private *priv)
671{ 656{
672 u16 mode = P2P_MODE_DISABLE; 657 u16 mode = P2P_MODE_DISABLE;
673 658
674 if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA)
675 mwifiex_set_bss_role(priv, MWIFIEX_BSS_ROLE_STA);
676
677 if (mwifiex_send_cmd(priv, HostCmd_CMD_P2P_MODE_CFG, 659 if (mwifiex_send_cmd(priv, HostCmd_CMD_P2P_MODE_CFG,
678 HostCmd_ACT_GEN_SET, 0, &mode, true)) 660 HostCmd_ACT_GEN_SET, 0, &mode, true))
679 return -1; 661 return -1;
@@ -730,12 +712,249 @@ mwifiex_cfg80211_init_p2p_go(struct mwifiex_private *priv)
730 HostCmd_ACT_GEN_SET, 0, &mode, true)) 712 HostCmd_ACT_GEN_SET, 0, &mode, true))
731 return -1; 713 return -1;
732 714
733 if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_UAP) 715 return 0;
734 mwifiex_set_bss_role(priv, MWIFIEX_BSS_ROLE_UAP); 716}
717
718static int mwifiex_deinit_priv_params(struct mwifiex_private *priv)
719{
720 priv->mgmt_frame_mask = 0;
721 if (mwifiex_send_cmd(priv, HostCmd_CMD_MGMT_FRAME_REG,
722 HostCmd_ACT_GEN_SET, 0,
723 &priv->mgmt_frame_mask, false)) {
724 dev_warn(priv->adapter->dev,
725 "could not unregister mgmt frame rx\n");
726 return -1;
727 }
728
729 mwifiex_deauthenticate(priv, NULL);
730 mwifiex_free_priv(priv);
731 priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
732 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
733 priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM;
735 734
736 return 0; 735 return 0;
737} 736}
738 737
738static int
739mwifiex_init_new_priv_params(struct mwifiex_private *priv,
740 struct net_device *dev,
741 enum nl80211_iftype type)
742{
743 mwifiex_init_priv(priv);
744
745 priv->bss_mode = type;
746 priv->wdev.iftype = type;
747
748 mwifiex_init_priv_params(priv, priv->netdev);
749 priv->bss_started = 0;
750
751 switch (type) {
752 case NL80211_IFTYPE_STATION:
753 case NL80211_IFTYPE_ADHOC:
754 priv->bss_role = MWIFIEX_BSS_ROLE_STA;
755 priv->bss_type = MWIFIEX_BSS_TYPE_STA;
756 break;
757 case NL80211_IFTYPE_P2P_CLIENT:
758 case NL80211_IFTYPE_P2P_GO:
759 priv->bss_role = MWIFIEX_BSS_ROLE_STA;
760 priv->bss_type = MWIFIEX_BSS_TYPE_P2P;
761 break;
762 case NL80211_IFTYPE_AP:
763 priv->bss_type = MWIFIEX_BSS_TYPE_UAP;
764 priv->bss_role = MWIFIEX_BSS_ROLE_UAP;
765 break;
766 default:
767 dev_err(priv->adapter->dev,
768 "%s: changing to %d not supported\n",
769 dev->name, type);
770 return -EOPNOTSUPP;
771 }
772
773 return 0;
774}
775
776static int
777mwifiex_change_vif_to_p2p(struct net_device *dev,
778 enum nl80211_iftype curr_iftype,
779 enum nl80211_iftype type, u32 *flags,
780 struct vif_params *params)
781{
782 struct mwifiex_private *priv;
783 struct mwifiex_adapter *adapter;
784
785 priv = mwifiex_netdev_get_priv(dev);
786
787 if (!priv)
788 return -1;
789
790 adapter = priv->adapter;
791
792 if (adapter->curr_iface_comb.p2p_intf ==
793 adapter->iface_limit.p2p_intf) {
794 dev_err(adapter->dev,
795 "cannot create multiple P2P ifaces\n");
796 return -1;
797 }
798
799 dev_dbg(priv->adapter->dev, "%s: changing role to p2p\n", dev->name);
800
801 if (mwifiex_deinit_priv_params(priv))
802 return -1;
803 if (mwifiex_init_new_priv_params(priv, dev, type))
804 return -1;
805
806 switch (type) {
807 case NL80211_IFTYPE_P2P_CLIENT:
808 if (mwifiex_cfg80211_init_p2p_client(priv))
809 return -EFAULT;
810 break;
811 case NL80211_IFTYPE_P2P_GO:
812 if (mwifiex_cfg80211_init_p2p_go(priv))
813 return -EFAULT;
814 break;
815 default:
816 dev_err(priv->adapter->dev,
817 "%s: changing to %d not supported\n",
818 dev->name, type);
819 return -EOPNOTSUPP;
820 }
821
822 if (mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
823 HostCmd_ACT_GEN_SET, 0, NULL, true))
824 return -1;
825
826 if (mwifiex_sta_init_cmd(priv, false, false))
827 return -1;
828
829 switch (curr_iftype) {
830 case NL80211_IFTYPE_STATION:
831 case NL80211_IFTYPE_ADHOC:
832 adapter->curr_iface_comb.sta_intf--;
833 break;
834 case NL80211_IFTYPE_AP:
835 adapter->curr_iface_comb.uap_intf--;
836 break;
837 default:
838 break;
839 }
840
841 adapter->curr_iface_comb.p2p_intf++;
842 dev->ieee80211_ptr->iftype = type;
843
844 return 0;
845}
846
847static int
848mwifiex_change_vif_to_sta_adhoc(struct net_device *dev,
849 enum nl80211_iftype curr_iftype,
850 enum nl80211_iftype type, u32 *flags,
851 struct vif_params *params)
852{
853 struct mwifiex_private *priv;
854 struct mwifiex_adapter *adapter;
855
856 priv = mwifiex_netdev_get_priv(dev);
857
858 if (!priv)
859 return -1;
860
861 adapter = priv->adapter;
862
863 if ((curr_iftype != NL80211_IFTYPE_P2P_CLIENT &&
864 curr_iftype != NL80211_IFTYPE_P2P_GO) &&
865 (adapter->curr_iface_comb.sta_intf ==
866 adapter->iface_limit.sta_intf)) {
867 dev_err(adapter->dev,
868 "cannot create multiple station/adhoc ifaces\n");
869 return -1;
870 }
871
872 if (type == NL80211_IFTYPE_STATION)
873 dev_notice(adapter->dev,
874 "%s: changing role to station\n", dev->name);
875 else
876 dev_notice(adapter->dev,
877 "%s: changing role to adhoc\n", dev->name);
878
879 if (mwifiex_deinit_priv_params(priv))
880 return -1;
881 if (mwifiex_init_new_priv_params(priv, dev, type))
882 return -1;
883 if (mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
884 HostCmd_ACT_GEN_SET, 0, NULL, true))
885 return -1;
886 if (mwifiex_sta_init_cmd(priv, false, false))
887 return -1;
888
889 switch (curr_iftype) {
890 case NL80211_IFTYPE_P2P_CLIENT:
891 case NL80211_IFTYPE_P2P_GO:
892 adapter->curr_iface_comb.p2p_intf--;
893 break;
894 case NL80211_IFTYPE_AP:
895 adapter->curr_iface_comb.uap_intf--;
896 break;
897 default:
898 break;
899 }
900
901 adapter->curr_iface_comb.sta_intf++;
902 dev->ieee80211_ptr->iftype = type;
903 return 0;
904}
905
906static int
907mwifiex_change_vif_to_ap(struct net_device *dev,
908 enum nl80211_iftype curr_iftype,
909 enum nl80211_iftype type, u32 *flags,
910 struct vif_params *params)
911{
912 struct mwifiex_private *priv;
913 struct mwifiex_adapter *adapter;
914
915 priv = mwifiex_netdev_get_priv(dev);
916
917 if (!priv)
918 return -1;
919
920 adapter = priv->adapter;
921
922 if (adapter->curr_iface_comb.uap_intf ==
923 adapter->iface_limit.uap_intf) {
924 dev_err(adapter->dev,
925 "cannot create multiple AP ifaces\n");
926 return -1;
927 }
928
929 dev_notice(adapter->dev, "%s: changing role to AP\n", dev->name);
930
931 if (mwifiex_deinit_priv_params(priv))
932 return -1;
933 if (mwifiex_init_new_priv_params(priv, dev, type))
934 return -1;
935 if (mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
936 HostCmd_ACT_GEN_SET, 0, NULL, true))
937 return -1;
938 if (mwifiex_sta_init_cmd(priv, false, false))
939 return -1;
940
941 switch (curr_iftype) {
942 case NL80211_IFTYPE_P2P_CLIENT:
943 case NL80211_IFTYPE_P2P_GO:
944 adapter->curr_iface_comb.p2p_intf--;
945 break;
946 case NL80211_IFTYPE_STATION:
947 case NL80211_IFTYPE_ADHOC:
948 adapter->curr_iface_comb.sta_intf--;
949 break;
950 default:
951 break;
952 }
953
954 adapter->curr_iface_comb.uap_intf++;
955 dev->ieee80211_ptr->iftype = type;
956 return 0;
957}
739/* 958/*
740 * CFG802.11 operation handler to change interface type. 959 * CFG802.11 operation handler to change interface type.
741 */ 960 */
@@ -745,19 +964,32 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
745 enum nl80211_iftype type, u32 *flags, 964 enum nl80211_iftype type, u32 *flags,
746 struct vif_params *params) 965 struct vif_params *params)
747{ 966{
748 int ret;
749 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 967 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
968 enum nl80211_iftype curr_iftype = dev->ieee80211_ptr->iftype;
750 969
751 switch (dev->ieee80211_ptr->iftype) { 970 switch (curr_iftype) {
752 case NL80211_IFTYPE_ADHOC: 971 case NL80211_IFTYPE_ADHOC:
753 switch (type) { 972 switch (type) {
754 case NL80211_IFTYPE_STATION: 973 case NL80211_IFTYPE_STATION:
755 break; 974 priv->bss_mode = type;
975 priv->sec_info.authentication_mode =
976 NL80211_AUTHTYPE_OPEN_SYSTEM;
977 dev->ieee80211_ptr->iftype = type;
978 mwifiex_deauthenticate(priv, NULL);
979 return mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
980 HostCmd_ACT_GEN_SET, 0, NULL,
981 true);
982 case NL80211_IFTYPE_P2P_CLIENT:
983 case NL80211_IFTYPE_P2P_GO:
984 return mwifiex_change_vif_to_p2p(dev, curr_iftype,
985 type, flags, params);
986 case NL80211_IFTYPE_AP:
987 return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
988 flags, params);
756 case NL80211_IFTYPE_UNSPECIFIED: 989 case NL80211_IFTYPE_UNSPECIFIED:
757 wiphy_warn(wiphy, "%s: kept type as IBSS\n", dev->name); 990 wiphy_warn(wiphy, "%s: kept type as IBSS\n", dev->name);
758 case NL80211_IFTYPE_ADHOC: /* This shouldn't happen */ 991 case NL80211_IFTYPE_ADHOC: /* This shouldn't happen */
759 return 0; 992 return 0;
760 case NL80211_IFTYPE_AP:
761 default: 993 default:
762 wiphy_err(wiphy, "%s: changing to %d not supported\n", 994 wiphy_err(wiphy, "%s: changing to %d not supported\n",
763 dev->name, type); 995 dev->name, type);
@@ -767,22 +999,25 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
767 case NL80211_IFTYPE_STATION: 999 case NL80211_IFTYPE_STATION:
768 switch (type) { 1000 switch (type) {
769 case NL80211_IFTYPE_ADHOC: 1001 case NL80211_IFTYPE_ADHOC:
770 break; 1002 priv->bss_mode = type;
771 case NL80211_IFTYPE_P2P_CLIENT: 1003 priv->sec_info.authentication_mode =
772 if (mwifiex_cfg80211_init_p2p_client(priv)) 1004 NL80211_AUTHTYPE_OPEN_SYSTEM;
773 return -EFAULT;
774 dev->ieee80211_ptr->iftype = type; 1005 dev->ieee80211_ptr->iftype = type;
775 return 0; 1006 mwifiex_deauthenticate(priv, NULL);
1007 return mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
1008 HostCmd_ACT_GEN_SET, 0, NULL,
1009 true);
1010 case NL80211_IFTYPE_P2P_CLIENT:
776 case NL80211_IFTYPE_P2P_GO: 1011 case NL80211_IFTYPE_P2P_GO:
777 if (mwifiex_cfg80211_init_p2p_go(priv)) 1012 return mwifiex_change_vif_to_p2p(dev, curr_iftype,
778 return -EFAULT; 1013 type, flags, params);
779 dev->ieee80211_ptr->iftype = type; 1014 case NL80211_IFTYPE_AP:
780 return 0; 1015 return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
1016 flags, params);
781 case NL80211_IFTYPE_UNSPECIFIED: 1017 case NL80211_IFTYPE_UNSPECIFIED:
782 wiphy_warn(wiphy, "%s: kept type as STA\n", dev->name); 1018 wiphy_warn(wiphy, "%s: kept type as STA\n", dev->name);
783 case NL80211_IFTYPE_STATION: /* This shouldn't happen */ 1019 case NL80211_IFTYPE_STATION: /* This shouldn't happen */
784 return 0; 1020 return 0;
785 case NL80211_IFTYPE_AP:
786 default: 1021 default:
787 wiphy_err(wiphy, "%s: changing to %d not supported\n", 1022 wiphy_err(wiphy, "%s: changing to %d not supported\n",
788 dev->name, type); 1023 dev->name, type);
@@ -791,12 +1026,20 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
791 break; 1026 break;
792 case NL80211_IFTYPE_AP: 1027 case NL80211_IFTYPE_AP:
793 switch (type) { 1028 switch (type) {
1029 case NL80211_IFTYPE_ADHOC:
1030 case NL80211_IFTYPE_STATION:
1031 return mwifiex_change_vif_to_sta_adhoc(dev, curr_iftype,
1032 type, flags,
1033 params);
1034 break;
1035 case NL80211_IFTYPE_P2P_CLIENT:
1036 case NL80211_IFTYPE_P2P_GO:
1037 return mwifiex_change_vif_to_p2p(dev, curr_iftype,
1038 type, flags, params);
794 case NL80211_IFTYPE_UNSPECIFIED: 1039 case NL80211_IFTYPE_UNSPECIFIED:
795 wiphy_warn(wiphy, "%s: kept type as AP\n", dev->name); 1040 wiphy_warn(wiphy, "%s: kept type as AP\n", dev->name);
796 case NL80211_IFTYPE_AP: /* This shouldn't happen */ 1041 case NL80211_IFTYPE_AP: /* This shouldn't happen */
797 return 0; 1042 return 0;
798 case NL80211_IFTYPE_ADHOC:
799 case NL80211_IFTYPE_STATION:
800 default: 1043 default:
801 wiphy_err(wiphy, "%s: changing to %d not supported\n", 1044 wiphy_err(wiphy, "%s: changing to %d not supported\n",
802 dev->name, type); 1045 dev->name, type);
@@ -807,11 +1050,30 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
807 case NL80211_IFTYPE_P2P_GO: 1050 case NL80211_IFTYPE_P2P_GO:
808 switch (type) { 1051 switch (type) {
809 case NL80211_IFTYPE_STATION: 1052 case NL80211_IFTYPE_STATION:
810 if (mwifiex_cfg80211_deinit_p2p(priv)) 1053 if (mwifiex_cfg80211_init_p2p_client(priv))
811 return -EFAULT; 1054 return -EFAULT;
812 dev->ieee80211_ptr->iftype = type; 1055 dev->ieee80211_ptr->iftype = type;
1056 break;
1057 case NL80211_IFTYPE_ADHOC:
1058 if (mwifiex_cfg80211_deinit_p2p(priv))
1059 return -EFAULT;
1060 return mwifiex_change_vif_to_sta_adhoc(dev, curr_iftype,
1061 type, flags,
1062 params);
1063 break;
1064 case NL80211_IFTYPE_AP:
1065 if (mwifiex_cfg80211_deinit_p2p(priv))
1066 return -EFAULT;
1067 return mwifiex_change_vif_to_ap(dev, curr_iftype, type,
1068 flags, params);
1069 case NL80211_IFTYPE_UNSPECIFIED:
1070 wiphy_warn(wiphy, "%s: kept type as P2P\n", dev->name);
1071 case NL80211_IFTYPE_P2P_CLIENT:
1072 case NL80211_IFTYPE_P2P_GO:
813 return 0; 1073 return 0;
814 default: 1074 default:
1075 wiphy_err(wiphy, "%s: changing to %d not supported\n",
1076 dev->name, type);
815 return -EOPNOTSUPP; 1077 return -EOPNOTSUPP;
816 } 1078 }
817 break; 1079 break;
@@ -821,16 +1083,8 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
821 return -EOPNOTSUPP; 1083 return -EOPNOTSUPP;
822 } 1084 }
823 1085
824 dev->ieee80211_ptr->iftype = type;
825 priv->bss_mode = type;
826 mwifiex_deauthenticate(priv, NULL);
827
828 priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM;
829 1086
830 ret = mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE, 1087 return 0;
831 HostCmd_ACT_GEN_SET, 0, NULL, true);
832
833 return ret;
834} 1088}
835 1089
836static void 1090static void
@@ -1397,10 +1651,13 @@ static int mwifiex_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
1397{ 1651{
1398 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 1652 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1399 1653
1654 mwifiex_abort_cac(priv);
1655
1400 if (mwifiex_del_mgmt_ies(priv)) 1656 if (mwifiex_del_mgmt_ies(priv))
1401 wiphy_err(wiphy, "Failed to delete mgmt IEs!\n"); 1657 wiphy_err(wiphy, "Failed to delete mgmt IEs!\n");
1402 1658
1403 priv->ap_11n_enabled = 0; 1659 priv->ap_11n_enabled = 0;
1660 memset(&priv->bss_cfg, 0, sizeof(priv->bss_cfg));
1404 1661
1405 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP, 1662 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP,
1406 HostCmd_ACT_GEN_SET, 0, NULL, true)) { 1663 HostCmd_ACT_GEN_SET, 0, NULL, true)) {
@@ -1422,12 +1679,9 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
1422{ 1679{
1423 struct mwifiex_uap_bss_param *bss_cfg; 1680 struct mwifiex_uap_bss_param *bss_cfg;
1424 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 1681 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1425 u8 config_bands = 0;
1426 1682
1427 if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_UAP) 1683 if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_UAP)
1428 return -1; 1684 return -1;
1429 if (mwifiex_set_mgmt_ies(priv, &params->beacon))
1430 return -1;
1431 1685
1432 bss_cfg = kzalloc(sizeof(struct mwifiex_uap_bss_param), GFP_KERNEL); 1686 bss_cfg = kzalloc(sizeof(struct mwifiex_uap_bss_param), GFP_KERNEL);
1433 if (!bss_cfg) 1687 if (!bss_cfg)
@@ -1444,6 +1698,11 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
1444 memcpy(bss_cfg->ssid.ssid, params->ssid, params->ssid_len); 1698 memcpy(bss_cfg->ssid.ssid, params->ssid, params->ssid_len);
1445 bss_cfg->ssid.ssid_len = params->ssid_len; 1699 bss_cfg->ssid.ssid_len = params->ssid_len;
1446 } 1700 }
1701 if (params->inactivity_timeout > 0) {
1702 /* sta_ao_timer/ps_sta_ao_timer is in unit of 100ms */
1703 bss_cfg->sta_ao_timer = 10 * params->inactivity_timeout;
1704 bss_cfg->ps_sta_ao_timer = 10 * params->inactivity_timeout;
1705 }
1447 1706
1448 switch (params->hidden_ssid) { 1707 switch (params->hidden_ssid) {
1449 case NL80211_HIDDEN_SSID_NOT_IN_USE: 1708 case NL80211_HIDDEN_SSID_NOT_IN_USE:
@@ -1459,33 +1718,8 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
1459 return -EINVAL; 1718 return -EINVAL;
1460 } 1719 }
1461 1720
1462 bss_cfg->channel = ieee80211_frequency_to_channel( 1721 mwifiex_uap_set_channel(bss_cfg, params->chandef);
1463 params->chandef.chan->center_freq);
1464
1465 /* Set appropriate bands */
1466 if (params->chandef.chan->band == IEEE80211_BAND_2GHZ) {
1467 bss_cfg->band_cfg = BAND_CONFIG_BG;
1468 config_bands = BAND_B | BAND_G;
1469
1470 if (params->chandef.width > NL80211_CHAN_WIDTH_20_NOHT)
1471 config_bands |= BAND_GN;
1472 } else {
1473 bss_cfg->band_cfg = BAND_CONFIG_A;
1474 config_bands = BAND_A;
1475
1476 if (params->chandef.width > NL80211_CHAN_WIDTH_20_NOHT)
1477 config_bands |= BAND_AN;
1478
1479 if (params->chandef.width > NL80211_CHAN_WIDTH_40)
1480 config_bands |= BAND_AAC;
1481 }
1482
1483 if (!((config_bands | priv->adapter->fw_bands) &
1484 ~priv->adapter->fw_bands))
1485 priv->adapter->config_bands = config_bands;
1486
1487 mwifiex_set_uap_rates(bss_cfg, params); 1722 mwifiex_set_uap_rates(bss_cfg, params);
1488 mwifiex_send_domain_info_cmd_fw(wiphy);
1489 1723
1490 if (mwifiex_set_secure_params(priv, bss_cfg, params)) { 1724 if (mwifiex_set_secure_params(priv, bss_cfg, params)) {
1491 kfree(bss_cfg); 1725 kfree(bss_cfg);
@@ -1508,45 +1742,29 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
1508 1742
1509 mwifiex_set_wmm_params(priv, bss_cfg, params); 1743 mwifiex_set_wmm_params(priv, bss_cfg, params);
1510 1744
1511 if (params->inactivity_timeout > 0) { 1745 if (mwifiex_is_11h_active(priv) &&
1512 /* sta_ao_timer/ps_sta_ao_timer is in unit of 100ms */ 1746 !cfg80211_chandef_dfs_required(wiphy, &params->chandef,
1513 bss_cfg->sta_ao_timer = 10 * params->inactivity_timeout; 1747 priv->bss_mode)) {
1514 bss_cfg->ps_sta_ao_timer = 10 * params->inactivity_timeout; 1748 dev_dbg(priv->adapter->dev, "Disable 11h extensions in FW\n");
1749 if (mwifiex_11h_activate(priv, false)) {
1750 dev_err(priv->adapter->dev,
1751 "Failed to disable 11h extensions!!");
1752 return -1;
1753 }
1754 priv->state_11h.is_11h_active = true;
1515 } 1755 }
1516 1756
1517 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_STOP, 1757 if (mwifiex_config_start_uap(priv, bss_cfg)) {
1518 HostCmd_ACT_GEN_SET, 0, NULL, true)) { 1758 wiphy_err(wiphy, "Failed to start AP\n");
1519 wiphy_err(wiphy, "Failed to stop the BSS\n");
1520 kfree(bss_cfg); 1759 kfree(bss_cfg);
1521 return -1; 1760 return -1;
1522 } 1761 }
1523 1762
1524 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_SYS_CONFIG, 1763 if (mwifiex_set_mgmt_ies(priv, &params->beacon))
1525 HostCmd_ACT_GEN_SET,
1526 UAP_BSS_PARAMS_I, bss_cfg, false)) {
1527 wiphy_err(wiphy, "Failed to set the SSID\n");
1528 kfree(bss_cfg);
1529 return -1; 1764 return -1;
1530 }
1531 1765
1766 memcpy(&priv->bss_cfg, bss_cfg, sizeof(priv->bss_cfg));
1532 kfree(bss_cfg); 1767 kfree(bss_cfg);
1533
1534 if (mwifiex_send_cmd(priv, HostCmd_CMD_UAP_BSS_START,
1535 HostCmd_ACT_GEN_SET, 0, NULL, false)) {
1536 wiphy_err(wiphy, "Failed to start the BSS\n");
1537 return -1;
1538 }
1539
1540 if (priv->sec_info.wep_enabled)
1541 priv->curr_pkt_filter |= HostCmd_ACT_MAC_WEP_ENABLE;
1542 else
1543 priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE;
1544
1545 if (mwifiex_send_cmd(priv, HostCmd_CMD_MAC_CONTROL,
1546 HostCmd_ACT_GEN_SET, 0,
1547 &priv->curr_pkt_filter, true))
1548 return -1;
1549
1550 return 0; 1768 return 0;
1551} 1769}
1552 1770
@@ -1605,15 +1823,15 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv)
1605 ie_len = ie_buf[1] + sizeof(struct ieee_types_header); 1823 ie_len = ie_buf[1] + sizeof(struct ieee_types_header);
1606 1824
1607 band = mwifiex_band_to_radio_type(priv->curr_bss_params.band); 1825 band = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
1608 chan = __ieee80211_get_channel(priv->wdev->wiphy, 1826 chan = __ieee80211_get_channel(priv->wdev.wiphy,
1609 ieee80211_channel_to_frequency(bss_info.bss_chan, 1827 ieee80211_channel_to_frequency(bss_info.bss_chan,
1610 band)); 1828 band));
1611 1829
1612 bss = cfg80211_inform_bss(priv->wdev->wiphy, chan, 1830 bss = cfg80211_inform_bss(priv->wdev.wiphy, chan,
1613 CFG80211_BSS_FTYPE_UNKNOWN, 1831 CFG80211_BSS_FTYPE_UNKNOWN,
1614 bss_info.bssid, 0, WLAN_CAPABILITY_IBSS, 1832 bss_info.bssid, 0, WLAN_CAPABILITY_IBSS,
1615 0, ie_buf, ie_len, 0, GFP_KERNEL); 1833 0, ie_buf, ie_len, 0, GFP_KERNEL);
1616 cfg80211_put_bss(priv->wdev->wiphy, bss); 1834 cfg80211_put_bss(priv->wdev.wiphy, bss);
1617 memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN); 1835 memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN);
1618 1836
1619 return 0; 1837 return 0;
@@ -1734,12 +1952,12 @@ done:
1734 1952
1735 /* Find the BSS we want using available scan results */ 1953 /* Find the BSS we want using available scan results */
1736 if (mode == NL80211_IFTYPE_ADHOC) 1954 if (mode == NL80211_IFTYPE_ADHOC)
1737 bss = cfg80211_get_bss(priv->wdev->wiphy, channel, 1955 bss = cfg80211_get_bss(priv->wdev.wiphy, channel,
1738 bssid, ssid, ssid_len, 1956 bssid, ssid, ssid_len,
1739 WLAN_CAPABILITY_IBSS, 1957 WLAN_CAPABILITY_IBSS,
1740 WLAN_CAPABILITY_IBSS); 1958 WLAN_CAPABILITY_IBSS);
1741 else 1959 else
1742 bss = cfg80211_get_bss(priv->wdev->wiphy, channel, 1960 bss = cfg80211_get_bss(priv->wdev.wiphy, channel,
1743 bssid, ssid, ssid_len, 1961 bssid, ssid, ssid_len,
1744 WLAN_CAPABILITY_ESS, 1962 WLAN_CAPABILITY_ESS,
1745 WLAN_CAPABILITY_ESS); 1963 WLAN_CAPABILITY_ESS);
@@ -1796,7 +2014,7 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1796 return -EINVAL; 2014 return -EINVAL;
1797 } 2015 }
1798 2016
1799 if (priv->wdev && priv->wdev->current_bss) { 2017 if (priv->wdev.current_bss) {
1800 wiphy_warn(wiphy, "%s: already connected\n", dev->name); 2018 wiphy_warn(wiphy, "%s: already connected\n", dev->name);
1801 return -EALREADY; 2019 return -EALREADY;
1802 } 2020 }
@@ -1854,7 +2072,7 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
1854static int mwifiex_set_ibss_params(struct mwifiex_private *priv, 2072static int mwifiex_set_ibss_params(struct mwifiex_private *priv,
1855 struct cfg80211_ibss_params *params) 2073 struct cfg80211_ibss_params *params)
1856{ 2074{
1857 struct wiphy *wiphy = priv->wdev->wiphy; 2075 struct wiphy *wiphy = priv->wdev.wiphy;
1858 struct mwifiex_adapter *adapter = priv->adapter; 2076 struct mwifiex_adapter *adapter = priv->adapter;
1859 int index = 0, i; 2077 int index = 0, i;
1860 u8 config_bands = 0; 2078 u8 config_bands = 0;
@@ -2179,6 +2397,7 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info,
2179 ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; 2397 ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
2180} 2398}
2181 2399
2400#define MWIFIEX_MAX_WQ_LEN 30
2182/* 2401/*
2183 * create a new virtual interface with the given name 2402 * create a new virtual interface with the given name
2184 */ 2403 */
@@ -2192,7 +2411,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2192 struct mwifiex_private *priv; 2411 struct mwifiex_private *priv;
2193 struct net_device *dev; 2412 struct net_device *dev;
2194 void *mdev_priv; 2413 void *mdev_priv;
2195 struct wireless_dev *wdev; 2414 char dfs_cac_str[MWIFIEX_MAX_WQ_LEN], dfs_chsw_str[MWIFIEX_MAX_WQ_LEN];
2196 2415
2197 if (!adapter) 2416 if (!adapter)
2198 return ERR_PTR(-EFAULT); 2417 return ERR_PTR(-EFAULT);
@@ -2201,20 +2420,22 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2201 case NL80211_IFTYPE_UNSPECIFIED: 2420 case NL80211_IFTYPE_UNSPECIFIED:
2202 case NL80211_IFTYPE_STATION: 2421 case NL80211_IFTYPE_STATION:
2203 case NL80211_IFTYPE_ADHOC: 2422 case NL80211_IFTYPE_ADHOC:
2204 priv = adapter->priv[MWIFIEX_BSS_TYPE_STA]; 2423 if (adapter->curr_iface_comb.sta_intf ==
2205 if (priv->bss_mode) { 2424 adapter->iface_limit.sta_intf) {
2206 wiphy_err(wiphy, 2425 wiphy_err(wiphy,
2207 "cannot create multiple sta/adhoc ifaces\n"); 2426 "cannot create multiple sta/adhoc ifaces\n");
2208 return ERR_PTR(-EINVAL); 2427 return ERR_PTR(-EINVAL);
2209 } 2428 }
2210 2429
2211 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); 2430 priv = mwifiex_get_unused_priv(adapter);
2212 if (!wdev) 2431 if (!priv) {
2213 return ERR_PTR(-ENOMEM); 2432 wiphy_err(wiphy,
2433 "could not get free private struct\n");
2434 return ERR_PTR(-EFAULT);
2435 }
2214 2436
2215 wdev->wiphy = wiphy; 2437 priv->wdev.wiphy = wiphy;
2216 priv->wdev = wdev; 2438 priv->wdev.iftype = NL80211_IFTYPE_STATION;
2217 wdev->iftype = NL80211_IFTYPE_STATION;
2218 2439
2219 if (type == NL80211_IFTYPE_UNSPECIFIED) 2440 if (type == NL80211_IFTYPE_UNSPECIFIED)
2220 priv->bss_mode = NL80211_IFTYPE_STATION; 2441 priv->bss_mode = NL80211_IFTYPE_STATION;
@@ -2229,20 +2450,22 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2229 2450
2230 break; 2451 break;
2231 case NL80211_IFTYPE_AP: 2452 case NL80211_IFTYPE_AP:
2232 priv = adapter->priv[MWIFIEX_BSS_TYPE_UAP]; 2453 if (adapter->curr_iface_comb.uap_intf ==
2233 2454 adapter->iface_limit.uap_intf) {
2234 if (priv->bss_mode) { 2455 wiphy_err(wiphy,
2235 wiphy_err(wiphy, "Can't create multiple AP interfaces"); 2456 "cannot create multiple AP ifaces\n");
2236 return ERR_PTR(-EINVAL); 2457 return ERR_PTR(-EINVAL);
2237 } 2458 }
2238 2459
2239 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); 2460 priv = mwifiex_get_unused_priv(adapter);
2240 if (!wdev) 2461 if (!priv) {
2241 return ERR_PTR(-ENOMEM); 2462 wiphy_err(wiphy,
2463 "could not get free private struct\n");
2464 return ERR_PTR(-EFAULT);
2465 }
2242 2466
2243 priv->wdev = wdev; 2467 priv->wdev.wiphy = wiphy;
2244 wdev->wiphy = wiphy; 2468 priv->wdev.iftype = NL80211_IFTYPE_AP;
2245 wdev->iftype = NL80211_IFTYPE_AP;
2246 2469
2247 priv->bss_type = MWIFIEX_BSS_TYPE_UAP; 2470 priv->bss_type = MWIFIEX_BSS_TYPE_UAP;
2248 priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II; 2471 priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
@@ -2254,24 +2477,25 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2254 2477
2255 break; 2478 break;
2256 case NL80211_IFTYPE_P2P_CLIENT: 2479 case NL80211_IFTYPE_P2P_CLIENT:
2257 priv = adapter->priv[MWIFIEX_BSS_TYPE_P2P]; 2480 if (adapter->curr_iface_comb.p2p_intf ==
2258 2481 adapter->iface_limit.p2p_intf) {
2259 if (priv->bss_mode) { 2482 wiphy_err(wiphy,
2260 wiphy_err(wiphy, "Can't create multiple P2P ifaces"); 2483 "cannot create multiple P2P ifaces\n");
2261 return ERR_PTR(-EINVAL); 2484 return ERR_PTR(-EINVAL);
2262 } 2485 }
2263 2486
2264 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); 2487 priv = mwifiex_get_unused_priv(adapter);
2265 if (!wdev) 2488 if (!priv) {
2266 return ERR_PTR(-ENOMEM); 2489 wiphy_err(wiphy,
2267 2490 "could not get free private struct\n");
2268 priv->wdev = wdev; 2491 return ERR_PTR(-EFAULT);
2269 wdev->wiphy = wiphy; 2492 }
2270 2493
2494 priv->wdev.wiphy = wiphy;
2271 /* At start-up, wpa_supplicant tries to change the interface 2495 /* At start-up, wpa_supplicant tries to change the interface
2272 * to NL80211_IFTYPE_STATION if it is not managed mode. 2496 * to NL80211_IFTYPE_STATION if it is not managed mode.
2273 */ 2497 */
2274 wdev->iftype = NL80211_IFTYPE_P2P_CLIENT; 2498 priv->wdev.iftype = NL80211_IFTYPE_P2P_CLIENT;
2275 priv->bss_mode = NL80211_IFTYPE_P2P_CLIENT; 2499 priv->bss_mode = NL80211_IFTYPE_P2P_CLIENT;
2276 2500
2277 /* Setting bss_type to P2P tells firmware that this interface 2501 /* Setting bss_type to P2P tells firmware that this interface
@@ -2287,8 +2511,9 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2287 priv->bss_num = 0; 2511 priv->bss_num = 0;
2288 2512
2289 if (mwifiex_cfg80211_init_p2p_client(priv)) { 2513 if (mwifiex_cfg80211_init_p2p_client(priv)) {
2290 wdev = ERR_PTR(-EFAULT); 2514 memset(&priv->wdev, 0, sizeof(priv->wdev));
2291 goto done; 2515 priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
2516 return ERR_PTR(-EFAULT);
2292 } 2517 }
2293 2518
2294 break; 2519 break;
@@ -2302,9 +2527,10 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2302 IEEE80211_NUM_ACS, 1); 2527 IEEE80211_NUM_ACS, 1);
2303 if (!dev) { 2528 if (!dev) {
2304 wiphy_err(wiphy, "no memory available for netdevice\n"); 2529 wiphy_err(wiphy, "no memory available for netdevice\n");
2530 memset(&priv->wdev, 0, sizeof(priv->wdev));
2531 priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
2305 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; 2532 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
2306 wdev = ERR_PTR(-ENOMEM); 2533 return ERR_PTR(-ENOMEM);
2307 goto done;
2308 } 2534 }
2309 2535
2310 mwifiex_init_priv_params(priv, dev); 2536 mwifiex_init_priv_params(priv, dev);
@@ -2324,7 +2550,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2324 &wiphy->bands[IEEE80211_BAND_5GHZ]->vht_cap, priv); 2550 &wiphy->bands[IEEE80211_BAND_5GHZ]->vht_cap, priv);
2325 2551
2326 dev_net_set(dev, wiphy_net(wiphy)); 2552 dev_net_set(dev, wiphy_net(wiphy));
2327 dev->ieee80211_ptr = priv->wdev; 2553 dev->ieee80211_ptr = &priv->wdev;
2328 dev->ieee80211_ptr->iftype = priv->bss_mode; 2554 dev->ieee80211_ptr->iftype = priv->bss_mode;
2329 memcpy(dev->dev_addr, wiphy->perm_addr, ETH_ALEN); 2555 memcpy(dev->dev_addr, wiphy->perm_addr, ETH_ALEN);
2330 SET_NETDEV_DEV(dev, wiphy_dev(wiphy)); 2556 SET_NETDEV_DEV(dev, wiphy_dev(wiphy));
@@ -2345,10 +2571,47 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2345 free_netdev(dev); 2571 free_netdev(dev);
2346 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; 2572 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
2347 priv->netdev = NULL; 2573 priv->netdev = NULL;
2348 wdev = ERR_PTR(-EFAULT); 2574 memset(&priv->wdev, 0, sizeof(priv->wdev));
2349 goto done; 2575 priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
2576 return ERR_PTR(-EFAULT);
2577 }
2578
2579 strcpy(dfs_cac_str, "MWIFIEX_DFS_CAC");
2580 strcat(dfs_cac_str, name);
2581 priv->dfs_cac_workqueue = alloc_workqueue(dfs_cac_str,
2582 WQ_HIGHPRI |
2583 WQ_MEM_RECLAIM |
2584 WQ_UNBOUND, 1);
2585 if (!priv->dfs_cac_workqueue) {
2586 wiphy_err(wiphy, "cannot register virtual network device\n");
2587 free_netdev(dev);
2588 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
2589 priv->netdev = NULL;
2590 memset(&priv->wdev, 0, sizeof(priv->wdev));
2591 priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
2592 return ERR_PTR(-ENOMEM);
2593 }
2594
2595 INIT_DELAYED_WORK(&priv->dfs_cac_work, mwifiex_dfs_cac_work_queue);
2596
2597 strcpy(dfs_chsw_str, "MWIFIEX_DFS_CHSW");
2598 strcat(dfs_chsw_str, name);
2599 priv->dfs_chan_sw_workqueue = alloc_workqueue(dfs_chsw_str,
2600 WQ_HIGHPRI | WQ_UNBOUND |
2601 WQ_MEM_RECLAIM, 1);
2602 if (!priv->dfs_chan_sw_workqueue) {
2603 wiphy_err(wiphy, "cannot register virtual network device\n");
2604 free_netdev(dev);
2605 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
2606 priv->netdev = NULL;
2607 memset(&priv->wdev, 0, sizeof(priv->wdev));
2608 priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
2609 return ERR_PTR(-ENOMEM);
2350 } 2610 }
2351 2611
2612 INIT_DELAYED_WORK(&priv->dfs_chan_sw_work,
2613 mwifiex_dfs_chan_sw_work_queue);
2614
2352 sema_init(&priv->async_sem, 1); 2615 sema_init(&priv->async_sem, 1);
2353 2616
2354 dev_dbg(adapter->dev, "info: %s: Marvell 802.11 Adapter\n", dev->name); 2617 dev_dbg(adapter->dev, "info: %s: Marvell 802.11 Adapter\n", dev->name);
@@ -2357,13 +2620,24 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
2357 mwifiex_dev_debugfs_init(priv); 2620 mwifiex_dev_debugfs_init(priv);
2358#endif 2621#endif
2359 2622
2360done: 2623 switch (type) {
2361 if (IS_ERR(wdev)) { 2624 case NL80211_IFTYPE_UNSPECIFIED:
2362 kfree(priv->wdev); 2625 case NL80211_IFTYPE_STATION:
2363 priv->wdev = NULL; 2626 case NL80211_IFTYPE_ADHOC:
2627 adapter->curr_iface_comb.sta_intf++;
2628 break;
2629 case NL80211_IFTYPE_AP:
2630 adapter->curr_iface_comb.uap_intf++;
2631 break;
2632 case NL80211_IFTYPE_P2P_CLIENT:
2633 adapter->curr_iface_comb.p2p_intf++;
2634 break;
2635 default:
2636 wiphy_err(wiphy, "type not supported\n");
2637 return ERR_PTR(-EINVAL);
2364 } 2638 }
2365 2639
2366 return wdev; 2640 return &priv->wdev;
2367} 2641}
2368EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf); 2642EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf);
2369 2643
@@ -2373,12 +2647,13 @@ EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf);
2373int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev) 2647int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
2374{ 2648{
2375 struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev); 2649 struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev);
2650 struct mwifiex_adapter *adapter = priv->adapter;
2376 2651
2377#ifdef CONFIG_DEBUG_FS 2652#ifdef CONFIG_DEBUG_FS
2378 mwifiex_dev_debugfs_remove(priv); 2653 mwifiex_dev_debugfs_remove(priv);
2379#endif 2654#endif
2380 2655
2381 mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter); 2656 mwifiex_stop_net_dev_queue(priv->netdev, adapter);
2382 2657
2383 if (netif_carrier_ok(priv->netdev)) 2658 if (netif_carrier_ok(priv->netdev))
2384 netif_carrier_off(priv->netdev); 2659 netif_carrier_off(priv->netdev);
@@ -2386,14 +2661,42 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
2386 if (wdev->netdev->reg_state == NETREG_REGISTERED) 2661 if (wdev->netdev->reg_state == NETREG_REGISTERED)
2387 unregister_netdevice(wdev->netdev); 2662 unregister_netdevice(wdev->netdev);
2388 2663
2664 if (priv->dfs_cac_workqueue) {
2665 flush_workqueue(priv->dfs_cac_workqueue);
2666 destroy_workqueue(priv->dfs_cac_workqueue);
2667 priv->dfs_cac_workqueue = NULL;
2668 }
2669
2670 if (priv->dfs_chan_sw_workqueue) {
2671 flush_workqueue(priv->dfs_chan_sw_workqueue);
2672 destroy_workqueue(priv->dfs_chan_sw_workqueue);
2673 priv->dfs_chan_sw_workqueue = NULL;
2674 }
2389 /* Clear the priv in adapter */ 2675 /* Clear the priv in adapter */
2390 priv->netdev->ieee80211_ptr = NULL; 2676 priv->netdev->ieee80211_ptr = NULL;
2391 priv->netdev = NULL; 2677 priv->netdev = NULL;
2392 kfree(wdev); 2678 priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
2393 priv->wdev = NULL;
2394 2679
2395 priv->media_connected = false; 2680 priv->media_connected = false;
2396 2681
2682 switch (priv->bss_mode) {
2683 case NL80211_IFTYPE_UNSPECIFIED:
2684 case NL80211_IFTYPE_STATION:
2685 case NL80211_IFTYPE_ADHOC:
2686 adapter->curr_iface_comb.sta_intf++;
2687 break;
2688 case NL80211_IFTYPE_AP:
2689 adapter->curr_iface_comb.uap_intf++;
2690 break;
2691 case NL80211_IFTYPE_P2P_CLIENT:
2692 case NL80211_IFTYPE_P2P_GO:
2693 adapter->curr_iface_comb.p2p_intf++;
2694 break;
2695 default:
2696 dev_err(adapter->dev, "del_virtual_intf: type not supported\n");
2697 break;
2698 }
2699
2397 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; 2700 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
2398 2701
2399 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA || 2702 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA ||
@@ -2848,6 +3151,102 @@ mwifiex_cfg80211_add_station(struct wiphy *wiphy, struct net_device *dev,
2848} 3151}
2849 3152
2850static int 3153static int
3154mwifiex_cfg80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
3155 struct cfg80211_csa_settings *params)
3156{
3157 struct ieee_types_header *chsw_ie;
3158 struct ieee80211_channel_sw_ie *channel_sw;
3159 int chsw_msec;
3160 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
3161
3162 if (priv->adapter->scan_processing) {
3163 dev_err(priv->adapter->dev,
3164 "radar detection: scan in process...\n");
3165 return -EBUSY;
3166 }
3167
3168 if (priv->wdev.cac_started)
3169 return -EBUSY;
3170
3171 if (cfg80211_chandef_identical(&params->chandef,
3172 &priv->dfs_chandef))
3173 return -EINVAL;
3174
3175 chsw_ie = (void *)cfg80211_find_ie(WLAN_EID_CHANNEL_SWITCH,
3176 params->beacon_csa.tail,
3177 params->beacon_csa.tail_len);
3178 if (!chsw_ie) {
3179 dev_err(priv->adapter->dev,
3180 "Could not parse channel switch announcement IE\n");
3181 return -EINVAL;
3182 }
3183
3184 channel_sw = (void *)(chsw_ie + 1);
3185 if (channel_sw->mode) {
3186 if (netif_carrier_ok(priv->netdev))
3187 netif_carrier_off(priv->netdev);
3188 mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter);
3189 }
3190
3191 if (mwifiex_del_mgmt_ies(priv))
3192 wiphy_err(wiphy, "Failed to delete mgmt IEs!\n");
3193
3194 if (mwifiex_set_mgmt_ies(priv, &params->beacon_csa)) {
3195 wiphy_err(wiphy, "%s: setting mgmt ies failed\n", __func__);
3196 return -EFAULT;
3197 }
3198
3199 memcpy(&priv->dfs_chandef, &params->chandef, sizeof(priv->dfs_chandef));
3200 memcpy(&priv->beacon_after, &params->beacon_after,
3201 sizeof(priv->beacon_after));
3202
3203 chsw_msec = max(channel_sw->count * priv->bss_cfg.beacon_period, 100);
3204 queue_delayed_work(priv->dfs_chan_sw_workqueue, &priv->dfs_chan_sw_work,
3205 msecs_to_jiffies(chsw_msec));
3206 return 0;
3207}
3208
3209static int
3210mwifiex_cfg80211_start_radar_detection(struct wiphy *wiphy,
3211 struct net_device *dev,
3212 struct cfg80211_chan_def *chandef,
3213 u32 cac_time_ms)
3214{
3215 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
3216 struct mwifiex_radar_params radar_params;
3217
3218 if (priv->adapter->scan_processing) {
3219 dev_err(priv->adapter->dev,
3220 "radar detection: scan already in process...\n");
3221 return -EBUSY;
3222 }
3223
3224 if (!mwifiex_is_11h_active(priv)) {
3225 dev_dbg(priv->adapter->dev, "Enable 11h extensions in FW\n");
3226 if (mwifiex_11h_activate(priv, true)) {
3227 dev_err(priv->adapter->dev,
3228 "Failed to activate 11h extensions!!");
3229 return -1;
3230 }
3231 priv->state_11h.is_11h_active = true;
3232 }
3233
3234 memset(&radar_params, 0, sizeof(struct mwifiex_radar_params));
3235 radar_params.chandef = chandef;
3236 radar_params.cac_time_ms = cac_time_ms;
3237
3238 memcpy(&priv->dfs_chandef, chandef, sizeof(priv->dfs_chandef));
3239
3240 if (mwifiex_send_cmd(priv, HostCmd_CMD_CHAN_REPORT_REQUEST,
3241 HostCmd_ACT_GEN_SET, 0, &radar_params, true))
3242 return -1;
3243
3244 queue_delayed_work(priv->dfs_cac_workqueue, &priv->dfs_cac_work,
3245 msecs_to_jiffies(cac_time_ms));
3246 return 0;
3247}
3248
3249static int
2851mwifiex_cfg80211_change_station(struct wiphy *wiphy, struct net_device *dev, 3250mwifiex_cfg80211_change_station(struct wiphy *wiphy, struct net_device *dev,
2852 const u8 *mac, 3251 const u8 *mac,
2853 struct station_parameters *params) 3252 struct station_parameters *params)
@@ -2911,6 +3310,8 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
2911 .tdls_oper = mwifiex_cfg80211_tdls_oper, 3310 .tdls_oper = mwifiex_cfg80211_tdls_oper,
2912 .add_station = mwifiex_cfg80211_add_station, 3311 .add_station = mwifiex_cfg80211_add_station,
2913 .change_station = mwifiex_cfg80211_change_station, 3312 .change_station = mwifiex_cfg80211_change_station,
3313 .start_radar_detection = mwifiex_cfg80211_start_radar_detection,
3314 .channel_switch = mwifiex_cfg80211_channel_switch,
2914}; 3315};
2915 3316
2916#ifdef CONFIG_PM 3317#ifdef CONFIG_PM
@@ -3009,12 +3410,13 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
3009 wiphy->cipher_suites = mwifiex_cipher_suites; 3410 wiphy->cipher_suites = mwifiex_cipher_suites;
3010 wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites); 3411 wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites);
3011 3412
3012 memcpy(wiphy->perm_addr, priv->curr_addr, ETH_ALEN); 3413 ether_addr_copy(wiphy->perm_addr, adapter->perm_addr);
3013 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; 3414 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3014 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME | 3415 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
3015 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD | 3416 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
3016 WIPHY_FLAG_AP_UAPSD | 3417 WIPHY_FLAG_AP_UAPSD |
3017 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; 3418 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
3419 WIPHY_FLAG_HAS_CHANNEL_SWITCH;
3018 3420
3019 if (ISSUPP_TDLS_ENABLED(adapter->fw_cap_info)) 3421 if (ISSUPP_TDLS_ENABLED(adapter->fw_cap_info))
3020 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS | 3422 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS |