0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/debugfs.h>
0009
0010 #include "main.h"
0011 #include "11n.h"
0012
0013
0014 static struct dentry *mwifiex_dfs_dir;
0015
0016 static char *bss_modes[] = {
0017 "UNSPECIFIED",
0018 "ADHOC",
0019 "STATION",
0020 "AP",
0021 "AP_VLAN",
0022 "WDS",
0023 "MONITOR",
0024 "MESH_POINT",
0025 "P2P_CLIENT",
0026 "P2P_GO",
0027 "P2P_DEVICE",
0028 };
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061 static ssize_t
0062 mwifiex_info_read(struct file *file, char __user *ubuf,
0063 size_t count, loff_t *ppos)
0064 {
0065 struct mwifiex_private *priv =
0066 (struct mwifiex_private *) file->private_data;
0067 struct net_device *netdev = priv->netdev;
0068 struct netdev_hw_addr *ha;
0069 struct netdev_queue *txq;
0070 unsigned long page = get_zeroed_page(GFP_KERNEL);
0071 char *p = (char *) page, fmt[64];
0072 struct mwifiex_bss_info info;
0073 ssize_t ret;
0074 int i = 0;
0075
0076 if (!p)
0077 return -ENOMEM;
0078
0079 memset(&info, 0, sizeof(info));
0080 ret = mwifiex_get_bss_info(priv, &info);
0081 if (ret)
0082 goto free_and_exit;
0083
0084 mwifiex_drv_get_driver_version(priv->adapter, fmt, sizeof(fmt) - 1);
0085
0086 mwifiex_get_ver_ext(priv, 0);
0087
0088 p += sprintf(p, "driver_name = " "\"mwifiex\"\n");
0089 p += sprintf(p, "driver_version = %s", fmt);
0090 p += sprintf(p, "\nverext = %s", priv->version_str);
0091 p += sprintf(p, "\ninterface_name=\"%s\"\n", netdev->name);
0092
0093 if (info.bss_mode >= ARRAY_SIZE(bss_modes))
0094 p += sprintf(p, "bss_mode=\"%d\"\n", info.bss_mode);
0095 else
0096 p += sprintf(p, "bss_mode=\"%s\"\n", bss_modes[info.bss_mode]);
0097
0098 p += sprintf(p, "media_state=\"%s\"\n",
0099 (!priv->media_connected ? "Disconnected" : "Connected"));
0100 p += sprintf(p, "mac_address=\"%pM\"\n", netdev->dev_addr);
0101
0102 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) {
0103 p += sprintf(p, "multicast_count=\"%d\"\n",
0104 netdev_mc_count(netdev));
0105 p += sprintf(p, "essid=\"%.*s\"\n", info.ssid.ssid_len,
0106 info.ssid.ssid);
0107 p += sprintf(p, "bssid=\"%pM\"\n", info.bssid);
0108 p += sprintf(p, "channel=\"%d\"\n", (int) info.bss_chan);
0109 p += sprintf(p, "country_code = \"%s\"\n", info.country_code);
0110 p += sprintf(p, "region_code=\"0x%x\"\n",
0111 priv->adapter->region_code);
0112
0113 netdev_for_each_mc_addr(ha, netdev)
0114 p += sprintf(p, "multicast_address[%d]=\"%pM\"\n",
0115 i++, ha->addr);
0116 }
0117
0118 p += sprintf(p, "num_tx_bytes = %lu\n", priv->stats.tx_bytes);
0119 p += sprintf(p, "num_rx_bytes = %lu\n", priv->stats.rx_bytes);
0120 p += sprintf(p, "num_tx_pkts = %lu\n", priv->stats.tx_packets);
0121 p += sprintf(p, "num_rx_pkts = %lu\n", priv->stats.rx_packets);
0122 p += sprintf(p, "num_tx_pkts_dropped = %lu\n", priv->stats.tx_dropped);
0123 p += sprintf(p, "num_rx_pkts_dropped = %lu\n", priv->stats.rx_dropped);
0124 p += sprintf(p, "num_tx_pkts_err = %lu\n", priv->stats.tx_errors);
0125 p += sprintf(p, "num_rx_pkts_err = %lu\n", priv->stats.rx_errors);
0126 p += sprintf(p, "carrier %s\n", ((netif_carrier_ok(priv->netdev))
0127 ? "on" : "off"));
0128 p += sprintf(p, "tx queue");
0129 for (i = 0; i < netdev->num_tx_queues; i++) {
0130 txq = netdev_get_tx_queue(netdev, i);
0131 p += sprintf(p, " %d:%s", i, netif_tx_queue_stopped(txq) ?
0132 "stopped" : "started");
0133 }
0134 p += sprintf(p, "\n");
0135
0136 ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page,
0137 (unsigned long) p - page);
0138
0139 free_and_exit:
0140 free_page(page);
0141 return ret;
0142 }
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165 static ssize_t
0166 mwifiex_getlog_read(struct file *file, char __user *ubuf,
0167 size_t count, loff_t *ppos)
0168 {
0169 struct mwifiex_private *priv =
0170 (struct mwifiex_private *) file->private_data;
0171 unsigned long page = get_zeroed_page(GFP_KERNEL);
0172 char *p = (char *) page;
0173 ssize_t ret;
0174 struct mwifiex_ds_get_stats stats;
0175
0176 if (!p)
0177 return -ENOMEM;
0178
0179 memset(&stats, 0, sizeof(stats));
0180 ret = mwifiex_get_stats_info(priv, &stats);
0181 if (ret)
0182 goto free_and_exit;
0183
0184 p += sprintf(p, "\n"
0185 "mcasttxframe %u\n"
0186 "failed %u\n"
0187 "retry %u\n"
0188 "multiretry %u\n"
0189 "framedup %u\n"
0190 "rtssuccess %u\n"
0191 "rtsfailure %u\n"
0192 "ackfailure %u\n"
0193 "rxfrag %u\n"
0194 "mcastrxframe %u\n"
0195 "fcserror %u\n"
0196 "txframe %u\n"
0197 "wepicverrcnt-1 %u\n"
0198 "wepicverrcnt-2 %u\n"
0199 "wepicverrcnt-3 %u\n"
0200 "wepicverrcnt-4 %u\n"
0201 "bcn_rcv_cnt %u\n"
0202 "bcn_miss_cnt %u\n",
0203 stats.mcast_tx_frame,
0204 stats.failed,
0205 stats.retry,
0206 stats.multi_retry,
0207 stats.frame_dup,
0208 stats.rts_success,
0209 stats.rts_failure,
0210 stats.ack_failure,
0211 stats.rx_frag,
0212 stats.mcast_rx_frame,
0213 stats.fcs_error,
0214 stats.tx_frame,
0215 stats.wep_icv_error[0],
0216 stats.wep_icv_error[1],
0217 stats.wep_icv_error[2],
0218 stats.wep_icv_error[3],
0219 stats.bcn_rcv_cnt,
0220 stats.bcn_miss_cnt);
0221
0222
0223 ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page,
0224 (unsigned long) p - page);
0225
0226 free_and_exit:
0227 free_page(page);
0228 return ret;
0229 }
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241 static ssize_t
0242 mwifiex_histogram_read(struct file *file, char __user *ubuf,
0243 size_t count, loff_t *ppos)
0244 {
0245 struct mwifiex_private *priv =
0246 (struct mwifiex_private *)file->private_data;
0247 ssize_t ret;
0248 struct mwifiex_histogram_data *phist_data;
0249 int i, value;
0250 unsigned long page = get_zeroed_page(GFP_KERNEL);
0251 char *p = (char *)page;
0252
0253 if (!p)
0254 return -ENOMEM;
0255
0256 if (!priv || !priv->hist_data)
0257 return -EFAULT;
0258 phist_data = priv->hist_data;
0259
0260 p += sprintf(p, "\n"
0261 "total samples = %d\n",
0262 atomic_read(&phist_data->num_samples));
0263
0264 p += sprintf(p,
0265 "rx rates (in Mbps): 0=1M 1=2M 2=5.5M 3=11M 4=6M 5=9M 6=12M\n"
0266 "7=18M 8=24M 9=36M 10=48M 11=54M 12-27=MCS0-15(BW20) 28-43=MCS0-15(BW40)\n");
0267
0268 if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info)) {
0269 p += sprintf(p,
0270 "44-53=MCS0-9(VHT:BW20) 54-63=MCS0-9(VHT:BW40) 64-73=MCS0-9(VHT:BW80)\n\n");
0271 } else {
0272 p += sprintf(p, "\n");
0273 }
0274
0275 for (i = 0; i < MWIFIEX_MAX_RX_RATES; i++) {
0276 value = atomic_read(&phist_data->rx_rate[i]);
0277 if (value)
0278 p += sprintf(p, "rx_rate[%02d] = %d\n", i, value);
0279 }
0280
0281 if (ISSUPP_11ACENABLED(priv->adapter->fw_cap_info)) {
0282 for (i = MWIFIEX_MAX_RX_RATES; i < MWIFIEX_MAX_AC_RX_RATES;
0283 i++) {
0284 value = atomic_read(&phist_data->rx_rate[i]);
0285 if (value)
0286 p += sprintf(p, "rx_rate[%02d] = %d\n",
0287 i, value);
0288 }
0289 }
0290
0291 for (i = 0; i < MWIFIEX_MAX_SNR; i++) {
0292 value = atomic_read(&phist_data->snr[i]);
0293 if (value)
0294 p += sprintf(p, "snr[%02ddB] = %d\n", i, value);
0295 }
0296 for (i = 0; i < MWIFIEX_MAX_NOISE_FLR; i++) {
0297 value = atomic_read(&phist_data->noise_flr[i]);
0298 if (value)
0299 p += sprintf(p, "noise_flr[%02ddBm] = %d\n",
0300 (int)(i-128), value);
0301 }
0302 for (i = 0; i < MWIFIEX_MAX_SIG_STRENGTH; i++) {
0303 value = atomic_read(&phist_data->sig_str[i]);
0304 if (value)
0305 p += sprintf(p, "sig_strength[-%02ddBm] = %d\n",
0306 i, value);
0307 }
0308
0309 ret = simple_read_from_buffer(ubuf, count, ppos, (char *)page,
0310 (unsigned long)p - page);
0311
0312 return ret;
0313 }
0314
0315 static ssize_t
0316 mwifiex_histogram_write(struct file *file, const char __user *ubuf,
0317 size_t count, loff_t *ppos)
0318 {
0319 struct mwifiex_private *priv = (void *)file->private_data;
0320
0321 if (priv && priv->hist_data)
0322 mwifiex_hist_data_reset(priv);
0323 return 0;
0324 }
0325
0326 static struct mwifiex_debug_info info;
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375 static ssize_t
0376 mwifiex_debug_read(struct file *file, char __user *ubuf,
0377 size_t count, loff_t *ppos)
0378 {
0379 struct mwifiex_private *priv =
0380 (struct mwifiex_private *) file->private_data;
0381 unsigned long page = get_zeroed_page(GFP_KERNEL);
0382 char *p = (char *) page;
0383 ssize_t ret;
0384
0385 if (!p)
0386 return -ENOMEM;
0387
0388 ret = mwifiex_get_debug_info(priv, &info);
0389 if (ret)
0390 goto free_and_exit;
0391
0392 p += mwifiex_debug_info_to_buffer(priv, p, &info);
0393
0394 ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page,
0395 (unsigned long) p - page);
0396
0397 free_and_exit:
0398 free_page(page);
0399 return ret;
0400 }
0401
0402 static u32 saved_reg_type, saved_reg_offset, saved_reg_value;
0403
0404
0405
0406
0407
0408
0409
0410
0411 static ssize_t
0412 mwifiex_regrdwr_write(struct file *file,
0413 const char __user *ubuf, size_t count, loff_t *ppos)
0414 {
0415 char *buf;
0416 int ret;
0417 u32 reg_type = 0, reg_offset = 0, reg_value = UINT_MAX;
0418
0419 buf = memdup_user_nul(ubuf, min(count, (size_t)(PAGE_SIZE - 1)));
0420 if (IS_ERR(buf))
0421 return PTR_ERR(buf);
0422
0423 sscanf(buf, "%u %x %x", ®_type, ®_offset, ®_value);
0424
0425 if (reg_type == 0 || reg_offset == 0) {
0426 ret = -EINVAL;
0427 goto done;
0428 } else {
0429 saved_reg_type = reg_type;
0430 saved_reg_offset = reg_offset;
0431 saved_reg_value = reg_value;
0432 ret = count;
0433 }
0434 done:
0435 kfree(buf);
0436 return ret;
0437 }
0438
0439
0440
0441
0442
0443
0444
0445
0446 static ssize_t
0447 mwifiex_regrdwr_read(struct file *file, char __user *ubuf,
0448 size_t count, loff_t *ppos)
0449 {
0450 struct mwifiex_private *priv =
0451 (struct mwifiex_private *) file->private_data;
0452 unsigned long addr = get_zeroed_page(GFP_KERNEL);
0453 char *buf = (char *) addr;
0454 int pos = 0, ret = 0;
0455 u32 reg_value;
0456
0457 if (!buf)
0458 return -ENOMEM;
0459
0460 if (!saved_reg_type) {
0461
0462 pos += snprintf(buf, PAGE_SIZE, "0");
0463 goto done;
0464 }
0465
0466 if (saved_reg_value != UINT_MAX) {
0467 ret = mwifiex_reg_write(priv, saved_reg_type, saved_reg_offset,
0468 saved_reg_value);
0469
0470 pos += snprintf(buf, PAGE_SIZE, "%u 0x%x 0x%x\n",
0471 saved_reg_type, saved_reg_offset,
0472 saved_reg_value);
0473
0474 ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
0475
0476 goto done;
0477 }
0478
0479 ret = mwifiex_reg_read(priv, saved_reg_type,
0480 saved_reg_offset, ®_value);
0481 if (ret) {
0482 ret = -EINVAL;
0483 goto done;
0484 }
0485
0486 pos += snprintf(buf, PAGE_SIZE, "%u 0x%x 0x%x\n", saved_reg_type,
0487 saved_reg_offset, reg_value);
0488
0489 ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
0490
0491 done:
0492 free_page(addr);
0493 return ret;
0494 }
0495
0496
0497
0498
0499
0500 static ssize_t
0501 mwifiex_debug_mask_read(struct file *file, char __user *ubuf,
0502 size_t count, loff_t *ppos)
0503 {
0504 struct mwifiex_private *priv =
0505 (struct mwifiex_private *)file->private_data;
0506 unsigned long page = get_zeroed_page(GFP_KERNEL);
0507 char *buf = (char *)page;
0508 size_t ret = 0;
0509 int pos = 0;
0510
0511 if (!buf)
0512 return -ENOMEM;
0513
0514 pos += snprintf(buf, PAGE_SIZE, "debug mask=0x%08x\n",
0515 priv->adapter->debug_mask);
0516 ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
0517
0518 free_page(page);
0519 return ret;
0520 }
0521
0522
0523
0524
0525
0526 static ssize_t
0527 mwifiex_debug_mask_write(struct file *file, const char __user *ubuf,
0528 size_t count, loff_t *ppos)
0529 {
0530 int ret;
0531 unsigned long debug_mask;
0532 struct mwifiex_private *priv = (void *)file->private_data;
0533 char *buf;
0534
0535 buf = memdup_user_nul(ubuf, min(count, (size_t)(PAGE_SIZE - 1)));
0536 if (IS_ERR(buf))
0537 return PTR_ERR(buf);
0538
0539 if (kstrtoul(buf, 0, &debug_mask)) {
0540 ret = -EINVAL;
0541 goto done;
0542 }
0543
0544 priv->adapter->debug_mask = debug_mask;
0545 ret = count;
0546 done:
0547 kfree(buf);
0548 return ret;
0549 }
0550
0551
0552
0553
0554 static ssize_t
0555 mwifiex_verext_write(struct file *file, const char __user *ubuf,
0556 size_t count, loff_t *ppos)
0557 {
0558 int ret;
0559 u32 versionstrsel;
0560 struct mwifiex_private *priv = (void *)file->private_data;
0561 char buf[16];
0562
0563 memset(buf, 0, sizeof(buf));
0564
0565 if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count)))
0566 return -EFAULT;
0567
0568 ret = kstrtou32(buf, 10, &versionstrsel);
0569 if (ret)
0570 return ret;
0571
0572 priv->versionstrsel = versionstrsel;
0573
0574 return count;
0575 }
0576
0577
0578
0579
0580
0581 static ssize_t
0582 mwifiex_verext_read(struct file *file, char __user *ubuf,
0583 size_t count, loff_t *ppos)
0584 {
0585 struct mwifiex_private *priv =
0586 (struct mwifiex_private *)file->private_data;
0587 char buf[256];
0588 int ret;
0589
0590 mwifiex_get_ver_ext(priv, priv->versionstrsel);
0591 ret = snprintf(buf, sizeof(buf), "version string: %s\n",
0592 priv->version_str);
0593
0594 return simple_read_from_buffer(ubuf, count, ppos, buf, ret);
0595 }
0596
0597
0598
0599
0600
0601 static ssize_t
0602 mwifiex_memrw_write(struct file *file, const char __user *ubuf, size_t count,
0603 loff_t *ppos)
0604 {
0605 int ret;
0606 char cmd;
0607 struct mwifiex_ds_mem_rw mem_rw;
0608 u16 cmd_action;
0609 struct mwifiex_private *priv = (void *)file->private_data;
0610 char *buf;
0611
0612 buf = memdup_user_nul(ubuf, min(count, (size_t)(PAGE_SIZE - 1)));
0613 if (IS_ERR(buf))
0614 return PTR_ERR(buf);
0615
0616 ret = sscanf(buf, "%c %x %x", &cmd, &mem_rw.addr, &mem_rw.value);
0617 if (ret != 3) {
0618 ret = -EINVAL;
0619 goto done;
0620 }
0621
0622 if ((cmd == 'r') || (cmd == 'R')) {
0623 cmd_action = HostCmd_ACT_GEN_GET;
0624 mem_rw.value = 0;
0625 } else if ((cmd == 'w') || (cmd == 'W')) {
0626 cmd_action = HostCmd_ACT_GEN_SET;
0627 } else {
0628 ret = -EINVAL;
0629 goto done;
0630 }
0631
0632 memcpy(&priv->mem_rw, &mem_rw, sizeof(mem_rw));
0633 if (mwifiex_send_cmd(priv, HostCmd_CMD_MEM_ACCESS, cmd_action, 0,
0634 &mem_rw, true))
0635 ret = -1;
0636 else
0637 ret = count;
0638
0639 done:
0640 kfree(buf);
0641 return ret;
0642 }
0643
0644
0645
0646
0647
0648 static ssize_t
0649 mwifiex_memrw_read(struct file *file, char __user *ubuf,
0650 size_t count, loff_t *ppos)
0651 {
0652 struct mwifiex_private *priv = (void *)file->private_data;
0653 unsigned long addr = get_zeroed_page(GFP_KERNEL);
0654 char *buf = (char *)addr;
0655 int ret, pos = 0;
0656
0657 if (!buf)
0658 return -ENOMEM;
0659
0660 pos += snprintf(buf, PAGE_SIZE, "0x%x 0x%x\n", priv->mem_rw.addr,
0661 priv->mem_rw.value);
0662 ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
0663
0664 free_page(addr);
0665 return ret;
0666 }
0667
0668 static u32 saved_offset = -1, saved_bytes = -1;
0669
0670
0671
0672
0673
0674
0675
0676
0677 static ssize_t
0678 mwifiex_rdeeprom_write(struct file *file,
0679 const char __user *ubuf, size_t count, loff_t *ppos)
0680 {
0681 char *buf;
0682 int ret = 0;
0683 int offset = -1, bytes = -1;
0684
0685 buf = memdup_user_nul(ubuf, min(count, (size_t)(PAGE_SIZE - 1)));
0686 if (IS_ERR(buf))
0687 return PTR_ERR(buf);
0688
0689 sscanf(buf, "%d %d", &offset, &bytes);
0690
0691 if (offset == -1 || bytes == -1) {
0692 ret = -EINVAL;
0693 goto done;
0694 } else {
0695 saved_offset = offset;
0696 saved_bytes = bytes;
0697 ret = count;
0698 }
0699 done:
0700 kfree(buf);
0701 return ret;
0702 }
0703
0704
0705
0706
0707
0708
0709
0710
0711 static ssize_t
0712 mwifiex_rdeeprom_read(struct file *file, char __user *ubuf,
0713 size_t count, loff_t *ppos)
0714 {
0715 struct mwifiex_private *priv =
0716 (struct mwifiex_private *) file->private_data;
0717 unsigned long addr = get_zeroed_page(GFP_KERNEL);
0718 char *buf = (char *) addr;
0719 int pos, ret, i;
0720 u8 value[MAX_EEPROM_DATA];
0721
0722 if (!buf)
0723 return -ENOMEM;
0724
0725 if (saved_offset == -1) {
0726
0727 pos = snprintf(buf, PAGE_SIZE, "0");
0728 goto done;
0729 }
0730
0731
0732 ret = mwifiex_eeprom_read(priv, (u16) saved_offset,
0733 (u16) saved_bytes, value);
0734 if (ret) {
0735 ret = -EINVAL;
0736 goto out_free;
0737 }
0738
0739 pos = snprintf(buf, PAGE_SIZE, "%d %d ", saved_offset, saved_bytes);
0740
0741 for (i = 0; i < saved_bytes; i++)
0742 pos += scnprintf(buf + pos, PAGE_SIZE - pos, "%d ", value[i]);
0743
0744 done:
0745 ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
0746 out_free:
0747 free_page(addr);
0748 return ret;
0749 }
0750
0751
0752
0753
0754 static ssize_t
0755 mwifiex_hscfg_write(struct file *file, const char __user *ubuf,
0756 size_t count, loff_t *ppos)
0757 {
0758 struct mwifiex_private *priv = (void *)file->private_data;
0759 char *buf;
0760 int ret, arg_num;
0761 struct mwifiex_ds_hs_cfg hscfg;
0762 int conditions = HS_CFG_COND_DEF;
0763 u32 gpio = HS_CFG_GPIO_DEF, gap = HS_CFG_GAP_DEF;
0764
0765 buf = memdup_user_nul(ubuf, min(count, (size_t)(PAGE_SIZE - 1)));
0766 if (IS_ERR(buf))
0767 return PTR_ERR(buf);
0768
0769 arg_num = sscanf(buf, "%d %x %x", &conditions, &gpio, &gap);
0770
0771 memset(&hscfg, 0, sizeof(struct mwifiex_ds_hs_cfg));
0772
0773 if (arg_num > 3) {
0774 mwifiex_dbg(priv->adapter, ERROR,
0775 "Too many arguments\n");
0776 ret = -EINVAL;
0777 goto done;
0778 }
0779
0780 if (arg_num >= 1 && arg_num < 3)
0781 mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_GET,
0782 MWIFIEX_SYNC_CMD, &hscfg);
0783
0784 if (arg_num) {
0785 if (conditions == HS_CFG_CANCEL) {
0786 mwifiex_cancel_hs(priv, MWIFIEX_ASYNC_CMD);
0787 ret = count;
0788 goto done;
0789 }
0790 hscfg.conditions = conditions;
0791 }
0792 if (arg_num >= 2)
0793 hscfg.gpio = gpio;
0794 if (arg_num == 3)
0795 hscfg.gap = gap;
0796
0797 hscfg.is_invoke_hostcmd = false;
0798 mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET,
0799 MWIFIEX_SYNC_CMD, &hscfg);
0800
0801 mwifiex_enable_hs(priv->adapter);
0802 clear_bit(MWIFIEX_IS_HS_ENABLING, &priv->adapter->work_flags);
0803 ret = count;
0804 done:
0805 kfree(buf);
0806 return ret;
0807 }
0808
0809
0810
0811
0812
0813 static ssize_t
0814 mwifiex_hscfg_read(struct file *file, char __user *ubuf,
0815 size_t count, loff_t *ppos)
0816 {
0817 struct mwifiex_private *priv = (void *)file->private_data;
0818 unsigned long addr = get_zeroed_page(GFP_KERNEL);
0819 char *buf = (char *)addr;
0820 int pos, ret;
0821 struct mwifiex_ds_hs_cfg hscfg;
0822
0823 if (!buf)
0824 return -ENOMEM;
0825
0826 mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_GET,
0827 MWIFIEX_SYNC_CMD, &hscfg);
0828
0829 pos = snprintf(buf, PAGE_SIZE, "%u 0x%x 0x%x\n", hscfg.conditions,
0830 hscfg.gpio, hscfg.gap);
0831
0832 ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
0833
0834 free_page(addr);
0835 return ret;
0836 }
0837
0838 static ssize_t
0839 mwifiex_timeshare_coex_read(struct file *file, char __user *ubuf,
0840 size_t count, loff_t *ppos)
0841 {
0842 struct mwifiex_private *priv = file->private_data;
0843 char buf[3];
0844 bool timeshare_coex;
0845 int ret;
0846 unsigned int len;
0847
0848 if (priv->adapter->fw_api_ver != MWIFIEX_FW_V15)
0849 return -EOPNOTSUPP;
0850
0851 ret = mwifiex_send_cmd(priv, HostCmd_CMD_ROBUST_COEX,
0852 HostCmd_ACT_GEN_GET, 0, ×hare_coex, true);
0853 if (ret)
0854 return ret;
0855
0856 len = sprintf(buf, "%d\n", timeshare_coex);
0857 return simple_read_from_buffer(ubuf, count, ppos, buf, len);
0858 }
0859
0860 static ssize_t
0861 mwifiex_timeshare_coex_write(struct file *file, const char __user *ubuf,
0862 size_t count, loff_t *ppos)
0863 {
0864 bool timeshare_coex;
0865 struct mwifiex_private *priv = file->private_data;
0866 char kbuf[16];
0867 int ret;
0868
0869 if (priv->adapter->fw_api_ver != MWIFIEX_FW_V15)
0870 return -EOPNOTSUPP;
0871
0872 memset(kbuf, 0, sizeof(kbuf));
0873
0874 if (copy_from_user(&kbuf, ubuf, min_t(size_t, sizeof(kbuf) - 1, count)))
0875 return -EFAULT;
0876
0877 if (strtobool(kbuf, ×hare_coex))
0878 return -EINVAL;
0879
0880 ret = mwifiex_send_cmd(priv, HostCmd_CMD_ROBUST_COEX,
0881 HostCmd_ACT_GEN_SET, 0, ×hare_coex, true);
0882 if (ret)
0883 return ret;
0884 else
0885 return count;
0886 }
0887
0888 static ssize_t
0889 mwifiex_reset_write(struct file *file,
0890 const char __user *ubuf, size_t count, loff_t *ppos)
0891 {
0892 struct mwifiex_private *priv = file->private_data;
0893 struct mwifiex_adapter *adapter = priv->adapter;
0894 bool result;
0895 int rc;
0896
0897 rc = kstrtobool_from_user(ubuf, count, &result);
0898 if (rc)
0899 return rc;
0900
0901 if (!result)
0902 return -EINVAL;
0903
0904 if (adapter->if_ops.card_reset) {
0905 dev_info(adapter->dev, "Resetting per request\n");
0906 adapter->if_ops.card_reset(adapter);
0907 }
0908
0909 return count;
0910 }
0911
0912 #define MWIFIEX_DFS_ADD_FILE(name) do { \
0913 debugfs_create_file(#name, 0644, priv->dfs_dev_dir, priv, \
0914 &mwifiex_dfs_##name##_fops); \
0915 } while (0);
0916
0917 #define MWIFIEX_DFS_FILE_OPS(name) \
0918 static const struct file_operations mwifiex_dfs_##name##_fops = { \
0919 .read = mwifiex_##name##_read, \
0920 .write = mwifiex_##name##_write, \
0921 .open = simple_open, \
0922 };
0923
0924 #define MWIFIEX_DFS_FILE_READ_OPS(name) \
0925 static const struct file_operations mwifiex_dfs_##name##_fops = { \
0926 .read = mwifiex_##name##_read, \
0927 .open = simple_open, \
0928 };
0929
0930 #define MWIFIEX_DFS_FILE_WRITE_OPS(name) \
0931 static const struct file_operations mwifiex_dfs_##name##_fops = { \
0932 .write = mwifiex_##name##_write, \
0933 .open = simple_open, \
0934 };
0935
0936
0937 MWIFIEX_DFS_FILE_READ_OPS(info);
0938 MWIFIEX_DFS_FILE_READ_OPS(debug);
0939 MWIFIEX_DFS_FILE_READ_OPS(getlog);
0940 MWIFIEX_DFS_FILE_OPS(regrdwr);
0941 MWIFIEX_DFS_FILE_OPS(rdeeprom);
0942 MWIFIEX_DFS_FILE_OPS(memrw);
0943 MWIFIEX_DFS_FILE_OPS(hscfg);
0944 MWIFIEX_DFS_FILE_OPS(histogram);
0945 MWIFIEX_DFS_FILE_OPS(debug_mask);
0946 MWIFIEX_DFS_FILE_OPS(timeshare_coex);
0947 MWIFIEX_DFS_FILE_WRITE_OPS(reset);
0948 MWIFIEX_DFS_FILE_OPS(verext);
0949
0950
0951
0952
0953 void
0954 mwifiex_dev_debugfs_init(struct mwifiex_private *priv)
0955 {
0956 if (!mwifiex_dfs_dir || !priv)
0957 return;
0958
0959 priv->dfs_dev_dir = debugfs_create_dir(priv->netdev->name,
0960 mwifiex_dfs_dir);
0961
0962 if (!priv->dfs_dev_dir)
0963 return;
0964
0965 MWIFIEX_DFS_ADD_FILE(info);
0966 MWIFIEX_DFS_ADD_FILE(debug);
0967 MWIFIEX_DFS_ADD_FILE(getlog);
0968 MWIFIEX_DFS_ADD_FILE(regrdwr);
0969 MWIFIEX_DFS_ADD_FILE(rdeeprom);
0970
0971 MWIFIEX_DFS_ADD_FILE(memrw);
0972 MWIFIEX_DFS_ADD_FILE(hscfg);
0973 MWIFIEX_DFS_ADD_FILE(histogram);
0974 MWIFIEX_DFS_ADD_FILE(debug_mask);
0975 MWIFIEX_DFS_ADD_FILE(timeshare_coex);
0976 MWIFIEX_DFS_ADD_FILE(reset);
0977 MWIFIEX_DFS_ADD_FILE(verext);
0978 }
0979
0980
0981
0982
0983 void
0984 mwifiex_dev_debugfs_remove(struct mwifiex_private *priv)
0985 {
0986 if (!priv)
0987 return;
0988
0989 debugfs_remove_recursive(priv->dfs_dev_dir);
0990 }
0991
0992
0993
0994
0995 void
0996 mwifiex_debugfs_init(void)
0997 {
0998 if (!mwifiex_dfs_dir)
0999 mwifiex_dfs_dir = debugfs_create_dir("mwifiex", NULL);
1000 }
1001
1002
1003
1004
1005 void
1006 mwifiex_debugfs_remove(void)
1007 {
1008 debugfs_remove(mwifiex_dfs_dir);
1009 }