162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* /proc routines for Host AP driver */ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include <linux/types.h> 562306a36Sopenharmony_ci#include <linux/proc_fs.h> 662306a36Sopenharmony_ci#include <linux/export.h> 762306a36Sopenharmony_ci#include <net/lib80211.h> 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include "hostap_wlan.h" 1062306a36Sopenharmony_ci#include "hostap.h" 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#define PROC_LIMIT (PAGE_SIZE - 80) 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#if !defined(PRISM2_NO_PROCFS_DEBUG) && defined(CONFIG_PROC_FS) 1562306a36Sopenharmony_cistatic int prism2_debug_proc_show(struct seq_file *m, void *v) 1662306a36Sopenharmony_ci{ 1762306a36Sopenharmony_ci local_info_t *local = m->private; 1862306a36Sopenharmony_ci int i; 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci seq_printf(m, "next_txfid=%d next_alloc=%d\n", 2162306a36Sopenharmony_ci local->next_txfid, local->next_alloc); 2262306a36Sopenharmony_ci for (i = 0; i < PRISM2_TXFID_COUNT; i++) 2362306a36Sopenharmony_ci seq_printf(m, "FID: tx=%04X intransmit=%04X\n", 2462306a36Sopenharmony_ci local->txfid[i], local->intransmitfid[i]); 2562306a36Sopenharmony_ci seq_printf(m, "FW TX rate control: %d\n", local->fw_tx_rate_control); 2662306a36Sopenharmony_ci seq_printf(m, "beacon_int=%d\n", local->beacon_int); 2762306a36Sopenharmony_ci seq_printf(m, "dtim_period=%d\n", local->dtim_period); 2862306a36Sopenharmony_ci seq_printf(m, "wds_max_connections=%d\n", local->wds_max_connections); 2962306a36Sopenharmony_ci seq_printf(m, "dev_enabled=%d\n", local->dev_enabled); 3062306a36Sopenharmony_ci seq_printf(m, "sw_tick_stuck=%d\n", local->sw_tick_stuck); 3162306a36Sopenharmony_ci for (i = 0; i < WEP_KEYS; i++) { 3262306a36Sopenharmony_ci if (local->crypt_info.crypt[i] && 3362306a36Sopenharmony_ci local->crypt_info.crypt[i]->ops) { 3462306a36Sopenharmony_ci seq_printf(m, "crypt[%d]=%s\n", i, 3562306a36Sopenharmony_ci local->crypt_info.crypt[i]->ops->name); 3662306a36Sopenharmony_ci } 3762306a36Sopenharmony_ci } 3862306a36Sopenharmony_ci seq_printf(m, "pri_only=%d\n", local->pri_only); 3962306a36Sopenharmony_ci seq_printf(m, "pci=%d\n", local->func->hw_type == HOSTAP_HW_PCI); 4062306a36Sopenharmony_ci seq_printf(m, "sram_type=%d\n", local->sram_type); 4162306a36Sopenharmony_ci seq_printf(m, "no_pri=%d\n", local->no_pri); 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci return 0; 4462306a36Sopenharmony_ci} 4562306a36Sopenharmony_ci#endif 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci#ifdef CONFIG_PROC_FS 4862306a36Sopenharmony_cistatic int prism2_stats_proc_show(struct seq_file *m, void *v) 4962306a36Sopenharmony_ci{ 5062306a36Sopenharmony_ci local_info_t *local = m->private; 5162306a36Sopenharmony_ci struct comm_tallies_sums *sums = &local->comm_tallies; 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci seq_printf(m, "TxUnicastFrames=%u\n", sums->tx_unicast_frames); 5462306a36Sopenharmony_ci seq_printf(m, "TxMulticastframes=%u\n", sums->tx_multicast_frames); 5562306a36Sopenharmony_ci seq_printf(m, "TxFragments=%u\n", sums->tx_fragments); 5662306a36Sopenharmony_ci seq_printf(m, "TxUnicastOctets=%u\n", sums->tx_unicast_octets); 5762306a36Sopenharmony_ci seq_printf(m, "TxMulticastOctets=%u\n", sums->tx_multicast_octets); 5862306a36Sopenharmony_ci seq_printf(m, "TxDeferredTransmissions=%u\n", 5962306a36Sopenharmony_ci sums->tx_deferred_transmissions); 6062306a36Sopenharmony_ci seq_printf(m, "TxSingleRetryFrames=%u\n", sums->tx_single_retry_frames); 6162306a36Sopenharmony_ci seq_printf(m, "TxMultipleRetryFrames=%u\n", 6262306a36Sopenharmony_ci sums->tx_multiple_retry_frames); 6362306a36Sopenharmony_ci seq_printf(m, "TxRetryLimitExceeded=%u\n", 6462306a36Sopenharmony_ci sums->tx_retry_limit_exceeded); 6562306a36Sopenharmony_ci seq_printf(m, "TxDiscards=%u\n", sums->tx_discards); 6662306a36Sopenharmony_ci seq_printf(m, "RxUnicastFrames=%u\n", sums->rx_unicast_frames); 6762306a36Sopenharmony_ci seq_printf(m, "RxMulticastFrames=%u\n", sums->rx_multicast_frames); 6862306a36Sopenharmony_ci seq_printf(m, "RxFragments=%u\n", sums->rx_fragments); 6962306a36Sopenharmony_ci seq_printf(m, "RxUnicastOctets=%u\n", sums->rx_unicast_octets); 7062306a36Sopenharmony_ci seq_printf(m, "RxMulticastOctets=%u\n", sums->rx_multicast_octets); 7162306a36Sopenharmony_ci seq_printf(m, "RxFCSErrors=%u\n", sums->rx_fcs_errors); 7262306a36Sopenharmony_ci seq_printf(m, "RxDiscardsNoBuffer=%u\n", sums->rx_discards_no_buffer); 7362306a36Sopenharmony_ci seq_printf(m, "TxDiscardsWrongSA=%u\n", sums->tx_discards_wrong_sa); 7462306a36Sopenharmony_ci seq_printf(m, "RxDiscardsWEPUndecryptable=%u\n", 7562306a36Sopenharmony_ci sums->rx_discards_wep_undecryptable); 7662306a36Sopenharmony_ci seq_printf(m, "RxMessageInMsgFragments=%u\n", 7762306a36Sopenharmony_ci sums->rx_message_in_msg_fragments); 7862306a36Sopenharmony_ci seq_printf(m, "RxMessageInBadMsgFragments=%u\n", 7962306a36Sopenharmony_ci sums->rx_message_in_bad_msg_fragments); 8062306a36Sopenharmony_ci /* FIX: this may grow too long for one page(?) */ 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci return 0; 8362306a36Sopenharmony_ci} 8462306a36Sopenharmony_ci#endif 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_cistatic int prism2_wds_proc_show(struct seq_file *m, void *v) 8762306a36Sopenharmony_ci{ 8862306a36Sopenharmony_ci struct list_head *ptr = v; 8962306a36Sopenharmony_ci struct hostap_interface *iface; 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci iface = list_entry(ptr, struct hostap_interface, list); 9262306a36Sopenharmony_ci if (iface->type == HOSTAP_INTERFACE_WDS) 9362306a36Sopenharmony_ci seq_printf(m, "%s\t%pM\n", 9462306a36Sopenharmony_ci iface->dev->name, iface->u.wds.remote_addr); 9562306a36Sopenharmony_ci return 0; 9662306a36Sopenharmony_ci} 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_cistatic void *prism2_wds_proc_start(struct seq_file *m, loff_t *_pos) 9962306a36Sopenharmony_ci{ 10062306a36Sopenharmony_ci local_info_t *local = pde_data(file_inode(m->file)); 10162306a36Sopenharmony_ci read_lock_bh(&local->iface_lock); 10262306a36Sopenharmony_ci return seq_list_start(&local->hostap_interfaces, *_pos); 10362306a36Sopenharmony_ci} 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_cistatic void *prism2_wds_proc_next(struct seq_file *m, void *v, loff_t *_pos) 10662306a36Sopenharmony_ci{ 10762306a36Sopenharmony_ci local_info_t *local = pde_data(file_inode(m->file)); 10862306a36Sopenharmony_ci return seq_list_next(v, &local->hostap_interfaces, _pos); 10962306a36Sopenharmony_ci} 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_cistatic void prism2_wds_proc_stop(struct seq_file *m, void *v) 11262306a36Sopenharmony_ci{ 11362306a36Sopenharmony_ci local_info_t *local = pde_data(file_inode(m->file)); 11462306a36Sopenharmony_ci read_unlock_bh(&local->iface_lock); 11562306a36Sopenharmony_ci} 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_cistatic const struct seq_operations prism2_wds_proc_seqops = { 11862306a36Sopenharmony_ci .start = prism2_wds_proc_start, 11962306a36Sopenharmony_ci .next = prism2_wds_proc_next, 12062306a36Sopenharmony_ci .stop = prism2_wds_proc_stop, 12162306a36Sopenharmony_ci .show = prism2_wds_proc_show, 12262306a36Sopenharmony_ci}; 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_cistatic int prism2_bss_list_proc_show(struct seq_file *m, void *v) 12562306a36Sopenharmony_ci{ 12662306a36Sopenharmony_ci local_info_t *local = pde_data(file_inode(m->file)); 12762306a36Sopenharmony_ci struct list_head *ptr = v; 12862306a36Sopenharmony_ci struct hostap_bss_info *bss; 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci if (ptr == &local->bss_list) { 13162306a36Sopenharmony_ci seq_printf(m, "#BSSID\tlast_update\tcount\tcapab_info\tSSID(txt)\t" 13262306a36Sopenharmony_ci "SSID(hex)\tWPA IE\n"); 13362306a36Sopenharmony_ci return 0; 13462306a36Sopenharmony_ci } 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci bss = list_entry(ptr, struct hostap_bss_info, list); 13762306a36Sopenharmony_ci seq_printf(m, "%pM\t%lu\t%u\t0x%x\t", 13862306a36Sopenharmony_ci bss->bssid, bss->last_update, 13962306a36Sopenharmony_ci bss->count, bss->capab_info); 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci seq_printf(m, "%*pE", (int)bss->ssid_len, bss->ssid); 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci seq_putc(m, '\t'); 14462306a36Sopenharmony_ci seq_printf(m, "%*phN", (int)bss->ssid_len, bss->ssid); 14562306a36Sopenharmony_ci seq_putc(m, '\t'); 14662306a36Sopenharmony_ci seq_printf(m, "%*phN", (int)bss->wpa_ie_len, bss->wpa_ie); 14762306a36Sopenharmony_ci seq_putc(m, '\n'); 14862306a36Sopenharmony_ci return 0; 14962306a36Sopenharmony_ci} 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_cistatic void *prism2_bss_list_proc_start(struct seq_file *m, loff_t *_pos) 15262306a36Sopenharmony_ci __acquires(&local->lock) 15362306a36Sopenharmony_ci{ 15462306a36Sopenharmony_ci local_info_t *local = pde_data(file_inode(m->file)); 15562306a36Sopenharmony_ci spin_lock_bh(&local->lock); 15662306a36Sopenharmony_ci return seq_list_start_head(&local->bss_list, *_pos); 15762306a36Sopenharmony_ci} 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_cistatic void *prism2_bss_list_proc_next(struct seq_file *m, void *v, loff_t *_pos) 16062306a36Sopenharmony_ci{ 16162306a36Sopenharmony_ci local_info_t *local = pde_data(file_inode(m->file)); 16262306a36Sopenharmony_ci return seq_list_next(v, &local->bss_list, _pos); 16362306a36Sopenharmony_ci} 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_cistatic void prism2_bss_list_proc_stop(struct seq_file *m, void *v) 16662306a36Sopenharmony_ci __releases(&local->lock) 16762306a36Sopenharmony_ci{ 16862306a36Sopenharmony_ci local_info_t *local = pde_data(file_inode(m->file)); 16962306a36Sopenharmony_ci spin_unlock_bh(&local->lock); 17062306a36Sopenharmony_ci} 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_cistatic const struct seq_operations prism2_bss_list_proc_seqops = { 17362306a36Sopenharmony_ci .start = prism2_bss_list_proc_start, 17462306a36Sopenharmony_ci .next = prism2_bss_list_proc_next, 17562306a36Sopenharmony_ci .stop = prism2_bss_list_proc_stop, 17662306a36Sopenharmony_ci .show = prism2_bss_list_proc_show, 17762306a36Sopenharmony_ci}; 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci#ifdef CONFIG_PROC_FS 18062306a36Sopenharmony_cistatic int prism2_crypt_proc_show(struct seq_file *m, void *v) 18162306a36Sopenharmony_ci{ 18262306a36Sopenharmony_ci local_info_t *local = m->private; 18362306a36Sopenharmony_ci int i; 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci seq_printf(m, "tx_keyidx=%d\n", local->crypt_info.tx_keyidx); 18662306a36Sopenharmony_ci for (i = 0; i < WEP_KEYS; i++) { 18762306a36Sopenharmony_ci if (local->crypt_info.crypt[i] && 18862306a36Sopenharmony_ci local->crypt_info.crypt[i]->ops && 18962306a36Sopenharmony_ci local->crypt_info.crypt[i]->ops->print_stats) { 19062306a36Sopenharmony_ci local->crypt_info.crypt[i]->ops->print_stats( 19162306a36Sopenharmony_ci m, local->crypt_info.crypt[i]->priv); 19262306a36Sopenharmony_ci } 19362306a36Sopenharmony_ci } 19462306a36Sopenharmony_ci return 0; 19562306a36Sopenharmony_ci} 19662306a36Sopenharmony_ci#endif 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_cistatic ssize_t prism2_pda_proc_read(struct file *file, char __user *buf, 19962306a36Sopenharmony_ci size_t count, loff_t *_pos) 20062306a36Sopenharmony_ci{ 20162306a36Sopenharmony_ci local_info_t *local = pde_data(file_inode(file)); 20262306a36Sopenharmony_ci size_t off; 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci if (local->pda == NULL || *_pos >= PRISM2_PDA_SIZE) 20562306a36Sopenharmony_ci return 0; 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_ci off = *_pos; 20862306a36Sopenharmony_ci if (count > PRISM2_PDA_SIZE - off) 20962306a36Sopenharmony_ci count = PRISM2_PDA_SIZE - off; 21062306a36Sopenharmony_ci if (copy_to_user(buf, local->pda + off, count) != 0) 21162306a36Sopenharmony_ci return -EFAULT; 21262306a36Sopenharmony_ci *_pos += count; 21362306a36Sopenharmony_ci return count; 21462306a36Sopenharmony_ci} 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_cistatic const struct proc_ops prism2_pda_proc_ops = { 21762306a36Sopenharmony_ci .proc_read = prism2_pda_proc_read, 21862306a36Sopenharmony_ci .proc_lseek = generic_file_llseek, 21962306a36Sopenharmony_ci}; 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_cistatic ssize_t prism2_aux_dump_proc_no_read(struct file *file, char __user *buf, 22362306a36Sopenharmony_ci size_t bufsize, loff_t *_pos) 22462306a36Sopenharmony_ci{ 22562306a36Sopenharmony_ci return 0; 22662306a36Sopenharmony_ci} 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_cistatic const struct proc_ops prism2_aux_dump_proc_ops = { 22962306a36Sopenharmony_ci .proc_read = prism2_aux_dump_proc_no_read, 23062306a36Sopenharmony_ci .proc_lseek = default_llseek, 23162306a36Sopenharmony_ci}; 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci#ifdef PRISM2_IO_DEBUG 23562306a36Sopenharmony_cistatic int prism2_io_debug_proc_read(char *page, char **start, off_t off, 23662306a36Sopenharmony_ci int count, int *eof, void *data) 23762306a36Sopenharmony_ci{ 23862306a36Sopenharmony_ci local_info_t *local = (local_info_t *) data; 23962306a36Sopenharmony_ci int head = local->io_debug_head; 24062306a36Sopenharmony_ci int start_bytes, left, copy; 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci if (off + count > PRISM2_IO_DEBUG_SIZE * 4) { 24362306a36Sopenharmony_ci *eof = 1; 24462306a36Sopenharmony_ci if (off >= PRISM2_IO_DEBUG_SIZE * 4) 24562306a36Sopenharmony_ci return 0; 24662306a36Sopenharmony_ci count = PRISM2_IO_DEBUG_SIZE * 4 - off; 24762306a36Sopenharmony_ci } 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci start_bytes = (PRISM2_IO_DEBUG_SIZE - head) * 4; 25062306a36Sopenharmony_ci left = count; 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci if (off < start_bytes) { 25362306a36Sopenharmony_ci copy = start_bytes - off; 25462306a36Sopenharmony_ci if (copy > count) 25562306a36Sopenharmony_ci copy = count; 25662306a36Sopenharmony_ci memcpy(page, ((u8 *) &local->io_debug[head]) + off, copy); 25762306a36Sopenharmony_ci left -= copy; 25862306a36Sopenharmony_ci if (left > 0) 25962306a36Sopenharmony_ci memcpy(&page[copy], local->io_debug, left); 26062306a36Sopenharmony_ci } else { 26162306a36Sopenharmony_ci memcpy(page, ((u8 *) local->io_debug) + (off - start_bytes), 26262306a36Sopenharmony_ci left); 26362306a36Sopenharmony_ci } 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci *start = page; 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci return count; 26862306a36Sopenharmony_ci} 26962306a36Sopenharmony_ci#endif /* PRISM2_IO_DEBUG */ 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci#ifndef PRISM2_NO_STATION_MODES 27362306a36Sopenharmony_cistatic int prism2_scan_results_proc_show(struct seq_file *m, void *v) 27462306a36Sopenharmony_ci{ 27562306a36Sopenharmony_ci local_info_t *local = pde_data(file_inode(m->file)); 27662306a36Sopenharmony_ci unsigned long entry; 27762306a36Sopenharmony_ci int i, len; 27862306a36Sopenharmony_ci struct hfa384x_hostscan_result *scanres; 27962306a36Sopenharmony_ci u8 *p; 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_ci if (v == SEQ_START_TOKEN) { 28262306a36Sopenharmony_ci seq_printf(m, 28362306a36Sopenharmony_ci "CHID ANL SL BcnInt Capab Rate BSSID ATIM SupRates SSID\n"); 28462306a36Sopenharmony_ci return 0; 28562306a36Sopenharmony_ci } 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci entry = (unsigned long)v - 2; 28862306a36Sopenharmony_ci scanres = &local->last_scan_results[entry]; 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_ci seq_printf(m, "%d %d %d %d 0x%02x %d %pM %d ", 29162306a36Sopenharmony_ci le16_to_cpu(scanres->chid), 29262306a36Sopenharmony_ci (s16) le16_to_cpu(scanres->anl), 29362306a36Sopenharmony_ci (s16) le16_to_cpu(scanres->sl), 29462306a36Sopenharmony_ci le16_to_cpu(scanres->beacon_interval), 29562306a36Sopenharmony_ci le16_to_cpu(scanres->capability), 29662306a36Sopenharmony_ci le16_to_cpu(scanres->rate), 29762306a36Sopenharmony_ci scanres->bssid, 29862306a36Sopenharmony_ci le16_to_cpu(scanres->atim)); 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci p = scanres->sup_rates; 30162306a36Sopenharmony_ci for (i = 0; i < sizeof(scanres->sup_rates); i++) { 30262306a36Sopenharmony_ci if (p[i] == 0) 30362306a36Sopenharmony_ci break; 30462306a36Sopenharmony_ci seq_printf(m, "<%02x>", p[i]); 30562306a36Sopenharmony_ci } 30662306a36Sopenharmony_ci seq_putc(m, ' '); 30762306a36Sopenharmony_ci 30862306a36Sopenharmony_ci p = scanres->ssid; 30962306a36Sopenharmony_ci len = le16_to_cpu(scanres->ssid_len); 31062306a36Sopenharmony_ci if (len > 32) 31162306a36Sopenharmony_ci len = 32; 31262306a36Sopenharmony_ci for (i = 0; i < len; i++) { 31362306a36Sopenharmony_ci unsigned char c = p[i]; 31462306a36Sopenharmony_ci if (c >= 32 && c < 127) 31562306a36Sopenharmony_ci seq_putc(m, c); 31662306a36Sopenharmony_ci else 31762306a36Sopenharmony_ci seq_printf(m, "<%02x>", c); 31862306a36Sopenharmony_ci } 31962306a36Sopenharmony_ci seq_putc(m, '\n'); 32062306a36Sopenharmony_ci return 0; 32162306a36Sopenharmony_ci} 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_cistatic void *prism2_scan_results_proc_start(struct seq_file *m, loff_t *_pos) 32462306a36Sopenharmony_ci{ 32562306a36Sopenharmony_ci local_info_t *local = pde_data(file_inode(m->file)); 32662306a36Sopenharmony_ci spin_lock_bh(&local->lock); 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci /* We have a header (pos 0) + N results to show (pos 1...N) */ 32962306a36Sopenharmony_ci if (*_pos > local->last_scan_results_count) 33062306a36Sopenharmony_ci return NULL; 33162306a36Sopenharmony_ci return (void *)(unsigned long)(*_pos + 1); /* 0 would be EOF */ 33262306a36Sopenharmony_ci} 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_cistatic void *prism2_scan_results_proc_next(struct seq_file *m, void *v, loff_t *_pos) 33562306a36Sopenharmony_ci{ 33662306a36Sopenharmony_ci local_info_t *local = pde_data(file_inode(m->file)); 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_ci ++*_pos; 33962306a36Sopenharmony_ci if (*_pos > local->last_scan_results_count) 34062306a36Sopenharmony_ci return NULL; 34162306a36Sopenharmony_ci return (void *)(unsigned long)(*_pos + 1); /* 0 would be EOF */ 34262306a36Sopenharmony_ci} 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_cistatic void prism2_scan_results_proc_stop(struct seq_file *m, void *v) 34562306a36Sopenharmony_ci{ 34662306a36Sopenharmony_ci local_info_t *local = pde_data(file_inode(m->file)); 34762306a36Sopenharmony_ci spin_unlock_bh(&local->lock); 34862306a36Sopenharmony_ci} 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_cistatic const struct seq_operations prism2_scan_results_proc_seqops = { 35162306a36Sopenharmony_ci .start = prism2_scan_results_proc_start, 35262306a36Sopenharmony_ci .next = prism2_scan_results_proc_next, 35362306a36Sopenharmony_ci .stop = prism2_scan_results_proc_stop, 35462306a36Sopenharmony_ci .show = prism2_scan_results_proc_show, 35562306a36Sopenharmony_ci}; 35662306a36Sopenharmony_ci#endif /* PRISM2_NO_STATION_MODES */ 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_civoid hostap_init_proc(local_info_t *local) 36062306a36Sopenharmony_ci{ 36162306a36Sopenharmony_ci local->proc = NULL; 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci if (hostap_proc == NULL) { 36462306a36Sopenharmony_ci printk(KERN_WARNING "%s: hostap proc directory not created\n", 36562306a36Sopenharmony_ci local->dev->name); 36662306a36Sopenharmony_ci return; 36762306a36Sopenharmony_ci } 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_ci local->proc = proc_mkdir(local->ddev->name, hostap_proc); 37062306a36Sopenharmony_ci if (local->proc == NULL) { 37162306a36Sopenharmony_ci printk(KERN_INFO "/proc/net/hostap/%s creation failed\n", 37262306a36Sopenharmony_ci local->ddev->name); 37362306a36Sopenharmony_ci return; 37462306a36Sopenharmony_ci } 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_ci#ifndef PRISM2_NO_PROCFS_DEBUG 37762306a36Sopenharmony_ci proc_create_single_data("debug", 0, local->proc, 37862306a36Sopenharmony_ci prism2_debug_proc_show, local); 37962306a36Sopenharmony_ci#endif /* PRISM2_NO_PROCFS_DEBUG */ 38062306a36Sopenharmony_ci proc_create_single_data("stats", 0, local->proc, prism2_stats_proc_show, 38162306a36Sopenharmony_ci local); 38262306a36Sopenharmony_ci proc_create_seq_data("wds", 0, local->proc, 38362306a36Sopenharmony_ci &prism2_wds_proc_seqops, local); 38462306a36Sopenharmony_ci proc_create_data("pda", 0, local->proc, 38562306a36Sopenharmony_ci &prism2_pda_proc_ops, local); 38662306a36Sopenharmony_ci proc_create_data("aux_dump", 0, local->proc, 38762306a36Sopenharmony_ci local->func->read_aux_proc_ops ?: &prism2_aux_dump_proc_ops, 38862306a36Sopenharmony_ci local); 38962306a36Sopenharmony_ci proc_create_seq_data("bss_list", 0, local->proc, 39062306a36Sopenharmony_ci &prism2_bss_list_proc_seqops, local); 39162306a36Sopenharmony_ci proc_create_single_data("crypt", 0, local->proc, prism2_crypt_proc_show, 39262306a36Sopenharmony_ci local); 39362306a36Sopenharmony_ci#ifdef PRISM2_IO_DEBUG 39462306a36Sopenharmony_ci proc_create_single_data("io_debug", 0, local->proc, 39562306a36Sopenharmony_ci prism2_debug_proc_show, local); 39662306a36Sopenharmony_ci#endif /* PRISM2_IO_DEBUG */ 39762306a36Sopenharmony_ci#ifndef PRISM2_NO_STATION_MODES 39862306a36Sopenharmony_ci proc_create_seq_data("scan_results", 0, local->proc, 39962306a36Sopenharmony_ci &prism2_scan_results_proc_seqops, local); 40062306a36Sopenharmony_ci#endif /* PRISM2_NO_STATION_MODES */ 40162306a36Sopenharmony_ci} 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_civoid hostap_remove_proc(local_info_t *local) 40562306a36Sopenharmony_ci{ 40662306a36Sopenharmony_ci proc_remove(local->proc); 40762306a36Sopenharmony_ci} 40862306a36Sopenharmony_ci 40962306a36Sopenharmony_ci 41062306a36Sopenharmony_ciEXPORT_SYMBOL(hostap_init_proc); 41162306a36Sopenharmony_ciEXPORT_SYMBOL(hostap_remove_proc); 412