xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/ssv6xxx/ssvdevice/ssv_cmd.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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], &regval));
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, &regval));
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, &regval));
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, &regval));
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, &regval));
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, &regval));
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, &regval));
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, &regval));
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, &regval));
1312     chip_tag = ((u64)regval<<32);
1313     if(SSV_REG_READ1(ssv6xxx_debug_ifops, ADR_IC_TIME_TAG_0, &regval));
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, &regval));
1318     *((u32 *)&chip_id[0]) = (u32)LONGSWAP(regval);
1319     if(SSV_REG_READ1(ssv6xxx_debug_ifops, ADR_CHIP_ID_2, &regval));
1320     *((u32 *)&chip_id[4]) = (u32)LONGSWAP(regval);
1321     if(SSV_REG_READ1(ssv6xxx_debug_ifops, ADR_CHIP_ID_1, &regval));
1322     *((u32 *)&chip_id[8]) = (u32)LONGSWAP(regval);
1323     if(SSV_REG_READ1(ssv6xxx_debug_ifops, ADR_CHIP_ID_0, &regval));
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, &regval));
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