1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
5  *
6  ******************************************************************************/
7 #define _RTW_DEBUG_C_
8 
9 #include <rtw_debug.h>
10 #include <usb_ops_linux.h>
11 
proc_get_drv_version(char * page,char ** start,off_t offset,int count,int * eof,void * data)12 int proc_get_drv_version(char *page, char **start,
13 			  off_t offset, int count,
14 			  int *eof, void *data)
15 {
16 	int len = 0;
17 
18 	len += snprintf(page + len, count - len, "%s\n", DRIVERVERSION);
19 
20 	*eof = 1;
21 	return len;
22 }
23 
proc_get_write_reg(char * page,char ** start,off_t offset,int count,int * eof,void * data)24 int proc_get_write_reg(char *page, char **start,
25 			  off_t offset, int count,
26 			  int *eof, void *data)
27 {
28 	*eof = 1;
29 	return 0;
30 }
31 
proc_set_write_reg(struct file * file,const char __user * buffer,unsigned long count,void * data)32 int proc_set_write_reg(struct file *file, const char __user *buffer,
33 		unsigned long count, void *data)
34 {
35 	struct net_device *dev = data;
36 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
37 	char tmp[32];
38 	u32 addr, val, len;
39 
40 	if (count < 3) {
41 		DBG_88E("argument size is less than 3\n");
42 		return -EFAULT;
43 	}
44 
45 	if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
46 		int num = sscanf(tmp, "%x %x %x", &addr, &val, &len);
47 
48 		if (num !=  3) {
49 			DBG_88E("invalid write_reg parameter!\n");
50 			return count;
51 		}
52 		switch (len) {
53 		case 1:
54 			usb_write8(padapter, addr, (u8)val);
55 			break;
56 		case 2:
57 			usb_write16(padapter, addr, (u16)val);
58 			break;
59 		case 4:
60 			usb_write32(padapter, addr, val);
61 			break;
62 		default:
63 			DBG_88E("error write length =%d", len);
64 			break;
65 		}
66 	}
67 	return count;
68 }
69 
70 static u32 proc_get_read_addr = 0xeeeeeeee;
71 static u32 proc_get_read_len = 0x4;
72 
proc_get_read_reg(char * page,char ** start,off_t offset,int count,int * eof,void * data)73 int proc_get_read_reg(char *page, char **start,
74 			  off_t offset, int count,
75 			  int *eof, void *data)
76 {
77 	struct net_device *dev = data;
78 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
79 
80 	int len = 0;
81 
82 	if (proc_get_read_addr == 0xeeeeeeee) {
83 		*eof = 1;
84 		return len;
85 	}
86 
87 	switch (proc_get_read_len) {
88 	case 1:
89 		len += snprintf(page + len, count - len, "usb_read8(0x%x)=0x%x\n", proc_get_read_addr, usb_read8(padapter, proc_get_read_addr));
90 		break;
91 	case 2:
92 		len += snprintf(page + len, count - len, "usb_read16(0x%x)=0x%x\n", proc_get_read_addr, usb_read16(padapter, proc_get_read_addr));
93 		break;
94 	case 4:
95 		len += snprintf(page + len, count - len, "usb_read32(0x%x)=0x%x\n", proc_get_read_addr, usb_read32(padapter, proc_get_read_addr));
96 		break;
97 	default:
98 		len += snprintf(page + len, count - len, "error read length=%d\n", proc_get_read_len);
99 		break;
100 	}
101 
102 	*eof = 1;
103 	return len;
104 }
105 
proc_set_read_reg(struct file * file,const char __user * buffer,unsigned long count,void * data)106 int proc_set_read_reg(struct file *file, const char __user *buffer,
107 		unsigned long count, void *data)
108 {
109 	char tmp[16];
110 	u32 addr, len;
111 
112 	if (count < 2) {
113 		DBG_88E("argument size is less than 2\n");
114 		return -EFAULT;
115 	}
116 
117 	if (buffer && !copy_from_user(tmp, buffer, sizeof(tmp))) {
118 		int num = sscanf(tmp, "%x %x", &addr, &len);
119 
120 		if (num !=  2) {
121 			DBG_88E("invalid read_reg parameter!\n");
122 			return count;
123 		}
124 
125 		proc_get_read_addr = addr;
126 
127 		proc_get_read_len = len;
128 	}
129 
130 	return count;
131 }
132 
proc_get_adapter_state(char * page,char ** start,off_t offset,int count,int * eof,void * data)133 int proc_get_adapter_state(char *page, char **start,
134 			  off_t offset, int count,
135 			  int *eof, void *data)
136 {
137 	struct net_device *dev = data;
138 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
139 	int len = 0;
140 
141 	len += snprintf(page + len, count - len, "bSurpriseRemoved=%d, bDriverStopped=%d\n",
142 						padapter->bSurpriseRemoved, padapter->bDriverStopped);
143 
144 	*eof = 1;
145 	return len;
146 }
147 
proc_get_best_channel(char * page,char ** start,off_t offset,int count,int * eof,void * data)148 int proc_get_best_channel(char *page, char **start,
149 			  off_t offset, int count,
150 			  int *eof, void *data)
151 {
152 	struct net_device *dev = data;
153 	struct adapter *padapter = (struct adapter *)rtw_netdev_priv(dev);
154 	struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
155 	int len = 0;
156 	u32 i, best_channel_24G = 1, best_channel_5G = 36, index_24G = 0, index_5G = 0;
157 
158 	for (i = 0; pmlmeext->channel_set[i].ChannelNum != 0; i++) {
159 		if (pmlmeext->channel_set[i].ChannelNum == 1)
160 			index_24G = i;
161 		if (pmlmeext->channel_set[i].ChannelNum == 36)
162 			index_5G = i;
163 	}
164 
165 	for (i = 0; pmlmeext->channel_set[i].ChannelNum != 0; i++) {
166 		/*  2.4G */
167 		if (pmlmeext->channel_set[i].ChannelNum == 6) {
168 			if (pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_24G].rx_count) {
169 				index_24G = i;
170 				best_channel_24G = pmlmeext->channel_set[i].ChannelNum;
171 			}
172 		}
173 
174 		/*  5G */
175 		if (pmlmeext->channel_set[i].ChannelNum >= 36 &&
176 		    pmlmeext->channel_set[i].ChannelNum < 140) {
177 			/*  Find primary channel */
178 			if (((pmlmeext->channel_set[i].ChannelNum - 36) % 8 == 0) &&
179 			    (pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_5G].rx_count)) {
180 				index_5G = i;
181 				best_channel_5G = pmlmeext->channel_set[i].ChannelNum;
182 			}
183 		}
184 
185 		if (pmlmeext->channel_set[i].ChannelNum >= 149 &&
186 		    pmlmeext->channel_set[i].ChannelNum < 165) {
187 			/*  find primary channel */
188 			if (((pmlmeext->channel_set[i].ChannelNum - 149) % 8 == 0) &&
189 			    (pmlmeext->channel_set[i].rx_count < pmlmeext->channel_set[index_5G].rx_count)) {
190 				index_5G = i;
191 				best_channel_5G = pmlmeext->channel_set[i].ChannelNum;
192 			}
193 		}
194 		/*  debug */
195 		len += snprintf(page + len, count - len, "The rx cnt of channel %3d = %d\n",
196 					pmlmeext->channel_set[i].ChannelNum, pmlmeext->channel_set[i].rx_count);
197 	}
198 
199 	len += snprintf(page + len, count - len, "best_channel_5G = %d\n", best_channel_5G);
200 	len += snprintf(page + len, count - len, "best_channel_24G = %d\n", best_channel_24G);
201 
202 	*eof = 1;
203 	return len;
204 }
205