Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

lib80211: consolidate crypt init routines

Signed-off-by: John W. Linville <linville@tuxdriver.com>

+54 -117
+2 -59
drivers/net/wireless/hostap/hostap_hw.c
··· 2788 2788 } 2789 2789 2790 2790 2791 - static void prism2_crypt_deinit_entries(local_info_t *local, int force) 2792 - { 2793 - struct list_head *ptr, *n; 2794 - struct lib80211_crypt_data *entry; 2795 - 2796 - for (ptr = local->crypt_info.crypt_deinit_list.next, n = ptr->next; 2797 - ptr != &local->crypt_info.crypt_deinit_list; 2798 - ptr = n, n = ptr->next) { 2799 - entry = list_entry(ptr, struct lib80211_crypt_data, list); 2800 - 2801 - if (atomic_read(&entry->refcnt) != 0 && !force) 2802 - continue; 2803 - 2804 - list_del(ptr); 2805 - 2806 - if (entry->ops) 2807 - entry->ops->deinit(entry->priv); 2808 - kfree(entry); 2809 - } 2810 - } 2811 - 2812 - 2813 - static void prism2_crypt_deinit_handler(unsigned long data) 2814 - { 2815 - local_info_t *local = (local_info_t *) data; 2816 - unsigned long flags; 2817 - 2818 - spin_lock_irqsave(&local->lock, flags); 2819 - prism2_crypt_deinit_entries(local, 0); 2820 - if (!list_empty(&local->crypt_info.crypt_deinit_list)) { 2821 - printk(KERN_DEBUG "%s: entries remaining in delayed crypt " 2822 - "deletion list\n", local->dev->name); 2823 - local->crypt_info.crypt_deinit_timer.expires = jiffies + HZ; 2824 - add_timer(&local->crypt_info.crypt_deinit_timer); 2825 - } 2826 - spin_unlock_irqrestore(&local->lock, flags); 2827 - 2828 - } 2829 - 2830 - 2831 2791 static void hostap_passive_scan(unsigned long data) 2832 2792 { 2833 2793 local_info_t *local = (local_info_t *) data; ··· 3212 3252 INIT_LIST_HEAD(&local->cmd_queue); 3213 3253 init_waitqueue_head(&local->hostscan_wq); 3214 3254 3215 - local->crypt_info.name = dev->name; 3216 - local->crypt_info.lock = &local->lock; 3217 - INIT_LIST_HEAD(&local->crypt_info.crypt_deinit_list); 3218 - init_timer(&local->crypt_info.crypt_deinit_timer); 3219 - local->crypt_info.crypt_deinit_timer.data = (unsigned long) local; 3220 - local->crypt_info.crypt_deinit_timer.function = prism2_crypt_deinit_handler; 3255 + lib80211_crypt_info_init(&local->crypt_info, dev->name, &local->lock); 3221 3256 3222 3257 init_timer(&local->passive_scan_timer); 3223 3258 local->passive_scan_timer.data = (unsigned long) local; ··· 3313 3358 3314 3359 flush_scheduled_work(); 3315 3360 3316 - if (timer_pending(&local->crypt_info.crypt_deinit_timer)) 3317 - del_timer(&local->crypt_info.crypt_deinit_timer); 3318 - prism2_crypt_deinit_entries(local, 1); 3361 + lib80211_crypt_info_free(&local->crypt_info); 3319 3362 3320 3363 if (timer_pending(&local->passive_scan_timer)) 3321 3364 del_timer(&local->passive_scan_timer); ··· 3329 3376 3330 3377 if (local->dev_enabled) 3331 3378 prism2_callback(local, PRISM2_CALLBACK_DISABLE); 3332 - 3333 - for (i = 0; i < WEP_KEYS; i++) { 3334 - struct lib80211_crypt_data *crypt = local->crypt_info.crypt[i]; 3335 - if (crypt) { 3336 - if (crypt->ops) 3337 - crypt->ops->deinit(crypt->priv); 3338 - kfree(crypt); 3339 - local->crypt_info.crypt[i] = NULL; 3340 - } 3341 - } 3342 3379 3343 3380 if (local->ap != NULL) 3344 3381 hostap_free_data(local->ap);
+9 -34
drivers/net/wireless/hostap/hostap_ioctl.c
··· 116 116 } 117 117 118 118 119 - static void prism2_crypt_delayed_deinit(local_info_t *local, 120 - struct lib80211_crypt_data **crypt) 121 - { 122 - struct lib80211_crypt_data *tmp; 123 - unsigned long flags; 124 - 125 - tmp = *crypt; 126 - *crypt = NULL; 127 - 128 - if (tmp == NULL) 129 - return; 130 - 131 - /* must not run ops->deinit() while there may be pending encrypt or 132 - * decrypt operations. Use a list of delayed deinits to avoid needing 133 - * locking. */ 134 - 135 - spin_lock_irqsave(&local->lock, flags); 136 - list_add(&tmp->list, &local->crypt_info.crypt_deinit_list); 137 - if (!timer_pending(&local->crypt_info.crypt_deinit_timer)) { 138 - local->crypt_info.crypt_deinit_timer.expires = jiffies + HZ; 139 - add_timer(&local->crypt_info.crypt_deinit_timer); 140 - } 141 - spin_unlock_irqrestore(&local->lock, flags); 142 - } 143 - 144 - 145 119 static int prism2_ioctl_siwencode(struct net_device *dev, 146 120 struct iw_request_info *info, 147 121 struct iw_point *erq, char *keybuf) ··· 140 166 141 167 if (erq->flags & IW_ENCODE_DISABLED) { 142 168 if (*crypt) 143 - prism2_crypt_delayed_deinit(local, crypt); 169 + lib80211_crypt_delayed_deinit(&local->crypt_info, crypt); 144 170 goto done; 145 171 } 146 172 147 173 if (*crypt != NULL && (*crypt)->ops != NULL && 148 174 strcmp((*crypt)->ops->name, "WEP") != 0) { 149 175 /* changing to use WEP; deinit previously used algorithm */ 150 - prism2_crypt_delayed_deinit(local, crypt); 176 + lib80211_crypt_delayed_deinit(&local->crypt_info, crypt); 151 177 } 152 178 153 179 if (*crypt == NULL) { ··· 163 189 request_module("lib80211_crypt_wep"); 164 190 new_crypt->ops = lib80211_get_crypto_ops("WEP"); 165 191 } 166 - if (new_crypt->ops) 192 + if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) 167 193 new_crypt->priv = new_crypt->ops->init(i); 168 194 if (!new_crypt->ops || !new_crypt->priv) { 169 195 kfree(new_crypt); ··· 3243 3269 if ((erq->flags & IW_ENCODE_DISABLED) || 3244 3270 ext->alg == IW_ENCODE_ALG_NONE) { 3245 3271 if (*crypt) 3246 - prism2_crypt_delayed_deinit(local, crypt); 3272 + lib80211_crypt_delayed_deinit(&local->crypt_info, crypt); 3247 3273 goto done; 3248 3274 } 3249 3275 ··· 3291 3317 if (*crypt == NULL || (*crypt)->ops != ops) { 3292 3318 struct lib80211_crypt_data *new_crypt; 3293 3319 3294 - prism2_crypt_delayed_deinit(local, crypt); 3320 + lib80211_crypt_delayed_deinit(&local->crypt_info, crypt); 3295 3321 3296 3322 new_crypt = kzalloc(sizeof(struct lib80211_crypt_data), 3297 3323 GFP_KERNEL); ··· 3300 3326 goto done; 3301 3327 } 3302 3328 new_crypt->ops = ops; 3303 - new_crypt->priv = new_crypt->ops->init(i); 3329 + if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) 3330 + new_crypt->priv = new_crypt->ops->init(i); 3304 3331 if (new_crypt->priv == NULL) { 3305 3332 kfree(new_crypt); 3306 3333 ret = -EINVAL; ··· 3478 3503 3479 3504 if (strcmp(param->u.crypt.alg, "none") == 0) { 3480 3505 if (crypt) 3481 - prism2_crypt_delayed_deinit(local, crypt); 3506 + lib80211_crypt_delayed_deinit(&local->crypt_info, crypt); 3482 3507 goto done; 3483 3508 } 3484 3509 ··· 3508 3533 if (*crypt == NULL || (*crypt)->ops != ops) { 3509 3534 struct lib80211_crypt_data *new_crypt; 3510 3535 3511 - prism2_crypt_delayed_deinit(local, crypt); 3536 + lib80211_crypt_delayed_deinit(&local->crypt_info, crypt); 3512 3537 3513 3538 new_crypt = kzalloc(sizeof(struct lib80211_crypt_data), 3514 3539 GFP_KERNEL);
+3
include/net/lib80211.h
··· 114 114 int crypt_quiesced; 115 115 }; 116 116 117 + int lib80211_crypt_info_init(struct lib80211_crypt_info *info, char *name, 118 + spinlock_t *lock); 119 + void lib80211_crypt_info_free(struct lib80211_crypt_info *info); 117 120 int lib80211_register_crypto_ops(struct lib80211_crypto_ops *ops); 118 121 int lib80211_unregister_crypto_ops(struct lib80211_crypto_ops *ops); 119 122 struct lib80211_crypto_ops *lib80211_get_crypto_ops(const char *name);
+2 -24
net/ieee80211/ieee80211_module.c
··· 182 182 183 183 spin_lock_init(&ieee->lock); 184 184 185 - ieee->crypt_info.name = dev->name; 186 - ieee->crypt_info.lock = &ieee->lock; 187 - INIT_LIST_HEAD(&ieee->crypt_info.crypt_deinit_list); 188 - setup_timer(&ieee->crypt_info.crypt_deinit_timer, 189 - lib80211_crypt_deinit_handler, 190 - (unsigned long)&ieee->crypt_info); 191 - ieee->crypt_info.crypt_quiesced = 0; 185 + lib80211_crypt_info_init(&ieee->crypt_info, dev->name, &ieee->lock); 192 186 193 187 ieee->wpa_enabled = 0; 194 188 ieee->drop_unencrypted = 0; ··· 200 206 { 201 207 struct ieee80211_device *ieee = netdev_priv(dev); 202 208 203 - int i; 204 - 205 - lib80211_crypt_quiescing(&ieee->crypt_info); 206 - del_timer_sync(&ieee->crypt_info.crypt_deinit_timer); 207 - lib80211_crypt_deinit_entries(&ieee->crypt_info, 1); 208 - 209 - for (i = 0; i < WEP_KEYS; i++) { 210 - struct lib80211_crypt_data *crypt = ieee->crypt_info.crypt[i]; 211 - if (crypt) { 212 - if (crypt->ops) { 213 - crypt->ops->deinit(crypt->priv); 214 - module_put(crypt->ops->owner); 215 - } 216 - kfree(crypt); 217 - ieee->crypt_info.crypt[i] = NULL; 218 - } 219 - } 209 + lib80211_crypt_info_free(&ieee->crypt_info); 220 210 221 211 ieee80211_networks_free(ieee); 222 212 free_netdev(dev);
+38
net/wireless/lib80211.c
··· 71 71 } 72 72 EXPORT_SYMBOL(print_ssid); 73 73 74 + int lib80211_crypt_info_init(struct lib80211_crypt_info *info, char *name, 75 + spinlock_t *lock) 76 + { 77 + memset(info, 0, sizeof(*info)); 78 + 79 + info->name = name; 80 + info->lock = lock; 81 + 82 + INIT_LIST_HEAD(&info->crypt_deinit_list); 83 + setup_timer(&info->crypt_deinit_timer, lib80211_crypt_deinit_handler, 84 + (unsigned long)info); 85 + 86 + return 0; 87 + } 88 + EXPORT_SYMBOL(lib80211_crypt_info_init); 89 + 90 + void lib80211_crypt_info_free(struct lib80211_crypt_info *info) 91 + { 92 + int i; 93 + 94 + lib80211_crypt_quiescing(info); 95 + del_timer_sync(&info->crypt_deinit_timer); 96 + lib80211_crypt_deinit_entries(info, 1); 97 + 98 + for (i = 0; i < NUM_WEP_KEYS; i++) { 99 + struct lib80211_crypt_data *crypt = info->crypt[i]; 100 + if (crypt) { 101 + if (crypt->ops) { 102 + crypt->ops->deinit(crypt->priv); 103 + module_put(crypt->ops->owner); 104 + } 105 + kfree(crypt); 106 + info->crypt[i] = NULL; 107 + } 108 + } 109 + } 110 + EXPORT_SYMBOL(lib80211_crypt_info_free); 111 + 74 112 void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *info, int force) 75 113 { 76 114 struct lib80211_crypt_data *entry, *next;