📄 debugfs.c
字号:
#include <linux/module.h>#include <linux/dcache.h>#include <linux/debugfs.h>#include <linux/delay.h>#include <linux/mm.h>#include <linux/string.h>#include <net/iw_handler.h>#include "dev.h"#include "decl.h"#include "host.h"#include "debugfs.h"static struct dentry *libertas_dir = NULL;static char *szStates[] = { "Connected", "Disconnected"};#ifdef PROC_DEBUGstatic void libertas_debug_init(wlan_private * priv, struct net_device *dev);#endifstatic int open_file_generic(struct inode *inode, struct file *file){ file->private_data = inode->i_private; return 0;}static ssize_t write_file_dummy(struct file *file, const char __user *buf, size_t count, loff_t *ppos){ return -EINVAL;}static const size_t len = PAGE_SIZE;static ssize_t libertas_dev_info(struct file *file, char __user *userbuf, size_t count, loff_t *ppos){ wlan_private *priv = file->private_data; size_t pos = 0; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; ssize_t res; pos += snprintf(buf+pos, len-pos, "state = %s\n", szStates[priv->adapter->connect_status]); pos += snprintf(buf+pos, len-pos, "region_code = %02x\n", (u32) priv->adapter->regioncode); res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); free_page(addr); return res;}static ssize_t libertas_getscantable(struct file *file, char __user *userbuf, size_t count, loff_t *ppos){ wlan_private *priv = file->private_data; size_t pos = 0; int numscansdone = 0, res; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; DECLARE_MAC_BUF(mac); struct bss_descriptor * iter_bss; pos += snprintf(buf+pos, len-pos, "# | ch | rssi | bssid | cap | Qual | SSID \n"); mutex_lock(&priv->adapter->lock); list_for_each_entry (iter_bss, &priv->adapter->network_list, list) { u16 ibss = (iter_bss->capability & WLAN_CAPABILITY_IBSS); u16 privacy = (iter_bss->capability & WLAN_CAPABILITY_PRIVACY); u16 spectrum_mgmt = (iter_bss->capability & WLAN_CAPABILITY_SPECTRUM_MGMT); pos += snprintf(buf+pos, len-pos, "%02u| %03d | %04ld | %s |", numscansdone, iter_bss->channel, iter_bss->rssi, print_mac(mac, iter_bss->bssid)); pos += snprintf(buf+pos, len-pos, " %04x-", iter_bss->capability); pos += snprintf(buf+pos, len-pos, "%c%c%c |", ibss ? 'A' : 'I', privacy ? 'P' : ' ', spectrum_mgmt ? 'S' : ' '); pos += snprintf(buf+pos, len-pos, " %04d |", SCAN_RSSI(iter_bss->rssi)); pos += snprintf(buf+pos, len-pos, " %s\n", escape_essid(iter_bss->ssid, iter_bss->ssid_len)); numscansdone++; } mutex_unlock(&priv->adapter->lock); res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); free_page(addr); return res;}static ssize_t libertas_sleepparams_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos){ wlan_private *priv = file->private_data; ssize_t buf_size, res; int p1, p2, p3, p4, p5, p6; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; buf_size = min(count, len - 1); if (copy_from_user(buf, user_buf, buf_size)) { res = -EFAULT; goto out_unlock; } res = sscanf(buf, "%d %d %d %d %d %d", &p1, &p2, &p3, &p4, &p5, &p6); if (res != 6) { res = -EFAULT; goto out_unlock; } priv->adapter->sp.sp_error = p1; priv->adapter->sp.sp_offset = p2; priv->adapter->sp.sp_stabletime = p3; priv->adapter->sp.sp_calcontrol = p4; priv->adapter->sp.sp_extsleepclk = p5; priv->adapter->sp.sp_reserved = p6; res = libertas_prepare_and_send_command(priv, CMD_802_11_SLEEP_PARAMS, CMD_ACT_SET, CMD_OPTION_WAITFORRSP, 0, NULL); if (!res) res = count; else res = -EINVAL;out_unlock: free_page(addr); return res;}static ssize_t libertas_sleepparams_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos){ wlan_private *priv = file->private_data; wlan_adapter *adapter = priv->adapter; ssize_t res; size_t pos = 0; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; res = libertas_prepare_and_send_command(priv, CMD_802_11_SLEEP_PARAMS, CMD_ACT_GET, CMD_OPTION_WAITFORRSP, 0, NULL); if (res) { res = -EFAULT; goto out_unlock; } pos += snprintf(buf, len, "%d %d %d %d %d %d\n", adapter->sp.sp_error, adapter->sp.sp_offset, adapter->sp.sp_stabletime, adapter->sp.sp_calcontrol, adapter->sp.sp_extsleepclk, adapter->sp.sp_reserved); res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);out_unlock: free_page(addr); return res;}static ssize_t libertas_extscan(struct file *file, const char __user *userbuf, size_t count, loff_t *ppos){ wlan_private *priv = file->private_data; ssize_t res, buf_size; union iwreq_data wrqu; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; buf_size = min(count, len - 1); if (copy_from_user(buf, userbuf, buf_size)) { res = -EFAULT; goto out_unlock; } libertas_send_specific_ssid_scan(priv, buf, strlen(buf)-1, 0); memset(&wrqu, 0, sizeof(union iwreq_data)); wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);out_unlock: free_page(addr); return count;}static int libertas_parse_chan(char *buf, size_t count, struct wlan_ioctl_user_scan_cfg *scan_cfg, int dur){ char *start, *end, *hold, *str; int i = 0; start = strstr(buf, "chan="); if (!start) return -EINVAL; start += 5; end = strchr(start, ' '); if (!end) end = buf + count; hold = kzalloc((end - start)+1, GFP_KERNEL); if (!hold) return -ENOMEM; strncpy(hold, start, end - start); hold[(end-start)+1] = '\0'; while(hold && (str = strsep(&hold, ","))) { int chan; char band, passive = 0; sscanf(str, "%d%c%c", &chan, &band, &passive); scan_cfg->chanlist[i].channumber = chan; scan_cfg->chanlist[i].scantype = passive ? 1 : 0; if (band == 'b' || band == 'g') scan_cfg->chanlist[i].radiotype = 0; else if (band == 'a') scan_cfg->chanlist[i].radiotype = 1; scan_cfg->chanlist[i].scantime = dur; i++; } kfree(hold); return i;}static void libertas_parse_bssid(char *buf, size_t count, struct wlan_ioctl_user_scan_cfg *scan_cfg){ char *hold; unsigned int mac[ETH_ALEN]; hold = strstr(buf, "bssid="); if (!hold) return; hold += 6; sscanf(hold, MAC_FMT, mac, mac+1, mac+2, mac+3, mac+4, mac+5); memcpy(scan_cfg->bssid, mac, ETH_ALEN);}static void libertas_parse_ssid(char *buf, size_t count, struct wlan_ioctl_user_scan_cfg *scan_cfg){ char *hold, *end; ssize_t size; hold = strstr(buf, "ssid="); if (!hold) return; hold += 5; end = strchr(hold, ' '); if (!end) end = buf + count - 1; size = min((size_t)IW_ESSID_MAX_SIZE, (size_t) (end - hold)); strncpy(scan_cfg->ssid, hold, size); return;}static int libertas_parse_clear(char *buf, size_t count, const char *tag){ char *hold; int val; hold = strstr(buf, tag); if (!hold) return 0; hold += strlen(tag); sscanf(hold, "%d", &val); if (val != 0) val = 1; return val;}static int libertas_parse_dur(char *buf, size_t count, struct wlan_ioctl_user_scan_cfg *scan_cfg){ char *hold; int val; hold = strstr(buf, "dur="); if (!hold) return 0; hold += 4; sscanf(hold, "%d", &val); return val;}static void libertas_parse_probes(char *buf, size_t count, struct wlan_ioctl_user_scan_cfg *scan_cfg){ char *hold; int val; hold = strstr(buf, "probes="); if (!hold) return; hold += 7; sscanf(hold, "%d", &val); scan_cfg->numprobes = val; return;}static void libertas_parse_type(char *buf, size_t count, struct wlan_ioctl_user_scan_cfg *scan_cfg){ char *hold; int val; hold = strstr(buf, "type="); if (!hold) return; hold += 5; sscanf(hold, "%d", &val); /* type=1,2 or 3 */ if (val < 1 || val > 3) return; scan_cfg->bsstype = val; return;}static ssize_t libertas_setuserscan(struct file *file, const char __user *userbuf, size_t count, loff_t *ppos){ wlan_private *priv = file->private_data; ssize_t res, buf_size; struct wlan_ioctl_user_scan_cfg *scan_cfg; union iwreq_data wrqu; int dur; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; scan_cfg = kzalloc(sizeof(struct wlan_ioctl_user_scan_cfg), GFP_KERNEL); if (!scan_cfg) return -ENOMEM; buf_size = min(count, len - 1); if (copy_from_user(buf, userbuf, buf_size)) { res = -EFAULT; goto out_unlock; } scan_cfg->bsstype = WLAN_SCAN_BSS_TYPE_ANY; dur = libertas_parse_dur(buf, count, scan_cfg); libertas_parse_chan(buf, count, scan_cfg, dur); libertas_parse_bssid(buf, count, scan_cfg); scan_cfg->clear_bssid = libertas_parse_clear(buf, count, "clear_bssid="); libertas_parse_ssid(buf, count, scan_cfg); scan_cfg->clear_ssid = libertas_parse_clear(buf, count, "clear_ssid="); libertas_parse_probes(buf, count, scan_cfg); libertas_parse_type(buf, count, scan_cfg); wlan_scan_networks(priv, scan_cfg, 1); wait_event_interruptible(priv->adapter->cmd_pending, !priv->adapter->nr_cmd_pending); memset(&wrqu, 0x00, sizeof(union iwreq_data)); wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);out_unlock: free_page(addr); kfree(scan_cfg); return count;}static int libertas_event_initcmd(wlan_private *priv, void **response_buf, struct cmd_ctrl_node **cmdnode, struct cmd_ds_command **cmd){ u16 wait_option = CMD_OPTION_WAITFORRSP; if (!(*cmdnode = libertas_get_free_cmd_ctrl_node(priv))) { lbs_deb_debugfs("failed libertas_get_free_cmd_ctrl_node\n"); return -ENOMEM; } if (!(*response_buf = kmalloc(3000, GFP_KERNEL))) { lbs_deb_debugfs("failed to allocate response buffer!\n"); return -ENOMEM; } libertas_set_cmd_ctrl_node(priv, *cmdnode, 0, wait_option, NULL); init_waitqueue_head(&(*cmdnode)->cmdwait_q); (*cmdnode)->pdata_buf = *response_buf; (*cmdnode)->cmdflags |= CMD_F_HOSTCMD; (*cmdnode)->cmdwaitqwoken = 0; *cmd = (struct cmd_ds_command *)(*cmdnode)->bufvirtualaddr; (*cmd)->command = cpu_to_le16(CMD_802_11_SUBSCRIBE_EVENT); (*cmd)->seqnum = cpu_to_le16(++priv->adapter->seqnum); (*cmd)->result = 0; return 0;}static ssize_t libertas_lowrssi_read(struct file *file, char __user *userbuf, size_t count, loff_t *ppos){ wlan_private *priv = file->private_data; wlan_adapter *adapter = priv->adapter; struct cmd_ctrl_node *pcmdnode; struct cmd_ds_command *pcmdptr; struct cmd_ds_802_11_subscribe_event *event; void *response_buf; int res, cmd_len; ssize_t pos = 0; unsigned long addr = get_zeroed_page(GFP_KERNEL); char *buf = (char *)addr; res = libertas_event_initcmd(priv, &response_buf, &pcmdnode, &pcmdptr); if (res < 0) { free_page(addr); return res; } event = &pcmdptr->params.subscribe_event; event->action = cpu_to_le16(CMD_ACT_GET); pcmdptr->size = cpu_to_le16(sizeof(*event) + S_DS_GEN); libertas_queue_cmd(adapter, pcmdnode, 1); wake_up_interruptible(&priv->waitq); /* Sleep until response is generated by FW */ wait_event_interruptible(pcmdnode->cmdwait_q, pcmdnode->cmdwaitqwoken); pcmdptr = response_buf; if (pcmdptr->result) { lbs_pr_err("%s: fail, result=%d\n", __func__, le16_to_cpu(pcmdptr->result)); kfree(response_buf); free_page(addr); return 0; } if (pcmdptr->command != cpu_to_le16(CMD_RET(CMD_802_11_SUBSCRIBE_EVENT))) { lbs_pr_err("command response incorrect!\n"); kfree(response_buf); free_page(addr); return 0; } cmd_len = S_DS_GEN + sizeof(struct cmd_ds_802_11_subscribe_event); event = (void *)(response_buf + S_DS_GEN); while (cmd_len < le16_to_cpu(pcmdptr->size)) { struct mrvlietypesheader *header = (void *)(response_buf + cmd_len); switch (header->type) { struct mrvlietypes_rssithreshold *Lowrssi; case __constant_cpu_to_le16(TLV_TYPE_RSSI_LOW): Lowrssi = (void *)(response_buf + cmd_len); pos += snprintf(buf+pos, len-pos, "%d %d %d\n", Lowrssi->rssivalue, Lowrssi->rssifreq, (event->events & cpu_to_le16(0x0001))?1:0); default: cmd_len += sizeof(struct mrvlietypes_snrthreshold); break; } } kfree(response_buf); res = simple_read_from_buffer(userbuf, count, ppos, buf, pos); free_page(addr); return res;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -