diff options
author | John W. Linville <linville@tuxdriver.com> | 2011-02-22 15:10:22 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-02-22 15:10:22 -0500 |
commit | 5db5e44cdcdc5ee9cc821bd4d63445af0bb34bce (patch) | |
tree | b5e5787a6d5c15e589d275c7434ebbf341257234 | |
parent | db62983a1e4b2af9e79c97af768f0c8b80bd93f0 (diff) | |
parent | 320d6c1b56de5f461c6062625b9664095f90ee95 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
153 files changed, 22696 insertions, 6364 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 057602d5555d..d6f5255ca547 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -35,6 +35,17 @@ Who: Luis R. Rodriguez <lrodriguez@atheros.com> | |||
35 | 35 | ||
36 | --------------------------- | 36 | --------------------------- |
37 | 37 | ||
38 | What: AR9170USB | ||
39 | When: 2.6.40 | ||
40 | |||
41 | Why: This driver is deprecated and the firmware is no longer | ||
42 | maintained. The replacement driver "carl9170" has been | ||
43 | around for a while, so the devices are still supported. | ||
44 | |||
45 | Who: Christian Lamparter <chunkeey@googlemail.com> | ||
46 | |||
47 | --------------------------- | ||
48 | |||
38 | What: IRQF_SAMPLE_RANDOM | 49 | What: IRQF_SAMPLE_RANDOM |
39 | Check: IRQF_SAMPLE_RANDOM | 50 | Check: IRQF_SAMPLE_RANDOM |
40 | When: July 2009 | 51 | When: July 2009 |
diff --git a/MAINTAINERS b/MAINTAINERS index 1eacf29f0431..0d83e5898233 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -1205,7 +1205,7 @@ ATHEROS AR9170 WIRELESS DRIVER | |||
1205 | M: Christian Lamparter <chunkeey@web.de> | 1205 | M: Christian Lamparter <chunkeey@web.de> |
1206 | L: linux-wireless@vger.kernel.org | 1206 | L: linux-wireless@vger.kernel.org |
1207 | W: http://wireless.kernel.org/en/users/Drivers/ar9170 | 1207 | W: http://wireless.kernel.org/en/users/Drivers/ar9170 |
1208 | S: Maintained | 1208 | S: Obsolete |
1209 | F: drivers/net/wireless/ath/ar9170/ | 1209 | F: drivers/net/wireless/ath/ar9170/ |
1210 | 1210 | ||
1211 | CARL9170 LINUX COMMUNITY WIRELESS DRIVER | 1211 | CARL9170 LINUX COMMUNITY WIRELESS DRIVER |
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 333c21289d97..5577ed656e2f 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c | |||
@@ -31,6 +31,30 @@ | |||
31 | 31 | ||
32 | #define VERSION "1.0" | 32 | #define VERSION "1.0" |
33 | 33 | ||
34 | #define ATH3K_DNLOAD 0x01 | ||
35 | #define ATH3K_GETSTATE 0x05 | ||
36 | #define ATH3K_SET_NORMAL_MODE 0x07 | ||
37 | #define ATH3K_GETVERSION 0x09 | ||
38 | #define USB_REG_SWITCH_VID_PID 0x0a | ||
39 | |||
40 | #define ATH3K_MODE_MASK 0x3F | ||
41 | #define ATH3K_NORMAL_MODE 0x0E | ||
42 | |||
43 | #define ATH3K_PATCH_UPDATE 0x80 | ||
44 | #define ATH3K_SYSCFG_UPDATE 0x40 | ||
45 | |||
46 | #define ATH3K_XTAL_FREQ_26M 0x00 | ||
47 | #define ATH3K_XTAL_FREQ_40M 0x01 | ||
48 | #define ATH3K_XTAL_FREQ_19P2 0x02 | ||
49 | #define ATH3K_NAME_LEN 0xFF | ||
50 | |||
51 | struct ath3k_version { | ||
52 | unsigned int rom_version; | ||
53 | unsigned int build_version; | ||
54 | unsigned int ram_version; | ||
55 | unsigned char ref_clock; | ||
56 | unsigned char reserved[0x07]; | ||
57 | }; | ||
34 | 58 | ||
35 | static struct usb_device_id ath3k_table[] = { | 59 | static struct usb_device_id ath3k_table[] = { |
36 | /* Atheros AR3011 */ | 60 | /* Atheros AR3011 */ |
@@ -41,13 +65,32 @@ static struct usb_device_id ath3k_table[] = { | |||
41 | 65 | ||
42 | /* Atheros AR9285 Malbec with sflash firmware */ | 66 | /* Atheros AR9285 Malbec with sflash firmware */ |
43 | { USB_DEVICE(0x03F0, 0x311D) }, | 67 | { USB_DEVICE(0x03F0, 0x311D) }, |
68 | |||
69 | /* Atheros AR3012 with sflash firmware*/ | ||
70 | { USB_DEVICE(0x0CF3, 0x3004) }, | ||
71 | |||
72 | /* Atheros AR5BBU12 with sflash firmware */ | ||
73 | { USB_DEVICE(0x0489, 0xE02C) }, | ||
74 | |||
44 | { } /* Terminating entry */ | 75 | { } /* Terminating entry */ |
45 | }; | 76 | }; |
46 | 77 | ||
47 | MODULE_DEVICE_TABLE(usb, ath3k_table); | 78 | MODULE_DEVICE_TABLE(usb, ath3k_table); |
48 | 79 | ||
80 | #define BTUSB_ATH3012 0x80 | ||
81 | /* This table is to load patch and sysconfig files | ||
82 | * for AR3012 */ | ||
83 | static struct usb_device_id ath3k_blist_tbl[] = { | ||
84 | |||
85 | /* Atheros AR3012 with sflash firmware*/ | ||
86 | { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, | ||
87 | |||
88 | { } /* Terminating entry */ | ||
89 | }; | ||
90 | |||
49 | #define USB_REQ_DFU_DNLOAD 1 | 91 | #define USB_REQ_DFU_DNLOAD 1 |
50 | #define BULK_SIZE 4096 | 92 | #define BULK_SIZE 4096 |
93 | #define FW_HDR_SIZE 20 | ||
51 | 94 | ||
52 | static int ath3k_load_firmware(struct usb_device *udev, | 95 | static int ath3k_load_firmware(struct usb_device *udev, |
53 | const struct firmware *firmware) | 96 | const struct firmware *firmware) |
@@ -103,28 +146,265 @@ error: | |||
103 | return err; | 146 | return err; |
104 | } | 147 | } |
105 | 148 | ||
149 | static int ath3k_get_state(struct usb_device *udev, unsigned char *state) | ||
150 | { | ||
151 | int pipe = 0; | ||
152 | |||
153 | pipe = usb_rcvctrlpipe(udev, 0); | ||
154 | return usb_control_msg(udev, pipe, ATH3K_GETSTATE, | ||
155 | USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, | ||
156 | state, 0x01, USB_CTRL_SET_TIMEOUT); | ||
157 | } | ||
158 | |||
159 | static int ath3k_get_version(struct usb_device *udev, | ||
160 | struct ath3k_version *version) | ||
161 | { | ||
162 | int pipe = 0; | ||
163 | |||
164 | pipe = usb_rcvctrlpipe(udev, 0); | ||
165 | return usb_control_msg(udev, pipe, ATH3K_GETVERSION, | ||
166 | USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, version, | ||
167 | sizeof(struct ath3k_version), | ||
168 | USB_CTRL_SET_TIMEOUT); | ||
169 | } | ||
170 | |||
171 | static int ath3k_load_fwfile(struct usb_device *udev, | ||
172 | const struct firmware *firmware) | ||
173 | { | ||
174 | u8 *send_buf; | ||
175 | int err, pipe, len, size, count, sent = 0; | ||
176 | int ret; | ||
177 | |||
178 | count = firmware->size; | ||
179 | |||
180 | send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC); | ||
181 | if (!send_buf) { | ||
182 | BT_ERR("Can't allocate memory chunk for firmware"); | ||
183 | return -ENOMEM; | ||
184 | } | ||
185 | |||
186 | size = min_t(uint, count, FW_HDR_SIZE); | ||
187 | memcpy(send_buf, firmware->data, size); | ||
188 | |||
189 | pipe = usb_sndctrlpipe(udev, 0); | ||
190 | ret = usb_control_msg(udev, pipe, ATH3K_DNLOAD, | ||
191 | USB_TYPE_VENDOR, 0, 0, send_buf, | ||
192 | size, USB_CTRL_SET_TIMEOUT); | ||
193 | if (ret < 0) { | ||
194 | BT_ERR("Can't change to loading configuration err"); | ||
195 | kfree(send_buf); | ||
196 | return ret; | ||
197 | } | ||
198 | |||
199 | sent += size; | ||
200 | count -= size; | ||
201 | |||
202 | while (count) { | ||
203 | size = min_t(uint, count, BULK_SIZE); | ||
204 | pipe = usb_sndbulkpipe(udev, 0x02); | ||
205 | |||
206 | memcpy(send_buf, firmware->data + sent, size); | ||
207 | |||
208 | err = usb_bulk_msg(udev, pipe, send_buf, size, | ||
209 | &len, 3000); | ||
210 | if (err || (len != size)) { | ||
211 | BT_ERR("Error in firmware loading err = %d," | ||
212 | "len = %d, size = %d", err, len, size); | ||
213 | kfree(send_buf); | ||
214 | return err; | ||
215 | } | ||
216 | sent += size; | ||
217 | count -= size; | ||
218 | } | ||
219 | |||
220 | kfree(send_buf); | ||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | static int ath3k_switch_pid(struct usb_device *udev) | ||
225 | { | ||
226 | int pipe = 0; | ||
227 | |||
228 | pipe = usb_sndctrlpipe(udev, 0); | ||
229 | return usb_control_msg(udev, pipe, USB_REG_SWITCH_VID_PID, | ||
230 | USB_TYPE_VENDOR, 0, 0, | ||
231 | NULL, 0, USB_CTRL_SET_TIMEOUT); | ||
232 | } | ||
233 | |||
234 | static int ath3k_set_normal_mode(struct usb_device *udev) | ||
235 | { | ||
236 | unsigned char fw_state; | ||
237 | int pipe = 0, ret; | ||
238 | |||
239 | ret = ath3k_get_state(udev, &fw_state); | ||
240 | if (ret < 0) { | ||
241 | BT_ERR("Can't get state to change to normal mode err"); | ||
242 | return ret; | ||
243 | } | ||
244 | |||
245 | if ((fw_state & ATH3K_MODE_MASK) == ATH3K_NORMAL_MODE) { | ||
246 | BT_DBG("firmware was already in normal mode"); | ||
247 | return 0; | ||
248 | } | ||
249 | |||
250 | pipe = usb_sndctrlpipe(udev, 0); | ||
251 | return usb_control_msg(udev, pipe, ATH3K_SET_NORMAL_MODE, | ||
252 | USB_TYPE_VENDOR, 0, 0, | ||
253 | NULL, 0, USB_CTRL_SET_TIMEOUT); | ||
254 | } | ||
255 | |||
256 | static int ath3k_load_patch(struct usb_device *udev) | ||
257 | { | ||
258 | unsigned char fw_state; | ||
259 | char filename[ATH3K_NAME_LEN] = {0}; | ||
260 | const struct firmware *firmware; | ||
261 | struct ath3k_version fw_version, pt_version; | ||
262 | int ret; | ||
263 | |||
264 | ret = ath3k_get_state(udev, &fw_state); | ||
265 | if (ret < 0) { | ||
266 | BT_ERR("Can't get state to change to load ram patch err"); | ||
267 | return ret; | ||
268 | } | ||
269 | |||
270 | if (fw_state & ATH3K_PATCH_UPDATE) { | ||
271 | BT_DBG("Patch was already downloaded"); | ||
272 | return 0; | ||
273 | } | ||
274 | |||
275 | ret = ath3k_get_version(udev, &fw_version); | ||
276 | if (ret < 0) { | ||
277 | BT_ERR("Can't get version to change to load ram patch err"); | ||
278 | return ret; | ||
279 | } | ||
280 | |||
281 | snprintf(filename, ATH3K_NAME_LEN, "ar3k/AthrBT_0x%08x.dfu", | ||
282 | fw_version.rom_version); | ||
283 | |||
284 | ret = request_firmware(&firmware, filename, &udev->dev); | ||
285 | if (ret < 0) { | ||
286 | BT_ERR("Patch file not found %s", filename); | ||
287 | return ret; | ||
288 | } | ||
289 | |||
290 | pt_version.rom_version = *(int *)(firmware->data + firmware->size - 8); | ||
291 | pt_version.build_version = *(int *) | ||
292 | (firmware->data + firmware->size - 4); | ||
293 | |||
294 | if ((pt_version.rom_version != fw_version.rom_version) || | ||
295 | (pt_version.build_version <= fw_version.build_version)) { | ||
296 | BT_ERR("Patch file version did not match with firmware"); | ||
297 | release_firmware(firmware); | ||
298 | return -EINVAL; | ||
299 | } | ||
300 | |||
301 | ret = ath3k_load_fwfile(udev, firmware); | ||
302 | release_firmware(firmware); | ||
303 | |||
304 | return ret; | ||
305 | } | ||
306 | |||
307 | static int ath3k_load_syscfg(struct usb_device *udev) | ||
308 | { | ||
309 | unsigned char fw_state; | ||
310 | char filename[ATH3K_NAME_LEN] = {0}; | ||
311 | const struct firmware *firmware; | ||
312 | struct ath3k_version fw_version; | ||
313 | int clk_value, ret; | ||
314 | |||
315 | ret = ath3k_get_state(udev, &fw_state); | ||
316 | if (ret < 0) { | ||
317 | BT_ERR("Can't get state to change to load configration err"); | ||
318 | return -EBUSY; | ||
319 | } | ||
320 | |||
321 | ret = ath3k_get_version(udev, &fw_version); | ||
322 | if (ret < 0) { | ||
323 | BT_ERR("Can't get version to change to load ram patch err"); | ||
324 | return ret; | ||
325 | } | ||
326 | |||
327 | switch (fw_version.ref_clock) { | ||
328 | |||
329 | case ATH3K_XTAL_FREQ_26M: | ||
330 | clk_value = 26; | ||
331 | break; | ||
332 | case ATH3K_XTAL_FREQ_40M: | ||
333 | clk_value = 40; | ||
334 | break; | ||
335 | case ATH3K_XTAL_FREQ_19P2: | ||
336 | clk_value = 19; | ||
337 | break; | ||
338 | default: | ||
339 | clk_value = 0; | ||
340 | break; | ||
341 | } | ||
342 | |||
343 | snprintf(filename, ATH3K_NAME_LEN, "ar3k/ramps_0x%08x_%d%s", | ||
344 | fw_version.rom_version, clk_value, ".dfu"); | ||
345 | |||
346 | ret = request_firmware(&firmware, filename, &udev->dev); | ||
347 | if (ret < 0) { | ||
348 | BT_ERR("Configuration file not found %s", filename); | ||
349 | return ret; | ||
350 | } | ||
351 | |||
352 | ret = ath3k_load_fwfile(udev, firmware); | ||
353 | release_firmware(firmware); | ||
354 | |||
355 | return ret; | ||
356 | } | ||
357 | |||
106 | static int ath3k_probe(struct usb_interface *intf, | 358 | static int ath3k_probe(struct usb_interface *intf, |
107 | const struct usb_device_id *id) | 359 | const struct usb_device_id *id) |
108 | { | 360 | { |
109 | const struct firmware *firmware; | 361 | const struct firmware *firmware; |
110 | struct usb_device *udev = interface_to_usbdev(intf); | 362 | struct usb_device *udev = interface_to_usbdev(intf); |
363 | int ret; | ||
111 | 364 | ||
112 | BT_DBG("intf %p id %p", intf, id); | 365 | BT_DBG("intf %p id %p", intf, id); |
113 | 366 | ||
114 | if (intf->cur_altsetting->desc.bInterfaceNumber != 0) | 367 | if (intf->cur_altsetting->desc.bInterfaceNumber != 0) |
115 | return -ENODEV; | 368 | return -ENODEV; |
116 | 369 | ||
117 | if (request_firmware(&firmware, "ath3k-1.fw", &udev->dev) < 0) { | 370 | /* match device ID in ath3k blacklist table */ |
118 | return -EIO; | 371 | if (!id->driver_info) { |
372 | const struct usb_device_id *match; | ||
373 | match = usb_match_id(intf, ath3k_blist_tbl); | ||
374 | if (match) | ||
375 | id = match; | ||
119 | } | 376 | } |
120 | 377 | ||
121 | if (ath3k_load_firmware(udev, firmware)) { | 378 | /* load patch and sysconfig files for AR3012 */ |
122 | release_firmware(firmware); | 379 | if (id->driver_info & BTUSB_ATH3012) { |
380 | ret = ath3k_load_patch(udev); | ||
381 | if (ret < 0) { | ||
382 | BT_ERR("Loading patch file failed"); | ||
383 | return ret; | ||
384 | } | ||
385 | ret = ath3k_load_syscfg(udev); | ||
386 | if (ret < 0) { | ||
387 | BT_ERR("Loading sysconfig file failed"); | ||
388 | return ret; | ||
389 | } | ||
390 | ret = ath3k_set_normal_mode(udev); | ||
391 | if (ret < 0) { | ||
392 | BT_ERR("Set normal mode failed"); | ||
393 | return ret; | ||
394 | } | ||
395 | ath3k_switch_pid(udev); | ||
396 | return 0; | ||
397 | } | ||
398 | |||
399 | if (request_firmware(&firmware, "ath3k-1.fw", &udev->dev) < 0) { | ||
400 | BT_ERR("Error loading firmware"); | ||
123 | return -EIO; | 401 | return -EIO; |
124 | } | 402 | } |
403 | |||
404 | ret = ath3k_load_firmware(udev, firmware); | ||
125 | release_firmware(firmware); | 405 | release_firmware(firmware); |
126 | 406 | ||
127 | return 0; | 407 | return ret; |
128 | } | 408 | } |
129 | 409 | ||
130 | static void ath3k_disconnect(struct usb_interface *intf) | 410 | static void ath3k_disconnect(struct usb_interface *intf) |
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 4cefa91e6c34..411ae9c9b384 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -105,6 +105,12 @@ static struct usb_device_id blacklist_table[] = { | |||
105 | /* Atheros AR9285 Malbec with sflash firmware */ | 105 | /* Atheros AR9285 Malbec with sflash firmware */ |
106 | { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, | 106 | { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, |
107 | 107 | ||
108 | /* Atheros 3012 with sflash firmware */ | ||
109 | { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_IGNORE }, | ||
110 | |||
111 | /* Atheros AR5BBU12 with sflash firmware */ | ||
112 | { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, | ||
113 | |||
108 | /* Broadcom BCM2035 */ | 114 | /* Broadcom BCM2035 */ |
109 | { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU }, | 115 | { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU }, |
110 | { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU }, | 116 | { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU }, |
@@ -711,15 +717,11 @@ static int btusb_send_frame(struct sk_buff *skb) | |||
711 | pipe = usb_sndisocpipe(data->udev, | 717 | pipe = usb_sndisocpipe(data->udev, |
712 | data->isoc_tx_ep->bEndpointAddress); | 718 | data->isoc_tx_ep->bEndpointAddress); |
713 | 719 | ||
714 | urb->dev = data->udev; | 720 | usb_fill_int_urb(urb, data->udev, pipe, |
715 | urb->pipe = pipe; | 721 | skb->data, skb->len, btusb_isoc_tx_complete, |
716 | urb->context = skb; | 722 | skb, data->isoc_tx_ep->bInterval); |
717 | urb->complete = btusb_isoc_tx_complete; | ||
718 | urb->interval = data->isoc_tx_ep->bInterval; | ||
719 | 723 | ||
720 | urb->transfer_flags = URB_ISO_ASAP; | 724 | urb->transfer_flags = URB_ISO_ASAP; |
721 | urb->transfer_buffer = skb->data; | ||
722 | urb->transfer_buffer_length = skb->len; | ||
723 | 725 | ||
724 | __fill_isoc_descriptor(urb, skb->len, | 726 | __fill_isoc_descriptor(urb, skb->len, |
725 | le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize)); | 727 | le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize)); |
@@ -829,7 +831,7 @@ static void btusb_work(struct work_struct *work) | |||
829 | 831 | ||
830 | if (hdev->conn_hash.sco_num > 0) { | 832 | if (hdev->conn_hash.sco_num > 0) { |
831 | if (!test_bit(BTUSB_DID_ISO_RESUME, &data->flags)) { | 833 | if (!test_bit(BTUSB_DID_ISO_RESUME, &data->flags)) { |
832 | err = usb_autopm_get_interface(data->isoc); | 834 | err = usb_autopm_get_interface(data->isoc ? data->isoc : data->intf); |
833 | if (err < 0) { | 835 | if (err < 0) { |
834 | clear_bit(BTUSB_ISOC_RUNNING, &data->flags); | 836 | clear_bit(BTUSB_ISOC_RUNNING, &data->flags); |
835 | usb_kill_anchored_urbs(&data->isoc_anchor); | 837 | usb_kill_anchored_urbs(&data->isoc_anchor); |
@@ -858,7 +860,7 @@ static void btusb_work(struct work_struct *work) | |||
858 | 860 | ||
859 | __set_isoc_interface(hdev, 0); | 861 | __set_isoc_interface(hdev, 0); |
860 | if (test_and_clear_bit(BTUSB_DID_ISO_RESUME, &data->flags)) | 862 | if (test_and_clear_bit(BTUSB_DID_ISO_RESUME, &data->flags)) |
861 | usb_autopm_put_interface(data->isoc); | 863 | usb_autopm_put_interface(data->isoc ? data->isoc : data->intf); |
862 | } | 864 | } |
863 | } | 865 | } |
864 | 866 | ||
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 3c6cabcb7d84..48ad2a7ab080 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c | |||
@@ -398,6 +398,7 @@ static int hci_uart_register_dev(struct hci_uart *hu) | |||
398 | hdev->flush = hci_uart_flush; | 398 | hdev->flush = hci_uart_flush; |
399 | hdev->send = hci_uart_send_frame; | 399 | hdev->send = hci_uart_send_frame; |
400 | hdev->destruct = hci_uart_destruct; | 400 | hdev->destruct = hci_uart_destruct; |
401 | hdev->parent = hu->tty->dev; | ||
401 | 402 | ||
402 | hdev->owner = THIS_MODULE; | 403 | hdev->owner = THIS_MODULE; |
403 | 404 | ||
diff --git a/drivers/net/wireless/ath/ar9170/Kconfig b/drivers/net/wireless/ath/ar9170/Kconfig index d7a4799d20fb..7b9672b0d090 100644 --- a/drivers/net/wireless/ath/ar9170/Kconfig +++ b/drivers/net/wireless/ath/ar9170/Kconfig | |||
@@ -1,8 +1,10 @@ | |||
1 | config AR9170_USB | 1 | config AR9170_USB |
2 | tristate "Atheros AR9170 802.11n USB support" | 2 | tristate "Atheros AR9170 802.11n USB support (OBSOLETE)" |
3 | depends on USB && MAC80211 | 3 | depends on USB && MAC80211 |
4 | select FW_LOADER | 4 | select FW_LOADER |
5 | help | 5 | help |
6 | This driver is going to get replaced by carl9170. | ||
7 | |||
6 | This is a driver for the Atheros "otus" 802.11n USB devices. | 8 | This is a driver for the Atheros "otus" 802.11n USB devices. |
7 | 9 | ||
8 | These devices require additional firmware (2 files). | 10 | These devices require additional firmware (2 files). |
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index e43175a89d67..70abb61e9eff 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h | |||
@@ -1158,6 +1158,26 @@ void ath5k_hw_deinit(struct ath5k_hw *ah); | |||
1158 | int ath5k_sysfs_register(struct ath5k_softc *sc); | 1158 | int ath5k_sysfs_register(struct ath5k_softc *sc); |
1159 | void ath5k_sysfs_unregister(struct ath5k_softc *sc); | 1159 | void ath5k_sysfs_unregister(struct ath5k_softc *sc); |
1160 | 1160 | ||
1161 | /* base.c */ | ||
1162 | struct ath5k_buf; | ||
1163 | struct ath5k_txq; | ||
1164 | |||
1165 | void set_beacon_filter(struct ieee80211_hw *hw, bool enable); | ||
1166 | bool ath_any_vif_assoc(struct ath5k_softc *sc); | ||
1167 | int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
1168 | struct ath5k_txq *txq); | ||
1169 | int ath5k_init_hw(struct ath5k_softc *sc); | ||
1170 | int ath5k_stop_hw(struct ath5k_softc *sc); | ||
1171 | void ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif); | ||
1172 | void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, | ||
1173 | struct ieee80211_vif *vif); | ||
1174 | int ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan); | ||
1175 | void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); | ||
1176 | int ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif); | ||
1177 | void ath5k_beacon_config(struct ath5k_softc *sc); | ||
1178 | void ath5k_txbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf); | ||
1179 | void ath5k_rxbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf); | ||
1180 | |||
1161 | /*Chip id helper functions */ | 1181 | /*Chip id helper functions */ |
1162 | const char *ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val); | 1182 | const char *ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val); |
1163 | int ath5k_hw_read_srev(struct ath5k_hw *ah); | 1183 | int ath5k_hw_read_srev(struct ath5k_hw *ah); |
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index c71fdbb4c439..bc8240560488 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c | |||
@@ -220,7 +220,8 @@ int ath5k_hw_init(struct ath5k_softc *sc) | |||
220 | ah->ah_radio = AR5K_RF5112; | 220 | ah->ah_radio = AR5K_RF5112; |
221 | ah->ah_single_chip = false; | 221 | ah->ah_single_chip = false; |
222 | ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5112B; | 222 | ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5112B; |
223 | } else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4)) { | 223 | } else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4) || |
224 | ah->ah_mac_version == (AR5K_SREV_AR2315_R6 >> 4)) { | ||
224 | ah->ah_radio = AR5K_RF2316; | 225 | ah->ah_radio = AR5K_RF2316; |
225 | ah->ah_single_chip = true; | 226 | ah->ah_single_chip = true; |
226 | ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2316; | 227 | ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2316; |
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index 36a51995a7bc..a60a726a140c 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c | |||
@@ -48,23 +48,6 @@ | |||
48 | 48 | ||
49 | extern int ath5k_modparam_nohwcrypt; | 49 | extern int ath5k_modparam_nohwcrypt; |
50 | 50 | ||
51 | /* functions used from base.c */ | ||
52 | void set_beacon_filter(struct ieee80211_hw *hw, bool enable); | ||
53 | bool ath_any_vif_assoc(struct ath5k_softc *sc); | ||
54 | int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
55 | struct ath5k_txq *txq); | ||
56 | int ath5k_init_hw(struct ath5k_softc *sc); | ||
57 | int ath5k_stop_hw(struct ath5k_softc *sc); | ||
58 | void ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif); | ||
59 | void ath5k_update_bssid_mask_and_opmode(struct ath5k_softc *sc, | ||
60 | struct ieee80211_vif *vif); | ||
61 | int ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan); | ||
62 | void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); | ||
63 | int ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif); | ||
64 | void ath5k_beacon_config(struct ath5k_softc *sc); | ||
65 | void ath5k_txbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf); | ||
66 | void ath5k_rxbuf_free_skb(struct ath5k_softc *sc, struct ath5k_buf *bf); | ||
67 | |||
68 | /********************\ | 51 | /********************\ |
69 | * Mac80211 functions * | 52 | * Mac80211 functions * |
70 | \********************/ | 53 | \********************/ |
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index d673ab2f6cda..62ce2f4e8605 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c | |||
@@ -1281,6 +1281,7 @@ static int ath5k_hw_channel(struct ath5k_hw *ah, | |||
1281 | case AR5K_RF5111: | 1281 | case AR5K_RF5111: |
1282 | ret = ath5k_hw_rf5111_channel(ah, channel); | 1282 | ret = ath5k_hw_rf5111_channel(ah, channel); |
1283 | break; | 1283 | break; |
1284 | case AR5K_RF2317: | ||
1284 | case AR5K_RF2425: | 1285 | case AR5K_RF2425: |
1285 | ret = ath5k_hw_rf2425_channel(ah, channel); | 1286 | ret = ath5k_hw_rf2425_channel(ah, channel); |
1286 | break; | 1287 | break; |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 06fb2c850535..6fa3c24af2da 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c | |||
@@ -28,7 +28,67 @@ | |||
28 | */ | 28 | */ |
29 | static void ar9003_hw_init_mode_regs(struct ath_hw *ah) | 29 | static void ar9003_hw_init_mode_regs(struct ath_hw *ah) |
30 | { | 30 | { |
31 | if (AR_SREV_9485(ah)) { | 31 | if (AR_SREV_9485_11(ah)) { |
32 | /* mac */ | ||
33 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); | ||
34 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], | ||
35 | ar9485_1_1_mac_core, | ||
36 | ARRAY_SIZE(ar9485_1_1_mac_core), 2); | ||
37 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], | ||
38 | ar9485_1_1_mac_postamble, | ||
39 | ARRAY_SIZE(ar9485_1_1_mac_postamble), 5); | ||
40 | |||
41 | /* bb */ | ||
42 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], ar9485_1_1, | ||
43 | ARRAY_SIZE(ar9485_1_1), 2); | ||
44 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], | ||
45 | ar9485_1_1_baseband_core, | ||
46 | ARRAY_SIZE(ar9485_1_1_baseband_core), 2); | ||
47 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], | ||
48 | ar9485_1_1_baseband_postamble, | ||
49 | ARRAY_SIZE(ar9485_1_1_baseband_postamble), 5); | ||
50 | |||
51 | /* radio */ | ||
52 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); | ||
53 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], | ||
54 | ar9485_1_1_radio_core, | ||
55 | ARRAY_SIZE(ar9485_1_1_radio_core), 2); | ||
56 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], | ||
57 | ar9485_1_1_radio_postamble, | ||
58 | ARRAY_SIZE(ar9485_1_1_radio_postamble), 2); | ||
59 | |||
60 | /* soc */ | ||
61 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], | ||
62 | ar9485_1_1_soc_preamble, | ||
63 | ARRAY_SIZE(ar9485_1_1_soc_preamble), 2); | ||
64 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); | ||
65 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], NULL, 0, 0); | ||
66 | |||
67 | /* rx/tx gain */ | ||
68 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
69 | ar9485_common_rx_gain_1_1, | ||
70 | ARRAY_SIZE(ar9485_common_rx_gain_1_1), 2); | ||
71 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
72 | ar9485_modes_lowest_ob_db_tx_gain_1_1, | ||
73 | ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1), | ||
74 | 5); | ||
75 | |||
76 | /* Load PCIE SERDES settings from INI */ | ||
77 | |||
78 | /* Awake Setting */ | ||
79 | |||
80 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | ||
81 | ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1, | ||
82 | ARRAY_SIZE(ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1), | ||
83 | 2); | ||
84 | |||
85 | /* Sleep Setting */ | ||
86 | |||
87 | INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, | ||
88 | ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1, | ||
89 | ARRAY_SIZE(ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1), | ||
90 | 2); | ||
91 | } else if (AR_SREV_9485(ah)) { | ||
32 | /* mac */ | 92 | /* mac */ |
33 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); | 93 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); |
34 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], | 94 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], |
@@ -85,8 +145,8 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) | |||
85 | /* Sleep Setting */ | 145 | /* Sleep Setting */ |
86 | 146 | ||
87 | INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, | 147 | INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, |
88 | ar9485_1_0_pcie_phy_pll_on_clkreq_enable_L1, | 148 | ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1, |
89 | ARRAY_SIZE(ar9485_1_0_pcie_phy_pll_on_clkreq_enable_L1), | 149 | ARRAY_SIZE(ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1), |
90 | 2); | 150 | 2); |
91 | } else { | 151 | } else { |
92 | /* mac */ | 152 | /* mac */ |
@@ -163,7 +223,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) | |||
163 | switch (ar9003_hw_get_tx_gain_idx(ah)) { | 223 | switch (ar9003_hw_get_tx_gain_idx(ah)) { |
164 | case 0: | 224 | case 0: |
165 | default: | 225 | default: |
166 | if (AR_SREV_9485(ah)) | 226 | if (AR_SREV_9485_11(ah)) |
227 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
228 | ar9485_modes_lowest_ob_db_tx_gain_1_1, | ||
229 | ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1), | ||
230 | 5); | ||
231 | else if (AR_SREV_9485(ah)) | ||
167 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 232 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
168 | ar9485Modes_lowest_ob_db_tx_gain_1_0, | 233 | ar9485Modes_lowest_ob_db_tx_gain_1_0, |
169 | ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0), | 234 | ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0), |
@@ -175,10 +240,15 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) | |||
175 | 5); | 240 | 5); |
176 | break; | 241 | break; |
177 | case 1: | 242 | case 1: |
178 | if (AR_SREV_9485(ah)) | 243 | if (AR_SREV_9485_11(ah)) |
244 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
245 | ar9485Modes_high_ob_db_tx_gain_1_1, | ||
246 | ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1), | ||
247 | 5); | ||
248 | else if (AR_SREV_9485(ah)) | ||
179 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 249 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
180 | ar9485Modes_high_ob_db_tx_gain_1_0, | 250 | ar9485Modes_high_ob_db_tx_gain_1_0, |
181 | ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0), | 251 | ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_0), |
182 | 5); | 252 | 5); |
183 | else | 253 | else |
184 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 254 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
@@ -187,10 +257,15 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) | |||
187 | 5); | 257 | 5); |
188 | break; | 258 | break; |
189 | case 2: | 259 | case 2: |
190 | if (AR_SREV_9485(ah)) | 260 | if (AR_SREV_9485_11(ah)) |
261 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
262 | ar9485Modes_low_ob_db_tx_gain_1_1, | ||
263 | ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1), | ||
264 | 5); | ||
265 | else if (AR_SREV_9485(ah)) | ||
191 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 266 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
192 | ar9485Modes_low_ob_db_tx_gain_1_0, | 267 | ar9485Modes_low_ob_db_tx_gain_1_0, |
193 | ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0), | 268 | ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_0), |
194 | 5); | 269 | 5); |
195 | else | 270 | else |
196 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 271 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
@@ -199,7 +274,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) | |||
199 | 5); | 274 | 5); |
200 | break; | 275 | break; |
201 | case 3: | 276 | case 3: |
202 | if (AR_SREV_9485(ah)) | 277 | if (AR_SREV_9485_11(ah)) |
278 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
279 | ar9485Modes_high_power_tx_gain_1_1, | ||
280 | ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1), | ||
281 | 5); | ||
282 | else if (AR_SREV_9485(ah)) | ||
203 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 283 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
204 | ar9485Modes_high_power_tx_gain_1_0, | 284 | ar9485Modes_high_power_tx_gain_1_0, |
205 | ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_0), | 285 | ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_0), |
@@ -218,7 +298,12 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah) | |||
218 | switch (ar9003_hw_get_rx_gain_idx(ah)) { | 298 | switch (ar9003_hw_get_rx_gain_idx(ah)) { |
219 | case 0: | 299 | case 0: |
220 | default: | 300 | default: |
221 | if (AR_SREV_9485(ah)) | 301 | if (AR_SREV_9485_11(ah)) |
302 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
303 | ar9485_common_rx_gain_1_1, | ||
304 | ARRAY_SIZE(ar9485_common_rx_gain_1_1), | ||
305 | 2); | ||
306 | else if (AR_SREV_9485(ah)) | ||
222 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 307 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
223 | ar9485Common_rx_gain_1_0, | 308 | ar9485Common_rx_gain_1_0, |
224 | ARRAY_SIZE(ar9485Common_rx_gain_1_0), | 309 | ARRAY_SIZE(ar9485Common_rx_gain_1_0), |
@@ -230,7 +315,12 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah) | |||
230 | 2); | 315 | 2); |
231 | break; | 316 | break; |
232 | case 1: | 317 | case 1: |
233 | if (AR_SREV_9485(ah)) | 318 | if (AR_SREV_9485_11(ah)) |
319 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
320 | ar9485Common_wo_xlna_rx_gain_1_1, | ||
321 | ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), | ||
322 | 2); | ||
323 | else if (AR_SREV_9485(ah)) | ||
234 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 324 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
235 | ar9485Common_wo_xlna_rx_gain_1_0, | 325 | ar9485Common_wo_xlna_rx_gain_1_0, |
236 | ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_0), | 326 | ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_0), |
diff --git a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h index 70de3d89a7b5..eac4d8526fc1 100644 --- a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h | |||
@@ -940,4 +940,1145 @@ static const u32 ar9485_1_0_mac_core[][2] = { | |||
940 | {0x000083cc, 0x00000200}, | 940 | {0x000083cc, 0x00000200}, |
941 | {0x000083d0, 0x000301ff}, | 941 | {0x000083d0, 0x000301ff}, |
942 | }; | 942 | }; |
943 | |||
944 | static const u32 ar9485_1_1_mac_core[][2] = { | ||
945 | /* Addr allmodes */ | ||
946 | {0x00000008, 0x00000000}, | ||
947 | {0x00000030, 0x00020085}, | ||
948 | {0x00000034, 0x00000005}, | ||
949 | {0x00000040, 0x00000000}, | ||
950 | {0x00000044, 0x00000000}, | ||
951 | {0x00000048, 0x00000008}, | ||
952 | {0x0000004c, 0x00000010}, | ||
953 | {0x00000050, 0x00000000}, | ||
954 | {0x00001040, 0x002ffc0f}, | ||
955 | {0x00001044, 0x002ffc0f}, | ||
956 | {0x00001048, 0x002ffc0f}, | ||
957 | {0x0000104c, 0x002ffc0f}, | ||
958 | {0x00001050, 0x002ffc0f}, | ||
959 | {0x00001054, 0x002ffc0f}, | ||
960 | {0x00001058, 0x002ffc0f}, | ||
961 | {0x0000105c, 0x002ffc0f}, | ||
962 | {0x00001060, 0x002ffc0f}, | ||
963 | {0x00001064, 0x002ffc0f}, | ||
964 | {0x000010f0, 0x00000100}, | ||
965 | {0x00001270, 0x00000000}, | ||
966 | {0x000012b0, 0x00000000}, | ||
967 | {0x000012f0, 0x00000000}, | ||
968 | {0x0000143c, 0x00000000}, | ||
969 | {0x0000147c, 0x00000000}, | ||
970 | {0x00008000, 0x00000000}, | ||
971 | {0x00008004, 0x00000000}, | ||
972 | {0x00008008, 0x00000000}, | ||
973 | {0x0000800c, 0x00000000}, | ||
974 | {0x00008018, 0x00000000}, | ||
975 | {0x00008020, 0x00000000}, | ||
976 | {0x00008038, 0x00000000}, | ||
977 | {0x0000803c, 0x00000000}, | ||
978 | {0x00008040, 0x00000000}, | ||
979 | {0x00008044, 0x00000000}, | ||
980 | {0x00008048, 0x00000000}, | ||
981 | {0x0000804c, 0xffffffff}, | ||
982 | {0x00008054, 0x00000000}, | ||
983 | {0x00008058, 0x00000000}, | ||
984 | {0x0000805c, 0x000fc78f}, | ||
985 | {0x00008060, 0x0000000f}, | ||
986 | {0x00008064, 0x00000000}, | ||
987 | {0x00008070, 0x00000310}, | ||
988 | {0x00008074, 0x00000020}, | ||
989 | {0x00008078, 0x00000000}, | ||
990 | {0x0000809c, 0x0000000f}, | ||
991 | {0x000080a0, 0x00000000}, | ||
992 | {0x000080a4, 0x02ff0000}, | ||
993 | {0x000080a8, 0x0e070605}, | ||
994 | {0x000080ac, 0x0000000d}, | ||
995 | {0x000080b0, 0x00000000}, | ||
996 | {0x000080b4, 0x00000000}, | ||
997 | {0x000080b8, 0x00000000}, | ||
998 | {0x000080bc, 0x00000000}, | ||
999 | {0x000080c0, 0x2a800000}, | ||
1000 | {0x000080c4, 0x06900168}, | ||
1001 | {0x000080c8, 0x13881c22}, | ||
1002 | {0x000080cc, 0x01f40000}, | ||
1003 | {0x000080d0, 0x00252500}, | ||
1004 | {0x000080d4, 0x00a00000}, | ||
1005 | {0x000080d8, 0x00400000}, | ||
1006 | {0x000080dc, 0x00000000}, | ||
1007 | {0x000080e0, 0xffffffff}, | ||
1008 | {0x000080e4, 0x0000ffff}, | ||
1009 | {0x000080e8, 0x3f3f3f3f}, | ||
1010 | {0x000080ec, 0x00000000}, | ||
1011 | {0x000080f0, 0x00000000}, | ||
1012 | {0x000080f4, 0x00000000}, | ||
1013 | {0x000080fc, 0x00020000}, | ||
1014 | {0x00008100, 0x00000000}, | ||
1015 | {0x00008108, 0x00000052}, | ||
1016 | {0x0000810c, 0x00000000}, | ||
1017 | {0x00008110, 0x00000000}, | ||
1018 | {0x00008114, 0x000007ff}, | ||
1019 | {0x00008118, 0x000000aa}, | ||
1020 | {0x0000811c, 0x00003210}, | ||
1021 | {0x00008124, 0x00000000}, | ||
1022 | {0x00008128, 0x00000000}, | ||
1023 | {0x0000812c, 0x00000000}, | ||
1024 | {0x00008130, 0x00000000}, | ||
1025 | {0x00008134, 0x00000000}, | ||
1026 | {0x00008138, 0x00000000}, | ||
1027 | {0x0000813c, 0x0000ffff}, | ||
1028 | {0x00008144, 0xffffffff}, | ||
1029 | {0x00008168, 0x00000000}, | ||
1030 | {0x0000816c, 0x00000000}, | ||
1031 | {0x00008170, 0x18486200}, | ||
1032 | {0x00008174, 0x33332210}, | ||
1033 | {0x00008178, 0x00000000}, | ||
1034 | {0x0000817c, 0x00020000}, | ||
1035 | {0x000081c0, 0x00000000}, | ||
1036 | {0x000081c4, 0x33332210}, | ||
1037 | {0x000081d4, 0x00000000}, | ||
1038 | {0x000081ec, 0x00000000}, | ||
1039 | {0x000081f0, 0x00000000}, | ||
1040 | {0x000081f4, 0x00000000}, | ||
1041 | {0x000081f8, 0x00000000}, | ||
1042 | {0x000081fc, 0x00000000}, | ||
1043 | {0x00008240, 0x00100000}, | ||
1044 | {0x00008244, 0x0010f400}, | ||
1045 | {0x00008248, 0x00000800}, | ||
1046 | {0x0000824c, 0x0001e800}, | ||
1047 | {0x00008250, 0x00000000}, | ||
1048 | {0x00008254, 0x00000000}, | ||
1049 | {0x00008258, 0x00000000}, | ||
1050 | {0x0000825c, 0x40000000}, | ||
1051 | {0x00008260, 0x00080922}, | ||
1052 | {0x00008264, 0x9ca00010}, | ||
1053 | {0x00008268, 0xffffffff}, | ||
1054 | {0x0000826c, 0x0000ffff}, | ||
1055 | {0x00008270, 0x00000000}, | ||
1056 | {0x00008274, 0x40000000}, | ||
1057 | {0x00008278, 0x003e4180}, | ||
1058 | {0x0000827c, 0x00000004}, | ||
1059 | {0x00008284, 0x0000002c}, | ||
1060 | {0x00008288, 0x0000002c}, | ||
1061 | {0x0000828c, 0x000000ff}, | ||
1062 | {0x00008294, 0x00000000}, | ||
1063 | {0x00008298, 0x00000000}, | ||
1064 | {0x0000829c, 0x00000000}, | ||
1065 | {0x00008300, 0x00000140}, | ||
1066 | {0x00008314, 0x00000000}, | ||
1067 | {0x0000831c, 0x0000010d}, | ||
1068 | {0x00008328, 0x00000000}, | ||
1069 | {0x0000832c, 0x00000007}, | ||
1070 | {0x00008330, 0x00000302}, | ||
1071 | {0x00008334, 0x00000700}, | ||
1072 | {0x00008338, 0x00ff0000}, | ||
1073 | {0x0000833c, 0x02400000}, | ||
1074 | {0x00008340, 0x000107ff}, | ||
1075 | {0x00008344, 0xa248105b}, | ||
1076 | {0x00008348, 0x008f0000}, | ||
1077 | {0x0000835c, 0x00000000}, | ||
1078 | {0x00008360, 0xffffffff}, | ||
1079 | {0x00008364, 0xffffffff}, | ||
1080 | {0x00008368, 0x00000000}, | ||
1081 | {0x00008370, 0x00000000}, | ||
1082 | {0x00008374, 0x000000ff}, | ||
1083 | {0x00008378, 0x00000000}, | ||
1084 | {0x0000837c, 0x00000000}, | ||
1085 | {0x00008380, 0xffffffff}, | ||
1086 | {0x00008384, 0xffffffff}, | ||
1087 | {0x00008390, 0xffffffff}, | ||
1088 | {0x00008394, 0xffffffff}, | ||
1089 | {0x00008398, 0x00000000}, | ||
1090 | {0x0000839c, 0x00000000}, | ||
1091 | {0x000083a0, 0x00000000}, | ||
1092 | {0x000083a4, 0x0000fa14}, | ||
1093 | {0x000083a8, 0x000f0c00}, | ||
1094 | {0x000083ac, 0x33332210}, | ||
1095 | {0x000083b0, 0x33332210}, | ||
1096 | {0x000083b4, 0x33332210}, | ||
1097 | {0x000083b8, 0x33332210}, | ||
1098 | {0x000083bc, 0x00000000}, | ||
1099 | {0x000083c0, 0x00000000}, | ||
1100 | {0x000083c4, 0x00000000}, | ||
1101 | {0x000083c8, 0x00000000}, | ||
1102 | {0x000083cc, 0x00000200}, | ||
1103 | {0x000083d0, 0x000301ff}, | ||
1104 | }; | ||
1105 | |||
1106 | static const u32 ar9485_1_1_baseband_core[][2] = { | ||
1107 | /* Addr allmodes */ | ||
1108 | {0x00009800, 0xafe68e30}, | ||
1109 | {0x00009804, 0xfd14e000}, | ||
1110 | {0x00009808, 0x9c0a8f6b}, | ||
1111 | {0x0000980c, 0x04800000}, | ||
1112 | {0x00009814, 0x9280c00a}, | ||
1113 | {0x00009818, 0x00000000}, | ||
1114 | {0x0000981c, 0x00020028}, | ||
1115 | {0x00009834, 0x5f3ca3de}, | ||
1116 | {0x00009838, 0x0108ecff}, | ||
1117 | {0x0000983c, 0x14750600}, | ||
1118 | {0x00009880, 0x201fff00}, | ||
1119 | {0x00009884, 0x00001042}, | ||
1120 | {0x000098a4, 0x00200400}, | ||
1121 | {0x000098b0, 0x52440bbe}, | ||
1122 | {0x000098d0, 0x004b6a8e}, | ||
1123 | {0x000098d4, 0x00000820}, | ||
1124 | {0x000098dc, 0x00000000}, | ||
1125 | {0x000098f0, 0x00000000}, | ||
1126 | {0x000098f4, 0x00000000}, | ||
1127 | {0x00009c04, 0x00000000}, | ||
1128 | {0x00009c08, 0x03200000}, | ||
1129 | {0x00009c0c, 0x00000000}, | ||
1130 | {0x00009c10, 0x00000000}, | ||
1131 | {0x00009c14, 0x00046384}, | ||
1132 | {0x00009c18, 0x05b6b440}, | ||
1133 | {0x00009c1c, 0x00b6b440}, | ||
1134 | {0x00009d00, 0xc080a333}, | ||
1135 | {0x00009d04, 0x40206c10}, | ||
1136 | {0x00009d08, 0x009c4060}, | ||
1137 | {0x00009d0c, 0x1883800a}, | ||
1138 | {0x00009d10, 0x01834061}, | ||
1139 | {0x00009d14, 0x00c00400}, | ||
1140 | {0x00009d18, 0x00000000}, | ||
1141 | {0x00009d1c, 0x00000000}, | ||
1142 | {0x00009e08, 0x0038233c}, | ||
1143 | {0x00009e24, 0x9927b515}, | ||
1144 | {0x00009e28, 0x12ef0200}, | ||
1145 | {0x00009e30, 0x06336f77}, | ||
1146 | {0x00009e34, 0x6af6532f}, | ||
1147 | {0x00009e38, 0x0cc80c00}, | ||
1148 | {0x00009e40, 0x0d261820}, | ||
1149 | {0x00009e4c, 0x00001004}, | ||
1150 | {0x00009e50, 0x00ff03f1}, | ||
1151 | {0x00009fc0, 0x80be4788}, | ||
1152 | {0x00009fc4, 0x0001efb5}, | ||
1153 | {0x00009fcc, 0x40000014}, | ||
1154 | {0x0000a20c, 0x00000000}, | ||
1155 | {0x0000a210, 0x00000000}, | ||
1156 | {0x0000a220, 0x00000000}, | ||
1157 | {0x0000a224, 0x00000000}, | ||
1158 | {0x0000a228, 0x10002310}, | ||
1159 | {0x0000a23c, 0x00000000}, | ||
1160 | {0x0000a244, 0x0c000000}, | ||
1161 | {0x0000a2a0, 0x00000001}, | ||
1162 | {0x0000a2c0, 0x00000001}, | ||
1163 | {0x0000a2c8, 0x00000000}, | ||
1164 | {0x0000a2cc, 0x18c43433}, | ||
1165 | {0x0000a2d4, 0x00000000}, | ||
1166 | {0x0000a2dc, 0x00000000}, | ||
1167 | {0x0000a2e0, 0x00000000}, | ||
1168 | {0x0000a2e4, 0x00000000}, | ||
1169 | {0x0000a2e8, 0x00000000}, | ||
1170 | {0x0000a2ec, 0x00000000}, | ||
1171 | {0x0000a2f0, 0x00000000}, | ||
1172 | {0x0000a2f4, 0x00000000}, | ||
1173 | {0x0000a2f8, 0x00000000}, | ||
1174 | {0x0000a344, 0x00000000}, | ||
1175 | {0x0000a34c, 0x00000000}, | ||
1176 | {0x0000a350, 0x0000a000}, | ||
1177 | {0x0000a364, 0x00000000}, | ||
1178 | {0x0000a370, 0x00000000}, | ||
1179 | {0x0000a390, 0x00000001}, | ||
1180 | {0x0000a394, 0x00000444}, | ||
1181 | {0x0000a398, 0x001f0e0f}, | ||
1182 | {0x0000a39c, 0x0075393f}, | ||
1183 | {0x0000a3a0, 0xb79f6427}, | ||
1184 | {0x0000a3a4, 0x000000ff}, | ||
1185 | {0x0000a3a8, 0x3b3b3b3b}, | ||
1186 | {0x0000a3ac, 0x2f2f2f2f}, | ||
1187 | {0x0000a3c0, 0x20202020}, | ||
1188 | {0x0000a3c4, 0x22222220}, | ||
1189 | {0x0000a3c8, 0x20200020}, | ||
1190 | {0x0000a3cc, 0x20202020}, | ||
1191 | {0x0000a3d0, 0x20202020}, | ||
1192 | {0x0000a3d4, 0x20202020}, | ||
1193 | {0x0000a3d8, 0x20202020}, | ||
1194 | {0x0000a3dc, 0x20202020}, | ||
1195 | {0x0000a3e0, 0x20202020}, | ||
1196 | {0x0000a3e4, 0x20202020}, | ||
1197 | {0x0000a3e8, 0x20202020}, | ||
1198 | {0x0000a3ec, 0x20202020}, | ||
1199 | {0x0000a3f0, 0x00000000}, | ||
1200 | {0x0000a3f4, 0x00000006}, | ||
1201 | {0x0000a3f8, 0x0cdbd380}, | ||
1202 | {0x0000a3fc, 0x000f0f01}, | ||
1203 | {0x0000a400, 0x8fa91f01}, | ||
1204 | {0x0000a404, 0x00000000}, | ||
1205 | {0x0000a408, 0x0e79e5c6}, | ||
1206 | {0x0000a40c, 0x00820820}, | ||
1207 | {0x0000a414, 0x1ce739cf}, | ||
1208 | {0x0000a418, 0x2d0019ce}, | ||
1209 | {0x0000a41c, 0x1ce739ce}, | ||
1210 | {0x0000a420, 0x000001ce}, | ||
1211 | {0x0000a424, 0x1ce739ce}, | ||
1212 | {0x0000a428, 0x000001ce}, | ||
1213 | {0x0000a42c, 0x1ce739ce}, | ||
1214 | {0x0000a430, 0x1ce739ce}, | ||
1215 | {0x0000a434, 0x00000000}, | ||
1216 | {0x0000a438, 0x00001801}, | ||
1217 | {0x0000a43c, 0x00000000}, | ||
1218 | {0x0000a440, 0x00000000}, | ||
1219 | {0x0000a444, 0x00000000}, | ||
1220 | {0x0000a448, 0x04000000}, | ||
1221 | {0x0000a44c, 0x00000001}, | ||
1222 | {0x0000a450, 0x00010000}, | ||
1223 | {0x0000a5c4, 0xbfad9d74}, | ||
1224 | {0x0000a5c8, 0x0048060a}, | ||
1225 | {0x0000a5cc, 0x00000637}, | ||
1226 | {0x0000a760, 0x03020100}, | ||
1227 | {0x0000a764, 0x09080504}, | ||
1228 | {0x0000a768, 0x0d0c0b0a}, | ||
1229 | {0x0000a76c, 0x13121110}, | ||
1230 | {0x0000a770, 0x31301514}, | ||
1231 | {0x0000a774, 0x35343332}, | ||
1232 | {0x0000a778, 0x00000036}, | ||
1233 | {0x0000a780, 0x00000838}, | ||
1234 | {0x0000a7c0, 0x00000000}, | ||
1235 | {0x0000a7c4, 0xfffffffc}, | ||
1236 | {0x0000a7c8, 0x00000000}, | ||
1237 | {0x0000a7cc, 0x00000000}, | ||
1238 | {0x0000a7d0, 0x00000000}, | ||
1239 | {0x0000a7d4, 0x00000004}, | ||
1240 | {0x0000a7dc, 0x00000000}, | ||
1241 | }; | ||
1242 | |||
1243 | static const u32 ar9485Common_1_1[][2] = { | ||
1244 | /* Addr allmodes */ | ||
1245 | {0x00007010, 0x00000022}, | ||
1246 | {0x00007020, 0x00000000}, | ||
1247 | {0x00007034, 0x00000002}, | ||
1248 | {0x00007038, 0x000004c2}, | ||
1249 | }; | ||
1250 | |||
1251 | static const u32 ar9485_1_1_baseband_postamble[][5] = { | ||
1252 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
1253 | {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005}, | ||
1254 | {0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e}, | ||
1255 | {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, | ||
1256 | {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, | ||
1257 | {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, | ||
1258 | {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c}, | ||
1259 | {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044}, | ||
1260 | {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0}, | ||
1261 | {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020}, | ||
1262 | {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, | ||
1263 | {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec80d2e, 0x7ec80d2e}, | ||
1264 | {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e}, | ||
1265 | {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1266 | {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, | ||
1267 | {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, | ||
1268 | {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, | ||
1269 | {0x00009e3c, 0xcf946220, 0xcf946220, 0xcf946222, 0xcf946222}, | ||
1270 | {0x00009e44, 0x02321e27, 0x02321e27, 0x02282324, 0x02282324}, | ||
1271 | {0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010}, | ||
1272 | {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, | ||
1273 | {0x0000a204, 0x01303fc0, 0x01303fc4, 0x01303fc4, 0x01303fc0}, | ||
1274 | {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, | ||
1275 | {0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b}, | ||
1276 | {0x0000a234, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff}, | ||
1277 | {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018}, | ||
1278 | {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, | ||
1279 | {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, | ||
1280 | {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002}, | ||
1281 | {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, | ||
1282 | {0x0000a260, 0x3a021501, 0x3a021501, 0x3a021501, 0x3a021501}, | ||
1283 | {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, | ||
1284 | {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b}, | ||
1285 | {0x0000a284, 0x00000000, 0x00000000, 0x000002a0, 0x000002a0}, | ||
1286 | {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1287 | {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1288 | {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, | ||
1289 | {0x0000a2d0, 0x00071981, 0x00071981, 0x00071982, 0x00071982}, | ||
1290 | {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, | ||
1291 | {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1292 | {0x0000be04, 0x00802020, 0x00802020, 0x00802020, 0x00802020}, | ||
1293 | {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1294 | }; | ||
1295 | |||
1296 | static const u32 ar9485Modes_high_ob_db_tx_gain_1_1[][5] = { | ||
1297 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
1298 | {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, | ||
1299 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, | ||
1300 | {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1301 | {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, | ||
1302 | {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, | ||
1303 | {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, | ||
1304 | {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, | ||
1305 | {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, | ||
1306 | {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, | ||
1307 | {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, | ||
1308 | {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, | ||
1309 | {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603}, | ||
1310 | {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605}, | ||
1311 | {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03}, | ||
1312 | {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04}, | ||
1313 | {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20}, | ||
1314 | {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21}, | ||
1315 | {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62}, | ||
1316 | {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63}, | ||
1317 | {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65}, | ||
1318 | {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66}, | ||
1319 | {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645}, | ||
1320 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, | ||
1321 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, | ||
1322 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, | ||
1323 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, | ||
1324 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, | ||
1325 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1326 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, | ||
1327 | {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1328 | {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1329 | {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1330 | {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1331 | {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1332 | {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1333 | {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1334 | {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1335 | {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1336 | {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1337 | {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1338 | {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1339 | {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1340 | {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1341 | {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1342 | {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1343 | {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1344 | {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1345 | {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1346 | {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1347 | {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1348 | {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1349 | {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1350 | {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1351 | {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1352 | {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1353 | {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1354 | {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1355 | {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1356 | {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1357 | {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1358 | {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1359 | {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1360 | {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1361 | {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1362 | {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1363 | {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1364 | {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1365 | {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db}, | ||
1366 | {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, | ||
1367 | }; | ||
1368 | |||
1369 | static const u32 ar9485_modes_lowest_ob_db_tx_gain_1_1[][5] = { | ||
1370 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
1371 | {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, | ||
1372 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, | ||
1373 | {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1374 | {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, | ||
1375 | {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, | ||
1376 | {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, | ||
1377 | {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, | ||
1378 | {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, | ||
1379 | {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, | ||
1380 | {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, | ||
1381 | {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, | ||
1382 | {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603}, | ||
1383 | {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605}, | ||
1384 | {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03}, | ||
1385 | {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04}, | ||
1386 | {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20}, | ||
1387 | {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21}, | ||
1388 | {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62}, | ||
1389 | {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63}, | ||
1390 | {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65}, | ||
1391 | {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66}, | ||
1392 | {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645}, | ||
1393 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, | ||
1394 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, | ||
1395 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, | ||
1396 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, | ||
1397 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, | ||
1398 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1399 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, | ||
1400 | {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1401 | {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1402 | {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1403 | {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1404 | {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1405 | {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1406 | {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1407 | {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1408 | {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1409 | {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1410 | {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1411 | {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1412 | {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1413 | {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1414 | {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1415 | {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1416 | {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1417 | {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1418 | {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1419 | {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1420 | {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1421 | {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1422 | {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1423 | {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1424 | {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1425 | {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1426 | {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1427 | {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1428 | {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1429 | {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1430 | {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1431 | {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1432 | {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1433 | {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1434 | {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1435 | {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1436 | {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1437 | {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1438 | {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db}, | ||
1439 | {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, | ||
1440 | }; | ||
1441 | |||
1442 | static const u32 ar9485_1_1_radio_postamble[][2] = { | ||
1443 | /* Addr allmodes */ | ||
1444 | {0x0001609c, 0x0b283f31}, | ||
1445 | {0x000160ac, 0x24611800}, | ||
1446 | {0x000160b0, 0x03284f3e}, | ||
1447 | {0x0001610c, 0x00170000}, | ||
1448 | {0x00016140, 0x10804008}, | ||
1449 | }; | ||
1450 | |||
1451 | static const u32 ar9485_1_1_mac_postamble[][5] = { | ||
1452 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
1453 | {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, | ||
1454 | {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, | ||
1455 | {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, | ||
1456 | {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, | ||
1457 | {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, | ||
1458 | {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, | ||
1459 | {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, | ||
1460 | {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, | ||
1461 | }; | ||
1462 | |||
1463 | static const u32 ar9485_1_1_radio_core[][2] = { | ||
1464 | /* Addr allmodes */ | ||
1465 | {0x00016000, 0x36db6db6}, | ||
1466 | {0x00016004, 0x6db6db40}, | ||
1467 | {0x00016008, 0x73800000}, | ||
1468 | {0x0001600c, 0x00000000}, | ||
1469 | {0x00016040, 0x7f80fff8}, | ||
1470 | {0x0001604c, 0x000f0278}, | ||
1471 | {0x00016050, 0x4db6db8c}, | ||
1472 | {0x00016054, 0x6db60000}, | ||
1473 | {0x00016080, 0x00080000}, | ||
1474 | {0x00016084, 0x0e48048c}, | ||
1475 | {0x00016088, 0x14214514}, | ||
1476 | {0x0001608c, 0x119f081e}, | ||
1477 | {0x00016090, 0x24926490}, | ||
1478 | {0x00016098, 0xd28b3330}, | ||
1479 | {0x000160a0, 0xc2108ffe}, | ||
1480 | {0x000160a4, 0x812fc370}, | ||
1481 | {0x000160a8, 0x423c8000}, | ||
1482 | {0x000160b4, 0x92480040}, | ||
1483 | {0x000160c0, 0x006db6db}, | ||
1484 | {0x000160c4, 0x0186db60}, | ||
1485 | {0x000160c8, 0x6db6db6c}, | ||
1486 | {0x000160cc, 0x6de6fbe0}, | ||
1487 | {0x000160d0, 0xf7dfcf3c}, | ||
1488 | {0x00016100, 0x04cb0001}, | ||
1489 | {0x00016104, 0xfff80015}, | ||
1490 | {0x00016108, 0x00080010}, | ||
1491 | {0x00016144, 0x01884080}, | ||
1492 | {0x00016148, 0x00008040}, | ||
1493 | {0x00016240, 0x08400000}, | ||
1494 | {0x00016244, 0x1bf90f00}, | ||
1495 | {0x00016248, 0x00000000}, | ||
1496 | {0x0001624c, 0x00000000}, | ||
1497 | {0x00016280, 0x01000015}, | ||
1498 | {0x00016284, 0x00d30000}, | ||
1499 | {0x00016288, 0x00318000}, | ||
1500 | {0x0001628c, 0x50000000}, | ||
1501 | {0x00016290, 0x4b96210f}, | ||
1502 | {0x00016380, 0x00000000}, | ||
1503 | {0x00016384, 0x00000000}, | ||
1504 | {0x00016388, 0x00800700}, | ||
1505 | {0x0001638c, 0x00800700}, | ||
1506 | {0x00016390, 0x00800700}, | ||
1507 | {0x00016394, 0x00000000}, | ||
1508 | {0x00016398, 0x00000000}, | ||
1509 | {0x0001639c, 0x00000000}, | ||
1510 | {0x000163a0, 0x00000001}, | ||
1511 | {0x000163a4, 0x00000001}, | ||
1512 | {0x000163a8, 0x00000000}, | ||
1513 | {0x000163ac, 0x00000000}, | ||
1514 | {0x000163b0, 0x00000000}, | ||
1515 | {0x000163b4, 0x00000000}, | ||
1516 | {0x000163b8, 0x00000000}, | ||
1517 | {0x000163bc, 0x00000000}, | ||
1518 | {0x000163c0, 0x000000a0}, | ||
1519 | {0x000163c4, 0x000c0000}, | ||
1520 | {0x000163c8, 0x14021402}, | ||
1521 | {0x000163cc, 0x00001402}, | ||
1522 | {0x000163d0, 0x00000000}, | ||
1523 | {0x000163d4, 0x00000000}, | ||
1524 | {0x00016c40, 0x13188278}, | ||
1525 | {0x00016c44, 0x12000000}, | ||
1526 | }; | ||
1527 | |||
1528 | static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_enable_L1[][2] = { | ||
1529 | /* Addr allmodes */ | ||
1530 | {0x00018c00, 0x10052e5e}, | ||
1531 | {0x00018c04, 0x000801d8}, | ||
1532 | {0x00018c08, 0x0000080c}, | ||
1533 | }; | ||
1534 | |||
1535 | static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = { | ||
1536 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
1537 | {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, | ||
1538 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, | ||
1539 | {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1540 | {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, | ||
1541 | {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, | ||
1542 | {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, | ||
1543 | {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, | ||
1544 | {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, | ||
1545 | {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, | ||
1546 | {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, | ||
1547 | {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, | ||
1548 | {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603}, | ||
1549 | {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605}, | ||
1550 | {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03}, | ||
1551 | {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04}, | ||
1552 | {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20}, | ||
1553 | {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21}, | ||
1554 | {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62}, | ||
1555 | {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63}, | ||
1556 | {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65}, | ||
1557 | {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66}, | ||
1558 | {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645}, | ||
1559 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, | ||
1560 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, | ||
1561 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, | ||
1562 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, | ||
1563 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, | ||
1564 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1565 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, | ||
1566 | {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1567 | {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1568 | {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1569 | {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1570 | {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1571 | {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1572 | {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1573 | {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1574 | {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1575 | {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1576 | {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1577 | {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1578 | {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1579 | {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1580 | {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1581 | {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1582 | {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1583 | {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1584 | {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1585 | {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1586 | {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1587 | {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1588 | {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1589 | {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1590 | {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1591 | {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1592 | {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1593 | {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1594 | {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1595 | {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1596 | {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1597 | {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1598 | {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1599 | {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1600 | {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1601 | {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1602 | {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1603 | {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1604 | {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db}, | ||
1605 | {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, | ||
1606 | }; | ||
1607 | |||
1608 | static const u32 ar9485_1_1[][2] = { | ||
1609 | /* Addr allmodes */ | ||
1610 | {0x0000a580, 0x00000000}, | ||
1611 | {0x0000a584, 0x00000000}, | ||
1612 | {0x0000a588, 0x00000000}, | ||
1613 | {0x0000a58c, 0x00000000}, | ||
1614 | {0x0000a590, 0x00000000}, | ||
1615 | {0x0000a594, 0x00000000}, | ||
1616 | {0x0000a598, 0x00000000}, | ||
1617 | {0x0000a59c, 0x00000000}, | ||
1618 | {0x0000a5a0, 0x00000000}, | ||
1619 | {0x0000a5a4, 0x00000000}, | ||
1620 | {0x0000a5a8, 0x00000000}, | ||
1621 | {0x0000a5ac, 0x00000000}, | ||
1622 | {0x0000a5b0, 0x00000000}, | ||
1623 | {0x0000a5b4, 0x00000000}, | ||
1624 | {0x0000a5b8, 0x00000000}, | ||
1625 | {0x0000a5bc, 0x00000000}, | ||
1626 | }; | ||
1627 | |||
1628 | static const u32 ar9485_modes_green_ob_db_tx_gain_1_1[][5] = { | ||
1629 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
1630 | {0x000098bc, 0x00000003, 0x00000003, 0x00000003, 0x00000003}, | ||
1631 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, | ||
1632 | {0x0000a458, 0x80000000, 0x80000000, 0x80000000, 0x80000000}, | ||
1633 | {0x0000a500, 0x00022200, 0x00022200, 0x00000006, 0x00000006}, | ||
1634 | {0x0000a504, 0x05062002, 0x05062002, 0x03000201, 0x03000201}, | ||
1635 | {0x0000a508, 0x0c002e00, 0x0c002e00, 0x06000203, 0x06000203}, | ||
1636 | {0x0000a50c, 0x11062202, 0x11062202, 0x0a000401, 0x0a000401}, | ||
1637 | {0x0000a510, 0x17022e00, 0x17022e00, 0x0e000403, 0x0e000403}, | ||
1638 | {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x12000405, 0x12000405}, | ||
1639 | {0x0000a518, 0x25020ec0, 0x25020ec0, 0x15000604, 0x15000604}, | ||
1640 | {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x18000605, 0x18000605}, | ||
1641 | {0x0000a520, 0x2f001f04, 0x2f001f04, 0x1c000a04, 0x1c000a04}, | ||
1642 | {0x0000a524, 0x35001fc4, 0x35001fc4, 0x21000a06, 0x21000a06}, | ||
1643 | {0x0000a528, 0x3c022f04, 0x3c022f04, 0x29000a24, 0x29000a24}, | ||
1644 | {0x0000a52c, 0x41023e85, 0x41023e85, 0x2f000e21, 0x2f000e21}, | ||
1645 | {0x0000a530, 0x48023ec6, 0x48023ec6, 0x31000e20, 0x31000e20}, | ||
1646 | {0x0000a534, 0x4d023f01, 0x4d023f01, 0x33000e20, 0x33000e20}, | ||
1647 | {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62}, | ||
1648 | {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63}, | ||
1649 | {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65}, | ||
1650 | {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66}, | ||
1651 | {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645}, | ||
1652 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, | ||
1653 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, | ||
1654 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, | ||
1655 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, | ||
1656 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, | ||
1657 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1658 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, | ||
1659 | {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1660 | {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1661 | {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1662 | {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1663 | {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1664 | {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1665 | {0x0000b500, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
1666 | {0x0000b504, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
1667 | {0x0000b508, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
1668 | {0x0000b50c, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
1669 | {0x0000b510, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
1670 | {0x0000b514, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
1671 | {0x0000b518, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
1672 | {0x0000b51c, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
1673 | {0x0000b520, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
1674 | {0x0000b524, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
1675 | {0x0000b528, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, | ||
1676 | {0x0000b52c, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a}, | ||
1677 | {0x0000b530, 0x0000003a, 0x0000003a, 0x0000003a, 0x0000003a}, | ||
1678 | {0x0000b534, 0x0000004a, 0x0000004a, 0x0000004a, 0x0000004a}, | ||
1679 | {0x0000b538, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
1680 | {0x0000b53c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
1681 | {0x0000b540, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
1682 | {0x0000b544, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
1683 | {0x0000b548, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
1684 | {0x0000b54c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
1685 | {0x0000b550, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
1686 | {0x0000b554, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
1687 | {0x0000b558, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
1688 | {0x0000b55c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
1689 | {0x0000b560, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
1690 | {0x0000b564, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
1691 | {0x0000b568, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
1692 | {0x0000b56c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
1693 | {0x0000b570, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
1694 | {0x0000b574, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
1695 | {0x0000b578, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
1696 | {0x0000b57c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, | ||
1697 | {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db}, | ||
1698 | {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, | ||
1699 | }; | ||
1700 | |||
1701 | static const u32 ar9485_1_1_pcie_phy_clkreq_disable_L1[][2] = { | ||
1702 | /* Addr allmodes */ | ||
1703 | {0x00018c00, 0x10013e5e}, | ||
1704 | {0x00018c04, 0x000801d8}, | ||
1705 | {0x00018c08, 0x0000080c}, | ||
1706 | }; | ||
1707 | |||
1708 | static const u32 ar9485_1_1_soc_preamble[][2] = { | ||
1709 | /* Addr allmodes */ | ||
1710 | {0x00004014, 0xba280400}, | ||
1711 | {0x000040a4, 0x00a0c9c9}, | ||
1712 | {0x00007010, 0x00000022}, | ||
1713 | {0x00007020, 0x00000000}, | ||
1714 | {0x00007034, 0x00000002}, | ||
1715 | {0x00007038, 0x000004c2}, | ||
1716 | {0x00007048, 0x00000002}, | ||
1717 | }; | ||
1718 | |||
1719 | static const u32 ar9485_1_1_baseband_core_txfir_coeff_japan_2484[][2] = { | ||
1720 | /* Addr allmodes */ | ||
1721 | {0x0000a398, 0x00000000}, | ||
1722 | {0x0000a39c, 0x6f7f0301}, | ||
1723 | {0x0000a3a0, 0xca9228ee}, | ||
1724 | }; | ||
1725 | |||
1726 | static const u32 ar9485Modes_low_ob_db_tx_gain_1_1[][5] = { | ||
1727 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
1728 | {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, | ||
1729 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, | ||
1730 | {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1731 | {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, | ||
1732 | {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, | ||
1733 | {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, | ||
1734 | {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, | ||
1735 | {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, | ||
1736 | {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, | ||
1737 | {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, | ||
1738 | {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, | ||
1739 | {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603}, | ||
1740 | {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605}, | ||
1741 | {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03}, | ||
1742 | {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04}, | ||
1743 | {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20}, | ||
1744 | {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21}, | ||
1745 | {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62}, | ||
1746 | {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63}, | ||
1747 | {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65}, | ||
1748 | {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66}, | ||
1749 | {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645}, | ||
1750 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, | ||
1751 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, | ||
1752 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, | ||
1753 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb}, | ||
1754 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, | ||
1755 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1756 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, | ||
1757 | {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1758 | {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1759 | {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1760 | {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1761 | {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1762 | {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
1763 | {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1764 | {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1765 | {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1766 | {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1767 | {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1768 | {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1769 | {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1770 | {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1771 | {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1772 | {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1773 | {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1774 | {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1775 | {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1776 | {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1777 | {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1778 | {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1779 | {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1780 | {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1781 | {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1782 | {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1783 | {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1784 | {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1785 | {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1786 | {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1787 | {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1788 | {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1789 | {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1790 | {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1791 | {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1792 | {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1793 | {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1794 | {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1795 | {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db}, | ||
1796 | {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, | ||
1797 | }; | ||
1798 | |||
1799 | static const u32 ar9485_fast_clock_1_1_baseband_postamble[][3] = { | ||
1800 | /* Addr 5G_HT2 5G_HT40 */ | ||
1801 | {0x00009e00, 0x03721821, 0x03721821}, | ||
1802 | {0x0000a230, 0x0000400b, 0x00004016}, | ||
1803 | {0x0000a254, 0x00000898, 0x00001130}, | ||
1804 | }; | ||
1805 | |||
1806 | static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1[][2] = { | ||
1807 | /* Addr allmodes */ | ||
1808 | {0x00018c00, 0x10012e5e}, | ||
1809 | {0x00018c04, 0x000801d8}, | ||
1810 | {0x00018c08, 0x0000080c}, | ||
1811 | }; | ||
1812 | |||
1813 | static const u32 ar9485_common_rx_gain_1_1[][2] = { | ||
1814 | /* Addr allmodes */ | ||
1815 | {0x0000a000, 0x00010000}, | ||
1816 | {0x0000a004, 0x00030002}, | ||
1817 | {0x0000a008, 0x00050004}, | ||
1818 | {0x0000a00c, 0x00810080}, | ||
1819 | {0x0000a010, 0x01800082}, | ||
1820 | {0x0000a014, 0x01820181}, | ||
1821 | {0x0000a018, 0x01840183}, | ||
1822 | {0x0000a01c, 0x01880185}, | ||
1823 | {0x0000a020, 0x018a0189}, | ||
1824 | {0x0000a024, 0x02850284}, | ||
1825 | {0x0000a028, 0x02890288}, | ||
1826 | {0x0000a02c, 0x03850384}, | ||
1827 | {0x0000a030, 0x03890388}, | ||
1828 | {0x0000a034, 0x038b038a}, | ||
1829 | {0x0000a038, 0x038d038c}, | ||
1830 | {0x0000a03c, 0x03910390}, | ||
1831 | {0x0000a040, 0x03930392}, | ||
1832 | {0x0000a044, 0x03950394}, | ||
1833 | {0x0000a048, 0x00000396}, | ||
1834 | {0x0000a04c, 0x00000000}, | ||
1835 | {0x0000a050, 0x00000000}, | ||
1836 | {0x0000a054, 0x00000000}, | ||
1837 | {0x0000a058, 0x00000000}, | ||
1838 | {0x0000a05c, 0x00000000}, | ||
1839 | {0x0000a060, 0x00000000}, | ||
1840 | {0x0000a064, 0x00000000}, | ||
1841 | {0x0000a068, 0x00000000}, | ||
1842 | {0x0000a06c, 0x00000000}, | ||
1843 | {0x0000a070, 0x00000000}, | ||
1844 | {0x0000a074, 0x00000000}, | ||
1845 | {0x0000a078, 0x00000000}, | ||
1846 | {0x0000a07c, 0x00000000}, | ||
1847 | {0x0000a080, 0x28282828}, | ||
1848 | {0x0000a084, 0x28282828}, | ||
1849 | {0x0000a088, 0x28282828}, | ||
1850 | {0x0000a08c, 0x28282828}, | ||
1851 | {0x0000a090, 0x28282828}, | ||
1852 | {0x0000a094, 0x21212128}, | ||
1853 | {0x0000a098, 0x171c1c1c}, | ||
1854 | {0x0000a09c, 0x02020212}, | ||
1855 | {0x0000a0a0, 0x00000202}, | ||
1856 | {0x0000a0a4, 0x00000000}, | ||
1857 | {0x0000a0a8, 0x00000000}, | ||
1858 | {0x0000a0ac, 0x00000000}, | ||
1859 | {0x0000a0b0, 0x00000000}, | ||
1860 | {0x0000a0b4, 0x00000000}, | ||
1861 | {0x0000a0b8, 0x00000000}, | ||
1862 | {0x0000a0bc, 0x00000000}, | ||
1863 | {0x0000a0c0, 0x001f0000}, | ||
1864 | {0x0000a0c4, 0x111f1100}, | ||
1865 | {0x0000a0c8, 0x111d111e}, | ||
1866 | {0x0000a0cc, 0x111b111c}, | ||
1867 | {0x0000a0d0, 0x22032204}, | ||
1868 | {0x0000a0d4, 0x22012202}, | ||
1869 | {0x0000a0d8, 0x221f2200}, | ||
1870 | {0x0000a0dc, 0x221d221e}, | ||
1871 | {0x0000a0e0, 0x33013302}, | ||
1872 | {0x0000a0e4, 0x331f3300}, | ||
1873 | {0x0000a0e8, 0x4402331e}, | ||
1874 | {0x0000a0ec, 0x44004401}, | ||
1875 | {0x0000a0f0, 0x441e441f}, | ||
1876 | {0x0000a0f4, 0x55015502}, | ||
1877 | {0x0000a0f8, 0x551f5500}, | ||
1878 | {0x0000a0fc, 0x6602551e}, | ||
1879 | {0x0000a100, 0x66006601}, | ||
1880 | {0x0000a104, 0x661e661f}, | ||
1881 | {0x0000a108, 0x7703661d}, | ||
1882 | {0x0000a10c, 0x77017702}, | ||
1883 | {0x0000a110, 0x00007700}, | ||
1884 | {0x0000a114, 0x00000000}, | ||
1885 | {0x0000a118, 0x00000000}, | ||
1886 | {0x0000a11c, 0x00000000}, | ||
1887 | {0x0000a120, 0x00000000}, | ||
1888 | {0x0000a124, 0x00000000}, | ||
1889 | {0x0000a128, 0x00000000}, | ||
1890 | {0x0000a12c, 0x00000000}, | ||
1891 | {0x0000a130, 0x00000000}, | ||
1892 | {0x0000a134, 0x00000000}, | ||
1893 | {0x0000a138, 0x00000000}, | ||
1894 | {0x0000a13c, 0x00000000}, | ||
1895 | {0x0000a140, 0x001f0000}, | ||
1896 | {0x0000a144, 0x111f1100}, | ||
1897 | {0x0000a148, 0x111d111e}, | ||
1898 | {0x0000a14c, 0x111b111c}, | ||
1899 | {0x0000a150, 0x22032204}, | ||
1900 | {0x0000a154, 0x22012202}, | ||
1901 | {0x0000a158, 0x221f2200}, | ||
1902 | {0x0000a15c, 0x221d221e}, | ||
1903 | {0x0000a160, 0x33013302}, | ||
1904 | {0x0000a164, 0x331f3300}, | ||
1905 | {0x0000a168, 0x4402331e}, | ||
1906 | {0x0000a16c, 0x44004401}, | ||
1907 | {0x0000a170, 0x441e441f}, | ||
1908 | {0x0000a174, 0x55015502}, | ||
1909 | {0x0000a178, 0x551f5500}, | ||
1910 | {0x0000a17c, 0x6602551e}, | ||
1911 | {0x0000a180, 0x66006601}, | ||
1912 | {0x0000a184, 0x661e661f}, | ||
1913 | {0x0000a188, 0x7703661d}, | ||
1914 | {0x0000a18c, 0x77017702}, | ||
1915 | {0x0000a190, 0x00007700}, | ||
1916 | {0x0000a194, 0x00000000}, | ||
1917 | {0x0000a198, 0x00000000}, | ||
1918 | {0x0000a19c, 0x00000000}, | ||
1919 | {0x0000a1a0, 0x00000000}, | ||
1920 | {0x0000a1a4, 0x00000000}, | ||
1921 | {0x0000a1a8, 0x00000000}, | ||
1922 | {0x0000a1ac, 0x00000000}, | ||
1923 | {0x0000a1b0, 0x00000000}, | ||
1924 | {0x0000a1b4, 0x00000000}, | ||
1925 | {0x0000a1b8, 0x00000000}, | ||
1926 | {0x0000a1bc, 0x00000000}, | ||
1927 | {0x0000a1c0, 0x00000000}, | ||
1928 | {0x0000a1c4, 0x00000000}, | ||
1929 | {0x0000a1c8, 0x00000000}, | ||
1930 | {0x0000a1cc, 0x00000000}, | ||
1931 | {0x0000a1d0, 0x00000000}, | ||
1932 | {0x0000a1d4, 0x00000000}, | ||
1933 | {0x0000a1d8, 0x00000000}, | ||
1934 | {0x0000a1dc, 0x00000000}, | ||
1935 | {0x0000a1e0, 0x00000000}, | ||
1936 | {0x0000a1e4, 0x00000000}, | ||
1937 | {0x0000a1e8, 0x00000000}, | ||
1938 | {0x0000a1ec, 0x00000000}, | ||
1939 | {0x0000a1f0, 0x00000396}, | ||
1940 | {0x0000a1f4, 0x00000396}, | ||
1941 | {0x0000a1f8, 0x00000396}, | ||
1942 | {0x0000a1fc, 0x00000296}, | ||
1943 | }; | ||
1944 | |||
1945 | static const u32 ar9485_1_1_pcie_phy_clkreq_enable_L1[][2] = { | ||
1946 | /* Addr allmodes */ | ||
1947 | {0x00018c00, 0x10053e5e}, | ||
1948 | {0x00018c04, 0x000801d8}, | ||
1949 | {0x00018c08, 0x0000080c}, | ||
1950 | }; | ||
1951 | |||
1952 | static const u32 ar9485Common_wo_xlna_rx_gain_1_1[][2] = { | ||
1953 | /* Addr allmodes */ | ||
1954 | {0x0000a000, 0x00060005}, | ||
1955 | {0x0000a004, 0x00810080}, | ||
1956 | {0x0000a008, 0x00830082}, | ||
1957 | {0x0000a00c, 0x00850084}, | ||
1958 | {0x0000a010, 0x01820181}, | ||
1959 | {0x0000a014, 0x01840183}, | ||
1960 | {0x0000a018, 0x01880185}, | ||
1961 | {0x0000a01c, 0x018a0189}, | ||
1962 | {0x0000a020, 0x02850284}, | ||
1963 | {0x0000a024, 0x02890288}, | ||
1964 | {0x0000a028, 0x028b028a}, | ||
1965 | {0x0000a02c, 0x03850384}, | ||
1966 | {0x0000a030, 0x03890388}, | ||
1967 | {0x0000a034, 0x038b038a}, | ||
1968 | {0x0000a038, 0x038d038c}, | ||
1969 | {0x0000a03c, 0x03910390}, | ||
1970 | {0x0000a040, 0x03930392}, | ||
1971 | {0x0000a044, 0x03950394}, | ||
1972 | {0x0000a048, 0x00000396}, | ||
1973 | {0x0000a04c, 0x00000000}, | ||
1974 | {0x0000a050, 0x00000000}, | ||
1975 | {0x0000a054, 0x00000000}, | ||
1976 | {0x0000a058, 0x00000000}, | ||
1977 | {0x0000a05c, 0x00000000}, | ||
1978 | {0x0000a060, 0x00000000}, | ||
1979 | {0x0000a064, 0x00000000}, | ||
1980 | {0x0000a068, 0x00000000}, | ||
1981 | {0x0000a06c, 0x00000000}, | ||
1982 | {0x0000a070, 0x00000000}, | ||
1983 | {0x0000a074, 0x00000000}, | ||
1984 | {0x0000a078, 0x00000000}, | ||
1985 | {0x0000a07c, 0x00000000}, | ||
1986 | {0x0000a080, 0x28282828}, | ||
1987 | {0x0000a084, 0x28282828}, | ||
1988 | {0x0000a088, 0x28282828}, | ||
1989 | {0x0000a08c, 0x28282828}, | ||
1990 | {0x0000a090, 0x28282828}, | ||
1991 | {0x0000a094, 0x24242428}, | ||
1992 | {0x0000a098, 0x171e1e1e}, | ||
1993 | {0x0000a09c, 0x02020b0b}, | ||
1994 | {0x0000a0a0, 0x02020202}, | ||
1995 | {0x0000a0a4, 0x00000000}, | ||
1996 | {0x0000a0a8, 0x00000000}, | ||
1997 | {0x0000a0ac, 0x00000000}, | ||
1998 | {0x0000a0b0, 0x00000000}, | ||
1999 | {0x0000a0b4, 0x00000000}, | ||
2000 | {0x0000a0b8, 0x00000000}, | ||
2001 | {0x0000a0bc, 0x00000000}, | ||
2002 | {0x0000a0c0, 0x22072208}, | ||
2003 | {0x0000a0c4, 0x22052206}, | ||
2004 | {0x0000a0c8, 0x22032204}, | ||
2005 | {0x0000a0cc, 0x22012202}, | ||
2006 | {0x0000a0d0, 0x221f2200}, | ||
2007 | {0x0000a0d4, 0x221d221e}, | ||
2008 | {0x0000a0d8, 0x33023303}, | ||
2009 | {0x0000a0dc, 0x33003301}, | ||
2010 | {0x0000a0e0, 0x331e331f}, | ||
2011 | {0x0000a0e4, 0x4402331d}, | ||
2012 | {0x0000a0e8, 0x44004401}, | ||
2013 | {0x0000a0ec, 0x441e441f}, | ||
2014 | {0x0000a0f0, 0x55025503}, | ||
2015 | {0x0000a0f4, 0x55005501}, | ||
2016 | {0x0000a0f8, 0x551e551f}, | ||
2017 | {0x0000a0fc, 0x6602551d}, | ||
2018 | {0x0000a100, 0x66006601}, | ||
2019 | {0x0000a104, 0x661e661f}, | ||
2020 | {0x0000a108, 0x7703661d}, | ||
2021 | {0x0000a10c, 0x77017702}, | ||
2022 | {0x0000a110, 0x00007700}, | ||
2023 | {0x0000a114, 0x00000000}, | ||
2024 | {0x0000a118, 0x00000000}, | ||
2025 | {0x0000a11c, 0x00000000}, | ||
2026 | {0x0000a120, 0x00000000}, | ||
2027 | {0x0000a124, 0x00000000}, | ||
2028 | {0x0000a128, 0x00000000}, | ||
2029 | {0x0000a12c, 0x00000000}, | ||
2030 | {0x0000a130, 0x00000000}, | ||
2031 | {0x0000a134, 0x00000000}, | ||
2032 | {0x0000a138, 0x00000000}, | ||
2033 | {0x0000a13c, 0x00000000}, | ||
2034 | {0x0000a140, 0x001f0000}, | ||
2035 | {0x0000a144, 0x111f1100}, | ||
2036 | {0x0000a148, 0x111d111e}, | ||
2037 | {0x0000a14c, 0x111b111c}, | ||
2038 | {0x0000a150, 0x22032204}, | ||
2039 | {0x0000a154, 0x22012202}, | ||
2040 | {0x0000a158, 0x221f2200}, | ||
2041 | {0x0000a15c, 0x221d221e}, | ||
2042 | {0x0000a160, 0x33013302}, | ||
2043 | {0x0000a164, 0x331f3300}, | ||
2044 | {0x0000a168, 0x4402331e}, | ||
2045 | {0x0000a16c, 0x44004401}, | ||
2046 | {0x0000a170, 0x441e441f}, | ||
2047 | {0x0000a174, 0x55015502}, | ||
2048 | {0x0000a178, 0x551f5500}, | ||
2049 | {0x0000a17c, 0x6602551e}, | ||
2050 | {0x0000a180, 0x66006601}, | ||
2051 | {0x0000a184, 0x661e661f}, | ||
2052 | {0x0000a188, 0x7703661d}, | ||
2053 | {0x0000a18c, 0x77017702}, | ||
2054 | {0x0000a190, 0x00007700}, | ||
2055 | {0x0000a194, 0x00000000}, | ||
2056 | {0x0000a198, 0x00000000}, | ||
2057 | {0x0000a19c, 0x00000000}, | ||
2058 | {0x0000a1a0, 0x00000000}, | ||
2059 | {0x0000a1a4, 0x00000000}, | ||
2060 | {0x0000a1a8, 0x00000000}, | ||
2061 | {0x0000a1ac, 0x00000000}, | ||
2062 | {0x0000a1b0, 0x00000000}, | ||
2063 | {0x0000a1b4, 0x00000000}, | ||
2064 | {0x0000a1b8, 0x00000000}, | ||
2065 | {0x0000a1bc, 0x00000000}, | ||
2066 | {0x0000a1c0, 0x00000000}, | ||
2067 | {0x0000a1c4, 0x00000000}, | ||
2068 | {0x0000a1c8, 0x00000000}, | ||
2069 | {0x0000a1cc, 0x00000000}, | ||
2070 | {0x0000a1d0, 0x00000000}, | ||
2071 | {0x0000a1d4, 0x00000000}, | ||
2072 | {0x0000a1d8, 0x00000000}, | ||
2073 | {0x0000a1dc, 0x00000000}, | ||
2074 | {0x0000a1e0, 0x00000000}, | ||
2075 | {0x0000a1e4, 0x00000000}, | ||
2076 | {0x0000a1e8, 0x00000000}, | ||
2077 | {0x0000a1ec, 0x00000000}, | ||
2078 | {0x0000a1f0, 0x00000396}, | ||
2079 | {0x0000a1f4, 0x00000396}, | ||
2080 | {0x0000a1f8, 0x00000396}, | ||
2081 | {0x0000a1fc, 0x00000296}, | ||
2082 | }; | ||
2083 | |||
943 | #endif | 2084 | #endif |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 9272278aff5e..f9f0389b92ab 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/device.h> | 21 | #include <linux/device.h> |
22 | #include <linux/leds.h> | 22 | #include <linux/leds.h> |
23 | #include <linux/completion.h> | 23 | #include <linux/completion.h> |
24 | #include <linux/pm_qos_params.h> | ||
25 | 24 | ||
26 | #include "debug.h" | 25 | #include "debug.h" |
27 | #include "common.h" | 26 | #include "common.h" |
@@ -57,8 +56,6 @@ struct ath_node; | |||
57 | 56 | ||
58 | #define A_MAX(a, b) ((a) > (b) ? (a) : (b)) | 57 | #define A_MAX(a, b) ((a) > (b) ? (a) : (b)) |
59 | 58 | ||
60 | #define ATH9K_PM_QOS_DEFAULT_VALUE 55 | ||
61 | |||
62 | #define TSF_TO_TU(_h,_l) \ | 59 | #define TSF_TO_TU(_h,_l) \ |
63 | ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10)) | 60 | ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10)) |
64 | 61 | ||
@@ -192,6 +189,7 @@ struct ath_txq { | |||
192 | u32 axq_ampdu_depth; | 189 | u32 axq_ampdu_depth; |
193 | bool stopped; | 190 | bool stopped; |
194 | bool axq_tx_inprogress; | 191 | bool axq_tx_inprogress; |
192 | bool txq_flush_inprogress; | ||
195 | struct list_head axq_acq; | 193 | struct list_head axq_acq; |
196 | struct list_head txq_fifo[ATH_TXFIFO_DEPTH]; | 194 | struct list_head txq_fifo[ATH_TXFIFO_DEPTH]; |
197 | struct list_head txq_fifo_pending; | 195 | struct list_head txq_fifo_pending; |
@@ -349,6 +347,7 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid | |||
349 | 347 | ||
350 | struct ath_vif { | 348 | struct ath_vif { |
351 | int av_bslot; | 349 | int av_bslot; |
350 | bool is_bslot_active; | ||
352 | __le64 tsf_adjust; /* TSF adjustment for staggered beacons */ | 351 | __le64 tsf_adjust; /* TSF adjustment for staggered beacons */ |
353 | enum nl80211_iftype av_opmode; | 352 | enum nl80211_iftype av_opmode; |
354 | struct ath_buf *av_bcbuf; | 353 | struct ath_buf *av_bcbuf; |
@@ -371,7 +370,7 @@ struct ath_vif { | |||
371 | #define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024) | 370 | #define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024) |
372 | 371 | ||
373 | struct ath_beacon_config { | 372 | struct ath_beacon_config { |
374 | u16 beacon_interval; | 373 | int beacon_interval; |
375 | u16 listen_interval; | 374 | u16 listen_interval; |
376 | u16 dtim_period; | 375 | u16 dtim_period; |
377 | u16 bmiss_timeout; | 376 | u16 bmiss_timeout; |
@@ -403,6 +402,7 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif); | |||
403 | int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif); | 402 | int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif); |
404 | void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp); | 403 | void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp); |
405 | int ath_beaconq_config(struct ath_softc *sc); | 404 | int ath_beaconq_config(struct ath_softc *sc); |
405 | void ath9k_set_beaconing_status(struct ath_softc *sc, bool status); | ||
406 | 406 | ||
407 | /*******/ | 407 | /*******/ |
408 | /* ANI */ | 408 | /* ANI */ |
@@ -633,8 +633,6 @@ struct ath_softc { | |||
633 | struct ath9k_hw_cal_data caldata; | 633 | struct ath9k_hw_cal_data caldata; |
634 | int last_rssi; | 634 | int last_rssi; |
635 | 635 | ||
636 | int beacon_interval; | ||
637 | |||
638 | #ifdef CONFIG_ATH9K_DEBUGFS | 636 | #ifdef CONFIG_ATH9K_DEBUGFS |
639 | struct ath9k_debug debug; | 637 | struct ath9k_debug debug; |
640 | spinlock_t nodes_lock; | 638 | spinlock_t nodes_lock; |
@@ -649,8 +647,6 @@ struct ath_softc { | |||
649 | struct ath_descdma txsdma; | 647 | struct ath_descdma txsdma; |
650 | 648 | ||
651 | struct ath_ant_comb ant_comb; | 649 | struct ath_ant_comb ant_comb; |
652 | |||
653 | struct pm_qos_request_list pm_qos_req; | ||
654 | }; | 650 | }; |
655 | 651 | ||
656 | void ath9k_tasklet(unsigned long data); | 652 | void ath9k_tasklet(unsigned long data); |
@@ -665,7 +661,6 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz) | |||
665 | extern struct ieee80211_ops ath9k_ops; | 661 | extern struct ieee80211_ops ath9k_ops; |
666 | extern int ath9k_modparam_nohwcrypt; | 662 | extern int ath9k_modparam_nohwcrypt; |
667 | extern int led_blink; | 663 | extern int led_blink; |
668 | extern int ath9k_pm_qos_value; | ||
669 | extern bool is_ath9k_unloaded; | 664 | extern bool is_ath9k_unloaded; |
670 | 665 | ||
671 | irqreturn_t ath_isr(int irq, void *dev); | 666 | irqreturn_t ath_isr(int irq, void *dev); |
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index fcb36abfc309..a4bdfdb043ef 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -143,7 +143,7 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, | |||
143 | avp = (void *)vif->drv_priv; | 143 | avp = (void *)vif->drv_priv; |
144 | cabq = sc->beacon.cabq; | 144 | cabq = sc->beacon.cabq; |
145 | 145 | ||
146 | if (avp->av_bcbuf == NULL) | 146 | if ((avp->av_bcbuf == NULL) || !avp->is_bslot_active) |
147 | return NULL; | 147 | return NULL; |
148 | 148 | ||
149 | /* Release the old beacon first */ | 149 | /* Release the old beacon first */ |
@@ -226,6 +226,7 @@ int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
226 | struct ath_vif *avp; | 226 | struct ath_vif *avp; |
227 | struct ath_buf *bf; | 227 | struct ath_buf *bf; |
228 | struct sk_buff *skb; | 228 | struct sk_buff *skb; |
229 | struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; | ||
229 | __le64 tstamp; | 230 | __le64 tstamp; |
230 | 231 | ||
231 | avp = (void *)vif->drv_priv; | 232 | avp = (void *)vif->drv_priv; |
@@ -248,6 +249,7 @@ int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
248 | for (slot = 0; slot < ATH_BCBUF; slot++) | 249 | for (slot = 0; slot < ATH_BCBUF; slot++) |
249 | if (sc->beacon.bslot[slot] == NULL) { | 250 | if (sc->beacon.bslot[slot] == NULL) { |
250 | avp->av_bslot = slot; | 251 | avp->av_bslot = slot; |
252 | avp->is_bslot_active = false; | ||
251 | 253 | ||
252 | /* NB: keep looking for a double slot */ | 254 | /* NB: keep looking for a double slot */ |
253 | if (slot == 0 || !sc->beacon.bslot[slot-1]) | 255 | if (slot == 0 || !sc->beacon.bslot[slot-1]) |
@@ -282,7 +284,7 @@ int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
282 | u64 tsfadjust; | 284 | u64 tsfadjust; |
283 | int intval; | 285 | int intval; |
284 | 286 | ||
285 | intval = sc->beacon_interval ? : ATH_DEFAULT_BINTVAL; | 287 | intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL; |
286 | 288 | ||
287 | /* | 289 | /* |
288 | * Calculate the TSF offset for this beacon slot, i.e., the | 290 | * Calculate the TSF offset for this beacon slot, i.e., the |
@@ -314,6 +316,7 @@ int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
314 | ath_err(common, "dma_mapping_error on beacon alloc\n"); | 316 | ath_err(common, "dma_mapping_error on beacon alloc\n"); |
315 | return -ENOMEM; | 317 | return -ENOMEM; |
316 | } | 318 | } |
319 | avp->is_bslot_active = true; | ||
317 | 320 | ||
318 | return 0; | 321 | return 0; |
319 | } | 322 | } |
@@ -346,6 +349,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp) | |||
346 | void ath_beacon_tasklet(unsigned long data) | 349 | void ath_beacon_tasklet(unsigned long data) |
347 | { | 350 | { |
348 | struct ath_softc *sc = (struct ath_softc *)data; | 351 | struct ath_softc *sc = (struct ath_softc *)data; |
352 | struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; | ||
349 | struct ath_hw *ah = sc->sc_ah; | 353 | struct ath_hw *ah = sc->sc_ah; |
350 | struct ath_common *common = ath9k_hw_common(ah); | 354 | struct ath_common *common = ath9k_hw_common(ah); |
351 | struct ath_buf *bf = NULL; | 355 | struct ath_buf *bf = NULL; |
@@ -393,7 +397,7 @@ void ath_beacon_tasklet(unsigned long data) | |||
393 | * on the tsf to safeguard against missing an swba. | 397 | * on the tsf to safeguard against missing an swba. |
394 | */ | 398 | */ |
395 | 399 | ||
396 | intval = sc->beacon_interval ? : ATH_DEFAULT_BINTVAL; | 400 | intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL; |
397 | 401 | ||
398 | tsf = ath9k_hw_gettsf64(ah); | 402 | tsf = ath9k_hw_gettsf64(ah); |
399 | tsftu = TSF_TO_TU(tsf>>32, tsf); | 403 | tsftu = TSF_TO_TU(tsf>>32, tsf); |
@@ -747,3 +751,36 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
747 | 751 | ||
748 | sc->sc_flags |= SC_OP_BEACONS; | 752 | sc->sc_flags |= SC_OP_BEACONS; |
749 | } | 753 | } |
754 | |||
755 | void ath9k_set_beaconing_status(struct ath_softc *sc, bool status) | ||
756 | { | ||
757 | struct ath_hw *ah = sc->sc_ah; | ||
758 | struct ath_vif *avp; | ||
759 | int slot; | ||
760 | bool found = false; | ||
761 | |||
762 | ath9k_ps_wakeup(sc); | ||
763 | if (status) { | ||
764 | for (slot = 0; slot < ATH_BCBUF; slot++) { | ||
765 | if (sc->beacon.bslot[slot]) { | ||
766 | avp = (void *)sc->beacon.bslot[slot]->drv_priv; | ||
767 | if (avp->is_bslot_active) { | ||
768 | found = true; | ||
769 | break; | ||
770 | } | ||
771 | } | ||
772 | } | ||
773 | if (found) { | ||
774 | /* Re-enable beaconing */ | ||
775 | ah->imask |= ATH9K_INT_SWBA; | ||
776 | ath9k_hw_set_interrupts(ah, ah->imask); | ||
777 | } | ||
778 | } else { | ||
779 | /* Disable SWBA interrupt */ | ||
780 | ah->imask &= ~ATH9K_INT_SWBA; | ||
781 | ath9k_hw_set_interrupts(ah, ah->imask); | ||
782 | tasklet_kill(&sc->bcon_tasklet); | ||
783 | ath9k_hw_stoptxdma(ah, sc->beacon.beaconq); | ||
784 | } | ||
785 | ath9k_ps_restore(sc); | ||
786 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 953036a4ed53..50fde0e10595 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
@@ -169,7 +169,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, | |||
169 | struct ieee80211_conf *conf = &common->hw->conf; | 169 | struct ieee80211_conf *conf = &common->hw->conf; |
170 | bool fastcc; | 170 | bool fastcc; |
171 | struct ieee80211_channel *channel = hw->conf.channel; | 171 | struct ieee80211_channel *channel = hw->conf.channel; |
172 | struct ath9k_hw_cal_data *caldata; | 172 | struct ath9k_hw_cal_data *caldata = NULL; |
173 | enum htc_phymode mode; | 173 | enum htc_phymode mode; |
174 | __be16 htc_mode; | 174 | __be16 htc_mode; |
175 | u8 cmd_rsp; | 175 | u8 cmd_rsp; |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index f9cf81551817..9a3438174f86 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -1100,7 +1100,6 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah) | |||
1100 | REG_WRITE(ah, AR_RC, AR_RC_AHB); | 1100 | REG_WRITE(ah, AR_RC, AR_RC_AHB); |
1101 | 1101 | ||
1102 | REG_WRITE(ah, AR_RTC_RESET, 0); | 1102 | REG_WRITE(ah, AR_RTC_RESET, 0); |
1103 | udelay(2); | ||
1104 | 1103 | ||
1105 | REGWRITE_BUFFER_FLUSH(ah); | 1104 | REGWRITE_BUFFER_FLUSH(ah); |
1106 | 1105 | ||
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index e5c1eead98a2..f66c882a39e2 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -41,10 +41,6 @@ static int ath9k_btcoex_enable; | |||
41 | module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444); | 41 | module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444); |
42 | MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence"); | 42 | MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence"); |
43 | 43 | ||
44 | int ath9k_pm_qos_value = ATH9K_PM_QOS_DEFAULT_VALUE; | ||
45 | module_param_named(pmqos, ath9k_pm_qos_value, int, S_IRUSR | S_IRGRP | S_IROTH); | ||
46 | MODULE_PARM_DESC(pmqos, "User specified PM-QOS value"); | ||
47 | |||
48 | bool is_ath9k_unloaded; | 44 | bool is_ath9k_unloaded; |
49 | /* We use the hw_value as an index into our private channel structure */ | 45 | /* We use the hw_value as an index into our private channel structure */ |
50 | 46 | ||
@@ -760,9 +756,6 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
760 | ath_init_leds(sc); | 756 | ath_init_leds(sc); |
761 | ath_start_rfkill_poll(sc); | 757 | ath_start_rfkill_poll(sc); |
762 | 758 | ||
763 | pm_qos_add_request(&sc->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, | ||
764 | PM_QOS_DEFAULT_VALUE); | ||
765 | |||
766 | return 0; | 759 | return 0; |
767 | 760 | ||
768 | error_world: | 761 | error_world: |
@@ -819,7 +812,6 @@ void ath9k_deinit_device(struct ath_softc *sc) | |||
819 | ath9k_ps_restore(sc); | 812 | ath9k_ps_restore(sc); |
820 | 813 | ||
821 | ieee80211_unregister_hw(hw); | 814 | ieee80211_unregister_hw(hw); |
822 | pm_qos_remove_request(&sc->pm_qos_req); | ||
823 | ath_rx_cleanup(sc); | 815 | ath_rx_cleanup(sc); |
824 | ath_tx_cleanup(sc); | 816 | ath_tx_cleanup(sc); |
825 | ath9k_deinit_softc(sc); | 817 | ath9k_deinit_softc(sc); |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 4ed43b2b8df6..a71550049d84 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -15,6 +15,7 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/nl80211.h> | 17 | #include <linux/nl80211.h> |
18 | #include <linux/delay.h> | ||
18 | #include "ath9k.h" | 19 | #include "ath9k.h" |
19 | #include "btcoex.h" | 20 | #include "btcoex.h" |
20 | 21 | ||
@@ -53,6 +54,21 @@ static u8 parse_mpdudensity(u8 mpdudensity) | |||
53 | } | 54 | } |
54 | } | 55 | } |
55 | 56 | ||
57 | static bool ath9k_has_pending_frames(struct ath_softc *sc, struct ath_txq *txq) | ||
58 | { | ||
59 | bool pending = false; | ||
60 | |||
61 | spin_lock_bh(&txq->axq_lock); | ||
62 | |||
63 | if (txq->axq_depth || !list_empty(&txq->axq_acq)) | ||
64 | pending = true; | ||
65 | else if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | ||
66 | pending = !list_empty(&txq->txq_fifo_pending); | ||
67 | |||
68 | spin_unlock_bh(&txq->axq_lock); | ||
69 | return pending; | ||
70 | } | ||
71 | |||
56 | bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode) | 72 | bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode) |
57 | { | 73 | { |
58 | unsigned long flags; | 74 | unsigned long flags; |
@@ -1117,12 +1133,6 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1117 | ath9k_btcoex_timer_resume(sc); | 1133 | ath9k_btcoex_timer_resume(sc); |
1118 | } | 1134 | } |
1119 | 1135 | ||
1120 | /* User has the option to provide pm-qos value as a module | ||
1121 | * parameter rather than using the default value of | ||
1122 | * 'ATH9K_PM_QOS_DEFAULT_VALUE'. | ||
1123 | */ | ||
1124 | pm_qos_update_request(&sc->pm_qos_req, ath9k_pm_qos_value); | ||
1125 | |||
1126 | if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en) | 1136 | if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en) |
1127 | common->bus_ops->extn_synch_en(common); | 1137 | common->bus_ops->extn_synch_en(common); |
1128 | 1138 | ||
@@ -1267,8 +1277,6 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
1267 | 1277 | ||
1268 | sc->sc_flags |= SC_OP_INVALID; | 1278 | sc->sc_flags |= SC_OP_INVALID; |
1269 | 1279 | ||
1270 | pm_qos_update_request(&sc->pm_qos_req, PM_QOS_DEFAULT_VALUE); | ||
1271 | |||
1272 | mutex_unlock(&sc->mutex); | 1280 | mutex_unlock(&sc->mutex); |
1273 | 1281 | ||
1274 | ath_dbg(common, ATH_DBG_CONFIG, "Driver halt\n"); | 1282 | ath_dbg(common, ATH_DBG_CONFIG, "Driver halt\n"); |
@@ -1291,24 +1299,10 @@ static void ath9k_reclaim_beacon(struct ath_softc *sc, | |||
1291 | { | 1299 | { |
1292 | struct ath_vif *avp = (void *)vif->drv_priv; | 1300 | struct ath_vif *avp = (void *)vif->drv_priv; |
1293 | 1301 | ||
1294 | /* Disable SWBA interrupt */ | 1302 | ath9k_set_beaconing_status(sc, false); |
1295 | sc->sc_ah->imask &= ~ATH9K_INT_SWBA; | ||
1296 | ath9k_ps_wakeup(sc); | ||
1297 | ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); | ||
1298 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | ||
1299 | tasklet_kill(&sc->bcon_tasklet); | ||
1300 | ath9k_ps_restore(sc); | ||
1301 | |||
1302 | ath_beacon_return(sc, avp); | 1303 | ath_beacon_return(sc, avp); |
1304 | ath9k_set_beaconing_status(sc, true); | ||
1303 | sc->sc_flags &= ~SC_OP_BEACONS; | 1305 | sc->sc_flags &= ~SC_OP_BEACONS; |
1304 | |||
1305 | if (sc->nbcnvifs > 0) { | ||
1306 | /* Re-enable beaconing */ | ||
1307 | sc->sc_ah->imask |= ATH9K_INT_SWBA; | ||
1308 | ath9k_ps_wakeup(sc); | ||
1309 | ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); | ||
1310 | ath9k_ps_restore(sc); | ||
1311 | } | ||
1312 | } | 1306 | } |
1313 | 1307 | ||
1314 | static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | 1308 | static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) |
@@ -1436,16 +1430,17 @@ static void ath9k_do_vif_add_setup(struct ieee80211_hw *hw, | |||
1436 | 1430 | ||
1437 | if (ath9k_uses_beacons(vif->type)) { | 1431 | if (ath9k_uses_beacons(vif->type)) { |
1438 | int error; | 1432 | int error; |
1439 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | ||
1440 | /* This may fail because upper levels do not have beacons | 1433 | /* This may fail because upper levels do not have beacons |
1441 | * properly configured yet. That's OK, we assume it | 1434 | * properly configured yet. That's OK, we assume it |
1442 | * will be properly configured and then we will be notified | 1435 | * will be properly configured and then we will be notified |
1443 | * in the info_changed method and set up beacons properly | 1436 | * in the info_changed method and set up beacons properly |
1444 | * there. | 1437 | * there. |
1445 | */ | 1438 | */ |
1439 | ath9k_set_beaconing_status(sc, false); | ||
1446 | error = ath_beacon_alloc(sc, vif); | 1440 | error = ath_beacon_alloc(sc, vif); |
1447 | if (!error) | 1441 | if (!error) |
1448 | ath_beacon_config(sc, vif); | 1442 | ath_beacon_config(sc, vif); |
1443 | ath9k_set_beaconing_status(sc, true); | ||
1449 | } | 1444 | } |
1450 | } | 1445 | } |
1451 | 1446 | ||
@@ -1676,8 +1671,9 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1676 | else | 1671 | else |
1677 | sc->sc_flags &= ~SC_OP_OFFCHANNEL; | 1672 | sc->sc_flags &= ~SC_OP_OFFCHANNEL; |
1678 | 1673 | ||
1679 | ath_dbg(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n", | 1674 | ath_dbg(common, ATH_DBG_CONFIG, |
1680 | curchan->center_freq); | 1675 | "Set channel: %d MHz type: %d\n", |
1676 | curchan->center_freq, conf->channel_type); | ||
1681 | 1677 | ||
1682 | ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos], | 1678 | ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos], |
1683 | curchan, conf->channel_type); | 1679 | curchan, conf->channel_type); |
@@ -1723,6 +1719,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1723 | } | 1719 | } |
1724 | 1720 | ||
1725 | if (changed & IEEE80211_CONF_CHANGE_POWER) { | 1721 | if (changed & IEEE80211_CONF_CHANGE_POWER) { |
1722 | ath_dbg(common, ATH_DBG_CONFIG, | ||
1723 | "Set power: %d\n", conf->power_level); | ||
1726 | sc->config.txpowlimit = 2 * conf->power_level; | 1724 | sc->config.txpowlimit = 2 * conf->power_level; |
1727 | ath9k_ps_wakeup(sc); | 1725 | ath9k_ps_wakeup(sc); |
1728 | ath9k_cmn_update_txpow(ah, sc->curtxpow, | 1726 | ath9k_cmn_update_txpow(ah, sc->curtxpow, |
@@ -1886,6 +1884,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
1886 | u32 changed) | 1884 | u32 changed) |
1887 | { | 1885 | { |
1888 | struct ath_softc *sc = hw->priv; | 1886 | struct ath_softc *sc = hw->priv; |
1887 | struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; | ||
1889 | struct ath_hw *ah = sc->sc_ah; | 1888 | struct ath_hw *ah = sc->sc_ah; |
1890 | struct ath_common *common = ath9k_hw_common(ah); | 1889 | struct ath_common *common = ath9k_hw_common(ah); |
1891 | struct ath_vif *avp = (void *)vif->drv_priv; | 1890 | struct ath_vif *avp = (void *)vif->drv_priv; |
@@ -1914,10 +1913,11 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
1914 | /* Enable transmission of beacons (AP, IBSS, MESH) */ | 1913 | /* Enable transmission of beacons (AP, IBSS, MESH) */ |
1915 | if ((changed & BSS_CHANGED_BEACON) || | 1914 | if ((changed & BSS_CHANGED_BEACON) || |
1916 | ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon)) { | 1915 | ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon)) { |
1917 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | 1916 | ath9k_set_beaconing_status(sc, false); |
1918 | error = ath_beacon_alloc(sc, vif); | 1917 | error = ath_beacon_alloc(sc, vif); |
1919 | if (!error) | 1918 | if (!error) |
1920 | ath_beacon_config(sc, vif); | 1919 | ath_beacon_config(sc, vif); |
1920 | ath9k_set_beaconing_status(sc, true); | ||
1921 | } | 1921 | } |
1922 | 1922 | ||
1923 | if (changed & BSS_CHANGED_ERP_SLOT) { | 1923 | if (changed & BSS_CHANGED_ERP_SLOT) { |
@@ -1940,21 +1940,26 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
1940 | } | 1940 | } |
1941 | 1941 | ||
1942 | /* Disable transmission of beacons */ | 1942 | /* Disable transmission of beacons */ |
1943 | if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon) | 1943 | if ((changed & BSS_CHANGED_BEACON_ENABLED) && |
1944 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | 1944 | !bss_conf->enable_beacon) { |
1945 | ath9k_set_beaconing_status(sc, false); | ||
1946 | avp->is_bslot_active = false; | ||
1947 | ath9k_set_beaconing_status(sc, true); | ||
1948 | } | ||
1945 | 1949 | ||
1946 | if (changed & BSS_CHANGED_BEACON_INT) { | 1950 | if (changed & BSS_CHANGED_BEACON_INT) { |
1947 | sc->beacon_interval = bss_conf->beacon_int; | 1951 | cur_conf->beacon_interval = bss_conf->beacon_int; |
1948 | /* | 1952 | /* |
1949 | * In case of AP mode, the HW TSF has to be reset | 1953 | * In case of AP mode, the HW TSF has to be reset |
1950 | * when the beacon interval changes. | 1954 | * when the beacon interval changes. |
1951 | */ | 1955 | */ |
1952 | if (vif->type == NL80211_IFTYPE_AP) { | 1956 | if (vif->type == NL80211_IFTYPE_AP) { |
1953 | sc->sc_flags |= SC_OP_TSF_RESET; | 1957 | sc->sc_flags |= SC_OP_TSF_RESET; |
1954 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | 1958 | ath9k_set_beaconing_status(sc, false); |
1955 | error = ath_beacon_alloc(sc, vif); | 1959 | error = ath_beacon_alloc(sc, vif); |
1956 | if (!error) | 1960 | if (!error) |
1957 | ath_beacon_config(sc, vif); | 1961 | ath_beacon_config(sc, vif); |
1962 | ath9k_set_beaconing_status(sc, true); | ||
1958 | } else { | 1963 | } else { |
1959 | ath_beacon_config(sc, vif); | 1964 | ath_beacon_config(sc, vif); |
1960 | } | 1965 | } |
@@ -2122,6 +2127,60 @@ static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) | |||
2122 | mutex_unlock(&sc->mutex); | 2127 | mutex_unlock(&sc->mutex); |
2123 | } | 2128 | } |
2124 | 2129 | ||
2130 | static void ath9k_flush(struct ieee80211_hw *hw, bool drop) | ||
2131 | { | ||
2132 | #define ATH_FLUSH_TIMEOUT 60 /* ms */ | ||
2133 | struct ath_softc *sc = hw->priv; | ||
2134 | struct ath_txq *txq; | ||
2135 | struct ath_hw *ah = sc->sc_ah; | ||
2136 | struct ath_common *common = ath9k_hw_common(ah); | ||
2137 | int i, j, npend = 0; | ||
2138 | |||
2139 | mutex_lock(&sc->mutex); | ||
2140 | |||
2141 | cancel_delayed_work_sync(&sc->tx_complete_work); | ||
2142 | |||
2143 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { | ||
2144 | if (!ATH_TXQ_SETUP(sc, i)) | ||
2145 | continue; | ||
2146 | txq = &sc->tx.txq[i]; | ||
2147 | |||
2148 | if (!drop) { | ||
2149 | for (j = 0; j < ATH_FLUSH_TIMEOUT; j++) { | ||
2150 | if (!ath9k_has_pending_frames(sc, txq)) | ||
2151 | break; | ||
2152 | usleep_range(1000, 2000); | ||
2153 | } | ||
2154 | } | ||
2155 | |||
2156 | if (drop || ath9k_has_pending_frames(sc, txq)) { | ||
2157 | ath_dbg(common, ATH_DBG_QUEUE, "Drop frames from hw queue:%d\n", | ||
2158 | txq->axq_qnum); | ||
2159 | spin_lock_bh(&txq->axq_lock); | ||
2160 | txq->txq_flush_inprogress = true; | ||
2161 | spin_unlock_bh(&txq->axq_lock); | ||
2162 | |||
2163 | ath9k_ps_wakeup(sc); | ||
2164 | ath9k_hw_stoptxdma(ah, txq->axq_qnum); | ||
2165 | npend = ath9k_hw_numtxpending(ah, txq->axq_qnum); | ||
2166 | ath9k_ps_restore(sc); | ||
2167 | if (npend) | ||
2168 | break; | ||
2169 | |||
2170 | ath_draintxq(sc, txq, false); | ||
2171 | txq->txq_flush_inprogress = false; | ||
2172 | } | ||
2173 | } | ||
2174 | |||
2175 | if (npend) { | ||
2176 | ath_reset(sc, false); | ||
2177 | txq->txq_flush_inprogress = false; | ||
2178 | } | ||
2179 | |||
2180 | ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0); | ||
2181 | mutex_unlock(&sc->mutex); | ||
2182 | } | ||
2183 | |||
2125 | struct ieee80211_ops ath9k_ops = { | 2184 | struct ieee80211_ops ath9k_ops = { |
2126 | .tx = ath9k_tx, | 2185 | .tx = ath9k_tx, |
2127 | .start = ath9k_start, | 2186 | .start = ath9k_start, |
@@ -2143,4 +2202,5 @@ struct ieee80211_ops ath9k_ops = { | |||
2143 | .get_survey = ath9k_get_survey, | 2202 | .get_survey = ath9k_get_survey, |
2144 | .rfkill_poll = ath9k_rfkill_poll_state, | 2203 | .rfkill_poll = ath9k_rfkill_poll_state, |
2145 | .set_coverage_class = ath9k_set_coverage_class, | 2204 | .set_coverage_class = ath9k_set_coverage_class, |
2205 | .flush = ath9k_flush, | ||
2146 | }; | 2206 | }; |
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index b262e98709de..64b226a78b2e 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h | |||
@@ -789,6 +789,7 @@ | |||
789 | #define AR_SREV_REVISION_9300_20 2 /* 2.0 and 2.1 */ | 789 | #define AR_SREV_REVISION_9300_20 2 /* 2.0 and 2.1 */ |
790 | #define AR_SREV_VERSION_9485 0x240 | 790 | #define AR_SREV_VERSION_9485 0x240 |
791 | #define AR_SREV_REVISION_9485_10 0 | 791 | #define AR_SREV_REVISION_9485_10 0 |
792 | #define AR_SREV_REVISION_9485_11 1 | ||
792 | 793 | ||
793 | #define AR_SREV_5416(_ah) \ | 794 | #define AR_SREV_5416(_ah) \ |
794 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \ | 795 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \ |
@@ -866,6 +867,9 @@ | |||
866 | #define AR_SREV_9485_10(_ah) \ | 867 | #define AR_SREV_9485_10(_ah) \ |
867 | (AR_SREV_9485(_ah) && \ | 868 | (AR_SREV_9485(_ah) && \ |
868 | ((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_10)) | 869 | ((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_10)) |
870 | #define AR_SREV_9485_11(_ah) \ | ||
871 | (AR_SREV_9485(_ah) && \ | ||
872 | ((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_11)) | ||
869 | 873 | ||
870 | #define AR_SREV_9285E_20(_ah) \ | 874 | #define AR_SREV_9285E_20(_ah) \ |
871 | (AR_SREV_9285_12_OR_LATER(_ah) && \ | 875 | (AR_SREV_9285_12_OR_LATER(_ah) && \ |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 9f4e755d27ce..e16136d61799 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -1055,6 +1055,7 @@ int ath_txq_update(struct ath_softc *sc, int qnum, | |||
1055 | int ath_cabq_update(struct ath_softc *sc) | 1055 | int ath_cabq_update(struct ath_softc *sc) |
1056 | { | 1056 | { |
1057 | struct ath9k_tx_queue_info qi; | 1057 | struct ath9k_tx_queue_info qi; |
1058 | struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; | ||
1058 | int qnum = sc->beacon.cabq->axq_qnum; | 1059 | int qnum = sc->beacon.cabq->axq_qnum; |
1059 | 1060 | ||
1060 | ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi); | 1061 | ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi); |
@@ -1066,7 +1067,7 @@ int ath_cabq_update(struct ath_softc *sc) | |||
1066 | else if (sc->config.cabqReadytime > ATH9K_READY_TIME_HI_BOUND) | 1067 | else if (sc->config.cabqReadytime > ATH9K_READY_TIME_HI_BOUND) |
1067 | sc->config.cabqReadytime = ATH9K_READY_TIME_HI_BOUND; | 1068 | sc->config.cabqReadytime = ATH9K_READY_TIME_HI_BOUND; |
1068 | 1069 | ||
1069 | qi.tqi_readyTime = (sc->beacon_interval * | 1070 | qi.tqi_readyTime = (cur_conf->beacon_interval * |
1070 | sc->config.cabqReadytime) / 100; | 1071 | sc->config.cabqReadytime) / 100; |
1071 | ath_txq_update(sc, qnum, &qi); | 1072 | ath_txq_update(sc, qnum, &qi); |
1072 | 1073 | ||
@@ -2013,7 +2014,8 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2013 | spin_lock_bh(&txq->axq_lock); | 2014 | spin_lock_bh(&txq->axq_lock); |
2014 | if (list_empty(&txq->axq_q)) { | 2015 | if (list_empty(&txq->axq_q)) { |
2015 | txq->axq_link = NULL; | 2016 | txq->axq_link = NULL; |
2016 | if (sc->sc_flags & SC_OP_TXAGGR) | 2017 | if (sc->sc_flags & SC_OP_TXAGGR && |
2018 | !txq->txq_flush_inprogress) | ||
2017 | ath_txq_schedule(sc, txq); | 2019 | ath_txq_schedule(sc, txq); |
2018 | spin_unlock_bh(&txq->axq_lock); | 2020 | spin_unlock_bh(&txq->axq_lock); |
2019 | break; | 2021 | break; |
@@ -2070,6 +2072,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2070 | 2072 | ||
2071 | if (bf_is_ampdu_not_probing(bf)) | 2073 | if (bf_is_ampdu_not_probing(bf)) |
2072 | txq->axq_ampdu_depth--; | 2074 | txq->axq_ampdu_depth--; |
2075 | |||
2073 | spin_unlock_bh(&txq->axq_lock); | 2076 | spin_unlock_bh(&txq->axq_lock); |
2074 | 2077 | ||
2075 | if (bf_held) | 2078 | if (bf_held) |
@@ -2093,7 +2096,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2093 | 2096 | ||
2094 | spin_lock_bh(&txq->axq_lock); | 2097 | spin_lock_bh(&txq->axq_lock); |
2095 | 2098 | ||
2096 | if (sc->sc_flags & SC_OP_TXAGGR) | 2099 | if (sc->sc_flags & SC_OP_TXAGGR && !txq->txq_flush_inprogress) |
2097 | ath_txq_schedule(sc, txq); | 2100 | ath_txq_schedule(sc, txq); |
2098 | spin_unlock_bh(&txq->axq_lock); | 2101 | spin_unlock_bh(&txq->axq_lock); |
2099 | } | 2102 | } |
@@ -2264,15 +2267,18 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) | |||
2264 | 2267 | ||
2265 | spin_lock_bh(&txq->axq_lock); | 2268 | spin_lock_bh(&txq->axq_lock); |
2266 | 2269 | ||
2267 | if (!list_empty(&txq->txq_fifo_pending)) { | 2270 | if (!txq->txq_flush_inprogress) { |
2268 | INIT_LIST_HEAD(&bf_head); | 2271 | if (!list_empty(&txq->txq_fifo_pending)) { |
2269 | bf = list_first_entry(&txq->txq_fifo_pending, | 2272 | INIT_LIST_HEAD(&bf_head); |
2270 | struct ath_buf, list); | 2273 | bf = list_first_entry(&txq->txq_fifo_pending, |
2271 | list_cut_position(&bf_head, &txq->txq_fifo_pending, | 2274 | struct ath_buf, list); |
2272 | &bf->bf_lastbf->list); | 2275 | list_cut_position(&bf_head, |
2273 | ath_tx_txqaddbuf(sc, txq, &bf_head); | 2276 | &txq->txq_fifo_pending, |
2274 | } else if (sc->sc_flags & SC_OP_TXAGGR) | 2277 | &bf->bf_lastbf->list); |
2275 | ath_txq_schedule(sc, txq); | 2278 | ath_tx_txqaddbuf(sc, txq, &bf_head); |
2279 | } else if (sc->sc_flags & SC_OP_TXAGGR) | ||
2280 | ath_txq_schedule(sc, txq); | ||
2281 | } | ||
2276 | spin_unlock_bh(&txq->axq_lock); | 2282 | spin_unlock_bh(&txq->axq_lock); |
2277 | } | 2283 | } |
2278 | } | 2284 | } |
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 3c5dd36ff417..30483e27ce5c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c | |||
@@ -265,7 +265,8 @@ static struct iwl_lib_ops iwl2000_lib = { | |||
265 | .txq_free_tfd = iwl_hw_txq_free_tfd, | 265 | .txq_free_tfd = iwl_hw_txq_free_tfd, |
266 | .txq_init = iwl_hw_tx_queue_init, | 266 | .txq_init = iwl_hw_tx_queue_init, |
267 | .rx_handler_setup = iwlagn_rx_handler_setup, | 267 | .rx_handler_setup = iwlagn_rx_handler_setup, |
268 | .setup_deferred_work = iwlagn_setup_deferred_work, | 268 | .setup_deferred_work = iwlagn_bt_setup_deferred_work, |
269 | .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, | ||
269 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, | 270 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, |
270 | .load_ucode = iwlagn_load_ucode, | 271 | .load_ucode = iwlagn_load_ucode, |
271 | .dump_nic_event_log = iwl_dump_nic_event_log, | 272 | .dump_nic_event_log = iwl_dump_nic_event_log, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 3aa486437509..325ff5c89ee8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c | |||
@@ -1832,7 +1832,7 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) | |||
1832 | * IBSS mode (no proper uCode support for coex then). | 1832 | * IBSS mode (no proper uCode support for coex then). |
1833 | */ | 1833 | */ |
1834 | if (!bt_coex_active || priv->iw_mode == NL80211_IFTYPE_ADHOC) { | 1834 | if (!bt_coex_active || priv->iw_mode == NL80211_IFTYPE_ADHOC) { |
1835 | bt_cmd.flags = 0; | 1835 | bt_cmd.flags = IWLAGN_BT_FLAG_COEX_MODE_DISABLED; |
1836 | } else { | 1836 | } else { |
1837 | bt_cmd.flags = IWLAGN_BT_FLAG_COEX_MODE_3W << | 1837 | bt_cmd.flags = IWLAGN_BT_FLAG_COEX_MODE_3W << |
1838 | IWLAGN_BT_FLAG_COEX_MODE_SHIFT; | 1838 | IWLAGN_BT_FLAG_COEX_MODE_SHIFT; |
@@ -1869,6 +1869,11 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) | |||
1869 | struct iwl_rxon_context *ctx; | 1869 | struct iwl_rxon_context *ctx; |
1870 | int smps_request = -1; | 1870 | int smps_request = -1; |
1871 | 1871 | ||
1872 | if (priv->bt_enable_flag == IWLAGN_BT_FLAG_COEX_MODE_DISABLED) { | ||
1873 | /* bt coex disabled */ | ||
1874 | return; | ||
1875 | } | ||
1876 | |||
1872 | /* | 1877 | /* |
1873 | * Note: bt_traffic_load can be overridden by scan complete and | 1878 | * Note: bt_traffic_load can be overridden by scan complete and |
1874 | * coex profile notifications. Ignore that since only bad consequence | 1879 | * coex profile notifications. Ignore that since only bad consequence |
@@ -2022,6 +2027,11 @@ void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, | |||
2022 | struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif; | 2027 | struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif; |
2023 | struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg; | 2028 | struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg; |
2024 | 2029 | ||
2030 | if (priv->bt_enable_flag == IWLAGN_BT_FLAG_COEX_MODE_DISABLED) { | ||
2031 | /* bt coex disabled */ | ||
2032 | return; | ||
2033 | } | ||
2034 | |||
2025 | IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n"); | 2035 | IWL_DEBUG_NOTIF(priv, "BT Coex notification:\n"); |
2026 | IWL_DEBUG_NOTIF(priv, " status: %d\n", coex->bt_status); | 2036 | IWL_DEBUG_NOTIF(priv, " status: %d\n", coex->bt_status); |
2027 | IWL_DEBUG_NOTIF(priv, " traffic load: %d\n", coex->bt_traffic_load); | 2037 | IWL_DEBUG_NOTIF(priv, " traffic load: %d\n", coex->bt_traffic_load); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 8ee810f5fc06..abd0461bd307 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -1413,34 +1413,42 @@ static void iwl_irq_tasklet(struct iwl_priv *priv) | |||
1413 | /** | 1413 | /** |
1414 | * iwl_good_ack_health - checks for ACK count ratios, BA timeout retries. | 1414 | * iwl_good_ack_health - checks for ACK count ratios, BA timeout retries. |
1415 | * | 1415 | * |
1416 | * When the ACK count ratio is 0 and aggregated BA timeout retries exceeding | 1416 | * When the ACK count ratio is low and aggregated BA timeout retries exceeding |
1417 | * the BA_TIMEOUT_MAX, reload firmware and bring system back to normal | 1417 | * the BA_TIMEOUT_MAX, reload firmware and bring system back to normal |
1418 | * operation state. | 1418 | * operation state. |
1419 | */ | 1419 | */ |
1420 | bool iwl_good_ack_health(struct iwl_priv *priv, | 1420 | bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt) |
1421 | struct iwl_rx_packet *pkt) | ||
1422 | { | 1421 | { |
1423 | bool rc = true; | 1422 | int actual_delta, expected_delta, ba_timeout_delta; |
1424 | int actual_ack_cnt_delta, expected_ack_cnt_delta; | 1423 | struct statistics_tx *cur, *old; |
1425 | int ba_timeout_delta; | 1424 | |
1426 | 1425 | if (priv->_agn.agg_tids_count) | |
1427 | actual_ack_cnt_delta = | 1426 | return true; |
1428 | le32_to_cpu(pkt->u.stats.tx.actual_ack_cnt) - | 1427 | |
1429 | le32_to_cpu(priv->_agn.statistics.tx.actual_ack_cnt); | 1428 | if (iwl_bt_statistics(priv)) { |
1430 | expected_ack_cnt_delta = | 1429 | cur = &pkt->u.stats_bt.tx; |
1431 | le32_to_cpu(pkt->u.stats.tx.expected_ack_cnt) - | 1430 | old = &priv->_agn.statistics_bt.tx; |
1432 | le32_to_cpu(priv->_agn.statistics.tx.expected_ack_cnt); | 1431 | } else { |
1433 | ba_timeout_delta = | 1432 | cur = &pkt->u.stats.tx; |
1434 | le32_to_cpu(pkt->u.stats.tx.agg.ba_timeout) - | 1433 | old = &priv->_agn.statistics.tx; |
1435 | le32_to_cpu(priv->_agn.statistics.tx.agg.ba_timeout); | 1434 | } |
1436 | if ((priv->_agn.agg_tids_count > 0) && | 1435 | |
1437 | (expected_ack_cnt_delta > 0) && | 1436 | actual_delta = le32_to_cpu(cur->actual_ack_cnt) - |
1438 | (((actual_ack_cnt_delta * 100) / expected_ack_cnt_delta) | 1437 | le32_to_cpu(old->actual_ack_cnt); |
1439 | < ACK_CNT_RATIO) && | 1438 | expected_delta = le32_to_cpu(cur->expected_ack_cnt) - |
1440 | (ba_timeout_delta > BA_TIMEOUT_CNT)) { | 1439 | le32_to_cpu(old->expected_ack_cnt); |
1441 | IWL_DEBUG_RADIO(priv, "actual_ack_cnt delta = %d," | 1440 | |
1442 | " expected_ack_cnt = %d\n", | 1441 | /* Values should not be negative, but we do not trust the firmware */ |
1443 | actual_ack_cnt_delta, expected_ack_cnt_delta); | 1442 | if (actual_delta <= 0 || expected_delta <= 0) |
1443 | return true; | ||
1444 | |||
1445 | ba_timeout_delta = le32_to_cpu(cur->agg.ba_timeout) - | ||
1446 | le32_to_cpu(old->agg.ba_timeout); | ||
1447 | |||
1448 | if ((actual_delta * 100 / expected_delta) < ACK_CNT_RATIO && | ||
1449 | ba_timeout_delta > BA_TIMEOUT_CNT) { | ||
1450 | IWL_DEBUG_RADIO(priv, "deltas: actual %d expected %d ba_timeout %d\n", | ||
1451 | actual_delta, expected_delta, ba_timeout_delta); | ||
1444 | 1452 | ||
1445 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 1453 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
1446 | /* | 1454 | /* |
@@ -1448,20 +1456,18 @@ bool iwl_good_ack_health(struct iwl_priv *priv, | |||
1448 | * statistics aren't available. If DEBUGFS is set but | 1456 | * statistics aren't available. If DEBUGFS is set but |
1449 | * DEBUG is not, these will just compile out. | 1457 | * DEBUG is not, these will just compile out. |
1450 | */ | 1458 | */ |
1451 | IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta = %d\n", | 1459 | IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta %d\n", |
1452 | priv->_agn.delta_statistics.tx.rx_detected_cnt); | 1460 | priv->_agn.delta_statistics.tx.rx_detected_cnt); |
1453 | IWL_DEBUG_RADIO(priv, | 1461 | IWL_DEBUG_RADIO(priv, |
1454 | "ack_or_ba_timeout_collision delta = %d\n", | 1462 | "ack_or_ba_timeout_collision delta %d\n", |
1455 | priv->_agn.delta_statistics.tx. | 1463 | priv->_agn.delta_statistics.tx.ack_or_ba_timeout_collision); |
1456 | ack_or_ba_timeout_collision); | ||
1457 | #endif | 1464 | #endif |
1458 | IWL_DEBUG_RADIO(priv, "agg ba_timeout delta = %d\n", | 1465 | |
1459 | ba_timeout_delta); | 1466 | if (ba_timeout_delta >= BA_TIMEOUT_MAX) |
1460 | if (!actual_ack_cnt_delta && | 1467 | return false; |
1461 | (ba_timeout_delta >= BA_TIMEOUT_MAX)) | ||
1462 | rc = false; | ||
1463 | } | 1468 | } |
1464 | return rc; | 1469 | |
1470 | return true; | ||
1465 | } | 1471 | } |
1466 | 1472 | ||
1467 | 1473 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 87a6fd84d4d2..bc89393fb696 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
@@ -234,33 +234,20 @@ EXPORT_SYMBOL(iwl_rx_spectrum_measure_notif); | |||
234 | void iwl_recover_from_statistics(struct iwl_priv *priv, | 234 | void iwl_recover_from_statistics(struct iwl_priv *priv, |
235 | struct iwl_rx_packet *pkt) | 235 | struct iwl_rx_packet *pkt) |
236 | { | 236 | { |
237 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 237 | if (test_bit(STATUS_EXIT_PENDING, &priv->status) || |
238 | !iwl_is_any_associated(priv)) | ||
238 | return; | 239 | return; |
239 | if (iwl_is_any_associated(priv)) { | 240 | |
240 | if (priv->cfg->ops->lib->check_ack_health) { | 241 | if (priv->cfg->ops->lib->check_ack_health && |
241 | if (!priv->cfg->ops->lib->check_ack_health( | 242 | !priv->cfg->ops->lib->check_ack_health(priv, pkt)) { |
242 | priv, pkt)) { | 243 | IWL_ERR(priv, "low ack count detected, restart firmware\n"); |
243 | /* | 244 | if (!iwl_force_reset(priv, IWL_FW_RESET, false)) |
244 | * low ack count detected | 245 | return; |
245 | * restart Firmware | ||
246 | */ | ||
247 | IWL_ERR(priv, "low ack count detected, " | ||
248 | "restart firmware\n"); | ||
249 | if (!iwl_force_reset(priv, IWL_FW_RESET, false)) | ||
250 | return; | ||
251 | } | ||
252 | } | ||
253 | if (priv->cfg->ops->lib->check_plcp_health) { | ||
254 | if (!priv->cfg->ops->lib->check_plcp_health( | ||
255 | priv, pkt)) { | ||
256 | /* | ||
257 | * high plcp error detected | ||
258 | * reset Radio | ||
259 | */ | ||
260 | iwl_force_reset(priv, IWL_RF_RESET, false); | ||
261 | } | ||
262 | } | ||
263 | } | 246 | } |
247 | |||
248 | if (priv->cfg->ops->lib->check_plcp_health && | ||
249 | !priv->cfg->ops->lib->check_plcp_health(priv, pkt)) | ||
250 | iwl_force_reset(priv, IWL_RF_RESET, false); | ||
264 | } | 251 | } |
265 | EXPORT_SYMBOL(iwl_recover_from_statistics); | 252 | EXPORT_SYMBOL(iwl_recover_from_statistics); |
266 | 253 | ||
diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c index 35b09aa0529b..f54e15fcd623 100644 --- a/drivers/net/wireless/p54/eeprom.c +++ b/drivers/net/wireless/p54/eeprom.c | |||
@@ -55,6 +55,17 @@ static struct ieee80211_rate p54_arates[] = { | |||
55 | { .bitrate = 540, .hw_value = 11, }, | 55 | { .bitrate = 540, .hw_value = 11, }, |
56 | }; | 56 | }; |
57 | 57 | ||
58 | static struct p54_rssi_db_entry p54_rssi_default = { | ||
59 | /* | ||
60 | * The defaults are taken from usb-logs of the | ||
61 | * vendor driver. So, they should be safe to | ||
62 | * use in case we can't get a match from the | ||
63 | * rssi <-> dBm conversion database. | ||
64 | */ | ||
65 | .mul = 130, | ||
66 | .add = -398, | ||
67 | }; | ||
68 | |||
58 | #define CHAN_HAS_CAL BIT(0) | 69 | #define CHAN_HAS_CAL BIT(0) |
59 | #define CHAN_HAS_LIMIT BIT(1) | 70 | #define CHAN_HAS_LIMIT BIT(1) |
60 | #define CHAN_HAS_CURVE BIT(2) | 71 | #define CHAN_HAS_CURVE BIT(2) |
@@ -87,13 +98,27 @@ static int p54_get_band_from_freq(u16 freq) | |||
87 | return -1; | 98 | return -1; |
88 | } | 99 | } |
89 | 100 | ||
101 | static int same_band(u16 freq, u16 freq2) | ||
102 | { | ||
103 | return p54_get_band_from_freq(freq) == p54_get_band_from_freq(freq2); | ||
104 | } | ||
105 | |||
90 | static int p54_compare_channels(const void *_a, | 106 | static int p54_compare_channels(const void *_a, |
91 | const void *_b) | 107 | const void *_b) |
92 | { | 108 | { |
93 | const struct p54_channel_entry *a = _a; | 109 | const struct p54_channel_entry *a = _a; |
94 | const struct p54_channel_entry *b = _b; | 110 | const struct p54_channel_entry *b = _b; |
95 | 111 | ||
96 | return a->index - b->index; | 112 | return a->freq - b->freq; |
113 | } | ||
114 | |||
115 | static int p54_compare_rssichan(const void *_a, | ||
116 | const void *_b) | ||
117 | { | ||
118 | const struct p54_rssi_db_entry *a = _a; | ||
119 | const struct p54_rssi_db_entry *b = _b; | ||
120 | |||
121 | return a->freq - b->freq; | ||
97 | } | 122 | } |
98 | 123 | ||
99 | static int p54_fill_band_bitrates(struct ieee80211_hw *dev, | 124 | static int p54_fill_band_bitrates(struct ieee80211_hw *dev, |
@@ -145,25 +170,26 @@ static int p54_generate_band(struct ieee80211_hw *dev, | |||
145 | 170 | ||
146 | for (i = 0, j = 0; (j < list->band_channel_num[band]) && | 171 | for (i = 0, j = 0; (j < list->band_channel_num[band]) && |
147 | (i < list->entries); i++) { | 172 | (i < list->entries); i++) { |
173 | struct p54_channel_entry *chan = &list->channels[i]; | ||
148 | 174 | ||
149 | if (list->channels[i].band != band) | 175 | if (chan->band != band) |
150 | continue; | 176 | continue; |
151 | 177 | ||
152 | if (list->channels[i].data != CHAN_HAS_ALL) { | 178 | if (chan->data != CHAN_HAS_ALL) { |
153 | wiphy_err(dev->wiphy, | 179 | wiphy_err(dev->wiphy, "%s%s%s is/are missing for " |
154 | "%s%s%s is/are missing for channel:%d [%d MHz].\n", | 180 | "channel:%d [%d MHz].\n", |
155 | (list->channels[i].data & CHAN_HAS_CAL ? "" : | 181 | (chan->data & CHAN_HAS_CAL ? "" : |
156 | " [iqauto calibration data]"), | 182 | " [iqauto calibration data]"), |
157 | (list->channels[i].data & CHAN_HAS_LIMIT ? "" : | 183 | (chan->data & CHAN_HAS_LIMIT ? "" : |
158 | " [output power limits]"), | 184 | " [output power limits]"), |
159 | (list->channels[i].data & CHAN_HAS_CURVE ? "" : | 185 | (chan->data & CHAN_HAS_CURVE ? "" : |
160 | " [curve data]"), | 186 | " [curve data]"), |
161 | list->channels[i].index, list->channels[i].freq); | 187 | chan->index, chan->freq); |
162 | continue; | 188 | continue; |
163 | } | 189 | } |
164 | 190 | ||
165 | tmp->channels[j].band = list->channels[i].band; | 191 | tmp->channels[j].band = chan->band; |
166 | tmp->channels[j].center_freq = list->channels[i].freq; | 192 | tmp->channels[j].center_freq = chan->freq; |
167 | j++; | 193 | j++; |
168 | } | 194 | } |
169 | 195 | ||
@@ -291,7 +317,7 @@ static int p54_generate_channel_lists(struct ieee80211_hw *dev) | |||
291 | } | 317 | } |
292 | } | 318 | } |
293 | 319 | ||
294 | /* sort the list by the channel index */ | 320 | /* sort the channel list by frequency */ |
295 | sort(list->channels, list->entries, sizeof(struct p54_channel_entry), | 321 | sort(list->channels, list->entries, sizeof(struct p54_channel_entry), |
296 | p54_compare_channels, NULL); | 322 | p54_compare_channels, NULL); |
297 | 323 | ||
@@ -410,33 +436,118 @@ static int p54_convert_rev1(struct ieee80211_hw *dev, | |||
410 | static const char *p54_rf_chips[] = { "INVALID-0", "Duette3", "Duette2", | 436 | static const char *p54_rf_chips[] = { "INVALID-0", "Duette3", "Duette2", |
411 | "Frisbee", "Xbow", "Longbow", "INVALID-6", "INVALID-7" }; | 437 | "Frisbee", "Xbow", "Longbow", "INVALID-6", "INVALID-7" }; |
412 | 438 | ||
413 | static void p54_parse_rssical(struct ieee80211_hw *dev, void *data, int len, | 439 | static int p54_parse_rssical(struct ieee80211_hw *dev, |
414 | u16 type) | 440 | u8 *data, int len, u16 type) |
415 | { | 441 | { |
416 | struct p54_common *priv = dev->priv; | 442 | struct p54_common *priv = dev->priv; |
417 | int offset = (type == PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) ? 2 : 0; | 443 | struct p54_rssi_db_entry *entry; |
418 | int entry_size = sizeof(struct pda_rssi_cal_entry) + offset; | 444 | size_t db_len, entries; |
419 | int num_entries = (type == PDR_RSSI_LINEAR_APPROXIMATION) ? 1 : 2; | 445 | int offset = 0, i; |
420 | int i; | 446 | |
447 | if (type != PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) { | ||
448 | entries = (type == PDR_RSSI_LINEAR_APPROXIMATION) ? 1 : 2; | ||
449 | if (len != sizeof(struct pda_rssi_cal_entry) * entries) { | ||
450 | wiphy_err(dev->wiphy, "rssical size mismatch.\n"); | ||
451 | goto err_data; | ||
452 | } | ||
453 | } else { | ||
454 | /* | ||
455 | * Some devices (Dell 1450 USB, Xbow 5GHz card, etc...) | ||
456 | * have an empty two byte header. | ||
457 | */ | ||
458 | if (*((__le16 *)&data[offset]) == cpu_to_le16(0)) | ||
459 | offset += 2; | ||
421 | 460 | ||
422 | if (len != (entry_size * num_entries)) { | 461 | entries = (len - offset) / |
423 | wiphy_err(dev->wiphy, | 462 | sizeof(struct pda_rssi_cal_ext_entry); |
424 | "unknown rssi calibration data packing type:(%x) len:%d.\n", | ||
425 | type, len); | ||
426 | 463 | ||
427 | print_hex_dump_bytes("rssical:", DUMP_PREFIX_NONE, | 464 | if ((len - offset) % sizeof(struct pda_rssi_cal_ext_entry) || |
428 | data, len); | 465 | entries <= 0) { |
466 | wiphy_err(dev->wiphy, "invalid rssi database.\n"); | ||
467 | goto err_data; | ||
468 | } | ||
469 | } | ||
429 | 470 | ||
430 | wiphy_err(dev->wiphy, "please report this issue.\n"); | 471 | db_len = sizeof(*entry) * entries; |
431 | return; | 472 | priv->rssi_db = kzalloc(db_len + sizeof(*priv->rssi_db), GFP_KERNEL); |
473 | if (!priv->rssi_db) | ||
474 | return -ENOMEM; | ||
475 | |||
476 | priv->rssi_db->offset = 0; | ||
477 | priv->rssi_db->entries = entries; | ||
478 | priv->rssi_db->entry_size = sizeof(*entry); | ||
479 | priv->rssi_db->len = db_len; | ||
480 | |||
481 | entry = (void *)((unsigned long)priv->rssi_db->data + priv->rssi_db->offset); | ||
482 | if (type == PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) { | ||
483 | struct pda_rssi_cal_ext_entry *cal = (void *) &data[offset]; | ||
484 | |||
485 | for (i = 0; i < entries; i++) { | ||
486 | entry[i].freq = le16_to_cpu(cal[i].freq); | ||
487 | entry[i].mul = (s16) le16_to_cpu(cal[i].mul); | ||
488 | entry[i].add = (s16) le16_to_cpu(cal[i].add); | ||
489 | } | ||
490 | } else { | ||
491 | struct pda_rssi_cal_entry *cal = (void *) &data[offset]; | ||
492 | |||
493 | for (i = 0; i < entries; i++) { | ||
494 | u16 freq; | ||
495 | switch (i) { | ||
496 | case IEEE80211_BAND_2GHZ: | ||
497 | freq = 2437; | ||
498 | break; | ||
499 | case IEEE80211_BAND_5GHZ: | ||
500 | freq = 5240; | ||
501 | break; | ||
502 | } | ||
503 | |||
504 | entry[i].freq = freq; | ||
505 | entry[i].mul = (s16) le16_to_cpu(cal[i].mul); | ||
506 | entry[i].add = (s16) le16_to_cpu(cal[i].add); | ||
507 | } | ||
432 | } | 508 | } |
433 | 509 | ||
434 | for (i = 0; i < num_entries; i++) { | 510 | /* sort the list by channel frequency */ |
435 | struct pda_rssi_cal_entry *cal = data + | 511 | sort(entry, entries, sizeof(*entry), p54_compare_rssichan, NULL); |
436 | (offset + i * entry_size); | 512 | return 0; |
437 | priv->rssical_db[i].mul = (s16) le16_to_cpu(cal->mul); | 513 | |
438 | priv->rssical_db[i].add = (s16) le16_to_cpu(cal->add); | 514 | err_data: |
515 | wiphy_err(dev->wiphy, | ||
516 | "rssi calibration data packing type:(%x) len:%d.\n", | ||
517 | type, len); | ||
518 | |||
519 | print_hex_dump_bytes("rssical:", DUMP_PREFIX_NONE, data, len); | ||
520 | |||
521 | wiphy_err(dev->wiphy, "please report this issue.\n"); | ||
522 | return -EINVAL; | ||
523 | } | ||
524 | |||
525 | struct p54_rssi_db_entry *p54_rssi_find(struct p54_common *priv, const u16 freq) | ||
526 | { | ||
527 | struct p54_rssi_db_entry *entry = (void *)(priv->rssi_db->data + | ||
528 | priv->rssi_db->offset); | ||
529 | int i, found = -1; | ||
530 | |||
531 | for (i = 0; i < priv->rssi_db->entries; i++) { | ||
532 | if (!same_band(freq, entry[i].freq)) | ||
533 | continue; | ||
534 | |||
535 | if (found == -1) { | ||
536 | found = i; | ||
537 | continue; | ||
538 | } | ||
539 | |||
540 | /* nearest match */ | ||
541 | if (abs(freq - entry[i].freq) < | ||
542 | abs(freq - entry[found].freq)) { | ||
543 | found = i; | ||
544 | continue; | ||
545 | } else { | ||
546 | break; | ||
547 | } | ||
439 | } | 548 | } |
549 | |||
550 | return found < 0 ? &p54_rssi_default : &entry[found]; | ||
440 | } | 551 | } |
441 | 552 | ||
442 | static void p54_parse_default_country(struct ieee80211_hw *dev, | 553 | static void p54_parse_default_country(struct ieee80211_hw *dev, |
@@ -627,21 +738,30 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) | |||
627 | case PDR_RSSI_LINEAR_APPROXIMATION: | 738 | case PDR_RSSI_LINEAR_APPROXIMATION: |
628 | case PDR_RSSI_LINEAR_APPROXIMATION_DUAL_BAND: | 739 | case PDR_RSSI_LINEAR_APPROXIMATION_DUAL_BAND: |
629 | case PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED: | 740 | case PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED: |
630 | p54_parse_rssical(dev, entry->data, data_len, | 741 | err = p54_parse_rssical(dev, entry->data, data_len, |
631 | le16_to_cpu(entry->code)); | 742 | le16_to_cpu(entry->code)); |
743 | if (err) | ||
744 | goto err; | ||
632 | break; | 745 | break; |
633 | case PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM: { | 746 | case PDR_RSSI_LINEAR_APPROXIMATION_CUSTOMV2: { |
634 | __le16 *src = (void *) entry->data; | 747 | struct pda_custom_wrapper *pda = (void *) entry->data; |
635 | s16 *dst = (void *) &priv->rssical_db; | 748 | __le16 *src; |
749 | u16 *dst; | ||
636 | int i; | 750 | int i; |
637 | 751 | ||
638 | if (data_len != sizeof(priv->rssical_db)) { | 752 | if (priv->rssi_db || data_len < sizeof(*pda)) |
639 | err = -EINVAL; | 753 | break; |
640 | goto err; | 754 | |
641 | } | 755 | priv->rssi_db = p54_convert_db(pda, data_len); |
642 | for (i = 0; i < sizeof(priv->rssical_db) / | 756 | if (!priv->rssi_db) |
643 | sizeof(*src); i++) | 757 | break; |
758 | |||
759 | src = (void *) priv->rssi_db->data; | ||
760 | dst = (void *) priv->rssi_db->data; | ||
761 | |||
762 | for (i = 0; i < priv->rssi_db->entries; i++) | ||
644 | *(dst++) = (s16) le16_to_cpu(*(src++)); | 763 | *(dst++) = (s16) le16_to_cpu(*(src++)); |
764 | |||
645 | } | 765 | } |
646 | break; | 766 | break; |
647 | case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM: { | 767 | case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM: { |
@@ -717,6 +837,8 @@ good_eeprom: | |||
717 | SET_IEEE80211_PERM_ADDR(dev, perm_addr); | 837 | SET_IEEE80211_PERM_ADDR(dev, perm_addr); |
718 | } | 838 | } |
719 | 839 | ||
840 | priv->cur_rssi = &p54_rssi_default; | ||
841 | |||
720 | wiphy_info(dev->wiphy, "hwaddr %pM, MAC:isl38%02x RF:%s\n", | 842 | wiphy_info(dev->wiphy, "hwaddr %pM, MAC:isl38%02x RF:%s\n", |
721 | dev->wiphy->perm_addr, priv->version, | 843 | dev->wiphy->perm_addr, priv->version, |
722 | p54_rf_chips[priv->rxhw]); | 844 | p54_rf_chips[priv->rxhw]); |
@@ -727,9 +849,11 @@ err: | |||
727 | kfree(priv->iq_autocal); | 849 | kfree(priv->iq_autocal); |
728 | kfree(priv->output_limit); | 850 | kfree(priv->output_limit); |
729 | kfree(priv->curve_data); | 851 | kfree(priv->curve_data); |
852 | kfree(priv->rssi_db); | ||
730 | priv->iq_autocal = NULL; | 853 | priv->iq_autocal = NULL; |
731 | priv->output_limit = NULL; | 854 | priv->output_limit = NULL; |
732 | priv->curve_data = NULL; | 855 | priv->curve_data = NULL; |
856 | priv->rssi_db = NULL; | ||
733 | 857 | ||
734 | wiphy_err(dev->wiphy, "eeprom parse failed!\n"); | 858 | wiphy_err(dev->wiphy, "eeprom parse failed!\n"); |
735 | return err; | 859 | return err; |
diff --git a/drivers/net/wireless/p54/eeprom.h b/drivers/net/wireless/p54/eeprom.h index 9051aef11249..afde72b84606 100644 --- a/drivers/net/wireless/p54/eeprom.h +++ b/drivers/net/wireless/p54/eeprom.h | |||
@@ -81,6 +81,12 @@ struct pda_pa_curve_data { | |||
81 | u8 data[0]; | 81 | u8 data[0]; |
82 | } __packed; | 82 | } __packed; |
83 | 83 | ||
84 | struct pda_rssi_cal_ext_entry { | ||
85 | __le16 freq; | ||
86 | __le16 mul; | ||
87 | __le16 add; | ||
88 | } __packed; | ||
89 | |||
84 | struct pda_rssi_cal_entry { | 90 | struct pda_rssi_cal_entry { |
85 | __le16 mul; | 91 | __le16 mul; |
86 | __le16 add; | 92 | __le16 add; |
@@ -179,6 +185,7 @@ struct pda_custom_wrapper { | |||
179 | 185 | ||
180 | /* used by our modificated eeprom image */ | 186 | /* used by our modificated eeprom image */ |
181 | #define PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM 0xDEAD | 187 | #define PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM 0xDEAD |
188 | #define PDR_RSSI_LINEAR_APPROXIMATION_CUSTOMV2 0xCAFF | ||
182 | #define PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM 0xBEEF | 189 | #define PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM 0xBEEF |
183 | #define PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM 0xB05D | 190 | #define PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM 0xB05D |
184 | 191 | ||
diff --git a/drivers/net/wireless/p54/fwio.c b/drivers/net/wireless/p54/fwio.c index 92b9b1f05fd5..0d3d108f6fe2 100644 --- a/drivers/net/wireless/p54/fwio.c +++ b/drivers/net/wireless/p54/fwio.c | |||
@@ -397,9 +397,9 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell) | |||
397 | union p54_scan_body_union *body; | 397 | union p54_scan_body_union *body; |
398 | struct p54_scan_tail_rate *rate; | 398 | struct p54_scan_tail_rate *rate; |
399 | struct pda_rssi_cal_entry *rssi; | 399 | struct pda_rssi_cal_entry *rssi; |
400 | struct p54_rssi_db_entry *rssi_data; | ||
400 | unsigned int i; | 401 | unsigned int i; |
401 | void *entry; | 402 | void *entry; |
402 | int band = priv->hw->conf.channel->band; | ||
403 | __le16 freq = cpu_to_le16(priv->hw->conf.channel->center_freq); | 403 | __le16 freq = cpu_to_le16(priv->hw->conf.channel->center_freq); |
404 | 404 | ||
405 | skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*head) + | 405 | skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*head) + |
@@ -503,13 +503,14 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell) | |||
503 | } | 503 | } |
504 | 504 | ||
505 | rssi = (struct pda_rssi_cal_entry *) skb_put(skb, sizeof(*rssi)); | 505 | rssi = (struct pda_rssi_cal_entry *) skb_put(skb, sizeof(*rssi)); |
506 | rssi->mul = cpu_to_le16(priv->rssical_db[band].mul); | 506 | rssi_data = p54_rssi_find(priv, le16_to_cpu(freq)); |
507 | rssi->add = cpu_to_le16(priv->rssical_db[band].add); | 507 | rssi->mul = cpu_to_le16(rssi_data->mul); |
508 | rssi->add = cpu_to_le16(rssi_data->add); | ||
508 | if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) { | 509 | if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) { |
509 | /* Longbow frontend needs ever more */ | 510 | /* Longbow frontend needs ever more */ |
510 | rssi = (void *) skb_put(skb, sizeof(*rssi)); | 511 | rssi = (void *) skb_put(skb, sizeof(*rssi)); |
511 | rssi->mul = cpu_to_le16(priv->rssical_db[band].longbow_unkn); | 512 | rssi->mul = cpu_to_le16(rssi_data->longbow_unkn); |
512 | rssi->add = cpu_to_le16(priv->rssical_db[band].longbow_unk2); | 513 | rssi->add = cpu_to_le16(rssi_data->longbow_unk2); |
513 | } | 514 | } |
514 | 515 | ||
515 | if (priv->fw_var >= 0x509) { | 516 | if (priv->fw_var >= 0x509) { |
@@ -523,6 +524,7 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell) | |||
523 | hdr->len = cpu_to_le16(skb->len - sizeof(*hdr)); | 524 | hdr->len = cpu_to_le16(skb->len - sizeof(*hdr)); |
524 | 525 | ||
525 | p54_tx(priv, skb); | 526 | p54_tx(priv, skb); |
527 | priv->cur_rssi = rssi_data; | ||
526 | return 0; | 528 | return 0; |
527 | 529 | ||
528 | err: | 530 | err: |
diff --git a/drivers/net/wireless/p54/lmac.h b/drivers/net/wireless/p54/lmac.h index 04b63ec80fa4..5ca117e6f95b 100644 --- a/drivers/net/wireless/p54/lmac.h +++ b/drivers/net/wireless/p54/lmac.h | |||
@@ -551,6 +551,7 @@ int p54_upload_key(struct p54_common *priv, u8 algo, int slot, | |||
551 | /* eeprom */ | 551 | /* eeprom */ |
552 | int p54_download_eeprom(struct p54_common *priv, void *buf, | 552 | int p54_download_eeprom(struct p54_common *priv, void *buf, |
553 | u16 offset, u16 len); | 553 | u16 offset, u16 len); |
554 | struct p54_rssi_db_entry *p54_rssi_find(struct p54_common *p, const u16 freq); | ||
554 | 555 | ||
555 | /* utility */ | 556 | /* utility */ |
556 | u8 *p54_find_ie(struct sk_buff *skb, u8 ie); | 557 | u8 *p54_find_ie(struct sk_buff *skb, u8 ie); |
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index 622d27b6d8f2..e14a05bbc485 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c | |||
@@ -524,6 +524,48 @@ static int p54_get_survey(struct ieee80211_hw *dev, int idx, | |||
524 | return 0; | 524 | return 0; |
525 | } | 525 | } |
526 | 526 | ||
527 | static unsigned int p54_flush_count(struct p54_common *priv) | ||
528 | { | ||
529 | unsigned int total = 0, i; | ||
530 | |||
531 | BUILD_BUG_ON(P54_QUEUE_NUM > ARRAY_SIZE(priv->tx_stats)); | ||
532 | |||
533 | /* | ||
534 | * Because the firmware has the sole control over any frames | ||
535 | * in the P54_QUEUE_BEACON or P54_QUEUE_SCAN queues, they | ||
536 | * don't really count as pending or active. | ||
537 | */ | ||
538 | for (i = P54_QUEUE_MGMT; i < P54_QUEUE_NUM; i++) | ||
539 | total += priv->tx_stats[i].len; | ||
540 | return total; | ||
541 | } | ||
542 | |||
543 | static void p54_flush(struct ieee80211_hw *dev, bool drop) | ||
544 | { | ||
545 | struct p54_common *priv = dev->priv; | ||
546 | unsigned int total, i; | ||
547 | |||
548 | /* | ||
549 | * Currently, it wouldn't really matter if we wait for one second | ||
550 | * or 15 minutes. But once someone gets around and completes the | ||
551 | * TODOs [ancel stuck frames / reset device] in p54_work, it will | ||
552 | * suddenly make sense to wait that long. | ||
553 | */ | ||
554 | i = P54_STATISTICS_UPDATE * 2 / 20; | ||
555 | |||
556 | /* | ||
557 | * In this case no locking is required because as we speak the | ||
558 | * queues have already been stopped and no new frames can sneak | ||
559 | * up from behind. | ||
560 | */ | ||
561 | while ((total = p54_flush_count(priv) && i--)) { | ||
562 | /* waste time */ | ||
563 | msleep(20); | ||
564 | } | ||
565 | |||
566 | WARN(total, "tx flush timeout, unresponsive firmware"); | ||
567 | } | ||
568 | |||
527 | static const struct ieee80211_ops p54_ops = { | 569 | static const struct ieee80211_ops p54_ops = { |
528 | .tx = p54_tx_80211, | 570 | .tx = p54_tx_80211, |
529 | .start = p54_start, | 571 | .start = p54_start, |
@@ -536,6 +578,7 @@ static const struct ieee80211_ops p54_ops = { | |||
536 | .sta_remove = p54_sta_add_remove, | 578 | .sta_remove = p54_sta_add_remove, |
537 | .set_key = p54_set_key, | 579 | .set_key = p54_set_key, |
538 | .config = p54_config, | 580 | .config = p54_config, |
581 | .flush = p54_flush, | ||
539 | .bss_info_changed = p54_bss_info_changed, | 582 | .bss_info_changed = p54_bss_info_changed, |
540 | .configure_filter = p54_configure_filter, | 583 | .configure_filter = p54_configure_filter, |
541 | .conf_tx = p54_conf_tx, | 584 | .conf_tx = p54_conf_tx, |
@@ -611,7 +654,7 @@ EXPORT_SYMBOL_GPL(p54_init_common); | |||
611 | 654 | ||
612 | int p54_register_common(struct ieee80211_hw *dev, struct device *pdev) | 655 | int p54_register_common(struct ieee80211_hw *dev, struct device *pdev) |
613 | { | 656 | { |
614 | struct p54_common *priv = dev->priv; | 657 | struct p54_common __maybe_unused *priv = dev->priv; |
615 | int err; | 658 | int err; |
616 | 659 | ||
617 | err = ieee80211_register_hw(dev); | 660 | err = ieee80211_register_hw(dev); |
@@ -642,10 +685,12 @@ void p54_free_common(struct ieee80211_hw *dev) | |||
642 | kfree(priv->iq_autocal); | 685 | kfree(priv->iq_autocal); |
643 | kfree(priv->output_limit); | 686 | kfree(priv->output_limit); |
644 | kfree(priv->curve_data); | 687 | kfree(priv->curve_data); |
688 | kfree(priv->rssi_db); | ||
645 | kfree(priv->used_rxkeys); | 689 | kfree(priv->used_rxkeys); |
646 | priv->iq_autocal = NULL; | 690 | priv->iq_autocal = NULL; |
647 | priv->output_limit = NULL; | 691 | priv->output_limit = NULL; |
648 | priv->curve_data = NULL; | 692 | priv->curve_data = NULL; |
693 | priv->rssi_db = NULL; | ||
649 | priv->used_rxkeys = NULL; | 694 | priv->used_rxkeys = NULL; |
650 | ieee80211_free_hw(dev); | 695 | ieee80211_free_hw(dev); |
651 | } | 696 | } |
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h index 43a3b2ead81a..f951c8f31863 100644 --- a/drivers/net/wireless/p54/p54.h +++ b/drivers/net/wireless/p54/p54.h | |||
@@ -116,7 +116,8 @@ struct p54_edcf_queue_param { | |||
116 | __le16 txop; | 116 | __le16 txop; |
117 | } __packed; | 117 | } __packed; |
118 | 118 | ||
119 | struct p54_rssi_linear_approximation { | 119 | struct p54_rssi_db_entry { |
120 | u16 freq; | ||
120 | s16 mul; | 121 | s16 mul; |
121 | s16 add; | 122 | s16 add; |
122 | s16 longbow_unkn; | 123 | s16 longbow_unkn; |
@@ -197,13 +198,14 @@ struct p54_common { | |||
197 | u8 rx_diversity_mask; | 198 | u8 rx_diversity_mask; |
198 | u8 tx_diversity_mask; | 199 | u8 tx_diversity_mask; |
199 | unsigned int output_power; | 200 | unsigned int output_power; |
201 | struct p54_rssi_db_entry *cur_rssi; | ||
200 | int noise; | 202 | int noise; |
201 | /* calibration, output power limit and rssi<->dBm conversation data */ | 203 | /* calibration, output power limit and rssi<->dBm conversation data */ |
202 | struct pda_iq_autocal_entry *iq_autocal; | 204 | struct pda_iq_autocal_entry *iq_autocal; |
203 | unsigned int iq_autocal_len; | 205 | unsigned int iq_autocal_len; |
204 | struct p54_cal_database *curve_data; | 206 | struct p54_cal_database *curve_data; |
205 | struct p54_cal_database *output_limit; | 207 | struct p54_cal_database *output_limit; |
206 | struct p54_rssi_linear_approximation rssical_db[IEEE80211_NUM_BANDS]; | 208 | struct p54_cal_database *rssi_db; |
207 | struct ieee80211_supported_band *band_table[IEEE80211_NUM_BANDS]; | 209 | struct ieee80211_supported_band *band_table[IEEE80211_NUM_BANDS]; |
208 | 210 | ||
209 | /* BBP/MAC state */ | 211 | /* BBP/MAC state */ |
diff --git a/drivers/net/wireless/p54/p54spi_eeprom.h b/drivers/net/wireless/p54/p54spi_eeprom.h index d592cbd34d78..0b7bfb0adcf2 100644 --- a/drivers/net/wireless/p54/p54spi_eeprom.h +++ b/drivers/net/wireless/p54/p54spi_eeprom.h | |||
@@ -65,9 +65,10 @@ static unsigned char p54spi_eeprom[] = { | |||
65 | 0x03, 0x00, 0x00, 0x11, /* PDR_ANTENNA_GAIN */ | 65 | 0x03, 0x00, 0x00, 0x11, /* PDR_ANTENNA_GAIN */ |
66 | 0x08, 0x08, 0x08, 0x08, | 66 | 0x08, 0x08, 0x08, 0x08, |
67 | 67 | ||
68 | 0x09, 0x00, 0xad, 0xde, /* PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM */ | 68 | 0x0a, 0x00, 0xff, 0xca, /* PDR_RSSI_LINEAR_APPROXIMATION_CUSTOMV2 */ |
69 | 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, | 69 | 0x01, 0x00, 0x0a, 0x00, |
70 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 70 | 0x00, 0x00, 0x0a, 0x00, |
71 | 0x85, 0x09, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, | ||
71 | 72 | ||
72 | /* struct pda_custom_wrapper */ | 73 | /* struct pda_custom_wrapper */ |
73 | 0x10, 0x06, 0x5d, 0xb0, /* PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM */ | 74 | 0x10, 0x06, 0x5d, 0xb0, /* PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM */ |
@@ -671,7 +672,7 @@ static unsigned char p54spi_eeprom[] = { | |||
671 | 0xa8, 0x09, 0x25, 0x00, 0xf5, 0xff, 0xf9, 0xff, 0x00, 0x01, | 672 | 0xa8, 0x09, 0x25, 0x00, 0xf5, 0xff, 0xf9, 0xff, 0x00, 0x01, |
672 | 673 | ||
673 | 0x02, 0x00, 0x00, 0x00, /* PDR_END */ | 674 | 0x02, 0x00, 0x00, 0x00, /* PDR_END */ |
674 | 0x67, 0x99, | 675 | 0xb6, 0x04, |
675 | }; | 676 | }; |
676 | 677 | ||
677 | #endif /* P54SPI_EEPROM_H */ | 678 | #endif /* P54SPI_EEPROM_H */ |
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c index f618b9623e5a..917d5d948e3c 100644 --- a/drivers/net/wireless/p54/txrx.c +++ b/drivers/net/wireless/p54/txrx.c | |||
@@ -273,11 +273,9 @@ void p54_tx(struct p54_common *priv, struct sk_buff *skb) | |||
273 | 273 | ||
274 | static int p54_rssi_to_dbm(struct p54_common *priv, int rssi) | 274 | static int p54_rssi_to_dbm(struct p54_common *priv, int rssi) |
275 | { | 275 | { |
276 | int band = priv->hw->conf.channel->band; | ||
277 | |||
278 | if (priv->rxhw != 5) { | 276 | if (priv->rxhw != 5) { |
279 | return ((rssi * priv->rssical_db[band].mul) / 64 + | 277 | return ((rssi * priv->cur_rssi->mul) / 64 + |
280 | priv->rssical_db[band].add) / 4; | 278 | priv->cur_rssi->add) / 4; |
281 | } else { | 279 | } else { |
282 | /* | 280 | /* |
283 | * TODO: find the correct formula | 281 | * TODO: find the correct formula |
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index 6f383cd684b0..f630552427b7 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig | |||
@@ -97,6 +97,18 @@ config RT2800PCI_RT35XX | |||
97 | Support for these devices is non-functional at the moment and is | 97 | Support for these devices is non-functional at the moment and is |
98 | intended for testers and developers. | 98 | intended for testers and developers. |
99 | 99 | ||
100 | config RT2800PCI_RT53XX | ||
101 | bool "rt2800-pci - Include support for rt53xx devices (EXPERIMENTAL)" | ||
102 | depends on EXPERIMENTAL | ||
103 | default n | ||
104 | ---help--- | ||
105 | This adds support for rt53xx wireless chipset family to the | ||
106 | rt2800pci driver. | ||
107 | Supported chips: RT5390 | ||
108 | |||
109 | Support for these devices is non-functional at the moment and is | ||
110 | intended for testers and developers. | ||
111 | |||
100 | endif | 112 | endif |
101 | 113 | ||
102 | config RT2500USB | 114 | config RT2500USB |
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index ec8159ce0ee8..6f4a2432c021 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h | |||
@@ -51,6 +51,7 @@ | |||
51 | * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390) | 51 | * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390) |
52 | * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392) | 52 | * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392) |
53 | * RF3853 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662) | 53 | * RF3853 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662) |
54 | * RF5390 2.4G 1T1R | ||
54 | */ | 55 | */ |
55 | #define RF2820 0x0001 | 56 | #define RF2820 0x0001 |
56 | #define RF2850 0x0002 | 57 | #define RF2850 0x0002 |
@@ -65,6 +66,7 @@ | |||
65 | #define RF3320 0x000b | 66 | #define RF3320 0x000b |
66 | #define RF3322 0x000c | 67 | #define RF3322 0x000c |
67 | #define RF3853 0x000d | 68 | #define RF3853 0x000d |
69 | #define RF5390 0x5390 | ||
68 | 70 | ||
69 | /* | 71 | /* |
70 | * Chipset revisions. | 72 | * Chipset revisions. |
@@ -77,6 +79,7 @@ | |||
77 | #define REV_RT3071E 0x0211 | 79 | #define REV_RT3071E 0x0211 |
78 | #define REV_RT3090E 0x0211 | 80 | #define REV_RT3090E 0x0211 |
79 | #define REV_RT3390E 0x0211 | 81 | #define REV_RT3390E 0x0211 |
82 | #define REV_RT5390F 0x0502 | ||
80 | 83 | ||
81 | /* | 84 | /* |
82 | * Signal information. | 85 | * Signal information. |
@@ -121,6 +124,13 @@ | |||
121 | #define E2PROM_CSR_RELOAD FIELD32(0x00000080) | 124 | #define E2PROM_CSR_RELOAD FIELD32(0x00000080) |
122 | 125 | ||
123 | /* | 126 | /* |
127 | * AUX_CTRL: Aux/PCI-E related configuration | ||
128 | */ | ||
129 | #define AUX_CTRL 0x10c | ||
130 | #define AUX_CTRL_WAKE_PCIE_EN FIELD32(0x00000002) | ||
131 | #define AUX_CTRL_FORCE_PCIE_CLK FIELD32(0x00000400) | ||
132 | |||
133 | /* | ||
124 | * OPT_14: Unknown register used by rt3xxx devices. | 134 | * OPT_14: Unknown register used by rt3xxx devices. |
125 | */ | 135 | */ |
126 | #define OPT_14_CSR 0x0114 | 136 | #define OPT_14_CSR 0x0114 |
@@ -270,6 +280,7 @@ | |||
270 | 280 | ||
271 | /* | 281 | /* |
272 | * GPIO_CTRL_CFG: | 282 | * GPIO_CTRL_CFG: |
283 | * GPIOD: GPIO direction, 0: Output, 1: Input | ||
273 | */ | 284 | */ |
274 | #define GPIO_CTRL_CFG 0x0228 | 285 | #define GPIO_CTRL_CFG 0x0228 |
275 | #define GPIO_CTRL_CFG_BIT0 FIELD32(0x00000001) | 286 | #define GPIO_CTRL_CFG_BIT0 FIELD32(0x00000001) |
@@ -280,7 +291,14 @@ | |||
280 | #define GPIO_CTRL_CFG_BIT5 FIELD32(0x00000020) | 291 | #define GPIO_CTRL_CFG_BIT5 FIELD32(0x00000020) |
281 | #define GPIO_CTRL_CFG_BIT6 FIELD32(0x00000040) | 292 | #define GPIO_CTRL_CFG_BIT6 FIELD32(0x00000040) |
282 | #define GPIO_CTRL_CFG_BIT7 FIELD32(0x00000080) | 293 | #define GPIO_CTRL_CFG_BIT7 FIELD32(0x00000080) |
283 | #define GPIO_CTRL_CFG_BIT8 FIELD32(0x00000100) | 294 | #define GPIO_CTRL_CFG_GPIOD_BIT0 FIELD32(0x00000100) |
295 | #define GPIO_CTRL_CFG_GPIOD_BIT1 FIELD32(0x00000200) | ||
296 | #define GPIO_CTRL_CFG_GPIOD_BIT2 FIELD32(0x00000400) | ||
297 | #define GPIO_CTRL_CFG_GPIOD_BIT3 FIELD32(0x00000800) | ||
298 | #define GPIO_CTRL_CFG_GPIOD_BIT4 FIELD32(0x00001000) | ||
299 | #define GPIO_CTRL_CFG_GPIOD_BIT5 FIELD32(0x00002000) | ||
300 | #define GPIO_CTRL_CFG_GPIOD_BIT6 FIELD32(0x00004000) | ||
301 | #define GPIO_CTRL_CFG_GPIOD_BIT7 FIELD32(0x00008000) | ||
284 | 302 | ||
285 | /* | 303 | /* |
286 | * MCU_CMD_CFG | 304 | * MCU_CMD_CFG |
@@ -446,7 +464,7 @@ | |||
446 | */ | 464 | */ |
447 | #define RF_CSR_CFG 0x0500 | 465 | #define RF_CSR_CFG 0x0500 |
448 | #define RF_CSR_CFG_DATA FIELD32(0x000000ff) | 466 | #define RF_CSR_CFG_DATA FIELD32(0x000000ff) |
449 | #define RF_CSR_CFG_REGNUM FIELD32(0x00001f00) | 467 | #define RF_CSR_CFG_REGNUM FIELD32(0x00003f00) |
450 | #define RF_CSR_CFG_WRITE FIELD32(0x00010000) | 468 | #define RF_CSR_CFG_WRITE FIELD32(0x00010000) |
451 | #define RF_CSR_CFG_BUSY FIELD32(0x00020000) | 469 | #define RF_CSR_CFG_BUSY FIELD32(0x00020000) |
452 | 470 | ||
@@ -1136,8 +1154,8 @@ | |||
1136 | * PROTECT_RATE: Protection control frame rate for CCK TX(RTS/CTS/CFEnd) | 1154 | * PROTECT_RATE: Protection control frame rate for CCK TX(RTS/CTS/CFEnd) |
1137 | * PROTECT_CTRL: Protection control frame type for CCK TX | 1155 | * PROTECT_CTRL: Protection control frame type for CCK TX |
1138 | * 0:none, 1:RTS/CTS, 2:CTS-to-self | 1156 | * 0:none, 1:RTS/CTS, 2:CTS-to-self |
1139 | * PROTECT_NAV: TXOP protection type for CCK TX | 1157 | * PROTECT_NAV_SHORT: TXOP protection type for CCK TX with short NAV |
1140 | * 0:none, 1:ShortNAVprotect, 2:LongNAVProtect | 1158 | * PROTECT_NAV_LONG: TXOP protection type for CCK TX with long NAV |
1141 | * TX_OP_ALLOW_CCK: CCK TXOP allowance, 0:disallow | 1159 | * TX_OP_ALLOW_CCK: CCK TXOP allowance, 0:disallow |
1142 | * TX_OP_ALLOW_OFDM: CCK TXOP allowance, 0:disallow | 1160 | * TX_OP_ALLOW_OFDM: CCK TXOP allowance, 0:disallow |
1143 | * TX_OP_ALLOW_MM20: CCK TXOP allowance, 0:disallow | 1161 | * TX_OP_ALLOW_MM20: CCK TXOP allowance, 0:disallow |
@@ -1149,7 +1167,8 @@ | |||
1149 | #define CCK_PROT_CFG 0x1364 | 1167 | #define CCK_PROT_CFG 0x1364 |
1150 | #define CCK_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff) | 1168 | #define CCK_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff) |
1151 | #define CCK_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000) | 1169 | #define CCK_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000) |
1152 | #define CCK_PROT_CFG_PROTECT_NAV FIELD32(0x000c0000) | 1170 | #define CCK_PROT_CFG_PROTECT_NAV_SHORT FIELD32(0x00040000) |
1171 | #define CCK_PROT_CFG_PROTECT_NAV_LONG FIELD32(0x00080000) | ||
1153 | #define CCK_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000) | 1172 | #define CCK_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000) |
1154 | #define CCK_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000) | 1173 | #define CCK_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000) |
1155 | #define CCK_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000) | 1174 | #define CCK_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000) |
@@ -1164,7 +1183,8 @@ | |||
1164 | #define OFDM_PROT_CFG 0x1368 | 1183 | #define OFDM_PROT_CFG 0x1368 |
1165 | #define OFDM_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff) | 1184 | #define OFDM_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff) |
1166 | #define OFDM_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000) | 1185 | #define OFDM_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000) |
1167 | #define OFDM_PROT_CFG_PROTECT_NAV FIELD32(0x000c0000) | 1186 | #define OFDM_PROT_CFG_PROTECT_NAV_SHORT FIELD32(0x00040000) |
1187 | #define OFDM_PROT_CFG_PROTECT_NAV_LONG FIELD32(0x00080000) | ||
1168 | #define OFDM_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000) | 1188 | #define OFDM_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000) |
1169 | #define OFDM_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000) | 1189 | #define OFDM_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000) |
1170 | #define OFDM_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000) | 1190 | #define OFDM_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000) |
@@ -1179,7 +1199,8 @@ | |||
1179 | #define MM20_PROT_CFG 0x136c | 1199 | #define MM20_PROT_CFG 0x136c |
1180 | #define MM20_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff) | 1200 | #define MM20_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff) |
1181 | #define MM20_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000) | 1201 | #define MM20_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000) |
1182 | #define MM20_PROT_CFG_PROTECT_NAV FIELD32(0x000c0000) | 1202 | #define MM20_PROT_CFG_PROTECT_NAV_SHORT FIELD32(0x00040000) |
1203 | #define MM20_PROT_CFG_PROTECT_NAV_LONG FIELD32(0x00080000) | ||
1183 | #define MM20_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000) | 1204 | #define MM20_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000) |
1184 | #define MM20_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000) | 1205 | #define MM20_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000) |
1185 | #define MM20_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000) | 1206 | #define MM20_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000) |
@@ -1194,7 +1215,8 @@ | |||
1194 | #define MM40_PROT_CFG 0x1370 | 1215 | #define MM40_PROT_CFG 0x1370 |
1195 | #define MM40_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff) | 1216 | #define MM40_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff) |
1196 | #define MM40_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000) | 1217 | #define MM40_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000) |
1197 | #define MM40_PROT_CFG_PROTECT_NAV FIELD32(0x000c0000) | 1218 | #define MM40_PROT_CFG_PROTECT_NAV_SHORT FIELD32(0x00040000) |
1219 | #define MM40_PROT_CFG_PROTECT_NAV_LONG FIELD32(0x00080000) | ||
1198 | #define MM40_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000) | 1220 | #define MM40_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000) |
1199 | #define MM40_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000) | 1221 | #define MM40_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000) |
1200 | #define MM40_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000) | 1222 | #define MM40_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000) |
@@ -1209,7 +1231,8 @@ | |||
1209 | #define GF20_PROT_CFG 0x1374 | 1231 | #define GF20_PROT_CFG 0x1374 |
1210 | #define GF20_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff) | 1232 | #define GF20_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff) |
1211 | #define GF20_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000) | 1233 | #define GF20_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000) |
1212 | #define GF20_PROT_CFG_PROTECT_NAV FIELD32(0x000c0000) | 1234 | #define GF20_PROT_CFG_PROTECT_NAV_SHORT FIELD32(0x00040000) |
1235 | #define GF20_PROT_CFG_PROTECT_NAV_LONG FIELD32(0x00080000) | ||
1213 | #define GF20_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000) | 1236 | #define GF20_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000) |
1214 | #define GF20_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000) | 1237 | #define GF20_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000) |
1215 | #define GF20_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000) | 1238 | #define GF20_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000) |
@@ -1224,7 +1247,8 @@ | |||
1224 | #define GF40_PROT_CFG 0x1378 | 1247 | #define GF40_PROT_CFG 0x1378 |
1225 | #define GF40_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff) | 1248 | #define GF40_PROT_CFG_PROTECT_RATE FIELD32(0x0000ffff) |
1226 | #define GF40_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000) | 1249 | #define GF40_PROT_CFG_PROTECT_CTRL FIELD32(0x00030000) |
1227 | #define GF40_PROT_CFG_PROTECT_NAV FIELD32(0x000c0000) | 1250 | #define GF40_PROT_CFG_PROTECT_NAV_SHORT FIELD32(0x00040000) |
1251 | #define GF40_PROT_CFG_PROTECT_NAV_LONG FIELD32(0x00080000) | ||
1228 | #define GF40_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000) | 1252 | #define GF40_PROT_CFG_TX_OP_ALLOW_CCK FIELD32(0x00100000) |
1229 | #define GF40_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000) | 1253 | #define GF40_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000) |
1230 | #define GF40_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000) | 1254 | #define GF40_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000) |
@@ -1701,11 +1725,14 @@ struct mac_iveiv_entry { | |||
1701 | */ | 1725 | */ |
1702 | 1726 | ||
1703 | /* | 1727 | /* |
1704 | * BBP 1: TX Antenna & Power | 1728 | * BBP 1: TX Antenna & Power Control |
1705 | * POWER: 0 - normal, 1 - drop tx power by 6dBm, 2 - drop tx power by 12dBm, | 1729 | * POWER_CTRL: |
1706 | * 3 - increase tx power by 6dBm | 1730 | * 0 - normal, |
1731 | * 1 - drop tx power by 6dBm, | ||
1732 | * 2 - drop tx power by 12dBm, | ||
1733 | * 3 - increase tx power by 6dBm | ||
1707 | */ | 1734 | */ |
1708 | #define BBP1_TX_POWER FIELD8(0x07) | 1735 | #define BBP1_TX_POWER_CTRL FIELD8(0x07) |
1709 | #define BBP1_TX_ANTENNA FIELD8(0x18) | 1736 | #define BBP1_TX_ANTENNA FIELD8(0x18) |
1710 | 1737 | ||
1711 | /* | 1738 | /* |
@@ -1719,6 +1746,13 @@ struct mac_iveiv_entry { | |||
1719 | */ | 1746 | */ |
1720 | #define BBP4_TX_BF FIELD8(0x01) | 1747 | #define BBP4_TX_BF FIELD8(0x01) |
1721 | #define BBP4_BANDWIDTH FIELD8(0x18) | 1748 | #define BBP4_BANDWIDTH FIELD8(0x18) |
1749 | #define BBP4_MAC_IF_CTRL FIELD8(0x40) | ||
1750 | |||
1751 | /* | ||
1752 | * BBP 109 | ||
1753 | */ | ||
1754 | #define BBP109_TX0_POWER FIELD8(0x0f) | ||
1755 | #define BBP109_TX1_POWER FIELD8(0xf0) | ||
1722 | 1756 | ||
1723 | /* | 1757 | /* |
1724 | * BBP 138: Unknown | 1758 | * BBP 138: Unknown |
@@ -1729,6 +1763,11 @@ struct mac_iveiv_entry { | |||
1729 | #define BBP138_TX_DAC2 FIELD8(0x40) | 1763 | #define BBP138_TX_DAC2 FIELD8(0x40) |
1730 | 1764 | ||
1731 | /* | 1765 | /* |
1766 | * BBP 152: Rx Ant | ||
1767 | */ | ||
1768 | #define BBP152_RX_DEFAULT_ANT FIELD8(0x80) | ||
1769 | |||
1770 | /* | ||
1732 | * RFCSR registers | 1771 | * RFCSR registers |
1733 | * The wordsize of the RFCSR is 8 bits. | 1772 | * The wordsize of the RFCSR is 8 bits. |
1734 | */ | 1773 | */ |
@@ -1737,12 +1776,18 @@ struct mac_iveiv_entry { | |||
1737 | * RFCSR 1: | 1776 | * RFCSR 1: |
1738 | */ | 1777 | */ |
1739 | #define RFCSR1_RF_BLOCK_EN FIELD8(0x01) | 1778 | #define RFCSR1_RF_BLOCK_EN FIELD8(0x01) |
1779 | #define RFCSR1_PLL_PD FIELD8(0x02) | ||
1740 | #define RFCSR1_RX0_PD FIELD8(0x04) | 1780 | #define RFCSR1_RX0_PD FIELD8(0x04) |
1741 | #define RFCSR1_TX0_PD FIELD8(0x08) | 1781 | #define RFCSR1_TX0_PD FIELD8(0x08) |
1742 | #define RFCSR1_RX1_PD FIELD8(0x10) | 1782 | #define RFCSR1_RX1_PD FIELD8(0x10) |
1743 | #define RFCSR1_TX1_PD FIELD8(0x20) | 1783 | #define RFCSR1_TX1_PD FIELD8(0x20) |
1744 | 1784 | ||
1745 | /* | 1785 | /* |
1786 | * RFCSR 2: | ||
1787 | */ | ||
1788 | #define RFCSR2_RESCAL_EN FIELD8(0x80) | ||
1789 | |||
1790 | /* | ||
1746 | * RFCSR 6: | 1791 | * RFCSR 6: |
1747 | */ | 1792 | */ |
1748 | #define RFCSR6_R1 FIELD8(0x03) | 1793 | #define RFCSR6_R1 FIELD8(0x03) |
@@ -1754,6 +1799,11 @@ struct mac_iveiv_entry { | |||
1754 | #define RFCSR7_RF_TUNING FIELD8(0x01) | 1799 | #define RFCSR7_RF_TUNING FIELD8(0x01) |
1755 | 1800 | ||
1756 | /* | 1801 | /* |
1802 | * RFCSR 11: | ||
1803 | */ | ||
1804 | #define RFCSR11_R FIELD8(0x03) | ||
1805 | |||
1806 | /* | ||
1757 | * RFCSR 12: | 1807 | * RFCSR 12: |
1758 | */ | 1808 | */ |
1759 | #define RFCSR12_TX_POWER FIELD8(0x1f) | 1809 | #define RFCSR12_TX_POWER FIELD8(0x1f) |
@@ -1774,6 +1824,7 @@ struct mac_iveiv_entry { | |||
1774 | #define RFCSR17_TXMIXER_GAIN FIELD8(0x07) | 1824 | #define RFCSR17_TXMIXER_GAIN FIELD8(0x07) |
1775 | #define RFCSR17_TX_LO1_EN FIELD8(0x08) | 1825 | #define RFCSR17_TX_LO1_EN FIELD8(0x08) |
1776 | #define RFCSR17_R FIELD8(0x20) | 1826 | #define RFCSR17_R FIELD8(0x20) |
1827 | #define RFCSR17_CODE FIELD8(0x7f) | ||
1777 | 1828 | ||
1778 | /* | 1829 | /* |
1779 | * RFCSR 20: | 1830 | * RFCSR 20: |
@@ -1806,6 +1857,9 @@ struct mac_iveiv_entry { | |||
1806 | /* | 1857 | /* |
1807 | * RFCSR 30: | 1858 | * RFCSR 30: |
1808 | */ | 1859 | */ |
1860 | #define RFCSR30_TX_H20M FIELD8(0x02) | ||
1861 | #define RFCSR30_RX_H20M FIELD8(0x04) | ||
1862 | #define RFCSR30_RX_VCM FIELD8(0x18) | ||
1809 | #define RFCSR30_RF_CALIBRATION FIELD8(0x80) | 1863 | #define RFCSR30_RF_CALIBRATION FIELD8(0x80) |
1810 | 1864 | ||
1811 | /* | 1865 | /* |
@@ -1815,6 +1869,21 @@ struct mac_iveiv_entry { | |||
1815 | #define RFCSR31_RX_H20M FIELD8(0x20) | 1869 | #define RFCSR31_RX_H20M FIELD8(0x20) |
1816 | 1870 | ||
1817 | /* | 1871 | /* |
1872 | * RFCSR 38: | ||
1873 | */ | ||
1874 | #define RFCSR38_RX_LO1_EN FIELD8(0x20) | ||
1875 | |||
1876 | /* | ||
1877 | * RFCSR 39: | ||
1878 | */ | ||
1879 | #define RFCSR39_RX_LO2_EN FIELD8(0x80) | ||
1880 | |||
1881 | /* | ||
1882 | * RFCSR 49: | ||
1883 | */ | ||
1884 | #define RFCSR49_TX FIELD8(0x3f) | ||
1885 | |||
1886 | /* | ||
1818 | * RF registers | 1887 | * RF registers |
1819 | */ | 1888 | */ |
1820 | 1889 | ||
@@ -1847,6 +1916,11 @@ struct mac_iveiv_entry { | |||
1847 | */ | 1916 | */ |
1848 | 1917 | ||
1849 | /* | 1918 | /* |
1919 | * Chip ID | ||
1920 | */ | ||
1921 | #define EEPROM_CHIP_ID 0x0000 | ||
1922 | |||
1923 | /* | ||
1850 | * EEPROM Version | 1924 | * EEPROM Version |
1851 | */ | 1925 | */ |
1852 | #define EEPROM_VERSION 0x0001 | 1926 | #define EEPROM_VERSION 0x0001 |
@@ -1999,23 +2073,26 @@ struct mac_iveiv_entry { | |||
1999 | #define EEPROM_RSSI_A2_LNA_A2 FIELD16(0xff00) | 2073 | #define EEPROM_RSSI_A2_LNA_A2 FIELD16(0xff00) |
2000 | 2074 | ||
2001 | /* | 2075 | /* |
2002 | * EEPROM Maximum TX power values | 2076 | * EEPROM EIRP Maximum TX power values(unit: dbm) |
2003 | */ | 2077 | */ |
2004 | #define EEPROM_MAX_TX_POWER 0x0027 | 2078 | #define EEPROM_EIRP_MAX_TX_POWER 0x0027 |
2005 | #define EEPROM_MAX_TX_POWER_24GHZ FIELD16(0x00ff) | 2079 | #define EEPROM_EIRP_MAX_TX_POWER_2GHZ FIELD16(0x00ff) |
2006 | #define EEPROM_MAX_TX_POWER_5GHZ FIELD16(0xff00) | 2080 | #define EEPROM_EIRP_MAX_TX_POWER_5GHZ FIELD16(0xff00) |
2007 | 2081 | ||
2008 | /* | 2082 | /* |
2009 | * EEPROM TXpower delta: 20MHZ AND 40 MHZ use different power. | 2083 | * EEPROM TXpower delta: 20MHZ AND 40 MHZ use different power. |
2010 | * This is delta in 40MHZ. | 2084 | * This is delta in 40MHZ. |
2011 | * VALUE: Tx Power dalta value (MAX=4) | 2085 | * VALUE: Tx Power dalta value, MAX=4(unit: dbm) |
2012 | * TYPE: 1: Plus the delta value, 0: minus the delta value | 2086 | * TYPE: 1: Plus the delta value, 0: minus the delta value |
2013 | * TXPOWER: Enable: | 2087 | * ENABLE: enable tx power compensation for 40BW |
2014 | */ | 2088 | */ |
2015 | #define EEPROM_TXPOWER_DELTA 0x0028 | 2089 | #define EEPROM_TXPOWER_DELTA 0x0028 |
2016 | #define EEPROM_TXPOWER_DELTA_VALUE FIELD16(0x003f) | 2090 | #define EEPROM_TXPOWER_DELTA_VALUE_2G FIELD16(0x003f) |
2017 | #define EEPROM_TXPOWER_DELTA_TYPE FIELD16(0x0040) | 2091 | #define EEPROM_TXPOWER_DELTA_TYPE_2G FIELD16(0x0040) |
2018 | #define EEPROM_TXPOWER_DELTA_TXPOWER FIELD16(0x0080) | 2092 | #define EEPROM_TXPOWER_DELTA_ENABLE_2G FIELD16(0x0080) |
2093 | #define EEPROM_TXPOWER_DELTA_VALUE_5G FIELD16(0x3f00) | ||
2094 | #define EEPROM_TXPOWER_DELTA_TYPE_5G FIELD16(0x4000) | ||
2095 | #define EEPROM_TXPOWER_DELTA_ENABLE_5G FIELD16(0x8000) | ||
2019 | 2096 | ||
2020 | /* | 2097 | /* |
2021 | * EEPROM TXPOWER 802.11BG | 2098 | * EEPROM TXPOWER 802.11BG |
@@ -2068,6 +2145,7 @@ struct mac_iveiv_entry { | |||
2068 | #define MCU_LED_LED_POLARITY 0x54 | 2145 | #define MCU_LED_LED_POLARITY 0x54 |
2069 | #define MCU_RADAR 0x60 | 2146 | #define MCU_RADAR 0x60 |
2070 | #define MCU_BOOT_SIGNAL 0x72 | 2147 | #define MCU_BOOT_SIGNAL 0x72 |
2148 | #define MCU_ANT_SELECT 0X73 | ||
2071 | #define MCU_BBP_SIGNAL 0x80 | 2149 | #define MCU_BBP_SIGNAL 0x80 |
2072 | #define MCU_POWER_SAVE 0x83 | 2150 | #define MCU_POWER_SAVE 0x83 |
2073 | 2151 | ||
@@ -2212,4 +2290,9 @@ struct mac_iveiv_entry { | |||
2212 | #define TXPOWER_A_TO_DEV(__txpower) \ | 2290 | #define TXPOWER_A_TO_DEV(__txpower) \ |
2213 | clamp_t(char, __txpower, MIN_A_TXPOWER, MAX_A_TXPOWER) | 2291 | clamp_t(char, __txpower, MIN_A_TXPOWER, MAX_A_TXPOWER) |
2214 | 2292 | ||
2293 | /* | ||
2294 | * Board's maximun TX power limitation | ||
2295 | */ | ||
2296 | #define EIRP_MAX_TX_POWER_LIMIT 0x50 | ||
2297 | |||
2215 | #endif /* RT2800_H */ | 2298 | #endif /* RT2800_H */ |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index c9bf074342ba..3da78bf0ca26 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -400,8 +400,15 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, | |||
400 | if (rt2800_wait_csr_ready(rt2x00dev)) | 400 | if (rt2800_wait_csr_ready(rt2x00dev)) |
401 | return -EBUSY; | 401 | return -EBUSY; |
402 | 402 | ||
403 | if (rt2x00_is_pci(rt2x00dev)) | 403 | if (rt2x00_is_pci(rt2x00dev)) { |
404 | if (rt2x00_rt(rt2x00dev, RT5390)) { | ||
405 | rt2800_register_read(rt2x00dev, AUX_CTRL, ®); | ||
406 | rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1); | ||
407 | rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1); | ||
408 | rt2800_register_write(rt2x00dev, AUX_CTRL, reg); | ||
409 | } | ||
404 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000002); | 410 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000002); |
411 | } | ||
405 | 412 | ||
406 | /* | 413 | /* |
407 | * Disable DMA, will be reenabled later when enabling | 414 | * Disable DMA, will be reenabled later when enabling |
@@ -773,13 +780,14 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) | |||
773 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | 780 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
774 | unsigned int beacon_base; | 781 | unsigned int beacon_base; |
775 | unsigned int padding_len; | 782 | unsigned int padding_len; |
776 | u32 reg; | 783 | u32 orig_reg, reg; |
777 | 784 | ||
778 | /* | 785 | /* |
779 | * Disable beaconing while we are reloading the beacon data, | 786 | * Disable beaconing while we are reloading the beacon data, |
780 | * otherwise we might be sending out invalid data. | 787 | * otherwise we might be sending out invalid data. |
781 | */ | 788 | */ |
782 | rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); | 789 | rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); |
790 | orig_reg = reg; | ||
783 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); | 791 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); |
784 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | 792 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); |
785 | 793 | ||
@@ -810,7 +818,14 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) | |||
810 | * Write entire beacon with TXWI and padding to register. | 818 | * Write entire beacon with TXWI and padding to register. |
811 | */ | 819 | */ |
812 | padding_len = roundup(entry->skb->len, 4) - entry->skb->len; | 820 | padding_len = roundup(entry->skb->len, 4) - entry->skb->len; |
813 | skb_pad(entry->skb, padding_len); | 821 | if (padding_len && skb_pad(entry->skb, padding_len)) { |
822 | ERROR(rt2x00dev, "Failure padding beacon, aborting\n"); | ||
823 | /* skb freed by skb_pad() on failure */ | ||
824 | entry->skb = NULL; | ||
825 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, orig_reg); | ||
826 | return; | ||
827 | } | ||
828 | |||
814 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); | 829 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); |
815 | rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data, | 830 | rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data, |
816 | entry->skb->len + padding_len); | 831 | entry->skb->len + padding_len); |
@@ -1368,10 +1383,32 @@ void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp, | |||
1368 | } | 1383 | } |
1369 | EXPORT_SYMBOL_GPL(rt2800_config_erp); | 1384 | EXPORT_SYMBOL_GPL(rt2800_config_erp); |
1370 | 1385 | ||
1386 | static void rt2800_set_ant_diversity(struct rt2x00_dev *rt2x00dev, | ||
1387 | enum antenna ant) | ||
1388 | { | ||
1389 | u32 reg; | ||
1390 | u8 eesk_pin = (ant == ANTENNA_A) ? 1 : 0; | ||
1391 | u8 gpio_bit3 = (ant == ANTENNA_A) ? 0 : 1; | ||
1392 | |||
1393 | if (rt2x00_is_pci(rt2x00dev)) { | ||
1394 | rt2800_register_read(rt2x00dev, E2PROM_CSR, ®); | ||
1395 | rt2x00_set_field32(®, E2PROM_CSR_DATA_CLOCK, eesk_pin); | ||
1396 | rt2800_register_write(rt2x00dev, E2PROM_CSR, reg); | ||
1397 | } else if (rt2x00_is_usb(rt2x00dev)) | ||
1398 | rt2800_mcu_request(rt2x00dev, MCU_ANT_SELECT, 0xff, | ||
1399 | eesk_pin, 0); | ||
1400 | |||
1401 | rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); | ||
1402 | rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT3, 0); | ||
1403 | rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT3, gpio_bit3); | ||
1404 | rt2800_register_write(rt2x00dev, GPIO_CTRL_CFG, reg); | ||
1405 | } | ||
1406 | |||
1371 | void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant) | 1407 | void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant) |
1372 | { | 1408 | { |
1373 | u8 r1; | 1409 | u8 r1; |
1374 | u8 r3; | 1410 | u8 r3; |
1411 | u16 eeprom; | ||
1375 | 1412 | ||
1376 | rt2800_bbp_read(rt2x00dev, 1, &r1); | 1413 | rt2800_bbp_read(rt2x00dev, 1, &r1); |
1377 | rt2800_bbp_read(rt2x00dev, 3, &r3); | 1414 | rt2800_bbp_read(rt2x00dev, 3, &r3); |
@@ -1379,7 +1416,7 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant) | |||
1379 | /* | 1416 | /* |
1380 | * Configure the TX antenna. | 1417 | * Configure the TX antenna. |
1381 | */ | 1418 | */ |
1382 | switch ((int)ant->tx) { | 1419 | switch (ant->tx_chain_num) { |
1383 | case 1: | 1420 | case 1: |
1384 | rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0); | 1421 | rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0); |
1385 | break; | 1422 | break; |
@@ -1394,8 +1431,18 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant) | |||
1394 | /* | 1431 | /* |
1395 | * Configure the RX antenna. | 1432 | * Configure the RX antenna. |
1396 | */ | 1433 | */ |
1397 | switch ((int)ant->rx) { | 1434 | switch (ant->rx_chain_num) { |
1398 | case 1: | 1435 | case 1: |
1436 | if (rt2x00_rt(rt2x00dev, RT3070) || | ||
1437 | rt2x00_rt(rt2x00dev, RT3090) || | ||
1438 | rt2x00_rt(rt2x00dev, RT3390)) { | ||
1439 | rt2x00_eeprom_read(rt2x00dev, | ||
1440 | EEPROM_NIC_CONF1, &eeprom); | ||
1441 | if (rt2x00_get_field16(eeprom, | ||
1442 | EEPROM_NIC_CONF1_ANT_DIVERSITY)) | ||
1443 | rt2800_set_ant_diversity(rt2x00dev, | ||
1444 | rt2x00dev->default_ant.rx); | ||
1445 | } | ||
1399 | rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 0); | 1446 | rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 0); |
1400 | break; | 1447 | break; |
1401 | case 2: | 1448 | case 2: |
@@ -1441,13 +1488,13 @@ static void rt2800_config_channel_rf2xxx(struct rt2x00_dev *rt2x00dev, | |||
1441 | { | 1488 | { |
1442 | rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset); | 1489 | rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset); |
1443 | 1490 | ||
1444 | if (rt2x00dev->default_ant.tx == 1) | 1491 | if (rt2x00dev->default_ant.tx_chain_num == 1) |
1445 | rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_TX1, 1); | 1492 | rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_TX1, 1); |
1446 | 1493 | ||
1447 | if (rt2x00dev->default_ant.rx == 1) { | 1494 | if (rt2x00dev->default_ant.rx_chain_num == 1) { |
1448 | rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX1, 1); | 1495 | rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX1, 1); |
1449 | rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1); | 1496 | rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1); |
1450 | } else if (rt2x00dev->default_ant.rx == 2) | 1497 | } else if (rt2x00dev->default_ant.rx_chain_num == 2) |
1451 | rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1); | 1498 | rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1); |
1452 | 1499 | ||
1453 | if (rf->channel > 14) { | 1500 | if (rf->channel > 14) { |
@@ -1533,6 +1580,99 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev, | |||
1533 | rt2800_rfcsr_write(rt2x00dev, 7, rfcsr); | 1580 | rt2800_rfcsr_write(rt2x00dev, 7, rfcsr); |
1534 | } | 1581 | } |
1535 | 1582 | ||
1583 | |||
1584 | #define RT5390_POWER_BOUND 0x27 | ||
1585 | #define RT5390_FREQ_OFFSET_BOUND 0x5f | ||
1586 | |||
1587 | static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev, | ||
1588 | struct ieee80211_conf *conf, | ||
1589 | struct rf_channel *rf, | ||
1590 | struct channel_info *info) | ||
1591 | { | ||
1592 | u8 rfcsr; | ||
1593 | u16 eeprom; | ||
1594 | |||
1595 | rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1); | ||
1596 | rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3); | ||
1597 | rt2800_rfcsr_read(rt2x00dev, 11, &rfcsr); | ||
1598 | rt2x00_set_field8(&rfcsr, RFCSR11_R, rf->rf2); | ||
1599 | rt2800_rfcsr_write(rt2x00dev, 11, rfcsr); | ||
1600 | |||
1601 | rt2800_rfcsr_read(rt2x00dev, 49, &rfcsr); | ||
1602 | if (info->default_power1 > RT5390_POWER_BOUND) | ||
1603 | rt2x00_set_field8(&rfcsr, RFCSR49_TX, RT5390_POWER_BOUND); | ||
1604 | else | ||
1605 | rt2x00_set_field8(&rfcsr, RFCSR49_TX, info->default_power1); | ||
1606 | rt2800_rfcsr_write(rt2x00dev, 49, rfcsr); | ||
1607 | |||
1608 | rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); | ||
1609 | rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); | ||
1610 | rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1); | ||
1611 | rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1); | ||
1612 | rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1); | ||
1613 | rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); | ||
1614 | |||
1615 | rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); | ||
1616 | if (rt2x00dev->freq_offset > RT5390_FREQ_OFFSET_BOUND) | ||
1617 | rt2x00_set_field8(&rfcsr, RFCSR17_CODE, RT5390_FREQ_OFFSET_BOUND); | ||
1618 | else | ||
1619 | rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset); | ||
1620 | rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); | ||
1621 | |||
1622 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); | ||
1623 | if (rf->channel <= 14) { | ||
1624 | int idx = rf->channel-1; | ||
1625 | |||
1626 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) { | ||
1627 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) { | ||
1628 | /* r55/r59 value array of channel 1~14 */ | ||
1629 | static const char r55_bt_rev[] = {0x83, 0x83, | ||
1630 | 0x83, 0x73, 0x73, 0x63, 0x53, 0x53, | ||
1631 | 0x53, 0x43, 0x43, 0x43, 0x43, 0x43}; | ||
1632 | static const char r59_bt_rev[] = {0x0e, 0x0e, | ||
1633 | 0x0e, 0x0e, 0x0e, 0x0b, 0x0a, 0x09, | ||
1634 | 0x07, 0x07, 0x07, 0x07, 0x07, 0x07}; | ||
1635 | |||
1636 | rt2800_rfcsr_write(rt2x00dev, 55, r55_bt_rev[idx]); | ||
1637 | rt2800_rfcsr_write(rt2x00dev, 59, r59_bt_rev[idx]); | ||
1638 | } else { | ||
1639 | static const char r59_bt[] = {0x8b, 0x8b, 0x8b, | ||
1640 | 0x8b, 0x8b, 0x8b, 0x8b, 0x8a, 0x89, | ||
1641 | 0x88, 0x88, 0x86, 0x85, 0x84}; | ||
1642 | |||
1643 | rt2800_rfcsr_write(rt2x00dev, 59, r59_bt[idx]); | ||
1644 | } | ||
1645 | } else { | ||
1646 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) { | ||
1647 | static const char r55_nonbt_rev[] = {0x23, 0x23, | ||
1648 | 0x23, 0x23, 0x13, 0x13, 0x03, 0x03, | ||
1649 | 0x03, 0x03, 0x03, 0x03, 0x03, 0x03}; | ||
1650 | static const char r59_nonbt_rev[] = {0x07, 0x07, | ||
1651 | 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, | ||
1652 | 0x07, 0x07, 0x06, 0x05, 0x04, 0x04}; | ||
1653 | |||
1654 | rt2800_rfcsr_write(rt2x00dev, 55, r55_nonbt_rev[idx]); | ||
1655 | rt2800_rfcsr_write(rt2x00dev, 59, r59_nonbt_rev[idx]); | ||
1656 | } else if (rt2x00_rt(rt2x00dev, RT5390)) { | ||
1657 | static const char r59_non_bt[] = {0x8f, 0x8f, | ||
1658 | 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8d, | ||
1659 | 0x8a, 0x88, 0x88, 0x87, 0x87, 0x86}; | ||
1660 | |||
1661 | rt2800_rfcsr_write(rt2x00dev, 59, r59_non_bt[idx]); | ||
1662 | } | ||
1663 | } | ||
1664 | } | ||
1665 | |||
1666 | rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); | ||
1667 | rt2x00_set_field8(&rfcsr, RFCSR30_TX_H20M, 0); | ||
1668 | rt2x00_set_field8(&rfcsr, RFCSR30_RX_H20M, 0); | ||
1669 | rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); | ||
1670 | |||
1671 | rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); | ||
1672 | rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); | ||
1673 | rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); | ||
1674 | } | ||
1675 | |||
1536 | static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | 1676 | static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, |
1537 | struct ieee80211_conf *conf, | 1677 | struct ieee80211_conf *conf, |
1538 | struct rf_channel *rf, | 1678 | struct rf_channel *rf, |
@@ -1557,6 +1697,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | |||
1557 | rt2x00_rf(rt2x00dev, RF3052) || | 1697 | rt2x00_rf(rt2x00dev, RF3052) || |
1558 | rt2x00_rf(rt2x00dev, RF3320)) | 1698 | rt2x00_rf(rt2x00dev, RF3320)) |
1559 | rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info); | 1699 | rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info); |
1700 | else if (rt2x00_rf(rt2x00dev, RF5390)) | ||
1701 | rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info); | ||
1560 | else | 1702 | else |
1561 | rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); | 1703 | rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); |
1562 | 1704 | ||
@@ -1569,12 +1711,14 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | |||
1569 | rt2800_bbp_write(rt2x00dev, 86, 0); | 1711 | rt2800_bbp_write(rt2x00dev, 86, 0); |
1570 | 1712 | ||
1571 | if (rf->channel <= 14) { | 1713 | if (rf->channel <= 14) { |
1572 | if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) { | 1714 | if (!rt2x00_rt(rt2x00dev, RT5390)) { |
1573 | rt2800_bbp_write(rt2x00dev, 82, 0x62); | 1715 | if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) { |
1574 | rt2800_bbp_write(rt2x00dev, 75, 0x46); | 1716 | rt2800_bbp_write(rt2x00dev, 82, 0x62); |
1575 | } else { | 1717 | rt2800_bbp_write(rt2x00dev, 75, 0x46); |
1576 | rt2800_bbp_write(rt2x00dev, 82, 0x84); | 1718 | } else { |
1577 | rt2800_bbp_write(rt2x00dev, 75, 0x50); | 1719 | rt2800_bbp_write(rt2x00dev, 82, 0x84); |
1720 | rt2800_bbp_write(rt2x00dev, 75, 0x50); | ||
1721 | } | ||
1578 | } | 1722 | } |
1579 | } else { | 1723 | } else { |
1580 | rt2800_bbp_write(rt2x00dev, 82, 0xf2); | 1724 | rt2800_bbp_write(rt2x00dev, 82, 0xf2); |
@@ -1594,13 +1738,13 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | |||
1594 | tx_pin = 0; | 1738 | tx_pin = 0; |
1595 | 1739 | ||
1596 | /* Turn on unused PA or LNA when not using 1T or 1R */ | 1740 | /* Turn on unused PA or LNA when not using 1T or 1R */ |
1597 | if (rt2x00dev->default_ant.tx != 1) { | 1741 | if (rt2x00dev->default_ant.tx_chain_num == 2) { |
1598 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, 1); | 1742 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, 1); |
1599 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, 1); | 1743 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, 1); |
1600 | } | 1744 | } |
1601 | 1745 | ||
1602 | /* Turn on unused PA or LNA when not using 1T or 1R */ | 1746 | /* Turn on unused PA or LNA when not using 1T or 1R */ |
1603 | if (rt2x00dev->default_ant.rx != 1) { | 1747 | if (rt2x00dev->default_ant.rx_chain_num == 2) { |
1604 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN, 1); | 1748 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN, 1); |
1605 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN, 1); | 1749 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN, 1); |
1606 | } | 1750 | } |
@@ -1644,30 +1788,116 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | |||
1644 | rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, ®); | 1788 | rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, ®); |
1645 | } | 1789 | } |
1646 | 1790 | ||
1791 | static int rt2800_get_txpower_bw_comp(struct rt2x00_dev *rt2x00dev, | ||
1792 | enum ieee80211_band band) | ||
1793 | { | ||
1794 | u16 eeprom; | ||
1795 | u8 comp_en; | ||
1796 | u8 comp_type; | ||
1797 | int comp_value; | ||
1798 | |||
1799 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_DELTA, &eeprom); | ||
1800 | |||
1801 | if (eeprom == 0xffff) | ||
1802 | return 0; | ||
1803 | |||
1804 | if (band == IEEE80211_BAND_2GHZ) { | ||
1805 | comp_en = rt2x00_get_field16(eeprom, | ||
1806 | EEPROM_TXPOWER_DELTA_ENABLE_2G); | ||
1807 | if (comp_en) { | ||
1808 | comp_type = rt2x00_get_field16(eeprom, | ||
1809 | EEPROM_TXPOWER_DELTA_TYPE_2G); | ||
1810 | comp_value = rt2x00_get_field16(eeprom, | ||
1811 | EEPROM_TXPOWER_DELTA_VALUE_2G); | ||
1812 | if (!comp_type) | ||
1813 | comp_value = -comp_value; | ||
1814 | } | ||
1815 | } else { | ||
1816 | comp_en = rt2x00_get_field16(eeprom, | ||
1817 | EEPROM_TXPOWER_DELTA_ENABLE_5G); | ||
1818 | if (comp_en) { | ||
1819 | comp_type = rt2x00_get_field16(eeprom, | ||
1820 | EEPROM_TXPOWER_DELTA_TYPE_5G); | ||
1821 | comp_value = rt2x00_get_field16(eeprom, | ||
1822 | EEPROM_TXPOWER_DELTA_VALUE_5G); | ||
1823 | if (!comp_type) | ||
1824 | comp_value = -comp_value; | ||
1825 | } | ||
1826 | } | ||
1827 | |||
1828 | return comp_value; | ||
1829 | } | ||
1830 | |||
1831 | static u8 rt2800_compesate_txpower(struct rt2x00_dev *rt2x00dev, | ||
1832 | int is_rate_b, | ||
1833 | enum ieee80211_band band, | ||
1834 | int power_level, | ||
1835 | u8 txpower) | ||
1836 | { | ||
1837 | u32 reg; | ||
1838 | u16 eeprom; | ||
1839 | u8 criterion; | ||
1840 | u8 eirp_txpower; | ||
1841 | u8 eirp_txpower_criterion; | ||
1842 | u8 reg_limit; | ||
1843 | int bw_comp = 0; | ||
1844 | |||
1845 | if (!((band == IEEE80211_BAND_5GHZ) && is_rate_b)) | ||
1846 | return txpower; | ||
1847 | |||
1848 | if (test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags)) | ||
1849 | bw_comp = rt2800_get_txpower_bw_comp(rt2x00dev, band); | ||
1850 | |||
1851 | if (test_bit(CONFIG_SUPPORT_POWER_LIMIT, &rt2x00dev->flags)) { | ||
1852 | /* | ||
1853 | * Check if eirp txpower exceed txpower_limit. | ||
1854 | * We use OFDM 6M as criterion and its eirp txpower | ||
1855 | * is stored at EEPROM_EIRP_MAX_TX_POWER. | ||
1856 | * .11b data rate need add additional 4dbm | ||
1857 | * when calculating eirp txpower. | ||
1858 | */ | ||
1859 | rt2800_register_read(rt2x00dev, TX_PWR_CFG_0, ®); | ||
1860 | criterion = rt2x00_get_field32(reg, TX_PWR_CFG_0_6MBS); | ||
1861 | |||
1862 | rt2x00_eeprom_read(rt2x00dev, | ||
1863 | EEPROM_EIRP_MAX_TX_POWER, &eeprom); | ||
1864 | |||
1865 | if (band == IEEE80211_BAND_2GHZ) | ||
1866 | eirp_txpower_criterion = rt2x00_get_field16(eeprom, | ||
1867 | EEPROM_EIRP_MAX_TX_POWER_2GHZ); | ||
1868 | else | ||
1869 | eirp_txpower_criterion = rt2x00_get_field16(eeprom, | ||
1870 | EEPROM_EIRP_MAX_TX_POWER_5GHZ); | ||
1871 | |||
1872 | eirp_txpower = eirp_txpower_criterion + (txpower - criterion) + | ||
1873 | (is_rate_b ? 4 : 0) + bw_comp; | ||
1874 | |||
1875 | reg_limit = (eirp_txpower > power_level) ? | ||
1876 | (eirp_txpower - power_level) : 0; | ||
1877 | } else | ||
1878 | reg_limit = 0; | ||
1879 | |||
1880 | return txpower + bw_comp - reg_limit; | ||
1881 | } | ||
1882 | |||
1647 | static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, | 1883 | static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, |
1648 | const int max_txpower) | 1884 | struct ieee80211_conf *conf) |
1649 | { | 1885 | { |
1650 | u8 txpower; | 1886 | u8 txpower; |
1651 | u8 max_value = (u8)max_txpower; | ||
1652 | u16 eeprom; | 1887 | u16 eeprom; |
1653 | int i; | 1888 | int i, is_rate_b; |
1654 | u32 reg; | 1889 | u32 reg; |
1655 | u8 r1; | 1890 | u8 r1; |
1656 | u32 offset; | 1891 | u32 offset; |
1892 | enum ieee80211_band band = conf->channel->band; | ||
1893 | int power_level = conf->power_level; | ||
1657 | 1894 | ||
1658 | /* | 1895 | /* |
1659 | * set to normal tx power mode: +/- 0dBm | 1896 | * set to normal bbp tx power control mode: +/- 0dBm |
1660 | */ | 1897 | */ |
1661 | rt2800_bbp_read(rt2x00dev, 1, &r1); | 1898 | rt2800_bbp_read(rt2x00dev, 1, &r1); |
1662 | rt2x00_set_field8(&r1, BBP1_TX_POWER, 0); | 1899 | rt2x00_set_field8(&r1, BBP1_TX_POWER_CTRL, 0); |
1663 | rt2800_bbp_write(rt2x00dev, 1, r1); | 1900 | rt2800_bbp_write(rt2x00dev, 1, r1); |
1664 | |||
1665 | /* | ||
1666 | * The eeprom contains the tx power values for each rate. These | ||
1667 | * values map to 100% tx power. Each 16bit word contains four tx | ||
1668 | * power values and the order is the same as used in the TX_PWR_CFG | ||
1669 | * registers. | ||
1670 | */ | ||
1671 | offset = TX_PWR_CFG_0; | 1901 | offset = TX_PWR_CFG_0; |
1672 | 1902 | ||
1673 | for (i = 0; i < EEPROM_TXPOWER_BYRATE_SIZE; i += 2) { | 1903 | for (i = 0; i < EEPROM_TXPOWER_BYRATE_SIZE; i += 2) { |
@@ -1681,73 +1911,99 @@ static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev, | |||
1681 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i, | 1911 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i, |
1682 | &eeprom); | 1912 | &eeprom); |
1683 | 1913 | ||
1684 | /* TX_PWR_CFG_0: 1MBS, TX_PWR_CFG_1: 24MBS, | 1914 | is_rate_b = i ? 0 : 1; |
1915 | /* | ||
1916 | * TX_PWR_CFG_0: 1MBS, TX_PWR_CFG_1: 24MBS, | ||
1685 | * TX_PWR_CFG_2: MCS4, TX_PWR_CFG_3: MCS12, | 1917 | * TX_PWR_CFG_2: MCS4, TX_PWR_CFG_3: MCS12, |
1686 | * TX_PWR_CFG_4: unknown */ | 1918 | * TX_PWR_CFG_4: unknown |
1919 | */ | ||
1687 | txpower = rt2x00_get_field16(eeprom, | 1920 | txpower = rt2x00_get_field16(eeprom, |
1688 | EEPROM_TXPOWER_BYRATE_RATE0); | 1921 | EEPROM_TXPOWER_BYRATE_RATE0); |
1689 | rt2x00_set_field32(®, TX_PWR_CFG_RATE0, | 1922 | txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, |
1690 | min(txpower, max_value)); | 1923 | power_level, txpower); |
1924 | rt2x00_set_field32(®, TX_PWR_CFG_RATE0, txpower); | ||
1691 | 1925 | ||
1692 | /* TX_PWR_CFG_0: 2MBS, TX_PWR_CFG_1: 36MBS, | 1926 | /* |
1927 | * TX_PWR_CFG_0: 2MBS, TX_PWR_CFG_1: 36MBS, | ||
1693 | * TX_PWR_CFG_2: MCS5, TX_PWR_CFG_3: MCS13, | 1928 | * TX_PWR_CFG_2: MCS5, TX_PWR_CFG_3: MCS13, |
1694 | * TX_PWR_CFG_4: unknown */ | 1929 | * TX_PWR_CFG_4: unknown |
1930 | */ | ||
1695 | txpower = rt2x00_get_field16(eeprom, | 1931 | txpower = rt2x00_get_field16(eeprom, |
1696 | EEPROM_TXPOWER_BYRATE_RATE1); | 1932 | EEPROM_TXPOWER_BYRATE_RATE1); |
1697 | rt2x00_set_field32(®, TX_PWR_CFG_RATE1, | 1933 | txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, |
1698 | min(txpower, max_value)); | 1934 | power_level, txpower); |
1935 | rt2x00_set_field32(®, TX_PWR_CFG_RATE1, txpower); | ||
1699 | 1936 | ||
1700 | /* TX_PWR_CFG_0: 55MBS, TX_PWR_CFG_1: 48MBS, | 1937 | /* |
1938 | * TX_PWR_CFG_0: 5.5MBS, TX_PWR_CFG_1: 48MBS, | ||
1701 | * TX_PWR_CFG_2: MCS6, TX_PWR_CFG_3: MCS14, | 1939 | * TX_PWR_CFG_2: MCS6, TX_PWR_CFG_3: MCS14, |
1702 | * TX_PWR_CFG_4: unknown */ | 1940 | * TX_PWR_CFG_4: unknown |
1941 | */ | ||
1703 | txpower = rt2x00_get_field16(eeprom, | 1942 | txpower = rt2x00_get_field16(eeprom, |
1704 | EEPROM_TXPOWER_BYRATE_RATE2); | 1943 | EEPROM_TXPOWER_BYRATE_RATE2); |
1705 | rt2x00_set_field32(®, TX_PWR_CFG_RATE2, | 1944 | txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, |
1706 | min(txpower, max_value)); | 1945 | power_level, txpower); |
1946 | rt2x00_set_field32(®, TX_PWR_CFG_RATE2, txpower); | ||
1707 | 1947 | ||
1708 | /* TX_PWR_CFG_0: 11MBS, TX_PWR_CFG_1: 54MBS, | 1948 | /* |
1949 | * TX_PWR_CFG_0: 11MBS, TX_PWR_CFG_1: 54MBS, | ||
1709 | * TX_PWR_CFG_2: MCS7, TX_PWR_CFG_3: MCS15, | 1950 | * TX_PWR_CFG_2: MCS7, TX_PWR_CFG_3: MCS15, |
1710 | * TX_PWR_CFG_4: unknown */ | 1951 | * TX_PWR_CFG_4: unknown |
1952 | */ | ||
1711 | txpower = rt2x00_get_field16(eeprom, | 1953 | txpower = rt2x00_get_field16(eeprom, |
1712 | EEPROM_TXPOWER_BYRATE_RATE3); | 1954 | EEPROM_TXPOWER_BYRATE_RATE3); |
1713 | rt2x00_set_field32(®, TX_PWR_CFG_RATE3, | 1955 | txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, |
1714 | min(txpower, max_value)); | 1956 | power_level, txpower); |
1957 | rt2x00_set_field32(®, TX_PWR_CFG_RATE3, txpower); | ||
1715 | 1958 | ||
1716 | /* read the next four txpower values */ | 1959 | /* read the next four txpower values */ |
1717 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i + 1, | 1960 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_BYRATE + i + 1, |
1718 | &eeprom); | 1961 | &eeprom); |
1719 | 1962 | ||
1720 | /* TX_PWR_CFG_0: 6MBS, TX_PWR_CFG_1: MCS0, | 1963 | is_rate_b = 0; |
1964 | /* | ||
1965 | * TX_PWR_CFG_0: 6MBS, TX_PWR_CFG_1: MCS0, | ||
1721 | * TX_PWR_CFG_2: MCS8, TX_PWR_CFG_3: unknown, | 1966 | * TX_PWR_CFG_2: MCS8, TX_PWR_CFG_3: unknown, |
1722 | * TX_PWR_CFG_4: unknown */ | 1967 | * TX_PWR_CFG_4: unknown |
1968 | */ | ||
1723 | txpower = rt2x00_get_field16(eeprom, | 1969 | txpower = rt2x00_get_field16(eeprom, |
1724 | EEPROM_TXPOWER_BYRATE_RATE0); | 1970 | EEPROM_TXPOWER_BYRATE_RATE0); |
1725 | rt2x00_set_field32(®, TX_PWR_CFG_RATE4, | 1971 | txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, |
1726 | min(txpower, max_value)); | 1972 | power_level, txpower); |
1973 | rt2x00_set_field32(®, TX_PWR_CFG_RATE4, txpower); | ||
1727 | 1974 | ||
1728 | /* TX_PWR_CFG_0: 9MBS, TX_PWR_CFG_1: MCS1, | 1975 | /* |
1976 | * TX_PWR_CFG_0: 9MBS, TX_PWR_CFG_1: MCS1, | ||
1729 | * TX_PWR_CFG_2: MCS9, TX_PWR_CFG_3: unknown, | 1977 | * TX_PWR_CFG_2: MCS9, TX_PWR_CFG_3: unknown, |
1730 | * TX_PWR_CFG_4: unknown */ | 1978 | * TX_PWR_CFG_4: unknown |
1979 | */ | ||
1731 | txpower = rt2x00_get_field16(eeprom, | 1980 | txpower = rt2x00_get_field16(eeprom, |
1732 | EEPROM_TXPOWER_BYRATE_RATE1); | 1981 | EEPROM_TXPOWER_BYRATE_RATE1); |
1733 | rt2x00_set_field32(®, TX_PWR_CFG_RATE5, | 1982 | txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, |
1734 | min(txpower, max_value)); | 1983 | power_level, txpower); |
1984 | rt2x00_set_field32(®, TX_PWR_CFG_RATE5, txpower); | ||
1735 | 1985 | ||
1736 | /* TX_PWR_CFG_0: 12MBS, TX_PWR_CFG_1: MCS2, | 1986 | /* |
1987 | * TX_PWR_CFG_0: 12MBS, TX_PWR_CFG_1: MCS2, | ||
1737 | * TX_PWR_CFG_2: MCS10, TX_PWR_CFG_3: unknown, | 1988 | * TX_PWR_CFG_2: MCS10, TX_PWR_CFG_3: unknown, |
1738 | * TX_PWR_CFG_4: unknown */ | 1989 | * TX_PWR_CFG_4: unknown |
1990 | */ | ||
1739 | txpower = rt2x00_get_field16(eeprom, | 1991 | txpower = rt2x00_get_field16(eeprom, |
1740 | EEPROM_TXPOWER_BYRATE_RATE2); | 1992 | EEPROM_TXPOWER_BYRATE_RATE2); |
1741 | rt2x00_set_field32(®, TX_PWR_CFG_RATE6, | 1993 | txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, |
1742 | min(txpower, max_value)); | 1994 | power_level, txpower); |
1995 | rt2x00_set_field32(®, TX_PWR_CFG_RATE6, txpower); | ||
1743 | 1996 | ||
1744 | /* TX_PWR_CFG_0: 18MBS, TX_PWR_CFG_1: MCS3, | 1997 | /* |
1998 | * TX_PWR_CFG_0: 18MBS, TX_PWR_CFG_1: MCS3, | ||
1745 | * TX_PWR_CFG_2: MCS11, TX_PWR_CFG_3: unknown, | 1999 | * TX_PWR_CFG_2: MCS11, TX_PWR_CFG_3: unknown, |
1746 | * TX_PWR_CFG_4: unknown */ | 2000 | * TX_PWR_CFG_4: unknown |
2001 | */ | ||
1747 | txpower = rt2x00_get_field16(eeprom, | 2002 | txpower = rt2x00_get_field16(eeprom, |
1748 | EEPROM_TXPOWER_BYRATE_RATE3); | 2003 | EEPROM_TXPOWER_BYRATE_RATE3); |
1749 | rt2x00_set_field32(®, TX_PWR_CFG_RATE7, | 2004 | txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band, |
1750 | min(txpower, max_value)); | 2005 | power_level, txpower); |
2006 | rt2x00_set_field32(®, TX_PWR_CFG_RATE7, txpower); | ||
1751 | 2007 | ||
1752 | rt2800_register_write(rt2x00dev, offset, reg); | 2008 | rt2800_register_write(rt2x00dev, offset, reg); |
1753 | 2009 | ||
@@ -1806,11 +2062,13 @@ void rt2800_config(struct rt2x00_dev *rt2x00dev, | |||
1806 | /* Always recalculate LNA gain before changing configuration */ | 2062 | /* Always recalculate LNA gain before changing configuration */ |
1807 | rt2800_config_lna_gain(rt2x00dev, libconf); | 2063 | rt2800_config_lna_gain(rt2x00dev, libconf); |
1808 | 2064 | ||
1809 | if (flags & IEEE80211_CONF_CHANGE_CHANNEL) | 2065 | if (flags & IEEE80211_CONF_CHANGE_CHANNEL) { |
1810 | rt2800_config_channel(rt2x00dev, libconf->conf, | 2066 | rt2800_config_channel(rt2x00dev, libconf->conf, |
1811 | &libconf->rf, &libconf->channel); | 2067 | &libconf->rf, &libconf->channel); |
2068 | rt2800_config_txpower(rt2x00dev, libconf->conf); | ||
2069 | } | ||
1812 | if (flags & IEEE80211_CONF_CHANGE_POWER) | 2070 | if (flags & IEEE80211_CONF_CHANGE_POWER) |
1813 | rt2800_config_txpower(rt2x00dev, libconf->conf->power_level); | 2071 | rt2800_config_txpower(rt2x00dev, libconf->conf); |
1814 | if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS) | 2072 | if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS) |
1815 | rt2800_config_retry_limit(rt2x00dev, libconf); | 2073 | rt2800_config_retry_limit(rt2x00dev, libconf); |
1816 | if (flags & IEEE80211_CONF_CHANGE_PS) | 2074 | if (flags & IEEE80211_CONF_CHANGE_PS) |
@@ -1839,7 +2097,8 @@ static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev) | |||
1839 | if (rt2x00_rt(rt2x00dev, RT3070) || | 2097 | if (rt2x00_rt(rt2x00dev, RT3070) || |
1840 | rt2x00_rt(rt2x00dev, RT3071) || | 2098 | rt2x00_rt(rt2x00dev, RT3071) || |
1841 | rt2x00_rt(rt2x00dev, RT3090) || | 2099 | rt2x00_rt(rt2x00dev, RT3090) || |
1842 | rt2x00_rt(rt2x00dev, RT3390)) | 2100 | rt2x00_rt(rt2x00dev, RT3390) || |
2101 | rt2x00_rt(rt2x00dev, RT5390)) | ||
1843 | return 0x1c + (2 * rt2x00dev->lna_gain); | 2102 | return 0x1c + (2 * rt2x00dev->lna_gain); |
1844 | else | 2103 | else |
1845 | return 0x2e + rt2x00dev->lna_gain; | 2104 | return 0x2e + rt2x00dev->lna_gain; |
@@ -1971,6 +2230,10 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1971 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); | 2230 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); |
1972 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000); | 2231 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000); |
1973 | rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x0000001f); | 2232 | rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x0000001f); |
2233 | } else if (rt2x00_rt(rt2x00dev, RT5390)) { | ||
2234 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); | ||
2235 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); | ||
2236 | rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); | ||
1974 | } else { | 2237 | } else { |
1975 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000); | 2238 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000); |
1976 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); | 2239 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); |
@@ -2039,7 +2302,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
2039 | rt2800_register_read(rt2x00dev, CCK_PROT_CFG, ®); | 2302 | rt2800_register_read(rt2x00dev, CCK_PROT_CFG, ®); |
2040 | rt2x00_set_field32(®, CCK_PROT_CFG_PROTECT_RATE, 3); | 2303 | rt2x00_set_field32(®, CCK_PROT_CFG_PROTECT_RATE, 3); |
2041 | rt2x00_set_field32(®, CCK_PROT_CFG_PROTECT_CTRL, 0); | 2304 | rt2x00_set_field32(®, CCK_PROT_CFG_PROTECT_CTRL, 0); |
2042 | rt2x00_set_field32(®, CCK_PROT_CFG_PROTECT_NAV, 1); | 2305 | rt2x00_set_field32(®, CCK_PROT_CFG_PROTECT_NAV_SHORT, 1); |
2043 | rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_CCK, 1); | 2306 | rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_CCK, 1); |
2044 | rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_OFDM, 1); | 2307 | rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_OFDM, 1); |
2045 | rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_MM20, 1); | 2308 | rt2x00_set_field32(®, CCK_PROT_CFG_TX_OP_ALLOW_MM20, 1); |
@@ -2052,7 +2315,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
2052 | rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, ®); | 2315 | rt2800_register_read(rt2x00dev, OFDM_PROT_CFG, ®); |
2053 | rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_RATE, 3); | 2316 | rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_RATE, 3); |
2054 | rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_CTRL, 0); | 2317 | rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_CTRL, 0); |
2055 | rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_NAV, 1); | 2318 | rt2x00_set_field32(®, OFDM_PROT_CFG_PROTECT_NAV_SHORT, 1); |
2056 | rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_CCK, 1); | 2319 | rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_CCK, 1); |
2057 | rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_OFDM, 1); | 2320 | rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_OFDM, 1); |
2058 | rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_MM20, 1); | 2321 | rt2x00_set_field32(®, OFDM_PROT_CFG_TX_OP_ALLOW_MM20, 1); |
@@ -2065,7 +2328,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
2065 | rt2800_register_read(rt2x00dev, MM20_PROT_CFG, ®); | 2328 | rt2800_register_read(rt2x00dev, MM20_PROT_CFG, ®); |
2066 | rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_RATE, 0x4004); | 2329 | rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_RATE, 0x4004); |
2067 | rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_CTRL, 0); | 2330 | rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_CTRL, 0); |
2068 | rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_NAV, 1); | 2331 | rt2x00_set_field32(®, MM20_PROT_CFG_PROTECT_NAV_SHORT, 1); |
2069 | rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_CCK, 1); | 2332 | rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_CCK, 1); |
2070 | rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_OFDM, 1); | 2333 | rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_OFDM, 1); |
2071 | rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_MM20, 1); | 2334 | rt2x00_set_field32(®, MM20_PROT_CFG_TX_OP_ALLOW_MM20, 1); |
@@ -2078,7 +2341,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
2078 | rt2800_register_read(rt2x00dev, MM40_PROT_CFG, ®); | 2341 | rt2800_register_read(rt2x00dev, MM40_PROT_CFG, ®); |
2079 | rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_RATE, 0x4084); | 2342 | rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_RATE, 0x4084); |
2080 | rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_CTRL, 0); | 2343 | rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_CTRL, 0); |
2081 | rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_NAV, 1); | 2344 | rt2x00_set_field32(®, MM40_PROT_CFG_PROTECT_NAV_SHORT, 1); |
2082 | rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_CCK, 1); | 2345 | rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_CCK, 1); |
2083 | rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_OFDM, 1); | 2346 | rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_OFDM, 1); |
2084 | rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_MM20, 1); | 2347 | rt2x00_set_field32(®, MM40_PROT_CFG_TX_OP_ALLOW_MM20, 1); |
@@ -2091,7 +2354,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
2091 | rt2800_register_read(rt2x00dev, GF20_PROT_CFG, ®); | 2354 | rt2800_register_read(rt2x00dev, GF20_PROT_CFG, ®); |
2092 | rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_RATE, 0x4004); | 2355 | rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_RATE, 0x4004); |
2093 | rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_CTRL, 0); | 2356 | rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_CTRL, 0); |
2094 | rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_NAV, 1); | 2357 | rt2x00_set_field32(®, GF20_PROT_CFG_PROTECT_NAV_SHORT, 1); |
2095 | rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_CCK, 1); | 2358 | rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_CCK, 1); |
2096 | rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_OFDM, 1); | 2359 | rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_OFDM, 1); |
2097 | rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_MM20, 1); | 2360 | rt2x00_set_field32(®, GF20_PROT_CFG_TX_OP_ALLOW_MM20, 1); |
@@ -2104,7 +2367,7 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
2104 | rt2800_register_read(rt2x00dev, GF40_PROT_CFG, ®); | 2367 | rt2800_register_read(rt2x00dev, GF40_PROT_CFG, ®); |
2105 | rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_RATE, 0x4084); | 2368 | rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_RATE, 0x4084); |
2106 | rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_CTRL, 0); | 2369 | rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_CTRL, 0); |
2107 | rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_NAV, 1); | 2370 | rt2x00_set_field32(®, GF40_PROT_CFG_PROTECT_NAV_SHORT, 1); |
2108 | rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_CCK, 1); | 2371 | rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_CCK, 1); |
2109 | rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_OFDM, 1); | 2372 | rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_OFDM, 1); |
2110 | rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_MM20, 1); | 2373 | rt2x00_set_field32(®, GF40_PROT_CFG_TX_OP_ALLOW_MM20, 1); |
@@ -2346,15 +2609,31 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | |||
2346 | rt2800_wait_bbp_ready(rt2x00dev))) | 2609 | rt2800_wait_bbp_ready(rt2x00dev))) |
2347 | return -EACCES; | 2610 | return -EACCES; |
2348 | 2611 | ||
2349 | if (rt2800_is_305x_soc(rt2x00dev)) | 2612 | if (rt2x00_rt(rt2x00dev, RT5390)) { |
2613 | rt2800_bbp_read(rt2x00dev, 4, &value); | ||
2614 | rt2x00_set_field8(&value, BBP4_MAC_IF_CTRL, 1); | ||
2615 | rt2800_bbp_write(rt2x00dev, 4, value); | ||
2616 | } | ||
2617 | |||
2618 | if (rt2800_is_305x_soc(rt2x00dev) || | ||
2619 | rt2x00_rt(rt2x00dev, RT5390)) | ||
2350 | rt2800_bbp_write(rt2x00dev, 31, 0x08); | 2620 | rt2800_bbp_write(rt2x00dev, 31, 0x08); |
2351 | 2621 | ||
2352 | rt2800_bbp_write(rt2x00dev, 65, 0x2c); | 2622 | rt2800_bbp_write(rt2x00dev, 65, 0x2c); |
2353 | rt2800_bbp_write(rt2x00dev, 66, 0x38); | 2623 | rt2800_bbp_write(rt2x00dev, 66, 0x38); |
2354 | 2624 | ||
2625 | if (rt2x00_rt(rt2x00dev, RT5390)) | ||
2626 | rt2800_bbp_write(rt2x00dev, 68, 0x0b); | ||
2627 | |||
2355 | if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) { | 2628 | if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) { |
2356 | rt2800_bbp_write(rt2x00dev, 69, 0x16); | 2629 | rt2800_bbp_write(rt2x00dev, 69, 0x16); |
2357 | rt2800_bbp_write(rt2x00dev, 73, 0x12); | 2630 | rt2800_bbp_write(rt2x00dev, 73, 0x12); |
2631 | } else if (rt2x00_rt(rt2x00dev, RT5390)) { | ||
2632 | rt2800_bbp_write(rt2x00dev, 69, 0x12); | ||
2633 | rt2800_bbp_write(rt2x00dev, 73, 0x13); | ||
2634 | rt2800_bbp_write(rt2x00dev, 75, 0x46); | ||
2635 | rt2800_bbp_write(rt2x00dev, 76, 0x28); | ||
2636 | rt2800_bbp_write(rt2x00dev, 77, 0x59); | ||
2358 | } else { | 2637 | } else { |
2359 | rt2800_bbp_write(rt2x00dev, 69, 0x12); | 2638 | rt2800_bbp_write(rt2x00dev, 69, 0x12); |
2360 | rt2800_bbp_write(rt2x00dev, 73, 0x10); | 2639 | rt2800_bbp_write(rt2x00dev, 73, 0x10); |
@@ -2365,7 +2644,8 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | |||
2365 | if (rt2x00_rt(rt2x00dev, RT3070) || | 2644 | if (rt2x00_rt(rt2x00dev, RT3070) || |
2366 | rt2x00_rt(rt2x00dev, RT3071) || | 2645 | rt2x00_rt(rt2x00dev, RT3071) || |
2367 | rt2x00_rt(rt2x00dev, RT3090) || | 2646 | rt2x00_rt(rt2x00dev, RT3090) || |
2368 | rt2x00_rt(rt2x00dev, RT3390)) { | 2647 | rt2x00_rt(rt2x00dev, RT3390) || |
2648 | rt2x00_rt(rt2x00dev, RT5390)) { | ||
2369 | rt2800_bbp_write(rt2x00dev, 79, 0x13); | 2649 | rt2800_bbp_write(rt2x00dev, 79, 0x13); |
2370 | rt2800_bbp_write(rt2x00dev, 80, 0x05); | 2650 | rt2800_bbp_write(rt2x00dev, 80, 0x05); |
2371 | rt2800_bbp_write(rt2x00dev, 81, 0x33); | 2651 | rt2800_bbp_write(rt2x00dev, 81, 0x33); |
@@ -2377,35 +2657,62 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | |||
2377 | } | 2657 | } |
2378 | 2658 | ||
2379 | rt2800_bbp_write(rt2x00dev, 82, 0x62); | 2659 | rt2800_bbp_write(rt2x00dev, 82, 0x62); |
2380 | rt2800_bbp_write(rt2x00dev, 83, 0x6a); | 2660 | if (rt2x00_rt(rt2x00dev, RT5390)) |
2661 | rt2800_bbp_write(rt2x00dev, 83, 0x7a); | ||
2662 | else | ||
2663 | rt2800_bbp_write(rt2x00dev, 83, 0x6a); | ||
2381 | 2664 | ||
2382 | if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D)) | 2665 | if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D)) |
2383 | rt2800_bbp_write(rt2x00dev, 84, 0x19); | 2666 | rt2800_bbp_write(rt2x00dev, 84, 0x19); |
2667 | else if (rt2x00_rt(rt2x00dev, RT5390)) | ||
2668 | rt2800_bbp_write(rt2x00dev, 84, 0x9a); | ||
2384 | else | 2669 | else |
2385 | rt2800_bbp_write(rt2x00dev, 84, 0x99); | 2670 | rt2800_bbp_write(rt2x00dev, 84, 0x99); |
2386 | 2671 | ||
2387 | rt2800_bbp_write(rt2x00dev, 86, 0x00); | 2672 | if (rt2x00_rt(rt2x00dev, RT5390)) |
2673 | rt2800_bbp_write(rt2x00dev, 86, 0x38); | ||
2674 | else | ||
2675 | rt2800_bbp_write(rt2x00dev, 86, 0x00); | ||
2676 | |||
2388 | rt2800_bbp_write(rt2x00dev, 91, 0x04); | 2677 | rt2800_bbp_write(rt2x00dev, 91, 0x04); |
2389 | rt2800_bbp_write(rt2x00dev, 92, 0x00); | 2678 | |
2679 | if (rt2x00_rt(rt2x00dev, RT5390)) | ||
2680 | rt2800_bbp_write(rt2x00dev, 92, 0x02); | ||
2681 | else | ||
2682 | rt2800_bbp_write(rt2x00dev, 92, 0x00); | ||
2390 | 2683 | ||
2391 | if (rt2x00_rt_rev_gte(rt2x00dev, RT3070, REV_RT3070F) || | 2684 | if (rt2x00_rt_rev_gte(rt2x00dev, RT3070, REV_RT3070F) || |
2392 | rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) || | 2685 | rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) || |
2393 | rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) || | 2686 | rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) || |
2394 | rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) || | 2687 | rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) || |
2688 | rt2x00_rt(rt2x00dev, RT5390) || | ||
2395 | rt2800_is_305x_soc(rt2x00dev)) | 2689 | rt2800_is_305x_soc(rt2x00dev)) |
2396 | rt2800_bbp_write(rt2x00dev, 103, 0xc0); | 2690 | rt2800_bbp_write(rt2x00dev, 103, 0xc0); |
2397 | else | 2691 | else |
2398 | rt2800_bbp_write(rt2x00dev, 103, 0x00); | 2692 | rt2800_bbp_write(rt2x00dev, 103, 0x00); |
2399 | 2693 | ||
2694 | if (rt2x00_rt(rt2x00dev, RT5390)) | ||
2695 | rt2800_bbp_write(rt2x00dev, 104, 0x92); | ||
2696 | |||
2400 | if (rt2800_is_305x_soc(rt2x00dev)) | 2697 | if (rt2800_is_305x_soc(rt2x00dev)) |
2401 | rt2800_bbp_write(rt2x00dev, 105, 0x01); | 2698 | rt2800_bbp_write(rt2x00dev, 105, 0x01); |
2699 | else if (rt2x00_rt(rt2x00dev, RT5390)) | ||
2700 | rt2800_bbp_write(rt2x00dev, 105, 0x3c); | ||
2402 | else | 2701 | else |
2403 | rt2800_bbp_write(rt2x00dev, 105, 0x05); | 2702 | rt2800_bbp_write(rt2x00dev, 105, 0x05); |
2404 | rt2800_bbp_write(rt2x00dev, 106, 0x35); | 2703 | |
2704 | if (rt2x00_rt(rt2x00dev, RT5390)) | ||
2705 | rt2800_bbp_write(rt2x00dev, 106, 0x03); | ||
2706 | else | ||
2707 | rt2800_bbp_write(rt2x00dev, 106, 0x35); | ||
2708 | |||
2709 | if (rt2x00_rt(rt2x00dev, RT5390)) | ||
2710 | rt2800_bbp_write(rt2x00dev, 128, 0x12); | ||
2405 | 2711 | ||
2406 | if (rt2x00_rt(rt2x00dev, RT3071) || | 2712 | if (rt2x00_rt(rt2x00dev, RT3071) || |
2407 | rt2x00_rt(rt2x00dev, RT3090) || | 2713 | rt2x00_rt(rt2x00dev, RT3090) || |
2408 | rt2x00_rt(rt2x00dev, RT3390)) { | 2714 | rt2x00_rt(rt2x00dev, RT3390) || |
2715 | rt2x00_rt(rt2x00dev, RT5390)) { | ||
2409 | rt2800_bbp_read(rt2x00dev, 138, &value); | 2716 | rt2800_bbp_read(rt2x00dev, 138, &value); |
2410 | 2717 | ||
2411 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); | 2718 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); |
@@ -2417,6 +2724,41 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | |||
2417 | rt2800_bbp_write(rt2x00dev, 138, value); | 2724 | rt2800_bbp_write(rt2x00dev, 138, value); |
2418 | } | 2725 | } |
2419 | 2726 | ||
2727 | if (rt2x00_rt(rt2x00dev, RT5390)) { | ||
2728 | int ant, div_mode; | ||
2729 | |||
2730 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); | ||
2731 | div_mode = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_ANT_DIVERSITY); | ||
2732 | ant = (div_mode == 3) ? 1 : 0; | ||
2733 | |||
2734 | /* check if this is a Bluetooth combo card */ | ||
2735 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); | ||
2736 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) { | ||
2737 | u32 reg; | ||
2738 | |||
2739 | rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); | ||
2740 | rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT3, 0); | ||
2741 | rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT6, 0); | ||
2742 | rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT3, 0); | ||
2743 | rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT6, 0); | ||
2744 | if (ant == 0) | ||
2745 | rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT3, 1); | ||
2746 | else if (ant == 1) | ||
2747 | rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT6, 1); | ||
2748 | rt2800_register_write(rt2x00dev, GPIO_CTRL_CFG, reg); | ||
2749 | } | ||
2750 | |||
2751 | rt2800_bbp_read(rt2x00dev, 152, &value); | ||
2752 | if (ant == 0) | ||
2753 | rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 1); | ||
2754 | else | ||
2755 | rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 0); | ||
2756 | rt2800_bbp_write(rt2x00dev, 152, value); | ||
2757 | |||
2758 | /* Init frequency calibration */ | ||
2759 | rt2800_bbp_write(rt2x00dev, 142, 1); | ||
2760 | rt2800_bbp_write(rt2x00dev, 143, 57); | ||
2761 | } | ||
2420 | 2762 | ||
2421 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { | 2763 | for (i = 0; i < EEPROM_BBP_SIZE; i++) { |
2422 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); | 2764 | rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom); |
@@ -2506,18 +2848,28 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
2506 | !rt2x00_rt(rt2x00dev, RT3071) && | 2848 | !rt2x00_rt(rt2x00dev, RT3071) && |
2507 | !rt2x00_rt(rt2x00dev, RT3090) && | 2849 | !rt2x00_rt(rt2x00dev, RT3090) && |
2508 | !rt2x00_rt(rt2x00dev, RT3390) && | 2850 | !rt2x00_rt(rt2x00dev, RT3390) && |
2851 | !rt2x00_rt(rt2x00dev, RT5390) && | ||
2509 | !rt2800_is_305x_soc(rt2x00dev)) | 2852 | !rt2800_is_305x_soc(rt2x00dev)) |
2510 | return 0; | 2853 | return 0; |
2511 | 2854 | ||
2512 | /* | 2855 | /* |
2513 | * Init RF calibration. | 2856 | * Init RF calibration. |
2514 | */ | 2857 | */ |
2515 | rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); | 2858 | if (rt2x00_rt(rt2x00dev, RT5390)) { |
2516 | rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); | 2859 | rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr); |
2517 | rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); | 2860 | rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1); |
2518 | msleep(1); | 2861 | rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); |
2519 | rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0); | 2862 | msleep(1); |
2520 | rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); | 2863 | rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 0); |
2864 | rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); | ||
2865 | } else { | ||
2866 | rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); | ||
2867 | rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); | ||
2868 | rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); | ||
2869 | msleep(1); | ||
2870 | rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0); | ||
2871 | rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); | ||
2872 | } | ||
2521 | 2873 | ||
2522 | if (rt2x00_rt(rt2x00dev, RT3070) || | 2874 | if (rt2x00_rt(rt2x00dev, RT3070) || |
2523 | rt2x00_rt(rt2x00dev, RT3071) || | 2875 | rt2x00_rt(rt2x00dev, RT3071) || |
@@ -2608,6 +2960,87 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
2608 | rt2800_rfcsr_write(rt2x00dev, 30, 0x00); | 2960 | rt2800_rfcsr_write(rt2x00dev, 30, 0x00); |
2609 | rt2800_rfcsr_write(rt2x00dev, 31, 0x00); | 2961 | rt2800_rfcsr_write(rt2x00dev, 31, 0x00); |
2610 | return 0; | 2962 | return 0; |
2963 | } else if (rt2x00_rt(rt2x00dev, RT5390)) { | ||
2964 | rt2800_rfcsr_write(rt2x00dev, 1, 0x0f); | ||
2965 | rt2800_rfcsr_write(rt2x00dev, 2, 0x80); | ||
2966 | rt2800_rfcsr_write(rt2x00dev, 3, 0x88); | ||
2967 | rt2800_rfcsr_write(rt2x00dev, 5, 0x10); | ||
2968 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) | ||
2969 | rt2800_rfcsr_write(rt2x00dev, 6, 0xe0); | ||
2970 | else | ||
2971 | rt2800_rfcsr_write(rt2x00dev, 6, 0xa0); | ||
2972 | rt2800_rfcsr_write(rt2x00dev, 7, 0x00); | ||
2973 | rt2800_rfcsr_write(rt2x00dev, 10, 0x53); | ||
2974 | rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); | ||
2975 | rt2800_rfcsr_write(rt2x00dev, 12, 0xc6); | ||
2976 | rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); | ||
2977 | rt2800_rfcsr_write(rt2x00dev, 14, 0x00); | ||
2978 | rt2800_rfcsr_write(rt2x00dev, 15, 0x00); | ||
2979 | rt2800_rfcsr_write(rt2x00dev, 16, 0x00); | ||
2980 | rt2800_rfcsr_write(rt2x00dev, 18, 0x03); | ||
2981 | rt2800_rfcsr_write(rt2x00dev, 19, 0x00); | ||
2982 | |||
2983 | rt2800_rfcsr_write(rt2x00dev, 20, 0x00); | ||
2984 | rt2800_rfcsr_write(rt2x00dev, 21, 0x00); | ||
2985 | rt2800_rfcsr_write(rt2x00dev, 22, 0x20); | ||
2986 | rt2800_rfcsr_write(rt2x00dev, 23, 0x00); | ||
2987 | rt2800_rfcsr_write(rt2x00dev, 24, 0x00); | ||
2988 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) | ||
2989 | rt2800_rfcsr_write(rt2x00dev, 25, 0x80); | ||
2990 | else | ||
2991 | rt2800_rfcsr_write(rt2x00dev, 25, 0xc0); | ||
2992 | rt2800_rfcsr_write(rt2x00dev, 26, 0x00); | ||
2993 | rt2800_rfcsr_write(rt2x00dev, 27, 0x09); | ||
2994 | rt2800_rfcsr_write(rt2x00dev, 28, 0x00); | ||
2995 | rt2800_rfcsr_write(rt2x00dev, 29, 0x10); | ||
2996 | |||
2997 | rt2800_rfcsr_write(rt2x00dev, 30, 0x00); | ||
2998 | rt2800_rfcsr_write(rt2x00dev, 31, 0x80); | ||
2999 | rt2800_rfcsr_write(rt2x00dev, 32, 0x80); | ||
3000 | rt2800_rfcsr_write(rt2x00dev, 33, 0x00); | ||
3001 | rt2800_rfcsr_write(rt2x00dev, 34, 0x07); | ||
3002 | rt2800_rfcsr_write(rt2x00dev, 35, 0x12); | ||
3003 | rt2800_rfcsr_write(rt2x00dev, 36, 0x00); | ||
3004 | rt2800_rfcsr_write(rt2x00dev, 37, 0x08); | ||
3005 | rt2800_rfcsr_write(rt2x00dev, 38, 0x85); | ||
3006 | rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); | ||
3007 | |||
3008 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) | ||
3009 | rt2800_rfcsr_write(rt2x00dev, 40, 0x0b); | ||
3010 | else | ||
3011 | rt2800_rfcsr_write(rt2x00dev, 40, 0x4b); | ||
3012 | rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); | ||
3013 | rt2800_rfcsr_write(rt2x00dev, 42, 0xd2); | ||
3014 | rt2800_rfcsr_write(rt2x00dev, 43, 0x9a); | ||
3015 | rt2800_rfcsr_write(rt2x00dev, 44, 0x0e); | ||
3016 | rt2800_rfcsr_write(rt2x00dev, 45, 0xa2); | ||
3017 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) | ||
3018 | rt2800_rfcsr_write(rt2x00dev, 46, 0x73); | ||
3019 | else | ||
3020 | rt2800_rfcsr_write(rt2x00dev, 46, 0x7b); | ||
3021 | rt2800_rfcsr_write(rt2x00dev, 47, 0x00); | ||
3022 | rt2800_rfcsr_write(rt2x00dev, 48, 0x10); | ||
3023 | rt2800_rfcsr_write(rt2x00dev, 49, 0x94); | ||
3024 | |||
3025 | rt2800_rfcsr_write(rt2x00dev, 52, 0x38); | ||
3026 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) | ||
3027 | rt2800_rfcsr_write(rt2x00dev, 53, 0x00); | ||
3028 | else | ||
3029 | rt2800_rfcsr_write(rt2x00dev, 53, 0x84); | ||
3030 | rt2800_rfcsr_write(rt2x00dev, 54, 0x78); | ||
3031 | rt2800_rfcsr_write(rt2x00dev, 55, 0x44); | ||
3032 | rt2800_rfcsr_write(rt2x00dev, 56, 0x22); | ||
3033 | rt2800_rfcsr_write(rt2x00dev, 57, 0x80); | ||
3034 | rt2800_rfcsr_write(rt2x00dev, 58, 0x7f); | ||
3035 | rt2800_rfcsr_write(rt2x00dev, 59, 0x63); | ||
3036 | |||
3037 | rt2800_rfcsr_write(rt2x00dev, 60, 0x45); | ||
3038 | if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) | ||
3039 | rt2800_rfcsr_write(rt2x00dev, 61, 0xd1); | ||
3040 | else | ||
3041 | rt2800_rfcsr_write(rt2x00dev, 61, 0xdd); | ||
3042 | rt2800_rfcsr_write(rt2x00dev, 62, 0x00); | ||
3043 | rt2800_rfcsr_write(rt2x00dev, 63, 0x00); | ||
2611 | } | 3044 | } |
2612 | 3045 | ||
2613 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) { | 3046 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) { |
@@ -2661,21 +3094,23 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
2661 | rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x15); | 3094 | rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x15); |
2662 | } | 3095 | } |
2663 | 3096 | ||
2664 | /* | 3097 | if (!rt2x00_rt(rt2x00dev, RT5390)) { |
2665 | * Set back to initial state | 3098 | /* |
2666 | */ | 3099 | * Set back to initial state |
2667 | rt2800_bbp_write(rt2x00dev, 24, 0); | 3100 | */ |
3101 | rt2800_bbp_write(rt2x00dev, 24, 0); | ||
2668 | 3102 | ||
2669 | rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr); | 3103 | rt2800_rfcsr_read(rt2x00dev, 22, &rfcsr); |
2670 | rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 0); | 3104 | rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 0); |
2671 | rt2800_rfcsr_write(rt2x00dev, 22, rfcsr); | 3105 | rt2800_rfcsr_write(rt2x00dev, 22, rfcsr); |
2672 | 3106 | ||
2673 | /* | 3107 | /* |
2674 | * set BBP back to BW20 | 3108 | * Set BBP back to BW20 |
2675 | */ | 3109 | */ |
2676 | rt2800_bbp_read(rt2x00dev, 4, &bbp); | 3110 | rt2800_bbp_read(rt2x00dev, 4, &bbp); |
2677 | rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 0); | 3111 | rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 0); |
2678 | rt2800_bbp_write(rt2x00dev, 4, bbp); | 3112 | rt2800_bbp_write(rt2x00dev, 4, bbp); |
3113 | } | ||
2679 | 3114 | ||
2680 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F) || | 3115 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F) || |
2681 | rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || | 3116 | rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || |
@@ -2687,21 +3122,23 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
2687 | rt2x00_set_field32(®, OPT_14_CSR_BIT0, 1); | 3122 | rt2x00_set_field32(®, OPT_14_CSR_BIT0, 1); |
2688 | rt2800_register_write(rt2x00dev, OPT_14_CSR, reg); | 3123 | rt2800_register_write(rt2x00dev, OPT_14_CSR, reg); |
2689 | 3124 | ||
2690 | rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); | 3125 | if (!rt2x00_rt(rt2x00dev, RT5390)) { |
2691 | rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0); | 3126 | rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); |
2692 | if (rt2x00_rt(rt2x00dev, RT3070) || | 3127 | rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0); |
2693 | rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || | 3128 | if (rt2x00_rt(rt2x00dev, RT3070) || |
2694 | rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || | 3129 | rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || |
2695 | rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) { | 3130 | rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || |
2696 | if (!test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) | 3131 | rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) { |
2697 | rt2x00_set_field8(&rfcsr, RFCSR17_R, 1); | 3132 | if (!test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) |
2698 | } | 3133 | rt2x00_set_field8(&rfcsr, RFCSR17_R, 1); |
2699 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom); | 3134 | } |
2700 | if (rt2x00_get_field16(eeprom, EEPROM_TXMIXER_GAIN_BG_VAL) >= 1) | 3135 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom); |
2701 | rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN, | 3136 | if (rt2x00_get_field16(eeprom, EEPROM_TXMIXER_GAIN_BG_VAL) >= 1) |
2702 | rt2x00_get_field16(eeprom, | 3137 | rt2x00_set_field8(&rfcsr, RFCSR17_TXMIXER_GAIN, |
2703 | EEPROM_TXMIXER_GAIN_BG_VAL)); | 3138 | rt2x00_get_field16(eeprom, |
2704 | rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); | 3139 | EEPROM_TXMIXER_GAIN_BG_VAL)); |
3140 | rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); | ||
3141 | } | ||
2705 | 3142 | ||
2706 | if (rt2x00_rt(rt2x00dev, RT3090)) { | 3143 | if (rt2x00_rt(rt2x00dev, RT3090)) { |
2707 | rt2800_bbp_read(rt2x00dev, 138, &bbp); | 3144 | rt2800_bbp_read(rt2x00dev, 138, &bbp); |
@@ -2752,6 +3189,20 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
2752 | rt2800_rfcsr_write(rt2x00dev, 27, rfcsr); | 3189 | rt2800_rfcsr_write(rt2x00dev, 27, rfcsr); |
2753 | } | 3190 | } |
2754 | 3191 | ||
3192 | if (rt2x00_rt(rt2x00dev, RT5390)) { | ||
3193 | rt2800_rfcsr_read(rt2x00dev, 38, &rfcsr); | ||
3194 | rt2x00_set_field8(&rfcsr, RFCSR38_RX_LO1_EN, 0); | ||
3195 | rt2800_rfcsr_write(rt2x00dev, 38, rfcsr); | ||
3196 | |||
3197 | rt2800_rfcsr_read(rt2x00dev, 39, &rfcsr); | ||
3198 | rt2x00_set_field8(&rfcsr, RFCSR39_RX_LO2_EN, 0); | ||
3199 | rt2800_rfcsr_write(rt2x00dev, 39, rfcsr); | ||
3200 | |||
3201 | rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); | ||
3202 | rt2x00_set_field8(&rfcsr, RFCSR30_RX_VCM, 2); | ||
3203 | rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); | ||
3204 | } | ||
3205 | |||
2755 | return 0; | 3206 | return 0; |
2756 | } | 3207 | } |
2757 | 3208 | ||
@@ -3000,13 +3451,6 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
3000 | default_lna_gain); | 3451 | default_lna_gain); |
3001 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word); | 3452 | rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word); |
3002 | 3453 | ||
3003 | rt2x00_eeprom_read(rt2x00dev, EEPROM_MAX_TX_POWER, &word); | ||
3004 | if (rt2x00_get_field16(word, EEPROM_MAX_TX_POWER_24GHZ) == 0xff) | ||
3005 | rt2x00_set_field16(&word, EEPROM_MAX_TX_POWER_24GHZ, MAX_G_TXPOWER); | ||
3006 | if (rt2x00_get_field16(word, EEPROM_MAX_TX_POWER_5GHZ) == 0xff) | ||
3007 | rt2x00_set_field16(&word, EEPROM_MAX_TX_POWER_5GHZ, MAX_A_TXPOWER); | ||
3008 | rt2x00_eeprom_write(rt2x00dev, EEPROM_MAX_TX_POWER, word); | ||
3009 | |||
3010 | return 0; | 3454 | return 0; |
3011 | } | 3455 | } |
3012 | EXPORT_SYMBOL_GPL(rt2800_validate_eeprom); | 3456 | EXPORT_SYMBOL_GPL(rt2800_validate_eeprom); |
@@ -3023,10 +3467,15 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
3023 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); | 3467 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF0, &eeprom); |
3024 | 3468 | ||
3025 | /* | 3469 | /* |
3026 | * Identify RF chipset. | 3470 | * Identify RF chipset by EEPROM value |
3471 | * RT28xx/RT30xx: defined in "EEPROM_NIC_CONF0_RF_TYPE" field | ||
3472 | * RT53xx: defined in "EEPROM_CHIP_ID" field | ||
3027 | */ | 3473 | */ |
3028 | value = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE); | ||
3029 | rt2800_register_read(rt2x00dev, MAC_CSR0, ®); | 3474 | rt2800_register_read(rt2x00dev, MAC_CSR0, ®); |
3475 | if (rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5390) | ||
3476 | rt2x00_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &value); | ||
3477 | else | ||
3478 | value = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE); | ||
3030 | 3479 | ||
3031 | rt2x00_set_chip(rt2x00dev, rt2x00_get_field32(reg, MAC_CSR0_CHIPSET), | 3480 | rt2x00_set_chip(rt2x00dev, rt2x00_get_field32(reg, MAC_CSR0_CHIPSET), |
3032 | value, rt2x00_get_field32(reg, MAC_CSR0_REVISION)); | 3481 | value, rt2x00_get_field32(reg, MAC_CSR0_REVISION)); |
@@ -3038,7 +3487,8 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
3038 | !rt2x00_rt(rt2x00dev, RT3071) && | 3487 | !rt2x00_rt(rt2x00dev, RT3071) && |
3039 | !rt2x00_rt(rt2x00dev, RT3090) && | 3488 | !rt2x00_rt(rt2x00dev, RT3090) && |
3040 | !rt2x00_rt(rt2x00dev, RT3390) && | 3489 | !rt2x00_rt(rt2x00dev, RT3390) && |
3041 | !rt2x00_rt(rt2x00dev, RT3572)) { | 3490 | !rt2x00_rt(rt2x00dev, RT3572) && |
3491 | !rt2x00_rt(rt2x00dev, RT5390)) { | ||
3042 | ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); | 3492 | ERROR(rt2x00dev, "Invalid RT chipset detected.\n"); |
3043 | return -ENODEV; | 3493 | return -ENODEV; |
3044 | } | 3494 | } |
@@ -3052,7 +3502,8 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
3052 | !rt2x00_rf(rt2x00dev, RF3021) && | 3502 | !rt2x00_rf(rt2x00dev, RF3021) && |
3053 | !rt2x00_rf(rt2x00dev, RF3022) && | 3503 | !rt2x00_rf(rt2x00dev, RF3022) && |
3054 | !rt2x00_rf(rt2x00dev, RF3052) && | 3504 | !rt2x00_rf(rt2x00dev, RF3052) && |
3055 | !rt2x00_rf(rt2x00dev, RF3320)) { | 3505 | !rt2x00_rf(rt2x00dev, RF3320) && |
3506 | !rt2x00_rf(rt2x00dev, RF5390)) { | ||
3056 | ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); | 3507 | ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); |
3057 | return -ENODEV; | 3508 | return -ENODEV; |
3058 | } | 3509 | } |
@@ -3060,11 +3511,35 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
3060 | /* | 3511 | /* |
3061 | * Identify default antenna configuration. | 3512 | * Identify default antenna configuration. |
3062 | */ | 3513 | */ |
3063 | rt2x00dev->default_ant.tx = | 3514 | rt2x00dev->default_ant.tx_chain_num = |
3064 | rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH); | 3515 | rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_TXPATH); |
3065 | rt2x00dev->default_ant.rx = | 3516 | rt2x00dev->default_ant.rx_chain_num = |
3066 | rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH); | 3517 | rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RXPATH); |
3067 | 3518 | ||
3519 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); | ||
3520 | |||
3521 | if (rt2x00_rt(rt2x00dev, RT3070) || | ||
3522 | rt2x00_rt(rt2x00dev, RT3090) || | ||
3523 | rt2x00_rt(rt2x00dev, RT3390)) { | ||
3524 | value = rt2x00_get_field16(eeprom, | ||
3525 | EEPROM_NIC_CONF1_ANT_DIVERSITY); | ||
3526 | switch (value) { | ||
3527 | case 0: | ||
3528 | case 1: | ||
3529 | case 2: | ||
3530 | rt2x00dev->default_ant.tx = ANTENNA_A; | ||
3531 | rt2x00dev->default_ant.rx = ANTENNA_A; | ||
3532 | break; | ||
3533 | case 3: | ||
3534 | rt2x00dev->default_ant.tx = ANTENNA_A; | ||
3535 | rt2x00dev->default_ant.rx = ANTENNA_B; | ||
3536 | break; | ||
3537 | } | ||
3538 | } else { | ||
3539 | rt2x00dev->default_ant.tx = ANTENNA_A; | ||
3540 | rt2x00dev->default_ant.rx = ANTENNA_A; | ||
3541 | } | ||
3542 | |||
3068 | /* | 3543 | /* |
3069 | * Read frequency offset and RF programming sequence. | 3544 | * Read frequency offset and RF programming sequence. |
3070 | */ | 3545 | */ |
@@ -3098,6 +3573,15 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
3098 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &rt2x00dev->led_mcu_reg); | 3573 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &rt2x00dev->led_mcu_reg); |
3099 | #endif /* CONFIG_RT2X00_LIB_LEDS */ | 3574 | #endif /* CONFIG_RT2X00_LIB_LEDS */ |
3100 | 3575 | ||
3576 | /* | ||
3577 | * Check if support EIRP tx power limit feature. | ||
3578 | */ | ||
3579 | rt2x00_eeprom_read(rt2x00dev, EEPROM_EIRP_MAX_TX_POWER, &eeprom); | ||
3580 | |||
3581 | if (rt2x00_get_field16(eeprom, EEPROM_EIRP_MAX_TX_POWER_2GHZ) < | ||
3582 | EIRP_MAX_TX_POWER_LIMIT) | ||
3583 | __set_bit(CONFIG_SUPPORT_POWER_LIMIT, &rt2x00dev->flags); | ||
3584 | |||
3101 | return 0; | 3585 | return 0; |
3102 | } | 3586 | } |
3103 | EXPORT_SYMBOL_GPL(rt2800_init_eeprom); | 3587 | EXPORT_SYMBOL_GPL(rt2800_init_eeprom); |
@@ -3250,7 +3734,6 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
3250 | char *default_power1; | 3734 | char *default_power1; |
3251 | char *default_power2; | 3735 | char *default_power2; |
3252 | unsigned int i; | 3736 | unsigned int i; |
3253 | unsigned short max_power; | ||
3254 | u16 eeprom; | 3737 | u16 eeprom; |
3255 | 3738 | ||
3256 | /* | 3739 | /* |
@@ -3317,7 +3800,8 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
3317 | rt2x00_rf(rt2x00dev, RF2020) || | 3800 | rt2x00_rf(rt2x00dev, RF2020) || |
3318 | rt2x00_rf(rt2x00dev, RF3021) || | 3801 | rt2x00_rf(rt2x00dev, RF3021) || |
3319 | rt2x00_rf(rt2x00dev, RF3022) || | 3802 | rt2x00_rf(rt2x00dev, RF3022) || |
3320 | rt2x00_rf(rt2x00dev, RF3320)) { | 3803 | rt2x00_rf(rt2x00dev, RF3320) || |
3804 | rt2x00_rf(rt2x00dev, RF5390)) { | ||
3321 | spec->num_channels = 14; | 3805 | spec->num_channels = 14; |
3322 | spec->channels = rf_vals_3x; | 3806 | spec->channels = rf_vals_3x; |
3323 | } else if (rt2x00_rf(rt2x00dev, RF3052)) { | 3807 | } else if (rt2x00_rf(rt2x00dev, RF3052)) { |
@@ -3375,26 +3859,21 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
3375 | 3859 | ||
3376 | spec->channels_info = info; | 3860 | spec->channels_info = info; |
3377 | 3861 | ||
3378 | rt2x00_eeprom_read(rt2x00dev, EEPROM_MAX_TX_POWER, &eeprom); | ||
3379 | max_power = rt2x00_get_field16(eeprom, EEPROM_MAX_TX_POWER_24GHZ); | ||
3380 | default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1); | 3862 | default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1); |
3381 | default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2); | 3863 | default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2); |
3382 | 3864 | ||
3383 | for (i = 0; i < 14; i++) { | 3865 | for (i = 0; i < 14; i++) { |
3384 | info[i].max_power = max_power; | 3866 | info[i].default_power1 = default_power1[i]; |
3385 | info[i].default_power1 = TXPOWER_G_FROM_DEV(default_power1[i]); | 3867 | info[i].default_power2 = default_power2[i]; |
3386 | info[i].default_power2 = TXPOWER_G_FROM_DEV(default_power2[i]); | ||
3387 | } | 3868 | } |
3388 | 3869 | ||
3389 | if (spec->num_channels > 14) { | 3870 | if (spec->num_channels > 14) { |
3390 | max_power = rt2x00_get_field16(eeprom, EEPROM_MAX_TX_POWER_5GHZ); | ||
3391 | default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1); | 3871 | default_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1); |
3392 | default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2); | 3872 | default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2); |
3393 | 3873 | ||
3394 | for (i = 14; i < spec->num_channels; i++) { | 3874 | for (i = 14; i < spec->num_channels; i++) { |
3395 | info[i].max_power = max_power; | 3875 | info[i].default_power1 = default_power1[i]; |
3396 | info[i].default_power1 = TXPOWER_A_FROM_DEV(default_power1[i]); | 3876 | info[i].default_power2 = default_power2[i]; |
3397 | info[i].default_power2 = TXPOWER_A_FROM_DEV(default_power2[i]); | ||
3398 | } | 3877 | } |
3399 | } | 3878 | } |
3400 | 3879 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 8f4dfc3d8023..38605e9fe427 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
@@ -493,6 +493,13 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
493 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); | 493 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); |
494 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); | 494 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); |
495 | 495 | ||
496 | if (rt2x00_rt(rt2x00dev, RT5390)) { | ||
497 | rt2800_register_read(rt2x00dev, AUX_CTRL, ®); | ||
498 | rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1); | ||
499 | rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1); | ||
500 | rt2800_register_write(rt2x00dev, AUX_CTRL, reg); | ||
501 | } | ||
502 | |||
496 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); | 503 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); |
497 | 504 | ||
498 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | 505 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); |
@@ -1119,12 +1126,17 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { | |||
1119 | { PCI_DEVICE(0x1814, 0x3390), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1126 | { PCI_DEVICE(0x1814, 0x3390), PCI_DEVICE_DATA(&rt2800pci_ops) }, |
1120 | #endif | 1127 | #endif |
1121 | #ifdef CONFIG_RT2800PCI_RT35XX | 1128 | #ifdef CONFIG_RT2800PCI_RT35XX |
1129 | { PCI_DEVICE(0x1432, 0x7711), PCI_DEVICE_DATA(&rt2800pci_ops) }, | ||
1130 | { PCI_DEVICE(0x1432, 0x7722), PCI_DEVICE_DATA(&rt2800pci_ops) }, | ||
1122 | { PCI_DEVICE(0x1814, 0x3060), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1131 | { PCI_DEVICE(0x1814, 0x3060), PCI_DEVICE_DATA(&rt2800pci_ops) }, |
1123 | { PCI_DEVICE(0x1814, 0x3062), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1132 | { PCI_DEVICE(0x1814, 0x3062), PCI_DEVICE_DATA(&rt2800pci_ops) }, |
1124 | { PCI_DEVICE(0x1814, 0x3562), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1133 | { PCI_DEVICE(0x1814, 0x3562), PCI_DEVICE_DATA(&rt2800pci_ops) }, |
1125 | { PCI_DEVICE(0x1814, 0x3592), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1134 | { PCI_DEVICE(0x1814, 0x3592), PCI_DEVICE_DATA(&rt2800pci_ops) }, |
1126 | { PCI_DEVICE(0x1814, 0x3593), PCI_DEVICE_DATA(&rt2800pci_ops) }, | 1135 | { PCI_DEVICE(0x1814, 0x3593), PCI_DEVICE_DATA(&rt2800pci_ops) }, |
1127 | #endif | 1136 | #endif |
1137 | #ifdef CONFIG_RT2800PCI_RT53XX | ||
1138 | { PCI_DEVICE(0x1814, 0x5390), PCI_DEVICE_DATA(&rt2800pci_ops) }, | ||
1139 | #endif | ||
1128 | { 0, } | 1140 | { 0, } |
1129 | }; | 1141 | }; |
1130 | #endif /* CONFIG_PCI */ | 1142 | #endif /* CONFIG_PCI */ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 39bc2faf1793..1df432c1f2c7 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -189,6 +189,7 @@ struct rt2x00_chip { | |||
189 | #define RT3572 0x3572 | 189 | #define RT3572 0x3572 |
190 | #define RT3593 0x3593 /* PCIe */ | 190 | #define RT3593 0x3593 /* PCIe */ |
191 | #define RT3883 0x3883 /* WSOC */ | 191 | #define RT3883 0x3883 /* WSOC */ |
192 | #define RT5390 0x5390 /* 2.4GHz */ | ||
192 | 193 | ||
193 | u16 rf; | 194 | u16 rf; |
194 | u16 rev; | 195 | u16 rev; |
@@ -225,6 +226,8 @@ struct channel_info { | |||
225 | struct antenna_setup { | 226 | struct antenna_setup { |
226 | enum antenna rx; | 227 | enum antenna rx; |
227 | enum antenna tx; | 228 | enum antenna tx; |
229 | u8 rx_chain_num; | ||
230 | u8 tx_chain_num; | ||
228 | }; | 231 | }; |
229 | 232 | ||
230 | /* | 233 | /* |
@@ -665,6 +668,7 @@ enum rt2x00_flags { | |||
665 | */ | 668 | */ |
666 | CONFIG_SUPPORT_HW_BUTTON, | 669 | CONFIG_SUPPORT_HW_BUTTON, |
667 | CONFIG_SUPPORT_HW_CRYPTO, | 670 | CONFIG_SUPPORT_HW_CRYPTO, |
671 | CONFIG_SUPPORT_POWER_LIMIT, | ||
668 | DRIVER_SUPPORT_CONTROL_FILTERS, | 672 | DRIVER_SUPPORT_CONTROL_FILTERS, |
669 | DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, | 673 | DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, |
670 | DRIVER_SUPPORT_PRE_TBTT_INTERRUPT, | 674 | DRIVER_SUPPORT_PRE_TBTT_INTERRUPT, |
diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c index b7ad46ecaa1d..03d9579da681 100644 --- a/drivers/net/wireless/rt2x00/rt2x00ht.c +++ b/drivers/net/wireless/rt2x00/rt2x00ht.c | |||
@@ -69,7 +69,6 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, | |||
69 | txdesc->mcs |= 0x08; | 69 | txdesc->mcs |= 0x08; |
70 | } | 70 | } |
71 | 71 | ||
72 | |||
73 | /* | 72 | /* |
74 | * This frame is eligible for an AMPDU, however, don't aggregate | 73 | * This frame is eligible for an AMPDU, however, don't aggregate |
75 | * frames that are intended to probe a specific tx rate. | 74 | * frames that are intended to probe a specific tx rate. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 6a66021d8f65..1b3edef9e3d2 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -139,9 +139,9 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
139 | * either RTS or CTS-to-self frame and handles everything | 139 | * either RTS or CTS-to-self frame and handles everything |
140 | * inside the hardware. | 140 | * inside the hardware. |
141 | */ | 141 | */ |
142 | if ((tx_info->control.rates[0].flags & (IEEE80211_TX_RC_USE_RTS_CTS | | 142 | if (!rt2x00dev->ops->hw->set_rts_threshold && |
143 | IEEE80211_TX_RC_USE_CTS_PROTECT)) && | 143 | (tx_info->control.rates[0].flags & (IEEE80211_TX_RC_USE_RTS_CTS | |
144 | !rt2x00dev->ops->hw->set_rts_threshold) { | 144 | IEEE80211_TX_RC_USE_CTS_PROTECT))) { |
145 | if (rt2x00queue_available(queue) <= 1) | 145 | if (rt2x00queue_available(queue) <= 1) |
146 | goto exit_fail; | 146 | goto exit_fail; |
147 | 147 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index fa17c83b9685..bf9bba356280 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -365,13 +365,10 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | |||
365 | 365 | ||
366 | /* | 366 | /* |
367 | * Beacons and probe responses require the tsf timestamp | 367 | * Beacons and probe responses require the tsf timestamp |
368 | * to be inserted into the frame, except for a frame that has been injected | 368 | * to be inserted into the frame. |
369 | * through a monitor interface. This latter is needed for testing a | ||
370 | * monitor interface. | ||
371 | */ | 369 | */ |
372 | if ((ieee80211_is_beacon(hdr->frame_control) || | 370 | if (ieee80211_is_beacon(hdr->frame_control) || |
373 | ieee80211_is_probe_resp(hdr->frame_control)) && | 371 | ieee80211_is_probe_resp(hdr->frame_control)) |
374 | (!(tx_info->flags & IEEE80211_TX_CTL_INJECTED))) | ||
375 | __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags); | 372 | __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags); |
376 | 373 | ||
377 | /* | 374 | /* |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index dd2164d4d57b..927a4a3e0eeb 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -1978,13 +1978,14 @@ static void rt61pci_write_beacon(struct queue_entry *entry, | |||
1978 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 1978 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; |
1979 | unsigned int beacon_base; | 1979 | unsigned int beacon_base; |
1980 | unsigned int padding_len; | 1980 | unsigned int padding_len; |
1981 | u32 reg; | 1981 | u32 orig_reg, reg; |
1982 | 1982 | ||
1983 | /* | 1983 | /* |
1984 | * Disable beaconing while we are reloading the beacon data, | 1984 | * Disable beaconing while we are reloading the beacon data, |
1985 | * otherwise we might be sending out invalid data. | 1985 | * otherwise we might be sending out invalid data. |
1986 | */ | 1986 | */ |
1987 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | 1987 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); |
1988 | orig_reg = reg; | ||
1988 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | 1989 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); |
1989 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | 1990 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); |
1990 | 1991 | ||
@@ -2002,7 +2003,14 @@ static void rt61pci_write_beacon(struct queue_entry *entry, | |||
2002 | * Write entire beacon with descriptor and padding to register. | 2003 | * Write entire beacon with descriptor and padding to register. |
2003 | */ | 2004 | */ |
2004 | padding_len = roundup(entry->skb->len, 4) - entry->skb->len; | 2005 | padding_len = roundup(entry->skb->len, 4) - entry->skb->len; |
2005 | skb_pad(entry->skb, padding_len); | 2006 | if (padding_len && skb_pad(entry->skb, padding_len)) { |
2007 | ERROR(rt2x00dev, "Failure padding beacon, aborting\n"); | ||
2008 | /* skb freed by skb_pad() on failure */ | ||
2009 | entry->skb = NULL; | ||
2010 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, orig_reg); | ||
2011 | return; | ||
2012 | } | ||
2013 | |||
2006 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); | 2014 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); |
2007 | rt2x00pci_register_multiwrite(rt2x00dev, beacon_base, | 2015 | rt2x00pci_register_multiwrite(rt2x00dev, beacon_base, |
2008 | entry_priv->desc, TXINFO_SIZE); | 2016 | entry_priv->desc, TXINFO_SIZE); |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 5ff72deea8d4..6e9981a1dd7f 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -1533,13 +1533,14 @@ static void rt73usb_write_beacon(struct queue_entry *entry, | |||
1533 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 1533 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
1534 | unsigned int beacon_base; | 1534 | unsigned int beacon_base; |
1535 | unsigned int padding_len; | 1535 | unsigned int padding_len; |
1536 | u32 reg; | 1536 | u32 orig_reg, reg; |
1537 | 1537 | ||
1538 | /* | 1538 | /* |
1539 | * Disable beaconing while we are reloading the beacon data, | 1539 | * Disable beaconing while we are reloading the beacon data, |
1540 | * otherwise we might be sending out invalid data. | 1540 | * otherwise we might be sending out invalid data. |
1541 | */ | 1541 | */ |
1542 | rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®); | 1542 | rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, ®); |
1543 | orig_reg = reg; | ||
1543 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | 1544 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); |
1544 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); | 1545 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); |
1545 | 1546 | ||
@@ -1563,7 +1564,14 @@ static void rt73usb_write_beacon(struct queue_entry *entry, | |||
1563 | * Write entire beacon with descriptor and padding to register. | 1564 | * Write entire beacon with descriptor and padding to register. |
1564 | */ | 1565 | */ |
1565 | padding_len = roundup(entry->skb->len, 4) - entry->skb->len; | 1566 | padding_len = roundup(entry->skb->len, 4) - entry->skb->len; |
1566 | skb_pad(entry->skb, padding_len); | 1567 | if (padding_len && skb_pad(entry->skb, padding_len)) { |
1568 | ERROR(rt2x00dev, "Failure padding beacon, aborting\n"); | ||
1569 | /* skb freed by skb_pad() on failure */ | ||
1570 | entry->skb = NULL; | ||
1571 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, orig_reg); | ||
1572 | return; | ||
1573 | } | ||
1574 | |||
1567 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); | 1575 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); |
1568 | rt2x00usb_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data, | 1576 | rt2x00usb_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data, |
1569 | entry->skb->len + padding_len); | 1577 | entry->skb->len + padding_len); |
diff --git a/drivers/net/wireless/rtlwifi/Kconfig b/drivers/net/wireless/rtlwifi/Kconfig index 7f6573f7f470..86f8d4d64037 100644 --- a/drivers/net/wireless/rtlwifi/Kconfig +++ b/drivers/net/wireless/rtlwifi/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config RTL8192CE | 1 | config RTL8192CE |
2 | tristate "Realtek RTL8192CE/RTL8188SE Wireless Network Adapter" | 2 | tristate "Realtek RTL8192CE/RTL8188CE Wireless Network Adapter" |
3 | depends on MAC80211 && EXPERIMENTAL | 3 | depends on MAC80211 && PCI && EXPERIMENTAL |
4 | select FW_LOADER | 4 | select FW_LOADER |
5 | select RTLWIFI | 5 | select RTLWIFI |
6 | ---help--- | 6 | ---help--- |
@@ -9,7 +9,18 @@ config RTL8192CE | |||
9 | 9 | ||
10 | If you choose to build it as a module, it will be called rtl8192ce | 10 | If you choose to build it as a module, it will be called rtl8192ce |
11 | 11 | ||
12 | config RTL8192CU | ||
13 | tristate "Realtek RTL8192CU/RTL8188CU USB Wireless Network Adapter" | ||
14 | depends on MAC80211 && USB && EXPERIMENTAL | ||
15 | select FW_LOADER | ||
16 | select RTLWIFI | ||
17 | ---help--- | ||
18 | This is the driver for Realtek RTL8192CU/RTL8188CU 802.11n USB | ||
19 | wireless network adapters. | ||
20 | |||
21 | If you choose to build it as a module, it will be called rtl8192cu | ||
22 | |||
12 | config RTLWIFI | 23 | config RTLWIFI |
13 | tristate | 24 | tristate |
14 | depends on RTL8192CE | 25 | depends on RTL8192CE || RTL8192CU |
15 | default m | 26 | default m |
diff --git a/drivers/net/wireless/rtlwifi/Makefile b/drivers/net/wireless/rtlwifi/Makefile index 2a7a4384f8ee..c3e83a1da33b 100644 --- a/drivers/net/wireless/rtlwifi/Makefile +++ b/drivers/net/wireless/rtlwifi/Makefile | |||
@@ -8,6 +8,10 @@ rtlwifi-objs := \ | |||
8 | pci.o \ | 8 | pci.o \ |
9 | ps.o \ | 9 | ps.o \ |
10 | rc.o \ | 10 | rc.o \ |
11 | regd.o | 11 | regd.o \ |
12 | usb.o | ||
12 | 13 | ||
13 | obj-$(CONFIG_RTL8192CE) += rtl8192ce/ | 14 | obj-$(CONFIG_RTL8192CE) += rtl8192ce/ |
15 | obj-$(CONFIG_RTL8192CU) += rtl8192cu/ | ||
16 | |||
17 | ccflags-y += -D__CHECK_ENDIAN__ | ||
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index cf0b73e51fc2..3f40dc2b129c 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c | |||
@@ -144,7 +144,7 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, | |||
144 | ht_cap->mcs.rx_mask[1] = 0xFF; | 144 | ht_cap->mcs.rx_mask[1] = 0xFF; |
145 | ht_cap->mcs.rx_mask[4] = 0x01; | 145 | ht_cap->mcs.rx_mask[4] = 0x01; |
146 | 146 | ||
147 | ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS15; | 147 | ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS15); |
148 | } else if (get_rf_type(rtlphy) == RF_1T1R) { | 148 | } else if (get_rf_type(rtlphy) == RF_1T1R) { |
149 | 149 | ||
150 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("1T1R\n")); | 150 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("1T1R\n")); |
@@ -153,7 +153,7 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, | |||
153 | ht_cap->mcs.rx_mask[1] = 0x00; | 153 | ht_cap->mcs.rx_mask[1] = 0x00; |
154 | ht_cap->mcs.rx_mask[4] = 0x01; | 154 | ht_cap->mcs.rx_mask[4] = 0x01; |
155 | 155 | ||
156 | ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS7; | 156 | ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS7); |
157 | } | 157 | } |
158 | } | 158 | } |
159 | 159 | ||
@@ -399,21 +399,21 @@ static void _rtl_query_protection_mode(struct ieee80211_hw *hw, | |||
399 | u8 rate_flag = info->control.rates[0].flags; | 399 | u8 rate_flag = info->control.rates[0].flags; |
400 | 400 | ||
401 | /* Common Settings */ | 401 | /* Common Settings */ |
402 | tcb_desc->b_rts_stbc = false; | 402 | tcb_desc->rts_stbc = false; |
403 | tcb_desc->b_cts_enable = false; | 403 | tcb_desc->cts_enable = false; |
404 | tcb_desc->rts_sc = 0; | 404 | tcb_desc->rts_sc = 0; |
405 | tcb_desc->b_rts_bw = false; | 405 | tcb_desc->rts_bw = false; |
406 | tcb_desc->b_rts_use_shortpreamble = false; | 406 | tcb_desc->rts_use_shortpreamble = false; |
407 | tcb_desc->b_rts_use_shortgi = false; | 407 | tcb_desc->rts_use_shortgi = false; |
408 | 408 | ||
409 | if (rate_flag & IEEE80211_TX_RC_USE_CTS_PROTECT) { | 409 | if (rate_flag & IEEE80211_TX_RC_USE_CTS_PROTECT) { |
410 | /* Use CTS-to-SELF in protection mode. */ | 410 | /* Use CTS-to-SELF in protection mode. */ |
411 | tcb_desc->b_rts_enable = true; | 411 | tcb_desc->rts_enable = true; |
412 | tcb_desc->b_cts_enable = true; | 412 | tcb_desc->cts_enable = true; |
413 | tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M]; | 413 | tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M]; |
414 | } else if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS) { | 414 | } else if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS) { |
415 | /* Use RTS-CTS in protection mode. */ | 415 | /* Use RTS-CTS in protection mode. */ |
416 | tcb_desc->b_rts_enable = true; | 416 | tcb_desc->rts_enable = true; |
417 | tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M]; | 417 | tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M]; |
418 | } | 418 | } |
419 | 419 | ||
@@ -429,7 +429,7 @@ static void _rtl_txrate_selectmode(struct ieee80211_hw *hw, | |||
429 | if (mac->opmode == NL80211_IFTYPE_STATION) | 429 | if (mac->opmode == NL80211_IFTYPE_STATION) |
430 | tcb_desc->ratr_index = 0; | 430 | tcb_desc->ratr_index = 0; |
431 | else if (mac->opmode == NL80211_IFTYPE_ADHOC) { | 431 | else if (mac->opmode == NL80211_IFTYPE_ADHOC) { |
432 | if (tcb_desc->b_multicast || tcb_desc->b_broadcast) { | 432 | if (tcb_desc->multicast || tcb_desc->broadcast) { |
433 | tcb_desc->hw_rate = | 433 | tcb_desc->hw_rate = |
434 | rtlpriv->cfg->maps[RTL_RC_CCK_RATE2M]; | 434 | rtlpriv->cfg->maps[RTL_RC_CCK_RATE2M]; |
435 | tcb_desc->use_driver_rate = 1; | 435 | tcb_desc->use_driver_rate = 1; |
@@ -439,7 +439,7 @@ static void _rtl_txrate_selectmode(struct ieee80211_hw *hw, | |||
439 | } | 439 | } |
440 | } | 440 | } |
441 | 441 | ||
442 | if (rtlpriv->dm.b_useramask) { | 442 | if (rtlpriv->dm.useramask) { |
443 | /* TODO we will differentiate adhoc and station futrue */ | 443 | /* TODO we will differentiate adhoc and station futrue */ |
444 | tcb_desc->mac_id = 0; | 444 | tcb_desc->mac_id = 0; |
445 | 445 | ||
@@ -461,19 +461,19 @@ static void _rtl_query_bandwidth_mode(struct ieee80211_hw *hw, | |||
461 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 461 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
462 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 462 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
463 | 463 | ||
464 | tcb_desc->b_packet_bw = false; | 464 | tcb_desc->packet_bw = false; |
465 | 465 | ||
466 | if (!mac->bw_40 || !mac->ht_enable) | 466 | if (!mac->bw_40 || !mac->ht_enable) |
467 | return; | 467 | return; |
468 | 468 | ||
469 | if (tcb_desc->b_multicast || tcb_desc->b_broadcast) | 469 | if (tcb_desc->multicast || tcb_desc->broadcast) |
470 | return; | 470 | return; |
471 | 471 | ||
472 | /*use legency rate, shall use 20MHz */ | 472 | /*use legency rate, shall use 20MHz */ |
473 | if (tcb_desc->hw_rate <= rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M]) | 473 | if (tcb_desc->hw_rate <= rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M]) |
474 | return; | 474 | return; |
475 | 475 | ||
476 | tcb_desc->b_packet_bw = true; | 476 | tcb_desc->packet_bw = true; |
477 | } | 477 | } |
478 | 478 | ||
479 | static u8 _rtl_get_highest_n_rate(struct ieee80211_hw *hw) | 479 | static u8 _rtl_get_highest_n_rate(struct ieee80211_hw *hw) |
@@ -498,7 +498,7 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw, | |||
498 | struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); | 498 | struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); |
499 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); | 499 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); |
500 | struct ieee80211_rate *txrate; | 500 | struct ieee80211_rate *txrate; |
501 | u16 fc = le16_to_cpu(hdr->frame_control); | 501 | __le16 fc = hdr->frame_control; |
502 | 502 | ||
503 | memset(tcb_desc, 0, sizeof(struct rtl_tcb_desc)); | 503 | memset(tcb_desc, 0, sizeof(struct rtl_tcb_desc)); |
504 | 504 | ||
@@ -545,9 +545,9 @@ void rtl_get_tcb_desc(struct ieee80211_hw *hw, | |||
545 | } | 545 | } |
546 | 546 | ||
547 | if (is_multicast_ether_addr(ieee80211_get_DA(hdr))) | 547 | if (is_multicast_ether_addr(ieee80211_get_DA(hdr))) |
548 | tcb_desc->b_multicast = 1; | 548 | tcb_desc->multicast = 1; |
549 | else if (is_broadcast_ether_addr(ieee80211_get_DA(hdr))) | 549 | else if (is_broadcast_ether_addr(ieee80211_get_DA(hdr))) |
550 | tcb_desc->b_broadcast = 1; | 550 | tcb_desc->broadcast = 1; |
551 | 551 | ||
552 | _rtl_txrate_selectmode(hw, tcb_desc); | 552 | _rtl_txrate_selectmode(hw, tcb_desc); |
553 | _rtl_query_bandwidth_mode(hw, tcb_desc); | 553 | _rtl_query_bandwidth_mode(hw, tcb_desc); |
@@ -570,7 +570,7 @@ bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
570 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 570 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
571 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 571 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
572 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); | 572 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); |
573 | u16 fc = le16_to_cpu(hdr->frame_control); | 573 | __le16 fc = hdr->frame_control; |
574 | 574 | ||
575 | if (ieee80211_is_auth(fc)) { | 575 | if (ieee80211_is_auth(fc)) { |
576 | RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n")); | 576 | RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n")); |
@@ -587,7 +587,7 @@ bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) | |||
587 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 587 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
588 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); | 588 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); |
589 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 589 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
590 | u16 fc = le16_to_cpu(hdr->frame_control); | 590 | __le16 fc = hdr->frame_control; |
591 | u8 *act = (u8 *) (((u8 *) skb->data + MAC80211_3ADDR_LEN)); | 591 | u8 *act = (u8 *) (((u8 *) skb->data + MAC80211_3ADDR_LEN)); |
592 | u8 category; | 592 | u8 category; |
593 | 593 | ||
@@ -632,7 +632,7 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) | |||
632 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 632 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
633 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); | 633 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); |
634 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 634 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
635 | u16 fc = le16_to_cpu(hdr->frame_control); | 635 | __le16 fc = hdr->frame_control; |
636 | u16 ether_type; | 636 | u16 ether_type; |
637 | u8 mac_hdr_len = ieee80211_get_hdrlen_from_skb(skb); | 637 | u8 mac_hdr_len = ieee80211_get_hdrlen_from_skb(skb); |
638 | const struct iphdr *ip; | 638 | const struct iphdr *ip; |
@@ -646,7 +646,6 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) | |||
646 | ip = (struct iphdr *)((u8 *) skb->data + mac_hdr_len + | 646 | ip = (struct iphdr *)((u8 *) skb->data + mac_hdr_len + |
647 | SNAP_SIZE + PROTOC_TYPE_SIZE); | 647 | SNAP_SIZE + PROTOC_TYPE_SIZE); |
648 | ether_type = *(u16 *) ((u8 *) skb->data + mac_hdr_len + SNAP_SIZE); | 648 | ether_type = *(u16 *) ((u8 *) skb->data + mac_hdr_len + SNAP_SIZE); |
649 | ether_type = ntohs(ether_type); | ||
650 | 649 | ||
651 | if (ETH_P_IP == ether_type) { | 650 | if (ETH_P_IP == ether_type) { |
652 | if (IPPROTO_UDP == ip->protocol) { | 651 | if (IPPROTO_UDP == ip->protocol) { |
@@ -690,7 +689,8 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) | |||
690 | } | 689 | } |
691 | 690 | ||
692 | return true; | 691 | return true; |
693 | } else if (0x86DD == ether_type) { | 692 | } else if (ETH_P_IPV6 == ether_type) { |
693 | /* IPv6 */ | ||
694 | return true; | 694 | return true; |
695 | } | 695 | } |
696 | 696 | ||
@@ -777,10 +777,10 @@ void rtl_watchdog_wq_callback(void *data) | |||
777 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 777 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
778 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 778 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
779 | 779 | ||
780 | bool b_busytraffic = false; | 780 | bool busytraffic = false; |
781 | bool b_higher_busytraffic = false; | 781 | bool higher_busytraffic = false; |
782 | bool b_higher_busyrxtraffic = false; | 782 | bool higher_busyrxtraffic = false; |
783 | bool b_higher_busytxtraffic = false; | 783 | bool higher_busytxtraffic = false; |
784 | 784 | ||
785 | u8 idx = 0; | 785 | u8 idx = 0; |
786 | u32 rx_cnt_inp4eriod = 0; | 786 | u32 rx_cnt_inp4eriod = 0; |
@@ -788,7 +788,7 @@ void rtl_watchdog_wq_callback(void *data) | |||
788 | u32 aver_rx_cnt_inperiod = 0; | 788 | u32 aver_rx_cnt_inperiod = 0; |
789 | u32 aver_tx_cnt_inperiod = 0; | 789 | u32 aver_tx_cnt_inperiod = 0; |
790 | 790 | ||
791 | bool benter_ps = false; | 791 | bool enter_ps = false; |
792 | 792 | ||
793 | if (is_hal_stop(rtlhal)) | 793 | if (is_hal_stop(rtlhal)) |
794 | return; | 794 | return; |
@@ -832,29 +832,29 @@ void rtl_watchdog_wq_callback(void *data) | |||
832 | 832 | ||
833 | /* (2) check traffic busy */ | 833 | /* (2) check traffic busy */ |
834 | if (aver_rx_cnt_inperiod > 100 || aver_tx_cnt_inperiod > 100) | 834 | if (aver_rx_cnt_inperiod > 100 || aver_tx_cnt_inperiod > 100) |
835 | b_busytraffic = true; | 835 | busytraffic = true; |
836 | 836 | ||
837 | /* Higher Tx/Rx data. */ | 837 | /* Higher Tx/Rx data. */ |
838 | if (aver_rx_cnt_inperiod > 4000 || | 838 | if (aver_rx_cnt_inperiod > 4000 || |
839 | aver_tx_cnt_inperiod > 4000) { | 839 | aver_tx_cnt_inperiod > 4000) { |
840 | b_higher_busytraffic = true; | 840 | higher_busytraffic = true; |
841 | 841 | ||
842 | /* Extremely high Rx data. */ | 842 | /* Extremely high Rx data. */ |
843 | if (aver_rx_cnt_inperiod > 5000) | 843 | if (aver_rx_cnt_inperiod > 5000) |
844 | b_higher_busyrxtraffic = true; | 844 | higher_busyrxtraffic = true; |
845 | else | 845 | else |
846 | b_higher_busytxtraffic = false; | 846 | higher_busytxtraffic = false; |
847 | } | 847 | } |
848 | 848 | ||
849 | if (((rtlpriv->link_info.num_rx_inperiod + | 849 | if (((rtlpriv->link_info.num_rx_inperiod + |
850 | rtlpriv->link_info.num_tx_inperiod) > 8) || | 850 | rtlpriv->link_info.num_tx_inperiod) > 8) || |
851 | (rtlpriv->link_info.num_rx_inperiod > 2)) | 851 | (rtlpriv->link_info.num_rx_inperiod > 2)) |
852 | benter_ps = false; | 852 | enter_ps = false; |
853 | else | 853 | else |
854 | benter_ps = true; | 854 | enter_ps = true; |
855 | 855 | ||
856 | /* LeisurePS only work in infra mode. */ | 856 | /* LeisurePS only work in infra mode. */ |
857 | if (benter_ps) | 857 | if (enter_ps) |
858 | rtl_lps_enter(hw); | 858 | rtl_lps_enter(hw); |
859 | else | 859 | else |
860 | rtl_lps_leave(hw); | 860 | rtl_lps_leave(hw); |
@@ -863,9 +863,9 @@ void rtl_watchdog_wq_callback(void *data) | |||
863 | rtlpriv->link_info.num_rx_inperiod = 0; | 863 | rtlpriv->link_info.num_rx_inperiod = 0; |
864 | rtlpriv->link_info.num_tx_inperiod = 0; | 864 | rtlpriv->link_info.num_tx_inperiod = 0; |
865 | 865 | ||
866 | rtlpriv->link_info.b_busytraffic = b_busytraffic; | 866 | rtlpriv->link_info.busytraffic = busytraffic; |
867 | rtlpriv->link_info.b_higher_busytraffic = b_higher_busytraffic; | 867 | rtlpriv->link_info.higher_busytraffic = higher_busytraffic; |
868 | rtlpriv->link_info.b_higher_busyrxtraffic = b_higher_busyrxtraffic; | 868 | rtlpriv->link_info.higher_busyrxtraffic = higher_busyrxtraffic; |
869 | 869 | ||
870 | } | 870 | } |
871 | 871 | ||
diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/rtlwifi/base.h index 3de5a14745f1..043045342bc7 100644 --- a/drivers/net/wireless/rtlwifi/base.h +++ b/drivers/net/wireless/rtlwifi/base.h | |||
@@ -30,6 +30,7 @@ | |||
30 | #define __RTL_BASE_H__ | 30 | #define __RTL_BASE_H__ |
31 | 31 | ||
32 | #define RTL_DUMMY_OFFSET 0 | 32 | #define RTL_DUMMY_OFFSET 0 |
33 | #define RTL_RX_DESC_SIZE 24 | ||
33 | #define RTL_DUMMY_UNIT 8 | 34 | #define RTL_DUMMY_UNIT 8 |
34 | #define RTL_TX_DUMMY_SIZE (RTL_DUMMY_OFFSET * RTL_DUMMY_UNIT) | 35 | #define RTL_TX_DUMMY_SIZE (RTL_DUMMY_OFFSET * RTL_DUMMY_UNIT) |
35 | #define RTL_TX_DESC_SIZE 32 | 36 | #define RTL_TX_DESC_SIZE 32 |
@@ -52,46 +53,22 @@ | |||
52 | #define FRAME_OFFSET_SEQUENCE 22 | 53 | #define FRAME_OFFSET_SEQUENCE 22 |
53 | #define FRAME_OFFSET_ADDRESS4 24 | 54 | #define FRAME_OFFSET_ADDRESS4 24 |
54 | 55 | ||
55 | #define SET_80211_HDR_FRAME_CONTROL(_hdr, _val) \ | ||
56 | WRITEEF2BYTE(_hdr, _val) | ||
57 | #define SET_80211_HDR_TYPE_AND_SUBTYPE(_hdr, _val) \ | ||
58 | WRITEEF1BYTE(_hdr, _val) | ||
59 | #define SET_80211_HDR_PWR_MGNT(_hdr, _val) \ | ||
60 | SET_BITS_TO_LE_2BYTE(_hdr, 12, 1, _val) | ||
61 | #define SET_80211_HDR_TO_DS(_hdr, _val) \ | ||
62 | SET_BITS_TO_LE_2BYTE(_hdr, 8, 1, _val) | ||
63 | 56 | ||
64 | #define SET_80211_PS_POLL_AID(_hdr, _val) \ | 57 | #define SET_80211_PS_POLL_AID(_hdr, _val) \ |
65 | WRITEEF2BYTE(((u8 *)(_hdr)) + 2, _val) | 58 | (*(u16 *)((u8 *)(_hdr) + 2) = le16_to_cpu(_val)) |
66 | #define SET_80211_PS_POLL_BSSID(_hdr, _val) \ | 59 | #define SET_80211_PS_POLL_BSSID(_hdr, _val) \ |
67 | CP_MACADDR(((u8 *)(_hdr)) + 4, (u8 *)(_val)) | 60 | memcpy(((u8 *)(_hdr)) + 4, (u8 *)(_val), ETH_ALEN) |
68 | #define SET_80211_PS_POLL_TA(_hdr, _val) \ | 61 | #define SET_80211_PS_POLL_TA(_hdr, _val) \ |
69 | CP_MACADDR(((u8 *)(_hdr)) + 10, (u8 *)(_val)) | 62 | memcpy(((u8 *)(_hdr)) + 10, (u8 *)(_val), ETH_ALEN) |
70 | 63 | ||
71 | #define SET_80211_HDR_DURATION(_hdr, _val) \ | 64 | #define SET_80211_HDR_DURATION(_hdr, _val) \ |
72 | WRITEEF2BYTE((u8 *)(_hdr)+FRAME_OFFSET_DURATION, _val) | 65 | (*(u16 *)((u8 *)(_hdr) + FRAME_OFFSET_DURATION) = le16_to_cpu(_val)) |
73 | #define SET_80211_HDR_ADDRESS1(_hdr, _val) \ | 66 | #define SET_80211_HDR_ADDRESS1(_hdr, _val) \ |
74 | CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS1, (u8*)(_val)) | 67 | memcpy((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS1, (u8*)(_val), ETH_ALEN) |
75 | #define SET_80211_HDR_ADDRESS2(_hdr, _val) \ | 68 | #define SET_80211_HDR_ADDRESS2(_hdr, _val) \ |
76 | CP_MACADDR((u8 *)(_hdr) + FRAME_OFFSET_ADDRESS2, (u8 *)(_val)) | 69 | memcpy((u8 *)(_hdr) + FRAME_OFFSET_ADDRESS2, (u8 *)(_val), ETH_ALEN) |
77 | #define SET_80211_HDR_ADDRESS3(_hdr, _val) \ | 70 | #define SET_80211_HDR_ADDRESS3(_hdr, _val) \ |
78 | CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS3, (u8 *)(_val)) | 71 | memcpy((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS3, (u8 *)(_val), ETH_ALEN) |
79 | #define SET_80211_HDR_FRAGMENT_SEQUENCE(_hdr, _val) \ | ||
80 | WRITEEF2BYTE((u8 *)(_hdr)+FRAME_OFFSET_SEQUENCE, _val) | ||
81 | |||
82 | #define SET_BEACON_PROBE_RSP_TIME_STAMP_LOW(__phdr, __val) \ | ||
83 | WRITEEF4BYTE(((u8 *)(__phdr)) + 24, __val) | ||
84 | #define SET_BEACON_PROBE_RSP_TIME_STAMP_HIGH(__phdr, __val) \ | ||
85 | WRITEEF4BYTE(((u8 *)(__phdr)) + 28, __val) | ||
86 | #define SET_BEACON_PROBE_RSP_BEACON_INTERVAL(__phdr, __val) \ | ||
87 | WRITEEF2BYTE(((u8 *)(__phdr)) + 32, __val) | ||
88 | #define GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) \ | ||
89 | READEF2BYTE(((u8 *)(__phdr)) + 34) | ||
90 | #define SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \ | ||
91 | WRITEEF2BYTE(((u8 *)(__phdr)) + 34, __val) | ||
92 | #define MASK_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \ | ||
93 | SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, \ | ||
94 | (GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) & (~(__val)))) | ||
95 | 72 | ||
96 | int rtl_init_core(struct ieee80211_hw *hw); | 73 | int rtl_init_core(struct ieee80211_hw *hw); |
97 | void rtl_deinit_core(struct ieee80211_hw *hw); | 74 | void rtl_deinit_core(struct ieee80211_hw *hw); |
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index 25d2d667ffba..b0996bf8a214 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c | |||
@@ -434,9 +434,9 @@ static int rtl_op_conf_tx(struct ieee80211_hw *hw, u16 queue, | |||
434 | 434 | ||
435 | aci = _rtl_get_hal_qnum(queue); | 435 | aci = _rtl_get_hal_qnum(queue); |
436 | mac->ac[aci].aifs = param->aifs; | 436 | mac->ac[aci].aifs = param->aifs; |
437 | mac->ac[aci].cw_min = param->cw_min; | 437 | mac->ac[aci].cw_min = cpu_to_le16(param->cw_min); |
438 | mac->ac[aci].cw_max = param->cw_max; | 438 | mac->ac[aci].cw_max = cpu_to_le16(param->cw_max); |
439 | mac->ac[aci].tx_op = param->txop; | 439 | mac->ac[aci].tx_op = cpu_to_le16(param->txop); |
440 | memcpy(&mac->edca_param[aci], param, sizeof(*param)); | 440 | memcpy(&mac->edca_param[aci], param, sizeof(*param)); |
441 | rtlpriv->cfg->ops->set_qos(hw, aci); | 441 | rtlpriv->cfg->ops->set_qos(hw, aci); |
442 | return 0; | 442 | return 0; |
@@ -666,7 +666,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, | |||
666 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE, | 666 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE, |
667 | (u8 *) (&basic_rates)); | 667 | (u8 *) (&basic_rates)); |
668 | 668 | ||
669 | if (rtlpriv->dm.b_useramask) | 669 | if (rtlpriv->dm.useramask) |
670 | rtlpriv->cfg->ops->update_rate_mask(hw, 0); | 670 | rtlpriv->cfg->ops->update_rate_mask(hw, 0); |
671 | else | 671 | else |
672 | rtlpriv->cfg->ops->update_rate_table(hw); | 672 | rtlpriv->cfg->ops->update_rate_table(hw); |
@@ -681,7 +681,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, | |||
681 | */ | 681 | */ |
682 | if (changed & BSS_CHANGED_ASSOC) { | 682 | if (changed & BSS_CHANGED_ASSOC) { |
683 | if (bss_conf->assoc) { | 683 | if (bss_conf->assoc) { |
684 | if (ppsc->b_fwctrl_lps) { | 684 | if (ppsc->fwctrl_lps) { |
685 | u8 mstatus = RT_MEDIA_CONNECT; | 685 | u8 mstatus = RT_MEDIA_CONNECT; |
686 | rtlpriv->cfg->ops->set_hw_reg(hw, | 686 | rtlpriv->cfg->ops->set_hw_reg(hw, |
687 | HW_VAR_H2C_FW_JOINBSSRPT, | 687 | HW_VAR_H2C_FW_JOINBSSRPT, |
@@ -689,7 +689,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, | |||
689 | ppsc->report_linked = true; | 689 | ppsc->report_linked = true; |
690 | } | 690 | } |
691 | } else { | 691 | } else { |
692 | if (ppsc->b_fwctrl_lps) { | 692 | if (ppsc->fwctrl_lps) { |
693 | u8 mstatus = RT_MEDIA_DISCONNECT; | 693 | u8 mstatus = RT_MEDIA_DISCONNECT; |
694 | rtlpriv->cfg->ops->set_hw_reg(hw, | 694 | rtlpriv->cfg->ops->set_hw_reg(hw, |
695 | HW_VAR_H2C_FW_JOINBSSRPT, | 695 | HW_VAR_H2C_FW_JOINBSSRPT, |
@@ -818,7 +818,7 @@ static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw) | |||
818 | /* fix fwlps issue */ | 818 | /* fix fwlps issue */ |
819 | rtlpriv->cfg->ops->set_network_type(hw, mac->opmode); | 819 | rtlpriv->cfg->ops->set_network_type(hw, mac->opmode); |
820 | 820 | ||
821 | if (rtlpriv->dm.b_useramask) | 821 | if (rtlpriv->dm.useramask) |
822 | rtlpriv->cfg->ops->update_rate_mask(hw, 0); | 822 | rtlpriv->cfg->ops->update_rate_mask(hw, 0); |
823 | else | 823 | else |
824 | rtlpriv->cfg->ops->update_rate_table(hw); | 824 | rtlpriv->cfg->ops->update_rate_table(hw); |
diff --git a/drivers/net/wireless/rtlwifi/debug.h b/drivers/net/wireless/rtlwifi/debug.h index 08bdec2ceda4..e4aa8687408c 100644 --- a/drivers/net/wireless/rtlwifi/debug.h +++ b/drivers/net/wireless/rtlwifi/debug.h | |||
@@ -105,6 +105,7 @@ | |||
105 | #define COMP_MAC80211 BIT(26) | 105 | #define COMP_MAC80211 BIT(26) |
106 | #define COMP_REGD BIT(27) | 106 | #define COMP_REGD BIT(27) |
107 | #define COMP_CHAN BIT(28) | 107 | #define COMP_CHAN BIT(28) |
108 | #define COMP_USB BIT(29) | ||
108 | 109 | ||
109 | /*-------------------------------------------------------------- | 110 | /*-------------------------------------------------------------- |
110 | Define the rt_print components | 111 | Define the rt_print components |
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 1758d4463247..1f18bf7df741 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c | |||
@@ -50,7 +50,7 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw) | |||
50 | u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor; | 50 | u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor; |
51 | 51 | ||
52 | ppsc->reg_rfps_level = 0; | 52 | ppsc->reg_rfps_level = 0; |
53 | ppsc->b_support_aspm = 0; | 53 | ppsc->support_aspm = 0; |
54 | 54 | ||
55 | /*Update PCI ASPM setting */ | 55 | /*Update PCI ASPM setting */ |
56 | ppsc->const_amdpci_aspm = rtlpci->const_amdpci_aspm; | 56 | ppsc->const_amdpci_aspm = rtlpci->const_amdpci_aspm; |
@@ -115,29 +115,29 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw) | |||
115 | switch (rtlpci->const_support_pciaspm) { | 115 | switch (rtlpci->const_support_pciaspm) { |
116 | case 0:{ | 116 | case 0:{ |
117 | /*Not support ASPM. */ | 117 | /*Not support ASPM. */ |
118 | bool b_support_aspm = false; | 118 | bool support_aspm = false; |
119 | ppsc->b_support_aspm = b_support_aspm; | 119 | ppsc->support_aspm = support_aspm; |
120 | break; | 120 | break; |
121 | } | 121 | } |
122 | case 1:{ | 122 | case 1:{ |
123 | /*Support ASPM. */ | 123 | /*Support ASPM. */ |
124 | bool b_support_aspm = true; | 124 | bool support_aspm = true; |
125 | bool b_support_backdoor = true; | 125 | bool support_backdoor = true; |
126 | ppsc->b_support_aspm = b_support_aspm; | 126 | ppsc->support_aspm = support_aspm; |
127 | 127 | ||
128 | /*if(priv->oem_id == RT_CID_TOSHIBA && | 128 | /*if(priv->oem_id == RT_CID_TOSHIBA && |
129 | !priv->ndis_adapter.amd_l1_patch) | 129 | !priv->ndis_adapter.amd_l1_patch) |
130 | b_support_backdoor = false; */ | 130 | support_backdoor = false; */ |
131 | 131 | ||
132 | ppsc->b_support_backdoor = b_support_backdoor; | 132 | ppsc->support_backdoor = support_backdoor; |
133 | 133 | ||
134 | break; | 134 | break; |
135 | } | 135 | } |
136 | case 2: | 136 | case 2: |
137 | /*ASPM value set by chipset. */ | 137 | /*ASPM value set by chipset. */ |
138 | if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL) { | 138 | if (pcibridge_vendor == PCI_BRIDGE_VENDOR_INTEL) { |
139 | bool b_support_aspm = true; | 139 | bool support_aspm = true; |
140 | ppsc->b_support_aspm = b_support_aspm; | 140 | ppsc->support_aspm = support_aspm; |
141 | } | 141 | } |
142 | break; | 142 | break; |
143 | default: | 143 | default: |
@@ -476,9 +476,9 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) | |||
476 | 476 | ||
477 | skb = __skb_dequeue(&ring->queue); | 477 | skb = __skb_dequeue(&ring->queue); |
478 | pci_unmap_single(rtlpci->pdev, | 478 | pci_unmap_single(rtlpci->pdev, |
479 | le32_to_cpu(rtlpriv->cfg->ops-> | 479 | rtlpriv->cfg->ops-> |
480 | get_desc((u8 *) entry, true, | 480 | get_desc((u8 *) entry, true, |
481 | HW_DESC_TXBUFF_ADDR)), | 481 | HW_DESC_TXBUFF_ADDR), |
482 | skb->len, PCI_DMA_TODEVICE); | 482 | skb->len, PCI_DMA_TODEVICE); |
483 | 483 | ||
484 | RT_TRACE(rtlpriv, (COMP_INTR | COMP_SEND), DBG_TRACE, | 484 | RT_TRACE(rtlpriv, (COMP_INTR | COMP_SEND), DBG_TRACE, |
@@ -557,7 +557,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) | |||
557 | return; | 557 | return; |
558 | } else { | 558 | } else { |
559 | struct ieee80211_hdr *hdr; | 559 | struct ieee80211_hdr *hdr; |
560 | u16 fc; | 560 | __le16 fc; |
561 | struct sk_buff *new_skb = NULL; | 561 | struct sk_buff *new_skb = NULL; |
562 | 562 | ||
563 | rtlpriv->cfg->ops->query_rx_desc(hw, &stats, | 563 | rtlpriv->cfg->ops->query_rx_desc(hw, &stats, |
@@ -583,9 +583,9 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) | |||
583 | */ | 583 | */ |
584 | 584 | ||
585 | hdr = (struct ieee80211_hdr *)(skb->data); | 585 | hdr = (struct ieee80211_hdr *)(skb->data); |
586 | fc = le16_to_cpu(hdr->frame_control); | 586 | fc = hdr->frame_control; |
587 | 587 | ||
588 | if (!stats.b_crc) { | 588 | if (!stats.crc) { |
589 | memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, | 589 | memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, |
590 | sizeof(rx_status)); | 590 | sizeof(rx_status)); |
591 | 591 | ||
@@ -666,7 +666,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) | |||
666 | 666 | ||
667 | } | 667 | } |
668 | done: | 668 | done: |
669 | bufferaddress = cpu_to_le32(*((dma_addr_t *) skb->cb)); | 669 | bufferaddress = (u32)(*((dma_addr_t *) skb->cb)); |
670 | tmp_one = 1; | 670 | tmp_one = 1; |
671 | rtlpriv->cfg->ops->set_desc((u8 *) pdesc, false, | 671 | rtlpriv->cfg->ops->set_desc((u8 *) pdesc, false, |
672 | HW_DESC_RXBUFF_ADDR, | 672 | HW_DESC_RXBUFF_ADDR, |
@@ -690,75 +690,6 @@ done: | |||
690 | 690 | ||
691 | } | 691 | } |
692 | 692 | ||
693 | void _rtl_pci_tx_interrupt(struct ieee80211_hw *hw) | ||
694 | { | ||
695 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
696 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
697 | int prio; | ||
698 | |||
699 | for (prio = 0; prio < RTL_PCI_MAX_TX_QUEUE_COUNT; prio++) { | ||
700 | struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[prio]; | ||
701 | |||
702 | while (skb_queue_len(&ring->queue)) { | ||
703 | struct rtl_tx_desc *entry = &ring->desc[ring->idx]; | ||
704 | struct sk_buff *skb; | ||
705 | struct ieee80211_tx_info *info; | ||
706 | u8 own; | ||
707 | |||
708 | /* | ||
709 | *beacon packet will only use the first | ||
710 | *descriptor defautly, and the own may not | ||
711 | *be cleared by the hardware, and | ||
712 | *beacon will free in prepare beacon | ||
713 | */ | ||
714 | if (prio == BEACON_QUEUE || prio == TXCMD_QUEUE || | ||
715 | prio == HCCA_QUEUE) | ||
716 | break; | ||
717 | |||
718 | own = (u8)rtlpriv->cfg->ops->get_desc((u8 *)entry, | ||
719 | true, | ||
720 | HW_DESC_OWN); | ||
721 | |||
722 | if (own) | ||
723 | break; | ||
724 | |||
725 | skb = __skb_dequeue(&ring->queue); | ||
726 | pci_unmap_single(rtlpci->pdev, | ||
727 | le32_to_cpu(rtlpriv->cfg->ops-> | ||
728 | get_desc((u8 *) entry, | ||
729 | true, | ||
730 | HW_DESC_TXBUFF_ADDR)), | ||
731 | skb->len, PCI_DMA_TODEVICE); | ||
732 | |||
733 | ring->idx = (ring->idx + 1) % ring->entries; | ||
734 | |||
735 | info = IEEE80211_SKB_CB(skb); | ||
736 | ieee80211_tx_info_clear_status(info); | ||
737 | |||
738 | info->flags |= IEEE80211_TX_STAT_ACK; | ||
739 | /*info->status.rates[0].count = 1; */ | ||
740 | |||
741 | ieee80211_tx_status_irqsafe(hw, skb); | ||
742 | |||
743 | if ((ring->entries - skb_queue_len(&ring->queue)) | ||
744 | == 2 && prio != BEACON_QUEUE) { | ||
745 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
746 | ("more desc left, wake " | ||
747 | "skb_queue@%d,ring->idx = %d," | ||
748 | "skb_queue_len = 0x%d\n", | ||
749 | prio, ring->idx, | ||
750 | skb_queue_len(&ring->queue))); | ||
751 | |||
752 | ieee80211_wake_queue(hw, | ||
753 | skb_get_queue_mapping | ||
754 | (skb)); | ||
755 | } | ||
756 | |||
757 | skb = NULL; | ||
758 | } | ||
759 | } | ||
760 | } | ||
761 | |||
762 | static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) | 693 | static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) |
763 | { | 694 | { |
764 | struct ieee80211_hw *hw = dev_id; | 695 | struct ieee80211_hw *hw = dev_id; |
@@ -959,17 +890,17 @@ static void _rtl_pci_init_struct(struct ieee80211_hw *hw, | |||
959 | rtlhal->hw = hw; | 890 | rtlhal->hw = hw; |
960 | rtlpci->pdev = pdev; | 891 | rtlpci->pdev = pdev; |
961 | 892 | ||
962 | ppsc->b_inactiveps = false; | 893 | ppsc->inactiveps = false; |
963 | ppsc->b_leisure_ps = true; | 894 | ppsc->leisure_ps = true; |
964 | ppsc->b_fwctrl_lps = true; | 895 | ppsc->fwctrl_lps = true; |
965 | ppsc->b_reg_fwctrl_lps = 3; | 896 | ppsc->reg_fwctrl_lps = 3; |
966 | ppsc->reg_max_lps_awakeintvl = 5; | 897 | ppsc->reg_max_lps_awakeintvl = 5; |
967 | 898 | ||
968 | if (ppsc->b_reg_fwctrl_lps == 1) | 899 | if (ppsc->reg_fwctrl_lps == 1) |
969 | ppsc->fwctrl_psmode = FW_PS_MIN_MODE; | 900 | ppsc->fwctrl_psmode = FW_PS_MIN_MODE; |
970 | else if (ppsc->b_reg_fwctrl_lps == 2) | 901 | else if (ppsc->reg_fwctrl_lps == 2) |
971 | ppsc->fwctrl_psmode = FW_PS_MAX_MODE; | 902 | ppsc->fwctrl_psmode = FW_PS_MAX_MODE; |
972 | else if (ppsc->b_reg_fwctrl_lps == 3) | 903 | else if (ppsc->reg_fwctrl_lps == 3) |
973 | ppsc->fwctrl_psmode = FW_PS_DTIM_MODE; | 904 | ppsc->fwctrl_psmode = FW_PS_DTIM_MODE; |
974 | 905 | ||
975 | /*Tx/Rx related var */ | 906 | /*Tx/Rx related var */ |
@@ -1024,9 +955,8 @@ static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw, | |||
1024 | ("queue:%d, ring_addr:%p\n", prio, ring)); | 955 | ("queue:%d, ring_addr:%p\n", prio, ring)); |
1025 | 956 | ||
1026 | for (i = 0; i < entries; i++) { | 957 | for (i = 0; i < entries; i++) { |
1027 | nextdescaddress = cpu_to_le32((u32) dma + | 958 | nextdescaddress = (u32) dma + ((i + 1) % entries) * |
1028 | ((i + 1) % entries) * | 959 | sizeof(*ring); |
1029 | sizeof(*ring)); | ||
1030 | 960 | ||
1031 | rtlpriv->cfg->ops->set_desc((u8 *)&(ring[i]), | 961 | rtlpriv->cfg->ops->set_desc((u8 *)&(ring[i]), |
1032 | true, HW_DESC_TX_NEXTDESC_ADDR, | 962 | true, HW_DESC_TX_NEXTDESC_ADDR, |
@@ -1090,7 +1020,7 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw) | |||
1090 | rtlpci->rxbuffersize, | 1020 | rtlpci->rxbuffersize, |
1091 | PCI_DMA_FROMDEVICE); | 1021 | PCI_DMA_FROMDEVICE); |
1092 | 1022 | ||
1093 | bufferaddress = cpu_to_le32(*((dma_addr_t *)skb->cb)); | 1023 | bufferaddress = (u32)(*((dma_addr_t *)skb->cb)); |
1094 | rtlpriv->cfg->ops->set_desc((u8 *)entry, false, | 1024 | rtlpriv->cfg->ops->set_desc((u8 *)entry, false, |
1095 | HW_DESC_RXBUFF_ADDR, | 1025 | HW_DESC_RXBUFF_ADDR, |
1096 | (u8 *)&bufferaddress); | 1026 | (u8 *)&bufferaddress); |
@@ -1121,9 +1051,9 @@ static void _rtl_pci_free_tx_ring(struct ieee80211_hw *hw, | |||
1121 | struct sk_buff *skb = __skb_dequeue(&ring->queue); | 1051 | struct sk_buff *skb = __skb_dequeue(&ring->queue); |
1122 | 1052 | ||
1123 | pci_unmap_single(rtlpci->pdev, | 1053 | pci_unmap_single(rtlpci->pdev, |
1124 | le32_to_cpu(rtlpriv->cfg-> | 1054 | rtlpriv->cfg-> |
1125 | ops->get_desc((u8 *) entry, true, | 1055 | ops->get_desc((u8 *) entry, true, |
1126 | HW_DESC_TXBUFF_ADDR)), | 1056 | HW_DESC_TXBUFF_ADDR), |
1127 | skb->len, PCI_DMA_TODEVICE); | 1057 | skb->len, PCI_DMA_TODEVICE); |
1128 | kfree_skb(skb); | 1058 | kfree_skb(skb); |
1129 | ring->idx = (ring->idx + 1) % ring->entries; | 1059 | ring->idx = (ring->idx + 1) % ring->entries; |
@@ -1255,11 +1185,11 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw) | |||
1255 | __skb_dequeue(&ring->queue); | 1185 | __skb_dequeue(&ring->queue); |
1256 | 1186 | ||
1257 | pci_unmap_single(rtlpci->pdev, | 1187 | pci_unmap_single(rtlpci->pdev, |
1258 | le32_to_cpu(rtlpriv->cfg->ops-> | 1188 | rtlpriv->cfg->ops-> |
1259 | get_desc((u8 *) | 1189 | get_desc((u8 *) |
1260 | entry, | 1190 | entry, |
1261 | true, | 1191 | true, |
1262 | HW_DESC_TXBUFF_ADDR)), | 1192 | HW_DESC_TXBUFF_ADDR), |
1263 | skb->len, PCI_DMA_TODEVICE); | 1193 | skb->len, PCI_DMA_TODEVICE); |
1264 | kfree_skb(skb); | 1194 | kfree_skb(skb); |
1265 | ring->idx = (ring->idx + 1) % ring->entries; | 1195 | ring->idx = (ring->idx + 1) % ring->entries; |
@@ -1273,7 +1203,7 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw) | |||
1273 | return 0; | 1203 | return 0; |
1274 | } | 1204 | } |
1275 | 1205 | ||
1276 | unsigned int _rtl_mac_to_hwqueue(u16 fc, | 1206 | static unsigned int _rtl_mac_to_hwqueue(__le16 fc, |
1277 | unsigned int mac80211_queue_index) | 1207 | unsigned int mac80211_queue_index) |
1278 | { | 1208 | { |
1279 | unsigned int hw_queue_index; | 1209 | unsigned int hw_queue_index; |
@@ -1312,7 +1242,7 @@ out: | |||
1312 | return hw_queue_index; | 1242 | return hw_queue_index; |
1313 | } | 1243 | } |
1314 | 1244 | ||
1315 | int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | 1245 | static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb) |
1316 | { | 1246 | { |
1317 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1247 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
1318 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 1248 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
@@ -1323,7 +1253,7 @@ int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1323 | unsigned int queue_index, hw_queue; | 1253 | unsigned int queue_index, hw_queue; |
1324 | unsigned long flags; | 1254 | unsigned long flags; |
1325 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); | 1255 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); |
1326 | u16 fc = le16_to_cpu(hdr->frame_control); | 1256 | __le16 fc = hdr->frame_control; |
1327 | u8 *pda_addr = hdr->addr1; | 1257 | u8 *pda_addr = hdr->addr1; |
1328 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 1258 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
1329 | /*ssn */ | 1259 | /*ssn */ |
@@ -1429,7 +1359,7 @@ int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1429 | return 0; | 1359 | return 0; |
1430 | } | 1360 | } |
1431 | 1361 | ||
1432 | void rtl_pci_deinit(struct ieee80211_hw *hw) | 1362 | static void rtl_pci_deinit(struct ieee80211_hw *hw) |
1433 | { | 1363 | { |
1434 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1364 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
1435 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 1365 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
@@ -1444,7 +1374,7 @@ void rtl_pci_deinit(struct ieee80211_hw *hw) | |||
1444 | 1374 | ||
1445 | } | 1375 | } |
1446 | 1376 | ||
1447 | int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev) | 1377 | static int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev) |
1448 | { | 1378 | { |
1449 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1379 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
1450 | int err; | 1380 | int err; |
@@ -1461,7 +1391,7 @@ int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev) | |||
1461 | return 1; | 1391 | return 1; |
1462 | } | 1392 | } |
1463 | 1393 | ||
1464 | int rtl_pci_start(struct ieee80211_hw *hw) | 1394 | static int rtl_pci_start(struct ieee80211_hw *hw) |
1465 | { | 1395 | { |
1466 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1396 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
1467 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 1397 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
@@ -1496,7 +1426,7 @@ int rtl_pci_start(struct ieee80211_hw *hw) | |||
1496 | return 0; | 1426 | return 0; |
1497 | } | 1427 | } |
1498 | 1428 | ||
1499 | void rtl_pci_stop(struct ieee80211_hw *hw) | 1429 | static void rtl_pci_stop(struct ieee80211_hw *hw) |
1500 | { | 1430 | { |
1501 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1431 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
1502 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 1432 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
@@ -1838,7 +1768,7 @@ fail3: | |||
1838 | ieee80211_free_hw(hw); | 1768 | ieee80211_free_hw(hw); |
1839 | 1769 | ||
1840 | if (rtlpriv->io.pci_mem_start != 0) | 1770 | if (rtlpriv->io.pci_mem_start != 0) |
1841 | pci_iounmap(pdev, (void *)rtlpriv->io.pci_mem_start); | 1771 | pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start); |
1842 | 1772 | ||
1843 | fail2: | 1773 | fail2: |
1844 | pci_release_regions(pdev); | 1774 | pci_release_regions(pdev); |
@@ -1888,7 +1818,7 @@ void rtl_pci_disconnect(struct pci_dev *pdev) | |||
1888 | } | 1818 | } |
1889 | 1819 | ||
1890 | if (rtlpriv->io.pci_mem_start != 0) { | 1820 | if (rtlpriv->io.pci_mem_start != 0) { |
1891 | pci_iounmap(pdev, (void *)rtlpriv->io.pci_mem_start); | 1821 | pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start); |
1892 | pci_release_regions(pdev); | 1822 | pci_release_regions(pdev); |
1893 | } | 1823 | } |
1894 | 1824 | ||
diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h index d36a66939958..0caa81429726 100644 --- a/drivers/net/wireless/rtlwifi/pci.h +++ b/drivers/net/wireless/rtlwifi/pci.h | |||
@@ -244,34 +244,34 @@ int rtl_pci_resume(struct pci_dev *pdev); | |||
244 | 244 | ||
245 | static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr) | 245 | static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr) |
246 | { | 246 | { |
247 | return 0xff & readb((u8 *) rtlpriv->io.pci_mem_start + addr); | 247 | return readb((u8 __iomem *) rtlpriv->io.pci_mem_start + addr); |
248 | } | 248 | } |
249 | 249 | ||
250 | static inline u16 pci_read16_sync(struct rtl_priv *rtlpriv, u32 addr) | 250 | static inline u16 pci_read16_sync(struct rtl_priv *rtlpriv, u32 addr) |
251 | { | 251 | { |
252 | return readw((u8 *) rtlpriv->io.pci_mem_start + addr); | 252 | return readw((u8 __iomem *) rtlpriv->io.pci_mem_start + addr); |
253 | } | 253 | } |
254 | 254 | ||
255 | static inline u32 pci_read32_sync(struct rtl_priv *rtlpriv, u32 addr) | 255 | static inline u32 pci_read32_sync(struct rtl_priv *rtlpriv, u32 addr) |
256 | { | 256 | { |
257 | return readl((u8 *) rtlpriv->io.pci_mem_start + addr); | 257 | return readl((u8 __iomem *) rtlpriv->io.pci_mem_start + addr); |
258 | } | 258 | } |
259 | 259 | ||
260 | static inline void pci_write8_async(struct rtl_priv *rtlpriv, u32 addr, u8 val) | 260 | static inline void pci_write8_async(struct rtl_priv *rtlpriv, u32 addr, u8 val) |
261 | { | 261 | { |
262 | writeb(val, (u8 *) rtlpriv->io.pci_mem_start + addr); | 262 | writeb(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr); |
263 | } | 263 | } |
264 | 264 | ||
265 | static inline void pci_write16_async(struct rtl_priv *rtlpriv, | 265 | static inline void pci_write16_async(struct rtl_priv *rtlpriv, |
266 | u32 addr, u16 val) | 266 | u32 addr, u16 val) |
267 | { | 267 | { |
268 | writew(val, (u8 *) rtlpriv->io.pci_mem_start + addr); | 268 | writew(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr); |
269 | } | 269 | } |
270 | 270 | ||
271 | static inline void pci_write32_async(struct rtl_priv *rtlpriv, | 271 | static inline void pci_write32_async(struct rtl_priv *rtlpriv, |
272 | u32 addr, u32 val) | 272 | u32 addr, u32 val) |
273 | { | 273 | { |
274 | writel(val, (u8 *) rtlpriv->io.pci_mem_start + addr); | 274 | writel(val, (u8 __iomem *) rtlpriv->io.pci_mem_start + addr); |
275 | } | 275 | } |
276 | 276 | ||
277 | static inline void rtl_pci_raw_write_port_ulong(u32 port, u32 val) | 277 | static inline void rtl_pci_raw_write_port_ulong(u32 port, u32 val) |
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index d2326c13449e..6b7e217b6b89 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c | |||
@@ -86,7 +86,7 @@ bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, | |||
86 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 86 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
87 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 87 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
88 | enum rf_pwrstate rtstate; | 88 | enum rf_pwrstate rtstate; |
89 | bool b_actionallowed = false; | 89 | bool actionallowed = false; |
90 | u16 rfwait_cnt = 0; | 90 | u16 rfwait_cnt = 0; |
91 | unsigned long flag; | 91 | unsigned long flag; |
92 | 92 | ||
@@ -139,13 +139,13 @@ no_protect: | |||
139 | ppsc->rfoff_reason &= (~changesource); | 139 | ppsc->rfoff_reason &= (~changesource); |
140 | 140 | ||
141 | if ((changesource == RF_CHANGE_BY_HW) && | 141 | if ((changesource == RF_CHANGE_BY_HW) && |
142 | (ppsc->b_hwradiooff == true)) { | 142 | (ppsc->hwradiooff == true)) { |
143 | ppsc->b_hwradiooff = false; | 143 | ppsc->hwradiooff = false; |
144 | } | 144 | } |
145 | 145 | ||
146 | if (!ppsc->rfoff_reason) { | 146 | if (!ppsc->rfoff_reason) { |
147 | ppsc->rfoff_reason = 0; | 147 | ppsc->rfoff_reason = 0; |
148 | b_actionallowed = true; | 148 | actionallowed = true; |
149 | } | 149 | } |
150 | 150 | ||
151 | break; | 151 | break; |
@@ -153,17 +153,17 @@ no_protect: | |||
153 | case ERFOFF: | 153 | case ERFOFF: |
154 | 154 | ||
155 | if ((changesource == RF_CHANGE_BY_HW) | 155 | if ((changesource == RF_CHANGE_BY_HW) |
156 | && (ppsc->b_hwradiooff == false)) { | 156 | && (ppsc->hwradiooff == false)) { |
157 | ppsc->b_hwradiooff = true; | 157 | ppsc->hwradiooff = true; |
158 | } | 158 | } |
159 | 159 | ||
160 | ppsc->rfoff_reason |= changesource; | 160 | ppsc->rfoff_reason |= changesource; |
161 | b_actionallowed = true; | 161 | actionallowed = true; |
162 | break; | 162 | break; |
163 | 163 | ||
164 | case ERFSLEEP: | 164 | case ERFSLEEP: |
165 | ppsc->rfoff_reason |= changesource; | 165 | ppsc->rfoff_reason |= changesource; |
166 | b_actionallowed = true; | 166 | actionallowed = true; |
167 | break; | 167 | break; |
168 | 168 | ||
169 | default: | 169 | default: |
@@ -172,7 +172,7 @@ no_protect: | |||
172 | break; | 172 | break; |
173 | } | 173 | } |
174 | 174 | ||
175 | if (b_actionallowed) | 175 | if (actionallowed) |
176 | rtlpriv->cfg->ops->set_rf_power_state(hw, state_toset); | 176 | rtlpriv->cfg->ops->set_rf_power_state(hw, state_toset); |
177 | 177 | ||
178 | if (!protect_or_not) { | 178 | if (!protect_or_not) { |
@@ -181,7 +181,7 @@ no_protect: | |||
181 | spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); | 181 | spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); |
182 | } | 182 | } |
183 | 183 | ||
184 | return b_actionallowed; | 184 | return actionallowed; |
185 | } | 185 | } |
186 | EXPORT_SYMBOL(rtl_ps_set_rf_state); | 186 | EXPORT_SYMBOL(rtl_ps_set_rf_state); |
187 | 187 | ||
@@ -191,7 +191,7 @@ static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw) | |||
191 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 191 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
192 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 192 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
193 | 193 | ||
194 | ppsc->b_swrf_processing = true; | 194 | ppsc->swrf_processing = true; |
195 | 195 | ||
196 | if (ppsc->inactive_pwrstate == ERFON && rtlhal->interface == INTF_PCI) { | 196 | if (ppsc->inactive_pwrstate == ERFON && rtlhal->interface == INTF_PCI) { |
197 | if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && | 197 | if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && |
@@ -213,7 +213,7 @@ static void _rtl_ps_inactive_ps(struct ieee80211_hw *hw) | |||
213 | } | 213 | } |
214 | } | 214 | } |
215 | 215 | ||
216 | ppsc->b_swrf_processing = false; | 216 | ppsc->swrf_processing = false; |
217 | } | 217 | } |
218 | 218 | ||
219 | void rtl_ips_nic_off_wq_callback(void *data) | 219 | void rtl_ips_nic_off_wq_callback(void *data) |
@@ -239,13 +239,13 @@ void rtl_ips_nic_off_wq_callback(void *data) | |||
239 | if (rtlpriv->sec.being_setkey) | 239 | if (rtlpriv->sec.being_setkey) |
240 | return; | 240 | return; |
241 | 241 | ||
242 | if (ppsc->b_inactiveps) { | 242 | if (ppsc->inactiveps) { |
243 | rtstate = ppsc->rfpwr_state; | 243 | rtstate = ppsc->rfpwr_state; |
244 | 244 | ||
245 | /* | 245 | /* |
246 | *Do not enter IPS in the following conditions: | 246 | *Do not enter IPS in the following conditions: |
247 | *(1) RF is already OFF or Sleep | 247 | *(1) RF is already OFF or Sleep |
248 | *(2) b_swrf_processing (indicates the IPS is still under going) | 248 | *(2) swrf_processing (indicates the IPS is still under going) |
249 | *(3) Connectted (only disconnected can trigger IPS) | 249 | *(3) Connectted (only disconnected can trigger IPS) |
250 | *(4) IBSS (send Beacon) | 250 | *(4) IBSS (send Beacon) |
251 | *(5) AP mode (send Beacon) | 251 | *(5) AP mode (send Beacon) |
@@ -253,14 +253,14 @@ void rtl_ips_nic_off_wq_callback(void *data) | |||
253 | */ | 253 | */ |
254 | 254 | ||
255 | if (rtstate == ERFON && | 255 | if (rtstate == ERFON && |
256 | !ppsc->b_swrf_processing && | 256 | !ppsc->swrf_processing && |
257 | (mac->link_state == MAC80211_NOLINK) && | 257 | (mac->link_state == MAC80211_NOLINK) && |
258 | !mac->act_scanning) { | 258 | !mac->act_scanning) { |
259 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, | 259 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, |
260 | ("IPSEnter(): Turn off RF.\n")); | 260 | ("IPSEnter(): Turn off RF.\n")); |
261 | 261 | ||
262 | ppsc->inactive_pwrstate = ERFOFF; | 262 | ppsc->inactive_pwrstate = ERFOFF; |
263 | ppsc->b_in_powersavemode = true; | 263 | ppsc->in_powersavemode = true; |
264 | 264 | ||
265 | /*rtl_pci_reset_trx_ring(hw); */ | 265 | /*rtl_pci_reset_trx_ring(hw); */ |
266 | _rtl_ps_inactive_ps(hw); | 266 | _rtl_ps_inactive_ps(hw); |
@@ -290,15 +290,15 @@ void rtl_ips_nic_on(struct ieee80211_hw *hw) | |||
290 | 290 | ||
291 | spin_lock_irqsave(&rtlpriv->locks.ips_lock, flags); | 291 | spin_lock_irqsave(&rtlpriv->locks.ips_lock, flags); |
292 | 292 | ||
293 | if (ppsc->b_inactiveps) { | 293 | if (ppsc->inactiveps) { |
294 | rtstate = ppsc->rfpwr_state; | 294 | rtstate = ppsc->rfpwr_state; |
295 | 295 | ||
296 | if (rtstate != ERFON && | 296 | if (rtstate != ERFON && |
297 | !ppsc->b_swrf_processing && | 297 | !ppsc->swrf_processing && |
298 | ppsc->rfoff_reason <= RF_CHANGE_BY_IPS) { | 298 | ppsc->rfoff_reason <= RF_CHANGE_BY_IPS) { |
299 | 299 | ||
300 | ppsc->inactive_pwrstate = ERFON; | 300 | ppsc->inactive_pwrstate = ERFON; |
301 | ppsc->b_in_powersavemode = false; | 301 | ppsc->in_powersavemode = false; |
302 | 302 | ||
303 | _rtl_ps_inactive_ps(hw); | 303 | _rtl_ps_inactive_ps(hw); |
304 | } | 304 | } |
@@ -370,9 +370,9 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode) | |||
370 | * mode and set RPWM to turn RF on. | 370 | * mode and set RPWM to turn RF on. |
371 | */ | 371 | */ |
372 | 372 | ||
373 | if ((ppsc->b_fwctrl_lps) && (ppsc->b_leisure_ps) && | 373 | if ((ppsc->fwctrl_lps) && (ppsc->leisure_ps) && |
374 | ppsc->report_linked) { | 374 | ppsc->report_linked) { |
375 | bool b_fw_current_inps; | 375 | bool fw_current_inps; |
376 | if (ppsc->dot11_psmode == EACTIVE) { | 376 | if (ppsc->dot11_psmode == EACTIVE) { |
377 | RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, | 377 | RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, |
378 | ("FW LPS leave ps_mode:%x\n", | 378 | ("FW LPS leave ps_mode:%x\n", |
@@ -385,11 +385,11 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode) | |||
385 | rtlpriv->cfg->ops->set_hw_reg(hw, | 385 | rtlpriv->cfg->ops->set_hw_reg(hw, |
386 | HW_VAR_H2C_FW_PWRMODE, | 386 | HW_VAR_H2C_FW_PWRMODE, |
387 | (u8 *) (&fw_pwrmode)); | 387 | (u8 *) (&fw_pwrmode)); |
388 | b_fw_current_inps = false; | 388 | fw_current_inps = false; |
389 | 389 | ||
390 | rtlpriv->cfg->ops->set_hw_reg(hw, | 390 | rtlpriv->cfg->ops->set_hw_reg(hw, |
391 | HW_VAR_FW_PSMODE_STATUS, | 391 | HW_VAR_FW_PSMODE_STATUS, |
392 | (u8 *) (&b_fw_current_inps)); | 392 | (u8 *) (&fw_current_inps)); |
393 | 393 | ||
394 | } else { | 394 | } else { |
395 | if (rtl_get_fwlps_doze(hw)) { | 395 | if (rtl_get_fwlps_doze(hw)) { |
@@ -398,10 +398,10 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode) | |||
398 | ppsc->fwctrl_psmode)); | 398 | ppsc->fwctrl_psmode)); |
399 | 399 | ||
400 | rpwm_val = 0x02; /* RF off */ | 400 | rpwm_val = 0x02; /* RF off */ |
401 | b_fw_current_inps = true; | 401 | fw_current_inps = true; |
402 | rtlpriv->cfg->ops->set_hw_reg(hw, | 402 | rtlpriv->cfg->ops->set_hw_reg(hw, |
403 | HW_VAR_FW_PSMODE_STATUS, | 403 | HW_VAR_FW_PSMODE_STATUS, |
404 | (u8 *) (&b_fw_current_inps)); | 404 | (u8 *) (&fw_current_inps)); |
405 | rtlpriv->cfg->ops->set_hw_reg(hw, | 405 | rtlpriv->cfg->ops->set_hw_reg(hw, |
406 | HW_VAR_H2C_FW_PWRMODE, | 406 | HW_VAR_H2C_FW_PWRMODE, |
407 | (u8 *) (&ppsc->fwctrl_psmode)); | 407 | (u8 *) (&ppsc->fwctrl_psmode)); |
@@ -425,13 +425,13 @@ void rtl_lps_enter(struct ieee80211_hw *hw) | |||
425 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 425 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
426 | unsigned long flag; | 426 | unsigned long flag; |
427 | 427 | ||
428 | if (!(ppsc->b_fwctrl_lps && ppsc->b_leisure_ps)) | 428 | if (!(ppsc->fwctrl_lps && ppsc->leisure_ps)) |
429 | return; | 429 | return; |
430 | 430 | ||
431 | if (rtlpriv->sec.being_setkey) | 431 | if (rtlpriv->sec.being_setkey) |
432 | return; | 432 | return; |
433 | 433 | ||
434 | if (rtlpriv->link_info.b_busytraffic) | 434 | if (rtlpriv->link_info.busytraffic) |
435 | return; | 435 | return; |
436 | 436 | ||
437 | /*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */ | 437 | /*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */ |
@@ -446,7 +446,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw) | |||
446 | 446 | ||
447 | spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag); | 447 | spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag); |
448 | 448 | ||
449 | if (ppsc->b_leisure_ps) { | 449 | if (ppsc->leisure_ps) { |
450 | /* Idle for a while if we connect to AP a while ago. */ | 450 | /* Idle for a while if we connect to AP a while ago. */ |
451 | if (mac->cnt_after_linked >= 2) { | 451 | if (mac->cnt_after_linked >= 2) { |
452 | if (ppsc->dot11_psmode == EACTIVE) { | 452 | if (ppsc->dot11_psmode == EACTIVE) { |
@@ -470,7 +470,7 @@ void rtl_lps_leave(struct ieee80211_hw *hw) | |||
470 | 470 | ||
471 | spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag); | 471 | spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag); |
472 | 472 | ||
473 | if (ppsc->b_fwctrl_lps && ppsc->b_leisure_ps) { | 473 | if (ppsc->fwctrl_lps && ppsc->leisure_ps) { |
474 | if (ppsc->dot11_psmode != EACTIVE) { | 474 | if (ppsc->dot11_psmode != EACTIVE) { |
475 | 475 | ||
476 | /*FIX ME */ | 476 | /*FIX ME */ |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c new file mode 100644 index 000000000000..b4f1e4e6b733 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | |||
@@ -0,0 +1,1388 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 Realtek Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | struct dig_t dm_digtable; | ||
31 | static struct ps_t dm_pstable; | ||
32 | |||
33 | static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = { | ||
34 | 0x7f8001fe, | ||
35 | 0x788001e2, | ||
36 | 0x71c001c7, | ||
37 | 0x6b8001ae, | ||
38 | 0x65400195, | ||
39 | 0x5fc0017f, | ||
40 | 0x5a400169, | ||
41 | 0x55400155, | ||
42 | 0x50800142, | ||
43 | 0x4c000130, | ||
44 | 0x47c0011f, | ||
45 | 0x43c0010f, | ||
46 | 0x40000100, | ||
47 | 0x3c8000f2, | ||
48 | 0x390000e4, | ||
49 | 0x35c000d7, | ||
50 | 0x32c000cb, | ||
51 | 0x300000c0, | ||
52 | 0x2d4000b5, | ||
53 | 0x2ac000ab, | ||
54 | 0x288000a2, | ||
55 | 0x26000098, | ||
56 | 0x24000090, | ||
57 | 0x22000088, | ||
58 | 0x20000080, | ||
59 | 0x1e400079, | ||
60 | 0x1c800072, | ||
61 | 0x1b00006c, | ||
62 | 0x19800066, | ||
63 | 0x18000060, | ||
64 | 0x16c0005b, | ||
65 | 0x15800056, | ||
66 | 0x14400051, | ||
67 | 0x1300004c, | ||
68 | 0x12000048, | ||
69 | 0x11000044, | ||
70 | 0x10000040, | ||
71 | }; | ||
72 | |||
73 | static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = { | ||
74 | {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, | ||
75 | {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, | ||
76 | {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, | ||
77 | {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, | ||
78 | {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, | ||
79 | {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, | ||
80 | {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, | ||
81 | {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, | ||
82 | {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, | ||
83 | {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, | ||
84 | {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, | ||
85 | {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, | ||
86 | {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, | ||
87 | {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, | ||
88 | {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, | ||
89 | {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, | ||
90 | {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, | ||
91 | {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, | ||
92 | {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, | ||
93 | {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, | ||
94 | {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, | ||
95 | {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, | ||
96 | {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, | ||
97 | {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, | ||
98 | {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, | ||
99 | {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, | ||
100 | {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, | ||
101 | {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, | ||
102 | {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, | ||
103 | {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, | ||
104 | {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, | ||
105 | {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, | ||
106 | {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} | ||
107 | }; | ||
108 | |||
109 | static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = { | ||
110 | {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, | ||
111 | {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, | ||
112 | {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, | ||
113 | {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, | ||
114 | {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, | ||
115 | {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, | ||
116 | {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, | ||
117 | {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, | ||
118 | {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, | ||
119 | {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, | ||
120 | {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, | ||
121 | {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, | ||
122 | {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, | ||
123 | {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, | ||
124 | {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, | ||
125 | {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, | ||
126 | {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, | ||
127 | {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, | ||
128 | {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, | ||
129 | {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, | ||
130 | {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, | ||
131 | {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, | ||
132 | {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, | ||
133 | {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, | ||
134 | {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, | ||
135 | {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, | ||
136 | {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, | ||
137 | {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, | ||
138 | {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, | ||
139 | {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, | ||
140 | {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, | ||
141 | {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, | ||
142 | {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} | ||
143 | }; | ||
144 | |||
145 | static void rtl92c_dm_diginit(struct ieee80211_hw *hw) | ||
146 | { | ||
147 | dm_digtable.dig_enable_flag = true; | ||
148 | dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; | ||
149 | dm_digtable.cur_igvalue = 0x20; | ||
150 | dm_digtable.pre_igvalue = 0x0; | ||
151 | dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT; | ||
152 | dm_digtable.presta_connectstate = DIG_STA_DISCONNECT; | ||
153 | dm_digtable.curmultista_connectstate = DIG_MULTISTA_DISCONNECT; | ||
154 | dm_digtable.rssi_lowthresh = DM_DIG_THRESH_LOW; | ||
155 | dm_digtable.rssi_highthresh = DM_DIG_THRESH_HIGH; | ||
156 | dm_digtable.fa_lowthresh = DM_FALSEALARM_THRESH_LOW; | ||
157 | dm_digtable.fa_highthresh = DM_FALSEALARM_THRESH_HIGH; | ||
158 | dm_digtable.rx_gain_range_max = DM_DIG_MAX; | ||
159 | dm_digtable.rx_gain_range_min = DM_DIG_MIN; | ||
160 | dm_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT; | ||
161 | dm_digtable.backoff_val_range_max = DM_DIG_BACKOFF_MAX; | ||
162 | dm_digtable.backoff_val_range_min = DM_DIG_BACKOFF_MIN; | ||
163 | dm_digtable.pre_cck_pd_state = CCK_PD_STAGE_MAX; | ||
164 | dm_digtable.cur_cck_pd_state = CCK_PD_STAGE_MAX; | ||
165 | } | ||
166 | |||
167 | static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw) | ||
168 | { | ||
169 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
170 | long rssi_val_min = 0; | ||
171 | |||
172 | if ((dm_digtable.curmultista_connectstate == DIG_MULTISTA_CONNECT) && | ||
173 | (dm_digtable.cursta_connectctate == DIG_STA_CONNECT)) { | ||
174 | if (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb != 0) | ||
175 | rssi_val_min = | ||
176 | (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb > | ||
177 | rtlpriv->dm.undecorated_smoothed_pwdb) ? | ||
178 | rtlpriv->dm.undecorated_smoothed_pwdb : | ||
179 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | ||
180 | else | ||
181 | rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb; | ||
182 | } else if (dm_digtable.cursta_connectctate == DIG_STA_CONNECT || | ||
183 | dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT) { | ||
184 | rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb; | ||
185 | } else if (dm_digtable.curmultista_connectstate == | ||
186 | DIG_MULTISTA_CONNECT) { | ||
187 | rssi_val_min = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | ||
188 | } | ||
189 | |||
190 | return (u8) rssi_val_min; | ||
191 | } | ||
192 | |||
193 | static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) | ||
194 | { | ||
195 | u32 ret_value; | ||
196 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
197 | struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); | ||
198 | |||
199 | ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD); | ||
200 | falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16); | ||
201 | |||
202 | ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD); | ||
203 | falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff); | ||
204 | falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16); | ||
205 | |||
206 | ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD); | ||
207 | falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff); | ||
208 | falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail + | ||
209 | falsealm_cnt->cnt_rate_illegal + | ||
210 | falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail; | ||
211 | |||
212 | rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1); | ||
213 | ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0); | ||
214 | falsealm_cnt->cnt_cck_fail = ret_value; | ||
215 | |||
216 | ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3); | ||
217 | falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8; | ||
218 | falsealm_cnt->cnt_all = (falsealm_cnt->cnt_parity_fail + | ||
219 | falsealm_cnt->cnt_rate_illegal + | ||
220 | falsealm_cnt->cnt_crc8_fail + | ||
221 | falsealm_cnt->cnt_mcs_fail + | ||
222 | falsealm_cnt->cnt_cck_fail); | ||
223 | |||
224 | rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1); | ||
225 | rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0); | ||
226 | rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0); | ||
227 | rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2); | ||
228 | |||
229 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, | ||
230 | ("cnt_parity_fail = %d, cnt_rate_illegal = %d, " | ||
231 | "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n", | ||
232 | falsealm_cnt->cnt_parity_fail, | ||
233 | falsealm_cnt->cnt_rate_illegal, | ||
234 | falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail)); | ||
235 | |||
236 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, | ||
237 | ("cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n", | ||
238 | falsealm_cnt->cnt_ofdm_fail, | ||
239 | falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all)); | ||
240 | } | ||
241 | |||
242 | static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw) | ||
243 | { | ||
244 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
245 | u8 value_igi = dm_digtable.cur_igvalue; | ||
246 | |||
247 | if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0) | ||
248 | value_igi--; | ||
249 | else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1) | ||
250 | value_igi += 0; | ||
251 | else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH2) | ||
252 | value_igi++; | ||
253 | else if (rtlpriv->falsealm_cnt.cnt_all >= DM_DIG_FA_TH2) | ||
254 | value_igi += 2; | ||
255 | if (value_igi > DM_DIG_FA_UPPER) | ||
256 | value_igi = DM_DIG_FA_UPPER; | ||
257 | else if (value_igi < DM_DIG_FA_LOWER) | ||
258 | value_igi = DM_DIG_FA_LOWER; | ||
259 | if (rtlpriv->falsealm_cnt.cnt_all > 10000) | ||
260 | value_igi = 0x32; | ||
261 | |||
262 | dm_digtable.cur_igvalue = value_igi; | ||
263 | rtl92c_dm_write_dig(hw); | ||
264 | } | ||
265 | |||
266 | static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw) | ||
267 | { | ||
268 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
269 | |||
270 | if (rtlpriv->falsealm_cnt.cnt_all > dm_digtable.fa_highthresh) { | ||
271 | if ((dm_digtable.backoff_val - 2) < | ||
272 | dm_digtable.backoff_val_range_min) | ||
273 | dm_digtable.backoff_val = | ||
274 | dm_digtable.backoff_val_range_min; | ||
275 | else | ||
276 | dm_digtable.backoff_val -= 2; | ||
277 | } else if (rtlpriv->falsealm_cnt.cnt_all < dm_digtable.fa_lowthresh) { | ||
278 | if ((dm_digtable.backoff_val + 2) > | ||
279 | dm_digtable.backoff_val_range_max) | ||
280 | dm_digtable.backoff_val = | ||
281 | dm_digtable.backoff_val_range_max; | ||
282 | else | ||
283 | dm_digtable.backoff_val += 2; | ||
284 | } | ||
285 | |||
286 | if ((dm_digtable.rssi_val_min + 10 - dm_digtable.backoff_val) > | ||
287 | dm_digtable.rx_gain_range_max) | ||
288 | dm_digtable.cur_igvalue = dm_digtable.rx_gain_range_max; | ||
289 | else if ((dm_digtable.rssi_val_min + 10 - | ||
290 | dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min) | ||
291 | dm_digtable.cur_igvalue = dm_digtable.rx_gain_range_min; | ||
292 | else | ||
293 | dm_digtable.cur_igvalue = dm_digtable.rssi_val_min + 10 - | ||
294 | dm_digtable.backoff_val; | ||
295 | |||
296 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, | ||
297 | ("rssi_val_min = %x backoff_val %x\n", | ||
298 | dm_digtable.rssi_val_min, dm_digtable.backoff_val)); | ||
299 | |||
300 | rtl92c_dm_write_dig(hw); | ||
301 | } | ||
302 | |||
303 | static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) | ||
304 | { | ||
305 | static u8 binitialized; /* initialized to false */ | ||
306 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
307 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
308 | long rssi_strength = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | ||
309 | bool multi_sta = false; | ||
310 | |||
311 | if (mac->opmode == NL80211_IFTYPE_ADHOC) | ||
312 | multi_sta = true; | ||
313 | |||
314 | if ((multi_sta == false) || (dm_digtable.cursta_connectctate != | ||
315 | DIG_STA_DISCONNECT)) { | ||
316 | binitialized = false; | ||
317 | dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; | ||
318 | return; | ||
319 | } else if (binitialized == false) { | ||
320 | binitialized = true; | ||
321 | dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; | ||
322 | dm_digtable.cur_igvalue = 0x20; | ||
323 | rtl92c_dm_write_dig(hw); | ||
324 | } | ||
325 | |||
326 | if (dm_digtable.curmultista_connectstate == DIG_MULTISTA_CONNECT) { | ||
327 | if ((rssi_strength < dm_digtable.rssi_lowthresh) && | ||
328 | (dm_digtable.dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) { | ||
329 | |||
330 | if (dm_digtable.dig_ext_port_stage == | ||
331 | DIG_EXT_PORT_STAGE_2) { | ||
332 | dm_digtable.cur_igvalue = 0x20; | ||
333 | rtl92c_dm_write_dig(hw); | ||
334 | } | ||
335 | |||
336 | dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_1; | ||
337 | } else if (rssi_strength > dm_digtable.rssi_highthresh) { | ||
338 | dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_2; | ||
339 | rtl92c_dm_ctrl_initgain_by_fa(hw); | ||
340 | } | ||
341 | } else if (dm_digtable.dig_ext_port_stage != DIG_EXT_PORT_STAGE_0) { | ||
342 | dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; | ||
343 | dm_digtable.cur_igvalue = 0x20; | ||
344 | rtl92c_dm_write_dig(hw); | ||
345 | } | ||
346 | |||
347 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, | ||
348 | ("curmultista_connectstate = " | ||
349 | "%x dig_ext_port_stage %x\n", | ||
350 | dm_digtable.curmultista_connectstate, | ||
351 | dm_digtable.dig_ext_port_stage)); | ||
352 | } | ||
353 | |||
354 | static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw) | ||
355 | { | ||
356 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
357 | |||
358 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, | ||
359 | ("presta_connectstate = %x," | ||
360 | " cursta_connectctate = %x\n", | ||
361 | dm_digtable.presta_connectstate, | ||
362 | dm_digtable.cursta_connectctate)); | ||
363 | |||
364 | if (dm_digtable.presta_connectstate == dm_digtable.cursta_connectctate | ||
365 | || dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT | ||
366 | || dm_digtable.cursta_connectctate == DIG_STA_CONNECT) { | ||
367 | |||
368 | if (dm_digtable.cursta_connectctate != DIG_STA_DISCONNECT) { | ||
369 | dm_digtable.rssi_val_min = | ||
370 | rtl92c_dm_initial_gain_min_pwdb(hw); | ||
371 | rtl92c_dm_ctrl_initgain_by_rssi(hw); | ||
372 | } | ||
373 | } else { | ||
374 | dm_digtable.rssi_val_min = 0; | ||
375 | dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; | ||
376 | dm_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT; | ||
377 | dm_digtable.cur_igvalue = 0x20; | ||
378 | dm_digtable.pre_igvalue = 0; | ||
379 | rtl92c_dm_write_dig(hw); | ||
380 | } | ||
381 | } | ||
382 | |||
383 | static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) | ||
384 | { | ||
385 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
386 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
387 | |||
388 | if (dm_digtable.cursta_connectctate == DIG_STA_CONNECT) { | ||
389 | dm_digtable.rssi_val_min = rtl92c_dm_initial_gain_min_pwdb(hw); | ||
390 | |||
391 | if (dm_digtable.pre_cck_pd_state == CCK_PD_STAGE_LowRssi) { | ||
392 | if (dm_digtable.rssi_val_min <= 25) | ||
393 | dm_digtable.cur_cck_pd_state = | ||
394 | CCK_PD_STAGE_LowRssi; | ||
395 | else | ||
396 | dm_digtable.cur_cck_pd_state = | ||
397 | CCK_PD_STAGE_HighRssi; | ||
398 | } else { | ||
399 | if (dm_digtable.rssi_val_min <= 20) | ||
400 | dm_digtable.cur_cck_pd_state = | ||
401 | CCK_PD_STAGE_LowRssi; | ||
402 | else | ||
403 | dm_digtable.cur_cck_pd_state = | ||
404 | CCK_PD_STAGE_HighRssi; | ||
405 | } | ||
406 | } else { | ||
407 | dm_digtable.cur_cck_pd_state = CCK_PD_STAGE_MAX; | ||
408 | } | ||
409 | |||
410 | if (dm_digtable.pre_cck_pd_state != dm_digtable.cur_cck_pd_state) { | ||
411 | if (dm_digtable.cur_cck_pd_state == CCK_PD_STAGE_LowRssi) { | ||
412 | if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800) | ||
413 | dm_digtable.cur_cck_fa_state = | ||
414 | CCK_FA_STAGE_High; | ||
415 | else | ||
416 | dm_digtable.cur_cck_fa_state = CCK_FA_STAGE_Low; | ||
417 | |||
418 | if (dm_digtable.pre_cck_fa_state != | ||
419 | dm_digtable.cur_cck_fa_state) { | ||
420 | if (dm_digtable.cur_cck_fa_state == | ||
421 | CCK_FA_STAGE_Low) | ||
422 | rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, | ||
423 | 0x83); | ||
424 | else | ||
425 | rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, | ||
426 | 0xcd); | ||
427 | |||
428 | dm_digtable.pre_cck_fa_state = | ||
429 | dm_digtable.cur_cck_fa_state; | ||
430 | } | ||
431 | |||
432 | rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40); | ||
433 | |||
434 | if (IS_92C_SERIAL(rtlhal->version)) | ||
435 | rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, | ||
436 | MASKBYTE2, 0xd7); | ||
437 | } else { | ||
438 | rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); | ||
439 | rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47); | ||
440 | |||
441 | if (IS_92C_SERIAL(rtlhal->version)) | ||
442 | rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, | ||
443 | MASKBYTE2, 0xd3); | ||
444 | } | ||
445 | dm_digtable.pre_cck_pd_state = dm_digtable.cur_cck_pd_state; | ||
446 | } | ||
447 | |||
448 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, | ||
449 | ("CCKPDStage=%x\n", dm_digtable.cur_cck_pd_state)); | ||
450 | |||
451 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, | ||
452 | ("is92C=%x\n", IS_92C_SERIAL(rtlhal->version))); | ||
453 | } | ||
454 | |||
455 | static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) | ||
456 | { | ||
457 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
458 | |||
459 | if (mac->act_scanning == true) | ||
460 | return; | ||
461 | |||
462 | if ((mac->link_state > MAC80211_NOLINK) && | ||
463 | (mac->link_state < MAC80211_LINKED)) | ||
464 | dm_digtable.cursta_connectctate = DIG_STA_BEFORE_CONNECT; | ||
465 | else if (mac->link_state >= MAC80211_LINKED) | ||
466 | dm_digtable.cursta_connectctate = DIG_STA_CONNECT; | ||
467 | else | ||
468 | dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT; | ||
469 | |||
470 | rtl92c_dm_initial_gain_sta(hw); | ||
471 | rtl92c_dm_initial_gain_multi_sta(hw); | ||
472 | rtl92c_dm_cck_packet_detection_thresh(hw); | ||
473 | |||
474 | dm_digtable.presta_connectstate = dm_digtable.cursta_connectctate; | ||
475 | |||
476 | } | ||
477 | |||
478 | static void rtl92c_dm_dig(struct ieee80211_hw *hw) | ||
479 | { | ||
480 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
481 | |||
482 | if (rtlpriv->dm.dm_initialgain_enable == false) | ||
483 | return; | ||
484 | if (dm_digtable.dig_enable_flag == false) | ||
485 | return; | ||
486 | |||
487 | rtl92c_dm_ctrl_initgain_by_twoport(hw); | ||
488 | |||
489 | } | ||
490 | |||
491 | static void rtl92c_dm_init_dynamic_txpower(struct ieee80211_hw *hw) | ||
492 | { | ||
493 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
494 | |||
495 | rtlpriv->dm.dynamic_txpower_enable = false; | ||
496 | |||
497 | rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; | ||
498 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; | ||
499 | } | ||
500 | |||
501 | void rtl92c_dm_write_dig(struct ieee80211_hw *hw) | ||
502 | { | ||
503 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
504 | |||
505 | RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, | ||
506 | ("cur_igvalue = 0x%x, " | ||
507 | "pre_igvalue = 0x%x, backoff_val = %d\n", | ||
508 | dm_digtable.cur_igvalue, dm_digtable.pre_igvalue, | ||
509 | dm_digtable.backoff_val)); | ||
510 | |||
511 | if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) { | ||
512 | rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, | ||
513 | dm_digtable.cur_igvalue); | ||
514 | rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f, | ||
515 | dm_digtable.cur_igvalue); | ||
516 | |||
517 | dm_digtable.pre_igvalue = dm_digtable.cur_igvalue; | ||
518 | } | ||
519 | } | ||
520 | |||
521 | static void rtl92c_dm_pwdb_monitor(struct ieee80211_hw *hw) | ||
522 | { | ||
523 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
524 | long tmpentry_max_pwdb = 0, tmpentry_min_pwdb = 0xff; | ||
525 | |||
526 | u8 h2c_parameter[3] = { 0 }; | ||
527 | |||
528 | return; | ||
529 | |||
530 | if (tmpentry_max_pwdb != 0) { | ||
531 | rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = | ||
532 | tmpentry_max_pwdb; | ||
533 | } else { | ||
534 | rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = 0; | ||
535 | } | ||
536 | |||
537 | if (tmpentry_min_pwdb != 0xff) { | ||
538 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = | ||
539 | tmpentry_min_pwdb; | ||
540 | } else { | ||
541 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = 0; | ||
542 | } | ||
543 | |||
544 | h2c_parameter[2] = (u8) (rtlpriv->dm.undecorated_smoothed_pwdb & 0xFF); | ||
545 | h2c_parameter[0] = 0; | ||
546 | |||
547 | rtl92c_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, h2c_parameter); | ||
548 | } | ||
549 | |||
550 | void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw) | ||
551 | { | ||
552 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
553 | rtlpriv->dm.current_turbo_edca = false; | ||
554 | rtlpriv->dm.is_any_nonbepkts = false; | ||
555 | rtlpriv->dm.is_cur_rdlstate = false; | ||
556 | } | ||
557 | |||
558 | static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw) | ||
559 | { | ||
560 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
561 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
562 | static u64 last_txok_cnt; | ||
563 | static u64 last_rxok_cnt; | ||
564 | u64 cur_txok_cnt; | ||
565 | u64 cur_rxok_cnt; | ||
566 | u32 edca_be_ul = 0x5ea42b; | ||
567 | u32 edca_be_dl = 0x5ea42b; | ||
568 | |||
569 | if (mac->opmode == NL80211_IFTYPE_ADHOC) | ||
570 | goto dm_checkedcaturbo_exit; | ||
571 | |||
572 | if (mac->link_state != MAC80211_LINKED) { | ||
573 | rtlpriv->dm.current_turbo_edca = false; | ||
574 | return; | ||
575 | } | ||
576 | |||
577 | if (!mac->ht_enable) { /*FIX MERGE */ | ||
578 | if (!(edca_be_ul & 0xffff0000)) | ||
579 | edca_be_ul |= 0x005e0000; | ||
580 | |||
581 | if (!(edca_be_dl & 0xffff0000)) | ||
582 | edca_be_dl |= 0x005e0000; | ||
583 | } | ||
584 | |||
585 | if ((!rtlpriv->dm.is_any_nonbepkts) && | ||
586 | (!rtlpriv->dm.disable_framebursting)) { | ||
587 | cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt; | ||
588 | cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt; | ||
589 | if (cur_rxok_cnt > 4 * cur_txok_cnt) { | ||
590 | if (!rtlpriv->dm.is_cur_rdlstate || | ||
591 | !rtlpriv->dm.current_turbo_edca) { | ||
592 | rtl_write_dword(rtlpriv, | ||
593 | REG_EDCA_BE_PARAM, | ||
594 | edca_be_dl); | ||
595 | rtlpriv->dm.is_cur_rdlstate = true; | ||
596 | } | ||
597 | } else { | ||
598 | if (rtlpriv->dm.is_cur_rdlstate || | ||
599 | !rtlpriv->dm.current_turbo_edca) { | ||
600 | rtl_write_dword(rtlpriv, | ||
601 | REG_EDCA_BE_PARAM, | ||
602 | edca_be_ul); | ||
603 | rtlpriv->dm.is_cur_rdlstate = false; | ||
604 | } | ||
605 | } | ||
606 | rtlpriv->dm.current_turbo_edca = true; | ||
607 | } else { | ||
608 | if (rtlpriv->dm.current_turbo_edca) { | ||
609 | u8 tmp = AC0_BE; | ||
610 | rtlpriv->cfg->ops->set_hw_reg(hw, | ||
611 | HW_VAR_AC_PARAM, | ||
612 | (u8 *) (&tmp)); | ||
613 | rtlpriv->dm.current_turbo_edca = false; | ||
614 | } | ||
615 | } | ||
616 | |||
617 | dm_checkedcaturbo_exit: | ||
618 | rtlpriv->dm.is_any_nonbepkts = false; | ||
619 | last_txok_cnt = rtlpriv->stats.txbytesunicast; | ||
620 | last_rxok_cnt = rtlpriv->stats.rxbytesunicast; | ||
621 | } | ||
622 | |||
623 | static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw | ||
624 | *hw) | ||
625 | { | ||
626 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
627 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
628 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
629 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
630 | u8 thermalvalue, delta, delta_lck, delta_iqk; | ||
631 | long ele_a, ele_d, temp_cck, val_x, value32; | ||
632 | long val_y, ele_c; | ||
633 | u8 ofdm_index[2], cck_index, ofdm_index_old[2], cck_index_old; | ||
634 | int i; | ||
635 | bool is2t = IS_92C_SERIAL(rtlhal->version); | ||
636 | u8 txpwr_level[2] = {0, 0}; | ||
637 | u8 ofdm_min_index = 6, rf; | ||
638 | |||
639 | rtlpriv->dm.txpower_trackingInit = true; | ||
640 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | ||
641 | ("rtl92c_dm_txpower_tracking_callback_thermalmeter\n")); | ||
642 | |||
643 | thermalvalue = (u8) rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f); | ||
644 | |||
645 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | ||
646 | ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " | ||
647 | "eeprom_thermalmeter 0x%x\n", | ||
648 | thermalvalue, rtlpriv->dm.thermalvalue, | ||
649 | rtlefuse->eeprom_thermalmeter)); | ||
650 | |||
651 | rtl92c_phy_ap_calibrate(hw, (thermalvalue - | ||
652 | rtlefuse->eeprom_thermalmeter)); | ||
653 | if (is2t) | ||
654 | rf = 2; | ||
655 | else | ||
656 | rf = 1; | ||
657 | |||
658 | if (thermalvalue) { | ||
659 | ele_d = rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, | ||
660 | MASKDWORD) & MASKOFDM_D; | ||
661 | |||
662 | for (i = 0; i < OFDM_TABLE_LENGTH; i++) { | ||
663 | if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) { | ||
664 | ofdm_index_old[0] = (u8) i; | ||
665 | |||
666 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | ||
667 | ("Initial pathA ele_d reg0x%x = 0x%lx, " | ||
668 | "ofdm_index=0x%x\n", | ||
669 | ROFDM0_XATXIQIMBALANCE, | ||
670 | ele_d, ofdm_index_old[0])); | ||
671 | break; | ||
672 | } | ||
673 | } | ||
674 | |||
675 | if (is2t) { | ||
676 | ele_d = rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, | ||
677 | MASKDWORD) & MASKOFDM_D; | ||
678 | |||
679 | for (i = 0; i < OFDM_TABLE_LENGTH; i++) { | ||
680 | if (ele_d == (ofdmswing_table[i] & | ||
681 | MASKOFDM_D)) { | ||
682 | ofdm_index_old[1] = (u8) i; | ||
683 | |||
684 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, | ||
685 | DBG_LOUD, | ||
686 | ("Initial pathB ele_d reg0x%x = " | ||
687 | "0x%lx, ofdm_index=0x%x\n", | ||
688 | ROFDM0_XBTXIQIMBALANCE, ele_d, | ||
689 | ofdm_index_old[1])); | ||
690 | break; | ||
691 | } | ||
692 | } | ||
693 | } | ||
694 | |||
695 | temp_cck = | ||
696 | rtl_get_bbreg(hw, RCCK0_TXFILTER2, MASKDWORD) & MASKCCK; | ||
697 | |||
698 | for (i = 0; i < CCK_TABLE_LENGTH; i++) { | ||
699 | if (rtlpriv->dm.cck_inch14) { | ||
700 | if (memcmp((void *)&temp_cck, | ||
701 | (void *)&cckswing_table_ch14[i][2], | ||
702 | 4) == 0) { | ||
703 | cck_index_old = (u8) i; | ||
704 | |||
705 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, | ||
706 | DBG_LOUD, | ||
707 | ("Initial reg0x%x = 0x%lx, " | ||
708 | "cck_index=0x%x, ch 14 %d\n", | ||
709 | RCCK0_TXFILTER2, temp_cck, | ||
710 | cck_index_old, | ||
711 | rtlpriv->dm.cck_inch14)); | ||
712 | break; | ||
713 | } | ||
714 | } else { | ||
715 | if (memcmp((void *)&temp_cck, | ||
716 | (void *) | ||
717 | &cckswing_table_ch1ch13[i][2], | ||
718 | 4) == 0) { | ||
719 | cck_index_old = (u8) i; | ||
720 | |||
721 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, | ||
722 | DBG_LOUD, | ||
723 | ("Initial reg0x%x = 0x%lx, " | ||
724 | "cck_index=0x%x, ch14 %d\n", | ||
725 | RCCK0_TXFILTER2, temp_cck, | ||
726 | cck_index_old, | ||
727 | rtlpriv->dm.cck_inch14)); | ||
728 | break; | ||
729 | } | ||
730 | } | ||
731 | } | ||
732 | |||
733 | if (!rtlpriv->dm.thermalvalue) { | ||
734 | rtlpriv->dm.thermalvalue = | ||
735 | rtlefuse->eeprom_thermalmeter; | ||
736 | rtlpriv->dm.thermalvalue_lck = thermalvalue; | ||
737 | rtlpriv->dm.thermalvalue_iqk = thermalvalue; | ||
738 | for (i = 0; i < rf; i++) | ||
739 | rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i]; | ||
740 | rtlpriv->dm.cck_index = cck_index_old; | ||
741 | } | ||
742 | |||
743 | delta = (thermalvalue > rtlpriv->dm.thermalvalue) ? | ||
744 | (thermalvalue - rtlpriv->dm.thermalvalue) : | ||
745 | (rtlpriv->dm.thermalvalue - thermalvalue); | ||
746 | |||
747 | delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ? | ||
748 | (thermalvalue - rtlpriv->dm.thermalvalue_lck) : | ||
749 | (rtlpriv->dm.thermalvalue_lck - thermalvalue); | ||
750 | |||
751 | delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ? | ||
752 | (thermalvalue - rtlpriv->dm.thermalvalue_iqk) : | ||
753 | (rtlpriv->dm.thermalvalue_iqk - thermalvalue); | ||
754 | |||
755 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | ||
756 | ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " | ||
757 | "eeprom_thermalmeter 0x%x delta 0x%x " | ||
758 | "delta_lck 0x%x delta_iqk 0x%x\n", | ||
759 | thermalvalue, rtlpriv->dm.thermalvalue, | ||
760 | rtlefuse->eeprom_thermalmeter, delta, delta_lck, | ||
761 | delta_iqk)); | ||
762 | |||
763 | if (delta_lck > 1) { | ||
764 | rtlpriv->dm.thermalvalue_lck = thermalvalue; | ||
765 | rtl92c_phy_lc_calibrate(hw); | ||
766 | } | ||
767 | |||
768 | if (delta > 0 && rtlpriv->dm.txpower_track_control) { | ||
769 | if (thermalvalue > rtlpriv->dm.thermalvalue) { | ||
770 | for (i = 0; i < rf; i++) | ||
771 | rtlpriv->dm.ofdm_index[i] -= delta; | ||
772 | rtlpriv->dm.cck_index -= delta; | ||
773 | } else { | ||
774 | for (i = 0; i < rf; i++) | ||
775 | rtlpriv->dm.ofdm_index[i] += delta; | ||
776 | rtlpriv->dm.cck_index += delta; | ||
777 | } | ||
778 | |||
779 | if (is2t) { | ||
780 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | ||
781 | ("temp OFDM_A_index=0x%x, " | ||
782 | "OFDM_B_index=0x%x," | ||
783 | "cck_index=0x%x\n", | ||
784 | rtlpriv->dm.ofdm_index[0], | ||
785 | rtlpriv->dm.ofdm_index[1], | ||
786 | rtlpriv->dm.cck_index)); | ||
787 | } else { | ||
788 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | ||
789 | ("temp OFDM_A_index=0x%x," | ||
790 | "cck_index=0x%x\n", | ||
791 | rtlpriv->dm.ofdm_index[0], | ||
792 | rtlpriv->dm.cck_index)); | ||
793 | } | ||
794 | |||
795 | if (thermalvalue > rtlefuse->eeprom_thermalmeter) { | ||
796 | for (i = 0; i < rf; i++) | ||
797 | ofdm_index[i] = | ||
798 | rtlpriv->dm.ofdm_index[i] | ||
799 | + 1; | ||
800 | cck_index = rtlpriv->dm.cck_index + 1; | ||
801 | } else { | ||
802 | for (i = 0; i < rf; i++) | ||
803 | ofdm_index[i] = | ||
804 | rtlpriv->dm.ofdm_index[i]; | ||
805 | cck_index = rtlpriv->dm.cck_index; | ||
806 | } | ||
807 | |||
808 | for (i = 0; i < rf; i++) { | ||
809 | if (txpwr_level[i] >= 0 && | ||
810 | txpwr_level[i] <= 26) { | ||
811 | if (thermalvalue > | ||
812 | rtlefuse->eeprom_thermalmeter) { | ||
813 | if (delta < 5) | ||
814 | ofdm_index[i] -= 1; | ||
815 | |||
816 | else | ||
817 | ofdm_index[i] -= 2; | ||
818 | } else if (delta > 5 && thermalvalue < | ||
819 | rtlefuse-> | ||
820 | eeprom_thermalmeter) { | ||
821 | ofdm_index[i] += 1; | ||
822 | } | ||
823 | } else if (txpwr_level[i] >= 27 && | ||
824 | txpwr_level[i] <= 32 | ||
825 | && thermalvalue > | ||
826 | rtlefuse->eeprom_thermalmeter) { | ||
827 | if (delta < 5) | ||
828 | ofdm_index[i] -= 1; | ||
829 | |||
830 | else | ||
831 | ofdm_index[i] -= 2; | ||
832 | } else if (txpwr_level[i] >= 32 && | ||
833 | txpwr_level[i] <= 38 && | ||
834 | thermalvalue > | ||
835 | rtlefuse->eeprom_thermalmeter | ||
836 | && delta > 5) { | ||
837 | ofdm_index[i] -= 1; | ||
838 | } | ||
839 | } | ||
840 | |||
841 | if (txpwr_level[i] >= 0 && txpwr_level[i] <= 26) { | ||
842 | if (thermalvalue > | ||
843 | rtlefuse->eeprom_thermalmeter) { | ||
844 | if (delta < 5) | ||
845 | cck_index -= 1; | ||
846 | |||
847 | else | ||
848 | cck_index -= 2; | ||
849 | } else if (delta > 5 && thermalvalue < | ||
850 | rtlefuse->eeprom_thermalmeter) { | ||
851 | cck_index += 1; | ||
852 | } | ||
853 | } else if (txpwr_level[i] >= 27 && | ||
854 | txpwr_level[i] <= 32 && | ||
855 | thermalvalue > | ||
856 | rtlefuse->eeprom_thermalmeter) { | ||
857 | if (delta < 5) | ||
858 | cck_index -= 1; | ||
859 | |||
860 | else | ||
861 | cck_index -= 2; | ||
862 | } else if (txpwr_level[i] >= 32 && | ||
863 | txpwr_level[i] <= 38 && | ||
864 | thermalvalue > rtlefuse->eeprom_thermalmeter | ||
865 | && delta > 5) { | ||
866 | cck_index -= 1; | ||
867 | } | ||
868 | |||
869 | for (i = 0; i < rf; i++) { | ||
870 | if (ofdm_index[i] > OFDM_TABLE_SIZE - 1) | ||
871 | ofdm_index[i] = OFDM_TABLE_SIZE - 1; | ||
872 | |||
873 | else if (ofdm_index[i] < ofdm_min_index) | ||
874 | ofdm_index[i] = ofdm_min_index; | ||
875 | } | ||
876 | |||
877 | if (cck_index > CCK_TABLE_SIZE - 1) | ||
878 | cck_index = CCK_TABLE_SIZE - 1; | ||
879 | else if (cck_index < 0) | ||
880 | cck_index = 0; | ||
881 | |||
882 | if (is2t) { | ||
883 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | ||
884 | ("new OFDM_A_index=0x%x, " | ||
885 | "OFDM_B_index=0x%x," | ||
886 | "cck_index=0x%x\n", | ||
887 | ofdm_index[0], ofdm_index[1], | ||
888 | cck_index)); | ||
889 | } else { | ||
890 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | ||
891 | ("new OFDM_A_index=0x%x," | ||
892 | "cck_index=0x%x\n", | ||
893 | ofdm_index[0], cck_index)); | ||
894 | } | ||
895 | } | ||
896 | |||
897 | if (rtlpriv->dm.txpower_track_control && delta != 0) { | ||
898 | ele_d = | ||
899 | (ofdmswing_table[ofdm_index[0]] & 0xFFC00000) >> 22; | ||
900 | val_x = rtlphy->reg_e94; | ||
901 | val_y = rtlphy->reg_e9c; | ||
902 | |||
903 | if (val_x != 0) { | ||
904 | if ((val_x & 0x00000200) != 0) | ||
905 | val_x = val_x | 0xFFFFFC00; | ||
906 | ele_a = ((val_x * ele_d) >> 8) & 0x000003FF; | ||
907 | |||
908 | if ((val_y & 0x00000200) != 0) | ||
909 | val_y = val_y | 0xFFFFFC00; | ||
910 | ele_c = ((val_y * ele_d) >> 8) & 0x000003FF; | ||
911 | |||
912 | value32 = (ele_d << 22) | | ||
913 | ((ele_c & 0x3F) << 16) | ele_a; | ||
914 | |||
915 | rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, | ||
916 | MASKDWORD, value32); | ||
917 | |||
918 | value32 = (ele_c & 0x000003C0) >> 6; | ||
919 | rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, | ||
920 | value32); | ||
921 | |||
922 | value32 = ((val_x * ele_d) >> 7) & 0x01; | ||
923 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, | ||
924 | BIT(31), value32); | ||
925 | |||
926 | value32 = ((val_y * ele_d) >> 7) & 0x01; | ||
927 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, | ||
928 | BIT(29), value32); | ||
929 | } else { | ||
930 | rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, | ||
931 | MASKDWORD, | ||
932 | ofdmswing_table[ofdm_index[0]]); | ||
933 | |||
934 | rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, | ||
935 | 0x00); | ||
936 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, | ||
937 | BIT(31) | BIT(29), 0x00); | ||
938 | } | ||
939 | |||
940 | if (!rtlpriv->dm.cck_inch14) { | ||
941 | rtl_write_byte(rtlpriv, 0xa22, | ||
942 | cckswing_table_ch1ch13[cck_index] | ||
943 | [0]); | ||
944 | rtl_write_byte(rtlpriv, 0xa23, | ||
945 | cckswing_table_ch1ch13[cck_index] | ||
946 | [1]); | ||
947 | rtl_write_byte(rtlpriv, 0xa24, | ||
948 | cckswing_table_ch1ch13[cck_index] | ||
949 | [2]); | ||
950 | rtl_write_byte(rtlpriv, 0xa25, | ||
951 | cckswing_table_ch1ch13[cck_index] | ||
952 | [3]); | ||
953 | rtl_write_byte(rtlpriv, 0xa26, | ||
954 | cckswing_table_ch1ch13[cck_index] | ||
955 | [4]); | ||
956 | rtl_write_byte(rtlpriv, 0xa27, | ||
957 | cckswing_table_ch1ch13[cck_index] | ||
958 | [5]); | ||
959 | rtl_write_byte(rtlpriv, 0xa28, | ||
960 | cckswing_table_ch1ch13[cck_index] | ||
961 | [6]); | ||
962 | rtl_write_byte(rtlpriv, 0xa29, | ||
963 | cckswing_table_ch1ch13[cck_index] | ||
964 | [7]); | ||
965 | } else { | ||
966 | rtl_write_byte(rtlpriv, 0xa22, | ||
967 | cckswing_table_ch14[cck_index] | ||
968 | [0]); | ||
969 | rtl_write_byte(rtlpriv, 0xa23, | ||
970 | cckswing_table_ch14[cck_index] | ||
971 | [1]); | ||
972 | rtl_write_byte(rtlpriv, 0xa24, | ||
973 | cckswing_table_ch14[cck_index] | ||
974 | [2]); | ||
975 | rtl_write_byte(rtlpriv, 0xa25, | ||
976 | cckswing_table_ch14[cck_index] | ||
977 | [3]); | ||
978 | rtl_write_byte(rtlpriv, 0xa26, | ||
979 | cckswing_table_ch14[cck_index] | ||
980 | [4]); | ||
981 | rtl_write_byte(rtlpriv, 0xa27, | ||
982 | cckswing_table_ch14[cck_index] | ||
983 | [5]); | ||
984 | rtl_write_byte(rtlpriv, 0xa28, | ||
985 | cckswing_table_ch14[cck_index] | ||
986 | [6]); | ||
987 | rtl_write_byte(rtlpriv, 0xa29, | ||
988 | cckswing_table_ch14[cck_index] | ||
989 | [7]); | ||
990 | } | ||
991 | |||
992 | if (is2t) { | ||
993 | ele_d = (ofdmswing_table[ofdm_index[1]] & | ||
994 | 0xFFC00000) >> 22; | ||
995 | |||
996 | val_x = rtlphy->reg_eb4; | ||
997 | val_y = rtlphy->reg_ebc; | ||
998 | |||
999 | if (val_x != 0) { | ||
1000 | if ((val_x & 0x00000200) != 0) | ||
1001 | val_x = val_x | 0xFFFFFC00; | ||
1002 | ele_a = ((val_x * ele_d) >> 8) & | ||
1003 | 0x000003FF; | ||
1004 | |||
1005 | if ((val_y & 0x00000200) != 0) | ||
1006 | val_y = val_y | 0xFFFFFC00; | ||
1007 | ele_c = ((val_y * ele_d) >> 8) & | ||
1008 | 0x00003FF; | ||
1009 | |||
1010 | value32 = (ele_d << 22) | | ||
1011 | ((ele_c & 0x3F) << 16) | ele_a; | ||
1012 | rtl_set_bbreg(hw, | ||
1013 | ROFDM0_XBTXIQIMBALANCE, | ||
1014 | MASKDWORD, value32); | ||
1015 | |||
1016 | value32 = (ele_c & 0x000003C0) >> 6; | ||
1017 | rtl_set_bbreg(hw, ROFDM0_XDTXAFE, | ||
1018 | MASKH4BITS, value32); | ||
1019 | |||
1020 | value32 = ((val_x * ele_d) >> 7) & 0x01; | ||
1021 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, | ||
1022 | BIT(27), value32); | ||
1023 | |||
1024 | value32 = ((val_y * ele_d) >> 7) & 0x01; | ||
1025 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, | ||
1026 | BIT(25), value32); | ||
1027 | } else { | ||
1028 | rtl_set_bbreg(hw, | ||
1029 | ROFDM0_XBTXIQIMBALANCE, | ||
1030 | MASKDWORD, | ||
1031 | ofdmswing_table[ofdm_index | ||
1032 | [1]]); | ||
1033 | rtl_set_bbreg(hw, ROFDM0_XDTXAFE, | ||
1034 | MASKH4BITS, 0x00); | ||
1035 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, | ||
1036 | BIT(27) | BIT(25), 0x00); | ||
1037 | } | ||
1038 | |||
1039 | } | ||
1040 | } | ||
1041 | |||
1042 | if (delta_iqk > 3) { | ||
1043 | rtlpriv->dm.thermalvalue_iqk = thermalvalue; | ||
1044 | rtl92c_phy_iq_calibrate(hw, false); | ||
1045 | } | ||
1046 | |||
1047 | if (rtlpriv->dm.txpower_track_control) | ||
1048 | rtlpriv->dm.thermalvalue = thermalvalue; | ||
1049 | } | ||
1050 | |||
1051 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("<===\n")); | ||
1052 | |||
1053 | } | ||
1054 | |||
1055 | static void rtl92c_dm_initialize_txpower_tracking_thermalmeter( | ||
1056 | struct ieee80211_hw *hw) | ||
1057 | { | ||
1058 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1059 | |||
1060 | rtlpriv->dm.txpower_tracking = true; | ||
1061 | rtlpriv->dm.txpower_trackingInit = false; | ||
1062 | |||
1063 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | ||
1064 | ("pMgntInfo->txpower_tracking = %d\n", | ||
1065 | rtlpriv->dm.txpower_tracking)); | ||
1066 | } | ||
1067 | |||
1068 | static void rtl92c_dm_initialize_txpower_tracking(struct ieee80211_hw *hw) | ||
1069 | { | ||
1070 | rtl92c_dm_initialize_txpower_tracking_thermalmeter(hw); | ||
1071 | } | ||
1072 | |||
1073 | static void rtl92c_dm_txpower_tracking_directcall(struct ieee80211_hw *hw) | ||
1074 | { | ||
1075 | rtl92c_dm_txpower_tracking_callback_thermalmeter(hw); | ||
1076 | } | ||
1077 | |||
1078 | static void rtl92c_dm_check_txpower_tracking_thermal_meter( | ||
1079 | struct ieee80211_hw *hw) | ||
1080 | { | ||
1081 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1082 | static u8 tm_trigger; | ||
1083 | |||
1084 | if (!rtlpriv->dm.txpower_tracking) | ||
1085 | return; | ||
1086 | |||
1087 | if (!tm_trigger) { | ||
1088 | rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, RFREG_OFFSET_MASK, | ||
1089 | 0x60); | ||
1090 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | ||
1091 | ("Trigger 92S Thermal Meter!!\n")); | ||
1092 | tm_trigger = 1; | ||
1093 | return; | ||
1094 | } else { | ||
1095 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | ||
1096 | ("Schedule TxPowerTracking direct call!!\n")); | ||
1097 | rtl92c_dm_txpower_tracking_directcall(hw); | ||
1098 | tm_trigger = 0; | ||
1099 | } | ||
1100 | } | ||
1101 | |||
1102 | void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw) | ||
1103 | { | ||
1104 | rtl92c_dm_check_txpower_tracking_thermal_meter(hw); | ||
1105 | } | ||
1106 | |||
1107 | void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) | ||
1108 | { | ||
1109 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1110 | struct rate_adaptive *p_ra = &(rtlpriv->ra); | ||
1111 | |||
1112 | p_ra->ratr_state = DM_RATR_STA_INIT; | ||
1113 | p_ra->pre_ratr_state = DM_RATR_STA_INIT; | ||
1114 | |||
1115 | if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) | ||
1116 | rtlpriv->dm.useramask = true; | ||
1117 | else | ||
1118 | rtlpriv->dm.useramask = false; | ||
1119 | |||
1120 | } | ||
1121 | |||
1122 | static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) | ||
1123 | { | ||
1124 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1125 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1126 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
1127 | struct rate_adaptive *p_ra = &(rtlpriv->ra); | ||
1128 | u32 low_rssithresh_for_ra, high_rssithresh_for_ra; | ||
1129 | |||
1130 | if (is_hal_stop(rtlhal)) { | ||
1131 | RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, | ||
1132 | ("<---- driver is going to unload\n")); | ||
1133 | return; | ||
1134 | } | ||
1135 | |||
1136 | if (!rtlpriv->dm.useramask) { | ||
1137 | RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, | ||
1138 | ("<---- driver does not control rate adaptive mask\n")); | ||
1139 | return; | ||
1140 | } | ||
1141 | |||
1142 | if (mac->link_state == MAC80211_LINKED) { | ||
1143 | |||
1144 | switch (p_ra->pre_ratr_state) { | ||
1145 | case DM_RATR_STA_HIGH: | ||
1146 | high_rssithresh_for_ra = 50; | ||
1147 | low_rssithresh_for_ra = 20; | ||
1148 | break; | ||
1149 | case DM_RATR_STA_MIDDLE: | ||
1150 | high_rssithresh_for_ra = 55; | ||
1151 | low_rssithresh_for_ra = 20; | ||
1152 | break; | ||
1153 | case DM_RATR_STA_LOW: | ||
1154 | high_rssithresh_for_ra = 50; | ||
1155 | low_rssithresh_for_ra = 25; | ||
1156 | break; | ||
1157 | default: | ||
1158 | high_rssithresh_for_ra = 50; | ||
1159 | low_rssithresh_for_ra = 20; | ||
1160 | break; | ||
1161 | } | ||
1162 | |||
1163 | if (rtlpriv->dm.undecorated_smoothed_pwdb > | ||
1164 | (long)high_rssithresh_for_ra) | ||
1165 | p_ra->ratr_state = DM_RATR_STA_HIGH; | ||
1166 | else if (rtlpriv->dm.undecorated_smoothed_pwdb > | ||
1167 | (long)low_rssithresh_for_ra) | ||
1168 | p_ra->ratr_state = DM_RATR_STA_MIDDLE; | ||
1169 | else | ||
1170 | p_ra->ratr_state = DM_RATR_STA_LOW; | ||
1171 | |||
1172 | if (p_ra->pre_ratr_state != p_ra->ratr_state) { | ||
1173 | RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, | ||
1174 | ("RSSI = %ld\n", | ||
1175 | rtlpriv->dm.undecorated_smoothed_pwdb)); | ||
1176 | RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, | ||
1177 | ("RSSI_LEVEL = %d\n", p_ra->ratr_state)); | ||
1178 | RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, | ||
1179 | ("PreState = %d, CurState = %d\n", | ||
1180 | p_ra->pre_ratr_state, p_ra->ratr_state)); | ||
1181 | |||
1182 | rtlpriv->cfg->ops->update_rate_mask(hw, | ||
1183 | p_ra->ratr_state); | ||
1184 | |||
1185 | p_ra->pre_ratr_state = p_ra->ratr_state; | ||
1186 | } | ||
1187 | } | ||
1188 | } | ||
1189 | |||
1190 | static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw) | ||
1191 | { | ||
1192 | dm_pstable.pre_ccastate = CCA_MAX; | ||
1193 | dm_pstable.cur_ccasate = CCA_MAX; | ||
1194 | dm_pstable.pre_rfstate = RF_MAX; | ||
1195 | dm_pstable.cur_rfstate = RF_MAX; | ||
1196 | dm_pstable.rssi_val_min = 0; | ||
1197 | } | ||
1198 | |||
1199 | static void rtl92c_dm_1r_cca(struct ieee80211_hw *hw) | ||
1200 | { | ||
1201 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1202 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1203 | |||
1204 | if (dm_pstable.rssi_val_min != 0) { | ||
1205 | if (dm_pstable.pre_ccastate == CCA_2R) { | ||
1206 | if (dm_pstable.rssi_val_min >= 35) | ||
1207 | dm_pstable.cur_ccasate = CCA_1R; | ||
1208 | else | ||
1209 | dm_pstable.cur_ccasate = CCA_2R; | ||
1210 | } else { | ||
1211 | if (dm_pstable.rssi_val_min <= 30) | ||
1212 | dm_pstable.cur_ccasate = CCA_2R; | ||
1213 | else | ||
1214 | dm_pstable.cur_ccasate = CCA_1R; | ||
1215 | } | ||
1216 | } else { | ||
1217 | dm_pstable.cur_ccasate = CCA_MAX; | ||
1218 | } | ||
1219 | |||
1220 | if (dm_pstable.pre_ccastate != dm_pstable.cur_ccasate) { | ||
1221 | if (dm_pstable.cur_ccasate == CCA_1R) { | ||
1222 | if (get_rf_type(rtlphy) == RF_2T2R) { | ||
1223 | rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, | ||
1224 | MASKBYTE0, 0x13); | ||
1225 | rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x20); | ||
1226 | } else { | ||
1227 | rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, | ||
1228 | MASKBYTE0, 0x23); | ||
1229 | rtl_set_bbreg(hw, 0xe70, 0x7fc00000, 0x10c); | ||
1230 | } | ||
1231 | } else { | ||
1232 | rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, | ||
1233 | 0x33); | ||
1234 | rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x63); | ||
1235 | } | ||
1236 | dm_pstable.pre_ccastate = dm_pstable.cur_ccasate; | ||
1237 | } | ||
1238 | |||
1239 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, ("CCAStage = %s\n", | ||
1240 | (dm_pstable.cur_ccasate == | ||
1241 | 0) ? "1RCCA" : "2RCCA")); | ||
1242 | } | ||
1243 | |||
1244 | void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal) | ||
1245 | { | ||
1246 | static u8 initialize; | ||
1247 | static u32 reg_874, reg_c70, reg_85c, reg_a74; | ||
1248 | |||
1249 | if (initialize == 0) { | ||
1250 | reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, | ||
1251 | MASKDWORD) & 0x1CC000) >> 14; | ||
1252 | |||
1253 | reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1, | ||
1254 | MASKDWORD) & BIT(3)) >> 3; | ||
1255 | |||
1256 | reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, | ||
1257 | MASKDWORD) & 0xFF000000) >> 24; | ||
1258 | |||
1259 | reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & 0xF000) >> 12; | ||
1260 | |||
1261 | initialize = 1; | ||
1262 | } | ||
1263 | |||
1264 | if (!bforce_in_normal) { | ||
1265 | if (dm_pstable.rssi_val_min != 0) { | ||
1266 | if (dm_pstable.pre_rfstate == RF_NORMAL) { | ||
1267 | if (dm_pstable.rssi_val_min >= 30) | ||
1268 | dm_pstable.cur_rfstate = RF_SAVE; | ||
1269 | else | ||
1270 | dm_pstable.cur_rfstate = RF_NORMAL; | ||
1271 | } else { | ||
1272 | if (dm_pstable.rssi_val_min <= 25) | ||
1273 | dm_pstable.cur_rfstate = RF_NORMAL; | ||
1274 | else | ||
1275 | dm_pstable.cur_rfstate = RF_SAVE; | ||
1276 | } | ||
1277 | } else { | ||
1278 | dm_pstable.cur_rfstate = RF_MAX; | ||
1279 | } | ||
1280 | } else { | ||
1281 | dm_pstable.cur_rfstate = RF_NORMAL; | ||
1282 | } | ||
1283 | |||
1284 | if (dm_pstable.pre_rfstate != dm_pstable.cur_rfstate) { | ||
1285 | if (dm_pstable.cur_rfstate == RF_SAVE) { | ||
1286 | rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, | ||
1287 | 0x1C0000, 0x2); | ||
1288 | rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 0); | ||
1289 | rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, | ||
1290 | 0xFF000000, 0x63); | ||
1291 | rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, | ||
1292 | 0xC000, 0x2); | ||
1293 | rtl_set_bbreg(hw, 0xa74, 0xF000, 0x3); | ||
1294 | rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); | ||
1295 | rtl_set_bbreg(hw, 0x818, BIT(28), 0x1); | ||
1296 | } else { | ||
1297 | rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, | ||
1298 | 0x1CC000, reg_874); | ||
1299 | rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), | ||
1300 | reg_c70); | ||
1301 | rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000, | ||
1302 | reg_85c); | ||
1303 | rtl_set_bbreg(hw, 0xa74, 0xF000, reg_a74); | ||
1304 | rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); | ||
1305 | } | ||
1306 | |||
1307 | dm_pstable.pre_rfstate = dm_pstable.cur_rfstate; | ||
1308 | } | ||
1309 | } | ||
1310 | |||
1311 | static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw) | ||
1312 | { | ||
1313 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1314 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
1315 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1316 | |||
1317 | if (((mac->link_state == MAC80211_NOLINK)) && | ||
1318 | (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { | ||
1319 | dm_pstable.rssi_val_min = 0; | ||
1320 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, | ||
1321 | ("Not connected to any\n")); | ||
1322 | } | ||
1323 | |||
1324 | if (mac->link_state == MAC80211_LINKED) { | ||
1325 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { | ||
1326 | dm_pstable.rssi_val_min = | ||
1327 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | ||
1328 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, | ||
1329 | ("AP Client PWDB = 0x%lx\n", | ||
1330 | dm_pstable.rssi_val_min)); | ||
1331 | } else { | ||
1332 | dm_pstable.rssi_val_min = | ||
1333 | rtlpriv->dm.undecorated_smoothed_pwdb; | ||
1334 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, | ||
1335 | ("STA Default Port PWDB = 0x%lx\n", | ||
1336 | dm_pstable.rssi_val_min)); | ||
1337 | } | ||
1338 | } else { | ||
1339 | dm_pstable.rssi_val_min = | ||
1340 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | ||
1341 | |||
1342 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, | ||
1343 | ("AP Ext Port PWDB = 0x%lx\n", | ||
1344 | dm_pstable.rssi_val_min)); | ||
1345 | } | ||
1346 | |||
1347 | if (IS_92C_SERIAL(rtlhal->version)) | ||
1348 | rtl92c_dm_1r_cca(hw); | ||
1349 | } | ||
1350 | |||
1351 | void rtl92c_dm_init(struct ieee80211_hw *hw) | ||
1352 | { | ||
1353 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1354 | |||
1355 | rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; | ||
1356 | rtl92c_dm_diginit(hw); | ||
1357 | rtl92c_dm_init_dynamic_txpower(hw); | ||
1358 | rtl92c_dm_init_edca_turbo(hw); | ||
1359 | rtl92c_dm_init_rate_adaptive_mask(hw); | ||
1360 | rtl92c_dm_initialize_txpower_tracking(hw); | ||
1361 | rtl92c_dm_init_dynamic_bb_powersaving(hw); | ||
1362 | } | ||
1363 | |||
1364 | void rtl92c_dm_watchdog(struct ieee80211_hw *hw) | ||
1365 | { | ||
1366 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1367 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
1368 | bool fw_current_inpsmode = false; | ||
1369 | bool fw_ps_awake = true; | ||
1370 | |||
1371 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, | ||
1372 | (u8 *) (&fw_current_inpsmode)); | ||
1373 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, | ||
1374 | (u8 *) (&fw_ps_awake)); | ||
1375 | |||
1376 | if ((ppsc->rfpwr_state == ERFON) && ((!fw_current_inpsmode) && | ||
1377 | fw_ps_awake) | ||
1378 | && (!ppsc->rfchange_inprogress)) { | ||
1379 | rtl92c_dm_pwdb_monitor(hw); | ||
1380 | rtl92c_dm_dig(hw); | ||
1381 | rtl92c_dm_false_alarm_counter_statistics(hw); | ||
1382 | rtl92c_dm_dynamic_bb_powersaving(hw); | ||
1383 | rtl92c_dm_dynamic_txpower(hw); | ||
1384 | rtl92c_dm_check_txpower_tracking(hw); | ||
1385 | rtl92c_dm_refresh_rate_adaptive_mask(hw); | ||
1386 | rtl92c_dm_check_edca_turbo(hw); | ||
1387 | } | ||
1388 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c new file mode 100644 index 000000000000..3728abc4df59 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c | |||
@@ -0,0 +1,2049 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 Realtek Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | /* Define macro to shorten lines */ | ||
31 | #define MCS_TXPWR mcs_txpwrlevel_origoffset | ||
32 | |||
33 | static u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, | ||
34 | enum radio_path rfpath, u32 offset); | ||
35 | static void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, | ||
36 | enum radio_path rfpath, u32 offset, | ||
37 | u32 data); | ||
38 | static u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, | ||
39 | enum radio_path rfpath, u32 offset); | ||
40 | static void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, | ||
41 | enum radio_path rfpath, u32 offset, | ||
42 | u32 data); | ||
43 | static u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask); | ||
44 | static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw); | ||
45 | static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); | ||
46 | static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, | ||
47 | u8 configtype); | ||
48 | static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, | ||
49 | u8 configtype); | ||
50 | static void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw); | ||
51 | static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, | ||
52 | u32 cmdtableidx, u32 cmdtablesz, | ||
53 | enum swchnlcmd_id cmdid, u32 para1, | ||
54 | u32 para2, u32 msdelay); | ||
55 | static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, | ||
56 | u8 channel, u8 *stage, u8 *step, | ||
57 | u32 *delay); | ||
58 | static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, | ||
59 | enum wireless_mode wirelessmode, | ||
60 | long power_indbm); | ||
61 | static bool _rtl92c_phy_config_rf_external_pa(struct ieee80211_hw *hw, | ||
62 | enum radio_path rfpath); | ||
63 | static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, | ||
64 | enum wireless_mode wirelessmode, | ||
65 | u8 txpwridx); | ||
66 | static void _rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t); | ||
67 | |||
68 | u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) | ||
69 | { | ||
70 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
71 | u32 returnvalue, originalvalue, bitshift; | ||
72 | |||
73 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " | ||
74 | "bitmask(%#x)\n", regaddr, | ||
75 | bitmask)); | ||
76 | originalvalue = rtl_read_dword(rtlpriv, regaddr); | ||
77 | bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); | ||
78 | returnvalue = (originalvalue & bitmask) >> bitshift; | ||
79 | |||
80 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("BBR MASK=0x%x " | ||
81 | "Addr[0x%x]=0x%x\n", bitmask, | ||
82 | regaddr, originalvalue)); | ||
83 | |||
84 | return returnvalue; | ||
85 | |||
86 | } | ||
87 | |||
88 | void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, | ||
89 | u32 regaddr, u32 bitmask, u32 data) | ||
90 | { | ||
91 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
92 | u32 originalvalue, bitshift; | ||
93 | |||
94 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," | ||
95 | " data(%#x)\n", regaddr, bitmask, | ||
96 | data)); | ||
97 | |||
98 | if (bitmask != MASKDWORD) { | ||
99 | originalvalue = rtl_read_dword(rtlpriv, regaddr); | ||
100 | bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); | ||
101 | data = ((originalvalue & (~bitmask)) | (data << bitshift)); | ||
102 | } | ||
103 | |||
104 | rtl_write_dword(rtlpriv, regaddr, data); | ||
105 | |||
106 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," | ||
107 | " data(%#x)\n", regaddr, bitmask, | ||
108 | data)); | ||
109 | |||
110 | } | ||
111 | |||
112 | static u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, | ||
113 | enum radio_path rfpath, u32 offset) | ||
114 | { | ||
115 | RT_ASSERT(false, ("deprecated!\n")); | ||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | static void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, | ||
120 | enum radio_path rfpath, u32 offset, | ||
121 | u32 data) | ||
122 | { | ||
123 | RT_ASSERT(false, ("deprecated!\n")); | ||
124 | } | ||
125 | |||
126 | static u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, | ||
127 | enum radio_path rfpath, u32 offset) | ||
128 | { | ||
129 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
130 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
131 | struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; | ||
132 | u32 newoffset; | ||
133 | u32 tmplong, tmplong2; | ||
134 | u8 rfpi_enable = 0; | ||
135 | u32 retvalue; | ||
136 | |||
137 | offset &= 0x3f; | ||
138 | newoffset = offset; | ||
139 | if (RT_CANNOT_IO(hw)) { | ||
140 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("return all one\n")); | ||
141 | return 0xFFFFFFFF; | ||
142 | } | ||
143 | tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD); | ||
144 | if (rfpath == RF90_PATH_A) | ||
145 | tmplong2 = tmplong; | ||
146 | else | ||
147 | tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD); | ||
148 | tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) | | ||
149 | (newoffset << 23) | BLSSIREADEDGE; | ||
150 | rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, | ||
151 | tmplong & (~BLSSIREADEDGE)); | ||
152 | mdelay(1); | ||
153 | rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2); | ||
154 | mdelay(1); | ||
155 | rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, | ||
156 | tmplong | BLSSIREADEDGE); | ||
157 | mdelay(1); | ||
158 | if (rfpath == RF90_PATH_A) | ||
159 | rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, | ||
160 | BIT(8)); | ||
161 | else if (rfpath == RF90_PATH_B) | ||
162 | rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, | ||
163 | BIT(8)); | ||
164 | if (rfpi_enable) | ||
165 | retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi, | ||
166 | BLSSIREADBACKDATA); | ||
167 | else | ||
168 | retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, | ||
169 | BLSSIREADBACKDATA); | ||
170 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x]=0x%x\n", | ||
171 | rfpath, pphyreg->rflssi_readback, | ||
172 | retvalue)); | ||
173 | return retvalue; | ||
174 | } | ||
175 | |||
176 | static void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, | ||
177 | enum radio_path rfpath, u32 offset, | ||
178 | u32 data) | ||
179 | { | ||
180 | u32 data_and_addr; | ||
181 | u32 newoffset; | ||
182 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
183 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
184 | struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; | ||
185 | |||
186 | if (RT_CANNOT_IO(hw)) { | ||
187 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("stop\n")); | ||
188 | return; | ||
189 | } | ||
190 | offset &= 0x3f; | ||
191 | newoffset = offset; | ||
192 | data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; | ||
193 | rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); | ||
194 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n", | ||
195 | rfpath, pphyreg->rf3wire_offset, | ||
196 | data_and_addr)); | ||
197 | } | ||
198 | |||
199 | static u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask) | ||
200 | { | ||
201 | u32 i; | ||
202 | |||
203 | for (i = 0; i <= 31; i++) { | ||
204 | if (((bitmask >> i) & 0x1) == 1) | ||
205 | break; | ||
206 | } | ||
207 | return i; | ||
208 | } | ||
209 | |||
210 | static void _rtl92c_phy_bb_config_1t(struct ieee80211_hw *hw) | ||
211 | { | ||
212 | rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2); | ||
213 | rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022); | ||
214 | rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45); | ||
215 | rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23); | ||
216 | rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1); | ||
217 | rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2); | ||
218 | rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2); | ||
219 | rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2); | ||
220 | rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2); | ||
221 | rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2); | ||
222 | } | ||
223 | bool rtl92c_phy_rf_config(struct ieee80211_hw *hw) | ||
224 | { | ||
225 | return rtl92c_phy_rf6052_config(hw); | ||
226 | } | ||
227 | |||
228 | static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw) | ||
229 | { | ||
230 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
231 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
232 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
233 | bool rtstatus; | ||
234 | |||
235 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("==>\n")); | ||
236 | rtstatus = _rtl92c_phy_config_bb_with_headerfile(hw, | ||
237 | BASEBAND_CONFIG_PHY_REG); | ||
238 | if (rtstatus != true) { | ||
239 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Write BB Reg Fail!!")); | ||
240 | return false; | ||
241 | } | ||
242 | if (rtlphy->rf_type == RF_1T2R) { | ||
243 | _rtl92c_phy_bb_config_1t(hw); | ||
244 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Config to 1T!!\n")); | ||
245 | } | ||
246 | if (rtlefuse->autoload_failflag == false) { | ||
247 | rtlphy->pwrgroup_cnt = 0; | ||
248 | rtstatus = _rtl92c_phy_config_bb_with_pgheaderfile(hw, | ||
249 | BASEBAND_CONFIG_PHY_REG); | ||
250 | } | ||
251 | if (rtstatus != true) { | ||
252 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("BB_PG Reg Fail!!")); | ||
253 | return false; | ||
254 | } | ||
255 | rtstatus = _rtl92c_phy_config_bb_with_headerfile(hw, | ||
256 | BASEBAND_CONFIG_AGC_TAB); | ||
257 | if (rtstatus != true) { | ||
258 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("AGC Table Fail\n")); | ||
259 | return false; | ||
260 | } | ||
261 | rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw, | ||
262 | RFPGA0_XA_HSSIPARAMETER2, | ||
263 | 0x200)); | ||
264 | return true; | ||
265 | } | ||
266 | |||
267 | |||
268 | void rtl92c_phy_config_bb_external_pa(struct ieee80211_hw *hw) | ||
269 | { | ||
270 | } | ||
271 | |||
272 | static void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, | ||
273 | u32 regaddr, u32 bitmask, | ||
274 | u32 data) | ||
275 | { | ||
276 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
277 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
278 | |||
279 | if (regaddr == RTXAGC_A_RATE18_06) { | ||
280 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0] = data; | ||
281 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
282 | ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n", | ||
283 | rtlphy->pwrgroup_cnt, | ||
284 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0])); | ||
285 | } | ||
286 | if (regaddr == RTXAGC_A_RATE54_24) { | ||
287 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1] = data; | ||
288 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
289 | ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n", | ||
290 | rtlphy->pwrgroup_cnt, | ||
291 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1])); | ||
292 | } | ||
293 | if (regaddr == RTXAGC_A_CCK1_MCS32) { | ||
294 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6] = data; | ||
295 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
296 | ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n", | ||
297 | rtlphy->pwrgroup_cnt, | ||
298 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6])); | ||
299 | } | ||
300 | if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) { | ||
301 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7] = data; | ||
302 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
303 | ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n", | ||
304 | rtlphy->pwrgroup_cnt, | ||
305 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7])); | ||
306 | } | ||
307 | if (regaddr == RTXAGC_A_MCS03_MCS00) { | ||
308 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2] = data; | ||
309 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
310 | ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n", | ||
311 | rtlphy->pwrgroup_cnt, | ||
312 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2])); | ||
313 | } | ||
314 | if (regaddr == RTXAGC_A_MCS07_MCS04) { | ||
315 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3] = data; | ||
316 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
317 | ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n", | ||
318 | rtlphy->pwrgroup_cnt, | ||
319 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3])); | ||
320 | } | ||
321 | if (regaddr == RTXAGC_A_MCS11_MCS08) { | ||
322 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4] = data; | ||
323 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
324 | ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n", | ||
325 | rtlphy->pwrgroup_cnt, | ||
326 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4])); | ||
327 | } | ||
328 | if (regaddr == RTXAGC_A_MCS15_MCS12) { | ||
329 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5] = data; | ||
330 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
331 | ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n", | ||
332 | rtlphy->pwrgroup_cnt, | ||
333 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5])); | ||
334 | } | ||
335 | if (regaddr == RTXAGC_B_RATE18_06) { | ||
336 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8] = data; | ||
337 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
338 | ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n", | ||
339 | rtlphy->pwrgroup_cnt, | ||
340 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8])); | ||
341 | } | ||
342 | if (regaddr == RTXAGC_B_RATE54_24) { | ||
343 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9] = data; | ||
344 | |||
345 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
346 | ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n", | ||
347 | rtlphy->pwrgroup_cnt, | ||
348 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9])); | ||
349 | } | ||
350 | |||
351 | if (regaddr == RTXAGC_B_CCK1_55_MCS32) { | ||
352 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14] = data; | ||
353 | |||
354 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
355 | ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n", | ||
356 | rtlphy->pwrgroup_cnt, | ||
357 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14])); | ||
358 | } | ||
359 | |||
360 | if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) { | ||
361 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15] = data; | ||
362 | |||
363 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
364 | ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n", | ||
365 | rtlphy->pwrgroup_cnt, | ||
366 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15])); | ||
367 | } | ||
368 | |||
369 | if (regaddr == RTXAGC_B_MCS03_MCS00) { | ||
370 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10] = data; | ||
371 | |||
372 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
373 | ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n", | ||
374 | rtlphy->pwrgroup_cnt, | ||
375 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10])); | ||
376 | } | ||
377 | |||
378 | if (regaddr == RTXAGC_B_MCS07_MCS04) { | ||
379 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11] = data; | ||
380 | |||
381 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
382 | ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n", | ||
383 | rtlphy->pwrgroup_cnt, | ||
384 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11])); | ||
385 | } | ||
386 | |||
387 | if (regaddr == RTXAGC_B_MCS11_MCS08) { | ||
388 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12] = data; | ||
389 | |||
390 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
391 | ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n", | ||
392 | rtlphy->pwrgroup_cnt, | ||
393 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12])); | ||
394 | } | ||
395 | |||
396 | if (regaddr == RTXAGC_B_MCS15_MCS12) { | ||
397 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13] = data; | ||
398 | |||
399 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
400 | ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n", | ||
401 | rtlphy->pwrgroup_cnt, | ||
402 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13])); | ||
403 | |||
404 | rtlphy->pwrgroup_cnt++; | ||
405 | } | ||
406 | } | ||
407 | |||
408 | static bool _rtl92c_phy_config_rf_external_pa(struct ieee80211_hw *hw, | ||
409 | enum radio_path rfpath) | ||
410 | { | ||
411 | return true; | ||
412 | } | ||
413 | |||
414 | void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) | ||
415 | { | ||
416 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
417 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
418 | |||
419 | rtlphy->default_initialgain[0] = | ||
420 | (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); | ||
421 | rtlphy->default_initialgain[1] = | ||
422 | (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); | ||
423 | rtlphy->default_initialgain[2] = | ||
424 | (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0); | ||
425 | rtlphy->default_initialgain[3] = | ||
426 | (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); | ||
427 | |||
428 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
429 | ("Default initial gain (c50=0x%x, " | ||
430 | "c58=0x%x, c60=0x%x, c68=0x%x\n", | ||
431 | rtlphy->default_initialgain[0], | ||
432 | rtlphy->default_initialgain[1], | ||
433 | rtlphy->default_initialgain[2], | ||
434 | rtlphy->default_initialgain[3])); | ||
435 | |||
436 | rtlphy->framesync = (u8) rtl_get_bbreg(hw, | ||
437 | ROFDM0_RXDETECTOR3, MASKBYTE0); | ||
438 | rtlphy->framesync_c34 = rtl_get_bbreg(hw, | ||
439 | ROFDM0_RXDETECTOR2, MASKDWORD); | ||
440 | |||
441 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
442 | ("Default framesync (0x%x) = 0x%x\n", | ||
443 | ROFDM0_RXDETECTOR3, rtlphy->framesync)); | ||
444 | } | ||
445 | |||
446 | static void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) | ||
447 | { | ||
448 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
449 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
450 | |||
451 | rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; | ||
452 | rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; | ||
453 | rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW; | ||
454 | rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW; | ||
455 | |||
456 | rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB; | ||
457 | rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB; | ||
458 | rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB; | ||
459 | rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB; | ||
460 | |||
461 | rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; | ||
462 | rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; | ||
463 | |||
464 | rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; | ||
465 | rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; | ||
466 | |||
467 | rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = | ||
468 | RFPGA0_XA_LSSIPARAMETER; | ||
469 | rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = | ||
470 | RFPGA0_XB_LSSIPARAMETER; | ||
471 | |||
472 | rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = rFPGA0_XAB_RFPARAMETER; | ||
473 | rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = rFPGA0_XAB_RFPARAMETER; | ||
474 | rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = rFPGA0_XCD_RFPARAMETER; | ||
475 | rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = rFPGA0_XCD_RFPARAMETER; | ||
476 | |||
477 | rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE; | ||
478 | rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE; | ||
479 | rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE; | ||
480 | rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE; | ||
481 | |||
482 | rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1; | ||
483 | rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1; | ||
484 | |||
485 | rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; | ||
486 | rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; | ||
487 | |||
488 | rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control = | ||
489 | RFPGA0_XAB_SWITCHCONTROL; | ||
490 | rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control = | ||
491 | RFPGA0_XAB_SWITCHCONTROL; | ||
492 | rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control = | ||
493 | RFPGA0_XCD_SWITCHCONTROL; | ||
494 | rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control = | ||
495 | RFPGA0_XCD_SWITCHCONTROL; | ||
496 | |||
497 | rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; | ||
498 | rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1; | ||
499 | rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1; | ||
500 | rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1; | ||
501 | |||
502 | rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2; | ||
503 | rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2; | ||
504 | rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2; | ||
505 | rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; | ||
506 | |||
507 | rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance = | ||
508 | ROFDM0_XARXIQIMBALANCE; | ||
509 | rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance = | ||
510 | ROFDM0_XBRXIQIMBALANCE; | ||
511 | rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance = | ||
512 | ROFDM0_XCRXIQIMBANLANCE; | ||
513 | rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance = | ||
514 | ROFDM0_XDRXIQIMBALANCE; | ||
515 | |||
516 | rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; | ||
517 | rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE; | ||
518 | rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE; | ||
519 | rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; | ||
520 | |||
521 | rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance = | ||
522 | ROFDM0_XATXIQIMBALANCE; | ||
523 | rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance = | ||
524 | ROFDM0_XBTXIQIMBALANCE; | ||
525 | rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance = | ||
526 | ROFDM0_XCTXIQIMBALANCE; | ||
527 | rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance = | ||
528 | ROFDM0_XDTXIQIMBALANCE; | ||
529 | |||
530 | rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; | ||
531 | rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE; | ||
532 | rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE; | ||
533 | rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE; | ||
534 | |||
535 | rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback = | ||
536 | RFPGA0_XA_LSSIREADBACK; | ||
537 | rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback = | ||
538 | RFPGA0_XB_LSSIREADBACK; | ||
539 | rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback = | ||
540 | RFPGA0_XC_LSSIREADBACK; | ||
541 | rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback = | ||
542 | RFPGA0_XD_LSSIREADBACK; | ||
543 | |||
544 | rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi = | ||
545 | TRANSCEIVEA_HSPI_READBACK; | ||
546 | rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi = | ||
547 | TRANSCEIVEB_HSPI_READBACK; | ||
548 | |||
549 | } | ||
550 | |||
551 | void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel) | ||
552 | { | ||
553 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
554 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
555 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
556 | u8 txpwr_level; | ||
557 | long txpwr_dbm; | ||
558 | |||
559 | txpwr_level = rtlphy->cur_cck_txpwridx; | ||
560 | txpwr_dbm = _rtl92c_phy_txpwr_idx_to_dbm(hw, | ||
561 | WIRELESS_MODE_B, txpwr_level); | ||
562 | txpwr_level = rtlphy->cur_ofdm24g_txpwridx + | ||
563 | rtlefuse->legacy_ht_txpowerdiff; | ||
564 | if (_rtl92c_phy_txpwr_idx_to_dbm(hw, | ||
565 | WIRELESS_MODE_G, | ||
566 | txpwr_level) > txpwr_dbm) | ||
567 | txpwr_dbm = | ||
568 | _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, | ||
569 | txpwr_level); | ||
570 | txpwr_level = rtlphy->cur_ofdm24g_txpwridx; | ||
571 | if (_rtl92c_phy_txpwr_idx_to_dbm(hw, | ||
572 | WIRELESS_MODE_N_24G, | ||
573 | txpwr_level) > txpwr_dbm) | ||
574 | txpwr_dbm = | ||
575 | _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, | ||
576 | txpwr_level); | ||
577 | *powerlevel = txpwr_dbm; | ||
578 | } | ||
579 | |||
580 | static void _rtl92c_get_txpower_index(struct ieee80211_hw *hw, u8 channel, | ||
581 | u8 *cckpowerlevel, u8 *ofdmpowerlevel) | ||
582 | { | ||
583 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
584 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
585 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
586 | u8 index = (channel - 1); | ||
587 | |||
588 | cckpowerlevel[RF90_PATH_A] = | ||
589 | rtlefuse->txpwrlevel_cck[RF90_PATH_A][index]; | ||
590 | cckpowerlevel[RF90_PATH_B] = | ||
591 | rtlefuse->txpwrlevel_cck[RF90_PATH_B][index]; | ||
592 | if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) { | ||
593 | ofdmpowerlevel[RF90_PATH_A] = | ||
594 | rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index]; | ||
595 | ofdmpowerlevel[RF90_PATH_B] = | ||
596 | rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index]; | ||
597 | } else if (get_rf_type(rtlphy) == RF_2T2R) { | ||
598 | ofdmpowerlevel[RF90_PATH_A] = | ||
599 | rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index]; | ||
600 | ofdmpowerlevel[RF90_PATH_B] = | ||
601 | rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index]; | ||
602 | } | ||
603 | } | ||
604 | |||
605 | static void _rtl92c_ccxpower_index_check(struct ieee80211_hw *hw, | ||
606 | u8 channel, u8 *cckpowerlevel, | ||
607 | u8 *ofdmpowerlevel) | ||
608 | { | ||
609 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
610 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
611 | |||
612 | rtlphy->cur_cck_txpwridx = cckpowerlevel[0]; | ||
613 | rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0]; | ||
614 | } | ||
615 | |||
616 | void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) | ||
617 | { | ||
618 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
619 | u8 cckpowerlevel[2], ofdmpowerlevel[2]; | ||
620 | |||
621 | if (rtlefuse->txpwr_fromeprom == false) | ||
622 | return; | ||
623 | _rtl92c_get_txpower_index(hw, channel, | ||
624 | &cckpowerlevel[0], &ofdmpowerlevel[0]); | ||
625 | _rtl92c_ccxpower_index_check(hw, | ||
626 | channel, &cckpowerlevel[0], | ||
627 | &ofdmpowerlevel[0]); | ||
628 | rtl92c_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]); | ||
629 | rtl92c_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel); | ||
630 | } | ||
631 | |||
632 | bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm) | ||
633 | { | ||
634 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
635 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
636 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
637 | u8 idx; | ||
638 | u8 rf_path; | ||
639 | |||
640 | u8 ccktxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw, | ||
641 | WIRELESS_MODE_B, | ||
642 | power_indbm); | ||
643 | u8 ofdmtxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw, | ||
644 | WIRELESS_MODE_N_24G, | ||
645 | power_indbm); | ||
646 | if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0) | ||
647 | ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff; | ||
648 | else | ||
649 | ofdmtxpwridx = 0; | ||
650 | RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE, | ||
651 | ("%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n", | ||
652 | power_indbm, ccktxpwridx, ofdmtxpwridx)); | ||
653 | for (idx = 0; idx < 14; idx++) { | ||
654 | for (rf_path = 0; rf_path < 2; rf_path++) { | ||
655 | rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx; | ||
656 | rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] = | ||
657 | ofdmtxpwridx; | ||
658 | rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] = | ||
659 | ofdmtxpwridx; | ||
660 | } | ||
661 | } | ||
662 | rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); | ||
663 | return true; | ||
664 | } | ||
665 | |||
666 | void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, u16 beaconinterval) | ||
667 | { | ||
668 | } | ||
669 | |||
670 | static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, | ||
671 | enum wireless_mode wirelessmode, | ||
672 | long power_indbm) | ||
673 | { | ||
674 | u8 txpwridx; | ||
675 | long offset; | ||
676 | |||
677 | switch (wirelessmode) { | ||
678 | case WIRELESS_MODE_B: | ||
679 | offset = -7; | ||
680 | break; | ||
681 | case WIRELESS_MODE_G: | ||
682 | case WIRELESS_MODE_N_24G: | ||
683 | offset = -8; | ||
684 | break; | ||
685 | default: | ||
686 | offset = -8; | ||
687 | break; | ||
688 | } | ||
689 | |||
690 | if ((power_indbm - offset) > 0) | ||
691 | txpwridx = (u8) ((power_indbm - offset) * 2); | ||
692 | else | ||
693 | txpwridx = 0; | ||
694 | |||
695 | if (txpwridx > MAX_TXPWR_IDX_NMODE_92S) | ||
696 | txpwridx = MAX_TXPWR_IDX_NMODE_92S; | ||
697 | |||
698 | return txpwridx; | ||
699 | } | ||
700 | |||
701 | static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, | ||
702 | enum wireless_mode wirelessmode, | ||
703 | u8 txpwridx) | ||
704 | { | ||
705 | long offset; | ||
706 | long pwrout_dbm; | ||
707 | |||
708 | switch (wirelessmode) { | ||
709 | case WIRELESS_MODE_B: | ||
710 | offset = -7; | ||
711 | break; | ||
712 | case WIRELESS_MODE_G: | ||
713 | case WIRELESS_MODE_N_24G: | ||
714 | offset = -8; | ||
715 | break; | ||
716 | default: | ||
717 | offset = -8; | ||
718 | break; | ||
719 | } | ||
720 | pwrout_dbm = txpwridx / 2 + offset; | ||
721 | return pwrout_dbm; | ||
722 | } | ||
723 | |||
724 | void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) | ||
725 | { | ||
726 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
727 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
728 | enum io_type iotype; | ||
729 | |||
730 | if (!is_hal_stop(rtlhal)) { | ||
731 | switch (operation) { | ||
732 | case SCAN_OPT_BACKUP: | ||
733 | iotype = IO_CMD_PAUSE_DM_BY_SCAN; | ||
734 | rtlpriv->cfg->ops->set_hw_reg(hw, | ||
735 | HW_VAR_IO_CMD, | ||
736 | (u8 *)&iotype); | ||
737 | |||
738 | break; | ||
739 | case SCAN_OPT_RESTORE: | ||
740 | iotype = IO_CMD_RESUME_DM_BY_SCAN; | ||
741 | rtlpriv->cfg->ops->set_hw_reg(hw, | ||
742 | HW_VAR_IO_CMD, | ||
743 | (u8 *)&iotype); | ||
744 | break; | ||
745 | default: | ||
746 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
747 | ("Unknown Scan Backup operation.\n")); | ||
748 | break; | ||
749 | } | ||
750 | } | ||
751 | } | ||
752 | |||
753 | void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, | ||
754 | enum nl80211_channel_type ch_type) | ||
755 | { | ||
756 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
757 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
758 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
759 | u8 tmp_bw = rtlphy->current_chan_bw; | ||
760 | |||
761 | if (rtlphy->set_bwmode_inprogress) | ||
762 | return; | ||
763 | rtlphy->set_bwmode_inprogress = true; | ||
764 | if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) | ||
765 | rtl92c_phy_set_bw_mode_callback(hw); | ||
766 | else { | ||
767 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | ||
768 | ("FALSE driver sleep or unload\n")); | ||
769 | rtlphy->set_bwmode_inprogress = false; | ||
770 | rtlphy->current_chan_bw = tmp_bw; | ||
771 | } | ||
772 | } | ||
773 | |||
774 | void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw) | ||
775 | { | ||
776 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
777 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
778 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
779 | u32 delay; | ||
780 | |||
781 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, | ||
782 | ("switch to channel%d\n", rtlphy->current_channel)); | ||
783 | if (is_hal_stop(rtlhal)) | ||
784 | return; | ||
785 | do { | ||
786 | if (!rtlphy->sw_chnl_inprogress) | ||
787 | break; | ||
788 | if (!_rtl92c_phy_sw_chnl_step_by_step | ||
789 | (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage, | ||
790 | &rtlphy->sw_chnl_step, &delay)) { | ||
791 | if (delay > 0) | ||
792 | mdelay(delay); | ||
793 | else | ||
794 | continue; | ||
795 | } else | ||
796 | rtlphy->sw_chnl_inprogress = false; | ||
797 | break; | ||
798 | } while (true); | ||
799 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); | ||
800 | } | ||
801 | |||
802 | u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw) | ||
803 | { | ||
804 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
805 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
806 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
807 | |||
808 | if (rtlphy->sw_chnl_inprogress) | ||
809 | return 0; | ||
810 | if (rtlphy->set_bwmode_inprogress) | ||
811 | return 0; | ||
812 | RT_ASSERT((rtlphy->current_channel <= 14), | ||
813 | ("WIRELESS_MODE_G but channel>14")); | ||
814 | rtlphy->sw_chnl_inprogress = true; | ||
815 | rtlphy->sw_chnl_stage = 0; | ||
816 | rtlphy->sw_chnl_step = 0; | ||
817 | if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { | ||
818 | rtl92c_phy_sw_chnl_callback(hw); | ||
819 | RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, | ||
820 | ("sw_chnl_inprogress false schdule workitem\n")); | ||
821 | rtlphy->sw_chnl_inprogress = false; | ||
822 | } else { | ||
823 | RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, | ||
824 | ("sw_chnl_inprogress false driver sleep or" | ||
825 | " unload\n")); | ||
826 | rtlphy->sw_chnl_inprogress = false; | ||
827 | } | ||
828 | return 1; | ||
829 | } | ||
830 | |||
831 | static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, | ||
832 | u8 channel, u8 *stage, u8 *step, | ||
833 | u32 *delay) | ||
834 | { | ||
835 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
836 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
837 | struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; | ||
838 | u32 precommoncmdcnt; | ||
839 | struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; | ||
840 | u32 postcommoncmdcnt; | ||
841 | struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT]; | ||
842 | u32 rfdependcmdcnt; | ||
843 | struct swchnlcmd *currentcmd = NULL; | ||
844 | u8 rfpath; | ||
845 | u8 num_total_rfpath = rtlphy->num_total_rfpath; | ||
846 | |||
847 | precommoncmdcnt = 0; | ||
848 | _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, | ||
849 | MAX_PRECMD_CNT, | ||
850 | CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0); | ||
851 | _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, | ||
852 | MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); | ||
853 | |||
854 | postcommoncmdcnt = 0; | ||
855 | |||
856 | _rtl92c_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, | ||
857 | MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0); | ||
858 | |||
859 | rfdependcmdcnt = 0; | ||
860 | |||
861 | RT_ASSERT((channel >= 1 && channel <= 14), | ||
862 | ("illegal channel for Zebra: %d\n", channel)); | ||
863 | |||
864 | _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, | ||
865 | MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, | ||
866 | RF_CHNLBW, channel, 10); | ||
867 | |||
868 | _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, | ||
869 | MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, | ||
870 | 0); | ||
871 | |||
872 | do { | ||
873 | switch (*stage) { | ||
874 | case 0: | ||
875 | currentcmd = &precommoncmd[*step]; | ||
876 | break; | ||
877 | case 1: | ||
878 | currentcmd = &rfdependcmd[*step]; | ||
879 | break; | ||
880 | case 2: | ||
881 | currentcmd = &postcommoncmd[*step]; | ||
882 | break; | ||
883 | } | ||
884 | |||
885 | if (currentcmd->cmdid == CMDID_END) { | ||
886 | if ((*stage) == 2) { | ||
887 | return true; | ||
888 | } else { | ||
889 | (*stage)++; | ||
890 | (*step) = 0; | ||
891 | continue; | ||
892 | } | ||
893 | } | ||
894 | |||
895 | switch (currentcmd->cmdid) { | ||
896 | case CMDID_SET_TXPOWEROWER_LEVEL: | ||
897 | rtl92c_phy_set_txpower_level(hw, channel); | ||
898 | break; | ||
899 | case CMDID_WRITEPORT_ULONG: | ||
900 | rtl_write_dword(rtlpriv, currentcmd->para1, | ||
901 | currentcmd->para2); | ||
902 | break; | ||
903 | case CMDID_WRITEPORT_USHORT: | ||
904 | rtl_write_word(rtlpriv, currentcmd->para1, | ||
905 | (u16) currentcmd->para2); | ||
906 | break; | ||
907 | case CMDID_WRITEPORT_UCHAR: | ||
908 | rtl_write_byte(rtlpriv, currentcmd->para1, | ||
909 | (u8) currentcmd->para2); | ||
910 | break; | ||
911 | case CMDID_RF_WRITEREG: | ||
912 | for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { | ||
913 | rtlphy->rfreg_chnlval[rfpath] = | ||
914 | ((rtlphy->rfreg_chnlval[rfpath] & | ||
915 | 0xfffffc00) | currentcmd->para2); | ||
916 | |||
917 | rtl_set_rfreg(hw, (enum radio_path)rfpath, | ||
918 | currentcmd->para1, | ||
919 | RFREG_OFFSET_MASK, | ||
920 | rtlphy->rfreg_chnlval[rfpath]); | ||
921 | } | ||
922 | break; | ||
923 | default: | ||
924 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
925 | ("switch case not process\n")); | ||
926 | break; | ||
927 | } | ||
928 | |||
929 | break; | ||
930 | } while (true); | ||
931 | |||
932 | (*delay) = currentcmd->msdelay; | ||
933 | (*step)++; | ||
934 | return false; | ||
935 | } | ||
936 | |||
937 | static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, | ||
938 | u32 cmdtableidx, u32 cmdtablesz, | ||
939 | enum swchnlcmd_id cmdid, | ||
940 | u32 para1, u32 para2, u32 msdelay) | ||
941 | { | ||
942 | struct swchnlcmd *pcmd; | ||
943 | |||
944 | if (cmdtable == NULL) { | ||
945 | RT_ASSERT(false, ("cmdtable cannot be NULL.\n")); | ||
946 | return false; | ||
947 | } | ||
948 | |||
949 | if (cmdtableidx >= cmdtablesz) | ||
950 | return false; | ||
951 | |||
952 | pcmd = cmdtable + cmdtableidx; | ||
953 | pcmd->cmdid = cmdid; | ||
954 | pcmd->para1 = para1; | ||
955 | pcmd->para2 = para2; | ||
956 | pcmd->msdelay = msdelay; | ||
957 | return true; | ||
958 | } | ||
959 | |||
960 | bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath) | ||
961 | { | ||
962 | return true; | ||
963 | } | ||
964 | |||
965 | static u8 _rtl92c_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb) | ||
966 | { | ||
967 | u32 reg_eac, reg_e94, reg_e9c, reg_ea4; | ||
968 | u8 result = 0x00; | ||
969 | |||
970 | rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f); | ||
971 | rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f); | ||
972 | rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102); | ||
973 | rtl_set_bbreg(hw, 0xe3c, MASKDWORD, | ||
974 | config_pathb ? 0x28160202 : 0x28160502); | ||
975 | |||
976 | if (config_pathb) { | ||
977 | rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22); | ||
978 | rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22); | ||
979 | rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102); | ||
980 | rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202); | ||
981 | } | ||
982 | |||
983 | rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1); | ||
984 | rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000); | ||
985 | rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000); | ||
986 | |||
987 | mdelay(IQK_DELAY_TIME); | ||
988 | |||
989 | reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); | ||
990 | reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD); | ||
991 | reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD); | ||
992 | reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD); | ||
993 | |||
994 | if (!(reg_eac & BIT(28)) && | ||
995 | (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && | ||
996 | (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) | ||
997 | result |= 0x01; | ||
998 | else | ||
999 | return result; | ||
1000 | |||
1001 | if (!(reg_eac & BIT(27)) && | ||
1002 | (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) && | ||
1003 | (((reg_eac & 0x03FF0000) >> 16) != 0x36)) | ||
1004 | result |= 0x02; | ||
1005 | return result; | ||
1006 | } | ||
1007 | |||
1008 | static u8 _rtl92c_phy_path_b_iqk(struct ieee80211_hw *hw) | ||
1009 | { | ||
1010 | u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc; | ||
1011 | u8 result = 0x00; | ||
1012 | |||
1013 | rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002); | ||
1014 | rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000); | ||
1015 | mdelay(IQK_DELAY_TIME); | ||
1016 | reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); | ||
1017 | reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD); | ||
1018 | reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD); | ||
1019 | reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD); | ||
1020 | reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD); | ||
1021 | if (!(reg_eac & BIT(31)) && | ||
1022 | (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) && | ||
1023 | (((reg_ebc & 0x03FF0000) >> 16) != 0x42)) | ||
1024 | result |= 0x01; | ||
1025 | else | ||
1026 | return result; | ||
1027 | |||
1028 | if (!(reg_eac & BIT(30)) && | ||
1029 | (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) && | ||
1030 | (((reg_ecc & 0x03FF0000) >> 16) != 0x36)) | ||
1031 | result |= 0x02; | ||
1032 | return result; | ||
1033 | } | ||
1034 | |||
1035 | static void _rtl92c_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw, | ||
1036 | bool iqk_ok, long result[][8], | ||
1037 | u8 final_candidate, bool btxonly) | ||
1038 | { | ||
1039 | u32 oldval_0, x, tx0_a, reg; | ||
1040 | long y, tx0_c; | ||
1041 | |||
1042 | if (final_candidate == 0xFF) | ||
1043 | return; | ||
1044 | else if (iqk_ok) { | ||
1045 | oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, | ||
1046 | MASKDWORD) >> 22) & 0x3FF; | ||
1047 | x = result[final_candidate][0]; | ||
1048 | if ((x & 0x00000200) != 0) | ||
1049 | x = x | 0xFFFFFC00; | ||
1050 | tx0_a = (x * oldval_0) >> 8; | ||
1051 | rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a); | ||
1052 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31), | ||
1053 | ((x * oldval_0 >> 7) & 0x1)); | ||
1054 | y = result[final_candidate][1]; | ||
1055 | if ((y & 0x00000200) != 0) | ||
1056 | y = y | 0xFFFFFC00; | ||
1057 | tx0_c = (y * oldval_0) >> 8; | ||
1058 | rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000, | ||
1059 | ((tx0_c & 0x3C0) >> 6)); | ||
1060 | rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000, | ||
1061 | (tx0_c & 0x3F)); | ||
1062 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29), | ||
1063 | ((y * oldval_0 >> 7) & 0x1)); | ||
1064 | if (btxonly) | ||
1065 | return; | ||
1066 | reg = result[final_candidate][2]; | ||
1067 | rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg); | ||
1068 | reg = result[final_candidate][3] & 0x3F; | ||
1069 | rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg); | ||
1070 | reg = (result[final_candidate][3] >> 6) & 0xF; | ||
1071 | rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); | ||
1072 | } | ||
1073 | } | ||
1074 | |||
1075 | static void _rtl92c_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw, | ||
1076 | bool iqk_ok, long result[][8], | ||
1077 | u8 final_candidate, bool btxonly) | ||
1078 | { | ||
1079 | u32 oldval_1, x, tx1_a, reg; | ||
1080 | long y, tx1_c; | ||
1081 | |||
1082 | if (final_candidate == 0xFF) | ||
1083 | return; | ||
1084 | else if (iqk_ok) { | ||
1085 | oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, | ||
1086 | MASKDWORD) >> 22) & 0x3FF; | ||
1087 | x = result[final_candidate][4]; | ||
1088 | if ((x & 0x00000200) != 0) | ||
1089 | x = x | 0xFFFFFC00; | ||
1090 | tx1_a = (x * oldval_1) >> 8; | ||
1091 | rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a); | ||
1092 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27), | ||
1093 | ((x * oldval_1 >> 7) & 0x1)); | ||
1094 | y = result[final_candidate][5]; | ||
1095 | if ((y & 0x00000200) != 0) | ||
1096 | y = y | 0xFFFFFC00; | ||
1097 | tx1_c = (y * oldval_1) >> 8; | ||
1098 | rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000, | ||
1099 | ((tx1_c & 0x3C0) >> 6)); | ||
1100 | rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000, | ||
1101 | (tx1_c & 0x3F)); | ||
1102 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25), | ||
1103 | ((y * oldval_1 >> 7) & 0x1)); | ||
1104 | if (btxonly) | ||
1105 | return; | ||
1106 | reg = result[final_candidate][6]; | ||
1107 | rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg); | ||
1108 | reg = result[final_candidate][7] & 0x3F; | ||
1109 | rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg); | ||
1110 | reg = (result[final_candidate][7] >> 6) & 0xF; | ||
1111 | rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, reg); | ||
1112 | } | ||
1113 | } | ||
1114 | |||
1115 | static void _rtl92c_phy_save_adda_registers(struct ieee80211_hw *hw, | ||
1116 | u32 *addareg, u32 *addabackup, | ||
1117 | u32 registernum) | ||
1118 | { | ||
1119 | u32 i; | ||
1120 | |||
1121 | for (i = 0; i < registernum; i++) | ||
1122 | addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD); | ||
1123 | } | ||
1124 | |||
1125 | static void _rtl92c_phy_save_mac_registers(struct ieee80211_hw *hw, | ||
1126 | u32 *macreg, u32 *macbackup) | ||
1127 | { | ||
1128 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1129 | u32 i; | ||
1130 | |||
1131 | for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) | ||
1132 | macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]); | ||
1133 | macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]); | ||
1134 | } | ||
1135 | |||
1136 | static void _rtl92c_phy_reload_adda_registers(struct ieee80211_hw *hw, | ||
1137 | u32 *addareg, u32 *addabackup, | ||
1138 | u32 regiesternum) | ||
1139 | { | ||
1140 | u32 i; | ||
1141 | |||
1142 | for (i = 0; i < regiesternum; i++) | ||
1143 | rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]); | ||
1144 | } | ||
1145 | |||
1146 | static void _rtl92c_phy_reload_mac_registers(struct ieee80211_hw *hw, | ||
1147 | u32 *macreg, u32 *macbackup) | ||
1148 | { | ||
1149 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1150 | u32 i; | ||
1151 | |||
1152 | for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) | ||
1153 | rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]); | ||
1154 | rtl_write_dword(rtlpriv, macreg[i], macbackup[i]); | ||
1155 | } | ||
1156 | |||
1157 | static void _rtl92c_phy_path_adda_on(struct ieee80211_hw *hw, | ||
1158 | u32 *addareg, bool is_patha_on, bool is2t) | ||
1159 | { | ||
1160 | u32 pathOn; | ||
1161 | u32 i; | ||
1162 | |||
1163 | pathOn = is_patha_on ? 0x04db25a4 : 0x0b1b25a4; | ||
1164 | if (false == is2t) { | ||
1165 | pathOn = 0x0bdb25a0; | ||
1166 | rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0); | ||
1167 | } else { | ||
1168 | rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathOn); | ||
1169 | } | ||
1170 | |||
1171 | for (i = 1; i < IQK_ADDA_REG_NUM; i++) | ||
1172 | rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathOn); | ||
1173 | } | ||
1174 | |||
1175 | static void _rtl92c_phy_mac_setting_calibration(struct ieee80211_hw *hw, | ||
1176 | u32 *macreg, u32 *macbackup) | ||
1177 | { | ||
1178 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1179 | u32 i; | ||
1180 | |||
1181 | rtl_write_byte(rtlpriv, macreg[0], 0x3F); | ||
1182 | |||
1183 | for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) | ||
1184 | rtl_write_byte(rtlpriv, macreg[i], | ||
1185 | (u8) (macbackup[i] & (~BIT(3)))); | ||
1186 | rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5)))); | ||
1187 | } | ||
1188 | |||
1189 | static void _rtl92c_phy_path_a_standby(struct ieee80211_hw *hw) | ||
1190 | { | ||
1191 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0); | ||
1192 | rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); | ||
1193 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); | ||
1194 | } | ||
1195 | |||
1196 | static void _rtl92c_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode) | ||
1197 | { | ||
1198 | u32 mode; | ||
1199 | |||
1200 | mode = pi_mode ? 0x01000100 : 0x01000000; | ||
1201 | rtl_set_bbreg(hw, 0x820, MASKDWORD, mode); | ||
1202 | rtl_set_bbreg(hw, 0x828, MASKDWORD, mode); | ||
1203 | } | ||
1204 | |||
1205 | static bool _rtl92c_phy_simularity_compare(struct ieee80211_hw *hw, | ||
1206 | long result[][8], u8 c1, u8 c2) | ||
1207 | { | ||
1208 | u32 i, j, diff, simularity_bitmap, bound; | ||
1209 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1210 | |||
1211 | u8 final_candidate[2] = { 0xFF, 0xFF }; | ||
1212 | bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version); | ||
1213 | |||
1214 | if (is2t) | ||
1215 | bound = 8; | ||
1216 | else | ||
1217 | bound = 4; | ||
1218 | |||
1219 | simularity_bitmap = 0; | ||
1220 | |||
1221 | for (i = 0; i < bound; i++) { | ||
1222 | diff = (result[c1][i] > result[c2][i]) ? | ||
1223 | (result[c1][i] - result[c2][i]) : | ||
1224 | (result[c2][i] - result[c1][i]); | ||
1225 | |||
1226 | if (diff > MAX_TOLERANCE) { | ||
1227 | if ((i == 2 || i == 6) && !simularity_bitmap) { | ||
1228 | if (result[c1][i] + result[c1][i + 1] == 0) | ||
1229 | final_candidate[(i / 4)] = c2; | ||
1230 | else if (result[c2][i] + result[c2][i + 1] == 0) | ||
1231 | final_candidate[(i / 4)] = c1; | ||
1232 | else | ||
1233 | simularity_bitmap = simularity_bitmap | | ||
1234 | (1 << i); | ||
1235 | } else | ||
1236 | simularity_bitmap = | ||
1237 | simularity_bitmap | (1 << i); | ||
1238 | } | ||
1239 | } | ||
1240 | |||
1241 | if (simularity_bitmap == 0) { | ||
1242 | for (i = 0; i < (bound / 4); i++) { | ||
1243 | if (final_candidate[i] != 0xFF) { | ||
1244 | for (j = i * 4; j < (i + 1) * 4 - 2; j++) | ||
1245 | result[3][j] = | ||
1246 | result[final_candidate[i]][j]; | ||
1247 | bresult = false; | ||
1248 | } | ||
1249 | } | ||
1250 | return bresult; | ||
1251 | } else if (!(simularity_bitmap & 0x0F)) { | ||
1252 | for (i = 0; i < 4; i++) | ||
1253 | result[3][i] = result[c1][i]; | ||
1254 | return false; | ||
1255 | } else if (!(simularity_bitmap & 0xF0) && is2t) { | ||
1256 | for (i = 4; i < 8; i++) | ||
1257 | result[3][i] = result[c1][i]; | ||
1258 | return false; | ||
1259 | } else { | ||
1260 | return false; | ||
1261 | } | ||
1262 | |||
1263 | } | ||
1264 | |||
1265 | static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, | ||
1266 | long result[][8], u8 t, bool is2t) | ||
1267 | { | ||
1268 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1269 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1270 | u32 i; | ||
1271 | u8 patha_ok, pathb_ok; | ||
1272 | u32 adda_reg[IQK_ADDA_REG_NUM] = { | ||
1273 | 0x85c, 0xe6c, 0xe70, 0xe74, | ||
1274 | 0xe78, 0xe7c, 0xe80, 0xe84, | ||
1275 | 0xe88, 0xe8c, 0xed0, 0xed4, | ||
1276 | 0xed8, 0xedc, 0xee0, 0xeec | ||
1277 | }; | ||
1278 | |||
1279 | u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { | ||
1280 | 0x522, 0x550, 0x551, 0x040 | ||
1281 | }; | ||
1282 | |||
1283 | const u32 retrycount = 2; | ||
1284 | |||
1285 | u32 bbvalue; | ||
1286 | |||
1287 | if (t == 0) { | ||
1288 | bbvalue = rtl_get_bbreg(hw, 0x800, MASKDWORD); | ||
1289 | |||
1290 | _rtl92c_phy_save_adda_registers(hw, adda_reg, | ||
1291 | rtlphy->adda_backup, 16); | ||
1292 | _rtl92c_phy_save_mac_registers(hw, iqk_mac_reg, | ||
1293 | rtlphy->iqk_mac_backup); | ||
1294 | } | ||
1295 | _rtl92c_phy_path_adda_on(hw, adda_reg, true, is2t); | ||
1296 | if (t == 0) { | ||
1297 | rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw, | ||
1298 | RFPGA0_XA_HSSIPARAMETER1, | ||
1299 | BIT(8)); | ||
1300 | } | ||
1301 | if (!rtlphy->rfpi_enable) | ||
1302 | _rtl92c_phy_pi_mode_switch(hw, true); | ||
1303 | if (t == 0) { | ||
1304 | rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD); | ||
1305 | rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD); | ||
1306 | rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD); | ||
1307 | } | ||
1308 | rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600); | ||
1309 | rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4); | ||
1310 | rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000); | ||
1311 | if (is2t) { | ||
1312 | rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); | ||
1313 | rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000); | ||
1314 | } | ||
1315 | _rtl92c_phy_mac_setting_calibration(hw, iqk_mac_reg, | ||
1316 | rtlphy->iqk_mac_backup); | ||
1317 | rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000); | ||
1318 | if (is2t) | ||
1319 | rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000); | ||
1320 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); | ||
1321 | rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00); | ||
1322 | rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800); | ||
1323 | for (i = 0; i < retrycount; i++) { | ||
1324 | patha_ok = _rtl92c_phy_path_a_iqk(hw, is2t); | ||
1325 | if (patha_ok == 0x03) { | ||
1326 | result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) & | ||
1327 | 0x3FF0000) >> 16; | ||
1328 | result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & | ||
1329 | 0x3FF0000) >> 16; | ||
1330 | result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) & | ||
1331 | 0x3FF0000) >> 16; | ||
1332 | result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) & | ||
1333 | 0x3FF0000) >> 16; | ||
1334 | break; | ||
1335 | } else if (i == (retrycount - 1) && patha_ok == 0x01) | ||
1336 | result[t][0] = (rtl_get_bbreg(hw, 0xe94, | ||
1337 | MASKDWORD) & 0x3FF0000) >> | ||
1338 | 16; | ||
1339 | result[t][1] = | ||
1340 | (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16; | ||
1341 | |||
1342 | } | ||
1343 | |||
1344 | if (is2t) { | ||
1345 | _rtl92c_phy_path_a_standby(hw); | ||
1346 | _rtl92c_phy_path_adda_on(hw, adda_reg, false, is2t); | ||
1347 | for (i = 0; i < retrycount; i++) { | ||
1348 | pathb_ok = _rtl92c_phy_path_b_iqk(hw); | ||
1349 | if (pathb_ok == 0x03) { | ||
1350 | result[t][4] = (rtl_get_bbreg(hw, | ||
1351 | 0xeb4, | ||
1352 | MASKDWORD) & | ||
1353 | 0x3FF0000) >> 16; | ||
1354 | result[t][5] = | ||
1355 | (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & | ||
1356 | 0x3FF0000) >> 16; | ||
1357 | result[t][6] = | ||
1358 | (rtl_get_bbreg(hw, 0xec4, MASKDWORD) & | ||
1359 | 0x3FF0000) >> 16; | ||
1360 | result[t][7] = | ||
1361 | (rtl_get_bbreg(hw, 0xecc, MASKDWORD) & | ||
1362 | 0x3FF0000) >> 16; | ||
1363 | break; | ||
1364 | } else if (i == (retrycount - 1) && pathb_ok == 0x01) { | ||
1365 | result[t][4] = (rtl_get_bbreg(hw, | ||
1366 | 0xeb4, | ||
1367 | MASKDWORD) & | ||
1368 | 0x3FF0000) >> 16; | ||
1369 | } | ||
1370 | result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & | ||
1371 | 0x3FF0000) >> 16; | ||
1372 | } | ||
1373 | } | ||
1374 | rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04); | ||
1375 | rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874); | ||
1376 | rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08); | ||
1377 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0); | ||
1378 | rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3); | ||
1379 | if (is2t) | ||
1380 | rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3); | ||
1381 | if (t != 0) { | ||
1382 | if (!rtlphy->rfpi_enable) | ||
1383 | _rtl92c_phy_pi_mode_switch(hw, false); | ||
1384 | _rtl92c_phy_reload_adda_registers(hw, adda_reg, | ||
1385 | rtlphy->adda_backup, 16); | ||
1386 | _rtl92c_phy_reload_mac_registers(hw, iqk_mac_reg, | ||
1387 | rtlphy->iqk_mac_backup); | ||
1388 | } | ||
1389 | } | ||
1390 | |||
1391 | static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, | ||
1392 | char delta, bool is2t) | ||
1393 | { | ||
1394 | /* This routine is deliberately dummied out for later fixes */ | ||
1395 | #if 0 | ||
1396 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1397 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1398 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
1399 | |||
1400 | u32 reg_d[PATH_NUM]; | ||
1401 | u32 tmpreg, index, offset, path, i, pathbound = PATH_NUM, apkbound; | ||
1402 | |||
1403 | u32 bb_backup[APK_BB_REG_NUM]; | ||
1404 | u32 bb_reg[APK_BB_REG_NUM] = { | ||
1405 | 0x904, 0xc04, 0x800, 0xc08, 0x874 | ||
1406 | }; | ||
1407 | u32 bb_ap_mode[APK_BB_REG_NUM] = { | ||
1408 | 0x00000020, 0x00a05430, 0x02040000, | ||
1409 | 0x000800e4, 0x00204000 | ||
1410 | }; | ||
1411 | u32 bb_normal_ap_mode[APK_BB_REG_NUM] = { | ||
1412 | 0x00000020, 0x00a05430, 0x02040000, | ||
1413 | 0x000800e4, 0x22204000 | ||
1414 | }; | ||
1415 | |||
1416 | u32 afe_backup[APK_AFE_REG_NUM]; | ||
1417 | u32 afe_reg[APK_AFE_REG_NUM] = { | ||
1418 | 0x85c, 0xe6c, 0xe70, 0xe74, 0xe78, | ||
1419 | 0xe7c, 0xe80, 0xe84, 0xe88, 0xe8c, | ||
1420 | 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, | ||
1421 | 0xeec | ||
1422 | }; | ||
1423 | |||
1424 | u32 mac_backup[IQK_MAC_REG_NUM]; | ||
1425 | u32 mac_reg[IQK_MAC_REG_NUM] = { | ||
1426 | 0x522, 0x550, 0x551, 0x040 | ||
1427 | }; | ||
1428 | |||
1429 | u32 apk_rf_init_value[PATH_NUM][APK_BB_REG_NUM] = { | ||
1430 | {0x0852c, 0x1852c, 0x5852c, 0x1852c, 0x5852c}, | ||
1431 | {0x2852e, 0x0852e, 0x3852e, 0x0852e, 0x0852e} | ||
1432 | }; | ||
1433 | |||
1434 | u32 apk_normal_rf_init_value[PATH_NUM][APK_BB_REG_NUM] = { | ||
1435 | {0x0852c, 0x0a52c, 0x3a52c, 0x5a52c, 0x5a52c}, | ||
1436 | {0x0852c, 0x0a52c, 0x5a52c, 0x5a52c, 0x5a52c} | ||
1437 | }; | ||
1438 | |||
1439 | u32 apk_rf_value_0[PATH_NUM][APK_BB_REG_NUM] = { | ||
1440 | {0x52019, 0x52014, 0x52013, 0x5200f, 0x5208d}, | ||
1441 | {0x5201a, 0x52019, 0x52016, 0x52033, 0x52050} | ||
1442 | }; | ||
1443 | |||
1444 | u32 apk_normal_rf_value_0[PATH_NUM][APK_BB_REG_NUM] = { | ||
1445 | {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a}, | ||
1446 | {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a} | ||
1447 | }; | ||
1448 | |||
1449 | u32 afe_on_off[PATH_NUM] = { | ||
1450 | 0x04db25a4, 0x0b1b25a4 | ||
1451 | }; | ||
1452 | |||
1453 | u32 apk_offset[PATH_NUM] = { 0xb68, 0xb6c }; | ||
1454 | |||
1455 | u32 apk_normal_offset[PATH_NUM] = { 0xb28, 0xb98 }; | ||
1456 | |||
1457 | u32 apk_value[PATH_NUM] = { 0x92fc0000, 0x12fc0000 }; | ||
1458 | |||
1459 | u32 apk_normal_value[PATH_NUM] = { 0x92680000, 0x12680000 }; | ||
1460 | |||
1461 | const char apk_delta_mapping[APK_BB_REG_NUM][13] = { | ||
1462 | {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, | ||
1463 | {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, | ||
1464 | {-6, -4, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, | ||
1465 | {-1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6}, | ||
1466 | {-11, -9, -7, -5, -3, -1, 0, 0, 0, 0, 0, 0, 0} | ||
1467 | }; | ||
1468 | |||
1469 | const u32 apk_normal_setting_value_1[13] = { | ||
1470 | 0x01017018, 0xf7ed8f84, 0x1b1a1816, 0x2522201e, 0x322e2b28, | ||
1471 | 0x433f3a36, 0x5b544e49, 0x7b726a62, 0xa69a8f84, 0xdfcfc0b3, | ||
1472 | 0x12680000, 0x00880000, 0x00880000 | ||
1473 | }; | ||
1474 | |||
1475 | const u32 apk_normal_setting_value_2[16] = { | ||
1476 | 0x01c7021d, 0x01670183, 0x01000123, 0x00bf00e2, 0x008d00a3, | ||
1477 | 0x0068007b, 0x004d0059, 0x003a0042, 0x002b0031, 0x001f0025, | ||
1478 | 0x0017001b, 0x00110014, 0x000c000f, 0x0009000b, 0x00070008, | ||
1479 | 0x00050006 | ||
1480 | }; | ||
1481 | |||
1482 | const u32 apk_result[PATH_NUM][APK_BB_REG_NUM]; | ||
1483 | |||
1484 | long bb_offset, delta_v, delta_offset; | ||
1485 | |||
1486 | if (!is2t) | ||
1487 | pathbound = 1; | ||
1488 | |||
1489 | for (index = 0; index < PATH_NUM; index++) { | ||
1490 | apk_offset[index] = apk_normal_offset[index]; | ||
1491 | apk_value[index] = apk_normal_value[index]; | ||
1492 | afe_on_off[index] = 0x6fdb25a4; | ||
1493 | } | ||
1494 | |||
1495 | for (index = 0; index < APK_BB_REG_NUM; index++) { | ||
1496 | for (path = 0; path < pathbound; path++) { | ||
1497 | apk_rf_init_value[path][index] = | ||
1498 | apk_normal_rf_init_value[path][index]; | ||
1499 | apk_rf_value_0[path][index] = | ||
1500 | apk_normal_rf_value_0[path][index]; | ||
1501 | } | ||
1502 | bb_ap_mode[index] = bb_normal_ap_mode[index]; | ||
1503 | |||
1504 | apkbound = 6; | ||
1505 | } | ||
1506 | |||
1507 | for (index = 0; index < APK_BB_REG_NUM; index++) { | ||
1508 | if (index == 0) | ||
1509 | continue; | ||
1510 | bb_backup[index] = rtl_get_bbreg(hw, bb_reg[index], MASKDWORD); | ||
1511 | } | ||
1512 | |||
1513 | _rtl92c_phy_save_mac_registers(hw, mac_reg, mac_backup); | ||
1514 | |||
1515 | _rtl92c_phy_save_adda_registers(hw, afe_reg, afe_backup, 16); | ||
1516 | |||
1517 | for (path = 0; path < pathbound; path++) { | ||
1518 | if (path == RF90_PATH_A) { | ||
1519 | offset = 0xb00; | ||
1520 | for (index = 0; index < 11; index++) { | ||
1521 | rtl_set_bbreg(hw, offset, MASKDWORD, | ||
1522 | apk_normal_setting_value_1 | ||
1523 | [index]); | ||
1524 | |||
1525 | offset += 0x04; | ||
1526 | } | ||
1527 | |||
1528 | rtl_set_bbreg(hw, 0xb98, MASKDWORD, 0x12680000); | ||
1529 | |||
1530 | offset = 0xb68; | ||
1531 | for (; index < 13; index++) { | ||
1532 | rtl_set_bbreg(hw, offset, MASKDWORD, | ||
1533 | apk_normal_setting_value_1 | ||
1534 | [index]); | ||
1535 | |||
1536 | offset += 0x04; | ||
1537 | } | ||
1538 | |||
1539 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x40000000); | ||
1540 | |||
1541 | offset = 0xb00; | ||
1542 | for (index = 0; index < 16; index++) { | ||
1543 | rtl_set_bbreg(hw, offset, MASKDWORD, | ||
1544 | apk_normal_setting_value_2 | ||
1545 | [index]); | ||
1546 | |||
1547 | offset += 0x04; | ||
1548 | } | ||
1549 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); | ||
1550 | } else if (path == RF90_PATH_B) { | ||
1551 | offset = 0xb70; | ||
1552 | for (index = 0; index < 10; index++) { | ||
1553 | rtl_set_bbreg(hw, offset, MASKDWORD, | ||
1554 | apk_normal_setting_value_1 | ||
1555 | [index]); | ||
1556 | |||
1557 | offset += 0x04; | ||
1558 | } | ||
1559 | rtl_set_bbreg(hw, 0xb28, MASKDWORD, 0x12680000); | ||
1560 | rtl_set_bbreg(hw, 0xb98, MASKDWORD, 0x12680000); | ||
1561 | |||
1562 | offset = 0xb68; | ||
1563 | index = 11; | ||
1564 | for (; index < 13; index++) { | ||
1565 | rtl_set_bbreg(hw, offset, MASKDWORD, | ||
1566 | apk_normal_setting_value_1 | ||
1567 | [index]); | ||
1568 | |||
1569 | offset += 0x04; | ||
1570 | } | ||
1571 | |||
1572 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x40000000); | ||
1573 | |||
1574 | offset = 0xb60; | ||
1575 | for (index = 0; index < 16; index++) { | ||
1576 | rtl_set_bbreg(hw, offset, MASKDWORD, | ||
1577 | apk_normal_setting_value_2 | ||
1578 | [index]); | ||
1579 | |||
1580 | offset += 0x04; | ||
1581 | } | ||
1582 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); | ||
1583 | } | ||
1584 | |||
1585 | reg_d[path] = rtl_get_rfreg(hw, (enum radio_path)path, | ||
1586 | 0xd, MASKDWORD); | ||
1587 | |||
1588 | for (index = 0; index < APK_AFE_REG_NUM; index++) | ||
1589 | rtl_set_bbreg(hw, afe_reg[index], MASKDWORD, | ||
1590 | afe_on_off[path]); | ||
1591 | |||
1592 | if (path == RF90_PATH_A) { | ||
1593 | for (index = 0; index < APK_BB_REG_NUM; index++) { | ||
1594 | if (index == 0) | ||
1595 | continue; | ||
1596 | rtl_set_bbreg(hw, bb_reg[index], MASKDWORD, | ||
1597 | bb_ap_mode[index]); | ||
1598 | } | ||
1599 | } | ||
1600 | |||
1601 | _rtl92c_phy_mac_setting_calibration(hw, mac_reg, mac_backup); | ||
1602 | |||
1603 | if (path == 0) { | ||
1604 | rtl_set_rfreg(hw, RF90_PATH_B, 0x0, MASKDWORD, 0x10000); | ||
1605 | } else { | ||
1606 | rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASKDWORD, | ||
1607 | 0x10000); | ||
1608 | rtl_set_rfreg(hw, RF90_PATH_A, 0x10, MASKDWORD, | ||
1609 | 0x1000f); | ||
1610 | rtl_set_rfreg(hw, RF90_PATH_A, 0x11, MASKDWORD, | ||
1611 | 0x20103); | ||
1612 | } | ||
1613 | |||
1614 | delta_offset = ((delta + 14) / 2); | ||
1615 | if (delta_offset < 0) | ||
1616 | delta_offset = 0; | ||
1617 | else if (delta_offset > 12) | ||
1618 | delta_offset = 12; | ||
1619 | |||
1620 | for (index = 0; index < APK_BB_REG_NUM; index++) { | ||
1621 | if (index != 1) | ||
1622 | continue; | ||
1623 | |||
1624 | tmpreg = apk_rf_init_value[path][index]; | ||
1625 | |||
1626 | if (!rtlefuse->apk_thermalmeterignore) { | ||
1627 | bb_offset = (tmpreg & 0xF0000) >> 16; | ||
1628 | |||
1629 | if (!(tmpreg & BIT(15))) | ||
1630 | bb_offset = -bb_offset; | ||
1631 | |||
1632 | delta_v = | ||
1633 | apk_delta_mapping[index][delta_offset]; | ||
1634 | |||
1635 | bb_offset += delta_v; | ||
1636 | |||
1637 | if (bb_offset < 0) { | ||
1638 | tmpreg = tmpreg & (~BIT(15)); | ||
1639 | bb_offset = -bb_offset; | ||
1640 | } else { | ||
1641 | tmpreg = tmpreg | BIT(15); | ||
1642 | } | ||
1643 | |||
1644 | tmpreg = | ||
1645 | (tmpreg & 0xFFF0FFFF) | (bb_offset << 16); | ||
1646 | } | ||
1647 | |||
1648 | rtl_set_rfreg(hw, (enum radio_path)path, 0xc, | ||
1649 | MASKDWORD, 0x8992e); | ||
1650 | rtl_set_rfreg(hw, (enum radio_path)path, 0x0, | ||
1651 | MASKDWORD, apk_rf_value_0[path][index]); | ||
1652 | rtl_set_rfreg(hw, (enum radio_path)path, 0xd, | ||
1653 | MASKDWORD, tmpreg); | ||
1654 | |||
1655 | i = 0; | ||
1656 | do { | ||
1657 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80000000); | ||
1658 | rtl_set_bbreg(hw, apk_offset[path], | ||
1659 | MASKDWORD, apk_value[0]); | ||
1660 | RTPRINT(rtlpriv, FINIT, INIT_IQK, | ||
1661 | ("PHY_APCalibrate() offset 0x%x " | ||
1662 | "value 0x%x\n", | ||
1663 | apk_offset[path], | ||
1664 | rtl_get_bbreg(hw, apk_offset[path], | ||
1665 | MASKDWORD))); | ||
1666 | |||
1667 | mdelay(3); | ||
1668 | |||
1669 | rtl_set_bbreg(hw, apk_offset[path], | ||
1670 | MASKDWORD, apk_value[1]); | ||
1671 | RTPRINT(rtlpriv, FINIT, INIT_IQK, | ||
1672 | ("PHY_APCalibrate() offset 0x%x " | ||
1673 | "value 0x%x\n", | ||
1674 | apk_offset[path], | ||
1675 | rtl_get_bbreg(hw, apk_offset[path], | ||
1676 | MASKDWORD))); | ||
1677 | |||
1678 | mdelay(20); | ||
1679 | |||
1680 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); | ||
1681 | |||
1682 | if (path == RF90_PATH_A) | ||
1683 | tmpreg = rtl_get_bbreg(hw, 0xbd8, | ||
1684 | 0x03E00000); | ||
1685 | else | ||
1686 | tmpreg = rtl_get_bbreg(hw, 0xbd8, | ||
1687 | 0xF8000000); | ||
1688 | |||
1689 | RTPRINT(rtlpriv, FINIT, INIT_IQK, | ||
1690 | ("PHY_APCalibrate() offset " | ||
1691 | "0xbd8[25:21] %x\n", tmpreg)); | ||
1692 | |||
1693 | i++; | ||
1694 | |||
1695 | } while (tmpreg > apkbound && i < 4); | ||
1696 | |||
1697 | apk_result[path][index] = tmpreg; | ||
1698 | } | ||
1699 | } | ||
1700 | |||
1701 | _rtl92c_phy_reload_mac_registers(hw, mac_reg, mac_backup); | ||
1702 | |||
1703 | for (index = 0; index < APK_BB_REG_NUM; index++) { | ||
1704 | if (index == 0) | ||
1705 | continue; | ||
1706 | rtl_set_bbreg(hw, bb_reg[index], MASKDWORD, bb_backup[index]); | ||
1707 | } | ||
1708 | |||
1709 | _rtl92c_phy_reload_adda_registers(hw, afe_reg, afe_backup, 16); | ||
1710 | |||
1711 | for (path = 0; path < pathbound; path++) { | ||
1712 | rtl_set_rfreg(hw, (enum radio_path)path, 0xd, | ||
1713 | MASKDWORD, reg_d[path]); | ||
1714 | |||
1715 | if (path == RF90_PATH_B) { | ||
1716 | rtl_set_rfreg(hw, RF90_PATH_A, 0x10, MASKDWORD, | ||
1717 | 0x1000f); | ||
1718 | rtl_set_rfreg(hw, RF90_PATH_A, 0x11, MASKDWORD, | ||
1719 | 0x20101); | ||
1720 | } | ||
1721 | |||
1722 | if (apk_result[path][1] > 6) | ||
1723 | apk_result[path][1] = 6; | ||
1724 | } | ||
1725 | |||
1726 | for (path = 0; path < pathbound; path++) { | ||
1727 | rtl_set_rfreg(hw, (enum radio_path)path, 0x3, MASKDWORD, | ||
1728 | ((apk_result[path][1] << 15) | | ||
1729 | (apk_result[path][1] << 10) | | ||
1730 | (apk_result[path][1] << 5) | | ||
1731 | apk_result[path][1])); | ||
1732 | |||
1733 | if (path == RF90_PATH_A) | ||
1734 | rtl_set_rfreg(hw, (enum radio_path)path, 0x4, MASKDWORD, | ||
1735 | ((apk_result[path][1] << 15) | | ||
1736 | (apk_result[path][1] << 10) | | ||
1737 | (0x00 << 5) | 0x05)); | ||
1738 | else | ||
1739 | rtl_set_rfreg(hw, (enum radio_path)path, 0x4, MASKDWORD, | ||
1740 | ((apk_result[path][1] << 15) | | ||
1741 | (apk_result[path][1] << 10) | | ||
1742 | (0x02 << 5) | 0x05)); | ||
1743 | |||
1744 | rtl_set_rfreg(hw, (enum radio_path)path, 0xe, MASKDWORD, | ||
1745 | ((0x08 << 15) | (0x08 << 10) | (0x08 << 5) | | ||
1746 | 0x08)); | ||
1747 | |||
1748 | } | ||
1749 | |||
1750 | rtlphy->apk_done = true; | ||
1751 | #endif | ||
1752 | } | ||
1753 | |||
1754 | static void _rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, | ||
1755 | bool bmain, bool is2t) | ||
1756 | { | ||
1757 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1758 | |||
1759 | if (is_hal_stop(rtlhal)) { | ||
1760 | rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01); | ||
1761 | rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01); | ||
1762 | } | ||
1763 | if (is2t) { | ||
1764 | if (bmain) | ||
1765 | rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, | ||
1766 | BIT(5) | BIT(6), 0x1); | ||
1767 | else | ||
1768 | rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, | ||
1769 | BIT(5) | BIT(6), 0x2); | ||
1770 | } else { | ||
1771 | if (bmain) | ||
1772 | rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2); | ||
1773 | else | ||
1774 | rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1); | ||
1775 | |||
1776 | } | ||
1777 | } | ||
1778 | |||
1779 | #undef IQK_ADDA_REG_NUM | ||
1780 | #undef IQK_DELAY_TIME | ||
1781 | |||
1782 | void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery) | ||
1783 | { | ||
1784 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1785 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1786 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1787 | |||
1788 | long result[4][8]; | ||
1789 | u8 i, final_candidate; | ||
1790 | bool patha_ok, pathb_ok; | ||
1791 | long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4, | ||
1792 | reg_ecc, reg_tmp = 0; | ||
1793 | bool is12simular, is13simular, is23simular; | ||
1794 | bool start_conttx = false, singletone = false; | ||
1795 | u32 iqk_bb_reg[10] = { | ||
1796 | ROFDM0_XARXIQIMBALANCE, | ||
1797 | ROFDM0_XBRXIQIMBALANCE, | ||
1798 | ROFDM0_ECCATHRESHOLD, | ||
1799 | ROFDM0_AGCRSSITABLE, | ||
1800 | ROFDM0_XATXIQIMBALANCE, | ||
1801 | ROFDM0_XBTXIQIMBALANCE, | ||
1802 | ROFDM0_XCTXIQIMBALANCE, | ||
1803 | ROFDM0_XCTXAFE, | ||
1804 | ROFDM0_XDTXAFE, | ||
1805 | ROFDM0_RXIQEXTANTA | ||
1806 | }; | ||
1807 | |||
1808 | if (recovery) { | ||
1809 | _rtl92c_phy_reload_adda_registers(hw, | ||
1810 | iqk_bb_reg, | ||
1811 | rtlphy->iqk_bb_backup, 10); | ||
1812 | return; | ||
1813 | } | ||
1814 | if (start_conttx || singletone) | ||
1815 | return; | ||
1816 | for (i = 0; i < 8; i++) { | ||
1817 | result[0][i] = 0; | ||
1818 | result[1][i] = 0; | ||
1819 | result[2][i] = 0; | ||
1820 | result[3][i] = 0; | ||
1821 | } | ||
1822 | final_candidate = 0xff; | ||
1823 | patha_ok = false; | ||
1824 | pathb_ok = false; | ||
1825 | is12simular = false; | ||
1826 | is23simular = false; | ||
1827 | is13simular = false; | ||
1828 | for (i = 0; i < 3; i++) { | ||
1829 | if (IS_92C_SERIAL(rtlhal->version)) | ||
1830 | _rtl92c_phy_iq_calibrate(hw, result, i, true); | ||
1831 | else | ||
1832 | _rtl92c_phy_iq_calibrate(hw, result, i, false); | ||
1833 | if (i == 1) { | ||
1834 | is12simular = _rtl92c_phy_simularity_compare(hw, | ||
1835 | result, 0, | ||
1836 | 1); | ||
1837 | if (is12simular) { | ||
1838 | final_candidate = 0; | ||
1839 | break; | ||
1840 | } | ||
1841 | } | ||
1842 | if (i == 2) { | ||
1843 | is13simular = _rtl92c_phy_simularity_compare(hw, | ||
1844 | result, 0, | ||
1845 | 2); | ||
1846 | if (is13simular) { | ||
1847 | final_candidate = 0; | ||
1848 | break; | ||
1849 | } | ||
1850 | is23simular = _rtl92c_phy_simularity_compare(hw, | ||
1851 | result, 1, | ||
1852 | 2); | ||
1853 | if (is23simular) | ||
1854 | final_candidate = 1; | ||
1855 | else { | ||
1856 | for (i = 0; i < 8; i++) | ||
1857 | reg_tmp += result[3][i]; | ||
1858 | |||
1859 | if (reg_tmp != 0) | ||
1860 | final_candidate = 3; | ||
1861 | else | ||
1862 | final_candidate = 0xFF; | ||
1863 | } | ||
1864 | } | ||
1865 | } | ||
1866 | for (i = 0; i < 4; i++) { | ||
1867 | reg_e94 = result[i][0]; | ||
1868 | reg_e9c = result[i][1]; | ||
1869 | reg_ea4 = result[i][2]; | ||
1870 | reg_eac = result[i][3]; | ||
1871 | reg_eb4 = result[i][4]; | ||
1872 | reg_ebc = result[i][5]; | ||
1873 | reg_ec4 = result[i][6]; | ||
1874 | reg_ecc = result[i][7]; | ||
1875 | } | ||
1876 | if (final_candidate != 0xff) { | ||
1877 | rtlphy->reg_e94 = reg_e94 = result[final_candidate][0]; | ||
1878 | rtlphy->reg_e9c = reg_e9c = result[final_candidate][1]; | ||
1879 | reg_ea4 = result[final_candidate][2]; | ||
1880 | reg_eac = result[final_candidate][3]; | ||
1881 | rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4]; | ||
1882 | rtlphy->reg_ebc = reg_ebc = result[final_candidate][5]; | ||
1883 | reg_ec4 = result[final_candidate][6]; | ||
1884 | reg_ecc = result[final_candidate][7]; | ||
1885 | patha_ok = pathb_ok = true; | ||
1886 | } else { | ||
1887 | rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; | ||
1888 | rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0; | ||
1889 | } | ||
1890 | if (reg_e94 != 0) /*&&(reg_ea4 != 0) */ | ||
1891 | _rtl92c_phy_path_a_fill_iqk_matrix(hw, patha_ok, result, | ||
1892 | final_candidate, | ||
1893 | (reg_ea4 == 0)); | ||
1894 | if (IS_92C_SERIAL(rtlhal->version)) { | ||
1895 | if (reg_eb4 != 0) /*&&(reg_ec4 != 0) */ | ||
1896 | _rtl92c_phy_path_b_fill_iqk_matrix(hw, pathb_ok, | ||
1897 | result, | ||
1898 | final_candidate, | ||
1899 | (reg_ec4 == 0)); | ||
1900 | } | ||
1901 | _rtl92c_phy_save_adda_registers(hw, iqk_bb_reg, | ||
1902 | rtlphy->iqk_bb_backup, 10); | ||
1903 | } | ||
1904 | |||
1905 | void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw) | ||
1906 | { | ||
1907 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1908 | bool start_conttx = false, singletone = false; | ||
1909 | |||
1910 | if (start_conttx || singletone) | ||
1911 | return; | ||
1912 | if (IS_92C_SERIAL(rtlhal->version)) | ||
1913 | _rtl92c_phy_lc_calibrate(hw, true); | ||
1914 | else | ||
1915 | _rtl92c_phy_lc_calibrate(hw, false); | ||
1916 | } | ||
1917 | |||
1918 | void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta) | ||
1919 | { | ||
1920 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1921 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1922 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1923 | |||
1924 | if (rtlphy->apk_done) | ||
1925 | return; | ||
1926 | if (IS_92C_SERIAL(rtlhal->version)) | ||
1927 | _rtl92c_phy_ap_calibrate(hw, delta, true); | ||
1928 | else | ||
1929 | _rtl92c_phy_ap_calibrate(hw, delta, false); | ||
1930 | } | ||
1931 | |||
1932 | void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain) | ||
1933 | { | ||
1934 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1935 | |||
1936 | if (IS_92C_SERIAL(rtlhal->version)) | ||
1937 | _rtl92c_phy_set_rfpath_switch(hw, bmain, true); | ||
1938 | else | ||
1939 | _rtl92c_phy_set_rfpath_switch(hw, bmain, false); | ||
1940 | } | ||
1941 | |||
1942 | bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) | ||
1943 | { | ||
1944 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1945 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1946 | bool postprocessing = false; | ||
1947 | |||
1948 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, | ||
1949 | ("-->IO Cmd(%#x), set_io_inprogress(%d)\n", | ||
1950 | iotype, rtlphy->set_io_inprogress)); | ||
1951 | do { | ||
1952 | switch (iotype) { | ||
1953 | case IO_CMD_RESUME_DM_BY_SCAN: | ||
1954 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, | ||
1955 | ("[IO CMD] Resume DM after scan.\n")); | ||
1956 | postprocessing = true; | ||
1957 | break; | ||
1958 | case IO_CMD_PAUSE_DM_BY_SCAN: | ||
1959 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, | ||
1960 | ("[IO CMD] Pause DM before scan.\n")); | ||
1961 | postprocessing = true; | ||
1962 | break; | ||
1963 | default: | ||
1964 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
1965 | ("switch case not process\n")); | ||
1966 | break; | ||
1967 | } | ||
1968 | } while (false); | ||
1969 | if (postprocessing && !rtlphy->set_io_inprogress) { | ||
1970 | rtlphy->set_io_inprogress = true; | ||
1971 | rtlphy->current_io_type = iotype; | ||
1972 | } else { | ||
1973 | return false; | ||
1974 | } | ||
1975 | rtl92c_phy_set_io(hw); | ||
1976 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, ("<--IO Type(%#x)\n", iotype)); | ||
1977 | return true; | ||
1978 | } | ||
1979 | |||
1980 | void rtl92c_phy_set_io(struct ieee80211_hw *hw) | ||
1981 | { | ||
1982 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1983 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1984 | |||
1985 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, | ||
1986 | ("--->Cmd(%#x), set_io_inprogress(%d)\n", | ||
1987 | rtlphy->current_io_type, rtlphy->set_io_inprogress)); | ||
1988 | switch (rtlphy->current_io_type) { | ||
1989 | case IO_CMD_RESUME_DM_BY_SCAN: | ||
1990 | dm_digtable.cur_igvalue = rtlphy->initgain_backup.xaagccore1; | ||
1991 | rtl92c_dm_write_dig(hw); | ||
1992 | rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); | ||
1993 | break; | ||
1994 | case IO_CMD_PAUSE_DM_BY_SCAN: | ||
1995 | rtlphy->initgain_backup.xaagccore1 = dm_digtable.cur_igvalue; | ||
1996 | dm_digtable.cur_igvalue = 0x17; | ||
1997 | rtl92c_dm_write_dig(hw); | ||
1998 | break; | ||
1999 | default: | ||
2000 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
2001 | ("switch case not process\n")); | ||
2002 | break; | ||
2003 | } | ||
2004 | rtlphy->set_io_inprogress = false; | ||
2005 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, | ||
2006 | ("<---(%#x)\n", rtlphy->current_io_type)); | ||
2007 | } | ||
2008 | |||
2009 | void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw) | ||
2010 | { | ||
2011 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2012 | |||
2013 | rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); | ||
2014 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); | ||
2015 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); | ||
2016 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); | ||
2017 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); | ||
2018 | rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); | ||
2019 | } | ||
2020 | |||
2021 | static void _rtl92ce_phy_set_rf_sleep(struct ieee80211_hw *hw) | ||
2022 | { | ||
2023 | u32 u4b_tmp; | ||
2024 | u8 delay = 5; | ||
2025 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2026 | |||
2027 | rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); | ||
2028 | rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); | ||
2029 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); | ||
2030 | u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); | ||
2031 | while (u4b_tmp != 0 && delay > 0) { | ||
2032 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0); | ||
2033 | rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); | ||
2034 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); | ||
2035 | u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); | ||
2036 | delay--; | ||
2037 | } | ||
2038 | if (delay == 0) { | ||
2039 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); | ||
2040 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); | ||
2041 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); | ||
2042 | rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); | ||
2043 | RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, | ||
2044 | ("Switch RF timeout !!!.\n")); | ||
2045 | return; | ||
2046 | } | ||
2047 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); | ||
2048 | rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); | ||
2049 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile b/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile index 0f0be7c763b8..5c5fdde637cb 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/Makefile | |||
@@ -10,3 +10,5 @@ rtl8192ce-objs := \ | |||
10 | trx.o | 10 | trx.o |
11 | 11 | ||
12 | obj-$(CONFIG_RTL8192CE) += rtl8192ce.o | 12 | obj-$(CONFIG_RTL8192CE) += rtl8192ce.o |
13 | |||
14 | ccflags-y += -D__CHECK_ENDIAN__ | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h index 83cd64895292..2f577c8828fc 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h | |||
@@ -121,11 +121,37 @@ | |||
121 | #define CHIP_92C 0x01 | 121 | #define CHIP_92C 0x01 |
122 | #define CHIP_88C 0x00 | 122 | #define CHIP_88C 0x00 |
123 | 123 | ||
124 | /* Add vendor information into chip version definition. | ||
125 | * Add UMC B-Cut and RTL8723 chip info definition. | ||
126 | * | ||
127 | * BIT 7 Reserved | ||
128 | * BIT 6 UMC BCut | ||
129 | * BIT 5 Manufacturer(TSMC/UMC) | ||
130 | * BIT 4 TEST/NORMAL | ||
131 | * BIT 3 8723 Version | ||
132 | * BIT 2 8723? | ||
133 | * BIT 1 1T2R? | ||
134 | * BIT 0 88C/92C | ||
135 | */ | ||
136 | |||
124 | enum version_8192c { | 137 | enum version_8192c { |
125 | VERSION_A_CHIP_92C = 0x01, | 138 | VERSION_A_CHIP_92C = 0x01, |
126 | VERSION_A_CHIP_88C = 0x00, | 139 | VERSION_A_CHIP_88C = 0x00, |
127 | VERSION_B_CHIP_92C = 0x11, | 140 | VERSION_B_CHIP_92C = 0x11, |
128 | VERSION_B_CHIP_88C = 0x10, | 141 | VERSION_B_CHIP_88C = 0x10, |
142 | VERSION_TEST_CHIP_88C = 0x00, | ||
143 | VERSION_TEST_CHIP_92C = 0x01, | ||
144 | VERSION_NORMAL_TSMC_CHIP_88C = 0x10, | ||
145 | VERSION_NORMAL_TSMC_CHIP_92C = 0x11, | ||
146 | VERSION_NORMAL_TSMC_CHIP_92C_1T2R = 0x13, | ||
147 | VERSION_NORMAL_UMC_CHIP_88C_A_CUT = 0x30, | ||
148 | VERSION_NORMAL_UMC_CHIP_92C_A_CUT = 0x31, | ||
149 | VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT = 0x33, | ||
150 | VERSION_NORMA_UMC_CHIP_8723_1T1R_A_CUT = 0x34, | ||
151 | VERSION_NORMA_UMC_CHIP_8723_1T1R_B_CUT = 0x3c, | ||
152 | VERSION_NORMAL_UMC_CHIP_88C_B_CUT = 0x70, | ||
153 | VERSION_NORMAL_UMC_CHIP_92C_B_CUT = 0x71, | ||
154 | VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT = 0x73, | ||
129 | VERSION_UNKNOWN = 0x88, | 155 | VERSION_UNKNOWN = 0x88, |
130 | }; | 156 | }; |
131 | 157 | ||
@@ -254,4 +280,122 @@ struct h2c_cmd_8192c { | |||
254 | u8 *p_cmdbuffer; | 280 | u8 *p_cmdbuffer; |
255 | }; | 281 | }; |
256 | 282 | ||
283 | static inline u8 _rtl92c_get_chnl_group(u8 chnl) | ||
284 | { | ||
285 | u8 group = 0; | ||
286 | |||
287 | if (chnl < 3) | ||
288 | group = 0; | ||
289 | else if (chnl < 9) | ||
290 | group = 1; | ||
291 | else | ||
292 | group = 2; | ||
293 | |||
294 | return group; | ||
295 | } | ||
296 | |||
297 | /* NOTE: reference to rtl8192c_rates struct */ | ||
298 | static inline int _rtl92c_rate_mapping(struct ieee80211_hw *hw, bool isHT, | ||
299 | u8 desc_rate, bool first_ampdu) | ||
300 | { | ||
301 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
302 | int rate_idx = 0; | ||
303 | |||
304 | if (first_ampdu) { | ||
305 | if (false == isHT) { | ||
306 | switch (desc_rate) { | ||
307 | case DESC92C_RATE1M: | ||
308 | rate_idx = 0; | ||
309 | break; | ||
310 | case DESC92C_RATE2M: | ||
311 | rate_idx = 1; | ||
312 | break; | ||
313 | case DESC92C_RATE5_5M: | ||
314 | rate_idx = 2; | ||
315 | break; | ||
316 | case DESC92C_RATE11M: | ||
317 | rate_idx = 3; | ||
318 | break; | ||
319 | case DESC92C_RATE6M: | ||
320 | rate_idx = 4; | ||
321 | break; | ||
322 | case DESC92C_RATE9M: | ||
323 | rate_idx = 5; | ||
324 | break; | ||
325 | case DESC92C_RATE12M: | ||
326 | rate_idx = 6; | ||
327 | break; | ||
328 | case DESC92C_RATE18M: | ||
329 | rate_idx = 7; | ||
330 | break; | ||
331 | case DESC92C_RATE24M: | ||
332 | rate_idx = 8; | ||
333 | break; | ||
334 | case DESC92C_RATE36M: | ||
335 | rate_idx = 9; | ||
336 | break; | ||
337 | case DESC92C_RATE48M: | ||
338 | rate_idx = 10; | ||
339 | break; | ||
340 | case DESC92C_RATE54M: | ||
341 | rate_idx = 11; | ||
342 | break; | ||
343 | default: | ||
344 | RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG, | ||
345 | ("Rate %d is not support, set to " | ||
346 | "1M rate.\n", desc_rate)); | ||
347 | rate_idx = 0; | ||
348 | break; | ||
349 | } | ||
350 | } else { | ||
351 | rate_idx = 11; | ||
352 | } | ||
353 | return rate_idx; | ||
354 | } | ||
355 | switch (desc_rate) { | ||
356 | case DESC92C_RATE1M: | ||
357 | rate_idx = 0; | ||
358 | break; | ||
359 | case DESC92C_RATE2M: | ||
360 | rate_idx = 1; | ||
361 | break; | ||
362 | case DESC92C_RATE5_5M: | ||
363 | rate_idx = 2; | ||
364 | break; | ||
365 | case DESC92C_RATE11M: | ||
366 | rate_idx = 3; | ||
367 | break; | ||
368 | case DESC92C_RATE6M: | ||
369 | rate_idx = 4; | ||
370 | break; | ||
371 | case DESC92C_RATE9M: | ||
372 | rate_idx = 5; | ||
373 | break; | ||
374 | case DESC92C_RATE12M: | ||
375 | rate_idx = 6; | ||
376 | break; | ||
377 | case DESC92C_RATE18M: | ||
378 | rate_idx = 7; | ||
379 | break; | ||
380 | case DESC92C_RATE24M: | ||
381 | rate_idx = 8; | ||
382 | break; | ||
383 | case DESC92C_RATE36M: | ||
384 | rate_idx = 9; | ||
385 | break; | ||
386 | case DESC92C_RATE48M: | ||
387 | rate_idx = 10; | ||
388 | break; | ||
389 | case DESC92C_RATE54M: | ||
390 | rate_idx = 11; | ||
391 | break; | ||
392 | /* TODO: How to mapping MCS rate? */ | ||
393 | /* NOTE: referenc to __ieee80211_rx */ | ||
394 | default: | ||
395 | rate_idx = 11; | ||
396 | break; | ||
397 | } | ||
398 | return rate_idx; | ||
399 | } | ||
400 | |||
257 | #endif | 401 | #endif |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c index 62e7c64e087b..888df5e2d2fc 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c | |||
@@ -35,485 +35,16 @@ | |||
35 | #include "dm.h" | 35 | #include "dm.h" |
36 | #include "fw.h" | 36 | #include "fw.h" |
37 | 37 | ||
38 | struct dig_t dm_digtable; | 38 | #include "../rtl8192c/dm_common.c" |
39 | static struct ps_t dm_pstable; | ||
40 | 39 | ||
41 | static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = { | 40 | void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) |
42 | 0x7f8001fe, | ||
43 | 0x788001e2, | ||
44 | 0x71c001c7, | ||
45 | 0x6b8001ae, | ||
46 | 0x65400195, | ||
47 | 0x5fc0017f, | ||
48 | 0x5a400169, | ||
49 | 0x55400155, | ||
50 | 0x50800142, | ||
51 | 0x4c000130, | ||
52 | 0x47c0011f, | ||
53 | 0x43c0010f, | ||
54 | 0x40000100, | ||
55 | 0x3c8000f2, | ||
56 | 0x390000e4, | ||
57 | 0x35c000d7, | ||
58 | 0x32c000cb, | ||
59 | 0x300000c0, | ||
60 | 0x2d4000b5, | ||
61 | 0x2ac000ab, | ||
62 | 0x288000a2, | ||
63 | 0x26000098, | ||
64 | 0x24000090, | ||
65 | 0x22000088, | ||
66 | 0x20000080, | ||
67 | 0x1e400079, | ||
68 | 0x1c800072, | ||
69 | 0x1b00006c, | ||
70 | 0x19800066, | ||
71 | 0x18000060, | ||
72 | 0x16c0005b, | ||
73 | 0x15800056, | ||
74 | 0x14400051, | ||
75 | 0x1300004c, | ||
76 | 0x12000048, | ||
77 | 0x11000044, | ||
78 | 0x10000040, | ||
79 | }; | ||
80 | |||
81 | static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = { | ||
82 | {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, | ||
83 | {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, | ||
84 | {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, | ||
85 | {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, | ||
86 | {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, | ||
87 | {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, | ||
88 | {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, | ||
89 | {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, | ||
90 | {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, | ||
91 | {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, | ||
92 | {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, | ||
93 | {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, | ||
94 | {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, | ||
95 | {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, | ||
96 | {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, | ||
97 | {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, | ||
98 | {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, | ||
99 | {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, | ||
100 | {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, | ||
101 | {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, | ||
102 | {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, | ||
103 | {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, | ||
104 | {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, | ||
105 | {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, | ||
106 | {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, | ||
107 | {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, | ||
108 | {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, | ||
109 | {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, | ||
110 | {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, | ||
111 | {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, | ||
112 | {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, | ||
113 | {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, | ||
114 | {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} | ||
115 | }; | ||
116 | |||
117 | static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = { | ||
118 | {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, | ||
119 | {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, | ||
120 | {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, | ||
121 | {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, | ||
122 | {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, | ||
123 | {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, | ||
124 | {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, | ||
125 | {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, | ||
126 | {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, | ||
127 | {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, | ||
128 | {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, | ||
129 | {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, | ||
130 | {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, | ||
131 | {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, | ||
132 | {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, | ||
133 | {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, | ||
134 | {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, | ||
135 | {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, | ||
136 | {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, | ||
137 | {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, | ||
138 | {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, | ||
139 | {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, | ||
140 | {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, | ||
141 | {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, | ||
142 | {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, | ||
143 | {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, | ||
144 | {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, | ||
145 | {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, | ||
146 | {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, | ||
147 | {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, | ||
148 | {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, | ||
149 | {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, | ||
150 | {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} | ||
151 | }; | ||
152 | |||
153 | static void rtl92c_dm_diginit(struct ieee80211_hw *hw) | ||
154 | { | ||
155 | dm_digtable.dig_enable_flag = true; | ||
156 | dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; | ||
157 | dm_digtable.cur_igvalue = 0x20; | ||
158 | dm_digtable.pre_igvalue = 0x0; | ||
159 | dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT; | ||
160 | dm_digtable.presta_connectstate = DIG_STA_DISCONNECT; | ||
161 | dm_digtable.curmultista_connectstate = DIG_MULTISTA_DISCONNECT; | ||
162 | dm_digtable.rssi_lowthresh = DM_DIG_THRESH_LOW; | ||
163 | dm_digtable.rssi_highthresh = DM_DIG_THRESH_HIGH; | ||
164 | dm_digtable.fa_lowthresh = DM_FALSEALARM_THRESH_LOW; | ||
165 | dm_digtable.fa_highthresh = DM_FALSEALARM_THRESH_HIGH; | ||
166 | dm_digtable.rx_gain_range_max = DM_DIG_MAX; | ||
167 | dm_digtable.rx_gain_range_min = DM_DIG_MIN; | ||
168 | dm_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT; | ||
169 | dm_digtable.backoff_val_range_max = DM_DIG_BACKOFF_MAX; | ||
170 | dm_digtable.backoff_val_range_min = DM_DIG_BACKOFF_MIN; | ||
171 | dm_digtable.pre_cck_pd_state = CCK_PD_STAGE_MAX; | ||
172 | dm_digtable.cur_cck_pd_state = CCK_PD_STAGE_MAX; | ||
173 | } | ||
174 | |||
175 | static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw) | ||
176 | { | ||
177 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
178 | long rssi_val_min = 0; | ||
179 | |||
180 | if ((dm_digtable.curmultista_connectstate == DIG_MULTISTA_CONNECT) && | ||
181 | (dm_digtable.cursta_connectctate == DIG_STA_CONNECT)) { | ||
182 | if (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb != 0) | ||
183 | rssi_val_min = | ||
184 | (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb > | ||
185 | rtlpriv->dm.undecorated_smoothed_pwdb) ? | ||
186 | rtlpriv->dm.undecorated_smoothed_pwdb : | ||
187 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | ||
188 | else | ||
189 | rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb; | ||
190 | } else if (dm_digtable.cursta_connectctate == DIG_STA_CONNECT || | ||
191 | dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT) { | ||
192 | rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb; | ||
193 | } else if (dm_digtable.curmultista_connectstate == | ||
194 | DIG_MULTISTA_CONNECT) { | ||
195 | rssi_val_min = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | ||
196 | } | ||
197 | |||
198 | return (u8) rssi_val_min; | ||
199 | } | ||
200 | |||
201 | static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) | ||
202 | { | ||
203 | u32 ret_value; | ||
204 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
205 | struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); | ||
206 | |||
207 | ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD); | ||
208 | falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16); | ||
209 | |||
210 | ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD); | ||
211 | falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff); | ||
212 | falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16); | ||
213 | |||
214 | ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD); | ||
215 | falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff); | ||
216 | falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail + | ||
217 | falsealm_cnt->cnt_rate_illegal + | ||
218 | falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail; | ||
219 | |||
220 | rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1); | ||
221 | ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0); | ||
222 | falsealm_cnt->cnt_cck_fail = ret_value; | ||
223 | |||
224 | ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3); | ||
225 | falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8; | ||
226 | falsealm_cnt->cnt_all = (falsealm_cnt->cnt_parity_fail + | ||
227 | falsealm_cnt->cnt_rate_illegal + | ||
228 | falsealm_cnt->cnt_crc8_fail + | ||
229 | falsealm_cnt->cnt_mcs_fail + | ||
230 | falsealm_cnt->cnt_cck_fail); | ||
231 | |||
232 | rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1); | ||
233 | rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0); | ||
234 | rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0); | ||
235 | rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2); | ||
236 | |||
237 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, | ||
238 | ("cnt_parity_fail = %d, cnt_rate_illegal = %d, " | ||
239 | "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n", | ||
240 | falsealm_cnt->cnt_parity_fail, | ||
241 | falsealm_cnt->cnt_rate_illegal, | ||
242 | falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail)); | ||
243 | |||
244 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, | ||
245 | ("cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n", | ||
246 | falsealm_cnt->cnt_ofdm_fail, | ||
247 | falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all)); | ||
248 | } | ||
249 | |||
250 | static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw) | ||
251 | { | ||
252 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
253 | u8 value_igi = dm_digtable.cur_igvalue; | ||
254 | |||
255 | if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0) | ||
256 | value_igi--; | ||
257 | else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1) | ||
258 | value_igi += 0; | ||
259 | else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH2) | ||
260 | value_igi++; | ||
261 | else if (rtlpriv->falsealm_cnt.cnt_all >= DM_DIG_FA_TH2) | ||
262 | value_igi += 2; | ||
263 | if (value_igi > DM_DIG_FA_UPPER) | ||
264 | value_igi = DM_DIG_FA_UPPER; | ||
265 | else if (value_igi < DM_DIG_FA_LOWER) | ||
266 | value_igi = DM_DIG_FA_LOWER; | ||
267 | if (rtlpriv->falsealm_cnt.cnt_all > 10000) | ||
268 | value_igi = 0x32; | ||
269 | |||
270 | dm_digtable.cur_igvalue = value_igi; | ||
271 | rtl92c_dm_write_dig(hw); | ||
272 | } | ||
273 | |||
274 | static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw) | ||
275 | { | ||
276 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
277 | |||
278 | if (rtlpriv->falsealm_cnt.cnt_all > dm_digtable.fa_highthresh) { | ||
279 | if ((dm_digtable.backoff_val - 2) < | ||
280 | dm_digtable.backoff_val_range_min) | ||
281 | dm_digtable.backoff_val = | ||
282 | dm_digtable.backoff_val_range_min; | ||
283 | else | ||
284 | dm_digtable.backoff_val -= 2; | ||
285 | } else if (rtlpriv->falsealm_cnt.cnt_all < dm_digtable.fa_lowthresh) { | ||
286 | if ((dm_digtable.backoff_val + 2) > | ||
287 | dm_digtable.backoff_val_range_max) | ||
288 | dm_digtable.backoff_val = | ||
289 | dm_digtable.backoff_val_range_max; | ||
290 | else | ||
291 | dm_digtable.backoff_val += 2; | ||
292 | } | ||
293 | |||
294 | if ((dm_digtable.rssi_val_min + 10 - dm_digtable.backoff_val) > | ||
295 | dm_digtable.rx_gain_range_max) | ||
296 | dm_digtable.cur_igvalue = dm_digtable.rx_gain_range_max; | ||
297 | else if ((dm_digtable.rssi_val_min + 10 - | ||
298 | dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min) | ||
299 | dm_digtable.cur_igvalue = dm_digtable.rx_gain_range_min; | ||
300 | else | ||
301 | dm_digtable.cur_igvalue = dm_digtable.rssi_val_min + 10 - | ||
302 | dm_digtable.backoff_val; | ||
303 | |||
304 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, | ||
305 | ("rssi_val_min = %x backoff_val %x\n", | ||
306 | dm_digtable.rssi_val_min, dm_digtable.backoff_val)); | ||
307 | |||
308 | rtl92c_dm_write_dig(hw); | ||
309 | } | ||
310 | |||
311 | static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) | ||
312 | { | ||
313 | static u8 binitialized; /* initialized to false */ | ||
314 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
315 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
316 | long rssi_strength = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | ||
317 | bool b_multi_sta = false; | ||
318 | |||
319 | if (mac->opmode == NL80211_IFTYPE_ADHOC) | ||
320 | b_multi_sta = true; | ||
321 | |||
322 | if ((b_multi_sta == false) || (dm_digtable.cursta_connectctate != | ||
323 | DIG_STA_DISCONNECT)) { | ||
324 | binitialized = false; | ||
325 | dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; | ||
326 | return; | ||
327 | } else if (binitialized == false) { | ||
328 | binitialized = true; | ||
329 | dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; | ||
330 | dm_digtable.cur_igvalue = 0x20; | ||
331 | rtl92c_dm_write_dig(hw); | ||
332 | } | ||
333 | |||
334 | if (dm_digtable.curmultista_connectstate == DIG_MULTISTA_CONNECT) { | ||
335 | if ((rssi_strength < dm_digtable.rssi_lowthresh) && | ||
336 | (dm_digtable.dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) { | ||
337 | |||
338 | if (dm_digtable.dig_ext_port_stage == | ||
339 | DIG_EXT_PORT_STAGE_2) { | ||
340 | dm_digtable.cur_igvalue = 0x20; | ||
341 | rtl92c_dm_write_dig(hw); | ||
342 | } | ||
343 | |||
344 | dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_1; | ||
345 | } else if (rssi_strength > dm_digtable.rssi_highthresh) { | ||
346 | dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_2; | ||
347 | rtl92c_dm_ctrl_initgain_by_fa(hw); | ||
348 | } | ||
349 | } else if (dm_digtable.dig_ext_port_stage != DIG_EXT_PORT_STAGE_0) { | ||
350 | dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; | ||
351 | dm_digtable.cur_igvalue = 0x20; | ||
352 | rtl92c_dm_write_dig(hw); | ||
353 | } | ||
354 | |||
355 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, | ||
356 | ("curmultista_connectstate = " | ||
357 | "%x dig_ext_port_stage %x\n", | ||
358 | dm_digtable.curmultista_connectstate, | ||
359 | dm_digtable.dig_ext_port_stage)); | ||
360 | } | ||
361 | |||
362 | static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw) | ||
363 | { | ||
364 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
365 | |||
366 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, | ||
367 | ("presta_connectstate = %x," | ||
368 | " cursta_connectctate = %x\n", | ||
369 | dm_digtable.presta_connectstate, | ||
370 | dm_digtable.cursta_connectctate)); | ||
371 | |||
372 | if (dm_digtable.presta_connectstate == dm_digtable.cursta_connectctate | ||
373 | || dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT | ||
374 | || dm_digtable.cursta_connectctate == DIG_STA_CONNECT) { | ||
375 | |||
376 | if (dm_digtable.cursta_connectctate != DIG_STA_DISCONNECT) { | ||
377 | dm_digtable.rssi_val_min = | ||
378 | rtl92c_dm_initial_gain_min_pwdb(hw); | ||
379 | rtl92c_dm_ctrl_initgain_by_rssi(hw); | ||
380 | } | ||
381 | } else { | ||
382 | dm_digtable.rssi_val_min = 0; | ||
383 | dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; | ||
384 | dm_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT; | ||
385 | dm_digtable.cur_igvalue = 0x20; | ||
386 | dm_digtable.pre_igvalue = 0; | ||
387 | rtl92c_dm_write_dig(hw); | ||
388 | } | ||
389 | } | ||
390 | |||
391 | static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) | ||
392 | { | ||
393 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
394 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
395 | |||
396 | if (dm_digtable.cursta_connectctate == DIG_STA_CONNECT) { | ||
397 | dm_digtable.rssi_val_min = rtl92c_dm_initial_gain_min_pwdb(hw); | ||
398 | |||
399 | if (dm_digtable.pre_cck_pd_state == CCK_PD_STAGE_LowRssi) { | ||
400 | if (dm_digtable.rssi_val_min <= 25) | ||
401 | dm_digtable.cur_cck_pd_state = | ||
402 | CCK_PD_STAGE_LowRssi; | ||
403 | else | ||
404 | dm_digtable.cur_cck_pd_state = | ||
405 | CCK_PD_STAGE_HighRssi; | ||
406 | } else { | ||
407 | if (dm_digtable.rssi_val_min <= 20) | ||
408 | dm_digtable.cur_cck_pd_state = | ||
409 | CCK_PD_STAGE_LowRssi; | ||
410 | else | ||
411 | dm_digtable.cur_cck_pd_state = | ||
412 | CCK_PD_STAGE_HighRssi; | ||
413 | } | ||
414 | } else { | ||
415 | dm_digtable.cur_cck_pd_state = CCK_PD_STAGE_MAX; | ||
416 | } | ||
417 | |||
418 | if (dm_digtable.pre_cck_pd_state != dm_digtable.cur_cck_pd_state) { | ||
419 | if (dm_digtable.cur_cck_pd_state == CCK_PD_STAGE_LowRssi) { | ||
420 | if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800) | ||
421 | dm_digtable.cur_cck_fa_state = | ||
422 | CCK_FA_STAGE_High; | ||
423 | else | ||
424 | dm_digtable.cur_cck_fa_state = CCK_FA_STAGE_Low; | ||
425 | |||
426 | if (dm_digtable.pre_cck_fa_state != | ||
427 | dm_digtable.cur_cck_fa_state) { | ||
428 | if (dm_digtable.cur_cck_fa_state == | ||
429 | CCK_FA_STAGE_Low) | ||
430 | rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, | ||
431 | 0x83); | ||
432 | else | ||
433 | rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, | ||
434 | 0xcd); | ||
435 | |||
436 | dm_digtable.pre_cck_fa_state = | ||
437 | dm_digtable.cur_cck_fa_state; | ||
438 | } | ||
439 | |||
440 | rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40); | ||
441 | |||
442 | if (IS_92C_SERIAL(rtlhal->version)) | ||
443 | rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, | ||
444 | MASKBYTE2, 0xd7); | ||
445 | } else { | ||
446 | rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); | ||
447 | rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47); | ||
448 | |||
449 | if (IS_92C_SERIAL(rtlhal->version)) | ||
450 | rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, | ||
451 | MASKBYTE2, 0xd3); | ||
452 | } | ||
453 | dm_digtable.pre_cck_pd_state = dm_digtable.cur_cck_pd_state; | ||
454 | } | ||
455 | |||
456 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, | ||
457 | ("CCKPDStage=%x\n", dm_digtable.cur_cck_pd_state)); | ||
458 | |||
459 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, | ||
460 | ("is92C=%x\n", IS_92C_SERIAL(rtlhal->version))); | ||
461 | } | ||
462 | |||
463 | static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) | ||
464 | { | ||
465 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
466 | |||
467 | if (mac->act_scanning == true) | ||
468 | return; | ||
469 | |||
470 | if ((mac->link_state > MAC80211_NOLINK) && | ||
471 | (mac->link_state < MAC80211_LINKED)) | ||
472 | dm_digtable.cursta_connectctate = DIG_STA_BEFORE_CONNECT; | ||
473 | else if (mac->link_state >= MAC80211_LINKED) | ||
474 | dm_digtable.cursta_connectctate = DIG_STA_CONNECT; | ||
475 | else | ||
476 | dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT; | ||
477 | |||
478 | rtl92c_dm_initial_gain_sta(hw); | ||
479 | rtl92c_dm_initial_gain_multi_sta(hw); | ||
480 | rtl92c_dm_cck_packet_detection_thresh(hw); | ||
481 | |||
482 | dm_digtable.presta_connectstate = dm_digtable.cursta_connectctate; | ||
483 | |||
484 | } | ||
485 | |||
486 | static void rtl92c_dm_dig(struct ieee80211_hw *hw) | ||
487 | { | ||
488 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
489 | |||
490 | if (rtlpriv->dm.b_dm_initialgain_enable == false) | ||
491 | return; | ||
492 | if (dm_digtable.dig_enable_flag == false) | ||
493 | return; | ||
494 | |||
495 | rtl92c_dm_ctrl_initgain_by_twoport(hw); | ||
496 | |||
497 | } | ||
498 | |||
499 | static void rtl92c_dm_init_dynamic_txpower(struct ieee80211_hw *hw) | ||
500 | { | ||
501 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
502 | |||
503 | rtlpriv->dm.bdynamic_txpower_enable = false; | ||
504 | |||
505 | rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; | ||
506 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; | ||
507 | } | ||
508 | |||
509 | static void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) | ||
510 | { | 41 | { |
511 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 42 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
512 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 43 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
513 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 44 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
514 | long undecorated_smoothed_pwdb; | 45 | long undecorated_smoothed_pwdb; |
515 | 46 | ||
516 | if (!rtlpriv->dm.bdynamic_txpower_enable) | 47 | if (!rtlpriv->dm.dynamic_txpower_enable) |
517 | return; | 48 | return; |
518 | 49 | ||
519 | if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) { | 50 | if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) { |
@@ -584,890 +115,4 @@ static void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) | |||
584 | rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; | 115 | rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; |
585 | } | 116 | } |
586 | 117 | ||
587 | void rtl92c_dm_write_dig(struct ieee80211_hw *hw) | ||
588 | { | ||
589 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
590 | |||
591 | RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, | ||
592 | ("cur_igvalue = 0x%x, " | ||
593 | "pre_igvalue = 0x%x, backoff_val = %d\n", | ||
594 | dm_digtable.cur_igvalue, dm_digtable.pre_igvalue, | ||
595 | dm_digtable.backoff_val)); | ||
596 | |||
597 | if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) { | ||
598 | rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, | ||
599 | dm_digtable.cur_igvalue); | ||
600 | rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f, | ||
601 | dm_digtable.cur_igvalue); | ||
602 | |||
603 | dm_digtable.pre_igvalue = dm_digtable.cur_igvalue; | ||
604 | } | ||
605 | } | ||
606 | |||
607 | static void rtl92c_dm_pwdb_monitor(struct ieee80211_hw *hw) | ||
608 | { | ||
609 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
610 | long tmpentry_max_pwdb = 0, tmpentry_min_pwdb = 0xff; | ||
611 | |||
612 | u8 h2c_parameter[3] = { 0 }; | ||
613 | |||
614 | return; | ||
615 | |||
616 | if (tmpentry_max_pwdb != 0) { | ||
617 | rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = | ||
618 | tmpentry_max_pwdb; | ||
619 | } else { | ||
620 | rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = 0; | ||
621 | } | ||
622 | |||
623 | if (tmpentry_min_pwdb != 0xff) { | ||
624 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = | ||
625 | tmpentry_min_pwdb; | ||
626 | } else { | ||
627 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = 0; | ||
628 | } | ||
629 | |||
630 | h2c_parameter[2] = (u8) (rtlpriv->dm.undecorated_smoothed_pwdb & 0xFF); | ||
631 | h2c_parameter[0] = 0; | ||
632 | |||
633 | rtl92c_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, h2c_parameter); | ||
634 | } | ||
635 | |||
636 | void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw) | ||
637 | { | ||
638 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
639 | rtlpriv->dm.bcurrent_turbo_edca = false; | ||
640 | rtlpriv->dm.bis_any_nonbepkts = false; | ||
641 | rtlpriv->dm.bis_cur_rdlstate = false; | ||
642 | } | ||
643 | |||
644 | static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw) | ||
645 | { | ||
646 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
647 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
648 | static u64 last_txok_cnt; | ||
649 | static u64 last_rxok_cnt; | ||
650 | u64 cur_txok_cnt; | ||
651 | u64 cur_rxok_cnt; | ||
652 | u32 edca_be_ul = 0x5ea42b; | ||
653 | u32 edca_be_dl = 0x5ea42b; | ||
654 | |||
655 | if (mac->opmode == NL80211_IFTYPE_ADHOC) | ||
656 | goto dm_checkedcaturbo_exit; | ||
657 | |||
658 | if (mac->link_state != MAC80211_LINKED) { | ||
659 | rtlpriv->dm.bcurrent_turbo_edca = false; | ||
660 | return; | ||
661 | } | ||
662 | |||
663 | if (!mac->ht_enable) { /*FIX MERGE */ | ||
664 | if (!(edca_be_ul & 0xffff0000)) | ||
665 | edca_be_ul |= 0x005e0000; | ||
666 | |||
667 | if (!(edca_be_dl & 0xffff0000)) | ||
668 | edca_be_dl |= 0x005e0000; | ||
669 | } | ||
670 | |||
671 | if ((!rtlpriv->dm.bis_any_nonbepkts) && | ||
672 | (!rtlpriv->dm.b_disable_framebursting)) { | ||
673 | cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt; | ||
674 | cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt; | ||
675 | if (cur_rxok_cnt > 4 * cur_txok_cnt) { | ||
676 | if (!rtlpriv->dm.bis_cur_rdlstate || | ||
677 | !rtlpriv->dm.bcurrent_turbo_edca) { | ||
678 | rtl_write_dword(rtlpriv, | ||
679 | REG_EDCA_BE_PARAM, | ||
680 | edca_be_dl); | ||
681 | rtlpriv->dm.bis_cur_rdlstate = true; | ||
682 | } | ||
683 | } else { | ||
684 | if (rtlpriv->dm.bis_cur_rdlstate || | ||
685 | !rtlpriv->dm.bcurrent_turbo_edca) { | ||
686 | rtl_write_dword(rtlpriv, | ||
687 | REG_EDCA_BE_PARAM, | ||
688 | edca_be_ul); | ||
689 | rtlpriv->dm.bis_cur_rdlstate = false; | ||
690 | } | ||
691 | } | ||
692 | rtlpriv->dm.bcurrent_turbo_edca = true; | ||
693 | } else { | ||
694 | if (rtlpriv->dm.bcurrent_turbo_edca) { | ||
695 | u8 tmp = AC0_BE; | ||
696 | rtlpriv->cfg->ops->set_hw_reg(hw, | ||
697 | HW_VAR_AC_PARAM, | ||
698 | (u8 *) (&tmp)); | ||
699 | rtlpriv->dm.bcurrent_turbo_edca = false; | ||
700 | } | ||
701 | } | ||
702 | |||
703 | dm_checkedcaturbo_exit: | ||
704 | rtlpriv->dm.bis_any_nonbepkts = false; | ||
705 | last_txok_cnt = rtlpriv->stats.txbytesunicast; | ||
706 | last_rxok_cnt = rtlpriv->stats.rxbytesunicast; | ||
707 | } | ||
708 | |||
709 | static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw | ||
710 | *hw) | ||
711 | { | ||
712 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
713 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
714 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
715 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
716 | u8 thermalvalue, delta, delta_lck, delta_iqk; | ||
717 | long ele_a, ele_d, temp_cck, val_x, value32; | ||
718 | long val_y, ele_c; | ||
719 | u8 ofdm_index[2], cck_index, ofdm_index_old[2], cck_index_old; | ||
720 | int i; | ||
721 | bool is2t = IS_92C_SERIAL(rtlhal->version); | ||
722 | u8 txpwr_level[2] = {0, 0}; | ||
723 | u8 ofdm_min_index = 6, rf; | ||
724 | |||
725 | rtlpriv->dm.btxpower_trackingInit = true; | ||
726 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | ||
727 | ("rtl92c_dm_txpower_tracking_callback_thermalmeter\n")); | ||
728 | |||
729 | thermalvalue = (u8) rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f); | ||
730 | |||
731 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | ||
732 | ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " | ||
733 | "eeprom_thermalmeter 0x%x\n", | ||
734 | thermalvalue, rtlpriv->dm.thermalvalue, | ||
735 | rtlefuse->eeprom_thermalmeter)); | ||
736 | |||
737 | rtl92c_phy_ap_calibrate(hw, (thermalvalue - | ||
738 | rtlefuse->eeprom_thermalmeter)); | ||
739 | if (is2t) | ||
740 | rf = 2; | ||
741 | else | ||
742 | rf = 1; | ||
743 | |||
744 | if (thermalvalue) { | ||
745 | ele_d = rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, | ||
746 | MASKDWORD) & MASKOFDM_D; | ||
747 | |||
748 | for (i = 0; i < OFDM_TABLE_LENGTH; i++) { | ||
749 | if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) { | ||
750 | ofdm_index_old[0] = (u8) i; | ||
751 | |||
752 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | ||
753 | ("Initial pathA ele_d reg0x%x = 0x%lx, " | ||
754 | "ofdm_index=0x%x\n", | ||
755 | ROFDM0_XATXIQIMBALANCE, | ||
756 | ele_d, ofdm_index_old[0])); | ||
757 | break; | ||
758 | } | ||
759 | } | ||
760 | |||
761 | if (is2t) { | ||
762 | ele_d = rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, | ||
763 | MASKDWORD) & MASKOFDM_D; | ||
764 | |||
765 | for (i = 0; i < OFDM_TABLE_LENGTH; i++) { | ||
766 | if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) { | ||
767 | ofdm_index_old[1] = (u8) i; | ||
768 | |||
769 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, | ||
770 | DBG_LOUD, | ||
771 | ("Initial pathB ele_d reg0x%x = " | ||
772 | "0x%lx, ofdm_index=0x%x\n", | ||
773 | ROFDM0_XBTXIQIMBALANCE, ele_d, | ||
774 | ofdm_index_old[1])); | ||
775 | break; | ||
776 | } | ||
777 | } | ||
778 | } | ||
779 | |||
780 | temp_cck = | ||
781 | rtl_get_bbreg(hw, RCCK0_TXFILTER2, MASKDWORD) & MASKCCK; | ||
782 | |||
783 | for (i = 0; i < CCK_TABLE_LENGTH; i++) { | ||
784 | if (rtlpriv->dm.b_cck_inch14) { | ||
785 | if (memcmp((void *)&temp_cck, | ||
786 | (void *)&cckswing_table_ch14[i][2], | ||
787 | 4) == 0) { | ||
788 | cck_index_old = (u8) i; | ||
789 | |||
790 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, | ||
791 | DBG_LOUD, | ||
792 | ("Initial reg0x%x = 0x%lx, " | ||
793 | "cck_index=0x%x, ch 14 %d\n", | ||
794 | RCCK0_TXFILTER2, temp_cck, | ||
795 | cck_index_old, | ||
796 | rtlpriv->dm.b_cck_inch14)); | ||
797 | break; | ||
798 | } | ||
799 | } else { | ||
800 | if (memcmp((void *)&temp_cck, | ||
801 | (void *) | ||
802 | &cckswing_table_ch1ch13[i][2], | ||
803 | 4) == 0) { | ||
804 | cck_index_old = (u8) i; | ||
805 | 118 | ||
806 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, | ||
807 | DBG_LOUD, | ||
808 | ("Initial reg0x%x = 0x%lx, " | ||
809 | "cck_index=0x%x, ch14 %d\n", | ||
810 | RCCK0_TXFILTER2, temp_cck, | ||
811 | cck_index_old, | ||
812 | rtlpriv->dm.b_cck_inch14)); | ||
813 | break; | ||
814 | } | ||
815 | } | ||
816 | } | ||
817 | |||
818 | if (!rtlpriv->dm.thermalvalue) { | ||
819 | rtlpriv->dm.thermalvalue = | ||
820 | rtlefuse->eeprom_thermalmeter; | ||
821 | rtlpriv->dm.thermalvalue_lck = thermalvalue; | ||
822 | rtlpriv->dm.thermalvalue_iqk = thermalvalue; | ||
823 | for (i = 0; i < rf; i++) | ||
824 | rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i]; | ||
825 | rtlpriv->dm.cck_index = cck_index_old; | ||
826 | } | ||
827 | |||
828 | delta = (thermalvalue > rtlpriv->dm.thermalvalue) ? | ||
829 | (thermalvalue - rtlpriv->dm.thermalvalue) : | ||
830 | (rtlpriv->dm.thermalvalue - thermalvalue); | ||
831 | |||
832 | delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ? | ||
833 | (thermalvalue - rtlpriv->dm.thermalvalue_lck) : | ||
834 | (rtlpriv->dm.thermalvalue_lck - thermalvalue); | ||
835 | |||
836 | delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ? | ||
837 | (thermalvalue - rtlpriv->dm.thermalvalue_iqk) : | ||
838 | (rtlpriv->dm.thermalvalue_iqk - thermalvalue); | ||
839 | |||
840 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | ||
841 | ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " | ||
842 | "eeprom_thermalmeter 0x%x delta 0x%x " | ||
843 | "delta_lck 0x%x delta_iqk 0x%x\n", | ||
844 | thermalvalue, rtlpriv->dm.thermalvalue, | ||
845 | rtlefuse->eeprom_thermalmeter, delta, delta_lck, | ||
846 | delta_iqk)); | ||
847 | |||
848 | if (delta_lck > 1) { | ||
849 | rtlpriv->dm.thermalvalue_lck = thermalvalue; | ||
850 | rtl92c_phy_lc_calibrate(hw); | ||
851 | } | ||
852 | |||
853 | if (delta > 0 && rtlpriv->dm.txpower_track_control) { | ||
854 | if (thermalvalue > rtlpriv->dm.thermalvalue) { | ||
855 | for (i = 0; i < rf; i++) | ||
856 | rtlpriv->dm.ofdm_index[i] -= delta; | ||
857 | rtlpriv->dm.cck_index -= delta; | ||
858 | } else { | ||
859 | for (i = 0; i < rf; i++) | ||
860 | rtlpriv->dm.ofdm_index[i] += delta; | ||
861 | rtlpriv->dm.cck_index += delta; | ||
862 | } | ||
863 | |||
864 | if (is2t) { | ||
865 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | ||
866 | ("temp OFDM_A_index=0x%x, " | ||
867 | "OFDM_B_index=0x%x," | ||
868 | "cck_index=0x%x\n", | ||
869 | rtlpriv->dm.ofdm_index[0], | ||
870 | rtlpriv->dm.ofdm_index[1], | ||
871 | rtlpriv->dm.cck_index)); | ||
872 | } else { | ||
873 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | ||
874 | ("temp OFDM_A_index=0x%x," | ||
875 | "cck_index=0x%x\n", | ||
876 | rtlpriv->dm.ofdm_index[0], | ||
877 | rtlpriv->dm.cck_index)); | ||
878 | } | ||
879 | |||
880 | if (thermalvalue > rtlefuse->eeprom_thermalmeter) { | ||
881 | for (i = 0; i < rf; i++) | ||
882 | ofdm_index[i] = | ||
883 | rtlpriv->dm.ofdm_index[i] | ||
884 | + 1; | ||
885 | cck_index = rtlpriv->dm.cck_index + 1; | ||
886 | } else { | ||
887 | for (i = 0; i < rf; i++) | ||
888 | ofdm_index[i] = | ||
889 | rtlpriv->dm.ofdm_index[i]; | ||
890 | cck_index = rtlpriv->dm.cck_index; | ||
891 | } | ||
892 | |||
893 | for (i = 0; i < rf; i++) { | ||
894 | if (txpwr_level[i] >= 0 && | ||
895 | txpwr_level[i] <= 26) { | ||
896 | if (thermalvalue > | ||
897 | rtlefuse->eeprom_thermalmeter) { | ||
898 | if (delta < 5) | ||
899 | ofdm_index[i] -= 1; | ||
900 | |||
901 | else | ||
902 | ofdm_index[i] -= 2; | ||
903 | } else if (delta > 5 && thermalvalue < | ||
904 | rtlefuse-> | ||
905 | eeprom_thermalmeter) { | ||
906 | ofdm_index[i] += 1; | ||
907 | } | ||
908 | } else if (txpwr_level[i] >= 27 && | ||
909 | txpwr_level[i] <= 32 | ||
910 | && thermalvalue > | ||
911 | rtlefuse->eeprom_thermalmeter) { | ||
912 | if (delta < 5) | ||
913 | ofdm_index[i] -= 1; | ||
914 | |||
915 | else | ||
916 | ofdm_index[i] -= 2; | ||
917 | } else if (txpwr_level[i] >= 32 && | ||
918 | txpwr_level[i] <= 38 && | ||
919 | thermalvalue > | ||
920 | rtlefuse->eeprom_thermalmeter | ||
921 | && delta > 5) { | ||
922 | ofdm_index[i] -= 1; | ||
923 | } | ||
924 | } | ||
925 | |||
926 | if (txpwr_level[i] >= 0 && txpwr_level[i] <= 26) { | ||
927 | if (thermalvalue > | ||
928 | rtlefuse->eeprom_thermalmeter) { | ||
929 | if (delta < 5) | ||
930 | cck_index -= 1; | ||
931 | |||
932 | else | ||
933 | cck_index -= 2; | ||
934 | } else if (delta > 5 && thermalvalue < | ||
935 | rtlefuse->eeprom_thermalmeter) { | ||
936 | cck_index += 1; | ||
937 | } | ||
938 | } else if (txpwr_level[i] >= 27 && | ||
939 | txpwr_level[i] <= 32 && | ||
940 | thermalvalue > | ||
941 | rtlefuse->eeprom_thermalmeter) { | ||
942 | if (delta < 5) | ||
943 | cck_index -= 1; | ||
944 | |||
945 | else | ||
946 | cck_index -= 2; | ||
947 | } else if (txpwr_level[i] >= 32 && | ||
948 | txpwr_level[i] <= 38 && | ||
949 | thermalvalue > rtlefuse->eeprom_thermalmeter | ||
950 | && delta > 5) { | ||
951 | cck_index -= 1; | ||
952 | } | ||
953 | |||
954 | for (i = 0; i < rf; i++) { | ||
955 | if (ofdm_index[i] > OFDM_TABLE_SIZE - 1) | ||
956 | ofdm_index[i] = OFDM_TABLE_SIZE - 1; | ||
957 | |||
958 | else if (ofdm_index[i] < ofdm_min_index) | ||
959 | ofdm_index[i] = ofdm_min_index; | ||
960 | } | ||
961 | |||
962 | if (cck_index > CCK_TABLE_SIZE - 1) | ||
963 | cck_index = CCK_TABLE_SIZE - 1; | ||
964 | else if (cck_index < 0) | ||
965 | cck_index = 0; | ||
966 | |||
967 | if (is2t) { | ||
968 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | ||
969 | ("new OFDM_A_index=0x%x, " | ||
970 | "OFDM_B_index=0x%x," | ||
971 | "cck_index=0x%x\n", | ||
972 | ofdm_index[0], ofdm_index[1], | ||
973 | cck_index)); | ||
974 | } else { | ||
975 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | ||
976 | ("new OFDM_A_index=0x%x," | ||
977 | "cck_index=0x%x\n", | ||
978 | ofdm_index[0], cck_index)); | ||
979 | } | ||
980 | } | ||
981 | |||
982 | if (rtlpriv->dm.txpower_track_control && delta != 0) { | ||
983 | ele_d = | ||
984 | (ofdmswing_table[ofdm_index[0]] & 0xFFC00000) >> 22; | ||
985 | val_x = rtlphy->reg_e94; | ||
986 | val_y = rtlphy->reg_e9c; | ||
987 | |||
988 | if (val_x != 0) { | ||
989 | if ((val_x & 0x00000200) != 0) | ||
990 | val_x = val_x | 0xFFFFFC00; | ||
991 | ele_a = ((val_x * ele_d) >> 8) & 0x000003FF; | ||
992 | |||
993 | if ((val_y & 0x00000200) != 0) | ||
994 | val_y = val_y | 0xFFFFFC00; | ||
995 | ele_c = ((val_y * ele_d) >> 8) & 0x000003FF; | ||
996 | |||
997 | value32 = (ele_d << 22) | | ||
998 | ((ele_c & 0x3F) << 16) | ele_a; | ||
999 | |||
1000 | rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, | ||
1001 | MASKDWORD, value32); | ||
1002 | |||
1003 | value32 = (ele_c & 0x000003C0) >> 6; | ||
1004 | rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, | ||
1005 | value32); | ||
1006 | |||
1007 | value32 = ((val_x * ele_d) >> 7) & 0x01; | ||
1008 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, | ||
1009 | BIT(31), value32); | ||
1010 | |||
1011 | value32 = ((val_y * ele_d) >> 7) & 0x01; | ||
1012 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, | ||
1013 | BIT(29), value32); | ||
1014 | } else { | ||
1015 | rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, | ||
1016 | MASKDWORD, | ||
1017 | ofdmswing_table[ofdm_index[0]]); | ||
1018 | |||
1019 | rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, | ||
1020 | 0x00); | ||
1021 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, | ||
1022 | BIT(31) | BIT(29), 0x00); | ||
1023 | } | ||
1024 | |||
1025 | if (!rtlpriv->dm.b_cck_inch14) { | ||
1026 | rtl_write_byte(rtlpriv, 0xa22, | ||
1027 | cckswing_table_ch1ch13[cck_index] | ||
1028 | [0]); | ||
1029 | rtl_write_byte(rtlpriv, 0xa23, | ||
1030 | cckswing_table_ch1ch13[cck_index] | ||
1031 | [1]); | ||
1032 | rtl_write_byte(rtlpriv, 0xa24, | ||
1033 | cckswing_table_ch1ch13[cck_index] | ||
1034 | [2]); | ||
1035 | rtl_write_byte(rtlpriv, 0xa25, | ||
1036 | cckswing_table_ch1ch13[cck_index] | ||
1037 | [3]); | ||
1038 | rtl_write_byte(rtlpriv, 0xa26, | ||
1039 | cckswing_table_ch1ch13[cck_index] | ||
1040 | [4]); | ||
1041 | rtl_write_byte(rtlpriv, 0xa27, | ||
1042 | cckswing_table_ch1ch13[cck_index] | ||
1043 | [5]); | ||
1044 | rtl_write_byte(rtlpriv, 0xa28, | ||
1045 | cckswing_table_ch1ch13[cck_index] | ||
1046 | [6]); | ||
1047 | rtl_write_byte(rtlpriv, 0xa29, | ||
1048 | cckswing_table_ch1ch13[cck_index] | ||
1049 | [7]); | ||
1050 | } else { | ||
1051 | rtl_write_byte(rtlpriv, 0xa22, | ||
1052 | cckswing_table_ch14[cck_index] | ||
1053 | [0]); | ||
1054 | rtl_write_byte(rtlpriv, 0xa23, | ||
1055 | cckswing_table_ch14[cck_index] | ||
1056 | [1]); | ||
1057 | rtl_write_byte(rtlpriv, 0xa24, | ||
1058 | cckswing_table_ch14[cck_index] | ||
1059 | [2]); | ||
1060 | rtl_write_byte(rtlpriv, 0xa25, | ||
1061 | cckswing_table_ch14[cck_index] | ||
1062 | [3]); | ||
1063 | rtl_write_byte(rtlpriv, 0xa26, | ||
1064 | cckswing_table_ch14[cck_index] | ||
1065 | [4]); | ||
1066 | rtl_write_byte(rtlpriv, 0xa27, | ||
1067 | cckswing_table_ch14[cck_index] | ||
1068 | [5]); | ||
1069 | rtl_write_byte(rtlpriv, 0xa28, | ||
1070 | cckswing_table_ch14[cck_index] | ||
1071 | [6]); | ||
1072 | rtl_write_byte(rtlpriv, 0xa29, | ||
1073 | cckswing_table_ch14[cck_index] | ||
1074 | [7]); | ||
1075 | } | ||
1076 | |||
1077 | if (is2t) { | ||
1078 | ele_d = (ofdmswing_table[ofdm_index[1]] & | ||
1079 | 0xFFC00000) >> 22; | ||
1080 | |||
1081 | val_x = rtlphy->reg_eb4; | ||
1082 | val_y = rtlphy->reg_ebc; | ||
1083 | |||
1084 | if (val_x != 0) { | ||
1085 | if ((val_x & 0x00000200) != 0) | ||
1086 | val_x = val_x | 0xFFFFFC00; | ||
1087 | ele_a = ((val_x * ele_d) >> 8) & | ||
1088 | 0x000003FF; | ||
1089 | |||
1090 | if ((val_y & 0x00000200) != 0) | ||
1091 | val_y = val_y | 0xFFFFFC00; | ||
1092 | ele_c = ((val_y * ele_d) >> 8) & | ||
1093 | 0x00003FF; | ||
1094 | |||
1095 | value32 = (ele_d << 22) | | ||
1096 | ((ele_c & 0x3F) << 16) | ele_a; | ||
1097 | rtl_set_bbreg(hw, | ||
1098 | ROFDM0_XBTXIQIMBALANCE, | ||
1099 | MASKDWORD, value32); | ||
1100 | |||
1101 | value32 = (ele_c & 0x000003C0) >> 6; | ||
1102 | rtl_set_bbreg(hw, ROFDM0_XDTXAFE, | ||
1103 | MASKH4BITS, value32); | ||
1104 | |||
1105 | value32 = ((val_x * ele_d) >> 7) & 0x01; | ||
1106 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, | ||
1107 | BIT(27), value32); | ||
1108 | |||
1109 | value32 = ((val_y * ele_d) >> 7) & 0x01; | ||
1110 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, | ||
1111 | BIT(25), value32); | ||
1112 | } else { | ||
1113 | rtl_set_bbreg(hw, | ||
1114 | ROFDM0_XBTXIQIMBALANCE, | ||
1115 | MASKDWORD, | ||
1116 | ofdmswing_table[ofdm_index | ||
1117 | [1]]); | ||
1118 | rtl_set_bbreg(hw, ROFDM0_XDTXAFE, | ||
1119 | MASKH4BITS, 0x00); | ||
1120 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, | ||
1121 | BIT(27) | BIT(25), 0x00); | ||
1122 | } | ||
1123 | |||
1124 | } | ||
1125 | } | ||
1126 | |||
1127 | if (delta_iqk > 3) { | ||
1128 | rtlpriv->dm.thermalvalue_iqk = thermalvalue; | ||
1129 | rtl92c_phy_iq_calibrate(hw, false); | ||
1130 | } | ||
1131 | |||
1132 | if (rtlpriv->dm.txpower_track_control) | ||
1133 | rtlpriv->dm.thermalvalue = thermalvalue; | ||
1134 | } | ||
1135 | |||
1136 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("<===\n")); | ||
1137 | |||
1138 | } | ||
1139 | |||
1140 | static void rtl92c_dm_initialize_txpower_tracking_thermalmeter( | ||
1141 | struct ieee80211_hw *hw) | ||
1142 | { | ||
1143 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1144 | |||
1145 | rtlpriv->dm.btxpower_tracking = true; | ||
1146 | rtlpriv->dm.btxpower_trackingInit = false; | ||
1147 | |||
1148 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | ||
1149 | ("pMgntInfo->btxpower_tracking = %d\n", | ||
1150 | rtlpriv->dm.btxpower_tracking)); | ||
1151 | } | ||
1152 | |||
1153 | static void rtl92c_dm_initialize_txpower_tracking(struct ieee80211_hw *hw) | ||
1154 | { | ||
1155 | rtl92c_dm_initialize_txpower_tracking_thermalmeter(hw); | ||
1156 | } | ||
1157 | |||
1158 | static void rtl92c_dm_txpower_tracking_directcall(struct ieee80211_hw *hw) | ||
1159 | { | ||
1160 | rtl92c_dm_txpower_tracking_callback_thermalmeter(hw); | ||
1161 | } | ||
1162 | |||
1163 | static void rtl92c_dm_check_txpower_tracking_thermal_meter( | ||
1164 | struct ieee80211_hw *hw) | ||
1165 | { | ||
1166 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1167 | static u8 tm_trigger; | ||
1168 | |||
1169 | if (!rtlpriv->dm.btxpower_tracking) | ||
1170 | return; | ||
1171 | |||
1172 | if (!tm_trigger) { | ||
1173 | rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, RFREG_OFFSET_MASK, | ||
1174 | 0x60); | ||
1175 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | ||
1176 | ("Trigger 92S Thermal Meter!!\n")); | ||
1177 | tm_trigger = 1; | ||
1178 | return; | ||
1179 | } else { | ||
1180 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | ||
1181 | ("Schedule TxPowerTracking direct call!!\n")); | ||
1182 | rtl92c_dm_txpower_tracking_directcall(hw); | ||
1183 | tm_trigger = 0; | ||
1184 | } | ||
1185 | } | ||
1186 | |||
1187 | void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw) | ||
1188 | { | ||
1189 | rtl92c_dm_check_txpower_tracking_thermal_meter(hw); | ||
1190 | } | ||
1191 | |||
1192 | void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) | ||
1193 | { | ||
1194 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1195 | struct rate_adaptive *p_ra = &(rtlpriv->ra); | ||
1196 | |||
1197 | p_ra->ratr_state = DM_RATR_STA_INIT; | ||
1198 | p_ra->pre_ratr_state = DM_RATR_STA_INIT; | ||
1199 | |||
1200 | if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) | ||
1201 | rtlpriv->dm.b_useramask = true; | ||
1202 | else | ||
1203 | rtlpriv->dm.b_useramask = false; | ||
1204 | |||
1205 | } | ||
1206 | |||
1207 | static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) | ||
1208 | { | ||
1209 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1210 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1211 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
1212 | struct rate_adaptive *p_ra = &(rtlpriv->ra); | ||
1213 | u32 low_rssithresh_for_ra, high_rssithresh_for_ra; | ||
1214 | |||
1215 | if (is_hal_stop(rtlhal)) { | ||
1216 | RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, | ||
1217 | ("<---- driver is going to unload\n")); | ||
1218 | return; | ||
1219 | } | ||
1220 | |||
1221 | if (!rtlpriv->dm.b_useramask) { | ||
1222 | RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, | ||
1223 | ("<---- driver does not control rate adaptive mask\n")); | ||
1224 | return; | ||
1225 | } | ||
1226 | |||
1227 | if (mac->link_state == MAC80211_LINKED) { | ||
1228 | |||
1229 | switch (p_ra->pre_ratr_state) { | ||
1230 | case DM_RATR_STA_HIGH: | ||
1231 | high_rssithresh_for_ra = 50; | ||
1232 | low_rssithresh_for_ra = 20; | ||
1233 | break; | ||
1234 | case DM_RATR_STA_MIDDLE: | ||
1235 | high_rssithresh_for_ra = 55; | ||
1236 | low_rssithresh_for_ra = 20; | ||
1237 | break; | ||
1238 | case DM_RATR_STA_LOW: | ||
1239 | high_rssithresh_for_ra = 50; | ||
1240 | low_rssithresh_for_ra = 25; | ||
1241 | break; | ||
1242 | default: | ||
1243 | high_rssithresh_for_ra = 50; | ||
1244 | low_rssithresh_for_ra = 20; | ||
1245 | break; | ||
1246 | } | ||
1247 | |||
1248 | if (rtlpriv->dm.undecorated_smoothed_pwdb > | ||
1249 | (long)high_rssithresh_for_ra) | ||
1250 | p_ra->ratr_state = DM_RATR_STA_HIGH; | ||
1251 | else if (rtlpriv->dm.undecorated_smoothed_pwdb > | ||
1252 | (long)low_rssithresh_for_ra) | ||
1253 | p_ra->ratr_state = DM_RATR_STA_MIDDLE; | ||
1254 | else | ||
1255 | p_ra->ratr_state = DM_RATR_STA_LOW; | ||
1256 | |||
1257 | if (p_ra->pre_ratr_state != p_ra->ratr_state) { | ||
1258 | RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, | ||
1259 | ("RSSI = %ld\n", | ||
1260 | rtlpriv->dm.undecorated_smoothed_pwdb)); | ||
1261 | RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, | ||
1262 | ("RSSI_LEVEL = %d\n", p_ra->ratr_state)); | ||
1263 | RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, | ||
1264 | ("PreState = %d, CurState = %d\n", | ||
1265 | p_ra->pre_ratr_state, p_ra->ratr_state)); | ||
1266 | |||
1267 | rtlpriv->cfg->ops->update_rate_mask(hw, | ||
1268 | p_ra->ratr_state); | ||
1269 | |||
1270 | p_ra->pre_ratr_state = p_ra->ratr_state; | ||
1271 | } | ||
1272 | } | ||
1273 | } | ||
1274 | |||
1275 | static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw) | ||
1276 | { | ||
1277 | dm_pstable.pre_ccastate = CCA_MAX; | ||
1278 | dm_pstable.cur_ccasate = CCA_MAX; | ||
1279 | dm_pstable.pre_rfstate = RF_MAX; | ||
1280 | dm_pstable.cur_rfstate = RF_MAX; | ||
1281 | dm_pstable.rssi_val_min = 0; | ||
1282 | } | ||
1283 | |||
1284 | static void rtl92c_dm_1r_cca(struct ieee80211_hw *hw) | ||
1285 | { | ||
1286 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1287 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1288 | |||
1289 | if (dm_pstable.rssi_val_min != 0) { | ||
1290 | if (dm_pstable.pre_ccastate == CCA_2R) { | ||
1291 | if (dm_pstable.rssi_val_min >= 35) | ||
1292 | dm_pstable.cur_ccasate = CCA_1R; | ||
1293 | else | ||
1294 | dm_pstable.cur_ccasate = CCA_2R; | ||
1295 | } else { | ||
1296 | if (dm_pstable.rssi_val_min <= 30) | ||
1297 | dm_pstable.cur_ccasate = CCA_2R; | ||
1298 | else | ||
1299 | dm_pstable.cur_ccasate = CCA_1R; | ||
1300 | } | ||
1301 | } else { | ||
1302 | dm_pstable.cur_ccasate = CCA_MAX; | ||
1303 | } | ||
1304 | |||
1305 | if (dm_pstable.pre_ccastate != dm_pstable.cur_ccasate) { | ||
1306 | if (dm_pstable.cur_ccasate == CCA_1R) { | ||
1307 | if (get_rf_type(rtlphy) == RF_2T2R) { | ||
1308 | rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, | ||
1309 | MASKBYTE0, 0x13); | ||
1310 | rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x20); | ||
1311 | } else { | ||
1312 | rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, | ||
1313 | MASKBYTE0, 0x23); | ||
1314 | rtl_set_bbreg(hw, 0xe70, 0x7fc00000, 0x10c); | ||
1315 | } | ||
1316 | } else { | ||
1317 | rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, | ||
1318 | 0x33); | ||
1319 | rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x63); | ||
1320 | } | ||
1321 | dm_pstable.pre_ccastate = dm_pstable.cur_ccasate; | ||
1322 | } | ||
1323 | |||
1324 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, ("CCAStage = %s\n", | ||
1325 | (dm_pstable.cur_ccasate == | ||
1326 | 0) ? "1RCCA" : "2RCCA")); | ||
1327 | } | ||
1328 | |||
1329 | void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal) | ||
1330 | { | ||
1331 | static u8 initialize; | ||
1332 | static u32 reg_874, reg_c70, reg_85c, reg_a74; | ||
1333 | |||
1334 | if (initialize == 0) { | ||
1335 | reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, | ||
1336 | MASKDWORD) & 0x1CC000) >> 14; | ||
1337 | |||
1338 | reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1, | ||
1339 | MASKDWORD) & BIT(3)) >> 3; | ||
1340 | |||
1341 | reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, | ||
1342 | MASKDWORD) & 0xFF000000) >> 24; | ||
1343 | |||
1344 | reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & 0xF000) >> 12; | ||
1345 | |||
1346 | initialize = 1; | ||
1347 | } | ||
1348 | |||
1349 | if (!bforce_in_normal) { | ||
1350 | if (dm_pstable.rssi_val_min != 0) { | ||
1351 | if (dm_pstable.pre_rfstate == RF_NORMAL) { | ||
1352 | if (dm_pstable.rssi_val_min >= 30) | ||
1353 | dm_pstable.cur_rfstate = RF_SAVE; | ||
1354 | else | ||
1355 | dm_pstable.cur_rfstate = RF_NORMAL; | ||
1356 | } else { | ||
1357 | if (dm_pstable.rssi_val_min <= 25) | ||
1358 | dm_pstable.cur_rfstate = RF_NORMAL; | ||
1359 | else | ||
1360 | dm_pstable.cur_rfstate = RF_SAVE; | ||
1361 | } | ||
1362 | } else { | ||
1363 | dm_pstable.cur_rfstate = RF_MAX; | ||
1364 | } | ||
1365 | } else { | ||
1366 | dm_pstable.cur_rfstate = RF_NORMAL; | ||
1367 | } | ||
1368 | |||
1369 | if (dm_pstable.pre_rfstate != dm_pstable.cur_rfstate) { | ||
1370 | if (dm_pstable.cur_rfstate == RF_SAVE) { | ||
1371 | rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, | ||
1372 | 0x1C0000, 0x2); | ||
1373 | rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 0); | ||
1374 | rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, | ||
1375 | 0xFF000000, 0x63); | ||
1376 | rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, | ||
1377 | 0xC000, 0x2); | ||
1378 | rtl_set_bbreg(hw, 0xa74, 0xF000, 0x3); | ||
1379 | rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); | ||
1380 | rtl_set_bbreg(hw, 0x818, BIT(28), 0x1); | ||
1381 | } else { | ||
1382 | rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, | ||
1383 | 0x1CC000, reg_874); | ||
1384 | rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), | ||
1385 | reg_c70); | ||
1386 | rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000, | ||
1387 | reg_85c); | ||
1388 | rtl_set_bbreg(hw, 0xa74, 0xF000, reg_a74); | ||
1389 | rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); | ||
1390 | } | ||
1391 | |||
1392 | dm_pstable.pre_rfstate = dm_pstable.cur_rfstate; | ||
1393 | } | ||
1394 | } | ||
1395 | |||
1396 | static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw) | ||
1397 | { | ||
1398 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1399 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
1400 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1401 | |||
1402 | if (((mac->link_state == MAC80211_NOLINK)) && | ||
1403 | (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { | ||
1404 | dm_pstable.rssi_val_min = 0; | ||
1405 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, | ||
1406 | ("Not connected to any\n")); | ||
1407 | } | ||
1408 | |||
1409 | if (mac->link_state == MAC80211_LINKED) { | ||
1410 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { | ||
1411 | dm_pstable.rssi_val_min = | ||
1412 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | ||
1413 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, | ||
1414 | ("AP Client PWDB = 0x%lx\n", | ||
1415 | dm_pstable.rssi_val_min)); | ||
1416 | } else { | ||
1417 | dm_pstable.rssi_val_min = | ||
1418 | rtlpriv->dm.undecorated_smoothed_pwdb; | ||
1419 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, | ||
1420 | ("STA Default Port PWDB = 0x%lx\n", | ||
1421 | dm_pstable.rssi_val_min)); | ||
1422 | } | ||
1423 | } else { | ||
1424 | dm_pstable.rssi_val_min = | ||
1425 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | ||
1426 | |||
1427 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, | ||
1428 | ("AP Ext Port PWDB = 0x%lx\n", | ||
1429 | dm_pstable.rssi_val_min)); | ||
1430 | } | ||
1431 | |||
1432 | if (IS_92C_SERIAL(rtlhal->version)) | ||
1433 | rtl92c_dm_1r_cca(hw); | ||
1434 | } | ||
1435 | |||
1436 | void rtl92c_dm_init(struct ieee80211_hw *hw) | ||
1437 | { | ||
1438 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1439 | |||
1440 | rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; | ||
1441 | rtl92c_dm_diginit(hw); | ||
1442 | rtl92c_dm_init_dynamic_txpower(hw); | ||
1443 | rtl92c_dm_init_edca_turbo(hw); | ||
1444 | rtl92c_dm_init_rate_adaptive_mask(hw); | ||
1445 | rtl92c_dm_initialize_txpower_tracking(hw); | ||
1446 | rtl92c_dm_init_dynamic_bb_powersaving(hw); | ||
1447 | } | ||
1448 | |||
1449 | void rtl92c_dm_watchdog(struct ieee80211_hw *hw) | ||
1450 | { | ||
1451 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1452 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
1453 | bool b_fw_current_inpsmode = false; | ||
1454 | bool b_fw_ps_awake = true; | ||
1455 | |||
1456 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, | ||
1457 | (u8 *) (&b_fw_current_inpsmode)); | ||
1458 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, | ||
1459 | (u8 *) (&b_fw_ps_awake)); | ||
1460 | |||
1461 | if ((ppsc->rfpwr_state == ERFON) && ((!b_fw_current_inpsmode) && | ||
1462 | b_fw_ps_awake) | ||
1463 | && (!ppsc->rfchange_inprogress)) { | ||
1464 | rtl92c_dm_pwdb_monitor(hw); | ||
1465 | rtl92c_dm_dig(hw); | ||
1466 | rtl92c_dm_false_alarm_counter_statistics(hw); | ||
1467 | rtl92c_dm_dynamic_bb_powersaving(hw); | ||
1468 | rtl92c_dm_dynamic_txpower(hw); | ||
1469 | rtl92c_dm_check_txpower_tracking(hw); | ||
1470 | rtl92c_dm_refresh_rate_adaptive_mask(hw); | ||
1471 | rtl92c_dm_check_edca_turbo(hw); | ||
1472 | } | ||
1473 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h index 463439e4074c..5911d52a24ac 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h | |||
@@ -192,5 +192,6 @@ void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw); | |||
192 | void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw); | 192 | void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw); |
193 | void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw); | 193 | void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw); |
194 | void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal); | 194 | void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal); |
195 | void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw); | ||
195 | 196 | ||
196 | #endif | 197 | #endif |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/fw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/fw.c index 11dd22b987e7..11c8bdb4af59 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/fw.c | |||
@@ -133,17 +133,15 @@ static void _rtl92c_write_fw(struct ieee80211_hw *hw, | |||
133 | { | 133 | { |
134 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 134 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
135 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 135 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
136 | bool is_version_b; | ||
137 | u8 *bufferPtr = (u8 *) buffer; | 136 | u8 *bufferPtr = (u8 *) buffer; |
138 | 137 | ||
139 | RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size)); | 138 | RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size)); |
140 | 139 | ||
141 | is_version_b = IS_CHIP_VER_B(version); | 140 | if (IS_CHIP_VER_B(version)) { |
142 | if (is_version_b) { | ||
143 | u32 pageNums, remainSize; | 141 | u32 pageNums, remainSize; |
144 | u32 page, offset; | 142 | u32 page, offset; |
145 | 143 | ||
146 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE) | 144 | if (IS_HARDWARE_TYPE_8192CE(rtlhal)) |
147 | _rtl92c_fill_dummy(bufferPtr, &size); | 145 | _rtl92c_fill_dummy(bufferPtr, &size); |
148 | 146 | ||
149 | pageNums = size / FW_8192C_PAGE_SIZE; | 147 | pageNums = size / FW_8192C_PAGE_SIZE; |
@@ -231,14 +229,14 @@ int rtl92c_download_fw(struct ieee80211_hw *hw) | |||
231 | u32 fwsize; | 229 | u32 fwsize; |
232 | int err; | 230 | int err; |
233 | enum version_8192c version = rtlhal->version; | 231 | enum version_8192c version = rtlhal->version; |
232 | const struct firmware *firmware; | ||
234 | 233 | ||
235 | const struct firmware *firmware = NULL; | 234 | printk(KERN_INFO "rtl8192cu: Loading firmware file %s\n", |
236 | 235 | rtlpriv->cfg->fw_name); | |
237 | err = request_firmware(&firmware, rtlpriv->cfg->fw_name, | 236 | err = request_firmware(&firmware, rtlpriv->cfg->fw_name, |
238 | rtlpriv->io.dev); | 237 | rtlpriv->io.dev); |
239 | if (err) { | 238 | if (err) { |
240 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | 239 | printk(KERN_ERR "rtl8192cu: Firmware loading failed\n"); |
241 | ("Failed to request firmware!\n")); | ||
242 | return 1; | 240 | return 1; |
243 | } | 241 | } |
244 | 242 | ||
@@ -318,12 +316,12 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, | |||
318 | 316 | ||
319 | while (true) { | 317 | while (true) { |
320 | spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); | 318 | spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); |
321 | if (rtlhal->b_h2c_setinprogress) { | 319 | if (rtlhal->h2c_setinprogress) { |
322 | RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, | 320 | RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, |
323 | ("H2C set in progress! Wait to set.." | 321 | ("H2C set in progress! Wait to set.." |
324 | "element_id(%d).\n", element_id)); | 322 | "element_id(%d).\n", element_id)); |
325 | 323 | ||
326 | while (rtlhal->b_h2c_setinprogress) { | 324 | while (rtlhal->h2c_setinprogress) { |
327 | spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, | 325 | spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, |
328 | flag); | 326 | flag); |
329 | h2c_waitcounter++; | 327 | h2c_waitcounter++; |
@@ -339,7 +337,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, | |||
339 | } | 337 | } |
340 | spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); | 338 | spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); |
341 | } else { | 339 | } else { |
342 | rtlhal->b_h2c_setinprogress = true; | 340 | rtlhal->h2c_setinprogress = true; |
343 | spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); | 341 | spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); |
344 | break; | 342 | break; |
345 | } | 343 | } |
@@ -495,7 +493,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, | |||
495 | } | 493 | } |
496 | 494 | ||
497 | spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); | 495 | spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); |
498 | rtlhal->b_h2c_setinprogress = false; | 496 | rtlhal->h2c_setinprogress = false; |
499 | spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); | 497 | spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); |
500 | 498 | ||
501 | RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n")); | 499 | RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n")); |
@@ -507,7 +505,7 @@ void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, | |||
507 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 505 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
508 | u32 tmp_cmdbuf[2]; | 506 | u32 tmp_cmdbuf[2]; |
509 | 507 | ||
510 | if (rtlhal->bfw_ready == false) { | 508 | if (rtlhal->fw_ready == false) { |
511 | RT_ASSERT(false, ("return H2C cmd because of Fw " | 509 | RT_ASSERT(false, ("return H2C cmd because of Fw " |
512 | "download fail!!!\n")); | 510 | "download fail!!!\n")); |
513 | return; | 511 | return; |
@@ -560,39 +558,6 @@ void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) | |||
560 | 558 | ||
561 | } | 559 | } |
562 | 560 | ||
563 | static bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, | ||
564 | struct sk_buff *skb) | ||
565 | { | ||
566 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
567 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
568 | struct rtl8192_tx_ring *ring; | ||
569 | struct rtl_tx_desc *pdesc; | ||
570 | u8 own; | ||
571 | unsigned long flags; | ||
572 | struct sk_buff *pskb = NULL; | ||
573 | |||
574 | ring = &rtlpci->tx_ring[BEACON_QUEUE]; | ||
575 | |||
576 | pskb = __skb_dequeue(&ring->queue); | ||
577 | if (pskb) | ||
578 | kfree_skb(pskb); | ||
579 | |||
580 | spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); | ||
581 | |||
582 | pdesc = &ring->desc[0]; | ||
583 | own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN); | ||
584 | |||
585 | rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb); | ||
586 | |||
587 | __skb_queue_tail(&ring->queue, skb); | ||
588 | |||
589 | spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); | ||
590 | |||
591 | rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE); | ||
592 | |||
593 | return true; | ||
594 | } | ||
595 | |||
596 | #define BEACON_PG 0 /*->1*/ | 561 | #define BEACON_PG 0 /*->1*/ |
597 | #define PSPOLL_PG 2 | 562 | #define PSPOLL_PG 2 |
598 | #define NULL_PG 3 | 563 | #define NULL_PG 3 |
@@ -776,7 +741,7 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished) | |||
776 | memcpy((u8 *) skb_put(skb, totalpacketlen), | 741 | memcpy((u8 *) skb_put(skb, totalpacketlen), |
777 | &reserved_page_packet, totalpacketlen); | 742 | &reserved_page_packet, totalpacketlen); |
778 | 743 | ||
779 | rtstatus = _rtl92c_cmd_send_packet(hw, skb); | 744 | rtstatus = rtlpriv->cfg->ops->cmd_send_packet(hw, skb); |
780 | 745 | ||
781 | if (rtstatus) | 746 | if (rtstatus) |
782 | b_dlok = true; | 747 | b_dlok = true; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index 1c41a0c93506..0b910921e606 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | |||
@@ -124,7 +124,7 @@ void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
124 | break; | 124 | break; |
125 | } | 125 | } |
126 | case HW_VAR_FW_PSMODE_STATUS: | 126 | case HW_VAR_FW_PSMODE_STATUS: |
127 | *((bool *) (val)) = ppsc->b_fw_current_inpsmode; | 127 | *((bool *) (val)) = ppsc->fw_current_inpsmode; |
128 | break; | 128 | break; |
129 | case HW_VAR_CORRECT_TSF:{ | 129 | case HW_VAR_CORRECT_TSF:{ |
130 | u64 tsf; | 130 | u64 tsf; |
@@ -173,15 +173,15 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
173 | break; | 173 | break; |
174 | } | 174 | } |
175 | case HW_VAR_BASIC_RATE:{ | 175 | case HW_VAR_BASIC_RATE:{ |
176 | u16 b_rate_cfg = ((u16 *) val)[0]; | 176 | u16 rate_cfg = ((u16 *) val)[0]; |
177 | u8 rate_index = 0; | 177 | u8 rate_index = 0; |
178 | b_rate_cfg = b_rate_cfg & 0x15f; | 178 | rate_cfg &= 0x15f; |
179 | b_rate_cfg |= 0x01; | 179 | rate_cfg |= 0x01; |
180 | rtl_write_byte(rtlpriv, REG_RRSR, b_rate_cfg & 0xff); | 180 | rtl_write_byte(rtlpriv, REG_RRSR, rate_cfg & 0xff); |
181 | rtl_write_byte(rtlpriv, REG_RRSR + 1, | 181 | rtl_write_byte(rtlpriv, REG_RRSR + 1, |
182 | (b_rate_cfg >> 8)&0xff); | 182 | (rate_cfg >> 8)&0xff); |
183 | while (b_rate_cfg > 0x1) { | 183 | while (rate_cfg > 0x1) { |
184 | b_rate_cfg = (b_rate_cfg >> 1); | 184 | rate_cfg = (rate_cfg >> 1); |
185 | rate_index++; | 185 | rate_index++; |
186 | } | 186 | } |
187 | rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, | 187 | rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, |
@@ -318,15 +318,17 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
318 | } | 318 | } |
319 | case HW_VAR_AC_PARAM:{ | 319 | case HW_VAR_AC_PARAM:{ |
320 | u8 e_aci = *((u8 *) val); | 320 | u8 e_aci = *((u8 *) val); |
321 | u32 u4b_ac_param = 0; | 321 | u32 u4b_ac_param; |
322 | u16 cw_min = le16_to_cpu(mac->ac[e_aci].cw_min); | ||
323 | u16 cw_max = le16_to_cpu(mac->ac[e_aci].cw_max); | ||
324 | u16 tx_op = le16_to_cpu(mac->ac[e_aci].tx_op); | ||
322 | 325 | ||
323 | u4b_ac_param |= (u32) mac->ac[e_aci].aifs; | 326 | u4b_ac_param = (u32) mac->ac[e_aci].aifs; |
324 | u4b_ac_param |= ((u32) mac->ac[e_aci].cw_min | 327 | u4b_ac_param |= ((u32)cw_min |
325 | & 0xF) << AC_PARAM_ECW_MIN_OFFSET; | 328 | & 0xF) << AC_PARAM_ECW_MIN_OFFSET; |
326 | u4b_ac_param |= ((u32) mac->ac[e_aci].cw_max & | 329 | u4b_ac_param |= ((u32)cw_max & |
327 | 0xF) << AC_PARAM_ECW_MAX_OFFSET; | 330 | 0xF) << AC_PARAM_ECW_MAX_OFFSET; |
328 | u4b_ac_param |= (u32) mac->ac[e_aci].tx_op | 331 | u4b_ac_param |= (u32)tx_op << AC_PARAM_TXOP_OFFSET; |
329 | << AC_PARAM_TXOP_LIMIT_OFFSET; | ||
330 | 332 | ||
331 | RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, | 333 | RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, |
332 | ("queue:%x, ac_param:%x\n", e_aci, | 334 | ("queue:%x, ac_param:%x\n", e_aci, |
@@ -469,12 +471,12 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
469 | break; | 471 | break; |
470 | } | 472 | } |
471 | case HW_VAR_FW_PSMODE_STATUS: | 473 | case HW_VAR_FW_PSMODE_STATUS: |
472 | ppsc->b_fw_current_inpsmode = *((bool *) val); | 474 | ppsc->fw_current_inpsmode = *((bool *) val); |
473 | break; | 475 | break; |
474 | case HW_VAR_H2C_FW_JOINBSSRPT:{ | 476 | case HW_VAR_H2C_FW_JOINBSSRPT:{ |
475 | u8 mstatus = (*(u8 *) val); | 477 | u8 mstatus = (*(u8 *) val); |
476 | u8 tmp_regcr, tmp_reg422; | 478 | u8 tmp_regcr, tmp_reg422; |
477 | bool b_recover = false; | 479 | bool recover = false; |
478 | 480 | ||
479 | if (mstatus == RT_MEDIA_CONNECT) { | 481 | if (mstatus == RT_MEDIA_CONNECT) { |
480 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, | 482 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, |
@@ -491,7 +493,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
491 | rtl_read_byte(rtlpriv, | 493 | rtl_read_byte(rtlpriv, |
492 | REG_FWHW_TXQ_CTRL + 2); | 494 | REG_FWHW_TXQ_CTRL + 2); |
493 | if (tmp_reg422 & BIT(6)) | 495 | if (tmp_reg422 & BIT(6)) |
494 | b_recover = true; | 496 | recover = true; |
495 | rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, | 497 | rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, |
496 | tmp_reg422 & (~BIT(6))); | 498 | tmp_reg422 & (~BIT(6))); |
497 | 499 | ||
@@ -500,7 +502,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | |||
500 | _rtl92ce_set_bcn_ctrl_reg(hw, BIT(3), 0); | 502 | _rtl92ce_set_bcn_ctrl_reg(hw, BIT(3), 0); |
501 | _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(4)); | 503 | _rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(4)); |
502 | 504 | ||
503 | if (b_recover) { | 505 | if (recover) { |
504 | rtl_write_byte(rtlpriv, | 506 | rtl_write_byte(rtlpriv, |
505 | REG_FWHW_TXQ_CTRL + 2, | 507 | REG_FWHW_TXQ_CTRL + 2, |
506 | tmp_reg422); | 508 | tmp_reg422); |
@@ -868,7 +870,7 @@ static void _rtl92ce_enable_aspm_back_door(struct ieee80211_hw *hw) | |||
868 | rtl_write_word(rtlpriv, 0x350, 0x870c); | 870 | rtl_write_word(rtlpriv, 0x350, 0x870c); |
869 | rtl_write_byte(rtlpriv, 0x352, 0x1); | 871 | rtl_write_byte(rtlpriv, 0x352, 0x1); |
870 | 872 | ||
871 | if (ppsc->b_support_backdoor) | 873 | if (ppsc->support_backdoor) |
872 | rtl_write_byte(rtlpriv, 0x349, 0x1b); | 874 | rtl_write_byte(rtlpriv, 0x349, 0x1b); |
873 | else | 875 | else |
874 | rtl_write_byte(rtlpriv, 0x349, 0x03); | 876 | rtl_write_byte(rtlpriv, 0x349, 0x03); |
@@ -940,10 +942,10 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) | |||
940 | ("Failed to download FW. Init HW " | 942 | ("Failed to download FW. Init HW " |
941 | "without FW now..\n")); | 943 | "without FW now..\n")); |
942 | err = 1; | 944 | err = 1; |
943 | rtlhal->bfw_ready = false; | 945 | rtlhal->fw_ready = false; |
944 | return err; | 946 | return err; |
945 | } else { | 947 | } else { |
946 | rtlhal->bfw_ready = true; | 948 | rtlhal->fw_ready = true; |
947 | } | 949 | } |
948 | 950 | ||
949 | rtlhal->last_hmeboxnum = 0; | 951 | rtlhal->last_hmeboxnum = 0; |
@@ -1170,21 +1172,20 @@ void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci) | |||
1170 | { | 1172 | { |
1171 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1173 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
1172 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 1174 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
1173 | |||
1174 | u32 u4b_ac_param; | 1175 | u32 u4b_ac_param; |
1176 | u16 cw_min = le16_to_cpu(mac->ac[aci].cw_min); | ||
1177 | u16 cw_max = le16_to_cpu(mac->ac[aci].cw_max); | ||
1178 | u16 tx_op = le16_to_cpu(mac->ac[aci].tx_op); | ||
1175 | 1179 | ||
1176 | rtl92c_dm_init_edca_turbo(hw); | 1180 | rtl92c_dm_init_edca_turbo(hw); |
1177 | |||
1178 | u4b_ac_param = (u32) mac->ac[aci].aifs; | 1181 | u4b_ac_param = (u32) mac->ac[aci].aifs; |
1179 | u4b_ac_param |= | 1182 | u4b_ac_param |= (u32) ((cw_min & 0xF) << AC_PARAM_ECW_MIN_OFFSET); |
1180 | ((u32) mac->ac[aci].cw_min & 0xF) << AC_PARAM_ECW_MIN_OFFSET; | 1183 | u4b_ac_param |= (u32) ((cw_max & 0xF) << AC_PARAM_ECW_MAX_OFFSET); |
1181 | u4b_ac_param |= | 1184 | u4b_ac_param |= (u32) (tx_op << AC_PARAM_TXOP_OFFSET); |
1182 | ((u32) mac->ac[aci].cw_max & 0xF) << AC_PARAM_ECW_MAX_OFFSET; | ||
1183 | u4b_ac_param |= (u32) mac->ac[aci].tx_op << AC_PARAM_TXOP_LIMIT_OFFSET; | ||
1184 | RT_TRACE(rtlpriv, COMP_QOS, DBG_DMESG, | 1185 | RT_TRACE(rtlpriv, COMP_QOS, DBG_DMESG, |
1185 | ("queue:%x, ac_param:%x aifs:%x cwmin:%x cwmax:%x txop:%x\n", | 1186 | ("queue:%x, ac_param:%x aifs:%x cwmin:%x cwmax:%x txop:%x\n", |
1186 | aci, u4b_ac_param, mac->ac[aci].aifs, mac->ac[aci].cw_min, | 1187 | aci, u4b_ac_param, mac->ac[aci].aifs, cw_min, |
1187 | mac->ac[aci].cw_max, mac->ac[aci].tx_op)); | 1188 | cw_max, tx_op)); |
1188 | switch (aci) { | 1189 | switch (aci) { |
1189 | case AC1_BK: | 1190 | case AC1_BK: |
1190 | rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, u4b_ac_param); | 1191 | rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, u4b_ac_param); |
@@ -1237,7 +1238,7 @@ static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw) | |||
1237 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); | 1238 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); |
1238 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); | 1239 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); |
1239 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE0); | 1240 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE0); |
1240 | if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && rtlhal->bfw_ready) | 1241 | if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && rtlhal->fw_ready) |
1241 | rtl92c_firmware_selfreset(hw); | 1242 | rtl92c_firmware_selfreset(hw); |
1242 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x51); | 1243 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x51); |
1243 | rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); | 1244 | rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); |
@@ -1335,19 +1336,6 @@ void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw, | |||
1335 | rtl92ce_enable_interrupt(hw); | 1336 | rtl92ce_enable_interrupt(hw); |
1336 | } | 1337 | } |
1337 | 1338 | ||
1338 | static u8 _rtl92c_get_chnl_group(u8 chnl) | ||
1339 | { | ||
1340 | u8 group; | ||
1341 | |||
1342 | if (chnl < 3) | ||
1343 | group = 0; | ||
1344 | else if (chnl < 9) | ||
1345 | group = 1; | ||
1346 | else | ||
1347 | group = 2; | ||
1348 | return group; | ||
1349 | } | ||
1350 | |||
1351 | static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, | 1339 | static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, |
1352 | bool autoload_fail, | 1340 | bool autoload_fail, |
1353 | u8 *hwinfo) | 1341 | u8 *hwinfo) |
@@ -1568,7 +1556,7 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, | |||
1568 | rtlefuse->eeprom_thermalmeter = (tempval & 0x1f); | 1556 | rtlefuse->eeprom_thermalmeter = (tempval & 0x1f); |
1569 | 1557 | ||
1570 | if (rtlefuse->eeprom_thermalmeter == 0x1f || autoload_fail) | 1558 | if (rtlefuse->eeprom_thermalmeter == 0x1f || autoload_fail) |
1571 | rtlefuse->b_apk_thermalmeterignore = true; | 1559 | rtlefuse->apk_thermalmeterignore = true; |
1572 | 1560 | ||
1573 | rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; | 1561 | rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; |
1574 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | 1562 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, |
@@ -1625,7 +1613,7 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw) | |||
1625 | 1613 | ||
1626 | rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; | 1614 | rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; |
1627 | rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; | 1615 | rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; |
1628 | rtlefuse->b_txpwr_fromeprom = true; | 1616 | rtlefuse->txpwr_fromeprom = true; |
1629 | rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; | 1617 | rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; |
1630 | 1618 | ||
1631 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, | 1619 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, |
@@ -1668,7 +1656,7 @@ static void _rtl92ce_hal_customized_behavior(struct ieee80211_hw *hw) | |||
1668 | 1656 | ||
1669 | switch (rtlhal->oem_id) { | 1657 | switch (rtlhal->oem_id) { |
1670 | case RT_CID_819x_HP: | 1658 | case RT_CID_819x_HP: |
1671 | pcipriv->ledctl.bled_opendrain = true; | 1659 | pcipriv->ledctl.led_opendrain = true; |
1672 | break; | 1660 | break; |
1673 | case RT_CID_819x_Lenovo: | 1661 | case RT_CID_819x_Lenovo: |
1674 | case RT_CID_DEFAULT: | 1662 | case RT_CID_DEFAULT: |
@@ -1693,10 +1681,10 @@ void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw) | |||
1693 | 1681 | ||
1694 | rtlhal->version = _rtl92ce_read_chip_version(hw); | 1682 | rtlhal->version = _rtl92ce_read_chip_version(hw); |
1695 | if (get_rf_type(rtlphy) == RF_1T1R) | 1683 | if (get_rf_type(rtlphy) == RF_1T1R) |
1696 | rtlpriv->dm.brfpath_rxenable[0] = true; | 1684 | rtlpriv->dm.rfpath_rxenable[0] = true; |
1697 | else | 1685 | else |
1698 | rtlpriv->dm.brfpath_rxenable[0] = | 1686 | rtlpriv->dm.rfpath_rxenable[0] = |
1699 | rtlpriv->dm.brfpath_rxenable[1] = true; | 1687 | rtlpriv->dm.rfpath_rxenable[1] = true; |
1700 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("VersionID = 0x%4x\n", | 1688 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("VersionID = 0x%4x\n", |
1701 | rtlhal->version)); | 1689 | rtlhal->version)); |
1702 | tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); | 1690 | tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); |
@@ -1725,18 +1713,18 @@ void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw) | |||
1725 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 1713 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
1726 | 1714 | ||
1727 | u32 ratr_value = (u32) mac->basic_rates; | 1715 | u32 ratr_value = (u32) mac->basic_rates; |
1728 | u8 *p_mcsrate = mac->mcs; | 1716 | u8 *mcsrate = mac->mcs; |
1729 | u8 ratr_index = 0; | 1717 | u8 ratr_index = 0; |
1730 | u8 b_nmode = mac->ht_enable; | 1718 | u8 nmode = mac->ht_enable; |
1731 | u8 mimo_ps = 1; | 1719 | u8 mimo_ps = 1; |
1732 | u16 shortgi_rate; | 1720 | u16 shortgi_rate; |
1733 | u32 tmp_ratr_value; | 1721 | u32 tmp_ratr_value; |
1734 | u8 b_curtxbw_40mhz = mac->bw_40; | 1722 | u8 curtxbw_40mhz = mac->bw_40; |
1735 | u8 b_curshortgi_40mhz = mac->sgi_40; | 1723 | u8 curshortgi_40mhz = mac->sgi_40; |
1736 | u8 b_curshortgi_20mhz = mac->sgi_20; | 1724 | u8 curshortgi_20mhz = mac->sgi_20; |
1737 | enum wireless_mode wirelessmode = mac->mode; | 1725 | enum wireless_mode wirelessmode = mac->mode; |
1738 | 1726 | ||
1739 | ratr_value |= EF2BYTE((*(u16 *) (p_mcsrate))) << 12; | 1727 | ratr_value |= ((*(u16 *) (mcsrate))) << 12; |
1740 | 1728 | ||
1741 | switch (wirelessmode) { | 1729 | switch (wirelessmode) { |
1742 | case WIRELESS_MODE_B: | 1730 | case WIRELESS_MODE_B: |
@@ -1750,7 +1738,7 @@ void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw) | |||
1750 | break; | 1738 | break; |
1751 | case WIRELESS_MODE_N_24G: | 1739 | case WIRELESS_MODE_N_24G: |
1752 | case WIRELESS_MODE_N_5G: | 1740 | case WIRELESS_MODE_N_5G: |
1753 | b_nmode = 1; | 1741 | nmode = 1; |
1754 | if (mimo_ps == 0) { | 1742 | if (mimo_ps == 0) { |
1755 | ratr_value &= 0x0007F005; | 1743 | ratr_value &= 0x0007F005; |
1756 | } else { | 1744 | } else { |
@@ -1776,9 +1764,8 @@ void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw) | |||
1776 | 1764 | ||
1777 | ratr_value &= 0x0FFFFFFF; | 1765 | ratr_value &= 0x0FFFFFFF; |
1778 | 1766 | ||
1779 | if (b_nmode && ((b_curtxbw_40mhz && | 1767 | if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) || (!curtxbw_40mhz && |
1780 | b_curshortgi_40mhz) || (!b_curtxbw_40mhz && | 1768 | curshortgi_20mhz))) { |
1781 | b_curshortgi_20mhz))) { | ||
1782 | 1769 | ||
1783 | ratr_value |= 0x10000000; | 1770 | ratr_value |= 0x10000000; |
1784 | tmp_ratr_value = (ratr_value >> 12); | 1771 | tmp_ratr_value = (ratr_value >> 12); |
@@ -1806,11 +1793,11 @@ void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) | |||
1806 | u32 ratr_bitmap = (u32) mac->basic_rates; | 1793 | u32 ratr_bitmap = (u32) mac->basic_rates; |
1807 | u8 *p_mcsrate = mac->mcs; | 1794 | u8 *p_mcsrate = mac->mcs; |
1808 | u8 ratr_index; | 1795 | u8 ratr_index; |
1809 | u8 b_curtxbw_40mhz = mac->bw_40; | 1796 | u8 curtxbw_40mhz = mac->bw_40; |
1810 | u8 b_curshortgi_40mhz = mac->sgi_40; | 1797 | u8 curshortgi_40mhz = mac->sgi_40; |
1811 | u8 b_curshortgi_20mhz = mac->sgi_20; | 1798 | u8 curshortgi_20mhz = mac->sgi_20; |
1812 | enum wireless_mode wirelessmode = mac->mode; | 1799 | enum wireless_mode wirelessmode = mac->mode; |
1813 | bool b_shortgi = false; | 1800 | bool shortgi = false; |
1814 | u8 rate_mask[5]; | 1801 | u8 rate_mask[5]; |
1815 | u8 macid = 0; | 1802 | u8 macid = 0; |
1816 | u8 mimops = 1; | 1803 | u8 mimops = 1; |
@@ -1852,7 +1839,7 @@ void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) | |||
1852 | } else { | 1839 | } else { |
1853 | if (rtlphy->rf_type == RF_1T2R || | 1840 | if (rtlphy->rf_type == RF_1T2R || |
1854 | rtlphy->rf_type == RF_1T1R) { | 1841 | rtlphy->rf_type == RF_1T1R) { |
1855 | if (b_curtxbw_40mhz) { | 1842 | if (curtxbw_40mhz) { |
1856 | if (rssi_level == 1) | 1843 | if (rssi_level == 1) |
1857 | ratr_bitmap &= 0x000f0000; | 1844 | ratr_bitmap &= 0x000f0000; |
1858 | else if (rssi_level == 2) | 1845 | else if (rssi_level == 2) |
@@ -1868,7 +1855,7 @@ void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) | |||
1868 | ratr_bitmap &= 0x000ff005; | 1855 | ratr_bitmap &= 0x000ff005; |
1869 | } | 1856 | } |
1870 | } else { | 1857 | } else { |
1871 | if (b_curtxbw_40mhz) { | 1858 | if (curtxbw_40mhz) { |
1872 | if (rssi_level == 1) | 1859 | if (rssi_level == 1) |
1873 | ratr_bitmap &= 0x0f0f0000; | 1860 | ratr_bitmap &= 0x0f0f0000; |
1874 | else if (rssi_level == 2) | 1861 | else if (rssi_level == 2) |
@@ -1886,13 +1873,13 @@ void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) | |||
1886 | } | 1873 | } |
1887 | } | 1874 | } |
1888 | 1875 | ||
1889 | if ((b_curtxbw_40mhz && b_curshortgi_40mhz) || | 1876 | if ((curtxbw_40mhz && curshortgi_40mhz) || |
1890 | (!b_curtxbw_40mhz && b_curshortgi_20mhz)) { | 1877 | (!curtxbw_40mhz && curshortgi_20mhz)) { |
1891 | 1878 | ||
1892 | if (macid == 0) | 1879 | if (macid == 0) |
1893 | b_shortgi = true; | 1880 | shortgi = true; |
1894 | else if (macid == 1) | 1881 | else if (macid == 1) |
1895 | b_shortgi = false; | 1882 | shortgi = false; |
1896 | } | 1883 | } |
1897 | break; | 1884 | break; |
1898 | default: | 1885 | default: |
@@ -1906,9 +1893,9 @@ void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) | |||
1906 | } | 1893 | } |
1907 | RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, | 1894 | RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, |
1908 | ("ratr_bitmap :%x\n", ratr_bitmap)); | 1895 | ("ratr_bitmap :%x\n", ratr_bitmap)); |
1909 | *(u32 *)&rate_mask = EF4BYTE((ratr_bitmap & 0x0fffffff) | | 1896 | *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) | |
1910 | (ratr_index << 28)); | 1897 | (ratr_index << 28); |
1911 | rate_mask[4] = macid | (b_shortgi ? 0x20 : 0x00) | 0x80; | 1898 | rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; |
1912 | RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("Rate_index:%x, " | 1899 | RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("Rate_index:%x, " |
1913 | "ratr_val:%x, %x:%x:%x:%x:%x\n", | 1900 | "ratr_val:%x, %x:%x:%x:%x:%x\n", |
1914 | ratr_index, ratr_bitmap, | 1901 | ratr_index, ratr_bitmap, |
@@ -1940,13 +1927,13 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid) | |||
1940 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 1927 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
1941 | enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate; | 1928 | enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate; |
1942 | u8 u1tmp; | 1929 | u8 u1tmp; |
1943 | bool b_actuallyset = false; | 1930 | bool actuallyset = false; |
1944 | unsigned long flag; | 1931 | unsigned long flag; |
1945 | 1932 | ||
1946 | if ((rtlpci->up_first_time == 1) || (rtlpci->being_init_adapter)) | 1933 | if ((rtlpci->up_first_time == 1) || (rtlpci->being_init_adapter)) |
1947 | return false; | 1934 | return false; |
1948 | 1935 | ||
1949 | if (ppsc->b_swrf_processing) | 1936 | if (ppsc->swrf_processing) |
1950 | return false; | 1937 | return false; |
1951 | 1938 | ||
1952 | spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); | 1939 | spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); |
@@ -1972,24 +1959,24 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid) | |||
1972 | u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL); | 1959 | u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL); |
1973 | e_rfpowerstate_toset = (u1tmp & BIT(3)) ? ERFON : ERFOFF; | 1960 | e_rfpowerstate_toset = (u1tmp & BIT(3)) ? ERFON : ERFOFF; |
1974 | 1961 | ||
1975 | if ((ppsc->b_hwradiooff == true) && (e_rfpowerstate_toset == ERFON)) { | 1962 | if ((ppsc->hwradiooff == true) && (e_rfpowerstate_toset == ERFON)) { |
1976 | RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, | 1963 | RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, |
1977 | ("GPIOChangeRF - HW Radio ON, RF ON\n")); | 1964 | ("GPIOChangeRF - HW Radio ON, RF ON\n")); |
1978 | 1965 | ||
1979 | e_rfpowerstate_toset = ERFON; | 1966 | e_rfpowerstate_toset = ERFON; |
1980 | ppsc->b_hwradiooff = false; | 1967 | ppsc->hwradiooff = false; |
1981 | b_actuallyset = true; | 1968 | actuallyset = true; |
1982 | } else if ((ppsc->b_hwradiooff == false) | 1969 | } else if ((ppsc->hwradiooff == false) |
1983 | && (e_rfpowerstate_toset == ERFOFF)) { | 1970 | && (e_rfpowerstate_toset == ERFOFF)) { |
1984 | RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, | 1971 | RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, |
1985 | ("GPIOChangeRF - HW Radio OFF, RF OFF\n")); | 1972 | ("GPIOChangeRF - HW Radio OFF, RF OFF\n")); |
1986 | 1973 | ||
1987 | e_rfpowerstate_toset = ERFOFF; | 1974 | e_rfpowerstate_toset = ERFOFF; |
1988 | ppsc->b_hwradiooff = true; | 1975 | ppsc->hwradiooff = true; |
1989 | b_actuallyset = true; | 1976 | actuallyset = true; |
1990 | } | 1977 | } |
1991 | 1978 | ||
1992 | if (b_actuallyset) { | 1979 | if (actuallyset) { |
1993 | if (e_rfpowerstate_toset == ERFON) { | 1980 | if (e_rfpowerstate_toset == ERFON) { |
1994 | if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && | 1981 | if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && |
1995 | RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM)) { | 1982 | RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM)) { |
@@ -2028,7 +2015,7 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid) | |||
2028 | } | 2015 | } |
2029 | 2016 | ||
2030 | *valid = 1; | 2017 | *valid = 1; |
2031 | return !ppsc->b_hwradiooff; | 2018 | return !ppsc->hwradiooff; |
2032 | 2019 | ||
2033 | } | 2020 | } |
2034 | 2021 | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c index 78a0569208ea..7b1da8d7508f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c | |||
@@ -57,7 +57,7 @@ void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) | |||
57 | ("switch case not process\n")); | 57 | ("switch case not process\n")); |
58 | break; | 58 | break; |
59 | } | 59 | } |
60 | pled->b_ledon = true; | 60 | pled->ledon = true; |
61 | } | 61 | } |
62 | 62 | ||
63 | void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) | 63 | void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) |
@@ -76,7 +76,7 @@ void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) | |||
76 | break; | 76 | break; |
77 | case LED_PIN_LED0: | 77 | case LED_PIN_LED0: |
78 | ledcfg &= 0xf0; | 78 | ledcfg &= 0xf0; |
79 | if (pcipriv->ledctl.bled_opendrain == true) | 79 | if (pcipriv->ledctl.led_opendrain == true) |
80 | rtl_write_byte(rtlpriv, REG_LEDCFG2, | 80 | rtl_write_byte(rtlpriv, REG_LEDCFG2, |
81 | (ledcfg | BIT(1) | BIT(5) | BIT(6))); | 81 | (ledcfg | BIT(1) | BIT(5) | BIT(6))); |
82 | else | 82 | else |
@@ -92,7 +92,7 @@ void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) | |||
92 | ("switch case not process\n")); | 92 | ("switch case not process\n")); |
93 | break; | 93 | break; |
94 | } | 94 | } |
95 | pled->b_ledon = false; | 95 | pled->ledon = false; |
96 | } | 96 | } |
97 | 97 | ||
98 | void rtl92ce_init_sw_leds(struct ieee80211_hw *hw) | 98 | void rtl92ce_init_sw_leds(struct ieee80211_hw *hw) |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c index 45044117139a..191106033b3c 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c | |||
@@ -37,82 +37,7 @@ | |||
37 | #include "dm.h" | 37 | #include "dm.h" |
38 | #include "table.h" | 38 | #include "table.h" |
39 | 39 | ||
40 | static u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, | 40 | #include "../rtl8192c/phy_common.c" |
41 | enum radio_path rfpath, u32 offset); | ||
42 | static void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, | ||
43 | enum radio_path rfpath, u32 offset, | ||
44 | u32 data); | ||
45 | static u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, | ||
46 | enum radio_path rfpath, u32 offset); | ||
47 | static void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, | ||
48 | enum radio_path rfpath, u32 offset, | ||
49 | u32 data); | ||
50 | static u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask); | ||
51 | static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw); | ||
52 | static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); | ||
53 | static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, | ||
54 | u8 configtype); | ||
55 | static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, | ||
56 | u8 configtype); | ||
57 | static void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw); | ||
58 | static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, | ||
59 | u32 cmdtableidx, u32 cmdtablesz, | ||
60 | enum swchnlcmd_id cmdid, u32 para1, | ||
61 | u32 para2, u32 msdelay); | ||
62 | static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, | ||
63 | u8 channel, u8 *stage, u8 *step, | ||
64 | u32 *delay); | ||
65 | static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, | ||
66 | enum wireless_mode wirelessmode, | ||
67 | long power_indbm); | ||
68 | static bool _rtl92c_phy_config_rf_external_pa(struct ieee80211_hw *hw, | ||
69 | enum radio_path rfpath); | ||
70 | static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, | ||
71 | enum wireless_mode wirelessmode, | ||
72 | u8 txpwridx); | ||
73 | u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) | ||
74 | { | ||
75 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
76 | u32 returnvalue, originalvalue, bitshift; | ||
77 | |||
78 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " | ||
79 | "bitmask(%#x)\n", regaddr, | ||
80 | bitmask)); | ||
81 | originalvalue = rtl_read_dword(rtlpriv, regaddr); | ||
82 | bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); | ||
83 | returnvalue = (originalvalue & bitmask) >> bitshift; | ||
84 | |||
85 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("BBR MASK=0x%x " | ||
86 | "Addr[0x%x]=0x%x\n", bitmask, | ||
87 | regaddr, originalvalue)); | ||
88 | |||
89 | return returnvalue; | ||
90 | |||
91 | } | ||
92 | |||
93 | void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, | ||
94 | u32 regaddr, u32 bitmask, u32 data) | ||
95 | { | ||
96 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
97 | u32 originalvalue, bitshift; | ||
98 | |||
99 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," | ||
100 | " data(%#x)\n", regaddr, bitmask, | ||
101 | data)); | ||
102 | |||
103 | if (bitmask != MASKDWORD) { | ||
104 | originalvalue = rtl_read_dword(rtlpriv, regaddr); | ||
105 | bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); | ||
106 | data = ((originalvalue & (~bitmask)) | (data << bitshift)); | ||
107 | } | ||
108 | |||
109 | rtl_write_dword(rtlpriv, regaddr, data); | ||
110 | |||
111 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," | ||
112 | " data(%#x)\n", regaddr, bitmask, | ||
113 | data)); | ||
114 | |||
115 | } | ||
116 | 41 | ||
117 | u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, | 42 | u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, |
118 | enum radio_path rfpath, u32 regaddr, u32 bitmask) | 43 | enum radio_path rfpath, u32 regaddr, u32 bitmask) |
@@ -197,118 +122,6 @@ void rtl92c_phy_set_rf_reg(struct ieee80211_hw *hw, | |||
197 | bitmask, data, rfpath)); | 122 | bitmask, data, rfpath)); |
198 | } | 123 | } |
199 | 124 | ||
200 | static u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, | ||
201 | enum radio_path rfpath, u32 offset) | ||
202 | { | ||
203 | RT_ASSERT(false, ("deprecated!\n")); | ||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | static void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, | ||
208 | enum radio_path rfpath, u32 offset, | ||
209 | u32 data) | ||
210 | { | ||
211 | RT_ASSERT(false, ("deprecated!\n")); | ||
212 | } | ||
213 | |||
214 | static u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, | ||
215 | enum radio_path rfpath, u32 offset) | ||
216 | { | ||
217 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
218 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
219 | struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; | ||
220 | u32 newoffset; | ||
221 | u32 tmplong, tmplong2; | ||
222 | u8 rfpi_enable = 0; | ||
223 | u32 retvalue; | ||
224 | |||
225 | offset &= 0x3f; | ||
226 | newoffset = offset; | ||
227 | if (RT_CANNOT_IO(hw)) { | ||
228 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("return all one\n")); | ||
229 | return 0xFFFFFFFF; | ||
230 | } | ||
231 | tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD); | ||
232 | if (rfpath == RF90_PATH_A) | ||
233 | tmplong2 = tmplong; | ||
234 | else | ||
235 | tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD); | ||
236 | tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) | | ||
237 | (newoffset << 23) | BLSSIREADEDGE; | ||
238 | rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, | ||
239 | tmplong & (~BLSSIREADEDGE)); | ||
240 | mdelay(1); | ||
241 | rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2); | ||
242 | mdelay(1); | ||
243 | rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, | ||
244 | tmplong | BLSSIREADEDGE); | ||
245 | mdelay(1); | ||
246 | if (rfpath == RF90_PATH_A) | ||
247 | rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, | ||
248 | BIT(8)); | ||
249 | else if (rfpath == RF90_PATH_B) | ||
250 | rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, | ||
251 | BIT(8)); | ||
252 | if (rfpi_enable) | ||
253 | retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi, | ||
254 | BLSSIREADBACKDATA); | ||
255 | else | ||
256 | retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, | ||
257 | BLSSIREADBACKDATA); | ||
258 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x]=0x%x\n", | ||
259 | rfpath, pphyreg->rflssi_readback, | ||
260 | retvalue)); | ||
261 | return retvalue; | ||
262 | } | ||
263 | |||
264 | static void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, | ||
265 | enum radio_path rfpath, u32 offset, | ||
266 | u32 data) | ||
267 | { | ||
268 | u32 data_and_addr; | ||
269 | u32 newoffset; | ||
270 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
271 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
272 | struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; | ||
273 | |||
274 | if (RT_CANNOT_IO(hw)) { | ||
275 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("stop\n")); | ||
276 | return; | ||
277 | } | ||
278 | offset &= 0x3f; | ||
279 | newoffset = offset; | ||
280 | data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; | ||
281 | rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); | ||
282 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n", | ||
283 | rfpath, pphyreg->rf3wire_offset, | ||
284 | data_and_addr)); | ||
285 | } | ||
286 | |||
287 | static u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask) | ||
288 | { | ||
289 | u32 i; | ||
290 | |||
291 | for (i = 0; i <= 31; i++) { | ||
292 | if (((bitmask >> i) & 0x1) == 1) | ||
293 | break; | ||
294 | } | ||
295 | return i; | ||
296 | } | ||
297 | |||
298 | static void _rtl92c_phy_bb_config_1t(struct ieee80211_hw *hw) | ||
299 | { | ||
300 | rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2); | ||
301 | rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022); | ||
302 | rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45); | ||
303 | rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23); | ||
304 | rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1); | ||
305 | rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2); | ||
306 | rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2); | ||
307 | rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2); | ||
308 | rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2); | ||
309 | rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2); | ||
310 | } | ||
311 | |||
312 | bool rtl92c_phy_mac_config(struct ieee80211_hw *hw) | 125 | bool rtl92c_phy_mac_config(struct ieee80211_hw *hw) |
313 | { | 126 | { |
314 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 127 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
@@ -327,7 +140,7 @@ bool rtl92c_phy_bb_config(struct ieee80211_hw *hw) | |||
327 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 140 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
328 | u16 regval; | 141 | u16 regval; |
329 | u32 regvaldw; | 142 | u32 regvaldw; |
330 | u8 b_reg_hwparafile = 1; | 143 | u8 reg_hwparafile = 1; |
331 | 144 | ||
332 | _rtl92c_phy_init_bb_rf_register_definition(hw); | 145 | _rtl92c_phy_init_bb_rf_register_definition(hw); |
333 | regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); | 146 | regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); |
@@ -342,55 +155,11 @@ bool rtl92c_phy_bb_config(struct ieee80211_hw *hw) | |||
342 | rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80); | 155 | rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80); |
343 | regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0); | 156 | regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0); |
344 | rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23)); | 157 | rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23)); |
345 | if (b_reg_hwparafile == 1) | 158 | if (reg_hwparafile == 1) |
346 | rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw); | 159 | rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw); |
347 | return rtstatus; | 160 | return rtstatus; |
348 | } | 161 | } |
349 | 162 | ||
350 | bool rtl92c_phy_rf_config(struct ieee80211_hw *hw) | ||
351 | { | ||
352 | return rtl92c_phy_rf6052_config(hw); | ||
353 | } | ||
354 | |||
355 | static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw) | ||
356 | { | ||
357 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
358 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
359 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
360 | bool rtstatus; | ||
361 | |||
362 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("==>\n")); | ||
363 | rtstatus = _rtl92c_phy_config_bb_with_headerfile(hw, | ||
364 | BASEBAND_CONFIG_PHY_REG); | ||
365 | if (rtstatus != true) { | ||
366 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Write BB Reg Fail!!")); | ||
367 | return false; | ||
368 | } | ||
369 | if (rtlphy->rf_type == RF_1T2R) { | ||
370 | _rtl92c_phy_bb_config_1t(hw); | ||
371 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Config to 1T!!\n")); | ||
372 | } | ||
373 | if (rtlefuse->autoload_failflag == false) { | ||
374 | rtlphy->pwrgroup_cnt = 0; | ||
375 | rtstatus = _rtl92c_phy_config_bb_with_pgheaderfile(hw, | ||
376 | BASEBAND_CONFIG_PHY_REG); | ||
377 | } | ||
378 | if (rtstatus != true) { | ||
379 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("BB_PG Reg Fail!!")); | ||
380 | return false; | ||
381 | } | ||
382 | rtstatus = _rtl92c_phy_config_bb_with_headerfile(hw, | ||
383 | BASEBAND_CONFIG_AGC_TAB); | ||
384 | if (rtstatus != true) { | ||
385 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("AGC Table Fail\n")); | ||
386 | return false; | ||
387 | } | ||
388 | rtlphy->bcck_high_power = (bool) (rtl_get_bbreg(hw, | ||
389 | RFPGA0_XA_HSSIPARAMETER2, | ||
390 | 0x200)); | ||
391 | return true; | ||
392 | } | ||
393 | |||
394 | static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) | 163 | static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) |
395 | { | 164 | { |
396 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 165 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
@@ -408,10 +177,6 @@ static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) | |||
408 | return true; | 177 | return true; |
409 | } | 178 | } |
410 | 179 | ||
411 | void rtl92c_phy_config_bb_external_pa(struct ieee80211_hw *hw) | ||
412 | { | ||
413 | } | ||
414 | |||
415 | static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, | 180 | static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, |
416 | u8 configtype) | 181 | u8 configtype) |
417 | { | 182 | { |
@@ -472,174 +237,6 @@ static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, | |||
472 | return true; | 237 | return true; |
473 | } | 238 | } |
474 | 239 | ||
475 | static void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, | ||
476 | u32 regaddr, u32 bitmask, | ||
477 | u32 data) | ||
478 | { | ||
479 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
480 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
481 | |||
482 | if (regaddr == RTXAGC_A_RATE18_06) { | ||
483 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] = | ||
484 | data; | ||
485 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
486 | ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n", | ||
487 | rtlphy->pwrgroup_cnt, | ||
488 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | ||
489 | pwrgroup_cnt][0])); | ||
490 | } | ||
491 | if (regaddr == RTXAGC_A_RATE54_24) { | ||
492 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] = | ||
493 | data; | ||
494 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
495 | ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n", | ||
496 | rtlphy->pwrgroup_cnt, | ||
497 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | ||
498 | pwrgroup_cnt][1])); | ||
499 | } | ||
500 | if (regaddr == RTXAGC_A_CCK1_MCS32) { | ||
501 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] = | ||
502 | data; | ||
503 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
504 | ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n", | ||
505 | rtlphy->pwrgroup_cnt, | ||
506 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | ||
507 | pwrgroup_cnt][6])); | ||
508 | } | ||
509 | if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) { | ||
510 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][7] = | ||
511 | data; | ||
512 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
513 | ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n", | ||
514 | rtlphy->pwrgroup_cnt, | ||
515 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | ||
516 | pwrgroup_cnt][7])); | ||
517 | } | ||
518 | if (regaddr == RTXAGC_A_MCS03_MCS00) { | ||
519 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] = | ||
520 | data; | ||
521 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
522 | ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n", | ||
523 | rtlphy->pwrgroup_cnt, | ||
524 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | ||
525 | pwrgroup_cnt][2])); | ||
526 | } | ||
527 | if (regaddr == RTXAGC_A_MCS07_MCS04) { | ||
528 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] = | ||
529 | data; | ||
530 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
531 | ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n", | ||
532 | rtlphy->pwrgroup_cnt, | ||
533 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | ||
534 | pwrgroup_cnt][3])); | ||
535 | } | ||
536 | if (regaddr == RTXAGC_A_MCS11_MCS08) { | ||
537 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] = | ||
538 | data; | ||
539 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
540 | ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n", | ||
541 | rtlphy->pwrgroup_cnt, | ||
542 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | ||
543 | pwrgroup_cnt][4])); | ||
544 | } | ||
545 | if (regaddr == RTXAGC_A_MCS15_MCS12) { | ||
546 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] = | ||
547 | data; | ||
548 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
549 | ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n", | ||
550 | rtlphy->pwrgroup_cnt, | ||
551 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | ||
552 | pwrgroup_cnt][5])); | ||
553 | } | ||
554 | if (regaddr == RTXAGC_B_RATE18_06) { | ||
555 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][8] = | ||
556 | data; | ||
557 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
558 | ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n", | ||
559 | rtlphy->pwrgroup_cnt, | ||
560 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | ||
561 | pwrgroup_cnt][8])); | ||
562 | } | ||
563 | if (regaddr == RTXAGC_B_RATE54_24) { | ||
564 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][9] = | ||
565 | data; | ||
566 | |||
567 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
568 | ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n", | ||
569 | rtlphy->pwrgroup_cnt, | ||
570 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | ||
571 | pwrgroup_cnt][9])); | ||
572 | } | ||
573 | |||
574 | if (regaddr == RTXAGC_B_CCK1_55_MCS32) { | ||
575 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][14] = | ||
576 | data; | ||
577 | |||
578 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
579 | ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n", | ||
580 | rtlphy->pwrgroup_cnt, | ||
581 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | ||
582 | pwrgroup_cnt][14])); | ||
583 | } | ||
584 | |||
585 | if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) { | ||
586 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][15] = | ||
587 | data; | ||
588 | |||
589 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
590 | ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n", | ||
591 | rtlphy->pwrgroup_cnt, | ||
592 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | ||
593 | pwrgroup_cnt][15])); | ||
594 | } | ||
595 | |||
596 | if (regaddr == RTXAGC_B_MCS03_MCS00) { | ||
597 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][10] = | ||
598 | data; | ||
599 | |||
600 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
601 | ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n", | ||
602 | rtlphy->pwrgroup_cnt, | ||
603 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | ||
604 | pwrgroup_cnt][10])); | ||
605 | } | ||
606 | |||
607 | if (regaddr == RTXAGC_B_MCS07_MCS04) { | ||
608 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][11] = | ||
609 | data; | ||
610 | |||
611 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
612 | ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n", | ||
613 | rtlphy->pwrgroup_cnt, | ||
614 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | ||
615 | pwrgroup_cnt][11])); | ||
616 | } | ||
617 | |||
618 | if (regaddr == RTXAGC_B_MCS11_MCS08) { | ||
619 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][12] = | ||
620 | data; | ||
621 | |||
622 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
623 | ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n", | ||
624 | rtlphy->pwrgroup_cnt, | ||
625 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | ||
626 | pwrgroup_cnt][12])); | ||
627 | } | ||
628 | |||
629 | if (regaddr == RTXAGC_B_MCS15_MCS12) { | ||
630 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][13] = | ||
631 | data; | ||
632 | |||
633 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
634 | ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n", | ||
635 | rtlphy->pwrgroup_cnt, | ||
636 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | ||
637 | pwrgroup_cnt][13])); | ||
638 | |||
639 | rtlphy->pwrgroup_cnt++; | ||
640 | } | ||
641 | } | ||
642 | |||
643 | static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, | 240 | static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, |
644 | u8 configtype) | 241 | u8 configtype) |
645 | { | 242 | { |
@@ -679,12 +276,6 @@ static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, | |||
679 | return true; | 276 | return true; |
680 | } | 277 | } |
681 | 278 | ||
682 | static bool _rtl92c_phy_config_rf_external_pa(struct ieee80211_hw *hw, | ||
683 | enum radio_path rfpath) | ||
684 | { | ||
685 | return true; | ||
686 | } | ||
687 | |||
688 | bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, | 279 | bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, |
689 | enum radio_path rfpath) | 280 | enum radio_path rfpath) |
690 | { | 281 | { |
@@ -776,345 +367,6 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, | |||
776 | return true; | 367 | return true; |
777 | } | 368 | } |
778 | 369 | ||
779 | void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) | ||
780 | { | ||
781 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
782 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
783 | |||
784 | rtlphy->default_initialgain[0] = | ||
785 | (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); | ||
786 | rtlphy->default_initialgain[1] = | ||
787 | (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); | ||
788 | rtlphy->default_initialgain[2] = | ||
789 | (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0); | ||
790 | rtlphy->default_initialgain[3] = | ||
791 | (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); | ||
792 | |||
793 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
794 | ("Default initial gain (c50=0x%x, " | ||
795 | "c58=0x%x, c60=0x%x, c68=0x%x\n", | ||
796 | rtlphy->default_initialgain[0], | ||
797 | rtlphy->default_initialgain[1], | ||
798 | rtlphy->default_initialgain[2], | ||
799 | rtlphy->default_initialgain[3])); | ||
800 | |||
801 | rtlphy->framesync = (u8) rtl_get_bbreg(hw, | ||
802 | ROFDM0_RXDETECTOR3, MASKBYTE0); | ||
803 | rtlphy->framesync_c34 = rtl_get_bbreg(hw, | ||
804 | ROFDM0_RXDETECTOR2, MASKDWORD); | ||
805 | |||
806 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
807 | ("Default framesync (0x%x) = 0x%x\n", | ||
808 | ROFDM0_RXDETECTOR3, rtlphy->framesync)); | ||
809 | } | ||
810 | |||
811 | static void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) | ||
812 | { | ||
813 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
814 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
815 | |||
816 | rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; | ||
817 | rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; | ||
818 | rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW; | ||
819 | rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW; | ||
820 | |||
821 | rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB; | ||
822 | rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB; | ||
823 | rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB; | ||
824 | rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB; | ||
825 | |||
826 | rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; | ||
827 | rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; | ||
828 | |||
829 | rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; | ||
830 | rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; | ||
831 | |||
832 | rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = | ||
833 | RFPGA0_XA_LSSIPARAMETER; | ||
834 | rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = | ||
835 | RFPGA0_XB_LSSIPARAMETER; | ||
836 | |||
837 | rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = rFPGA0_XAB_RFPARAMETER; | ||
838 | rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = rFPGA0_XAB_RFPARAMETER; | ||
839 | rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = rFPGA0_XCD_RFPARAMETER; | ||
840 | rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = rFPGA0_XCD_RFPARAMETER; | ||
841 | |||
842 | rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE; | ||
843 | rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE; | ||
844 | rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE; | ||
845 | rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE; | ||
846 | |||
847 | rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1; | ||
848 | rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1; | ||
849 | |||
850 | rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; | ||
851 | rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; | ||
852 | |||
853 | rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control = | ||
854 | RFPGA0_XAB_SWITCHCONTROL; | ||
855 | rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control = | ||
856 | RFPGA0_XAB_SWITCHCONTROL; | ||
857 | rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control = | ||
858 | RFPGA0_XCD_SWITCHCONTROL; | ||
859 | rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control = | ||
860 | RFPGA0_XCD_SWITCHCONTROL; | ||
861 | |||
862 | rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; | ||
863 | rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1; | ||
864 | rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1; | ||
865 | rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1; | ||
866 | |||
867 | rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2; | ||
868 | rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2; | ||
869 | rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2; | ||
870 | rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; | ||
871 | |||
872 | rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance = | ||
873 | ROFDM0_XARXIQIMBALANCE; | ||
874 | rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance = | ||
875 | ROFDM0_XBRXIQIMBALANCE; | ||
876 | rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance = | ||
877 | ROFDM0_XCRXIQIMBANLANCE; | ||
878 | rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance = | ||
879 | ROFDM0_XDRXIQIMBALANCE; | ||
880 | |||
881 | rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; | ||
882 | rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE; | ||
883 | rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE; | ||
884 | rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; | ||
885 | |||
886 | rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance = | ||
887 | ROFDM0_XATXIQIMBALANCE; | ||
888 | rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance = | ||
889 | ROFDM0_XBTXIQIMBALANCE; | ||
890 | rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance = | ||
891 | ROFDM0_XCTXIQIMBALANCE; | ||
892 | rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance = | ||
893 | ROFDM0_XDTXIQIMBALANCE; | ||
894 | |||
895 | rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; | ||
896 | rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE; | ||
897 | rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE; | ||
898 | rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE; | ||
899 | |||
900 | rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback = | ||
901 | RFPGA0_XA_LSSIREADBACK; | ||
902 | rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback = | ||
903 | RFPGA0_XB_LSSIREADBACK; | ||
904 | rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback = | ||
905 | RFPGA0_XC_LSSIREADBACK; | ||
906 | rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback = | ||
907 | RFPGA0_XD_LSSIREADBACK; | ||
908 | |||
909 | rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi = | ||
910 | TRANSCEIVEA_HSPI_READBACK; | ||
911 | rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi = | ||
912 | TRANSCEIVEB_HSPI_READBACK; | ||
913 | |||
914 | } | ||
915 | |||
916 | void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel) | ||
917 | { | ||
918 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
919 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
920 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
921 | u8 txpwr_level; | ||
922 | long txpwr_dbm; | ||
923 | |||
924 | txpwr_level = rtlphy->cur_cck_txpwridx; | ||
925 | txpwr_dbm = _rtl92c_phy_txpwr_idx_to_dbm(hw, | ||
926 | WIRELESS_MODE_B, txpwr_level); | ||
927 | txpwr_level = rtlphy->cur_ofdm24g_txpwridx + | ||
928 | rtlefuse->legacy_ht_txpowerdiff; | ||
929 | if (_rtl92c_phy_txpwr_idx_to_dbm(hw, | ||
930 | WIRELESS_MODE_G, | ||
931 | txpwr_level) > txpwr_dbm) | ||
932 | txpwr_dbm = | ||
933 | _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, | ||
934 | txpwr_level); | ||
935 | txpwr_level = rtlphy->cur_ofdm24g_txpwridx; | ||
936 | if (_rtl92c_phy_txpwr_idx_to_dbm(hw, | ||
937 | WIRELESS_MODE_N_24G, | ||
938 | txpwr_level) > txpwr_dbm) | ||
939 | txpwr_dbm = | ||
940 | _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, | ||
941 | txpwr_level); | ||
942 | *powerlevel = txpwr_dbm; | ||
943 | } | ||
944 | |||
945 | static void _rtl92c_get_txpower_index(struct ieee80211_hw *hw, u8 channel, | ||
946 | u8 *cckpowerlevel, u8 *ofdmpowerlevel) | ||
947 | { | ||
948 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
949 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
950 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
951 | u8 index = (channel - 1); | ||
952 | |||
953 | cckpowerlevel[RF90_PATH_A] = | ||
954 | rtlefuse->txpwrlevel_cck[RF90_PATH_A][index]; | ||
955 | cckpowerlevel[RF90_PATH_B] = | ||
956 | rtlefuse->txpwrlevel_cck[RF90_PATH_B][index]; | ||
957 | if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) { | ||
958 | ofdmpowerlevel[RF90_PATH_A] = | ||
959 | rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index]; | ||
960 | ofdmpowerlevel[RF90_PATH_B] = | ||
961 | rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index]; | ||
962 | } else if (get_rf_type(rtlphy) == RF_2T2R) { | ||
963 | ofdmpowerlevel[RF90_PATH_A] = | ||
964 | rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index]; | ||
965 | ofdmpowerlevel[RF90_PATH_B] = | ||
966 | rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index]; | ||
967 | } | ||
968 | } | ||
969 | |||
970 | static void _rtl92c_ccxpower_index_check(struct ieee80211_hw *hw, | ||
971 | u8 channel, u8 *cckpowerlevel, | ||
972 | u8 *ofdmpowerlevel) | ||
973 | { | ||
974 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
975 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
976 | |||
977 | rtlphy->cur_cck_txpwridx = cckpowerlevel[0]; | ||
978 | rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0]; | ||
979 | } | ||
980 | |||
981 | void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) | ||
982 | { | ||
983 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
984 | u8 cckpowerlevel[2], ofdmpowerlevel[2]; | ||
985 | |||
986 | if (rtlefuse->b_txpwr_fromeprom == false) | ||
987 | return; | ||
988 | _rtl92c_get_txpower_index(hw, channel, | ||
989 | &cckpowerlevel[0], &ofdmpowerlevel[0]); | ||
990 | _rtl92c_ccxpower_index_check(hw, | ||
991 | channel, &cckpowerlevel[0], | ||
992 | &ofdmpowerlevel[0]); | ||
993 | rtl92c_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]); | ||
994 | rtl92c_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel); | ||
995 | } | ||
996 | |||
997 | bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm) | ||
998 | { | ||
999 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1000 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1001 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
1002 | u8 idx; | ||
1003 | u8 rf_path; | ||
1004 | |||
1005 | u8 ccktxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw, | ||
1006 | WIRELESS_MODE_B, | ||
1007 | power_indbm); | ||
1008 | u8 ofdmtxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw, | ||
1009 | WIRELESS_MODE_N_24G, | ||
1010 | power_indbm); | ||
1011 | if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0) | ||
1012 | ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff; | ||
1013 | else | ||
1014 | ofdmtxpwridx = 0; | ||
1015 | RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE, | ||
1016 | ("%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n", | ||
1017 | power_indbm, ccktxpwridx, ofdmtxpwridx)); | ||
1018 | for (idx = 0; idx < 14; idx++) { | ||
1019 | for (rf_path = 0; rf_path < 2; rf_path++) { | ||
1020 | rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx; | ||
1021 | rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] = | ||
1022 | ofdmtxpwridx; | ||
1023 | rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] = | ||
1024 | ofdmtxpwridx; | ||
1025 | } | ||
1026 | } | ||
1027 | rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); | ||
1028 | return true; | ||
1029 | } | ||
1030 | |||
1031 | void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, u16 beaconinterval) | ||
1032 | { | ||
1033 | } | ||
1034 | |||
1035 | static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, | ||
1036 | enum wireless_mode wirelessmode, | ||
1037 | long power_indbm) | ||
1038 | { | ||
1039 | u8 txpwridx; | ||
1040 | long offset; | ||
1041 | |||
1042 | switch (wirelessmode) { | ||
1043 | case WIRELESS_MODE_B: | ||
1044 | offset = -7; | ||
1045 | break; | ||
1046 | case WIRELESS_MODE_G: | ||
1047 | case WIRELESS_MODE_N_24G: | ||
1048 | offset = -8; | ||
1049 | break; | ||
1050 | default: | ||
1051 | offset = -8; | ||
1052 | break; | ||
1053 | } | ||
1054 | |||
1055 | if ((power_indbm - offset) > 0) | ||
1056 | txpwridx = (u8) ((power_indbm - offset) * 2); | ||
1057 | else | ||
1058 | txpwridx = 0; | ||
1059 | |||
1060 | if (txpwridx > MAX_TXPWR_IDX_NMODE_92S) | ||
1061 | txpwridx = MAX_TXPWR_IDX_NMODE_92S; | ||
1062 | |||
1063 | return txpwridx; | ||
1064 | } | ||
1065 | |||
1066 | static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, | ||
1067 | enum wireless_mode wirelessmode, | ||
1068 | u8 txpwridx) | ||
1069 | { | ||
1070 | long offset; | ||
1071 | long pwrout_dbm; | ||
1072 | |||
1073 | switch (wirelessmode) { | ||
1074 | case WIRELESS_MODE_B: | ||
1075 | offset = -7; | ||
1076 | break; | ||
1077 | case WIRELESS_MODE_G: | ||
1078 | case WIRELESS_MODE_N_24G: | ||
1079 | offset = -8; | ||
1080 | break; | ||
1081 | default: | ||
1082 | offset = -8; | ||
1083 | break; | ||
1084 | } | ||
1085 | pwrout_dbm = txpwridx / 2 + offset; | ||
1086 | return pwrout_dbm; | ||
1087 | } | ||
1088 | |||
1089 | void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) | ||
1090 | { | ||
1091 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1092 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1093 | enum io_type iotype; | ||
1094 | |||
1095 | if (!is_hal_stop(rtlhal)) { | ||
1096 | switch (operation) { | ||
1097 | case SCAN_OPT_BACKUP: | ||
1098 | iotype = IO_CMD_PAUSE_DM_BY_SCAN; | ||
1099 | rtlpriv->cfg->ops->set_hw_reg(hw, | ||
1100 | HW_VAR_IO_CMD, | ||
1101 | (u8 *)&iotype); | ||
1102 | |||
1103 | break; | ||
1104 | case SCAN_OPT_RESTORE: | ||
1105 | iotype = IO_CMD_RESUME_DM_BY_SCAN; | ||
1106 | rtlpriv->cfg->ops->set_hw_reg(hw, | ||
1107 | HW_VAR_IO_CMD, | ||
1108 | (u8 *)&iotype); | ||
1109 | break; | ||
1110 | default: | ||
1111 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
1112 | ("Unknown Scan Backup operation.\n")); | ||
1113 | break; | ||
1114 | } | ||
1115 | } | ||
1116 | } | ||
1117 | |||
1118 | void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw) | 370 | void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw) |
1119 | { | 371 | { |
1120 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 372 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
@@ -1183,644 +435,6 @@ void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw) | |||
1183 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); | 435 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); |
1184 | } | 436 | } |
1185 | 437 | ||
1186 | void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, | ||
1187 | enum nl80211_channel_type ch_type) | ||
1188 | { | ||
1189 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1190 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1191 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1192 | u8 tmp_bw = rtlphy->current_chan_bw; | ||
1193 | |||
1194 | if (rtlphy->set_bwmode_inprogress) | ||
1195 | return; | ||
1196 | rtlphy->set_bwmode_inprogress = true; | ||
1197 | if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) | ||
1198 | rtl92c_phy_set_bw_mode_callback(hw); | ||
1199 | else { | ||
1200 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | ||
1201 | ("FALSE driver sleep or unload\n")); | ||
1202 | rtlphy->set_bwmode_inprogress = false; | ||
1203 | rtlphy->current_chan_bw = tmp_bw; | ||
1204 | } | ||
1205 | } | ||
1206 | |||
1207 | void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw) | ||
1208 | { | ||
1209 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1210 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1211 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1212 | u32 delay; | ||
1213 | |||
1214 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, | ||
1215 | ("switch to channel%d\n", rtlphy->current_channel)); | ||
1216 | if (is_hal_stop(rtlhal)) | ||
1217 | return; | ||
1218 | do { | ||
1219 | if (!rtlphy->sw_chnl_inprogress) | ||
1220 | break; | ||
1221 | if (!_rtl92c_phy_sw_chnl_step_by_step | ||
1222 | (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage, | ||
1223 | &rtlphy->sw_chnl_step, &delay)) { | ||
1224 | if (delay > 0) | ||
1225 | mdelay(delay); | ||
1226 | else | ||
1227 | continue; | ||
1228 | } else | ||
1229 | rtlphy->sw_chnl_inprogress = false; | ||
1230 | break; | ||
1231 | } while (true); | ||
1232 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); | ||
1233 | } | ||
1234 | |||
1235 | u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw) | ||
1236 | { | ||
1237 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1238 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1239 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1240 | |||
1241 | if (rtlphy->sw_chnl_inprogress) | ||
1242 | return 0; | ||
1243 | if (rtlphy->set_bwmode_inprogress) | ||
1244 | return 0; | ||
1245 | RT_ASSERT((rtlphy->current_channel <= 14), | ||
1246 | ("WIRELESS_MODE_G but channel>14")); | ||
1247 | rtlphy->sw_chnl_inprogress = true; | ||
1248 | rtlphy->sw_chnl_stage = 0; | ||
1249 | rtlphy->sw_chnl_step = 0; | ||
1250 | if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { | ||
1251 | rtl92c_phy_sw_chnl_callback(hw); | ||
1252 | RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, | ||
1253 | ("sw_chnl_inprogress false schdule workitem\n")); | ||
1254 | rtlphy->sw_chnl_inprogress = false; | ||
1255 | } else { | ||
1256 | RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, | ||
1257 | ("sw_chnl_inprogress false driver sleep or" | ||
1258 | " unload\n")); | ||
1259 | rtlphy->sw_chnl_inprogress = false; | ||
1260 | } | ||
1261 | return 1; | ||
1262 | } | ||
1263 | |||
1264 | static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, | ||
1265 | u8 channel, u8 *stage, u8 *step, | ||
1266 | u32 *delay) | ||
1267 | { | ||
1268 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1269 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1270 | struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; | ||
1271 | u32 precommoncmdcnt; | ||
1272 | struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; | ||
1273 | u32 postcommoncmdcnt; | ||
1274 | struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT]; | ||
1275 | u32 rfdependcmdcnt; | ||
1276 | struct swchnlcmd *currentcmd = NULL; | ||
1277 | u8 rfpath; | ||
1278 | u8 num_total_rfpath = rtlphy->num_total_rfpath; | ||
1279 | |||
1280 | precommoncmdcnt = 0; | ||
1281 | _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, | ||
1282 | MAX_PRECMD_CNT, | ||
1283 | CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0); | ||
1284 | _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, | ||
1285 | MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); | ||
1286 | |||
1287 | postcommoncmdcnt = 0; | ||
1288 | |||
1289 | _rtl92c_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, | ||
1290 | MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0); | ||
1291 | |||
1292 | rfdependcmdcnt = 0; | ||
1293 | |||
1294 | RT_ASSERT((channel >= 1 && channel <= 14), | ||
1295 | ("illegal channel for Zebra: %d\n", channel)); | ||
1296 | |||
1297 | _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, | ||
1298 | MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, | ||
1299 | RF_CHNLBW, channel, 10); | ||
1300 | |||
1301 | _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, | ||
1302 | MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, | ||
1303 | 0); | ||
1304 | |||
1305 | do { | ||
1306 | switch (*stage) { | ||
1307 | case 0: | ||
1308 | currentcmd = &precommoncmd[*step]; | ||
1309 | break; | ||
1310 | case 1: | ||
1311 | currentcmd = &rfdependcmd[*step]; | ||
1312 | break; | ||
1313 | case 2: | ||
1314 | currentcmd = &postcommoncmd[*step]; | ||
1315 | break; | ||
1316 | } | ||
1317 | |||
1318 | if (currentcmd->cmdid == CMDID_END) { | ||
1319 | if ((*stage) == 2) { | ||
1320 | return true; | ||
1321 | } else { | ||
1322 | (*stage)++; | ||
1323 | (*step) = 0; | ||
1324 | continue; | ||
1325 | } | ||
1326 | } | ||
1327 | |||
1328 | switch (currentcmd->cmdid) { | ||
1329 | case CMDID_SET_TXPOWEROWER_LEVEL: | ||
1330 | rtl92c_phy_set_txpower_level(hw, channel); | ||
1331 | break; | ||
1332 | case CMDID_WRITEPORT_ULONG: | ||
1333 | rtl_write_dword(rtlpriv, currentcmd->para1, | ||
1334 | currentcmd->para2); | ||
1335 | break; | ||
1336 | case CMDID_WRITEPORT_USHORT: | ||
1337 | rtl_write_word(rtlpriv, currentcmd->para1, | ||
1338 | (u16) currentcmd->para2); | ||
1339 | break; | ||
1340 | case CMDID_WRITEPORT_UCHAR: | ||
1341 | rtl_write_byte(rtlpriv, currentcmd->para1, | ||
1342 | (u8) currentcmd->para2); | ||
1343 | break; | ||
1344 | case CMDID_RF_WRITEREG: | ||
1345 | for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { | ||
1346 | rtlphy->rfreg_chnlval[rfpath] = | ||
1347 | ((rtlphy->rfreg_chnlval[rfpath] & | ||
1348 | 0xfffffc00) | currentcmd->para2); | ||
1349 | |||
1350 | rtl_set_rfreg(hw, (enum radio_path)rfpath, | ||
1351 | currentcmd->para1, | ||
1352 | RFREG_OFFSET_MASK, | ||
1353 | rtlphy->rfreg_chnlval[rfpath]); | ||
1354 | } | ||
1355 | break; | ||
1356 | default: | ||
1357 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
1358 | ("switch case not process\n")); | ||
1359 | break; | ||
1360 | } | ||
1361 | |||
1362 | break; | ||
1363 | } while (true); | ||
1364 | |||
1365 | (*delay) = currentcmd->msdelay; | ||
1366 | (*step)++; | ||
1367 | return false; | ||
1368 | } | ||
1369 | |||
1370 | static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, | ||
1371 | u32 cmdtableidx, u32 cmdtablesz, | ||
1372 | enum swchnlcmd_id cmdid, | ||
1373 | u32 para1, u32 para2, u32 msdelay) | ||
1374 | { | ||
1375 | struct swchnlcmd *pcmd; | ||
1376 | |||
1377 | if (cmdtable == NULL) { | ||
1378 | RT_ASSERT(false, ("cmdtable cannot be NULL.\n")); | ||
1379 | return false; | ||
1380 | } | ||
1381 | |||
1382 | if (cmdtableidx >= cmdtablesz) | ||
1383 | return false; | ||
1384 | |||
1385 | pcmd = cmdtable + cmdtableidx; | ||
1386 | pcmd->cmdid = cmdid; | ||
1387 | pcmd->para1 = para1; | ||
1388 | pcmd->para2 = para2; | ||
1389 | pcmd->msdelay = msdelay; | ||
1390 | return true; | ||
1391 | } | ||
1392 | |||
1393 | bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath) | ||
1394 | { | ||
1395 | return true; | ||
1396 | } | ||
1397 | |||
1398 | static u8 _rtl92c_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb) | ||
1399 | { | ||
1400 | u32 reg_eac, reg_e94, reg_e9c, reg_ea4; | ||
1401 | u8 result = 0x00; | ||
1402 | |||
1403 | rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f); | ||
1404 | rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f); | ||
1405 | rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102); | ||
1406 | rtl_set_bbreg(hw, 0xe3c, MASKDWORD, | ||
1407 | config_pathb ? 0x28160202 : 0x28160502); | ||
1408 | |||
1409 | if (config_pathb) { | ||
1410 | rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22); | ||
1411 | rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22); | ||
1412 | rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102); | ||
1413 | rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202); | ||
1414 | } | ||
1415 | |||
1416 | rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1); | ||
1417 | rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000); | ||
1418 | rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000); | ||
1419 | |||
1420 | mdelay(IQK_DELAY_TIME); | ||
1421 | |||
1422 | reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); | ||
1423 | reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD); | ||
1424 | reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD); | ||
1425 | reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD); | ||
1426 | |||
1427 | if (!(reg_eac & BIT(28)) && | ||
1428 | (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && | ||
1429 | (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) | ||
1430 | result |= 0x01; | ||
1431 | else | ||
1432 | return result; | ||
1433 | |||
1434 | if (!(reg_eac & BIT(27)) && | ||
1435 | (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) && | ||
1436 | (((reg_eac & 0x03FF0000) >> 16) != 0x36)) | ||
1437 | result |= 0x02; | ||
1438 | return result; | ||
1439 | } | ||
1440 | |||
1441 | static u8 _rtl92c_phy_path_b_iqk(struct ieee80211_hw *hw) | ||
1442 | { | ||
1443 | u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc; | ||
1444 | u8 result = 0x00; | ||
1445 | |||
1446 | rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002); | ||
1447 | rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000); | ||
1448 | mdelay(IQK_DELAY_TIME); | ||
1449 | reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); | ||
1450 | reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD); | ||
1451 | reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD); | ||
1452 | reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD); | ||
1453 | reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD); | ||
1454 | if (!(reg_eac & BIT(31)) && | ||
1455 | (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) && | ||
1456 | (((reg_ebc & 0x03FF0000) >> 16) != 0x42)) | ||
1457 | result |= 0x01; | ||
1458 | else | ||
1459 | return result; | ||
1460 | |||
1461 | if (!(reg_eac & BIT(30)) && | ||
1462 | (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) && | ||
1463 | (((reg_ecc & 0x03FF0000) >> 16) != 0x36)) | ||
1464 | result |= 0x02; | ||
1465 | return result; | ||
1466 | } | ||
1467 | |||
1468 | static void _rtl92c_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw, | ||
1469 | bool b_iqk_ok, long result[][8], | ||
1470 | u8 final_candidate, bool btxonly) | ||
1471 | { | ||
1472 | u32 oldval_0, x, tx0_a, reg; | ||
1473 | long y, tx0_c; | ||
1474 | |||
1475 | if (final_candidate == 0xFF) | ||
1476 | return; | ||
1477 | else if (b_iqk_ok) { | ||
1478 | oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, | ||
1479 | MASKDWORD) >> 22) & 0x3FF; | ||
1480 | x = result[final_candidate][0]; | ||
1481 | if ((x & 0x00000200) != 0) | ||
1482 | x = x | 0xFFFFFC00; | ||
1483 | tx0_a = (x * oldval_0) >> 8; | ||
1484 | rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a); | ||
1485 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31), | ||
1486 | ((x * oldval_0 >> 7) & 0x1)); | ||
1487 | y = result[final_candidate][1]; | ||
1488 | if ((y & 0x00000200) != 0) | ||
1489 | y = y | 0xFFFFFC00; | ||
1490 | tx0_c = (y * oldval_0) >> 8; | ||
1491 | rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000, | ||
1492 | ((tx0_c & 0x3C0) >> 6)); | ||
1493 | rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000, | ||
1494 | (tx0_c & 0x3F)); | ||
1495 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29), | ||
1496 | ((y * oldval_0 >> 7) & 0x1)); | ||
1497 | if (btxonly) | ||
1498 | return; | ||
1499 | reg = result[final_candidate][2]; | ||
1500 | rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg); | ||
1501 | reg = result[final_candidate][3] & 0x3F; | ||
1502 | rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg); | ||
1503 | reg = (result[final_candidate][3] >> 6) & 0xF; | ||
1504 | rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); | ||
1505 | } | ||
1506 | } | ||
1507 | |||
1508 | static void _rtl92c_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw, | ||
1509 | bool b_iqk_ok, long result[][8], | ||
1510 | u8 final_candidate, bool btxonly) | ||
1511 | { | ||
1512 | u32 oldval_1, x, tx1_a, reg; | ||
1513 | long y, tx1_c; | ||
1514 | |||
1515 | if (final_candidate == 0xFF) | ||
1516 | return; | ||
1517 | else if (b_iqk_ok) { | ||
1518 | oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, | ||
1519 | MASKDWORD) >> 22) & 0x3FF; | ||
1520 | x = result[final_candidate][4]; | ||
1521 | if ((x & 0x00000200) != 0) | ||
1522 | x = x | 0xFFFFFC00; | ||
1523 | tx1_a = (x * oldval_1) >> 8; | ||
1524 | rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a); | ||
1525 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27), | ||
1526 | ((x * oldval_1 >> 7) & 0x1)); | ||
1527 | y = result[final_candidate][5]; | ||
1528 | if ((y & 0x00000200) != 0) | ||
1529 | y = y | 0xFFFFFC00; | ||
1530 | tx1_c = (y * oldval_1) >> 8; | ||
1531 | rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000, | ||
1532 | ((tx1_c & 0x3C0) >> 6)); | ||
1533 | rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000, | ||
1534 | (tx1_c & 0x3F)); | ||
1535 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25), | ||
1536 | ((y * oldval_1 >> 7) & 0x1)); | ||
1537 | if (btxonly) | ||
1538 | return; | ||
1539 | reg = result[final_candidate][6]; | ||
1540 | rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg); | ||
1541 | reg = result[final_candidate][7] & 0x3F; | ||
1542 | rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg); | ||
1543 | reg = (result[final_candidate][7] >> 6) & 0xF; | ||
1544 | rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, reg); | ||
1545 | } | ||
1546 | } | ||
1547 | |||
1548 | static void _rtl92c_phy_save_adda_registers(struct ieee80211_hw *hw, | ||
1549 | u32 *addareg, u32 *addabackup, | ||
1550 | u32 registernum) | ||
1551 | { | ||
1552 | u32 i; | ||
1553 | |||
1554 | for (i = 0; i < registernum; i++) | ||
1555 | addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD); | ||
1556 | } | ||
1557 | |||
1558 | static void _rtl92c_phy_save_mac_registers(struct ieee80211_hw *hw, | ||
1559 | u32 *macreg, u32 *macbackup) | ||
1560 | { | ||
1561 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1562 | u32 i; | ||
1563 | |||
1564 | for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) | ||
1565 | macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]); | ||
1566 | macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]); | ||
1567 | } | ||
1568 | |||
1569 | static void _rtl92c_phy_reload_adda_registers(struct ieee80211_hw *hw, | ||
1570 | u32 *addareg, u32 *addabackup, | ||
1571 | u32 regiesternum) | ||
1572 | { | ||
1573 | u32 i; | ||
1574 | |||
1575 | for (i = 0; i < regiesternum; i++) | ||
1576 | rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]); | ||
1577 | } | ||
1578 | |||
1579 | static void _rtl92c_phy_reload_mac_registers(struct ieee80211_hw *hw, | ||
1580 | u32 *macreg, u32 *macbackup) | ||
1581 | { | ||
1582 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1583 | u32 i; | ||
1584 | |||
1585 | for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) | ||
1586 | rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]); | ||
1587 | rtl_write_dword(rtlpriv, macreg[i], macbackup[i]); | ||
1588 | } | ||
1589 | |||
1590 | static void _rtl92c_phy_path_adda_on(struct ieee80211_hw *hw, | ||
1591 | u32 *addareg, bool is_patha_on, bool is2t) | ||
1592 | { | ||
1593 | u32 pathOn; | ||
1594 | u32 i; | ||
1595 | |||
1596 | pathOn = is_patha_on ? 0x04db25a4 : 0x0b1b25a4; | ||
1597 | if (false == is2t) { | ||
1598 | pathOn = 0x0bdb25a0; | ||
1599 | rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0); | ||
1600 | } else { | ||
1601 | rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathOn); | ||
1602 | } | ||
1603 | |||
1604 | for (i = 1; i < IQK_ADDA_REG_NUM; i++) | ||
1605 | rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathOn); | ||
1606 | } | ||
1607 | |||
1608 | static void _rtl92c_phy_mac_setting_calibration(struct ieee80211_hw *hw, | ||
1609 | u32 *macreg, u32 *macbackup) | ||
1610 | { | ||
1611 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1612 | u32 i; | ||
1613 | |||
1614 | rtl_write_byte(rtlpriv, macreg[0], 0x3F); | ||
1615 | |||
1616 | for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) | ||
1617 | rtl_write_byte(rtlpriv, macreg[i], | ||
1618 | (u8) (macbackup[i] & (~BIT(3)))); | ||
1619 | rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5)))); | ||
1620 | } | ||
1621 | |||
1622 | static void _rtl92c_phy_path_a_standby(struct ieee80211_hw *hw) | ||
1623 | { | ||
1624 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0); | ||
1625 | rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); | ||
1626 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); | ||
1627 | } | ||
1628 | |||
1629 | static void _rtl92c_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode) | ||
1630 | { | ||
1631 | u32 mode; | ||
1632 | |||
1633 | mode = pi_mode ? 0x01000100 : 0x01000000; | ||
1634 | rtl_set_bbreg(hw, 0x820, MASKDWORD, mode); | ||
1635 | rtl_set_bbreg(hw, 0x828, MASKDWORD, mode); | ||
1636 | } | ||
1637 | |||
1638 | static bool _rtl92c_phy_simularity_compare(struct ieee80211_hw *hw, | ||
1639 | long result[][8], u8 c1, u8 c2) | ||
1640 | { | ||
1641 | u32 i, j, diff, simularity_bitmap, bound; | ||
1642 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1643 | |||
1644 | u8 final_candidate[2] = { 0xFF, 0xFF }; | ||
1645 | bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version); | ||
1646 | |||
1647 | if (is2t) | ||
1648 | bound = 8; | ||
1649 | else | ||
1650 | bound = 4; | ||
1651 | |||
1652 | simularity_bitmap = 0; | ||
1653 | |||
1654 | for (i = 0; i < bound; i++) { | ||
1655 | diff = (result[c1][i] > result[c2][i]) ? | ||
1656 | (result[c1][i] - result[c2][i]) : | ||
1657 | (result[c2][i] - result[c1][i]); | ||
1658 | |||
1659 | if (diff > MAX_TOLERANCE) { | ||
1660 | if ((i == 2 || i == 6) && !simularity_bitmap) { | ||
1661 | if (result[c1][i] + result[c1][i + 1] == 0) | ||
1662 | final_candidate[(i / 4)] = c2; | ||
1663 | else if (result[c2][i] + result[c2][i + 1] == 0) | ||
1664 | final_candidate[(i / 4)] = c1; | ||
1665 | else | ||
1666 | simularity_bitmap = simularity_bitmap | | ||
1667 | (1 << i); | ||
1668 | } else | ||
1669 | simularity_bitmap = | ||
1670 | simularity_bitmap | (1 << i); | ||
1671 | } | ||
1672 | } | ||
1673 | |||
1674 | if (simularity_bitmap == 0) { | ||
1675 | for (i = 0; i < (bound / 4); i++) { | ||
1676 | if (final_candidate[i] != 0xFF) { | ||
1677 | for (j = i * 4; j < (i + 1) * 4 - 2; j++) | ||
1678 | result[3][j] = | ||
1679 | result[final_candidate[i]][j]; | ||
1680 | bresult = false; | ||
1681 | } | ||
1682 | } | ||
1683 | return bresult; | ||
1684 | } else if (!(simularity_bitmap & 0x0F)) { | ||
1685 | for (i = 0; i < 4; i++) | ||
1686 | result[3][i] = result[c1][i]; | ||
1687 | return false; | ||
1688 | } else if (!(simularity_bitmap & 0xF0) && is2t) { | ||
1689 | for (i = 4; i < 8; i++) | ||
1690 | result[3][i] = result[c1][i]; | ||
1691 | return false; | ||
1692 | } else { | ||
1693 | return false; | ||
1694 | } | ||
1695 | |||
1696 | } | ||
1697 | |||
1698 | static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, | ||
1699 | long result[][8], u8 t, bool is2t) | ||
1700 | { | ||
1701 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1702 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1703 | u32 i; | ||
1704 | u8 patha_ok, pathb_ok; | ||
1705 | u32 adda_reg[IQK_ADDA_REG_NUM] = { | ||
1706 | 0x85c, 0xe6c, 0xe70, 0xe74, | ||
1707 | 0xe78, 0xe7c, 0xe80, 0xe84, | ||
1708 | 0xe88, 0xe8c, 0xed0, 0xed4, | ||
1709 | 0xed8, 0xedc, 0xee0, 0xeec | ||
1710 | }; | ||
1711 | |||
1712 | u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { | ||
1713 | 0x522, 0x550, 0x551, 0x040 | ||
1714 | }; | ||
1715 | |||
1716 | const u32 retrycount = 2; | ||
1717 | |||
1718 | u32 bbvalue; | ||
1719 | |||
1720 | if (t == 0) { | ||
1721 | bbvalue = rtl_get_bbreg(hw, 0x800, MASKDWORD); | ||
1722 | |||
1723 | _rtl92c_phy_save_adda_registers(hw, adda_reg, | ||
1724 | rtlphy->adda_backup, 16); | ||
1725 | _rtl92c_phy_save_mac_registers(hw, iqk_mac_reg, | ||
1726 | rtlphy->iqk_mac_backup); | ||
1727 | } | ||
1728 | _rtl92c_phy_path_adda_on(hw, adda_reg, true, is2t); | ||
1729 | if (t == 0) { | ||
1730 | rtlphy->b_rfpi_enable = (u8) rtl_get_bbreg(hw, | ||
1731 | RFPGA0_XA_HSSIPARAMETER1, | ||
1732 | BIT(8)); | ||
1733 | } | ||
1734 | if (!rtlphy->b_rfpi_enable) | ||
1735 | _rtl92c_phy_pi_mode_switch(hw, true); | ||
1736 | if (t == 0) { | ||
1737 | rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD); | ||
1738 | rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD); | ||
1739 | rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD); | ||
1740 | } | ||
1741 | rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600); | ||
1742 | rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4); | ||
1743 | rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000); | ||
1744 | if (is2t) { | ||
1745 | rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); | ||
1746 | rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000); | ||
1747 | } | ||
1748 | _rtl92c_phy_mac_setting_calibration(hw, iqk_mac_reg, | ||
1749 | rtlphy->iqk_mac_backup); | ||
1750 | rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000); | ||
1751 | if (is2t) | ||
1752 | rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000); | ||
1753 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); | ||
1754 | rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00); | ||
1755 | rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800); | ||
1756 | for (i = 0; i < retrycount; i++) { | ||
1757 | patha_ok = _rtl92c_phy_path_a_iqk(hw, is2t); | ||
1758 | if (patha_ok == 0x03) { | ||
1759 | result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) & | ||
1760 | 0x3FF0000) >> 16; | ||
1761 | result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & | ||
1762 | 0x3FF0000) >> 16; | ||
1763 | result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) & | ||
1764 | 0x3FF0000) >> 16; | ||
1765 | result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) & | ||
1766 | 0x3FF0000) >> 16; | ||
1767 | break; | ||
1768 | } else if (i == (retrycount - 1) && patha_ok == 0x01) | ||
1769 | result[t][0] = (rtl_get_bbreg(hw, 0xe94, | ||
1770 | MASKDWORD) & 0x3FF0000) >> | ||
1771 | 16; | ||
1772 | result[t][1] = | ||
1773 | (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16; | ||
1774 | |||
1775 | } | ||
1776 | |||
1777 | if (is2t) { | ||
1778 | _rtl92c_phy_path_a_standby(hw); | ||
1779 | _rtl92c_phy_path_adda_on(hw, adda_reg, false, is2t); | ||
1780 | for (i = 0; i < retrycount; i++) { | ||
1781 | pathb_ok = _rtl92c_phy_path_b_iqk(hw); | ||
1782 | if (pathb_ok == 0x03) { | ||
1783 | result[t][4] = (rtl_get_bbreg(hw, | ||
1784 | 0xeb4, | ||
1785 | MASKDWORD) & | ||
1786 | 0x3FF0000) >> 16; | ||
1787 | result[t][5] = | ||
1788 | (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & | ||
1789 | 0x3FF0000) >> 16; | ||
1790 | result[t][6] = | ||
1791 | (rtl_get_bbreg(hw, 0xec4, MASKDWORD) & | ||
1792 | 0x3FF0000) >> 16; | ||
1793 | result[t][7] = | ||
1794 | (rtl_get_bbreg(hw, 0xecc, MASKDWORD) & | ||
1795 | 0x3FF0000) >> 16; | ||
1796 | break; | ||
1797 | } else if (i == (retrycount - 1) && pathb_ok == 0x01) { | ||
1798 | result[t][4] = (rtl_get_bbreg(hw, | ||
1799 | 0xeb4, | ||
1800 | MASKDWORD) & | ||
1801 | 0x3FF0000) >> 16; | ||
1802 | } | ||
1803 | result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & | ||
1804 | 0x3FF0000) >> 16; | ||
1805 | } | ||
1806 | } | ||
1807 | rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04); | ||
1808 | rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874); | ||
1809 | rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08); | ||
1810 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0); | ||
1811 | rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3); | ||
1812 | if (is2t) | ||
1813 | rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3); | ||
1814 | if (t != 0) { | ||
1815 | if (!rtlphy->b_rfpi_enable) | ||
1816 | _rtl92c_phy_pi_mode_switch(hw, false); | ||
1817 | _rtl92c_phy_reload_adda_registers(hw, adda_reg, | ||
1818 | rtlphy->adda_backup, 16); | ||
1819 | _rtl92c_phy_reload_mac_registers(hw, iqk_mac_reg, | ||
1820 | rtlphy->iqk_mac_backup); | ||
1821 | } | ||
1822 | } | ||
1823 | |||
1824 | static void _rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) | 438 | static void _rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) |
1825 | { | 439 | { |
1826 | u8 tmpreg; | 440 | u8 tmpreg; |
@@ -1866,666 +480,6 @@ static void _rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) | |||
1866 | } | 480 | } |
1867 | } | 481 | } |
1868 | 482 | ||
1869 | static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, | ||
1870 | char delta, bool is2t) | ||
1871 | { | ||
1872 | /* This routine is deliberately dummied out for later fixes */ | ||
1873 | #if 0 | ||
1874 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1875 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1876 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
1877 | |||
1878 | u32 reg_d[PATH_NUM]; | ||
1879 | u32 tmpreg, index, offset, path, i, pathbound = PATH_NUM, apkbound; | ||
1880 | |||
1881 | u32 bb_backup[APK_BB_REG_NUM]; | ||
1882 | u32 bb_reg[APK_BB_REG_NUM] = { | ||
1883 | 0x904, 0xc04, 0x800, 0xc08, 0x874 | ||
1884 | }; | ||
1885 | u32 bb_ap_mode[APK_BB_REG_NUM] = { | ||
1886 | 0x00000020, 0x00a05430, 0x02040000, | ||
1887 | 0x000800e4, 0x00204000 | ||
1888 | }; | ||
1889 | u32 bb_normal_ap_mode[APK_BB_REG_NUM] = { | ||
1890 | 0x00000020, 0x00a05430, 0x02040000, | ||
1891 | 0x000800e4, 0x22204000 | ||
1892 | }; | ||
1893 | |||
1894 | u32 afe_backup[APK_AFE_REG_NUM]; | ||
1895 | u32 afe_reg[APK_AFE_REG_NUM] = { | ||
1896 | 0x85c, 0xe6c, 0xe70, 0xe74, 0xe78, | ||
1897 | 0xe7c, 0xe80, 0xe84, 0xe88, 0xe8c, | ||
1898 | 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, | ||
1899 | 0xeec | ||
1900 | }; | ||
1901 | |||
1902 | u32 mac_backup[IQK_MAC_REG_NUM]; | ||
1903 | u32 mac_reg[IQK_MAC_REG_NUM] = { | ||
1904 | 0x522, 0x550, 0x551, 0x040 | ||
1905 | }; | ||
1906 | |||
1907 | u32 apk_rf_init_value[PATH_NUM][APK_BB_REG_NUM] = { | ||
1908 | {0x0852c, 0x1852c, 0x5852c, 0x1852c, 0x5852c}, | ||
1909 | {0x2852e, 0x0852e, 0x3852e, 0x0852e, 0x0852e} | ||
1910 | }; | ||
1911 | |||
1912 | u32 apk_normal_rf_init_value[PATH_NUM][APK_BB_REG_NUM] = { | ||
1913 | {0x0852c, 0x0a52c, 0x3a52c, 0x5a52c, 0x5a52c}, | ||
1914 | {0x0852c, 0x0a52c, 0x5a52c, 0x5a52c, 0x5a52c} | ||
1915 | }; | ||
1916 | |||
1917 | u32 apk_rf_value_0[PATH_NUM][APK_BB_REG_NUM] = { | ||
1918 | {0x52019, 0x52014, 0x52013, 0x5200f, 0x5208d}, | ||
1919 | {0x5201a, 0x52019, 0x52016, 0x52033, 0x52050} | ||
1920 | }; | ||
1921 | |||
1922 | u32 apk_normal_rf_value_0[PATH_NUM][APK_BB_REG_NUM] = { | ||
1923 | {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a}, | ||
1924 | {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a} | ||
1925 | }; | ||
1926 | |||
1927 | u32 afe_on_off[PATH_NUM] = { | ||
1928 | 0x04db25a4, 0x0b1b25a4 | ||
1929 | }; | ||
1930 | |||
1931 | u32 apk_offset[PATH_NUM] = { 0xb68, 0xb6c }; | ||
1932 | |||
1933 | u32 apk_normal_offset[PATH_NUM] = { 0xb28, 0xb98 }; | ||
1934 | |||
1935 | u32 apk_value[PATH_NUM] = { 0x92fc0000, 0x12fc0000 }; | ||
1936 | |||
1937 | u32 apk_normal_value[PATH_NUM] = { 0x92680000, 0x12680000 }; | ||
1938 | |||
1939 | const char apk_delta_mapping[APK_BB_REG_NUM][13] = { | ||
1940 | {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, | ||
1941 | {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, | ||
1942 | {-6, -4, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, | ||
1943 | {-1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6}, | ||
1944 | {-11, -9, -7, -5, -3, -1, 0, 0, 0, 0, 0, 0, 0} | ||
1945 | }; | ||
1946 | |||
1947 | const u32 apk_normal_setting_value_1[13] = { | ||
1948 | 0x01017018, 0xf7ed8f84, 0x1b1a1816, 0x2522201e, 0x322e2b28, | ||
1949 | 0x433f3a36, 0x5b544e49, 0x7b726a62, 0xa69a8f84, 0xdfcfc0b3, | ||
1950 | 0x12680000, 0x00880000, 0x00880000 | ||
1951 | }; | ||
1952 | |||
1953 | const u32 apk_normal_setting_value_2[16] = { | ||
1954 | 0x01c7021d, 0x01670183, 0x01000123, 0x00bf00e2, 0x008d00a3, | ||
1955 | 0x0068007b, 0x004d0059, 0x003a0042, 0x002b0031, 0x001f0025, | ||
1956 | 0x0017001b, 0x00110014, 0x000c000f, 0x0009000b, 0x00070008, | ||
1957 | 0x00050006 | ||
1958 | }; | ||
1959 | |||
1960 | const u32 apk_result[PATH_NUM][APK_BB_REG_NUM]; | ||
1961 | |||
1962 | long bb_offset, delta_v, delta_offset; | ||
1963 | |||
1964 | if (!is2t) | ||
1965 | pathbound = 1; | ||
1966 | |||
1967 | for (index = 0; index < PATH_NUM; index++) { | ||
1968 | apk_offset[index] = apk_normal_offset[index]; | ||
1969 | apk_value[index] = apk_normal_value[index]; | ||
1970 | afe_on_off[index] = 0x6fdb25a4; | ||
1971 | } | ||
1972 | |||
1973 | for (index = 0; index < APK_BB_REG_NUM; index++) { | ||
1974 | for (path = 0; path < pathbound; path++) { | ||
1975 | apk_rf_init_value[path][index] = | ||
1976 | apk_normal_rf_init_value[path][index]; | ||
1977 | apk_rf_value_0[path][index] = | ||
1978 | apk_normal_rf_value_0[path][index]; | ||
1979 | } | ||
1980 | bb_ap_mode[index] = bb_normal_ap_mode[index]; | ||
1981 | |||
1982 | apkbound = 6; | ||
1983 | } | ||
1984 | |||
1985 | for (index = 0; index < APK_BB_REG_NUM; index++) { | ||
1986 | if (index == 0) | ||
1987 | continue; | ||
1988 | bb_backup[index] = rtl_get_bbreg(hw, bb_reg[index], MASKDWORD); | ||
1989 | } | ||
1990 | |||
1991 | _rtl92c_phy_save_mac_registers(hw, mac_reg, mac_backup); | ||
1992 | |||
1993 | _rtl92c_phy_save_adda_registers(hw, afe_reg, afe_backup, 16); | ||
1994 | |||
1995 | for (path = 0; path < pathbound; path++) { | ||
1996 | if (path == RF90_PATH_A) { | ||
1997 | offset = 0xb00; | ||
1998 | for (index = 0; index < 11; index++) { | ||
1999 | rtl_set_bbreg(hw, offset, MASKDWORD, | ||
2000 | apk_normal_setting_value_1 | ||
2001 | [index]); | ||
2002 | |||
2003 | offset += 0x04; | ||
2004 | } | ||
2005 | |||
2006 | rtl_set_bbreg(hw, 0xb98, MASKDWORD, 0x12680000); | ||
2007 | |||
2008 | offset = 0xb68; | ||
2009 | for (; index < 13; index++) { | ||
2010 | rtl_set_bbreg(hw, offset, MASKDWORD, | ||
2011 | apk_normal_setting_value_1 | ||
2012 | [index]); | ||
2013 | |||
2014 | offset += 0x04; | ||
2015 | } | ||
2016 | |||
2017 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x40000000); | ||
2018 | |||
2019 | offset = 0xb00; | ||
2020 | for (index = 0; index < 16; index++) { | ||
2021 | rtl_set_bbreg(hw, offset, MASKDWORD, | ||
2022 | apk_normal_setting_value_2 | ||
2023 | [index]); | ||
2024 | |||
2025 | offset += 0x04; | ||
2026 | } | ||
2027 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); | ||
2028 | } else if (path == RF90_PATH_B) { | ||
2029 | offset = 0xb70; | ||
2030 | for (index = 0; index < 10; index++) { | ||
2031 | rtl_set_bbreg(hw, offset, MASKDWORD, | ||
2032 | apk_normal_setting_value_1 | ||
2033 | [index]); | ||
2034 | |||
2035 | offset += 0x04; | ||
2036 | } | ||
2037 | rtl_set_bbreg(hw, 0xb28, MASKDWORD, 0x12680000); | ||
2038 | rtl_set_bbreg(hw, 0xb98, MASKDWORD, 0x12680000); | ||
2039 | |||
2040 | offset = 0xb68; | ||
2041 | index = 11; | ||
2042 | for (; index < 13; index++) { | ||
2043 | rtl_set_bbreg(hw, offset, MASKDWORD, | ||
2044 | apk_normal_setting_value_1 | ||
2045 | [index]); | ||
2046 | |||
2047 | offset += 0x04; | ||
2048 | } | ||
2049 | |||
2050 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x40000000); | ||
2051 | |||
2052 | offset = 0xb60; | ||
2053 | for (index = 0; index < 16; index++) { | ||
2054 | rtl_set_bbreg(hw, offset, MASKDWORD, | ||
2055 | apk_normal_setting_value_2 | ||
2056 | [index]); | ||
2057 | |||
2058 | offset += 0x04; | ||
2059 | } | ||
2060 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); | ||
2061 | } | ||
2062 | |||
2063 | reg_d[path] = rtl_get_rfreg(hw, (enum radio_path)path, | ||
2064 | 0xd, MASKDWORD); | ||
2065 | |||
2066 | for (index = 0; index < APK_AFE_REG_NUM; index++) | ||
2067 | rtl_set_bbreg(hw, afe_reg[index], MASKDWORD, | ||
2068 | afe_on_off[path]); | ||
2069 | |||
2070 | if (path == RF90_PATH_A) { | ||
2071 | for (index = 0; index < APK_BB_REG_NUM; index++) { | ||
2072 | if (index == 0) | ||
2073 | continue; | ||
2074 | rtl_set_bbreg(hw, bb_reg[index], MASKDWORD, | ||
2075 | bb_ap_mode[index]); | ||
2076 | } | ||
2077 | } | ||
2078 | |||
2079 | _rtl92c_phy_mac_setting_calibration(hw, mac_reg, mac_backup); | ||
2080 | |||
2081 | if (path == 0) { | ||
2082 | rtl_set_rfreg(hw, RF90_PATH_B, 0x0, MASKDWORD, 0x10000); | ||
2083 | } else { | ||
2084 | rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASKDWORD, | ||
2085 | 0x10000); | ||
2086 | rtl_set_rfreg(hw, RF90_PATH_A, 0x10, MASKDWORD, | ||
2087 | 0x1000f); | ||
2088 | rtl_set_rfreg(hw, RF90_PATH_A, 0x11, MASKDWORD, | ||
2089 | 0x20103); | ||
2090 | } | ||
2091 | |||
2092 | delta_offset = ((delta + 14) / 2); | ||
2093 | if (delta_offset < 0) | ||
2094 | delta_offset = 0; | ||
2095 | else if (delta_offset > 12) | ||
2096 | delta_offset = 12; | ||
2097 | |||
2098 | for (index = 0; index < APK_BB_REG_NUM; index++) { | ||
2099 | if (index != 1) | ||
2100 | continue; | ||
2101 | |||
2102 | tmpreg = apk_rf_init_value[path][index]; | ||
2103 | |||
2104 | if (!rtlefuse->b_apk_thermalmeterignore) { | ||
2105 | bb_offset = (tmpreg & 0xF0000) >> 16; | ||
2106 | |||
2107 | if (!(tmpreg & BIT(15))) | ||
2108 | bb_offset = -bb_offset; | ||
2109 | |||
2110 | delta_v = | ||
2111 | apk_delta_mapping[index][delta_offset]; | ||
2112 | |||
2113 | bb_offset += delta_v; | ||
2114 | |||
2115 | if (bb_offset < 0) { | ||
2116 | tmpreg = tmpreg & (~BIT(15)); | ||
2117 | bb_offset = -bb_offset; | ||
2118 | } else { | ||
2119 | tmpreg = tmpreg | BIT(15); | ||
2120 | } | ||
2121 | |||
2122 | tmpreg = | ||
2123 | (tmpreg & 0xFFF0FFFF) | (bb_offset << 16); | ||
2124 | } | ||
2125 | |||
2126 | rtl_set_rfreg(hw, (enum radio_path)path, 0xc, | ||
2127 | MASKDWORD, 0x8992e); | ||
2128 | rtl_set_rfreg(hw, (enum radio_path)path, 0x0, | ||
2129 | MASKDWORD, apk_rf_value_0[path][index]); | ||
2130 | rtl_set_rfreg(hw, (enum radio_path)path, 0xd, | ||
2131 | MASKDWORD, tmpreg); | ||
2132 | |||
2133 | i = 0; | ||
2134 | do { | ||
2135 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80000000); | ||
2136 | rtl_set_bbreg(hw, apk_offset[path], | ||
2137 | MASKDWORD, apk_value[0]); | ||
2138 | RTPRINT(rtlpriv, FINIT, INIT_IQK, | ||
2139 | ("PHY_APCalibrate() offset 0x%x " | ||
2140 | "value 0x%x\n", | ||
2141 | apk_offset[path], | ||
2142 | rtl_get_bbreg(hw, apk_offset[path], | ||
2143 | MASKDWORD))); | ||
2144 | |||
2145 | mdelay(3); | ||
2146 | |||
2147 | rtl_set_bbreg(hw, apk_offset[path], | ||
2148 | MASKDWORD, apk_value[1]); | ||
2149 | RTPRINT(rtlpriv, FINIT, INIT_IQK, | ||
2150 | ("PHY_APCalibrate() offset 0x%x " | ||
2151 | "value 0x%x\n", | ||
2152 | apk_offset[path], | ||
2153 | rtl_get_bbreg(hw, apk_offset[path], | ||
2154 | MASKDWORD))); | ||
2155 | |||
2156 | mdelay(20); | ||
2157 | |||
2158 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); | ||
2159 | |||
2160 | if (path == RF90_PATH_A) | ||
2161 | tmpreg = rtl_get_bbreg(hw, 0xbd8, | ||
2162 | 0x03E00000); | ||
2163 | else | ||
2164 | tmpreg = rtl_get_bbreg(hw, 0xbd8, | ||
2165 | 0xF8000000); | ||
2166 | |||
2167 | RTPRINT(rtlpriv, FINIT, INIT_IQK, | ||
2168 | ("PHY_APCalibrate() offset " | ||
2169 | "0xbd8[25:21] %x\n", tmpreg)); | ||
2170 | |||
2171 | i++; | ||
2172 | |||
2173 | } while (tmpreg > apkbound && i < 4); | ||
2174 | |||
2175 | apk_result[path][index] = tmpreg; | ||
2176 | } | ||
2177 | } | ||
2178 | |||
2179 | _rtl92c_phy_reload_mac_registers(hw, mac_reg, mac_backup); | ||
2180 | |||
2181 | for (index = 0; index < APK_BB_REG_NUM; index++) { | ||
2182 | if (index == 0) | ||
2183 | continue; | ||
2184 | rtl_set_bbreg(hw, bb_reg[index], MASKDWORD, bb_backup[index]); | ||
2185 | } | ||
2186 | |||
2187 | _rtl92c_phy_reload_adda_registers(hw, afe_reg, afe_backup, 16); | ||
2188 | |||
2189 | for (path = 0; path < pathbound; path++) { | ||
2190 | rtl_set_rfreg(hw, (enum radio_path)path, 0xd, | ||
2191 | MASKDWORD, reg_d[path]); | ||
2192 | |||
2193 | if (path == RF90_PATH_B) { | ||
2194 | rtl_set_rfreg(hw, RF90_PATH_A, 0x10, MASKDWORD, | ||
2195 | 0x1000f); | ||
2196 | rtl_set_rfreg(hw, RF90_PATH_A, 0x11, MASKDWORD, | ||
2197 | 0x20101); | ||
2198 | } | ||
2199 | |||
2200 | if (apk_result[path][1] > 6) | ||
2201 | apk_result[path][1] = 6; | ||
2202 | } | ||
2203 | |||
2204 | for (path = 0; path < pathbound; path++) { | ||
2205 | rtl_set_rfreg(hw, (enum radio_path)path, 0x3, MASKDWORD, | ||
2206 | ((apk_result[path][1] << 15) | | ||
2207 | (apk_result[path][1] << 10) | | ||
2208 | (apk_result[path][1] << 5) | | ||
2209 | apk_result[path][1])); | ||
2210 | |||
2211 | if (path == RF90_PATH_A) | ||
2212 | rtl_set_rfreg(hw, (enum radio_path)path, 0x4, MASKDWORD, | ||
2213 | ((apk_result[path][1] << 15) | | ||
2214 | (apk_result[path][1] << 10) | | ||
2215 | (0x00 << 5) | 0x05)); | ||
2216 | else | ||
2217 | rtl_set_rfreg(hw, (enum radio_path)path, 0x4, MASKDWORD, | ||
2218 | ((apk_result[path][1] << 15) | | ||
2219 | (apk_result[path][1] << 10) | | ||
2220 | (0x02 << 5) | 0x05)); | ||
2221 | |||
2222 | rtl_set_rfreg(hw, (enum radio_path)path, 0xe, MASKDWORD, | ||
2223 | ((0x08 << 15) | (0x08 << 10) | (0x08 << 5) | | ||
2224 | 0x08)); | ||
2225 | |||
2226 | } | ||
2227 | |||
2228 | rtlphy->b_apk_done = true; | ||
2229 | #endif | ||
2230 | } | ||
2231 | |||
2232 | static void _rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, | ||
2233 | bool bmain, bool is2t) | ||
2234 | { | ||
2235 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
2236 | |||
2237 | if (is_hal_stop(rtlhal)) { | ||
2238 | rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01); | ||
2239 | rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01); | ||
2240 | } | ||
2241 | if (is2t) { | ||
2242 | if (bmain) | ||
2243 | rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, | ||
2244 | BIT(5) | BIT(6), 0x1); | ||
2245 | else | ||
2246 | rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, | ||
2247 | BIT(5) | BIT(6), 0x2); | ||
2248 | } else { | ||
2249 | if (bmain) | ||
2250 | rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2); | ||
2251 | else | ||
2252 | rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1); | ||
2253 | |||
2254 | } | ||
2255 | } | ||
2256 | |||
2257 | #undef IQK_ADDA_REG_NUM | ||
2258 | #undef IQK_DELAY_TIME | ||
2259 | |||
2260 | void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery) | ||
2261 | { | ||
2262 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2263 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
2264 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
2265 | |||
2266 | long result[4][8]; | ||
2267 | u8 i, final_candidate; | ||
2268 | bool b_patha_ok, b_pathb_ok; | ||
2269 | long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4, | ||
2270 | reg_ecc, reg_tmp = 0; | ||
2271 | bool is12simular, is13simular, is23simular; | ||
2272 | bool b_start_conttx = false, b_singletone = false; | ||
2273 | u32 iqk_bb_reg[10] = { | ||
2274 | ROFDM0_XARXIQIMBALANCE, | ||
2275 | ROFDM0_XBRXIQIMBALANCE, | ||
2276 | ROFDM0_ECCATHRESHOLD, | ||
2277 | ROFDM0_AGCRSSITABLE, | ||
2278 | ROFDM0_XATXIQIMBALANCE, | ||
2279 | ROFDM0_XBTXIQIMBALANCE, | ||
2280 | ROFDM0_XCTXIQIMBALANCE, | ||
2281 | ROFDM0_XCTXAFE, | ||
2282 | ROFDM0_XDTXAFE, | ||
2283 | ROFDM0_RXIQEXTANTA | ||
2284 | }; | ||
2285 | |||
2286 | if (b_recovery) { | ||
2287 | _rtl92c_phy_reload_adda_registers(hw, | ||
2288 | iqk_bb_reg, | ||
2289 | rtlphy->iqk_bb_backup, 10); | ||
2290 | return; | ||
2291 | } | ||
2292 | if (b_start_conttx || b_singletone) | ||
2293 | return; | ||
2294 | for (i = 0; i < 8; i++) { | ||
2295 | result[0][i] = 0; | ||
2296 | result[1][i] = 0; | ||
2297 | result[2][i] = 0; | ||
2298 | result[3][i] = 0; | ||
2299 | } | ||
2300 | final_candidate = 0xff; | ||
2301 | b_patha_ok = false; | ||
2302 | b_pathb_ok = false; | ||
2303 | is12simular = false; | ||
2304 | is23simular = false; | ||
2305 | is13simular = false; | ||
2306 | for (i = 0; i < 3; i++) { | ||
2307 | if (IS_92C_SERIAL(rtlhal->version)) | ||
2308 | _rtl92c_phy_iq_calibrate(hw, result, i, true); | ||
2309 | else | ||
2310 | _rtl92c_phy_iq_calibrate(hw, result, i, false); | ||
2311 | if (i == 1) { | ||
2312 | is12simular = _rtl92c_phy_simularity_compare(hw, | ||
2313 | result, 0, | ||
2314 | 1); | ||
2315 | if (is12simular) { | ||
2316 | final_candidate = 0; | ||
2317 | break; | ||
2318 | } | ||
2319 | } | ||
2320 | if (i == 2) { | ||
2321 | is13simular = _rtl92c_phy_simularity_compare(hw, | ||
2322 | result, 0, | ||
2323 | 2); | ||
2324 | if (is13simular) { | ||
2325 | final_candidate = 0; | ||
2326 | break; | ||
2327 | } | ||
2328 | is23simular = _rtl92c_phy_simularity_compare(hw, | ||
2329 | result, 1, | ||
2330 | 2); | ||
2331 | if (is23simular) | ||
2332 | final_candidate = 1; | ||
2333 | else { | ||
2334 | for (i = 0; i < 8; i++) | ||
2335 | reg_tmp += result[3][i]; | ||
2336 | |||
2337 | if (reg_tmp != 0) | ||
2338 | final_candidate = 3; | ||
2339 | else | ||
2340 | final_candidate = 0xFF; | ||
2341 | } | ||
2342 | } | ||
2343 | } | ||
2344 | for (i = 0; i < 4; i++) { | ||
2345 | reg_e94 = result[i][0]; | ||
2346 | reg_e9c = result[i][1]; | ||
2347 | reg_ea4 = result[i][2]; | ||
2348 | reg_eac = result[i][3]; | ||
2349 | reg_eb4 = result[i][4]; | ||
2350 | reg_ebc = result[i][5]; | ||
2351 | reg_ec4 = result[i][6]; | ||
2352 | reg_ecc = result[i][7]; | ||
2353 | } | ||
2354 | if (final_candidate != 0xff) { | ||
2355 | rtlphy->reg_e94 = reg_e94 = result[final_candidate][0]; | ||
2356 | rtlphy->reg_e9c = reg_e9c = result[final_candidate][1]; | ||
2357 | reg_ea4 = result[final_candidate][2]; | ||
2358 | reg_eac = result[final_candidate][3]; | ||
2359 | rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4]; | ||
2360 | rtlphy->reg_ebc = reg_ebc = result[final_candidate][5]; | ||
2361 | reg_ec4 = result[final_candidate][6]; | ||
2362 | reg_ecc = result[final_candidate][7]; | ||
2363 | b_patha_ok = b_pathb_ok = true; | ||
2364 | } else { | ||
2365 | rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; | ||
2366 | rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0; | ||
2367 | } | ||
2368 | if (reg_e94 != 0) /*&&(reg_ea4 != 0) */ | ||
2369 | _rtl92c_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result, | ||
2370 | final_candidate, | ||
2371 | (reg_ea4 == 0)); | ||
2372 | if (IS_92C_SERIAL(rtlhal->version)) { | ||
2373 | if (reg_eb4 != 0) /*&&(reg_ec4 != 0) */ | ||
2374 | _rtl92c_phy_path_b_fill_iqk_matrix(hw, b_pathb_ok, | ||
2375 | result, | ||
2376 | final_candidate, | ||
2377 | (reg_ec4 == 0)); | ||
2378 | } | ||
2379 | _rtl92c_phy_save_adda_registers(hw, iqk_bb_reg, | ||
2380 | rtlphy->iqk_bb_backup, 10); | ||
2381 | } | ||
2382 | |||
2383 | void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw) | ||
2384 | { | ||
2385 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
2386 | bool b_start_conttx = false, b_singletone = false; | ||
2387 | |||
2388 | if (b_start_conttx || b_singletone) | ||
2389 | return; | ||
2390 | if (IS_92C_SERIAL(rtlhal->version)) | ||
2391 | _rtl92c_phy_lc_calibrate(hw, true); | ||
2392 | else | ||
2393 | _rtl92c_phy_lc_calibrate(hw, false); | ||
2394 | } | ||
2395 | |||
2396 | void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta) | ||
2397 | { | ||
2398 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2399 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
2400 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
2401 | |||
2402 | if (rtlphy->b_apk_done) | ||
2403 | return; | ||
2404 | if (IS_92C_SERIAL(rtlhal->version)) | ||
2405 | _rtl92c_phy_ap_calibrate(hw, delta, true); | ||
2406 | else | ||
2407 | _rtl92c_phy_ap_calibrate(hw, delta, false); | ||
2408 | } | ||
2409 | |||
2410 | void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain) | ||
2411 | { | ||
2412 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
2413 | |||
2414 | if (IS_92C_SERIAL(rtlhal->version)) | ||
2415 | _rtl92c_phy_set_rfpath_switch(hw, bmain, true); | ||
2416 | else | ||
2417 | _rtl92c_phy_set_rfpath_switch(hw, bmain, false); | ||
2418 | } | ||
2419 | |||
2420 | bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) | ||
2421 | { | ||
2422 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2423 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
2424 | bool b_postprocessing = false; | ||
2425 | |||
2426 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, | ||
2427 | ("-->IO Cmd(%#x), set_io_inprogress(%d)\n", | ||
2428 | iotype, rtlphy->set_io_inprogress)); | ||
2429 | do { | ||
2430 | switch (iotype) { | ||
2431 | case IO_CMD_RESUME_DM_BY_SCAN: | ||
2432 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, | ||
2433 | ("[IO CMD] Resume DM after scan.\n")); | ||
2434 | b_postprocessing = true; | ||
2435 | break; | ||
2436 | case IO_CMD_PAUSE_DM_BY_SCAN: | ||
2437 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, | ||
2438 | ("[IO CMD] Pause DM before scan.\n")); | ||
2439 | b_postprocessing = true; | ||
2440 | break; | ||
2441 | default: | ||
2442 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
2443 | ("switch case not process\n")); | ||
2444 | break; | ||
2445 | } | ||
2446 | } while (false); | ||
2447 | if (b_postprocessing && !rtlphy->set_io_inprogress) { | ||
2448 | rtlphy->set_io_inprogress = true; | ||
2449 | rtlphy->current_io_type = iotype; | ||
2450 | } else { | ||
2451 | return false; | ||
2452 | } | ||
2453 | rtl92c_phy_set_io(hw); | ||
2454 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, ("<--IO Type(%#x)\n", iotype)); | ||
2455 | return true; | ||
2456 | } | ||
2457 | |||
2458 | void rtl92c_phy_set_io(struct ieee80211_hw *hw) | ||
2459 | { | ||
2460 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2461 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
2462 | |||
2463 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, | ||
2464 | ("--->Cmd(%#x), set_io_inprogress(%d)\n", | ||
2465 | rtlphy->current_io_type, rtlphy->set_io_inprogress)); | ||
2466 | switch (rtlphy->current_io_type) { | ||
2467 | case IO_CMD_RESUME_DM_BY_SCAN: | ||
2468 | dm_digtable.cur_igvalue = rtlphy->initgain_backup.xaagccore1; | ||
2469 | rtl92c_dm_write_dig(hw); | ||
2470 | rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); | ||
2471 | break; | ||
2472 | case IO_CMD_PAUSE_DM_BY_SCAN: | ||
2473 | rtlphy->initgain_backup.xaagccore1 = dm_digtable.cur_igvalue; | ||
2474 | dm_digtable.cur_igvalue = 0x17; | ||
2475 | rtl92c_dm_write_dig(hw); | ||
2476 | break; | ||
2477 | default: | ||
2478 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
2479 | ("switch case not process\n")); | ||
2480 | break; | ||
2481 | } | ||
2482 | rtlphy->set_io_inprogress = false; | ||
2483 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, | ||
2484 | ("<---(%#x)\n", rtlphy->current_io_type)); | ||
2485 | } | ||
2486 | |||
2487 | void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw) | ||
2488 | { | ||
2489 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2490 | |||
2491 | rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); | ||
2492 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); | ||
2493 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); | ||
2494 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); | ||
2495 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); | ||
2496 | rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); | ||
2497 | } | ||
2498 | |||
2499 | static void _rtl92ce_phy_set_rf_sleep(struct ieee80211_hw *hw) | ||
2500 | { | ||
2501 | u32 u4b_tmp; | ||
2502 | u8 delay = 5; | ||
2503 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2504 | |||
2505 | rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); | ||
2506 | rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); | ||
2507 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); | ||
2508 | u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); | ||
2509 | while (u4b_tmp != 0 && delay > 0) { | ||
2510 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0); | ||
2511 | rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); | ||
2512 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); | ||
2513 | u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); | ||
2514 | delay--; | ||
2515 | } | ||
2516 | if (delay == 0) { | ||
2517 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); | ||
2518 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); | ||
2519 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); | ||
2520 | rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); | ||
2521 | RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, | ||
2522 | ("Switch RF timeout !!!.\n")); | ||
2523 | return; | ||
2524 | } | ||
2525 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); | ||
2526 | rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); | ||
2527 | } | ||
2528 | |||
2529 | static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, | 483 | static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, |
2530 | enum rf_pwrstate rfpwr_state) | 484 | enum rf_pwrstate rfpwr_state) |
2531 | { | 485 | { |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h index ca4daee6e9a8..3fc60e434cef 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h | |||
@@ -57,8 +57,6 @@ | |||
57 | #define IQK_MAC_REG_NUM 4 | 57 | #define IQK_MAC_REG_NUM 4 |
58 | 58 | ||
59 | #define RF90_PATH_MAX 2 | 59 | #define RF90_PATH_MAX 2 |
60 | #define CHANNEL_MAX_NUMBER 14 | ||
61 | #define CHANNEL_GROUP_MAX 3 | ||
62 | 60 | ||
63 | #define CT_OFFSET_MAC_ADDR 0X16 | 61 | #define CT_OFFSET_MAC_ADDR 0X16 |
64 | 62 | ||
@@ -78,9 +76,7 @@ | |||
78 | #define CT_OFFSET_CUSTOMER_ID 0x7F | 76 | #define CT_OFFSET_CUSTOMER_ID 0x7F |
79 | 77 | ||
80 | #define RTL92C_MAX_PATH_NUM 2 | 78 | #define RTL92C_MAX_PATH_NUM 2 |
81 | #define CHANNEL_MAX_NUMBER 14 | 79 | #define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER 255 |
82 | #define CHANNEL_GROUP_MAX 3 | ||
83 | |||
84 | enum swchnlcmd_id { | 80 | enum swchnlcmd_id { |
85 | CMDID_END, | 81 | CMDID_END, |
86 | CMDID_SET_TXPOWEROWER_LEVEL, | 82 | CMDID_SET_TXPOWEROWER_LEVEL, |
@@ -233,5 +229,6 @@ void rtl92c_phy_config_bb_external_pa(struct ieee80211_hw *hw); | |||
233 | void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw); | 229 | void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw); |
234 | bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); | 230 | bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); |
235 | void rtl92c_phy_set_io(struct ieee80211_hw *hw); | 231 | void rtl92c_phy_set_io(struct ieee80211_hw *hw); |
232 | void rtl92c_bb_block_on(struct ieee80211_hw *hw); | ||
236 | 233 | ||
237 | #endif | 234 | #endif |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h index 875d51465225..b0868a613841 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h | |||
@@ -63,7 +63,15 @@ | |||
63 | #define REG_LEDCFG3 0x004F | 63 | #define REG_LEDCFG3 0x004F |
64 | #define REG_FSIMR 0x0050 | 64 | #define REG_FSIMR 0x0050 |
65 | #define REG_FSISR 0x0054 | 65 | #define REG_FSISR 0x0054 |
66 | 66 | #define REG_HSIMR 0x0058 | |
67 | #define REG_HSISR 0x005c | ||
68 | |||
69 | /* RTL8723 WIFI/BT/GPS Multi-Function GPIO Pin Control. */ | ||
70 | #define REG_GPIO_PIN_CTRL_2 0x0060 | ||
71 | /* RTL8723 WIFI/BT/GPS Multi-Function GPIO Select. */ | ||
72 | #define REG_GPIO_IO_SEL_2 0x0062 | ||
73 | /* RTL8723 WIFI/BT/GPS Multi-Function control source. */ | ||
74 | #define REG_MULTI_FUNC_CTRL 0x0068 | ||
67 | #define REG_MCUFWDL 0x0080 | 75 | #define REG_MCUFWDL 0x0080 |
68 | 76 | ||
69 | #define REG_HMEBOX_EXT_0 0x0088 | 77 | #define REG_HMEBOX_EXT_0 0x0088 |
@@ -79,6 +87,7 @@ | |||
79 | #define REG_PCIE_MIO_INTD 0x00E8 | 87 | #define REG_PCIE_MIO_INTD 0x00E8 |
80 | #define REG_HPON_FSM 0x00EC | 88 | #define REG_HPON_FSM 0x00EC |
81 | #define REG_SYS_CFG 0x00F0 | 89 | #define REG_SYS_CFG 0x00F0 |
90 | #define REG_GPIO_OUTSTS 0x00F4 /* For RTL8723 only.*/ | ||
82 | 91 | ||
83 | #define REG_CR 0x0100 | 92 | #define REG_CR 0x0100 |
84 | #define REG_PBP 0x0104 | 93 | #define REG_PBP 0x0104 |
@@ -209,6 +218,8 @@ | |||
209 | #define REG_RDG_PIFS 0x0513 | 218 | #define REG_RDG_PIFS 0x0513 |
210 | #define REG_SIFS_CTX 0x0514 | 219 | #define REG_SIFS_CTX 0x0514 |
211 | #define REG_SIFS_TRX 0x0516 | 220 | #define REG_SIFS_TRX 0x0516 |
221 | #define REG_SIFS_CCK 0x0514 | ||
222 | #define REG_SIFS_OFDM 0x0516 | ||
212 | #define REG_AGGR_BREAK_TIME 0x051A | 223 | #define REG_AGGR_BREAK_TIME 0x051A |
213 | #define REG_SLOT 0x051B | 224 | #define REG_SLOT 0x051B |
214 | #define REG_TX_PTCL_CTRL 0x0520 | 225 | #define REG_TX_PTCL_CTRL 0x0520 |
@@ -261,6 +272,10 @@ | |||
261 | #define REG_MAC_SPEC_SIFS 0x063A | 272 | #define REG_MAC_SPEC_SIFS 0x063A |
262 | #define REG_RESP_SIFS_CCK 0x063C | 273 | #define REG_RESP_SIFS_CCK 0x063C |
263 | #define REG_RESP_SIFS_OFDM 0x063E | 274 | #define REG_RESP_SIFS_OFDM 0x063E |
275 | /* [15:8]SIFS_R2T_OFDM, [7:0]SIFS_R2T_CCK */ | ||
276 | #define REG_R2T_SIFS 0x063C | ||
277 | /* [15:8]SIFS_T2T_OFDM, [7:0]SIFS_T2T_CCK */ | ||
278 | #define REG_T2T_SIFS 0x063E | ||
264 | #define REG_ACKTO 0x0640 | 279 | #define REG_ACKTO 0x0640 |
265 | #define REG_CTS2TO 0x0641 | 280 | #define REG_CTS2TO 0x0641 |
266 | #define REG_EIFS 0x0642 | 281 | #define REG_EIFS 0x0642 |
@@ -641,9 +656,10 @@ | |||
641 | #define STOPBE BIT(1) | 656 | #define STOPBE BIT(1) |
642 | #define STOPBK BIT(0) | 657 | #define STOPBK BIT(0) |
643 | 658 | ||
644 | #define RCR_APPFCS BIT(31) | 659 | #define RCR_APP_FCS BIT(31) |
645 | #define RCR_APP_MIC BIT(30) | 660 | #define RCR_APP_MIC BIT(30) |
646 | #define RCR_APP_ICV BIT(29) | 661 | #define RCR_APP_ICV BIT(29) |
662 | #define RCR_APP_PHYSTS BIT(28) | ||
647 | #define RCR_APP_PHYST_RXFF BIT(28) | 663 | #define RCR_APP_PHYST_RXFF BIT(28) |
648 | #define RCR_APP_BA_SSN BIT(27) | 664 | #define RCR_APP_BA_SSN BIT(27) |
649 | #define RCR_ENMBID BIT(24) | 665 | #define RCR_ENMBID BIT(24) |
@@ -759,6 +775,7 @@ | |||
759 | 775 | ||
760 | #define BOOT_FROM_EEPROM BIT(4) | 776 | #define BOOT_FROM_EEPROM BIT(4) |
761 | #define EEPROM_EN BIT(5) | 777 | #define EEPROM_EN BIT(5) |
778 | #define EEPROMSEL BOOT_FROM_EEPROM | ||
762 | 779 | ||
763 | #define AFE_BGEN BIT(0) | 780 | #define AFE_BGEN BIT(0) |
764 | #define AFE_MBEN BIT(1) | 781 | #define AFE_MBEN BIT(1) |
@@ -876,6 +893,8 @@ | |||
876 | #define BD_MAC2 BIT(9) | 893 | #define BD_MAC2 BIT(9) |
877 | #define BD_MAC1 BIT(10) | 894 | #define BD_MAC1 BIT(10) |
878 | #define IC_MACPHY_MODE BIT(11) | 895 | #define IC_MACPHY_MODE BIT(11) |
896 | #define BT_FUNC BIT(16) | ||
897 | #define VENDOR_ID BIT(19) | ||
879 | #define PAD_HWPD_IDN BIT(22) | 898 | #define PAD_HWPD_IDN BIT(22) |
880 | #define TRP_VAUX_EN BIT(23) | 899 | #define TRP_VAUX_EN BIT(23) |
881 | #define TRP_BT_EN BIT(24) | 900 | #define TRP_BT_EN BIT(24) |
@@ -883,6 +902,28 @@ | |||
883 | #define BD_HCI_SEL BIT(26) | 902 | #define BD_HCI_SEL BIT(26) |
884 | #define TYPE_ID BIT(27) | 903 | #define TYPE_ID BIT(27) |
885 | 904 | ||
905 | /* REG_GPIO_OUTSTS (For RTL8723 only) */ | ||
906 | #define EFS_HCI_SEL (BIT(0)|BIT(1)) | ||
907 | #define PAD_HCI_SEL (BIT(2)|BIT(3)) | ||
908 | #define HCI_SEL (BIT(4)|BIT(5)) | ||
909 | #define PKG_SEL_HCI BIT(6) | ||
910 | #define FEN_GPS BIT(7) | ||
911 | #define FEN_BT BIT(8) | ||
912 | #define FEN_WL BIT(9) | ||
913 | #define FEN_PCI BIT(10) | ||
914 | #define FEN_USB BIT(11) | ||
915 | #define BTRF_HWPDN_N BIT(12) | ||
916 | #define WLRF_HWPDN_N BIT(13) | ||
917 | #define PDN_BT_N BIT(14) | ||
918 | #define PDN_GPS_N BIT(15) | ||
919 | #define BT_CTL_HWPDN BIT(16) | ||
920 | #define GPS_CTL_HWPDN BIT(17) | ||
921 | #define PPHY_SUSB BIT(20) | ||
922 | #define UPHY_SUSB BIT(21) | ||
923 | #define PCI_SUSEN BIT(22) | ||
924 | #define USB_SUSEN BIT(23) | ||
925 | #define RF_RL_ID (BIT(31) | BIT(30) | BIT(29) | BIT(28)) | ||
926 | |||
886 | #define CHIP_VER_RTL_MASK 0xF000 | 927 | #define CHIP_VER_RTL_MASK 0xF000 |
887 | #define CHIP_VER_RTL_SHIFT 12 | 928 | #define CHIP_VER_RTL_SHIFT 12 |
888 | 929 | ||
@@ -1035,7 +1076,7 @@ | |||
1035 | #define _RARF_RC7(x) (((x) & 0x1F) << 16) | 1076 | #define _RARF_RC7(x) (((x) & 0x1F) << 16) |
1036 | #define _RARF_RC8(x) (((x) & 0x1F) << 24) | 1077 | #define _RARF_RC8(x) (((x) & 0x1F) << 24) |
1037 | 1078 | ||
1038 | #define AC_PARAM_TXOP_LIMIT_OFFSET 16 | 1079 | #define AC_PARAM_TXOP_OFFSET 16 |
1039 | #define AC_PARAM_ECW_MAX_OFFSET 12 | 1080 | #define AC_PARAM_ECW_MAX_OFFSET 12 |
1040 | #define AC_PARAM_ECW_MIN_OFFSET 8 | 1081 | #define AC_PARAM_ECW_MIN_OFFSET 8 |
1041 | #define AC_PARAM_AIFS_OFFSET 0 | 1082 | #define AC_PARAM_AIFS_OFFSET 0 |
@@ -1184,6 +1225,30 @@ | |||
1184 | 1225 | ||
1185 | #define HAL_8192C_HW_GPIO_WPS_BIT BIT(2) | 1226 | #define HAL_8192C_HW_GPIO_WPS_BIT BIT(2) |
1186 | 1227 | ||
1228 | /* REG_MULTI_FUNC_CTRL(For RTL8723 Only) */ | ||
1229 | /* Enable GPIO[9] as WiFi HW PDn source */ | ||
1230 | #define WL_HWPDN_EN BIT(0) | ||
1231 | /* WiFi HW PDn polarity control */ | ||
1232 | #define WL_HWPDN_SL BIT(1) | ||
1233 | /* WiFi function enable */ | ||
1234 | #define WL_FUNC_EN BIT(2) | ||
1235 | /* Enable GPIO[9] as WiFi RF HW PDn source */ | ||
1236 | #define WL_HWROF_EN BIT(3) | ||
1237 | /* Enable GPIO[11] as BT HW PDn source */ | ||
1238 | #define BT_HWPDN_EN BIT(16) | ||
1239 | /* BT HW PDn polarity control */ | ||
1240 | #define BT_HWPDN_SL BIT(17) | ||
1241 | /* BT function enable */ | ||
1242 | #define BT_FUNC_EN BIT(18) | ||
1243 | /* Enable GPIO[11] as BT/GPS RF HW PDn source */ | ||
1244 | #define BT_HWROF_EN BIT(19) | ||
1245 | /* Enable GPIO[10] as GPS HW PDn source */ | ||
1246 | #define GPS_HWPDN_EN BIT(20) | ||
1247 | /* GPS HW PDn polarity control */ | ||
1248 | #define GPS_HWPDN_SL BIT(21) | ||
1249 | /* GPS function enable */ | ||
1250 | #define GPS_FUNC_EN BIT(22) | ||
1251 | |||
1187 | #define RPMAC_RESET 0x100 | 1252 | #define RPMAC_RESET 0x100 |
1188 | #define RPMAC_TXSTART 0x104 | 1253 | #define RPMAC_TXSTART 0x104 |
1189 | #define RPMAC_TXLEGACYSIG 0x108 | 1254 | #define RPMAC_TXLEGACYSIG 0x108 |
@@ -1496,7 +1561,7 @@ | |||
1496 | #define BTXHTSTBC 0x30 | 1561 | #define BTXHTSTBC 0x30 |
1497 | #define BTXHTADVANCECODING 0x40 | 1562 | #define BTXHTADVANCECODING 0x40 |
1498 | #define BTXHTSHORTGI 0x80 | 1563 | #define BTXHTSHORTGI 0x80 |
1499 | #define BTXHTNUMBERHT_LT F 0x300 | 1564 | #define BTXHTNUMBERHT_LTF 0x300 |
1500 | #define BTXHTCRC8 0x3fc00 | 1565 | #define BTXHTCRC8 0x3fc00 |
1501 | #define BCOUNTERRESET 0x10000 | 1566 | #define BCOUNTERRESET 0x10000 |
1502 | #define BNUMOFOFDMTX 0xffff | 1567 | #define BNUMOFOFDMTX 0xffff |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index b366e8862929..b4df0b332832 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | |||
@@ -46,13 +46,13 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw) | |||
46 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 46 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
47 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 47 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
48 | 48 | ||
49 | rtlpriv->dm.b_dm_initialgain_enable = 1; | 49 | rtlpriv->dm.dm_initialgain_enable = 1; |
50 | rtlpriv->dm.dm_flag = 0; | 50 | rtlpriv->dm.dm_flag = 0; |
51 | rtlpriv->dm.b_disable_framebursting = 0;; | 51 | rtlpriv->dm.disable_framebursting = 0; |
52 | rtlpriv->dm.thermalvalue = 0; | 52 | rtlpriv->dm.thermalvalue = 0; |
53 | rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13); | 53 | rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13); |
54 | 54 | ||
55 | rtlpci->receive_config = (RCR_APPFCS | | 55 | rtlpci->receive_config = (RCR_APP_FCS | |
56 | RCR_AMF | | 56 | RCR_AMF | |
57 | RCR_ADF | | 57 | RCR_ADF | |
58 | RCR_APP_MIC | | 58 | RCR_APP_MIC | |
@@ -135,6 +135,7 @@ static struct rtl_hal_ops rtl8192ce_hal_ops = { | |||
135 | .set_bbreg = rtl92c_phy_set_bb_reg, | 135 | .set_bbreg = rtl92c_phy_set_bb_reg, |
136 | .get_rfreg = rtl92c_phy_query_rf_reg, | 136 | .get_rfreg = rtl92c_phy_query_rf_reg, |
137 | .set_rfreg = rtl92c_phy_set_rf_reg, | 137 | .set_rfreg = rtl92c_phy_set_rf_reg, |
138 | .cmd_send_packet = _rtl92c_cmd_send_packet, | ||
138 | }; | 139 | }; |
139 | 140 | ||
140 | static struct rtl_mod_params rtl92ce_mod_params = { | 141 | static struct rtl_mod_params rtl92ce_mod_params = { |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h index de1198c38d4e..0568d6dc83d7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h | |||
@@ -33,5 +33,7 @@ | |||
33 | int rtl92c_init_sw_vars(struct ieee80211_hw *hw); | 33 | int rtl92c_init_sw_vars(struct ieee80211_hw *hw); |
34 | void rtl92c_deinit_sw_vars(struct ieee80211_hw *hw); | 34 | void rtl92c_deinit_sw_vars(struct ieee80211_hw *hw); |
35 | void rtl92c_init_var_map(struct ieee80211_hw *hw); | 35 | void rtl92c_init_var_map(struct ieee80211_hw *hw); |
36 | bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, | ||
37 | struct sk_buff *skb); | ||
36 | 38 | ||
37 | #endif | 39 | #endif |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index bf5852f2d634..01b95427fee0 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | |||
@@ -36,7 +36,7 @@ | |||
36 | #include "trx.h" | 36 | #include "trx.h" |
37 | #include "led.h" | 37 | #include "led.h" |
38 | 38 | ||
39 | static enum rtl_desc_qsel _rtl92ce_map_hwqueue_to_fwqueue(u16 fc, | 39 | static enum rtl_desc_qsel _rtl92ce_map_hwqueue_to_fwqueue(__le16 fc, |
40 | unsigned int | 40 | unsigned int |
41 | skb_queue) | 41 | skb_queue) |
42 | { | 42 | { |
@@ -245,9 +245,9 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, | |||
245 | struct rtl_stats *pstats, | 245 | struct rtl_stats *pstats, |
246 | struct rx_desc_92c *pdesc, | 246 | struct rx_desc_92c *pdesc, |
247 | struct rx_fwinfo_92c *p_drvinfo, | 247 | struct rx_fwinfo_92c *p_drvinfo, |
248 | bool bpacket_match_bssid, | 248 | bool packet_match_bssid, |
249 | bool bpacket_toself, | 249 | bool packet_toself, |
250 | bool b_packet_beacon) | 250 | bool packet_beacon) |
251 | { | 251 | { |
252 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 252 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
253 | struct phy_sts_cck_8192s_t *cck_buf; | 253 | struct phy_sts_cck_8192s_t *cck_buf; |
@@ -258,11 +258,11 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, | |||
258 | bool is_cck_rate; | 258 | bool is_cck_rate; |
259 | 259 | ||
260 | is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc); | 260 | is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc); |
261 | pstats->b_packet_matchbssid = bpacket_match_bssid; | 261 | pstats->packet_matchbssid = packet_match_bssid; |
262 | pstats->b_packet_toself = bpacket_toself; | 262 | pstats->packet_toself = packet_toself; |
263 | pstats->b_is_cck = is_cck_rate; | 263 | pstats->is_cck = is_cck_rate; |
264 | pstats->b_packet_beacon = b_packet_beacon; | 264 | pstats->packet_beacon = packet_beacon; |
265 | pstats->b_is_cck = is_cck_rate; | 265 | pstats->is_cck = is_cck_rate; |
266 | pstats->rx_mimo_signalquality[0] = -1; | 266 | pstats->rx_mimo_signalquality[0] = -1; |
267 | pstats->rx_mimo_signalquality[1] = -1; | 267 | pstats->rx_mimo_signalquality[1] = -1; |
268 | 268 | ||
@@ -315,7 +315,7 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, | |||
315 | pstats->rx_pwdb_all = pwdb_all; | 315 | pstats->rx_pwdb_all = pwdb_all; |
316 | pstats->recvsignalpower = rx_pwr_all; | 316 | pstats->recvsignalpower = rx_pwr_all; |
317 | 317 | ||
318 | if (bpacket_match_bssid) { | 318 | if (packet_match_bssid) { |
319 | u8 sq; | 319 | u8 sq; |
320 | if (pstats->rx_pwdb_all > 40) | 320 | if (pstats->rx_pwdb_all > 40) |
321 | sq = 100; | 321 | sq = 100; |
@@ -334,10 +334,10 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, | |||
334 | pstats->rx_mimo_signalquality[1] = -1; | 334 | pstats->rx_mimo_signalquality[1] = -1; |
335 | } | 335 | } |
336 | } else { | 336 | } else { |
337 | rtlpriv->dm.brfpath_rxenable[0] = | 337 | rtlpriv->dm.rfpath_rxenable[0] = |
338 | rtlpriv->dm.brfpath_rxenable[1] = true; | 338 | rtlpriv->dm.rfpath_rxenable[1] = true; |
339 | for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) { | 339 | for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) { |
340 | if (rtlpriv->dm.brfpath_rxenable[i]) | 340 | if (rtlpriv->dm.rfpath_rxenable[i]) |
341 | rf_rx_num++; | 341 | rf_rx_num++; |
342 | 342 | ||
343 | rx_pwr[i] = | 343 | rx_pwr[i] = |
@@ -347,7 +347,7 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, | |||
347 | rtlpriv->stats.rx_snr_db[i] = | 347 | rtlpriv->stats.rx_snr_db[i] = |
348 | (long)(p_drvinfo->rxsnr[i] / 2); | 348 | (long)(p_drvinfo->rxsnr[i] / 2); |
349 | 349 | ||
350 | if (bpacket_match_bssid) | 350 | if (packet_match_bssid) |
351 | pstats->rx_mimo_signalstrength[i] = (u8) rssi; | 351 | pstats->rx_mimo_signalstrength[i] = (u8) rssi; |
352 | } | 352 | } |
353 | 353 | ||
@@ -366,7 +366,7 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, | |||
366 | for (i = 0; i < max_spatial_stream; i++) { | 366 | for (i = 0; i < max_spatial_stream; i++) { |
367 | evm = _rtl92c_evm_db_to_percentage(p_drvinfo->rxevm[i]); | 367 | evm = _rtl92c_evm_db_to_percentage(p_drvinfo->rxevm[i]); |
368 | 368 | ||
369 | if (bpacket_match_bssid) { | 369 | if (packet_match_bssid) { |
370 | if (i == 0) | 370 | if (i == 0) |
371 | pstats->signalquality = | 371 | pstats->signalquality = |
372 | (u8) (evm & 0xff); | 372 | (u8) (evm & 0xff); |
@@ -393,7 +393,7 @@ static void _rtl92ce_process_ui_rssi(struct ieee80211_hw *hw, | |||
393 | u8 rfpath; | 393 | u8 rfpath; |
394 | u32 last_rssi, tmpval; | 394 | u32 last_rssi, tmpval; |
395 | 395 | ||
396 | if (pstats->b_packet_toself || pstats->b_packet_beacon) { | 396 | if (pstats->packet_toself || pstats->packet_beacon) { |
397 | rtlpriv->stats.rssi_calculate_cnt++; | 397 | rtlpriv->stats.rssi_calculate_cnt++; |
398 | 398 | ||
399 | if (rtlpriv->stats.ui_rssi.total_num++ >= | 399 | if (rtlpriv->stats.ui_rssi.total_num++ >= |
@@ -421,7 +421,7 @@ static void _rtl92ce_process_ui_rssi(struct ieee80211_hw *hw, | |||
421 | pstats->rssi = rtlpriv->stats.signal_strength; | 421 | pstats->rssi = rtlpriv->stats.signal_strength; |
422 | } | 422 | } |
423 | 423 | ||
424 | if (!pstats->b_is_cck && pstats->b_packet_toself) { | 424 | if (!pstats->is_cck && pstats->packet_toself) { |
425 | for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; | 425 | for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; |
426 | rfpath++) { | 426 | rfpath++) { |
427 | 427 | ||
@@ -493,7 +493,7 @@ static void _rtl92ce_process_pwdb(struct ieee80211_hw *hw, | |||
493 | rtlpriv->dm.undecorated_smoothed_pwdb; | 493 | rtlpriv->dm.undecorated_smoothed_pwdb; |
494 | } | 494 | } |
495 | 495 | ||
496 | if (pstats->b_packet_toself || pstats->b_packet_beacon) { | 496 | if (pstats->packet_toself || pstats->packet_beacon) { |
497 | if (undecorated_smoothed_pwdb < 0) | 497 | if (undecorated_smoothed_pwdb < 0) |
498 | undecorated_smoothed_pwdb = pstats->rx_pwdb_all; | 498 | undecorated_smoothed_pwdb = pstats->rx_pwdb_all; |
499 | 499 | ||
@@ -525,7 +525,7 @@ static void _rtl92ce_process_ui_link_quality(struct ieee80211_hw *hw, | |||
525 | u32 last_evm, n_spatialstream, tmpval; | 525 | u32 last_evm, n_spatialstream, tmpval; |
526 | 526 | ||
527 | if (pstats->signalquality != 0) { | 527 | if (pstats->signalquality != 0) { |
528 | if (pstats->b_packet_toself || pstats->b_packet_beacon) { | 528 | if (pstats->packet_toself || pstats->packet_beacon) { |
529 | 529 | ||
530 | if (rtlpriv->stats.ui_link_quality.total_num++ >= | 530 | if (rtlpriv->stats.ui_link_quality.total_num++ >= |
531 | PHY_LINKQUALITY_SLID_WIN_MAX) { | 531 | PHY_LINKQUALITY_SLID_WIN_MAX) { |
@@ -595,8 +595,8 @@ static void _rtl92ce_process_phyinfo(struct ieee80211_hw *hw, | |||
595 | struct rtl_stats *pcurrent_stats) | 595 | struct rtl_stats *pcurrent_stats) |
596 | { | 596 | { |
597 | 597 | ||
598 | if (!pcurrent_stats->b_packet_matchbssid && | 598 | if (!pcurrent_stats->packet_matchbssid && |
599 | !pcurrent_stats->b_packet_beacon) | 599 | !pcurrent_stats->packet_beacon) |
600 | return; | 600 | return; |
601 | 601 | ||
602 | _rtl92ce_process_ui_rssi(hw, pcurrent_stats); | 602 | _rtl92ce_process_ui_rssi(hw, pcurrent_stats); |
@@ -617,34 +617,36 @@ static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw, | |||
617 | u8 *tmp_buf; | 617 | u8 *tmp_buf; |
618 | u8 *praddr; | 618 | u8 *praddr; |
619 | u8 *psaddr; | 619 | u8 *psaddr; |
620 | u16 fc, type; | 620 | __le16 fc; |
621 | bool b_packet_matchbssid, b_packet_toself, b_packet_beacon; | 621 | u16 type, c_fc; |
622 | bool packet_matchbssid, packet_toself, packet_beacon; | ||
622 | 623 | ||
623 | tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift; | 624 | tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift; |
624 | 625 | ||
625 | hdr = (struct ieee80211_hdr *)tmp_buf; | 626 | hdr = (struct ieee80211_hdr *)tmp_buf; |
626 | fc = le16_to_cpu(hdr->frame_control); | 627 | fc = hdr->frame_control; |
628 | c_fc = le16_to_cpu(fc); | ||
627 | type = WLAN_FC_GET_TYPE(fc); | 629 | type = WLAN_FC_GET_TYPE(fc); |
628 | praddr = hdr->addr1; | 630 | praddr = hdr->addr1; |
629 | psaddr = hdr->addr2; | 631 | psaddr = hdr->addr2; |
630 | 632 | ||
631 | b_packet_matchbssid = | 633 | packet_matchbssid = |
632 | ((IEEE80211_FTYPE_CTL != type) && | 634 | ((IEEE80211_FTYPE_CTL != type) && |
633 | (!compare_ether_addr(mac->bssid, | 635 | (!compare_ether_addr(mac->bssid, |
634 | (fc & IEEE80211_FCTL_TODS) ? | 636 | (c_fc & IEEE80211_FCTL_TODS) ? |
635 | hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS) ? | 637 | hdr->addr1 : (c_fc & IEEE80211_FCTL_FROMDS) ? |
636 | hdr->addr2 : hdr->addr3)) && | 638 | hdr->addr2 : hdr->addr3)) && |
637 | (!pstats->b_hwerror) && (!pstats->b_crc) && (!pstats->b_icv)); | 639 | (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv)); |
638 | 640 | ||
639 | b_packet_toself = b_packet_matchbssid && | 641 | packet_toself = packet_matchbssid && |
640 | (!compare_ether_addr(praddr, rtlefuse->dev_addr)); | 642 | (!compare_ether_addr(praddr, rtlefuse->dev_addr)); |
641 | 643 | ||
642 | if (ieee80211_is_beacon(fc)) | 644 | if (ieee80211_is_beacon(fc)) |
643 | b_packet_beacon = true; | 645 | packet_beacon = true; |
644 | 646 | ||
645 | _rtl92ce_query_rxphystatus(hw, pstats, pdesc, p_drvinfo, | 647 | _rtl92ce_query_rxphystatus(hw, pstats, pdesc, p_drvinfo, |
646 | b_packet_matchbssid, b_packet_toself, | 648 | packet_matchbssid, packet_toself, |
647 | b_packet_beacon); | 649 | packet_beacon); |
648 | 650 | ||
649 | _rtl92ce_process_phyinfo(hw, tmp_buf, pstats); | 651 | _rtl92ce_process_phyinfo(hw, tmp_buf, pstats); |
650 | } | 652 | } |
@@ -662,14 +664,14 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw, | |||
662 | stats->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) * | 664 | stats->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) * |
663 | RX_DRV_INFO_SIZE_UNIT; | 665 | RX_DRV_INFO_SIZE_UNIT; |
664 | stats->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03); | 666 | stats->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03); |
665 | stats->b_icv = (u16) GET_RX_DESC_ICV(pdesc); | 667 | stats->icv = (u16) GET_RX_DESC_ICV(pdesc); |
666 | stats->b_crc = (u16) GET_RX_DESC_CRC32(pdesc); | 668 | stats->crc = (u16) GET_RX_DESC_CRC32(pdesc); |
667 | stats->b_hwerror = (stats->b_crc | stats->b_icv); | 669 | stats->hwerror = (stats->crc | stats->icv); |
668 | stats->decrypted = !GET_RX_DESC_SWDEC(pdesc); | 670 | stats->decrypted = !GET_RX_DESC_SWDEC(pdesc); |
669 | stats->rate = (u8) GET_RX_DESC_RXMCS(pdesc); | 671 | stats->rate = (u8) GET_RX_DESC_RXMCS(pdesc); |
670 | stats->b_shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc); | 672 | stats->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc); |
671 | stats->b_isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1); | 673 | stats->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1); |
672 | stats->b_isampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1) | 674 | stats->isampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1) |
673 | && (GET_RX_DESC_FAGGR(pdesc) == 1)); | 675 | && (GET_RX_DESC_FAGGR(pdesc) == 1)); |
674 | stats->timestamp_low = GET_RX_DESC_TSFL(pdesc); | 676 | stats->timestamp_low = GET_RX_DESC_TSFL(pdesc); |
675 | stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc); | 677 | stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc); |
@@ -727,27 +729,24 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, | |||
727 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 729 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
728 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 730 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
729 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 731 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
730 | bool b_defaultadapter = true; | 732 | bool defaultadapter = true; |
731 | |||
732 | struct ieee80211_sta *sta = ieee80211_find_sta(mac->vif, mac->bssid); | 733 | struct ieee80211_sta *sta = ieee80211_find_sta(mac->vif, mac->bssid); |
733 | |||
734 | u8 *pdesc = (u8 *) pdesc_tx; | 734 | u8 *pdesc = (u8 *) pdesc_tx; |
735 | struct rtl_tcb_desc tcb_desc; | 735 | struct rtl_tcb_desc tcb_desc; |
736 | u8 *qc = ieee80211_get_qos_ctl(hdr); | 736 | u8 *qc = ieee80211_get_qos_ctl(hdr); |
737 | u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; | 737 | u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; |
738 | u16 seq_number; | 738 | u16 seq_number; |
739 | u16 fc = le16_to_cpu(hdr->frame_control); | 739 | __le16 fc = hdr->frame_control; |
740 | u8 rate_flag = info->control.rates[0].flags; | 740 | u8 rate_flag = info->control.rates[0].flags; |
741 | 741 | ||
742 | enum rtl_desc_qsel fw_qsel = | 742 | enum rtl_desc_qsel fw_qsel = |
743 | _rtl92ce_map_hwqueue_to_fwqueue(le16_to_cpu(hdr->frame_control), | 743 | _rtl92ce_map_hwqueue_to_fwqueue(fc, queue_index); |
744 | queue_index); | ||
745 | 744 | ||
746 | bool b_firstseg = ((hdr->seq_ctrl & | 745 | bool firstseg = ((hdr->seq_ctrl & |
747 | cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0); | 746 | cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0); |
748 | 747 | ||
749 | bool b_lastseg = ((hdr->frame_control & | 748 | bool lastseg = ((hdr->frame_control & |
750 | cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0); | 749 | cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0); |
751 | 750 | ||
752 | dma_addr_t mapping = pci_map_single(rtlpci->pdev, | 751 | dma_addr_t mapping = pci_map_single(rtlpci->pdev, |
753 | skb->data, skb->len, | 752 | skb->data, skb->len, |
@@ -759,7 +758,7 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, | |||
759 | 758 | ||
760 | CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92c)); | 759 | CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92c)); |
761 | 760 | ||
762 | if (b_firstseg) { | 761 | if (firstseg) { |
763 | SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); | 762 | SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); |
764 | 763 | ||
765 | SET_TX_DESC_TX_RATE(pdesc, tcb_desc.hw_rate); | 764 | SET_TX_DESC_TX_RATE(pdesc, tcb_desc.hw_rate); |
@@ -774,25 +773,25 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, | |||
774 | } | 773 | } |
775 | SET_TX_DESC_SEQ(pdesc, seq_number); | 774 | SET_TX_DESC_SEQ(pdesc, seq_number); |
776 | 775 | ||
777 | SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc.b_rts_enable && | 776 | SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc.rts_enable && |
778 | !tcb_desc. | 777 | !tcb_desc. |
779 | b_cts_enable) ? 1 : 0)); | 778 | cts_enable) ? 1 : 0)); |
780 | SET_TX_DESC_HW_RTS_ENABLE(pdesc, | 779 | SET_TX_DESC_HW_RTS_ENABLE(pdesc, |
781 | ((tcb_desc.b_rts_enable | 780 | ((tcb_desc.rts_enable |
782 | || tcb_desc.b_cts_enable) ? 1 : 0)); | 781 | || tcb_desc.cts_enable) ? 1 : 0)); |
783 | SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc.b_cts_enable) ? 1 : 0)); | 782 | SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc.cts_enable) ? 1 : 0)); |
784 | SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc.b_rts_stbc) ? 1 : 0)); | 783 | SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc.rts_stbc) ? 1 : 0)); |
785 | 784 | ||
786 | SET_TX_DESC_RTS_RATE(pdesc, tcb_desc.rts_rate); | 785 | SET_TX_DESC_RTS_RATE(pdesc, tcb_desc.rts_rate); |
787 | SET_TX_DESC_RTS_BW(pdesc, 0); | 786 | SET_TX_DESC_RTS_BW(pdesc, 0); |
788 | SET_TX_DESC_RTS_SC(pdesc, tcb_desc.rts_sc); | 787 | SET_TX_DESC_RTS_SC(pdesc, tcb_desc.rts_sc); |
789 | SET_TX_DESC_RTS_SHORT(pdesc, | 788 | SET_TX_DESC_RTS_SHORT(pdesc, |
790 | ((tcb_desc.rts_rate <= DESC92C_RATE54M) ? | 789 | ((tcb_desc.rts_rate <= DESC92C_RATE54M) ? |
791 | (tcb_desc.b_rts_use_shortpreamble ? 1 : 0) | 790 | (tcb_desc.rts_use_shortpreamble ? 1 : 0) |
792 | : (tcb_desc.b_rts_use_shortgi ? 1 : 0))); | 791 | : (tcb_desc.rts_use_shortgi ? 1 : 0))); |
793 | 792 | ||
794 | if (mac->bw_40) { | 793 | if (mac->bw_40) { |
795 | if (tcb_desc.b_packet_bw) { | 794 | if (tcb_desc.packet_bw) { |
796 | SET_TX_DESC_DATA_BW(pdesc, 1); | 795 | SET_TX_DESC_DATA_BW(pdesc, 1); |
797 | SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3); | 796 | SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3); |
798 | } else { | 797 | } else { |
@@ -854,14 +853,14 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, | |||
854 | } | 853 | } |
855 | } | 854 | } |
856 | 855 | ||
857 | SET_TX_DESC_FIRST_SEG(pdesc, (b_firstseg ? 1 : 0)); | 856 | SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0)); |
858 | SET_TX_DESC_LAST_SEG(pdesc, (b_lastseg ? 1 : 0)); | 857 | SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0)); |
859 | 858 | ||
860 | SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len); | 859 | SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len); |
861 | 860 | ||
862 | SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping)); | 861 | SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping)); |
863 | 862 | ||
864 | if (rtlpriv->dm.b_useramask) { | 863 | if (rtlpriv->dm.useramask) { |
865 | SET_TX_DESC_RATE_ID(pdesc, tcb_desc.ratr_index); | 864 | SET_TX_DESC_RATE_ID(pdesc, tcb_desc.ratr_index); |
866 | SET_TX_DESC_MACID(pdesc, tcb_desc.mac_id); | 865 | SET_TX_DESC_MACID(pdesc, tcb_desc.mac_id); |
867 | } else { | 866 | } else { |
@@ -869,16 +868,16 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, | |||
869 | SET_TX_DESC_MACID(pdesc, tcb_desc.ratr_index); | 868 | SET_TX_DESC_MACID(pdesc, tcb_desc.ratr_index); |
870 | } | 869 | } |
871 | 870 | ||
872 | if ((!ieee80211_is_data_qos(fc)) && ppsc->b_leisure_ps && | 871 | if ((!ieee80211_is_data_qos(fc)) && ppsc->leisure_ps && |
873 | ppsc->b_fwctrl_lps) { | 872 | ppsc->fwctrl_lps) { |
874 | SET_TX_DESC_HWSEQ_EN(pdesc, 1); | 873 | SET_TX_DESC_HWSEQ_EN(pdesc, 1); |
875 | SET_TX_DESC_PKT_ID(pdesc, 8); | 874 | SET_TX_DESC_PKT_ID(pdesc, 8); |
876 | 875 | ||
877 | if (!b_defaultadapter) | 876 | if (!defaultadapter) |
878 | SET_TX_DESC_QOS(pdesc, 1); | 877 | SET_TX_DESC_QOS(pdesc, 1); |
879 | } | 878 | } |
880 | 879 | ||
881 | SET_TX_DESC_MORE_FRAG(pdesc, (b_lastseg ? 0 : 1)); | 880 | SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1)); |
882 | 881 | ||
883 | if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) || | 882 | if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) || |
884 | is_broadcast_ether_addr(ieee80211_get_DA(hdr))) { | 883 | is_broadcast_ether_addr(ieee80211_get_DA(hdr))) { |
@@ -889,8 +888,8 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, | |||
889 | } | 888 | } |
890 | 889 | ||
891 | void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, | 890 | void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, |
892 | u8 *pdesc, bool b_firstseg, | 891 | u8 *pdesc, bool firstseg, |
893 | bool b_lastseg, struct sk_buff *skb) | 892 | bool lastseg, struct sk_buff *skb) |
894 | { | 893 | { |
895 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 894 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
896 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 895 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
@@ -901,11 +900,11 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, | |||
901 | PCI_DMA_TODEVICE); | 900 | PCI_DMA_TODEVICE); |
902 | 901 | ||
903 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); | 902 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); |
904 | u16 fc = le16_to_cpu(hdr->frame_control); | 903 | __le16 fc = hdr->frame_control; |
905 | 904 | ||
906 | CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE); | 905 | CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE); |
907 | 906 | ||
908 | if (b_firstseg) | 907 | if (firstseg) |
909 | SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); | 908 | SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); |
910 | 909 | ||
911 | SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M); | 910 | SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M); |
@@ -1029,3 +1028,36 @@ void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue) | |||
1029 | BIT(0) << (hw_queue)); | 1028 | BIT(0) << (hw_queue)); |
1030 | } | 1029 | } |
1031 | } | 1030 | } |
1031 | |||
1032 | bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, | ||
1033 | struct sk_buff *skb) | ||
1034 | { | ||
1035 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1036 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
1037 | struct rtl8192_tx_ring *ring; | ||
1038 | struct rtl_tx_desc *pdesc; | ||
1039 | u8 own; | ||
1040 | unsigned long flags; | ||
1041 | struct sk_buff *pskb = NULL; | ||
1042 | |||
1043 | ring = &rtlpci->tx_ring[BEACON_QUEUE]; | ||
1044 | |||
1045 | spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); | ||
1046 | |||
1047 | pskb = __skb_dequeue(&ring->queue); | ||
1048 | if (pskb) | ||
1049 | kfree_skb(pskb); | ||
1050 | |||
1051 | pdesc = &ring->desc[0]; | ||
1052 | own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN); | ||
1053 | |||
1054 | rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb); | ||
1055 | |||
1056 | __skb_queue_tail(&ring->queue, skb); | ||
1057 | |||
1058 | spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); | ||
1059 | |||
1060 | rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE); | ||
1061 | |||
1062 | return true; | ||
1063 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h index 53d0e0a5af5c..803adcc80c96 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h | |||
@@ -40,470 +40,494 @@ | |||
40 | #define USB_HWDESC_HEADER_LEN 32 | 40 | #define USB_HWDESC_HEADER_LEN 32 |
41 | #define CRCLENGTH 4 | 41 | #define CRCLENGTH 4 |
42 | 42 | ||
43 | /* Define a macro that takes a le32 word, converts it to host ordering, | ||
44 | * right shifts by a specified count, creates a mask of the specified | ||
45 | * bit count, and extracts that number of bits. | ||
46 | */ | ||
47 | |||
48 | #define SHIFT_AND_MASK_LE(__pdesc, __shift, __mask) \ | ||
49 | ((le32_to_cpu(*(((__le32 *)(__pdesc)))) >> (__shift)) & \ | ||
50 | BIT_LEN_MASK_32(__mask)) | ||
51 | |||
52 | /* Define a macro that clears a bit field in an le32 word and | ||
53 | * sets the specified value into that bit field. The resulting | ||
54 | * value remains in le32 ordering; however, it is properly converted | ||
55 | * to host ordering for the clear and set operations before conversion | ||
56 | * back to le32. | ||
57 | */ | ||
58 | |||
59 | #define SET_BITS_OFFSET_LE(__pdesc, __shift, __len, __val) \ | ||
60 | (*(__le32 *)(__pdesc) = \ | ||
61 | (cpu_to_le32((le32_to_cpu(*((__le32 *)(__pdesc))) & \ | ||
62 | (~(BIT_OFFSET_LEN_MASK_32((__shift), __len)))) | \ | ||
63 | (((u32)(__val) & BIT_LEN_MASK_32(__len)) << (__shift))))); | ||
64 | |||
65 | /* macros to read/write various fields in RX or TX descriptors */ | ||
66 | |||
43 | #define SET_TX_DESC_PKT_SIZE(__pdesc, __val) \ | 67 | #define SET_TX_DESC_PKT_SIZE(__pdesc, __val) \ |
44 | SET_BITS_TO_LE_4BYTE(__pdesc, 0, 16, __val) | 68 | SET_BITS_OFFSET_LE(__pdesc, 0, 16, __val) |
45 | #define SET_TX_DESC_OFFSET(__pdesc, __val) \ | 69 | #define SET_TX_DESC_OFFSET(__pdesc, __val) \ |
46 | SET_BITS_TO_LE_4BYTE(__pdesc, 16, 8, __val) | 70 | SET_BITS_OFFSET_LE(__pdesc, 16, 8, __val) |
47 | #define SET_TX_DESC_BMC(__pdesc, __val) \ | 71 | #define SET_TX_DESC_BMC(__pdesc, __val) \ |
48 | SET_BITS_TO_LE_4BYTE(__pdesc, 24, 1, __val) | 72 | SET_BITS_OFFSET_LE(__pdesc, 24, 1, __val) |
49 | #define SET_TX_DESC_HTC(__pdesc, __val) \ | 73 | #define SET_TX_DESC_HTC(__pdesc, __val) \ |
50 | SET_BITS_TO_LE_4BYTE(__pdesc, 25, 1, __val) | 74 | SET_BITS_OFFSET_LE(__pdesc, 25, 1, __val) |
51 | #define SET_TX_DESC_LAST_SEG(__pdesc, __val) \ | 75 | #define SET_TX_DESC_LAST_SEG(__pdesc, __val) \ |
52 | SET_BITS_TO_LE_4BYTE(__pdesc, 26, 1, __val) | 76 | SET_BITS_OFFSET_LE(__pdesc, 26, 1, __val) |
53 | #define SET_TX_DESC_FIRST_SEG(__pdesc, __val) \ | 77 | #define SET_TX_DESC_FIRST_SEG(__pdesc, __val) \ |
54 | SET_BITS_TO_LE_4BYTE(__pdesc, 27, 1, __val) | 78 | SET_BITS_OFFSET_LE(__pdesc, 27, 1, __val) |
55 | #define SET_TX_DESC_LINIP(__pdesc, __val) \ | 79 | #define SET_TX_DESC_LINIP(__pdesc, __val) \ |
56 | SET_BITS_TO_LE_4BYTE(__pdesc, 28, 1, __val) | 80 | SET_BITS_OFFSET_LE(__pdesc, 28, 1, __val) |
57 | #define SET_TX_DESC_NO_ACM(__pdesc, __val) \ | 81 | #define SET_TX_DESC_NO_ACM(__pdesc, __val) \ |
58 | SET_BITS_TO_LE_4BYTE(__pdesc, 29, 1, __val) | 82 | SET_BITS_OFFSET_LE(__pdesc, 29, 1, __val) |
59 | #define SET_TX_DESC_GF(__pdesc, __val) \ | 83 | #define SET_TX_DESC_GF(__pdesc, __val) \ |
60 | SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val) | 84 | SET_BITS_OFFSET_LE(__pdesc, 30, 1, __val) |
61 | #define SET_TX_DESC_OWN(__pdesc, __val) \ | 85 | #define SET_TX_DESC_OWN(__pdesc, __val) \ |
62 | SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val) | 86 | SET_BITS_OFFSET_LE(__pdesc, 31, 1, __val) |
63 | 87 | ||
64 | #define GET_TX_DESC_PKT_SIZE(__pdesc) \ | 88 | #define GET_TX_DESC_PKT_SIZE(__pdesc) \ |
65 | LE_BITS_TO_4BYTE(__pdesc, 0, 16) | 89 | SHIFT_AND_MASK_LE(__pdesc, 0, 16) |
66 | #define GET_TX_DESC_OFFSET(__pdesc) \ | 90 | #define GET_TX_DESC_OFFSET(__pdesc) \ |
67 | LE_BITS_TO_4BYTE(__pdesc, 16, 8) | 91 | SHIFT_AND_MASK_LE(__pdesc, 16, 8) |
68 | #define GET_TX_DESC_BMC(__pdesc) \ | 92 | #define GET_TX_DESC_BMC(__pdesc) \ |
69 | LE_BITS_TO_4BYTE(__pdesc, 24, 1) | 93 | SHIFT_AND_MASK_LE(__pdesc, 24, 1) |
70 | #define GET_TX_DESC_HTC(__pdesc) \ | 94 | #define GET_TX_DESC_HTC(__pdesc) \ |
71 | LE_BITS_TO_4BYTE(__pdesc, 25, 1) | 95 | SHIFT_AND_MASK_LE(__pdesc, 25, 1) |
72 | #define GET_TX_DESC_LAST_SEG(__pdesc) \ | 96 | #define GET_TX_DESC_LAST_SEG(__pdesc) \ |
73 | LE_BITS_TO_4BYTE(__pdesc, 26, 1) | 97 | SHIFT_AND_MASK_LE(__pdesc, 26, 1) |
74 | #define GET_TX_DESC_FIRST_SEG(__pdesc) \ | 98 | #define GET_TX_DESC_FIRST_SEG(__pdesc) \ |
75 | LE_BITS_TO_4BYTE(__pdesc, 27, 1) | 99 | SHIFT_AND_MASK_LE(__pdesc, 27, 1) |
76 | #define GET_TX_DESC_LINIP(__pdesc) \ | 100 | #define GET_TX_DESC_LINIP(__pdesc) \ |
77 | LE_BITS_TO_4BYTE(__pdesc, 28, 1) | 101 | SHIFT_AND_MASK_LE(__pdesc, 28, 1) |
78 | #define GET_TX_DESC_NO_ACM(__pdesc) \ | 102 | #define GET_TX_DESC_NO_ACM(__pdesc) \ |
79 | LE_BITS_TO_4BYTE(__pdesc, 29, 1) | 103 | SHIFT_AND_MASK_LE(__pdesc, 29, 1) |
80 | #define GET_TX_DESC_GF(__pdesc) \ | 104 | #define GET_TX_DESC_GF(__pdesc) \ |
81 | LE_BITS_TO_4BYTE(__pdesc, 30, 1) | 105 | SHIFT_AND_MASK_LE(__pdesc, 30, 1) |
82 | #define GET_TX_DESC_OWN(__pdesc) \ | 106 | #define GET_TX_DESC_OWN(__pdesc) \ |
83 | LE_BITS_TO_4BYTE(__pdesc, 31, 1) | 107 | SHIFT_AND_MASK_LE(__pdesc, 31, 1) |
84 | 108 | ||
85 | #define SET_TX_DESC_MACID(__pdesc, __val) \ | 109 | #define SET_TX_DESC_MACID(__pdesc, __val) \ |
86 | SET_BITS_TO_LE_4BYTE(__pdesc+4, 0, 5, __val) | 110 | SET_BITS_OFFSET_LE(__pdesc+4, 0, 5, __val) |
87 | #define SET_TX_DESC_AGG_BREAK(__pdesc, __val) \ | 111 | #define SET_TX_DESC_AGG_BREAK(__pdesc, __val) \ |
88 | SET_BITS_TO_LE_4BYTE(__pdesc+4, 5, 1, __val) | 112 | SET_BITS_OFFSET_LE(__pdesc+4, 5, 1, __val) |
89 | #define SET_TX_DESC_BK(__pdesc, __val) \ | 113 | #define SET_TX_DESC_BK(__pdesc, __val) \ |
90 | SET_BITS_TO_LE_4BYTE(__pdesc+4, 6, 1, __val) | 114 | SET_BITS_OFFSET_LE(__pdesc+4, 6, 1, __val) |
91 | #define SET_TX_DESC_RDG_ENABLE(__pdesc, __val) \ | 115 | #define SET_TX_DESC_RDG_ENABLE(__pdesc, __val) \ |
92 | SET_BITS_TO_LE_4BYTE(__pdesc+4, 7, 1, __val) | 116 | SET_BITS_OFFSET_LE(__pdesc+4, 7, 1, __val) |
93 | #define SET_TX_DESC_QUEUE_SEL(__pdesc, __val) \ | 117 | #define SET_TX_DESC_QUEUE_SEL(__pdesc, __val) \ |
94 | SET_BITS_TO_LE_4BYTE(__pdesc+4, 8, 5, __val) | 118 | SET_BITS_OFFSET_LE(__pdesc+4, 8, 5, __val) |
95 | #define SET_TX_DESC_RDG_NAV_EXT(__pdesc, __val) \ | 119 | #define SET_TX_DESC_RDG_NAV_EXT(__pdesc, __val) \ |
96 | SET_BITS_TO_LE_4BYTE(__pdesc+4, 13, 1, __val) | 120 | SET_BITS_OFFSET_LE(__pdesc+4, 13, 1, __val) |
97 | #define SET_TX_DESC_LSIG_TXOP_EN(__pdesc, __val) \ | 121 | #define SET_TX_DESC_LSIG_TXOP_EN(__pdesc, __val) \ |
98 | SET_BITS_TO_LE_4BYTE(__pdesc+4, 14, 1, __val) | 122 | SET_BITS_OFFSET_LE(__pdesc+4, 14, 1, __val) |
99 | #define SET_TX_DESC_PIFS(__pdesc, __val) \ | 123 | #define SET_TX_DESC_PIFS(__pdesc, __val) \ |
100 | SET_BITS_TO_LE_4BYTE(__pdesc+4, 15, 1, __val) | 124 | SET_BITS_OFFSET_LE(__pdesc+4, 15, 1, __val) |
101 | #define SET_TX_DESC_RATE_ID(__pdesc, __val) \ | 125 | #define SET_TX_DESC_RATE_ID(__pdesc, __val) \ |
102 | SET_BITS_TO_LE_4BYTE(__pdesc+4, 16, 4, __val) | 126 | SET_BITS_OFFSET_LE(__pdesc+4, 16, 4, __val) |
103 | #define SET_TX_DESC_NAV_USE_HDR(__pdesc, __val) \ | 127 | #define SET_TX_DESC_NAV_USE_HDR(__pdesc, __val) \ |
104 | SET_BITS_TO_LE_4BYTE(__pdesc+4, 20, 1, __val) | 128 | SET_BITS_OFFSET_LE(__pdesc+4, 20, 1, __val) |
105 | #define SET_TX_DESC_EN_DESC_ID(__pdesc, __val) \ | 129 | #define SET_TX_DESC_EN_DESC_ID(__pdesc, __val) \ |
106 | SET_BITS_TO_LE_4BYTE(__pdesc+4, 21, 1, __val) | 130 | SET_BITS_OFFSET_LE(__pdesc+4, 21, 1, __val) |
107 | #define SET_TX_DESC_SEC_TYPE(__pdesc, __val) \ | 131 | #define SET_TX_DESC_SEC_TYPE(__pdesc, __val) \ |
108 | SET_BITS_TO_LE_4BYTE(__pdesc+4, 22, 2, __val) | 132 | SET_BITS_OFFSET_LE(__pdesc+4, 22, 2, __val) |
109 | #define SET_TX_DESC_PKT_OFFSET(__pdesc, __val) \ | 133 | #define SET_TX_DESC_PKT_OFFSET(__pdesc, __val) \ |
110 | SET_BITS_TO_LE_4BYTE(__pdesc+4, 24, 8, __val) | 134 | SET_BITS_OFFSET_LE(__pdesc+4, 24, 8, __val) |
111 | 135 | ||
112 | #define GET_TX_DESC_MACID(__pdesc) \ | 136 | #define GET_TX_DESC_MACID(__pdesc) \ |
113 | LE_BITS_TO_4BYTE(__pdesc+4, 0, 5) | 137 | SHIFT_AND_MASK_LE(__pdesc+4, 0, 5) |
114 | #define GET_TX_DESC_AGG_ENABLE(__pdesc) \ | 138 | #define GET_TX_DESC_AGG_ENABLE(__pdesc) \ |
115 | LE_BITS_TO_4BYTE(__pdesc+4, 5, 1) | 139 | SHIFT_AND_MASK_LE(__pdesc+4, 5, 1) |
116 | #define GET_TX_DESC_AGG_BREAK(__pdesc) \ | 140 | #define GET_TX_DESC_AGG_BREAK(__pdesc) \ |
117 | LE_BITS_TO_4BYTE(__pdesc+4, 6, 1) | 141 | SHIFT_AND_MASK_LE(__pdesc+4, 6, 1) |
118 | #define GET_TX_DESC_RDG_ENABLE(__pdesc) \ | 142 | #define GET_TX_DESC_RDG_ENABLE(__pdesc) \ |
119 | LE_BITS_TO_4BYTE(__pdesc+4, 7, 1) | 143 | SHIFT_AND_MASK_LE(__pdesc+4, 7, 1) |
120 | #define GET_TX_DESC_QUEUE_SEL(__pdesc) \ | 144 | #define GET_TX_DESC_QUEUE_SEL(__pdesc) \ |
121 | LE_BITS_TO_4BYTE(__pdesc+4, 8, 5) | 145 | SHIFT_AND_MASK_LE(__pdesc+4, 8, 5) |
122 | #define GET_TX_DESC_RDG_NAV_EXT(__pdesc) \ | 146 | #define GET_TX_DESC_RDG_NAV_EXT(__pdesc) \ |
123 | LE_BITS_TO_4BYTE(__pdesc+4, 13, 1) | 147 | SHIFT_AND_MASK_LE(__pdesc+4, 13, 1) |
124 | #define GET_TX_DESC_LSIG_TXOP_EN(__pdesc) \ | 148 | #define GET_TX_DESC_LSIG_TXOP_EN(__pdesc) \ |
125 | LE_BITS_TO_4BYTE(__pdesc+4, 14, 1) | 149 | SHIFT_AND_MASK_LE(__pdesc+4, 14, 1) |
126 | #define GET_TX_DESC_PIFS(__pdesc) \ | 150 | #define GET_TX_DESC_PIFS(__pdesc) \ |
127 | LE_BITS_TO_4BYTE(__pdesc+4, 15, 1) | 151 | SHIFT_AND_MASK_LE(__pdesc+4, 15, 1) |
128 | #define GET_TX_DESC_RATE_ID(__pdesc) \ | 152 | #define GET_TX_DESC_RATE_ID(__pdesc) \ |
129 | LE_BITS_TO_4BYTE(__pdesc+4, 16, 4) | 153 | SHIFT_AND_MASK_LE(__pdesc+4, 16, 4) |
130 | #define GET_TX_DESC_NAV_USE_HDR(__pdesc) \ | 154 | #define GET_TX_DESC_NAV_USE_HDR(__pdesc) \ |
131 | LE_BITS_TO_4BYTE(__pdesc+4, 20, 1) | 155 | SHIFT_AND_MASK_LE(__pdesc+4, 20, 1) |
132 | #define GET_TX_DESC_EN_DESC_ID(__pdesc) \ | 156 | #define GET_TX_DESC_EN_DESC_ID(__pdesc) \ |
133 | LE_BITS_TO_4BYTE(__pdesc+4, 21, 1) | 157 | SHIFT_AND_MASK_LE(__pdesc+4, 21, 1) |
134 | #define GET_TX_DESC_SEC_TYPE(__pdesc) \ | 158 | #define GET_TX_DESC_SEC_TYPE(__pdesc) \ |
135 | LE_BITS_TO_4BYTE(__pdesc+4, 22, 2) | 159 | SHIFT_AND_MASK_LE(__pdesc+4, 22, 2) |
136 | #define GET_TX_DESC_PKT_OFFSET(__pdesc) \ | 160 | #define GET_TX_DESC_PKT_OFFSET(__pdesc) \ |
137 | LE_BITS_TO_4BYTE(__pdesc+4, 24, 8) | 161 | SHIFT_AND_MASK_LE(__pdesc+4, 24, 8) |
138 | 162 | ||
139 | #define SET_TX_DESC_RTS_RC(__pdesc, __val) \ | 163 | #define SET_TX_DESC_RTS_RC(__pdesc, __val) \ |
140 | SET_BITS_TO_LE_4BYTE(__pdesc+8, 0, 6, __val) | 164 | SET_BITS_OFFSET_LE(__pdesc+8, 0, 6, __val) |
141 | #define SET_TX_DESC_DATA_RC(__pdesc, __val) \ | 165 | #define SET_TX_DESC_DATA_RC(__pdesc, __val) \ |
142 | SET_BITS_TO_LE_4BYTE(__pdesc+8, 6, 6, __val) | 166 | SET_BITS_OFFSET_LE(__pdesc+8, 6, 6, __val) |
143 | #define SET_TX_DESC_BAR_RTY_TH(__pdesc, __val) \ | 167 | #define SET_TX_DESC_BAR_RTY_TH(__pdesc, __val) \ |
144 | SET_BITS_TO_LE_4BYTE(__pdesc+8, 14, 2, __val) | 168 | SET_BITS_OFFSET_LE(__pdesc+8, 14, 2, __val) |
145 | #define SET_TX_DESC_MORE_FRAG(__pdesc, __val) \ | 169 | #define SET_TX_DESC_MORE_FRAG(__pdesc, __val) \ |
146 | SET_BITS_TO_LE_4BYTE(__pdesc+8, 17, 1, __val) | 170 | SET_BITS_OFFSET_LE(__pdesc+8, 17, 1, __val) |
147 | #define SET_TX_DESC_RAW(__pdesc, __val) \ | 171 | #define SET_TX_DESC_RAW(__pdesc, __val) \ |
148 | SET_BITS_TO_LE_4BYTE(__pdesc+8, 18, 1, __val) | 172 | SET_BITS_OFFSET_LE(__pdesc+8, 18, 1, __val) |
149 | #define SET_TX_DESC_CCX(__pdesc, __val) \ | 173 | #define SET_TX_DESC_CCX(__pdesc, __val) \ |
150 | SET_BITS_TO_LE_4BYTE(__pdesc+8, 19, 1, __val) | 174 | SET_BITS_OFFSET_LE(__pdesc+8, 19, 1, __val) |
151 | #define SET_TX_DESC_AMPDU_DENSITY(__pdesc, __val) \ | 175 | #define SET_TX_DESC_AMPDU_DENSITY(__pdesc, __val) \ |
152 | SET_BITS_TO_LE_4BYTE(__pdesc+8, 20, 3, __val) | 176 | SET_BITS_OFFSET_LE(__pdesc+8, 20, 3, __val) |
153 | #define SET_TX_DESC_ANTSEL_A(__pdesc, __val) \ | 177 | #define SET_TX_DESC_ANTSEL_A(__pdesc, __val) \ |
154 | SET_BITS_TO_LE_4BYTE(__pdesc+8, 24, 1, __val) | 178 | SET_BITS_OFFSET_LE(__pdesc+8, 24, 1, __val) |
155 | #define SET_TX_DESC_ANTSEL_B(__pdesc, __val) \ | 179 | #define SET_TX_DESC_ANTSEL_B(__pdesc, __val) \ |
156 | SET_BITS_TO_LE_4BYTE(__pdesc+8, 25, 1, __val) | 180 | SET_BITS_OFFSET_LE(__pdesc+8, 25, 1, __val) |
157 | #define SET_TX_DESC_TX_ANT_CCK(__pdesc, __val) \ | 181 | #define SET_TX_DESC_TX_ANT_CCK(__pdesc, __val) \ |
158 | SET_BITS_TO_LE_4BYTE(__pdesc+8, 26, 2, __val) | 182 | SET_BITS_OFFSET_LE(__pdesc+8, 26, 2, __val) |
159 | #define SET_TX_DESC_TX_ANTL(__pdesc, __val) \ | 183 | #define SET_TX_DESC_TX_ANTL(__pdesc, __val) \ |
160 | SET_BITS_TO_LE_4BYTE(__pdesc+8, 28, 2, __val) | 184 | SET_BITS_OFFSET_LE(__pdesc+8, 28, 2, __val) |
161 | #define SET_TX_DESC_TX_ANT_HT(__pdesc, __val) \ | 185 | #define SET_TX_DESC_TX_ANT_HT(__pdesc, __val) \ |
162 | SET_BITS_TO_LE_4BYTE(__pdesc+8, 30, 2, __val) | 186 | SET_BITS_OFFSET_LE(__pdesc+8, 30, 2, __val) |
163 | 187 | ||
164 | #define GET_TX_DESC_RTS_RC(__pdesc) \ | 188 | #define GET_TX_DESC_RTS_RC(__pdesc) \ |
165 | LE_BITS_TO_4BYTE(__pdesc+8, 0, 6) | 189 | SHIFT_AND_MASK_LE(__pdesc+8, 0, 6) |
166 | #define GET_TX_DESC_DATA_RC(__pdesc) \ | 190 | #define GET_TX_DESC_DATA_RC(__pdesc) \ |
167 | LE_BITS_TO_4BYTE(__pdesc+8, 6, 6) | 191 | SHIFT_AND_MASK_LE(__pdesc+8, 6, 6) |
168 | #define GET_TX_DESC_BAR_RTY_TH(__pdesc) \ | 192 | #define GET_TX_DESC_BAR_RTY_TH(__pdesc) \ |
169 | LE_BITS_TO_4BYTE(__pdesc+8, 14, 2) | 193 | SHIFT_AND_MASK_LE(__pdesc+8, 14, 2) |
170 | #define GET_TX_DESC_MORE_FRAG(__pdesc) \ | 194 | #define GET_TX_DESC_MORE_FRAG(__pdesc) \ |
171 | LE_BITS_TO_4BYTE(__pdesc+8, 17, 1) | 195 | SHIFT_AND_MASK_LE(__pdesc+8, 17, 1) |
172 | #define GET_TX_DESC_RAW(__pdesc) \ | 196 | #define GET_TX_DESC_RAW(__pdesc) \ |
173 | LE_BITS_TO_4BYTE(__pdesc+8, 18, 1) | 197 | SHIFT_AND_MASK_LE(__pdesc+8, 18, 1) |
174 | #define GET_TX_DESC_CCX(__pdesc) \ | 198 | #define GET_TX_DESC_CCX(__pdesc) \ |
175 | LE_BITS_TO_4BYTE(__pdesc+8, 19, 1) | 199 | SHIFT_AND_MASK_LE(__pdesc+8, 19, 1) |
176 | #define GET_TX_DESC_AMPDU_DENSITY(__pdesc) \ | 200 | #define GET_TX_DESC_AMPDU_DENSITY(__pdesc) \ |
177 | LE_BITS_TO_4BYTE(__pdesc+8, 20, 3) | 201 | SHIFT_AND_MASK_LE(__pdesc+8, 20, 3) |
178 | #define GET_TX_DESC_ANTSEL_A(__pdesc) \ | 202 | #define GET_TX_DESC_ANTSEL_A(__pdesc) \ |
179 | LE_BITS_TO_4BYTE(__pdesc+8, 24, 1) | 203 | SHIFT_AND_MASK_LE(__pdesc+8, 24, 1) |
180 | #define GET_TX_DESC_ANTSEL_B(__pdesc) \ | 204 | #define GET_TX_DESC_ANTSEL_B(__pdesc) \ |
181 | LE_BITS_TO_4BYTE(__pdesc+8, 25, 1) | 205 | SHIFT_AND_MASK_LE(__pdesc+8, 25, 1) |
182 | #define GET_TX_DESC_TX_ANT_CCK(__pdesc) \ | 206 | #define GET_TX_DESC_TX_ANT_CCK(__pdesc) \ |
183 | LE_BITS_TO_4BYTE(__pdesc+8, 26, 2) | 207 | SHIFT_AND_MASK_LE(__pdesc+8, 26, 2) |
184 | #define GET_TX_DESC_TX_ANTL(__pdesc) \ | 208 | #define GET_TX_DESC_TX_ANTL(__pdesc) \ |
185 | LE_BITS_TO_4BYTE(__pdesc+8, 28, 2) | 209 | SHIFT_AND_MASK_LE(__pdesc+8, 28, 2) |
186 | #define GET_TX_DESC_TX_ANT_HT(__pdesc) \ | 210 | #define GET_TX_DESC_TX_ANT_HT(__pdesc) \ |
187 | LE_BITS_TO_4BYTE(__pdesc+8, 30, 2) | 211 | SHIFT_AND_MASK_LE(__pdesc+8, 30, 2) |
188 | 212 | ||
189 | #define SET_TX_DESC_NEXT_HEAP_PAGE(__pdesc, __val) \ | 213 | #define SET_TX_DESC_NEXT_HEAP_PAGE(__pdesc, __val) \ |
190 | SET_BITS_TO_LE_4BYTE(__pdesc+12, 0, 8, __val) | 214 | SET_BITS_OFFSET_LE(__pdesc+12, 0, 8, __val) |
191 | #define SET_TX_DESC_TAIL_PAGE(__pdesc, __val) \ | 215 | #define SET_TX_DESC_TAIL_PAGE(__pdesc, __val) \ |
192 | SET_BITS_TO_LE_4BYTE(__pdesc+12, 8, 8, __val) | 216 | SET_BITS_OFFSET_LE(__pdesc+12, 8, 8, __val) |
193 | #define SET_TX_DESC_SEQ(__pdesc, __val) \ | 217 | #define SET_TX_DESC_SEQ(__pdesc, __val) \ |
194 | SET_BITS_TO_LE_4BYTE(__pdesc+12, 16, 12, __val) | 218 | SET_BITS_OFFSET_LE(__pdesc+12, 16, 12, __val) |
195 | #define SET_TX_DESC_PKT_ID(__pdesc, __val) \ | 219 | #define SET_TX_DESC_PKT_ID(__pdesc, __val) \ |
196 | SET_BITS_TO_LE_4BYTE(__pdesc+12, 28, 4, __val) | 220 | SET_BITS_OFFSET_LE(__pdesc+12, 28, 4, __val) |
197 | 221 | ||
198 | #define GET_TX_DESC_NEXT_HEAP_PAGE(__pdesc) \ | 222 | #define GET_TX_DESC_NEXT_HEAP_PAGE(__pdesc) \ |
199 | LE_BITS_TO_4BYTE(__pdesc+12, 0, 8) | 223 | SHIFT_AND_MASK_LE(__pdesc+12, 0, 8) |
200 | #define GET_TX_DESC_TAIL_PAGE(__pdesc) \ | 224 | #define GET_TX_DESC_TAIL_PAGE(__pdesc) \ |
201 | LE_BITS_TO_4BYTE(__pdesc+12, 8, 8) | 225 | SHIFT_AND_MASK_LE(__pdesc+12, 8, 8) |
202 | #define GET_TX_DESC_SEQ(__pdesc) \ | 226 | #define GET_TX_DESC_SEQ(__pdesc) \ |
203 | LE_BITS_TO_4BYTE(__pdesc+12, 16, 12) | 227 | SHIFT_AND_MASK_LE(__pdesc+12, 16, 12) |
204 | #define GET_TX_DESC_PKT_ID(__pdesc) \ | 228 | #define GET_TX_DESC_PKT_ID(__pdesc) \ |
205 | LE_BITS_TO_4BYTE(__pdesc+12, 28, 4) | 229 | SHIFT_AND_MASK_LE(__pdesc+12, 28, 4) |
206 | 230 | ||
207 | #define SET_TX_DESC_RTS_RATE(__pdesc, __val) \ | 231 | #define SET_TX_DESC_RTS_RATE(__pdesc, __val) \ |
208 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 0, 5, __val) | 232 | SET_BITS_OFFSET_LE(__pdesc+16, 0, 5, __val) |
209 | #define SET_TX_DESC_AP_DCFE(__pdesc, __val) \ | 233 | #define SET_TX_DESC_AP_DCFE(__pdesc, __val) \ |
210 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 5, 1, __val) | 234 | SET_BITS_OFFSET_LE(__pdesc+16, 5, 1, __val) |
211 | #define SET_TX_DESC_QOS(__pdesc, __val) \ | 235 | #define SET_TX_DESC_QOS(__pdesc, __val) \ |
212 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 6, 1, __val) | 236 | SET_BITS_OFFSET_LE(__pdesc+16, 6, 1, __val) |
213 | #define SET_TX_DESC_HWSEQ_EN(__pdesc, __val) \ | 237 | #define SET_TX_DESC_HWSEQ_EN(__pdesc, __val) \ |
214 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 7, 1, __val) | 238 | SET_BITS_OFFSET_LE(__pdesc+16, 7, 1, __val) |
215 | #define SET_TX_DESC_USE_RATE(__pdesc, __val) \ | 239 | #define SET_TX_DESC_USE_RATE(__pdesc, __val) \ |
216 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 8, 1, __val) | 240 | SET_BITS_OFFSET_LE(__pdesc+16, 8, 1, __val) |
217 | #define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val) \ | 241 | #define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val) \ |
218 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 9, 1, __val) | 242 | SET_BITS_OFFSET_LE(__pdesc+16, 9, 1, __val) |
219 | #define SET_TX_DESC_DISABLE_FB(__pdesc, __val) \ | 243 | #define SET_TX_DESC_DISABLE_FB(__pdesc, __val) \ |
220 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 10, 1, __val) | 244 | SET_BITS_OFFSET_LE(__pdesc+16, 10, 1, __val) |
221 | #define SET_TX_DESC_CTS2SELF(__pdesc, __val) \ | 245 | #define SET_TX_DESC_CTS2SELF(__pdesc, __val) \ |
222 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 11, 1, __val) | 246 | SET_BITS_OFFSET_LE(__pdesc+16, 11, 1, __val) |
223 | #define SET_TX_DESC_RTS_ENABLE(__pdesc, __val) \ | 247 | #define SET_TX_DESC_RTS_ENABLE(__pdesc, __val) \ |
224 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 12, 1, __val) | 248 | SET_BITS_OFFSET_LE(__pdesc+16, 12, 1, __val) |
225 | #define SET_TX_DESC_HW_RTS_ENABLE(__pdesc, __val) \ | 249 | #define SET_TX_DESC_HW_RTS_ENABLE(__pdesc, __val) \ |
226 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 13, 1, __val) | 250 | SET_BITS_OFFSET_LE(__pdesc+16, 13, 1, __val) |
227 | #define SET_TX_DESC_PORT_ID(__pdesc, __val) \ | 251 | #define SET_TX_DESC_PORT_ID(__pdesc, __val) \ |
228 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 14, 1, __val) | 252 | SET_BITS_OFFSET_LE(__pdesc+16, 14, 1, __val) |
229 | #define SET_TX_DESC_WAIT_DCTS(__pdesc, __val) \ | 253 | #define SET_TX_DESC_WAIT_DCTS(__pdesc, __val) \ |
230 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 18, 1, __val) | 254 | SET_BITS_OFFSET_LE(__pdesc+16, 18, 1, __val) |
231 | #define SET_TX_DESC_CTS2AP_EN(__pdesc, __val) \ | 255 | #define SET_TX_DESC_CTS2AP_EN(__pdesc, __val) \ |
232 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 19, 1, __val) | 256 | SET_BITS_OFFSET_LE(__pdesc+16, 19, 1, __val) |
233 | #define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val) \ | 257 | #define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val) \ |
234 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 20, 2, __val) | 258 | SET_BITS_OFFSET_LE(__pdesc+16, 20, 2, __val) |
235 | #define SET_TX_DESC_TX_STBC(__pdesc, __val) \ | 259 | #define SET_TX_DESC_TX_STBC(__pdesc, __val) \ |
236 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 22, 2, __val) | 260 | SET_BITS_OFFSET_LE(__pdesc+16, 22, 2, __val) |
237 | #define SET_TX_DESC_DATA_SHORT(__pdesc, __val) \ | 261 | #define SET_TX_DESC_DATA_SHORT(__pdesc, __val) \ |
238 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 24, 1, __val) | 262 | SET_BITS_OFFSET_LE(__pdesc+16, 24, 1, __val) |
239 | #define SET_TX_DESC_DATA_BW(__pdesc, __val) \ | 263 | #define SET_TX_DESC_DATA_BW(__pdesc, __val) \ |
240 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 25, 1, __val) | 264 | SET_BITS_OFFSET_LE(__pdesc+16, 25, 1, __val) |
241 | #define SET_TX_DESC_RTS_SHORT(__pdesc, __val) \ | 265 | #define SET_TX_DESC_RTS_SHORT(__pdesc, __val) \ |
242 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 26, 1, __val) | 266 | SET_BITS_OFFSET_LE(__pdesc+16, 26, 1, __val) |
243 | #define SET_TX_DESC_RTS_BW(__pdesc, __val) \ | 267 | #define SET_TX_DESC_RTS_BW(__pdesc, __val) \ |
244 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 27, 1, __val) | 268 | SET_BITS_OFFSET_LE(__pdesc+16, 27, 1, __val) |
245 | #define SET_TX_DESC_RTS_SC(__pdesc, __val) \ | 269 | #define SET_TX_DESC_RTS_SC(__pdesc, __val) \ |
246 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 28, 2, __val) | 270 | SET_BITS_OFFSET_LE(__pdesc+16, 28, 2, __val) |
247 | #define SET_TX_DESC_RTS_STBC(__pdesc, __val) \ | 271 | #define SET_TX_DESC_RTS_STBC(__pdesc, __val) \ |
248 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 30, 2, __val) | 272 | SET_BITS_OFFSET_LE(__pdesc+16, 30, 2, __val) |
249 | 273 | ||
250 | #define GET_TX_DESC_RTS_RATE(__pdesc) \ | 274 | #define GET_TX_DESC_RTS_RATE(__pdesc) \ |
251 | LE_BITS_TO_4BYTE(__pdesc+16, 0, 5) | 275 | SHIFT_AND_MASK_LE(__pdesc+16, 0, 5) |
252 | #define GET_TX_DESC_AP_DCFE(__pdesc) \ | 276 | #define GET_TX_DESC_AP_DCFE(__pdesc) \ |
253 | LE_BITS_TO_4BYTE(__pdesc+16, 5, 1) | 277 | SHIFT_AND_MASK_LE(__pdesc+16, 5, 1) |
254 | #define GET_TX_DESC_QOS(__pdesc) \ | 278 | #define GET_TX_DESC_QOS(__pdesc) \ |
255 | LE_BITS_TO_4BYTE(__pdesc+16, 6, 1) | 279 | SHIFT_AND_MASK_LE(__pdesc+16, 6, 1) |
256 | #define GET_TX_DESC_HWSEQ_EN(__pdesc) \ | 280 | #define GET_TX_DESC_HWSEQ_EN(__pdesc) \ |
257 | LE_BITS_TO_4BYTE(__pdesc+16, 7, 1) | 281 | SHIFT_AND_MASK_LE(__pdesc+16, 7, 1) |
258 | #define GET_TX_DESC_USE_RATE(__pdesc) \ | 282 | #define GET_TX_DESC_USE_RATE(__pdesc) \ |
259 | LE_BITS_TO_4BYTE(__pdesc+16, 8, 1) | 283 | SHIFT_AND_MASK_LE(__pdesc+16, 8, 1) |
260 | #define GET_TX_DESC_DISABLE_RTS_FB(__pdesc) \ | 284 | #define GET_TX_DESC_DISABLE_RTS_FB(__pdesc) \ |
261 | LE_BITS_TO_4BYTE(__pdesc+16, 9, 1) | 285 | SHIFT_AND_MASK_LE(__pdesc+16, 9, 1) |
262 | #define GET_TX_DESC_DISABLE_FB(__pdesc) \ | 286 | #define GET_TX_DESC_DISABLE_FB(__pdesc) \ |
263 | LE_BITS_TO_4BYTE(__pdesc+16, 10, 1) | 287 | SHIFT_AND_MASK_LE(__pdesc+16, 10, 1) |
264 | #define GET_TX_DESC_CTS2SELF(__pdesc) \ | 288 | #define GET_TX_DESC_CTS2SELF(__pdesc) \ |
265 | LE_BITS_TO_4BYTE(__pdesc+16, 11, 1) | 289 | SHIFT_AND_MASK_LE(__pdesc+16, 11, 1) |
266 | #define GET_TX_DESC_RTS_ENABLE(__pdesc) \ | 290 | #define GET_TX_DESC_RTS_ENABLE(__pdesc) \ |
267 | LE_BITS_TO_4BYTE(__pdesc+16, 12, 1) | 291 | SHIFT_AND_MASK_LE(__pdesc+16, 12, 1) |
268 | #define GET_TX_DESC_HW_RTS_ENABLE(__pdesc) \ | 292 | #define GET_TX_DESC_HW_RTS_ENABLE(__pdesc) \ |
269 | LE_BITS_TO_4BYTE(__pdesc+16, 13, 1) | 293 | SHIFT_AND_MASK_LE(__pdesc+16, 13, 1) |
270 | #define GET_TX_DESC_PORT_ID(__pdesc) \ | 294 | #define GET_TX_DESC_PORT_ID(__pdesc) \ |
271 | LE_BITS_TO_4BYTE(__pdesc+16, 14, 1) | 295 | SHIFT_AND_MASK_LE(__pdesc+16, 14, 1) |
272 | #define GET_TX_DESC_WAIT_DCTS(__pdesc) \ | 296 | #define GET_TX_DESC_WAIT_DCTS(__pdesc) \ |
273 | LE_BITS_TO_4BYTE(__pdesc+16, 18, 1) | 297 | SHIFT_AND_MASK_LE(__pdesc+16, 18, 1) |
274 | #define GET_TX_DESC_CTS2AP_EN(__pdesc) \ | 298 | #define GET_TX_DESC_CTS2AP_EN(__pdesc) \ |
275 | LE_BITS_TO_4BYTE(__pdesc+16, 19, 1) | 299 | SHIFT_AND_MASK_LE(__pdesc+16, 19, 1) |
276 | #define GET_TX_DESC_TX_SUB_CARRIER(__pdesc) \ | 300 | #define GET_TX_DESC_TX_SUB_CARRIER(__pdesc) \ |
277 | LE_BITS_TO_4BYTE(__pdesc+16, 20, 2) | 301 | SHIFT_AND_MASK_LE(__pdesc+16, 20, 2) |
278 | #define GET_TX_DESC_TX_STBC(__pdesc) \ | 302 | #define GET_TX_DESC_TX_STBC(__pdesc) \ |
279 | LE_BITS_TO_4BYTE(__pdesc+16, 22, 2) | 303 | SHIFT_AND_MASK_LE(__pdesc+16, 22, 2) |
280 | #define GET_TX_DESC_DATA_SHORT(__pdesc) \ | 304 | #define GET_TX_DESC_DATA_SHORT(__pdesc) \ |
281 | LE_BITS_TO_4BYTE(__pdesc+16, 24, 1) | 305 | SHIFT_AND_MASK_LE(__pdesc+16, 24, 1) |
282 | #define GET_TX_DESC_DATA_BW(__pdesc) \ | 306 | #define GET_TX_DESC_DATA_BW(__pdesc) \ |
283 | LE_BITS_TO_4BYTE(__pdesc+16, 25, 1) | 307 | SHIFT_AND_MASK_LE(__pdesc+16, 25, 1) |
284 | #define GET_TX_DESC_RTS_SHORT(__pdesc) \ | 308 | #define GET_TX_DESC_RTS_SHORT(__pdesc) \ |
285 | LE_BITS_TO_4BYTE(__pdesc+16, 26, 1) | 309 | SHIFT_AND_MASK_LE(__pdesc+16, 26, 1) |
286 | #define GET_TX_DESC_RTS_BW(__pdesc) \ | 310 | #define GET_TX_DESC_RTS_BW(__pdesc) \ |
287 | LE_BITS_TO_4BYTE(__pdesc+16, 27, 1) | 311 | SHIFT_AND_MASK_LE(__pdesc+16, 27, 1) |
288 | #define GET_TX_DESC_RTS_SC(__pdesc) \ | 312 | #define GET_TX_DESC_RTS_SC(__pdesc) \ |
289 | LE_BITS_TO_4BYTE(__pdesc+16, 28, 2) | 313 | SHIFT_AND_MASK_LE(__pdesc+16, 28, 2) |
290 | #define GET_TX_DESC_RTS_STBC(__pdesc) \ | 314 | #define GET_TX_DESC_RTS_STBC(__pdesc) \ |
291 | LE_BITS_TO_4BYTE(__pdesc+16, 30, 2) | 315 | SHIFT_AND_MASK_LE(__pdesc+16, 30, 2) |
292 | 316 | ||
293 | #define SET_TX_DESC_TX_RATE(__pdesc, __val) \ | 317 | #define SET_TX_DESC_TX_RATE(__pdesc, __val) \ |
294 | SET_BITS_TO_LE_4BYTE(__pdesc+20, 0, 6, __val) | 318 | SET_BITS_OFFSET_LE(__pdesc+20, 0, 6, __val) |
295 | #define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val) \ | 319 | #define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val) \ |
296 | SET_BITS_TO_LE_4BYTE(__pdesc+20, 6, 1, __val) | 320 | SET_BITS_OFFSET_LE(__pdesc+20, 6, 1, __val) |
297 | #define SET_TX_DESC_CCX_TAG(__pdesc, __val) \ | 321 | #define SET_TX_DESC_CCX_TAG(__pdesc, __val) \ |
298 | SET_BITS_TO_LE_4BYTE(__pdesc+20, 7, 1, __val) | 322 | SET_BITS_OFFSET_LE(__pdesc+20, 7, 1, __val) |
299 | #define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val) \ | 323 | #define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val) \ |
300 | SET_BITS_TO_LE_4BYTE(__pdesc+20, 8, 5, __val) | 324 | SET_BITS_OFFSET_LE(__pdesc+20, 8, 5, __val) |
301 | #define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val) \ | 325 | #define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val) \ |
302 | SET_BITS_TO_LE_4BYTE(__pdesc+20, 13, 4, __val) | 326 | SET_BITS_OFFSET_LE(__pdesc+20, 13, 4, __val) |
303 | #define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val) \ | 327 | #define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val) \ |
304 | SET_BITS_TO_LE_4BYTE(__pdesc+20, 17, 1, __val) | 328 | SET_BITS_OFFSET_LE(__pdesc+20, 17, 1, __val) |
305 | #define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val) \ | 329 | #define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val) \ |
306 | SET_BITS_TO_LE_4BYTE(__pdesc+20, 18, 6, __val) | 330 | SET_BITS_OFFSET_LE(__pdesc+20, 18, 6, __val) |
307 | #define SET_TX_DESC_USB_TXAGG_NUM(__pdesc, __val) \ | 331 | #define SET_TX_DESC_USB_TXAGG_NUM(__pdesc, __val) \ |
308 | SET_BITS_TO_LE_4BYTE(__pdesc+20, 24, 8, __val) | 332 | SET_BITS_OFFSET_LE(__pdesc+20, 24, 8, __val) |
309 | 333 | ||
310 | #define GET_TX_DESC_TX_RATE(__pdesc) \ | 334 | #define GET_TX_DESC_TX_RATE(__pdesc) \ |
311 | LE_BITS_TO_4BYTE(__pdesc+20, 0, 6) | 335 | SHIFT_AND_MASK_LE(__pdesc+20, 0, 6) |
312 | #define GET_TX_DESC_DATA_SHORTGI(__pdesc) \ | 336 | #define GET_TX_DESC_DATA_SHORTGI(__pdesc) \ |
313 | LE_BITS_TO_4BYTE(__pdesc+20, 6, 1) | 337 | SHIFT_AND_MASK_LE(__pdesc+20, 6, 1) |
314 | #define GET_TX_DESC_CCX_TAG(__pdesc) \ | 338 | #define GET_TX_DESC_CCX_TAG(__pdesc) \ |
315 | LE_BITS_TO_4BYTE(__pdesc+20, 7, 1) | 339 | SHIFT_AND_MASK_LE(__pdesc+20, 7, 1) |
316 | #define GET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc) \ | 340 | #define GET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc) \ |
317 | LE_BITS_TO_4BYTE(__pdesc+20, 8, 5) | 341 | SHIFT_AND_MASK_LE(__pdesc+20, 8, 5) |
318 | #define GET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc) \ | 342 | #define GET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc) \ |
319 | LE_BITS_TO_4BYTE(__pdesc+20, 13, 4) | 343 | SHIFT_AND_MASK_LE(__pdesc+20, 13, 4) |
320 | #define GET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc) \ | 344 | #define GET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc) \ |
321 | LE_BITS_TO_4BYTE(__pdesc+20, 17, 1) | 345 | SHIFT_AND_MASK_LE(__pdesc+20, 17, 1) |
322 | #define GET_TX_DESC_DATA_RETRY_LIMIT(__pdesc) \ | 346 | #define GET_TX_DESC_DATA_RETRY_LIMIT(__pdesc) \ |
323 | LE_BITS_TO_4BYTE(__pdesc+20, 18, 6) | 347 | SHIFT_AND_MASK_LE(__pdesc+20, 18, 6) |
324 | #define GET_TX_DESC_USB_TXAGG_NUM(__pdesc) \ | 348 | #define GET_TX_DESC_USB_TXAGG_NUM(__pdesc) \ |
325 | LE_BITS_TO_4BYTE(__pdesc+20, 24, 8) | 349 | SHIFT_AND_MASK_LE(__pdesc+20, 24, 8) |
326 | 350 | ||
327 | #define SET_TX_DESC_TXAGC_A(__pdesc, __val) \ | 351 | #define SET_TX_DESC_TXAGC_A(__pdesc, __val) \ |
328 | SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 5, __val) | 352 | SET_BITS_OFFSET_LE(__pdesc+24, 0, 5, __val) |
329 | #define SET_TX_DESC_TXAGC_B(__pdesc, __val) \ | 353 | #define SET_TX_DESC_TXAGC_B(__pdesc, __val) \ |
330 | SET_BITS_TO_LE_4BYTE(__pdesc+24, 5, 5, __val) | 354 | SET_BITS_OFFSET_LE(__pdesc+24, 5, 5, __val) |
331 | #define SET_TX_DESC_USE_MAX_LEN(__pdesc, __val) \ | 355 | #define SET_TX_DESC_USE_MAX_LEN(__pdesc, __val) \ |
332 | SET_BITS_TO_LE_4BYTE(__pdesc+24, 10, 1, __val) | 356 | SET_BITS_OFFSET_LE(__pdesc+24, 10, 1, __val) |
333 | #define SET_TX_DESC_MAX_AGG_NUM(__pdesc, __val) \ | 357 | #define SET_TX_DESC_MAX_AGG_NUM(__pdesc, __val) \ |
334 | SET_BITS_TO_LE_4BYTE(__pdesc+24, 11, 5, __val) | 358 | SET_BITS_OFFSET_LE(__pdesc+24, 11, 5, __val) |
335 | #define SET_TX_DESC_MCSG1_MAX_LEN(__pdesc, __val) \ | 359 | #define SET_TX_DESC_MCSG1_MAX_LEN(__pdesc, __val) \ |
336 | SET_BITS_TO_LE_4BYTE(__pdesc+24, 16, 4, __val) | 360 | SET_BITS_OFFSET_LE(__pdesc+24, 16, 4, __val) |
337 | #define SET_TX_DESC_MCSG2_MAX_LEN(__pdesc, __val) \ | 361 | #define SET_TX_DESC_MCSG2_MAX_LEN(__pdesc, __val) \ |
338 | SET_BITS_TO_LE_4BYTE(__pdesc+24, 20, 4, __val) | 362 | SET_BITS_OFFSET_LE(__pdesc+24, 20, 4, __val) |
339 | #define SET_TX_DESC_MCSG3_MAX_LEN(__pdesc, __val) \ | 363 | #define SET_TX_DESC_MCSG3_MAX_LEN(__pdesc, __val) \ |
340 | SET_BITS_TO_LE_4BYTE(__pdesc+24, 24, 4, __val) | 364 | SET_BITS_OFFSET_LE(__pdesc+24, 24, 4, __val) |
341 | #define SET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc, __val) \ | 365 | #define SET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc, __val) \ |
342 | SET_BITS_TO_LE_4BYTE(__pdesc+24, 28, 4, __val) | 366 | SET_BITS_OFFSET_LE(__pdesc+24, 28, 4, __val) |
343 | 367 | ||
344 | #define GET_TX_DESC_TXAGC_A(__pdesc) \ | 368 | #define GET_TX_DESC_TXAGC_A(__pdesc) \ |
345 | LE_BITS_TO_4BYTE(__pdesc+24, 0, 5) | 369 | SHIFT_AND_MASK_LE(__pdesc+24, 0, 5) |
346 | #define GET_TX_DESC_TXAGC_B(__pdesc) \ | 370 | #define GET_TX_DESC_TXAGC_B(__pdesc) \ |
347 | LE_BITS_TO_4BYTE(__pdesc+24, 5, 5) | 371 | SHIFT_AND_MASK_LE(__pdesc+24, 5, 5) |
348 | #define GET_TX_DESC_USE_MAX_LEN(__pdesc) \ | 372 | #define GET_TX_DESC_USE_MAX_LEN(__pdesc) \ |
349 | LE_BITS_TO_4BYTE(__pdesc+24, 10, 1) | 373 | SHIFT_AND_MASK_LE(__pdesc+24, 10, 1) |
350 | #define GET_TX_DESC_MAX_AGG_NUM(__pdesc) \ | 374 | #define GET_TX_DESC_MAX_AGG_NUM(__pdesc) \ |
351 | LE_BITS_TO_4BYTE(__pdesc+24, 11, 5) | 375 | SHIFT_AND_MASK_LE(__pdesc+24, 11, 5) |
352 | #define GET_TX_DESC_MCSG1_MAX_LEN(__pdesc) \ | 376 | #define GET_TX_DESC_MCSG1_MAX_LEN(__pdesc) \ |
353 | LE_BITS_TO_4BYTE(__pdesc+24, 16, 4) | 377 | SHIFT_AND_MASK_LE(__pdesc+24, 16, 4) |
354 | #define GET_TX_DESC_MCSG2_MAX_LEN(__pdesc) \ | 378 | #define GET_TX_DESC_MCSG2_MAX_LEN(__pdesc) \ |
355 | LE_BITS_TO_4BYTE(__pdesc+24, 20, 4) | 379 | SHIFT_AND_MASK_LE(__pdesc+24, 20, 4) |
356 | #define GET_TX_DESC_MCSG3_MAX_LEN(__pdesc) \ | 380 | #define GET_TX_DESC_MCSG3_MAX_LEN(__pdesc) \ |
357 | LE_BITS_TO_4BYTE(__pdesc+24, 24, 4) | 381 | SHIFT_AND_MASK_LE(__pdesc+24, 24, 4) |
358 | #define GET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc) \ | 382 | #define GET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc) \ |
359 | LE_BITS_TO_4BYTE(__pdesc+24, 28, 4) | 383 | SHIFT_AND_MASK_LE(__pdesc+24, 28, 4) |
360 | 384 | ||
361 | #define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val) \ | 385 | #define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val) \ |
362 | SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 16, __val) | 386 | SET_BITS_OFFSET_LE(__pdesc+28, 0, 16, __val) |
363 | #define SET_TX_DESC_MCSG4_MAX_LEN(__pdesc, __val) \ | 387 | #define SET_TX_DESC_MCSG4_MAX_LEN(__pdesc, __val) \ |
364 | SET_BITS_TO_LE_4BYTE(__pdesc+28, 16, 4, __val) | 388 | SET_BITS_OFFSET_LE(__pdesc+28, 16, 4, __val) |
365 | #define SET_TX_DESC_MCSG5_MAX_LEN(__pdesc, __val) \ | 389 | #define SET_TX_DESC_MCSG5_MAX_LEN(__pdesc, __val) \ |
366 | SET_BITS_TO_LE_4BYTE(__pdesc+28, 20, 4, __val) | 390 | SET_BITS_OFFSET_LE(__pdesc+28, 20, 4, __val) |
367 | #define SET_TX_DESC_MCSG6_MAX_LEN(__pdesc, __val) \ | 391 | #define SET_TX_DESC_MCSG6_MAX_LEN(__pdesc, __val) \ |
368 | SET_BITS_TO_LE_4BYTE(__pdesc+28, 24, 4, __val) | 392 | SET_BITS_OFFSET_LE(__pdesc+28, 24, 4, __val) |
369 | #define SET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc, __val) \ | 393 | #define SET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc, __val) \ |
370 | SET_BITS_TO_LE_4BYTE(__pdesc+28, 28, 4, __val) | 394 | SET_BITS_OFFSET_LE(__pdesc+28, 28, 4, __val) |
371 | 395 | ||
372 | #define GET_TX_DESC_TX_BUFFER_SIZE(__pdesc) \ | 396 | #define GET_TX_DESC_TX_BUFFER_SIZE(__pdesc) \ |
373 | LE_BITS_TO_4BYTE(__pdesc+28, 0, 16) | 397 | SHIFT_AND_MASK_LE(__pdesc+28, 0, 16) |
374 | #define GET_TX_DESC_MCSG4_MAX_LEN(__pdesc) \ | 398 | #define GET_TX_DESC_MCSG4_MAX_LEN(__pdesc) \ |
375 | LE_BITS_TO_4BYTE(__pdesc+28, 16, 4) | 399 | SHIFT_AND_MASK_LE(__pdesc+28, 16, 4) |
376 | #define GET_TX_DESC_MCSG5_MAX_LEN(__pdesc) \ | 400 | #define GET_TX_DESC_MCSG5_MAX_LEN(__pdesc) \ |
377 | LE_BITS_TO_4BYTE(__pdesc+28, 20, 4) | 401 | SHIFT_AND_MASK_LE(__pdesc+28, 20, 4) |
378 | #define GET_TX_DESC_MCSG6_MAX_LEN(__pdesc) \ | 402 | #define GET_TX_DESC_MCSG6_MAX_LEN(__pdesc) \ |
379 | LE_BITS_TO_4BYTE(__pdesc+28, 24, 4) | 403 | SHIFT_AND_MASK_LE(__pdesc+28, 24, 4) |
380 | #define GET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc) \ | 404 | #define GET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc) \ |
381 | LE_BITS_TO_4BYTE(__pdesc+28, 28, 4) | 405 | SHIFT_AND_MASK_LE(__pdesc+28, 28, 4) |
382 | 406 | ||
383 | #define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val) \ | 407 | #define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val) \ |
384 | SET_BITS_TO_LE_4BYTE(__pdesc+32, 0, 32, __val) | 408 | SET_BITS_OFFSET_LE(__pdesc+32, 0, 32, __val) |
385 | #define SET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc, __val) \ | 409 | #define SET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc, __val) \ |
386 | SET_BITS_TO_LE_4BYTE(__pdesc+36, 0, 32, __val) | 410 | SET_BITS_OFFSET_LE(__pdesc+36, 0, 32, __val) |
387 | 411 | ||
388 | #define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc) \ | 412 | #define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc) \ |
389 | LE_BITS_TO_4BYTE(__pdesc+32, 0, 32) | 413 | SHIFT_AND_MASK_LE(__pdesc+32, 0, 32) |
390 | #define GET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc) \ | 414 | #define GET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc) \ |
391 | LE_BITS_TO_4BYTE(__pdesc+36, 0, 32) | 415 | SHIFT_AND_MASK_LE(__pdesc+36, 0, 32) |
392 | 416 | ||
393 | #define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val) \ | 417 | #define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val) \ |
394 | SET_BITS_TO_LE_4BYTE(__pdesc+40, 0, 32, __val) | 418 | SET_BITS_OFFSET_LE(__pdesc+40, 0, 32, __val) |
395 | #define SET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc, __val) \ | 419 | #define SET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc, __val) \ |
396 | SET_BITS_TO_LE_4BYTE(__pdesc+44, 0, 32, __val) | 420 | SET_BITS_OFFSET_LE(__pdesc+44, 0, 32, __val) |
397 | 421 | ||
398 | #define GET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc) \ | 422 | #define GET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc) \ |
399 | LE_BITS_TO_4BYTE(__pdesc+40, 0, 32) | 423 | SHIFT_AND_MASK_LE(__pdesc+40, 0, 32) |
400 | #define GET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc) \ | 424 | #define GET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc) \ |
401 | LE_BITS_TO_4BYTE(__pdesc+44, 0, 32) | 425 | SHIFT_AND_MASK_LE(__pdesc+44, 0, 32) |
402 | 426 | ||
403 | #define GET_RX_DESC_PKT_LEN(__pdesc) \ | 427 | #define GET_RX_DESC_PKT_LEN(__pdesc) \ |
404 | LE_BITS_TO_4BYTE(__pdesc, 0, 14) | 428 | SHIFT_AND_MASK_LE(__pdesc, 0, 14) |
405 | #define GET_RX_DESC_CRC32(__pdesc) \ | 429 | #define GET_RX_DESC_CRC32(__pdesc) \ |
406 | LE_BITS_TO_4BYTE(__pdesc, 14, 1) | 430 | SHIFT_AND_MASK_LE(__pdesc, 14, 1) |
407 | #define GET_RX_DESC_ICV(__pdesc) \ | 431 | #define GET_RX_DESC_ICV(__pdesc) \ |
408 | LE_BITS_TO_4BYTE(__pdesc, 15, 1) | 432 | SHIFT_AND_MASK_LE(__pdesc, 15, 1) |
409 | #define GET_RX_DESC_DRV_INFO_SIZE(__pdesc) \ | 433 | #define GET_RX_DESC_DRV_INFO_SIZE(__pdesc) \ |
410 | LE_BITS_TO_4BYTE(__pdesc, 16, 4) | 434 | SHIFT_AND_MASK_LE(__pdesc, 16, 4) |
411 | #define GET_RX_DESC_SECURITY(__pdesc) \ | 435 | #define GET_RX_DESC_SECURITY(__pdesc) \ |
412 | LE_BITS_TO_4BYTE(__pdesc, 20, 3) | 436 | SHIFT_AND_MASK_LE(__pdesc, 20, 3) |
413 | #define GET_RX_DESC_QOS(__pdesc) \ | 437 | #define GET_RX_DESC_QOS(__pdesc) \ |
414 | LE_BITS_TO_4BYTE(__pdesc, 23, 1) | 438 | SHIFT_AND_MASK_LE(__pdesc, 23, 1) |
415 | #define GET_RX_DESC_SHIFT(__pdesc) \ | 439 | #define GET_RX_DESC_SHIFT(__pdesc) \ |
416 | LE_BITS_TO_4BYTE(__pdesc, 24, 2) | 440 | SHIFT_AND_MASK_LE(__pdesc, 24, 2) |
417 | #define GET_RX_DESC_PHYST(__pdesc) \ | 441 | #define GET_RX_DESC_PHYST(__pdesc) \ |
418 | LE_BITS_TO_4BYTE(__pdesc, 26, 1) | 442 | SHIFT_AND_MASK_LE(__pdesc, 26, 1) |
419 | #define GET_RX_DESC_SWDEC(__pdesc) \ | 443 | #define GET_RX_DESC_SWDEC(__pdesc) \ |
420 | LE_BITS_TO_4BYTE(__pdesc, 27, 1) | 444 | SHIFT_AND_MASK_LE(__pdesc, 27, 1) |
421 | #define GET_RX_DESC_LS(__pdesc) \ | 445 | #define GET_RX_DESC_LS(__pdesc) \ |
422 | LE_BITS_TO_4BYTE(__pdesc, 28, 1) | 446 | SHIFT_AND_MASK_LE(__pdesc, 28, 1) |
423 | #define GET_RX_DESC_FS(__pdesc) \ | 447 | #define GET_RX_DESC_FS(__pdesc) \ |
424 | LE_BITS_TO_4BYTE(__pdesc, 29, 1) | 448 | SHIFT_AND_MASK_LE(__pdesc, 29, 1) |
425 | #define GET_RX_DESC_EOR(__pdesc) \ | 449 | #define GET_RX_DESC_EOR(__pdesc) \ |
426 | LE_BITS_TO_4BYTE(__pdesc, 30, 1) | 450 | SHIFT_AND_MASK_LE(__pdesc, 30, 1) |
427 | #define GET_RX_DESC_OWN(__pdesc) \ | 451 | #define GET_RX_DESC_OWN(__pdesc) \ |
428 | LE_BITS_TO_4BYTE(__pdesc, 31, 1) | 452 | SHIFT_AND_MASK_LE(__pdesc, 31, 1) |
429 | 453 | ||
430 | #define SET_RX_DESC_PKT_LEN(__pdesc, __val) \ | 454 | #define SET_RX_DESC_PKT_LEN(__pdesc, __val) \ |
431 | SET_BITS_TO_LE_4BYTE(__pdesc, 0, 14, __val) | 455 | SET_BITS_OFFSET_LE(__pdesc, 0, 14, __val) |
432 | #define SET_RX_DESC_EOR(__pdesc, __val) \ | 456 | #define SET_RX_DESC_EOR(__pdesc, __val) \ |
433 | SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val) | 457 | SET_BITS_OFFSET_LE(__pdesc, 30, 1, __val) |
434 | #define SET_RX_DESC_OWN(__pdesc, __val) \ | 458 | #define SET_RX_DESC_OWN(__pdesc, __val) \ |
435 | SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val) | 459 | SET_BITS_OFFSET_LE(__pdesc, 31, 1, __val) |
436 | 460 | ||
437 | #define GET_RX_DESC_MACID(__pdesc) \ | 461 | #define GET_RX_DESC_MACID(__pdesc) \ |
438 | LE_BITS_TO_4BYTE(__pdesc+4, 0, 5) | 462 | SHIFT_AND_MASK_LE(__pdesc+4, 0, 5) |
439 | #define GET_RX_DESC_TID(__pdesc) \ | 463 | #define GET_RX_DESC_TID(__pdesc) \ |
440 | LE_BITS_TO_4BYTE(__pdesc+4, 5, 4) | 464 | SHIFT_AND_MASK_LE(__pdesc+4, 5, 4) |
441 | #define GET_RX_DESC_HWRSVD(__pdesc) \ | 465 | #define GET_RX_DESC_HWRSVD(__pdesc) \ |
442 | LE_BITS_TO_4BYTE(__pdesc+4, 9, 5) | 466 | SHIFT_AND_MASK_LE(__pdesc+4, 9, 5) |
443 | #define GET_RX_DESC_PAGGR(__pdesc) \ | 467 | #define GET_RX_DESC_PAGGR(__pdesc) \ |
444 | LE_BITS_TO_4BYTE(__pdesc+4, 14, 1) | 468 | SHIFT_AND_MASK_LE(__pdesc+4, 14, 1) |
445 | #define GET_RX_DESC_FAGGR(__pdesc) \ | 469 | #define GET_RX_DESC_FAGGR(__pdesc) \ |
446 | LE_BITS_TO_4BYTE(__pdesc+4, 15, 1) | 470 | SHIFT_AND_MASK_LE(__pdesc+4, 15, 1) |
447 | #define GET_RX_DESC_A1_FIT(__pdesc) \ | 471 | #define GET_RX_DESC_A1_FIT(__pdesc) \ |
448 | LE_BITS_TO_4BYTE(__pdesc+4, 16, 4) | 472 | SHIFT_AND_MASK_LE(__pdesc+4, 16, 4) |
449 | #define GET_RX_DESC_A2_FIT(__pdesc) \ | 473 | #define GET_RX_DESC_A2_FIT(__pdesc) \ |
450 | LE_BITS_TO_4BYTE(__pdesc+4, 20, 4) | 474 | SHIFT_AND_MASK_LE(__pdesc+4, 20, 4) |
451 | #define GET_RX_DESC_PAM(__pdesc) \ | 475 | #define GET_RX_DESC_PAM(__pdesc) \ |
452 | LE_BITS_TO_4BYTE(__pdesc+4, 24, 1) | 476 | SHIFT_AND_MASK_LE(__pdesc+4, 24, 1) |
453 | #define GET_RX_DESC_PWR(__pdesc) \ | 477 | #define GET_RX_DESC_PWR(__pdesc) \ |
454 | LE_BITS_TO_4BYTE(__pdesc+4, 25, 1) | 478 | SHIFT_AND_MASK_LE(__pdesc+4, 25, 1) |
455 | #define GET_RX_DESC_MD(__pdesc) \ | 479 | #define GET_RX_DESC_MD(__pdesc) \ |
456 | LE_BITS_TO_4BYTE(__pdesc+4, 26, 1) | 480 | SHIFT_AND_MASK_LE(__pdesc+4, 26, 1) |
457 | #define GET_RX_DESC_MF(__pdesc) \ | 481 | #define GET_RX_DESC_MF(__pdesc) \ |
458 | LE_BITS_TO_4BYTE(__pdesc+4, 27, 1) | 482 | SHIFT_AND_MASK_LE(__pdesc+4, 27, 1) |
459 | #define GET_RX_DESC_TYPE(__pdesc) \ | 483 | #define GET_RX_DESC_TYPE(__pdesc) \ |
460 | LE_BITS_TO_4BYTE(__pdesc+4, 28, 2) | 484 | SHIFT_AND_MASK_LE(__pdesc+4, 28, 2) |
461 | #define GET_RX_DESC_MC(__pdesc) \ | 485 | #define GET_RX_DESC_MC(__pdesc) \ |
462 | LE_BITS_TO_4BYTE(__pdesc+4, 30, 1) | 486 | SHIFT_AND_MASK_LE(__pdesc+4, 30, 1) |
463 | #define GET_RX_DESC_BC(__pdesc) \ | 487 | #define GET_RX_DESC_BC(__pdesc) \ |
464 | LE_BITS_TO_4BYTE(__pdesc+4, 31, 1) | 488 | SHIFT_AND_MASK_LE(__pdesc+4, 31, 1) |
465 | #define GET_RX_DESC_SEQ(__pdesc) \ | 489 | #define GET_RX_DESC_SEQ(__pdesc) \ |
466 | LE_BITS_TO_4BYTE(__pdesc+8, 0, 12) | 490 | SHIFT_AND_MASK_LE(__pdesc+8, 0, 12) |
467 | #define GET_RX_DESC_FRAG(__pdesc) \ | 491 | #define GET_RX_DESC_FRAG(__pdesc) \ |
468 | LE_BITS_TO_4BYTE(__pdesc+8, 12, 4) | 492 | SHIFT_AND_MASK_LE(__pdesc+8, 12, 4) |
469 | #define GET_RX_DESC_NEXT_PKT_LEN(__pdesc) \ | 493 | #define GET_RX_DESC_NEXT_PKT_LEN(__pdesc) \ |
470 | LE_BITS_TO_4BYTE(__pdesc+8, 16, 14) | 494 | SHIFT_AND_MASK_LE(__pdesc+8, 16, 14) |
471 | #define GET_RX_DESC_NEXT_IND(__pdesc) \ | 495 | #define GET_RX_DESC_NEXT_IND(__pdesc) \ |
472 | LE_BITS_TO_4BYTE(__pdesc+8, 30, 1) | 496 | SHIFT_AND_MASK_LE(__pdesc+8, 30, 1) |
473 | #define GET_RX_DESC_RSVD(__pdesc) \ | 497 | #define GET_RX_DESC_RSVD(__pdesc) \ |
474 | LE_BITS_TO_4BYTE(__pdesc+8, 31, 1) | 498 | SHIFT_AND_MASK_LE(__pdesc+8, 31, 1) |
475 | 499 | ||
476 | #define GET_RX_DESC_RXMCS(__pdesc) \ | 500 | #define GET_RX_DESC_RXMCS(__pdesc) \ |
477 | LE_BITS_TO_4BYTE(__pdesc+12, 0, 6) | 501 | SHIFT_AND_MASK_LE(__pdesc+12, 0, 6) |
478 | #define GET_RX_DESC_RXHT(__pdesc) \ | 502 | #define GET_RX_DESC_RXHT(__pdesc) \ |
479 | LE_BITS_TO_4BYTE(__pdesc+12, 6, 1) | 503 | SHIFT_AND_MASK_LE(__pdesc+12, 6, 1) |
480 | #define GET_RX_DESC_SPLCP(__pdesc) \ | 504 | #define GET_RX_DESC_SPLCP(__pdesc) \ |
481 | LE_BITS_TO_4BYTE(__pdesc+12, 8, 1) | 505 | SHIFT_AND_MASK_LE(__pdesc+12, 8, 1) |
482 | #define GET_RX_DESC_BW(__pdesc) \ | 506 | #define GET_RX_DESC_BW(__pdesc) \ |
483 | LE_BITS_TO_4BYTE(__pdesc+12, 9, 1) | 507 | SHIFT_AND_MASK_LE(__pdesc+12, 9, 1) |
484 | #define GET_RX_DESC_HTC(__pdesc) \ | 508 | #define GET_RX_DESC_HTC(__pdesc) \ |
485 | LE_BITS_TO_4BYTE(__pdesc+12, 10, 1) | 509 | SHIFT_AND_MASK_LE(__pdesc+12, 10, 1) |
486 | #define GET_RX_DESC_HWPC_ERR(__pdesc) \ | 510 | #define GET_RX_DESC_HWPC_ERR(__pdesc) \ |
487 | LE_BITS_TO_4BYTE(__pdesc+12, 14, 1) | 511 | SHIFT_AND_MASK_LE(__pdesc+12, 14, 1) |
488 | #define GET_RX_DESC_HWPC_IND(__pdesc) \ | 512 | #define GET_RX_DESC_HWPC_IND(__pdesc) \ |
489 | LE_BITS_TO_4BYTE(__pdesc+12, 15, 1) | 513 | SHIFT_AND_MASK_LE(__pdesc+12, 15, 1) |
490 | #define GET_RX_DESC_IV0(__pdesc) \ | 514 | #define GET_RX_DESC_IV0(__pdesc) \ |
491 | LE_BITS_TO_4BYTE(__pdesc+12, 16, 16) | 515 | SHIFT_AND_MASK_LE(__pdesc+12, 16, 16) |
492 | 516 | ||
493 | #define GET_RX_DESC_IV1(__pdesc) \ | 517 | #define GET_RX_DESC_IV1(__pdesc) \ |
494 | LE_BITS_TO_4BYTE(__pdesc+16, 0, 32) | 518 | SHIFT_AND_MASK_LE(__pdesc+16, 0, 32) |
495 | #define GET_RX_DESC_TSFL(__pdesc) \ | 519 | #define GET_RX_DESC_TSFL(__pdesc) \ |
496 | LE_BITS_TO_4BYTE(__pdesc+20, 0, 32) | 520 | SHIFT_AND_MASK_LE(__pdesc+20, 0, 32) |
497 | 521 | ||
498 | #define GET_RX_DESC_BUFF_ADDR(__pdesc) \ | 522 | #define GET_RX_DESC_BUFF_ADDR(__pdesc) \ |
499 | LE_BITS_TO_4BYTE(__pdesc+24, 0, 32) | 523 | SHIFT_AND_MASK_LE(__pdesc+24, 0, 32) |
500 | #define GET_RX_DESC_BUFF_ADDR64(__pdesc) \ | 524 | #define GET_RX_DESC_BUFF_ADDR64(__pdesc) \ |
501 | LE_BITS_TO_4BYTE(__pdesc+28, 0, 32) | 525 | SHIFT_AND_MASK_LE(__pdesc+28, 0, 32) |
502 | 526 | ||
503 | #define SET_RX_DESC_BUFF_ADDR(__pdesc, __val) \ | 527 | #define SET_RX_DESC_BUFF_ADDR(__pdesc, __val) \ |
504 | SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 32, __val) | 528 | SET_BITS_OFFSET_LE(__pdesc+24, 0, 32, __val) |
505 | #define SET_RX_DESC_BUFF_ADDR64(__pdesc, __val) \ | 529 | #define SET_RX_DESC_BUFF_ADDR64(__pdesc, __val) \ |
506 | SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 32, __val) | 530 | SET_BITS_OFFSET_LE(__pdesc+28, 0, 32, __val) |
507 | 531 | ||
508 | #define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \ | 532 | #define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \ |
509 | do { \ | 533 | do { \ |
@@ -711,4 +735,6 @@ void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue); | |||
711 | void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, | 735 | void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, |
712 | bool b_firstseg, bool b_lastseg, | 736 | bool b_firstseg, bool b_lastseg, |
713 | struct sk_buff *skb); | 737 | struct sk_buff *skb); |
738 | bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb); | ||
739 | |||
714 | #endif | 740 | #endif |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/Makefile b/drivers/net/wireless/rtlwifi/rtl8192cu/Makefile new file mode 100644 index 000000000000..91c65122ca80 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/Makefile | |||
@@ -0,0 +1,15 @@ | |||
1 | rtl8192cu-objs := \ | ||
2 | dm.o \ | ||
3 | fw.o \ | ||
4 | hw.o \ | ||
5 | led.o \ | ||
6 | mac.o \ | ||
7 | phy.o \ | ||
8 | rf.o \ | ||
9 | sw.o \ | ||
10 | table.o \ | ||
11 | trx.o | ||
12 | |||
13 | obj-$(CONFIG_RTL8192CU) += rtl8192cu.o | ||
14 | |||
15 | ccflags-y += -D__CHECK_ENDIAN__ | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/def.h b/drivers/net/wireless/rtlwifi/rtl8192cu/def.h new file mode 100644 index 000000000000..c54940ea72fe --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/def.h | |||
@@ -0,0 +1,62 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 Realtek Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #include "../rtl8192ce/def.h" | ||
31 | |||
32 | /*------------------------------------------------------------------------- | ||
33 | * Chip specific | ||
34 | *-------------------------------------------------------------------------*/ | ||
35 | #define CHIP_8723 BIT(2) /* RTL8723 With BT feature */ | ||
36 | #define CHIP_8723_DRV_REV BIT(3) /* RTL8723 Driver Revised */ | ||
37 | #define NORMAL_CHIP BIT(4) | ||
38 | #define CHIP_VENDOR_UMC BIT(5) | ||
39 | #define CHIP_VENDOR_UMC_B_CUT BIT(6) | ||
40 | |||
41 | #define IS_NORMAL_CHIP(version) \ | ||
42 | (((version) & NORMAL_CHIP) ? true : false) | ||
43 | |||
44 | #define IS_8723_SERIES(version) \ | ||
45 | (((version) & CHIP_8723) ? true : false) | ||
46 | |||
47 | #define IS_92C_1T2R(version) \ | ||
48 | (((version) & CHIP_92C) && ((version) & CHIP_92C_1T2R)) | ||
49 | |||
50 | #define IS_VENDOR_UMC(version) \ | ||
51 | (((version) & CHIP_VENDOR_UMC) ? true : false) | ||
52 | |||
53 | #define IS_VENDOR_UMC_A_CUT(version) \ | ||
54 | (((version) & CHIP_VENDOR_UMC) ? (((version) & (BIT(6) | BIT(7))) ? \ | ||
55 | false : true) : false) | ||
56 | |||
57 | #define IS_VENDOR_8723_A_CUT(version) \ | ||
58 | (((version) & CHIP_VENDOR_UMC) ? (((version) & (BIT(6))) ? \ | ||
59 | false : true) : false) | ||
60 | |||
61 | #define CHIP_BONDING_92C_1T2R 0x1 | ||
62 | #define CHIP_BONDING_IDENTIFIER(_value) (((_value) >> 22) & 0x3) | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c new file mode 100644 index 000000000000..a4649a2f7e6f --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c | |||
@@ -0,0 +1,116 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 Realtek Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #include "../wifi.h" | ||
31 | #include "../base.h" | ||
32 | #include "reg.h" | ||
33 | #include "def.h" | ||
34 | #include "phy.h" | ||
35 | #include "dm.h" | ||
36 | #include "fw.h" | ||
37 | |||
38 | #include "../rtl8192c/dm_common.c" | ||
39 | |||
40 | void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) | ||
41 | { | ||
42 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
43 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
44 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
45 | long undecorated_smoothed_pwdb; | ||
46 | |||
47 | if (!rtlpriv->dm.dynamic_txpower_enable) | ||
48 | return; | ||
49 | |||
50 | if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) { | ||
51 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; | ||
52 | return; | ||
53 | } | ||
54 | |||
55 | if ((mac->link_state < MAC80211_LINKED) && | ||
56 | (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { | ||
57 | RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, | ||
58 | ("Not connected to any\n")); | ||
59 | |||
60 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; | ||
61 | |||
62 | rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; | ||
63 | return; | ||
64 | } | ||
65 | |||
66 | if (mac->link_state >= MAC80211_LINKED) { | ||
67 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { | ||
68 | undecorated_smoothed_pwdb = | ||
69 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | ||
70 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
71 | ("AP Client PWDB = 0x%lx\n", | ||
72 | undecorated_smoothed_pwdb)); | ||
73 | } else { | ||
74 | undecorated_smoothed_pwdb = | ||
75 | rtlpriv->dm.undecorated_smoothed_pwdb; | ||
76 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
77 | ("STA Default Port PWDB = 0x%lx\n", | ||
78 | undecorated_smoothed_pwdb)); | ||
79 | } | ||
80 | } else { | ||
81 | undecorated_smoothed_pwdb = | ||
82 | rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; | ||
83 | |||
84 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
85 | ("AP Ext Port PWDB = 0x%lx\n", | ||
86 | undecorated_smoothed_pwdb)); | ||
87 | } | ||
88 | |||
89 | if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { | ||
90 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; | ||
91 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
92 | ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n")); | ||
93 | } else if ((undecorated_smoothed_pwdb < | ||
94 | (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && | ||
95 | (undecorated_smoothed_pwdb >= | ||
96 | TX_POWER_NEAR_FIELD_THRESH_LVL1)) { | ||
97 | |||
98 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; | ||
99 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
100 | ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n")); | ||
101 | } else if (undecorated_smoothed_pwdb < | ||
102 | (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { | ||
103 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; | ||
104 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
105 | ("TXHIGHPWRLEVEL_NORMAL\n")); | ||
106 | } | ||
107 | |||
108 | if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) { | ||
109 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
110 | ("PHY_SetTxPowerLevel8192S() Channel = %d\n", | ||
111 | rtlphy->current_channel)); | ||
112 | rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); | ||
113 | } | ||
114 | |||
115 | rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; | ||
116 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h new file mode 100644 index 000000000000..5e7fbfc2851b --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h | |||
@@ -0,0 +1,32 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 Realtek Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #include "../rtl8192ce/dm.h" | ||
31 | |||
32 | void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw); | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/fw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/fw.c new file mode 100644 index 000000000000..8e350eea3422 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/fw.c | |||
@@ -0,0 +1,30 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 Realtek Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #include "../rtl8192ce/fw.c" | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/fw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/fw.h new file mode 100644 index 000000000000..a3bbac811d08 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/fw.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 Realtek Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #include "../rtl8192ce/fw.h" | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c new file mode 100644 index 000000000000..df8fe3b51c9b --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | |||
@@ -0,0 +1,2505 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #include "../wifi.h" | ||
31 | #include "../efuse.h" | ||
32 | #include "../base.h" | ||
33 | #include "../cam.h" | ||
34 | #include "../ps.h" | ||
35 | #include "../usb.h" | ||
36 | #include "reg.h" | ||
37 | #include "def.h" | ||
38 | #include "phy.h" | ||
39 | #include "mac.h" | ||
40 | #include "dm.h" | ||
41 | #include "fw.h" | ||
42 | #include "hw.h" | ||
43 | #include "trx.h" | ||
44 | #include "led.h" | ||
45 | #include "table.h" | ||
46 | |||
47 | static void _rtl92cu_phy_param_tab_init(struct ieee80211_hw *hw) | ||
48 | { | ||
49 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
50 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
51 | struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv); | ||
52 | |||
53 | rtlphy->hwparam_tables[MAC_REG].length = RTL8192CUMAC_2T_ARRAYLENGTH; | ||
54 | rtlphy->hwparam_tables[MAC_REG].pdata = RTL8192CUMAC_2T_ARRAY; | ||
55 | if (IS_HIGHT_PA(rtlefuse->board_type)) { | ||
56 | rtlphy->hwparam_tables[PHY_REG_PG].length = | ||
57 | RTL8192CUPHY_REG_Array_PG_HPLength; | ||
58 | rtlphy->hwparam_tables[PHY_REG_PG].pdata = | ||
59 | RTL8192CUPHY_REG_Array_PG_HP; | ||
60 | } else { | ||
61 | rtlphy->hwparam_tables[PHY_REG_PG].length = | ||
62 | RTL8192CUPHY_REG_ARRAY_PGLENGTH; | ||
63 | rtlphy->hwparam_tables[PHY_REG_PG].pdata = | ||
64 | RTL8192CUPHY_REG_ARRAY_PG; | ||
65 | } | ||
66 | /* 2T */ | ||
67 | rtlphy->hwparam_tables[PHY_REG_2T].length = | ||
68 | RTL8192CUPHY_REG_2TARRAY_LENGTH; | ||
69 | rtlphy->hwparam_tables[PHY_REG_2T].pdata = | ||
70 | RTL8192CUPHY_REG_2TARRAY; | ||
71 | rtlphy->hwparam_tables[RADIOA_2T].length = | ||
72 | RTL8192CURADIOA_2TARRAYLENGTH; | ||
73 | rtlphy->hwparam_tables[RADIOA_2T].pdata = | ||
74 | RTL8192CURADIOA_2TARRAY; | ||
75 | rtlphy->hwparam_tables[RADIOB_2T].length = | ||
76 | RTL8192CURADIOB_2TARRAYLENGTH; | ||
77 | rtlphy->hwparam_tables[RADIOB_2T].pdata = | ||
78 | RTL8192CU_RADIOB_2TARRAY; | ||
79 | rtlphy->hwparam_tables[AGCTAB_2T].length = | ||
80 | RTL8192CUAGCTAB_2TARRAYLENGTH; | ||
81 | rtlphy->hwparam_tables[AGCTAB_2T].pdata = | ||
82 | RTL8192CUAGCTAB_2TARRAY; | ||
83 | /* 1T */ | ||
84 | if (IS_HIGHT_PA(rtlefuse->board_type)) { | ||
85 | rtlphy->hwparam_tables[PHY_REG_1T].length = | ||
86 | RTL8192CUPHY_REG_1T_HPArrayLength; | ||
87 | rtlphy->hwparam_tables[PHY_REG_1T].pdata = | ||
88 | RTL8192CUPHY_REG_1T_HPArray; | ||
89 | rtlphy->hwparam_tables[RADIOA_1T].length = | ||
90 | RTL8192CURadioA_1T_HPArrayLength; | ||
91 | rtlphy->hwparam_tables[RADIOA_1T].pdata = | ||
92 | RTL8192CURadioA_1T_HPArray; | ||
93 | rtlphy->hwparam_tables[RADIOB_1T].length = | ||
94 | RTL8192CURADIOB_1TARRAYLENGTH; | ||
95 | rtlphy->hwparam_tables[RADIOB_1T].pdata = | ||
96 | RTL8192CU_RADIOB_1TARRAY; | ||
97 | rtlphy->hwparam_tables[AGCTAB_1T].length = | ||
98 | RTL8192CUAGCTAB_1T_HPArrayLength; | ||
99 | rtlphy->hwparam_tables[AGCTAB_1T].pdata = | ||
100 | Rtl8192CUAGCTAB_1T_HPArray; | ||
101 | } else { | ||
102 | rtlphy->hwparam_tables[PHY_REG_1T].length = | ||
103 | RTL8192CUPHY_REG_1TARRAY_LENGTH; | ||
104 | rtlphy->hwparam_tables[PHY_REG_1T].pdata = | ||
105 | RTL8192CUPHY_REG_1TARRAY; | ||
106 | rtlphy->hwparam_tables[RADIOA_1T].length = | ||
107 | RTL8192CURADIOA_1TARRAYLENGTH; | ||
108 | rtlphy->hwparam_tables[RADIOA_1T].pdata = | ||
109 | RTL8192CU_RADIOA_1TARRAY; | ||
110 | rtlphy->hwparam_tables[RADIOB_1T].length = | ||
111 | RTL8192CURADIOB_1TARRAYLENGTH; | ||
112 | rtlphy->hwparam_tables[RADIOB_1T].pdata = | ||
113 | RTL8192CU_RADIOB_1TARRAY; | ||
114 | rtlphy->hwparam_tables[AGCTAB_1T].length = | ||
115 | RTL8192CUAGCTAB_1TARRAYLENGTH; | ||
116 | rtlphy->hwparam_tables[AGCTAB_1T].pdata = | ||
117 | RTL8192CUAGCTAB_1TARRAY; | ||
118 | } | ||
119 | } | ||
120 | |||
121 | static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, | ||
122 | bool autoload_fail, | ||
123 | u8 *hwinfo) | ||
124 | { | ||
125 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
126 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
127 | u8 rf_path, index, tempval; | ||
128 | u16 i; | ||
129 | |||
130 | for (rf_path = 0; rf_path < 2; rf_path++) { | ||
131 | for (i = 0; i < 3; i++) { | ||
132 | if (!autoload_fail) { | ||
133 | rtlefuse-> | ||
134 | eeprom_chnlarea_txpwr_cck[rf_path][i] = | ||
135 | hwinfo[EEPROM_TXPOWERCCK + rf_path * 3 + i]; | ||
136 | rtlefuse-> | ||
137 | eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] = | ||
138 | hwinfo[EEPROM_TXPOWERHT40_1S + rf_path * 3 + | ||
139 | i]; | ||
140 | } else { | ||
141 | rtlefuse-> | ||
142 | eeprom_chnlarea_txpwr_cck[rf_path][i] = | ||
143 | EEPROM_DEFAULT_TXPOWERLEVEL; | ||
144 | rtlefuse-> | ||
145 | eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] = | ||
146 | EEPROM_DEFAULT_TXPOWERLEVEL; | ||
147 | } | ||
148 | } | ||
149 | } | ||
150 | for (i = 0; i < 3; i++) { | ||
151 | if (!autoload_fail) | ||
152 | tempval = hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i]; | ||
153 | else | ||
154 | tempval = EEPROM_DEFAULT_HT40_2SDIFF; | ||
155 | rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[RF90_PATH_A][i] = | ||
156 | (tempval & 0xf); | ||
157 | rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[RF90_PATH_B][i] = | ||
158 | ((tempval & 0xf0) >> 4); | ||
159 | } | ||
160 | for (rf_path = 0; rf_path < 2; rf_path++) | ||
161 | for (i = 0; i < 3; i++) | ||
162 | RTPRINT(rtlpriv, FINIT, INIT_EEPROM, | ||
163 | ("RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path, | ||
164 | i, rtlefuse-> | ||
165 | eeprom_chnlarea_txpwr_cck[rf_path][i])); | ||
166 | for (rf_path = 0; rf_path < 2; rf_path++) | ||
167 | for (i = 0; i < 3; i++) | ||
168 | RTPRINT(rtlpriv, FINIT, INIT_EEPROM, | ||
169 | ("RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", | ||
170 | rf_path, i, | ||
171 | rtlefuse-> | ||
172 | eeprom_chnlarea_txpwr_ht40_1s[rf_path][i])); | ||
173 | for (rf_path = 0; rf_path < 2; rf_path++) | ||
174 | for (i = 0; i < 3; i++) | ||
175 | RTPRINT(rtlpriv, FINIT, INIT_EEPROM, | ||
176 | ("RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", | ||
177 | rf_path, i, | ||
178 | rtlefuse-> | ||
179 | eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path] | ||
180 | [i])); | ||
181 | for (rf_path = 0; rf_path < 2; rf_path++) { | ||
182 | for (i = 0; i < 14; i++) { | ||
183 | index = _rtl92c_get_chnl_group((u8) i); | ||
184 | rtlefuse->txpwrlevel_cck[rf_path][i] = | ||
185 | rtlefuse->eeprom_chnlarea_txpwr_cck[rf_path][index]; | ||
186 | rtlefuse->txpwrlevel_ht40_1s[rf_path][i] = | ||
187 | rtlefuse-> | ||
188 | eeprom_chnlarea_txpwr_ht40_1s[rf_path][index]; | ||
189 | if ((rtlefuse-> | ||
190 | eeprom_chnlarea_txpwr_ht40_1s[rf_path][index] - | ||
191 | rtlefuse-> | ||
192 | eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][index]) | ||
193 | > 0) { | ||
194 | rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = | ||
195 | rtlefuse-> | ||
196 | eeprom_chnlarea_txpwr_ht40_1s[rf_path] | ||
197 | [index] - rtlefuse-> | ||
198 | eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path] | ||
199 | [index]; | ||
200 | } else { | ||
201 | rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 0; | ||
202 | } | ||
203 | } | ||
204 | for (i = 0; i < 14; i++) { | ||
205 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | ||
206 | ("RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = " | ||
207 | "[0x%x / 0x%x / 0x%x]\n", rf_path, i, | ||
208 | rtlefuse->txpwrlevel_cck[rf_path][i], | ||
209 | rtlefuse->txpwrlevel_ht40_1s[rf_path][i], | ||
210 | rtlefuse->txpwrlevel_ht40_2s[rf_path][i])); | ||
211 | } | ||
212 | } | ||
213 | for (i = 0; i < 3; i++) { | ||
214 | if (!autoload_fail) { | ||
215 | rtlefuse->eeprom_pwrlimit_ht40[i] = | ||
216 | hwinfo[EEPROM_TXPWR_GROUP + i]; | ||
217 | rtlefuse->eeprom_pwrlimit_ht20[i] = | ||
218 | hwinfo[EEPROM_TXPWR_GROUP + 3 + i]; | ||
219 | } else { | ||
220 | rtlefuse->eeprom_pwrlimit_ht40[i] = 0; | ||
221 | rtlefuse->eeprom_pwrlimit_ht20[i] = 0; | ||
222 | } | ||
223 | } | ||
224 | for (rf_path = 0; rf_path < 2; rf_path++) { | ||
225 | for (i = 0; i < 14; i++) { | ||
226 | index = _rtl92c_get_chnl_group((u8) i); | ||
227 | if (rf_path == RF90_PATH_A) { | ||
228 | rtlefuse->pwrgroup_ht20[rf_path][i] = | ||
229 | (rtlefuse->eeprom_pwrlimit_ht20[index] | ||
230 | & 0xf); | ||
231 | rtlefuse->pwrgroup_ht40[rf_path][i] = | ||
232 | (rtlefuse->eeprom_pwrlimit_ht40[index] | ||
233 | & 0xf); | ||
234 | } else if (rf_path == RF90_PATH_B) { | ||
235 | rtlefuse->pwrgroup_ht20[rf_path][i] = | ||
236 | ((rtlefuse->eeprom_pwrlimit_ht20[index] | ||
237 | & 0xf0) >> 4); | ||
238 | rtlefuse->pwrgroup_ht40[rf_path][i] = | ||
239 | ((rtlefuse->eeprom_pwrlimit_ht40[index] | ||
240 | & 0xf0) >> 4); | ||
241 | } | ||
242 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | ||
243 | ("RF-%d pwrgroup_ht20[%d] = 0x%x\n", | ||
244 | rf_path, i, | ||
245 | rtlefuse->pwrgroup_ht20[rf_path][i])); | ||
246 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | ||
247 | ("RF-%d pwrgroup_ht40[%d] = 0x%x\n", | ||
248 | rf_path, i, | ||
249 | rtlefuse->pwrgroup_ht40[rf_path][i])); | ||
250 | } | ||
251 | } | ||
252 | for (i = 0; i < 14; i++) { | ||
253 | index = _rtl92c_get_chnl_group((u8) i); | ||
254 | if (!autoload_fail) | ||
255 | tempval = hwinfo[EEPROM_TXPOWERHT20DIFF + index]; | ||
256 | else | ||
257 | tempval = EEPROM_DEFAULT_HT20_DIFF; | ||
258 | rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] = (tempval & 0xF); | ||
259 | rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] = | ||
260 | ((tempval >> 4) & 0xF); | ||
261 | if (rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] & BIT(3)) | ||
262 | rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] |= 0xF0; | ||
263 | if (rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] & BIT(3)) | ||
264 | rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] |= 0xF0; | ||
265 | index = _rtl92c_get_chnl_group((u8) i); | ||
266 | if (!autoload_fail) | ||
267 | tempval = hwinfo[EEPROM_TXPOWER_OFDMDIFF + index]; | ||
268 | else | ||
269 | tempval = EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF; | ||
270 | rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i] = (tempval & 0xF); | ||
271 | rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i] = | ||
272 | ((tempval >> 4) & 0xF); | ||
273 | } | ||
274 | rtlefuse->legacy_ht_txpowerdiff = | ||
275 | rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][7]; | ||
276 | for (i = 0; i < 14; i++) | ||
277 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | ||
278 | ("RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i, | ||
279 | rtlefuse->txpwr_ht20diff[RF90_PATH_A][i])); | ||
280 | for (i = 0; i < 14; i++) | ||
281 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | ||
282 | ("RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i, | ||
283 | rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i])); | ||
284 | for (i = 0; i < 14; i++) | ||
285 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | ||
286 | ("RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i, | ||
287 | rtlefuse->txpwr_ht20diff[RF90_PATH_B][i])); | ||
288 | for (i = 0; i < 14; i++) | ||
289 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | ||
290 | ("RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i, | ||
291 | rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i])); | ||
292 | if (!autoload_fail) | ||
293 | rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7); | ||
294 | else | ||
295 | rtlefuse->eeprom_regulatory = 0; | ||
296 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | ||
297 | ("eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory)); | ||
298 | if (!autoload_fail) { | ||
299 | rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A]; | ||
300 | rtlefuse->eeprom_tssi[RF90_PATH_B] = hwinfo[EEPROM_TSSI_B]; | ||
301 | } else { | ||
302 | rtlefuse->eeprom_tssi[RF90_PATH_A] = EEPROM_DEFAULT_TSSI; | ||
303 | rtlefuse->eeprom_tssi[RF90_PATH_B] = EEPROM_DEFAULT_TSSI; | ||
304 | } | ||
305 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | ||
306 | ("TSSI_A = 0x%x, TSSI_B = 0x%x\n", | ||
307 | rtlefuse->eeprom_tssi[RF90_PATH_A], | ||
308 | rtlefuse->eeprom_tssi[RF90_PATH_B])); | ||
309 | if (!autoload_fail) | ||
310 | tempval = hwinfo[EEPROM_THERMAL_METER]; | ||
311 | else | ||
312 | tempval = EEPROM_DEFAULT_THERMALMETER; | ||
313 | rtlefuse->eeprom_thermalmeter = (tempval & 0x1f); | ||
314 | if (rtlefuse->eeprom_thermalmeter < 0x06 || | ||
315 | rtlefuse->eeprom_thermalmeter > 0x1c) | ||
316 | rtlefuse->eeprom_thermalmeter = 0x12; | ||
317 | if (rtlefuse->eeprom_thermalmeter == 0x1f || autoload_fail) | ||
318 | rtlefuse->apk_thermalmeterignore = true; | ||
319 | rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; | ||
320 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | ||
321 | ("thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter)); | ||
322 | } | ||
323 | |||
324 | static void _rtl92cu_read_board_type(struct ieee80211_hw *hw, u8 *contents) | ||
325 | { | ||
326 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
327 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
328 | u8 boardType; | ||
329 | |||
330 | if (IS_NORMAL_CHIP(rtlhal->version)) { | ||
331 | boardType = ((contents[EEPROM_RF_OPT1]) & | ||
332 | BOARD_TYPE_NORMAL_MASK) >> 5; /*bit[7:5]*/ | ||
333 | } else { | ||
334 | boardType = contents[EEPROM_RF_OPT4]; | ||
335 | boardType &= BOARD_TYPE_TEST_MASK; | ||
336 | } | ||
337 | rtlefuse->board_type = boardType; | ||
338 | if (IS_HIGHT_PA(rtlefuse->board_type)) | ||
339 | rtlefuse->external_pa = 1; | ||
340 | printk(KERN_INFO "rtl8192cu: Board Type %x\n", rtlefuse->board_type); | ||
341 | |||
342 | #ifdef CONFIG_ANTENNA_DIVERSITY | ||
343 | /* Antenna Diversity setting. */ | ||
344 | if (registry_par->antdiv_cfg == 2) /* 2: From Efuse */ | ||
345 | rtl_efuse->antenna_cfg = (contents[EEPROM_RF_OPT1]&0x18)>>3; | ||
346 | else | ||
347 | rtl_efuse->antenna_cfg = registry_par->antdiv_cfg; /* 0:OFF, */ | ||
348 | |||
349 | printk(KERN_INFO "rtl8192cu: Antenna Config %x\n", | ||
350 | rtl_efuse->antenna_cfg); | ||
351 | #endif | ||
352 | } | ||
353 | |||
354 | #ifdef CONFIG_BT_COEXIST | ||
355 | static void _update_bt_param(_adapter *padapter) | ||
356 | { | ||
357 | struct btcoexist_priv *pbtpriv = &(padapter->halpriv.bt_coexist); | ||
358 | struct registry_priv *registry_par = &padapter->registrypriv; | ||
359 | if (2 != registry_par->bt_iso) { | ||
360 | /* 0:Low, 1:High, 2:From Efuse */ | ||
361 | pbtpriv->BT_Ant_isolation = registry_par->bt_iso; | ||
362 | } | ||
363 | if (registry_par->bt_sco == 1) { | ||
364 | /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter, 4.Busy, | ||
365 | * 5.OtherBusy */ | ||
366 | pbtpriv->BT_Service = BT_OtherAction; | ||
367 | } else if (registry_par->bt_sco == 2) { | ||
368 | pbtpriv->BT_Service = BT_SCO; | ||
369 | } else if (registry_par->bt_sco == 4) { | ||
370 | pbtpriv->BT_Service = BT_Busy; | ||
371 | } else if (registry_par->bt_sco == 5) { | ||
372 | pbtpriv->BT_Service = BT_OtherBusy; | ||
373 | } else { | ||
374 | pbtpriv->BT_Service = BT_Idle; | ||
375 | } | ||
376 | pbtpriv->BT_Ampdu = registry_par->bt_ampdu; | ||
377 | pbtpriv->bCOBT = _TRUE; | ||
378 | pbtpriv->BtEdcaUL = 0; | ||
379 | pbtpriv->BtEdcaDL = 0; | ||
380 | pbtpriv->BtRssiState = 0xff; | ||
381 | pbtpriv->bInitSet = _FALSE; | ||
382 | pbtpriv->bBTBusyTraffic = _FALSE; | ||
383 | pbtpriv->bBTTrafficModeSet = _FALSE; | ||
384 | pbtpriv->bBTNonTrafficModeSet = _FALSE; | ||
385 | pbtpriv->CurrentState = 0; | ||
386 | pbtpriv->PreviousState = 0; | ||
387 | printk(KERN_INFO "rtl8192cu: BT Coexistance = %s\n", | ||
388 | (pbtpriv->BT_Coexist == _TRUE) ? "enable" : "disable"); | ||
389 | if (pbtpriv->BT_Coexist) { | ||
390 | if (pbtpriv->BT_Ant_Num == Ant_x2) | ||
391 | printk(KERN_INFO "rtl8192cu: BlueTooth BT_" | ||
392 | "Ant_Num = Antx2\n"); | ||
393 | else if (pbtpriv->BT_Ant_Num == Ant_x1) | ||
394 | printk(KERN_INFO "rtl8192cu: BlueTooth BT_" | ||
395 | "Ant_Num = Antx1\n"); | ||
396 | switch (pbtpriv->BT_CoexistType) { | ||
397 | case BT_2Wire: | ||
398 | printk(KERN_INFO "rtl8192cu: BlueTooth BT_" | ||
399 | "CoexistType = BT_2Wire\n"); | ||
400 | break; | ||
401 | case BT_ISSC_3Wire: | ||
402 | printk(KERN_INFO "rtl8192cu: BlueTooth BT_" | ||
403 | "CoexistType = BT_ISSC_3Wire\n"); | ||
404 | break; | ||
405 | case BT_Accel: | ||
406 | printk(KERN_INFO "rtl8192cu: BlueTooth BT_" | ||
407 | "CoexistType = BT_Accel\n"); | ||
408 | break; | ||
409 | case BT_CSR_BC4: | ||
410 | printk(KERN_INFO "rtl8192cu: BlueTooth BT_" | ||
411 | "CoexistType = BT_CSR_BC4\n"); | ||
412 | break; | ||
413 | case BT_CSR_BC8: | ||
414 | printk(KERN_INFO "rtl8192cu: BlueTooth BT_" | ||
415 | "CoexistType = BT_CSR_BC8\n"); | ||
416 | break; | ||
417 | case BT_RTL8756: | ||
418 | printk(KERN_INFO "rtl8192cu: BlueTooth BT_" | ||
419 | "CoexistType = BT_RTL8756\n"); | ||
420 | break; | ||
421 | default: | ||
422 | printk(KERN_INFO "rtl8192cu: BlueTooth BT_" | ||
423 | "CoexistType = Unknown\n"); | ||
424 | break; | ||
425 | } | ||
426 | printk(KERN_INFO "rtl8192cu: BlueTooth BT_Ant_isolation = %d\n", | ||
427 | pbtpriv->BT_Ant_isolation); | ||
428 | switch (pbtpriv->BT_Service) { | ||
429 | case BT_OtherAction: | ||
430 | printk(KERN_INFO "rtl8192cu: BlueTooth BT_Service = " | ||
431 | "BT_OtherAction\n"); | ||
432 | break; | ||
433 | case BT_SCO: | ||
434 | printk(KERN_INFO "rtl8192cu: BlueTooth BT_Service = " | ||
435 | "BT_SCO\n"); | ||
436 | break; | ||
437 | case BT_Busy: | ||
438 | printk(KERN_INFO "rtl8192cu: BlueTooth BT_Service = " | ||
439 | "BT_Busy\n"); | ||
440 | break; | ||
441 | case BT_OtherBusy: | ||
442 | printk(KERN_INFO "rtl8192cu: BlueTooth BT_Service = " | ||
443 | "BT_OtherBusy\n"); | ||
444 | break; | ||
445 | default: | ||
446 | printk(KERN_INFO "rtl8192cu: BlueTooth BT_Service = " | ||
447 | "BT_Idle\n"); | ||
448 | break; | ||
449 | } | ||
450 | printk(KERN_INFO "rtl8192cu: BT_RadioSharedType = 0x%x\n", | ||
451 | pbtpriv->BT_RadioSharedType); | ||
452 | } | ||
453 | } | ||
454 | |||
455 | #define GET_BT_COEXIST(priv) (&priv->bt_coexist) | ||
456 | |||
457 | static void _rtl92cu_read_bluetooth_coexistInfo(struct ieee80211_hw *hw, | ||
458 | u8 *contents, | ||
459 | bool bautoloadfailed); | ||
460 | { | ||
461 | HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); | ||
462 | bool isNormal = IS_NORMAL_CHIP(pHalData->VersionID); | ||
463 | struct btcoexist_priv *pbtpriv = &pHalData->bt_coexist; | ||
464 | u8 rf_opt4; | ||
465 | |||
466 | _rtw_memset(pbtpriv, 0, sizeof(struct btcoexist_priv)); | ||
467 | if (AutoloadFail) { | ||
468 | pbtpriv->BT_Coexist = _FALSE; | ||
469 | pbtpriv->BT_CoexistType = BT_2Wire; | ||
470 | pbtpriv->BT_Ant_Num = Ant_x2; | ||
471 | pbtpriv->BT_Ant_isolation = 0; | ||
472 | pbtpriv->BT_RadioSharedType = BT_Radio_Shared; | ||
473 | return; | ||
474 | } | ||
475 | if (isNormal) { | ||
476 | if (pHalData->BoardType == BOARD_USB_COMBO) | ||
477 | pbtpriv->BT_Coexist = _TRUE; | ||
478 | else | ||
479 | pbtpriv->BT_Coexist = ((PROMContent[EEPROM_RF_OPT3] & | ||
480 | 0x20) >> 5); /* bit[5] */ | ||
481 | rf_opt4 = PROMContent[EEPROM_RF_OPT4]; | ||
482 | pbtpriv->BT_CoexistType = ((rf_opt4&0xe)>>1); /* bit [3:1] */ | ||
483 | pbtpriv->BT_Ant_Num = (rf_opt4&0x1); /* bit [0] */ | ||
484 | pbtpriv->BT_Ant_isolation = ((rf_opt4&0x10)>>4); /* bit [4] */ | ||
485 | pbtpriv->BT_RadioSharedType = ((rf_opt4&0x20)>>5); /* bit [5] */ | ||
486 | } else { | ||
487 | pbtpriv->BT_Coexist = (PROMContent[EEPROM_RF_OPT4] >> 4) ? | ||
488 | _TRUE : _FALSE; | ||
489 | } | ||
490 | _update_bt_param(Adapter); | ||
491 | } | ||
492 | #endif | ||
493 | |||
494 | static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw) | ||
495 | { | ||
496 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
497 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
498 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
499 | u16 i, usvalue; | ||
500 | u8 hwinfo[HWSET_MAX_SIZE] = {0}; | ||
501 | u16 eeprom_id; | ||
502 | |||
503 | if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) { | ||
504 | rtl_efuse_shadow_map_update(hw); | ||
505 | memcpy((void *)hwinfo, | ||
506 | (void *)&rtlefuse->efuse_map[EFUSE_INIT_MAP][0], | ||
507 | HWSET_MAX_SIZE); | ||
508 | } else if (rtlefuse->epromtype == EEPROM_93C46) { | ||
509 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
510 | ("RTL819X Not boot from eeprom, check it !!")); | ||
511 | } | ||
512 | RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, ("MAP\n"), | ||
513 | hwinfo, HWSET_MAX_SIZE); | ||
514 | eeprom_id = *((u16 *)&hwinfo[0]); | ||
515 | if (eeprom_id != RTL8190_EEPROM_ID) { | ||
516 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
517 | ("EEPROM ID(%#x) is invalid!!\n", eeprom_id)); | ||
518 | rtlefuse->autoload_failflag = true; | ||
519 | } else { | ||
520 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); | ||
521 | rtlefuse->autoload_failflag = false; | ||
522 | } | ||
523 | if (rtlefuse->autoload_failflag == true) | ||
524 | return; | ||
525 | for (i = 0; i < 6; i += 2) { | ||
526 | usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i]; | ||
527 | *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue; | ||
528 | } | ||
529 | printk(KERN_INFO "rtl8192cu: MAC address: %pM\n", rtlefuse->dev_addr); | ||
530 | _rtl92cu_read_txpower_info_from_hwpg(hw, | ||
531 | rtlefuse->autoload_failflag, hwinfo); | ||
532 | rtlefuse->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID]; | ||
533 | rtlefuse->eeprom_did = *(u16 *)&hwinfo[EEPROM_DID]; | ||
534 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
535 | (" VID = 0x%02x PID = 0x%02x\n", | ||
536 | rtlefuse->eeprom_vid, rtlefuse->eeprom_did)); | ||
537 | rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; | ||
538 | rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; | ||
539 | rtlefuse->txpwr_fromeprom = true; | ||
540 | rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; | ||
541 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, | ||
542 | ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid)); | ||
543 | if (rtlhal->oem_id == RT_CID_DEFAULT) { | ||
544 | switch (rtlefuse->eeprom_oemid) { | ||
545 | case EEPROM_CID_DEFAULT: | ||
546 | if (rtlefuse->eeprom_did == 0x8176) { | ||
547 | if ((rtlefuse->eeprom_svid == 0x103C && | ||
548 | rtlefuse->eeprom_smid == 0x1629)) | ||
549 | rtlhal->oem_id = RT_CID_819x_HP; | ||
550 | else | ||
551 | rtlhal->oem_id = RT_CID_DEFAULT; | ||
552 | } else { | ||
553 | rtlhal->oem_id = RT_CID_DEFAULT; | ||
554 | } | ||
555 | break; | ||
556 | case EEPROM_CID_TOSHIBA: | ||
557 | rtlhal->oem_id = RT_CID_TOSHIBA; | ||
558 | break; | ||
559 | case EEPROM_CID_QMI: | ||
560 | rtlhal->oem_id = RT_CID_819x_QMI; | ||
561 | break; | ||
562 | case EEPROM_CID_WHQL: | ||
563 | default: | ||
564 | rtlhal->oem_id = RT_CID_DEFAULT; | ||
565 | break; | ||
566 | } | ||
567 | } | ||
568 | _rtl92cu_read_board_type(hw, hwinfo); | ||
569 | #ifdef CONFIG_BT_COEXIST | ||
570 | _rtl92cu_read_bluetooth_coexistInfo(hw, hwinfo, | ||
571 | rtlefuse->autoload_failflag); | ||
572 | #endif | ||
573 | } | ||
574 | |||
575 | static void _rtl92cu_hal_customized_behavior(struct ieee80211_hw *hw) | ||
576 | { | ||
577 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
578 | struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw); | ||
579 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
580 | |||
581 | switch (rtlhal->oem_id) { | ||
582 | case RT_CID_819x_HP: | ||
583 | usb_priv->ledctl.led_opendrain = true; | ||
584 | break; | ||
585 | case RT_CID_819x_Lenovo: | ||
586 | case RT_CID_DEFAULT: | ||
587 | case RT_CID_TOSHIBA: | ||
588 | case RT_CID_CCX: | ||
589 | case RT_CID_819x_Acer: | ||
590 | case RT_CID_WHQL: | ||
591 | default: | ||
592 | break; | ||
593 | } | ||
594 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
595 | ("RT Customized ID: 0x%02X\n", rtlhal->oem_id)); | ||
596 | } | ||
597 | |||
598 | void rtl92cu_read_eeprom_info(struct ieee80211_hw *hw) | ||
599 | { | ||
600 | |||
601 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
602 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
603 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
604 | u8 tmp_u1b; | ||
605 | |||
606 | if (!IS_NORMAL_CHIP(rtlhal->version)) | ||
607 | return; | ||
608 | tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); | ||
609 | rtlefuse->epromtype = (tmp_u1b & EEPROMSEL) ? | ||
610 | EEPROM_93C46 : EEPROM_BOOT_EFUSE; | ||
611 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from %s\n", | ||
612 | (tmp_u1b & EEPROMSEL) ? "EERROM" : "EFUSE")); | ||
613 | rtlefuse->autoload_failflag = (tmp_u1b & EEPROM_EN) ? false : true; | ||
614 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload %s\n", | ||
615 | (tmp_u1b & EEPROM_EN) ? "OK!!" : "ERR!!")); | ||
616 | _rtl92cu_read_adapter_info(hw); | ||
617 | _rtl92cu_hal_customized_behavior(hw); | ||
618 | return; | ||
619 | } | ||
620 | |||
621 | static int _rtl92cu_init_power_on(struct ieee80211_hw *hw) | ||
622 | { | ||
623 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
624 | int status = 0; | ||
625 | u16 value16; | ||
626 | u8 value8; | ||
627 | /* polling autoload done. */ | ||
628 | u32 pollingCount = 0; | ||
629 | |||
630 | do { | ||
631 | if (rtl_read_byte(rtlpriv, REG_APS_FSMCO) & PFM_ALDN) { | ||
632 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
633 | ("Autoload Done!\n")); | ||
634 | break; | ||
635 | } | ||
636 | if (pollingCount++ > 100) { | ||
637 | RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, | ||
638 | ("Failed to polling REG_APS_FSMCO[PFM_ALDN]" | ||
639 | " done!\n")); | ||
640 | return -ENODEV; | ||
641 | } | ||
642 | } while (true); | ||
643 | /* 0. RSV_CTRL 0x1C[7:0] = 0 unlock ISO/CLK/Power control register */ | ||
644 | rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0); | ||
645 | /* Power on when re-enter from IPS/Radio off/card disable */ | ||
646 | /* enable SPS into PWM mode */ | ||
647 | rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); | ||
648 | udelay(100); | ||
649 | value8 = rtl_read_byte(rtlpriv, REG_LDOV12D_CTRL); | ||
650 | if (0 == (value8 & LDV12_EN)) { | ||
651 | value8 |= LDV12_EN; | ||
652 | rtl_write_byte(rtlpriv, REG_LDOV12D_CTRL, value8); | ||
653 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
654 | (" power-on :REG_LDOV12D_CTRL Reg0x21:0x%02x.\n", | ||
655 | value8)); | ||
656 | udelay(100); | ||
657 | value8 = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL); | ||
658 | value8 &= ~ISO_MD2PP; | ||
659 | rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, value8); | ||
660 | } | ||
661 | /* auto enable WLAN */ | ||
662 | pollingCount = 0; | ||
663 | value16 = rtl_read_word(rtlpriv, REG_APS_FSMCO); | ||
664 | value16 |= APFM_ONMAC; | ||
665 | rtl_write_word(rtlpriv, REG_APS_FSMCO, value16); | ||
666 | do { | ||
667 | if (!(rtl_read_word(rtlpriv, REG_APS_FSMCO) & APFM_ONMAC)) { | ||
668 | printk(KERN_INFO "rtl8192cu: MAC auto ON okay!\n"); | ||
669 | break; | ||
670 | } | ||
671 | if (pollingCount++ > 100) { | ||
672 | RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, | ||
673 | ("Failed to polling REG_APS_FSMCO[APFM_ONMAC]" | ||
674 | " done!\n")); | ||
675 | return -ENODEV; | ||
676 | } | ||
677 | } while (true); | ||
678 | /* Enable Radio ,GPIO ,and LED function */ | ||
679 | rtl_write_word(rtlpriv, REG_APS_FSMCO, 0x0812); | ||
680 | /* release RF digital isolation */ | ||
681 | value16 = rtl_read_word(rtlpriv, REG_SYS_ISO_CTRL); | ||
682 | value16 &= ~ISO_DIOR; | ||
683 | rtl_write_word(rtlpriv, REG_SYS_ISO_CTRL, value16); | ||
684 | /* Reconsider when to do this operation after asking HWSD. */ | ||
685 | pollingCount = 0; | ||
686 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, (rtl_read_byte(rtlpriv, | ||
687 | REG_APSD_CTRL) & ~BIT(6))); | ||
688 | do { | ||
689 | pollingCount++; | ||
690 | } while ((pollingCount < 200) && | ||
691 | (rtl_read_byte(rtlpriv, REG_APSD_CTRL) & BIT(7))); | ||
692 | /* Enable MAC DMA/WMAC/SCHEDULE/SEC block */ | ||
693 | value16 = rtl_read_word(rtlpriv, REG_CR); | ||
694 | value16 |= (HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN | | ||
695 | PROTOCOL_EN | SCHEDULE_EN | MACTXEN | MACRXEN | ENSEC); | ||
696 | rtl_write_word(rtlpriv, REG_CR, value16); | ||
697 | return status; | ||
698 | } | ||
699 | |||
700 | static void _rtl92cu_init_queue_reserved_page(struct ieee80211_hw *hw, | ||
701 | bool wmm_enable, | ||
702 | u8 out_ep_num, | ||
703 | u8 queue_sel) | ||
704 | { | ||
705 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
706 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
707 | bool isChipN = IS_NORMAL_CHIP(rtlhal->version); | ||
708 | u32 outEPNum = (u32)out_ep_num; | ||
709 | u32 numHQ = 0; | ||
710 | u32 numLQ = 0; | ||
711 | u32 numNQ = 0; | ||
712 | u32 numPubQ; | ||
713 | u32 value32; | ||
714 | u8 value8; | ||
715 | u32 txQPageNum, txQPageUnit, txQRemainPage; | ||
716 | |||
717 | if (!wmm_enable) { | ||
718 | numPubQ = (isChipN) ? CHIP_B_PAGE_NUM_PUBQ : | ||
719 | CHIP_A_PAGE_NUM_PUBQ; | ||
720 | txQPageNum = TX_TOTAL_PAGE_NUMBER - numPubQ; | ||
721 | |||
722 | txQPageUnit = txQPageNum/outEPNum; | ||
723 | txQRemainPage = txQPageNum % outEPNum; | ||
724 | if (queue_sel & TX_SELE_HQ) | ||
725 | numHQ = txQPageUnit; | ||
726 | if (queue_sel & TX_SELE_LQ) | ||
727 | numLQ = txQPageUnit; | ||
728 | /* HIGH priority queue always present in the configuration of | ||
729 | * 2 out-ep. Remainder pages have assigned to High queue */ | ||
730 | if ((outEPNum > 1) && (txQRemainPage)) | ||
731 | numHQ += txQRemainPage; | ||
732 | /* NOTE: This step done before writting REG_RQPN. */ | ||
733 | if (isChipN) { | ||
734 | if (queue_sel & TX_SELE_NQ) | ||
735 | numNQ = txQPageUnit; | ||
736 | value8 = (u8)_NPQ(numNQ); | ||
737 | rtl_write_byte(rtlpriv, REG_RQPN_NPQ, value8); | ||
738 | } | ||
739 | } else { | ||
740 | /* for WMM ,number of out-ep must more than or equal to 2! */ | ||
741 | numPubQ = isChipN ? WMM_CHIP_B_PAGE_NUM_PUBQ : | ||
742 | WMM_CHIP_A_PAGE_NUM_PUBQ; | ||
743 | if (queue_sel & TX_SELE_HQ) { | ||
744 | numHQ = isChipN ? WMM_CHIP_B_PAGE_NUM_HPQ : | ||
745 | WMM_CHIP_A_PAGE_NUM_HPQ; | ||
746 | } | ||
747 | if (queue_sel & TX_SELE_LQ) { | ||
748 | numLQ = isChipN ? WMM_CHIP_B_PAGE_NUM_LPQ : | ||
749 | WMM_CHIP_A_PAGE_NUM_LPQ; | ||
750 | } | ||
751 | /* NOTE: This step done before writting REG_RQPN. */ | ||
752 | if (isChipN) { | ||
753 | if (queue_sel & TX_SELE_NQ) | ||
754 | numNQ = WMM_CHIP_B_PAGE_NUM_NPQ; | ||
755 | value8 = (u8)_NPQ(numNQ); | ||
756 | rtl_write_byte(rtlpriv, REG_RQPN_NPQ, value8); | ||
757 | } | ||
758 | } | ||
759 | /* TX DMA */ | ||
760 | value32 = _HPQ(numHQ) | _LPQ(numLQ) | _PUBQ(numPubQ) | LD_RQPN; | ||
761 | rtl_write_dword(rtlpriv, REG_RQPN, value32); | ||
762 | } | ||
763 | |||
764 | static void _rtl92c_init_trx_buffer(struct ieee80211_hw *hw, bool wmm_enable) | ||
765 | { | ||
766 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
767 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
768 | u8 txpktbuf_bndy; | ||
769 | u8 value8; | ||
770 | |||
771 | if (!wmm_enable) | ||
772 | txpktbuf_bndy = TX_PAGE_BOUNDARY; | ||
773 | else /* for WMM */ | ||
774 | txpktbuf_bndy = (IS_NORMAL_CHIP(rtlhal->version)) | ||
775 | ? WMM_CHIP_B_TX_PAGE_BOUNDARY | ||
776 | : WMM_CHIP_A_TX_PAGE_BOUNDARY; | ||
777 | rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy); | ||
778 | rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy); | ||
779 | rtl_write_byte(rtlpriv, REG_TXPKTBUF_WMAC_LBK_BF_HD, txpktbuf_bndy); | ||
780 | rtl_write_byte(rtlpriv, REG_TRXFF_BNDY, txpktbuf_bndy); | ||
781 | rtl_write_byte(rtlpriv, REG_TDECTRL+1, txpktbuf_bndy); | ||
782 | rtl_write_word(rtlpriv, (REG_TRXFF_BNDY + 2), 0x27FF); | ||
783 | value8 = _PSRX(RX_PAGE_SIZE_REG_VALUE) | _PSTX(PBP_128); | ||
784 | rtl_write_byte(rtlpriv, REG_PBP, value8); | ||
785 | } | ||
786 | |||
787 | static void _rtl92c_init_chipN_reg_priority(struct ieee80211_hw *hw, u16 beQ, | ||
788 | u16 bkQ, u16 viQ, u16 voQ, | ||
789 | u16 mgtQ, u16 hiQ) | ||
790 | { | ||
791 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
792 | u16 value16 = (rtl_read_word(rtlpriv, REG_TRXDMA_CTRL) & 0x7); | ||
793 | |||
794 | value16 |= _TXDMA_BEQ_MAP(beQ) | _TXDMA_BKQ_MAP(bkQ) | | ||
795 | _TXDMA_VIQ_MAP(viQ) | _TXDMA_VOQ_MAP(voQ) | | ||
796 | _TXDMA_MGQ_MAP(mgtQ) | _TXDMA_HIQ_MAP(hiQ); | ||
797 | rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, value16); | ||
798 | } | ||
799 | |||
800 | static void _rtl92cu_init_chipN_one_out_ep_priority(struct ieee80211_hw *hw, | ||
801 | bool wmm_enable, | ||
802 | u8 queue_sel) | ||
803 | { | ||
804 | u16 uninitialized_var(value); | ||
805 | |||
806 | switch (queue_sel) { | ||
807 | case TX_SELE_HQ: | ||
808 | value = QUEUE_HIGH; | ||
809 | break; | ||
810 | case TX_SELE_LQ: | ||
811 | value = QUEUE_LOW; | ||
812 | break; | ||
813 | case TX_SELE_NQ: | ||
814 | value = QUEUE_NORMAL; | ||
815 | break; | ||
816 | default: | ||
817 | WARN_ON(1); /* Shall not reach here! */ | ||
818 | break; | ||
819 | } | ||
820 | _rtl92c_init_chipN_reg_priority(hw, value, value, value, value, | ||
821 | value, value); | ||
822 | printk(KERN_INFO "rtl8192cu: Tx queue select: 0x%02x\n", queue_sel); | ||
823 | } | ||
824 | |||
825 | static void _rtl92cu_init_chipN_two_out_ep_priority(struct ieee80211_hw *hw, | ||
826 | bool wmm_enable, | ||
827 | u8 queue_sel) | ||
828 | { | ||
829 | u16 beQ, bkQ, viQ, voQ, mgtQ, hiQ; | ||
830 | u16 uninitialized_var(valueHi); | ||
831 | u16 uninitialized_var(valueLow); | ||
832 | |||
833 | switch (queue_sel) { | ||
834 | case (TX_SELE_HQ | TX_SELE_LQ): | ||
835 | valueHi = QUEUE_HIGH; | ||
836 | valueLow = QUEUE_LOW; | ||
837 | break; | ||
838 | case (TX_SELE_NQ | TX_SELE_LQ): | ||
839 | valueHi = QUEUE_NORMAL; | ||
840 | valueLow = QUEUE_LOW; | ||
841 | break; | ||
842 | case (TX_SELE_HQ | TX_SELE_NQ): | ||
843 | valueHi = QUEUE_HIGH; | ||
844 | valueLow = QUEUE_NORMAL; | ||
845 | break; | ||
846 | default: | ||
847 | WARN_ON(1); | ||
848 | break; | ||
849 | } | ||
850 | if (!wmm_enable) { | ||
851 | beQ = valueLow; | ||
852 | bkQ = valueLow; | ||
853 | viQ = valueHi; | ||
854 | voQ = valueHi; | ||
855 | mgtQ = valueHi; | ||
856 | hiQ = valueHi; | ||
857 | } else {/* for WMM ,CONFIG_OUT_EP_WIFI_MODE */ | ||
858 | beQ = valueHi; | ||
859 | bkQ = valueLow; | ||
860 | viQ = valueLow; | ||
861 | voQ = valueHi; | ||
862 | mgtQ = valueHi; | ||
863 | hiQ = valueHi; | ||
864 | } | ||
865 | _rtl92c_init_chipN_reg_priority(hw, beQ, bkQ, viQ, voQ, mgtQ, hiQ); | ||
866 | printk(KERN_INFO "rtl8192cu: Tx queue select: 0x%02x\n", queue_sel); | ||
867 | } | ||
868 | |||
869 | static void _rtl92cu_init_chipN_three_out_ep_priority(struct ieee80211_hw *hw, | ||
870 | bool wmm_enable, | ||
871 | u8 queue_sel) | ||
872 | { | ||
873 | u16 beQ, bkQ, viQ, voQ, mgtQ, hiQ; | ||
874 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
875 | |||
876 | if (!wmm_enable) { /* typical setting */ | ||
877 | beQ = QUEUE_LOW; | ||
878 | bkQ = QUEUE_LOW; | ||
879 | viQ = QUEUE_NORMAL; | ||
880 | voQ = QUEUE_HIGH; | ||
881 | mgtQ = QUEUE_HIGH; | ||
882 | hiQ = QUEUE_HIGH; | ||
883 | } else { /* for WMM */ | ||
884 | beQ = QUEUE_LOW; | ||
885 | bkQ = QUEUE_NORMAL; | ||
886 | viQ = QUEUE_NORMAL; | ||
887 | voQ = QUEUE_HIGH; | ||
888 | mgtQ = QUEUE_HIGH; | ||
889 | hiQ = QUEUE_HIGH; | ||
890 | } | ||
891 | _rtl92c_init_chipN_reg_priority(hw, beQ, bkQ, viQ, voQ, mgtQ, hiQ); | ||
892 | RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, | ||
893 | ("Tx queue select :0x%02x..\n", queue_sel)); | ||
894 | } | ||
895 | |||
896 | static void _rtl92cu_init_chipN_queue_priority(struct ieee80211_hw *hw, | ||
897 | bool wmm_enable, | ||
898 | u8 out_ep_num, | ||
899 | u8 queue_sel) | ||
900 | { | ||
901 | switch (out_ep_num) { | ||
902 | case 1: | ||
903 | _rtl92cu_init_chipN_one_out_ep_priority(hw, wmm_enable, | ||
904 | queue_sel); | ||
905 | break; | ||
906 | case 2: | ||
907 | _rtl92cu_init_chipN_two_out_ep_priority(hw, wmm_enable, | ||
908 | queue_sel); | ||
909 | break; | ||
910 | case 3: | ||
911 | _rtl92cu_init_chipN_three_out_ep_priority(hw, wmm_enable, | ||
912 | queue_sel); | ||
913 | break; | ||
914 | default: | ||
915 | WARN_ON(1); /* Shall not reach here! */ | ||
916 | break; | ||
917 | } | ||
918 | } | ||
919 | |||
920 | static void _rtl92cu_init_chipT_queue_priority(struct ieee80211_hw *hw, | ||
921 | bool wmm_enable, | ||
922 | u8 out_ep_num, | ||
923 | u8 queue_sel) | ||
924 | { | ||
925 | u8 hq_sele; | ||
926 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
927 | |||
928 | switch (out_ep_num) { | ||
929 | case 2: /* (TX_SELE_HQ|TX_SELE_LQ) */ | ||
930 | if (!wmm_enable) /* typical setting */ | ||
931 | hq_sele = HQSEL_VOQ | HQSEL_VIQ | HQSEL_MGTQ | | ||
932 | HQSEL_HIQ; | ||
933 | else /* for WMM */ | ||
934 | hq_sele = HQSEL_VOQ | HQSEL_BEQ | HQSEL_MGTQ | | ||
935 | HQSEL_HIQ; | ||
936 | break; | ||
937 | case 1: | ||
938 | if (TX_SELE_LQ == queue_sel) { | ||
939 | /* map all endpoint to Low queue */ | ||
940 | hq_sele = 0; | ||
941 | } else if (TX_SELE_HQ == queue_sel) { | ||
942 | /* map all endpoint to High queue */ | ||
943 | hq_sele = HQSEL_VOQ | HQSEL_VIQ | HQSEL_BEQ | | ||
944 | HQSEL_BKQ | HQSEL_MGTQ | HQSEL_HIQ; | ||
945 | } | ||
946 | break; | ||
947 | default: | ||
948 | WARN_ON(1); /* Shall not reach here! */ | ||
949 | break; | ||
950 | } | ||
951 | rtl_write_byte(rtlpriv, (REG_TRXDMA_CTRL+1), hq_sele); | ||
952 | RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, | ||
953 | ("Tx queue select :0x%02x..\n", hq_sele)); | ||
954 | } | ||
955 | |||
956 | static void _rtl92cu_init_queue_priority(struct ieee80211_hw *hw, | ||
957 | bool wmm_enable, | ||
958 | u8 out_ep_num, | ||
959 | u8 queue_sel) | ||
960 | { | ||
961 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
962 | if (IS_NORMAL_CHIP(rtlhal->version)) | ||
963 | _rtl92cu_init_chipN_queue_priority(hw, wmm_enable, out_ep_num, | ||
964 | queue_sel); | ||
965 | else | ||
966 | _rtl92cu_init_chipT_queue_priority(hw, wmm_enable, out_ep_num, | ||
967 | queue_sel); | ||
968 | } | ||
969 | |||
970 | static void _rtl92cu_init_usb_aggregation(struct ieee80211_hw *hw) | ||
971 | { | ||
972 | } | ||
973 | |||
974 | static void _rtl92cu_init_wmac_setting(struct ieee80211_hw *hw) | ||
975 | { | ||
976 | u16 value16; | ||
977 | |||
978 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
979 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
980 | |||
981 | mac->rx_conf = (RCR_APM | RCR_AM | RCR_ADF | RCR_AB | RCR_APP_FCS | | ||
982 | RCR_APP_ICV | RCR_AMF | RCR_HTC_LOC_CTRL | | ||
983 | RCR_APP_MIC | RCR_APP_PHYSTS | RCR_ACRC32); | ||
984 | rtl_write_dword(rtlpriv, REG_RCR, mac->rx_conf); | ||
985 | /* Accept all multicast address */ | ||
986 | rtl_write_dword(rtlpriv, REG_MAR, 0xFFFFFFFF); | ||
987 | rtl_write_dword(rtlpriv, REG_MAR + 4, 0xFFFFFFFF); | ||
988 | /* Accept all management frames */ | ||
989 | value16 = 0xFFFF; | ||
990 | rtl92c_set_mgt_filter(hw, value16); | ||
991 | /* Reject all control frame - default value is 0 */ | ||
992 | rtl92c_set_ctrl_filter(hw, 0x0); | ||
993 | /* Accept all data frames */ | ||
994 | value16 = 0xFFFF; | ||
995 | rtl92c_set_data_filter(hw, value16); | ||
996 | } | ||
997 | |||
998 | static int _rtl92cu_init_mac(struct ieee80211_hw *hw) | ||
999 | { | ||
1000 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1001 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1002 | struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw); | ||
1003 | struct rtl_usb *rtlusb = rtl_usbdev(usb_priv); | ||
1004 | int err = 0; | ||
1005 | u32 boundary = 0; | ||
1006 | u8 wmm_enable = false; /* TODO */ | ||
1007 | u8 out_ep_nums = rtlusb->out_ep_nums; | ||
1008 | u8 queue_sel = rtlusb->out_queue_sel; | ||
1009 | err = _rtl92cu_init_power_on(hw); | ||
1010 | |||
1011 | if (err) { | ||
1012 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
1013 | ("Failed to init power on!\n")); | ||
1014 | return err; | ||
1015 | } | ||
1016 | if (!wmm_enable) { | ||
1017 | boundary = TX_PAGE_BOUNDARY; | ||
1018 | } else { /* for WMM */ | ||
1019 | boundary = (IS_NORMAL_CHIP(rtlhal->version)) | ||
1020 | ? WMM_CHIP_B_TX_PAGE_BOUNDARY | ||
1021 | : WMM_CHIP_A_TX_PAGE_BOUNDARY; | ||
1022 | } | ||
1023 | if (false == rtl92c_init_llt_table(hw, boundary)) { | ||
1024 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
1025 | ("Failed to init LLT Table!\n")); | ||
1026 | return -EINVAL; | ||
1027 | } | ||
1028 | _rtl92cu_init_queue_reserved_page(hw, wmm_enable, out_ep_nums, | ||
1029 | queue_sel); | ||
1030 | _rtl92c_init_trx_buffer(hw, wmm_enable); | ||
1031 | _rtl92cu_init_queue_priority(hw, wmm_enable, out_ep_nums, | ||
1032 | queue_sel); | ||
1033 | /* Get Rx PHY status in order to report RSSI and others. */ | ||
1034 | rtl92c_init_driver_info_size(hw, RTL92C_DRIVER_INFO_SIZE); | ||
1035 | rtl92c_init_interrupt(hw); | ||
1036 | rtl92c_init_network_type(hw); | ||
1037 | _rtl92cu_init_wmac_setting(hw); | ||
1038 | rtl92c_init_adaptive_ctrl(hw); | ||
1039 | rtl92c_init_edca(hw); | ||
1040 | rtl92c_init_rate_fallback(hw); | ||
1041 | rtl92c_init_retry_function(hw); | ||
1042 | _rtl92cu_init_usb_aggregation(hw); | ||
1043 | rtlpriv->cfg->ops->set_bw_mode(hw, NL80211_CHAN_HT20); | ||
1044 | rtl92c_set_min_space(hw, IS_92C_SERIAL(rtlhal->version)); | ||
1045 | rtl92c_init_beacon_parameters(hw, rtlhal->version); | ||
1046 | rtl92c_init_ampdu_aggregation(hw); | ||
1047 | rtl92c_init_beacon_max_error(hw, true); | ||
1048 | return err; | ||
1049 | } | ||
1050 | |||
1051 | void rtl92cu_enable_hw_security_config(struct ieee80211_hw *hw) | ||
1052 | { | ||
1053 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1054 | u8 sec_reg_value = 0x0; | ||
1055 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | ||
1056 | |||
1057 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, | ||
1058 | ("PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", | ||
1059 | rtlpriv->sec.pairwise_enc_algorithm, | ||
1060 | rtlpriv->sec.group_enc_algorithm)); | ||
1061 | if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { | ||
1062 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | ||
1063 | ("not open sw encryption\n")); | ||
1064 | return; | ||
1065 | } | ||
1066 | sec_reg_value = SCR_TxEncEnable | SCR_RxDecEnable; | ||
1067 | if (rtlpriv->sec.use_defaultkey) { | ||
1068 | sec_reg_value |= SCR_TxUseDK; | ||
1069 | sec_reg_value |= SCR_RxUseDK; | ||
1070 | } | ||
1071 | if (IS_NORMAL_CHIP(rtlhal->version)) | ||
1072 | sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK); | ||
1073 | rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); | ||
1074 | RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, | ||
1075 | ("The SECR-value %x\n", sec_reg_value)); | ||
1076 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); | ||
1077 | } | ||
1078 | |||
1079 | static void _rtl92cu_hw_configure(struct ieee80211_hw *hw) | ||
1080 | { | ||
1081 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1082 | struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); | ||
1083 | |||
1084 | /* To Fix MAC loopback mode fail. */ | ||
1085 | rtl_write_byte(rtlpriv, REG_LDOHCI12_CTRL, 0x0f); | ||
1086 | rtl_write_byte(rtlpriv, 0x15, 0xe9); | ||
1087 | /* HW SEQ CTRL */ | ||
1088 | /* set 0x0 to 0xFF by tynli. Default enable HW SEQ NUM. */ | ||
1089 | rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF); | ||
1090 | /* fixed USB interface interference issue */ | ||
1091 | rtl_write_byte(rtlpriv, 0xfe40, 0xe0); | ||
1092 | rtl_write_byte(rtlpriv, 0xfe41, 0x8d); | ||
1093 | rtl_write_byte(rtlpriv, 0xfe42, 0x80); | ||
1094 | rtlusb->reg_bcn_ctrl_val = 0x18; | ||
1095 | rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8)rtlusb->reg_bcn_ctrl_val); | ||
1096 | } | ||
1097 | |||
1098 | static void _InitPABias(struct ieee80211_hw *hw) | ||
1099 | { | ||
1100 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1101 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1102 | u8 pa_setting; | ||
1103 | |||
1104 | /* FIXED PA current issue */ | ||
1105 | pa_setting = efuse_read_1byte(hw, 0x1FA); | ||
1106 | if (!(pa_setting & BIT(0))) { | ||
1107 | rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0FFFFF, 0x0F406); | ||
1108 | rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0FFFFF, 0x4F406); | ||
1109 | rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0FFFFF, 0x8F406); | ||
1110 | rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0FFFFF, 0xCF406); | ||
1111 | } | ||
1112 | if (!(pa_setting & BIT(1)) && IS_NORMAL_CHIP(rtlhal->version) && | ||
1113 | IS_92C_SERIAL(rtlhal->version)) { | ||
1114 | rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0FFFFF, 0x0F406); | ||
1115 | rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0FFFFF, 0x4F406); | ||
1116 | rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0FFFFF, 0x8F406); | ||
1117 | rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0FFFFF, 0xCF406); | ||
1118 | } | ||
1119 | if (!(pa_setting & BIT(4))) { | ||
1120 | pa_setting = rtl_read_byte(rtlpriv, 0x16); | ||
1121 | pa_setting &= 0x0F; | ||
1122 | rtl_write_byte(rtlpriv, 0x16, pa_setting | 0x90); | ||
1123 | } | ||
1124 | } | ||
1125 | |||
1126 | static void _InitAntenna_Selection(struct ieee80211_hw *hw) | ||
1127 | { | ||
1128 | #ifdef CONFIG_ANTENNA_DIVERSITY | ||
1129 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1130 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1131 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1132 | |||
1133 | if (pHalData->AntDivCfg == 0) | ||
1134 | return; | ||
1135 | |||
1136 | if (rtlphy->rf_type == RF_1T1R) { | ||
1137 | rtl_write_dword(rtlpriv, REG_LEDCFG0, | ||
1138 | rtl_read_dword(rtlpriv, | ||
1139 | REG_LEDCFG0)|BIT(23)); | ||
1140 | rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01); | ||
1141 | if (rtl_get_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300) == | ||
1142 | Antenna_A) | ||
1143 | pHalData->CurAntenna = Antenna_A; | ||
1144 | else | ||
1145 | pHalData->CurAntenna = Antenna_B; | ||
1146 | } | ||
1147 | #endif | ||
1148 | } | ||
1149 | |||
1150 | static void _dump_registers(struct ieee80211_hw *hw) | ||
1151 | { | ||
1152 | } | ||
1153 | |||
1154 | static void _update_mac_setting(struct ieee80211_hw *hw) | ||
1155 | { | ||
1156 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1157 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
1158 | |||
1159 | mac->rx_conf = rtl_read_dword(rtlpriv, REG_RCR); | ||
1160 | mac->rx_mgt_filter = rtl_read_word(rtlpriv, REG_RXFLTMAP0); | ||
1161 | mac->rx_ctrl_filter = rtl_read_word(rtlpriv, REG_RXFLTMAP1); | ||
1162 | mac->rx_data_filter = rtl_read_word(rtlpriv, REG_RXFLTMAP2); | ||
1163 | } | ||
1164 | |||
1165 | int rtl92cu_hw_init(struct ieee80211_hw *hw) | ||
1166 | { | ||
1167 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1168 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1169 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
1170 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1171 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
1172 | int err = 0; | ||
1173 | static bool iqk_initialized; | ||
1174 | |||
1175 | rtlhal->hw_type = HARDWARE_TYPE_RTL8192CU; | ||
1176 | err = _rtl92cu_init_mac(hw); | ||
1177 | if (err) { | ||
1178 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("init mac failed!\n")); | ||
1179 | return err; | ||
1180 | } | ||
1181 | err = rtl92c_download_fw(hw); | ||
1182 | if (err) { | ||
1183 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | ||
1184 | ("Failed to download FW. Init HW without FW now..\n")); | ||
1185 | err = 1; | ||
1186 | rtlhal->fw_ready = false; | ||
1187 | return err; | ||
1188 | } else { | ||
1189 | rtlhal->fw_ready = true; | ||
1190 | } | ||
1191 | rtlhal->last_hmeboxnum = 0; /* h2c */ | ||
1192 | _rtl92cu_phy_param_tab_init(hw); | ||
1193 | rtl92c_phy_mac_config(hw); | ||
1194 | rtl92c_phy_bb_config(hw); | ||
1195 | rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; | ||
1196 | rtl92c_phy_rf_config(hw); | ||
1197 | if (IS_VENDOR_UMC_A_CUT(rtlhal->version) && | ||
1198 | !IS_92C_SERIAL(rtlhal->version)) { | ||
1199 | rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, 0x30255); | ||
1200 | rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G2, MASKDWORD, 0x50a00); | ||
1201 | } | ||
1202 | rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0, | ||
1203 | RF_CHNLBW, RFREG_OFFSET_MASK); | ||
1204 | rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1, | ||
1205 | RF_CHNLBW, RFREG_OFFSET_MASK); | ||
1206 | rtl92c_bb_block_on(hw); | ||
1207 | rtl_cam_reset_all_entry(hw); | ||
1208 | rtl92cu_enable_hw_security_config(hw); | ||
1209 | ppsc->rfpwr_state = ERFON; | ||
1210 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); | ||
1211 | if (ppsc->rfpwr_state == ERFON) { | ||
1212 | rtl92c_phy_set_rfpath_switch(hw, 1); | ||
1213 | if (iqk_initialized) { | ||
1214 | rtl92c_phy_iq_calibrate(hw, false); | ||
1215 | } else { | ||
1216 | rtl92c_phy_iq_calibrate(hw, false); | ||
1217 | iqk_initialized = true; | ||
1218 | } | ||
1219 | rtl92c_dm_check_txpower_tracking(hw); | ||
1220 | rtl92c_phy_lc_calibrate(hw); | ||
1221 | } | ||
1222 | _rtl92cu_hw_configure(hw); | ||
1223 | _InitPABias(hw); | ||
1224 | _InitAntenna_Selection(hw); | ||
1225 | _update_mac_setting(hw); | ||
1226 | rtl92c_dm_init(hw); | ||
1227 | _dump_registers(hw); | ||
1228 | return err; | ||
1229 | } | ||
1230 | |||
1231 | static void _DisableRFAFEAndResetBB(struct ieee80211_hw *hw) | ||
1232 | { | ||
1233 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1234 | /************************************** | ||
1235 | a. TXPAUSE 0x522[7:0] = 0xFF Pause MAC TX queue | ||
1236 | b. RF path 0 offset 0x00 = 0x00 disable RF | ||
1237 | c. APSD_CTRL 0x600[7:0] = 0x40 | ||
1238 | d. SYS_FUNC_EN 0x02[7:0] = 0x16 reset BB state machine | ||
1239 | e. SYS_FUNC_EN 0x02[7:0] = 0x14 reset BB state machine | ||
1240 | ***************************************/ | ||
1241 | u8 eRFPath = 0, value8 = 0; | ||
1242 | rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); | ||
1243 | rtl_set_rfreg(hw, (enum radio_path)eRFPath, 0x0, MASKBYTE0, 0x0); | ||
1244 | |||
1245 | value8 |= APSDOFF; | ||
1246 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, value8); /*0x40*/ | ||
1247 | value8 = 0; | ||
1248 | value8 |= (FEN_USBD | FEN_USBA | FEN_BB_GLB_RSTn); | ||
1249 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, value8);/*0x16*/ | ||
1250 | value8 &= (~FEN_BB_GLB_RSTn); | ||
1251 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, value8); /*0x14*/ | ||
1252 | } | ||
1253 | |||
1254 | static void _ResetDigitalProcedure1(struct ieee80211_hw *hw, bool bWithoutHWSM) | ||
1255 | { | ||
1256 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1257 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1258 | |||
1259 | if (rtlhal->fw_version <= 0x20) { | ||
1260 | /***************************** | ||
1261 | f. MCUFWDL 0x80[7:0]=0 reset MCU ready status | ||
1262 | g. SYS_FUNC_EN 0x02[10]= 0 reset MCU reg, (8051 reset) | ||
1263 | h. SYS_FUNC_EN 0x02[15-12]= 5 reset MAC reg, DCORE | ||
1264 | i. SYS_FUNC_EN 0x02[10]= 1 enable MCU reg, (8051 enable) | ||
1265 | ******************************/ | ||
1266 | u16 valu16 = 0; | ||
1267 | |||
1268 | rtl_write_byte(rtlpriv, REG_MCUFWDL, 0); | ||
1269 | valu16 = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); | ||
1270 | rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (valu16 & | ||
1271 | (~FEN_CPUEN))); /* reset MCU ,8051 */ | ||
1272 | valu16 = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN)&0x0FFF; | ||
1273 | rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (valu16 | | ||
1274 | (FEN_HWPDN|FEN_ELDR))); /* reset MAC */ | ||
1275 | valu16 = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); | ||
1276 | rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (valu16 | | ||
1277 | FEN_CPUEN)); /* enable MCU ,8051 */ | ||
1278 | } else { | ||
1279 | u8 retry_cnts = 0; | ||
1280 | |||
1281 | /* IF fw in RAM code, do reset */ | ||
1282 | if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(1)) { | ||
1283 | /* reset MCU ready status */ | ||
1284 | rtl_write_byte(rtlpriv, REG_MCUFWDL, 0); | ||
1285 | if (rtlhal->fw_ready) { | ||
1286 | /* 8051 reset by self */ | ||
1287 | rtl_write_byte(rtlpriv, REG_HMETFR+3, 0x20); | ||
1288 | while ((retry_cnts++ < 100) && | ||
1289 | (FEN_CPUEN & rtl_read_word(rtlpriv, | ||
1290 | REG_SYS_FUNC_EN))) { | ||
1291 | udelay(50); | ||
1292 | } | ||
1293 | if (retry_cnts >= 100) { | ||
1294 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
1295 | ("#####=> 8051 reset failed!.." | ||
1296 | ".......................\n");); | ||
1297 | /* if 8051 reset fail, reset MAC. */ | ||
1298 | rtl_write_byte(rtlpriv, | ||
1299 | REG_SYS_FUNC_EN + 1, | ||
1300 | 0x50); | ||
1301 | udelay(100); | ||
1302 | } | ||
1303 | } | ||
1304 | } | ||
1305 | /* Reset MAC and Enable 8051 */ | ||
1306 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x54); | ||
1307 | rtl_write_byte(rtlpriv, REG_MCUFWDL, 0); | ||
1308 | } | ||
1309 | if (bWithoutHWSM) { | ||
1310 | /***************************** | ||
1311 | Without HW auto state machine | ||
1312 | g.SYS_CLKR 0x08[15:0] = 0x30A3 disable MAC clock | ||
1313 | h.AFE_PLL_CTRL 0x28[7:0] = 0x80 disable AFE PLL | ||
1314 | i.AFE_XTAL_CTRL 0x24[15:0] = 0x880F gated AFE DIG_CLOCK | ||
1315 | j.SYS_ISu_CTRL 0x00[7:0] = 0xF9 isolated digital to PON | ||
1316 | ******************************/ | ||
1317 | rtl_write_word(rtlpriv, REG_SYS_CLKR, 0x70A3); | ||
1318 | rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x80); | ||
1319 | rtl_write_word(rtlpriv, REG_AFE_XTAL_CTRL, 0x880F); | ||
1320 | rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, 0xF9); | ||
1321 | } | ||
1322 | } | ||
1323 | |||
1324 | static void _ResetDigitalProcedure2(struct ieee80211_hw *hw) | ||
1325 | { | ||
1326 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1327 | /***************************** | ||
1328 | k. SYS_FUNC_EN 0x03[7:0] = 0x44 disable ELDR runction | ||
1329 | l. SYS_CLKR 0x08[15:0] = 0x3083 disable ELDR clock | ||
1330 | m. SYS_ISO_CTRL 0x01[7:0] = 0x83 isolated ELDR to PON | ||
1331 | ******************************/ | ||
1332 | rtl_write_word(rtlpriv, REG_SYS_CLKR, 0x70A3); | ||
1333 | rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL+1, 0x82); | ||
1334 | } | ||
1335 | |||
1336 | static void _DisableGPIO(struct ieee80211_hw *hw) | ||
1337 | { | ||
1338 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1339 | /*************************************** | ||
1340 | j. GPIO_PIN_CTRL 0x44[31:0]=0x000 | ||
1341 | k. Value = GPIO_PIN_CTRL[7:0] | ||
1342 | l. GPIO_PIN_CTRL 0x44[31:0] = 0x00FF0000 | (value <<8); write ext PIN level | ||
1343 | m. GPIO_MUXCFG 0x42 [15:0] = 0x0780 | ||
1344 | n. LEDCFG 0x4C[15:0] = 0x8080 | ||
1345 | ***************************************/ | ||
1346 | u8 value8; | ||
1347 | u16 value16; | ||
1348 | u32 value32; | ||
1349 | |||
1350 | /* 1. Disable GPIO[7:0] */ | ||
1351 | rtl_write_word(rtlpriv, REG_GPIO_PIN_CTRL+2, 0x0000); | ||
1352 | value32 = rtl_read_dword(rtlpriv, REG_GPIO_PIN_CTRL) & 0xFFFF00FF; | ||
1353 | value8 = (u8) (value32&0x000000FF); | ||
1354 | value32 |= ((value8<<8) | 0x00FF0000); | ||
1355 | rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, value32); | ||
1356 | /* 2. Disable GPIO[10:8] */ | ||
1357 | rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG+3, 0x00); | ||
1358 | value16 = rtl_read_word(rtlpriv, REG_GPIO_MUXCFG+2) & 0xFF0F; | ||
1359 | value8 = (u8) (value16&0x000F); | ||
1360 | value16 |= ((value8<<4) | 0x0780); | ||
1361 | rtl_write_word(rtlpriv, REG_GPIO_PIN_CTRL+2, value16); | ||
1362 | /* 3. Disable LED0 & 1 */ | ||
1363 | rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8080); | ||
1364 | } | ||
1365 | |||
1366 | static void _DisableAnalog(struct ieee80211_hw *hw, bool bWithoutHWSM) | ||
1367 | { | ||
1368 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1369 | u16 value16 = 0; | ||
1370 | u8 value8 = 0; | ||
1371 | |||
1372 | if (bWithoutHWSM) { | ||
1373 | /***************************** | ||
1374 | n. LDOA15_CTRL 0x20[7:0] = 0x04 disable A15 power | ||
1375 | o. LDOV12D_CTRL 0x21[7:0] = 0x54 disable digital core power | ||
1376 | r. When driver call disable, the ASIC will turn off remaining | ||
1377 | clock automatically | ||
1378 | ******************************/ | ||
1379 | rtl_write_byte(rtlpriv, REG_LDOA15_CTRL, 0x04); | ||
1380 | value8 = rtl_read_byte(rtlpriv, REG_LDOV12D_CTRL); | ||
1381 | value8 &= (~LDV12_EN); | ||
1382 | rtl_write_byte(rtlpriv, REG_LDOV12D_CTRL, value8); | ||
1383 | } | ||
1384 | |||
1385 | /***************************** | ||
1386 | h. SPS0_CTRL 0x11[7:0] = 0x23 enter PFM mode | ||
1387 | i. APS_FSMCO 0x04[15:0] = 0x4802 set USB suspend | ||
1388 | ******************************/ | ||
1389 | rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23); | ||
1390 | value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN); | ||
1391 | rtl_write_word(rtlpriv, REG_APS_FSMCO, (u16)value16); | ||
1392 | rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0E); | ||
1393 | } | ||
1394 | |||
1395 | static void _CardDisableHWSM(struct ieee80211_hw *hw) | ||
1396 | { | ||
1397 | /* ==== RF Off Sequence ==== */ | ||
1398 | _DisableRFAFEAndResetBB(hw); | ||
1399 | /* ==== Reset digital sequence ====== */ | ||
1400 | _ResetDigitalProcedure1(hw, false); | ||
1401 | /* ==== Pull GPIO PIN to balance level and LED control ====== */ | ||
1402 | _DisableGPIO(hw); | ||
1403 | /* ==== Disable analog sequence === */ | ||
1404 | _DisableAnalog(hw, false); | ||
1405 | } | ||
1406 | |||
1407 | static void _CardDisableWithoutHWSM(struct ieee80211_hw *hw) | ||
1408 | { | ||
1409 | /*==== RF Off Sequence ==== */ | ||
1410 | _DisableRFAFEAndResetBB(hw); | ||
1411 | /* ==== Reset digital sequence ====== */ | ||
1412 | _ResetDigitalProcedure1(hw, true); | ||
1413 | /* ==== Pull GPIO PIN to balance level and LED control ====== */ | ||
1414 | _DisableGPIO(hw); | ||
1415 | /* ==== Reset digital sequence ====== */ | ||
1416 | _ResetDigitalProcedure2(hw); | ||
1417 | /* ==== Disable analog sequence === */ | ||
1418 | _DisableAnalog(hw, true); | ||
1419 | } | ||
1420 | |||
1421 | static void _rtl92cu_set_bcn_ctrl_reg(struct ieee80211_hw *hw, | ||
1422 | u8 set_bits, u8 clear_bits) | ||
1423 | { | ||
1424 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1425 | struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); | ||
1426 | |||
1427 | rtlusb->reg_bcn_ctrl_val |= set_bits; | ||
1428 | rtlusb->reg_bcn_ctrl_val &= ~clear_bits; | ||
1429 | rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8) rtlusb->reg_bcn_ctrl_val); | ||
1430 | } | ||
1431 | |||
1432 | static void _rtl92cu_stop_tx_beacon(struct ieee80211_hw *hw) | ||
1433 | { | ||
1434 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1435 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | ||
1436 | u8 tmp1byte = 0; | ||
1437 | if (IS_NORMAL_CHIP(rtlhal->version)) { | ||
1438 | tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); | ||
1439 | rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, | ||
1440 | tmp1byte & (~BIT(6))); | ||
1441 | rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64); | ||
1442 | tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); | ||
1443 | tmp1byte &= ~(BIT(0)); | ||
1444 | rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); | ||
1445 | } else { | ||
1446 | rtl_write_byte(rtlpriv, REG_TXPAUSE, | ||
1447 | rtl_read_byte(rtlpriv, REG_TXPAUSE) | BIT(6)); | ||
1448 | } | ||
1449 | } | ||
1450 | |||
1451 | static void _rtl92cu_resume_tx_beacon(struct ieee80211_hw *hw) | ||
1452 | { | ||
1453 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1454 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | ||
1455 | u8 tmp1byte = 0; | ||
1456 | |||
1457 | if (IS_NORMAL_CHIP(rtlhal->version)) { | ||
1458 | tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); | ||
1459 | rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, | ||
1460 | tmp1byte | BIT(6)); | ||
1461 | rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); | ||
1462 | tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); | ||
1463 | tmp1byte |= BIT(0); | ||
1464 | rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); | ||
1465 | } else { | ||
1466 | rtl_write_byte(rtlpriv, REG_TXPAUSE, | ||
1467 | rtl_read_byte(rtlpriv, REG_TXPAUSE) & (~BIT(6))); | ||
1468 | } | ||
1469 | } | ||
1470 | |||
1471 | static void _rtl92cu_enable_bcn_sub_func(struct ieee80211_hw *hw) | ||
1472 | { | ||
1473 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1474 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | ||
1475 | |||
1476 | if (IS_NORMAL_CHIP(rtlhal->version)) | ||
1477 | _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(1)); | ||
1478 | else | ||
1479 | _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(4)); | ||
1480 | } | ||
1481 | |||
1482 | static void _rtl92cu_disable_bcn_sub_func(struct ieee80211_hw *hw) | ||
1483 | { | ||
1484 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1485 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | ||
1486 | |||
1487 | if (IS_NORMAL_CHIP(rtlhal->version)) | ||
1488 | _rtl92cu_set_bcn_ctrl_reg(hw, BIT(1), 0); | ||
1489 | else | ||
1490 | _rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0); | ||
1491 | } | ||
1492 | |||
1493 | static int _rtl92cu_set_media_status(struct ieee80211_hw *hw, | ||
1494 | enum nl80211_iftype type) | ||
1495 | { | ||
1496 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1497 | u8 bt_msr = rtl_read_byte(rtlpriv, MSR); | ||
1498 | enum led_ctl_mode ledaction = LED_CTL_NO_LINK; | ||
1499 | |||
1500 | bt_msr &= 0xfc; | ||
1501 | rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xFF); | ||
1502 | if (type == NL80211_IFTYPE_UNSPECIFIED || type == | ||
1503 | NL80211_IFTYPE_STATION) { | ||
1504 | _rtl92cu_stop_tx_beacon(hw); | ||
1505 | _rtl92cu_enable_bcn_sub_func(hw); | ||
1506 | } else if (type == NL80211_IFTYPE_ADHOC || type == NL80211_IFTYPE_AP) { | ||
1507 | _rtl92cu_resume_tx_beacon(hw); | ||
1508 | _rtl92cu_disable_bcn_sub_func(hw); | ||
1509 | } else { | ||
1510 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("Set HW_VAR_MEDIA_" | ||
1511 | "STATUS:No such media status(%x).\n", type)); | ||
1512 | } | ||
1513 | switch (type) { | ||
1514 | case NL80211_IFTYPE_UNSPECIFIED: | ||
1515 | bt_msr |= MSR_NOLINK; | ||
1516 | ledaction = LED_CTL_LINK; | ||
1517 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
1518 | ("Set Network type to NO LINK!\n")); | ||
1519 | break; | ||
1520 | case NL80211_IFTYPE_ADHOC: | ||
1521 | bt_msr |= MSR_ADHOC; | ||
1522 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
1523 | ("Set Network type to Ad Hoc!\n")); | ||
1524 | break; | ||
1525 | case NL80211_IFTYPE_STATION: | ||
1526 | bt_msr |= MSR_INFRA; | ||
1527 | ledaction = LED_CTL_LINK; | ||
1528 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
1529 | ("Set Network type to STA!\n")); | ||
1530 | break; | ||
1531 | case NL80211_IFTYPE_AP: | ||
1532 | bt_msr |= MSR_AP; | ||
1533 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
1534 | ("Set Network type to AP!\n")); | ||
1535 | break; | ||
1536 | default: | ||
1537 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
1538 | ("Network type %d not support!\n", type)); | ||
1539 | goto error_out; | ||
1540 | } | ||
1541 | rtl_write_byte(rtlpriv, (MSR), bt_msr); | ||
1542 | rtlpriv->cfg->ops->led_control(hw, ledaction); | ||
1543 | if ((bt_msr & 0xfc) == MSR_AP) | ||
1544 | rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); | ||
1545 | else | ||
1546 | rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66); | ||
1547 | return 0; | ||
1548 | error_out: | ||
1549 | return 1; | ||
1550 | } | ||
1551 | |||
1552 | void rtl92cu_card_disable(struct ieee80211_hw *hw) | ||
1553 | { | ||
1554 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1555 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
1556 | struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); | ||
1557 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
1558 | enum nl80211_iftype opmode; | ||
1559 | |||
1560 | mac->link_state = MAC80211_NOLINK; | ||
1561 | opmode = NL80211_IFTYPE_UNSPECIFIED; | ||
1562 | _rtl92cu_set_media_status(hw, opmode); | ||
1563 | rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); | ||
1564 | RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); | ||
1565 | if (rtlusb->disableHWSM) | ||
1566 | _CardDisableHWSM(hw); | ||
1567 | else | ||
1568 | _CardDisableWithoutHWSM(hw); | ||
1569 | } | ||
1570 | |||
1571 | void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) | ||
1572 | { | ||
1573 | /* dummy routine needed for callback from rtl_op_configure_filter() */ | ||
1574 | } | ||
1575 | |||
1576 | /*========================================================================== */ | ||
1577 | |||
1578 | static void _rtl92cu_set_check_bssid(struct ieee80211_hw *hw, | ||
1579 | enum nl80211_iftype type) | ||
1580 | { | ||
1581 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1582 | u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR); | ||
1583 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | ||
1584 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1585 | u8 filterout_non_associated_bssid = false; | ||
1586 | |||
1587 | switch (type) { | ||
1588 | case NL80211_IFTYPE_ADHOC: | ||
1589 | case NL80211_IFTYPE_STATION: | ||
1590 | filterout_non_associated_bssid = true; | ||
1591 | break; | ||
1592 | case NL80211_IFTYPE_UNSPECIFIED: | ||
1593 | case NL80211_IFTYPE_AP: | ||
1594 | default: | ||
1595 | break; | ||
1596 | } | ||
1597 | if (filterout_non_associated_bssid == true) { | ||
1598 | if (IS_NORMAL_CHIP(rtlhal->version)) { | ||
1599 | switch (rtlphy->current_io_type) { | ||
1600 | case IO_CMD_RESUME_DM_BY_SCAN: | ||
1601 | reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); | ||
1602 | rtlpriv->cfg->ops->set_hw_reg(hw, | ||
1603 | HW_VAR_RCR, (u8 *)(®_rcr)); | ||
1604 | /* enable update TSF */ | ||
1605 | _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(4)); | ||
1606 | break; | ||
1607 | case IO_CMD_PAUSE_DM_BY_SCAN: | ||
1608 | reg_rcr &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN); | ||
1609 | rtlpriv->cfg->ops->set_hw_reg(hw, | ||
1610 | HW_VAR_RCR, (u8 *)(®_rcr)); | ||
1611 | /* disable update TSF */ | ||
1612 | _rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0); | ||
1613 | break; | ||
1614 | } | ||
1615 | } else { | ||
1616 | reg_rcr |= (RCR_CBSSID); | ||
1617 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, | ||
1618 | (u8 *)(®_rcr)); | ||
1619 | _rtl92cu_set_bcn_ctrl_reg(hw, 0, (BIT(4)|BIT(5))); | ||
1620 | } | ||
1621 | } else if (filterout_non_associated_bssid == false) { | ||
1622 | if (IS_NORMAL_CHIP(rtlhal->version)) { | ||
1623 | reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); | ||
1624 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, | ||
1625 | (u8 *)(®_rcr)); | ||
1626 | _rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0); | ||
1627 | } else { | ||
1628 | reg_rcr &= (~RCR_CBSSID); | ||
1629 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, | ||
1630 | (u8 *)(®_rcr)); | ||
1631 | _rtl92cu_set_bcn_ctrl_reg(hw, (BIT(4)|BIT(5)), 0); | ||
1632 | } | ||
1633 | } | ||
1634 | } | ||
1635 | |||
1636 | int rtl92cu_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) | ||
1637 | { | ||
1638 | if (_rtl92cu_set_media_status(hw, type)) | ||
1639 | return -EOPNOTSUPP; | ||
1640 | _rtl92cu_set_check_bssid(hw, type); | ||
1641 | return 0; | ||
1642 | } | ||
1643 | |||
1644 | static void _InitBeaconParameters(struct ieee80211_hw *hw) | ||
1645 | { | ||
1646 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1647 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | ||
1648 | |||
1649 | rtl_write_word(rtlpriv, REG_BCN_CTRL, 0x1010); | ||
1650 | |||
1651 | /* TODO: Remove these magic number */ | ||
1652 | rtl_write_word(rtlpriv, REG_TBTT_PROHIBIT, 0x6404); | ||
1653 | rtl_write_byte(rtlpriv, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME); | ||
1654 | rtl_write_byte(rtlpriv, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME); | ||
1655 | /* Change beacon AIFS to the largest number | ||
1656 | * beacause test chip does not contension before sending beacon. */ | ||
1657 | if (IS_NORMAL_CHIP(rtlhal->version)) | ||
1658 | rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660F); | ||
1659 | else | ||
1660 | rtl_write_word(rtlpriv, REG_BCNTCFG, 0x66FF); | ||
1661 | } | ||
1662 | |||
1663 | static void _beacon_function_enable(struct ieee80211_hw *hw, bool Enable, | ||
1664 | bool Linked) | ||
1665 | { | ||
1666 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1667 | |||
1668 | _rtl92cu_set_bcn_ctrl_reg(hw, (BIT(4) | BIT(3) | BIT(1)), 0x00); | ||
1669 | rtl_write_byte(rtlpriv, REG_RD_CTRL+1, 0x6F); | ||
1670 | } | ||
1671 | |||
1672 | void rtl92cu_set_beacon_related_registers(struct ieee80211_hw *hw) | ||
1673 | { | ||
1674 | |||
1675 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1676 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
1677 | u16 bcn_interval, atim_window; | ||
1678 | u32 value32; | ||
1679 | |||
1680 | bcn_interval = mac->beacon_interval; | ||
1681 | atim_window = 2; /*FIX MERGE */ | ||
1682 | rtl_write_word(rtlpriv, REG_ATIMWND, atim_window); | ||
1683 | rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); | ||
1684 | _InitBeaconParameters(hw); | ||
1685 | rtl_write_byte(rtlpriv, REG_SLOT, 0x09); | ||
1686 | /* | ||
1687 | * Force beacon frame transmission even after receiving beacon frame | ||
1688 | * from other ad hoc STA | ||
1689 | * | ||
1690 | * | ||
1691 | * Reset TSF Timer to zero, added by Roger. 2008.06.24 | ||
1692 | */ | ||
1693 | value32 = rtl_read_dword(rtlpriv, REG_TCR); | ||
1694 | value32 &= ~TSFRST; | ||
1695 | rtl_write_dword(rtlpriv, REG_TCR, value32); | ||
1696 | value32 |= TSFRST; | ||
1697 | rtl_write_dword(rtlpriv, REG_TCR, value32); | ||
1698 | RT_TRACE(rtlpriv, COMP_INIT|COMP_BEACON, DBG_LOUD, | ||
1699 | ("SetBeaconRelatedRegisters8192CUsb(): Set TCR(%x)\n", | ||
1700 | value32)); | ||
1701 | /* TODO: Modify later (Find the right parameters) | ||
1702 | * NOTE: Fix test chip's bug (about contention windows's randomness) */ | ||
1703 | if ((mac->opmode == NL80211_IFTYPE_ADHOC) || | ||
1704 | (mac->opmode == NL80211_IFTYPE_AP)) { | ||
1705 | rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x50); | ||
1706 | rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x50); | ||
1707 | } | ||
1708 | _beacon_function_enable(hw, true, true); | ||
1709 | } | ||
1710 | |||
1711 | void rtl92cu_set_beacon_interval(struct ieee80211_hw *hw) | ||
1712 | { | ||
1713 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1714 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
1715 | u16 bcn_interval = mac->beacon_interval; | ||
1716 | |||
1717 | RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, | ||
1718 | ("beacon_interval:%d\n", bcn_interval)); | ||
1719 | rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); | ||
1720 | } | ||
1721 | |||
1722 | void rtl92cu_update_interrupt_mask(struct ieee80211_hw *hw, | ||
1723 | u32 add_msr, u32 rm_msr) | ||
1724 | { | ||
1725 | } | ||
1726 | |||
1727 | void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | ||
1728 | { | ||
1729 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1730 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
1731 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
1732 | |||
1733 | switch (variable) { | ||
1734 | case HW_VAR_RCR: | ||
1735 | *((u32 *)(val)) = mac->rx_conf; | ||
1736 | break; | ||
1737 | case HW_VAR_RF_STATE: | ||
1738 | *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state; | ||
1739 | break; | ||
1740 | case HW_VAR_FWLPS_RF_ON:{ | ||
1741 | enum rf_pwrstate rfState; | ||
1742 | u32 val_rcr; | ||
1743 | |||
1744 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, | ||
1745 | (u8 *)(&rfState)); | ||
1746 | if (rfState == ERFOFF) { | ||
1747 | *((bool *) (val)) = true; | ||
1748 | } else { | ||
1749 | val_rcr = rtl_read_dword(rtlpriv, REG_RCR); | ||
1750 | val_rcr &= 0x00070000; | ||
1751 | if (val_rcr) | ||
1752 | *((bool *) (val)) = false; | ||
1753 | else | ||
1754 | *((bool *) (val)) = true; | ||
1755 | } | ||
1756 | break; | ||
1757 | } | ||
1758 | case HW_VAR_FW_PSMODE_STATUS: | ||
1759 | *((bool *) (val)) = ppsc->fw_current_inpsmode; | ||
1760 | break; | ||
1761 | case HW_VAR_CORRECT_TSF:{ | ||
1762 | u64 tsf; | ||
1763 | u32 *ptsf_low = (u32 *)&tsf; | ||
1764 | u32 *ptsf_high = ((u32 *)&tsf) + 1; | ||
1765 | |||
1766 | *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4)); | ||
1767 | *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); | ||
1768 | *((u64 *)(val)) = tsf; | ||
1769 | break; | ||
1770 | } | ||
1771 | case HW_VAR_MGT_FILTER: | ||
1772 | *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP0); | ||
1773 | break; | ||
1774 | case HW_VAR_CTRL_FILTER: | ||
1775 | *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP1); | ||
1776 | break; | ||
1777 | case HW_VAR_DATA_FILTER: | ||
1778 | *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP2); | ||
1779 | break; | ||
1780 | default: | ||
1781 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
1782 | ("switch case not process\n")); | ||
1783 | break; | ||
1784 | } | ||
1785 | } | ||
1786 | |||
1787 | void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | ||
1788 | { | ||
1789 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1790 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
1791 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1792 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
1793 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
1794 | struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); | ||
1795 | enum wireless_mode wirelessmode = mac->mode; | ||
1796 | u8 idx = 0; | ||
1797 | |||
1798 | switch (variable) { | ||
1799 | case HW_VAR_ETHER_ADDR:{ | ||
1800 | for (idx = 0; idx < ETH_ALEN; idx++) { | ||
1801 | rtl_write_byte(rtlpriv, (REG_MACID + idx), | ||
1802 | val[idx]); | ||
1803 | } | ||
1804 | break; | ||
1805 | } | ||
1806 | case HW_VAR_BASIC_RATE:{ | ||
1807 | u16 rate_cfg = ((u16 *) val)[0]; | ||
1808 | u8 rate_index = 0; | ||
1809 | |||
1810 | rate_cfg &= 0x15f; | ||
1811 | /* TODO */ | ||
1812 | /* if (mac->current_network.vender == HT_IOT_PEER_CISCO | ||
1813 | * && ((rate_cfg & 0x150) == 0)) { | ||
1814 | * rate_cfg |= 0x010; | ||
1815 | * } */ | ||
1816 | rate_cfg |= 0x01; | ||
1817 | rtl_write_byte(rtlpriv, REG_RRSR, rate_cfg & 0xff); | ||
1818 | rtl_write_byte(rtlpriv, REG_RRSR + 1, | ||
1819 | (rate_cfg >> 8) & 0xff); | ||
1820 | while (rate_cfg > 0x1) { | ||
1821 | rate_cfg >>= 1; | ||
1822 | rate_index++; | ||
1823 | } | ||
1824 | rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, | ||
1825 | rate_index); | ||
1826 | break; | ||
1827 | } | ||
1828 | case HW_VAR_BSSID:{ | ||
1829 | for (idx = 0; idx < ETH_ALEN; idx++) { | ||
1830 | rtl_write_byte(rtlpriv, (REG_BSSID + idx), | ||
1831 | val[idx]); | ||
1832 | } | ||
1833 | break; | ||
1834 | } | ||
1835 | case HW_VAR_SIFS:{ | ||
1836 | rtl_write_byte(rtlpriv, REG_SIFS_CCK + 1, val[0]); | ||
1837 | rtl_write_byte(rtlpriv, REG_SIFS_OFDM + 1, val[1]); | ||
1838 | rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]); | ||
1839 | rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]); | ||
1840 | rtl_write_byte(rtlpriv, REG_R2T_SIFS+1, val[0]); | ||
1841 | rtl_write_byte(rtlpriv, REG_T2T_SIFS+1, val[0]); | ||
1842 | RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, | ||
1843 | ("HW_VAR_SIFS\n")); | ||
1844 | break; | ||
1845 | } | ||
1846 | case HW_VAR_SLOT_TIME:{ | ||
1847 | u8 e_aci; | ||
1848 | u8 QOS_MODE = 1; | ||
1849 | |||
1850 | rtl_write_byte(rtlpriv, REG_SLOT, val[0]); | ||
1851 | RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, | ||
1852 | ("HW_VAR_SLOT_TIME %x\n", val[0])); | ||
1853 | if (QOS_MODE) { | ||
1854 | for (e_aci = 0; e_aci < AC_MAX; e_aci++) | ||
1855 | rtlpriv->cfg->ops->set_hw_reg(hw, | ||
1856 | HW_VAR_AC_PARAM, | ||
1857 | (u8 *)(&e_aci)); | ||
1858 | } else { | ||
1859 | u8 sifstime = 0; | ||
1860 | u8 u1bAIFS; | ||
1861 | |||
1862 | if (IS_WIRELESS_MODE_A(wirelessmode) || | ||
1863 | IS_WIRELESS_MODE_N_24G(wirelessmode) || | ||
1864 | IS_WIRELESS_MODE_N_5G(wirelessmode)) | ||
1865 | sifstime = 16; | ||
1866 | else | ||
1867 | sifstime = 10; | ||
1868 | u1bAIFS = sifstime + (2 * val[0]); | ||
1869 | rtl_write_byte(rtlpriv, REG_EDCA_VO_PARAM, | ||
1870 | u1bAIFS); | ||
1871 | rtl_write_byte(rtlpriv, REG_EDCA_VI_PARAM, | ||
1872 | u1bAIFS); | ||
1873 | rtl_write_byte(rtlpriv, REG_EDCA_BE_PARAM, | ||
1874 | u1bAIFS); | ||
1875 | rtl_write_byte(rtlpriv, REG_EDCA_BK_PARAM, | ||
1876 | u1bAIFS); | ||
1877 | } | ||
1878 | break; | ||
1879 | } | ||
1880 | case HW_VAR_ACK_PREAMBLE:{ | ||
1881 | u8 reg_tmp; | ||
1882 | u8 short_preamble = (bool) (*(u8 *) val); | ||
1883 | reg_tmp = 0; | ||
1884 | if (short_preamble) | ||
1885 | reg_tmp |= 0x80; | ||
1886 | rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_tmp); | ||
1887 | break; | ||
1888 | } | ||
1889 | case HW_VAR_AMPDU_MIN_SPACE:{ | ||
1890 | u8 min_spacing_to_set; | ||
1891 | u8 sec_min_space; | ||
1892 | |||
1893 | min_spacing_to_set = *((u8 *) val); | ||
1894 | if (min_spacing_to_set <= 7) { | ||
1895 | switch (rtlpriv->sec.pairwise_enc_algorithm) { | ||
1896 | case NO_ENCRYPTION: | ||
1897 | case AESCCMP_ENCRYPTION: | ||
1898 | sec_min_space = 0; | ||
1899 | break; | ||
1900 | case WEP40_ENCRYPTION: | ||
1901 | case WEP104_ENCRYPTION: | ||
1902 | case TKIP_ENCRYPTION: | ||
1903 | sec_min_space = 6; | ||
1904 | break; | ||
1905 | default: | ||
1906 | sec_min_space = 7; | ||
1907 | break; | ||
1908 | } | ||
1909 | if (min_spacing_to_set < sec_min_space) | ||
1910 | min_spacing_to_set = sec_min_space; | ||
1911 | mac->min_space_cfg = ((mac->min_space_cfg & | ||
1912 | 0xf8) | | ||
1913 | min_spacing_to_set); | ||
1914 | *val = min_spacing_to_set; | ||
1915 | RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, | ||
1916 | ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", | ||
1917 | mac->min_space_cfg)); | ||
1918 | rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, | ||
1919 | mac->min_space_cfg); | ||
1920 | } | ||
1921 | break; | ||
1922 | } | ||
1923 | case HW_VAR_SHORTGI_DENSITY:{ | ||
1924 | u8 density_to_set; | ||
1925 | |||
1926 | density_to_set = *((u8 *) val); | ||
1927 | density_to_set &= 0x1f; | ||
1928 | mac->min_space_cfg &= 0x07; | ||
1929 | mac->min_space_cfg |= (density_to_set << 3); | ||
1930 | RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, | ||
1931 | ("Set HW_VAR_SHORTGI_DENSITY: %#x\n", | ||
1932 | mac->min_space_cfg)); | ||
1933 | rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, | ||
1934 | mac->min_space_cfg); | ||
1935 | break; | ||
1936 | } | ||
1937 | case HW_VAR_AMPDU_FACTOR:{ | ||
1938 | u8 regtoset_normal[4] = {0x41, 0xa8, 0x72, 0xb9}; | ||
1939 | u8 factor_toset; | ||
1940 | u8 *p_regtoset = NULL; | ||
1941 | u8 index = 0; | ||
1942 | |||
1943 | p_regtoset = regtoset_normal; | ||
1944 | factor_toset = *((u8 *) val); | ||
1945 | if (factor_toset <= 3) { | ||
1946 | factor_toset = (1 << (factor_toset + 2)); | ||
1947 | if (factor_toset > 0xf) | ||
1948 | factor_toset = 0xf; | ||
1949 | for (index = 0; index < 4; index++) { | ||
1950 | if ((p_regtoset[index] & 0xf0) > | ||
1951 | (factor_toset << 4)) | ||
1952 | p_regtoset[index] = | ||
1953 | (p_regtoset[index] & 0x0f) | ||
1954 | | (factor_toset << 4); | ||
1955 | if ((p_regtoset[index] & 0x0f) > | ||
1956 | factor_toset) | ||
1957 | p_regtoset[index] = | ||
1958 | (p_regtoset[index] & 0xf0) | ||
1959 | | (factor_toset); | ||
1960 | rtl_write_byte(rtlpriv, | ||
1961 | (REG_AGGLEN_LMT + index), | ||
1962 | p_regtoset[index]); | ||
1963 | } | ||
1964 | RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, | ||
1965 | ("Set HW_VAR_AMPDU_FACTOR: %#x\n", | ||
1966 | factor_toset)); | ||
1967 | } | ||
1968 | break; | ||
1969 | } | ||
1970 | case HW_VAR_AC_PARAM:{ | ||
1971 | u8 e_aci = *((u8 *) val); | ||
1972 | u32 u4b_ac_param; | ||
1973 | u16 cw_min = le16_to_cpu(mac->ac[e_aci].cw_min); | ||
1974 | u16 cw_max = le16_to_cpu(mac->ac[e_aci].cw_max); | ||
1975 | u16 tx_op = le16_to_cpu(mac->ac[e_aci].tx_op); | ||
1976 | |||
1977 | u4b_ac_param = (u32) mac->ac[e_aci].aifs; | ||
1978 | u4b_ac_param |= (u32) ((cw_min & 0xF) << | ||
1979 | AC_PARAM_ECW_MIN_OFFSET); | ||
1980 | u4b_ac_param |= (u32) ((cw_max & 0xF) << | ||
1981 | AC_PARAM_ECW_MAX_OFFSET); | ||
1982 | u4b_ac_param |= (u32) tx_op << AC_PARAM_TXOP_OFFSET; | ||
1983 | RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, | ||
1984 | ("queue:%x, ac_param:%x\n", e_aci, | ||
1985 | u4b_ac_param)); | ||
1986 | switch (e_aci) { | ||
1987 | case AC1_BK: | ||
1988 | rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, | ||
1989 | u4b_ac_param); | ||
1990 | break; | ||
1991 | case AC0_BE: | ||
1992 | rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, | ||
1993 | u4b_ac_param); | ||
1994 | break; | ||
1995 | case AC2_VI: | ||
1996 | rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, | ||
1997 | u4b_ac_param); | ||
1998 | break; | ||
1999 | case AC3_VO: | ||
2000 | rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, | ||
2001 | u4b_ac_param); | ||
2002 | break; | ||
2003 | default: | ||
2004 | RT_ASSERT(false, ("SetHwReg8185(): invalid" | ||
2005 | " aci: %d !\n", e_aci)); | ||
2006 | break; | ||
2007 | } | ||
2008 | if (rtlusb->acm_method != eAcmWay2_SW) | ||
2009 | rtlpriv->cfg->ops->set_hw_reg(hw, | ||
2010 | HW_VAR_ACM_CTRL, (u8 *)(&e_aci)); | ||
2011 | break; | ||
2012 | } | ||
2013 | case HW_VAR_ACM_CTRL:{ | ||
2014 | u8 e_aci = *((u8 *) val); | ||
2015 | union aci_aifsn *p_aci_aifsn = (union aci_aifsn *) | ||
2016 | (&(mac->ac[0].aifs)); | ||
2017 | u8 acm = p_aci_aifsn->f.acm; | ||
2018 | u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL); | ||
2019 | |||
2020 | acm_ctrl = | ||
2021 | acm_ctrl | ((rtlusb->acm_method == 2) ? 0x0 : 0x1); | ||
2022 | if (acm) { | ||
2023 | switch (e_aci) { | ||
2024 | case AC0_BE: | ||
2025 | acm_ctrl |= AcmHw_BeqEn; | ||
2026 | break; | ||
2027 | case AC2_VI: | ||
2028 | acm_ctrl |= AcmHw_ViqEn; | ||
2029 | break; | ||
2030 | case AC3_VO: | ||
2031 | acm_ctrl |= AcmHw_VoqEn; | ||
2032 | break; | ||
2033 | default: | ||
2034 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | ||
2035 | ("HW_VAR_ACM_CTRL acm set " | ||
2036 | "failed: eACI is %d\n", acm)); | ||
2037 | break; | ||
2038 | } | ||
2039 | } else { | ||
2040 | switch (e_aci) { | ||
2041 | case AC0_BE: | ||
2042 | acm_ctrl &= (~AcmHw_BeqEn); | ||
2043 | break; | ||
2044 | case AC2_VI: | ||
2045 | acm_ctrl &= (~AcmHw_ViqEn); | ||
2046 | break; | ||
2047 | case AC3_VO: | ||
2048 | acm_ctrl &= (~AcmHw_BeqEn); | ||
2049 | break; | ||
2050 | default: | ||
2051 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
2052 | ("switch case not process\n")); | ||
2053 | break; | ||
2054 | } | ||
2055 | } | ||
2056 | RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE, | ||
2057 | ("SetHwReg8190pci(): [HW_VAR_ACM_CTRL] " | ||
2058 | "Write 0x%X\n", acm_ctrl)); | ||
2059 | rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl); | ||
2060 | break; | ||
2061 | } | ||
2062 | case HW_VAR_RCR:{ | ||
2063 | rtl_write_dword(rtlpriv, REG_RCR, ((u32 *) (val))[0]); | ||
2064 | mac->rx_conf = ((u32 *) (val))[0]; | ||
2065 | RT_TRACE(rtlpriv, COMP_RECV, DBG_DMESG, | ||
2066 | ("### Set RCR(0x%08x) ###\n", mac->rx_conf)); | ||
2067 | break; | ||
2068 | } | ||
2069 | case HW_VAR_RETRY_LIMIT:{ | ||
2070 | u8 retry_limit = ((u8 *) (val))[0]; | ||
2071 | |||
2072 | rtl_write_word(rtlpriv, REG_RL, | ||
2073 | retry_limit << RETRY_LIMIT_SHORT_SHIFT | | ||
2074 | retry_limit << RETRY_LIMIT_LONG_SHIFT); | ||
2075 | RT_TRACE(rtlpriv, COMP_MLME, DBG_DMESG, ("Set HW_VAR_R" | ||
2076 | "ETRY_LIMIT(0x%08x)\n", retry_limit)); | ||
2077 | break; | ||
2078 | } | ||
2079 | case HW_VAR_DUAL_TSF_RST: | ||
2080 | rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1))); | ||
2081 | break; | ||
2082 | case HW_VAR_EFUSE_BYTES: | ||
2083 | rtlefuse->efuse_usedbytes = *((u16 *) val); | ||
2084 | break; | ||
2085 | case HW_VAR_EFUSE_USAGE: | ||
2086 | rtlefuse->efuse_usedpercentage = *((u8 *) val); | ||
2087 | break; | ||
2088 | case HW_VAR_IO_CMD: | ||
2089 | rtl92c_phy_set_io_cmd(hw, (*(enum io_type *)val)); | ||
2090 | break; | ||
2091 | case HW_VAR_WPA_CONFIG: | ||
2092 | rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *) val)); | ||
2093 | break; | ||
2094 | case HW_VAR_SET_RPWM:{ | ||
2095 | u8 rpwm_val = rtl_read_byte(rtlpriv, REG_USB_HRPWM); | ||
2096 | |||
2097 | if (rpwm_val & BIT(7)) | ||
2098 | rtl_write_byte(rtlpriv, REG_USB_HRPWM, | ||
2099 | (*(u8 *)val)); | ||
2100 | else | ||
2101 | rtl_write_byte(rtlpriv, REG_USB_HRPWM, | ||
2102 | ((*(u8 *)val) | BIT(7))); | ||
2103 | break; | ||
2104 | } | ||
2105 | case HW_VAR_H2C_FW_PWRMODE:{ | ||
2106 | u8 psmode = (*(u8 *) val); | ||
2107 | |||
2108 | if ((psmode != FW_PS_ACTIVE_MODE) && | ||
2109 | (!IS_92C_SERIAL(rtlhal->version))) | ||
2110 | rtl92c_dm_rf_saving(hw, true); | ||
2111 | rtl92c_set_fw_pwrmode_cmd(hw, (*(u8 *) val)); | ||
2112 | break; | ||
2113 | } | ||
2114 | case HW_VAR_FW_PSMODE_STATUS: | ||
2115 | ppsc->fw_current_inpsmode = *((bool *) val); | ||
2116 | break; | ||
2117 | case HW_VAR_H2C_FW_JOINBSSRPT:{ | ||
2118 | u8 mstatus = (*(u8 *) val); | ||
2119 | u8 tmp_reg422; | ||
2120 | bool recover = false; | ||
2121 | |||
2122 | if (mstatus == RT_MEDIA_CONNECT) { | ||
2123 | rtlpriv->cfg->ops->set_hw_reg(hw, | ||
2124 | HW_VAR_AID, NULL); | ||
2125 | rtl_write_byte(rtlpriv, REG_CR + 1, 0x03); | ||
2126 | _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(3)); | ||
2127 | _rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0); | ||
2128 | tmp_reg422 = rtl_read_byte(rtlpriv, | ||
2129 | REG_FWHW_TXQ_CTRL + 2); | ||
2130 | if (tmp_reg422 & BIT(6)) | ||
2131 | recover = true; | ||
2132 | rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, | ||
2133 | tmp_reg422 & (~BIT(6))); | ||
2134 | rtl92c_set_fw_rsvdpagepkt(hw, 0); | ||
2135 | _rtl92cu_set_bcn_ctrl_reg(hw, BIT(3), 0); | ||
2136 | _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(4)); | ||
2137 | if (recover) | ||
2138 | rtl_write_byte(rtlpriv, | ||
2139 | REG_FWHW_TXQ_CTRL + 2, | ||
2140 | tmp_reg422 | BIT(6)); | ||
2141 | rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); | ||
2142 | } | ||
2143 | rtl92c_set_fw_joinbss_report_cmd(hw, (*(u8 *) val)); | ||
2144 | break; | ||
2145 | } | ||
2146 | case HW_VAR_AID:{ | ||
2147 | u16 u2btmp; | ||
2148 | |||
2149 | u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT); | ||
2150 | u2btmp &= 0xC000; | ||
2151 | rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, | ||
2152 | (u2btmp | mac->assoc_id)); | ||
2153 | break; | ||
2154 | } | ||
2155 | case HW_VAR_CORRECT_TSF:{ | ||
2156 | u8 btype_ibss = ((u8 *) (val))[0]; | ||
2157 | |||
2158 | if (btype_ibss == true) | ||
2159 | _rtl92cu_stop_tx_beacon(hw); | ||
2160 | _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(3)); | ||
2161 | rtl_write_dword(rtlpriv, REG_TSFTR, (u32)(mac->tsf & | ||
2162 | 0xffffffff)); | ||
2163 | rtl_write_dword(rtlpriv, REG_TSFTR + 4, | ||
2164 | (u32)((mac->tsf >> 32) & 0xffffffff)); | ||
2165 | _rtl92cu_set_bcn_ctrl_reg(hw, BIT(3), 0); | ||
2166 | if (btype_ibss == true) | ||
2167 | _rtl92cu_resume_tx_beacon(hw); | ||
2168 | break; | ||
2169 | } | ||
2170 | case HW_VAR_MGT_FILTER: | ||
2171 | rtl_write_word(rtlpriv, REG_RXFLTMAP0, *(u16 *)val); | ||
2172 | break; | ||
2173 | case HW_VAR_CTRL_FILTER: | ||
2174 | rtl_write_word(rtlpriv, REG_RXFLTMAP1, *(u16 *)val); | ||
2175 | break; | ||
2176 | case HW_VAR_DATA_FILTER: | ||
2177 | rtl_write_word(rtlpriv, REG_RXFLTMAP2, *(u16 *)val); | ||
2178 | break; | ||
2179 | default: | ||
2180 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case " | ||
2181 | "not process\n")); | ||
2182 | break; | ||
2183 | } | ||
2184 | } | ||
2185 | |||
2186 | void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw) | ||
2187 | { | ||
2188 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2189 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
2190 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
2191 | u32 ratr_value = (u32) mac->basic_rates; | ||
2192 | u8 *mcsrate = mac->mcs; | ||
2193 | u8 ratr_index = 0; | ||
2194 | u8 nmode = mac->ht_enable; | ||
2195 | u8 mimo_ps = 1; | ||
2196 | u16 shortgi_rate = 0; | ||
2197 | u32 tmp_ratr_value = 0; | ||
2198 | u8 curtxbw_40mhz = mac->bw_40; | ||
2199 | u8 curshortgi_40mhz = mac->sgi_40; | ||
2200 | u8 curshortgi_20mhz = mac->sgi_20; | ||
2201 | enum wireless_mode wirelessmode = mac->mode; | ||
2202 | |||
2203 | ratr_value |= ((*(u16 *) (mcsrate))) << 12; | ||
2204 | switch (wirelessmode) { | ||
2205 | case WIRELESS_MODE_B: | ||
2206 | if (ratr_value & 0x0000000c) | ||
2207 | ratr_value &= 0x0000000d; | ||
2208 | else | ||
2209 | ratr_value &= 0x0000000f; | ||
2210 | break; | ||
2211 | case WIRELESS_MODE_G: | ||
2212 | ratr_value &= 0x00000FF5; | ||
2213 | break; | ||
2214 | case WIRELESS_MODE_N_24G: | ||
2215 | case WIRELESS_MODE_N_5G: | ||
2216 | nmode = 1; | ||
2217 | if (mimo_ps == 0) { | ||
2218 | ratr_value &= 0x0007F005; | ||
2219 | } else { | ||
2220 | u32 ratr_mask; | ||
2221 | |||
2222 | if (get_rf_type(rtlphy) == RF_1T2R || | ||
2223 | get_rf_type(rtlphy) == RF_1T1R) | ||
2224 | ratr_mask = 0x000ff005; | ||
2225 | else | ||
2226 | ratr_mask = 0x0f0ff005; | ||
2227 | if (curtxbw_40mhz) | ||
2228 | ratr_mask |= 0x00000010; | ||
2229 | ratr_value &= ratr_mask; | ||
2230 | } | ||
2231 | break; | ||
2232 | default: | ||
2233 | if (rtlphy->rf_type == RF_1T2R) | ||
2234 | ratr_value &= 0x000ff0ff; | ||
2235 | else | ||
2236 | ratr_value &= 0x0f0ff0ff; | ||
2237 | break; | ||
2238 | } | ||
2239 | ratr_value &= 0x0FFFFFFF; | ||
2240 | if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) || | ||
2241 | (!curtxbw_40mhz && curshortgi_20mhz))) { | ||
2242 | ratr_value |= 0x10000000; | ||
2243 | tmp_ratr_value = (ratr_value >> 12); | ||
2244 | for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) { | ||
2245 | if ((1 << shortgi_rate) & tmp_ratr_value) | ||
2246 | break; | ||
2247 | } | ||
2248 | shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) | | ||
2249 | (shortgi_rate << 4) | (shortgi_rate); | ||
2250 | } | ||
2251 | rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); | ||
2252 | RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("%x\n", rtl_read_dword(rtlpriv, | ||
2253 | REG_ARFR0))); | ||
2254 | } | ||
2255 | |||
2256 | void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) | ||
2257 | { | ||
2258 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2259 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
2260 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
2261 | u32 ratr_bitmap = (u32) mac->basic_rates; | ||
2262 | u8 *p_mcsrate = mac->mcs; | ||
2263 | u8 ratr_index = 0; | ||
2264 | u8 curtxbw_40mhz = mac->bw_40; | ||
2265 | u8 curshortgi_40mhz = mac->sgi_40; | ||
2266 | u8 curshortgi_20mhz = mac->sgi_20; | ||
2267 | enum wireless_mode wirelessmode = mac->mode; | ||
2268 | bool shortgi = false; | ||
2269 | u8 rate_mask[5]; | ||
2270 | u8 macid = 0; | ||
2271 | u8 mimops = 1; | ||
2272 | |||
2273 | ratr_bitmap |= (p_mcsrate[1] << 20) | (p_mcsrate[0] << 12); | ||
2274 | switch (wirelessmode) { | ||
2275 | case WIRELESS_MODE_B: | ||
2276 | ratr_index = RATR_INX_WIRELESS_B; | ||
2277 | if (ratr_bitmap & 0x0000000c) | ||
2278 | ratr_bitmap &= 0x0000000d; | ||
2279 | else | ||
2280 | ratr_bitmap &= 0x0000000f; | ||
2281 | break; | ||
2282 | case WIRELESS_MODE_G: | ||
2283 | ratr_index = RATR_INX_WIRELESS_GB; | ||
2284 | if (rssi_level == 1) | ||
2285 | ratr_bitmap &= 0x00000f00; | ||
2286 | else if (rssi_level == 2) | ||
2287 | ratr_bitmap &= 0x00000ff0; | ||
2288 | else | ||
2289 | ratr_bitmap &= 0x00000ff5; | ||
2290 | break; | ||
2291 | case WIRELESS_MODE_A: | ||
2292 | ratr_index = RATR_INX_WIRELESS_A; | ||
2293 | ratr_bitmap &= 0x00000ff0; | ||
2294 | break; | ||
2295 | case WIRELESS_MODE_N_24G: | ||
2296 | case WIRELESS_MODE_N_5G: | ||
2297 | ratr_index = RATR_INX_WIRELESS_NGB; | ||
2298 | if (mimops == 0) { | ||
2299 | if (rssi_level == 1) | ||
2300 | ratr_bitmap &= 0x00070000; | ||
2301 | else if (rssi_level == 2) | ||
2302 | ratr_bitmap &= 0x0007f000; | ||
2303 | else | ||
2304 | ratr_bitmap &= 0x0007f005; | ||
2305 | } else { | ||
2306 | if (rtlphy->rf_type == RF_1T2R || | ||
2307 | rtlphy->rf_type == RF_1T1R) { | ||
2308 | if (curtxbw_40mhz) { | ||
2309 | if (rssi_level == 1) | ||
2310 | ratr_bitmap &= 0x000f0000; | ||
2311 | else if (rssi_level == 2) | ||
2312 | ratr_bitmap &= 0x000ff000; | ||
2313 | else | ||
2314 | ratr_bitmap &= 0x000ff015; | ||
2315 | } else { | ||
2316 | if (rssi_level == 1) | ||
2317 | ratr_bitmap &= 0x000f0000; | ||
2318 | else if (rssi_level == 2) | ||
2319 | ratr_bitmap &= 0x000ff000; | ||
2320 | else | ||
2321 | ratr_bitmap &= 0x000ff005; | ||
2322 | } | ||
2323 | } else { | ||
2324 | if (curtxbw_40mhz) { | ||
2325 | if (rssi_level == 1) | ||
2326 | ratr_bitmap &= 0x0f0f0000; | ||
2327 | else if (rssi_level == 2) | ||
2328 | ratr_bitmap &= 0x0f0ff000; | ||
2329 | else | ||
2330 | ratr_bitmap &= 0x0f0ff015; | ||
2331 | } else { | ||
2332 | if (rssi_level == 1) | ||
2333 | ratr_bitmap &= 0x0f0f0000; | ||
2334 | else if (rssi_level == 2) | ||
2335 | ratr_bitmap &= 0x0f0ff000; | ||
2336 | else | ||
2337 | ratr_bitmap &= 0x0f0ff005; | ||
2338 | } | ||
2339 | } | ||
2340 | } | ||
2341 | if ((curtxbw_40mhz && curshortgi_40mhz) || | ||
2342 | (!curtxbw_40mhz && curshortgi_20mhz)) { | ||
2343 | if (macid == 0) | ||
2344 | shortgi = true; | ||
2345 | else if (macid == 1) | ||
2346 | shortgi = false; | ||
2347 | } | ||
2348 | break; | ||
2349 | default: | ||
2350 | ratr_index = RATR_INX_WIRELESS_NGB; | ||
2351 | if (rtlphy->rf_type == RF_1T2R) | ||
2352 | ratr_bitmap &= 0x000ff0ff; | ||
2353 | else | ||
2354 | ratr_bitmap &= 0x0f0ff0ff; | ||
2355 | break; | ||
2356 | } | ||
2357 | RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("ratr_bitmap :%x\n", | ||
2358 | ratr_bitmap)); | ||
2359 | *(u32 *)&rate_mask = ((ratr_bitmap & 0x0fffffff) | | ||
2360 | ratr_index << 28); | ||
2361 | rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; | ||
2362 | RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("Rate_index:%x, " | ||
2363 | "ratr_val:%x, %x:%x:%x:%x:%x\n", | ||
2364 | ratr_index, ratr_bitmap, | ||
2365 | rate_mask[0], rate_mask[1], | ||
2366 | rate_mask[2], rate_mask[3], | ||
2367 | rate_mask[4])); | ||
2368 | rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask); | ||
2369 | } | ||
2370 | |||
2371 | void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw) | ||
2372 | { | ||
2373 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2374 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
2375 | u16 sifs_timer; | ||
2376 | |||
2377 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, | ||
2378 | (u8 *)&mac->slot_time); | ||
2379 | if (!mac->ht_enable) | ||
2380 | sifs_timer = 0x0a0a; | ||
2381 | else | ||
2382 | sifs_timer = 0x0e0e; | ||
2383 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); | ||
2384 | } | ||
2385 | |||
2386 | bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid) | ||
2387 | { | ||
2388 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2389 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
2390 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
2391 | enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate; | ||
2392 | u8 u1tmp = 0; | ||
2393 | bool actuallyset = false; | ||
2394 | unsigned long flag = 0; | ||
2395 | /* to do - usb autosuspend */ | ||
2396 | u8 usb_autosuspend = 0; | ||
2397 | |||
2398 | if (ppsc->swrf_processing) | ||
2399 | return false; | ||
2400 | spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); | ||
2401 | if (ppsc->rfchange_inprogress) { | ||
2402 | spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); | ||
2403 | return false; | ||
2404 | } else { | ||
2405 | ppsc->rfchange_inprogress = true; | ||
2406 | spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); | ||
2407 | } | ||
2408 | cur_rfstate = ppsc->rfpwr_state; | ||
2409 | if (usb_autosuspend) { | ||
2410 | /* to do................... */ | ||
2411 | } else { | ||
2412 | if (ppsc->pwrdown_mode) { | ||
2413 | u1tmp = rtl_read_byte(rtlpriv, REG_HSISR); | ||
2414 | e_rfpowerstate_toset = (u1tmp & BIT(7)) ? | ||
2415 | ERFOFF : ERFON; | ||
2416 | RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, | ||
2417 | ("pwrdown, 0x5c(BIT7)=%02x\n", u1tmp)); | ||
2418 | } else { | ||
2419 | rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, | ||
2420 | rtl_read_byte(rtlpriv, | ||
2421 | REG_MAC_PINMUX_CFG) & ~(BIT(3))); | ||
2422 | u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL); | ||
2423 | e_rfpowerstate_toset = (u1tmp & BIT(3)) ? | ||
2424 | ERFON : ERFOFF; | ||
2425 | RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, | ||
2426 | ("GPIO_IN=%02x\n", u1tmp)); | ||
2427 | } | ||
2428 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("N-SS RF =%x\n", | ||
2429 | e_rfpowerstate_toset)); | ||
2430 | } | ||
2431 | if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) { | ||
2432 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("GPIOChangeRF - HW " | ||
2433 | "Radio ON, RF ON\n")); | ||
2434 | ppsc->hwradiooff = false; | ||
2435 | actuallyset = true; | ||
2436 | } else if ((!ppsc->hwradiooff) && (e_rfpowerstate_toset == | ||
2437 | ERFOFF)) { | ||
2438 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("GPIOChangeRF - HW" | ||
2439 | " Radio OFF\n")); | ||
2440 | ppsc->hwradiooff = true; | ||
2441 | actuallyset = true; | ||
2442 | } else { | ||
2443 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD , | ||
2444 | ("pHalData->bHwRadioOff and eRfPowerStateToSet do not" | ||
2445 | " match: pHalData->bHwRadioOff %x, eRfPowerStateToSet " | ||
2446 | "%x\n", ppsc->hwradiooff, e_rfpowerstate_toset)); | ||
2447 | } | ||
2448 | if (actuallyset) { | ||
2449 | ppsc->hwradiooff = 1; | ||
2450 | if (e_rfpowerstate_toset == ERFON) { | ||
2451 | if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && | ||
2452 | RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM)) | ||
2453 | RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); | ||
2454 | else if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_PCI_D3) | ||
2455 | && RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_PCI_D3)) | ||
2456 | RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_PCI_D3); | ||
2457 | } | ||
2458 | spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); | ||
2459 | ppsc->rfchange_inprogress = false; | ||
2460 | spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); | ||
2461 | /* For power down module, we need to enable register block | ||
2462 | * contrl reg at 0x1c. Then enable power down control bit | ||
2463 | * of register 0x04 BIT4 and BIT15 as 1. | ||
2464 | */ | ||
2465 | if (ppsc->pwrdown_mode && e_rfpowerstate_toset == ERFOFF) { | ||
2466 | /* Enable register area 0x0-0xc. */ | ||
2467 | rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0); | ||
2468 | if (IS_HARDWARE_TYPE_8723U(rtlhal)) { | ||
2469 | /* | ||
2470 | * We should configure HW PDn source for WiFi | ||
2471 | * ONLY, and then our HW will be set in | ||
2472 | * power-down mode if PDn source from all | ||
2473 | * functions are configured. | ||
2474 | */ | ||
2475 | u1tmp = rtl_read_byte(rtlpriv, | ||
2476 | REG_MULTI_FUNC_CTRL); | ||
2477 | rtl_write_byte(rtlpriv, REG_MULTI_FUNC_CTRL, | ||
2478 | (u1tmp|WL_HWPDN_EN)); | ||
2479 | } else { | ||
2480 | rtl_write_word(rtlpriv, REG_APS_FSMCO, 0x8812); | ||
2481 | } | ||
2482 | } | ||
2483 | if (e_rfpowerstate_toset == ERFOFF) { | ||
2484 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) | ||
2485 | RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); | ||
2486 | else if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_PCI_D3) | ||
2487 | RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_PCI_D3); | ||
2488 | } | ||
2489 | } else if (e_rfpowerstate_toset == ERFOFF || cur_rfstate == ERFOFF) { | ||
2490 | /* Enter D3 or ASPM after GPIO had been done. */ | ||
2491 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) | ||
2492 | RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); | ||
2493 | else if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_PCI_D3) | ||
2494 | RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_PCI_D3); | ||
2495 | spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); | ||
2496 | ppsc->rfchange_inprogress = false; | ||
2497 | spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); | ||
2498 | } else { | ||
2499 | spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); | ||
2500 | ppsc->rfchange_inprogress = false; | ||
2501 | spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); | ||
2502 | } | ||
2503 | *valid = 1; | ||
2504 | return !ppsc->hwradiooff; | ||
2505 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h new file mode 100644 index 000000000000..3c0ea5ea6db5 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h | |||
@@ -0,0 +1,107 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 Realtek Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #ifndef __RTL92CU_HW_H__ | ||
31 | #define __RTL92CU_HW_H__ | ||
32 | |||
33 | #define LLT_POLLING_LLT_THRESHOLD 20 | ||
34 | #define LLT_POLLING_READY_TIMEOUT_COUNT 100 | ||
35 | #define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER 255 | ||
36 | |||
37 | #define RX_PAGE_SIZE_REG_VALUE PBP_128 | ||
38 | /* Note: We will divide number of page equally for each queue | ||
39 | * other than public queue! */ | ||
40 | #define TX_TOTAL_PAGE_NUMBER 0xF8 | ||
41 | #define TX_PAGE_BOUNDARY (TX_TOTAL_PAGE_NUMBER + 1) | ||
42 | |||
43 | |||
44 | #define CHIP_B_PAGE_NUM_PUBQ 0xE7 | ||
45 | |||
46 | /* For Test Chip Setting | ||
47 | * (HPQ + LPQ + PUBQ) shall be TX_TOTAL_PAGE_NUMBER */ | ||
48 | #define CHIP_A_PAGE_NUM_PUBQ 0x7E | ||
49 | |||
50 | |||
51 | /* For Chip A Setting */ | ||
52 | #define WMM_CHIP_A_TX_TOTAL_PAGE_NUMBER 0xF5 | ||
53 | #define WMM_CHIP_A_TX_PAGE_BOUNDARY \ | ||
54 | (WMM_CHIP_A_TX_TOTAL_PAGE_NUMBER + 1) /* F6 */ | ||
55 | |||
56 | #define WMM_CHIP_A_PAGE_NUM_PUBQ 0xA3 | ||
57 | #define WMM_CHIP_A_PAGE_NUM_HPQ 0x29 | ||
58 | #define WMM_CHIP_A_PAGE_NUM_LPQ 0x29 | ||
59 | |||
60 | |||
61 | |||
62 | /* Note: For Chip B Setting ,modify later */ | ||
63 | #define WMM_CHIP_B_TX_TOTAL_PAGE_NUMBER 0xF5 | ||
64 | #define WMM_CHIP_B_TX_PAGE_BOUNDARY \ | ||
65 | (WMM_CHIP_B_TX_TOTAL_PAGE_NUMBER + 1) /* F6 */ | ||
66 | |||
67 | #define WMM_CHIP_B_PAGE_NUM_PUBQ 0xB0 | ||
68 | #define WMM_CHIP_B_PAGE_NUM_HPQ 0x29 | ||
69 | #define WMM_CHIP_B_PAGE_NUM_LPQ 0x1C | ||
70 | #define WMM_CHIP_B_PAGE_NUM_NPQ 0x1C | ||
71 | |||
72 | #define BOARD_TYPE_NORMAL_MASK 0xE0 | ||
73 | #define BOARD_TYPE_TEST_MASK 0x0F | ||
74 | |||
75 | /* should be renamed and moved to another file */ | ||
76 | enum _BOARD_TYPE_8192CUSB { | ||
77 | BOARD_USB_DONGLE = 0, /* USB dongle */ | ||
78 | BOARD_USB_High_PA = 1, /* USB dongle - high power PA */ | ||
79 | BOARD_MINICARD = 2, /* Minicard */ | ||
80 | BOARD_USB_SOLO = 3, /* USB solo-Slim module */ | ||
81 | BOARD_USB_COMBO = 4, /* USB Combo-Slim module */ | ||
82 | }; | ||
83 | |||
84 | #define IS_HIGHT_PA(boardtype) \ | ||
85 | ((boardtype == BOARD_USB_High_PA) ? true : false) | ||
86 | |||
87 | #define RTL92C_DRIVER_INFO_SIZE 4 | ||
88 | void rtl92cu_read_eeprom_info(struct ieee80211_hw *hw); | ||
89 | void rtl92cu_enable_hw_security_config(struct ieee80211_hw *hw); | ||
90 | int rtl92cu_hw_init(struct ieee80211_hw *hw); | ||
91 | void rtl92cu_card_disable(struct ieee80211_hw *hw); | ||
92 | int rtl92cu_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type); | ||
93 | void rtl92cu_set_beacon_related_registers(struct ieee80211_hw *hw); | ||
94 | void rtl92cu_set_beacon_interval(struct ieee80211_hw *hw); | ||
95 | void rtl92cu_update_interrupt_mask(struct ieee80211_hw *hw, | ||
96 | u32 add_msr, u32 rm_msr); | ||
97 | void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); | ||
98 | void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); | ||
99 | void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw); | ||
100 | void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level); | ||
101 | |||
102 | void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw); | ||
103 | bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid); | ||
104 | void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid); | ||
105 | u8 _rtl92c_get_chnl_group(u8 chnl); | ||
106 | |||
107 | #endif | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/led.c b/drivers/net/wireless/rtlwifi/rtl8192cu/led.c new file mode 100644 index 000000000000..332c74348a69 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/led.c | |||
@@ -0,0 +1,142 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | *****************************************************************************/ | ||
27 | |||
28 | #include "../wifi.h" | ||
29 | #include "../usb.h" | ||
30 | #include "reg.h" | ||
31 | #include "led.h" | ||
32 | |||
33 | static void _rtl92cu_init_led(struct ieee80211_hw *hw, | ||
34 | struct rtl_led *pled, enum rtl_led_pin ledpin) | ||
35 | { | ||
36 | pled->hw = hw; | ||
37 | pled->ledpin = ledpin; | ||
38 | pled->ledon = false; | ||
39 | } | ||
40 | |||
41 | static void _rtl92cu_deInit_led(struct rtl_led *pled) | ||
42 | { | ||
43 | } | ||
44 | |||
45 | void rtl92cu_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) | ||
46 | { | ||
47 | u8 ledcfg; | ||
48 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
49 | |||
50 | RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, | ||
51 | ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin)); | ||
52 | ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); | ||
53 | switch (pled->ledpin) { | ||
54 | case LED_PIN_GPIO0: | ||
55 | break; | ||
56 | case LED_PIN_LED0: | ||
57 | rtl_write_byte(rtlpriv, | ||
58 | REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5) | BIT(6)); | ||
59 | break; | ||
60 | case LED_PIN_LED1: | ||
61 | rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0x0f) | BIT(5)); | ||
62 | break; | ||
63 | default: | ||
64 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
65 | ("switch case not process\n")); | ||
66 | break; | ||
67 | } | ||
68 | pled->ledon = true; | ||
69 | } | ||
70 | |||
71 | void rtl92cu_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) | ||
72 | { | ||
73 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
74 | struct rtl_usb_priv *usbpriv = rtl_usbpriv(hw); | ||
75 | u8 ledcfg; | ||
76 | |||
77 | RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, | ||
78 | ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin)); | ||
79 | ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); | ||
80 | switch (pled->ledpin) { | ||
81 | case LED_PIN_GPIO0: | ||
82 | break; | ||
83 | case LED_PIN_LED0: | ||
84 | ledcfg &= 0xf0; | ||
85 | if (usbpriv->ledctl.led_opendrain == true) | ||
86 | rtl_write_byte(rtlpriv, REG_LEDCFG2, | ||
87 | (ledcfg | BIT(1) | BIT(5) | BIT(6))); | ||
88 | else | ||
89 | rtl_write_byte(rtlpriv, REG_LEDCFG2, | ||
90 | (ledcfg | BIT(3) | BIT(5) | BIT(6))); | ||
91 | break; | ||
92 | case LED_PIN_LED1: | ||
93 | ledcfg &= 0x0f; | ||
94 | rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(3))); | ||
95 | break; | ||
96 | default: | ||
97 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
98 | ("switch case not process\n")); | ||
99 | break; | ||
100 | } | ||
101 | pled->ledon = false; | ||
102 | } | ||
103 | |||
104 | void rtl92cu_init_sw_leds(struct ieee80211_hw *hw) | ||
105 | { | ||
106 | struct rtl_usb_priv *usbpriv = rtl_usbpriv(hw); | ||
107 | _rtl92cu_init_led(hw, &(usbpriv->ledctl.sw_led0), LED_PIN_LED0); | ||
108 | _rtl92cu_init_led(hw, &(usbpriv->ledctl.sw_led1), LED_PIN_LED1); | ||
109 | } | ||
110 | |||
111 | void rtl92cu_deinit_sw_leds(struct ieee80211_hw *hw) | ||
112 | { | ||
113 | struct rtl_usb_priv *usbpriv = rtl_usbpriv(hw); | ||
114 | _rtl92cu_deInit_led(&(usbpriv->ledctl.sw_led0)); | ||
115 | _rtl92cu_deInit_led(&(usbpriv->ledctl.sw_led1)); | ||
116 | } | ||
117 | |||
118 | static void _rtl92cu_sw_led_control(struct ieee80211_hw *hw, | ||
119 | enum led_ctl_mode ledaction) | ||
120 | { | ||
121 | } | ||
122 | |||
123 | void rtl92cu_led_control(struct ieee80211_hw *hw, | ||
124 | enum led_ctl_mode ledaction) | ||
125 | { | ||
126 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
127 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
128 | |||
129 | if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) && | ||
130 | (ledaction == LED_CTL_TX || | ||
131 | ledaction == LED_CTL_RX || | ||
132 | ledaction == LED_CTL_SITE_SURVEY || | ||
133 | ledaction == LED_CTL_LINK || | ||
134 | ledaction == LED_CTL_NO_LINK || | ||
135 | ledaction == LED_CTL_START_TO_LINK || | ||
136 | ledaction == LED_CTL_POWER_ON)) { | ||
137 | return; | ||
138 | } | ||
139 | RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n", | ||
140 | ledaction)); | ||
141 | _rtl92cu_sw_led_control(hw, ledaction); | ||
142 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/led.h b/drivers/net/wireless/rtlwifi/rtl8192cu/led.h new file mode 100644 index 000000000000..decaee4d1eb1 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/led.h | |||
@@ -0,0 +1,37 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | *****************************************************************************/ | ||
27 | |||
28 | #ifndef __RTL92CU_LED_H__ | ||
29 | #define __RTL92CU_LED_H__ | ||
30 | |||
31 | void rtl92cu_init_sw_leds(struct ieee80211_hw *hw); | ||
32 | void rtl92cu_deinit_sw_leds(struct ieee80211_hw *hw); | ||
33 | void rtl92cu_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled); | ||
34 | void rtl92cu_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled); | ||
35 | void rtl92cu_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction); | ||
36 | |||
37 | #endif | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c new file mode 100644 index 000000000000..f8514cba17b6 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c | |||
@@ -0,0 +1,1144 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | ****************************************************************************/ | ||
29 | #include <linux/module.h> | ||
30 | |||
31 | #include "../wifi.h" | ||
32 | #include "../pci.h" | ||
33 | #include "../usb.h" | ||
34 | #include "../ps.h" | ||
35 | #include "../cam.h" | ||
36 | #include "reg.h" | ||
37 | #include "def.h" | ||
38 | #include "phy.h" | ||
39 | #include "rf.h" | ||
40 | #include "dm.h" | ||
41 | #include "mac.h" | ||
42 | #include "trx.h" | ||
43 | |||
44 | /* macro to shorten lines */ | ||
45 | |||
46 | #define LINK_Q ui_link_quality | ||
47 | #define RX_EVM rx_evm_percentage | ||
48 | #define RX_SIGQ rx_mimo_signalquality | ||
49 | |||
50 | |||
51 | void rtl92c_read_chip_version(struct ieee80211_hw *hw) | ||
52 | { | ||
53 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
54 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
55 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | ||
56 | enum version_8192c chip_version = VERSION_UNKNOWN; | ||
57 | u32 value32; | ||
58 | |||
59 | value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG); | ||
60 | if (value32 & TRP_VAUX_EN) { | ||
61 | chip_version = (value32 & TYPE_ID) ? VERSION_TEST_CHIP_92C : | ||
62 | VERSION_TEST_CHIP_88C; | ||
63 | } else { | ||
64 | /* Normal mass production chip. */ | ||
65 | chip_version = NORMAL_CHIP; | ||
66 | chip_version |= ((value32 & TYPE_ID) ? CHIP_92C : 0); | ||
67 | chip_version |= ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : 0); | ||
68 | /* RTL8723 with BT function. */ | ||
69 | chip_version |= ((value32 & BT_FUNC) ? CHIP_8723 : 0); | ||
70 | if (IS_VENDOR_UMC(chip_version)) | ||
71 | chip_version |= ((value32 & CHIP_VER_RTL_MASK) ? | ||
72 | CHIP_VENDOR_UMC_B_CUT : 0); | ||
73 | if (IS_92C_SERIAL(chip_version)) { | ||
74 | value32 = rtl_read_dword(rtlpriv, REG_HPON_FSM); | ||
75 | chip_version |= ((CHIP_BONDING_IDENTIFIER(value32) == | ||
76 | CHIP_BONDING_92C_1T2R) ? CHIP_92C_1T2R : 0); | ||
77 | } else if (IS_8723_SERIES(chip_version)) { | ||
78 | value32 = rtl_read_dword(rtlpriv, REG_GPIO_OUTSTS); | ||
79 | chip_version |= ((value32 & RF_RL_ID) ? | ||
80 | CHIP_8723_DRV_REV : 0); | ||
81 | } | ||
82 | } | ||
83 | rtlhal->version = (enum version_8192c)chip_version; | ||
84 | switch (rtlhal->version) { | ||
85 | case VERSION_NORMAL_TSMC_CHIP_92C_1T2R: | ||
86 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
87 | ("Chip Version ID: VERSION_B_CHIP_92C.\n")); | ||
88 | break; | ||
89 | case VERSION_NORMAL_TSMC_CHIP_92C: | ||
90 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
91 | ("Chip Version ID: VERSION_NORMAL_TSMC_CHIP_92C.\n")); | ||
92 | break; | ||
93 | case VERSION_NORMAL_TSMC_CHIP_88C: | ||
94 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
95 | ("Chip Version ID: VERSION_NORMAL_TSMC_CHIP_88C.\n")); | ||
96 | break; | ||
97 | case VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT: | ||
98 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
99 | ("Chip Version ID: VERSION_NORMAL_UMC_CHIP_i" | ||
100 | "92C_1T2R_A_CUT.\n")); | ||
101 | break; | ||
102 | case VERSION_NORMAL_UMC_CHIP_92C_A_CUT: | ||
103 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
104 | ("Chip Version ID: VERSION_NORMAL_UMC_CHIP_" | ||
105 | "92C_A_CUT.\n")); | ||
106 | break; | ||
107 | case VERSION_NORMAL_UMC_CHIP_88C_A_CUT: | ||
108 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
109 | ("Chip Version ID: VERSION_NORMAL_UMC_CHIP" | ||
110 | "_88C_A_CUT.\n")); | ||
111 | break; | ||
112 | case VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT: | ||
113 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
114 | ("Chip Version ID: VERSION_NORMAL_UMC_CHIP" | ||
115 | "_92C_1T2R_B_CUT.\n")); | ||
116 | break; | ||
117 | case VERSION_NORMAL_UMC_CHIP_92C_B_CUT: | ||
118 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
119 | ("Chip Version ID: VERSION_NORMAL_UMC_CHIP" | ||
120 | "_92C_B_CUT.\n")); | ||
121 | break; | ||
122 | case VERSION_NORMAL_UMC_CHIP_88C_B_CUT: | ||
123 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
124 | ("Chip Version ID: VERSION_NORMAL_UMC_CHIP" | ||
125 | "_88C_B_CUT.\n")); | ||
126 | break; | ||
127 | case VERSION_NORMA_UMC_CHIP_8723_1T1R_A_CUT: | ||
128 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
129 | ("Chip Version ID: VERSION_NORMA_UMC_CHIP" | ||
130 | "_8723_1T1R_A_CUT.\n")); | ||
131 | break; | ||
132 | case VERSION_NORMA_UMC_CHIP_8723_1T1R_B_CUT: | ||
133 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
134 | ("Chip Version ID: VERSION_NORMA_UMC_CHIP" | ||
135 | "_8723_1T1R_B_CUT.\n")); | ||
136 | break; | ||
137 | case VERSION_TEST_CHIP_92C: | ||
138 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
139 | ("Chip Version ID: VERSION_TEST_CHIP_92C.\n")); | ||
140 | break; | ||
141 | case VERSION_TEST_CHIP_88C: | ||
142 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
143 | ("Chip Version ID: VERSION_TEST_CHIP_88C.\n")); | ||
144 | break; | ||
145 | default: | ||
146 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
147 | ("Chip Version ID: ???????????????.\n")); | ||
148 | break; | ||
149 | } | ||
150 | if (IS_92C_SERIAL(rtlhal->version)) | ||
151 | rtlphy->rf_type = | ||
152 | (IS_92C_1T2R(rtlhal->version)) ? RF_1T2R : RF_2T2R; | ||
153 | else | ||
154 | rtlphy->rf_type = RF_1T1R; | ||
155 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, | ||
156 | ("Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ? | ||
157 | "RF_2T2R" : "RF_1T1R")); | ||
158 | if (get_rf_type(rtlphy) == RF_1T1R) | ||
159 | rtlpriv->dm.rfpath_rxenable[0] = true; | ||
160 | else | ||
161 | rtlpriv->dm.rfpath_rxenable[0] = | ||
162 | rtlpriv->dm.rfpath_rxenable[1] = true; | ||
163 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("VersionID = 0x%4x\n", | ||
164 | rtlhal->version)); | ||
165 | } | ||
166 | |||
167 | /** | ||
168 | * writeLLT - LLT table write access | ||
169 | * @io: io callback | ||
170 | * @address: LLT logical address. | ||
171 | * @data: LLT data content | ||
172 | * | ||
173 | * Realtek hardware access function. | ||
174 | * | ||
175 | */ | ||
176 | bool rtl92c_llt_write(struct ieee80211_hw *hw, u32 address, u32 data) | ||
177 | { | ||
178 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
179 | bool status = true; | ||
180 | long count = 0; | ||
181 | u32 value = _LLT_INIT_ADDR(address) | | ||
182 | _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS); | ||
183 | |||
184 | rtl_write_dword(rtlpriv, REG_LLT_INIT, value); | ||
185 | do { | ||
186 | value = rtl_read_dword(rtlpriv, REG_LLT_INIT); | ||
187 | if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) | ||
188 | break; | ||
189 | if (count > POLLING_LLT_THRESHOLD) { | ||
190 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
191 | ("Failed to polling write LLT done at" | ||
192 | " address %d! _LLT_OP_VALUE(%x)\n", | ||
193 | address, _LLT_OP_VALUE(value))); | ||
194 | status = false; | ||
195 | break; | ||
196 | } | ||
197 | } while (++count); | ||
198 | return status; | ||
199 | } | ||
200 | /** | ||
201 | * rtl92c_init_LLT_table - Init LLT table | ||
202 | * @io: io callback | ||
203 | * @boundary: | ||
204 | * | ||
205 | * Realtek hardware access function. | ||
206 | * | ||
207 | */ | ||
208 | bool rtl92c_init_llt_table(struct ieee80211_hw *hw, u32 boundary) | ||
209 | { | ||
210 | bool rst = true; | ||
211 | u32 i; | ||
212 | |||
213 | for (i = 0; i < (boundary - 1); i++) { | ||
214 | rst = rtl92c_llt_write(hw, i , i + 1); | ||
215 | if (true != rst) { | ||
216 | printk(KERN_ERR "===> %s #1 fail\n", __func__); | ||
217 | return rst; | ||
218 | } | ||
219 | } | ||
220 | /* end of list */ | ||
221 | rst = rtl92c_llt_write(hw, (boundary - 1), 0xFF); | ||
222 | if (true != rst) { | ||
223 | printk(KERN_ERR "===> %s #2 fail\n", __func__); | ||
224 | return rst; | ||
225 | } | ||
226 | /* Make the other pages as ring buffer | ||
227 | * This ring buffer is used as beacon buffer if we config this MAC | ||
228 | * as two MAC transfer. | ||
229 | * Otherwise used as local loopback buffer. | ||
230 | */ | ||
231 | for (i = boundary; i < LLT_LAST_ENTRY_OF_TX_PKT_BUFFER; i++) { | ||
232 | rst = rtl92c_llt_write(hw, i, (i + 1)); | ||
233 | if (true != rst) { | ||
234 | printk(KERN_ERR "===> %s #3 fail\n", __func__); | ||
235 | return rst; | ||
236 | } | ||
237 | } | ||
238 | /* Let last entry point to the start entry of ring buffer */ | ||
239 | rst = rtl92c_llt_write(hw, LLT_LAST_ENTRY_OF_TX_PKT_BUFFER, boundary); | ||
240 | if (true != rst) { | ||
241 | printk(KERN_ERR "===> %s #4 fail\n", __func__); | ||
242 | return rst; | ||
243 | } | ||
244 | return rst; | ||
245 | } | ||
246 | void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index, | ||
247 | u8 *p_macaddr, bool is_group, u8 enc_algo, | ||
248 | bool is_wepkey, bool clear_all) | ||
249 | { | ||
250 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
251 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
252 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
253 | u8 *macaddr = p_macaddr; | ||
254 | u32 entry_id = 0; | ||
255 | bool is_pairwise = false; | ||
256 | static u8 cam_const_addr[4][6] = { | ||
257 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, | ||
258 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, | ||
259 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, | ||
260 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} | ||
261 | }; | ||
262 | static u8 cam_const_broad[] = { | ||
263 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff | ||
264 | }; | ||
265 | |||
266 | if (clear_all) { | ||
267 | u8 idx = 0; | ||
268 | u8 cam_offset = 0; | ||
269 | u8 clear_number = 5; | ||
270 | |||
271 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n")); | ||
272 | for (idx = 0; idx < clear_number; idx++) { | ||
273 | rtl_cam_mark_invalid(hw, cam_offset + idx); | ||
274 | rtl_cam_empty_entry(hw, cam_offset + idx); | ||
275 | if (idx < 5) { | ||
276 | memset(rtlpriv->sec.key_buf[idx], 0, | ||
277 | MAX_KEY_LEN); | ||
278 | rtlpriv->sec.key_len[idx] = 0; | ||
279 | } | ||
280 | } | ||
281 | } else { | ||
282 | switch (enc_algo) { | ||
283 | case WEP40_ENCRYPTION: | ||
284 | enc_algo = CAM_WEP40; | ||
285 | break; | ||
286 | case WEP104_ENCRYPTION: | ||
287 | enc_algo = CAM_WEP104; | ||
288 | break; | ||
289 | case TKIP_ENCRYPTION: | ||
290 | enc_algo = CAM_TKIP; | ||
291 | break; | ||
292 | case AESCCMP_ENCRYPTION: | ||
293 | enc_algo = CAM_AES; | ||
294 | break; | ||
295 | default: | ||
296 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
297 | ("iillegal switch case\n")); | ||
298 | enc_algo = CAM_TKIP; | ||
299 | break; | ||
300 | } | ||
301 | if (is_wepkey || rtlpriv->sec.use_defaultkey) { | ||
302 | macaddr = cam_const_addr[key_index]; | ||
303 | entry_id = key_index; | ||
304 | } else { | ||
305 | if (is_group) { | ||
306 | macaddr = cam_const_broad; | ||
307 | entry_id = key_index; | ||
308 | } else { | ||
309 | key_index = PAIRWISE_KEYIDX; | ||
310 | entry_id = CAM_PAIRWISE_KEY_POSITION; | ||
311 | is_pairwise = true; | ||
312 | } | ||
313 | } | ||
314 | if (rtlpriv->sec.key_len[key_index] == 0) { | ||
315 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | ||
316 | ("delete one entry\n")); | ||
317 | rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); | ||
318 | } else { | ||
319 | RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, | ||
320 | ("The insert KEY length is %d\n", | ||
321 | rtlpriv->sec.key_len[PAIRWISE_KEYIDX])); | ||
322 | RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, | ||
323 | ("The insert KEY is %x %x\n", | ||
324 | rtlpriv->sec.key_buf[0][0], | ||
325 | rtlpriv->sec.key_buf[0][1])); | ||
326 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | ||
327 | ("add one entry\n")); | ||
328 | if (is_pairwise) { | ||
329 | RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, | ||
330 | "Pairwiase Key content :", | ||
331 | rtlpriv->sec.pairwise_key, | ||
332 | rtlpriv->sec. | ||
333 | key_len[PAIRWISE_KEYIDX]); | ||
334 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | ||
335 | ("set Pairwiase key\n")); | ||
336 | |||
337 | rtl_cam_add_one_entry(hw, macaddr, key_index, | ||
338 | entry_id, enc_algo, | ||
339 | CAM_CONFIG_NO_USEDK, | ||
340 | rtlpriv->sec. | ||
341 | key_buf[key_index]); | ||
342 | } else { | ||
343 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | ||
344 | ("set group key\n")); | ||
345 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { | ||
346 | rtl_cam_add_one_entry(hw, | ||
347 | rtlefuse->dev_addr, | ||
348 | PAIRWISE_KEYIDX, | ||
349 | CAM_PAIRWISE_KEY_POSITION, | ||
350 | enc_algo, | ||
351 | CAM_CONFIG_NO_USEDK, | ||
352 | rtlpriv->sec.key_buf | ||
353 | [entry_id]); | ||
354 | } | ||
355 | rtl_cam_add_one_entry(hw, macaddr, key_index, | ||
356 | entry_id, enc_algo, | ||
357 | CAM_CONFIG_NO_USEDK, | ||
358 | rtlpriv->sec.key_buf[entry_id]); | ||
359 | } | ||
360 | } | ||
361 | } | ||
362 | } | ||
363 | |||
364 | u32 rtl92c_get_txdma_status(struct ieee80211_hw *hw) | ||
365 | { | ||
366 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
367 | |||
368 | return rtl_read_dword(rtlpriv, REG_TXDMA_STATUS); | ||
369 | } | ||
370 | |||
371 | void rtl92c_enable_interrupt(struct ieee80211_hw *hw) | ||
372 | { | ||
373 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
374 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
375 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
376 | struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); | ||
377 | |||
378 | if (IS_HARDWARE_TYPE_8192CE(rtlhal)) { | ||
379 | rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & | ||
380 | 0xFFFFFFFF); | ||
381 | rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & | ||
382 | 0xFFFFFFFF); | ||
383 | rtlpci->irq_enabled = true; | ||
384 | } else { | ||
385 | rtl_write_dword(rtlpriv, REG_HIMR, rtlusb->irq_mask[0] & | ||
386 | 0xFFFFFFFF); | ||
387 | rtl_write_dword(rtlpriv, REG_HIMRE, rtlusb->irq_mask[1] & | ||
388 | 0xFFFFFFFF); | ||
389 | rtlusb->irq_enabled = true; | ||
390 | } | ||
391 | } | ||
392 | |||
393 | void rtl92c_init_interrupt(struct ieee80211_hw *hw) | ||
394 | { | ||
395 | rtl92c_enable_interrupt(hw); | ||
396 | } | ||
397 | |||
398 | void rtl92c_disable_interrupt(struct ieee80211_hw *hw) | ||
399 | { | ||
400 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
401 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
402 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
403 | struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); | ||
404 | |||
405 | rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED); | ||
406 | rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED); | ||
407 | if (IS_HARDWARE_TYPE_8192CE(rtlhal)) | ||
408 | rtlpci->irq_enabled = false; | ||
409 | else if (IS_HARDWARE_TYPE_8192CU(rtlhal)) | ||
410 | rtlusb->irq_enabled = false; | ||
411 | } | ||
412 | |||
413 | void rtl92c_set_qos(struct ieee80211_hw *hw, int aci) | ||
414 | { | ||
415 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
416 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
417 | u32 u4b_ac_param; | ||
418 | |||
419 | rtl92c_dm_init_edca_turbo(hw); | ||
420 | u4b_ac_param = (u32) mac->ac[aci].aifs; | ||
421 | u4b_ac_param |= | ||
422 | ((u32) le16_to_cpu(mac->ac[aci].cw_min) & 0xF) << | ||
423 | AC_PARAM_ECW_MIN_OFFSET; | ||
424 | u4b_ac_param |= | ||
425 | ((u32) le16_to_cpu(mac->ac[aci].cw_max) & 0xF) << | ||
426 | AC_PARAM_ECW_MAX_OFFSET; | ||
427 | u4b_ac_param |= (u32) le16_to_cpu(mac->ac[aci].tx_op) << | ||
428 | AC_PARAM_TXOP_OFFSET; | ||
429 | RT_TRACE(rtlpriv, COMP_QOS, DBG_LOUD, | ||
430 | ("queue:%x, ac_param:%x\n", aci, u4b_ac_param)); | ||
431 | switch (aci) { | ||
432 | case AC1_BK: | ||
433 | rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, u4b_ac_param); | ||
434 | break; | ||
435 | case AC0_BE: | ||
436 | rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, u4b_ac_param); | ||
437 | break; | ||
438 | case AC2_VI: | ||
439 | rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, u4b_ac_param); | ||
440 | break; | ||
441 | case AC3_VO: | ||
442 | rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, u4b_ac_param); | ||
443 | break; | ||
444 | default: | ||
445 | RT_ASSERT(false, ("invalid aci: %d !\n", aci)); | ||
446 | break; | ||
447 | } | ||
448 | } | ||
449 | |||
450 | /*------------------------------------------------------------------------- | ||
451 | * HW MAC Address | ||
452 | *-------------------------------------------------------------------------*/ | ||
453 | void rtl92c_set_mac_addr(struct ieee80211_hw *hw, const u8 *addr) | ||
454 | { | ||
455 | u32 i; | ||
456 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
457 | |||
458 | for (i = 0 ; i < ETH_ALEN ; i++) | ||
459 | rtl_write_byte(rtlpriv, (REG_MACID + i), *(addr+i)); | ||
460 | |||
461 | RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, ("MAC Address: %02X-%02X-%02X-" | ||
462 | "%02X-%02X-%02X\n", | ||
463 | rtl_read_byte(rtlpriv, REG_MACID), | ||
464 | rtl_read_byte(rtlpriv, REG_MACID+1), | ||
465 | rtl_read_byte(rtlpriv, REG_MACID+2), | ||
466 | rtl_read_byte(rtlpriv, REG_MACID+3), | ||
467 | rtl_read_byte(rtlpriv, REG_MACID+4), | ||
468 | rtl_read_byte(rtlpriv, REG_MACID+5))); | ||
469 | } | ||
470 | |||
471 | void rtl92c_init_driver_info_size(struct ieee80211_hw *hw, u8 size) | ||
472 | { | ||
473 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
474 | rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, size); | ||
475 | } | ||
476 | |||
477 | int rtl92c_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) | ||
478 | { | ||
479 | u8 value; | ||
480 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
481 | |||
482 | switch (type) { | ||
483 | case NL80211_IFTYPE_UNSPECIFIED: | ||
484 | value = NT_NO_LINK; | ||
485 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
486 | ("Set Network type to NO LINK!\n")); | ||
487 | break; | ||
488 | case NL80211_IFTYPE_ADHOC: | ||
489 | value = NT_LINK_AD_HOC; | ||
490 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
491 | ("Set Network type to Ad Hoc!\n")); | ||
492 | break; | ||
493 | case NL80211_IFTYPE_STATION: | ||
494 | value = NT_LINK_AP; | ||
495 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
496 | ("Set Network type to STA!\n")); | ||
497 | break; | ||
498 | case NL80211_IFTYPE_AP: | ||
499 | value = NT_AS_AP; | ||
500 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
501 | ("Set Network type to AP!\n")); | ||
502 | break; | ||
503 | default: | ||
504 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
505 | ("Network type %d not support!\n", type)); | ||
506 | return -EOPNOTSUPP; | ||
507 | } | ||
508 | rtl_write_byte(rtlpriv, (REG_CR + 2), value); | ||
509 | return 0; | ||
510 | } | ||
511 | |||
512 | void rtl92c_init_network_type(struct ieee80211_hw *hw) | ||
513 | { | ||
514 | rtl92c_set_network_type(hw, NL80211_IFTYPE_UNSPECIFIED); | ||
515 | } | ||
516 | |||
517 | void rtl92c_init_adaptive_ctrl(struct ieee80211_hw *hw) | ||
518 | { | ||
519 | u16 value16; | ||
520 | u32 value32; | ||
521 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
522 | |||
523 | /* Response Rate Set */ | ||
524 | value32 = rtl_read_dword(rtlpriv, REG_RRSR); | ||
525 | value32 &= ~RATE_BITMAP_ALL; | ||
526 | value32 |= RATE_RRSR_CCK_ONLY_1M; | ||
527 | rtl_write_dword(rtlpriv, REG_RRSR, value32); | ||
528 | /* SIFS (used in NAV) */ | ||
529 | value16 = _SPEC_SIFS_CCK(0x10) | _SPEC_SIFS_OFDM(0x10); | ||
530 | rtl_write_word(rtlpriv, REG_SPEC_SIFS, value16); | ||
531 | /* Retry Limit */ | ||
532 | value16 = _LRL(0x30) | _SRL(0x30); | ||
533 | rtl_write_dword(rtlpriv, REG_RL, value16); | ||
534 | } | ||
535 | |||
536 | void rtl92c_init_rate_fallback(struct ieee80211_hw *hw) | ||
537 | { | ||
538 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
539 | |||
540 | /* Set Data Auto Rate Fallback Retry Count register. */ | ||
541 | rtl_write_dword(rtlpriv, REG_DARFRC, 0x00000000); | ||
542 | rtl_write_dword(rtlpriv, REG_DARFRC+4, 0x10080404); | ||
543 | rtl_write_dword(rtlpriv, REG_RARFRC, 0x04030201); | ||
544 | rtl_write_dword(rtlpriv, REG_RARFRC+4, 0x08070605); | ||
545 | } | ||
546 | |||
547 | static void rtl92c_set_cck_sifs(struct ieee80211_hw *hw, u8 trx_sifs, | ||
548 | u8 ctx_sifs) | ||
549 | { | ||
550 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
551 | |||
552 | rtl_write_byte(rtlpriv, REG_SIFS_CCK, trx_sifs); | ||
553 | rtl_write_byte(rtlpriv, (REG_SIFS_CCK + 1), ctx_sifs); | ||
554 | } | ||
555 | |||
556 | static void rtl92c_set_ofdm_sifs(struct ieee80211_hw *hw, u8 trx_sifs, | ||
557 | u8 ctx_sifs) | ||
558 | { | ||
559 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
560 | |||
561 | rtl_write_byte(rtlpriv, REG_SIFS_OFDM, trx_sifs); | ||
562 | rtl_write_byte(rtlpriv, (REG_SIFS_OFDM + 1), ctx_sifs); | ||
563 | } | ||
564 | |||
565 | void rtl92c_init_edca_param(struct ieee80211_hw *hw, | ||
566 | u16 queue, u16 txop, u8 cw_min, u8 cw_max, u8 aifs) | ||
567 | { | ||
568 | /* sequence: VO, VI, BE, BK ==> the same as 92C hardware design. | ||
569 | * referenc : enum nl80211_txq_q or ieee80211_set_wmm_default function. | ||
570 | */ | ||
571 | u32 value; | ||
572 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
573 | |||
574 | value = (u32)aifs; | ||
575 | value |= ((u32)cw_min & 0xF) << 8; | ||
576 | value |= ((u32)cw_max & 0xF) << 12; | ||
577 | value |= (u32)txop << 16; | ||
578 | /* 92C hardware register sequence is the same as queue number. */ | ||
579 | rtl_write_dword(rtlpriv, (REG_EDCA_VO_PARAM + (queue * 4)), value); | ||
580 | } | ||
581 | |||
582 | void rtl92c_init_edca(struct ieee80211_hw *hw) | ||
583 | { | ||
584 | u16 value16; | ||
585 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
586 | |||
587 | /* disable EDCCA count down, to reduce collison and retry */ | ||
588 | value16 = rtl_read_word(rtlpriv, REG_RD_CTRL); | ||
589 | value16 |= DIS_EDCA_CNT_DWN; | ||
590 | rtl_write_word(rtlpriv, REG_RD_CTRL, value16); | ||
591 | /* Update SIFS timing. ?????????? | ||
592 | * pHalData->SifsTime = 0x0e0e0a0a; */ | ||
593 | rtl92c_set_cck_sifs(hw, 0xa, 0xa); | ||
594 | rtl92c_set_ofdm_sifs(hw, 0xe, 0xe); | ||
595 | /* Set CCK/OFDM SIFS to be 10us. */ | ||
596 | rtl_write_word(rtlpriv, REG_SIFS_CCK, 0x0a0a); | ||
597 | rtl_write_word(rtlpriv, REG_SIFS_OFDM, 0x1010); | ||
598 | rtl_write_word(rtlpriv, REG_PROT_MODE_CTRL, 0x0204); | ||
599 | rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0x014004); | ||
600 | /* TXOP */ | ||
601 | rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, 0x005EA42B); | ||
602 | rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0x0000A44F); | ||
603 | rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x005EA324); | ||
604 | rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x002FA226); | ||
605 | /* PIFS */ | ||
606 | rtl_write_byte(rtlpriv, REG_PIFS, 0x1C); | ||
607 | /* AGGR BREAK TIME Register */ | ||
608 | rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16); | ||
609 | rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0040); | ||
610 | rtl_write_byte(rtlpriv, REG_BCNDMATIM, 0x02); | ||
611 | rtl_write_byte(rtlpriv, REG_ATIMWND, 0x02); | ||
612 | } | ||
613 | |||
614 | void rtl92c_init_ampdu_aggregation(struct ieee80211_hw *hw) | ||
615 | { | ||
616 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
617 | |||
618 | rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0x99997631); | ||
619 | rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16); | ||
620 | /* init AMPDU aggregation number, tuning for Tx's TP, */ | ||
621 | rtl_write_word(rtlpriv, 0x4CA, 0x0708); | ||
622 | } | ||
623 | |||
624 | void rtl92c_init_beacon_max_error(struct ieee80211_hw *hw, bool infra_mode) | ||
625 | { | ||
626 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
627 | |||
628 | rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xFF); | ||
629 | } | ||
630 | |||
631 | void rtl92c_init_rdg_setting(struct ieee80211_hw *hw) | ||
632 | { | ||
633 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
634 | |||
635 | rtl_write_byte(rtlpriv, REG_RD_CTRL, 0xFF); | ||
636 | rtl_write_word(rtlpriv, REG_RD_NAV_NXT, 0x200); | ||
637 | rtl_write_byte(rtlpriv, REG_RD_RESP_PKT_TH, 0x05); | ||
638 | } | ||
639 | |||
640 | void rtl92c_init_retry_function(struct ieee80211_hw *hw) | ||
641 | { | ||
642 | u8 value8; | ||
643 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
644 | |||
645 | value8 = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL); | ||
646 | value8 |= EN_AMPDU_RTY_NEW; | ||
647 | rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL, value8); | ||
648 | /* Set ACK timeout */ | ||
649 | rtl_write_byte(rtlpriv, REG_ACKTO, 0x40); | ||
650 | } | ||
651 | |||
652 | void rtl92c_init_beacon_parameters(struct ieee80211_hw *hw, | ||
653 | enum version_8192c version) | ||
654 | { | ||
655 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
656 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | ||
657 | |||
658 | rtl_write_word(rtlpriv, REG_TBTT_PROHIBIT, 0x6404);/* ms */ | ||
659 | rtl_write_byte(rtlpriv, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME);/*ms*/ | ||
660 | rtl_write_byte(rtlpriv, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME); | ||
661 | if (IS_NORMAL_CHIP(rtlhal->version)) | ||
662 | rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660F); | ||
663 | else | ||
664 | rtl_write_word(rtlpriv, REG_BCNTCFG, 0x66FF); | ||
665 | } | ||
666 | |||
667 | void rtl92c_disable_fast_edca(struct ieee80211_hw *hw) | ||
668 | { | ||
669 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
670 | |||
671 | rtl_write_word(rtlpriv, REG_FAST_EDCA_CTRL, 0); | ||
672 | } | ||
673 | |||
674 | void rtl92c_set_min_space(struct ieee80211_hw *hw, bool is2T) | ||
675 | { | ||
676 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
677 | u8 value = is2T ? MAX_MSS_DENSITY_2T : MAX_MSS_DENSITY_1T; | ||
678 | |||
679 | rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, value); | ||
680 | } | ||
681 | |||
682 | u16 rtl92c_get_mgt_filter(struct ieee80211_hw *hw) | ||
683 | { | ||
684 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
685 | |||
686 | return rtl_read_word(rtlpriv, REG_RXFLTMAP0); | ||
687 | } | ||
688 | |||
689 | void rtl92c_set_mgt_filter(struct ieee80211_hw *hw, u16 filter) | ||
690 | { | ||
691 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
692 | |||
693 | rtl_write_word(rtlpriv, REG_RXFLTMAP0, filter); | ||
694 | } | ||
695 | |||
696 | u16 rtl92c_get_ctrl_filter(struct ieee80211_hw *hw) | ||
697 | { | ||
698 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
699 | |||
700 | return rtl_read_word(rtlpriv, REG_RXFLTMAP1); | ||
701 | } | ||
702 | |||
703 | void rtl92c_set_ctrl_filter(struct ieee80211_hw *hw, u16 filter) | ||
704 | { | ||
705 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
706 | |||
707 | rtl_write_word(rtlpriv, REG_RXFLTMAP1, filter); | ||
708 | } | ||
709 | |||
710 | u16 rtl92c_get_data_filter(struct ieee80211_hw *hw) | ||
711 | { | ||
712 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
713 | |||
714 | return rtl_read_word(rtlpriv, REG_RXFLTMAP2); | ||
715 | } | ||
716 | |||
717 | void rtl92c_set_data_filter(struct ieee80211_hw *hw, u16 filter) | ||
718 | { | ||
719 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
720 | |||
721 | rtl_write_word(rtlpriv, REG_RXFLTMAP2, filter); | ||
722 | } | ||
723 | /*==============================================================*/ | ||
724 | |||
725 | static u8 _rtl92c_query_rxpwrpercentage(char antpower) | ||
726 | { | ||
727 | if ((antpower <= -100) || (antpower >= 20)) | ||
728 | return 0; | ||
729 | else if (antpower >= 0) | ||
730 | return 100; | ||
731 | else | ||
732 | return 100 + antpower; | ||
733 | } | ||
734 | |||
735 | static u8 _rtl92c_evm_db_to_percentage(char value) | ||
736 | { | ||
737 | char ret_val; | ||
738 | |||
739 | ret_val = value; | ||
740 | if (ret_val >= 0) | ||
741 | ret_val = 0; | ||
742 | if (ret_val <= -33) | ||
743 | ret_val = -33; | ||
744 | ret_val = 0 - ret_val; | ||
745 | ret_val *= 3; | ||
746 | if (ret_val == 99) | ||
747 | ret_val = 100; | ||
748 | return ret_val; | ||
749 | } | ||
750 | |||
751 | static long _rtl92c_translate_todbm(struct ieee80211_hw *hw, | ||
752 | u8 signal_strength_index) | ||
753 | { | ||
754 | long signal_power; | ||
755 | |||
756 | signal_power = (long)((signal_strength_index + 1) >> 1); | ||
757 | signal_power -= 95; | ||
758 | return signal_power; | ||
759 | } | ||
760 | |||
761 | static long _rtl92c_signal_scale_mapping(struct ieee80211_hw *hw, | ||
762 | long currsig) | ||
763 | { | ||
764 | long retsig; | ||
765 | |||
766 | if (currsig >= 61 && currsig <= 100) | ||
767 | retsig = 90 + ((currsig - 60) / 4); | ||
768 | else if (currsig >= 41 && currsig <= 60) | ||
769 | retsig = 78 + ((currsig - 40) / 2); | ||
770 | else if (currsig >= 31 && currsig <= 40) | ||
771 | retsig = 66 + (currsig - 30); | ||
772 | else if (currsig >= 21 && currsig <= 30) | ||
773 | retsig = 54 + (currsig - 20); | ||
774 | else if (currsig >= 5 && currsig <= 20) | ||
775 | retsig = 42 + (((currsig - 5) * 2) / 3); | ||
776 | else if (currsig == 4) | ||
777 | retsig = 36; | ||
778 | else if (currsig == 3) | ||
779 | retsig = 27; | ||
780 | else if (currsig == 2) | ||
781 | retsig = 18; | ||
782 | else if (currsig == 1) | ||
783 | retsig = 9; | ||
784 | else | ||
785 | retsig = currsig; | ||
786 | return retsig; | ||
787 | } | ||
788 | |||
789 | static void _rtl92c_query_rxphystatus(struct ieee80211_hw *hw, | ||
790 | struct rtl_stats *pstats, | ||
791 | struct rx_desc_92c *pdesc, | ||
792 | struct rx_fwinfo_92c *p_drvinfo, | ||
793 | bool packet_match_bssid, | ||
794 | bool packet_toself, | ||
795 | bool packet_beacon) | ||
796 | { | ||
797 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
798 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
799 | struct phy_sts_cck_8192s_t *cck_buf; | ||
800 | s8 rx_pwr_all = 0, rx_pwr[4]; | ||
801 | u8 rf_rx_num = 0, evm, pwdb_all; | ||
802 | u8 i, max_spatial_stream; | ||
803 | u32 rssi, total_rssi = 0; | ||
804 | bool in_powersavemode = false; | ||
805 | bool is_cck_rate; | ||
806 | |||
807 | is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc); | ||
808 | pstats->packet_matchbssid = packet_match_bssid; | ||
809 | pstats->packet_toself = packet_toself; | ||
810 | pstats->is_cck = is_cck_rate; | ||
811 | pstats->packet_beacon = packet_beacon; | ||
812 | pstats->is_cck = is_cck_rate; | ||
813 | pstats->RX_SIGQ[0] = -1; | ||
814 | pstats->RX_SIGQ[1] = -1; | ||
815 | if (is_cck_rate) { | ||
816 | u8 report, cck_highpwr; | ||
817 | cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo; | ||
818 | if (!in_powersavemode) | ||
819 | cck_highpwr = rtlphy->cck_high_power; | ||
820 | else | ||
821 | cck_highpwr = false; | ||
822 | if (!cck_highpwr) { | ||
823 | u8 cck_agc_rpt = cck_buf->cck_agc_rpt; | ||
824 | report = cck_buf->cck_agc_rpt & 0xc0; | ||
825 | report = report >> 6; | ||
826 | switch (report) { | ||
827 | case 0x3: | ||
828 | rx_pwr_all = -46 - (cck_agc_rpt & 0x3e); | ||
829 | break; | ||
830 | case 0x2: | ||
831 | rx_pwr_all = -26 - (cck_agc_rpt & 0x3e); | ||
832 | break; | ||
833 | case 0x1: | ||
834 | rx_pwr_all = -12 - (cck_agc_rpt & 0x3e); | ||
835 | break; | ||
836 | case 0x0: | ||
837 | rx_pwr_all = 16 - (cck_agc_rpt & 0x3e); | ||
838 | break; | ||
839 | } | ||
840 | } else { | ||
841 | u8 cck_agc_rpt = cck_buf->cck_agc_rpt; | ||
842 | report = p_drvinfo->cfosho[0] & 0x60; | ||
843 | report = report >> 5; | ||
844 | switch (report) { | ||
845 | case 0x3: | ||
846 | rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1); | ||
847 | break; | ||
848 | case 0x2: | ||
849 | rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1); | ||
850 | break; | ||
851 | case 0x1: | ||
852 | rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1); | ||
853 | break; | ||
854 | case 0x0: | ||
855 | rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1); | ||
856 | break; | ||
857 | } | ||
858 | } | ||
859 | pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all); | ||
860 | pstats->rx_pwdb_all = pwdb_all; | ||
861 | pstats->recvsignalpower = rx_pwr_all; | ||
862 | if (packet_match_bssid) { | ||
863 | u8 sq; | ||
864 | if (pstats->rx_pwdb_all > 40) | ||
865 | sq = 100; | ||
866 | else { | ||
867 | sq = cck_buf->sq_rpt; | ||
868 | if (sq > 64) | ||
869 | sq = 0; | ||
870 | else if (sq < 20) | ||
871 | sq = 100; | ||
872 | else | ||
873 | sq = ((64 - sq) * 100) / 44; | ||
874 | } | ||
875 | pstats->signalquality = sq; | ||
876 | pstats->RX_SIGQ[0] = sq; | ||
877 | pstats->RX_SIGQ[1] = -1; | ||
878 | } | ||
879 | } else { | ||
880 | rtlpriv->dm.rfpath_rxenable[0] = | ||
881 | rtlpriv->dm.rfpath_rxenable[1] = true; | ||
882 | for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) { | ||
883 | if (rtlpriv->dm.rfpath_rxenable[i]) | ||
884 | rf_rx_num++; | ||
885 | rx_pwr[i] = | ||
886 | ((p_drvinfo->gain_trsw[i] & 0x3f) * 2) - 110; | ||
887 | rssi = _rtl92c_query_rxpwrpercentage(rx_pwr[i]); | ||
888 | total_rssi += rssi; | ||
889 | rtlpriv->stats.rx_snr_db[i] = | ||
890 | (long)(p_drvinfo->rxsnr[i] / 2); | ||
891 | |||
892 | if (packet_match_bssid) | ||
893 | pstats->rx_mimo_signalstrength[i] = (u8) rssi; | ||
894 | } | ||
895 | rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110; | ||
896 | pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all); | ||
897 | pstats->rx_pwdb_all = pwdb_all; | ||
898 | pstats->rxpower = rx_pwr_all; | ||
899 | pstats->recvsignalpower = rx_pwr_all; | ||
900 | if (GET_RX_DESC_RX_MCS(pdesc) && | ||
901 | GET_RX_DESC_RX_MCS(pdesc) >= DESC92C_RATEMCS8 && | ||
902 | GET_RX_DESC_RX_MCS(pdesc) <= DESC92C_RATEMCS15) | ||
903 | max_spatial_stream = 2; | ||
904 | else | ||
905 | max_spatial_stream = 1; | ||
906 | for (i = 0; i < max_spatial_stream; i++) { | ||
907 | evm = _rtl92c_evm_db_to_percentage(p_drvinfo->rxevm[i]); | ||
908 | if (packet_match_bssid) { | ||
909 | if (i == 0) | ||
910 | pstats->signalquality = | ||
911 | (u8) (evm & 0xff); | ||
912 | pstats->RX_SIGQ[i] = | ||
913 | (u8) (evm & 0xff); | ||
914 | } | ||
915 | } | ||
916 | } | ||
917 | if (is_cck_rate) | ||
918 | pstats->signalstrength = | ||
919 | (u8) (_rtl92c_signal_scale_mapping(hw, pwdb_all)); | ||
920 | else if (rf_rx_num != 0) | ||
921 | pstats->signalstrength = | ||
922 | (u8) (_rtl92c_signal_scale_mapping | ||
923 | (hw, total_rssi /= rf_rx_num)); | ||
924 | } | ||
925 | |||
926 | static void _rtl92c_process_ui_rssi(struct ieee80211_hw *hw, | ||
927 | struct rtl_stats *pstats) | ||
928 | { | ||
929 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
930 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
931 | u8 rfpath; | ||
932 | u32 last_rssi, tmpval; | ||
933 | |||
934 | if (pstats->packet_toself || pstats->packet_beacon) { | ||
935 | rtlpriv->stats.rssi_calculate_cnt++; | ||
936 | if (rtlpriv->stats.ui_rssi.total_num++ >= | ||
937 | PHY_RSSI_SLID_WIN_MAX) { | ||
938 | rtlpriv->stats.ui_rssi.total_num = | ||
939 | PHY_RSSI_SLID_WIN_MAX; | ||
940 | last_rssi = | ||
941 | rtlpriv->stats.ui_rssi.elements[rtlpriv-> | ||
942 | stats.ui_rssi.index]; | ||
943 | rtlpriv->stats.ui_rssi.total_val -= last_rssi; | ||
944 | } | ||
945 | rtlpriv->stats.ui_rssi.total_val += pstats->signalstrength; | ||
946 | rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi. | ||
947 | index++] = pstats->signalstrength; | ||
948 | if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX) | ||
949 | rtlpriv->stats.ui_rssi.index = 0; | ||
950 | tmpval = rtlpriv->stats.ui_rssi.total_val / | ||
951 | rtlpriv->stats.ui_rssi.total_num; | ||
952 | rtlpriv->stats.signal_strength = | ||
953 | _rtl92c_translate_todbm(hw, (u8) tmpval); | ||
954 | pstats->rssi = rtlpriv->stats.signal_strength; | ||
955 | } | ||
956 | if (!pstats->is_cck && pstats->packet_toself) { | ||
957 | for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; | ||
958 | rfpath++) { | ||
959 | if (!rtl8192_phy_check_is_legal_rfpath(hw, rfpath)) | ||
960 | continue; | ||
961 | if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) { | ||
962 | rtlpriv->stats.rx_rssi_percentage[rfpath] = | ||
963 | pstats->rx_mimo_signalstrength[rfpath]; | ||
964 | } | ||
965 | if (pstats->rx_mimo_signalstrength[rfpath] > | ||
966 | rtlpriv->stats.rx_rssi_percentage[rfpath]) { | ||
967 | rtlpriv->stats.rx_rssi_percentage[rfpath] = | ||
968 | ((rtlpriv->stats. | ||
969 | rx_rssi_percentage[rfpath] * | ||
970 | (RX_SMOOTH_FACTOR - 1)) + | ||
971 | (pstats->rx_mimo_signalstrength[rfpath])) / | ||
972 | (RX_SMOOTH_FACTOR); | ||
973 | |||
974 | rtlpriv->stats.rx_rssi_percentage[rfpath] = | ||
975 | rtlpriv->stats.rx_rssi_percentage[rfpath] + | ||
976 | 1; | ||
977 | } else { | ||
978 | rtlpriv->stats.rx_rssi_percentage[rfpath] = | ||
979 | ((rtlpriv->stats. | ||
980 | rx_rssi_percentage[rfpath] * | ||
981 | (RX_SMOOTH_FACTOR - 1)) + | ||
982 | (pstats->rx_mimo_signalstrength[rfpath])) / | ||
983 | (RX_SMOOTH_FACTOR); | ||
984 | } | ||
985 | } | ||
986 | } | ||
987 | } | ||
988 | |||
989 | static void _rtl92c_update_rxsignalstatistics(struct ieee80211_hw *hw, | ||
990 | struct rtl_stats *pstats) | ||
991 | { | ||
992 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
993 | int weighting = 0; | ||
994 | |||
995 | if (rtlpriv->stats.recv_signal_power == 0) | ||
996 | rtlpriv->stats.recv_signal_power = pstats->recvsignalpower; | ||
997 | if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power) | ||
998 | weighting = 5; | ||
999 | else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power) | ||
1000 | weighting = (-5); | ||
1001 | rtlpriv->stats.recv_signal_power = | ||
1002 | (rtlpriv->stats.recv_signal_power * 5 + | ||
1003 | pstats->recvsignalpower + weighting) / 6; | ||
1004 | } | ||
1005 | |||
1006 | static void _rtl92c_process_pwdb(struct ieee80211_hw *hw, | ||
1007 | struct rtl_stats *pstats) | ||
1008 | { | ||
1009 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1010 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
1011 | long undecorated_smoothed_pwdb = 0; | ||
1012 | |||
1013 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { | ||
1014 | return; | ||
1015 | } else { | ||
1016 | undecorated_smoothed_pwdb = | ||
1017 | rtlpriv->dm.undecorated_smoothed_pwdb; | ||
1018 | } | ||
1019 | if (pstats->packet_toself || pstats->packet_beacon) { | ||
1020 | if (undecorated_smoothed_pwdb < 0) | ||
1021 | undecorated_smoothed_pwdb = pstats->rx_pwdb_all; | ||
1022 | if (pstats->rx_pwdb_all > (u32) undecorated_smoothed_pwdb) { | ||
1023 | undecorated_smoothed_pwdb = | ||
1024 | (((undecorated_smoothed_pwdb) * | ||
1025 | (RX_SMOOTH_FACTOR - 1)) + | ||
1026 | (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); | ||
1027 | undecorated_smoothed_pwdb = undecorated_smoothed_pwdb | ||
1028 | + 1; | ||
1029 | } else { | ||
1030 | undecorated_smoothed_pwdb = | ||
1031 | (((undecorated_smoothed_pwdb) * | ||
1032 | (RX_SMOOTH_FACTOR - 1)) + | ||
1033 | (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); | ||
1034 | } | ||
1035 | rtlpriv->dm.undecorated_smoothed_pwdb = | ||
1036 | undecorated_smoothed_pwdb; | ||
1037 | _rtl92c_update_rxsignalstatistics(hw, pstats); | ||
1038 | } | ||
1039 | } | ||
1040 | |||
1041 | static void _rtl92c_process_LINK_Q(struct ieee80211_hw *hw, | ||
1042 | struct rtl_stats *pstats) | ||
1043 | { | ||
1044 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1045 | u32 last_evm = 0, n_stream, tmpval; | ||
1046 | |||
1047 | if (pstats->signalquality != 0) { | ||
1048 | if (pstats->packet_toself || pstats->packet_beacon) { | ||
1049 | if (rtlpriv->stats.LINK_Q.total_num++ >= | ||
1050 | PHY_LINKQUALITY_SLID_WIN_MAX) { | ||
1051 | rtlpriv->stats.LINK_Q.total_num = | ||
1052 | PHY_LINKQUALITY_SLID_WIN_MAX; | ||
1053 | last_evm = | ||
1054 | rtlpriv->stats.LINK_Q.elements | ||
1055 | [rtlpriv->stats.LINK_Q.index]; | ||
1056 | rtlpriv->stats.LINK_Q.total_val -= | ||
1057 | last_evm; | ||
1058 | } | ||
1059 | rtlpriv->stats.LINK_Q.total_val += | ||
1060 | pstats->signalquality; | ||
1061 | rtlpriv->stats.LINK_Q.elements | ||
1062 | [rtlpriv->stats.LINK_Q.index++] = | ||
1063 | pstats->signalquality; | ||
1064 | if (rtlpriv->stats.LINK_Q.index >= | ||
1065 | PHY_LINKQUALITY_SLID_WIN_MAX) | ||
1066 | rtlpriv->stats.LINK_Q.index = 0; | ||
1067 | tmpval = rtlpriv->stats.LINK_Q.total_val / | ||
1068 | rtlpriv->stats.LINK_Q.total_num; | ||
1069 | rtlpriv->stats.signal_quality = tmpval; | ||
1070 | rtlpriv->stats.last_sigstrength_inpercent = tmpval; | ||
1071 | for (n_stream = 0; n_stream < 2; | ||
1072 | n_stream++) { | ||
1073 | if (pstats->RX_SIGQ[n_stream] != -1) { | ||
1074 | if (!rtlpriv->stats.RX_EVM[n_stream]) { | ||
1075 | rtlpriv->stats.RX_EVM[n_stream] | ||
1076 | = pstats->RX_SIGQ[n_stream]; | ||
1077 | } | ||
1078 | rtlpriv->stats.RX_EVM[n_stream] = | ||
1079 | ((rtlpriv->stats.RX_EVM | ||
1080 | [n_stream] * | ||
1081 | (RX_SMOOTH_FACTOR - 1)) + | ||
1082 | (pstats->RX_SIGQ | ||
1083 | [n_stream] * 1)) / | ||
1084 | (RX_SMOOTH_FACTOR); | ||
1085 | } | ||
1086 | } | ||
1087 | } | ||
1088 | } else { | ||
1089 | ; | ||
1090 | } | ||
1091 | } | ||
1092 | |||
1093 | static void _rtl92c_process_phyinfo(struct ieee80211_hw *hw, | ||
1094 | u8 *buffer, | ||
1095 | struct rtl_stats *pcurrent_stats) | ||
1096 | { | ||
1097 | if (!pcurrent_stats->packet_matchbssid && | ||
1098 | !pcurrent_stats->packet_beacon) | ||
1099 | return; | ||
1100 | _rtl92c_process_ui_rssi(hw, pcurrent_stats); | ||
1101 | _rtl92c_process_pwdb(hw, pcurrent_stats); | ||
1102 | _rtl92c_process_LINK_Q(hw, pcurrent_stats); | ||
1103 | } | ||
1104 | |||
1105 | void rtl92c_translate_rx_signal_stuff(struct ieee80211_hw *hw, | ||
1106 | struct sk_buff *skb, | ||
1107 | struct rtl_stats *pstats, | ||
1108 | struct rx_desc_92c *pdesc, | ||
1109 | struct rx_fwinfo_92c *p_drvinfo) | ||
1110 | { | ||
1111 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
1112 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
1113 | struct ieee80211_hdr *hdr; | ||
1114 | u8 *tmp_buf; | ||
1115 | u8 *praddr; | ||
1116 | u8 *psaddr; | ||
1117 | __le16 fc; | ||
1118 | u16 type, cpu_fc; | ||
1119 | bool packet_matchbssid, packet_toself, packet_beacon; | ||
1120 | |||
1121 | tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift; | ||
1122 | hdr = (struct ieee80211_hdr *)tmp_buf; | ||
1123 | fc = hdr->frame_control; | ||
1124 | cpu_fc = le16_to_cpu(fc); | ||
1125 | type = WLAN_FC_GET_TYPE(fc); | ||
1126 | praddr = hdr->addr1; | ||
1127 | psaddr = hdr->addr2; | ||
1128 | packet_matchbssid = | ||
1129 | ((IEEE80211_FTYPE_CTL != type) && | ||
1130 | (!compare_ether_addr(mac->bssid, | ||
1131 | (cpu_fc & IEEE80211_FCTL_TODS) ? | ||
1132 | hdr->addr1 : (cpu_fc & IEEE80211_FCTL_FROMDS) ? | ||
1133 | hdr->addr2 : hdr->addr3)) && | ||
1134 | (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv)); | ||
1135 | |||
1136 | packet_toself = packet_matchbssid && | ||
1137 | (!compare_ether_addr(praddr, rtlefuse->dev_addr)); | ||
1138 | if (ieee80211_is_beacon(fc)) | ||
1139 | packet_beacon = true; | ||
1140 | _rtl92c_query_rxphystatus(hw, pstats, pdesc, p_drvinfo, | ||
1141 | packet_matchbssid, packet_toself, | ||
1142 | packet_beacon); | ||
1143 | _rtl92c_process_phyinfo(hw, tmp_buf, pstats); | ||
1144 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h new file mode 100644 index 000000000000..298fdb724aa5 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h | |||
@@ -0,0 +1,180 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #ifndef __RTL92C_MAC_H__ | ||
31 | #define __RTL92C_MAC_H__ | ||
32 | |||
33 | #define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER 255 | ||
34 | #define DRIVER_EARLY_INT_TIME 0x05 | ||
35 | #define BCN_DMA_ATIME_INT_TIME 0x02 | ||
36 | |||
37 | void rtl92c_read_chip_version(struct ieee80211_hw *hw); | ||
38 | bool rtl92c_llt_write(struct ieee80211_hw *hw, u32 address, u32 data); | ||
39 | bool rtl92c_init_llt_table(struct ieee80211_hw *hw, u32 boundary); | ||
40 | void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index, | ||
41 | u8 *p_macaddr, bool is_group, u8 enc_algo, | ||
42 | bool is_wepkey, bool clear_all); | ||
43 | void rtl92c_enable_interrupt(struct ieee80211_hw *hw); | ||
44 | void rtl92c_disable_interrupt(struct ieee80211_hw *hw); | ||
45 | void rtl92c_set_qos(struct ieee80211_hw *hw, int aci); | ||
46 | |||
47 | |||
48 | /*--------------------------------------------------------------- | ||
49 | * Hardware init functions | ||
50 | *---------------------------------------------------------------*/ | ||
51 | void rtl92c_set_mac_addr(struct ieee80211_hw *hw, const u8 *addr); | ||
52 | void rtl92c_init_interrupt(struct ieee80211_hw *hw); | ||
53 | void rtl92c_init_driver_info_size(struct ieee80211_hw *hw, u8 size); | ||
54 | |||
55 | int rtl92c_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type); | ||
56 | void rtl92c_init_network_type(struct ieee80211_hw *hw); | ||
57 | void rtl92c_init_adaptive_ctrl(struct ieee80211_hw *hw); | ||
58 | void rtl92c_init_rate_fallback(struct ieee80211_hw *hw); | ||
59 | |||
60 | void rtl92c_init_edca_param(struct ieee80211_hw *hw, | ||
61 | u16 queue, | ||
62 | u16 txop, | ||
63 | u8 ecwmax, | ||
64 | u8 ecwmin, | ||
65 | u8 aifs); | ||
66 | |||
67 | void rtl92c_init_edca(struct ieee80211_hw *hw); | ||
68 | void rtl92c_init_ampdu_aggregation(struct ieee80211_hw *hw); | ||
69 | void rtl92c_init_beacon_max_error(struct ieee80211_hw *hw, bool infra_mode); | ||
70 | void rtl92c_init_rdg_setting(struct ieee80211_hw *hw); | ||
71 | void rtl92c_init_retry_function(struct ieee80211_hw *hw); | ||
72 | |||
73 | void rtl92c_init_beacon_parameters(struct ieee80211_hw *hw, | ||
74 | enum version_8192c version); | ||
75 | |||
76 | void rtl92c_disable_fast_edca(struct ieee80211_hw *hw); | ||
77 | void rtl92c_set_min_space(struct ieee80211_hw *hw, bool is2T); | ||
78 | |||
79 | /* For filter */ | ||
80 | u16 rtl92c_get_mgt_filter(struct ieee80211_hw *hw); | ||
81 | void rtl92c_set_mgt_filter(struct ieee80211_hw *hw, u16 filter); | ||
82 | u16 rtl92c_get_ctrl_filter(struct ieee80211_hw *hw); | ||
83 | void rtl92c_set_ctrl_filter(struct ieee80211_hw *hw, u16 filter); | ||
84 | u16 rtl92c_get_data_filter(struct ieee80211_hw *hw); | ||
85 | void rtl92c_set_data_filter(struct ieee80211_hw *hw, u16 filter); | ||
86 | |||
87 | |||
88 | u32 rtl92c_get_txdma_status(struct ieee80211_hw *hw); | ||
89 | |||
90 | #define RX_HAL_IS_CCK_RATE(_pdesc)\ | ||
91 | (GET_RX_DESC_RX_MCS(_pdesc) == DESC92C_RATE1M ||\ | ||
92 | GET_RX_DESC_RX_MCS(_pdesc) == DESC92C_RATE2M ||\ | ||
93 | GET_RX_DESC_RX_MCS(_pdesc) == DESC92C_RATE5_5M ||\ | ||
94 | GET_RX_DESC_RX_MCS(_pdesc) == DESC92C_RATE11M) | ||
95 | |||
96 | struct rx_fwinfo_92c { | ||
97 | u8 gain_trsw[4]; | ||
98 | u8 pwdb_all; | ||
99 | u8 cfosho[4]; | ||
100 | u8 cfotail[4]; | ||
101 | char rxevm[2]; | ||
102 | char rxsnr[4]; | ||
103 | u8 pdsnr[2]; | ||
104 | u8 csi_current[2]; | ||
105 | u8 csi_target[2]; | ||
106 | u8 sigevm; | ||
107 | u8 max_ex_pwr; | ||
108 | u8 ex_intf_flag:1; | ||
109 | u8 sgi_en:1; | ||
110 | u8 rxsc:2; | ||
111 | u8 reserve:4; | ||
112 | } __packed; | ||
113 | |||
114 | struct rx_desc_92c { | ||
115 | u32 length:14; | ||
116 | u32 crc32:1; | ||
117 | u32 icverror:1; | ||
118 | u32 drv_infosize:4; | ||
119 | u32 security:3; | ||
120 | u32 qos:1; | ||
121 | u32 shift:2; | ||
122 | u32 phystatus:1; | ||
123 | u32 swdec:1; | ||
124 | u32 lastseg:1; | ||
125 | u32 firstseg:1; | ||
126 | u32 eor:1; | ||
127 | u32 own:1; | ||
128 | u32 macid:5; /* word 1 */ | ||
129 | u32 tid:4; | ||
130 | u32 hwrsvd:5; | ||
131 | u32 paggr:1; | ||
132 | u32 faggr:1; | ||
133 | u32 a1_fit:4; | ||
134 | u32 a2_fit:4; | ||
135 | u32 pam:1; | ||
136 | u32 pwr:1; | ||
137 | u32 moredata:1; | ||
138 | u32 morefrag:1; | ||
139 | u32 type:2; | ||
140 | u32 mc:1; | ||
141 | u32 bc:1; | ||
142 | u32 seq:12; /* word 2 */ | ||
143 | u32 frag:4; | ||
144 | u32 nextpktlen:14; | ||
145 | u32 nextind:1; | ||
146 | u32 rsvd:1; | ||
147 | u32 rxmcs:6; /* word 3 */ | ||
148 | u32 rxht:1; | ||
149 | u32 amsdu:1; | ||
150 | u32 splcp:1; | ||
151 | u32 bandwidth:1; | ||
152 | u32 htc:1; | ||
153 | u32 tcpchk_rpt:1; | ||
154 | u32 ipcchk_rpt:1; | ||
155 | u32 tcpchk_valid:1; | ||
156 | u32 hwpcerr:1; | ||
157 | u32 hwpcind:1; | ||
158 | u32 iv0:16; | ||
159 | u32 iv1; /* word 4 */ | ||
160 | u32 tsfl; /* word 5 */ | ||
161 | u32 bufferaddress; /* word 6 */ | ||
162 | u32 bufferaddress64; /* word 7 */ | ||
163 | } __packed; | ||
164 | |||
165 | enum rtl_desc_qsel rtl92c_map_hwqueue_to_fwqueue(u16 fc, | ||
166 | unsigned int | ||
167 | skb_queue); | ||
168 | void rtl92c_translate_rx_signal_stuff(struct ieee80211_hw *hw, | ||
169 | struct sk_buff *skb, | ||
170 | struct rtl_stats *pstats, | ||
171 | struct rx_desc_92c *pdesc, | ||
172 | struct rx_fwinfo_92c *p_drvinfo); | ||
173 | |||
174 | /*--------------------------------------------------------------- | ||
175 | * Card disable functions | ||
176 | *---------------------------------------------------------------*/ | ||
177 | |||
178 | |||
179 | |||
180 | #endif | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c new file mode 100644 index 000000000000..dc65ef2bbeac --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c | |||
@@ -0,0 +1,611 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 Realtek Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #include "../wifi.h" | ||
31 | #include "../pci.h" | ||
32 | #include "../ps.h" | ||
33 | #include "reg.h" | ||
34 | #include "def.h" | ||
35 | #include "phy.h" | ||
36 | #include "rf.h" | ||
37 | #include "dm.h" | ||
38 | #include "table.h" | ||
39 | |||
40 | #include "../rtl8192c/phy_common.c" | ||
41 | |||
42 | u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, | ||
43 | enum radio_path rfpath, u32 regaddr, u32 bitmask) | ||
44 | { | ||
45 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
46 | u32 original_value, readback_value, bitshift; | ||
47 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
48 | |||
49 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " | ||
50 | "rfpath(%#x), bitmask(%#x)\n", | ||
51 | regaddr, rfpath, bitmask)); | ||
52 | if (rtlphy->rf_mode != RF_OP_BY_FW) { | ||
53 | original_value = _rtl92c_phy_rf_serial_read(hw, | ||
54 | rfpath, regaddr); | ||
55 | } else { | ||
56 | original_value = _rtl92c_phy_fw_rf_serial_read(hw, | ||
57 | rfpath, regaddr); | ||
58 | } | ||
59 | bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); | ||
60 | readback_value = (original_value & bitmask) >> bitshift; | ||
61 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, | ||
62 | ("regaddr(%#x), rfpath(%#x), " | ||
63 | "bitmask(%#x), original_value(%#x)\n", | ||
64 | regaddr, rfpath, bitmask, original_value)); | ||
65 | return readback_value; | ||
66 | } | ||
67 | |||
68 | void rtl92c_phy_set_rf_reg(struct ieee80211_hw *hw, | ||
69 | enum radio_path rfpath, | ||
70 | u32 regaddr, u32 bitmask, u32 data) | ||
71 | { | ||
72 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
73 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
74 | u32 original_value, bitshift; | ||
75 | |||
76 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, | ||
77 | ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", | ||
78 | regaddr, bitmask, data, rfpath)); | ||
79 | if (rtlphy->rf_mode != RF_OP_BY_FW) { | ||
80 | if (bitmask != RFREG_OFFSET_MASK) { | ||
81 | original_value = _rtl92c_phy_rf_serial_read(hw, | ||
82 | rfpath, | ||
83 | regaddr); | ||
84 | bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); | ||
85 | data = | ||
86 | ((original_value & (~bitmask)) | | ||
87 | (data << bitshift)); | ||
88 | } | ||
89 | _rtl92c_phy_rf_serial_write(hw, rfpath, regaddr, data); | ||
90 | } else { | ||
91 | if (bitmask != RFREG_OFFSET_MASK) { | ||
92 | original_value = _rtl92c_phy_fw_rf_serial_read(hw, | ||
93 | rfpath, | ||
94 | regaddr); | ||
95 | bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); | ||
96 | data = | ||
97 | ((original_value & (~bitmask)) | | ||
98 | (data << bitshift)); | ||
99 | } | ||
100 | _rtl92c_phy_fw_rf_serial_write(hw, rfpath, regaddr, data); | ||
101 | } | ||
102 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " | ||
103 | "bitmask(%#x), data(%#x), rfpath(%#x)\n", | ||
104 | regaddr, bitmask, data, rfpath)); | ||
105 | } | ||
106 | |||
107 | bool rtl92c_phy_mac_config(struct ieee80211_hw *hw) | ||
108 | { | ||
109 | bool rtstatus; | ||
110 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
111 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
112 | bool is92c = IS_92C_SERIAL(rtlhal->version); | ||
113 | |||
114 | rtstatus = _rtl92c_phy_config_mac_with_headerfile(hw); | ||
115 | if (is92c && IS_HARDWARE_TYPE_8192CE(rtlhal)) | ||
116 | rtl_write_byte(rtlpriv, 0x14, 0x71); | ||
117 | return rtstatus; | ||
118 | } | ||
119 | |||
120 | bool rtl92c_phy_bb_config(struct ieee80211_hw *hw) | ||
121 | { | ||
122 | bool rtstatus = true; | ||
123 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
124 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
125 | u16 regval; | ||
126 | u8 b_reg_hwparafile = 1; | ||
127 | |||
128 | _rtl92c_phy_init_bb_rf_register_definition(hw); | ||
129 | regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); | ||
130 | rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, regval | BIT(13) | | ||
131 | BIT(0) | BIT(1)); | ||
132 | rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83); | ||
133 | rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb); | ||
134 | rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB); | ||
135 | if (IS_HARDWARE_TYPE_8192CE(rtlhal)) { | ||
136 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, FEN_PPLL | FEN_PCIEA | | ||
137 | FEN_DIO_PCIE | FEN_BB_GLB_RSTn | FEN_BBRSTB); | ||
138 | } else if (IS_HARDWARE_TYPE_8192CU(rtlhal)) { | ||
139 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, FEN_USBA | FEN_USBD | | ||
140 | FEN_BB_GLB_RSTn | FEN_BBRSTB); | ||
141 | rtl_write_byte(rtlpriv, REG_LDOHCI12_CTRL, 0x0f); | ||
142 | } | ||
143 | rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80); | ||
144 | if (b_reg_hwparafile == 1) | ||
145 | rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw); | ||
146 | return rtstatus; | ||
147 | } | ||
148 | |||
149 | static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) | ||
150 | { | ||
151 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
152 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
153 | u32 i; | ||
154 | u32 arraylength; | ||
155 | u32 *ptrarray; | ||
156 | |||
157 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Read Rtl819XMACPHY_Array\n")); | ||
158 | arraylength = rtlphy->hwparam_tables[MAC_REG].length ; | ||
159 | ptrarray = rtlphy->hwparam_tables[MAC_REG].pdata; | ||
160 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
161 | ("Img:RTL8192CEMAC_2T_ARRAY\n")); | ||
162 | for (i = 0; i < arraylength; i = i + 2) | ||
163 | rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]); | ||
164 | return true; | ||
165 | } | ||
166 | |||
167 | static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, | ||
168 | u8 configtype) | ||
169 | { | ||
170 | int i; | ||
171 | u32 *phy_regarray_table; | ||
172 | u32 *agctab_array_table; | ||
173 | u16 phy_reg_arraylen, agctab_arraylen; | ||
174 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
175 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
176 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
177 | |||
178 | if (IS_92C_SERIAL(rtlhal->version)) { | ||
179 | agctab_arraylen = rtlphy->hwparam_tables[AGCTAB_2T].length; | ||
180 | agctab_array_table = rtlphy->hwparam_tables[AGCTAB_2T].pdata; | ||
181 | phy_reg_arraylen = rtlphy->hwparam_tables[PHY_REG_2T].length; | ||
182 | phy_regarray_table = rtlphy->hwparam_tables[PHY_REG_2T].pdata; | ||
183 | } else { | ||
184 | agctab_arraylen = rtlphy->hwparam_tables[AGCTAB_1T].length; | ||
185 | agctab_array_table = rtlphy->hwparam_tables[AGCTAB_1T].pdata; | ||
186 | phy_reg_arraylen = rtlphy->hwparam_tables[PHY_REG_1T].length; | ||
187 | phy_regarray_table = rtlphy->hwparam_tables[PHY_REG_1T].pdata; | ||
188 | } | ||
189 | if (configtype == BASEBAND_CONFIG_PHY_REG) { | ||
190 | for (i = 0; i < phy_reg_arraylen; i = i + 2) { | ||
191 | if (phy_regarray_table[i] == 0xfe) | ||
192 | mdelay(50); | ||
193 | else if (phy_regarray_table[i] == 0xfd) | ||
194 | mdelay(5); | ||
195 | else if (phy_regarray_table[i] == 0xfc) | ||
196 | mdelay(1); | ||
197 | else if (phy_regarray_table[i] == 0xfb) | ||
198 | udelay(50); | ||
199 | else if (phy_regarray_table[i] == 0xfa) | ||
200 | udelay(5); | ||
201 | else if (phy_regarray_table[i] == 0xf9) | ||
202 | udelay(1); | ||
203 | rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD, | ||
204 | phy_regarray_table[i + 1]); | ||
205 | udelay(1); | ||
206 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
207 | ("The phy_regarray_table[0] is %x" | ||
208 | " Rtl819XPHY_REGArray[1] is %x\n", | ||
209 | phy_regarray_table[i], | ||
210 | phy_regarray_table[i + 1])); | ||
211 | } | ||
212 | rtl92c_phy_config_bb_external_pa(hw); | ||
213 | } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { | ||
214 | for (i = 0; i < agctab_arraylen; i = i + 2) { | ||
215 | rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD, | ||
216 | agctab_array_table[i + 1]); | ||
217 | udelay(1); | ||
218 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
219 | ("The agctab_array_table[0] is " | ||
220 | "%x Rtl819XPHY_REGArray[1] is %x\n", | ||
221 | agctab_array_table[i], | ||
222 | agctab_array_table[i + 1])); | ||
223 | } | ||
224 | } | ||
225 | return true; | ||
226 | } | ||
227 | |||
228 | static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, | ||
229 | u8 configtype) | ||
230 | { | ||
231 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
232 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
233 | int i; | ||
234 | u32 *phy_regarray_table_pg; | ||
235 | u16 phy_regarray_pg_len; | ||
236 | |||
237 | rtlphy->pwrgroup_cnt = 0; | ||
238 | phy_regarray_pg_len = rtlphy->hwparam_tables[PHY_REG_PG].length; | ||
239 | phy_regarray_table_pg = rtlphy->hwparam_tables[PHY_REG_PG].pdata; | ||
240 | if (configtype == BASEBAND_CONFIG_PHY_REG) { | ||
241 | for (i = 0; i < phy_regarray_pg_len; i = i + 3) { | ||
242 | if (phy_regarray_table_pg[i] == 0xfe) | ||
243 | mdelay(50); | ||
244 | else if (phy_regarray_table_pg[i] == 0xfd) | ||
245 | mdelay(5); | ||
246 | else if (phy_regarray_table_pg[i] == 0xfc) | ||
247 | mdelay(1); | ||
248 | else if (phy_regarray_table_pg[i] == 0xfb) | ||
249 | udelay(50); | ||
250 | else if (phy_regarray_table_pg[i] == 0xfa) | ||
251 | udelay(5); | ||
252 | else if (phy_regarray_table_pg[i] == 0xf9) | ||
253 | udelay(1); | ||
254 | _rtl92c_store_pwrIndex_diffrate_offset(hw, | ||
255 | phy_regarray_table_pg[i], | ||
256 | phy_regarray_table_pg[i + 1], | ||
257 | phy_regarray_table_pg[i + 2]); | ||
258 | } | ||
259 | } else { | ||
260 | RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, | ||
261 | ("configtype != BaseBand_Config_PHY_REG\n")); | ||
262 | } | ||
263 | return true; | ||
264 | } | ||
265 | |||
266 | bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, | ||
267 | enum radio_path rfpath) | ||
268 | { | ||
269 | int i; | ||
270 | u32 *radioa_array_table; | ||
271 | u32 *radiob_array_table; | ||
272 | u16 radioa_arraylen, radiob_arraylen; | ||
273 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
274 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
275 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
276 | |||
277 | if (IS_92C_SERIAL(rtlhal->version)) { | ||
278 | radioa_arraylen = rtlphy->hwparam_tables[RADIOA_2T].length; | ||
279 | radioa_array_table = rtlphy->hwparam_tables[RADIOA_2T].pdata; | ||
280 | radiob_arraylen = rtlphy->hwparam_tables[RADIOB_2T].length; | ||
281 | radiob_array_table = rtlphy->hwparam_tables[RADIOB_2T].pdata; | ||
282 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
283 | ("Radio_A:RTL8192CERADIOA_2TARRAY\n")); | ||
284 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
285 | ("Radio_B:RTL8192CE_RADIOB_2TARRAY\n")); | ||
286 | } else { | ||
287 | radioa_arraylen = rtlphy->hwparam_tables[RADIOA_1T].length; | ||
288 | radioa_array_table = rtlphy->hwparam_tables[RADIOA_1T].pdata; | ||
289 | radiob_arraylen = rtlphy->hwparam_tables[RADIOB_1T].length; | ||
290 | radiob_array_table = rtlphy->hwparam_tables[RADIOB_1T].pdata; | ||
291 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
292 | ("Radio_A:RTL8192CE_RADIOA_1TARRAY\n")); | ||
293 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
294 | ("Radio_B:RTL8192CE_RADIOB_1TARRAY\n")); | ||
295 | } | ||
296 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath)); | ||
297 | switch (rfpath) { | ||
298 | case RF90_PATH_A: | ||
299 | for (i = 0; i < radioa_arraylen; i = i + 2) { | ||
300 | if (radioa_array_table[i] == 0xfe) | ||
301 | mdelay(50); | ||
302 | else if (radioa_array_table[i] == 0xfd) | ||
303 | mdelay(5); | ||
304 | else if (radioa_array_table[i] == 0xfc) | ||
305 | mdelay(1); | ||
306 | else if (radioa_array_table[i] == 0xfb) | ||
307 | udelay(50); | ||
308 | else if (radioa_array_table[i] == 0xfa) | ||
309 | udelay(5); | ||
310 | else if (radioa_array_table[i] == 0xf9) | ||
311 | udelay(1); | ||
312 | else { | ||
313 | rtl_set_rfreg(hw, rfpath, radioa_array_table[i], | ||
314 | RFREG_OFFSET_MASK, | ||
315 | radioa_array_table[i + 1]); | ||
316 | udelay(1); | ||
317 | } | ||
318 | } | ||
319 | _rtl92c_phy_config_rf_external_pa(hw, rfpath); | ||
320 | break; | ||
321 | case RF90_PATH_B: | ||
322 | for (i = 0; i < radiob_arraylen; i = i + 2) { | ||
323 | if (radiob_array_table[i] == 0xfe) { | ||
324 | mdelay(50); | ||
325 | } else if (radiob_array_table[i] == 0xfd) | ||
326 | mdelay(5); | ||
327 | else if (radiob_array_table[i] == 0xfc) | ||
328 | mdelay(1); | ||
329 | else if (radiob_array_table[i] == 0xfb) | ||
330 | udelay(50); | ||
331 | else if (radiob_array_table[i] == 0xfa) | ||
332 | udelay(5); | ||
333 | else if (radiob_array_table[i] == 0xf9) | ||
334 | udelay(1); | ||
335 | else { | ||
336 | rtl_set_rfreg(hw, rfpath, radiob_array_table[i], | ||
337 | RFREG_OFFSET_MASK, | ||
338 | radiob_array_table[i + 1]); | ||
339 | udelay(1); | ||
340 | } | ||
341 | } | ||
342 | break; | ||
343 | case RF90_PATH_C: | ||
344 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
345 | ("switch case not process\n")); | ||
346 | break; | ||
347 | case RF90_PATH_D: | ||
348 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
349 | ("switch case not process\n")); | ||
350 | break; | ||
351 | } | ||
352 | return true; | ||
353 | } | ||
354 | |||
355 | void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw) | ||
356 | { | ||
357 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
358 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
359 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
360 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
361 | u8 reg_bw_opmode; | ||
362 | u8 reg_prsr_rsc; | ||
363 | |||
364 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, | ||
365 | ("Switch to %s bandwidth\n", | ||
366 | rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? | ||
367 | "20MHz" : "40MHz")) | ||
368 | if (is_hal_stop(rtlhal)) { | ||
369 | rtlphy->set_bwmode_inprogress = false; | ||
370 | return; | ||
371 | } | ||
372 | reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); | ||
373 | reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); | ||
374 | switch (rtlphy->current_chan_bw) { | ||
375 | case HT_CHANNEL_WIDTH_20: | ||
376 | reg_bw_opmode |= BW_OPMODE_20MHZ; | ||
377 | rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); | ||
378 | break; | ||
379 | case HT_CHANNEL_WIDTH_20_40: | ||
380 | reg_bw_opmode &= ~BW_OPMODE_20MHZ; | ||
381 | rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); | ||
382 | reg_prsr_rsc = | ||
383 | (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5); | ||
384 | rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc); | ||
385 | break; | ||
386 | default: | ||
387 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
388 | ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); | ||
389 | break; | ||
390 | } | ||
391 | switch (rtlphy->current_chan_bw) { | ||
392 | case HT_CHANNEL_WIDTH_20: | ||
393 | rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); | ||
394 | rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); | ||
395 | rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); | ||
396 | break; | ||
397 | case HT_CHANNEL_WIDTH_20_40: | ||
398 | rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); | ||
399 | rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); | ||
400 | rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND, | ||
401 | (mac->cur_40_prime_sc >> 1)); | ||
402 | rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc); | ||
403 | rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0); | ||
404 | rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)), | ||
405 | (mac->cur_40_prime_sc == | ||
406 | HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); | ||
407 | break; | ||
408 | default: | ||
409 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
410 | ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); | ||
411 | break; | ||
412 | } | ||
413 | rtl92c_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); | ||
414 | rtlphy->set_bwmode_inprogress = false; | ||
415 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); | ||
416 | } | ||
417 | |||
418 | void rtl92c_bb_block_on(struct ieee80211_hw *hw) | ||
419 | { | ||
420 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
421 | |||
422 | mutex_lock(&rtlpriv->io.bb_mutex); | ||
423 | rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1); | ||
424 | rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1); | ||
425 | mutex_unlock(&rtlpriv->io.bb_mutex); | ||
426 | } | ||
427 | |||
428 | static void _rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) | ||
429 | { | ||
430 | u8 tmpreg; | ||
431 | u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal; | ||
432 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
433 | |||
434 | tmpreg = rtl_read_byte(rtlpriv, 0xd03); | ||
435 | |||
436 | if ((tmpreg & 0x70) != 0) | ||
437 | rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F); | ||
438 | else | ||
439 | rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); | ||
440 | |||
441 | if ((tmpreg & 0x70) != 0) { | ||
442 | rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS); | ||
443 | if (is2t) | ||
444 | rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00, | ||
445 | MASK12BITS); | ||
446 | rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, | ||
447 | (rf_a_mode & 0x8FFFF) | 0x10000); | ||
448 | if (is2t) | ||
449 | rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, | ||
450 | (rf_b_mode & 0x8FFFF) | 0x10000); | ||
451 | } | ||
452 | lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS); | ||
453 | rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000); | ||
454 | mdelay(100); | ||
455 | if ((tmpreg & 0x70) != 0) { | ||
456 | rtl_write_byte(rtlpriv, 0xd03, tmpreg); | ||
457 | rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode); | ||
458 | if (is2t) | ||
459 | rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, | ||
460 | rf_b_mode); | ||
461 | } else { | ||
462 | rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); | ||
463 | } | ||
464 | } | ||
465 | |||
466 | static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, | ||
467 | enum rf_pwrstate rfpwr_state) | ||
468 | { | ||
469 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
470 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); | ||
471 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
472 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
473 | bool bresult = true; | ||
474 | u8 i, queue_id; | ||
475 | struct rtl8192_tx_ring *ring = NULL; | ||
476 | |||
477 | ppsc->set_rfpowerstate_inprogress = true; | ||
478 | switch (rfpwr_state) { | ||
479 | case ERFON: | ||
480 | if ((ppsc->rfpwr_state == ERFOFF) && | ||
481 | RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { | ||
482 | bool rtstatus; | ||
483 | u32 InitializeCount = 0; | ||
484 | |||
485 | do { | ||
486 | InitializeCount++; | ||
487 | RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, | ||
488 | ("IPS Set eRf nic enable\n")); | ||
489 | rtstatus = rtl_ps_enable_nic(hw); | ||
490 | } while ((rtstatus != true) | ||
491 | && (InitializeCount < 10)); | ||
492 | RT_CLEAR_PS_LEVEL(ppsc, | ||
493 | RT_RF_OFF_LEVL_HALT_NIC); | ||
494 | } else { | ||
495 | RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, | ||
496 | ("Set ERFON sleeped:%d ms\n", | ||
497 | jiffies_to_msecs(jiffies - | ||
498 | ppsc-> | ||
499 | last_sleep_jiffies))); | ||
500 | ppsc->last_awake_jiffies = jiffies; | ||
501 | rtl92ce_phy_set_rf_on(hw); | ||
502 | } | ||
503 | if (mac->link_state == MAC80211_LINKED) { | ||
504 | rtlpriv->cfg->ops->led_control(hw, | ||
505 | LED_CTL_LINK); | ||
506 | } else { | ||
507 | rtlpriv->cfg->ops->led_control(hw, | ||
508 | LED_CTL_NO_LINK); | ||
509 | } | ||
510 | break; | ||
511 | case ERFOFF: | ||
512 | for (queue_id = 0, i = 0; | ||
513 | queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { | ||
514 | ring = &pcipriv->dev.tx_ring[queue_id]; | ||
515 | if (skb_queue_len(&ring->queue) == 0 || | ||
516 | queue_id == BEACON_QUEUE) { | ||
517 | queue_id++; | ||
518 | continue; | ||
519 | } else { | ||
520 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | ||
521 | ("eRf Off/Sleep: %d times " | ||
522 | "TcbBusyQueue[%d] " | ||
523 | "=%d before doze!\n", (i + 1), | ||
524 | queue_id, | ||
525 | skb_queue_len(&ring->queue))); | ||
526 | udelay(10); | ||
527 | i++; | ||
528 | } | ||
529 | if (i >= MAX_DOZE_WAITING_TIMES_9x) { | ||
530 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | ||
531 | ("\nERFOFF: %d times " | ||
532 | "TcbBusyQueue[%d] = %d !\n", | ||
533 | MAX_DOZE_WAITING_TIMES_9x, | ||
534 | queue_id, | ||
535 | skb_queue_len(&ring->queue))); | ||
536 | break; | ||
537 | } | ||
538 | } | ||
539 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { | ||
540 | RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, | ||
541 | ("IPS Set eRf nic disable\n")); | ||
542 | rtl_ps_disable_nic(hw); | ||
543 | RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); | ||
544 | } else { | ||
545 | if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) { | ||
546 | rtlpriv->cfg->ops->led_control(hw, | ||
547 | LED_CTL_NO_LINK); | ||
548 | } else { | ||
549 | rtlpriv->cfg->ops->led_control(hw, | ||
550 | LED_CTL_POWER_OFF); | ||
551 | } | ||
552 | } | ||
553 | break; | ||
554 | case ERFSLEEP: | ||
555 | if (ppsc->rfpwr_state == ERFOFF) | ||
556 | break; | ||
557 | for (queue_id = 0, i = 0; | ||
558 | queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { | ||
559 | ring = &pcipriv->dev.tx_ring[queue_id]; | ||
560 | if (skb_queue_len(&ring->queue) == 0) { | ||
561 | queue_id++; | ||
562 | continue; | ||
563 | } else { | ||
564 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | ||
565 | ("eRf Off/Sleep: %d times " | ||
566 | "TcbBusyQueue[%d] =%d before " | ||
567 | "doze!\n", (i + 1), queue_id, | ||
568 | skb_queue_len(&ring->queue))); | ||
569 | udelay(10); | ||
570 | i++; | ||
571 | } | ||
572 | if (i >= MAX_DOZE_WAITING_TIMES_9x) { | ||
573 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | ||
574 | ("\n ERFSLEEP: %d times " | ||
575 | "TcbBusyQueue[%d] = %d !\n", | ||
576 | MAX_DOZE_WAITING_TIMES_9x, | ||
577 | queue_id, | ||
578 | skb_queue_len(&ring->queue))); | ||
579 | break; | ||
580 | } | ||
581 | } | ||
582 | RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, | ||
583 | ("Set ERFSLEEP awaked:%d ms\n", | ||
584 | jiffies_to_msecs(jiffies - | ||
585 | ppsc->last_awake_jiffies))); | ||
586 | ppsc->last_sleep_jiffies = jiffies; | ||
587 | _rtl92ce_phy_set_rf_sleep(hw); | ||
588 | break; | ||
589 | default: | ||
590 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
591 | ("switch case not process\n")); | ||
592 | bresult = false; | ||
593 | break; | ||
594 | } | ||
595 | if (bresult) | ||
596 | ppsc->rfpwr_state = rfpwr_state; | ||
597 | ppsc->set_rfpowerstate_inprogress = false; | ||
598 | return bresult; | ||
599 | } | ||
600 | |||
601 | bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw, | ||
602 | enum rf_pwrstate rfpwr_state) | ||
603 | { | ||
604 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
605 | bool bresult = false; | ||
606 | |||
607 | if (rfpwr_state == ppsc->rfpwr_state) | ||
608 | return bresult; | ||
609 | bresult = _rtl92ce_phy_set_rf_power_state(hw, rfpwr_state); | ||
610 | return bresult; | ||
611 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h new file mode 100644 index 000000000000..c456c15afbf1 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h | |||
@@ -0,0 +1,34 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 Realtek Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #include "../rtl8192ce/phy.h" | ||
31 | |||
32 | void rtl92c_bb_block_on(struct ieee80211_hw *hw); | ||
33 | bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath); | ||
34 | void rtl92c_phy_set_io(struct ieee80211_hw *hw); | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/reg.h b/drivers/net/wireless/rtlwifi/rtl8192cu/reg.h new file mode 100644 index 000000000000..7f1be614c998 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/reg.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 Realtek Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #include "../rtl8192ce/reg.h" | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c new file mode 100644 index 000000000000..9149adcc8fa5 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c | |||
@@ -0,0 +1,493 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 Realtek Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #include "../wifi.h" | ||
31 | #include "reg.h" | ||
32 | #include "def.h" | ||
33 | #include "phy.h" | ||
34 | #include "rf.h" | ||
35 | #include "dm.h" | ||
36 | |||
37 | static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw); | ||
38 | |||
39 | void rtl92c_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) | ||
40 | { | ||
41 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
42 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
43 | |||
44 | switch (bandwidth) { | ||
45 | case HT_CHANNEL_WIDTH_20: | ||
46 | rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & | ||
47 | 0xfffff3ff) | 0x0400); | ||
48 | rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, | ||
49 | rtlphy->rfreg_chnlval[0]); | ||
50 | break; | ||
51 | case HT_CHANNEL_WIDTH_20_40: | ||
52 | rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & | ||
53 | 0xfffff3ff)); | ||
54 | rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, | ||
55 | rtlphy->rfreg_chnlval[0]); | ||
56 | break; | ||
57 | default: | ||
58 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
59 | ("unknown bandwidth: %#X\n", bandwidth)); | ||
60 | break; | ||
61 | } | ||
62 | } | ||
63 | |||
64 | void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, | ||
65 | u8 *ppowerlevel) | ||
66 | { | ||
67 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
68 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
69 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | ||
70 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
71 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
72 | u32 tx_agc[2] = { 0, 0 }, tmpval = 0; | ||
73 | bool turbo_scanoff = false; | ||
74 | u8 idx1, idx2; | ||
75 | u8 *ptr; | ||
76 | |||
77 | if (rtlhal->interface == INTF_PCI) { | ||
78 | if (rtlefuse->eeprom_regulatory != 0) | ||
79 | turbo_scanoff = true; | ||
80 | } else { | ||
81 | if ((rtlefuse->eeprom_regulatory != 0) || | ||
82 | (rtlefuse->external_pa)) | ||
83 | turbo_scanoff = true; | ||
84 | } | ||
85 | if (mac->act_scanning == true) { | ||
86 | tx_agc[RF90_PATH_A] = 0x3f3f3f3f; | ||
87 | tx_agc[RF90_PATH_B] = 0x3f3f3f3f; | ||
88 | if (turbo_scanoff) { | ||
89 | for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { | ||
90 | tx_agc[idx1] = ppowerlevel[idx1] | | ||
91 | (ppowerlevel[idx1] << 8) | | ||
92 | (ppowerlevel[idx1] << 16) | | ||
93 | (ppowerlevel[idx1] << 24); | ||
94 | if (rtlhal->interface == INTF_USB) { | ||
95 | if (tx_agc[idx1] > 0x20 && | ||
96 | rtlefuse->external_pa) | ||
97 | tx_agc[idx1] = 0x20; | ||
98 | } | ||
99 | } | ||
100 | } | ||
101 | } else { | ||
102 | if (rtlpriv->dm.dynamic_txhighpower_lvl == | ||
103 | TXHIGHPWRLEVEL_LEVEL1) { | ||
104 | tx_agc[RF90_PATH_A] = 0x10101010; | ||
105 | tx_agc[RF90_PATH_B] = 0x10101010; | ||
106 | } else if (rtlpriv->dm.dynamic_txhighpower_lvl == | ||
107 | TXHIGHPWRLEVEL_LEVEL1) { | ||
108 | tx_agc[RF90_PATH_A] = 0x00000000; | ||
109 | tx_agc[RF90_PATH_B] = 0x00000000; | ||
110 | } else{ | ||
111 | for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { | ||
112 | tx_agc[idx1] = ppowerlevel[idx1] | | ||
113 | (ppowerlevel[idx1] << 8) | | ||
114 | (ppowerlevel[idx1] << 16) | | ||
115 | (ppowerlevel[idx1] << 24); | ||
116 | } | ||
117 | if (rtlefuse->eeprom_regulatory == 0) { | ||
118 | tmpval = (rtlphy->mcs_txpwrlevel_origoffset | ||
119 | [0][6]) + | ||
120 | (rtlphy->mcs_txpwrlevel_origoffset | ||
121 | [0][7] << 8); | ||
122 | tx_agc[RF90_PATH_A] += tmpval; | ||
123 | tmpval = (rtlphy->mcs_txpwrlevel_origoffset | ||
124 | [0][14]) + | ||
125 | (rtlphy->mcs_txpwrlevel_origoffset | ||
126 | [0][15] << 24); | ||
127 | tx_agc[RF90_PATH_B] += tmpval; | ||
128 | } | ||
129 | } | ||
130 | } | ||
131 | for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { | ||
132 | ptr = (u8 *) (&(tx_agc[idx1])); | ||
133 | for (idx2 = 0; idx2 < 4; idx2++) { | ||
134 | if (*ptr > RF6052_MAX_TX_PWR) | ||
135 | *ptr = RF6052_MAX_TX_PWR; | ||
136 | ptr++; | ||
137 | } | ||
138 | } | ||
139 | tmpval = tx_agc[RF90_PATH_A] & 0xff; | ||
140 | rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval); | ||
141 | |||
142 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | ||
143 | ("CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, | ||
144 | RTXAGC_A_CCK1_MCS32)); | ||
145 | |||
146 | tmpval = tx_agc[RF90_PATH_A] >> 8; | ||
147 | if (mac->mode == WIRELESS_MODE_B) | ||
148 | tmpval = tmpval & 0xff00ffff; | ||
149 | rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); | ||
150 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | ||
151 | ("CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, | ||
152 | RTXAGC_B_CCK11_A_CCK2_11)); | ||
153 | tmpval = tx_agc[RF90_PATH_B] >> 24; | ||
154 | rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval); | ||
155 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | ||
156 | ("CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, | ||
157 | RTXAGC_B_CCK11_A_CCK2_11)); | ||
158 | tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff; | ||
159 | rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval); | ||
160 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | ||
161 | ("CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, | ||
162 | RTXAGC_B_CCK1_55_MCS32)); | ||
163 | } | ||
164 | |||
165 | static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw, | ||
166 | u8 *ppowerlevel, u8 channel, | ||
167 | u32 *ofdmbase, u32 *mcsbase) | ||
168 | { | ||
169 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
170 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
171 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
172 | u32 powerBase0, powerBase1; | ||
173 | u8 legacy_pwrdiff = 0, ht20_pwrdiff = 0; | ||
174 | u8 i, powerlevel[2]; | ||
175 | |||
176 | for (i = 0; i < 2; i++) { | ||
177 | powerlevel[i] = ppowerlevel[i]; | ||
178 | legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff[i][channel - 1]; | ||
179 | powerBase0 = powerlevel[i] + legacy_pwrdiff; | ||
180 | powerBase0 = (powerBase0 << 24) | (powerBase0 << 16) | | ||
181 | (powerBase0 << 8) | powerBase0; | ||
182 | *(ofdmbase + i) = powerBase0; | ||
183 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | ||
184 | (" [OFDM power base index rf(%c) = 0x%x]\n", | ||
185 | ((i == 0) ? 'A' : 'B'), *(ofdmbase + i))); | ||
186 | } | ||
187 | for (i = 0; i < 2; i++) { | ||
188 | if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) { | ||
189 | ht20_pwrdiff = rtlefuse->txpwr_ht20diff[i][channel - 1]; | ||
190 | powerlevel[i] += ht20_pwrdiff; | ||
191 | } | ||
192 | powerBase1 = powerlevel[i]; | ||
193 | powerBase1 = (powerBase1 << 24) | | ||
194 | (powerBase1 << 16) | (powerBase1 << 8) | powerBase1; | ||
195 | *(mcsbase + i) = powerBase1; | ||
196 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | ||
197 | (" [MCS power base index rf(%c) = 0x%x]\n", | ||
198 | ((i == 0) ? 'A' : 'B'), *(mcsbase + i))); | ||
199 | } | ||
200 | } | ||
201 | |||
202 | static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, | ||
203 | u8 channel, u8 index, | ||
204 | u32 *powerBase0, | ||
205 | u32 *powerBase1, | ||
206 | u32 *p_outwriteval) | ||
207 | { | ||
208 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
209 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
210 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
211 | u8 i, chnlgroup = 0, pwr_diff_limit[4]; | ||
212 | u32 writeVal, customer_limit, rf; | ||
213 | |||
214 | for (rf = 0; rf < 2; rf++) { | ||
215 | switch (rtlefuse->eeprom_regulatory) { | ||
216 | case 0: | ||
217 | chnlgroup = 0; | ||
218 | writeVal = rtlphy->mcs_txpwrlevel_origoffset | ||
219 | [chnlgroup][index + (rf ? 8 : 0)] | ||
220 | + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); | ||
221 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | ||
222 | ("RTK better performance,writeVal(%c) = 0x%x\n", | ||
223 | ((rf == 0) ? 'A' : 'B'), writeVal)); | ||
224 | break; | ||
225 | case 1: | ||
226 | if (rtlphy->pwrgroup_cnt == 1) | ||
227 | chnlgroup = 0; | ||
228 | if (rtlphy->pwrgroup_cnt >= 3) { | ||
229 | if (channel <= 3) | ||
230 | chnlgroup = 0; | ||
231 | else if (channel >= 4 && channel <= 9) | ||
232 | chnlgroup = 1; | ||
233 | else if (channel > 9) | ||
234 | chnlgroup = 2; | ||
235 | if (rtlphy->current_chan_bw == | ||
236 | HT_CHANNEL_WIDTH_20) | ||
237 | chnlgroup++; | ||
238 | else | ||
239 | chnlgroup += 4; | ||
240 | } | ||
241 | writeVal = rtlphy->mcs_txpwrlevel_origoffset | ||
242 | [chnlgroup][index + | ||
243 | (rf ? 8 : 0)] + | ||
244 | ((index < 2) ? powerBase0[rf] : | ||
245 | powerBase1[rf]); | ||
246 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | ||
247 | ("Realtek regulatory, 20MHz, " | ||
248 | "writeVal(%c) = 0x%x\n", | ||
249 | ((rf == 0) ? 'A' : 'B'), writeVal)); | ||
250 | break; | ||
251 | case 2: | ||
252 | writeVal = ((index < 2) ? powerBase0[rf] : | ||
253 | powerBase1[rf]); | ||
254 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | ||
255 | ("Better regulatory,writeVal(%c) = 0x%x\n", | ||
256 | ((rf == 0) ? 'A' : 'B'), writeVal)); | ||
257 | break; | ||
258 | case 3: | ||
259 | chnlgroup = 0; | ||
260 | if (rtlphy->current_chan_bw == | ||
261 | HT_CHANNEL_WIDTH_20_40) { | ||
262 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | ||
263 | ("customer's limit, 40MHzrf(%c) = " | ||
264 | "0x%x\n", ((rf == 0) ? 'A' : 'B'), | ||
265 | rtlefuse->pwrgroup_ht40[rf] | ||
266 | [channel - 1])); | ||
267 | } else { | ||
268 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | ||
269 | ("customer's limit, 20MHz rf(%c) = " | ||
270 | "0x%x\n", ((rf == 0) ? 'A' : 'B'), | ||
271 | rtlefuse->pwrgroup_ht20[rf] | ||
272 | [channel - 1])); | ||
273 | } | ||
274 | for (i = 0; i < 4; i++) { | ||
275 | pwr_diff_limit[i] = | ||
276 | (u8) ((rtlphy->mcs_txpwrlevel_origoffset | ||
277 | [chnlgroup][index + (rf ? 8 : 0)] | ||
278 | & (0x7f << (i * 8))) >> (i * 8)); | ||
279 | if (rtlphy->current_chan_bw == | ||
280 | HT_CHANNEL_WIDTH_20_40) { | ||
281 | if (pwr_diff_limit[i] > | ||
282 | rtlefuse->pwrgroup_ht40[rf] | ||
283 | [channel - 1]) | ||
284 | pwr_diff_limit[i] = rtlefuse-> | ||
285 | pwrgroup_ht40[rf] | ||
286 | [channel - 1]; | ||
287 | } else { | ||
288 | if (pwr_diff_limit[i] > | ||
289 | rtlefuse->pwrgroup_ht20[rf] | ||
290 | [channel - 1]) | ||
291 | pwr_diff_limit[i] = | ||
292 | rtlefuse->pwrgroup_ht20[rf] | ||
293 | [channel - 1]; | ||
294 | } | ||
295 | } | ||
296 | customer_limit = (pwr_diff_limit[3] << 24) | | ||
297 | (pwr_diff_limit[2] << 16) | | ||
298 | (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]); | ||
299 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | ||
300 | ("Customer's limit rf(%c) = 0x%x\n", | ||
301 | ((rf == 0) ? 'A' : 'B'), customer_limit)); | ||
302 | writeVal = customer_limit + ((index < 2) ? | ||
303 | powerBase0[rf] : powerBase1[rf]); | ||
304 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | ||
305 | ("Customer, writeVal rf(%c)= 0x%x\n", | ||
306 | ((rf == 0) ? 'A' : 'B'), writeVal)); | ||
307 | break; | ||
308 | default: | ||
309 | chnlgroup = 0; | ||
310 | writeVal = rtlphy->mcs_txpwrlevel_origoffset[chnlgroup] | ||
311 | [index + (rf ? 8 : 0)] + ((index < 2) ? | ||
312 | powerBase0[rf] : powerBase1[rf]); | ||
313 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, ("RTK better " | ||
314 | "performance, writeValrf(%c) = 0x%x\n", | ||
315 | ((rf == 0) ? 'A' : 'B'), writeVal)); | ||
316 | break; | ||
317 | } | ||
318 | if (rtlpriv->dm.dynamic_txhighpower_lvl == | ||
319 | TXHIGHPWRLEVEL_LEVEL1) | ||
320 | writeVal = 0x14141414; | ||
321 | else if (rtlpriv->dm.dynamic_txhighpower_lvl == | ||
322 | TXHIGHPWRLEVEL_LEVEL2) | ||
323 | writeVal = 0x00000000; | ||
324 | if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1) | ||
325 | writeVal = writeVal - 0x06060606; | ||
326 | else if (rtlpriv->dm.dynamic_txhighpower_lvl == | ||
327 | TXHIGHPWRLEVEL_BT2) | ||
328 | writeVal = writeVal; | ||
329 | *(p_outwriteval + rf) = writeVal; | ||
330 | } | ||
331 | } | ||
332 | |||
333 | static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw, | ||
334 | u8 index, u32 *pValue) | ||
335 | { | ||
336 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
337 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
338 | u16 regoffset_a[6] = { | ||
339 | RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24, | ||
340 | RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04, | ||
341 | RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12 | ||
342 | }; | ||
343 | u16 regoffset_b[6] = { | ||
344 | RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24, | ||
345 | RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04, | ||
346 | RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12 | ||
347 | }; | ||
348 | u8 i, rf, pwr_val[4]; | ||
349 | u32 writeVal; | ||
350 | u16 regoffset; | ||
351 | |||
352 | for (rf = 0; rf < 2; rf++) { | ||
353 | writeVal = pValue[rf]; | ||
354 | for (i = 0; i < 4; i++) { | ||
355 | pwr_val[i] = (u8)((writeVal & (0x7f << (i * 8))) >> | ||
356 | (i * 8)); | ||
357 | if (pwr_val[i] > RF6052_MAX_TX_PWR) | ||
358 | pwr_val[i] = RF6052_MAX_TX_PWR; | ||
359 | } | ||
360 | writeVal = (pwr_val[3] << 24) | (pwr_val[2] << 16) | | ||
361 | (pwr_val[1] << 8) | pwr_val[0]; | ||
362 | if (rf == 0) | ||
363 | regoffset = regoffset_a[index]; | ||
364 | else | ||
365 | regoffset = regoffset_b[index]; | ||
366 | rtl_set_bbreg(hw, regoffset, MASKDWORD, writeVal); | ||
367 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | ||
368 | ("Set 0x%x = %08x\n", regoffset, writeVal)); | ||
369 | if (((get_rf_type(rtlphy) == RF_2T2R) && | ||
370 | (regoffset == RTXAGC_A_MCS15_MCS12 || | ||
371 | regoffset == RTXAGC_B_MCS15_MCS12)) || | ||
372 | ((get_rf_type(rtlphy) != RF_2T2R) && | ||
373 | (regoffset == RTXAGC_A_MCS07_MCS04 || | ||
374 | regoffset == RTXAGC_B_MCS07_MCS04))) { | ||
375 | writeVal = pwr_val[3]; | ||
376 | if (regoffset == RTXAGC_A_MCS15_MCS12 || | ||
377 | regoffset == RTXAGC_A_MCS07_MCS04) | ||
378 | regoffset = 0xc90; | ||
379 | if (regoffset == RTXAGC_B_MCS15_MCS12 || | ||
380 | regoffset == RTXAGC_B_MCS07_MCS04) | ||
381 | regoffset = 0xc98; | ||
382 | for (i = 0; i < 3; i++) { | ||
383 | writeVal = (writeVal > 6) ? (writeVal - 6) : 0; | ||
384 | rtl_write_byte(rtlpriv, (u32)(regoffset + i), | ||
385 | (u8)writeVal); | ||
386 | } | ||
387 | } | ||
388 | } | ||
389 | } | ||
390 | |||
391 | void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, | ||
392 | u8 *ppowerlevel, u8 channel) | ||
393 | { | ||
394 | u32 writeVal[2], powerBase0[2], powerBase1[2]; | ||
395 | u8 index = 0; | ||
396 | |||
397 | rtl92c_phy_get_power_base(hw, ppowerlevel, | ||
398 | channel, &powerBase0[0], &powerBase1[0]); | ||
399 | for (index = 0; index < 6; index++) { | ||
400 | _rtl92c_get_txpower_writeval_by_regulatory(hw, | ||
401 | channel, index, | ||
402 | &powerBase0[0], | ||
403 | &powerBase1[0], | ||
404 | &writeVal[0]); | ||
405 | _rtl92c_write_ofdm_power_reg(hw, index, &writeVal[0]); | ||
406 | } | ||
407 | } | ||
408 | |||
409 | bool rtl92c_phy_rf6052_config(struct ieee80211_hw *hw) | ||
410 | { | ||
411 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
412 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
413 | bool rtstatus = true; | ||
414 | u8 b_reg_hwparafile = 1; | ||
415 | |||
416 | if (rtlphy->rf_type == RF_1T1R) | ||
417 | rtlphy->num_total_rfpath = 1; | ||
418 | else | ||
419 | rtlphy->num_total_rfpath = 2; | ||
420 | if (b_reg_hwparafile == 1) | ||
421 | rtstatus = _rtl92c_phy_rf6052_config_parafile(hw); | ||
422 | return rtstatus; | ||
423 | } | ||
424 | |||
425 | static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw) | ||
426 | { | ||
427 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
428 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
429 | u32 u4_regvalue = 0; | ||
430 | u8 rfpath; | ||
431 | bool rtstatus = true; | ||
432 | struct bb_reg_def *pphyreg; | ||
433 | |||
434 | for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { | ||
435 | pphyreg = &rtlphy->phyreg_def[rfpath]; | ||
436 | switch (rfpath) { | ||
437 | case RF90_PATH_A: | ||
438 | case RF90_PATH_C: | ||
439 | u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, | ||
440 | BRFSI_RFENV); | ||
441 | break; | ||
442 | case RF90_PATH_B: | ||
443 | case RF90_PATH_D: | ||
444 | u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, | ||
445 | BRFSI_RFENV << 16); | ||
446 | break; | ||
447 | } | ||
448 | rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1); | ||
449 | udelay(1); | ||
450 | rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1); | ||
451 | udelay(1); | ||
452 | rtl_set_bbreg(hw, pphyreg->rfhssi_para2, | ||
453 | B3WIREADDREAALENGTH, 0x0); | ||
454 | udelay(1); | ||
455 | rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0); | ||
456 | udelay(1); | ||
457 | switch (rfpath) { | ||
458 | case RF90_PATH_A: | ||
459 | rtstatus = rtl92c_phy_config_rf_with_headerfile(hw, | ||
460 | (enum radio_path) rfpath); | ||
461 | break; | ||
462 | case RF90_PATH_B: | ||
463 | rtstatus = rtl92c_phy_config_rf_with_headerfile(hw, | ||
464 | (enum radio_path) rfpath); | ||
465 | break; | ||
466 | case RF90_PATH_C: | ||
467 | break; | ||
468 | case RF90_PATH_D: | ||
469 | break; | ||
470 | } | ||
471 | switch (rfpath) { | ||
472 | case RF90_PATH_A: | ||
473 | case RF90_PATH_C: | ||
474 | rtl_set_bbreg(hw, pphyreg->rfintfs, | ||
475 | BRFSI_RFENV, u4_regvalue); | ||
476 | break; | ||
477 | case RF90_PATH_B: | ||
478 | case RF90_PATH_D: | ||
479 | rtl_set_bbreg(hw, pphyreg->rfintfs, | ||
480 | BRFSI_RFENV << 16, u4_regvalue); | ||
481 | break; | ||
482 | } | ||
483 | if (rtstatus != true) { | ||
484 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
485 | ("Radio[%d] Fail!!", rfpath)); | ||
486 | goto phy_rf_cfg_fail; | ||
487 | } | ||
488 | } | ||
489 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("<---\n")); | ||
490 | return rtstatus; | ||
491 | phy_rf_cfg_fail: | ||
492 | return rtstatus; | ||
493 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h new file mode 100644 index 000000000000..c4ed125ef4dc --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 Realtek Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #include "../rtl8192ce/rf.h" | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c new file mode 100644 index 000000000000..4e937e0da8e2 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | |||
@@ -0,0 +1,327 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #include "../wifi.h" | ||
31 | #include "../core.h" | ||
32 | #include "../usb.h" | ||
33 | #include "../efuse.h" | ||
34 | #include "reg.h" | ||
35 | #include "def.h" | ||
36 | #include "phy.h" | ||
37 | #include "mac.h" | ||
38 | #include "dm.h" | ||
39 | #include "sw.h" | ||
40 | #include "trx.h" | ||
41 | #include "led.h" | ||
42 | #include "hw.h" | ||
43 | |||
44 | |||
45 | MODULE_AUTHOR("Georgia <georgia@realtek.com>"); | ||
46 | MODULE_AUTHOR("Ziv Huang <ziv_huang@realtek.com>"); | ||
47 | MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>"); | ||
48 | MODULE_LICENSE("GPL"); | ||
49 | MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n USB wireless"); | ||
50 | MODULE_FIRMWARE("rtlwifi/rtl8192cufw.bin"); | ||
51 | |||
52 | static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw) | ||
53 | { | ||
54 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
55 | |||
56 | rtlpriv->dm.dm_initialgain_enable = 1; | ||
57 | rtlpriv->dm.dm_flag = 0; | ||
58 | rtlpriv->dm.disable_framebursting = 0; | ||
59 | rtlpriv->dm.thermalvalue = 0; | ||
60 | rtlpriv->rtlhal.pfirmware = vmalloc(0x4000); | ||
61 | if (!rtlpriv->rtlhal.pfirmware) { | ||
62 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
63 | ("Can't alloc buffer for fw.\n")); | ||
64 | return 1; | ||
65 | } | ||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | static void rtl92cu_deinit_sw_vars(struct ieee80211_hw *hw) | ||
70 | { | ||
71 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
72 | |||
73 | if (rtlpriv->rtlhal.pfirmware) { | ||
74 | vfree(rtlpriv->rtlhal.pfirmware); | ||
75 | rtlpriv->rtlhal.pfirmware = NULL; | ||
76 | } | ||
77 | } | ||
78 | |||
79 | static struct rtl_hal_ops rtl8192cu_hal_ops = { | ||
80 | .init_sw_vars = rtl92cu_init_sw_vars, | ||
81 | .deinit_sw_vars = rtl92cu_deinit_sw_vars, | ||
82 | .read_chip_version = rtl92c_read_chip_version, | ||
83 | .read_eeprom_info = rtl92cu_read_eeprom_info, | ||
84 | .enable_interrupt = rtl92c_enable_interrupt, | ||
85 | .disable_interrupt = rtl92c_disable_interrupt, | ||
86 | .hw_init = rtl92cu_hw_init, | ||
87 | .hw_disable = rtl92cu_card_disable, | ||
88 | .set_network_type = rtl92cu_set_network_type, | ||
89 | .set_chk_bssid = rtl92cu_set_check_bssid, | ||
90 | .set_qos = rtl92c_set_qos, | ||
91 | .set_bcn_reg = rtl92cu_set_beacon_related_registers, | ||
92 | .set_bcn_intv = rtl92cu_set_beacon_interval, | ||
93 | .update_interrupt_mask = rtl92cu_update_interrupt_mask, | ||
94 | .get_hw_reg = rtl92cu_get_hw_reg, | ||
95 | .set_hw_reg = rtl92cu_set_hw_reg, | ||
96 | .update_rate_table = rtl92cu_update_hal_rate_table, | ||
97 | .update_rate_mask = rtl92cu_update_hal_rate_mask, | ||
98 | .fill_tx_desc = rtl92cu_tx_fill_desc, | ||
99 | .fill_fake_txdesc = rtl92cu_fill_fake_txdesc, | ||
100 | .fill_tx_cmddesc = rtl92cu_tx_fill_cmddesc, | ||
101 | .cmd_send_packet = rtl92cu_cmd_send_packet, | ||
102 | .query_rx_desc = rtl92cu_rx_query_desc, | ||
103 | .set_channel_access = rtl92cu_update_channel_access_setting, | ||
104 | .radio_onoff_checking = rtl92cu_gpio_radio_on_off_checking, | ||
105 | .set_bw_mode = rtl92c_phy_set_bw_mode, | ||
106 | .switch_channel = rtl92c_phy_sw_chnl, | ||
107 | .dm_watchdog = rtl92c_dm_watchdog, | ||
108 | .scan_operation_backup = rtl92c_phy_scan_operation_backup, | ||
109 | .set_rf_power_state = rtl92c_phy_set_rf_power_state, | ||
110 | .led_control = rtl92cu_led_control, | ||
111 | .enable_hw_sec = rtl92cu_enable_hw_security_config, | ||
112 | .set_key = rtl92c_set_key, | ||
113 | .init_sw_leds = rtl92cu_init_sw_leds, | ||
114 | .deinit_sw_leds = rtl92cu_deinit_sw_leds, | ||
115 | .get_bbreg = rtl92c_phy_query_bb_reg, | ||
116 | .set_bbreg = rtl92c_phy_set_bb_reg, | ||
117 | .get_rfreg = rtl92c_phy_query_rf_reg, | ||
118 | .set_rfreg = rtl92c_phy_set_rf_reg, | ||
119 | }; | ||
120 | |||
121 | static struct rtl_mod_params rtl92cu_mod_params = { | ||
122 | .sw_crypto = 0, | ||
123 | }; | ||
124 | |||
125 | static struct rtl_hal_usbint_cfg rtl92cu_interface_cfg = { | ||
126 | /* rx */ | ||
127 | .in_ep_num = RTL92C_USB_BULK_IN_NUM, | ||
128 | .rx_urb_num = RTL92C_NUM_RX_URBS, | ||
129 | .rx_max_size = RTL92C_SIZE_MAX_RX_BUFFER, | ||
130 | .usb_rx_hdl = rtl8192cu_rx_hdl, | ||
131 | .usb_rx_segregate_hdl = NULL, /* rtl8192c_rx_segregate_hdl; */ | ||
132 | /* tx */ | ||
133 | .usb_tx_cleanup = rtl8192c_tx_cleanup, | ||
134 | .usb_tx_post_hdl = rtl8192c_tx_post_hdl, | ||
135 | .usb_tx_aggregate_hdl = rtl8192c_tx_aggregate_hdl, | ||
136 | /* endpoint mapping */ | ||
137 | .usb_endpoint_mapping = rtl8192cu_endpoint_mapping, | ||
138 | .usb_mq_to_hwq = rtl8192cu_mq_to_hwq, | ||
139 | }; | ||
140 | |||
141 | static struct rtl_hal_cfg rtl92cu_hal_cfg = { | ||
142 | .name = "rtl92c_usb", | ||
143 | .fw_name = "rtlwifi/rtl8192cufw.bin", | ||
144 | .ops = &rtl8192cu_hal_ops, | ||
145 | .mod_params = &rtl92cu_mod_params, | ||
146 | .usb_interface_cfg = &rtl92cu_interface_cfg, | ||
147 | |||
148 | .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, | ||
149 | .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN, | ||
150 | .maps[SYS_CLK] = REG_SYS_CLKR, | ||
151 | .maps[MAC_RCR_AM] = AM, | ||
152 | .maps[MAC_RCR_AB] = AB, | ||
153 | .maps[MAC_RCR_ACRC32] = ACRC32, | ||
154 | .maps[MAC_RCR_ACF] = ACF, | ||
155 | .maps[MAC_RCR_AAP] = AAP, | ||
156 | |||
157 | .maps[EFUSE_TEST] = REG_EFUSE_TEST, | ||
158 | .maps[EFUSE_CTRL] = REG_EFUSE_CTRL, | ||
159 | .maps[EFUSE_CLK] = 0, | ||
160 | .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL, | ||
161 | .maps[EFUSE_PWC_EV12V] = PWC_EV12V, | ||
162 | .maps[EFUSE_FEN_ELDR] = FEN_ELDR, | ||
163 | .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN, | ||
164 | .maps[EFUSE_ANA8M] = EFUSE_ANA8M, | ||
165 | .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE, | ||
166 | .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION, | ||
167 | .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN, | ||
168 | |||
169 | .maps[RWCAM] = REG_CAMCMD, | ||
170 | .maps[WCAMI] = REG_CAMWRITE, | ||
171 | .maps[RCAMO] = REG_CAMREAD, | ||
172 | .maps[CAMDBG] = REG_CAMDBG, | ||
173 | .maps[SECR] = REG_SECCFG, | ||
174 | .maps[SEC_CAM_NONE] = CAM_NONE, | ||
175 | .maps[SEC_CAM_WEP40] = CAM_WEP40, | ||
176 | .maps[SEC_CAM_TKIP] = CAM_TKIP, | ||
177 | .maps[SEC_CAM_AES] = CAM_AES, | ||
178 | .maps[SEC_CAM_WEP104] = CAM_WEP104, | ||
179 | |||
180 | .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6, | ||
181 | .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5, | ||
182 | .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4, | ||
183 | .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3, | ||
184 | .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2, | ||
185 | .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1, | ||
186 | .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8, | ||
187 | .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7, | ||
188 | .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6, | ||
189 | .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5, | ||
190 | .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4, | ||
191 | .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3, | ||
192 | .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2, | ||
193 | .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1, | ||
194 | .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2, | ||
195 | .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1, | ||
196 | |||
197 | .maps[RTL_IMR_TXFOVW] = IMR_TXFOVW, | ||
198 | .maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT, | ||
199 | .maps[RTL_IMR_BcnInt] = IMR_BCNINT, | ||
200 | .maps[RTL_IMR_RXFOVW] = IMR_RXFOVW, | ||
201 | .maps[RTL_IMR_RDU] = IMR_RDU, | ||
202 | .maps[RTL_IMR_ATIMEND] = IMR_ATIMEND, | ||
203 | .maps[RTL_IMR_BDOK] = IMR_BDOK, | ||
204 | .maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK, | ||
205 | .maps[RTL_IMR_TBDER] = IMR_TBDER, | ||
206 | .maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK, | ||
207 | .maps[RTL_IMR_TBDOK] = IMR_TBDOK, | ||
208 | .maps[RTL_IMR_BKDOK] = IMR_BKDOK, | ||
209 | .maps[RTL_IMR_BEDOK] = IMR_BEDOK, | ||
210 | .maps[RTL_IMR_VIDOK] = IMR_VIDOK, | ||
211 | .maps[RTL_IMR_VODOK] = IMR_VODOK, | ||
212 | .maps[RTL_IMR_ROK] = IMR_ROK, | ||
213 | .maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER), | ||
214 | |||
215 | .maps[RTL_RC_CCK_RATE1M] = DESC92C_RATE1M, | ||
216 | .maps[RTL_RC_CCK_RATE2M] = DESC92C_RATE2M, | ||
217 | .maps[RTL_RC_CCK_RATE5_5M] = DESC92C_RATE5_5M, | ||
218 | .maps[RTL_RC_CCK_RATE11M] = DESC92C_RATE11M, | ||
219 | .maps[RTL_RC_OFDM_RATE6M] = DESC92C_RATE6M, | ||
220 | .maps[RTL_RC_OFDM_RATE9M] = DESC92C_RATE9M, | ||
221 | .maps[RTL_RC_OFDM_RATE12M] = DESC92C_RATE12M, | ||
222 | .maps[RTL_RC_OFDM_RATE18M] = DESC92C_RATE18M, | ||
223 | .maps[RTL_RC_OFDM_RATE24M] = DESC92C_RATE24M, | ||
224 | .maps[RTL_RC_OFDM_RATE36M] = DESC92C_RATE36M, | ||
225 | .maps[RTL_RC_OFDM_RATE48M] = DESC92C_RATE48M, | ||
226 | .maps[RTL_RC_OFDM_RATE54M] = DESC92C_RATE54M, | ||
227 | .maps[RTL_RC_HT_RATEMCS7] = DESC92C_RATEMCS7, | ||
228 | .maps[RTL_RC_HT_RATEMCS15] = DESC92C_RATEMCS15, | ||
229 | }; | ||
230 | |||
231 | #define USB_VENDER_ID_REALTEK 0x0bda | ||
232 | |||
233 | /* 2010-10-19 DID_USB_V3.4 */ | ||
234 | static struct usb_device_id rtl8192c_usb_ids[] = { | ||
235 | |||
236 | /*=== Realtek demoboard ===*/ | ||
237 | /* Default ID */ | ||
238 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8191, rtl92cu_hal_cfg)}, | ||
239 | |||
240 | /****** 8188CU ********/ | ||
241 | /* 8188CE-VAU USB minCard */ | ||
242 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8170, rtl92cu_hal_cfg)}, | ||
243 | /* 8188cu 1*1 dongle */ | ||
244 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8176, rtl92cu_hal_cfg)}, | ||
245 | /* 8188cu 1*1 dongle, (b/g mode only) */ | ||
246 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8177, rtl92cu_hal_cfg)}, | ||
247 | /* 8188cu Slim Solo */ | ||
248 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817a, rtl92cu_hal_cfg)}, | ||
249 | /* 8188cu Slim Combo */ | ||
250 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817b, rtl92cu_hal_cfg)}, | ||
251 | /* 8188RU High-power USB Dongle */ | ||
252 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817d, rtl92cu_hal_cfg)}, | ||
253 | /* 8188CE-VAU USB minCard (b/g mode only) */ | ||
254 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817e, rtl92cu_hal_cfg)}, | ||
255 | /* 8188 Combo for BC4 */ | ||
256 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8754, rtl92cu_hal_cfg)}, | ||
257 | |||
258 | /****** 8192CU ********/ | ||
259 | /* 8191cu 1*2 */ | ||
260 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8177, rtl92cu_hal_cfg)}, | ||
261 | /* 8192cu 2*2 */ | ||
262 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817b, rtl92cu_hal_cfg)}, | ||
263 | /* 8192CE-VAU USB minCard */ | ||
264 | {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817c, rtl92cu_hal_cfg)}, | ||
265 | |||
266 | /*=== Customer ID ===*/ | ||
267 | /****** 8188CU ********/ | ||
268 | {RTL_USB_DEVICE(0x050d, 0x1102, rtl92cu_hal_cfg)}, /*Belkin - Edimax*/ | ||
269 | {RTL_USB_DEVICE(0x06f8, 0xe033, rtl92cu_hal_cfg)}, /*Hercules - Edimax*/ | ||
270 | {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ | ||
271 | {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ | ||
272 | {RTL_USB_DEVICE(0x0Df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ | ||
273 | {RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/ | ||
274 | /* HP - Lite-On ,8188CUS Slim Combo */ | ||
275 | {RTL_USB_DEVICE(0x103c, 0x1629, rtl92cu_hal_cfg)}, | ||
276 | {RTL_USB_DEVICE(0x2001, 0x3308, rtl92cu_hal_cfg)}, /*D-Link - Alpha*/ | ||
277 | {RTL_USB_DEVICE(0x2019, 0xab2a, rtl92cu_hal_cfg)}, /*Planex - Abocom*/ | ||
278 | {RTL_USB_DEVICE(0x2019, 0xed17, rtl92cu_hal_cfg)}, /*PCI - Edimax*/ | ||
279 | {RTL_USB_DEVICE(0x20f4, 0x648b, rtl92cu_hal_cfg)}, /*TRENDnet - Cameo*/ | ||
280 | {RTL_USB_DEVICE(0x7392, 0x7811, rtl92cu_hal_cfg)}, /*Edimax - Edimax*/ | ||
281 | {RTL_USB_DEVICE(0x3358, 0x13d3, rtl92cu_hal_cfg)}, /*Azwave 8188CE-VAU*/ | ||
282 | /* Russian customer -Azwave (8188CE-VAU b/g mode only) */ | ||
283 | {RTL_USB_DEVICE(0x3359, 0x13d3, rtl92cu_hal_cfg)}, | ||
284 | |||
285 | /****** 8192CU ********/ | ||
286 | {RTL_USB_DEVICE(0x0586, 0x341f, rtl92cu_hal_cfg)}, /*Zyxel -Abocom*/ | ||
287 | {RTL_USB_DEVICE(0x07aa, 0x0056, rtl92cu_hal_cfg)}, /*ATKK-Gemtek*/ | ||
288 | {RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Funai -Abocom*/ | ||
289 | {RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Abocom -Abocom*/ | ||
290 | {RTL_USB_DEVICE(0x2001, 0x3307, rtl92cu_hal_cfg)}, /*D-Link-Cameo*/ | ||
291 | {RTL_USB_DEVICE(0x2001, 0x3309, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/ | ||
292 | {RTL_USB_DEVICE(0x2001, 0x330a, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/ | ||
293 | {RTL_USB_DEVICE(0x2019, 0xab2b, rtl92cu_hal_cfg)}, /*Planex -Abocom*/ | ||
294 | {RTL_USB_DEVICE(0x7392, 0x7822, rtl92cu_hal_cfg)}, /*Edimax -Edimax*/ | ||
295 | {} | ||
296 | }; | ||
297 | |||
298 | MODULE_DEVICE_TABLE(usb, rtl8192c_usb_ids); | ||
299 | |||
300 | static struct usb_driver rtl8192cu_driver = { | ||
301 | .name = "rtl8192cu", | ||
302 | .probe = rtl_usb_probe, | ||
303 | .disconnect = rtl_usb_disconnect, | ||
304 | .id_table = rtl8192c_usb_ids, | ||
305 | |||
306 | #ifdef CONFIG_PM | ||
307 | /* .suspend = rtl_usb_suspend, */ | ||
308 | /* .resume = rtl_usb_resume, */ | ||
309 | /* .reset_resume = rtl8192c_resume, */ | ||
310 | #endif /* CONFIG_PM */ | ||
311 | #ifdef CONFIG_AUTOSUSPEND | ||
312 | .supports_autosuspend = 1, | ||
313 | #endif | ||
314 | }; | ||
315 | |||
316 | static int __init rtl8192cu_init(void) | ||
317 | { | ||
318 | return usb_register(&rtl8192cu_driver); | ||
319 | } | ||
320 | |||
321 | static void __exit rtl8192cu_exit(void) | ||
322 | { | ||
323 | usb_deregister(&rtl8192cu_driver); | ||
324 | } | ||
325 | |||
326 | module_init(rtl8192cu_init); | ||
327 | module_exit(rtl8192cu_exit); | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h new file mode 100644 index 000000000000..3b2c66339554 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h | |||
@@ -0,0 +1,35 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #ifndef __RTL92CU_SW_H__ | ||
31 | #define __RTL92CU_SW_H__ | ||
32 | |||
33 | #define EFUSE_MAX_SECTION 16 | ||
34 | |||
35 | #endif | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/table.c b/drivers/net/wireless/rtlwifi/rtl8192cu/table.c new file mode 100644 index 000000000000..d57ef5e88a9e --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/table.c | |||
@@ -0,0 +1,1888 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 Realtek Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #include "table.h" | ||
31 | |||
32 | u32 RTL8192CUPHY_REG_2TARRAY[RTL8192CUPHY_REG_2TARRAY_LENGTH] = { | ||
33 | 0x024, 0x0011800f, | ||
34 | 0x028, 0x00ffdb83, | ||
35 | 0x800, 0x80040002, | ||
36 | 0x804, 0x00000003, | ||
37 | 0x808, 0x0000fc00, | ||
38 | 0x80c, 0x0000000a, | ||
39 | 0x810, 0x10005388, | ||
40 | 0x814, 0x020c3d10, | ||
41 | 0x818, 0x02200385, | ||
42 | 0x81c, 0x00000000, | ||
43 | 0x820, 0x01000100, | ||
44 | 0x824, 0x00390004, | ||
45 | 0x828, 0x01000100, | ||
46 | 0x82c, 0x00390004, | ||
47 | 0x830, 0x27272727, | ||
48 | 0x834, 0x27272727, | ||
49 | 0x838, 0x27272727, | ||
50 | 0x83c, 0x27272727, | ||
51 | 0x840, 0x00010000, | ||
52 | 0x844, 0x00010000, | ||
53 | 0x848, 0x27272727, | ||
54 | 0x84c, 0x27272727, | ||
55 | 0x850, 0x00000000, | ||
56 | 0x854, 0x00000000, | ||
57 | 0x858, 0x569a569a, | ||
58 | 0x85c, 0x0c1b25a4, | ||
59 | 0x860, 0x66e60230, | ||
60 | 0x864, 0x061f0130, | ||
61 | 0x868, 0x27272727, | ||
62 | 0x86c, 0x2b2b2b27, | ||
63 | 0x870, 0x07000700, | ||
64 | 0x874, 0x22184000, | ||
65 | 0x878, 0x08080808, | ||
66 | 0x87c, 0x00000000, | ||
67 | 0x880, 0xc0083070, | ||
68 | 0x884, 0x000004d5, | ||
69 | 0x888, 0x00000000, | ||
70 | 0x88c, 0xcc0000c0, | ||
71 | 0x890, 0x00000800, | ||
72 | 0x894, 0xfffffffe, | ||
73 | 0x898, 0x40302010, | ||
74 | 0x89c, 0x00706050, | ||
75 | 0x900, 0x00000000, | ||
76 | 0x904, 0x00000023, | ||
77 | 0x908, 0x00000000, | ||
78 | 0x90c, 0x81121313, | ||
79 | 0xa00, 0x00d047c8, | ||
80 | 0xa04, 0x80ff000c, | ||
81 | 0xa08, 0x8c838300, | ||
82 | 0xa0c, 0x2e68120f, | ||
83 | 0xa10, 0x9500bb78, | ||
84 | 0xa14, 0x11144028, | ||
85 | 0xa18, 0x00881117, | ||
86 | 0xa1c, 0x89140f00, | ||
87 | 0xa20, 0x1a1b0000, | ||
88 | 0xa24, 0x090e1317, | ||
89 | 0xa28, 0x00000204, | ||
90 | 0xa2c, 0x00d30000, | ||
91 | 0xa70, 0x101fbf00, | ||
92 | 0xa74, 0x00000007, | ||
93 | 0xc00, 0x48071d40, | ||
94 | 0xc04, 0x03a05633, | ||
95 | 0xc08, 0x000000e4, | ||
96 | 0xc0c, 0x6c6c6c6c, | ||
97 | 0xc10, 0x08800000, | ||
98 | 0xc14, 0x40000100, | ||
99 | 0xc18, 0x08800000, | ||
100 | 0xc1c, 0x40000100, | ||
101 | 0xc20, 0x00000000, | ||
102 | 0xc24, 0x00000000, | ||
103 | 0xc28, 0x00000000, | ||
104 | 0xc2c, 0x00000000, | ||
105 | 0xc30, 0x69e9ac44, | ||
106 | 0xc34, 0x469652cf, | ||
107 | 0xc38, 0x49795994, | ||
108 | 0xc3c, 0x0a97971c, | ||
109 | 0xc40, 0x1f7c403f, | ||
110 | 0xc44, 0x000100b7, | ||
111 | 0xc48, 0xec020107, | ||
112 | 0xc4c, 0x007f037f, | ||
113 | 0xc50, 0x6954341e, | ||
114 | 0xc54, 0x43bc0094, | ||
115 | 0xc58, 0x6954341e, | ||
116 | 0xc5c, 0x433c0094, | ||
117 | 0xc60, 0x00000000, | ||
118 | 0xc64, 0x5116848b, | ||
119 | 0xc68, 0x47c00bff, | ||
120 | 0xc6c, 0x00000036, | ||
121 | 0xc70, 0x2c7f000d, | ||
122 | 0xc74, 0x0186115b, | ||
123 | 0xc78, 0x0000001f, | ||
124 | 0xc7c, 0x00b99612, | ||
125 | 0xc80, 0x40000100, | ||
126 | 0xc84, 0x20f60000, | ||
127 | 0xc88, 0x40000100, | ||
128 | 0xc8c, 0x20200000, | ||
129 | 0xc90, 0x00121820, | ||
130 | 0xc94, 0x00000000, | ||
131 | 0xc98, 0x00121820, | ||
132 | 0xc9c, 0x00007f7f, | ||
133 | 0xca0, 0x00000000, | ||
134 | 0xca4, 0x00000080, | ||
135 | 0xca8, 0x00000000, | ||
136 | 0xcac, 0x00000000, | ||
137 | 0xcb0, 0x00000000, | ||
138 | 0xcb4, 0x00000000, | ||
139 | 0xcb8, 0x00000000, | ||
140 | 0xcbc, 0x28000000, | ||
141 | 0xcc0, 0x00000000, | ||
142 | 0xcc4, 0x00000000, | ||
143 | 0xcc8, 0x00000000, | ||
144 | 0xccc, 0x00000000, | ||
145 | 0xcd0, 0x00000000, | ||
146 | 0xcd4, 0x00000000, | ||
147 | 0xcd8, 0x64b22427, | ||
148 | 0xcdc, 0x00766932, | ||
149 | 0xce0, 0x00222222, | ||
150 | 0xce4, 0x00000000, | ||
151 | 0xce8, 0x37644302, | ||
152 | 0xcec, 0x2f97d40c, | ||
153 | 0xd00, 0x00080740, | ||
154 | 0xd04, 0x00020403, | ||
155 | 0xd08, 0x0000907f, | ||
156 | 0xd0c, 0x20010201, | ||
157 | 0xd10, 0xa0633333, | ||
158 | 0xd14, 0x3333bc43, | ||
159 | 0xd18, 0x7a8f5b6b, | ||
160 | 0xd2c, 0xcc979975, | ||
161 | 0xd30, 0x00000000, | ||
162 | 0xd34, 0x80608000, | ||
163 | 0xd38, 0x00000000, | ||
164 | 0xd3c, 0x00027293, | ||
165 | 0xd40, 0x00000000, | ||
166 | 0xd44, 0x00000000, | ||
167 | 0xd48, 0x00000000, | ||
168 | 0xd4c, 0x00000000, | ||
169 | 0xd50, 0x6437140a, | ||
170 | 0xd54, 0x00000000, | ||
171 | 0xd58, 0x00000000, | ||
172 | 0xd5c, 0x30032064, | ||
173 | 0xd60, 0x4653de68, | ||
174 | 0xd64, 0x04518a3c, | ||
175 | 0xd68, 0x00002101, | ||
176 | 0xd6c, 0x2a201c16, | ||
177 | 0xd70, 0x1812362e, | ||
178 | 0xd74, 0x322c2220, | ||
179 | 0xd78, 0x000e3c24, | ||
180 | 0xe00, 0x2a2a2a2a, | ||
181 | 0xe04, 0x2a2a2a2a, | ||
182 | 0xe08, 0x03902a2a, | ||
183 | 0xe10, 0x2a2a2a2a, | ||
184 | 0xe14, 0x2a2a2a2a, | ||
185 | 0xe18, 0x2a2a2a2a, | ||
186 | 0xe1c, 0x2a2a2a2a, | ||
187 | 0xe28, 0x00000000, | ||
188 | 0xe30, 0x1000dc1f, | ||
189 | 0xe34, 0x10008c1f, | ||
190 | 0xe38, 0x02140102, | ||
191 | 0xe3c, 0x681604c2, | ||
192 | 0xe40, 0x01007c00, | ||
193 | 0xe44, 0x01004800, | ||
194 | 0xe48, 0xfb000000, | ||
195 | 0xe4c, 0x000028d1, | ||
196 | 0xe50, 0x1000dc1f, | ||
197 | 0xe54, 0x10008c1f, | ||
198 | 0xe58, 0x02140102, | ||
199 | 0xe5c, 0x28160d05, | ||
200 | 0xe60, 0x00000010, | ||
201 | 0xe68, 0x001b25a4, | ||
202 | 0xe6c, 0x63db25a4, | ||
203 | 0xe70, 0x63db25a4, | ||
204 | 0xe74, 0x0c1b25a4, | ||
205 | 0xe78, 0x0c1b25a4, | ||
206 | 0xe7c, 0x0c1b25a4, | ||
207 | 0xe80, 0x0c1b25a4, | ||
208 | 0xe84, 0x63db25a4, | ||
209 | 0xe88, 0x0c1b25a4, | ||
210 | 0xe8c, 0x63db25a4, | ||
211 | 0xed0, 0x63db25a4, | ||
212 | 0xed4, 0x63db25a4, | ||
213 | 0xed8, 0x63db25a4, | ||
214 | 0xedc, 0x001b25a4, | ||
215 | 0xee0, 0x001b25a4, | ||
216 | 0xeec, 0x6fdb25a4, | ||
217 | 0xf14, 0x00000003, | ||
218 | 0xf4c, 0x00000000, | ||
219 | 0xf00, 0x00000300, | ||
220 | }; | ||
221 | |||
222 | u32 RTL8192CUPHY_REG_1TARRAY[RTL8192CUPHY_REG_1TARRAY_LENGTH] = { | ||
223 | 0x024, 0x0011800f, | ||
224 | 0x028, 0x00ffdb83, | ||
225 | 0x800, 0x80040000, | ||
226 | 0x804, 0x00000001, | ||
227 | 0x808, 0x0000fc00, | ||
228 | 0x80c, 0x0000000a, | ||
229 | 0x810, 0x10005388, | ||
230 | 0x814, 0x020c3d10, | ||
231 | 0x818, 0x02200385, | ||
232 | 0x81c, 0x00000000, | ||
233 | 0x820, 0x01000100, | ||
234 | 0x824, 0x00390004, | ||
235 | 0x828, 0x00000000, | ||
236 | 0x82c, 0x00000000, | ||
237 | 0x830, 0x00000000, | ||
238 | 0x834, 0x00000000, | ||
239 | 0x838, 0x00000000, | ||
240 | 0x83c, 0x00000000, | ||
241 | 0x840, 0x00010000, | ||
242 | 0x844, 0x00000000, | ||
243 | 0x848, 0x00000000, | ||
244 | 0x84c, 0x00000000, | ||
245 | 0x850, 0x00000000, | ||
246 | 0x854, 0x00000000, | ||
247 | 0x858, 0x569a569a, | ||
248 | 0x85c, 0x001b25a4, | ||
249 | 0x860, 0x66e60230, | ||
250 | 0x864, 0x061f0130, | ||
251 | 0x868, 0x00000000, | ||
252 | 0x86c, 0x32323200, | ||
253 | 0x870, 0x07000700, | ||
254 | 0x874, 0x22004000, | ||
255 | 0x878, 0x00000808, | ||
256 | 0x87c, 0x00000000, | ||
257 | 0x880, 0xc0083070, | ||
258 | 0x884, 0x000004d5, | ||
259 | 0x888, 0x00000000, | ||
260 | 0x88c, 0xccc000c0, | ||
261 | 0x890, 0x00000800, | ||
262 | 0x894, 0xfffffffe, | ||
263 | 0x898, 0x40302010, | ||
264 | 0x89c, 0x00706050, | ||
265 | 0x900, 0x00000000, | ||
266 | 0x904, 0x00000023, | ||
267 | 0x908, 0x00000000, | ||
268 | 0x90c, 0x81121111, | ||
269 | 0xa00, 0x00d047c8, | ||
270 | 0xa04, 0x80ff000c, | ||
271 | 0xa08, 0x8c838300, | ||
272 | 0xa0c, 0x2e68120f, | ||
273 | 0xa10, 0x9500bb78, | ||
274 | 0xa14, 0x11144028, | ||
275 | 0xa18, 0x00881117, | ||
276 | 0xa1c, 0x89140f00, | ||
277 | 0xa20, 0x1a1b0000, | ||
278 | 0xa24, 0x090e1317, | ||
279 | 0xa28, 0x00000204, | ||
280 | 0xa2c, 0x00d30000, | ||
281 | 0xa70, 0x101fbf00, | ||
282 | 0xa74, 0x00000007, | ||
283 | 0xc00, 0x48071d40, | ||
284 | 0xc04, 0x03a05611, | ||
285 | 0xc08, 0x000000e4, | ||
286 | 0xc0c, 0x6c6c6c6c, | ||
287 | 0xc10, 0x08800000, | ||
288 | 0xc14, 0x40000100, | ||
289 | 0xc18, 0x08800000, | ||
290 | 0xc1c, 0x40000100, | ||
291 | 0xc20, 0x00000000, | ||
292 | 0xc24, 0x00000000, | ||
293 | 0xc28, 0x00000000, | ||
294 | 0xc2c, 0x00000000, | ||
295 | 0xc30, 0x69e9ac44, | ||
296 | 0xc34, 0x469652cf, | ||
297 | 0xc38, 0x49795994, | ||
298 | 0xc3c, 0x0a97971c, | ||
299 | 0xc40, 0x1f7c403f, | ||
300 | 0xc44, 0x000100b7, | ||
301 | 0xc48, 0xec020107, | ||
302 | 0xc4c, 0x007f037f, | ||
303 | 0xc50, 0x6954341e, | ||
304 | 0xc54, 0x43bc0094, | ||
305 | 0xc58, 0x6954341e, | ||
306 | 0xc5c, 0x433c0094, | ||
307 | 0xc60, 0x00000000, | ||
308 | 0xc64, 0x5116848b, | ||
309 | 0xc68, 0x47c00bff, | ||
310 | 0xc6c, 0x00000036, | ||
311 | 0xc70, 0x2c7f000d, | ||
312 | 0xc74, 0x018610db, | ||
313 | 0xc78, 0x0000001f, | ||
314 | 0xc7c, 0x00b91612, | ||
315 | 0xc80, 0x40000100, | ||
316 | 0xc84, 0x20f60000, | ||
317 | 0xc88, 0x40000100, | ||
318 | 0xc8c, 0x20200000, | ||
319 | 0xc90, 0x00121820, | ||
320 | 0xc94, 0x00000000, | ||
321 | 0xc98, 0x00121820, | ||
322 | 0xc9c, 0x00007f7f, | ||
323 | 0xca0, 0x00000000, | ||
324 | 0xca4, 0x00000080, | ||
325 | 0xca8, 0x00000000, | ||
326 | 0xcac, 0x00000000, | ||
327 | 0xcb0, 0x00000000, | ||
328 | 0xcb4, 0x00000000, | ||
329 | 0xcb8, 0x00000000, | ||
330 | 0xcbc, 0x28000000, | ||
331 | 0xcc0, 0x00000000, | ||
332 | 0xcc4, 0x00000000, | ||
333 | 0xcc8, 0x00000000, | ||
334 | 0xccc, 0x00000000, | ||
335 | 0xcd0, 0x00000000, | ||
336 | 0xcd4, 0x00000000, | ||
337 | 0xcd8, 0x64b22427, | ||
338 | 0xcdc, 0x00766932, | ||
339 | 0xce0, 0x00222222, | ||
340 | 0xce4, 0x00000000, | ||
341 | 0xce8, 0x37644302, | ||
342 | 0xcec, 0x2f97d40c, | ||
343 | 0xd00, 0x00080740, | ||
344 | 0xd04, 0x00020401, | ||
345 | 0xd08, 0x0000907f, | ||
346 | 0xd0c, 0x20010201, | ||
347 | 0xd10, 0xa0633333, | ||
348 | 0xd14, 0x3333bc43, | ||
349 | 0xd18, 0x7a8f5b6b, | ||
350 | 0xd2c, 0xcc979975, | ||
351 | 0xd30, 0x00000000, | ||
352 | 0xd34, 0x80608000, | ||
353 | 0xd38, 0x00000000, | ||
354 | 0xd3c, 0x00027293, | ||
355 | 0xd40, 0x00000000, | ||
356 | 0xd44, 0x00000000, | ||
357 | 0xd48, 0x00000000, | ||
358 | 0xd4c, 0x00000000, | ||
359 | 0xd50, 0x6437140a, | ||
360 | 0xd54, 0x00000000, | ||
361 | 0xd58, 0x00000000, | ||
362 | 0xd5c, 0x30032064, | ||
363 | 0xd60, 0x4653de68, | ||
364 | 0xd64, 0x04518a3c, | ||
365 | 0xd68, 0x00002101, | ||
366 | 0xd6c, 0x2a201c16, | ||
367 | 0xd70, 0x1812362e, | ||
368 | 0xd74, 0x322c2220, | ||
369 | 0xd78, 0x000e3c24, | ||
370 | 0xe00, 0x2a2a2a2a, | ||
371 | 0xe04, 0x2a2a2a2a, | ||
372 | 0xe08, 0x03902a2a, | ||
373 | 0xe10, 0x2a2a2a2a, | ||
374 | 0xe14, 0x2a2a2a2a, | ||
375 | 0xe18, 0x2a2a2a2a, | ||
376 | 0xe1c, 0x2a2a2a2a, | ||
377 | 0xe28, 0x00000000, | ||
378 | 0xe30, 0x1000dc1f, | ||
379 | 0xe34, 0x10008c1f, | ||
380 | 0xe38, 0x02140102, | ||
381 | 0xe3c, 0x681604c2, | ||
382 | 0xe40, 0x01007c00, | ||
383 | 0xe44, 0x01004800, | ||
384 | 0xe48, 0xfb000000, | ||
385 | 0xe4c, 0x000028d1, | ||
386 | 0xe50, 0x1000dc1f, | ||
387 | 0xe54, 0x10008c1f, | ||
388 | 0xe58, 0x02140102, | ||
389 | 0xe5c, 0x28160d05, | ||
390 | 0xe60, 0x00000008, | ||
391 | 0xe68, 0x001b25a4, | ||
392 | 0xe6c, 0x631b25a0, | ||
393 | 0xe70, 0x631b25a0, | ||
394 | 0xe74, 0x081b25a0, | ||
395 | 0xe78, 0x081b25a0, | ||
396 | 0xe7c, 0x081b25a0, | ||
397 | 0xe80, 0x081b25a0, | ||
398 | 0xe84, 0x631b25a0, | ||
399 | 0xe88, 0x081b25a0, | ||
400 | 0xe8c, 0x631b25a0, | ||
401 | 0xed0, 0x631b25a0, | ||
402 | 0xed4, 0x631b25a0, | ||
403 | 0xed8, 0x631b25a0, | ||
404 | 0xedc, 0x001b25a0, | ||
405 | 0xee0, 0x001b25a0, | ||
406 | 0xeec, 0x6b1b25a0, | ||
407 | 0xf14, 0x00000003, | ||
408 | 0xf4c, 0x00000000, | ||
409 | 0xf00, 0x00000300, | ||
410 | }; | ||
411 | |||
412 | u32 RTL8192CUPHY_REG_ARRAY_PG[RTL8192CUPHY_REG_ARRAY_PGLENGTH] = { | ||
413 | 0xe00, 0xffffffff, 0x07090c0c, | ||
414 | 0xe04, 0xffffffff, 0x01020405, | ||
415 | 0xe08, 0x0000ff00, 0x00000000, | ||
416 | 0x86c, 0xffffff00, 0x00000000, | ||
417 | 0xe10, 0xffffffff, 0x0b0c0c0e, | ||
418 | 0xe14, 0xffffffff, 0x01030506, | ||
419 | 0xe18, 0xffffffff, 0x0b0c0d0e, | ||
420 | 0xe1c, 0xffffffff, 0x01030509, | ||
421 | 0x830, 0xffffffff, 0x07090c0c, | ||
422 | 0x834, 0xffffffff, 0x01020405, | ||
423 | 0x838, 0xffffff00, 0x00000000, | ||
424 | 0x86c, 0x000000ff, 0x00000000, | ||
425 | 0x83c, 0xffffffff, 0x0b0c0d0e, | ||
426 | 0x848, 0xffffffff, 0x01030509, | ||
427 | 0x84c, 0xffffffff, 0x0b0c0d0e, | ||
428 | 0x868, 0xffffffff, 0x01030509, | ||
429 | 0xe00, 0xffffffff, 0x00000000, | ||
430 | 0xe04, 0xffffffff, 0x00000000, | ||
431 | 0xe08, 0x0000ff00, 0x00000000, | ||
432 | 0x86c, 0xffffff00, 0x00000000, | ||
433 | 0xe10, 0xffffffff, 0x00000000, | ||
434 | 0xe14, 0xffffffff, 0x00000000, | ||
435 | 0xe18, 0xffffffff, 0x00000000, | ||
436 | 0xe1c, 0xffffffff, 0x00000000, | ||
437 | 0x830, 0xffffffff, 0x00000000, | ||
438 | 0x834, 0xffffffff, 0x00000000, | ||
439 | 0x838, 0xffffff00, 0x00000000, | ||
440 | 0x86c, 0x000000ff, 0x00000000, | ||
441 | 0x83c, 0xffffffff, 0x00000000, | ||
442 | 0x848, 0xffffffff, 0x00000000, | ||
443 | 0x84c, 0xffffffff, 0x00000000, | ||
444 | 0x868, 0xffffffff, 0x00000000, | ||
445 | 0xe00, 0xffffffff, 0x04040404, | ||
446 | 0xe04, 0xffffffff, 0x00020204, | ||
447 | 0xe08, 0x0000ff00, 0x00000000, | ||
448 | 0x86c, 0xffffff00, 0x00000000, | ||
449 | 0xe10, 0xffffffff, 0x06060606, | ||
450 | 0xe14, 0xffffffff, 0x00020406, | ||
451 | 0xe18, 0xffffffff, 0x00000000, | ||
452 | 0xe1c, 0xffffffff, 0x00000000, | ||
453 | 0x830, 0xffffffff, 0x04040404, | ||
454 | 0x834, 0xffffffff, 0x00020204, | ||
455 | 0x838, 0xffffff00, 0x00000000, | ||
456 | 0x86c, 0x000000ff, 0x00000000, | ||
457 | 0x83c, 0xffffffff, 0x06060606, | ||
458 | 0x848, 0xffffffff, 0x00020406, | ||
459 | 0x84c, 0xffffffff, 0x00000000, | ||
460 | 0x868, 0xffffffff, 0x00000000, | ||
461 | 0xe00, 0xffffffff, 0x00000000, | ||
462 | 0xe04, 0xffffffff, 0x00000000, | ||
463 | 0xe08, 0x0000ff00, 0x00000000, | ||
464 | 0x86c, 0xffffff00, 0x00000000, | ||
465 | 0xe10, 0xffffffff, 0x00000000, | ||
466 | 0xe14, 0xffffffff, 0x00000000, | ||
467 | 0xe18, 0xffffffff, 0x00000000, | ||
468 | 0xe1c, 0xffffffff, 0x00000000, | ||
469 | 0x830, 0xffffffff, 0x00000000, | ||
470 | 0x834, 0xffffffff, 0x00000000, | ||
471 | 0x838, 0xffffff00, 0x00000000, | ||
472 | 0x86c, 0x000000ff, 0x00000000, | ||
473 | 0x83c, 0xffffffff, 0x00000000, | ||
474 | 0x848, 0xffffffff, 0x00000000, | ||
475 | 0x84c, 0xffffffff, 0x00000000, | ||
476 | 0x868, 0xffffffff, 0x00000000, | ||
477 | 0xe00, 0xffffffff, 0x00000000, | ||
478 | 0xe04, 0xffffffff, 0x00000000, | ||
479 | 0xe08, 0x0000ff00, 0x00000000, | ||
480 | 0x86c, 0xffffff00, 0x00000000, | ||
481 | 0xe10, 0xffffffff, 0x00000000, | ||
482 | 0xe14, 0xffffffff, 0x00000000, | ||
483 | 0xe18, 0xffffffff, 0x00000000, | ||
484 | 0xe1c, 0xffffffff, 0x00000000, | ||
485 | 0x830, 0xffffffff, 0x00000000, | ||
486 | 0x834, 0xffffffff, 0x00000000, | ||
487 | 0x838, 0xffffff00, 0x00000000, | ||
488 | 0x86c, 0x000000ff, 0x00000000, | ||
489 | 0x83c, 0xffffffff, 0x00000000, | ||
490 | 0x848, 0xffffffff, 0x00000000, | ||
491 | 0x84c, 0xffffffff, 0x00000000, | ||
492 | 0x868, 0xffffffff, 0x00000000, | ||
493 | 0xe00, 0xffffffff, 0x04040404, | ||
494 | 0xe04, 0xffffffff, 0x00020204, | ||
495 | 0xe08, 0x0000ff00, 0x00000000, | ||
496 | 0x86c, 0xffffff00, 0x00000000, | ||
497 | 0xe10, 0xffffffff, 0x00000000, | ||
498 | 0xe14, 0xffffffff, 0x00000000, | ||
499 | 0xe18, 0xffffffff, 0x00000000, | ||
500 | 0xe1c, 0xffffffff, 0x00000000, | ||
501 | 0x830, 0xffffffff, 0x04040404, | ||
502 | 0x834, 0xffffffff, 0x00020204, | ||
503 | 0x838, 0xffffff00, 0x00000000, | ||
504 | 0x86c, 0x000000ff, 0x00000000, | ||
505 | 0x83c, 0xffffffff, 0x00000000, | ||
506 | 0x848, 0xffffffff, 0x00000000, | ||
507 | 0x84c, 0xffffffff, 0x00000000, | ||
508 | 0x868, 0xffffffff, 0x00000000, | ||
509 | 0xe00, 0xffffffff, 0x00000000, | ||
510 | 0xe04, 0xffffffff, 0x00000000, | ||
511 | 0xe08, 0x0000ff00, 0x00000000, | ||
512 | 0x86c, 0xffffff00, 0x00000000, | ||
513 | 0xe10, 0xffffffff, 0x00000000, | ||
514 | 0xe14, 0xffffffff, 0x00000000, | ||
515 | 0xe18, 0xffffffff, 0x00000000, | ||
516 | 0xe1c, 0xffffffff, 0x00000000, | ||
517 | 0x830, 0xffffffff, 0x00000000, | ||
518 | 0x834, 0xffffffff, 0x00000000, | ||
519 | 0x838, 0xffffff00, 0x00000000, | ||
520 | 0x86c, 0x000000ff, 0x00000000, | ||
521 | 0x83c, 0xffffffff, 0x00000000, | ||
522 | 0x848, 0xffffffff, 0x00000000, | ||
523 | 0x84c, 0xffffffff, 0x00000000, | ||
524 | 0x868, 0xffffffff, 0x00000000, | ||
525 | }; | ||
526 | |||
527 | u32 RTL8192CURADIOA_2TARRAY[RTL8192CURADIOA_2TARRAYLENGTH] = { | ||
528 | 0x000, 0x00030159, | ||
529 | 0x001, 0x00031284, | ||
530 | 0x002, 0x00098000, | ||
531 | 0x003, 0x00018c63, | ||
532 | 0x004, 0x000210e7, | ||
533 | 0x009, 0x0002044f, | ||
534 | 0x00a, 0x0001adb1, | ||
535 | 0x00b, 0x00054867, | ||
536 | 0x00c, 0x0008992e, | ||
537 | 0x00d, 0x0000e52c, | ||
538 | 0x00e, 0x00039ce7, | ||
539 | 0x00f, 0x00000451, | ||
540 | 0x019, 0x00000000, | ||
541 | 0x01a, 0x00010255, | ||
542 | 0x01b, 0x00060a00, | ||
543 | 0x01c, 0x000fc378, | ||
544 | 0x01d, 0x000a1250, | ||
545 | 0x01e, 0x0004445f, | ||
546 | 0x01f, 0x00080001, | ||
547 | 0x020, 0x0000b614, | ||
548 | 0x021, 0x0006c000, | ||
549 | 0x022, 0x00000000, | ||
550 | 0x023, 0x00001558, | ||
551 | 0x024, 0x00000060, | ||
552 | 0x025, 0x00000483, | ||
553 | 0x026, 0x0004f000, | ||
554 | 0x027, 0x000ec7d9, | ||
555 | 0x028, 0x000577c0, | ||
556 | 0x029, 0x00004783, | ||
557 | 0x02a, 0x00000001, | ||
558 | 0x02b, 0x00021334, | ||
559 | 0x02a, 0x00000000, | ||
560 | 0x02b, 0x00000054, | ||
561 | 0x02a, 0x00000001, | ||
562 | 0x02b, 0x00000808, | ||
563 | 0x02b, 0x00053333, | ||
564 | 0x02c, 0x0000000c, | ||
565 | 0x02a, 0x00000002, | ||
566 | 0x02b, 0x00000808, | ||
567 | 0x02b, 0x0005b333, | ||
568 | 0x02c, 0x0000000d, | ||
569 | 0x02a, 0x00000003, | ||
570 | 0x02b, 0x00000808, | ||
571 | 0x02b, 0x00063333, | ||
572 | 0x02c, 0x0000000d, | ||
573 | 0x02a, 0x00000004, | ||
574 | 0x02b, 0x00000808, | ||
575 | 0x02b, 0x0006b333, | ||
576 | 0x02c, 0x0000000d, | ||
577 | 0x02a, 0x00000005, | ||
578 | 0x02b, 0x00000808, | ||
579 | 0x02b, 0x00073333, | ||
580 | 0x02c, 0x0000000d, | ||
581 | 0x02a, 0x00000006, | ||
582 | 0x02b, 0x00000709, | ||
583 | 0x02b, 0x0005b333, | ||
584 | 0x02c, 0x0000000d, | ||
585 | 0x02a, 0x00000007, | ||
586 | 0x02b, 0x00000709, | ||
587 | 0x02b, 0x00063333, | ||
588 | 0x02c, 0x0000000d, | ||
589 | 0x02a, 0x00000008, | ||
590 | 0x02b, 0x0000060a, | ||
591 | 0x02b, 0x0004b333, | ||
592 | 0x02c, 0x0000000d, | ||
593 | 0x02a, 0x00000009, | ||
594 | 0x02b, 0x0000060a, | ||
595 | 0x02b, 0x00053333, | ||
596 | 0x02c, 0x0000000d, | ||
597 | 0x02a, 0x0000000a, | ||
598 | 0x02b, 0x0000060a, | ||
599 | 0x02b, 0x0005b333, | ||
600 | 0x02c, 0x0000000d, | ||
601 | 0x02a, 0x0000000b, | ||
602 | 0x02b, 0x0000060a, | ||
603 | 0x02b, 0x00063333, | ||
604 | 0x02c, 0x0000000d, | ||
605 | 0x02a, 0x0000000c, | ||
606 | 0x02b, 0x0000060a, | ||
607 | 0x02b, 0x0006b333, | ||
608 | 0x02c, 0x0000000d, | ||
609 | 0x02a, 0x0000000d, | ||
610 | 0x02b, 0x0000060a, | ||
611 | 0x02b, 0x00073333, | ||
612 | 0x02c, 0x0000000d, | ||
613 | 0x02a, 0x0000000e, | ||
614 | 0x02b, 0x0000050b, | ||
615 | 0x02b, 0x00066666, | ||
616 | 0x02c, 0x0000001a, | ||
617 | 0x02a, 0x000e0000, | ||
618 | 0x010, 0x0004000f, | ||
619 | 0x011, 0x000e31fc, | ||
620 | 0x010, 0x0006000f, | ||
621 | 0x011, 0x000ff9f8, | ||
622 | 0x010, 0x0002000f, | ||
623 | 0x011, 0x000203f9, | ||
624 | 0x010, 0x0003000f, | ||
625 | 0x011, 0x000ff500, | ||
626 | 0x010, 0x00000000, | ||
627 | 0x011, 0x00000000, | ||
628 | 0x010, 0x0008000f, | ||
629 | 0x011, 0x0003f100, | ||
630 | 0x010, 0x0009000f, | ||
631 | 0x011, 0x00023100, | ||
632 | 0x012, 0x00032000, | ||
633 | 0x012, 0x00071000, | ||
634 | 0x012, 0x000b0000, | ||
635 | 0x012, 0x000fc000, | ||
636 | 0x013, 0x000287af, | ||
637 | 0x013, 0x000244b7, | ||
638 | 0x013, 0x000204ab, | ||
639 | 0x013, 0x0001c49f, | ||
640 | 0x013, 0x00018493, | ||
641 | 0x013, 0x00014297, | ||
642 | 0x013, 0x00010295, | ||
643 | 0x013, 0x0000c298, | ||
644 | 0x013, 0x0000819c, | ||
645 | 0x013, 0x000040a8, | ||
646 | 0x013, 0x0000001c, | ||
647 | 0x014, 0x0001944c, | ||
648 | 0x014, 0x00059444, | ||
649 | 0x014, 0x0009944c, | ||
650 | 0x014, 0x000d9444, | ||
651 | 0x015, 0x0000f424, | ||
652 | 0x015, 0x0004f424, | ||
653 | 0x015, 0x0008f424, | ||
654 | 0x015, 0x000cf424, | ||
655 | 0x016, 0x000e0330, | ||
656 | 0x016, 0x000a0330, | ||
657 | 0x016, 0x00060330, | ||
658 | 0x016, 0x00020330, | ||
659 | 0x000, 0x00010159, | ||
660 | 0x018, 0x0000f401, | ||
661 | 0x0fe, 0x00000000, | ||
662 | 0x0fe, 0x00000000, | ||
663 | 0x01f, 0x00080003, | ||
664 | 0x0fe, 0x00000000, | ||
665 | 0x0fe, 0x00000000, | ||
666 | 0x01e, 0x00044457, | ||
667 | 0x01f, 0x00080000, | ||
668 | 0x000, 0x00030159, | ||
669 | }; | ||
670 | |||
671 | u32 RTL8192CU_RADIOB_2TARRAY[RTL8192CURADIOB_2TARRAYLENGTH] = { | ||
672 | 0x000, 0x00030159, | ||
673 | 0x001, 0x00031284, | ||
674 | 0x002, 0x00098000, | ||
675 | 0x003, 0x00018c63, | ||
676 | 0x004, 0x000210e7, | ||
677 | 0x009, 0x0002044f, | ||
678 | 0x00a, 0x0001adb1, | ||
679 | 0x00b, 0x00054867, | ||
680 | 0x00c, 0x0008992e, | ||
681 | 0x00d, 0x0000e52c, | ||
682 | 0x00e, 0x00039ce7, | ||
683 | 0x00f, 0x00000451, | ||
684 | 0x012, 0x00032000, | ||
685 | 0x012, 0x00071000, | ||
686 | 0x012, 0x000b0000, | ||
687 | 0x012, 0x000fc000, | ||
688 | 0x013, 0x000287af, | ||
689 | 0x013, 0x000244b7, | ||
690 | 0x013, 0x000204ab, | ||
691 | 0x013, 0x0001c49f, | ||
692 | 0x013, 0x00018493, | ||
693 | 0x013, 0x00014297, | ||
694 | 0x013, 0x00010295, | ||
695 | 0x013, 0x0000c298, | ||
696 | 0x013, 0x0000819c, | ||
697 | 0x013, 0x000040a8, | ||
698 | 0x013, 0x0000001c, | ||
699 | 0x014, 0x0001944c, | ||
700 | 0x014, 0x00059444, | ||
701 | 0x014, 0x0009944c, | ||
702 | 0x014, 0x000d9444, | ||
703 | 0x015, 0x0000f424, | ||
704 | 0x015, 0x0004f424, | ||
705 | 0x015, 0x0008f424, | ||
706 | 0x015, 0x000cf424, | ||
707 | 0x016, 0x000e0330, | ||
708 | 0x016, 0x000a0330, | ||
709 | 0x016, 0x00060330, | ||
710 | 0x016, 0x00020330, | ||
711 | }; | ||
712 | |||
713 | u32 RTL8192CU_RADIOA_1TARRAY[RTL8192CURADIOA_1TARRAYLENGTH] = { | ||
714 | 0x000, 0x00030159, | ||
715 | 0x001, 0x00031284, | ||
716 | 0x002, 0x00098000, | ||
717 | 0x003, 0x00018c63, | ||
718 | 0x004, 0x000210e7, | ||
719 | 0x009, 0x0002044f, | ||
720 | 0x00a, 0x0001adb1, | ||
721 | 0x00b, 0x00054867, | ||
722 | 0x00c, 0x0008992e, | ||
723 | 0x00d, 0x0000e52c, | ||
724 | 0x00e, 0x00039ce7, | ||
725 | 0x00f, 0x00000451, | ||
726 | 0x019, 0x00000000, | ||
727 | 0x01a, 0x00010255, | ||
728 | 0x01b, 0x00060a00, | ||
729 | 0x01c, 0x000fc378, | ||
730 | 0x01d, 0x000a1250, | ||
731 | 0x01e, 0x0004445f, | ||
732 | 0x01f, 0x00080001, | ||
733 | 0x020, 0x0000b614, | ||
734 | 0x021, 0x0006c000, | ||
735 | 0x022, 0x00000000, | ||
736 | 0x023, 0x00001558, | ||
737 | 0x024, 0x00000060, | ||
738 | 0x025, 0x00000483, | ||
739 | 0x026, 0x0004f000, | ||
740 | 0x027, 0x000ec7d9, | ||
741 | 0x028, 0x000577c0, | ||
742 | 0x029, 0x00004783, | ||
743 | 0x02a, 0x00000001, | ||
744 | 0x02b, 0x00021334, | ||
745 | 0x02a, 0x00000000, | ||
746 | 0x02b, 0x00000054, | ||
747 | 0x02a, 0x00000001, | ||
748 | 0x02b, 0x00000808, | ||
749 | 0x02b, 0x00053333, | ||
750 | 0x02c, 0x0000000c, | ||
751 | 0x02a, 0x00000002, | ||
752 | 0x02b, 0x00000808, | ||
753 | 0x02b, 0x0005b333, | ||
754 | 0x02c, 0x0000000d, | ||
755 | 0x02a, 0x00000003, | ||
756 | 0x02b, 0x00000808, | ||
757 | 0x02b, 0x00063333, | ||
758 | 0x02c, 0x0000000d, | ||
759 | 0x02a, 0x00000004, | ||
760 | 0x02b, 0x00000808, | ||
761 | 0x02b, 0x0006b333, | ||
762 | 0x02c, 0x0000000d, | ||
763 | 0x02a, 0x00000005, | ||
764 | 0x02b, 0x00000808, | ||
765 | 0x02b, 0x00073333, | ||
766 | 0x02c, 0x0000000d, | ||
767 | 0x02a, 0x00000006, | ||
768 | 0x02b, 0x00000709, | ||
769 | 0x02b, 0x0005b333, | ||
770 | 0x02c, 0x0000000d, | ||
771 | 0x02a, 0x00000007, | ||
772 | 0x02b, 0x00000709, | ||
773 | 0x02b, 0x00063333, | ||
774 | 0x02c, 0x0000000d, | ||
775 | 0x02a, 0x00000008, | ||
776 | 0x02b, 0x0000060a, | ||
777 | 0x02b, 0x0004b333, | ||
778 | 0x02c, 0x0000000d, | ||
779 | 0x02a, 0x00000009, | ||
780 | 0x02b, 0x0000060a, | ||
781 | 0x02b, 0x00053333, | ||
782 | 0x02c, 0x0000000d, | ||
783 | 0x02a, 0x0000000a, | ||
784 | 0x02b, 0x0000060a, | ||
785 | 0x02b, 0x0005b333, | ||
786 | 0x02c, 0x0000000d, | ||
787 | 0x02a, 0x0000000b, | ||
788 | 0x02b, 0x0000060a, | ||
789 | 0x02b, 0x00063333, | ||
790 | 0x02c, 0x0000000d, | ||
791 | 0x02a, 0x0000000c, | ||
792 | 0x02b, 0x0000060a, | ||
793 | 0x02b, 0x0006b333, | ||
794 | 0x02c, 0x0000000d, | ||
795 | 0x02a, 0x0000000d, | ||
796 | 0x02b, 0x0000060a, | ||
797 | 0x02b, 0x00073333, | ||
798 | 0x02c, 0x0000000d, | ||
799 | 0x02a, 0x0000000e, | ||
800 | 0x02b, 0x0000050b, | ||
801 | 0x02b, 0x00066666, | ||
802 | 0x02c, 0x0000001a, | ||
803 | 0x02a, 0x000e0000, | ||
804 | 0x010, 0x0004000f, | ||
805 | 0x011, 0x000e31fc, | ||
806 | 0x010, 0x0006000f, | ||
807 | 0x011, 0x000ff9f8, | ||
808 | 0x010, 0x0002000f, | ||
809 | 0x011, 0x000203f9, | ||
810 | 0x010, 0x0003000f, | ||
811 | 0x011, 0x000ff500, | ||
812 | 0x010, 0x00000000, | ||
813 | 0x011, 0x00000000, | ||
814 | 0x010, 0x0008000f, | ||
815 | 0x011, 0x0003f100, | ||
816 | 0x010, 0x0009000f, | ||
817 | 0x011, 0x00023100, | ||
818 | 0x012, 0x00032000, | ||
819 | 0x012, 0x00071000, | ||
820 | 0x012, 0x000b0000, | ||
821 | 0x012, 0x000fc000, | ||
822 | 0x013, 0x000287b3, | ||
823 | 0x013, 0x000244b7, | ||
824 | 0x013, 0x000204ab, | ||
825 | 0x013, 0x0001c49f, | ||
826 | 0x013, 0x00018493, | ||
827 | 0x013, 0x0001429b, | ||
828 | 0x013, 0x00010299, | ||
829 | 0x013, 0x0000c29c, | ||
830 | 0x013, 0x000081a0, | ||
831 | 0x013, 0x000040ac, | ||
832 | 0x013, 0x00000020, | ||
833 | 0x014, 0x0001944c, | ||
834 | 0x014, 0x00059444, | ||
835 | 0x014, 0x0009944c, | ||
836 | 0x014, 0x000d9444, | ||
837 | 0x015, 0x0000f405, | ||
838 | 0x015, 0x0004f405, | ||
839 | 0x015, 0x0008f405, | ||
840 | 0x015, 0x000cf405, | ||
841 | 0x016, 0x000e0330, | ||
842 | 0x016, 0x000a0330, | ||
843 | 0x016, 0x00060330, | ||
844 | 0x016, 0x00020330, | ||
845 | 0x000, 0x00010159, | ||
846 | 0x018, 0x0000f401, | ||
847 | 0x0fe, 0x00000000, | ||
848 | 0x0fe, 0x00000000, | ||
849 | 0x01f, 0x00080003, | ||
850 | 0x0fe, 0x00000000, | ||
851 | 0x0fe, 0x00000000, | ||
852 | 0x01e, 0x00044457, | ||
853 | 0x01f, 0x00080000, | ||
854 | 0x000, 0x00030159, | ||
855 | }; | ||
856 | |||
857 | u32 RTL8192CU_RADIOB_1TARRAY[RTL8192CURADIOB_1TARRAYLENGTH] = { | ||
858 | 0x0, | ||
859 | }; | ||
860 | |||
861 | u32 RTL8192CUMAC_2T_ARRAY[RTL8192CUMAC_2T_ARRAYLENGTH] = { | ||
862 | 0x420, 0x00000080, | ||
863 | 0x423, 0x00000000, | ||
864 | 0x430, 0x00000000, | ||
865 | 0x431, 0x00000000, | ||
866 | 0x432, 0x00000000, | ||
867 | 0x433, 0x00000001, | ||
868 | 0x434, 0x00000004, | ||
869 | 0x435, 0x00000005, | ||
870 | 0x436, 0x00000006, | ||
871 | 0x437, 0x00000007, | ||
872 | 0x438, 0x00000000, | ||
873 | 0x439, 0x00000000, | ||
874 | 0x43a, 0x00000000, | ||
875 | 0x43b, 0x00000001, | ||
876 | 0x43c, 0x00000004, | ||
877 | 0x43d, 0x00000005, | ||
878 | 0x43e, 0x00000006, | ||
879 | 0x43f, 0x00000007, | ||
880 | 0x440, 0x0000005d, | ||
881 | 0x441, 0x00000001, | ||
882 | 0x442, 0x00000000, | ||
883 | 0x444, 0x00000015, | ||
884 | 0x445, 0x000000f0, | ||
885 | 0x446, 0x0000000f, | ||
886 | 0x447, 0x00000000, | ||
887 | 0x458, 0x00000041, | ||
888 | 0x459, 0x000000a8, | ||
889 | 0x45a, 0x00000072, | ||
890 | 0x45b, 0x000000b9, | ||
891 | 0x460, 0x00000066, | ||
892 | 0x461, 0x00000066, | ||
893 | 0x462, 0x00000008, | ||
894 | 0x463, 0x00000003, | ||
895 | 0x4c8, 0x000000ff, | ||
896 | 0x4c9, 0x00000008, | ||
897 | 0x4cc, 0x000000ff, | ||
898 | 0x4cd, 0x000000ff, | ||
899 | 0x4ce, 0x00000001, | ||
900 | 0x500, 0x00000026, | ||
901 | 0x501, 0x000000a2, | ||
902 | 0x502, 0x0000002f, | ||
903 | 0x503, 0x00000000, | ||
904 | 0x504, 0x00000028, | ||
905 | 0x505, 0x000000a3, | ||
906 | 0x506, 0x0000005e, | ||
907 | 0x507, 0x00000000, | ||
908 | 0x508, 0x0000002b, | ||
909 | 0x509, 0x000000a4, | ||
910 | 0x50a, 0x0000005e, | ||
911 | 0x50b, 0x00000000, | ||
912 | 0x50c, 0x0000004f, | ||
913 | 0x50d, 0x000000a4, | ||
914 | 0x50e, 0x00000000, | ||
915 | 0x50f, 0x00000000, | ||
916 | 0x512, 0x0000001c, | ||
917 | 0x514, 0x0000000a, | ||
918 | 0x515, 0x00000010, | ||
919 | 0x516, 0x0000000a, | ||
920 | 0x517, 0x00000010, | ||
921 | 0x51a, 0x00000016, | ||
922 | 0x524, 0x0000000f, | ||
923 | 0x525, 0x0000004f, | ||
924 | 0x546, 0x00000040, | ||
925 | 0x547, 0x00000000, | ||
926 | 0x550, 0x00000010, | ||
927 | 0x551, 0x00000010, | ||
928 | 0x559, 0x00000002, | ||
929 | 0x55a, 0x00000002, | ||
930 | 0x55d, 0x000000ff, | ||
931 | 0x605, 0x00000030, | ||
932 | 0x608, 0x0000000e, | ||
933 | 0x609, 0x0000002a, | ||
934 | 0x652, 0x00000020, | ||
935 | 0x63c, 0x0000000a, | ||
936 | 0x63d, 0x0000000e, | ||
937 | 0x63e, 0x0000000a, | ||
938 | 0x63f, 0x0000000e, | ||
939 | 0x66e, 0x00000005, | ||
940 | 0x700, 0x00000021, | ||
941 | 0x701, 0x00000043, | ||
942 | 0x702, 0x00000065, | ||
943 | 0x703, 0x00000087, | ||
944 | 0x708, 0x00000021, | ||
945 | 0x709, 0x00000043, | ||
946 | 0x70a, 0x00000065, | ||
947 | 0x70b, 0x00000087, | ||
948 | }; | ||
949 | |||
950 | u32 RTL8192CUAGCTAB_2TARRAY[RTL8192CUAGCTAB_2TARRAYLENGTH] = { | ||
951 | 0xc78, 0x7b000001, | ||
952 | 0xc78, 0x7b010001, | ||
953 | 0xc78, 0x7b020001, | ||
954 | 0xc78, 0x7b030001, | ||
955 | 0xc78, 0x7b040001, | ||
956 | 0xc78, 0x7b050001, | ||
957 | 0xc78, 0x7a060001, | ||
958 | 0xc78, 0x79070001, | ||
959 | 0xc78, 0x78080001, | ||
960 | 0xc78, 0x77090001, | ||
961 | 0xc78, 0x760a0001, | ||
962 | 0xc78, 0x750b0001, | ||
963 | 0xc78, 0x740c0001, | ||
964 | 0xc78, 0x730d0001, | ||
965 | 0xc78, 0x720e0001, | ||
966 | 0xc78, 0x710f0001, | ||
967 | 0xc78, 0x70100001, | ||
968 | 0xc78, 0x6f110001, | ||
969 | 0xc78, 0x6e120001, | ||
970 | 0xc78, 0x6d130001, | ||
971 | 0xc78, 0x6c140001, | ||
972 | 0xc78, 0x6b150001, | ||
973 | 0xc78, 0x6a160001, | ||
974 | 0xc78, 0x69170001, | ||
975 | 0xc78, 0x68180001, | ||
976 | 0xc78, 0x67190001, | ||
977 | 0xc78, 0x661a0001, | ||
978 | 0xc78, 0x651b0001, | ||
979 | 0xc78, 0x641c0001, | ||
980 | 0xc78, 0x631d0001, | ||
981 | 0xc78, 0x621e0001, | ||
982 | 0xc78, 0x611f0001, | ||
983 | 0xc78, 0x60200001, | ||
984 | 0xc78, 0x49210001, | ||
985 | 0xc78, 0x48220001, | ||
986 | 0xc78, 0x47230001, | ||
987 | 0xc78, 0x46240001, | ||
988 | 0xc78, 0x45250001, | ||
989 | 0xc78, 0x44260001, | ||
990 | 0xc78, 0x43270001, | ||
991 | 0xc78, 0x42280001, | ||
992 | 0xc78, 0x41290001, | ||
993 | 0xc78, 0x402a0001, | ||
994 | 0xc78, 0x262b0001, | ||
995 | 0xc78, 0x252c0001, | ||
996 | 0xc78, 0x242d0001, | ||
997 | 0xc78, 0x232e0001, | ||
998 | 0xc78, 0x222f0001, | ||
999 | 0xc78, 0x21300001, | ||
1000 | 0xc78, 0x20310001, | ||
1001 | 0xc78, 0x06320001, | ||
1002 | 0xc78, 0x05330001, | ||
1003 | 0xc78, 0x04340001, | ||
1004 | 0xc78, 0x03350001, | ||
1005 | 0xc78, 0x02360001, | ||
1006 | 0xc78, 0x01370001, | ||
1007 | 0xc78, 0x00380001, | ||
1008 | 0xc78, 0x00390001, | ||
1009 | 0xc78, 0x003a0001, | ||
1010 | 0xc78, 0x003b0001, | ||
1011 | 0xc78, 0x003c0001, | ||
1012 | 0xc78, 0x003d0001, | ||
1013 | 0xc78, 0x003e0001, | ||
1014 | 0xc78, 0x003f0001, | ||
1015 | 0xc78, 0x7b400001, | ||
1016 | 0xc78, 0x7b410001, | ||
1017 | 0xc78, 0x7b420001, | ||
1018 | 0xc78, 0x7b430001, | ||
1019 | 0xc78, 0x7b440001, | ||
1020 | 0xc78, 0x7b450001, | ||
1021 | 0xc78, 0x7a460001, | ||
1022 | 0xc78, 0x79470001, | ||
1023 | 0xc78, 0x78480001, | ||
1024 | 0xc78, 0x77490001, | ||
1025 | 0xc78, 0x764a0001, | ||
1026 | 0xc78, 0x754b0001, | ||
1027 | 0xc78, 0x744c0001, | ||
1028 | 0xc78, 0x734d0001, | ||
1029 | 0xc78, 0x724e0001, | ||
1030 | 0xc78, 0x714f0001, | ||
1031 | 0xc78, 0x70500001, | ||
1032 | 0xc78, 0x6f510001, | ||
1033 | 0xc78, 0x6e520001, | ||
1034 | 0xc78, 0x6d530001, | ||
1035 | 0xc78, 0x6c540001, | ||
1036 | 0xc78, 0x6b550001, | ||
1037 | 0xc78, 0x6a560001, | ||
1038 | 0xc78, 0x69570001, | ||
1039 | 0xc78, 0x68580001, | ||
1040 | 0xc78, 0x67590001, | ||
1041 | 0xc78, 0x665a0001, | ||
1042 | 0xc78, 0x655b0001, | ||
1043 | 0xc78, 0x645c0001, | ||
1044 | 0xc78, 0x635d0001, | ||
1045 | 0xc78, 0x625e0001, | ||
1046 | 0xc78, 0x615f0001, | ||
1047 | 0xc78, 0x60600001, | ||
1048 | 0xc78, 0x49610001, | ||
1049 | 0xc78, 0x48620001, | ||
1050 | 0xc78, 0x47630001, | ||
1051 | 0xc78, 0x46640001, | ||
1052 | 0xc78, 0x45650001, | ||
1053 | 0xc78, 0x44660001, | ||
1054 | 0xc78, 0x43670001, | ||
1055 | 0xc78, 0x42680001, | ||
1056 | 0xc78, 0x41690001, | ||
1057 | 0xc78, 0x406a0001, | ||
1058 | 0xc78, 0x266b0001, | ||
1059 | 0xc78, 0x256c0001, | ||
1060 | 0xc78, 0x246d0001, | ||
1061 | 0xc78, 0x236e0001, | ||
1062 | 0xc78, 0x226f0001, | ||
1063 | 0xc78, 0x21700001, | ||
1064 | 0xc78, 0x20710001, | ||
1065 | 0xc78, 0x06720001, | ||
1066 | 0xc78, 0x05730001, | ||
1067 | 0xc78, 0x04740001, | ||
1068 | 0xc78, 0x03750001, | ||
1069 | 0xc78, 0x02760001, | ||
1070 | 0xc78, 0x01770001, | ||
1071 | 0xc78, 0x00780001, | ||
1072 | 0xc78, 0x00790001, | ||
1073 | 0xc78, 0x007a0001, | ||
1074 | 0xc78, 0x007b0001, | ||
1075 | 0xc78, 0x007c0001, | ||
1076 | 0xc78, 0x007d0001, | ||
1077 | 0xc78, 0x007e0001, | ||
1078 | 0xc78, 0x007f0001, | ||
1079 | 0xc78, 0x3800001e, | ||
1080 | 0xc78, 0x3801001e, | ||
1081 | 0xc78, 0x3802001e, | ||
1082 | 0xc78, 0x3803001e, | ||
1083 | 0xc78, 0x3804001e, | ||
1084 | 0xc78, 0x3805001e, | ||
1085 | 0xc78, 0x3806001e, | ||
1086 | 0xc78, 0x3807001e, | ||
1087 | 0xc78, 0x3808001e, | ||
1088 | 0xc78, 0x3c09001e, | ||
1089 | 0xc78, 0x3e0a001e, | ||
1090 | 0xc78, 0x400b001e, | ||
1091 | 0xc78, 0x440c001e, | ||
1092 | 0xc78, 0x480d001e, | ||
1093 | 0xc78, 0x4c0e001e, | ||
1094 | 0xc78, 0x500f001e, | ||
1095 | 0xc78, 0x5210001e, | ||
1096 | 0xc78, 0x5611001e, | ||
1097 | 0xc78, 0x5a12001e, | ||
1098 | 0xc78, 0x5e13001e, | ||
1099 | 0xc78, 0x6014001e, | ||
1100 | 0xc78, 0x6015001e, | ||
1101 | 0xc78, 0x6016001e, | ||
1102 | 0xc78, 0x6217001e, | ||
1103 | 0xc78, 0x6218001e, | ||
1104 | 0xc78, 0x6219001e, | ||
1105 | 0xc78, 0x621a001e, | ||
1106 | 0xc78, 0x621b001e, | ||
1107 | 0xc78, 0x621c001e, | ||
1108 | 0xc78, 0x621d001e, | ||
1109 | 0xc78, 0x621e001e, | ||
1110 | 0xc78, 0x621f001e, | ||
1111 | }; | ||
1112 | |||
1113 | u32 RTL8192CUAGCTAB_1TARRAY[RTL8192CUAGCTAB_1TARRAYLENGTH] = { | ||
1114 | 0xc78, 0x7b000001, | ||
1115 | 0xc78, 0x7b010001, | ||
1116 | 0xc78, 0x7b020001, | ||
1117 | 0xc78, 0x7b030001, | ||
1118 | 0xc78, 0x7b040001, | ||
1119 | 0xc78, 0x7b050001, | ||
1120 | 0xc78, 0x7a060001, | ||
1121 | 0xc78, 0x79070001, | ||
1122 | 0xc78, 0x78080001, | ||
1123 | 0xc78, 0x77090001, | ||
1124 | 0xc78, 0x760a0001, | ||
1125 | 0xc78, 0x750b0001, | ||
1126 | 0xc78, 0x740c0001, | ||
1127 | 0xc78, 0x730d0001, | ||
1128 | 0xc78, 0x720e0001, | ||
1129 | 0xc78, 0x710f0001, | ||
1130 | 0xc78, 0x70100001, | ||
1131 | 0xc78, 0x6f110001, | ||
1132 | 0xc78, 0x6e120001, | ||
1133 | 0xc78, 0x6d130001, | ||
1134 | 0xc78, 0x6c140001, | ||
1135 | 0xc78, 0x6b150001, | ||
1136 | 0xc78, 0x6a160001, | ||
1137 | 0xc78, 0x69170001, | ||
1138 | 0xc78, 0x68180001, | ||
1139 | 0xc78, 0x67190001, | ||
1140 | 0xc78, 0x661a0001, | ||
1141 | 0xc78, 0x651b0001, | ||
1142 | 0xc78, 0x641c0001, | ||
1143 | 0xc78, 0x631d0001, | ||
1144 | 0xc78, 0x621e0001, | ||
1145 | 0xc78, 0x611f0001, | ||
1146 | 0xc78, 0x60200001, | ||
1147 | 0xc78, 0x49210001, | ||
1148 | 0xc78, 0x48220001, | ||
1149 | 0xc78, 0x47230001, | ||
1150 | 0xc78, 0x46240001, | ||
1151 | 0xc78, 0x45250001, | ||
1152 | 0xc78, 0x44260001, | ||
1153 | 0xc78, 0x43270001, | ||
1154 | 0xc78, 0x42280001, | ||
1155 | 0xc78, 0x41290001, | ||
1156 | 0xc78, 0x402a0001, | ||
1157 | 0xc78, 0x262b0001, | ||
1158 | 0xc78, 0x252c0001, | ||
1159 | 0xc78, 0x242d0001, | ||
1160 | 0xc78, 0x232e0001, | ||
1161 | 0xc78, 0x222f0001, | ||
1162 | 0xc78, 0x21300001, | ||
1163 | 0xc78, 0x20310001, | ||
1164 | 0xc78, 0x06320001, | ||
1165 | 0xc78, 0x05330001, | ||
1166 | 0xc78, 0x04340001, | ||
1167 | 0xc78, 0x03350001, | ||
1168 | 0xc78, 0x02360001, | ||
1169 | 0xc78, 0x01370001, | ||
1170 | 0xc78, 0x00380001, | ||
1171 | 0xc78, 0x00390001, | ||
1172 | 0xc78, 0x003a0001, | ||
1173 | 0xc78, 0x003b0001, | ||
1174 | 0xc78, 0x003c0001, | ||
1175 | 0xc78, 0x003d0001, | ||
1176 | 0xc78, 0x003e0001, | ||
1177 | 0xc78, 0x003f0001, | ||
1178 | 0xc78, 0x7b400001, | ||
1179 | 0xc78, 0x7b410001, | ||
1180 | 0xc78, 0x7b420001, | ||
1181 | 0xc78, 0x7b430001, | ||
1182 | 0xc78, 0x7b440001, | ||
1183 | 0xc78, 0x7b450001, | ||
1184 | 0xc78, 0x7a460001, | ||
1185 | 0xc78, 0x79470001, | ||
1186 | 0xc78, 0x78480001, | ||
1187 | 0xc78, 0x77490001, | ||
1188 | 0xc78, 0x764a0001, | ||
1189 | 0xc78, 0x754b0001, | ||
1190 | 0xc78, 0x744c0001, | ||
1191 | 0xc78, 0x734d0001, | ||
1192 | 0xc78, 0x724e0001, | ||
1193 | 0xc78, 0x714f0001, | ||
1194 | 0xc78, 0x70500001, | ||
1195 | 0xc78, 0x6f510001, | ||
1196 | 0xc78, 0x6e520001, | ||
1197 | 0xc78, 0x6d530001, | ||
1198 | 0xc78, 0x6c540001, | ||
1199 | 0xc78, 0x6b550001, | ||
1200 | 0xc78, 0x6a560001, | ||
1201 | 0xc78, 0x69570001, | ||
1202 | 0xc78, 0x68580001, | ||
1203 | 0xc78, 0x67590001, | ||
1204 | 0xc78, 0x665a0001, | ||
1205 | 0xc78, 0x655b0001, | ||
1206 | 0xc78, 0x645c0001, | ||
1207 | 0xc78, 0x635d0001, | ||
1208 | 0xc78, 0x625e0001, | ||
1209 | 0xc78, 0x615f0001, | ||
1210 | 0xc78, 0x60600001, | ||
1211 | 0xc78, 0x49610001, | ||
1212 | 0xc78, 0x48620001, | ||
1213 | 0xc78, 0x47630001, | ||
1214 | 0xc78, 0x46640001, | ||
1215 | 0xc78, 0x45650001, | ||
1216 | 0xc78, 0x44660001, | ||
1217 | 0xc78, 0x43670001, | ||
1218 | 0xc78, 0x42680001, | ||
1219 | 0xc78, 0x41690001, | ||
1220 | 0xc78, 0x406a0001, | ||
1221 | 0xc78, 0x266b0001, | ||
1222 | 0xc78, 0x256c0001, | ||
1223 | 0xc78, 0x246d0001, | ||
1224 | 0xc78, 0x236e0001, | ||
1225 | 0xc78, 0x226f0001, | ||
1226 | 0xc78, 0x21700001, | ||
1227 | 0xc78, 0x20710001, | ||
1228 | 0xc78, 0x06720001, | ||
1229 | 0xc78, 0x05730001, | ||
1230 | 0xc78, 0x04740001, | ||
1231 | 0xc78, 0x03750001, | ||
1232 | 0xc78, 0x02760001, | ||
1233 | 0xc78, 0x01770001, | ||
1234 | 0xc78, 0x00780001, | ||
1235 | 0xc78, 0x00790001, | ||
1236 | 0xc78, 0x007a0001, | ||
1237 | 0xc78, 0x007b0001, | ||
1238 | 0xc78, 0x007c0001, | ||
1239 | 0xc78, 0x007d0001, | ||
1240 | 0xc78, 0x007e0001, | ||
1241 | 0xc78, 0x007f0001, | ||
1242 | 0xc78, 0x3800001e, | ||
1243 | 0xc78, 0x3801001e, | ||
1244 | 0xc78, 0x3802001e, | ||
1245 | 0xc78, 0x3803001e, | ||
1246 | 0xc78, 0x3804001e, | ||
1247 | 0xc78, 0x3805001e, | ||
1248 | 0xc78, 0x3806001e, | ||
1249 | 0xc78, 0x3807001e, | ||
1250 | 0xc78, 0x3808001e, | ||
1251 | 0xc78, 0x3c09001e, | ||
1252 | 0xc78, 0x3e0a001e, | ||
1253 | 0xc78, 0x400b001e, | ||
1254 | 0xc78, 0x440c001e, | ||
1255 | 0xc78, 0x480d001e, | ||
1256 | 0xc78, 0x4c0e001e, | ||
1257 | 0xc78, 0x500f001e, | ||
1258 | 0xc78, 0x5210001e, | ||
1259 | 0xc78, 0x5611001e, | ||
1260 | 0xc78, 0x5a12001e, | ||
1261 | 0xc78, 0x5e13001e, | ||
1262 | 0xc78, 0x6014001e, | ||
1263 | 0xc78, 0x6015001e, | ||
1264 | 0xc78, 0x6016001e, | ||
1265 | 0xc78, 0x6217001e, | ||
1266 | 0xc78, 0x6218001e, | ||
1267 | 0xc78, 0x6219001e, | ||
1268 | 0xc78, 0x621a001e, | ||
1269 | 0xc78, 0x621b001e, | ||
1270 | 0xc78, 0x621c001e, | ||
1271 | 0xc78, 0x621d001e, | ||
1272 | 0xc78, 0x621e001e, | ||
1273 | 0xc78, 0x621f001e, | ||
1274 | }; | ||
1275 | |||
1276 | u32 RTL8192CUPHY_REG_1T_HPArray[RTL8192CUPHY_REG_1T_HPArrayLength] = { | ||
1277 | 0x024, 0x0011800f, | ||
1278 | 0x028, 0x00ffdb83, | ||
1279 | 0x040, 0x000c0004, | ||
1280 | 0x800, 0x80040000, | ||
1281 | 0x804, 0x00000001, | ||
1282 | 0x808, 0x0000fc00, | ||
1283 | 0x80c, 0x0000000a, | ||
1284 | 0x810, 0x10005388, | ||
1285 | 0x814, 0x020c3d10, | ||
1286 | 0x818, 0x02200385, | ||
1287 | 0x81c, 0x00000000, | ||
1288 | 0x820, 0x01000100, | ||
1289 | 0x824, 0x00390204, | ||
1290 | 0x828, 0x00000000, | ||
1291 | 0x82c, 0x00000000, | ||
1292 | 0x830, 0x00000000, | ||
1293 | 0x834, 0x00000000, | ||
1294 | 0x838, 0x00000000, | ||
1295 | 0x83c, 0x00000000, | ||
1296 | 0x840, 0x00010000, | ||
1297 | 0x844, 0x00000000, | ||
1298 | 0x848, 0x00000000, | ||
1299 | 0x84c, 0x00000000, | ||
1300 | 0x850, 0x00000000, | ||
1301 | 0x854, 0x00000000, | ||
1302 | 0x858, 0x569a569a, | ||
1303 | 0x85c, 0x001b25a4, | ||
1304 | 0x860, 0x66e60230, | ||
1305 | 0x864, 0x061f0130, | ||
1306 | 0x868, 0x00000000, | ||
1307 | 0x86c, 0x20202000, | ||
1308 | 0x870, 0x03000300, | ||
1309 | 0x874, 0x22004000, | ||
1310 | 0x878, 0x00000808, | ||
1311 | 0x87c, 0x00ffc3f1, | ||
1312 | 0x880, 0xc0083070, | ||
1313 | 0x884, 0x000004d5, | ||
1314 | 0x888, 0x00000000, | ||
1315 | 0x88c, 0xccc000c0, | ||
1316 | 0x890, 0x00000800, | ||
1317 | 0x894, 0xfffffffe, | ||
1318 | 0x898, 0x40302010, | ||
1319 | 0x89c, 0x00706050, | ||
1320 | 0x900, 0x00000000, | ||
1321 | 0x904, 0x00000023, | ||
1322 | 0x908, 0x00000000, | ||
1323 | 0x90c, 0x81121111, | ||
1324 | 0xa00, 0x00d047c8, | ||
1325 | 0xa04, 0x80ff000c, | ||
1326 | 0xa08, 0x8c838300, | ||
1327 | 0xa0c, 0x2e68120f, | ||
1328 | 0xa10, 0x9500bb78, | ||
1329 | 0xa14, 0x11144028, | ||
1330 | 0xa18, 0x00881117, | ||
1331 | 0xa1c, 0x89140f00, | ||
1332 | 0xa20, 0x15160000, | ||
1333 | 0xa24, 0x070b0f12, | ||
1334 | 0xa28, 0x00000104, | ||
1335 | 0xa2c, 0x00d30000, | ||
1336 | 0xa70, 0x101fbf00, | ||
1337 | 0xa74, 0x00000007, | ||
1338 | 0xc00, 0x48071d40, | ||
1339 | 0xc04, 0x03a05611, | ||
1340 | 0xc08, 0x000000e4, | ||
1341 | 0xc0c, 0x6c6c6c6c, | ||
1342 | 0xc10, 0x08800000, | ||
1343 | 0xc14, 0x40000100, | ||
1344 | 0xc18, 0x08800000, | ||
1345 | 0xc1c, 0x40000100, | ||
1346 | 0xc20, 0x00000000, | ||
1347 | 0xc24, 0x00000000, | ||
1348 | 0xc28, 0x00000000, | ||
1349 | 0xc2c, 0x00000000, | ||
1350 | 0xc30, 0x69e9ac44, | ||
1351 | 0xc34, 0x469652cf, | ||
1352 | 0xc38, 0x49795994, | ||
1353 | 0xc3c, 0x0a97971c, | ||
1354 | 0xc40, 0x1f7c403f, | ||
1355 | 0xc44, 0x000100b7, | ||
1356 | 0xc48, 0xec020107, | ||
1357 | 0xc4c, 0x007f037f, | ||
1358 | 0xc50, 0x6954342e, | ||
1359 | 0xc54, 0x43bc0094, | ||
1360 | 0xc58, 0x6954342f, | ||
1361 | 0xc5c, 0x433c0094, | ||
1362 | 0xc60, 0x00000000, | ||
1363 | 0xc64, 0x5116848b, | ||
1364 | 0xc68, 0x47c00bff, | ||
1365 | 0xc6c, 0x00000036, | ||
1366 | 0xc70, 0x2c46000d, | ||
1367 | 0xc74, 0x018610db, | ||
1368 | 0xc78, 0x0000001f, | ||
1369 | 0xc7c, 0x00b91612, | ||
1370 | 0xc80, 0x24000090, | ||
1371 | 0xc84, 0x20f60000, | ||
1372 | 0xc88, 0x24000090, | ||
1373 | 0xc8c, 0x20200000, | ||
1374 | 0xc90, 0x00121820, | ||
1375 | 0xc94, 0x00000000, | ||
1376 | 0xc98, 0x00121820, | ||
1377 | 0xc9c, 0x00007f7f, | ||
1378 | 0xca0, 0x00000000, | ||
1379 | 0xca4, 0x00000080, | ||
1380 | 0xca8, 0x00000000, | ||
1381 | 0xcac, 0x00000000, | ||
1382 | 0xcb0, 0x00000000, | ||
1383 | 0xcb4, 0x00000000, | ||
1384 | 0xcb8, 0x00000000, | ||
1385 | 0xcbc, 0x28000000, | ||
1386 | 0xcc0, 0x00000000, | ||
1387 | 0xcc4, 0x00000000, | ||
1388 | 0xcc8, 0x00000000, | ||
1389 | 0xccc, 0x00000000, | ||
1390 | 0xcd0, 0x00000000, | ||
1391 | 0xcd4, 0x00000000, | ||
1392 | 0xcd8, 0x64b22427, | ||
1393 | 0xcdc, 0x00766932, | ||
1394 | 0xce0, 0x00222222, | ||
1395 | 0xce4, 0x00000000, | ||
1396 | 0xce8, 0x37644302, | ||
1397 | 0xcec, 0x2f97d40c, | ||
1398 | 0xd00, 0x00080740, | ||
1399 | 0xd04, 0x00020401, | ||
1400 | 0xd08, 0x0000907f, | ||
1401 | 0xd0c, 0x20010201, | ||
1402 | 0xd10, 0xa0633333, | ||
1403 | 0xd14, 0x3333bc43, | ||
1404 | 0xd18, 0x7a8f5b6b, | ||
1405 | 0xd2c, 0xcc979975, | ||
1406 | 0xd30, 0x00000000, | ||
1407 | 0xd34, 0x80608000, | ||
1408 | 0xd38, 0x00000000, | ||
1409 | 0xd3c, 0x00027293, | ||
1410 | 0xd40, 0x00000000, | ||
1411 | 0xd44, 0x00000000, | ||
1412 | 0xd48, 0x00000000, | ||
1413 | 0xd4c, 0x00000000, | ||
1414 | 0xd50, 0x6437140a, | ||
1415 | 0xd54, 0x00000000, | ||
1416 | 0xd58, 0x00000000, | ||
1417 | 0xd5c, 0x30032064, | ||
1418 | 0xd60, 0x4653de68, | ||
1419 | 0xd64, 0x04518a3c, | ||
1420 | 0xd68, 0x00002101, | ||
1421 | 0xd6c, 0x2a201c16, | ||
1422 | 0xd70, 0x1812362e, | ||
1423 | 0xd74, 0x322c2220, | ||
1424 | 0xd78, 0x000e3c24, | ||
1425 | 0xe00, 0x24242424, | ||
1426 | 0xe04, 0x24242424, | ||
1427 | 0xe08, 0x03902024, | ||
1428 | 0xe10, 0x24242424, | ||
1429 | 0xe14, 0x24242424, | ||
1430 | 0xe18, 0x24242424, | ||
1431 | 0xe1c, 0x24242424, | ||
1432 | 0xe28, 0x00000000, | ||
1433 | 0xe30, 0x1000dc1f, | ||
1434 | 0xe34, 0x10008c1f, | ||
1435 | 0xe38, 0x02140102, | ||
1436 | 0xe3c, 0x681604c2, | ||
1437 | 0xe40, 0x01007c00, | ||
1438 | 0xe44, 0x01004800, | ||
1439 | 0xe48, 0xfb000000, | ||
1440 | 0xe4c, 0x000028d1, | ||
1441 | 0xe50, 0x1000dc1f, | ||
1442 | 0xe54, 0x10008c1f, | ||
1443 | 0xe58, 0x02140102, | ||
1444 | 0xe5c, 0x28160d05, | ||
1445 | 0xe60, 0x00000008, | ||
1446 | 0xe68, 0x001b25a4, | ||
1447 | 0xe6c, 0x631b25a0, | ||
1448 | 0xe70, 0x631b25a0, | ||
1449 | 0xe74, 0x081b25a0, | ||
1450 | 0xe78, 0x081b25a0, | ||
1451 | 0xe7c, 0x081b25a0, | ||
1452 | 0xe80, 0x081b25a0, | ||
1453 | 0xe84, 0x631b25a0, | ||
1454 | 0xe88, 0x081b25a0, | ||
1455 | 0xe8c, 0x631b25a0, | ||
1456 | 0xed0, 0x631b25a0, | ||
1457 | 0xed4, 0x631b25a0, | ||
1458 | 0xed8, 0x631b25a0, | ||
1459 | 0xedc, 0x001b25a0, | ||
1460 | 0xee0, 0x001b25a0, | ||
1461 | 0xeec, 0x6b1b25a0, | ||
1462 | 0xee8, 0x31555448, | ||
1463 | 0xf14, 0x00000003, | ||
1464 | 0xf4c, 0x00000000, | ||
1465 | 0xf00, 0x00000300, | ||
1466 | }; | ||
1467 | |||
1468 | u32 RTL8192CUPHY_REG_Array_PG_HP[RTL8192CUPHY_REG_Array_PG_HPLength] = { | ||
1469 | 0xe00, 0xffffffff, 0x06080808, | ||
1470 | 0xe04, 0xffffffff, 0x00040406, | ||
1471 | 0xe08, 0x0000ff00, 0x00000000, | ||
1472 | 0x86c, 0xffffff00, 0x00000000, | ||
1473 | 0xe10, 0xffffffff, 0x04060608, | ||
1474 | 0xe14, 0xffffffff, 0x00020204, | ||
1475 | 0xe18, 0xffffffff, 0x04060608, | ||
1476 | 0xe1c, 0xffffffff, 0x00020204, | ||
1477 | 0x830, 0xffffffff, 0x06080808, | ||
1478 | 0x834, 0xffffffff, 0x00040406, | ||
1479 | 0x838, 0xffffff00, 0x00000000, | ||
1480 | 0x86c, 0x000000ff, 0x00000000, | ||
1481 | 0x83c, 0xffffffff, 0x04060608, | ||
1482 | 0x848, 0xffffffff, 0x00020204, | ||
1483 | 0x84c, 0xffffffff, 0x04060608, | ||
1484 | 0x868, 0xffffffff, 0x00020204, | ||
1485 | 0xe00, 0xffffffff, 0x00000000, | ||
1486 | 0xe04, 0xffffffff, 0x00000000, | ||
1487 | 0xe08, 0x0000ff00, 0x00000000, | ||
1488 | 0x86c, 0xffffff00, 0x00000000, | ||
1489 | 0xe10, 0xffffffff, 0x00000000, | ||
1490 | 0xe14, 0xffffffff, 0x00000000, | ||
1491 | 0xe18, 0xffffffff, 0x00000000, | ||
1492 | 0xe1c, 0xffffffff, 0x00000000, | ||
1493 | 0x830, 0xffffffff, 0x00000000, | ||
1494 | 0x834, 0xffffffff, 0x00000000, | ||
1495 | 0x838, 0xffffff00, 0x00000000, | ||
1496 | 0x86c, 0x000000ff, 0x00000000, | ||
1497 | 0x83c, 0xffffffff, 0x00000000, | ||
1498 | 0x848, 0xffffffff, 0x00000000, | ||
1499 | 0x84c, 0xffffffff, 0x00000000, | ||
1500 | 0x868, 0xffffffff, 0x00000000, | ||
1501 | 0xe00, 0xffffffff, 0x00000000, | ||
1502 | 0xe04, 0xffffffff, 0x00000000, | ||
1503 | 0xe08, 0x0000ff00, 0x00000000, | ||
1504 | 0x86c, 0xffffff00, 0x00000000, | ||
1505 | 0xe10, 0xffffffff, 0x00000000, | ||
1506 | 0xe14, 0xffffffff, 0x00000000, | ||
1507 | 0xe18, 0xffffffff, 0x00000000, | ||
1508 | 0xe1c, 0xffffffff, 0x00000000, | ||
1509 | 0x830, 0xffffffff, 0x00000000, | ||
1510 | 0x834, 0xffffffff, 0x00000000, | ||
1511 | 0x838, 0xffffff00, 0x00000000, | ||
1512 | 0x86c, 0x000000ff, 0x00000000, | ||
1513 | 0x83c, 0xffffffff, 0x00000000, | ||
1514 | 0x848, 0xffffffff, 0x00000000, | ||
1515 | 0x84c, 0xffffffff, 0x00000000, | ||
1516 | 0x868, 0xffffffff, 0x00000000, | ||
1517 | 0xe00, 0xffffffff, 0x00000000, | ||
1518 | 0xe04, 0xffffffff, 0x00000000, | ||
1519 | 0xe08, 0x0000ff00, 0x00000000, | ||
1520 | 0x86c, 0xffffff00, 0x00000000, | ||
1521 | 0xe10, 0xffffffff, 0x00000000, | ||
1522 | 0xe14, 0xffffffff, 0x00000000, | ||
1523 | 0xe18, 0xffffffff, 0x00000000, | ||
1524 | 0xe1c, 0xffffffff, 0x00000000, | ||
1525 | 0x830, 0xffffffff, 0x00000000, | ||
1526 | 0x834, 0xffffffff, 0x00000000, | ||
1527 | 0x838, 0xffffff00, 0x00000000, | ||
1528 | 0x86c, 0x000000ff, 0x00000000, | ||
1529 | 0x83c, 0xffffffff, 0x00000000, | ||
1530 | 0x848, 0xffffffff, 0x00000000, | ||
1531 | 0x84c, 0xffffffff, 0x00000000, | ||
1532 | 0x868, 0xffffffff, 0x00000000, | ||
1533 | 0xe00, 0xffffffff, 0x00000000, | ||
1534 | 0xe04, 0xffffffff, 0x00000000, | ||
1535 | 0xe08, 0x0000ff00, 0x00000000, | ||
1536 | 0x86c, 0xffffff00, 0x00000000, | ||
1537 | 0xe10, 0xffffffff, 0x00000000, | ||
1538 | 0xe14, 0xffffffff, 0x00000000, | ||
1539 | 0xe18, 0xffffffff, 0x00000000, | ||
1540 | 0xe1c, 0xffffffff, 0x00000000, | ||
1541 | 0x830, 0xffffffff, 0x00000000, | ||
1542 | 0x834, 0xffffffff, 0x00000000, | ||
1543 | 0x838, 0xffffff00, 0x00000000, | ||
1544 | 0x86c, 0x000000ff, 0x00000000, | ||
1545 | 0x83c, 0xffffffff, 0x00000000, | ||
1546 | 0x848, 0xffffffff, 0x00000000, | ||
1547 | 0x84c, 0xffffffff, 0x00000000, | ||
1548 | 0x868, 0xffffffff, 0x00000000, | ||
1549 | 0xe00, 0xffffffff, 0x00000000, | ||
1550 | 0xe04, 0xffffffff, 0x00000000, | ||
1551 | 0xe08, 0x0000ff00, 0x00000000, | ||
1552 | 0x86c, 0xffffff00, 0x00000000, | ||
1553 | 0xe10, 0xffffffff, 0x00000000, | ||
1554 | 0xe14, 0xffffffff, 0x00000000, | ||
1555 | 0xe18, 0xffffffff, 0x00000000, | ||
1556 | 0xe1c, 0xffffffff, 0x00000000, | ||
1557 | 0x830, 0xffffffff, 0x00000000, | ||
1558 | 0x834, 0xffffffff, 0x00000000, | ||
1559 | 0x838, 0xffffff00, 0x00000000, | ||
1560 | 0x86c, 0x000000ff, 0x00000000, | ||
1561 | 0x83c, 0xffffffff, 0x00000000, | ||
1562 | 0x848, 0xffffffff, 0x00000000, | ||
1563 | 0x84c, 0xffffffff, 0x00000000, | ||
1564 | 0x868, 0xffffffff, 0x00000000, | ||
1565 | 0xe00, 0xffffffff, 0x00000000, | ||
1566 | 0xe04, 0xffffffff, 0x00000000, | ||
1567 | 0xe08, 0x0000ff00, 0x00000000, | ||
1568 | 0x86c, 0xffffff00, 0x00000000, | ||
1569 | 0xe10, 0xffffffff, 0x00000000, | ||
1570 | 0xe14, 0xffffffff, 0x00000000, | ||
1571 | 0xe18, 0xffffffff, 0x00000000, | ||
1572 | 0xe1c, 0xffffffff, 0x00000000, | ||
1573 | 0x830, 0xffffffff, 0x00000000, | ||
1574 | 0x834, 0xffffffff, 0x00000000, | ||
1575 | 0x838, 0xffffff00, 0x00000000, | ||
1576 | 0x86c, 0x000000ff, 0x00000000, | ||
1577 | 0x83c, 0xffffffff, 0x00000000, | ||
1578 | 0x848, 0xffffffff, 0x00000000, | ||
1579 | 0x84c, 0xffffffff, 0x00000000, | ||
1580 | 0x868, 0xffffffff, 0x00000000, | ||
1581 | }; | ||
1582 | |||
1583 | u32 RTL8192CURadioA_1T_HPArray[RTL8192CURadioA_1T_HPArrayLength] = { | ||
1584 | 0x000, 0x00030159, | ||
1585 | 0x001, 0x00031284, | ||
1586 | 0x002, 0x00098000, | ||
1587 | 0x003, 0x00018c63, | ||
1588 | 0x004, 0x000210e7, | ||
1589 | 0x009, 0x0002044f, | ||
1590 | 0x00a, 0x0001adb0, | ||
1591 | 0x00b, 0x00054867, | ||
1592 | 0x00c, 0x0008992e, | ||
1593 | 0x00d, 0x0000e529, | ||
1594 | 0x00e, 0x00039ce7, | ||
1595 | 0x00f, 0x00000451, | ||
1596 | 0x019, 0x00000000, | ||
1597 | 0x01a, 0x00000255, | ||
1598 | 0x01b, 0x00060a00, | ||
1599 | 0x01c, 0x000fc378, | ||
1600 | 0x01d, 0x000a1250, | ||
1601 | 0x01e, 0x0004445f, | ||
1602 | 0x01f, 0x00080001, | ||
1603 | 0x020, 0x0000b614, | ||
1604 | 0x021, 0x0006c000, | ||
1605 | 0x022, 0x0000083c, | ||
1606 | 0x023, 0x00001558, | ||
1607 | 0x024, 0x00000060, | ||
1608 | 0x025, 0x00000483, | ||
1609 | 0x026, 0x0004f000, | ||
1610 | 0x027, 0x000ec7d9, | ||
1611 | 0x028, 0x000977c0, | ||
1612 | 0x029, 0x00004783, | ||
1613 | 0x02a, 0x00000001, | ||
1614 | 0x02b, 0x00021334, | ||
1615 | 0x02a, 0x00000000, | ||
1616 | 0x02b, 0x00000054, | ||
1617 | 0x02a, 0x00000001, | ||
1618 | 0x02b, 0x00000808, | ||
1619 | 0x02b, 0x00053333, | ||
1620 | 0x02c, 0x0000000c, | ||
1621 | 0x02a, 0x00000002, | ||
1622 | 0x02b, 0x00000808, | ||
1623 | 0x02b, 0x0005b333, | ||
1624 | 0x02c, 0x0000000d, | ||
1625 | 0x02a, 0x00000003, | ||
1626 | 0x02b, 0x00000808, | ||
1627 | 0x02b, 0x00063333, | ||
1628 | 0x02c, 0x0000000d, | ||
1629 | 0x02a, 0x00000004, | ||
1630 | 0x02b, 0x00000808, | ||
1631 | 0x02b, 0x0006b333, | ||
1632 | 0x02c, 0x0000000d, | ||
1633 | 0x02a, 0x00000005, | ||
1634 | 0x02b, 0x00000808, | ||
1635 | 0x02b, 0x00073333, | ||
1636 | 0x02c, 0x0000000d, | ||
1637 | 0x02a, 0x00000006, | ||
1638 | 0x02b, 0x00000709, | ||
1639 | 0x02b, 0x0005b333, | ||
1640 | 0x02c, 0x0000000d, | ||
1641 | 0x02a, 0x00000007, | ||
1642 | 0x02b, 0x00000709, | ||
1643 | 0x02b, 0x00063333, | ||
1644 | 0x02c, 0x0000000d, | ||
1645 | 0x02a, 0x00000008, | ||
1646 | 0x02b, 0x0000060a, | ||
1647 | 0x02b, 0x0004b333, | ||
1648 | 0x02c, 0x0000000d, | ||
1649 | 0x02a, 0x00000009, | ||
1650 | 0x02b, 0x0000060a, | ||
1651 | 0x02b, 0x00053333, | ||
1652 | 0x02c, 0x0000000d, | ||
1653 | 0x02a, 0x0000000a, | ||
1654 | 0x02b, 0x0000060a, | ||
1655 | 0x02b, 0x0005b333, | ||
1656 | 0x02c, 0x0000000d, | ||
1657 | 0x02a, 0x0000000b, | ||
1658 | 0x02b, 0x0000060a, | ||
1659 | 0x02b, 0x00063333, | ||
1660 | 0x02c, 0x0000000d, | ||
1661 | 0x02a, 0x0000000c, | ||
1662 | 0x02b, 0x0000060a, | ||
1663 | 0x02b, 0x0006b333, | ||
1664 | 0x02c, 0x0000000d, | ||
1665 | 0x02a, 0x0000000d, | ||
1666 | 0x02b, 0x0000060a, | ||
1667 | 0x02b, 0x00073333, | ||
1668 | 0x02c, 0x0000000d, | ||
1669 | 0x02a, 0x0000000e, | ||
1670 | 0x02b, 0x0000050b, | ||
1671 | 0x02b, 0x00066666, | ||
1672 | 0x02c, 0x0000001a, | ||
1673 | 0x02a, 0x000e0000, | ||
1674 | 0x010, 0x0004000f, | ||
1675 | 0x011, 0x000e31fc, | ||
1676 | 0x010, 0x0006000f, | ||
1677 | 0x011, 0x000ff9f8, | ||
1678 | 0x010, 0x0002000f, | ||
1679 | 0x011, 0x000203f9, | ||
1680 | 0x010, 0x0003000f, | ||
1681 | 0x011, 0x000ff500, | ||
1682 | 0x010, 0x00000000, | ||
1683 | 0x011, 0x00000000, | ||
1684 | 0x010, 0x0008000f, | ||
1685 | 0x011, 0x0003f100, | ||
1686 | 0x010, 0x0009000f, | ||
1687 | 0x011, 0x00023100, | ||
1688 | 0x012, 0x000d8000, | ||
1689 | 0x012, 0x00090000, | ||
1690 | 0x012, 0x00051000, | ||
1691 | 0x012, 0x00012000, | ||
1692 | 0x013, 0x00028fb4, | ||
1693 | 0x013, 0x00024fa8, | ||
1694 | 0x013, 0x000207a4, | ||
1695 | 0x013, 0x0001c798, | ||
1696 | 0x013, 0x000183a4, | ||
1697 | 0x013, 0x00014398, | ||
1698 | 0x013, 0x000101a4, | ||
1699 | 0x013, 0x0000c198, | ||
1700 | 0x013, 0x000080a4, | ||
1701 | 0x013, 0x00004098, | ||
1702 | 0x013, 0x00000000, | ||
1703 | 0x014, 0x0001944c, | ||
1704 | 0x014, 0x00059444, | ||
1705 | 0x014, 0x0009944c, | ||
1706 | 0x014, 0x000d9444, | ||
1707 | 0x015, 0x0000f405, | ||
1708 | 0x015, 0x0004f405, | ||
1709 | 0x015, 0x0008f405, | ||
1710 | 0x015, 0x000cf405, | ||
1711 | 0x016, 0x000e0330, | ||
1712 | 0x016, 0x000a0330, | ||
1713 | 0x016, 0x00060330, | ||
1714 | 0x016, 0x00020330, | ||
1715 | 0x000, 0x00010159, | ||
1716 | 0x018, 0x0000f401, | ||
1717 | 0x0fe, 0x00000000, | ||
1718 | 0x0fe, 0x00000000, | ||
1719 | 0x01f, 0x00080003, | ||
1720 | 0x0fe, 0x00000000, | ||
1721 | 0x0fe, 0x00000000, | ||
1722 | 0x01e, 0x00044457, | ||
1723 | 0x01f, 0x00080000, | ||
1724 | 0x000, 0x00030159, | ||
1725 | }; | ||
1726 | |||
1727 | u32 Rtl8192CUAGCTAB_1T_HPArray[RTL8192CUAGCTAB_1T_HPArrayLength] = { | ||
1728 | 0xc78, 0x7b000001, | ||
1729 | 0xc78, 0x7b010001, | ||
1730 | 0xc78, 0x7b020001, | ||
1731 | 0xc78, 0x7b030001, | ||
1732 | 0xc78, 0x7b040001, | ||
1733 | 0xc78, 0x7b050001, | ||
1734 | 0xc78, 0x7b060001, | ||
1735 | 0xc78, 0x7b070001, | ||
1736 | 0xc78, 0x7b080001, | ||
1737 | 0xc78, 0x7a090001, | ||
1738 | 0xc78, 0x790a0001, | ||
1739 | 0xc78, 0x780b0001, | ||
1740 | 0xc78, 0x770c0001, | ||
1741 | 0xc78, 0x760d0001, | ||
1742 | 0xc78, 0x750e0001, | ||
1743 | 0xc78, 0x740f0001, | ||
1744 | 0xc78, 0x73100001, | ||
1745 | 0xc78, 0x72110001, | ||
1746 | 0xc78, 0x71120001, | ||
1747 | 0xc78, 0x70130001, | ||
1748 | 0xc78, 0x6f140001, | ||
1749 | 0xc78, 0x6e150001, | ||
1750 | 0xc78, 0x6d160001, | ||
1751 | 0xc78, 0x6c170001, | ||
1752 | 0xc78, 0x6b180001, | ||
1753 | 0xc78, 0x6a190001, | ||
1754 | 0xc78, 0x691a0001, | ||
1755 | 0xc78, 0x681b0001, | ||
1756 | 0xc78, 0x671c0001, | ||
1757 | 0xc78, 0x661d0001, | ||
1758 | 0xc78, 0x651e0001, | ||
1759 | 0xc78, 0x641f0001, | ||
1760 | 0xc78, 0x63200001, | ||
1761 | 0xc78, 0x62210001, | ||
1762 | 0xc78, 0x61220001, | ||
1763 | 0xc78, 0x60230001, | ||
1764 | 0xc78, 0x46240001, | ||
1765 | 0xc78, 0x45250001, | ||
1766 | 0xc78, 0x44260001, | ||
1767 | 0xc78, 0x43270001, | ||
1768 | 0xc78, 0x42280001, | ||
1769 | 0xc78, 0x41290001, | ||
1770 | 0xc78, 0x402a0001, | ||
1771 | 0xc78, 0x262b0001, | ||
1772 | 0xc78, 0x252c0001, | ||
1773 | 0xc78, 0x242d0001, | ||
1774 | 0xc78, 0x232e0001, | ||
1775 | 0xc78, 0x222f0001, | ||
1776 | 0xc78, 0x21300001, | ||
1777 | 0xc78, 0x20310001, | ||
1778 | 0xc78, 0x06320001, | ||
1779 | 0xc78, 0x05330001, | ||
1780 | 0xc78, 0x04340001, | ||
1781 | 0xc78, 0x03350001, | ||
1782 | 0xc78, 0x02360001, | ||
1783 | 0xc78, 0x01370001, | ||
1784 | 0xc78, 0x00380001, | ||
1785 | 0xc78, 0x00390001, | ||
1786 | 0xc78, 0x003a0001, | ||
1787 | 0xc78, 0x003b0001, | ||
1788 | 0xc78, 0x003c0001, | ||
1789 | 0xc78, 0x003d0001, | ||
1790 | 0xc78, 0x003e0001, | ||
1791 | 0xc78, 0x003f0001, | ||
1792 | 0xc78, 0x7b400001, | ||
1793 | 0xc78, 0x7b410001, | ||
1794 | 0xc78, 0x7b420001, | ||
1795 | 0xc78, 0x7b430001, | ||
1796 | 0xc78, 0x7b440001, | ||
1797 | 0xc78, 0x7b450001, | ||
1798 | 0xc78, 0x7b460001, | ||
1799 | 0xc78, 0x7b470001, | ||
1800 | 0xc78, 0x7b480001, | ||
1801 | 0xc78, 0x7a490001, | ||
1802 | 0xc78, 0x794a0001, | ||
1803 | 0xc78, 0x784b0001, | ||
1804 | 0xc78, 0x774c0001, | ||
1805 | 0xc78, 0x764d0001, | ||
1806 | 0xc78, 0x754e0001, | ||
1807 | 0xc78, 0x744f0001, | ||
1808 | 0xc78, 0x73500001, | ||
1809 | 0xc78, 0x72510001, | ||
1810 | 0xc78, 0x71520001, | ||
1811 | 0xc78, 0x70530001, | ||
1812 | 0xc78, 0x6f540001, | ||
1813 | 0xc78, 0x6e550001, | ||
1814 | 0xc78, 0x6d560001, | ||
1815 | 0xc78, 0x6c570001, | ||
1816 | 0xc78, 0x6b580001, | ||
1817 | 0xc78, 0x6a590001, | ||
1818 | 0xc78, 0x695a0001, | ||
1819 | 0xc78, 0x685b0001, | ||
1820 | 0xc78, 0x675c0001, | ||
1821 | 0xc78, 0x665d0001, | ||
1822 | 0xc78, 0x655e0001, | ||
1823 | 0xc78, 0x645f0001, | ||
1824 | 0xc78, 0x63600001, | ||
1825 | 0xc78, 0x62610001, | ||
1826 | 0xc78, 0x61620001, | ||
1827 | 0xc78, 0x60630001, | ||
1828 | 0xc78, 0x46640001, | ||
1829 | 0xc78, 0x45650001, | ||
1830 | 0xc78, 0x44660001, | ||
1831 | 0xc78, 0x43670001, | ||
1832 | 0xc78, 0x42680001, | ||
1833 | 0xc78, 0x41690001, | ||
1834 | 0xc78, 0x406a0001, | ||
1835 | 0xc78, 0x266b0001, | ||
1836 | 0xc78, 0x256c0001, | ||
1837 | 0xc78, 0x246d0001, | ||
1838 | 0xc78, 0x236e0001, | ||
1839 | 0xc78, 0x226f0001, | ||
1840 | 0xc78, 0x21700001, | ||
1841 | 0xc78, 0x20710001, | ||
1842 | 0xc78, 0x06720001, | ||
1843 | 0xc78, 0x05730001, | ||
1844 | 0xc78, 0x04740001, | ||
1845 | 0xc78, 0x03750001, | ||
1846 | 0xc78, 0x02760001, | ||
1847 | 0xc78, 0x01770001, | ||
1848 | 0xc78, 0x00780001, | ||
1849 | 0xc78, 0x00790001, | ||
1850 | 0xc78, 0x007a0001, | ||
1851 | 0xc78, 0x007b0001, | ||
1852 | 0xc78, 0x007c0001, | ||
1853 | 0xc78, 0x007d0001, | ||
1854 | 0xc78, 0x007e0001, | ||
1855 | 0xc78, 0x007f0001, | ||
1856 | 0xc78, 0x3800001e, | ||
1857 | 0xc78, 0x3801001e, | ||
1858 | 0xc78, 0x3802001e, | ||
1859 | 0xc78, 0x3803001e, | ||
1860 | 0xc78, 0x3804001e, | ||
1861 | 0xc78, 0x3805001e, | ||
1862 | 0xc78, 0x3806001e, | ||
1863 | 0xc78, 0x3807001e, | ||
1864 | 0xc78, 0x3808001e, | ||
1865 | 0xc78, 0x3c09001e, | ||
1866 | 0xc78, 0x3e0a001e, | ||
1867 | 0xc78, 0x400b001e, | ||
1868 | 0xc78, 0x440c001e, | ||
1869 | 0xc78, 0x480d001e, | ||
1870 | 0xc78, 0x4c0e001e, | ||
1871 | 0xc78, 0x500f001e, | ||
1872 | 0xc78, 0x5210001e, | ||
1873 | 0xc78, 0x5611001e, | ||
1874 | 0xc78, 0x5a12001e, | ||
1875 | 0xc78, 0x5e13001e, | ||
1876 | 0xc78, 0x6014001e, | ||
1877 | 0xc78, 0x6015001e, | ||
1878 | 0xc78, 0x6016001e, | ||
1879 | 0xc78, 0x6217001e, | ||
1880 | 0xc78, 0x6218001e, | ||
1881 | 0xc78, 0x6219001e, | ||
1882 | 0xc78, 0x621a001e, | ||
1883 | 0xc78, 0x621b001e, | ||
1884 | 0xc78, 0x621c001e, | ||
1885 | 0xc78, 0x621d001e, | ||
1886 | 0xc78, 0x621e001e, | ||
1887 | 0xc78, 0x621f001e, | ||
1888 | }; | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/table.h b/drivers/net/wireless/rtlwifi/rtl8192cu/table.h new file mode 100644 index 000000000000..c3d5cd826cfa --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/table.h | |||
@@ -0,0 +1,71 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #ifndef __RTL92CU_TABLE__H_ | ||
31 | #define __RTL92CU_TABLE__H_ | ||
32 | |||
33 | #include <linux/types.h> | ||
34 | |||
35 | #define RTL8192CUPHY_REG_2TARRAY_LENGTH 374 | ||
36 | extern u32 RTL8192CUPHY_REG_2TARRAY[RTL8192CUPHY_REG_2TARRAY_LENGTH]; | ||
37 | #define RTL8192CUPHY_REG_1TARRAY_LENGTH 374 | ||
38 | extern u32 RTL8192CUPHY_REG_1TARRAY[RTL8192CUPHY_REG_1TARRAY_LENGTH]; | ||
39 | |||
40 | #define RTL8192CUPHY_REG_ARRAY_PGLENGTH 336 | ||
41 | extern u32 RTL8192CUPHY_REG_ARRAY_PG[RTL8192CUPHY_REG_ARRAY_PGLENGTH]; | ||
42 | |||
43 | #define RTL8192CURADIOA_2TARRAYLENGTH 282 | ||
44 | extern u32 RTL8192CURADIOA_2TARRAY[RTL8192CURADIOA_2TARRAYLENGTH]; | ||
45 | #define RTL8192CURADIOB_2TARRAYLENGTH 78 | ||
46 | extern u32 RTL8192CU_RADIOB_2TARRAY[RTL8192CURADIOB_2TARRAYLENGTH]; | ||
47 | #define RTL8192CURADIOA_1TARRAYLENGTH 282 | ||
48 | extern u32 RTL8192CU_RADIOA_1TARRAY[RTL8192CURADIOA_1TARRAYLENGTH]; | ||
49 | #define RTL8192CURADIOB_1TARRAYLENGTH 1 | ||
50 | extern u32 RTL8192CU_RADIOB_1TARRAY[RTL8192CURADIOB_1TARRAYLENGTH]; | ||
51 | |||
52 | #define RTL8192CUMAC_2T_ARRAYLENGTH 172 | ||
53 | extern u32 RTL8192CUMAC_2T_ARRAY[RTL8192CUMAC_2T_ARRAYLENGTH]; | ||
54 | |||
55 | #define RTL8192CUAGCTAB_2TARRAYLENGTH 320 | ||
56 | extern u32 RTL8192CUAGCTAB_2TARRAY[RTL8192CUAGCTAB_2TARRAYLENGTH]; | ||
57 | #define RTL8192CUAGCTAB_1TARRAYLENGTH 320 | ||
58 | extern u32 RTL8192CUAGCTAB_1TARRAY[RTL8192CUAGCTAB_1TARRAYLENGTH]; | ||
59 | |||
60 | #define RTL8192CUPHY_REG_1T_HPArrayLength 378 | ||
61 | extern u32 RTL8192CUPHY_REG_1T_HPArray[RTL8192CUPHY_REG_1T_HPArrayLength]; | ||
62 | |||
63 | #define RTL8192CUPHY_REG_Array_PG_HPLength 336 | ||
64 | extern u32 RTL8192CUPHY_REG_Array_PG_HP[RTL8192CUPHY_REG_Array_PG_HPLength]; | ||
65 | |||
66 | #define RTL8192CURadioA_1T_HPArrayLength 282 | ||
67 | extern u32 RTL8192CURadioA_1T_HPArray[RTL8192CURadioA_1T_HPArrayLength]; | ||
68 | #define RTL8192CUAGCTAB_1T_HPArrayLength 320 | ||
69 | extern u32 Rtl8192CUAGCTAB_1T_HPArray[RTL8192CUAGCTAB_1T_HPArrayLength]; | ||
70 | |||
71 | #endif | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c new file mode 100644 index 000000000000..9855c3e0a4b2 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | |||
@@ -0,0 +1,684 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #include "../wifi.h" | ||
31 | #include "../usb.h" | ||
32 | #include "../ps.h" | ||
33 | #include "../base.h" | ||
34 | #include "reg.h" | ||
35 | #include "def.h" | ||
36 | #include "phy.h" | ||
37 | #include "rf.h" | ||
38 | #include "dm.h" | ||
39 | #include "mac.h" | ||
40 | #include "trx.h" | ||
41 | |||
42 | static int _ConfigVerTOutEP(struct ieee80211_hw *hw) | ||
43 | { | ||
44 | u8 ep_cfg, txqsele; | ||
45 | u8 ep_nums = 0; | ||
46 | |||
47 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
48 | struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw); | ||
49 | struct rtl_usb *rtlusb = rtl_usbdev(usb_priv); | ||
50 | |||
51 | rtlusb->out_queue_sel = 0; | ||
52 | ep_cfg = rtl_read_byte(rtlpriv, REG_TEST_SIE_OPTIONAL); | ||
53 | ep_cfg = (ep_cfg & USB_TEST_EP_MASK) >> USB_TEST_EP_SHIFT; | ||
54 | switch (ep_cfg) { | ||
55 | case 0: /* 2 bulk OUT, 1 bulk IN */ | ||
56 | case 3: | ||
57 | rtlusb->out_queue_sel = TX_SELE_HQ | TX_SELE_LQ; | ||
58 | ep_nums = 2; | ||
59 | break; | ||
60 | case 1: /* 1 bulk IN/OUT => map all endpoint to Low queue */ | ||
61 | case 2: /* 1 bulk IN, 1 bulk OUT => map all endpoint to High queue */ | ||
62 | txqsele = rtl_read_byte(rtlpriv, REG_TEST_USB_TXQS); | ||
63 | if (txqsele & 0x0F) /* /map all endpoint to High queue */ | ||
64 | rtlusb->out_queue_sel = TX_SELE_HQ; | ||
65 | else if (txqsele&0xF0) /* map all endpoint to Low queue */ | ||
66 | rtlusb->out_queue_sel = TX_SELE_LQ; | ||
67 | ep_nums = 1; | ||
68 | break; | ||
69 | default: | ||
70 | break; | ||
71 | } | ||
72 | return (rtlusb->out_ep_nums == ep_nums) ? 0 : -EINVAL; | ||
73 | } | ||
74 | |||
75 | static int _ConfigVerNOutEP(struct ieee80211_hw *hw) | ||
76 | { | ||
77 | u8 ep_cfg; | ||
78 | u8 ep_nums = 0; | ||
79 | |||
80 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
81 | struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw); | ||
82 | struct rtl_usb *rtlusb = rtl_usbdev(usb_priv); | ||
83 | |||
84 | rtlusb->out_queue_sel = 0; | ||
85 | /* Normal and High queue */ | ||
86 | ep_cfg = rtl_read_byte(rtlpriv, (REG_NORMAL_SIE_EP + 1)); | ||
87 | if (ep_cfg & USB_NORMAL_SIE_EP_MASK) { | ||
88 | rtlusb->out_queue_sel |= TX_SELE_HQ; | ||
89 | ep_nums++; | ||
90 | } | ||
91 | if ((ep_cfg >> USB_NORMAL_SIE_EP_SHIFT) & USB_NORMAL_SIE_EP_MASK) { | ||
92 | rtlusb->out_queue_sel |= TX_SELE_NQ; | ||
93 | ep_nums++; | ||
94 | } | ||
95 | /* Low queue */ | ||
96 | ep_cfg = rtl_read_byte(rtlpriv, (REG_NORMAL_SIE_EP + 2)); | ||
97 | if (ep_cfg & USB_NORMAL_SIE_EP_MASK) { | ||
98 | rtlusb->out_queue_sel |= TX_SELE_LQ; | ||
99 | ep_nums++; | ||
100 | } | ||
101 | return (rtlusb->out_ep_nums == ep_nums) ? 0 : -EINVAL; | ||
102 | } | ||
103 | |||
104 | static void _TwoOutEpMapping(struct ieee80211_hw *hw, bool bIsChipB, | ||
105 | bool bwificfg, struct rtl_ep_map *ep_map) | ||
106 | { | ||
107 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
108 | |||
109 | if (bwificfg) { /* for WMM */ | ||
110 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
111 | ("USB Chip-B & WMM Setting.....\n")); | ||
112 | ep_map->ep_mapping[RTL_TXQ_BE] = 2; | ||
113 | ep_map->ep_mapping[RTL_TXQ_BK] = 3; | ||
114 | ep_map->ep_mapping[RTL_TXQ_VI] = 3; | ||
115 | ep_map->ep_mapping[RTL_TXQ_VO] = 2; | ||
116 | ep_map->ep_mapping[RTL_TXQ_MGT] = 2; | ||
117 | ep_map->ep_mapping[RTL_TXQ_BCN] = 2; | ||
118 | ep_map->ep_mapping[RTL_TXQ_HI] = 2; | ||
119 | } else { /* typical setting */ | ||
120 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
121 | ("USB typical Setting.....\n")); | ||
122 | ep_map->ep_mapping[RTL_TXQ_BE] = 3; | ||
123 | ep_map->ep_mapping[RTL_TXQ_BK] = 3; | ||
124 | ep_map->ep_mapping[RTL_TXQ_VI] = 2; | ||
125 | ep_map->ep_mapping[RTL_TXQ_VO] = 2; | ||
126 | ep_map->ep_mapping[RTL_TXQ_MGT] = 2; | ||
127 | ep_map->ep_mapping[RTL_TXQ_BCN] = 2; | ||
128 | ep_map->ep_mapping[RTL_TXQ_HI] = 2; | ||
129 | } | ||
130 | } | ||
131 | |||
132 | static void _ThreeOutEpMapping(struct ieee80211_hw *hw, bool bwificfg, | ||
133 | struct rtl_ep_map *ep_map) | ||
134 | { | ||
135 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
136 | if (bwificfg) { /* for WMM */ | ||
137 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
138 | ("USB 3EP Setting for WMM.....\n")); | ||
139 | ep_map->ep_mapping[RTL_TXQ_BE] = 5; | ||
140 | ep_map->ep_mapping[RTL_TXQ_BK] = 3; | ||
141 | ep_map->ep_mapping[RTL_TXQ_VI] = 3; | ||
142 | ep_map->ep_mapping[RTL_TXQ_VO] = 2; | ||
143 | ep_map->ep_mapping[RTL_TXQ_MGT] = 2; | ||
144 | ep_map->ep_mapping[RTL_TXQ_BCN] = 2; | ||
145 | ep_map->ep_mapping[RTL_TXQ_HI] = 2; | ||
146 | } else { /* typical setting */ | ||
147 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
148 | ("USB 3EP Setting for typical.....\n")); | ||
149 | ep_map->ep_mapping[RTL_TXQ_BE] = 5; | ||
150 | ep_map->ep_mapping[RTL_TXQ_BK] = 5; | ||
151 | ep_map->ep_mapping[RTL_TXQ_VI] = 3; | ||
152 | ep_map->ep_mapping[RTL_TXQ_VO] = 2; | ||
153 | ep_map->ep_mapping[RTL_TXQ_MGT] = 2; | ||
154 | ep_map->ep_mapping[RTL_TXQ_BCN] = 2; | ||
155 | ep_map->ep_mapping[RTL_TXQ_HI] = 2; | ||
156 | } | ||
157 | } | ||
158 | |||
159 | static void _OneOutEpMapping(struct ieee80211_hw *hw, struct rtl_ep_map *ep_map) | ||
160 | { | ||
161 | ep_map->ep_mapping[RTL_TXQ_BE] = 2; | ||
162 | ep_map->ep_mapping[RTL_TXQ_BK] = 2; | ||
163 | ep_map->ep_mapping[RTL_TXQ_VI] = 2; | ||
164 | ep_map->ep_mapping[RTL_TXQ_VO] = 2; | ||
165 | ep_map->ep_mapping[RTL_TXQ_MGT] = 2; | ||
166 | ep_map->ep_mapping[RTL_TXQ_BCN] = 2; | ||
167 | ep_map->ep_mapping[RTL_TXQ_HI] = 2; | ||
168 | } | ||
169 | static int _out_ep_mapping(struct ieee80211_hw *hw) | ||
170 | { | ||
171 | int err = 0; | ||
172 | bool bIsChipN, bwificfg = false; | ||
173 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
174 | struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw); | ||
175 | struct rtl_usb *rtlusb = rtl_usbdev(usb_priv); | ||
176 | struct rtl_ep_map *ep_map = &(rtlusb->ep_map); | ||
177 | |||
178 | bIsChipN = IS_NORMAL_CHIP(rtlhal->version); | ||
179 | switch (rtlusb->out_ep_nums) { | ||
180 | case 2: | ||
181 | _TwoOutEpMapping(hw, bIsChipN, bwificfg, ep_map); | ||
182 | break; | ||
183 | case 3: | ||
184 | /* Test chip doesn't support three out EPs. */ | ||
185 | if (!bIsChipN) { | ||
186 | err = -EINVAL; | ||
187 | goto err_out; | ||
188 | } | ||
189 | _ThreeOutEpMapping(hw, bIsChipN, ep_map); | ||
190 | break; | ||
191 | case 1: | ||
192 | _OneOutEpMapping(hw, ep_map); | ||
193 | break; | ||
194 | default: | ||
195 | err = -EINVAL; | ||
196 | break; | ||
197 | } | ||
198 | err_out: | ||
199 | return err; | ||
200 | |||
201 | } | ||
202 | /* endpoint mapping */ | ||
203 | int rtl8192cu_endpoint_mapping(struct ieee80211_hw *hw) | ||
204 | { | ||
205 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
206 | int error = 0; | ||
207 | if (likely(IS_NORMAL_CHIP(rtlhal->version))) | ||
208 | error = _ConfigVerNOutEP(hw); | ||
209 | else | ||
210 | error = _ConfigVerTOutEP(hw); | ||
211 | if (error) | ||
212 | goto err_out; | ||
213 | error = _out_ep_mapping(hw); | ||
214 | if (error) | ||
215 | goto err_out; | ||
216 | err_out: | ||
217 | return error; | ||
218 | } | ||
219 | |||
220 | u16 rtl8192cu_mq_to_hwq(__le16 fc, u16 mac80211_queue_index) | ||
221 | { | ||
222 | u16 hw_queue_index; | ||
223 | |||
224 | if (unlikely(ieee80211_is_beacon(fc))) { | ||
225 | hw_queue_index = RTL_TXQ_BCN; | ||
226 | goto out; | ||
227 | } | ||
228 | if (ieee80211_is_mgmt(fc)) { | ||
229 | hw_queue_index = RTL_TXQ_MGT; | ||
230 | goto out; | ||
231 | } | ||
232 | switch (mac80211_queue_index) { | ||
233 | case 0: | ||
234 | hw_queue_index = RTL_TXQ_VO; | ||
235 | break; | ||
236 | case 1: | ||
237 | hw_queue_index = RTL_TXQ_VI; | ||
238 | break; | ||
239 | case 2: | ||
240 | hw_queue_index = RTL_TXQ_BE; | ||
241 | break; | ||
242 | case 3: | ||
243 | hw_queue_index = RTL_TXQ_BK; | ||
244 | break; | ||
245 | default: | ||
246 | hw_queue_index = RTL_TXQ_BE; | ||
247 | RT_ASSERT(false, ("QSLT_BE queue, skb_queue:%d\n", | ||
248 | mac80211_queue_index)); | ||
249 | break; | ||
250 | } | ||
251 | out: | ||
252 | return hw_queue_index; | ||
253 | } | ||
254 | |||
255 | static enum rtl_desc_qsel _rtl8192cu_mq_to_descq(struct ieee80211_hw *hw, | ||
256 | __le16 fc, u16 mac80211_queue_index) | ||
257 | { | ||
258 | enum rtl_desc_qsel qsel; | ||
259 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
260 | |||
261 | if (unlikely(ieee80211_is_beacon(fc))) { | ||
262 | qsel = QSLT_BEACON; | ||
263 | goto out; | ||
264 | } | ||
265 | if (ieee80211_is_mgmt(fc)) { | ||
266 | qsel = QSLT_MGNT; | ||
267 | goto out; | ||
268 | } | ||
269 | switch (mac80211_queue_index) { | ||
270 | case 0: /* VO */ | ||
271 | qsel = QSLT_VO; | ||
272 | RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG, | ||
273 | ("VO queue, set qsel = 0x%x\n", QSLT_VO)); | ||
274 | break; | ||
275 | case 1: /* VI */ | ||
276 | qsel = QSLT_VI; | ||
277 | RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG, | ||
278 | ("VI queue, set qsel = 0x%x\n", QSLT_VI)); | ||
279 | break; | ||
280 | case 3: /* BK */ | ||
281 | qsel = QSLT_BK; | ||
282 | RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG, | ||
283 | ("BK queue, set qsel = 0x%x\n", QSLT_BK)); | ||
284 | break; | ||
285 | case 2: /* BE */ | ||
286 | default: | ||
287 | qsel = QSLT_BE; | ||
288 | RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG, | ||
289 | ("BE queue, set qsel = 0x%x\n", QSLT_BE)); | ||
290 | break; | ||
291 | } | ||
292 | out: | ||
293 | return qsel; | ||
294 | } | ||
295 | |||
296 | /* =============================================================== */ | ||
297 | |||
298 | /*---------------------------------------------------------------------- | ||
299 | * | ||
300 | * Rx handler | ||
301 | * | ||
302 | *---------------------------------------------------------------------- */ | ||
303 | bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw, | ||
304 | struct rtl_stats *stats, | ||
305 | struct ieee80211_rx_status *rx_status, | ||
306 | u8 *p_desc, struct sk_buff *skb) | ||
307 | { | ||
308 | struct rx_fwinfo_92c *p_drvinfo; | ||
309 | struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc; | ||
310 | u32 phystatus = GET_RX_DESC_PHY_STATUS(pdesc); | ||
311 | |||
312 | stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc); | ||
313 | stats->rx_drvinfo_size = (u8)GET_RX_DESC_DRVINFO_SIZE(pdesc) * | ||
314 | RX_DRV_INFO_SIZE_UNIT; | ||
315 | stats->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03); | ||
316 | stats->icv = (u16) GET_RX_DESC_ICV(pdesc); | ||
317 | stats->crc = (u16) GET_RX_DESC_CRC32(pdesc); | ||
318 | stats->hwerror = (stats->crc | stats->icv); | ||
319 | stats->decrypted = !GET_RX_DESC_SWDEC(pdesc); | ||
320 | stats->rate = (u8) GET_RX_DESC_RX_MCS(pdesc); | ||
321 | stats->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc); | ||
322 | stats->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1); | ||
323 | stats->isampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1) | ||
324 | && (GET_RX_DESC_FAGGR(pdesc) == 1)); | ||
325 | stats->timestamp_low = GET_RX_DESC_TSFL(pdesc); | ||
326 | stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc); | ||
327 | rx_status->freq = hw->conf.channel->center_freq; | ||
328 | rx_status->band = hw->conf.channel->band; | ||
329 | if (GET_RX_DESC_CRC32(pdesc)) | ||
330 | rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; | ||
331 | if (!GET_RX_DESC_SWDEC(pdesc)) | ||
332 | rx_status->flag |= RX_FLAG_DECRYPTED; | ||
333 | if (GET_RX_DESC_BW(pdesc)) | ||
334 | rx_status->flag |= RX_FLAG_40MHZ; | ||
335 | if (GET_RX_DESC_RX_HT(pdesc)) | ||
336 | rx_status->flag |= RX_FLAG_HT; | ||
337 | rx_status->flag |= RX_FLAG_TSFT; | ||
338 | if (stats->decrypted) | ||
339 | rx_status->flag |= RX_FLAG_DECRYPTED; | ||
340 | rx_status->rate_idx = _rtl92c_rate_mapping(hw, | ||
341 | (bool)GET_RX_DESC_RX_HT(pdesc), | ||
342 | (u8)GET_RX_DESC_RX_MCS(pdesc), | ||
343 | (bool)GET_RX_DESC_PAGGR(pdesc)); | ||
344 | rx_status->mactime = GET_RX_DESC_TSFL(pdesc); | ||
345 | if (phystatus == true) { | ||
346 | p_drvinfo = (struct rx_fwinfo_92c *)(pdesc + RTL_RX_DESC_SIZE); | ||
347 | rtl92c_translate_rx_signal_stuff(hw, skb, stats, pdesc, | ||
348 | p_drvinfo); | ||
349 | } | ||
350 | /*rx_status->qual = stats->signal; */ | ||
351 | rx_status->signal = stats->rssi + 10; | ||
352 | /*rx_status->noise = -stats->noise; */ | ||
353 | return true; | ||
354 | } | ||
355 | |||
356 | #define RTL_RX_DRV_INFO_UNIT 8 | ||
357 | |||
358 | static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
359 | { | ||
360 | struct ieee80211_rx_status *rx_status = | ||
361 | (struct ieee80211_rx_status *)IEEE80211_SKB_RXCB(skb); | ||
362 | u32 skb_len, pkt_len, drvinfo_len; | ||
363 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
364 | u8 *rxdesc; | ||
365 | struct rtl_stats stats = { | ||
366 | .signal = 0, | ||
367 | .noise = -98, | ||
368 | .rate = 0, | ||
369 | }; | ||
370 | struct rx_fwinfo_92c *p_drvinfo; | ||
371 | bool bv; | ||
372 | __le16 fc; | ||
373 | struct ieee80211_hdr *hdr; | ||
374 | |||
375 | memset(rx_status, 0, sizeof(rx_status)); | ||
376 | rxdesc = skb->data; | ||
377 | skb_len = skb->len; | ||
378 | drvinfo_len = (GET_RX_DESC_DRVINFO_SIZE(rxdesc) * RTL_RX_DRV_INFO_UNIT); | ||
379 | pkt_len = GET_RX_DESC_PKT_LEN(rxdesc); | ||
380 | /* TODO: Error recovery. drop this skb or something. */ | ||
381 | WARN_ON(skb_len < (pkt_len + RTL_RX_DESC_SIZE + drvinfo_len)); | ||
382 | stats.length = (u16) GET_RX_DESC_PKT_LEN(rxdesc); | ||
383 | stats.rx_drvinfo_size = (u8)GET_RX_DESC_DRVINFO_SIZE(rxdesc) * | ||
384 | RX_DRV_INFO_SIZE_UNIT; | ||
385 | stats.rx_bufshift = (u8) (GET_RX_DESC_SHIFT(rxdesc) & 0x03); | ||
386 | stats.icv = (u16) GET_RX_DESC_ICV(rxdesc); | ||
387 | stats.crc = (u16) GET_RX_DESC_CRC32(rxdesc); | ||
388 | stats.hwerror = (stats.crc | stats.icv); | ||
389 | stats.decrypted = !GET_RX_DESC_SWDEC(rxdesc); | ||
390 | stats.rate = (u8) GET_RX_DESC_RX_MCS(rxdesc); | ||
391 | stats.shortpreamble = (u16) GET_RX_DESC_SPLCP(rxdesc); | ||
392 | stats.isampdu = (bool) ((GET_RX_DESC_PAGGR(rxdesc) == 1) | ||
393 | && (GET_RX_DESC_FAGGR(rxdesc) == 1)); | ||
394 | stats.timestamp_low = GET_RX_DESC_TSFL(rxdesc); | ||
395 | stats.rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(rxdesc); | ||
396 | /* TODO: is center_freq changed when doing scan? */ | ||
397 | /* TODO: Shall we add protection or just skip those two step? */ | ||
398 | rx_status->freq = hw->conf.channel->center_freq; | ||
399 | rx_status->band = hw->conf.channel->band; | ||
400 | if (GET_RX_DESC_CRC32(rxdesc)) | ||
401 | rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; | ||
402 | if (!GET_RX_DESC_SWDEC(rxdesc)) | ||
403 | rx_status->flag |= RX_FLAG_DECRYPTED; | ||
404 | if (GET_RX_DESC_BW(rxdesc)) | ||
405 | rx_status->flag |= RX_FLAG_40MHZ; | ||
406 | if (GET_RX_DESC_RX_HT(rxdesc)) | ||
407 | rx_status->flag |= RX_FLAG_HT; | ||
408 | /* Data rate */ | ||
409 | rx_status->rate_idx = _rtl92c_rate_mapping(hw, | ||
410 | (bool)GET_RX_DESC_RX_HT(rxdesc), | ||
411 | (u8)GET_RX_DESC_RX_MCS(rxdesc), | ||
412 | (bool)GET_RX_DESC_PAGGR(rxdesc) | ||
413 | ); | ||
414 | /* There is a phy status after this rx descriptor. */ | ||
415 | if (GET_RX_DESC_PHY_STATUS(rxdesc)) { | ||
416 | p_drvinfo = (struct rx_fwinfo_92c *)(rxdesc + RTL_RX_DESC_SIZE); | ||
417 | rtl92c_translate_rx_signal_stuff(hw, skb, &stats, | ||
418 | (struct rx_desc_92c *)rxdesc, p_drvinfo); | ||
419 | } | ||
420 | skb_pull(skb, (drvinfo_len + RTL_RX_DESC_SIZE)); | ||
421 | hdr = (struct ieee80211_hdr *)(skb->data); | ||
422 | fc = hdr->frame_control; | ||
423 | bv = ieee80211_is_probe_resp(fc); | ||
424 | if (bv) | ||
425 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
426 | ("Got probe response frame.\n")); | ||
427 | if (ieee80211_is_beacon(fc)) | ||
428 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
429 | ("Got beacon frame.\n")); | ||
430 | if (ieee80211_is_data(fc)) | ||
431 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Got data frame.\n")); | ||
432 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
433 | ("Fram: fc = 0x%X addr1 = 0x%02X:0x%02X:0x%02X:0x%02X:0x%02X:" | ||
434 | "0x%02X\n", fc, (u32)hdr->addr1[0], (u32)hdr->addr1[1], | ||
435 | (u32)hdr->addr1[2], (u32)hdr->addr1[3], (u32)hdr->addr1[4], | ||
436 | (u32)hdr->addr1[5])); | ||
437 | memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); | ||
438 | ieee80211_rx_irqsafe(hw, skb); | ||
439 | } | ||
440 | |||
441 | void rtl8192cu_rx_hdl(struct ieee80211_hw *hw, struct sk_buff * skb) | ||
442 | { | ||
443 | _rtl_rx_process(hw, skb); | ||
444 | } | ||
445 | |||
446 | void rtl8192c_rx_segregate_hdl( | ||
447 | struct ieee80211_hw *hw, | ||
448 | struct sk_buff *skb, | ||
449 | struct sk_buff_head *skb_list) | ||
450 | { | ||
451 | } | ||
452 | |||
453 | /*---------------------------------------------------------------------- | ||
454 | * | ||
455 | * Tx handler | ||
456 | * | ||
457 | *---------------------------------------------------------------------- */ | ||
458 | void rtl8192c_tx_cleanup(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
459 | { | ||
460 | } | ||
461 | |||
462 | int rtl8192c_tx_post_hdl(struct ieee80211_hw *hw, struct urb *urb, | ||
463 | struct sk_buff *skb) | ||
464 | { | ||
465 | return 0; | ||
466 | } | ||
467 | |||
468 | struct sk_buff *rtl8192c_tx_aggregate_hdl(struct ieee80211_hw *hw, | ||
469 | struct sk_buff_head *list) | ||
470 | { | ||
471 | return skb_dequeue(list); | ||
472 | } | ||
473 | |||
474 | /*======================================== trx ===============================*/ | ||
475 | |||
476 | static void _rtl_fill_usb_tx_desc(u8 *txdesc) | ||
477 | { | ||
478 | SET_TX_DESC_OWN(txdesc, 1); | ||
479 | SET_TX_DESC_LAST_SEG(txdesc, 1); | ||
480 | SET_TX_DESC_FIRST_SEG(txdesc, 1); | ||
481 | } | ||
482 | /** | ||
483 | * For HW recovery information | ||
484 | */ | ||
485 | static void _rtl_tx_desc_checksum(u8 *txdesc) | ||
486 | { | ||
487 | u16 *ptr = (u16 *)txdesc; | ||
488 | u16 checksum = 0; | ||
489 | u32 index; | ||
490 | |||
491 | /* Clear first */ | ||
492 | SET_TX_DESC_TX_DESC_CHECKSUM(txdesc, 0); | ||
493 | for (index = 0; index < 16; index++) | ||
494 | checksum = checksum ^ (*(ptr + index)); | ||
495 | SET_TX_DESC_TX_DESC_CHECKSUM(txdesc, checksum); | ||
496 | } | ||
497 | |||
498 | void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, | ||
499 | struct ieee80211_hdr *hdr, u8 *pdesc_tx, | ||
500 | struct ieee80211_tx_info *info, struct sk_buff *skb, | ||
501 | unsigned int queue_index) | ||
502 | { | ||
503 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
504 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
505 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
506 | bool defaultadapter = true; | ||
507 | struct ieee80211_sta *sta = ieee80211_find_sta(mac->vif, mac->bssid); | ||
508 | struct rtl_tcb_desc tcb_desc; | ||
509 | u8 *qc = ieee80211_get_qos_ctl(hdr); | ||
510 | u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; | ||
511 | u16 seq_number; | ||
512 | __le16 fc = hdr->frame_control; | ||
513 | u8 rate_flag = info->control.rates[0].flags; | ||
514 | u16 pktlen = skb->len; | ||
515 | enum rtl_desc_qsel fw_qsel = _rtl8192cu_mq_to_descq(hw, fc, | ||
516 | skb_get_queue_mapping(skb)); | ||
517 | u8 *txdesc; | ||
518 | |||
519 | seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; | ||
520 | rtl_get_tcb_desc(hw, info, skb, &tcb_desc); | ||
521 | txdesc = (u8 *)skb_push(skb, RTL_TX_HEADER_SIZE); | ||
522 | memset(txdesc, 0, RTL_TX_HEADER_SIZE); | ||
523 | SET_TX_DESC_PKT_SIZE(txdesc, pktlen); | ||
524 | SET_TX_DESC_LINIP(txdesc, 0); | ||
525 | SET_TX_DESC_PKT_OFFSET(txdesc, RTL_DUMMY_OFFSET); | ||
526 | SET_TX_DESC_OFFSET(txdesc, RTL_TX_HEADER_SIZE); | ||
527 | SET_TX_DESC_TX_RATE(txdesc, tcb_desc.hw_rate); | ||
528 | if (tcb_desc.use_shortgi || tcb_desc.use_shortpreamble) | ||
529 | SET_TX_DESC_DATA_SHORTGI(txdesc, 1); | ||
530 | if (mac->tids[tid].agg.agg_state == RTL_AGG_ON && | ||
531 | info->flags & IEEE80211_TX_CTL_AMPDU) { | ||
532 | SET_TX_DESC_AGG_ENABLE(txdesc, 1); | ||
533 | SET_TX_DESC_MAX_AGG_NUM(txdesc, 0x14); | ||
534 | } else { | ||
535 | SET_TX_DESC_AGG_BREAK(txdesc, 1); | ||
536 | } | ||
537 | SET_TX_DESC_SEQ(txdesc, seq_number); | ||
538 | SET_TX_DESC_RTS_ENABLE(txdesc, ((tcb_desc.rts_enable && | ||
539 | !tcb_desc.cts_enable) ? 1 : 0)); | ||
540 | SET_TX_DESC_HW_RTS_ENABLE(txdesc, ((tcb_desc.rts_enable || | ||
541 | tcb_desc.cts_enable) ? 1 : 0)); | ||
542 | SET_TX_DESC_CTS2SELF(txdesc, ((tcb_desc.cts_enable) ? 1 : 0)); | ||
543 | SET_TX_DESC_RTS_STBC(txdesc, ((tcb_desc.rts_stbc) ? 1 : 0)); | ||
544 | SET_TX_DESC_RTS_RATE(txdesc, tcb_desc.rts_rate); | ||
545 | SET_TX_DESC_RTS_BW(txdesc, 0); | ||
546 | SET_TX_DESC_RTS_SC(txdesc, tcb_desc.rts_sc); | ||
547 | SET_TX_DESC_RTS_SHORT(txdesc, | ||
548 | ((tcb_desc.rts_rate <= DESC92C_RATE54M) ? | ||
549 | (tcb_desc.rts_use_shortpreamble ? 1 : 0) | ||
550 | : (tcb_desc.rts_use_shortgi ? 1 : 0))); | ||
551 | if (mac->bw_40) { | ||
552 | if (tcb_desc.packet_bw) { | ||
553 | SET_TX_DESC_DATA_BW(txdesc, 1); | ||
554 | SET_TX_DESC_DATA_SC(txdesc, 3); | ||
555 | } else { | ||
556 | SET_TX_DESC_DATA_BW(txdesc, 0); | ||
557 | if (rate_flag & IEEE80211_TX_RC_DUP_DATA) | ||
558 | SET_TX_DESC_DATA_SC(txdesc, | ||
559 | mac->cur_40_prime_sc); | ||
560 | } | ||
561 | } else { | ||
562 | SET_TX_DESC_DATA_BW(txdesc, 0); | ||
563 | SET_TX_DESC_DATA_SC(txdesc, 0); | ||
564 | } | ||
565 | if (sta) { | ||
566 | u8 ampdu_density = sta->ht_cap.ampdu_density; | ||
567 | SET_TX_DESC_AMPDU_DENSITY(txdesc, ampdu_density); | ||
568 | } | ||
569 | if (info->control.hw_key) { | ||
570 | struct ieee80211_key_conf *keyconf = info->control.hw_key; | ||
571 | switch (keyconf->cipher) { | ||
572 | case WLAN_CIPHER_SUITE_WEP40: | ||
573 | case WLAN_CIPHER_SUITE_WEP104: | ||
574 | case WLAN_CIPHER_SUITE_TKIP: | ||
575 | SET_TX_DESC_SEC_TYPE(txdesc, 0x1); | ||
576 | break; | ||
577 | case WLAN_CIPHER_SUITE_CCMP: | ||
578 | SET_TX_DESC_SEC_TYPE(txdesc, 0x3); | ||
579 | break; | ||
580 | default: | ||
581 | SET_TX_DESC_SEC_TYPE(txdesc, 0x0); | ||
582 | break; | ||
583 | } | ||
584 | } | ||
585 | SET_TX_DESC_PKT_ID(txdesc, 0); | ||
586 | SET_TX_DESC_QUEUE_SEL(txdesc, fw_qsel); | ||
587 | SET_TX_DESC_DATA_RATE_FB_LIMIT(txdesc, 0x1F); | ||
588 | SET_TX_DESC_RTS_RATE_FB_LIMIT(txdesc, 0xF); | ||
589 | SET_TX_DESC_DISABLE_FB(txdesc, 0); | ||
590 | SET_TX_DESC_USE_RATE(txdesc, tcb_desc.use_driver_rate ? 1 : 0); | ||
591 | if (ieee80211_is_data_qos(fc)) { | ||
592 | if (mac->rdg_en) { | ||
593 | RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, | ||
594 | ("Enable RDG function.\n")); | ||
595 | SET_TX_DESC_RDG_ENABLE(txdesc, 1); | ||
596 | SET_TX_DESC_HTC(txdesc, 1); | ||
597 | } | ||
598 | } | ||
599 | if (rtlpriv->dm.useramask) { | ||
600 | SET_TX_DESC_RATE_ID(txdesc, tcb_desc.ratr_index); | ||
601 | SET_TX_DESC_MACID(txdesc, tcb_desc.mac_id); | ||
602 | } else { | ||
603 | SET_TX_DESC_RATE_ID(txdesc, 0xC + tcb_desc.ratr_index); | ||
604 | SET_TX_DESC_MACID(txdesc, tcb_desc.ratr_index); | ||
605 | } | ||
606 | if ((!ieee80211_is_data_qos(fc)) && ppsc->leisure_ps && | ||
607 | ppsc->fwctrl_lps) { | ||
608 | SET_TX_DESC_HWSEQ_EN(txdesc, 1); | ||
609 | SET_TX_DESC_PKT_ID(txdesc, 8); | ||
610 | if (!defaultadapter) | ||
611 | SET_TX_DESC_QOS(txdesc, 1); | ||
612 | } | ||
613 | if (ieee80211_has_morefrags(fc)) | ||
614 | SET_TX_DESC_MORE_FRAG(txdesc, 1); | ||
615 | if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) || | ||
616 | is_broadcast_ether_addr(ieee80211_get_DA(hdr))) | ||
617 | SET_TX_DESC_BMC(txdesc, 1); | ||
618 | _rtl_fill_usb_tx_desc(txdesc); | ||
619 | _rtl_tx_desc_checksum(txdesc); | ||
620 | RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, (" %s ==>\n", __func__)); | ||
621 | } | ||
622 | |||
623 | void rtl92cu_fill_fake_txdesc(struct ieee80211_hw *hw, u8 * pDesc, | ||
624 | u32 buffer_len, bool bIsPsPoll) | ||
625 | { | ||
626 | /* Clear all status */ | ||
627 | memset(pDesc, 0, RTL_TX_HEADER_SIZE); | ||
628 | SET_TX_DESC_FIRST_SEG(pDesc, 1); /* bFirstSeg; */ | ||
629 | SET_TX_DESC_LAST_SEG(pDesc, 1); /* bLastSeg; */ | ||
630 | SET_TX_DESC_OFFSET(pDesc, RTL_TX_HEADER_SIZE); /* Offset = 32 */ | ||
631 | SET_TX_DESC_PKT_SIZE(pDesc, buffer_len); /* Buffer size + command hdr */ | ||
632 | SET_TX_DESC_QUEUE_SEL(pDesc, QSLT_MGNT); /* Fixed queue of Mgnt queue */ | ||
633 | /* Set NAVUSEHDR to prevent Ps-poll AId filed to be changed to error | ||
634 | * vlaue by Hw. */ | ||
635 | if (bIsPsPoll) { | ||
636 | SET_TX_DESC_NAV_USE_HDR(pDesc, 1); | ||
637 | } else { | ||
638 | SET_TX_DESC_HWSEQ_EN(pDesc, 1); /* Hw set sequence number */ | ||
639 | SET_TX_DESC_PKT_ID(pDesc, 0x100); /* set bit3 to 1. */ | ||
640 | } | ||
641 | SET_TX_DESC_USE_RATE(pDesc, 1); /* use data rate which is set by Sw */ | ||
642 | SET_TX_DESC_OWN(pDesc, 1); | ||
643 | SET_TX_DESC_TX_RATE(pDesc, DESC92C_RATE1M); | ||
644 | _rtl_tx_desc_checksum(pDesc); | ||
645 | } | ||
646 | |||
647 | void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw, | ||
648 | u8 *pdesc, bool firstseg, | ||
649 | bool lastseg, struct sk_buff *skb) | ||
650 | { | ||
651 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
652 | u8 fw_queue = QSLT_BEACON; | ||
653 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); | ||
654 | __le16 fc = hdr->frame_control; | ||
655 | |||
656 | memset((void *)pdesc, 0, RTL_TX_HEADER_SIZE); | ||
657 | if (firstseg) | ||
658 | SET_TX_DESC_OFFSET(pdesc, RTL_TX_HEADER_SIZE); | ||
659 | SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M); | ||
660 | SET_TX_DESC_SEQ(pdesc, 0); | ||
661 | SET_TX_DESC_LINIP(pdesc, 0); | ||
662 | SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue); | ||
663 | SET_TX_DESC_FIRST_SEG(pdesc, 1); | ||
664 | SET_TX_DESC_LAST_SEG(pdesc, 1); | ||
665 | SET_TX_DESC_RATE_ID(pdesc, 7); | ||
666 | SET_TX_DESC_MACID(pdesc, 0); | ||
667 | SET_TX_DESC_OWN(pdesc, 1); | ||
668 | SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len)); | ||
669 | SET_TX_DESC_FIRST_SEG(pdesc, 1); | ||
670 | SET_TX_DESC_LAST_SEG(pdesc, 1); | ||
671 | SET_TX_DESC_OFFSET(pdesc, 0x20); | ||
672 | SET_TX_DESC_USE_RATE(pdesc, 1); | ||
673 | if (!ieee80211_is_data_qos(fc)) { | ||
674 | SET_TX_DESC_HWSEQ_EN(pdesc, 1); | ||
675 | SET_TX_DESC_PKT_ID(pdesc, 8); | ||
676 | } | ||
677 | RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, "H2C Tx Cmd Content\n", | ||
678 | pdesc, RTL_TX_DESC_SIZE); | ||
679 | } | ||
680 | |||
681 | bool rtl92cu_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
682 | { | ||
683 | return true; | ||
684 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h new file mode 100644 index 000000000000..b396d46edbb7 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h | |||
@@ -0,0 +1,430 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #ifndef __RTL92CU_TRX_H__ | ||
31 | #define __RTL92CU_TRX_H__ | ||
32 | |||
33 | #define RTL92C_USB_BULK_IN_NUM 1 | ||
34 | #define RTL92C_NUM_RX_URBS 8 | ||
35 | #define RTL92C_NUM_TX_URBS 32 | ||
36 | |||
37 | #define RTL92C_SIZE_MAX_RX_BUFFER 15360 /* 8192 */ | ||
38 | #define RX_DRV_INFO_SIZE_UNIT 8 | ||
39 | |||
40 | enum usb_rx_agg_mode { | ||
41 | USB_RX_AGG_DISABLE, | ||
42 | USB_RX_AGG_DMA, | ||
43 | USB_RX_AGG_USB, | ||
44 | USB_RX_AGG_DMA_USB | ||
45 | }; | ||
46 | |||
47 | #define TX_SELE_HQ BIT(0) /* High Queue */ | ||
48 | #define TX_SELE_LQ BIT(1) /* Low Queue */ | ||
49 | #define TX_SELE_NQ BIT(2) /* Normal Queue */ | ||
50 | |||
51 | #define RTL_USB_TX_AGG_NUM_DESC 5 | ||
52 | |||
53 | #define RTL_USB_RX_AGG_PAGE_NUM 4 | ||
54 | #define RTL_USB_RX_AGG_PAGE_TIMEOUT 3 | ||
55 | |||
56 | #define RTL_USB_RX_AGG_BLOCK_NUM 5 | ||
57 | #define RTL_USB_RX_AGG_BLOCK_TIMEOUT 3 | ||
58 | |||
59 | /*======================== rx status =========================================*/ | ||
60 | |||
61 | struct rx_drv_info_92c { | ||
62 | /* | ||
63 | * Driver info contain PHY status and other variabel size info | ||
64 | * PHY Status content as below | ||
65 | */ | ||
66 | |||
67 | /* DWORD 0 */ | ||
68 | u8 gain_trsw[4]; | ||
69 | |||
70 | /* DWORD 1 */ | ||
71 | u8 pwdb_all; | ||
72 | u8 cfosho[4]; | ||
73 | |||
74 | /* DWORD 2 */ | ||
75 | u8 cfotail[4]; | ||
76 | |||
77 | /* DWORD 3 */ | ||
78 | s8 rxevm[2]; | ||
79 | s8 rxsnr[4]; | ||
80 | |||
81 | /* DWORD 4 */ | ||
82 | u8 pdsnr[2]; | ||
83 | |||
84 | /* DWORD 5 */ | ||
85 | u8 csi_current[2]; | ||
86 | u8 csi_target[2]; | ||
87 | |||
88 | /* DWORD 6 */ | ||
89 | u8 sigevm; | ||
90 | u8 max_ex_pwr; | ||
91 | u8 ex_intf_flag:1; | ||
92 | u8 sgi_en:1; | ||
93 | u8 rxsc:2; | ||
94 | u8 reserve:4; | ||
95 | } __packed; | ||
96 | |||
97 | /* Define a macro that takes a le32 word, converts it to host ordering, | ||
98 | * right shifts by a specified count, creates a mask of the specified | ||
99 | * bit count, and extracts that number of bits. | ||
100 | */ | ||
101 | |||
102 | #define SHIFT_AND_MASK_LE(__pdesc, __shift, __bits) \ | ||
103 | ((le32_to_cpu(*(((__le32 *)(__pdesc)))) >> (__shift)) & \ | ||
104 | BIT_LEN_MASK_32(__bits)) | ||
105 | |||
106 | /* Define a macro that clears a bit field in an le32 word and | ||
107 | * sets the specified value into that bit field. The resulting | ||
108 | * value remains in le32 ordering; however, it is properly converted | ||
109 | * to host ordering for the clear and set operations before conversion | ||
110 | * back to le32. | ||
111 | */ | ||
112 | |||
113 | #define SET_BITS_OFFSET_LE(__pdesc, __shift, __len, __val) \ | ||
114 | (*(__le32 *)(__pdesc) = \ | ||
115 | (cpu_to_le32((le32_to_cpu(*((__le32 *)(__pdesc))) & \ | ||
116 | (~(BIT_OFFSET_LEN_MASK_32((__shift), __len)))) | \ | ||
117 | (((u32)(__val) & BIT_LEN_MASK_32(__len)) << (__shift))))); | ||
118 | |||
119 | /* macros to read various fields in RX descriptor */ | ||
120 | |||
121 | /* DWORD 0 */ | ||
122 | #define GET_RX_DESC_PKT_LEN(__rxdesc) \ | ||
123 | SHIFT_AND_MASK_LE((__rxdesc), 0, 14) | ||
124 | #define GET_RX_DESC_CRC32(__rxdesc) \ | ||
125 | SHIFT_AND_MASK_LE(__rxdesc, 14, 1) | ||
126 | #define GET_RX_DESC_ICV(__rxdesc) \ | ||
127 | SHIFT_AND_MASK_LE(__rxdesc, 15, 1) | ||
128 | #define GET_RX_DESC_DRVINFO_SIZE(__rxdesc) \ | ||
129 | SHIFT_AND_MASK_LE(__rxdesc, 16, 4) | ||
130 | #define GET_RX_DESC_SECURITY(__rxdesc) \ | ||
131 | SHIFT_AND_MASK_LE(__rxdesc, 20, 3) | ||
132 | #define GET_RX_DESC_QOS(__rxdesc) \ | ||
133 | SHIFT_AND_MASK_LE(__rxdesc, 23, 1) | ||
134 | #define GET_RX_DESC_SHIFT(__rxdesc) \ | ||
135 | SHIFT_AND_MASK_LE(__rxdesc, 24, 2) | ||
136 | #define GET_RX_DESC_PHY_STATUS(__rxdesc) \ | ||
137 | SHIFT_AND_MASK_LE(__rxdesc, 26, 1) | ||
138 | #define GET_RX_DESC_SWDEC(__rxdesc) \ | ||
139 | SHIFT_AND_MASK_LE(__rxdesc, 27, 1) | ||
140 | #define GET_RX_DESC_LAST_SEG(__rxdesc) \ | ||
141 | SHIFT_AND_MASK_LE(__rxdesc, 28, 1) | ||
142 | #define GET_RX_DESC_FIRST_SEG(__rxdesc) \ | ||
143 | SHIFT_AND_MASK_LE(__rxdesc, 29, 1) | ||
144 | #define GET_RX_DESC_EOR(__rxdesc) \ | ||
145 | SHIFT_AND_MASK_LE(__rxdesc, 30, 1) | ||
146 | #define GET_RX_DESC_OWN(__rxdesc) \ | ||
147 | SHIFT_AND_MASK_LE(__rxdesc, 31, 1) | ||
148 | |||
149 | /* DWORD 1 */ | ||
150 | #define GET_RX_DESC_MACID(__rxdesc) \ | ||
151 | SHIFT_AND_MASK_LE(__rxdesc+4, 0, 5) | ||
152 | #define GET_RX_DESC_TID(__rxdesc) \ | ||
153 | SHIFT_AND_MASK_LE(__rxdesc+4, 5, 4) | ||
154 | #define GET_RX_DESC_PAGGR(__rxdesc) \ | ||
155 | SHIFT_AND_MASK_LE(__rxdesc+4, 14, 1) | ||
156 | #define GET_RX_DESC_FAGGR(__rxdesc) \ | ||
157 | SHIFT_AND_MASK_LE(__rxdesc+4, 15, 1) | ||
158 | #define GET_RX_DESC_A1_FIT(__rxdesc) \ | ||
159 | SHIFT_AND_MASK_LE(__rxdesc+4, 16, 4) | ||
160 | #define GET_RX_DESC_A2_FIT(__rxdesc) \ | ||
161 | SHIFT_AND_MASK_LE(__rxdesc+4, 20, 4) | ||
162 | #define GET_RX_DESC_PAM(__rxdesc) \ | ||
163 | SHIFT_AND_MASK_LE(__rxdesc+4, 24, 1) | ||
164 | #define GET_RX_DESC_PWR(__rxdesc) \ | ||
165 | SHIFT_AND_MASK_LE(__rxdesc+4, 25, 1) | ||
166 | #define GET_RX_DESC_MORE_DATA(__rxdesc) \ | ||
167 | SHIFT_AND_MASK_LE(__rxdesc+4, 26, 1) | ||
168 | #define GET_RX_DESC_MORE_FRAG(__rxdesc) \ | ||
169 | SHIFT_AND_MASK_LE(__rxdesc+4, 27, 1) | ||
170 | #define GET_RX_DESC_TYPE(__rxdesc) \ | ||
171 | SHIFT_AND_MASK_LE(__rxdesc+4, 28, 2) | ||
172 | #define GET_RX_DESC_MC(__rxdesc) \ | ||
173 | SHIFT_AND_MASK_LE(__rxdesc+4, 30, 1) | ||
174 | #define GET_RX_DESC_BC(__rxdesc) \ | ||
175 | SHIFT_AND_MASK_LE(__rxdesc+4, 31, 1) | ||
176 | |||
177 | /* DWORD 2 */ | ||
178 | #define GET_RX_DESC_SEQ(__rxdesc) \ | ||
179 | SHIFT_AND_MASK_LE(__rxdesc+8, 0, 12) | ||
180 | #define GET_RX_DESC_FRAG(__rxdesc) \ | ||
181 | SHIFT_AND_MASK_LE(__rxdesc+8, 12, 4) | ||
182 | #define GET_RX_DESC_USB_AGG_PKTNUM(__rxdesc) \ | ||
183 | SHIFT_AND_MASK_LE(__rxdesc+8, 16, 8) | ||
184 | #define GET_RX_DESC_NEXT_IND(__rxdesc) \ | ||
185 | SHIFT_AND_MASK_LE(__rxdesc+8, 30, 1) | ||
186 | |||
187 | /* DWORD 3 */ | ||
188 | #define GET_RX_DESC_RX_MCS(__rxdesc) \ | ||
189 | SHIFT_AND_MASK_LE(__rxdesc+12, 0, 6) | ||
190 | #define GET_RX_DESC_RX_HT(__rxdesc) \ | ||
191 | SHIFT_AND_MASK_LE(__rxdesc+12, 6, 1) | ||
192 | #define GET_RX_DESC_AMSDU(__rxdesc) \ | ||
193 | SHIFT_AND_MASK_LE(__rxdesc+12, 7, 1) | ||
194 | #define GET_RX_DESC_SPLCP(__rxdesc) \ | ||
195 | SHIFT_AND_MASK_LE(__rxdesc+12, 8, 1) | ||
196 | #define GET_RX_DESC_BW(__rxdesc) \ | ||
197 | SHIFT_AND_MASK_LE(__rxdesc+12, 9, 1) | ||
198 | #define GET_RX_DESC_HTC(__rxdesc) \ | ||
199 | SHIFT_AND_MASK_LE(__rxdesc+12, 10, 1) | ||
200 | #define GET_RX_DESC_TCP_CHK_RPT(__rxdesc) \ | ||
201 | SHIFT_AND_MASK_LE(__rxdesc+12, 11, 1) | ||
202 | #define GET_RX_DESC_IP_CHK_RPT(__rxdesc) \ | ||
203 | SHIFT_AND_MASK_LE(__rxdesc+12, 12, 1) | ||
204 | #define GET_RX_DESC_TCP_CHK_VALID(__rxdesc) \ | ||
205 | SHIFT_AND_MASK_LE(__rxdesc+12, 13, 1) | ||
206 | #define GET_RX_DESC_HWPC_ERR(__rxdesc) \ | ||
207 | SHIFT_AND_MASK_LE(__rxdesc+12, 14, 1) | ||
208 | #define GET_RX_DESC_HWPC_IND(__rxdesc) \ | ||
209 | SHIFT_AND_MASK_LE(__rxdesc+12, 15, 1) | ||
210 | #define GET_RX_DESC_IV0(__rxdesc) \ | ||
211 | SHIFT_AND_MASK_LE(__rxdesc+12, 16, 16) | ||
212 | |||
213 | /* DWORD 4 */ | ||
214 | #define GET_RX_DESC_IV1(__rxdesc) \ | ||
215 | SHIFT_AND_MASK_LE(__rxdesc+16, 0, 32) | ||
216 | |||
217 | /* DWORD 5 */ | ||
218 | #define GET_RX_DESC_TSFL(__rxdesc) \ | ||
219 | SHIFT_AND_MASK_LE(__rxdesc+20, 0, 32) | ||
220 | |||
221 | /*======================= tx desc ============================================*/ | ||
222 | |||
223 | /* macros to set various fields in TX descriptor */ | ||
224 | |||
225 | /* Dword 0 */ | ||
226 | #define SET_TX_DESC_PKT_SIZE(__txdesc, __value) \ | ||
227 | SET_BITS_OFFSET_LE(__txdesc, 0, 16, __value) | ||
228 | #define SET_TX_DESC_OFFSET(__txdesc, __value) \ | ||
229 | SET_BITS_OFFSET_LE(__txdesc, 16, 8, __value) | ||
230 | #define SET_TX_DESC_BMC(__txdesc, __value) \ | ||
231 | SET_BITS_OFFSET_LE(__txdesc, 24, 1, __value) | ||
232 | #define SET_TX_DESC_HTC(__txdesc, __value) \ | ||
233 | SET_BITS_OFFSET_LE(__txdesc, 25, 1, __value) | ||
234 | #define SET_TX_DESC_LAST_SEG(__txdesc, __value) \ | ||
235 | SET_BITS_OFFSET_LE(__txdesc, 26, 1, __value) | ||
236 | #define SET_TX_DESC_FIRST_SEG(__txdesc, __value) \ | ||
237 | SET_BITS_OFFSET_LE(__txdesc, 27, 1, __value) | ||
238 | #define SET_TX_DESC_LINIP(__txdesc, __value) \ | ||
239 | SET_BITS_OFFSET_LE(__txdesc, 28, 1, __value) | ||
240 | #define SET_TX_DESC_NO_ACM(__txdesc, __value) \ | ||
241 | SET_BITS_OFFSET_LE(__txdesc, 29, 1, __value) | ||
242 | #define SET_TX_DESC_GF(__txdesc, __value) \ | ||
243 | SET_BITS_OFFSET_LE(__txdesc, 30, 1, __value) | ||
244 | #define SET_TX_DESC_OWN(__txdesc, __value) \ | ||
245 | SET_BITS_OFFSET_LE(__txdesc, 31, 1, __value) | ||
246 | |||
247 | |||
248 | /* Dword 1 */ | ||
249 | #define SET_TX_DESC_MACID(__txdesc, __value) \ | ||
250 | SET_BITS_OFFSET_LE(__txdesc+4, 0, 5, __value) | ||
251 | #define SET_TX_DESC_AGG_ENABLE(__txdesc, __value) \ | ||
252 | SET_BITS_OFFSET_LE(__txdesc+4, 5, 1, __value) | ||
253 | #define SET_TX_DESC_AGG_BREAK(__txdesc, __value) \ | ||
254 | SET_BITS_OFFSET_LE(__txdesc+4, 6, 1, __value) | ||
255 | #define SET_TX_DESC_RDG_ENABLE(__txdesc, __value) \ | ||
256 | SET_BITS_OFFSET_LE(__txdesc+4, 7, 1, __value) | ||
257 | #define SET_TX_DESC_QUEUE_SEL(__txdesc, __value) \ | ||
258 | SET_BITS_OFFSET_LE(__txdesc+4, 8, 5, __value) | ||
259 | #define SET_TX_DESC_RDG_NAV_EXT(__txdesc, __value) \ | ||
260 | SET_BITS_OFFSET_LE(__txdesc+4, 13, 1, __value) | ||
261 | #define SET_TX_DESC_LSIG_TXOP_EN(__txdesc, __value) \ | ||
262 | SET_BITS_OFFSET_LE(__txdesc+4, 14, 1, __value) | ||
263 | #define SET_TX_DESC_PIFS(__txdesc, __value) \ | ||
264 | SET_BITS_OFFSET_LE(__txdesc+4, 15, 1, __value) | ||
265 | #define SET_TX_DESC_RATE_ID(__txdesc, __value) \ | ||
266 | SET_BITS_OFFSET_LE(__txdesc+4, 16, 4, __value) | ||
267 | #define SET_TX_DESC_RA_BRSR_ID(__txdesc, __value) \ | ||
268 | SET_BITS_OFFSET_LE(__txdesc+4, 16, 4, __value) | ||
269 | #define SET_TX_DESC_NAV_USE_HDR(__txdesc, __value) \ | ||
270 | SET_BITS_OFFSET_LE(__txdesc+4, 20, 1, __value) | ||
271 | #define SET_TX_DESC_EN_DESC_ID(__txdesc, __value) \ | ||
272 | SET_BITS_OFFSET_LE(__txdesc+4, 21, 1, __value) | ||
273 | #define SET_TX_DESC_SEC_TYPE(__txdesc, __value) \ | ||
274 | SET_BITS_OFFSET_LE(__txdesc+4, 22, 2, __value) | ||
275 | #define SET_TX_DESC_PKT_OFFSET(__txdesc, __value) \ | ||
276 | SET_BITS_OFFSET_LE(__txdesc+4, 26, 5, __value) | ||
277 | |||
278 | /* Dword 2 */ | ||
279 | #define SET_TX_DESC_RTS_RC(__txdesc, __value) \ | ||
280 | SET_BITS_OFFSET_LE(__txdesc+8, 0, 6, __value) | ||
281 | #define SET_TX_DESC_DATA_RC(__txdesc, __value) \ | ||
282 | SET_BITS_OFFSET_LE(__txdesc+8, 6, 6, __value) | ||
283 | #define SET_TX_DESC_BAR_RTY_TH(__txdesc, __value) \ | ||
284 | SET_BITS_OFFSET_LE(__txdesc+8, 14, 2, __value) | ||
285 | #define SET_TX_DESC_MORE_FRAG(__txdesc, __value) \ | ||
286 | SET_BITS_OFFSET_LE(__txdesc+8, 17, 1, __value) | ||
287 | #define SET_TX_DESC_RAW(__txdesc, __value) \ | ||
288 | SET_BITS_OFFSET_LE(__txdesc+8, 18, 1, __value) | ||
289 | #define SET_TX_DESC_CCX(__txdesc, __value) \ | ||
290 | SET_BITS_OFFSET_LE(__txdesc+8, 19, 1, __value) | ||
291 | #define SET_TX_DESC_AMPDU_DENSITY(__txdesc, __value) \ | ||
292 | SET_BITS_OFFSET_LE(__txdesc+8, 20, 3, __value) | ||
293 | #define SET_TX_DESC_ANTSEL_A(__txdesc, __value) \ | ||
294 | SET_BITS_OFFSET_LE(__txdesc+8, 24, 1, __value) | ||
295 | #define SET_TX_DESC_ANTSEL_B(__txdesc, __value) \ | ||
296 | SET_BITS_OFFSET_LE(__txdesc+8, 25, 1, __value) | ||
297 | #define SET_TX_DESC_TX_ANT_CCK(__txdesc, __value) \ | ||
298 | SET_BITS_OFFSET_LE(__txdesc+8, 26, 2, __value) | ||
299 | #define SET_TX_DESC_TX_ANTL(__txdesc, __value) \ | ||
300 | SET_BITS_OFFSET_LE(__txdesc+8, 28, 2, __value) | ||
301 | #define SET_TX_DESC_TX_ANT_HT(__txdesc, __value) \ | ||
302 | SET_BITS_OFFSET_LE(__txdesc+8, 30, 2, __value) | ||
303 | |||
304 | /* Dword 3 */ | ||
305 | #define SET_TX_DESC_NEXT_HEAP_PAGE(__txdesc, __value) \ | ||
306 | SET_BITS_OFFSET_LE(__txdesc+12, 0, 8, __value) | ||
307 | #define SET_TX_DESC_TAIL_PAGE(__txdesc, __value) \ | ||
308 | SET_BITS_OFFSET_LE(__txdesc+12, 8, 8, __value) | ||
309 | #define SET_TX_DESC_SEQ(__txdesc, __value) \ | ||
310 | SET_BITS_OFFSET_LE(__txdesc+12, 16, 12, __value) | ||
311 | #define SET_TX_DESC_PKT_ID(__txdesc, __value) \ | ||
312 | SET_BITS_OFFSET_LE(__txdesc+12, 28, 4, __value) | ||
313 | |||
314 | /* Dword 4 */ | ||
315 | #define SET_TX_DESC_RTS_RATE(__txdesc, __value) \ | ||
316 | SET_BITS_OFFSET_LE(__txdesc+16, 0, 5, __value) | ||
317 | #define SET_TX_DESC_AP_DCFE(__txdesc, __value) \ | ||
318 | SET_BITS_OFFSET_LE(__txdesc+16, 5, 1, __value) | ||
319 | #define SET_TX_DESC_QOS(__txdesc, __value) \ | ||
320 | SET_BITS_OFFSET_LE(__txdesc+16, 6, 1, __value) | ||
321 | #define SET_TX_DESC_HWSEQ_EN(__txdesc, __value) \ | ||
322 | SET_BITS_OFFSET_LE(__txdesc+16, 7, 1, __value) | ||
323 | #define SET_TX_DESC_USE_RATE(__txdesc, __value) \ | ||
324 | SET_BITS_OFFSET_LE(__txdesc+16, 8, 1, __value) | ||
325 | #define SET_TX_DESC_DISABLE_RTS_FB(__txdesc, __value) \ | ||
326 | SET_BITS_OFFSET_LE(__txdesc+16, 9, 1, __value) | ||
327 | #define SET_TX_DESC_DISABLE_FB(__txdesc, __value) \ | ||
328 | SET_BITS_OFFSET_LE(__txdesc+16, 10, 1, __value) | ||
329 | #define SET_TX_DESC_CTS2SELF(__txdesc, __value) \ | ||
330 | SET_BITS_OFFSET_LE(__txdesc+16, 11, 1, __value) | ||
331 | #define SET_TX_DESC_RTS_ENABLE(__txdesc, __value) \ | ||
332 | SET_BITS_OFFSET_LE(__txdesc+16, 12, 1, __value) | ||
333 | #define SET_TX_DESC_HW_RTS_ENABLE(__txdesc, __value) \ | ||
334 | SET_BITS_OFFSET_LE(__txdesc+16, 13, 1, __value) | ||
335 | #define SET_TX_DESC_WAIT_DCTS(__txdesc, __value) \ | ||
336 | SET_BITS_OFFSET_LE(__txdesc+16, 18, 1, __value) | ||
337 | #define SET_TX_DESC_CTS2AP_EN(__txdesc, __value) \ | ||
338 | SET_BITS_OFFSET_LE(__txdesc+16, 19, 1, __value) | ||
339 | #define SET_TX_DESC_DATA_SC(__txdesc, __value) \ | ||
340 | SET_BITS_OFFSET_LE(__txdesc+16, 20, 2, __value) | ||
341 | #define SET_TX_DESC_DATA_STBC(__txdesc, __value) \ | ||
342 | SET_BITS_OFFSET_LE(__txdesc+16, 22, 2, __value) | ||
343 | #define SET_TX_DESC_DATA_SHORT(__txdesc, __value) \ | ||
344 | SET_BITS_OFFSET_LE(__txdesc+16, 24, 1, __value) | ||
345 | #define SET_TX_DESC_DATA_BW(__txdesc, __value) \ | ||
346 | SET_BITS_OFFSET_LE(__txdesc+16, 25, 1, __value) | ||
347 | #define SET_TX_DESC_RTS_SHORT(__txdesc, __value) \ | ||
348 | SET_BITS_OFFSET_LE(__txdesc+16, 26, 1, __value) | ||
349 | #define SET_TX_DESC_RTS_BW(__txdesc, __value) \ | ||
350 | SET_BITS_OFFSET_LE(__txdesc+16, 27, 1, __value) | ||
351 | #define SET_TX_DESC_RTS_SC(__txdesc, __value) \ | ||
352 | SET_BITS_OFFSET_LE(__txdesc+16, 28, 2, __value) | ||
353 | #define SET_TX_DESC_RTS_STBC(__txdesc, __value) \ | ||
354 | SET_BITS_OFFSET_LE(__txdesc+16, 30, 2, __value) | ||
355 | |||
356 | /* Dword 5 */ | ||
357 | #define SET_TX_DESC_TX_RATE(__pdesc, __val) \ | ||
358 | SET_BITS_OFFSET_LE(__pdesc+20, 0, 6, __val) | ||
359 | #define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val) \ | ||
360 | SET_BITS_OFFSET_LE(__pdesc+20, 6, 1, __val) | ||
361 | #define SET_TX_DESC_CCX_TAG(__pdesc, __val) \ | ||
362 | SET_BITS_OFFSET_LE(__pdesc+20, 7, 1, __val) | ||
363 | #define SET_TX_DESC_DATA_RATE_FB_LIMIT(__txdesc, __value) \ | ||
364 | SET_BITS_OFFSET_LE(__txdesc+20, 8, 5, __value) | ||
365 | #define SET_TX_DESC_RTS_RATE_FB_LIMIT(__txdesc, __value) \ | ||
366 | SET_BITS_OFFSET_LE(__txdesc+20, 13, 4, __value) | ||
367 | #define SET_TX_DESC_RETRY_LIMIT_ENABLE(__txdesc, __value) \ | ||
368 | SET_BITS_OFFSET_LE(__txdesc+20, 17, 1, __value) | ||
369 | #define SET_TX_DESC_DATA_RETRY_LIMIT(__txdesc, __value) \ | ||
370 | SET_BITS_OFFSET_LE(__txdesc+20, 18, 6, __value) | ||
371 | #define SET_TX_DESC_USB_TXAGG_NUM(__txdesc, __value) \ | ||
372 | SET_BITS_OFFSET_LE(__txdesc+20, 24, 8, __value) | ||
373 | |||
374 | /* Dword 6 */ | ||
375 | #define SET_TX_DESC_TXAGC_A(__txdesc, __value) \ | ||
376 | SET_BITS_OFFSET_LE(__txdesc+24, 0, 5, __value) | ||
377 | #define SET_TX_DESC_TXAGC_B(__txdesc, __value) \ | ||
378 | SET_BITS_OFFSET_LE(__txdesc+24, 5, 5, __value) | ||
379 | #define SET_TX_DESC_USB_MAX_LEN(__txdesc, __value) \ | ||
380 | SET_BITS_OFFSET_LE(__txdesc+24, 10, 1, __value) | ||
381 | #define SET_TX_DESC_MAX_AGG_NUM(__txdesc, __value) \ | ||
382 | SET_BITS_OFFSET_LE(__txdesc+24, 11, 5, __value) | ||
383 | #define SET_TX_DESC_MCSG1_MAX_LEN(__txdesc, __value) \ | ||
384 | SET_BITS_OFFSET_LE(__txdesc+24, 16, 4, __value) | ||
385 | #define SET_TX_DESC_MCSG2_MAX_LEN(__txdesc, __value) \ | ||
386 | SET_BITS_OFFSET_LE(__txdesc+24, 20, 4, __value) | ||
387 | #define SET_TX_DESC_MCSG3_MAX_LEN(__txdesc, __value) \ | ||
388 | SET_BITS_OFFSET_LE(__txdesc+24, 24, 4, __value) | ||
389 | #define SET_TX_DESC_MCSG7_MAX_LEN(__txdesc, __value) \ | ||
390 | SET_BITS_OFFSET_LE(__txdesc+24, 28, 4, __value) | ||
391 | |||
392 | /* Dword 7 */ | ||
393 | #define SET_TX_DESC_TX_DESC_CHECKSUM(__txdesc, __value) \ | ||
394 | SET_BITS_OFFSET_LE(__txdesc+28, 0, 16, __value) | ||
395 | #define SET_TX_DESC_MCSG4_MAX_LEN(__txdesc, __value) \ | ||
396 | SET_BITS_OFFSET_LE(__txdesc+28, 16, 4, __value) | ||
397 | #define SET_TX_DESC_MCSG5_MAX_LEN(__txdesc, __value) \ | ||
398 | SET_BITS_OFFSET_LE(__txdesc+28, 20, 4, __value) | ||
399 | #define SET_TX_DESC_MCSG6_MAX_LEN(__txdesc, __value) \ | ||
400 | SET_BITS_OFFSET_LE(__txdesc+28, 24, 4, __value) | ||
401 | #define SET_TX_DESC_MCSG15_MAX_LEN(__txdesc, __value) \ | ||
402 | SET_BITS_OFFSET_LE(__txdesc+28, 28, 4, __value) | ||
403 | |||
404 | |||
405 | int rtl8192cu_endpoint_mapping(struct ieee80211_hw *hw); | ||
406 | u16 rtl8192cu_mq_to_hwq(__le16 fc, u16 mac80211_queue_index); | ||
407 | bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw, | ||
408 | struct rtl_stats *stats, | ||
409 | struct ieee80211_rx_status *rx_status, | ||
410 | u8 *p_desc, struct sk_buff *skb); | ||
411 | void rtl8192cu_rx_hdl(struct ieee80211_hw *hw, struct sk_buff * skb); | ||
412 | void rtl8192c_rx_segregate_hdl(struct ieee80211_hw *, struct sk_buff *, | ||
413 | struct sk_buff_head *); | ||
414 | void rtl8192c_tx_cleanup(struct ieee80211_hw *hw, struct sk_buff *skb); | ||
415 | int rtl8192c_tx_post_hdl(struct ieee80211_hw *hw, struct urb *urb, | ||
416 | struct sk_buff *skb); | ||
417 | struct sk_buff *rtl8192c_tx_aggregate_hdl(struct ieee80211_hw *, | ||
418 | struct sk_buff_head *); | ||
419 | void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, | ||
420 | struct ieee80211_hdr *hdr, u8 *pdesc_tx, | ||
421 | struct ieee80211_tx_info *info, struct sk_buff *skb, | ||
422 | unsigned int queue_index); | ||
423 | void rtl92cu_fill_fake_txdesc(struct ieee80211_hw *hw, u8 * pDesc, | ||
424 | u32 buffer_len, bool bIsPsPoll); | ||
425 | void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw, | ||
426 | u8 *pdesc, bool b_firstseg, | ||
427 | bool b_lastseg, struct sk_buff *skb); | ||
428 | bool rtl92cu_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb); | ||
429 | |||
430 | #endif | ||
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c new file mode 100644 index 000000000000..a4b2613d6a8c --- /dev/null +++ b/drivers/net/wireless/rtlwifi/usb.c | |||
@@ -0,0 +1,1035 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2011 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | *****************************************************************************/ | ||
27 | #include <linux/usb.h> | ||
28 | #include "core.h" | ||
29 | #include "wifi.h" | ||
30 | #include "usb.h" | ||
31 | #include "base.h" | ||
32 | #include "ps.h" | ||
33 | |||
34 | #define REALTEK_USB_VENQT_READ 0xC0 | ||
35 | #define REALTEK_USB_VENQT_WRITE 0x40 | ||
36 | #define REALTEK_USB_VENQT_CMD_REQ 0x05 | ||
37 | #define REALTEK_USB_VENQT_CMD_IDX 0x00 | ||
38 | |||
39 | #define REALTEK_USB_VENQT_MAX_BUF_SIZE 254 | ||
40 | |||
41 | static void usbctrl_async_callback(struct urb *urb) | ||
42 | { | ||
43 | if (urb) | ||
44 | kfree(urb->context); | ||
45 | } | ||
46 | |||
47 | static int _usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request, | ||
48 | u16 value, u16 index, void *pdata, | ||
49 | u16 len) | ||
50 | { | ||
51 | int rc; | ||
52 | unsigned int pipe; | ||
53 | u8 reqtype; | ||
54 | struct usb_ctrlrequest *dr; | ||
55 | struct urb *urb; | ||
56 | struct rtl819x_async_write_data { | ||
57 | u8 data[REALTEK_USB_VENQT_MAX_BUF_SIZE]; | ||
58 | struct usb_ctrlrequest dr; | ||
59 | } *buf; | ||
60 | |||
61 | pipe = usb_sndctrlpipe(udev, 0); /* write_out */ | ||
62 | reqtype = REALTEK_USB_VENQT_WRITE; | ||
63 | |||
64 | buf = kmalloc(sizeof(*buf), GFP_ATOMIC); | ||
65 | if (!buf) | ||
66 | return -ENOMEM; | ||
67 | |||
68 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
69 | if (!urb) { | ||
70 | kfree(buf); | ||
71 | return -ENOMEM; | ||
72 | } | ||
73 | |||
74 | dr = &buf->dr; | ||
75 | |||
76 | dr->bRequestType = reqtype; | ||
77 | dr->bRequest = request; | ||
78 | dr->wValue = cpu_to_le16(value); | ||
79 | dr->wIndex = cpu_to_le16(index); | ||
80 | dr->wLength = cpu_to_le16(len); | ||
81 | memcpy(buf, pdata, len); | ||
82 | usb_fill_control_urb(urb, udev, pipe, | ||
83 | (unsigned char *)dr, buf, len, | ||
84 | usbctrl_async_callback, buf); | ||
85 | rc = usb_submit_urb(urb, GFP_ATOMIC); | ||
86 | if (rc < 0) | ||
87 | kfree(buf); | ||
88 | usb_free_urb(urb); | ||
89 | return rc; | ||
90 | } | ||
91 | |||
92 | static int _usbctrl_vendorreq_sync_read(struct usb_device *udev, u8 request, | ||
93 | u16 value, u16 index, void *pdata, | ||
94 | u16 len) | ||
95 | { | ||
96 | unsigned int pipe; | ||
97 | int status; | ||
98 | u8 reqtype; | ||
99 | |||
100 | pipe = usb_rcvctrlpipe(udev, 0); /* read_in */ | ||
101 | reqtype = REALTEK_USB_VENQT_READ; | ||
102 | |||
103 | status = usb_control_msg(udev, pipe, request, reqtype, value, index, | ||
104 | pdata, len, 0); /* max. timeout */ | ||
105 | |||
106 | if (status < 0) | ||
107 | printk(KERN_ERR "reg 0x%x, usbctrl_vendorreq TimeOut! " | ||
108 | "status:0x%x value=0x%x\n", value, status, | ||
109 | *(u32 *)pdata); | ||
110 | return status; | ||
111 | } | ||
112 | |||
113 | static u32 _usb_read_sync(struct usb_device *udev, u32 addr, u16 len) | ||
114 | { | ||
115 | u8 request; | ||
116 | u16 wvalue; | ||
117 | u16 index; | ||
118 | u32 *data; | ||
119 | u32 ret; | ||
120 | |||
121 | data = kmalloc(sizeof(u32), GFP_KERNEL); | ||
122 | if (!data) | ||
123 | return -ENOMEM; | ||
124 | request = REALTEK_USB_VENQT_CMD_REQ; | ||
125 | index = REALTEK_USB_VENQT_CMD_IDX; /* n/a */ | ||
126 | |||
127 | wvalue = (u16)addr; | ||
128 | _usbctrl_vendorreq_sync_read(udev, request, wvalue, index, data, len); | ||
129 | ret = *data; | ||
130 | kfree(data); | ||
131 | return ret; | ||
132 | } | ||
133 | |||
134 | static u8 _usb_read8_sync(struct rtl_priv *rtlpriv, u32 addr) | ||
135 | { | ||
136 | struct device *dev = rtlpriv->io.dev; | ||
137 | |||
138 | return (u8)_usb_read_sync(to_usb_device(dev), addr, 1); | ||
139 | } | ||
140 | |||
141 | static u16 _usb_read16_sync(struct rtl_priv *rtlpriv, u32 addr) | ||
142 | { | ||
143 | struct device *dev = rtlpriv->io.dev; | ||
144 | |||
145 | return (u16)_usb_read_sync(to_usb_device(dev), addr, 2); | ||
146 | } | ||
147 | |||
148 | static u32 _usb_read32_sync(struct rtl_priv *rtlpriv, u32 addr) | ||
149 | { | ||
150 | struct device *dev = rtlpriv->io.dev; | ||
151 | |||
152 | return _usb_read_sync(to_usb_device(dev), addr, 4); | ||
153 | } | ||
154 | |||
155 | static void _usb_write_async(struct usb_device *udev, u32 addr, u32 val, | ||
156 | u16 len) | ||
157 | { | ||
158 | u8 request; | ||
159 | u16 wvalue; | ||
160 | u16 index; | ||
161 | u32 data; | ||
162 | |||
163 | request = REALTEK_USB_VENQT_CMD_REQ; | ||
164 | index = REALTEK_USB_VENQT_CMD_IDX; /* n/a */ | ||
165 | wvalue = (u16)(addr&0x0000ffff); | ||
166 | data = val; | ||
167 | _usbctrl_vendorreq_async_write(udev, request, wvalue, index, &data, | ||
168 | len); | ||
169 | } | ||
170 | |||
171 | static void _usb_write8_async(struct rtl_priv *rtlpriv, u32 addr, u8 val) | ||
172 | { | ||
173 | struct device *dev = rtlpriv->io.dev; | ||
174 | |||
175 | _usb_write_async(to_usb_device(dev), addr, val, 1); | ||
176 | } | ||
177 | |||
178 | static void _usb_write16_async(struct rtl_priv *rtlpriv, u32 addr, u16 val) | ||
179 | { | ||
180 | struct device *dev = rtlpriv->io.dev; | ||
181 | |||
182 | _usb_write_async(to_usb_device(dev), addr, val, 2); | ||
183 | } | ||
184 | |||
185 | static void _usb_write32_async(struct rtl_priv *rtlpriv, u32 addr, u32 val) | ||
186 | { | ||
187 | struct device *dev = rtlpriv->io.dev; | ||
188 | |||
189 | _usb_write_async(to_usb_device(dev), addr, val, 4); | ||
190 | } | ||
191 | |||
192 | static int _usb_nbytes_read_write(struct usb_device *udev, bool read, u32 addr, | ||
193 | u16 len, u8 *pdata) | ||
194 | { | ||
195 | int status; | ||
196 | u8 request; | ||
197 | u16 wvalue; | ||
198 | u16 index; | ||
199 | |||
200 | request = REALTEK_USB_VENQT_CMD_REQ; | ||
201 | index = REALTEK_USB_VENQT_CMD_IDX; /* n/a */ | ||
202 | wvalue = (u16)addr; | ||
203 | if (read) | ||
204 | status = _usbctrl_vendorreq_sync_read(udev, request, wvalue, | ||
205 | index, pdata, len); | ||
206 | else | ||
207 | status = _usbctrl_vendorreq_async_write(udev, request, wvalue, | ||
208 | index, pdata, len); | ||
209 | return status; | ||
210 | } | ||
211 | |||
212 | static int _usb_readN_sync(struct rtl_priv *rtlpriv, u32 addr, u16 len, | ||
213 | u8 *pdata) | ||
214 | { | ||
215 | struct device *dev = rtlpriv->io.dev; | ||
216 | |||
217 | return _usb_nbytes_read_write(to_usb_device(dev), true, addr, len, | ||
218 | pdata); | ||
219 | } | ||
220 | |||
221 | static int _usb_writeN_async(struct rtl_priv *rtlpriv, u32 addr, u16 len, | ||
222 | u8 *pdata) | ||
223 | { | ||
224 | struct device *dev = rtlpriv->io.dev; | ||
225 | |||
226 | return _usb_nbytes_read_write(to_usb_device(dev), false, addr, len, | ||
227 | pdata); | ||
228 | } | ||
229 | |||
230 | static void _rtl_usb_io_handler_init(struct device *dev, | ||
231 | struct ieee80211_hw *hw) | ||
232 | { | ||
233 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
234 | |||
235 | rtlpriv->io.dev = dev; | ||
236 | mutex_init(&rtlpriv->io.bb_mutex); | ||
237 | rtlpriv->io.write8_async = _usb_write8_async; | ||
238 | rtlpriv->io.write16_async = _usb_write16_async; | ||
239 | rtlpriv->io.write32_async = _usb_write32_async; | ||
240 | rtlpriv->io.writeN_async = _usb_writeN_async; | ||
241 | rtlpriv->io.read8_sync = _usb_read8_sync; | ||
242 | rtlpriv->io.read16_sync = _usb_read16_sync; | ||
243 | rtlpriv->io.read32_sync = _usb_read32_sync; | ||
244 | rtlpriv->io.readN_sync = _usb_readN_sync; | ||
245 | } | ||
246 | |||
247 | static void _rtl_usb_io_handler_release(struct ieee80211_hw *hw) | ||
248 | { | ||
249 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
250 | |||
251 | mutex_destroy(&rtlpriv->io.bb_mutex); | ||
252 | } | ||
253 | |||
254 | /** | ||
255 | * | ||
256 | * Default aggregation handler. Do nothing and just return the oldest skb. | ||
257 | */ | ||
258 | static struct sk_buff *_none_usb_tx_aggregate_hdl(struct ieee80211_hw *hw, | ||
259 | struct sk_buff_head *list) | ||
260 | { | ||
261 | return skb_dequeue(list); | ||
262 | } | ||
263 | |||
264 | #define IS_HIGH_SPEED_USB(udev) \ | ||
265 | ((USB_SPEED_HIGH == (udev)->speed) ? true : false) | ||
266 | |||
267 | static int _rtl_usb_init_tx(struct ieee80211_hw *hw) | ||
268 | { | ||
269 | u32 i; | ||
270 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
271 | struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); | ||
272 | |||
273 | rtlusb->max_bulk_out_size = IS_HIGH_SPEED_USB(rtlusb->udev) | ||
274 | ? USB_HIGH_SPEED_BULK_SIZE | ||
275 | : USB_FULL_SPEED_BULK_SIZE; | ||
276 | |||
277 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("USB Max Bulk-out Size=%d\n", | ||
278 | rtlusb->max_bulk_out_size)); | ||
279 | |||
280 | for (i = 0; i < __RTL_TXQ_NUM; i++) { | ||
281 | u32 ep_num = rtlusb->ep_map.ep_mapping[i]; | ||
282 | if (!ep_num) { | ||
283 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
284 | ("Invalid endpoint map setting!\n")); | ||
285 | return -EINVAL; | ||
286 | } | ||
287 | } | ||
288 | |||
289 | rtlusb->usb_tx_post_hdl = | ||
290 | rtlpriv->cfg->usb_interface_cfg->usb_tx_post_hdl; | ||
291 | rtlusb->usb_tx_cleanup = | ||
292 | rtlpriv->cfg->usb_interface_cfg->usb_tx_cleanup; | ||
293 | rtlusb->usb_tx_aggregate_hdl = | ||
294 | (rtlpriv->cfg->usb_interface_cfg->usb_tx_aggregate_hdl) | ||
295 | ? rtlpriv->cfg->usb_interface_cfg->usb_tx_aggregate_hdl | ||
296 | : &_none_usb_tx_aggregate_hdl; | ||
297 | |||
298 | init_usb_anchor(&rtlusb->tx_submitted); | ||
299 | for (i = 0; i < RTL_USB_MAX_EP_NUM; i++) { | ||
300 | skb_queue_head_init(&rtlusb->tx_skb_queue[i]); | ||
301 | init_usb_anchor(&rtlusb->tx_pending[i]); | ||
302 | } | ||
303 | return 0; | ||
304 | } | ||
305 | |||
306 | static int _rtl_usb_init_rx(struct ieee80211_hw *hw) | ||
307 | { | ||
308 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
309 | struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw); | ||
310 | struct rtl_usb *rtlusb = rtl_usbdev(usb_priv); | ||
311 | |||
312 | rtlusb->rx_max_size = rtlpriv->cfg->usb_interface_cfg->rx_max_size; | ||
313 | rtlusb->rx_urb_num = rtlpriv->cfg->usb_interface_cfg->rx_urb_num; | ||
314 | rtlusb->in_ep = rtlpriv->cfg->usb_interface_cfg->in_ep_num; | ||
315 | rtlusb->usb_rx_hdl = rtlpriv->cfg->usb_interface_cfg->usb_rx_hdl; | ||
316 | rtlusb->usb_rx_segregate_hdl = | ||
317 | rtlpriv->cfg->usb_interface_cfg->usb_rx_segregate_hdl; | ||
318 | |||
319 | printk(KERN_INFO "rtl8192cu: rx_max_size %d, rx_urb_num %d, in_ep %d\n", | ||
320 | rtlusb->rx_max_size, rtlusb->rx_urb_num, rtlusb->in_ep); | ||
321 | init_usb_anchor(&rtlusb->rx_submitted); | ||
322 | return 0; | ||
323 | } | ||
324 | |||
325 | static int _rtl_usb_init(struct ieee80211_hw *hw) | ||
326 | { | ||
327 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
328 | struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw); | ||
329 | struct rtl_usb *rtlusb = rtl_usbdev(usb_priv); | ||
330 | int err; | ||
331 | u8 epidx; | ||
332 | struct usb_interface *usb_intf = rtlusb->intf; | ||
333 | u8 epnums = usb_intf->cur_altsetting->desc.bNumEndpoints; | ||
334 | |||
335 | rtlusb->out_ep_nums = rtlusb->in_ep_nums = 0; | ||
336 | for (epidx = 0; epidx < epnums; epidx++) { | ||
337 | struct usb_endpoint_descriptor *pep_desc; | ||
338 | pep_desc = &usb_intf->cur_altsetting->endpoint[epidx].desc; | ||
339 | |||
340 | if (usb_endpoint_dir_in(pep_desc)) | ||
341 | rtlusb->in_ep_nums++; | ||
342 | else if (usb_endpoint_dir_out(pep_desc)) | ||
343 | rtlusb->out_ep_nums++; | ||
344 | |||
345 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
346 | ("USB EP(0x%02x), MaxPacketSize=%d ,Interval=%d.\n", | ||
347 | pep_desc->bEndpointAddress, pep_desc->wMaxPacketSize, | ||
348 | pep_desc->bInterval)); | ||
349 | } | ||
350 | if (rtlusb->in_ep_nums < rtlpriv->cfg->usb_interface_cfg->in_ep_num) | ||
351 | return -EINVAL ; | ||
352 | |||
353 | /* usb endpoint mapping */ | ||
354 | err = rtlpriv->cfg->usb_interface_cfg->usb_endpoint_mapping(hw); | ||
355 | rtlusb->usb_mq_to_hwq = rtlpriv->cfg->usb_interface_cfg->usb_mq_to_hwq; | ||
356 | _rtl_usb_init_tx(hw); | ||
357 | _rtl_usb_init_rx(hw); | ||
358 | return err; | ||
359 | } | ||
360 | |||
361 | static int _rtl_usb_init_sw(struct ieee80211_hw *hw) | ||
362 | { | ||
363 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
364 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
365 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
366 | struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); | ||
367 | |||
368 | rtlhal->hw = hw; | ||
369 | ppsc->inactiveps = false; | ||
370 | ppsc->leisure_ps = false; | ||
371 | ppsc->fwctrl_lps = false; | ||
372 | ppsc->reg_fwctrl_lps = 3; | ||
373 | ppsc->reg_max_lps_awakeintvl = 5; | ||
374 | ppsc->fwctrl_psmode = FW_PS_DTIM_MODE; | ||
375 | |||
376 | /* IBSS */ | ||
377 | mac->beacon_interval = 100; | ||
378 | |||
379 | /* AMPDU */ | ||
380 | mac->min_space_cfg = 0; | ||
381 | mac->max_mss_density = 0; | ||
382 | |||
383 | /* set sane AMPDU defaults */ | ||
384 | mac->current_ampdu_density = 7; | ||
385 | mac->current_ampdu_factor = 3; | ||
386 | |||
387 | /* QOS */ | ||
388 | rtlusb->acm_method = eAcmWay2_SW; | ||
389 | |||
390 | /* IRQ */ | ||
391 | /* HIMR - turn all on */ | ||
392 | rtlusb->irq_mask[0] = 0xFFFFFFFF; | ||
393 | /* HIMR_EX - turn all on */ | ||
394 | rtlusb->irq_mask[1] = 0xFFFFFFFF; | ||
395 | rtlusb->disableHWSM = true; | ||
396 | return 0; | ||
397 | } | ||
398 | |||
399 | #define __RADIO_TAP_SIZE_RSV 32 | ||
400 | |||
401 | static void _rtl_rx_completed(struct urb *urb); | ||
402 | |||
403 | static struct sk_buff *_rtl_prep_rx_urb(struct ieee80211_hw *hw, | ||
404 | struct rtl_usb *rtlusb, | ||
405 | struct urb *urb, | ||
406 | gfp_t gfp_mask) | ||
407 | { | ||
408 | struct sk_buff *skb; | ||
409 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
410 | |||
411 | skb = __dev_alloc_skb((rtlusb->rx_max_size + __RADIO_TAP_SIZE_RSV), | ||
412 | gfp_mask); | ||
413 | if (!skb) { | ||
414 | RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, | ||
415 | ("Failed to __dev_alloc_skb!!\n")) | ||
416 | return ERR_PTR(-ENOMEM); | ||
417 | } | ||
418 | |||
419 | /* reserve some space for mac80211's radiotap */ | ||
420 | skb_reserve(skb, __RADIO_TAP_SIZE_RSV); | ||
421 | usb_fill_bulk_urb(urb, rtlusb->udev, | ||
422 | usb_rcvbulkpipe(rtlusb->udev, rtlusb->in_ep), | ||
423 | skb->data, min(skb_tailroom(skb), | ||
424 | (int)rtlusb->rx_max_size), | ||
425 | _rtl_rx_completed, skb); | ||
426 | |||
427 | _rtl_install_trx_info(rtlusb, skb, rtlusb->in_ep); | ||
428 | return skb; | ||
429 | } | ||
430 | |||
431 | #undef __RADIO_TAP_SIZE_RSV | ||
432 | |||
433 | static void _rtl_usb_rx_process_agg(struct ieee80211_hw *hw, | ||
434 | struct sk_buff *skb) | ||
435 | { | ||
436 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
437 | u8 *rxdesc = skb->data; | ||
438 | struct ieee80211_hdr *hdr; | ||
439 | bool unicast = false; | ||
440 | __le16 fc; | ||
441 | struct ieee80211_rx_status rx_status = {0}; | ||
442 | struct rtl_stats stats = { | ||
443 | .signal = 0, | ||
444 | .noise = -98, | ||
445 | .rate = 0, | ||
446 | }; | ||
447 | |||
448 | skb_pull(skb, RTL_RX_DESC_SIZE); | ||
449 | rtlpriv->cfg->ops->query_rx_desc(hw, &stats, &rx_status, rxdesc, skb); | ||
450 | skb_pull(skb, (stats.rx_drvinfo_size + stats.rx_bufshift)); | ||
451 | hdr = (struct ieee80211_hdr *)(skb->data); | ||
452 | fc = hdr->frame_control; | ||
453 | if (!stats.crc) { | ||
454 | memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); | ||
455 | |||
456 | if (is_broadcast_ether_addr(hdr->addr1)) { | ||
457 | /*TODO*/; | ||
458 | } else if (is_multicast_ether_addr(hdr->addr1)) { | ||
459 | /*TODO*/ | ||
460 | } else { | ||
461 | unicast = true; | ||
462 | rtlpriv->stats.rxbytesunicast += skb->len; | ||
463 | } | ||
464 | |||
465 | rtl_is_special_data(hw, skb, false); | ||
466 | |||
467 | if (ieee80211_is_data(fc)) { | ||
468 | rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); | ||
469 | |||
470 | if (unicast) | ||
471 | rtlpriv->link_info.num_rx_inperiod++; | ||
472 | } | ||
473 | } | ||
474 | } | ||
475 | |||
476 | static void _rtl_usb_rx_process_noagg(struct ieee80211_hw *hw, | ||
477 | struct sk_buff *skb) | ||
478 | { | ||
479 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
480 | u8 *rxdesc = skb->data; | ||
481 | struct ieee80211_hdr *hdr; | ||
482 | bool unicast = false; | ||
483 | __le16 fc; | ||
484 | struct ieee80211_rx_status rx_status = {0}; | ||
485 | struct rtl_stats stats = { | ||
486 | .signal = 0, | ||
487 | .noise = -98, | ||
488 | .rate = 0, | ||
489 | }; | ||
490 | |||
491 | skb_pull(skb, RTL_RX_DESC_SIZE); | ||
492 | rtlpriv->cfg->ops->query_rx_desc(hw, &stats, &rx_status, rxdesc, skb); | ||
493 | skb_pull(skb, (stats.rx_drvinfo_size + stats.rx_bufshift)); | ||
494 | hdr = (struct ieee80211_hdr *)(skb->data); | ||
495 | fc = hdr->frame_control; | ||
496 | if (!stats.crc) { | ||
497 | memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); | ||
498 | |||
499 | if (is_broadcast_ether_addr(hdr->addr1)) { | ||
500 | /*TODO*/; | ||
501 | } else if (is_multicast_ether_addr(hdr->addr1)) { | ||
502 | /*TODO*/ | ||
503 | } else { | ||
504 | unicast = true; | ||
505 | rtlpriv->stats.rxbytesunicast += skb->len; | ||
506 | } | ||
507 | |||
508 | rtl_is_special_data(hw, skb, false); | ||
509 | |||
510 | if (ieee80211_is_data(fc)) { | ||
511 | rtlpriv->cfg->ops->led_control(hw, LED_CTL_RX); | ||
512 | |||
513 | if (unicast) | ||
514 | rtlpriv->link_info.num_rx_inperiod++; | ||
515 | } | ||
516 | if (likely(rtl_action_proc(hw, skb, false))) { | ||
517 | struct sk_buff *uskb = NULL; | ||
518 | u8 *pdata; | ||
519 | |||
520 | uskb = dev_alloc_skb(skb->len + 128); | ||
521 | memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status, | ||
522 | sizeof(rx_status)); | ||
523 | pdata = (u8 *)skb_put(uskb, skb->len); | ||
524 | memcpy(pdata, skb->data, skb->len); | ||
525 | dev_kfree_skb_any(skb); | ||
526 | ieee80211_rx_irqsafe(hw, uskb); | ||
527 | } else { | ||
528 | dev_kfree_skb_any(skb); | ||
529 | } | ||
530 | } | ||
531 | } | ||
532 | |||
533 | static void _rtl_rx_pre_process(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
534 | { | ||
535 | struct sk_buff *_skb; | ||
536 | struct sk_buff_head rx_queue; | ||
537 | struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); | ||
538 | |||
539 | skb_queue_head_init(&rx_queue); | ||
540 | if (rtlusb->usb_rx_segregate_hdl) | ||
541 | rtlusb->usb_rx_segregate_hdl(hw, skb, &rx_queue); | ||
542 | WARN_ON(skb_queue_empty(&rx_queue)); | ||
543 | while (!skb_queue_empty(&rx_queue)) { | ||
544 | _skb = skb_dequeue(&rx_queue); | ||
545 | _rtl_usb_rx_process_agg(hw, skb); | ||
546 | ieee80211_rx_irqsafe(hw, skb); | ||
547 | } | ||
548 | } | ||
549 | |||
550 | static void _rtl_rx_completed(struct urb *_urb) | ||
551 | { | ||
552 | struct sk_buff *skb = (struct sk_buff *)_urb->context; | ||
553 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
554 | struct rtl_usb *rtlusb = (struct rtl_usb *)info->rate_driver_data[0]; | ||
555 | struct ieee80211_hw *hw = usb_get_intfdata(rtlusb->intf); | ||
556 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
557 | int err = 0; | ||
558 | |||
559 | if (unlikely(IS_USB_STOP(rtlusb))) | ||
560 | goto free; | ||
561 | |||
562 | if (likely(0 == _urb->status)) { | ||
563 | /* If this code were moved to work queue, would CPU | ||
564 | * utilization be improved? NOTE: We shall allocate another skb | ||
565 | * and reuse the original one. | ||
566 | */ | ||
567 | skb_put(skb, _urb->actual_length); | ||
568 | |||
569 | if (likely(!rtlusb->usb_rx_segregate_hdl)) { | ||
570 | struct sk_buff *_skb; | ||
571 | _rtl_usb_rx_process_noagg(hw, skb); | ||
572 | _skb = _rtl_prep_rx_urb(hw, rtlusb, _urb, GFP_ATOMIC); | ||
573 | if (IS_ERR(_skb)) { | ||
574 | err = PTR_ERR(_skb); | ||
575 | RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, | ||
576 | ("Can't allocate skb for bulk IN!\n")); | ||
577 | return; | ||
578 | } | ||
579 | skb = _skb; | ||
580 | } else{ | ||
581 | /* TO DO */ | ||
582 | _rtl_rx_pre_process(hw, skb); | ||
583 | printk(KERN_ERR "rtlwifi: rx agg not supported\n"); | ||
584 | } | ||
585 | goto resubmit; | ||
586 | } | ||
587 | |||
588 | switch (_urb->status) { | ||
589 | /* disconnect */ | ||
590 | case -ENOENT: | ||
591 | case -ECONNRESET: | ||
592 | case -ENODEV: | ||
593 | case -ESHUTDOWN: | ||
594 | goto free; | ||
595 | default: | ||
596 | break; | ||
597 | } | ||
598 | |||
599 | resubmit: | ||
600 | skb_reset_tail_pointer(skb); | ||
601 | skb_trim(skb, 0); | ||
602 | |||
603 | usb_anchor_urb(_urb, &rtlusb->rx_submitted); | ||
604 | err = usb_submit_urb(_urb, GFP_ATOMIC); | ||
605 | if (unlikely(err)) { | ||
606 | usb_unanchor_urb(_urb); | ||
607 | goto free; | ||
608 | } | ||
609 | return; | ||
610 | |||
611 | free: | ||
612 | dev_kfree_skb_irq(skb); | ||
613 | } | ||
614 | |||
615 | static int _rtl_usb_receive(struct ieee80211_hw *hw) | ||
616 | { | ||
617 | struct urb *urb; | ||
618 | struct sk_buff *skb; | ||
619 | int err; | ||
620 | int i; | ||
621 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
622 | struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); | ||
623 | |||
624 | WARN_ON(0 == rtlusb->rx_urb_num); | ||
625 | /* 1600 == 1514 + max WLAN header + rtk info */ | ||
626 | WARN_ON(rtlusb->rx_max_size < 1600); | ||
627 | |||
628 | for (i = 0; i < rtlusb->rx_urb_num; i++) { | ||
629 | err = -ENOMEM; | ||
630 | urb = usb_alloc_urb(0, GFP_KERNEL); | ||
631 | if (!urb) { | ||
632 | RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, | ||
633 | ("Failed to alloc URB!!\n")) | ||
634 | goto err_out; | ||
635 | } | ||
636 | |||
637 | skb = _rtl_prep_rx_urb(hw, rtlusb, urb, GFP_KERNEL); | ||
638 | if (IS_ERR(skb)) { | ||
639 | RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, | ||
640 | ("Failed to prep_rx_urb!!\n")) | ||
641 | err = PTR_ERR(skb); | ||
642 | goto err_out; | ||
643 | } | ||
644 | |||
645 | usb_anchor_urb(urb, &rtlusb->rx_submitted); | ||
646 | err = usb_submit_urb(urb, GFP_KERNEL); | ||
647 | if (err) | ||
648 | goto err_out; | ||
649 | usb_free_urb(urb); | ||
650 | } | ||
651 | return 0; | ||
652 | |||
653 | err_out: | ||
654 | usb_kill_anchored_urbs(&rtlusb->rx_submitted); | ||
655 | return err; | ||
656 | } | ||
657 | |||
658 | static int rtl_usb_start(struct ieee80211_hw *hw) | ||
659 | { | ||
660 | int err; | ||
661 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
662 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
663 | struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); | ||
664 | |||
665 | err = rtlpriv->cfg->ops->hw_init(hw); | ||
666 | rtl_init_rx_config(hw); | ||
667 | |||
668 | /* Enable software */ | ||
669 | SET_USB_START(rtlusb); | ||
670 | /* should after adapter start and interrupt enable. */ | ||
671 | set_hal_start(rtlhal); | ||
672 | |||
673 | /* Start bulk IN */ | ||
674 | _rtl_usb_receive(hw); | ||
675 | |||
676 | return err; | ||
677 | } | ||
678 | /** | ||
679 | * | ||
680 | * | ||
681 | */ | ||
682 | |||
683 | /*======================= tx =========================================*/ | ||
684 | static void rtl_usb_cleanup(struct ieee80211_hw *hw) | ||
685 | { | ||
686 | u32 i; | ||
687 | struct sk_buff *_skb; | ||
688 | struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); | ||
689 | struct ieee80211_tx_info *txinfo; | ||
690 | |||
691 | SET_USB_STOP(rtlusb); | ||
692 | |||
693 | /* clean up rx stuff. */ | ||
694 | usb_kill_anchored_urbs(&rtlusb->rx_submitted); | ||
695 | |||
696 | /* clean up tx stuff */ | ||
697 | for (i = 0; i < RTL_USB_MAX_EP_NUM; i++) { | ||
698 | while ((_skb = skb_dequeue(&rtlusb->tx_skb_queue[i]))) { | ||
699 | rtlusb->usb_tx_cleanup(hw, _skb); | ||
700 | txinfo = IEEE80211_SKB_CB(_skb); | ||
701 | ieee80211_tx_info_clear_status(txinfo); | ||
702 | txinfo->flags |= IEEE80211_TX_STAT_ACK; | ||
703 | ieee80211_tx_status_irqsafe(hw, _skb); | ||
704 | } | ||
705 | usb_kill_anchored_urbs(&rtlusb->tx_pending[i]); | ||
706 | } | ||
707 | usb_kill_anchored_urbs(&rtlusb->tx_submitted); | ||
708 | } | ||
709 | |||
710 | /** | ||
711 | * | ||
712 | * We may add some struct into struct rtl_usb later. Do deinit here. | ||
713 | * | ||
714 | */ | ||
715 | static void rtl_usb_deinit(struct ieee80211_hw *hw) | ||
716 | { | ||
717 | rtl_usb_cleanup(hw); | ||
718 | } | ||
719 | |||
720 | static void rtl_usb_stop(struct ieee80211_hw *hw) | ||
721 | { | ||
722 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
723 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
724 | struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); | ||
725 | |||
726 | /* should after adapter start and interrupt enable. */ | ||
727 | set_hal_stop(rtlhal); | ||
728 | /* Enable software */ | ||
729 | SET_USB_STOP(rtlusb); | ||
730 | rtl_usb_deinit(hw); | ||
731 | rtlpriv->cfg->ops->hw_disable(hw); | ||
732 | } | ||
733 | |||
734 | static void _rtl_submit_tx_urb(struct ieee80211_hw *hw, struct urb *_urb) | ||
735 | { | ||
736 | int err; | ||
737 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
738 | struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); | ||
739 | |||
740 | usb_anchor_urb(_urb, &rtlusb->tx_submitted); | ||
741 | err = usb_submit_urb(_urb, GFP_ATOMIC); | ||
742 | if (err < 0) { | ||
743 | struct sk_buff *skb; | ||
744 | |||
745 | RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, | ||
746 | ("Failed to submit urb.\n")); | ||
747 | usb_unanchor_urb(_urb); | ||
748 | skb = (struct sk_buff *)_urb->context; | ||
749 | kfree_skb(skb); | ||
750 | } | ||
751 | usb_free_urb(_urb); | ||
752 | } | ||
753 | |||
754 | static int _usb_tx_post(struct ieee80211_hw *hw, struct urb *urb, | ||
755 | struct sk_buff *skb) | ||
756 | { | ||
757 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
758 | struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); | ||
759 | struct ieee80211_tx_info *txinfo; | ||
760 | |||
761 | rtlusb->usb_tx_post_hdl(hw, urb, skb); | ||
762 | skb_pull(skb, RTL_TX_HEADER_SIZE); | ||
763 | txinfo = IEEE80211_SKB_CB(skb); | ||
764 | ieee80211_tx_info_clear_status(txinfo); | ||
765 | txinfo->flags |= IEEE80211_TX_STAT_ACK; | ||
766 | |||
767 | if (urb->status) { | ||
768 | RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, | ||
769 | ("Urb has error status 0x%X\n", urb->status)); | ||
770 | goto out; | ||
771 | } | ||
772 | /* TODO: statistics */ | ||
773 | out: | ||
774 | ieee80211_tx_status_irqsafe(hw, skb); | ||
775 | return urb->status; | ||
776 | } | ||
777 | |||
778 | static void _rtl_tx_complete(struct urb *urb) | ||
779 | { | ||
780 | struct sk_buff *skb = (struct sk_buff *)urb->context; | ||
781 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
782 | struct rtl_usb *rtlusb = (struct rtl_usb *)info->rate_driver_data[0]; | ||
783 | struct ieee80211_hw *hw = usb_get_intfdata(rtlusb->intf); | ||
784 | int err; | ||
785 | |||
786 | if (unlikely(IS_USB_STOP(rtlusb))) | ||
787 | return; | ||
788 | err = _usb_tx_post(hw, urb, skb); | ||
789 | if (err) { | ||
790 | /* Ignore error and keep issuiing other urbs */ | ||
791 | return; | ||
792 | } | ||
793 | } | ||
794 | |||
795 | static struct urb *_rtl_usb_tx_urb_setup(struct ieee80211_hw *hw, | ||
796 | struct sk_buff *skb, u32 ep_num) | ||
797 | { | ||
798 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
799 | struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); | ||
800 | struct urb *_urb; | ||
801 | |||
802 | WARN_ON(NULL == skb); | ||
803 | _urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
804 | if (!_urb) { | ||
805 | RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, | ||
806 | ("Can't allocate URB for bulk out!\n")); | ||
807 | kfree_skb(skb); | ||
808 | return NULL; | ||
809 | } | ||
810 | _rtl_install_trx_info(rtlusb, skb, ep_num); | ||
811 | usb_fill_bulk_urb(_urb, rtlusb->udev, usb_sndbulkpipe(rtlusb->udev, | ||
812 | ep_num), skb->data, skb->len, _rtl_tx_complete, skb); | ||
813 | _urb->transfer_flags |= URB_ZERO_PACKET; | ||
814 | return _urb; | ||
815 | } | ||
816 | |||
817 | static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
818 | enum rtl_txq qnum) | ||
819 | { | ||
820 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
821 | struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); | ||
822 | u32 ep_num; | ||
823 | struct urb *_urb = NULL; | ||
824 | struct sk_buff *_skb = NULL; | ||
825 | struct sk_buff_head *skb_list; | ||
826 | struct usb_anchor *urb_list; | ||
827 | |||
828 | WARN_ON(NULL == rtlusb->usb_tx_aggregate_hdl); | ||
829 | if (unlikely(IS_USB_STOP(rtlusb))) { | ||
830 | RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, | ||
831 | ("USB device is stopping...\n")); | ||
832 | kfree_skb(skb); | ||
833 | return; | ||
834 | } | ||
835 | ep_num = rtlusb->ep_map.ep_mapping[qnum]; | ||
836 | skb_list = &rtlusb->tx_skb_queue[ep_num]; | ||
837 | _skb = skb; | ||
838 | _urb = _rtl_usb_tx_urb_setup(hw, _skb, ep_num); | ||
839 | if (unlikely(!_urb)) { | ||
840 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
841 | ("Can't allocate urb. Drop skb!\n")); | ||
842 | return; | ||
843 | } | ||
844 | urb_list = &rtlusb->tx_pending[ep_num]; | ||
845 | _rtl_submit_tx_urb(hw, _urb); | ||
846 | } | ||
847 | |||
848 | static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
849 | u16 hw_queue) | ||
850 | { | ||
851 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
852 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
853 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
854 | struct rtl_tx_desc *pdesc = NULL; | ||
855 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); | ||
856 | __le16 fc = hdr->frame_control; | ||
857 | u8 *pda_addr = hdr->addr1; | ||
858 | /* ssn */ | ||
859 | u8 *qc = NULL; | ||
860 | u8 tid = 0; | ||
861 | u16 seq_number = 0; | ||
862 | |||
863 | if (ieee80211_is_mgmt(fc)) | ||
864 | rtl_tx_mgmt_proc(hw, skb); | ||
865 | rtl_action_proc(hw, skb, true); | ||
866 | if (is_multicast_ether_addr(pda_addr)) | ||
867 | rtlpriv->stats.txbytesmulticast += skb->len; | ||
868 | else if (is_broadcast_ether_addr(pda_addr)) | ||
869 | rtlpriv->stats.txbytesbroadcast += skb->len; | ||
870 | else | ||
871 | rtlpriv->stats.txbytesunicast += skb->len; | ||
872 | if (ieee80211_is_data_qos(fc)) { | ||
873 | qc = ieee80211_get_qos_ctl(hdr); | ||
874 | tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; | ||
875 | seq_number = (le16_to_cpu(hdr->seq_ctrl) & | ||
876 | IEEE80211_SCTL_SEQ) >> 4; | ||
877 | seq_number += 1; | ||
878 | seq_number <<= 4; | ||
879 | } | ||
880 | rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *)pdesc, info, skb, | ||
881 | hw_queue); | ||
882 | if (!ieee80211_has_morefrags(hdr->frame_control)) { | ||
883 | if (qc) | ||
884 | mac->tids[tid].seq_number = seq_number; | ||
885 | } | ||
886 | if (ieee80211_is_data(fc)) | ||
887 | rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX); | ||
888 | } | ||
889 | |||
890 | static int rtl_usb_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
891 | { | ||
892 | struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); | ||
893 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
894 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); | ||
895 | __le16 fc = hdr->frame_control; | ||
896 | u16 hw_queue; | ||
897 | |||
898 | if (unlikely(is_hal_stop(rtlhal))) | ||
899 | goto err_free; | ||
900 | hw_queue = rtlusb->usb_mq_to_hwq(fc, skb_get_queue_mapping(skb)); | ||
901 | _rtl_usb_tx_preprocess(hw, skb, hw_queue); | ||
902 | _rtl_usb_transmit(hw, skb, hw_queue); | ||
903 | return NETDEV_TX_OK; | ||
904 | |||
905 | err_free: | ||
906 | dev_kfree_skb_any(skb); | ||
907 | return NETDEV_TX_OK; | ||
908 | } | ||
909 | |||
910 | static bool rtl_usb_tx_chk_waitq_insert(struct ieee80211_hw *hw, | ||
911 | struct sk_buff *skb) | ||
912 | { | ||
913 | return false; | ||
914 | } | ||
915 | |||
916 | static struct rtl_intf_ops rtl_usb_ops = { | ||
917 | .adapter_start = rtl_usb_start, | ||
918 | .adapter_stop = rtl_usb_stop, | ||
919 | .adapter_tx = rtl_usb_tx, | ||
920 | .waitq_insert = rtl_usb_tx_chk_waitq_insert, | ||
921 | }; | ||
922 | |||
923 | int __devinit rtl_usb_probe(struct usb_interface *intf, | ||
924 | const struct usb_device_id *id) | ||
925 | { | ||
926 | int err; | ||
927 | struct ieee80211_hw *hw = NULL; | ||
928 | struct rtl_priv *rtlpriv = NULL; | ||
929 | struct usb_device *udev; | ||
930 | struct rtl_usb_priv *usb_priv; | ||
931 | |||
932 | hw = ieee80211_alloc_hw(sizeof(struct rtl_priv) + | ||
933 | sizeof(struct rtl_usb_priv), &rtl_ops); | ||
934 | if (!hw) { | ||
935 | RT_ASSERT(false, ("%s : ieee80211 alloc failed\n", __func__)); | ||
936 | return -ENOMEM; | ||
937 | } | ||
938 | rtlpriv = hw->priv; | ||
939 | SET_IEEE80211_DEV(hw, &intf->dev); | ||
940 | udev = interface_to_usbdev(intf); | ||
941 | usb_get_dev(udev); | ||
942 | usb_priv = rtl_usbpriv(hw); | ||
943 | memset(usb_priv, 0, sizeof(*usb_priv)); | ||
944 | usb_priv->dev.intf = intf; | ||
945 | usb_priv->dev.udev = udev; | ||
946 | usb_set_intfdata(intf, hw); | ||
947 | /* init cfg & intf_ops */ | ||
948 | rtlpriv->rtlhal.interface = INTF_USB; | ||
949 | rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_info); | ||
950 | rtlpriv->intf_ops = &rtl_usb_ops; | ||
951 | rtl_dbgp_flag_init(hw); | ||
952 | /* Init IO handler */ | ||
953 | _rtl_usb_io_handler_init(&udev->dev, hw); | ||
954 | rtlpriv->cfg->ops->read_chip_version(hw); | ||
955 | /*like read eeprom and so on */ | ||
956 | rtlpriv->cfg->ops->read_eeprom_info(hw); | ||
957 | if (rtlpriv->cfg->ops->init_sw_vars(hw)) { | ||
958 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
959 | ("Can't init_sw_vars.\n")); | ||
960 | goto error_out; | ||
961 | } | ||
962 | rtlpriv->cfg->ops->init_sw_leds(hw); | ||
963 | err = _rtl_usb_init(hw); | ||
964 | err = _rtl_usb_init_sw(hw); | ||
965 | /* Init mac80211 sw */ | ||
966 | err = rtl_init_core(hw); | ||
967 | if (err) { | ||
968 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
969 | ("Can't allocate sw for mac80211.\n")); | ||
970 | goto error_out; | ||
971 | } | ||
972 | |||
973 | /*init rfkill */ | ||
974 | /* rtl_init_rfkill(hw); */ | ||
975 | |||
976 | err = ieee80211_register_hw(hw); | ||
977 | if (err) { | ||
978 | RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, | ||
979 | ("Can't register mac80211 hw.\n")); | ||
980 | goto error_out; | ||
981 | } else { | ||
982 | rtlpriv->mac80211.mac80211_registered = 1; | ||
983 | } | ||
984 | set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); | ||
985 | return 0; | ||
986 | error_out: | ||
987 | rtl_deinit_core(hw); | ||
988 | _rtl_usb_io_handler_release(hw); | ||
989 | ieee80211_free_hw(hw); | ||
990 | usb_put_dev(udev); | ||
991 | return -ENODEV; | ||
992 | } | ||
993 | EXPORT_SYMBOL(rtl_usb_probe); | ||
994 | |||
995 | void rtl_usb_disconnect(struct usb_interface *intf) | ||
996 | { | ||
997 | struct ieee80211_hw *hw = usb_get_intfdata(intf); | ||
998 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
999 | struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); | ||
1000 | struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); | ||
1001 | |||
1002 | if (unlikely(!rtlpriv)) | ||
1003 | return; | ||
1004 | /*ieee80211_unregister_hw will call ops_stop */ | ||
1005 | if (rtlmac->mac80211_registered == 1) { | ||
1006 | ieee80211_unregister_hw(hw); | ||
1007 | rtlmac->mac80211_registered = 0; | ||
1008 | } else { | ||
1009 | rtl_deinit_deferred_work(hw); | ||
1010 | rtlpriv->intf_ops->adapter_stop(hw); | ||
1011 | } | ||
1012 | /*deinit rfkill */ | ||
1013 | /* rtl_deinit_rfkill(hw); */ | ||
1014 | rtl_usb_deinit(hw); | ||
1015 | rtl_deinit_core(hw); | ||
1016 | rtlpriv->cfg->ops->deinit_sw_leds(hw); | ||
1017 | rtlpriv->cfg->ops->deinit_sw_vars(hw); | ||
1018 | _rtl_usb_io_handler_release(hw); | ||
1019 | usb_put_dev(rtlusb->udev); | ||
1020 | usb_set_intfdata(intf, NULL); | ||
1021 | ieee80211_free_hw(hw); | ||
1022 | } | ||
1023 | EXPORT_SYMBOL(rtl_usb_disconnect); | ||
1024 | |||
1025 | int rtl_usb_suspend(struct usb_interface *pusb_intf, pm_message_t message) | ||
1026 | { | ||
1027 | return 0; | ||
1028 | } | ||
1029 | EXPORT_SYMBOL(rtl_usb_suspend); | ||
1030 | |||
1031 | int rtl_usb_resume(struct usb_interface *pusb_intf) | ||
1032 | { | ||
1033 | return 0; | ||
1034 | } | ||
1035 | EXPORT_SYMBOL(rtl_usb_resume); | ||
diff --git a/drivers/net/wireless/rtlwifi/usb.h b/drivers/net/wireless/rtlwifi/usb.h new file mode 100644 index 000000000000..abadfe918d30 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/usb.h | |||
@@ -0,0 +1,164 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2011 Realtek Corporation. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | *****************************************************************************/ | ||
27 | |||
28 | #ifndef __RTL_USB_H__ | ||
29 | #define __RTL_USB_H__ | ||
30 | |||
31 | #include <linux/usb.h> | ||
32 | #include <linux/skbuff.h> | ||
33 | |||
34 | #define RTL_USB_DEVICE(vend, prod, cfg) \ | ||
35 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, \ | ||
36 | .idVendor = (vend), \ | ||
37 | .idProduct = (prod), \ | ||
38 | .driver_info = (kernel_ulong_t)&(cfg) | ||
39 | |||
40 | #define USB_HIGH_SPEED_BULK_SIZE 512 | ||
41 | #define USB_FULL_SPEED_BULK_SIZE 64 | ||
42 | |||
43 | |||
44 | #define RTL_USB_MAX_TXQ_NUM 4 /* max tx queue */ | ||
45 | #define RTL_USB_MAX_EP_NUM 6 /* max ep number */ | ||
46 | #define RTL_USB_MAX_TX_URBS_NUM 8 | ||
47 | |||
48 | enum rtl_txq { | ||
49 | /* These definitions shall be consistent with value | ||
50 | * returned by skb_get_queue_mapping | ||
51 | *------------------------------------*/ | ||
52 | RTL_TXQ_BK, | ||
53 | RTL_TXQ_BE, | ||
54 | RTL_TXQ_VI, | ||
55 | RTL_TXQ_VO, | ||
56 | /*------------------------------------*/ | ||
57 | RTL_TXQ_BCN, | ||
58 | RTL_TXQ_MGT, | ||
59 | RTL_TXQ_HI, | ||
60 | |||
61 | /* Must be last */ | ||
62 | __RTL_TXQ_NUM, | ||
63 | }; | ||
64 | |||
65 | struct rtl_ep_map { | ||
66 | u32 ep_mapping[__RTL_TXQ_NUM]; | ||
67 | }; | ||
68 | |||
69 | struct _trx_info { | ||
70 | struct rtl_usb *rtlusb; | ||
71 | u32 ep_num; | ||
72 | }; | ||
73 | |||
74 | static inline void _rtl_install_trx_info(struct rtl_usb *rtlusb, | ||
75 | struct sk_buff *skb, | ||
76 | u32 ep_num) | ||
77 | { | ||
78 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
79 | info->rate_driver_data[0] = rtlusb; | ||
80 | info->rate_driver_data[1] = (void *)(__kernel_size_t)ep_num; | ||
81 | } | ||
82 | |||
83 | |||
84 | /* Add suspend/resume later */ | ||
85 | enum rtl_usb_state { | ||
86 | USB_STATE_STOP = 0, | ||
87 | USB_STATE_START = 1, | ||
88 | }; | ||
89 | |||
90 | #define IS_USB_STOP(rtlusb_ptr) (USB_STATE_STOP == (rtlusb_ptr)->state) | ||
91 | #define IS_USB_START(rtlusb_ptr) (USB_STATE_START == (rtlusb_ptr)->state) | ||
92 | #define SET_USB_STOP(rtlusb_ptr) \ | ||
93 | do { \ | ||
94 | (rtlusb_ptr)->state = USB_STATE_STOP; \ | ||
95 | } while (0) | ||
96 | |||
97 | #define SET_USB_START(rtlusb_ptr) \ | ||
98 | do { \ | ||
99 | (rtlusb_ptr)->state = USB_STATE_START; \ | ||
100 | } while (0) | ||
101 | |||
102 | struct rtl_usb { | ||
103 | struct usb_device *udev; | ||
104 | struct usb_interface *intf; | ||
105 | enum rtl_usb_state state; | ||
106 | |||
107 | /* Bcn control register setting */ | ||
108 | u32 reg_bcn_ctrl_val; | ||
109 | /* for 88/92cu card disable */ | ||
110 | u8 disableHWSM; | ||
111 | /*QOS & EDCA */ | ||
112 | enum acm_method acm_method; | ||
113 | /* irq . HIMR,HIMR_EX */ | ||
114 | u32 irq_mask[2]; | ||
115 | bool irq_enabled; | ||
116 | |||
117 | u16 (*usb_mq_to_hwq)(__le16 fc, u16 mac80211_queue_index); | ||
118 | |||
119 | /* Tx */ | ||
120 | u8 out_ep_nums ; | ||
121 | u8 out_queue_sel; | ||
122 | struct rtl_ep_map ep_map; | ||
123 | |||
124 | u32 max_bulk_out_size; | ||
125 | u32 tx_submitted_urbs; | ||
126 | struct sk_buff_head tx_skb_queue[RTL_USB_MAX_EP_NUM]; | ||
127 | |||
128 | struct usb_anchor tx_pending[RTL_USB_MAX_EP_NUM]; | ||
129 | struct usb_anchor tx_submitted; | ||
130 | |||
131 | struct sk_buff *(*usb_tx_aggregate_hdl)(struct ieee80211_hw *, | ||
132 | struct sk_buff_head *); | ||
133 | int (*usb_tx_post_hdl)(struct ieee80211_hw *, | ||
134 | struct urb *, struct sk_buff *); | ||
135 | void (*usb_tx_cleanup)(struct ieee80211_hw *, struct sk_buff *); | ||
136 | |||
137 | /* Rx */ | ||
138 | u8 in_ep_nums ; | ||
139 | u32 in_ep; /* Bulk IN endpoint number */ | ||
140 | u32 rx_max_size; /* Bulk IN max buffer size */ | ||
141 | u32 rx_urb_num; /* How many Bulk INs are submitted to host. */ | ||
142 | struct usb_anchor rx_submitted; | ||
143 | void (*usb_rx_segregate_hdl)(struct ieee80211_hw *, struct sk_buff *, | ||
144 | struct sk_buff_head *); | ||
145 | void (*usb_rx_hdl)(struct ieee80211_hw *, struct sk_buff *); | ||
146 | }; | ||
147 | |||
148 | struct rtl_usb_priv { | ||
149 | struct rtl_usb dev; | ||
150 | struct rtl_led_ctl ledctl; | ||
151 | }; | ||
152 | |||
153 | #define rtl_usbpriv(hw) (((struct rtl_usb_priv *)(rtl_priv(hw))->priv)) | ||
154 | #define rtl_usbdev(usbpriv) (&((usbpriv)->dev)) | ||
155 | |||
156 | |||
157 | |||
158 | int __devinit rtl_usb_probe(struct usb_interface *intf, | ||
159 | const struct usb_device_id *id); | ||
160 | void rtl_usb_disconnect(struct usb_interface *intf); | ||
161 | int rtl_usb_suspend(struct usb_interface *pusb_intf, pm_message_t message); | ||
162 | int rtl_usb_resume(struct usb_interface *pusb_intf); | ||
163 | |||
164 | #endif | ||
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index d44d79613d2d..4b90b35f211e 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/firmware.h> | 34 | #include <linux/firmware.h> |
35 | #include <linux/version.h> | 35 | #include <linux/version.h> |
36 | #include <linux/etherdevice.h> | 36 | #include <linux/etherdevice.h> |
37 | #include <linux/usb.h> | ||
37 | #include <net/mac80211.h> | 38 | #include <net/mac80211.h> |
38 | #include "debug.h" | 39 | #include "debug.h" |
39 | 40 | ||
@@ -82,6 +83,19 @@ | |||
82 | #define MAC80211_3ADDR_LEN 24 | 83 | #define MAC80211_3ADDR_LEN 24 |
83 | #define MAC80211_4ADDR_LEN 30 | 84 | #define MAC80211_4ADDR_LEN 30 |
84 | 85 | ||
86 | #define CHANNEL_MAX_NUMBER (14 + 24 + 21) /* 14 is the max channel no */ | ||
87 | #define CHANNEL_GROUP_MAX (3 + 9) /* ch1~3, 4~9, 10~14 = three groups */ | ||
88 | #define MAX_PG_GROUP 13 | ||
89 | #define CHANNEL_GROUP_MAX_2G 3 | ||
90 | #define CHANNEL_GROUP_IDX_5GL 3 | ||
91 | #define CHANNEL_GROUP_IDX_5GM 6 | ||
92 | #define CHANNEL_GROUP_IDX_5GH 9 | ||
93 | #define CHANNEL_GROUP_MAX_5G 9 | ||
94 | #define CHANNEL_MAX_NUMBER_2G 14 | ||
95 | #define AVG_THERMAL_NUM 8 | ||
96 | |||
97 | /* for early mode */ | ||
98 | #define EM_HDR_LEN 8 | ||
85 | enum intf_type { | 99 | enum intf_type { |
86 | INTF_PCI = 0, | 100 | INTF_PCI = 0, |
87 | INTF_USB = 1, | 101 | INTF_USB = 1, |
@@ -113,11 +127,38 @@ enum hardware_type { | |||
113 | HARDWARE_TYPE_RTL8192CU, | 127 | HARDWARE_TYPE_RTL8192CU, |
114 | HARDWARE_TYPE_RTL8192DE, | 128 | HARDWARE_TYPE_RTL8192DE, |
115 | HARDWARE_TYPE_RTL8192DU, | 129 | HARDWARE_TYPE_RTL8192DU, |
130 | HARDWARE_TYPE_RTL8723E, | ||
131 | HARDWARE_TYPE_RTL8723U, | ||
116 | 132 | ||
117 | /*keep it last*/ | 133 | /* keep it last */ |
118 | HARDWARE_TYPE_NUM | 134 | HARDWARE_TYPE_NUM |
119 | }; | 135 | }; |
120 | 136 | ||
137 | #define IS_HARDWARE_TYPE_8192SU(rtlhal) \ | ||
138 | (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SU) | ||
139 | #define IS_HARDWARE_TYPE_8192SE(rtlhal) \ | ||
140 | (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) | ||
141 | #define IS_HARDWARE_TYPE_8192CE(rtlhal) \ | ||
142 | (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE) | ||
143 | #define IS_HARDWARE_TYPE_8192CU(rtlhal) \ | ||
144 | (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CU) | ||
145 | #define IS_HARDWARE_TYPE_8192DE(rtlhal) \ | ||
146 | (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE) | ||
147 | #define IS_HARDWARE_TYPE_8192DU(rtlhal) \ | ||
148 | (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DU) | ||
149 | #define IS_HARDWARE_TYPE_8723E(rtlhal) \ | ||
150 | (rtlhal->hw_type == HARDWARE_TYPE_RTL8723E) | ||
151 | #define IS_HARDWARE_TYPE_8723U(rtlhal) \ | ||
152 | (rtlhal->hw_type == HARDWARE_TYPE_RTL8723U) | ||
153 | #define IS_HARDWARE_TYPE_8192S(rtlhal) \ | ||
154 | (IS_HARDWARE_TYPE_8192SE(rtlhal) || IS_HARDWARE_TYPE_8192SU(rtlhal)) | ||
155 | #define IS_HARDWARE_TYPE_8192C(rtlhal) \ | ||
156 | (IS_HARDWARE_TYPE_8192CE(rtlhal) || IS_HARDWARE_TYPE_8192CU(rtlhal)) | ||
157 | #define IS_HARDWARE_TYPE_8192D(rtlhal) \ | ||
158 | (IS_HARDWARE_TYPE_8192DE(rtlhal) || IS_HARDWARE_TYPE_8192DU(rtlhal)) | ||
159 | #define IS_HARDWARE_TYPE_8723(rtlhal) \ | ||
160 | (IS_HARDWARE_TYPE_8723E(rtlhal) || IS_HARDWARE_TYPE_8723U(rtlhal)) | ||
161 | |||
121 | enum scan_operation_backup_opt { | 162 | enum scan_operation_backup_opt { |
122 | SCAN_OPT_BACKUP = 0, | 163 | SCAN_OPT_BACKUP = 0, |
123 | SCAN_OPT_RESTORE, | 164 | SCAN_OPT_RESTORE, |
@@ -315,6 +356,7 @@ enum rf_type { | |||
315 | RF_1T1R = 0, | 356 | RF_1T1R = 0, |
316 | RF_1T2R = 1, | 357 | RF_1T2R = 1, |
317 | RF_2T2R = 2, | 358 | RF_2T2R = 2, |
359 | RF_2T2R_GREEN = 3, | ||
318 | }; | 360 | }; |
319 | 361 | ||
320 | enum ht_channel_width { | 362 | enum ht_channel_width { |
@@ -359,6 +401,8 @@ enum rtl_var_map { | |||
359 | EFUSE_LOADER_CLK_EN, | 401 | EFUSE_LOADER_CLK_EN, |
360 | EFUSE_ANA8M, | 402 | EFUSE_ANA8M, |
361 | EFUSE_HWSET_MAX_SIZE, | 403 | EFUSE_HWSET_MAX_SIZE, |
404 | EFUSE_MAX_SECTION_MAP, | ||
405 | EFUSE_REAL_CONTENT_SIZE, | ||
362 | 406 | ||
363 | /*CAM map */ | 407 | /*CAM map */ |
364 | RWCAM, | 408 | RWCAM, |
@@ -397,6 +441,7 @@ enum rtl_var_map { | |||
397 | RTL_IMR_ATIMEND, /*For 92C,ATIM Window End Interrupt */ | 441 | RTL_IMR_ATIMEND, /*For 92C,ATIM Window End Interrupt */ |
398 | RTL_IMR_BDOK, /*Beacon Queue DMA OK Interrup */ | 442 | RTL_IMR_BDOK, /*Beacon Queue DMA OK Interrup */ |
399 | RTL_IMR_HIGHDOK, /*High Queue DMA OK Interrupt */ | 443 | RTL_IMR_HIGHDOK, /*High Queue DMA OK Interrupt */ |
444 | RTL_IMR_COMDOK, /*Command Queue DMA OK Interrupt*/ | ||
400 | RTL_IMR_TBDOK, /*Transmit Beacon OK interrup */ | 445 | RTL_IMR_TBDOK, /*Transmit Beacon OK interrup */ |
401 | RTL_IMR_MGNTDOK, /*Management Queue DMA OK Interrupt */ | 446 | RTL_IMR_MGNTDOK, /*Management Queue DMA OK Interrupt */ |
402 | RTL_IMR_TBDER, /*For 92C,Transmit Beacon Error Interrupt */ | 447 | RTL_IMR_TBDER, /*For 92C,Transmit Beacon Error Interrupt */ |
@@ -405,7 +450,8 @@ enum rtl_var_map { | |||
405 | RTL_IMR_VIDOK, /*AC_VI DMA OK Interrupt */ | 450 | RTL_IMR_VIDOK, /*AC_VI DMA OK Interrupt */ |
406 | RTL_IMR_VODOK, /*AC_VO DMA Interrupt */ | 451 | RTL_IMR_VODOK, /*AC_VO DMA Interrupt */ |
407 | RTL_IMR_ROK, /*Receive DMA OK Interrupt */ | 452 | RTL_IMR_ROK, /*Receive DMA OK Interrupt */ |
408 | RTL_IBSS_INT_MASKS, /*(RTL_IMR_BcnInt|RTL_IMR_TBDOK|RTL_IMR_TBDER)*/ | 453 | RTL_IBSS_INT_MASKS, /*(RTL_IMR_BcnInt | RTL_IMR_TBDOK | |
454 | * RTL_IMR_TBDER) */ | ||
409 | 455 | ||
410 | /*CCK Rates, TxHT = 0 */ | 456 | /*CCK Rates, TxHT = 0 */ |
411 | RTL_RC_CCK_RATE1M, | 457 | RTL_RC_CCK_RATE1M, |
@@ -481,6 +527,19 @@ enum acm_method { | |||
481 | eAcmWay2_SW = 2, | 527 | eAcmWay2_SW = 2, |
482 | }; | 528 | }; |
483 | 529 | ||
530 | enum macphy_mode { | ||
531 | SINGLEMAC_SINGLEPHY = 0, | ||
532 | DUALMAC_DUALPHY, | ||
533 | DUALMAC_SINGLEPHY, | ||
534 | }; | ||
535 | |||
536 | enum band_type { | ||
537 | BAND_ON_2_4G = 0, | ||
538 | BAND_ON_5G, | ||
539 | BAND_ON_BOTH, | ||
540 | BANDMAX | ||
541 | }; | ||
542 | |||
484 | /*aci/aifsn Field. | 543 | /*aci/aifsn Field. |
485 | Ref: WMM spec 2.2.2: WME Parameter Element, p.12.*/ | 544 | Ref: WMM spec 2.2.2: WME Parameter Element, p.12.*/ |
486 | union aci_aifsn { | 545 | union aci_aifsn { |
@@ -505,6 +564,17 @@ enum wireless_mode { | |||
505 | WIRELESS_MODE_N_5G = 0x20 | 564 | WIRELESS_MODE_N_5G = 0x20 |
506 | }; | 565 | }; |
507 | 566 | ||
567 | #define IS_WIRELESS_MODE_A(wirelessmode) \ | ||
568 | (wirelessmode == WIRELESS_MODE_A) | ||
569 | #define IS_WIRELESS_MODE_B(wirelessmode) \ | ||
570 | (wirelessmode == WIRELESS_MODE_B) | ||
571 | #define IS_WIRELESS_MODE_G(wirelessmode) \ | ||
572 | (wirelessmode == WIRELESS_MODE_G) | ||
573 | #define IS_WIRELESS_MODE_N_24G(wirelessmode) \ | ||
574 | (wirelessmode == WIRELESS_MODE_N_24G) | ||
575 | #define IS_WIRELESS_MODE_N_5G(wirelessmode) \ | ||
576 | (wirelessmode == WIRELESS_MODE_N_5G) | ||
577 | |||
508 | enum ratr_table_mode { | 578 | enum ratr_table_mode { |
509 | RATR_INX_WIRELESS_NGB = 0, | 579 | RATR_INX_WIRELESS_NGB = 0, |
510 | RATR_INX_WIRELESS_NG = 1, | 580 | RATR_INX_WIRELESS_NG = 1, |
@@ -574,11 +644,11 @@ struct rtl_probe_rsp { | |||
574 | struct rtl_led { | 644 | struct rtl_led { |
575 | void *hw; | 645 | void *hw; |
576 | enum rtl_led_pin ledpin; | 646 | enum rtl_led_pin ledpin; |
577 | bool b_ledon; | 647 | bool ledon; |
578 | }; | 648 | }; |
579 | 649 | ||
580 | struct rtl_led_ctl { | 650 | struct rtl_led_ctl { |
581 | bool bled_opendrain; | 651 | bool led_opendrain; |
582 | struct rtl_led sw_led0; | 652 | struct rtl_led sw_led0; |
583 | struct rtl_led sw_led1; | 653 | struct rtl_led sw_led1; |
584 | }; | 654 | }; |
@@ -603,6 +673,8 @@ struct false_alarm_statistics { | |||
603 | u32 cnt_rate_illegal; | 673 | u32 cnt_rate_illegal; |
604 | u32 cnt_crc8_fail; | 674 | u32 cnt_crc8_fail; |
605 | u32 cnt_mcs_fail; | 675 | u32 cnt_mcs_fail; |
676 | u32 cnt_fast_fsync_fail; | ||
677 | u32 cnt_sb_search_fail; | ||
606 | u32 cnt_ofdm_fail; | 678 | u32 cnt_ofdm_fail; |
607 | u32 cnt_cck_fail; | 679 | u32 cnt_cck_fail; |
608 | u32 cnt_all; | 680 | u32 cnt_all; |
@@ -690,6 +762,32 @@ struct rtl_rfkill { | |||
690 | bool rfkill_state; /*0 is off, 1 is on */ | 762 | bool rfkill_state; /*0 is off, 1 is on */ |
691 | }; | 763 | }; |
692 | 764 | ||
765 | #define IQK_MATRIX_REG_NUM 8 | ||
766 | #define IQK_MATRIX_SETTINGS_NUM (1 + 24 + 21) | ||
767 | struct iqk_matrix_regs { | ||
768 | bool b_iqk_done; | ||
769 | long value[1][IQK_MATRIX_REG_NUM]; | ||
770 | }; | ||
771 | |||
772 | struct phy_parameters { | ||
773 | u16 length; | ||
774 | u32 *pdata; | ||
775 | }; | ||
776 | |||
777 | enum hw_param_tab_index { | ||
778 | PHY_REG_2T, | ||
779 | PHY_REG_1T, | ||
780 | PHY_REG_PG, | ||
781 | RADIOA_2T, | ||
782 | RADIOB_2T, | ||
783 | RADIOA_1T, | ||
784 | RADIOB_1T, | ||
785 | MAC_REG, | ||
786 | AGCTAB_2T, | ||
787 | AGCTAB_1T, | ||
788 | MAX_TAB | ||
789 | }; | ||
790 | |||
693 | struct rtl_phy { | 791 | struct rtl_phy { |
694 | struct bb_reg_def phyreg_def[4]; /*Radio A/B/C/D */ | 792 | struct bb_reg_def phyreg_def[4]; /*Radio A/B/C/D */ |
695 | struct init_gain initgain_backup; | 793 | struct init_gain initgain_backup; |
@@ -705,8 +803,9 @@ struct rtl_phy { | |||
705 | u8 current_channel; | 803 | u8 current_channel; |
706 | u8 h2c_box_num; | 804 | u8 h2c_box_num; |
707 | u8 set_io_inprogress; | 805 | u8 set_io_inprogress; |
806 | u8 lck_inprogress; | ||
708 | 807 | ||
709 | /*record for power tracking*/ | 808 | /* record for power tracking */ |
710 | s32 reg_e94; | 809 | s32 reg_e94; |
711 | s32 reg_e9c; | 810 | s32 reg_e9c; |
712 | s32 reg_ea4; | 811 | s32 reg_ea4; |
@@ -723,26 +822,32 @@ struct rtl_phy { | |||
723 | u32 iqk_mac_backup[IQK_MAC_REG_NUM]; | 822 | u32 iqk_mac_backup[IQK_MAC_REG_NUM]; |
724 | u32 iqk_bb_backup[10]; | 823 | u32 iqk_bb_backup[10]; |
725 | 824 | ||
726 | bool b_rfpi_enable; | 825 | /* Dual mac */ |
826 | bool need_iqk; | ||
827 | struct iqk_matrix_regs iqk_matrix_regsetting[IQK_MATRIX_SETTINGS_NUM]; | ||
828 | |||
829 | bool rfpi_enable; | ||
727 | 830 | ||
728 | u8 pwrgroup_cnt; | 831 | u8 pwrgroup_cnt; |
729 | u8 bcck_high_power; | 832 | u8 cck_high_power; |
730 | /* 3 groups of pwr diff by rates*/ | 833 | /* MAX_PG_GROUP groups of pwr diff by rates */ |
731 | u32 mcs_txpwrlevel_origoffset[4][16]; | 834 | u32 mcs_txpwrlevel_origoffset[MAX_PG_GROUP][16]; |
732 | u8 default_initialgain[4]; | 835 | u8 default_initialgain[4]; |
733 | 836 | ||
734 | /*the current Tx power level*/ | 837 | /* the current Tx power level */ |
735 | u8 cur_cck_txpwridx; | 838 | u8 cur_cck_txpwridx; |
736 | u8 cur_ofdm24g_txpwridx; | 839 | u8 cur_ofdm24g_txpwridx; |
737 | 840 | ||
738 | u32 rfreg_chnlval[2]; | 841 | u32 rfreg_chnlval[2]; |
739 | bool b_apk_done; | 842 | bool apk_done; |
843 | u32 reg_rf3c[2]; /* pathA / pathB */ | ||
740 | 844 | ||
741 | /*fsync*/ | ||
742 | u8 framesync; | 845 | u8 framesync; |
743 | u32 framesync_c34; | 846 | u32 framesync_c34; |
744 | 847 | ||
745 | u8 num_total_rfpath; | 848 | u8 num_total_rfpath; |
849 | struct phy_parameters hwparam_tables[MAX_TAB]; | ||
850 | u16 rf_pathmap; | ||
746 | }; | 851 | }; |
747 | 852 | ||
748 | #define MAX_TID_COUNT 9 | 853 | #define MAX_TID_COUNT 9 |
@@ -768,6 +873,7 @@ struct rtl_tid_data { | |||
768 | struct rtl_priv; | 873 | struct rtl_priv; |
769 | struct rtl_io { | 874 | struct rtl_io { |
770 | struct device *dev; | 875 | struct device *dev; |
876 | struct mutex bb_mutex; | ||
771 | 877 | ||
772 | /*PCI MEM map */ | 878 | /*PCI MEM map */ |
773 | unsigned long pci_mem_end; /*shared mem end */ | 879 | unsigned long pci_mem_end; /*shared mem end */ |
@@ -779,11 +885,14 @@ struct rtl_io { | |||
779 | void (*write8_async) (struct rtl_priv *rtlpriv, u32 addr, u8 val); | 885 | void (*write8_async) (struct rtl_priv *rtlpriv, u32 addr, u8 val); |
780 | void (*write16_async) (struct rtl_priv *rtlpriv, u32 addr, u16 val); | 886 | void (*write16_async) (struct rtl_priv *rtlpriv, u32 addr, u16 val); |
781 | void (*write32_async) (struct rtl_priv *rtlpriv, u32 addr, u32 val); | 887 | void (*write32_async) (struct rtl_priv *rtlpriv, u32 addr, u32 val); |
782 | 888 | int (*writeN_async) (struct rtl_priv *rtlpriv, u32 addr, u16 len, | |
783 | u8(*read8_sync) (struct rtl_priv *rtlpriv, u32 addr); | 889 | u8 *pdata); |
784 | u16(*read16_sync) (struct rtl_priv *rtlpriv, u32 addr); | 890 | |
785 | u32(*read32_sync) (struct rtl_priv *rtlpriv, u32 addr); | 891 | u8(*read8_sync) (struct rtl_priv *rtlpriv, u32 addr); |
786 | 892 | u16(*read16_sync) (struct rtl_priv *rtlpriv, u32 addr); | |
893 | u32(*read32_sync) (struct rtl_priv *rtlpriv, u32 addr); | ||
894 | int (*readN_sync) (struct rtl_priv *rtlpriv, u32 addr, u16 len, | ||
895 | u8 *pdata); | ||
787 | }; | 896 | }; |
788 | 897 | ||
789 | struct rtl_mac { | 898 | struct rtl_mac { |
@@ -815,16 +924,24 @@ struct rtl_mac { | |||
815 | bool act_scanning; | 924 | bool act_scanning; |
816 | u8 cnt_after_linked; | 925 | u8 cnt_after_linked; |
817 | 926 | ||
818 | /*RDG*/ bool rdg_en; | 927 | /* early mode */ |
928 | /* skb wait queue */ | ||
929 | struct sk_buff_head skb_waitq[MAX_TID_COUNT]; | ||
930 | u8 earlymode_threshold; | ||
931 | |||
932 | /*RDG*/ | ||
933 | bool rdg_en; | ||
819 | 934 | ||
820 | /*AP*/ u8 bssid[6]; | 935 | /*AP*/ |
821 | u8 mcs[16]; /*16 bytes mcs for HT rates.*/ | 936 | u8 bssid[6]; |
822 | u32 basic_rates; /*b/g rates*/ | 937 | u32 vendor; |
938 | u8 mcs[16]; /* 16 bytes mcs for HT rates. */ | ||
939 | u32 basic_rates; /* b/g rates */ | ||
823 | u8 ht_enable; | 940 | u8 ht_enable; |
824 | u8 sgi_40; | 941 | u8 sgi_40; |
825 | u8 sgi_20; | 942 | u8 sgi_20; |
826 | u8 bw_40; | 943 | u8 bw_40; |
827 | u8 mode; /*wireless mode*/ | 944 | u8 mode; /* wireless mode */ |
828 | u8 slot_time; | 945 | u8 slot_time; |
829 | u8 short_preamble; | 946 | u8 short_preamble; |
830 | u8 use_cts_protect; | 947 | u8 use_cts_protect; |
@@ -835,9 +952,11 @@ struct rtl_mac { | |||
835 | u8 retry_long; | 952 | u8 retry_long; |
836 | u16 assoc_id; | 953 | u16 assoc_id; |
837 | 954 | ||
838 | /*IBSS*/ int beacon_interval; | 955 | /*IBSS*/ |
956 | int beacon_interval; | ||
839 | 957 | ||
840 | /*AMPDU*/ u8 min_space_cfg; /*For Min spacing configurations */ | 958 | /*AMPDU*/ |
959 | u8 min_space_cfg; /*For Min spacing configurations */ | ||
841 | u8 max_mss_density; | 960 | u8 max_mss_density; |
842 | u8 current_ampdu_factor; | 961 | u8 current_ampdu_factor; |
843 | u8 current_ampdu_density; | 962 | u8 current_ampdu_density; |
@@ -852,17 +971,54 @@ struct rtl_hal { | |||
852 | 971 | ||
853 | enum intf_type interface; | 972 | enum intf_type interface; |
854 | u16 hw_type; /*92c or 92d or 92s and so on */ | 973 | u16 hw_type; /*92c or 92d or 92s and so on */ |
974 | u8 ic_class; | ||
855 | u8 oem_id; | 975 | u8 oem_id; |
856 | u8 version; /*version of chip */ | 976 | u32 version; /*version of chip */ |
857 | u8 state; /*stop 0, start 1 */ | 977 | u8 state; /*stop 0, start 1 */ |
858 | 978 | ||
859 | /*firmware */ | 979 | /*firmware */ |
980 | u32 fwsize; | ||
860 | u8 *pfirmware; | 981 | u8 *pfirmware; |
861 | bool b_h2c_setinprogress; | 982 | u16 fw_version; |
983 | u16 fw_subversion; | ||
984 | bool h2c_setinprogress; | ||
862 | u8 last_hmeboxnum; | 985 | u8 last_hmeboxnum; |
863 | bool bfw_ready; | 986 | bool fw_ready; |
864 | /*Reserve page start offset except beacon in TxQ. */ | 987 | /*Reserve page start offset except beacon in TxQ. */ |
865 | u8 fw_rsvdpage_startoffset; | 988 | u8 fw_rsvdpage_startoffset; |
989 | u8 h2c_txcmd_seq; | ||
990 | |||
991 | /* FW Cmd IO related */ | ||
992 | u16 fwcmd_iomap; | ||
993 | u32 fwcmd_ioparam; | ||
994 | bool set_fwcmd_inprogress; | ||
995 | u8 current_fwcmd_io; | ||
996 | |||
997 | /**/ | ||
998 | bool driver_going2unload; | ||
999 | |||
1000 | /*AMPDU init min space*/ | ||
1001 | u8 minspace_cfg; /*For Min spacing configurations */ | ||
1002 | |||
1003 | /* Dual mac */ | ||
1004 | enum macphy_mode macphymode; | ||
1005 | enum band_type current_bandtype; /* 0:2.4G, 1:5G */ | ||
1006 | enum band_type current_bandtypebackup; | ||
1007 | enum band_type bandset; | ||
1008 | /* dual MAC 0--Mac0 1--Mac1 */ | ||
1009 | u32 interfaceindex; | ||
1010 | /* just for DualMac S3S4 */ | ||
1011 | u8 macphyctl_reg; | ||
1012 | bool earlymode_enable; | ||
1013 | /* Dual mac*/ | ||
1014 | bool during_mac0init_radiob; | ||
1015 | bool during_mac1init_radioa; | ||
1016 | bool reloadtxpowerindex; | ||
1017 | /* True if IMR or IQK have done | ||
1018 | for 2.4G in scan progress */ | ||
1019 | bool load_imrandiqk_setting_for2g; | ||
1020 | |||
1021 | bool disable_amsdu_8k; | ||
866 | }; | 1022 | }; |
867 | 1023 | ||
868 | struct rtl_security { | 1024 | struct rtl_security { |
@@ -887,48 +1043,61 @@ struct rtl_security { | |||
887 | }; | 1043 | }; |
888 | 1044 | ||
889 | struct rtl_dm { | 1045 | struct rtl_dm { |
890 | /*PHY status for DM */ | 1046 | /*PHY status for Dynamic Management */ |
891 | long entry_min_undecoratedsmoothed_pwdb; | 1047 | long entry_min_undecoratedsmoothed_pwdb; |
892 | long undecorated_smoothed_pwdb; /*out dm */ | 1048 | long undecorated_smoothed_pwdb; /*out dm */ |
893 | long entry_max_undecoratedsmoothed_pwdb; | 1049 | long entry_max_undecoratedsmoothed_pwdb; |
894 | bool b_dm_initialgain_enable; | 1050 | bool dm_initialgain_enable; |
895 | bool bdynamic_txpower_enable; | 1051 | bool dynamic_txpower_enable; |
896 | bool bcurrent_turbo_edca; | 1052 | bool current_turbo_edca; |
897 | bool bis_any_nonbepkts; /*out dm */ | 1053 | bool is_any_nonbepkts; /*out dm */ |
898 | bool bis_cur_rdlstate; | 1054 | bool is_cur_rdlstate; |
899 | bool btxpower_trackingInit; | 1055 | bool txpower_trackingInit; |
900 | bool b_disable_framebursting; | 1056 | bool disable_framebursting; |
901 | bool b_cck_inch14; | 1057 | bool cck_inch14; |
902 | bool btxpower_tracking; | 1058 | bool txpower_tracking; |
903 | bool b_useramask; | 1059 | bool useramask; |
904 | bool brfpath_rxenable[4]; | 1060 | bool rfpath_rxenable[4]; |
905 | 1061 | bool inform_fw_driverctrldm; | |
1062 | bool current_mrc_switch; | ||
1063 | u8 txpowercount; | ||
1064 | |||
1065 | u8 thermalvalue_rxgain; | ||
906 | u8 thermalvalue_iqk; | 1066 | u8 thermalvalue_iqk; |
907 | u8 thermalvalue_lck; | 1067 | u8 thermalvalue_lck; |
908 | u8 thermalvalue; | 1068 | u8 thermalvalue; |
909 | u8 last_dtp_lvl; | 1069 | u8 last_dtp_lvl; |
1070 | u8 thermalvalue_avg[AVG_THERMAL_NUM]; | ||
1071 | u8 thermalvalue_avg_index; | ||
1072 | bool done_txpower; | ||
910 | u8 dynamic_txhighpower_lvl; /*Tx high power level */ | 1073 | u8 dynamic_txhighpower_lvl; /*Tx high power level */ |
911 | u8 dm_flag; /*Indicate if each dynamic mechanism's status. */ | 1074 | u8 dm_flag; /*Indicate each dynamic mechanism's status. */ |
912 | u8 dm_type; | 1075 | u8 dm_type; |
913 | u8 txpower_track_control; | 1076 | u8 txpower_track_control; |
914 | 1077 | bool interrupt_migration; | |
1078 | bool disable_tx_int; | ||
915 | char ofdm_index[2]; | 1079 | char ofdm_index[2]; |
916 | char cck_index; | 1080 | char cck_index; |
1081 | u8 power_index_backup[6]; | ||
917 | }; | 1082 | }; |
918 | 1083 | ||
919 | #define EFUSE_MAX_LOGICAL_SIZE 128 | 1084 | #define EFUSE_MAX_LOGICAL_SIZE 256 |
920 | 1085 | ||
921 | struct rtl_efuse { | 1086 | struct rtl_efuse { |
922 | bool bautoLoad_ok; | 1087 | bool autoLoad_ok; |
923 | bool bootfromefuse; | 1088 | bool bootfromefuse; |
924 | u16 max_physical_size; | 1089 | u16 max_physical_size; |
925 | u8 contents[EFUSE_MAX_LOGICAL_SIZE]; | ||
926 | 1090 | ||
927 | u8 efuse_map[2][EFUSE_MAX_LOGICAL_SIZE]; | 1091 | u8 efuse_map[2][EFUSE_MAX_LOGICAL_SIZE]; |
928 | u16 efuse_usedbytes; | 1092 | u16 efuse_usedbytes; |
929 | u8 efuse_usedpercentage; | 1093 | u8 efuse_usedpercentage; |
1094 | #ifdef EFUSE_REPG_WORKAROUND | ||
1095 | bool efuse_re_pg_sec1flag; | ||
1096 | u8 efuse_re_pg_data[8]; | ||
1097 | #endif | ||
930 | 1098 | ||
931 | u8 autoload_failflag; | 1099 | u8 autoload_failflag; |
1100 | u8 autoload_status; | ||
932 | 1101 | ||
933 | short epromtype; | 1102 | short epromtype; |
934 | u16 eeprom_vid; | 1103 | u16 eeprom_vid; |
@@ -938,69 +1107,90 @@ struct rtl_efuse { | |||
938 | u8 eeprom_oemid; | 1107 | u8 eeprom_oemid; |
939 | u16 eeprom_channelplan; | 1108 | u16 eeprom_channelplan; |
940 | u8 eeprom_version; | 1109 | u8 eeprom_version; |
1110 | u8 board_type; | ||
1111 | u8 external_pa; | ||
941 | 1112 | ||
942 | u8 dev_addr[6]; | 1113 | u8 dev_addr[6]; |
943 | 1114 | ||
944 | bool b_txpwr_fromeprom; | 1115 | bool txpwr_fromeprom; |
1116 | u8 eeprom_crystalcap; | ||
945 | u8 eeprom_tssi[2]; | 1117 | u8 eeprom_tssi[2]; |
946 | u8 eeprom_pwrlimit_ht20[3]; | 1118 | u8 eeprom_tssi_5g[3][2]; /* for 5GL/5GM/5GH band. */ |
947 | u8 eeprom_pwrlimit_ht40[3]; | 1119 | u8 eeprom_pwrlimit_ht20[CHANNEL_GROUP_MAX]; |
948 | u8 eeprom_chnlarea_txpwr_cck[2][3]; | 1120 | u8 eeprom_pwrlimit_ht40[CHANNEL_GROUP_MAX]; |
949 | u8 eeprom_chnlarea_txpwr_ht40_1s[2][3]; | 1121 | u8 eeprom_chnlarea_txpwr_cck[2][CHANNEL_GROUP_MAX_2G]; |
950 | u8 eeprom_chnlarea_txpwr_ht40_2sdiif[2][3]; | 1122 | u8 eeprom_chnlarea_txpwr_ht40_1s[2][CHANNEL_GROUP_MAX]; |
951 | u8 txpwrlevel_cck[2][14]; | 1123 | u8 eeprom_chnlarea_txpwr_ht40_2sdiif[2][CHANNEL_GROUP_MAX]; |
952 | u8 txpwrlevel_ht40_1s[2][14]; /*For HT 40MHZ pwr */ | 1124 | u8 txpwrlevel_cck[2][CHANNEL_MAX_NUMBER_2G]; |
953 | u8 txpwrlevel_ht40_2s[2][14]; /*For HT 40MHZ pwr */ | 1125 | u8 txpwrlevel_ht40_1s[2][CHANNEL_MAX_NUMBER]; /*For HT 40MHZ pwr */ |
1126 | u8 txpwrlevel_ht40_2s[2][CHANNEL_MAX_NUMBER]; /*For HT 40MHZ pwr */ | ||
1127 | |||
1128 | u8 internal_pa_5g[2]; /* pathA / pathB */ | ||
1129 | u8 eeprom_c9; | ||
1130 | u8 eeprom_cc; | ||
954 | 1131 | ||
955 | /*For power group */ | 1132 | /*For power group */ |
956 | u8 pwrgroup_ht20[2][14]; | 1133 | u8 eeprom_pwrgroup[2][3]; |
957 | u8 pwrgroup_ht40[2][14]; | 1134 | u8 pwrgroup_ht20[2][CHANNEL_MAX_NUMBER]; |
958 | 1135 | u8 pwrgroup_ht40[2][CHANNEL_MAX_NUMBER]; | |
959 | char txpwr_ht20diff[2][14]; /*HT 20<->40 Pwr diff */ | 1136 | |
960 | u8 txpwr_legacyhtdiff[2][14]; /*For HT<->legacy pwr diff */ | 1137 | char txpwr_ht20diff[2][CHANNEL_MAX_NUMBER]; /*HT 20<->40 Pwr diff */ |
1138 | /*For HT<->legacy pwr diff*/ | ||
1139 | u8 txpwr_legacyhtdiff[2][CHANNEL_MAX_NUMBER]; | ||
1140 | u8 txpwr_safetyflag; /* Band edge enable flag */ | ||
1141 | u16 eeprom_txpowerdiff; | ||
1142 | u8 legacy_httxpowerdiff; /* Legacy to HT rate power diff */ | ||
1143 | u8 antenna_txpwdiff[3]; | ||
961 | 1144 | ||
962 | u8 eeprom_regulatory; | 1145 | u8 eeprom_regulatory; |
963 | u8 eeprom_thermalmeter; | 1146 | u8 eeprom_thermalmeter; |
964 | /*ThermalMeter, index 0 for RFIC0, and 1 for RFIC1 */ | 1147 | u8 thermalmeter[2]; /*ThermalMeter, index 0 for RFIC0, 1 for RFIC1 */ |
965 | u8 thermalmeter[2]; | 1148 | u16 tssi_13dbm; |
1149 | u8 crystalcap; /* CrystalCap. */ | ||
1150 | u8 delta_iqk; | ||
1151 | u8 delta_lck; | ||
966 | 1152 | ||
967 | u8 legacy_ht_txpowerdiff; /*Legacy to HT rate power diff */ | 1153 | u8 legacy_ht_txpowerdiff; /*Legacy to HT rate power diff */ |
968 | bool b_apk_thermalmeterignore; | 1154 | bool apk_thermalmeterignore; |
1155 | |||
1156 | bool b1x1_recvcombine; | ||
1157 | bool b1ss_support; | ||
1158 | |||
1159 | /*channel plan */ | ||
1160 | u8 channel_plan; | ||
969 | }; | 1161 | }; |
970 | 1162 | ||
971 | struct rtl_ps_ctl { | 1163 | struct rtl_ps_ctl { |
1164 | bool pwrdomain_protect; | ||
972 | bool set_rfpowerstate_inprogress; | 1165 | bool set_rfpowerstate_inprogress; |
973 | bool b_in_powersavemode; | 1166 | bool in_powersavemode; |
974 | bool rfchange_inprogress; | 1167 | bool rfchange_inprogress; |
975 | bool b_swrf_processing; | 1168 | bool swrf_processing; |
976 | bool b_hwradiooff; | 1169 | bool hwradiooff; |
977 | |||
978 | u32 last_sleep_jiffies; | ||
979 | u32 last_awake_jiffies; | ||
980 | u32 last_delaylps_stamp_jiffies; | ||
981 | 1170 | ||
982 | /* | 1171 | /* |
983 | * just for PCIE ASPM | 1172 | * just for PCIE ASPM |
984 | * If it supports ASPM, Offset[560h] = 0x40, | 1173 | * If it supports ASPM, Offset[560h] = 0x40, |
985 | * otherwise Offset[560h] = 0x00. | 1174 | * otherwise Offset[560h] = 0x00. |
986 | * */ | 1175 | * */ |
987 | bool b_support_aspm; | 1176 | bool support_aspm; |
988 | bool b_support_backdoor; | 1177 | bool support_backdoor; |
989 | 1178 | ||
990 | /*for LPS */ | 1179 | /*for LPS */ |
991 | enum rt_psmode dot11_psmode; /*Power save mode configured. */ | 1180 | enum rt_psmode dot11_psmode; /*Power save mode configured. */ |
992 | bool b_leisure_ps; | 1181 | bool swctrl_lps; |
993 | bool b_fwctrl_lps; | 1182 | bool leisure_ps; |
1183 | bool fwctrl_lps; | ||
994 | u8 fwctrl_psmode; | 1184 | u8 fwctrl_psmode; |
995 | /*For Fw control LPS mode */ | 1185 | /*For Fw control LPS mode */ |
996 | u8 b_reg_fwctrl_lps; | 1186 | u8 reg_fwctrl_lps; |
997 | /*Record Fw PS mode status. */ | 1187 | /*Record Fw PS mode status. */ |
998 | bool b_fw_current_inpsmode; | 1188 | bool fw_current_inpsmode; |
999 | u8 reg_max_lps_awakeintvl; | 1189 | u8 reg_max_lps_awakeintvl; |
1000 | bool report_linked; | 1190 | bool report_linked; |
1001 | 1191 | ||
1002 | /*for IPS */ | 1192 | /*for IPS */ |
1003 | bool b_inactiveps; | 1193 | bool inactiveps; |
1004 | 1194 | ||
1005 | u32 rfoff_reason; | 1195 | u32 rfoff_reason; |
1006 | 1196 | ||
@@ -1011,8 +1201,26 @@ struct rtl_ps_ctl { | |||
1011 | /*just for PCIE ASPM */ | 1201 | /*just for PCIE ASPM */ |
1012 | u8 const_amdpci_aspm; | 1202 | u8 const_amdpci_aspm; |
1013 | 1203 | ||
1204 | bool pwrdown_mode; | ||
1205 | |||
1014 | enum rf_pwrstate inactive_pwrstate; | 1206 | enum rf_pwrstate inactive_pwrstate; |
1015 | enum rf_pwrstate rfpwr_state; /*cur power state */ | 1207 | enum rf_pwrstate rfpwr_state; /*cur power state */ |
1208 | |||
1209 | /* for SW LPS*/ | ||
1210 | bool sw_ps_enabled; | ||
1211 | bool state; | ||
1212 | bool state_inap; | ||
1213 | bool multi_buffered; | ||
1214 | u16 nullfunc_seq; | ||
1215 | unsigned int dtim_counter; | ||
1216 | unsigned int sleep_ms; | ||
1217 | unsigned long last_sleep_jiffies; | ||
1218 | unsigned long last_awake_jiffies; | ||
1219 | unsigned long last_delaylps_stamp_jiffies; | ||
1220 | unsigned long last_dtim; | ||
1221 | unsigned long last_beacon; | ||
1222 | unsigned long last_action; | ||
1223 | unsigned long last_slept; | ||
1016 | }; | 1224 | }; |
1017 | 1225 | ||
1018 | struct rtl_stats { | 1226 | struct rtl_stats { |
@@ -1038,10 +1246,10 @@ struct rtl_stats { | |||
1038 | s32 recvsignalpower; | 1246 | s32 recvsignalpower; |
1039 | s8 rxpower; /*in dBm Translate from PWdB */ | 1247 | s8 rxpower; /*in dBm Translate from PWdB */ |
1040 | u8 signalstrength; /*in 0-100 index. */ | 1248 | u8 signalstrength; /*in 0-100 index. */ |
1041 | u16 b_hwerror:1; | 1249 | u16 hwerror:1; |
1042 | u16 b_crc:1; | 1250 | u16 crc:1; |
1043 | u16 b_icv:1; | 1251 | u16 icv:1; |
1044 | u16 b_shortpreamble:1; | 1252 | u16 shortpreamble:1; |
1045 | u16 antenna:1; | 1253 | u16 antenna:1; |
1046 | u16 decrypted:1; | 1254 | u16 decrypted:1; |
1047 | u16 wakeup:1; | 1255 | u16 wakeup:1; |
@@ -1050,15 +1258,16 @@ struct rtl_stats { | |||
1050 | 1258 | ||
1051 | u8 rx_drvinfo_size; | 1259 | u8 rx_drvinfo_size; |
1052 | u8 rx_bufshift; | 1260 | u8 rx_bufshift; |
1053 | bool b_isampdu; | 1261 | bool isampdu; |
1262 | bool isfirst_ampdu; | ||
1054 | bool rx_is40Mhzpacket; | 1263 | bool rx_is40Mhzpacket; |
1055 | u32 rx_pwdb_all; | 1264 | u32 rx_pwdb_all; |
1056 | u8 rx_mimo_signalstrength[4]; /*in 0~100 index */ | 1265 | u8 rx_mimo_signalstrength[4]; /*in 0~100 index */ |
1057 | s8 rx_mimo_signalquality[2]; | 1266 | s8 rx_mimo_signalquality[2]; |
1058 | bool b_packet_matchbssid; | 1267 | bool packet_matchbssid; |
1059 | bool b_is_cck; | 1268 | bool is_cck; |
1060 | bool b_packet_toself; | 1269 | bool packet_toself; |
1061 | bool b_packet_beacon; /*for rssi */ | 1270 | bool packet_beacon; /*for rssi */ |
1062 | char cck_adc_pwdb[4]; /*for rx path selection */ | 1271 | char cck_adc_pwdb[4]; /*for rx path selection */ |
1063 | }; | 1272 | }; |
1064 | 1273 | ||
@@ -1069,23 +1278,23 @@ struct rt_link_detect { | |||
1069 | u32 num_tx_inperiod; | 1278 | u32 num_tx_inperiod; |
1070 | u32 num_rx_inperiod; | 1279 | u32 num_rx_inperiod; |
1071 | 1280 | ||
1072 | bool b_busytraffic; | 1281 | bool busytraffic; |
1073 | bool b_higher_busytraffic; | 1282 | bool higher_busytraffic; |
1074 | bool b_higher_busyrxtraffic; | 1283 | bool higher_busyrxtraffic; |
1075 | }; | 1284 | }; |
1076 | 1285 | ||
1077 | struct rtl_tcb_desc { | 1286 | struct rtl_tcb_desc { |
1078 | u8 b_packet_bw:1; | 1287 | u8 packet_bw:1; |
1079 | u8 b_multicast:1; | 1288 | u8 multicast:1; |
1080 | u8 b_broadcast:1; | 1289 | u8 broadcast:1; |
1081 | 1290 | ||
1082 | u8 b_rts_stbc:1; | 1291 | u8 rts_stbc:1; |
1083 | u8 b_rts_enable:1; | 1292 | u8 rts_enable:1; |
1084 | u8 b_cts_enable:1; | 1293 | u8 cts_enable:1; |
1085 | u8 b_rts_use_shortpreamble:1; | 1294 | u8 rts_use_shortpreamble:1; |
1086 | u8 b_rts_use_shortgi:1; | 1295 | u8 rts_use_shortgi:1; |
1087 | u8 rts_sc:1; | 1296 | u8 rts_sc:1; |
1088 | u8 b_rts_bw:1; | 1297 | u8 rts_bw:1; |
1089 | u8 rts_rate; | 1298 | u8 rts_rate; |
1090 | 1299 | ||
1091 | u8 use_shortgi:1; | 1300 | u8 use_shortgi:1; |
@@ -1096,20 +1305,34 @@ struct rtl_tcb_desc { | |||
1096 | u8 ratr_index; | 1305 | u8 ratr_index; |
1097 | u8 mac_id; | 1306 | u8 mac_id; |
1098 | u8 hw_rate; | 1307 | u8 hw_rate; |
1308 | |||
1309 | u8 last_inipkt:1; | ||
1310 | u8 cmd_or_init:1; | ||
1311 | u8 queue_index; | ||
1312 | |||
1313 | /* early mode */ | ||
1314 | u8 empkt_num; | ||
1315 | /* The max value by HW */ | ||
1316 | u32 empkt_len[5]; | ||
1099 | }; | 1317 | }; |
1100 | 1318 | ||
1101 | struct rtl_hal_ops { | 1319 | struct rtl_hal_ops { |
1102 | int (*init_sw_vars) (struct ieee80211_hw *hw); | 1320 | int (*init_sw_vars) (struct ieee80211_hw *hw); |
1103 | void (*deinit_sw_vars) (struct ieee80211_hw *hw); | 1321 | void (*deinit_sw_vars) (struct ieee80211_hw *hw); |
1322 | void (*read_chip_version)(struct ieee80211_hw *hw); | ||
1104 | void (*read_eeprom_info) (struct ieee80211_hw *hw); | 1323 | void (*read_eeprom_info) (struct ieee80211_hw *hw); |
1105 | void (*interrupt_recognized) (struct ieee80211_hw *hw, | 1324 | void (*interrupt_recognized) (struct ieee80211_hw *hw, |
1106 | u32 *p_inta, u32 *p_intb); | 1325 | u32 *p_inta, u32 *p_intb); |
1107 | int (*hw_init) (struct ieee80211_hw *hw); | 1326 | int (*hw_init) (struct ieee80211_hw *hw); |
1108 | void (*hw_disable) (struct ieee80211_hw *hw); | 1327 | void (*hw_disable) (struct ieee80211_hw *hw); |
1328 | void (*hw_suspend) (struct ieee80211_hw *hw); | ||
1329 | void (*hw_resume) (struct ieee80211_hw *hw); | ||
1109 | void (*enable_interrupt) (struct ieee80211_hw *hw); | 1330 | void (*enable_interrupt) (struct ieee80211_hw *hw); |
1110 | void (*disable_interrupt) (struct ieee80211_hw *hw); | 1331 | void (*disable_interrupt) (struct ieee80211_hw *hw); |
1111 | int (*set_network_type) (struct ieee80211_hw *hw, | 1332 | int (*set_network_type) (struct ieee80211_hw *hw, |
1112 | enum nl80211_iftype type); | 1333 | enum nl80211_iftype type); |
1334 | void (*set_chk_bssid)(struct ieee80211_hw *hw, | ||
1335 | bool check_bssid); | ||
1113 | void (*set_bw_mode) (struct ieee80211_hw *hw, | 1336 | void (*set_bw_mode) (struct ieee80211_hw *hw, |
1114 | enum nl80211_channel_type ch_type); | 1337 | enum nl80211_channel_type ch_type); |
1115 | u8(*switch_channel) (struct ieee80211_hw *hw); | 1338 | u8(*switch_channel) (struct ieee80211_hw *hw); |
@@ -1126,23 +1349,26 @@ struct rtl_hal_ops { | |||
1126 | struct ieee80211_hdr *hdr, u8 *pdesc_tx, | 1349 | struct ieee80211_hdr *hdr, u8 *pdesc_tx, |
1127 | struct ieee80211_tx_info *info, | 1350 | struct ieee80211_tx_info *info, |
1128 | struct sk_buff *skb, unsigned int queue_index); | 1351 | struct sk_buff *skb, unsigned int queue_index); |
1352 | void (*fill_fake_txdesc) (struct ieee80211_hw *hw, u8 * pDesc, | ||
1353 | u32 buffer_len, bool bIsPsPoll); | ||
1129 | void (*fill_tx_cmddesc) (struct ieee80211_hw *hw, u8 *pdesc, | 1354 | void (*fill_tx_cmddesc) (struct ieee80211_hw *hw, u8 *pdesc, |
1130 | bool b_firstseg, bool b_lastseg, | 1355 | bool firstseg, bool lastseg, |
1131 | struct sk_buff *skb); | 1356 | struct sk_buff *skb); |
1132 | bool(*query_rx_desc) (struct ieee80211_hw *hw, | 1357 | bool (*cmd_send_packet)(struct ieee80211_hw *hw, struct sk_buff *skb); |
1358 | bool (*query_rx_desc) (struct ieee80211_hw *hw, | ||
1133 | struct rtl_stats *stats, | 1359 | struct rtl_stats *stats, |
1134 | struct ieee80211_rx_status *rx_status, | 1360 | struct ieee80211_rx_status *rx_status, |
1135 | u8 *pdesc, struct sk_buff *skb); | 1361 | u8 *pdesc, struct sk_buff *skb); |
1136 | void (*set_channel_access) (struct ieee80211_hw *hw); | 1362 | void (*set_channel_access) (struct ieee80211_hw *hw); |
1137 | bool(*radio_onoff_checking) (struct ieee80211_hw *hw, u8 *valid); | 1363 | bool (*radio_onoff_checking) (struct ieee80211_hw *hw, u8 *valid); |
1138 | void (*dm_watchdog) (struct ieee80211_hw *hw); | 1364 | void (*dm_watchdog) (struct ieee80211_hw *hw); |
1139 | void (*scan_operation_backup) (struct ieee80211_hw *hw, u8 operation); | 1365 | void (*scan_operation_backup) (struct ieee80211_hw *hw, u8 operation); |
1140 | bool(*set_rf_power_state) (struct ieee80211_hw *hw, | 1366 | bool (*set_rf_power_state) (struct ieee80211_hw *hw, |
1141 | enum rf_pwrstate rfpwr_state); | 1367 | enum rf_pwrstate rfpwr_state); |
1142 | void (*led_control) (struct ieee80211_hw *hw, | 1368 | void (*led_control) (struct ieee80211_hw *hw, |
1143 | enum led_ctl_mode ledaction); | 1369 | enum led_ctl_mode ledaction); |
1144 | void (*set_desc) (u8 *pdesc, bool istx, u8 desc_name, u8 *val); | 1370 | void (*set_desc) (u8 *pdesc, bool istx, u8 desc_name, u8 *val); |
1145 | u32(*get_desc) (u8 *pdesc, bool istx, u8 desc_name); | 1371 | u32 (*get_desc) (u8 *pdesc, bool istx, u8 desc_name); |
1146 | void (*tx_polling) (struct ieee80211_hw *hw, unsigned int hw_queue); | 1372 | void (*tx_polling) (struct ieee80211_hw *hw, unsigned int hw_queue); |
1147 | void (*enable_hw_sec) (struct ieee80211_hw *hw); | 1373 | void (*enable_hw_sec) (struct ieee80211_hw *hw); |
1148 | void (*set_key) (struct ieee80211_hw *hw, u32 key_index, | 1374 | void (*set_key) (struct ieee80211_hw *hw, u32 key_index, |
@@ -1150,10 +1376,10 @@ struct rtl_hal_ops { | |||
1150 | bool is_wepkey, bool clear_all); | 1376 | bool is_wepkey, bool clear_all); |
1151 | void (*init_sw_leds) (struct ieee80211_hw *hw); | 1377 | void (*init_sw_leds) (struct ieee80211_hw *hw); |
1152 | void (*deinit_sw_leds) (struct ieee80211_hw *hw); | 1378 | void (*deinit_sw_leds) (struct ieee80211_hw *hw); |
1153 | u32(*get_bbreg) (struct ieee80211_hw *hw, u32 regaddr, u32 bitmask); | 1379 | u32 (*get_bbreg) (struct ieee80211_hw *hw, u32 regaddr, u32 bitmask); |
1154 | void (*set_bbreg) (struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, | 1380 | void (*set_bbreg) (struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, |
1155 | u32 data); | 1381 | u32 data); |
1156 | u32(*get_rfreg) (struct ieee80211_hw *hw, enum radio_path rfpath, | 1382 | u32 (*get_rfreg) (struct ieee80211_hw *hw, enum radio_path rfpath, |
1157 | u32 regaddr, u32 bitmask); | 1383 | u32 regaddr, u32 bitmask); |
1158 | void (*set_rfreg) (struct ieee80211_hw *hw, enum radio_path rfpath, | 1384 | void (*set_rfreg) (struct ieee80211_hw *hw, enum radio_path rfpath, |
1159 | u32 regaddr, u32 bitmask, u32 data); | 1385 | u32 regaddr, u32 bitmask, u32 data); |
@@ -1161,11 +1387,13 @@ struct rtl_hal_ops { | |||
1161 | 1387 | ||
1162 | struct rtl_intf_ops { | 1388 | struct rtl_intf_ops { |
1163 | /*com */ | 1389 | /*com */ |
1390 | void (*read_efuse_byte)(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf); | ||
1164 | int (*adapter_start) (struct ieee80211_hw *hw); | 1391 | int (*adapter_start) (struct ieee80211_hw *hw); |
1165 | void (*adapter_stop) (struct ieee80211_hw *hw); | 1392 | void (*adapter_stop) (struct ieee80211_hw *hw); |
1166 | 1393 | ||
1167 | int (*adapter_tx) (struct ieee80211_hw *hw, struct sk_buff *skb); | 1394 | int (*adapter_tx) (struct ieee80211_hw *hw, struct sk_buff *skb); |
1168 | int (*reset_trx_ring) (struct ieee80211_hw *hw); | 1395 | int (*reset_trx_ring) (struct ieee80211_hw *hw); |
1396 | bool (*waitq_insert) (struct ieee80211_hw *hw, struct sk_buff *skb); | ||
1169 | 1397 | ||
1170 | /*pci */ | 1398 | /*pci */ |
1171 | void (*disable_aspm) (struct ieee80211_hw *hw); | 1399 | void (*disable_aspm) (struct ieee80211_hw *hw); |
@@ -1179,11 +1407,36 @@ struct rtl_mod_params { | |||
1179 | int sw_crypto; | 1407 | int sw_crypto; |
1180 | }; | 1408 | }; |
1181 | 1409 | ||
1410 | struct rtl_hal_usbint_cfg { | ||
1411 | /* data - rx */ | ||
1412 | u32 in_ep_num; | ||
1413 | u32 rx_urb_num; | ||
1414 | u32 rx_max_size; | ||
1415 | |||
1416 | /* op - rx */ | ||
1417 | void (*usb_rx_hdl)(struct ieee80211_hw *, struct sk_buff *); | ||
1418 | void (*usb_rx_segregate_hdl)(struct ieee80211_hw *, struct sk_buff *, | ||
1419 | struct sk_buff_head *); | ||
1420 | |||
1421 | /* tx */ | ||
1422 | void (*usb_tx_cleanup)(struct ieee80211_hw *, struct sk_buff *); | ||
1423 | int (*usb_tx_post_hdl)(struct ieee80211_hw *, struct urb *, | ||
1424 | struct sk_buff *); | ||
1425 | struct sk_buff *(*usb_tx_aggregate_hdl)(struct ieee80211_hw *, | ||
1426 | struct sk_buff_head *); | ||
1427 | |||
1428 | /* endpoint mapping */ | ||
1429 | int (*usb_endpoint_mapping)(struct ieee80211_hw *hw); | ||
1430 | u16 (*usb_mq_to_hwq)(__le16 fc, u16 mac80211_queue_index); | ||
1431 | }; | ||
1432 | |||
1182 | struct rtl_hal_cfg { | 1433 | struct rtl_hal_cfg { |
1434 | u8 bar_id; | ||
1183 | char *name; | 1435 | char *name; |
1184 | char *fw_name; | 1436 | char *fw_name; |
1185 | struct rtl_hal_ops *ops; | 1437 | struct rtl_hal_ops *ops; |
1186 | struct rtl_mod_params *mod_params; | 1438 | struct rtl_mod_params *mod_params; |
1439 | struct rtl_hal_usbint_cfg *usb_interface_cfg; | ||
1187 | 1440 | ||
1188 | /*this map used for some registers or vars | 1441 | /*this map used for some registers or vars |
1189 | defined int HAL but used in MAIN */ | 1442 | defined int HAL but used in MAIN */ |
@@ -1202,6 +1455,11 @@ struct rtl_locks { | |||
1202 | spinlock_t rf_ps_lock; | 1455 | spinlock_t rf_ps_lock; |
1203 | spinlock_t rf_lock; | 1456 | spinlock_t rf_lock; |
1204 | spinlock_t lps_lock; | 1457 | spinlock_t lps_lock; |
1458 | spinlock_t waitq_lock; | ||
1459 | spinlock_t tx_urb_lock; | ||
1460 | |||
1461 | /*Dual mac*/ | ||
1462 | spinlock_t cck_and_rw_pagea_lock; | ||
1205 | }; | 1463 | }; |
1206 | 1464 | ||
1207 | struct rtl_works { | 1465 | struct rtl_works { |
@@ -1218,12 +1476,20 @@ struct rtl_works { | |||
1218 | struct workqueue_struct *rtl_wq; | 1476 | struct workqueue_struct *rtl_wq; |
1219 | struct delayed_work watchdog_wq; | 1477 | struct delayed_work watchdog_wq; |
1220 | struct delayed_work ips_nic_off_wq; | 1478 | struct delayed_work ips_nic_off_wq; |
1479 | |||
1480 | /* For SW LPS */ | ||
1481 | struct delayed_work ps_work; | ||
1482 | struct delayed_work ps_rfon_wq; | ||
1221 | }; | 1483 | }; |
1222 | 1484 | ||
1223 | struct rtl_debug { | 1485 | struct rtl_debug { |
1224 | u32 dbgp_type[DBGP_TYPE_MAX]; | 1486 | u32 dbgp_type[DBGP_TYPE_MAX]; |
1225 | u32 global_debuglevel; | 1487 | u32 global_debuglevel; |
1226 | u64 global_debugcomponents; | 1488 | u64 global_debugcomponents; |
1489 | |||
1490 | /* add for proc debug */ | ||
1491 | struct proc_dir_entry *proc_dir; | ||
1492 | char proc_name[20]; | ||
1227 | }; | 1493 | }; |
1228 | 1494 | ||
1229 | struct rtl_priv { | 1495 | struct rtl_priv { |
@@ -1274,6 +1540,91 @@ struct rtl_priv { | |||
1274 | #define rtl_efuse(rtlpriv) (&((rtlpriv)->efuse)) | 1540 | #define rtl_efuse(rtlpriv) (&((rtlpriv)->efuse)) |
1275 | #define rtl_psc(rtlpriv) (&((rtlpriv)->psc)) | 1541 | #define rtl_psc(rtlpriv) (&((rtlpriv)->psc)) |
1276 | 1542 | ||
1543 | |||
1544 | /*************************************** | ||
1545 | Bluetooth Co-existance Related | ||
1546 | ****************************************/ | ||
1547 | |||
1548 | enum bt_ant_num { | ||
1549 | ANT_X2 = 0, | ||
1550 | ANT_X1 = 1, | ||
1551 | }; | ||
1552 | |||
1553 | enum bt_co_type { | ||
1554 | BT_2WIRE = 0, | ||
1555 | BT_ISSC_3WIRE = 1, | ||
1556 | BT_ACCEL = 2, | ||
1557 | BT_CSR_BC4 = 3, | ||
1558 | BT_CSR_BC8 = 4, | ||
1559 | BT_RTL8756 = 5, | ||
1560 | }; | ||
1561 | |||
1562 | enum bt_cur_state { | ||
1563 | BT_OFF = 0, | ||
1564 | BT_ON = 1, | ||
1565 | }; | ||
1566 | |||
1567 | enum bt_service_type { | ||
1568 | BT_SCO = 0, | ||
1569 | BT_A2DP = 1, | ||
1570 | BT_HID = 2, | ||
1571 | BT_HID_IDLE = 3, | ||
1572 | BT_SCAN = 4, | ||
1573 | BT_IDLE = 5, | ||
1574 | BT_OTHER_ACTION = 6, | ||
1575 | BT_BUSY = 7, | ||
1576 | BT_OTHERBUSY = 8, | ||
1577 | BT_PAN = 9, | ||
1578 | }; | ||
1579 | |||
1580 | enum bt_radio_shared { | ||
1581 | BT_RADIO_SHARED = 0, | ||
1582 | BT_RADIO_INDIVIDUAL = 1, | ||
1583 | }; | ||
1584 | |||
1585 | struct bt_coexist_info { | ||
1586 | |||
1587 | /* EEPROM BT info. */ | ||
1588 | u8 eeprom_bt_coexist; | ||
1589 | u8 eeprom_bt_type; | ||
1590 | u8 eeprom_bt_ant_num; | ||
1591 | u8 eeprom_bt_ant_isolation; | ||
1592 | u8 eeprom_bt_radio_shared; | ||
1593 | |||
1594 | u8 bt_coexistence; | ||
1595 | u8 bt_ant_num; | ||
1596 | u8 bt_coexist_type; | ||
1597 | u8 bt_state; | ||
1598 | u8 bt_cur_state; /* 0:on, 1:off */ | ||
1599 | u8 bt_ant_isolation; /* 0:good, 1:bad */ | ||
1600 | u8 bt_pape_ctrl; /* 0:SW, 1:SW/HW dynamic */ | ||
1601 | u8 bt_service; | ||
1602 | u8 bt_radio_shared_type; | ||
1603 | u8 bt_rfreg_origin_1e; | ||
1604 | u8 bt_rfreg_origin_1f; | ||
1605 | u8 bt_rssi_state; | ||
1606 | u32 ratio_tx; | ||
1607 | u32 ratio_pri; | ||
1608 | u32 bt_edca_ul; | ||
1609 | u32 bt_edca_dl; | ||
1610 | |||
1611 | bool b_init_set; | ||
1612 | bool b_bt_busy_traffic; | ||
1613 | bool b_bt_traffic_mode_set; | ||
1614 | bool b_bt_non_traffic_mode_set; | ||
1615 | |||
1616 | bool b_fw_coexist_all_off; | ||
1617 | bool b_sw_coexist_all_off; | ||
1618 | u32 current_state; | ||
1619 | u32 previous_state; | ||
1620 | u8 bt_pre_rssi_state; | ||
1621 | |||
1622 | u8 b_reg_bt_iso; | ||
1623 | u8 b_reg_bt_sco; | ||
1624 | |||
1625 | }; | ||
1626 | |||
1627 | |||
1277 | /**************************************** | 1628 | /**************************************** |
1278 | mem access macro define start | 1629 | mem access macro define start |
1279 | Call endian free function when | 1630 | Call endian free function when |
@@ -1281,7 +1632,7 @@ struct rtl_priv { | |||
1281 | 2. Before write integer to IO. | 1632 | 2. Before write integer to IO. |
1282 | 3. After read integer from IO. | 1633 | 3. After read integer from IO. |
1283 | ****************************************/ | 1634 | ****************************************/ |
1284 | /* Convert little data endian to host */ | 1635 | /* Convert little data endian to host ordering */ |
1285 | #define EF1BYTE(_val) \ | 1636 | #define EF1BYTE(_val) \ |
1286 | ((u8)(_val)) | 1637 | ((u8)(_val)) |
1287 | #define EF2BYTE(_val) \ | 1638 | #define EF2BYTE(_val) \ |
@@ -1289,27 +1640,21 @@ struct rtl_priv { | |||
1289 | #define EF4BYTE(_val) \ | 1640 | #define EF4BYTE(_val) \ |
1290 | (le32_to_cpu(_val)) | 1641 | (le32_to_cpu(_val)) |
1291 | 1642 | ||
1292 | /* Read data from memory */ | 1643 | /* Read le16 data from memory and convert to host ordering */ |
1293 | #define READEF1BYTE(_ptr) \ | ||
1294 | EF1BYTE(*((u8 *)(_ptr))) | ||
1295 | #define READEF2BYTE(_ptr) \ | 1644 | #define READEF2BYTE(_ptr) \ |
1296 | EF2BYTE(*((u16 *)(_ptr))) | 1645 | EF2BYTE(*((u16 *)(_ptr))) |
1297 | #define READEF4BYTE(_ptr) \ | ||
1298 | EF4BYTE(*((u32 *)(_ptr))) | ||
1299 | 1646 | ||
1300 | /* Write data to memory */ | 1647 | /* Write le16 data to memory in host ordering */ |
1301 | #define WRITEEF1BYTE(_ptr, _val) \ | ||
1302 | (*((u8 *)(_ptr))) = EF1BYTE(_val) | ||
1303 | #define WRITEEF2BYTE(_ptr, _val) \ | 1648 | #define WRITEEF2BYTE(_ptr, _val) \ |
1304 | (*((u16 *)(_ptr))) = EF2BYTE(_val) | 1649 | (*((u16 *)(_ptr))) = EF2BYTE(_val) |
1305 | #define WRITEEF4BYTE(_ptr, _val) \ | 1650 | |
1306 | (*((u32 *)(_ptr))) = EF4BYTE(_val) | 1651 | /* Create a bit mask |
1307 | 1652 | * Examples: | |
1308 | /*Example: | 1653 | * BIT_LEN_MASK_32(0) => 0x00000000 |
1309 | BIT_LEN_MASK_32(0) => 0x00000000 | 1654 | * BIT_LEN_MASK_32(1) => 0x00000001 |
1310 | BIT_LEN_MASK_32(1) => 0x00000001 | 1655 | * BIT_LEN_MASK_32(2) => 0x00000003 |
1311 | BIT_LEN_MASK_32(2) => 0x00000003 | 1656 | * BIT_LEN_MASK_32(32) => 0xFFFFFFFF |
1312 | BIT_LEN_MASK_32(32) => 0xFFFFFFFF*/ | 1657 | */ |
1313 | #define BIT_LEN_MASK_32(__bitlen) \ | 1658 | #define BIT_LEN_MASK_32(__bitlen) \ |
1314 | (0xFFFFFFFF >> (32 - (__bitlen))) | 1659 | (0xFFFFFFFF >> (32 - (__bitlen))) |
1315 | #define BIT_LEN_MASK_16(__bitlen) \ | 1660 | #define BIT_LEN_MASK_16(__bitlen) \ |
@@ -1317,9 +1662,11 @@ BIT_LEN_MASK_32(32) => 0xFFFFFFFF*/ | |||
1317 | #define BIT_LEN_MASK_8(__bitlen) \ | 1662 | #define BIT_LEN_MASK_8(__bitlen) \ |
1318 | (0xFF >> (8 - (__bitlen))) | 1663 | (0xFF >> (8 - (__bitlen))) |
1319 | 1664 | ||
1320 | /*Example: | 1665 | /* Create an offset bit mask |
1321 | BIT_OFFSET_LEN_MASK_32(0, 2) => 0x00000003 | 1666 | * Examples: |
1322 | BIT_OFFSET_LEN_MASK_32(16, 2) => 0x00030000*/ | 1667 | * BIT_OFFSET_LEN_MASK_32(0, 2) => 0x00000003 |
1668 | * BIT_OFFSET_LEN_MASK_32(16, 2) => 0x00030000 | ||
1669 | */ | ||
1323 | #define BIT_OFFSET_LEN_MASK_32(__bitoffset, __bitlen) \ | 1670 | #define BIT_OFFSET_LEN_MASK_32(__bitoffset, __bitlen) \ |
1324 | (BIT_LEN_MASK_32(__bitlen) << (__bitoffset)) | 1671 | (BIT_LEN_MASK_32(__bitlen) << (__bitoffset)) |
1325 | #define BIT_OFFSET_LEN_MASK_16(__bitoffset, __bitlen) \ | 1672 | #define BIT_OFFSET_LEN_MASK_16(__bitoffset, __bitlen) \ |
@@ -1328,8 +1675,9 @@ BIT_OFFSET_LEN_MASK_32(16, 2) => 0x00030000*/ | |||
1328 | (BIT_LEN_MASK_8(__bitlen) << (__bitoffset)) | 1675 | (BIT_LEN_MASK_8(__bitlen) << (__bitoffset)) |
1329 | 1676 | ||
1330 | /*Description: | 1677 | /*Description: |
1331 | Return 4-byte value in host byte ordering from | 1678 | * Return 4-byte value in host byte ordering from |
1332 | 4-byte pointer in little-endian system.*/ | 1679 | * 4-byte pointer in little-endian system. |
1680 | */ | ||
1333 | #define LE_P4BYTE_TO_HOST_4BYTE(__pstart) \ | 1681 | #define LE_P4BYTE_TO_HOST_4BYTE(__pstart) \ |
1334 | (EF4BYTE(*((u32 *)(__pstart)))) | 1682 | (EF4BYTE(*((u32 *)(__pstart)))) |
1335 | #define LE_P2BYTE_TO_HOST_2BYTE(__pstart) \ | 1683 | #define LE_P2BYTE_TO_HOST_2BYTE(__pstart) \ |
@@ -1337,28 +1685,10 @@ Return 4-byte value in host byte ordering from | |||
1337 | #define LE_P1BYTE_TO_HOST_1BYTE(__pstart) \ | 1685 | #define LE_P1BYTE_TO_HOST_1BYTE(__pstart) \ |
1338 | (EF1BYTE(*((u8 *)(__pstart)))) | 1686 | (EF1BYTE(*((u8 *)(__pstart)))) |
1339 | 1687 | ||
1340 | /*Description: | 1688 | /* Description: |
1341 | Translate subfield (continuous bits in little-endian) of 4-byte | 1689 | * Mask subfield (continuous bits in little-endian) of 4-byte value |
1342 | value to host byte ordering.*/ | 1690 | * and return the result in 4-byte value in host byte ordering. |
1343 | #define LE_BITS_TO_4BYTE(__pstart, __bitoffset, __bitlen) \ | 1691 | */ |
1344 | ( \ | ||
1345 | (LE_P4BYTE_TO_HOST_4BYTE(__pstart) >> (__bitoffset)) & \ | ||
1346 | BIT_LEN_MASK_32(__bitlen) \ | ||
1347 | ) | ||
1348 | #define LE_BITS_TO_2BYTE(__pstart, __bitoffset, __bitlen) \ | ||
1349 | ( \ | ||
1350 | (LE_P2BYTE_TO_HOST_2BYTE(__pstart) >> (__bitoffset)) & \ | ||
1351 | BIT_LEN_MASK_16(__bitlen) \ | ||
1352 | ) | ||
1353 | #define LE_BITS_TO_1BYTE(__pstart, __bitoffset, __bitlen) \ | ||
1354 | ( \ | ||
1355 | (LE_P1BYTE_TO_HOST_1BYTE(__pstart) >> (__bitoffset)) & \ | ||
1356 | BIT_LEN_MASK_8(__bitlen) \ | ||
1357 | ) | ||
1358 | |||
1359 | /*Description: | ||
1360 | Mask subfield (continuous bits in little-endian) of 4-byte value | ||
1361 | and return the result in 4-byte value in host byte ordering.*/ | ||
1362 | #define LE_BITS_CLEARED_TO_4BYTE(__pstart, __bitoffset, __bitlen) \ | 1692 | #define LE_BITS_CLEARED_TO_4BYTE(__pstart, __bitoffset, __bitlen) \ |
1363 | ( \ | 1693 | ( \ |
1364 | LE_P4BYTE_TO_HOST_4BYTE(__pstart) & \ | 1694 | LE_P4BYTE_TO_HOST_4BYTE(__pstart) & \ |
@@ -1375,20 +1705,9 @@ and return the result in 4-byte value in host byte ordering.*/ | |||
1375 | (~BIT_OFFSET_LEN_MASK_8(__bitoffset, __bitlen)) \ | 1705 | (~BIT_OFFSET_LEN_MASK_8(__bitoffset, __bitlen)) \ |
1376 | ) | 1706 | ) |
1377 | 1707 | ||
1378 | /*Description: | 1708 | /* Description: |
1379 | Set subfield of little-endian 4-byte value to specified value. */ | 1709 | * Set subfield of little-endian 4-byte value to specified value. |
1380 | #define SET_BITS_TO_LE_4BYTE(__pstart, __bitoffset, __bitlen, __val) \ | 1710 | */ |
1381 | *((u32 *)(__pstart)) = EF4BYTE \ | ||
1382 | ( \ | ||
1383 | LE_BITS_CLEARED_TO_4BYTE(__pstart, __bitoffset, __bitlen) | \ | ||
1384 | ((((u32)__val) & BIT_LEN_MASK_32(__bitlen)) << (__bitoffset)) \ | ||
1385 | ); | ||
1386 | #define SET_BITS_TO_LE_2BYTE(__pstart, __bitoffset, __bitlen, __val) \ | ||
1387 | *((u16 *)(__pstart)) = EF2BYTE \ | ||
1388 | ( \ | ||
1389 | LE_BITS_CLEARED_TO_2BYTE(__pstart, __bitoffset, __bitlen) | \ | ||
1390 | ((((u16)__val) & BIT_LEN_MASK_16(__bitlen)) << (__bitoffset)) \ | ||
1391 | ); | ||
1392 | #define SET_BITS_TO_LE_1BYTE(__pstart, __bitoffset, __bitlen, __val) \ | 1711 | #define SET_BITS_TO_LE_1BYTE(__pstart, __bitoffset, __bitlen, __val) \ |
1393 | *((u8 *)(__pstart)) = EF1BYTE \ | 1712 | *((u8 *)(__pstart)) = EF1BYTE \ |
1394 | ( \ | 1713 | ( \ |
@@ -1400,13 +1719,14 @@ Set subfield of little-endian 4-byte value to specified value. */ | |||
1400 | mem access macro define end | 1719 | mem access macro define end |
1401 | ****************************************/ | 1720 | ****************************************/ |
1402 | 1721 | ||
1403 | #define packet_get_type(_packet) (EF1BYTE((_packet).octet[0]) & 0xFC) | 1722 | #define byte(x, n) ((x >> (8 * n)) & 0xff) |
1723 | |||
1404 | #define RTL_WATCH_DOG_TIME 2000 | 1724 | #define RTL_WATCH_DOG_TIME 2000 |
1405 | #define MSECS(t) msecs_to_jiffies(t) | 1725 | #define MSECS(t) msecs_to_jiffies(t) |
1406 | #define WLAN_FC_GET_VERS(fc) ((fc) & IEEE80211_FCTL_VERS) | 1726 | #define WLAN_FC_GET_VERS(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_VERS) |
1407 | #define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE) | 1727 | #define WLAN_FC_GET_TYPE(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE) |
1408 | #define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE) | 1728 | #define WLAN_FC_GET_STYPE(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_STYPE) |
1409 | #define WLAN_FC_MORE_DATA(fc) ((fc) & IEEE80211_FCTL_MOREDATA) | 1729 | #define WLAN_FC_MORE_DATA(fc) (le16_to_cpu(fc) & IEEE80211_FCTL_MOREDATA) |
1410 | #define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) | 1730 | #define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) |
1411 | #define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) | 1731 | #define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ) |
1412 | #define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) | 1732 | #define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4) |
@@ -1420,6 +1740,8 @@ Set subfield of little-endian 4-byte value to specified value. */ | |||
1420 | #define RT_RF_OFF_LEVL_FW_32K BIT(5) /*FW in 32k */ | 1740 | #define RT_RF_OFF_LEVL_FW_32K BIT(5) /*FW in 32k */ |
1421 | /*Always enable ASPM and Clock Req in initialization.*/ | 1741 | /*Always enable ASPM and Clock Req in initialization.*/ |
1422 | #define RT_RF_PS_LEVEL_ALWAYS_ASPM BIT(6) | 1742 | #define RT_RF_PS_LEVEL_ALWAYS_ASPM BIT(6) |
1743 | /* no matter RFOFF or SLEEP we set PS_ASPM_LEVL*/ | ||
1744 | #define RT_PS_LEVEL_ASPM BIT(7) | ||
1423 | /*When LPS is on, disable 2R if no packet is received or transmittd.*/ | 1745 | /*When LPS is on, disable 2R if no packet is received or transmittd.*/ |
1424 | #define RT_RF_LPS_DISALBE_2R BIT(30) | 1746 | #define RT_RF_LPS_DISALBE_2R BIT(30) |
1425 | #define RT_RF_LPS_LEVEL_ASPM BIT(31) /*LPS with ASPM */ | 1747 | #define RT_RF_LPS_LEVEL_ASPM BIT(31) /*LPS with ASPM */ |
@@ -1433,15 +1755,6 @@ Set subfield of little-endian 4-byte value to specified value. */ | |||
1433 | #define container_of_dwork_rtl(x, y, z) \ | 1755 | #define container_of_dwork_rtl(x, y, z) \ |
1434 | container_of(container_of(x, struct delayed_work, work), y, z) | 1756 | container_of(container_of(x, struct delayed_work, work), y, z) |
1435 | 1757 | ||
1436 | #define FILL_OCTET_STRING(_os, _octet, _len) \ | ||
1437 | (_os).octet = (u8 *)(_octet); \ | ||
1438 | (_os).length = (_len); | ||
1439 | |||
1440 | #define CP_MACADDR(des, src) \ | ||
1441 | ((des)[0] = (src)[0], (des)[1] = (src)[1],\ | ||
1442 | (des)[2] = (src)[2], (des)[3] = (src)[3],\ | ||
1443 | (des)[4] = (src)[4], (des)[5] = (src)[5]) | ||
1444 | |||
1445 | static inline u8 rtl_read_byte(struct rtl_priv *rtlpriv, u32 addr) | 1758 | static inline u8 rtl_read_byte(struct rtl_priv *rtlpriv, u32 addr) |
1446 | { | 1759 | { |
1447 | return rtlpriv->io.read8_sync(rtlpriv, addr); | 1760 | return rtlpriv->io.read8_sync(rtlpriv, addr); |
diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig index 0e65bce457d6..692ebff38fc8 100644 --- a/drivers/net/wireless/wl12xx/Kconfig +++ b/drivers/net/wireless/wl12xx/Kconfig | |||
@@ -54,7 +54,7 @@ config WL12XX_SDIO | |||
54 | 54 | ||
55 | config WL12XX_SDIO_TEST | 55 | config WL12XX_SDIO_TEST |
56 | tristate "TI wl12xx SDIO testing support" | 56 | tristate "TI wl12xx SDIO testing support" |
57 | depends on WL12XX && MMC | 57 | depends on WL12XX && MMC && WL12XX_SDIO |
58 | default n | 58 | default n |
59 | ---help--- | 59 | ---help--- |
60 | This module adds support for the SDIO bus testing with the | 60 | This module adds support for the SDIO bus testing with the |
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c index afdc601aa7ea..33840d95d17d 100644 --- a/drivers/net/wireless/wl12xx/acx.c +++ b/drivers/net/wireless/wl12xx/acx.c | |||
@@ -783,6 +783,10 @@ int wl1271_acx_sta_rate_policies(struct wl1271 *wl) | |||
783 | 783 | ||
784 | acx->rate_class_cnt = cpu_to_le32(ACX_TX_RATE_POLICY_CNT); | 784 | acx->rate_class_cnt = cpu_to_le32(ACX_TX_RATE_POLICY_CNT); |
785 | 785 | ||
786 | wl1271_debug(DEBUG_ACX, "basic_rate: 0x%x, full_rate: 0x%x", | ||
787 | acx->rate_class[ACX_TX_BASIC_RATE].enabled_rates, | ||
788 | acx->rate_class[ACX_TX_AP_FULL_RATE].enabled_rates); | ||
789 | |||
786 | ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx)); | 790 | ret = wl1271_cmd_configure(wl, ACX_RATE_POLICY, acx, sizeof(*acx)); |
787 | if (ret < 0) { | 791 | if (ret < 0) { |
788 | wl1271_warning("Setting of rate policies failed: %d", ret); | 792 | wl1271_warning("Setting of rate policies failed: %d", ret); |
@@ -947,9 +951,9 @@ out: | |||
947 | return ret; | 951 | return ret; |
948 | } | 952 | } |
949 | 953 | ||
950 | int wl1271_acx_mem_cfg(struct wl1271 *wl) | 954 | int wl1271_acx_ap_mem_cfg(struct wl1271 *wl) |
951 | { | 955 | { |
952 | struct wl1271_acx_config_memory *mem_conf; | 956 | struct wl1271_acx_ap_config_memory *mem_conf; |
953 | int ret; | 957 | int ret; |
954 | 958 | ||
955 | wl1271_debug(DEBUG_ACX, "wl1271 mem cfg"); | 959 | wl1271_debug(DEBUG_ACX, "wl1271 mem cfg"); |
@@ -961,10 +965,10 @@ int wl1271_acx_mem_cfg(struct wl1271 *wl) | |||
961 | } | 965 | } |
962 | 966 | ||
963 | /* memory config */ | 967 | /* memory config */ |
964 | mem_conf->num_stations = DEFAULT_NUM_STATIONS; | 968 | mem_conf->num_stations = wl->conf.mem.num_stations; |
965 | mem_conf->rx_mem_block_num = ACX_RX_MEM_BLOCKS; | 969 | mem_conf->rx_mem_block_num = wl->conf.mem.rx_block_num; |
966 | mem_conf->tx_min_mem_block_num = ACX_TX_MIN_MEM_BLOCKS; | 970 | mem_conf->tx_min_mem_block_num = wl->conf.mem.tx_min_block_num; |
967 | mem_conf->num_ssid_profiles = ACX_NUM_SSID_PROFILES; | 971 | mem_conf->num_ssid_profiles = wl->conf.mem.ssid_profiles; |
968 | mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS); | 972 | mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS); |
969 | 973 | ||
970 | ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf, | 974 | ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf, |
@@ -979,13 +983,45 @@ out: | |||
979 | return ret; | 983 | return ret; |
980 | } | 984 | } |
981 | 985 | ||
982 | int wl1271_acx_init_mem_config(struct wl1271 *wl) | 986 | int wl1271_acx_sta_mem_cfg(struct wl1271 *wl) |
983 | { | 987 | { |
988 | struct wl1271_acx_sta_config_memory *mem_conf; | ||
984 | int ret; | 989 | int ret; |
985 | 990 | ||
986 | ret = wl1271_acx_mem_cfg(wl); | 991 | wl1271_debug(DEBUG_ACX, "wl1271 mem cfg"); |
987 | if (ret < 0) | 992 | |
988 | return ret; | 993 | mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL); |
994 | if (!mem_conf) { | ||
995 | ret = -ENOMEM; | ||
996 | goto out; | ||
997 | } | ||
998 | |||
999 | /* memory config */ | ||
1000 | mem_conf->num_stations = wl->conf.mem.num_stations; | ||
1001 | mem_conf->rx_mem_block_num = wl->conf.mem.rx_block_num; | ||
1002 | mem_conf->tx_min_mem_block_num = wl->conf.mem.tx_min_block_num; | ||
1003 | mem_conf->num_ssid_profiles = wl->conf.mem.ssid_profiles; | ||
1004 | mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS); | ||
1005 | mem_conf->dyn_mem_enable = wl->conf.mem.dynamic_memory; | ||
1006 | mem_conf->tx_free_req = wl->conf.mem.min_req_tx_blocks; | ||
1007 | mem_conf->rx_free_req = wl->conf.mem.min_req_rx_blocks; | ||
1008 | mem_conf->tx_min = wl->conf.mem.tx_min; | ||
1009 | |||
1010 | ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf, | ||
1011 | sizeof(*mem_conf)); | ||
1012 | if (ret < 0) { | ||
1013 | wl1271_warning("wl1271 mem config failed: %d", ret); | ||
1014 | goto out; | ||
1015 | } | ||
1016 | |||
1017 | out: | ||
1018 | kfree(mem_conf); | ||
1019 | return ret; | ||
1020 | } | ||
1021 | |||
1022 | int wl1271_acx_init_mem_config(struct wl1271 *wl) | ||
1023 | { | ||
1024 | int ret; | ||
989 | 1025 | ||
990 | wl->target_mem_map = kzalloc(sizeof(struct wl1271_acx_mem_map), | 1026 | wl->target_mem_map = kzalloc(sizeof(struct wl1271_acx_mem_map), |
991 | GFP_KERNEL); | 1027 | GFP_KERNEL); |
@@ -1476,3 +1512,33 @@ out: | |||
1476 | kfree(acx); | 1512 | kfree(acx); |
1477 | return ret; | 1513 | return ret; |
1478 | } | 1514 | } |
1515 | |||
1516 | int wl1271_acx_config_ps(struct wl1271 *wl) | ||
1517 | { | ||
1518 | struct wl1271_acx_config_ps *config_ps; | ||
1519 | int ret; | ||
1520 | |||
1521 | wl1271_debug(DEBUG_ACX, "acx config ps"); | ||
1522 | |||
1523 | config_ps = kzalloc(sizeof(*config_ps), GFP_KERNEL); | ||
1524 | if (!config_ps) { | ||
1525 | ret = -ENOMEM; | ||
1526 | goto out; | ||
1527 | } | ||
1528 | |||
1529 | config_ps->exit_retries = wl->conf.conn.psm_exit_retries; | ||
1530 | config_ps->enter_retries = wl->conf.conn.psm_entry_retries; | ||
1531 | config_ps->null_data_rate = cpu_to_le32(wl->basic_rate); | ||
1532 | |||
1533 | ret = wl1271_cmd_configure(wl, ACX_CONFIG_PS, config_ps, | ||
1534 | sizeof(*config_ps)); | ||
1535 | |||
1536 | if (ret < 0) { | ||
1537 | wl1271_warning("acx config ps failed: %d", ret); | ||
1538 | goto out; | ||
1539 | } | ||
1540 | |||
1541 | out: | ||
1542 | kfree(config_ps); | ||
1543 | return ret; | ||
1544 | } | ||
diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h index 4bbaf04f434e..4e301de916bb 100644 --- a/drivers/net/wireless/wl12xx/acx.h +++ b/drivers/net/wireless/wl12xx/acx.h | |||
@@ -133,7 +133,6 @@ enum { | |||
133 | 133 | ||
134 | #define DEFAULT_UCAST_PRIORITY 0 | 134 | #define DEFAULT_UCAST_PRIORITY 0 |
135 | #define DEFAULT_RX_Q_PRIORITY 0 | 135 | #define DEFAULT_RX_Q_PRIORITY 0 |
136 | #define DEFAULT_NUM_STATIONS 1 | ||
137 | #define DEFAULT_RXQ_PRIORITY 0 /* low 0 .. 15 high */ | 136 | #define DEFAULT_RXQ_PRIORITY 0 /* low 0 .. 15 high */ |
138 | #define DEFAULT_RXQ_TYPE 0x07 /* All frames, Data/Ctrl/Mgmt */ | 137 | #define DEFAULT_RXQ_TYPE 0x07 /* All frames, Data/Ctrl/Mgmt */ |
139 | #define TRACE_BUFFER_MAX_SIZE 256 | 138 | #define TRACE_BUFFER_MAX_SIZE 256 |
@@ -797,12 +796,9 @@ struct acx_tx_config_options { | |||
797 | __le16 tx_compl_threshold; /* number of packets */ | 796 | __le16 tx_compl_threshold; /* number of packets */ |
798 | } __packed; | 797 | } __packed; |
799 | 798 | ||
800 | #define ACX_RX_MEM_BLOCKS 70 | ||
801 | #define ACX_TX_MIN_MEM_BLOCKS 40 | ||
802 | #define ACX_TX_DESCRIPTORS 32 | 799 | #define ACX_TX_DESCRIPTORS 32 |
803 | #define ACX_NUM_SSID_PROFILES 1 | ||
804 | 800 | ||
805 | struct wl1271_acx_config_memory { | 801 | struct wl1271_acx_ap_config_memory { |
806 | struct acx_header header; | 802 | struct acx_header header; |
807 | 803 | ||
808 | u8 rx_mem_block_num; | 804 | u8 rx_mem_block_num; |
@@ -812,6 +808,20 @@ struct wl1271_acx_config_memory { | |||
812 | __le32 total_tx_descriptors; | 808 | __le32 total_tx_descriptors; |
813 | } __packed; | 809 | } __packed; |
814 | 810 | ||
811 | struct wl1271_acx_sta_config_memory { | ||
812 | struct acx_header header; | ||
813 | |||
814 | u8 rx_mem_block_num; | ||
815 | u8 tx_min_mem_block_num; | ||
816 | u8 num_stations; | ||
817 | u8 num_ssid_profiles; | ||
818 | __le32 total_tx_descriptors; | ||
819 | u8 dyn_mem_enable; | ||
820 | u8 tx_free_req; | ||
821 | u8 rx_free_req; | ||
822 | u8 tx_min; | ||
823 | } __packed; | ||
824 | |||
815 | struct wl1271_acx_mem_map { | 825 | struct wl1271_acx_mem_map { |
816 | struct acx_header header; | 826 | struct acx_header header; |
817 | 827 | ||
@@ -1136,6 +1146,15 @@ struct wl1271_acx_max_tx_retry { | |||
1136 | u8 padding_1[2]; | 1146 | u8 padding_1[2]; |
1137 | } __packed; | 1147 | } __packed; |
1138 | 1148 | ||
1149 | struct wl1271_acx_config_ps { | ||
1150 | struct acx_header header; | ||
1151 | |||
1152 | u8 exit_retries; | ||
1153 | u8 enter_retries; | ||
1154 | u8 padding[2]; | ||
1155 | __le32 null_data_rate; | ||
1156 | } __packed; | ||
1157 | |||
1139 | enum { | 1158 | enum { |
1140 | ACX_WAKE_UP_CONDITIONS = 0x0002, | 1159 | ACX_WAKE_UP_CONDITIONS = 0x0002, |
1141 | ACX_MEM_CFG = 0x0003, | 1160 | ACX_MEM_CFG = 0x0003, |
@@ -1193,6 +1212,8 @@ enum { | |||
1193 | ACX_HT_BSS_OPERATION = 0x0058, | 1212 | ACX_HT_BSS_OPERATION = 0x0058, |
1194 | ACX_COEX_ACTIVITY = 0x0059, | 1213 | ACX_COEX_ACTIVITY = 0x0059, |
1195 | ACX_SET_DCO_ITRIM_PARAMS = 0x0061, | 1214 | ACX_SET_DCO_ITRIM_PARAMS = 0x0061, |
1215 | ACX_GEN_FW_CMD = 0x0070, | ||
1216 | ACX_HOST_IF_CFG_BITMAP = 0x0071, | ||
1196 | ACX_MAX_TX_FAILURE = 0x0072, | 1217 | ACX_MAX_TX_FAILURE = 0x0072, |
1197 | DOT11_RX_MSDU_LIFE_TIME = 0x1004, | 1218 | DOT11_RX_MSDU_LIFE_TIME = 0x1004, |
1198 | DOT11_CUR_TX_PWR = 0x100D, | 1219 | DOT11_CUR_TX_PWR = 0x100D, |
@@ -1200,10 +1221,8 @@ enum { | |||
1200 | DOT11_RTS_THRESHOLD = 0x1013, | 1221 | DOT11_RTS_THRESHOLD = 0x1013, |
1201 | DOT11_GROUP_ADDRESS_TBL = 0x1014, | 1222 | DOT11_GROUP_ADDRESS_TBL = 0x1014, |
1202 | ACX_PM_CONFIG = 0x1016, | 1223 | ACX_PM_CONFIG = 0x1016, |
1203 | 1224 | ACX_CONFIG_PS = 0x1017, | |
1204 | MAX_DOT11_IE = DOT11_GROUP_ADDRESS_TBL, | 1225 | ACX_CONFIG_HANGOVER = 0x1018, |
1205 | |||
1206 | MAX_IE = 0xFFFF | ||
1207 | }; | 1226 | }; |
1208 | 1227 | ||
1209 | 1228 | ||
@@ -1245,7 +1264,8 @@ int wl1271_acx_tid_cfg(struct wl1271 *wl, u8 queue_id, u8 channel_type, | |||
1245 | u32 apsd_conf0, u32 apsd_conf1); | 1264 | u32 apsd_conf0, u32 apsd_conf1); |
1246 | int wl1271_acx_frag_threshold(struct wl1271 *wl, u16 frag_threshold); | 1265 | int wl1271_acx_frag_threshold(struct wl1271 *wl, u16 frag_threshold); |
1247 | int wl1271_acx_tx_config_options(struct wl1271 *wl); | 1266 | int wl1271_acx_tx_config_options(struct wl1271 *wl); |
1248 | int wl1271_acx_mem_cfg(struct wl1271 *wl); | 1267 | int wl1271_acx_ap_mem_cfg(struct wl1271 *wl); |
1268 | int wl1271_acx_sta_mem_cfg(struct wl1271 *wl); | ||
1249 | int wl1271_acx_init_mem_config(struct wl1271 *wl); | 1269 | int wl1271_acx_init_mem_config(struct wl1271 *wl); |
1250 | int wl1271_acx_init_rx_interrupt(struct wl1271 *wl); | 1270 | int wl1271_acx_init_rx_interrupt(struct wl1271 *wl); |
1251 | int wl1271_acx_smart_reflex(struct wl1271 *wl); | 1271 | int wl1271_acx_smart_reflex(struct wl1271 *wl); |
@@ -1269,5 +1289,6 @@ int wl1271_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, u16 ssn, | |||
1269 | bool enable); | 1289 | bool enable); |
1270 | int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime); | 1290 | int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime); |
1271 | int wl1271_acx_max_tx_retry(struct wl1271 *wl); | 1291 | int wl1271_acx_max_tx_retry(struct wl1271 *wl); |
1292 | int wl1271_acx_config_ps(struct wl1271 *wl); | ||
1272 | 1293 | ||
1273 | #endif /* __WL1271_ACX_H__ */ | 1294 | #endif /* __WL1271_ACX_H__ */ |
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c index 1bb8be5e805b..97ffd7aa57a8 100644 --- a/drivers/net/wireless/wl12xx/cmd.c +++ b/drivers/net/wireless/wl12xx/cmd.c | |||
@@ -286,6 +286,7 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type) | |||
286 | join->rx_filter_options = cpu_to_le32(wl->rx_filter); | 286 | join->rx_filter_options = cpu_to_le32(wl->rx_filter); |
287 | join->bss_type = bss_type; | 287 | join->bss_type = bss_type; |
288 | join->basic_rate_set = cpu_to_le32(wl->basic_rate_set); | 288 | join->basic_rate_set = cpu_to_le32(wl->basic_rate_set); |
289 | join->supported_rate_set = cpu_to_le32(wl->rate_set); | ||
289 | 290 | ||
290 | if (wl->band == IEEE80211_BAND_5GHZ) | 291 | if (wl->band == IEEE80211_BAND_5GHZ) |
291 | join->bss_type |= WL1271_JOIN_CMD_BSS_TYPE_5GHZ; | 292 | join->bss_type |= WL1271_JOIN_CMD_BSS_TYPE_5GHZ; |
@@ -303,6 +304,9 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type) | |||
303 | wl->tx_security_last_seq = 0; | 304 | wl->tx_security_last_seq = 0; |
304 | wl->tx_security_seq = 0; | 305 | wl->tx_security_seq = 0; |
305 | 306 | ||
307 | wl1271_debug(DEBUG_CMD, "cmd join: basic_rate_set=0x%x, rate_set=0x%x", | ||
308 | join->basic_rate_set, join->supported_rate_set); | ||
309 | |||
306 | ret = wl1271_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join), 0); | 310 | ret = wl1271_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join), 0); |
307 | if (ret < 0) { | 311 | if (ret < 0) { |
308 | wl1271_error("failed to initiate cmd join"); | 312 | wl1271_error("failed to initiate cmd join"); |
@@ -454,7 +458,7 @@ out: | |||
454 | return ret; | 458 | return ret; |
455 | } | 459 | } |
456 | 460 | ||
457 | int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send) | 461 | int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode) |
458 | { | 462 | { |
459 | struct wl1271_cmd_ps_params *ps_params = NULL; | 463 | struct wl1271_cmd_ps_params *ps_params = NULL; |
460 | int ret = 0; | 464 | int ret = 0; |
@@ -468,10 +472,6 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send) | |||
468 | } | 472 | } |
469 | 473 | ||
470 | ps_params->ps_mode = ps_mode; | 474 | ps_params->ps_mode = ps_mode; |
471 | ps_params->send_null_data = send; | ||
472 | ps_params->retries = wl->conf.conn.psm_entry_nullfunc_retries; | ||
473 | ps_params->hang_over_period = wl->conf.conn.psm_entry_hangover_period; | ||
474 | ps_params->null_data_rate = cpu_to_le32(rates); | ||
475 | 475 | ||
476 | ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params, | 476 | ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params, |
477 | sizeof(*ps_params), 0); | 477 | sizeof(*ps_params), 0); |
diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h index 751281414006..54c12e71417e 100644 --- a/drivers/net/wireless/wl12xx/cmd.h +++ b/drivers/net/wireless/wl12xx/cmd.h | |||
@@ -39,7 +39,7 @@ int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer); | |||
39 | int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len); | 39 | int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len); |
40 | int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len); | 40 | int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len); |
41 | int wl1271_cmd_data_path(struct wl1271 *wl, bool enable); | 41 | int wl1271_cmd_data_path(struct wl1271 *wl, bool enable); |
42 | int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, u32 rates, bool send); | 42 | int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode); |
43 | int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer, | 43 | int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer, |
44 | size_t len); | 44 | size_t len); |
45 | int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, | 45 | int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id, |
@@ -140,6 +140,7 @@ enum cmd_templ { | |||
140 | * For CTS-to-self (FastCTS) mechanism | 140 | * For CTS-to-self (FastCTS) mechanism |
141 | * for BT/WLAN coexistence (SoftGemini). */ | 141 | * for BT/WLAN coexistence (SoftGemini). */ |
142 | CMD_TEMPL_ARP_RSP, | 142 | CMD_TEMPL_ARP_RSP, |
143 | CMD_TEMPL_LINK_MEASUREMENT_REPORT, | ||
143 | 144 | ||
144 | /* AP-mode specific */ | 145 | /* AP-mode specific */ |
145 | CMD_TEMPL_AP_BEACON = 13, | 146 | CMD_TEMPL_AP_BEACON = 13, |
@@ -216,6 +217,7 @@ struct wl1271_cmd_join { | |||
216 | * ACK or CTS frames). | 217 | * ACK or CTS frames). |
217 | */ | 218 | */ |
218 | __le32 basic_rate_set; | 219 | __le32 basic_rate_set; |
220 | __le32 supported_rate_set; | ||
219 | u8 dtim_interval; | 221 | u8 dtim_interval; |
220 | /* | 222 | /* |
221 | * bits 0-2: This bitwise field specifies the type | 223 | * bits 0-2: This bitwise field specifies the type |
@@ -278,15 +280,7 @@ struct wl1271_cmd_ps_params { | |||
278 | struct wl1271_cmd_header header; | 280 | struct wl1271_cmd_header header; |
279 | 281 | ||
280 | u8 ps_mode; /* STATION_* */ | 282 | u8 ps_mode; /* STATION_* */ |
281 | u8 send_null_data; /* Do we have to send NULL data packet ? */ | 283 | u8 padding[3]; |
282 | u8 retries; /* Number of retires for the initial NULL data packet */ | ||
283 | |||
284 | /* | ||
285 | * TUs during which the target stays awake after switching | ||
286 | * to power save mode. | ||
287 | */ | ||
288 | u8 hang_over_period; | ||
289 | __le32 null_data_rate; | ||
290 | } __packed; | 284 | } __packed; |
291 | 285 | ||
292 | /* HW encryption keys */ | 286 | /* HW encryption keys */ |
diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h index fd1dac9ab4db..856a8a2fff4f 100644 --- a/drivers/net/wireless/wl12xx/conf.h +++ b/drivers/net/wireless/wl12xx/conf.h | |||
@@ -960,6 +960,14 @@ struct conf_conn_settings { | |||
960 | u8 psm_entry_retries; | 960 | u8 psm_entry_retries; |
961 | 961 | ||
962 | /* | 962 | /* |
963 | * Specifies the maximum number of times to try PSM exit if it fails | ||
964 | * (if sending the appropriate null-func message fails.) | ||
965 | * | ||
966 | * Range 0 - 255 | ||
967 | */ | ||
968 | u8 psm_exit_retries; | ||
969 | |||
970 | /* | ||
963 | * Specifies the maximum number of times to try transmit the PSM entry | 971 | * Specifies the maximum number of times to try transmit the PSM entry |
964 | * null-func frame for each PSM entry attempt | 972 | * null-func frame for each PSM entry attempt |
965 | * | 973 | * |
@@ -1143,6 +1151,46 @@ struct conf_ht_setting { | |||
1143 | u16 inactivity_timeout; | 1151 | u16 inactivity_timeout; |
1144 | }; | 1152 | }; |
1145 | 1153 | ||
1154 | struct conf_memory_settings { | ||
1155 | /* Number of stations supported in IBSS mode */ | ||
1156 | u8 num_stations; | ||
1157 | |||
1158 | /* Number of ssid profiles used in IBSS mode */ | ||
1159 | u8 ssid_profiles; | ||
1160 | |||
1161 | /* Number of memory buffers allocated to rx pool */ | ||
1162 | u8 rx_block_num; | ||
1163 | |||
1164 | /* Minimum number of blocks allocated to tx pool */ | ||
1165 | u8 tx_min_block_num; | ||
1166 | |||
1167 | /* Disable/Enable dynamic memory */ | ||
1168 | u8 dynamic_memory; | ||
1169 | |||
1170 | /* | ||
1171 | * Minimum required free tx memory blocks in order to assure optimum | ||
1172 | * performence | ||
1173 | * | ||
1174 | * Range: 0-120 | ||
1175 | */ | ||
1176 | u8 min_req_tx_blocks; | ||
1177 | |||
1178 | /* | ||
1179 | * Minimum required free rx memory blocks in order to assure optimum | ||
1180 | * performence | ||
1181 | * | ||
1182 | * Range: 0-120 | ||
1183 | */ | ||
1184 | u8 min_req_rx_blocks; | ||
1185 | |||
1186 | /* | ||
1187 | * Minimum number of mem blocks (free+used) guaranteed for TX | ||
1188 | * | ||
1189 | * Range: 0-120 | ||
1190 | */ | ||
1191 | u8 tx_min; | ||
1192 | }; | ||
1193 | |||
1146 | struct conf_drv_settings { | 1194 | struct conf_drv_settings { |
1147 | struct conf_sg_settings sg; | 1195 | struct conf_sg_settings sg; |
1148 | struct conf_rx_settings rx; | 1196 | struct conf_rx_settings rx; |
@@ -1154,6 +1202,7 @@ struct conf_drv_settings { | |||
1154 | struct conf_scan_settings scan; | 1202 | struct conf_scan_settings scan; |
1155 | struct conf_rf_settings rf; | 1203 | struct conf_rf_settings rf; |
1156 | struct conf_ht_setting ht; | 1204 | struct conf_ht_setting ht; |
1205 | struct conf_memory_settings mem; | ||
1157 | }; | 1206 | }; |
1158 | 1207 | ||
1159 | #endif | 1208 | #endif |
diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c index 3376a5de09d7..1b170c5cc595 100644 --- a/drivers/net/wireless/wl12xx/event.c +++ b/drivers/net/wireless/wl12xx/event.c | |||
@@ -135,20 +135,6 @@ static int wl1271_event_ps_report(struct wl1271 *wl, | |||
135 | /* go to extremely low power mode */ | 135 | /* go to extremely low power mode */ |
136 | wl1271_ps_elp_sleep(wl); | 136 | wl1271_ps_elp_sleep(wl); |
137 | break; | 137 | break; |
138 | case EVENT_EXIT_POWER_SAVE_FAIL: | ||
139 | wl1271_debug(DEBUG_PSM, "PSM exit failed"); | ||
140 | |||
141 | if (test_bit(WL1271_FLAG_PSM, &wl->flags)) { | ||
142 | wl->psm_entry_retry = 0; | ||
143 | break; | ||
144 | } | ||
145 | |||
146 | /* make sure the firmware goes to active mode - the frame to | ||
147 | be sent next will indicate to the AP, that we are active. */ | ||
148 | ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE, | ||
149 | wl->basic_rate, false); | ||
150 | break; | ||
151 | case EVENT_EXIT_POWER_SAVE_SUCCESS: | ||
152 | default: | 138 | default: |
153 | break; | 139 | break; |
154 | } | 140 | } |
diff --git a/drivers/net/wireless/wl12xx/event.h b/drivers/net/wireless/wl12xx/event.h index 1d5ef670d480..0e80886f3031 100644 --- a/drivers/net/wireless/wl12xx/event.h +++ b/drivers/net/wireless/wl12xx/event.h | |||
@@ -75,8 +75,6 @@ enum { | |||
75 | enum { | 75 | enum { |
76 | EVENT_ENTER_POWER_SAVE_FAIL = 0, | 76 | EVENT_ENTER_POWER_SAVE_FAIL = 0, |
77 | EVENT_ENTER_POWER_SAVE_SUCCESS, | 77 | EVENT_ENTER_POWER_SAVE_SUCCESS, |
78 | EVENT_EXIT_POWER_SAVE_FAIL, | ||
79 | EVENT_EXIT_POWER_SAVE_SUCCESS, | ||
80 | }; | 78 | }; |
81 | 79 | ||
82 | struct event_debug_report { | 80 | struct event_debug_report { |
diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c index 70b3dc88a219..62dc9839dd31 100644 --- a/drivers/net/wireless/wl12xx/init.c +++ b/drivers/net/wireless/wl12xx/init.c | |||
@@ -325,6 +325,11 @@ static int wl1271_sta_hw_init(struct wl1271 *wl) | |||
325 | if (ret < 0) | 325 | if (ret < 0) |
326 | return ret; | 326 | return ret; |
327 | 327 | ||
328 | /* PS config */ | ||
329 | ret = wl1271_acx_config_ps(wl); | ||
330 | if (ret < 0) | ||
331 | return ret; | ||
332 | |||
328 | ret = wl1271_sta_init_templates_config(wl); | 333 | ret = wl1271_sta_init_templates_config(wl); |
329 | if (ret < 0) | 334 | if (ret < 0) |
330 | return ret; | 335 | return ret; |
@@ -367,6 +372,10 @@ static int wl1271_sta_hw_init(struct wl1271 *wl) | |||
367 | if (ret < 0) | 372 | if (ret < 0) |
368 | return ret; | 373 | return ret; |
369 | 374 | ||
375 | ret = wl1271_acx_sta_mem_cfg(wl); | ||
376 | if (ret < 0) | ||
377 | return ret; | ||
378 | |||
370 | return 0; | 379 | return 0; |
371 | } | 380 | } |
372 | 381 | ||
@@ -433,6 +442,10 @@ static int wl1271_ap_hw_init(struct wl1271 *wl) | |||
433 | if (ret < 0) | 442 | if (ret < 0) |
434 | return ret; | 443 | return ret; |
435 | 444 | ||
445 | ret = wl1271_acx_ap_mem_cfg(wl); | ||
446 | if (ret < 0) | ||
447 | return ret; | ||
448 | |||
436 | return 0; | 449 | return 0; |
437 | } | 450 | } |
438 | 451 | ||
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 254b7daccee1..61dea73f5fdc 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c | |||
@@ -256,6 +256,7 @@ static struct conf_drv_settings default_conf = { | |||
256 | .bet_enable = CONF_BET_MODE_ENABLE, | 256 | .bet_enable = CONF_BET_MODE_ENABLE, |
257 | .bet_max_consecutive = 10, | 257 | .bet_max_consecutive = 10, |
258 | .psm_entry_retries = 5, | 258 | .psm_entry_retries = 5, |
259 | .psm_exit_retries = 255, | ||
259 | .psm_entry_nullfunc_retries = 3, | 260 | .psm_entry_nullfunc_retries = 3, |
260 | .psm_entry_hangover_period = 1, | 261 | .psm_entry_hangover_period = 1, |
261 | .keep_alive_interval = 55000, | 262 | .keep_alive_interval = 55000, |
@@ -297,6 +298,16 @@ static struct conf_drv_settings default_conf = { | |||
297 | .tx_ba_win_size = 64, | 298 | .tx_ba_win_size = 64, |
298 | .inactivity_timeout = 10000, | 299 | .inactivity_timeout = 10000, |
299 | }, | 300 | }, |
301 | .mem = { | ||
302 | .num_stations = 1, | ||
303 | .ssid_profiles = 1, | ||
304 | .rx_block_num = 70, | ||
305 | .tx_min_block_num = 40, | ||
306 | .dynamic_memory = 0, | ||
307 | .min_req_tx_blocks = 104, | ||
308 | .min_req_rx_blocks = 22, | ||
309 | .tx_min = 27, | ||
310 | } | ||
300 | }; | 311 | }; |
301 | 312 | ||
302 | static void __wl1271_op_remove_interface(struct wl1271 *wl); | 313 | static void __wl1271_op_remove_interface(struct wl1271 *wl); |
@@ -523,13 +534,19 @@ static int wl1271_plt_init(struct wl1271 *wl) | |||
523 | } | 534 | } |
524 | 535 | ||
525 | static void wl1271_fw_status(struct wl1271 *wl, | 536 | static void wl1271_fw_status(struct wl1271 *wl, |
526 | struct wl1271_fw_status *status) | 537 | struct wl1271_fw_full_status *full_status) |
527 | { | 538 | { |
539 | struct wl1271_fw_common_status *status = &full_status->common; | ||
528 | struct timespec ts; | 540 | struct timespec ts; |
529 | u32 total = 0; | 541 | u32 total = 0; |
530 | int i; | 542 | int i; |
531 | 543 | ||
532 | wl1271_raw_read(wl, FW_STATUS_ADDR, status, sizeof(*status), false); | 544 | if (wl->bss_type == BSS_TYPE_AP_BSS) |
545 | wl1271_raw_read(wl, FW_STATUS_ADDR, status, | ||
546 | sizeof(struct wl1271_fw_ap_status), false); | ||
547 | else | ||
548 | wl1271_raw_read(wl, FW_STATUS_ADDR, status, | ||
549 | sizeof(struct wl1271_fw_sta_status), false); | ||
533 | 550 | ||
534 | wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, " | 551 | wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, " |
535 | "drv_rx_counter = %d, tx_results_counter = %d)", | 552 | "drv_rx_counter = %d, tx_results_counter = %d)", |
@@ -588,7 +605,7 @@ static void wl1271_irq_work(struct work_struct *work) | |||
588 | loopcount--; | 605 | loopcount--; |
589 | 606 | ||
590 | wl1271_fw_status(wl, wl->fw_status); | 607 | wl1271_fw_status(wl, wl->fw_status); |
591 | intr = le32_to_cpu(wl->fw_status->intr); | 608 | intr = le32_to_cpu(wl->fw_status->common.intr); |
592 | if (!intr) { | 609 | if (!intr) { |
593 | wl1271_debug(DEBUG_IRQ, "Zero interrupt received."); | 610 | wl1271_debug(DEBUG_IRQ, "Zero interrupt received."); |
594 | spin_lock_irqsave(&wl->wl_lock, flags); | 611 | spin_lock_irqsave(&wl->wl_lock, flags); |
@@ -610,7 +627,7 @@ static void wl1271_irq_work(struct work_struct *work) | |||
610 | wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); | 627 | wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); |
611 | 628 | ||
612 | /* check for tx results */ | 629 | /* check for tx results */ |
613 | if (wl->fw_status->tx_results_counter != | 630 | if (wl->fw_status->common.tx_results_counter != |
614 | (wl->tx_results_count & 0xff)) | 631 | (wl->tx_results_count & 0xff)) |
615 | wl1271_tx_complete(wl); | 632 | wl1271_tx_complete(wl); |
616 | 633 | ||
@@ -624,7 +641,7 @@ static void wl1271_irq_work(struct work_struct *work) | |||
624 | wl1271_tx_work_locked(wl); | 641 | wl1271_tx_work_locked(wl); |
625 | } | 642 | } |
626 | 643 | ||
627 | wl1271_rx(wl, wl->fw_status); | 644 | wl1271_rx(wl, &wl->fw_status->common); |
628 | } | 645 | } |
629 | 646 | ||
630 | if (intr & WL1271_ACX_INTR_EVENT_A) { | 647 | if (intr & WL1271_ACX_INTR_EVENT_A) { |
@@ -961,39 +978,10 @@ int wl1271_plt_stop(struct wl1271 *wl) | |||
961 | static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | 978 | static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) |
962 | { | 979 | { |
963 | struct wl1271 *wl = hw->priv; | 980 | struct wl1271 *wl = hw->priv; |
964 | struct ieee80211_conf *conf = &hw->conf; | ||
965 | struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb); | ||
966 | struct ieee80211_sta *sta = txinfo->control.sta; | ||
967 | unsigned long flags; | 981 | unsigned long flags; |
968 | int q; | 982 | int q; |
969 | 983 | ||
970 | /* | ||
971 | * peek into the rates configured in the STA entry. | ||
972 | * The rates set after connection stage, The first block only BG sets: | ||
973 | * the compare is for bit 0-16 of sta_rate_set. The second block add | ||
974 | * HT rates in case of HT supported. | ||
975 | */ | ||
976 | spin_lock_irqsave(&wl->wl_lock, flags); | 984 | spin_lock_irqsave(&wl->wl_lock, flags); |
977 | if (sta && | ||
978 | (sta->supp_rates[conf->channel->band] != | ||
979 | (wl->sta_rate_set & HW_BG_RATES_MASK)) && | ||
980 | wl->bss_type != BSS_TYPE_AP_BSS) { | ||
981 | wl->sta_rate_set = sta->supp_rates[conf->channel->band]; | ||
982 | set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags); | ||
983 | } | ||
984 | |||
985 | #ifdef CONFIG_WL12XX_HT | ||
986 | if (sta && | ||
987 | sta->ht_cap.ht_supported && | ||
988 | ((wl->sta_rate_set >> HW_HT_RATES_OFFSET) != | ||
989 | sta->ht_cap.mcs.rx_mask[0])) { | ||
990 | /* Clean MCS bits before setting them */ | ||
991 | wl->sta_rate_set &= HW_BG_RATES_MASK; | ||
992 | wl->sta_rate_set |= | ||
993 | (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET); | ||
994 | set_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags); | ||
995 | } | ||
996 | #endif | ||
997 | wl->tx_queue_count++; | 985 | wl->tx_queue_count++; |
998 | spin_unlock_irqrestore(&wl->wl_lock, flags); | 986 | spin_unlock_irqrestore(&wl->wl_lock, flags); |
999 | 987 | ||
@@ -1228,7 +1216,6 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl) | |||
1228 | wl->time_offset = 0; | 1216 | wl->time_offset = 0; |
1229 | wl->session_counter = 0; | 1217 | wl->session_counter = 0; |
1230 | wl->rate_set = CONF_TX_RATE_MASK_BASIC; | 1218 | wl->rate_set = CONF_TX_RATE_MASK_BASIC; |
1231 | wl->sta_rate_set = 0; | ||
1232 | wl->flags = 0; | 1219 | wl->flags = 0; |
1233 | wl->vif = NULL; | 1220 | wl->vif = NULL; |
1234 | wl->filters = 0; | 1221 | wl->filters = 0; |
@@ -1415,7 +1402,6 @@ static int wl1271_sta_handle_idle(struct wl1271 *wl, bool idle) | |||
1415 | goto out; | 1402 | goto out; |
1416 | } | 1403 | } |
1417 | wl->rate_set = wl1271_tx_min_rate_get(wl); | 1404 | wl->rate_set = wl1271_tx_min_rate_get(wl); |
1418 | wl->sta_rate_set = 0; | ||
1419 | ret = wl1271_acx_sta_rate_policies(wl); | 1405 | ret = wl1271_acx_sta_rate_policies(wl); |
1420 | if (ret < 0) | 1406 | if (ret < 0) |
1421 | goto out; | 1407 | goto out; |
@@ -2229,6 +2215,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, | |||
2229 | { | 2215 | { |
2230 | bool do_join = false, set_assoc = false; | 2216 | bool do_join = false, set_assoc = false; |
2231 | bool is_ibss = (wl->bss_type == BSS_TYPE_IBSS); | 2217 | bool is_ibss = (wl->bss_type == BSS_TYPE_IBSS); |
2218 | u32 sta_rate_set = 0; | ||
2232 | int ret; | 2219 | int ret; |
2233 | struct ieee80211_sta *sta; | 2220 | struct ieee80211_sta *sta; |
2234 | 2221 | ||
@@ -2294,6 +2281,49 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, | |||
2294 | } | 2281 | } |
2295 | } | 2282 | } |
2296 | 2283 | ||
2284 | rcu_read_lock(); | ||
2285 | sta = ieee80211_find_sta(vif, bss_conf->bssid); | ||
2286 | if (sta) { | ||
2287 | /* save the supp_rates of the ap */ | ||
2288 | sta_rate_set = sta->supp_rates[wl->hw->conf.channel->band]; | ||
2289 | if (sta->ht_cap.ht_supported) | ||
2290 | sta_rate_set |= | ||
2291 | (sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET); | ||
2292 | |||
2293 | /* handle new association with HT and HT information change */ | ||
2294 | if ((changed & BSS_CHANGED_HT) && | ||
2295 | (bss_conf->channel_type != NL80211_CHAN_NO_HT)) { | ||
2296 | ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, | ||
2297 | true); | ||
2298 | if (ret < 0) { | ||
2299 | wl1271_warning("Set ht cap true failed %d", | ||
2300 | ret); | ||
2301 | rcu_read_unlock(); | ||
2302 | goto out; | ||
2303 | } | ||
2304 | ret = wl1271_acx_set_ht_information(wl, | ||
2305 | bss_conf->ht_operation_mode); | ||
2306 | if (ret < 0) { | ||
2307 | wl1271_warning("Set ht information failed %d", | ||
2308 | ret); | ||
2309 | rcu_read_unlock(); | ||
2310 | goto out; | ||
2311 | } | ||
2312 | } | ||
2313 | /* handle new association without HT and disassociation */ | ||
2314 | else if (changed & BSS_CHANGED_ASSOC) { | ||
2315 | ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, | ||
2316 | false); | ||
2317 | if (ret < 0) { | ||
2318 | wl1271_warning("Set ht cap false failed %d", | ||
2319 | ret); | ||
2320 | rcu_read_unlock(); | ||
2321 | goto out; | ||
2322 | } | ||
2323 | } | ||
2324 | } | ||
2325 | rcu_read_unlock(); | ||
2326 | |||
2297 | if ((changed & BSS_CHANGED_ASSOC)) { | 2327 | if ((changed & BSS_CHANGED_ASSOC)) { |
2298 | if (bss_conf->assoc) { | 2328 | if (bss_conf->assoc) { |
2299 | u32 rates; | 2329 | u32 rates; |
@@ -2311,6 +2341,9 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, | |||
2311 | wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, | 2341 | wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, |
2312 | rates); | 2342 | rates); |
2313 | wl->basic_rate = wl1271_tx_min_rate_get(wl); | 2343 | wl->basic_rate = wl1271_tx_min_rate_get(wl); |
2344 | if (sta_rate_set) | ||
2345 | wl->rate_set = wl1271_tx_enabled_rates_get(wl, | ||
2346 | sta_rate_set); | ||
2314 | ret = wl1271_acx_sta_rate_policies(wl); | 2347 | ret = wl1271_acx_sta_rate_policies(wl); |
2315 | if (ret < 0) | 2348 | if (ret < 0) |
2316 | goto out; | 2349 | goto out; |
@@ -2389,43 +2422,6 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, | |||
2389 | if (ret < 0) | 2422 | if (ret < 0) |
2390 | goto out; | 2423 | goto out; |
2391 | 2424 | ||
2392 | rcu_read_lock(); | ||
2393 | sta = ieee80211_find_sta(vif, bss_conf->bssid); | ||
2394 | if (sta) { | ||
2395 | /* handle new association with HT and HT information change */ | ||
2396 | if ((changed & BSS_CHANGED_HT) && | ||
2397 | (bss_conf->channel_type != NL80211_CHAN_NO_HT)) { | ||
2398 | ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, | ||
2399 | true); | ||
2400 | if (ret < 0) { | ||
2401 | wl1271_warning("Set ht cap true failed %d", | ||
2402 | ret); | ||
2403 | rcu_read_unlock(); | ||
2404 | goto out; | ||
2405 | } | ||
2406 | ret = wl1271_acx_set_ht_information(wl, | ||
2407 | bss_conf->ht_operation_mode); | ||
2408 | if (ret < 0) { | ||
2409 | wl1271_warning("Set ht information failed %d", | ||
2410 | ret); | ||
2411 | rcu_read_unlock(); | ||
2412 | goto out; | ||
2413 | } | ||
2414 | } | ||
2415 | /* handle new association without HT and disassociation */ | ||
2416 | else if (changed & BSS_CHANGED_ASSOC) { | ||
2417 | ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, | ||
2418 | false); | ||
2419 | if (ret < 0) { | ||
2420 | wl1271_warning("Set ht cap false failed %d", | ||
2421 | ret); | ||
2422 | rcu_read_unlock(); | ||
2423 | goto out; | ||
2424 | } | ||
2425 | } | ||
2426 | } | ||
2427 | rcu_read_unlock(); | ||
2428 | |||
2429 | if (changed & BSS_CHANGED_ARP_FILTER) { | 2425 | if (changed & BSS_CHANGED_ARP_FILTER) { |
2430 | __be32 addr = bss_conf->arp_addr_list[0]; | 2426 | __be32 addr = bss_conf->arp_addr_list[0]; |
2431 | WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS); | 2427 | WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS); |
@@ -3313,7 +3309,6 @@ struct ieee80211_hw *wl1271_alloc_hw(void) | |||
3313 | wl->basic_rate_set = CONF_TX_RATE_MASK_BASIC; | 3309 | wl->basic_rate_set = CONF_TX_RATE_MASK_BASIC; |
3314 | wl->basic_rate = CONF_TX_RATE_MASK_BASIC; | 3310 | wl->basic_rate = CONF_TX_RATE_MASK_BASIC; |
3315 | wl->rate_set = CONF_TX_RATE_MASK_BASIC; | 3311 | wl->rate_set = CONF_TX_RATE_MASK_BASIC; |
3316 | wl->sta_rate_set = 0; | ||
3317 | wl->band = IEEE80211_BAND_2GHZ; | 3312 | wl->band = IEEE80211_BAND_2GHZ; |
3318 | wl->vif = NULL; | 3313 | wl->vif = NULL; |
3319 | wl->flags = 0; | 3314 | wl->flags = 0; |
diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c index 60a3738eadb0..2d3086ae6338 100644 --- a/drivers/net/wireless/wl12xx/ps.c +++ b/drivers/net/wireless/wl12xx/ps.c | |||
@@ -139,8 +139,7 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, | |||
139 | return ret; | 139 | return ret; |
140 | } | 140 | } |
141 | 141 | ||
142 | ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE, | 142 | ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE); |
143 | rates, send); | ||
144 | if (ret < 0) | 143 | if (ret < 0) |
145 | return ret; | 144 | return ret; |
146 | 145 | ||
@@ -163,8 +162,7 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode, | |||
163 | if (ret < 0) | 162 | if (ret < 0) |
164 | return ret; | 163 | return ret; |
165 | 164 | ||
166 | ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE, | 165 | ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE); |
167 | rates, send); | ||
168 | if (ret < 0) | 166 | if (ret < 0) |
169 | return ret; | 167 | return ret; |
170 | 168 | ||
diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c index b0c6ddc2a945..00d250d8da18 100644 --- a/drivers/net/wireless/wl12xx/rx.c +++ b/drivers/net/wireless/wl12xx/rx.c | |||
@@ -29,14 +29,14 @@ | |||
29 | #include "rx.h" | 29 | #include "rx.h" |
30 | #include "io.h" | 30 | #include "io.h" |
31 | 31 | ||
32 | static u8 wl1271_rx_get_mem_block(struct wl1271_fw_status *status, | 32 | static u8 wl1271_rx_get_mem_block(struct wl1271_fw_common_status *status, |
33 | u32 drv_rx_counter) | 33 | u32 drv_rx_counter) |
34 | { | 34 | { |
35 | return le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) & | 35 | return le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) & |
36 | RX_MEM_BLOCK_MASK; | 36 | RX_MEM_BLOCK_MASK; |
37 | } | 37 | } |
38 | 38 | ||
39 | static u32 wl1271_rx_get_buf_size(struct wl1271_fw_status *status, | 39 | static u32 wl1271_rx_get_buf_size(struct wl1271_fw_common_status *status, |
40 | u32 drv_rx_counter) | 40 | u32 drv_rx_counter) |
41 | { | 41 | { |
42 | return (le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) & | 42 | return (le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]) & |
@@ -134,7 +134,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length) | |||
134 | return 0; | 134 | return 0; |
135 | } | 135 | } |
136 | 136 | ||
137 | void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status) | 137 | void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status) |
138 | { | 138 | { |
139 | struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map; | 139 | struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map; |
140 | u32 buf_size; | 140 | u32 buf_size; |
diff --git a/drivers/net/wireless/wl12xx/rx.h b/drivers/net/wireless/wl12xx/rx.h index 8d048b36bbba..4cef8fa3dee1 100644 --- a/drivers/net/wireless/wl12xx/rx.h +++ b/drivers/net/wireless/wl12xx/rx.h | |||
@@ -119,7 +119,7 @@ struct wl1271_rx_descriptor { | |||
119 | u8 reserved; | 119 | u8 reserved; |
120 | } __packed; | 120 | } __packed; |
121 | 121 | ||
122 | void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status); | 122 | void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_common_status *status); |
123 | u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); | 123 | u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); |
124 | void wl1271_set_default_filters(struct wl1271 *wl); | 124 | void wl1271_set_default_filters(struct wl1271 *wl); |
125 | 125 | ||
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c index 3507c81c7500..67a00946e3dd 100644 --- a/drivers/net/wireless/wl12xx/tx.c +++ b/drivers/net/wireless/wl12xx/tx.c | |||
@@ -334,35 +334,13 @@ void wl1271_tx_work_locked(struct wl1271 *wl) | |||
334 | { | 334 | { |
335 | struct sk_buff *skb; | 335 | struct sk_buff *skb; |
336 | bool woken_up = false; | 336 | bool woken_up = false; |
337 | u32 sta_rates = 0; | ||
338 | u32 buf_offset = 0; | 337 | u32 buf_offset = 0; |
339 | bool sent_packets = false; | 338 | bool sent_packets = false; |
340 | int ret; | 339 | int ret; |
341 | 340 | ||
342 | /* check if the rates supported by the AP have changed */ | ||
343 | if (unlikely(test_and_clear_bit(WL1271_FLAG_STA_RATES_CHANGED, | ||
344 | &wl->flags))) { | ||
345 | unsigned long flags; | ||
346 | |||
347 | spin_lock_irqsave(&wl->wl_lock, flags); | ||
348 | sta_rates = wl->sta_rate_set; | ||
349 | spin_unlock_irqrestore(&wl->wl_lock, flags); | ||
350 | } | ||
351 | |||
352 | if (unlikely(wl->state == WL1271_STATE_OFF)) | 341 | if (unlikely(wl->state == WL1271_STATE_OFF)) |
353 | goto out; | 342 | goto out; |
354 | 343 | ||
355 | /* if rates have changed, re-configure the rate policy */ | ||
356 | if (unlikely(sta_rates)) { | ||
357 | ret = wl1271_ps_elp_wakeup(wl, false); | ||
358 | if (ret < 0) | ||
359 | goto out; | ||
360 | woken_up = true; | ||
361 | |||
362 | wl->rate_set = wl1271_tx_enabled_rates_get(wl, sta_rates); | ||
363 | wl1271_acx_sta_rate_policies(wl); | ||
364 | } | ||
365 | |||
366 | while ((skb = wl1271_skb_dequeue(wl))) { | 344 | while ((skb = wl1271_skb_dequeue(wl))) { |
367 | if (!woken_up) { | 345 | if (!woken_up) { |
368 | ret = wl1271_ps_elp_wakeup(wl, false); | 346 | ret = wl1271_ps_elp_wakeup(wl, false); |
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index d1de13fe7d9a..1d6c94304b1a 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h | |||
@@ -130,7 +130,7 @@ extern u32 wl12xx_debug_level; | |||
130 | 130 | ||
131 | 131 | ||
132 | 132 | ||
133 | #define WL1271_FW_NAME "wl1271-fw.bin" | 133 | #define WL1271_FW_NAME "wl1271-fw-2.bin" |
134 | #define WL1271_AP_FW_NAME "wl1271-fw-ap.bin" | 134 | #define WL1271_AP_FW_NAME "wl1271-fw-ap.bin" |
135 | 135 | ||
136 | #define WL1271_NVS_NAME "wl1271-nvs.bin" | 136 | #define WL1271_NVS_NAME "wl1271-nvs.bin" |
@@ -214,8 +214,8 @@ struct wl1271_stats { | |||
214 | /* Broadcast and Global links + links to stations */ | 214 | /* Broadcast and Global links + links to stations */ |
215 | #define AP_MAX_LINKS (AP_MAX_STATIONS + 2) | 215 | #define AP_MAX_LINKS (AP_MAX_STATIONS + 2) |
216 | 216 | ||
217 | /* FW status registers */ | 217 | /* FW status registers common for AP/STA */ |
218 | struct wl1271_fw_status { | 218 | struct wl1271_fw_common_status { |
219 | __le32 intr; | 219 | __le32 intr; |
220 | u8 fw_rx_counter; | 220 | u8 fw_rx_counter; |
221 | u8 drv_rx_counter; | 221 | u8 drv_rx_counter; |
@@ -224,6 +224,11 @@ struct wl1271_fw_status { | |||
224 | __le32 rx_pkt_descs[NUM_RX_PKT_DESC]; | 224 | __le32 rx_pkt_descs[NUM_RX_PKT_DESC]; |
225 | __le32 tx_released_blks[NUM_TX_QUEUES]; | 225 | __le32 tx_released_blks[NUM_TX_QUEUES]; |
226 | __le32 fw_localtime; | 226 | __le32 fw_localtime; |
227 | } __packed; | ||
228 | |||
229 | /* FW status registers for AP */ | ||
230 | struct wl1271_fw_ap_status { | ||
231 | struct wl1271_fw_common_status common; | ||
227 | 232 | ||
228 | /* Next fields valid only in AP FW */ | 233 | /* Next fields valid only in AP FW */ |
229 | 234 | ||
@@ -238,6 +243,24 @@ struct wl1271_fw_status { | |||
238 | u8 padding_1[1]; | 243 | u8 padding_1[1]; |
239 | } __packed; | 244 | } __packed; |
240 | 245 | ||
246 | /* FW status registers for STA */ | ||
247 | struct wl1271_fw_sta_status { | ||
248 | struct wl1271_fw_common_status common; | ||
249 | |||
250 | u8 tx_total; | ||
251 | u8 reserved1; | ||
252 | __le16 reserved2; | ||
253 | } __packed; | ||
254 | |||
255 | struct wl1271_fw_full_status { | ||
256 | union { | ||
257 | struct wl1271_fw_common_status common; | ||
258 | struct wl1271_fw_sta_status sta; | ||
259 | struct wl1271_fw_ap_status ap; | ||
260 | }; | ||
261 | } __packed; | ||
262 | |||
263 | |||
241 | struct wl1271_rx_mem_pool_addr { | 264 | struct wl1271_rx_mem_pool_addr { |
242 | u32 addr; | 265 | u32 addr; |
243 | u32 addr_extra; | 266 | u32 addr_extra; |
@@ -278,6 +301,24 @@ struct wl1271_ap_key { | |||
278 | u16 tx_seq_16; | 301 | u16 tx_seq_16; |
279 | }; | 302 | }; |
280 | 303 | ||
304 | enum wl12xx_flags { | ||
305 | WL1271_FLAG_STA_ASSOCIATED, | ||
306 | WL1271_FLAG_JOINED, | ||
307 | WL1271_FLAG_GPIO_POWER, | ||
308 | WL1271_FLAG_TX_QUEUE_STOPPED, | ||
309 | WL1271_FLAG_IN_ELP, | ||
310 | WL1271_FLAG_PSM, | ||
311 | WL1271_FLAG_PSM_REQUESTED, | ||
312 | WL1271_FLAG_IRQ_PENDING, | ||
313 | WL1271_FLAG_IRQ_RUNNING, | ||
314 | WL1271_FLAG_IDLE, | ||
315 | WL1271_FLAG_IDLE_REQUESTED, | ||
316 | WL1271_FLAG_PSPOLL_FAILURE, | ||
317 | WL1271_FLAG_STA_STATE_SENT, | ||
318 | WL1271_FLAG_FW_TX_BUSY, | ||
319 | WL1271_FLAG_AP_STARTED | ||
320 | }; | ||
321 | |||
281 | struct wl1271 { | 322 | struct wl1271 { |
282 | struct platform_device *plat_dev; | 323 | struct platform_device *plat_dev; |
283 | struct ieee80211_hw *hw; | 324 | struct ieee80211_hw *hw; |
@@ -296,22 +337,6 @@ struct wl1271 { | |||
296 | enum wl1271_state state; | 337 | enum wl1271_state state; |
297 | struct mutex mutex; | 338 | struct mutex mutex; |
298 | 339 | ||
299 | #define WL1271_FLAG_STA_RATES_CHANGED (0) | ||
300 | #define WL1271_FLAG_STA_ASSOCIATED (1) | ||
301 | #define WL1271_FLAG_JOINED (2) | ||
302 | #define WL1271_FLAG_GPIO_POWER (3) | ||
303 | #define WL1271_FLAG_TX_QUEUE_STOPPED (4) | ||
304 | #define WL1271_FLAG_IN_ELP (5) | ||
305 | #define WL1271_FLAG_PSM (6) | ||
306 | #define WL1271_FLAG_PSM_REQUESTED (7) | ||
307 | #define WL1271_FLAG_IRQ_PENDING (8) | ||
308 | #define WL1271_FLAG_IRQ_RUNNING (9) | ||
309 | #define WL1271_FLAG_IDLE (10) | ||
310 | #define WL1271_FLAG_IDLE_REQUESTED (11) | ||
311 | #define WL1271_FLAG_PSPOLL_FAILURE (12) | ||
312 | #define WL1271_FLAG_STA_STATE_SENT (13) | ||
313 | #define WL1271_FLAG_FW_TX_BUSY (14) | ||
314 | #define WL1271_FLAG_AP_STARTED (15) | ||
315 | unsigned long flags; | 340 | unsigned long flags; |
316 | 341 | ||
317 | struct wl1271_partition_set part; | 342 | struct wl1271_partition_set part; |
@@ -405,7 +430,6 @@ struct wl1271 { | |||
405 | * bits 16-23 - 802.11n MCS index mask | 430 | * bits 16-23 - 802.11n MCS index mask |
406 | * support only 1 stream, thus only 8 bits for the MCS rates (0-7). | 431 | * support only 1 stream, thus only 8 bits for the MCS rates (0-7). |
407 | */ | 432 | */ |
408 | u32 sta_rate_set; | ||
409 | u32 basic_rate_set; | 433 | u32 basic_rate_set; |
410 | u32 basic_rate; | 434 | u32 basic_rate; |
411 | u32 rate_set; | 435 | u32 rate_set; |
@@ -445,7 +469,7 @@ struct wl1271 { | |||
445 | u32 buffer_cmd; | 469 | u32 buffer_cmd; |
446 | u32 buffer_busyword[WL1271_BUSY_WORD_CNT]; | 470 | u32 buffer_busyword[WL1271_BUSY_WORD_CNT]; |
447 | 471 | ||
448 | struct wl1271_fw_status *fw_status; | 472 | struct wl1271_fw_full_status *fw_status; |
449 | struct wl1271_tx_hw_res_if *tx_res_if; | 473 | struct wl1271_tx_hw_res_if *tx_res_if; |
450 | 474 | ||
451 | struct ieee80211_vif *vif; | 475 | struct ieee80211_vif *vif; |
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index 54f68f134ea7..a73a305d3cba 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c | |||
@@ -142,8 +142,9 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr | |||
142 | return 0; | 142 | return 0; |
143 | } | 143 | } |
144 | 144 | ||
145 | int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, | 145 | static int _zd_iowrite32v_async_locked(struct zd_chip *chip, |
146 | unsigned int count) | 146 | const struct zd_ioreq32 *ioreqs, |
147 | unsigned int count) | ||
147 | { | 148 | { |
148 | int i, j, r; | 149 | int i, j, r; |
149 | struct zd_ioreq16 ioreqs16[USB_MAX_IOWRITE32_COUNT * 2]; | 150 | struct zd_ioreq16 ioreqs16[USB_MAX_IOWRITE32_COUNT * 2]; |
@@ -170,7 +171,7 @@ int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, | |||
170 | ioreqs16[j+1].addr = ioreqs[i].addr; | 171 | ioreqs16[j+1].addr = ioreqs[i].addr; |
171 | } | 172 | } |
172 | 173 | ||
173 | r = zd_usb_iowrite16v(&chip->usb, ioreqs16, count16); | 174 | r = zd_usb_iowrite16v_async(&chip->usb, ioreqs16, count16); |
174 | #ifdef DEBUG | 175 | #ifdef DEBUG |
175 | if (r) { | 176 | if (r) { |
176 | dev_dbg_f(zd_chip_dev(chip), | 177 | dev_dbg_f(zd_chip_dev(chip), |
@@ -180,6 +181,20 @@ int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, | |||
180 | return r; | 181 | return r; |
181 | } | 182 | } |
182 | 183 | ||
184 | int _zd_iowrite32v_locked(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, | ||
185 | unsigned int count) | ||
186 | { | ||
187 | int r; | ||
188 | |||
189 | zd_usb_iowrite16v_async_start(&chip->usb); | ||
190 | r = _zd_iowrite32v_async_locked(chip, ioreqs, count); | ||
191 | if (r) { | ||
192 | zd_usb_iowrite16v_async_end(&chip->usb, 0); | ||
193 | return r; | ||
194 | } | ||
195 | return zd_usb_iowrite16v_async_end(&chip->usb, 50 /* ms */); | ||
196 | } | ||
197 | |||
183 | int zd_iowrite16a_locked(struct zd_chip *chip, | 198 | int zd_iowrite16a_locked(struct zd_chip *chip, |
184 | const struct zd_ioreq16 *ioreqs, unsigned int count) | 199 | const struct zd_ioreq16 *ioreqs, unsigned int count) |
185 | { | 200 | { |
@@ -187,6 +202,8 @@ int zd_iowrite16a_locked(struct zd_chip *chip, | |||
187 | unsigned int i, j, t, max; | 202 | unsigned int i, j, t, max; |
188 | 203 | ||
189 | ZD_ASSERT(mutex_is_locked(&chip->mutex)); | 204 | ZD_ASSERT(mutex_is_locked(&chip->mutex)); |
205 | zd_usb_iowrite16v_async_start(&chip->usb); | ||
206 | |||
190 | for (i = 0; i < count; i += j + t) { | 207 | for (i = 0; i < count; i += j + t) { |
191 | t = 0; | 208 | t = 0; |
192 | max = count-i; | 209 | max = count-i; |
@@ -199,8 +216,9 @@ int zd_iowrite16a_locked(struct zd_chip *chip, | |||
199 | } | 216 | } |
200 | } | 217 | } |
201 | 218 | ||
202 | r = zd_usb_iowrite16v(&chip->usb, &ioreqs[i], j); | 219 | r = zd_usb_iowrite16v_async(&chip->usb, &ioreqs[i], j); |
203 | if (r) { | 220 | if (r) { |
221 | zd_usb_iowrite16v_async_end(&chip->usb, 0); | ||
204 | dev_dbg_f(zd_chip_dev(chip), | 222 | dev_dbg_f(zd_chip_dev(chip), |
205 | "error zd_usb_iowrite16v. Error number %d\n", | 223 | "error zd_usb_iowrite16v. Error number %d\n", |
206 | r); | 224 | r); |
@@ -208,7 +226,7 @@ int zd_iowrite16a_locked(struct zd_chip *chip, | |||
208 | } | 226 | } |
209 | } | 227 | } |
210 | 228 | ||
211 | return 0; | 229 | return zd_usb_iowrite16v_async_end(&chip->usb, 50 /* ms */); |
212 | } | 230 | } |
213 | 231 | ||
214 | /* Writes a variable number of 32 bit registers. The functions will split | 232 | /* Writes a variable number of 32 bit registers. The functions will split |
@@ -221,6 +239,8 @@ int zd_iowrite32a_locked(struct zd_chip *chip, | |||
221 | int r; | 239 | int r; |
222 | unsigned int i, j, t, max; | 240 | unsigned int i, j, t, max; |
223 | 241 | ||
242 | zd_usb_iowrite16v_async_start(&chip->usb); | ||
243 | |||
224 | for (i = 0; i < count; i += j + t) { | 244 | for (i = 0; i < count; i += j + t) { |
225 | t = 0; | 245 | t = 0; |
226 | max = count-i; | 246 | max = count-i; |
@@ -233,8 +253,9 @@ int zd_iowrite32a_locked(struct zd_chip *chip, | |||
233 | } | 253 | } |
234 | } | 254 | } |
235 | 255 | ||
236 | r = _zd_iowrite32v_locked(chip, &ioreqs[i], j); | 256 | r = _zd_iowrite32v_async_locked(chip, &ioreqs[i], j); |
237 | if (r) { | 257 | if (r) { |
258 | zd_usb_iowrite16v_async_end(&chip->usb, 0); | ||
238 | dev_dbg_f(zd_chip_dev(chip), | 259 | dev_dbg_f(zd_chip_dev(chip), |
239 | "error _zd_iowrite32v_locked." | 260 | "error _zd_iowrite32v_locked." |
240 | " Error number %d\n", r); | 261 | " Error number %d\n", r); |
@@ -242,7 +263,7 @@ int zd_iowrite32a_locked(struct zd_chip *chip, | |||
242 | } | 263 | } |
243 | } | 264 | } |
244 | 265 | ||
245 | return 0; | 266 | return zd_usb_iowrite16v_async_end(&chip->usb, 50 /* ms */); |
246 | } | 267 | } |
247 | 268 | ||
248 | int zd_ioread16(struct zd_chip *chip, zd_addr_t addr, u16 *value) | 269 | int zd_ioread16(struct zd_chip *chip, zd_addr_t addr, u16 *value) |
diff --git a/drivers/net/wireless/zd1211rw/zd_def.h b/drivers/net/wireless/zd1211rw/zd_def.h index 6ac597ffd3b9..5463ca9ebc01 100644 --- a/drivers/net/wireless/zd1211rw/zd_def.h +++ b/drivers/net/wireless/zd1211rw/zd_def.h | |||
@@ -45,7 +45,7 @@ typedef u16 __nocast zd_addr_t; | |||
45 | #ifdef DEBUG | 45 | #ifdef DEBUG |
46 | # define ZD_ASSERT(x) \ | 46 | # define ZD_ASSERT(x) \ |
47 | do { \ | 47 | do { \ |
48 | if (!(x)) { \ | 48 | if (unlikely(!(x))) { \ |
49 | pr_debug("%s:%d ASSERT %s VIOLATED!\n", \ | 49 | pr_debug("%s:%d ASSERT %s VIOLATED!\n", \ |
50 | __FILE__, __LINE__, __stringify(x)); \ | 50 | __FILE__, __LINE__, __stringify(x)); \ |
51 | dump_stack(); \ | 51 | dump_stack(); \ |
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index f6df3665fdb6..81e80489a052 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c | |||
@@ -1156,6 +1156,7 @@ void zd_usb_init(struct zd_usb *usb, struct ieee80211_hw *hw, | |||
1156 | memset(usb, 0, sizeof(*usb)); | 1156 | memset(usb, 0, sizeof(*usb)); |
1157 | usb->intf = usb_get_intf(intf); | 1157 | usb->intf = usb_get_intf(intf); |
1158 | usb_set_intfdata(usb->intf, hw); | 1158 | usb_set_intfdata(usb->intf, hw); |
1159 | init_usb_anchor(&usb->submitted_cmds); | ||
1159 | init_usb_interrupt(usb); | 1160 | init_usb_interrupt(usb); |
1160 | init_usb_tx(usb); | 1161 | init_usb_tx(usb); |
1161 | init_usb_rx(usb); | 1162 | init_usb_rx(usb); |
@@ -1634,15 +1635,15 @@ int zd_usb_ioread16v(struct zd_usb *usb, u16 *values, | |||
1634 | 1635 | ||
1635 | udev = zd_usb_to_usbdev(usb); | 1636 | udev = zd_usb_to_usbdev(usb); |
1636 | prepare_read_regs_int(usb); | 1637 | prepare_read_regs_int(usb); |
1637 | r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, EP_REGS_OUT), | 1638 | r = usb_interrupt_msg(udev, usb_sndintpipe(udev, EP_REGS_OUT), |
1638 | req, req_len, &actual_req_len, 50 /* ms */); | 1639 | req, req_len, &actual_req_len, 50 /* ms */); |
1639 | if (r) { | 1640 | if (r) { |
1640 | dev_dbg_f(zd_usb_dev(usb), | 1641 | dev_dbg_f(zd_usb_dev(usb), |
1641 | "error in usb_bulk_msg(). Error number %d\n", r); | 1642 | "error in usb_interrupt_msg(). Error number %d\n", r); |
1642 | goto error; | 1643 | goto error; |
1643 | } | 1644 | } |
1644 | if (req_len != actual_req_len) { | 1645 | if (req_len != actual_req_len) { |
1645 | dev_dbg_f(zd_usb_dev(usb), "error in usb_bulk_msg()\n" | 1646 | dev_dbg_f(zd_usb_dev(usb), "error in usb_interrupt_msg()\n" |
1646 | " req_len %d != actual_req_len %d\n", | 1647 | " req_len %d != actual_req_len %d\n", |
1647 | req_len, actual_req_len); | 1648 | req_len, actual_req_len); |
1648 | r = -EIO; | 1649 | r = -EIO; |
@@ -1663,13 +1664,103 @@ error: | |||
1663 | return r; | 1664 | return r; |
1664 | } | 1665 | } |
1665 | 1666 | ||
1666 | int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, | 1667 | static void iowrite16v_urb_complete(struct urb *urb) |
1667 | unsigned int count) | 1668 | { |
1669 | struct zd_usb *usb = urb->context; | ||
1670 | |||
1671 | if (urb->status && !usb->cmd_error) | ||
1672 | usb->cmd_error = urb->status; | ||
1673 | } | ||
1674 | |||
1675 | static int zd_submit_waiting_urb(struct zd_usb *usb, bool last) | ||
1676 | { | ||
1677 | int r = 0; | ||
1678 | struct urb *urb = usb->urb_async_waiting; | ||
1679 | |||
1680 | if (!urb) | ||
1681 | return 0; | ||
1682 | |||
1683 | usb->urb_async_waiting = NULL; | ||
1684 | |||
1685 | if (!last) | ||
1686 | urb->transfer_flags |= URB_NO_INTERRUPT; | ||
1687 | |||
1688 | usb_anchor_urb(urb, &usb->submitted_cmds); | ||
1689 | r = usb_submit_urb(urb, GFP_KERNEL); | ||
1690 | if (r) { | ||
1691 | usb_unanchor_urb(urb); | ||
1692 | dev_dbg_f(zd_usb_dev(usb), | ||
1693 | "error in usb_submit_urb(). Error number %d\n", r); | ||
1694 | goto error; | ||
1695 | } | ||
1696 | |||
1697 | /* fall-through with r == 0 */ | ||
1698 | error: | ||
1699 | usb_free_urb(urb); | ||
1700 | return r; | ||
1701 | } | ||
1702 | |||
1703 | void zd_usb_iowrite16v_async_start(struct zd_usb *usb) | ||
1704 | { | ||
1705 | ZD_ASSERT(usb_anchor_empty(&usb->submitted_cmds)); | ||
1706 | ZD_ASSERT(usb->urb_async_waiting == NULL); | ||
1707 | ZD_ASSERT(!usb->in_async); | ||
1708 | |||
1709 | ZD_ASSERT(mutex_is_locked(&zd_usb_to_chip(usb)->mutex)); | ||
1710 | |||
1711 | usb->in_async = 1; | ||
1712 | usb->cmd_error = 0; | ||
1713 | usb->urb_async_waiting = NULL; | ||
1714 | } | ||
1715 | |||
1716 | int zd_usb_iowrite16v_async_end(struct zd_usb *usb, unsigned int timeout) | ||
1717 | { | ||
1718 | int r; | ||
1719 | |||
1720 | ZD_ASSERT(mutex_is_locked(&zd_usb_to_chip(usb)->mutex)); | ||
1721 | ZD_ASSERT(usb->in_async); | ||
1722 | |||
1723 | /* Submit last iowrite16v URB */ | ||
1724 | r = zd_submit_waiting_urb(usb, true); | ||
1725 | if (r) { | ||
1726 | dev_dbg_f(zd_usb_dev(usb), | ||
1727 | "error in zd_submit_waiting_usb(). " | ||
1728 | "Error number %d\n", r); | ||
1729 | |||
1730 | usb_kill_anchored_urbs(&usb->submitted_cmds); | ||
1731 | goto error; | ||
1732 | } | ||
1733 | |||
1734 | if (timeout) | ||
1735 | timeout = usb_wait_anchor_empty_timeout(&usb->submitted_cmds, | ||
1736 | timeout); | ||
1737 | if (!timeout) { | ||
1738 | usb_kill_anchored_urbs(&usb->submitted_cmds); | ||
1739 | if (usb->cmd_error == -ENOENT) { | ||
1740 | dev_dbg_f(zd_usb_dev(usb), "timed out"); | ||
1741 | r = -ETIMEDOUT; | ||
1742 | goto error; | ||
1743 | } | ||
1744 | } | ||
1745 | |||
1746 | r = usb->cmd_error; | ||
1747 | error: | ||
1748 | usb->in_async = 0; | ||
1749 | return r; | ||
1750 | } | ||
1751 | |||
1752 | int zd_usb_iowrite16v_async(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, | ||
1753 | unsigned int count) | ||
1668 | { | 1754 | { |
1669 | int r; | 1755 | int r; |
1670 | struct usb_device *udev; | 1756 | struct usb_device *udev; |
1671 | struct usb_req_write_regs *req = NULL; | 1757 | struct usb_req_write_regs *req = NULL; |
1672 | int i, req_len, actual_req_len; | 1758 | int i, req_len; |
1759 | struct urb *urb; | ||
1760 | struct usb_host_endpoint *ep; | ||
1761 | |||
1762 | ZD_ASSERT(mutex_is_locked(&zd_usb_to_chip(usb)->mutex)); | ||
1763 | ZD_ASSERT(usb->in_async); | ||
1673 | 1764 | ||
1674 | if (count == 0) | 1765 | if (count == 0) |
1675 | return 0; | 1766 | return 0; |
@@ -1685,17 +1776,23 @@ int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, | |||
1685 | return -EWOULDBLOCK; | 1776 | return -EWOULDBLOCK; |
1686 | } | 1777 | } |
1687 | 1778 | ||
1688 | ZD_ASSERT(mutex_is_locked(&zd_usb_to_chip(usb)->mutex)); | 1779 | udev = zd_usb_to_usbdev(usb); |
1689 | BUILD_BUG_ON(sizeof(struct usb_req_write_regs) + | 1780 | |
1690 | USB_MAX_IOWRITE16_COUNT * sizeof(struct reg_data) > | 1781 | ep = usb_pipe_endpoint(udev, usb_sndintpipe(udev, EP_REGS_OUT)); |
1691 | sizeof(usb->req_buf)); | 1782 | if (!ep) |
1692 | BUG_ON(sizeof(struct usb_req_write_regs) + | 1783 | return -ENOENT; |
1693 | count * sizeof(struct reg_data) > | 1784 | |
1694 | sizeof(usb->req_buf)); | 1785 | urb = usb_alloc_urb(0, GFP_KERNEL); |
1786 | if (!urb) | ||
1787 | return -ENOMEM; | ||
1695 | 1788 | ||
1696 | req_len = sizeof(struct usb_req_write_regs) + | 1789 | req_len = sizeof(struct usb_req_write_regs) + |
1697 | count * sizeof(struct reg_data); | 1790 | count * sizeof(struct reg_data); |
1698 | req = (void *)usb->req_buf; | 1791 | req = kmalloc(req_len, GFP_KERNEL); |
1792 | if (!req) { | ||
1793 | r = -ENOMEM; | ||
1794 | goto error; | ||
1795 | } | ||
1699 | 1796 | ||
1700 | req->id = cpu_to_le16(USB_REQ_WRITE_REGS); | 1797 | req->id = cpu_to_le16(USB_REQ_WRITE_REGS); |
1701 | for (i = 0; i < count; i++) { | 1798 | for (i = 0; i < count; i++) { |
@@ -1704,28 +1801,44 @@ int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, | |||
1704 | rw->value = cpu_to_le16(ioreqs[i].value); | 1801 | rw->value = cpu_to_le16(ioreqs[i].value); |
1705 | } | 1802 | } |
1706 | 1803 | ||
1707 | udev = zd_usb_to_usbdev(usb); | 1804 | usb_fill_int_urb(urb, udev, usb_sndintpipe(udev, EP_REGS_OUT), |
1708 | r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, EP_REGS_OUT), | 1805 | req, req_len, iowrite16v_urb_complete, usb, |
1709 | req, req_len, &actual_req_len, 50 /* ms */); | 1806 | ep->desc.bInterval); |
1807 | urb->transfer_flags |= URB_FREE_BUFFER | URB_SHORT_NOT_OK; | ||
1808 | |||
1809 | /* Submit previous URB */ | ||
1810 | r = zd_submit_waiting_urb(usb, false); | ||
1710 | if (r) { | 1811 | if (r) { |
1711 | dev_dbg_f(zd_usb_dev(usb), | 1812 | dev_dbg_f(zd_usb_dev(usb), |
1712 | "error in usb_bulk_msg(). Error number %d\n", r); | 1813 | "error in zd_submit_waiting_usb(). " |
1713 | goto error; | 1814 | "Error number %d\n", r); |
1714 | } | ||
1715 | if (req_len != actual_req_len) { | ||
1716 | dev_dbg_f(zd_usb_dev(usb), | ||
1717 | "error in usb_bulk_msg()" | ||
1718 | " req_len %d != actual_req_len %d\n", | ||
1719 | req_len, actual_req_len); | ||
1720 | r = -EIO; | ||
1721 | goto error; | 1815 | goto error; |
1722 | } | 1816 | } |
1723 | 1817 | ||
1724 | /* FALL-THROUGH with r == 0 */ | 1818 | /* Delay submit so that URB_NO_INTERRUPT flag can be set for all URBs |
1819 | * of currect batch except for very last. | ||
1820 | */ | ||
1821 | usb->urb_async_waiting = urb; | ||
1822 | return 0; | ||
1725 | error: | 1823 | error: |
1824 | usb_free_urb(urb); | ||
1726 | return r; | 1825 | return r; |
1727 | } | 1826 | } |
1728 | 1827 | ||
1828 | int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, | ||
1829 | unsigned int count) | ||
1830 | { | ||
1831 | int r; | ||
1832 | |||
1833 | zd_usb_iowrite16v_async_start(usb); | ||
1834 | r = zd_usb_iowrite16v_async(usb, ioreqs, count); | ||
1835 | if (r) { | ||
1836 | zd_usb_iowrite16v_async_end(usb, 0); | ||
1837 | return r; | ||
1838 | } | ||
1839 | return zd_usb_iowrite16v_async_end(usb, 50 /* ms */); | ||
1840 | } | ||
1841 | |||
1729 | int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits) | 1842 | int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits) |
1730 | { | 1843 | { |
1731 | int r; | 1844 | int r; |
@@ -1794,15 +1907,15 @@ int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits) | |||
1794 | } | 1907 | } |
1795 | 1908 | ||
1796 | udev = zd_usb_to_usbdev(usb); | 1909 | udev = zd_usb_to_usbdev(usb); |
1797 | r = usb_bulk_msg(udev, usb_sndbulkpipe(udev, EP_REGS_OUT), | 1910 | r = usb_interrupt_msg(udev, usb_sndintpipe(udev, EP_REGS_OUT), |
1798 | req, req_len, &actual_req_len, 50 /* ms */); | 1911 | req, req_len, &actual_req_len, 50 /* ms */); |
1799 | if (r) { | 1912 | if (r) { |
1800 | dev_dbg_f(zd_usb_dev(usb), | 1913 | dev_dbg_f(zd_usb_dev(usb), |
1801 | "error in usb_bulk_msg(). Error number %d\n", r); | 1914 | "error in usb_interrupt_msg(). Error number %d\n", r); |
1802 | goto out; | 1915 | goto out; |
1803 | } | 1916 | } |
1804 | if (req_len != actual_req_len) { | 1917 | if (req_len != actual_req_len) { |
1805 | dev_dbg_f(zd_usb_dev(usb), "error in usb_bulk_msg()" | 1918 | dev_dbg_f(zd_usb_dev(usb), "error in usb_interrupt_msg()" |
1806 | " req_len %d != actual_req_len %d\n", | 1919 | " req_len %d != actual_req_len %d\n", |
1807 | req_len, actual_req_len); | 1920 | req_len, actual_req_len); |
1808 | r = -EIO; | 1921 | r = -EIO; |
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h index 2d688f48a34c..b3df2c8116cc 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.h +++ b/drivers/net/wireless/zd1211rw/zd_usb.h | |||
@@ -217,8 +217,11 @@ struct zd_usb { | |||
217 | struct zd_usb_rx rx; | 217 | struct zd_usb_rx rx; |
218 | struct zd_usb_tx tx; | 218 | struct zd_usb_tx tx; |
219 | struct usb_interface *intf; | 219 | struct usb_interface *intf; |
220 | struct usb_anchor submitted_cmds; | ||
221 | struct urb *urb_async_waiting; | ||
222 | int cmd_error; | ||
220 | u8 req_buf[64]; /* zd_usb_iowrite16v needs 62 bytes */ | 223 | u8 req_buf[64]; /* zd_usb_iowrite16v needs 62 bytes */ |
221 | u8 is_zd1211b:1, initialized:1, was_running:1; | 224 | u8 is_zd1211b:1, initialized:1, was_running:1, in_async:1; |
222 | }; | 225 | }; |
223 | 226 | ||
224 | #define zd_usb_dev(usb) (&usb->intf->dev) | 227 | #define zd_usb_dev(usb) (&usb->intf->dev) |
@@ -270,6 +273,10 @@ static inline int zd_usb_ioread16(struct zd_usb *usb, u16 *value, | |||
270 | return zd_usb_ioread16v(usb, value, (const zd_addr_t *)&addr, 1); | 273 | return zd_usb_ioread16v(usb, value, (const zd_addr_t *)&addr, 1); |
271 | } | 274 | } |
272 | 275 | ||
276 | void zd_usb_iowrite16v_async_start(struct zd_usb *usb); | ||
277 | int zd_usb_iowrite16v_async_end(struct zd_usb *usb, unsigned int timeout); | ||
278 | int zd_usb_iowrite16v_async(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, | ||
279 | unsigned int count); | ||
273 | int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, | 280 | int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs, |
274 | unsigned int count); | 281 | unsigned int count); |
275 | 282 | ||
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index 3918d2cc5856..e05ba6eefc7e 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c | |||
@@ -1192,10 +1192,10 @@ void ssb_device_enable(struct ssb_device *dev, u32 core_specific_flags) | |||
1192 | } | 1192 | } |
1193 | EXPORT_SYMBOL(ssb_device_enable); | 1193 | EXPORT_SYMBOL(ssb_device_enable); |
1194 | 1194 | ||
1195 | /* Wait for a bit in a register to get set or unset. | 1195 | /* Wait for bitmask in a register to get set or cleared. |
1196 | * timeout is in units of ten-microseconds */ | 1196 | * timeout is in units of ten-microseconds */ |
1197 | static int ssb_wait_bit(struct ssb_device *dev, u16 reg, u32 bitmask, | 1197 | static int ssb_wait_bits(struct ssb_device *dev, u16 reg, u32 bitmask, |
1198 | int timeout, int set) | 1198 | int timeout, int set) |
1199 | { | 1199 | { |
1200 | int i; | 1200 | int i; |
1201 | u32 val; | 1201 | u32 val; |
@@ -1203,7 +1203,7 @@ static int ssb_wait_bit(struct ssb_device *dev, u16 reg, u32 bitmask, | |||
1203 | for (i = 0; i < timeout; i++) { | 1203 | for (i = 0; i < timeout; i++) { |
1204 | val = ssb_read32(dev, reg); | 1204 | val = ssb_read32(dev, reg); |
1205 | if (set) { | 1205 | if (set) { |
1206 | if (val & bitmask) | 1206 | if ((val & bitmask) == bitmask) |
1207 | return 0; | 1207 | return 0; |
1208 | } else { | 1208 | } else { |
1209 | if (!(val & bitmask)) | 1209 | if (!(val & bitmask)) |
@@ -1220,20 +1220,38 @@ static int ssb_wait_bit(struct ssb_device *dev, u16 reg, u32 bitmask, | |||
1220 | 1220 | ||
1221 | void ssb_device_disable(struct ssb_device *dev, u32 core_specific_flags) | 1221 | void ssb_device_disable(struct ssb_device *dev, u32 core_specific_flags) |
1222 | { | 1222 | { |
1223 | u32 reject; | 1223 | u32 reject, val; |
1224 | 1224 | ||
1225 | if (ssb_read32(dev, SSB_TMSLOW) & SSB_TMSLOW_RESET) | 1225 | if (ssb_read32(dev, SSB_TMSLOW) & SSB_TMSLOW_RESET) |
1226 | return; | 1226 | return; |
1227 | 1227 | ||
1228 | reject = ssb_tmslow_reject_bitmask(dev); | 1228 | reject = ssb_tmslow_reject_bitmask(dev); |
1229 | ssb_write32(dev, SSB_TMSLOW, reject | SSB_TMSLOW_CLOCK); | 1229 | |
1230 | ssb_wait_bit(dev, SSB_TMSLOW, reject, 1000, 1); | 1230 | if (ssb_read32(dev, SSB_TMSLOW) & SSB_TMSLOW_CLOCK) { |
1231 | ssb_wait_bit(dev, SSB_TMSHIGH, SSB_TMSHIGH_BUSY, 1000, 0); | 1231 | ssb_write32(dev, SSB_TMSLOW, reject | SSB_TMSLOW_CLOCK); |
1232 | ssb_write32(dev, SSB_TMSLOW, | 1232 | ssb_wait_bits(dev, SSB_TMSLOW, reject, 1000, 1); |
1233 | SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | | 1233 | ssb_wait_bits(dev, SSB_TMSHIGH, SSB_TMSHIGH_BUSY, 1000, 0); |
1234 | reject | SSB_TMSLOW_RESET | | 1234 | |
1235 | core_specific_flags); | 1235 | if (ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_INITIATOR) { |
1236 | ssb_flush_tmslow(dev); | 1236 | val = ssb_read32(dev, SSB_IMSTATE); |
1237 | val |= SSB_IMSTATE_REJECT; | ||
1238 | ssb_write32(dev, SSB_IMSTATE, val); | ||
1239 | ssb_wait_bits(dev, SSB_IMSTATE, SSB_IMSTATE_BUSY, 1000, | ||
1240 | 0); | ||
1241 | } | ||
1242 | |||
1243 | ssb_write32(dev, SSB_TMSLOW, | ||
1244 | SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | | ||
1245 | reject | SSB_TMSLOW_RESET | | ||
1246 | core_specific_flags); | ||
1247 | ssb_flush_tmslow(dev); | ||
1248 | |||
1249 | if (ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_INITIATOR) { | ||
1250 | val = ssb_read32(dev, SSB_IMSTATE); | ||
1251 | val &= ~SSB_IMSTATE_REJECT; | ||
1252 | ssb_write32(dev, SSB_IMSTATE, val); | ||
1253 | } | ||
1254 | } | ||
1237 | 1255 | ||
1238 | ssb_write32(dev, SSB_TMSLOW, | 1256 | ssb_write32(dev, SSB_TMSLOW, |
1239 | reject | SSB_TMSLOW_RESET | | 1257 | reject | SSB_TMSLOW_RESET | |
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index 158449e55044..a467b20baac8 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c | |||
@@ -468,10 +468,14 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in) | |||
468 | SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 0); | 468 | SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 0); |
469 | SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0); | 469 | SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0); |
470 | SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0); | 470 | SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0); |
471 | SPEX(boardflags2_lo, SSB_SPROM4_BFL2LO, 0xFFFF, 0); | ||
472 | SPEX(boardflags2_hi, SSB_SPROM4_BFL2HI, 0xFFFF, 0); | ||
471 | } else { | 473 | } else { |
472 | SPEX(country_code, SSB_SPROM5_CCODE, 0xFFFF, 0); | 474 | SPEX(country_code, SSB_SPROM5_CCODE, 0xFFFF, 0); |
473 | SPEX(boardflags_lo, SSB_SPROM5_BFLLO, 0xFFFF, 0); | 475 | SPEX(boardflags_lo, SSB_SPROM5_BFLLO, 0xFFFF, 0); |
474 | SPEX(boardflags_hi, SSB_SPROM5_BFLHI, 0xFFFF, 0); | 476 | SPEX(boardflags_hi, SSB_SPROM5_BFLHI, 0xFFFF, 0); |
477 | SPEX(boardflags2_lo, SSB_SPROM5_BFL2LO, 0xFFFF, 0); | ||
478 | SPEX(boardflags2_hi, SSB_SPROM5_BFL2HI, 0xFFFF, 0); | ||
475 | } | 479 | } |
476 | SPEX(ant_available_a, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_A, | 480 | SPEX(ant_available_a, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_A, |
477 | SSB_SPROM4_ANTAVAIL_A_SHIFT); | 481 | SSB_SPROM4_ANTAVAIL_A_SHIFT); |
@@ -641,7 +645,7 @@ static int sprom_extract(struct ssb_bus *bus, struct ssb_sprom *out, | |||
641 | break; | 645 | break; |
642 | default: | 646 | default: |
643 | ssb_printk(KERN_WARNING PFX "Unsupported SPROM" | 647 | ssb_printk(KERN_WARNING PFX "Unsupported SPROM" |
644 | " revision %d detected. Will extract" | 648 | " revision %d detected. Will extract" |
645 | " v1\n", out->revision); | 649 | " v1\n", out->revision); |
646 | out->revision = 1; | 650 | out->revision = 1; |
647 | sprom_extract_r123(out, in); | 651 | sprom_extract_r123(out, in); |
diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index 991463f4a7f4..9b7b71c294b8 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c | |||
@@ -2313,7 +2313,9 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi) | |||
2313 | notif_bss_info->frame_len = | 2313 | notif_bss_info->frame_len = |
2314 | offsetof(struct ieee80211_mgmt, | 2314 | offsetof(struct ieee80211_mgmt, |
2315 | u.beacon.variable) + wl_get_ielen(wl); | 2315 | u.beacon.variable) + wl_get_ielen(wl); |
2316 | freq = ieee80211_channel_to_frequency(notif_bss_info->channel); | 2316 | freq = ieee80211_channel_to_frequency(notif_bss_info->channel, |
2317 | band->band); | ||
2318 | |||
2317 | channel = ieee80211_get_channel(wiphy, freq); | 2319 | channel = ieee80211_get_channel(wiphy, freq); |
2318 | 2320 | ||
2319 | WL_DBG("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM\n", | 2321 | WL_DBG("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM\n", |
diff --git a/include/linux/ssb/ssb_regs.h b/include/linux/ssb/ssb_regs.h index 489f7b6d61c5..402955ae48ce 100644 --- a/include/linux/ssb/ssb_regs.h +++ b/include/linux/ssb/ssb_regs.h | |||
@@ -85,6 +85,8 @@ | |||
85 | #define SSB_IMSTATE_AP_RSV 0x00000030 /* Reserved */ | 85 | #define SSB_IMSTATE_AP_RSV 0x00000030 /* Reserved */ |
86 | #define SSB_IMSTATE_IBE 0x00020000 /* In Band Error */ | 86 | #define SSB_IMSTATE_IBE 0x00020000 /* In Band Error */ |
87 | #define SSB_IMSTATE_TO 0x00040000 /* Timeout */ | 87 | #define SSB_IMSTATE_TO 0x00040000 /* Timeout */ |
88 | #define SSB_IMSTATE_BUSY 0x01800000 /* Busy (Backplane rev >= 2.3 only) */ | ||
89 | #define SSB_IMSTATE_REJECT 0x02000000 /* Reject (Backplane rev >= 2.3 only) */ | ||
88 | #define SSB_INTVEC 0x0F94 /* SB Interrupt Mask */ | 90 | #define SSB_INTVEC 0x0F94 /* SB Interrupt Mask */ |
89 | #define SSB_INTVEC_PCI 0x00000001 /* Enable interrupts for PCI */ | 91 | #define SSB_INTVEC_PCI 0x00000001 /* Enable interrupts for PCI */ |
90 | #define SSB_INTVEC_ENET0 0x00000002 /* Enable interrupts for enet 0 */ | 92 | #define SSB_INTVEC_ENET0 0x00000002 /* Enable interrupts for enet 0 */ |
@@ -97,7 +99,6 @@ | |||
97 | #define SSB_TMSLOW_RESET 0x00000001 /* Reset */ | 99 | #define SSB_TMSLOW_RESET 0x00000001 /* Reset */ |
98 | #define SSB_TMSLOW_REJECT_22 0x00000002 /* Reject (Backplane rev 2.2) */ | 100 | #define SSB_TMSLOW_REJECT_22 0x00000002 /* Reject (Backplane rev 2.2) */ |
99 | #define SSB_TMSLOW_REJECT_23 0x00000004 /* Reject (Backplane rev 2.3) */ | 101 | #define SSB_TMSLOW_REJECT_23 0x00000004 /* Reject (Backplane rev 2.3) */ |
100 | #define SSB_TMSLOW_PHYCLK 0x00000010 /* MAC PHY Clock Control Enable */ | ||
101 | #define SSB_TMSLOW_CLOCK 0x00010000 /* Clock Enable */ | 102 | #define SSB_TMSLOW_CLOCK 0x00010000 /* Clock Enable */ |
102 | #define SSB_TMSLOW_FGC 0x00020000 /* Force Gated Clocks On */ | 103 | #define SSB_TMSLOW_FGC 0x00020000 /* Force Gated Clocks On */ |
103 | #define SSB_TMSLOW_PE 0x40000000 /* Power Management Enable */ | 104 | #define SSB_TMSLOW_PE 0x40000000 /* Power Management Enable */ |
@@ -268,6 +269,8 @@ | |||
268 | /* SPROM Revision 4 */ | 269 | /* SPROM Revision 4 */ |
269 | #define SSB_SPROM4_BFLLO 0x0044 /* Boardflags (low 16 bits) */ | 270 | #define SSB_SPROM4_BFLLO 0x0044 /* Boardflags (low 16 bits) */ |
270 | #define SSB_SPROM4_BFLHI 0x0046 /* Board Flags Hi */ | 271 | #define SSB_SPROM4_BFLHI 0x0046 /* Board Flags Hi */ |
272 | #define SSB_SPROM4_BFL2LO 0x0048 /* Board flags 2 (low 16 bits) */ | ||
273 | #define SSB_SPROM4_BFL2HI 0x004A /* Board flags 2 Hi */ | ||
271 | #define SSB_SPROM4_IL0MAC 0x004C /* 6 byte MAC address for a/b/g/n */ | 274 | #define SSB_SPROM4_IL0MAC 0x004C /* 6 byte MAC address for a/b/g/n */ |
272 | #define SSB_SPROM4_CCODE 0x0052 /* Country Code (2 bytes) */ | 275 | #define SSB_SPROM4_CCODE 0x0052 /* Country Code (2 bytes) */ |
273 | #define SSB_SPROM4_GPIOA 0x0056 /* Gen. Purpose IO # 0 and 1 */ | 276 | #define SSB_SPROM4_GPIOA 0x0056 /* Gen. Purpose IO # 0 and 1 */ |
@@ -358,6 +361,8 @@ | |||
358 | #define SSB_SPROM5_CCODE 0x0044 /* Country Code (2 bytes) */ | 361 | #define SSB_SPROM5_CCODE 0x0044 /* Country Code (2 bytes) */ |
359 | #define SSB_SPROM5_BFLLO 0x004A /* Boardflags (low 16 bits) */ | 362 | #define SSB_SPROM5_BFLLO 0x004A /* Boardflags (low 16 bits) */ |
360 | #define SSB_SPROM5_BFLHI 0x004C /* Board Flags Hi */ | 363 | #define SSB_SPROM5_BFLHI 0x004C /* Board Flags Hi */ |
364 | #define SSB_SPROM5_BFL2LO 0x004E /* Board flags 2 (low 16 bits) */ | ||
365 | #define SSB_SPROM5_BFL2HI 0x0050 /* Board flags 2 Hi */ | ||
361 | #define SSB_SPROM5_IL0MAC 0x0052 /* 6 byte MAC address for a/b/g/n */ | 366 | #define SSB_SPROM5_IL0MAC 0x0052 /* 6 byte MAC address for a/b/g/n */ |
362 | #define SSB_SPROM5_GPIOA 0x0076 /* Gen. Purpose IO # 0 and 1 */ | 367 | #define SSB_SPROM5_GPIOA 0x0076 /* Gen. Purpose IO # 0 and 1 */ |
363 | #define SSB_SPROM5_GPIOA_P0 0x00FF /* Pin 0 */ | 368 | #define SSB_SPROM5_GPIOA_P0 0x00FF /* Pin 0 */ |
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 0c5e72503b77..43750439c521 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h | |||
@@ -64,6 +64,11 @@ struct bt_security { | |||
64 | 64 | ||
65 | #define BT_DEFER_SETUP 7 | 65 | #define BT_DEFER_SETUP 7 |
66 | 66 | ||
67 | #define BT_FLUSHABLE 8 | ||
68 | |||
69 | #define BT_FLUSHABLE_OFF 0 | ||
70 | #define BT_FLUSHABLE_ON 1 | ||
71 | |||
67 | #define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg) | 72 | #define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg) |
68 | #define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg) | 73 | #define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg) |
69 | #define BT_DBG(fmt, arg...) pr_debug("%s: " fmt "\n" , __func__ , ## arg) | 74 | #define BT_DBG(fmt, arg...) pr_debug("%s: " fmt "\n" , __func__ , ## arg) |
@@ -200,4 +205,32 @@ extern void bt_sysfs_cleanup(void); | |||
200 | 205 | ||
201 | extern struct dentry *bt_debugfs; | 206 | extern struct dentry *bt_debugfs; |
202 | 207 | ||
208 | #ifdef CONFIG_BT_L2CAP | ||
209 | int l2cap_init(void); | ||
210 | void l2cap_exit(void); | ||
211 | #else | ||
212 | static inline int l2cap_init(void) | ||
213 | { | ||
214 | return 0; | ||
215 | } | ||
216 | |||
217 | static inline void l2cap_exit(void) | ||
218 | { | ||
219 | } | ||
220 | #endif | ||
221 | |||
222 | #ifdef CONFIG_BT_SCO | ||
223 | int sco_init(void); | ||
224 | void sco_exit(void); | ||
225 | #else | ||
226 | static inline int sco_init(void) | ||
227 | { | ||
228 | return 0; | ||
229 | } | ||
230 | |||
231 | static inline void sco_exit(void) | ||
232 | { | ||
233 | } | ||
234 | #endif | ||
235 | |||
203 | #endif /* __BLUETOOTH_H */ | 236 | #endif /* __BLUETOOTH_H */ |
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 29a7a8ca0438..a5f8c4684a32 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h | |||
@@ -76,6 +76,14 @@ enum { | |||
76 | HCI_INQUIRY, | 76 | HCI_INQUIRY, |
77 | 77 | ||
78 | HCI_RAW, | 78 | HCI_RAW, |
79 | |||
80 | HCI_SETUP, | ||
81 | HCI_AUTO_OFF, | ||
82 | HCI_MGMT, | ||
83 | HCI_PAIRABLE, | ||
84 | HCI_SERVICE_CACHE, | ||
85 | HCI_LINK_KEYS, | ||
86 | HCI_DEBUG_KEYS, | ||
79 | }; | 87 | }; |
80 | 88 | ||
81 | /* HCI ioctl defines */ | 89 | /* HCI ioctl defines */ |
@@ -111,6 +119,7 @@ enum { | |||
111 | #define HCI_PAIRING_TIMEOUT (60000) /* 60 seconds */ | 119 | #define HCI_PAIRING_TIMEOUT (60000) /* 60 seconds */ |
112 | #define HCI_IDLE_TIMEOUT (6000) /* 6 seconds */ | 120 | #define HCI_IDLE_TIMEOUT (6000) /* 6 seconds */ |
113 | #define HCI_INIT_TIMEOUT (10000) /* 10 seconds */ | 121 | #define HCI_INIT_TIMEOUT (10000) /* 10 seconds */ |
122 | #define HCI_CMD_TIMEOUT (1000) /* 1 seconds */ | ||
114 | 123 | ||
115 | /* HCI data types */ | 124 | /* HCI data types */ |
116 | #define HCI_COMMAND_PKT 0x01 | 125 | #define HCI_COMMAND_PKT 0x01 |
@@ -150,6 +159,7 @@ enum { | |||
150 | #define EDR_ESCO_MASK (ESCO_2EV3 | ESCO_3EV3 | ESCO_2EV5 | ESCO_3EV5) | 159 | #define EDR_ESCO_MASK (ESCO_2EV3 | ESCO_3EV3 | ESCO_2EV5 | ESCO_3EV5) |
151 | 160 | ||
152 | /* ACL flags */ | 161 | /* ACL flags */ |
162 | #define ACL_START_NO_FLUSH 0x00 | ||
153 | #define ACL_CONT 0x01 | 163 | #define ACL_CONT 0x01 |
154 | #define ACL_START 0x02 | 164 | #define ACL_START 0x02 |
155 | #define ACL_ACTIVE_BCAST 0x04 | 165 | #define ACL_ACTIVE_BCAST 0x04 |
@@ -159,6 +169,8 @@ enum { | |||
159 | #define SCO_LINK 0x00 | 169 | #define SCO_LINK 0x00 |
160 | #define ACL_LINK 0x01 | 170 | #define ACL_LINK 0x01 |
161 | #define ESCO_LINK 0x02 | 171 | #define ESCO_LINK 0x02 |
172 | /* Low Energy links do not have defined link type. Use invented one */ | ||
173 | #define LE_LINK 0x80 | ||
162 | 174 | ||
163 | /* LMP features */ | 175 | /* LMP features */ |
164 | #define LMP_3SLOT 0x01 | 176 | #define LMP_3SLOT 0x01 |
@@ -183,17 +195,25 @@ enum { | |||
183 | #define LMP_PSCHEME 0x02 | 195 | #define LMP_PSCHEME 0x02 |
184 | #define LMP_PCONTROL 0x04 | 196 | #define LMP_PCONTROL 0x04 |
185 | 197 | ||
198 | #define LMP_RSSI_INQ 0x40 | ||
186 | #define LMP_ESCO 0x80 | 199 | #define LMP_ESCO 0x80 |
187 | 200 | ||
188 | #define LMP_EV4 0x01 | 201 | #define LMP_EV4 0x01 |
189 | #define LMP_EV5 0x02 | 202 | #define LMP_EV5 0x02 |
203 | #define LMP_LE 0x40 | ||
190 | 204 | ||
191 | #define LMP_SNIFF_SUBR 0x02 | 205 | #define LMP_SNIFF_SUBR 0x02 |
206 | #define LMP_PAUSE_ENC 0x04 | ||
192 | #define LMP_EDR_ESCO_2M 0x20 | 207 | #define LMP_EDR_ESCO_2M 0x20 |
193 | #define LMP_EDR_ESCO_3M 0x40 | 208 | #define LMP_EDR_ESCO_3M 0x40 |
194 | #define LMP_EDR_3S_ESCO 0x80 | 209 | #define LMP_EDR_3S_ESCO 0x80 |
195 | 210 | ||
211 | #define LMP_EXT_INQ 0x01 | ||
196 | #define LMP_SIMPLE_PAIR 0x08 | 212 | #define LMP_SIMPLE_PAIR 0x08 |
213 | #define LMP_NO_FLUSH 0x40 | ||
214 | |||
215 | #define LMP_LSTO 0x01 | ||
216 | #define LMP_INQ_TX_PWR 0x02 | ||
197 | 217 | ||
198 | /* Connection modes */ | 218 | /* Connection modes */ |
199 | #define HCI_CM_ACTIVE 0x0000 | 219 | #define HCI_CM_ACTIVE 0x0000 |
@@ -225,6 +245,8 @@ enum { | |||
225 | #define HCI_AT_GENERAL_BONDING_MITM 0x05 | 245 | #define HCI_AT_GENERAL_BONDING_MITM 0x05 |
226 | 246 | ||
227 | /* ----- HCI Commands ---- */ | 247 | /* ----- HCI Commands ---- */ |
248 | #define HCI_OP_NOP 0x0000 | ||
249 | |||
228 | #define HCI_OP_INQUIRY 0x0401 | 250 | #define HCI_OP_INQUIRY 0x0401 |
229 | struct hci_cp_inquiry { | 251 | struct hci_cp_inquiry { |
230 | __u8 lap[3]; | 252 | __u8 lap[3]; |
@@ -292,11 +314,19 @@ struct hci_cp_pin_code_reply { | |||
292 | __u8 pin_len; | 314 | __u8 pin_len; |
293 | __u8 pin_code[16]; | 315 | __u8 pin_code[16]; |
294 | } __packed; | 316 | } __packed; |
317 | struct hci_rp_pin_code_reply { | ||
318 | __u8 status; | ||
319 | bdaddr_t bdaddr; | ||
320 | } __packed; | ||
295 | 321 | ||
296 | #define HCI_OP_PIN_CODE_NEG_REPLY 0x040e | 322 | #define HCI_OP_PIN_CODE_NEG_REPLY 0x040e |
297 | struct hci_cp_pin_code_neg_reply { | 323 | struct hci_cp_pin_code_neg_reply { |
298 | bdaddr_t bdaddr; | 324 | bdaddr_t bdaddr; |
299 | } __packed; | 325 | } __packed; |
326 | struct hci_rp_pin_code_neg_reply { | ||
327 | __u8 status; | ||
328 | bdaddr_t bdaddr; | ||
329 | } __packed; | ||
300 | 330 | ||
301 | #define HCI_OP_CHANGE_CONN_PTYPE 0x040f | 331 | #define HCI_OP_CHANGE_CONN_PTYPE 0x040f |
302 | struct hci_cp_change_conn_ptype { | 332 | struct hci_cp_change_conn_ptype { |
@@ -377,6 +407,20 @@ struct hci_cp_reject_sync_conn_req { | |||
377 | __u8 reason; | 407 | __u8 reason; |
378 | } __packed; | 408 | } __packed; |
379 | 409 | ||
410 | #define HCI_OP_IO_CAPABILITY_REPLY 0x042b | ||
411 | struct hci_cp_io_capability_reply { | ||
412 | bdaddr_t bdaddr; | ||
413 | __u8 capability; | ||
414 | __u8 oob_data; | ||
415 | __u8 authentication; | ||
416 | } __packed; | ||
417 | |||
418 | #define HCI_OP_IO_CAPABILITY_NEG_REPLY 0x0434 | ||
419 | struct hci_cp_io_capability_neg_reply { | ||
420 | bdaddr_t bdaddr; | ||
421 | __u8 reason; | ||
422 | } __packed; | ||
423 | |||
380 | #define HCI_OP_SNIFF_MODE 0x0803 | 424 | #define HCI_OP_SNIFF_MODE 0x0803 |
381 | struct hci_cp_sniff_mode { | 425 | struct hci_cp_sniff_mode { |
382 | __le16 handle; | 426 | __le16 handle; |
@@ -474,6 +518,12 @@ struct hci_cp_set_event_flt { | |||
474 | #define HCI_CONN_SETUP_AUTO_OFF 0x01 | 518 | #define HCI_CONN_SETUP_AUTO_OFF 0x01 |
475 | #define HCI_CONN_SETUP_AUTO_ON 0x02 | 519 | #define HCI_CONN_SETUP_AUTO_ON 0x02 |
476 | 520 | ||
521 | #define HCI_OP_DELETE_STORED_LINK_KEY 0x0c12 | ||
522 | struct hci_cp_delete_stored_link_key { | ||
523 | bdaddr_t bdaddr; | ||
524 | __u8 delete_all; | ||
525 | } __packed; | ||
526 | |||
477 | #define HCI_OP_WRITE_LOCAL_NAME 0x0c13 | 527 | #define HCI_OP_WRITE_LOCAL_NAME 0x0c13 |
478 | struct hci_cp_write_local_name { | 528 | struct hci_cp_write_local_name { |
479 | __u8 name[248]; | 529 | __u8 name[248]; |
@@ -537,6 +587,8 @@ struct hci_cp_host_buffer_size { | |||
537 | __le16 sco_max_pkt; | 587 | __le16 sco_max_pkt; |
538 | } __packed; | 588 | } __packed; |
539 | 589 | ||
590 | #define HCI_OP_WRITE_INQUIRY_MODE 0x0c45 | ||
591 | |||
540 | #define HCI_OP_READ_SSP_MODE 0x0c55 | 592 | #define HCI_OP_READ_SSP_MODE 0x0c55 |
541 | struct hci_rp_read_ssp_mode { | 593 | struct hci_rp_read_ssp_mode { |
542 | __u8 status; | 594 | __u8 status; |
@@ -548,6 +600,8 @@ struct hci_cp_write_ssp_mode { | |||
548 | __u8 mode; | 600 | __u8 mode; |
549 | } __packed; | 601 | } __packed; |
550 | 602 | ||
603 | #define HCI_OP_READ_INQ_RSP_TX_POWER 0x0c58 | ||
604 | |||
551 | #define HCI_OP_READ_LOCAL_VERSION 0x1001 | 605 | #define HCI_OP_READ_LOCAL_VERSION 0x1001 |
552 | struct hci_rp_read_local_version { | 606 | struct hci_rp_read_local_version { |
553 | __u8 status; | 607 | __u8 status; |
@@ -593,6 +647,47 @@ struct hci_rp_read_bd_addr { | |||
593 | bdaddr_t bdaddr; | 647 | bdaddr_t bdaddr; |
594 | } __packed; | 648 | } __packed; |
595 | 649 | ||
650 | #define HCI_OP_LE_SET_EVENT_MASK 0x2001 | ||
651 | struct hci_cp_le_set_event_mask { | ||
652 | __u8 mask[8]; | ||
653 | } __packed; | ||
654 | |||
655 | #define HCI_OP_LE_READ_BUFFER_SIZE 0x2002 | ||
656 | struct hci_rp_le_read_buffer_size { | ||
657 | __u8 status; | ||
658 | __le16 le_mtu; | ||
659 | __u8 le_max_pkt; | ||
660 | } __packed; | ||
661 | |||
662 | #define HCI_OP_LE_CREATE_CONN 0x200d | ||
663 | struct hci_cp_le_create_conn { | ||
664 | __le16 scan_interval; | ||
665 | __le16 scan_window; | ||
666 | __u8 filter_policy; | ||
667 | __u8 peer_addr_type; | ||
668 | bdaddr_t peer_addr; | ||
669 | __u8 own_address_type; | ||
670 | __le16 conn_interval_min; | ||
671 | __le16 conn_interval_max; | ||
672 | __le16 conn_latency; | ||
673 | __le16 supervision_timeout; | ||
674 | __le16 min_ce_len; | ||
675 | __le16 max_ce_len; | ||
676 | } __packed; | ||
677 | |||
678 | #define HCI_OP_LE_CREATE_CONN_CANCEL 0x200e | ||
679 | |||
680 | #define HCI_OP_LE_CONN_UPDATE 0x2013 | ||
681 | struct hci_cp_le_conn_update { | ||
682 | __le16 handle; | ||
683 | __le16 conn_interval_min; | ||
684 | __le16 conn_interval_max; | ||
685 | __le16 conn_latency; | ||
686 | __le16 supervision_timeout; | ||
687 | __le16 min_ce_len; | ||
688 | __le16 max_ce_len; | ||
689 | } __packed; | ||
690 | |||
596 | /* ---- HCI Events ---- */ | 691 | /* ---- HCI Events ---- */ |
597 | #define HCI_EV_INQUIRY_COMPLETE 0x01 | 692 | #define HCI_EV_INQUIRY_COMPLETE 0x01 |
598 | 693 | ||
@@ -833,6 +928,14 @@ struct hci_ev_io_capa_request { | |||
833 | bdaddr_t bdaddr; | 928 | bdaddr_t bdaddr; |
834 | } __packed; | 929 | } __packed; |
835 | 930 | ||
931 | #define HCI_EV_IO_CAPA_REPLY 0x32 | ||
932 | struct hci_ev_io_capa_reply { | ||
933 | bdaddr_t bdaddr; | ||
934 | __u8 capability; | ||
935 | __u8 oob_data; | ||
936 | __u8 authentication; | ||
937 | } __packed; | ||
938 | |||
836 | #define HCI_EV_SIMPLE_PAIR_COMPLETE 0x36 | 939 | #define HCI_EV_SIMPLE_PAIR_COMPLETE 0x36 |
837 | struct hci_ev_simple_pair_complete { | 940 | struct hci_ev_simple_pair_complete { |
838 | __u8 status; | 941 | __u8 status; |
@@ -845,6 +948,25 @@ struct hci_ev_remote_host_features { | |||
845 | __u8 features[8]; | 948 | __u8 features[8]; |
846 | } __packed; | 949 | } __packed; |
847 | 950 | ||
951 | #define HCI_EV_LE_META 0x3e | ||
952 | struct hci_ev_le_meta { | ||
953 | __u8 subevent; | ||
954 | } __packed; | ||
955 | |||
956 | /* Low energy meta events */ | ||
957 | #define HCI_EV_LE_CONN_COMPLETE 0x01 | ||
958 | struct hci_ev_le_conn_complete { | ||
959 | __u8 status; | ||
960 | __le16 handle; | ||
961 | __u8 role; | ||
962 | __u8 bdaddr_type; | ||
963 | bdaddr_t bdaddr; | ||
964 | __le16 interval; | ||
965 | __le16 latency; | ||
966 | __le16 supervision_timeout; | ||
967 | __u8 clk_accurancy; | ||
968 | } __packed; | ||
969 | |||
848 | /* Internal events generated by Bluetooth stack */ | 970 | /* Internal events generated by Bluetooth stack */ |
849 | #define HCI_EV_STACK_INTERNAL 0xfd | 971 | #define HCI_EV_STACK_INTERNAL 0xfd |
850 | struct hci_ev_stack_internal { | 972 | struct hci_ev_stack_internal { |
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index d2cf88407690..d5d8454236bf 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -60,12 +60,28 @@ struct hci_conn_hash { | |||
60 | spinlock_t lock; | 60 | spinlock_t lock; |
61 | unsigned int acl_num; | 61 | unsigned int acl_num; |
62 | unsigned int sco_num; | 62 | unsigned int sco_num; |
63 | unsigned int le_num; | ||
63 | }; | 64 | }; |
64 | 65 | ||
65 | struct bdaddr_list { | 66 | struct bdaddr_list { |
66 | struct list_head list; | 67 | struct list_head list; |
67 | bdaddr_t bdaddr; | 68 | bdaddr_t bdaddr; |
68 | }; | 69 | }; |
70 | |||
71 | struct bt_uuid { | ||
72 | struct list_head list; | ||
73 | u8 uuid[16]; | ||
74 | u8 svc_hint; | ||
75 | }; | ||
76 | |||
77 | struct link_key { | ||
78 | struct list_head list; | ||
79 | bdaddr_t bdaddr; | ||
80 | u8 type; | ||
81 | u8 val[16]; | ||
82 | u8 pin_len; | ||
83 | }; | ||
84 | |||
69 | #define NUM_REASSEMBLY 4 | 85 | #define NUM_REASSEMBLY 4 |
70 | struct hci_dev { | 86 | struct hci_dev { |
71 | struct list_head list; | 87 | struct list_head list; |
@@ -80,13 +96,18 @@ struct hci_dev { | |||
80 | bdaddr_t bdaddr; | 96 | bdaddr_t bdaddr; |
81 | __u8 dev_name[248]; | 97 | __u8 dev_name[248]; |
82 | __u8 dev_class[3]; | 98 | __u8 dev_class[3]; |
99 | __u8 major_class; | ||
100 | __u8 minor_class; | ||
83 | __u8 features[8]; | 101 | __u8 features[8]; |
84 | __u8 commands[64]; | 102 | __u8 commands[64]; |
85 | __u8 ssp_mode; | 103 | __u8 ssp_mode; |
86 | __u8 hci_ver; | 104 | __u8 hci_ver; |
87 | __u16 hci_rev; | 105 | __u16 hci_rev; |
106 | __u8 lmp_ver; | ||
88 | __u16 manufacturer; | 107 | __u16 manufacturer; |
108 | __le16 lmp_subver; | ||
89 | __u16 voice_setting; | 109 | __u16 voice_setting; |
110 | __u8 io_capability; | ||
90 | 111 | ||
91 | __u16 pkt_type; | 112 | __u16 pkt_type; |
92 | __u16 esco_type; | 113 | __u16 esco_type; |
@@ -102,18 +123,26 @@ struct hci_dev { | |||
102 | atomic_t cmd_cnt; | 123 | atomic_t cmd_cnt; |
103 | unsigned int acl_cnt; | 124 | unsigned int acl_cnt; |
104 | unsigned int sco_cnt; | 125 | unsigned int sco_cnt; |
126 | unsigned int le_cnt; | ||
105 | 127 | ||
106 | unsigned int acl_mtu; | 128 | unsigned int acl_mtu; |
107 | unsigned int sco_mtu; | 129 | unsigned int sco_mtu; |
130 | unsigned int le_mtu; | ||
108 | unsigned int acl_pkts; | 131 | unsigned int acl_pkts; |
109 | unsigned int sco_pkts; | 132 | unsigned int sco_pkts; |
133 | unsigned int le_pkts; | ||
110 | 134 | ||
111 | unsigned long cmd_last_tx; | ||
112 | unsigned long acl_last_tx; | 135 | unsigned long acl_last_tx; |
113 | unsigned long sco_last_tx; | 136 | unsigned long sco_last_tx; |
137 | unsigned long le_last_tx; | ||
114 | 138 | ||
115 | struct workqueue_struct *workqueue; | 139 | struct workqueue_struct *workqueue; |
116 | 140 | ||
141 | struct work_struct power_on; | ||
142 | struct work_struct power_off; | ||
143 | struct timer_list off_timer; | ||
144 | |||
145 | struct timer_list cmd_timer; | ||
117 | struct tasklet_struct cmd_task; | 146 | struct tasklet_struct cmd_task; |
118 | struct tasklet_struct rx_task; | 147 | struct tasklet_struct rx_task; |
119 | struct tasklet_struct tx_task; | 148 | struct tasklet_struct tx_task; |
@@ -129,12 +158,17 @@ struct hci_dev { | |||
129 | wait_queue_head_t req_wait_q; | 158 | wait_queue_head_t req_wait_q; |
130 | __u32 req_status; | 159 | __u32 req_status; |
131 | __u32 req_result; | 160 | __u32 req_result; |
132 | __u16 req_last_cmd; | 161 | |
162 | __u16 init_last_cmd; | ||
133 | 163 | ||
134 | struct inquiry_cache inq_cache; | 164 | struct inquiry_cache inq_cache; |
135 | struct hci_conn_hash conn_hash; | 165 | struct hci_conn_hash conn_hash; |
136 | struct list_head blacklist; | 166 | struct list_head blacklist; |
137 | 167 | ||
168 | struct list_head uuids; | ||
169 | |||
170 | struct list_head link_keys; | ||
171 | |||
138 | struct hci_dev_stats stat; | 172 | struct hci_dev_stats stat; |
139 | 173 | ||
140 | struct sk_buff_head driver_init; | 174 | struct sk_buff_head driver_init; |
@@ -165,31 +199,37 @@ struct hci_dev { | |||
165 | struct hci_conn { | 199 | struct hci_conn { |
166 | struct list_head list; | 200 | struct list_head list; |
167 | 201 | ||
168 | atomic_t refcnt; | 202 | atomic_t refcnt; |
169 | spinlock_t lock; | 203 | spinlock_t lock; |
170 | 204 | ||
171 | bdaddr_t dst; | 205 | bdaddr_t dst; |
172 | __u16 handle; | 206 | __u16 handle; |
173 | __u16 state; | 207 | __u16 state; |
174 | __u8 mode; | 208 | __u8 mode; |
175 | __u8 type; | 209 | __u8 type; |
176 | __u8 out; | 210 | __u8 out; |
177 | __u8 attempt; | 211 | __u8 attempt; |
178 | __u8 dev_class[3]; | 212 | __u8 dev_class[3]; |
179 | __u8 features[8]; | 213 | __u8 features[8]; |
180 | __u8 ssp_mode; | 214 | __u8 ssp_mode; |
181 | __u16 interval; | 215 | __u16 interval; |
182 | __u16 pkt_type; | 216 | __u16 pkt_type; |
183 | __u16 link_policy; | 217 | __u16 link_policy; |
184 | __u32 link_mode; | 218 | __u32 link_mode; |
185 | __u8 auth_type; | 219 | __u8 auth_type; |
186 | __u8 sec_level; | 220 | __u8 sec_level; |
187 | __u8 pending_sec_level; | 221 | __u8 pending_sec_level; |
188 | __u8 power_save; | 222 | __u8 pin_length; |
189 | __u16 disc_timeout; | 223 | __u8 io_capability; |
190 | unsigned long pend; | 224 | __u8 power_save; |
191 | 225 | __u16 disc_timeout; | |
192 | unsigned int sent; | 226 | unsigned long pend; |
227 | |||
228 | __u8 remote_cap; | ||
229 | __u8 remote_oob; | ||
230 | __u8 remote_auth; | ||
231 | |||
232 | unsigned int sent; | ||
193 | 233 | ||
194 | struct sk_buff_head data_q; | 234 | struct sk_buff_head data_q; |
195 | 235 | ||
@@ -274,24 +314,40 @@ static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c) | |||
274 | { | 314 | { |
275 | struct hci_conn_hash *h = &hdev->conn_hash; | 315 | struct hci_conn_hash *h = &hdev->conn_hash; |
276 | list_add(&c->list, &h->list); | 316 | list_add(&c->list, &h->list); |
277 | if (c->type == ACL_LINK) | 317 | switch (c->type) { |
318 | case ACL_LINK: | ||
278 | h->acl_num++; | 319 | h->acl_num++; |
279 | else | 320 | break; |
321 | case LE_LINK: | ||
322 | h->le_num++; | ||
323 | break; | ||
324 | case SCO_LINK: | ||
325 | case ESCO_LINK: | ||
280 | h->sco_num++; | 326 | h->sco_num++; |
327 | break; | ||
328 | } | ||
281 | } | 329 | } |
282 | 330 | ||
283 | static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c) | 331 | static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c) |
284 | { | 332 | { |
285 | struct hci_conn_hash *h = &hdev->conn_hash; | 333 | struct hci_conn_hash *h = &hdev->conn_hash; |
286 | list_del(&c->list); | 334 | list_del(&c->list); |
287 | if (c->type == ACL_LINK) | 335 | switch (c->type) { |
336 | case ACL_LINK: | ||
288 | h->acl_num--; | 337 | h->acl_num--; |
289 | else | 338 | break; |
339 | case LE_LINK: | ||
340 | h->le_num--; | ||
341 | break; | ||
342 | case SCO_LINK: | ||
343 | case ESCO_LINK: | ||
290 | h->sco_num--; | 344 | h->sco_num--; |
345 | break; | ||
346 | } | ||
291 | } | 347 | } |
292 | 348 | ||
293 | static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev, | 349 | static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev, |
294 | __u16 handle) | 350 | __u16 handle) |
295 | { | 351 | { |
296 | struct hci_conn_hash *h = &hdev->conn_hash; | 352 | struct hci_conn_hash *h = &hdev->conn_hash; |
297 | struct list_head *p; | 353 | struct list_head *p; |
@@ -306,7 +362,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev, | |||
306 | } | 362 | } |
307 | 363 | ||
308 | static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev, | 364 | static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev, |
309 | __u8 type, bdaddr_t *ba) | 365 | __u8 type, bdaddr_t *ba) |
310 | { | 366 | { |
311 | struct hci_conn_hash *h = &hdev->conn_hash; | 367 | struct hci_conn_hash *h = &hdev->conn_hash; |
312 | struct list_head *p; | 368 | struct list_head *p; |
@@ -321,7 +377,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev, | |||
321 | } | 377 | } |
322 | 378 | ||
323 | static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev, | 379 | static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev, |
324 | __u8 type, __u16 state) | 380 | __u8 type, __u16 state) |
325 | { | 381 | { |
326 | struct hci_conn_hash *h = &hdev->conn_hash; | 382 | struct hci_conn_hash *h = &hdev->conn_hash; |
327 | struct list_head *p; | 383 | struct list_head *p; |
@@ -437,6 +493,16 @@ int hci_inquiry(void __user *arg); | |||
437 | struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr); | 493 | struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr); |
438 | int hci_blacklist_clear(struct hci_dev *hdev); | 494 | int hci_blacklist_clear(struct hci_dev *hdev); |
439 | 495 | ||
496 | int hci_uuids_clear(struct hci_dev *hdev); | ||
497 | |||
498 | int hci_link_keys_clear(struct hci_dev *hdev); | ||
499 | struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr); | ||
500 | int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr, | ||
501 | u8 *key, u8 type, u8 pin_len); | ||
502 | int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr); | ||
503 | |||
504 | void hci_del_off_timer(struct hci_dev *hdev); | ||
505 | |||
440 | void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); | 506 | void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); |
441 | 507 | ||
442 | int hci_recv_frame(struct sk_buff *skb); | 508 | int hci_recv_frame(struct sk_buff *skb); |
@@ -458,6 +524,8 @@ void hci_conn_del_sysfs(struct hci_conn *conn); | |||
458 | #define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR) | 524 | #define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR) |
459 | #define lmp_esco_capable(dev) ((dev)->features[3] & LMP_ESCO) | 525 | #define lmp_esco_capable(dev) ((dev)->features[3] & LMP_ESCO) |
460 | #define lmp_ssp_capable(dev) ((dev)->features[6] & LMP_SIMPLE_PAIR) | 526 | #define lmp_ssp_capable(dev) ((dev)->features[6] & LMP_SIMPLE_PAIR) |
527 | #define lmp_no_flush_capable(dev) ((dev)->features[6] & LMP_NO_FLUSH) | ||
528 | #define lmp_le_capable(dev) ((dev)->features[4] & LMP_LE) | ||
461 | 529 | ||
462 | /* ----- HCI protocols ----- */ | 530 | /* ----- HCI protocols ----- */ |
463 | struct hci_proto { | 531 | struct hci_proto { |
@@ -660,12 +728,24 @@ void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode); | |||
660 | void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data); | 728 | void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data); |
661 | 729 | ||
662 | /* ----- HCI Sockets ----- */ | 730 | /* ----- HCI Sockets ----- */ |
663 | void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb); | 731 | void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb, |
732 | struct sock *skip_sk); | ||
664 | 733 | ||
665 | /* Management interface */ | 734 | /* Management interface */ |
666 | int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); | 735 | int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len); |
667 | int mgmt_index_added(u16 index); | 736 | int mgmt_index_added(u16 index); |
668 | int mgmt_index_removed(u16 index); | 737 | int mgmt_index_removed(u16 index); |
738 | int mgmt_powered(u16 index, u8 powered); | ||
739 | int mgmt_discoverable(u16 index, u8 discoverable); | ||
740 | int mgmt_connectable(u16 index, u8 connectable); | ||
741 | int mgmt_new_key(u16 index, struct link_key *key, u8 old_key_type); | ||
742 | int mgmt_connected(u16 index, bdaddr_t *bdaddr); | ||
743 | int mgmt_disconnected(u16 index, bdaddr_t *bdaddr); | ||
744 | int mgmt_disconnect_failed(u16 index); | ||
745 | int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status); | ||
746 | int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr); | ||
747 | int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status); | ||
748 | int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status); | ||
669 | 749 | ||
670 | /* HCI info for socket */ | 750 | /* HCI info for socket */ |
671 | #define hci_pi(sk) ((struct hci_pinfo *) sk) | 751 | #define hci_pi(sk) ((struct hci_pinfo *) sk) |
@@ -697,4 +777,6 @@ struct hci_sec_filter { | |||
697 | 777 | ||
698 | void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result); | 778 | void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result); |
699 | 779 | ||
780 | void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, | ||
781 | u16 latency, u16 to_multiplier); | ||
700 | #endif /* __HCI_CORE_H */ | 782 | #endif /* __HCI_CORE_H */ |
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 7ad25ca60ec0..4f4bff1eaed6 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h | |||
@@ -38,6 +38,7 @@ | |||
38 | #define L2CAP_DEFAULT_MAX_PDU_SIZE 1009 /* Sized for 3-DH5 packet */ | 38 | #define L2CAP_DEFAULT_MAX_PDU_SIZE 1009 /* Sized for 3-DH5 packet */ |
39 | #define L2CAP_DEFAULT_ACK_TO 200 | 39 | #define L2CAP_DEFAULT_ACK_TO 200 |
40 | #define L2CAP_LOCAL_BUSY_TRIES 12 | 40 | #define L2CAP_LOCAL_BUSY_TRIES 12 |
41 | #define L2CAP_LE_DEFAULT_MTU 23 | ||
41 | 42 | ||
42 | #define L2CAP_CONN_TIMEOUT (40000) /* 40 seconds */ | 43 | #define L2CAP_CONN_TIMEOUT (40000) /* 40 seconds */ |
43 | #define L2CAP_INFO_TIMEOUT (4000) /* 4 seconds */ | 44 | #define L2CAP_INFO_TIMEOUT (4000) /* 4 seconds */ |
@@ -88,6 +89,8 @@ struct l2cap_conninfo { | |||
88 | #define L2CAP_ECHO_RSP 0x09 | 89 | #define L2CAP_ECHO_RSP 0x09 |
89 | #define L2CAP_INFO_REQ 0x0a | 90 | #define L2CAP_INFO_REQ 0x0a |
90 | #define L2CAP_INFO_RSP 0x0b | 91 | #define L2CAP_INFO_RSP 0x0b |
92 | #define L2CAP_CONN_PARAM_UPDATE_REQ 0x12 | ||
93 | #define L2CAP_CONN_PARAM_UPDATE_RSP 0x13 | ||
91 | 94 | ||
92 | /* L2CAP feature mask */ | 95 | /* L2CAP feature mask */ |
93 | #define L2CAP_FEAT_FLOWCTL 0x00000001 | 96 | #define L2CAP_FEAT_FLOWCTL 0x00000001 |
@@ -160,6 +163,9 @@ struct l2cap_conn_rsp { | |||
160 | /* channel indentifier */ | 163 | /* channel indentifier */ |
161 | #define L2CAP_CID_SIGNALING 0x0001 | 164 | #define L2CAP_CID_SIGNALING 0x0001 |
162 | #define L2CAP_CID_CONN_LESS 0x0002 | 165 | #define L2CAP_CID_CONN_LESS 0x0002 |
166 | #define L2CAP_CID_LE_DATA 0x0004 | ||
167 | #define L2CAP_CID_LE_SIGNALING 0x0005 | ||
168 | #define L2CAP_CID_SMP 0x0006 | ||
163 | #define L2CAP_CID_DYN_START 0x0040 | 169 | #define L2CAP_CID_DYN_START 0x0040 |
164 | #define L2CAP_CID_DYN_END 0xffff | 170 | #define L2CAP_CID_DYN_END 0xffff |
165 | 171 | ||
@@ -255,6 +261,21 @@ struct l2cap_info_rsp { | |||
255 | #define L2CAP_IR_SUCCESS 0x0000 | 261 | #define L2CAP_IR_SUCCESS 0x0000 |
256 | #define L2CAP_IR_NOTSUPP 0x0001 | 262 | #define L2CAP_IR_NOTSUPP 0x0001 |
257 | 263 | ||
264 | struct l2cap_conn_param_update_req { | ||
265 | __le16 min; | ||
266 | __le16 max; | ||
267 | __le16 latency; | ||
268 | __le16 to_multiplier; | ||
269 | } __packed; | ||
270 | |||
271 | struct l2cap_conn_param_update_rsp { | ||
272 | __le16 result; | ||
273 | } __packed; | ||
274 | |||
275 | /* Connection Parameters result */ | ||
276 | #define L2CAP_CONN_PARAM_ACCEPTED 0x0000 | ||
277 | #define L2CAP_CONN_PARAM_REJECTED 0x0001 | ||
278 | |||
258 | /* ----- L2CAP connections ----- */ | 279 | /* ----- L2CAP connections ----- */ |
259 | struct l2cap_chan_list { | 280 | struct l2cap_chan_list { |
260 | struct sock *head; | 281 | struct sock *head; |
@@ -327,6 +348,7 @@ struct l2cap_pinfo { | |||
327 | __u8 sec_level; | 348 | __u8 sec_level; |
328 | __u8 role_switch; | 349 | __u8 role_switch; |
329 | __u8 force_reliable; | 350 | __u8 force_reliable; |
351 | __u8 flushable; | ||
330 | 352 | ||
331 | __u8 conf_req[64]; | 353 | __u8 conf_req[64]; |
332 | __u8 conf_len; | 354 | __u8 conf_len; |
@@ -423,6 +445,35 @@ static inline int l2cap_tx_window_full(struct sock *sk) | |||
423 | #define __is_sframe(ctrl) ((ctrl) & L2CAP_CTRL_FRAME_TYPE) | 445 | #define __is_sframe(ctrl) ((ctrl) & L2CAP_CTRL_FRAME_TYPE) |
424 | #define __is_sar_start(ctrl) (((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START) | 446 | #define __is_sar_start(ctrl) (((ctrl) & L2CAP_CTRL_SAR) == L2CAP_SDU_START) |
425 | 447 | ||
426 | void l2cap_load(void); | 448 | extern int disable_ertm; |
449 | extern const struct proto_ops l2cap_sock_ops; | ||
450 | extern struct bt_sock_list l2cap_sk_list; | ||
451 | |||
452 | int l2cap_init_sockets(void); | ||
453 | void l2cap_cleanup_sockets(void); | ||
454 | |||
455 | u8 l2cap_get_ident(struct l2cap_conn *conn); | ||
456 | void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data); | ||
457 | int l2cap_build_conf_req(struct sock *sk, void *data); | ||
458 | int __l2cap_wait_ack(struct sock *sk); | ||
459 | |||
460 | struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len); | ||
461 | struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len); | ||
462 | struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, size_t len, u16 control, u16 sdulen); | ||
463 | int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len); | ||
464 | void l2cap_do_send(struct sock *sk, struct sk_buff *skb); | ||
465 | void l2cap_streaming_send(struct sock *sk); | ||
466 | int l2cap_ertm_send(struct sock *sk); | ||
467 | |||
468 | void l2cap_sock_set_timer(struct sock *sk, long timeout); | ||
469 | void l2cap_sock_clear_timer(struct sock *sk); | ||
470 | void __l2cap_sock_close(struct sock *sk, int reason); | ||
471 | void l2cap_sock_kill(struct sock *sk); | ||
472 | void l2cap_sock_init(struct sock *sk, struct sock *parent); | ||
473 | struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, | ||
474 | int proto, gfp_t prio); | ||
475 | void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err); | ||
476 | void l2cap_chan_del(struct sock *sk, int err); | ||
477 | int l2cap_do_connect(struct sock *sk); | ||
427 | 478 | ||
428 | #endif /* __L2CAP_H */ | 479 | #endif /* __L2CAP_H */ |
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index ca29c1367ffd..44ac55c85079 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h | |||
@@ -47,6 +47,7 @@ struct mgmt_rp_read_info { | |||
47 | __le16 index; | 47 | __le16 index; |
48 | __u8 type; | 48 | __u8 type; |
49 | __u8 powered; | 49 | __u8 powered; |
50 | __u8 connectable; | ||
50 | __u8 discoverable; | 51 | __u8 discoverable; |
51 | __u8 pairable; | 52 | __u8 pairable; |
52 | __u8 sec_mode; | 53 | __u8 sec_mode; |
@@ -58,6 +59,107 @@ struct mgmt_rp_read_info { | |||
58 | __u16 hci_rev; | 59 | __u16 hci_rev; |
59 | } __packed; | 60 | } __packed; |
60 | 61 | ||
62 | struct mgmt_mode { | ||
63 | __le16 index; | ||
64 | __u8 val; | ||
65 | } __packed; | ||
66 | |||
67 | #define MGMT_OP_SET_POWERED 0x0005 | ||
68 | |||
69 | #define MGMT_OP_SET_DISCOVERABLE 0x0006 | ||
70 | |||
71 | #define MGMT_OP_SET_CONNECTABLE 0x0007 | ||
72 | |||
73 | #define MGMT_OP_SET_PAIRABLE 0x0008 | ||
74 | |||
75 | #define MGMT_OP_ADD_UUID 0x0009 | ||
76 | struct mgmt_cp_add_uuid { | ||
77 | __le16 index; | ||
78 | __u8 uuid[16]; | ||
79 | __u8 svc_hint; | ||
80 | } __packed; | ||
81 | |||
82 | #define MGMT_OP_REMOVE_UUID 0x000A | ||
83 | struct mgmt_cp_remove_uuid { | ||
84 | __le16 index; | ||
85 | __u8 uuid[16]; | ||
86 | } __packed; | ||
87 | |||
88 | #define MGMT_OP_SET_DEV_CLASS 0x000B | ||
89 | struct mgmt_cp_set_dev_class { | ||
90 | __le16 index; | ||
91 | __u8 major; | ||
92 | __u8 minor; | ||
93 | } __packed; | ||
94 | |||
95 | #define MGMT_OP_SET_SERVICE_CACHE 0x000C | ||
96 | struct mgmt_cp_set_service_cache { | ||
97 | __le16 index; | ||
98 | __u8 enable; | ||
99 | } __packed; | ||
100 | |||
101 | struct mgmt_key_info { | ||
102 | bdaddr_t bdaddr; | ||
103 | u8 type; | ||
104 | u8 val[16]; | ||
105 | u8 pin_len; | ||
106 | } __packed; | ||
107 | |||
108 | #define MGMT_OP_LOAD_KEYS 0x000D | ||
109 | struct mgmt_cp_load_keys { | ||
110 | __le16 index; | ||
111 | __u8 debug_keys; | ||
112 | __le16 key_count; | ||
113 | struct mgmt_key_info keys[0]; | ||
114 | } __packed; | ||
115 | |||
116 | #define MGMT_OP_REMOVE_KEY 0x000E | ||
117 | struct mgmt_cp_remove_key { | ||
118 | __le16 index; | ||
119 | bdaddr_t bdaddr; | ||
120 | __u8 disconnect; | ||
121 | } __packed; | ||
122 | |||
123 | #define MGMT_OP_DISCONNECT 0x000F | ||
124 | struct mgmt_cp_disconnect { | ||
125 | __le16 index; | ||
126 | bdaddr_t bdaddr; | ||
127 | } __packed; | ||
128 | struct mgmt_rp_disconnect { | ||
129 | __le16 index; | ||
130 | bdaddr_t bdaddr; | ||
131 | } __packed; | ||
132 | |||
133 | #define MGMT_OP_GET_CONNECTIONS 0x0010 | ||
134 | struct mgmt_cp_get_connections { | ||
135 | __le16 index; | ||
136 | } __packed; | ||
137 | struct mgmt_rp_get_connections { | ||
138 | __le16 index; | ||
139 | __le16 conn_count; | ||
140 | bdaddr_t conn[0]; | ||
141 | } __packed; | ||
142 | |||
143 | #define MGMT_OP_PIN_CODE_REPLY 0x0011 | ||
144 | struct mgmt_cp_pin_code_reply { | ||
145 | __le16 index; | ||
146 | bdaddr_t bdaddr; | ||
147 | __u8 pin_len; | ||
148 | __u8 pin_code[16]; | ||
149 | } __packed; | ||
150 | |||
151 | #define MGMT_OP_PIN_CODE_NEG_REPLY 0x0012 | ||
152 | struct mgmt_cp_pin_code_neg_reply { | ||
153 | __le16 index; | ||
154 | bdaddr_t bdaddr; | ||
155 | } __packed; | ||
156 | |||
157 | #define MGMT_OP_SET_IO_CAPABILITY 0x0013 | ||
158 | struct mgmt_cp_set_io_capability { | ||
159 | __le16 index; | ||
160 | __u8 io_capability; | ||
161 | } __packed; | ||
162 | |||
61 | #define MGMT_EV_CMD_COMPLETE 0x0001 | 163 | #define MGMT_EV_CMD_COMPLETE 0x0001 |
62 | struct mgmt_ev_cmd_complete { | 164 | struct mgmt_ev_cmd_complete { |
63 | __le16 opcode; | 165 | __le16 opcode; |
@@ -85,3 +187,43 @@ struct mgmt_ev_index_added { | |||
85 | struct mgmt_ev_index_removed { | 187 | struct mgmt_ev_index_removed { |
86 | __le16 index; | 188 | __le16 index; |
87 | } __packed; | 189 | } __packed; |
190 | |||
191 | #define MGMT_EV_POWERED 0x0006 | ||
192 | |||
193 | #define MGMT_EV_DISCOVERABLE 0x0007 | ||
194 | |||
195 | #define MGMT_EV_CONNECTABLE 0x0008 | ||
196 | |||
197 | #define MGMT_EV_PAIRABLE 0x0009 | ||
198 | |||
199 | #define MGMT_EV_NEW_KEY 0x000A | ||
200 | struct mgmt_ev_new_key { | ||
201 | __le16 index; | ||
202 | struct mgmt_key_info key; | ||
203 | __u8 old_key_type; | ||
204 | } __packed; | ||
205 | |||
206 | #define MGMT_EV_CONNECTED 0x000B | ||
207 | struct mgmt_ev_connected { | ||
208 | __le16 index; | ||
209 | bdaddr_t bdaddr; | ||
210 | } __packed; | ||
211 | |||
212 | #define MGMT_EV_DISCONNECTED 0x000C | ||
213 | struct mgmt_ev_disconnected { | ||
214 | __le16 index; | ||
215 | bdaddr_t bdaddr; | ||
216 | } __packed; | ||
217 | |||
218 | #define MGMT_EV_CONNECT_FAILED 0x000D | ||
219 | struct mgmt_ev_connect_failed { | ||
220 | __le16 index; | ||
221 | bdaddr_t bdaddr; | ||
222 | __u8 status; | ||
223 | } __packed; | ||
224 | |||
225 | #define MGMT_EV_PIN_CODE_REQUEST 0x000E | ||
226 | struct mgmt_ev_pin_code_request { | ||
227 | __le16 index; | ||
228 | bdaddr_t bdaddr; | ||
229 | } __packed; | ||
diff --git a/include/net/bluetooth/smp.h b/include/net/bluetooth/smp.h new file mode 100644 index 000000000000..8f2edbf979dc --- /dev/null +++ b/include/net/bluetooth/smp.h | |||
@@ -0,0 +1,76 @@ | |||
1 | #ifndef __SMP_H | ||
2 | #define __SMP_H | ||
3 | |||
4 | struct smp_command_hdr { | ||
5 | __u8 code; | ||
6 | } __packed; | ||
7 | |||
8 | #define SMP_CMD_PAIRING_REQ 0x01 | ||
9 | #define SMP_CMD_PAIRING_RSP 0x02 | ||
10 | struct smp_cmd_pairing { | ||
11 | __u8 io_capability; | ||
12 | __u8 oob_flag; | ||
13 | __u8 auth_req; | ||
14 | __u8 max_key_size; | ||
15 | __u8 init_key_dist; | ||
16 | __u8 resp_key_dist; | ||
17 | } __packed; | ||
18 | |||
19 | #define SMP_CMD_PAIRING_CONFIRM 0x03 | ||
20 | struct smp_cmd_pairing_confirm { | ||
21 | __u8 confirm_val[16]; | ||
22 | } __packed; | ||
23 | |||
24 | #define SMP_CMD_PAIRING_RANDOM 0x04 | ||
25 | struct smp_cmd_pairing_random { | ||
26 | __u8 rand_val[16]; | ||
27 | } __packed; | ||
28 | |||
29 | #define SMP_CMD_PAIRING_FAIL 0x05 | ||
30 | struct smp_cmd_pairing_fail { | ||
31 | __u8 reason; | ||
32 | } __packed; | ||
33 | |||
34 | #define SMP_CMD_ENCRYPT_INFO 0x06 | ||
35 | struct smp_cmd_encrypt_info { | ||
36 | __u8 ltk[16]; | ||
37 | } __packed; | ||
38 | |||
39 | #define SMP_CMD_MASTER_IDENT 0x07 | ||
40 | struct smp_cmd_master_ident { | ||
41 | __u16 ediv; | ||
42 | __u8 rand[8]; | ||
43 | } __packed; | ||
44 | |||
45 | #define SMP_CMD_IDENT_INFO 0x08 | ||
46 | struct smp_cmd_ident_info { | ||
47 | __u8 irk[16]; | ||
48 | } __packed; | ||
49 | |||
50 | #define SMP_CMD_IDENT_ADDR_INFO 0x09 | ||
51 | struct smp_cmd_ident_addr_info { | ||
52 | __u8 addr_type; | ||
53 | bdaddr_t bdaddr; | ||
54 | } __packed; | ||
55 | |||
56 | #define SMP_CMD_SIGN_INFO 0x0a | ||
57 | struct smp_cmd_sign_info { | ||
58 | __u8 csrk[16]; | ||
59 | } __packed; | ||
60 | |||
61 | #define SMP_CMD_SECURITY_REQ 0x0b | ||
62 | struct smp_cmd_security_req { | ||
63 | __u8 auth_req; | ||
64 | } __packed; | ||
65 | |||
66 | #define SMP_PASSKEY_ENTRY_FAILED 0x01 | ||
67 | #define SMP_OOB_NOT_AVAIL 0x02 | ||
68 | #define SMP_AUTH_REQUIREMENTS 0x03 | ||
69 | #define SMP_CONFIRM_FAILED 0x04 | ||
70 | #define SMP_PAIRING_NOTSUPP 0x05 | ||
71 | #define SMP_ENC_KEY_SIZE 0x06 | ||
72 | #define SMP_CMD_NOTSUPP 0x07 | ||
73 | #define SMP_UNSPECIFIED 0x08 | ||
74 | #define SMP_REPEATED_ATTEMPTS 0x09 | ||
75 | |||
76 | #endif /* __SMP_H */ | ||
diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig index ed371684c133..c6f9c2fb4891 100644 --- a/net/bluetooth/Kconfig +++ b/net/bluetooth/Kconfig | |||
@@ -27,12 +27,12 @@ menuconfig BT | |||
27 | compile it as module (bluetooth). | 27 | compile it as module (bluetooth). |
28 | 28 | ||
29 | To use Linux Bluetooth subsystem, you will need several user-space | 29 | To use Linux Bluetooth subsystem, you will need several user-space |
30 | utilities like hciconfig and hcid. These utilities and updates to | 30 | utilities like hciconfig and bluetoothd. These utilities and updates |
31 | Bluetooth kernel modules are provided in the BlueZ packages. | 31 | to Bluetooth kernel modules are provided in the BlueZ packages. For |
32 | For more information, see <http://www.bluez.org/>. | 32 | more information, see <http://www.bluez.org/>. |
33 | 33 | ||
34 | config BT_L2CAP | 34 | config BT_L2CAP |
35 | tristate "L2CAP protocol support" | 35 | bool "L2CAP protocol support" |
36 | depends on BT | 36 | depends on BT |
37 | select CRC16 | 37 | select CRC16 |
38 | help | 38 | help |
@@ -40,19 +40,13 @@ config BT_L2CAP | |||
40 | connection oriented and connection-less data transport. L2CAP | 40 | connection oriented and connection-less data transport. L2CAP |
41 | support is required for most Bluetooth applications. | 41 | support is required for most Bluetooth applications. |
42 | 42 | ||
43 | Say Y here to compile L2CAP support into the kernel or say M to | ||
44 | compile it as module (l2cap). | ||
45 | |||
46 | config BT_SCO | 43 | config BT_SCO |
47 | tristate "SCO links support" | 44 | bool "SCO links support" |
48 | depends on BT | 45 | depends on BT |
49 | help | 46 | help |
50 | SCO link provides voice transport over Bluetooth. SCO support is | 47 | SCO link provides voice transport over Bluetooth. SCO support is |
51 | required for voice applications like Headset and Audio. | 48 | required for voice applications like Headset and Audio. |
52 | 49 | ||
53 | Say Y here to compile SCO support into the kernel or say M to | ||
54 | compile it as module (sco). | ||
55 | |||
56 | source "net/bluetooth/rfcomm/Kconfig" | 50 | source "net/bluetooth/rfcomm/Kconfig" |
57 | 51 | ||
58 | source "net/bluetooth/bnep/Kconfig" | 52 | source "net/bluetooth/bnep/Kconfig" |
diff --git a/net/bluetooth/Makefile b/net/bluetooth/Makefile index 250f954f0213..f04fe9a9d634 100644 --- a/net/bluetooth/Makefile +++ b/net/bluetooth/Makefile | |||
@@ -3,11 +3,11 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_BT) += bluetooth.o | 5 | obj-$(CONFIG_BT) += bluetooth.o |
6 | obj-$(CONFIG_BT_L2CAP) += l2cap.o | ||
7 | obj-$(CONFIG_BT_SCO) += sco.o | ||
8 | obj-$(CONFIG_BT_RFCOMM) += rfcomm/ | 6 | obj-$(CONFIG_BT_RFCOMM) += rfcomm/ |
9 | obj-$(CONFIG_BT_BNEP) += bnep/ | 7 | obj-$(CONFIG_BT_BNEP) += bnep/ |
10 | obj-$(CONFIG_BT_CMTP) += cmtp/ | 8 | obj-$(CONFIG_BT_CMTP) += cmtp/ |
11 | obj-$(CONFIG_BT_HIDP) += hidp/ | 9 | obj-$(CONFIG_BT_HIDP) += hidp/ |
12 | 10 | ||
13 | bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o hci_sock.o hci_sysfs.o lib.o | 11 | bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o hci_sock.o hci_sysfs.o lib.o |
12 | bluetooth-$(CONFIG_BT_L2CAP) += l2cap_core.o l2cap_sock.o | ||
13 | bluetooth-$(CONFIG_BT_SCO) += sco.o | ||
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c index c4cf3f595004..88af9eb9aa48 100644 --- a/net/bluetooth/af_bluetooth.c +++ b/net/bluetooth/af_bluetooth.c | |||
@@ -40,7 +40,7 @@ | |||
40 | 40 | ||
41 | #include <net/bluetooth/bluetooth.h> | 41 | #include <net/bluetooth/bluetooth.h> |
42 | 42 | ||
43 | #define VERSION "2.15" | 43 | #define VERSION "2.16" |
44 | 44 | ||
45 | /* Bluetooth sockets */ | 45 | /* Bluetooth sockets */ |
46 | #define BT_MAX_PROTO 8 | 46 | #define BT_MAX_PROTO 8 |
@@ -199,14 +199,15 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock) | |||
199 | 199 | ||
200 | BT_DBG("parent %p", parent); | 200 | BT_DBG("parent %p", parent); |
201 | 201 | ||
202 | local_bh_disable(); | ||
202 | list_for_each_safe(p, n, &bt_sk(parent)->accept_q) { | 203 | list_for_each_safe(p, n, &bt_sk(parent)->accept_q) { |
203 | sk = (struct sock *) list_entry(p, struct bt_sock, accept_q); | 204 | sk = (struct sock *) list_entry(p, struct bt_sock, accept_q); |
204 | 205 | ||
205 | lock_sock(sk); | 206 | bh_lock_sock(sk); |
206 | 207 | ||
207 | /* FIXME: Is this check still needed */ | 208 | /* FIXME: Is this check still needed */ |
208 | if (sk->sk_state == BT_CLOSED) { | 209 | if (sk->sk_state == BT_CLOSED) { |
209 | release_sock(sk); | 210 | bh_unlock_sock(sk); |
210 | bt_accept_unlink(sk); | 211 | bt_accept_unlink(sk); |
211 | continue; | 212 | continue; |
212 | } | 213 | } |
@@ -216,12 +217,16 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock) | |||
216 | bt_accept_unlink(sk); | 217 | bt_accept_unlink(sk); |
217 | if (newsock) | 218 | if (newsock) |
218 | sock_graft(sk, newsock); | 219 | sock_graft(sk, newsock); |
219 | release_sock(sk); | 220 | |
221 | bh_unlock_sock(sk); | ||
222 | local_bh_enable(); | ||
220 | return sk; | 223 | return sk; |
221 | } | 224 | } |
222 | 225 | ||
223 | release_sock(sk); | 226 | bh_unlock_sock(sk); |
224 | } | 227 | } |
228 | local_bh_enable(); | ||
229 | |||
225 | return NULL; | 230 | return NULL; |
226 | } | 231 | } |
227 | EXPORT_SYMBOL(bt_accept_dequeue); | 232 | EXPORT_SYMBOL(bt_accept_dequeue); |
@@ -240,7 +245,8 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
240 | if (flags & (MSG_OOB)) | 245 | if (flags & (MSG_OOB)) |
241 | return -EOPNOTSUPP; | 246 | return -EOPNOTSUPP; |
242 | 247 | ||
243 | if (!(skb = skb_recv_datagram(sk, flags, noblock, &err))) { | 248 | skb = skb_recv_datagram(sk, flags, noblock, &err); |
249 | if (!skb) { | ||
244 | if (sk->sk_shutdown & RCV_SHUTDOWN) | 250 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
245 | return 0; | 251 | return 0; |
246 | return err; | 252 | return err; |
@@ -323,7 +329,8 @@ int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
323 | if (copied >= target) | 329 | if (copied >= target) |
324 | break; | 330 | break; |
325 | 331 | ||
326 | if ((err = sock_error(sk)) != 0) | 332 | err = sock_error(sk); |
333 | if (err) | ||
327 | break; | 334 | break; |
328 | if (sk->sk_shutdown & RCV_SHUTDOWN) | 335 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
329 | break; | 336 | break; |
@@ -390,7 +397,7 @@ static inline unsigned int bt_accept_poll(struct sock *parent) | |||
390 | return 0; | 397 | return 0; |
391 | } | 398 | } |
392 | 399 | ||
393 | unsigned int bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait) | 400 | unsigned int bt_sock_poll(struct file *file, struct socket *sock, poll_table *wait) |
394 | { | 401 | { |
395 | struct sock *sk = sock->sk; | 402 | struct sock *sk = sock->sk; |
396 | unsigned int mask = 0; | 403 | unsigned int mask = 0; |
@@ -538,13 +545,41 @@ static int __init bt_init(void) | |||
538 | 545 | ||
539 | BT_INFO("HCI device and connection manager initialized"); | 546 | BT_INFO("HCI device and connection manager initialized"); |
540 | 547 | ||
541 | hci_sock_init(); | 548 | err = hci_sock_init(); |
549 | if (err < 0) | ||
550 | goto error; | ||
551 | |||
552 | err = l2cap_init(); | ||
553 | if (err < 0) { | ||
554 | hci_sock_cleanup(); | ||
555 | goto sock_err; | ||
556 | } | ||
557 | |||
558 | err = sco_init(); | ||
559 | if (err < 0) { | ||
560 | l2cap_exit(); | ||
561 | goto sock_err; | ||
562 | } | ||
542 | 563 | ||
543 | return 0; | 564 | return 0; |
565 | |||
566 | sock_err: | ||
567 | hci_sock_cleanup(); | ||
568 | |||
569 | error: | ||
570 | sock_unregister(PF_BLUETOOTH); | ||
571 | bt_sysfs_cleanup(); | ||
572 | |||
573 | return err; | ||
544 | } | 574 | } |
545 | 575 | ||
546 | static void __exit bt_exit(void) | 576 | static void __exit bt_exit(void) |
547 | { | 577 | { |
578 | |||
579 | sco_exit(); | ||
580 | |||
581 | l2cap_exit(); | ||
582 | |||
548 | hci_sock_cleanup(); | 583 | hci_sock_cleanup(); |
549 | 584 | ||
550 | sock_unregister(PF_BLUETOOTH); | 585 | sock_unregister(PF_BLUETOOTH); |
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c index 5868597534e5..03d4d1245d58 100644 --- a/net/bluetooth/bnep/core.c +++ b/net/bluetooth/bnep/core.c | |||
@@ -708,8 +708,6 @@ static int __init bnep_init(void) | |||
708 | { | 708 | { |
709 | char flt[50] = ""; | 709 | char flt[50] = ""; |
710 | 710 | ||
711 | l2cap_load(); | ||
712 | |||
713 | #ifdef CONFIG_BT_BNEP_PROTO_FILTER | 711 | #ifdef CONFIG_BT_BNEP_PROTO_FILTER |
714 | strcat(flt, "protocol "); | 712 | strcat(flt, "protocol "); |
715 | #endif | 713 | #endif |
diff --git a/net/bluetooth/bnep/sock.c b/net/bluetooth/bnep/sock.c index 2862f53b66b1..d935da71ab3b 100644 --- a/net/bluetooth/bnep/sock.c +++ b/net/bluetooth/bnep/sock.c | |||
@@ -88,6 +88,7 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long | |||
88 | sockfd_put(nsock); | 88 | sockfd_put(nsock); |
89 | return -EBADFD; | 89 | return -EBADFD; |
90 | } | 90 | } |
91 | ca.device[sizeof(ca.device)-1] = 0; | ||
91 | 92 | ||
92 | err = bnep_add_connection(&ca, nsock); | 93 | err = bnep_add_connection(&ca, nsock); |
93 | if (!err) { | 94 | if (!err) { |
diff --git a/net/bluetooth/cmtp/capi.c b/net/bluetooth/cmtp/capi.c index 3487cfe74aec..67cff810c77d 100644 --- a/net/bluetooth/cmtp/capi.c +++ b/net/bluetooth/cmtp/capi.c | |||
@@ -155,7 +155,8 @@ static void cmtp_send_interopmsg(struct cmtp_session *session, | |||
155 | 155 | ||
156 | BT_DBG("session %p subcmd 0x%02x appl %d msgnum %d", session, subcmd, appl, msgnum); | 156 | BT_DBG("session %p subcmd 0x%02x appl %d msgnum %d", session, subcmd, appl, msgnum); |
157 | 157 | ||
158 | if (!(skb = alloc_skb(CAPI_MSG_BASELEN + 6 + len, GFP_ATOMIC))) { | 158 | skb = alloc_skb(CAPI_MSG_BASELEN + 6 + len, GFP_ATOMIC); |
159 | if (!skb) { | ||
159 | BT_ERR("Can't allocate memory for interoperability packet"); | 160 | BT_ERR("Can't allocate memory for interoperability packet"); |
160 | return; | 161 | return; |
161 | } | 162 | } |
diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index 8e5f292529ac..964ea9126f9f 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c | |||
@@ -115,7 +115,8 @@ static inline void cmtp_add_msgpart(struct cmtp_session *session, int id, const | |||
115 | 115 | ||
116 | size = (skb) ? skb->len + count : count; | 116 | size = (skb) ? skb->len + count : count; |
117 | 117 | ||
118 | if (!(nskb = alloc_skb(size, GFP_ATOMIC))) { | 118 | nskb = alloc_skb(size, GFP_ATOMIC); |
119 | if (!nskb) { | ||
119 | BT_ERR("Can't allocate memory for CAPI message"); | 120 | BT_ERR("Can't allocate memory for CAPI message"); |
120 | return; | 121 | return; |
121 | } | 122 | } |
@@ -216,7 +217,8 @@ static void cmtp_process_transmit(struct cmtp_session *session) | |||
216 | 217 | ||
217 | BT_DBG("session %p", session); | 218 | BT_DBG("session %p", session); |
218 | 219 | ||
219 | if (!(nskb = alloc_skb(session->mtu, GFP_ATOMIC))) { | 220 | nskb = alloc_skb(session->mtu, GFP_ATOMIC); |
221 | if (!nskb) { | ||
220 | BT_ERR("Can't allocate memory for new frame"); | 222 | BT_ERR("Can't allocate memory for new frame"); |
221 | return; | 223 | return; |
222 | } | 224 | } |
@@ -224,7 +226,8 @@ static void cmtp_process_transmit(struct cmtp_session *session) | |||
224 | while ((skb = skb_dequeue(&session->transmit))) { | 226 | while ((skb = skb_dequeue(&session->transmit))) { |
225 | struct cmtp_scb *scb = (void *) skb->cb; | 227 | struct cmtp_scb *scb = (void *) skb->cb; |
226 | 228 | ||
227 | if ((tail = (session->mtu - nskb->len)) < 5) { | 229 | tail = session->mtu - nskb->len; |
230 | if (tail < 5) { | ||
228 | cmtp_send_frame(session, nskb->data, nskb->len); | 231 | cmtp_send_frame(session, nskb->data, nskb->len); |
229 | skb_trim(nskb, 0); | 232 | skb_trim(nskb, 0); |
230 | tail = session->mtu; | 233 | tail = session->mtu; |
@@ -466,8 +469,6 @@ int cmtp_get_conninfo(struct cmtp_conninfo *ci) | |||
466 | 469 | ||
467 | static int __init cmtp_init(void) | 470 | static int __init cmtp_init(void) |
468 | { | 471 | { |
469 | l2cap_load(); | ||
470 | |||
471 | BT_INFO("CMTP (CAPI Emulation) ver %s", VERSION); | 472 | BT_INFO("CMTP (CAPI Emulation) ver %s", VERSION); |
472 | 473 | ||
473 | cmtp_init_sockets(); | 474 | cmtp_init_sockets(); |
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 99cd8d9d891b..a050a6984901 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -45,6 +45,33 @@ | |||
45 | #include <net/bluetooth/bluetooth.h> | 45 | #include <net/bluetooth/bluetooth.h> |
46 | #include <net/bluetooth/hci_core.h> | 46 | #include <net/bluetooth/hci_core.h> |
47 | 47 | ||
48 | static void hci_le_connect(struct hci_conn *conn) | ||
49 | { | ||
50 | struct hci_dev *hdev = conn->hdev; | ||
51 | struct hci_cp_le_create_conn cp; | ||
52 | |||
53 | conn->state = BT_CONNECT; | ||
54 | conn->out = 1; | ||
55 | conn->link_mode |= HCI_LM_MASTER; | ||
56 | |||
57 | memset(&cp, 0, sizeof(cp)); | ||
58 | cp.scan_interval = cpu_to_le16(0x0004); | ||
59 | cp.scan_window = cpu_to_le16(0x0004); | ||
60 | bacpy(&cp.peer_addr, &conn->dst); | ||
61 | cp.conn_interval_min = cpu_to_le16(0x0008); | ||
62 | cp.conn_interval_max = cpu_to_le16(0x0100); | ||
63 | cp.supervision_timeout = cpu_to_le16(0x0064); | ||
64 | cp.min_ce_len = cpu_to_le16(0x0001); | ||
65 | cp.max_ce_len = cpu_to_le16(0x0001); | ||
66 | |||
67 | hci_send_cmd(hdev, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp); | ||
68 | } | ||
69 | |||
70 | static void hci_le_connect_cancel(struct hci_conn *conn) | ||
71 | { | ||
72 | hci_send_cmd(conn->hdev, HCI_OP_LE_CREATE_CONN_CANCEL, 0, NULL); | ||
73 | } | ||
74 | |||
48 | void hci_acl_connect(struct hci_conn *conn) | 75 | void hci_acl_connect(struct hci_conn *conn) |
49 | { | 76 | { |
50 | struct hci_dev *hdev = conn->hdev; | 77 | struct hci_dev *hdev = conn->hdev; |
@@ -156,6 +183,26 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle) | |||
156 | hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp); | 183 | hci_send_cmd(hdev, HCI_OP_SETUP_SYNC_CONN, sizeof(cp), &cp); |
157 | } | 184 | } |
158 | 185 | ||
186 | void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, | ||
187 | u16 latency, u16 to_multiplier) | ||
188 | { | ||
189 | struct hci_cp_le_conn_update cp; | ||
190 | struct hci_dev *hdev = conn->hdev; | ||
191 | |||
192 | memset(&cp, 0, sizeof(cp)); | ||
193 | |||
194 | cp.handle = cpu_to_le16(conn->handle); | ||
195 | cp.conn_interval_min = cpu_to_le16(min); | ||
196 | cp.conn_interval_max = cpu_to_le16(max); | ||
197 | cp.conn_latency = cpu_to_le16(latency); | ||
198 | cp.supervision_timeout = cpu_to_le16(to_multiplier); | ||
199 | cp.min_ce_len = cpu_to_le16(0x0001); | ||
200 | cp.max_ce_len = cpu_to_le16(0x0001); | ||
201 | |||
202 | hci_send_cmd(hdev, HCI_OP_LE_CONN_UPDATE, sizeof(cp), &cp); | ||
203 | } | ||
204 | EXPORT_SYMBOL(hci_le_conn_update); | ||
205 | |||
159 | /* Device _must_ be locked */ | 206 | /* Device _must_ be locked */ |
160 | void hci_sco_setup(struct hci_conn *conn, __u8 status) | 207 | void hci_sco_setup(struct hci_conn *conn, __u8 status) |
161 | { | 208 | { |
@@ -193,8 +240,12 @@ static void hci_conn_timeout(unsigned long arg) | |||
193 | switch (conn->state) { | 240 | switch (conn->state) { |
194 | case BT_CONNECT: | 241 | case BT_CONNECT: |
195 | case BT_CONNECT2: | 242 | case BT_CONNECT2: |
196 | if (conn->type == ACL_LINK && conn->out) | 243 | if (conn->out) { |
197 | hci_acl_connect_cancel(conn); | 244 | if (conn->type == ACL_LINK) |
245 | hci_acl_connect_cancel(conn); | ||
246 | else if (conn->type == LE_LINK) | ||
247 | hci_le_connect_cancel(conn); | ||
248 | } | ||
198 | break; | 249 | break; |
199 | case BT_CONFIG: | 250 | case BT_CONFIG: |
200 | case BT_CONNECTED: | 251 | case BT_CONNECTED: |
@@ -234,6 +285,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) | |||
234 | conn->mode = HCI_CM_ACTIVE; | 285 | conn->mode = HCI_CM_ACTIVE; |
235 | conn->state = BT_OPEN; | 286 | conn->state = BT_OPEN; |
236 | conn->auth_type = HCI_AT_GENERAL_BONDING; | 287 | conn->auth_type = HCI_AT_GENERAL_BONDING; |
288 | conn->io_capability = hdev->io_capability; | ||
237 | 289 | ||
238 | conn->power_save = 1; | 290 | conn->power_save = 1; |
239 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; | 291 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; |
@@ -295,6 +347,11 @@ int hci_conn_del(struct hci_conn *conn) | |||
295 | 347 | ||
296 | /* Unacked frames */ | 348 | /* Unacked frames */ |
297 | hdev->acl_cnt += conn->sent; | 349 | hdev->acl_cnt += conn->sent; |
350 | } else if (conn->type == LE_LINK) { | ||
351 | if (hdev->le_pkts) | ||
352 | hdev->le_cnt += conn->sent; | ||
353 | else | ||
354 | hdev->acl_cnt += conn->sent; | ||
298 | } else { | 355 | } else { |
299 | struct hci_conn *acl = conn->link; | 356 | struct hci_conn *acl = conn->link; |
300 | if (acl) { | 357 | if (acl) { |
@@ -360,15 +417,30 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src) | |||
360 | } | 417 | } |
361 | EXPORT_SYMBOL(hci_get_route); | 418 | EXPORT_SYMBOL(hci_get_route); |
362 | 419 | ||
363 | /* Create SCO or ACL connection. | 420 | /* Create SCO, ACL or LE connection. |
364 | * Device _must_ be locked */ | 421 | * Device _must_ be locked */ |
365 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type) | 422 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type) |
366 | { | 423 | { |
367 | struct hci_conn *acl; | 424 | struct hci_conn *acl; |
368 | struct hci_conn *sco; | 425 | struct hci_conn *sco; |
426 | struct hci_conn *le; | ||
369 | 427 | ||
370 | BT_DBG("%s dst %s", hdev->name, batostr(dst)); | 428 | BT_DBG("%s dst %s", hdev->name, batostr(dst)); |
371 | 429 | ||
430 | if (type == LE_LINK) { | ||
431 | le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst); | ||
432 | if (!le) | ||
433 | le = hci_conn_add(hdev, LE_LINK, dst); | ||
434 | if (!le) | ||
435 | return NULL; | ||
436 | if (le->state == BT_OPEN) | ||
437 | hci_le_connect(le); | ||
438 | |||
439 | hci_conn_hold(le); | ||
440 | |||
441 | return le; | ||
442 | } | ||
443 | |||
372 | acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); | 444 | acl = hci_conn_hash_lookup_ba(hdev, ACL_LINK, dst); |
373 | if (!acl) { | 445 | if (!acl) { |
374 | acl = hci_conn_add(hdev, ACL_LINK, dst); | 446 | acl = hci_conn_add(hdev, ACL_LINK, dst); |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 9c4541bc488a..b372fb8bcdcf 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <linux/interrupt.h> | 41 | #include <linux/interrupt.h> |
42 | #include <linux/notifier.h> | 42 | #include <linux/notifier.h> |
43 | #include <linux/rfkill.h> | 43 | #include <linux/rfkill.h> |
44 | #include <linux/timer.h> | ||
44 | #include <net/sock.h> | 45 | #include <net/sock.h> |
45 | 46 | ||
46 | #include <asm/system.h> | 47 | #include <asm/system.h> |
@@ -50,6 +51,8 @@ | |||
50 | #include <net/bluetooth/bluetooth.h> | 51 | #include <net/bluetooth/bluetooth.h> |
51 | #include <net/bluetooth/hci_core.h> | 52 | #include <net/bluetooth/hci_core.h> |
52 | 53 | ||
54 | #define AUTO_OFF_TIMEOUT 2000 | ||
55 | |||
53 | static void hci_cmd_task(unsigned long arg); | 56 | static void hci_cmd_task(unsigned long arg); |
54 | static void hci_rx_task(unsigned long arg); | 57 | static void hci_rx_task(unsigned long arg); |
55 | static void hci_tx_task(unsigned long arg); | 58 | static void hci_tx_task(unsigned long arg); |
@@ -95,11 +98,10 @@ void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result) | |||
95 | { | 98 | { |
96 | BT_DBG("%s command 0x%04x result 0x%2.2x", hdev->name, cmd, result); | 99 | BT_DBG("%s command 0x%04x result 0x%2.2x", hdev->name, cmd, result); |
97 | 100 | ||
98 | /* If the request has set req_last_cmd (typical for multi-HCI | 101 | /* If this is the init phase check if the completed command matches |
99 | * command requests) check if the completed command matches | 102 | * the last init command, and if not just return. |
100 | * this, and if not just return. Single HCI command requests | 103 | */ |
101 | * typically leave req_last_cmd as 0 */ | 104 | if (test_bit(HCI_INIT, &hdev->flags) && hdev->init_last_cmd != cmd) |
102 | if (hdev->req_last_cmd && cmd != hdev->req_last_cmd) | ||
103 | return; | 105 | return; |
104 | 106 | ||
105 | if (hdev->req_status == HCI_REQ_PEND) { | 107 | if (hdev->req_status == HCI_REQ_PEND) { |
@@ -122,7 +124,7 @@ static void hci_req_cancel(struct hci_dev *hdev, int err) | |||
122 | 124 | ||
123 | /* Execute request and wait for completion. */ | 125 | /* Execute request and wait for completion. */ |
124 | static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt), | 126 | static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt), |
125 | unsigned long opt, __u32 timeout) | 127 | unsigned long opt, __u32 timeout) |
126 | { | 128 | { |
127 | DECLARE_WAITQUEUE(wait, current); | 129 | DECLARE_WAITQUEUE(wait, current); |
128 | int err = 0; | 130 | int err = 0; |
@@ -156,7 +158,7 @@ static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, | |||
156 | break; | 158 | break; |
157 | } | 159 | } |
158 | 160 | ||
159 | hdev->req_last_cmd = hdev->req_status = hdev->req_result = 0; | 161 | hdev->req_status = hdev->req_result = 0; |
160 | 162 | ||
161 | BT_DBG("%s end: err %d", hdev->name, err); | 163 | BT_DBG("%s end: err %d", hdev->name, err); |
162 | 164 | ||
@@ -164,7 +166,7 @@ static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, | |||
164 | } | 166 | } |
165 | 167 | ||
166 | static inline int hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt), | 168 | static inline int hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt), |
167 | unsigned long opt, __u32 timeout) | 169 | unsigned long opt, __u32 timeout) |
168 | { | 170 | { |
169 | int ret; | 171 | int ret; |
170 | 172 | ||
@@ -189,6 +191,7 @@ static void hci_reset_req(struct hci_dev *hdev, unsigned long opt) | |||
189 | 191 | ||
190 | static void hci_init_req(struct hci_dev *hdev, unsigned long opt) | 192 | static void hci_init_req(struct hci_dev *hdev, unsigned long opt) |
191 | { | 193 | { |
194 | struct hci_cp_delete_stored_link_key cp; | ||
192 | struct sk_buff *skb; | 195 | struct sk_buff *skb; |
193 | __le16 param; | 196 | __le16 param; |
194 | __u8 flt_type; | 197 | __u8 flt_type; |
@@ -252,15 +255,21 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt) | |||
252 | flt_type = HCI_FLT_CLEAR_ALL; | 255 | flt_type = HCI_FLT_CLEAR_ALL; |
253 | hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type); | 256 | hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type); |
254 | 257 | ||
255 | /* Page timeout ~20 secs */ | ||
256 | param = cpu_to_le16(0x8000); | ||
257 | hci_send_cmd(hdev, HCI_OP_WRITE_PG_TIMEOUT, 2, ¶m); | ||
258 | |||
259 | /* Connection accept timeout ~20 secs */ | 258 | /* Connection accept timeout ~20 secs */ |
260 | param = cpu_to_le16(0x7d00); | 259 | param = cpu_to_le16(0x7d00); |
261 | hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); | 260 | hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); |
262 | 261 | ||
263 | hdev->req_last_cmd = HCI_OP_WRITE_CA_TIMEOUT; | 262 | bacpy(&cp.bdaddr, BDADDR_ANY); |
263 | cp.delete_all = 1; | ||
264 | hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp); | ||
265 | } | ||
266 | |||
267 | static void hci_le_init_req(struct hci_dev *hdev, unsigned long opt) | ||
268 | { | ||
269 | BT_DBG("%s", hdev->name); | ||
270 | |||
271 | /* Read LE buffer size */ | ||
272 | hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); | ||
264 | } | 273 | } |
265 | 274 | ||
266 | static void hci_scan_req(struct hci_dev *hdev, unsigned long opt) | 275 | static void hci_scan_req(struct hci_dev *hdev, unsigned long opt) |
@@ -429,7 +438,8 @@ int hci_inquiry(void __user *arg) | |||
429 | if (copy_from_user(&ir, ptr, sizeof(ir))) | 438 | if (copy_from_user(&ir, ptr, sizeof(ir))) |
430 | return -EFAULT; | 439 | return -EFAULT; |
431 | 440 | ||
432 | if (!(hdev = hci_dev_get(ir.dev_id))) | 441 | hdev = hci_dev_get(ir.dev_id); |
442 | if (!hdev) | ||
433 | return -ENODEV; | 443 | return -ENODEV; |
434 | 444 | ||
435 | hci_dev_lock_bh(hdev); | 445 | hci_dev_lock_bh(hdev); |
@@ -455,7 +465,7 @@ int hci_inquiry(void __user *arg) | |||
455 | /* cache_dump can't sleep. Therefore we allocate temp buffer and then | 465 | /* cache_dump can't sleep. Therefore we allocate temp buffer and then |
456 | * copy it to the user space. | 466 | * copy it to the user space. |
457 | */ | 467 | */ |
458 | buf = kmalloc(sizeof(struct inquiry_info) *max_rsp, GFP_KERNEL); | 468 | buf = kmalloc(sizeof(struct inquiry_info) * max_rsp, GFP_KERNEL); |
459 | if (!buf) { | 469 | if (!buf) { |
460 | err = -ENOMEM; | 470 | err = -ENOMEM; |
461 | goto done; | 471 | goto done; |
@@ -489,7 +499,8 @@ int hci_dev_open(__u16 dev) | |||
489 | struct hci_dev *hdev; | 499 | struct hci_dev *hdev; |
490 | int ret = 0; | 500 | int ret = 0; |
491 | 501 | ||
492 | if (!(hdev = hci_dev_get(dev))) | 502 | hdev = hci_dev_get(dev); |
503 | if (!hdev) | ||
493 | return -ENODEV; | 504 | return -ENODEV; |
494 | 505 | ||
495 | BT_DBG("%s %p", hdev->name, hdev); | 506 | BT_DBG("%s %p", hdev->name, hdev); |
@@ -521,11 +532,15 @@ int hci_dev_open(__u16 dev) | |||
521 | if (!test_bit(HCI_RAW, &hdev->flags)) { | 532 | if (!test_bit(HCI_RAW, &hdev->flags)) { |
522 | atomic_set(&hdev->cmd_cnt, 1); | 533 | atomic_set(&hdev->cmd_cnt, 1); |
523 | set_bit(HCI_INIT, &hdev->flags); | 534 | set_bit(HCI_INIT, &hdev->flags); |
535 | hdev->init_last_cmd = 0; | ||
524 | 536 | ||
525 | //__hci_request(hdev, hci_reset_req, 0, HZ); | ||
526 | ret = __hci_request(hdev, hci_init_req, 0, | 537 | ret = __hci_request(hdev, hci_init_req, 0, |
527 | msecs_to_jiffies(HCI_INIT_TIMEOUT)); | 538 | msecs_to_jiffies(HCI_INIT_TIMEOUT)); |
528 | 539 | ||
540 | if (lmp_le_capable(hdev)) | ||
541 | ret = __hci_request(hdev, hci_le_init_req, 0, | ||
542 | msecs_to_jiffies(HCI_INIT_TIMEOUT)); | ||
543 | |||
529 | clear_bit(HCI_INIT, &hdev->flags); | 544 | clear_bit(HCI_INIT, &hdev->flags); |
530 | } | 545 | } |
531 | 546 | ||
@@ -533,6 +548,8 @@ int hci_dev_open(__u16 dev) | |||
533 | hci_dev_hold(hdev); | 548 | hci_dev_hold(hdev); |
534 | set_bit(HCI_UP, &hdev->flags); | 549 | set_bit(HCI_UP, &hdev->flags); |
535 | hci_notify(hdev, HCI_DEV_UP); | 550 | hci_notify(hdev, HCI_DEV_UP); |
551 | if (!test_bit(HCI_SETUP, &hdev->flags)) | ||
552 | mgmt_powered(hdev->id, 1); | ||
536 | } else { | 553 | } else { |
537 | /* Init failed, cleanup */ | 554 | /* Init failed, cleanup */ |
538 | tasklet_kill(&hdev->rx_task); | 555 | tasklet_kill(&hdev->rx_task); |
@@ -606,6 +623,7 @@ static int hci_dev_do_close(struct hci_dev *hdev) | |||
606 | 623 | ||
607 | /* Drop last sent command */ | 624 | /* Drop last sent command */ |
608 | if (hdev->sent_cmd) { | 625 | if (hdev->sent_cmd) { |
626 | del_timer_sync(&hdev->cmd_timer); | ||
609 | kfree_skb(hdev->sent_cmd); | 627 | kfree_skb(hdev->sent_cmd); |
610 | hdev->sent_cmd = NULL; | 628 | hdev->sent_cmd = NULL; |
611 | } | 629 | } |
@@ -614,6 +632,8 @@ static int hci_dev_do_close(struct hci_dev *hdev) | |||
614 | * and no tasks are scheduled. */ | 632 | * and no tasks are scheduled. */ |
615 | hdev->close(hdev); | 633 | hdev->close(hdev); |
616 | 634 | ||
635 | mgmt_powered(hdev->id, 0); | ||
636 | |||
617 | /* Clear flags */ | 637 | /* Clear flags */ |
618 | hdev->flags = 0; | 638 | hdev->flags = 0; |
619 | 639 | ||
@@ -664,7 +684,7 @@ int hci_dev_reset(__u16 dev) | |||
664 | hdev->flush(hdev); | 684 | hdev->flush(hdev); |
665 | 685 | ||
666 | atomic_set(&hdev->cmd_cnt, 1); | 686 | atomic_set(&hdev->cmd_cnt, 1); |
667 | hdev->acl_cnt = 0; hdev->sco_cnt = 0; | 687 | hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; |
668 | 688 | ||
669 | if (!test_bit(HCI_RAW, &hdev->flags)) | 689 | if (!test_bit(HCI_RAW, &hdev->flags)) |
670 | ret = __hci_request(hdev, hci_reset_req, 0, | 690 | ret = __hci_request(hdev, hci_reset_req, 0, |
@@ -793,9 +813,17 @@ int hci_get_dev_list(void __user *arg) | |||
793 | read_lock_bh(&hci_dev_list_lock); | 813 | read_lock_bh(&hci_dev_list_lock); |
794 | list_for_each(p, &hci_dev_list) { | 814 | list_for_each(p, &hci_dev_list) { |
795 | struct hci_dev *hdev; | 815 | struct hci_dev *hdev; |
816 | |||
796 | hdev = list_entry(p, struct hci_dev, list); | 817 | hdev = list_entry(p, struct hci_dev, list); |
818 | |||
819 | hci_del_off_timer(hdev); | ||
820 | |||
821 | if (!test_bit(HCI_MGMT, &hdev->flags)) | ||
822 | set_bit(HCI_PAIRABLE, &hdev->flags); | ||
823 | |||
797 | (dr + n)->dev_id = hdev->id; | 824 | (dr + n)->dev_id = hdev->id; |
798 | (dr + n)->dev_opt = hdev->flags; | 825 | (dr + n)->dev_opt = hdev->flags; |
826 | |||
799 | if (++n >= dev_num) | 827 | if (++n >= dev_num) |
800 | break; | 828 | break; |
801 | } | 829 | } |
@@ -823,6 +851,11 @@ int hci_get_dev_info(void __user *arg) | |||
823 | if (!hdev) | 851 | if (!hdev) |
824 | return -ENODEV; | 852 | return -ENODEV; |
825 | 853 | ||
854 | hci_del_off_timer(hdev); | ||
855 | |||
856 | if (!test_bit(HCI_MGMT, &hdev->flags)) | ||
857 | set_bit(HCI_PAIRABLE, &hdev->flags); | ||
858 | |||
826 | strcpy(di.name, hdev->name); | 859 | strcpy(di.name, hdev->name); |
827 | di.bdaddr = hdev->bdaddr; | 860 | di.bdaddr = hdev->bdaddr; |
828 | di.type = (hdev->bus & 0x0f) | (hdev->dev_type << 4); | 861 | di.type = (hdev->bus & 0x0f) | (hdev->dev_type << 4); |
@@ -891,6 +924,159 @@ void hci_free_dev(struct hci_dev *hdev) | |||
891 | } | 924 | } |
892 | EXPORT_SYMBOL(hci_free_dev); | 925 | EXPORT_SYMBOL(hci_free_dev); |
893 | 926 | ||
927 | static void hci_power_on(struct work_struct *work) | ||
928 | { | ||
929 | struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); | ||
930 | |||
931 | BT_DBG("%s", hdev->name); | ||
932 | |||
933 | if (hci_dev_open(hdev->id) < 0) | ||
934 | return; | ||
935 | |||
936 | if (test_bit(HCI_AUTO_OFF, &hdev->flags)) | ||
937 | mod_timer(&hdev->off_timer, | ||
938 | jiffies + msecs_to_jiffies(AUTO_OFF_TIMEOUT)); | ||
939 | |||
940 | if (test_and_clear_bit(HCI_SETUP, &hdev->flags)) | ||
941 | mgmt_index_added(hdev->id); | ||
942 | } | ||
943 | |||
944 | static void hci_power_off(struct work_struct *work) | ||
945 | { | ||
946 | struct hci_dev *hdev = container_of(work, struct hci_dev, power_off); | ||
947 | |||
948 | BT_DBG("%s", hdev->name); | ||
949 | |||
950 | hci_dev_close(hdev->id); | ||
951 | } | ||
952 | |||
953 | static void hci_auto_off(unsigned long data) | ||
954 | { | ||
955 | struct hci_dev *hdev = (struct hci_dev *) data; | ||
956 | |||
957 | BT_DBG("%s", hdev->name); | ||
958 | |||
959 | clear_bit(HCI_AUTO_OFF, &hdev->flags); | ||
960 | |||
961 | queue_work(hdev->workqueue, &hdev->power_off); | ||
962 | } | ||
963 | |||
964 | void hci_del_off_timer(struct hci_dev *hdev) | ||
965 | { | ||
966 | BT_DBG("%s", hdev->name); | ||
967 | |||
968 | clear_bit(HCI_AUTO_OFF, &hdev->flags); | ||
969 | del_timer(&hdev->off_timer); | ||
970 | } | ||
971 | |||
972 | int hci_uuids_clear(struct hci_dev *hdev) | ||
973 | { | ||
974 | struct list_head *p, *n; | ||
975 | |||
976 | list_for_each_safe(p, n, &hdev->uuids) { | ||
977 | struct bt_uuid *uuid; | ||
978 | |||
979 | uuid = list_entry(p, struct bt_uuid, list); | ||
980 | |||
981 | list_del(p); | ||
982 | kfree(uuid); | ||
983 | } | ||
984 | |||
985 | return 0; | ||
986 | } | ||
987 | |||
988 | int hci_link_keys_clear(struct hci_dev *hdev) | ||
989 | { | ||
990 | struct list_head *p, *n; | ||
991 | |||
992 | list_for_each_safe(p, n, &hdev->link_keys) { | ||
993 | struct link_key *key; | ||
994 | |||
995 | key = list_entry(p, struct link_key, list); | ||
996 | |||
997 | list_del(p); | ||
998 | kfree(key); | ||
999 | } | ||
1000 | |||
1001 | return 0; | ||
1002 | } | ||
1003 | |||
1004 | struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) | ||
1005 | { | ||
1006 | struct list_head *p; | ||
1007 | |||
1008 | list_for_each(p, &hdev->link_keys) { | ||
1009 | struct link_key *k; | ||
1010 | |||
1011 | k = list_entry(p, struct link_key, list); | ||
1012 | |||
1013 | if (bacmp(bdaddr, &k->bdaddr) == 0) | ||
1014 | return k; | ||
1015 | } | ||
1016 | |||
1017 | return NULL; | ||
1018 | } | ||
1019 | |||
1020 | int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr, | ||
1021 | u8 *val, u8 type, u8 pin_len) | ||
1022 | { | ||
1023 | struct link_key *key, *old_key; | ||
1024 | u8 old_key_type; | ||
1025 | |||
1026 | old_key = hci_find_link_key(hdev, bdaddr); | ||
1027 | if (old_key) { | ||
1028 | old_key_type = old_key->type; | ||
1029 | key = old_key; | ||
1030 | } else { | ||
1031 | old_key_type = 0xff; | ||
1032 | key = kzalloc(sizeof(*key), GFP_ATOMIC); | ||
1033 | if (!key) | ||
1034 | return -ENOMEM; | ||
1035 | list_add(&key->list, &hdev->link_keys); | ||
1036 | } | ||
1037 | |||
1038 | BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type); | ||
1039 | |||
1040 | bacpy(&key->bdaddr, bdaddr); | ||
1041 | memcpy(key->val, val, 16); | ||
1042 | key->type = type; | ||
1043 | key->pin_len = pin_len; | ||
1044 | |||
1045 | if (new_key) | ||
1046 | mgmt_new_key(hdev->id, key, old_key_type); | ||
1047 | |||
1048 | if (type == 0x06) | ||
1049 | key->type = old_key_type; | ||
1050 | |||
1051 | return 0; | ||
1052 | } | ||
1053 | |||
1054 | int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) | ||
1055 | { | ||
1056 | struct link_key *key; | ||
1057 | |||
1058 | key = hci_find_link_key(hdev, bdaddr); | ||
1059 | if (!key) | ||
1060 | return -ENOENT; | ||
1061 | |||
1062 | BT_DBG("%s removing %s", hdev->name, batostr(bdaddr)); | ||
1063 | |||
1064 | list_del(&key->list); | ||
1065 | kfree(key); | ||
1066 | |||
1067 | return 0; | ||
1068 | } | ||
1069 | |||
1070 | /* HCI command timer function */ | ||
1071 | static void hci_cmd_timer(unsigned long arg) | ||
1072 | { | ||
1073 | struct hci_dev *hdev = (void *) arg; | ||
1074 | |||
1075 | BT_ERR("%s command tx timeout", hdev->name); | ||
1076 | atomic_set(&hdev->cmd_cnt, 1); | ||
1077 | tasklet_schedule(&hdev->cmd_task); | ||
1078 | } | ||
1079 | |||
894 | /* Register HCI device */ | 1080 | /* Register HCI device */ |
895 | int hci_register_dev(struct hci_dev *hdev) | 1081 | int hci_register_dev(struct hci_dev *hdev) |
896 | { | 1082 | { |
@@ -923,6 +1109,7 @@ int hci_register_dev(struct hci_dev *hdev) | |||
923 | hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); | 1109 | hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); |
924 | hdev->esco_type = (ESCO_HV1); | 1110 | hdev->esco_type = (ESCO_HV1); |
925 | hdev->link_mode = (HCI_LM_ACCEPT); | 1111 | hdev->link_mode = (HCI_LM_ACCEPT); |
1112 | hdev->io_capability = 0x03; /* No Input No Output */ | ||
926 | 1113 | ||
927 | hdev->idle_timeout = 0; | 1114 | hdev->idle_timeout = 0; |
928 | hdev->sniff_max_interval = 800; | 1115 | hdev->sniff_max_interval = 800; |
@@ -936,6 +1123,8 @@ int hci_register_dev(struct hci_dev *hdev) | |||
936 | skb_queue_head_init(&hdev->cmd_q); | 1123 | skb_queue_head_init(&hdev->cmd_q); |
937 | skb_queue_head_init(&hdev->raw_q); | 1124 | skb_queue_head_init(&hdev->raw_q); |
938 | 1125 | ||
1126 | setup_timer(&hdev->cmd_timer, hci_cmd_timer, (unsigned long) hdev); | ||
1127 | |||
939 | for (i = 0; i < NUM_REASSEMBLY; i++) | 1128 | for (i = 0; i < NUM_REASSEMBLY; i++) |
940 | hdev->reassembly[i] = NULL; | 1129 | hdev->reassembly[i] = NULL; |
941 | 1130 | ||
@@ -948,6 +1137,14 @@ int hci_register_dev(struct hci_dev *hdev) | |||
948 | 1137 | ||
949 | INIT_LIST_HEAD(&hdev->blacklist); | 1138 | INIT_LIST_HEAD(&hdev->blacklist); |
950 | 1139 | ||
1140 | INIT_LIST_HEAD(&hdev->uuids); | ||
1141 | |||
1142 | INIT_LIST_HEAD(&hdev->link_keys); | ||
1143 | |||
1144 | INIT_WORK(&hdev->power_on, hci_power_on); | ||
1145 | INIT_WORK(&hdev->power_off, hci_power_off); | ||
1146 | setup_timer(&hdev->off_timer, hci_auto_off, (unsigned long) hdev); | ||
1147 | |||
951 | memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); | 1148 | memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); |
952 | 1149 | ||
953 | atomic_set(&hdev->promisc, 0); | 1150 | atomic_set(&hdev->promisc, 0); |
@@ -969,7 +1166,10 @@ int hci_register_dev(struct hci_dev *hdev) | |||
969 | } | 1166 | } |
970 | } | 1167 | } |
971 | 1168 | ||
972 | mgmt_index_added(hdev->id); | 1169 | set_bit(HCI_AUTO_OFF, &hdev->flags); |
1170 | set_bit(HCI_SETUP, &hdev->flags); | ||
1171 | queue_work(hdev->workqueue, &hdev->power_on); | ||
1172 | |||
973 | hci_notify(hdev, HCI_DEV_REG); | 1173 | hci_notify(hdev, HCI_DEV_REG); |
974 | 1174 | ||
975 | return id; | 1175 | return id; |
@@ -999,7 +1199,10 @@ int hci_unregister_dev(struct hci_dev *hdev) | |||
999 | for (i = 0; i < NUM_REASSEMBLY; i++) | 1199 | for (i = 0; i < NUM_REASSEMBLY; i++) |
1000 | kfree_skb(hdev->reassembly[i]); | 1200 | kfree_skb(hdev->reassembly[i]); |
1001 | 1201 | ||
1002 | mgmt_index_removed(hdev->id); | 1202 | if (!test_bit(HCI_INIT, &hdev->flags) && |
1203 | !test_bit(HCI_SETUP, &hdev->flags)) | ||
1204 | mgmt_index_removed(hdev->id); | ||
1205 | |||
1003 | hci_notify(hdev, HCI_DEV_UNREG); | 1206 | hci_notify(hdev, HCI_DEV_UNREG); |
1004 | 1207 | ||
1005 | if (hdev->rfkill) { | 1208 | if (hdev->rfkill) { |
@@ -1009,10 +1212,14 @@ int hci_unregister_dev(struct hci_dev *hdev) | |||
1009 | 1212 | ||
1010 | hci_unregister_sysfs(hdev); | 1213 | hci_unregister_sysfs(hdev); |
1011 | 1214 | ||
1215 | hci_del_off_timer(hdev); | ||
1216 | |||
1012 | destroy_workqueue(hdev->workqueue); | 1217 | destroy_workqueue(hdev->workqueue); |
1013 | 1218 | ||
1014 | hci_dev_lock_bh(hdev); | 1219 | hci_dev_lock_bh(hdev); |
1015 | hci_blacklist_clear(hdev); | 1220 | hci_blacklist_clear(hdev); |
1221 | hci_uuids_clear(hdev); | ||
1222 | hci_link_keys_clear(hdev); | ||
1016 | hci_dev_unlock_bh(hdev); | 1223 | hci_dev_unlock_bh(hdev); |
1017 | 1224 | ||
1018 | __hci_dev_put(hdev); | 1225 | __hci_dev_put(hdev); |
@@ -1313,7 +1520,7 @@ static int hci_send_frame(struct sk_buff *skb) | |||
1313 | /* Time stamp */ | 1520 | /* Time stamp */ |
1314 | __net_timestamp(skb); | 1521 | __net_timestamp(skb); |
1315 | 1522 | ||
1316 | hci_send_to_sock(hdev, skb); | 1523 | hci_send_to_sock(hdev, skb, NULL); |
1317 | } | 1524 | } |
1318 | 1525 | ||
1319 | /* Get rid of skb owner, prior to sending to the driver. */ | 1526 | /* Get rid of skb owner, prior to sending to the driver. */ |
@@ -1349,6 +1556,9 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param) | |||
1349 | bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; | 1556 | bt_cb(skb)->pkt_type = HCI_COMMAND_PKT; |
1350 | skb->dev = (void *) hdev; | 1557 | skb->dev = (void *) hdev; |
1351 | 1558 | ||
1559 | if (test_bit(HCI_INIT, &hdev->flags)) | ||
1560 | hdev->init_last_cmd = opcode; | ||
1561 | |||
1352 | skb_queue_tail(&hdev->cmd_q, skb); | 1562 | skb_queue_tail(&hdev->cmd_q, skb); |
1353 | tasklet_schedule(&hdev->cmd_task); | 1563 | tasklet_schedule(&hdev->cmd_task); |
1354 | 1564 | ||
@@ -1395,7 +1605,7 @@ void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags) | |||
1395 | 1605 | ||
1396 | skb->dev = (void *) hdev; | 1606 | skb->dev = (void *) hdev; |
1397 | bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; | 1607 | bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; |
1398 | hci_add_acl_hdr(skb, conn->handle, flags | ACL_START); | 1608 | hci_add_acl_hdr(skb, conn->handle, flags); |
1399 | 1609 | ||
1400 | list = skb_shinfo(skb)->frag_list; | 1610 | list = skb_shinfo(skb)->frag_list; |
1401 | if (!list) { | 1611 | if (!list) { |
@@ -1413,12 +1623,15 @@ void hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags) | |||
1413 | spin_lock_bh(&conn->data_q.lock); | 1623 | spin_lock_bh(&conn->data_q.lock); |
1414 | 1624 | ||
1415 | __skb_queue_tail(&conn->data_q, skb); | 1625 | __skb_queue_tail(&conn->data_q, skb); |
1626 | |||
1627 | flags &= ~ACL_START; | ||
1628 | flags |= ACL_CONT; | ||
1416 | do { | 1629 | do { |
1417 | skb = list; list = list->next; | 1630 | skb = list; list = list->next; |
1418 | 1631 | ||
1419 | skb->dev = (void *) hdev; | 1632 | skb->dev = (void *) hdev; |
1420 | bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; | 1633 | bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT; |
1421 | hci_add_acl_hdr(skb, conn->handle, flags | ACL_CONT); | 1634 | hci_add_acl_hdr(skb, conn->handle, flags); |
1422 | 1635 | ||
1423 | BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); | 1636 | BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len); |
1424 | 1637 | ||
@@ -1486,8 +1699,25 @@ static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int | |||
1486 | } | 1699 | } |
1487 | 1700 | ||
1488 | if (conn) { | 1701 | if (conn) { |
1489 | int cnt = (type == ACL_LINK ? hdev->acl_cnt : hdev->sco_cnt); | 1702 | int cnt, q; |
1490 | int q = cnt / num; | 1703 | |
1704 | switch (conn->type) { | ||
1705 | case ACL_LINK: | ||
1706 | cnt = hdev->acl_cnt; | ||
1707 | break; | ||
1708 | case SCO_LINK: | ||
1709 | case ESCO_LINK: | ||
1710 | cnt = hdev->sco_cnt; | ||
1711 | break; | ||
1712 | case LE_LINK: | ||
1713 | cnt = hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt; | ||
1714 | break; | ||
1715 | default: | ||
1716 | cnt = 0; | ||
1717 | BT_ERR("Unknown link type"); | ||
1718 | } | ||
1719 | |||
1720 | q = cnt / num; | ||
1491 | *quote = q ? q : 1; | 1721 | *quote = q ? q : 1; |
1492 | } else | 1722 | } else |
1493 | *quote = 0; | 1723 | *quote = 0; |
@@ -1496,19 +1726,19 @@ static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int | |||
1496 | return conn; | 1726 | return conn; |
1497 | } | 1727 | } |
1498 | 1728 | ||
1499 | static inline void hci_acl_tx_to(struct hci_dev *hdev) | 1729 | static inline void hci_link_tx_to(struct hci_dev *hdev, __u8 type) |
1500 | { | 1730 | { |
1501 | struct hci_conn_hash *h = &hdev->conn_hash; | 1731 | struct hci_conn_hash *h = &hdev->conn_hash; |
1502 | struct list_head *p; | 1732 | struct list_head *p; |
1503 | struct hci_conn *c; | 1733 | struct hci_conn *c; |
1504 | 1734 | ||
1505 | BT_ERR("%s ACL tx timeout", hdev->name); | 1735 | BT_ERR("%s link tx timeout", hdev->name); |
1506 | 1736 | ||
1507 | /* Kill stalled connections */ | 1737 | /* Kill stalled connections */ |
1508 | list_for_each(p, &h->list) { | 1738 | list_for_each(p, &h->list) { |
1509 | c = list_entry(p, struct hci_conn, list); | 1739 | c = list_entry(p, struct hci_conn, list); |
1510 | if (c->type == ACL_LINK && c->sent) { | 1740 | if (c->type == type && c->sent) { |
1511 | BT_ERR("%s killing stalled ACL connection %s", | 1741 | BT_ERR("%s killing stalled connection %s", |
1512 | hdev->name, batostr(&c->dst)); | 1742 | hdev->name, batostr(&c->dst)); |
1513 | hci_acl_disconn(c, 0x13); | 1743 | hci_acl_disconn(c, 0x13); |
1514 | } | 1744 | } |
@@ -1527,7 +1757,7 @@ static inline void hci_sched_acl(struct hci_dev *hdev) | |||
1527 | /* ACL tx timeout must be longer than maximum | 1757 | /* ACL tx timeout must be longer than maximum |
1528 | * link supervision timeout (40.9 seconds) */ | 1758 | * link supervision timeout (40.9 seconds) */ |
1529 | if (!hdev->acl_cnt && time_after(jiffies, hdev->acl_last_tx + HZ * 45)) | 1759 | if (!hdev->acl_cnt && time_after(jiffies, hdev->acl_last_tx + HZ * 45)) |
1530 | hci_acl_tx_to(hdev); | 1760 | hci_link_tx_to(hdev, ACL_LINK); |
1531 | } | 1761 | } |
1532 | 1762 | ||
1533 | while (hdev->acl_cnt && (conn = hci_low_sent(hdev, ACL_LINK, "e))) { | 1763 | while (hdev->acl_cnt && (conn = hci_low_sent(hdev, ACL_LINK, "e))) { |
@@ -1586,6 +1816,40 @@ static inline void hci_sched_esco(struct hci_dev *hdev) | |||
1586 | } | 1816 | } |
1587 | } | 1817 | } |
1588 | 1818 | ||
1819 | static inline void hci_sched_le(struct hci_dev *hdev) | ||
1820 | { | ||
1821 | struct hci_conn *conn; | ||
1822 | struct sk_buff *skb; | ||
1823 | int quote, cnt; | ||
1824 | |||
1825 | BT_DBG("%s", hdev->name); | ||
1826 | |||
1827 | if (!test_bit(HCI_RAW, &hdev->flags)) { | ||
1828 | /* LE tx timeout must be longer than maximum | ||
1829 | * link supervision timeout (40.9 seconds) */ | ||
1830 | if (!hdev->le_cnt && hdev->le_pkts && | ||
1831 | time_after(jiffies, hdev->le_last_tx + HZ * 45)) | ||
1832 | hci_link_tx_to(hdev, LE_LINK); | ||
1833 | } | ||
1834 | |||
1835 | cnt = hdev->le_pkts ? hdev->le_cnt : hdev->acl_cnt; | ||
1836 | while (cnt && (conn = hci_low_sent(hdev, LE_LINK, "e))) { | ||
1837 | while (quote-- && (skb = skb_dequeue(&conn->data_q))) { | ||
1838 | BT_DBG("skb %p len %d", skb, skb->len); | ||
1839 | |||
1840 | hci_send_frame(skb); | ||
1841 | hdev->le_last_tx = jiffies; | ||
1842 | |||
1843 | cnt--; | ||
1844 | conn->sent++; | ||
1845 | } | ||
1846 | } | ||
1847 | if (hdev->le_pkts) | ||
1848 | hdev->le_cnt = cnt; | ||
1849 | else | ||
1850 | hdev->acl_cnt = cnt; | ||
1851 | } | ||
1852 | |||
1589 | static void hci_tx_task(unsigned long arg) | 1853 | static void hci_tx_task(unsigned long arg) |
1590 | { | 1854 | { |
1591 | struct hci_dev *hdev = (struct hci_dev *) arg; | 1855 | struct hci_dev *hdev = (struct hci_dev *) arg; |
@@ -1593,7 +1857,8 @@ static void hci_tx_task(unsigned long arg) | |||
1593 | 1857 | ||
1594 | read_lock(&hci_task_lock); | 1858 | read_lock(&hci_task_lock); |
1595 | 1859 | ||
1596 | BT_DBG("%s acl %d sco %d", hdev->name, hdev->acl_cnt, hdev->sco_cnt); | 1860 | BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, |
1861 | hdev->sco_cnt, hdev->le_cnt); | ||
1597 | 1862 | ||
1598 | /* Schedule queues and send stuff to HCI driver */ | 1863 | /* Schedule queues and send stuff to HCI driver */ |
1599 | 1864 | ||
@@ -1603,6 +1868,8 @@ static void hci_tx_task(unsigned long arg) | |||
1603 | 1868 | ||
1604 | hci_sched_esco(hdev); | 1869 | hci_sched_esco(hdev); |
1605 | 1870 | ||
1871 | hci_sched_le(hdev); | ||
1872 | |||
1606 | /* Send next queued raw (unknown type) packet */ | 1873 | /* Send next queued raw (unknown type) packet */ |
1607 | while ((skb = skb_dequeue(&hdev->raw_q))) | 1874 | while ((skb = skb_dequeue(&hdev->raw_q))) |
1608 | hci_send_frame(skb); | 1875 | hci_send_frame(skb); |
@@ -1700,7 +1967,7 @@ static void hci_rx_task(unsigned long arg) | |||
1700 | while ((skb = skb_dequeue(&hdev->rx_q))) { | 1967 | while ((skb = skb_dequeue(&hdev->rx_q))) { |
1701 | if (atomic_read(&hdev->promisc)) { | 1968 | if (atomic_read(&hdev->promisc)) { |
1702 | /* Send copy to the sockets */ | 1969 | /* Send copy to the sockets */ |
1703 | hci_send_to_sock(hdev, skb); | 1970 | hci_send_to_sock(hdev, skb, NULL); |
1704 | } | 1971 | } |
1705 | 1972 | ||
1706 | if (test_bit(HCI_RAW, &hdev->flags)) { | 1973 | if (test_bit(HCI_RAW, &hdev->flags)) { |
@@ -1750,20 +2017,20 @@ static void hci_cmd_task(unsigned long arg) | |||
1750 | 2017 | ||
1751 | BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt)); | 2018 | BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt)); |
1752 | 2019 | ||
1753 | if (!atomic_read(&hdev->cmd_cnt) && time_after(jiffies, hdev->cmd_last_tx + HZ)) { | ||
1754 | BT_ERR("%s command tx timeout", hdev->name); | ||
1755 | atomic_set(&hdev->cmd_cnt, 1); | ||
1756 | } | ||
1757 | |||
1758 | /* Send queued commands */ | 2020 | /* Send queued commands */ |
1759 | if (atomic_read(&hdev->cmd_cnt) && (skb = skb_dequeue(&hdev->cmd_q))) { | 2021 | if (atomic_read(&hdev->cmd_cnt)) { |
2022 | skb = skb_dequeue(&hdev->cmd_q); | ||
2023 | if (!skb) | ||
2024 | return; | ||
2025 | |||
1760 | kfree_skb(hdev->sent_cmd); | 2026 | kfree_skb(hdev->sent_cmd); |
1761 | 2027 | ||
1762 | hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC); | 2028 | hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC); |
1763 | if (hdev->sent_cmd) { | 2029 | if (hdev->sent_cmd) { |
1764 | atomic_dec(&hdev->cmd_cnt); | 2030 | atomic_dec(&hdev->cmd_cnt); |
1765 | hci_send_frame(skb); | 2031 | hci_send_frame(skb); |
1766 | hdev->cmd_last_tx = jiffies; | 2032 | mod_timer(&hdev->cmd_timer, |
2033 | jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT)); | ||
1767 | } else { | 2034 | } else { |
1768 | skb_queue_head(&hdev->cmd_q, skb); | 2035 | skb_queue_head(&hdev->cmd_q, skb); |
1769 | tasklet_schedule(&hdev->cmd_task); | 2036 | tasklet_schedule(&hdev->cmd_task); |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index a290854fdaa6..98b5764e4315 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -274,15 +274,24 @@ static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb) | |||
274 | 274 | ||
275 | if (!status) { | 275 | if (!status) { |
276 | __u8 param = *((__u8 *) sent); | 276 | __u8 param = *((__u8 *) sent); |
277 | int old_pscan, old_iscan; | ||
277 | 278 | ||
278 | clear_bit(HCI_PSCAN, &hdev->flags); | 279 | old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags); |
279 | clear_bit(HCI_ISCAN, &hdev->flags); | 280 | old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags); |
280 | 281 | ||
281 | if (param & SCAN_INQUIRY) | 282 | if (param & SCAN_INQUIRY) { |
282 | set_bit(HCI_ISCAN, &hdev->flags); | 283 | set_bit(HCI_ISCAN, &hdev->flags); |
284 | if (!old_iscan) | ||
285 | mgmt_discoverable(hdev->id, 1); | ||
286 | } else if (old_iscan) | ||
287 | mgmt_discoverable(hdev->id, 0); | ||
283 | 288 | ||
284 | if (param & SCAN_PAGE) | 289 | if (param & SCAN_PAGE) { |
285 | set_bit(HCI_PSCAN, &hdev->flags); | 290 | set_bit(HCI_PSCAN, &hdev->flags); |
291 | if (!old_pscan) | ||
292 | mgmt_connectable(hdev->id, 1); | ||
293 | } else if (old_pscan) | ||
294 | mgmt_connectable(hdev->id, 0); | ||
286 | } | 295 | } |
287 | 296 | ||
288 | hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status); | 297 | hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status); |
@@ -415,6 +424,115 @@ static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) | |||
415 | hdev->ssp_mode = *((__u8 *) sent); | 424 | hdev->ssp_mode = *((__u8 *) sent); |
416 | } | 425 | } |
417 | 426 | ||
427 | static u8 hci_get_inquiry_mode(struct hci_dev *hdev) | ||
428 | { | ||
429 | if (hdev->features[6] & LMP_EXT_INQ) | ||
430 | return 2; | ||
431 | |||
432 | if (hdev->features[3] & LMP_RSSI_INQ) | ||
433 | return 1; | ||
434 | |||
435 | if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 && | ||
436 | hdev->lmp_subver == 0x0757) | ||
437 | return 1; | ||
438 | |||
439 | if (hdev->manufacturer == 15) { | ||
440 | if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963) | ||
441 | return 1; | ||
442 | if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963) | ||
443 | return 1; | ||
444 | if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965) | ||
445 | return 1; | ||
446 | } | ||
447 | |||
448 | if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 && | ||
449 | hdev->lmp_subver == 0x1805) | ||
450 | return 1; | ||
451 | |||
452 | return 0; | ||
453 | } | ||
454 | |||
455 | static void hci_setup_inquiry_mode(struct hci_dev *hdev) | ||
456 | { | ||
457 | u8 mode; | ||
458 | |||
459 | mode = hci_get_inquiry_mode(hdev); | ||
460 | |||
461 | hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode); | ||
462 | } | ||
463 | |||
464 | static void hci_setup_event_mask(struct hci_dev *hdev) | ||
465 | { | ||
466 | /* The second byte is 0xff instead of 0x9f (two reserved bits | ||
467 | * disabled) since a Broadcom 1.2 dongle doesn't respond to the | ||
468 | * command otherwise */ | ||
469 | u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 }; | ||
470 | |||
471 | /* Events for 1.2 and newer controllers */ | ||
472 | if (hdev->lmp_ver > 1) { | ||
473 | events[4] |= 0x01; /* Flow Specification Complete */ | ||
474 | events[4] |= 0x02; /* Inquiry Result with RSSI */ | ||
475 | events[4] |= 0x04; /* Read Remote Extended Features Complete */ | ||
476 | events[5] |= 0x08; /* Synchronous Connection Complete */ | ||
477 | events[5] |= 0x10; /* Synchronous Connection Changed */ | ||
478 | } | ||
479 | |||
480 | if (hdev->features[3] & LMP_RSSI_INQ) | ||
481 | events[4] |= 0x04; /* Inquiry Result with RSSI */ | ||
482 | |||
483 | if (hdev->features[5] & LMP_SNIFF_SUBR) | ||
484 | events[5] |= 0x20; /* Sniff Subrating */ | ||
485 | |||
486 | if (hdev->features[5] & LMP_PAUSE_ENC) | ||
487 | events[5] |= 0x80; /* Encryption Key Refresh Complete */ | ||
488 | |||
489 | if (hdev->features[6] & LMP_EXT_INQ) | ||
490 | events[5] |= 0x40; /* Extended Inquiry Result */ | ||
491 | |||
492 | if (hdev->features[6] & LMP_NO_FLUSH) | ||
493 | events[7] |= 0x01; /* Enhanced Flush Complete */ | ||
494 | |||
495 | if (hdev->features[7] & LMP_LSTO) | ||
496 | events[6] |= 0x80; /* Link Supervision Timeout Changed */ | ||
497 | |||
498 | if (hdev->features[6] & LMP_SIMPLE_PAIR) { | ||
499 | events[6] |= 0x01; /* IO Capability Request */ | ||
500 | events[6] |= 0x02; /* IO Capability Response */ | ||
501 | events[6] |= 0x04; /* User Confirmation Request */ | ||
502 | events[6] |= 0x08; /* User Passkey Request */ | ||
503 | events[6] |= 0x10; /* Remote OOB Data Request */ | ||
504 | events[6] |= 0x20; /* Simple Pairing Complete */ | ||
505 | events[7] |= 0x04; /* User Passkey Notification */ | ||
506 | events[7] |= 0x08; /* Keypress Notification */ | ||
507 | events[7] |= 0x10; /* Remote Host Supported | ||
508 | * Features Notification */ | ||
509 | } | ||
510 | |||
511 | if (hdev->features[4] & LMP_LE) | ||
512 | events[7] |= 0x20; /* LE Meta-Event */ | ||
513 | |||
514 | hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events); | ||
515 | } | ||
516 | |||
517 | static void hci_setup(struct hci_dev *hdev) | ||
518 | { | ||
519 | hci_setup_event_mask(hdev); | ||
520 | |||
521 | if (hdev->lmp_ver > 1) | ||
522 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); | ||
523 | |||
524 | if (hdev->features[6] & LMP_SIMPLE_PAIR) { | ||
525 | u8 mode = 0x01; | ||
526 | hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, sizeof(mode), &mode); | ||
527 | } | ||
528 | |||
529 | if (hdev->features[3] & LMP_RSSI_INQ) | ||
530 | hci_setup_inquiry_mode(hdev); | ||
531 | |||
532 | if (hdev->features[7] & LMP_INQ_TX_PWR) | ||
533 | hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL); | ||
534 | } | ||
535 | |||
418 | static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) | 536 | static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) |
419 | { | 537 | { |
420 | struct hci_rp_read_local_version *rp = (void *) skb->data; | 538 | struct hci_rp_read_local_version *rp = (void *) skb->data; |
@@ -426,11 +544,34 @@ static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) | |||
426 | 544 | ||
427 | hdev->hci_ver = rp->hci_ver; | 545 | hdev->hci_ver = rp->hci_ver; |
428 | hdev->hci_rev = __le16_to_cpu(rp->hci_rev); | 546 | hdev->hci_rev = __le16_to_cpu(rp->hci_rev); |
547 | hdev->lmp_ver = rp->lmp_ver; | ||
429 | hdev->manufacturer = __le16_to_cpu(rp->manufacturer); | 548 | hdev->manufacturer = __le16_to_cpu(rp->manufacturer); |
549 | hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver); | ||
430 | 550 | ||
431 | BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name, | 551 | BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name, |
432 | hdev->manufacturer, | 552 | hdev->manufacturer, |
433 | hdev->hci_ver, hdev->hci_rev); | 553 | hdev->hci_ver, hdev->hci_rev); |
554 | |||
555 | if (test_bit(HCI_INIT, &hdev->flags)) | ||
556 | hci_setup(hdev); | ||
557 | } | ||
558 | |||
559 | static void hci_setup_link_policy(struct hci_dev *hdev) | ||
560 | { | ||
561 | u16 link_policy = 0; | ||
562 | |||
563 | if (hdev->features[0] & LMP_RSWITCH) | ||
564 | link_policy |= HCI_LP_RSWITCH; | ||
565 | if (hdev->features[0] & LMP_HOLD) | ||
566 | link_policy |= HCI_LP_HOLD; | ||
567 | if (hdev->features[0] & LMP_SNIFF) | ||
568 | link_policy |= HCI_LP_SNIFF; | ||
569 | if (hdev->features[1] & LMP_PARK) | ||
570 | link_policy |= HCI_LP_PARK; | ||
571 | |||
572 | link_policy = cpu_to_le16(link_policy); | ||
573 | hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, | ||
574 | sizeof(link_policy), &link_policy); | ||
434 | } | 575 | } |
435 | 576 | ||
436 | static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb) | 577 | static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb) |
@@ -440,9 +581,15 @@ static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb | |||
440 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 581 | BT_DBG("%s status 0x%x", hdev->name, rp->status); |
441 | 582 | ||
442 | if (rp->status) | 583 | if (rp->status) |
443 | return; | 584 | goto done; |
444 | 585 | ||
445 | memcpy(hdev->commands, rp->commands, sizeof(hdev->commands)); | 586 | memcpy(hdev->commands, rp->commands, sizeof(hdev->commands)); |
587 | |||
588 | if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10)) | ||
589 | hci_setup_link_policy(hdev); | ||
590 | |||
591 | done: | ||
592 | hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status); | ||
446 | } | 593 | } |
447 | 594 | ||
448 | static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb) | 595 | static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb) |
@@ -548,6 +695,107 @@ static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb) | |||
548 | hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status); | 695 | hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status); |
549 | } | 696 | } |
550 | 697 | ||
698 | static void hci_cc_delete_stored_link_key(struct hci_dev *hdev, | ||
699 | struct sk_buff *skb) | ||
700 | { | ||
701 | __u8 status = *((__u8 *) skb->data); | ||
702 | |||
703 | BT_DBG("%s status 0x%x", hdev->name, status); | ||
704 | |||
705 | hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status); | ||
706 | } | ||
707 | |||
708 | static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb) | ||
709 | { | ||
710 | __u8 status = *((__u8 *) skb->data); | ||
711 | |||
712 | BT_DBG("%s status 0x%x", hdev->name, status); | ||
713 | |||
714 | hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status); | ||
715 | } | ||
716 | |||
717 | static void hci_cc_write_inquiry_mode(struct hci_dev *hdev, | ||
718 | struct sk_buff *skb) | ||
719 | { | ||
720 | __u8 status = *((__u8 *) skb->data); | ||
721 | |||
722 | BT_DBG("%s status 0x%x", hdev->name, status); | ||
723 | |||
724 | hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status); | ||
725 | } | ||
726 | |||
727 | static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev, | ||
728 | struct sk_buff *skb) | ||
729 | { | ||
730 | __u8 status = *((__u8 *) skb->data); | ||
731 | |||
732 | BT_DBG("%s status 0x%x", hdev->name, status); | ||
733 | |||
734 | hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status); | ||
735 | } | ||
736 | |||
737 | static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb) | ||
738 | { | ||
739 | __u8 status = *((__u8 *) skb->data); | ||
740 | |||
741 | BT_DBG("%s status 0x%x", hdev->name, status); | ||
742 | |||
743 | hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status); | ||
744 | } | ||
745 | |||
746 | static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb) | ||
747 | { | ||
748 | struct hci_rp_pin_code_reply *rp = (void *) skb->data; | ||
749 | struct hci_cp_pin_code_reply *cp; | ||
750 | struct hci_conn *conn; | ||
751 | |||
752 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | ||
753 | |||
754 | if (test_bit(HCI_MGMT, &hdev->flags)) | ||
755 | mgmt_pin_code_reply_complete(hdev->id, &rp->bdaddr, rp->status); | ||
756 | |||
757 | if (rp->status != 0) | ||
758 | return; | ||
759 | |||
760 | cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY); | ||
761 | if (!cp) | ||
762 | return; | ||
763 | |||
764 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); | ||
765 | if (conn) | ||
766 | conn->pin_length = cp->pin_len; | ||
767 | } | ||
768 | |||
769 | static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) | ||
770 | { | ||
771 | struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data; | ||
772 | |||
773 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | ||
774 | |||
775 | if (test_bit(HCI_MGMT, &hdev->flags)) | ||
776 | mgmt_pin_code_neg_reply_complete(hdev->id, &rp->bdaddr, | ||
777 | rp->status); | ||
778 | } | ||
779 | static void hci_cc_le_read_buffer_size(struct hci_dev *hdev, | ||
780 | struct sk_buff *skb) | ||
781 | { | ||
782 | struct hci_rp_le_read_buffer_size *rp = (void *) skb->data; | ||
783 | |||
784 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | ||
785 | |||
786 | if (rp->status) | ||
787 | return; | ||
788 | |||
789 | hdev->le_mtu = __le16_to_cpu(rp->le_mtu); | ||
790 | hdev->le_pkts = rp->le_max_pkt; | ||
791 | |||
792 | hdev->le_cnt = hdev->le_pkts; | ||
793 | |||
794 | BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts); | ||
795 | |||
796 | hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status); | ||
797 | } | ||
798 | |||
551 | static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) | 799 | static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) |
552 | { | 800 | { |
553 | BT_DBG("%s status 0x%x", hdev->name, status); | 801 | BT_DBG("%s status 0x%x", hdev->name, status); |
@@ -622,11 +870,14 @@ static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status) | |||
622 | hci_dev_lock(hdev); | 870 | hci_dev_lock(hdev); |
623 | 871 | ||
624 | acl = hci_conn_hash_lookup_handle(hdev, handle); | 872 | acl = hci_conn_hash_lookup_handle(hdev, handle); |
625 | if (acl && (sco = acl->link)) { | 873 | if (acl) { |
626 | sco->state = BT_CLOSED; | 874 | sco = acl->link; |
875 | if (sco) { | ||
876 | sco->state = BT_CLOSED; | ||
627 | 877 | ||
628 | hci_proto_connect_cfm(sco, status); | 878 | hci_proto_connect_cfm(sco, status); |
629 | hci_conn_del(sco); | 879 | hci_conn_del(sco); |
880 | } | ||
630 | } | 881 | } |
631 | 882 | ||
632 | hci_dev_unlock(hdev); | 883 | hci_dev_unlock(hdev); |
@@ -687,7 +938,7 @@ static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status) | |||
687 | } | 938 | } |
688 | 939 | ||
689 | static int hci_outgoing_auth_needed(struct hci_dev *hdev, | 940 | static int hci_outgoing_auth_needed(struct hci_dev *hdev, |
690 | struct hci_conn *conn) | 941 | struct hci_conn *conn) |
691 | { | 942 | { |
692 | if (conn->state != BT_CONFIG || !conn->out) | 943 | if (conn->state != BT_CONFIG || !conn->out) |
693 | return 0; | 944 | return 0; |
@@ -808,11 +1059,14 @@ static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status) | |||
808 | hci_dev_lock(hdev); | 1059 | hci_dev_lock(hdev); |
809 | 1060 | ||
810 | acl = hci_conn_hash_lookup_handle(hdev, handle); | 1061 | acl = hci_conn_hash_lookup_handle(hdev, handle); |
811 | if (acl && (sco = acl->link)) { | 1062 | if (acl) { |
812 | sco->state = BT_CLOSED; | 1063 | sco = acl->link; |
1064 | if (sco) { | ||
1065 | sco->state = BT_CLOSED; | ||
813 | 1066 | ||
814 | hci_proto_connect_cfm(sco, status); | 1067 | hci_proto_connect_cfm(sco, status); |
815 | hci_conn_del(sco); | 1068 | hci_conn_del(sco); |
1069 | } | ||
816 | } | 1070 | } |
817 | 1071 | ||
818 | hci_dev_unlock(hdev); | 1072 | hci_dev_unlock(hdev); |
@@ -872,6 +1126,43 @@ static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status) | |||
872 | hci_dev_unlock(hdev); | 1126 | hci_dev_unlock(hdev); |
873 | } | 1127 | } |
874 | 1128 | ||
1129 | static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status) | ||
1130 | { | ||
1131 | struct hci_cp_le_create_conn *cp; | ||
1132 | struct hci_conn *conn; | ||
1133 | |||
1134 | BT_DBG("%s status 0x%x", hdev->name, status); | ||
1135 | |||
1136 | cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN); | ||
1137 | if (!cp) | ||
1138 | return; | ||
1139 | |||
1140 | hci_dev_lock(hdev); | ||
1141 | |||
1142 | conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr); | ||
1143 | |||
1144 | BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr), | ||
1145 | conn); | ||
1146 | |||
1147 | if (status) { | ||
1148 | if (conn && conn->state == BT_CONNECT) { | ||
1149 | conn->state = BT_CLOSED; | ||
1150 | hci_proto_connect_cfm(conn, status); | ||
1151 | hci_conn_del(conn); | ||
1152 | } | ||
1153 | } else { | ||
1154 | if (!conn) { | ||
1155 | conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr); | ||
1156 | if (conn) | ||
1157 | conn->out = 1; | ||
1158 | else | ||
1159 | BT_ERR("No memory for new connection"); | ||
1160 | } | ||
1161 | } | ||
1162 | |||
1163 | hci_dev_unlock(hdev); | ||
1164 | } | ||
1165 | |||
875 | static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 1166 | static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) |
876 | { | 1167 | { |
877 | __u8 status = *((__u8 *) skb->data); | 1168 | __u8 status = *((__u8 *) skb->data); |
@@ -942,6 +1233,7 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
942 | conn->state = BT_CONFIG; | 1233 | conn->state = BT_CONFIG; |
943 | hci_conn_hold(conn); | 1234 | hci_conn_hold(conn); |
944 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; | 1235 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; |
1236 | mgmt_connected(hdev->id, &ev->bdaddr); | ||
945 | } else | 1237 | } else |
946 | conn->state = BT_CONNECTED; | 1238 | conn->state = BT_CONNECTED; |
947 | 1239 | ||
@@ -970,8 +1262,11 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
970 | hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, | 1262 | hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, |
971 | sizeof(cp), &cp); | 1263 | sizeof(cp), &cp); |
972 | } | 1264 | } |
973 | } else | 1265 | } else { |
974 | conn->state = BT_CLOSED; | 1266 | conn->state = BT_CLOSED; |
1267 | if (conn->type == ACL_LINK) | ||
1268 | mgmt_connect_failed(hdev->id, &ev->bdaddr, ev->status); | ||
1269 | } | ||
975 | 1270 | ||
976 | if (conn->type == ACL_LINK) | 1271 | if (conn->type == ACL_LINK) |
977 | hci_sco_setup(conn, ev->status); | 1272 | hci_sco_setup(conn, ev->status); |
@@ -998,7 +1293,8 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
998 | 1293 | ||
999 | mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type); | 1294 | mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type); |
1000 | 1295 | ||
1001 | if ((mask & HCI_LM_ACCEPT) && !hci_blacklist_lookup(hdev, &ev->bdaddr)) { | 1296 | if ((mask & HCI_LM_ACCEPT) && |
1297 | !hci_blacklist_lookup(hdev, &ev->bdaddr)) { | ||
1002 | /* Connection accepted */ | 1298 | /* Connection accepted */ |
1003 | struct inquiry_entry *ie; | 1299 | struct inquiry_entry *ie; |
1004 | struct hci_conn *conn; | 1300 | struct hci_conn *conn; |
@@ -1068,19 +1364,26 @@ static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff | |||
1068 | 1364 | ||
1069 | BT_DBG("%s status %d", hdev->name, ev->status); | 1365 | BT_DBG("%s status %d", hdev->name, ev->status); |
1070 | 1366 | ||
1071 | if (ev->status) | 1367 | if (ev->status) { |
1368 | mgmt_disconnect_failed(hdev->id); | ||
1072 | return; | 1369 | return; |
1370 | } | ||
1073 | 1371 | ||
1074 | hci_dev_lock(hdev); | 1372 | hci_dev_lock(hdev); |
1075 | 1373 | ||
1076 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); | 1374 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); |
1077 | if (conn) { | 1375 | if (!conn) |
1078 | conn->state = BT_CLOSED; | 1376 | goto unlock; |
1079 | 1377 | ||
1080 | hci_proto_disconn_cfm(conn, ev->reason); | 1378 | conn->state = BT_CLOSED; |
1081 | hci_conn_del(conn); | 1379 | |
1082 | } | 1380 | if (conn->type == ACL_LINK) |
1381 | mgmt_disconnected(hdev->id, &conn->dst); | ||
1083 | 1382 | ||
1383 | hci_proto_disconn_cfm(conn, ev->reason); | ||
1384 | hci_conn_del(conn); | ||
1385 | |||
1386 | unlock: | ||
1084 | hci_dev_unlock(hdev); | 1387 | hci_dev_unlock(hdev); |
1085 | } | 1388 | } |
1086 | 1389 | ||
@@ -1393,11 +1696,46 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
1393 | hci_cc_write_ca_timeout(hdev, skb); | 1696 | hci_cc_write_ca_timeout(hdev, skb); |
1394 | break; | 1697 | break; |
1395 | 1698 | ||
1699 | case HCI_OP_DELETE_STORED_LINK_KEY: | ||
1700 | hci_cc_delete_stored_link_key(hdev, skb); | ||
1701 | break; | ||
1702 | |||
1703 | case HCI_OP_SET_EVENT_MASK: | ||
1704 | hci_cc_set_event_mask(hdev, skb); | ||
1705 | break; | ||
1706 | |||
1707 | case HCI_OP_WRITE_INQUIRY_MODE: | ||
1708 | hci_cc_write_inquiry_mode(hdev, skb); | ||
1709 | break; | ||
1710 | |||
1711 | case HCI_OP_READ_INQ_RSP_TX_POWER: | ||
1712 | hci_cc_read_inq_rsp_tx_power(hdev, skb); | ||
1713 | break; | ||
1714 | |||
1715 | case HCI_OP_SET_EVENT_FLT: | ||
1716 | hci_cc_set_event_flt(hdev, skb); | ||
1717 | break; | ||
1718 | |||
1719 | case HCI_OP_PIN_CODE_REPLY: | ||
1720 | hci_cc_pin_code_reply(hdev, skb); | ||
1721 | break; | ||
1722 | |||
1723 | case HCI_OP_PIN_CODE_NEG_REPLY: | ||
1724 | hci_cc_pin_code_neg_reply(hdev, skb); | ||
1725 | break; | ||
1726 | |||
1727 | case HCI_OP_LE_READ_BUFFER_SIZE: | ||
1728 | hci_cc_le_read_buffer_size(hdev, skb); | ||
1729 | break; | ||
1730 | |||
1396 | default: | 1731 | default: |
1397 | BT_DBG("%s opcode 0x%x", hdev->name, opcode); | 1732 | BT_DBG("%s opcode 0x%x", hdev->name, opcode); |
1398 | break; | 1733 | break; |
1399 | } | 1734 | } |
1400 | 1735 | ||
1736 | if (ev->opcode != HCI_OP_NOP) | ||
1737 | del_timer(&hdev->cmd_timer); | ||
1738 | |||
1401 | if (ev->ncmd) { | 1739 | if (ev->ncmd) { |
1402 | atomic_set(&hdev->cmd_cnt, 1); | 1740 | atomic_set(&hdev->cmd_cnt, 1); |
1403 | if (!skb_queue_empty(&hdev->cmd_q)) | 1741 | if (!skb_queue_empty(&hdev->cmd_q)) |
@@ -1459,11 +1797,23 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
1459 | hci_cs_exit_sniff_mode(hdev, ev->status); | 1797 | hci_cs_exit_sniff_mode(hdev, ev->status); |
1460 | break; | 1798 | break; |
1461 | 1799 | ||
1800 | case HCI_OP_DISCONNECT: | ||
1801 | if (ev->status != 0) | ||
1802 | mgmt_disconnect_failed(hdev->id); | ||
1803 | break; | ||
1804 | |||
1805 | case HCI_OP_LE_CREATE_CONN: | ||
1806 | hci_cs_le_create_conn(hdev, ev->status); | ||
1807 | break; | ||
1808 | |||
1462 | default: | 1809 | default: |
1463 | BT_DBG("%s opcode 0x%x", hdev->name, opcode); | 1810 | BT_DBG("%s opcode 0x%x", hdev->name, opcode); |
1464 | break; | 1811 | break; |
1465 | } | 1812 | } |
1466 | 1813 | ||
1814 | if (ev->opcode != HCI_OP_NOP) | ||
1815 | del_timer(&hdev->cmd_timer); | ||
1816 | |||
1467 | if (ev->ncmd) { | 1817 | if (ev->ncmd) { |
1468 | atomic_set(&hdev->cmd_cnt, 1); | 1818 | atomic_set(&hdev->cmd_cnt, 1); |
1469 | if (!skb_queue_empty(&hdev->cmd_q)) | 1819 | if (!skb_queue_empty(&hdev->cmd_q)) |
@@ -1529,6 +1879,16 @@ static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *s | |||
1529 | hdev->acl_cnt += count; | 1879 | hdev->acl_cnt += count; |
1530 | if (hdev->acl_cnt > hdev->acl_pkts) | 1880 | if (hdev->acl_cnt > hdev->acl_pkts) |
1531 | hdev->acl_cnt = hdev->acl_pkts; | 1881 | hdev->acl_cnt = hdev->acl_pkts; |
1882 | } else if (conn->type == LE_LINK) { | ||
1883 | if (hdev->le_pkts) { | ||
1884 | hdev->le_cnt += count; | ||
1885 | if (hdev->le_cnt > hdev->le_pkts) | ||
1886 | hdev->le_cnt = hdev->le_pkts; | ||
1887 | } else { | ||
1888 | hdev->acl_cnt += count; | ||
1889 | if (hdev->acl_cnt > hdev->acl_pkts) | ||
1890 | hdev->acl_cnt = hdev->acl_pkts; | ||
1891 | } | ||
1532 | } else { | 1892 | } else { |
1533 | hdev->sco_cnt += count; | 1893 | hdev->sco_cnt += count; |
1534 | if (hdev->sco_cnt > hdev->sco_pkts) | 1894 | if (hdev->sco_cnt > hdev->sco_pkts) |
@@ -1586,18 +1946,72 @@ static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff | |||
1586 | hci_conn_put(conn); | 1946 | hci_conn_put(conn); |
1587 | } | 1947 | } |
1588 | 1948 | ||
1949 | if (!test_bit(HCI_PAIRABLE, &hdev->flags)) | ||
1950 | hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, | ||
1951 | sizeof(ev->bdaddr), &ev->bdaddr); | ||
1952 | |||
1953 | if (test_bit(HCI_MGMT, &hdev->flags)) | ||
1954 | mgmt_pin_code_request(hdev->id, &ev->bdaddr); | ||
1955 | |||
1589 | hci_dev_unlock(hdev); | 1956 | hci_dev_unlock(hdev); |
1590 | } | 1957 | } |
1591 | 1958 | ||
1592 | static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) | 1959 | static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) |
1593 | { | 1960 | { |
1961 | struct hci_ev_link_key_req *ev = (void *) skb->data; | ||
1962 | struct hci_cp_link_key_reply cp; | ||
1963 | struct hci_conn *conn; | ||
1964 | struct link_key *key; | ||
1965 | |||
1594 | BT_DBG("%s", hdev->name); | 1966 | BT_DBG("%s", hdev->name); |
1967 | |||
1968 | if (!test_bit(HCI_LINK_KEYS, &hdev->flags)) | ||
1969 | return; | ||
1970 | |||
1971 | hci_dev_lock(hdev); | ||
1972 | |||
1973 | key = hci_find_link_key(hdev, &ev->bdaddr); | ||
1974 | if (!key) { | ||
1975 | BT_DBG("%s link key not found for %s", hdev->name, | ||
1976 | batostr(&ev->bdaddr)); | ||
1977 | goto not_found; | ||
1978 | } | ||
1979 | |||
1980 | BT_DBG("%s found key type %u for %s", hdev->name, key->type, | ||
1981 | batostr(&ev->bdaddr)); | ||
1982 | |||
1983 | if (!test_bit(HCI_DEBUG_KEYS, &hdev->flags) && key->type == 0x03) { | ||
1984 | BT_DBG("%s ignoring debug key", hdev->name); | ||
1985 | goto not_found; | ||
1986 | } | ||
1987 | |||
1988 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); | ||
1989 | |||
1990 | if (key->type == 0x04 && conn && conn->auth_type != 0xff && | ||
1991 | (conn->auth_type & 0x01)) { | ||
1992 | BT_DBG("%s ignoring unauthenticated key", hdev->name); | ||
1993 | goto not_found; | ||
1994 | } | ||
1995 | |||
1996 | bacpy(&cp.bdaddr, &ev->bdaddr); | ||
1997 | memcpy(cp.link_key, key->val, 16); | ||
1998 | |||
1999 | hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp); | ||
2000 | |||
2001 | hci_dev_unlock(hdev); | ||
2002 | |||
2003 | return; | ||
2004 | |||
2005 | not_found: | ||
2006 | hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr); | ||
2007 | hci_dev_unlock(hdev); | ||
1595 | } | 2008 | } |
1596 | 2009 | ||
1597 | static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) | 2010 | static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) |
1598 | { | 2011 | { |
1599 | struct hci_ev_link_key_notify *ev = (void *) skb->data; | 2012 | struct hci_ev_link_key_notify *ev = (void *) skb->data; |
1600 | struct hci_conn *conn; | 2013 | struct hci_conn *conn; |
2014 | u8 pin_len = 0; | ||
1601 | 2015 | ||
1602 | BT_DBG("%s", hdev->name); | 2016 | BT_DBG("%s", hdev->name); |
1603 | 2017 | ||
@@ -1607,9 +2021,14 @@ static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff | |||
1607 | if (conn) { | 2021 | if (conn) { |
1608 | hci_conn_hold(conn); | 2022 | hci_conn_hold(conn); |
1609 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; | 2023 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; |
2024 | pin_len = conn->pin_length; | ||
1610 | hci_conn_put(conn); | 2025 | hci_conn_put(conn); |
1611 | } | 2026 | } |
1612 | 2027 | ||
2028 | if (test_bit(HCI_LINK_KEYS, &hdev->flags)) | ||
2029 | hci_add_link_key(hdev, 1, &ev->bdaddr, ev->link_key, | ||
2030 | ev->key_type, pin_len); | ||
2031 | |||
1613 | hci_dev_unlock(hdev); | 2032 | hci_dev_unlock(hdev); |
1614 | } | 2033 | } |
1615 | 2034 | ||
@@ -1683,7 +2102,8 @@ static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct | |||
1683 | hci_dev_lock(hdev); | 2102 | hci_dev_lock(hdev); |
1684 | 2103 | ||
1685 | if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) { | 2104 | if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) { |
1686 | struct inquiry_info_with_rssi_and_pscan_mode *info = (void *) (skb->data + 1); | 2105 | struct inquiry_info_with_rssi_and_pscan_mode *info; |
2106 | info = (void *) (skb->data + 1); | ||
1687 | 2107 | ||
1688 | for (; num_rsp; num_rsp--) { | 2108 | for (; num_rsp; num_rsp--) { |
1689 | bacpy(&data.bdaddr, &info->bdaddr); | 2109 | bacpy(&data.bdaddr, &info->bdaddr); |
@@ -1824,17 +2244,8 @@ static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buf | |||
1824 | static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb) | 2244 | static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb) |
1825 | { | 2245 | { |
1826 | struct hci_ev_sniff_subrate *ev = (void *) skb->data; | 2246 | struct hci_ev_sniff_subrate *ev = (void *) skb->data; |
1827 | struct hci_conn *conn; | ||
1828 | 2247 | ||
1829 | BT_DBG("%s status %d", hdev->name, ev->status); | 2248 | BT_DBG("%s status %d", hdev->name, ev->status); |
1830 | |||
1831 | hci_dev_lock(hdev); | ||
1832 | |||
1833 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); | ||
1834 | if (conn) { | ||
1835 | } | ||
1836 | |||
1837 | hci_dev_unlock(hdev); | ||
1838 | } | 2249 | } |
1839 | 2250 | ||
1840 | static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) | 2251 | static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) |
@@ -1852,12 +2263,12 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct | |||
1852 | 2263 | ||
1853 | for (; num_rsp; num_rsp--) { | 2264 | for (; num_rsp; num_rsp--) { |
1854 | bacpy(&data.bdaddr, &info->bdaddr); | 2265 | bacpy(&data.bdaddr, &info->bdaddr); |
1855 | data.pscan_rep_mode = info->pscan_rep_mode; | 2266 | data.pscan_rep_mode = info->pscan_rep_mode; |
1856 | data.pscan_period_mode = info->pscan_period_mode; | 2267 | data.pscan_period_mode = info->pscan_period_mode; |
1857 | data.pscan_mode = 0x00; | 2268 | data.pscan_mode = 0x00; |
1858 | memcpy(data.dev_class, info->dev_class, 3); | 2269 | memcpy(data.dev_class, info->dev_class, 3); |
1859 | data.clock_offset = info->clock_offset; | 2270 | data.clock_offset = info->clock_offset; |
1860 | data.rssi = info->rssi; | 2271 | data.rssi = info->rssi; |
1861 | data.ssp_mode = 0x01; | 2272 | data.ssp_mode = 0x01; |
1862 | info++; | 2273 | info++; |
1863 | hci_inquiry_cache_update(hdev, &data); | 2274 | hci_inquiry_cache_update(hdev, &data); |
@@ -1866,6 +2277,25 @@ static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct | |||
1866 | hci_dev_unlock(hdev); | 2277 | hci_dev_unlock(hdev); |
1867 | } | 2278 | } |
1868 | 2279 | ||
2280 | static inline u8 hci_get_auth_req(struct hci_conn *conn) | ||
2281 | { | ||
2282 | /* If remote requests dedicated bonding follow that lead */ | ||
2283 | if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) { | ||
2284 | /* If both remote and local IO capabilities allow MITM | ||
2285 | * protection then require it, otherwise don't */ | ||
2286 | if (conn->remote_cap == 0x03 || conn->io_capability == 0x03) | ||
2287 | return 0x02; | ||
2288 | else | ||
2289 | return 0x03; | ||
2290 | } | ||
2291 | |||
2292 | /* If remote requests no-bonding follow that lead */ | ||
2293 | if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01) | ||
2294 | return 0x00; | ||
2295 | |||
2296 | return conn->auth_type; | ||
2297 | } | ||
2298 | |||
1869 | static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb) | 2299 | static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb) |
1870 | { | 2300 | { |
1871 | struct hci_ev_io_capa_request *ev = (void *) skb->data; | 2301 | struct hci_ev_io_capa_request *ev = (void *) skb->data; |
@@ -1876,9 +2306,59 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff | |||
1876 | hci_dev_lock(hdev); | 2306 | hci_dev_lock(hdev); |
1877 | 2307 | ||
1878 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); | 2308 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); |
1879 | if (conn) | 2309 | if (!conn) |
1880 | hci_conn_hold(conn); | 2310 | goto unlock; |
2311 | |||
2312 | hci_conn_hold(conn); | ||
2313 | |||
2314 | if (!test_bit(HCI_MGMT, &hdev->flags)) | ||
2315 | goto unlock; | ||
2316 | |||
2317 | if (test_bit(HCI_PAIRABLE, &hdev->flags) || | ||
2318 | (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) { | ||
2319 | struct hci_cp_io_capability_reply cp; | ||
2320 | |||
2321 | bacpy(&cp.bdaddr, &ev->bdaddr); | ||
2322 | cp.capability = conn->io_capability; | ||
2323 | cp.oob_data = 0; | ||
2324 | cp.authentication = hci_get_auth_req(conn); | ||
2325 | |||
2326 | hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY, | ||
2327 | sizeof(cp), &cp); | ||
2328 | } else { | ||
2329 | struct hci_cp_io_capability_neg_reply cp; | ||
2330 | |||
2331 | bacpy(&cp.bdaddr, &ev->bdaddr); | ||
2332 | cp.reason = 0x16; /* Pairing not allowed */ | ||
2333 | |||
2334 | hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY, | ||
2335 | sizeof(cp), &cp); | ||
2336 | } | ||
2337 | |||
2338 | unlock: | ||
2339 | hci_dev_unlock(hdev); | ||
2340 | } | ||
2341 | |||
2342 | static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb) | ||
2343 | { | ||
2344 | struct hci_ev_io_capa_reply *ev = (void *) skb->data; | ||
2345 | struct hci_conn *conn; | ||
2346 | |||
2347 | BT_DBG("%s", hdev->name); | ||
2348 | |||
2349 | hci_dev_lock(hdev); | ||
1881 | 2350 | ||
2351 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); | ||
2352 | if (!conn) | ||
2353 | goto unlock; | ||
2354 | |||
2355 | hci_conn_hold(conn); | ||
2356 | |||
2357 | conn->remote_cap = ev->capability; | ||
2358 | conn->remote_oob = ev->oob_data; | ||
2359 | conn->remote_auth = ev->authentication; | ||
2360 | |||
2361 | unlock: | ||
1882 | hci_dev_unlock(hdev); | 2362 | hci_dev_unlock(hdev); |
1883 | } | 2363 | } |
1884 | 2364 | ||
@@ -1914,6 +2394,60 @@ static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_ | |||
1914 | hci_dev_unlock(hdev); | 2394 | hci_dev_unlock(hdev); |
1915 | } | 2395 | } |
1916 | 2396 | ||
2397 | static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | ||
2398 | { | ||
2399 | struct hci_ev_le_conn_complete *ev = (void *) skb->data; | ||
2400 | struct hci_conn *conn; | ||
2401 | |||
2402 | BT_DBG("%s status %d", hdev->name, ev->status); | ||
2403 | |||
2404 | hci_dev_lock(hdev); | ||
2405 | |||
2406 | conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr); | ||
2407 | if (!conn) { | ||
2408 | conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr); | ||
2409 | if (!conn) { | ||
2410 | BT_ERR("No memory for new connection"); | ||
2411 | hci_dev_unlock(hdev); | ||
2412 | return; | ||
2413 | } | ||
2414 | } | ||
2415 | |||
2416 | if (ev->status) { | ||
2417 | hci_proto_connect_cfm(conn, ev->status); | ||
2418 | conn->state = BT_CLOSED; | ||
2419 | hci_conn_del(conn); | ||
2420 | goto unlock; | ||
2421 | } | ||
2422 | |||
2423 | conn->handle = __le16_to_cpu(ev->handle); | ||
2424 | conn->state = BT_CONNECTED; | ||
2425 | |||
2426 | hci_conn_hold_device(conn); | ||
2427 | hci_conn_add_sysfs(conn); | ||
2428 | |||
2429 | hci_proto_connect_cfm(conn, ev->status); | ||
2430 | |||
2431 | unlock: | ||
2432 | hci_dev_unlock(hdev); | ||
2433 | } | ||
2434 | |||
2435 | static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb) | ||
2436 | { | ||
2437 | struct hci_ev_le_meta *le_ev = (void *) skb->data; | ||
2438 | |||
2439 | skb_pull(skb, sizeof(*le_ev)); | ||
2440 | |||
2441 | switch (le_ev->subevent) { | ||
2442 | case HCI_EV_LE_CONN_COMPLETE: | ||
2443 | hci_le_conn_complete_evt(hdev, skb); | ||
2444 | break; | ||
2445 | |||
2446 | default: | ||
2447 | break; | ||
2448 | } | ||
2449 | } | ||
2450 | |||
1917 | void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | 2451 | void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) |
1918 | { | 2452 | { |
1919 | struct hci_event_hdr *hdr = (void *) skb->data; | 2453 | struct hci_event_hdr *hdr = (void *) skb->data; |
@@ -2042,6 +2576,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
2042 | hci_io_capa_request_evt(hdev, skb); | 2576 | hci_io_capa_request_evt(hdev, skb); |
2043 | break; | 2577 | break; |
2044 | 2578 | ||
2579 | case HCI_EV_IO_CAPA_REPLY: | ||
2580 | hci_io_capa_reply_evt(hdev, skb); | ||
2581 | break; | ||
2582 | |||
2045 | case HCI_EV_SIMPLE_PAIR_COMPLETE: | 2583 | case HCI_EV_SIMPLE_PAIR_COMPLETE: |
2046 | hci_simple_pair_complete_evt(hdev, skb); | 2584 | hci_simple_pair_complete_evt(hdev, skb); |
2047 | break; | 2585 | break; |
@@ -2050,6 +2588,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
2050 | hci_remote_host_features_evt(hdev, skb); | 2588 | hci_remote_host_features_evt(hdev, skb); |
2051 | break; | 2589 | break; |
2052 | 2590 | ||
2591 | case HCI_EV_LE_META: | ||
2592 | hci_le_meta_evt(hdev, skb); | ||
2593 | break; | ||
2594 | |||
2053 | default: | 2595 | default: |
2054 | BT_DBG("%s event 0x%x", hdev->name, event); | 2596 | BT_DBG("%s event 0x%x", hdev->name, event); |
2055 | break; | 2597 | break; |
@@ -2083,6 +2625,6 @@ void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data) | |||
2083 | 2625 | ||
2084 | bt_cb(skb)->pkt_type = HCI_EVENT_PKT; | 2626 | bt_cb(skb)->pkt_type = HCI_EVENT_PKT; |
2085 | skb->dev = (void *) hdev; | 2627 | skb->dev = (void *) hdev; |
2086 | hci_send_to_sock(hdev, skb); | 2628 | hci_send_to_sock(hdev, skb, NULL); |
2087 | kfree_skb(skb); | 2629 | kfree_skb(skb); |
2088 | } | 2630 | } |
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 29827c77f6ce..d50e96136608 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c | |||
@@ -85,7 +85,8 @@ static struct bt_sock_list hci_sk_list = { | |||
85 | }; | 85 | }; |
86 | 86 | ||
87 | /* Send frame to RAW socket */ | 87 | /* Send frame to RAW socket */ |
88 | void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb) | 88 | void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb, |
89 | struct sock *skip_sk) | ||
89 | { | 90 | { |
90 | struct sock *sk; | 91 | struct sock *sk; |
91 | struct hlist_node *node; | 92 | struct hlist_node *node; |
@@ -97,6 +98,9 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb) | |||
97 | struct hci_filter *flt; | 98 | struct hci_filter *flt; |
98 | struct sk_buff *nskb; | 99 | struct sk_buff *nskb; |
99 | 100 | ||
101 | if (sk == skip_sk) | ||
102 | continue; | ||
103 | |||
100 | if (sk->sk_state != BT_BOUND || hci_pi(sk)->hdev != hdev) | 104 | if (sk->sk_state != BT_BOUND || hci_pi(sk)->hdev != hdev) |
101 | continue; | 105 | continue; |
102 | 106 | ||
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c index 5fce3d6d07b4..3c838a65a75a 100644 --- a/net/bluetooth/hci_sysfs.c +++ b/net/bluetooth/hci_sysfs.c | |||
@@ -11,7 +11,7 @@ | |||
11 | 11 | ||
12 | static struct class *bt_class; | 12 | static struct class *bt_class; |
13 | 13 | ||
14 | struct dentry *bt_debugfs = NULL; | 14 | struct dentry *bt_debugfs; |
15 | EXPORT_SYMBOL_GPL(bt_debugfs); | 15 | EXPORT_SYMBOL_GPL(bt_debugfs); |
16 | 16 | ||
17 | static inline char *link_typetostr(int type) | 17 | static inline char *link_typetostr(int type) |
@@ -51,8 +51,8 @@ static ssize_t show_link_features(struct device *dev, struct device_attribute *a | |||
51 | conn->features[6], conn->features[7]); | 51 | conn->features[6], conn->features[7]); |
52 | } | 52 | } |
53 | 53 | ||
54 | #define LINK_ATTR(_name,_mode,_show,_store) \ | 54 | #define LINK_ATTR(_name, _mode, _show, _store) \ |
55 | struct device_attribute link_attr_##_name = __ATTR(_name,_mode,_show,_store) | 55 | struct device_attribute link_attr_##_name = __ATTR(_name, _mode, _show, _store) |
56 | 56 | ||
57 | static LINK_ATTR(type, S_IRUGO, show_link_type, NULL); | 57 | static LINK_ATTR(type, S_IRUGO, show_link_type, NULL); |
58 | static LINK_ATTR(address, S_IRUGO, show_link_address, NULL); | 58 | static LINK_ATTR(address, S_IRUGO, show_link_address, NULL); |
@@ -461,6 +461,56 @@ static const struct file_operations blacklist_fops = { | |||
461 | .llseek = seq_lseek, | 461 | .llseek = seq_lseek, |
462 | .release = single_release, | 462 | .release = single_release, |
463 | }; | 463 | }; |
464 | |||
465 | static void print_bt_uuid(struct seq_file *f, u8 *uuid) | ||
466 | { | ||
467 | u32 data0, data4; | ||
468 | u16 data1, data2, data3, data5; | ||
469 | |||
470 | memcpy(&data0, &uuid[0], 4); | ||
471 | memcpy(&data1, &uuid[4], 2); | ||
472 | memcpy(&data2, &uuid[6], 2); | ||
473 | memcpy(&data3, &uuid[8], 2); | ||
474 | memcpy(&data4, &uuid[10], 4); | ||
475 | memcpy(&data5, &uuid[14], 2); | ||
476 | |||
477 | seq_printf(f, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x\n", | ||
478 | ntohl(data0), ntohs(data1), ntohs(data2), | ||
479 | ntohs(data3), ntohl(data4), ntohs(data5)); | ||
480 | } | ||
481 | |||
482 | static int uuids_show(struct seq_file *f, void *p) | ||
483 | { | ||
484 | struct hci_dev *hdev = f->private; | ||
485 | struct list_head *l; | ||
486 | |||
487 | hci_dev_lock_bh(hdev); | ||
488 | |||
489 | list_for_each(l, &hdev->uuids) { | ||
490 | struct bt_uuid *uuid; | ||
491 | |||
492 | uuid = list_entry(l, struct bt_uuid, list); | ||
493 | |||
494 | print_bt_uuid(f, uuid->uuid); | ||
495 | } | ||
496 | |||
497 | hci_dev_unlock_bh(hdev); | ||
498 | |||
499 | return 0; | ||
500 | } | ||
501 | |||
502 | static int uuids_open(struct inode *inode, struct file *file) | ||
503 | { | ||
504 | return single_open(file, uuids_show, inode->i_private); | ||
505 | } | ||
506 | |||
507 | static const struct file_operations uuids_fops = { | ||
508 | .open = uuids_open, | ||
509 | .read = seq_read, | ||
510 | .llseek = seq_lseek, | ||
511 | .release = single_release, | ||
512 | }; | ||
513 | |||
464 | int hci_register_sysfs(struct hci_dev *hdev) | 514 | int hci_register_sysfs(struct hci_dev *hdev) |
465 | { | 515 | { |
466 | struct device *dev = &hdev->dev; | 516 | struct device *dev = &hdev->dev; |
@@ -493,6 +543,8 @@ int hci_register_sysfs(struct hci_dev *hdev) | |||
493 | debugfs_create_file("blacklist", 0444, hdev->debugfs, | 543 | debugfs_create_file("blacklist", 0444, hdev->debugfs, |
494 | hdev, &blacklist_fops); | 544 | hdev, &blacklist_fops); |
495 | 545 | ||
546 | debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops); | ||
547 | |||
496 | return 0; | 548 | return 0; |
497 | } | 549 | } |
498 | 550 | ||
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 29544c21f4b5..2429ca2d7b06 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
@@ -157,7 +157,8 @@ static int hidp_queue_event(struct hidp_session *session, struct input_dev *dev, | |||
157 | 157 | ||
158 | session->leds = newleds; | 158 | session->leds = newleds; |
159 | 159 | ||
160 | if (!(skb = alloc_skb(3, GFP_ATOMIC))) { | 160 | skb = alloc_skb(3, GFP_ATOMIC); |
161 | if (!skb) { | ||
161 | BT_ERR("Can't allocate memory for new frame"); | 162 | BT_ERR("Can't allocate memory for new frame"); |
162 | return -ENOMEM; | 163 | return -ENOMEM; |
163 | } | 164 | } |
@@ -250,7 +251,8 @@ static int __hidp_send_ctrl_message(struct hidp_session *session, | |||
250 | 251 | ||
251 | BT_DBG("session %p data %p size %d", session, data, size); | 252 | BT_DBG("session %p data %p size %d", session, data, size); |
252 | 253 | ||
253 | if (!(skb = alloc_skb(size + 1, GFP_ATOMIC))) { | 254 | skb = alloc_skb(size + 1, GFP_ATOMIC); |
255 | if (!skb) { | ||
254 | BT_ERR("Can't allocate memory for new frame"); | 256 | BT_ERR("Can't allocate memory for new frame"); |
255 | return -ENOMEM; | 257 | return -ENOMEM; |
256 | } | 258 | } |
@@ -283,7 +285,8 @@ static int hidp_queue_report(struct hidp_session *session, | |||
283 | 285 | ||
284 | BT_DBG("session %p hid %p data %p size %d", session, session->hid, data, size); | 286 | BT_DBG("session %p hid %p data %p size %d", session, session->hid, data, size); |
285 | 287 | ||
286 | if (!(skb = alloc_skb(size + 1, GFP_ATOMIC))) { | 288 | skb = alloc_skb(size + 1, GFP_ATOMIC); |
289 | if (!skb) { | ||
287 | BT_ERR("Can't allocate memory for new frame"); | 290 | BT_ERR("Can't allocate memory for new frame"); |
288 | return -ENOMEM; | 291 | return -ENOMEM; |
289 | } | 292 | } |
@@ -1016,8 +1019,6 @@ static int __init hidp_init(void) | |||
1016 | { | 1019 | { |
1017 | int ret; | 1020 | int ret; |
1018 | 1021 | ||
1019 | l2cap_load(); | ||
1020 | |||
1021 | BT_INFO("HIDP (Human Interface Emulation) ver %s", VERSION); | 1022 | BT_INFO("HIDP (Human Interface Emulation) ver %s", VERSION); |
1022 | 1023 | ||
1023 | ret = hid_register_driver(&hidp_driver); | 1024 | ret = hid_register_driver(&hidp_driver); |
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap_core.c index 675614e38e14..efcef0dc1259 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -24,7 +24,7 @@ | |||
24 | SOFTWARE IS DISCLAIMED. | 24 | SOFTWARE IS DISCLAIMED. |
25 | */ | 25 | */ |
26 | 26 | ||
27 | /* Bluetooth L2CAP core and sockets. */ | 27 | /* Bluetooth L2CAP core. */ |
28 | 28 | ||
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | 30 | ||
@@ -55,79 +55,24 @@ | |||
55 | #include <net/bluetooth/hci_core.h> | 55 | #include <net/bluetooth/hci_core.h> |
56 | #include <net/bluetooth/l2cap.h> | 56 | #include <net/bluetooth/l2cap.h> |
57 | 57 | ||
58 | #define VERSION "2.15" | 58 | int disable_ertm; |
59 | |||
60 | static int disable_ertm; | ||
61 | 59 | ||
62 | static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN; | 60 | static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN; |
63 | static u8 l2cap_fixed_chan[8] = { 0x02, }; | 61 | static u8 l2cap_fixed_chan[8] = { 0x02, }; |
64 | 62 | ||
65 | static const struct proto_ops l2cap_sock_ops; | ||
66 | |||
67 | static struct workqueue_struct *_busy_wq; | 63 | static struct workqueue_struct *_busy_wq; |
68 | 64 | ||
69 | static struct bt_sock_list l2cap_sk_list = { | 65 | struct bt_sock_list l2cap_sk_list = { |
70 | .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock) | 66 | .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock) |
71 | }; | 67 | }; |
72 | 68 | ||
73 | static void l2cap_busy_work(struct work_struct *work); | 69 | static void l2cap_busy_work(struct work_struct *work); |
74 | 70 | ||
75 | static void __l2cap_sock_close(struct sock *sk, int reason); | ||
76 | static void l2cap_sock_close(struct sock *sk); | ||
77 | static void l2cap_sock_kill(struct sock *sk); | ||
78 | |||
79 | static int l2cap_build_conf_req(struct sock *sk, void *data); | ||
80 | static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, | 71 | static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, |
81 | u8 code, u8 ident, u16 dlen, void *data); | 72 | u8 code, u8 ident, u16 dlen, void *data); |
82 | 73 | ||
83 | static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb); | 74 | static int l2cap_ertm_data_rcv(struct sock *sk, struct sk_buff *skb); |
84 | 75 | ||
85 | /* ---- L2CAP timers ---- */ | ||
86 | static void l2cap_sock_set_timer(struct sock *sk, long timeout) | ||
87 | { | ||
88 | BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout); | ||
89 | sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout); | ||
90 | } | ||
91 | |||
92 | static void l2cap_sock_clear_timer(struct sock *sk) | ||
93 | { | ||
94 | BT_DBG("sock %p state %d", sk, sk->sk_state); | ||
95 | sk_stop_timer(sk, &sk->sk_timer); | ||
96 | } | ||
97 | |||
98 | static void l2cap_sock_timeout(unsigned long arg) | ||
99 | { | ||
100 | struct sock *sk = (struct sock *) arg; | ||
101 | int reason; | ||
102 | |||
103 | BT_DBG("sock %p state %d", sk, sk->sk_state); | ||
104 | |||
105 | bh_lock_sock(sk); | ||
106 | |||
107 | if (sock_owned_by_user(sk)) { | ||
108 | /* sk is owned by user. Try again later */ | ||
109 | l2cap_sock_set_timer(sk, HZ / 5); | ||
110 | bh_unlock_sock(sk); | ||
111 | sock_put(sk); | ||
112 | return; | ||
113 | } | ||
114 | |||
115 | if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG) | ||
116 | reason = ECONNREFUSED; | ||
117 | else if (sk->sk_state == BT_CONNECT && | ||
118 | l2cap_pi(sk)->sec_level != BT_SECURITY_SDP) | ||
119 | reason = ECONNREFUSED; | ||
120 | else | ||
121 | reason = ETIMEDOUT; | ||
122 | |||
123 | __l2cap_sock_close(sk, reason); | ||
124 | |||
125 | bh_unlock_sock(sk); | ||
126 | |||
127 | l2cap_sock_kill(sk); | ||
128 | sock_put(sk); | ||
129 | } | ||
130 | |||
131 | /* ---- L2CAP channels ---- */ | 76 | /* ---- L2CAP channels ---- */ |
132 | static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid) | 77 | static struct sock *__l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, u16 cid) |
133 | { | 78 | { |
@@ -236,8 +181,16 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct so | |||
236 | l2cap_pi(sk)->conn = conn; | 181 | l2cap_pi(sk)->conn = conn; |
237 | 182 | ||
238 | if (sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) { | 183 | if (sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) { |
239 | /* Alloc CID for connection-oriented socket */ | 184 | if (conn->hcon->type == LE_LINK) { |
240 | l2cap_pi(sk)->scid = l2cap_alloc_cid(l); | 185 | /* LE connection */ |
186 | l2cap_pi(sk)->omtu = L2CAP_LE_DEFAULT_MTU; | ||
187 | l2cap_pi(sk)->scid = L2CAP_CID_LE_DATA; | ||
188 | l2cap_pi(sk)->dcid = L2CAP_CID_LE_DATA; | ||
189 | } else { | ||
190 | /* Alloc CID for connection-oriented socket */ | ||
191 | l2cap_pi(sk)->scid = l2cap_alloc_cid(l); | ||
192 | l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU; | ||
193 | } | ||
241 | } else if (sk->sk_type == SOCK_DGRAM) { | 194 | } else if (sk->sk_type == SOCK_DGRAM) { |
242 | /* Connectionless socket */ | 195 | /* Connectionless socket */ |
243 | l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS; | 196 | l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS; |
@@ -258,7 +211,7 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct so | |||
258 | 211 | ||
259 | /* Delete channel. | 212 | /* Delete channel. |
260 | * Must be called on the locked socket. */ | 213 | * Must be called on the locked socket. */ |
261 | static void l2cap_chan_del(struct sock *sk, int err) | 214 | void l2cap_chan_del(struct sock *sk, int err) |
262 | { | 215 | { |
263 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | 216 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; |
264 | struct sock *parent = bt_sk(sk)->parent; | 217 | struct sock *parent = bt_sk(sk)->parent; |
@@ -348,7 +301,7 @@ static inline int l2cap_check_security(struct sock *sk) | |||
348 | auth_type); | 301 | auth_type); |
349 | } | 302 | } |
350 | 303 | ||
351 | static inline u8 l2cap_get_ident(struct l2cap_conn *conn) | 304 | u8 l2cap_get_ident(struct l2cap_conn *conn) |
352 | { | 305 | { |
353 | u8 id; | 306 | u8 id; |
354 | 307 | ||
@@ -370,16 +323,22 @@ static inline u8 l2cap_get_ident(struct l2cap_conn *conn) | |||
370 | return id; | 323 | return id; |
371 | } | 324 | } |
372 | 325 | ||
373 | static inline void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data) | 326 | void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data) |
374 | { | 327 | { |
375 | struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data); | 328 | struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data); |
329 | u8 flags; | ||
376 | 330 | ||
377 | BT_DBG("code 0x%2.2x", code); | 331 | BT_DBG("code 0x%2.2x", code); |
378 | 332 | ||
379 | if (!skb) | 333 | if (!skb) |
380 | return; | 334 | return; |
381 | 335 | ||
382 | hci_send_acl(conn->hcon, skb, 0); | 336 | if (lmp_no_flush_capable(conn->hcon->hdev)) |
337 | flags = ACL_START_NO_FLUSH; | ||
338 | else | ||
339 | flags = ACL_START; | ||
340 | |||
341 | hci_send_acl(conn->hcon, skb, flags); | ||
383 | } | 342 | } |
384 | 343 | ||
385 | static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control) | 344 | static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control) |
@@ -389,6 +348,7 @@ static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control) | |||
389 | struct l2cap_conn *conn = pi->conn; | 348 | struct l2cap_conn *conn = pi->conn; |
390 | struct sock *sk = (struct sock *)pi; | 349 | struct sock *sk = (struct sock *)pi; |
391 | int count, hlen = L2CAP_HDR_SIZE + 2; | 350 | int count, hlen = L2CAP_HDR_SIZE + 2; |
351 | u8 flags; | ||
392 | 352 | ||
393 | if (sk->sk_state != BT_CONNECTED) | 353 | if (sk->sk_state != BT_CONNECTED) |
394 | return; | 354 | return; |
@@ -425,7 +385,12 @@ static inline void l2cap_send_sframe(struct l2cap_pinfo *pi, u16 control) | |||
425 | put_unaligned_le16(fcs, skb_put(skb, 2)); | 385 | put_unaligned_le16(fcs, skb_put(skb, 2)); |
426 | } | 386 | } |
427 | 387 | ||
428 | hci_send_acl(pi->conn->hcon, skb, 0); | 388 | if (lmp_no_flush_capable(conn->hcon->hdev)) |
389 | flags = ACL_START_NO_FLUSH; | ||
390 | else | ||
391 | flags = ACL_START; | ||
392 | |||
393 | hci_send_acl(pi->conn->hcon, skb, flags); | ||
429 | } | 394 | } |
430 | 395 | ||
431 | static inline void l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control) | 396 | static inline void l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control) |
@@ -496,7 +461,7 @@ static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask) | |||
496 | } | 461 | } |
497 | } | 462 | } |
498 | 463 | ||
499 | static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err) | 464 | void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err) |
500 | { | 465 | { |
501 | struct l2cap_disconn_req req; | 466 | struct l2cap_disconn_req req; |
502 | 467 | ||
@@ -624,6 +589,82 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
624 | } | 589 | } |
625 | } | 590 | } |
626 | 591 | ||
592 | /* Find socket with cid and source bdaddr. | ||
593 | * Returns closest match, locked. | ||
594 | */ | ||
595 | static struct sock *l2cap_get_sock_by_scid(int state, __le16 cid, bdaddr_t *src) | ||
596 | { | ||
597 | struct sock *s, *sk = NULL, *sk1 = NULL; | ||
598 | struct hlist_node *node; | ||
599 | |||
600 | read_lock(&l2cap_sk_list.lock); | ||
601 | |||
602 | sk_for_each(sk, node, &l2cap_sk_list.head) { | ||
603 | if (state && sk->sk_state != state) | ||
604 | continue; | ||
605 | |||
606 | if (l2cap_pi(sk)->scid == cid) { | ||
607 | /* Exact match. */ | ||
608 | if (!bacmp(&bt_sk(sk)->src, src)) | ||
609 | break; | ||
610 | |||
611 | /* Closest match */ | ||
612 | if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) | ||
613 | sk1 = sk; | ||
614 | } | ||
615 | } | ||
616 | s = node ? sk : sk1; | ||
617 | if (s) | ||
618 | bh_lock_sock(s); | ||
619 | read_unlock(&l2cap_sk_list.lock); | ||
620 | |||
621 | return s; | ||
622 | } | ||
623 | |||
624 | static void l2cap_le_conn_ready(struct l2cap_conn *conn) | ||
625 | { | ||
626 | struct l2cap_chan_list *list = &conn->chan_list; | ||
627 | struct sock *parent, *uninitialized_var(sk); | ||
628 | |||
629 | BT_DBG(""); | ||
630 | |||
631 | /* Check if we have socket listening on cid */ | ||
632 | parent = l2cap_get_sock_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA, | ||
633 | conn->src); | ||
634 | if (!parent) | ||
635 | return; | ||
636 | |||
637 | /* Check for backlog size */ | ||
638 | if (sk_acceptq_is_full(parent)) { | ||
639 | BT_DBG("backlog full %d", parent->sk_ack_backlog); | ||
640 | goto clean; | ||
641 | } | ||
642 | |||
643 | sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC); | ||
644 | if (!sk) | ||
645 | goto clean; | ||
646 | |||
647 | write_lock_bh(&list->lock); | ||
648 | |||
649 | hci_conn_hold(conn->hcon); | ||
650 | |||
651 | l2cap_sock_init(sk, parent); | ||
652 | bacpy(&bt_sk(sk)->src, conn->src); | ||
653 | bacpy(&bt_sk(sk)->dst, conn->dst); | ||
654 | |||
655 | __l2cap_chan_add(conn, sk, parent); | ||
656 | |||
657 | l2cap_sock_set_timer(sk, sk->sk_sndtimeo); | ||
658 | |||
659 | sk->sk_state = BT_CONNECTED; | ||
660 | parent->sk_data_ready(parent, 0); | ||
661 | |||
662 | write_unlock_bh(&list->lock); | ||
663 | |||
664 | clean: | ||
665 | bh_unlock_sock(parent); | ||
666 | } | ||
667 | |||
627 | static void l2cap_conn_ready(struct l2cap_conn *conn) | 668 | static void l2cap_conn_ready(struct l2cap_conn *conn) |
628 | { | 669 | { |
629 | struct l2cap_chan_list *l = &conn->chan_list; | 670 | struct l2cap_chan_list *l = &conn->chan_list; |
@@ -631,11 +672,20 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) | |||
631 | 672 | ||
632 | BT_DBG("conn %p", conn); | 673 | BT_DBG("conn %p", conn); |
633 | 674 | ||
675 | if (!conn->hcon->out && conn->hcon->type == LE_LINK) | ||
676 | l2cap_le_conn_ready(conn); | ||
677 | |||
634 | read_lock(&l->lock); | 678 | read_lock(&l->lock); |
635 | 679 | ||
636 | for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { | 680 | for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { |
637 | bh_lock_sock(sk); | 681 | bh_lock_sock(sk); |
638 | 682 | ||
683 | if (conn->hcon->type == LE_LINK) { | ||
684 | l2cap_sock_clear_timer(sk); | ||
685 | sk->sk_state = BT_CONNECTED; | ||
686 | sk->sk_state_change(sk); | ||
687 | } | ||
688 | |||
639 | if (sk->sk_type != SOCK_SEQPACKET && | 689 | if (sk->sk_type != SOCK_SEQPACKET && |
640 | sk->sk_type != SOCK_STREAM) { | 690 | sk->sk_type != SOCK_STREAM) { |
641 | l2cap_sock_clear_timer(sk); | 691 | l2cap_sock_clear_timer(sk); |
@@ -694,7 +744,11 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) | |||
694 | 744 | ||
695 | BT_DBG("hcon %p conn %p", hcon, conn); | 745 | BT_DBG("hcon %p conn %p", hcon, conn); |
696 | 746 | ||
697 | conn->mtu = hcon->hdev->acl_mtu; | 747 | if (hcon->hdev->le_mtu && hcon->type == LE_LINK) |
748 | conn->mtu = hcon->hdev->le_mtu; | ||
749 | else | ||
750 | conn->mtu = hcon->hdev->acl_mtu; | ||
751 | |||
698 | conn->src = &hcon->hdev->bdaddr; | 752 | conn->src = &hcon->hdev->bdaddr; |
699 | conn->dst = &hcon->dst; | 753 | conn->dst = &hcon->dst; |
700 | 754 | ||
@@ -703,7 +757,8 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) | |||
703 | spin_lock_init(&conn->lock); | 757 | spin_lock_init(&conn->lock); |
704 | rwlock_init(&conn->chan_list.lock); | 758 | rwlock_init(&conn->chan_list.lock); |
705 | 759 | ||
706 | setup_timer(&conn->info_timer, l2cap_info_timeout, | 760 | if (hcon->type != LE_LINK) |
761 | setup_timer(&conn->info_timer, l2cap_info_timeout, | ||
707 | (unsigned long) conn); | 762 | (unsigned long) conn); |
708 | 763 | ||
709 | conn->disc_reason = 0x13; | 764 | conn->disc_reason = 0x13; |
@@ -747,17 +802,6 @@ static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, stru | |||
747 | } | 802 | } |
748 | 803 | ||
749 | /* ---- Socket interface ---- */ | 804 | /* ---- Socket interface ---- */ |
750 | static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src) | ||
751 | { | ||
752 | struct sock *sk; | ||
753 | struct hlist_node *node; | ||
754 | sk_for_each(sk, node, &l2cap_sk_list.head) | ||
755 | if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src)) | ||
756 | goto found; | ||
757 | sk = NULL; | ||
758 | found: | ||
759 | return sk; | ||
760 | } | ||
761 | 805 | ||
762 | /* Find socket with psm and source bdaddr. | 806 | /* Find socket with psm and source bdaddr. |
763 | * Returns closest match. | 807 | * Returns closest match. |
@@ -789,277 +833,7 @@ static struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src) | |||
789 | return node ? sk : sk1; | 833 | return node ? sk : sk1; |
790 | } | 834 | } |
791 | 835 | ||
792 | static void l2cap_sock_destruct(struct sock *sk) | 836 | int l2cap_do_connect(struct sock *sk) |
793 | { | ||
794 | BT_DBG("sk %p", sk); | ||
795 | |||
796 | skb_queue_purge(&sk->sk_receive_queue); | ||
797 | skb_queue_purge(&sk->sk_write_queue); | ||
798 | } | ||
799 | |||
800 | static void l2cap_sock_cleanup_listen(struct sock *parent) | ||
801 | { | ||
802 | struct sock *sk; | ||
803 | |||
804 | BT_DBG("parent %p", parent); | ||
805 | |||
806 | /* Close not yet accepted channels */ | ||
807 | while ((sk = bt_accept_dequeue(parent, NULL))) | ||
808 | l2cap_sock_close(sk); | ||
809 | |||
810 | parent->sk_state = BT_CLOSED; | ||
811 | sock_set_flag(parent, SOCK_ZAPPED); | ||
812 | } | ||
813 | |||
814 | /* Kill socket (only if zapped and orphan) | ||
815 | * Must be called on unlocked socket. | ||
816 | */ | ||
817 | static void l2cap_sock_kill(struct sock *sk) | ||
818 | { | ||
819 | if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) | ||
820 | return; | ||
821 | |||
822 | BT_DBG("sk %p state %d", sk, sk->sk_state); | ||
823 | |||
824 | /* Kill poor orphan */ | ||
825 | bt_sock_unlink(&l2cap_sk_list, sk); | ||
826 | sock_set_flag(sk, SOCK_DEAD); | ||
827 | sock_put(sk); | ||
828 | } | ||
829 | |||
830 | static void __l2cap_sock_close(struct sock *sk, int reason) | ||
831 | { | ||
832 | BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket); | ||
833 | |||
834 | switch (sk->sk_state) { | ||
835 | case BT_LISTEN: | ||
836 | l2cap_sock_cleanup_listen(sk); | ||
837 | break; | ||
838 | |||
839 | case BT_CONNECTED: | ||
840 | case BT_CONFIG: | ||
841 | if (sk->sk_type == SOCK_SEQPACKET || | ||
842 | sk->sk_type == SOCK_STREAM) { | ||
843 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | ||
844 | |||
845 | l2cap_sock_set_timer(sk, sk->sk_sndtimeo); | ||
846 | l2cap_send_disconn_req(conn, sk, reason); | ||
847 | } else | ||
848 | l2cap_chan_del(sk, reason); | ||
849 | break; | ||
850 | |||
851 | case BT_CONNECT2: | ||
852 | if (sk->sk_type == SOCK_SEQPACKET || | ||
853 | sk->sk_type == SOCK_STREAM) { | ||
854 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | ||
855 | struct l2cap_conn_rsp rsp; | ||
856 | __u16 result; | ||
857 | |||
858 | if (bt_sk(sk)->defer_setup) | ||
859 | result = L2CAP_CR_SEC_BLOCK; | ||
860 | else | ||
861 | result = L2CAP_CR_BAD_PSM; | ||
862 | sk->sk_state = BT_DISCONN; | ||
863 | |||
864 | rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); | ||
865 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); | ||
866 | rsp.result = cpu_to_le16(result); | ||
867 | rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); | ||
868 | l2cap_send_cmd(conn, l2cap_pi(sk)->ident, | ||
869 | L2CAP_CONN_RSP, sizeof(rsp), &rsp); | ||
870 | } else | ||
871 | l2cap_chan_del(sk, reason); | ||
872 | break; | ||
873 | |||
874 | case BT_CONNECT: | ||
875 | case BT_DISCONN: | ||
876 | l2cap_chan_del(sk, reason); | ||
877 | break; | ||
878 | |||
879 | default: | ||
880 | sock_set_flag(sk, SOCK_ZAPPED); | ||
881 | break; | ||
882 | } | ||
883 | } | ||
884 | |||
885 | /* Must be called on unlocked socket. */ | ||
886 | static void l2cap_sock_close(struct sock *sk) | ||
887 | { | ||
888 | l2cap_sock_clear_timer(sk); | ||
889 | lock_sock(sk); | ||
890 | __l2cap_sock_close(sk, ECONNRESET); | ||
891 | release_sock(sk); | ||
892 | l2cap_sock_kill(sk); | ||
893 | } | ||
894 | |||
895 | static void l2cap_sock_init(struct sock *sk, struct sock *parent) | ||
896 | { | ||
897 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
898 | |||
899 | BT_DBG("sk %p", sk); | ||
900 | |||
901 | if (parent) { | ||
902 | sk->sk_type = parent->sk_type; | ||
903 | bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup; | ||
904 | |||
905 | pi->imtu = l2cap_pi(parent)->imtu; | ||
906 | pi->omtu = l2cap_pi(parent)->omtu; | ||
907 | pi->conf_state = l2cap_pi(parent)->conf_state; | ||
908 | pi->mode = l2cap_pi(parent)->mode; | ||
909 | pi->fcs = l2cap_pi(parent)->fcs; | ||
910 | pi->max_tx = l2cap_pi(parent)->max_tx; | ||
911 | pi->tx_win = l2cap_pi(parent)->tx_win; | ||
912 | pi->sec_level = l2cap_pi(parent)->sec_level; | ||
913 | pi->role_switch = l2cap_pi(parent)->role_switch; | ||
914 | pi->force_reliable = l2cap_pi(parent)->force_reliable; | ||
915 | } else { | ||
916 | pi->imtu = L2CAP_DEFAULT_MTU; | ||
917 | pi->omtu = 0; | ||
918 | if (!disable_ertm && sk->sk_type == SOCK_STREAM) { | ||
919 | pi->mode = L2CAP_MODE_ERTM; | ||
920 | pi->conf_state |= L2CAP_CONF_STATE2_DEVICE; | ||
921 | } else { | ||
922 | pi->mode = L2CAP_MODE_BASIC; | ||
923 | } | ||
924 | pi->max_tx = L2CAP_DEFAULT_MAX_TX; | ||
925 | pi->fcs = L2CAP_FCS_CRC16; | ||
926 | pi->tx_win = L2CAP_DEFAULT_TX_WINDOW; | ||
927 | pi->sec_level = BT_SECURITY_LOW; | ||
928 | pi->role_switch = 0; | ||
929 | pi->force_reliable = 0; | ||
930 | } | ||
931 | |||
932 | /* Default config options */ | ||
933 | pi->conf_len = 0; | ||
934 | pi->flush_to = L2CAP_DEFAULT_FLUSH_TO; | ||
935 | skb_queue_head_init(TX_QUEUE(sk)); | ||
936 | skb_queue_head_init(SREJ_QUEUE(sk)); | ||
937 | skb_queue_head_init(BUSY_QUEUE(sk)); | ||
938 | INIT_LIST_HEAD(SREJ_LIST(sk)); | ||
939 | } | ||
940 | |||
941 | static struct proto l2cap_proto = { | ||
942 | .name = "L2CAP", | ||
943 | .owner = THIS_MODULE, | ||
944 | .obj_size = sizeof(struct l2cap_pinfo) | ||
945 | }; | ||
946 | |||
947 | static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio) | ||
948 | { | ||
949 | struct sock *sk; | ||
950 | |||
951 | sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto); | ||
952 | if (!sk) | ||
953 | return NULL; | ||
954 | |||
955 | sock_init_data(sock, sk); | ||
956 | INIT_LIST_HEAD(&bt_sk(sk)->accept_q); | ||
957 | |||
958 | sk->sk_destruct = l2cap_sock_destruct; | ||
959 | sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT); | ||
960 | |||
961 | sock_reset_flag(sk, SOCK_ZAPPED); | ||
962 | |||
963 | sk->sk_protocol = proto; | ||
964 | sk->sk_state = BT_OPEN; | ||
965 | |||
966 | setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk); | ||
967 | |||
968 | bt_sock_link(&l2cap_sk_list, sk); | ||
969 | return sk; | ||
970 | } | ||
971 | |||
972 | static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol, | ||
973 | int kern) | ||
974 | { | ||
975 | struct sock *sk; | ||
976 | |||
977 | BT_DBG("sock %p", sock); | ||
978 | |||
979 | sock->state = SS_UNCONNECTED; | ||
980 | |||
981 | if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM && | ||
982 | sock->type != SOCK_DGRAM && sock->type != SOCK_RAW) | ||
983 | return -ESOCKTNOSUPPORT; | ||
984 | |||
985 | if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW)) | ||
986 | return -EPERM; | ||
987 | |||
988 | sock->ops = &l2cap_sock_ops; | ||
989 | |||
990 | sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC); | ||
991 | if (!sk) | ||
992 | return -ENOMEM; | ||
993 | |||
994 | l2cap_sock_init(sk, NULL); | ||
995 | return 0; | ||
996 | } | ||
997 | |||
998 | static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) | ||
999 | { | ||
1000 | struct sock *sk = sock->sk; | ||
1001 | struct sockaddr_l2 la; | ||
1002 | int len, err = 0; | ||
1003 | |||
1004 | BT_DBG("sk %p", sk); | ||
1005 | |||
1006 | if (!addr || addr->sa_family != AF_BLUETOOTH) | ||
1007 | return -EINVAL; | ||
1008 | |||
1009 | memset(&la, 0, sizeof(la)); | ||
1010 | len = min_t(unsigned int, sizeof(la), alen); | ||
1011 | memcpy(&la, addr, len); | ||
1012 | |||
1013 | if (la.l2_cid) | ||
1014 | return -EINVAL; | ||
1015 | |||
1016 | lock_sock(sk); | ||
1017 | |||
1018 | if (sk->sk_state != BT_OPEN) { | ||
1019 | err = -EBADFD; | ||
1020 | goto done; | ||
1021 | } | ||
1022 | |||
1023 | if (la.l2_psm) { | ||
1024 | __u16 psm = __le16_to_cpu(la.l2_psm); | ||
1025 | |||
1026 | /* PSM must be odd and lsb of upper byte must be 0 */ | ||
1027 | if ((psm & 0x0101) != 0x0001) { | ||
1028 | err = -EINVAL; | ||
1029 | goto done; | ||
1030 | } | ||
1031 | |||
1032 | /* Restrict usage of well-known PSMs */ | ||
1033 | if (psm < 0x1001 && !capable(CAP_NET_BIND_SERVICE)) { | ||
1034 | err = -EACCES; | ||
1035 | goto done; | ||
1036 | } | ||
1037 | } | ||
1038 | |||
1039 | write_lock_bh(&l2cap_sk_list.lock); | ||
1040 | |||
1041 | if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) { | ||
1042 | err = -EADDRINUSE; | ||
1043 | } else { | ||
1044 | /* Save source address */ | ||
1045 | bacpy(&bt_sk(sk)->src, &la.l2_bdaddr); | ||
1046 | l2cap_pi(sk)->psm = la.l2_psm; | ||
1047 | l2cap_pi(sk)->sport = la.l2_psm; | ||
1048 | sk->sk_state = BT_BOUND; | ||
1049 | |||
1050 | if (__le16_to_cpu(la.l2_psm) == 0x0001 || | ||
1051 | __le16_to_cpu(la.l2_psm) == 0x0003) | ||
1052 | l2cap_pi(sk)->sec_level = BT_SECURITY_SDP; | ||
1053 | } | ||
1054 | |||
1055 | write_unlock_bh(&l2cap_sk_list.lock); | ||
1056 | |||
1057 | done: | ||
1058 | release_sock(sk); | ||
1059 | return err; | ||
1060 | } | ||
1061 | |||
1062 | static int l2cap_do_connect(struct sock *sk) | ||
1063 | { | 837 | { |
1064 | bdaddr_t *src = &bt_sk(sk)->src; | 838 | bdaddr_t *src = &bt_sk(sk)->src; |
1065 | bdaddr_t *dst = &bt_sk(sk)->dst; | 839 | bdaddr_t *dst = &bt_sk(sk)->dst; |
@@ -1082,8 +856,13 @@ static int l2cap_do_connect(struct sock *sk) | |||
1082 | 856 | ||
1083 | auth_type = l2cap_get_auth_type(sk); | 857 | auth_type = l2cap_get_auth_type(sk); |
1084 | 858 | ||
1085 | hcon = hci_connect(hdev, ACL_LINK, dst, | 859 | if (l2cap_pi(sk)->dcid == L2CAP_CID_LE_DATA) |
860 | hcon = hci_connect(hdev, LE_LINK, dst, | ||
861 | l2cap_pi(sk)->sec_level, auth_type); | ||
862 | else | ||
863 | hcon = hci_connect(hdev, ACL_LINK, dst, | ||
1086 | l2cap_pi(sk)->sec_level, auth_type); | 864 | l2cap_pi(sk)->sec_level, auth_type); |
865 | |||
1087 | if (!hcon) | 866 | if (!hcon) |
1088 | goto done; | 867 | goto done; |
1089 | 868 | ||
@@ -1119,230 +898,7 @@ done: | |||
1119 | return err; | 898 | return err; |
1120 | } | 899 | } |
1121 | 900 | ||
1122 | static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags) | 901 | int __l2cap_wait_ack(struct sock *sk) |
1123 | { | ||
1124 | struct sock *sk = sock->sk; | ||
1125 | struct sockaddr_l2 la; | ||
1126 | int len, err = 0; | ||
1127 | |||
1128 | BT_DBG("sk %p", sk); | ||
1129 | |||
1130 | if (!addr || alen < sizeof(addr->sa_family) || | ||
1131 | addr->sa_family != AF_BLUETOOTH) | ||
1132 | return -EINVAL; | ||
1133 | |||
1134 | memset(&la, 0, sizeof(la)); | ||
1135 | len = min_t(unsigned int, sizeof(la), alen); | ||
1136 | memcpy(&la, addr, len); | ||
1137 | |||
1138 | if (la.l2_cid) | ||
1139 | return -EINVAL; | ||
1140 | |||
1141 | lock_sock(sk); | ||
1142 | |||
1143 | if ((sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) | ||
1144 | && !la.l2_psm) { | ||
1145 | err = -EINVAL; | ||
1146 | goto done; | ||
1147 | } | ||
1148 | |||
1149 | switch (l2cap_pi(sk)->mode) { | ||
1150 | case L2CAP_MODE_BASIC: | ||
1151 | break; | ||
1152 | case L2CAP_MODE_ERTM: | ||
1153 | case L2CAP_MODE_STREAMING: | ||
1154 | if (!disable_ertm) | ||
1155 | break; | ||
1156 | /* fall through */ | ||
1157 | default: | ||
1158 | err = -ENOTSUPP; | ||
1159 | goto done; | ||
1160 | } | ||
1161 | |||
1162 | switch (sk->sk_state) { | ||
1163 | case BT_CONNECT: | ||
1164 | case BT_CONNECT2: | ||
1165 | case BT_CONFIG: | ||
1166 | /* Already connecting */ | ||
1167 | goto wait; | ||
1168 | |||
1169 | case BT_CONNECTED: | ||
1170 | /* Already connected */ | ||
1171 | err = -EISCONN; | ||
1172 | goto done; | ||
1173 | |||
1174 | case BT_OPEN: | ||
1175 | case BT_BOUND: | ||
1176 | /* Can connect */ | ||
1177 | break; | ||
1178 | |||
1179 | default: | ||
1180 | err = -EBADFD; | ||
1181 | goto done; | ||
1182 | } | ||
1183 | |||
1184 | /* PSM must be odd and lsb of upper byte must be 0 */ | ||
1185 | if ((__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001 && | ||
1186 | sk->sk_type != SOCK_RAW) { | ||
1187 | err = -EINVAL; | ||
1188 | goto done; | ||
1189 | } | ||
1190 | |||
1191 | /* Set destination address and psm */ | ||
1192 | bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr); | ||
1193 | l2cap_pi(sk)->psm = la.l2_psm; | ||
1194 | |||
1195 | err = l2cap_do_connect(sk); | ||
1196 | if (err) | ||
1197 | goto done; | ||
1198 | |||
1199 | wait: | ||
1200 | err = bt_sock_wait_state(sk, BT_CONNECTED, | ||
1201 | sock_sndtimeo(sk, flags & O_NONBLOCK)); | ||
1202 | done: | ||
1203 | release_sock(sk); | ||
1204 | return err; | ||
1205 | } | ||
1206 | |||
1207 | static int l2cap_sock_listen(struct socket *sock, int backlog) | ||
1208 | { | ||
1209 | struct sock *sk = sock->sk; | ||
1210 | int err = 0; | ||
1211 | |||
1212 | BT_DBG("sk %p backlog %d", sk, backlog); | ||
1213 | |||
1214 | lock_sock(sk); | ||
1215 | |||
1216 | if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM) | ||
1217 | || sk->sk_state != BT_BOUND) { | ||
1218 | err = -EBADFD; | ||
1219 | goto done; | ||
1220 | } | ||
1221 | |||
1222 | switch (l2cap_pi(sk)->mode) { | ||
1223 | case L2CAP_MODE_BASIC: | ||
1224 | break; | ||
1225 | case L2CAP_MODE_ERTM: | ||
1226 | case L2CAP_MODE_STREAMING: | ||
1227 | if (!disable_ertm) | ||
1228 | break; | ||
1229 | /* fall through */ | ||
1230 | default: | ||
1231 | err = -ENOTSUPP; | ||
1232 | goto done; | ||
1233 | } | ||
1234 | |||
1235 | if (!l2cap_pi(sk)->psm) { | ||
1236 | bdaddr_t *src = &bt_sk(sk)->src; | ||
1237 | u16 psm; | ||
1238 | |||
1239 | err = -EINVAL; | ||
1240 | |||
1241 | write_lock_bh(&l2cap_sk_list.lock); | ||
1242 | |||
1243 | for (psm = 0x1001; psm < 0x1100; psm += 2) | ||
1244 | if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) { | ||
1245 | l2cap_pi(sk)->psm = cpu_to_le16(psm); | ||
1246 | l2cap_pi(sk)->sport = cpu_to_le16(psm); | ||
1247 | err = 0; | ||
1248 | break; | ||
1249 | } | ||
1250 | |||
1251 | write_unlock_bh(&l2cap_sk_list.lock); | ||
1252 | |||
1253 | if (err < 0) | ||
1254 | goto done; | ||
1255 | } | ||
1256 | |||
1257 | sk->sk_max_ack_backlog = backlog; | ||
1258 | sk->sk_ack_backlog = 0; | ||
1259 | sk->sk_state = BT_LISTEN; | ||
1260 | |||
1261 | done: | ||
1262 | release_sock(sk); | ||
1263 | return err; | ||
1264 | } | ||
1265 | |||
1266 | static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags) | ||
1267 | { | ||
1268 | DECLARE_WAITQUEUE(wait, current); | ||
1269 | struct sock *sk = sock->sk, *nsk; | ||
1270 | long timeo; | ||
1271 | int err = 0; | ||
1272 | |||
1273 | lock_sock_nested(sk, SINGLE_DEPTH_NESTING); | ||
1274 | |||
1275 | if (sk->sk_state != BT_LISTEN) { | ||
1276 | err = -EBADFD; | ||
1277 | goto done; | ||
1278 | } | ||
1279 | |||
1280 | timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); | ||
1281 | |||
1282 | BT_DBG("sk %p timeo %ld", sk, timeo); | ||
1283 | |||
1284 | /* Wait for an incoming connection. (wake-one). */ | ||
1285 | add_wait_queue_exclusive(sk_sleep(sk), &wait); | ||
1286 | while (!(nsk = bt_accept_dequeue(sk, newsock))) { | ||
1287 | set_current_state(TASK_INTERRUPTIBLE); | ||
1288 | if (!timeo) { | ||
1289 | err = -EAGAIN; | ||
1290 | break; | ||
1291 | } | ||
1292 | |||
1293 | release_sock(sk); | ||
1294 | timeo = schedule_timeout(timeo); | ||
1295 | lock_sock_nested(sk, SINGLE_DEPTH_NESTING); | ||
1296 | |||
1297 | if (sk->sk_state != BT_LISTEN) { | ||
1298 | err = -EBADFD; | ||
1299 | break; | ||
1300 | } | ||
1301 | |||
1302 | if (signal_pending(current)) { | ||
1303 | err = sock_intr_errno(timeo); | ||
1304 | break; | ||
1305 | } | ||
1306 | } | ||
1307 | set_current_state(TASK_RUNNING); | ||
1308 | remove_wait_queue(sk_sleep(sk), &wait); | ||
1309 | |||
1310 | if (err) | ||
1311 | goto done; | ||
1312 | |||
1313 | newsock->state = SS_CONNECTED; | ||
1314 | |||
1315 | BT_DBG("new socket %p", nsk); | ||
1316 | |||
1317 | done: | ||
1318 | release_sock(sk); | ||
1319 | return err; | ||
1320 | } | ||
1321 | |||
1322 | static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer) | ||
1323 | { | ||
1324 | struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr; | ||
1325 | struct sock *sk = sock->sk; | ||
1326 | |||
1327 | BT_DBG("sock %p, sk %p", sock, sk); | ||
1328 | |||
1329 | addr->sa_family = AF_BLUETOOTH; | ||
1330 | *len = sizeof(struct sockaddr_l2); | ||
1331 | |||
1332 | if (peer) { | ||
1333 | la->l2_psm = l2cap_pi(sk)->psm; | ||
1334 | bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst); | ||
1335 | la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid); | ||
1336 | } else { | ||
1337 | la->l2_psm = l2cap_pi(sk)->sport; | ||
1338 | bacpy(&la->l2_bdaddr, &bt_sk(sk)->src); | ||
1339 | la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid); | ||
1340 | } | ||
1341 | |||
1342 | return 0; | ||
1343 | } | ||
1344 | |||
1345 | static int __l2cap_wait_ack(struct sock *sk) | ||
1346 | { | 902 | { |
1347 | DECLARE_WAITQUEUE(wait, current); | 903 | DECLARE_WAITQUEUE(wait, current); |
1348 | int err = 0; | 904 | int err = 0; |
@@ -1428,16 +984,23 @@ static void l2cap_drop_acked_frames(struct sock *sk) | |||
1428 | del_timer(&l2cap_pi(sk)->retrans_timer); | 984 | del_timer(&l2cap_pi(sk)->retrans_timer); |
1429 | } | 985 | } |
1430 | 986 | ||
1431 | static inline void l2cap_do_send(struct sock *sk, struct sk_buff *skb) | 987 | void l2cap_do_send(struct sock *sk, struct sk_buff *skb) |
1432 | { | 988 | { |
1433 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 989 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
990 | struct hci_conn *hcon = pi->conn->hcon; | ||
991 | u16 flags; | ||
1434 | 992 | ||
1435 | BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len); | 993 | BT_DBG("sk %p, skb %p len %d", sk, skb, skb->len); |
1436 | 994 | ||
1437 | hci_send_acl(pi->conn->hcon, skb, 0); | 995 | if (!pi->flushable && lmp_no_flush_capable(hcon->hdev)) |
996 | flags = ACL_START_NO_FLUSH; | ||
997 | else | ||
998 | flags = ACL_START; | ||
999 | |||
1000 | hci_send_acl(hcon, skb, flags); | ||
1438 | } | 1001 | } |
1439 | 1002 | ||
1440 | static void l2cap_streaming_send(struct sock *sk) | 1003 | void l2cap_streaming_send(struct sock *sk) |
1441 | { | 1004 | { |
1442 | struct sk_buff *skb; | 1005 | struct sk_buff *skb; |
1443 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 1006 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
@@ -1506,7 +1069,7 @@ static void l2cap_retransmit_one_frame(struct sock *sk, u8 tx_seq) | |||
1506 | l2cap_do_send(sk, tx_skb); | 1069 | l2cap_do_send(sk, tx_skb); |
1507 | } | 1070 | } |
1508 | 1071 | ||
1509 | static int l2cap_ertm_send(struct sock *sk) | 1072 | int l2cap_ertm_send(struct sock *sk) |
1510 | { | 1073 | { |
1511 | struct sk_buff *skb, *tx_skb; | 1074 | struct sk_buff *skb, *tx_skb; |
1512 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 1075 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
@@ -1646,7 +1209,7 @@ static inline int l2cap_skbuff_fromiovec(struct sock *sk, struct msghdr *msg, in | |||
1646 | return sent; | 1209 | return sent; |
1647 | } | 1210 | } |
1648 | 1211 | ||
1649 | static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len) | 1212 | struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr *msg, size_t len) |
1650 | { | 1213 | { |
1651 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | 1214 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; |
1652 | struct sk_buff *skb; | 1215 | struct sk_buff *skb; |
@@ -1675,7 +1238,7 @@ static struct sk_buff *l2cap_create_connless_pdu(struct sock *sk, struct msghdr | |||
1675 | return skb; | 1238 | return skb; |
1676 | } | 1239 | } |
1677 | 1240 | ||
1678 | static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len) | 1241 | struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *msg, size_t len) |
1679 | { | 1242 | { |
1680 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | 1243 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; |
1681 | struct sk_buff *skb; | 1244 | struct sk_buff *skb; |
@@ -1703,7 +1266,7 @@ static struct sk_buff *l2cap_create_basic_pdu(struct sock *sk, struct msghdr *ms | |||
1703 | return skb; | 1266 | return skb; |
1704 | } | 1267 | } |
1705 | 1268 | ||
1706 | static struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, size_t len, u16 control, u16 sdulen) | 1269 | struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *msg, size_t len, u16 control, u16 sdulen) |
1707 | { | 1270 | { |
1708 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | 1271 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; |
1709 | struct sk_buff *skb; | 1272 | struct sk_buff *skb; |
@@ -1748,7 +1311,7 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct sock *sk, struct msghdr *m | |||
1748 | return skb; | 1311 | return skb; |
1749 | } | 1312 | } |
1750 | 1313 | ||
1751 | static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len) | 1314 | int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, size_t len) |
1752 | { | 1315 | { |
1753 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 1316 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
1754 | struct sk_buff *skb; | 1317 | struct sk_buff *skb; |
@@ -1794,487 +1357,6 @@ static inline int l2cap_sar_segment_sdu(struct sock *sk, struct msghdr *msg, siz | |||
1794 | return size; | 1357 | return size; |
1795 | } | 1358 | } |
1796 | 1359 | ||
1797 | static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len) | ||
1798 | { | ||
1799 | struct sock *sk = sock->sk; | ||
1800 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
1801 | struct sk_buff *skb; | ||
1802 | u16 control; | ||
1803 | int err; | ||
1804 | |||
1805 | BT_DBG("sock %p, sk %p", sock, sk); | ||
1806 | |||
1807 | err = sock_error(sk); | ||
1808 | if (err) | ||
1809 | return err; | ||
1810 | |||
1811 | if (msg->msg_flags & MSG_OOB) | ||
1812 | return -EOPNOTSUPP; | ||
1813 | |||
1814 | lock_sock(sk); | ||
1815 | |||
1816 | if (sk->sk_state != BT_CONNECTED) { | ||
1817 | err = -ENOTCONN; | ||
1818 | goto done; | ||
1819 | } | ||
1820 | |||
1821 | /* Connectionless channel */ | ||
1822 | if (sk->sk_type == SOCK_DGRAM) { | ||
1823 | skb = l2cap_create_connless_pdu(sk, msg, len); | ||
1824 | if (IS_ERR(skb)) { | ||
1825 | err = PTR_ERR(skb); | ||
1826 | } else { | ||
1827 | l2cap_do_send(sk, skb); | ||
1828 | err = len; | ||
1829 | } | ||
1830 | goto done; | ||
1831 | } | ||
1832 | |||
1833 | switch (pi->mode) { | ||
1834 | case L2CAP_MODE_BASIC: | ||
1835 | /* Check outgoing MTU */ | ||
1836 | if (len > pi->omtu) { | ||
1837 | err = -EMSGSIZE; | ||
1838 | goto done; | ||
1839 | } | ||
1840 | |||
1841 | /* Create a basic PDU */ | ||
1842 | skb = l2cap_create_basic_pdu(sk, msg, len); | ||
1843 | if (IS_ERR(skb)) { | ||
1844 | err = PTR_ERR(skb); | ||
1845 | goto done; | ||
1846 | } | ||
1847 | |||
1848 | l2cap_do_send(sk, skb); | ||
1849 | err = len; | ||
1850 | break; | ||
1851 | |||
1852 | case L2CAP_MODE_ERTM: | ||
1853 | case L2CAP_MODE_STREAMING: | ||
1854 | /* Entire SDU fits into one PDU */ | ||
1855 | if (len <= pi->remote_mps) { | ||
1856 | control = L2CAP_SDU_UNSEGMENTED; | ||
1857 | skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0); | ||
1858 | if (IS_ERR(skb)) { | ||
1859 | err = PTR_ERR(skb); | ||
1860 | goto done; | ||
1861 | } | ||
1862 | __skb_queue_tail(TX_QUEUE(sk), skb); | ||
1863 | |||
1864 | if (sk->sk_send_head == NULL) | ||
1865 | sk->sk_send_head = skb; | ||
1866 | |||
1867 | } else { | ||
1868 | /* Segment SDU into multiples PDUs */ | ||
1869 | err = l2cap_sar_segment_sdu(sk, msg, len); | ||
1870 | if (err < 0) | ||
1871 | goto done; | ||
1872 | } | ||
1873 | |||
1874 | if (pi->mode == L2CAP_MODE_STREAMING) { | ||
1875 | l2cap_streaming_send(sk); | ||
1876 | } else { | ||
1877 | if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) && | ||
1878 | (pi->conn_state & L2CAP_CONN_WAIT_F)) { | ||
1879 | err = len; | ||
1880 | break; | ||
1881 | } | ||
1882 | err = l2cap_ertm_send(sk); | ||
1883 | } | ||
1884 | |||
1885 | if (err >= 0) | ||
1886 | err = len; | ||
1887 | break; | ||
1888 | |||
1889 | default: | ||
1890 | BT_DBG("bad state %1.1x", pi->mode); | ||
1891 | err = -EBADFD; | ||
1892 | } | ||
1893 | |||
1894 | done: | ||
1895 | release_sock(sk); | ||
1896 | return err; | ||
1897 | } | ||
1898 | |||
1899 | static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags) | ||
1900 | { | ||
1901 | struct sock *sk = sock->sk; | ||
1902 | |||
1903 | lock_sock(sk); | ||
1904 | |||
1905 | if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) { | ||
1906 | struct l2cap_conn_rsp rsp; | ||
1907 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | ||
1908 | u8 buf[128]; | ||
1909 | |||
1910 | sk->sk_state = BT_CONFIG; | ||
1911 | |||
1912 | rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); | ||
1913 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); | ||
1914 | rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS); | ||
1915 | rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); | ||
1916 | l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident, | ||
1917 | L2CAP_CONN_RSP, sizeof(rsp), &rsp); | ||
1918 | |||
1919 | if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) { | ||
1920 | release_sock(sk); | ||
1921 | return 0; | ||
1922 | } | ||
1923 | |||
1924 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; | ||
1925 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | ||
1926 | l2cap_build_conf_req(sk, buf), buf); | ||
1927 | l2cap_pi(sk)->num_conf_req++; | ||
1928 | |||
1929 | release_sock(sk); | ||
1930 | return 0; | ||
1931 | } | ||
1932 | |||
1933 | release_sock(sk); | ||
1934 | |||
1935 | if (sock->type == SOCK_STREAM) | ||
1936 | return bt_sock_stream_recvmsg(iocb, sock, msg, len, flags); | ||
1937 | |||
1938 | return bt_sock_recvmsg(iocb, sock, msg, len, flags); | ||
1939 | } | ||
1940 | |||
1941 | static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen) | ||
1942 | { | ||
1943 | struct sock *sk = sock->sk; | ||
1944 | struct l2cap_options opts; | ||
1945 | int len, err = 0; | ||
1946 | u32 opt; | ||
1947 | |||
1948 | BT_DBG("sk %p", sk); | ||
1949 | |||
1950 | lock_sock(sk); | ||
1951 | |||
1952 | switch (optname) { | ||
1953 | case L2CAP_OPTIONS: | ||
1954 | if (sk->sk_state == BT_CONNECTED) { | ||
1955 | err = -EINVAL; | ||
1956 | break; | ||
1957 | } | ||
1958 | |||
1959 | opts.imtu = l2cap_pi(sk)->imtu; | ||
1960 | opts.omtu = l2cap_pi(sk)->omtu; | ||
1961 | opts.flush_to = l2cap_pi(sk)->flush_to; | ||
1962 | opts.mode = l2cap_pi(sk)->mode; | ||
1963 | opts.fcs = l2cap_pi(sk)->fcs; | ||
1964 | opts.max_tx = l2cap_pi(sk)->max_tx; | ||
1965 | opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win; | ||
1966 | |||
1967 | len = min_t(unsigned int, sizeof(opts), optlen); | ||
1968 | if (copy_from_user((char *) &opts, optval, len)) { | ||
1969 | err = -EFAULT; | ||
1970 | break; | ||
1971 | } | ||
1972 | |||
1973 | if (opts.txwin_size > L2CAP_DEFAULT_TX_WINDOW) { | ||
1974 | err = -EINVAL; | ||
1975 | break; | ||
1976 | } | ||
1977 | |||
1978 | l2cap_pi(sk)->mode = opts.mode; | ||
1979 | switch (l2cap_pi(sk)->mode) { | ||
1980 | case L2CAP_MODE_BASIC: | ||
1981 | l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_STATE2_DEVICE; | ||
1982 | break; | ||
1983 | case L2CAP_MODE_ERTM: | ||
1984 | case L2CAP_MODE_STREAMING: | ||
1985 | if (!disable_ertm) | ||
1986 | break; | ||
1987 | /* fall through */ | ||
1988 | default: | ||
1989 | err = -EINVAL; | ||
1990 | break; | ||
1991 | } | ||
1992 | |||
1993 | l2cap_pi(sk)->imtu = opts.imtu; | ||
1994 | l2cap_pi(sk)->omtu = opts.omtu; | ||
1995 | l2cap_pi(sk)->fcs = opts.fcs; | ||
1996 | l2cap_pi(sk)->max_tx = opts.max_tx; | ||
1997 | l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size; | ||
1998 | break; | ||
1999 | |||
2000 | case L2CAP_LM: | ||
2001 | if (get_user(opt, (u32 __user *) optval)) { | ||
2002 | err = -EFAULT; | ||
2003 | break; | ||
2004 | } | ||
2005 | |||
2006 | if (opt & L2CAP_LM_AUTH) | ||
2007 | l2cap_pi(sk)->sec_level = BT_SECURITY_LOW; | ||
2008 | if (opt & L2CAP_LM_ENCRYPT) | ||
2009 | l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM; | ||
2010 | if (opt & L2CAP_LM_SECURE) | ||
2011 | l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH; | ||
2012 | |||
2013 | l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER); | ||
2014 | l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE); | ||
2015 | break; | ||
2016 | |||
2017 | default: | ||
2018 | err = -ENOPROTOOPT; | ||
2019 | break; | ||
2020 | } | ||
2021 | |||
2022 | release_sock(sk); | ||
2023 | return err; | ||
2024 | } | ||
2025 | |||
2026 | static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen) | ||
2027 | { | ||
2028 | struct sock *sk = sock->sk; | ||
2029 | struct bt_security sec; | ||
2030 | int len, err = 0; | ||
2031 | u32 opt; | ||
2032 | |||
2033 | BT_DBG("sk %p", sk); | ||
2034 | |||
2035 | if (level == SOL_L2CAP) | ||
2036 | return l2cap_sock_setsockopt_old(sock, optname, optval, optlen); | ||
2037 | |||
2038 | if (level != SOL_BLUETOOTH) | ||
2039 | return -ENOPROTOOPT; | ||
2040 | |||
2041 | lock_sock(sk); | ||
2042 | |||
2043 | switch (optname) { | ||
2044 | case BT_SECURITY: | ||
2045 | if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM | ||
2046 | && sk->sk_type != SOCK_RAW) { | ||
2047 | err = -EINVAL; | ||
2048 | break; | ||
2049 | } | ||
2050 | |||
2051 | sec.level = BT_SECURITY_LOW; | ||
2052 | |||
2053 | len = min_t(unsigned int, sizeof(sec), optlen); | ||
2054 | if (copy_from_user((char *) &sec, optval, len)) { | ||
2055 | err = -EFAULT; | ||
2056 | break; | ||
2057 | } | ||
2058 | |||
2059 | if (sec.level < BT_SECURITY_LOW || | ||
2060 | sec.level > BT_SECURITY_HIGH) { | ||
2061 | err = -EINVAL; | ||
2062 | break; | ||
2063 | } | ||
2064 | |||
2065 | l2cap_pi(sk)->sec_level = sec.level; | ||
2066 | break; | ||
2067 | |||
2068 | case BT_DEFER_SETUP: | ||
2069 | if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) { | ||
2070 | err = -EINVAL; | ||
2071 | break; | ||
2072 | } | ||
2073 | |||
2074 | if (get_user(opt, (u32 __user *) optval)) { | ||
2075 | err = -EFAULT; | ||
2076 | break; | ||
2077 | } | ||
2078 | |||
2079 | bt_sk(sk)->defer_setup = opt; | ||
2080 | break; | ||
2081 | |||
2082 | default: | ||
2083 | err = -ENOPROTOOPT; | ||
2084 | break; | ||
2085 | } | ||
2086 | |||
2087 | release_sock(sk); | ||
2088 | return err; | ||
2089 | } | ||
2090 | |||
2091 | static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen) | ||
2092 | { | ||
2093 | struct sock *sk = sock->sk; | ||
2094 | struct l2cap_options opts; | ||
2095 | struct l2cap_conninfo cinfo; | ||
2096 | int len, err = 0; | ||
2097 | u32 opt; | ||
2098 | |||
2099 | BT_DBG("sk %p", sk); | ||
2100 | |||
2101 | if (get_user(len, optlen)) | ||
2102 | return -EFAULT; | ||
2103 | |||
2104 | lock_sock(sk); | ||
2105 | |||
2106 | switch (optname) { | ||
2107 | case L2CAP_OPTIONS: | ||
2108 | opts.imtu = l2cap_pi(sk)->imtu; | ||
2109 | opts.omtu = l2cap_pi(sk)->omtu; | ||
2110 | opts.flush_to = l2cap_pi(sk)->flush_to; | ||
2111 | opts.mode = l2cap_pi(sk)->mode; | ||
2112 | opts.fcs = l2cap_pi(sk)->fcs; | ||
2113 | opts.max_tx = l2cap_pi(sk)->max_tx; | ||
2114 | opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win; | ||
2115 | |||
2116 | len = min_t(unsigned int, len, sizeof(opts)); | ||
2117 | if (copy_to_user(optval, (char *) &opts, len)) | ||
2118 | err = -EFAULT; | ||
2119 | |||
2120 | break; | ||
2121 | |||
2122 | case L2CAP_LM: | ||
2123 | switch (l2cap_pi(sk)->sec_level) { | ||
2124 | case BT_SECURITY_LOW: | ||
2125 | opt = L2CAP_LM_AUTH; | ||
2126 | break; | ||
2127 | case BT_SECURITY_MEDIUM: | ||
2128 | opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT; | ||
2129 | break; | ||
2130 | case BT_SECURITY_HIGH: | ||
2131 | opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT | | ||
2132 | L2CAP_LM_SECURE; | ||
2133 | break; | ||
2134 | default: | ||
2135 | opt = 0; | ||
2136 | break; | ||
2137 | } | ||
2138 | |||
2139 | if (l2cap_pi(sk)->role_switch) | ||
2140 | opt |= L2CAP_LM_MASTER; | ||
2141 | |||
2142 | if (l2cap_pi(sk)->force_reliable) | ||
2143 | opt |= L2CAP_LM_RELIABLE; | ||
2144 | |||
2145 | if (put_user(opt, (u32 __user *) optval)) | ||
2146 | err = -EFAULT; | ||
2147 | break; | ||
2148 | |||
2149 | case L2CAP_CONNINFO: | ||
2150 | if (sk->sk_state != BT_CONNECTED && | ||
2151 | !(sk->sk_state == BT_CONNECT2 && | ||
2152 | bt_sk(sk)->defer_setup)) { | ||
2153 | err = -ENOTCONN; | ||
2154 | break; | ||
2155 | } | ||
2156 | |||
2157 | cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle; | ||
2158 | memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3); | ||
2159 | |||
2160 | len = min_t(unsigned int, len, sizeof(cinfo)); | ||
2161 | if (copy_to_user(optval, (char *) &cinfo, len)) | ||
2162 | err = -EFAULT; | ||
2163 | |||
2164 | break; | ||
2165 | |||
2166 | default: | ||
2167 | err = -ENOPROTOOPT; | ||
2168 | break; | ||
2169 | } | ||
2170 | |||
2171 | release_sock(sk); | ||
2172 | return err; | ||
2173 | } | ||
2174 | |||
2175 | static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen) | ||
2176 | { | ||
2177 | struct sock *sk = sock->sk; | ||
2178 | struct bt_security sec; | ||
2179 | int len, err = 0; | ||
2180 | |||
2181 | BT_DBG("sk %p", sk); | ||
2182 | |||
2183 | if (level == SOL_L2CAP) | ||
2184 | return l2cap_sock_getsockopt_old(sock, optname, optval, optlen); | ||
2185 | |||
2186 | if (level != SOL_BLUETOOTH) | ||
2187 | return -ENOPROTOOPT; | ||
2188 | |||
2189 | if (get_user(len, optlen)) | ||
2190 | return -EFAULT; | ||
2191 | |||
2192 | lock_sock(sk); | ||
2193 | |||
2194 | switch (optname) { | ||
2195 | case BT_SECURITY: | ||
2196 | if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM | ||
2197 | && sk->sk_type != SOCK_RAW) { | ||
2198 | err = -EINVAL; | ||
2199 | break; | ||
2200 | } | ||
2201 | |||
2202 | sec.level = l2cap_pi(sk)->sec_level; | ||
2203 | |||
2204 | len = min_t(unsigned int, len, sizeof(sec)); | ||
2205 | if (copy_to_user(optval, (char *) &sec, len)) | ||
2206 | err = -EFAULT; | ||
2207 | |||
2208 | break; | ||
2209 | |||
2210 | case BT_DEFER_SETUP: | ||
2211 | if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) { | ||
2212 | err = -EINVAL; | ||
2213 | break; | ||
2214 | } | ||
2215 | |||
2216 | if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval)) | ||
2217 | err = -EFAULT; | ||
2218 | |||
2219 | break; | ||
2220 | |||
2221 | default: | ||
2222 | err = -ENOPROTOOPT; | ||
2223 | break; | ||
2224 | } | ||
2225 | |||
2226 | release_sock(sk); | ||
2227 | return err; | ||
2228 | } | ||
2229 | |||
2230 | static int l2cap_sock_shutdown(struct socket *sock, int how) | ||
2231 | { | ||
2232 | struct sock *sk = sock->sk; | ||
2233 | int err = 0; | ||
2234 | |||
2235 | BT_DBG("sock %p, sk %p", sock, sk); | ||
2236 | |||
2237 | if (!sk) | ||
2238 | return 0; | ||
2239 | |||
2240 | lock_sock(sk); | ||
2241 | if (!sk->sk_shutdown) { | ||
2242 | if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) | ||
2243 | err = __l2cap_wait_ack(sk); | ||
2244 | |||
2245 | sk->sk_shutdown = SHUTDOWN_MASK; | ||
2246 | l2cap_sock_clear_timer(sk); | ||
2247 | __l2cap_sock_close(sk, 0); | ||
2248 | |||
2249 | if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) | ||
2250 | err = bt_sock_wait_state(sk, BT_CLOSED, | ||
2251 | sk->sk_lingertime); | ||
2252 | } | ||
2253 | |||
2254 | if (!err && sk->sk_err) | ||
2255 | err = -sk->sk_err; | ||
2256 | |||
2257 | release_sock(sk); | ||
2258 | return err; | ||
2259 | } | ||
2260 | |||
2261 | static int l2cap_sock_release(struct socket *sock) | ||
2262 | { | ||
2263 | struct sock *sk = sock->sk; | ||
2264 | int err; | ||
2265 | |||
2266 | BT_DBG("sock %p, sk %p", sock, sk); | ||
2267 | |||
2268 | if (!sk) | ||
2269 | return 0; | ||
2270 | |||
2271 | err = l2cap_sock_shutdown(sock, 2); | ||
2272 | |||
2273 | sock_orphan(sk); | ||
2274 | l2cap_sock_kill(sk); | ||
2275 | return err; | ||
2276 | } | ||
2277 | |||
2278 | static void l2cap_chan_ready(struct sock *sk) | 1360 | static void l2cap_chan_ready(struct sock *sk) |
2279 | { | 1361 | { |
2280 | struct sock *parent = bt_sk(sk)->parent; | 1362 | struct sock *parent = bt_sk(sk)->parent; |
@@ -2346,7 +1428,11 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, | |||
2346 | 1428 | ||
2347 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); | 1429 | lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); |
2348 | lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen); | 1430 | lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen); |
2349 | lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING); | 1431 | |
1432 | if (conn->hcon->type == LE_LINK) | ||
1433 | lh->cid = cpu_to_le16(L2CAP_CID_LE_SIGNALING); | ||
1434 | else | ||
1435 | lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING); | ||
2350 | 1436 | ||
2351 | cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE); | 1437 | cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE); |
2352 | cmd->code = code; | 1438 | cmd->code = code; |
@@ -2493,7 +1579,7 @@ static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask) | |||
2493 | } | 1579 | } |
2494 | } | 1580 | } |
2495 | 1581 | ||
2496 | static int l2cap_build_conf_req(struct sock *sk, void *data) | 1582 | int l2cap_build_conf_req(struct sock *sk, void *data) |
2497 | { | 1583 | { |
2498 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 1584 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
2499 | struct l2cap_conf_req *req = data; | 1585 | struct l2cap_conf_req *req = data; |
@@ -2518,11 +1604,11 @@ static int l2cap_build_conf_req(struct sock *sk, void *data) | |||
2518 | } | 1604 | } |
2519 | 1605 | ||
2520 | done: | 1606 | done: |
1607 | if (pi->imtu != L2CAP_DEFAULT_MTU) | ||
1608 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu); | ||
1609 | |||
2521 | switch (pi->mode) { | 1610 | switch (pi->mode) { |
2522 | case L2CAP_MODE_BASIC: | 1611 | case L2CAP_MODE_BASIC: |
2523 | if (pi->imtu != L2CAP_DEFAULT_MTU) | ||
2524 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu); | ||
2525 | |||
2526 | if (!(pi->conn->feat_mask & L2CAP_FEAT_ERTM) && | 1612 | if (!(pi->conn->feat_mask & L2CAP_FEAT_ERTM) && |
2527 | !(pi->conn->feat_mask & L2CAP_FEAT_STREAMING)) | 1613 | !(pi->conn->feat_mask & L2CAP_FEAT_STREAMING)) |
2528 | break; | 1614 | break; |
@@ -2585,10 +1671,6 @@ done: | |||
2585 | break; | 1671 | break; |
2586 | } | 1672 | } |
2587 | 1673 | ||
2588 | /* FIXME: Need actual value of the flush timeout */ | ||
2589 | //if (flush_to != L2CAP_DEFAULT_FLUSH_TO) | ||
2590 | // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to); | ||
2591 | |||
2592 | req->dcid = cpu_to_le16(pi->dcid); | 1674 | req->dcid = cpu_to_le16(pi->dcid); |
2593 | req->flags = cpu_to_le16(0); | 1675 | req->flags = cpu_to_le16(0); |
2594 | 1676 | ||
@@ -3415,12 +2497,153 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm | |||
3415 | return 0; | 2497 | return 0; |
3416 | } | 2498 | } |
3417 | 2499 | ||
3418 | static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb) | 2500 | static inline int l2cap_check_conn_param(u16 min, u16 max, u16 latency, |
2501 | u16 to_multiplier) | ||
2502 | { | ||
2503 | u16 max_latency; | ||
2504 | |||
2505 | if (min > max || min < 6 || max > 3200) | ||
2506 | return -EINVAL; | ||
2507 | |||
2508 | if (to_multiplier < 10 || to_multiplier > 3200) | ||
2509 | return -EINVAL; | ||
2510 | |||
2511 | if (max >= to_multiplier * 8) | ||
2512 | return -EINVAL; | ||
2513 | |||
2514 | max_latency = (to_multiplier * 8 / max) - 1; | ||
2515 | if (latency > 499 || latency > max_latency) | ||
2516 | return -EINVAL; | ||
2517 | |||
2518 | return 0; | ||
2519 | } | ||
2520 | |||
2521 | static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn, | ||
2522 | struct l2cap_cmd_hdr *cmd, u8 *data) | ||
2523 | { | ||
2524 | struct hci_conn *hcon = conn->hcon; | ||
2525 | struct l2cap_conn_param_update_req *req; | ||
2526 | struct l2cap_conn_param_update_rsp rsp; | ||
2527 | u16 min, max, latency, to_multiplier, cmd_len; | ||
2528 | int err; | ||
2529 | |||
2530 | if (!(hcon->link_mode & HCI_LM_MASTER)) | ||
2531 | return -EINVAL; | ||
2532 | |||
2533 | cmd_len = __le16_to_cpu(cmd->len); | ||
2534 | if (cmd_len != sizeof(struct l2cap_conn_param_update_req)) | ||
2535 | return -EPROTO; | ||
2536 | |||
2537 | req = (struct l2cap_conn_param_update_req *) data; | ||
2538 | min = __le16_to_cpu(req->min); | ||
2539 | max = __le16_to_cpu(req->max); | ||
2540 | latency = __le16_to_cpu(req->latency); | ||
2541 | to_multiplier = __le16_to_cpu(req->to_multiplier); | ||
2542 | |||
2543 | BT_DBG("min 0x%4.4x max 0x%4.4x latency: 0x%4.4x Timeout: 0x%4.4x", | ||
2544 | min, max, latency, to_multiplier); | ||
2545 | |||
2546 | memset(&rsp, 0, sizeof(rsp)); | ||
2547 | |||
2548 | err = l2cap_check_conn_param(min, max, latency, to_multiplier); | ||
2549 | if (err) | ||
2550 | rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_REJECTED); | ||
2551 | else | ||
2552 | rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED); | ||
2553 | |||
2554 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP, | ||
2555 | sizeof(rsp), &rsp); | ||
2556 | |||
2557 | if (!err) | ||
2558 | hci_le_conn_update(hcon, min, max, latency, to_multiplier); | ||
2559 | |||
2560 | return 0; | ||
2561 | } | ||
2562 | |||
2563 | static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, | ||
2564 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data) | ||
2565 | { | ||
2566 | int err = 0; | ||
2567 | |||
2568 | switch (cmd->code) { | ||
2569 | case L2CAP_COMMAND_REJ: | ||
2570 | l2cap_command_rej(conn, cmd, data); | ||
2571 | break; | ||
2572 | |||
2573 | case L2CAP_CONN_REQ: | ||
2574 | err = l2cap_connect_req(conn, cmd, data); | ||
2575 | break; | ||
2576 | |||
2577 | case L2CAP_CONN_RSP: | ||
2578 | err = l2cap_connect_rsp(conn, cmd, data); | ||
2579 | break; | ||
2580 | |||
2581 | case L2CAP_CONF_REQ: | ||
2582 | err = l2cap_config_req(conn, cmd, cmd_len, data); | ||
2583 | break; | ||
2584 | |||
2585 | case L2CAP_CONF_RSP: | ||
2586 | err = l2cap_config_rsp(conn, cmd, data); | ||
2587 | break; | ||
2588 | |||
2589 | case L2CAP_DISCONN_REQ: | ||
2590 | err = l2cap_disconnect_req(conn, cmd, data); | ||
2591 | break; | ||
2592 | |||
2593 | case L2CAP_DISCONN_RSP: | ||
2594 | err = l2cap_disconnect_rsp(conn, cmd, data); | ||
2595 | break; | ||
2596 | |||
2597 | case L2CAP_ECHO_REQ: | ||
2598 | l2cap_send_cmd(conn, cmd->ident, L2CAP_ECHO_RSP, cmd_len, data); | ||
2599 | break; | ||
2600 | |||
2601 | case L2CAP_ECHO_RSP: | ||
2602 | break; | ||
2603 | |||
2604 | case L2CAP_INFO_REQ: | ||
2605 | err = l2cap_information_req(conn, cmd, data); | ||
2606 | break; | ||
2607 | |||
2608 | case L2CAP_INFO_RSP: | ||
2609 | err = l2cap_information_rsp(conn, cmd, data); | ||
2610 | break; | ||
2611 | |||
2612 | default: | ||
2613 | BT_ERR("Unknown BR/EDR signaling command 0x%2.2x", cmd->code); | ||
2614 | err = -EINVAL; | ||
2615 | break; | ||
2616 | } | ||
2617 | |||
2618 | return err; | ||
2619 | } | ||
2620 | |||
2621 | static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn, | ||
2622 | struct l2cap_cmd_hdr *cmd, u8 *data) | ||
2623 | { | ||
2624 | switch (cmd->code) { | ||
2625 | case L2CAP_COMMAND_REJ: | ||
2626 | return 0; | ||
2627 | |||
2628 | case L2CAP_CONN_PARAM_UPDATE_REQ: | ||
2629 | return l2cap_conn_param_update_req(conn, cmd, data); | ||
2630 | |||
2631 | case L2CAP_CONN_PARAM_UPDATE_RSP: | ||
2632 | return 0; | ||
2633 | |||
2634 | default: | ||
2635 | BT_ERR("Unknown LE signaling command 0x%2.2x", cmd->code); | ||
2636 | return -EINVAL; | ||
2637 | } | ||
2638 | } | ||
2639 | |||
2640 | static inline void l2cap_sig_channel(struct l2cap_conn *conn, | ||
2641 | struct sk_buff *skb) | ||
3419 | { | 2642 | { |
3420 | u8 *data = skb->data; | 2643 | u8 *data = skb->data; |
3421 | int len = skb->len; | 2644 | int len = skb->len; |
3422 | struct l2cap_cmd_hdr cmd; | 2645 | struct l2cap_cmd_hdr cmd; |
3423 | int err = 0; | 2646 | int err; |
3424 | 2647 | ||
3425 | l2cap_raw_recv(conn, skb); | 2648 | l2cap_raw_recv(conn, skb); |
3426 | 2649 | ||
@@ -3439,55 +2662,10 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *sk | |||
3439 | break; | 2662 | break; |
3440 | } | 2663 | } |
3441 | 2664 | ||
3442 | switch (cmd.code) { | 2665 | if (conn->hcon->type == LE_LINK) |
3443 | case L2CAP_COMMAND_REJ: | 2666 | err = l2cap_le_sig_cmd(conn, &cmd, data); |
3444 | l2cap_command_rej(conn, &cmd, data); | 2667 | else |
3445 | break; | 2668 | err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data); |
3446 | |||
3447 | case L2CAP_CONN_REQ: | ||
3448 | err = l2cap_connect_req(conn, &cmd, data); | ||
3449 | break; | ||
3450 | |||
3451 | case L2CAP_CONN_RSP: | ||
3452 | err = l2cap_connect_rsp(conn, &cmd, data); | ||
3453 | break; | ||
3454 | |||
3455 | case L2CAP_CONF_REQ: | ||
3456 | err = l2cap_config_req(conn, &cmd, cmd_len, data); | ||
3457 | break; | ||
3458 | |||
3459 | case L2CAP_CONF_RSP: | ||
3460 | err = l2cap_config_rsp(conn, &cmd, data); | ||
3461 | break; | ||
3462 | |||
3463 | case L2CAP_DISCONN_REQ: | ||
3464 | err = l2cap_disconnect_req(conn, &cmd, data); | ||
3465 | break; | ||
3466 | |||
3467 | case L2CAP_DISCONN_RSP: | ||
3468 | err = l2cap_disconnect_rsp(conn, &cmd, data); | ||
3469 | break; | ||
3470 | |||
3471 | case L2CAP_ECHO_REQ: | ||
3472 | l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd_len, data); | ||
3473 | break; | ||
3474 | |||
3475 | case L2CAP_ECHO_RSP: | ||
3476 | break; | ||
3477 | |||
3478 | case L2CAP_INFO_REQ: | ||
3479 | err = l2cap_information_req(conn, &cmd, data); | ||
3480 | break; | ||
3481 | |||
3482 | case L2CAP_INFO_RSP: | ||
3483 | err = l2cap_information_rsp(conn, &cmd, data); | ||
3484 | break; | ||
3485 | |||
3486 | default: | ||
3487 | BT_ERR("Unknown signaling command 0x%2.2x", cmd.code); | ||
3488 | err = -EINVAL; | ||
3489 | break; | ||
3490 | } | ||
3491 | 2669 | ||
3492 | if (err) { | 2670 | if (err) { |
3493 | struct l2cap_cmd_rej rej; | 2671 | struct l2cap_cmd_rej rej; |
@@ -4484,6 +3662,7 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) | |||
4484 | BT_DBG("len %d, cid 0x%4.4x", len, cid); | 3662 | BT_DBG("len %d, cid 0x%4.4x", len, cid); |
4485 | 3663 | ||
4486 | switch (cid) { | 3664 | switch (cid) { |
3665 | case L2CAP_CID_LE_SIGNALING: | ||
4487 | case L2CAP_CID_SIGNALING: | 3666 | case L2CAP_CID_SIGNALING: |
4488 | l2cap_sig_channel(conn, skb); | 3667 | l2cap_sig_channel(conn, skb); |
4489 | break; | 3668 | break; |
@@ -4541,7 +3720,7 @@ static int l2cap_connect_cfm(struct hci_conn *hcon, u8 status) | |||
4541 | 3720 | ||
4542 | BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status); | 3721 | BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status); |
4543 | 3722 | ||
4544 | if (hcon->type != ACL_LINK) | 3723 | if (!(hcon->type == ACL_LINK || hcon->type == LE_LINK)) |
4545 | return -EINVAL; | 3724 | return -EINVAL; |
4546 | 3725 | ||
4547 | if (!status) { | 3726 | if (!status) { |
@@ -4570,7 +3749,7 @@ static int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason) | |||
4570 | { | 3749 | { |
4571 | BT_DBG("hcon %p reason %d", hcon, reason); | 3750 | BT_DBG("hcon %p reason %d", hcon, reason); |
4572 | 3751 | ||
4573 | if (hcon->type != ACL_LINK) | 3752 | if (!(hcon->type == ACL_LINK || hcon->type == LE_LINK)) |
4574 | return -EINVAL; | 3753 | return -EINVAL; |
4575 | 3754 | ||
4576 | l2cap_conn_del(hcon, bt_err(reason)); | 3755 | l2cap_conn_del(hcon, bt_err(reason)); |
@@ -4673,12 +3852,15 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl | |||
4673 | { | 3852 | { |
4674 | struct l2cap_conn *conn = hcon->l2cap_data; | 3853 | struct l2cap_conn *conn = hcon->l2cap_data; |
4675 | 3854 | ||
4676 | if (!conn && !(conn = l2cap_conn_add(hcon, 0))) | 3855 | if (!conn) |
3856 | conn = l2cap_conn_add(hcon, 0); | ||
3857 | |||
3858 | if (!conn) | ||
4677 | goto drop; | 3859 | goto drop; |
4678 | 3860 | ||
4679 | BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags); | 3861 | BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags); |
4680 | 3862 | ||
4681 | if (flags & ACL_START) { | 3863 | if (!(flags & ACL_CONT)) { |
4682 | struct l2cap_hdr *hdr; | 3864 | struct l2cap_hdr *hdr; |
4683 | struct sock *sk; | 3865 | struct sock *sk; |
4684 | u16 cid; | 3866 | u16 cid; |
@@ -4784,12 +3966,13 @@ static int l2cap_debugfs_show(struct seq_file *f, void *p) | |||
4784 | sk_for_each(sk, node, &l2cap_sk_list.head) { | 3966 | sk_for_each(sk, node, &l2cap_sk_list.head) { |
4785 | struct l2cap_pinfo *pi = l2cap_pi(sk); | 3967 | struct l2cap_pinfo *pi = l2cap_pi(sk); |
4786 | 3968 | ||
4787 | seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n", | 3969 | seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n", |
4788 | batostr(&bt_sk(sk)->src), | 3970 | batostr(&bt_sk(sk)->src), |
4789 | batostr(&bt_sk(sk)->dst), | 3971 | batostr(&bt_sk(sk)->dst), |
4790 | sk->sk_state, __le16_to_cpu(pi->psm), | 3972 | sk->sk_state, __le16_to_cpu(pi->psm), |
4791 | pi->scid, pi->dcid, | 3973 | pi->scid, pi->dcid, |
4792 | pi->imtu, pi->omtu, pi->sec_level); | 3974 | pi->imtu, pi->omtu, pi->sec_level, |
3975 | pi->mode); | ||
4793 | } | 3976 | } |
4794 | 3977 | ||
4795 | read_unlock_bh(&l2cap_sk_list.lock); | 3978 | read_unlock_bh(&l2cap_sk_list.lock); |
@@ -4811,32 +3994,6 @@ static const struct file_operations l2cap_debugfs_fops = { | |||
4811 | 3994 | ||
4812 | static struct dentry *l2cap_debugfs; | 3995 | static struct dentry *l2cap_debugfs; |
4813 | 3996 | ||
4814 | static const struct proto_ops l2cap_sock_ops = { | ||
4815 | .family = PF_BLUETOOTH, | ||
4816 | .owner = THIS_MODULE, | ||
4817 | .release = l2cap_sock_release, | ||
4818 | .bind = l2cap_sock_bind, | ||
4819 | .connect = l2cap_sock_connect, | ||
4820 | .listen = l2cap_sock_listen, | ||
4821 | .accept = l2cap_sock_accept, | ||
4822 | .getname = l2cap_sock_getname, | ||
4823 | .sendmsg = l2cap_sock_sendmsg, | ||
4824 | .recvmsg = l2cap_sock_recvmsg, | ||
4825 | .poll = bt_sock_poll, | ||
4826 | .ioctl = bt_sock_ioctl, | ||
4827 | .mmap = sock_no_mmap, | ||
4828 | .socketpair = sock_no_socketpair, | ||
4829 | .shutdown = l2cap_sock_shutdown, | ||
4830 | .setsockopt = l2cap_sock_setsockopt, | ||
4831 | .getsockopt = l2cap_sock_getsockopt | ||
4832 | }; | ||
4833 | |||
4834 | static const struct net_proto_family l2cap_sock_family_ops = { | ||
4835 | .family = PF_BLUETOOTH, | ||
4836 | .owner = THIS_MODULE, | ||
4837 | .create = l2cap_sock_create, | ||
4838 | }; | ||
4839 | |||
4840 | static struct hci_proto l2cap_hci_proto = { | 3997 | static struct hci_proto l2cap_hci_proto = { |
4841 | .name = "L2CAP", | 3998 | .name = "L2CAP", |
4842 | .id = HCI_PROTO_L2CAP, | 3999 | .id = HCI_PROTO_L2CAP, |
@@ -4848,23 +4005,17 @@ static struct hci_proto l2cap_hci_proto = { | |||
4848 | .recv_acldata = l2cap_recv_acldata | 4005 | .recv_acldata = l2cap_recv_acldata |
4849 | }; | 4006 | }; |
4850 | 4007 | ||
4851 | static int __init l2cap_init(void) | 4008 | int __init l2cap_init(void) |
4852 | { | 4009 | { |
4853 | int err; | 4010 | int err; |
4854 | 4011 | ||
4855 | err = proto_register(&l2cap_proto, 0); | 4012 | err = l2cap_init_sockets(); |
4856 | if (err < 0) | 4013 | if (err < 0) |
4857 | return err; | 4014 | return err; |
4858 | 4015 | ||
4859 | _busy_wq = create_singlethread_workqueue("l2cap"); | 4016 | _busy_wq = create_singlethread_workqueue("l2cap"); |
4860 | if (!_busy_wq) { | 4017 | if (!_busy_wq) { |
4861 | proto_unregister(&l2cap_proto); | 4018 | err = -ENOMEM; |
4862 | return -ENOMEM; | ||
4863 | } | ||
4864 | |||
4865 | err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops); | ||
4866 | if (err < 0) { | ||
4867 | BT_ERR("L2CAP socket registration failed"); | ||
4868 | goto error; | 4019 | goto error; |
4869 | } | 4020 | } |
4870 | 4021 | ||
@@ -4882,49 +4033,28 @@ static int __init l2cap_init(void) | |||
4882 | BT_ERR("Failed to create L2CAP debug file"); | 4033 | BT_ERR("Failed to create L2CAP debug file"); |
4883 | } | 4034 | } |
4884 | 4035 | ||
4885 | BT_INFO("L2CAP ver %s", VERSION); | ||
4886 | BT_INFO("L2CAP socket layer initialized"); | 4036 | BT_INFO("L2CAP socket layer initialized"); |
4887 | 4037 | ||
4888 | return 0; | 4038 | return 0; |
4889 | 4039 | ||
4890 | error: | 4040 | error: |
4891 | destroy_workqueue(_busy_wq); | 4041 | destroy_workqueue(_busy_wq); |
4892 | proto_unregister(&l2cap_proto); | 4042 | l2cap_cleanup_sockets(); |
4893 | return err; | 4043 | return err; |
4894 | } | 4044 | } |
4895 | 4045 | ||
4896 | static void __exit l2cap_exit(void) | 4046 | void l2cap_exit(void) |
4897 | { | 4047 | { |
4898 | debugfs_remove(l2cap_debugfs); | 4048 | debugfs_remove(l2cap_debugfs); |
4899 | 4049 | ||
4900 | flush_workqueue(_busy_wq); | 4050 | flush_workqueue(_busy_wq); |
4901 | destroy_workqueue(_busy_wq); | 4051 | destroy_workqueue(_busy_wq); |
4902 | 4052 | ||
4903 | if (bt_sock_unregister(BTPROTO_L2CAP) < 0) | ||
4904 | BT_ERR("L2CAP socket unregistration failed"); | ||
4905 | |||
4906 | if (hci_unregister_proto(&l2cap_hci_proto) < 0) | 4053 | if (hci_unregister_proto(&l2cap_hci_proto) < 0) |
4907 | BT_ERR("L2CAP protocol unregistration failed"); | 4054 | BT_ERR("L2CAP protocol unregistration failed"); |
4908 | 4055 | ||
4909 | proto_unregister(&l2cap_proto); | 4056 | l2cap_cleanup_sockets(); |
4910 | } | 4057 | } |
4911 | 4058 | ||
4912 | void l2cap_load(void) | ||
4913 | { | ||
4914 | /* Dummy function to trigger automatic L2CAP module loading by | ||
4915 | * other modules that use L2CAP sockets but don't use any other | ||
4916 | * symbols from it. */ | ||
4917 | } | ||
4918 | EXPORT_SYMBOL(l2cap_load); | ||
4919 | |||
4920 | module_init(l2cap_init); | ||
4921 | module_exit(l2cap_exit); | ||
4922 | |||
4923 | module_param(disable_ertm, bool, 0644); | 4059 | module_param(disable_ertm, bool, 0644); |
4924 | MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode"); | 4060 | MODULE_PARM_DESC(disable_ertm, "Disable enhanced retransmission mode"); |
4925 | |||
4926 | MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); | ||
4927 | MODULE_DESCRIPTION("Bluetooth L2CAP ver " VERSION); | ||
4928 | MODULE_VERSION(VERSION); | ||
4929 | MODULE_LICENSE("GPL"); | ||
4930 | MODULE_ALIAS("bt-proto-0"); | ||
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c new file mode 100644 index 000000000000..fc85e7ae33c7 --- /dev/null +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -0,0 +1,1156 @@ | |||
1 | /* | ||
2 | BlueZ - Bluetooth protocol stack for Linux | ||
3 | Copyright (C) 2000-2001 Qualcomm Incorporated | ||
4 | Copyright (C) 2009-2010 Gustavo F. Padovan <gustavo@padovan.org> | ||
5 | Copyright (C) 2010 Google Inc. | ||
6 | |||
7 | Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> | ||
8 | |||
9 | This program is free software; you can redistribute it and/or modify | ||
10 | it under the terms of the GNU General Public License version 2 as | ||
11 | published by the Free Software Foundation; | ||
12 | |||
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
14 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. | ||
16 | IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY | ||
17 | CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES | ||
18 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
19 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
20 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
21 | |||
22 | ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, | ||
23 | COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS | ||
24 | SOFTWARE IS DISCLAIMED. | ||
25 | */ | ||
26 | |||
27 | /* Bluetooth L2CAP sockets. */ | ||
28 | |||
29 | #include <net/bluetooth/bluetooth.h> | ||
30 | #include <net/bluetooth/hci_core.h> | ||
31 | #include <net/bluetooth/l2cap.h> | ||
32 | |||
33 | /* ---- L2CAP timers ---- */ | ||
34 | static void l2cap_sock_timeout(unsigned long arg) | ||
35 | { | ||
36 | struct sock *sk = (struct sock *) arg; | ||
37 | int reason; | ||
38 | |||
39 | BT_DBG("sock %p state %d", sk, sk->sk_state); | ||
40 | |||
41 | bh_lock_sock(sk); | ||
42 | |||
43 | if (sock_owned_by_user(sk)) { | ||
44 | /* sk is owned by user. Try again later */ | ||
45 | l2cap_sock_set_timer(sk, HZ / 5); | ||
46 | bh_unlock_sock(sk); | ||
47 | sock_put(sk); | ||
48 | return; | ||
49 | } | ||
50 | |||
51 | if (sk->sk_state == BT_CONNECTED || sk->sk_state == BT_CONFIG) | ||
52 | reason = ECONNREFUSED; | ||
53 | else if (sk->sk_state == BT_CONNECT && | ||
54 | l2cap_pi(sk)->sec_level != BT_SECURITY_SDP) | ||
55 | reason = ECONNREFUSED; | ||
56 | else | ||
57 | reason = ETIMEDOUT; | ||
58 | |||
59 | __l2cap_sock_close(sk, reason); | ||
60 | |||
61 | bh_unlock_sock(sk); | ||
62 | |||
63 | l2cap_sock_kill(sk); | ||
64 | sock_put(sk); | ||
65 | } | ||
66 | |||
67 | void l2cap_sock_set_timer(struct sock *sk, long timeout) | ||
68 | { | ||
69 | BT_DBG("sk %p state %d timeout %ld", sk, sk->sk_state, timeout); | ||
70 | sk_reset_timer(sk, &sk->sk_timer, jiffies + timeout); | ||
71 | } | ||
72 | |||
73 | void l2cap_sock_clear_timer(struct sock *sk) | ||
74 | { | ||
75 | BT_DBG("sock %p state %d", sk, sk->sk_state); | ||
76 | sk_stop_timer(sk, &sk->sk_timer); | ||
77 | } | ||
78 | |||
79 | static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src) | ||
80 | { | ||
81 | struct sock *sk; | ||
82 | struct hlist_node *node; | ||
83 | sk_for_each(sk, node, &l2cap_sk_list.head) | ||
84 | if (l2cap_pi(sk)->sport == psm && !bacmp(&bt_sk(sk)->src, src)) | ||
85 | goto found; | ||
86 | sk = NULL; | ||
87 | found: | ||
88 | return sk; | ||
89 | } | ||
90 | |||
91 | static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) | ||
92 | { | ||
93 | struct sock *sk = sock->sk; | ||
94 | struct sockaddr_l2 la; | ||
95 | int len, err = 0; | ||
96 | |||
97 | BT_DBG("sk %p", sk); | ||
98 | |||
99 | if (!addr || addr->sa_family != AF_BLUETOOTH) | ||
100 | return -EINVAL; | ||
101 | |||
102 | memset(&la, 0, sizeof(la)); | ||
103 | len = min_t(unsigned int, sizeof(la), alen); | ||
104 | memcpy(&la, addr, len); | ||
105 | |||
106 | if (la.l2_cid && la.l2_psm) | ||
107 | return -EINVAL; | ||
108 | |||
109 | lock_sock(sk); | ||
110 | |||
111 | if (sk->sk_state != BT_OPEN) { | ||
112 | err = -EBADFD; | ||
113 | goto done; | ||
114 | } | ||
115 | |||
116 | if (la.l2_psm) { | ||
117 | __u16 psm = __le16_to_cpu(la.l2_psm); | ||
118 | |||
119 | /* PSM must be odd and lsb of upper byte must be 0 */ | ||
120 | if ((psm & 0x0101) != 0x0001) { | ||
121 | err = -EINVAL; | ||
122 | goto done; | ||
123 | } | ||
124 | |||
125 | /* Restrict usage of well-known PSMs */ | ||
126 | if (psm < 0x1001 && !capable(CAP_NET_BIND_SERVICE)) { | ||
127 | err = -EACCES; | ||
128 | goto done; | ||
129 | } | ||
130 | } | ||
131 | |||
132 | write_lock_bh(&l2cap_sk_list.lock); | ||
133 | |||
134 | if (la.l2_psm && __l2cap_get_sock_by_addr(la.l2_psm, &la.l2_bdaddr)) { | ||
135 | err = -EADDRINUSE; | ||
136 | } else { | ||
137 | /* Save source address */ | ||
138 | bacpy(&bt_sk(sk)->src, &la.l2_bdaddr); | ||
139 | l2cap_pi(sk)->psm = la.l2_psm; | ||
140 | l2cap_pi(sk)->sport = la.l2_psm; | ||
141 | sk->sk_state = BT_BOUND; | ||
142 | |||
143 | if (__le16_to_cpu(la.l2_psm) == 0x0001 || | ||
144 | __le16_to_cpu(la.l2_psm) == 0x0003) | ||
145 | l2cap_pi(sk)->sec_level = BT_SECURITY_SDP; | ||
146 | } | ||
147 | |||
148 | if (la.l2_cid) | ||
149 | l2cap_pi(sk)->scid = la.l2_cid; | ||
150 | |||
151 | write_unlock_bh(&l2cap_sk_list.lock); | ||
152 | |||
153 | done: | ||
154 | release_sock(sk); | ||
155 | return err; | ||
156 | } | ||
157 | |||
158 | static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags) | ||
159 | { | ||
160 | struct sock *sk = sock->sk; | ||
161 | struct sockaddr_l2 la; | ||
162 | int len, err = 0; | ||
163 | |||
164 | BT_DBG("sk %p", sk); | ||
165 | |||
166 | if (!addr || alen < sizeof(addr->sa_family) || | ||
167 | addr->sa_family != AF_BLUETOOTH) | ||
168 | return -EINVAL; | ||
169 | |||
170 | memset(&la, 0, sizeof(la)); | ||
171 | len = min_t(unsigned int, sizeof(la), alen); | ||
172 | memcpy(&la, addr, len); | ||
173 | |||
174 | if (la.l2_cid && la.l2_psm) | ||
175 | return -EINVAL; | ||
176 | |||
177 | lock_sock(sk); | ||
178 | |||
179 | if ((sk->sk_type == SOCK_SEQPACKET || sk->sk_type == SOCK_STREAM) | ||
180 | && !(la.l2_psm || la.l2_cid)) { | ||
181 | err = -EINVAL; | ||
182 | goto done; | ||
183 | } | ||
184 | |||
185 | switch (l2cap_pi(sk)->mode) { | ||
186 | case L2CAP_MODE_BASIC: | ||
187 | break; | ||
188 | case L2CAP_MODE_ERTM: | ||
189 | case L2CAP_MODE_STREAMING: | ||
190 | if (!disable_ertm) | ||
191 | break; | ||
192 | /* fall through */ | ||
193 | default: | ||
194 | err = -ENOTSUPP; | ||
195 | goto done; | ||
196 | } | ||
197 | |||
198 | switch (sk->sk_state) { | ||
199 | case BT_CONNECT: | ||
200 | case BT_CONNECT2: | ||
201 | case BT_CONFIG: | ||
202 | /* Already connecting */ | ||
203 | goto wait; | ||
204 | |||
205 | case BT_CONNECTED: | ||
206 | /* Already connected */ | ||
207 | err = -EISCONN; | ||
208 | goto done; | ||
209 | |||
210 | case BT_OPEN: | ||
211 | case BT_BOUND: | ||
212 | /* Can connect */ | ||
213 | break; | ||
214 | |||
215 | default: | ||
216 | err = -EBADFD; | ||
217 | goto done; | ||
218 | } | ||
219 | |||
220 | /* PSM must be odd and lsb of upper byte must be 0 */ | ||
221 | if ((__le16_to_cpu(la.l2_psm) & 0x0101) != 0x0001 && | ||
222 | sk->sk_type != SOCK_RAW && !la.l2_cid) { | ||
223 | err = -EINVAL; | ||
224 | goto done; | ||
225 | } | ||
226 | |||
227 | /* Set destination address and psm */ | ||
228 | bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr); | ||
229 | l2cap_pi(sk)->psm = la.l2_psm; | ||
230 | l2cap_pi(sk)->dcid = la.l2_cid; | ||
231 | |||
232 | err = l2cap_do_connect(sk); | ||
233 | if (err) | ||
234 | goto done; | ||
235 | |||
236 | wait: | ||
237 | err = bt_sock_wait_state(sk, BT_CONNECTED, | ||
238 | sock_sndtimeo(sk, flags & O_NONBLOCK)); | ||
239 | done: | ||
240 | release_sock(sk); | ||
241 | return err; | ||
242 | } | ||
243 | |||
244 | static int l2cap_sock_listen(struct socket *sock, int backlog) | ||
245 | { | ||
246 | struct sock *sk = sock->sk; | ||
247 | int err = 0; | ||
248 | |||
249 | BT_DBG("sk %p backlog %d", sk, backlog); | ||
250 | |||
251 | lock_sock(sk); | ||
252 | |||
253 | if ((sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM) | ||
254 | || sk->sk_state != BT_BOUND) { | ||
255 | err = -EBADFD; | ||
256 | goto done; | ||
257 | } | ||
258 | |||
259 | switch (l2cap_pi(sk)->mode) { | ||
260 | case L2CAP_MODE_BASIC: | ||
261 | break; | ||
262 | case L2CAP_MODE_ERTM: | ||
263 | case L2CAP_MODE_STREAMING: | ||
264 | if (!disable_ertm) | ||
265 | break; | ||
266 | /* fall through */ | ||
267 | default: | ||
268 | err = -ENOTSUPP; | ||
269 | goto done; | ||
270 | } | ||
271 | |||
272 | if (!l2cap_pi(sk)->psm && !l2cap_pi(sk)->dcid) { | ||
273 | bdaddr_t *src = &bt_sk(sk)->src; | ||
274 | u16 psm; | ||
275 | |||
276 | err = -EINVAL; | ||
277 | |||
278 | write_lock_bh(&l2cap_sk_list.lock); | ||
279 | |||
280 | for (psm = 0x1001; psm < 0x1100; psm += 2) | ||
281 | if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) { | ||
282 | l2cap_pi(sk)->psm = cpu_to_le16(psm); | ||
283 | l2cap_pi(sk)->sport = cpu_to_le16(psm); | ||
284 | err = 0; | ||
285 | break; | ||
286 | } | ||
287 | |||
288 | write_unlock_bh(&l2cap_sk_list.lock); | ||
289 | |||
290 | if (err < 0) | ||
291 | goto done; | ||
292 | } | ||
293 | |||
294 | sk->sk_max_ack_backlog = backlog; | ||
295 | sk->sk_ack_backlog = 0; | ||
296 | sk->sk_state = BT_LISTEN; | ||
297 | |||
298 | done: | ||
299 | release_sock(sk); | ||
300 | return err; | ||
301 | } | ||
302 | |||
303 | static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags) | ||
304 | { | ||
305 | DECLARE_WAITQUEUE(wait, current); | ||
306 | struct sock *sk = sock->sk, *nsk; | ||
307 | long timeo; | ||
308 | int err = 0; | ||
309 | |||
310 | lock_sock_nested(sk, SINGLE_DEPTH_NESTING); | ||
311 | |||
312 | if (sk->sk_state != BT_LISTEN) { | ||
313 | err = -EBADFD; | ||
314 | goto done; | ||
315 | } | ||
316 | |||
317 | timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK); | ||
318 | |||
319 | BT_DBG("sk %p timeo %ld", sk, timeo); | ||
320 | |||
321 | /* Wait for an incoming connection. (wake-one). */ | ||
322 | add_wait_queue_exclusive(sk_sleep(sk), &wait); | ||
323 | while (!(nsk = bt_accept_dequeue(sk, newsock))) { | ||
324 | set_current_state(TASK_INTERRUPTIBLE); | ||
325 | if (!timeo) { | ||
326 | err = -EAGAIN; | ||
327 | break; | ||
328 | } | ||
329 | |||
330 | release_sock(sk); | ||
331 | timeo = schedule_timeout(timeo); | ||
332 | lock_sock_nested(sk, SINGLE_DEPTH_NESTING); | ||
333 | |||
334 | if (sk->sk_state != BT_LISTEN) { | ||
335 | err = -EBADFD; | ||
336 | break; | ||
337 | } | ||
338 | |||
339 | if (signal_pending(current)) { | ||
340 | err = sock_intr_errno(timeo); | ||
341 | break; | ||
342 | } | ||
343 | } | ||
344 | set_current_state(TASK_RUNNING); | ||
345 | remove_wait_queue(sk_sleep(sk), &wait); | ||
346 | |||
347 | if (err) | ||
348 | goto done; | ||
349 | |||
350 | newsock->state = SS_CONNECTED; | ||
351 | |||
352 | BT_DBG("new socket %p", nsk); | ||
353 | |||
354 | done: | ||
355 | release_sock(sk); | ||
356 | return err; | ||
357 | } | ||
358 | |||
359 | static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer) | ||
360 | { | ||
361 | struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr; | ||
362 | struct sock *sk = sock->sk; | ||
363 | |||
364 | BT_DBG("sock %p, sk %p", sock, sk); | ||
365 | |||
366 | addr->sa_family = AF_BLUETOOTH; | ||
367 | *len = sizeof(struct sockaddr_l2); | ||
368 | |||
369 | if (peer) { | ||
370 | la->l2_psm = l2cap_pi(sk)->psm; | ||
371 | bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst); | ||
372 | la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid); | ||
373 | } else { | ||
374 | la->l2_psm = l2cap_pi(sk)->sport; | ||
375 | bacpy(&la->l2_bdaddr, &bt_sk(sk)->src); | ||
376 | la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid); | ||
377 | } | ||
378 | |||
379 | return 0; | ||
380 | } | ||
381 | |||
382 | static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __user *optval, int __user *optlen) | ||
383 | { | ||
384 | struct sock *sk = sock->sk; | ||
385 | struct l2cap_options opts; | ||
386 | struct l2cap_conninfo cinfo; | ||
387 | int len, err = 0; | ||
388 | u32 opt; | ||
389 | |||
390 | BT_DBG("sk %p", sk); | ||
391 | |||
392 | if (get_user(len, optlen)) | ||
393 | return -EFAULT; | ||
394 | |||
395 | lock_sock(sk); | ||
396 | |||
397 | switch (optname) { | ||
398 | case L2CAP_OPTIONS: | ||
399 | memset(&opts, 0, sizeof(opts)); | ||
400 | opts.imtu = l2cap_pi(sk)->imtu; | ||
401 | opts.omtu = l2cap_pi(sk)->omtu; | ||
402 | opts.flush_to = l2cap_pi(sk)->flush_to; | ||
403 | opts.mode = l2cap_pi(sk)->mode; | ||
404 | opts.fcs = l2cap_pi(sk)->fcs; | ||
405 | opts.max_tx = l2cap_pi(sk)->max_tx; | ||
406 | opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win; | ||
407 | |||
408 | len = min_t(unsigned int, len, sizeof(opts)); | ||
409 | if (copy_to_user(optval, (char *) &opts, len)) | ||
410 | err = -EFAULT; | ||
411 | |||
412 | break; | ||
413 | |||
414 | case L2CAP_LM: | ||
415 | switch (l2cap_pi(sk)->sec_level) { | ||
416 | case BT_SECURITY_LOW: | ||
417 | opt = L2CAP_LM_AUTH; | ||
418 | break; | ||
419 | case BT_SECURITY_MEDIUM: | ||
420 | opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT; | ||
421 | break; | ||
422 | case BT_SECURITY_HIGH: | ||
423 | opt = L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT | | ||
424 | L2CAP_LM_SECURE; | ||
425 | break; | ||
426 | default: | ||
427 | opt = 0; | ||
428 | break; | ||
429 | } | ||
430 | |||
431 | if (l2cap_pi(sk)->role_switch) | ||
432 | opt |= L2CAP_LM_MASTER; | ||
433 | |||
434 | if (l2cap_pi(sk)->force_reliable) | ||
435 | opt |= L2CAP_LM_RELIABLE; | ||
436 | |||
437 | if (put_user(opt, (u32 __user *) optval)) | ||
438 | err = -EFAULT; | ||
439 | break; | ||
440 | |||
441 | case L2CAP_CONNINFO: | ||
442 | if (sk->sk_state != BT_CONNECTED && | ||
443 | !(sk->sk_state == BT_CONNECT2 && | ||
444 | bt_sk(sk)->defer_setup)) { | ||
445 | err = -ENOTCONN; | ||
446 | break; | ||
447 | } | ||
448 | |||
449 | cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle; | ||
450 | memcpy(cinfo.dev_class, l2cap_pi(sk)->conn->hcon->dev_class, 3); | ||
451 | |||
452 | len = min_t(unsigned int, len, sizeof(cinfo)); | ||
453 | if (copy_to_user(optval, (char *) &cinfo, len)) | ||
454 | err = -EFAULT; | ||
455 | |||
456 | break; | ||
457 | |||
458 | default: | ||
459 | err = -ENOPROTOOPT; | ||
460 | break; | ||
461 | } | ||
462 | |||
463 | release_sock(sk); | ||
464 | return err; | ||
465 | } | ||
466 | |||
467 | static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen) | ||
468 | { | ||
469 | struct sock *sk = sock->sk; | ||
470 | struct bt_security sec; | ||
471 | int len, err = 0; | ||
472 | |||
473 | BT_DBG("sk %p", sk); | ||
474 | |||
475 | if (level == SOL_L2CAP) | ||
476 | return l2cap_sock_getsockopt_old(sock, optname, optval, optlen); | ||
477 | |||
478 | if (level != SOL_BLUETOOTH) | ||
479 | return -ENOPROTOOPT; | ||
480 | |||
481 | if (get_user(len, optlen)) | ||
482 | return -EFAULT; | ||
483 | |||
484 | lock_sock(sk); | ||
485 | |||
486 | switch (optname) { | ||
487 | case BT_SECURITY: | ||
488 | if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM | ||
489 | && sk->sk_type != SOCK_RAW) { | ||
490 | err = -EINVAL; | ||
491 | break; | ||
492 | } | ||
493 | |||
494 | sec.level = l2cap_pi(sk)->sec_level; | ||
495 | |||
496 | len = min_t(unsigned int, len, sizeof(sec)); | ||
497 | if (copy_to_user(optval, (char *) &sec, len)) | ||
498 | err = -EFAULT; | ||
499 | |||
500 | break; | ||
501 | |||
502 | case BT_DEFER_SETUP: | ||
503 | if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) { | ||
504 | err = -EINVAL; | ||
505 | break; | ||
506 | } | ||
507 | |||
508 | if (put_user(bt_sk(sk)->defer_setup, (u32 __user *) optval)) | ||
509 | err = -EFAULT; | ||
510 | |||
511 | break; | ||
512 | |||
513 | case BT_FLUSHABLE: | ||
514 | if (put_user(l2cap_pi(sk)->flushable, (u32 __user *) optval)) | ||
515 | err = -EFAULT; | ||
516 | |||
517 | break; | ||
518 | |||
519 | default: | ||
520 | err = -ENOPROTOOPT; | ||
521 | break; | ||
522 | } | ||
523 | |||
524 | release_sock(sk); | ||
525 | return err; | ||
526 | } | ||
527 | |||
528 | static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen) | ||
529 | { | ||
530 | struct sock *sk = sock->sk; | ||
531 | struct l2cap_options opts; | ||
532 | int len, err = 0; | ||
533 | u32 opt; | ||
534 | |||
535 | BT_DBG("sk %p", sk); | ||
536 | |||
537 | lock_sock(sk); | ||
538 | |||
539 | switch (optname) { | ||
540 | case L2CAP_OPTIONS: | ||
541 | if (sk->sk_state == BT_CONNECTED) { | ||
542 | err = -EINVAL; | ||
543 | break; | ||
544 | } | ||
545 | |||
546 | opts.imtu = l2cap_pi(sk)->imtu; | ||
547 | opts.omtu = l2cap_pi(sk)->omtu; | ||
548 | opts.flush_to = l2cap_pi(sk)->flush_to; | ||
549 | opts.mode = l2cap_pi(sk)->mode; | ||
550 | opts.fcs = l2cap_pi(sk)->fcs; | ||
551 | opts.max_tx = l2cap_pi(sk)->max_tx; | ||
552 | opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win; | ||
553 | |||
554 | len = min_t(unsigned int, sizeof(opts), optlen); | ||
555 | if (copy_from_user((char *) &opts, optval, len)) { | ||
556 | err = -EFAULT; | ||
557 | break; | ||
558 | } | ||
559 | |||
560 | if (opts.txwin_size > L2CAP_DEFAULT_TX_WINDOW) { | ||
561 | err = -EINVAL; | ||
562 | break; | ||
563 | } | ||
564 | |||
565 | l2cap_pi(sk)->mode = opts.mode; | ||
566 | switch (l2cap_pi(sk)->mode) { | ||
567 | case L2CAP_MODE_BASIC: | ||
568 | l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_STATE2_DEVICE; | ||
569 | break; | ||
570 | case L2CAP_MODE_ERTM: | ||
571 | case L2CAP_MODE_STREAMING: | ||
572 | if (!disable_ertm) | ||
573 | break; | ||
574 | /* fall through */ | ||
575 | default: | ||
576 | err = -EINVAL; | ||
577 | break; | ||
578 | } | ||
579 | |||
580 | l2cap_pi(sk)->imtu = opts.imtu; | ||
581 | l2cap_pi(sk)->omtu = opts.omtu; | ||
582 | l2cap_pi(sk)->fcs = opts.fcs; | ||
583 | l2cap_pi(sk)->max_tx = opts.max_tx; | ||
584 | l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size; | ||
585 | break; | ||
586 | |||
587 | case L2CAP_LM: | ||
588 | if (get_user(opt, (u32 __user *) optval)) { | ||
589 | err = -EFAULT; | ||
590 | break; | ||
591 | } | ||
592 | |||
593 | if (opt & L2CAP_LM_AUTH) | ||
594 | l2cap_pi(sk)->sec_level = BT_SECURITY_LOW; | ||
595 | if (opt & L2CAP_LM_ENCRYPT) | ||
596 | l2cap_pi(sk)->sec_level = BT_SECURITY_MEDIUM; | ||
597 | if (opt & L2CAP_LM_SECURE) | ||
598 | l2cap_pi(sk)->sec_level = BT_SECURITY_HIGH; | ||
599 | |||
600 | l2cap_pi(sk)->role_switch = (opt & L2CAP_LM_MASTER); | ||
601 | l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE); | ||
602 | break; | ||
603 | |||
604 | default: | ||
605 | err = -ENOPROTOOPT; | ||
606 | break; | ||
607 | } | ||
608 | |||
609 | release_sock(sk); | ||
610 | return err; | ||
611 | } | ||
612 | |||
613 | static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen) | ||
614 | { | ||
615 | struct sock *sk = sock->sk; | ||
616 | struct bt_security sec; | ||
617 | int len, err = 0; | ||
618 | u32 opt; | ||
619 | |||
620 | BT_DBG("sk %p", sk); | ||
621 | |||
622 | if (level == SOL_L2CAP) | ||
623 | return l2cap_sock_setsockopt_old(sock, optname, optval, optlen); | ||
624 | |||
625 | if (level != SOL_BLUETOOTH) | ||
626 | return -ENOPROTOOPT; | ||
627 | |||
628 | lock_sock(sk); | ||
629 | |||
630 | switch (optname) { | ||
631 | case BT_SECURITY: | ||
632 | if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM | ||
633 | && sk->sk_type != SOCK_RAW) { | ||
634 | err = -EINVAL; | ||
635 | break; | ||
636 | } | ||
637 | |||
638 | sec.level = BT_SECURITY_LOW; | ||
639 | |||
640 | len = min_t(unsigned int, sizeof(sec), optlen); | ||
641 | if (copy_from_user((char *) &sec, optval, len)) { | ||
642 | err = -EFAULT; | ||
643 | break; | ||
644 | } | ||
645 | |||
646 | if (sec.level < BT_SECURITY_LOW || | ||
647 | sec.level > BT_SECURITY_HIGH) { | ||
648 | err = -EINVAL; | ||
649 | break; | ||
650 | } | ||
651 | |||
652 | l2cap_pi(sk)->sec_level = sec.level; | ||
653 | break; | ||
654 | |||
655 | case BT_DEFER_SETUP: | ||
656 | if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) { | ||
657 | err = -EINVAL; | ||
658 | break; | ||
659 | } | ||
660 | |||
661 | if (get_user(opt, (u32 __user *) optval)) { | ||
662 | err = -EFAULT; | ||
663 | break; | ||
664 | } | ||
665 | |||
666 | bt_sk(sk)->defer_setup = opt; | ||
667 | break; | ||
668 | |||
669 | case BT_FLUSHABLE: | ||
670 | if (get_user(opt, (u32 __user *) optval)) { | ||
671 | err = -EFAULT; | ||
672 | break; | ||
673 | } | ||
674 | |||
675 | if (opt > BT_FLUSHABLE_ON) { | ||
676 | err = -EINVAL; | ||
677 | break; | ||
678 | } | ||
679 | |||
680 | if (opt == BT_FLUSHABLE_OFF) { | ||
681 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | ||
682 | /* proceed futher only when we have l2cap_conn and | ||
683 | No Flush support in the LM */ | ||
684 | if (!conn || !lmp_no_flush_capable(conn->hcon->hdev)) { | ||
685 | err = -EINVAL; | ||
686 | break; | ||
687 | } | ||
688 | } | ||
689 | |||
690 | l2cap_pi(sk)->flushable = opt; | ||
691 | break; | ||
692 | |||
693 | default: | ||
694 | err = -ENOPROTOOPT; | ||
695 | break; | ||
696 | } | ||
697 | |||
698 | release_sock(sk); | ||
699 | return err; | ||
700 | } | ||
701 | |||
702 | static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len) | ||
703 | { | ||
704 | struct sock *sk = sock->sk; | ||
705 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
706 | struct sk_buff *skb; | ||
707 | u16 control; | ||
708 | int err; | ||
709 | |||
710 | BT_DBG("sock %p, sk %p", sock, sk); | ||
711 | |||
712 | err = sock_error(sk); | ||
713 | if (err) | ||
714 | return err; | ||
715 | |||
716 | if (msg->msg_flags & MSG_OOB) | ||
717 | return -EOPNOTSUPP; | ||
718 | |||
719 | lock_sock(sk); | ||
720 | |||
721 | if (sk->sk_state != BT_CONNECTED) { | ||
722 | err = -ENOTCONN; | ||
723 | goto done; | ||
724 | } | ||
725 | |||
726 | /* Connectionless channel */ | ||
727 | if (sk->sk_type == SOCK_DGRAM) { | ||
728 | skb = l2cap_create_connless_pdu(sk, msg, len); | ||
729 | if (IS_ERR(skb)) { | ||
730 | err = PTR_ERR(skb); | ||
731 | } else { | ||
732 | l2cap_do_send(sk, skb); | ||
733 | err = len; | ||
734 | } | ||
735 | goto done; | ||
736 | } | ||
737 | |||
738 | switch (pi->mode) { | ||
739 | case L2CAP_MODE_BASIC: | ||
740 | /* Check outgoing MTU */ | ||
741 | if (len > pi->omtu) { | ||
742 | err = -EMSGSIZE; | ||
743 | goto done; | ||
744 | } | ||
745 | |||
746 | /* Create a basic PDU */ | ||
747 | skb = l2cap_create_basic_pdu(sk, msg, len); | ||
748 | if (IS_ERR(skb)) { | ||
749 | err = PTR_ERR(skb); | ||
750 | goto done; | ||
751 | } | ||
752 | |||
753 | l2cap_do_send(sk, skb); | ||
754 | err = len; | ||
755 | break; | ||
756 | |||
757 | case L2CAP_MODE_ERTM: | ||
758 | case L2CAP_MODE_STREAMING: | ||
759 | /* Entire SDU fits into one PDU */ | ||
760 | if (len <= pi->remote_mps) { | ||
761 | control = L2CAP_SDU_UNSEGMENTED; | ||
762 | skb = l2cap_create_iframe_pdu(sk, msg, len, control, 0); | ||
763 | if (IS_ERR(skb)) { | ||
764 | err = PTR_ERR(skb); | ||
765 | goto done; | ||
766 | } | ||
767 | __skb_queue_tail(TX_QUEUE(sk), skb); | ||
768 | |||
769 | if (sk->sk_send_head == NULL) | ||
770 | sk->sk_send_head = skb; | ||
771 | |||
772 | } else { | ||
773 | /* Segment SDU into multiples PDUs */ | ||
774 | err = l2cap_sar_segment_sdu(sk, msg, len); | ||
775 | if (err < 0) | ||
776 | goto done; | ||
777 | } | ||
778 | |||
779 | if (pi->mode == L2CAP_MODE_STREAMING) { | ||
780 | l2cap_streaming_send(sk); | ||
781 | } else { | ||
782 | if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) && | ||
783 | (pi->conn_state & L2CAP_CONN_WAIT_F)) { | ||
784 | err = len; | ||
785 | break; | ||
786 | } | ||
787 | err = l2cap_ertm_send(sk); | ||
788 | } | ||
789 | |||
790 | if (err >= 0) | ||
791 | err = len; | ||
792 | break; | ||
793 | |||
794 | default: | ||
795 | BT_DBG("bad state %1.1x", pi->mode); | ||
796 | err = -EBADFD; | ||
797 | } | ||
798 | |||
799 | done: | ||
800 | release_sock(sk); | ||
801 | return err; | ||
802 | } | ||
803 | |||
804 | static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags) | ||
805 | { | ||
806 | struct sock *sk = sock->sk; | ||
807 | |||
808 | lock_sock(sk); | ||
809 | |||
810 | if (sk->sk_state == BT_CONNECT2 && bt_sk(sk)->defer_setup) { | ||
811 | struct l2cap_conn_rsp rsp; | ||
812 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | ||
813 | u8 buf[128]; | ||
814 | |||
815 | sk->sk_state = BT_CONFIG; | ||
816 | |||
817 | rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); | ||
818 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); | ||
819 | rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS); | ||
820 | rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); | ||
821 | l2cap_send_cmd(l2cap_pi(sk)->conn, l2cap_pi(sk)->ident, | ||
822 | L2CAP_CONN_RSP, sizeof(rsp), &rsp); | ||
823 | |||
824 | if (l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) { | ||
825 | release_sock(sk); | ||
826 | return 0; | ||
827 | } | ||
828 | |||
829 | l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT; | ||
830 | l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ, | ||
831 | l2cap_build_conf_req(sk, buf), buf); | ||
832 | l2cap_pi(sk)->num_conf_req++; | ||
833 | |||
834 | release_sock(sk); | ||
835 | return 0; | ||
836 | } | ||
837 | |||
838 | release_sock(sk); | ||
839 | |||
840 | if (sock->type == SOCK_STREAM) | ||
841 | return bt_sock_stream_recvmsg(iocb, sock, msg, len, flags); | ||
842 | |||
843 | return bt_sock_recvmsg(iocb, sock, msg, len, flags); | ||
844 | } | ||
845 | |||
846 | /* Kill socket (only if zapped and orphan) | ||
847 | * Must be called on unlocked socket. | ||
848 | */ | ||
849 | void l2cap_sock_kill(struct sock *sk) | ||
850 | { | ||
851 | if (!sock_flag(sk, SOCK_ZAPPED) || sk->sk_socket) | ||
852 | return; | ||
853 | |||
854 | BT_DBG("sk %p state %d", sk, sk->sk_state); | ||
855 | |||
856 | /* Kill poor orphan */ | ||
857 | bt_sock_unlink(&l2cap_sk_list, sk); | ||
858 | sock_set_flag(sk, SOCK_DEAD); | ||
859 | sock_put(sk); | ||
860 | } | ||
861 | |||
862 | /* Must be called on unlocked socket. */ | ||
863 | static void l2cap_sock_close(struct sock *sk) | ||
864 | { | ||
865 | l2cap_sock_clear_timer(sk); | ||
866 | lock_sock(sk); | ||
867 | __l2cap_sock_close(sk, ECONNRESET); | ||
868 | release_sock(sk); | ||
869 | l2cap_sock_kill(sk); | ||
870 | } | ||
871 | |||
872 | static void l2cap_sock_cleanup_listen(struct sock *parent) | ||
873 | { | ||
874 | struct sock *sk; | ||
875 | |||
876 | BT_DBG("parent %p", parent); | ||
877 | |||
878 | /* Close not yet accepted channels */ | ||
879 | while ((sk = bt_accept_dequeue(parent, NULL))) | ||
880 | l2cap_sock_close(sk); | ||
881 | |||
882 | parent->sk_state = BT_CLOSED; | ||
883 | sock_set_flag(parent, SOCK_ZAPPED); | ||
884 | } | ||
885 | |||
886 | void __l2cap_sock_close(struct sock *sk, int reason) | ||
887 | { | ||
888 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | ||
889 | |||
890 | BT_DBG("sk %p state %d socket %p", sk, sk->sk_state, sk->sk_socket); | ||
891 | |||
892 | switch (sk->sk_state) { | ||
893 | case BT_LISTEN: | ||
894 | l2cap_sock_cleanup_listen(sk); | ||
895 | break; | ||
896 | |||
897 | case BT_CONNECTED: | ||
898 | case BT_CONFIG: | ||
899 | if ((sk->sk_type == SOCK_SEQPACKET || | ||
900 | sk->sk_type == SOCK_STREAM) && | ||
901 | conn->hcon->type == ACL_LINK) { | ||
902 | l2cap_sock_set_timer(sk, sk->sk_sndtimeo); | ||
903 | l2cap_send_disconn_req(conn, sk, reason); | ||
904 | } else | ||
905 | l2cap_chan_del(sk, reason); | ||
906 | break; | ||
907 | |||
908 | case BT_CONNECT2: | ||
909 | if ((sk->sk_type == SOCK_SEQPACKET || | ||
910 | sk->sk_type == SOCK_STREAM) && | ||
911 | conn->hcon->type == ACL_LINK) { | ||
912 | struct l2cap_conn_rsp rsp; | ||
913 | __u16 result; | ||
914 | |||
915 | if (bt_sk(sk)->defer_setup) | ||
916 | result = L2CAP_CR_SEC_BLOCK; | ||
917 | else | ||
918 | result = L2CAP_CR_BAD_PSM; | ||
919 | |||
920 | rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); | ||
921 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); | ||
922 | rsp.result = cpu_to_le16(result); | ||
923 | rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); | ||
924 | l2cap_send_cmd(conn, l2cap_pi(sk)->ident, | ||
925 | L2CAP_CONN_RSP, sizeof(rsp), &rsp); | ||
926 | } else | ||
927 | l2cap_chan_del(sk, reason); | ||
928 | break; | ||
929 | |||
930 | case BT_CONNECT: | ||
931 | case BT_DISCONN: | ||
932 | l2cap_chan_del(sk, reason); | ||
933 | break; | ||
934 | |||
935 | default: | ||
936 | sock_set_flag(sk, SOCK_ZAPPED); | ||
937 | break; | ||
938 | } | ||
939 | } | ||
940 | |||
941 | static int l2cap_sock_shutdown(struct socket *sock, int how) | ||
942 | { | ||
943 | struct sock *sk = sock->sk; | ||
944 | int err = 0; | ||
945 | |||
946 | BT_DBG("sock %p, sk %p", sock, sk); | ||
947 | |||
948 | if (!sk) | ||
949 | return 0; | ||
950 | |||
951 | lock_sock(sk); | ||
952 | if (!sk->sk_shutdown) { | ||
953 | if (l2cap_pi(sk)->mode == L2CAP_MODE_ERTM) | ||
954 | err = __l2cap_wait_ack(sk); | ||
955 | |||
956 | sk->sk_shutdown = SHUTDOWN_MASK; | ||
957 | l2cap_sock_clear_timer(sk); | ||
958 | __l2cap_sock_close(sk, 0); | ||
959 | |||
960 | if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) | ||
961 | err = bt_sock_wait_state(sk, BT_CLOSED, | ||
962 | sk->sk_lingertime); | ||
963 | } | ||
964 | |||
965 | if (!err && sk->sk_err) | ||
966 | err = -sk->sk_err; | ||
967 | |||
968 | release_sock(sk); | ||
969 | return err; | ||
970 | } | ||
971 | |||
972 | static int l2cap_sock_release(struct socket *sock) | ||
973 | { | ||
974 | struct sock *sk = sock->sk; | ||
975 | int err; | ||
976 | |||
977 | BT_DBG("sock %p, sk %p", sock, sk); | ||
978 | |||
979 | if (!sk) | ||
980 | return 0; | ||
981 | |||
982 | err = l2cap_sock_shutdown(sock, 2); | ||
983 | |||
984 | sock_orphan(sk); | ||
985 | l2cap_sock_kill(sk); | ||
986 | return err; | ||
987 | } | ||
988 | |||
989 | static void l2cap_sock_destruct(struct sock *sk) | ||
990 | { | ||
991 | BT_DBG("sk %p", sk); | ||
992 | |||
993 | skb_queue_purge(&sk->sk_receive_queue); | ||
994 | skb_queue_purge(&sk->sk_write_queue); | ||
995 | } | ||
996 | |||
997 | void l2cap_sock_init(struct sock *sk, struct sock *parent) | ||
998 | { | ||
999 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
1000 | |||
1001 | BT_DBG("sk %p", sk); | ||
1002 | |||
1003 | if (parent) { | ||
1004 | sk->sk_type = parent->sk_type; | ||
1005 | bt_sk(sk)->defer_setup = bt_sk(parent)->defer_setup; | ||
1006 | |||
1007 | pi->imtu = l2cap_pi(parent)->imtu; | ||
1008 | pi->omtu = l2cap_pi(parent)->omtu; | ||
1009 | pi->conf_state = l2cap_pi(parent)->conf_state; | ||
1010 | pi->mode = l2cap_pi(parent)->mode; | ||
1011 | pi->fcs = l2cap_pi(parent)->fcs; | ||
1012 | pi->max_tx = l2cap_pi(parent)->max_tx; | ||
1013 | pi->tx_win = l2cap_pi(parent)->tx_win; | ||
1014 | pi->sec_level = l2cap_pi(parent)->sec_level; | ||
1015 | pi->role_switch = l2cap_pi(parent)->role_switch; | ||
1016 | pi->force_reliable = l2cap_pi(parent)->force_reliable; | ||
1017 | pi->flushable = l2cap_pi(parent)->flushable; | ||
1018 | } else { | ||
1019 | pi->imtu = L2CAP_DEFAULT_MTU; | ||
1020 | pi->omtu = 0; | ||
1021 | if (!disable_ertm && sk->sk_type == SOCK_STREAM) { | ||
1022 | pi->mode = L2CAP_MODE_ERTM; | ||
1023 | pi->conf_state |= L2CAP_CONF_STATE2_DEVICE; | ||
1024 | } else { | ||
1025 | pi->mode = L2CAP_MODE_BASIC; | ||
1026 | } | ||
1027 | pi->max_tx = L2CAP_DEFAULT_MAX_TX; | ||
1028 | pi->fcs = L2CAP_FCS_CRC16; | ||
1029 | pi->tx_win = L2CAP_DEFAULT_TX_WINDOW; | ||
1030 | pi->sec_level = BT_SECURITY_LOW; | ||
1031 | pi->role_switch = 0; | ||
1032 | pi->force_reliable = 0; | ||
1033 | pi->flushable = BT_FLUSHABLE_OFF; | ||
1034 | } | ||
1035 | |||
1036 | /* Default config options */ | ||
1037 | pi->conf_len = 0; | ||
1038 | pi->flush_to = L2CAP_DEFAULT_FLUSH_TO; | ||
1039 | skb_queue_head_init(TX_QUEUE(sk)); | ||
1040 | skb_queue_head_init(SREJ_QUEUE(sk)); | ||
1041 | skb_queue_head_init(BUSY_QUEUE(sk)); | ||
1042 | INIT_LIST_HEAD(SREJ_LIST(sk)); | ||
1043 | } | ||
1044 | |||
1045 | static struct proto l2cap_proto = { | ||
1046 | .name = "L2CAP", | ||
1047 | .owner = THIS_MODULE, | ||
1048 | .obj_size = sizeof(struct l2cap_pinfo) | ||
1049 | }; | ||
1050 | |||
1051 | struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int proto, gfp_t prio) | ||
1052 | { | ||
1053 | struct sock *sk; | ||
1054 | |||
1055 | sk = sk_alloc(net, PF_BLUETOOTH, prio, &l2cap_proto); | ||
1056 | if (!sk) | ||
1057 | return NULL; | ||
1058 | |||
1059 | sock_init_data(sock, sk); | ||
1060 | INIT_LIST_HEAD(&bt_sk(sk)->accept_q); | ||
1061 | |||
1062 | sk->sk_destruct = l2cap_sock_destruct; | ||
1063 | sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT); | ||
1064 | |||
1065 | sock_reset_flag(sk, SOCK_ZAPPED); | ||
1066 | |||
1067 | sk->sk_protocol = proto; | ||
1068 | sk->sk_state = BT_OPEN; | ||
1069 | |||
1070 | setup_timer(&sk->sk_timer, l2cap_sock_timeout, (unsigned long) sk); | ||
1071 | |||
1072 | bt_sock_link(&l2cap_sk_list, sk); | ||
1073 | return sk; | ||
1074 | } | ||
1075 | |||
1076 | static int l2cap_sock_create(struct net *net, struct socket *sock, int protocol, | ||
1077 | int kern) | ||
1078 | { | ||
1079 | struct sock *sk; | ||
1080 | |||
1081 | BT_DBG("sock %p", sock); | ||
1082 | |||
1083 | sock->state = SS_UNCONNECTED; | ||
1084 | |||
1085 | if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_STREAM && | ||
1086 | sock->type != SOCK_DGRAM && sock->type != SOCK_RAW) | ||
1087 | return -ESOCKTNOSUPPORT; | ||
1088 | |||
1089 | if (sock->type == SOCK_RAW && !kern && !capable(CAP_NET_RAW)) | ||
1090 | return -EPERM; | ||
1091 | |||
1092 | sock->ops = &l2cap_sock_ops; | ||
1093 | |||
1094 | sk = l2cap_sock_alloc(net, sock, protocol, GFP_ATOMIC); | ||
1095 | if (!sk) | ||
1096 | return -ENOMEM; | ||
1097 | |||
1098 | l2cap_sock_init(sk, NULL); | ||
1099 | return 0; | ||
1100 | } | ||
1101 | |||
1102 | const struct proto_ops l2cap_sock_ops = { | ||
1103 | .family = PF_BLUETOOTH, | ||
1104 | .owner = THIS_MODULE, | ||
1105 | .release = l2cap_sock_release, | ||
1106 | .bind = l2cap_sock_bind, | ||
1107 | .connect = l2cap_sock_connect, | ||
1108 | .listen = l2cap_sock_listen, | ||
1109 | .accept = l2cap_sock_accept, | ||
1110 | .getname = l2cap_sock_getname, | ||
1111 | .sendmsg = l2cap_sock_sendmsg, | ||
1112 | .recvmsg = l2cap_sock_recvmsg, | ||
1113 | .poll = bt_sock_poll, | ||
1114 | .ioctl = bt_sock_ioctl, | ||
1115 | .mmap = sock_no_mmap, | ||
1116 | .socketpair = sock_no_socketpair, | ||
1117 | .shutdown = l2cap_sock_shutdown, | ||
1118 | .setsockopt = l2cap_sock_setsockopt, | ||
1119 | .getsockopt = l2cap_sock_getsockopt | ||
1120 | }; | ||
1121 | |||
1122 | static const struct net_proto_family l2cap_sock_family_ops = { | ||
1123 | .family = PF_BLUETOOTH, | ||
1124 | .owner = THIS_MODULE, | ||
1125 | .create = l2cap_sock_create, | ||
1126 | }; | ||
1127 | |||
1128 | int __init l2cap_init_sockets(void) | ||
1129 | { | ||
1130 | int err; | ||
1131 | |||
1132 | err = proto_register(&l2cap_proto, 0); | ||
1133 | if (err < 0) | ||
1134 | return err; | ||
1135 | |||
1136 | err = bt_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops); | ||
1137 | if (err < 0) | ||
1138 | goto error; | ||
1139 | |||
1140 | BT_INFO("L2CAP socket layer initialized"); | ||
1141 | |||
1142 | return 0; | ||
1143 | |||
1144 | error: | ||
1145 | BT_ERR("L2CAP socket registration failed"); | ||
1146 | proto_unregister(&l2cap_proto); | ||
1147 | return err; | ||
1148 | } | ||
1149 | |||
1150 | void l2cap_cleanup_sockets(void) | ||
1151 | { | ||
1152 | if (bt_sock_unregister(BTPROTO_L2CAP) < 0) | ||
1153 | BT_ERR("L2CAP socket unregistration failed"); | ||
1154 | |||
1155 | proto_unregister(&l2cap_proto); | ||
1156 | } | ||
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index f827fd908380..f5ef7a3374c7 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -22,7 +22,7 @@ | |||
22 | 22 | ||
23 | /* Bluetooth HCI Management interface */ | 23 | /* Bluetooth HCI Management interface */ |
24 | 24 | ||
25 | #include <asm/uaccess.h> | 25 | #include <linux/uaccess.h> |
26 | #include <asm/unaligned.h> | 26 | #include <asm/unaligned.h> |
27 | 27 | ||
28 | #include <net/bluetooth/bluetooth.h> | 28 | #include <net/bluetooth/bluetooth.h> |
@@ -32,6 +32,16 @@ | |||
32 | #define MGMT_VERSION 0 | 32 | #define MGMT_VERSION 0 |
33 | #define MGMT_REVISION 1 | 33 | #define MGMT_REVISION 1 |
34 | 34 | ||
35 | struct pending_cmd { | ||
36 | struct list_head list; | ||
37 | __u16 opcode; | ||
38 | int index; | ||
39 | void *cmd; | ||
40 | struct sock *sk; | ||
41 | }; | ||
42 | |||
43 | LIST_HEAD(cmd_list); | ||
44 | |||
35 | static int cmd_status(struct sock *sk, u16 cmd, u8 status) | 45 | static int cmd_status(struct sock *sk, u16 cmd, u8 status) |
36 | { | 46 | { |
37 | struct sk_buff *skb; | 47 | struct sk_buff *skb; |
@@ -59,29 +69,26 @@ static int cmd_status(struct sock *sk, u16 cmd, u8 status) | |||
59 | return 0; | 69 | return 0; |
60 | } | 70 | } |
61 | 71 | ||
62 | static int read_version(struct sock *sk) | 72 | static int cmd_complete(struct sock *sk, u16 cmd, void *rp, size_t rp_len) |
63 | { | 73 | { |
64 | struct sk_buff *skb; | 74 | struct sk_buff *skb; |
65 | struct mgmt_hdr *hdr; | 75 | struct mgmt_hdr *hdr; |
66 | struct mgmt_ev_cmd_complete *ev; | 76 | struct mgmt_ev_cmd_complete *ev; |
67 | struct mgmt_rp_read_version *rp; | ||
68 | 77 | ||
69 | BT_DBG("sock %p", sk); | 78 | BT_DBG("sock %p", sk); |
70 | 79 | ||
71 | skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + sizeof(*rp), GFP_ATOMIC); | 80 | skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + rp_len, GFP_ATOMIC); |
72 | if (!skb) | 81 | if (!skb) |
73 | return -ENOMEM; | 82 | return -ENOMEM; |
74 | 83 | ||
75 | hdr = (void *) skb_put(skb, sizeof(*hdr)); | 84 | hdr = (void *) skb_put(skb, sizeof(*hdr)); |
76 | hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE); | ||
77 | hdr->len = cpu_to_le16(sizeof(*ev) + sizeof(*rp)); | ||
78 | 85 | ||
79 | ev = (void *) skb_put(skb, sizeof(*ev)); | 86 | hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE); |
80 | put_unaligned_le16(MGMT_OP_READ_VERSION, &ev->opcode); | 87 | hdr->len = cpu_to_le16(sizeof(*ev) + rp_len); |
81 | 88 | ||
82 | rp = (void *) skb_put(skb, sizeof(*rp)); | 89 | ev = (void *) skb_put(skb, sizeof(*ev) + rp_len); |
83 | rp->version = MGMT_VERSION; | 90 | put_unaligned_le16(cmd, &ev->opcode); |
84 | put_unaligned_le16(MGMT_REVISION, &rp->revision); | 91 | memcpy(ev->data, rp, rp_len); |
85 | 92 | ||
86 | if (sock_queue_rcv_skb(sk, skb) < 0) | 93 | if (sock_queue_rcv_skb(sk, skb) < 0) |
87 | kfree_skb(skb); | 94 | kfree_skb(skb); |
@@ -89,16 +96,25 @@ static int read_version(struct sock *sk) | |||
89 | return 0; | 96 | return 0; |
90 | } | 97 | } |
91 | 98 | ||
99 | static int read_version(struct sock *sk) | ||
100 | { | ||
101 | struct mgmt_rp_read_version rp; | ||
102 | |||
103 | BT_DBG("sock %p", sk); | ||
104 | |||
105 | rp.version = MGMT_VERSION; | ||
106 | put_unaligned_le16(MGMT_REVISION, &rp.revision); | ||
107 | |||
108 | return cmd_complete(sk, MGMT_OP_READ_VERSION, &rp, sizeof(rp)); | ||
109 | } | ||
110 | |||
92 | static int read_index_list(struct sock *sk) | 111 | static int read_index_list(struct sock *sk) |
93 | { | 112 | { |
94 | struct sk_buff *skb; | ||
95 | struct mgmt_hdr *hdr; | ||
96 | struct mgmt_ev_cmd_complete *ev; | ||
97 | struct mgmt_rp_read_index_list *rp; | 113 | struct mgmt_rp_read_index_list *rp; |
98 | struct list_head *p; | 114 | struct list_head *p; |
99 | size_t body_len; | 115 | size_t rp_len; |
100 | u16 count; | 116 | u16 count; |
101 | int i; | 117 | int i, err; |
102 | 118 | ||
103 | BT_DBG("sock %p", sk); | 119 | BT_DBG("sock %p", sk); |
104 | 120 | ||
@@ -109,43 +125,43 @@ static int read_index_list(struct sock *sk) | |||
109 | count++; | 125 | count++; |
110 | } | 126 | } |
111 | 127 | ||
112 | body_len = sizeof(*ev) + sizeof(*rp) + (2 * count); | 128 | rp_len = sizeof(*rp) + (2 * count); |
113 | skb = alloc_skb(sizeof(*hdr) + body_len, GFP_ATOMIC); | 129 | rp = kmalloc(rp_len, GFP_ATOMIC); |
114 | if (!skb) | 130 | if (!rp) { |
131 | read_unlock(&hci_dev_list_lock); | ||
115 | return -ENOMEM; | 132 | return -ENOMEM; |
133 | } | ||
116 | 134 | ||
117 | hdr = (void *) skb_put(skb, sizeof(*hdr)); | ||
118 | hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE); | ||
119 | hdr->len = cpu_to_le16(body_len); | ||
120 | |||
121 | ev = (void *) skb_put(skb, sizeof(*ev)); | ||
122 | put_unaligned_le16(MGMT_OP_READ_INDEX_LIST, &ev->opcode); | ||
123 | |||
124 | rp = (void *) skb_put(skb, sizeof(*rp) + (2 * count)); | ||
125 | put_unaligned_le16(count, &rp->num_controllers); | 135 | put_unaligned_le16(count, &rp->num_controllers); |
126 | 136 | ||
127 | i = 0; | 137 | i = 0; |
128 | list_for_each(p, &hci_dev_list) { | 138 | list_for_each(p, &hci_dev_list) { |
129 | struct hci_dev *d = list_entry(p, struct hci_dev, list); | 139 | struct hci_dev *d = list_entry(p, struct hci_dev, list); |
140 | |||
141 | hci_del_off_timer(d); | ||
142 | |||
143 | set_bit(HCI_MGMT, &d->flags); | ||
144 | |||
145 | if (test_bit(HCI_SETUP, &d->flags)) | ||
146 | continue; | ||
147 | |||
130 | put_unaligned_le16(d->id, &rp->index[i++]); | 148 | put_unaligned_le16(d->id, &rp->index[i++]); |
131 | BT_DBG("Added hci%u", d->id); | 149 | BT_DBG("Added hci%u", d->id); |
132 | } | 150 | } |
133 | 151 | ||
134 | read_unlock(&hci_dev_list_lock); | 152 | read_unlock(&hci_dev_list_lock); |
135 | 153 | ||
136 | if (sock_queue_rcv_skb(sk, skb) < 0) | 154 | err = cmd_complete(sk, MGMT_OP_READ_INDEX_LIST, rp, rp_len); |
137 | kfree_skb(skb); | ||
138 | 155 | ||
139 | return 0; | 156 | kfree(rp); |
157 | |||
158 | return err; | ||
140 | } | 159 | } |
141 | 160 | ||
142 | static int read_controller_info(struct sock *sk, unsigned char *data, u16 len) | 161 | static int read_controller_info(struct sock *sk, unsigned char *data, u16 len) |
143 | { | 162 | { |
144 | struct sk_buff *skb; | 163 | struct mgmt_rp_read_info rp; |
145 | struct mgmt_hdr *hdr; | 164 | struct mgmt_cp_read_info *cp = (void *) data; |
146 | struct mgmt_ev_cmd_complete *ev; | ||
147 | struct mgmt_rp_read_info *rp; | ||
148 | struct mgmt_cp_read_info *cp; | ||
149 | struct hci_dev *hdev; | 165 | struct hci_dev *hdev; |
150 | u16 dev_id; | 166 | u16 dev_id; |
151 | 167 | ||
@@ -154,18 +170,333 @@ static int read_controller_info(struct sock *sk, unsigned char *data, u16 len) | |||
154 | if (len != 2) | 170 | if (len != 2) |
155 | return cmd_status(sk, MGMT_OP_READ_INFO, EINVAL); | 171 | return cmd_status(sk, MGMT_OP_READ_INFO, EINVAL); |
156 | 172 | ||
157 | skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + sizeof(*rp), GFP_ATOMIC); | 173 | dev_id = get_unaligned_le16(&cp->index); |
174 | |||
175 | BT_DBG("request for hci%u", dev_id); | ||
176 | |||
177 | hdev = hci_dev_get(dev_id); | ||
178 | if (!hdev) | ||
179 | return cmd_status(sk, MGMT_OP_READ_INFO, ENODEV); | ||
180 | |||
181 | hci_del_off_timer(hdev); | ||
182 | |||
183 | hci_dev_lock_bh(hdev); | ||
184 | |||
185 | set_bit(HCI_MGMT, &hdev->flags); | ||
186 | |||
187 | put_unaligned_le16(hdev->id, &rp.index); | ||
188 | rp.type = hdev->dev_type; | ||
189 | |||
190 | rp.powered = test_bit(HCI_UP, &hdev->flags); | ||
191 | rp.connectable = test_bit(HCI_PSCAN, &hdev->flags); | ||
192 | rp.discoverable = test_bit(HCI_ISCAN, &hdev->flags); | ||
193 | rp.pairable = test_bit(HCI_PSCAN, &hdev->flags); | ||
194 | |||
195 | if (test_bit(HCI_AUTH, &hdev->flags)) | ||
196 | rp.sec_mode = 3; | ||
197 | else if (hdev->ssp_mode > 0) | ||
198 | rp.sec_mode = 4; | ||
199 | else | ||
200 | rp.sec_mode = 2; | ||
201 | |||
202 | bacpy(&rp.bdaddr, &hdev->bdaddr); | ||
203 | memcpy(rp.features, hdev->features, 8); | ||
204 | memcpy(rp.dev_class, hdev->dev_class, 3); | ||
205 | put_unaligned_le16(hdev->manufacturer, &rp.manufacturer); | ||
206 | rp.hci_ver = hdev->hci_ver; | ||
207 | put_unaligned_le16(hdev->hci_rev, &rp.hci_rev); | ||
208 | |||
209 | hci_dev_unlock_bh(hdev); | ||
210 | hci_dev_put(hdev); | ||
211 | |||
212 | return cmd_complete(sk, MGMT_OP_READ_INFO, &rp, sizeof(rp)); | ||
213 | } | ||
214 | |||
215 | static void mgmt_pending_free(struct pending_cmd *cmd) | ||
216 | { | ||
217 | sock_put(cmd->sk); | ||
218 | kfree(cmd->cmd); | ||
219 | kfree(cmd); | ||
220 | } | ||
221 | |||
222 | static int mgmt_pending_add(struct sock *sk, u16 opcode, int index, | ||
223 | void *data, u16 len) | ||
224 | { | ||
225 | struct pending_cmd *cmd; | ||
226 | |||
227 | cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC); | ||
228 | if (!cmd) | ||
229 | return -ENOMEM; | ||
230 | |||
231 | cmd->opcode = opcode; | ||
232 | cmd->index = index; | ||
233 | |||
234 | cmd->cmd = kmalloc(len, GFP_ATOMIC); | ||
235 | if (!cmd->cmd) { | ||
236 | kfree(cmd); | ||
237 | return -ENOMEM; | ||
238 | } | ||
239 | |||
240 | memcpy(cmd->cmd, data, len); | ||
241 | |||
242 | cmd->sk = sk; | ||
243 | sock_hold(sk); | ||
244 | |||
245 | list_add(&cmd->list, &cmd_list); | ||
246 | |||
247 | return 0; | ||
248 | } | ||
249 | |||
250 | static void mgmt_pending_foreach(u16 opcode, int index, | ||
251 | void (*cb)(struct pending_cmd *cmd, void *data), | ||
252 | void *data) | ||
253 | { | ||
254 | struct list_head *p, *n; | ||
255 | |||
256 | list_for_each_safe(p, n, &cmd_list) { | ||
257 | struct pending_cmd *cmd; | ||
258 | |||
259 | cmd = list_entry(p, struct pending_cmd, list); | ||
260 | |||
261 | if (cmd->opcode != opcode) | ||
262 | continue; | ||
263 | |||
264 | if (index >= 0 && cmd->index != index) | ||
265 | continue; | ||
266 | |||
267 | cb(cmd, data); | ||
268 | } | ||
269 | } | ||
270 | |||
271 | static struct pending_cmd *mgmt_pending_find(u16 opcode, int index) | ||
272 | { | ||
273 | struct list_head *p; | ||
274 | |||
275 | list_for_each(p, &cmd_list) { | ||
276 | struct pending_cmd *cmd; | ||
277 | |||
278 | cmd = list_entry(p, struct pending_cmd, list); | ||
279 | |||
280 | if (cmd->opcode != opcode) | ||
281 | continue; | ||
282 | |||
283 | if (index >= 0 && cmd->index != index) | ||
284 | continue; | ||
285 | |||
286 | return cmd; | ||
287 | } | ||
288 | |||
289 | return NULL; | ||
290 | } | ||
291 | |||
292 | static void mgmt_pending_remove(u16 opcode, int index) | ||
293 | { | ||
294 | struct pending_cmd *cmd; | ||
295 | |||
296 | cmd = mgmt_pending_find(opcode, index); | ||
297 | if (cmd == NULL) | ||
298 | return; | ||
299 | |||
300 | list_del(&cmd->list); | ||
301 | mgmt_pending_free(cmd); | ||
302 | } | ||
303 | |||
304 | static int set_powered(struct sock *sk, unsigned char *data, u16 len) | ||
305 | { | ||
306 | struct mgmt_mode *cp; | ||
307 | struct hci_dev *hdev; | ||
308 | u16 dev_id; | ||
309 | int ret, up; | ||
310 | |||
311 | cp = (void *) data; | ||
312 | dev_id = get_unaligned_le16(&cp->index); | ||
313 | |||
314 | BT_DBG("request for hci%u", dev_id); | ||
315 | |||
316 | hdev = hci_dev_get(dev_id); | ||
317 | if (!hdev) | ||
318 | return cmd_status(sk, MGMT_OP_SET_POWERED, ENODEV); | ||
319 | |||
320 | hci_dev_lock_bh(hdev); | ||
321 | |||
322 | up = test_bit(HCI_UP, &hdev->flags); | ||
323 | if ((cp->val && up) || (!cp->val && !up)) { | ||
324 | ret = cmd_status(sk, MGMT_OP_SET_POWERED, EALREADY); | ||
325 | goto failed; | ||
326 | } | ||
327 | |||
328 | if (mgmt_pending_find(MGMT_OP_SET_POWERED, dev_id)) { | ||
329 | ret = cmd_status(sk, MGMT_OP_SET_POWERED, EBUSY); | ||
330 | goto failed; | ||
331 | } | ||
332 | |||
333 | ret = mgmt_pending_add(sk, MGMT_OP_SET_POWERED, dev_id, data, len); | ||
334 | if (ret < 0) | ||
335 | goto failed; | ||
336 | |||
337 | if (cp->val) | ||
338 | queue_work(hdev->workqueue, &hdev->power_on); | ||
339 | else | ||
340 | queue_work(hdev->workqueue, &hdev->power_off); | ||
341 | |||
342 | ret = 0; | ||
343 | |||
344 | failed: | ||
345 | hci_dev_unlock_bh(hdev); | ||
346 | hci_dev_put(hdev); | ||
347 | return ret; | ||
348 | } | ||
349 | |||
350 | static int set_discoverable(struct sock *sk, unsigned char *data, u16 len) | ||
351 | { | ||
352 | struct mgmt_mode *cp; | ||
353 | struct hci_dev *hdev; | ||
354 | u16 dev_id; | ||
355 | u8 scan; | ||
356 | int err; | ||
357 | |||
358 | cp = (void *) data; | ||
359 | dev_id = get_unaligned_le16(&cp->index); | ||
360 | |||
361 | BT_DBG("request for hci%u", dev_id); | ||
362 | |||
363 | hdev = hci_dev_get(dev_id); | ||
364 | if (!hdev) | ||
365 | return cmd_status(sk, MGMT_OP_SET_DISCOVERABLE, ENODEV); | ||
366 | |||
367 | hci_dev_lock_bh(hdev); | ||
368 | |||
369 | if (!test_bit(HCI_UP, &hdev->flags)) { | ||
370 | err = cmd_status(sk, MGMT_OP_SET_DISCOVERABLE, ENETDOWN); | ||
371 | goto failed; | ||
372 | } | ||
373 | |||
374 | if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, dev_id) || | ||
375 | mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, dev_id)) { | ||
376 | err = cmd_status(sk, MGMT_OP_SET_DISCOVERABLE, EBUSY); | ||
377 | goto failed; | ||
378 | } | ||
379 | |||
380 | if (cp->val == test_bit(HCI_ISCAN, &hdev->flags) && | ||
381 | test_bit(HCI_PSCAN, &hdev->flags)) { | ||
382 | err = cmd_status(sk, MGMT_OP_SET_DISCOVERABLE, EALREADY); | ||
383 | goto failed; | ||
384 | } | ||
385 | |||
386 | err = mgmt_pending_add(sk, MGMT_OP_SET_DISCOVERABLE, dev_id, data, len); | ||
387 | if (err < 0) | ||
388 | goto failed; | ||
389 | |||
390 | scan = SCAN_PAGE; | ||
391 | |||
392 | if (cp->val) | ||
393 | scan |= SCAN_INQUIRY; | ||
394 | |||
395 | err = hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); | ||
396 | if (err < 0) | ||
397 | mgmt_pending_remove(MGMT_OP_SET_DISCOVERABLE, dev_id); | ||
398 | |||
399 | failed: | ||
400 | hci_dev_unlock_bh(hdev); | ||
401 | hci_dev_put(hdev); | ||
402 | |||
403 | return err; | ||
404 | } | ||
405 | |||
406 | static int set_connectable(struct sock *sk, unsigned char *data, u16 len) | ||
407 | { | ||
408 | struct mgmt_mode *cp; | ||
409 | struct hci_dev *hdev; | ||
410 | u16 dev_id; | ||
411 | u8 scan; | ||
412 | int err; | ||
413 | |||
414 | cp = (void *) data; | ||
415 | dev_id = get_unaligned_le16(&cp->index); | ||
416 | |||
417 | BT_DBG("request for hci%u", dev_id); | ||
418 | |||
419 | hdev = hci_dev_get(dev_id); | ||
420 | if (!hdev) | ||
421 | return cmd_status(sk, MGMT_OP_SET_CONNECTABLE, ENODEV); | ||
422 | |||
423 | hci_dev_lock_bh(hdev); | ||
424 | |||
425 | if (!test_bit(HCI_UP, &hdev->flags)) { | ||
426 | err = cmd_status(sk, MGMT_OP_SET_CONNECTABLE, ENETDOWN); | ||
427 | goto failed; | ||
428 | } | ||
429 | |||
430 | if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, dev_id) || | ||
431 | mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, dev_id)) { | ||
432 | err = cmd_status(sk, MGMT_OP_SET_CONNECTABLE, EBUSY); | ||
433 | goto failed; | ||
434 | } | ||
435 | |||
436 | if (cp->val == test_bit(HCI_PSCAN, &hdev->flags)) { | ||
437 | err = cmd_status(sk, MGMT_OP_SET_CONNECTABLE, EALREADY); | ||
438 | goto failed; | ||
439 | } | ||
440 | |||
441 | err = mgmt_pending_add(sk, MGMT_OP_SET_CONNECTABLE, dev_id, data, len); | ||
442 | if (err < 0) | ||
443 | goto failed; | ||
444 | |||
445 | if (cp->val) | ||
446 | scan = SCAN_PAGE; | ||
447 | else | ||
448 | scan = 0; | ||
449 | |||
450 | err = hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); | ||
451 | if (err < 0) | ||
452 | mgmt_pending_remove(MGMT_OP_SET_CONNECTABLE, dev_id); | ||
453 | |||
454 | failed: | ||
455 | hci_dev_unlock_bh(hdev); | ||
456 | hci_dev_put(hdev); | ||
457 | |||
458 | return err; | ||
459 | } | ||
460 | |||
461 | static int mgmt_event(u16 event, void *data, u16 data_len, struct sock *skip_sk) | ||
462 | { | ||
463 | struct sk_buff *skb; | ||
464 | struct mgmt_hdr *hdr; | ||
465 | |||
466 | skb = alloc_skb(sizeof(*hdr) + data_len, GFP_ATOMIC); | ||
158 | if (!skb) | 467 | if (!skb) |
159 | return -ENOMEM; | 468 | return -ENOMEM; |
160 | 469 | ||
470 | bt_cb(skb)->channel = HCI_CHANNEL_CONTROL; | ||
471 | |||
161 | hdr = (void *) skb_put(skb, sizeof(*hdr)); | 472 | hdr = (void *) skb_put(skb, sizeof(*hdr)); |
162 | hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE); | 473 | hdr->opcode = cpu_to_le16(event); |
163 | hdr->len = cpu_to_le16(sizeof(*ev) + sizeof(*rp)); | 474 | hdr->len = cpu_to_le16(data_len); |
164 | 475 | ||
165 | ev = (void *) skb_put(skb, sizeof(*ev)); | 476 | memcpy(skb_put(skb, data_len), data, data_len); |
166 | put_unaligned_le16(MGMT_OP_READ_INFO, &ev->opcode); | ||
167 | 477 | ||
168 | rp = (void *) skb_put(skb, sizeof(*rp)); | 478 | hci_send_to_sock(NULL, skb, skip_sk); |
479 | kfree_skb(skb); | ||
480 | |||
481 | return 0; | ||
482 | } | ||
483 | |||
484 | static int send_mode_rsp(struct sock *sk, u16 opcode, u16 index, u8 val) | ||
485 | { | ||
486 | struct mgmt_mode rp; | ||
487 | |||
488 | put_unaligned_le16(index, &rp.index); | ||
489 | rp.val = val; | ||
490 | |||
491 | return cmd_complete(sk, opcode, &rp, sizeof(rp)); | ||
492 | } | ||
493 | |||
494 | static int set_pairable(struct sock *sk, unsigned char *data, u16 len) | ||
495 | { | ||
496 | struct mgmt_mode *cp, ev; | ||
497 | struct hci_dev *hdev; | ||
498 | u16 dev_id; | ||
499 | int err; | ||
169 | 500 | ||
170 | cp = (void *) data; | 501 | cp = (void *) data; |
171 | dev_id = get_unaligned_le16(&cp->index); | 502 | dev_id = get_unaligned_le16(&cp->index); |
@@ -173,43 +504,547 @@ static int read_controller_info(struct sock *sk, unsigned char *data, u16 len) | |||
173 | BT_DBG("request for hci%u", dev_id); | 504 | BT_DBG("request for hci%u", dev_id); |
174 | 505 | ||
175 | hdev = hci_dev_get(dev_id); | 506 | hdev = hci_dev_get(dev_id); |
176 | if (!hdev) { | 507 | if (!hdev) |
177 | kfree_skb(skb); | 508 | return cmd_status(sk, MGMT_OP_SET_PAIRABLE, ENODEV); |
178 | return cmd_status(sk, MGMT_OP_READ_INFO, ENODEV); | 509 | |
510 | hci_dev_lock_bh(hdev); | ||
511 | |||
512 | if (cp->val) | ||
513 | set_bit(HCI_PAIRABLE, &hdev->flags); | ||
514 | else | ||
515 | clear_bit(HCI_PAIRABLE, &hdev->flags); | ||
516 | |||
517 | err = send_mode_rsp(sk, MGMT_OP_SET_PAIRABLE, dev_id, cp->val); | ||
518 | if (err < 0) | ||
519 | goto failed; | ||
520 | |||
521 | put_unaligned_le16(dev_id, &ev.index); | ||
522 | ev.val = cp->val; | ||
523 | |||
524 | err = mgmt_event(MGMT_EV_PAIRABLE, &ev, sizeof(ev), sk); | ||
525 | |||
526 | failed: | ||
527 | hci_dev_unlock_bh(hdev); | ||
528 | hci_dev_put(hdev); | ||
529 | |||
530 | return err; | ||
531 | } | ||
532 | |||
533 | static u8 get_service_classes(struct hci_dev *hdev) | ||
534 | { | ||
535 | struct list_head *p; | ||
536 | u8 val = 0; | ||
537 | |||
538 | list_for_each(p, &hdev->uuids) { | ||
539 | struct bt_uuid *uuid = list_entry(p, struct bt_uuid, list); | ||
540 | |||
541 | val |= uuid->svc_hint; | ||
542 | } | ||
543 | |||
544 | return val; | ||
545 | } | ||
546 | |||
547 | static int update_class(struct hci_dev *hdev) | ||
548 | { | ||
549 | u8 cod[3]; | ||
550 | |||
551 | BT_DBG("%s", hdev->name); | ||
552 | |||
553 | if (test_bit(HCI_SERVICE_CACHE, &hdev->flags)) | ||
554 | return 0; | ||
555 | |||
556 | cod[0] = hdev->minor_class; | ||
557 | cod[1] = hdev->major_class; | ||
558 | cod[2] = get_service_classes(hdev); | ||
559 | |||
560 | if (memcmp(cod, hdev->dev_class, 3) == 0) | ||
561 | return 0; | ||
562 | |||
563 | return hci_send_cmd(hdev, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod); | ||
564 | } | ||
565 | |||
566 | static int add_uuid(struct sock *sk, unsigned char *data, u16 len) | ||
567 | { | ||
568 | struct mgmt_cp_add_uuid *cp; | ||
569 | struct hci_dev *hdev; | ||
570 | struct bt_uuid *uuid; | ||
571 | u16 dev_id; | ||
572 | int err; | ||
573 | |||
574 | cp = (void *) data; | ||
575 | dev_id = get_unaligned_le16(&cp->index); | ||
576 | |||
577 | BT_DBG("request for hci%u", dev_id); | ||
578 | |||
579 | hdev = hci_dev_get(dev_id); | ||
580 | if (!hdev) | ||
581 | return cmd_status(sk, MGMT_OP_ADD_UUID, ENODEV); | ||
582 | |||
583 | hci_dev_lock_bh(hdev); | ||
584 | |||
585 | uuid = kmalloc(sizeof(*uuid), GFP_ATOMIC); | ||
586 | if (!uuid) { | ||
587 | err = -ENOMEM; | ||
588 | goto failed; | ||
179 | } | 589 | } |
180 | 590 | ||
591 | memcpy(uuid->uuid, cp->uuid, 16); | ||
592 | uuid->svc_hint = cp->svc_hint; | ||
593 | |||
594 | list_add(&uuid->list, &hdev->uuids); | ||
595 | |||
596 | err = update_class(hdev); | ||
597 | if (err < 0) | ||
598 | goto failed; | ||
599 | |||
600 | err = cmd_complete(sk, MGMT_OP_ADD_UUID, &dev_id, sizeof(dev_id)); | ||
601 | |||
602 | failed: | ||
603 | hci_dev_unlock_bh(hdev); | ||
604 | hci_dev_put(hdev); | ||
605 | |||
606 | return err; | ||
607 | } | ||
608 | |||
609 | static int remove_uuid(struct sock *sk, unsigned char *data, u16 len) | ||
610 | { | ||
611 | struct list_head *p, *n; | ||
612 | struct mgmt_cp_add_uuid *cp; | ||
613 | struct hci_dev *hdev; | ||
614 | u8 bt_uuid_any[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; | ||
615 | u16 dev_id; | ||
616 | int err, found; | ||
617 | |||
618 | cp = (void *) data; | ||
619 | dev_id = get_unaligned_le16(&cp->index); | ||
620 | |||
621 | BT_DBG("request for hci%u", dev_id); | ||
622 | |||
623 | hdev = hci_dev_get(dev_id); | ||
624 | if (!hdev) | ||
625 | return cmd_status(sk, MGMT_OP_REMOVE_UUID, ENODEV); | ||
626 | |||
181 | hci_dev_lock_bh(hdev); | 627 | hci_dev_lock_bh(hdev); |
182 | 628 | ||
183 | put_unaligned_le16(hdev->id, &rp->index); | 629 | if (memcmp(cp->uuid, bt_uuid_any, 16) == 0) { |
184 | rp->type = hdev->dev_type; | 630 | err = hci_uuids_clear(hdev); |
631 | goto unlock; | ||
632 | } | ||
185 | 633 | ||
186 | rp->powered = test_bit(HCI_UP, &hdev->flags); | 634 | found = 0; |
187 | rp->discoverable = test_bit(HCI_ISCAN, &hdev->flags); | ||
188 | rp->pairable = test_bit(HCI_PSCAN, &hdev->flags); | ||
189 | 635 | ||
190 | if (test_bit(HCI_AUTH, &hdev->flags)) | 636 | list_for_each_safe(p, n, &hdev->uuids) { |
191 | rp->sec_mode = 3; | 637 | struct bt_uuid *match = list_entry(p, struct bt_uuid, list); |
192 | else if (hdev->ssp_mode > 0) | ||
193 | rp->sec_mode = 4; | ||
194 | else | ||
195 | rp->sec_mode = 2; | ||
196 | 638 | ||
197 | bacpy(&rp->bdaddr, &hdev->bdaddr); | 639 | if (memcmp(match->uuid, cp->uuid, 16) != 0) |
198 | memcpy(rp->features, hdev->features, 8); | 640 | continue; |
199 | memcpy(rp->dev_class, hdev->dev_class, 3); | ||
200 | put_unaligned_le16(hdev->manufacturer, &rp->manufacturer); | ||
201 | rp->hci_ver = hdev->hci_ver; | ||
202 | put_unaligned_le16(hdev->hci_rev, &rp->hci_rev); | ||
203 | 641 | ||
642 | list_del(&match->list); | ||
643 | found++; | ||
644 | } | ||
645 | |||
646 | if (found == 0) { | ||
647 | err = cmd_status(sk, MGMT_OP_REMOVE_UUID, ENOENT); | ||
648 | goto unlock; | ||
649 | } | ||
650 | |||
651 | err = update_class(hdev); | ||
652 | if (err < 0) | ||
653 | goto unlock; | ||
654 | |||
655 | err = cmd_complete(sk, MGMT_OP_REMOVE_UUID, &dev_id, sizeof(dev_id)); | ||
656 | |||
657 | unlock: | ||
204 | hci_dev_unlock_bh(hdev); | 658 | hci_dev_unlock_bh(hdev); |
205 | hci_dev_put(hdev); | 659 | hci_dev_put(hdev); |
206 | 660 | ||
207 | if (sock_queue_rcv_skb(sk, skb) < 0) | 661 | return err; |
208 | kfree_skb(skb); | 662 | } |
663 | |||
664 | static int set_dev_class(struct sock *sk, unsigned char *data, u16 len) | ||
665 | { | ||
666 | struct hci_dev *hdev; | ||
667 | struct mgmt_cp_set_dev_class *cp; | ||
668 | u16 dev_id; | ||
669 | int err; | ||
670 | |||
671 | cp = (void *) data; | ||
672 | dev_id = get_unaligned_le16(&cp->index); | ||
673 | |||
674 | BT_DBG("request for hci%u", dev_id); | ||
675 | |||
676 | hdev = hci_dev_get(dev_id); | ||
677 | if (!hdev) | ||
678 | return cmd_status(sk, MGMT_OP_SET_DEV_CLASS, ENODEV); | ||
679 | |||
680 | hci_dev_lock_bh(hdev); | ||
681 | |||
682 | hdev->major_class = cp->major; | ||
683 | hdev->minor_class = cp->minor; | ||
684 | |||
685 | err = update_class(hdev); | ||
686 | |||
687 | if (err == 0) | ||
688 | err = cmd_complete(sk, MGMT_OP_SET_DEV_CLASS, &dev_id, | ||
689 | sizeof(dev_id)); | ||
690 | |||
691 | hci_dev_unlock_bh(hdev); | ||
692 | hci_dev_put(hdev); | ||
693 | |||
694 | return err; | ||
695 | } | ||
696 | |||
697 | static int set_service_cache(struct sock *sk, unsigned char *data, u16 len) | ||
698 | { | ||
699 | struct hci_dev *hdev; | ||
700 | struct mgmt_cp_set_service_cache *cp; | ||
701 | u16 dev_id; | ||
702 | int err; | ||
703 | |||
704 | cp = (void *) data; | ||
705 | dev_id = get_unaligned_le16(&cp->index); | ||
706 | |||
707 | hdev = hci_dev_get(dev_id); | ||
708 | if (!hdev) | ||
709 | return cmd_status(sk, MGMT_OP_SET_SERVICE_CACHE, ENODEV); | ||
710 | |||
711 | hci_dev_lock_bh(hdev); | ||
712 | |||
713 | BT_DBG("hci%u enable %d", dev_id, cp->enable); | ||
714 | |||
715 | if (cp->enable) { | ||
716 | set_bit(HCI_SERVICE_CACHE, &hdev->flags); | ||
717 | err = 0; | ||
718 | } else { | ||
719 | clear_bit(HCI_SERVICE_CACHE, &hdev->flags); | ||
720 | err = update_class(hdev); | ||
721 | } | ||
722 | |||
723 | if (err == 0) | ||
724 | err = cmd_complete(sk, MGMT_OP_SET_SERVICE_CACHE, &dev_id, | ||
725 | sizeof(dev_id)); | ||
726 | |||
727 | hci_dev_unlock_bh(hdev); | ||
728 | hci_dev_put(hdev); | ||
729 | |||
730 | return err; | ||
731 | } | ||
732 | |||
733 | static int load_keys(struct sock *sk, unsigned char *data, u16 len) | ||
734 | { | ||
735 | struct hci_dev *hdev; | ||
736 | struct mgmt_cp_load_keys *cp; | ||
737 | u16 dev_id, key_count, expected_len; | ||
738 | int i; | ||
739 | |||
740 | cp = (void *) data; | ||
741 | dev_id = get_unaligned_le16(&cp->index); | ||
742 | key_count = get_unaligned_le16(&cp->key_count); | ||
743 | |||
744 | expected_len = sizeof(*cp) + key_count * sizeof(struct mgmt_key_info); | ||
745 | if (expected_len != len) { | ||
746 | BT_ERR("load_keys: expected %u bytes, got %u bytes", | ||
747 | len, expected_len); | ||
748 | return -EINVAL; | ||
749 | } | ||
750 | |||
751 | hdev = hci_dev_get(dev_id); | ||
752 | if (!hdev) | ||
753 | return cmd_status(sk, MGMT_OP_LOAD_KEYS, ENODEV); | ||
754 | |||
755 | BT_DBG("hci%u debug_keys %u key_count %u", dev_id, cp->debug_keys, | ||
756 | key_count); | ||
757 | |||
758 | hci_dev_lock_bh(hdev); | ||
759 | |||
760 | hci_link_keys_clear(hdev); | ||
761 | |||
762 | set_bit(HCI_LINK_KEYS, &hdev->flags); | ||
763 | |||
764 | if (cp->debug_keys) | ||
765 | set_bit(HCI_DEBUG_KEYS, &hdev->flags); | ||
766 | else | ||
767 | clear_bit(HCI_DEBUG_KEYS, &hdev->flags); | ||
768 | |||
769 | for (i = 0; i < key_count; i++) { | ||
770 | struct mgmt_key_info *key = &cp->keys[i]; | ||
771 | |||
772 | hci_add_link_key(hdev, 0, &key->bdaddr, key->val, key->type, | ||
773 | key->pin_len); | ||
774 | } | ||
775 | |||
776 | hci_dev_unlock_bh(hdev); | ||
777 | hci_dev_put(hdev); | ||
209 | 778 | ||
210 | return 0; | 779 | return 0; |
211 | } | 780 | } |
212 | 781 | ||
782 | static int remove_key(struct sock *sk, unsigned char *data, u16 len) | ||
783 | { | ||
784 | struct hci_dev *hdev; | ||
785 | struct mgmt_cp_remove_key *cp; | ||
786 | struct hci_conn *conn; | ||
787 | u16 dev_id; | ||
788 | int err; | ||
789 | |||
790 | cp = (void *) data; | ||
791 | dev_id = get_unaligned_le16(&cp->index); | ||
792 | |||
793 | hdev = hci_dev_get(dev_id); | ||
794 | if (!hdev) | ||
795 | return cmd_status(sk, MGMT_OP_REMOVE_KEY, ENODEV); | ||
796 | |||
797 | hci_dev_lock_bh(hdev); | ||
798 | |||
799 | err = hci_remove_link_key(hdev, &cp->bdaddr); | ||
800 | if (err < 0) { | ||
801 | err = cmd_status(sk, MGMT_OP_REMOVE_KEY, -err); | ||
802 | goto unlock; | ||
803 | } | ||
804 | |||
805 | err = 0; | ||
806 | |||
807 | if (!test_bit(HCI_UP, &hdev->flags) || !cp->disconnect) | ||
808 | goto unlock; | ||
809 | |||
810 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); | ||
811 | if (conn) { | ||
812 | struct hci_cp_disconnect dc; | ||
813 | |||
814 | put_unaligned_le16(conn->handle, &dc.handle); | ||
815 | dc.reason = 0x13; /* Remote User Terminated Connection */ | ||
816 | err = hci_send_cmd(hdev, HCI_OP_DISCONNECT, 0, NULL); | ||
817 | } | ||
818 | |||
819 | unlock: | ||
820 | hci_dev_unlock_bh(hdev); | ||
821 | hci_dev_put(hdev); | ||
822 | |||
823 | return err; | ||
824 | } | ||
825 | |||
826 | static int disconnect(struct sock *sk, unsigned char *data, u16 len) | ||
827 | { | ||
828 | struct hci_dev *hdev; | ||
829 | struct mgmt_cp_disconnect *cp; | ||
830 | struct hci_cp_disconnect dc; | ||
831 | struct hci_conn *conn; | ||
832 | u16 dev_id; | ||
833 | int err; | ||
834 | |||
835 | BT_DBG(""); | ||
836 | |||
837 | cp = (void *) data; | ||
838 | dev_id = get_unaligned_le16(&cp->index); | ||
839 | |||
840 | hdev = hci_dev_get(dev_id); | ||
841 | if (!hdev) | ||
842 | return cmd_status(sk, MGMT_OP_DISCONNECT, ENODEV); | ||
843 | |||
844 | hci_dev_lock_bh(hdev); | ||
845 | |||
846 | if (!test_bit(HCI_UP, &hdev->flags)) { | ||
847 | err = cmd_status(sk, MGMT_OP_DISCONNECT, ENETDOWN); | ||
848 | goto failed; | ||
849 | } | ||
850 | |||
851 | if (mgmt_pending_find(MGMT_OP_DISCONNECT, dev_id)) { | ||
852 | err = cmd_status(sk, MGMT_OP_DISCONNECT, EBUSY); | ||
853 | goto failed; | ||
854 | } | ||
855 | |||
856 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); | ||
857 | if (!conn) { | ||
858 | err = cmd_status(sk, MGMT_OP_DISCONNECT, ENOTCONN); | ||
859 | goto failed; | ||
860 | } | ||
861 | |||
862 | err = mgmt_pending_add(sk, MGMT_OP_DISCONNECT, dev_id, data, len); | ||
863 | if (err < 0) | ||
864 | goto failed; | ||
865 | |||
866 | put_unaligned_le16(conn->handle, &dc.handle); | ||
867 | dc.reason = 0x13; /* Remote User Terminated Connection */ | ||
868 | |||
869 | err = hci_send_cmd(hdev, HCI_OP_DISCONNECT, sizeof(dc), &dc); | ||
870 | if (err < 0) | ||
871 | mgmt_pending_remove(MGMT_OP_DISCONNECT, dev_id); | ||
872 | |||
873 | failed: | ||
874 | hci_dev_unlock_bh(hdev); | ||
875 | hci_dev_put(hdev); | ||
876 | |||
877 | return err; | ||
878 | } | ||
879 | |||
880 | static int get_connections(struct sock *sk, unsigned char *data, u16 len) | ||
881 | { | ||
882 | struct mgmt_cp_get_connections *cp; | ||
883 | struct mgmt_rp_get_connections *rp; | ||
884 | struct hci_dev *hdev; | ||
885 | struct list_head *p; | ||
886 | size_t rp_len; | ||
887 | u16 dev_id, count; | ||
888 | int i, err; | ||
889 | |||
890 | BT_DBG(""); | ||
891 | |||
892 | cp = (void *) data; | ||
893 | dev_id = get_unaligned_le16(&cp->index); | ||
894 | |||
895 | hdev = hci_dev_get(dev_id); | ||
896 | if (!hdev) | ||
897 | return cmd_status(sk, MGMT_OP_GET_CONNECTIONS, ENODEV); | ||
898 | |||
899 | hci_dev_lock_bh(hdev); | ||
900 | |||
901 | count = 0; | ||
902 | list_for_each(p, &hdev->conn_hash.list) { | ||
903 | count++; | ||
904 | } | ||
905 | |||
906 | rp_len = sizeof(*rp) + (count * sizeof(bdaddr_t)); | ||
907 | rp = kmalloc(rp_len, GFP_ATOMIC); | ||
908 | if (!rp) { | ||
909 | err = -ENOMEM; | ||
910 | goto unlock; | ||
911 | } | ||
912 | |||
913 | put_unaligned_le16(dev_id, &rp->index); | ||
914 | put_unaligned_le16(count, &rp->conn_count); | ||
915 | |||
916 | read_lock(&hci_dev_list_lock); | ||
917 | |||
918 | i = 0; | ||
919 | list_for_each(p, &hdev->conn_hash.list) { | ||
920 | struct hci_conn *c = list_entry(p, struct hci_conn, list); | ||
921 | |||
922 | bacpy(&rp->conn[i++], &c->dst); | ||
923 | } | ||
924 | |||
925 | read_unlock(&hci_dev_list_lock); | ||
926 | |||
927 | err = cmd_complete(sk, MGMT_OP_GET_CONNECTIONS, rp, rp_len); | ||
928 | |||
929 | unlock: | ||
930 | kfree(rp); | ||
931 | hci_dev_unlock_bh(hdev); | ||
932 | hci_dev_put(hdev); | ||
933 | return err; | ||
934 | } | ||
935 | |||
936 | static int pin_code_reply(struct sock *sk, unsigned char *data, u16 len) | ||
937 | { | ||
938 | struct hci_dev *hdev; | ||
939 | struct mgmt_cp_pin_code_reply *cp; | ||
940 | struct hci_cp_pin_code_reply reply; | ||
941 | u16 dev_id; | ||
942 | int err; | ||
943 | |||
944 | BT_DBG(""); | ||
945 | |||
946 | cp = (void *) data; | ||
947 | dev_id = get_unaligned_le16(&cp->index); | ||
948 | |||
949 | hdev = hci_dev_get(dev_id); | ||
950 | if (!hdev) | ||
951 | return cmd_status(sk, MGMT_OP_DISCONNECT, ENODEV); | ||
952 | |||
953 | hci_dev_lock_bh(hdev); | ||
954 | |||
955 | if (!test_bit(HCI_UP, &hdev->flags)) { | ||
956 | err = cmd_status(sk, MGMT_OP_PIN_CODE_REPLY, ENETDOWN); | ||
957 | goto failed; | ||
958 | } | ||
959 | |||
960 | err = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_REPLY, dev_id, data, len); | ||
961 | if (err < 0) | ||
962 | goto failed; | ||
963 | |||
964 | bacpy(&reply.bdaddr, &cp->bdaddr); | ||
965 | reply.pin_len = cp->pin_len; | ||
966 | memcpy(reply.pin_code, cp->pin_code, 16); | ||
967 | |||
968 | err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_REPLY, sizeof(reply), &reply); | ||
969 | if (err < 0) | ||
970 | mgmt_pending_remove(MGMT_OP_PIN_CODE_REPLY, dev_id); | ||
971 | |||
972 | failed: | ||
973 | hci_dev_unlock_bh(hdev); | ||
974 | hci_dev_put(hdev); | ||
975 | |||
976 | return err; | ||
977 | } | ||
978 | |||
979 | static int pin_code_neg_reply(struct sock *sk, unsigned char *data, u16 len) | ||
980 | { | ||
981 | struct hci_dev *hdev; | ||
982 | struct mgmt_cp_pin_code_neg_reply *cp; | ||
983 | u16 dev_id; | ||
984 | int err; | ||
985 | |||
986 | BT_DBG(""); | ||
987 | |||
988 | cp = (void *) data; | ||
989 | dev_id = get_unaligned_le16(&cp->index); | ||
990 | |||
991 | hdev = hci_dev_get(dev_id); | ||
992 | if (!hdev) | ||
993 | return cmd_status(sk, MGMT_OP_PIN_CODE_NEG_REPLY, ENODEV); | ||
994 | |||
995 | hci_dev_lock_bh(hdev); | ||
996 | |||
997 | if (!test_bit(HCI_UP, &hdev->flags)) { | ||
998 | err = cmd_status(sk, MGMT_OP_PIN_CODE_NEG_REPLY, ENETDOWN); | ||
999 | goto failed; | ||
1000 | } | ||
1001 | |||
1002 | err = mgmt_pending_add(sk, MGMT_OP_PIN_CODE_NEG_REPLY, dev_id, | ||
1003 | data, len); | ||
1004 | if (err < 0) | ||
1005 | goto failed; | ||
1006 | |||
1007 | err = hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, sizeof(bdaddr_t), | ||
1008 | &cp->bdaddr); | ||
1009 | if (err < 0) | ||
1010 | mgmt_pending_remove(MGMT_OP_PIN_CODE_NEG_REPLY, dev_id); | ||
1011 | |||
1012 | failed: | ||
1013 | hci_dev_unlock_bh(hdev); | ||
1014 | hci_dev_put(hdev); | ||
1015 | |||
1016 | return err; | ||
1017 | } | ||
1018 | |||
1019 | static int set_io_capability(struct sock *sk, unsigned char *data, u16 len) | ||
1020 | { | ||
1021 | struct hci_dev *hdev; | ||
1022 | struct mgmt_cp_set_io_capability *cp; | ||
1023 | u16 dev_id; | ||
1024 | |||
1025 | BT_DBG(""); | ||
1026 | |||
1027 | cp = (void *) data; | ||
1028 | dev_id = get_unaligned_le16(&cp->index); | ||
1029 | |||
1030 | hdev = hci_dev_get(dev_id); | ||
1031 | if (!hdev) | ||
1032 | return cmd_status(sk, MGMT_OP_SET_IO_CAPABILITY, ENODEV); | ||
1033 | |||
1034 | hci_dev_lock_bh(hdev); | ||
1035 | |||
1036 | hdev->io_capability = cp->io_capability; | ||
1037 | |||
1038 | BT_DBG("%s IO capability set to 0x%02x", hdev->name, | ||
1039 | hdev->io_capability); | ||
1040 | |||
1041 | hci_dev_unlock_bh(hdev); | ||
1042 | hci_dev_put(hdev); | ||
1043 | |||
1044 | return cmd_complete(sk, MGMT_OP_SET_IO_CAPABILITY, | ||
1045 | &dev_id, sizeof(dev_id)); | ||
1046 | } | ||
1047 | |||
213 | int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) | 1048 | int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) |
214 | { | 1049 | { |
215 | unsigned char *buf; | 1050 | unsigned char *buf; |
@@ -250,6 +1085,51 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) | |||
250 | case MGMT_OP_READ_INFO: | 1085 | case MGMT_OP_READ_INFO: |
251 | err = read_controller_info(sk, buf + sizeof(*hdr), len); | 1086 | err = read_controller_info(sk, buf + sizeof(*hdr), len); |
252 | break; | 1087 | break; |
1088 | case MGMT_OP_SET_POWERED: | ||
1089 | err = set_powered(sk, buf + sizeof(*hdr), len); | ||
1090 | break; | ||
1091 | case MGMT_OP_SET_DISCOVERABLE: | ||
1092 | err = set_discoverable(sk, buf + sizeof(*hdr), len); | ||
1093 | break; | ||
1094 | case MGMT_OP_SET_CONNECTABLE: | ||
1095 | err = set_connectable(sk, buf + sizeof(*hdr), len); | ||
1096 | break; | ||
1097 | case MGMT_OP_SET_PAIRABLE: | ||
1098 | err = set_pairable(sk, buf + sizeof(*hdr), len); | ||
1099 | break; | ||
1100 | case MGMT_OP_ADD_UUID: | ||
1101 | err = add_uuid(sk, buf + sizeof(*hdr), len); | ||
1102 | break; | ||
1103 | case MGMT_OP_REMOVE_UUID: | ||
1104 | err = remove_uuid(sk, buf + sizeof(*hdr), len); | ||
1105 | break; | ||
1106 | case MGMT_OP_SET_DEV_CLASS: | ||
1107 | err = set_dev_class(sk, buf + sizeof(*hdr), len); | ||
1108 | break; | ||
1109 | case MGMT_OP_SET_SERVICE_CACHE: | ||
1110 | err = set_service_cache(sk, buf + sizeof(*hdr), len); | ||
1111 | break; | ||
1112 | case MGMT_OP_LOAD_KEYS: | ||
1113 | err = load_keys(sk, buf + sizeof(*hdr), len); | ||
1114 | break; | ||
1115 | case MGMT_OP_REMOVE_KEY: | ||
1116 | err = remove_key(sk, buf + sizeof(*hdr), len); | ||
1117 | break; | ||
1118 | case MGMT_OP_DISCONNECT: | ||
1119 | err = disconnect(sk, buf + sizeof(*hdr), len); | ||
1120 | break; | ||
1121 | case MGMT_OP_GET_CONNECTIONS: | ||
1122 | err = get_connections(sk, buf + sizeof(*hdr), len); | ||
1123 | break; | ||
1124 | case MGMT_OP_PIN_CODE_REPLY: | ||
1125 | err = pin_code_reply(sk, buf + sizeof(*hdr), len); | ||
1126 | break; | ||
1127 | case MGMT_OP_PIN_CODE_NEG_REPLY: | ||
1128 | err = pin_code_neg_reply(sk, buf + sizeof(*hdr), len); | ||
1129 | break; | ||
1130 | case MGMT_OP_SET_IO_CAPABILITY: | ||
1131 | err = set_io_capability(sk, buf + sizeof(*hdr), len); | ||
1132 | break; | ||
253 | default: | 1133 | default: |
254 | BT_DBG("Unknown op %u", opcode); | 1134 | BT_DBG("Unknown op %u", opcode); |
255 | err = cmd_status(sk, opcode, 0x01); | 1135 | err = cmd_status(sk, opcode, 0x01); |
@@ -266,43 +1146,247 @@ done: | |||
266 | return err; | 1146 | return err; |
267 | } | 1147 | } |
268 | 1148 | ||
269 | static int mgmt_event(u16 event, void *data, u16 data_len) | 1149 | int mgmt_index_added(u16 index) |
270 | { | 1150 | { |
271 | struct sk_buff *skb; | 1151 | struct mgmt_ev_index_added ev; |
272 | struct mgmt_hdr *hdr; | ||
273 | 1152 | ||
274 | skb = alloc_skb(sizeof(*hdr) + data_len, GFP_ATOMIC); | 1153 | put_unaligned_le16(index, &ev.index); |
275 | if (!skb) | ||
276 | return -ENOMEM; | ||
277 | 1154 | ||
278 | bt_cb(skb)->channel = HCI_CHANNEL_CONTROL; | 1155 | return mgmt_event(MGMT_EV_INDEX_ADDED, &ev, sizeof(ev), NULL); |
1156 | } | ||
279 | 1157 | ||
280 | hdr = (void *) skb_put(skb, sizeof(*hdr)); | 1158 | int mgmt_index_removed(u16 index) |
281 | hdr->opcode = cpu_to_le16(event); | 1159 | { |
282 | hdr->len = cpu_to_le16(data_len); | 1160 | struct mgmt_ev_index_added ev; |
283 | 1161 | ||
284 | memcpy(skb_put(skb, data_len), data, data_len); | 1162 | put_unaligned_le16(index, &ev.index); |
285 | 1163 | ||
286 | hci_send_to_sock(NULL, skb); | 1164 | return mgmt_event(MGMT_EV_INDEX_REMOVED, &ev, sizeof(ev), NULL); |
287 | kfree_skb(skb); | 1165 | } |
288 | 1166 | ||
289 | return 0; | 1167 | struct cmd_lookup { |
1168 | u8 val; | ||
1169 | struct sock *sk; | ||
1170 | }; | ||
1171 | |||
1172 | static void mode_rsp(struct pending_cmd *cmd, void *data) | ||
1173 | { | ||
1174 | struct mgmt_mode *cp = cmd->cmd; | ||
1175 | struct cmd_lookup *match = data; | ||
1176 | |||
1177 | if (cp->val != match->val) | ||
1178 | return; | ||
1179 | |||
1180 | send_mode_rsp(cmd->sk, cmd->opcode, cmd->index, cp->val); | ||
1181 | |||
1182 | list_del(&cmd->list); | ||
1183 | |||
1184 | if (match->sk == NULL) { | ||
1185 | match->sk = cmd->sk; | ||
1186 | sock_hold(match->sk); | ||
1187 | } | ||
1188 | |||
1189 | mgmt_pending_free(cmd); | ||
290 | } | 1190 | } |
291 | 1191 | ||
292 | int mgmt_index_added(u16 index) | 1192 | int mgmt_powered(u16 index, u8 powered) |
293 | { | 1193 | { |
294 | struct mgmt_ev_index_added ev; | 1194 | struct mgmt_mode ev; |
1195 | struct cmd_lookup match = { powered, NULL }; | ||
1196 | int ret; | ||
1197 | |||
1198 | mgmt_pending_foreach(MGMT_OP_SET_POWERED, index, mode_rsp, &match); | ||
295 | 1199 | ||
296 | put_unaligned_le16(index, &ev.index); | 1200 | put_unaligned_le16(index, &ev.index); |
1201 | ev.val = powered; | ||
1202 | |||
1203 | ret = mgmt_event(MGMT_EV_POWERED, &ev, sizeof(ev), match.sk); | ||
297 | 1204 | ||
298 | return mgmt_event(MGMT_EV_INDEX_ADDED, &ev, sizeof(ev)); | 1205 | if (match.sk) |
1206 | sock_put(match.sk); | ||
1207 | |||
1208 | return ret; | ||
299 | } | 1209 | } |
300 | 1210 | ||
301 | int mgmt_index_removed(u16 index) | 1211 | int mgmt_discoverable(u16 index, u8 discoverable) |
302 | { | 1212 | { |
303 | struct mgmt_ev_index_added ev; | 1213 | struct mgmt_mode ev; |
1214 | struct cmd_lookup match = { discoverable, NULL }; | ||
1215 | int ret; | ||
1216 | |||
1217 | mgmt_pending_foreach(MGMT_OP_SET_DISCOVERABLE, index, | ||
1218 | mode_rsp, &match); | ||
1219 | |||
1220 | put_unaligned_le16(index, &ev.index); | ||
1221 | ev.val = discoverable; | ||
1222 | |||
1223 | ret = mgmt_event(MGMT_EV_DISCOVERABLE, &ev, sizeof(ev), match.sk); | ||
1224 | |||
1225 | if (match.sk) | ||
1226 | sock_put(match.sk); | ||
1227 | |||
1228 | return ret; | ||
1229 | } | ||
1230 | |||
1231 | int mgmt_connectable(u16 index, u8 connectable) | ||
1232 | { | ||
1233 | struct mgmt_mode ev; | ||
1234 | struct cmd_lookup match = { connectable, NULL }; | ||
1235 | int ret; | ||
1236 | |||
1237 | mgmt_pending_foreach(MGMT_OP_SET_CONNECTABLE, index, mode_rsp, &match); | ||
1238 | |||
1239 | put_unaligned_le16(index, &ev.index); | ||
1240 | ev.val = connectable; | ||
1241 | |||
1242 | ret = mgmt_event(MGMT_EV_CONNECTABLE, &ev, sizeof(ev), match.sk); | ||
1243 | |||
1244 | if (match.sk) | ||
1245 | sock_put(match.sk); | ||
1246 | |||
1247 | return ret; | ||
1248 | } | ||
1249 | |||
1250 | int mgmt_new_key(u16 index, struct link_key *key, u8 old_key_type) | ||
1251 | { | ||
1252 | struct mgmt_ev_new_key ev; | ||
1253 | |||
1254 | memset(&ev, 0, sizeof(ev)); | ||
1255 | |||
1256 | put_unaligned_le16(index, &ev.index); | ||
1257 | |||
1258 | bacpy(&ev.key.bdaddr, &key->bdaddr); | ||
1259 | ev.key.type = key->type; | ||
1260 | memcpy(ev.key.val, key->val, 16); | ||
1261 | ev.key.pin_len = key->pin_len; | ||
1262 | ev.old_key_type = old_key_type; | ||
1263 | |||
1264 | return mgmt_event(MGMT_EV_NEW_KEY, &ev, sizeof(ev), NULL); | ||
1265 | } | ||
1266 | |||
1267 | int mgmt_connected(u16 index, bdaddr_t *bdaddr) | ||
1268 | { | ||
1269 | struct mgmt_ev_connected ev; | ||
304 | 1270 | ||
305 | put_unaligned_le16(index, &ev.index); | 1271 | put_unaligned_le16(index, &ev.index); |
1272 | bacpy(&ev.bdaddr, bdaddr); | ||
306 | 1273 | ||
307 | return mgmt_event(MGMT_EV_INDEX_REMOVED, &ev, sizeof(ev)); | 1274 | return mgmt_event(MGMT_EV_CONNECTED, &ev, sizeof(ev), NULL); |
1275 | } | ||
1276 | |||
1277 | static void disconnect_rsp(struct pending_cmd *cmd, void *data) | ||
1278 | { | ||
1279 | struct mgmt_cp_disconnect *cp = cmd->cmd; | ||
1280 | struct sock **sk = data; | ||
1281 | struct mgmt_rp_disconnect rp; | ||
1282 | |||
1283 | put_unaligned_le16(cmd->index, &rp.index); | ||
1284 | bacpy(&rp.bdaddr, &cp->bdaddr); | ||
1285 | |||
1286 | cmd_complete(cmd->sk, MGMT_OP_DISCONNECT, &rp, sizeof(rp)); | ||
1287 | |||
1288 | *sk = cmd->sk; | ||
1289 | sock_hold(*sk); | ||
1290 | |||
1291 | list_del(&cmd->list); | ||
1292 | mgmt_pending_free(cmd); | ||
1293 | } | ||
1294 | |||
1295 | int mgmt_disconnected(u16 index, bdaddr_t *bdaddr) | ||
1296 | { | ||
1297 | struct mgmt_ev_disconnected ev; | ||
1298 | struct sock *sk = NULL; | ||
1299 | int err; | ||
1300 | |||
1301 | mgmt_pending_foreach(MGMT_OP_DISCONNECT, index, disconnect_rsp, &sk); | ||
1302 | |||
1303 | put_unaligned_le16(index, &ev.index); | ||
1304 | bacpy(&ev.bdaddr, bdaddr); | ||
1305 | |||
1306 | err = mgmt_event(MGMT_EV_DISCONNECTED, &ev, sizeof(ev), sk); | ||
1307 | |||
1308 | if (sk) | ||
1309 | sock_put(sk); | ||
1310 | |||
1311 | return err; | ||
1312 | } | ||
1313 | |||
1314 | int mgmt_disconnect_failed(u16 index) | ||
1315 | { | ||
1316 | struct pending_cmd *cmd; | ||
1317 | int err; | ||
1318 | |||
1319 | cmd = mgmt_pending_find(MGMT_OP_DISCONNECT, index); | ||
1320 | if (!cmd) | ||
1321 | return -ENOENT; | ||
1322 | |||
1323 | err = cmd_status(cmd->sk, MGMT_OP_DISCONNECT, EIO); | ||
1324 | |||
1325 | list_del(&cmd->list); | ||
1326 | mgmt_pending_free(cmd); | ||
1327 | |||
1328 | return err; | ||
1329 | } | ||
1330 | |||
1331 | int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status) | ||
1332 | { | ||
1333 | struct mgmt_ev_connect_failed ev; | ||
1334 | |||
1335 | put_unaligned_le16(index, &ev.index); | ||
1336 | bacpy(&ev.bdaddr, bdaddr); | ||
1337 | ev.status = status; | ||
1338 | |||
1339 | return mgmt_event(MGMT_EV_CONNECT_FAILED, &ev, sizeof(ev), NULL); | ||
1340 | } | ||
1341 | |||
1342 | int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr) | ||
1343 | { | ||
1344 | struct mgmt_ev_pin_code_request ev; | ||
1345 | |||
1346 | put_unaligned_le16(index, &ev.index); | ||
1347 | bacpy(&ev.bdaddr, bdaddr); | ||
1348 | |||
1349 | return mgmt_event(MGMT_EV_PIN_CODE_REQUEST, &ev, sizeof(ev), NULL); | ||
1350 | } | ||
1351 | |||
1352 | int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | ||
1353 | { | ||
1354 | struct pending_cmd *cmd; | ||
1355 | int err; | ||
1356 | |||
1357 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_REPLY, index); | ||
1358 | if (!cmd) | ||
1359 | return -ENOENT; | ||
1360 | |||
1361 | if (status != 0) | ||
1362 | err = cmd_status(cmd->sk, MGMT_OP_PIN_CODE_REPLY, status); | ||
1363 | else | ||
1364 | err = cmd_complete(cmd->sk, MGMT_OP_PIN_CODE_REPLY, | ||
1365 | bdaddr, sizeof(*bdaddr)); | ||
1366 | |||
1367 | list_del(&cmd->list); | ||
1368 | mgmt_pending_free(cmd); | ||
1369 | |||
1370 | return err; | ||
1371 | } | ||
1372 | |||
1373 | int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status) | ||
1374 | { | ||
1375 | struct pending_cmd *cmd; | ||
1376 | int err; | ||
1377 | |||
1378 | cmd = mgmt_pending_find(MGMT_OP_PIN_CODE_NEG_REPLY, index); | ||
1379 | if (!cmd) | ||
1380 | return -ENOENT; | ||
1381 | |||
1382 | if (status != 0) | ||
1383 | err = cmd_status(cmd->sk, MGMT_OP_PIN_CODE_NEG_REPLY, status); | ||
1384 | else | ||
1385 | err = cmd_complete(cmd->sk, MGMT_OP_PIN_CODE_NEG_REPLY, | ||
1386 | bdaddr, sizeof(*bdaddr)); | ||
1387 | |||
1388 | list_del(&cmd->list); | ||
1389 | mgmt_pending_free(cmd); | ||
1390 | |||
1391 | return err; | ||
308 | } | 1392 | } |
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 6b83776534fb..c9973932456f 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
@@ -2154,8 +2154,6 @@ static int __init rfcomm_init(void) | |||
2154 | { | 2154 | { |
2155 | int err; | 2155 | int err; |
2156 | 2156 | ||
2157 | l2cap_load(); | ||
2158 | |||
2159 | hci_register_cb(&rfcomm_cb); | 2157 | hci_register_cb(&rfcomm_cb); |
2160 | 2158 | ||
2161 | rfcomm_thread = kthread_run(rfcomm_run, NULL, "krfcommd"); | 2159 | rfcomm_thread = kthread_run(rfcomm_run, NULL, "krfcommd"); |
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index 2575c2db6404..d7b9af4703d0 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c | |||
@@ -727,7 +727,9 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp) | |||
727 | break; | 727 | break; |
728 | } | 728 | } |
729 | 729 | ||
730 | tty_unlock(); | ||
730 | schedule(); | 731 | schedule(); |
732 | tty_lock(); | ||
731 | } | 733 | } |
732 | set_current_state(TASK_RUNNING); | 734 | set_current_state(TASK_RUNNING); |
733 | remove_wait_queue(&dev->wait, &wait); | 735 | remove_wait_queue(&dev->wait, &wait); |
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 960c6d1637da..c9348ddda877 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
@@ -50,8 +50,6 @@ | |||
50 | #include <net/bluetooth/hci_core.h> | 50 | #include <net/bluetooth/hci_core.h> |
51 | #include <net/bluetooth/sco.h> | 51 | #include <net/bluetooth/sco.h> |
52 | 52 | ||
53 | #define VERSION "0.6" | ||
54 | |||
55 | static int disable_esco; | 53 | static int disable_esco; |
56 | 54 | ||
57 | static const struct proto_ops sco_sock_ops; | 55 | static const struct proto_ops sco_sock_ops; |
@@ -703,6 +701,7 @@ static int sco_sock_getsockopt_old(struct socket *sock, int optname, char __user | |||
703 | break; | 701 | break; |
704 | } | 702 | } |
705 | 703 | ||
704 | memset(&cinfo, 0, sizeof(cinfo)); | ||
706 | cinfo.hci_handle = sco_pi(sk)->conn->hcon->handle; | 705 | cinfo.hci_handle = sco_pi(sk)->conn->hcon->handle; |
707 | memcpy(cinfo.dev_class, sco_pi(sk)->conn->hcon->dev_class, 3); | 706 | memcpy(cinfo.dev_class, sco_pi(sk)->conn->hcon->dev_class, 3); |
708 | 707 | ||
@@ -1023,7 +1022,7 @@ static struct hci_proto sco_hci_proto = { | |||
1023 | .recv_scodata = sco_recv_scodata | 1022 | .recv_scodata = sco_recv_scodata |
1024 | }; | 1023 | }; |
1025 | 1024 | ||
1026 | static int __init sco_init(void) | 1025 | int __init sco_init(void) |
1027 | { | 1026 | { |
1028 | int err; | 1027 | int err; |
1029 | 1028 | ||
@@ -1051,7 +1050,6 @@ static int __init sco_init(void) | |||
1051 | BT_ERR("Failed to create SCO debug file"); | 1050 | BT_ERR("Failed to create SCO debug file"); |
1052 | } | 1051 | } |
1053 | 1052 | ||
1054 | BT_INFO("SCO (Voice Link) ver %s", VERSION); | ||
1055 | BT_INFO("SCO socket layer initialized"); | 1053 | BT_INFO("SCO socket layer initialized"); |
1056 | 1054 | ||
1057 | return 0; | 1055 | return 0; |
@@ -1061,7 +1059,7 @@ error: | |||
1061 | return err; | 1059 | return err; |
1062 | } | 1060 | } |
1063 | 1061 | ||
1064 | static void __exit sco_exit(void) | 1062 | void __exit sco_exit(void) |
1065 | { | 1063 | { |
1066 | debugfs_remove(sco_debugfs); | 1064 | debugfs_remove(sco_debugfs); |
1067 | 1065 | ||
@@ -1074,14 +1072,5 @@ static void __exit sco_exit(void) | |||
1074 | proto_unregister(&sco_proto); | 1072 | proto_unregister(&sco_proto); |
1075 | } | 1073 | } |
1076 | 1074 | ||
1077 | module_init(sco_init); | ||
1078 | module_exit(sco_exit); | ||
1079 | |||
1080 | module_param(disable_esco, bool, 0644); | 1075 | module_param(disable_esco, bool, 0644); |
1081 | MODULE_PARM_DESC(disable_esco, "Disable eSCO connection creation"); | 1076 | MODULE_PARM_DESC(disable_esco, "Disable eSCO connection creation"); |
1082 | |||
1083 | MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>"); | ||
1084 | MODULE_DESCRIPTION("Bluetooth SCO ver " VERSION); | ||
1085 | MODULE_VERSION(VERSION); | ||
1086 | MODULE_LICENSE("GPL"); | ||
1087 | MODULE_ALIAS("bt-proto-2"); | ||
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index c766056d0488..dbf5e4006bc1 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig | |||
@@ -17,7 +17,7 @@ comment "CFG80211 needs to be enabled for MAC80211" | |||
17 | if MAC80211 != n | 17 | if MAC80211 != n |
18 | 18 | ||
19 | config MAC80211_HAS_RC | 19 | config MAC80211_HAS_RC |
20 | def_bool n | 20 | bool |
21 | 21 | ||
22 | config MAC80211_RC_PID | 22 | config MAC80211_RC_PID |
23 | bool "PID controller based rate control algorithm" if EXPERT | 23 | bool "PID controller based rate control algorithm" if EXPERT |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 2ba3af850dda..140503d4c97a 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -1863,6 +1863,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, | |||
1863 | 1863 | ||
1864 | wk->type = IEEE80211_WORK_OFFCHANNEL_TX; | 1864 | wk->type = IEEE80211_WORK_OFFCHANNEL_TX; |
1865 | wk->chan = chan; | 1865 | wk->chan = chan; |
1866 | wk->chan_type = channel_type; | ||
1866 | wk->sdata = sdata; | 1867 | wk->sdata = sdata; |
1867 | wk->done = ieee80211_offchan_tx_done; | 1868 | wk->done = ieee80211_offchan_tx_done; |
1868 | wk->offchan_tx.frame = skb; | 1869 | wk->offchan_tx.frame = skb; |
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 1f02e599a318..51f0d780dafa 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c | |||
@@ -60,6 +60,10 @@ static const struct file_operations name## _ops = { \ | |||
60 | debugfs_create_file(#name, mode, phyd, local, &name## _ops); | 60 | debugfs_create_file(#name, mode, phyd, local, &name## _ops); |
61 | 61 | ||
62 | 62 | ||
63 | DEBUGFS_READONLY_FILE(user_power, "%d", | ||
64 | local->user_power_level); | ||
65 | DEBUGFS_READONLY_FILE(power, "%d", | ||
66 | local->hw.conf.power_level); | ||
63 | DEBUGFS_READONLY_FILE(frequency, "%d", | 67 | DEBUGFS_READONLY_FILE(frequency, "%d", |
64 | local->hw.conf.channel->center_freq); | 68 | local->hw.conf.channel->center_freq); |
65 | DEBUGFS_READONLY_FILE(total_ps_buffered, "%d", | 69 | DEBUGFS_READONLY_FILE(total_ps_buffered, "%d", |
@@ -391,6 +395,8 @@ void debugfs_hw_add(struct ieee80211_local *local) | |||
391 | DEBUGFS_ADD(uapsd_queues); | 395 | DEBUGFS_ADD(uapsd_queues); |
392 | DEBUGFS_ADD(uapsd_max_sp_len); | 396 | DEBUGFS_ADD(uapsd_max_sp_len); |
393 | DEBUGFS_ADD(channel_type); | 397 | DEBUGFS_ADD(channel_type); |
398 | DEBUGFS_ADD(user_power); | ||
399 | DEBUGFS_ADD(power); | ||
394 | 400 | ||
395 | statsd = debugfs_create_dir("statistics", phyd); | 401 | statsd = debugfs_create_dir("statistics", phyd); |
396 | 402 | ||
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 775fb63471c4..a42aa61269ea 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -664,12 +664,13 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) | |||
664 | } | 664 | } |
665 | 665 | ||
666 | static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, | 666 | static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, |
667 | struct ieee80211_mgmt *mgmt, | 667 | struct sk_buff *req) |
668 | size_t len) | ||
669 | { | 668 | { |
669 | struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(req); | ||
670 | struct ieee80211_mgmt *mgmt = (void *)req->data; | ||
670 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | 671 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; |
671 | struct ieee80211_local *local = sdata->local; | 672 | struct ieee80211_local *local = sdata->local; |
672 | int tx_last_beacon; | 673 | int tx_last_beacon, len = req->len; |
673 | struct sk_buff *skb; | 674 | struct sk_buff *skb; |
674 | struct ieee80211_mgmt *resp; | 675 | struct ieee80211_mgmt *resp; |
675 | u8 *pos, *end; | 676 | u8 *pos, *end; |
@@ -689,7 +690,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, | |||
689 | mgmt->bssid, tx_last_beacon); | 690 | mgmt->bssid, tx_last_beacon); |
690 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 691 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
691 | 692 | ||
692 | if (!tx_last_beacon) | 693 | if (!tx_last_beacon && !(rx_status->rx_flags & IEEE80211_RX_RA_MATCH)) |
693 | return; | 694 | return; |
694 | 695 | ||
695 | if (memcmp(mgmt->bssid, ifibss->bssid, ETH_ALEN) != 0 && | 696 | if (memcmp(mgmt->bssid, ifibss->bssid, ETH_ALEN) != 0 && |
@@ -786,7 +787,7 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
786 | 787 | ||
787 | switch (fc & IEEE80211_FCTL_STYPE) { | 788 | switch (fc & IEEE80211_FCTL_STYPE) { |
788 | case IEEE80211_STYPE_PROBE_REQ: | 789 | case IEEE80211_STYPE_PROBE_REQ: |
789 | ieee80211_rx_mgmt_probe_req(sdata, mgmt, skb->len); | 790 | ieee80211_rx_mgmt_probe_req(sdata, skb); |
790 | break; | 791 | break; |
791 | case IEEE80211_STYPE_PROBE_RESP: | 792 | case IEEE80211_STYPE_PROBE_RESP: |
792 | ieee80211_rx_mgmt_probe_resp(sdata, mgmt, skb->len, | 793 | ieee80211_rx_mgmt_probe_resp(sdata, mgmt, skb->len, |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index f2ef15d910a5..0a570a111a84 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1066,8 +1066,6 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
1066 | void ieee80211_configure_filter(struct ieee80211_local *local); | 1066 | void ieee80211_configure_filter(struct ieee80211_local *local); |
1067 | u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata); | 1067 | u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata); |
1068 | 1068 | ||
1069 | extern bool ieee80211_disable_40mhz_24ghz; | ||
1070 | |||
1071 | /* STA code */ | 1069 | /* STA code */ |
1072 | void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata); | 1070 | void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata); |
1073 | int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | 1071 | int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index c155c0b69426..2543e48bd813 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -34,7 +34,7 @@ | |||
34 | #include "debugfs.h" | 34 | #include "debugfs.h" |
35 | 35 | ||
36 | 36 | ||
37 | bool ieee80211_disable_40mhz_24ghz; | 37 | static bool ieee80211_disable_40mhz_24ghz; |
38 | module_param(ieee80211_disable_40mhz_24ghz, bool, 0644); | 38 | module_param(ieee80211_disable_40mhz_24ghz, bool, 0644); |
39 | MODULE_PARM_DESC(ieee80211_disable_40mhz_24ghz, | 39 | MODULE_PARM_DESC(ieee80211_disable_40mhz_24ghz, |
40 | "Disable 40MHz support in the 2.4GHz band"); | 40 | "Disable 40MHz support in the 2.4GHz band"); |
@@ -112,7 +112,13 @@ bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local) | |||
112 | /* This logic needs to match logic in ieee80211_hw_config */ | 112 | /* This logic needs to match logic in ieee80211_hw_config */ |
113 | if (local->scan_channel) { | 113 | if (local->scan_channel) { |
114 | chan = local->scan_channel; | 114 | chan = local->scan_channel; |
115 | channel_type = NL80211_CHAN_NO_HT; | 115 | /* If scanning on oper channel, use whatever channel-type |
116 | * is currently in use. | ||
117 | */ | ||
118 | if (chan == local->oper_channel) | ||
119 | channel_type = local->_oper_channel_type; | ||
120 | else | ||
121 | channel_type = NL80211_CHAN_NO_HT; | ||
116 | } else if (local->tmp_channel) { | 122 | } else if (local->tmp_channel) { |
117 | chan = scan_chan = local->tmp_channel; | 123 | chan = scan_chan = local->tmp_channel; |
118 | channel_type = local->tmp_channel_type; | 124 | channel_type = local->tmp_channel_type; |
@@ -151,7 +157,13 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | |||
151 | offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; | 157 | offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; |
152 | if (scan_chan) { | 158 | if (scan_chan) { |
153 | chan = scan_chan; | 159 | chan = scan_chan; |
154 | channel_type = NL80211_CHAN_NO_HT; | 160 | /* If scanning on oper channel, use whatever channel-type |
161 | * is currently in use. | ||
162 | */ | ||
163 | if (chan == local->oper_channel) | ||
164 | channel_type = local->_oper_channel_type; | ||
165 | else | ||
166 | channel_type = NL80211_CHAN_NO_HT; | ||
155 | } else if (local->tmp_channel) { | 167 | } else if (local->tmp_channel) { |
156 | chan = scan_chan = local->tmp_channel; | 168 | chan = scan_chan = local->tmp_channel; |
157 | channel_type = local->tmp_channel_type; | 169 | channel_type = local->tmp_channel_type; |
@@ -187,7 +199,8 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | |||
187 | changed |= IEEE80211_CONF_CHANGE_SMPS; | 199 | changed |= IEEE80211_CONF_CHANGE_SMPS; |
188 | } | 200 | } |
189 | 201 | ||
190 | if (scan_chan) | 202 | if ((local->scanning & SCAN_SW_SCANNING) || |
203 | (local->scanning & SCAN_HW_SCANNING)) | ||
191 | power = chan->max_power; | 204 | power = chan->max_power; |
192 | else | 205 | else |
193 | power = local->power_constr_level ? | 206 | power = local->power_constr_level ? |
@@ -710,6 +723,18 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
710 | } | 723 | } |
711 | channels += sband->n_channels; | 724 | channels += sband->n_channels; |
712 | 725 | ||
726 | /* | ||
727 | * Since ieee80211_disable_40mhz_24ghz is global, we can | ||
728 | * modify the sband's ht data even if the driver uses a | ||
729 | * global structure for that. | ||
730 | */ | ||
731 | if (ieee80211_disable_40mhz_24ghz && | ||
732 | band == IEEE80211_BAND_2GHZ && | ||
733 | sband->ht_cap.ht_supported) { | ||
734 | sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; | ||
735 | sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40; | ||
736 | } | ||
737 | |||
713 | if (max_bitrates < sband->n_bitrates) | 738 | if (max_bitrates < sband->n_bitrates) |
714 | max_bitrates = sband->n_bitrates; | 739 | max_bitrates = sband->n_bitrates; |
715 | supp_ht = supp_ht || sband->ht_cap.ht_supported; | 740 | supp_ht = supp_ht || sband->ht_cap.ht_supported; |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index f77adf1a520e..7b3f9df725bd 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -1071,6 +1071,12 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, | |||
1071 | if (is_multicast_ether_addr(hdr->addr1)) | 1071 | if (is_multicast_ether_addr(hdr->addr1)) |
1072 | return; | 1072 | return; |
1073 | 1073 | ||
1074 | /* | ||
1075 | * In case we receive frames after disassociation. | ||
1076 | */ | ||
1077 | if (!sdata->u.mgd.associated) | ||
1078 | return; | ||
1079 | |||
1074 | ieee80211_sta_reset_conn_monitor(sdata); | 1080 | ieee80211_sta_reset_conn_monitor(sdata); |
1075 | } | 1081 | } |
1076 | 1082 | ||
@@ -2294,6 +2300,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
2294 | else | 2300 | else |
2295 | wk->type = IEEE80211_WORK_DIRECT_PROBE; | 2301 | wk->type = IEEE80211_WORK_DIRECT_PROBE; |
2296 | wk->chan = req->bss->channel; | 2302 | wk->chan = req->bss->channel; |
2303 | wk->chan_type = NL80211_CHAN_NO_HT; | ||
2297 | wk->sdata = sdata; | 2304 | wk->sdata = sdata; |
2298 | wk->done = ieee80211_probe_auth_done; | 2305 | wk->done = ieee80211_probe_auth_done; |
2299 | 2306 | ||
@@ -2443,6 +2450,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
2443 | memcpy(wk->assoc.prev_bssid, req->prev_bssid, ETH_ALEN); | 2450 | memcpy(wk->assoc.prev_bssid, req->prev_bssid, ETH_ALEN); |
2444 | 2451 | ||
2445 | wk->chan = req->bss->channel; | 2452 | wk->chan = req->bss->channel; |
2453 | wk->chan_type = NL80211_CHAN_NO_HT; | ||
2446 | wk->sdata = sdata; | 2454 | wk->sdata = sdata; |
2447 | wk->done = ieee80211_assoc_done; | 2455 | wk->done = ieee80211_assoc_done; |
2448 | if (!bss->dtim_period && | 2456 | if (!bss->dtim_period && |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 045b2fe4a414..f502634d43af 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -832,18 +832,8 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | |||
832 | ieee80211_is_pspoll(hdr->frame_control)) && | 832 | ieee80211_is_pspoll(hdr->frame_control)) && |
833 | rx->sdata->vif.type != NL80211_IFTYPE_ADHOC && | 833 | rx->sdata->vif.type != NL80211_IFTYPE_ADHOC && |
834 | rx->sdata->vif.type != NL80211_IFTYPE_WDS && | 834 | rx->sdata->vif.type != NL80211_IFTYPE_WDS && |
835 | (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) { | 835 | (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) |
836 | if ((!ieee80211_has_fromds(hdr->frame_control) && | ||
837 | !ieee80211_has_tods(hdr->frame_control) && | ||
838 | ieee80211_is_data(hdr->frame_control)) || | ||
839 | !(status->rx_flags & IEEE80211_RX_RA_MATCH)) { | ||
840 | /* Drop IBSS frames and frames for other hosts | ||
841 | * silently. */ | ||
842 | return RX_DROP_MONITOR; | ||
843 | } | ||
844 | |||
845 | return RX_DROP_MONITOR; | 836 | return RX_DROP_MONITOR; |
846 | } | ||
847 | 837 | ||
848 | return RX_CONTINUE; | 838 | return RX_CONTINUE; |
849 | } | 839 | } |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 0ea6adae3e06..842954509925 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -307,11 +307,15 @@ static void __ieee80211_scan_completed_finish(struct ieee80211_hw *hw, | |||
307 | mutex_lock(&local->mtx); | 307 | mutex_lock(&local->mtx); |
308 | on_oper_chan = ieee80211_cfg_on_oper_channel(local); | 308 | on_oper_chan = ieee80211_cfg_on_oper_channel(local); |
309 | 309 | ||
310 | WARN_ON(local->scanning & (SCAN_SW_SCANNING | SCAN_HW_SCANNING)); | ||
311 | |||
310 | if (was_hw_scan || !on_oper_chan) { | 312 | if (was_hw_scan || !on_oper_chan) { |
311 | if (WARN_ON(local->scan_channel)) | 313 | if (WARN_ON(local->scan_channel)) |
312 | local->scan_channel = NULL; | 314 | local->scan_channel = NULL; |
313 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | 315 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); |
314 | } | 316 | } else |
317 | /* Set power back to normal operating levels. */ | ||
318 | ieee80211_hw_config(local, 0); | ||
315 | 319 | ||
316 | if (!was_hw_scan) { | 320 | if (!was_hw_scan) { |
317 | bool on_oper_chan2; | 321 | bool on_oper_chan2; |
@@ -377,6 +381,9 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local) | |||
377 | 381 | ||
378 | ieee80211_configure_filter(local); | 382 | ieee80211_configure_filter(local); |
379 | 383 | ||
384 | /* We need to set power level at maximum rate for scanning. */ | ||
385 | ieee80211_hw_config(local, 0); | ||
386 | |||
380 | ieee80211_queue_delayed_work(&local->hw, | 387 | ieee80211_queue_delayed_work(&local->hw, |
381 | &local->scan_work, | 388 | &local->scan_work, |
382 | IEEE80211_CHANNEL_TIME); | 389 | IEEE80211_CHANNEL_TIME); |
@@ -517,8 +524,7 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local, | |||
517 | 524 | ||
518 | if (ieee80211_cfg_on_oper_channel(local)) { | 525 | if (ieee80211_cfg_on_oper_channel(local)) { |
519 | /* We're currently on operating channel. */ | 526 | /* We're currently on operating channel. */ |
520 | if ((next_chan == local->oper_channel) && | 527 | if (next_chan == local->oper_channel) |
521 | (local->_oper_channel_type == NL80211_CHAN_NO_HT)) | ||
522 | /* We don't need to move off of operating channel. */ | 528 | /* We don't need to move off of operating channel. */ |
523 | local->next_scan_state = SCAN_SET_CHANNEL; | 529 | local->next_scan_state = SCAN_SET_CHANNEL; |
524 | else | 530 | else |
@@ -620,8 +626,7 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local, | |||
620 | local->scan_channel = chan; | 626 | local->scan_channel = chan; |
621 | 627 | ||
622 | /* Only call hw-config if we really need to change channels. */ | 628 | /* Only call hw-config if we really need to change channels. */ |
623 | if ((chan != local->hw.conf.channel) || | 629 | if (chan != local->hw.conf.channel) |
624 | (local->hw.conf.channel_type != NL80211_CHAN_NO_HT)) | ||
625 | if (ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL)) | 630 | if (ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL)) |
626 | skip = 1; | 631 | skip = 1; |
627 | 632 | ||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 17ef4f4e8602..34edf7f22b0e 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -236,6 +236,7 @@ ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx) | |||
236 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { | 236 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { |
237 | ieee80211_stop_queues_by_reason(&local->hw, | 237 | ieee80211_stop_queues_by_reason(&local->hw, |
238 | IEEE80211_QUEUE_STOP_REASON_PS); | 238 | IEEE80211_QUEUE_STOP_REASON_PS); |
239 | ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED; | ||
239 | ieee80211_queue_work(&local->hw, | 240 | ieee80211_queue_work(&local->hw, |
240 | &local->dynamic_ps_disable_work); | 241 | &local->dynamic_ps_disable_work); |
241 | } | 242 | } |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index d036597aabbe..556647a910ac 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -986,12 +986,6 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | |||
986 | u16 cap = sband->ht_cap.cap; | 986 | u16 cap = sband->ht_cap.cap; |
987 | __le16 tmp; | 987 | __le16 tmp; |
988 | 988 | ||
989 | if (ieee80211_disable_40mhz_24ghz && | ||
990 | sband->band == IEEE80211_BAND_2GHZ) { | ||
991 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; | ||
992 | cap &= ~IEEE80211_HT_CAP_SGI_40; | ||
993 | } | ||
994 | |||
995 | *pos++ = WLAN_EID_HT_CAPABILITY; | 989 | *pos++ = WLAN_EID_HT_CAPABILITY; |
996 | *pos++ = sizeof(struct ieee80211_ht_cap); | 990 | *pos++ = sizeof(struct ieee80211_ht_cap); |
997 | memset(pos, 0, sizeof(struct ieee80211_ht_cap)); | 991 | memset(pos, 0, sizeof(struct ieee80211_ht_cap)); |
diff --git a/net/mac80211/work.c b/net/mac80211/work.c index 6bf787a5b38a..204f0a4db969 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c | |||
@@ -126,12 +126,6 @@ static void ieee80211_add_ht_ie(struct sk_buff *skb, const u8 *ht_info_ie, | |||
126 | 126 | ||
127 | /* determine capability flags */ | 127 | /* determine capability flags */ |
128 | 128 | ||
129 | if (ieee80211_disable_40mhz_24ghz && | ||
130 | sband->band == IEEE80211_BAND_2GHZ) { | ||
131 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; | ||
132 | cap &= ~IEEE80211_HT_CAP_SGI_40; | ||
133 | } | ||
134 | |||
135 | switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { | 129 | switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { |
136 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: | 130 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: |
137 | if (flags & IEEE80211_CHAN_NO_HT40PLUS) { | 131 | if (flags & IEEE80211_CHAN_NO_HT40PLUS) { |
@@ -874,6 +868,44 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local, | |||
874 | kfree_skb(skb); | 868 | kfree_skb(skb); |
875 | } | 869 | } |
876 | 870 | ||
871 | static bool ieee80211_work_ct_coexists(enum nl80211_channel_type wk_ct, | ||
872 | enum nl80211_channel_type oper_ct) | ||
873 | { | ||
874 | switch (wk_ct) { | ||
875 | case NL80211_CHAN_NO_HT: | ||
876 | return true; | ||
877 | case NL80211_CHAN_HT20: | ||
878 | if (oper_ct != NL80211_CHAN_NO_HT) | ||
879 | return true; | ||
880 | return false; | ||
881 | case NL80211_CHAN_HT40MINUS: | ||
882 | case NL80211_CHAN_HT40PLUS: | ||
883 | return (wk_ct == oper_ct); | ||
884 | } | ||
885 | WARN_ON(1); /* shouldn't get here */ | ||
886 | return false; | ||
887 | } | ||
888 | |||
889 | static enum nl80211_channel_type | ||
890 | ieee80211_calc_ct(enum nl80211_channel_type wk_ct, | ||
891 | enum nl80211_channel_type oper_ct) | ||
892 | { | ||
893 | switch (wk_ct) { | ||
894 | case NL80211_CHAN_NO_HT: | ||
895 | return oper_ct; | ||
896 | case NL80211_CHAN_HT20: | ||
897 | if (oper_ct != NL80211_CHAN_NO_HT) | ||
898 | return oper_ct; | ||
899 | return wk_ct; | ||
900 | case NL80211_CHAN_HT40MINUS: | ||
901 | case NL80211_CHAN_HT40PLUS: | ||
902 | return wk_ct; | ||
903 | } | ||
904 | WARN_ON(1); /* shouldn't get here */ | ||
905 | return wk_ct; | ||
906 | } | ||
907 | |||
908 | |||
877 | static void ieee80211_work_timer(unsigned long data) | 909 | static void ieee80211_work_timer(unsigned long data) |
878 | { | 910 | { |
879 | struct ieee80211_local *local = (void *) data; | 911 | struct ieee80211_local *local = (void *) data; |
@@ -927,14 +959,22 @@ static void ieee80211_work_work(struct work_struct *work) | |||
927 | bool on_oper_chan; | 959 | bool on_oper_chan; |
928 | bool tmp_chan_changed = false; | 960 | bool tmp_chan_changed = false; |
929 | bool on_oper_chan2; | 961 | bool on_oper_chan2; |
962 | enum nl80211_channel_type wk_ct; | ||
930 | on_oper_chan = ieee80211_cfg_on_oper_channel(local); | 963 | on_oper_chan = ieee80211_cfg_on_oper_channel(local); |
964 | |||
965 | /* Work with existing channel type if possible. */ | ||
966 | wk_ct = wk->chan_type; | ||
967 | if (wk->chan == local->hw.conf.channel) | ||
968 | wk_ct = ieee80211_calc_ct(wk->chan_type, | ||
969 | local->hw.conf.channel_type); | ||
970 | |||
931 | if (local->tmp_channel) | 971 | if (local->tmp_channel) |
932 | if ((local->tmp_channel != wk->chan) || | 972 | if ((local->tmp_channel != wk->chan) || |
933 | (local->tmp_channel_type != wk->chan_type)) | 973 | (local->tmp_channel_type != wk_ct)) |
934 | tmp_chan_changed = true; | 974 | tmp_chan_changed = true; |
935 | 975 | ||
936 | local->tmp_channel = wk->chan; | 976 | local->tmp_channel = wk->chan; |
937 | local->tmp_channel_type = wk->chan_type; | 977 | local->tmp_channel_type = wk_ct; |
938 | /* | 978 | /* |
939 | * Leave the station vifs in awake mode if they | 979 | * Leave the station vifs in awake mode if they |
940 | * happen to be on the same channel as | 980 | * happen to be on the same channel as |
@@ -1031,7 +1071,8 @@ static void ieee80211_work_work(struct work_struct *work) | |||
1031 | continue; | 1071 | continue; |
1032 | if (wk->chan != local->tmp_channel) | 1072 | if (wk->chan != local->tmp_channel) |
1033 | continue; | 1073 | continue; |
1034 | if (wk->chan_type != local->tmp_channel_type) | 1074 | if (ieee80211_work_ct_coexists(wk->chan_type, |
1075 | local->tmp_channel_type)) | ||
1035 | continue; | 1076 | continue; |
1036 | remain_off_channel = true; | 1077 | remain_off_channel = true; |
1037 | } | 1078 | } |