aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorVasanthakumar Thiagarajan <vasanth@atheros.com>2008-09-10 09:19:27 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-09-15 16:48:19 -0400
commit8feceb67929bd23bfca58d5f49df93d7fc315bb1 (patch)
treefe6449d4a96141d520bcbbf6637ab04013044585 /drivers
parentf8e77caefea8940ee1fb09c9ebb0107ca2eadb72 (diff)
ath9k: Re-order functions in main.c
Some of the functions in main.c are re-ordered in such a way that all local functions are defined before mac80211 and pci callbacks. Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/ath9k/main.c938
1 files changed, 469 insertions, 469 deletions
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index 57d7cc87cb0f..07e5b5d877b6 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -325,6 +325,475 @@ static u8 parse_mpdudensity(u8 mpdudensity)
325 } 325 }
326} 326}
327 327
328static void ath9k_ht_conf(struct ath_softc *sc,
329 struct ieee80211_bss_conf *bss_conf)
330{
331#define IEEE80211_HT_CAP_40MHZ_INTOLERANT BIT(14)
332 struct ath_ht_info *ht_info = &sc->sc_ht_info;
333
334 if (bss_conf->assoc_ht) {
335 ht_info->ext_chan_offset =
336 bss_conf->ht_bss_conf->bss_cap &
337 IEEE80211_HT_IE_CHA_SEC_OFFSET;
338
339 if (!(bss_conf->ht_conf->cap &
340 IEEE80211_HT_CAP_40MHZ_INTOLERANT) &&
341 (bss_conf->ht_bss_conf->bss_cap &
342 IEEE80211_HT_IE_CHA_WIDTH))
343 ht_info->tx_chan_width = ATH9K_HT_MACMODE_2040;
344 else
345 ht_info->tx_chan_width = ATH9K_HT_MACMODE_20;
346
347 ath9k_hw_set11nmac2040(sc->sc_ah, ht_info->tx_chan_width);
348 ht_info->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR +
349 bss_conf->ht_conf->ampdu_factor);
350 ht_info->mpdudensity =
351 parse_mpdudensity(bss_conf->ht_conf->ampdu_density);
352
353 }
354
355#undef IEEE80211_HT_CAP_40MHZ_INTOLERANT
356}
357
358static void ath9k_bss_assoc_info(struct ath_softc *sc,
359 struct ieee80211_bss_conf *bss_conf)
360{
361 struct ieee80211_hw *hw = sc->hw;
362 struct ieee80211_channel *curchan = hw->conf.channel;
363 struct ath_vap *avp;
364 int pos;
365 DECLARE_MAC_BUF(mac);
366
367 if (bss_conf->assoc) {
368 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Bss Info ASSOC %d\n",
369 __func__,
370 bss_conf->aid);
371
372 avp = sc->sc_vaps[0];
373 if (avp == NULL) {
374 DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid interface\n",
375 __func__);
376 return;
377 }
378
379 /* New association, store aid */
380 if (avp->av_opmode == ATH9K_M_STA) {
381 sc->sc_curaid = bss_conf->aid;
382 ath9k_hw_write_associd(sc->sc_ah, sc->sc_curbssid,
383 sc->sc_curaid);
384 }
385
386 /* Configure the beacon */
387 ath_beacon_config(sc, 0);
388 sc->sc_flags |= SC_OP_BEACONS;
389
390 /* Reset rssi stats */
391 sc->sc_halstats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER;
392 sc->sc_halstats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER;
393 sc->sc_halstats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER;
394 sc->sc_halstats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER;
395
396 /* Update chainmask */
397 ath_update_chainmask(sc, bss_conf->assoc_ht);
398
399 DPRINTF(sc, ATH_DBG_CONFIG,
400 "%s: bssid %s aid 0x%x\n",
401 __func__,
402 print_mac(mac, sc->sc_curbssid), sc->sc_curaid);
403
404 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Set channel: %d MHz\n",
405 __func__,
406 curchan->center_freq);
407
408 pos = ath_get_channel(sc, curchan);
409 if (pos == -1) {
410 DPRINTF(sc, ATH_DBG_FATAL,
411 "%s: Invalid channel\n", __func__);
412 return;
413 }
414
415 if (hw->conf.ht_conf.ht_supported)
416 sc->sc_ah->ah_channels[pos].chanmode =
417 ath_get_extchanmode(sc, curchan);
418 else
419 sc->sc_ah->ah_channels[pos].chanmode =
420 (curchan->band == IEEE80211_BAND_2GHZ) ?
421 CHANNEL_G : CHANNEL_A;
422
423 /* set h/w channel */
424 if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0)
425 DPRINTF(sc, ATH_DBG_FATAL,
426 "%s: Unable to set channel\n",
427 __func__);
428
429 ath_rate_newstate(sc, avp);
430 /* Update ratectrl about the new state */
431 ath_rc_node_update(hw, avp->rc_node);
432 } else {
433 DPRINTF(sc, ATH_DBG_CONFIG,
434 "%s: Bss Info DISSOC\n", __func__);
435 sc->sc_curaid = 0;
436 }
437}
438
439void ath_get_beaconconfig(struct ath_softc *sc,
440 int if_id,
441 struct ath_beacon_config *conf)
442{
443 struct ieee80211_hw *hw = sc->hw;
444
445 /* fill in beacon config data */
446
447 conf->beacon_interval = hw->conf.beacon_int;
448 conf->listen_interval = 100;
449 conf->dtim_count = 1;
450 conf->bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf->listen_interval;
451}
452
453void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
454 struct ath_xmit_status *tx_status, struct ath_node *an)
455{
456 struct ieee80211_hw *hw = sc->hw;
457 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
458
459 DPRINTF(sc, ATH_DBG_XMIT,
460 "%s: TX complete: skb: %p\n", __func__, skb);
461
462 if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK ||
463 tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
464 /* free driver's private data area of tx_info */
465 if (tx_info->driver_data[0] != NULL)
466 kfree(tx_info->driver_data[0]);
467 tx_info->driver_data[0] = NULL;
468 }
469
470 if (tx_status->flags & ATH_TX_BAR) {
471 tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
472 tx_status->flags &= ~ATH_TX_BAR;
473 }
474
475 if (tx_status->flags & (ATH_TX_ERROR | ATH_TX_XRETRY)) {
476 if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) {
477 /* Frame was not ACKed, but an ACK was expected */
478 tx_info->status.excessive_retries = 1;
479 }
480 } else {
481 /* Frame was ACKed */
482 tx_info->flags |= IEEE80211_TX_STAT_ACK;
483 }
484
485 tx_info->status.retry_count = tx_status->retries;
486
487 ieee80211_tx_status(hw, skb);
488 if (an)
489 ath_node_put(sc, an, ATH9K_BH_STATUS_CHANGE);
490}
491
492int _ath_rx_indicate(struct ath_softc *sc,
493 struct sk_buff *skb,
494 struct ath_recv_status *status,
495 u16 keyix)
496{
497 struct ieee80211_hw *hw = sc->hw;
498 struct ath_node *an = NULL;
499 struct ieee80211_rx_status rx_status;
500 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
501 int hdrlen = ieee80211_get_hdrlen_from_skb(skb);
502 int padsize;
503 enum ATH_RX_TYPE st;
504
505 /* see if any padding is done by the hw and remove it */
506 if (hdrlen & 3) {
507 padsize = hdrlen % 4;
508 memmove(skb->data + padsize, skb->data, hdrlen);
509 skb_pull(skb, padsize);
510 }
511
512 /* Prepare rx status */
513 ath9k_rx_prepare(sc, skb, status, &rx_status);
514
515 if (!(keyix == ATH9K_RXKEYIX_INVALID) &&
516 !(status->flags & ATH_RX_DECRYPT_ERROR)) {
517 rx_status.flag |= RX_FLAG_DECRYPTED;
518 } else if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_PROTECTED)
519 && !(status->flags & ATH_RX_DECRYPT_ERROR)
520 && skb->len >= hdrlen + 4) {
521 keyix = skb->data[hdrlen + 3] >> 6;
522
523 if (test_bit(keyix, sc->sc_keymap))
524 rx_status.flag |= RX_FLAG_DECRYPTED;
525 }
526
527 spin_lock_bh(&sc->node_lock);
528 an = ath_node_find(sc, hdr->addr2);
529 spin_unlock_bh(&sc->node_lock);
530
531 if (an) {
532 ath_rx_input(sc, an,
533 hw->conf.ht_conf.ht_supported,
534 skb, status, &st);
535 }
536 if (!an || (st != ATH_RX_CONSUMED))
537 __ieee80211_rx(hw, skb, &rx_status);
538
539 return 0;
540}
541
542int ath_rx_subframe(struct ath_node *an,
543 struct sk_buff *skb,
544 struct ath_recv_status *status)
545{
546 struct ath_softc *sc = an->an_sc;
547 struct ieee80211_hw *hw = sc->hw;
548 struct ieee80211_rx_status rx_status;
549
550 /* Prepare rx status */
551 ath9k_rx_prepare(sc, skb, status, &rx_status);
552 if (!(status->flags & ATH_RX_DECRYPT_ERROR))
553 rx_status.flag |= RX_FLAG_DECRYPTED;
554
555 __ieee80211_rx(hw, skb, &rx_status);
556
557 return 0;
558}
559
560/********************************/
561/* LED functions */
562/********************************/
563
564static void ath_led_brightness(struct led_classdev *led_cdev,
565 enum led_brightness brightness)
566{
567 struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
568 struct ath_softc *sc = led->sc;
569
570 switch (brightness) {
571 case LED_OFF:
572 if (led->led_type == ATH_LED_ASSOC ||
573 led->led_type == ATH_LED_RADIO)
574 sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
575 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN,
576 (led->led_type == ATH_LED_RADIO) ? 1 :
577 !!(sc->sc_flags & SC_OP_LED_ASSOCIATED));
578 break;
579 case LED_FULL:
580 if (led->led_type == ATH_LED_ASSOC)
581 sc->sc_flags |= SC_OP_LED_ASSOCIATED;
582 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0);
583 break;
584 default:
585 break;
586 }
587}
588
589static int ath_register_led(struct ath_softc *sc, struct ath_led *led,
590 char *trigger)
591{
592 int ret;
593
594 led->sc = sc;
595 led->led_cdev.name = led->name;
596 led->led_cdev.default_trigger = trigger;
597 led->led_cdev.brightness_set = ath_led_brightness;
598
599 ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev);
600 if (ret)
601 DPRINTF(sc, ATH_DBG_FATAL,
602 "Failed to register led:%s", led->name);
603 else
604 led->registered = 1;
605 return ret;
606}
607
608static void ath_unregister_led(struct ath_led *led)
609{
610 if (led->registered) {
611 led_classdev_unregister(&led->led_cdev);
612 led->registered = 0;
613 }
614}
615
616static void ath_deinit_leds(struct ath_softc *sc)
617{
618 ath_unregister_led(&sc->assoc_led);
619 sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
620 ath_unregister_led(&sc->tx_led);
621 ath_unregister_led(&sc->rx_led);
622 ath_unregister_led(&sc->radio_led);
623 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
624}
625
626static void ath_init_leds(struct ath_softc *sc)
627{
628 char *trigger;
629 int ret;
630
631 /* Configure gpio 1 for output */
632 ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN,
633 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
634 /* LED off, active low */
635 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
636
637 trigger = ieee80211_get_radio_led_name(sc->hw);
638 snprintf(sc->radio_led.name, sizeof(sc->radio_led.name),
639 "ath9k-%s:radio", wiphy_name(sc->hw->wiphy));
640 ret = ath_register_led(sc, &sc->radio_led, trigger);
641 sc->radio_led.led_type = ATH_LED_RADIO;
642 if (ret)
643 goto fail;
644
645 trigger = ieee80211_get_assoc_led_name(sc->hw);
646 snprintf(sc->assoc_led.name, sizeof(sc->assoc_led.name),
647 "ath9k-%s:assoc", wiphy_name(sc->hw->wiphy));
648 ret = ath_register_led(sc, &sc->assoc_led, trigger);
649 sc->assoc_led.led_type = ATH_LED_ASSOC;
650 if (ret)
651 goto fail;
652
653 trigger = ieee80211_get_tx_led_name(sc->hw);
654 snprintf(sc->tx_led.name, sizeof(sc->tx_led.name),
655 "ath9k-%s:tx", wiphy_name(sc->hw->wiphy));
656 ret = ath_register_led(sc, &sc->tx_led, trigger);
657 sc->tx_led.led_type = ATH_LED_TX;
658 if (ret)
659 goto fail;
660
661 trigger = ieee80211_get_rx_led_name(sc->hw);
662 snprintf(sc->rx_led.name, sizeof(sc->rx_led.name),
663 "ath9k-%s:rx", wiphy_name(sc->hw->wiphy));
664 ret = ath_register_led(sc, &sc->rx_led, trigger);
665 sc->rx_led.led_type = ATH_LED_RX;
666 if (ret)
667 goto fail;
668
669 return;
670
671fail:
672 ath_deinit_leds(sc);
673}
674
675static int ath_detach(struct ath_softc *sc)
676{
677 struct ieee80211_hw *hw = sc->hw;
678
679 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Detach ATH hw\n", __func__);
680
681 /* Deinit LED control */
682 ath_deinit_leds(sc);
683
684 /* Unregister hw */
685
686 ieee80211_unregister_hw(hw);
687
688 /* unregister Rate control */
689 ath_rate_control_unregister();
690
691 /* tx/rx cleanup */
692
693 ath_rx_cleanup(sc);
694 ath_tx_cleanup(sc);
695
696 /* Deinit */
697
698 ath_deinit(sc);
699
700 return 0;
701}
702
703static int ath_attach(u16 devid,
704 struct ath_softc *sc)
705{
706 struct ieee80211_hw *hw = sc->hw;
707 int error = 0;
708
709 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Attach ATH hw\n", __func__);
710
711 error = ath_init(devid, sc);
712 if (error != 0)
713 return error;
714
715 /* Init nodes */
716
717 INIT_LIST_HEAD(&sc->node_list);
718 spin_lock_init(&sc->node_lock);
719
720 /* get mac address from hardware and set in mac80211 */
721
722 SET_IEEE80211_PERM_ADDR(hw, sc->sc_myaddr);
723
724 /* setup channels and rates */
725
726 sc->sbands[IEEE80211_BAND_2GHZ].channels =
727 sc->channels[IEEE80211_BAND_2GHZ];
728 sc->sbands[IEEE80211_BAND_2GHZ].bitrates =
729 sc->rates[IEEE80211_BAND_2GHZ];
730 sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
731
732 if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT)
733 /* Setup HT capabilities for 2.4Ghz*/
734 setup_ht_cap(&sc->sbands[IEEE80211_BAND_2GHZ].ht_info);
735
736 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
737 &sc->sbands[IEEE80211_BAND_2GHZ];
738
739 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes)) {
740 sc->sbands[IEEE80211_BAND_5GHZ].channels =
741 sc->channels[IEEE80211_BAND_5GHZ];
742 sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
743 sc->rates[IEEE80211_BAND_5GHZ];
744 sc->sbands[IEEE80211_BAND_5GHZ].band =
745 IEEE80211_BAND_5GHZ;
746
747 if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT)
748 /* Setup HT capabilities for 5Ghz*/
749 setup_ht_cap(&sc->sbands[IEEE80211_BAND_5GHZ].ht_info);
750
751 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
752 &sc->sbands[IEEE80211_BAND_5GHZ];
753 }
754
755 /* FIXME: Have to figure out proper hw init values later */
756
757 hw->queues = 4;
758 hw->ampdu_queues = 1;
759
760 /* Register rate control */
761 hw->rate_control_algorithm = "ath9k_rate_control";
762 error = ath_rate_control_register();
763 if (error != 0) {
764 DPRINTF(sc, ATH_DBG_FATAL,
765 "%s: Unable to register rate control "
766 "algorithm:%d\n", __func__, error);
767 ath_rate_control_unregister();
768 goto bad;
769 }
770
771 error = ieee80211_register_hw(hw);
772 if (error != 0) {
773 ath_rate_control_unregister();
774 goto bad;
775 }
776
777 /* Initialize LED control */
778 ath_init_leds(sc);
779
780 /* initialize tx/rx engine */
781
782 error = ath_tx_init(sc, ATH_TXBUF);
783 if (error != 0)
784 goto detach;
785
786 error = ath_rx_init(sc, ATH_RXBUF);
787 if (error != 0)
788 goto detach;
789
790 return 0;
791detach:
792 ath_detach(sc);
793bad:
794 return error;
795}
796
328static int ath9k_start(struct ieee80211_hw *hw) 797static int ath9k_start(struct ieee80211_hw *hw)
329{ 798{
330 struct ath_softc *sc = hw->priv; 799 struct ath_softc *sc = hw->priv;
@@ -798,117 +1267,6 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
798 return ret; 1267 return ret;
799} 1268}
800 1269
801static void ath9k_ht_conf(struct ath_softc *sc,
802 struct ieee80211_bss_conf *bss_conf)
803{
804#define IEEE80211_HT_CAP_40MHZ_INTOLERANT BIT(14)
805 struct ath_ht_info *ht_info = &sc->sc_ht_info;
806
807 if (bss_conf->assoc_ht) {
808 ht_info->ext_chan_offset =
809 bss_conf->ht_bss_conf->bss_cap &
810 IEEE80211_HT_IE_CHA_SEC_OFFSET;
811
812 if (!(bss_conf->ht_conf->cap &
813 IEEE80211_HT_CAP_40MHZ_INTOLERANT) &&
814 (bss_conf->ht_bss_conf->bss_cap &
815 IEEE80211_HT_IE_CHA_WIDTH))
816 ht_info->tx_chan_width = ATH9K_HT_MACMODE_2040;
817 else
818 ht_info->tx_chan_width = ATH9K_HT_MACMODE_20;
819
820 ath9k_hw_set11nmac2040(sc->sc_ah, ht_info->tx_chan_width);
821 ht_info->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR +
822 bss_conf->ht_conf->ampdu_factor);
823 ht_info->mpdudensity =
824 parse_mpdudensity(bss_conf->ht_conf->ampdu_density);
825
826 }
827
828#undef IEEE80211_HT_CAP_40MHZ_INTOLERANT
829}
830
831static void ath9k_bss_assoc_info(struct ath_softc *sc,
832 struct ieee80211_bss_conf *bss_conf)
833{
834 struct ieee80211_hw *hw = sc->hw;
835 struct ieee80211_channel *curchan = hw->conf.channel;
836 struct ath_vap *avp;
837 int pos;
838 DECLARE_MAC_BUF(mac);
839
840 if (bss_conf->assoc) {
841 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Bss Info ASSOC %d\n",
842 __func__,
843 bss_conf->aid);
844
845 avp = sc->sc_vaps[0];
846 if (avp == NULL) {
847 DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid interface\n",
848 __func__);
849 return;
850 }
851
852 /* New association, store aid */
853 if (avp->av_opmode == ATH9K_M_STA) {
854 sc->sc_curaid = bss_conf->aid;
855 ath9k_hw_write_associd(sc->sc_ah, sc->sc_curbssid,
856 sc->sc_curaid);
857 }
858
859 /* Configure the beacon */
860 ath_beacon_config(sc, 0);
861 sc->sc_flags |= SC_OP_BEACONS;
862
863 /* Reset rssi stats */
864 sc->sc_halstats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER;
865 sc->sc_halstats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER;
866 sc->sc_halstats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER;
867 sc->sc_halstats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER;
868
869 /* Update chainmask */
870 ath_update_chainmask(sc, bss_conf->assoc_ht);
871
872 DPRINTF(sc, ATH_DBG_CONFIG,
873 "%s: bssid %s aid 0x%x\n",
874 __func__,
875 print_mac(mac, sc->sc_curbssid), sc->sc_curaid);
876
877 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Set channel: %d MHz\n",
878 __func__,
879 curchan->center_freq);
880
881 pos = ath_get_channel(sc, curchan);
882 if (pos == -1) {
883 DPRINTF(sc, ATH_DBG_FATAL,
884 "%s: Invalid channel\n", __func__);
885 return;
886 }
887
888 if (hw->conf.ht_conf.ht_supported)
889 sc->sc_ah->ah_channels[pos].chanmode =
890 ath_get_extchanmode(sc, curchan);
891 else
892 sc->sc_ah->ah_channels[pos].chanmode =
893 (curchan->band == IEEE80211_BAND_2GHZ) ?
894 CHANNEL_G : CHANNEL_A;
895
896 /* set h/w channel */
897 if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0)
898 DPRINTF(sc, ATH_DBG_FATAL,
899 "%s: Unable to set channel\n",
900 __func__);
901
902 ath_rate_newstate(sc, avp);
903 /* Update ratectrl about the new state */
904 ath_rc_node_update(hw, avp->rc_node);
905 } else {
906 DPRINTF(sc, ATH_DBG_CONFIG,
907 "%s: Bss Info DISSOC\n", __func__);
908 sc->sc_curaid = 0;
909 }
910}
911
912static void ath9k_bss_info_changed(struct ieee80211_hw *hw, 1270static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
913 struct ieee80211_vif *vif, 1271 struct ieee80211_vif *vif,
914 struct ieee80211_bss_conf *bss_conf, 1272 struct ieee80211_bss_conf *bss_conf,
@@ -1048,364 +1406,6 @@ static struct ieee80211_ops ath9k_ops = {
1048 .ampdu_action = ath9k_ampdu_action 1406 .ampdu_action = ath9k_ampdu_action
1049}; 1407};
1050 1408
1051void ath_get_beaconconfig(struct ath_softc *sc,
1052 int if_id,
1053 struct ath_beacon_config *conf)
1054{
1055 struct ieee80211_hw *hw = sc->hw;
1056
1057 /* fill in beacon config data */
1058
1059 conf->beacon_interval = hw->conf.beacon_int;
1060 conf->listen_interval = 100;
1061 conf->dtim_count = 1;
1062 conf->bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf->listen_interval;
1063}
1064
1065void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
1066 struct ath_xmit_status *tx_status, struct ath_node *an)
1067{
1068 struct ieee80211_hw *hw = sc->hw;
1069 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1070
1071 DPRINTF(sc, ATH_DBG_XMIT,
1072 "%s: TX complete: skb: %p\n", __func__, skb);
1073
1074 if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK ||
1075 tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
1076 /* free driver's private data area of tx_info */
1077 if (tx_info->driver_data[0] != NULL)
1078 kfree(tx_info->driver_data[0]);
1079 tx_info->driver_data[0] = NULL;
1080 }
1081
1082 if (tx_status->flags & ATH_TX_BAR) {
1083 tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
1084 tx_status->flags &= ~ATH_TX_BAR;
1085 }
1086
1087 if (tx_status->flags & (ATH_TX_ERROR | ATH_TX_XRETRY)) {
1088 if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) {
1089 /* Frame was not ACKed, but an ACK was expected */
1090 tx_info->status.excessive_retries = 1;
1091 }
1092 } else {
1093 /* Frame was ACKed */
1094 tx_info->flags |= IEEE80211_TX_STAT_ACK;
1095 }
1096
1097 tx_info->status.retry_count = tx_status->retries;
1098
1099 ieee80211_tx_status(hw, skb);
1100 if (an)
1101 ath_node_put(sc, an, ATH9K_BH_STATUS_CHANGE);
1102}
1103
1104int _ath_rx_indicate(struct ath_softc *sc,
1105 struct sk_buff *skb,
1106 struct ath_recv_status *status,
1107 u16 keyix)
1108{
1109 struct ieee80211_hw *hw = sc->hw;
1110 struct ath_node *an = NULL;
1111 struct ieee80211_rx_status rx_status;
1112 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1113 int hdrlen = ieee80211_get_hdrlen_from_skb(skb);
1114 int padsize;
1115 enum ATH_RX_TYPE st;
1116
1117 /* see if any padding is done by the hw and remove it */
1118 if (hdrlen & 3) {
1119 padsize = hdrlen % 4;
1120 memmove(skb->data + padsize, skb->data, hdrlen);
1121 skb_pull(skb, padsize);
1122 }
1123
1124 /* Prepare rx status */
1125 ath9k_rx_prepare(sc, skb, status, &rx_status);
1126
1127 if (!(keyix == ATH9K_RXKEYIX_INVALID) &&
1128 !(status->flags & ATH_RX_DECRYPT_ERROR)) {
1129 rx_status.flag |= RX_FLAG_DECRYPTED;
1130 } else if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_PROTECTED)
1131 && !(status->flags & ATH_RX_DECRYPT_ERROR)
1132 && skb->len >= hdrlen + 4) {
1133 keyix = skb->data[hdrlen + 3] >> 6;
1134
1135 if (test_bit(keyix, sc->sc_keymap))
1136 rx_status.flag |= RX_FLAG_DECRYPTED;
1137 }
1138
1139 spin_lock_bh(&sc->node_lock);
1140 an = ath_node_find(sc, hdr->addr2);
1141 spin_unlock_bh(&sc->node_lock);
1142
1143 if (an) {
1144 ath_rx_input(sc, an,
1145 hw->conf.ht_conf.ht_supported,
1146 skb, status, &st);
1147 }
1148 if (!an || (st != ATH_RX_CONSUMED))
1149 __ieee80211_rx(hw, skb, &rx_status);
1150
1151 return 0;
1152}
1153
1154int ath_rx_subframe(struct ath_node *an,
1155 struct sk_buff *skb,
1156 struct ath_recv_status *status)
1157{
1158 struct ath_softc *sc = an->an_sc;
1159 struct ieee80211_hw *hw = sc->hw;
1160 struct ieee80211_rx_status rx_status;
1161
1162 /* Prepare rx status */
1163 ath9k_rx_prepare(sc, skb, status, &rx_status);
1164 if (!(status->flags & ATH_RX_DECRYPT_ERROR))
1165 rx_status.flag |= RX_FLAG_DECRYPTED;
1166
1167 __ieee80211_rx(hw, skb, &rx_status);
1168
1169 return 0;
1170}
1171
1172/********************************/
1173/* LED functions */
1174/********************************/
1175
1176static void ath_led_brightness(struct led_classdev *led_cdev,
1177 enum led_brightness brightness)
1178{
1179 struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
1180 struct ath_softc *sc = led->sc;
1181
1182 switch (brightness) {
1183 case LED_OFF:
1184 if (led->led_type == ATH_LED_ASSOC ||
1185 led->led_type == ATH_LED_RADIO)
1186 sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
1187 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN,
1188 (led->led_type == ATH_LED_RADIO) ? 1 :
1189 !!(sc->sc_flags & SC_OP_LED_ASSOCIATED));
1190 break;
1191 case LED_FULL:
1192 if (led->led_type == ATH_LED_ASSOC)
1193 sc->sc_flags |= SC_OP_LED_ASSOCIATED;
1194 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0);
1195 break;
1196 default:
1197 break;
1198 }
1199}
1200
1201static int ath_register_led(struct ath_softc *sc, struct ath_led *led,
1202 char *trigger)
1203{
1204 int ret;
1205
1206 led->sc = sc;
1207 led->led_cdev.name = led->name;
1208 led->led_cdev.default_trigger = trigger;
1209 led->led_cdev.brightness_set = ath_led_brightness;
1210
1211 ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev);
1212 if (ret)
1213 DPRINTF(sc, ATH_DBG_FATAL,
1214 "Failed to register led:%s", led->name);
1215 else
1216 led->registered = 1;
1217 return ret;
1218}
1219
1220static void ath_unregister_led(struct ath_led *led)
1221{
1222 if (led->registered) {
1223 led_classdev_unregister(&led->led_cdev);
1224 led->registered = 0;
1225 }
1226}
1227
1228static void ath_deinit_leds(struct ath_softc *sc)
1229{
1230 ath_unregister_led(&sc->assoc_led);
1231 sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
1232 ath_unregister_led(&sc->tx_led);
1233 ath_unregister_led(&sc->rx_led);
1234 ath_unregister_led(&sc->radio_led);
1235 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
1236}
1237
1238static void ath_init_leds(struct ath_softc *sc)
1239{
1240 char *trigger;
1241 int ret;
1242
1243 /* Configure gpio 1 for output */
1244 ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN,
1245 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
1246 /* LED off, active low */
1247 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
1248
1249 trigger = ieee80211_get_radio_led_name(sc->hw);
1250 snprintf(sc->radio_led.name, sizeof(sc->radio_led.name),
1251 "ath9k-%s:radio", wiphy_name(sc->hw->wiphy));
1252 ret = ath_register_led(sc, &sc->radio_led, trigger);
1253 sc->radio_led.led_type = ATH_LED_RADIO;
1254 if (ret)
1255 goto fail;
1256
1257 trigger = ieee80211_get_assoc_led_name(sc->hw);
1258 snprintf(sc->assoc_led.name, sizeof(sc->assoc_led.name),
1259 "ath9k-%s:assoc", wiphy_name(sc->hw->wiphy));
1260 ret = ath_register_led(sc, &sc->assoc_led, trigger);
1261 sc->assoc_led.led_type = ATH_LED_ASSOC;
1262 if (ret)
1263 goto fail;
1264
1265 trigger = ieee80211_get_tx_led_name(sc->hw);
1266 snprintf(sc->tx_led.name, sizeof(sc->tx_led.name),
1267 "ath9k-%s:tx", wiphy_name(sc->hw->wiphy));
1268 ret = ath_register_led(sc, &sc->tx_led, trigger);
1269 sc->tx_led.led_type = ATH_LED_TX;
1270 if (ret)
1271 goto fail;
1272
1273 trigger = ieee80211_get_rx_led_name(sc->hw);
1274 snprintf(sc->rx_led.name, sizeof(sc->rx_led.name),
1275 "ath9k-%s:rx", wiphy_name(sc->hw->wiphy));
1276 ret = ath_register_led(sc, &sc->rx_led, trigger);
1277 sc->rx_led.led_type = ATH_LED_RX;
1278 if (ret)
1279 goto fail;
1280
1281 return;
1282
1283fail:
1284 ath_deinit_leds(sc);
1285}
1286
1287static int ath_detach(struct ath_softc *sc)
1288{
1289 struct ieee80211_hw *hw = sc->hw;
1290
1291 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Detach ATH hw\n", __func__);
1292
1293 /* Deinit LED control */
1294 ath_deinit_leds(sc);
1295
1296 /* Unregister hw */
1297
1298 ieee80211_unregister_hw(hw);
1299
1300 /* unregister Rate control */
1301 ath_rate_control_unregister();
1302
1303 /* tx/rx cleanup */
1304
1305 ath_rx_cleanup(sc);
1306 ath_tx_cleanup(sc);
1307
1308 /* Deinit */
1309
1310 ath_deinit(sc);
1311
1312 return 0;
1313}
1314
1315static int ath_attach(u16 devid,
1316 struct ath_softc *sc)
1317{
1318 struct ieee80211_hw *hw = sc->hw;
1319 int error = 0;
1320
1321 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Attach ATH hw\n", __func__);
1322
1323 error = ath_init(devid, sc);
1324 if (error != 0)
1325 return error;
1326
1327 /* Init nodes */
1328
1329 INIT_LIST_HEAD(&sc->node_list);
1330 spin_lock_init(&sc->node_lock);
1331
1332 /* get mac address from hardware and set in mac80211 */
1333
1334 SET_IEEE80211_PERM_ADDR(hw, sc->sc_myaddr);
1335
1336 /* setup channels and rates */
1337
1338 sc->sbands[IEEE80211_BAND_2GHZ].channels =
1339 sc->channels[IEEE80211_BAND_2GHZ];
1340 sc->sbands[IEEE80211_BAND_2GHZ].bitrates =
1341 sc->rates[IEEE80211_BAND_2GHZ];
1342 sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
1343
1344 if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT)
1345 /* Setup HT capabilities for 2.4Ghz*/
1346 setup_ht_cap(&sc->sbands[IEEE80211_BAND_2GHZ].ht_info);
1347
1348 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
1349 &sc->sbands[IEEE80211_BAND_2GHZ];
1350
1351 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes)) {
1352 sc->sbands[IEEE80211_BAND_5GHZ].channels =
1353 sc->channels[IEEE80211_BAND_5GHZ];
1354 sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
1355 sc->rates[IEEE80211_BAND_5GHZ];
1356 sc->sbands[IEEE80211_BAND_5GHZ].band =
1357 IEEE80211_BAND_5GHZ;
1358
1359 if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT)
1360 /* Setup HT capabilities for 5Ghz*/
1361 setup_ht_cap(&sc->sbands[IEEE80211_BAND_5GHZ].ht_info);
1362
1363 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
1364 &sc->sbands[IEEE80211_BAND_5GHZ];
1365 }
1366
1367 /* FIXME: Have to figure out proper hw init values later */
1368
1369 hw->queues = 4;
1370 hw->ampdu_queues = 1;
1371
1372 /* Register rate control */
1373 hw->rate_control_algorithm = "ath9k_rate_control";
1374 error = ath_rate_control_register();
1375 if (error != 0) {
1376 DPRINTF(sc, ATH_DBG_FATAL,
1377 "%s: Unable to register rate control "
1378 "algorithm:%d\n", __func__, error);
1379 ath_rate_control_unregister();
1380 goto bad;
1381 }
1382
1383 error = ieee80211_register_hw(hw);
1384 if (error != 0) {
1385 ath_rate_control_unregister();
1386 goto bad;
1387 }
1388
1389 /* Initialize LED control */
1390 ath_init_leds(sc);
1391
1392 /* initialize tx/rx engine */
1393
1394 error = ath_tx_init(sc, ATH_TXBUF);
1395 if (error != 0)
1396 goto detach;
1397
1398 error = ath_rx_init(sc, ATH_RXBUF);
1399 if (error != 0)
1400 goto detach;
1401
1402 return 0;
1403detach:
1404 ath_detach(sc);
1405bad:
1406 return error;
1407}
1408
1409static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) 1409static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1410{ 1410{
1411 void __iomem *mem; 1411 void __iomem *mem;