1/*
2 * Wireless network adapter utilities (ecos-specific)
3 *
4 * Copyright (C) 2010, Broadcom Corporation. All Rights Reserved.
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * $Id: wl_ecos.c,v 1.1 2010/09/15 10:47:27 Exp $
19 */
20
21#include <stdio.h>
22#include <stdlib.h>
23#include <unistd.h>
24#include <ctype.h>
25#include <string.h>
26
27#include <typedefs.h>
28#include <wlioctl.h>
29
30#include <sys/param.h>
31#include <sys/socket.h>
32#include <sys/ioctl.h>
33#include <netinet/in.h>
34#include <net/if.h>
35
36typedef u_int64_t u64;
37typedef u_int32_t u32;
38typedef u_int16_t u16;
39typedef u_int8_t u8;
40#include <ethtool.h>
41
42
43int
44wl_ioctl(char *name, int cmd, void *buf, int len)
45{
46	struct ifreq ifr;
47	wl_ioctl_t ioc;
48	int ret = 0;
49	int s;
50
51	memset(&ifr, 0, sizeof(ifr));
52	strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
53
54	/* open socket to kernel */
55	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
56		ret = -1;
57	}
58
59	/* do it */
60	memset(&ioc, 0, sizeof(ioc));
61	ioc.cmd = cmd;
62	ioc.buf = buf;
63	ioc.len = len;
64
65	memset(&ifr, 0, sizeof(ifr));
66	strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
67	ifr.ifr_data = (caddr_t) &ioc;
68	if ((ret = ioctl(s, SIOCDEVPRIVATE, &ifr)) < 0) {
69		if (cmd != WLC_GET_MAGIC) {
70			ret = -2;
71		}
72	}
73
74	/* cleanup */
75	close(s);
76
77	return ret;
78}
79
80int
81wl_get(void *wl, int cmd, void *buf, int len)
82{
83	return wl_ioctl(wl, cmd, buf, len);
84}
85
86int
87wl_set(void *wl, int cmd, void *buf, int len)
88{
89	return wl_ioctl(wl, cmd, buf, len);
90}
91
92int
93wl_get_dev_type(char *name, void *buf, int len)
94{
95	int s;
96	int ret;
97	struct ifreq ifr;
98	struct ethtool_drvinfo info;
99
100	/* open socket to kernel */
101	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
102		return -1;
103	}
104
105	/* get device type */
106	memset(&info, 0, sizeof(info));
107	info.cmd = ETHTOOL_GDRVINFO;
108	ifr.ifr_data = (caddr_t)&info;
109	strncpy(ifr.ifr_name, name, IFNAMSIZ);
110	if ((ret = ioctl(s, SIOCETHTOOL, &ifr)) < 0) {
111		*(char *)buf = '\0';
112	} else
113		strncpy(buf, info.driver, len);
114
115	close(s);
116
117	return ret;
118}
119
120int
121wl_hwaddr(char *name, unsigned char *hwaddr)
122{
123	struct ifreq ifr;
124	int ret = 0;
125	int s;
126
127	/* open socket to kernel */
128	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
129		return -1;
130	}
131
132	/* do it */
133	memset(&ifr, 0, sizeof(ifr));
134	strncpy(ifr.ifr_name, name, IFNAMSIZ);
135	if ((ret = ioctl(s, SIOCGIFHWADDR, &ifr)) == 0)
136		memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);
137
138	/* cleanup */
139	close(s);
140
141	return ret;
142}
143
144/**
145 * strnicmp - Case insensitive, length-limited string comparison
146 * @s1: One string
147 * @s2: The other string
148 * @len: the maximum number of characters to compare
149 */
150int strnicmp(const char *s1, const char *s2, size_t len)
151{
152	/* Yes, Virginia, it had better be unsigned */
153	unsigned char c1, c2;
154
155	c1 = 0;	c2 = 0;
156	if (len)
157	{
158		do
159		{
160			c1 = *s1; c2 = *s2;
161			s1++; s2++;
162			if (!c1)
163				break;
164			if (!c2)
165				break;
166			if (c1 == c2)
167				continue;
168			c1 = tolower(c1);
169			c2 = tolower(c2);
170			if (c1 != c2)
171				break;
172		} while (--len);
173	}
174	return (int)c1 - (int)c2;
175}
176
177int stricmp(const char *s1, const char *s2)
178{
179	return (strnicmp(s1, s2, strlen(s1)));
180}
181