Ejemplo n.º 1
0
int wl1251_acx_fw_version(struct wl1251 *wl, char *buf, size_t len)
{
	struct acx_revision *rev;
	int ret;

	wl1251_debug(DEBUG_ACX, "acx fw rev");

	rev = kzalloc(sizeof(*rev), GFP_KERNEL);
	if (!rev)
		return -ENOMEM;

	ret = wl1251_cmd_interrogate(wl, ACX_FW_REV, rev, sizeof(*rev));
	if (ret < 0) {
		wl1251_warning("ACX_FW_REV interrogate failed");
		goto out;
	}

	/* be careful with the buffer sizes */
	strncpy(buf, rev->fw_version, min(len, sizeof(rev->fw_version)));

	/*
	 * if the firmware version string is exactly
	 * sizeof(rev->fw_version) long or fw_len is less than
	 * sizeof(rev->fw_version) it won't be null terminated
	 */
	buf[min(len, sizeof(rev->fw_version)) - 1] = '\0';

out:
	kfree(rev);
	return ret;
}
Ejemplo n.º 2
0
int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime)
{
	struct acx_tsf_info *tsf_info;
	int ret;

	tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL);
	if (!tsf_info) {
		ret = -ENOMEM;
		goto out;
	}

	ret = wl1251_cmd_interrogate(wl, ACX_TSF_INFO,
				     tsf_info, sizeof(*tsf_info));
	if (ret < 0) {
		wl1251_warning("ACX_FW_REV interrogate failed");
		goto out;
	}

	*mactime = tsf_info->current_tsf_lsb |
		(tsf_info->current_tsf_msb << 31);

out:
	kfree(tsf_info);
	return ret;
}
Ejemplo n.º 3
0
int wl1251_acx_mem_map(struct wl1251 *wl, struct acx_header *mem_map,
		       size_t len)
{
	int ret;

	wl1251_debug(DEBUG_ACX, "acx mem map");

	ret = wl1251_cmd_interrogate(wl, ACX_MEM_MAP, mem_map, len);
	if (ret < 0)
		return ret;

	return 0;
}
Ejemplo n.º 4
0
int wl1251_acx_statistics(struct wl1251 *wl, struct acx_statistics *stats)
{
	int ret;

	wl1251_debug(DEBUG_ACX, "acx statistics");

	ret = wl1251_cmd_interrogate(wl, ACX_STATISTICS, stats,
				     sizeof(*stats));
	if (ret < 0) {
		wl1251_warning("acx statistics failed: %d", ret);
		return -ENOMEM;
	}

	return 0;
}
Ejemplo n.º 5
0
int wl1251_acx_data_path_params(struct wl1251 *wl,
				struct acx_data_path_params_resp *resp)
{
	struct acx_data_path_params *params;
	int ret;

	wl1251_debug(DEBUG_ACX, "acx data path params");

	params = kzalloc(sizeof(*params), GFP_KERNEL);
	if (!params) {
		ret = -ENOMEM;
		goto out;
	}

	params->rx_packet_ring_chunk_size = DP_RX_PACKET_RING_CHUNK_SIZE;
	params->tx_packet_ring_chunk_size = DP_TX_PACKET_RING_CHUNK_SIZE;

	params->rx_packet_ring_chunk_num = DP_RX_PACKET_RING_CHUNK_NUM;
	params->tx_packet_ring_chunk_num = DP_TX_PACKET_RING_CHUNK_NUM;

	params->tx_complete_threshold = 1;

	params->tx_complete_ring_depth = FW_TX_CMPLT_BLOCK_SIZE;

	params->tx_complete_timeout = DP_TX_COMPLETE_TIME_OUT;

	ret = wl1251_cmd_configure(wl, ACX_DATA_PATH_PARAMS,
				   params, sizeof(*params));
	if (ret < 0)
		goto out;

	/* FIXME: shouldn't this be ACX_DATA_PATH_RESP_PARAMS? */
	ret = wl1251_cmd_interrogate(wl, ACX_DATA_PATH_PARAMS,
				     resp, sizeof(*resp));

	if (ret < 0) {
		wl1251_warning("failed to read data path parameters: %d", ret);
		goto out;
	} else if (resp->header.cmd.status != CMD_STATUS_SUCCESS) {
		wl1251_warning("data path parameter acx status failed");
		ret = -EIO;
		goto out;
	}

out:
	kfree(params);
	return ret;
}
Ejemplo n.º 6
0
static int wl1251_nl_interrogate(struct sk_buff *skb, struct genl_info *info)
{
	struct wl1251 *wl;
	struct sk_buff *msg;
	int ret = -ENOBUFS, cmd_ie, cmd_ie_len;
	struct wl1251_command *cmd;
	void *hdr;

	if (!info->attrs[WL1251_NL_ATTR_CMD_IE])
		return -EINVAL;

	if (!info->attrs[WL1251_NL_ATTR_CMD_IE_LEN])
		return -EINVAL;

	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
	if (!cmd)
		return -ENOMEM;

	msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
	if (!msg)
		return -ENOMEM;

	wl = ifname_to_wl1251(&init_net, info);
	if (wl == NULL) {
		wl1251_error("wl1251 not found");
		ret = -EINVAL;
		goto nla_put_failure;
	}

	/* acx id */
	cmd_ie = nla_get_u32(info->attrs[WL1251_NL_ATTR_CMD_IE]);

	/* maximum length of acx, including all headers */
	cmd_ie_len = nla_get_u32(info->attrs[WL1251_NL_ATTR_CMD_IE_LEN]);

	wl1251_debug(DEBUG_NETLINK, "Getting IE 0x%x (len %d)",
		     cmd_ie, cmd_ie_len);

	mutex_lock(&wl->mutex);
	ret = wl1251_cmd_interrogate(wl, cmd_ie, cmd, cmd_ie_len);
	mutex_unlock(&wl->mutex);

	if (ret < 0) {
		wl1251_error("%s() failed", __func__);
		goto nla_put_failure;
	}

	hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq,
			  &wl1251_nl_family, 0, WL1251_NL_CMD_INTERROGATE);
	if (IS_ERR(hdr)) {
		ret = PTR_ERR(hdr);
		goto nla_put_failure;
	}

	NLA_PUT_STRING(msg, WL1251_NL_ATTR_IFNAME,
		       nla_data(info->attrs[WL1251_NL_ATTR_IFNAME]));
	NLA_PUT(msg, WL1251_NL_ATTR_CMD_IE_ANSWER, cmd_ie_len, cmd);

	ret = genlmsg_end(msg, hdr);
	if (ret < 0) {
		wl1251_error("%s() failed", __func__);
		goto nla_put_failure;
	}

	kfree(cmd);
	return genlmsg_reply(msg, info);

 nla_put_failure:
	kfree(cmd);
	nlmsg_free(msg);

	return ret;
}