int dhd_sel_ant_from_file(dhd_pub_t *dhd)
{
	struct file *fp = NULL;
	int ret = -1;
	uint32 ant_val = 0;
	uint32 btc_mode = 0;
	uint32 rsdb_mode = 0;
	char *filepath = ANTINFO;
	char iovbuf[WLC_IOCTL_SMLEN];
	uint chip_id = dhd_bus_chip_id(dhd);

	/* Check if this chip can support MIMO */
	if (chip_id != BCM4324_CHIP_ID &&
		chip_id != BCM4350_CHIP_ID &&
		chip_id != BCM4354_CHIP_ID &&
		chip_id != BCM4356_CHIP_ID &&
		chip_id != BCM43569_CHIP_ID &&
		chip_id != BCM4358_CHIP_ID &&
		chip_id != BCM4359_CHIP_ID &&
		chip_id != BCM4355_CHIP_ID) {
		DHD_ERROR(("[WIFI_SEC] %s: This chipset does not support MIMO\n",
			__FUNCTION__));
		return ret;
	}

	/* Read antenna settings from the file */
	fp = filp_open(filepath, O_RDONLY, 0);
	if (IS_ERR(fp)) {
		DHD_ERROR(("[WIFI_SEC] %s: File [%s] doesn't exist\n", __FUNCTION__, filepath));
		return ret;
	} else {
		ret = kernel_read(fp, 0, (char *)&ant_val, 4);
		if (ret < 0) {
			DHD_ERROR(("[WIFI_SEC] %s: File read error, ret=%d\n", __FUNCTION__, ret));
			filp_close(fp, NULL);
			return ret;
		}

		ant_val = bcm_atoi((char *)&ant_val);

		DHD_ERROR(("[WIFI_SEC]%s: ANT val = %d\n", __FUNCTION__, ant_val));
		filp_close(fp, NULL);

		/* Check value from the file */
		if (ant_val < 1 || ant_val > 3) {
			DHD_ERROR(("[WIFI_SEC] %s: Invalid value %d read from the file %s\n",
				__FUNCTION__, ant_val, filepath));
			return -1;
		}
	}

	/* bt coex mode off */
	if (dhd_get_fw_mode(dhd->info) == DHD_FLAG_MFG_MODE) {
		bcm_mkiovar("btc_mode", (char *)&btc_mode, 4, iovbuf, sizeof(iovbuf));
		ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
		if (ret) {
			DHD_ERROR(("[WIFI_SEC] %s: Fail to execute dhd_wl_ioctl_cmd(): "
				"btc_mode, ret=%d\n",
				__FUNCTION__, ret));
			return ret;
		}
	}

	/* rsdb mode off */
	DHD_ERROR(("[WIFI_SEC] %s: %s the RSDB mode!\n",
		__FUNCTION__, rsdb_mode ? "Enable" : "Disable"));
	bcm_mkiovar("rsdb_mode", (char *)&rsdb_mode, 4, iovbuf, sizeof(iovbuf));
	ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
	if (ret) {
		DHD_ERROR(("[WIFI_SEC] %s: Fail to execute dhd_wl_ioctl_cmd(): "
			"rsdb_mode, ret=%d\n", __FUNCTION__, ret));
		return ret;
	}

	/* Select Antenna */
	bcm_mkiovar("txchain", (char *)&ant_val, 4, iovbuf, sizeof(iovbuf));
	ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
	if (ret) {
		DHD_ERROR(("[WIFI_SEC] %s: Fail to execute dhd_wl_ioctl_cmd(): txchain, ret=%d\n",
			__FUNCTION__, ret));
		return ret;
	}

	bcm_mkiovar("rxchain", (char *)&ant_val, 4, iovbuf, sizeof(iovbuf));
	ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
	if (ret) {
		DHD_ERROR(("[WIFI_SEC] %s: Fail to execute dhd_wl_ioctl_cmd(): rxchain, ret=%d\n",
			__FUNCTION__, ret));
		return ret;
	}

	return 0;
}
bool
dhd_tcpack_suppress(dhd_pub_t *dhdp, void *pkt)
{
	uint8 *new_ether_hdr;	/* Ethernet header of the new packet */
	uint16 new_ether_type;	/* Ethernet type of the new packet */
	uint8 *new_ip_hdr;		/* IP header of the new packet */
	uint8 *new_tcp_hdr;		/* TCP header of the new packet */
	uint32 new_ip_hdr_len;	/* IP header length of the new packet */
	uint32 cur_framelen;
	uint32 new_tcp_ack_num;		/* TCP acknowledge number of the new packet */
	uint16 new_ip_total_len;	/* Total length of IP packet for the new packet */
	uint32 new_tcp_hdr_len;		/* TCP header length of the new packet */
	tcpack_sup_module_t *tcpack_sup_mod;
	tcpack_info_t *tcpack_info_tbl;
	int i;
	bool ret = FALSE;
	bool set_dotxinrx = TRUE;
	unsigned long flags;


	if (dhdp->tcpack_sup_mode == TCPACK_SUP_OFF)
		goto exit;

	new_ether_hdr = PKTDATA(dhdp->osh, pkt);
	cur_framelen = PKTLEN(dhdp->osh, pkt);

	if (cur_framelen < TCPACKSZMIN || cur_framelen > TCPACKSZMAX) {
		DHD_TRACE(("%s %d: Too short or long length %d to be TCP ACK\n",
			__FUNCTION__, __LINE__, cur_framelen));
		goto exit;
	}

	new_ether_type = new_ether_hdr[12] << 8 | new_ether_hdr[13];

	if (new_ether_type != ETHER_TYPE_IP) {
		DHD_TRACE(("%s %d: Not a IP packet 0x%x\n",
			__FUNCTION__, __LINE__, new_ether_type));
		goto exit;
	}

	DHD_TRACE(("%s %d: IP pkt! 0x%x\n", __FUNCTION__, __LINE__, new_ether_type));

	new_ip_hdr = new_ether_hdr + ETHER_HDR_LEN;
	cur_framelen -= ETHER_HDR_LEN;

	ASSERT(cur_framelen >= IPV4_MIN_HEADER_LEN);

	new_ip_hdr_len = IPV4_HLEN(new_ip_hdr);
	if (IP_VER(new_ip_hdr) != IP_VER_4 || IPV4_PROT(new_ip_hdr) != IP_PROT_TCP) {
		DHD_TRACE(("%s %d: Not IPv4 nor TCP! ip ver %d, prot %d\n",
			__FUNCTION__, __LINE__, IP_VER(new_ip_hdr), IPV4_PROT(new_ip_hdr)));
		goto exit;
	}

	new_tcp_hdr = new_ip_hdr + new_ip_hdr_len;
	cur_framelen -= new_ip_hdr_len;

	ASSERT(cur_framelen >= TCP_MIN_HEADER_LEN);

	DHD_TRACE(("%s %d: TCP pkt!\n", __FUNCTION__, __LINE__));

	/* is it an ack ? Allow only ACK flag, not to suppress others. */
	if (new_tcp_hdr[TCP_FLAGS_OFFSET] != TCP_FLAG_ACK) {
		DHD_TRACE(("%s %d: Do not touch TCP flag 0x%x\n",
			__FUNCTION__, __LINE__, new_tcp_hdr[TCP_FLAGS_OFFSET]));
		goto exit;
	}

	new_ip_total_len = ntoh16_ua(&new_ip_hdr[IPV4_PKTLEN_OFFSET]);
	new_tcp_hdr_len = 4 * TCP_HDRLEN(new_tcp_hdr[TCP_HLEN_OFFSET]);

	/* This packet has TCP data, so just send */
	if (new_ip_total_len > new_ip_hdr_len + new_tcp_hdr_len) {
		DHD_TRACE(("%s %d: Do nothing for TCP DATA\n", __FUNCTION__, __LINE__));
		goto exit;
	}

	ASSERT(new_ip_total_len == new_ip_hdr_len + new_tcp_hdr_len);

	new_tcp_ack_num = ntoh32_ua(&new_tcp_hdr[TCP_ACK_NUM_OFFSET]);

	DHD_TRACE(("%s %d: TCP ACK with zero DATA length"
		" IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR" TCP port %d %d\n",
		__FUNCTION__, __LINE__,
		IPV4_ADDR_TO_STR(ntoh32_ua(&new_ip_hdr[IPV4_SRC_IP_OFFSET])),
		IPV4_ADDR_TO_STR(ntoh32_ua(&new_ip_hdr[IPV4_DEST_IP_OFFSET])),
		ntoh16_ua(&new_tcp_hdr[TCP_SRC_PORT_OFFSET]),
		ntoh16_ua(&new_tcp_hdr[TCP_DEST_PORT_OFFSET])));

	/* Look for tcp_ack_info that has the same ip src/dst addrs and tcp src/dst ports */
	flags = dhd_os_tcpacklock(dhdp);
#if defined(DEBUG_COUNTER) && defined(DHDTCPACK_SUP_DBG)
	counter_printlog(&tack_tbl);
	tack_tbl.cnt[0]++;
#endif /* DEBUG_COUNTER && DHDTCPACK_SUP_DBG */

	tcpack_sup_mod = dhdp->tcpack_sup_module;
	tcpack_info_tbl = tcpack_sup_mod->tcpack_info_tbl;

	if (!tcpack_sup_mod) {
		DHD_ERROR(("%s %d: tcpack suppress module NULL!!\n", __FUNCTION__, __LINE__));
		ret = BCME_ERROR;
		dhd_os_tcpackunlock(dhdp, flags);
		goto exit;
	}

	if (dhd_tcpdata_psh_acked(dhdp, new_ip_hdr, new_tcp_hdr, new_tcp_ack_num)) {
		/* This TCPACK is ACK to TCPDATA PSH pkt, so keep set_dotxinrx TRUE */
#if defined(DEBUG_COUNTER) && defined(DHDTCPACK_SUP_DBG)
		tack_tbl.cnt[5]++;
#endif /* DEBUG_COUNTER && DHDTCPACK_SUP_DBG */
	} else
		set_dotxinrx = FALSE;

	for (i = 0; i < tcpack_sup_mod->tcpack_info_cnt; i++) {
		void *oldpkt;	/* TCPACK packet that is already in txq or DelayQ */
		uint8 *old_ether_hdr, *old_ip_hdr, *old_tcp_hdr;
		uint32 old_ip_hdr_len, old_tcp_hdr_len;
		uint32 old_tcpack_num;	/* TCP ACK number of old TCPACK packet in Q */

		if ((oldpkt = tcpack_info_tbl[i].pkt_in_q) == NULL) {
			DHD_ERROR(("%s %d: Unexpected error!! cur idx %d, ttl cnt %d\n",
				__FUNCTION__, __LINE__, i, tcpack_sup_mod->tcpack_info_cnt));
			break;
		}

		if (PKTDATA(dhdp->osh, oldpkt) == NULL) {
			DHD_ERROR(("%s %d: oldpkt data NULL!! cur idx %d, ttl cnt %d\n",
				__FUNCTION__, __LINE__, i, tcpack_sup_mod->tcpack_info_cnt));
			break;
		}

		old_ether_hdr = tcpack_info_tbl[i].pkt_ether_hdr;
		old_ip_hdr = old_ether_hdr + ETHER_HDR_LEN;
		old_ip_hdr_len = IPV4_HLEN(old_ip_hdr);
		old_tcp_hdr = old_ip_hdr + old_ip_hdr_len;
		old_tcp_hdr_len = 4 * TCP_HDRLEN(old_tcp_hdr[TCP_HLEN_OFFSET]);

		DHD_TRACE(("%s %d: oldpkt %p[%d], IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR
			" TCP port %d %d\n", __FUNCTION__, __LINE__, oldpkt, i,
			IPV4_ADDR_TO_STR(ntoh32_ua(&old_ip_hdr[IPV4_SRC_IP_OFFSET])),
			IPV4_ADDR_TO_STR(ntoh32_ua(&old_ip_hdr[IPV4_DEST_IP_OFFSET])),
			ntoh16_ua(&old_tcp_hdr[TCP_SRC_PORT_OFFSET]),
			ntoh16_ua(&old_tcp_hdr[TCP_DEST_PORT_OFFSET])));

		/* If either of IP address or TCP port number does not match, skip. */
		if (memcmp(&new_ip_hdr[IPV4_SRC_IP_OFFSET],
			&old_ip_hdr[IPV4_SRC_IP_OFFSET], IPV4_ADDR_LEN * 2) ||
			memcmp(&new_tcp_hdr[TCP_SRC_PORT_OFFSET],
			&old_tcp_hdr[TCP_SRC_PORT_OFFSET], TCP_PORT_LEN * 2))
			continue;

		old_tcpack_num = ntoh32_ua(&old_tcp_hdr[TCP_ACK_NUM_OFFSET]);

		if (IS_TCPSEQ_GT(new_tcp_ack_num, old_tcpack_num)) {
			/* New packet has higher TCP ACK number, so it replaces the old packet */
			if (new_ip_hdr_len == old_ip_hdr_len &&
				new_tcp_hdr_len == old_tcp_hdr_len) {
				ASSERT(memcmp(new_ether_hdr, old_ether_hdr, ETHER_HDR_LEN) == 0);
				bcopy(new_ip_hdr, old_ip_hdr, new_ip_total_len);
				PKTFREE(dhdp->osh, pkt, FALSE);
				DHD_TRACE(("%s %d: TCP ACK replace %u -> %u\n",
					__FUNCTION__, __LINE__, old_tcpack_num, new_tcp_ack_num));
#if defined(DEBUG_COUNTER) && defined(DHDTCPACK_SUP_DBG)
				tack_tbl.cnt[2]++;
#endif /* DEBUG_COUNTER && DHDTCPACK_SUP_DBG */
				ret = TRUE;
			} else {
#if defined(DEBUG_COUNTER) && defined(DHDTCPACK_SUP_DBG)
				tack_tbl.cnt[6]++;
#endif /* DEBUG_COUNTER && DHDTCPACK_SUP_DBG */
				DHD_TRACE(("%s %d: lenth mismatch %d != %d || %d != %d"
					" ACK %u -> %u\n", __FUNCTION__, __LINE__,
					new_ip_hdr_len, old_ip_hdr_len,
					new_tcp_hdr_len, old_tcp_hdr_len,
					old_tcpack_num, new_tcp_ack_num));
			}
		} else if (new_tcp_ack_num == old_tcpack_num) {
			set_dotxinrx = TRUE;
			/* TCPACK retransmission */
#if defined(DEBUG_COUNTER) && defined(DHDTCPACK_SUP_DBG)
			tack_tbl.cnt[3]++;
#endif /* DEBUG_COUNTER && DHDTCPACK_SUP_DBG */
		} else {
			DHD_TRACE(("%s %d: ACK number reverse old %u(0x%p) new %u(0x%p)\n",
				__FUNCTION__, __LINE__, old_tcpack_num, oldpkt,
				new_tcp_ack_num, pkt));
		}
		dhd_os_tcpackunlock(dhdp, flags);
		goto exit;
	}

	if (i == tcpack_sup_mod->tcpack_info_cnt && i < TCPACK_INFO_MAXNUM) {
		/* No TCPACK packet with the same IP addr and TCP port is found
		 * in tcp_ack_info_tbl. So add this packet to the table.
		 */
		DHD_TRACE(("%s %d: Add pkt 0x%p(ether_hdr 0x%p) to tbl[%d]\n",
			__FUNCTION__, __LINE__, pkt, new_ether_hdr,
			tcpack_sup_mod->tcpack_info_cnt));

		tcpack_info_tbl[tcpack_sup_mod->tcpack_info_cnt].pkt_in_q = pkt;
		tcpack_info_tbl[tcpack_sup_mod->tcpack_info_cnt].pkt_ether_hdr = new_ether_hdr;
		tcpack_sup_mod->tcpack_info_cnt++;
#if defined(DEBUG_COUNTER) && defined(DHDTCPACK_SUP_DBG)
		tack_tbl.cnt[1]++;
#endif /* DEBUG_COUNTER && DHDTCPACK_SUP_DBG */
	} else {
		ASSERT(i == tcpack_sup_mod->tcpack_info_cnt);
		DHD_TRACE(("%s %d: No empty tcp ack info tbl\n",
			__FUNCTION__, __LINE__));
	}
	dhd_os_tcpackunlock(dhdp, flags);

exit:
	/* Unless TCPACK_SUP_DELAYTX, dotxinrx is alwasy TRUE, so no need to set here */
	if (dhdp->tcpack_sup_mode == TCPACK_SUP_DELAYTX && set_dotxinrx)
		dhd_bus_set_dotxinrx(dhdp->bus, TRUE);

	return ret;
}
Esempio n. 3
0
int
wl_host_event(struct dhd_info *dhd, int *ifidx, void *pktdata,
              wl_event_msg_t *event, void **data_ptr)
{
	/* check whether packet is a BRCM event pkt */
	bcm_event_t *pvt_data = (bcm_event_t *)pktdata;
	char *event_data;
	uint32 type, status;
	uint16 flags;
	int evlen;

	if (bcmp(BRCM_OUI, &pvt_data->bcm_hdr.oui[0], DOT11_OUI_LEN)) {
		DHD_ERROR(("%s: mismatched OUI, bailing\n", __FUNCTION__));
		return (BCME_ERROR);
	}

	/* BRCM event pkt may be unaligned - use xxx_ua to load user_subtype. */
	if (ntoh16_ua((void *)&pvt_data->bcm_hdr.usr_subtype) != BCMILCP_BCM_SUBTYPE_EVENT) {
		DHD_ERROR(("%s: mismatched subtype, bailing\n", __FUNCTION__));
		return (BCME_ERROR);
	}

	*data_ptr = &pvt_data[1];
	event_data = *data_ptr;

	/* memcpy since BRCM event pkt may be unaligned. */
	memcpy(event, &pvt_data->event, sizeof(wl_event_msg_t));

	type = ntoh32_ua((void *)&event->event_type);
	flags = ntoh16_ua((void *)&event->flags);
	status = ntoh32_ua((void *)&event->status);
	evlen = ntoh32_ua((void *)&event->datalen) + sizeof(bcm_event_t);

	switch (type) {
		case WLC_E_IF:
			{
				dhd_if_event_t *ifevent = (dhd_if_event_t *)event_data;
				DHD_TRACE(("%s: if event\n", __FUNCTION__));

				if (ifevent->ifidx > 0 && ifevent->ifidx < DHD_MAX_IFS)
				{
					if (ifevent->action == WLC_E_IF_ADD)
						dhd_add_if(dhd, ifevent->ifidx,
							NULL, event->ifname,
							pvt_data->eth.ether_dhost,
							ifevent->flags, ifevent->bssidx);
					else
						dhd_del_if(dhd, ifevent->ifidx);
				} else {
					DHD_ERROR(("%s: Invalid ifidx %d for %s\n",
						__FUNCTION__, ifevent->ifidx, event->ifname));
				}
				if (ifevent->action != WLC_E_IF_ADD) {
			/* send up the if event: btamp user needs it */
			*ifidx = dhd_ifname2idx(dhd, event->ifname);
			}
			}
			
			/* push up to external supp/auth */
			dhd_event(dhd, (char *)pvt_data, evlen, *ifidx);
			break;


#ifdef P2P
		case WLC_E_NDIS_LINK:
			break;
#endif
		/* fall through */
		/* These are what external supplicant/authenticator wants */
		case WLC_E_LINK:
		case WLC_E_ASSOC_IND:
		case WLC_E_REASSOC_IND:
		case WLC_E_DISASSOC_IND:
		case WLC_E_MIC_ERROR:
		default:
		/* Fall through: this should get _everything_  */

			*ifidx = dhd_ifname2idx(dhd, event->ifname);
			/* push up to external supp/auth */
			dhd_event(dhd, (char *)pvt_data, evlen, *ifidx);
			DHD_TRACE(("%s: MAC event %d, flags %x, status %x\n",
			           __FUNCTION__, type, flags, status));

			/* put it back to WLC_E_NDIS_LINK */
			if (type == WLC_E_NDIS_LINK) {
				uint32 temp;

				temp = ntoh32_ua((void *)&event->event_type);
				DHD_TRACE(("Converted to WLC_E_LINK type %d\n", temp));

				temp = ntoh32(WLC_E_NDIS_LINK);
				memcpy((void *)(&pvt_data->event.event_type), &temp,
					sizeof(pvt_data->event.event_type));
			}
			break;
	}

#ifdef SHOW_EVENTS
	wl_show_host_event(event, event_data);
#endif /* SHOW_EVENTS */

	return (BCME_OK);
}
Esempio n. 4
0
static int wl_android_set_pno_setup(struct net_device *dev, char *command, int total_len)
{
	wlc_ssid_t ssids_local[MAX_PFN_LIST_COUNT];
	int res = -1;
	int nssid = 0;
	cmd_tlv_t *cmd_tlv_temp;
	char *str_ptr;
	int tlv_size_left;
	int pno_time = 0;
	int pno_repeat = 0;
	int pno_freq_expo_max = 0;

#ifdef PNO_SET_DEBUG
	int i;
	char pno_in_example[] = {
		'P', 'N', 'O', 'S', 'E', 'T', 'U', 'P', ' ',
		'S', '1', '2', '0',
		'S',
		0x05,
		'd', 'l', 'i', 'n', 'k',
		'S',
		0x04,
		'G', 'O', 'O', 'G',
		'T',
		'0', 'B',
		'R',
		'2',
		'M',
		'2',
		0x00
		};
#endif /* PNO_SET_DEBUG */

	DHD_INFO(("%s: command=%s, len=%d\n", __FUNCTION__, command, total_len));

	if (total_len < (strlen(CMD_PNOSETUP_SET) + sizeof(cmd_tlv_t))) {
		DHD_ERROR(("%s argument=%d less min size\n", __FUNCTION__, total_len));
		goto exit_proc;
	}

#ifdef PNO_SET_DEBUG
	memcpy(command, pno_in_example, sizeof(pno_in_example));
	for (i = 0; i < sizeof(pno_in_example); i++)
		printf("%02X ", command[i]);
	printf("\n");
	total_len = sizeof(pno_in_example);
#endif

	str_ptr = command + strlen(CMD_PNOSETUP_SET);
	tlv_size_left = total_len - strlen(CMD_PNOSETUP_SET);

	cmd_tlv_temp = (cmd_tlv_t *)str_ptr;
	memset(ssids_local, 0, sizeof(ssids_local));

	if ((cmd_tlv_temp->prefix == PNO_TLV_PREFIX) &&
		(cmd_tlv_temp->version == PNO_TLV_VERSION) &&
		(cmd_tlv_temp->subver == PNO_TLV_SUBVERSION)) {

		str_ptr += sizeof(cmd_tlv_t);
		tlv_size_left -= sizeof(cmd_tlv_t);

		if ((nssid = wl_iw_parse_ssid_list_tlv(&str_ptr, ssids_local,
			MAX_PFN_LIST_COUNT, &tlv_size_left)) <= 0) {
			DHD_ERROR(("SSID is not presented or corrupted ret=%d\n", nssid));
			goto exit_proc;
		} else {
			if ((str_ptr[0] != PNO_TLV_TYPE_TIME) || (tlv_size_left <= 1)) {
				DHD_ERROR(("%s scan duration corrupted field size %d\n",
					__FUNCTION__, tlv_size_left));
				goto exit_proc;
			}
			str_ptr++;
			pno_time = simple_strtoul(str_ptr, &str_ptr, 16);
			DHD_INFO(("%s: pno_time=%d\n", __FUNCTION__, pno_time));

			if (str_ptr[0] != 0) {
				if ((str_ptr[0] != PNO_TLV_FREQ_REPEAT)) {
					DHD_ERROR(("%s pno repeat : corrupted field\n",
						__FUNCTION__));
					goto exit_proc;
				}
				str_ptr++;
				pno_repeat = simple_strtoul(str_ptr, &str_ptr, 16);
				DHD_INFO(("%s :got pno_repeat=%d\n", __FUNCTION__, pno_repeat));
				if (str_ptr[0] != PNO_TLV_FREQ_EXPO_MAX) {
					DHD_ERROR(("%s FREQ_EXPO_MAX corrupted field size\n",
						__FUNCTION__));
					goto exit_proc;
				}
				str_ptr++;
				pno_freq_expo_max = simple_strtoul(str_ptr, &str_ptr, 16);
				DHD_INFO(("%s: pno_freq_expo_max=%d\n",
					__FUNCTION__, pno_freq_expo_max));
			}
		}
	} else {
		DHD_ERROR(("%s get wrong TLV command\n", __FUNCTION__));
		goto exit_proc;
	}

	res = dhd_dev_pno_set(dev, ssids_local, nssid, pno_time, pno_repeat, pno_freq_expo_max);

exit_proc:
	return res;
}
int dhd_tcpack_suppress_set(dhd_pub_t *dhdp, uint8 mode)
{
	int ret = BCME_OK;
	unsigned long flags;

	flags = dhd_os_tcpacklock(dhdp);

	if (dhdp->tcpack_sup_mode == mode) {
		DHD_ERROR(("%s %d: already set to %d\n", __FUNCTION__, __LINE__, mode));
		goto exit;
	}

	if (mode >= TCPACK_SUP_LAST_MODE ||
#ifndef BCMSDIO
		mode == TCPACK_SUP_DELAYTX ||
#endif /* !BCMSDIO */
		FALSE) {
		DHD_ERROR(("%s %d: Invalid mode %d\n", __FUNCTION__, __LINE__, mode));
		ret = BCME_BADARG;
		goto exit;
	}

	DHD_TRACE(("%s: %d -> %d\n",
		__FUNCTION__, dhdp->tcpack_sup_mode, mode));

#ifdef BCMSDIO
	/* Old tcpack_sup_mode is TCPACK_SUP_DELAYTX */
	if (dhdp->tcpack_sup_mode == TCPACK_SUP_DELAYTX) {
		tcpack_sup_module_t *tcpack_sup_mod = dhdp->tcpack_sup_module;
		/* We won't need tdata_psh_info pool and tcpddata_info_tbl anymore */
		_tdata_psh_info_pool_deinit(dhdp, tcpack_sup_mod);
		tcpack_sup_mod->tcpdata_info_cnt = 0;
		bzero(tcpack_sup_mod->tcpdata_info_tbl,
			sizeof(tcpdata_info_t) * TCPDATA_INFO_MAXNUM);
		/* For half duplex bus interface, tx precedes rx by default */
		if (dhdp->bus)
			dhd_bus_set_dotxinrx(dhdp->bus, TRUE);
	}
#endif
	dhdp->tcpack_sup_mode = mode;

	if (mode == TCPACK_SUP_OFF) {
		ASSERT(dhdp->tcpack_sup_module != NULL);
		/* Clean up timer/data structure for any remaining/pending packet or timer. */
		dhd_tcpack_info_tbl_clean(dhdp);
		MFREE(dhdp->osh, dhdp->tcpack_sup_module, sizeof(tcpack_sup_module_t));
		dhdp->tcpack_sup_module = NULL;
		goto exit;
	}

	if (dhdp->tcpack_sup_module == NULL) {
		tcpack_sup_module_t *tcpack_sup_mod =
			MALLOC(dhdp->osh, sizeof(tcpack_sup_module_t));
		if (tcpack_sup_mod == NULL) {
			DHD_ERROR(("%s %d: No MEM\n", __FUNCTION__, __LINE__));
			dhdp->tcpack_sup_mode = TCPACK_SUP_OFF;
			ret = BCME_NOMEM;
			goto exit;
		}
		bzero(tcpack_sup_mod, sizeof(tcpack_sup_module_t));
		dhdp->tcpack_sup_module = tcpack_sup_mod;
	}

#ifdef BCMSDIO
	if (mode == TCPACK_SUP_DELAYTX) {
		ret = _tdata_psh_info_pool_init(dhdp, dhdp->tcpack_sup_module);
		if (ret != BCME_OK)
			DHD_ERROR(("%s %d: pool init fail with %d\n", __FUNCTION__, __LINE__, ret));
		else if (dhdp->bus)
			dhd_bus_set_dotxinrx(dhdp->bus, FALSE);
	}
#endif /* BCMSDIO */

	if (mode == TCPACK_SUP_HOLD) {
		int i;
		tcpack_sup_module_t *tcpack_sup_mod =
			(tcpack_sup_module_t *)dhdp->tcpack_sup_module;
		dhdp->tcpack_sup_ratio = TCPACK_SUPP_RATIO;
		dhdp->tcpack_sup_delay = TCPACK_DELAY_TIME;
		for (i = 0; i < TCPACK_INFO_MAXNUM; i++)
		{
			tcpack_sup_mod->tcpack_info_tbl[i].dhdp = dhdp;
			init_timer(&tcpack_sup_mod->tcpack_info_tbl[i].timer);
			tcpack_sup_mod->tcpack_info_tbl[i].timer.data =
				(ulong)&tcpack_sup_mod->tcpack_info_tbl[i];
			tcpack_sup_mod->tcpack_info_tbl[i].timer.function = dhd_tcpack_send;
		}
	}

exit:
	dhd_os_tcpackunlock(dhdp, flags);
	return ret;
}
Esempio n. 6
0
static int
wl_android_set_ap_mac_list(struct net_device *dev, int macmode, struct maclist *maclist)
{
	int i, j, match;
	int ret	= 0;
	char mac_buf[MAX_NUM_OF_ASSOCLIST *
		sizeof(struct ether_addr) + sizeof(uint)] = {0};
	struct maclist *assoc_maclist = (struct maclist *)mac_buf;

	/* set filtering mode */
	if ((ret = wldev_ioctl(dev, WLC_SET_MACMODE, &macmode, sizeof(macmode), true)) != 0) {
		DHD_ERROR(("%s : WLC_SET_MACMODE error=%d\n", __FUNCTION__, ret));
		return ret;
	}
	if (macmode != MACLIST_MODE_DISABLED) {
		/* set the MAC filter list */
		if ((ret = wldev_ioctl(dev, WLC_SET_MACLIST, maclist,
			sizeof(int) + sizeof(struct ether_addr) * maclist->count, true)) != 0) {
			DHD_ERROR(("%s : WLC_SET_MACLIST error=%d\n", __FUNCTION__, ret));
			return ret;
		}
		/* get the current list of associated STAs */
		assoc_maclist->count = MAX_NUM_OF_ASSOCLIST;
		if ((ret = wldev_ioctl(dev, WLC_GET_ASSOCLIST, assoc_maclist,
			sizeof(mac_buf), false)) != 0) {
			DHD_ERROR(("%s : WLC_GET_ASSOCLIST error=%d\n", __FUNCTION__, ret));
			return ret;
		}
		/* do we have any STA associated?  */
		if (assoc_maclist->count) {
			/* iterate each associated STA */
			for (i = 0; i < assoc_maclist->count; i++) {
				match = 0;
				/* compare with each entry */
				for (j = 0; j < maclist->count; j++) {
					DHD_INFO(("%s : associated="MACDBG " list="MACDBG "\n",
					__FUNCTION__, MAC2STRDBG(assoc_maclist->ea[i].octet),
					MAC2STRDBG(maclist->ea[j].octet)));
					if (memcmp(assoc_maclist->ea[i].octet,
						maclist->ea[j].octet, ETHER_ADDR_LEN) == 0) {
						match = 1;
						break;
					}
				}
				/* do conditional deauth */
				/*   "if not in the allow list" or "if in the deny list" */
				if ((macmode == MACLIST_MODE_ALLOW && !match) ||
					(macmode == MACLIST_MODE_DENY && match)) {
					scb_val_t scbval;

					scbval.val = htod32(1);
					memcpy(&scbval.ea, &assoc_maclist->ea[i],
						ETHER_ADDR_LEN);
					if ((ret = wldev_ioctl(dev,
						WLC_SCB_DEAUTHENTICATE_FOR_REASON,
						&scbval, sizeof(scb_val_t), true)) != 0)
						DHD_ERROR(("%s WLC_SCB_DEAUTHENTICATE error=%d\n",
							__FUNCTION__, ret));
				}
			}
		}
	}
	return ret;
}
Esempio n. 7
0
void sec_dhd_config_pm(dhd_pub_t *dhd, uint power_mode)
{
	struct file *fp      = NULL;
	char* filepath       = "/data/.psm.info";
	char iovbuf[WL_EVENTING_MASK_LEN + 12];

	/* Set PowerSave mode */
	fp = filp_open(filepath, O_RDONLY, 0);
	if(IS_ERR(fp))// the file is not exist
	{
		/* Set PowerSave mode */
		dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM, (char *)&power_mode, sizeof(power_mode));

		fp = filp_open(filepath, O_RDWR | O_CREAT, 0666);
		if(IS_ERR(fp)||(fp==NULL))
		{
			DHD_ERROR(("[WIFI] %s: File open error\n", filepath));
		}
		else
		{
			char buffer[2]   = {1};
			if(fp->f_mode & FMODE_WRITE)
			{
				sprintf(buffer,"1\n");
				fp->f_op->write(fp, (const char *)buffer, sizeof(buffer), &fp->f_pos);
			}
		}
	}
	else
	{
		char buffer[1]   = {0};
		kernel_read(fp, fp->f_pos, buffer, 1);
		if(strncmp(buffer, "1",1)==0)
		{
			/* Set PowerSave mode */
			dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM, (char *)&power_mode, sizeof(power_mode));
		}
		else
		{
			/*Disable Power save features for CERTIFICATION*/
			power_mode = 0;
		 
			/* Set PowerSave mode */
			dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM, (char *)&power_mode, sizeof(power_mode));
		 
			/* Disable MPC */    
			bcm_mkiovar("mpc", (char *)&power_mode, 4, iovbuf, sizeof(iovbuf));
			dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));

			fp = filp_open(filepath, O_RDWR | O_CREAT, 0666);
			if(IS_ERR(fp)||(fp==NULL))
			{
				DHD_ERROR(("[WIFI] %s: File open error\n", filepath));
			}
			else
			{
				char buffer[2]   = {1};
				if(fp->f_mode & FMODE_WRITE)
				{
					sprintf(buffer,"1\n");
					fp->f_op->write(fp, (const char *)buffer, sizeof(buffer), &fp->f_pos);
				}
			}
		}
	}

	if(fp)
		filp_close(fp, NULL);
}
int dhd_write_macaddr(struct ether_addr *mac)
{
	char *filepath_data      = MACINFO;
	char *filepath_efs      = MACINFO_EFS;

	struct file *fp_mac = NULL;
	char buf[WRMAC_BUF_SIZE]      = {0};
	mm_segment_t oldfs    = {0};
	int ret = -1;
	int retry_count = 0;

startwrite:

	sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X\n",
		mac->octet[0], mac->octet[1], mac->octet[2],
		mac->octet[3], mac->octet[4], mac->octet[5]);

	/* File will be created /data/.mac.info. */
	fp_mac = filp_open(filepath_data, O_RDWR | O_CREAT, 0666);

	if (IS_ERR(fp_mac)) {
		DHD_ERROR(("[WIFI_SEC] %s: File open error\n", filepath_data));
		return -1;
	} else {
		oldfs = get_fs();
		set_fs(get_ds());

		if (fp_mac->f_mode & FMODE_WRITE) {
			ret = fp_mac->f_op->write(fp_mac, (const char *)buf,
				sizeof(buf), &fp_mac->f_pos);
			if (ret < 0)
				DHD_ERROR(("[WIFI_SEC] Mac address [%s] Failed to"
				" write into File: %s\n", buf, filepath_data));
			else
				DHD_INFO(("[WIFI_SEC] Mac address [%s] written"
				" into File: %s\n", buf, filepath_data));
		}
		set_fs(oldfs);
		filp_close(fp_mac, NULL);
	}
	/* check .mac.info file is 0 byte */
	fp_mac = filp_open(filepath_data, O_RDONLY, 0);
	ret = kernel_read(fp_mac, 0, buf, 18);

	if ((ret == 0) && (retry_count++ < 3)) {
		filp_close(fp_mac, NULL);
		goto startwrite;
	}

	filp_close(fp_mac, NULL);
	/* end of /data/.mac.info */

	if (filepath_efs == NULL) {
		DHD_ERROR(("[WIFI_SEC] %s : no efs filepath", __func__));
		return 0;
	}

	/* File will be created /efs/wifi/.mac.info. */
	fp_mac = filp_open(filepath_efs, O_RDWR | O_CREAT, 0666);

	if (IS_ERR(fp_mac)) {
		DHD_ERROR(("[WIFI_SEC] %s: File open error\n", filepath_efs));
		return -1;
	} else {
		oldfs = get_fs();
		set_fs(get_ds());

		if (fp_mac->f_mode & FMODE_WRITE) {
			ret = fp_mac->f_op->write(fp_mac, (const char *)buf,
				sizeof(buf), &fp_mac->f_pos);
			if (ret < 0)
				DHD_ERROR(("[WIFI_SEC] Mac address [%s] Failed to"
				" write into File: %s\n", buf, filepath_efs));
			else
				DHD_INFO(("[WIFI_SEC] Mac address [%s] written"
				" into File: %s\n", buf, filepath_efs));
		}
		set_fs(oldfs);
		filp_close(fp_mac, NULL);
	}

	/* check .mac.info file is 0 byte */
	fp_mac = filp_open(filepath_efs, O_RDONLY, 0);
	ret = kernel_read(fp_mac, 0, buf, 18);

	if ((ret == 0) && (retry_count++ < 3)) {
		filp_close(fp_mac, NULL);
		goto startwrite;
	}

	filp_close(fp_mac, NULL);

	return 0;
}
Esempio n. 9
0
int dhd_tcpack_suppress_set(dhd_pub_t *dhdp, uint8 mode)
{
	int ret = BCME_OK;

	dhd_os_tcpacklock(dhdp);

	if (dhdp->tcpack_sup_mode == mode) {
		DHD_ERROR(("%s %d: already set to %d\n", __FUNCTION__, __LINE__, mode));
		goto exit;
	}

	if (mode > TCPACK_SUP_DELAYTX) {
		DHD_ERROR(("%s %d: Invalid mode %d\n", __FUNCTION__, __LINE__, mode));
		ret = BCME_BADARG;
		goto exit;
	}

	DHD_TRACE(("%s: %d -> %d\n",
		__FUNCTION__, dhdp->tcpack_sup_mode, mode));

	/* Old tcpack_sup_mode is TCPACK_SUP_DELAYTX */
	if (dhdp->tcpack_sup_mode == TCPACK_SUP_DELAYTX) {
		tcpack_sup_module_t *tcpack_sup_mod = dhdp->tcpack_sup_module;
		/* We won't need tdata_psh_info pool and tcpddata_info_tbl anymore */
		_tdata_psh_info_pool_deinit(dhdp, tcpack_sup_mod);
		tcpack_sup_mod->tcpdata_info_cnt = 0;
		bzero(tcpack_sup_mod->tcpdata_info_tbl,
			sizeof(tcpdata_info_t) * TCPDATA_INFO_MAXNUM);
		/* For half duplex bus interface, tx precedes rx by default */
		if (dhdp->bus)
			dhd_bus_set_dotxinrx(dhdp->bus, TRUE);
	}

	dhdp->tcpack_sup_mode = mode;

	if (mode == TCPACK_SUP_OFF) {
		ASSERT(dhdp->tcpack_sup_module != NULL);
		MFREE(dhdp->osh, dhdp->tcpack_sup_module, sizeof(tcpack_sup_module_t));
		dhdp->tcpack_sup_module = NULL;
		goto exit;
	}

	if (dhdp->tcpack_sup_module == NULL) {
		tcpack_sup_module_t *tcpack_sup_mod =
			MALLOC(dhdp->osh, sizeof(tcpack_sup_module_t));
		if (tcpack_sup_mod == NULL) {
			DHD_ERROR(("%s %d: No MEM\n", __FUNCTION__, __LINE__));
			dhdp->tcpack_sup_mode = TCPACK_SUP_OFF;
			ret = BCME_NOMEM;
			goto exit;
		}
		bzero(tcpack_sup_mod, sizeof(tcpack_sup_module_t));
		dhdp->tcpack_sup_module = tcpack_sup_mod;
	}

	if (mode == TCPACK_SUP_DELAYTX) {
		ret = _tdata_psh_info_pool_init(dhdp, dhdp->tcpack_sup_module);
		if (ret != BCME_OK)
			DHD_ERROR(("%s %d: pool init fail with %d\n", __FUNCTION__, __LINE__, ret));
		else if (dhdp->bus)
			dhd_bus_set_dotxinrx(dhdp->bus, FALSE);
	}

exit:
	dhd_os_tcpackunlock(dhdp);
	return ret;
}
int dhd_check_module_cid(dhd_pub_t *dhd)
{
	int ret = -1;
	unsigned char cis_buf[CIS_BUF_SIZE] = {0};
	const char *cidfilepath = CIDINFO;
	cis_rw_t *cish = (cis_rw_t *)&cis_buf[8];
	int idx, max;
	vid_info_t *cur_info;
	unsigned char *vid_start = NULL;
	unsigned char vid_length = 0;
#ifdef SUPPORT_MULTIPLE_BOARDTYPE
	board_info_t *cur_b_info = NULL;
	board_info_t *vendor_b_info = NULL;
	unsigned char *btype_start;
	unsigned char boardtype_len = 0;
#endif /* SUPPORT_MULTIPLE_BOARDTYPE */
	unsigned char cid_info[MAX_VNAME_LEN + MAX_BNAME_LEN];
	bool found = FALSE;
#if defined(BCM4334_CHIP) || defined(BCM4335_CHIP)
	const char *revfilepath = REVINFO;
#ifdef BCM4334_CHIP
	int flag_b3;
#else
	char rev_str[10] = {0};
#endif /* BCM4334_CHIP */
#endif /* BCM4334_CHIP || BCM4335_CHIP */

	/* Try reading out from CIS */
	cish->source = 0;
	cish->byteoff = 0;
	cish->nbytes = sizeof(cis_buf);

	strcpy(cis_buf, "cisdump");
	ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cis_buf,
		sizeof(cis_buf), 0, 0);
	if (ret < 0) {
		DHD_INFO(("[WIFI_SEC] %s: CIS reading failed, ret=%d\n",
			__FUNCTION__, ret));
		return ret;
	}

	DHD_ERROR(("[WIFI_SEC] %s: CIS reading success, ret=%d\n",
		__FUNCTION__, ret));
#ifdef DUMP_CIS
	dhd_dump_cis(cis_buf, 48);
#endif
	max = sizeof(cis_buf);
	idx = find_tuple_from_otp(cis_buf, max, CIS_TUPLE_TAG_VENDOR, &vid_length);
	if (idx > 0) {
		found = TRUE;
		vid_start = &cis_buf[idx];
	}

	if (found) {
		max = sizeof(vid_info) / sizeof(vid_info_t);
		for (idx = 0; idx < max; idx++) {
			cur_info = &vid_info[idx];
#if defined(BCM4358_CHIP)
			if (cur_info->vid_length  == 6 && vid_length == 6) {
				if (cur_info->vid[0] == vid_start[0] &&
				    cur_info->vid[3] == vid_start[3] &&
				    cur_info->vid[4] == vid_start[4])
				goto check_board_type;
			}
#endif /* BCM4358_CHIP */
			if ((cur_info->vid_length == vid_length) &&
				(cur_info->vid_length != 0) &&
				(memcmp(cur_info->vid, vid_start, cur_info->vid_length - 1) == 0))
				goto check_board_type;
		}
	}

	/* find default nvram, if exist */
	DHD_ERROR(("[WIFI_SEC] %s: cannot find CIS TUPLE set as default\n", __FUNCTION__));
	max = sizeof(vid_info) / sizeof(vid_info_t);
	for (idx = 0; idx < max; idx++) {
		cur_info = &vid_info[idx];
		if (cur_info->vid_length == 0)
			goto write_cid;
	}
	DHD_ERROR(("[WIFI_SEC] %s: cannot find default CID\n", __FUNCTION__));
	return -1;

check_board_type:
#ifdef SUPPORT_MULTIPLE_BOARDTYPE
	max = sizeof(cis_buf) - 4;
	for (idx = 0; idx < max; idx++) {
		if (cis_buf[idx] == CIS_TUPLE_TAG_START &&
			cis_buf[idx + 2] == CIS_TUPLE_TAG_BOARDTYPE) {
			boardtype_len = cis_buf[idx + 1];
			btype_start = &cis_buf[idx + 3];

			/* Check buffer overflow */
			if (&cis_buf[idx + 1] + boardtype_len
				<= &cis_buf[CIS_BUF_SIZE - 1]) {
				DHD_INFO(("[WIFI_SEC] %s: board type found.\n",
					__FUNCTION__));
				break;
			} else {
				boardtype_len = 0;
			}
		}
	}

	if (strcmp(cur_info->vname, "semco") == 0) {
		vendor_b_info = semco_board_info;
		max = sizeof(semco_board_info) / sizeof(board_info_t);
	} else if (strcmp(cur_info->vname, "murata") == 0) {
		vendor_b_info = murata_board_info;
		max = sizeof(murata_board_info) / sizeof(board_info_t);
	} else {
		max = 0;
	}

	if (boardtype_len) {
		for (idx = 0; idx < max; idx++) {
			cur_b_info = vendor_b_info;
			if ((cur_b_info->b_len == boardtype_len) &&
					(cur_b_info->b_len != 0) &&
					(memcmp(cur_b_info->btype, btype_start,
					cur_b_info->b_len - 1) == 0)) {
				DHD_INFO(("[WIFI_SEC] %s : board type name : %s\n",
					__FUNCTION__, cur_b_info->bname));
				break;
			}
			cur_b_info = NULL;
			vendor_b_info++;
		}
	}
#endif /* SUPPORT_MULTIPLE_BOARDTYPE */

write_cid:
#ifdef SUPPORT_MULTIPLE_BOARDTYPE
	if (cur_b_info && cur_b_info->b_len > 0) {
		strcpy(cid_info, cur_info->vname);
		strcpy(cid_info + strlen(cur_info->vname), cur_b_info->bname);
	} else
#endif /* SUPPORT_MULTIPLE_BOARDTYPE */
	strcpy(cid_info, cur_info->vname);

	DHD_ERROR(("[WIFI_SEC] CIS MATCH FOUND : %s\n", cid_info));
	dhd_write_cid_file(cidfilepath, cid_info, strlen(cid_info)+1);

#if defined(BCM4334_CHIP)
	/* Try reading out from OTP to distinguish B2 or B3 */
	memset(cis_buf, 0, sizeof(cis_buf));
	cish = (cis_rw_t *)&cis_buf[8];

	cish->source = 0;
	cish->byteoff = 0;
	cish->nbytes = sizeof(cis_buf);

	strcpy(cis_buf, "otpdump");
	ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cis_buf,
		sizeof(cis_buf), 0, 0);
	if (ret < 0) {
		DHD_ERROR(("[WIFI_SEC] %s: OTP reading failed, err=%d\n",
			__FUNCTION__, ret));
		return ret;
	}

	/* otp 33th character is identifier for 4334B3 */
	cis_buf[34] = '\0';
	flag_b3 = bcm_atoi(&cis_buf[33]);
	if (flag_b3 & 0x1) {
		DHD_ERROR(("[WIFI_SEC] REV MATCH FOUND : 4334B3, %c\n", cis_buf[33]));
		dhd_write_cid_file(revfilepath, "4334B3", 6);
	}
#endif /* BCM4334_CHIP */
#if defined(BCM4335_CHIP)
	DHD_TRACE(("[WIFI_SEC] %s: BCM4335 Multiple Revision Check\n", __FUNCTION__));
	if (concate_revision(dhd->bus, rev_str, rev_str) < 0) {
		DHD_ERROR(("[WIFI_SEC] %s: fail to concate revision\n", __FUNCTION__));
		ret = -1;
	} else {
		if (strstr(rev_str, "_a0")) {
			DHD_ERROR(("[WIFI_SEC] REV MATCH FOUND : 4335A0\n"));
			dhd_write_cid_file(revfilepath, "BCM4335A0", 9);
		} else {
			DHD_ERROR(("[WIFI_SEC] REV MATCH FOUND : 4335B0\n"));
			dhd_write_cid_file(revfilepath, "BCM4335B0", 9);
		}
	}
#endif /* BCM4335_CHIP */

	return ret;
}
int dhd_check_module_mac(dhd_pub_t *dhd, struct ether_addr *mac)
{
	int ret = -1;
	unsigned char cis_buf[CIS_BUF_SIZE] = {0};
	unsigned char mac_buf[20] = {0};
	unsigned char otp_mac_buf[20] = {0};
	const char *macfilepath = MACINFO_EFS;

	/* Try reading out from CIS */
	cis_rw_t *cish = (cis_rw_t *)&cis_buf[8];
	struct file *fp_mac = NULL;

	cish->source = 0;
	cish->byteoff = 0;
	cish->nbytes = sizeof(cis_buf);

	strcpy(cis_buf, "cisdump");
	ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cis_buf,
		sizeof(cis_buf), 0, 0);
	if (ret < 0) {
		DHD_INFO(("[WIFI_SEC] %s: CIS reading failed, ret=%d\n",
			__FUNCTION__, ret));

		sprintf(otp_mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X\n",
			mac->octet[0], mac->octet[1], mac->octet[2],
			mac->octet[3], mac->octet[4], mac->octet[5]);
		DHD_ERROR(("[WIFI_SEC] %s: Check module mac by legacy FW : " MACDBG "\n",
			__FUNCTION__, MAC2STRDBG(mac->octet)));
	} else {
		int max, idx, macaddr_idx;
#ifdef DUMP_CIS
		dhd_dump_cis(cis_buf, 48);
#endif

		/* Find a new tuple tag */
		max = sizeof(cis_buf) - 8;
		for (idx = 0; idx < max; idx++) {
			if (cis_buf[idx] == CIS_TUPLE_TAG_START) {
				if (cis_buf[idx + 2] == CIS_TUPLE_TAG_MACADDR &&
					cis_buf[idx + 1] == 7) {
					macaddr_idx = idx + 3;
					/* found MAC Address tuple */
					break;
				}
			}
		}
		if (idx < max) {
			sprintf(otp_mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X\n",
				cis_buf[macaddr_idx], cis_buf[macaddr_idx + 1],
				cis_buf[macaddr_idx + 2], cis_buf[macaddr_idx + 3],
				cis_buf[macaddr_idx + 4], cis_buf[macaddr_idx + 5]);
			DHD_ERROR(("[WIFI_SEC] MAC address is taken from OTP\n"));

		} else {
			sprintf(otp_mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X\n",
				mac->octet[0], mac->octet[1], mac->octet[2],
				mac->octet[3], mac->octet[4], mac->octet[5]);
			DHD_ERROR(("[WIFI_SEC] %s: Cannot find MAC address info from OTP,"
					" Check module mac by initial value: " MACDBG "\n",
					__FUNCTION__, MAC2STRDBG(mac->octet)));
		}
	}

	fp_mac = filp_open(macfilepath, O_RDONLY, 0);
	if (!IS_ERR(fp_mac)) {
		DHD_ERROR(("[WIFI_SEC] Check Mac address in .mac.info \n"));
		kernel_read(fp_mac, fp_mac->f_pos, mac_buf, sizeof(mac_buf));
		filp_close(fp_mac, NULL);

		if (strncmp(mac_buf, otp_mac_buf, 17) != 0) {
			DHD_ERROR(("[WIFI_SEC] file MAC is wrong. Write OTP MAC in .mac.info \n"));
			dhd_write_mac_file(macfilepath, otp_mac_buf, sizeof(otp_mac_buf));
		}
	}

	return ret;
}
int dhd_read_macaddr(struct dhd_info *dhd, struct ether_addr *mac)
{
	struct file *fp      = NULL;
	char macbuffer[18]   = {0};
	mm_segment_t oldfs   = {0};
	char randommac[3]    = {0};
	char buf[18]         = {0};
	char *filepath_efs       = MACINFO_EFS;
	int ret = 0;

	fp = filp_open(filepath_efs, O_RDONLY, 0);
	if (IS_ERR(fp)) {
start_readmac:
		/* File Doesn't Exist. Create and write mac addr. */
		fp = filp_open(filepath_efs, O_RDWR | O_CREAT, 0666);
		if (IS_ERR(fp)) {
			DHD_ERROR(("[WIFI_SEC] %s: File open error\n", filepath_efs));
			return -1;
		}
		oldfs = get_fs();
		set_fs(get_ds());

		/* Generating the Random Bytes for 3 last octects of the MAC address */
		get_random_bytes(randommac, 3);

		sprintf(macbuffer, "%02X:%02X:%02X:%02X:%02X:%02X\n",
			0x00, 0x12, 0x34, randommac[0], randommac[1], randommac[2]);
		DHD_ERROR(("[WIFI_SEC] The Random Generated MAC ID: %s\n", macbuffer));

		if (fp->f_mode & FMODE_WRITE) {
			ret = fp->f_op->write(fp, (const char *)macbuffer,
			sizeof(macbuffer), &fp->f_pos);
			if (ret < 0)
				DHD_ERROR(("[WIFI_SEC] MAC address [%s] Failed to write into File:"
					" %s\n", macbuffer, filepath_efs));
			else
				DHD_ERROR(("[WIFI_SEC] MAC address [%s] written into File: %s\n",
					macbuffer, filepath_efs));
		}
		set_fs(oldfs);
		/* Reading the MAC Address from .mac.info file
		   ( the existed file or just created file)
		 */
		ret = kernel_read(fp, 0, buf, 18);
	} else {
		/* Reading the MAC Address from
		   .mac.info file( the existed file or just created file)
		 */
		ret = kernel_read(fp, 0, buf, 18);
		/* to prevent abnormal string display
		* when mac address is displayed on the screen.
		*/
		buf[17] = '\0';
		if (strncmp(buf, "00:00:00:00:00:00", 17) < 1) {
			DHD_ERROR(("[WIFI_SEC] goto start_readmac \r\n"));
			filp_close(fp, NULL);
			goto start_readmac;
		}
	}

	if (ret)
		sscanf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
			(unsigned int *)&(mac->octet[0]), (unsigned int *)&(mac->octet[1]),
			(unsigned int *)&(mac->octet[2]), (unsigned int *)&(mac->octet[3]),
			(unsigned int *)&(mac->octet[4]), (unsigned int *)&(mac->octet[5]));
	else
		DHD_ERROR(("[WIFI_SEC] dhd_bus_start: Reading from the '%s' returns 0 bytes\n",
			filepath_efs));

	if (fp)
		filp_close(fp, NULL);

	/* Writing Newly generated MAC ID to the Dongle */
	if (_dhd_set_mac_address(dhd, 0, mac) == 0)
		DHD_INFO(("[WIFI_SEC] dhd_bus_start: MACID is overwritten\n"));
	else
		DHD_ERROR(("[WIFI_SEC] dhd_bus_start: _dhd_set_mac_address() failed\n"));

	return 0;
}
uint32 sec_save_wlinfo(char *firm_ver, char *dhd_ver, char *nvram_p)
{
	struct file *fp = NULL;
	struct file *nvfp = NULL;
	char *filepath = WIFIVERINFO;
	int min_len, str_len = 0;
	int ret = 0;
	char* nvram_buf;
	char temp_buf[256];

	DHD_TRACE(("[WIFI_SEC] %s: Entered.\n", __FUNCTION__));

	DHD_INFO(("[WIFI_SEC] firmware version   : %s\n", firm_ver));
	DHD_INFO(("[WIFI_SEC] dhd driver version : %s\n", dhd_ver));
	DHD_INFO(("[WIFI_SEC] nvram path : %s\n", nvram_p));

	memset(version_info, 0, sizeof(version_info));

	if (strlen(dhd_ver)) {
		min_len = min(strlen(dhd_ver), max_len(temp_buf, DHD_PREFIX));
		min_len += strlen(DHD_PREFIX) + 3;
		DHD_INFO(("[WIFI_SEC] DHD ver length : %d\n", min_len));
		snprintf(version_info+str_len, min_len, DHD_PREFIX " %s\n", dhd_ver);
		str_len = strlen(version_info);

		DHD_INFO(("[WIFI_SEC] Driver version_info len : %d\n", str_len));
		DHD_INFO(("[WIFI_SEC] Driver version_info : %s\n", version_info));
	} else {
		DHD_ERROR(("[WIFI_SEC] Driver version is missing.\n"));
	}

	if (strlen(firm_ver)) {
		min_len = min(strlen(firm_ver), max_len(temp_buf, FIRM_PREFIX));
		min_len += strlen(FIRM_PREFIX) + 3;
		DHD_INFO(("[WIFI_SEC] firmware ver length : %d\n", min_len));
		snprintf(version_info+str_len, min_len, FIRM_PREFIX " %s\n", firm_ver);
		str_len = strlen(version_info);

		DHD_INFO(("[WIFI_SEC] Firmware version_info len : %d\n", str_len));
		DHD_INFO(("[WIFI_SEC] Firmware version_info : %s\n", version_info));
	} else {
		DHD_ERROR(("[WIFI_SEC] Firmware version is missing.\n"));
	}

	if (nvram_p) {
		memset(temp_buf, 0, sizeof(temp_buf));
		nvfp = filp_open(nvram_p, O_RDONLY, 0);
		if (IS_ERR(nvfp) || (nvfp == NULL)) {
			DHD_ERROR(("[WIFI_SEC] %s: Nvarm File open failed.\n", __FUNCTION__));
			return -1;
		} else {
			ret = kernel_read(nvfp, nvfp->f_pos, temp_buf, sizeof(temp_buf));
			filp_close(nvfp, NULL);
		}

		if (strlen(temp_buf)) {
			nvram_buf = temp_buf;
			bcmstrtok(&nvram_buf, "\n", 0);
			DHD_INFO(("[WIFI_SEC] nvram tolkening : %s(%zu) \n",
				temp_buf, strlen(temp_buf)));
			snprintf(version_info+str_len, tstr_len(temp_buf, NV_PREFIX),
				NV_PREFIX " %s\n", temp_buf);
			str_len = strlen(version_info);
			DHD_INFO(("[WIFI_SEC] NVRAM version_info : %s\n", version_info));
			DHD_INFO(("[WIFI_SEC] NVRAM version_info len : %d, nvram len : %zu\n",
				str_len, strlen(temp_buf)));
		} else {
			DHD_ERROR(("[WIFI_SEC] NVRAM info is missing.\n"));
		}
	} else {
		DHD_ERROR(("[WIFI_SEC] Not exist nvram path\n"));
	}

	DHD_INFO(("[WIFI_SEC] version_info : %s, strlen : %zu\n",
		version_info, strlen(version_info)));

	fp = filp_open(filepath, O_RDONLY, 0);
	if (IS_ERR(fp) || (fp == NULL)) {
		DHD_ERROR(("[WIFI_SEC] %s: .wifiver.info File open failed.\n", __FUNCTION__));
	} else {
		memset(version_old_info, 0, sizeof(version_old_info));
		ret = kernel_read(fp, fp->f_pos, version_old_info, sizeof(version_info));
		filp_close(fp, NULL);
		DHD_INFO(("[WIFI_SEC] kernel_read ret : %d.\n", ret));
		if (strcmp(version_info, version_old_info) == 0) {
			DHD_ERROR(("[WIFI_SEC] .wifiver.info already saved.\n"));
			return 0;
		}
	}

	fp = filp_open(filepath, O_RDWR | O_CREAT, 0664);
	if (IS_ERR(fp) || (fp == NULL)) {
		DHD_ERROR(("[WIFI_SEC] %s: .wifiver.info File open failed.\n",
			__FUNCTION__));
	} else {
		ret = write_filesystem(fp, fp->f_pos, version_info, sizeof(version_info));
		DHD_INFO(("[WIFI_SEC] sec_save_wlinfo done. ret : %d\n", ret));
		DHD_ERROR(("[WIFI_SEC] save .wifiver.info file.\n"));
		filp_close(fp, NULL);
	}
	return ret;
}
int sec_get_param_wfa_cert(dhd_pub_t *dhd, int mode, uint* read_val)
{
	struct file *fp = NULL;
	char *filepath = NULL;
	int val = 0;

	if (!dhd || (mode < SET_PARAM_BUS_TXGLOM_MODE) ||
		(mode >= PARAM_LAST_VALUE)) {
		DHD_ERROR(("[WIFI_SEC] %s: invalid argument\n", __FUNCTION__));
		return BCME_ERROR;
	}

	switch (mode) {
		case SET_PARAM_BUS_TXGLOM_MODE:
			filepath = "/data/.bustxglom.info";
			break;
		case SET_PARAM_ROAMOFF:
			filepath = "/data/.roamoff.info";
			break;
#ifdef USE_WL_FRAMEBURST
		case SET_PARAM_FRAMEBURST:
			filepath = "/data/.frameburst.info";
			break;
#endif /* USE_WL_FRAMEBURST */
#ifdef USE_WL_TXBF
		case SET_PARAM_TXBF:
			filepath = "/data/.txbf.info";
			break;
#endif /* USE_WL_TXBF */
#ifdef PROP_TXSTATUS
		case SET_PARAM_PROPTX:
			filepath = "/data/.proptx.info";
			break;
#endif /* PROP_TXSTATUS */
		default:
			DHD_ERROR(("[WIFI_SEC] %s: File to find file name for index=%d\n",
				__FUNCTION__, mode));
			return BCME_ERROR;
	}

	fp = filp_open(filepath, O_RDONLY, 0);
	if (IS_ERR(fp) || (fp == NULL)) {
		DHD_ERROR(("[WIFI_SEC] %s: File [%s] doesn't exist \n",
			__FUNCTION__, filepath));
		return BCME_ERROR;
	} else {
		if (kernel_read(fp, fp->f_pos, (char *)&val, 4) < 0) {
			filp_close(fp, NULL);
			/* File operation is failed so we will return error code */
			DHD_ERROR(("[WIFI_SEC] %s: read failed, file path=%s\n",
				__FUNCTION__, filepath));
			return BCME_ERROR;
		}
		filp_close(fp, NULL);
	}

	val = bcm_atoi((char *)&val);

	switch (mode) {
		case SET_PARAM_ROAMOFF:
#ifdef USE_WL_FRAMEBURST
		case SET_PARAM_FRAMEBURST:
#endif /* USE_WL_FRAMEBURST */
#ifdef USE_WL_TXBF
		case SET_PARAM_TXBF:
#endif /* USE_WL_TXBF */
#ifdef PROP_TXSTATUS
		case SET_PARAM_PROPTX:
#endif /* PROP_TXSTATUS */
		if (val < 0 || val > 1) {
			DHD_ERROR(("[WIFI_SEC] %s: value[%d] is out of range\n",
				__FUNCTION__, *read_val));
			return BCME_ERROR;
		}
			break;
		default:
			return BCME_ERROR;
	}
	*read_val = (uint)val;
	return BCME_OK;
}
static int dhd_cfgvendor_priv_string_handler(struct wiphy *wiphy,
	struct wireless_dev *wdev, const void  *data, int len)
{
	const struct bcm_nlmsg_hdr *nlioc = data;
	struct net_device *ndev = NULL;
	struct bcm_cfg80211 *cfg;
	struct sk_buff *reply;
	void *buf = NULL, *cur;
	dhd_pub_t *dhd;
	dhd_ioctl_t ioc = { 0 };
	int ret = 0, ret_len, payload, msglen;
	int maxmsglen = PAGE_SIZE - 0x100;
	int8 index;

	WL_TRACE(("entry: cmd = %d\n", nlioc->cmd));
	DHD_ERROR(("entry: cmd = %d\n", nlioc->cmd));

	cfg = wiphy_priv(wiphy);
	dhd = cfg->pub;

	DHD_OS_WAKE_LOCK(dhd);

	/* send to dongle only if we are not waiting for reload already */
	if (dhd->hang_was_sent) {
		WL_ERR(("HANG was sent up earlier\n"));
		DHD_OS_WAKE_LOCK_CTRL_TIMEOUT_ENABLE(dhd, DHD_EVENT_TIMEOUT_MS);
		DHD_OS_WAKE_UNLOCK(dhd);
		return OSL_ERROR(BCME_DONGLE_DOWN);
	}

	len -= sizeof(struct bcm_nlmsg_hdr);
	ret_len = nlioc->len;
	if (ret_len > 0 || len > 0) {
		if (len > DHD_IOCTL_MAXLEN) {
			WL_ERR(("oversize input buffer %d\n", len));
			len = DHD_IOCTL_MAXLEN;
		}
		if (ret_len > DHD_IOCTL_MAXLEN) {
			WL_ERR(("oversize return buffer %d\n", ret_len));
			ret_len = DHD_IOCTL_MAXLEN;
		}
		payload = max(ret_len, len) + 1;
		buf = vzalloc(payload);
		if (!buf) {
			DHD_OS_WAKE_UNLOCK(dhd);
			return -ENOMEM;
		}
		memcpy(buf, (void *)nlioc + nlioc->offset, len);
		*(char *)(buf + len) = '\0';
	}

	ndev = wdev_to_wlc_ndev(wdev, cfg);
	index = dhd_net2idx(dhd->info, ndev);
	if (index == DHD_BAD_IF) {
		WL_ERR(("Bad ifidx from wdev:%p\n", wdev));
		ret = BCME_ERROR;
		goto done;
	}

	ioc.cmd = nlioc->cmd;
	ioc.len = nlioc->len;
	ioc.set = nlioc->set;
	ioc.driver = nlioc->magic;
	ret = dhd_ioctl_process(dhd, index, &ioc, buf);
	if (ret) {
		WL_TRACE(("dhd_ioctl_process return err %d\n", ret));
		ret = OSL_ERROR(ret);
		goto done;
	}

	cur = buf;
	while (ret_len > 0) {
		msglen = nlioc->len > maxmsglen ? maxmsglen : ret_len;
		ret_len -= msglen;
		payload = msglen + sizeof(msglen);
		reply = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, payload);
		if (!reply) {
			WL_ERR(("Failed to allocate reply msg\n"));
			ret = -ENOMEM;
			break;
		}

		if (nla_put(reply, BCM_NLATTR_DATA, msglen, cur) ||
			nla_put_u16(reply, BCM_NLATTR_LEN, msglen)) {
			kfree_skb(reply);
			ret = -ENOBUFS;
			break;
		}

		ret = cfg80211_vendor_cmd_reply(reply);
		if (ret) {
			WL_ERR(("testmode reply failed:%d\n", ret));
			break;
		}
		cur += msglen;
	}

done:
	vfree(buf);
	DHD_OS_WAKE_UNLOCK(dhd);
	return ret;
}
Esempio n. 16
0
inline int dhd_tcpack_check_xmit(dhd_pub_t *dhdp, void *pkt)
{
	uint8 i;
	tcpack_sup_module_t *tcpack_sup_mod;
	tcpack_info_t *tcpack_info_tbl;
	int tbl_cnt;
	uint pushed_len;
	int ret = BCME_OK;
	void *pdata;
	uint32 pktlen;

	if (dhdp->tcpack_sup_mode == TCPACK_SUP_OFF)
		goto exit;

	pdata = PKTDATA(dhdp->osh, pkt);

	/* Length of BDC(+WLFC) headers pushed */
	pushed_len = BDC_HEADER_LEN + (((struct bdc_header *)pdata)->dataOffset * 4);
	pktlen = PKTLEN(dhdp->osh, pkt) - pushed_len;

	if (pktlen < TCPACKSZMIN || pktlen > TCPACKSZMAX) {
		DHD_TRACE(("%s %d: Too short or long length %d to be TCP ACK\n",
			__FUNCTION__, __LINE__, pktlen));
		goto exit;
	}

	dhd_os_tcpacklock(dhdp);
	tcpack_sup_mod = dhdp->tcpack_sup_module;

	if (!tcpack_sup_mod) {
		DHD_ERROR(("%s %d: tcpack suppress module NULL!!\n", __FUNCTION__, __LINE__));
		ret = BCME_ERROR;
		dhd_os_tcpackunlock(dhdp);
		goto exit;
	}
	tbl_cnt = tcpack_sup_mod->tcpack_info_cnt;
	tcpack_info_tbl = tcpack_sup_mod->tcpack_info_tbl;

	ASSERT(tbl_cnt <= TCPACK_INFO_MAXNUM);

	for (i = 0; i < tbl_cnt; i++) {
		if (tcpack_info_tbl[i].pkt_in_q == pkt) {
			DHD_TRACE(("%s %d: pkt %p sent out. idx %d, tbl_cnt %d\n",
				__FUNCTION__, __LINE__, pkt, i, tbl_cnt));
			/* This pkt is being transmitted so remove the tcp_ack_info of it. */
			if (i < tbl_cnt - 1) {
				bcopy(&tcpack_info_tbl[tbl_cnt - 1],
					&tcpack_info_tbl[i], sizeof(tcpack_info_t));
			}
			bzero(&tcpack_info_tbl[tbl_cnt - 1], sizeof(tcpack_info_t));
			if (--tcpack_sup_mod->tcpack_info_cnt < 0) {
				DHD_ERROR(("%s %d: ERROR!!! tcp_ack_info_cnt %d\n",
					__FUNCTION__, __LINE__, tcpack_sup_mod->tcpack_info_cnt));
				ret = BCME_ERROR;
			}
			break;
		}
	}
	dhd_os_tcpackunlock(dhdp);

exit:
	return ret;
}
int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
{
#define PRIVATE_COMMAND_MAX_LEN	8192
	int ret = 0;
	char *command = NULL;
	int bytes_written = 0;
	android_wifi_priv_cmd priv_cmd;

	net_os_wake_lock(net);

	if (!ifr->ifr_data) {
		ret = -EINVAL;
		goto exit;
	}
	if (copy_from_user(&priv_cmd, ifr->ifr_data, sizeof(android_wifi_priv_cmd))) {
		ret = -EFAULT;
		goto exit;
	}
	if (priv_cmd.total_len > PRIVATE_COMMAND_MAX_LEN)
	{
		DHD_ERROR(("%s: too long priavte command\n", __FUNCTION__));
		ret = -EINVAL;
	}
	command = kmalloc(priv_cmd.total_len, GFP_KERNEL);
	if (!command)
	{
		DHD_ERROR(("%s: failed to allocate memory\n", __FUNCTION__));
		ret = -ENOMEM;
		goto exit;
	}
	if (copy_from_user(command, priv_cmd.buf, priv_cmd.total_len)) {
		ret = -EFAULT;
		goto exit;
	}
	DHD_INFO(("%s: Android private cmd \"%s\" on %s\n", __FUNCTION__, command, ifr->ifr_name));

	if (strnicmp(command, CMD_START, strlen(CMD_START)) == 0) {
		DHD_INFO(("%s, Received regular START command\n", __FUNCTION__));
		bytes_written = wl_android_wifi_on(net);
	}
	else if (strnicmp(command, CMD_SETFWPATH, strlen(CMD_SETFWPATH)) == 0) {
		bytes_written = wl_android_set_fwpath(net, command, priv_cmd.total_len);
	}

	if (!g_wifi_on) {
		DHD_ERROR(("%s: Ignore private cmd \"%s\" - iface %s is down\n",
			__FUNCTION__, command, ifr->ifr_name));
		ret = 0;
		goto exit;
	}

	if (strnicmp(command, CMD_STOP, strlen(CMD_STOP)) == 0) {
		bytes_written = wl_android_wifi_off(net);
	}
	else if (strnicmp(command, CMD_SCAN_ACTIVE, strlen(CMD_SCAN_ACTIVE)) == 0) {
		/* TBD: SCAN-ACTIVE */
	}
	else if (strnicmp(command, CMD_SCAN_PASSIVE, strlen(CMD_SCAN_PASSIVE)) == 0) {
		/* TBD: SCAN-PASSIVE */
	}
	else if (strnicmp(command, CMD_RSSI, strlen(CMD_RSSI)) == 0) {
		bytes_written = wl_android_get_rssi(net, command, priv_cmd.total_len);
	}
	else if (strnicmp(command, CMD_LINKSPEED, strlen(CMD_LINKSPEED)) == 0) {
		bytes_written = wl_android_get_link_speed(net, command, priv_cmd.total_len);
	}
#ifdef PKT_FILTER_SUPPORT
	else if (strnicmp(command, CMD_RXFILTER_START, strlen(CMD_RXFILTER_START)) == 0) {
		bytes_written = net_os_enable_packet_filter(net, 1);
	}
	else if (strnicmp(command, CMD_RXFILTER_STOP, strlen(CMD_RXFILTER_STOP)) == 0) {
		bytes_written = net_os_enable_packet_filter(net, 0);
	}
	else if (strnicmp(command, CMD_RXFILTER_ADD, strlen(CMD_RXFILTER_ADD)) == 0) {
		int filter_num = *(command + strlen(CMD_RXFILTER_ADD) + 1) - '0';
		bytes_written = net_os_rxfilter_add_remove(net, TRUE, filter_num);
	}
	else if (strnicmp(command, CMD_RXFILTER_REMOVE, strlen(CMD_RXFILTER_REMOVE)) == 0) {
		int filter_num = *(command + strlen(CMD_RXFILTER_REMOVE) + 1) - '0';
		bytes_written = net_os_rxfilter_add_remove(net, FALSE, filter_num);
	}
#endif /* PKT_FILTER_SUPPORT */
	else if (strnicmp(command, CMD_BTCOEXSCAN_START, strlen(CMD_BTCOEXSCAN_START)) == 0) {
		/* TBD: BTCOEXSCAN-START */
	}
	else if (strnicmp(command, CMD_BTCOEXSCAN_STOP, strlen(CMD_BTCOEXSCAN_STOP)) == 0) {
		/* TBD: BTCOEXSCAN-STOP */
	}
	else if (strnicmp(command, CMD_BTCOEXMODE, strlen(CMD_BTCOEXMODE)) == 0) {
#ifdef WL_CFG80211
		bytes_written = wl_cfg80211_set_btcoex_dhcp(net, command);
#else
#ifdef PKT_FILTER_SUPPORT
		uint mode = *(command + strlen(CMD_BTCOEXMODE) + 1) - '0';

		if (mode == 1)
			net_os_enable_packet_filter(net, 0); /* DHCP starts */
		else
			net_os_enable_packet_filter(net, 1); /* DHCP ends */
#endif /* PKT_FILTER_SUPPORT */
#endif /* WL_CFG80211 */
	}
	else if (strnicmp(command, CMD_SETSUSPENDOPT, strlen(CMD_SETSUSPENDOPT)) == 0) {
		bytes_written = wl_android_set_suspendopt(net, command, priv_cmd.total_len);
	}
	else if (strnicmp(command, CMD_SETSUSPENDMODE, strlen(CMD_SETSUSPENDMODE)) == 0) {
		bytes_written = wl_android_set_suspendmode(net, command, priv_cmd.total_len);
	}
	else if (strnicmp(command, CMD_SETBAND, strlen(CMD_SETBAND)) == 0) {
		uint band = *(command + strlen(CMD_SETBAND) + 1) - '0';
#ifdef WL_HOST_BAND_MGMT
		if (wl_cfg80211_set_band(net, band) < 0) {
			bytes_written = -1;
			goto exit;
		}
		if (band == WLC_BAND_AUTO)
			bytes_written = wldev_set_band(net, band);
#else
		bytes_written = wldev_set_band(net, band);
#endif /* WL_HOST_BAND_MGMT */
	}
	else if (strnicmp(command, CMD_GETBAND, strlen(CMD_GETBAND)) == 0) {
		bytes_written = wl_android_get_band(net, command, priv_cmd.total_len);
	}
#ifdef WL_CFG80211
	/* CUSTOMER_SET_COUNTRY feature is define for only GGSM model */
	else if (strnicmp(command, CMD_COUNTRY, strlen(CMD_COUNTRY)) == 0) {
		char *country_code = command + strlen(CMD_COUNTRY) + 1;
		bytes_written = wldev_set_country(net, country_code);
	}
#endif /* WL_CFG80211 */
#if defined(PNO_SUPPORT) && !defined(WL_SCHED_SCAN)
	else if (strnicmp(command, CMD_PNOSSIDCLR_SET, strlen(CMD_PNOSSIDCLR_SET)) == 0) {
		bytes_written = dhd_dev_pno_reset(net);
	}
	else if (strnicmp(command, CMD_PNOSETUP_SET, strlen(CMD_PNOSETUP_SET)) == 0) {
		bytes_written = wl_android_set_pno_setup(net, command, priv_cmd.total_len);
	}
	else if (strnicmp(command, CMD_PNOENABLE_SET, strlen(CMD_PNOENABLE_SET)) == 0) {
		uint pfn_enabled = *(command + strlen(CMD_PNOENABLE_SET) + 1) - '0';
		bytes_written = dhd_dev_pno_enable(net, pfn_enabled);
	}
#endif /* PNO_SUPPORT && !WL_SCHED_SCAN */
	else if (strnicmp(command, CMD_P2P_DEV_ADDR, strlen(CMD_P2P_DEV_ADDR)) == 0) {
		bytes_written = wl_android_get_p2p_dev_addr(net, command, priv_cmd.total_len);
	}
	else if (strnicmp(command, CMD_P2P_SET_NOA, strlen(CMD_P2P_SET_NOA)) == 0) {
		int skip = strlen(CMD_P2P_SET_NOA) + 1;
		bytes_written = wl_cfg80211_set_p2p_noa(net, command + skip,
			priv_cmd.total_len - skip);
	}
#if !defined WL_ENABLE_P2P_IF
	else if (strnicmp(command, CMD_P2P_GET_NOA, strlen(CMD_P2P_GET_NOA)) == 0) {
		bytes_written = wl_cfg80211_get_p2p_noa(net, command, priv_cmd.total_len);
	}
#endif /* WL_ENABLE_P2P_IF */
	else if (strnicmp(command, CMD_P2P_SET_PS, strlen(CMD_P2P_SET_PS)) == 0) {
		int skip = strlen(CMD_P2P_SET_PS) + 1;
		bytes_written = wl_cfg80211_set_p2p_ps(net, command + skip,
			priv_cmd.total_len - skip);
	}
#ifdef WL_CFG80211
	else if (strnicmp(command, CMD_SET_AP_WPS_P2P_IE,
		strlen(CMD_SET_AP_WPS_P2P_IE)) == 0) {
		int skip = strlen(CMD_SET_AP_WPS_P2P_IE) + 3;
		bytes_written = wl_cfg80211_set_wps_p2p_ie(net, command + skip,
			priv_cmd.total_len - skip, *(command + skip - 2) - '0');
	}
#endif /* WL_CFG80211 */
	else if (strnicmp(command, CMD_OKC_SET_PMK, strlen(CMD_OKC_SET_PMK)) == 0)
		bytes_written = wl_android_set_pmk(net, command, priv_cmd.total_len);
	else if (strnicmp(command, CMD_OKC_ENABLE, strlen(CMD_OKC_ENABLE)) == 0)
		bytes_written = wl_android_okc_enable(net, command, priv_cmd.total_len);
	else if (strnicmp(command, CMD_SETROAMMODE, strlen(CMD_SETROAMMODE)) == 0)
		bytes_written = wl_android_set_roam_mode(net, command, priv_cmd.total_len);
	else {
		DHD_ERROR(("Unknown PRIVATE command %s - ignored\n", command));
		snprintf(command, 3, "OK");
		bytes_written = strlen("OK");
	}

	if (bytes_written >= 0) {
		if ((bytes_written == 0) && (priv_cmd.total_len > 0))
			command[0] = '\0';
		if (bytes_written >= priv_cmd.total_len) {
			DHD_ERROR(("%s: bytes_written = %d\n", __FUNCTION__, bytes_written));
			bytes_written = priv_cmd.total_len;
		} else {
			bytes_written++;
		}
		priv_cmd.used_len = bytes_written;
		if (copy_to_user(priv_cmd.buf, command, bytes_written)) {
			DHD_ERROR(("%s: failed to copy data to user buffer\n", __FUNCTION__));
			ret = -EFAULT;
		}
	}
	else {
		ret = bytes_written;
	}

exit:
	net_os_wake_unlock(net);
	if (command) {
		kfree(command);
	}

	return ret;
}
Esempio n. 18
0
int CheckRDWR_Macaddr(	struct dhd_info *dhd, dhd_pub_t *dhdp, struct ether_addr *mac)
{
    struct file *fp_mac	= NULL;
    struct file *fp_nvm	= NULL;
    char macbuffer[18]		= {0};
    char randommac[3]		= {0};
    char buf[18]			= {0};
    char* filepath			= "/data/.mac.info";
    char* nvfilepath		= "/data/.nvmac.info";
    char cur_mac[128]		= {0};
    char dummy_mac[ETHER_ADDR_LEN]		= { 0x00, 0x90, 0x4C, 0xC5, 0x12, 0x38 };
    char cur_macbuffer[18]	= {0};
    int ret = -1;

    g_iMacFlag = MACADDR_NONE;

    fp_nvm = filp_open(nvfilepath, O_RDONLY, 0);
    if(IS_ERR(fp_nvm)) { // file is not exist
        //read MAC Address;
        //ReadMacAddress_OTP(dhd,cur_mac);
        //dhd_os_proto_block(dhdp);
        strcpy(cur_mac, "cur_etheraddr");
        //ret = dhdcdc_query_ioctl(dhdp, 0, WLC_GET_VAR, cur_mac, sizeof(cur_mac));
        ret = dhd_wl_ioctl_cmd(dhdp, WLC_GET_VAR, cur_mac, sizeof(cur_mac), 0, 0);
        if (ret < 0) {
            DHD_ERROR(("Current READ MAC error \r\n"));
            memset(cur_mac , 0 , ETHER_ADDR_LEN);
            return -1;
        }
        else {
            DHD_ERROR(("MAC (OTP) : [%02X:%02X:%02X:%02X:%02X:%02X] \r\n" ,
                       cur_mac[0], cur_mac[1], cur_mac[2], cur_mac[3], cur_mac[4], cur_mac[5]));
        }
        //dhd_os_proto_unblock(dhdp);

        sprintf(cur_macbuffer,"%02X:%02X:%02X:%02X:%02X:%02X\n",
                cur_mac[0],cur_mac[1],cur_mac[2],cur_mac[3],cur_mac[4],cur_mac[5]);

        fp_mac = filp_open(filepath, O_RDONLY, 0);
        if(IS_ERR(fp_mac)) { // file is not exist

            if(memcmp(cur_mac,dummy_mac,ETHER_ADDR_LEN) == 0) { // read mac is 00:90:4C:C5:12:38
                g_iMacFlag = MACADDR_MOD_RANDOM;
            }
            else if(strncmp(buf , "00:00:00:00:00:00" , 17) == 0) {
                g_iMacFlag = MACADDR_MOD_RANDOM;
            }
            else {
                g_iMacFlag = MACADDR_MOD;
            }
        }
        else {
            int is_zeromac;

            ret = kernel_read(fp_mac, 0, buf, 18);
            filp_close(fp_mac, NULL);
            buf[17] ='\0';

            is_zeromac = strncmp(buf, "00:00:00:00:00:00", 17);
            DHD_ERROR(("MAC (FILE): [%s] [%d] \r\n" , buf, is_zeromac));

            if (is_zeromac == 0) {
                DHD_ERROR(("Zero MAC detected. Trying Random MAC.\n"));
                g_iMacFlag = MACADDR_MOD_RANDOM;
            } else {
                sscanf(buf,"%02X:%02X:%02X:%02X:%02X:%02X",
                       &(mac->octet[0]), &(mac->octet[1]), &(mac->octet[2]),
                       &(mac->octet[3]), &(mac->octet[4]), &(mac->octet[5]));
                if(memcmp(cur_mac,mac->octet,ETHER_ADDR_LEN) == 0) { // read mac is same
                    g_iMacFlag = MACADDR_NONE;
                }
                else { // change mac..
                    if (0 == _dhd_set_mac_address(dhd, 0, mac)) {
                        DHD_INFO(("dhd_bus_start: MACID is overwritten\n"));
                        g_iMacFlag = MACADDR_MOD;
                    }
                    else {
                        DHD_ERROR(("dhd_bus_start: _dhd_set_mac_address() failed\n"));
                        g_iMacFlag = MACADDR_NONE;
                    }
                }
            }
        }
    }
    else {
        // COB type. only COB.
        /* Reading the MAC Address from .nvmac.info file( the existed file or just created file)*/
        ret = kernel_read(fp_nvm, 0, buf, 18);
        buf[17] ='\0';   // to prevent abnormal string display when mac address is displayed on the screen.
        DHD_ERROR(("Read MAC : [%s] [%d] \r\n" , buf, strncmp(buf , "00:00:00:00:00:00" , 17)));
        if(strncmp(buf , "00:00:00:00:00:00" , 17) == 0) {
            filp_close(fp_nvm, NULL);
            g_iMacFlag = MACADDR_COB_RANDOM;
        }
        else {
            sscanf(buf,"%02X:%02X:%02X:%02X:%02X:%02X",
                   &(mac->octet[0]), &(mac->octet[1]), &(mac->octet[2]),
                   &(mac->octet[3]), &(mac->octet[4]), &(mac->octet[5]));
            /* Writing Newly generated MAC ID to the Dongle */
            if (0 == _dhd_set_mac_address(dhd, 0, mac)) {
                DHD_INFO(("dhd_bus_start: MACID is overwritten\n"));
                g_iMacFlag = MACADDR_COB;
            }
            else {
                DHD_ERROR(("dhd_bus_start: _dhd_set_mac_address() failed\n"));
            }
        }
        filp_close(fp_nvm, NULL);
    }

    if((g_iMacFlag == MACADDR_COB_RANDOM) || (g_iMacFlag == MACADDR_MOD_RANDOM)) {
        get_random_bytes(randommac, 3);
        sprintf(macbuffer,"%02X:%02X:%02X:%02X:%02X:%02X\n",
                0x60,0xd0,0xa9,randommac[0],randommac[1],randommac[2]);
        DHD_ERROR(("[WIFI] The Random Generated MAC ID : %s\n", macbuffer));
        sscanf(macbuffer,"%02X:%02X:%02X:%02X:%02X:%02X",
               &(mac->octet[0]), &(mac->octet[1]), &(mac->octet[2]),
               &(mac->octet[3]), &(mac->octet[4]), &(mac->octet[5]));
        if (0 == _dhd_set_mac_address(dhd, 0, mac)) {
            DHD_INFO(("dhd_bus_start: MACID is overwritten\n"));
            g_iMacFlag = MACADDR_COB;
        }
        else {
            DHD_ERROR(("dhd_bus_start: _dhd_set_mac_address() failed\n"));
        }
    }


    return 0;
}
Esempio n. 19
0
int
dhd_read_macaddr(dhd_info_t *dhd)
{
    struct file *fp      = NULL;
    struct file *fpnv      = NULL;
    char macbuffer[18]   = {0};
    mm_segment_t oldfs   = {0};
  char randommac[3]    = {0};
  char buf[18]         = {0};
  char* filepath       = "/data/.mac.info";
    char* nvfilepath       = "/data/.nvmac.info";
  int ret;

  //MAC address copied from nv
  fpnv = filp_open(nvfilepath, O_RDONLY, 0);
  if (IS_ERR(fpnv)) {
start_readmac:
    fpnv = NULL;
    fp = filp_open(filepath, O_RDONLY, 0);
    if (IS_ERR(fp)) {
      /* File Doesn't Exist. Create and write mac addr.*/
      fp = filp_open(filepath, O_RDWR | O_CREAT, 0666);
      if(IS_ERR(fp)) {
        DHD_ERROR(("[WIFI] %s: File open error\n", filepath));
        return -1;
      }

      oldfs = get_fs();
      set_fs(get_ds());

    /* Generating the Random Bytes for 3 last octects of the MAC address */
    get_random_bytes(randommac, 3);
    
    sprintf(macbuffer,"%02X:%02X:%02X:%02X:%02X:%02X\n",
      0x60,0xd0,0xa9,randommac[0],randommac[1],randommac[2]);
      DHD_INFO(("[WIFI] The Random Generated MAC ID : %s\n", macbuffer));
      printk("[WIFI] The Random Generated MAC ID : %s\n", macbuffer);

      if(fp->f_mode & FMODE_WRITE) {      
        ret = fp->f_op->write(fp, (const char *)macbuffer, sizeof(macbuffer), &fp->f_pos);
        if(ret < 0)
          DHD_ERROR(("[WIFI] Mac address [%s] Failed to write into File: %s\n", macbuffer, filepath));
        else
          DHD_INFO(("[WIFI] Mac address [%s] written into File: %s\n", macbuffer, filepath));
      }
      set_fs(oldfs);
    }
    /* Reading the MAC Address from .mac.info file( the existed file or just created file)*/
    //rtn_value=kernel_read(fp, fp->f_pos, buf, 18);  
    ret = kernel_read(fp, 0, buf, 18);  
  }
  else {
    /* Reading the MAC Address from .nvmac.info file( the existed file or just created file)*/
    ret = kernel_read(fpnv, 0, buf, 18);
    buf[17] ='\0';   // to prevent abnormal string display when mac address is displayed on the screen. 
    printk("Read MAC : [%s] [%d] \r\n" , buf, strncmp(buf , "00:00:00:00:00:00" , 17));
    if(strncmp(buf , "00:00:00:00:00:00" , 17) == 0) {
      filp_close(fpnv, NULL);
      goto start_readmac;
    }

    fp = filp_open(filepath, O_RDONLY, 0);
    if (IS_ERR(fp))   // If you want to write MAC address to /data/.mac.info once, 
    {
      fp = filp_open(filepath, O_RDWR | O_CREAT, 0666);
      if(IS_ERR(fp)) {
        DHD_ERROR(("[WIFI] %s: File open error\n", filepath));
        return -1;
      }

      oldfs = get_fs();
      set_fs(get_ds());
      
      if(fp->f_mode & FMODE_WRITE) {
        ret = fp->f_op->write(fp, (const char *)buf, sizeof(buf), &fp->f_pos);
        if(ret < 0)
          DHD_ERROR(("[WIFI] Mac address [%s] Failed to write into File: %s\n", buf, filepath));
        else
          DHD_INFO(("[WIFI] Mac address [%s] written into File: %s\n", buf, filepath));
      }       
      set_fs(oldfs);
    } 
    ret = kernel_read(fp, 0, buf, 18);  
  }

  if(ret)
    sscanf(buf,"%02X:%02X:%02X:%02X:%02X:%02X",
         &dhd->pub.mac.octet[0], &dhd->pub.mac.octet[1], &dhd->pub.mac.octet[2], 
         &dhd->pub.mac.octet[3], &dhd->pub.mac.octet[4], &dhd->pub.mac.octet[5]);
  else
    DHD_ERROR(("dhd_bus_start: Reading from the '%s' returns 0 bytes\n", filepath));

  if (fp)
    filp_close(fp, NULL);
  if (fpnv)
    filp_close(fpnv, NULL);      

  /* Writing Newly generated MAC ID to the Dongle */
  if (0 == _dhd_set_mac_address(dhd, 0, &dhd->pub.mac))
    DHD_INFO(("dhd_bus_start: MACID is overwritten\n"));
  else
    DHD_ERROR(("dhd_bus_start: _dhd_set_mac_address() failed\n"));

    return 0;
}
Esempio n. 20
0
void
dhd_pktfilter_offload_enable(dhd_pub_t * dhd, char *arg, int enable, int master_mode)
{
	char				*argv[8];
	int					i = 0;
	const char 			*str;
	int					buf_len;
	int					str_len;
	char				*arg_save = 0, *arg_org = 0;
	int					rc;
	char				buf[128];
	wl_pkt_filter_enable_t	enable_parm;
	wl_pkt_filter_enable_t	* pkt_filterp;

	if (!(arg_save = MALLOC(dhd->osh, strlen(arg) + 1))) {
		DHD_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
		goto fail;
	}
	arg_org = arg_save;
	memcpy(arg_save, arg, strlen(arg) + 1);

	argv[i] = bcmstrtok(&arg_save, " ", 0);

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

	str = "pkt_filter_enable";
	str_len = strlen(str);
	strncpy(buf, str, str_len);
	buf[str_len] = '\0';
	buf_len = str_len + 1;

	pkt_filterp = (wl_pkt_filter_enable_t *)(buf + str_len + 1);

	/* Parse packet filter id. */
	enable_parm.id = htod32(strtoul(argv[i], NULL, 0));

	/* Parse enable/disable value. */
	enable_parm.enable = htod32(enable);

	buf_len += sizeof(enable_parm);
	memcpy((char *)pkt_filterp,
	       &enable_parm,
	       sizeof(enable_parm));

	/* Enable/disable the specified filter. */
	rc = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, buf_len, TRUE, 0);
	rc = rc >= 0 ? 0 : rc;
	if (rc)
		DHD_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n",
		__FUNCTION__, arg, rc));
	else
		DHD_TRACE(("%s: successfully added pktfilter %s\n",
		__FUNCTION__, arg));

	/* Contorl the master mode */
	bcm_mkiovar("pkt_filter_mode", (char *)&master_mode, 4, buf, sizeof(buf));
	rc = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, sizeof(buf), TRUE, 0);
	rc = rc >= 0 ? 0 : rc;
	if (rc)
		DHD_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n",
		__FUNCTION__, arg, rc));

fail:
	if (arg_org)
		MFREE(dhd->osh, arg_org, strlen(arg) + 1);
}
Esempio n. 21
0
static int
dhd_rtt_start(dhd_pub_t *dhd) {
	int err = BCME_OK;
	int mpc = 0;
	int nss, mcs, bw;
	uint32 rspec = 0;
	int8 eabuf[ETHER_ADDR_STR_LEN];
	int8 chanbuf[CHANSPEC_STR_LEN];
	bool set_mpc = FALSE;
	wl_proxd_iovar_t proxd_iovar;
	wl_proxd_params_iovar_t proxd_params;
	wl_proxd_params_iovar_t proxd_tune;
	wl_proxd_params_tof_method_t *tof_params = &proxd_params.u.tof_params;
	rtt_status_info_t *rtt_status;
	rtt_target_info_t *rtt_target;
	NULL_CHECK(dhd, "dhd is NULL", err);

	rtt_status = GET_RTTSTATE(dhd);
	NULL_CHECK(rtt_status, "rtt_status is NULL", err);
	/* turn off mpc in case of non-associted */
	if (!dhd_is_associated(dhd, NULL, NULL)) {
		err = dhd_iovar(dhd, 0, "mpc", (char *)&mpc, sizeof(mpc), 1);
		if (err < 0) {
				DHD_ERROR(("%s : failed to set proxd_tune\n", __FUNCTION__));
				goto exit;
		}
		set_mpc = TRUE;
	}

	if (rtt_status->cur_idx >= rtt_status->rtt_config.rtt_target_cnt) {
		err = BCME_RANGE;
		goto exit;
	}
	DHD_RTT(("%s enter\n", __FUNCTION__));
	bzero(&proxd_tune, sizeof(proxd_tune));
	bzero(&proxd_params, sizeof(proxd_params));
	mutex_lock(&rtt_status->rtt_mutex);
	/* Get a target information */
	rtt_target = &rtt_status->rtt_config.target_info[rtt_status->cur_idx];
	mutex_unlock(&rtt_status->rtt_mutex);
	/* set role */
	proxd_iovar.method = PROXD_TOF_METHOD;
	proxd_iovar.mode = WL_PROXD_MODE_INITIATOR;

	/* make sure that proxd is stop */
	//dhd_iovar(dhd, 0, "proxd_stop", (char *)NULL, 0, 1);

	err = dhd_iovar(dhd, 0, "proxd", (char *)&proxd_iovar, sizeof(proxd_iovar), 1);
	if (err < 0 && err != BCME_BUSY) {
		DHD_ERROR(("%s : failed to set proxd %d\n", __FUNCTION__, err));
		goto exit;
	}
	/* mac address */
	bcopy(&rtt_target->addr, &tof_params->tgt_mac, ETHER_ADDR_LEN);
	/* frame count */
	if (rtt_target->ftm_cnt > RTT_MAX_FRAME_CNT)
		rtt_target->ftm_cnt = RTT_MAX_FRAME_CNT;

	if (rtt_target->ftm_cnt)
		tof_params->ftm_cnt = htol16(rtt_target->ftm_cnt);
	else
		tof_params->ftm_cnt = htol16(DEFAULT_FTM_CNT);

	if (rtt_target->retry_cnt > RTT_MAX_RETRY_CNT)
		rtt_target->retry_cnt = RTT_MAX_RETRY_CNT;

	/* retry count */
	if (rtt_target->retry_cnt)
		tof_params->retry_cnt = htol16(rtt_target->retry_cnt);
	else
		tof_params->retry_cnt = htol16(DEFAULT_RETRY_CNT);

	/* chanspec */
	tof_params->chanspec = htol16(rtt_target->chanspec);
	/* set parameter */
	DHD_RTT(("Target addr(Idx %d) %s, Channel : %s for RTT (ftm_cnt %d, rety_cnt : %d)\n",
			rtt_status->cur_idx,
			bcm_ether_ntoa((const struct ether_addr *)&rtt_target->addr, eabuf),
			wf_chspec_ntoa(rtt_target->chanspec, chanbuf), rtt_target->ftm_cnt,
			rtt_target->retry_cnt));

	if (rtt_target->type == RTT_ONE_WAY) {
		proxd_tune.u.tof_tune.flags = htol32(WL_PROXD_FLAG_ONEWAY);
		/* report RTT results for initiator */
		proxd_tune.u.tof_tune.flags |= htol32(WL_PROXD_FLAG_INITIATOR_RPTRTT);
		proxd_tune.u.tof_tune.vhtack = 0;
		tof_params->tx_rate = htol16(WL_RATE_6M);
		tof_params->vht_rate = htol16((WL_RATE_6M >> 16));
	} else { /* RTT TWO WAY */
Esempio n. 22
0
void
dhd_pktfilter_offload_set(dhd_pub_t * dhd, char *arg)
{
	const char 			*str;
	wl_pkt_filter_t		pkt_filter;
	wl_pkt_filter_t		*pkt_filterp;
	int					buf_len;
	int					str_len;
	int 				rc;
	uint32				mask_size;
	uint32				pattern_size;
	char				*argv[8], * buf = 0;
	int					i = 0;
	char				*arg_save = 0, *arg_org = 0;
#define BUF_SIZE		2048

	if (!(arg_save = MALLOC(dhd->osh, strlen(arg) + 1))) {
		DHD_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
		goto fail;
	}

	arg_org = arg_save;

	if (!(buf = MALLOC(dhd->osh, BUF_SIZE))) {
		DHD_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
		goto fail;
	}

	memcpy(arg_save, arg, strlen(arg) + 1);

	if (strlen(arg) > BUF_SIZE) {
		DHD_ERROR(("Not enough buffer %d < %d\n", (int)strlen(arg), (int)sizeof(buf)));
		goto fail;
	}

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

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

	str = "pkt_filter_add";
	str_len = strlen(str);
	strncpy(buf, str, str_len);
	buf[ str_len ] = '\0';
	buf_len = str_len + 1;

	pkt_filterp = (wl_pkt_filter_t *) (buf + str_len + 1);

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

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

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

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

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

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

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

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

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

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

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

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

	pkt_filter.u.pattern.size_bytes = mask_size;
	buf_len += WL_PKT_FILTER_FIXED_LEN;
	buf_len += (WL_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,
	       WL_PKT_FILTER_FIXED_LEN + WL_PKT_FILTER_PATTERN_FIXED_LEN);

	rc = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, buf_len, TRUE, 0);
	rc = rc >= 0 ? 0 : rc;

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

fail:
	if (arg_org)
		MFREE(dhd->osh, arg_org, strlen(arg) + 1);

	if (buf)
		MFREE(dhd->osh, buf, BUF_SIZE);
}
bool
dhd_tcpack_hold(dhd_pub_t *dhdp, void *pkt, int ifidx)
{
	uint8 *new_ether_hdr;	/* Ethernet header of the new packet */
	uint16 new_ether_type;	/* Ethernet type of the new packet */
	uint8 *new_ip_hdr;		/* IP header of the new packet */
	uint8 *new_tcp_hdr;		/* TCP header of the new packet */
	uint32 new_ip_hdr_len;	/* IP header length of the new packet */
	uint32 cur_framelen;
	uint32 new_tcp_ack_num;		/* TCP acknowledge number of the new packet */
	uint16 new_ip_total_len;	/* Total length of IP packet for the new packet */
	uint32 new_tcp_hdr_len;		/* TCP header length of the new packet */
	tcpack_sup_module_t *tcpack_sup_mod;
	tcpack_info_t *tcpack_info_tbl;
	int i, free_slot = TCPACK_INFO_MAXNUM;
	bool hold = FALSE;
	unsigned long flags;

	if (dhdp->tcpack_sup_mode != TCPACK_SUP_HOLD) {
		goto exit;
	}

	if (dhdp->tcpack_sup_ratio == 1) {
		goto exit;
	}

	new_ether_hdr = PKTDATA(dhdp->osh, pkt);
	cur_framelen = PKTLEN(dhdp->osh, pkt);

	if (cur_framelen < TCPACKSZMIN || cur_framelen > TCPACKSZMAX) {
		DHD_TRACE(("%s %d: Too short or long length %d to be TCP ACK\n",
			__FUNCTION__, __LINE__, cur_framelen));
		goto exit;
	}

	new_ether_type = new_ether_hdr[12] << 8 | new_ether_hdr[13];

	if (new_ether_type != ETHER_TYPE_IP) {
		DHD_TRACE(("%s %d: Not a IP packet 0x%x\n",
			__FUNCTION__, __LINE__, new_ether_type));
		goto exit;
	}

	DHD_TRACE(("%s %d: IP pkt! 0x%x\n", __FUNCTION__, __LINE__, new_ether_type));

	new_ip_hdr = new_ether_hdr + ETHER_HDR_LEN;
	cur_framelen -= ETHER_HDR_LEN;

	ASSERT(cur_framelen >= IPV4_MIN_HEADER_LEN);

	new_ip_hdr_len = IPV4_HLEN(new_ip_hdr);
	if (IP_VER(new_ip_hdr) != IP_VER_4 || IPV4_PROT(new_ip_hdr) != IP_PROT_TCP) {
		DHD_TRACE(("%s %d: Not IPv4 nor TCP! ip ver %d, prot %d\n",
			__FUNCTION__, __LINE__, IP_VER(new_ip_hdr), IPV4_PROT(new_ip_hdr)));
		goto exit;
	}

	new_tcp_hdr = new_ip_hdr + new_ip_hdr_len;
	cur_framelen -= new_ip_hdr_len;

	ASSERT(cur_framelen >= TCP_MIN_HEADER_LEN);

	DHD_TRACE(("%s %d: TCP pkt!\n", __FUNCTION__, __LINE__));

	/* is it an ack ? Allow only ACK flag, not to suppress others. */
	if (new_tcp_hdr[TCP_FLAGS_OFFSET] != TCP_FLAG_ACK) {
		DHD_TRACE(("%s %d: Do not touch TCP flag 0x%x\n",
			__FUNCTION__, __LINE__, new_tcp_hdr[TCP_FLAGS_OFFSET]));
		goto exit;
	}

	new_ip_total_len = ntoh16_ua(&new_ip_hdr[IPV4_PKTLEN_OFFSET]);
	new_tcp_hdr_len = 4 * TCP_HDRLEN(new_tcp_hdr[TCP_HLEN_OFFSET]);

	/* This packet has TCP data, so just send */
	if (new_ip_total_len > new_ip_hdr_len + new_tcp_hdr_len) {
		DHD_TRACE(("%s %d: Do nothing for TCP DATA\n", __FUNCTION__, __LINE__));
		goto exit;
	}

	ASSERT(new_ip_total_len == new_ip_hdr_len + new_tcp_hdr_len);

	new_tcp_ack_num = ntoh32_ua(&new_tcp_hdr[TCP_ACK_NUM_OFFSET]);

	DHD_TRACE(("%s %d: TCP ACK with zero DATA length"
		" IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR" TCP port %d %d\n",
		__FUNCTION__, __LINE__,
		IPV4_ADDR_TO_STR(ntoh32_ua(&new_ip_hdr[IPV4_SRC_IP_OFFSET])),
		IPV4_ADDR_TO_STR(ntoh32_ua(&new_ip_hdr[IPV4_DEST_IP_OFFSET])),
		ntoh16_ua(&new_tcp_hdr[TCP_SRC_PORT_OFFSET]),
		ntoh16_ua(&new_tcp_hdr[TCP_DEST_PORT_OFFSET])));

	/* Look for tcp_ack_info that has the same ip src/dst addrs and tcp src/dst ports */
	flags = dhd_os_tcpacklock(dhdp);

	tcpack_sup_mod = dhdp->tcpack_sup_module;
	tcpack_info_tbl = tcpack_sup_mod->tcpack_info_tbl;

	if (!tcpack_sup_mod) {
		DHD_ERROR(("%s %d: tcpack suppress module NULL!!\n", __FUNCTION__, __LINE__));
		dhd_os_tcpackunlock(dhdp, flags);
		goto exit;
	}

	hold = TRUE;

	for (i = 0; i < TCPACK_INFO_MAXNUM; i++) {
		void *oldpkt;	/* TCPACK packet that is already in txq or DelayQ */
		uint8 *old_ether_hdr, *old_ip_hdr, *old_tcp_hdr;
		uint32 old_ip_hdr_len, old_tcp_hdr_len;
		uint32 old_tcpack_num;	/* TCP ACK number of old TCPACK packet in Q */

		if ((oldpkt = tcpack_info_tbl[i].pkt_in_q) == NULL) {
			if (free_slot == TCPACK_INFO_MAXNUM) {
				free_slot = i;
			}
			continue;
		}

		if (PKTDATA(dhdp->osh, oldpkt) == NULL) {
			DHD_ERROR(("%s %d: oldpkt data NULL!! cur idx %d\n",
				__FUNCTION__, __LINE__, i));
			hold = FALSE;
			dhd_os_tcpackunlock(dhdp, flags);
			goto exit;
		}

		old_ether_hdr = tcpack_info_tbl[i].pkt_ether_hdr;
		old_ip_hdr = old_ether_hdr + ETHER_HDR_LEN;
		old_ip_hdr_len = IPV4_HLEN(old_ip_hdr);
		old_tcp_hdr = old_ip_hdr + old_ip_hdr_len;
		old_tcp_hdr_len = 4 * TCP_HDRLEN(old_tcp_hdr[TCP_HLEN_OFFSET]);

		DHD_TRACE(("%s %d: oldpkt %p[%d], IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR
			" TCP port %d %d\n", __FUNCTION__, __LINE__, oldpkt, i,
			IPV4_ADDR_TO_STR(ntoh32_ua(&old_ip_hdr[IPV4_SRC_IP_OFFSET])),
			IPV4_ADDR_TO_STR(ntoh32_ua(&old_ip_hdr[IPV4_DEST_IP_OFFSET])),
			ntoh16_ua(&old_tcp_hdr[TCP_SRC_PORT_OFFSET]),
			ntoh16_ua(&old_tcp_hdr[TCP_DEST_PORT_OFFSET])));

		/* If either of IP address or TCP port number does not match, skip. */
		if (memcmp(&new_ip_hdr[IPV4_SRC_IP_OFFSET],
			&old_ip_hdr[IPV4_SRC_IP_OFFSET], IPV4_ADDR_LEN * 2) ||
			memcmp(&new_tcp_hdr[TCP_SRC_PORT_OFFSET],
			&old_tcp_hdr[TCP_SRC_PORT_OFFSET], TCP_PORT_LEN * 2)) {
			continue;
		}

		old_tcpack_num = ntoh32_ua(&old_tcp_hdr[TCP_ACK_NUM_OFFSET]);

		if (IS_TCPSEQ_GE(new_tcp_ack_num, old_tcpack_num)) {
			tcpack_info_tbl[i].supp_cnt++;
			if (tcpack_info_tbl[i].supp_cnt >= dhdp->tcpack_sup_ratio) {
				tcpack_info_tbl[i].pkt_in_q = NULL;
				tcpack_info_tbl[i].pkt_ether_hdr = NULL;
				tcpack_info_tbl[i].ifidx = 0;
				tcpack_info_tbl[i].supp_cnt = 0;
				hold = FALSE;
			} else {
				tcpack_info_tbl[i].pkt_in_q = pkt;
				tcpack_info_tbl[i].pkt_ether_hdr = new_ether_hdr;
				tcpack_info_tbl[i].ifidx = ifidx;
			}
			PKTFREE(dhdp->osh, oldpkt, TRUE);
		} else {
			PKTFREE(dhdp->osh, pkt, TRUE);
		}
		dhd_os_tcpackunlock(dhdp, flags);

		if (!hold) {
			del_timer_sync(&tcpack_info_tbl[i].timer);
		}
		goto exit;
	}

	if (free_slot < TCPACK_INFO_MAXNUM) {
		/* No TCPACK packet with the same IP addr and TCP port is found
		 * in tcp_ack_info_tbl. So add this packet to the table.
		 */
		DHD_TRACE(("%s %d: Add pkt 0x%p(ether_hdr 0x%p) to tbl[%d]\n",
			__FUNCTION__, __LINE__, pkt, new_ether_hdr,
			free_slot));

		tcpack_info_tbl[free_slot].pkt_in_q = pkt;
		tcpack_info_tbl[free_slot].pkt_ether_hdr = new_ether_hdr;
		tcpack_info_tbl[free_slot].ifidx = ifidx;
		tcpack_info_tbl[free_slot].supp_cnt = 1;
		mod_timer(&tcpack_sup_mod->tcpack_info_tbl[free_slot].timer,
			jiffies + msecs_to_jiffies(dhdp->tcpack_sup_delay));
		tcpack_sup_mod->tcpack_info_cnt++;
	} else {
		DHD_TRACE(("%s %d: No empty tcp ack info tbl\n",
			__FUNCTION__, __LINE__));
	}
	dhd_os_tcpackunlock(dhdp, flags);

exit:
	return hold;
}
Esempio n. 24
0
/*
* delete disappeared AP from specific scan cache
*/
int
dhd_iscan_delete_bss(/* TBD void *dhdp, */ void *addr)
{
	int i = 0, j = 0, l = 0;
	iscan_buf_t *iscan_cur;
	wl_iscan_results_t *list;
	wl_scan_results_t *results;
	wl_bss_info_t UNALIGNED *bi, *bi_new, *bi_next;

	uchar *s_addr = addr;
	DHD_TRACE(("%s: Entered\n", __FUNCTION__));

	dhd_iscan_lock();
	DHD_TRACE(("%s: BSS to remove %X:%X:%X:%X:%X:%X\n",
	__FUNCTION__, s_addr[0], s_addr[1], s_addr[2],
	s_addr[3], s_addr[4], s_addr[5]));

	DHD_TRACE(("%s: Scan cache before delete\n",
	__FUNCTION__));

	iscan_cur = dhd_iscan_result_buf();

	while (iscan_cur) {
			list = (wl_iscan_results_t *)iscan_cur->iscan_buf;
			if (!list)
				break;

			results = (wl_scan_results_t *)&list->results;
			if (!results)
				break;

			if (results->version != WL_BSS_INFO_VERSION) {
			DHD_ERROR(("%s: results->version %d != WL_BSS_INFO_VERSION\n",
				__FUNCTION__, results->version));
				goto done;
			}

			bi = results->bss_info;
			for (i = 0; i < results->count; i++) {
				if (!bi)
					break;

				if (!memcmp(bi->BSSID.octet, addr, ETHER_ADDR_LEN)) {
					DHD_TRACE(("%s: Del BSS[%2.2d:%2.2d] %X:%X:%X:%X:%X:%X\n",
					__FUNCTION__, l, i, bi->BSSID.octet[0], bi->BSSID.octet[1],
					bi->BSSID.octet[2], bi->BSSID.octet[3], bi->BSSID.octet[4],
					bi->BSSID.octet[5]));

					bi_new = bi;
					bi = (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length));


					for (j = i; j < results->count; j++) {
					DHD_TRACE(("%s: Moved up BSS[%2.2d:%2.2d]"
					" %X:%X:%X:%X:%X:%X\n",
					__FUNCTION__, l, j, bi->BSSID.octet[0], bi->BSSID.octet[1],
					bi->BSSID.octet[2], bi->BSSID.octet[3], bi->BSSID.octet[4],
					bi->BSSID.octet[5]));

					bi_next = (wl_bss_info_t *)((uintptr)bi +
						dtoh32(bi->length));
							bcopy(bi, bi_new, dtoh32(bi->length));
					bi_new = (wl_bss_info_t *)((uintptr)bi_new +
						dtoh32(bi_new->length));
							bi = bi_next;
						}
				results->count--;
					if (results->count == 0) {
						/* Prune now empty partial scan list */
						goto done;
					}
					break;
				}

				bi = (wl_bss_info_t *)((uintptr)bi + dtoh32(bi->length));
			}
		iscan_cur = iscan_cur->next;
		l++;
	}

done:
	DHD_TRACE(("%s: Scan cache after delete\n",
		__FUNCTION__));
	dhd_iscan_unlock();
	return 0;
}
static INLINE bool dhd_tcpdata_psh_acked(dhd_pub_t *dhdp, uint8 *ip_hdr,
	uint8 *tcp_hdr, uint32 tcp_ack_num)
{
	tcpack_sup_module_t *tcpack_sup_mod;
	int i;
	tcpdata_info_t *tcpdata_info = NULL;
	tdata_psh_info_t *tdata_psh_info = NULL;
	bool ret = FALSE;

	if (dhdp->tcpack_sup_mode != TCPACK_SUP_DELAYTX)
		goto exit;

	tcpack_sup_mod = dhdp->tcpack_sup_module;

	if (!tcpack_sup_mod) {
		DHD_ERROR(("%s %d: tcpack suppress module NULL!!\n", __FUNCTION__, __LINE__));
		goto exit;
	}

	DHD_TRACE(("%s %d: IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR
		" TCP port %d %d, ack %u\n", __FUNCTION__, __LINE__,
		IPV4_ADDR_TO_STR(ntoh32_ua(&ip_hdr[IPV4_SRC_IP_OFFSET])),
		IPV4_ADDR_TO_STR(ntoh32_ua(&ip_hdr[IPV4_DEST_IP_OFFSET])),
		ntoh16_ua(&tcp_hdr[TCP_SRC_PORT_OFFSET]),
		ntoh16_ua(&tcp_hdr[TCP_DEST_PORT_OFFSET]),
		tcp_ack_num));

	for (i = 0; i < tcpack_sup_mod->tcpdata_info_cnt; i++) {
		tcpdata_info_t *tcpdata_info_tmp = &tcpack_sup_mod->tcpdata_info_tbl[i];
		DHD_TRACE(("%s %d: data info[%d], IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR
			" TCP port %d %d\n", __FUNCTION__, __LINE__, i,
			IPV4_ADDR_TO_STR(ntoh32_ua(tcpdata_info_tmp->src_ip_addr)),
			IPV4_ADDR_TO_STR(ntoh32_ua(tcpdata_info_tmp->dst_ip_addr)),
			ntoh16_ua(tcpdata_info_tmp->src_tcp_port),
			ntoh16_ua(tcpdata_info_tmp->dst_tcp_port)));

		/* If either IP address or TCP port number does not match, skip. */
		if (memcmp(&ip_hdr[IPV4_SRC_IP_OFFSET],
			tcpdata_info_tmp->dst_ip_addr, IPV4_ADDR_LEN) == 0 &&
			memcmp(&ip_hdr[IPV4_DEST_IP_OFFSET],
			tcpdata_info_tmp->src_ip_addr, IPV4_ADDR_LEN) == 0 &&
			memcmp(&tcp_hdr[TCP_SRC_PORT_OFFSET],
			tcpdata_info_tmp->dst_tcp_port, TCP_PORT_LEN) == 0 &&
			memcmp(&tcp_hdr[TCP_DEST_PORT_OFFSET],
			tcpdata_info_tmp->src_tcp_port, TCP_PORT_LEN) == 0) {
			tcpdata_info = tcpdata_info_tmp;
			break;
		}
	}

	if (tcpdata_info == NULL) {
		DHD_TRACE(("%s %d: no tcpdata_info!\n", __FUNCTION__, __LINE__));
		goto exit;
	}

	if (tcpdata_info->tdata_psh_info_head == NULL) {
		DHD_TRACE(("%s %d: No PSH DATA to be acked!\n", __FUNCTION__, __LINE__));
	}

	while ((tdata_psh_info = tcpdata_info->tdata_psh_info_head)) {
		if (IS_TCPSEQ_GE(tcp_ack_num, tdata_psh_info->end_seq)) {
			DHD_TRACE(("%s %d: PSH ACKED! %u >= %u\n",
				__FUNCTION__, __LINE__, tcp_ack_num, tdata_psh_info->end_seq));
			tcpdata_info->tdata_psh_info_head = tdata_psh_info->next;
			tdata_psh_info->next = NULL;
			_tdata_psh_info_pool_enq(tcpack_sup_mod, tdata_psh_info);
			ret = TRUE;
		} else
			break;
	}
	if (tdata_psh_info == NULL)
		tcpdata_info->tdata_psh_info_tail = NULL;

#ifdef DHDTCPACK_SUP_DBG
	DHD_TRACE(("%s %d: PSH INFO ENQ %d\n",
		__FUNCTION__, __LINE__, tcpack_sup_mod->psh_info_enq_num));
#endif /* DHDTCPACK_SUP_DBG */

exit:
	return ret;
}
Esempio n. 26
0
/* Function to execute combined scan */
int
dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, uchar scan_fr)
{
	int err = -1;
	char iovbuf[128];
	int k, i;
	wl_pfn_param_t pfn_param;
	wl_pfn_t	pfn_element;

	DHD_TRACE(("%s nssid=%d nchan=%d\n", __FUNCTION__, nssid, scan_fr));

	if ((!dhd) && (!ssids_local)) {
		DHD_ERROR(("%s error exit\n", __FUNCTION__));
		err = -1;
	}

	/* Check for broadcast ssid */
	for (k = 0; k < nssid; k++) {
		if (!ssids_local[k].SSID_len) {
			DHD_ERROR(("%d: Broadcast SSID is ilegal for PNO setting\n", k));
			return err;
		}
	}
/* #define  PNO_DUMP 1 */
#ifdef PNO_DUMP
	{
		int j;
		for (j = 0; j < nssid; j++) {
			DHD_ERROR(("%d: scan  for  %s size =%d\n", j,
				ssids_local[j].SSID, ssids_local[j].SSID_len));
		}
	}
#endif /* PNO_DUMP */

	/* clean up everything */
	if  ((err = dhd_pno_clean(dhd)) < 0) {
		DHD_ERROR(("%s failed error=%d\n", __FUNCTION__, err));
		return err;
	}
	memset(&pfn_param, 0, sizeof(pfn_param));
	memset(&pfn_element, 0, sizeof(pfn_element));

	/* set pfn parameters */
	pfn_param.version = htod32(PFN_VERSION);
	pfn_param.flags = htod16((PFN_LIST_ORDER << SORT_CRITERIA_BIT));

	/* set up pno scan fr */
	if (scan_fr  != 0)
		pfn_param.scan_freq = htod32(scan_fr);

	bcm_mkiovar("pfn_set", (char *)&pfn_param, sizeof(pfn_param), iovbuf, sizeof(iovbuf));
	dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);

	/* set all pfn ssid */
	for (i = 0; i < nssid; i++) {

		pfn_element.bss_type = htod32(DOT11_BSSTYPE_INFRASTRUCTURE);
		pfn_element.auth = (DOT11_OPEN_SYSTEM);
		pfn_element.wpa_auth = htod32(WPA_AUTH_PFN_ANY);
		pfn_element.wsec = htod32(0);
		pfn_element.infra = htod32(1);

		memcpy((char *)pfn_element.ssid.SSID, ssids_local[i].SSID, ssids_local[i].SSID_len);
		pfn_element.ssid.SSID_len = ssids_local[i].SSID_len;

		if ((err =
		bcm_mkiovar("pfn_add", (char *)&pfn_element,
			sizeof(pfn_element), iovbuf, sizeof(iovbuf))) > 0) {
			if ((err =
			dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) < 0) {
				DHD_ERROR(("%s failed for i=%d error=%d\n",
					__FUNCTION__, i, err));
				return err;
			}
		}
		else DHD_ERROR(("%s failed err=%d\n", __FUNCTION__, err));
	}

	/* Enable PNO */
	/* dhd_pno_enable(dhd, 1); */
	return err;
}
bool
dhd_tcpdata_info_get(dhd_pub_t *dhdp, void *pkt)
{
	uint8 *ether_hdr;	/* Ethernet header of the new packet */
	uint16 ether_type;	/* Ethernet type of the new packet */
	uint8 *ip_hdr;		/* IP header of the new packet */
	uint8 *tcp_hdr;		/* TCP header of the new packet */
	uint32 ip_hdr_len;	/* IP header length of the new packet */
	uint32 cur_framelen;
	uint16 ip_total_len;	/* Total length of IP packet for the new packet */
	uint32 tcp_hdr_len;		/* TCP header length of the new packet */
	uint32 tcp_seq_num;		/* TCP sequence number of the new packet */
	uint16 tcp_data_len;	/* TCP DATA length that excludes IP and TCP headers */
	uint32 end_tcp_seq_num;	/* TCP seq number of the last byte in the new packet */
	tcpack_sup_module_t *tcpack_sup_mod;
	tcpdata_info_t *tcpdata_info = NULL;
	tdata_psh_info_t *tdata_psh_info;

	int i;
	bool ret = FALSE;
	unsigned long flags;

	if (dhdp->tcpack_sup_mode != TCPACK_SUP_DELAYTX)
		goto exit;

	ether_hdr = PKTDATA(dhdp->osh, pkt);
	cur_framelen = PKTLEN(dhdp->osh, pkt);

	ether_type = ether_hdr[12] << 8 | ether_hdr[13];

	if (ether_type != ETHER_TYPE_IP) {
		DHD_TRACE(("%s %d: Not a IP packet 0x%x\n",
			__FUNCTION__, __LINE__, ether_type));
		goto exit;
	}

	DHD_TRACE(("%s %d: IP pkt! 0x%x\n", __FUNCTION__, __LINE__, ether_type));

	ip_hdr = ether_hdr + ETHER_HDR_LEN;
	cur_framelen -= ETHER_HDR_LEN;

	ASSERT(cur_framelen >= IPV4_MIN_HEADER_LEN);

	ip_hdr_len = IPV4_HLEN(ip_hdr);
	if (IP_VER(ip_hdr) != IP_VER_4 || IPV4_PROT(ip_hdr) != IP_PROT_TCP) {
		DHD_TRACE(("%s %d: Not IPv4 nor TCP! ip ver %d, prot %d\n",
			__FUNCTION__, __LINE__, IP_VER(ip_hdr), IPV4_PROT(ip_hdr)));
		goto exit;
	}

	tcp_hdr = ip_hdr + ip_hdr_len;
	cur_framelen -= ip_hdr_len;

	ASSERT(cur_framelen >= TCP_MIN_HEADER_LEN);

	DHD_TRACE(("%s %d: TCP pkt!\n", __FUNCTION__, __LINE__));

	ip_total_len = ntoh16_ua(&ip_hdr[IPV4_PKTLEN_OFFSET]);
	tcp_hdr_len = 4 * TCP_HDRLEN(tcp_hdr[TCP_HLEN_OFFSET]);

	/* This packet is mere TCP ACK, so do nothing */
	if (ip_total_len == ip_hdr_len + tcp_hdr_len) {
		DHD_TRACE(("%s %d: Do nothing for no data TCP ACK\n", __FUNCTION__, __LINE__));
		goto exit;
	}

	ASSERT(ip_total_len > ip_hdr_len + tcp_hdr_len);

	if ((tcp_hdr[TCP_FLAGS_OFFSET] & TCP_FLAG_PSH) == 0) {
		DHD_TRACE(("%s %d: Not interested TCP DATA packet\n", __FUNCTION__, __LINE__));
		goto exit;
	}

	DHD_TRACE(("%s %d: TCP DATA with nonzero DATA length"
		" IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR" TCP port %d %d, flag 0x%x\n",
		__FUNCTION__, __LINE__,
		IPV4_ADDR_TO_STR(ntoh32_ua(&ip_hdr[IPV4_SRC_IP_OFFSET])),
		IPV4_ADDR_TO_STR(ntoh32_ua(&ip_hdr[IPV4_DEST_IP_OFFSET])),
		ntoh16_ua(&tcp_hdr[TCP_SRC_PORT_OFFSET]),
		ntoh16_ua(&tcp_hdr[TCP_DEST_PORT_OFFSET]),
		tcp_hdr[TCP_FLAGS_OFFSET]));

	flags = dhd_os_tcpacklock(dhdp);
	tcpack_sup_mod = dhdp->tcpack_sup_module;

	if (!tcpack_sup_mod) {
		DHD_ERROR(("%s %d: tcpack suppress module NULL!!\n", __FUNCTION__, __LINE__));
		ret = BCME_ERROR;
		dhd_os_tcpackunlock(dhdp, flags);
		goto exit;
	}

	/* Look for tcpdata_info that has the same ip src/dst addrs and tcp src/dst ports */
	i = 0;
	while (i < tcpack_sup_mod->tcpdata_info_cnt) {
		tcpdata_info_t *tdata_info_tmp = &tcpack_sup_mod->tcpdata_info_tbl[i];
		uint32 now_in_ms = OSL_SYSUPTIME();
		DHD_TRACE(("%s %d: data info[%d], IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR
			" TCP port %d %d\n", __FUNCTION__, __LINE__, i,
			IPV4_ADDR_TO_STR(ntoh32_ua(tdata_info_tmp->src_ip_addr)),
			IPV4_ADDR_TO_STR(ntoh32_ua(tdata_info_tmp->dst_ip_addr)),
			ntoh16_ua(tdata_info_tmp->src_tcp_port),
			ntoh16_ua(tdata_info_tmp->dst_tcp_port)));

		/* If both IP address and TCP port number match, we found it so break. */
		if (memcmp(&ip_hdr[IPV4_SRC_IP_OFFSET],	tdata_info_tmp->src_ip_addr,
				IPV4_ADDR_LEN) == 0 &&
				memcmp(&ip_hdr[IPV4_DEST_IP_OFFSET], tdata_info_tmp->dst_ip_addr,
				IPV4_ADDR_LEN) == 0 &&
				memcmp(&tcp_hdr[TCP_SRC_PORT_OFFSET], tdata_info_tmp->src_tcp_port,
				TCP_PORT_LEN) == 0 &&
				memcmp(&tcp_hdr[TCP_DEST_PORT_OFFSET], tdata_info_tmp->dst_tcp_port,
				TCP_PORT_LEN) == 0) {
			tcpdata_info = tdata_info_tmp;
			tcpdata_info->last_used_time = now_in_ms;
			break;
		}

		if (now_in_ms - tdata_info_tmp->last_used_time > TCPDATA_INFO_TIMEOUT) {
			tdata_psh_info_t *tdata_psh_info_tmp;
			tcpdata_info_t *last_tdata_info;

			while ((tdata_psh_info_tmp = tdata_info_tmp->tdata_psh_info_head)) {
				tdata_info_tmp->tdata_psh_info_head = tdata_psh_info_tmp->next;
				tdata_psh_info_tmp->next = NULL;
				DHD_TRACE(("%s %d: Clean tdata_psh_info(end_seq %u)!\n",
					__FUNCTION__, __LINE__, tdata_psh_info_tmp->end_seq));
				_tdata_psh_info_pool_enq(tcpack_sup_mod, tdata_psh_info_tmp);
			}
#ifdef DHDTCPACK_SUP_DBG
			DHD_ERROR(("%s %d: PSH INFO ENQ %d\n",
				__FUNCTION__, __LINE__, tcpack_sup_mod->psh_info_enq_num));
#endif /* DHDTCPACK_SUP_DBG */
			tcpack_sup_mod->tcpdata_info_cnt--;
			ASSERT(tcpack_sup_mod->tcpdata_info_cnt >= 0);

			last_tdata_info =
				&tcpack_sup_mod->tcpdata_info_tbl[tcpack_sup_mod->tcpdata_info_cnt];
			if (i < tcpack_sup_mod->tcpdata_info_cnt) {
				ASSERT(last_tdata_info != tdata_info_tmp);
				bcopy(last_tdata_info, tdata_info_tmp, sizeof(tcpdata_info_t));
			}
			bzero(last_tdata_info, sizeof(tcpdata_info_t));
			DHD_INFO(("%s %d: tcpdata_info(idx %d) is aged out. ttl cnt is now %d\n",
				__FUNCTION__, __LINE__, i, tcpack_sup_mod->tcpdata_info_cnt));
			/* Don't increase "i" here, so that the prev last tcpdata_info is checked */
		} else
			 i++;
	}

	tcp_seq_num = ntoh32_ua(&tcp_hdr[TCP_SEQ_NUM_OFFSET]);
	tcp_data_len = ip_total_len - ip_hdr_len - tcp_hdr_len;
	end_tcp_seq_num = tcp_seq_num + tcp_data_len;

	if (tcpdata_info == NULL) {
		ASSERT(i == tcpack_sup_mod->tcpdata_info_cnt);
		if (i >= TCPDATA_INFO_MAXNUM) {
			DHD_TRACE(("%s %d: tcp_data_info_tbl FULL! %d %d"
				" IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR" TCP port %d %d\n",
				__FUNCTION__, __LINE__, i, tcpack_sup_mod->tcpdata_info_cnt,
				IPV4_ADDR_TO_STR(ntoh32_ua(&ip_hdr[IPV4_SRC_IP_OFFSET])),
				IPV4_ADDR_TO_STR(ntoh32_ua(&ip_hdr[IPV4_DEST_IP_OFFSET])),
				ntoh16_ua(&tcp_hdr[TCP_SRC_PORT_OFFSET]),
				ntoh16_ua(&tcp_hdr[TCP_DEST_PORT_OFFSET])));
			dhd_os_tcpackunlock(dhdp, flags);
			goto exit;
		}
		tcpdata_info = &tcpack_sup_mod->tcpdata_info_tbl[i];

		/* No TCP flow with the same IP addr and TCP port is found
		 * in tcp_data_info_tbl. So add this flow to the table.
		 */
		DHD_INFO(("%s %d: Add data info to tbl[%d]: IP addr "IPV4_ADDR_STR" "IPV4_ADDR_STR
			" TCP port %d %d\n",
			__FUNCTION__, __LINE__, tcpack_sup_mod->tcpdata_info_cnt,
			IPV4_ADDR_TO_STR(ntoh32_ua(&ip_hdr[IPV4_SRC_IP_OFFSET])),
			IPV4_ADDR_TO_STR(ntoh32_ua(&ip_hdr[IPV4_DEST_IP_OFFSET])),
			ntoh16_ua(&tcp_hdr[TCP_SRC_PORT_OFFSET]),
			ntoh16_ua(&tcp_hdr[TCP_DEST_PORT_OFFSET])));

		bcopy(&ip_hdr[IPV4_SRC_IP_OFFSET], tcpdata_info->src_ip_addr,
			IPV4_ADDR_LEN);
		bcopy(&ip_hdr[IPV4_DEST_IP_OFFSET], tcpdata_info->dst_ip_addr,
			IPV4_ADDR_LEN);
		bcopy(&tcp_hdr[TCP_SRC_PORT_OFFSET], tcpdata_info->src_tcp_port,
			TCP_PORT_LEN);
		bcopy(&tcp_hdr[TCP_DEST_PORT_OFFSET], tcpdata_info->dst_tcp_port,
			TCP_PORT_LEN);

		tcpdata_info->last_used_time = OSL_SYSUPTIME();
		tcpack_sup_mod->tcpdata_info_cnt++;
	}

	ASSERT(tcpdata_info != NULL);

	tdata_psh_info = _tdata_psh_info_pool_deq(tcpack_sup_mod);
#ifdef DHDTCPACK_SUP_DBG
	DHD_TRACE(("%s %d: PSH INFO ENQ %d\n",
		__FUNCTION__, __LINE__, tcpack_sup_mod->psh_info_enq_num));
#endif /* DHDTCPACK_SUP_DBG */

	if (tdata_psh_info == NULL) {
		DHD_ERROR(("%s %d: No more free tdata_psh_info!!\n", __FUNCTION__, __LINE__));
		ret = BCME_ERROR;
		dhd_os_tcpackunlock(dhdp, flags);
		goto exit;
	}
	tdata_psh_info->end_seq = end_tcp_seq_num;

#if defined(DEBUG_COUNTER) && defined(DHDTCPACK_SUP_DBG)
	tack_tbl.cnt[4]++;
#endif /* DEBUG_COUNTER && DHDTCPACK_SUP_DBG */

	DHD_TRACE(("%s %d: TCP PSH DATA recvd! end seq %u\n",
		__FUNCTION__, __LINE__, tdata_psh_info->end_seq));

	ASSERT(tdata_psh_info->next == NULL);

	if (tcpdata_info->tdata_psh_info_head == NULL)
		tcpdata_info->tdata_psh_info_head = tdata_psh_info;
	else {
		ASSERT(tcpdata_info->tdata_psh_info_tail);
		tcpdata_info->tdata_psh_info_tail->next = tdata_psh_info;
	}
	tcpdata_info->tdata_psh_info_tail = tdata_psh_info;

	dhd_os_tcpackunlock(dhdp, flags);

exit:
	return ret;
}
Esempio n. 28
0
/*
 *  SSIDs list parsing from cscan tlv list
 */
int
wl_iw_parse_ssid_list_tlv(char** list_str, wlc_ssid_t* ssid, int max, int *bytes_left)
{
	char* str =  *list_str;
	int idx = 0;

	if ((list_str == NULL) || (*list_str == NULL) || (*bytes_left < 0)) {
		DHD_ERROR(("%s error paramters\n", __FUNCTION__));
		return -1;
	}

	while (*bytes_left > 0) {

		if (str[0] != CSCAN_TLV_TYPE_SSID_IE) {
			*list_str = str;
			DHD_TRACE(("nssid=%d left_parse=%d %d\n", idx, *bytes_left, str[0]));
			return idx;
		}

		/* Get proper CSCAN_TLV_TYPE_SSID_IE */
		*bytes_left -= 1;
		str += 1;

		if (str[0] == 0) {
			/* Broadcast SSID */
			ssid[idx].SSID_len = 0;
			memset((char*)ssid[idx].SSID, 0x0, DOT11_MAX_SSID_LEN);
			*bytes_left -= 1;
			str += 1;

			DHD_TRACE(("BROADCAST SCAN  left=%d\n", *bytes_left));
		}
		else if (str[0] <= DOT11_MAX_SSID_LEN) {
			/* Get proper SSID size */
			ssid[idx].SSID_len = str[0];
			*bytes_left -= 1;
			str += 1;

			/* Get SSID */
			if (ssid[idx].SSID_len > *bytes_left) {
				DHD_ERROR(("%s out of memory range len=%d but left=%d\n",
				__FUNCTION__, ssid[idx].SSID_len, *bytes_left));
				return -1;
			}

			memcpy((char*)ssid[idx].SSID, str, ssid[idx].SSID_len);

			*bytes_left -= ssid[idx].SSID_len;
			str += ssid[idx].SSID_len;

			DHD_TRACE(("%s :size=%d left=%d\n",
				(char*)ssid[idx].SSID, ssid[idx].SSID_len, *bytes_left));
		}
		else {
			DHD_ERROR(("### SSID size more that %d\n", str[0]));
			return -1;
		}

		if (idx++ >  max) {
			DHD_ERROR(("%s number of SSIDs more that %d\n", __FUNCTION__, idx));
			return -1;
		}
	}

	*list_str = str;
	return idx;
}
static int dhd_wifi_platform_load_sdio(void)
{
	int i;
	int err = 0;
	wifi_adapter_info_t *adapter;

	BCM_REFERENCE(i);
	BCM_REFERENCE(adapter);
	/* Sanity check on the module parameters
	 * - Both watchdog and DPC as tasklets are ok
	 * - If both watchdog and DPC are threads, TX must be deferred
	 */
	if (!(dhd_watchdog_prio < 0 && dhd_dpc_prio < 0) &&
		!(dhd_watchdog_prio >= 0 && dhd_dpc_prio >= 0 && dhd_deferred_tx))
		return -EINVAL;

#if defined(BCMLXSDMMC)
	if (dhd_wifi_platdata == NULL) {
		DHD_ERROR(("DHD wifi platform data is required for Android build\n"));
		return -EINVAL;
	}

	sema_init(&dhd_registration_sem, 0);
	/* power up all adapters */
	for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) {
		bool chip_up = FALSE;
		int retry = POWERUP_MAX_RETRY;
		struct semaphore dhd_chipup_sem;

		adapter = &dhd_wifi_platdata->adapters[i];

		DHD_ERROR(("Power-up adapter '%s'\n", adapter->name));
		DHD_INFO((" - irq %d [flags %d], firmware: %s, nvram: %s\n",
			adapter->irq_num, adapter->intr_flags, adapter->fw_path, adapter->nv_path));
		DHD_INFO((" - bus type %d, bus num %d, slot num %d\n\n",
			adapter->bus_type, adapter->bus_num, adapter->slot_num));

		do {
			sema_init(&dhd_chipup_sem, 0);
			err = dhd_bus_reg_sdio_notify(&dhd_chipup_sem);
			if (err) {
				DHD_ERROR(("%s dhd_bus_reg_sdio_notify fail(%d)\n\n",
					__FUNCTION__, err));
				return err;
			}
			err = wifi_platform_set_power(adapter, TRUE, WIFI_TURNON_DELAY);
			if (err) {
				/* WL_REG_ON state unknown, Power off forcely */
				wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY);
				continue;
			} else {
				wifi_platform_bus_enumerate(adapter, TRUE);
				err = 0;
			}

			if (down_timeout(&dhd_chipup_sem, msecs_to_jiffies(POWERUP_WAIT_MS)) == 0) {
				dhd_bus_unreg_sdio_notify();
				chip_up = TRUE;
				break;
			}

			DHD_ERROR(("failed to power up %s, %d retry left\n", adapter->name, retry));
			dhd_bus_unreg_sdio_notify();
			wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY);
			wifi_platform_bus_enumerate(adapter, FALSE);
		} while (retry--);

		if (!chip_up) {
			DHD_ERROR(("failed to power up %s, max retry reached**\n", adapter->name));
			return -ENODEV;
		}

	}

	err = dhd_bus_register();

	if (err) {
		DHD_ERROR(("%s: sdio_register_driver failed\n", __FUNCTION__));
		goto fail;
	}


	/*
	 * Wait till MMC sdio_register_driver callback called and made driver attach.
	 * It's needed to make sync up exit from dhd insmod  and
	 * Kernel MMC sdio device callback registration
	 */
	err = down_timeout(&dhd_registration_sem, msecs_to_jiffies(DHD_REGISTRATION_TIMEOUT));
	if (err) {
		DHD_ERROR(("%s: sdio_register_driver timeout or error \n", __FUNCTION__));
		dhd_bus_unregister();
		goto fail;
	}

	return err;

fail:
	/* power down all adapters */
	for (i = 0; i < dhd_wifi_platdata->num_adapters; i++) {
		adapter = &dhd_wifi_platdata->adapters[i];
		wifi_platform_set_power(adapter, FALSE, WIFI_TURNOFF_DELAY);
		wifi_platform_bus_enumerate(adapter, FALSE);
	}
#else

	/* x86 bring-up PC needs no power-up operations */
	err = dhd_bus_register();

#endif 

	return err;
}
void sec_control_pm(dhd_pub_t *dhd, uint *power_mode)
{
	struct file *fp = NULL;
	char *filepath = PSMINFO;
	char power_val = 0;
	char iovbuf[WL_EVENTING_MASK_LEN + 12];
	int ret = 0;
#ifdef DHD_ENABLE_LPC
	uint32 lpc = 0;
#endif /* DHD_ENABLE_LPC */

	g_pm_control = FALSE;

	fp = filp_open(filepath, O_RDONLY, 0);
	if (IS_ERR(fp) || (fp == NULL)) {
		/* Enable PowerSave Mode */
		dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)power_mode,
			sizeof(uint), TRUE, 0);
		DHD_ERROR(("[WIFI_SEC] %s: /data/.psm.info doesn't exist"
			" so set PM to %d\n",
			__FUNCTION__, *power_mode));
		return;
	} else {
		kernel_read(fp, fp->f_pos, &power_val, 1);
		DHD_ERROR(("[WIFI_SEC] %s: POWER_VAL = %c \r\n", __FUNCTION__, power_val));

		if (power_val == '0') {
#ifdef ROAM_ENABLE
			uint roamvar = 1;
#endif
			uint32 ocl_enable = 0;
			uint32 wl_updown = 1;

			*power_mode = PM_OFF;
			/* Disable PowerSave Mode */
			dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)power_mode,
				sizeof(uint), TRUE, 0);
			/* Turn off MPC in AP mode */
			bcm_mkiovar("mpc", (char *)power_mode, 4,
				iovbuf, sizeof(iovbuf));
			dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
				sizeof(iovbuf), TRUE, 0);
			g_pm_control = TRUE;
#ifdef ROAM_ENABLE
			/* Roaming off of dongle */
			bcm_mkiovar("roam_off", (char *)&roamvar, 4,
				iovbuf, sizeof(iovbuf));
			dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
				sizeof(iovbuf), TRUE, 0);
#endif
#ifdef DHD_ENABLE_LPC
			/* Set lpc 0 */
			bcm_mkiovar("lpc", (char *)&lpc, 4, iovbuf, sizeof(iovbuf));
			if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
				sizeof(iovbuf), TRUE, 0)) < 0) {
				DHD_ERROR(("[WIFI_SEC] %s: Set lpc failed  %d\n",
				__FUNCTION__, ret));
			}
#endif /* DHD_ENABLE_LPC */
			/* Disable ocl */
			if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_UP, (char *)&wl_updown,
					sizeof(wl_updown), TRUE, 0)) < 0) {
				DHD_ERROR(("[WIFI_SEC] %s: WLC_UP faield %d\n", __FUNCTION__, ret));
			}

			bcm_mkiovar("ocl_enable", (char *)&ocl_enable, 4, iovbuf, sizeof(iovbuf));
			if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
					sizeof(iovbuf), TRUE, 0)) < 0) {
				DHD_ERROR(("[WIFI_SEC] %s: Set ocl_enable %d failed %d\n",
						__FUNCTION__, ocl_enable, ret));
			} else {
				DHD_ERROR(("[WIFI_SEC] %s: Set ocl_enable %d succeeded %d\n",
						__FUNCTION__, ocl_enable, ret));
			}

			if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_DOWN, (char *)&wl_updown,
					sizeof(wl_updown), TRUE, 0)) < 0) {
				DHD_ERROR(("[WIFI_SEC] %s: WLC_DOWN faield %d\n",
						__FUNCTION__, ret));
			}
		} else {
			dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)power_mode,
				sizeof(uint), TRUE, 0);
		}
	}

	if (fp)
		filp_close(fp, NULL);
}