1*5316050eSLee Jones /* 2dad0d04fSFariya Fatima * Copyright (c) 2014 Redpine Signals Inc. 3dad0d04fSFariya Fatima * 4dad0d04fSFariya Fatima * Permission to use, copy, modify, and/or distribute this software for any 5dad0d04fSFariya Fatima * purpose with or without fee is hereby granted, provided that the above 6dad0d04fSFariya Fatima * copyright notice and this permission notice appear in all copies. 7dad0d04fSFariya Fatima * 8dad0d04fSFariya Fatima * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9dad0d04fSFariya Fatima * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10dad0d04fSFariya Fatima * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11dad0d04fSFariya Fatima * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12dad0d04fSFariya Fatima * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13dad0d04fSFariya Fatima * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14dad0d04fSFariya Fatima * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15dad0d04fSFariya Fatima */ 16dad0d04fSFariya Fatima 17dad0d04fSFariya Fatima #include "rsi_debugfs.h" 18dad0d04fSFariya Fatima #include "rsi_sdio.h" 19dad0d04fSFariya Fatima 20dad0d04fSFariya Fatima /** 21dad0d04fSFariya Fatima * rsi_sdio_stats_read() - This function returns the sdio status of the driver. 22dad0d04fSFariya Fatima * @seq: Pointer to the sequence file structure. 23dad0d04fSFariya Fatima * @data: Pointer to the data. 24dad0d04fSFariya Fatima * 25dad0d04fSFariya Fatima * Return: 0 on success, -1 on failure. 26dad0d04fSFariya Fatima */ 27dad0d04fSFariya Fatima static int rsi_sdio_stats_read(struct seq_file *seq, void *data) 28dad0d04fSFariya Fatima { 29dad0d04fSFariya Fatima struct rsi_common *common = seq->private; 30dad0d04fSFariya Fatima struct rsi_hw *adapter = common->priv; 31dad0d04fSFariya Fatima struct rsi_91x_sdiodev *dev = 32dad0d04fSFariya Fatima (struct rsi_91x_sdiodev *)adapter->rsi_dev; 33dad0d04fSFariya Fatima 34dad0d04fSFariya Fatima seq_printf(seq, "total_sdio_interrupts: %d\n", 35dad0d04fSFariya Fatima dev->rx_info.sdio_int_counter); 36dad0d04fSFariya Fatima seq_printf(seq, "sdio_msdu_pending_intr_count: %d\n", 37dad0d04fSFariya Fatima dev->rx_info.total_sdio_msdu_pending_intr); 38dad0d04fSFariya Fatima seq_printf(seq, "sdio_buff_full_count : %d\n", 39dad0d04fSFariya Fatima dev->rx_info.buf_full_counter); 40dad0d04fSFariya Fatima seq_printf(seq, "sdio_buf_semi_full_count %d\n", 41dad0d04fSFariya Fatima dev->rx_info.buf_semi_full_counter); 42dad0d04fSFariya Fatima seq_printf(seq, "sdio_unknown_intr_count: %d\n", 43dad0d04fSFariya Fatima dev->rx_info.total_sdio_unknown_intr); 44dad0d04fSFariya Fatima /* RX Path Stats */ 45dad0d04fSFariya Fatima seq_printf(seq, "BUFFER FULL STATUS : %d\n", 46dad0d04fSFariya Fatima dev->rx_info.buffer_full); 47dad0d04fSFariya Fatima seq_printf(seq, "SEMI BUFFER FULL STATUS : %d\n", 48dad0d04fSFariya Fatima dev->rx_info.semi_buffer_full); 49dad0d04fSFariya Fatima seq_printf(seq, "MGMT BUFFER FULL STATUS : %d\n", 50dad0d04fSFariya Fatima dev->rx_info.mgmt_buffer_full); 51dad0d04fSFariya Fatima seq_printf(seq, "BUFFER FULL COUNTER : %d\n", 52dad0d04fSFariya Fatima dev->rx_info.buf_full_counter); 53dad0d04fSFariya Fatima seq_printf(seq, "BUFFER SEMI FULL COUNTER : %d\n", 54dad0d04fSFariya Fatima dev->rx_info.buf_semi_full_counter); 55dad0d04fSFariya Fatima seq_printf(seq, "MGMT BUFFER FULL COUNTER : %d\n", 56dad0d04fSFariya Fatima dev->rx_info.mgmt_buf_full_counter); 57dad0d04fSFariya Fatima 58dad0d04fSFariya Fatima return 0; 59dad0d04fSFariya Fatima } 60dad0d04fSFariya Fatima 61dad0d04fSFariya Fatima /** 62b9c767fdSSiva Rebbagondla * rsi_sdio_stats_open() - This function calls single open function of seq_file 63dad0d04fSFariya Fatima * to open file and read contents from it. 64dad0d04fSFariya Fatima * @inode: Pointer to the inode structure. 65dad0d04fSFariya Fatima * @file: Pointer to the file structure. 66dad0d04fSFariya Fatima * 67dad0d04fSFariya Fatima * Return: Pointer to the opened file status: 0 on success, ENOMEM on failure. 68dad0d04fSFariya Fatima */ 69dad0d04fSFariya Fatima static int rsi_sdio_stats_open(struct inode *inode, 70dad0d04fSFariya Fatima struct file *file) 71dad0d04fSFariya Fatima { 72dad0d04fSFariya Fatima return single_open(file, rsi_sdio_stats_read, inode->i_private); 73dad0d04fSFariya Fatima } 74dad0d04fSFariya Fatima 75dad0d04fSFariya Fatima /** 76dad0d04fSFariya Fatima * rsi_version_read() - This function gives driver and firmware version number. 77dad0d04fSFariya Fatima * @seq: Pointer to the sequence file structure. 78dad0d04fSFariya Fatima * @data: Pointer to the data. 79dad0d04fSFariya Fatima * 80dad0d04fSFariya Fatima * Return: 0 on success, -1 on failure. 81dad0d04fSFariya Fatima */ 82dad0d04fSFariya Fatima static int rsi_version_read(struct seq_file *seq, void *data) 83dad0d04fSFariya Fatima { 84dad0d04fSFariya Fatima struct rsi_common *common = seq->private; 85dad0d04fSFariya Fatima 86192524a4SPavani Muthyala seq_printf(seq, "LMAC : %d.%d.%d.%d\n", 87192524a4SPavani Muthyala common->lmac_ver.major, 88192524a4SPavani Muthyala common->lmac_ver.minor, 89192524a4SPavani Muthyala common->lmac_ver.release_num, 90192524a4SPavani Muthyala common->lmac_ver.patch_num); 91192524a4SPavani Muthyala 92dad0d04fSFariya Fatima return 0; 93dad0d04fSFariya Fatima } 94dad0d04fSFariya Fatima 95dad0d04fSFariya Fatima /** 96b9c767fdSSiva Rebbagondla * rsi_version_open() - This function calls single open function of seq_file to 97dad0d04fSFariya Fatima * open file and read contents from it. 98dad0d04fSFariya Fatima * @inode: Pointer to the inode structure. 99dad0d04fSFariya Fatima * @file: Pointer to the file structure. 100dad0d04fSFariya Fatima * 101dad0d04fSFariya Fatima * Return: Pointer to the opened file status: 0 on success, ENOMEM on failure. 102dad0d04fSFariya Fatima */ 103dad0d04fSFariya Fatima static int rsi_version_open(struct inode *inode, 104dad0d04fSFariya Fatima struct file *file) 105dad0d04fSFariya Fatima { 106dad0d04fSFariya Fatima return single_open(file, rsi_version_read, inode->i_private); 107dad0d04fSFariya Fatima } 108dad0d04fSFariya Fatima 109dad0d04fSFariya Fatima /** 110dad0d04fSFariya Fatima * rsi_stats_read() - This function return the status of the driver. 111dad0d04fSFariya Fatima * @seq: Pointer to the sequence file structure. 112dad0d04fSFariya Fatima * @data: Pointer to the data. 113dad0d04fSFariya Fatima * 114dad0d04fSFariya Fatima * Return: 0 on success, -1 on failure. 115dad0d04fSFariya Fatima */ 116dad0d04fSFariya Fatima static int rsi_stats_read(struct seq_file *seq, void *data) 117dad0d04fSFariya Fatima { 118dad0d04fSFariya Fatima struct rsi_common *common = seq->private; 119dad0d04fSFariya Fatima 120dad0d04fSFariya Fatima unsigned char fsm_state[][32] = { 12158828680SColin Ian King "FSM_FW_NOT_LOADED", 122dad0d04fSFariya Fatima "FSM_CARD_NOT_READY", 12358828680SColin Ian King "FSM_COMMON_DEV_PARAMS_SENT", 124dad0d04fSFariya Fatima "FSM_BOOT_PARAMS_SENT", 125dad0d04fSFariya Fatima "FSM_EEPROM_READ_MAC_ADDR", 12609cfb41fSPrameela Rani Garnepudi "FSM_EEPROM_READ_RF_TYPE", 127dad0d04fSFariya Fatima "FSM_RESET_MAC_SENT", 128dad0d04fSFariya Fatima "FSM_RADIO_CAPS_SENT", 129dad0d04fSFariya Fatima "FSM_BB_RF_PROG_SENT", 130dad0d04fSFariya Fatima "FSM_MAC_INIT_DONE" 131dad0d04fSFariya Fatima }; 132dad0d04fSFariya Fatima seq_puts(seq, "==> RSI STA DRIVER STATUS <==\n"); 133dad0d04fSFariya Fatima seq_puts(seq, "DRIVER_FSM_STATE: "); 134dad0d04fSFariya Fatima 135e0d0ae8aSAmitkumar Karwar BUILD_BUG_ON(ARRAY_SIZE(fsm_state) != NUM_FSM_STATES); 136e0d0ae8aSAmitkumar Karwar 137dad0d04fSFariya Fatima if (common->fsm_state <= FSM_MAC_INIT_DONE) 138dad0d04fSFariya Fatima seq_printf(seq, "%s", fsm_state[common->fsm_state]); 139dad0d04fSFariya Fatima 140dad0d04fSFariya Fatima seq_printf(seq, "(%d)\n\n", common->fsm_state); 141dad0d04fSFariya Fatima 142dad0d04fSFariya Fatima /* Mgmt TX Path Stats */ 143dad0d04fSFariya Fatima seq_printf(seq, "total_mgmt_pkt_send : %d\n", 144dad0d04fSFariya Fatima common->tx_stats.total_tx_pkt_send[MGMT_SOFT_Q]); 145dad0d04fSFariya Fatima seq_printf(seq, "total_mgmt_pkt_queued : %d\n", 14651b4a86aSJahnavi Meher skb_queue_len(&common->tx_queue[MGMT_SOFT_Q])); 147dad0d04fSFariya Fatima seq_printf(seq, "total_mgmt_pkt_freed : %d\n", 148dad0d04fSFariya Fatima common->tx_stats.total_tx_pkt_freed[MGMT_SOFT_Q]); 149dad0d04fSFariya Fatima 150dad0d04fSFariya Fatima /* Data TX Path Stats */ 151dad0d04fSFariya Fatima seq_printf(seq, "total_data_vo_pkt_send: %8d\t", 152dad0d04fSFariya Fatima common->tx_stats.total_tx_pkt_send[VO_Q]); 153dad0d04fSFariya Fatima seq_printf(seq, "total_data_vo_pkt_queued: %8d\t", 15451b4a86aSJahnavi Meher skb_queue_len(&common->tx_queue[VO_Q])); 155dad0d04fSFariya Fatima seq_printf(seq, "total_vo_pkt_freed: %8d\n", 156dad0d04fSFariya Fatima common->tx_stats.total_tx_pkt_freed[VO_Q]); 157dad0d04fSFariya Fatima seq_printf(seq, "total_data_vi_pkt_send: %8d\t", 158dad0d04fSFariya Fatima common->tx_stats.total_tx_pkt_send[VI_Q]); 159dad0d04fSFariya Fatima seq_printf(seq, "total_data_vi_pkt_queued: %8d\t", 16051b4a86aSJahnavi Meher skb_queue_len(&common->tx_queue[VI_Q])); 161dad0d04fSFariya Fatima seq_printf(seq, "total_vi_pkt_freed: %8d\n", 162dad0d04fSFariya Fatima common->tx_stats.total_tx_pkt_freed[VI_Q]); 163dad0d04fSFariya Fatima seq_printf(seq, "total_data_be_pkt_send: %8d\t", 164dad0d04fSFariya Fatima common->tx_stats.total_tx_pkt_send[BE_Q]); 165dad0d04fSFariya Fatima seq_printf(seq, "total_data_be_pkt_queued: %8d\t", 16651b4a86aSJahnavi Meher skb_queue_len(&common->tx_queue[BE_Q])); 167dad0d04fSFariya Fatima seq_printf(seq, "total_be_pkt_freed: %8d\n", 168dad0d04fSFariya Fatima common->tx_stats.total_tx_pkt_freed[BE_Q]); 169dad0d04fSFariya Fatima seq_printf(seq, "total_data_bk_pkt_send: %8d\t", 170dad0d04fSFariya Fatima common->tx_stats.total_tx_pkt_send[BK_Q]); 171dad0d04fSFariya Fatima seq_printf(seq, "total_data_bk_pkt_queued: %8d\t", 17251b4a86aSJahnavi Meher skb_queue_len(&common->tx_queue[BK_Q])); 173dad0d04fSFariya Fatima seq_printf(seq, "total_bk_pkt_freed: %8d\n", 174dad0d04fSFariya Fatima common->tx_stats.total_tx_pkt_freed[BK_Q]); 175dad0d04fSFariya Fatima 176dad0d04fSFariya Fatima seq_puts(seq, "\n"); 177dad0d04fSFariya Fatima return 0; 178dad0d04fSFariya Fatima } 179dad0d04fSFariya Fatima 180dad0d04fSFariya Fatima /** 181b9c767fdSSiva Rebbagondla * rsi_stats_open() - This function calls single open function of seq_file to 182dad0d04fSFariya Fatima * open file and read contents from it. 183dad0d04fSFariya Fatima * @inode: Pointer to the inode structure. 184dad0d04fSFariya Fatima * @file: Pointer to the file structure. 185dad0d04fSFariya Fatima * 186dad0d04fSFariya Fatima * Return: Pointer to the opened file status: 0 on success, ENOMEM on failure. 187dad0d04fSFariya Fatima */ 188dad0d04fSFariya Fatima static int rsi_stats_open(struct inode *inode, 189dad0d04fSFariya Fatima struct file *file) 190dad0d04fSFariya Fatima { 191dad0d04fSFariya Fatima return single_open(file, rsi_stats_read, inode->i_private); 192dad0d04fSFariya Fatima } 193dad0d04fSFariya Fatima 194dad0d04fSFariya Fatima /** 195dad0d04fSFariya Fatima * rsi_debug_zone_read() - This function display the currently enabled debug zones. 196dad0d04fSFariya Fatima * @seq: Pointer to the sequence file structure. 197dad0d04fSFariya Fatima * @data: Pointer to the data. 198dad0d04fSFariya Fatima * 199dad0d04fSFariya Fatima * Return: 0 on success, -1 on failure. 200dad0d04fSFariya Fatima */ 201dad0d04fSFariya Fatima static int rsi_debug_zone_read(struct seq_file *seq, void *data) 202dad0d04fSFariya Fatima { 203dad0d04fSFariya Fatima rsi_dbg(FSM_ZONE, "%x: rsi_enabled zone", rsi_zone_enabled); 204dad0d04fSFariya Fatima seq_printf(seq, "The zones available are %#x\n", 205dad0d04fSFariya Fatima rsi_zone_enabled); 206dad0d04fSFariya Fatima return 0; 207dad0d04fSFariya Fatima } 208dad0d04fSFariya Fatima 209dad0d04fSFariya Fatima /** 210b9c767fdSSiva Rebbagondla * rsi_debug_read() - This function calls single open function of seq_file to 211dad0d04fSFariya Fatima * open file and read contents from it. 212dad0d04fSFariya Fatima * @inode: Pointer to the inode structure. 213dad0d04fSFariya Fatima * @file: Pointer to the file structure. 214dad0d04fSFariya Fatima * 215dad0d04fSFariya Fatima * Return: Pointer to the opened file status: 0 on success, ENOMEM on failure. 216dad0d04fSFariya Fatima */ 217dad0d04fSFariya Fatima static int rsi_debug_read(struct inode *inode, 218dad0d04fSFariya Fatima struct file *file) 219dad0d04fSFariya Fatima { 220dad0d04fSFariya Fatima return single_open(file, rsi_debug_zone_read, inode->i_private); 221dad0d04fSFariya Fatima } 222dad0d04fSFariya Fatima 223dad0d04fSFariya Fatima /** 224dad0d04fSFariya Fatima * rsi_debug_zone_write() - This function writes into hal queues as per user 225dad0d04fSFariya Fatima * requirement. 226dad0d04fSFariya Fatima * @filp: Pointer to the file structure. 227dad0d04fSFariya Fatima * @buff: Pointer to the character buffer. 228dad0d04fSFariya Fatima * @len: Length of the data to be written into buffer. 229dad0d04fSFariya Fatima * @data: Pointer to the data. 230dad0d04fSFariya Fatima * 231dad0d04fSFariya Fatima * Return: len: Number of bytes read. 232dad0d04fSFariya Fatima */ 233dad0d04fSFariya Fatima static ssize_t rsi_debug_zone_write(struct file *filp, 234dad0d04fSFariya Fatima const char __user *buff, 235dad0d04fSFariya Fatima size_t len, 236dad0d04fSFariya Fatima loff_t *data) 237dad0d04fSFariya Fatima { 238dad0d04fSFariya Fatima unsigned long dbg_zone; 239dad0d04fSFariya Fatima int ret; 240dad0d04fSFariya Fatima 241dad0d04fSFariya Fatima if (!len) 242dad0d04fSFariya Fatima return 0; 243dad0d04fSFariya Fatima 244dad0d04fSFariya Fatima ret = kstrtoul_from_user(buff, len, 16, &dbg_zone); 245dad0d04fSFariya Fatima 246dad0d04fSFariya Fatima if (ret) 247dad0d04fSFariya Fatima return ret; 248dad0d04fSFariya Fatima 249dad0d04fSFariya Fatima rsi_zone_enabled = dbg_zone; 250dad0d04fSFariya Fatima return len; 251dad0d04fSFariya Fatima } 252dad0d04fSFariya Fatima 253dad0d04fSFariya Fatima #define FOPS(fopen) { \ 254dad0d04fSFariya Fatima .owner = THIS_MODULE, \ 255dad0d04fSFariya Fatima .open = (fopen), \ 256dad0d04fSFariya Fatima .read = seq_read, \ 257dad0d04fSFariya Fatima .llseek = seq_lseek, \ 258dad0d04fSFariya Fatima } 259dad0d04fSFariya Fatima 260dad0d04fSFariya Fatima #define FOPS_RW(fopen, fwrite) { \ 261dad0d04fSFariya Fatima .owner = THIS_MODULE, \ 262dad0d04fSFariya Fatima .open = (fopen), \ 263dad0d04fSFariya Fatima .read = seq_read, \ 264dad0d04fSFariya Fatima .llseek = seq_lseek, \ 265dad0d04fSFariya Fatima .write = (fwrite), \ 266dad0d04fSFariya Fatima } 267dad0d04fSFariya Fatima 268dad0d04fSFariya Fatima static const struct rsi_dbg_files dev_debugfs_files[] = { 269dad0d04fSFariya Fatima {"version", 0644, FOPS(rsi_version_open),}, 270dad0d04fSFariya Fatima {"stats", 0644, FOPS(rsi_stats_open),}, 271dad0d04fSFariya Fatima {"debug_zone", 0666, FOPS_RW(rsi_debug_read, rsi_debug_zone_write),}, 272dad0d04fSFariya Fatima {"sdio_stats", 0644, FOPS(rsi_sdio_stats_open),}, 273dad0d04fSFariya Fatima }; 274dad0d04fSFariya Fatima 275dad0d04fSFariya Fatima /** 276dad0d04fSFariya Fatima * rsi_init_dbgfs() - This function initializes the dbgfs entry. 277dad0d04fSFariya Fatima * @adapter: Pointer to the adapter structure. 278dad0d04fSFariya Fatima * 279dad0d04fSFariya Fatima * Return: 0 on success, -1 on failure. 280dad0d04fSFariya Fatima */ 281dad0d04fSFariya Fatima int rsi_init_dbgfs(struct rsi_hw *adapter) 282dad0d04fSFariya Fatima { 283dad0d04fSFariya Fatima struct rsi_common *common = adapter->priv; 284dad0d04fSFariya Fatima struct rsi_debugfs *dev_dbgfs; 285dad0d04fSFariya Fatima char devdir[6]; 286dad0d04fSFariya Fatima int ii; 287dad0d04fSFariya Fatima const struct rsi_dbg_files *files; 288dad0d04fSFariya Fatima 289dad0d04fSFariya Fatima dev_dbgfs = kzalloc(sizeof(*dev_dbgfs), GFP_KERNEL); 290b25e77fdSFariya Fatima if (!dev_dbgfs) 291b25e77fdSFariya Fatima return -ENOMEM; 292b25e77fdSFariya Fatima 293dad0d04fSFariya Fatima adapter->dfsentry = dev_dbgfs; 294dad0d04fSFariya Fatima 295dad0d04fSFariya Fatima snprintf(devdir, sizeof(devdir), "%s", 296dad0d04fSFariya Fatima wiphy_name(adapter->hw->wiphy)); 297b25e77fdSFariya Fatima 298dad0d04fSFariya Fatima dev_dbgfs->subdir = debugfs_create_dir(devdir, NULL); 299dad0d04fSFariya Fatima 300dad0d04fSFariya Fatima for (ii = 0; ii < adapter->num_debugfs_entries; ii++) { 301dad0d04fSFariya Fatima files = &dev_debugfs_files[ii]; 302dad0d04fSFariya Fatima dev_dbgfs->rsi_files[ii] = 303dad0d04fSFariya Fatima debugfs_create_file(files->name, 304dad0d04fSFariya Fatima files->perms, 305dad0d04fSFariya Fatima dev_dbgfs->subdir, 306dad0d04fSFariya Fatima common, 307dad0d04fSFariya Fatima &files->fops); 308dad0d04fSFariya Fatima } 309dad0d04fSFariya Fatima return 0; 310dad0d04fSFariya Fatima } 311dad0d04fSFariya Fatima EXPORT_SYMBOL_GPL(rsi_init_dbgfs); 312dad0d04fSFariya Fatima 313dad0d04fSFariya Fatima /** 314dad0d04fSFariya Fatima * rsi_remove_dbgfs() - Removes the previously created dbgfs file entries 315dad0d04fSFariya Fatima * in the reverse order of creation. 316dad0d04fSFariya Fatima * @adapter: Pointer to the adapter structure. 317dad0d04fSFariya Fatima * 318dad0d04fSFariya Fatima * Return: None. 319dad0d04fSFariya Fatima */ 320dad0d04fSFariya Fatima void rsi_remove_dbgfs(struct rsi_hw *adapter) 321dad0d04fSFariya Fatima { 322dad0d04fSFariya Fatima struct rsi_debugfs *dev_dbgfs = adapter->dfsentry; 323dad0d04fSFariya Fatima 324dad0d04fSFariya Fatima if (!dev_dbgfs) 325dad0d04fSFariya Fatima return; 326dad0d04fSFariya Fatima 327dad0d04fSFariya Fatima debugfs_remove_recursive(dev_dbgfs->subdir); 328dad0d04fSFariya Fatima } 329dad0d04fSFariya Fatima EXPORT_SYMBOL_GPL(rsi_remove_dbgfs); 330