aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStone Piao <piaoyun@marvell.com>2012-09-25 23:23:42 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-09-28 13:54:05 -0400
commit9197ab9e5f3016ad05e1aa3e627ddf7d08927ccf (patch)
tree76e45b4eaf6ee8a9e848a2bbdf36d3a6026383ff
parente1a2b7a394ad8c2da9d7f4276680aa9c42e0bd97 (diff)
mwifiex: add support for P2P GO in interface type change
When cfg80211 calls to change interface type for P2P GO, send P2P mode config commands to firmware and set bss role and bss mode accordingly. Signed-off-by: Stone Piao <piaoyun@marvell.com> Signed-off-by: Avinash Patil <patila@marvell.com> Signed-off-by: Bing Zhao <bzhao@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c42
-rw-r--r--drivers/net/wireless/mwifiex/fw.h1
-rw-r--r--drivers/net/wireless/mwifiex/init.c13
-rw-r--r--drivers/net/wireless/mwifiex/main.h5
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c2
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c30
6 files changed, 90 insertions, 3 deletions
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 499060304d15..94ac40c50062 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -679,6 +679,9 @@ mwifiex_cfg80211_deinit_p2p(struct mwifiex_private *priv)
679{ 679{
680 u16 mode = P2P_MODE_DISABLE; 680 u16 mode = P2P_MODE_DISABLE;
681 681
682 if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_STA)
683 mwifiex_set_bss_role(priv, MWIFIEX_BSS_ROLE_STA);
684
682 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_P2P_MODE_CFG, 685 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_P2P_MODE_CFG,
683 HostCmd_ACT_GEN_SET, 0, &mode)) 686 HostCmd_ACT_GEN_SET, 0, &mode))
684 return -1; 687 return -1;
@@ -713,6 +716,35 @@ mwifiex_cfg80211_init_p2p_client(struct mwifiex_private *priv)
713} 716}
714 717
715/* 718/*
719 * This function initializes the functionalities for P2P GO.
720 * The P2P GO initialization sequence is:
721 * disable -> device -> GO
722 */
723static int
724mwifiex_cfg80211_init_p2p_go(struct mwifiex_private *priv)
725{
726 u16 mode;
727
728 if (mwifiex_cfg80211_deinit_p2p(priv))
729 return -1;
730
731 mode = P2P_MODE_DEVICE;
732 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_P2P_MODE_CFG,
733 HostCmd_ACT_GEN_SET, 0, &mode))
734 return -1;
735
736 mode = P2P_MODE_GO;
737 if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_P2P_MODE_CFG,
738 HostCmd_ACT_GEN_SET, 0, &mode))
739 return -1;
740
741 if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_UAP)
742 mwifiex_set_bss_role(priv, MWIFIEX_BSS_ROLE_UAP);
743
744 return 0;
745}
746
747/*
716 * CFG802.11 operation handler to change interface type. 748 * CFG802.11 operation handler to change interface type.
717 */ 749 */
718static int 750static int
@@ -749,6 +781,11 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
749 return -EFAULT; 781 return -EFAULT;
750 dev->ieee80211_ptr->iftype = type; 782 dev->ieee80211_ptr->iftype = type;
751 return 0; 783 return 0;
784 case NL80211_IFTYPE_P2P_GO:
785 if (mwifiex_cfg80211_init_p2p_go(priv))
786 return -EFAULT;
787 dev->ieee80211_ptr->iftype = type;
788 return 0;
752 case NL80211_IFTYPE_UNSPECIFIED: 789 case NL80211_IFTYPE_UNSPECIFIED:
753 wiphy_warn(wiphy, "%s: kept type as STA\n", dev->name); 790 wiphy_warn(wiphy, "%s: kept type as STA\n", dev->name);
754 case NL80211_IFTYPE_STATION: /* This shouldn't happen */ 791 case NL80211_IFTYPE_STATION: /* This shouldn't happen */
@@ -775,6 +812,7 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
775 } 812 }
776 break; 813 break;
777 case NL80211_IFTYPE_P2P_CLIENT: 814 case NL80211_IFTYPE_P2P_CLIENT:
815 case NL80211_IFTYPE_P2P_GO:
778 switch (type) { 816 switch (type) {
779 case NL80211_IFTYPE_STATION: 817 case NL80211_IFTYPE_STATION:
780 if (mwifiex_cfg80211_deinit_p2p(priv)) 818 if (mwifiex_cfg80211_deinit_p2p(priv))
@@ -1135,7 +1173,7 @@ static int mwifiex_cfg80211_change_beacon(struct wiphy *wiphy,
1135{ 1173{
1136 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 1174 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1137 1175
1138 if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) { 1176 if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_UAP) {
1139 wiphy_err(wiphy, "%s: bss_type mismatched\n", __func__); 1177 wiphy_err(wiphy, "%s: bss_type mismatched\n", __func__);
1140 return -EINVAL; 1178 return -EINVAL;
1141 } 1179 }
@@ -1223,7 +1261,7 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
1223 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 1261 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1224 u8 config_bands = 0; 1262 u8 config_bands = 0;
1225 1263
1226 if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) 1264 if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_UAP)
1227 return -1; 1265 return -1;
1228 if (mwifiex_set_mgmt_ies(priv, &params->beacon)) 1266 if (mwifiex_set_mgmt_ies(priv, &params->beacon))
1229 return -1; 1267 return -1;
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 7887848448e9..857af0f9542c 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -1379,6 +1379,7 @@ struct host_cmd_ds_802_11_ibss_status {
1379 1379
1380#define CONNECTION_TYPE_INFRA 0 1380#define CONNECTION_TYPE_INFRA 0
1381#define CONNECTION_TYPE_ADHOC 1 1381#define CONNECTION_TYPE_ADHOC 1
1382#define CONNECTION_TYPE_AP 2
1382 1383
1383struct host_cmd_ds_set_bss_mode { 1384struct host_cmd_ds_set_bss_mode {
1384 u8 con_type; 1385 u8 con_type;
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index fa96dc328a5b..b5d37a8caa09 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -144,7 +144,7 @@ done:
144 * Additionally, it also initializes all the locks and sets up all the 144 * Additionally, it also initializes all the locks and sets up all the
145 * lists. 145 * lists.
146 */ 146 */
147static int mwifiex_init_priv(struct mwifiex_private *priv) 147int mwifiex_init_priv(struct mwifiex_private *priv)
148{ 148{
149 u32 i; 149 u32 i;
150 150
@@ -649,6 +649,17 @@ static void mwifiex_delete_bss_prio_tbl(struct mwifiex_private *priv)
649} 649}
650 650
651/* 651/*
652 * This function frees the private structure, including cleans
653 * up the TX and RX queues and frees the BSS priority tables.
654 */
655void mwifiex_free_priv(struct mwifiex_private *priv)
656{
657 mwifiex_clean_txrx(priv);
658 mwifiex_delete_bss_prio_tbl(priv);
659 mwifiex_free_curr_bcn(priv);
660}
661
662/*
652 * This function is used to shutdown the driver. 663 * This function is used to shutdown the driver.
653 * 664 *
654 * The following operations are performed sequentially - 665 * The following operations are performed sequentially -
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 89ba66e56143..956312f45e60 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -736,6 +736,9 @@ void mwifiex_stop_net_dev_queue(struct net_device *netdev,
736void mwifiex_wake_up_net_dev_queue(struct net_device *netdev, 736void mwifiex_wake_up_net_dev_queue(struct net_device *netdev,
737 struct mwifiex_adapter *adapter); 737 struct mwifiex_adapter *adapter);
738 738
739int mwifiex_init_priv(struct mwifiex_private *priv);
740void mwifiex_free_priv(struct mwifiex_private *priv);
741
739int mwifiex_init_fw(struct mwifiex_adapter *adapter); 742int mwifiex_init_fw(struct mwifiex_adapter *adapter);
740 743
741int mwifiex_init_fw_complete(struct mwifiex_adapter *adapter); 744int mwifiex_init_fw_complete(struct mwifiex_adapter *adapter);
@@ -1018,6 +1021,8 @@ int mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action,
1018 enum nl80211_channel_type *channel_type, 1021 enum nl80211_channel_type *channel_type,
1019 unsigned int duration); 1022 unsigned int duration);
1020 1023
1024int mwifiex_set_bss_role(struct mwifiex_private *priv, u8 bss_role);
1025
1021int mwifiex_get_stats_info(struct mwifiex_private *priv, 1026int mwifiex_get_stats_info(struct mwifiex_private *priv,
1022 struct mwifiex_ds_get_stats *log); 1027 struct mwifiex_ds_get_stats *log);
1023 1028
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index 704cfaaeba14..5d87195390f8 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -1261,6 +1261,8 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
1261 else if (priv->bss_mode == NL80211_IFTYPE_STATION) 1261 else if (priv->bss_mode == NL80211_IFTYPE_STATION)
1262 cmd_ptr->params.bss_mode.con_type = 1262 cmd_ptr->params.bss_mode.con_type =
1263 CONNECTION_TYPE_INFRA; 1263 CONNECTION_TYPE_INFRA;
1264 else if (priv->bss_mode == NL80211_IFTYPE_AP)
1265 cmd_ptr->params.bss_mode.con_type = CONNECTION_TYPE_AP;
1264 cmd_ptr->size = cpu_to_le16(sizeof(struct 1266 cmd_ptr->size = cpu_to_le16(sizeof(struct
1265 host_cmd_ds_set_bss_mode) + S_DS_GEN); 1267 host_cmd_ds_set_bss_mode) + S_DS_GEN);
1266 ret = 0; 1268 ret = 0;
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index fd09a21b8824..0c9f70b2cbe6 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -1072,6 +1072,36 @@ mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action,
1072 return roc_cfg.status; 1072 return roc_cfg.status;
1073} 1073}
1074 1074
1075int
1076mwifiex_set_bss_role(struct mwifiex_private *priv, u8 bss_role)
1077{
1078 if (GET_BSS_ROLE(priv) == bss_role) {
1079 dev_dbg(priv->adapter->dev,
1080 "info: already in the desired role.\n");
1081 return 0;
1082 }
1083
1084 mwifiex_free_priv(priv);
1085 mwifiex_init_priv(priv);
1086
1087 priv->bss_role = bss_role;
1088 switch (bss_role) {
1089 case MWIFIEX_BSS_ROLE_UAP:
1090 priv->bss_mode = NL80211_IFTYPE_AP;
1091 break;
1092 case MWIFIEX_BSS_ROLE_STA:
1093 case MWIFIEX_BSS_ROLE_ANY:
1094 default:
1095 priv->bss_mode = NL80211_IFTYPE_STATION;
1096 break;
1097 }
1098
1099 mwifiex_send_cmd_sync(priv, HostCmd_CMD_SET_BSS_MODE,
1100 HostCmd_ACT_GEN_SET, 0, NULL);
1101
1102 return mwifiex_sta_init_cmd(priv, false);
1103}
1104
1075/* 1105/*
1076 * Sends IOCTL request to get statistics information. 1106 * Sends IOCTL request to get statistics information.
1077 * 1107 *