diff options
Diffstat (limited to 'drivers/net/wireless/zd1211rw/zd_mac.c')
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_mac.c | 59 |
1 files changed, 40 insertions, 19 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 6753d240c168..f6c487aa8246 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -86,38 +86,46 @@ out: | |||
86 | return r; | 86 | return r; |
87 | } | 87 | } |
88 | 88 | ||
89 | int zd_mac_init_hw(struct zd_mac *mac, u8 device_type) | 89 | int zd_mac_preinit_hw(struct zd_mac *mac) |
90 | { | 90 | { |
91 | int r; | 91 | int r; |
92 | struct zd_chip *chip = &mac->chip; | ||
93 | u8 addr[ETH_ALEN]; | 92 | u8 addr[ETH_ALEN]; |
93 | |||
94 | r = zd_chip_read_mac_addr_fw(&mac->chip, addr); | ||
95 | if (r) | ||
96 | return r; | ||
97 | |||
98 | memcpy(mac->netdev->dev_addr, addr, ETH_ALEN); | ||
99 | return 0; | ||
100 | } | ||
101 | |||
102 | int zd_mac_init_hw(struct zd_mac *mac) | ||
103 | { | ||
104 | int r; | ||
105 | struct zd_chip *chip = &mac->chip; | ||
94 | u8 default_regdomain; | 106 | u8 default_regdomain; |
95 | 107 | ||
96 | r = zd_chip_enable_int(chip); | 108 | r = zd_chip_enable_int(chip); |
97 | if (r) | 109 | if (r) |
98 | goto out; | 110 | goto out; |
99 | r = zd_chip_init_hw(chip, device_type); | 111 | r = zd_chip_init_hw(chip); |
100 | if (r) | 112 | if (r) |
101 | goto disable_int; | 113 | goto disable_int; |
102 | 114 | ||
103 | zd_get_e2p_mac_addr(chip, addr); | ||
104 | r = zd_write_mac_addr(chip, addr); | ||
105 | if (r) | ||
106 | goto disable_int; | ||
107 | ZD_ASSERT(!irqs_disabled()); | 115 | ZD_ASSERT(!irqs_disabled()); |
108 | spin_lock_irq(&mac->lock); | ||
109 | memcpy(mac->netdev->dev_addr, addr, ETH_ALEN); | ||
110 | spin_unlock_irq(&mac->lock); | ||
111 | 116 | ||
112 | r = zd_read_regdomain(chip, &default_regdomain); | 117 | r = zd_read_regdomain(chip, &default_regdomain); |
113 | if (r) | 118 | if (r) |
114 | goto disable_int; | 119 | goto disable_int; |
115 | if (!zd_regdomain_supported(default_regdomain)) { | 120 | if (!zd_regdomain_supported(default_regdomain)) { |
116 | dev_dbg_f(zd_mac_dev(mac), | 121 | /* The vendor driver overrides the regulatory domain and |
117 | "Regulatory Domain %#04x is not supported.\n", | 122 | * allowed channel registers and unconditionally restricts |
118 | default_regdomain); | 123 | * available channels to 1-11 everywhere. Match their |
119 | r = -EINVAL; | 124 | * questionable behaviour only for regdomains which we don't |
120 | goto disable_int; | 125 | * recognise. */ |
126 | dev_warn(zd_mac_dev(mac), "Unrecognised regulatory domain: " | ||
127 | "%#04x. Defaulting to FCC.\n", default_regdomain); | ||
128 | default_regdomain = ZD_REGDOMAIN_FCC; | ||
121 | } | 129 | } |
122 | spin_lock_irq(&mac->lock); | 130 | spin_lock_irq(&mac->lock); |
123 | mac->regdomain = mac->default_regdomain = default_regdomain; | 131 | mac->regdomain = mac->default_regdomain = default_regdomain; |
@@ -164,14 +172,25 @@ int zd_mac_open(struct net_device *netdev) | |||
164 | { | 172 | { |
165 | struct zd_mac *mac = zd_netdev_mac(netdev); | 173 | struct zd_mac *mac = zd_netdev_mac(netdev); |
166 | struct zd_chip *chip = &mac->chip; | 174 | struct zd_chip *chip = &mac->chip; |
175 | struct zd_usb *usb = &chip->usb; | ||
167 | int r; | 176 | int r; |
168 | 177 | ||
178 | if (!usb->initialized) { | ||
179 | r = zd_usb_init_hw(usb); | ||
180 | if (r) | ||
181 | goto out; | ||
182 | } | ||
183 | |||
169 | tasklet_enable(&mac->rx_tasklet); | 184 | tasklet_enable(&mac->rx_tasklet); |
170 | 185 | ||
171 | r = zd_chip_enable_int(chip); | 186 | r = zd_chip_enable_int(chip); |
172 | if (r < 0) | 187 | if (r < 0) |
173 | goto out; | 188 | goto out; |
174 | 189 | ||
190 | r = zd_write_mac_addr(chip, netdev->dev_addr); | ||
191 | if (r) | ||
192 | goto disable_int; | ||
193 | |||
175 | r = zd_chip_set_basic_rates(chip, CR_RATES_80211B | CR_RATES_80211G); | 194 | r = zd_chip_set_basic_rates(chip, CR_RATES_80211B | CR_RATES_80211G); |
176 | if (r < 0) | 195 | if (r < 0) |
177 | goto disable_int; | 196 | goto disable_int; |
@@ -251,9 +270,11 @@ int zd_mac_set_mac_address(struct net_device *netdev, void *p) | |||
251 | dev_dbg_f(zd_mac_dev(mac), | 270 | dev_dbg_f(zd_mac_dev(mac), |
252 | "Setting MAC to " MAC_FMT "\n", MAC_ARG(addr->sa_data)); | 271 | "Setting MAC to " MAC_FMT "\n", MAC_ARG(addr->sa_data)); |
253 | 272 | ||
254 | r = zd_write_mac_addr(chip, addr->sa_data); | 273 | if (netdev->flags & IFF_UP) { |
255 | if (r) | 274 | r = zd_write_mac_addr(chip, addr->sa_data); |
256 | return r; | 275 | if (r) |
276 | return r; | ||
277 | } | ||
257 | 278 | ||
258 | spin_lock_irqsave(&mac->lock, flags); | 279 | spin_lock_irqsave(&mac->lock, flags); |
259 | memcpy(netdev->dev_addr, addr->sa_data, ETH_ALEN); | 280 | memcpy(netdev->dev_addr, addr->sa_data, ETH_ALEN); |
@@ -855,7 +876,7 @@ static int fill_ctrlset(struct zd_mac *mac, | |||
855 | /* ZD1211B: Computing the length difference this way, gives us | 876 | /* ZD1211B: Computing the length difference this way, gives us |
856 | * flexibility to compute the packet length. | 877 | * flexibility to compute the packet length. |
857 | */ | 878 | */ |
858 | cs->packet_length = cpu_to_le16(mac->chip.is_zd1211b ? | 879 | cs->packet_length = cpu_to_le16(zd_chip_is_zd1211b(&mac->chip) ? |
859 | packet_length - frag_len : packet_length); | 880 | packet_length - frag_len : packet_length); |
860 | 881 | ||
861 | /* | 882 | /* |