brintos

brintos / linux-shallow public Read only

0
0
Text · 37.4 KiB · d998a3f Raw
1380 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/******************************************************************************3 *4 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.5 *6 * Contact Information:7 *  Intel Linux Wireless <ilw@linux.intel.com>8 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-64979 *****************************************************************************/10#include <linux/ieee80211.h>11#include <linux/export.h>12#include <net/mac80211.h>13 14#include "common.h"15 16static void17il_clear_traffic_stats(struct il_priv *il)18{19	memset(&il->tx_stats, 0, sizeof(struct traffic_stats));20	memset(&il->rx_stats, 0, sizeof(struct traffic_stats));21}22 23/*24 * il_update_stats function record all the MGMT, CTRL and DATA pkt for25 * both TX and Rx . Use debugfs to display the rx/rx_stats26 */27void28il_update_stats(struct il_priv *il, bool is_tx, __le16 fc, u16 len)29{30	struct traffic_stats *stats;31 32	if (is_tx)33		stats = &il->tx_stats;34	else35		stats = &il->rx_stats;36 37	if (ieee80211_is_mgmt(fc)) {38		switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {39		case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ):40			stats->mgmt[MANAGEMENT_ASSOC_REQ]++;41			break;42		case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP):43			stats->mgmt[MANAGEMENT_ASSOC_RESP]++;44			break;45		case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ):46			stats->mgmt[MANAGEMENT_REASSOC_REQ]++;47			break;48		case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP):49			stats->mgmt[MANAGEMENT_REASSOC_RESP]++;50			break;51		case cpu_to_le16(IEEE80211_STYPE_PROBE_REQ):52			stats->mgmt[MANAGEMENT_PROBE_REQ]++;53			break;54		case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP):55			stats->mgmt[MANAGEMENT_PROBE_RESP]++;56			break;57		case cpu_to_le16(IEEE80211_STYPE_BEACON):58			stats->mgmt[MANAGEMENT_BEACON]++;59			break;60		case cpu_to_le16(IEEE80211_STYPE_ATIM):61			stats->mgmt[MANAGEMENT_ATIM]++;62			break;63		case cpu_to_le16(IEEE80211_STYPE_DISASSOC):64			stats->mgmt[MANAGEMENT_DISASSOC]++;65			break;66		case cpu_to_le16(IEEE80211_STYPE_AUTH):67			stats->mgmt[MANAGEMENT_AUTH]++;68			break;69		case cpu_to_le16(IEEE80211_STYPE_DEAUTH):70			stats->mgmt[MANAGEMENT_DEAUTH]++;71			break;72		case cpu_to_le16(IEEE80211_STYPE_ACTION):73			stats->mgmt[MANAGEMENT_ACTION]++;74			break;75		}76	} else if (ieee80211_is_ctl(fc)) {77		switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) {78		case cpu_to_le16(IEEE80211_STYPE_BACK_REQ):79			stats->ctrl[CONTROL_BACK_REQ]++;80			break;81		case cpu_to_le16(IEEE80211_STYPE_BACK):82			stats->ctrl[CONTROL_BACK]++;83			break;84		case cpu_to_le16(IEEE80211_STYPE_PSPOLL):85			stats->ctrl[CONTROL_PSPOLL]++;86			break;87		case cpu_to_le16(IEEE80211_STYPE_RTS):88			stats->ctrl[CONTROL_RTS]++;89			break;90		case cpu_to_le16(IEEE80211_STYPE_CTS):91			stats->ctrl[CONTROL_CTS]++;92			break;93		case cpu_to_le16(IEEE80211_STYPE_ACK):94			stats->ctrl[CONTROL_ACK]++;95			break;96		case cpu_to_le16(IEEE80211_STYPE_CFEND):97			stats->ctrl[CONTROL_CFEND]++;98			break;99		case cpu_to_le16(IEEE80211_STYPE_CFENDACK):100			stats->ctrl[CONTROL_CFENDACK]++;101			break;102		}103	} else {104		/* data */105		stats->data_cnt++;106		stats->data_bytes += len;107	}108}109EXPORT_SYMBOL(il_update_stats);110 111/* create and remove of files */112#define DEBUGFS_ADD_FILE(name, parent, mode) do {			\113	debugfs_create_file(#name, mode, parent, il,			\114			    &il_dbgfs_##name##_ops);			\115} while (0)116 117#define DEBUGFS_ADD_BOOL(name, parent, ptr) do {			\118	debugfs_create_bool(#name, 0600, parent, ptr);			\119} while (0)120 121/* file operation */122#define DEBUGFS_READ_FUNC(name)                                         \123static ssize_t il_dbgfs_##name##_read(struct file *file,               \124					char __user *user_buf,          \125					size_t count, loff_t *ppos);126 127#define DEBUGFS_WRITE_FUNC(name)                                        \128static ssize_t il_dbgfs_##name##_write(struct file *file,              \129					const char __user *user_buf,    \130					size_t count, loff_t *ppos);131 132 133#define DEBUGFS_READ_FILE_OPS(name)				\134	DEBUGFS_READ_FUNC(name);				\135static const struct file_operations il_dbgfs_##name##_ops = {	\136	.read = il_dbgfs_##name##_read,				\137	.open = simple_open,					\138	.llseek = generic_file_llseek,				\139};140 141#define DEBUGFS_WRITE_FILE_OPS(name)				\142	DEBUGFS_WRITE_FUNC(name);				\143static const struct file_operations il_dbgfs_##name##_ops = {	\144	.write = il_dbgfs_##name##_write,			\145	.open = simple_open,					\146	.llseek = generic_file_llseek,				\147};148 149#define DEBUGFS_READ_WRITE_FILE_OPS(name)			\150	DEBUGFS_READ_FUNC(name);				\151	DEBUGFS_WRITE_FUNC(name);				\152static const struct file_operations il_dbgfs_##name##_ops = {	\153	.write = il_dbgfs_##name##_write,			\154	.read = il_dbgfs_##name##_read,				\155	.open = simple_open,					\156	.llseek = generic_file_llseek,				\157};158 159static const char *160il_get_mgmt_string(int cmd)161{162	switch (cmd) {163	IL_CMD(MANAGEMENT_ASSOC_REQ);164	IL_CMD(MANAGEMENT_ASSOC_RESP);165	IL_CMD(MANAGEMENT_REASSOC_REQ);166	IL_CMD(MANAGEMENT_REASSOC_RESP);167	IL_CMD(MANAGEMENT_PROBE_REQ);168	IL_CMD(MANAGEMENT_PROBE_RESP);169	IL_CMD(MANAGEMENT_BEACON);170	IL_CMD(MANAGEMENT_ATIM);171	IL_CMD(MANAGEMENT_DISASSOC);172	IL_CMD(MANAGEMENT_AUTH);173	IL_CMD(MANAGEMENT_DEAUTH);174	IL_CMD(MANAGEMENT_ACTION);175	default:176		return "UNKNOWN";177 178	}179}180 181static const char *182il_get_ctrl_string(int cmd)183{184	switch (cmd) {185	IL_CMD(CONTROL_BACK_REQ);186	IL_CMD(CONTROL_BACK);187	IL_CMD(CONTROL_PSPOLL);188	IL_CMD(CONTROL_RTS);189	IL_CMD(CONTROL_CTS);190	IL_CMD(CONTROL_ACK);191	IL_CMD(CONTROL_CFEND);192	IL_CMD(CONTROL_CFENDACK);193	default:194		return "UNKNOWN";195 196	}197}198 199static ssize_t200il_dbgfs_tx_stats_read(struct file *file, char __user *user_buf, size_t count,201		       loff_t *ppos)202{203 204	struct il_priv *il = file->private_data;205	char *buf;206	int pos = 0;207 208	int cnt;209	ssize_t ret;210	const size_t bufsz =211	    100 + sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX);212	buf = kzalloc(bufsz, GFP_KERNEL);213	if (!buf)214		return -ENOMEM;215	pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");216	for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {217		pos +=218		    scnprintf(buf + pos, bufsz - pos, "\t%25s\t\t: %u\n",219			      il_get_mgmt_string(cnt), il->tx_stats.mgmt[cnt]);220	}221	pos += scnprintf(buf + pos, bufsz - pos, "Control\n");222	for (cnt = 0; cnt < CONTROL_MAX; cnt++) {223		pos +=224		    scnprintf(buf + pos, bufsz - pos, "\t%25s\t\t: %u\n",225			      il_get_ctrl_string(cnt), il->tx_stats.ctrl[cnt]);226	}227	pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");228	pos +=229	    scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",230		      il->tx_stats.data_cnt);231	pos +=232	    scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",233		      il->tx_stats.data_bytes);234	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);235	kfree(buf);236	return ret;237}238 239static ssize_t240il_dbgfs_clear_traffic_stats_write(struct file *file,241				   const char __user *user_buf, size_t count,242				   loff_t *ppos)243{244	struct il_priv *il = file->private_data;245	u32 clear_flag;246	char buf[8];247	int buf_size;248 249	memset(buf, 0, sizeof(buf));250	buf_size = min(count, sizeof(buf) - 1);251	if (copy_from_user(buf, user_buf, buf_size))252		return -EFAULT;253	if (sscanf(buf, "%x", &clear_flag) != 1)254		return -EFAULT;255	il_clear_traffic_stats(il);256 257	return count;258}259 260static ssize_t261il_dbgfs_rx_stats_read(struct file *file, char __user *user_buf, size_t count,262		       loff_t *ppos)263{264 265	struct il_priv *il = file->private_data;266	char *buf;267	int pos = 0;268	int cnt;269	ssize_t ret;270	const size_t bufsz =271	    100 + sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX);272	buf = kzalloc(bufsz, GFP_KERNEL);273	if (!buf)274		return -ENOMEM;275 276	pos += scnprintf(buf + pos, bufsz - pos, "Management:\n");277	for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) {278		pos +=279		    scnprintf(buf + pos, bufsz - pos, "\t%25s\t\t: %u\n",280			      il_get_mgmt_string(cnt), il->rx_stats.mgmt[cnt]);281	}282	pos += scnprintf(buf + pos, bufsz - pos, "Control:\n");283	for (cnt = 0; cnt < CONTROL_MAX; cnt++) {284		pos +=285		    scnprintf(buf + pos, bufsz - pos, "\t%25s\t\t: %u\n",286			      il_get_ctrl_string(cnt), il->rx_stats.ctrl[cnt]);287	}288	pos += scnprintf(buf + pos, bufsz - pos, "Data:\n");289	pos +=290	    scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n",291		      il->rx_stats.data_cnt);292	pos +=293	    scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n",294		      il->rx_stats.data_bytes);295 296	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);297	kfree(buf);298	return ret;299}300 301#define BYTE1_MASK 0x000000ff;302#define BYTE2_MASK 0x0000ffff;303#define BYTE3_MASK 0x00ffffff;304static ssize_t305il_dbgfs_sram_read(struct file *file, char __user *user_buf, size_t count,306		   loff_t *ppos)307{308	u32 val;309	char *buf;310	ssize_t ret;311	int i;312	int pos = 0;313	struct il_priv *il = file->private_data;314	size_t bufsz;315 316	/* default is to dump the entire data segment */317	if (!il->dbgfs_sram_offset && !il->dbgfs_sram_len) {318		il->dbgfs_sram_offset = 0x800000;319		if (il->ucode_type == UCODE_INIT)320			il->dbgfs_sram_len = il->ucode_init_data.len;321		else322			il->dbgfs_sram_len = il->ucode_data.len;323	}324	bufsz = 30 + il->dbgfs_sram_len * sizeof(char) * 10;325	buf = kmalloc(bufsz, GFP_KERNEL);326	if (!buf)327		return -ENOMEM;328	pos +=329	    scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n",330		      il->dbgfs_sram_len);331	pos +=332	    scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n",333		      il->dbgfs_sram_offset);334	for (i = il->dbgfs_sram_len; i > 0; i -= 4) {335		val =336		    il_read_targ_mem(il,337				     il->dbgfs_sram_offset +338				     il->dbgfs_sram_len - i);339		if (i < 4) {340			switch (i) {341			case 1:342				val &= BYTE1_MASK;343				break;344			case 2:345				val &= BYTE2_MASK;346				break;347			case 3:348				val &= BYTE3_MASK;349				break;350			}351		}352		if (!(i % 16))353			pos += scnprintf(buf + pos, bufsz - pos, "\n");354		pos += scnprintf(buf + pos, bufsz - pos, "0x%08x ", val);355	}356	pos += scnprintf(buf + pos, bufsz - pos, "\n");357 358	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);359	kfree(buf);360	return ret;361}362 363static ssize_t364il_dbgfs_sram_write(struct file *file, const char __user *user_buf,365		    size_t count, loff_t *ppos)366{367	struct il_priv *il = file->private_data;368	char buf[64];369	int buf_size;370	u32 offset, len;371 372	memset(buf, 0, sizeof(buf));373	buf_size = min(count, sizeof(buf) - 1);374	if (copy_from_user(buf, user_buf, buf_size))375		return -EFAULT;376 377	if (sscanf(buf, "%x,%x", &offset, &len) == 2) {378		il->dbgfs_sram_offset = offset;379		il->dbgfs_sram_len = len;380	} else {381		il->dbgfs_sram_offset = 0;382		il->dbgfs_sram_len = 0;383	}384 385	return count;386}387 388static ssize_t389il_dbgfs_stations_read(struct file *file, char __user *user_buf, size_t count,390		       loff_t *ppos)391{392	struct il_priv *il = file->private_data;393	struct il_station_entry *station;394	int max_sta = il->hw_params.max_stations;395	char *buf;396	int i, j, pos = 0;397	ssize_t ret;398	/* Add 30 for initial string */399	const size_t bufsz = 30 + sizeof(char) * 500 * (il->num_stations);400 401	buf = kmalloc(bufsz, GFP_KERNEL);402	if (!buf)403		return -ENOMEM;404 405	pos +=406	    scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n",407		      il->num_stations);408 409	for (i = 0; i < max_sta; i++) {410		station = &il->stations[i];411		if (!station->used)412			continue;413		pos +=414		    scnprintf(buf + pos, bufsz - pos,415			      "station %d - addr: %pM, flags: %#x\n", i,416			      station->sta.sta.addr,417			      station->sta.station_flags_msk);418		pos +=419		    scnprintf(buf + pos, bufsz - pos,420			      "TID\tseq_num\ttxq_id\tframes\ttfds\t");421		pos +=422		    scnprintf(buf + pos, bufsz - pos,423			      "start_idx\tbitmap\t\t\trate_n_flags\n");424 425		for (j = 0; j < MAX_TID_COUNT; j++) {426			pos +=427			    scnprintf(buf + pos, bufsz - pos,428				      "%d:\t%#x\t%#x\t%u\t%u\t%u\t\t%#.16llx\t%#x",429				      j, station->tid[j].seq_number,430				      station->tid[j].agg.txq_id,431				      station->tid[j].agg.frame_count,432				      station->tid[j].tfds_in_queue,433				      station->tid[j].agg.start_idx,434				      station->tid[j].agg.bitmap,435				      station->tid[j].agg.rate_n_flags);436 437			if (station->tid[j].agg.wait_for_ba)438				pos +=439				    scnprintf(buf + pos, bufsz - pos,440					      " - waitforba");441			pos += scnprintf(buf + pos, bufsz - pos, "\n");442		}443 444		pos += scnprintf(buf + pos, bufsz - pos, "\n");445	}446 447	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);448	kfree(buf);449	return ret;450}451 452static ssize_t453il_dbgfs_nvm_read(struct file *file, char __user *user_buf, size_t count,454		  loff_t *ppos)455{456	ssize_t ret;457	struct il_priv *il = file->private_data;458	int pos = 0, ofs = 0, buf_size = 0;459	const u8 *ptr;460	char *buf;461	u16 eeprom_ver;462	size_t eeprom_len = il->cfg->eeprom_size;463	buf_size = 4 * eeprom_len + 256;464 465	if (eeprom_len % 16) {466		IL_ERR("NVM size is not multiple of 16.\n");467		return -ENODATA;468	}469 470	ptr = il->eeprom;471	if (!ptr) {472		IL_ERR("Invalid EEPROM memory\n");473		return -ENOMEM;474	}475 476	/* 4 characters for byte 0xYY */477	buf = kzalloc(buf_size, GFP_KERNEL);478	if (!buf) {479		IL_ERR("Can not allocate Buffer\n");480		return -ENOMEM;481	}482	eeprom_ver = il_eeprom_query16(il, EEPROM_VERSION);483	pos +=484	    scnprintf(buf + pos, buf_size - pos, "EEPROM " "version: 0x%x\n",485		      eeprom_ver);486	for (ofs = 0; ofs < eeprom_len; ofs += 16) {487		pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x %16ph\n",488				 ofs, ptr + ofs);489	}490 491	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);492	kfree(buf);493	return ret;494}495 496static ssize_t497il_dbgfs_channels_read(struct file *file, char __user *user_buf, size_t count,498		       loff_t *ppos)499{500	struct il_priv *il = file->private_data;501	struct ieee80211_channel *channels = NULL;502	const struct ieee80211_supported_band *supp_band = NULL;503	int pos = 0, i, bufsz = PAGE_SIZE;504	char *buf;505	ssize_t ret;506 507	if (!test_bit(S_GEO_CONFIGURED, &il->status))508		return -EAGAIN;509 510	buf = kzalloc(bufsz, GFP_KERNEL);511	if (!buf) {512		IL_ERR("Can not allocate Buffer\n");513		return -ENOMEM;514	}515 516	supp_band = il_get_hw_mode(il, NL80211_BAND_2GHZ);517	if (supp_band) {518		channels = supp_band->channels;519 520		pos +=521		    scnprintf(buf + pos, bufsz - pos,522			      "Displaying %d channels in 2.4GHz band 802.11bg):\n",523			      supp_band->n_channels);524 525		for (i = 0; i < supp_band->n_channels; i++)526			pos +=527			    scnprintf(buf + pos, bufsz - pos,528				      "%d: %ddBm: BSS%s%s, %s.\n",529				      channels[i].hw_value,530				      channels[i].max_power,531				      channels[i].532				      flags & IEEE80211_CHAN_RADAR ?533				      " (IEEE 802.11h required)" : "",534				      ((channels[i].535					flags & IEEE80211_CHAN_NO_IR) ||536				       (channels[i].537					flags & IEEE80211_CHAN_RADAR)) ? "" :538				      ", IBSS",539				      channels[i].540				      flags & IEEE80211_CHAN_NO_IR ?541				      "passive only" : "active/passive");542	}543	supp_band = il_get_hw_mode(il, NL80211_BAND_5GHZ);544	if (supp_band) {545		channels = supp_band->channels;546 547		pos +=548		    scnprintf(buf + pos, bufsz - pos,549			      "Displaying %d channels in 5.2GHz band (802.11a)\n",550			      supp_band->n_channels);551 552		for (i = 0; i < supp_band->n_channels; i++)553			pos +=554			    scnprintf(buf + pos, bufsz - pos,555				      "%d: %ddBm: BSS%s%s, %s.\n",556				      channels[i].hw_value,557				      channels[i].max_power,558				      channels[i].559				      flags & IEEE80211_CHAN_RADAR ?560				      " (IEEE 802.11h required)" : "",561				      ((channels[i].562					flags & IEEE80211_CHAN_NO_IR) ||563				       (channels[i].564					flags & IEEE80211_CHAN_RADAR)) ? "" :565				      ", IBSS",566				      channels[i].567				      flags & IEEE80211_CHAN_NO_IR ?568				      "passive only" : "active/passive");569	}570	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);571	kfree(buf);572	return ret;573}574 575static ssize_t576il_dbgfs_status_read(struct file *file, char __user *user_buf, size_t count,577		     loff_t *ppos)578{579 580	struct il_priv *il = file->private_data;581	char buf[512];582	int pos = 0;583	const size_t bufsz = sizeof(buf);584 585	pos +=586	    scnprintf(buf + pos, bufsz - pos, "S_HCMD_ACTIVE:\t %d\n",587		      test_bit(S_HCMD_ACTIVE, &il->status));588	pos +=589	    scnprintf(buf + pos, bufsz - pos, "S_INT_ENABLED:\t %d\n",590		      test_bit(S_INT_ENABLED, &il->status));591	pos +=592	    scnprintf(buf + pos, bufsz - pos, "S_RFKILL:\t %d\n",593		      test_bit(S_RFKILL, &il->status));594	pos +=595	    scnprintf(buf + pos, bufsz - pos, "S_CT_KILL:\t\t %d\n",596		      test_bit(S_CT_KILL, &il->status));597	pos +=598	    scnprintf(buf + pos, bufsz - pos, "S_INIT:\t\t %d\n",599		      test_bit(S_INIT, &il->status));600	pos +=601	    scnprintf(buf + pos, bufsz - pos, "S_ALIVE:\t\t %d\n",602		      test_bit(S_ALIVE, &il->status));603	pos +=604	    scnprintf(buf + pos, bufsz - pos, "S_READY:\t\t %d\n",605		      test_bit(S_READY, &il->status));606	pos +=607	    scnprintf(buf + pos, bufsz - pos, "S_TEMPERATURE:\t %d\n",608		      test_bit(S_TEMPERATURE, &il->status));609	pos +=610	    scnprintf(buf + pos, bufsz - pos, "S_GEO_CONFIGURED:\t %d\n",611		      test_bit(S_GEO_CONFIGURED, &il->status));612	pos +=613	    scnprintf(buf + pos, bufsz - pos, "S_EXIT_PENDING:\t %d\n",614		      test_bit(S_EXIT_PENDING, &il->status));615	pos +=616	    scnprintf(buf + pos, bufsz - pos, "S_STATS:\t %d\n",617		      test_bit(S_STATS, &il->status));618	pos +=619	    scnprintf(buf + pos, bufsz - pos, "S_SCANNING:\t %d\n",620		      test_bit(S_SCANNING, &il->status));621	pos +=622	    scnprintf(buf + pos, bufsz - pos, "S_SCAN_ABORTING:\t %d\n",623		      test_bit(S_SCAN_ABORTING, &il->status));624	pos +=625	    scnprintf(buf + pos, bufsz - pos, "S_SCAN_HW:\t\t %d\n",626		      test_bit(S_SCAN_HW, &il->status));627	pos +=628	    scnprintf(buf + pos, bufsz - pos, "S_POWER_PMI:\t %d\n",629		      test_bit(S_POWER_PMI, &il->status));630	pos +=631	    scnprintf(buf + pos, bufsz - pos, "S_FW_ERROR:\t %d\n",632		      test_bit(S_FW_ERROR, &il->status));633	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);634}635 636static ssize_t637il_dbgfs_interrupt_read(struct file *file, char __user *user_buf, size_t count,638			loff_t *ppos)639{640 641	struct il_priv *il = file->private_data;642	int pos = 0;643	int cnt = 0;644	char *buf;645	int bufsz = 24 * 64;	/* 24 items * 64 char per item */646	ssize_t ret;647 648	buf = kzalloc(bufsz, GFP_KERNEL);649	if (!buf) {650		IL_ERR("Can not allocate Buffer\n");651		return -ENOMEM;652	}653 654	pos +=655	    scnprintf(buf + pos, bufsz - pos, "Interrupt Statistics Report:\n");656 657	pos +=658	    scnprintf(buf + pos, bufsz - pos, "HW Error:\t\t\t %u\n",659		      il->isr_stats.hw);660	pos +=661	    scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n",662		      il->isr_stats.sw);663	if (il->isr_stats.sw || il->isr_stats.hw) {664		pos +=665		    scnprintf(buf + pos, bufsz - pos,666			      "\tLast Restarting Code:  0x%X\n",667			      il->isr_stats.err_code);668	}669#ifdef CONFIG_IWLEGACY_DEBUG670	pos +=671	    scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n",672		      il->isr_stats.sch);673	pos +=674	    scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n",675		      il->isr_stats.alive);676#endif677	pos +=678	    scnprintf(buf + pos, bufsz - pos,679		      "HW RF KILL switch toggled:\t %u\n",680		      il->isr_stats.rfkill);681 682	pos +=683	    scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n",684		      il->isr_stats.ctkill);685 686	pos +=687	    scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n",688		      il->isr_stats.wakeup);689 690	pos +=691	    scnprintf(buf + pos, bufsz - pos, "Rx command responses:\t\t %u\n",692		      il->isr_stats.rx);693	for (cnt = 0; cnt < IL_CN_MAX; cnt++) {694		if (il->isr_stats.handlers[cnt] > 0)695			pos +=696			    scnprintf(buf + pos, bufsz - pos,697				      "\tRx handler[%36s]:\t\t %u\n",698				      il_get_cmd_string(cnt),699				      il->isr_stats.handlers[cnt]);700	}701 702	pos +=703	    scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n",704		      il->isr_stats.tx);705 706	pos +=707	    scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n",708		      il->isr_stats.unhandled);709 710	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);711	kfree(buf);712	return ret;713}714 715static ssize_t716il_dbgfs_interrupt_write(struct file *file, const char __user *user_buf,717			 size_t count, loff_t *ppos)718{719	struct il_priv *il = file->private_data;720	char buf[8];721	int buf_size;722	u32 reset_flag;723 724	memset(buf, 0, sizeof(buf));725	buf_size = min(count, sizeof(buf) - 1);726	if (copy_from_user(buf, user_buf, buf_size))727		return -EFAULT;728	if (sscanf(buf, "%x", &reset_flag) != 1)729		return -EFAULT;730	if (reset_flag == 0)731		il_clear_isr_stats(il);732 733	return count;734}735 736static ssize_t737il_dbgfs_qos_read(struct file *file, char __user *user_buf, size_t count,738		  loff_t *ppos)739{740	struct il_priv *il = file->private_data;741	int pos = 0, i;742	char buf[256];743	const size_t bufsz = sizeof(buf);744 745	for (i = 0; i < AC_NUM; i++) {746		pos +=747		    scnprintf(buf + pos, bufsz - pos,748			      "\tcw_min\tcw_max\taifsn\ttxop\n");749		pos +=750		    scnprintf(buf + pos, bufsz - pos,751			      "AC[%d]\t%u\t%u\t%u\t%u\n", i,752			      il->qos_data.def_qos_parm.ac[i].cw_min,753			      il->qos_data.def_qos_parm.ac[i].cw_max,754			      il->qos_data.def_qos_parm.ac[i].aifsn,755			      il->qos_data.def_qos_parm.ac[i].edca_txop);756	}757 758	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);759}760 761static ssize_t762il_dbgfs_disable_ht40_write(struct file *file, const char __user *user_buf,763			    size_t count, loff_t *ppos)764{765	struct il_priv *il = file->private_data;766	char buf[8];767	int buf_size;768	int ht40;769 770	memset(buf, 0, sizeof(buf));771	buf_size = min(count, sizeof(buf) - 1);772	if (copy_from_user(buf, user_buf, buf_size))773		return -EFAULT;774	if (sscanf(buf, "%d", &ht40) != 1)775		return -EFAULT;776	if (!il_is_any_associated(il))777		il->disable_ht40 = ht40 ? true : false;778	else {779		IL_ERR("Sta associated with AP - "780		       "Change to 40MHz channel support is not allowed\n");781		return -EINVAL;782	}783 784	return count;785}786 787static ssize_t788il_dbgfs_disable_ht40_read(struct file *file, char __user *user_buf,789			   size_t count, loff_t *ppos)790{791	struct il_priv *il = file->private_data;792	char buf[100];793	int pos = 0;794	const size_t bufsz = sizeof(buf);795 796	pos +=797	    scnprintf(buf + pos, bufsz - pos, "11n 40MHz Mode: %s\n",798		      il->disable_ht40 ? "Disabled" : "Enabled");799	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);800}801 802DEBUGFS_READ_WRITE_FILE_OPS(sram);803DEBUGFS_READ_FILE_OPS(nvm);804DEBUGFS_READ_FILE_OPS(stations);805DEBUGFS_READ_FILE_OPS(channels);806DEBUGFS_READ_FILE_OPS(status);807DEBUGFS_READ_WRITE_FILE_OPS(interrupt);808DEBUGFS_READ_FILE_OPS(qos);809DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40);810 811static ssize_t812il_dbgfs_tx_queue_read(struct file *file, char __user *user_buf, size_t count,813		       loff_t *ppos)814{815 816	struct il_priv *il = file->private_data;817	struct il_tx_queue *txq;818	struct il_queue *q;819	char *buf;820	int pos = 0;821	int cnt;822	int ret;823	const size_t bufsz =824	    sizeof(char) * 64 * il->cfg->num_of_queues;825 826	if (!il->txq) {827		IL_ERR("txq not ready\n");828		return -EAGAIN;829	}830	buf = kzalloc(bufsz, GFP_KERNEL);831	if (!buf)832		return -ENOMEM;833 834	for (cnt = 0; cnt < il->hw_params.max_txq_num; cnt++) {835		txq = &il->txq[cnt];836		q = &txq->q;837		pos +=838		    scnprintf(buf + pos, bufsz - pos,839			      "hwq %.2d: read=%u write=%u stop=%d"840			      " swq_id=%#.2x (ac %d/hwq %d)\n", cnt,841			      q->read_ptr, q->write_ptr,842			      !!test_bit(cnt, il->queue_stopped),843			      txq->swq_id, txq->swq_id & 3,844			      (txq->swq_id >> 2) & 0x1f);845		if (cnt >= 4)846			continue;847		/* for the ACs, display the stop count too */848		pos +=849		    scnprintf(buf + pos, bufsz - pos,850			      "        stop-count: %d\n",851			      atomic_read(&il->queue_stop_count[cnt]));852	}853	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);854	kfree(buf);855	return ret;856}857 858static ssize_t859il_dbgfs_rx_queue_read(struct file *file, char __user *user_buf, size_t count,860		       loff_t *ppos)861{862 863	struct il_priv *il = file->private_data;864	struct il_rx_queue *rxq = &il->rxq;865	char buf[256];866	int pos = 0;867	const size_t bufsz = sizeof(buf);868 869	pos += scnprintf(buf + pos, bufsz - pos, "read: %u\n", rxq->read);870	pos += scnprintf(buf + pos, bufsz - pos, "write: %u\n", rxq->write);871	pos +=872	    scnprintf(buf + pos, bufsz - pos, "free_count: %u\n",873		      rxq->free_count);874	if (rxq->rb_stts) {875		pos +=876		    scnprintf(buf + pos, bufsz - pos, "closed_rb_num: %u\n",877			      le16_to_cpu(rxq->rb_stts->878					  closed_rb_num) & 0x0FFF);879	} else {880		pos +=881		    scnprintf(buf + pos, bufsz - pos,882			      "closed_rb_num: Not Allocated\n");883	}884	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);885}886 887static ssize_t888il_dbgfs_ucode_rx_stats_read(struct file *file, char __user *user_buf,889			     size_t count, loff_t *ppos)890{891	struct il_priv *il = file->private_data;892 893	return il->debugfs_ops->rx_stats_read(file, user_buf, count, ppos);894}895 896static ssize_t897il_dbgfs_ucode_tx_stats_read(struct file *file, char __user *user_buf,898			     size_t count, loff_t *ppos)899{900	struct il_priv *il = file->private_data;901 902	return il->debugfs_ops->tx_stats_read(file, user_buf, count, ppos);903}904 905static ssize_t906il_dbgfs_ucode_general_stats_read(struct file *file, char __user *user_buf,907				  size_t count, loff_t *ppos)908{909	struct il_priv *il = file->private_data;910 911	return il->debugfs_ops->general_stats_read(file, user_buf, count, ppos);912}913 914static ssize_t915il_dbgfs_sensitivity_read(struct file *file, char __user *user_buf,916			  size_t count, loff_t *ppos)917{918 919	struct il_priv *il = file->private_data;920	int pos = 0;921	int cnt = 0;922	char *buf;923	int bufsz = sizeof(struct il_sensitivity_data) * 4 + 100;924	ssize_t ret;925	struct il_sensitivity_data *data;926 927	data = &il->sensitivity_data;928	buf = kzalloc(bufsz, GFP_KERNEL);929	if (!buf) {930		IL_ERR("Can not allocate Buffer\n");931		return -ENOMEM;932	}933 934	pos +=935	    scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm:\t\t\t %u\n",936		      data->auto_corr_ofdm);937	pos +=938	    scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_mrc:\t\t %u\n",939		      data->auto_corr_ofdm_mrc);940	pos +=941	    scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_x1:\t\t %u\n",942		      data->auto_corr_ofdm_x1);943	pos +=944	    scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_mrc_x1:\t\t %u\n",945		      data->auto_corr_ofdm_mrc_x1);946	pos +=947	    scnprintf(buf + pos, bufsz - pos, "auto_corr_cck:\t\t\t %u\n",948		      data->auto_corr_cck);949	pos +=950	    scnprintf(buf + pos, bufsz - pos, "auto_corr_cck_mrc:\t\t %u\n",951		      data->auto_corr_cck_mrc);952	pos +=953	    scnprintf(buf + pos, bufsz - pos,954		      "last_bad_plcp_cnt_ofdm:\t\t %u\n",955		      data->last_bad_plcp_cnt_ofdm);956	pos +=957	    scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_ofdm:\t\t %u\n",958		      data->last_fa_cnt_ofdm);959	pos +=960	    scnprintf(buf + pos, bufsz - pos, "last_bad_plcp_cnt_cck:\t\t %u\n",961		      data->last_bad_plcp_cnt_cck);962	pos +=963	    scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_cck:\t\t %u\n",964		      data->last_fa_cnt_cck);965	pos +=966	    scnprintf(buf + pos, bufsz - pos, "nrg_curr_state:\t\t\t %u\n",967		      data->nrg_curr_state);968	pos +=969	    scnprintf(buf + pos, bufsz - pos, "nrg_prev_state:\t\t\t %u\n",970		      data->nrg_prev_state);971	pos += scnprintf(buf + pos, bufsz - pos, "nrg_value:\t\t\t");972	for (cnt = 0; cnt < 10; cnt++) {973		pos +=974		    scnprintf(buf + pos, bufsz - pos, " %u",975			      data->nrg_value[cnt]);976	}977	pos += scnprintf(buf + pos, bufsz - pos, "\n");978	pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_rssi:\t\t");979	for (cnt = 0; cnt < NRG_NUM_PREV_STAT_L; cnt++) {980		pos +=981		    scnprintf(buf + pos, bufsz - pos, " %u",982			      data->nrg_silence_rssi[cnt]);983	}984	pos += scnprintf(buf + pos, bufsz - pos, "\n");985	pos +=986	    scnprintf(buf + pos, bufsz - pos, "nrg_silence_ref:\t\t %u\n",987		      data->nrg_silence_ref);988	pos +=989	    scnprintf(buf + pos, bufsz - pos, "nrg_energy_idx:\t\t\t %u\n",990		      data->nrg_energy_idx);991	pos +=992	    scnprintf(buf + pos, bufsz - pos, "nrg_silence_idx:\t\t %u\n",993		      data->nrg_silence_idx);994	pos +=995	    scnprintf(buf + pos, bufsz - pos, "nrg_th_cck:\t\t\t %u\n",996		      data->nrg_th_cck);997	pos +=998	    scnprintf(buf + pos, bufsz - pos,999		      "nrg_auto_corr_silence_diff:\t %u\n",1000		      data->nrg_auto_corr_silence_diff);1001	pos +=1002	    scnprintf(buf + pos, bufsz - pos, "num_in_cck_no_fa:\t\t %u\n",1003		      data->num_in_cck_no_fa);1004	pos +=1005	    scnprintf(buf + pos, bufsz - pos, "nrg_th_ofdm:\t\t\t %u\n",1006		      data->nrg_th_ofdm);1007 1008	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);1009	kfree(buf);1010	return ret;1011}1012 1013static ssize_t1014il_dbgfs_chain_noise_read(struct file *file, char __user *user_buf,1015			  size_t count, loff_t *ppos)1016{1017 1018	struct il_priv *il = file->private_data;1019	int pos = 0;1020	int cnt = 0;1021	char *buf;1022	int bufsz = sizeof(struct il_chain_noise_data) * 4 + 100;1023	ssize_t ret;1024	struct il_chain_noise_data *data;1025 1026	data = &il->chain_noise_data;1027	buf = kzalloc(bufsz, GFP_KERNEL);1028	if (!buf) {1029		IL_ERR("Can not allocate Buffer\n");1030		return -ENOMEM;1031	}1032 1033	pos +=1034	    scnprintf(buf + pos, bufsz - pos, "active_chains:\t\t\t %u\n",1035		      data->active_chains);1036	pos +=1037	    scnprintf(buf + pos, bufsz - pos, "chain_noise_a:\t\t\t %u\n",1038		      data->chain_noise_a);1039	pos +=1040	    scnprintf(buf + pos, bufsz - pos, "chain_noise_b:\t\t\t %u\n",1041		      data->chain_noise_b);1042	pos +=1043	    scnprintf(buf + pos, bufsz - pos, "chain_noise_c:\t\t\t %u\n",1044		      data->chain_noise_c);1045	pos +=1046	    scnprintf(buf + pos, bufsz - pos, "chain_signal_a:\t\t\t %u\n",1047		      data->chain_signal_a);1048	pos +=1049	    scnprintf(buf + pos, bufsz - pos, "chain_signal_b:\t\t\t %u\n",1050		      data->chain_signal_b);1051	pos +=1052	    scnprintf(buf + pos, bufsz - pos, "chain_signal_c:\t\t\t %u\n",1053		      data->chain_signal_c);1054	pos +=1055	    scnprintf(buf + pos, bufsz - pos, "beacon_count:\t\t\t %u\n",1056		      data->beacon_count);1057 1058	pos += scnprintf(buf + pos, bufsz - pos, "disconn_array:\t\t\t");1059	for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {1060		pos +=1061		    scnprintf(buf + pos, bufsz - pos, " %u",1062			      data->disconn_array[cnt]);1063	}1064	pos += scnprintf(buf + pos, bufsz - pos, "\n");1065	pos += scnprintf(buf + pos, bufsz - pos, "delta_gain_code:\t\t");1066	for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) {1067		pos +=1068		    scnprintf(buf + pos, bufsz - pos, " %u",1069			      data->delta_gain_code[cnt]);1070	}1071	pos += scnprintf(buf + pos, bufsz - pos, "\n");1072	pos +=1073	    scnprintf(buf + pos, bufsz - pos, "radio_write:\t\t\t %u\n",1074		      data->radio_write);1075	pos +=1076	    scnprintf(buf + pos, bufsz - pos, "state:\t\t\t\t %u\n",1077		      data->state);1078 1079	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);1080	kfree(buf);1081	return ret;1082}1083 1084static ssize_t1085il_dbgfs_power_save_status_read(struct file *file, char __user *user_buf,1086				size_t count, loff_t *ppos)1087{1088	struct il_priv *il = file->private_data;1089	char buf[60];1090	int pos = 0;1091	const size_t bufsz = sizeof(buf);1092	u32 pwrsave_status;1093 1094	pwrsave_status =1095	    _il_rd(il, CSR_GP_CNTRL) & CSR_GP_REG_POWER_SAVE_STATUS_MSK;1096 1097	pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: ");1098	pos +=1099	    scnprintf(buf + pos, bufsz - pos, "%s\n",1100		      (pwrsave_status == CSR_GP_REG_NO_POWER_SAVE) ? "none" :1101		      (pwrsave_status == CSR_GP_REG_MAC_POWER_SAVE) ? "MAC" :1102		      (pwrsave_status == CSR_GP_REG_PHY_POWER_SAVE) ? "PHY" :1103		      "error");1104 1105	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);1106}1107 1108static ssize_t1109il_dbgfs_clear_ucode_stats_write(struct file *file,1110				 const char __user *user_buf, size_t count,1111				 loff_t *ppos)1112{1113	struct il_priv *il = file->private_data;1114	char buf[8];1115	int buf_size;1116	int clear;1117 1118	memset(buf, 0, sizeof(buf));1119	buf_size = min(count, sizeof(buf) - 1);1120	if (copy_from_user(buf, user_buf, buf_size))1121		return -EFAULT;1122	if (sscanf(buf, "%d", &clear) != 1)1123		return -EFAULT;1124 1125	/* make request to uCode to retrieve stats information */1126	mutex_lock(&il->mutex);1127	il_send_stats_request(il, CMD_SYNC, true);1128	mutex_unlock(&il->mutex);1129 1130	return count;1131}1132 1133static ssize_t1134il_dbgfs_rxon_flags_read(struct file *file, char __user *user_buf,1135			 size_t count, loff_t *ppos)1136{1137 1138	struct il_priv *il = file->private_data;1139	int len = 0;1140	char buf[20];1141 1142	len = sprintf(buf, "0x%04X\n", le32_to_cpu(il->active.flags));1143	return simple_read_from_buffer(user_buf, count, ppos, buf, len);1144}1145 1146static ssize_t1147il_dbgfs_rxon_filter_flags_read(struct file *file, char __user *user_buf,1148				size_t count, loff_t *ppos)1149{1150 1151	struct il_priv *il = file->private_data;1152	int len = 0;1153	char buf[20];1154 1155	len =1156	    sprintf(buf, "0x%04X\n", le32_to_cpu(il->active.filter_flags));1157	return simple_read_from_buffer(user_buf, count, ppos, buf, len);1158}1159 1160static ssize_t1161il_dbgfs_fh_reg_read(struct file *file, char __user *user_buf, size_t count,1162		     loff_t *ppos)1163{1164	struct il_priv *il = file->private_data;1165	char *buf;1166	int pos = 0;1167	ssize_t ret = -EFAULT;1168 1169	if (il->ops->dump_fh) {1170		ret = pos = il->ops->dump_fh(il, &buf, true);1171		if (buf) {1172			ret =1173			    simple_read_from_buffer(user_buf, count, ppos, buf,1174						    pos);1175			kfree(buf);1176		}1177	}1178 1179	return ret;1180}1181 1182static ssize_t1183il_dbgfs_missed_beacon_read(struct file *file, char __user *user_buf,1184			    size_t count, loff_t *ppos)1185{1186 1187	struct il_priv *il = file->private_data;1188	int pos = 0;1189	char buf[12];1190	const size_t bufsz = sizeof(buf);1191 1192	pos +=1193	    scnprintf(buf + pos, bufsz - pos, "%d\n",1194		      il->missed_beacon_threshold);1195 1196	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);1197}1198 1199static ssize_t1200il_dbgfs_missed_beacon_write(struct file *file, const char __user *user_buf,1201			     size_t count, loff_t *ppos)1202{1203	struct il_priv *il = file->private_data;1204	char buf[8];1205	int buf_size;1206	int missed;1207 1208	memset(buf, 0, sizeof(buf));1209	buf_size = min(count, sizeof(buf) - 1);1210	if (copy_from_user(buf, user_buf, buf_size))1211		return -EFAULT;1212	if (sscanf(buf, "%d", &missed) != 1)1213		return -EINVAL;1214 1215	if (missed < IL_MISSED_BEACON_THRESHOLD_MIN ||1216	    missed > IL_MISSED_BEACON_THRESHOLD_MAX)1217		il->missed_beacon_threshold = IL_MISSED_BEACON_THRESHOLD_DEF;1218	else1219		il->missed_beacon_threshold = missed;1220 1221	return count;1222}1223 1224static ssize_t1225il_dbgfs_force_reset_read(struct file *file, char __user *user_buf,1226			  size_t count, loff_t *ppos)1227{1228 1229	struct il_priv *il = file->private_data;1230	int pos = 0;1231	char buf[300];1232	const size_t bufsz = sizeof(buf);1233	struct il_force_reset *force_reset;1234 1235	force_reset = &il->force_reset;1236 1237	pos +=1238	    scnprintf(buf + pos, bufsz - pos, "\tnumber of reset request: %d\n",1239		      force_reset->reset_request_count);1240	pos +=1241	    scnprintf(buf + pos, bufsz - pos,1242		      "\tnumber of reset request success: %d\n",1243		      force_reset->reset_success_count);1244	pos +=1245	    scnprintf(buf + pos, bufsz - pos,1246		      "\tnumber of reset request reject: %d\n",1247		      force_reset->reset_reject_count);1248	pos +=1249	    scnprintf(buf + pos, bufsz - pos, "\treset duration: %lu\n",1250		      force_reset->reset_duration);1251 1252	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);1253}1254 1255static ssize_t1256il_dbgfs_force_reset_write(struct file *file, const char __user *user_buf,1257			   size_t count, loff_t *ppos)1258{1259 1260	int ret;1261	struct il_priv *il = file->private_data;1262 1263	ret = il_force_reset(il, true);1264 1265	return ret ? ret : count;1266}1267 1268static ssize_t1269il_dbgfs_wd_timeout_write(struct file *file, const char __user *user_buf,1270			  size_t count, loff_t *ppos)1271{1272 1273	struct il_priv *il = file->private_data;1274	char buf[8];1275	int buf_size;1276	int timeout;1277 1278	memset(buf, 0, sizeof(buf));1279	buf_size = min(count, sizeof(buf) - 1);1280	if (copy_from_user(buf, user_buf, buf_size))1281		return -EFAULT;1282	if (sscanf(buf, "%d", &timeout) != 1)1283		return -EINVAL;1284	if (timeout < 0 || timeout > IL_MAX_WD_TIMEOUT)1285		timeout = IL_DEF_WD_TIMEOUT;1286 1287	il->cfg->wd_timeout = timeout;1288	il_setup_watchdog(il);1289	return count;1290}1291 1292DEBUGFS_READ_FILE_OPS(rx_stats);1293DEBUGFS_READ_FILE_OPS(tx_stats);1294DEBUGFS_READ_FILE_OPS(rx_queue);1295DEBUGFS_READ_FILE_OPS(tx_queue);1296DEBUGFS_READ_FILE_OPS(ucode_rx_stats);1297DEBUGFS_READ_FILE_OPS(ucode_tx_stats);1298DEBUGFS_READ_FILE_OPS(ucode_general_stats);1299DEBUGFS_READ_FILE_OPS(sensitivity);1300DEBUGFS_READ_FILE_OPS(chain_noise);1301DEBUGFS_READ_FILE_OPS(power_save_status);1302DEBUGFS_WRITE_FILE_OPS(clear_ucode_stats);1303DEBUGFS_WRITE_FILE_OPS(clear_traffic_stats);1304DEBUGFS_READ_FILE_OPS(fh_reg);1305DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon);1306DEBUGFS_READ_WRITE_FILE_OPS(force_reset);1307DEBUGFS_READ_FILE_OPS(rxon_flags);1308DEBUGFS_READ_FILE_OPS(rxon_filter_flags);1309DEBUGFS_WRITE_FILE_OPS(wd_timeout);1310 1311/*1312 * Create the debugfs files and directories1313 *1314 */1315void1316il_dbgfs_register(struct il_priv *il, const char *name)1317{1318	struct dentry *phyd = il->hw->wiphy->debugfsdir;1319	struct dentry *dir_drv, *dir_data, *dir_rf, *dir_debug;1320 1321	dir_drv = debugfs_create_dir(name, phyd);1322	il->debugfs_dir = dir_drv;1323 1324	dir_data = debugfs_create_dir("data", dir_drv);1325	dir_rf = debugfs_create_dir("rf", dir_drv);1326	dir_debug = debugfs_create_dir("debug", dir_drv);1327 1328	DEBUGFS_ADD_FILE(nvm, dir_data, 0400);1329	DEBUGFS_ADD_FILE(sram, dir_data, 0600);1330	DEBUGFS_ADD_FILE(stations, dir_data, 0400);1331	DEBUGFS_ADD_FILE(channels, dir_data, 0400);1332	DEBUGFS_ADD_FILE(status, dir_data, 0400);1333	DEBUGFS_ADD_FILE(interrupt, dir_data, 0600);1334	DEBUGFS_ADD_FILE(qos, dir_data, 0400);1335	DEBUGFS_ADD_FILE(disable_ht40, dir_data, 0600);1336	DEBUGFS_ADD_FILE(rx_stats, dir_debug, 0400);1337	DEBUGFS_ADD_FILE(tx_stats, dir_debug, 0400);1338	DEBUGFS_ADD_FILE(rx_queue, dir_debug, 0400);1339	DEBUGFS_ADD_FILE(tx_queue, dir_debug, 0400);1340	DEBUGFS_ADD_FILE(power_save_status, dir_debug, 0400);1341	DEBUGFS_ADD_FILE(clear_ucode_stats, dir_debug, 0200);1342	DEBUGFS_ADD_FILE(clear_traffic_stats, dir_debug, 0200);1343	DEBUGFS_ADD_FILE(fh_reg, dir_debug, 0400);1344	DEBUGFS_ADD_FILE(missed_beacon, dir_debug, 0200);1345	DEBUGFS_ADD_FILE(force_reset, dir_debug, 0600);1346	DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, 0400);1347	DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, 0400);1348	DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, 0400);1349 1350	if (il->cfg->sensitivity_calib_by_driver)1351		DEBUGFS_ADD_FILE(sensitivity, dir_debug, 0400);1352	if (il->cfg->chain_noise_calib_by_driver)1353		DEBUGFS_ADD_FILE(chain_noise, dir_debug, 0400);1354	DEBUGFS_ADD_FILE(rxon_flags, dir_debug, 0200);1355	DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, 0200);1356	DEBUGFS_ADD_FILE(wd_timeout, dir_debug, 0200);1357	if (il->cfg->sensitivity_calib_by_driver)1358		DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf,1359				 &il->disable_sens_cal);1360	if (il->cfg->chain_noise_calib_by_driver)1361		DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,1362				 &il->disable_chain_noise_cal);1363	DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf, &il->disable_tx_power_cal);1364}1365EXPORT_SYMBOL(il_dbgfs_register);1366 1367/*1368 * Remove the debugfs files and directories1369 */1370void1371il_dbgfs_unregister(struct il_priv *il)1372{1373	if (!il->debugfs_dir)1374		return;1375 1376	debugfs_remove_recursive(il->debugfs_dir);1377	il->debugfs_dir = NULL;1378}1379EXPORT_SYMBOL(il_dbgfs_unregister);1380