Changeset 1666

Show
Ignore:
Timestamp:
07/04/06 12:22:11 (3 years ago)
Author:
kelmo
Message:

This patch improves the ability of VAPs to handle proc entries.
Specifically it allows parts of the driver to register a proc entry
and appropriate handlers with the vap. The vap will then take care of
ensuring that this proc entry exists for the lifetime of the vap and
that it is correctly relocated if the vap is renamed.

Previously these tasks had to be handled by whatever registered the
proc entry, which promoted code duplication.

The list of proc entries for a specific vap is stored as a linked
list. Two new methods are added.

The first is used to add a proc entry to the vap. It is called
ieee80211_proc_vcreate.

  • vap - pointer to the vap to create the entry for
  • fileops - pointer to methods to handle read/writes from the entry.
    Any NULL entries in this structure will be substituted with
    default entries. These default entries will use a
    proc_ieee80211_priv structure to provide a list of associated
    stations. Typically a caller will only need to provide an open
    method to read the desired information into the read buffer of the
    proc_ieee80211_priv structure.
  • name - the name for the proc entry

The second method (ieee80211_proc_cleanup) is only used internally
and cleans up the memory used by the linked list of proc entries
when the vap is destroyed. ieee80211_proc_vdetach cannot be used for
this purpose as it is used when a vap is being renamed. Were we to
deallocate the linked list in the vdetach method all registered proc
entries would be lost if a vap was renamed.

This patch will make it significantly easier to perform further
development to add more information to the proc interface.

Closes #728

Signed-off-by: Matt Brown <matt@mattb.net.nz>

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/net80211/ieee80211.c

    r1614 r1666  
    579579 
    580580        ieee80211_sysctl_vdetach(vap); 
     581        ieee80211_proc_cleanup(vap); 
    581582        ieee80211_ioctl_vdetach(vap); 
    582583        ieee80211_vlan_vdetach(vap); 
  • trunk/net80211/ieee80211_linux.c

    r1590 r1666  
    319319#ifdef CONFIG_SYSCTL 
    320320 
    321 #define MAX_PROC_IEEE80211_SIZE 16383 
    322 #define PROC_IEEE80211_PERM 0644 
    323  
    324321static struct proc_dir_entry *proc_madwifi; 
    325322static int proc_madwifi_count = 0; 
    326  
    327 /* XXX: Not the right place for such a declaration */ 
    328 struct proc_ieee80211_priv { 
    329      int rlen; 
    330      int max_rlen; 
    331      char *rbuf; 
    332  
    333      int wlen; 
    334      int max_wlen; 
    335      char *wbuf; 
    336 }; 
    337323 
    338324static int 
     
    599585        int i, space; 
    600586        char *devname = NULL; 
     587        struct ieee80211_proc_entry *tmp=NULL; 
    601588         
    602589        space = 5 * sizeof(struct ctl_table) + sizeof(ieee80211_sysctl_template); 
     
    650637        } 
    651638 
     639        /* Ensure the base madwifi directory exists */ 
    652640        if (!proc_madwifi && proc_net != NULL) { 
    653641                proc_madwifi = proc_mkdir("madwifi", proc_net); 
     
    656644        } 
    657645 
     646        /* Create a proc directory named after the VAP */ 
    658647        if (proc_madwifi) { 
    659648                proc_madwifi_count++; 
    660649                vap->iv_proc = proc_mkdir(vap->iv_dev->name, proc_madwifi); 
     650        } 
     651         
     652        /* Create a proc entry listing the associated stations */ 
     653        ieee80211_proc_vcreate(vap, &proc_ieee80211_ops, "associated_sta"); 
     654 
     655        /* Recreate any other proc entries that have been registered */ 
    661656                if (vap->iv_proc) { 
    662                         vap->iv_proc_stations = create_proc_entry("associated_sta", 
     657                tmp = vap->iv_proc_entries; 
     658                while (tmp) { 
     659                        if (!tmp->entry) { 
     660                                tmp->entry = create_proc_entry(tmp->name,  
    663661                                PROC_IEEE80211_PERM, vap->iv_proc); 
    664                         vap->iv_proc_stations->data = vap; 
    665                         vap->iv_proc_stations->proc_fops = &proc_ieee80211_ops; 
     662                                tmp->entry->data = vap; 
     663                                tmp->entry->proc_fops = tmp->fileops; 
     664                        } 
     665                        tmp = tmp->next; 
    666666                } 
    667667        } 
    668668} 
    669669 
     670/* Frees all memory used for the list of proc entries */ 
     671void  
     672ieee80211_proc_cleanup(struct ieee80211vap *vap) 
     673{ 
     674        struct ieee80211_proc_entry *tmp=vap->iv_proc_entries; 
     675        struct ieee80211_proc_entry *next = NULL; 
     676        while (tmp) { 
     677                next = tmp->next; 
     678                kfree(tmp); 
     679                tmp = next; 
     680        } 
     681} 
     682 
     683/* Called by other modules to register a proc entry under the vap directory */ 
     684int  
     685ieee80211_proc_vcreate(struct ieee80211vap *vap,  
     686                struct file_operations *fileops, char *name) 
     687{ 
     688        struct ieee80211_proc_entry *entry; 
     689        struct ieee80211_proc_entry *tmp=NULL; 
     690 
     691        /* Ignore if already in the list */ 
     692        if (vap->iv_proc_entries) { 
     693                tmp = vap->iv_proc_entries; 
     694                do { 
     695                        if (strcmp(tmp->name, name)==0) 
     696                                return -1; 
     697                        /* Check for end of list */ 
     698                        if (!tmp->next) 
     699                                break; 
     700                        /* Otherwise move on */ 
     701                        tmp = tmp->next; 
     702                } while (1); 
     703        } 
     704         
     705        /* Create an item in our list for the new entry */ 
     706        entry = kmalloc(sizeof(struct ieee80211_proc_entry), GFP_KERNEL); 
     707        if (entry == NULL) { 
     708                printk("%s: no memory for new proc entry (%s)!\n", __func__,  
     709                                name); 
     710                return -1; 
     711        } 
     712 
     713        /* Replace null fileops pointers with our standard functions */ 
     714        if (!fileops->open) 
     715                fileops->open = proc_ieee80211_open; 
     716        if (!fileops->release) 
     717                fileops->release = proc_ieee80211_close; 
     718        if (!fileops->read) 
     719                fileops->read = proc_ieee80211_read; 
     720        if (!fileops->write) 
     721                fileops->write = proc_ieee80211_write; 
     722         
     723        /* Create the entry record */ 
     724        entry->name = name; 
     725        entry->fileops = fileops; 
     726        entry->next = NULL; 
     727        entry->entry = NULL; 
     728 
     729        /* Create the actual proc entry */ 
     730        if (vap->iv_proc) { 
     731                entry->entry = create_proc_entry(entry->name,  
     732                                PROC_IEEE80211_PERM, vap->iv_proc); 
     733                entry->entry->data = vap; 
     734                entry->entry->proc_fops = entry->fileops; 
     735        } 
     736 
     737        /* Add it to the list */ 
     738        if (!tmp) { 
     739                /* Add to the start */ 
     740                vap->iv_proc_entries = entry; 
     741        } else { 
     742                /* Add to the end */ 
     743                tmp->next = entry; 
     744        } 
     745 
     746        return 0; 
     747} 
     748EXPORT_SYMBOL(ieee80211_proc_vcreate); 
     749 
    670750void 
    671751ieee80211_sysctl_vdetach(struct ieee80211vap *vap) 
    672752{ 
     753        struct ieee80211_proc_entry *tmp=NULL; 
     754 
    673755        if (vap->iv_sysctl_header) { 
    674756                unregister_sysctl_table(vap->iv_sysctl_header); 
     
    677759 
    678760        if (vap->iv_proc) { 
    679                 remove_proc_entry("associated_sta", vap->iv_proc); 
     761                /* Remove child proc entries but leave them in the list */ 
     762                tmp = vap->iv_proc_entries; 
     763                while (tmp) { 
     764                        if (tmp->entry) { 
     765                                remove_proc_entry(tmp->name, vap->iv_proc); 
     766                                tmp->entry = NULL; 
     767                        } 
     768                        tmp = tmp->next; 
     769                } 
    680770                remove_proc_entry(vap->iv_proc->name, proc_madwifi); 
    681771                if (proc_madwifi_count == 1) { 
  • trunk/net80211/ieee80211_linux.h

    r1657 r1666  
    480480void ieee80211_sysctl_vattach(struct ieee80211vap *); 
    481481void ieee80211_sysctl_vdetach(struct ieee80211vap *); 
     482int ieee80211_proc_vcreate(struct ieee80211vap *, struct file_operations *, 
     483               char *); 
     484void ieee80211_proc_cleanup(struct ieee80211vap *); 
    482485#endif /* CONFIG_SYSCTL */ 
    483486 
  • trunk/net80211/ieee80211_var.h

    r1613 r1666  
    266266}; 
    267267 
     268#ifdef CONFIG_SYSCTL 
     269#define MAX_PROC_IEEE80211_SIZE 16383 
     270#define PROC_IEEE80211_PERM 0644 
     271 
     272struct proc_ieee80211_priv { 
     273     int rlen; 
     274     int max_rlen; 
     275     char *rbuf; 
     276 
     277     int wlen; 
     278     int max_wlen; 
     279     char *wbuf; 
     280}; 
     281 
     282struct ieee80211_proc_entry { 
     283        char *name; 
     284        struct file_operations *fileops; 
     285        struct proc_dir_entry *entry; 
     286        struct ieee80211_proc_entry *next; 
     287}; 
     288#endif 
     289 
    268290struct ieee80211vap { 
    269291        struct net_device *iv_dev;              /* associated device */ 
     
    276298        struct ctl_table_header *iv_sysctl_header; 
    277299        struct ctl_table *iv_sysctls; 
    278         struct proc_dir_entry *iv_proc_stations; 
    279300        struct proc_dir_entry *iv_proc; 
     301        struct ieee80211_proc_entry *iv_proc_entries; 
    280302#endif 
    281303        struct vlan_group *iv_vlgrp;            /* vlan group state */