aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/zd1211rw/zd_mac.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/zd1211rw/zd_mac.c')
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c75
1 files changed, 73 insertions, 2 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index f90f03f676de..69c45ca99051 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -475,6 +475,46 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs,
475 /* FIXME: Management frame? */ 475 /* FIXME: Management frame? */
476} 476}
477 477
478void zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon)
479{
480 struct zd_mac *mac = zd_hw_mac(hw);
481 u32 tmp, j = 0;
482 /* 4 more bytes for tail CRC */
483 u32 full_len = beacon->len + 4;
484 zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 0);
485 zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp);
486 while (tmp & 0x2) {
487 zd_ioread32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, &tmp);
488 if ((++j % 100) == 0) {
489 printk(KERN_ERR "CR_BCN_FIFO_SEMAPHORE not ready\n");
490 if (j >= 500) {
491 printk(KERN_ERR "Giving up beacon config.\n");
492 return;
493 }
494 }
495 msleep(1);
496 }
497
498 zd_iowrite32(&mac->chip, CR_BCN_FIFO, full_len - 1);
499 if (zd_chip_is_zd1211b(&mac->chip))
500 zd_iowrite32(&mac->chip, CR_BCN_LENGTH, full_len - 1);
501
502 for (j = 0 ; j < beacon->len; j++)
503 zd_iowrite32(&mac->chip, CR_BCN_FIFO,
504 *((u8 *)(beacon->data + j)));
505
506 for (j = 0; j < 4; j++)
507 zd_iowrite32(&mac->chip, CR_BCN_FIFO, 0x0);
508
509 zd_iowrite32(&mac->chip, CR_BCN_FIFO_SEMAPHORE, 1);
510 /* 802.11b/g 2.4G CCK 1Mb
511 * 802.11a, not yet implemented, uses different values (see GPL vendor
512 * driver)
513 */
514 zd_iowrite32(&mac->chip, CR_BCN_PLCP_CFG, 0x00000400 |
515 (full_len << 19));
516}
517
478static int fill_ctrlset(struct zd_mac *mac, 518static int fill_ctrlset(struct zd_mac *mac,
479 struct sk_buff *skb, 519 struct sk_buff *skb,
480 struct ieee80211_tx_control *control) 520 struct ieee80211_tx_control *control)
@@ -709,6 +749,7 @@ static int zd_op_add_interface(struct ieee80211_hw *hw,
709 749
710 switch (conf->type) { 750 switch (conf->type) {
711 case IEEE80211_IF_TYPE_MNTR: 751 case IEEE80211_IF_TYPE_MNTR:
752 case IEEE80211_IF_TYPE_MESH_POINT:
712 case IEEE80211_IF_TYPE_STA: 753 case IEEE80211_IF_TYPE_STA:
713 mac->type = conf->type; 754 mac->type = conf->type;
714 break; 755 break;
@@ -738,15 +779,43 @@ static int zd_op_config_interface(struct ieee80211_hw *hw,
738 struct ieee80211_if_conf *conf) 779 struct ieee80211_if_conf *conf)
739{ 780{
740 struct zd_mac *mac = zd_hw_mac(hw); 781 struct zd_mac *mac = zd_hw_mac(hw);
782 int associated;
783
784 if (mac->type == IEEE80211_IF_TYPE_MESH_POINT) {
785 associated = true;
786 if (conf->beacon) {
787 zd_mac_config_beacon(hw, conf->beacon);
788 kfree_skb(conf->beacon);
789 zd_set_beacon_interval(&mac->chip, BCN_MODE_IBSS |
790 hw->conf.beacon_int);
791 }
792 } else
793 associated = is_valid_ether_addr(conf->bssid);
741 794
742 spin_lock_irq(&mac->lock); 795 spin_lock_irq(&mac->lock);
743 mac->associated = is_valid_ether_addr(conf->bssid); 796 mac->associated = associated;
744 spin_unlock_irq(&mac->lock); 797 spin_unlock_irq(&mac->lock);
745 798
746 /* TODO: do hardware bssid filtering */ 799 /* TODO: do hardware bssid filtering */
747 return 0; 800 return 0;
748} 801}
749 802
803void zd_process_intr(struct work_struct *work)
804{
805 u16 int_status;
806 struct zd_mac *mac = container_of(work, struct zd_mac, process_intr);
807
808 int_status = le16_to_cpu(*(u16 *)(mac->intr_buffer+4));
809 if (int_status & INT_CFG_NEXT_BCN) {
810 if (net_ratelimit())
811 dev_dbg_f(zd_mac_dev(mac), "INT_CFG_NEXT_BCN\n");
812 } else
813 dev_dbg_f(zd_mac_dev(mac), "Unsupported interrupt\n");
814
815 zd_chip_enable_hwint(&mac->chip);
816}
817
818
750static void set_multicast_hash_handler(struct work_struct *work) 819static void set_multicast_hash_handler(struct work_struct *work)
751{ 820{
752 struct zd_mac *mac = 821 struct zd_mac *mac =
@@ -912,7 +981,8 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf)
912 981
913 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &mac->band; 982 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &mac->band;
914 983
915 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS; 984 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
985 IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE;
916 hw->max_rssi = 100; 986 hw->max_rssi = 100;
917 hw->max_signal = 100; 987 hw->max_signal = 100;
918 988
@@ -926,6 +996,7 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf)
926 INIT_WORK(&mac->set_multicast_hash_work, set_multicast_hash_handler); 996 INIT_WORK(&mac->set_multicast_hash_work, set_multicast_hash_handler);
927 INIT_WORK(&mac->set_rts_cts_work, set_rts_cts_work); 997 INIT_WORK(&mac->set_rts_cts_work, set_rts_cts_work);
928 INIT_WORK(&mac->set_rx_filter_work, set_rx_filter_handler); 998 INIT_WORK(&mac->set_rx_filter_work, set_rx_filter_handler);
999 INIT_WORK(&mac->process_intr, zd_process_intr);
929 1000
930 SET_IEEE80211_DEV(hw, &intf->dev); 1001 SET_IEEE80211_DEV(hw, &intf->dev);
931 return hw; 1002 return hw;