Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e48e0de0 authored by Avinash Patil's avatar Avinash Patil Committed by John W. Linville
Browse files

mwifiex: add cfg80211 add_station handler support



This patch adds cfg80211 add_station handler support for mwifiex
which is needed for TDLS setup. Driver issues create TDLS link
command to FW upon receiving add_station from cfg80211.

Signed-off-by: default avatarAvinash Patil <patila@marvell.com>
Signed-off-by: default avatarBing Zhao <bzhao@marvell.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 429d90d2
Loading
Loading
Loading
Loading
+18 −0
Original line number Original line Diff line number Diff line
@@ -2717,6 +2717,23 @@ mwifiex_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
	return mwifiex_tdls_oper(priv, peer, action);
	return mwifiex_tdls_oper(priv, peer, action);
}
}


static int
mwifiex_cfg80211_add_station(struct wiphy *wiphy,
			     struct net_device *dev,
			     u8 *mac, struct station_parameters *params)
{
	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);

	if (!(params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)))
		return -ENOTSUPP;

	/* make sure we are in station mode and connected */
	if ((priv->bss_type != MWIFIEX_BSS_TYPE_STA) || !priv->media_connected)
		return -ENOTSUPP;

	return mwifiex_tdls_oper(priv, mac, MWIFIEX_TDLS_CREATE_LINK);
}

/* station cfg80211 operations */
/* station cfg80211 operations */
static struct cfg80211_ops mwifiex_cfg80211_ops = {
static struct cfg80211_ops mwifiex_cfg80211_ops = {
	.add_virtual_intf = mwifiex_add_virtual_intf,
	.add_virtual_intf = mwifiex_add_virtual_intf,
@@ -2754,6 +2771,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
	.set_coalesce = mwifiex_cfg80211_set_coalesce,
	.set_coalesce = mwifiex_cfg80211_set_coalesce,
	.tdls_mgmt = mwifiex_cfg80211_tdls_mgmt,
	.tdls_mgmt = mwifiex_cfg80211_tdls_mgmt,
	.tdls_oper = mwifiex_cfg80211_tdls_oper,
	.tdls_oper = mwifiex_cfg80211_tdls_oper,
	.add_station = mwifiex_cfg80211_add_station,
};
};


#ifdef CONFIG_PM
#ifdef CONFIG_PM
+3 −0
Original line number Original line Diff line number Diff line
@@ -1300,6 +1300,9 @@ mwifiex_cmd_tdls_oper(struct mwifiex_private *priv,
	case MWIFIEX_TDLS_DISABLE_LINK:
	case MWIFIEX_TDLS_DISABLE_LINK:
		tdls_oper->tdls_action = cpu_to_le16(ACT_TDLS_DELETE);
		tdls_oper->tdls_action = cpu_to_le16(ACT_TDLS_DELETE);
		break;
		break;
	case MWIFIEX_TDLS_CREATE_LINK:
		tdls_oper->tdls_action = cpu_to_le16(ACT_TDLS_CREATE);
		break;
	default:
	default:
		dev_err(priv->adapter->dev, "Unknown TDLS operation\n");
		dev_err(priv->adapter->dev, "Unknown TDLS operation\n");
		return -ENOTSUPP;
		return -ENOTSUPP;
+15 −0
Original line number Original line Diff line number Diff line
@@ -807,6 +807,8 @@ static int mwifiex_ret_tdls_oper(struct mwifiex_private *priv,
	struct host_cmd_ds_tdls_oper *cmd_tdls_oper = &resp->params.tdls_oper;
	struct host_cmd_ds_tdls_oper *cmd_tdls_oper = &resp->params.tdls_oper;
	u16 reason = le16_to_cpu(cmd_tdls_oper->reason);
	u16 reason = le16_to_cpu(cmd_tdls_oper->reason);
	u16 action = le16_to_cpu(cmd_tdls_oper->tdls_action);
	u16 action = le16_to_cpu(cmd_tdls_oper->tdls_action);
	struct mwifiex_sta_node *node =
			   mwifiex_get_sta_entry(priv, cmd_tdls_oper->peer_mac);


	switch (action) {
	switch (action) {
	case ACT_TDLS_DELETE:
	case ACT_TDLS_DELETE:
@@ -819,6 +821,19 @@ static int mwifiex_ret_tdls_oper(struct mwifiex_private *priv,
				"TDLS link config for %pM successful\n",
				"TDLS link config for %pM successful\n",
				cmd_tdls_oper->peer_mac);
				cmd_tdls_oper->peer_mac);
		break;
		break;
	case ACT_TDLS_CREATE:
		if (reason) {
			dev_err(priv->adapter->dev,
				"TDLS link creation for %pM failed: reason %d",
				cmd_tdls_oper->peer_mac, reason);
			if (node && reason != TDLS_ERR_LINK_EXISTS)
				node->tdls_status = TDLS_SETUP_FAILURE;
		} else {
			dev_dbg(priv->adapter->dev,
				"TDLS link creation for %pM successful",
				cmd_tdls_oper->peer_mac);
		}
		break;
	default:
	default:
		dev_err(priv->adapter->dev,
		dev_err(priv->adapter->dev,
			"Unknown TDLS command action respnse %d", action);
			"Unknown TDLS command action respnse %d", action);
+28 −0
Original line number Original line Diff line number Diff line
@@ -543,6 +543,32 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
	return;
	return;
}
}


static int
mwifiex_tdls_process_create_link(struct mwifiex_private *priv, u8 *peer)
{
	struct mwifiex_sta_node *sta_ptr;
	struct mwifiex_ds_tdls_oper tdls_oper;

	memset(&tdls_oper, 0, sizeof(struct mwifiex_ds_tdls_oper));
	sta_ptr = mwifiex_get_sta_entry(priv, peer);

	if (sta_ptr && sta_ptr->tdls_status == TDLS_SETUP_INPROGRESS) {
		dev_dbg(priv->adapter->dev,
			"Setup already in progress for peer %pM\n", peer);
		return 0;
	}

	sta_ptr = mwifiex_add_sta_entry(priv, peer);
	if (!sta_ptr)
		return -ENOMEM;

	sta_ptr->tdls_status = TDLS_SETUP_INPROGRESS;
	memcpy(&tdls_oper.peer_mac, peer, ETH_ALEN);
	tdls_oper.tdls_action = MWIFIEX_TDLS_CREATE_LINK;
	return mwifiex_send_cmd_sync(priv, HostCmd_CMD_TDLS_OPER,
				     HostCmd_ACT_GEN_SET, 0, &tdls_oper);
}

static int
static int
mwifiex_tdls_process_disable_link(struct mwifiex_private *priv, u8 *peer)
mwifiex_tdls_process_disable_link(struct mwifiex_private *priv, u8 *peer)
{
{
@@ -634,6 +660,8 @@ int mwifiex_tdls_oper(struct mwifiex_private *priv, u8 *peer, u8 action)
		return mwifiex_tdls_process_enable_link(priv, peer);
		return mwifiex_tdls_process_enable_link(priv, peer);
	case MWIFIEX_TDLS_DISABLE_LINK:
	case MWIFIEX_TDLS_DISABLE_LINK:
		return mwifiex_tdls_process_disable_link(priv, peer);
		return mwifiex_tdls_process_disable_link(priv, peer);
	case MWIFIEX_TDLS_CREATE_LINK:
		return mwifiex_tdls_process_create_link(priv, peer);
	}
	}
	return 0;
	return 0;
}
}