diff options
Diffstat (limited to 'drivers/net/wireless/zd1211rw/zd_mac.c')
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_mac.c | 67 |
1 files changed, 52 insertions, 15 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 4d7b98b05030..fe1867b25ff7 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de> | 3 | * Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de> |
4 | * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org> | 4 | * Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org> |
5 | * Copyright (C) 2006-2007 Michael Wu <flamingice@sourmilk.net> | 5 | * Copyright (C) 2006-2007 Michael Wu <flamingice@sourmilk.net> |
6 | * Copyright (c) 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu> | 6 | * Copyright (C) 2007-2008 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
@@ -29,9 +29,23 @@ | |||
29 | #include "zd_def.h" | 29 | #include "zd_def.h" |
30 | #include "zd_chip.h" | 30 | #include "zd_chip.h" |
31 | #include "zd_mac.h" | 31 | #include "zd_mac.h" |
32 | #include "zd_ieee80211.h" | ||
33 | #include "zd_rf.h" | 32 | #include "zd_rf.h" |
34 | 33 | ||
34 | struct zd_reg_alpha2_map { | ||
35 | u32 reg; | ||
36 | char alpha2[2]; | ||
37 | }; | ||
38 | |||
39 | static struct zd_reg_alpha2_map reg_alpha2_map[] = { | ||
40 | { ZD_REGDOMAIN_FCC, "US" }, | ||
41 | { ZD_REGDOMAIN_IC, "CA" }, | ||
42 | { ZD_REGDOMAIN_ETSI, "DE" }, /* Generic ETSI, use most restrictive */ | ||
43 | { ZD_REGDOMAIN_JAPAN, "JP" }, | ||
44 | { ZD_REGDOMAIN_JAPAN_ADD, "JP" }, | ||
45 | { ZD_REGDOMAIN_SPAIN, "ES" }, | ||
46 | { ZD_REGDOMAIN_FRANCE, "FR" }, | ||
47 | }; | ||
48 | |||
35 | /* This table contains the hardware specific values for the modulation rates. */ | 49 | /* This table contains the hardware specific values for the modulation rates. */ |
36 | static const struct ieee80211_rate zd_rates[] = { | 50 | static const struct ieee80211_rate zd_rates[] = { |
37 | { .bitrate = 10, | 51 | { .bitrate = 10, |
@@ -95,6 +109,21 @@ static void housekeeping_init(struct zd_mac *mac); | |||
95 | static void housekeeping_enable(struct zd_mac *mac); | 109 | static void housekeeping_enable(struct zd_mac *mac); |
96 | static void housekeeping_disable(struct zd_mac *mac); | 110 | static void housekeeping_disable(struct zd_mac *mac); |
97 | 111 | ||
112 | static int zd_reg2alpha2(u8 regdomain, char *alpha2) | ||
113 | { | ||
114 | unsigned int i; | ||
115 | struct zd_reg_alpha2_map *reg_map; | ||
116 | for (i = 0; i < ARRAY_SIZE(reg_alpha2_map); i++) { | ||
117 | reg_map = ®_alpha2_map[i]; | ||
118 | if (regdomain == reg_map->reg) { | ||
119 | alpha2[0] = reg_map->alpha2[0]; | ||
120 | alpha2[1] = reg_map->alpha2[1]; | ||
121 | return 0; | ||
122 | } | ||
123 | } | ||
124 | return 1; | ||
125 | } | ||
126 | |||
98 | int zd_mac_preinit_hw(struct ieee80211_hw *hw) | 127 | int zd_mac_preinit_hw(struct ieee80211_hw *hw) |
99 | { | 128 | { |
100 | int r; | 129 | int r; |
@@ -115,6 +144,7 @@ int zd_mac_init_hw(struct ieee80211_hw *hw) | |||
115 | int r; | 144 | int r; |
116 | struct zd_mac *mac = zd_hw_mac(hw); | 145 | struct zd_mac *mac = zd_hw_mac(hw); |
117 | struct zd_chip *chip = &mac->chip; | 146 | struct zd_chip *chip = &mac->chip; |
147 | char alpha2[2]; | ||
118 | u8 default_regdomain; | 148 | u8 default_regdomain; |
119 | 149 | ||
120 | r = zd_chip_enable_int(chip); | 150 | r = zd_chip_enable_int(chip); |
@@ -139,7 +169,9 @@ int zd_mac_init_hw(struct ieee80211_hw *hw) | |||
139 | if (r) | 169 | if (r) |
140 | goto disable_int; | 170 | goto disable_int; |
141 | 171 | ||
142 | zd_geo_init(hw, mac->regdomain); | 172 | r = zd_reg2alpha2(mac->regdomain, alpha2); |
173 | if (!r) | ||
174 | regulatory_hint(hw->wiphy, alpha2, NULL); | ||
143 | 175 | ||
144 | r = 0; | 176 | r = 0; |
145 | disable_int: | 177 | disable_int: |
@@ -579,7 +611,7 @@ static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr, | |||
579 | 611 | ||
580 | q = &zd_hw_mac(hw)->ack_wait_queue; | 612 | q = &zd_hw_mac(hw)->ack_wait_queue; |
581 | spin_lock_irqsave(&q->lock, flags); | 613 | spin_lock_irqsave(&q->lock, flags); |
582 | for (skb = q->next; skb != (struct sk_buff *)q; skb = skb->next) { | 614 | skb_queue_walk(q, skb) { |
583 | struct ieee80211_hdr *tx_hdr; | 615 | struct ieee80211_hdr *tx_hdr; |
584 | 616 | ||
585 | tx_hdr = (struct ieee80211_hdr *)skb->data; | 617 | tx_hdr = (struct ieee80211_hdr *)skb->data; |
@@ -684,15 +716,15 @@ static int zd_op_add_interface(struct ieee80211_hw *hw, | |||
684 | { | 716 | { |
685 | struct zd_mac *mac = zd_hw_mac(hw); | 717 | struct zd_mac *mac = zd_hw_mac(hw); |
686 | 718 | ||
687 | /* using IEEE80211_IF_TYPE_INVALID to indicate no mode selected */ | 719 | /* using NL80211_IFTYPE_UNSPECIFIED to indicate no mode selected */ |
688 | if (mac->type != IEEE80211_IF_TYPE_INVALID) | 720 | if (mac->type != NL80211_IFTYPE_UNSPECIFIED) |
689 | return -EOPNOTSUPP; | 721 | return -EOPNOTSUPP; |
690 | 722 | ||
691 | switch (conf->type) { | 723 | switch (conf->type) { |
692 | case IEEE80211_IF_TYPE_MNTR: | 724 | case NL80211_IFTYPE_MONITOR: |
693 | case IEEE80211_IF_TYPE_MESH_POINT: | 725 | case NL80211_IFTYPE_MESH_POINT: |
694 | case IEEE80211_IF_TYPE_STA: | 726 | case NL80211_IFTYPE_STATION: |
695 | case IEEE80211_IF_TYPE_IBSS: | 727 | case NL80211_IFTYPE_ADHOC: |
696 | mac->type = conf->type; | 728 | mac->type = conf->type; |
697 | break; | 729 | break; |
698 | default: | 730 | default: |
@@ -706,7 +738,7 @@ static void zd_op_remove_interface(struct ieee80211_hw *hw, | |||
706 | struct ieee80211_if_init_conf *conf) | 738 | struct ieee80211_if_init_conf *conf) |
707 | { | 739 | { |
708 | struct zd_mac *mac = zd_hw_mac(hw); | 740 | struct zd_mac *mac = zd_hw_mac(hw); |
709 | mac->type = IEEE80211_IF_TYPE_INVALID; | 741 | mac->type = NL80211_IFTYPE_UNSPECIFIED; |
710 | zd_set_beacon_interval(&mac->chip, 0); | 742 | zd_set_beacon_interval(&mac->chip, 0); |
711 | zd_write_mac_addr(&mac->chip, NULL); | 743 | zd_write_mac_addr(&mac->chip, NULL); |
712 | } | 744 | } |
@@ -725,8 +757,8 @@ static int zd_op_config_interface(struct ieee80211_hw *hw, | |||
725 | int associated; | 757 | int associated; |
726 | int r; | 758 | int r; |
727 | 759 | ||
728 | if (mac->type == IEEE80211_IF_TYPE_MESH_POINT || | 760 | if (mac->type == NL80211_IFTYPE_MESH_POINT || |
729 | mac->type == IEEE80211_IF_TYPE_IBSS) { | 761 | mac->type == NL80211_IFTYPE_ADHOC) { |
730 | associated = true; | 762 | associated = true; |
731 | if (conf->changed & IEEE80211_IFCC_BEACON) { | 763 | if (conf->changed & IEEE80211_IFCC_BEACON) { |
732 | struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); | 764 | struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); |
@@ -753,7 +785,7 @@ static int zd_op_config_interface(struct ieee80211_hw *hw, | |||
753 | return 0; | 785 | return 0; |
754 | } | 786 | } |
755 | 787 | ||
756 | void zd_process_intr(struct work_struct *work) | 788 | static void zd_process_intr(struct work_struct *work) |
757 | { | 789 | { |
758 | u16 int_status; | 790 | u16 int_status; |
759 | struct zd_mac *mac = container_of(work, struct zd_mac, process_intr); | 791 | struct zd_mac *mac = container_of(work, struct zd_mac, process_intr); |
@@ -923,7 +955,7 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) | |||
923 | spin_lock_init(&mac->lock); | 955 | spin_lock_init(&mac->lock); |
924 | mac->hw = hw; | 956 | mac->hw = hw; |
925 | 957 | ||
926 | mac->type = IEEE80211_IF_TYPE_INVALID; | 958 | mac->type = NL80211_IFTYPE_UNSPECIFIED; |
927 | 959 | ||
928 | memcpy(mac->channels, zd_channels, sizeof(zd_channels)); | 960 | memcpy(mac->channels, zd_channels, sizeof(zd_channels)); |
929 | memcpy(mac->rates, zd_rates, sizeof(zd_rates)); | 961 | memcpy(mac->rates, zd_rates, sizeof(zd_rates)); |
@@ -937,6 +969,11 @@ struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) | |||
937 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | 969 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | |
938 | IEEE80211_HW_SIGNAL_DB; | 970 | IEEE80211_HW_SIGNAL_DB; |
939 | 971 | ||
972 | hw->wiphy->interface_modes = | ||
973 | BIT(NL80211_IFTYPE_MESH_POINT) | | ||
974 | BIT(NL80211_IFTYPE_STATION) | | ||
975 | BIT(NL80211_IFTYPE_ADHOC); | ||
976 | |||
940 | hw->max_signal = 100; | 977 | hw->max_signal = 100; |
941 | hw->queues = 1; | 978 | hw->queues = 1; |
942 | hw->extra_tx_headroom = sizeof(struct zd_ctrlset); | 979 | hw->extra_tx_headroom = sizeof(struct zd_ctrlset); |