1 /*
2 * Copyright (c) 2015 South Silicon Valley Microelectronics Inc.
3 * Copyright (c) 2015 iComm Corporation
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 * See the GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17 #include <linux/kernel.h>
18 #include <linux/version.h>
19 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0)
20 #include <linux/export.h>
21 #else
22 #include <linux/module.h>
23 #endif
24 #include <linux/platform_device.h>
25 #include <linux/string.h>
26 #include <ssv_conf_parser.h>
27 #include <ssv6200_reg.h>
28 #include <ssv6200.h>
29 #include <hci/hctrl.h>
30 #include <smac/dev.h>
31 #include "ssv_cmd.h"
32 #include <ssv_version.h>
33 #ifndef CONFIG_SSV_CABRIO_A
34 #include <ssv6200_configuration.h>
35 #endif
36 #define SSV_CMD_PRINTF()
37 struct ssv6xxx_dev_table {
38 u32 address;
39 u32 val;
40 };
41 struct ssv6xxx_debug {
42 struct device *dev;
43 struct platform_device *pdev;
44 struct ssv6xxx_hwif_ops *ifops;
45 };
46 static struct ssv6xxx_debug *ssv6xxx_debug_ifops;
47 static char sg_cmd_buffer[CLI_BUFFER_SIZE+1];
48 static char *sg_argv[CLI_ARG_SIZE];
49 static u32 sg_argc;
50 extern char *ssv6xxx_result_buf;
51 #if defined (CONFIG_ARM64) || defined (__x86_64__)
52 u64 ssv6xxx_ifdebug_info[3] = { 0, 0, 0 };
53 #else
54 u32 ssv6xxx_ifdebug_info[3] = { 0, 0, 0 };
55 #endif
56 EXPORT_SYMBOL(ssv6xxx_ifdebug_info);
ssvdevice_skb_alloc(s32 len)57 struct sk_buff *ssvdevice_skb_alloc(s32 len)
58 {
59 struct sk_buff *skb;
60 skb = __dev_alloc_skb(len + SSV6200_ALLOC_RSVD , GFP_KERNEL);
61 if (skb != NULL) {
62 skb_put(skb,0x20);
63 skb_pull(skb,0x20);
64 }
65 return skb;
66 }
ssvdevice_skb_free(struct sk_buff * skb)67 void ssvdevice_skb_free(struct sk_buff *skb)
68 {
69 dev_kfree_skb_any(skb);
70 }
ssv_cmd_help(int argc,char * argv[])71 static int ssv_cmd_help(int argc, char *argv[])
72 {
73 extern struct ssv_cmd_table cmd_table[];
74 struct ssv_cmd_table *sc_tbl;
75 char tmpbf[161];
76 int total_cmd=0;
77 {
78 sprintf(ssv6xxx_result_buf, "Usage:\n");
79 for( sc_tbl=&cmd_table[3]; sc_tbl->cmd; sc_tbl ++ ) {
80 sprintf(tmpbf, "%-20s\t\t%s\n", sc_tbl->cmd, sc_tbl->usage);
81 strcat(ssv6xxx_result_buf, tmpbf);
82 total_cmd ++;
83 }
84 sprintf(tmpbf, "Total CMDs: %d\n\nType cli help [CMD] for more detail command.\n\n", total_cmd);
85 strcat(ssv6xxx_result_buf, tmpbf);
86 }
87 return 0;
88 }
ssv_cmd_reg(int argc,char * argv[])89 static int ssv_cmd_reg(int argc, char *argv[])
90 {
91 u32 addr, value, count;
92 char tmpbf[64], *endp;
93 int s;
94 if (argc == 4 && strcmp(argv[1], "w")==0) {
95 addr = simple_strtoul(argv[2], &endp, 16);
96 value = simple_strtoul(argv[3], &endp, 16);
97 if(SSV_REG_WRITE1(ssv6xxx_debug_ifops, addr, value));
98 sprintf(ssv6xxx_result_buf, " => write [0x%08x]: 0x%08x\n",
99 addr, value);
100 return 0;
101 }
102 else if ((argc==4||argc==3) && strcmp(argv[1], "r")==0) {
103 count = (argc==3)? 1: simple_strtoul(argv[3], &endp, 10);
104 addr = simple_strtoul(argv[2], &endp, 16);
105 sprintf(ssv6xxx_result_buf, "ADDRESS: 0x%08x\n", addr);
106 for(s=0; s<count; s++, addr+=4) {
107 if(SSV_REG_READ1(ssv6xxx_debug_ifops, addr, &value));
108 sprintf(tmpbf, "%08x ", value);
109 strcat(ssv6xxx_result_buf, tmpbf);
110 if (((s+1)&0x07) == 0)
111 strcat(ssv6xxx_result_buf, "\n");
112 }
113 strcat(ssv6xxx_result_buf, "\n");
114 return 0;
115 }
116 else
117 {
118 sprintf(tmpbf, "reg [r|w] [address] [value|word-count]\n\n");
119 strcat(ssv6xxx_result_buf, tmpbf);
120 return 0;
121 }
122 return -1;
123 }
124 struct ssv6xxx_cfg ssv_cfg;
125 EXPORT_SYMBOL(ssv_cfg);
126 #if 0
127 static int __string2s32(u8 *val_str, void *val)
128 {
129 char *endp;
130 int base=10;
131 if (val_str[0]=='0' && ((val_str[1]=='x')||(val_str[1]=='X')))
132 base = 16;
133 *(int *)val = simple_strtoul(val_str, &endp, base);
134 return 0;
135 }
136 #endif
137 #if 0
138 static int __string2bool(u8 *u8str, void *val, u32 arg)
139 {
140 char *endp;
141 *(u8 *)val = !!simple_strtoul(u8str, &endp, 10);
142 return 0;
143 }
144 #endif
__string2u32(u8 * u8str,void * val,u32 arg)145 static int __string2u32(u8 *u8str, void *val, u32 arg)
146 {
147 char *endp;
148 int base=10;
149 if (u8str[0]=='0' && ((u8str[1]=='x')||(u8str[1]=='X')))
150 base = 16;
151 *(u32 *)val = simple_strtoul(u8str, &endp, base);
152 return 0;
153 }
__string2flag32(u8 * flag_str,void * flag,u32 arg)154 static int __string2flag32(u8 *flag_str, void *flag, u32 arg)
155 {
156 u32 *val=(u32 *)flag;
157 if (arg >= (sizeof(u32)<<3))
158 return -1;
159 if (strcmp(flag_str, "on")==0) {
160 *val |= (1<<arg);
161 return 0;
162 }
163 if (strcmp(flag_str, "off")==0) {
164 *val &= ~(1<<arg);
165 return 0;
166 }
167 return -1;
168 }
__string2mac(u8 * mac_str,void * val,u32 arg)169 static int __string2mac(u8 *mac_str, void *val, u32 arg)
170 {
171 int s, macaddr[6];
172 u8 *mac=(u8 *)val;
173 s = sscanf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x",
174 &macaddr[0], &macaddr[1], &macaddr[2],
175 &macaddr[3], &macaddr[4], &macaddr[5]);
176 if (s != 6)
177 return -1;
178 mac[0] = (u8)macaddr[0], mac[1] = (u8)macaddr[1];
179 mac[2] = (u8)macaddr[2], mac[3] = (u8)macaddr[3];
180 mac[4] = (u8)macaddr[4], mac[5] = (u8)macaddr[5];
181 return 0;
182 }
__string2str(u8 * path,void * val,u32 arg)183 static int __string2str(u8 *path, void *val, u32 arg)
184 {
185 u8 *temp=(u8 *)val;
186 sprintf(temp,"%s",path);
187 return 0;
188 }
__string2configuration(u8 * mac_str,void * val,u32 arg)189 static int __string2configuration(u8 *mac_str, void *val, u32 arg)
190 {
191 unsigned int address,value;
192 int i;
193 i = sscanf(mac_str, "%08x:%08x", &address, &value);
194 if (i != 2)
195 return -1;
196 for(i=0; i<EXTERNEL_CONFIG_SUPPORT; i++)
197 {
198 if(ssv_cfg.configuration[i][0] == 0x0)
199 {
200 ssv_cfg.configuration[i][0] = address;
201 ssv_cfg.configuration[i][1] = value;
202 return 0;
203 }
204 }
205 return 0;
206 }
207 struct ssv6xxx_cfg_cmd_table cfg_cmds[] = {
208 { "hw_mac", (void *)&ssv_cfg.maddr[0][0], 0, __string2mac },
209 { "hw_mac_2", (void *)&ssv_cfg.maddr[1][0], 0, __string2mac },
210 { "def_chan", (void *)&ssv_cfg.def_chan, 0, __string2u32 },
211 { "hw_cap_ht", (void *)&ssv_cfg.hw_caps, 0, __string2flag32 },
212 { "hw_cap_gf", (void *)&ssv_cfg.hw_caps, 1, __string2flag32 },
213 { "hw_cap_2ghz", (void *)&ssv_cfg.hw_caps, 2, __string2flag32 },
214 { "hw_cap_5ghz", (void *)&ssv_cfg.hw_caps, 3, __string2flag32 },
215 { "hw_cap_security", (void *)&ssv_cfg.hw_caps, 4, __string2flag32 },
216 { "hw_cap_sgi_20", (void *)&ssv_cfg.hw_caps, 5, __string2flag32 },
217 { "hw_cap_sgi_40", (void *)&ssv_cfg.hw_caps, 6, __string2flag32 },
218 { "hw_cap_ap", (void *)&ssv_cfg.hw_caps, 7, __string2flag32 },
219 { "hw_cap_p2p", (void *)&ssv_cfg.hw_caps, 8, __string2flag32 },
220 { "hw_cap_ampdu_rx", (void *)&ssv_cfg.hw_caps, 9, __string2flag32 },
221 { "hw_cap_ampdu_tx", (void *)&ssv_cfg.hw_caps, 10, __string2flag32 },
222 { "hw_cap_tdls", (void *)&ssv_cfg.hw_caps, 11, __string2flag32 },
223 { "use_wpa2_only", (void *)&ssv_cfg.use_wpa2_only, 0, __string2u32 },
224 { "wifi_tx_gain_level_gn",(void *)&ssv_cfg.wifi_tx_gain_level_gn, 0, __string2u32 },
225 { "wifi_tx_gain_level_b", (void *)&ssv_cfg.wifi_tx_gain_level_b, 0, __string2u32 },
226 { "rssi_ctl", (void *)&ssv_cfg.rssi_ctl, 0, __string2u32 },
227 { "xtal_clock", (void *)&ssv_cfg.crystal_type, 0, __string2u32 },
228 { "volt_regulator", (void *)&ssv_cfg.volt_regulator, 0, __string2u32 },
229 { "force_chip_identity", (void *)&ssv_cfg.force_chip_identity, 0, __string2u32 },
230 { "firmware_path", (void *)&ssv_cfg.firmware_path[0], 0, __string2str },
231 { "flash_bin_path",(void *)&ssv_cfg.flash_bin_path[0],0,__string2str },
232 { "mac_address_path", (void *)&ssv_cfg.mac_address_path[0], 0, __string2str },
233 { "mac_output_path", (void *)&ssv_cfg.mac_output_path[0], 0, __string2str },
234 { "ignore_efuse_mac", (void *)&ssv_cfg.ignore_efuse_mac, 0, __string2u32 },
235 { "mac_address_mode", (void *)&ssv_cfg.mac_address_mode, 0, __string2u32 },
236 { "sr_bhvr", (void *)&ssv_cfg.sr_bhvr, 0, __string2u32 },
237 { "register", NULL, 0, __string2configuration },
238 { NULL, NULL, 0, NULL },
239 };
240 EXPORT_SYMBOL(cfg_cmds);
ssv_cmd_cfg(int argc,char * argv[])241 static int ssv_cmd_cfg(int argc, char *argv[])
242 {
243 char temp_buf[64];
244 int s;
245 if (argc==2 && strcmp(argv[1], "reset")==0) {
246 memset(&ssv_cfg, 0, sizeof(ssv_cfg));
247 return 0;
248 }
249 else if (argc==2 && strcmp(argv[1], "show")==0) {
250 strcpy(ssv6xxx_result_buf, ">> ssv6xxx config:\n");
251 sprintf(temp_buf, " hw_caps = 0x%08x\n", ssv_cfg.hw_caps);
252 strcat(ssv6xxx_result_buf, temp_buf);
253 sprintf(temp_buf, " def_chan = %d\n", ssv_cfg.def_chan);
254 strcat(ssv6xxx_result_buf, temp_buf);
255 sprintf(temp_buf, " wifi_tx_gain_level_gn = %d\n", ssv_cfg.wifi_tx_gain_level_gn);
256 strcat(ssv6xxx_result_buf, temp_buf);
257 sprintf(temp_buf, " wifi_tx_gain_level_b = %d\n", ssv_cfg.wifi_tx_gain_level_b);
258 strcat(ssv6xxx_result_buf, temp_buf);
259 sprintf(temp_buf, " rssi_ctl = %d\n", ssv_cfg.rssi_ctl);
260 strcat(ssv6xxx_result_buf, temp_buf);
261 sprintf(temp_buf, " sr_bhvr = %d\n", ssv_cfg.sr_bhvr);
262 strcat(ssv6xxx_result_buf, temp_buf);
263 sprintf(temp_buf, " sta-mac = %02x:%02x:%02x:%02x:%02x:%02x",
264 ssv_cfg.maddr[0][0], ssv_cfg.maddr[0][1], ssv_cfg.maddr[0][2],
265 ssv_cfg.maddr[0][3], ssv_cfg.maddr[0][4], ssv_cfg.maddr[0][5]);
266 strcat(ssv6xxx_result_buf, temp_buf);
267 strcat(ssv6xxx_result_buf, "\n");
268 return 0;
269 }
270 if (argc != 4)
271 return -1;
272 for(s=0; cfg_cmds[s].cfg_cmd!=NULL; s++) {
273 if (strcmp(cfg_cmds[s].cfg_cmd, argv[1])==0) {
274 cfg_cmds[s].translate_func(argv[3],
275 cfg_cmds[s].var, cfg_cmds[s].arg);
276 strcpy(ssv6xxx_result_buf, "");
277 return 0;
278 }
279 }
280 return -1;
281 }
282 void *ssv_dbg_phy_table = NULL;
283 EXPORT_SYMBOL(ssv_dbg_phy_table);
284 u32 ssv_dbg_phy_len = 0;
285 EXPORT_SYMBOL(ssv_dbg_phy_len);
286 void *ssv_dbg_rf_table = NULL;
287 EXPORT_SYMBOL(ssv_dbg_rf_table);
288 u32 ssv_dbg_rf_len = 0;
289 EXPORT_SYMBOL(ssv_dbg_rf_len);
290 struct ssv_softc *ssv_dbg_sc = NULL;
291 EXPORT_SYMBOL(ssv_dbg_sc);
292 struct ssv6xxx_hci_ctrl *ssv_dbg_ctrl_hci = NULL;
293 EXPORT_SYMBOL(ssv_dbg_ctrl_hci);
294 struct Dump_Sta_Info {
295 char *dump_buf;
296 int sta_idx;
297 };
_dump_sta_info(struct ssv_softc * sc,struct ssv_vif_info * vif_info,struct ssv_sta_info * sta_info,void * param)298 static void _dump_sta_info (struct ssv_softc *sc,
299 struct ssv_vif_info *vif_info,
300 struct ssv_sta_info *sta_info,
301 void *param)
302 {
303 char tmpbf[128];
304 struct Dump_Sta_Info *dump_sta_info = (struct Dump_Sta_Info *)param;
305 struct ssv_sta_priv_data *priv_sta = (struct ssv_sta_priv_data *)sta_info->sta->drv_priv;
306 if ((sta_info->s_flags & STA_FLAG_VALID) == 0)
307 sprintf(tmpbf,
308 " Station %d: %d is not valid\n",
309 dump_sta_info->sta_idx, priv_sta->sta_idx);
310 else
311 sprintf(tmpbf,
312 " Station %d: %d\n"
313 " Address: %02X:%02X:%02X:%02X:%02X:%02X\n"
314 " WISD: %d\n"
315 " AID: %d\n"
316 " Sleep: %d\n",
317 dump_sta_info->sta_idx, priv_sta->sta_idx,
318 sta_info->sta->addr[0], sta_info->sta->addr[1], sta_info->sta->addr[2],
319 sta_info->sta->addr[3], sta_info->sta->addr[4], sta_info->sta->addr[5],
320 sta_info->hw_wsid, sta_info->aid, sta_info->sleeping);
321 dump_sta_info->sta_idx++;
322 strcat(dump_sta_info->dump_buf, tmpbf);
323 }
ssv6xxx_dump_sta_info(struct ssv_softc * sc,char * target_buf)324 void ssv6xxx_dump_sta_info (struct ssv_softc *sc, char *target_buf)
325 {
326 int j;
327 char tmpbf[128];
328 struct Dump_Sta_Info dump_sta_info = {target_buf, 0};
329 sprintf(tmpbf, " >>>> bcast queue len[%d]\n", sc->bcast_txq.cur_qsize);
330 strcat(target_buf, tmpbf);
331 for (j=0; j<SSV6200_MAX_VIF; j++) {
332 struct ieee80211_vif *vif = sc->vif_info[j].vif;
333 struct ssv_vif_priv_data *priv_vif;
334 struct ssv_sta_priv_data *sta_priv_iter;
335 if (vif == NULL)
336 {
337 sprintf(tmpbf, " VIF: %d is not used.\n", j);
338 strcat(target_buf, tmpbf);
339 continue;
340 }
341 sprintf(tmpbf,
342 " VIF: %d - [%02X:%02X:%02X:%02X:%02X:%02X] type[%d] p2p[%d]\n", j,
343 vif->addr[0], vif->addr[1], vif->addr[2],
344 vif->addr[3], vif->addr[4], vif->addr[5], vif->type, vif->p2p);
345 strcat(target_buf, tmpbf);
346 priv_vif = (struct ssv_vif_priv_data *)(vif->drv_priv);
347 list_for_each_entry(sta_priv_iter, &priv_vif->sta_list, list)
348 {
349 if ((sta_priv_iter->sta_info->s_flags & STA_FLAG_VALID) == 0)
350 {
351 sprintf(tmpbf, " VIF: %d is not valid.\n", j);
352 strcat(target_buf, tmpbf);
353 continue;
354 }
355 _dump_sta_info(sc, &sc->vif_info[priv_vif->vif_idx],
356 sta_priv_iter->sta_info, &dump_sta_info);
357 }
358 }
359 #if 0
360 sta set channel 7
361 if (argc >= 2 && strcmp(argv[1], "set")==0) {
362 if (argc==4 && strcmp(argv[2], "channel")==0) {
363 char *endp;
364 int ch=simple_strtoul(argv[3], &endp, 10);
365 if (ch>=0 && ch<=13) {
366 }
367 return -1;
368 }
369 }
370 #endif
371 }
ssv_cmd_sta(int argc,char * argv[])372 static int ssv_cmd_sta(int argc, char *argv[])
373 {
374 if (argc >= 2 && strcmp(argv[1], "show")==0)
375 ssv6xxx_dump_sta_info(ssv_dbg_sc, ssv6xxx_result_buf);
376 else
377 strcat(ssv6xxx_result_buf, "sta show\n\n");
378 return 0;
379 }
ssv_cmd_dump(int argc,char * argv[])380 static int ssv_cmd_dump(int argc, char *argv[])
381 {
382 u32 addr, regval;
383 char tmpbf[64];
384 int s;
385 if(!ssv6xxx_result_buf)
386 {
387 printk("ssv6xxx_result_buf = NULL!!\n");
388 return -1;
389 }
390 if (argc != 2)
391 {
392 sprintf(tmpbf, "dump [wsid|decision|phy-info|phy-reg|rf-reg]\n");
393 strcat(ssv6xxx_result_buf, tmpbf);
394 return 0;
395 }
396 if (strcmp(argv[1], "wsid") == 0) {
397 const u32 reg_wsid[]={ ADR_WSID0, ADR_WSID1 };
398 const u32 reg_wsid_tid0[]={ ADR_WSID0_TID0_RX_SEQ, ADR_WSID1_TID0_RX_SEQ };
399 const u32 reg_wsid_tid7[]={ ADR_WSID0_TID7_RX_SEQ, ADR_WSID1_TID7_RX_SEQ };
400 const u8 *op_mode_str[]={"STA", "AP", "AD-HOC", "WDS"};
401 const u8 *ht_mode_str[]={"Non-HT", "HT-MF", "HT-GF", "RSVD"};
402 for(s=0; s<SSV_NUM_HW_STA; s++) {
403 if(SSV_REG_READ1(ssv6xxx_debug_ifops, reg_wsid[s], ®val));
404 sprintf(tmpbf, "==>WSID[%d]\n\tvalid[%d] qos[%d] op_mode[%s] ht_mode[%s]\n",
405 s, regval&0x1, (regval>>1)&0x1, op_mode_str[((regval>>2)&3)], ht_mode_str[((regval>>4)&3)]);
406 strcat(ssv6xxx_result_buf, tmpbf);
407 if(SSV_REG_READ1(ssv6xxx_debug_ifops, reg_wsid[s]+4, ®val));
408 sprintf(tmpbf, "\tMAC[%02x:%02x:%02x:%02x:",
409 (regval&0xff), ((regval>>8)&0xff), ((regval>>16)&0xff), ((regval>>24)&0xff));
410 strcat(ssv6xxx_result_buf, tmpbf);
411 if(SSV_REG_READ1(ssv6xxx_debug_ifops, reg_wsid[s]+8, ®val));
412 sprintf(tmpbf, "%02x:%02x]\n",
413 (regval&0xff), ((regval>>8)&0xff));
414 strcat(ssv6xxx_result_buf, tmpbf);
415 for(addr=reg_wsid_tid0[s]; addr<=reg_wsid_tid7[s]; addr+=4){
416 if(SSV_REG_READ1(ssv6xxx_debug_ifops, addr, ®val));
417 sprintf(tmpbf, "\trx_seq%d[%d]\n", ((addr-reg_wsid_tid0[s])>>2), ((regval)&0xffff));
418 strcat(ssv6xxx_result_buf, tmpbf);
419 }
420 }
421 return 0;
422 }
423 if (strcmp(argv[1], "decision") ==0 ) {
424 strcpy(ssv6xxx_result_buf, ">> Decision Table:\n");
425 for(s=0,addr=ADR_MRX_FLT_TB0; s<16; s++, addr+=4) {
426 if(SSV_REG_READ1(ssv6xxx_debug_ifops, addr, ®val));
427 sprintf(tmpbf, " [%d]: ADDR[0x%08x] = 0x%08x\n",
428 s, addr, regval);
429 strcat(ssv6xxx_result_buf, tmpbf);
430 }
431 strcat(ssv6xxx_result_buf, "\n\n>> Decision Mask:\n");
432 for(s=0,addr=ADR_MRX_FLT_EN0; s<9; s++, addr+=4) {
433 if(SSV_REG_READ1(ssv6xxx_debug_ifops, addr, ®val));
434 sprintf(tmpbf, " [%d]: ADDR[0x%08x] = 0x%08x\n",
435 s, addr, regval);
436 strcat(ssv6xxx_result_buf, tmpbf);
437 }
438 strcat(ssv6xxx_result_buf, "\n\n");
439 return 0;
440 }
441 if (strcmp(argv[1], "phy-info") == 0) {
442 return 0;
443 }
444 if (strcmp(argv[1], "phy-reg") == 0) {
445 struct ssv6xxx_dev_table *raw;
446 raw = (struct ssv6xxx_dev_table *)ssv_dbg_phy_table;
447 strcpy(ssv6xxx_result_buf, ">> PHY Register Table:\n");
448 for(s=0; s<ssv_dbg_phy_len; s++, raw++) {
449 if(SSV_REG_READ1(ssv6xxx_debug_ifops, raw->address, ®val));
450 sprintf(tmpbf, " ADDR[0x%08x] = 0x%08x\n",
451 raw->address, regval);
452 strcat(ssv6xxx_result_buf, tmpbf);
453 }
454 strcat(ssv6xxx_result_buf, "\n\n");
455 return 0;
456 }
457 if (strcmp(argv[1], "rf-reg") == 0) {
458 struct ssv6xxx_dev_table *raw;
459 raw = (struct ssv6xxx_dev_table *)ssv_dbg_rf_table;
460 strcpy(ssv6xxx_result_buf, ">> RF Register Table:\n");
461 for(s=0; s<ssv_dbg_rf_len; s++, raw++) {
462 if(SSV_REG_READ1(ssv6xxx_debug_ifops, raw->address, ®val));
463 sprintf(tmpbf, " ADDR[0x%08x] = 0x%08x\n",
464 raw->address, regval);
465 strcat(ssv6xxx_result_buf, tmpbf);
466 }
467 strcat(ssv6xxx_result_buf, "\n\n");
468 return 0;
469 }
470 return -1;
471 }
ssv_cmd_irq(int argc,char * argv[])472 static int ssv_cmd_irq(int argc, char *argv[])
473 {
474 char *endp;
475 u32 irq_sts;
476 if (argc>=3 && strcmp(argv[1], "set")==0) {
477 if (strcmp(argv[2], "mask")==0 && argc==4) {
478 irq_sts = simple_strtoul(argv[3], &endp, 16);
479 if(!ssv6xxx_debug_ifops->ifops->irq_setmask) {
480 sprintf(ssv6xxx_result_buf, "The interface doesn't provide irq_setmask operation.\n");
481 return 0;
482 }
483 ssv6xxx_debug_ifops->ifops->irq_setmask(
484 ssv6xxx_debug_ifops->dev, irq_sts);
485 sprintf(ssv6xxx_result_buf, "set sdio irq mask to 0x%08x\n", irq_sts);
486 return 0;
487 }
488 if (strcmp(argv[2], "enable")==0) {
489 if(!ssv6xxx_debug_ifops->ifops->irq_enable) {
490 sprintf(ssv6xxx_result_buf, "The interface doesn't provide irq_enable operation.\n");
491 return 0;
492 }
493 ssv6xxx_debug_ifops->ifops->irq_enable(
494 ssv6xxx_debug_ifops->dev);
495 strcpy(ssv6xxx_result_buf, "enable sdio irq.\n");
496 return 0;
497 }
498 if (strcmp(argv[2], "disable")==0) {
499 if(!ssv6xxx_debug_ifops->ifops->irq_disable) {
500 sprintf(ssv6xxx_result_buf, "The interface doesn't provide irq_disable operation.\n");
501 return 0;
502 }
503 ssv6xxx_debug_ifops->ifops->irq_disable(
504 ssv6xxx_debug_ifops->dev, false);
505 strcpy(ssv6xxx_result_buf, "disable sdio irq.\n");
506 return 0;
507 }
508 return -1;
509 }
510 else if (argc==3 && strcmp(argv[1], "get")==0) {
511 if (strcmp(argv[2], "mask") == 0) {
512 if(!ssv6xxx_debug_ifops->ifops->irq_getmask) {
513 sprintf(ssv6xxx_result_buf, "The interface doesn't provide irq_getmask operation.\n");
514 return 0;
515 }
516 ssv6xxx_debug_ifops->ifops->irq_getmask(
517 ssv6xxx_debug_ifops->dev, &irq_sts);
518 sprintf(ssv6xxx_result_buf, "sdio irq mask: 0x%08x, int_mask=0x%08x\n", irq_sts,
519 ssv_dbg_ctrl_hci->int_mask);
520 return 0;
521 }
522 if (strcmp(argv[2], "status") == 0) {
523 if(!ssv6xxx_debug_ifops->ifops->irq_getstatus) {
524 sprintf(ssv6xxx_result_buf, "The interface doesn't provide irq_getstatus operation.\n");
525 return 0;
526 }
527 ssv6xxx_debug_ifops->ifops->irq_getstatus(
528 ssv6xxx_debug_ifops->dev, &irq_sts);
529 sprintf(ssv6xxx_result_buf, "sdio irq status: 0x%08x\n", irq_sts);
530 return 0;
531 }
532 return -1;
533 }
534 else
535 {
536 sprintf(ssv6xxx_result_buf, "irq [set|get] [mask|enable|disable|status]\n");
537 }
538 return 0;
539 }
ssv_cmd_mac(int argc,char * argv[])540 static int ssv_cmd_mac(int argc, char *argv[])
541 {
542 char temp_str[128], *endp;
543 u32 s;
544 int i;
545 if (argc==3 && !strcmp(argv[1], "wsid") && !strcmp(argv[2], "show")) {
546 for(s=0; s<SSV_NUM_HW_STA; s++) {
547 }
548 return 0;
549 }
550 else if (argc==3 && !strcmp(argv[1], "rx")){
551 if(!strcmp(argv[2], "enable")){
552 ssv_dbg_sc->dbg_rx_frame = 1;
553 }
554 else{
555 ssv_dbg_sc->dbg_rx_frame = 0;
556 }
557 sprintf(temp_str, " dbg_rx_frame %d\n", ssv_dbg_sc->dbg_rx_frame);
558 strcat(ssv6xxx_result_buf, temp_str);
559 return 0;
560 }
561 else if (argc==3 && !strcmp(argv[1], "tx")){
562 if(!strcmp(argv[2], "enable")){
563 ssv_dbg_sc->dbg_tx_frame = 1;
564 }
565 else{
566 ssv_dbg_sc->dbg_tx_frame = 0;
567 }
568 sprintf(temp_str, " dbg_tx_frame %d\n", ssv_dbg_sc->dbg_tx_frame);
569 strcat(ssv6xxx_result_buf, temp_str);
570 return 0;
571 }
572 else if (argc==3 && !strcmp(argv[1], "rxq") && !strcmp(argv[2], "show")) {
573 sprintf(temp_str, ">> MAC RXQ: (%s)\n cur_qsize=%d\n",
574 ((ssv_dbg_sc->sc_flags&SC_OP_OFFCHAN)? "off channel": "on channel"),
575 ssv_dbg_sc->rx.rxq_count);
576 strcat(ssv6xxx_result_buf, temp_str);
577 return 0;
578 }
579 #if 0
580 if (argc==3 && !strcmp(argv[1], "tx") && !strcmp(argv[2], "status")) {
581 sprintf(temp_str, ">> MAC TX Status:\n");
582 strcat(ssv6xxx_result_buf, temp_str);
583 sprintf(temp_str, " txq flow control: 0x%x\n", ssv_dbg_sc->tx.flow_ctrl_status);
584 strcat(ssv6xxx_result_buf, temp_str);
585 sprintf(temp_str, " rxq cur_qsize: %d\n", ssv_dbg_sc->rx.rxq_count);
586 strcat(ssv6xxx_result_buf, temp_str);
587 }
588 #endif
589 else if (argc==4 && !strcmp(argv[1], "set") && !strcmp(argv[2], "rate")) {
590 if (strcmp(argv[3], "auto")==0) {
591 ssv_dbg_sc->sc_flags &= ~SC_OP_FIXED_RATE;
592 return 0;
593 }
594 i = simple_strtoul(argv[3], &endp, 10);
595 if (i<0 || i>38) {
596 strcpy(ssv6xxx_result_buf, " Invalid rat index !!\n");
597 return -1;
598 }
599 ssv_dbg_sc->max_rate_idx = i;
600 ssv_dbg_sc->sc_flags |= SC_OP_FIXED_RATE;
601 sprintf(temp_str, " Set rate to index %d\n", i);
602 strcat(ssv6xxx_result_buf, temp_str);
603 return 0;
604 }
605 else if (argc==3 && !strcmp(argv[1], "get") && !strcmp(argv[2], "rate")) {
606 if (ssv_dbg_sc->sc_flags & SC_OP_FIXED_RATE)
607 sprintf(temp_str, " Current Rate Index: %d\n", ssv_dbg_sc->max_rate_idx);
608 else sprintf(temp_str, " Current Rate Index: auto\n");
609 strcpy(ssv6xxx_result_buf, temp_str);
610 return 0;
611 }
612 else
613 {
614 sprintf(temp_str, "mac [security|wsid|rxq] [show]\n");
615 strcat(ssv6xxx_result_buf, temp_str);
616 sprintf(temp_str, "mac [set|get] [rate] [auto|idx]\n");
617 strcat(ssv6xxx_result_buf, temp_str);
618 sprintf(temp_str, "mac [rx|tx] [eable|disable]\n");
619 strcat(ssv6xxx_result_buf, temp_str);
620 }
621 return 0;
622 }
623 #ifdef CONFIG_IRQ_DEBUG_COUNT
print_irq_count(void)624 void print_irq_count(void)
625 {
626 char temp_str[512];
627 sprintf(temp_str, "irq debug (%s)\n",ssv_dbg_ctrl_hci->irq_enable?"enable":"disable");
628 strcat(ssv6xxx_result_buf, temp_str);
629 sprintf(temp_str, "total irq (%d)\n",ssv_dbg_ctrl_hci->irq_count);
630 strcat(ssv6xxx_result_buf, temp_str);
631 sprintf(temp_str, "invalid irq (%d)\n",ssv_dbg_ctrl_hci->invalid_irq_count);
632 strcat(ssv6xxx_result_buf, temp_str);
633 sprintf(temp_str, "rx irq (%d)\n",ssv_dbg_ctrl_hci->rx_irq_count);
634 strcat(ssv6xxx_result_buf, temp_str);
635 sprintf(temp_str, "tx irq (%d)\n",ssv_dbg_ctrl_hci->tx_irq_count);
636 strcat(ssv6xxx_result_buf, temp_str);
637 sprintf(temp_str, "real tx count irq (%d)\n",ssv_dbg_ctrl_hci->real_tx_irq_count);
638 strcat(ssv6xxx_result_buf, temp_str);
639 sprintf(temp_str, "tx packet count (%d)\n",ssv_dbg_ctrl_hci->irq_tx_pkt_count);
640 strcat(ssv6xxx_result_buf, temp_str);
641 sprintf(temp_str, "rx packet (%d)\n",ssv_dbg_ctrl_hci->irq_rx_pkt_count);
642 strcat(ssv6xxx_result_buf, temp_str);
643 }
644 #endif
print_isr_info(void)645 void print_isr_info(void)
646 {
647 char temp_str[512];
648 sprintf(temp_str, ">>>> HCI Calculate ISR TIME(%s) unit:us\n",
649 ((ssv_dbg_ctrl_hci->isr_summary_eable)? "enable": "disable"));
650 strcat(ssv6xxx_result_buf, temp_str);
651 sprintf(temp_str, "isr_routine_time(%d)\n",
652 jiffies_to_usecs(ssv_dbg_ctrl_hci->isr_routine_time));
653 strcat(ssv6xxx_result_buf, temp_str);
654 sprintf(temp_str, "isr_tx_time(%d)\n",
655 jiffies_to_usecs(ssv_dbg_ctrl_hci->isr_tx_time));
656 strcat(ssv6xxx_result_buf, temp_str);
657 sprintf(temp_str, "isr_rx_time(%d)\n",
658 jiffies_to_usecs(ssv_dbg_ctrl_hci->isr_rx_time));
659 strcat(ssv6xxx_result_buf, temp_str);
660 sprintf(temp_str, "isr_idle_time(%d)\n",
661 jiffies_to_usecs(ssv_dbg_ctrl_hci->isr_idle_time));
662 strcat(ssv6xxx_result_buf, temp_str);
663 sprintf(temp_str, "isr_rx_idle_time(%d)\n",
664 jiffies_to_usecs(ssv_dbg_ctrl_hci->isr_rx_idle_time));
665 strcat(ssv6xxx_result_buf, temp_str);
666 sprintf(temp_str, "isr_miss_cnt(%d)\n",
667 ssv_dbg_ctrl_hci->isr_miss_cnt);
668 strcat(ssv6xxx_result_buf, temp_str);
669 sprintf(temp_str, "prev_isr_jiffes(%lu)\n",
670 ssv_dbg_ctrl_hci->prev_isr_jiffes);
671 strcat(ssv6xxx_result_buf, temp_str);
672 sprintf(temp_str, "prev_rx_isr_jiffes(%lu)\n",
673 ssv_dbg_ctrl_hci->prev_rx_isr_jiffes);
674 strcat(ssv6xxx_result_buf, temp_str);
675 }
ssv_cmd_hci(int argc,char * argv[])676 static int ssv_cmd_hci(int argc, char *argv[])
677 {
678 struct ssv_hw_txq *txq;
679 char temp_str[512];
680 int s,ac = 0;
681 if (argc==3 && !strcmp(argv[1], "txq") && !strcmp(argv[2], "show") )
682 {
683 for(s=0; s<WMM_NUM_AC; s++) {
684 if (ssv_dbg_sc != NULL)
685 ac = ssv_dbg_sc->tx.ac_txqid[s];
686 txq = &ssv_dbg_ctrl_hci->hw_txq[s];
687 sprintf(temp_str, ">> txq[%d]", txq->txq_no);
688 if (ssv_dbg_sc != NULL)
689 sprintf(temp_str, "(%s): ",((ssv_dbg_sc->sc_flags&SC_OP_OFFCHAN)? "off channel": "on channel"));
690 sprintf(temp_str, "cur_qsize=%d\n", skb_queue_len(&txq->qhead));
691 strcat(ssv6xxx_result_buf, temp_str);
692 sprintf(temp_str, " max_qsize=%d, pause=%d, resume_thres=%d",
693 txq->max_qsize, txq->paused, txq->resum_thres);\
694 if (ssv_dbg_sc != NULL)
695 sprintf(temp_str, " flow_control[%d]\n", !!(ssv_dbg_sc->tx.flow_ctrl_status&(1<<ac)));
696 strcat(ssv6xxx_result_buf, temp_str);
697 sprintf(temp_str, " Total %d frame sent\n", txq->tx_pkt);
698 strcat(ssv6xxx_result_buf, temp_str);
699 }
700 sprintf(temp_str, ">> HCI Debug Counters:\n read_rs0_info_fail=%d, read_rs1_info_fail=%d\n",
701 ssv_dbg_ctrl_hci->read_rs0_info_fail, ssv_dbg_ctrl_hci->read_rs1_info_fail);
702 strcat(ssv6xxx_result_buf, temp_str);
703 sprintf(temp_str, " rx_work_running=%d, isr_running=%d, xmit_running=%d\n",
704 ssv_dbg_ctrl_hci->rx_work_running, ssv_dbg_ctrl_hci->isr_running,
705 ssv_dbg_ctrl_hci->xmit_running);
706 strcat(ssv6xxx_result_buf, temp_str);
707 if (ssv_dbg_sc != NULL)
708 sprintf(temp_str, " flow_ctrl_status=%08x\n", ssv_dbg_sc->tx.flow_ctrl_status);
709 strcat(ssv6xxx_result_buf, temp_str);
710 return 0;
711 }
712 else if (argc==3 && !strcmp(argv[1], "rxq") && !strcmp(argv[2], "show") ) {
713 sprintf(temp_str, ">> HCI RX Queue (%s): cur_qsize=%d\n",
714 ((ssv_dbg_sc->sc_flags&SC_OP_OFFCHAN)? "off channel": "on channel"),
715 ssv_dbg_ctrl_hci->rx_pkt);
716 strcat(ssv6xxx_result_buf, temp_str);
717 return 0;
718 }
719 else if (argc==3 && !strcmp(argv[1], "isr_time") && !strcmp(argv[2], "start") ) {
720 ssv_dbg_ctrl_hci->isr_summary_eable = 1;
721 ssv_dbg_ctrl_hci->isr_routine_time = 0;
722 ssv_dbg_ctrl_hci->isr_tx_time = 0;
723 ssv_dbg_ctrl_hci->isr_rx_time = 0;
724 ssv_dbg_ctrl_hci->isr_idle_time = 0;
725 ssv_dbg_ctrl_hci->isr_rx_idle_time = 0;
726 ssv_dbg_ctrl_hci->isr_miss_cnt = 0;
727 ssv_dbg_ctrl_hci->prev_isr_jiffes = 0;
728 ssv_dbg_ctrl_hci->prev_rx_isr_jiffes = 0;
729 print_isr_info();
730 return 0;
731 }
732 else if (argc==3 && !strcmp(argv[1], "isr_time") && !strcmp(argv[2], "stop") ) {
733 ssv_dbg_ctrl_hci->isr_summary_eable = 0;
734 print_isr_info();
735 return 0;
736 }
737 else if (argc==3 && !strcmp(argv[1], "isr_time") && !strcmp(argv[2], "show") ) {
738 print_isr_info();
739 return 0;
740 }
741 #ifdef CONFIG_IRQ_DEBUG_COUNT
742 else if (argc==3 && !strcmp(argv[1], "isr_debug") && !strcmp(argv[2], "reset") ) {
743 ssv_dbg_ctrl_hci->irq_enable= 0;
744 ssv_dbg_ctrl_hci->irq_count = 0;
745 ssv_dbg_ctrl_hci->invalid_irq_count = 0;
746 ssv_dbg_ctrl_hci->tx_irq_count = 0;
747 ssv_dbg_ctrl_hci->real_tx_irq_count = 0;
748 ssv_dbg_ctrl_hci->rx_irq_count = 0;
749 ssv_dbg_ctrl_hci->isr_rx_idle_time = 0;
750 ssv_dbg_ctrl_hci->irq_rx_pkt_count = 0;
751 ssv_dbg_ctrl_hci->irq_tx_pkt_count = 0;
752 strcat(ssv6xxx_result_buf, "irq debug reset count\n");
753 return 0;
754 }
755 else if (argc==3 && !strcmp(argv[1], "isr_debug") && !strcmp(argv[2], "show") ) {
756 print_irq_count();
757 return 0;
758 }
759 else if (argc==3 && !strcmp(argv[1], "isr_debug") && !strcmp(argv[2], "stop") ) {
760 ssv_dbg_ctrl_hci->irq_enable= 0;
761 strcat(ssv6xxx_result_buf, "irq debug stop\n");
762 return 0;
763 }
764 else if (argc==3 && !strcmp(argv[1], "isr_debug") && !strcmp(argv[2], "start") ) {
765 ssv_dbg_ctrl_hci->irq_enable= 1;
766 strcat(ssv6xxx_result_buf, "irq debug start\n");
767 return 0;
768 }
769 #endif
770 else
771 {
772 strcat(ssv6xxx_result_buf, "hci [txq|rxq] [show]\nhci [isr_time] [start|stop|show]\n\n");
773 return 0;
774 }
775 return -1;
776 }
ssv_cmd_hwq(int argc,char * argv[])777 static int ssv_cmd_hwq(int argc, char *argv[])
778 {
779 #undef GET_FFO0_CNT
780 #undef GET_FFO1_CNT
781 #undef GET_FFO2_CNT
782 #undef GET_FFO3_CNT
783 #undef GET_FFO4_CNT
784 #undef GET_FFO5_CNT
785 #undef GET_FFO6_CNT
786 #undef GET_FFO7_CNT
787 #undef GET_FFO8_CNT
788 #undef GET_FFO9_CNT
789 #undef GET_FFO10_CNT
790 #undef GET_FFO11_CNT
791 #undef GET_FFO12_CNT
792 #undef GET_FFO13_CNT
793 #undef GET_FFO14_CNT
794 #undef GET_FFO15_CNT
795 #undef GET_FF0_CNT
796 #undef GET_FF1_CNT
797 #undef GET_FF3_CNT
798 #undef GET_FF5_CNT
799 #undef GET_FF6_CNT
800 #undef GET_FF7_CNT
801 #undef GET_FF8_CNT
802 #undef GET_FF9_CNT
803 #undef GET_FF10_CNT
804 #undef GET_FF11_CNT
805 #undef GET_FF12_CNT
806 #undef GET_FF13_CNT
807 #undef GET_FF14_CNT
808 #undef GET_FF15_CNT
809 #undef GET_FF4_CNT
810 #undef GET_FF2_CNT
811 #undef GET_TX_ID_ALC_LEN
812 #undef GET_RX_ID_ALC_LEN
813 #undef GET_AVA_TAG
814 #define GET_FFO0_CNT ((value & 0x0000001f ) >> 0)
815 #define GET_FFO1_CNT ((value & 0x000003e0 ) >> 5)
816 #define GET_FFO2_CNT ((value & 0x00000c00 ) >> 10)
817 #define GET_FFO3_CNT ((value & 0x000f8000 ) >> 15)
818 #define GET_FFO4_CNT ((value & 0x00300000 ) >> 20)
819 #define GET_FFO5_CNT ((value & 0x0e000000 ) >> 25)
820 #define GET_FFO6_CNT ((value1 & 0x0000000f ) >> 0)
821 #define GET_FFO7_CNT ((value1 & 0x000003e0 ) >> 5)
822 #define GET_FFO8_CNT ((value1 & 0x00007c00 ) >> 10)
823 #define GET_FFO9_CNT ((value1 & 0x000f8000 ) >> 15)
824 #define GET_FFO10_CNT ((value1 & 0x00f00000 ) >> 20)
825 #define GET_FFO11_CNT ((value1 & 0x3e000000 ) >> 25)
826 #define GET_FFO12_CNT ((value2 & 0x00000007 ) >> 0)
827 #define GET_FFO13_CNT ((value2 & 0x00000060 ) >> 5)
828 #define GET_FFO14_CNT ((value2 & 0x00000c00 ) >> 10)
829 #define GET_FFO15_CNT ((value2 & 0x001f8000 ) >> 15)
830 #define GET_FF0_CNT ((value & 0x0000001f ) >> 0)
831 #define GET_FF1_CNT ((value & 0x000001e0 ) >> 5)
832 #define GET_FF3_CNT ((value & 0x00003800 ) >> 11)
833 #define GET_FF5_CNT ((value & 0x000e0000 ) >> 17)
834 #define GET_FF6_CNT ((value & 0x00700000 ) >> 20)
835 #define GET_FF7_CNT ((value & 0x03800000 ) >> 23)
836 #define GET_FF8_CNT ((value & 0x1c000000 ) >> 26)
837 #define GET_FF9_CNT ((value & 0xe0000000 ) >> 29)
838 #define GET_FF10_CNT ((value1 & 0x00000007 ) >> 0)
839 #define GET_FF11_CNT ((value1 & 0x00000038 ) >> 3)
840 #define GET_FF12_CNT ((value1 & 0x000001c0 ) >> 6)
841 #define GET_FF13_CNT ((value1 & 0x00000600 ) >> 9)
842 #define GET_FF14_CNT ((value1 & 0x00001800 ) >> 11)
843 #define GET_FF15_CNT ((value1 & 0x00006000 ) >> 13)
844 #define GET_FF4_CNT ((value1 & 0x000f8000 ) >> 15)
845 #define GET_FF2_CNT ((value1 & 0x00700000 ) >> 20)
846 #define GET_TX_ID_ALC_LEN ((value & 0x0003fe00 ) >> 9)
847 #define GET_RX_ID_ALC_LEN ((value & 0x07fc0000 ) >> 18)
848 #define GET_AVA_TAG ((value1 & 0x01ff0000 ) >> 16)
849 u32 addr, value, value1, value2;
850 char temp_str[512];
851 addr = ADR_RD_FFOUT_CNT1;
852 if(SSV_REG_READ1(ssv6xxx_debug_ifops, addr, &value));
853 addr = ADR_RD_FFOUT_CNT2;
854 if(SSV_REG_READ1(ssv6xxx_debug_ifops, addr, &value1));
855 addr = ADR_RD_FFOUT_CNT3;
856 if(SSV_REG_READ1(ssv6xxx_debug_ifops, addr, &value2));
857 sprintf(temp_str, "\n[TAG] MCU - HCI - SEC - RX - MIC - TX0 - TX1 - TX2 - TX3 - TX4 - SEC - MIC - TSH\n");
858 strcat(ssv6xxx_result_buf, temp_str);
859 sprintf(temp_str,"OUTPUT %3d - %3d - %3d - %3d - %3d - %3d - %3d - %3d - %3d - %3d - %3d - %3d - %3d\n",
860 GET_FFO0_CNT, GET_FFO1_CNT, GET_FFO3_CNT, GET_FFO4_CNT, GET_FFO5_CNT, GET_FFO6_CNT,
861 GET_FFO7_CNT, GET_FFO8_CNT, GET_FFO9_CNT, GET_FFO10_CNT, GET_FFO11_CNT, GET_FFO12_CNT, GET_FFO15_CNT);
862 strcat(ssv6xxx_result_buf, temp_str);
863 addr = ADR_RD_IN_FFCNT1;
864 if(SSV_REG_READ1(ssv6xxx_debug_ifops, addr, &value));
865 addr = ADR_RD_IN_FFCNT2;
866 if(SSV_REG_READ1(ssv6xxx_debug_ifops, addr, &value1));
867 sprintf(temp_str, "INPUT %3d - %3d - %3d - %3d - %3d - %3d - %3d - %3d - %3d - %3d - %3d - %3d - %3d\n",
868 GET_FF0_CNT, GET_FF1_CNT, GET_FF3_CNT, GET_FF4_CNT, GET_FF5_CNT, GET_FF6_CNT,
869 GET_FF7_CNT, GET_FF8_CNT, GET_FF9_CNT, GET_FF10_CNT, GET_FF11_CNT, GET_FF12_CNT, GET_FF15_CNT);
870 strcat(ssv6xxx_result_buf, temp_str);
871 addr = ADR_ID_LEN_THREADSHOLD2;
872 if(SSV_REG_READ1(ssv6xxx_debug_ifops, addr, &value));
873 addr = ADR_TAG_STATUS;
874 if(SSV_REG_READ1(ssv6xxx_debug_ifops, addr, &value1));
875 sprintf(temp_str, "TX[%d]RX[%d]AVA[%d]\n",GET_TX_ID_ALC_LEN, GET_RX_ID_ALC_LEN, GET_AVA_TAG);
876 strcat(ssv6xxx_result_buf, temp_str);
877 return 0;
878 }
879 #ifdef CONFIG_P2P_NOA
880 #if 0
881 struct ssv6xxx_p2p_noa_param {
882 u32 duration;
883 u32 interval;
884 u32 start_time;
885 u32 enable:8;
886 u32 count:8;
887 u8 addr[6];
888 };
889 #endif
890 static struct ssv6xxx_p2p_noa_param cmd_noa_param = {
891 50,
892 100,
893 0x12345678,
894 1,
895 255,
896 {0x4c, 0xe6, 0x76, 0xa2, 0x4e, 0x7c}
897 };
noa_dump(char * temp_str)898 void noa_dump(char* temp_str)
899 {
900 sprintf(temp_str, "NOA Parameter:\nEnable=%d\nInterval=%d\nDuration=%d\nStart_time=0x%08x\nCount=%d\nAddr=[%02x:%02x:%02x:%02x:%02x:%02x]\n",
901 cmd_noa_param.enable,
902 cmd_noa_param.interval,
903 cmd_noa_param.duration,
904 cmd_noa_param.start_time,
905 cmd_noa_param.count,
906 cmd_noa_param.addr[0],
907 cmd_noa_param.addr[1],
908 cmd_noa_param.addr[2],
909 cmd_noa_param.addr[3],
910 cmd_noa_param.addr[4],
911 cmd_noa_param.addr[5]);
912 strcat(ssv6xxx_result_buf, temp_str);
913 }
ssv6xxx_send_noa_cmd(struct ssv_softc * sc,struct ssv6xxx_p2p_noa_param * p2p_noa_param)914 void ssv6xxx_send_noa_cmd(struct ssv_softc *sc, struct ssv6xxx_p2p_noa_param *p2p_noa_param)
915 {
916 struct sk_buff *skb;
917 struct cfg_host_cmd *host_cmd;
918 int retry_cnt = 5;
919 skb = ssvdevice_skb_alloc(HOST_CMD_HDR_LEN + sizeof(struct ssv6xxx_p2p_noa_param));
920 skb->data_len = HOST_CMD_HDR_LEN + sizeof(struct ssv6xxx_p2p_noa_param);
921 skb->len = skb->data_len;
922 host_cmd = (struct cfg_host_cmd *)skb->data;
923 host_cmd->c_type = HOST_CMD;
924 host_cmd->h_cmd = (u8)SSV6XXX_HOST_CMD_SET_NOA;
925 host_cmd->len = skb->data_len;
926 memcpy(host_cmd->dat32, p2p_noa_param, sizeof(struct ssv6xxx_p2p_noa_param));
927 while((HCI_SEND_CMD(sc->sh, skb)!=0)&&(retry_cnt)){
928 printk(KERN_INFO "NOA cmd retry=%d!!\n",retry_cnt);
929 retry_cnt--;
930 }
931 ssvdevice_skb_free(skb);
932 }
ssv_cmd_noa(int argc,char * argv[])933 static int ssv_cmd_noa(int argc, char *argv[])
934 {
935 char temp_str[512];
936 char *endp;
937 if (argc==2 && !strcmp(argv[1], "show") ) {
938 ;
939 }else if (argc==3 && !strcmp(argv[1], "duration") ){
940 cmd_noa_param.duration= simple_strtoul(argv[2], &endp, 0);
941 }else if (argc==3 && !strcmp(argv[1], "interval") ) {
942 cmd_noa_param.interval= simple_strtoul(argv[2], &endp, 0);
943 }else if (argc==3 && !strcmp(argv[1], "start") ) {
944 cmd_noa_param.start_time= simple_strtoul(argv[2], &endp, 0);
945 }else if (argc==3 && !strcmp(argv[1], "enable") ) {
946 cmd_noa_param.enable= simple_strtoul(argv[2], &endp, 0);
947 }else if (argc==3 && !strcmp(argv[1], "count") ) {
948 cmd_noa_param.count= simple_strtoul(argv[2], &endp, 0);
949 }else if (argc==8 && !strcmp(argv[1], "addr") ) {
950 cmd_noa_param.addr[0]= simple_strtoul(argv[2], &endp, 16);
951 cmd_noa_param.addr[1]= simple_strtoul(argv[3], &endp, 16);
952 cmd_noa_param.addr[2]= simple_strtoul(argv[4], &endp, 16);
953 cmd_noa_param.addr[3]= simple_strtoul(argv[5], &endp, 16);
954 cmd_noa_param.addr[4]= simple_strtoul(argv[6], &endp, 16);
955 cmd_noa_param.addr[5]= simple_strtoul(argv[7], &endp, 16);
956 }else if (argc==2 && !strcmp(argv[1], "send") ) {
957 ssv6xxx_send_noa_cmd(ssv_dbg_sc, &cmd_noa_param);
958 }else{
959 sprintf(temp_str,"## wrong command\n");
960 strcat(ssv6xxx_result_buf, temp_str);
961 return 0;
962 }
963 noa_dump(temp_str);
964 return 0;
965 }
966 #endif
ssv_cmd_mib(int argc,char * argv[])967 static int ssv_cmd_mib(int argc, char *argv[])
968 {
969 u32 addr, value;
970 char temp_str[512];
971 int i;
972 if (argc==2 && !strcmp(argv[1], "reset") ) {
973 addr = MIB_REG_BASE;
974 value = 0x0;
975 if(SSV_REG_WRITE1(ssv6xxx_debug_ifops, MIB_REG_BASE, value));
976 value = 0xffffffff;
977 if(SSV_REG_WRITE1(ssv6xxx_debug_ifops, MIB_REG_BASE, value));
978 value = 0x0;
979 if(SSV_REG_WRITE1(ssv6xxx_debug_ifops, 0xCE0023F8, value));
980 value = 0x100000;
981 if(SSV_REG_WRITE1(ssv6xxx_debug_ifops, 0xCE0023F8, value));
982 value = 0x0;
983 if(SSV_REG_WRITE1(ssv6xxx_debug_ifops, 0xCE0043F8, value));
984 value = 0x100000;
985 if(SSV_REG_WRITE1(ssv6xxx_debug_ifops, 0xCE0043F8, value));
986 value = 0x0;
987 if(SSV_REG_WRITE1(ssv6xxx_debug_ifops, 0xCE000088, value));
988 value = 0x80000000;
989 if(SSV_REG_WRITE1(ssv6xxx_debug_ifops, 0xCE000088, value));
990 sprintf(temp_str, " => MIB reseted\n");
991 strcat(ssv6xxx_result_buf, temp_str);
992 }else if (argc==2 && !strcmp(argv[1], "list") ) {
993 addr = MIB_REG_BASE;
994 for(i=0; i<120; i++, addr+=4) {
995 if(SSV_REG_READ1(ssv6xxx_debug_ifops, addr, &value));
996 sprintf(temp_str, "%08x ", value);
997 strcat(ssv6xxx_result_buf, temp_str);
998 if (((i+1)&0x07) == 0)
999 strcat(ssv6xxx_result_buf, "\n");
1000 }
1001 strcat(ssv6xxx_result_buf, "\n");
1002 }
1003 else if (argc == 2 && strcmp(argv[1], "rx")==0) {
1004 sprintf(temp_str, "%-10s\t\t%-10s\t\t%-10s\t\t%-10s\n","MRX_FCS_SUCC", "MRX_FCS_ERR", "MRX_ALC_FAIL", "MRX_MISS");
1005 strcat(ssv6xxx_result_buf, temp_str);
1006 if(SSV_REG_READ1(ssv6xxx_debug_ifops, ADR_MRX_FCS_SUCC, &value)) {
1007 sprintf(temp_str, "[%08x]\t\t", value);
1008 strcat(ssv6xxx_result_buf, temp_str);
1009 }
1010 if(SSV_REG_READ1(ssv6xxx_debug_ifops, ADR_MRX_FCS_ERR, &value)) {
1011 sprintf(temp_str, "[%08x]\t\t", value);
1012 strcat(ssv6xxx_result_buf, temp_str);
1013 }
1014 if(SSV_REG_READ1(ssv6xxx_debug_ifops, ADR_MRX_ALC_FAIL, &value)) {
1015 sprintf(temp_str, "[%08x]\t\t", value);
1016 strcat(ssv6xxx_result_buf, temp_str);
1017 }
1018 if(SSV_REG_READ1(ssv6xxx_debug_ifops, ADR_MRX_MISS, &value)) {
1019 sprintf(temp_str, "[%08x]\n", value);
1020 strcat(ssv6xxx_result_buf, temp_str);
1021 sprintf(temp_str, "%-10s\t\t%-10s\t\t%-10s\t%-10s\n", "MRX_MB_MISS", "MRX_NIDLE_MISS", "DBG_LEN_ALC_FAIL", "DBG_LEN_CRC_FAIL");
1022 strcat(ssv6xxx_result_buf, temp_str);
1023 }
1024 if(SSV_REG_READ1(ssv6xxx_debug_ifops, ADR_MRX_MB_MISS, &value)) {
1025 sprintf(temp_str, "[%08x]\t\t", value);
1026 strcat(ssv6xxx_result_buf, temp_str);
1027 }
1028 if(SSV_REG_READ1(ssv6xxx_debug_ifops, ADR_MRX_NIDLE_MISS, &value)) {
1029 sprintf(temp_str, "[%08x]\t\t", value);
1030 strcat(ssv6xxx_result_buf, temp_str);
1031 }
1032 if(SSV_REG_READ1(ssv6xxx_debug_ifops, ADR_DBG_LEN_ALC_FAIL, &value)) {
1033 sprintf(temp_str, "[%08x]\t\t", value);
1034 strcat(ssv6xxx_result_buf, temp_str);
1035 }
1036 if(SSV_REG_READ1(ssv6xxx_debug_ifops, ADR_DBG_LEN_CRC_FAIL, &value)) {
1037 sprintf(temp_str, "[%08x]\n\n", value);
1038 strcat(ssv6xxx_result_buf, temp_str);
1039 strcat(ssv6xxx_result_buf, temp_str);
1040 }
1041 if(SSV_REG_READ1(ssv6xxx_debug_ifops, ADR_DBG_AMPDU_PASS, &value)) {
1042 sprintf(temp_str, "[%08x]\t\t", value);
1043 strcat(ssv6xxx_result_buf, temp_str);
1044 }
1045 if(SSV_REG_READ1(ssv6xxx_debug_ifops, ADR_DBG_AMPDU_FAIL, &value)) {
1046 sprintf(temp_str, "[%08x]\t\t", value);
1047 strcat(ssv6xxx_result_buf, temp_str);
1048 }
1049 if(SSV_REG_READ1(ssv6xxx_debug_ifops, ADR_ID_ALC_FAIL1, &value)) {
1050 sprintf(temp_str, "[%08x]\t\t", value);
1051 strcat(ssv6xxx_result_buf, temp_str);
1052 }
1053 if(SSV_REG_READ1(ssv6xxx_debug_ifops, ADR_ID_ALC_FAIL2, &value)) {
1054 sprintf(temp_str, "[%08x]\n\n", value);
1055 strcat(ssv6xxx_result_buf, temp_str);
1056 sprintf(temp_str, "PHY B mode:\n");
1057 strcat(ssv6xxx_result_buf, temp_str);
1058 sprintf(temp_str, "%-10s\t\t%-10s\t\t%-10s\n", "CRC error","CCA","counter");
1059 strcat(ssv6xxx_result_buf, temp_str);
1060 }
1061 if(SSV_REG_READ1(ssv6xxx_debug_ifops, 0xCE0023E8, &value)) {
1062 sprintf(temp_str, "[%08x]\t\t", value&0xffff);
1063 strcat(ssv6xxx_result_buf, temp_str);
1064 }
1065 if(SSV_REG_READ1(ssv6xxx_debug_ifops, 0xCE0023EC, &value)) {
1066 sprintf(temp_str, "[%08x]\t\t", (value>>16)&0xffff);
1067 strcat(ssv6xxx_result_buf, temp_str);
1068 sprintf(temp_str, "[%08x]\t\t\n\n", value&0xffff);
1069 strcat(ssv6xxx_result_buf, temp_str);
1070 sprintf(temp_str, "PHY G/N mode:\n");
1071 strcat(ssv6xxx_result_buf, temp_str);
1072 sprintf(temp_str, "%-10s\t\t%-10s\t\t%-10s\n", "CRC error","CCA","counter");
1073 strcat(ssv6xxx_result_buf, temp_str);
1074 }
1075 if(SSV_REG_READ1(ssv6xxx_debug_ifops, 0xCE0043E8, &value)) {
1076 sprintf(temp_str, "[%08x]\t\t", value&0xffff);
1077 strcat(ssv6xxx_result_buf, temp_str);
1078 }
1079 if(SSV_REG_READ1(ssv6xxx_debug_ifops, 0xCE0043EC, &value)) {
1080 sprintf(temp_str, "[%08x]\t\t", (value>>16)&0xffff);
1081 strcat(ssv6xxx_result_buf, temp_str);
1082 sprintf(temp_str, "[%08x]\t\t\n\n", value&0xffff);
1083 strcat(ssv6xxx_result_buf, temp_str);
1084 }
1085 }
1086 else
1087 {
1088 sprintf(temp_str, "mib [reset|list|rx]\n\n");
1089 strcat(ssv6xxx_result_buf, temp_str);
1090 }
1091 return 0;
1092 }
ssv_cmd_sdio(int argc,char * argv[])1093 static int ssv_cmd_sdio(int argc, char *argv[])
1094 {
1095 u32 addr, value;
1096 char temp_str[512], *endp;
1097 int ret=0;
1098 if (argc==4 && !strcmp(argv[1], "reg") && !strcmp(argv[2], "r") ) {
1099 addr = simple_strtoul(argv[3], &endp, 16);
1100 if(!ssv6xxx_debug_ifops->ifops->cmd52_read){
1101 sprintf(temp_str,"The interface doesn't provide cmd52 read\n");
1102 strcat(ssv6xxx_result_buf, temp_str);
1103 return 0;
1104 }
1105 ret = ssv6xxx_debug_ifops->ifops->cmd52_read(
1106 ssv6xxx_debug_ifops->dev,
1107 addr,
1108 &value
1109 );
1110 if (ret >= 0) {
1111 sprintf(temp_str," ==> %x\n", value);
1112 strcat(ssv6xxx_result_buf, temp_str);
1113 return 0;
1114 }
1115 }
1116 else if (argc==5 && !strcmp(argv[1], "reg") && !strcmp(argv[2], "w") ) {
1117 addr = simple_strtoul(argv[3], &endp, 16);
1118 value = simple_strtoul(argv[4], &endp, 16);
1119 if(!ssv6xxx_debug_ifops->ifops->cmd52_write){
1120 sprintf(temp_str,"The interface doesn't provide cmd52 write\n");
1121 strcat(ssv6xxx_result_buf, temp_str);
1122 return 0;
1123 }
1124 ret = ssv6xxx_debug_ifops->ifops->cmd52_write(
1125 ssv6xxx_debug_ifops->dev,
1126 addr,
1127 value
1128 );
1129 if (ret >= 0) {
1130 sprintf(temp_str," ==> write odne.\n");
1131 strcat(ssv6xxx_result_buf, temp_str);
1132 return 0;
1133 }
1134 }
1135 sprintf(temp_str,"sdio cmd52 fail: %d\n", ret);
1136 strcat(ssv6xxx_result_buf, temp_str);
1137 return 0;
1138 }
1139 #ifdef CONFIG_SSV_CABRIO_E
1140 static struct ssv6xxx_iqk_cfg cmd_iqk_cfg = {
1141 SSV6XXX_IQK_CFG_XTAL_26M,
1142 SSV6XXX_IQK_CFG_PA_DEF,
1143 0,
1144 0,
1145 26,
1146 3,
1147 0x75,
1148 0x75,
1149 0x80,
1150 0x80,
1151 SSV6XXX_IQK_CMD_INIT_CALI,
1152 { SSV6XXX_IQK_TEMPERATURE
1153 + SSV6XXX_IQK_RXDC
1154 + SSV6XXX_IQK_RXRC
1155 + SSV6XXX_IQK_TXDC
1156 + SSV6XXX_IQK_TXIQ
1157 + SSV6XXX_IQK_RXIQ
1158 },
1159 };
ssv_cmd_iqk(int argc,char * argv[])1160 static int ssv_cmd_iqk (int argc, char *argv[]) {
1161 char temp_str[512], *endp;
1162 struct sk_buff *skb;
1163 struct cfg_host_cmd *host_cmd;
1164 u32 rxcnt_total, rxcnt_error;
1165 sprintf(temp_str,"# got iqk command\n");
1166 strcat(ssv6xxx_result_buf, temp_str);
1167 if ((argc == 3) && (strcmp(argv[1], "cfg-pa") == 0)) {
1168 cmd_iqk_cfg.cfg_pa = simple_strtoul(argv[2], &endp, 0);
1169 sprintf(temp_str,"## set cfg_pa as %d\n", cmd_iqk_cfg.cfg_pa);
1170 strcat(ssv6xxx_result_buf, temp_str);
1171 return 0;
1172 }
1173 else if ((argc == 3) && (strcmp(argv[1], "cfg-tssi-trgt") == 0)) {
1174 cmd_iqk_cfg.cfg_tssi_trgt = simple_strtoul(argv[2], &endp, 0);
1175 sprintf(temp_str,"## set cfg_tssi_trgt as %d\n", cmd_iqk_cfg.cfg_tssi_trgt);
1176 strcat(ssv6xxx_result_buf, temp_str);
1177 return 0;
1178 }
1179 else if ((argc == 3) && (strcmp(argv[1], "init-cali") == 0)) {
1180 cmd_iqk_cfg.cmd_sel = SSV6XXX_IQK_CMD_INIT_CALI;
1181 cmd_iqk_cfg.fx_sel = simple_strtoul(argv[2], &endp, 0);
1182 sprintf(temp_str,"## do init-cali\n");
1183 strcat(ssv6xxx_result_buf, temp_str);
1184 }
1185 else if ((argc == 3) && (strcmp(argv[1], "rtbl-load") == 0)) {
1186 cmd_iqk_cfg.cmd_sel = SSV6XXX_IQK_CMD_RTBL_LOAD;
1187 cmd_iqk_cfg.fx_sel = simple_strtoul(argv[2], &endp, 0);
1188 sprintf(temp_str,"## do rtbl-load\n");
1189 strcat(ssv6xxx_result_buf, temp_str);
1190 }
1191 else if ((argc == 3) && (strcmp(argv[1], "rtbl-load-def") == 0)) {
1192 cmd_iqk_cfg.cmd_sel = SSV6XXX_IQK_CMD_RTBL_LOAD_DEF;
1193 cmd_iqk_cfg.fx_sel = simple_strtoul(argv[2], &endp, 0);
1194 sprintf(temp_str,"## do rtbl-load\n");
1195 strcat(ssv6xxx_result_buf, temp_str);
1196 }
1197 else if ((argc == 3) && (strcmp(argv[1], "rtbl-reset") == 0)) {
1198 cmd_iqk_cfg.cmd_sel = SSV6XXX_IQK_CMD_RTBL_RESET;
1199 cmd_iqk_cfg.fx_sel = simple_strtoul(argv[2], &endp, 0);
1200 sprintf(temp_str,"## do rtbl-reset\n");
1201 strcat(ssv6xxx_result_buf, temp_str);
1202 }
1203 else if ((argc == 3) && (strcmp(argv[1], "rtbl-set") == 0)) {
1204 cmd_iqk_cfg.cmd_sel = SSV6XXX_IQK_CMD_RTBL_SET;
1205 cmd_iqk_cfg.fx_sel = simple_strtoul(argv[2], &endp, 0);
1206 sprintf(temp_str,"## do rtbl-set\n");
1207 strcat(ssv6xxx_result_buf, temp_str);
1208 }
1209 else if ((argc == 3) && (strcmp(argv[1], "rtbl-export") == 0)) {
1210 cmd_iqk_cfg.cmd_sel = SSV6XXX_IQK_CMD_RTBL_EXPORT;
1211 cmd_iqk_cfg.fx_sel = simple_strtoul(argv[2], &endp, 0);
1212 sprintf(temp_str,"## do rtbl-export\n");
1213 strcat(ssv6xxx_result_buf, temp_str);
1214 }
1215 else if ((argc == 3) && (strcmp(argv[1], "tk-evm") == 0)) {
1216 cmd_iqk_cfg.cmd_sel = SSV6XXX_IQK_CMD_TK_EVM;
1217 cmd_iqk_cfg.argv = simple_strtoul(argv[2], &endp, 0);
1218 sprintf(temp_str,"## do tk-evm\n");
1219 strcat(ssv6xxx_result_buf, temp_str);
1220 }
1221 else if ((argc == 3) && (strcmp(argv[1], "tk-tone") == 0)) {
1222 cmd_iqk_cfg.cmd_sel = SSV6XXX_IQK_CMD_TK_TONE;
1223 cmd_iqk_cfg.argv = simple_strtoul(argv[2], &endp, 0);
1224 sprintf(temp_str,"## do tk-tone\n");
1225 strcat(ssv6xxx_result_buf, temp_str);
1226 }
1227 else if ((argc == 3) && (strcmp(argv[1], "channel") == 0)) {
1228 cmd_iqk_cfg.cmd_sel = SSV6XXX_IQK_CMD_TK_CHCH;
1229 cmd_iqk_cfg.argv = simple_strtoul(argv[2], &endp, 0);
1230 sprintf(temp_str,"## do change channel\n");
1231 strcat(ssv6xxx_result_buf, temp_str);
1232 }
1233 else if ((argc == 2) && (strcmp(argv[1], "tk-rxcnt-report") == 0)) {
1234 if(SSV_REG_READ1(ssv6xxx_debug_ifops, 0xCE0043E8, &rxcnt_error));
1235 if(SSV_REG_READ1(ssv6xxx_debug_ifops, 0xCE0043EC, &rxcnt_total));
1236 sprintf(temp_str,"## GN Rx error rate = (%06d/%06d)\n", rxcnt_error, rxcnt_total);
1237 strcat(ssv6xxx_result_buf, temp_str);
1238 if(SSV_REG_READ1(ssv6xxx_debug_ifops, 0xCE0023E8, &rxcnt_error));
1239 if(SSV_REG_READ1(ssv6xxx_debug_ifops, 0xCE0023EC, &rxcnt_total));
1240 sprintf(temp_str,"## B Rx error rate = (%06d/%06d)\n", rxcnt_error, rxcnt_total);
1241 strcat(ssv6xxx_result_buf, temp_str);
1242 return 0;
1243 }
1244 else {
1245 sprintf(temp_str,"## invalid iqk command\n");
1246 strcat(ssv6xxx_result_buf, temp_str);
1247 sprintf(temp_str,"## cmd: cfg-pa/cfg-tssi-trgt\n");
1248 strcat(ssv6xxx_result_buf, temp_str);
1249 sprintf(temp_str,"## cmd: init-cali/rtbl-load/rtbl-load-def/rtbl-reset/rtbl-set/rtbl-export/tk-evm/tk-tone/tk-channel\n");
1250 strcat(ssv6xxx_result_buf, temp_str);
1251 sprintf(temp_str,"## fx_sel: 0x0008: RXDC\n");
1252 strcat(ssv6xxx_result_buf, temp_str);
1253 sprintf(temp_str," 0x0010: RXRC\n");
1254 strcat(ssv6xxx_result_buf, temp_str);
1255 sprintf(temp_str," 0x0020: TXDC\n");
1256 strcat(ssv6xxx_result_buf, temp_str);
1257 sprintf(temp_str," 0x0040: TXIQ\n");
1258 strcat(ssv6xxx_result_buf, temp_str);
1259 sprintf(temp_str," 0x0080: RXIQ\n");
1260 strcat(ssv6xxx_result_buf, temp_str);
1261 sprintf(temp_str," 0x0100: TSSI\n");
1262 strcat(ssv6xxx_result_buf, temp_str);
1263 sprintf(temp_str," 0x0200: PAPD\n");
1264 strcat(ssv6xxx_result_buf, temp_str);
1265 return 0;
1266 }
1267 skb = ssvdevice_skb_alloc(HOST_CMD_HDR_LEN + IQK_CFG_LEN + PHY_SETTING_SIZE + RF_SETTING_SIZE);
1268 if(skb == NULL)
1269 {
1270 printk("ssv command ssvdevice_skb_alloc fail!!!\n");
1271 return 0;
1272 }
1273 if((PHY_SETTING_SIZE > MAX_PHY_SETTING_TABLE_SIZE) ||
1274 (RF_SETTING_SIZE > MAX_RF_SETTING_TABLE_SIZE))
1275 {
1276 printk("Please check RF or PHY table size!!!\n");
1277 BUG_ON(1);
1278 return 0;
1279 }
1280 skb->data_len = HOST_CMD_HDR_LEN + IQK_CFG_LEN + PHY_SETTING_SIZE + RF_SETTING_SIZE;
1281 skb->len = skb->data_len;
1282 host_cmd = (struct cfg_host_cmd *)skb->data;
1283 host_cmd->c_type = HOST_CMD;
1284 host_cmd->h_cmd = (u8)SSV6XXX_HOST_CMD_INIT_CALI;
1285 host_cmd->len = skb->data_len;
1286 cmd_iqk_cfg.phy_tbl_size = PHY_SETTING_SIZE;
1287 cmd_iqk_cfg.rf_tbl_size = RF_SETTING_SIZE;
1288 memcpy(host_cmd->dat32, &cmd_iqk_cfg, IQK_CFG_LEN);
1289 memcpy(host_cmd->dat8+IQK_CFG_LEN, phy_setting, PHY_SETTING_SIZE);
1290 memcpy(host_cmd->dat8+IQK_CFG_LEN+PHY_SETTING_SIZE, asic_rf_setting, RF_SETTING_SIZE);
1291 if(ssv_dbg_ctrl_hci->shi->hci_ops->hci_send_cmd(skb) == 0) {
1292 sprintf(temp_str,"## hci send cmd success\n");
1293 strcat(ssv6xxx_result_buf, temp_str);
1294 }
1295 else {
1296 sprintf(temp_str,"## hci send cmd fail\n");
1297 strcat(ssv6xxx_result_buf, temp_str);
1298 }
1299 ssvdevice_skb_free(skb);
1300 return 0;
1301 }
1302 #endif
1303 #define LBYTESWAP(a) ((((a) & 0x00ff00ff) << 8) | \
1304 (((a) & 0xff00ff00) >> 8))
1305 #define LONGSWAP(a) ((LBYTESWAP(a) << 16) | (LBYTESWAP(a) >> 16))
ssv_cmd_version(int argc,char * argv[])1306 static int ssv_cmd_version (int argc, char *argv[]) {
1307 char temp_str[256];
1308 u32 regval;
1309 u64 chip_tag=0;
1310 char chip_id[24]="";
1311 if(SSV_REG_READ1(ssv6xxx_debug_ifops, ADR_IC_TIME_TAG_1, ®val));
1312 chip_tag = ((u64)regval<<32);
1313 if(SSV_REG_READ1(ssv6xxx_debug_ifops, ADR_IC_TIME_TAG_0, ®val));
1314 chip_tag |= (regval);
1315 sprintf(temp_str,"CHIP TAG: %llx \n",chip_tag);
1316 strcat(ssv6xxx_result_buf, temp_str);
1317 if(SSV_REG_READ1(ssv6xxx_debug_ifops, ADR_CHIP_ID_3, ®val));
1318 *((u32 *)&chip_id[0]) = (u32)LONGSWAP(regval);
1319 if(SSV_REG_READ1(ssv6xxx_debug_ifops, ADR_CHIP_ID_2, ®val));
1320 *((u32 *)&chip_id[4]) = (u32)LONGSWAP(regval);
1321 if(SSV_REG_READ1(ssv6xxx_debug_ifops, ADR_CHIP_ID_1, ®val));
1322 *((u32 *)&chip_id[8]) = (u32)LONGSWAP(regval);
1323 if(SSV_REG_READ1(ssv6xxx_debug_ifops, ADR_CHIP_ID_0, ®val));
1324 *((u32 *)&chip_id[12]) = (u32)LONGSWAP(regval);
1325 sprintf(temp_str,"CHIP ID: %s \n",chip_id);
1326 strcat(ssv6xxx_result_buf, temp_str);
1327 sprintf(temp_str,"# current Software mac version: %d\n", ssv_root_version);
1328 strcat(ssv6xxx_result_buf, temp_str);
1329 sprintf(temp_str,"SVN ROOT URL %s \n", SSV_ROOT_URl);
1330 strcat(ssv6xxx_result_buf, temp_str);
1331 sprintf(temp_str,"COMPILER HOST %s \n", COMPILERHOST);
1332 strcat(ssv6xxx_result_buf, temp_str);
1333 sprintf(temp_str,"COMPILER DATE %s \n", COMPILERDATE);
1334 strcat(ssv6xxx_result_buf, temp_str);
1335 sprintf(temp_str,"COMPILER OS %s \n", COMPILEROS);
1336 strcat(ssv6xxx_result_buf, temp_str);
1337 sprintf(temp_str,"COMPILER OS ARCH %s \n", COMPILEROSARCH);
1338 strcat(ssv6xxx_result_buf, temp_str);
1339 if(SSV_REG_READ1(ssv6xxx_debug_ifops, FW_VERSION_REG, ®val));
1340 sprintf(temp_str,"Firmware image version: %d\n", regval);
1341 strcat(ssv6xxx_result_buf, temp_str);
1342 sprintf(temp_str,"\n[Compiler Option!!]\n");
1343 strcat(ssv6xxx_result_buf, temp_str);
1344 regval = sizeof(conf_parser)/ sizeof(*conf_parser);
1345 while(regval)
1346 {
1347 sprintf(temp_str,"Define %s \n", conf_parser[--regval]);
1348 strcat(ssv6xxx_result_buf, temp_str);
1349 };
1350 return 0;
1351 }
ssv_cmd_tool(int argc,char * argv[])1352 static int ssv_cmd_tool(int argc, char *argv[])
1353 {
1354 u32 addr, value, count;
1355 char tmpbf[12], *endp;
1356 int s;
1357 if (argc == 4 && strcmp(argv[1], "w")==0) {
1358 addr = simple_strtoul(argv[2], &endp, 16);
1359 value = simple_strtoul(argv[3], &endp, 16);
1360 if(SSV_REG_WRITE1(ssv6xxx_debug_ifops, addr, value));
1361 sprintf(ssv6xxx_result_buf, "ok");
1362 return 0;
1363 }
1364 if ((argc==4||argc==3) && strcmp(argv[1], "r")==0) {
1365 count = (argc==3)? 1: simple_strtoul(argv[3], &endp, 10);
1366 addr = simple_strtoul(argv[2], &endp, 16);
1367 for(s=0; s<count; s++, addr+=4) {
1368 if(SSV_REG_READ1(ssv6xxx_debug_ifops, addr, &value));
1369 sprintf(tmpbf, "%08x\n", value);
1370 strcat(ssv6xxx_result_buf, tmpbf);
1371 }
1372 return 0;
1373 }
1374 return -1;
1375 }
1376 struct _ssv6xxx_txtput{
1377 struct task_struct *txtput_tsk;
1378 struct sk_buff *skb;
1379 u32 size_per_frame;
1380 u32 loop_times;
1381 u32 occupied_tx_pages;
1382 };
1383 struct _ssv6xxx_txtput *ssv6xxx_txtput;
1384 struct _ssv6xxx_txtput ssv_txtput = { NULL, NULL, 0, 0, 0};
txtput_thread_m2(void * data)1385 static int txtput_thread_m2(void *data)
1386 {
1387 #define Q_DELAY_MS 20
1388 struct sk_buff *skb = NULL;
1389 struct ssv6200_tx_desc *tx_desc;
1390 int qlen = 0, max_qlen, q_delay_urange[2];
1391 max_qlen = (200 * 1000 / 8 * Q_DELAY_MS) / ssv6xxx_txtput->size_per_frame;
1392 q_delay_urange[0] = Q_DELAY_MS * 1000;
1393 q_delay_urange[1] = q_delay_urange[0] + 1000;
1394 printk("max_qlen: %d\n", max_qlen);
1395 while (!kthread_should_stop() && ssv6xxx_txtput->loop_times > 0) {
1396 ssv6xxx_txtput->loop_times--;
1397 skb = ssvdevice_skb_alloc(ssv6xxx_txtput->size_per_frame);
1398 if (skb == NULL) {
1399 printk("ssv command txtput_generate_m2 "
1400 "ssvdevice_skb_alloc fail!!!\n");
1401 goto end;
1402 }
1403 skb->data_len = ssv6xxx_txtput->size_per_frame;
1404 skb->len = ssv6xxx_txtput->size_per_frame;
1405 tx_desc = (struct ssv6200_tx_desc *)skb->data;
1406 memset((void *)tx_desc, 0xff, SSV6XXX_TX_DESC_LEN);
1407 tx_desc->len = skb->len;
1408 tx_desc->c_type = M2_TXREQ;
1409 tx_desc->fCmd = (M_ENG_CPU << 4) | M_ENG_HWHCI;
1410 tx_desc->reason = ID_TRAP_SW_TXTPUT;
1411 qlen = ssv_dbg_ctrl_hci->shi->hci_ops->hci_tx(skb, 0, 0);
1412 if (qlen >= max_qlen) {
1413 usleep_range(q_delay_urange[0], q_delay_urange[1]);
1414 }
1415 }
1416 end:
1417 ssv6xxx_txtput->txtput_tsk = NULL;
1418 return 0;
1419 }
txtput_thread(void * data)1420 static int txtput_thread(void *data)
1421 {
1422 struct sk_buff *skb = ssv6xxx_txtput->skb;
1423 struct ssv6xxx_hci_txq_info2 txq_info2;
1424 u32 ret = 0, free_tx_page;
1425 int send_cnt;
1426 unsigned long start_time, end_time, throughput, time_elapse;
1427 throughput = ssv6xxx_txtput->loop_times * ssv6xxx_txtput->size_per_frame * 8;
1428 start_time = jiffies;
1429 while (!kthread_should_stop() && ssv6xxx_txtput->loop_times > 0) {
1430 ret = SSV_REG_READ1(ssv6xxx_debug_ifops, ADR_TX_ID_ALL_INFO2, (u32 *)&txq_info2);
1431 if (ret < 0) {
1432 printk("%s, read ADR_TX_ID_ALL_INFO2 failed\n", __func__);
1433 goto end;
1434 }
1435 free_tx_page = SSV6200_PAGE_TX_THRESHOLD - txq_info2.tx_use_page;
1436 send_cnt = free_tx_page / ssv6xxx_txtput->occupied_tx_pages;
1437 while (send_cnt > 0 && ssv6xxx_txtput->loop_times > 0) {
1438 send_cnt--;
1439 ssv6xxx_txtput->loop_times--;
1440 ssv_dbg_ctrl_hci->shi->hci_ops->hci_send_cmd(skb);
1441 }
1442 }
1443 end_time = jiffies;
1444 ssvdevice_skb_free(skb);
1445 time_elapse = ((end_time - start_time) * 1000) / HZ;
1446 if (time_elapse > 0) {
1447 throughput = throughput / time_elapse;
1448 printk("duration %ldms, avg. throughput %d Kbps\n", time_elapse, (int)throughput);
1449 }
1450 end:
1451 ssv6xxx_txtput->txtput_tsk = NULL;
1452 return 0;
1453 }
txtput_generate_m2(u32 size_per_frame,u32 loop_times)1454 int txtput_generate_m2(u32 size_per_frame, u32 loop_times)
1455 {
1456 ssv6xxx_txtput->size_per_frame = size_per_frame;
1457 ssv6xxx_txtput->loop_times = loop_times;
1458 ssv6xxx_txtput->txtput_tsk = kthread_run(txtput_thread_m2, NULL, "txtput_thread_m2");
1459 return 0;
1460 }
txtput_generate_host_cmd(u32 size_per_frame,u32 loop_times)1461 int txtput_generate_host_cmd(u32 size_per_frame, u32 loop_times)
1462 {
1463 #define PAGESIZE 256
1464 struct cfg_host_cmd *host_cmd;
1465 struct sk_buff *skb;
1466 skb = ssvdevice_skb_alloc(size_per_frame);
1467 if(skb == NULL) {
1468 printk("ssv command txtput_generate_host_cmd ssvdevice_skb_alloc fail!!!\n");
1469 return 0;
1470 }
1471 skb->data_len = size_per_frame;
1472 skb->len = skb->data_len;
1473 host_cmd = (struct cfg_host_cmd *)skb->data;
1474 host_cmd->c_type = TEST_CMD;
1475 host_cmd->h_cmd = (u8)SSV6XXX_HOST_CMD_TX_TPUT;
1476 host_cmd->len = skb->data_len;
1477 memcpy(host_cmd->dat32, skb->data, size_per_frame);
1478 ssv6xxx_txtput->occupied_tx_pages = (size_per_frame/PAGESIZE)+((size_per_frame%PAGESIZE)!=0);
1479 ssv6xxx_txtput->size_per_frame = size_per_frame;
1480 ssv6xxx_txtput->loop_times = loop_times;
1481 ssv6xxx_txtput->skb = skb;
1482 ssv6xxx_txtput->txtput_tsk = kthread_run(txtput_thread, NULL, "txtput_thread");
1483 return 0 ;
1484 }
txtput_tsk_cleanup(void)1485 int txtput_tsk_cleanup(void)
1486 {
1487 int ret = 0;
1488 if (ssv6xxx_txtput->txtput_tsk) {
1489 ret = kthread_stop(ssv6xxx_txtput->txtput_tsk);
1490 ssv6xxx_txtput->txtput_tsk = NULL;
1491 }
1492 return ret;
1493 }
watchdog_controller(struct ssv_hw * sh,u8 flag)1494 int watchdog_controller(struct ssv_hw *sh ,u8 flag)
1495 {
1496 struct sk_buff *skb;
1497 struct cfg_host_cmd *host_cmd;
1498 int ret = 0;
1499 printk("watchdog_controller %d\n",flag);
1500 skb = ssvdevice_skb_alloc(HOST_CMD_HDR_LEN);
1501 if(skb == NULL)
1502 {
1503 printk("init watchdog_controller fail!!!\n");
1504 return (-1);
1505 }
1506 skb->data_len = HOST_CMD_HDR_LEN;
1507 skb->len = skb->data_len;
1508 host_cmd = (struct cfg_host_cmd *)skb->data;
1509 host_cmd->c_type = HOST_CMD;
1510 host_cmd->h_cmd = (u8)flag;
1511 host_cmd->len = skb->data_len;
1512 sh->hci.hci_ops->hci_send_cmd(skb);
1513 ssvdevice_skb_free(skb);
1514 return ret;
1515 }
ssv_cmd_txtput(int argc,char * argv[])1516 static int ssv_cmd_txtput(int argc, char *argv[])
1517 {
1518 char tmpbf[64], *endp;
1519 u32 size_per_frame, loop_times, pkt_type;
1520 ssv6xxx_txtput = &ssv_txtput;
1521 if (argc == 2 && !strcmp(argv[1], "stop")) {
1522 txtput_tsk_cleanup();
1523 return 0;
1524 }
1525 if (argc != 4) {
1526 sprintf(tmpbf, "* txtput stop\n");
1527 strcat(ssv6xxx_result_buf, tmpbf);
1528 sprintf(tmpbf, "* txtput [type] [size] [frames]\n");
1529 strcat(ssv6xxx_result_buf, tmpbf);
1530 sprintf(tmpbf, " type(packet type):\n");
1531 strcat(ssv6xxx_result_buf, tmpbf);
1532 sprintf(tmpbf, " 0 = host_cmd\n");
1533 strcat(ssv6xxx_result_buf, tmpbf);
1534 sprintf(tmpbf, " 1 = m2_type \n");
1535 strcat(ssv6xxx_result_buf, tmpbf);
1536 sprintf(tmpbf, " EX: txtput 1 14000 9999 \n");
1537 strcat(ssv6xxx_result_buf, tmpbf);
1538 return 0;
1539 }
1540 pkt_type = simple_strtoul(argv[1], &endp, 10);
1541 size_per_frame = simple_strtoul(argv[2], &endp, 10);
1542 loop_times = simple_strtoul(argv[3], &endp, 10);
1543 sprintf(tmpbf, "type&size&frames:%d&%d&%d\n", pkt_type, size_per_frame, loop_times);
1544 strncat(ssv6xxx_result_buf, tmpbf, sizeof(tmpbf));
1545 if (ssv6xxx_txtput->txtput_tsk) {
1546 sprintf(tmpbf, "txtput already in progress\n");
1547 strcat(ssv6xxx_result_buf, tmpbf);
1548 return 0;
1549 }
1550 watchdog_controller(((struct ssv_softc *)ssv_dbg_sc)->sh ,(u8)SSV6XXX_HOST_CMD_WATCHDOG_STOP);
1551 ((struct ssv_softc *)ssv_dbg_sc)->watchdog_flag = WD_SLEEP;
1552 if (pkt_type)
1553 txtput_generate_m2(size_per_frame + SSV6XXX_TX_DESC_LEN, loop_times);
1554 else
1555 txtput_generate_host_cmd(size_per_frame + HOST_CMD_HDR_LEN, loop_times);
1556 return 0;
1557 }
ssv_cmd_rxtput(int argc,char * argv[])1558 static int ssv_cmd_rxtput(int argc, char *argv[])
1559 {
1560 struct sk_buff *skb;
1561 struct cfg_host_cmd *host_cmd;
1562 struct sdio_rxtput_cfg cmd_rxtput_cfg;
1563 char tmpbf[32], *endp;
1564 if (argc != 3) {
1565 sprintf(ssv6xxx_result_buf, "rxtput [size] [frames]\n");
1566 return 0;
1567 }
1568 skb = ssvdevice_skb_alloc(HOST_CMD_HDR_LEN + sizeof(struct sdio_rxtput_cfg));
1569 if(skb == NULL)
1570 {
1571 printk("ssv command ssvdevice_skb_alloc fail!!!\n");
1572 return 0;
1573 }
1574 watchdog_controller(((struct ssv_softc *)ssv_dbg_sc)->sh ,(u8)SSV6XXX_HOST_CMD_WATCHDOG_STOP);
1575 ((struct ssv_softc *)ssv_dbg_sc)->watchdog_flag = WD_SLEEP;
1576 cmd_rxtput_cfg.size_per_frame = simple_strtoul(argv[1], &endp, 10);
1577 cmd_rxtput_cfg.total_frames = simple_strtoul(argv[2], &endp, 10);
1578 sprintf(tmpbf, "size&frames:%d&%d\n", cmd_rxtput_cfg.size_per_frame, cmd_rxtput_cfg.total_frames);
1579 strcat(ssv6xxx_result_buf, tmpbf);
1580 skb->data_len = HOST_CMD_HDR_LEN + sizeof(struct sdio_rxtput_cfg);
1581 skb->len = skb->data_len;
1582 host_cmd = (struct cfg_host_cmd *)skb->data;
1583 host_cmd->c_type = HOST_CMD;
1584 host_cmd->h_cmd = (u8)SSV6XXX_HOST_CMD_RX_TPUT;
1585 host_cmd->len = skb->data_len;
1586 memcpy(host_cmd->dat32, &cmd_rxtput_cfg, sizeof(struct sdio_rxtput_cfg));
1587 if(ssv_dbg_ctrl_hci->shi->hci_ops->hci_send_cmd(skb) == 0) {
1588 strcat(ssv6xxx_result_buf, "## hci cmd was sent successfully\n");
1589 }
1590 else {
1591 strcat(ssv6xxx_result_buf, "## hci cmd was sent failed\n");
1592 }
1593 ssvdevice_skb_free(skb);
1594 return 0;
1595 }
ssv_cmd_check(int argc,char * argv[])1596 static int ssv_cmd_check(int argc, char *argv[])
1597 {
1598 u32 size,i,j,x,y,id,value,address,id_value;
1599 char *endp;
1600 u32 id_base_address[4];
1601 id_base_address[0] = 0xcd010008;
1602 id_base_address[1] = 0xcd01000c;
1603 id_base_address[2] = 0xcd010054;
1604 id_base_address[3] = 0xcd010058;
1605 if (argc != 2) {
1606 sprintf(ssv6xxx_result_buf, "check [packet size]\n");
1607 return 0;
1608 }
1609 size = simple_strtoul(argv[1], &endp, 10);
1610 size = size >> 2;
1611 for(x=0;x<4;x++)
1612 {
1613 if(SSV_REG_READ1(ssv6xxx_debug_ifops, id_base_address[x], &id_value));
1614 for(y=0;y<32 && id_value;y++,id_value>>=1)
1615 {
1616 if(id_value&0x1)
1617 {
1618 id = 32*x + y;
1619 address = 0x80000000 + (id<<16);
1620 {
1621 printk(" ");
1622 for (i= 0;i<size;i+=8)
1623 {
1624 if(SSV_REG_READ1(ssv6xxx_debug_ifops, address, &value));
1625 printk("\n%08X:%08X", address,value);
1626 address += 4;
1627 for (j = 1; j < 8; j++)
1628 {
1629 if(SSV_REG_READ1(ssv6xxx_debug_ifops, address, &value));
1630 printk(" %08X", value);
1631 address += 4;
1632 }
1633 }
1634 printk("\n");
1635 }
1636 }
1637 }
1638 }
1639 return 0;
1640 }
1641 struct ssv_cmd_table cmd_table[] = {
1642 { "help", ssv_cmd_help, "ssv6200 command usage." },
1643 { "-h", ssv_cmd_help, "ssv6200 command usage." },
1644 { "--help", ssv_cmd_help, "ssv6200 command usage." },
1645 { "reg", ssv_cmd_reg, "ssv6200 register read/write." },
1646 { "cfg", ssv_cmd_cfg, "ssv6200 configuration." },
1647 { "sta", ssv_cmd_sta, "svv6200 station info." },
1648 { "dump", ssv_cmd_dump, "dump ssv6200 tables." },
1649 { "hwq", ssv_cmd_hwq, "hardware queue staus" },
1650 #ifdef CONFIG_P2P_NOA
1651 { "noa", ssv_cmd_noa, "config noa param" },
1652 #endif
1653 { "irq", ssv_cmd_irq, "get sdio irq status." },
1654 { "mac", ssv_cmd_mac, "ieee80211 swmac." },
1655 { "hci", ssv_cmd_hci, "HCI command." },
1656 { "sdio", ssv_cmd_sdio, "SDIO command." },
1657 #ifdef CONFIG_SSV_CABRIO_E
1658 { "iqk", ssv_cmd_iqk, "iqk command" },
1659 #endif
1660 { "version",ssv_cmd_version,"version information" },
1661 { "mib", ssv_cmd_mib, "mib counter related" },
1662 { "tool", ssv_cmd_tool, "ssv6200 tool register read/write." },
1663 { "rxtput", ssv_cmd_rxtput, "test rx sdio throughput" },
1664 { "txtput", ssv_cmd_txtput, "test tx sdio throughput" },
1665 { "check", ssv_cmd_check, "dump all allocate packet buffer" },
1666 { NULL, NULL, NULL },
1667 };
ssv_cmd_submit(char * cmd)1668 int ssv_cmd_submit(char *cmd)
1669 {
1670 struct ssv_cmd_table *sc_tbl;
1671 char *pch, ch;
1672 int ret;
1673 ssv6xxx_debug_ifops = (void *)ssv6xxx_ifdebug_info;
1674 strcpy(sg_cmd_buffer, cmd);
1675 for( sg_argc=0,ch=0, pch=sg_cmd_buffer;
1676 (*pch!=0x00)&&(sg_argc<CLI_ARG_SIZE); pch++ )
1677 {
1678 if ( (ch==0) && (*pch!=' ') )
1679 {
1680 ch = 1;
1681 sg_argv[sg_argc] = pch;
1682 }
1683 if ( (ch==1) && (*pch==' ') )
1684 {
1685 *pch = 0x00;
1686 ch = 0;
1687 sg_argc ++;
1688 }
1689 }
1690 if ( ch == 1)
1691 {
1692 sg_argc ++;
1693 }
1694 else if ( sg_argc > 0 )
1695 {
1696 *(pch-1) = ' ';
1697 }
1698 if ( sg_argc > 0 )
1699 {
1700 for( sc_tbl=cmd_table; sc_tbl->cmd; sc_tbl ++ )
1701 {
1702 if ( !strcmp(sg_argv[0], sc_tbl->cmd) )
1703 {
1704 if( (sc_tbl->cmd_func_ptr != ssv_cmd_cfg) &&
1705 (!ssv6xxx_debug_ifops->dev||
1706 !ssv6xxx_debug_ifops->ifops||
1707 !ssv6xxx_debug_ifops->pdev))
1708 {
1709 strcpy(ssv6xxx_result_buf, "Member of ssv6xxx_ifdebug_info is NULL !\n");
1710 return -1;
1711 }
1712 ssv6xxx_result_buf[0] = 0x00;
1713 ret = sc_tbl->cmd_func_ptr(sg_argc, sg_argv);
1714 if (ret < 0) {
1715 strcpy(ssv6xxx_result_buf, "Invalid command !\n");
1716 }
1717 return 0;
1718 }
1719 }
1720 strcpy(ssv6xxx_result_buf, "Command not found !\n");
1721 }
1722 else
1723 {
1724 strcpy(ssv6xxx_result_buf, "./cli -h\n");
1725 }
1726 return 0;
1727 }
1728