16dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt/*
2ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt * Linux port of dhd command line utility, hacked from wl utility.
36dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt *
438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt * Copyright (C) 1999-2013, Broadcom Corporation
5ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt *
66dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * Permission to use, copy, modify, and/or distribute this software for any
76dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * purpose with or without fee is hereby granted, provided that the above
86dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * copyright notice and this permission notice appear in all copies.
96dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt *
106dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
116dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
126dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
136dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
146dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
156dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
166dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
176dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt *
1838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt * $Id: dhdu_linux.c 378962 2013-01-15 13:18:28Z $
196dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt */
206dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
216dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include <stdio.h>
226dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include <stdlib.h>
236dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include <unistd.h>
246dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include <ctype.h>
256dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include <string.h>
266dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include <errno.h>
276dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include <sys/types.h>
286dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include <sys/wait.h>
296dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include <sys/socket.h>
306dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include <proto/ethernet.h>
316dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include <proto/bcmip.h>
326dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include <arpa/inet.h>
336dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include <sys/ioctl.h>
346dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include <net/if.h>
356dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include <fcntl.h>
366dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include <sys/ioctl.h>
376dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include <unistd.h>
386dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
396dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#ifndef TARGETENV_android
406dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include <error.h>
416dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidttypedef u_int64_t u64;
426dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidttypedef u_int32_t u32;
436dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidttypedef u_int16_t u16;
446dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidttypedef u_int8_t u8;
456dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#endif /* TARGETENV_android */
466dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include <linux/sockios.h>
476dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include <linux/types.h>
486dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include <linux/ethtool.h>
496dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
506dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include <typedefs.h>
516dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include <signal.h>
526dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include <dhdioctl.h>
536dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include <wlioctl.h>
546dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include <bcmcdc.h>
556dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include <bcmutils.h>
56ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
57ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#if defined(RWL_WIFI) || defined(RWL_SOCKET) ||defined(RWL_SERIAL)
58ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#define RWL_ENABLE
59ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#endif
60ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
616dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include "dhdu.h"
62ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#ifdef RWL_ENABLE
63ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#include "wlu_remote.h"
64ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#include "wlu_client_shared.h"
65ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#include "wlu_pipe.h"
66ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#endif /* RWL_ENABLE */
676dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include <netdb.h>
68ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#include <netinet/in.h>
696dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include <dhdioctl.h>
706dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#include "dhdu_common.h"
7138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt#include "dhdu_nl80211.h"
726dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
736dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtchar *av0;
74ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtstatic int rwl_os_type = LINUX_OS;
756dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt/* Search the dhd_cmds table for a matching command name.
766dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * Return the matching command or NULL if no match found.
776dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt */
786dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtstatic cmd_t *
796dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtdhd_find_cmd(char* name)
806dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt{
816dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	cmd_t *cmd = NULL;
826dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	/* search the dhd_cmds for a matching name */
836dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	for (cmd = dhd_cmds; cmd->name && strcmp(cmd->name, name); cmd++);
846dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	if (cmd->name == NULL)
856dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		cmd = NULL;
866dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	return cmd;
876dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt}
886dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
896dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtstatic void
9038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtsyserr(const char *s)
916dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt{
9238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	fprintf(stderr, "%s: ", av0);
936dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	perror(s);
946dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	exit(errno);
956dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt}
966dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
9738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt#ifdef NL80211
9838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtstatic int __dhd_driver_io(void *dhd, dhd_ioctl_t *ioc)
9938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt{
10038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	struct dhd_netlink_info dhd_nli;
10138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	struct ifreq *ifr = (struct ifreq *)dhd;
10238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	int ret = 0;
10338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
10438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	dhd_nli.ifidx = if_nametoindex(ifr->ifr_name);
10538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if (!dhd_nli.ifidx) {
10638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		fprintf(stderr, "invalid device %s\n", ifr->ifr_name);
10738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return BCME_IOCTL_ERROR;
10838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	}
10938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
11038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if (dhd_nl_sock_connect(&dhd_nli) < 0)
11138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		syserr("socket");
11238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
11338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	ret = dhd_nl_do_testmode(&dhd_nli, ioc);
11438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	dhd_nl_sock_disconnect(&dhd_nli);
11538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	return ret;
11638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt}
11738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt#else
11838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidtstatic int __dhd_driver_io(void *dhd, dhd_ioctl_t *ioc)
11938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt{
12038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	struct ifreq *ifr = (struct ifreq *)dhd;
12138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	int s;
12238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	int ret = 0;
12338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
12438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	/* pass ioctl data */
12538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	ifr->ifr_data = (caddr_t)ioc;
12638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
12738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	/* open socket to kernel */
12838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
12938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		syserr("socket");
13038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
13138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	ret = ioctl(s, SIOCDEVPRIVATE, ifr);
13238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if (ret < 0 && errno != EAGAIN)
13338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		syserr(__FUNCTION__);
13438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
13538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	/* cleanup */
13638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	close(s);
13738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	return ret;
13838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt}
13938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt#endif /* NL80211 */
14038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
141ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt/* This function is called by ioctl_setinformation_fe or ioctl_queryinformation_fe
1426dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * for executing  remote commands or local commands
1436dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt */
1446dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtstatic int
1456dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtdhd_ioctl(void *dhd, int cmd, void *buf, int len, bool set)
1466dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt{
1476dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	dhd_ioctl_t ioc;
1486dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	int ret = 0;
14938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
1506dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	/* By default try to execute wl commands */
151ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	int driver_magic = WLC_IOCTL_MAGIC;
152ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	int get_magic = WLC_GET_MAGIC;
153ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
154ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	/* For local dhd commands execute dhd. For wifi transport we still
155ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	 * execute wl commands.
156ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	 */
157ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if (remote_type == NO_REMOTE && strncmp (buf, RWL_WIFI_ACTION_CMD,
158ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		strlen(RWL_WIFI_ACTION_CMD)) && strncmp(buf, RWL_WIFI_GET_ACTION_CMD,
159ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		strlen(RWL_WIFI_GET_ACTION_CMD))) {
160ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		driver_magic = DHD_IOCTL_MAGIC;
161ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		get_magic = DHD_GET_MAGIC;
162ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	}
1636dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
1646dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	/* do it */
1656dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	ioc.cmd = cmd;
1666dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	ioc.buf = buf;
1676dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	ioc.len = len;
1686dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	ioc.set = set;
1696dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	ioc.driver = driver_magic;
1706dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
17138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	ret = __dhd_driver_io(dhd, &ioc);
17238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if (ret < 0 && cmd != get_magic)
17338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		ret = BCME_IOCTL_ERROR;
1746dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	return ret;
1756dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt}
1766dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
1776dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt/* This function is called in wlu_pipe.c remote_wifi_ser_init() to execute
1786dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * the initial set of wl commands for wifi transport (e.g slow_timer, fast_timer etc)
1796dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt */
1806dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtint wl_ioctl(void *wl, int cmd, void *buf, int len, bool set)
1816dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt{
1826dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	return dhd_ioctl(wl, cmd, buf, len, set); /* Call actual wl_ioctl here: Shubhro */
1836dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt}
1846dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
1856dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt/* Search if dhd adapter or wl adapter is present
1866dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * This is called by dhd_find to check if it supports wl or dhd
1876dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * The reason for checking wl adapter is that we can still send remote dhd commands over
1886dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * wifi transport.
1896dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt */
1906dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtstatic int
1916dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtdhd_get_dev_type(char *name, void *buf, char *type)
1926dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt{
1936dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	int s;
1946dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	int ret;
1956dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	struct ifreq ifr;
1966dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	struct ethtool_drvinfo info;
1976dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
1986dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	/* open socket to kernel */
1996dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
2006dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		syserr("socket");
2016dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
2026dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	/* get device type */
2036dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	memset(&info, 0, sizeof(info));
2046dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	info.cmd = ETHTOOL_GDRVINFO;
2056dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	strcpy(info.driver, "?");
2066dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	strcat(info.driver, type);
2076dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	ifr.ifr_data = (caddr_t)&info;
2086dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	strncpy(ifr.ifr_name, name, IFNAMSIZ);
2096dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	if ((ret = ioctl(s, SIOCETHTOOL, &ifr)) < 0) {
2106dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
21138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		if (errno != EAGAIN)
21238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			syserr(__FUNCTION__);
2136dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
2146dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		*(char *)buf = '\0';
2156dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	}
2166dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	else
2176dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		strcpy(buf, info.driver);
2186dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
2196dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	close(s);
2206dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	return ret;
2216dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt}
2226dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
2236dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt/* dhd_get/dhd_set is called by several functions in dhdu.c. This used to call dhd_ioctl
2246dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * directly. However now we need to execute the dhd commands remotely.
2256dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * So we make use of wl pipes to execute this.
2266dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * wl_get or wl_set functions also check if it is a local command hence they in turn
2276dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * call dhd_ioctl if required. Name wl_get/wl_set is retained because these functions are
2286dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * also called by wlu_pipe.c wlu_client_shared.c
2296dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt */
2306dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtint
2316dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtdhd_get(void *dhd, int cmd, void *buf, int len)
2326dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt{
2336dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	return wl_get(dhd, cmd, buf, len);
2346dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt}
2356dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
2366dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt/*
2376dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * To use /dev/node interface:
2386dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt *   1.  mknod /dev/hnd0 c 248 0
2396dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt *   2.  chmod 777 /dev/hnd0
2406dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt */
2416dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt#define NODE "/dev/hnd0"
2426dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
2436dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtint
2446dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtdhd_set(void *dhd, int cmd, void *buf, int len)
2456dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt{
2466dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	static int dnode = -1;
2476dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
2486dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	switch (cmd) {
2496dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	case DHD_DLDN_ST:
2506dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		if (dnode == -1)
2516dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt			dnode = open(NODE, O_RDWR);
2526dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		else
2536dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt			fprintf(stderr, "devnode already opened!\n");
2546dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
2556dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		return dnode;
2566dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		break;
2576dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	case DHD_DLDN_WRITE:
2586dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		if (dnode > 0)
2596dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt			return write(dnode, buf, len);
2606dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		break;
2616dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	case DHD_DLDN_END:
2626dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		if (dnode > 0)
2636dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt			return close(dnode);
2646dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		break;
2656dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	default:
2666dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		return wl_set(dhd, cmd, buf, len);
2676dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
2686dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	}
2696dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
2706dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	return -1;
2716dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt}
2726dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
2736dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt/* Verify the wl adapter found.
2746dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * This is called by dhd_find to check if it supports wl
2756dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * The reason for checking wl adapter is that we can still send remote dhd commands over
2766dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * wifi transport. The function is copied from wlu.c.
2776dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt */
2786dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtint
2796dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtwl_check(void *wl)
2806dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt{
2816dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	int ret;
2826dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	int val = 0;
2836dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
2846dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	if (!dhd_check (wl))
2856dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		return 0;
2866dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
2876dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	/*
2886dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	 *  If dhd_check() fails then go for a regular wl driver verification
2896dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	 */
2906dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	if ((ret = wl_get(wl, WLC_GET_MAGIC, &val, sizeof(int))) < 0)
2916dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		return ret;
2926dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	if (val != WLC_IOCTL_MAGIC)
2936dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		return BCME_ERROR;
2946dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	if ((ret = wl_get(wl, WLC_GET_VERSION, &val, sizeof(int))) < 0)
2956dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		return ret;
2966dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	if (val > WLC_IOCTL_VERSION) {
2976dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		fprintf(stderr, "Version mismatch, please upgrade\n");
2986dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		return BCME_ERROR;
2996dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	}
3006dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	return 0;
3016dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt}
3026dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt/* Search and verify the request type of adapter (wl or dhd)
3036dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * This is called by main before executing local dhd commands
3046dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * or sending remote dhd commands over wifi transport
3056dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt */
3066dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtvoid
3076dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtdhd_find(struct ifreq *ifr, char *type)
3086dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt{
3096dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	char proc_net_dev[] = "/proc/net/dev";
3106dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	FILE *fp;
3116dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	static char buf[400];
3126dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	char *c, *name;
3136dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	char dev_type[32];
3146dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
3156dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	ifr->ifr_name[0] = '\0';
3166dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	/* eat first two lines */
3176dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	if (!(fp = fopen(proc_net_dev, "r")) ||
3186dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	    !fgets(buf, sizeof(buf), fp) ||
3196dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	    !fgets(buf, sizeof(buf), fp))
3206dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		return;
3216dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
3226dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	while (fgets(buf, sizeof(buf), fp)) {
3236dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		c = buf;
3246dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		while (isspace(*c))
3256dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt			c++;
3266dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		if (!(name = strsep(&c, ":")))
3276dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt			continue;
3286dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		strncpy(ifr->ifr_name, name, IFNAMSIZ);
3296dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		if (dhd_get_dev_type(name, dev_type, type) >= 0 &&
3306dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt			!strncmp(dev_type, type, strlen(dev_type) - 1))
3316dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		{
3326dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt			if (!wl_check((void*)ifr))
3336dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt				break;
3346dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		}
3356dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		ifr->ifr_name[0] = '\0';
3366dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	}
3376dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
3386dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	fclose(fp);
3396dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt}
3406dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt/* This function is called by wl_get to execute either local dhd command
3416dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * or send a dhd command over wl transport
3426dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt */
3436dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtstatic int
3446dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtioctl_queryinformation_fe(void *wl, int cmd, void* input_buf, int *input_len)
3456dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt{
346ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if (remote_type == NO_REMOTE) {
347ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		return dhd_ioctl(wl, cmd, input_buf, *input_len, FALSE);
348ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	}
349ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#ifdef RWL_ENABLE
350ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	else {
351ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		return rwl_queryinformation_fe(wl, cmd, input_buf,
352ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			(unsigned long*)input_len, 0, RDHD_GET_IOCTL);
353ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	}
354ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#else /* RWL_ENABLE */
35538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	return BCME_IOCTL_ERROR;
356ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#endif /* RWL_ENABLE */
3576dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt}
3586dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
3596dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt/* This function is called by wl_set to execute either local dhd command
3606dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * or send a dhd command over wl transport
3616dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt */
3626dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtstatic int
3636dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtioctl_setinformation_fe(void *wl, int cmd, void* buf, int *len)
3646dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt{
365ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if (remote_type == NO_REMOTE) {
366ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		return dhd_ioctl(wl,  cmd, buf, *len, TRUE);
367ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	}
368ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#ifdef RWL_ENABLE
369ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	else {
370ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		return rwl_setinformation_fe(wl, cmd, buf, (unsigned long*)len, 0, RDHD_SET_IOCTL);
371ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
372ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	}
373ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#else /* RWL_ENABLE */
37438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	return BCME_IOCTL_ERROR;
375ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#endif /* RWL_ENABLE */
3766dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt}
3776dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
378ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt/* The function is replica of wl_get in wlu_linux.c. Optimize when we have some
3796dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * common code between wlu_linux.c and dhdu_linux.c
3806dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt */
3816dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtint
3826dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtwl_get(void *wl, int cmd, void *buf, int len)
3836dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt{
3846dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	int error = BCME_OK;
385ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	/* For RWL: When interfacing to a Windows client, need t add in OID_BASE */
386ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if ((rwl_os_type == WIN32_OS) && (remote_type != NO_REMOTE)) {
387ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		error = (int)ioctl_queryinformation_fe(wl, WL_OID_BASE + cmd, buf, &len);
388ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	} else {
389ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		error = (int)ioctl_queryinformation_fe(wl, cmd, buf, &len);
390ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	}
39138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if (error == BCME_SERIAL_PORT_ERR)
39238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return BCME_SERIAL_PORT_ERR;
3936dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
3946dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	if (error != 0)
39538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return BCME_IOCTL_ERROR;
3966dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
3976dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	return error;
3986dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt}
3996dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
400ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt/* The function is replica of wl_set in wlu_linux.c. Optimize when we have some
4016dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * common code between wlu_linux.c and dhdu_linux.c
4026dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt */
4036dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtint
4046dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtwl_set(void *wl, int cmd, void *buf, int len)
4056dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt{
4066dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	int error = BCME_OK;
4076dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
408ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	/* For RWL: When interfacing to a Windows client, need t add in OID_BASE */
409ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if ((rwl_os_type == WIN32_OS) && (remote_type != NO_REMOTE)) {
410ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		error = (int)ioctl_setinformation_fe(wl, WL_OID_BASE + cmd, buf, &len);
411ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	} else {
412ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		error = (int)ioctl_setinformation_fe(wl, cmd, buf, &len);
413ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	}
414ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
41538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	if (error == BCME_SERIAL_PORT_ERR)
41638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return BCME_SERIAL_PORT_ERR;
4176dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
4186dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	if (error != 0) {
41938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		return BCME_IOCTL_ERROR;
4206dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	}
4216dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	return error;
4226dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt}
423ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
424ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtint
425ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtwl_validatedev(void *dev_handle)
426ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt{
427ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	int retval = 1;
428ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	struct ifreq *ifr = (struct ifreq *)dev_handle;
429ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	/* validate the interface */
430ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if (!ifr->ifr_name || wl_check((void *)ifr)) {
431ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		retval = 0;
432ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	}
433ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	return retval;
434ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt}
435ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
4366dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt/* Main client function
4376dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * The code is mostly from wlu_linux.c. This function takes care of executing remote dhd commands
4386dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * along with the local dhd commands now.
4396dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt */
4406dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtint
4416dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtmain(int argc, char **argv)
4426dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt{
4436dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	struct ifreq ifr;
4446dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	char *ifname = NULL;
4456dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	int err = 0;
4466dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	int help = 0;
4476dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	int status = CMD_DHD;
448ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#ifdef RWL_SOCKET
449ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	struct ipv4_addr temp;
450ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#endif /* RWL_SOCKET */
451ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
4526dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	UNUSED_PARAMETER(argc);
4536dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
454ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	av0 = argv[0];
4556dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	memset(&ifr, 0, sizeof(ifr));
4566dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	argv++;
4576dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
4586dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	if ((status = dhd_option(&argv, &ifname, &help)) == CMD_OPT) {
4596dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		if (ifname)
4606dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt			strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
4616dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	}
462ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	/* Linux client looking for a Win32 server */
463ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if (*argv && strncmp (*argv, "--wince", strlen(*argv)) == 0) {
464ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		rwl_os_type = WIN32_OS;
465ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		argv++;
466ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	}
467ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
468ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	/* RWL socket transport Usage: --socket ipaddr [port num] */
469ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if (*argv && strncmp (*argv, "--socket", strlen(*argv)) == 0) {
470ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		argv++;
471ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
472ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		remote_type = REMOTE_SOCKET;
473ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#ifdef RWL_SOCKET
474ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		if (!(*argv)) {
475ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			rwl_usage(remote_type);
476ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			return err;
477ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		}
478ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
479ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		if (!dhd_atoip(*argv, &temp)) {
480ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			rwl_usage(remote_type);
481ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			return err;
482ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		}
483ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		g_rwl_servIP = *argv;
484ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		argv++;
485ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
486ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		g_rwl_servport = DEFAULT_SERVER_PORT;
487ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		if ((*argv) && isdigit(**argv)) {
488ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			g_rwl_servport = atoi(*argv);
489ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			argv++;
490ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		}
491ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#endif /* RWL_SOCKET */
492ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	}
493ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
494ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	/* RWL from system serial port on client to uart dongle port on server */
495ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	/* Usage: --dongle /dev/ttyS0 */
496ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if (*argv && strncmp (*argv, "--dongle", strlen(*argv)) == 0) {
497ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		argv++;
498ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		remote_type = REMOTE_DONGLE;
499ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	}
5006dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
501ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	/* RWL over wifi.  Usage: --wifi mac_address */
502ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if (*argv && strncmp (*argv, "--wifi", strlen(*argv)) == 0) {
503ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		argv++;
504ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#ifdef RWL_WIFI
505ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		remote_type = NO_REMOTE;
506ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		if (!ifr.ifr_name[0])
507ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		{
508ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			dhd_find(&ifr, "wl");
509ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		}
510ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		/* validate the interface */
511ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		if (!ifr.ifr_name[0] || wl_check((void*)&ifr)) {
512ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			fprintf(stderr, "%s: wl driver adapter not found\n", av0);
513ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			exit(1);
514ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		}
515ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		remote_type = REMOTE_WIFI;
516ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
517ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		if (argc < 4) {
518ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			rwl_usage(remote_type);
519ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			return err;
520ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		}
521ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		/* copy server mac address to local buffer for later use by findserver cmd */
522ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		if (!dhd_ether_atoe(*argv, (struct ether_addr *)g_rwl_buf_mac)) {
523ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			fprintf(stderr,
524ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			        "could not parse as an ethernet MAC address\n");
525ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			return FAIL;
526ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		}
527ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		argv++;
528ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#else /* RWL_WIFI */
529ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		remote_type = REMOTE_WIFI;
530ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#endif /* RWL_WIFI */
531ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	}
532ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
533ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	/* Process for local dhd */
534ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if (remote_type == NO_REMOTE) {
535ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		err = process_args(&ifr, argv);
536ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		return err;
537ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	}
538ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
539ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#ifdef RWL_ENABLE
540ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if (*argv) {
541ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		err = process_args(&ifr, argv);
54238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt		if ((err == BCME_SERIAL_PORT_ERR) && (remote_type == REMOTE_DONGLE)) {
543ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			DPRINT_ERR(ERR, "\n Retry again\n");
544ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			err = process_args((struct ifreq*)&ifr, argv);
545ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		}
546ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		return err;
547ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	}
548ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	rwl_usage(remote_type);
549ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#endif /* RWL_ENABLE */
5506dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
5516dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	return err;
5526dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt}
5536dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt/*
5546dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * Function called for  'local' execution and for 'remote' non-interactive session
5556dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * (shell cmd, wl cmd) .The code is mostly from wlu_linux.c. This code can be
5566dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt * common to wlu_linux.c and dhdu_linux.c
5576dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt */
5586dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtstatic int
5596dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtprocess_args(struct ifreq* ifr, char **argv)
5606dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt{
5616dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	char *ifname = NULL;
5626dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	int help = 0;
5636dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	int status = 0;
5646dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	int err = BCME_OK;
5656dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	cmd_t *cmd = NULL;
5666dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	while (*argv) {
567ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#ifdef RWL_ENABLE
568ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		if ((strcmp (*argv, "sh") == 0) && (remote_type != NO_REMOTE)) {
569ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			argv++; /* Get the shell command */
570ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			if (*argv) {
571ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt				/* Register handler in case of shell command only */
572ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt				signal(SIGINT, ctrlc_handler);
573ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt				err = rwl_shell_cmd_proc((void*)ifr, argv, SHELL_CMD);
574ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			} else {
575ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt				DPRINT_ERR(ERR,
576ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt				"Enter the shell command (e.g ls(Linux) or dir(Win CE) \n");
577ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt				err = BCME_ERROR;
578ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			}
579ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			return err;
580ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		}
581ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#endif /* RWL_ENABLE */
5826dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		if ((status = dhd_option(&argv, &ifname, &help)) == CMD_OPT) {
5836dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt			if (help)
5846dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt				break;
5856dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt			if (ifname)
5866dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt				strncpy(ifr->ifr_name, ifname, IFNAMSIZ);
5876dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt			continue;
5886dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		}
5896dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		/* parse error */
5906dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		else if (status == CMD_ERR)
5916dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		    break;
5926dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
593ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		if (remote_type == NO_REMOTE) {
59438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			int ret;
59538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt
59638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			/* use default interface */
597ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			if (!ifr->ifr_name[0])
598ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt				dhd_find(ifr, "dhd");
599ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			/* validate the interface */
60038eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			if (!ifr->ifr_name[0]) {
60138eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt				if (strcmp("dldn", *argv) != 0) {
60238eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt					exit(ENXIO);
60338eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt					syserr("interface");
60438eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt				}
60538eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			}
60638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt			if ((ret = dhd_check((void *)ifr)) != 0) {
60738eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt				if (strcmp("dldn", *argv) != 0) {
60838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt					errno = -ret;
60938eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt					syserr("dhd_check");
610ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt				}
6116dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt			}
612ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		}
6136dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		/* search for command */
6146dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		cmd = dhd_find_cmd(*argv);
6156dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		/* if not found, use default set_var and get_var commands */
6166dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		if (!cmd) {
6176dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt			cmd = &dhd_varcmd;
6186dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		}
6196dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
6206dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		/* do command */
6216dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		err = (*cmd->func)((void *) ifr, cmd, argv);
6226dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		break;
6236dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	} /* while loop end */
6246dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
6256dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	/* provide for help on a particular command */
6266dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	if (help && *argv) {
6276dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		cmd = dhd_find_cmd(*argv);
6286dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		if (cmd) {
6296dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt			dhd_cmd_usage(cmd);
6306dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		} else {
631ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			DPRINT_ERR(ERR, "%s: Unrecognized command \"%s\", type -h for help\n",
6326dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt			           av0, *argv);
6336dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		}
6346dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	} else if (!cmd)
6356dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		dhd_usage(NULL);
63638eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	else if (err == BCME_USAGE_ERROR)
6376dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		dhd_cmd_usage(cmd);
63838eaaf5a34502fe465cf8b6ac7a2dfcafa17ba41Dmitry Shmidt	else if (err == BCME_IOCTL_ERROR)
6396dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt		dhd_printlasterror((void *) ifr);
6406dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
6416dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	return err;
6426dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt}
6436dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
6446dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtint
6456dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtrwl_shell_createproc(void *wl)
6466dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt{
6476dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	UNUSED_PARAMETER(wl);
6486dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	return fork();
6496dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt}
6506dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
6516dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtvoid
6526dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidtrwl_shell_killproc(int pid)
6536dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt{
6546dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt	kill(pid, SIGKILL);
6556dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt}
6566dbcf2181152a81ab5f3bc5fa765288341a1b7abDmitry Shmidt
657ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#ifdef RWL_SOCKET
658ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt/* validate hostname/ip given by the client */
659ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtint
660ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidtvalidate_server_address()
661ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt{
662ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	struct hostent *he;
663ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	struct ipv4_addr temp;
664ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt
665ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	if (!dhd_atoip(g_rwl_servIP, &temp)) {
666ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	/* Wrong IP address format check for hostname */
667ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		if ((he = gethostbyname(g_rwl_servIP)) != NULL) {
668ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			if (!dhd_atoip(*he->h_addr_list, &temp)) {
669ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt				g_rwl_servIP = inet_ntoa(*(struct in_addr *)*he->h_addr_list);
670ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt				if (g_rwl_servIP == NULL) {
671ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt					DPRINT_ERR(ERR, "Error at inet_ntoa \n");
672ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt					return FAIL;
673ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt				}
674ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			} else {
675ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt				DPRINT_ERR(ERR, "Error in IP address \n");
676ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt				return FAIL;
677ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			}
678ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		} else {
679ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			DPRINT_ERR(ERR, "Enter correct IP address/hostname format\n");
680ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt			return FAIL;
681ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt		}
682ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	}
683ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt	return SUCCESS;
684ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt}
685ac2bc7e7aaad957f235992ff74d5f9af34dc5f88Dmitry Shmidt#endif /* RWL_SOCKET */
686