1/*
2	Copyright 2003, CyberTAN  Inc.  All Rights Reserved
3
4	This is UNPUBLISHED PROPRIETARY SOURCE CODE of CyberTAN Inc.
5	the contents of this file may not be disclosed to third parties,
6	copied or duplicated in any form without the prior written
7	permission of CyberTAN Inc.
8
9	This software should be used as a reference only, and it not
10	intended for production use!
11
12	THIS SOFTWARE IS OFFERED "AS IS", AND CYBERTAN GRANTS NO WARRANTIES OF ANY
13	KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE.  CYBERTAN
14	SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
15	FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE
16*/
17
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21#include <errno.h>
22#include <net/if.h>
23#include <dirent.h>
24#include <unistd.h>
25#include <ctype.h>
26#include <syslog.h>
27#include <sys/socket.h>
28#include <netinet/in.h>
29#include <stdarg.h>
30#include <sys/ioctl.h>
31#include <sys/sysinfo.h>
32
33#include <utils.h>
34#include <bcmnvram.h>
35#include <shutils.h>
36#include <bcmdevs.h>
37#include <net/route.h>
38#include <bcmdevs.h>
39
40#include <linux/if_ether.h>
41#include <linux/sockios.h>
42
43#include "shared.h"
44
45
46// -----------------------------------------------------------------------------
47
48
49#if 0	// beyond here are obsolete functions
50
51struct wl_assoc_mac *get_wl_assoc_mac(int *c)
52{
53	FILE *f;
54	struct wl_assoc_mac *wlmac;
55	int count;
56	char line[80];
57	char mac[20];
58
59	wlmac = NULL;
60    count = 0;
61
62	if ((f = popen("wl assoclist", "r")) != NULL) {
63		// assoclist 00:11:22:33:44:55
64		while ((fgets(line, sizeof(line), f)) != NULL) {
65			if (sscanf(line,"assoclist %17s", mac) != 1) continue;
66
67			wlmac = realloc(wlmac, sizeof(wlmac[0]) * (count + 1));
68			if (!wlmac) {
69				count = 0;
70				break;
71			}
72
73			memset(&wlmac[count], 0, sizeof(wlmac[0]));
74			strlcpy(wlmac[count].mac, mac, sizeof(wlmac[0].mac));
75			++count;
76		}
77
78		pclose(f);
79	}
80
81	*c = count;
82	return wlmac;
83}
84
85
86/*
87void
88show_hw_type(int type)
89{
90	if(type == BCM4702_CHIP)
91		cprintf("The chipset is BCM4702\n");
92	else if(type == BCM5325E_CHIP)
93		cprintf("The chipset is BCM4712L + BCM5325E\n");
94	else if(type == BCM4704_BCM5325F_CHIP)
95		cprintf("The chipset is BCM4704 + BCM5325F\n");
96	else if(type == BCM5352E_CHIP)
97		cprintf("The chipset is BCM5352E\n");
98	else if(type == BCM4712_CHIP)
99		cprintf("The chipset is BCM4712 + ADMtek\n");
100	else
101		cprintf("The chipset is not defined\n");
102}
103*/
104
105
106#define SIOCGMIIREG	0x8948          /* Read MII PHY register.       */
107#define SIOCSMIIREG	0x8949          /* Write MII PHY register.      */
108
109struct mii_ioctl_data {
110	unsigned short		phy_id;
111	unsigned short		reg_num;
112	unsigned short		val_in;
113	unsigned short		val_out;
114};
115
116
117unsigned long get_register_value(unsigned short id, unsigned short num)
118{
119    struct ifreq ifr;
120    struct mii_ioctl_data stats;
121
122    stats.phy_id = id;
123    stats.reg_num = num;
124    stats.val_in = 0;
125    stats.val_out = 0;
126
127    ifr.ifr_data = (void *)&stats;
128
129    sys_netdev_ioctl(AF_INET, -1, get_device_name(), SIOCGMIIREG, &ifr);
130
131    return ((stats.val_in << 16) | stats.val_out);
132}
133
134// xref: set_register_value
135static char *get_device_name(void)
136{
137	switch (check_hw_type()){
138	case BCM5325E_CHIP:
139	case BCM4704_BCM5325F_CHIP:
140	case BCM5352E_CHIP:
141		return "eth0";
142	case BCM4702_CHIP:
143	case BCM4712_CHIP:
144	default:
145		return "qos0";
146	}
147}
148
149// xref: sys_netdev_ioctl
150static int sockets_open(int domain, int type, int protocol)
151{
152    int fd = socket(domain, type, protocol);
153    if (fd < 0)
154		cprintf("sockets_open: no usable address was found.\n");
155    return fd;
156}
157
158// xref: set_register_value
159static int sys_netdev_ioctl(int family, int socket, char *if_name, int cmd, struct ifreq *ifr)
160{
161    int rc, s;
162
163    if ((s = socket) < 0) {
164		if ((s = sockets_open(family, family == AF_PACKET ? SOCK_PACKET : SOCK_DGRAM,
165			family == AF_PACKET ? htons(ETH_P_ALL) : 0)) < 0) {
166			cprintf("sys_netdev_ioctl: failed\n");
167			return -1;
168		}
169    }
170    strcpy(ifr->ifr_name, if_name);
171    rc = ioctl(s, cmd, ifr);
172    if (socket < 0) close(s);
173    return rc;
174}
175
176// xref: rc
177int set_register_value(unsigned short port_addr, unsigned short option_content)
178{
179    struct ifreq ifr;
180    struct mii_ioctl_data stats;
181
182    stats.phy_id = port_addr;
183    stats.val_in = option_content;
184
185    ifr.ifr_data = (void *)&stats;
186
187    if (sys_netdev_ioctl(AF_INET, -1, get_device_name(), SIOCSMIIREG, &ifr) < 0)
188		return -1;
189
190    return 0;
191}
192
193#endif	// if 0
194