18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* /proc routines for Host AP driver */ 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci#include <linux/types.h> 58c2ecf20Sopenharmony_ci#include <linux/proc_fs.h> 68c2ecf20Sopenharmony_ci#include <linux/export.h> 78c2ecf20Sopenharmony_ci#include <net/lib80211.h> 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include "hostap_wlan.h" 108c2ecf20Sopenharmony_ci#include "hostap.h" 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#define PROC_LIMIT (PAGE_SIZE - 80) 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#if !defined(PRISM2_NO_PROCFS_DEBUG) && defined(CONFIG_PROC_FS) 158c2ecf20Sopenharmony_cistatic int prism2_debug_proc_show(struct seq_file *m, void *v) 168c2ecf20Sopenharmony_ci{ 178c2ecf20Sopenharmony_ci local_info_t *local = m->private; 188c2ecf20Sopenharmony_ci int i; 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci seq_printf(m, "next_txfid=%d next_alloc=%d\n", 218c2ecf20Sopenharmony_ci local->next_txfid, local->next_alloc); 228c2ecf20Sopenharmony_ci for (i = 0; i < PRISM2_TXFID_COUNT; i++) 238c2ecf20Sopenharmony_ci seq_printf(m, "FID: tx=%04X intransmit=%04X\n", 248c2ecf20Sopenharmony_ci local->txfid[i], local->intransmitfid[i]); 258c2ecf20Sopenharmony_ci seq_printf(m, "FW TX rate control: %d\n", local->fw_tx_rate_control); 268c2ecf20Sopenharmony_ci seq_printf(m, "beacon_int=%d\n", local->beacon_int); 278c2ecf20Sopenharmony_ci seq_printf(m, "dtim_period=%d\n", local->dtim_period); 288c2ecf20Sopenharmony_ci seq_printf(m, "wds_max_connections=%d\n", local->wds_max_connections); 298c2ecf20Sopenharmony_ci seq_printf(m, "dev_enabled=%d\n", local->dev_enabled); 308c2ecf20Sopenharmony_ci seq_printf(m, "sw_tick_stuck=%d\n", local->sw_tick_stuck); 318c2ecf20Sopenharmony_ci for (i = 0; i < WEP_KEYS; i++) { 328c2ecf20Sopenharmony_ci if (local->crypt_info.crypt[i] && 338c2ecf20Sopenharmony_ci local->crypt_info.crypt[i]->ops) { 348c2ecf20Sopenharmony_ci seq_printf(m, "crypt[%d]=%s\n", i, 358c2ecf20Sopenharmony_ci local->crypt_info.crypt[i]->ops->name); 368c2ecf20Sopenharmony_ci } 378c2ecf20Sopenharmony_ci } 388c2ecf20Sopenharmony_ci seq_printf(m, "pri_only=%d\n", local->pri_only); 398c2ecf20Sopenharmony_ci seq_printf(m, "pci=%d\n", local->func->hw_type == HOSTAP_HW_PCI); 408c2ecf20Sopenharmony_ci seq_printf(m, "sram_type=%d\n", local->sram_type); 418c2ecf20Sopenharmony_ci seq_printf(m, "no_pri=%d\n", local->no_pri); 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci return 0; 448c2ecf20Sopenharmony_ci} 458c2ecf20Sopenharmony_ci#endif 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci#ifdef CONFIG_PROC_FS 488c2ecf20Sopenharmony_cistatic int prism2_stats_proc_show(struct seq_file *m, void *v) 498c2ecf20Sopenharmony_ci{ 508c2ecf20Sopenharmony_ci local_info_t *local = m->private; 518c2ecf20Sopenharmony_ci struct comm_tallies_sums *sums = &local->comm_tallies; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci seq_printf(m, "TxUnicastFrames=%u\n", sums->tx_unicast_frames); 548c2ecf20Sopenharmony_ci seq_printf(m, "TxMulticastframes=%u\n", sums->tx_multicast_frames); 558c2ecf20Sopenharmony_ci seq_printf(m, "TxFragments=%u\n", sums->tx_fragments); 568c2ecf20Sopenharmony_ci seq_printf(m, "TxUnicastOctets=%u\n", sums->tx_unicast_octets); 578c2ecf20Sopenharmony_ci seq_printf(m, "TxMulticastOctets=%u\n", sums->tx_multicast_octets); 588c2ecf20Sopenharmony_ci seq_printf(m, "TxDeferredTransmissions=%u\n", 598c2ecf20Sopenharmony_ci sums->tx_deferred_transmissions); 608c2ecf20Sopenharmony_ci seq_printf(m, "TxSingleRetryFrames=%u\n", sums->tx_single_retry_frames); 618c2ecf20Sopenharmony_ci seq_printf(m, "TxMultipleRetryFrames=%u\n", 628c2ecf20Sopenharmony_ci sums->tx_multiple_retry_frames); 638c2ecf20Sopenharmony_ci seq_printf(m, "TxRetryLimitExceeded=%u\n", 648c2ecf20Sopenharmony_ci sums->tx_retry_limit_exceeded); 658c2ecf20Sopenharmony_ci seq_printf(m, "TxDiscards=%u\n", sums->tx_discards); 668c2ecf20Sopenharmony_ci seq_printf(m, "RxUnicastFrames=%u\n", sums->rx_unicast_frames); 678c2ecf20Sopenharmony_ci seq_printf(m, "RxMulticastFrames=%u\n", sums->rx_multicast_frames); 688c2ecf20Sopenharmony_ci seq_printf(m, "RxFragments=%u\n", sums->rx_fragments); 698c2ecf20Sopenharmony_ci seq_printf(m, "RxUnicastOctets=%u\n", sums->rx_unicast_octets); 708c2ecf20Sopenharmony_ci seq_printf(m, "RxMulticastOctets=%u\n", sums->rx_multicast_octets); 718c2ecf20Sopenharmony_ci seq_printf(m, "RxFCSErrors=%u\n", sums->rx_fcs_errors); 728c2ecf20Sopenharmony_ci seq_printf(m, "RxDiscardsNoBuffer=%u\n", sums->rx_discards_no_buffer); 738c2ecf20Sopenharmony_ci seq_printf(m, "TxDiscardsWrongSA=%u\n", sums->tx_discards_wrong_sa); 748c2ecf20Sopenharmony_ci seq_printf(m, "RxDiscardsWEPUndecryptable=%u\n", 758c2ecf20Sopenharmony_ci sums->rx_discards_wep_undecryptable); 768c2ecf20Sopenharmony_ci seq_printf(m, "RxMessageInMsgFragments=%u\n", 778c2ecf20Sopenharmony_ci sums->rx_message_in_msg_fragments); 788c2ecf20Sopenharmony_ci seq_printf(m, "RxMessageInBadMsgFragments=%u\n", 798c2ecf20Sopenharmony_ci sums->rx_message_in_bad_msg_fragments); 808c2ecf20Sopenharmony_ci /* FIX: this may grow too long for one page(?) */ 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci return 0; 838c2ecf20Sopenharmony_ci} 848c2ecf20Sopenharmony_ci#endif 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_cistatic int prism2_wds_proc_show(struct seq_file *m, void *v) 878c2ecf20Sopenharmony_ci{ 888c2ecf20Sopenharmony_ci struct list_head *ptr = v; 898c2ecf20Sopenharmony_ci struct hostap_interface *iface; 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci iface = list_entry(ptr, struct hostap_interface, list); 928c2ecf20Sopenharmony_ci if (iface->type == HOSTAP_INTERFACE_WDS) 938c2ecf20Sopenharmony_ci seq_printf(m, "%s\t%pM\n", 948c2ecf20Sopenharmony_ci iface->dev->name, iface->u.wds.remote_addr); 958c2ecf20Sopenharmony_ci return 0; 968c2ecf20Sopenharmony_ci} 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_cistatic void *prism2_wds_proc_start(struct seq_file *m, loff_t *_pos) 998c2ecf20Sopenharmony_ci{ 1008c2ecf20Sopenharmony_ci local_info_t *local = PDE_DATA(file_inode(m->file)); 1018c2ecf20Sopenharmony_ci read_lock_bh(&local->iface_lock); 1028c2ecf20Sopenharmony_ci return seq_list_start(&local->hostap_interfaces, *_pos); 1038c2ecf20Sopenharmony_ci} 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_cistatic void *prism2_wds_proc_next(struct seq_file *m, void *v, loff_t *_pos) 1068c2ecf20Sopenharmony_ci{ 1078c2ecf20Sopenharmony_ci local_info_t *local = PDE_DATA(file_inode(m->file)); 1088c2ecf20Sopenharmony_ci return seq_list_next(v, &local->hostap_interfaces, _pos); 1098c2ecf20Sopenharmony_ci} 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_cistatic void prism2_wds_proc_stop(struct seq_file *m, void *v) 1128c2ecf20Sopenharmony_ci{ 1138c2ecf20Sopenharmony_ci local_info_t *local = PDE_DATA(file_inode(m->file)); 1148c2ecf20Sopenharmony_ci read_unlock_bh(&local->iface_lock); 1158c2ecf20Sopenharmony_ci} 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_cistatic const struct seq_operations prism2_wds_proc_seqops = { 1188c2ecf20Sopenharmony_ci .start = prism2_wds_proc_start, 1198c2ecf20Sopenharmony_ci .next = prism2_wds_proc_next, 1208c2ecf20Sopenharmony_ci .stop = prism2_wds_proc_stop, 1218c2ecf20Sopenharmony_ci .show = prism2_wds_proc_show, 1228c2ecf20Sopenharmony_ci}; 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_cistatic int prism2_bss_list_proc_show(struct seq_file *m, void *v) 1258c2ecf20Sopenharmony_ci{ 1268c2ecf20Sopenharmony_ci local_info_t *local = PDE_DATA(file_inode(m->file)); 1278c2ecf20Sopenharmony_ci struct list_head *ptr = v; 1288c2ecf20Sopenharmony_ci struct hostap_bss_info *bss; 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci if (ptr == &local->bss_list) { 1318c2ecf20Sopenharmony_ci seq_printf(m, "#BSSID\tlast_update\tcount\tcapab_info\tSSID(txt)\t" 1328c2ecf20Sopenharmony_ci "SSID(hex)\tWPA IE\n"); 1338c2ecf20Sopenharmony_ci return 0; 1348c2ecf20Sopenharmony_ci } 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci bss = list_entry(ptr, struct hostap_bss_info, list); 1378c2ecf20Sopenharmony_ci seq_printf(m, "%pM\t%lu\t%u\t0x%x\t", 1388c2ecf20Sopenharmony_ci bss->bssid, bss->last_update, 1398c2ecf20Sopenharmony_ci bss->count, bss->capab_info); 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci seq_printf(m, "%*pE", (int)bss->ssid_len, bss->ssid); 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci seq_putc(m, '\t'); 1448c2ecf20Sopenharmony_ci seq_printf(m, "%*phN", (int)bss->ssid_len, bss->ssid); 1458c2ecf20Sopenharmony_ci seq_putc(m, '\t'); 1468c2ecf20Sopenharmony_ci seq_printf(m, "%*phN", (int)bss->wpa_ie_len, bss->wpa_ie); 1478c2ecf20Sopenharmony_ci seq_putc(m, '\n'); 1488c2ecf20Sopenharmony_ci return 0; 1498c2ecf20Sopenharmony_ci} 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_cistatic void *prism2_bss_list_proc_start(struct seq_file *m, loff_t *_pos) 1528c2ecf20Sopenharmony_ci __acquires(&local->lock) 1538c2ecf20Sopenharmony_ci{ 1548c2ecf20Sopenharmony_ci local_info_t *local = PDE_DATA(file_inode(m->file)); 1558c2ecf20Sopenharmony_ci spin_lock_bh(&local->lock); 1568c2ecf20Sopenharmony_ci return seq_list_start_head(&local->bss_list, *_pos); 1578c2ecf20Sopenharmony_ci} 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_cistatic void *prism2_bss_list_proc_next(struct seq_file *m, void *v, loff_t *_pos) 1608c2ecf20Sopenharmony_ci{ 1618c2ecf20Sopenharmony_ci local_info_t *local = PDE_DATA(file_inode(m->file)); 1628c2ecf20Sopenharmony_ci return seq_list_next(v, &local->bss_list, _pos); 1638c2ecf20Sopenharmony_ci} 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_cistatic void prism2_bss_list_proc_stop(struct seq_file *m, void *v) 1668c2ecf20Sopenharmony_ci __releases(&local->lock) 1678c2ecf20Sopenharmony_ci{ 1688c2ecf20Sopenharmony_ci local_info_t *local = PDE_DATA(file_inode(m->file)); 1698c2ecf20Sopenharmony_ci spin_unlock_bh(&local->lock); 1708c2ecf20Sopenharmony_ci} 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_cistatic const struct seq_operations prism2_bss_list_proc_seqops = { 1738c2ecf20Sopenharmony_ci .start = prism2_bss_list_proc_start, 1748c2ecf20Sopenharmony_ci .next = prism2_bss_list_proc_next, 1758c2ecf20Sopenharmony_ci .stop = prism2_bss_list_proc_stop, 1768c2ecf20Sopenharmony_ci .show = prism2_bss_list_proc_show, 1778c2ecf20Sopenharmony_ci}; 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci#ifdef CONFIG_PROC_FS 1808c2ecf20Sopenharmony_cistatic int prism2_crypt_proc_show(struct seq_file *m, void *v) 1818c2ecf20Sopenharmony_ci{ 1828c2ecf20Sopenharmony_ci local_info_t *local = m->private; 1838c2ecf20Sopenharmony_ci int i; 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci seq_printf(m, "tx_keyidx=%d\n", local->crypt_info.tx_keyidx); 1868c2ecf20Sopenharmony_ci for (i = 0; i < WEP_KEYS; i++) { 1878c2ecf20Sopenharmony_ci if (local->crypt_info.crypt[i] && 1888c2ecf20Sopenharmony_ci local->crypt_info.crypt[i]->ops && 1898c2ecf20Sopenharmony_ci local->crypt_info.crypt[i]->ops->print_stats) { 1908c2ecf20Sopenharmony_ci local->crypt_info.crypt[i]->ops->print_stats( 1918c2ecf20Sopenharmony_ci m, local->crypt_info.crypt[i]->priv); 1928c2ecf20Sopenharmony_ci } 1938c2ecf20Sopenharmony_ci } 1948c2ecf20Sopenharmony_ci return 0; 1958c2ecf20Sopenharmony_ci} 1968c2ecf20Sopenharmony_ci#endif 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_cistatic ssize_t prism2_pda_proc_read(struct file *file, char __user *buf, 1998c2ecf20Sopenharmony_ci size_t count, loff_t *_pos) 2008c2ecf20Sopenharmony_ci{ 2018c2ecf20Sopenharmony_ci local_info_t *local = PDE_DATA(file_inode(file)); 2028c2ecf20Sopenharmony_ci size_t off; 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci if (local->pda == NULL || *_pos >= PRISM2_PDA_SIZE) 2058c2ecf20Sopenharmony_ci return 0; 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci off = *_pos; 2088c2ecf20Sopenharmony_ci if (count > PRISM2_PDA_SIZE - off) 2098c2ecf20Sopenharmony_ci count = PRISM2_PDA_SIZE - off; 2108c2ecf20Sopenharmony_ci if (copy_to_user(buf, local->pda + off, count) != 0) 2118c2ecf20Sopenharmony_ci return -EFAULT; 2128c2ecf20Sopenharmony_ci *_pos += count; 2138c2ecf20Sopenharmony_ci return count; 2148c2ecf20Sopenharmony_ci} 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_cistatic const struct proc_ops prism2_pda_proc_ops = { 2178c2ecf20Sopenharmony_ci .proc_read = prism2_pda_proc_read, 2188c2ecf20Sopenharmony_ci .proc_lseek = generic_file_llseek, 2198c2ecf20Sopenharmony_ci}; 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_cistatic ssize_t prism2_aux_dump_proc_no_read(struct file *file, char __user *buf, 2238c2ecf20Sopenharmony_ci size_t bufsize, loff_t *_pos) 2248c2ecf20Sopenharmony_ci{ 2258c2ecf20Sopenharmony_ci return 0; 2268c2ecf20Sopenharmony_ci} 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_cistatic const struct proc_ops prism2_aux_dump_proc_ops = { 2298c2ecf20Sopenharmony_ci .proc_read = prism2_aux_dump_proc_no_read, 2308c2ecf20Sopenharmony_ci}; 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci#ifdef PRISM2_IO_DEBUG 2348c2ecf20Sopenharmony_cistatic int prism2_io_debug_proc_read(char *page, char **start, off_t off, 2358c2ecf20Sopenharmony_ci int count, int *eof, void *data) 2368c2ecf20Sopenharmony_ci{ 2378c2ecf20Sopenharmony_ci local_info_t *local = (local_info_t *) data; 2388c2ecf20Sopenharmony_ci int head = local->io_debug_head; 2398c2ecf20Sopenharmony_ci int start_bytes, left, copy; 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci if (off + count > PRISM2_IO_DEBUG_SIZE * 4) { 2428c2ecf20Sopenharmony_ci *eof = 1; 2438c2ecf20Sopenharmony_ci if (off >= PRISM2_IO_DEBUG_SIZE * 4) 2448c2ecf20Sopenharmony_ci return 0; 2458c2ecf20Sopenharmony_ci count = PRISM2_IO_DEBUG_SIZE * 4 - off; 2468c2ecf20Sopenharmony_ci } 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci start_bytes = (PRISM2_IO_DEBUG_SIZE - head) * 4; 2498c2ecf20Sopenharmony_ci left = count; 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_ci if (off < start_bytes) { 2528c2ecf20Sopenharmony_ci copy = start_bytes - off; 2538c2ecf20Sopenharmony_ci if (copy > count) 2548c2ecf20Sopenharmony_ci copy = count; 2558c2ecf20Sopenharmony_ci memcpy(page, ((u8 *) &local->io_debug[head]) + off, copy); 2568c2ecf20Sopenharmony_ci left -= copy; 2578c2ecf20Sopenharmony_ci if (left > 0) 2588c2ecf20Sopenharmony_ci memcpy(&page[copy], local->io_debug, left); 2598c2ecf20Sopenharmony_ci } else { 2608c2ecf20Sopenharmony_ci memcpy(page, ((u8 *) local->io_debug) + (off - start_bytes), 2618c2ecf20Sopenharmony_ci left); 2628c2ecf20Sopenharmony_ci } 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ci *start = page; 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_ci return count; 2678c2ecf20Sopenharmony_ci} 2688c2ecf20Sopenharmony_ci#endif /* PRISM2_IO_DEBUG */ 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci#ifndef PRISM2_NO_STATION_MODES 2728c2ecf20Sopenharmony_cistatic int prism2_scan_results_proc_show(struct seq_file *m, void *v) 2738c2ecf20Sopenharmony_ci{ 2748c2ecf20Sopenharmony_ci local_info_t *local = PDE_DATA(file_inode(m->file)); 2758c2ecf20Sopenharmony_ci unsigned long entry; 2768c2ecf20Sopenharmony_ci int i, len; 2778c2ecf20Sopenharmony_ci struct hfa384x_hostscan_result *scanres; 2788c2ecf20Sopenharmony_ci u8 *p; 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci if (v == SEQ_START_TOKEN) { 2818c2ecf20Sopenharmony_ci seq_printf(m, 2828c2ecf20Sopenharmony_ci "CHID ANL SL BcnInt Capab Rate BSSID ATIM SupRates SSID\n"); 2838c2ecf20Sopenharmony_ci return 0; 2848c2ecf20Sopenharmony_ci } 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ci entry = (unsigned long)v - 2; 2878c2ecf20Sopenharmony_ci scanres = &local->last_scan_results[entry]; 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_ci seq_printf(m, "%d %d %d %d 0x%02x %d %pM %d ", 2908c2ecf20Sopenharmony_ci le16_to_cpu(scanres->chid), 2918c2ecf20Sopenharmony_ci (s16) le16_to_cpu(scanres->anl), 2928c2ecf20Sopenharmony_ci (s16) le16_to_cpu(scanres->sl), 2938c2ecf20Sopenharmony_ci le16_to_cpu(scanres->beacon_interval), 2948c2ecf20Sopenharmony_ci le16_to_cpu(scanres->capability), 2958c2ecf20Sopenharmony_ci le16_to_cpu(scanres->rate), 2968c2ecf20Sopenharmony_ci scanres->bssid, 2978c2ecf20Sopenharmony_ci le16_to_cpu(scanres->atim)); 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_ci p = scanres->sup_rates; 3008c2ecf20Sopenharmony_ci for (i = 0; i < sizeof(scanres->sup_rates); i++) { 3018c2ecf20Sopenharmony_ci if (p[i] == 0) 3028c2ecf20Sopenharmony_ci break; 3038c2ecf20Sopenharmony_ci seq_printf(m, "<%02x>", p[i]); 3048c2ecf20Sopenharmony_ci } 3058c2ecf20Sopenharmony_ci seq_putc(m, ' '); 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_ci p = scanres->ssid; 3088c2ecf20Sopenharmony_ci len = le16_to_cpu(scanres->ssid_len); 3098c2ecf20Sopenharmony_ci if (len > 32) 3108c2ecf20Sopenharmony_ci len = 32; 3118c2ecf20Sopenharmony_ci for (i = 0; i < len; i++) { 3128c2ecf20Sopenharmony_ci unsigned char c = p[i]; 3138c2ecf20Sopenharmony_ci if (c >= 32 && c < 127) 3148c2ecf20Sopenharmony_ci seq_putc(m, c); 3158c2ecf20Sopenharmony_ci else 3168c2ecf20Sopenharmony_ci seq_printf(m, "<%02x>", c); 3178c2ecf20Sopenharmony_ci } 3188c2ecf20Sopenharmony_ci seq_putc(m, '\n'); 3198c2ecf20Sopenharmony_ci return 0; 3208c2ecf20Sopenharmony_ci} 3218c2ecf20Sopenharmony_ci 3228c2ecf20Sopenharmony_cistatic void *prism2_scan_results_proc_start(struct seq_file *m, loff_t *_pos) 3238c2ecf20Sopenharmony_ci{ 3248c2ecf20Sopenharmony_ci local_info_t *local = PDE_DATA(file_inode(m->file)); 3258c2ecf20Sopenharmony_ci spin_lock_bh(&local->lock); 3268c2ecf20Sopenharmony_ci 3278c2ecf20Sopenharmony_ci /* We have a header (pos 0) + N results to show (pos 1...N) */ 3288c2ecf20Sopenharmony_ci if (*_pos > local->last_scan_results_count) 3298c2ecf20Sopenharmony_ci return NULL; 3308c2ecf20Sopenharmony_ci return (void *)(unsigned long)(*_pos + 1); /* 0 would be EOF */ 3318c2ecf20Sopenharmony_ci} 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_cistatic void *prism2_scan_results_proc_next(struct seq_file *m, void *v, loff_t *_pos) 3348c2ecf20Sopenharmony_ci{ 3358c2ecf20Sopenharmony_ci local_info_t *local = PDE_DATA(file_inode(m->file)); 3368c2ecf20Sopenharmony_ci 3378c2ecf20Sopenharmony_ci ++*_pos; 3388c2ecf20Sopenharmony_ci if (*_pos > local->last_scan_results_count) 3398c2ecf20Sopenharmony_ci return NULL; 3408c2ecf20Sopenharmony_ci return (void *)(unsigned long)(*_pos + 1); /* 0 would be EOF */ 3418c2ecf20Sopenharmony_ci} 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_cistatic void prism2_scan_results_proc_stop(struct seq_file *m, void *v) 3448c2ecf20Sopenharmony_ci{ 3458c2ecf20Sopenharmony_ci local_info_t *local = PDE_DATA(file_inode(m->file)); 3468c2ecf20Sopenharmony_ci spin_unlock_bh(&local->lock); 3478c2ecf20Sopenharmony_ci} 3488c2ecf20Sopenharmony_ci 3498c2ecf20Sopenharmony_cistatic const struct seq_operations prism2_scan_results_proc_seqops = { 3508c2ecf20Sopenharmony_ci .start = prism2_scan_results_proc_start, 3518c2ecf20Sopenharmony_ci .next = prism2_scan_results_proc_next, 3528c2ecf20Sopenharmony_ci .stop = prism2_scan_results_proc_stop, 3538c2ecf20Sopenharmony_ci .show = prism2_scan_results_proc_show, 3548c2ecf20Sopenharmony_ci}; 3558c2ecf20Sopenharmony_ci#endif /* PRISM2_NO_STATION_MODES */ 3568c2ecf20Sopenharmony_ci 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_civoid hostap_init_proc(local_info_t *local) 3598c2ecf20Sopenharmony_ci{ 3608c2ecf20Sopenharmony_ci local->proc = NULL; 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_ci if (hostap_proc == NULL) { 3638c2ecf20Sopenharmony_ci printk(KERN_WARNING "%s: hostap proc directory not created\n", 3648c2ecf20Sopenharmony_ci local->dev->name); 3658c2ecf20Sopenharmony_ci return; 3668c2ecf20Sopenharmony_ci } 3678c2ecf20Sopenharmony_ci 3688c2ecf20Sopenharmony_ci local->proc = proc_mkdir(local->ddev->name, hostap_proc); 3698c2ecf20Sopenharmony_ci if (local->proc == NULL) { 3708c2ecf20Sopenharmony_ci printk(KERN_INFO "/proc/net/hostap/%s creation failed\n", 3718c2ecf20Sopenharmony_ci local->ddev->name); 3728c2ecf20Sopenharmony_ci return; 3738c2ecf20Sopenharmony_ci } 3748c2ecf20Sopenharmony_ci 3758c2ecf20Sopenharmony_ci#ifndef PRISM2_NO_PROCFS_DEBUG 3768c2ecf20Sopenharmony_ci proc_create_single_data("debug", 0, local->proc, 3778c2ecf20Sopenharmony_ci prism2_debug_proc_show, local); 3788c2ecf20Sopenharmony_ci#endif /* PRISM2_NO_PROCFS_DEBUG */ 3798c2ecf20Sopenharmony_ci proc_create_single_data("stats", 0, local->proc, prism2_stats_proc_show, 3808c2ecf20Sopenharmony_ci local); 3818c2ecf20Sopenharmony_ci proc_create_seq_data("wds", 0, local->proc, 3828c2ecf20Sopenharmony_ci &prism2_wds_proc_seqops, local); 3838c2ecf20Sopenharmony_ci proc_create_data("pda", 0, local->proc, 3848c2ecf20Sopenharmony_ci &prism2_pda_proc_ops, local); 3858c2ecf20Sopenharmony_ci proc_create_data("aux_dump", 0, local->proc, 3868c2ecf20Sopenharmony_ci local->func->read_aux_proc_ops ?: &prism2_aux_dump_proc_ops, 3878c2ecf20Sopenharmony_ci local); 3888c2ecf20Sopenharmony_ci proc_create_seq_data("bss_list", 0, local->proc, 3898c2ecf20Sopenharmony_ci &prism2_bss_list_proc_seqops, local); 3908c2ecf20Sopenharmony_ci proc_create_single_data("crypt", 0, local->proc, prism2_crypt_proc_show, 3918c2ecf20Sopenharmony_ci local); 3928c2ecf20Sopenharmony_ci#ifdef PRISM2_IO_DEBUG 3938c2ecf20Sopenharmony_ci proc_create_single_data("io_debug", 0, local->proc, 3948c2ecf20Sopenharmony_ci prism2_debug_proc_show, local); 3958c2ecf20Sopenharmony_ci#endif /* PRISM2_IO_DEBUG */ 3968c2ecf20Sopenharmony_ci#ifndef PRISM2_NO_STATION_MODES 3978c2ecf20Sopenharmony_ci proc_create_seq_data("scan_results", 0, local->proc, 3988c2ecf20Sopenharmony_ci &prism2_scan_results_proc_seqops, local); 3998c2ecf20Sopenharmony_ci#endif /* PRISM2_NO_STATION_MODES */ 4008c2ecf20Sopenharmony_ci} 4018c2ecf20Sopenharmony_ci 4028c2ecf20Sopenharmony_ci 4038c2ecf20Sopenharmony_civoid hostap_remove_proc(local_info_t *local) 4048c2ecf20Sopenharmony_ci{ 4058c2ecf20Sopenharmony_ci proc_remove(local->proc); 4068c2ecf20Sopenharmony_ci} 4078c2ecf20Sopenharmony_ci 4088c2ecf20Sopenharmony_ci 4098c2ecf20Sopenharmony_ciEXPORT_SYMBOL(hostap_init_proc); 4108c2ecf20Sopenharmony_ciEXPORT_SYMBOL(hostap_remove_proc); 411