示例#1
0
文件: dhd_common.c 项目: 3null/linux
static void brcmf_c_pktfilter_offload_set(struct brcmf_if *ifp, char *arg)
{
	struct brcmf_pkt_filter_le *pkt_filter;
	unsigned long res;
	int buf_len;
	s32 err;
	u32 mask_size;
	u32 pattern_size;
	char *argv[8], *buf = NULL;
	int i = 0;
	char *arg_save = NULL, *arg_org = NULL;

	arg_save = kstrdup(arg, GFP_ATOMIC);
	if (!arg_save)
		goto fail;

	arg_org = arg_save;

	buf = kmalloc(PKTFILTER_BUF_SIZE, GFP_ATOMIC);
	if (!buf)
		goto fail;

	argv[i] = strsep(&arg_save, " ");
	while (argv[i]) {
		i++;
		if (i >= 8) {
			brcmf_err("Too many parameters\n");
			goto fail;
		}
		argv[i] = strsep(&arg_save, " ");
	}

	if (i != 6) {
		brcmf_err("Not enough args provided %d\n", i);
		goto fail;
	}

	pkt_filter = (struct brcmf_pkt_filter_le *)buf;

	/* Parse packet filter id. */
	pkt_filter->id = 0;
	if (!kstrtoul(argv[0], 0, &res))
		pkt_filter->id = cpu_to_le32((u32)res);

	/* Parse filter polarity. */
	pkt_filter->negate_match = 0;
	if (!kstrtoul(argv[1], 0, &res))
		pkt_filter->negate_match = cpu_to_le32((u32)res);

	/* Parse filter type. */
	pkt_filter->type = 0;
	if (!kstrtoul(argv[2], 0, &res))
		pkt_filter->type = cpu_to_le32((u32)res);

	/* Parse pattern filter offset. */
	pkt_filter->u.pattern.offset = 0;
	if (!kstrtoul(argv[3], 0, &res))
		pkt_filter->u.pattern.offset = cpu_to_le32((u32)res);

	/* Parse pattern filter mask. */
	mask_size = brcmf_c_pattern_atoh(argv[4],
			(char *)pkt_filter->u.pattern.mask_and_pattern);

	/* Parse pattern filter pattern. */
	pattern_size = brcmf_c_pattern_atoh(argv[5],
		(char *)&pkt_filter->u.pattern.mask_and_pattern[mask_size]);

	if (mask_size != pattern_size) {
		brcmf_err("Mask and pattern not the same size\n");
		goto fail;
	}

	pkt_filter->u.pattern.size_bytes = cpu_to_le32(mask_size);
	buf_len = offsetof(struct brcmf_pkt_filter_le,
			   u.pattern.mask_and_pattern);
	buf_len += mask_size + pattern_size;

	err = brcmf_fil_iovar_data_set(ifp, "pkt_filter_add", pkt_filter,
				       buf_len);
	if (err)
		brcmf_err("Set pkt_filter_add error (%d)\n", err);

fail:
	kfree(arg_org);

	kfree(buf);
}
示例#2
0
void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg)
{
	const char *str;
	struct brcmf_pkt_filter pkt_filter;
	struct brcmf_pkt_filter *pkt_filterp;
	int buf_len;
	int str_len;
	int rc;
	u32 mask_size;
	u32 pattern_size;
	char *argv[8], *buf = 0;
	int i = 0;
	char *arg_save = 0, *arg_org = 0;

	arg_save = kmalloc(strlen(arg) + 1, GFP_ATOMIC);
	if (!arg_save) {
		BRCMF_ERROR(("%s: kmalloc failed\n", __func__));
		goto fail;
	}

	arg_org = arg_save;

	buf = kmalloc(PKTFILTER_BUF_SIZE, GFP_ATOMIC);
	if (!buf) {
		BRCMF_ERROR(("%s: kmalloc failed\n", __func__));
		goto fail;
	}

	strcpy(arg_save, arg);

	argv[i] = strsep(&arg_save, " ");
	while (argv[i++])
		argv[i] = strsep(&arg_save, " ");

	i = 0;
	if (NULL == argv[i]) {
		BRCMF_ERROR(("No args provided\n"));
		goto fail;
	}

	str = "pkt_filter_add";
	strcpy(buf, str);
	str_len = strlen(str);
	buf_len = str_len + 1;

	pkt_filterp = (struct brcmf_pkt_filter *) (buf + str_len + 1);

	/* Parse packet filter id. */
	pkt_filter.id = simple_strtoul(argv[i], NULL, 0);

	if (NULL == argv[++i]) {
		BRCMF_ERROR(("Polarity not provided\n"));
		goto fail;
	}

	/* Parse filter polarity. */
	pkt_filter.negate_match = simple_strtoul(argv[i], NULL, 0);

	if (NULL == argv[++i]) {
		BRCMF_ERROR(("Filter type not provided\n"));
		goto fail;
	}

	/* Parse filter type. */
	pkt_filter.type = simple_strtoul(argv[i], NULL, 0);

	if (NULL == argv[++i]) {
		BRCMF_ERROR(("Offset not provided\n"));
		goto fail;
	}

	/* Parse pattern filter offset. */
	pkt_filter.u.pattern.offset = simple_strtoul(argv[i], NULL, 0);

	if (NULL == argv[++i]) {
		BRCMF_ERROR(("Bitmask not provided\n"));
		goto fail;
	}

	/* Parse pattern filter mask. */
	mask_size =
	    brcmf_c_pattern_atoh
		   (argv[i], (char *)pkt_filterp->u.pattern.mask_and_pattern);

	if (NULL == argv[++i]) {
		BRCMF_ERROR(("Pattern not provided\n"));
		goto fail;
	}

	/* Parse pattern filter pattern. */
	pattern_size =
	    brcmf_c_pattern_atoh(argv[i],
				   (char *)&pkt_filterp->u.pattern.
				   mask_and_pattern[mask_size]);

	if (mask_size != pattern_size) {
		BRCMF_ERROR(("Mask and pattern not the same size\n"));
		goto fail;
	}

	pkt_filter.u.pattern.size_bytes = mask_size;
	buf_len += BRCMF_PKT_FILTER_FIXED_LEN;
	buf_len += (BRCMF_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);

	/* Keep-alive attributes are set in local
	 * variable (keep_alive_pkt), and
	 ** then memcpy'ed into buffer (keep_alive_pktp) since there is no
	 ** guarantee that the buffer is properly aligned.
	 */
	memcpy((char *)pkt_filterp,
	       &pkt_filter,
	       BRCMF_PKT_FILTER_FIXED_LEN + BRCMF_PKT_FILTER_PATTERN_FIXED_LEN);

	rc = brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, buf, buf_len);
	rc = rc >= 0 ? 0 : rc;

	if (rc)
		BRCMF_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n",
			     __func__, arg, rc));
	else
		BRCMF_TRACE(("%s: successfully added pktfilter %s\n",
			     __func__, arg));

fail:
	kfree(arg_org);

	kfree(buf);
}
void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg)
{
	const char *str;
	struct brcmf_pkt_filter_le pkt_filter;
	struct brcmf_pkt_filter_le *pkt_filterp;
	unsigned long res;
	int buf_len;
	int str_len;
	int rc;
	u32 mask_size;
	u32 pattern_size;
	char *argv[8], *buf = NULL;
	int i = 0;
	char *arg_save = NULL, *arg_org = NULL;

	arg_save = kstrdup(arg, GFP_ATOMIC);
	if (!arg_save)
		goto fail;

	arg_org = arg_save;

	buf = kmalloc(PKTFILTER_BUF_SIZE, GFP_ATOMIC);
	if (!buf)
		goto fail;

	argv[i] = strsep(&arg_save, " ");
	while (argv[i++])
		argv[i] = strsep(&arg_save, " ");

	i = 0;
	if (NULL == argv[i]) {
		brcmf_dbg(ERROR, "No args provided\n");
		goto fail;
	}

	str = "pkt_filter_add";
	strcpy(buf, str);
	str_len = strlen(str);
	buf_len = str_len + 1;

	pkt_filterp = (struct brcmf_pkt_filter_le *) (buf + str_len + 1);

	/* Parse packet filter id. */
	pkt_filter.id = 0;
	if (!kstrtoul(argv[i], 0, &res))
		pkt_filter.id = cpu_to_le32((u32)res);

	if (NULL == argv[++i]) {
		brcmf_dbg(ERROR, "Polarity not provided\n");
		goto fail;
	}

	/* Parse filter polarity. */
	pkt_filter.negate_match = 0;
	if (!kstrtoul(argv[i], 0, &res))
		pkt_filter.negate_match = cpu_to_le32((u32)res);

	if (NULL == argv[++i]) {
		brcmf_dbg(ERROR, "Filter type not provided\n");
		goto fail;
	}

	/* Parse filter type. */
	pkt_filter.type = 0;
	if (!kstrtoul(argv[i], 0, &res))
		pkt_filter.type = cpu_to_le32((u32)res);

	if (NULL == argv[++i]) {
		brcmf_dbg(ERROR, "Offset not provided\n");
		goto fail;
	}

	/* Parse pattern filter offset. */
	pkt_filter.u.pattern.offset = 0;
	if (!kstrtoul(argv[i], 0, &res))
		pkt_filter.u.pattern.offset = cpu_to_le32((u32)res);

	if (NULL == argv[++i]) {
		brcmf_dbg(ERROR, "Bitmask not provided\n");
		goto fail;
	}

	/* Parse pattern filter mask. */
	mask_size =
	    brcmf_c_pattern_atoh
		   (argv[i], (char *)pkt_filterp->u.pattern.mask_and_pattern);

	if (NULL == argv[++i]) {
		brcmf_dbg(ERROR, "Pattern not provided\n");
		goto fail;
	}

	/* Parse pattern filter pattern. */
	pattern_size =
	    brcmf_c_pattern_atoh(argv[i],
				   (char *)&pkt_filterp->u.pattern.
				   mask_and_pattern[mask_size]);

	if (mask_size != pattern_size) {
		brcmf_dbg(ERROR, "Mask and pattern not the same size\n");
		goto fail;
	}

	pkt_filter.u.pattern.size_bytes = cpu_to_le32(mask_size);
	buf_len += BRCMF_PKT_FILTER_FIXED_LEN;
	buf_len += (BRCMF_PKT_FILTER_PATTERN_FIXED_LEN + 2 * mask_size);

	/* Keep-alive attributes are set in local
	 * variable (keep_alive_pkt), and
	 ** then memcpy'ed into buffer (keep_alive_pktp) since there is no
	 ** guarantee that the buffer is properly aligned.
	 */
	memcpy((char *)pkt_filterp,
	       &pkt_filter,
	       BRCMF_PKT_FILTER_FIXED_LEN + BRCMF_PKT_FILTER_PATTERN_FIXED_LEN);

	rc = brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, buf, buf_len);
	rc = rc >= 0 ? 0 : rc;

	if (rc)
		brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n",
			  arg, rc);
	else
		brcmf_dbg(TRACE, "successfully added pktfilter %s\n", arg);

fail:
	kfree(arg_org);

	kfree(buf);
}