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

Commit eb5272b9 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: ipa4: add wigig messages support"

parents c8973440 2451562b
Loading
Loading
Loading
Loading
+162 −14
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ struct ipa_wigig_context {
	struct ipa_wigig_rx_pipe_data_buffer_info_smmu rx_buff_smmu;
	struct ipa_wigig_tx_pipe_data_buffer_info_smmu
		tx_buff_smmu[IPA_WIGIG_TX_PIPE_NUM];
	char clients_mac[IPA_WIGIG_TX_PIPE_NUM][IPA_MAC_ADDR_SIZE];
};

static struct ipa_wigig_context *ipa_wigig_ctx;
@@ -216,35 +217,85 @@ static void ipa_wigig_free_msg(void *msg, uint32_t len, uint32_t type)
	IPA_WIGIG_DBG("exit\n");
}

static int ipa_wigig_send_msg(uint8_t msg_type,
	const char *netdev_name,
	u8 *netdev_mac)
static int ipa_wigig_send_wlan_msg(enum ipa_wlan_event msg_type,
	const char *netdev_name, u8 *mac)
{
	struct ipa_msg_meta msg_meta;
	struct ipa_wlan_msg *msg;
	struct ipa_wlan_msg *wlan_msg;
	int ret;

	IPA_WIGIG_DBG("\n");
	IPA_WIGIG_DBG("%d\n", msg_type);

	msg_meta.msg_type = msg_type;
	wlan_msg = kzalloc(sizeof(*wlan_msg), GFP_KERNEL);
	if (wlan_msg == NULL)
		return -ENOMEM;
	strlcpy(wlan_msg->name, netdev_name, IPA_RESOURCE_NAME_MAX);
	memcpy(wlan_msg->mac_addr, mac, IPA_MAC_ADDR_SIZE);
	msg_meta.msg_len = sizeof(struct ipa_wlan_msg);
	msg_meta.msg_type = msg_type;

	IPA_WIGIG_DBG("send msg type:%d, len:%d, buff %pK", msg_meta.msg_type,
		msg_meta.msg_len, wlan_msg);
	ret = ipa_send_msg(&msg_meta, wlan_msg, ipa_wigig_free_msg);

	IPA_WIGIG_DBG("exit\n");

	return ret;
}

int ipa_wigig_send_msg(int msg_type,
	const char *netdev_name, u8 *mac,
	enum ipa_client_type client, bool to_wigig)
{
	struct ipa_msg_meta msg_meta;
	struct ipa_wigig_msg *wigig_msg;
	int ret;

	msg = kzalloc(sizeof(*msg), GFP_KERNEL);
	if (msg == NULL)
	IPA_WIGIG_DBG("\n");

	wigig_msg = kzalloc(sizeof(struct ipa_wigig_msg), GFP_KERNEL);
	if (wigig_msg == NULL)
		return -ENOMEM;
	strlcpy(wigig_msg->name, netdev_name, IPA_RESOURCE_NAME_MAX);
	memcpy(wigig_msg->client_mac_addr, mac, IPA_MAC_ADDR_SIZE);
	if (msg_type == WIGIG_CLIENT_CONNECT)
		wigig_msg->u.ipa_client = client;
	else
		wigig_msg->u.to_wigig = to_wigig;

	strlcpy(msg->name, netdev_name, IPA_RESOURCE_NAME_MAX);
	memcpy(msg->mac_addr, netdev_mac, IPA_MAC_ADDR_SIZE);
	msg_meta.msg_type = msg_type;
	msg_meta.msg_len = sizeof(struct ipa_wigig_msg);

	IPA_WIGIG_DBG("send msg type:%d, len:%d, buff %pK", msg_meta.msg_type,
		msg_meta.msg_len, msg);
	ret = ipa_send_msg(&msg_meta, msg, ipa_wigig_free_msg);
		msg_meta.msg_len, wigig_msg);
	ret = ipa_send_msg(&msg_meta, wigig_msg, ipa_wigig_free_msg);

	IPA_WIGIG_DBG("exit\n");

	return ret;
}

static int ipa_wigig_get_devname(char *netdev_name)
{
	struct ipa_wigig_intf_info *entry;

	mutex_lock(&ipa_wigig_ctx->lock);

	if (!list_is_singular(&ipa_wigig_ctx->head_intf_list)) {
		IPA_WIGIG_DBG("list is not singular, was an IF registered?\n");
		mutex_unlock(&ipa_wigig_ctx->lock);
		return -EFAULT;
	}
	entry = list_first_entry(&ipa_wigig_ctx->head_intf_list,
		struct ipa_wigig_intf_info,
		link);
	strlcpy(netdev_name, entry->netdev_name, IPA_RESOURCE_NAME_MAX);

	mutex_unlock(&ipa_wigig_ctx->lock);

	return 0;
}

int ipa_wigig_reg_intf(
	struct ipa_wigig_reg_intf_in_params *in)
{
@@ -359,7 +410,7 @@ int ipa_wigig_reg_intf(
		goto fail_register;
	}

	if (ipa_wigig_send_msg(WLAN_AP_CONNECT,
	if (ipa_wigig_send_wlan_msg(WLAN_AP_CONNECT,
		in->netdev_name,
		in->netdev_mac)) {
		IPA_WIGIG_ERR("couldn't send msg to IPACM\n");
@@ -453,7 +504,7 @@ int ipa_wigig_dereg_intf(const char *netdev_name)
				goto fail;
			}

			if (ipa_wigig_send_msg(WLAN_AP_DISCONNECT,
			if (ipa_wigig_send_wlan_msg(WLAN_AP_DISCONNECT,
				entry->netdev_name,
				entry->netdev_mac)) {
				IPA_WIGIG_ERR("couldn't send msg to IPACM\n");
@@ -1088,9 +1139,43 @@ int ipa_wigig_set_perf_profile(u32 max_supported_bw_mbps)
}
EXPORT_SYMBOL(ipa_wigig_set_perf_profile);

static int ipa_wigig_store_client_mac(enum ipa_client_type client,
	const char *mac)
{
	unsigned int idx;

	if (ipa_wigig_client_to_idx(client, &idx)) {
		IPA_WIGIG_ERR("couldn't acquire idx\n");
		return -EFAULT;
	}
	memcpy(ipa_wigig_ctx->clients_mac[idx - 1], mac, IPA_MAC_ADDR_SIZE);
	return 0;
}

static int ipa_wigig_get_client_mac(enum ipa_client_type client, char *mac)
{
	unsigned int idx;

	if (ipa_wigig_client_to_idx(client, &idx)) {
		IPA_WIGIG_ERR("couldn't acquire idx\n");
		return -EFAULT;
	}
	memcpy(mac, ipa_wigig_ctx->clients_mac[idx - 1], IPA_MAC_ADDR_SIZE);
	return 0;
}

static int ipa_wigig_clean_client_mac(enum ipa_client_type client)
{
	char zero_mac[IPA_MAC_ADDR_SIZE] = { 0 };

	return ipa_wigig_store_client_mac(client, zero_mac);
}

int ipa_wigig_conn_client(struct ipa_wigig_conn_tx_in_params *in,
	struct ipa_wigig_conn_out_params *out)
{
	char dev_name[IPA_RESOURCE_NAME_MAX];

	IPA_WIGIG_DBG("\n");

	if (!in || !out) {
@@ -1113,6 +1198,11 @@ int ipa_wigig_conn_client(struct ipa_wigig_conn_tx_in_params *in,
		return -EFAULT;
	}

	if (ipa_wigig_get_devname(dev_name)) {
		IPA_WIGIG_ERR("couldn't get dev name\n");
		return -EFAULT;
	}

	if (ipa_conn_wigig_client_i(in, out)) {
		IPA_WIGIG_ERR(
			"fail to connect client. MAC [%X][%X][%X][%X][%X][%X]\n"
@@ -1121,8 +1211,20 @@ int ipa_wigig_conn_client(struct ipa_wigig_conn_tx_in_params *in,
		return -EFAULT;
	}

	if (ipa_wigig_send_msg(WIGIG_CLIENT_CONNECT,
		dev_name,
		in->client_mac, out->client, false)) {
		IPA_WIGIG_ERR("couldn't send msg to IPACM\n");
		goto fail_sendmsg;
	}

	ipa_wigig_store_client_mac(out->client, in->client_mac);

	IPA_WIGIG_DBG("exit\n");
	return 0;
fail_sendmsg:
	ipa_disconn_wigig_pipe_i(out->client, NULL, NULL);
	return -EFAULT;
}
EXPORT_SYMBOL(ipa_wigig_conn_client);

@@ -1130,6 +1232,7 @@ int ipa_wigig_conn_client_smmu(
	struct ipa_wigig_conn_tx_in_params_smmu *in,
	struct ipa_wigig_conn_out_params *out)
{
	char netdev_name[IPA_RESOURCE_NAME_MAX];
	int ret;

	IPA_WIGIG_DBG("\n");
@@ -1155,6 +1258,11 @@ int ipa_wigig_conn_client_smmu(
		return ret;
	}

	if (ipa_wigig_get_devname(netdev_name)) {
		IPA_WIGIG_ERR("couldn't get dev name\n");
		return -EFAULT;
	}

	if (ipa_conn_wigig_client_i(in, out)) {
		IPA_WIGIG_ERR(
			"fail to connect client. MAC [%X][%X][%X][%X][%X][%X]\n"
@@ -1164,14 +1272,31 @@ int ipa_wigig_conn_client_smmu(
		return -EFAULT;
	}

	if (ipa_wigig_send_msg(WIGIG_CLIENT_CONNECT,
		netdev_name,
		in->client_mac, out->client, false)) {
		IPA_WIGIG_ERR("couldn't send msg to IPACM\n");
		ret = -EFAULT;
		goto fail_sendmsg;
	}

	ret = ipa_wigig_store_client_smmu_info(in, out->client);
	if (ret)
		goto fail_smmu;

	ipa_wigig_store_client_mac(out->client, in->client_mac);

	IPA_WIGIG_DBG("exit\n");
	return 0;

fail_smmu:
	/*
	 * wigig clients are disconnected with legacy message since there is
	 * no need to send ep, client MAC is sufficient for disconnect
	 */
	ipa_wigig_send_wlan_msg(WLAN_CLIENT_DISCONNECT, netdev_name,
		in->client_mac);
fail_sendmsg:
	ipa_disconn_wigig_pipe_i(out->client, &in->pipe_smmu, &in->dbuff_smmu);
	return ret;
}
@@ -1197,6 +1322,8 @@ static inline int ipa_wigig_validate_client_type(enum ipa_client_type client)
int ipa_wigig_disconn_pipe(enum ipa_client_type client)
{
	int ret;
	char dev_name[IPA_RESOURCE_NAME_MAX];
	char client_mac[IPA_MAC_ADDR_SIZE];

	IPA_WIGIG_DBG("\n");

@@ -1204,6 +1331,18 @@ int ipa_wigig_disconn_pipe(enum ipa_client_type client)
	if (ret)
		return ret;

	if (client != IPA_CLIENT_WIGIG_PROD) {
		if (ipa_wigig_get_devname(dev_name)) {
			IPA_WIGIG_ERR("couldn't get dev name\n");
			return -EFAULT;
		}

		if (ipa_wigig_get_client_mac(client, client_mac)) {
			IPA_WIGIG_ERR("couldn't get client mac\n");
			return -EFAULT;
		}
	}

	IPA_WIGIG_DBG("disconnecting ipa_client_type %d\n", client);

	if (ipa_wigig_is_smmu_enabled()) {
@@ -1259,6 +1398,15 @@ int ipa_wigig_disconn_pipe(enum ipa_client_type client)
			IPA_WIGIG_ERR("failed dereg pm\n");
			WARN_ON(1);
		}
	} else {
		/*
		 * wigig clients are disconnected with legacy message since
		 * there is no need to send ep, client MAC is sufficient for
		 * disconnect.
		 */
		ipa_wigig_send_wlan_msg(WLAN_CLIENT_DISCONNECT, dev_name,
			client_mac);
		ipa_wigig_clean_client_mac(client);
	}
	if (ipa_wigig_is_smmu_enabled())
		ipa_wigig_clean_smmu_info(client);
+4 −0
Original line number Diff line number Diff line
@@ -462,4 +462,8 @@ int ipa_enable_wigig_pipe_i(enum ipa_client_type client);

int ipa_disable_wigig_pipe_i(enum ipa_client_type client);

int ipa_wigig_send_msg(int msg_type,
	const char *netdev_name, u8 *mac,
	enum ipa_client_type client, bool to_wigig);

#endif /* _IPA_COMMON_I_H_ */
+14 −0
Original line number Diff line number Diff line
@@ -678,6 +678,7 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
	struct ipa_ioc_rm_dependency rm_depend;
	struct ipa_ioc_nat_dma_cmd *table_dma_cmd;
	struct ipa_ioc_get_vlan_mode vlan_mode;
	struct ipa_ioc_wigig_fst_switch fst_switch;
	size_t sz;
	int pre_entry;

@@ -1793,6 +1794,19 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
		}
		break;

	case IPA_IOC_WIGIG_FST_SWITCH:
		IPADBG("Got IPA_IOCTL_WIGIG_FST_SWITCH\n");
		if (copy_from_user(&fst_switch, (const void __user *)arg,
			sizeof(struct ipa_ioc_wigig_fst_switch))) {
			retval = -EFAULT;
			break;
		}
		retval = ipa_wigig_send_msg(WIGIG_FST_SWITCH,
			fst_switch.netdev_name,
			fst_switch.client_mac_addr,
			IPA_CLIENT_MAX,
			fst_switch.to_wigig);
		break;
	default:
		IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
		return -ENOTTY;
+38 −1
Original line number Diff line number Diff line
@@ -110,6 +110,7 @@
#define IPA_IOCTL_ODL_QUERY_MODEM_CONFIG        63
#define IPA_IOCTL_GSB_CONNECT                   64
#define IPA_IOCTL_GSB_DISCONNECT                65
#define IPA_IOCTL_WIGIG_FST_SWITCH              66


/**
@@ -612,7 +613,11 @@ enum ipa_coalesce_event {
#define IPA_COALESCE_EVENT_MAX IPA_COALESCE_EVENT_MAX
};

#define IPA_EVENT_MAX_NUM (IPA_COALESCE_EVENT_MAX)
#define WIGIG_CLIENT_CONNECT (IPA_COALESCE_EVENT_MAX)
#define WIGIG_FST_SWITCH (WIGIG_CLIENT_CONNECT + 1)
#define WIGIG_EVENT_MAX (WIGIG_FST_SWITCH + 1)

#define IPA_EVENT_MAX_NUM (WIGIG_EVENT_MAX)
#define IPA_EVENT_MAX ((int)IPA_EVENT_MAX_NUM)

/**
@@ -1795,6 +1800,18 @@ struct ipa_ioc_gsb_info {
	char name[IPA_RESOURCE_NAME_MAX];
};

/**
 * struct ipa_ioc_wigig_fst_switch - switch between wigig and wlan
 * @netdev_name: wigig interface name
 * @client_mac_addr: client to switch between netdevs
 * @to_wigig: shall wlan client switch to wigig or the opposite?
 */
struct ipa_ioc_wigig_fst_switch {
	uint8_t netdev_name[IPA_RESOURCE_NAME_MAX];
	uint8_t client_mac_addr[IPA_MAC_ADDR_SIZE];
	int to_wigig;
};

/**
 * struct ipa_msg_meta - Format of the message meta-data.
 * @msg_type: the type of the message
@@ -1879,6 +1896,22 @@ struct ipa_wlan_msg_ex {
	struct ipa_wlan_hdr_attrib_val attribs[0];
};

/**
 * struct ipa_wigig_msg- To hold information about wigig event
 * @name: name of the wigig interface
 * @client_mac_addr: the relevant wigig client mac address
 * @ipa_client: TX pipe associated with the wigig client in case of connect
 * @to_wigig: FST switch direction wlan->wigig?
 */
struct ipa_wigig_msg {
	char name[IPA_RESOURCE_NAME_MAX];
	uint8_t client_mac_addr[IPA_MAC_ADDR_SIZE];
	union {
		enum ipa_client_type ipa_client;
		uint8_t to_wigig;
	} u;
};

struct ipa_ecm_msg {
	char name[IPA_RESOURCE_NAME_MAX];
	int ifindex;
@@ -2251,6 +2284,10 @@ struct ipa_odl_modem_config {
				IPA_IOCTL_GSB_DISCONNECT, \
				struct ipa_ioc_gsb_info)

#define IPA_IOC_WIGIG_FST_SWITCH _IOWR(IPA_IOC_MAGIC, \
				IPA_IOCTL_WIGIG_FST_SWITCH, \
				struct ipa_ioc_wigig_fst_switch)

/*
 * unique magic number of the Tethering bridge ioctls
 */