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

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

Merge "wil6210: set edma variables only for Talyn-MB devices"

parents 29816c06 c3dcb56c
Loading
Loading
Loading
Loading
+325 −0
Original line number Diff line number Diff line
@@ -53,6 +53,49 @@ static struct ieee80211_channel wil_60ghz_channels[] = {
/* channel 4 not supported yet */
};

enum wil_nl_60g_cmd_type {
	NL_60G_CMD_FW_WMI,
	NL_60G_CMD_DEBUG,
	NL_60G_CMD_STATISTICS,
	NL_60G_CMD_REGISTER,
};

enum wil_nl_60g_evt_type {
	NL_60G_EVT_DRIVER_ERROR,
	NL_60G_EVT_FW_ERROR,
	NL_60G_EVT_FW_WMI,
	NL_60G_EVT_DRIVER_SHUTOWN,
	NL_60G_EVT_DRIVER_DEBUG_EVENT,
};

enum wil_nl_60g_debug_cmd {
	NL_60G_DBG_FORCE_WMI_SEND,
};

struct wil_nl_60g_send_receive_wmi {
	u32 cmd_id; /* enum wmi_command_id or enum wmi_event_id */
	u8 reserved[2];
	u8 dev_id; /* mid */
	u16 buf_len;
	u8 buf[0];
} __packed;

struct wil_nl_60g_event {
	u32 evt_type; /* wil_nl_60g_evt_type */
	u32 buf_len;
	u8 reserved[9];
	u8 buf[0];
} __packed;

struct wil_nl_60g_debug { /* NL_60G_CMD_DEBUG */
	u32 cmd_id; /* wil_nl_60g_debug_cmd */
} __packed;

struct wil_nl_60g_debug_force_wmi {
	struct wil_nl_60g_debug hdr;
	u32 enable;
} __packed;

/* Vendor id to be used in vendor specific command and events
 * to user space.
 * NOTE: The authoritative place for definition of QCA_NL80211_VENDOR_ID,
@@ -68,6 +111,8 @@ static struct ieee80211_channel wil_60ghz_channels[] = {

enum qca_wlan_vendor_attr_wil {
	QCA_ATTR_MAC_ADDR = 6,
	QCA_ATTR_FEATURE_FLAGS = 7,
	QCA_ATTR_TEST = 8,
	QCA_ATTR_PAD = 13,
	QCA_ATTR_TSF = 29,
	QCA_ATTR_DMG_RF_SECTOR_INDEX = 30,
@@ -79,6 +124,9 @@ enum qca_wlan_vendor_attr_wil {
	QCA_ATTR_WIL_MAX,
};

#define WIL_ATTR_60G_CMD_TYPE QCA_ATTR_FEATURE_FLAGS
#define WIL_ATTR_60G_BUF QCA_ATTR_TEST

enum qca_wlan_vendor_attr_dmg_rf_sector_type {
	QCA_ATTR_DMG_RF_SECTOR_TYPE_RX,
	QCA_ATTR_DMG_RF_SECTOR_TYPE_TX,
@@ -135,7 +183,14 @@ nla_policy wil_rf_sector_cfg_policy[QCA_ATTR_DMG_RF_SECTOR_CFG_MAX + 1] = {
	[QCA_ATTR_DMG_RF_SECTOR_CFG_DTYPE_X16] = { .type = NLA_U32 },
};

static const struct
nla_policy wil_nl_60g_policy[QCA_ATTR_WIL_MAX + 1] = {
	[WIL_ATTR_60G_CMD_TYPE] = { .type = NLA_U32 },
	[WIL_ATTR_60G_BUF] = { .type = NLA_BINARY },
};

enum qca_nl80211_vendor_subcmds {
	QCA_NL80211_VENDOR_SUBCMD_UNSPEC = 0,
	QCA_NL80211_VENDOR_SUBCMD_LOC_GET_CAPA = 128,
	QCA_NL80211_VENDOR_SUBCMD_FTM_START_SESSION = 129,
	QCA_NL80211_VENDOR_SUBCMD_FTM_ABORT_SESSION = 130,
@@ -167,6 +222,8 @@ static int wil_rf_sector_set_selected(struct wiphy *wiphy,
static int wil_brp_set_ant_limit(struct wiphy *wiphy, struct wireless_dev *wdev,
				 const void *data, int data_len);

static int wil_nl_60g_handle_cmd(struct wiphy *wiphy, struct wireless_dev *wdev,
				 const void *data, int data_len);
/* vendor specific commands */
static const struct wiphy_vendor_command wil_nl80211_vendor_commands[] = {
	{
@@ -248,6 +305,13 @@ static const struct wiphy_vendor_command wil_nl80211_vendor_commands[] = {
			 WIPHY_VENDOR_CMD_NEED_RUNNING,
		.doit = wil_brp_set_ant_limit
	},
	{
		.info.vendor_id = QCA_NL80211_VENDOR_ID,
		.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_UNSPEC,
		.flags = WIPHY_VENDOR_CMD_NEED_WDEV |
			 WIPHY_VENDOR_CMD_NEED_NETDEV,
		.doit = wil_nl_60g_handle_cmd
	},
};

/* vendor specific events */
@@ -264,6 +328,10 @@ static const struct nl80211_vendor_cmd_info wil_nl80211_vendor_events[] = {
			.vendor_id = QCA_NL80211_VENDOR_ID,
			.subcmd = QCA_NL80211_VENDOR_SUBCMD_AOA_MEAS_RESULT
	},
	[QCA_EVENT_UNSPEC_INDEX] = {
			.vendor_id = QCA_NL80211_VENDOR_ID,
			.subcmd = QCA_NL80211_VENDOR_SUBCMD_UNSPEC
	},
};

static struct ieee80211_supported_band wil_band_60ghz = {
@@ -356,6 +424,86 @@ int wil_iftype_nl2wmi(enum nl80211_iftype type)
	return -EOPNOTSUPP;
}

int wil_spec2wmi_ch(u8 spec_ch, u8 *wmi_ch)
{
	switch (spec_ch) {
	case 1:
		*wmi_ch = WMI_CHANNEL_1;
		break;
	case 2:
		*wmi_ch = WMI_CHANNEL_2;
		break;
	case 3:
		*wmi_ch = WMI_CHANNEL_3;
		break;
	case 4:
		*wmi_ch = WMI_CHANNEL_4;
		break;
	case 5:
		*wmi_ch = WMI_CHANNEL_5;
		break;
	case 6:
		*wmi_ch = WMI_CHANNEL_6;
		break;
	case 9:
		*wmi_ch = WMI_CHANNEL_9;
		break;
	case 10:
		*wmi_ch = WMI_CHANNEL_10;
		break;
	case 11:
		*wmi_ch = WMI_CHANNEL_11;
		break;
	case 12:
		*wmi_ch = WMI_CHANNEL_12;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

int wil_wmi2spec_ch(u8 wmi_ch, u8 *spec_ch)
{
	switch (wmi_ch) {
	case WMI_CHANNEL_1:
		*spec_ch = 1;
		break;
	case WMI_CHANNEL_2:
		*spec_ch = 2;
		break;
	case WMI_CHANNEL_3:
		*spec_ch = 3;
		break;
	case WMI_CHANNEL_4:
		*spec_ch = 4;
		break;
	case WMI_CHANNEL_5:
		*spec_ch = 5;
		break;
	case WMI_CHANNEL_6:
		*spec_ch = 6;
		break;
	case WMI_CHANNEL_9:
		*spec_ch = 9;
		break;
	case WMI_CHANNEL_10:
		*spec_ch = 10;
		break;
	case WMI_CHANNEL_11:
		*spec_ch = 11;
		break;
	case WMI_CHANNEL_12:
		*spec_ch = 12;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

int wil_cid_fill_sinfo(struct wil6210_vif *vif, int cid,
		       struct station_info *sinfo)
{
@@ -1103,6 +1251,16 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
	}
	conn.channel = ch - 1;

	if (test_bit(WMI_FW_CAPABILITY_CHANNEL_BONDING, wil->fw_capabilities))
		if (wil->force_edmg_channel) {
			rc = wil_spec2wmi_ch(wil->force_edmg_channel,
					     &conn.edmg_channel);
			if (rc)
				wil_err(wil,
					"wmi channel for channel %d not found",
					wil->force_edmg_channel);
		}

	ether_addr_copy(conn.bssid, bss->bssid);
	ether_addr_copy(conn.dst_mac, bss->bssid);

@@ -2965,3 +3123,170 @@ static int wil_brp_set_ant_limit(struct wiphy *wiphy, struct wireless_dev *wdev,
	return wil_brp_wmi_set_ant_limit(wil, vif->mid, cid, limit_mode,
					 antenna_num_limit);
}

static int wil_nl_60g_handle_cmd(struct wiphy *wiphy, struct wireless_dev *wdev,
				 const void *data, int data_len)
{
	struct wil6210_priv *wil = wdev_to_wil(wdev);
	struct nlattr *tb[QCA_ATTR_WIL_MAX + 1];
	struct wil_nl_60g_send_receive_wmi *cmd;
	struct wil_nl_60g_debug_force_wmi debug_force_wmi;
	int rc, len;
	u32 wil_nl_60g_cmd_type, publish;

	rc = nla_parse(tb, QCA_ATTR_WIL_MAX, data, data_len,
		       wil_nl_60g_policy, NULL);
	if (rc) {
		wil_err(wil, "Invalid nl_60g_cmd ATTR\n");
		return rc;
	}

	if (!tb[WIL_ATTR_60G_CMD_TYPE]) {
		wil_err(wil, "Invalid nl_60g_cmd type\n");
		return -EINVAL;
	}

	wil_nl_60g_cmd_type = nla_get_u32(tb[WIL_ATTR_60G_CMD_TYPE]);

	switch (wil_nl_60g_cmd_type) {
	case NL_60G_CMD_REGISTER:
		if (!tb[WIL_ATTR_60G_BUF]) {
			wil_err(wil, "Invalid nl_60g_cmd spec\n");
			return -EINVAL;
		}

		len = nla_len(tb[WIL_ATTR_60G_BUF]);
		if (len != sizeof(publish)) {
			wil_err(wil, "cmd buffer wrong len %d\n", len);
			return -EINVAL;
		}
		memcpy(&publish, nla_data(tb[WIL_ATTR_60G_BUF]), len);
		wil->publish_nl_evt = publish;

		wil_dbg_wmi(wil, "Publish wmi event %s\n",
			    publish ? "enabled" : "disabled");
		break;
	case NL_60G_CMD_DEBUG:
		if (!tb[WIL_ATTR_60G_BUF]) {
			wil_err(wil, "Invalid nl_60g_cmd spec\n");
			return -EINVAL;
		}

		len = nla_len(tb[WIL_ATTR_60G_BUF]);
		if (len < sizeof(struct wil_nl_60g_debug)) {
			wil_err(wil, "cmd buffer too short %d\n", len);
			return -EINVAL;
		}

		memcpy(&debug_force_wmi, nla_data(tb[WIL_ATTR_60G_BUF]),
		       sizeof(struct wil_nl_60g_debug));

		switch (debug_force_wmi.hdr.cmd_id) {
		case NL_60G_DBG_FORCE_WMI_SEND:
			if (len != sizeof(debug_force_wmi)) {
				wil_err(wil, "cmd buffer wrong len %d\n", len);
				return -EINVAL;
			}

			memcpy(&debug_force_wmi, nla_data(tb[WIL_ATTR_60G_BUF]),
			       sizeof(debug_force_wmi));
			wil->force_wmi_send = debug_force_wmi.enable;

			wil_dbg_wmi(wil, "force sending wmi commands %d\n",
				    wil->force_wmi_send);
			break;
		default:
			rc = -EINVAL;
			wil_err(wil, "invalid debug_cmd id %d",
				debug_force_wmi.hdr.cmd_id);
		}
		break;
	case NL_60G_CMD_FW_WMI:
		if (!tb[WIL_ATTR_60G_BUF]) {
			wil_err(wil, "Invalid nl_60g_cmd spec\n");
			return -EINVAL;
		}

		len = nla_len(tb[WIL_ATTR_60G_BUF]);
		if (len < offsetof(struct wil_nl_60g_send_receive_wmi, buf)) {
			wil_err(wil, "wmi cmd buffer too small\n");
			return -EINVAL;
		}

		cmd = kmalloc(len, GFP_KERNEL);
		if (!cmd)
			return -ENOMEM;

		memcpy(cmd, nla_data(tb[WIL_ATTR_60G_BUF]), (unsigned int)len);

		wil_dbg_wmi(wil, "sending user-space command (0x%04x) [%d]\n",
			    cmd->cmd_id, cmd->buf_len);

		if (wil->force_wmi_send)
			rc = wmi_force_send(wil, cmd->cmd_id, cmd->dev_id,
					    cmd->buf, cmd->buf_len);
		else
			rc = wmi_send(wil, cmd->cmd_id, cmd->dev_id,
				      cmd->buf, cmd->buf_len);

		kfree(cmd);
		break;
	default:
		rc = -EINVAL;
		wil_err(wil, "invalid nl_60g_cmd type %d", wil_nl_60g_cmd_type);
	}

	return rc;
}

void wil_nl_60g_receive_wmi_evt(struct wil6210_priv *wil, u8 *cmd, int len)
{
	struct sk_buff *vendor_event = NULL;
	struct wil_nl_60g_event *evt;
	struct wil_nl_60g_send_receive_wmi *wmi_buf;
	struct wmi_cmd_hdr *wmi_hdr = (struct wmi_cmd_hdr *)cmd;
	int data_len;

	if (!wil->publish_nl_evt)
		return;

	wil_dbg_wmi(wil, "report wmi event to user-space (0x%04x) [%d]\n",
		    le16_to_cpu(wmi_hdr->command_id), len);

	data_len = len - sizeof(struct wmi_cmd_hdr);

	evt = kzalloc(sizeof(*evt) + sizeof(*wmi_buf) + data_len, GFP_KERNEL);
	if (!evt)
		return;

	evt->evt_type = NL_60G_EVT_FW_WMI;
	evt->buf_len = sizeof(*wmi_buf) + data_len;

	wmi_buf = (struct wil_nl_60g_send_receive_wmi *)evt->buf;

	wmi_buf->cmd_id = le16_to_cpu(wmi_hdr->command_id);
	wmi_buf->dev_id = wmi_hdr->mid;
	wmi_buf->buf_len = data_len;
	memcpy(wmi_buf->buf, cmd + sizeof(struct wmi_cmd_hdr), data_len);

	vendor_event =
		cfg80211_vendor_event_alloc(wil_to_wiphy(wil),
					    NULL,
					    data_len + 4 + NLMSG_HDRLEN +
					    sizeof(*evt) + sizeof(*wmi_buf),
					    QCA_EVENT_UNSPEC_INDEX,
					    GFP_KERNEL);
	if (!vendor_event)
		goto out;

	if (nla_put(vendor_event, WIL_ATTR_60G_BUF,
		    sizeof(*evt) + sizeof(*wmi_buf) + data_len, evt)) {
		wil_err(wil, "failed to fill WIL_ATTR_60G_BUF\n");
		goto out;
	}

	cfg80211_vendor_event(vendor_event, GFP_KERNEL);

out:
	kfree(evt);
}
+6 −16
Original line number Diff line number Diff line
// SPDX-License-Identifier: ISC
/*
 * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
 */

#include <linux/module.h>
@@ -954,7 +943,7 @@ static ssize_t wil_read_pmccfg(struct file *file, char __user *user_buf,
	" - \"alloc <num descriptors> <descriptor_size>\" to allocate pmc\n"
	" - \"free\" to free memory allocated for pmc\n";

	sprintf(text, "Last command status: %d\n\n%s",
	snprintf(text, sizeof(text), "Last command status: %d\n\n%s",
		 wil_pmc_last_cmd_status(wil),
		 help);

@@ -2526,6 +2515,7 @@ static const struct dbg_off dbg_wil_off[] = {
	WIL_FIELD(tx_status_ring_order, 0644,	doff_u32),
	WIL_FIELD(rx_buff_id_count, 0644,	doff_u32),
	WIL_FIELD(amsdu_en, 0644,	doff_u8),
	WIL_FIELD(force_edmg_channel, 0644,	doff_u8),
	{},
};

+1 −0
Original line number Diff line number Diff line
@@ -401,6 +401,7 @@ enum qca_events_index {
	QCA_EVENT_FTM_MEAS_RESULT_INDEX,
	QCA_EVENT_FTM_SESSION_DONE_INDEX,
	QCA_EVENT_AOA_MEAS_RESULT_INDEX,
	QCA_EVENT_UNSPEC_INDEX,
};

/* measurement parameters. Specified for each peer as part
+7 −4
Original line number Diff line number Diff line
@@ -212,6 +212,7 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
	struct net_device *ndev = vif_to_ndev(vif);
	struct wireless_dev *wdev = vif_to_wdev(vif);
	struct wil_sta_info *sta = &wil->sta[cid];
	int min_ring_id = wil_get_min_tx_ring_id(wil);

	might_sleep();
	wil_dbg_misc(wil, "disconnect_cid: CID %d, MID %d, status %d\n",
@@ -263,7 +264,7 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
	memset(sta->tid_crypto_rx, 0, sizeof(sta->tid_crypto_rx));
	memset(&sta->group_crypto_rx, 0, sizeof(sta->group_crypto_rx));
	/* release vrings */
	for (i = 0; i < ARRAY_SIZE(wil->ring_tx); i++) {
	for (i = min_ring_id; i < ARRAY_SIZE(wil->ring_tx); i++) {
		if (wil->ring2cid_tid[i][0] == cid)
			wil_ring_fini_tx(wil, i);
	}
@@ -594,8 +595,10 @@ int wil_priv_init(struct wil6210_priv *wil)
		wil->sta[i].mid = U8_MAX;
	}

	for (i = 0; i < WIL6210_MAX_TX_RINGS; i++)
	for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) {
		spin_lock_init(&wil->ring_tx_data[i].lock);
		wil->ring2cid_tid[i][0] = WIL6210_MAX_CID;
	}

	mutex_init(&wil->mutex);
	mutex_init(&wil->vif_mutex);
@@ -643,8 +646,6 @@ int wil_priv_init(struct wil6210_priv *wil)

	/* edma configuration can be updated via debugfs before allocation */
	wil->num_rx_status_rings = WIL_DEFAULT_NUM_RX_STATUS_RINGS;
	wil->use_compressed_rx_status = true;
	wil->use_rx_hw_reordering = true;
	wil->tx_status_ring_order = WIL_TX_SRING_SIZE_ORDER_DEFAULT;

	/* Rx status ring size should be bigger than the number of RX buffers
@@ -1540,6 +1541,8 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)

	wmi_event_flush(wil);

	wil->force_wmi_send = false;

	flush_workqueue(wil->wq_service);
	flush_workqueue(wil->wmi_wq);

+1 −0
Original line number Diff line number Diff line
@@ -97,6 +97,7 @@ int wil_set_capabilities(struct wil6210_priv *wil)
		set_bit(hw_capa_no_flash, wil->hw_capa);
		wil->use_enhanced_dma_hw = true;
		wil->use_rx_hw_reordering = true;
		wil->use_compressed_rx_status = true;
		wil_fw_name = ftm_mode ? WIL_FW_NAME_FTM_TALYN :
			      WIL_FW_NAME_TALYN;
		if (wil_fw_verify_file_exists(wil, wil_fw_name))
Loading