0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include <linux/slab.h>
0017 #include <linux/firmware.h>
0018 #include <linux/etherdevice.h>
0019 #include <linux/module.h>
0020
0021 #include <net/mac80211.h>
0022
0023 #include "p54.h"
0024 #include "lmac.h"
0025
0026 static bool modparam_nohwcrypt;
0027 module_param_named(nohwcrypt, modparam_nohwcrypt, bool, 0444);
0028 MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
0029 MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
0030 MODULE_DESCRIPTION("Softmac Prism54 common code");
0031 MODULE_LICENSE("GPL");
0032 MODULE_ALIAS("prism54common");
0033
0034 static int p54_sta_add_remove(struct ieee80211_hw *hw,
0035 struct ieee80211_vif *vif,
0036 struct ieee80211_sta *sta)
0037 {
0038 struct p54_common *priv = hw->priv;
0039
0040
0041
0042
0043
0044
0045 p54_sta_unlock(priv, sta->addr);
0046
0047 return 0;
0048 }
0049
0050 static void p54_sta_notify(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
0051 enum sta_notify_cmd notify_cmd,
0052 struct ieee80211_sta *sta)
0053 {
0054 struct p54_common *priv = dev->priv;
0055
0056 switch (notify_cmd) {
0057 case STA_NOTIFY_AWAKE:
0058
0059 p54_sta_unlock(priv, sta->addr);
0060 break;
0061 default:
0062 break;
0063 }
0064 }
0065
0066 static int p54_set_tim(struct ieee80211_hw *dev, struct ieee80211_sta *sta,
0067 bool set)
0068 {
0069 struct p54_common *priv = dev->priv;
0070
0071 return p54_update_beacon_tim(priv, sta->aid, set);
0072 }
0073
0074 u8 *p54_find_ie(struct sk_buff *skb, u8 ie)
0075 {
0076 struct ieee80211_mgmt *mgmt = (void *)skb->data;
0077 u8 *pos, *end;
0078
0079 if (skb->len <= sizeof(mgmt))
0080 return NULL;
0081
0082 pos = (u8 *)mgmt->u.beacon.variable;
0083 end = skb->data + skb->len;
0084 while (pos < end) {
0085 if (pos + 2 + pos[1] > end)
0086 return NULL;
0087
0088 if (pos[0] == ie)
0089 return pos;
0090
0091 pos += 2 + pos[1];
0092 }
0093 return NULL;
0094 }
0095
0096 static int p54_beacon_format_ie_tim(struct sk_buff *skb)
0097 {
0098
0099
0100
0101
0102
0103 u8 *tim;
0104 u8 dtim_len;
0105 u8 dtim_period;
0106 u8 *next;
0107
0108 tim = p54_find_ie(skb, WLAN_EID_TIM);
0109 if (!tim)
0110 return 0;
0111
0112 dtim_len = tim[1];
0113 dtim_period = tim[3];
0114 next = tim + 2 + dtim_len;
0115
0116 if (dtim_len < 3)
0117 return -EINVAL;
0118
0119 memmove(tim, next, skb_tail_pointer(skb) - next);
0120 tim = skb_tail_pointer(skb) - (dtim_len + 2);
0121
0122
0123 tim[0] = WLAN_EID_TIM;
0124 tim[1] = 3;
0125 tim[2] = 0;
0126 tim[3] = dtim_period;
0127 tim[4] = 0;
0128
0129 if (dtim_len > 3)
0130 skb_trim(skb, skb->len - (dtim_len - 3));
0131
0132 return 0;
0133 }
0134
0135 static int p54_beacon_update(struct p54_common *priv,
0136 struct ieee80211_vif *vif)
0137 {
0138 struct ieee80211_tx_control control = { };
0139 struct sk_buff *beacon;
0140 int ret;
0141
0142 beacon = ieee80211_beacon_get(priv->hw, vif, 0);
0143 if (!beacon)
0144 return -ENOMEM;
0145 ret = p54_beacon_format_ie_tim(beacon);
0146 if (ret)
0147 return ret;
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158 p54_tx_80211(priv->hw, &control, beacon);
0159 priv->tsf_high32 = 0;
0160 priv->tsf_low32 = 0;
0161
0162 return 0;
0163 }
0164
0165 static int p54_start(struct ieee80211_hw *dev)
0166 {
0167 struct p54_common *priv = dev->priv;
0168 int err;
0169
0170 mutex_lock(&priv->conf_mutex);
0171 err = priv->open(dev);
0172 if (err)
0173 goto out;
0174 P54_SET_QUEUE(priv->qos_params[0], 0x0002, 0x0003, 0x0007, 47);
0175 P54_SET_QUEUE(priv->qos_params[1], 0x0002, 0x0007, 0x000f, 94);
0176 P54_SET_QUEUE(priv->qos_params[2], 0x0003, 0x000f, 0x03ff, 0);
0177 P54_SET_QUEUE(priv->qos_params[3], 0x0007, 0x000f, 0x03ff, 0);
0178 err = p54_set_edcf(priv);
0179 if (err)
0180 goto out;
0181
0182 eth_broadcast_addr(priv->bssid);
0183 priv->mode = NL80211_IFTYPE_MONITOR;
0184 err = p54_setup_mac(priv);
0185 if (err) {
0186 priv->mode = NL80211_IFTYPE_UNSPECIFIED;
0187 goto out;
0188 }
0189
0190 ieee80211_queue_delayed_work(dev, &priv->work, 0);
0191
0192 priv->softled_state = 0;
0193 err = p54_set_leds(priv);
0194
0195 out:
0196 mutex_unlock(&priv->conf_mutex);
0197 return err;
0198 }
0199
0200 static void p54_stop(struct ieee80211_hw *dev)
0201 {
0202 struct p54_common *priv = dev->priv;
0203 int i;
0204
0205 priv->mode = NL80211_IFTYPE_UNSPECIFIED;
0206 priv->softled_state = 0;
0207 cancel_delayed_work_sync(&priv->work);
0208 mutex_lock(&priv->conf_mutex);
0209 p54_set_leds(priv);
0210 priv->stop(dev);
0211 skb_queue_purge(&priv->tx_pending);
0212 skb_queue_purge(&priv->tx_queue);
0213 for (i = 0; i < P54_QUEUE_NUM; i++) {
0214 priv->tx_stats[i].count = 0;
0215 priv->tx_stats[i].len = 0;
0216 }
0217
0218 priv->beacon_req_id = cpu_to_le32(0);
0219 priv->tsf_high32 = priv->tsf_low32 = 0;
0220 mutex_unlock(&priv->conf_mutex);
0221 }
0222
0223 static int p54_add_interface(struct ieee80211_hw *dev,
0224 struct ieee80211_vif *vif)
0225 {
0226 struct p54_common *priv = dev->priv;
0227 int err;
0228
0229 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
0230
0231 mutex_lock(&priv->conf_mutex);
0232 if (priv->mode != NL80211_IFTYPE_MONITOR) {
0233 mutex_unlock(&priv->conf_mutex);
0234 return -EOPNOTSUPP;
0235 }
0236
0237 priv->vif = vif;
0238
0239 switch (vif->type) {
0240 case NL80211_IFTYPE_STATION:
0241 case NL80211_IFTYPE_ADHOC:
0242 case NL80211_IFTYPE_AP:
0243 case NL80211_IFTYPE_MESH_POINT:
0244 priv->mode = vif->type;
0245 break;
0246 default:
0247 mutex_unlock(&priv->conf_mutex);
0248 return -EOPNOTSUPP;
0249 }
0250
0251 memcpy(priv->mac_addr, vif->addr, ETH_ALEN);
0252 err = p54_setup_mac(priv);
0253 mutex_unlock(&priv->conf_mutex);
0254 return err;
0255 }
0256
0257 static void p54_remove_interface(struct ieee80211_hw *dev,
0258 struct ieee80211_vif *vif)
0259 {
0260 struct p54_common *priv = dev->priv;
0261
0262 mutex_lock(&priv->conf_mutex);
0263 priv->vif = NULL;
0264
0265
0266
0267
0268
0269 if (le32_to_cpu(priv->beacon_req_id) != 0) {
0270 p54_tx_cancel(priv, priv->beacon_req_id);
0271 wait_for_completion_interruptible_timeout(&priv->beacon_comp, HZ);
0272 }
0273 priv->mode = NL80211_IFTYPE_MONITOR;
0274 eth_zero_addr(priv->mac_addr);
0275 eth_zero_addr(priv->bssid);
0276 p54_setup_mac(priv);
0277 mutex_unlock(&priv->conf_mutex);
0278 }
0279
0280 static int p54_wait_for_stats(struct ieee80211_hw *dev)
0281 {
0282 struct p54_common *priv = dev->priv;
0283 int ret;
0284
0285 priv->update_stats = true;
0286 ret = p54_fetch_statistics(priv);
0287 if (ret)
0288 return ret;
0289
0290 ret = wait_for_completion_interruptible_timeout(&priv->stat_comp, HZ);
0291 if (ret == 0)
0292 return -ETIMEDOUT;
0293
0294 return 0;
0295 }
0296
0297 static void p54_reset_stats(struct p54_common *priv)
0298 {
0299 struct ieee80211_channel *chan = priv->curchan;
0300
0301 if (chan) {
0302 struct survey_info *info = &priv->survey[chan->hw_value];
0303
0304
0305 info->time = 0;
0306 info->time_busy = 0;
0307 info->time_tx = 0;
0308 }
0309
0310 priv->update_stats = true;
0311 priv->survey_raw.active = 0;
0312 priv->survey_raw.cca = 0;
0313 priv->survey_raw.tx = 0;
0314 }
0315
0316 static int p54_config(struct ieee80211_hw *dev, u32 changed)
0317 {
0318 int ret = 0;
0319 struct p54_common *priv = dev->priv;
0320 struct ieee80211_conf *conf = &dev->conf;
0321
0322 mutex_lock(&priv->conf_mutex);
0323 if (changed & IEEE80211_CONF_CHANGE_POWER)
0324 priv->output_power = conf->power_level << 2;
0325 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
0326 struct ieee80211_channel *oldchan;
0327 WARN_ON(p54_wait_for_stats(dev));
0328 oldchan = priv->curchan;
0329 priv->curchan = NULL;
0330 ret = p54_scan(priv, P54_SCAN_EXIT, 0);
0331 if (ret) {
0332 priv->curchan = oldchan;
0333 goto out;
0334 }
0335
0336
0337
0338
0339 priv->curchan = priv->hw->conf.chandef.chan;
0340 p54_reset_stats(priv);
0341 WARN_ON(p54_fetch_statistics(priv));
0342 }
0343 if (changed & IEEE80211_CONF_CHANGE_PS) {
0344 WARN_ON(p54_wait_for_stats(dev));
0345 ret = p54_set_ps(priv);
0346 if (ret)
0347 goto out;
0348 WARN_ON(p54_wait_for_stats(dev));
0349 }
0350 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
0351 WARN_ON(p54_wait_for_stats(dev));
0352 ret = p54_setup_mac(priv);
0353 if (ret)
0354 goto out;
0355 WARN_ON(p54_wait_for_stats(dev));
0356 }
0357
0358 out:
0359 mutex_unlock(&priv->conf_mutex);
0360 return ret;
0361 }
0362
0363 static u64 p54_prepare_multicast(struct ieee80211_hw *dev,
0364 struct netdev_hw_addr_list *mc_list)
0365 {
0366 struct p54_common *priv = dev->priv;
0367 struct netdev_hw_addr *ha;
0368 int i;
0369
0370 BUILD_BUG_ON(ARRAY_SIZE(priv->mc_maclist) !=
0371 ARRAY_SIZE(((struct p54_group_address_table *)NULL)->mac_list));
0372
0373
0374
0375
0376 i = 1;
0377 priv->mc_maclist_num = netdev_hw_addr_list_count(mc_list) + i;
0378 netdev_hw_addr_list_for_each(ha, mc_list) {
0379 memcpy(&priv->mc_maclist[i], ha->addr, ETH_ALEN);
0380 i++;
0381 if (i >= ARRAY_SIZE(priv->mc_maclist))
0382 break;
0383 }
0384
0385 return 1;
0386 }
0387
0388 static void p54_configure_filter(struct ieee80211_hw *dev,
0389 unsigned int changed_flags,
0390 unsigned int *total_flags,
0391 u64 multicast)
0392 {
0393 struct p54_common *priv = dev->priv;
0394
0395 *total_flags &= FIF_ALLMULTI | FIF_OTHER_BSS;
0396
0397 priv->filter_flags = *total_flags;
0398
0399 if (changed_flags & FIF_OTHER_BSS)
0400 p54_setup_mac(priv);
0401
0402 if (changed_flags & FIF_ALLMULTI || multicast)
0403 p54_set_groupfilter(priv);
0404 }
0405
0406 static int p54_conf_tx(struct ieee80211_hw *dev,
0407 struct ieee80211_vif *vif,
0408 unsigned int link_id, u16 queue,
0409 const struct ieee80211_tx_queue_params *params)
0410 {
0411 struct p54_common *priv = dev->priv;
0412 int ret;
0413
0414 mutex_lock(&priv->conf_mutex);
0415 P54_SET_QUEUE(priv->qos_params[queue], params->aifs,
0416 params->cw_min, params->cw_max, params->txop);
0417 ret = p54_set_edcf(priv);
0418 mutex_unlock(&priv->conf_mutex);
0419 return ret;
0420 }
0421
0422 static void p54_work(struct work_struct *work)
0423 {
0424 struct p54_common *priv = container_of(work, struct p54_common,
0425 work.work);
0426
0427 if (unlikely(priv->mode == NL80211_IFTYPE_UNSPECIFIED))
0428 return ;
0429
0430
0431
0432
0433
0434
0435
0436 mutex_lock(&priv->conf_mutex);
0437 WARN_ON_ONCE(p54_fetch_statistics(priv));
0438 mutex_unlock(&priv->conf_mutex);
0439 }
0440
0441 static int p54_get_stats(struct ieee80211_hw *dev,
0442 struct ieee80211_low_level_stats *stats)
0443 {
0444 struct p54_common *priv = dev->priv;
0445
0446 memcpy(stats, &priv->stats, sizeof(*stats));
0447 return 0;
0448 }
0449
0450 static void p54_bss_info_changed(struct ieee80211_hw *dev,
0451 struct ieee80211_vif *vif,
0452 struct ieee80211_bss_conf *info,
0453 u64 changed)
0454 {
0455 struct p54_common *priv = dev->priv;
0456
0457 mutex_lock(&priv->conf_mutex);
0458 if (changed & BSS_CHANGED_BSSID) {
0459 memcpy(priv->bssid, info->bssid, ETH_ALEN);
0460 p54_setup_mac(priv);
0461 }
0462
0463 if (changed & BSS_CHANGED_BEACON) {
0464 p54_scan(priv, P54_SCAN_EXIT, 0);
0465 p54_setup_mac(priv);
0466 p54_beacon_update(priv, vif);
0467 p54_set_edcf(priv);
0468 }
0469
0470 if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_BEACON)) {
0471 priv->use_short_slot = info->use_short_slot;
0472 p54_set_edcf(priv);
0473 }
0474 if (changed & BSS_CHANGED_BASIC_RATES) {
0475 if (dev->conf.chandef.chan->band == NL80211_BAND_5GHZ)
0476 priv->basic_rate_mask = (info->basic_rates << 4);
0477 else
0478 priv->basic_rate_mask = info->basic_rates;
0479 p54_setup_mac(priv);
0480 if (priv->fw_var >= 0x500)
0481 p54_scan(priv, P54_SCAN_EXIT, 0);
0482 }
0483 if (changed & BSS_CHANGED_ASSOC) {
0484 if (vif->cfg.assoc) {
0485 priv->aid = vif->cfg.aid;
0486 priv->wakeup_timer = info->beacon_int *
0487 info->dtim_period * 5;
0488 p54_setup_mac(priv);
0489 } else {
0490 priv->wakeup_timer = 500;
0491 priv->aid = 0;
0492 }
0493 }
0494
0495 mutex_unlock(&priv->conf_mutex);
0496 }
0497
0498 static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
0499 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
0500 struct ieee80211_key_conf *key)
0501 {
0502 struct p54_common *priv = dev->priv;
0503 int slot, ret = 0;
0504 u8 algo = 0;
0505 u8 *addr = NULL;
0506
0507 if (modparam_nohwcrypt)
0508 return -EOPNOTSUPP;
0509
0510 if (key->flags & IEEE80211_KEY_FLAG_RX_MGMT) {
0511
0512
0513
0514
0515
0516
0517
0518 return -EOPNOTSUPP;
0519 }
0520
0521 mutex_lock(&priv->conf_mutex);
0522 if (cmd == SET_KEY) {
0523 switch (key->cipher) {
0524 case WLAN_CIPHER_SUITE_TKIP:
0525 if (!(priv->privacy_caps & (BR_DESC_PRIV_CAP_MICHAEL |
0526 BR_DESC_PRIV_CAP_TKIP))) {
0527 ret = -EOPNOTSUPP;
0528 goto out_unlock;
0529 }
0530 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
0531 algo = P54_CRYPTO_TKIPMICHAEL;
0532 break;
0533 case WLAN_CIPHER_SUITE_WEP40:
0534 case WLAN_CIPHER_SUITE_WEP104:
0535 if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_WEP)) {
0536 ret = -EOPNOTSUPP;
0537 goto out_unlock;
0538 }
0539 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
0540 algo = P54_CRYPTO_WEP;
0541 break;
0542 case WLAN_CIPHER_SUITE_CCMP:
0543 if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP)) {
0544 ret = -EOPNOTSUPP;
0545 goto out_unlock;
0546 }
0547 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
0548 algo = P54_CRYPTO_AESCCMP;
0549 break;
0550 default:
0551 ret = -EOPNOTSUPP;
0552 goto out_unlock;
0553 }
0554 slot = bitmap_find_free_region(priv->used_rxkeys,
0555 priv->rx_keycache_size, 0);
0556
0557 if (slot < 0) {
0558
0559
0560
0561
0562
0563
0564
0565
0566
0567
0568 key->hw_key_idx = 0xff;
0569 goto out_unlock;
0570 }
0571
0572 key->flags |= IEEE80211_KEY_FLAG_RESERVE_TAILROOM;
0573 } else {
0574 slot = key->hw_key_idx;
0575
0576 if (slot == 0xff) {
0577
0578
0579 goto out_unlock;
0580 }
0581
0582 bitmap_release_region(priv->used_rxkeys, slot, 0);
0583 algo = 0;
0584 }
0585
0586 if (sta)
0587 addr = sta->addr;
0588
0589 ret = p54_upload_key(priv, algo, slot, key->keyidx,
0590 key->keylen, addr, key->key);
0591 if (ret) {
0592 bitmap_release_region(priv->used_rxkeys, slot, 0);
0593 ret = -EOPNOTSUPP;
0594 goto out_unlock;
0595 }
0596
0597 key->hw_key_idx = slot;
0598
0599 out_unlock:
0600 mutex_unlock(&priv->conf_mutex);
0601 return ret;
0602 }
0603
0604 static int p54_get_survey(struct ieee80211_hw *dev, int idx,
0605 struct survey_info *survey)
0606 {
0607 struct p54_common *priv = dev->priv;
0608 struct ieee80211_channel *chan;
0609 int err, tries;
0610 bool in_use = false;
0611
0612 if (idx >= priv->chan_num)
0613 return -ENOENT;
0614
0615 #define MAX_TRIES 1
0616 for (tries = 0; tries < MAX_TRIES; tries++) {
0617 chan = priv->curchan;
0618 if (chan && chan->hw_value == idx) {
0619 mutex_lock(&priv->conf_mutex);
0620 err = p54_wait_for_stats(dev);
0621 mutex_unlock(&priv->conf_mutex);
0622 if (err)
0623 return err;
0624
0625 in_use = true;
0626 }
0627
0628 memcpy(survey, &priv->survey[idx], sizeof(*survey));
0629
0630 if (in_use) {
0631
0632 if (survey->time != 0) {
0633 survey->filled |= SURVEY_INFO_IN_USE;
0634 } else {
0635
0636
0637
0638
0639
0640
0641 msleep(100);
0642 continue;
0643 }
0644 }
0645 return 0;
0646 }
0647 return -ETIMEDOUT;
0648 #undef MAX_TRIES
0649 }
0650
0651 static unsigned int p54_flush_count(struct p54_common *priv)
0652 {
0653 unsigned int total = 0, i;
0654
0655 BUILD_BUG_ON(P54_QUEUE_NUM > ARRAY_SIZE(priv->tx_stats));
0656
0657
0658
0659
0660
0661
0662 for (i = P54_QUEUE_MGMT; i < P54_QUEUE_NUM; i++)
0663 total += priv->tx_stats[i].len;
0664 return total;
0665 }
0666
0667 static void p54_flush(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
0668 u32 queues, bool drop)
0669 {
0670 struct p54_common *priv = dev->priv;
0671 unsigned int total, i;
0672
0673
0674
0675
0676
0677
0678
0679 i = P54_STATISTICS_UPDATE * 2 / 20;
0680
0681
0682
0683
0684
0685
0686 while ((total = p54_flush_count(priv)) && i--) {
0687
0688 msleep(20);
0689 }
0690
0691 WARN(total, "tx flush timeout, unresponsive firmware");
0692 }
0693
0694 static void p54_set_coverage_class(struct ieee80211_hw *dev,
0695 s16 coverage_class)
0696 {
0697 struct p54_common *priv = dev->priv;
0698
0699 mutex_lock(&priv->conf_mutex);
0700
0701 priv->coverage_class = clamp_t(u8, coverage_class, 0, 31);
0702 p54_set_edcf(priv);
0703 mutex_unlock(&priv->conf_mutex);
0704 }
0705
0706 static const struct ieee80211_ops p54_ops = {
0707 .tx = p54_tx_80211,
0708 .start = p54_start,
0709 .stop = p54_stop,
0710 .add_interface = p54_add_interface,
0711 .remove_interface = p54_remove_interface,
0712 .set_tim = p54_set_tim,
0713 .sta_notify = p54_sta_notify,
0714 .sta_add = p54_sta_add_remove,
0715 .sta_remove = p54_sta_add_remove,
0716 .set_key = p54_set_key,
0717 .config = p54_config,
0718 .flush = p54_flush,
0719 .bss_info_changed = p54_bss_info_changed,
0720 .prepare_multicast = p54_prepare_multicast,
0721 .configure_filter = p54_configure_filter,
0722 .conf_tx = p54_conf_tx,
0723 .get_stats = p54_get_stats,
0724 .get_survey = p54_get_survey,
0725 .set_coverage_class = p54_set_coverage_class,
0726 };
0727
0728 struct ieee80211_hw *p54_init_common(size_t priv_data_len)
0729 {
0730 struct ieee80211_hw *dev;
0731 struct p54_common *priv;
0732
0733 dev = ieee80211_alloc_hw(priv_data_len, &p54_ops);
0734 if (!dev)
0735 return NULL;
0736
0737 priv = dev->priv;
0738 priv->hw = dev;
0739 priv->mode = NL80211_IFTYPE_UNSPECIFIED;
0740 priv->basic_rate_mask = 0x15f;
0741 spin_lock_init(&priv->tx_stats_lock);
0742 skb_queue_head_init(&priv->tx_queue);
0743 skb_queue_head_init(&priv->tx_pending);
0744 ieee80211_hw_set(dev, REPORTS_TX_ACK_STATUS);
0745 ieee80211_hw_set(dev, MFP_CAPABLE);
0746 ieee80211_hw_set(dev, PS_NULLFUNC_STACK);
0747 ieee80211_hw_set(dev, SUPPORTS_PS);
0748 ieee80211_hw_set(dev, RX_INCLUDES_FCS);
0749 ieee80211_hw_set(dev, SIGNAL_DBM);
0750
0751 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
0752 BIT(NL80211_IFTYPE_ADHOC) |
0753 BIT(NL80211_IFTYPE_AP) |
0754 BIT(NL80211_IFTYPE_MESH_POINT);
0755
0756 priv->beacon_req_id = cpu_to_le32(0);
0757 priv->tx_stats[P54_QUEUE_BEACON].limit = 1;
0758 priv->tx_stats[P54_QUEUE_FWSCAN].limit = 1;
0759 priv->tx_stats[P54_QUEUE_MGMT].limit = 3;
0760 priv->tx_stats[P54_QUEUE_CAB].limit = 3;
0761 priv->tx_stats[P54_QUEUE_DATA].limit = 5;
0762 dev->queues = 1;
0763 priv->noise = -94;
0764
0765
0766
0767
0768
0769
0770
0771
0772 dev->max_rates = 4;
0773 dev->max_rate_tries = 7;
0774 dev->extra_tx_headroom = sizeof(struct p54_hdr) + 4 +
0775 sizeof(struct p54_tx_data);
0776
0777
0778
0779
0780
0781 dev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
0782
0783 mutex_init(&priv->conf_mutex);
0784 mutex_init(&priv->eeprom_mutex);
0785 init_completion(&priv->stat_comp);
0786 init_completion(&priv->eeprom_comp);
0787 init_completion(&priv->beacon_comp);
0788 INIT_DELAYED_WORK(&priv->work, p54_work);
0789
0790 eth_broadcast_addr(priv->mc_maclist[0]);
0791 priv->curchan = NULL;
0792 p54_reset_stats(priv);
0793 return dev;
0794 }
0795 EXPORT_SYMBOL_GPL(p54_init_common);
0796
0797 int p54_register_common(struct ieee80211_hw *dev, struct device *pdev)
0798 {
0799 struct p54_common __maybe_unused *priv = dev->priv;
0800 int err;
0801
0802 err = ieee80211_register_hw(dev);
0803 if (err) {
0804 dev_err(pdev, "Cannot register device (%d).\n", err);
0805 return err;
0806 }
0807 priv->registered = true;
0808
0809 #ifdef CONFIG_P54_LEDS
0810 err = p54_init_leds(priv);
0811 if (err) {
0812 p54_unregister_common(dev);
0813 return err;
0814 }
0815 #endif
0816
0817 dev_info(pdev, "is registered as '%s'\n", wiphy_name(dev->wiphy));
0818 return 0;
0819 }
0820 EXPORT_SYMBOL_GPL(p54_register_common);
0821
0822 void p54_free_common(struct ieee80211_hw *dev)
0823 {
0824 struct p54_common *priv = dev->priv;
0825 unsigned int i;
0826
0827 for (i = 0; i < NUM_NL80211_BANDS; i++)
0828 kfree(priv->band_table[i]);
0829
0830 kfree(priv->iq_autocal);
0831 kfree(priv->output_limit);
0832 kfree(priv->curve_data);
0833 kfree(priv->rssi_db);
0834 bitmap_free(priv->used_rxkeys);
0835 kfree(priv->survey);
0836 priv->iq_autocal = NULL;
0837 priv->output_limit = NULL;
0838 priv->curve_data = NULL;
0839 priv->rssi_db = NULL;
0840 priv->used_rxkeys = NULL;
0841 priv->survey = NULL;
0842 ieee80211_free_hw(dev);
0843 }
0844 EXPORT_SYMBOL_GPL(p54_free_common);
0845
0846 void p54_unregister_common(struct ieee80211_hw *dev)
0847 {
0848 struct p54_common *priv = dev->priv;
0849
0850 if (priv->registered) {
0851 priv->registered = false;
0852 #ifdef CONFIG_P54_LEDS
0853 p54_unregister_leds(priv);
0854 #endif
0855 ieee80211_unregister_hw(dev);
0856 }
0857
0858 mutex_destroy(&priv->conf_mutex);
0859 mutex_destroy(&priv->eeprom_mutex);
0860 }
0861 EXPORT_SYMBOL_GPL(p54_unregister_common);