예제 #1
0
int
wl_cfgnan_sub_handler(struct net_device *ndev,
	struct bcm_cfg80211 *cfg, char *cmd, nan_cmd_data_t *cmd_data)
{
	wl_nan_ioc_t *nanioc = NULL;
	struct bcm_tlvbuf *tbuf = NULL;
	wl_nan_disc_params_t params;
	s32 ret = BCME_OK;
	u16 kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
	uint16 nanioc_size = sizeof(wl_nan_ioc_t) + NAN_IOCTL_BUF_SIZE;

	/*
	 * proceed only if mandatory arguments are present - subscriber id,
	 * service hash
	 */
	if ((!cmd_data->sub_id) || (!cmd_data->svc_hash.data) ||
		(!cmd_data->svc_hash.dlen)) {
		WL_ERR((" mandatory arguments are not present \n"));
		return -EINVAL;
	}

	nanioc = kzalloc(nanioc_size, kflags);
	if (!nanioc) {
		WL_ERR((" memory allocation failed \n"));
		return -ENOMEM;
	}

	tbuf = bcm_xtlv_buf_alloc(NULL, BCM_XTLV_HDR_SIZE + sizeof(params));
	if (!tbuf) {
		WL_ERR((" memory allocation failed \n"));
		ret = -ENOMEM;
		goto fail;
	}

	/*
	 * command to test
	 *
	 * wl: wl nan subscribe 10 NAN123
	 *
	 * wpa_cli: DRIVER NAN_SUBSCRIBE SUB_ID=10 SVC_HASH=NAN123
	 */

	/* nan subscribe */
	params.period = 1;
	params.ttl = WL_NAN_TTL_UNTIL_CANCEL;
	params.flags = 0;
	params.instance_id = (wl_nan_instance_id_t)cmd_data->sub_id;
	memcpy((char *)params.svc_hash, cmd_data->svc_hash.data,
		cmd_data->svc_hash.dlen);
	bcm_xtlv_put_data(tbuf, WL_NAN_XTLV_SVC_PARAMS, &params, sizeof(params));

	nanioc->version = htod16(WL_NAN_IOCTL_VERSION);
	nanioc->id = htod16(WL_NAN_CMD_SUBSCRIBE);
	nanioc->len = htod16(bcm_xtlv_buf_len(tbuf));
	bcopy(bcm_xtlv_head(tbuf), nanioc->data, bcm_xtlv_buf_len(tbuf));
	nanioc_size = sizeof(wl_nan_ioc_t) + bcm_xtlv_buf_len(tbuf);
	ret = wldev_iovar_setbuf(ndev, "nan", nanioc, nanioc_size,
		cfg->ioctl_buf, WLC_IOCTL_MEDLEN, NULL);
	if (unlikely(ret)) {
		WL_ERR((" nan subscribe failed, error = %d \n", ret));
		goto fail;
	} else {
		WL_DBG((" nan subscribe successful \n"));
	}

fail:
	if (tbuf) {
		bcm_xtlv_buf_free(NULL, tbuf);
	}
	if (nanioc) {
		kfree(nanioc);
	}

	return ret;
}
예제 #2
0
int
wl_cfgnan_cancel_sub_handler(struct net_device *ndev,
	struct bcm_cfg80211 *cfg, char *cmd, nan_cmd_data_t *cmd_data)
{
	wl_nan_ioc_t *nanioc = NULL;
	struct bcm_tlvbuf *tbuf = NULL;
	wl_nan_disc_params_t params;
	s32 ret = BCME_OK;
	u16 kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL;
	uint16 nanioc_size = sizeof(wl_nan_ioc_t) + NAN_IOCTL_BUF_SIZE;

	/* proceed only if mandatory argument is present - subscriber id */
	if (!cmd_data->sub_id) {
		WL_ERR((" mandatory argument is not present \n"));
		return -EINVAL;
	}

	nanioc = kzalloc(nanioc_size, kflags);
	if (!nanioc) {
		WL_ERR((" memory allocation failed \n"));
		return -ENOMEM;
	}

	tbuf = bcm_xtlv_buf_alloc(NULL, BCM_XTLV_HDR_SIZE + sizeof(params));
	if (!tbuf) {
		WL_ERR((" memory allocation failed \n"));
		ret = -ENOMEM;
		goto fail;
	}

	/*
	 * command to test
	 *
	 * wl: wl nan cancel_subscribe 10
	 *
	 * wpa_cli: DRIVER NAN_CANCEL_SUBSCRIBE PUB_ID=10
	 */

	bcm_xtlv_put_data(tbuf, WL_NAN_XTLV_INSTANCE_ID, &cmd_data->sub_id,
		sizeof(wl_nan_instance_id_t));

	/* nan cancel subscribe */
	nanioc->version = htod16(WL_NAN_IOCTL_VERSION);
	nanioc->id = htod16(WL_NAN_CMD_CANCEL_SUBSCRIBE);
	nanioc->len = htod16(bcm_xtlv_buf_len(tbuf));
	bcopy(bcm_xtlv_head(tbuf), nanioc->data, bcm_xtlv_buf_len(tbuf));
	nanioc_size = sizeof(wl_nan_ioc_t) + bcm_xtlv_buf_len(tbuf);
	ret = wldev_iovar_setbuf(ndev, "nan", nanioc, nanioc_size,
		cfg->ioctl_buf, WLC_IOCTL_MEDLEN, NULL);
	if (unlikely(ret)) {
		WL_ERR((" nan cancel subscribe failed, error = %d \n", ret));
		goto fail;
	} else {
		WL_DBG((" nan cancel subscribe successful \n"));
	}

fail:
	if (tbuf) {
		bcm_xtlv_buf_free(NULL, tbuf);
	}
	if (nanioc) {
		kfree(nanioc);
	}

	return ret;
}
uint16
bcm_xtlv_buf_rlen(struct bcm_tlvbuf *tbuf)
{
	if (tbuf == NULL) return 0;
	return tbuf->size - bcm_xtlv_buf_len(tbuf);
}