Skip to content

Commit

Permalink
mwifiex: add support for P2P client in interface type change
Browse files Browse the repository at this point in the history
When cfg80211 calls to change interface type for P2P client,
send P2P mode config commands to firmware.

Signed-off-by: Stone Piao <piaoyun@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Stone Piao authored and John W. Linville committed Sep 28, 2012
1 parent 197f4a2 commit e1a2b7a
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 0 deletions.
54 changes: 54 additions & 0 deletions drivers/net/wireless/mwifiex/cfg80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,44 @@ mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
return 0;
}

static int
mwifiex_cfg80211_deinit_p2p(struct mwifiex_private *priv)
{
u16 mode = P2P_MODE_DISABLE;

if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_P2P_MODE_CFG,
HostCmd_ACT_GEN_SET, 0, &mode))
return -1;

return 0;
}

/*
* This function initializes the functionalities for P2P client.
* The P2P client initialization sequence is:
* disable -> device -> client
*/
static int
mwifiex_cfg80211_init_p2p_client(struct mwifiex_private *priv)
{
u16 mode;

if (mwifiex_cfg80211_deinit_p2p(priv))
return -1;

mode = P2P_MODE_DEVICE;
if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_P2P_MODE_CFG,
HostCmd_ACT_GEN_SET, 0, &mode))
return -1;

mode = P2P_MODE_CLIENT;
if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_P2P_MODE_CFG,
HostCmd_ACT_GEN_SET, 0, &mode))
return -1;

return 0;
}

/*
* CFG802.11 operation handler to change interface type.
*/
Expand Down Expand Up @@ -706,6 +744,11 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
switch (type) {
case NL80211_IFTYPE_ADHOC:
break;
case NL80211_IFTYPE_P2P_CLIENT:
if (mwifiex_cfg80211_init_p2p_client(priv))
return -EFAULT;
dev->ieee80211_ptr->iftype = type;
return 0;
case NL80211_IFTYPE_UNSPECIFIED:
wiphy_warn(wiphy, "%s: kept type as STA\n", dev->name);
case NL80211_IFTYPE_STATION: /* This shouldn't happen */
Expand All @@ -731,6 +774,17 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
return -EOPNOTSUPP;
}
break;
case NL80211_IFTYPE_P2P_CLIENT:
switch (type) {
case NL80211_IFTYPE_STATION:
if (mwifiex_cfg80211_deinit_p2p(priv))
return -EFAULT;
dev->ieee80211_ptr->iftype = type;
return 0;
default:
return -EOPNOTSUPP;
}
break;
default:
wiphy_err(wiphy, "%s: unknown iftype: %d\n",
dev->name, dev->ieee80211_ptr->iftype);
Expand Down
14 changes: 14 additions & 0 deletions drivers/net/wireless/mwifiex/fw.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
#define HostCmd_CMD_TX_RATE_CFG 0x00d6
#define HostCmd_CMD_802_11_PS_MODE_ENH 0x00e4
#define HostCmd_CMD_802_11_HS_CFG_ENH 0x00e5
#define HostCmd_CMD_P2P_MODE_CFG 0x00eb
#define HostCmd_CMD_CAU_REG_ACCESS 0x00ed
#define HostCmd_CMD_SET_BSS_MODE 0x00f7
#define HostCmd_CMD_PCIE_DESC_DETAILS 0x00fa
Expand Down Expand Up @@ -291,6 +292,13 @@ enum ENH_PS_MODES {
DIS_AUTO_PS = 0xfe,
};

enum P2P_MODES {
P2P_MODE_DISABLE = 0,
P2P_MODE_DEVICE = 1,
P2P_MODE_GO = 2,
P2P_MODE_CLIENT = 3,
};

#define HostCmd_RET_BIT 0x8000
#define HostCmd_ACT_GEN_GET 0x0000
#define HostCmd_ACT_GEN_SET 0x0001
Expand Down Expand Up @@ -1346,6 +1354,11 @@ struct host_cmd_ds_mgmt_frame_reg {
__le32 mask;
} __packed;

struct host_cmd_ds_p2p_mode_cfg {
__le16 action;
__le16 mode;
} __packed;

struct host_cmd_ds_remain_on_chan {
__le16 action;
u8 status;
Expand Down Expand Up @@ -1465,6 +1478,7 @@ struct host_cmd_ds_command {
struct host_cmd_ds_version_ext verext;
struct host_cmd_ds_mgmt_frame_reg reg_mask;
struct host_cmd_ds_remain_on_chan roc_cfg;
struct host_cmd_ds_p2p_mode_cfg mode_cfg;
struct host_cmd_ds_802_11_ibss_status ibss_coalescing;
struct host_cmd_ds_mac_reg_access mac_reg;
struct host_cmd_ds_bbp_reg_access bbp_reg;
Expand Down
8 changes: 8 additions & 0 deletions drivers/net/wireless/mwifiex/sta_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1184,6 +1184,14 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
cpu_to_le16(sizeof(struct host_cmd_ds_remain_on_chan) +
S_DS_GEN);
break;
case HostCmd_CMD_P2P_MODE_CFG:
cmd_ptr->command = cpu_to_le16(cmd_no);
cmd_ptr->params.mode_cfg.action = cpu_to_le16(cmd_action);
cmd_ptr->params.mode_cfg.mode = cpu_to_le16(*(u16 *)data_buf);
cmd_ptr->size =
cpu_to_le16(sizeof(struct host_cmd_ds_p2p_mode_cfg) +
S_DS_GEN);
break;
case HostCmd_CMD_FUNC_INIT:
if (priv->adapter->hw_status == MWIFIEX_HW_STATUS_RESET)
priv->adapter->hw_status = MWIFIEX_HW_STATUS_READY;
Expand Down
19 changes: 19 additions & 0 deletions drivers/net/wireless/mwifiex/sta_cmdresp.c
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,22 @@ mwifiex_ret_remain_on_chan(struct mwifiex_private *priv,
return 0;
}

/*
* This function handles the command response of P2P mode cfg.
*/
static int
mwifiex_ret_p2p_mode_cfg(struct mwifiex_private *priv,
struct host_cmd_ds_command *resp,
void *data_buf)
{
struct host_cmd_ds_p2p_mode_cfg *mode_cfg = &resp->params.mode_cfg;

if (data_buf)
*((u16 *)data_buf) = le16_to_cpu(mode_cfg->mode);

return 0;
}

/*
* This function handles the command response of register access.
*
Expand Down Expand Up @@ -894,6 +910,9 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
case HostCmd_CMD_REMAIN_ON_CHAN:
ret = mwifiex_ret_remain_on_chan(priv, resp, data_buf);
break;
case HostCmd_CMD_P2P_MODE_CFG:
ret = mwifiex_ret_p2p_mode_cfg(priv, resp, data_buf);
break;
case HostCmd_CMD_MGMT_FRAME_REG:
case HostCmd_CMD_FUNC_INIT:
case HostCmd_CMD_FUNC_SHUTDOWN:
Expand Down

0 comments on commit e1a2b7a

Please sign in to comment.