diff options
author | John W. Linville <linville@tuxdriver.com> | 2012-11-28 10:56:03 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-11-28 10:56:03 -0500 |
commit | 79d38f7d6cf545ff838dd5227869f3916d1d100d (patch) | |
tree | 859c8071aab68fd32f36ffb9ebc04cf12db6e5e0 /drivers/net | |
parent | 03f52a0a554210d5049eeed9f1bb29047dc807cb (diff) | |
parent | 0751f8654602e4255f0b9c17784d8100d5896010 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts:
drivers/net/wireless/iwlwifi/pcie/tx.c
Diffstat (limited to 'drivers/net')
207 files changed, 22895 insertions, 6619 deletions
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c index 99b9ddf21273..77fa4286e5e9 100644 --- a/drivers/net/wireless/at76c50x-usb.c +++ b/drivers/net/wireless/at76c50x-usb.c | |||
@@ -379,7 +379,7 @@ static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size, | |||
379 | manifest_sync_timeout); | 379 | manifest_sync_timeout); |
380 | 380 | ||
381 | if (!size) { | 381 | if (!size) { |
382 | dev_printk(KERN_ERR, &udev->dev, "FW buffer length invalid!\n"); | 382 | dev_err(&udev->dev, "FW buffer length invalid!\n"); |
383 | return -EINVAL; | 383 | return -EINVAL; |
384 | } | 384 | } |
385 | 385 | ||
@@ -391,8 +391,8 @@ static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size, | |||
391 | if (need_dfu_state) { | 391 | if (need_dfu_state) { |
392 | ret = at76_dfu_get_state(udev, &dfu_state); | 392 | ret = at76_dfu_get_state(udev, &dfu_state); |
393 | if (ret < 0) { | 393 | if (ret < 0) { |
394 | dev_printk(KERN_ERR, &udev->dev, | 394 | dev_err(&udev->dev, |
395 | "cannot get DFU state: %d\n", ret); | 395 | "cannot get DFU state: %d\n", ret); |
396 | goto exit; | 396 | goto exit; |
397 | } | 397 | } |
398 | need_dfu_state = 0; | 398 | need_dfu_state = 0; |
@@ -407,9 +407,9 @@ static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size, | |||
407 | dfu_timeout = at76_get_timeout(&dfu_stat_buf); | 407 | dfu_timeout = at76_get_timeout(&dfu_stat_buf); |
408 | need_dfu_state = 0; | 408 | need_dfu_state = 0; |
409 | } else | 409 | } else |
410 | dev_printk(KERN_ERR, &udev->dev, | 410 | dev_err(&udev->dev, |
411 | "at76_dfu_get_status returned %d\n", | 411 | "at76_dfu_get_status returned %d\n", |
412 | ret); | 412 | ret); |
413 | break; | 413 | break; |
414 | 414 | ||
415 | case STATE_DFU_DOWNLOAD_BUSY: | 415 | case STATE_DFU_DOWNLOAD_BUSY: |
@@ -438,9 +438,9 @@ static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size, | |||
438 | blockno++; | 438 | blockno++; |
439 | 439 | ||
440 | if (ret != bsize) | 440 | if (ret != bsize) |
441 | dev_printk(KERN_ERR, &udev->dev, | 441 | dev_err(&udev->dev, |
442 | "at76_load_int_fw_block " | 442 | "at76_load_int_fw_block returned %d\n", |
443 | "returned %d\n", ret); | 443 | ret); |
444 | need_dfu_state = 1; | 444 | need_dfu_state = 1; |
445 | break; | 445 | break; |
446 | 446 | ||
@@ -1255,8 +1255,7 @@ static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe) | |||
1255 | at76_dbg(DBG_DEVSTART, "opmode %d", op_mode); | 1255 | at76_dbg(DBG_DEVSTART, "opmode %d", op_mode); |
1256 | 1256 | ||
1257 | if (op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) { | 1257 | if (op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) { |
1258 | dev_printk(KERN_ERR, &udev->dev, "unexpected opmode %d\n", | 1258 | dev_err(&udev->dev, "unexpected opmode %d\n", op_mode); |
1259 | op_mode); | ||
1260 | return -EINVAL; | 1259 | return -EINVAL; |
1261 | } | 1260 | } |
1262 | 1261 | ||
@@ -1275,9 +1274,9 @@ static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe) | |||
1275 | size, bsize, blockno); | 1274 | size, bsize, blockno); |
1276 | ret = at76_load_ext_fw_block(udev, blockno, block, bsize); | 1275 | ret = at76_load_ext_fw_block(udev, blockno, block, bsize); |
1277 | if (ret != bsize) { | 1276 | if (ret != bsize) { |
1278 | dev_printk(KERN_ERR, &udev->dev, | 1277 | dev_err(&udev->dev, |
1279 | "loading %dth firmware block failed: %d\n", | 1278 | "loading %dth firmware block failed: %d\n", |
1280 | blockno, ret); | 1279 | blockno, ret); |
1281 | goto exit; | 1280 | goto exit; |
1282 | } | 1281 | } |
1283 | buf += bsize; | 1282 | buf += bsize; |
@@ -1293,8 +1292,8 @@ static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe) | |||
1293 | exit: | 1292 | exit: |
1294 | kfree(block); | 1293 | kfree(block); |
1295 | if (ret < 0) | 1294 | if (ret < 0) |
1296 | dev_printk(KERN_ERR, &udev->dev, | 1295 | dev_err(&udev->dev, |
1297 | "downloading external firmware failed: %d\n", ret); | 1296 | "downloading external firmware failed: %d\n", ret); |
1298 | return ret; | 1297 | return ret; |
1299 | } | 1298 | } |
1300 | 1299 | ||
@@ -1308,8 +1307,8 @@ static int at76_load_internal_fw(struct usb_device *udev, struct fwentry *fwe) | |||
1308 | need_remap ? 0 : 2 * HZ); | 1307 | need_remap ? 0 : 2 * HZ); |
1309 | 1308 | ||
1310 | if (ret < 0) { | 1309 | if (ret < 0) { |
1311 | dev_printk(KERN_ERR, &udev->dev, | 1310 | dev_err(&udev->dev, |
1312 | "downloading internal fw failed with %d\n", ret); | 1311 | "downloading internal fw failed with %d\n", ret); |
1313 | goto exit; | 1312 | goto exit; |
1314 | } | 1313 | } |
1315 | 1314 | ||
@@ -1319,8 +1318,8 @@ static int at76_load_internal_fw(struct usb_device *udev, struct fwentry *fwe) | |||
1319 | if (need_remap) { | 1318 | if (need_remap) { |
1320 | ret = at76_remap(udev); | 1319 | ret = at76_remap(udev); |
1321 | if (ret < 0) { | 1320 | if (ret < 0) { |
1322 | dev_printk(KERN_ERR, &udev->dev, | 1321 | dev_err(&udev->dev, |
1323 | "sending REMAP failed with %d\n", ret); | 1322 | "sending REMAP failed with %d\n", ret); |
1324 | goto exit; | 1323 | goto exit; |
1325 | } | 1324 | } |
1326 | } | 1325 | } |
@@ -1555,11 +1554,10 @@ static struct fwentry *at76_load_firmware(struct usb_device *udev, | |||
1555 | at76_dbg(DBG_FW, "downloading firmware %s", fwe->fwname); | 1554 | at76_dbg(DBG_FW, "downloading firmware %s", fwe->fwname); |
1556 | ret = request_firmware(&fwe->fw, fwe->fwname, &udev->dev); | 1555 | ret = request_firmware(&fwe->fw, fwe->fwname, &udev->dev); |
1557 | if (ret < 0) { | 1556 | if (ret < 0) { |
1558 | dev_printk(KERN_ERR, &udev->dev, "firmware %s not found!\n", | 1557 | dev_err(&udev->dev, "firmware %s not found!\n", |
1559 | fwe->fwname); | 1558 | fwe->fwname); |
1560 | dev_printk(KERN_ERR, &udev->dev, | 1559 | dev_err(&udev->dev, |
1561 | "you may need to download the firmware from " | 1560 | "you may need to download the firmware from http://developer.berlios.de/projects/at76c503a/\n"); |
1562 | "http://developer.berlios.de/projects/at76c503a/\n"); | ||
1563 | goto exit; | 1561 | goto exit; |
1564 | } | 1562 | } |
1565 | 1563 | ||
@@ -1567,17 +1565,17 @@ static struct fwentry *at76_load_firmware(struct usb_device *udev, | |||
1567 | fwh = (struct at76_fw_header *)(fwe->fw->data); | 1565 | fwh = (struct at76_fw_header *)(fwe->fw->data); |
1568 | 1566 | ||
1569 | if (fwe->fw->size <= sizeof(*fwh)) { | 1567 | if (fwe->fw->size <= sizeof(*fwh)) { |
1570 | dev_printk(KERN_ERR, &udev->dev, | 1568 | dev_err(&udev->dev, |
1571 | "firmware is too short (0x%zx)\n", fwe->fw->size); | 1569 | "firmware is too short (0x%zx)\n", fwe->fw->size); |
1572 | goto exit; | 1570 | goto exit; |
1573 | } | 1571 | } |
1574 | 1572 | ||
1575 | /* CRC currently not checked */ | 1573 | /* CRC currently not checked */ |
1576 | fwe->board_type = le32_to_cpu(fwh->board_type); | 1574 | fwe->board_type = le32_to_cpu(fwh->board_type); |
1577 | if (fwe->board_type != board_type) { | 1575 | if (fwe->board_type != board_type) { |
1578 | dev_printk(KERN_ERR, &udev->dev, | 1576 | dev_err(&udev->dev, |
1579 | "board type mismatch, requested %u, got %u\n", | 1577 | "board type mismatch, requested %u, got %u\n", |
1580 | board_type, fwe->board_type); | 1578 | board_type, fwe->board_type); |
1581 | goto exit; | 1579 | goto exit; |
1582 | } | 1580 | } |
1583 | 1581 | ||
@@ -2150,8 +2148,7 @@ static int at76_alloc_urbs(struct at76_priv *priv, | |||
2150 | } | 2148 | } |
2151 | 2149 | ||
2152 | if (!ep_in || !ep_out) { | 2150 | if (!ep_in || !ep_out) { |
2153 | dev_printk(KERN_ERR, &interface->dev, | 2151 | dev_err(&interface->dev, "bulk endpoints missing\n"); |
2154 | "bulk endpoints missing\n"); | ||
2155 | return -ENXIO; | 2152 | return -ENXIO; |
2156 | } | 2153 | } |
2157 | 2154 | ||
@@ -2161,15 +2158,14 @@ static int at76_alloc_urbs(struct at76_priv *priv, | |||
2161 | priv->rx_urb = usb_alloc_urb(0, GFP_KERNEL); | 2158 | priv->rx_urb = usb_alloc_urb(0, GFP_KERNEL); |
2162 | priv->tx_urb = usb_alloc_urb(0, GFP_KERNEL); | 2159 | priv->tx_urb = usb_alloc_urb(0, GFP_KERNEL); |
2163 | if (!priv->rx_urb || !priv->tx_urb) { | 2160 | if (!priv->rx_urb || !priv->tx_urb) { |
2164 | dev_printk(KERN_ERR, &interface->dev, "cannot allocate URB\n"); | 2161 | dev_err(&interface->dev, "cannot allocate URB\n"); |
2165 | return -ENOMEM; | 2162 | return -ENOMEM; |
2166 | } | 2163 | } |
2167 | 2164 | ||
2168 | buffer_size = sizeof(struct at76_tx_buffer) + MAX_PADDING_SIZE; | 2165 | buffer_size = sizeof(struct at76_tx_buffer) + MAX_PADDING_SIZE; |
2169 | priv->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL); | 2166 | priv->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL); |
2170 | if (!priv->bulk_out_buffer) { | 2167 | if (!priv->bulk_out_buffer) { |
2171 | dev_printk(KERN_ERR, &interface->dev, | 2168 | dev_err(&interface->dev, "cannot allocate output buffer\n"); |
2172 | "cannot allocate output buffer\n"); | ||
2173 | return -ENOMEM; | 2169 | return -ENOMEM; |
2174 | } | 2170 | } |
2175 | 2171 | ||
@@ -2230,8 +2226,7 @@ static int at76_init_new_device(struct at76_priv *priv, | |||
2230 | /* MAC address */ | 2226 | /* MAC address */ |
2231 | ret = at76_get_hw_config(priv); | 2227 | ret = at76_get_hw_config(priv); |
2232 | if (ret < 0) { | 2228 | if (ret < 0) { |
2233 | dev_printk(KERN_ERR, &interface->dev, | 2229 | dev_err(&interface->dev, "cannot get MAC address\n"); |
2234 | "cannot get MAC address\n"); | ||
2235 | goto exit; | 2230 | goto exit; |
2236 | } | 2231 | } |
2237 | 2232 | ||
@@ -2358,8 +2353,8 @@ static int at76_probe(struct usb_interface *interface, | |||
2358 | we get 204 with 2.4.23, Fiberline FL-WL240u (505A+RFMD2958) ??? */ | 2353 | we get 204 with 2.4.23, Fiberline FL-WL240u (505A+RFMD2958) ??? */ |
2359 | 2354 | ||
2360 | if (op_mode == OPMODE_HW_CONFIG_MODE) { | 2355 | if (op_mode == OPMODE_HW_CONFIG_MODE) { |
2361 | dev_printk(KERN_ERR, &interface->dev, | 2356 | dev_err(&interface->dev, |
2362 | "cannot handle a device in HW_CONFIG_MODE\n"); | 2357 | "cannot handle a device in HW_CONFIG_MODE\n"); |
2363 | ret = -EBUSY; | 2358 | ret = -EBUSY; |
2364 | goto error; | 2359 | goto error; |
2365 | } | 2360 | } |
@@ -2371,9 +2366,9 @@ static int at76_probe(struct usb_interface *interface, | |||
2371 | "downloading internal firmware\n"); | 2366 | "downloading internal firmware\n"); |
2372 | ret = at76_load_internal_fw(udev, fwe); | 2367 | ret = at76_load_internal_fw(udev, fwe); |
2373 | if (ret < 0) { | 2368 | if (ret < 0) { |
2374 | dev_printk(KERN_ERR, &interface->dev, | 2369 | dev_err(&interface->dev, |
2375 | "error %d downloading internal firmware\n", | 2370 | "error %d downloading internal firmware\n", |
2376 | ret); | 2371 | ret); |
2377 | goto error; | 2372 | goto error; |
2378 | } | 2373 | } |
2379 | usb_put_dev(udev); | 2374 | usb_put_dev(udev); |
@@ -2408,8 +2403,8 @@ static int at76_probe(struct usb_interface *interface, | |||
2408 | /* Re-check firmware version */ | 2403 | /* Re-check firmware version */ |
2409 | ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv)); | 2404 | ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv)); |
2410 | if (ret < 0) { | 2405 | if (ret < 0) { |
2411 | dev_printk(KERN_ERR, &interface->dev, | 2406 | dev_err(&interface->dev, |
2412 | "error %d getting firmware version\n", ret); | 2407 | "error %d getting firmware version\n", ret); |
2413 | goto error; | 2408 | goto error; |
2414 | } | 2409 | } |
2415 | } | 2410 | } |
@@ -2449,7 +2444,7 @@ static void at76_disconnect(struct usb_interface *interface) | |||
2449 | 2444 | ||
2450 | wiphy_info(priv->hw->wiphy, "disconnecting\n"); | 2445 | wiphy_info(priv->hw->wiphy, "disconnecting\n"); |
2451 | at76_delete_device(priv); | 2446 | at76_delete_device(priv); |
2452 | dev_printk(KERN_INFO, &interface->dev, "disconnected\n"); | 2447 | dev_info(&interface->dev, "disconnected\n"); |
2453 | } | 2448 | } |
2454 | 2449 | ||
2455 | /* Structure for registering this driver with the USB subsystem */ | 2450 | /* Structure for registering this driver with the USB subsystem */ |
diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c index f782b6e502bf..7157f7d311c5 100644 --- a/drivers/net/wireless/ath/ar5523/ar5523.c +++ b/drivers/net/wireless/ath/ar5523/ar5523.c | |||
@@ -50,18 +50,19 @@ static void ar5523_read_reply(struct ar5523 *ar, struct ar5523_cmd_hdr *hdr, | |||
50 | struct ar5523_tx_cmd *cmd) | 50 | struct ar5523_tx_cmd *cmd) |
51 | { | 51 | { |
52 | int dlen, olen; | 52 | int dlen, olen; |
53 | u32 *rp; | 53 | __be32 *rp; |
54 | 54 | ||
55 | dlen = hdr->len - sizeof(*hdr); | 55 | dlen = be32_to_cpu(hdr->len) - sizeof(*hdr); |
56 | 56 | ||
57 | if (dlen < 0) { | 57 | if (dlen < 0) { |
58 | WARN_ON(1); | 58 | WARN_ON(1); |
59 | goto out; | 59 | goto out; |
60 | } | 60 | } |
61 | 61 | ||
62 | ar5523_dbg(ar, "Code = %d len = %d\n", hdr->code & 0xff, dlen); | 62 | ar5523_dbg(ar, "Code = %d len = %d\n", be32_to_cpu(hdr->code) & 0xff, |
63 | dlen); | ||
63 | 64 | ||
64 | rp = (u32 *)(hdr + 1); | 65 | rp = (__be32 *)(hdr + 1); |
65 | if (dlen >= sizeof(u32)) { | 66 | if (dlen >= sizeof(u32)) { |
66 | olen = be32_to_cpu(rp[0]); | 67 | olen = be32_to_cpu(rp[0]); |
67 | dlen -= sizeof(u32); | 68 | dlen -= sizeof(u32); |
@@ -95,6 +96,7 @@ static void ar5523_cmd_rx_cb(struct urb *urb) | |||
95 | struct ar5523_tx_cmd *cmd = &ar->tx_cmd; | 96 | struct ar5523_tx_cmd *cmd = &ar->tx_cmd; |
96 | struct ar5523_cmd_hdr *hdr = ar->rx_cmd_buf; | 97 | struct ar5523_cmd_hdr *hdr = ar->rx_cmd_buf; |
97 | int dlen; | 98 | int dlen; |
99 | u32 code, hdrlen; | ||
98 | 100 | ||
99 | if (urb->status) { | 101 | if (urb->status) { |
100 | if (urb->status != -ESHUTDOWN) | 102 | if (urb->status != -ESHUTDOWN) |
@@ -110,15 +112,15 @@ static void ar5523_cmd_rx_cb(struct urb *urb) | |||
110 | ar5523_dbg(ar, "%s code %02x priv %d\n", __func__, | 112 | ar5523_dbg(ar, "%s code %02x priv %d\n", __func__, |
111 | be32_to_cpu(hdr->code) & 0xff, hdr->priv); | 113 | be32_to_cpu(hdr->code) & 0xff, hdr->priv); |
112 | 114 | ||
113 | hdr->code = be32_to_cpu(hdr->code); | 115 | code = be32_to_cpu(hdr->code); |
114 | hdr->len = be32_to_cpu(hdr->len); | 116 | hdrlen = be32_to_cpu(hdr->len); |
115 | 117 | ||
116 | switch (hdr->code & 0xff) { | 118 | switch (code & 0xff) { |
117 | default: | 119 | default: |
118 | /* reply to a read command */ | 120 | /* reply to a read command */ |
119 | if (hdr->priv != AR5523_CMD_ID) { | 121 | if (hdr->priv != AR5523_CMD_ID) { |
120 | ar5523_err(ar, "Unexpected command id: %02x\n", | 122 | ar5523_err(ar, "Unexpected command id: %02x\n", |
121 | hdr->code & 0xff); | 123 | code & 0xff); |
122 | goto skip; | 124 | goto skip; |
123 | } | 125 | } |
124 | ar5523_read_reply(ar, hdr, cmd); | 126 | ar5523_read_reply(ar, hdr, cmd); |
@@ -147,7 +149,7 @@ static void ar5523_cmd_rx_cb(struct urb *urb) | |||
147 | case WDCMSG_TARGET_START: | 149 | case WDCMSG_TARGET_START: |
148 | /* This command returns a bogus id so it needs special | 150 | /* This command returns a bogus id so it needs special |
149 | handling */ | 151 | handling */ |
150 | dlen = hdr->len - sizeof(*hdr); | 152 | dlen = hdrlen - sizeof(*hdr); |
151 | if (dlen != (int)sizeof(u32)) { | 153 | if (dlen != (int)sizeof(u32)) { |
152 | ar5523_err(ar, "Invalid reply to WDCMSG_TARGET_START"); | 154 | ar5523_err(ar, "Invalid reply to WDCMSG_TARGET_START"); |
153 | return; | 155 | return; |
@@ -303,7 +305,7 @@ static int ar5523_config(struct ar5523 *ar, u32 reg, u32 val) | |||
303 | 305 | ||
304 | write.reg = cpu_to_be32(reg); | 306 | write.reg = cpu_to_be32(reg); |
305 | write.len = cpu_to_be32(0); /* 0 = single write */ | 307 | write.len = cpu_to_be32(0); /* 0 = single write */ |
306 | *(u32 *)write.data = cpu_to_be32(val); | 308 | *(__be32 *)write.data = cpu_to_be32(val); |
307 | 309 | ||
308 | error = ar5523_cmd_write(ar, WDCMSG_TARGET_SET_CONFIG, &write, | 310 | error = ar5523_cmd_write(ar, WDCMSG_TARGET_SET_CONFIG, &write, |
309 | 3 * sizeof(u32), 0); | 311 | 3 * sizeof(u32), 0); |
@@ -335,29 +337,30 @@ static int ar5523_get_status(struct ar5523 *ar, u32 which, void *odata, | |||
335 | int olen) | 337 | int olen) |
336 | { | 338 | { |
337 | int error; | 339 | int error; |
340 | __be32 which_be; | ||
338 | 341 | ||
339 | which = cpu_to_be32(which); | 342 | which_be = cpu_to_be32(which); |
340 | error = ar5523_cmd_read(ar, WDCMSG_TARGET_GET_STATUS, | 343 | error = ar5523_cmd_read(ar, WDCMSG_TARGET_GET_STATUS, |
341 | &which, sizeof(which), odata, olen, AR5523_CMD_FLAG_MAGIC); | 344 | &which_be, sizeof(which_be), odata, olen, AR5523_CMD_FLAG_MAGIC); |
342 | if (error != 0) | 345 | if (error != 0) |
343 | ar5523_err(ar, "could not read EEPROM offset 0x%02x\n", | 346 | ar5523_err(ar, "could not read EEPROM offset 0x%02x\n", which); |
344 | be32_to_cpu(which)); | ||
345 | return error; | 347 | return error; |
346 | } | 348 | } |
347 | 349 | ||
348 | static int ar5523_get_capability(struct ar5523 *ar, u32 cap, u32 *val) | 350 | static int ar5523_get_capability(struct ar5523 *ar, u32 cap, u32 *val) |
349 | { | 351 | { |
350 | int error; | 352 | int error; |
353 | __be32 cap_be, val_be; | ||
351 | 354 | ||
352 | cap = cpu_to_be32(cap); | 355 | cap_be = cpu_to_be32(cap); |
353 | error = ar5523_cmd_read(ar, WDCMSG_TARGET_GET_CAPABILITY, | 356 | error = ar5523_cmd_read(ar, WDCMSG_TARGET_GET_CAPABILITY, &cap_be, |
354 | &cap, sizeof(cap), val, sizeof(u32), AR5523_CMD_FLAG_MAGIC); | 357 | sizeof(cap_be), &val_be, sizeof(__be32), |
358 | AR5523_CMD_FLAG_MAGIC); | ||
355 | if (error != 0) { | 359 | if (error != 0) { |
356 | ar5523_err(ar, "could not read capability %u\n", | 360 | ar5523_err(ar, "could not read capability %u\n", cap); |
357 | be32_to_cpu(cap)); | ||
358 | return error; | 361 | return error; |
359 | } | 362 | } |
360 | *val = be32_to_cpu(*val); | 363 | *val = be32_to_cpu(val_be); |
361 | return error; | 364 | return error; |
362 | } | 365 | } |
363 | 366 | ||
@@ -1193,8 +1196,8 @@ static void ar5523_create_rateset(struct ar5523 *ar, | |||
1193 | if (!sta) { | 1196 | if (!sta) { |
1194 | ar5523_info(ar, "STA not found. Cannot set rates\n"); | 1197 | ar5523_info(ar, "STA not found. Cannot set rates\n"); |
1195 | sta_rate_set = bss_conf->basic_rates; | 1198 | sta_rate_set = bss_conf->basic_rates; |
1196 | } | 1199 | } else |
1197 | sta_rate_set = sta->supp_rates[ar->hw->conf.channel->band]; | 1200 | sta_rate_set = sta->supp_rates[ar->hw->conf.channel->band]; |
1198 | 1201 | ||
1199 | ar5523_dbg(ar, "sta rate_set = %08x\n", sta_rate_set); | 1202 | ar5523_dbg(ar, "sta rate_set = %08x\n", sta_rate_set); |
1200 | 1203 | ||
@@ -1789,18 +1792,7 @@ static struct usb_driver ar5523_driver = { | |||
1789 | .disconnect = ar5523_disconnect, | 1792 | .disconnect = ar5523_disconnect, |
1790 | }; | 1793 | }; |
1791 | 1794 | ||
1792 | static int __init ar5523_init(void) | 1795 | module_usb_driver(ar5523_driver); |
1793 | { | ||
1794 | return usb_register(&ar5523_driver); | ||
1795 | } | ||
1796 | |||
1797 | static void __exit ar5523_exit(void) | ||
1798 | { | ||
1799 | usb_deregister(&ar5523_driver); | ||
1800 | } | ||
1801 | 1796 | ||
1802 | MODULE_LICENSE("Dual BSD/GPL"); | 1797 | MODULE_LICENSE("Dual BSD/GPL"); |
1803 | MODULE_FIRMWARE(AR5523_FIRMWARE_FILE); | 1798 | MODULE_FIRMWARE(AR5523_FIRMWARE_FILE); |
1804 | |||
1805 | module_init(ar5523_init); | ||
1806 | module_exit(ar5523_exit); | ||
diff --git a/drivers/net/wireless/ath/ar5523/ar5523_hw.h b/drivers/net/wireless/ath/ar5523/ar5523_hw.h index a0e8bf460316..0fe2c803f48f 100644 --- a/drivers/net/wireless/ath/ar5523/ar5523_hw.h +++ b/drivers/net/wireless/ath/ar5523/ar5523_hw.h | |||
@@ -161,7 +161,7 @@ struct ar5523_rx_desc { | |||
161 | 161 | ||
162 | struct ar5523_tx_desc { | 162 | struct ar5523_tx_desc { |
163 | __be32 msglen; | 163 | __be32 msglen; |
164 | __be32 msgid; /* msg id (supplied by host) */ | 164 | u32 msgid; /* msg id (supplied by host) */ |
165 | __be32 type; /* opcode: WDMSG_SEND or WDCMSG_FLUSH */ | 165 | __be32 type; /* opcode: WDMSG_SEND or WDCMSG_FLUSH */ |
166 | __be32 txqid; /* tx queue id and flags */ | 166 | __be32 txqid; /* tx queue id and flags */ |
167 | #define UATH_TXQID_MASK 0x0f | 167 | #define UATH_TXQID_MASK 0x0f |
diff --git a/drivers/net/wireless/ath/ath5k/ahb.c b/drivers/net/wireless/ath/ath5k/ahb.c index aec33cc207fd..8e8bcc7a4805 100644 --- a/drivers/net/wireless/ath/ath5k/ahb.c +++ b/drivers/net/wireless/ath/ath5k/ahb.c | |||
@@ -236,17 +236,4 @@ static struct platform_driver ath_ahb_driver = { | |||
236 | }, | 236 | }, |
237 | }; | 237 | }; |
238 | 238 | ||
239 | static int __init | 239 | module_platform_driver(ath_ahb_driver); |
240 | ath5k_ahb_init(void) | ||
241 | { | ||
242 | return platform_driver_register(&ath_ahb_driver); | ||
243 | } | ||
244 | |||
245 | static void __exit | ||
246 | ath5k_ahb_exit(void) | ||
247 | { | ||
248 | platform_driver_unregister(&ath_ahb_driver); | ||
249 | } | ||
250 | |||
251 | module_init(ath5k_ahb_init); | ||
252 | module_exit(ath5k_ahb_exit); | ||
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 9f31cfa56cc0..2fd5bab2e22a 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -511,8 +511,9 @@ ath5k_update_bssid_mask_and_opmode(struct ath5k_hw *ah, | |||
511 | ath5k_vif_iter(&iter_data, vif->addr, vif); | 511 | ath5k_vif_iter(&iter_data, vif->addr, vif); |
512 | 512 | ||
513 | /* Get list of all active MAC addresses */ | 513 | /* Get list of all active MAC addresses */ |
514 | ieee80211_iterate_active_interfaces_atomic(ah->hw, ath5k_vif_iter, | 514 | ieee80211_iterate_active_interfaces_atomic( |
515 | &iter_data); | 515 | ah->hw, IEEE80211_IFACE_ITER_RESUME_ALL, |
516 | ath5k_vif_iter, &iter_data); | ||
516 | memcpy(ah->bssidmask, iter_data.mask, ETH_ALEN); | 517 | memcpy(ah->bssidmask, iter_data.mask, ETH_ALEN); |
517 | 518 | ||
518 | ah->opmode = iter_data.opmode; | 519 | ah->opmode = iter_data.opmode; |
@@ -1348,7 +1349,7 @@ ath5k_receive_frame(struct ath5k_hw *ah, struct sk_buff *skb, | |||
1348 | * right now, so it's not too bad... | 1349 | * right now, so it's not too bad... |
1349 | */ | 1350 | */ |
1350 | rxs->mactime = ath5k_extend_tsf(ah, rs->rs_tstamp); | 1351 | rxs->mactime = ath5k_extend_tsf(ah, rs->rs_tstamp); |
1351 | rxs->flag |= RX_FLAG_MACTIME_MPDU; | 1352 | rxs->flag |= RX_FLAG_MACTIME_START; |
1352 | 1353 | ||
1353 | rxs->freq = ah->curchan->center_freq; | 1354 | rxs->freq = ah->curchan->center_freq; |
1354 | rxs->band = ah->curchan->band; | 1355 | rxs->band = ah->curchan->band; |
@@ -3045,8 +3046,9 @@ ath5k_any_vif_assoc(struct ath5k_hw *ah) | |||
3045 | iter_data.need_set_hw_addr = false; | 3046 | iter_data.need_set_hw_addr = false; |
3046 | iter_data.found_active = true; | 3047 | iter_data.found_active = true; |
3047 | 3048 | ||
3048 | ieee80211_iterate_active_interfaces_atomic(ah->hw, ath5k_vif_iter, | 3049 | ieee80211_iterate_active_interfaces_atomic( |
3049 | &iter_data); | 3050 | ah->hw, IEEE80211_IFACE_ITER_RESUME_ALL, |
3051 | ath5k_vif_iter, &iter_data); | ||
3050 | return iter_data.any_assoc; | 3052 | return iter_data.any_assoc; |
3051 | } | 3053 | } |
3052 | 3054 | ||
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index 7a28538e6e05..1ea8c8795c8e 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c | |||
@@ -452,8 +452,9 @@ ath5k_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, | |||
452 | iter_data.hw_macaddr = NULL; | 452 | iter_data.hw_macaddr = NULL; |
453 | iter_data.n_stas = 0; | 453 | iter_data.n_stas = 0; |
454 | iter_data.need_set_hw_addr = false; | 454 | iter_data.need_set_hw_addr = false; |
455 | ieee80211_iterate_active_interfaces_atomic(ah->hw, ath5k_vif_iter, | 455 | ieee80211_iterate_active_interfaces_atomic( |
456 | &iter_data); | 456 | ah->hw, IEEE80211_IFACE_ITER_RESUME_ALL, |
457 | ath5k_vif_iter, &iter_data); | ||
457 | 458 | ||
458 | /* Set up RX Filter */ | 459 | /* Set up RX Filter */ |
459 | if (iter_data.n_stas > 1) { | 460 | if (iter_data.n_stas > 1) { |
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 0c2dd4771c36..4084b1076286 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c | |||
@@ -789,9 +789,9 @@ ath5k_hw_nic_wakeup(struct ath5k_hw *ah, struct ieee80211_channel *channel) | |||
789 | * (I don't think it supports 44MHz) */ | 789 | * (I don't think it supports 44MHz) */ |
790 | /* On 2425 initvals TURBO_SHORT is not present */ | 790 | /* On 2425 initvals TURBO_SHORT is not present */ |
791 | if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) { | 791 | if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) { |
792 | turbo = AR5K_PHY_TURBO_MODE | | 792 | turbo = AR5K_PHY_TURBO_MODE; |
793 | (ah->ah_radio == AR5K_RF2425) ? 0 : | 793 | if (ah->ah_radio != AR5K_RF2425) |
794 | AR5K_PHY_TURBO_SHORT; | 794 | turbo |= AR5K_PHY_TURBO_SHORT; |
795 | } else if (ah->ah_bwmode != AR5K_BWMODE_DEFAULT) { | 795 | } else if (ah->ah_bwmode != AR5K_BWMODE_DEFAULT) { |
796 | if (ah->ah_radio == AR5K_RF5413) { | 796 | if (ah->ah_radio == AR5K_RF5413) { |
797 | mode |= (ah->ah_bwmode == AR5K_BWMODE_10MHZ) ? | 797 | mode |= (ah->ah_bwmode == AR5K_BWMODE_10MHZ) ? |
diff --git a/drivers/net/wireless/ath/ath6kl/Kconfig b/drivers/net/wireless/ath/ath6kl/Kconfig index d755a5e7ed20..26c4b7220859 100644 --- a/drivers/net/wireless/ath/ath6kl/Kconfig +++ b/drivers/net/wireless/ath/ath6kl/Kconfig | |||
@@ -30,3 +30,12 @@ config ATH6KL_DEBUG | |||
30 | depends on ATH6KL | 30 | depends on ATH6KL |
31 | ---help--- | 31 | ---help--- |
32 | Enables debug support | 32 | Enables debug support |
33 | |||
34 | config ATH6KL_REGDOMAIN | ||
35 | bool "Atheros ath6kl regdomain support" | ||
36 | depends on ATH6KL | ||
37 | depends on CFG80211_CERTIFICATION_ONUS | ||
38 | ---help--- | ||
39 | Enabling this makes it possible to change the regdomain in | ||
40 | the firmware. This can be only enabled if regulatory requirements | ||
41 | are taken into account. | ||
diff --git a/drivers/net/wireless/ath/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile index 8cae8886f17d..cab0ec0d5380 100644 --- a/drivers/net/wireless/ath/ath6kl/Makefile +++ b/drivers/net/wireless/ath/ath6kl/Makefile | |||
@@ -34,6 +34,7 @@ ath6kl_core-y += main.o | |||
34 | ath6kl_core-y += txrx.o | 34 | ath6kl_core-y += txrx.o |
35 | ath6kl_core-y += wmi.o | 35 | ath6kl_core-y += wmi.o |
36 | ath6kl_core-y += core.o | 36 | ath6kl_core-y += core.o |
37 | ath6kl_core-y += recovery.o | ||
37 | ath6kl_core-$(CONFIG_NL80211_TESTMODE) += testmode.o | 38 | ath6kl_core-$(CONFIG_NL80211_TESTMODE) += testmode.o |
38 | 39 | ||
39 | obj-$(CONFIG_ATH6KL_SDIO) += ath6kl_sdio.o | 40 | obj-$(CONFIG_ATH6KL_SDIO) += ath6kl_sdio.o |
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 277089963eb4..5516a8ccc3c6 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c | |||
@@ -147,15 +147,15 @@ static bool __ath6kl_cfg80211_sscan_stop(struct ath6kl_vif *vif) | |||
147 | { | 147 | { |
148 | struct ath6kl *ar = vif->ar; | 148 | struct ath6kl *ar = vif->ar; |
149 | 149 | ||
150 | if (ar->state != ATH6KL_STATE_SCHED_SCAN) | 150 | if (!test_and_clear_bit(SCHED_SCANNING, &vif->flags)) |
151 | return false; | 151 | return false; |
152 | 152 | ||
153 | del_timer_sync(&vif->sched_scan_timer); | 153 | del_timer_sync(&vif->sched_scan_timer); |
154 | 154 | ||
155 | ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, | 155 | if (ar->state == ATH6KL_STATE_RECOVERY) |
156 | ATH6KL_HOST_MODE_AWAKE); | 156 | return true; |
157 | 157 | ||
158 | ar->state = ATH6KL_STATE_ON; | 158 | ath6kl_wmi_enable_sched_scan_cmd(ar->wmi, vif->fw_vif_idx, false); |
159 | 159 | ||
160 | return true; | 160 | return true; |
161 | } | 161 | } |
@@ -369,17 +369,13 @@ static int ath6kl_nliftype_to_drv_iftype(enum nl80211_iftype type, u8 *nw_type) | |||
369 | { | 369 | { |
370 | switch (type) { | 370 | switch (type) { |
371 | case NL80211_IFTYPE_STATION: | 371 | case NL80211_IFTYPE_STATION: |
372 | case NL80211_IFTYPE_P2P_CLIENT: | ||
372 | *nw_type = INFRA_NETWORK; | 373 | *nw_type = INFRA_NETWORK; |
373 | break; | 374 | break; |
374 | case NL80211_IFTYPE_ADHOC: | 375 | case NL80211_IFTYPE_ADHOC: |
375 | *nw_type = ADHOC_NETWORK; | 376 | *nw_type = ADHOC_NETWORK; |
376 | break; | 377 | break; |
377 | case NL80211_IFTYPE_AP: | 378 | case NL80211_IFTYPE_AP: |
378 | *nw_type = AP_NETWORK; | ||
379 | break; | ||
380 | case NL80211_IFTYPE_P2P_CLIENT: | ||
381 | *nw_type = INFRA_NETWORK; | ||
382 | break; | ||
383 | case NL80211_IFTYPE_P2P_GO: | 379 | case NL80211_IFTYPE_P2P_GO: |
384 | *nw_type = AP_NETWORK; | 380 | *nw_type = AP_NETWORK; |
385 | break; | 381 | break; |
@@ -1031,30 +1027,15 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, | |||
1031 | 1027 | ||
1032 | vif->scan_req = request; | 1028 | vif->scan_req = request; |
1033 | 1029 | ||
1034 | if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX, | 1030 | ret = ath6kl_wmi_beginscan_cmd(ar->wmi, vif->fw_vif_idx, |
1035 | ar->fw_capabilities)) { | 1031 | WMI_LONG_SCAN, force_fg_scan, |
1036 | /* | 1032 | false, 0, |
1037 | * If capable of doing P2P mgmt operations using | 1033 | ATH6KL_FG_SCAN_INTERVAL, |
1038 | * station interface, send additional information like | 1034 | n_channels, channels, |
1039 | * supported rates to advertise and xmit rates for | 1035 | request->no_cck, |
1040 | * probe requests | 1036 | request->rates); |
1041 | */ | ||
1042 | ret = ath6kl_wmi_beginscan_cmd(ar->wmi, vif->fw_vif_idx, | ||
1043 | WMI_LONG_SCAN, force_fg_scan, | ||
1044 | false, 0, | ||
1045 | ATH6KL_FG_SCAN_INTERVAL, | ||
1046 | n_channels, channels, | ||
1047 | request->no_cck, | ||
1048 | request->rates); | ||
1049 | } else { | ||
1050 | ret = ath6kl_wmi_startscan_cmd(ar->wmi, vif->fw_vif_idx, | ||
1051 | WMI_LONG_SCAN, force_fg_scan, | ||
1052 | false, 0, | ||
1053 | ATH6KL_FG_SCAN_INTERVAL, | ||
1054 | n_channels, channels); | ||
1055 | } | ||
1056 | if (ret) { | 1037 | if (ret) { |
1057 | ath6kl_err("wmi_startscan_cmd failed\n"); | 1038 | ath6kl_err("failed to start scan: %d\n", ret); |
1058 | vif->scan_req = NULL; | 1039 | vif->scan_req = NULL; |
1059 | } | 1040 | } |
1060 | 1041 | ||
@@ -1093,15 +1074,18 @@ out: | |||
1093 | void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq, | 1074 | void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq, |
1094 | enum wmi_phy_mode mode) | 1075 | enum wmi_phy_mode mode) |
1095 | { | 1076 | { |
1096 | enum nl80211_channel_type type; | 1077 | struct cfg80211_chan_def chandef; |
1097 | 1078 | ||
1098 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, | 1079 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, |
1099 | "channel switch notify nw_type %d freq %d mode %d\n", | 1080 | "channel switch notify nw_type %d freq %d mode %d\n", |
1100 | vif->nw_type, freq, mode); | 1081 | vif->nw_type, freq, mode); |
1101 | 1082 | ||
1102 | type = (mode == WMI_11G_HT20) ? NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT; | 1083 | cfg80211_chandef_create(&chandef, |
1084 | ieee80211_get_channel(vif->ar->wiphy, freq), | ||
1085 | (mode == WMI_11G_HT20) ? | ||
1086 | NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT); | ||
1103 | 1087 | ||
1104 | cfg80211_ch_switch_notify(vif->ndev, freq, type); | 1088 | cfg80211_ch_switch_notify(vif->ndev, &chandef); |
1105 | } | 1089 | } |
1106 | 1090 | ||
1107 | static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, | 1091 | static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, |
@@ -1384,11 +1368,8 @@ static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) | |||
1384 | return 0; | 1368 | return 0; |
1385 | } | 1369 | } |
1386 | 1370 | ||
1387 | /* | ||
1388 | * The type nl80211_tx_power_setting replaces the following | ||
1389 | * data type from 2.6.36 onwards | ||
1390 | */ | ||
1391 | static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy, | 1371 | static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy, |
1372 | struct wireless_dev *wdev, | ||
1392 | enum nl80211_tx_power_setting type, | 1373 | enum nl80211_tx_power_setting type, |
1393 | int mbm) | 1374 | int mbm) |
1394 | { | 1375 | { |
@@ -1423,7 +1404,9 @@ static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy, | |||
1423 | return 0; | 1404 | return 0; |
1424 | } | 1405 | } |
1425 | 1406 | ||
1426 | static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm) | 1407 | static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy, |
1408 | struct wireless_dev *wdev, | ||
1409 | int *dbm) | ||
1427 | { | 1410 | { |
1428 | struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy); | 1411 | struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy); |
1429 | struct ath6kl_vif *vif; | 1412 | struct ath6kl_vif *vif; |
@@ -1614,8 +1597,8 @@ static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy, | |||
1614 | vif->ssid_len = ibss_param->ssid_len; | 1597 | vif->ssid_len = ibss_param->ssid_len; |
1615 | memcpy(vif->ssid, ibss_param->ssid, vif->ssid_len); | 1598 | memcpy(vif->ssid, ibss_param->ssid, vif->ssid_len); |
1616 | 1599 | ||
1617 | if (ibss_param->channel) | 1600 | if (ibss_param->chandef.chan) |
1618 | vif->ch_hint = ibss_param->channel->center_freq; | 1601 | vif->ch_hint = ibss_param->chandef.chan->center_freq; |
1619 | 1602 | ||
1620 | if (ibss_param->channel_fixed) { | 1603 | if (ibss_param->channel_fixed) { |
1621 | /* | 1604 | /* |
@@ -1889,7 +1872,7 @@ static int ath6kl_wow_usr(struct ath6kl *ar, struct ath6kl_vif *vif, | |||
1889 | struct cfg80211_wowlan *wow, u32 *filter) | 1872 | struct cfg80211_wowlan *wow, u32 *filter) |
1890 | { | 1873 | { |
1891 | int ret, pos; | 1874 | int ret, pos; |
1892 | u8 mask[WOW_MASK_SIZE]; | 1875 | u8 mask[WOW_PATTERN_SIZE]; |
1893 | u16 i; | 1876 | u16 i; |
1894 | 1877 | ||
1895 | /* Configure the patterns that we received from the user. */ | 1878 | /* Configure the patterns that we received from the user. */ |
@@ -2107,33 +2090,16 @@ static int ath6kl_cfg80211_host_sleep(struct ath6kl *ar, struct ath6kl_vif *vif) | |||
2107 | return ret; | 2090 | return ret; |
2108 | } | 2091 | } |
2109 | 2092 | ||
2110 | static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) | 2093 | static int ath6kl_wow_suspend_vif(struct ath6kl_vif *vif, |
2094 | struct cfg80211_wowlan *wow, u32 *filter) | ||
2111 | { | 2095 | { |
2096 | struct ath6kl *ar = vif->ar; | ||
2112 | struct in_device *in_dev; | 2097 | struct in_device *in_dev; |
2113 | struct in_ifaddr *ifa; | 2098 | struct in_ifaddr *ifa; |
2114 | struct ath6kl_vif *vif; | ||
2115 | int ret; | 2099 | int ret; |
2116 | u32 filter = 0; | ||
2117 | u16 i, bmiss_time; | 2100 | u16 i, bmiss_time; |
2118 | u8 index = 0; | ||
2119 | __be32 ips[MAX_IP_ADDRS]; | 2101 | __be32 ips[MAX_IP_ADDRS]; |
2120 | 2102 | u8 index = 0; | |
2121 | /* The FW currently can't support multi-vif WoW properly. */ | ||
2122 | if (ar->num_vif > 1) | ||
2123 | return -EIO; | ||
2124 | |||
2125 | vif = ath6kl_vif_first(ar); | ||
2126 | if (!vif) | ||
2127 | return -EIO; | ||
2128 | |||
2129 | if (!ath6kl_cfg80211_ready(vif)) | ||
2130 | return -EIO; | ||
2131 | |||
2132 | if (!test_bit(CONNECTED, &vif->flags)) | ||
2133 | return -ENOTCONN; | ||
2134 | |||
2135 | if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST)) | ||
2136 | return -EINVAL; | ||
2137 | 2103 | ||
2138 | if (!test_bit(NETDEV_MCAST_ALL_ON, &vif->flags) && | 2104 | if (!test_bit(NETDEV_MCAST_ALL_ON, &vif->flags) && |
2139 | test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER, | 2105 | test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER, |
@@ -2155,7 +2121,7 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) | |||
2155 | * the user. | 2121 | * the user. |
2156 | */ | 2122 | */ |
2157 | if (wow) | 2123 | if (wow) |
2158 | ret = ath6kl_wow_usr(ar, vif, wow, &filter); | 2124 | ret = ath6kl_wow_usr(ar, vif, wow, filter); |
2159 | else if (vif->nw_type == AP_NETWORK) | 2125 | else if (vif->nw_type == AP_NETWORK) |
2160 | ret = ath6kl_wow_ap(ar, vif); | 2126 | ret = ath6kl_wow_ap(ar, vif); |
2161 | else | 2127 | else |
@@ -2190,12 +2156,10 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) | |||
2190 | return ret; | 2156 | return ret; |
2191 | } | 2157 | } |
2192 | 2158 | ||
2193 | ar->state = ATH6KL_STATE_SUSPENDING; | ||
2194 | |||
2195 | /* Setup own IP addr for ARP agent. */ | 2159 | /* Setup own IP addr for ARP agent. */ |
2196 | in_dev = __in_dev_get_rtnl(vif->ndev); | 2160 | in_dev = __in_dev_get_rtnl(vif->ndev); |
2197 | if (!in_dev) | 2161 | if (!in_dev) |
2198 | goto skip_arp; | 2162 | return 0; |
2199 | 2163 | ||
2200 | ifa = in_dev->ifa_list; | 2164 | ifa = in_dev->ifa_list; |
2201 | memset(&ips, 0, sizeof(ips)); | 2165 | memset(&ips, 0, sizeof(ips)); |
@@ -2218,41 +2182,61 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) | |||
2218 | return ret; | 2182 | return ret; |
2219 | } | 2183 | } |
2220 | 2184 | ||
2221 | skip_arp: | 2185 | return ret; |
2222 | ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx, | 2186 | } |
2187 | |||
2188 | static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) | ||
2189 | { | ||
2190 | struct ath6kl_vif *first_vif, *vif; | ||
2191 | int ret = 0; | ||
2192 | u32 filter = 0; | ||
2193 | bool connected = false; | ||
2194 | |||
2195 | /* enter / leave wow suspend on first vif always */ | ||
2196 | first_vif = ath6kl_vif_first(ar); | ||
2197 | if (WARN_ON(unlikely(!first_vif)) || | ||
2198 | !ath6kl_cfg80211_ready(first_vif)) | ||
2199 | return -EIO; | ||
2200 | |||
2201 | if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST)) | ||
2202 | return -EINVAL; | ||
2203 | |||
2204 | /* install filters for each connected vif */ | ||
2205 | spin_lock_bh(&ar->list_lock); | ||
2206 | list_for_each_entry(vif, &ar->vif_list, list) { | ||
2207 | if (!test_bit(CONNECTED, &vif->flags) || | ||
2208 | !ath6kl_cfg80211_ready(vif)) | ||
2209 | continue; | ||
2210 | connected = true; | ||
2211 | |||
2212 | ret = ath6kl_wow_suspend_vif(vif, wow, &filter); | ||
2213 | if (ret) | ||
2214 | break; | ||
2215 | } | ||
2216 | spin_unlock_bh(&ar->list_lock); | ||
2217 | |||
2218 | if (!connected) | ||
2219 | return -ENOTCONN; | ||
2220 | else if (ret) | ||
2221 | return ret; | ||
2222 | |||
2223 | ar->state = ATH6KL_STATE_SUSPENDING; | ||
2224 | |||
2225 | ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, first_vif->fw_vif_idx, | ||
2223 | ATH6KL_WOW_MODE_ENABLE, | 2226 | ATH6KL_WOW_MODE_ENABLE, |
2224 | filter, | 2227 | filter, |
2225 | WOW_HOST_REQ_DELAY); | 2228 | WOW_HOST_REQ_DELAY); |
2226 | if (ret) | 2229 | if (ret) |
2227 | return ret; | 2230 | return ret; |
2228 | 2231 | ||
2229 | ret = ath6kl_cfg80211_host_sleep(ar, vif); | 2232 | return ath6kl_cfg80211_host_sleep(ar, first_vif); |
2230 | if (ret) | ||
2231 | return ret; | ||
2232 | |||
2233 | return 0; | ||
2234 | } | 2233 | } |
2235 | 2234 | ||
2236 | static int ath6kl_wow_resume(struct ath6kl *ar) | 2235 | static int ath6kl_wow_resume_vif(struct ath6kl_vif *vif) |
2237 | { | 2236 | { |
2238 | struct ath6kl_vif *vif; | 2237 | struct ath6kl *ar = vif->ar; |
2239 | int ret; | 2238 | int ret; |
2240 | 2239 | ||
2241 | vif = ath6kl_vif_first(ar); | ||
2242 | if (!vif) | ||
2243 | return -EIO; | ||
2244 | |||
2245 | ar->state = ATH6KL_STATE_RESUMING; | ||
2246 | |||
2247 | ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, | ||
2248 | ATH6KL_HOST_MODE_AWAKE); | ||
2249 | if (ret) { | ||
2250 | ath6kl_warn("Failed to configure host sleep mode for wow resume: %d\n", | ||
2251 | ret); | ||
2252 | ar->state = ATH6KL_STATE_WOW; | ||
2253 | return ret; | ||
2254 | } | ||
2255 | |||
2256 | if (vif->nw_type != AP_NETWORK) { | 2240 | if (vif->nw_type != AP_NETWORK) { |
2257 | ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, | 2241 | ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, |
2258 | 0, 0, 0, 0, 0, 0, 3, 0, 0, 0); | 2242 | 0, 0, 0, 0, 0, 0, 3, 0, 0, 0); |
@@ -2270,13 +2254,11 @@ static int ath6kl_wow_resume(struct ath6kl *ar) | |||
2270 | return ret; | 2254 | return ret; |
2271 | } | 2255 | } |
2272 | 2256 | ||
2273 | ar->state = ATH6KL_STATE_ON; | ||
2274 | |||
2275 | if (!test_bit(NETDEV_MCAST_ALL_OFF, &vif->flags) && | 2257 | if (!test_bit(NETDEV_MCAST_ALL_OFF, &vif->flags) && |
2276 | test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER, | 2258 | test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER, |
2277 | ar->fw_capabilities)) { | 2259 | ar->fw_capabilities)) { |
2278 | ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, | 2260 | ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, |
2279 | vif->fw_vif_idx, true); | 2261 | vif->fw_vif_idx, true); |
2280 | if (ret) | 2262 | if (ret) |
2281 | return ret; | 2263 | return ret; |
2282 | } | 2264 | } |
@@ -2286,6 +2268,48 @@ static int ath6kl_wow_resume(struct ath6kl *ar) | |||
2286 | return 0; | 2268 | return 0; |
2287 | } | 2269 | } |
2288 | 2270 | ||
2271 | static int ath6kl_wow_resume(struct ath6kl *ar) | ||
2272 | { | ||
2273 | struct ath6kl_vif *vif; | ||
2274 | int ret; | ||
2275 | |||
2276 | vif = ath6kl_vif_first(ar); | ||
2277 | if (WARN_ON(unlikely(!vif)) || | ||
2278 | !ath6kl_cfg80211_ready(vif)) | ||
2279 | return -EIO; | ||
2280 | |||
2281 | ar->state = ATH6KL_STATE_RESUMING; | ||
2282 | |||
2283 | ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, | ||
2284 | ATH6KL_HOST_MODE_AWAKE); | ||
2285 | if (ret) { | ||
2286 | ath6kl_warn("Failed to configure host sleep mode for wow resume: %d\n", | ||
2287 | ret); | ||
2288 | goto cleanup; | ||
2289 | } | ||
2290 | |||
2291 | spin_lock_bh(&ar->list_lock); | ||
2292 | list_for_each_entry(vif, &ar->vif_list, list) { | ||
2293 | if (!test_bit(CONNECTED, &vif->flags) || | ||
2294 | !ath6kl_cfg80211_ready(vif)) | ||
2295 | continue; | ||
2296 | ret = ath6kl_wow_resume_vif(vif); | ||
2297 | if (ret) | ||
2298 | break; | ||
2299 | } | ||
2300 | spin_unlock_bh(&ar->list_lock); | ||
2301 | |||
2302 | if (ret) | ||
2303 | goto cleanup; | ||
2304 | |||
2305 | ar->state = ATH6KL_STATE_ON; | ||
2306 | return 0; | ||
2307 | |||
2308 | cleanup: | ||
2309 | ar->state = ATH6KL_STATE_WOW; | ||
2310 | return ret; | ||
2311 | } | ||
2312 | |||
2289 | static int ath6kl_cfg80211_deepsleep_suspend(struct ath6kl *ar) | 2313 | static int ath6kl_cfg80211_deepsleep_suspend(struct ath6kl *ar) |
2290 | { | 2314 | { |
2291 | struct ath6kl_vif *vif; | 2315 | struct ath6kl_vif *vif; |
@@ -2422,13 +2446,6 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar, | |||
2422 | 2446 | ||
2423 | break; | 2447 | break; |
2424 | 2448 | ||
2425 | case ATH6KL_CFG_SUSPEND_SCHED_SCAN: | ||
2426 | /* | ||
2427 | * Nothing needed for schedule scan, firmware is already in | ||
2428 | * wow mode and sleeping most of the time. | ||
2429 | */ | ||
2430 | break; | ||
2431 | |||
2432 | default: | 2449 | default: |
2433 | break; | 2450 | break; |
2434 | } | 2451 | } |
@@ -2476,9 +2493,6 @@ int ath6kl_cfg80211_resume(struct ath6kl *ar) | |||
2476 | } | 2493 | } |
2477 | break; | 2494 | break; |
2478 | 2495 | ||
2479 | case ATH6KL_STATE_SCHED_SCAN: | ||
2480 | break; | ||
2481 | |||
2482 | default: | 2496 | default: |
2483 | break; | 2497 | break; |
2484 | } | 2498 | } |
@@ -2495,14 +2509,23 @@ static int __ath6kl_cfg80211_suspend(struct wiphy *wiphy, | |||
2495 | { | 2509 | { |
2496 | struct ath6kl *ar = wiphy_priv(wiphy); | 2510 | struct ath6kl *ar = wiphy_priv(wiphy); |
2497 | 2511 | ||
2512 | ath6kl_recovery_suspend(ar); | ||
2513 | |||
2498 | return ath6kl_hif_suspend(ar, wow); | 2514 | return ath6kl_hif_suspend(ar, wow); |
2499 | } | 2515 | } |
2500 | 2516 | ||
2501 | static int __ath6kl_cfg80211_resume(struct wiphy *wiphy) | 2517 | static int __ath6kl_cfg80211_resume(struct wiphy *wiphy) |
2502 | { | 2518 | { |
2503 | struct ath6kl *ar = wiphy_priv(wiphy); | 2519 | struct ath6kl *ar = wiphy_priv(wiphy); |
2520 | int err; | ||
2521 | |||
2522 | err = ath6kl_hif_resume(ar); | ||
2523 | if (err) | ||
2524 | return err; | ||
2504 | 2525 | ||
2505 | return ath6kl_hif_resume(ar); | 2526 | ath6kl_recovery_resume(ar); |
2527 | |||
2528 | return 0; | ||
2506 | } | 2529 | } |
2507 | 2530 | ||
2508 | /* | 2531 | /* |
@@ -2739,6 +2762,7 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev, | |||
2739 | int res; | 2762 | int res; |
2740 | int i, ret; | 2763 | int i, ret; |
2741 | u16 rsn_capab = 0; | 2764 | u16 rsn_capab = 0; |
2765 | int inactivity_timeout = 0; | ||
2742 | 2766 | ||
2743 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s:\n", __func__); | 2767 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s:\n", __func__); |
2744 | 2768 | ||
@@ -2857,7 +2881,7 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev, | |||
2857 | p.ssid_len = vif->ssid_len; | 2881 | p.ssid_len = vif->ssid_len; |
2858 | memcpy(p.ssid, vif->ssid, vif->ssid_len); | 2882 | memcpy(p.ssid, vif->ssid, vif->ssid_len); |
2859 | p.dot11_auth_mode = vif->dot11_auth_mode; | 2883 | p.dot11_auth_mode = vif->dot11_auth_mode; |
2860 | p.ch = cpu_to_le16(info->channel->center_freq); | 2884 | p.ch = cpu_to_le16(info->chandef.chan->center_freq); |
2861 | 2885 | ||
2862 | /* Enable uAPSD support by default */ | 2886 | /* Enable uAPSD support by default */ |
2863 | res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true); | 2887 | res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true); |
@@ -2875,14 +2899,22 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev, | |||
2875 | } | 2899 | } |
2876 | 2900 | ||
2877 | if (info->inactivity_timeout) { | 2901 | if (info->inactivity_timeout) { |
2902 | |||
2903 | inactivity_timeout = info->inactivity_timeout; | ||
2904 | |||
2905 | if (ar->hw.flags & ATH6KL_HW_AP_INACTIVITY_MINS) | ||
2906 | inactivity_timeout = DIV_ROUND_UP(inactivity_timeout, | ||
2907 | 60); | ||
2908 | |||
2878 | res = ath6kl_wmi_set_inact_period(ar->wmi, vif->fw_vif_idx, | 2909 | res = ath6kl_wmi_set_inact_period(ar->wmi, vif->fw_vif_idx, |
2879 | info->inactivity_timeout); | 2910 | inactivity_timeout); |
2880 | if (res < 0) | 2911 | if (res < 0) |
2881 | return res; | 2912 | return res; |
2882 | } | 2913 | } |
2883 | 2914 | ||
2884 | if (ath6kl_set_htcap(vif, info->channel->band, | 2915 | if (ath6kl_set_htcap(vif, info->chandef.chan->band, |
2885 | info->channel_type != NL80211_CHAN_NO_HT)) | 2916 | cfg80211_get_chandef_type(&info->chandef) |
2917 | != NL80211_CHAN_NO_HT)) | ||
2886 | return -EIO; | 2918 | return -EIO; |
2887 | 2919 | ||
2888 | /* | 2920 | /* |
@@ -2898,6 +2930,7 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev, | |||
2898 | WLAN_EID_RSN, WMI_RSN_IE_CAPB, | 2930 | WLAN_EID_RSN, WMI_RSN_IE_CAPB, |
2899 | (const u8 *) &rsn_capab, | 2931 | (const u8 *) &rsn_capab, |
2900 | sizeof(rsn_capab)); | 2932 | sizeof(rsn_capab)); |
2933 | vif->rsn_capab = rsn_capab; | ||
2901 | if (res < 0) | 2934 | if (res < 0) |
2902 | return res; | 2935 | return res; |
2903 | } | 2936 | } |
@@ -2977,7 +3010,6 @@ static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev, | |||
2977 | static int ath6kl_remain_on_channel(struct wiphy *wiphy, | 3010 | static int ath6kl_remain_on_channel(struct wiphy *wiphy, |
2978 | struct wireless_dev *wdev, | 3011 | struct wireless_dev *wdev, |
2979 | struct ieee80211_channel *chan, | 3012 | struct ieee80211_channel *chan, |
2980 | enum nl80211_channel_type channel_type, | ||
2981 | unsigned int duration, | 3013 | unsigned int duration, |
2982 | u64 *cookie) | 3014 | u64 *cookie) |
2983 | { | 3015 | { |
@@ -3136,10 +3168,8 @@ static bool ath6kl_is_p2p_go_ssid(const u8 *buf, size_t len) | |||
3136 | 3168 | ||
3137 | static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, | 3169 | static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, |
3138 | struct ieee80211_channel *chan, bool offchan, | 3170 | struct ieee80211_channel *chan, bool offchan, |
3139 | enum nl80211_channel_type channel_type, | 3171 | unsigned int wait, const u8 *buf, size_t len, |
3140 | bool channel_type_valid, unsigned int wait, | 3172 | bool no_cck, bool dont_wait_for_ack, u64 *cookie) |
3141 | const u8 *buf, size_t len, bool no_cck, | ||
3142 | bool dont_wait_for_ack, u64 *cookie) | ||
3143 | { | 3173 | { |
3144 | struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev); | 3174 | struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev); |
3145 | struct ath6kl *ar = ath6kl_priv(vif->ndev); | 3175 | struct ath6kl *ar = ath6kl_priv(vif->ndev); |
@@ -3211,7 +3241,7 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy, | |||
3211 | struct ath6kl *ar = ath6kl_priv(dev); | 3241 | struct ath6kl *ar = ath6kl_priv(dev); |
3212 | struct ath6kl_vif *vif = netdev_priv(dev); | 3242 | struct ath6kl_vif *vif = netdev_priv(dev); |
3213 | u16 interval; | 3243 | u16 interval; |
3214 | int ret; | 3244 | int ret, rssi_thold; |
3215 | 3245 | ||
3216 | if (ar->state != ATH6KL_STATE_ON) | 3246 | if (ar->state != ATH6KL_STATE_ON) |
3217 | return -EIO; | 3247 | return -EIO; |
@@ -3219,10 +3249,6 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy, | |||
3219 | if (vif->sme_state != SME_DISCONNECTED) | 3249 | if (vif->sme_state != SME_DISCONNECTED) |
3220 | return -EBUSY; | 3250 | return -EBUSY; |
3221 | 3251 | ||
3222 | /* The FW currently can't support multi-vif WoW properly. */ | ||
3223 | if (ar->num_vif > 1) | ||
3224 | return -EIO; | ||
3225 | |||
3226 | ath6kl_cfg80211_scan_complete_event(vif, true); | 3252 | ath6kl_cfg80211_scan_complete_event(vif, true); |
3227 | 3253 | ||
3228 | ret = ath6kl_set_probed_ssids(ar, vif, request->ssids, | 3254 | ret = ath6kl_set_probed_ssids(ar, vif, request->ssids, |
@@ -3244,6 +3270,23 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy, | |||
3244 | return ret; | 3270 | return ret; |
3245 | } | 3271 | } |
3246 | 3272 | ||
3273 | if (test_bit(ATH6KL_FW_CAPABILITY_RSSI_SCAN_THOLD, | ||
3274 | ar->fw_capabilities)) { | ||
3275 | if (request->rssi_thold <= NL80211_SCAN_RSSI_THOLD_OFF) | ||
3276 | rssi_thold = 0; | ||
3277 | else if (request->rssi_thold < -127) | ||
3278 | rssi_thold = -127; | ||
3279 | else | ||
3280 | rssi_thold = request->rssi_thold; | ||
3281 | |||
3282 | ret = ath6kl_wmi_set_rssi_filter_cmd(ar->wmi, vif->fw_vif_idx, | ||
3283 | rssi_thold); | ||
3284 | if (ret) { | ||
3285 | ath6kl_err("failed to set RSSI threshold for scan\n"); | ||
3286 | return ret; | ||
3287 | } | ||
3288 | } | ||
3289 | |||
3247 | /* fw uses seconds, also make sure that it's >0 */ | 3290 | /* fw uses seconds, also make sure that it's >0 */ |
3248 | interval = max_t(u16, 1, request->interval / 1000); | 3291 | interval = max_t(u16, 1, request->interval / 1000); |
3249 | 3292 | ||
@@ -3251,15 +3294,6 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy, | |||
3251 | interval, interval, | 3294 | interval, interval, |
3252 | vif->bg_scan_period, 0, 0, 0, 3, 0, 0, 0); | 3295 | vif->bg_scan_period, 0, 0, 0, 3, 0, 0, 0); |
3253 | 3296 | ||
3254 | ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx, | ||
3255 | ATH6KL_WOW_MODE_ENABLE, | ||
3256 | WOW_FILTER_SSID, | ||
3257 | WOW_HOST_REQ_DELAY); | ||
3258 | if (ret) { | ||
3259 | ath6kl_warn("Failed to enable wow with ssid filter: %d\n", ret); | ||
3260 | return ret; | ||
3261 | } | ||
3262 | |||
3263 | /* this also clears IE in fw if it's not set */ | 3297 | /* this also clears IE in fw if it's not set */ |
3264 | ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, | 3298 | ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, |
3265 | WMI_FRAME_PROBE_REQ, | 3299 | WMI_FRAME_PROBE_REQ, |
@@ -3270,17 +3304,13 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy, | |||
3270 | return ret; | 3304 | return ret; |
3271 | } | 3305 | } |
3272 | 3306 | ||
3273 | ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, | 3307 | ret = ath6kl_wmi_enable_sched_scan_cmd(ar->wmi, vif->fw_vif_idx, true); |
3274 | ATH6KL_HOST_MODE_ASLEEP); | 3308 | if (ret) |
3275 | if (ret) { | ||
3276 | ath6kl_warn("Failed to enable host sleep mode for sched scan: %d\n", | ||
3277 | ret); | ||
3278 | return ret; | 3309 | return ret; |
3279 | } | ||
3280 | 3310 | ||
3281 | ar->state = ATH6KL_STATE_SCHED_SCAN; | 3311 | set_bit(SCHED_SCANNING, &vif->flags); |
3282 | 3312 | ||
3283 | return ret; | 3313 | return 0; |
3284 | } | 3314 | } |
3285 | 3315 | ||
3286 | static int ath6kl_cfg80211_sscan_stop(struct wiphy *wiphy, | 3316 | static int ath6kl_cfg80211_sscan_stop(struct wiphy *wiphy, |
@@ -3309,6 +3339,27 @@ static int ath6kl_cfg80211_set_bitrate(struct wiphy *wiphy, | |||
3309 | mask); | 3339 | mask); |
3310 | } | 3340 | } |
3311 | 3341 | ||
3342 | static int ath6kl_cfg80211_set_txe_config(struct wiphy *wiphy, | ||
3343 | struct net_device *dev, | ||
3344 | u32 rate, u32 pkts, u32 intvl) | ||
3345 | { | ||
3346 | struct ath6kl *ar = ath6kl_priv(dev); | ||
3347 | struct ath6kl_vif *vif = netdev_priv(dev); | ||
3348 | |||
3349 | if (vif->nw_type != INFRA_NETWORK || | ||
3350 | !test_bit(ATH6KL_FW_CAPABILITY_TX_ERR_NOTIFY, ar->fw_capabilities)) | ||
3351 | return -EOPNOTSUPP; | ||
3352 | |||
3353 | if (vif->sme_state != SME_CONNECTED) | ||
3354 | return -ENOTCONN; | ||
3355 | |||
3356 | /* save this since the firmware won't report the interval */ | ||
3357 | vif->txe_intvl = intvl; | ||
3358 | |||
3359 | return ath6kl_wmi_set_txe_notify(ar->wmi, vif->fw_vif_idx, | ||
3360 | rate, pkts, intvl); | ||
3361 | } | ||
3362 | |||
3312 | static const struct ieee80211_txrx_stypes | 3363 | static const struct ieee80211_txrx_stypes |
3313 | ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = { | 3364 | ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = { |
3314 | [NL80211_IFTYPE_STATION] = { | 3365 | [NL80211_IFTYPE_STATION] = { |
@@ -3375,6 +3426,7 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = { | |||
3375 | .sched_scan_start = ath6kl_cfg80211_sscan_start, | 3426 | .sched_scan_start = ath6kl_cfg80211_sscan_start, |
3376 | .sched_scan_stop = ath6kl_cfg80211_sscan_stop, | 3427 | .sched_scan_stop = ath6kl_cfg80211_sscan_stop, |
3377 | .set_bitrate_mask = ath6kl_cfg80211_set_bitrate, | 3428 | .set_bitrate_mask = ath6kl_cfg80211_set_bitrate, |
3429 | .set_cqm_txe_config = ath6kl_cfg80211_set_txe_config, | ||
3378 | }; | 3430 | }; |
3379 | 3431 | ||
3380 | void ath6kl_cfg80211_stop(struct ath6kl_vif *vif) | 3432 | void ath6kl_cfg80211_stop(struct ath6kl_vif *vif) |
@@ -3395,16 +3447,22 @@ void ath6kl_cfg80211_stop(struct ath6kl_vif *vif) | |||
3395 | break; | 3447 | break; |
3396 | } | 3448 | } |
3397 | 3449 | ||
3398 | if (test_bit(CONNECTED, &vif->flags) || | 3450 | if (vif->ar->state != ATH6KL_STATE_RECOVERY && |
3399 | test_bit(CONNECT_PEND, &vif->flags)) | 3451 | (test_bit(CONNECTED, &vif->flags) || |
3452 | test_bit(CONNECT_PEND, &vif->flags))) | ||
3400 | ath6kl_wmi_disconnect_cmd(vif->ar->wmi, vif->fw_vif_idx); | 3453 | ath6kl_wmi_disconnect_cmd(vif->ar->wmi, vif->fw_vif_idx); |
3401 | 3454 | ||
3402 | vif->sme_state = SME_DISCONNECTED; | 3455 | vif->sme_state = SME_DISCONNECTED; |
3403 | clear_bit(CONNECTED, &vif->flags); | 3456 | clear_bit(CONNECTED, &vif->flags); |
3404 | clear_bit(CONNECT_PEND, &vif->flags); | 3457 | clear_bit(CONNECT_PEND, &vif->flags); |
3405 | 3458 | ||
3459 | /* Stop netdev queues, needed during recovery */ | ||
3460 | netif_stop_queue(vif->ndev); | ||
3461 | netif_carrier_off(vif->ndev); | ||
3462 | |||
3406 | /* disable scanning */ | 3463 | /* disable scanning */ |
3407 | if (ath6kl_wmi_scanparams_cmd(vif->ar->wmi, vif->fw_vif_idx, 0xFFFF, | 3464 | if (vif->ar->state != ATH6KL_STATE_RECOVERY && |
3465 | ath6kl_wmi_scanparams_cmd(vif->ar->wmi, vif->fw_vif_idx, 0xFFFF, | ||
3408 | 0, 0, 0, 0, 0, 0, 0, 0, 0) != 0) | 3466 | 0, 0, 0, 0, 0, 0, 0, 0, 0) != 0) |
3409 | ath6kl_warn("failed to disable scan during stop\n"); | 3467 | ath6kl_warn("failed to disable scan during stop\n"); |
3410 | 3468 | ||
@@ -3416,7 +3474,7 @@ void ath6kl_cfg80211_stop_all(struct ath6kl *ar) | |||
3416 | struct ath6kl_vif *vif; | 3474 | struct ath6kl_vif *vif; |
3417 | 3475 | ||
3418 | vif = ath6kl_vif_first(ar); | 3476 | vif = ath6kl_vif_first(ar); |
3419 | if (!vif) { | 3477 | if (!vif && ar->state != ATH6KL_STATE_RECOVERY) { |
3420 | /* save the current power mode before enabling power save */ | 3478 | /* save the current power mode before enabling power save */ |
3421 | ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode; | 3479 | ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode; |
3422 | 3480 | ||
@@ -3434,6 +3492,56 @@ void ath6kl_cfg80211_stop_all(struct ath6kl *ar) | |||
3434 | ath6kl_cfg80211_stop(vif); | 3492 | ath6kl_cfg80211_stop(vif); |
3435 | } | 3493 | } |
3436 | 3494 | ||
3495 | static int ath6kl_cfg80211_reg_notify(struct wiphy *wiphy, | ||
3496 | struct regulatory_request *request) | ||
3497 | { | ||
3498 | struct ath6kl *ar = wiphy_priv(wiphy); | ||
3499 | u32 rates[IEEE80211_NUM_BANDS]; | ||
3500 | int ret, i; | ||
3501 | |||
3502 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, | ||
3503 | "cfg reg_notify %c%c%s%s initiator %d hint_type %d\n", | ||
3504 | request->alpha2[0], request->alpha2[1], | ||
3505 | request->intersect ? " intersect" : "", | ||
3506 | request->processed ? " processed" : "", | ||
3507 | request->initiator, request->user_reg_hint_type); | ||
3508 | |||
3509 | /* | ||
3510 | * As firmware is not able intersect regdoms, we can only listen to | ||
3511 | * cellular hints. | ||
3512 | */ | ||
3513 | if (request->user_reg_hint_type != NL80211_USER_REG_HINT_CELL_BASE) | ||
3514 | return -EOPNOTSUPP; | ||
3515 | |||
3516 | ret = ath6kl_wmi_set_regdomain_cmd(ar->wmi, request->alpha2); | ||
3517 | if (ret) { | ||
3518 | ath6kl_err("failed to set regdomain: %d\n", ret); | ||
3519 | return ret; | ||
3520 | } | ||
3521 | |||
3522 | /* | ||
3523 | * Firmware will apply the regdomain change only after a scan is | ||
3524 | * issued and it will send a WMI_REGDOMAIN_EVENTID when it has been | ||
3525 | * changed. | ||
3526 | */ | ||
3527 | |||
3528 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) | ||
3529 | if (wiphy->bands[i]) | ||
3530 | rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1; | ||
3531 | |||
3532 | |||
3533 | ret = ath6kl_wmi_beginscan_cmd(ar->wmi, 0, WMI_LONG_SCAN, false, | ||
3534 | false, 0, ATH6KL_FG_SCAN_INTERVAL, | ||
3535 | 0, NULL, false, rates); | ||
3536 | if (ret) { | ||
3537 | ath6kl_err("failed to start scan for a regdomain change: %d\n", | ||
3538 | ret); | ||
3539 | return ret; | ||
3540 | } | ||
3541 | |||
3542 | return 0; | ||
3543 | } | ||
3544 | |||
3437 | static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif) | 3545 | static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif) |
3438 | { | 3546 | { |
3439 | vif->aggr_cntxt = aggr_init(vif); | 3547 | vif->aggr_cntxt = aggr_init(vif); |
@@ -3506,9 +3614,13 @@ struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name, | |||
3506 | vif->htcap[IEEE80211_BAND_5GHZ].ht_enable = true; | 3614 | vif->htcap[IEEE80211_BAND_5GHZ].ht_enable = true; |
3507 | 3615 | ||
3508 | memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN); | 3616 | memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN); |
3509 | if (fw_vif_idx != 0) | 3617 | if (fw_vif_idx != 0) { |
3510 | ndev->dev_addr[0] = (ndev->dev_addr[0] ^ (1 << fw_vif_idx)) | | 3618 | ndev->dev_addr[0] = (ndev->dev_addr[0] ^ (1 << fw_vif_idx)) | |
3511 | 0x2; | 3619 | 0x2; |
3620 | if (test_bit(ATH6KL_FW_CAPABILITY_CUSTOM_MAC_ADDR, | ||
3621 | ar->fw_capabilities)) | ||
3622 | ndev->dev_addr[4] ^= 0x80; | ||
3623 | } | ||
3512 | 3624 | ||
3513 | init_netdev(ndev); | 3625 | init_netdev(ndev); |
3514 | 3626 | ||
@@ -3562,6 +3674,12 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) | |||
3562 | BIT(NL80211_IFTYPE_P2P_CLIENT); | 3674 | BIT(NL80211_IFTYPE_P2P_CLIENT); |
3563 | } | 3675 | } |
3564 | 3676 | ||
3677 | if (config_enabled(CONFIG_ATH6KL_REGDOMAIN) && | ||
3678 | test_bit(ATH6KL_FW_CAPABILITY_REGDOMAIN, ar->fw_capabilities)) { | ||
3679 | wiphy->reg_notifier = ath6kl_cfg80211_reg_notify; | ||
3680 | ar->wiphy->features |= NL80211_FEATURE_CELL_BASE_REG_HINTS; | ||
3681 | } | ||
3682 | |||
3565 | /* max num of ssids that can be probed during scanning */ | 3683 | /* max num of ssids that can be probed during scanning */ |
3566 | wiphy->max_scan_ssids = MAX_PROBED_SSIDS; | 3684 | wiphy->max_scan_ssids = MAX_PROBED_SSIDS; |
3567 | 3685 | ||
@@ -3607,7 +3725,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) | |||
3607 | ath6kl_band_5ghz.ht_cap.ht_supported = false; | 3725 | ath6kl_band_5ghz.ht_cap.ht_supported = false; |
3608 | } | 3726 | } |
3609 | 3727 | ||
3610 | if (ar->hw.flags & ATH6KL_HW_FLAG_64BIT_RATES) { | 3728 | if (ar->hw.flags & ATH6KL_HW_64BIT_RATES) { |
3611 | ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff; | 3729 | ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff; |
3612 | ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff; | 3730 | ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff; |
3613 | ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff; | 3731 | ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff; |
@@ -3646,7 +3764,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) | |||
3646 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | | 3764 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | |
3647 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; | 3765 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; |
3648 | 3766 | ||
3649 | if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN, ar->fw_capabilities)) | 3767 | if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, ar->fw_capabilities)) |
3650 | ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; | 3768 | ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; |
3651 | 3769 | ||
3652 | if (test_bit(ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT, | 3770 | if (test_bit(ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT, |
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h index 780f77775a91..e5e70f3a8ca8 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.h +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.h | |||
@@ -22,7 +22,6 @@ enum ath6kl_cfg_suspend_mode { | |||
22 | ATH6KL_CFG_SUSPEND_DEEPSLEEP, | 22 | ATH6KL_CFG_SUSPEND_DEEPSLEEP, |
23 | ATH6KL_CFG_SUSPEND_CUTPOWER, | 23 | ATH6KL_CFG_SUSPEND_CUTPOWER, |
24 | ATH6KL_CFG_SUSPEND_WOW, | 24 | ATH6KL_CFG_SUSPEND_WOW, |
25 | ATH6KL_CFG_SUSPEND_SCHED_SCAN, | ||
26 | }; | 25 | }; |
27 | 26 | ||
28 | struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name, | 27 | struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name, |
diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c index 82c4dd2a960e..4b46adbe8c92 100644 --- a/drivers/net/wireless/ath/ath6kl/core.c +++ b/drivers/net/wireless/ath/ath6kl/core.c | |||
@@ -33,6 +33,8 @@ static unsigned int wow_mode; | |||
33 | static unsigned int uart_debug; | 33 | static unsigned int uart_debug; |
34 | static unsigned int ath6kl_p2p; | 34 | static unsigned int ath6kl_p2p; |
35 | static unsigned int testmode; | 35 | static unsigned int testmode; |
36 | static unsigned int recovery_enable; | ||
37 | static unsigned int heart_beat_poll; | ||
36 | 38 | ||
37 | module_param(debug_mask, uint, 0644); | 39 | module_param(debug_mask, uint, 0644); |
38 | module_param(suspend_mode, uint, 0644); | 40 | module_param(suspend_mode, uint, 0644); |
@@ -40,6 +42,12 @@ module_param(wow_mode, uint, 0644); | |||
40 | module_param(uart_debug, uint, 0644); | 42 | module_param(uart_debug, uint, 0644); |
41 | module_param(ath6kl_p2p, uint, 0644); | 43 | module_param(ath6kl_p2p, uint, 0644); |
42 | module_param(testmode, uint, 0644); | 44 | module_param(testmode, uint, 0644); |
45 | module_param(recovery_enable, uint, 0644); | ||
46 | module_param(heart_beat_poll, uint, 0644); | ||
47 | MODULE_PARM_DESC(recovery_enable, "Enable recovery from firmware error"); | ||
48 | MODULE_PARM_DESC(heart_beat_poll, "Enable fw error detection periodic" \ | ||
49 | "polling. This also specifies the polling interval in" \ | ||
50 | "msecs. Set reocvery_enable for this to be effective"); | ||
43 | 51 | ||
44 | void ath6kl_core_tx_complete(struct ath6kl *ar, struct sk_buff *skb) | 52 | void ath6kl_core_tx_complete(struct ath6kl *ar, struct sk_buff *skb) |
45 | { | 53 | { |
@@ -202,6 +210,17 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type) | |||
202 | ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n", | 210 | ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n", |
203 | __func__, wdev->netdev->name, wdev->netdev, ar); | 211 | __func__, wdev->netdev->name, wdev->netdev, ar); |
204 | 212 | ||
213 | ar->fw_recovery.enable = !!recovery_enable; | ||
214 | if (!ar->fw_recovery.enable) | ||
215 | return ret; | ||
216 | |||
217 | if (heart_beat_poll && | ||
218 | test_bit(ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL, | ||
219 | ar->fw_capabilities)) | ||
220 | ar->fw_recovery.hb_poll = heart_beat_poll; | ||
221 | |||
222 | ath6kl_recovery_init(ar); | ||
223 | |||
205 | return ret; | 224 | return ret; |
206 | 225 | ||
207 | err_rxbuf_cleanup: | 226 | err_rxbuf_cleanup: |
@@ -291,6 +310,8 @@ void ath6kl_core_cleanup(struct ath6kl *ar) | |||
291 | { | 310 | { |
292 | ath6kl_hif_power_off(ar); | 311 | ath6kl_hif_power_off(ar); |
293 | 312 | ||
313 | ath6kl_recovery_cleanup(ar); | ||
314 | |||
294 | destroy_workqueue(ar->ath6kl_wq); | 315 | destroy_workqueue(ar->ath6kl_wq); |
295 | 316 | ||
296 | if (ar->htc_target) | 317 | if (ar->htc_target) |
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index cec49a31029a..189d8faf8c87 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h | |||
@@ -115,6 +115,27 @@ enum ath6kl_fw_capability { | |||
115 | */ | 115 | */ |
116 | ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST, | 116 | ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST, |
117 | 117 | ||
118 | /* Firmware supports filtering BSS results by RSSI */ | ||
119 | ATH6KL_FW_CAPABILITY_RSSI_SCAN_THOLD, | ||
120 | |||
121 | /* FW sets mac_addr[4] ^= 0x80 for newly created interfaces */ | ||
122 | ATH6KL_FW_CAPABILITY_CUSTOM_MAC_ADDR, | ||
123 | |||
124 | /* Firmware supports TX error rate notification */ | ||
125 | ATH6KL_FW_CAPABILITY_TX_ERR_NOTIFY, | ||
126 | |||
127 | /* supports WMI_SET_REGDOMAIN_CMDID command */ | ||
128 | ATH6KL_FW_CAPABILITY_REGDOMAIN, | ||
129 | |||
130 | /* Firmware supports sched scan decoupled from host sleep */ | ||
131 | ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, | ||
132 | |||
133 | /* | ||
134 | * Firmware capability for hang detection through heart beat | ||
135 | * challenge messages. | ||
136 | */ | ||
137 | ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL, | ||
138 | |||
118 | /* this needs to be last */ | 139 | /* this needs to be last */ |
119 | ATH6KL_FW_CAPABILITY_MAX, | 140 | ATH6KL_FW_CAPABILITY_MAX, |
120 | }; | 141 | }; |
@@ -128,11 +149,15 @@ struct ath6kl_fw_ie { | |||
128 | }; | 149 | }; |
129 | 150 | ||
130 | enum ath6kl_hw_flags { | 151 | enum ath6kl_hw_flags { |
131 | ATH6KL_HW_FLAG_64BIT_RATES = BIT(0), | 152 | ATH6KL_HW_64BIT_RATES = BIT(0), |
153 | ATH6KL_HW_AP_INACTIVITY_MINS = BIT(1), | ||
154 | ATH6KL_HW_MAP_LP_ENDPOINT = BIT(2), | ||
155 | ATH6KL_HW_SDIO_CRC_ERROR_WAR = BIT(3), | ||
132 | }; | 156 | }; |
133 | 157 | ||
134 | #define ATH6KL_FW_API2_FILE "fw-2.bin" | 158 | #define ATH6KL_FW_API2_FILE "fw-2.bin" |
135 | #define ATH6KL_FW_API3_FILE "fw-3.bin" | 159 | #define ATH6KL_FW_API3_FILE "fw-3.bin" |
160 | #define ATH6KL_FW_API4_FILE "fw-4.bin" | ||
136 | 161 | ||
137 | /* AR6003 1.0 definitions */ | 162 | /* AR6003 1.0 definitions */ |
138 | #define AR6003_HW_1_0_VERSION 0x300002ba | 163 | #define AR6003_HW_1_0_VERSION 0x300002ba |
@@ -186,6 +211,13 @@ enum ath6kl_hw_flags { | |||
186 | #define AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE \ | 211 | #define AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE \ |
187 | AR6004_HW_1_2_FW_DIR "/bdata.bin" | 212 | AR6004_HW_1_2_FW_DIR "/bdata.bin" |
188 | 213 | ||
214 | /* AR6004 1.3 definitions */ | ||
215 | #define AR6004_HW_1_3_VERSION 0x31c8088a | ||
216 | #define AR6004_HW_1_3_FW_DIR "ath6k/AR6004/hw1.3" | ||
217 | #define AR6004_HW_1_3_FIRMWARE_FILE "fw.ram.bin" | ||
218 | #define AR6004_HW_1_3_BOARD_DATA_FILE "ath6k/AR6004/hw1.3/bdata.bin" | ||
219 | #define AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE "ath6k/AR6004/hw1.3/bdata.bin" | ||
220 | |||
189 | /* Per STA data, used in AP mode */ | 221 | /* Per STA data, used in AP mode */ |
190 | #define STA_PS_AWAKE BIT(0) | 222 | #define STA_PS_AWAKE BIT(0) |
191 | #define STA_PS_SLEEP BIT(1) | 223 | #define STA_PS_SLEEP BIT(1) |
@@ -536,6 +568,7 @@ enum ath6kl_vif_state { | |||
536 | HOST_SLEEP_MODE_CMD_PROCESSED, | 568 | HOST_SLEEP_MODE_CMD_PROCESSED, |
537 | NETDEV_MCAST_ALL_ON, | 569 | NETDEV_MCAST_ALL_ON, |
538 | NETDEV_MCAST_ALL_OFF, | 570 | NETDEV_MCAST_ALL_OFF, |
571 | SCHED_SCANNING, | ||
539 | }; | 572 | }; |
540 | 573 | ||
541 | struct ath6kl_vif { | 574 | struct ath6kl_vif { |
@@ -580,11 +613,13 @@ struct ath6kl_vif { | |||
580 | u16 assoc_bss_beacon_int; | 613 | u16 assoc_bss_beacon_int; |
581 | u16 listen_intvl_t; | 614 | u16 listen_intvl_t; |
582 | u16 bmiss_time_t; | 615 | u16 bmiss_time_t; |
616 | u32 txe_intvl; | ||
583 | u16 bg_scan_period; | 617 | u16 bg_scan_period; |
584 | u8 assoc_bss_dtim_period; | 618 | u8 assoc_bss_dtim_period; |
585 | struct net_device_stats net_stats; | 619 | struct net_device_stats net_stats; |
586 | struct target_stats target_stats; | 620 | struct target_stats target_stats; |
587 | struct wmi_connect_cmd profile; | 621 | struct wmi_connect_cmd profile; |
622 | u16 rsn_capab; | ||
588 | 623 | ||
589 | struct list_head mc_filter; | 624 | struct list_head mc_filter; |
590 | }; | 625 | }; |
@@ -609,6 +644,7 @@ enum ath6kl_dev_state { | |||
609 | SKIP_SCAN, | 644 | SKIP_SCAN, |
610 | ROAM_TBL_PEND, | 645 | ROAM_TBL_PEND, |
611 | FIRST_BOOT, | 646 | FIRST_BOOT, |
647 | RECOVERY_CLEANUP, | ||
612 | }; | 648 | }; |
613 | 649 | ||
614 | enum ath6kl_state { | 650 | enum ath6kl_state { |
@@ -619,7 +655,16 @@ enum ath6kl_state { | |||
619 | ATH6KL_STATE_DEEPSLEEP, | 655 | ATH6KL_STATE_DEEPSLEEP, |
620 | ATH6KL_STATE_CUTPOWER, | 656 | ATH6KL_STATE_CUTPOWER, |
621 | ATH6KL_STATE_WOW, | 657 | ATH6KL_STATE_WOW, |
622 | ATH6KL_STATE_SCHED_SCAN, | 658 | ATH6KL_STATE_RECOVERY, |
659 | }; | ||
660 | |||
661 | /* Fw error recovery */ | ||
662 | #define ATH6KL_HB_RESP_MISS_THRES 5 | ||
663 | |||
664 | enum ath6kl_fw_err { | ||
665 | ATH6KL_FW_ASSERT, | ||
666 | ATH6KL_FW_HB_RESP_FAILURE, | ||
667 | ATH6KL_FW_EP_FULL, | ||
623 | }; | 668 | }; |
624 | 669 | ||
625 | struct ath6kl { | 670 | struct ath6kl { |
@@ -679,6 +724,7 @@ struct ath6kl { | |||
679 | struct ath6kl_req_key ap_mode_bkey; | 724 | struct ath6kl_req_key ap_mode_bkey; |
680 | struct sk_buff_head mcastpsq; | 725 | struct sk_buff_head mcastpsq; |
681 | u32 want_ch_switch; | 726 | u32 want_ch_switch; |
727 | u16 last_ch; | ||
682 | 728 | ||
683 | /* | 729 | /* |
684 | * FIXME: protects access to mcastpsq but is actually useless as | 730 | * FIXME: protects access to mcastpsq but is actually useless as |
@@ -764,6 +810,17 @@ struct ath6kl { | |||
764 | 810 | ||
765 | bool wiphy_registered; | 811 | bool wiphy_registered; |
766 | 812 | ||
813 | struct ath6kl_fw_recovery { | ||
814 | struct work_struct recovery_work; | ||
815 | unsigned long err_reason; | ||
816 | unsigned long hb_poll; | ||
817 | struct timer_list hb_timer; | ||
818 | u32 seq_num; | ||
819 | bool hb_pending; | ||
820 | u8 hb_misscnt; | ||
821 | bool enable; | ||
822 | } fw_recovery; | ||
823 | |||
767 | #ifdef CONFIG_ATH6KL_DEBUG | 824 | #ifdef CONFIG_ATH6KL_DEBUG |
768 | struct { | 825 | struct { |
769 | struct sk_buff_head fwlog_queue; | 826 | struct sk_buff_head fwlog_queue; |
@@ -899,4 +956,12 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type); | |||
899 | void ath6kl_core_cleanup(struct ath6kl *ar); | 956 | void ath6kl_core_cleanup(struct ath6kl *ar); |
900 | void ath6kl_core_destroy(struct ath6kl *ar); | 957 | void ath6kl_core_destroy(struct ath6kl *ar); |
901 | 958 | ||
959 | /* Fw error recovery */ | ||
960 | void ath6kl_init_hw_restart(struct ath6kl *ar); | ||
961 | void ath6kl_recovery_err_notify(struct ath6kl *ar, enum ath6kl_fw_err reason); | ||
962 | void ath6kl_recovery_hb_event(struct ath6kl *ar, u32 cookie); | ||
963 | void ath6kl_recovery_init(struct ath6kl *ar); | ||
964 | void ath6kl_recovery_cleanup(struct ath6kl *ar); | ||
965 | void ath6kl_recovery_suspend(struct ath6kl *ar); | ||
966 | void ath6kl_recovery_resume(struct ath6kl *ar); | ||
902 | #endif /* CORE_H */ | 967 | #endif /* CORE_H */ |
diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h index 49639d8266c2..f97cd4ead543 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.h +++ b/drivers/net/wireless/ath/ath6kl/debug.h | |||
@@ -44,6 +44,7 @@ enum ATH6K_DEBUG_MASK { | |||
44 | ATH6KL_DBG_SUSPEND = BIT(20), | 44 | ATH6KL_DBG_SUSPEND = BIT(20), |
45 | ATH6KL_DBG_USB = BIT(21), | 45 | ATH6KL_DBG_USB = BIT(21), |
46 | ATH6KL_DBG_USB_BULK = BIT(22), | 46 | ATH6KL_DBG_USB_BULK = BIT(22), |
47 | ATH6KL_DBG_RECOVERY = BIT(23), | ||
47 | ATH6KL_DBG_ANY = 0xffffffff /* enable all logs */ | 48 | ATH6KL_DBG_ANY = 0xffffffff /* enable all logs */ |
48 | }; | 49 | }; |
49 | 50 | ||
diff --git a/drivers/net/wireless/ath/ath6kl/hif.c b/drivers/net/wireless/ath/ath6kl/hif.c index 68ed6c2665b7..a6b614421fa4 100644 --- a/drivers/net/wireless/ath/ath6kl/hif.c +++ b/drivers/net/wireless/ath/ath6kl/hif.c | |||
@@ -136,6 +136,7 @@ static int ath6kl_hif_proc_dbg_intr(struct ath6kl_device *dev) | |||
136 | 136 | ||
137 | ath6kl_hif_dump_fw_crash(dev->ar); | 137 | ath6kl_hif_dump_fw_crash(dev->ar); |
138 | ath6kl_read_fwlogs(dev->ar); | 138 | ath6kl_read_fwlogs(dev->ar); |
139 | ath6kl_recovery_err_notify(dev->ar, ATH6KL_FW_ASSERT); | ||
139 | 140 | ||
140 | return ret; | 141 | return ret; |
141 | } | 142 | } |
@@ -338,8 +339,7 @@ static int ath6kl_hif_proc_err_intr(struct ath6kl_device *dev) | |||
338 | status = hif_read_write_sync(dev->ar, ERROR_INT_STATUS_ADDRESS, | 339 | status = hif_read_write_sync(dev->ar, ERROR_INT_STATUS_ADDRESS, |
339 | reg_buf, 4, HIF_WR_SYNC_BYTE_FIX); | 340 | reg_buf, 4, HIF_WR_SYNC_BYTE_FIX); |
340 | 341 | ||
341 | if (status) | 342 | WARN_ON(status); |
342 | WARN_ON(1); | ||
343 | 343 | ||
344 | return status; | 344 | return status; |
345 | } | 345 | } |
@@ -383,8 +383,7 @@ static int ath6kl_hif_proc_cpu_intr(struct ath6kl_device *dev) | |||
383 | status = hif_read_write_sync(dev->ar, CPU_INT_STATUS_ADDRESS, | 383 | status = hif_read_write_sync(dev->ar, CPU_INT_STATUS_ADDRESS, |
384 | reg_buf, 4, HIF_WR_SYNC_BYTE_FIX); | 384 | reg_buf, 4, HIF_WR_SYNC_BYTE_FIX); |
385 | 385 | ||
386 | if (status) | 386 | WARN_ON(status); |
387 | WARN_ON(1); | ||
388 | 387 | ||
389 | return status; | 388 | return status; |
390 | } | 389 | } |
@@ -695,11 +694,6 @@ int ath6kl_hif_setup(struct ath6kl_device *dev) | |||
695 | ath6kl_dbg(ATH6KL_DBG_HIF, "hif block size %d mbox addr 0x%x\n", | 694 | ath6kl_dbg(ATH6KL_DBG_HIF, "hif block size %d mbox addr 0x%x\n", |
696 | dev->htc_cnxt->block_sz, dev->ar->mbox_info.htc_addr); | 695 | dev->htc_cnxt->block_sz, dev->ar->mbox_info.htc_addr); |
697 | 696 | ||
698 | /* usb doesn't support enabling interrupts */ | ||
699 | /* FIXME: remove check once USB support is implemented */ | ||
700 | if (dev->ar->hif_type == ATH6KL_HIF_TYPE_USB) | ||
701 | return 0; | ||
702 | |||
703 | status = ath6kl_hif_disable_intrs(dev); | 697 | status = ath6kl_hif_disable_intrs(dev); |
704 | 698 | ||
705 | fail_setup: | 699 | fail_setup: |
diff --git a/drivers/net/wireless/ath/ath6kl/htc_mbox.c b/drivers/net/wireless/ath/ath6kl/htc_mbox.c index cd0e1ba410d6..fbb78dfe078f 100644 --- a/drivers/net/wireless/ath/ath6kl/htc_mbox.c +++ b/drivers/net/wireless/ath/ath6kl/htc_mbox.c | |||
@@ -2492,7 +2492,8 @@ static int ath6kl_htc_mbox_conn_service(struct htc_target *target, | |||
2492 | max_msg_sz = le16_to_cpu(resp_msg->max_msg_sz); | 2492 | max_msg_sz = le16_to_cpu(resp_msg->max_msg_sz); |
2493 | } | 2493 | } |
2494 | 2494 | ||
2495 | if (assigned_ep >= ENDPOINT_MAX || !max_msg_sz) { | 2495 | if (WARN_ON_ONCE(assigned_ep == ENDPOINT_UNUSED || |
2496 | assigned_ep >= ENDPOINT_MAX || !max_msg_sz)) { | ||
2496 | status = -ENOMEM; | 2497 | status = -ENOMEM; |
2497 | goto fail_tx; | 2498 | goto fail_tx; |
2498 | } | 2499 | } |
@@ -2655,12 +2656,6 @@ static int ath6kl_htc_mbox_wait_target(struct htc_target *target) | |||
2655 | struct htc_service_connect_resp resp; | 2656 | struct htc_service_connect_resp resp; |
2656 | int status; | 2657 | int status; |
2657 | 2658 | ||
2658 | /* FIXME: remove once USB support is implemented */ | ||
2659 | if (target->dev->ar->hif_type == ATH6KL_HIF_TYPE_USB) { | ||
2660 | ath6kl_err("HTC doesn't support USB yet. Patience!\n"); | ||
2661 | return -EOPNOTSUPP; | ||
2662 | } | ||
2663 | |||
2664 | /* we should be getting 1 control message that the target is ready */ | 2659 | /* we should be getting 1 control message that the target is ready */ |
2665 | packet = htc_wait_for_ctrl_msg(target); | 2660 | packet = htc_wait_for_ctrl_msg(target); |
2666 | 2661 | ||
@@ -2890,9 +2885,7 @@ static void ath6kl_htc_mbox_cleanup(struct htc_target *target) | |||
2890 | { | 2885 | { |
2891 | struct htc_packet *packet, *tmp_packet; | 2886 | struct htc_packet *packet, *tmp_packet; |
2892 | 2887 | ||
2893 | /* FIXME: remove check once USB support is implemented */ | 2888 | ath6kl_hif_cleanup_scatter(target->dev->ar); |
2894 | if (target->dev->ar->hif_type != ATH6KL_HIF_TYPE_USB) | ||
2895 | ath6kl_hif_cleanup_scatter(target->dev->ar); | ||
2896 | 2889 | ||
2897 | list_for_each_entry_safe(packet, tmp_packet, | 2890 | list_for_each_entry_safe(packet, tmp_packet, |
2898 | &target->free_ctrl_txbuf, list) { | 2891 | &target->free_ctrl_txbuf, list) { |
diff --git a/drivers/net/wireless/ath/ath6kl/htc_pipe.c b/drivers/net/wireless/ath/ath6kl/htc_pipe.c index f9626c723693..ba6bd497b787 100644 --- a/drivers/net/wireless/ath/ath6kl/htc_pipe.c +++ b/drivers/net/wireless/ath/ath6kl/htc_pipe.c | |||
@@ -374,9 +374,8 @@ static enum htc_send_queue_result htc_try_send(struct htc_target *target, | |||
374 | packet = list_first_entry(txq, | 374 | packet = list_first_entry(txq, |
375 | struct htc_packet, | 375 | struct htc_packet, |
376 | list); | 376 | list); |
377 | list_del(&packet->list); | 377 | /* move to local queue */ |
378 | /* insert into local queue */ | 378 | list_move_tail(&packet->list, &send_queue); |
379 | list_add_tail(&packet->list, &send_queue); | ||
380 | } | 379 | } |
381 | 380 | ||
382 | /* | 381 | /* |
@@ -399,11 +398,10 @@ static enum htc_send_queue_result htc_try_send(struct htc_target *target, | |||
399 | * for cleanup */ | 398 | * for cleanup */ |
400 | } else { | 399 | } else { |
401 | /* callback wants to keep this packet, | 400 | /* callback wants to keep this packet, |
402 | * remove from caller's queue */ | 401 | * move from caller's queue to the send |
403 | list_del(&packet->list); | 402 | * queue */ |
404 | /* put it in the send queue */ | 403 | list_move_tail(&packet->list, |
405 | list_add_tail(&packet->list, | 404 | &send_queue); |
406 | &send_queue); | ||
407 | } | 405 | } |
408 | 406 | ||
409 | } | 407 | } |
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index f90b5db741cf..f21fa322e5ca 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c | |||
@@ -42,7 +42,7 @@ static const struct ath6kl_hw hw_list[] = { | |||
42 | .reserved_ram_size = 6912, | 42 | .reserved_ram_size = 6912, |
43 | .refclk_hz = 26000000, | 43 | .refclk_hz = 26000000, |
44 | .uarttx_pin = 8, | 44 | .uarttx_pin = 8, |
45 | .flags = 0, | 45 | .flags = ATH6KL_HW_SDIO_CRC_ERROR_WAR, |
46 | 46 | ||
47 | /* hw2.0 needs override address hardcoded */ | 47 | /* hw2.0 needs override address hardcoded */ |
48 | .app_start_override_addr = 0x944C00, | 48 | .app_start_override_addr = 0x944C00, |
@@ -68,7 +68,7 @@ static const struct ath6kl_hw hw_list[] = { | |||
68 | .refclk_hz = 26000000, | 68 | .refclk_hz = 26000000, |
69 | .uarttx_pin = 8, | 69 | .uarttx_pin = 8, |
70 | .testscript_addr = 0x57ef74, | 70 | .testscript_addr = 0x57ef74, |
71 | .flags = 0, | 71 | .flags = ATH6KL_HW_SDIO_CRC_ERROR_WAR, |
72 | 72 | ||
73 | .fw = { | 73 | .fw = { |
74 | .dir = AR6003_HW_2_1_1_FW_DIR, | 74 | .dir = AR6003_HW_2_1_1_FW_DIR, |
@@ -93,7 +93,8 @@ static const struct ath6kl_hw hw_list[] = { | |||
93 | .board_addr = 0x433900, | 93 | .board_addr = 0x433900, |
94 | .refclk_hz = 26000000, | 94 | .refclk_hz = 26000000, |
95 | .uarttx_pin = 11, | 95 | .uarttx_pin = 11, |
96 | .flags = ATH6KL_HW_FLAG_64BIT_RATES, | 96 | .flags = ATH6KL_HW_64BIT_RATES | |
97 | ATH6KL_HW_AP_INACTIVITY_MINS, | ||
97 | 98 | ||
98 | .fw = { | 99 | .fw = { |
99 | .dir = AR6004_HW_1_0_FW_DIR, | 100 | .dir = AR6004_HW_1_0_FW_DIR, |
@@ -113,8 +114,8 @@ static const struct ath6kl_hw hw_list[] = { | |||
113 | .board_addr = 0x43d400, | 114 | .board_addr = 0x43d400, |
114 | .refclk_hz = 40000000, | 115 | .refclk_hz = 40000000, |
115 | .uarttx_pin = 11, | 116 | .uarttx_pin = 11, |
116 | .flags = ATH6KL_HW_FLAG_64BIT_RATES, | 117 | .flags = ATH6KL_HW_64BIT_RATES | |
117 | 118 | ATH6KL_HW_AP_INACTIVITY_MINS, | |
118 | .fw = { | 119 | .fw = { |
119 | .dir = AR6004_HW_1_1_FW_DIR, | 120 | .dir = AR6004_HW_1_1_FW_DIR, |
120 | .fw = AR6004_HW_1_1_FIRMWARE_FILE, | 121 | .fw = AR6004_HW_1_1_FIRMWARE_FILE, |
@@ -133,7 +134,8 @@ static const struct ath6kl_hw hw_list[] = { | |||
133 | .board_addr = 0x435c00, | 134 | .board_addr = 0x435c00, |
134 | .refclk_hz = 40000000, | 135 | .refclk_hz = 40000000, |
135 | .uarttx_pin = 11, | 136 | .uarttx_pin = 11, |
136 | .flags = ATH6KL_HW_FLAG_64BIT_RATES, | 137 | .flags = ATH6KL_HW_64BIT_RATES | |
138 | ATH6KL_HW_AP_INACTIVITY_MINS, | ||
137 | 139 | ||
138 | .fw = { | 140 | .fw = { |
139 | .dir = AR6004_HW_1_2_FW_DIR, | 141 | .dir = AR6004_HW_1_2_FW_DIR, |
@@ -142,6 +144,28 @@ static const struct ath6kl_hw hw_list[] = { | |||
142 | .fw_board = AR6004_HW_1_2_BOARD_DATA_FILE, | 144 | .fw_board = AR6004_HW_1_2_BOARD_DATA_FILE, |
143 | .fw_default_board = AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE, | 145 | .fw_default_board = AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE, |
144 | }, | 146 | }, |
147 | { | ||
148 | .id = AR6004_HW_1_3_VERSION, | ||
149 | .name = "ar6004 hw 1.3", | ||
150 | .dataset_patch_addr = 0x437860, | ||
151 | .app_load_addr = 0x1234, | ||
152 | .board_ext_data_addr = 0x437000, | ||
153 | .reserved_ram_size = 7168, | ||
154 | .board_addr = 0x436400, | ||
155 | .refclk_hz = 40000000, | ||
156 | .uarttx_pin = 11, | ||
157 | .flags = ATH6KL_HW_64BIT_RATES | | ||
158 | ATH6KL_HW_AP_INACTIVITY_MINS | | ||
159 | ATH6KL_HW_MAP_LP_ENDPOINT, | ||
160 | |||
161 | .fw = { | ||
162 | .dir = AR6004_HW_1_3_FW_DIR, | ||
163 | .fw = AR6004_HW_1_3_FIRMWARE_FILE, | ||
164 | }, | ||
165 | |||
166 | .fw_board = AR6004_HW_1_3_BOARD_DATA_FILE, | ||
167 | .fw_default_board = AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE, | ||
168 | }, | ||
145 | }; | 169 | }; |
146 | 170 | ||
147 | /* | 171 | /* |
@@ -337,7 +361,7 @@ static int ath6kl_init_service_ep(struct ath6kl *ar) | |||
337 | if (ath6kl_connectservice(ar, &connect, "WMI DATA BK")) | 361 | if (ath6kl_connectservice(ar, &connect, "WMI DATA BK")) |
338 | return -EIO; | 362 | return -EIO; |
339 | 363 | ||
340 | /* connect to Video service, map this to to HI PRI */ | 364 | /* connect to Video service, map this to HI PRI */ |
341 | connect.svc_id = WMI_DATA_VI_SVC; | 365 | connect.svc_id = WMI_DATA_VI_SVC; |
342 | if (ath6kl_connectservice(ar, &connect, "WMI DATA VI")) | 366 | if (ath6kl_connectservice(ar, &connect, "WMI DATA VI")) |
343 | return -EIO; | 367 | return -EIO; |
@@ -1088,6 +1112,12 @@ int ath6kl_init_fetch_firmwares(struct ath6kl *ar) | |||
1088 | if (ret) | 1112 | if (ret) |
1089 | return ret; | 1113 | return ret; |
1090 | 1114 | ||
1115 | ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API4_FILE); | ||
1116 | if (ret == 0) { | ||
1117 | ar->fw_api = 4; | ||
1118 | goto out; | ||
1119 | } | ||
1120 | |||
1091 | ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API3_FILE); | 1121 | ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API3_FILE); |
1092 | if (ret == 0) { | 1122 | if (ret == 0) { |
1093 | ar->fw_api = 3; | 1123 | ar->fw_api = 3; |
@@ -1401,8 +1431,7 @@ static int ath6kl_init_upload(struct ath6kl *ar) | |||
1401 | return status; | 1431 | return status; |
1402 | 1432 | ||
1403 | /* WAR to avoid SDIO CRC err */ | 1433 | /* WAR to avoid SDIO CRC err */ |
1404 | if (ar->version.target_ver == AR6003_HW_2_0_VERSION || | 1434 | if (ar->hw.flags & ATH6KL_HW_SDIO_CRC_ERROR_WAR) { |
1405 | ar->version.target_ver == AR6003_HW_2_1_1_VERSION) { | ||
1406 | ath6kl_err("temporary war to avoid sdio crc error\n"); | 1435 | ath6kl_err("temporary war to avoid sdio crc error\n"); |
1407 | 1436 | ||
1408 | param = 0x28; | 1437 | param = 0x28; |
@@ -1520,7 +1549,7 @@ static const char *ath6kl_init_get_hif_name(enum ath6kl_hif_type type) | |||
1520 | return NULL; | 1549 | return NULL; |
1521 | } | 1550 | } |
1522 | 1551 | ||
1523 | int ath6kl_init_hw_start(struct ath6kl *ar) | 1552 | static int __ath6kl_init_hw_start(struct ath6kl *ar) |
1524 | { | 1553 | { |
1525 | long timeleft; | 1554 | long timeleft; |
1526 | int ret, i; | 1555 | int ret, i; |
@@ -1616,8 +1645,6 @@ int ath6kl_init_hw_start(struct ath6kl *ar) | |||
1616 | goto err_htc_stop; | 1645 | goto err_htc_stop; |
1617 | } | 1646 | } |
1618 | 1647 | ||
1619 | ar->state = ATH6KL_STATE_ON; | ||
1620 | |||
1621 | return 0; | 1648 | return 0; |
1622 | 1649 | ||
1623 | err_htc_stop: | 1650 | err_htc_stop: |
@@ -1630,7 +1657,18 @@ err_power_off: | |||
1630 | return ret; | 1657 | return ret; |
1631 | } | 1658 | } |
1632 | 1659 | ||
1633 | int ath6kl_init_hw_stop(struct ath6kl *ar) | 1660 | int ath6kl_init_hw_start(struct ath6kl *ar) |
1661 | { | ||
1662 | int err; | ||
1663 | |||
1664 | err = __ath6kl_init_hw_start(ar); | ||
1665 | if (err) | ||
1666 | return err; | ||
1667 | ar->state = ATH6KL_STATE_ON; | ||
1668 | return 0; | ||
1669 | } | ||
1670 | |||
1671 | static int __ath6kl_init_hw_stop(struct ath6kl *ar) | ||
1634 | { | 1672 | { |
1635 | int ret; | 1673 | int ret; |
1636 | 1674 | ||
@@ -1646,11 +1684,37 @@ int ath6kl_init_hw_stop(struct ath6kl *ar) | |||
1646 | if (ret) | 1684 | if (ret) |
1647 | ath6kl_warn("failed to power off hif: %d\n", ret); | 1685 | ath6kl_warn("failed to power off hif: %d\n", ret); |
1648 | 1686 | ||
1649 | ar->state = ATH6KL_STATE_OFF; | 1687 | return 0; |
1688 | } | ||
1650 | 1689 | ||
1690 | int ath6kl_init_hw_stop(struct ath6kl *ar) | ||
1691 | { | ||
1692 | int err; | ||
1693 | |||
1694 | err = __ath6kl_init_hw_stop(ar); | ||
1695 | if (err) | ||
1696 | return err; | ||
1697 | ar->state = ATH6KL_STATE_OFF; | ||
1651 | return 0; | 1698 | return 0; |
1652 | } | 1699 | } |
1653 | 1700 | ||
1701 | void ath6kl_init_hw_restart(struct ath6kl *ar) | ||
1702 | { | ||
1703 | clear_bit(WMI_READY, &ar->flag); | ||
1704 | |||
1705 | ath6kl_cfg80211_stop_all(ar); | ||
1706 | |||
1707 | if (__ath6kl_init_hw_stop(ar)) { | ||
1708 | ath6kl_dbg(ATH6KL_DBG_RECOVERY, "Failed to stop during fw error recovery\n"); | ||
1709 | return; | ||
1710 | } | ||
1711 | |||
1712 | if (__ath6kl_init_hw_start(ar)) { | ||
1713 | ath6kl_dbg(ATH6KL_DBG_RECOVERY, "Failed to restart during fw error recovery\n"); | ||
1714 | return; | ||
1715 | } | ||
1716 | } | ||
1717 | |||
1654 | /* FIXME: move this to cfg80211.c and rename to ath6kl_cfg80211_vif_stop() */ | 1718 | /* FIXME: move this to cfg80211.c and rename to ath6kl_cfg80211_vif_stop() */ |
1655 | void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready) | 1719 | void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready) |
1656 | { | 1720 | { |
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index c189e28e86a9..bd50b6b7b492 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c | |||
@@ -293,13 +293,17 @@ int ath6kl_read_fwlogs(struct ath6kl *ar) | |||
293 | } | 293 | } |
294 | 294 | ||
295 | address = TARG_VTOP(ar->target_type, debug_hdr_addr); | 295 | address = TARG_VTOP(ar->target_type, debug_hdr_addr); |
296 | ath6kl_diag_read(ar, address, &debug_hdr, sizeof(debug_hdr)); | 296 | ret = ath6kl_diag_read(ar, address, &debug_hdr, sizeof(debug_hdr)); |
297 | if (ret) | ||
298 | goto out; | ||
297 | 299 | ||
298 | address = TARG_VTOP(ar->target_type, | 300 | address = TARG_VTOP(ar->target_type, |
299 | le32_to_cpu(debug_hdr.dbuf_addr)); | 301 | le32_to_cpu(debug_hdr.dbuf_addr)); |
300 | firstbuf = address; | 302 | firstbuf = address; |
301 | dropped = le32_to_cpu(debug_hdr.dropped); | 303 | dropped = le32_to_cpu(debug_hdr.dropped); |
302 | ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf)); | 304 | ret = ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf)); |
305 | if (ret) | ||
306 | goto out; | ||
303 | 307 | ||
304 | loop = 100; | 308 | loop = 100; |
305 | 309 | ||
@@ -322,7 +326,8 @@ int ath6kl_read_fwlogs(struct ath6kl *ar) | |||
322 | 326 | ||
323 | address = TARG_VTOP(ar->target_type, | 327 | address = TARG_VTOP(ar->target_type, |
324 | le32_to_cpu(debug_buf.next)); | 328 | le32_to_cpu(debug_buf.next)); |
325 | ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf)); | 329 | ret = ath6kl_diag_read(ar, address, &debug_buf, |
330 | sizeof(debug_buf)); | ||
326 | if (ret) | 331 | if (ret) |
327 | goto out; | 332 | goto out; |
328 | 333 | ||
@@ -436,12 +441,9 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel) | |||
436 | break; | 441 | break; |
437 | } | 442 | } |
438 | 443 | ||
439 | if (ar->want_ch_switch & (1 << vif->fw_vif_idx)) { | 444 | if (ar->last_ch != channel) |
440 | ar->want_ch_switch &= ~(1 << vif->fw_vif_idx); | ||
441 | /* we actually don't know the phymode, default to HT20 */ | 445 | /* we actually don't know the phymode, default to HT20 */ |
442 | ath6kl_cfg80211_ch_switch_notify(vif, channel, | 446 | ath6kl_cfg80211_ch_switch_notify(vif, channel, WMI_11G_HT20); |
443 | WMI_11G_HT20); | ||
444 | } | ||
445 | 447 | ||
446 | ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, NONE_BSS_FILTER, 0); | 448 | ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, NONE_BSS_FILTER, 0); |
447 | set_bit(CONNECTED, &vif->flags); | 449 | set_bit(CONNECTED, &vif->flags); |
@@ -606,6 +608,18 @@ static int ath6kl_commit_ch_switch(struct ath6kl_vif *vif, u16 channel) | |||
606 | 608 | ||
607 | switch (vif->nw_type) { | 609 | switch (vif->nw_type) { |
608 | case AP_NETWORK: | 610 | case AP_NETWORK: |
611 | /* | ||
612 | * reconfigure any saved RSN IE capabilites in the beacon / | ||
613 | * probe response to stay in sync with the supplicant. | ||
614 | */ | ||
615 | if (vif->rsn_capab && | ||
616 | test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE, | ||
617 | ar->fw_capabilities)) | ||
618 | ath6kl_wmi_set_ie_cmd(ar->wmi, vif->fw_vif_idx, | ||
619 | WLAN_EID_RSN, WMI_RSN_IE_CAPB, | ||
620 | (const u8 *) &vif->rsn_capab, | ||
621 | sizeof(vif->rsn_capab)); | ||
622 | |||
609 | return ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, | 623 | return ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, |
610 | &vif->profile); | 624 | &vif->profile); |
611 | default: | 625 | default: |
@@ -628,6 +642,9 @@ static void ath6kl_check_ch_switch(struct ath6kl *ar, u16 channel) | |||
628 | if (ar->want_ch_switch & (1 << vif->fw_vif_idx)) | 642 | if (ar->want_ch_switch & (1 << vif->fw_vif_idx)) |
629 | res = ath6kl_commit_ch_switch(vif, channel); | 643 | res = ath6kl_commit_ch_switch(vif, channel); |
630 | 644 | ||
645 | /* if channel switch failed, oh well we tried */ | ||
646 | ar->want_ch_switch &= ~(1 << vif->fw_vif_idx); | ||
647 | |||
631 | if (res) | 648 | if (res) |
632 | ath6kl_err("channel switch failed nw_type %d res %d\n", | 649 | ath6kl_err("channel switch failed nw_type %d res %d\n", |
633 | vif->nw_type, res); | 650 | vif->nw_type, res); |
@@ -981,8 +998,25 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid, | |||
981 | if (vif->nw_type == AP_NETWORK) { | 998 | if (vif->nw_type == AP_NETWORK) { |
982 | /* disconnect due to other STA vif switching channels */ | 999 | /* disconnect due to other STA vif switching channels */ |
983 | if (reason == BSS_DISCONNECTED && | 1000 | if (reason == BSS_DISCONNECTED && |
984 | prot_reason_status == WMI_AP_REASON_STA_ROAM) | 1001 | prot_reason_status == WMI_AP_REASON_STA_ROAM) { |
985 | ar->want_ch_switch |= 1 << vif->fw_vif_idx; | 1002 | ar->want_ch_switch |= 1 << vif->fw_vif_idx; |
1003 | /* bail back to this channel if STA vif fails connect */ | ||
1004 | ar->last_ch = le16_to_cpu(vif->profile.ch); | ||
1005 | } | ||
1006 | |||
1007 | if (prot_reason_status == WMI_AP_REASON_MAX_STA) { | ||
1008 | /* send max client reached notification to user space */ | ||
1009 | cfg80211_conn_failed(vif->ndev, bssid, | ||
1010 | NL80211_CONN_FAIL_MAX_CLIENTS, | ||
1011 | GFP_KERNEL); | ||
1012 | } | ||
1013 | |||
1014 | if (prot_reason_status == WMI_AP_REASON_ACL) { | ||
1015 | /* send blocked client notification to user space */ | ||
1016 | cfg80211_conn_failed(vif->ndev, bssid, | ||
1017 | NL80211_CONN_FAIL_BLOCKED_CLIENT, | ||
1018 | GFP_KERNEL); | ||
1019 | } | ||
986 | 1020 | ||
987 | if (!ath6kl_remove_sta(ar, bssid, prot_reason_status)) | 1021 | if (!ath6kl_remove_sta(ar, bssid, prot_reason_status)) |
988 | return; | 1022 | return; |
@@ -1041,6 +1075,9 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid, | |||
1041 | } | 1075 | } |
1042 | } | 1076 | } |
1043 | 1077 | ||
1078 | /* restart disconnected concurrent vifs waiting for new channel */ | ||
1079 | ath6kl_check_ch_switch(ar, ar->last_ch); | ||
1080 | |||
1044 | /* update connect & link status atomically */ | 1081 | /* update connect & link status atomically */ |
1045 | spin_lock_bh(&vif->if_lock); | 1082 | spin_lock_bh(&vif->if_lock); |
1046 | clear_bit(CONNECTED, &vif->flags); | 1083 | clear_bit(CONNECTED, &vif->flags); |
diff --git a/drivers/net/wireless/ath/ath6kl/recovery.c b/drivers/net/wireless/ath/ath6kl/recovery.c new file mode 100644 index 000000000000..3a8d5e97dc8e --- /dev/null +++ b/drivers/net/wireless/ath/ath6kl/recovery.c | |||
@@ -0,0 +1,160 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012 Qualcomm Atheros, Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "core.h" | ||
18 | #include "cfg80211.h" | ||
19 | #include "debug.h" | ||
20 | |||
21 | static void ath6kl_recovery_work(struct work_struct *work) | ||
22 | { | ||
23 | struct ath6kl *ar = container_of(work, struct ath6kl, | ||
24 | fw_recovery.recovery_work); | ||
25 | |||
26 | ar->state = ATH6KL_STATE_RECOVERY; | ||
27 | |||
28 | del_timer_sync(&ar->fw_recovery.hb_timer); | ||
29 | |||
30 | ath6kl_init_hw_restart(ar); | ||
31 | |||
32 | ar->state = ATH6KL_STATE_ON; | ||
33 | clear_bit(WMI_CTRL_EP_FULL, &ar->flag); | ||
34 | |||
35 | ar->fw_recovery.err_reason = 0; | ||
36 | |||
37 | if (ar->fw_recovery.hb_poll) | ||
38 | mod_timer(&ar->fw_recovery.hb_timer, jiffies + | ||
39 | msecs_to_jiffies(ar->fw_recovery.hb_poll)); | ||
40 | } | ||
41 | |||
42 | void ath6kl_recovery_err_notify(struct ath6kl *ar, enum ath6kl_fw_err reason) | ||
43 | { | ||
44 | if (!ar->fw_recovery.enable) | ||
45 | return; | ||
46 | |||
47 | ath6kl_dbg(ATH6KL_DBG_RECOVERY, "Fw error detected, reason:%d\n", | ||
48 | reason); | ||
49 | |||
50 | set_bit(reason, &ar->fw_recovery.err_reason); | ||
51 | |||
52 | if (!test_bit(RECOVERY_CLEANUP, &ar->flag) && | ||
53 | ar->state != ATH6KL_STATE_RECOVERY) | ||
54 | queue_work(ar->ath6kl_wq, &ar->fw_recovery.recovery_work); | ||
55 | } | ||
56 | |||
57 | void ath6kl_recovery_hb_event(struct ath6kl *ar, u32 cookie) | ||
58 | { | ||
59 | if (cookie == ar->fw_recovery.seq_num) | ||
60 | ar->fw_recovery.hb_pending = false; | ||
61 | } | ||
62 | |||
63 | static void ath6kl_recovery_hb_timer(unsigned long data) | ||
64 | { | ||
65 | struct ath6kl *ar = (struct ath6kl *) data; | ||
66 | int err; | ||
67 | |||
68 | if (test_bit(RECOVERY_CLEANUP, &ar->flag) || | ||
69 | (ar->state == ATH6KL_STATE_RECOVERY)) | ||
70 | return; | ||
71 | |||
72 | if (ar->fw_recovery.hb_pending) | ||
73 | ar->fw_recovery.hb_misscnt++; | ||
74 | else | ||
75 | ar->fw_recovery.hb_misscnt = 0; | ||
76 | |||
77 | if (ar->fw_recovery.hb_misscnt > ATH6KL_HB_RESP_MISS_THRES) { | ||
78 | ar->fw_recovery.hb_misscnt = 0; | ||
79 | ar->fw_recovery.seq_num = 0; | ||
80 | ar->fw_recovery.hb_pending = false; | ||
81 | ath6kl_recovery_err_notify(ar, ATH6KL_FW_HB_RESP_FAILURE); | ||
82 | return; | ||
83 | } | ||
84 | |||
85 | ar->fw_recovery.seq_num++; | ||
86 | ar->fw_recovery.hb_pending = true; | ||
87 | |||
88 | err = ath6kl_wmi_get_challenge_resp_cmd(ar->wmi, | ||
89 | ar->fw_recovery.seq_num, 0); | ||
90 | if (err) | ||
91 | ath6kl_warn("Failed to send hb challenge request, err:%d\n", | ||
92 | err); | ||
93 | |||
94 | mod_timer(&ar->fw_recovery.hb_timer, jiffies + | ||
95 | msecs_to_jiffies(ar->fw_recovery.hb_poll)); | ||
96 | } | ||
97 | |||
98 | void ath6kl_recovery_init(struct ath6kl *ar) | ||
99 | { | ||
100 | struct ath6kl_fw_recovery *recovery = &ar->fw_recovery; | ||
101 | |||
102 | clear_bit(RECOVERY_CLEANUP, &ar->flag); | ||
103 | INIT_WORK(&recovery->recovery_work, ath6kl_recovery_work); | ||
104 | recovery->seq_num = 0; | ||
105 | recovery->hb_misscnt = 0; | ||
106 | ar->fw_recovery.hb_pending = false; | ||
107 | ar->fw_recovery.hb_timer.function = ath6kl_recovery_hb_timer; | ||
108 | ar->fw_recovery.hb_timer.data = (unsigned long) ar; | ||
109 | init_timer_deferrable(&ar->fw_recovery.hb_timer); | ||
110 | |||
111 | if (ar->fw_recovery.hb_poll) | ||
112 | mod_timer(&ar->fw_recovery.hb_timer, jiffies + | ||
113 | msecs_to_jiffies(ar->fw_recovery.hb_poll)); | ||
114 | } | ||
115 | |||
116 | void ath6kl_recovery_cleanup(struct ath6kl *ar) | ||
117 | { | ||
118 | if (!ar->fw_recovery.enable) | ||
119 | return; | ||
120 | |||
121 | set_bit(RECOVERY_CLEANUP, &ar->flag); | ||
122 | |||
123 | del_timer_sync(&ar->fw_recovery.hb_timer); | ||
124 | cancel_work_sync(&ar->fw_recovery.recovery_work); | ||
125 | } | ||
126 | |||
127 | void ath6kl_recovery_suspend(struct ath6kl *ar) | ||
128 | { | ||
129 | if (!ar->fw_recovery.enable) | ||
130 | return; | ||
131 | |||
132 | ath6kl_recovery_cleanup(ar); | ||
133 | |||
134 | if (!ar->fw_recovery.err_reason) | ||
135 | return; | ||
136 | |||
137 | /* Process pending fw error detection */ | ||
138 | ar->fw_recovery.err_reason = 0; | ||
139 | WARN_ON(ar->state != ATH6KL_STATE_ON); | ||
140 | ar->state = ATH6KL_STATE_RECOVERY; | ||
141 | ath6kl_init_hw_restart(ar); | ||
142 | ar->state = ATH6KL_STATE_ON; | ||
143 | } | ||
144 | |||
145 | void ath6kl_recovery_resume(struct ath6kl *ar) | ||
146 | { | ||
147 | if (!ar->fw_recovery.enable) | ||
148 | return; | ||
149 | |||
150 | clear_bit(RECOVERY_CLEANUP, &ar->flag); | ||
151 | |||
152 | if (!ar->fw_recovery.hb_poll) | ||
153 | return; | ||
154 | |||
155 | ar->fw_recovery.hb_pending = false; | ||
156 | ar->fw_recovery.seq_num = 0; | ||
157 | ar->fw_recovery.hb_misscnt = 0; | ||
158 | mod_timer(&ar->fw_recovery.hb_timer, | ||
159 | jiffies + msecs_to_jiffies(ar->fw_recovery.hb_poll)); | ||
160 | } | ||
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index 05b95405f7b5..d111980d44c0 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c | |||
@@ -709,7 +709,7 @@ static int ath6kl_sdio_enable_scatter(struct ath6kl *ar) | |||
709 | { | 709 | { |
710 | struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); | 710 | struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); |
711 | struct htc_target *target = ar->htc_target; | 711 | struct htc_target *target = ar->htc_target; |
712 | int ret; | 712 | int ret = 0; |
713 | bool virt_scat = false; | 713 | bool virt_scat = false; |
714 | 714 | ||
715 | if (ar_sdio->scatter_enabled) | 715 | if (ar_sdio->scatter_enabled) |
@@ -844,22 +844,6 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) | |||
844 | bool try_deepsleep = false; | 844 | bool try_deepsleep = false; |
845 | int ret; | 845 | int ret; |
846 | 846 | ||
847 | if (ar->state == ATH6KL_STATE_SCHED_SCAN) { | ||
848 | ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sched scan is in progress\n"); | ||
849 | |||
850 | ret = ath6kl_set_sdio_pm_caps(ar); | ||
851 | if (ret) | ||
852 | goto cut_pwr; | ||
853 | |||
854 | ret = ath6kl_cfg80211_suspend(ar, | ||
855 | ATH6KL_CFG_SUSPEND_SCHED_SCAN, | ||
856 | NULL); | ||
857 | if (ret) | ||
858 | goto cut_pwr; | ||
859 | |||
860 | return 0; | ||
861 | } | ||
862 | |||
863 | if (ar->suspend_mode == WLAN_POWER_STATE_WOW || | 847 | if (ar->suspend_mode == WLAN_POWER_STATE_WOW || |
864 | (!ar->suspend_mode && wow)) { | 848 | (!ar->suspend_mode && wow)) { |
865 | 849 | ||
@@ -942,14 +926,14 @@ static int ath6kl_sdio_resume(struct ath6kl *ar) | |||
942 | case ATH6KL_STATE_WOW: | 926 | case ATH6KL_STATE_WOW: |
943 | break; | 927 | break; |
944 | 928 | ||
945 | case ATH6KL_STATE_SCHED_SCAN: | ||
946 | break; | ||
947 | |||
948 | case ATH6KL_STATE_SUSPENDING: | 929 | case ATH6KL_STATE_SUSPENDING: |
949 | break; | 930 | break; |
950 | 931 | ||
951 | case ATH6KL_STATE_RESUMING: | 932 | case ATH6KL_STATE_RESUMING: |
952 | break; | 933 | break; |
934 | |||
935 | case ATH6KL_STATE_RECOVERY: | ||
936 | break; | ||
953 | } | 937 | } |
954 | 938 | ||
955 | ath6kl_cfg80211_resume(ar); | 939 | ath6kl_cfg80211_resume(ar); |
@@ -1462,3 +1446,6 @@ MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE); | |||
1462 | MODULE_FIRMWARE(AR6004_HW_1_2_FW_DIR "/" AR6004_HW_1_2_FIRMWARE_FILE); | 1446 | MODULE_FIRMWARE(AR6004_HW_1_2_FW_DIR "/" AR6004_HW_1_2_FIRMWARE_FILE); |
1463 | MODULE_FIRMWARE(AR6004_HW_1_2_BOARD_DATA_FILE); | 1447 | MODULE_FIRMWARE(AR6004_HW_1_2_BOARD_DATA_FILE); |
1464 | MODULE_FIRMWARE(AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE); | 1448 | MODULE_FIRMWARE(AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE); |
1449 | MODULE_FIRMWARE(AR6004_HW_1_3_FW_DIR "/" AR6004_HW_1_3_FIRMWARE_FILE); | ||
1450 | MODULE_FIRMWARE(AR6004_HW_1_3_BOARD_DATA_FILE); | ||
1451 | MODULE_FIRMWARE(AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE); | ||
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index 7dfa0fd86d7b..78b369286579 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c | |||
@@ -288,8 +288,16 @@ int ath6kl_control_tx(void *devt, struct sk_buff *skb, | |||
288 | int status = 0; | 288 | int status = 0; |
289 | struct ath6kl_cookie *cookie = NULL; | 289 | struct ath6kl_cookie *cookie = NULL; |
290 | 290 | ||
291 | if (WARN_ON_ONCE(ar->state == ATH6KL_STATE_WOW)) | 291 | if (WARN_ON_ONCE(ar->state == ATH6KL_STATE_WOW)) { |
292 | dev_kfree_skb(skb); | ||
292 | return -EACCES; | 293 | return -EACCES; |
294 | } | ||
295 | |||
296 | if (WARN_ON_ONCE(eid == ENDPOINT_UNUSED || | ||
297 | eid >= ENDPOINT_MAX)) { | ||
298 | status = -EINVAL; | ||
299 | goto fail_ctrl_tx; | ||
300 | } | ||
293 | 301 | ||
294 | spin_lock_bh(&ar->lock); | 302 | spin_lock_bh(&ar->lock); |
295 | 303 | ||
@@ -591,6 +599,7 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target, | |||
591 | */ | 599 | */ |
592 | set_bit(WMI_CTRL_EP_FULL, &ar->flag); | 600 | set_bit(WMI_CTRL_EP_FULL, &ar->flag); |
593 | ath6kl_err("wmi ctrl ep is full\n"); | 601 | ath6kl_err("wmi ctrl ep is full\n"); |
602 | ath6kl_recovery_err_notify(ar, ATH6KL_FW_EP_FULL); | ||
594 | return action; | 603 | return action; |
595 | } | 604 | } |
596 | 605 | ||
@@ -695,22 +704,31 @@ void ath6kl_tx_complete(struct htc_target *target, | |||
695 | list); | 704 | list); |
696 | list_del(&packet->list); | 705 | list_del(&packet->list); |
697 | 706 | ||
707 | if (WARN_ON_ONCE(packet->endpoint == ENDPOINT_UNUSED || | ||
708 | packet->endpoint >= ENDPOINT_MAX)) | ||
709 | continue; | ||
710 | |||
698 | ath6kl_cookie = (struct ath6kl_cookie *)packet->pkt_cntxt; | 711 | ath6kl_cookie = (struct ath6kl_cookie *)packet->pkt_cntxt; |
699 | if (!ath6kl_cookie) | 712 | if (WARN_ON_ONCE(!ath6kl_cookie)) |
700 | goto fatal; | 713 | continue; |
701 | 714 | ||
702 | status = packet->status; | 715 | status = packet->status; |
703 | skb = ath6kl_cookie->skb; | 716 | skb = ath6kl_cookie->skb; |
704 | eid = packet->endpoint; | 717 | eid = packet->endpoint; |
705 | map_no = ath6kl_cookie->map_no; | 718 | map_no = ath6kl_cookie->map_no; |
706 | 719 | ||
707 | if (!skb || !skb->data) | 720 | if (WARN_ON_ONCE(!skb || !skb->data)) { |
708 | goto fatal; | 721 | dev_kfree_skb(skb); |
722 | ath6kl_free_cookie(ar, ath6kl_cookie); | ||
723 | continue; | ||
724 | } | ||
709 | 725 | ||
710 | __skb_queue_tail(&skb_queue, skb); | 726 | __skb_queue_tail(&skb_queue, skb); |
711 | 727 | ||
712 | if (!status && (packet->act_len != skb->len)) | 728 | if (WARN_ON_ONCE(!status && (packet->act_len != skb->len))) { |
713 | goto fatal; | 729 | ath6kl_free_cookie(ar, ath6kl_cookie); |
730 | continue; | ||
731 | } | ||
714 | 732 | ||
715 | ar->tx_pending[eid]--; | 733 | ar->tx_pending[eid]--; |
716 | 734 | ||
@@ -792,11 +810,6 @@ void ath6kl_tx_complete(struct htc_target *target, | |||
792 | wake_up(&ar->event_wq); | 810 | wake_up(&ar->event_wq); |
793 | 811 | ||
794 | return; | 812 | return; |
795 | |||
796 | fatal: | ||
797 | WARN_ON(1); | ||
798 | spin_unlock_bh(&ar->lock); | ||
799 | return; | ||
800 | } | 813 | } |
801 | 814 | ||
802 | void ath6kl_tx_data_cleanup(struct ath6kl *ar) | 815 | void ath6kl_tx_data_cleanup(struct ath6kl *ar) |
@@ -885,8 +898,11 @@ void ath6kl_rx_refill(struct htc_target *target, enum htc_endpoint_id endpoint) | |||
885 | break; | 898 | break; |
886 | 899 | ||
887 | packet = (struct htc_packet *) skb->head; | 900 | packet = (struct htc_packet *) skb->head; |
888 | if (!IS_ALIGNED((unsigned long) skb->data, 4)) | 901 | if (!IS_ALIGNED((unsigned long) skb->data, 4)) { |
902 | size_t len = skb_headlen(skb); | ||
889 | skb->data = PTR_ALIGN(skb->data - 4, 4); | 903 | skb->data = PTR_ALIGN(skb->data - 4, 4); |
904 | skb_set_tail_pointer(skb, len); | ||
905 | } | ||
890 | set_htc_rxpkt_info(packet, skb, skb->data, | 906 | set_htc_rxpkt_info(packet, skb, skb->data, |
891 | ATH6KL_BUFFER_SIZE, endpoint); | 907 | ATH6KL_BUFFER_SIZE, endpoint); |
892 | packet->skb = skb; | 908 | packet->skb = skb; |
@@ -908,8 +924,11 @@ void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count) | |||
908 | return; | 924 | return; |
909 | 925 | ||
910 | packet = (struct htc_packet *) skb->head; | 926 | packet = (struct htc_packet *) skb->head; |
911 | if (!IS_ALIGNED((unsigned long) skb->data, 4)) | 927 | if (!IS_ALIGNED((unsigned long) skb->data, 4)) { |
928 | size_t len = skb_headlen(skb); | ||
912 | skb->data = PTR_ALIGN(skb->data - 4, 4); | 929 | skb->data = PTR_ALIGN(skb->data - 4, 4); |
930 | skb_set_tail_pointer(skb, len); | ||
931 | } | ||
913 | set_htc_rxpkt_info(packet, skb, skb->data, | 932 | set_htc_rxpkt_info(packet, skb, skb->data, |
914 | ATH6KL_AMSDU_BUFFER_SIZE, 0); | 933 | ATH6KL_AMSDU_BUFFER_SIZE, 0); |
915 | packet->skb = skb; | 934 | packet->skb = skb; |
diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c index 3740c3d6ab88..62bcc0d5bc23 100644 --- a/drivers/net/wireless/ath/ath6kl/usb.c +++ b/drivers/net/wireless/ath/ath6kl/usb.c | |||
@@ -185,9 +185,10 @@ static int ath6kl_usb_alloc_pipe_resources(struct ath6kl_usb_pipe *pipe, | |||
185 | for (i = 0; i < urb_cnt; i++) { | 185 | for (i = 0; i < urb_cnt; i++) { |
186 | urb_context = kzalloc(sizeof(struct ath6kl_urb_context), | 186 | urb_context = kzalloc(sizeof(struct ath6kl_urb_context), |
187 | GFP_KERNEL); | 187 | GFP_KERNEL); |
188 | if (urb_context == NULL) | 188 | if (urb_context == NULL) { |
189 | /* FIXME: set status to -ENOMEM */ | 189 | status = -ENOMEM; |
190 | break; | 190 | goto fail_alloc_pipe_resources; |
191 | } | ||
191 | 192 | ||
192 | urb_context->pipe = pipe; | 193 | urb_context->pipe = pipe; |
193 | 194 | ||
@@ -204,6 +205,7 @@ static int ath6kl_usb_alloc_pipe_resources(struct ath6kl_usb_pipe *pipe, | |||
204 | pipe->logical_pipe_num, pipe->usb_pipe_handle, | 205 | pipe->logical_pipe_num, pipe->usb_pipe_handle, |
205 | pipe->urb_alloc); | 206 | pipe->urb_alloc); |
206 | 207 | ||
208 | fail_alloc_pipe_resources: | ||
207 | return status; | 209 | return status; |
208 | } | 210 | } |
209 | 211 | ||
@@ -803,7 +805,11 @@ static int ath6kl_usb_map_service_pipe(struct ath6kl *ar, u16 svc_id, | |||
803 | *dl_pipe = ATH6KL_USB_PIPE_RX_DATA; | 805 | *dl_pipe = ATH6KL_USB_PIPE_RX_DATA; |
804 | break; | 806 | break; |
805 | case WMI_DATA_VI_SVC: | 807 | case WMI_DATA_VI_SVC: |
806 | *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_MP; | 808 | |
809 | if (ar->hw.flags & ATH6KL_HW_MAP_LP_ENDPOINT) | ||
810 | *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_LP; | ||
811 | else | ||
812 | *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_MP; | ||
807 | /* | 813 | /* |
808 | * Disable rxdata2 directly, it will be enabled | 814 | * Disable rxdata2 directly, it will be enabled |
809 | * if FW enable rxdata2 | 815 | * if FW enable rxdata2 |
@@ -811,7 +817,11 @@ static int ath6kl_usb_map_service_pipe(struct ath6kl *ar, u16 svc_id, | |||
811 | *dl_pipe = ATH6KL_USB_PIPE_RX_DATA; | 817 | *dl_pipe = ATH6KL_USB_PIPE_RX_DATA; |
812 | break; | 818 | break; |
813 | case WMI_DATA_VO_SVC: | 819 | case WMI_DATA_VO_SVC: |
814 | *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_HP; | 820 | |
821 | if (ar->hw.flags & ATH6KL_HW_MAP_LP_ENDPOINT) | ||
822 | *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_LP; | ||
823 | else | ||
824 | *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_MP; | ||
815 | /* | 825 | /* |
816 | * Disable rxdata2 directly, it will be enabled | 826 | * Disable rxdata2 directly, it will be enabled |
817 | * if FW enable rxdata2 | 827 | * if FW enable rxdata2 |
@@ -1196,7 +1206,14 @@ static struct usb_driver ath6kl_usb_driver = { | |||
1196 | 1206 | ||
1197 | static int ath6kl_usb_init(void) | 1207 | static int ath6kl_usb_init(void) |
1198 | { | 1208 | { |
1199 | usb_register(&ath6kl_usb_driver); | 1209 | int ret; |
1210 | |||
1211 | ret = usb_register(&ath6kl_usb_driver); | ||
1212 | if (ret) { | ||
1213 | ath6kl_err("usb registration failed: %d\n", ret); | ||
1214 | return ret; | ||
1215 | } | ||
1216 | |||
1200 | return 0; | 1217 | return 0; |
1201 | } | 1218 | } |
1202 | 1219 | ||
@@ -1220,3 +1237,6 @@ MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE); | |||
1220 | MODULE_FIRMWARE(AR6004_HW_1_2_FIRMWARE_FILE); | 1237 | MODULE_FIRMWARE(AR6004_HW_1_2_FIRMWARE_FILE); |
1221 | MODULE_FIRMWARE(AR6004_HW_1_2_BOARD_DATA_FILE); | 1238 | MODULE_FIRMWARE(AR6004_HW_1_2_BOARD_DATA_FILE); |
1222 | MODULE_FIRMWARE(AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE); | 1239 | MODULE_FIRMWARE(AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE); |
1240 | MODULE_FIRMWARE(AR6004_HW_1_3_FW_DIR "/" AR6004_HW_1_3_FIRMWARE_FILE); | ||
1241 | MODULE_FIRMWARE(AR6004_HW_1_3_BOARD_DATA_FILE); | ||
1242 | MODULE_FIRMWARE(AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE); | ||
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index c30ab4b11d61..998f8b0f62fd 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c | |||
@@ -474,7 +474,7 @@ static int ath6kl_wmi_remain_on_chnl_event_rx(struct wmi *wmi, u8 *datap, | |||
474 | return -EINVAL; | 474 | return -EINVAL; |
475 | } | 475 | } |
476 | id = vif->last_roc_id; | 476 | id = vif->last_roc_id; |
477 | cfg80211_ready_on_channel(&vif->wdev, id, chan, NL80211_CHAN_NO_HT, | 477 | cfg80211_ready_on_channel(&vif->wdev, id, chan, |
478 | dur, GFP_ATOMIC); | 478 | dur, GFP_ATOMIC); |
479 | 479 | ||
480 | return 0; | 480 | return 0; |
@@ -513,8 +513,7 @@ static int ath6kl_wmi_cancel_remain_on_chnl_event_rx(struct wmi *wmi, | |||
513 | else | 513 | else |
514 | id = vif->last_roc_id; /* timeout on uncanceled r-o-c */ | 514 | id = vif->last_roc_id; /* timeout on uncanceled r-o-c */ |
515 | vif->last_cancel_roc_id = 0; | 515 | vif->last_cancel_roc_id = 0; |
516 | cfg80211_remain_on_channel_expired(&vif->wdev, id, chan, | 516 | cfg80211_remain_on_channel_expired(&vif->wdev, id, chan, GFP_ATOMIC); |
517 | NL80211_CHAN_NO_HT, GFP_ATOMIC); | ||
518 | 517 | ||
519 | return 0; | 518 | return 0; |
520 | } | 519 | } |
@@ -936,8 +935,12 @@ static void ath6kl_wmi_regdomain_event(struct wmi *wmi, u8 *datap, int len) | |||
936 | 935 | ||
937 | regpair = ath6kl_get_regpair((u16) reg_code); | 936 | regpair = ath6kl_get_regpair((u16) reg_code); |
938 | country = ath6kl_regd_find_country_by_rd((u16) reg_code); | 937 | country = ath6kl_regd_find_country_by_rd((u16) reg_code); |
939 | ath6kl_dbg(ATH6KL_DBG_WMI, "Regpair used: 0x%0x\n", | 938 | if (regpair) |
940 | regpair->regDmnEnum); | 939 | ath6kl_dbg(ATH6KL_DBG_WMI, "Regpair used: 0x%0x\n", |
940 | regpair->regDmnEnum); | ||
941 | else | ||
942 | ath6kl_warn("Regpair not found reg_code 0x%0x\n", | ||
943 | reg_code); | ||
941 | } | 944 | } |
942 | 945 | ||
943 | if (country && wmi->parent_dev->wiphy_registered) { | 946 | if (country && wmi->parent_dev->wiphy_registered) { |
@@ -1116,7 +1119,7 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len, | |||
1116 | * the timer would not ever fire if the scan interval is short | 1119 | * the timer would not ever fire if the scan interval is short |
1117 | * enough. | 1120 | * enough. |
1118 | */ | 1121 | */ |
1119 | if (ar->state == ATH6KL_STATE_SCHED_SCAN && | 1122 | if (test_bit(SCHED_SCANNING, &vif->flags) && |
1120 | !timer_pending(&vif->sched_scan_timer)) { | 1123 | !timer_pending(&vif->sched_scan_timer)) { |
1121 | mod_timer(&vif->sched_scan_timer, jiffies + | 1124 | mod_timer(&vif->sched_scan_timer, jiffies + |
1122 | msecs_to_jiffies(ATH6KL_SCHED_SCAN_RESULT_DELAY)); | 1125 | msecs_to_jiffies(ATH6KL_SCHED_SCAN_RESULT_DELAY)); |
@@ -1170,6 +1173,9 @@ static int ath6kl_wmi_bitrate_reply_rx(struct wmi *wmi, u8 *datap, int len) | |||
1170 | rate = RATE_AUTO; | 1173 | rate = RATE_AUTO; |
1171 | } else { | 1174 | } else { |
1172 | index = reply->rate_index & 0x7f; | 1175 | index = reply->rate_index & 0x7f; |
1176 | if (WARN_ON_ONCE(index > (RATE_MCS_7_40 + 1))) | ||
1177 | return -EINVAL; | ||
1178 | |||
1173 | sgi = (reply->rate_index & 0x80) ? 1 : 0; | 1179 | sgi = (reply->rate_index & 0x80) ? 1 : 0; |
1174 | rate = wmi_rate_tbl[index][sgi]; | 1180 | rate = wmi_rate_tbl[index][sgi]; |
1175 | } | 1181 | } |
@@ -1531,6 +1537,68 @@ static int ath6kl_wmi_cac_event_rx(struct wmi *wmi, u8 *datap, int len, | |||
1531 | return 0; | 1537 | return 0; |
1532 | } | 1538 | } |
1533 | 1539 | ||
1540 | static int ath6kl_wmi_txe_notify_event_rx(struct wmi *wmi, u8 *datap, int len, | ||
1541 | struct ath6kl_vif *vif) | ||
1542 | { | ||
1543 | struct wmi_txe_notify_event *ev; | ||
1544 | u32 rate, pkts; | ||
1545 | |||
1546 | if (len < sizeof(*ev)) | ||
1547 | return -EINVAL; | ||
1548 | |||
1549 | if (vif->sme_state != SME_CONNECTED) | ||
1550 | return -ENOTCONN; | ||
1551 | |||
1552 | ev = (struct wmi_txe_notify_event *) datap; | ||
1553 | rate = le32_to_cpu(ev->rate); | ||
1554 | pkts = le32_to_cpu(ev->pkts); | ||
1555 | |||
1556 | ath6kl_dbg(ATH6KL_DBG_WMI, "TXE notify event: peer %pM rate %d% pkts %d intvl %ds\n", | ||
1557 | vif->bssid, rate, pkts, vif->txe_intvl); | ||
1558 | |||
1559 | cfg80211_cqm_txe_notify(vif->ndev, vif->bssid, pkts, | ||
1560 | rate, vif->txe_intvl, GFP_KERNEL); | ||
1561 | |||
1562 | return 0; | ||
1563 | } | ||
1564 | |||
1565 | int ath6kl_wmi_set_txe_notify(struct wmi *wmi, u8 idx, | ||
1566 | u32 rate, u32 pkts, u32 intvl) | ||
1567 | { | ||
1568 | struct sk_buff *skb; | ||
1569 | struct wmi_txe_notify_cmd *cmd; | ||
1570 | |||
1571 | skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); | ||
1572 | if (!skb) | ||
1573 | return -ENOMEM; | ||
1574 | |||
1575 | cmd = (struct wmi_txe_notify_cmd *) skb->data; | ||
1576 | cmd->rate = cpu_to_le32(rate); | ||
1577 | cmd->pkts = cpu_to_le32(pkts); | ||
1578 | cmd->intvl = cpu_to_le32(intvl); | ||
1579 | |||
1580 | return ath6kl_wmi_cmd_send(wmi, idx, skb, WMI_SET_TXE_NOTIFY_CMDID, | ||
1581 | NO_SYNC_WMIFLAG); | ||
1582 | } | ||
1583 | |||
1584 | int ath6kl_wmi_set_rssi_filter_cmd(struct wmi *wmi, u8 if_idx, s8 rssi) | ||
1585 | { | ||
1586 | struct sk_buff *skb; | ||
1587 | struct wmi_set_rssi_filter_cmd *cmd; | ||
1588 | int ret; | ||
1589 | |||
1590 | skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); | ||
1591 | if (!skb) | ||
1592 | return -ENOMEM; | ||
1593 | |||
1594 | cmd = (struct wmi_set_rssi_filter_cmd *) skb->data; | ||
1595 | cmd->rssi = rssi; | ||
1596 | |||
1597 | ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_RSSI_FILTER_CMDID, | ||
1598 | NO_SYNC_WMIFLAG); | ||
1599 | return ret; | ||
1600 | } | ||
1601 | |||
1534 | static int ath6kl_wmi_send_snr_threshold_params(struct wmi *wmi, | 1602 | static int ath6kl_wmi_send_snr_threshold_params(struct wmi *wmi, |
1535 | struct wmi_snr_threshold_params_cmd *snr_cmd) | 1603 | struct wmi_snr_threshold_params_cmd *snr_cmd) |
1536 | { | 1604 | { |
@@ -1677,8 +1745,11 @@ int ath6kl_wmi_cmd_send(struct wmi *wmi, u8 if_idx, struct sk_buff *skb, | |||
1677 | int ret; | 1745 | int ret; |
1678 | u16 info1; | 1746 | u16 info1; |
1679 | 1747 | ||
1680 | if (WARN_ON(skb == NULL || (if_idx > (wmi->parent_dev->vif_max - 1)))) | 1748 | if (WARN_ON(skb == NULL || |
1749 | (if_idx > (wmi->parent_dev->vif_max - 1)))) { | ||
1750 | dev_kfree_skb(skb); | ||
1681 | return -EINVAL; | 1751 | return -EINVAL; |
1752 | } | ||
1682 | 1753 | ||
1683 | ath6kl_dbg(ATH6KL_DBG_WMI, "wmi tx id %d len %d flag %d\n", | 1754 | ath6kl_dbg(ATH6KL_DBG_WMI, "wmi tx id %d len %d flag %d\n", |
1684 | cmd_id, skb->len, sync_flag); | 1755 | cmd_id, skb->len, sync_flag); |
@@ -1833,6 +1904,59 @@ int ath6kl_wmi_disconnect_cmd(struct wmi *wmi, u8 if_idx) | |||
1833 | return ret; | 1904 | return ret; |
1834 | } | 1905 | } |
1835 | 1906 | ||
1907 | /* ath6kl_wmi_start_scan_cmd is to be deprecated. Use | ||
1908 | * ath6kl_wmi_begin_scan_cmd instead. The new function supports P2P | ||
1909 | * mgmt operations using station interface. | ||
1910 | */ | ||
1911 | static int ath6kl_wmi_startscan_cmd(struct wmi *wmi, u8 if_idx, | ||
1912 | enum wmi_scan_type scan_type, | ||
1913 | u32 force_fgscan, u32 is_legacy, | ||
1914 | u32 home_dwell_time, | ||
1915 | u32 force_scan_interval, | ||
1916 | s8 num_chan, u16 *ch_list) | ||
1917 | { | ||
1918 | struct sk_buff *skb; | ||
1919 | struct wmi_start_scan_cmd *sc; | ||
1920 | s8 size; | ||
1921 | int i, ret; | ||
1922 | |||
1923 | size = sizeof(struct wmi_start_scan_cmd); | ||
1924 | |||
1925 | if ((scan_type != WMI_LONG_SCAN) && (scan_type != WMI_SHORT_SCAN)) | ||
1926 | return -EINVAL; | ||
1927 | |||
1928 | if (num_chan > WMI_MAX_CHANNELS) | ||
1929 | return -EINVAL; | ||
1930 | |||
1931 | if (num_chan) | ||
1932 | size += sizeof(u16) * (num_chan - 1); | ||
1933 | |||
1934 | skb = ath6kl_wmi_get_new_buf(size); | ||
1935 | if (!skb) | ||
1936 | return -ENOMEM; | ||
1937 | |||
1938 | sc = (struct wmi_start_scan_cmd *) skb->data; | ||
1939 | sc->scan_type = scan_type; | ||
1940 | sc->force_fg_scan = cpu_to_le32(force_fgscan); | ||
1941 | sc->is_legacy = cpu_to_le32(is_legacy); | ||
1942 | sc->home_dwell_time = cpu_to_le32(home_dwell_time); | ||
1943 | sc->force_scan_intvl = cpu_to_le32(force_scan_interval); | ||
1944 | sc->num_ch = num_chan; | ||
1945 | |||
1946 | for (i = 0; i < num_chan; i++) | ||
1947 | sc->ch_list[i] = cpu_to_le16(ch_list[i]); | ||
1948 | |||
1949 | ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_START_SCAN_CMDID, | ||
1950 | NO_SYNC_WMIFLAG); | ||
1951 | |||
1952 | return ret; | ||
1953 | } | ||
1954 | |||
1955 | /* | ||
1956 | * beginscan supports (compared to old startscan) P2P mgmt operations using | ||
1957 | * station interface, send additional information like supported rates to | ||
1958 | * advertise and xmit rates for probe requests | ||
1959 | */ | ||
1836 | int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx, | 1960 | int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx, |
1837 | enum wmi_scan_type scan_type, | 1961 | enum wmi_scan_type scan_type, |
1838 | u32 force_fgscan, u32 is_legacy, | 1962 | u32 force_fgscan, u32 is_legacy, |
@@ -1848,6 +1972,15 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx, | |||
1848 | int num_rates; | 1972 | int num_rates; |
1849 | u32 ratemask; | 1973 | u32 ratemask; |
1850 | 1974 | ||
1975 | if (!test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX, | ||
1976 | ar->fw_capabilities)) { | ||
1977 | return ath6kl_wmi_startscan_cmd(wmi, if_idx, | ||
1978 | scan_type, force_fgscan, | ||
1979 | is_legacy, home_dwell_time, | ||
1980 | force_scan_interval, | ||
1981 | num_chan, ch_list); | ||
1982 | } | ||
1983 | |||
1851 | size = sizeof(struct wmi_begin_scan_cmd); | 1984 | size = sizeof(struct wmi_begin_scan_cmd); |
1852 | 1985 | ||
1853 | if ((scan_type != WMI_LONG_SCAN) && (scan_type != WMI_SHORT_SCAN)) | 1986 | if ((scan_type != WMI_LONG_SCAN) && (scan_type != WMI_SHORT_SCAN)) |
@@ -1900,50 +2033,24 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx, | |||
1900 | return ret; | 2033 | return ret; |
1901 | } | 2034 | } |
1902 | 2035 | ||
1903 | /* ath6kl_wmi_start_scan_cmd is to be deprecated. Use | 2036 | int ath6kl_wmi_enable_sched_scan_cmd(struct wmi *wmi, u8 if_idx, bool enable) |
1904 | * ath6kl_wmi_begin_scan_cmd instead. The new function supports P2P | ||
1905 | * mgmt operations using station interface. | ||
1906 | */ | ||
1907 | int ath6kl_wmi_startscan_cmd(struct wmi *wmi, u8 if_idx, | ||
1908 | enum wmi_scan_type scan_type, | ||
1909 | u32 force_fgscan, u32 is_legacy, | ||
1910 | u32 home_dwell_time, u32 force_scan_interval, | ||
1911 | s8 num_chan, u16 *ch_list) | ||
1912 | { | 2037 | { |
1913 | struct sk_buff *skb; | 2038 | struct sk_buff *skb; |
1914 | struct wmi_start_scan_cmd *sc; | 2039 | struct wmi_enable_sched_scan_cmd *sc; |
1915 | s8 size; | 2040 | int ret; |
1916 | int i, ret; | ||
1917 | |||
1918 | size = sizeof(struct wmi_start_scan_cmd); | ||
1919 | |||
1920 | if ((scan_type != WMI_LONG_SCAN) && (scan_type != WMI_SHORT_SCAN)) | ||
1921 | return -EINVAL; | ||
1922 | |||
1923 | if (num_chan > WMI_MAX_CHANNELS) | ||
1924 | return -EINVAL; | ||
1925 | |||
1926 | if (num_chan) | ||
1927 | size += sizeof(u16) * (num_chan - 1); | ||
1928 | 2041 | ||
1929 | skb = ath6kl_wmi_get_new_buf(size); | 2042 | skb = ath6kl_wmi_get_new_buf(sizeof(*sc)); |
1930 | if (!skb) | 2043 | if (!skb) |
1931 | return -ENOMEM; | 2044 | return -ENOMEM; |
1932 | 2045 | ||
1933 | sc = (struct wmi_start_scan_cmd *) skb->data; | 2046 | ath6kl_dbg(ATH6KL_DBG_WMI, "%s scheduled scan on vif %d\n", |
1934 | sc->scan_type = scan_type; | 2047 | enable ? "enabling" : "disabling", if_idx); |
1935 | sc->force_fg_scan = cpu_to_le32(force_fgscan); | 2048 | sc = (struct wmi_enable_sched_scan_cmd *) skb->data; |
1936 | sc->is_legacy = cpu_to_le32(is_legacy); | 2049 | sc->enable = enable ? 1 : 0; |
1937 | sc->home_dwell_time = cpu_to_le32(home_dwell_time); | ||
1938 | sc->force_scan_intvl = cpu_to_le32(force_scan_interval); | ||
1939 | sc->num_ch = num_chan; | ||
1940 | |||
1941 | for (i = 0; i < num_chan; i++) | ||
1942 | sc->ch_list[i] = cpu_to_le16(ch_list[i]); | ||
1943 | 2050 | ||
1944 | ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_START_SCAN_CMDID, | 2051 | ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, |
2052 | WMI_ENABLE_SCHED_SCAN_CMDID, | ||
1945 | NO_SYNC_WMIFLAG); | 2053 | NO_SYNC_WMIFLAG); |
1946 | |||
1947 | return ret; | 2054 | return ret; |
1948 | } | 2055 | } |
1949 | 2056 | ||
@@ -2275,8 +2382,10 @@ static int ath6kl_wmi_data_sync_send(struct wmi *wmi, struct sk_buff *skb, | |||
2275 | struct wmi_data_hdr *data_hdr; | 2382 | struct wmi_data_hdr *data_hdr; |
2276 | int ret; | 2383 | int ret; |
2277 | 2384 | ||
2278 | if (WARN_ON(skb == NULL || ep_id == wmi->ep_id)) | 2385 | if (WARN_ON(skb == NULL || ep_id == wmi->ep_id)) { |
2386 | dev_kfree_skb(skb); | ||
2279 | return -EINVAL; | 2387 | return -EINVAL; |
2388 | } | ||
2280 | 2389 | ||
2281 | skb_push(skb, sizeof(struct wmi_data_hdr)); | 2390 | skb_push(skb, sizeof(struct wmi_data_hdr)); |
2282 | 2391 | ||
@@ -2313,10 +2422,8 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx) | |||
2313 | spin_unlock_bh(&wmi->lock); | 2422 | spin_unlock_bh(&wmi->lock); |
2314 | 2423 | ||
2315 | skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); | 2424 | skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); |
2316 | if (!skb) { | 2425 | if (!skb) |
2317 | ret = -ENOMEM; | 2426 | return -ENOMEM; |
2318 | goto free_skb; | ||
2319 | } | ||
2320 | 2427 | ||
2321 | cmd = (struct wmi_sync_cmd *) skb->data; | 2428 | cmd = (struct wmi_sync_cmd *) skb->data; |
2322 | 2429 | ||
@@ -2339,7 +2446,7 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx) | |||
2339 | * then do not send the Synchronize cmd on the control ep | 2446 | * then do not send the Synchronize cmd on the control ep |
2340 | */ | 2447 | */ |
2341 | if (ret) | 2448 | if (ret) |
2342 | goto free_skb; | 2449 | goto free_cmd_skb; |
2343 | 2450 | ||
2344 | /* | 2451 | /* |
2345 | * Send sync cmd followed by sync data messages on all | 2452 | * Send sync cmd followed by sync data messages on all |
@@ -2349,15 +2456,12 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx) | |||
2349 | NO_SYNC_WMIFLAG); | 2456 | NO_SYNC_WMIFLAG); |
2350 | 2457 | ||
2351 | if (ret) | 2458 | if (ret) |
2352 | goto free_skb; | 2459 | goto free_data_skb; |
2353 | |||
2354 | /* cmd buffer sent, we no longer own it */ | ||
2355 | skb = NULL; | ||
2356 | 2460 | ||
2357 | for (index = 0; index < num_pri_streams; index++) { | 2461 | for (index = 0; index < num_pri_streams; index++) { |
2358 | 2462 | ||
2359 | if (WARN_ON(!data_sync_bufs[index].skb)) | 2463 | if (WARN_ON(!data_sync_bufs[index].skb)) |
2360 | break; | 2464 | goto free_data_skb; |
2361 | 2465 | ||
2362 | ep_id = ath6kl_ac2_endpoint_id(wmi->parent_dev, | 2466 | ep_id = ath6kl_ac2_endpoint_id(wmi->parent_dev, |
2363 | data_sync_bufs[index]. | 2467 | data_sync_bufs[index]. |
@@ -2366,17 +2470,20 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx) | |||
2366 | ath6kl_wmi_data_sync_send(wmi, data_sync_bufs[index].skb, | 2470 | ath6kl_wmi_data_sync_send(wmi, data_sync_bufs[index].skb, |
2367 | ep_id, if_idx); | 2471 | ep_id, if_idx); |
2368 | 2472 | ||
2369 | if (ret) | ||
2370 | break; | ||
2371 | |||
2372 | data_sync_bufs[index].skb = NULL; | 2473 | data_sync_bufs[index].skb = NULL; |
2474 | |||
2475 | if (ret) | ||
2476 | goto free_data_skb; | ||
2373 | } | 2477 | } |
2374 | 2478 | ||
2375 | free_skb: | 2479 | return 0; |
2480 | |||
2481 | free_cmd_skb: | ||
2376 | /* free up any resources left over (possibly due to an error) */ | 2482 | /* free up any resources left over (possibly due to an error) */ |
2377 | if (skb) | 2483 | if (skb) |
2378 | dev_kfree_skb(skb); | 2484 | dev_kfree_skb(skb); |
2379 | 2485 | ||
2486 | free_data_skb: | ||
2380 | for (index = 0; index < num_pri_streams; index++) { | 2487 | for (index = 0; index < num_pri_streams; index++) { |
2381 | if (data_sync_bufs[index].skb != NULL) { | 2488 | if (data_sync_bufs[index].skb != NULL) { |
2382 | dev_kfree_skb((struct sk_buff *)data_sync_bufs[index]. | 2489 | dev_kfree_skb((struct sk_buff *)data_sync_bufs[index]. |
@@ -2618,11 +2725,13 @@ static int ath6kl_set_bitrate_mask64(struct wmi *wmi, u8 if_idx, | |||
2618 | { | 2725 | { |
2619 | struct sk_buff *skb; | 2726 | struct sk_buff *skb; |
2620 | int ret, mode, band; | 2727 | int ret, mode, band; |
2621 | u64 mcsrate, ratemask[IEEE80211_NUM_BANDS]; | 2728 | u64 mcsrate, ratemask[ATH6KL_NUM_BANDS]; |
2622 | struct wmi_set_tx_select_rates64_cmd *cmd; | 2729 | struct wmi_set_tx_select_rates64_cmd *cmd; |
2623 | 2730 | ||
2624 | memset(&ratemask, 0, sizeof(ratemask)); | 2731 | memset(&ratemask, 0, sizeof(ratemask)); |
2625 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 2732 | |
2733 | /* only check 2.4 and 5 GHz bands, skip the rest */ | ||
2734 | for (band = 0; band <= IEEE80211_BAND_5GHZ; band++) { | ||
2626 | /* copy legacy rate mask */ | 2735 | /* copy legacy rate mask */ |
2627 | ratemask[band] = mask->control[band].legacy; | 2736 | ratemask[band] = mask->control[band].legacy; |
2628 | if (band == IEEE80211_BAND_5GHZ) | 2737 | if (band == IEEE80211_BAND_5GHZ) |
@@ -2668,11 +2777,13 @@ static int ath6kl_set_bitrate_mask32(struct wmi *wmi, u8 if_idx, | |||
2668 | { | 2777 | { |
2669 | struct sk_buff *skb; | 2778 | struct sk_buff *skb; |
2670 | int ret, mode, band; | 2779 | int ret, mode, band; |
2671 | u32 mcsrate, ratemask[IEEE80211_NUM_BANDS]; | 2780 | u32 mcsrate, ratemask[ATH6KL_NUM_BANDS]; |
2672 | struct wmi_set_tx_select_rates32_cmd *cmd; | 2781 | struct wmi_set_tx_select_rates32_cmd *cmd; |
2673 | 2782 | ||
2674 | memset(&ratemask, 0, sizeof(ratemask)); | 2783 | memset(&ratemask, 0, sizeof(ratemask)); |
2675 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 2784 | |
2785 | /* only check 2.4 and 5 GHz bands, skip the rest */ | ||
2786 | for (band = 0; band <= IEEE80211_BAND_5GHZ; band++) { | ||
2676 | /* copy legacy rate mask */ | 2787 | /* copy legacy rate mask */ |
2677 | ratemask[band] = mask->control[band].legacy; | 2788 | ratemask[band] = mask->control[band].legacy; |
2678 | if (band == IEEE80211_BAND_5GHZ) | 2789 | if (band == IEEE80211_BAND_5GHZ) |
@@ -2716,7 +2827,7 @@ int ath6kl_wmi_set_bitrate_mask(struct wmi *wmi, u8 if_idx, | |||
2716 | { | 2827 | { |
2717 | struct ath6kl *ar = wmi->parent_dev; | 2828 | struct ath6kl *ar = wmi->parent_dev; |
2718 | 2829 | ||
2719 | if (ar->hw.flags & ATH6KL_HW_FLAG_64BIT_RATES) | 2830 | if (ar->hw.flags & ATH6KL_HW_64BIT_RATES) |
2720 | return ath6kl_set_bitrate_mask64(wmi, if_idx, mask); | 2831 | return ath6kl_set_bitrate_mask64(wmi, if_idx, mask); |
2721 | else | 2832 | else |
2722 | return ath6kl_set_bitrate_mask32(wmi, if_idx, mask); | 2833 | return ath6kl_set_bitrate_mask32(wmi, if_idx, mask); |
@@ -3139,12 +3250,40 @@ int ath6kl_wmi_sta_bmiss_enhance_cmd(struct wmi *wmi, u8 if_idx, bool enhance) | |||
3139 | return ret; | 3250 | return ret; |
3140 | } | 3251 | } |
3141 | 3252 | ||
3253 | int ath6kl_wmi_set_regdomain_cmd(struct wmi *wmi, const char *alpha2) | ||
3254 | { | ||
3255 | struct sk_buff *skb; | ||
3256 | struct wmi_set_regdomain_cmd *cmd; | ||
3257 | |||
3258 | skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); | ||
3259 | if (!skb) | ||
3260 | return -ENOMEM; | ||
3261 | |||
3262 | cmd = (struct wmi_set_regdomain_cmd *) skb->data; | ||
3263 | memcpy(cmd->iso_name, alpha2, 2); | ||
3264 | |||
3265 | return ath6kl_wmi_cmd_send(wmi, 0, skb, | ||
3266 | WMI_SET_REGDOMAIN_CMDID, | ||
3267 | NO_SYNC_WMIFLAG); | ||
3268 | } | ||
3269 | |||
3142 | s32 ath6kl_wmi_get_rate(s8 rate_index) | 3270 | s32 ath6kl_wmi_get_rate(s8 rate_index) |
3143 | { | 3271 | { |
3272 | u8 sgi = 0; | ||
3273 | |||
3144 | if (rate_index == RATE_AUTO) | 3274 | if (rate_index == RATE_AUTO) |
3145 | return 0; | 3275 | return 0; |
3146 | 3276 | ||
3147 | return wmi_rate_tbl[(u32) rate_index][0]; | 3277 | /* SGI is stored as the MSB of the rate_index */ |
3278 | if (rate_index & RATE_INDEX_MSB) { | ||
3279 | rate_index &= RATE_INDEX_WITHOUT_SGI_MASK; | ||
3280 | sgi = 1; | ||
3281 | } | ||
3282 | |||
3283 | if (WARN_ON(rate_index > RATE_MCS_7_40)) | ||
3284 | rate_index = RATE_MCS_7_40; | ||
3285 | |||
3286 | return wmi_rate_tbl[(u32) rate_index][sgi]; | ||
3148 | } | 3287 | } |
3149 | 3288 | ||
3150 | static int ath6kl_wmi_get_pmkid_list_event_rx(struct wmi *wmi, u8 *datap, | 3289 | static int ath6kl_wmi_get_pmkid_list_event_rx(struct wmi *wmi, u8 *datap, |
@@ -3634,6 +3773,19 @@ int ath6kl_wmi_set_inact_period(struct wmi *wmi, u8 if_idx, int inact_timeout) | |||
3634 | NO_SYNC_WMIFLAG); | 3773 | NO_SYNC_WMIFLAG); |
3635 | } | 3774 | } |
3636 | 3775 | ||
3776 | static void ath6kl_wmi_hb_challenge_resp_event(struct wmi *wmi, u8 *datap, | ||
3777 | int len) | ||
3778 | { | ||
3779 | struct wmix_hb_challenge_resp_cmd *cmd; | ||
3780 | |||
3781 | if (len < sizeof(struct wmix_hb_challenge_resp_cmd)) | ||
3782 | return; | ||
3783 | |||
3784 | cmd = (struct wmix_hb_challenge_resp_cmd *) datap; | ||
3785 | ath6kl_recovery_hb_event(wmi->parent_dev, | ||
3786 | le32_to_cpu(cmd->cookie)); | ||
3787 | } | ||
3788 | |||
3637 | static int ath6kl_wmi_control_rx_xtnd(struct wmi *wmi, struct sk_buff *skb) | 3789 | static int ath6kl_wmi_control_rx_xtnd(struct wmi *wmi, struct sk_buff *skb) |
3638 | { | 3790 | { |
3639 | struct wmix_cmd_hdr *cmd; | 3791 | struct wmix_cmd_hdr *cmd; |
@@ -3658,6 +3810,7 @@ static int ath6kl_wmi_control_rx_xtnd(struct wmi *wmi, struct sk_buff *skb) | |||
3658 | switch (id) { | 3810 | switch (id) { |
3659 | case WMIX_HB_CHALLENGE_RESP_EVENTID: | 3811 | case WMIX_HB_CHALLENGE_RESP_EVENTID: |
3660 | ath6kl_dbg(ATH6KL_DBG_WMI, "wmi event hb challenge resp\n"); | 3812 | ath6kl_dbg(ATH6KL_DBG_WMI, "wmi event hb challenge resp\n"); |
3813 | ath6kl_wmi_hb_challenge_resp_event(wmi, datap, len); | ||
3661 | break; | 3814 | break; |
3662 | case WMIX_DBGLOG_EVENTID: | 3815 | case WMIX_DBGLOG_EVENTID: |
3663 | ath6kl_dbg(ATH6KL_DBG_WMI, "wmi event dbglog len %d\n", len); | 3816 | ath6kl_dbg(ATH6KL_DBG_WMI, "wmi event dbglog len %d\n", len); |
@@ -3750,6 +3903,9 @@ static int ath6kl_wmi_proc_events_vif(struct wmi *wmi, u16 if_idx, u16 cmd_id, | |||
3750 | case WMI_RX_ACTION_EVENTID: | 3903 | case WMI_RX_ACTION_EVENTID: |
3751 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_ACTION_EVENTID\n"); | 3904 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_ACTION_EVENTID\n"); |
3752 | return ath6kl_wmi_rx_action_event_rx(wmi, datap, len, vif); | 3905 | return ath6kl_wmi_rx_action_event_rx(wmi, datap, len, vif); |
3906 | case WMI_TXE_NOTIFY_EVENTID: | ||
3907 | ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TXE_NOTIFY_EVENTID\n"); | ||
3908 | return ath6kl_wmi_txe_notify_event_rx(wmi, datap, len, vif); | ||
3753 | default: | 3909 | default: |
3754 | ath6kl_dbg(ATH6KL_DBG_WMI, "unknown cmd id 0x%x\n", cmd_id); | 3910 | ath6kl_dbg(ATH6KL_DBG_WMI, "unknown cmd id 0x%x\n", cmd_id); |
3755 | return -EINVAL; | 3911 | return -EINVAL; |
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index 43339aca585d..98b1755e67f4 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h | |||
@@ -48,7 +48,7 @@ | |||
48 | 48 | ||
49 | #define A_BAND_24GHZ 0 | 49 | #define A_BAND_24GHZ 0 |
50 | #define A_BAND_5GHZ 1 | 50 | #define A_BAND_5GHZ 1 |
51 | #define A_NUM_BANDS 2 | 51 | #define ATH6KL_NUM_BANDS 2 |
52 | 52 | ||
53 | /* in ms */ | 53 | /* in ms */ |
54 | #define WMI_IMPLICIT_PSTREAM_INACTIVITY_INT 5000 | 54 | #define WMI_IMPLICIT_PSTREAM_INACTIVITY_INT 5000 |
@@ -628,6 +628,20 @@ enum wmi_cmd_id { | |||
628 | WMI_SET_MCASTRATE, | 628 | WMI_SET_MCASTRATE, |
629 | 629 | ||
630 | WMI_STA_BMISS_ENHANCE_CMDID, | 630 | WMI_STA_BMISS_ENHANCE_CMDID, |
631 | |||
632 | WMI_SET_REGDOMAIN_CMDID, | ||
633 | |||
634 | WMI_SET_RSSI_FILTER_CMDID, | ||
635 | |||
636 | WMI_SET_KEEP_ALIVE_EXT, | ||
637 | |||
638 | WMI_VOICE_DETECTION_ENABLE_CMDID, | ||
639 | |||
640 | WMI_SET_TXE_NOTIFY_CMDID, | ||
641 | |||
642 | WMI_SET_RECOVERY_TEST_PARAMETER_CMDID, /*0xf094*/ | ||
643 | |||
644 | WMI_ENABLE_SCHED_SCAN_CMDID, | ||
631 | }; | 645 | }; |
632 | 646 | ||
633 | enum wmi_mgmt_frame_type { | 647 | enum wmi_mgmt_frame_type { |
@@ -843,7 +857,7 @@ struct wmi_begin_scan_cmd { | |||
843 | u8 scan_type; | 857 | u8 scan_type; |
844 | 858 | ||
845 | /* Supported rates to advertise in the probe request frames */ | 859 | /* Supported rates to advertise in the probe request frames */ |
846 | struct wmi_supp_rates supp_rates[IEEE80211_NUM_BANDS]; | 860 | struct wmi_supp_rates supp_rates[ATH6KL_NUM_BANDS]; |
847 | 861 | ||
848 | /* how many channels follow */ | 862 | /* how many channels follow */ |
849 | u8 num_ch; | 863 | u8 num_ch; |
@@ -941,6 +955,11 @@ struct wmi_scan_params_cmd { | |||
941 | __le32 max_dfsch_act_time; | 955 | __le32 max_dfsch_act_time; |
942 | } __packed; | 956 | } __packed; |
943 | 957 | ||
958 | /* WMI_ENABLE_SCHED_SCAN_CMDID */ | ||
959 | struct wmi_enable_sched_scan_cmd { | ||
960 | u8 enable; | ||
961 | } __packed; | ||
962 | |||
944 | /* WMI_SET_BSS_FILTER_CMDID */ | 963 | /* WMI_SET_BSS_FILTER_CMDID */ |
945 | enum wmi_bss_filter { | 964 | enum wmi_bss_filter { |
946 | /* no beacons forwarded */ | 965 | /* no beacons forwarded */ |
@@ -1032,6 +1051,11 @@ struct wmi_sta_bmiss_enhance_cmd { | |||
1032 | u8 enable; | 1051 | u8 enable; |
1033 | } __packed; | 1052 | } __packed; |
1034 | 1053 | ||
1054 | struct wmi_set_regdomain_cmd { | ||
1055 | u8 length; | ||
1056 | u8 iso_name[2]; | ||
1057 | } __packed; | ||
1058 | |||
1035 | /* WMI_SET_POWER_MODE_CMDID */ | 1059 | /* WMI_SET_POWER_MODE_CMDID */ |
1036 | enum wmi_power_mode { | 1060 | enum wmi_power_mode { |
1037 | REC_POWER = 0x01, | 1061 | REC_POWER = 0x01, |
@@ -1276,6 +1300,11 @@ struct wmi_snr_threshold_params_cmd { | |||
1276 | u8 reserved[3]; | 1300 | u8 reserved[3]; |
1277 | } __packed; | 1301 | } __packed; |
1278 | 1302 | ||
1303 | /* Don't report BSSs with signal (RSSI) below this threshold */ | ||
1304 | struct wmi_set_rssi_filter_cmd { | ||
1305 | s8 rssi; | ||
1306 | } __packed; | ||
1307 | |||
1279 | enum wmi_preamble_policy { | 1308 | enum wmi_preamble_policy { |
1280 | WMI_IGNORE_BARKER_IN_ERP = 0, | 1309 | WMI_IGNORE_BARKER_IN_ERP = 0, |
1281 | WMI_FOLLOW_BARKER_IN_ERP, | 1310 | WMI_FOLLOW_BARKER_IN_ERP, |
@@ -1455,6 +1484,20 @@ enum wmi_event_id { | |||
1455 | WMI_P2P_CAPABILITIES_EVENTID, | 1484 | WMI_P2P_CAPABILITIES_EVENTID, |
1456 | WMI_RX_ACTION_EVENTID, | 1485 | WMI_RX_ACTION_EVENTID, |
1457 | WMI_P2P_INFO_EVENTID, | 1486 | WMI_P2P_INFO_EVENTID, |
1487 | |||
1488 | /* WPS Events */ | ||
1489 | WMI_WPS_GET_STATUS_EVENTID, | ||
1490 | WMI_WPS_PROFILE_EVENTID, | ||
1491 | |||
1492 | /* more P2P events */ | ||
1493 | WMI_NOA_INFO_EVENTID, | ||
1494 | WMI_OPPPS_INFO_EVENTID, | ||
1495 | WMI_PORT_STATUS_EVENTID, | ||
1496 | |||
1497 | /* 802.11w */ | ||
1498 | WMI_GET_RSN_CAP_EVENTID, | ||
1499 | |||
1500 | WMI_TXE_NOTIFY_EVENTID, | ||
1458 | }; | 1501 | }; |
1459 | 1502 | ||
1460 | struct wmi_ready_event_2 { | 1503 | struct wmi_ready_event_2 { |
@@ -1749,6 +1792,9 @@ struct rx_stats { | |||
1749 | a_sle32 ucast_rate; | 1792 | a_sle32 ucast_rate; |
1750 | } __packed; | 1793 | } __packed; |
1751 | 1794 | ||
1795 | #define RATE_INDEX_WITHOUT_SGI_MASK 0x7f | ||
1796 | #define RATE_INDEX_MSB 0x80 | ||
1797 | |||
1752 | struct tkip_ccmp_stats { | 1798 | struct tkip_ccmp_stats { |
1753 | __le32 tkip_local_mic_fail; | 1799 | __le32 tkip_local_mic_fail; |
1754 | __le32 tkip_cnter_measures_invoked; | 1800 | __le32 tkip_cnter_measures_invoked; |
@@ -2019,7 +2065,6 @@ struct wmi_set_ie_cmd { | |||
2019 | 2065 | ||
2020 | #define WOW_MAX_FILTERS_PER_LIST 4 | 2066 | #define WOW_MAX_FILTERS_PER_LIST 4 |
2021 | #define WOW_PATTERN_SIZE 64 | 2067 | #define WOW_PATTERN_SIZE 64 |
2022 | #define WOW_MASK_SIZE 64 | ||
2023 | 2068 | ||
2024 | #define MAC_MAX_FILTERS_PER_LIST 4 | 2069 | #define MAC_MAX_FILTERS_PER_LIST 4 |
2025 | 2070 | ||
@@ -2028,7 +2073,7 @@ struct wow_filter { | |||
2028 | u8 wow_filter_id; | 2073 | u8 wow_filter_id; |
2029 | u8 wow_filter_size; | 2074 | u8 wow_filter_size; |
2030 | u8 wow_filter_offset; | 2075 | u8 wow_filter_offset; |
2031 | u8 wow_filter_mask[WOW_MASK_SIZE]; | 2076 | u8 wow_filter_mask[WOW_PATTERN_SIZE]; |
2032 | u8 wow_filter_pattern[WOW_PATTERN_SIZE]; | 2077 | u8 wow_filter_pattern[WOW_PATTERN_SIZE]; |
2033 | } __packed; | 2078 | } __packed; |
2034 | 2079 | ||
@@ -2087,6 +2132,19 @@ struct wmi_del_wow_pattern_cmd { | |||
2087 | __le16 filter_id; | 2132 | __le16 filter_id; |
2088 | } __packed; | 2133 | } __packed; |
2089 | 2134 | ||
2135 | /* WMI_SET_TXE_NOTIFY_CMDID */ | ||
2136 | struct wmi_txe_notify_cmd { | ||
2137 | __le32 rate; | ||
2138 | __le32 pkts; | ||
2139 | __le32 intvl; | ||
2140 | } __packed; | ||
2141 | |||
2142 | /* WMI_TXE_NOTIFY_EVENTID */ | ||
2143 | struct wmi_txe_notify_event { | ||
2144 | __le32 rate; | ||
2145 | __le32 pkts; | ||
2146 | } __packed; | ||
2147 | |||
2090 | /* WMI_SET_AKMP_PARAMS_CMD */ | 2148 | /* WMI_SET_AKMP_PARAMS_CMD */ |
2091 | 2149 | ||
2092 | struct wmi_pmkid { | 2150 | struct wmi_pmkid { |
@@ -2505,11 +2563,6 @@ int ath6kl_wmi_connect_cmd(struct wmi *wmi, u8 if_idx, | |||
2505 | int ath6kl_wmi_reconnect_cmd(struct wmi *wmi, u8 if_idx, u8 *bssid, | 2563 | int ath6kl_wmi_reconnect_cmd(struct wmi *wmi, u8 if_idx, u8 *bssid, |
2506 | u16 channel); | 2564 | u16 channel); |
2507 | int ath6kl_wmi_disconnect_cmd(struct wmi *wmi, u8 if_idx); | 2565 | int ath6kl_wmi_disconnect_cmd(struct wmi *wmi, u8 if_idx); |
2508 | int ath6kl_wmi_startscan_cmd(struct wmi *wmi, u8 if_idx, | ||
2509 | enum wmi_scan_type scan_type, | ||
2510 | u32 force_fgscan, u32 is_legacy, | ||
2511 | u32 home_dwell_time, u32 force_scan_interval, | ||
2512 | s8 num_chan, u16 *ch_list); | ||
2513 | 2566 | ||
2514 | int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx, | 2567 | int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx, |
2515 | enum wmi_scan_type scan_type, | 2568 | enum wmi_scan_type scan_type, |
@@ -2517,6 +2570,7 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx, | |||
2517 | u32 home_dwell_time, u32 force_scan_interval, | 2570 | u32 home_dwell_time, u32 force_scan_interval, |
2518 | s8 num_chan, u16 *ch_list, u32 no_cck, | 2571 | s8 num_chan, u16 *ch_list, u32 no_cck, |
2519 | u32 *rates); | 2572 | u32 *rates); |
2573 | int ath6kl_wmi_enable_sched_scan_cmd(struct wmi *wmi, u8 if_idx, bool enable); | ||
2520 | 2574 | ||
2521 | int ath6kl_wmi_scanparams_cmd(struct wmi *wmi, u8 if_idx, u16 fg_start_sec, | 2575 | int ath6kl_wmi_scanparams_cmd(struct wmi *wmi, u8 if_idx, u16 fg_start_sec, |
2522 | u16 fg_end_sec, u16 bg_sec, | 2576 | u16 fg_end_sec, u16 bg_sec, |
@@ -2592,6 +2646,7 @@ int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, | |||
2592 | const u8 *mask); | 2646 | const u8 *mask); |
2593 | int ath6kl_wmi_del_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, | 2647 | int ath6kl_wmi_del_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, |
2594 | u16 list_id, u16 filter_id); | 2648 | u16 list_id, u16 filter_id); |
2649 | int ath6kl_wmi_set_rssi_filter_cmd(struct wmi *wmi, u8 if_idx, s8 rssi); | ||
2595 | int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi); | 2650 | int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi); |
2596 | int ath6kl_wmi_ap_set_dtim_cmd(struct wmi *wmi, u8 if_idx, u32 dtim_period); | 2651 | int ath6kl_wmi_ap_set_dtim_cmd(struct wmi *wmi, u8 if_idx, u32 dtim_period); |
2597 | int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid); | 2652 | int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid); |
@@ -2600,6 +2655,9 @@ int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on); | |||
2600 | int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, | 2655 | int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, |
2601 | u8 *filter, bool add_filter); | 2656 | u8 *filter, bool add_filter); |
2602 | int ath6kl_wmi_sta_bmiss_enhance_cmd(struct wmi *wmi, u8 if_idx, bool enable); | 2657 | int ath6kl_wmi_sta_bmiss_enhance_cmd(struct wmi *wmi, u8 if_idx, bool enable); |
2658 | int ath6kl_wmi_set_txe_notify(struct wmi *wmi, u8 idx, | ||
2659 | u32 rate, u32 pkts, u32 intvl); | ||
2660 | int ath6kl_wmi_set_regdomain_cmd(struct wmi *wmi, const char *alpha2); | ||
2603 | 2661 | ||
2604 | /* AP mode uAPSD */ | 2662 | /* AP mode uAPSD */ |
2605 | int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable); | 2663 | int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable); |
@@ -2658,6 +2716,8 @@ int ath6kl_wmi_set_inact_period(struct wmi *wmi, u8 if_idx, int inact_timeout); | |||
2658 | 2716 | ||
2659 | void ath6kl_wmi_sscan_timer(unsigned long ptr); | 2717 | void ath6kl_wmi_sscan_timer(unsigned long ptr); |
2660 | 2718 | ||
2719 | int ath6kl_wmi_get_challenge_resp_cmd(struct wmi *wmi, u32 cookie, u32 source); | ||
2720 | |||
2661 | struct ath6kl_vif *ath6kl_get_vif_by_index(struct ath6kl *ar, u8 if_idx); | 2721 | struct ath6kl_vif *ath6kl_get_vif_by_index(struct ath6kl *ar, u8 if_idx); |
2662 | void *ath6kl_wmi_init(struct ath6kl *devt); | 2722 | void *ath6kl_wmi_init(struct ath6kl *devt); |
2663 | void ath6kl_wmi_shutdown(struct wmi *wmi); | 2723 | void ath6kl_wmi_shutdown(struct wmi *wmi); |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 162401f22f8c..8b0d8dcd7625 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c | |||
@@ -891,6 +891,74 @@ static void ar9003_hw_tx_iq_cal_reload(struct ath_hw *ah) | |||
891 | AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1); | 891 | AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1); |
892 | } | 892 | } |
893 | 893 | ||
894 | static void ar9003_hw_manual_peak_cal(struct ath_hw *ah, u8 chain, bool is_2g) | ||
895 | { | ||
896 | int offset[8], total = 0, test; | ||
897 | int agc_out, i; | ||
898 | |||
899 | REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain), | ||
900 | AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE, 0x1); | ||
901 | REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain), | ||
902 | AR_PHY_65NM_RXRF_GAINSTAGES_LNAON_CALDC, 0x0); | ||
903 | if (is_2g) | ||
904 | REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain), | ||
905 | AR_PHY_65NM_RXRF_GAINSTAGES_LNA2G_GAIN_OVR, 0x0); | ||
906 | else | ||
907 | REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain), | ||
908 | AR_PHY_65NM_RXRF_GAINSTAGES_LNA5G_GAIN_OVR, 0x0); | ||
909 | |||
910 | REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain), | ||
911 | AR_PHY_65NM_RXTX2_RXON_OVR, 0x1); | ||
912 | REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain), | ||
913 | AR_PHY_65NM_RXTX2_RXON, 0x0); | ||
914 | |||
915 | REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), | ||
916 | AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE, 0x1); | ||
917 | REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), | ||
918 | AR_PHY_65NM_RXRF_AGC_AGC_ON_OVR, 0x1); | ||
919 | REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), | ||
920 | AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0x1); | ||
921 | if (is_2g) | ||
922 | REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), | ||
923 | AR_PHY_65NM_RXRF_AGC_AGC2G_DBDAC_OVR, 0x0); | ||
924 | else | ||
925 | REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), | ||
926 | AR_PHY_65NM_RXRF_AGC_AGC5G_DBDAC_OVR, 0x0); | ||
927 | |||
928 | for (i = 6; i > 0; i--) { | ||
929 | offset[i] = BIT(i - 1); | ||
930 | test = total + offset[i]; | ||
931 | |||
932 | if (is_2g) | ||
933 | REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), | ||
934 | AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR, | ||
935 | test); | ||
936 | else | ||
937 | REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), | ||
938 | AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR, | ||
939 | test); | ||
940 | udelay(100); | ||
941 | agc_out = REG_READ_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), | ||
942 | AR_PHY_65NM_RXRF_AGC_AGC_OUT); | ||
943 | offset[i] = (agc_out) ? 0 : 1; | ||
944 | total += (offset[i] << (i - 1)); | ||
945 | } | ||
946 | |||
947 | if (is_2g) | ||
948 | REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), | ||
949 | AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR, total); | ||
950 | else | ||
951 | REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), | ||
952 | AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR, total); | ||
953 | |||
954 | REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain), | ||
955 | AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE, 0); | ||
956 | REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain), | ||
957 | AR_PHY_65NM_RXTX2_RXON_OVR, 0); | ||
958 | REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), | ||
959 | AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0); | ||
960 | } | ||
961 | |||
894 | static bool ar9003_hw_init_cal(struct ath_hw *ah, | 962 | static bool ar9003_hw_init_cal(struct ath_hw *ah, |
895 | struct ath9k_channel *chan) | 963 | struct ath9k_channel *chan) |
896 | { | 964 | { |
@@ -989,6 +1057,14 @@ skip_tx_iqcal: | |||
989 | status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, | 1057 | status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, |
990 | AR_PHY_AGC_CONTROL_CAL, | 1058 | AR_PHY_AGC_CONTROL_CAL, |
991 | 0, AH_WAIT_TIMEOUT); | 1059 | 0, AH_WAIT_TIMEOUT); |
1060 | if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { | ||
1061 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { | ||
1062 | if (!(ah->rxchainmask & (1 << i))) | ||
1063 | continue; | ||
1064 | ar9003_hw_manual_peak_cal(ah, i, | ||
1065 | IS_CHAN_2GHZ(chan)); | ||
1066 | } | ||
1067 | } | ||
992 | } | 1068 | } |
993 | 1069 | ||
994 | if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal) | 1070 | if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal) |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 0693cd95b746..74fd3977feeb 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c | |||
@@ -35,12 +35,6 @@ | |||
35 | */ | 35 | */ |
36 | static void ar9003_hw_init_mode_regs(struct ath_hw *ah) | 36 | static void ar9003_hw_init_mode_regs(struct ath_hw *ah) |
37 | { | 37 | { |
38 | #define AR9462_BB_CTX_COEFJ(x) \ | ||
39 | ar9462_##x##_baseband_core_txfir_coeff_japan_2484 | ||
40 | |||
41 | #define AR9462_BBC_TXIFR_COEFFJ \ | ||
42 | ar9462_2p0_baseband_core_txfir_coeff_japan_2484 | ||
43 | |||
44 | if (AR_SREV_9330_11(ah)) { | 38 | if (AR_SREV_9330_11(ah)) { |
45 | /* mac */ | 39 | /* mac */ |
46 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], | 40 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], |
@@ -70,6 +64,10 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) | |||
70 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 64 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
71 | ar9331_modes_lowest_ob_db_tx_gain_1p1); | 65 | ar9331_modes_lowest_ob_db_tx_gain_1p1); |
72 | 66 | ||
67 | /* Japan 2484 Mhz CCK */ | ||
68 | INIT_INI_ARRAY(&ah->iniCckfirJapan2484, | ||
69 | ar9331_1p1_baseband_core_txfir_coeff_japan_2484); | ||
70 | |||
73 | /* additional clock settings */ | 71 | /* additional clock settings */ |
74 | if (ah->is_clk_25mhz) | 72 | if (ah->is_clk_25mhz) |
75 | INIT_INI_ARRAY(&ah->iniAdditional, | 73 | INIT_INI_ARRAY(&ah->iniAdditional, |
@@ -106,6 +104,10 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) | |||
106 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 104 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
107 | ar9331_modes_lowest_ob_db_tx_gain_1p2); | 105 | ar9331_modes_lowest_ob_db_tx_gain_1p2); |
108 | 106 | ||
107 | /* Japan 2484 Mhz CCK */ | ||
108 | INIT_INI_ARRAY(&ah->iniCckfirJapan2484, | ||
109 | ar9331_1p2_baseband_core_txfir_coeff_japan_2484); | ||
110 | |||
109 | /* additional clock settings */ | 111 | /* additional clock settings */ |
110 | if (ah->is_clk_25mhz) | 112 | if (ah->is_clk_25mhz) |
111 | INIT_INI_ARRAY(&ah->iniAdditional, | 113 | INIT_INI_ARRAY(&ah->iniAdditional, |
@@ -180,6 +182,10 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) | |||
180 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 182 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
181 | ar9485_modes_lowest_ob_db_tx_gain_1_1); | 183 | ar9485_modes_lowest_ob_db_tx_gain_1_1); |
182 | 184 | ||
185 | /* Japan 2484 Mhz CCK */ | ||
186 | INIT_INI_ARRAY(&ah->iniCckfirJapan2484, | ||
187 | ar9485_1_1_baseband_core_txfir_coeff_japan_2484); | ||
188 | |||
183 | /* Load PCIE SERDES settings from INI */ | 189 | /* Load PCIE SERDES settings from INI */ |
184 | 190 | ||
185 | /* Awake Setting */ | 191 | /* Awake Setting */ |
@@ -229,9 +235,7 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) | |||
229 | ar9462_modes_fast_clock_2p0); | 235 | ar9462_modes_fast_clock_2p0); |
230 | 236 | ||
231 | INIT_INI_ARRAY(&ah->iniCckfirJapan2484, | 237 | INIT_INI_ARRAY(&ah->iniCckfirJapan2484, |
232 | AR9462_BB_CTX_COEFJ(2p0)); | 238 | ar9462_2p0_baseband_core_txfir_coeff_japan_2484); |
233 | |||
234 | INIT_INI_ARRAY(&ah->ini_japan2484, AR9462_BBC_TXIFR_COEFFJ); | ||
235 | } else if (AR_SREV_9550(ah)) { | 239 | } else if (AR_SREV_9550(ah)) { |
236 | /* mac */ | 240 | /* mac */ |
237 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], | 241 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c index 42b4412d6794..8dd069259e7b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c | |||
@@ -714,7 +714,6 @@ bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan) | |||
714 | 714 | ||
715 | return true; | 715 | return true; |
716 | } | 716 | } |
717 | EXPORT_SYMBOL(ar9003_mci_start_reset); | ||
718 | 717 | ||
719 | int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, | 718 | int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, |
720 | struct ath9k_hw_cal_data *caldata) | 719 | struct ath9k_hw_cal_data *caldata) |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 759f5f5a7154..ce19c09fa8e8 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | |||
@@ -784,7 +784,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, | |||
784 | REG_WRITE_ARRAY(&ah->iniAdditional, 1, regWrites); | 784 | REG_WRITE_ARRAY(&ah->iniAdditional, 1, regWrites); |
785 | 785 | ||
786 | if (chan->channel == 2484) | 786 | if (chan->channel == 2484) |
787 | ar9003_hw_prog_ini(ah, &ah->ini_japan2484, 1); | 787 | ar9003_hw_prog_ini(ah, &ah->iniCckfirJapan2484, 1); |
788 | 788 | ||
789 | if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) | 789 | if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) |
790 | REG_WRITE(ah, AR_GLB_SWREG_DISCONT_MODE, | 790 | REG_WRITE(ah, AR_GLB_SWREG_DISCONT_MODE, |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 8f585233a788..4c3d06de7111 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h | |||
@@ -698,13 +698,6 @@ | |||
698 | #define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT 0x0000ff00 | 698 | #define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT 0x0000ff00 |
699 | #define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT_S 8 | 699 | #define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT_S 8 |
700 | 700 | ||
701 | #define AR_PHY_65NM_CH0_RXTX1 0x16100 | ||
702 | #define AR_PHY_65NM_CH0_RXTX2 0x16104 | ||
703 | #define AR_PHY_65NM_CH1_RXTX1 0x16500 | ||
704 | #define AR_PHY_65NM_CH1_RXTX2 0x16504 | ||
705 | #define AR_PHY_65NM_CH2_RXTX1 0x16900 | ||
706 | #define AR_PHY_65NM_CH2_RXTX2 0x16904 | ||
707 | |||
708 | #define AR_CH0_TOP2 (AR_SREV_9300(ah) ? 0x1628c : \ | 701 | #define AR_CH0_TOP2 (AR_SREV_9300(ah) ? 0x1628c : \ |
709 | (AR_SREV_9462(ah) ? 0x16290 : 0x16284)) | 702 | (AR_SREV_9462(ah) ? 0x16290 : 0x16284)) |
710 | #define AR_CH0_TOP2_XPABIASLVL 0xf000 | 703 | #define AR_CH0_TOP2_XPABIASLVL 0xf000 |
@@ -1286,4 +1279,43 @@ | |||
1286 | #define AR_BTCOEX_WL_LNADIV_BT_INACTIVE_THRESHOLD 0xFC000000 | 1279 | #define AR_BTCOEX_WL_LNADIV_BT_INACTIVE_THRESHOLD 0xFC000000 |
1287 | #define AR_BTCOEX_WL_LNADIV_BT_INACTIVE_THRESHOLD_S 26 | 1280 | #define AR_BTCOEX_WL_LNADIV_BT_INACTIVE_THRESHOLD_S 26 |
1288 | 1281 | ||
1282 | /* Manual Peak detector calibration */ | ||
1283 | #define AR_PHY_65NM_BASE 0x16000 | ||
1284 | #define AR_PHY_65NM_RXRF_GAINSTAGES(i) (AR_PHY_65NM_BASE + \ | ||
1285 | (i * 0x400) + 0x8) | ||
1286 | #define AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE 0x80000000 | ||
1287 | #define AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE_S 31 | ||
1288 | #define AR_PHY_65NM_RXRF_GAINSTAGES_LNAON_CALDC 0x00000002 | ||
1289 | #define AR_PHY_65NM_RXRF_GAINSTAGES_LNAON_CALDC_S 1 | ||
1290 | #define AR_PHY_65NM_RXRF_GAINSTAGES_LNA2G_GAIN_OVR 0x70000000 | ||
1291 | #define AR_PHY_65NM_RXRF_GAINSTAGES_LNA2G_GAIN_OVR_S 28 | ||
1292 | #define AR_PHY_65NM_RXRF_GAINSTAGES_LNA5G_GAIN_OVR 0x03800000 | ||
1293 | #define AR_PHY_65NM_RXRF_GAINSTAGES_LNA5G_GAIN_OVR_S 23 | ||
1294 | |||
1295 | #define AR_PHY_65NM_RXTX2(i) (AR_PHY_65NM_BASE + \ | ||
1296 | (i * 0x400) + 0x104) | ||
1297 | #define AR_PHY_65NM_RXTX2_RXON_OVR 0x00001000 | ||
1298 | #define AR_PHY_65NM_RXTX2_RXON_OVR_S 12 | ||
1299 | #define AR_PHY_65NM_RXTX2_RXON 0x00000800 | ||
1300 | #define AR_PHY_65NM_RXTX2_RXON_S 11 | ||
1301 | |||
1302 | #define AR_PHY_65NM_RXRF_AGC(i) (AR_PHY_65NM_BASE + \ | ||
1303 | (i * 0x400) + 0xc) | ||
1304 | #define AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE 0x80000000 | ||
1305 | #define AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE_S 31 | ||
1306 | #define AR_PHY_65NM_RXRF_AGC_AGC_ON_OVR 0x40000000 | ||
1307 | #define AR_PHY_65NM_RXRF_AGC_AGC_ON_OVR_S 30 | ||
1308 | #define AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR 0x20000000 | ||
1309 | #define AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR_S 29 | ||
1310 | #define AR_PHY_65NM_RXRF_AGC_AGC2G_DBDAC_OVR 0x1E000000 | ||
1311 | #define AR_PHY_65NM_RXRF_AGC_AGC2G_DBDAC_OVR_S 25 | ||
1312 | #define AR_PHY_65NM_RXRF_AGC_AGC5G_DBDAC_OVR 0x00078000 | ||
1313 | #define AR_PHY_65NM_RXRF_AGC_AGC5G_DBDAC_OVR_S 15 | ||
1314 | #define AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR 0x01F80000 | ||
1315 | #define AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR_S 19 | ||
1316 | #define AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR 0x00007e00 | ||
1317 | #define AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR_S 9 | ||
1318 | #define AR_PHY_65NM_RXRF_AGC_AGC_OUT 0x00000004 | ||
1319 | #define AR_PHY_65NM_RXRF_AGC_AGC_OUT_S 2 | ||
1320 | |||
1289 | #endif /* AR9003_PHY_H */ | 1321 | #endif /* AR9003_PHY_H */ |
diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h index 58f30f65c6b6..ccc42a71b436 100644 --- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h | |||
@@ -78,7 +78,7 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = { | |||
78 | {0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150}, | 78 | {0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150}, |
79 | {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110}, | 79 | {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110}, |
80 | {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222}, | 80 | {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222}, |
81 | {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, | 81 | {0x0000a2c4, 0x00058d18, 0x00058d18, 0x00058d18, 0x00058d18}, |
82 | {0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982}, | 82 | {0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982}, |
83 | {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b}, | 83 | {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b}, |
84 | {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 84 | {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
diff --git a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h index fb4497fc7a3d..a3710f3bb90c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h | |||
@@ -18,7 +18,7 @@ | |||
18 | #ifndef INITVALS_9485_H | 18 | #ifndef INITVALS_9485_H |
19 | #define INITVALS_9485_H | 19 | #define INITVALS_9485_H |
20 | 20 | ||
21 | /* AR9485 1.0 */ | 21 | /* AR9485 1.1 */ |
22 | 22 | ||
23 | #define ar9485_1_1_mac_postamble ar9300_2p2_mac_postamble | 23 | #define ar9485_1_1_mac_postamble ar9300_2p2_mac_postamble |
24 | 24 | ||
@@ -31,6 +31,11 @@ static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1[][2] = { | |||
31 | 31 | ||
32 | static const u32 ar9485Common_wo_xlna_rx_gain_1_1[][2] = { | 32 | static const u32 ar9485Common_wo_xlna_rx_gain_1_1[][2] = { |
33 | /* Addr allmodes */ | 33 | /* Addr allmodes */ |
34 | {0x00009e00, 0x037216a0}, | ||
35 | {0x00009e04, 0x00182020}, | ||
36 | {0x00009e18, 0x00000000}, | ||
37 | {0x00009e2c, 0x00004121}, | ||
38 | {0x00009e44, 0x02282324}, | ||
34 | {0x0000a000, 0x00060005}, | 39 | {0x0000a000, 0x00060005}, |
35 | {0x0000a004, 0x00810080}, | 40 | {0x0000a004, 0x00810080}, |
36 | {0x0000a008, 0x00830082}, | 41 | {0x0000a008, 0x00830082}, |
@@ -164,6 +169,11 @@ static const u32 ar9485Common_wo_xlna_rx_gain_1_1[][2] = { | |||
164 | static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = { | 169 | static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = { |
165 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 170 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
166 | {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, | 171 | {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, |
172 | {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0x7999a83a, 0x7999a83a}, | ||
173 | {0x0000a2dc, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, | ||
174 | {0x0000a2e0, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, | ||
175 | {0x0000a2e4, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, | ||
176 | {0x0000a2e8, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, | ||
167 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, | 177 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, |
168 | {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 178 | {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
169 | {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, | 179 | {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, |
@@ -198,6 +208,22 @@ static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = { | |||
198 | {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | 208 | {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, |
199 | {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | 209 | {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, |
200 | {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | 210 | {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, |
211 | {0x0000a580, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
212 | {0x0000a584, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
213 | {0x0000a588, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
214 | {0x0000a58c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
215 | {0x0000a590, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
216 | {0x0000a594, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
217 | {0x0000a598, 0x00000000, 0x00000000, 0x01404501, 0x01404501}, | ||
218 | {0x0000a59c, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02}, | ||
219 | {0x0000a5a0, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02}, | ||
220 | {0x0000a5a4, 0x00000000, 0x00000000, 0x02808803, 0x02808803}, | ||
221 | {0x0000a5a8, 0x00000000, 0x00000000, 0x04c14b04, 0x04c14b04}, | ||
222 | {0x0000a5ac, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, | ||
223 | {0x0000a5b0, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, | ||
224 | {0x0000a5b4, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, | ||
225 | {0x0000a5b8, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, | ||
226 | {0x0000a5bc, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, | ||
201 | {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 227 | {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
202 | {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 228 | {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
203 | {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | 229 | {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, |
@@ -234,9 +260,193 @@ static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = { | |||
234 | {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, | 260 | {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, |
235 | }; | 261 | }; |
236 | 262 | ||
237 | #define ar9485Modes_high_ob_db_tx_gain_1_1 ar9485Modes_high_power_tx_gain_1_1 | 263 | static const u32 ar9485Modes_high_ob_db_tx_gain_1_1[][5] = { |
264 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
265 | {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, | ||
266 | {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0x7999a83a, 0x7999a83a}, | ||
267 | {0x0000a2dc, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, | ||
268 | {0x0000a2e0, 0x00000000, 0x00000000, 0xffc63a84, 0xffc63a84}, | ||
269 | {0x0000a2e4, 0x00000000, 0x00000000, 0xfe0fc000, 0xfe0fc000}, | ||
270 | {0x0000a2e8, 0x00000000, 0x00000000, 0xfff00000, 0xfff00000}, | ||
271 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, | ||
272 | {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
273 | {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, | ||
274 | {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, | ||
275 | {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, | ||
276 | {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, | ||
277 | {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, | ||
278 | {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, | ||
279 | {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, | ||
280 | {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, | ||
281 | {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603}, | ||
282 | {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605}, | ||
283 | {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03}, | ||
284 | {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04}, | ||
285 | {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20}, | ||
286 | {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21}, | ||
287 | {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62}, | ||
288 | {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63}, | ||
289 | {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65}, | ||
290 | {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66}, | ||
291 | {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645}, | ||
292 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, | ||
293 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, | ||
294 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, | ||
295 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, | ||
296 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, | ||
297 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
298 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, | ||
299 | {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
300 | {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
301 | {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
302 | {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
303 | {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
304 | {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
305 | {0x0000a580, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
306 | {0x0000a584, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
307 | {0x0000a588, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
308 | {0x0000a58c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
309 | {0x0000a590, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
310 | {0x0000a594, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
311 | {0x0000a598, 0x00000000, 0x00000000, 0x01404501, 0x01404501}, | ||
312 | {0x0000a59c, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02}, | ||
313 | {0x0000a5a0, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02}, | ||
314 | {0x0000a5a4, 0x00000000, 0x00000000, 0x02808803, 0x02808803}, | ||
315 | {0x0000a5a8, 0x00000000, 0x00000000, 0x04c14b04, 0x04c14b04}, | ||
316 | {0x0000a5ac, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, | ||
317 | {0x0000a5b0, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, | ||
318 | {0x0000a5b4, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, | ||
319 | {0x0000a5b8, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, | ||
320 | {0x0000a5bc, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, | ||
321 | {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
322 | {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
323 | {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
324 | {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
325 | {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
326 | {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
327 | {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
328 | {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
329 | {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
330 | {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
331 | {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
332 | {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
333 | {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
334 | {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
335 | {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
336 | {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
337 | {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
338 | {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
339 | {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
340 | {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
341 | {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
342 | {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
343 | {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
344 | {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
345 | {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
346 | {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
347 | {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
348 | {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
349 | {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
350 | {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
351 | {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
352 | {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
353 | {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db}, | ||
354 | {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, | ||
355 | }; | ||
238 | 356 | ||
239 | #define ar9485Modes_low_ob_db_tx_gain_1_1 ar9485Modes_high_ob_db_tx_gain_1_1 | 357 | static const u32 ar9485Modes_low_ob_db_tx_gain_1_1[][5] = { |
358 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
359 | {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, | ||
360 | {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0x7999a83a, 0x7999a83a}, | ||
361 | {0x0000a2dc, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, | ||
362 | {0x0000a2e0, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, | ||
363 | {0x0000a2e4, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, | ||
364 | {0x0000a2e8, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, | ||
365 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, | ||
366 | {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
367 | {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, | ||
368 | {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, | ||
369 | {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, | ||
370 | {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, | ||
371 | {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, | ||
372 | {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, | ||
373 | {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, | ||
374 | {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, | ||
375 | {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603}, | ||
376 | {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605}, | ||
377 | {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03}, | ||
378 | {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04}, | ||
379 | {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20}, | ||
380 | {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21}, | ||
381 | {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62}, | ||
382 | {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63}, | ||
383 | {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65}, | ||
384 | {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66}, | ||
385 | {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645}, | ||
386 | {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, | ||
387 | {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, | ||
388 | {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, | ||
389 | {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, | ||
390 | {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, | ||
391 | {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
392 | {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, | ||
393 | {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
394 | {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
395 | {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
396 | {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
397 | {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
398 | {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, | ||
399 | {0x0000a580, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
400 | {0x0000a584, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
401 | {0x0000a588, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
402 | {0x0000a58c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
403 | {0x0000a590, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
404 | {0x0000a594, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
405 | {0x0000a598, 0x00000000, 0x00000000, 0x01404501, 0x01404501}, | ||
406 | {0x0000a59c, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02}, | ||
407 | {0x0000a5a0, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02}, | ||
408 | {0x0000a5a4, 0x00000000, 0x00000000, 0x02808803, 0x02808803}, | ||
409 | {0x0000a5a8, 0x00000000, 0x00000000, 0x04c14b04, 0x04c14b04}, | ||
410 | {0x0000a5ac, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, | ||
411 | {0x0000a5b0, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, | ||
412 | {0x0000a5b4, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, | ||
413 | {0x0000a5b8, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, | ||
414 | {0x0000a5bc, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, | ||
415 | {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
416 | {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
417 | {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
418 | {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
419 | {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
420 | {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
421 | {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
422 | {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
423 | {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
424 | {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
425 | {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
426 | {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
427 | {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
428 | {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
429 | {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
430 | {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
431 | {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
432 | {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
433 | {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
434 | {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
435 | {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
436 | {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
437 | {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
438 | {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
439 | {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
440 | {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
441 | {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
442 | {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
443 | {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
444 | {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
445 | {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
446 | {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
447 | {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db}, | ||
448 | {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, | ||
449 | }; | ||
240 | 450 | ||
241 | #define ar9485_modes_lowest_ob_db_tx_gain_1_1 ar9485Modes_low_ob_db_tx_gain_1_1 | 451 | #define ar9485_modes_lowest_ob_db_tx_gain_1_1 ar9485Modes_low_ob_db_tx_gain_1_1 |
242 | 452 | ||
@@ -245,19 +455,19 @@ static const u32 ar9485_1_1[][2] = { | |||
245 | {0x0000a580, 0x00000000}, | 455 | {0x0000a580, 0x00000000}, |
246 | {0x0000a584, 0x00000000}, | 456 | {0x0000a584, 0x00000000}, |
247 | {0x0000a588, 0x00000000}, | 457 | {0x0000a588, 0x00000000}, |
248 | {0x0000a58c, 0x00000000}, | 458 | {0x0000a58c, 0x01804000}, |
249 | {0x0000a590, 0x00000000}, | 459 | {0x0000a590, 0x02808a02}, |
250 | {0x0000a594, 0x00000000}, | 460 | {0x0000a594, 0x0340ca02}, |
251 | {0x0000a598, 0x00000000}, | 461 | {0x0000a598, 0x0340cd03}, |
252 | {0x0000a59c, 0x00000000}, | 462 | {0x0000a59c, 0x0340cd03}, |
253 | {0x0000a5a0, 0x00000000}, | 463 | {0x0000a5a0, 0x06415304}, |
254 | {0x0000a5a4, 0x00000000}, | 464 | {0x0000a5a4, 0x04c11905}, |
255 | {0x0000a5a8, 0x00000000}, | 465 | {0x0000a5a8, 0x06415905}, |
256 | {0x0000a5ac, 0x00000000}, | 466 | {0x0000a5ac, 0x06415905}, |
257 | {0x0000a5b0, 0x00000000}, | 467 | {0x0000a5b0, 0x06415905}, |
258 | {0x0000a5b4, 0x00000000}, | 468 | {0x0000a5b4, 0x06415905}, |
259 | {0x0000a5b8, 0x00000000}, | 469 | {0x0000a5b8, 0x06415905}, |
260 | {0x0000a5bc, 0x00000000}, | 470 | {0x0000a5bc, 0x06415905}, |
261 | }; | 471 | }; |
262 | 472 | ||
263 | static const u32 ar9485_1_1_radio_core[][2] = { | 473 | static const u32 ar9485_1_1_radio_core[][2] = { |
@@ -340,7 +550,7 @@ static const u32 ar9485_1_1_baseband_core[][2] = { | |||
340 | {0x00009880, 0x201fff00}, | 550 | {0x00009880, 0x201fff00}, |
341 | {0x00009884, 0x00001042}, | 551 | {0x00009884, 0x00001042}, |
342 | {0x000098a4, 0x00200400}, | 552 | {0x000098a4, 0x00200400}, |
343 | {0x000098b0, 0x52440bbe}, | 553 | {0x000098b0, 0x32840bbe}, |
344 | {0x000098d0, 0x004b6a8e}, | 554 | {0x000098d0, 0x004b6a8e}, |
345 | {0x000098d4, 0x00000820}, | 555 | {0x000098d4, 0x00000820}, |
346 | {0x000098dc, 0x00000000}, | 556 | {0x000098dc, 0x00000000}, |
@@ -362,7 +572,7 @@ static const u32 ar9485_1_1_baseband_core[][2] = { | |||
362 | {0x00009d18, 0x00000000}, | 572 | {0x00009d18, 0x00000000}, |
363 | {0x00009d1c, 0x00000000}, | 573 | {0x00009d1c, 0x00000000}, |
364 | {0x00009e08, 0x0038233c}, | 574 | {0x00009e08, 0x0038233c}, |
365 | {0x00009e24, 0x9927b515}, | 575 | {0x00009e24, 0x992bb515}, |
366 | {0x00009e28, 0x12ef0200}, | 576 | {0x00009e28, 0x12ef0200}, |
367 | {0x00009e30, 0x06336f77}, | 577 | {0x00009e30, 0x06336f77}, |
368 | {0x00009e34, 0x6af6532f}, | 578 | {0x00009e34, 0x6af6532f}, |
@@ -427,7 +637,7 @@ static const u32 ar9485_1_1_baseband_core[][2] = { | |||
427 | {0x0000a408, 0x0e79e5c6}, | 637 | {0x0000a408, 0x0e79e5c6}, |
428 | {0x0000a40c, 0x00820820}, | 638 | {0x0000a40c, 0x00820820}, |
429 | {0x0000a414, 0x1ce739cf}, | 639 | {0x0000a414, 0x1ce739cf}, |
430 | {0x0000a418, 0x2d0019ce}, | 640 | {0x0000a418, 0x2d0021ce}, |
431 | {0x0000a41c, 0x1ce739ce}, | 641 | {0x0000a41c, 0x1ce739ce}, |
432 | {0x0000a420, 0x000001ce}, | 642 | {0x0000a420, 0x000001ce}, |
433 | {0x0000a424, 0x1ce739ce}, | 643 | {0x0000a424, 0x1ce739ce}, |
@@ -443,8 +653,8 @@ static const u32 ar9485_1_1_baseband_core[][2] = { | |||
443 | {0x0000a44c, 0x00000001}, | 653 | {0x0000a44c, 0x00000001}, |
444 | {0x0000a450, 0x00010000}, | 654 | {0x0000a450, 0x00010000}, |
445 | {0x0000a5c4, 0xbfad9d74}, | 655 | {0x0000a5c4, 0xbfad9d74}, |
446 | {0x0000a5c8, 0x0048060a}, | 656 | {0x0000a5c8, 0x00480605}, |
447 | {0x0000a5cc, 0x00000637}, | 657 | {0x0000a5cc, 0x00002e37}, |
448 | {0x0000a760, 0x03020100}, | 658 | {0x0000a760, 0x03020100}, |
449 | {0x0000a764, 0x09080504}, | 659 | {0x0000a764, 0x09080504}, |
450 | {0x0000a768, 0x0d0c0b0a}, | 660 | {0x0000a768, 0x0d0c0b0a}, |
@@ -464,17 +674,22 @@ static const u32 ar9485_1_1_baseband_core[][2] = { | |||
464 | 674 | ||
465 | static const u32 ar9485_common_rx_gain_1_1[][2] = { | 675 | static const u32 ar9485_common_rx_gain_1_1[][2] = { |
466 | /* Addr allmodes */ | 676 | /* Addr allmodes */ |
467 | {0x0000a000, 0x00010000}, | 677 | {0x00009e00, 0x03721b20}, |
468 | {0x0000a004, 0x00030002}, | 678 | {0x00009e04, 0x00082020}, |
469 | {0x0000a008, 0x00050004}, | 679 | {0x00009e18, 0x0300501e}, |
470 | {0x0000a00c, 0x00810080}, | 680 | {0x00009e2c, 0x00002e21}, |
471 | {0x0000a010, 0x01800082}, | 681 | {0x00009e44, 0x02182324}, |
472 | {0x0000a014, 0x01820181}, | 682 | {0x0000a000, 0x00060005}, |
473 | {0x0000a018, 0x01840183}, | 683 | {0x0000a004, 0x00810080}, |
474 | {0x0000a01c, 0x01880185}, | 684 | {0x0000a008, 0x00830082}, |
475 | {0x0000a020, 0x018a0189}, | 685 | {0x0000a00c, 0x00850084}, |
476 | {0x0000a024, 0x02850284}, | 686 | {0x0000a010, 0x01820181}, |
477 | {0x0000a028, 0x02890288}, | 687 | {0x0000a014, 0x01840183}, |
688 | {0x0000a018, 0x01880185}, | ||
689 | {0x0000a01c, 0x018a0189}, | ||
690 | {0x0000a020, 0x02850284}, | ||
691 | {0x0000a024, 0x02890288}, | ||
692 | {0x0000a028, 0x028b028a}, | ||
478 | {0x0000a02c, 0x03850384}, | 693 | {0x0000a02c, 0x03850384}, |
479 | {0x0000a030, 0x03890388}, | 694 | {0x0000a030, 0x03890388}, |
480 | {0x0000a034, 0x038b038a}, | 695 | {0x0000a034, 0x038b038a}, |
@@ -496,15 +711,15 @@ static const u32 ar9485_common_rx_gain_1_1[][2] = { | |||
496 | {0x0000a074, 0x00000000}, | 711 | {0x0000a074, 0x00000000}, |
497 | {0x0000a078, 0x00000000}, | 712 | {0x0000a078, 0x00000000}, |
498 | {0x0000a07c, 0x00000000}, | 713 | {0x0000a07c, 0x00000000}, |
499 | {0x0000a080, 0x28282828}, | 714 | {0x0000a080, 0x18181818}, |
500 | {0x0000a084, 0x28282828}, | 715 | {0x0000a084, 0x18181818}, |
501 | {0x0000a088, 0x28282828}, | 716 | {0x0000a088, 0x18181818}, |
502 | {0x0000a08c, 0x28282828}, | 717 | {0x0000a08c, 0x18181818}, |
503 | {0x0000a090, 0x28282828}, | 718 | {0x0000a090, 0x18181818}, |
504 | {0x0000a094, 0x21212128}, | 719 | {0x0000a094, 0x18181818}, |
505 | {0x0000a098, 0x171c1c1c}, | 720 | {0x0000a098, 0x17181818}, |
506 | {0x0000a09c, 0x02020212}, | 721 | {0x0000a09c, 0x02020b0b}, |
507 | {0x0000a0a0, 0x00000202}, | 722 | {0x0000a0a0, 0x02020202}, |
508 | {0x0000a0a4, 0x00000000}, | 723 | {0x0000a0a4, 0x00000000}, |
509 | {0x0000a0a8, 0x00000000}, | 724 | {0x0000a0a8, 0x00000000}, |
510 | {0x0000a0ac, 0x00000000}, | 725 | {0x0000a0ac, 0x00000000}, |
@@ -512,22 +727,22 @@ static const u32 ar9485_common_rx_gain_1_1[][2] = { | |||
512 | {0x0000a0b4, 0x00000000}, | 727 | {0x0000a0b4, 0x00000000}, |
513 | {0x0000a0b8, 0x00000000}, | 728 | {0x0000a0b8, 0x00000000}, |
514 | {0x0000a0bc, 0x00000000}, | 729 | {0x0000a0bc, 0x00000000}, |
515 | {0x0000a0c0, 0x001f0000}, | 730 | {0x0000a0c0, 0x22072208}, |
516 | {0x0000a0c4, 0x111f1100}, | 731 | {0x0000a0c4, 0x22052206}, |
517 | {0x0000a0c8, 0x111d111e}, | 732 | {0x0000a0c8, 0x22032204}, |
518 | {0x0000a0cc, 0x111b111c}, | 733 | {0x0000a0cc, 0x22012202}, |
519 | {0x0000a0d0, 0x22032204}, | 734 | {0x0000a0d0, 0x221f2200}, |
520 | {0x0000a0d4, 0x22012202}, | 735 | {0x0000a0d4, 0x221d221e}, |
521 | {0x0000a0d8, 0x221f2200}, | 736 | {0x0000a0d8, 0x33023303}, |
522 | {0x0000a0dc, 0x221d221e}, | 737 | {0x0000a0dc, 0x33003301}, |
523 | {0x0000a0e0, 0x33013302}, | 738 | {0x0000a0e0, 0x331e331f}, |
524 | {0x0000a0e4, 0x331f3300}, | 739 | {0x0000a0e4, 0x4402331d}, |
525 | {0x0000a0e8, 0x4402331e}, | 740 | {0x0000a0e8, 0x44004401}, |
526 | {0x0000a0ec, 0x44004401}, | 741 | {0x0000a0ec, 0x441e441f}, |
527 | {0x0000a0f0, 0x441e441f}, | 742 | {0x0000a0f0, 0x55025503}, |
528 | {0x0000a0f4, 0x55015502}, | 743 | {0x0000a0f4, 0x55005501}, |
529 | {0x0000a0f8, 0x551f5500}, | 744 | {0x0000a0f8, 0x551e551f}, |
530 | {0x0000a0fc, 0x6602551e}, | 745 | {0x0000a0fc, 0x6602551d}, |
531 | {0x0000a100, 0x66006601}, | 746 | {0x0000a100, 0x66006601}, |
532 | {0x0000a104, 0x661e661f}, | 747 | {0x0000a104, 0x661e661f}, |
533 | {0x0000a108, 0x7703661d}, | 748 | {0x0000a108, 0x7703661d}, |
@@ -636,17 +851,12 @@ static const u32 ar9485_1_1_baseband_postamble[][5] = { | |||
636 | {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, | 851 | {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, |
637 | {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c}, | 852 | {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c}, |
638 | {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044}, | 853 | {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044}, |
639 | {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0}, | ||
640 | {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020}, | ||
641 | {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, | 854 | {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, |
642 | {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec80d2e, 0x7ec80d2e}, | 855 | {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec80d2e, 0x7ec80d2e}, |
643 | {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e}, | 856 | {0x00009e14, 0x31395d53, 0x31396053, 0x312e6053, 0x312e5d53}, |
644 | {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
645 | {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, | 857 | {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, |
646 | {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, | 858 | {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, |
647 | {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, | ||
648 | {0x00009e3c, 0xcf946220, 0xcf946220, 0xcf946222, 0xcf946222}, | 859 | {0x00009e3c, 0xcf946220, 0xcf946220, 0xcf946222, 0xcf946222}, |
649 | {0x00009e44, 0x02321e27, 0x02321e27, 0x02282324, 0x02282324}, | ||
650 | {0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010}, | 860 | {0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010}, |
651 | {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, | 861 | {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, |
652 | {0x0000a204, 0x01303fc0, 0x01303fc4, 0x01303fc4, 0x01303fc0}, | 862 | {0x0000a204, 0x01303fc0, 0x01303fc4, 0x01303fc4, 0x01303fc0}, |
@@ -850,4 +1060,6 @@ static const u32 ar9485_1_1_mac_core[][2] = { | |||
850 | {0x000083d0, 0x000301ff}, | 1060 | {0x000083d0, 0x000301ff}, |
851 | }; | 1061 | }; |
852 | 1062 | ||
1063 | #define ar9485_1_1_baseband_core_txfir_coeff_japan_2484 ar9462_2p0_baseband_core_txfir_coeff_japan_2484 | ||
1064 | |||
853 | #endif /* INITVALS_9485_H */ | 1065 | #endif /* INITVALS_9485_H */ |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 4e125d8904a0..80bab1b8447a 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -129,10 +129,10 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd, | |||
129 | #define ATH_TXMAXTRY 13 | 129 | #define ATH_TXMAXTRY 13 |
130 | 130 | ||
131 | #define TID_TO_WME_AC(_tid) \ | 131 | #define TID_TO_WME_AC(_tid) \ |
132 | ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \ | 132 | ((((_tid) == 0) || ((_tid) == 3)) ? IEEE80211_AC_BE : \ |
133 | (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \ | 133 | (((_tid) == 1) || ((_tid) == 2)) ? IEEE80211_AC_BK : \ |
134 | (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \ | 134 | (((_tid) == 4) || ((_tid) == 5)) ? IEEE80211_AC_VI : \ |
135 | WME_AC_VO) | 135 | IEEE80211_AC_VO) |
136 | 136 | ||
137 | #define ATH_AGGR_DELIM_SZ 4 | 137 | #define ATH_AGGR_DELIM_SZ 4 |
138 | #define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */ | 138 | #define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */ |
@@ -259,13 +259,10 @@ struct ath_atx_tid { | |||
259 | }; | 259 | }; |
260 | 260 | ||
261 | struct ath_node { | 261 | struct ath_node { |
262 | #ifdef CONFIG_ATH9K_DEBUGFS | ||
263 | struct list_head list; /* for sc->nodes */ | ||
264 | #endif | ||
265 | struct ieee80211_sta *sta; /* station struct we're part of */ | 262 | struct ieee80211_sta *sta; /* station struct we're part of */ |
266 | struct ieee80211_vif *vif; /* interface with which we're associated */ | 263 | struct ieee80211_vif *vif; /* interface with which we're associated */ |
267 | struct ath_atx_tid tid[WME_NUM_TID]; | 264 | struct ath_atx_tid tid[WME_NUM_TID]; |
268 | struct ath_atx_ac ac[WME_NUM_AC]; | 265 | struct ath_atx_ac ac[IEEE80211_NUM_ACS]; |
269 | int ps_key; | 266 | int ps_key; |
270 | 267 | ||
271 | u16 maxampdu; | 268 | u16 maxampdu; |
@@ -299,9 +296,9 @@ struct ath_tx { | |||
299 | struct list_head txbuf; | 296 | struct list_head txbuf; |
300 | struct ath_txq txq[ATH9K_NUM_TX_QUEUES]; | 297 | struct ath_txq txq[ATH9K_NUM_TX_QUEUES]; |
301 | struct ath_descdma txdma; | 298 | struct ath_descdma txdma; |
302 | struct ath_txq *txq_map[WME_NUM_AC]; | 299 | struct ath_txq *txq_map[IEEE80211_NUM_ACS]; |
303 | u32 txq_max_pending[WME_NUM_AC]; | 300 | u32 txq_max_pending[IEEE80211_NUM_ACS]; |
304 | u16 max_aggr_framelen[WME_NUM_AC][4][32]; | 301 | u16 max_aggr_framelen[IEEE80211_NUM_ACS][4][32]; |
305 | }; | 302 | }; |
306 | 303 | ||
307 | struct ath_rx_edma { | 304 | struct ath_rx_edma { |
@@ -461,6 +458,12 @@ void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type); | |||
461 | /* BTCOEX */ | 458 | /* BTCOEX */ |
462 | /**********/ | 459 | /**********/ |
463 | 460 | ||
461 | #define ATH_DUMP_BTCOEX(_s, _val) \ | ||
462 | do { \ | ||
463 | len += snprintf(buf + len, size - len, \ | ||
464 | "%20s : %10d\n", _s, (_val)); \ | ||
465 | } while (0) | ||
466 | |||
464 | enum bt_op_flags { | 467 | enum bt_op_flags { |
465 | BT_OP_PRIORITY_DETECTED, | 468 | BT_OP_PRIORITY_DETECTED, |
466 | BT_OP_SCAN, | 469 | BT_OP_SCAN, |
@@ -482,6 +485,7 @@ struct ath_btcoex { | |||
482 | int rssi_count; | 485 | int rssi_count; |
483 | struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */ | 486 | struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */ |
484 | struct ath_mci_profile mci; | 487 | struct ath_mci_profile mci; |
488 | u8 stomp_audio; | ||
485 | }; | 489 | }; |
486 | 490 | ||
487 | #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT | 491 | #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT |
@@ -494,7 +498,7 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc); | |||
494 | void ath9k_btcoex_handle_interrupt(struct ath_softc *sc, u32 status); | 498 | void ath9k_btcoex_handle_interrupt(struct ath_softc *sc, u32 status); |
495 | u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen); | 499 | u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen); |
496 | void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc); | 500 | void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc); |
497 | int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, u32 len, u32 size); | 501 | int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, u32 size); |
498 | #else | 502 | #else |
499 | static inline int ath9k_init_btcoex(struct ath_softc *sc) | 503 | static inline int ath9k_init_btcoex(struct ath_softc *sc) |
500 | { | 504 | { |
@@ -521,8 +525,7 @@ static inline u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, | |||
521 | static inline void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc) | 525 | static inline void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc) |
522 | { | 526 | { |
523 | } | 527 | } |
524 | static inline int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, | 528 | static inline int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, u32 size) |
525 | u32 len, u32 size) | ||
526 | { | 529 | { |
527 | return 0; | 530 | return 0; |
528 | } | 531 | } |
@@ -717,9 +720,6 @@ struct ath_softc { | |||
717 | 720 | ||
718 | #ifdef CONFIG_ATH9K_DEBUGFS | 721 | #ifdef CONFIG_ATH9K_DEBUGFS |
719 | struct ath9k_debug debug; | 722 | struct ath9k_debug debug; |
720 | spinlock_t nodes_lock; | ||
721 | struct list_head nodes; /* basically, stations */ | ||
722 | unsigned int tx_complete_poll_work_seen; | ||
723 | #endif | 723 | #endif |
724 | struct ath_beacon_config cur_beacon_conf; | 724 | struct ath_beacon_config cur_beacon_conf; |
725 | struct delayed_work tx_complete_work; | 725 | struct delayed_work tx_complete_work; |
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 1b48414dca95..531fffd801a3 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -46,7 +46,7 @@ static void ath9k_beaconq_config(struct ath_softc *sc) | |||
46 | qi.tqi_cwmax = 0; | 46 | qi.tqi_cwmax = 0; |
47 | } else { | 47 | } else { |
48 | /* Adhoc mode; important thing is to use 2x cwmin. */ | 48 | /* Adhoc mode; important thing is to use 2x cwmin. */ |
49 | txq = sc->tx.txq_map[WME_AC_BE]; | 49 | txq = sc->tx.txq_map[IEEE80211_AC_BE]; |
50 | ath9k_hw_get_txq_props(ah, txq->axq_qnum, &qi_be); | 50 | ath9k_hw_get_txq_props(ah, txq->axq_qnum, &qi_be); |
51 | qi.tqi_aifs = qi_be.tqi_aifs; | 51 | qi.tqi_aifs = qi_be.tqi_aifs; |
52 | if (ah->slottime == ATH9K_SLOT_TIME_20) | 52 | if (ah->slottime == ATH9K_SLOT_TIME_20) |
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c index c90e9bc4b026..9963b0bf9f72 100644 --- a/drivers/net/wireless/ath/ath9k/btcoex.c +++ b/drivers/net/wireless/ath/ath9k/btcoex.c | |||
@@ -49,6 +49,7 @@ static const u32 mci_wlan_weights[ATH_BTCOEX_STOMP_MAX] | |||
49 | { 0x01017d01, 0x3b3b3b01, 0x3b3b3b01, 0x3b3b3b3b }, /* STOMP_LOW */ | 49 | { 0x01017d01, 0x3b3b3b01, 0x3b3b3b01, 0x3b3b3b3b }, /* STOMP_LOW */ |
50 | { 0x01017d01, 0x01010101, 0x01010101, 0x01010101 }, /* STOMP_NONE */ | 50 | { 0x01017d01, 0x01010101, 0x01010101, 0x01010101 }, /* STOMP_NONE */ |
51 | { 0x01017d01, 0x013b0101, 0x3b3b0101, 0x3b3b013b }, /* STOMP_LOW_FTP */ | 51 | { 0x01017d01, 0x013b0101, 0x3b3b0101, 0x3b3b013b }, /* STOMP_LOW_FTP */ |
52 | { 0xffffff01, 0xffffffff, 0xffffff01, 0xffffffff }, /* STOMP_AUDIO */ | ||
52 | }; | 53 | }; |
53 | 54 | ||
54 | void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum) | 55 | void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum) |
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h index 2f84ab273d0c..6de26ea5d5fa 100644 --- a/drivers/net/wireless/ath/ath9k/btcoex.h +++ b/drivers/net/wireless/ath/ath9k/btcoex.h | |||
@@ -50,6 +50,7 @@ enum ath_stomp_type { | |||
50 | ATH_BTCOEX_STOMP_LOW, | 50 | ATH_BTCOEX_STOMP_LOW, |
51 | ATH_BTCOEX_STOMP_NONE, | 51 | ATH_BTCOEX_STOMP_NONE, |
52 | ATH_BTCOEX_STOMP_LOW_FTP, | 52 | ATH_BTCOEX_STOMP_LOW_FTP, |
53 | ATH_BTCOEX_STOMP_AUDIO, | ||
53 | ATH_BTCOEX_STOMP_MAX | 54 | ATH_BTCOEX_STOMP_MAX |
54 | }; | 55 | }; |
55 | 56 | ||
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h index ad14fecc76c6..76b543900314 100644 --- a/drivers/net/wireless/ath/ath9k/common.h +++ b/drivers/net/wireless/ath/ath9k/common.h | |||
@@ -28,13 +28,6 @@ | |||
28 | #define WME_MAX_BA WME_BA_BMP_SIZE | 28 | #define WME_MAX_BA WME_BA_BMP_SIZE |
29 | #define ATH_TID_MAX_BUFS (2 * WME_MAX_BA) | 29 | #define ATH_TID_MAX_BUFS (2 * WME_MAX_BA) |
30 | 30 | ||
31 | /* These must match mac80211 skb queue mapping numbers */ | ||
32 | #define WME_AC_VO 0 | ||
33 | #define WME_AC_VI 1 | ||
34 | #define WME_AC_BE 2 | ||
35 | #define WME_AC_BK 3 | ||
36 | #define WME_NUM_AC 4 | ||
37 | |||
38 | #define ATH_RSSI_DUMMY_MARKER 0x127 | 31 | #define ATH_RSSI_DUMMY_MARKER 0x127 |
39 | #define ATH_RSSI_LPF_LEN 10 | 32 | #define ATH_RSSI_LPF_LEN 10 |
40 | #define RSSI_LPF_THRESHOLD -20 | 33 | #define RSSI_LPF_THRESHOLD -20 |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index a8be94b2a53a..939308c25712 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -512,62 +512,19 @@ static const struct file_operations fops_interrupt = { | |||
512 | .llseek = default_llseek, | 512 | .llseek = default_llseek, |
513 | }; | 513 | }; |
514 | 514 | ||
515 | #define PR_QNUM(_n) sc->tx.txq_map[_n]->axq_qnum | ||
516 | #define PR(str, elem) \ | ||
517 | do { \ | ||
518 | len += snprintf(buf + len, size - len, \ | ||
519 | "%s%13u%11u%10u%10u\n", str, \ | ||
520 | sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].elem, \ | ||
521 | sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].elem, \ | ||
522 | sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].elem, \ | ||
523 | sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].elem); \ | ||
524 | if (len >= size) \ | ||
525 | goto done; \ | ||
526 | } while(0) | ||
527 | |||
528 | #define PRX(str, elem) \ | ||
529 | do { \ | ||
530 | len += snprintf(buf + len, size - len, \ | ||
531 | "%s%13u%11u%10u%10u\n", str, \ | ||
532 | (unsigned int)(sc->tx.txq_map[WME_AC_BE]->elem), \ | ||
533 | (unsigned int)(sc->tx.txq_map[WME_AC_BK]->elem), \ | ||
534 | (unsigned int)(sc->tx.txq_map[WME_AC_VI]->elem), \ | ||
535 | (unsigned int)(sc->tx.txq_map[WME_AC_VO]->elem)); \ | ||
536 | if (len >= size) \ | ||
537 | goto done; \ | ||
538 | } while(0) | ||
539 | |||
540 | #define PRQLE(str, elem) \ | ||
541 | do { \ | ||
542 | len += snprintf(buf + len, size - len, \ | ||
543 | "%s%13i%11i%10i%10i\n", str, \ | ||
544 | list_empty(&sc->tx.txq_map[WME_AC_BE]->elem), \ | ||
545 | list_empty(&sc->tx.txq_map[WME_AC_BK]->elem), \ | ||
546 | list_empty(&sc->tx.txq_map[WME_AC_VI]->elem), \ | ||
547 | list_empty(&sc->tx.txq_map[WME_AC_VO]->elem)); \ | ||
548 | if (len >= size) \ | ||
549 | goto done; \ | ||
550 | } while (0) | ||
551 | |||
552 | static ssize_t read_file_xmit(struct file *file, char __user *user_buf, | 515 | static ssize_t read_file_xmit(struct file *file, char __user *user_buf, |
553 | size_t count, loff_t *ppos) | 516 | size_t count, loff_t *ppos) |
554 | { | 517 | { |
555 | struct ath_softc *sc = file->private_data; | 518 | struct ath_softc *sc = file->private_data; |
556 | char *buf; | 519 | char *buf; |
557 | unsigned int len = 0, size = 8000; | 520 | unsigned int len = 0, size = 2048; |
558 | int i; | ||
559 | ssize_t retval = 0; | 521 | ssize_t retval = 0; |
560 | char tmp[32]; | ||
561 | 522 | ||
562 | buf = kzalloc(size, GFP_KERNEL); | 523 | buf = kzalloc(size, GFP_KERNEL); |
563 | if (buf == NULL) | 524 | if (buf == NULL) |
564 | return -ENOMEM; | 525 | return -ENOMEM; |
565 | 526 | ||
566 | len += sprintf(buf, "Num-Tx-Queues: %i tx-queues-setup: 0x%x" | 527 | len += sprintf(buf, "%30s %10s%10s%10s\n\n", |
567 | " poll-work-seen: %u\n" | ||
568 | "%30s %10s%10s%10s\n\n", | ||
569 | ATH9K_NUM_TX_QUEUES, sc->tx.txqsetup, | ||
570 | sc->tx_complete_poll_work_seen, | ||
571 | "BE", "BK", "VI", "VO"); | 528 | "BE", "BK", "VI", "VO"); |
572 | 529 | ||
573 | PR("MPDUs Queued: ", queued); | 530 | PR("MPDUs Queued: ", queued); |
@@ -587,62 +544,11 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, | |||
587 | PR("DELIM Underrun: ", delim_underrun); | 544 | PR("DELIM Underrun: ", delim_underrun); |
588 | PR("TX-Pkts-All: ", tx_pkts_all); | 545 | PR("TX-Pkts-All: ", tx_pkts_all); |
589 | PR("TX-Bytes-All: ", tx_bytes_all); | 546 | PR("TX-Bytes-All: ", tx_bytes_all); |
590 | PR("hw-put-tx-buf: ", puttxbuf); | 547 | PR("HW-put-tx-buf: ", puttxbuf); |
591 | PR("hw-tx-start: ", txstart); | 548 | PR("HW-tx-start: ", txstart); |
592 | PR("hw-tx-proc-desc: ", txprocdesc); | 549 | PR("HW-tx-proc-desc: ", txprocdesc); |
593 | PR("TX-Failed: ", txfailed); | 550 | PR("TX-Failed: ", txfailed); |
594 | len += snprintf(buf + len, size - len, | ||
595 | "%s%11p%11p%10p%10p\n", "txq-memory-address:", | ||
596 | sc->tx.txq_map[WME_AC_BE], | ||
597 | sc->tx.txq_map[WME_AC_BK], | ||
598 | sc->tx.txq_map[WME_AC_VI], | ||
599 | sc->tx.txq_map[WME_AC_VO]); | ||
600 | if (len >= size) | ||
601 | goto done; | ||
602 | |||
603 | PRX("axq-qnum: ", axq_qnum); | ||
604 | PRX("axq-depth: ", axq_depth); | ||
605 | PRX("axq-ampdu_depth: ", axq_ampdu_depth); | ||
606 | PRX("axq-stopped ", stopped); | ||
607 | PRX("tx-in-progress ", axq_tx_inprogress); | ||
608 | PRX("pending-frames ", pending_frames); | ||
609 | PRX("txq_headidx: ", txq_headidx); | ||
610 | PRX("txq_tailidx: ", txq_headidx); | ||
611 | |||
612 | PRQLE("axq_q empty: ", axq_q); | ||
613 | PRQLE("axq_acq empty: ", axq_acq); | ||
614 | for (i = 0; i < ATH_TXFIFO_DEPTH; i++) { | ||
615 | snprintf(tmp, sizeof(tmp) - 1, "txq_fifo[%i] empty: ", i); | ||
616 | PRQLE(tmp, txq_fifo[i]); | ||
617 | } | ||
618 | |||
619 | /* Print out more detailed queue-info */ | ||
620 | for (i = 0; i <= WME_AC_BK; i++) { | ||
621 | struct ath_txq *txq = &(sc->tx.txq[i]); | ||
622 | struct ath_atx_ac *ac; | ||
623 | struct ath_atx_tid *tid; | ||
624 | if (len >= size) | ||
625 | goto done; | ||
626 | spin_lock_bh(&txq->axq_lock); | ||
627 | if (!list_empty(&txq->axq_acq)) { | ||
628 | ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, | ||
629 | list); | ||
630 | len += snprintf(buf + len, size - len, | ||
631 | "txq[%i] first-ac: %p sched: %i\n", | ||
632 | i, ac, ac->sched); | ||
633 | if (list_empty(&ac->tid_q) || (len >= size)) | ||
634 | goto done_for; | ||
635 | tid = list_first_entry(&ac->tid_q, struct ath_atx_tid, | ||
636 | list); | ||
637 | len += snprintf(buf + len, size - len, | ||
638 | " first-tid: %p sched: %i paused: %i\n", | ||
639 | tid, tid->sched, tid->paused); | ||
640 | } | ||
641 | done_for: | ||
642 | spin_unlock_bh(&txq->axq_lock); | ||
643 | } | ||
644 | 551 | ||
645 | done: | ||
646 | if (len > size) | 552 | if (len > size) |
647 | len = size; | 553 | len = size; |
648 | 554 | ||
@@ -652,62 +558,41 @@ done: | |||
652 | return retval; | 558 | return retval; |
653 | } | 559 | } |
654 | 560 | ||
655 | static ssize_t read_file_stations(struct file *file, char __user *user_buf, | 561 | static ssize_t read_file_queues(struct file *file, char __user *user_buf, |
656 | size_t count, loff_t *ppos) | 562 | size_t count, loff_t *ppos) |
657 | { | 563 | { |
658 | struct ath_softc *sc = file->private_data; | 564 | struct ath_softc *sc = file->private_data; |
565 | struct ath_txq *txq; | ||
659 | char *buf; | 566 | char *buf; |
660 | unsigned int len = 0, size = 64000; | 567 | unsigned int len = 0, size = 1024; |
661 | struct ath_node *an = NULL; | ||
662 | ssize_t retval = 0; | 568 | ssize_t retval = 0; |
663 | int q; | 569 | int i; |
570 | char *qname[4] = {"VO", "VI", "BE", "BK"}; | ||
664 | 571 | ||
665 | buf = kzalloc(size, GFP_KERNEL); | 572 | buf = kzalloc(size, GFP_KERNEL); |
666 | if (buf == NULL) | 573 | if (buf == NULL) |
667 | return -ENOMEM; | 574 | return -ENOMEM; |
668 | 575 | ||
669 | len += snprintf(buf + len, size - len, | 576 | for (i = 0; i < IEEE80211_NUM_ACS; i++) { |
670 | "Stations:\n" | 577 | txq = sc->tx.txq_map[i]; |
671 | " tid: addr sched paused buf_q-empty an ac baw\n" | 578 | len += snprintf(buf + len, size - len, "(%s): ", qname[i]); |
672 | " ac: addr sched tid_q-empty txq\n"); | ||
673 | |||
674 | spin_lock(&sc->nodes_lock); | ||
675 | list_for_each_entry(an, &sc->nodes, list) { | ||
676 | unsigned short ma = an->maxampdu; | ||
677 | if (ma == 0) | ||
678 | ma = 65535; /* see ath_lookup_rate */ | ||
679 | len += snprintf(buf + len, size - len, | ||
680 | "iface: %pM sta: %pM max-ampdu: %hu mpdu-density: %uus\n", | ||
681 | an->vif->addr, an->sta->addr, ma, | ||
682 | (unsigned int)(an->mpdudensity)); | ||
683 | if (len >= size) | ||
684 | goto done; | ||
685 | |||
686 | for (q = 0; q < WME_NUM_TID; q++) { | ||
687 | struct ath_atx_tid *tid = &(an->tid[q]); | ||
688 | len += snprintf(buf + len, size - len, | ||
689 | " tid: %p %s %s %i %p %p %hu\n", | ||
690 | tid, tid->sched ? "sched" : "idle", | ||
691 | tid->paused ? "paused" : "running", | ||
692 | skb_queue_empty(&tid->buf_q), | ||
693 | tid->an, tid->ac, tid->baw_size); | ||
694 | if (len >= size) | ||
695 | goto done; | ||
696 | } | ||
697 | 579 | ||
698 | for (q = 0; q < WME_NUM_AC; q++) { | 580 | ath_txq_lock(sc, txq); |
699 | struct ath_atx_ac *ac = &(an->ac[q]); | 581 | |
700 | len += snprintf(buf + len, size - len, | 582 | len += snprintf(buf + len, size - len, "%s: %d ", |
701 | " ac: %p %s %i %p\n", | 583 | "qnum", txq->axq_qnum); |
702 | ac, ac->sched ? "sched" : "idle", | 584 | len += snprintf(buf + len, size - len, "%s: %2d ", |
703 | list_empty(&ac->tid_q), ac->txq); | 585 | "qdepth", txq->axq_depth); |
704 | if (len >= size) | 586 | len += snprintf(buf + len, size - len, "%s: %2d ", |
705 | goto done; | 587 | "ampdu-depth", txq->axq_ampdu_depth); |
706 | } | 588 | len += snprintf(buf + len, size - len, "%s: %3d ", |
589 | "pending", txq->pending_frames); | ||
590 | len += snprintf(buf + len, size - len, "%s: %d\n", | ||
591 | "stopped", txq->stopped); | ||
592 | |||
593 | ath_txq_unlock(sc, txq); | ||
707 | } | 594 | } |
708 | 595 | ||
709 | done: | ||
710 | spin_unlock(&sc->nodes_lock); | ||
711 | if (len > size) | 596 | if (len > size) |
712 | len = size; | 597 | len = size; |
713 | 598 | ||
@@ -837,6 +722,9 @@ static ssize_t read_file_reset(struct file *file, char __user *user_buf, | |||
837 | len += snprintf(buf + len, sizeof(buf) - len, | 722 | len += snprintf(buf + len, sizeof(buf) - len, |
838 | "%17s: %2d\n", "PLL RX Hang", | 723 | "%17s: %2d\n", "PLL RX Hang", |
839 | sc->debug.stats.reset[RESET_TYPE_PLL_HANG]); | 724 | sc->debug.stats.reset[RESET_TYPE_PLL_HANG]); |
725 | len += snprintf(buf + len, sizeof(buf) - len, | ||
726 | "%17s: %2d\n", "MCI Reset", | ||
727 | sc->debug.stats.reset[RESET_TYPE_MCI]); | ||
840 | 728 | ||
841 | if (len > sizeof(buf)) | 729 | if (len > sizeof(buf)) |
842 | len = sizeof(buf); | 730 | len = sizeof(buf); |
@@ -919,8 +807,8 @@ static const struct file_operations fops_xmit = { | |||
919 | .llseek = default_llseek, | 807 | .llseek = default_llseek, |
920 | }; | 808 | }; |
921 | 809 | ||
922 | static const struct file_operations fops_stations = { | 810 | static const struct file_operations fops_queues = { |
923 | .read = read_file_stations, | 811 | .read = read_file_queues, |
924 | .open = simple_open, | 812 | .open = simple_open, |
925 | .owner = THIS_MODULE, | 813 | .owner = THIS_MODULE, |
926 | .llseek = default_llseek, | 814 | .llseek = default_llseek, |
@@ -1599,8 +1487,14 @@ static ssize_t read_file_btcoex(struct file *file, char __user *user_buf, | |||
1599 | if (buf == NULL) | 1487 | if (buf == NULL) |
1600 | return -ENOMEM; | 1488 | return -ENOMEM; |
1601 | 1489 | ||
1602 | len = ath9k_dump_btcoex(sc, buf, len, size); | 1490 | if (!sc->sc_ah->common.btcoex_enabled) { |
1491 | len = snprintf(buf, size, "%s\n", | ||
1492 | "BTCOEX is disabled"); | ||
1493 | goto exit; | ||
1494 | } | ||
1603 | 1495 | ||
1496 | len = ath9k_dump_btcoex(sc, buf, size); | ||
1497 | exit: | ||
1604 | retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); | 1498 | retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); |
1605 | kfree(buf); | 1499 | kfree(buf); |
1606 | 1500 | ||
@@ -1638,16 +1532,16 @@ int ath9k_init_debug(struct ath_hw *ah) | |||
1638 | &fops_interrupt); | 1532 | &fops_interrupt); |
1639 | debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, sc, | 1533 | debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, sc, |
1640 | &fops_xmit); | 1534 | &fops_xmit); |
1535 | debugfs_create_file("queues", S_IRUSR, sc->debug.debugfs_phy, sc, | ||
1536 | &fops_queues); | ||
1641 | debugfs_create_u32("qlen_bk", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, | 1537 | debugfs_create_u32("qlen_bk", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, |
1642 | &sc->tx.txq_max_pending[WME_AC_BK]); | 1538 | &sc->tx.txq_max_pending[IEEE80211_AC_BK]); |
1643 | debugfs_create_u32("qlen_be", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, | 1539 | debugfs_create_u32("qlen_be", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, |
1644 | &sc->tx.txq_max_pending[WME_AC_BE]); | 1540 | &sc->tx.txq_max_pending[IEEE80211_AC_BE]); |
1645 | debugfs_create_u32("qlen_vi", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, | 1541 | debugfs_create_u32("qlen_vi", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, |
1646 | &sc->tx.txq_max_pending[WME_AC_VI]); | 1542 | &sc->tx.txq_max_pending[IEEE80211_AC_VI]); |
1647 | debugfs_create_u32("qlen_vo", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, | 1543 | debugfs_create_u32("qlen_vo", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, |
1648 | &sc->tx.txq_max_pending[WME_AC_VO]); | 1544 | &sc->tx.txq_max_pending[IEEE80211_AC_VO]); |
1649 | debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy, sc, | ||
1650 | &fops_stations); | ||
1651 | debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc, | 1545 | debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc, |
1652 | &fops_misc); | 1546 | &fops_misc); |
1653 | debugfs_create_file("reset", S_IRUSR, sc->debug.debugfs_phy, sc, | 1547 | debugfs_create_file("reset", S_IRUSR, sc->debug.debugfs_phy, sc, |
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 2ed9785a38fa..f9bee18de5a0 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h | |||
@@ -41,6 +41,7 @@ enum ath_reset_type { | |||
41 | RESET_TYPE_PLL_HANG, | 41 | RESET_TYPE_PLL_HANG, |
42 | RESET_TYPE_MAC_HANG, | 42 | RESET_TYPE_MAC_HANG, |
43 | RESET_TYPE_BEACON_STUCK, | 43 | RESET_TYPE_BEACON_STUCK, |
44 | RESET_TYPE_MCI, | ||
44 | __RESET_TYPE_MAX | 45 | __RESET_TYPE_MAX |
45 | }; | 46 | }; |
46 | 47 | ||
@@ -178,6 +179,21 @@ struct ath_tx_stats { | |||
178 | u32 txfailed; | 179 | u32 txfailed; |
179 | }; | 180 | }; |
180 | 181 | ||
182 | /* | ||
183 | * Various utility macros to print TX/Queue counters. | ||
184 | */ | ||
185 | #define PR_QNUM(_n) sc->tx.txq_map[_n]->axq_qnum | ||
186 | #define TXSTATS sc->debug.stats.txstats | ||
187 | #define PR(str, elem) \ | ||
188 | do { \ | ||
189 | len += snprintf(buf + len, size - len, \ | ||
190 | "%s%13u%11u%10u%10u\n", str, \ | ||
191 | TXSTATS[PR_QNUM(IEEE80211_AC_BE)].elem, \ | ||
192 | TXSTATS[PR_QNUM(IEEE80211_AC_BK)].elem, \ | ||
193 | TXSTATS[PR_QNUM(IEEE80211_AC_VI)].elem, \ | ||
194 | TXSTATS[PR_QNUM(IEEE80211_AC_VO)].elem); \ | ||
195 | } while(0) | ||
196 | |||
181 | #define RX_STAT_INC(c) (sc->debug.stats.rxstats.c++) | 197 | #define RX_STAT_INC(c) (sc->debug.stats.rxstats.c++) |
182 | 198 | ||
183 | /** | 199 | /** |
@@ -226,7 +242,7 @@ struct ath_rx_stats { | |||
226 | 242 | ||
227 | struct ath_stats { | 243 | struct ath_stats { |
228 | struct ath_interrupt_stats istats; | 244 | struct ath_interrupt_stats istats; |
229 | struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES]; | 245 | struct ath_tx_stats txstats[IEEE80211_NUM_ACS]; |
230 | struct ath_rx_stats rxstats; | 246 | struct ath_rx_stats rxstats; |
231 | struct ath_dfs_stats dfs_stats; | 247 | struct ath_dfs_stats dfs_stats; |
232 | u32 reset[__RESET_TYPE_MAX]; | 248 | u32 reset[__RESET_TYPE_MAX]; |
diff --git a/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c b/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c index ea2a6cf7ef23..24877b00cbf4 100644 --- a/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c +++ b/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c | |||
@@ -42,10 +42,15 @@ struct radar_types { | |||
42 | #define MIN_PPB_THRESH 50 | 42 | #define MIN_PPB_THRESH 50 |
43 | #define PPB_THRESH(PPB) ((PPB * MIN_PPB_THRESH + 50) / 100) | 43 | #define PPB_THRESH(PPB) ((PPB * MIN_PPB_THRESH + 50) / 100) |
44 | #define PRF2PRI(PRF) ((1000000 + PRF / 2) / PRF) | 44 | #define PRF2PRI(PRF) ((1000000 + PRF / 2) / PRF) |
45 | /* percentage of pulse width tolerance */ | ||
46 | #define WIDTH_TOLERANCE 5 | ||
47 | #define WIDTH_LOWER(X) ((X*(100-WIDTH_TOLERANCE)+50)/100) | ||
48 | #define WIDTH_UPPER(X) ((X*(100+WIDTH_TOLERANCE)+50)/100) | ||
45 | 49 | ||
46 | #define ETSI_PATTERN(ID, WMIN, WMAX, PMIN, PMAX, PRF, PPB) \ | 50 | #define ETSI_PATTERN(ID, WMIN, WMAX, PMIN, PMAX, PRF, PPB) \ |
47 | { \ | 51 | { \ |
48 | ID, WMIN, WMAX, (PRF2PRI(PMAX) - PRI_TOLERANCE), \ | 52 | ID, WIDTH_LOWER(WMIN), WIDTH_UPPER(WMAX), \ |
53 | (PRF2PRI(PMAX) - PRI_TOLERANCE), \ | ||
49 | (PRF2PRI(PMIN) * PRF + PRI_TOLERANCE), PRF, PPB * PRF, \ | 54 | (PRF2PRI(PMIN) * PRF + PRI_TOLERANCE), PRF, PPB * PRF, \ |
50 | PPB_THRESH(PPB), PRI_TOLERANCE, \ | 55 | PPB_THRESH(PPB), PRI_TOLERANCE, \ |
51 | } | 56 | } |
@@ -274,7 +279,7 @@ static bool dpd_set_domain(struct dfs_pattern_detector *dpd, | |||
274 | 279 | ||
275 | static struct dfs_pattern_detector default_dpd = { | 280 | static struct dfs_pattern_detector default_dpd = { |
276 | .exit = dpd_exit, | 281 | .exit = dpd_exit, |
277 | .set_domain = dpd_set_domain, | 282 | .set_dfs_domain = dpd_set_domain, |
278 | .add_pulse = dpd_add_pulse, | 283 | .add_pulse = dpd_add_pulse, |
279 | .region = NL80211_DFS_UNSET, | 284 | .region = NL80211_DFS_UNSET, |
280 | }; | 285 | }; |
@@ -291,10 +296,11 @@ dfs_pattern_detector_init(enum nl80211_dfs_regions region) | |||
291 | *dpd = default_dpd; | 296 | *dpd = default_dpd; |
292 | INIT_LIST_HEAD(&dpd->channel_detectors); | 297 | INIT_LIST_HEAD(&dpd->channel_detectors); |
293 | 298 | ||
294 | if (dpd->set_domain(dpd, region)) | 299 | if (dpd->set_dfs_domain(dpd, region)) |
295 | return dpd; | 300 | return dpd; |
296 | 301 | ||
297 | pr_err("Could not set DFS domain to %d. ", region); | 302 | pr_err("Could not set DFS domain to %d. ", region); |
303 | kfree(dpd); | ||
298 | return NULL; | 304 | return NULL; |
299 | } | 305 | } |
300 | EXPORT_SYMBOL(dfs_pattern_detector_init); | 306 | EXPORT_SYMBOL(dfs_pattern_detector_init); |
diff --git a/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.h b/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.h index fd0328a30995..cda52f39f28a 100644 --- a/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.h +++ b/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.h | |||
@@ -62,7 +62,7 @@ struct radar_detector_specs { | |||
62 | /** | 62 | /** |
63 | * struct dfs_pattern_detector - DFS pattern detector | 63 | * struct dfs_pattern_detector - DFS pattern detector |
64 | * @exit(): destructor | 64 | * @exit(): destructor |
65 | * @set_domain(): set DFS domain, resets detector lines upon domain changes | 65 | * @set_dfs_domain(): set DFS domain, resets detector lines upon domain changes |
66 | * @add_pulse(): add radar pulse to detector, returns true on detection | 66 | * @add_pulse(): add radar pulse to detector, returns true on detection |
67 | * @region: active DFS region, NL80211_DFS_UNSET until set | 67 | * @region: active DFS region, NL80211_DFS_UNSET until set |
68 | * @num_radar_types: number of different radar types | 68 | * @num_radar_types: number of different radar types |
@@ -72,7 +72,7 @@ struct radar_detector_specs { | |||
72 | */ | 72 | */ |
73 | struct dfs_pattern_detector { | 73 | struct dfs_pattern_detector { |
74 | void (*exit)(struct dfs_pattern_detector *dpd); | 74 | void (*exit)(struct dfs_pattern_detector *dpd); |
75 | bool (*set_domain)(struct dfs_pattern_detector *dpd, | 75 | bool (*set_dfs_domain)(struct dfs_pattern_detector *dpd, |
76 | enum nl80211_dfs_regions region); | 76 | enum nl80211_dfs_regions region); |
77 | bool (*add_pulse)(struct dfs_pattern_detector *dpd, | 77 | bool (*add_pulse)(struct dfs_pattern_detector *dpd, |
78 | struct pulse_event *pe); | 78 | struct pulse_event *pe); |
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index a8ea57b9f49c..4b412aaf4f36 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c | |||
@@ -247,6 +247,9 @@ static void ath_btcoex_period_timer(unsigned long data) | |||
247 | stomp_type = ATH_BTCOEX_STOMP_ALL; | 247 | stomp_type = ATH_BTCOEX_STOMP_ALL; |
248 | timer_period = btcoex->btscan_no_stomp; | 248 | timer_period = btcoex->btscan_no_stomp; |
249 | } | 249 | } |
250 | } else if (btcoex->stomp_audio >= 5) { | ||
251 | stomp_type = ATH_BTCOEX_STOMP_AUDIO; | ||
252 | btcoex->stomp_audio = 0; | ||
250 | } | 253 | } |
251 | 254 | ||
252 | ath9k_hw_btcoex_bt_stomp(ah, stomp_type); | 255 | ath9k_hw_btcoex_bt_stomp(ah, stomp_type); |
@@ -295,7 +298,7 @@ static void ath_btcoex_no_stomp_timer(void *arg) | |||
295 | (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && | 298 | (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && |
296 | test_bit(BT_OP_SCAN, &btcoex->op_flags))) | 299 | test_bit(BT_OP_SCAN, &btcoex->op_flags))) |
297 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); | 300 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); |
298 | else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) | 301 | else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) |
299 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW); | 302 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW); |
300 | 303 | ||
301 | ath9k_hw_btcoex_enable(ah); | 304 | ath9k_hw_btcoex_enable(ah); |
@@ -471,7 +474,7 @@ int ath9k_init_btcoex(struct ath_softc *sc) | |||
471 | r = ath_init_btcoex_timer(sc); | 474 | r = ath_init_btcoex_timer(sc); |
472 | if (r) | 475 | if (r) |
473 | return -1; | 476 | return -1; |
474 | txq = sc->tx.txq_map[WME_AC_BE]; | 477 | txq = sc->tx.txq_map[IEEE80211_AC_BE]; |
475 | ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum); | 478 | ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum); |
476 | sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; | 479 | sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; |
477 | if (ath9k_hw_mci_is_enabled(ah)) { | 480 | if (ath9k_hw_mci_is_enabled(ah)) { |
@@ -494,35 +497,31 @@ int ath9k_init_btcoex(struct ath_softc *sc) | |||
494 | return 0; | 497 | return 0; |
495 | } | 498 | } |
496 | 499 | ||
497 | int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, u32 len, u32 size) | 500 | static int ath9k_dump_mci_btcoex(struct ath_softc *sc, u8 *buf, u32 size) |
498 | { | 501 | { |
499 | #define ATH_DUMP_BTCOEX(_s, _val) \ | ||
500 | do { \ | ||
501 | len += snprintf(buf + len, size - len, \ | ||
502 | "%20s : %10d\n", _s, (_val)); \ | ||
503 | } while (0) | ||
504 | |||
505 | struct ath_btcoex *btcoex = &sc->btcoex; | 502 | struct ath_btcoex *btcoex = &sc->btcoex; |
506 | struct ath_mci_profile *mci = &btcoex->mci; | 503 | struct ath_mci_profile *mci = &btcoex->mci; |
507 | struct ath_hw *ah = sc->sc_ah; | 504 | struct ath_hw *ah = sc->sc_ah; |
508 | struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; | 505 | struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; |
506 | u32 len = 0; | ||
509 | int i; | 507 | int i; |
510 | 508 | ||
511 | ATH_DUMP_BTCOEX("Total BT profiles", NUM_PROF(mci)); | 509 | ATH_DUMP_BTCOEX("Total BT profiles", NUM_PROF(mci)); |
512 | ATH_DUMP_BTCOEX("Number of MGMT", mci->num_mgmt); | 510 | ATH_DUMP_BTCOEX("MGMT", mci->num_mgmt); |
513 | ATH_DUMP_BTCOEX("Number of SCO", mci->num_sco); | 511 | ATH_DUMP_BTCOEX("SCO", mci->num_sco); |
514 | ATH_DUMP_BTCOEX("Number of A2DP", mci->num_a2dp); | 512 | ATH_DUMP_BTCOEX("A2DP", mci->num_a2dp); |
515 | ATH_DUMP_BTCOEX("Number of HID", mci->num_hid); | 513 | ATH_DUMP_BTCOEX("HID", mci->num_hid); |
516 | ATH_DUMP_BTCOEX("Number of PAN", mci->num_pan); | 514 | ATH_DUMP_BTCOEX("PAN", mci->num_pan); |
517 | ATH_DUMP_BTCOEX("Number of ACL", mci->num_other_acl); | 515 | ATH_DUMP_BTCOEX("ACL", mci->num_other_acl); |
518 | ATH_DUMP_BTCOEX("Number of BDR", mci->num_bdr); | 516 | ATH_DUMP_BTCOEX("BDR", mci->num_bdr); |
519 | ATH_DUMP_BTCOEX("Aggr. Limit", mci->aggr_limit); | 517 | ATH_DUMP_BTCOEX("Aggr. Limit", mci->aggr_limit); |
520 | ATH_DUMP_BTCOEX("Stomp Type", btcoex->bt_stomp_type); | 518 | ATH_DUMP_BTCOEX("Stomp Type", btcoex->bt_stomp_type); |
521 | ATH_DUMP_BTCOEX("BTCoex Period (msec)", btcoex->btcoex_period); | 519 | ATH_DUMP_BTCOEX("BTCoex Period (msec)", btcoex->btcoex_period); |
522 | ATH_DUMP_BTCOEX("Duty Cycle", btcoex->duty_cycle); | 520 | ATH_DUMP_BTCOEX("Duty Cycle", btcoex->duty_cycle); |
523 | ATH_DUMP_BTCOEX("BT Wait time", btcoex->bt_wait_time); | 521 | ATH_DUMP_BTCOEX("BT Wait time", btcoex->bt_wait_time); |
524 | ATH_DUMP_BTCOEX("Concurrent Tx", btcoex_hw->mci.concur_tx); | 522 | ATH_DUMP_BTCOEX("Concurrent Tx", btcoex_hw->mci.concur_tx); |
525 | ATH_DUMP_BTCOEX("Concur RSSI count", btcoex->rssi_count); | 523 | ATH_DUMP_BTCOEX("Concurrent RSSI cnt", btcoex->rssi_count); |
524 | |||
526 | len += snprintf(buf + len, size - len, "BT Weights: "); | 525 | len += snprintf(buf + len, size - len, "BT Weights: "); |
527 | for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++) | 526 | for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++) |
528 | len += snprintf(buf + len, size - len, "%08x ", | 527 | len += snprintf(buf + len, size - len, "%08x ", |
@@ -537,9 +536,32 @@ int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, u32 len, u32 size) | |||
537 | for (i = 0; i < ATH_BTCOEX_STOMP_MAX; i++) | 536 | for (i = 0; i < ATH_BTCOEX_STOMP_MAX; i++) |
538 | len += snprintf(buf + len, size - len, "%08x ", | 537 | len += snprintf(buf + len, size - len, "%08x ", |
539 | btcoex_hw->tx_prio[i]); | 538 | btcoex_hw->tx_prio[i]); |
539 | |||
540 | len += snprintf(buf + len, size - len, "\n"); | 540 | len += snprintf(buf + len, size - len, "\n"); |
541 | #undef ATH_DUMP_BTCOEX | ||
542 | 541 | ||
543 | return len; | 542 | return len; |
544 | } | 543 | } |
544 | |||
545 | static int ath9k_dump_legacy_btcoex(struct ath_softc *sc, u8 *buf, u32 size) | ||
546 | { | ||
547 | |||
548 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
549 | u32 len = 0; | ||
550 | |||
551 | ATH_DUMP_BTCOEX("Stomp Type", btcoex->bt_stomp_type); | ||
552 | ATH_DUMP_BTCOEX("BTCoex Period (msec)", btcoex->btcoex_period); | ||
553 | ATH_DUMP_BTCOEX("Duty Cycle", btcoex->duty_cycle); | ||
554 | ATH_DUMP_BTCOEX("BT Wait time", btcoex->bt_wait_time); | ||
555 | |||
556 | return len; | ||
557 | } | ||
558 | |||
559 | int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, u32 size) | ||
560 | { | ||
561 | if (ath9k_hw_mci_is_enabled(sc->sc_ah)) | ||
562 | return ath9k_dump_mci_btcoex(sc, buf, size); | ||
563 | else | ||
564 | return ath9k_dump_legacy_btcoex(sc, buf, size); | ||
565 | } | ||
566 | |||
545 | #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ | 567 | #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ |
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index b30596fcf73a..96bfb18078fa 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h | |||
@@ -331,7 +331,7 @@ struct ath_tx_stats { | |||
331 | u32 skb_success; | 331 | u32 skb_success; |
332 | u32 skb_failed; | 332 | u32 skb_failed; |
333 | u32 cab_queued; | 333 | u32 cab_queued; |
334 | u32 queue_stats[WME_NUM_AC]; | 334 | u32 queue_stats[IEEE80211_NUM_ACS]; |
335 | }; | 335 | }; |
336 | 336 | ||
337 | struct ath_rx_stats { | 337 | struct ath_rx_stats { |
@@ -493,7 +493,7 @@ struct ath9k_htc_priv { | |||
493 | 493 | ||
494 | int beaconq; | 494 | int beaconq; |
495 | int cabq; | 495 | int cabq; |
496 | int hwq_map[WME_NUM_AC]; | 496 | int hwq_map[IEEE80211_NUM_ACS]; |
497 | 497 | ||
498 | #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT | 498 | #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT |
499 | struct ath_btcoex btcoex; | 499 | struct ath_btcoex btcoex; |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index f42d2eb6af99..d0ce1f5bba10 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | |||
@@ -33,7 +33,7 @@ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv) | |||
33 | qi.tqi_cwmin = 0; | 33 | qi.tqi_cwmin = 0; |
34 | qi.tqi_cwmax = 0; | 34 | qi.tqi_cwmax = 0; |
35 | } else if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) { | 35 | } else if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) { |
36 | int qnum = priv->hwq_map[WME_AC_BE]; | 36 | int qnum = priv->hwq_map[IEEE80211_AC_BE]; |
37 | 37 | ||
38 | ath9k_hw_get_txq_props(ah, qnum, &qi_be); | 38 | ath9k_hw_get_txq_props(ah, qnum, &qi_be); |
39 | 39 | ||
@@ -587,9 +587,9 @@ static bool ath9k_htc_check_beacon_config(struct ath9k_htc_priv *priv, | |||
587 | (priv->num_sta_vif > 1) && | 587 | (priv->num_sta_vif > 1) && |
588 | (vif->type == NL80211_IFTYPE_STATION)) { | 588 | (vif->type == NL80211_IFTYPE_STATION)) { |
589 | beacon_configured = false; | 589 | beacon_configured = false; |
590 | ieee80211_iterate_active_interfaces_atomic(priv->hw, | 590 | ieee80211_iterate_active_interfaces_atomic( |
591 | ath9k_htc_beacon_iter, | 591 | priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL, |
592 | &beacon_configured); | 592 | ath9k_htc_beacon_iter, &beacon_configured); |
593 | 593 | ||
594 | if (beacon_configured) { | 594 | if (beacon_configured) { |
595 | ath_dbg(common, CONFIG, | 595 | ath_dbg(common, CONFIG, |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c index 3035deb7a0cd..87110de577ef 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c | |||
@@ -218,16 +218,16 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, | |||
218 | 218 | ||
219 | len += snprintf(buf + len, sizeof(buf) - len, | 219 | len += snprintf(buf + len, sizeof(buf) - len, |
220 | "%20s : %10u\n", "BE queued", | 220 | "%20s : %10u\n", "BE queued", |
221 | priv->debug.tx_stats.queue_stats[WME_AC_BE]); | 221 | priv->debug.tx_stats.queue_stats[IEEE80211_AC_BE]); |
222 | len += snprintf(buf + len, sizeof(buf) - len, | 222 | len += snprintf(buf + len, sizeof(buf) - len, |
223 | "%20s : %10u\n", "BK queued", | 223 | "%20s : %10u\n", "BK queued", |
224 | priv->debug.tx_stats.queue_stats[WME_AC_BK]); | 224 | priv->debug.tx_stats.queue_stats[IEEE80211_AC_BK]); |
225 | len += snprintf(buf + len, sizeof(buf) - len, | 225 | len += snprintf(buf + len, sizeof(buf) - len, |
226 | "%20s : %10u\n", "VI queued", | 226 | "%20s : %10u\n", "VI queued", |
227 | priv->debug.tx_stats.queue_stats[WME_AC_VI]); | 227 | priv->debug.tx_stats.queue_stats[IEEE80211_AC_VI]); |
228 | len += snprintf(buf + len, sizeof(buf) - len, | 228 | len += snprintf(buf + len, sizeof(buf) - len, |
229 | "%20s : %10u\n", "VO queued", | 229 | "%20s : %10u\n", "VO queued", |
230 | priv->debug.tx_stats.queue_stats[WME_AC_VO]); | 230 | priv->debug.tx_stats.queue_stats[IEEE80211_AC_VO]); |
231 | 231 | ||
232 | if (len > sizeof(buf)) | 232 | if (len > sizeof(buf)) |
233 | len = sizeof(buf); | 233 | len = sizeof(buf); |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c index 0eacfc13c915..105582d6b714 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c | |||
@@ -207,7 +207,7 @@ void ath9k_htc_init_btcoex(struct ath9k_htc_priv *priv, char *product) | |||
207 | priv->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; | 207 | priv->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; |
208 | ath9k_hw_btcoex_init_3wire(priv->ah); | 208 | ath9k_hw_btcoex_init_3wire(priv->ah); |
209 | ath_htc_init_btcoex_work(priv); | 209 | ath_htc_init_btcoex_work(priv); |
210 | qnum = priv->hwq_map[WME_AC_BE]; | 210 | qnum = priv->hwq_map[IEEE80211_AC_BE]; |
211 | ath9k_hw_init_btcoex_hw(priv->ah, qnum); | 211 | ath9k_hw_init_btcoex_hw(priv->ah, qnum); |
212 | break; | 212 | break; |
213 | default: | 213 | default: |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 5ecf1287dddd..05d5ba66cac3 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
@@ -549,20 +549,20 @@ static int ath9k_init_queues(struct ath9k_htc_priv *priv) | |||
549 | goto err; | 549 | goto err; |
550 | } | 550 | } |
551 | 551 | ||
552 | if (!ath9k_htc_txq_setup(priv, WME_AC_BE)) { | 552 | if (!ath9k_htc_txq_setup(priv, IEEE80211_AC_BE)) { |
553 | ath_err(common, "Unable to setup xmit queue for BE traffic\n"); | 553 | ath_err(common, "Unable to setup xmit queue for BE traffic\n"); |
554 | goto err; | 554 | goto err; |
555 | } | 555 | } |
556 | 556 | ||
557 | if (!ath9k_htc_txq_setup(priv, WME_AC_BK)) { | 557 | if (!ath9k_htc_txq_setup(priv, IEEE80211_AC_BK)) { |
558 | ath_err(common, "Unable to setup xmit queue for BK traffic\n"); | 558 | ath_err(common, "Unable to setup xmit queue for BK traffic\n"); |
559 | goto err; | 559 | goto err; |
560 | } | 560 | } |
561 | if (!ath9k_htc_txq_setup(priv, WME_AC_VI)) { | 561 | if (!ath9k_htc_txq_setup(priv, IEEE80211_AC_VI)) { |
562 | ath_err(common, "Unable to setup xmit queue for VI traffic\n"); | 562 | ath_err(common, "Unable to setup xmit queue for VI traffic\n"); |
563 | goto err; | 563 | goto err; |
564 | } | 564 | } |
565 | if (!ath9k_htc_txq_setup(priv, WME_AC_VO)) { | 565 | if (!ath9k_htc_txq_setup(priv, IEEE80211_AC_VO)) { |
566 | ath_err(common, "Unable to setup xmit queue for VO traffic\n"); | 566 | ath_err(common, "Unable to setup xmit queue for VO traffic\n"); |
567 | goto err; | 567 | goto err; |
568 | } | 568 | } |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 66f6a74c508e..9c07a8fa5134 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
@@ -127,8 +127,9 @@ static void ath9k_htc_vif_reconfig(struct ath9k_htc_priv *priv) | |||
127 | priv->rearm_ani = false; | 127 | priv->rearm_ani = false; |
128 | priv->reconfig_beacon = false; | 128 | priv->reconfig_beacon = false; |
129 | 129 | ||
130 | ieee80211_iterate_active_interfaces_atomic(priv->hw, | 130 | ieee80211_iterate_active_interfaces_atomic( |
131 | ath9k_htc_vif_iter, priv); | 131 | priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL, |
132 | ath9k_htc_vif_iter, priv); | ||
132 | if (priv->rearm_ani) | 133 | if (priv->rearm_ani) |
133 | ath9k_htc_start_ani(priv); | 134 | ath9k_htc_start_ani(priv); |
134 | 135 | ||
@@ -165,8 +166,9 @@ static void ath9k_htc_set_bssid_mask(struct ath9k_htc_priv *priv, | |||
165 | ath9k_htc_bssid_iter(&iter_data, vif->addr, vif); | 166 | ath9k_htc_bssid_iter(&iter_data, vif->addr, vif); |
166 | 167 | ||
167 | /* Get list of all active MAC addresses */ | 168 | /* Get list of all active MAC addresses */ |
168 | ieee80211_iterate_active_interfaces_atomic(priv->hw, ath9k_htc_bssid_iter, | 169 | ieee80211_iterate_active_interfaces_atomic( |
169 | &iter_data); | 170 | priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL, |
171 | ath9k_htc_bssid_iter, &iter_data); | ||
170 | 172 | ||
171 | memcpy(common->bssidmask, iter_data.mask, ETH_ALEN); | 173 | memcpy(common->bssidmask, iter_data.mask, ETH_ALEN); |
172 | ath_hw_setbssidmask(common); | 174 | ath_hw_setbssidmask(common); |
@@ -1144,8 +1146,9 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw, | |||
1144 | */ | 1146 | */ |
1145 | if ((vif->type == NL80211_IFTYPE_AP) && (priv->num_ap_vif == 0)) { | 1147 | if ((vif->type == NL80211_IFTYPE_AP) && (priv->num_ap_vif == 0)) { |
1146 | priv->rearm_ani = false; | 1148 | priv->rearm_ani = false; |
1147 | ieee80211_iterate_active_interfaces_atomic(priv->hw, | 1149 | ieee80211_iterate_active_interfaces_atomic( |
1148 | ath9k_htc_vif_iter, priv); | 1150 | priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL, |
1151 | ath9k_htc_vif_iter, priv); | ||
1149 | if (!priv->rearm_ani) | 1152 | if (!priv->rearm_ani) |
1150 | ath9k_htc_stop_ani(priv); | 1153 | ath9k_htc_stop_ani(priv); |
1151 | } | 1154 | } |
@@ -1346,7 +1349,7 @@ static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, | |||
1346 | struct ath9k_tx_queue_info qi; | 1349 | struct ath9k_tx_queue_info qi; |
1347 | int ret = 0, qnum; | 1350 | int ret = 0, qnum; |
1348 | 1351 | ||
1349 | if (queue >= WME_NUM_AC) | 1352 | if (queue >= IEEE80211_NUM_ACS) |
1350 | return 0; | 1353 | return 0; |
1351 | 1354 | ||
1352 | mutex_lock(&priv->mutex); | 1355 | mutex_lock(&priv->mutex); |
@@ -1373,7 +1376,7 @@ static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, | |||
1373 | } | 1376 | } |
1374 | 1377 | ||
1375 | if ((priv->ah->opmode == NL80211_IFTYPE_ADHOC) && | 1378 | if ((priv->ah->opmode == NL80211_IFTYPE_ADHOC) && |
1376 | (qnum == priv->hwq_map[WME_AC_BE])) | 1379 | (qnum == priv->hwq_map[IEEE80211_AC_BE])) |
1377 | ath9k_htc_beaconq_config(priv); | 1380 | ath9k_htc_beaconq_config(priv); |
1378 | out: | 1381 | out: |
1379 | ath9k_htc_ps_restore(priv); | 1382 | ath9k_htc_ps_restore(priv); |
@@ -1466,8 +1469,9 @@ static void ath9k_htc_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | |||
1466 | static void ath9k_htc_choose_set_bssid(struct ath9k_htc_priv *priv) | 1469 | static void ath9k_htc_choose_set_bssid(struct ath9k_htc_priv *priv) |
1467 | { | 1470 | { |
1468 | if (priv->num_sta_assoc_vif == 1) { | 1471 | if (priv->num_sta_assoc_vif == 1) { |
1469 | ieee80211_iterate_active_interfaces_atomic(priv->hw, | 1472 | ieee80211_iterate_active_interfaces_atomic( |
1470 | ath9k_htc_bss_iter, priv); | 1473 | priv->hw, IEEE80211_IFACE_ITER_RESUME_ALL, |
1474 | ath9k_htc_bss_iter, priv); | ||
1471 | ath9k_htc_set_bssid(priv); | 1475 | ath9k_htc_set_bssid(priv); |
1472 | } | 1476 | } |
1473 | } | 1477 | } |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 06cdcb772d78..28cd50ee521a 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | |||
@@ -21,10 +21,10 @@ | |||
21 | /******/ | 21 | /******/ |
22 | 22 | ||
23 | static const int subtype_txq_to_hwq[] = { | 23 | static const int subtype_txq_to_hwq[] = { |
24 | [WME_AC_BE] = ATH_TXQ_AC_BE, | 24 | [IEEE80211_AC_BE] = ATH_TXQ_AC_BE, |
25 | [WME_AC_BK] = ATH_TXQ_AC_BK, | 25 | [IEEE80211_AC_BK] = ATH_TXQ_AC_BK, |
26 | [WME_AC_VI] = ATH_TXQ_AC_VI, | 26 | [IEEE80211_AC_VI] = ATH_TXQ_AC_VI, |
27 | [WME_AC_VO] = ATH_TXQ_AC_VO, | 27 | [IEEE80211_AC_VO] = ATH_TXQ_AC_VO, |
28 | }; | 28 | }; |
29 | 29 | ||
30 | #define ATH9K_HTC_INIT_TXQ(subtype) do { \ | 30 | #define ATH9K_HTC_INIT_TXQ(subtype) do { \ |
@@ -41,15 +41,15 @@ int get_hw_qnum(u16 queue, int *hwq_map) | |||
41 | { | 41 | { |
42 | switch (queue) { | 42 | switch (queue) { |
43 | case 0: | 43 | case 0: |
44 | return hwq_map[WME_AC_VO]; | 44 | return hwq_map[IEEE80211_AC_VO]; |
45 | case 1: | 45 | case 1: |
46 | return hwq_map[WME_AC_VI]; | 46 | return hwq_map[IEEE80211_AC_VI]; |
47 | case 2: | 47 | case 2: |
48 | return hwq_map[WME_AC_BE]; | 48 | return hwq_map[IEEE80211_AC_BE]; |
49 | case 3: | 49 | case 3: |
50 | return hwq_map[WME_AC_BK]; | 50 | return hwq_map[IEEE80211_AC_BK]; |
51 | default: | 51 | default: |
52 | return hwq_map[WME_AC_BE]; | 52 | return hwq_map[IEEE80211_AC_BE]; |
53 | } | 53 | } |
54 | } | 54 | } |
55 | 55 | ||
@@ -106,20 +106,20 @@ static inline enum htc_endpoint_id get_htc_epid(struct ath9k_htc_priv *priv, | |||
106 | 106 | ||
107 | switch (qnum) { | 107 | switch (qnum) { |
108 | case 0: | 108 | case 0: |
109 | TX_QSTAT_INC(WME_AC_VO); | 109 | TX_QSTAT_INC(IEEE80211_AC_VO); |
110 | epid = priv->data_vo_ep; | 110 | epid = priv->data_vo_ep; |
111 | break; | 111 | break; |
112 | case 1: | 112 | case 1: |
113 | TX_QSTAT_INC(WME_AC_VI); | 113 | TX_QSTAT_INC(IEEE80211_AC_VI); |
114 | epid = priv->data_vi_ep; | 114 | epid = priv->data_vi_ep; |
115 | break; | 115 | break; |
116 | case 2: | 116 | case 2: |
117 | TX_QSTAT_INC(WME_AC_BE); | 117 | TX_QSTAT_INC(IEEE80211_AC_BE); |
118 | epid = priv->data_be_ep; | 118 | epid = priv->data_be_ep; |
119 | break; | 119 | break; |
120 | case 3: | 120 | case 3: |
121 | default: | 121 | default: |
122 | TX_QSTAT_INC(WME_AC_BK); | 122 | TX_QSTAT_INC(IEEE80211_AC_BK); |
123 | epid = priv->data_bk_ep; | 123 | epid = priv->data_bk_ep; |
124 | break; | 124 | break; |
125 | } | 125 | } |
@@ -1082,7 +1082,7 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, | |||
1082 | rx_status->freq = hw->conf.channel->center_freq; | 1082 | rx_status->freq = hw->conf.channel->center_freq; |
1083 | rx_status->signal = rxbuf->rxstatus.rs_rssi + ATH_DEFAULT_NOISE_FLOOR; | 1083 | rx_status->signal = rxbuf->rxstatus.rs_rssi + ATH_DEFAULT_NOISE_FLOOR; |
1084 | rx_status->antenna = rxbuf->rxstatus.rs_antenna; | 1084 | rx_status->antenna = rxbuf->rxstatus.rs_antenna; |
1085 | rx_status->flag |= RX_FLAG_MACTIME_MPDU; | 1085 | rx_status->flag |= RX_FLAG_MACTIME_START; |
1086 | 1086 | ||
1087 | return true; | 1087 | return true; |
1088 | 1088 | ||
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 741e73dece35..e06bcec655a7 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -2561,11 +2561,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
2561 | pCap->hw_caps |= ATH9K_HW_CAP_ANT_DIV_COMB; | 2561 | pCap->hw_caps |= ATH9K_HW_CAP_ANT_DIV_COMB; |
2562 | } | 2562 | } |
2563 | 2563 | ||
2564 | if (AR_SREV_9485_10(ah)) { | ||
2565 | pCap->pcie_lcr_extsync_en = true; | ||
2566 | pCap->pcie_lcr_offset = 0x80; | ||
2567 | } | ||
2568 | |||
2569 | if (ath9k_hw_dfs_tested(ah)) | 2564 | if (ath9k_hw_dfs_tested(ah)) |
2570 | pCap->hw_caps |= ATH9K_HW_CAP_DFS; | 2565 | pCap->hw_caps |= ATH9K_HW_CAP_DFS; |
2571 | 2566 | ||
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 3e73bfe2315e..3636dabf03e1 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -273,8 +273,6 @@ struct ath9k_hw_capabilities { | |||
273 | u8 rx_status_len; | 273 | u8 rx_status_len; |
274 | u8 tx_desc_len; | 274 | u8 tx_desc_len; |
275 | u8 txs_len; | 275 | u8 txs_len; |
276 | u16 pcie_lcr_offset; | ||
277 | bool pcie_lcr_extsync_en; | ||
278 | }; | 276 | }; |
279 | 277 | ||
280 | struct ath9k_ops_config { | 278 | struct ath9k_ops_config { |
@@ -877,7 +875,6 @@ struct ath_hw { | |||
877 | struct ar5416IniArray iniModesTxGain; | 875 | struct ar5416IniArray iniModesTxGain; |
878 | struct ar5416IniArray iniCckfirNormal; | 876 | struct ar5416IniArray iniCckfirNormal; |
879 | struct ar5416IniArray iniCckfirJapan2484; | 877 | struct ar5416IniArray iniCckfirJapan2484; |
880 | struct ar5416IniArray ini_japan2484; | ||
881 | struct ar5416IniArray iniModes_9271_ANI_reg; | 878 | struct ar5416IniArray iniModes_9271_ANI_reg; |
882 | struct ar5416IniArray ini_radio_post_sys2ant; | 879 | struct ar5416IniArray ini_radio_post_sys2ant; |
883 | 880 | ||
@@ -930,7 +927,6 @@ struct ath_bus_ops { | |||
930 | void (*read_cachesize)(struct ath_common *common, int *csz); | 927 | void (*read_cachesize)(struct ath_common *common, int *csz); |
931 | bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); | 928 | bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); |
932 | void (*bt_coex_prep)(struct ath_common *common); | 929 | void (*bt_coex_prep)(struct ath_common *common); |
933 | void (*extn_synch_en)(struct ath_common *common); | ||
934 | void (*aspm_init)(struct ath_common *common); | 930 | void (*aspm_init)(struct ath_common *common); |
935 | }; | 931 | }; |
936 | 932 | ||
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 546bae93647b..80cae53a33e5 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -435,7 +435,7 @@ static int ath9k_init_queues(struct ath_softc *sc) | |||
435 | sc->config.cabqReadytime = ATH_CABQ_READY_TIME; | 435 | sc->config.cabqReadytime = ATH_CABQ_READY_TIME; |
436 | ath_cabq_update(sc); | 436 | ath_cabq_update(sc); |
437 | 437 | ||
438 | for (i = 0; i < WME_NUM_AC; i++) { | 438 | for (i = 0; i < IEEE80211_NUM_ACS; i++) { |
439 | sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i); | 439 | sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i); |
440 | sc->tx.txq_map[i]->mac80211_qnum = i; | 440 | sc->tx.txq_map[i]->mac80211_qnum = i; |
441 | sc->tx.txq_max_pending[i] = ATH_MAX_QDEPTH; | 441 | sc->tx.txq_max_pending[i] = ATH_MAX_QDEPTH; |
@@ -563,10 +563,6 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | |||
563 | spin_lock_init(&sc->sc_serial_rw); | 563 | spin_lock_init(&sc->sc_serial_rw); |
564 | spin_lock_init(&sc->sc_pm_lock); | 564 | spin_lock_init(&sc->sc_pm_lock); |
565 | mutex_init(&sc->mutex); | 565 | mutex_init(&sc->mutex); |
566 | #ifdef CONFIG_ATH9K_DEBUGFS | ||
567 | spin_lock_init(&sc->nodes_lock); | ||
568 | INIT_LIST_HEAD(&sc->nodes); | ||
569 | #endif | ||
570 | #ifdef CONFIG_ATH9K_MAC_DEBUG | 566 | #ifdef CONFIG_ATH9K_MAC_DEBUG |
571 | spin_lock_init(&sc->debug.samp_lock); | 567 | spin_lock_init(&sc->debug.samp_lock); |
572 | #endif | 568 | #endif |
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c index 223b9693527e..fc6b075ad635 100644 --- a/drivers/net/wireless/ath/ath9k/link.c +++ b/drivers/net/wireless/ath/ath9k/link.c | |||
@@ -27,9 +27,6 @@ void ath_tx_complete_poll_work(struct work_struct *work) | |||
27 | struct ath_txq *txq; | 27 | struct ath_txq *txq; |
28 | int i; | 28 | int i; |
29 | bool needreset = false; | 29 | bool needreset = false; |
30 | #ifdef CONFIG_ATH9K_DEBUGFS | ||
31 | sc->tx_complete_poll_work_seen++; | ||
32 | #endif | ||
33 | 30 | ||
34 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) | 31 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) |
35 | if (ATH_TXQ_SETUP(sc, i)) { | 32 | if (ATH_TXQ_SETUP(sc, i)) { |
@@ -211,7 +208,7 @@ static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int | |||
211 | int time_left; | 208 | int time_left; |
212 | 209 | ||
213 | memset(&txctl, 0, sizeof(txctl)); | 210 | memset(&txctl, 0, sizeof(txctl)); |
214 | txctl.txq = sc->tx.txq_map[WME_AC_BE]; | 211 | txctl.txq = sc->tx.txq_map[IEEE80211_AC_BE]; |
215 | 212 | ||
216 | memset(tx_info, 0, sizeof(*tx_info)); | 213 | memset(tx_info, 0, sizeof(*tx_info)); |
217 | tx_info->band = hw->conf.channel->band; | 214 | tx_info->band = hw->conf.channel->band; |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 578a7234aa56..0653dbc99e31 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -331,11 +331,6 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, | |||
331 | u8 density; | 331 | u8 density; |
332 | an = (struct ath_node *)sta->drv_priv; | 332 | an = (struct ath_node *)sta->drv_priv; |
333 | 333 | ||
334 | #ifdef CONFIG_ATH9K_DEBUGFS | ||
335 | spin_lock(&sc->nodes_lock); | ||
336 | list_add(&an->list, &sc->nodes); | ||
337 | spin_unlock(&sc->nodes_lock); | ||
338 | #endif | ||
339 | an->sta = sta; | 334 | an->sta = sta; |
340 | an->vif = vif; | 335 | an->vif = vif; |
341 | 336 | ||
@@ -352,13 +347,6 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) | |||
352 | { | 347 | { |
353 | struct ath_node *an = (struct ath_node *)sta->drv_priv; | 348 | struct ath_node *an = (struct ath_node *)sta->drv_priv; |
354 | 349 | ||
355 | #ifdef CONFIG_ATH9K_DEBUGFS | ||
356 | spin_lock(&sc->nodes_lock); | ||
357 | list_del(&an->list); | ||
358 | spin_unlock(&sc->nodes_lock); | ||
359 | an->sta = NULL; | ||
360 | #endif | ||
361 | |||
362 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) | 350 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) |
363 | ath_tx_node_cleanup(sc, an); | 351 | ath_tx_node_cleanup(sc, an); |
364 | } | 352 | } |
@@ -494,17 +482,6 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
494 | if (status & SCHED_INTR) | 482 | if (status & SCHED_INTR) |
495 | sched = true; | 483 | sched = true; |
496 | 484 | ||
497 | #ifdef CONFIG_PM_SLEEP | ||
498 | if (status & ATH9K_INT_BMISS) { | ||
499 | if (atomic_read(&sc->wow_sleep_proc_intr) == 0) { | ||
500 | ath_dbg(common, ANY, "during WoW we got a BMISS\n"); | ||
501 | atomic_inc(&sc->wow_got_bmiss_intr); | ||
502 | atomic_dec(&sc->wow_sleep_proc_intr); | ||
503 | } | ||
504 | ath_dbg(common, INTERRUPT, "beacon miss interrupt\n"); | ||
505 | } | ||
506 | #endif | ||
507 | |||
508 | /* | 485 | /* |
509 | * If a FATAL or RXORN interrupt is received, we have to reset the | 486 | * If a FATAL or RXORN interrupt is received, we have to reset the |
510 | * chip immediately. | 487 | * chip immediately. |
@@ -523,7 +500,15 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
523 | 500 | ||
524 | goto chip_reset; | 501 | goto chip_reset; |
525 | } | 502 | } |
526 | 503 | #ifdef CONFIG_PM_SLEEP | |
504 | if (status & ATH9K_INT_BMISS) { | ||
505 | if (atomic_read(&sc->wow_sleep_proc_intr) == 0) { | ||
506 | ath_dbg(common, ANY, "during WoW we got a BMISS\n"); | ||
507 | atomic_inc(&sc->wow_got_bmiss_intr); | ||
508 | atomic_dec(&sc->wow_sleep_proc_intr); | ||
509 | } | ||
510 | } | ||
511 | #endif | ||
527 | if (status & ATH9K_INT_SWBA) | 512 | if (status & ATH9K_INT_SWBA) |
528 | tasklet_schedule(&sc->bcon_tasklet); | 513 | tasklet_schedule(&sc->bcon_tasklet); |
529 | 514 | ||
@@ -686,9 +671,6 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
686 | 671 | ||
687 | spin_unlock_bh(&sc->sc_pcu_lock); | 672 | spin_unlock_bh(&sc->sc_pcu_lock); |
688 | 673 | ||
689 | if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en) | ||
690 | common->bus_ops->extn_synch_en(common); | ||
691 | |||
692 | mutex_unlock(&sc->mutex); | 674 | mutex_unlock(&sc->mutex); |
693 | 675 | ||
694 | ath9k_ps_restore(sc); | 676 | ath9k_ps_restore(sc); |
@@ -924,8 +906,9 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw, | |||
924 | ath9k_vif_iter(iter_data, vif->addr, vif); | 906 | ath9k_vif_iter(iter_data, vif->addr, vif); |
925 | 907 | ||
926 | /* Get list of all active MAC addresses */ | 908 | /* Get list of all active MAC addresses */ |
927 | ieee80211_iterate_active_interfaces_atomic(sc->hw, ath9k_vif_iter, | 909 | ieee80211_iterate_active_interfaces_atomic( |
928 | iter_data); | 910 | sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL, |
911 | ath9k_vif_iter, iter_data); | ||
929 | } | 912 | } |
930 | 913 | ||
931 | /* Called with sc->mutex held. */ | 914 | /* Called with sc->mutex held. */ |
@@ -975,8 +958,9 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, | |||
975 | if (ah->opmode == NL80211_IFTYPE_STATION && | 958 | if (ah->opmode == NL80211_IFTYPE_STATION && |
976 | old_opmode == NL80211_IFTYPE_AP && | 959 | old_opmode == NL80211_IFTYPE_AP && |
977 | test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) { | 960 | test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) { |
978 | ieee80211_iterate_active_interfaces_atomic(sc->hw, | 961 | ieee80211_iterate_active_interfaces_atomic( |
979 | ath9k_sta_vif_iter, sc); | 962 | sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL, |
963 | ath9k_sta_vif_iter, sc); | ||
980 | } | 964 | } |
981 | } | 965 | } |
982 | 966 | ||
@@ -1329,7 +1313,7 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, | |||
1329 | struct ath9k_tx_queue_info qi; | 1313 | struct ath9k_tx_queue_info qi; |
1330 | int ret = 0; | 1314 | int ret = 0; |
1331 | 1315 | ||
1332 | if (queue >= WME_NUM_AC) | 1316 | if (queue >= IEEE80211_NUM_ACS) |
1333 | return 0; | 1317 | return 0; |
1334 | 1318 | ||
1335 | txq = sc->tx.txq_map[queue]; | 1319 | txq = sc->tx.txq_map[queue]; |
@@ -1505,8 +1489,9 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
1505 | clear_bit(SC_OP_BEACONS, &sc->sc_flags); | 1489 | clear_bit(SC_OP_BEACONS, &sc->sc_flags); |
1506 | } | 1490 | } |
1507 | 1491 | ||
1508 | ieee80211_iterate_active_interfaces_atomic(sc->hw, | 1492 | ieee80211_iterate_active_interfaces_atomic( |
1509 | ath9k_bss_assoc_iter, sc); | 1493 | sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL, |
1494 | ath9k_bss_assoc_iter, sc); | ||
1510 | 1495 | ||
1511 | if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags) && | 1496 | if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags) && |
1512 | ah->opmode == NL80211_IFTYPE_STATION) { | 1497 | ah->opmode == NL80211_IFTYPE_STATION) { |
@@ -1956,13 +1941,12 @@ static int ath9k_get_et_sset_count(struct ieee80211_hw *hw, | |||
1956 | return 0; | 1941 | return 0; |
1957 | } | 1942 | } |
1958 | 1943 | ||
1959 | #define PR_QNUM(_n) (sc->tx.txq_map[_n]->axq_qnum) | ||
1960 | #define AWDATA(elem) \ | 1944 | #define AWDATA(elem) \ |
1961 | do { \ | 1945 | do { \ |
1962 | data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].elem; \ | 1946 | data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].elem; \ |
1963 | data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].elem; \ | 1947 | data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].elem; \ |
1964 | data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].elem; \ | 1948 | data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].elem; \ |
1965 | data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].elem; \ | 1949 | data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].elem; \ |
1966 | } while (0) | 1950 | } while (0) |
1967 | 1951 | ||
1968 | #define AWDATA_RX(elem) \ | 1952 | #define AWDATA_RX(elem) \ |
@@ -1977,14 +1961,14 @@ static void ath9k_get_et_stats(struct ieee80211_hw *hw, | |||
1977 | struct ath_softc *sc = hw->priv; | 1961 | struct ath_softc *sc = hw->priv; |
1978 | int i = 0; | 1962 | int i = 0; |
1979 | 1963 | ||
1980 | data[i++] = (sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].tx_pkts_all + | 1964 | data[i++] = (sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_pkts_all + |
1981 | sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].tx_pkts_all + | 1965 | sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].tx_pkts_all + |
1982 | sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].tx_pkts_all + | 1966 | sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].tx_pkts_all + |
1983 | sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].tx_pkts_all); | 1967 | sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].tx_pkts_all); |
1984 | data[i++] = (sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].tx_bytes_all + | 1968 | data[i++] = (sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_bytes_all + |
1985 | sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].tx_bytes_all + | 1969 | sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].tx_bytes_all + |
1986 | sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].tx_bytes_all + | 1970 | sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].tx_bytes_all + |
1987 | sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].tx_bytes_all); | 1971 | sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].tx_bytes_all); |
1988 | AWDATA_RX(rx_pkts_all); | 1972 | AWDATA_RX(rx_pkts_all); |
1989 | AWDATA_RX(rx_bytes_all); | 1973 | AWDATA_RX(rx_bytes_all); |
1990 | 1974 | ||
diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index 0dd2cbb52d65..706378ea3ba2 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c | |||
@@ -207,23 +207,6 @@ skip_tuning: | |||
207 | ath9k_btcoex_timer_resume(sc); | 207 | ath9k_btcoex_timer_resume(sc); |
208 | } | 208 | } |
209 | 209 | ||
210 | static void ath_mci_wait_btcal_done(struct ath_softc *sc) | ||
211 | { | ||
212 | struct ath_hw *ah = sc->sc_ah; | ||
213 | |||
214 | /* Stop tx & rx */ | ||
215 | ieee80211_stop_queues(sc->hw); | ||
216 | ath_stoprecv(sc); | ||
217 | ath_drain_all_txq(sc, false); | ||
218 | |||
219 | /* Wait for cal done */ | ||
220 | ar9003_mci_start_reset(ah, ah->curchan); | ||
221 | |||
222 | /* Resume tx & rx */ | ||
223 | ath_startrecv(sc); | ||
224 | ieee80211_wake_queues(sc->hw); | ||
225 | } | ||
226 | |||
227 | static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) | 210 | static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) |
228 | { | 211 | { |
229 | struct ath_hw *ah = sc->sc_ah; | 212 | struct ath_hw *ah = sc->sc_ah; |
@@ -235,7 +218,7 @@ static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) | |||
235 | case MCI_GPM_BT_CAL_REQ: | 218 | case MCI_GPM_BT_CAL_REQ: |
236 | if (mci_hw->bt_state == MCI_BT_AWAKE) { | 219 | if (mci_hw->bt_state == MCI_BT_AWAKE) { |
237 | mci_hw->bt_state = MCI_BT_CAL_START; | 220 | mci_hw->bt_state = MCI_BT_CAL_START; |
238 | ath_mci_wait_btcal_done(sc); | 221 | ath9k_queue_reset(sc, RESET_TYPE_MCI); |
239 | } | 222 | } |
240 | ath_dbg(common, MCI, "MCI State : %d\n", mci_hw->bt_state); | 223 | ath_dbg(common, MCI, "MCI State : %d\n", mci_hw->bt_state); |
241 | break; | 224 | break; |
@@ -578,6 +561,8 @@ void ath_mci_intr(struct ath_softc *sc) | |||
578 | mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_GPM; | 561 | mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_GPM; |
579 | 562 | ||
580 | while (more_data == MCI_GPM_MORE) { | 563 | while (more_data == MCI_GPM_MORE) { |
564 | if (test_bit(SC_OP_HW_RESET, &sc->sc_flags)) | ||
565 | return; | ||
581 | 566 | ||
582 | pgpm = mci->gpm_buf.bf_addr; | 567 | pgpm = mci->gpm_buf.bf_addr; |
583 | offset = ar9003_mci_get_next_gpm_offset(ah, false, | 568 | offset = ar9003_mci_get_next_gpm_offset(ah, false, |
@@ -744,12 +729,30 @@ void ath9k_mci_set_txpower(struct ath_softc *sc, bool setchannel, | |||
744 | ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit, false); | 729 | ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit, false); |
745 | } | 730 | } |
746 | 731 | ||
732 | static void ath9k_mci_stomp_audio(struct ath_softc *sc) | ||
733 | { | ||
734 | struct ath_hw *ah = sc->sc_ah; | ||
735 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
736 | struct ath_mci_profile *mci = &btcoex->mci; | ||
737 | |||
738 | if (!mci->num_sco && !mci->num_a2dp) | ||
739 | return; | ||
740 | |||
741 | if (ah->stats.avgbrssi > 25) { | ||
742 | btcoex->stomp_audio = 0; | ||
743 | return; | ||
744 | } | ||
745 | |||
746 | btcoex->stomp_audio++; | ||
747 | } | ||
747 | void ath9k_mci_update_rssi(struct ath_softc *sc) | 748 | void ath9k_mci_update_rssi(struct ath_softc *sc) |
748 | { | 749 | { |
749 | struct ath_hw *ah = sc->sc_ah; | 750 | struct ath_hw *ah = sc->sc_ah; |
750 | struct ath_btcoex *btcoex = &sc->btcoex; | 751 | struct ath_btcoex *btcoex = &sc->btcoex; |
751 | struct ath9k_hw_mci *mci_hw = &sc->sc_ah->btcoex_hw.mci; | 752 | struct ath9k_hw_mci *mci_hw = &sc->sc_ah->btcoex_hw.mci; |
752 | 753 | ||
754 | ath9k_mci_stomp_audio(sc); | ||
755 | |||
753 | if (!(mci_hw->config & ATH_MCI_CONFIG_CONCUR_TX)) | 756 | if (!(mci_hw->config & ATH_MCI_CONFIG_CONCUR_TX)) |
754 | return; | 757 | return; |
755 | 758 | ||
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index f088f4bf9a26..9553203ee624 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c | |||
@@ -96,17 +96,6 @@ static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data) | |||
96 | return true; | 96 | return true; |
97 | } | 97 | } |
98 | 98 | ||
99 | static void ath_pci_extn_synch_enable(struct ath_common *common) | ||
100 | { | ||
101 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
102 | struct pci_dev *pdev = to_pci_dev(sc->dev); | ||
103 | u8 lnkctl; | ||
104 | |||
105 | pci_read_config_byte(pdev, sc->sc_ah->caps.pcie_lcr_offset, &lnkctl); | ||
106 | lnkctl |= PCI_EXP_LNKCTL_ES; | ||
107 | pci_write_config_byte(pdev, sc->sc_ah->caps.pcie_lcr_offset, lnkctl); | ||
108 | } | ||
109 | |||
110 | /* Need to be called after we discover btcoex capabilities */ | 99 | /* Need to be called after we discover btcoex capabilities */ |
111 | static void ath_pci_aspm_init(struct ath_common *common) | 100 | static void ath_pci_aspm_init(struct ath_common *common) |
112 | { | 101 | { |
@@ -153,7 +142,6 @@ static const struct ath_bus_ops ath_pci_bus_ops = { | |||
153 | .ath_bus_type = ATH_PCI, | 142 | .ath_bus_type = ATH_PCI, |
154 | .read_cachesize = ath_pci_read_cachesize, | 143 | .read_cachesize = ath_pci_read_cachesize, |
155 | .eeprom_read = ath_pci_eeprom_read, | 144 | .eeprom_read = ath_pci_eeprom_read, |
156 | .extn_synch_en = ath_pci_extn_synch_enable, | ||
157 | .aspm_init = ath_pci_aspm_init, | 145 | .aspm_init = ath_pci_aspm_init, |
158 | }; | 146 | }; |
159 | 147 | ||
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 27ed80b54881..714558d1ba78 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c | |||
@@ -982,16 +982,6 @@ static void ath_rc_update_per(struct ath_softc *sc, | |||
982 | } | 982 | } |
983 | } | 983 | } |
984 | 984 | ||
985 | static void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix, | ||
986 | int xretries, int retries, u8 per) | ||
987 | { | ||
988 | struct ath_rc_stats *stats = &rc->rcstats[rix]; | ||
989 | |||
990 | stats->xretries += xretries; | ||
991 | stats->retries += retries; | ||
992 | stats->per = per; | ||
993 | } | ||
994 | |||
995 | static void ath_rc_update_ht(struct ath_softc *sc, | 985 | static void ath_rc_update_ht(struct ath_softc *sc, |
996 | struct ath_rate_priv *ath_rc_priv, | 986 | struct ath_rate_priv *ath_rc_priv, |
997 | struct ieee80211_tx_info *tx_info, | 987 | struct ieee80211_tx_info *tx_info, |
@@ -1065,14 +1055,6 @@ static void ath_rc_update_ht(struct ath_softc *sc, | |||
1065 | 1055 | ||
1066 | } | 1056 | } |
1067 | 1057 | ||
1068 | static void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate) | ||
1069 | { | ||
1070 | struct ath_rc_stats *stats; | ||
1071 | |||
1072 | stats = &rc->rcstats[final_rate]; | ||
1073 | stats->success++; | ||
1074 | } | ||
1075 | |||
1076 | static void ath_rc_tx_status(struct ath_softc *sc, | 1058 | static void ath_rc_tx_status(struct ath_softc *sc, |
1077 | struct ath_rate_priv *ath_rc_priv, | 1059 | struct ath_rate_priv *ath_rc_priv, |
1078 | struct sk_buff *skb) | 1060 | struct sk_buff *skb) |
@@ -1350,7 +1332,25 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, | |||
1350 | } | 1332 | } |
1351 | } | 1333 | } |
1352 | 1334 | ||
1353 | #ifdef CONFIG_ATH9K_DEBUGFS | 1335 | #if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS) |
1336 | |||
1337 | void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate) | ||
1338 | { | ||
1339 | struct ath_rc_stats *stats; | ||
1340 | |||
1341 | stats = &rc->rcstats[final_rate]; | ||
1342 | stats->success++; | ||
1343 | } | ||
1344 | |||
1345 | void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix, | ||
1346 | int xretries, int retries, u8 per) | ||
1347 | { | ||
1348 | struct ath_rc_stats *stats = &rc->rcstats[rix]; | ||
1349 | |||
1350 | stats->xretries += xretries; | ||
1351 | stats->retries += retries; | ||
1352 | stats->per = per; | ||
1353 | } | ||
1354 | 1354 | ||
1355 | static ssize_t read_file_rcstat(struct file *file, char __user *user_buf, | 1355 | static ssize_t read_file_rcstat(struct file *file, char __user *user_buf, |
1356 | size_t count, loff_t *ppos) | 1356 | size_t count, loff_t *ppos) |
@@ -1428,10 +1428,17 @@ static void ath_rate_add_sta_debugfs(void *priv, void *priv_sta, | |||
1428 | struct dentry *dir) | 1428 | struct dentry *dir) |
1429 | { | 1429 | { |
1430 | struct ath_rate_priv *rc = priv_sta; | 1430 | struct ath_rate_priv *rc = priv_sta; |
1431 | debugfs_create_file("rc_stats", S_IRUGO, dir, rc, &fops_rcstat); | 1431 | rc->debugfs_rcstats = debugfs_create_file("rc_stats", S_IRUGO, |
1432 | dir, rc, &fops_rcstat); | ||
1433 | } | ||
1434 | |||
1435 | static void ath_rate_remove_sta_debugfs(void *priv, void *priv_sta) | ||
1436 | { | ||
1437 | struct ath_rate_priv *rc = priv_sta; | ||
1438 | debugfs_remove(rc->debugfs_rcstats); | ||
1432 | } | 1439 | } |
1433 | 1440 | ||
1434 | #endif /* CONFIG_ATH9K_DEBUGFS */ | 1441 | #endif /* CONFIG_MAC80211_DEBUGFS && CONFIG_ATH9K_DEBUGFS */ |
1435 | 1442 | ||
1436 | static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) | 1443 | static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) |
1437 | { | 1444 | { |
@@ -1476,8 +1483,10 @@ static struct rate_control_ops ath_rate_ops = { | |||
1476 | .free = ath_rate_free, | 1483 | .free = ath_rate_free, |
1477 | .alloc_sta = ath_rate_alloc_sta, | 1484 | .alloc_sta = ath_rate_alloc_sta, |
1478 | .free_sta = ath_rate_free_sta, | 1485 | .free_sta = ath_rate_free_sta, |
1479 | #ifdef CONFIG_ATH9K_DEBUGFS | 1486 | |
1487 | #if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS) | ||
1480 | .add_sta_debugfs = ath_rate_add_sta_debugfs, | 1488 | .add_sta_debugfs = ath_rate_add_sta_debugfs, |
1489 | .remove_sta_debugfs = ath_rate_remove_sta_debugfs, | ||
1481 | #endif | 1490 | #endif |
1482 | }; | 1491 | }; |
1483 | 1492 | ||
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h index 268e67dc5fb2..267dbfcfaa96 100644 --- a/drivers/net/wireless/ath/ath9k/rc.h +++ b/drivers/net/wireless/ath/ath9k/rc.h | |||
@@ -211,10 +211,26 @@ struct ath_rate_priv { | |||
211 | struct ath_rateset neg_ht_rates; | 211 | struct ath_rateset neg_ht_rates; |
212 | const struct ath_rate_table *rate_table; | 212 | const struct ath_rate_table *rate_table; |
213 | 213 | ||
214 | #if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS) | ||
214 | struct dentry *debugfs_rcstats; | 215 | struct dentry *debugfs_rcstats; |
215 | struct ath_rc_stats rcstats[RATE_TABLE_SIZE]; | 216 | struct ath_rc_stats rcstats[RATE_TABLE_SIZE]; |
217 | #endif | ||
216 | }; | 218 | }; |
217 | 219 | ||
220 | #if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS) | ||
221 | void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate); | ||
222 | void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix, | ||
223 | int xretries, int retries, u8 per); | ||
224 | #else | ||
225 | static inline void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate) | ||
226 | { | ||
227 | } | ||
228 | static inline void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix, | ||
229 | int xretries, int retries, u8 per) | ||
230 | { | ||
231 | } | ||
232 | #endif | ||
233 | |||
218 | #ifdef CONFIG_ATH9K_RATE_CONTROL | 234 | #ifdef CONFIG_ATH9K_RATE_CONTROL |
219 | int ath_rate_control_register(void); | 235 | int ath_rate_control_register(void); |
220 | void ath_rate_control_unregister(void); | 236 | void ath_rate_control_unregister(void); |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index a04028bce28b..6aafbb77c498 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -976,7 +976,7 @@ static int ath9k_rx_skb_preprocess(struct ath_common *common, | |||
976 | rx_status->freq = hw->conf.channel->center_freq; | 976 | rx_status->freq = hw->conf.channel->center_freq; |
977 | rx_status->signal = ah->noise + rx_stats->rs_rssi; | 977 | rx_status->signal = ah->noise + rx_stats->rs_rssi; |
978 | rx_status->antenna = rx_stats->rs_antenna; | 978 | rx_status->antenna = rx_stats->rs_antenna; |
979 | rx_status->flag |= RX_FLAG_MACTIME_MPDU; | 979 | rx_status->flag |= RX_FLAG_MACTIME_START; |
980 | if (rx_stats->rs_moreaggr) | 980 | if (rx_stats->rs_moreaggr) |
981 | rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; | 981 | rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL; |
982 | 982 | ||
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 741918a2027b..34130943f9de 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -1354,10 +1354,10 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) | |||
1354 | struct ath_hw *ah = sc->sc_ah; | 1354 | struct ath_hw *ah = sc->sc_ah; |
1355 | struct ath9k_tx_queue_info qi; | 1355 | struct ath9k_tx_queue_info qi; |
1356 | static const int subtype_txq_to_hwq[] = { | 1356 | static const int subtype_txq_to_hwq[] = { |
1357 | [WME_AC_BE] = ATH_TXQ_AC_BE, | 1357 | [IEEE80211_AC_BE] = ATH_TXQ_AC_BE, |
1358 | [WME_AC_BK] = ATH_TXQ_AC_BK, | 1358 | [IEEE80211_AC_BK] = ATH_TXQ_AC_BK, |
1359 | [WME_AC_VI] = ATH_TXQ_AC_VI, | 1359 | [IEEE80211_AC_VI] = ATH_TXQ_AC_VI, |
1360 | [WME_AC_VO] = ATH_TXQ_AC_VO, | 1360 | [IEEE80211_AC_VO] = ATH_TXQ_AC_VO, |
1361 | }; | 1361 | }; |
1362 | int axq_qnum, i; | 1362 | int axq_qnum, i; |
1363 | 1363 | ||
@@ -2319,6 +2319,8 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) | |||
2319 | 2319 | ||
2320 | ath_txq_lock(sc, txq); | 2320 | ath_txq_lock(sc, txq); |
2321 | 2321 | ||
2322 | TX_STAT_INC(txq->axq_qnum, txprocdesc); | ||
2323 | |||
2322 | if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) { | 2324 | if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) { |
2323 | ath_txq_unlock(sc, txq); | 2325 | ath_txq_unlock(sc, txq); |
2324 | return; | 2326 | return; |
@@ -2464,7 +2466,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) | |||
2464 | } | 2466 | } |
2465 | 2467 | ||
2466 | for (acno = 0, ac = &an->ac[acno]; | 2468 | for (acno = 0, ac = &an->ac[acno]; |
2467 | acno < WME_NUM_AC; acno++, ac++) { | 2469 | acno < IEEE80211_NUM_ACS; acno++, ac++) { |
2468 | ac->sched = false; | 2470 | ac->sched = false; |
2469 | ac->txq = sc->tx.txq_map[acno]; | 2471 | ac->txq = sc->tx.txq_map[acno]; |
2470 | INIT_LIST_HEAD(&ac->tid_q); | 2472 | INIT_LIST_HEAD(&ac->tid_q); |
diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c index 24ac2876a733..aaebecd19e59 100644 --- a/drivers/net/wireless/ath/carl9170/fw.c +++ b/drivers/net/wireless/ath/carl9170/fw.c | |||
@@ -28,11 +28,6 @@ | |||
28 | #include "fwcmd.h" | 28 | #include "fwcmd.h" |
29 | #include "version.h" | 29 | #include "version.h" |
30 | 30 | ||
31 | #define MAKE_STR(symbol) #symbol | ||
32 | #define TO_STR(symbol) MAKE_STR(symbol) | ||
33 | #define CARL9170FW_API_VER_STR TO_STR(CARL9170FW_API_MAX_VER) | ||
34 | MODULE_VERSION(CARL9170FW_API_VER_STR ":" CARL9170FW_VERSION_GIT); | ||
35 | |||
36 | static const u8 otus_magic[4] = { OTUS_MAGIC }; | 31 | static const u8 otus_magic[4] = { OTUS_MAGIC }; |
37 | 32 | ||
38 | static const void *carl9170_fw_find_desc(struct ar9170 *ar, const u8 descid[4], | 33 | static const void *carl9170_fw_find_desc(struct ar9170 *ar, const u8 descid[4], |
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index 136510edf3cf..8cb206a89083 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c | |||
@@ -796,7 +796,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) | |||
796 | status.mactime += mactime; | 796 | status.mactime += mactime; |
797 | if (low_mactime_now <= mactime) | 797 | if (low_mactime_now <= mactime) |
798 | status.mactime -= 0x10000; | 798 | status.mactime -= 0x10000; |
799 | status.flag |= RX_FLAG_MACTIME_MPDU; | 799 | status.flag |= RX_FLAG_MACTIME_START; |
800 | } | 800 | } |
801 | 801 | ||
802 | chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT; | 802 | chanid = (chanstat & B43_RX_CHAN_ID) >> B43_RX_CHAN_ID_SHIFT; |
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c index b8ffea6f5c64..849a28c80302 100644 --- a/drivers/net/wireless/b43legacy/xmit.c +++ b/drivers/net/wireless/b43legacy/xmit.c | |||
@@ -557,7 +557,7 @@ void b43legacy_rx(struct b43legacy_wldev *dev, | |||
557 | status.mactime += mactime; | 557 | status.mactime += mactime; |
558 | if (low_mactime_now <= mactime) | 558 | if (low_mactime_now <= mactime) |
559 | status.mactime -= 0x10000; | 559 | status.mactime -= 0x10000; |
560 | status.flag |= RX_FLAG_MACTIME_MPDU; | 560 | status.flag |= RX_FLAG_MACTIME_START; |
561 | } | 561 | } |
562 | 562 | ||
563 | chanid = (chanstat & B43legacy_RX_CHAN_ID) >> | 563 | chanid = (chanstat & B43legacy_RX_CHAN_ID) >> |
diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig index c9d811eb6556..1d92d874ebb6 100644 --- a/drivers/net/wireless/brcm80211/Kconfig +++ b/drivers/net/wireless/brcm80211/Kconfig | |||
@@ -55,13 +55,16 @@ config BRCMFMAC_USB | |||
55 | IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to | 55 | IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to |
56 | use the driver for an USB wireless card. | 56 | use the driver for an USB wireless card. |
57 | 57 | ||
58 | config BRCMISCAN | 58 | config BRCM_TRACING |
59 | bool "Broadcom I-Scan (OBSOLETE)" | 59 | bool "Broadcom device tracing" |
60 | depends on BRCMFMAC | 60 | depends on BRCMSMAC || BRCMFMAC |
61 | ---help--- | 61 | ---help--- |
62 | This option enables the I-Scan method. By default fullmac uses the | 62 | If you say Y here, the Broadcom wireless drivers will register |
63 | new E-Scan method which uses less memory in firmware and gives no | 63 | with ftrace to dump event information into the trace ringbuffer. |
64 | limitation on the number of scan results. | 64 | Tracing can be enabled at runtime to aid in debugging wireless |
65 | issues. This option adds a small amount of overhead when tracing | ||
66 | is disabled. If unsure, say Y to allow developers to better help | ||
67 | you when wireless problems occur. | ||
65 | 68 | ||
66 | config BRCMDBG | 69 | config BRCMDBG |
67 | bool "Broadcom driver debug functions" | 70 | bool "Broadcom driver debug functions" |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile index fe80b637c519..1a6661a9f008 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile +++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile | |||
@@ -25,6 +25,7 @@ obj-$(CONFIG_BRCMFMAC) += brcmfmac.o | |||
25 | brcmfmac-objs += \ | 25 | brcmfmac-objs += \ |
26 | wl_cfg80211.o \ | 26 | wl_cfg80211.o \ |
27 | fwil.o \ | 27 | fwil.o \ |
28 | fweh.o \ | ||
28 | dhd_cdc.o \ | 29 | dhd_cdc.o \ |
29 | dhd_common.o \ | 30 | dhd_common.o \ |
30 | dhd_linux.o | 31 | dhd_linux.o |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 3b2c4c20e7fc..334ddab4a8c5 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | |||
@@ -42,7 +42,8 @@ | |||
42 | #ifdef CONFIG_BRCMFMAC_SDIO_OOB | 42 | #ifdef CONFIG_BRCMFMAC_SDIO_OOB |
43 | static irqreturn_t brcmf_sdio_irqhandler(int irq, void *dev_id) | 43 | static irqreturn_t brcmf_sdio_irqhandler(int irq, void *dev_id) |
44 | { | 44 | { |
45 | struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(dev_id); | 45 | struct brcmf_bus *bus_if = dev_get_drvdata(dev_id); |
46 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; | ||
46 | 47 | ||
47 | brcmf_dbg(INTR, "oob intr triggered\n"); | 48 | brcmf_dbg(INTR, "oob intr triggered\n"); |
48 | 49 | ||
@@ -71,7 +72,7 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev) | |||
71 | brcmf_dbg(ERROR, "requesting irq %d\n", sdiodev->irq); | 72 | brcmf_dbg(ERROR, "requesting irq %d\n", sdiodev->irq); |
72 | ret = request_irq(sdiodev->irq, brcmf_sdio_irqhandler, | 73 | ret = request_irq(sdiodev->irq, brcmf_sdio_irqhandler, |
73 | sdiodev->irq_flags, "brcmf_oob_intr", | 74 | sdiodev->irq_flags, "brcmf_oob_intr", |
74 | &sdiodev->func[1]->card->dev); | 75 | &sdiodev->func[1]->dev); |
75 | if (ret != 0) | 76 | if (ret != 0) |
76 | return ret; | 77 | return ret; |
77 | spin_lock_init(&sdiodev->irq_en_lock); | 78 | spin_lock_init(&sdiodev->irq_en_lock); |
@@ -84,6 +85,8 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev) | |||
84 | return ret; | 85 | return ret; |
85 | sdiodev->irq_wake = true; | 86 | sdiodev->irq_wake = true; |
86 | 87 | ||
88 | sdio_claim_host(sdiodev->func[1]); | ||
89 | |||
87 | /* must configure SDIO_CCCR_IENx to enable irq */ | 90 | /* must configure SDIO_CCCR_IENx to enable irq */ |
88 | data = brcmf_sdio_regrb(sdiodev, SDIO_CCCR_IENx, &ret); | 91 | data = brcmf_sdio_regrb(sdiodev, SDIO_CCCR_IENx, &ret); |
89 | data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1; | 92 | data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1; |
@@ -95,6 +98,8 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev) | |||
95 | data |= SDIO_SEPINT_ACT_HI; | 98 | data |= SDIO_SEPINT_ACT_HI; |
96 | brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret); | 99 | brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret); |
97 | 100 | ||
101 | sdio_release_host(sdiodev->func[1]); | ||
102 | |||
98 | return 0; | 103 | return 0; |
99 | } | 104 | } |
100 | 105 | ||
@@ -102,14 +107,16 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev) | |||
102 | { | 107 | { |
103 | brcmf_dbg(TRACE, "Entering\n"); | 108 | brcmf_dbg(TRACE, "Entering\n"); |
104 | 109 | ||
110 | sdio_claim_host(sdiodev->func[1]); | ||
105 | brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL); | 111 | brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL); |
106 | brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL); | 112 | brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL); |
113 | sdio_release_host(sdiodev->func[1]); | ||
107 | 114 | ||
108 | if (sdiodev->irq_wake) { | 115 | if (sdiodev->irq_wake) { |
109 | disable_irq_wake(sdiodev->irq); | 116 | disable_irq_wake(sdiodev->irq); |
110 | sdiodev->irq_wake = false; | 117 | sdiodev->irq_wake = false; |
111 | } | 118 | } |
112 | free_irq(sdiodev->irq, &sdiodev->func[1]->card->dev); | 119 | free_irq(sdiodev->irq, &sdiodev->func[1]->dev); |
113 | sdiodev->irq_en = false; | 120 | sdiodev->irq_en = false; |
114 | 121 | ||
115 | return 0; | 122 | return 0; |
@@ -117,7 +124,8 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev) | |||
117 | #else /* CONFIG_BRCMFMAC_SDIO_OOB */ | 124 | #else /* CONFIG_BRCMFMAC_SDIO_OOB */ |
118 | static void brcmf_sdio_irqhandler(struct sdio_func *func) | 125 | static void brcmf_sdio_irqhandler(struct sdio_func *func) |
119 | { | 126 | { |
120 | struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev); | 127 | struct brcmf_bus *bus_if = dev_get_drvdata(&func->dev); |
128 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; | ||
121 | 129 | ||
122 | brcmf_dbg(INTR, "ib intr triggered\n"); | 130 | brcmf_dbg(INTR, "ib intr triggered\n"); |
123 | 131 | ||
@@ -249,9 +257,7 @@ u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) | |||
249 | int retval; | 257 | int retval; |
250 | 258 | ||
251 | brcmf_dbg(INFO, "addr:0x%08x\n", addr); | 259 | brcmf_dbg(INFO, "addr:0x%08x\n", addr); |
252 | sdio_claim_host(sdiodev->func[1]); | ||
253 | retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false); | 260 | retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false); |
254 | sdio_release_host(sdiodev->func[1]); | ||
255 | brcmf_dbg(INFO, "data:0x%02x\n", data); | 261 | brcmf_dbg(INFO, "data:0x%02x\n", data); |
256 | 262 | ||
257 | if (ret) | 263 | if (ret) |
@@ -266,9 +272,7 @@ u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) | |||
266 | int retval; | 272 | int retval; |
267 | 273 | ||
268 | brcmf_dbg(INFO, "addr:0x%08x\n", addr); | 274 | brcmf_dbg(INFO, "addr:0x%08x\n", addr); |
269 | sdio_claim_host(sdiodev->func[1]); | ||
270 | retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false); | 275 | retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false); |
271 | sdio_release_host(sdiodev->func[1]); | ||
272 | brcmf_dbg(INFO, "data:0x%08x\n", data); | 276 | brcmf_dbg(INFO, "data:0x%08x\n", data); |
273 | 277 | ||
274 | if (ret) | 278 | if (ret) |
@@ -283,9 +287,7 @@ void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr, | |||
283 | int retval; | 287 | int retval; |
284 | 288 | ||
285 | brcmf_dbg(INFO, "addr:0x%08x, data:0x%02x\n", addr, data); | 289 | brcmf_dbg(INFO, "addr:0x%08x, data:0x%02x\n", addr, data); |
286 | sdio_claim_host(sdiodev->func[1]); | ||
287 | retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true); | 290 | retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true); |
288 | sdio_release_host(sdiodev->func[1]); | ||
289 | 291 | ||
290 | if (ret) | 292 | if (ret) |
291 | *ret = retval; | 293 | *ret = retval; |
@@ -297,9 +299,7 @@ void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, | |||
297 | int retval; | 299 | int retval; |
298 | 300 | ||
299 | brcmf_dbg(INFO, "addr:0x%08x, data:0x%08x\n", addr, data); | 301 | brcmf_dbg(INFO, "addr:0x%08x, data:0x%08x\n", addr, data); |
300 | sdio_claim_host(sdiodev->func[1]); | ||
301 | retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true); | 302 | retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true); |
302 | sdio_release_host(sdiodev->func[1]); | ||
303 | 303 | ||
304 | if (ret) | 304 | if (ret) |
305 | *ret = retval; | 305 | *ret = retval; |
@@ -364,8 +364,6 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, | |||
364 | brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", | 364 | brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", |
365 | fn, addr, pkt->len); | 365 | fn, addr, pkt->len); |
366 | 366 | ||
367 | sdio_claim_host(sdiodev->func[1]); | ||
368 | |||
369 | width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; | 367 | width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; |
370 | err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr); | 368 | err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr); |
371 | if (err) | 369 | if (err) |
@@ -376,8 +374,6 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, | |||
376 | fn, addr, pkt); | 374 | fn, addr, pkt); |
377 | 375 | ||
378 | done: | 376 | done: |
379 | sdio_release_host(sdiodev->func[1]); | ||
380 | |||
381 | return err; | 377 | return err; |
382 | } | 378 | } |
383 | 379 | ||
@@ -391,8 +387,6 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, | |||
391 | brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", | 387 | brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", |
392 | fn, addr, pktq->qlen); | 388 | fn, addr, pktq->qlen); |
393 | 389 | ||
394 | sdio_claim_host(sdiodev->func[1]); | ||
395 | |||
396 | width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; | 390 | width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; |
397 | err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr); | 391 | err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr); |
398 | if (err) | 392 | if (err) |
@@ -403,8 +397,6 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, | |||
403 | pktq); | 397 | pktq); |
404 | 398 | ||
405 | done: | 399 | done: |
406 | sdio_release_host(sdiodev->func[1]); | ||
407 | |||
408 | return err; | 400 | return err; |
409 | } | 401 | } |
410 | 402 | ||
@@ -446,8 +438,6 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, | |||
446 | if (flags & SDIO_REQ_ASYNC) | 438 | if (flags & SDIO_REQ_ASYNC) |
447 | return -ENOTSUPP; | 439 | return -ENOTSUPP; |
448 | 440 | ||
449 | sdio_claim_host(sdiodev->func[1]); | ||
450 | |||
451 | if (bar0 != sdiodev->sbwad) { | 441 | if (bar0 != sdiodev->sbwad) { |
452 | err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0); | 442 | err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0); |
453 | if (err) | 443 | if (err) |
@@ -467,8 +457,6 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, | |||
467 | addr, pkt); | 457 | addr, pkt); |
468 | 458 | ||
469 | done: | 459 | done: |
470 | sdio_release_host(sdiodev->func[1]); | ||
471 | |||
472 | return err; | 460 | return err; |
473 | } | 461 | } |
474 | 462 | ||
@@ -510,10 +498,8 @@ int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn) | |||
510 | brcmf_dbg(TRACE, "Enter\n"); | 498 | brcmf_dbg(TRACE, "Enter\n"); |
511 | 499 | ||
512 | /* issue abort cmd52 command through F0 */ | 500 | /* issue abort cmd52 command through F0 */ |
513 | sdio_claim_host(sdiodev->func[1]); | ||
514 | brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, SDIO_FUNC_0, | 501 | brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, SDIO_FUNC_0, |
515 | SDIO_CCCR_ABORT, &t_func); | 502 | SDIO_CCCR_ABORT, &t_func); |
516 | sdio_release_host(sdiodev->func[1]); | ||
517 | 503 | ||
518 | brcmf_dbg(TRACE, "Exit\n"); | 504 | brcmf_dbg(TRACE, "Exit\n"); |
519 | return 0; | 505 | return 0; |
@@ -530,9 +516,6 @@ int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) | |||
530 | 516 | ||
531 | regs = SI_ENUM_BASE; | 517 | regs = SI_ENUM_BASE; |
532 | 518 | ||
533 | /* Report the BAR, to fix if needed */ | ||
534 | sdiodev->sbwad = SI_ENUM_BASE; | ||
535 | |||
536 | /* try to attach to the target device */ | 519 | /* try to attach to the target device */ |
537 | sdiodev->bus = brcmf_sdbrcm_probe(regs, sdiodev); | 520 | sdiodev->bus = brcmf_sdbrcm_probe(regs, sdiodev); |
538 | if (!sdiodev->bus) { | 521 | if (!sdiodev->bus) { |
@@ -551,6 +534,8 @@ EXPORT_SYMBOL(brcmf_sdio_probe); | |||
551 | 534 | ||
552 | int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev) | 535 | int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev) |
553 | { | 536 | { |
537 | sdiodev->bus_if->state = BRCMF_BUS_DOWN; | ||
538 | |||
554 | if (sdiodev->bus) { | 539 | if (sdiodev->bus) { |
555 | brcmf_sdbrcm_disconnect(sdiodev->bus); | 540 | brcmf_sdbrcm_disconnect(sdiodev->bus); |
556 | sdiodev->bus = NULL; | 541 | sdiodev->bus = NULL; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index c3247d5b3c22..a80050223710 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c | |||
@@ -372,9 +372,7 @@ static int brcmf_sdioh_enablefuncs(struct brcmf_sdio_dev *sdiodev) | |||
372 | } | 372 | } |
373 | 373 | ||
374 | /* Enable Function 1 */ | 374 | /* Enable Function 1 */ |
375 | sdio_claim_host(sdiodev->func[1]); | ||
376 | err_ret = sdio_enable_func(sdiodev->func[1]); | 375 | err_ret = sdio_enable_func(sdiodev->func[1]); |
377 | sdio_release_host(sdiodev->func[1]); | ||
378 | if (err_ret) | 376 | if (err_ret) |
379 | brcmf_dbg(ERROR, "Failed to enable F1 Err: 0x%08x\n", err_ret); | 377 | brcmf_dbg(ERROR, "Failed to enable F1 Err: 0x%08x\n", err_ret); |
380 | 378 | ||
@@ -393,16 +391,14 @@ int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev) | |||
393 | sdiodev->num_funcs = 2; | 391 | sdiodev->num_funcs = 2; |
394 | 392 | ||
395 | sdio_claim_host(sdiodev->func[1]); | 393 | sdio_claim_host(sdiodev->func[1]); |
394 | |||
396 | err_ret = sdio_set_block_size(sdiodev->func[1], SDIO_FUNC1_BLOCKSIZE); | 395 | err_ret = sdio_set_block_size(sdiodev->func[1], SDIO_FUNC1_BLOCKSIZE); |
397 | sdio_release_host(sdiodev->func[1]); | ||
398 | if (err_ret) { | 396 | if (err_ret) { |
399 | brcmf_dbg(ERROR, "Failed to set F1 blocksize\n"); | 397 | brcmf_dbg(ERROR, "Failed to set F1 blocksize\n"); |
400 | goto out; | 398 | goto out; |
401 | } | 399 | } |
402 | 400 | ||
403 | sdio_claim_host(sdiodev->func[2]); | ||
404 | err_ret = sdio_set_block_size(sdiodev->func[2], SDIO_FUNC2_BLOCKSIZE); | 401 | err_ret = sdio_set_block_size(sdiodev->func[2], SDIO_FUNC2_BLOCKSIZE); |
405 | sdio_release_host(sdiodev->func[2]); | ||
406 | if (err_ret) { | 402 | if (err_ret) { |
407 | brcmf_dbg(ERROR, "Failed to set F2 blocksize\n"); | 403 | brcmf_dbg(ERROR, "Failed to set F2 blocksize\n"); |
408 | goto out; | 404 | goto out; |
@@ -411,6 +407,7 @@ int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev) | |||
411 | brcmf_sdioh_enablefuncs(sdiodev); | 407 | brcmf_sdioh_enablefuncs(sdiodev); |
412 | 408 | ||
413 | out: | 409 | out: |
410 | sdio_release_host(sdiodev->func[1]); | ||
414 | brcmf_dbg(TRACE, "Done\n"); | 411 | brcmf_dbg(TRACE, "Done\n"); |
415 | return err_ret; | 412 | return err_ret; |
416 | } | 413 | } |
@@ -459,95 +456,106 @@ static inline int brcmf_sdio_getintrcfg(struct brcmf_sdio_dev *sdiodev) | |||
459 | #endif /* CONFIG_BRCMFMAC_SDIO_OOB */ | 456 | #endif /* CONFIG_BRCMFMAC_SDIO_OOB */ |
460 | 457 | ||
461 | static int brcmf_ops_sdio_probe(struct sdio_func *func, | 458 | static int brcmf_ops_sdio_probe(struct sdio_func *func, |
462 | const struct sdio_device_id *id) | 459 | const struct sdio_device_id *id) |
463 | { | 460 | { |
464 | int ret = 0; | 461 | int err; |
465 | struct brcmf_sdio_dev *sdiodev; | 462 | struct brcmf_sdio_dev *sdiodev; |
466 | struct brcmf_bus *bus_if; | 463 | struct brcmf_bus *bus_if; |
467 | 464 | ||
468 | brcmf_dbg(TRACE, "Enter\n"); | 465 | brcmf_dbg(TRACE, "Enter\n"); |
469 | brcmf_dbg(TRACE, "func->class=%x\n", func->class); | 466 | brcmf_dbg(TRACE, "Class=%x\n", func->class); |
470 | brcmf_dbg(TRACE, "sdio_vendor: 0x%04x\n", func->vendor); | 467 | brcmf_dbg(TRACE, "sdio vendor ID: 0x%04x\n", func->vendor); |
471 | brcmf_dbg(TRACE, "sdio_device: 0x%04x\n", func->device); | 468 | brcmf_dbg(TRACE, "sdio device ID: 0x%04x\n", func->device); |
472 | brcmf_dbg(TRACE, "Function#: 0x%04x\n", func->num); | 469 | brcmf_dbg(TRACE, "Function#: %d\n", func->num); |
473 | 470 | ||
474 | if (func->num == 1) { | 471 | /* Consume func num 1 but dont do anything with it. */ |
475 | if (dev_get_drvdata(&func->card->dev)) { | 472 | if (func->num == 1) |
476 | brcmf_dbg(ERROR, "card private drvdata occupied\n"); | 473 | return 0; |
477 | return -ENXIO; | 474 | |
478 | } | 475 | /* Ignore anything but func 2 */ |
479 | bus_if = kzalloc(sizeof(struct brcmf_bus), GFP_KERNEL); | 476 | if (func->num != 2) |
480 | if (!bus_if) | 477 | return -ENODEV; |
481 | return -ENOMEM; | 478 | |
482 | sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL); | 479 | bus_if = kzalloc(sizeof(struct brcmf_bus), GFP_KERNEL); |
483 | if (!sdiodev) { | 480 | if (!bus_if) |
484 | kfree(bus_if); | 481 | return -ENOMEM; |
485 | return -ENOMEM; | 482 | sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL); |
486 | } | 483 | if (!sdiodev) { |
487 | sdiodev->func[0] = func; | 484 | kfree(bus_if); |
488 | sdiodev->func[1] = func; | 485 | return -ENOMEM; |
489 | sdiodev->bus_if = bus_if; | ||
490 | bus_if->bus_priv.sdio = sdiodev; | ||
491 | bus_if->type = SDIO_BUS; | ||
492 | bus_if->align = BRCMF_SDALIGN; | ||
493 | dev_set_drvdata(&func->card->dev, sdiodev); | ||
494 | |||
495 | atomic_set(&sdiodev->suspend, false); | ||
496 | init_waitqueue_head(&sdiodev->request_byte_wait); | ||
497 | init_waitqueue_head(&sdiodev->request_word_wait); | ||
498 | init_waitqueue_head(&sdiodev->request_chain_wait); | ||
499 | init_waitqueue_head(&sdiodev->request_buffer_wait); | ||
500 | } | 486 | } |
501 | 487 | ||
502 | if (func->num == 2) { | 488 | sdiodev->func[0] = func->card->sdio_func[0]; |
503 | sdiodev = dev_get_drvdata(&func->card->dev); | 489 | sdiodev->func[1] = func->card->sdio_func[0]; |
504 | if ((!sdiodev) || (sdiodev->func[1]->card != func->card)) | 490 | sdiodev->func[2] = func; |
505 | return -ENODEV; | ||
506 | |||
507 | ret = brcmf_sdio_getintrcfg(sdiodev); | ||
508 | if (ret) | ||
509 | return ret; | ||
510 | sdiodev->func[2] = func; | ||
511 | 491 | ||
512 | bus_if = sdiodev->bus_if; | 492 | sdiodev->bus_if = bus_if; |
513 | sdiodev->dev = &func->dev; | 493 | bus_if->bus_priv.sdio = sdiodev; |
514 | dev_set_drvdata(&func->dev, bus_if); | 494 | bus_if->align = BRCMF_SDALIGN; |
495 | dev_set_drvdata(&func->dev, bus_if); | ||
496 | dev_set_drvdata(&sdiodev->func[1]->dev, bus_if); | ||
497 | sdiodev->dev = &sdiodev->func[1]->dev; | ||
515 | 498 | ||
516 | brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_probe...\n"); | 499 | atomic_set(&sdiodev->suspend, false); |
517 | ret = brcmf_sdio_probe(sdiodev); | 500 | init_waitqueue_head(&sdiodev->request_byte_wait); |
501 | init_waitqueue_head(&sdiodev->request_word_wait); | ||
502 | init_waitqueue_head(&sdiodev->request_chain_wait); | ||
503 | init_waitqueue_head(&sdiodev->request_buffer_wait); | ||
504 | err = brcmf_sdio_getintrcfg(sdiodev); | ||
505 | if (err) | ||
506 | goto fail; | ||
507 | |||
508 | brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_probe...\n"); | ||
509 | err = brcmf_sdio_probe(sdiodev); | ||
510 | if (err) { | ||
511 | brcmf_dbg(ERROR, "F2 error, probe failed %d...\n", err); | ||
512 | goto fail; | ||
518 | } | 513 | } |
514 | brcmf_dbg(TRACE, "F2 init completed...\n"); | ||
515 | return 0; | ||
519 | 516 | ||
520 | return ret; | 517 | fail: |
518 | dev_set_drvdata(&func->dev, NULL); | ||
519 | dev_set_drvdata(&sdiodev->func[1]->dev, NULL); | ||
520 | kfree(sdiodev); | ||
521 | kfree(bus_if); | ||
522 | return err; | ||
521 | } | 523 | } |
522 | 524 | ||
523 | static void brcmf_ops_sdio_remove(struct sdio_func *func) | 525 | static void brcmf_ops_sdio_remove(struct sdio_func *func) |
524 | { | 526 | { |
525 | struct brcmf_bus *bus_if; | 527 | struct brcmf_bus *bus_if; |
526 | struct brcmf_sdio_dev *sdiodev; | 528 | struct brcmf_sdio_dev *sdiodev; |
529 | |||
527 | brcmf_dbg(TRACE, "Enter\n"); | 530 | brcmf_dbg(TRACE, "Enter\n"); |
528 | brcmf_dbg(INFO, "func->class=%x\n", func->class); | 531 | brcmf_dbg(TRACE, "sdio vendor ID: 0x%04x\n", func->vendor); |
529 | brcmf_dbg(INFO, "sdio_vendor: 0x%04x\n", func->vendor); | 532 | brcmf_dbg(TRACE, "sdio device ID: 0x%04x\n", func->device); |
530 | brcmf_dbg(INFO, "sdio_device: 0x%04x\n", func->device); | 533 | brcmf_dbg(TRACE, "Function: %d\n", func->num); |
531 | brcmf_dbg(INFO, "Function#: 0x%04x\n", func->num); | ||
532 | 534 | ||
533 | if (func->num == 2) { | 535 | if (func->num != 1 && func->num != 2) |
534 | bus_if = dev_get_drvdata(&func->dev); | 536 | return; |
537 | |||
538 | bus_if = dev_get_drvdata(&func->dev); | ||
539 | if (bus_if) { | ||
535 | sdiodev = bus_if->bus_priv.sdio; | 540 | sdiodev = bus_if->bus_priv.sdio; |
536 | brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_remove...\n"); | ||
537 | brcmf_sdio_remove(sdiodev); | 541 | brcmf_sdio_remove(sdiodev); |
538 | dev_set_drvdata(&func->card->dev, NULL); | 542 | |
539 | dev_set_drvdata(&func->dev, NULL); | 543 | dev_set_drvdata(&sdiodev->func[1]->dev, NULL); |
544 | dev_set_drvdata(&sdiodev->func[2]->dev, NULL); | ||
545 | |||
540 | kfree(bus_if); | 546 | kfree(bus_if); |
541 | kfree(sdiodev); | 547 | kfree(sdiodev); |
542 | } | 548 | } |
549 | |||
550 | brcmf_dbg(TRACE, "Exit\n"); | ||
543 | } | 551 | } |
544 | 552 | ||
545 | #ifdef CONFIG_PM_SLEEP | 553 | #ifdef CONFIG_PM_SLEEP |
546 | static int brcmf_sdio_suspend(struct device *dev) | 554 | static int brcmf_sdio_suspend(struct device *dev) |
547 | { | 555 | { |
548 | mmc_pm_flag_t sdio_flags; | 556 | mmc_pm_flag_t sdio_flags; |
549 | struct sdio_func *func = dev_to_sdio_func(dev); | 557 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); |
550 | struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev); | 558 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; |
551 | int ret = 0; | 559 | int ret = 0; |
552 | 560 | ||
553 | brcmf_dbg(TRACE, "\n"); | 561 | brcmf_dbg(TRACE, "\n"); |
@@ -573,8 +581,8 @@ static int brcmf_sdio_suspend(struct device *dev) | |||
573 | 581 | ||
574 | static int brcmf_sdio_resume(struct device *dev) | 582 | static int brcmf_sdio_resume(struct device *dev) |
575 | { | 583 | { |
576 | struct sdio_func *func = dev_to_sdio_func(dev); | 584 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); |
577 | struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev); | 585 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; |
578 | 586 | ||
579 | brcmf_sdio_wdtmr_enable(sdiodev, true); | 587 | brcmf_sdio_wdtmr_enable(sdiodev, true); |
580 | atomic_set(&sdiodev->suspend, false); | 588 | atomic_set(&sdiodev->suspend, false); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index 8704daa2758f..24bc4e3e162b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h | |||
@@ -23,6 +23,8 @@ | |||
23 | 23 | ||
24 | #define BRCMF_VERSION_STR "4.218.248.5" | 24 | #define BRCMF_VERSION_STR "4.218.248.5" |
25 | 25 | ||
26 | #include "fweh.h" | ||
27 | |||
26 | /******************************************************************************* | 28 | /******************************************************************************* |
27 | * IO codes that are interpreted by dongle firmware | 29 | * IO codes that are interpreted by dongle firmware |
28 | ******************************************************************************/ | 30 | ******************************************************************************/ |
@@ -38,8 +40,11 @@ | |||
38 | #define BRCMF_C_GET_SSID 25 | 40 | #define BRCMF_C_GET_SSID 25 |
39 | #define BRCMF_C_SET_SSID 26 | 41 | #define BRCMF_C_SET_SSID 26 |
40 | #define BRCMF_C_GET_CHANNEL 29 | 42 | #define BRCMF_C_GET_CHANNEL 29 |
43 | #define BRCMF_C_SET_CHANNEL 30 | ||
41 | #define BRCMF_C_GET_SRL 31 | 44 | #define BRCMF_C_GET_SRL 31 |
45 | #define BRCMF_C_SET_SRL 32 | ||
42 | #define BRCMF_C_GET_LRL 33 | 46 | #define BRCMF_C_GET_LRL 33 |
47 | #define BRCMF_C_SET_LRL 34 | ||
43 | #define BRCMF_C_GET_RADIO 37 | 48 | #define BRCMF_C_GET_RADIO 37 |
44 | #define BRCMF_C_SET_RADIO 38 | 49 | #define BRCMF_C_SET_RADIO 38 |
45 | #define BRCMF_C_GET_PHYTYPE 39 | 50 | #define BRCMF_C_GET_PHYTYPE 39 |
@@ -58,6 +63,7 @@ | |||
58 | #define BRCMF_C_SET_COUNTRY 84 | 63 | #define BRCMF_C_SET_COUNTRY 84 |
59 | #define BRCMF_C_GET_PM 85 | 64 | #define BRCMF_C_GET_PM 85 |
60 | #define BRCMF_C_SET_PM 86 | 65 | #define BRCMF_C_SET_PM 86 |
66 | #define BRCMF_C_GET_CURR_RATESET 114 | ||
61 | #define BRCMF_C_GET_AP 117 | 67 | #define BRCMF_C_GET_AP 117 |
62 | #define BRCMF_C_SET_AP 118 | 68 | #define BRCMF_C_SET_AP 118 |
63 | #define BRCMF_C_GET_RSSI 127 | 69 | #define BRCMF_C_GET_RSSI 127 |
@@ -65,6 +71,7 @@ | |||
65 | #define BRCMF_C_SET_WSEC 134 | 71 | #define BRCMF_C_SET_WSEC 134 |
66 | #define BRCMF_C_GET_PHY_NOISE 135 | 72 | #define BRCMF_C_GET_PHY_NOISE 135 |
67 | #define BRCMF_C_GET_BSS_INFO 136 | 73 | #define BRCMF_C_GET_BSS_INFO 136 |
74 | #define BRCMF_C_GET_PHYLIST 180 | ||
68 | #define BRCMF_C_SET_SCAN_CHANNEL_TIME 185 | 75 | #define BRCMF_C_SET_SCAN_CHANNEL_TIME 185 |
69 | #define BRCMF_C_SET_SCAN_UNASSOC_TIME 187 | 76 | #define BRCMF_C_SET_SCAN_UNASSOC_TIME 187 |
70 | #define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON 201 | 77 | #define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON 201 |
@@ -100,29 +107,8 @@ | |||
100 | #define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff | 107 | #define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff |
101 | #define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16 | 108 | #define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16 |
102 | 109 | ||
103 | #define BRCMF_SCAN_ACTION_START 1 | ||
104 | #define BRCMF_SCAN_ACTION_CONTINUE 2 | ||
105 | #define WL_SCAN_ACTION_ABORT 3 | ||
106 | |||
107 | #define BRCMF_ISCAN_REQ_VERSION 1 | ||
108 | |||
109 | /* brcmf_iscan_results status values */ | ||
110 | #define BRCMF_SCAN_RESULTS_SUCCESS 0 | ||
111 | #define BRCMF_SCAN_RESULTS_PARTIAL 1 | ||
112 | #define BRCMF_SCAN_RESULTS_PENDING 2 | ||
113 | #define BRCMF_SCAN_RESULTS_ABORTED 3 | ||
114 | #define BRCMF_SCAN_RESULTS_NO_MEM 4 | ||
115 | |||
116 | /* Indicates this key is using soft encrypt */ | ||
117 | #define WL_SOFT_KEY (1 << 0) | ||
118 | /* primary (ie tx) key */ | 110 | /* primary (ie tx) key */ |
119 | #define BRCMF_PRIMARY_KEY (1 << 1) | 111 | #define BRCMF_PRIMARY_KEY (1 << 1) |
120 | /* Reserved for backward compat */ | ||
121 | #define WL_KF_RES_4 (1 << 4) | ||
122 | /* Reserved for backward compat */ | ||
123 | #define WL_KF_RES_5 (1 << 5) | ||
124 | /* Indicates a group key for a IBSS PEER */ | ||
125 | #define WL_IBSS_PEER_GROUP_KEY (1 << 6) | ||
126 | 112 | ||
127 | /* For supporting multiple interfaces */ | 113 | /* For supporting multiple interfaces */ |
128 | #define BRCMF_MAX_IFS 16 | 114 | #define BRCMF_MAX_IFS 16 |
@@ -130,10 +116,6 @@ | |||
130 | #define DOT11_BSSTYPE_ANY 2 | 116 | #define DOT11_BSSTYPE_ANY 2 |
131 | #define DOT11_MAX_DEFAULT_KEYS 4 | 117 | #define DOT11_MAX_DEFAULT_KEYS 4 |
132 | 118 | ||
133 | #define BRCMF_EVENT_MSG_LINK 0x01 | ||
134 | #define BRCMF_EVENT_MSG_FLUSHTXQ 0x02 | ||
135 | #define BRCMF_EVENT_MSG_GROUP 0x04 | ||
136 | |||
137 | #define BRCMF_ESCAN_REQ_VERSION 1 | 119 | #define BRCMF_ESCAN_REQ_VERSION 1 |
138 | 120 | ||
139 | #define WLC_BSS_RSSI_ON_CHANNEL 0x0002 | 121 | #define WLC_BSS_RSSI_ON_CHANNEL 0x0002 |
@@ -141,108 +123,6 @@ | |||
141 | #define BRCMF_MAXRATES_IN_SET 16 /* max # of rates in rateset */ | 123 | #define BRCMF_MAXRATES_IN_SET 16 /* max # of rates in rateset */ |
142 | #define BRCMF_STA_ASSOC 0x10 /* Associated */ | 124 | #define BRCMF_STA_ASSOC 0x10 /* Associated */ |
143 | 125 | ||
144 | struct brcmf_event_msg { | ||
145 | __be16 version; | ||
146 | __be16 flags; | ||
147 | __be32 event_type; | ||
148 | __be32 status; | ||
149 | __be32 reason; | ||
150 | __be32 auth_type; | ||
151 | __be32 datalen; | ||
152 | u8 addr[ETH_ALEN]; | ||
153 | char ifname[IFNAMSIZ]; | ||
154 | u8 ifidx; | ||
155 | u8 bsscfgidx; | ||
156 | } __packed; | ||
157 | |||
158 | struct brcm_ethhdr { | ||
159 | u16 subtype; | ||
160 | u16 length; | ||
161 | u8 version; | ||
162 | u8 oui[3]; | ||
163 | u16 usr_subtype; | ||
164 | } __packed; | ||
165 | |||
166 | struct brcmf_event { | ||
167 | struct ethhdr eth; | ||
168 | struct brcm_ethhdr hdr; | ||
169 | struct brcmf_event_msg msg; | ||
170 | } __packed; | ||
171 | |||
172 | /* event codes sent by the dongle to this driver */ | ||
173 | #define BRCMF_E_SET_SSID 0 | ||
174 | #define BRCMF_E_JOIN 1 | ||
175 | #define BRCMF_E_START 2 | ||
176 | #define BRCMF_E_AUTH 3 | ||
177 | #define BRCMF_E_AUTH_IND 4 | ||
178 | #define BRCMF_E_DEAUTH 5 | ||
179 | #define BRCMF_E_DEAUTH_IND 6 | ||
180 | #define BRCMF_E_ASSOC 7 | ||
181 | #define BRCMF_E_ASSOC_IND 8 | ||
182 | #define BRCMF_E_REASSOC 9 | ||
183 | #define BRCMF_E_REASSOC_IND 10 | ||
184 | #define BRCMF_E_DISASSOC 11 | ||
185 | #define BRCMF_E_DISASSOC_IND 12 | ||
186 | #define BRCMF_E_QUIET_START 13 | ||
187 | #define BRCMF_E_QUIET_END 14 | ||
188 | #define BRCMF_E_BEACON_RX 15 | ||
189 | #define BRCMF_E_LINK 16 | ||
190 | #define BRCMF_E_MIC_ERROR 17 | ||
191 | #define BRCMF_E_NDIS_LINK 18 | ||
192 | #define BRCMF_E_ROAM 19 | ||
193 | #define BRCMF_E_TXFAIL 20 | ||
194 | #define BRCMF_E_PMKID_CACHE 21 | ||
195 | #define BRCMF_E_RETROGRADE_TSF 22 | ||
196 | #define BRCMF_E_PRUNE 23 | ||
197 | #define BRCMF_E_AUTOAUTH 24 | ||
198 | #define BRCMF_E_EAPOL_MSG 25 | ||
199 | #define BRCMF_E_SCAN_COMPLETE 26 | ||
200 | #define BRCMF_E_ADDTS_IND 27 | ||
201 | #define BRCMF_E_DELTS_IND 28 | ||
202 | #define BRCMF_E_BCNSENT_IND 29 | ||
203 | #define BRCMF_E_BCNRX_MSG 30 | ||
204 | #define BRCMF_E_BCNLOST_MSG 31 | ||
205 | #define BRCMF_E_ROAM_PREP 32 | ||
206 | #define BRCMF_E_PFN_NET_FOUND 33 | ||
207 | #define BRCMF_E_PFN_NET_LOST 34 | ||
208 | #define BRCMF_E_RESET_COMPLETE 35 | ||
209 | #define BRCMF_E_JOIN_START 36 | ||
210 | #define BRCMF_E_ROAM_START 37 | ||
211 | #define BRCMF_E_ASSOC_START 38 | ||
212 | #define BRCMF_E_IBSS_ASSOC 39 | ||
213 | #define BRCMF_E_RADIO 40 | ||
214 | #define BRCMF_E_PSM_WATCHDOG 41 | ||
215 | #define BRCMF_E_PROBREQ_MSG 44 | ||
216 | #define BRCMF_E_SCAN_CONFIRM_IND 45 | ||
217 | #define BRCMF_E_PSK_SUP 46 | ||
218 | #define BRCMF_E_COUNTRY_CODE_CHANGED 47 | ||
219 | #define BRCMF_E_EXCEEDED_MEDIUM_TIME 48 | ||
220 | #define BRCMF_E_ICV_ERROR 49 | ||
221 | #define BRCMF_E_UNICAST_DECODE_ERROR 50 | ||
222 | #define BRCMF_E_MULTICAST_DECODE_ERROR 51 | ||
223 | #define BRCMF_E_TRACE 52 | ||
224 | #define BRCMF_E_IF 54 | ||
225 | #define BRCMF_E_RSSI 56 | ||
226 | #define BRCMF_E_PFN_SCAN_COMPLETE 57 | ||
227 | #define BRCMF_E_EXTLOG_MSG 58 | ||
228 | #define BRCMF_E_ACTION_FRAME 59 | ||
229 | #define BRCMF_E_ACTION_FRAME_COMPLETE 60 | ||
230 | #define BRCMF_E_PRE_ASSOC_IND 61 | ||
231 | #define BRCMF_E_PRE_REASSOC_IND 62 | ||
232 | #define BRCMF_E_CHANNEL_ADOPTED 63 | ||
233 | #define BRCMF_E_AP_STARTED 64 | ||
234 | #define BRCMF_E_DFS_AP_STOP 65 | ||
235 | #define BRCMF_E_DFS_AP_RESUME 66 | ||
236 | #define BRCMF_E_RESERVED1 67 | ||
237 | #define BRCMF_E_RESERVED2 68 | ||
238 | #define BRCMF_E_ESCAN_RESULT 69 | ||
239 | #define BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE 70 | ||
240 | #define BRCMF_E_DCS_REQUEST 73 | ||
241 | |||
242 | #define BRCMF_E_FIFO_CREDIT_MAP 74 | ||
243 | |||
244 | #define BRCMF_E_LAST 75 | ||
245 | |||
246 | #define BRCMF_E_STATUS_SUCCESS 0 | 126 | #define BRCMF_E_STATUS_SUCCESS 0 |
247 | #define BRCMF_E_STATUS_FAIL 1 | 127 | #define BRCMF_E_STATUS_FAIL 1 |
248 | #define BRCMF_E_STATUS_TIMEOUT 2 | 128 | #define BRCMF_E_STATUS_TIMEOUT 2 |
@@ -403,7 +283,7 @@ struct brcm_rateset_le { | |||
403 | /* # rates in this set */ | 283 | /* # rates in this set */ |
404 | __le32 count; | 284 | __le32 count; |
405 | /* rates in 500kbps units w/hi bit set if basic */ | 285 | /* rates in 500kbps units w/hi bit set if basic */ |
406 | u8 rates[WL_NUMRATES]; | 286 | u8 rates[BRCMF_MAXRATES_IN_SET]; |
407 | }; | 287 | }; |
408 | 288 | ||
409 | struct brcmf_ssid { | 289 | struct brcmf_ssid { |
@@ -452,14 +332,6 @@ struct brcmf_scan_params_le { | |||
452 | __le16 channel_list[1]; /* list of chanspecs */ | 332 | __le16 channel_list[1]; /* list of chanspecs */ |
453 | }; | 333 | }; |
454 | 334 | ||
455 | /* incremental scan struct */ | ||
456 | struct brcmf_iscan_params_le { | ||
457 | __le32 version; | ||
458 | __le16 action; | ||
459 | __le16 scan_duration; | ||
460 | struct brcmf_scan_params_le params_le; | ||
461 | }; | ||
462 | |||
463 | struct brcmf_scan_results { | 335 | struct brcmf_scan_results { |
464 | u32 buflen; | 336 | u32 buflen; |
465 | u32 version; | 337 | u32 version; |
@@ -467,12 +339,6 @@ struct brcmf_scan_results { | |||
467 | struct brcmf_bss_info_le bss_info_le[]; | 339 | struct brcmf_bss_info_le bss_info_le[]; |
468 | }; | 340 | }; |
469 | 341 | ||
470 | struct brcmf_scan_results_le { | ||
471 | __le32 buflen; | ||
472 | __le32 version; | ||
473 | __le32 count; | ||
474 | }; | ||
475 | |||
476 | struct brcmf_escan_params_le { | 342 | struct brcmf_escan_params_le { |
477 | __le32 version; | 343 | __le32 version; |
478 | __le16 action; | 344 | __le16 action; |
@@ -508,23 +374,6 @@ struct brcmf_join_params { | |||
508 | struct brcmf_assoc_params_le params_le; | 374 | struct brcmf_assoc_params_le params_le; |
509 | }; | 375 | }; |
510 | 376 | ||
511 | /* incremental scan results struct */ | ||
512 | struct brcmf_iscan_results { | ||
513 | union { | ||
514 | u32 status; | ||
515 | __le32 status_le; | ||
516 | }; | ||
517 | union { | ||
518 | struct brcmf_scan_results results; | ||
519 | struct brcmf_scan_results_le results_le; | ||
520 | }; | ||
521 | }; | ||
522 | |||
523 | /* size of brcmf_iscan_results not including variable length array */ | ||
524 | #define BRCMF_ISCAN_RESULTS_FIXED_SIZE \ | ||
525 | (sizeof(struct brcmf_scan_results) + \ | ||
526 | offsetof(struct brcmf_iscan_results, results)) | ||
527 | |||
528 | struct brcmf_wsec_key { | 377 | struct brcmf_wsec_key { |
529 | u32 index; /* key index */ | 378 | u32 index; /* key index */ |
530 | u32 len; /* key length */ | 379 | u32 len; /* key length */ |
@@ -661,10 +510,11 @@ struct brcmf_pub { | |||
661 | struct mutex proto_block; | 510 | struct mutex proto_block; |
662 | unsigned char proto_buf[BRCMF_DCMD_MAXLEN]; | 511 | unsigned char proto_buf[BRCMF_DCMD_MAXLEN]; |
663 | 512 | ||
664 | struct work_struct setmacaddr_work; | ||
665 | struct work_struct multicast_work; | ||
666 | u8 macvalue[ETH_ALEN]; | 513 | u8 macvalue[ETH_ALEN]; |
667 | atomic_t pend_8021x_cnt; | 514 | atomic_t pend_8021x_cnt; |
515 | wait_queue_head_t pend_8021x_wait; | ||
516 | |||
517 | struct brcmf_fweh_info fweh; | ||
668 | #ifdef DEBUG | 518 | #ifdef DEBUG |
669 | struct dentry *dbgfs_dir; | 519 | struct dentry *dbgfs_dir; |
670 | #endif | 520 | #endif |
@@ -701,6 +551,8 @@ struct brcmf_if { | |||
701 | struct brcmf_cfg80211_vif *vif; | 551 | struct brcmf_cfg80211_vif *vif; |
702 | struct net_device *ndev; | 552 | struct net_device *ndev; |
703 | struct net_device_stats stats; | 553 | struct net_device_stats stats; |
554 | struct work_struct setmacaddr_work; | ||
555 | struct work_struct multicast_work; | ||
704 | int idx; | 556 | int idx; |
705 | s32 bssidx; | 557 | s32 bssidx; |
706 | u8 mac_addr[ETH_ALEN]; | 558 | u8 mac_addr[ETH_ALEN]; |
@@ -714,9 +566,6 @@ static inline s32 brcmf_ndev_bssidx(struct net_device *ndev) | |||
714 | 566 | ||
715 | extern const struct bcmevent_name bcmevent_names[]; | 567 | extern const struct bcmevent_name bcmevent_names[]; |
716 | 568 | ||
717 | extern uint brcmf_c_mkiovar(char *name, char *data, uint datalen, | ||
718 | char *buf, uint len); | ||
719 | |||
720 | extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev); | 569 | extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev); |
721 | 570 | ||
722 | /* Return pointer to interface name */ | 571 | /* Return pointer to interface name */ |
@@ -728,14 +577,9 @@ extern int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, | |||
728 | extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, | 577 | extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, |
729 | void *buf, uint len); | 578 | void *buf, uint len); |
730 | 579 | ||
731 | extern int brcmf_ifname2idx(struct brcmf_pub *drvr, char *name); | ||
732 | extern int brcmf_c_host_event(struct brcmf_pub *drvr, int *idx, | ||
733 | void *pktdata, struct brcmf_event_msg *, | ||
734 | void **data_ptr); | ||
735 | |||
736 | extern int brcmf_net_attach(struct brcmf_if *ifp); | 580 | extern int brcmf_net_attach(struct brcmf_if *ifp); |
737 | extern struct brcmf_if *brcmf_add_if(struct device *dev, int ifidx, s32 bssidx, | 581 | extern struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, int ifidx, |
738 | char *name, u8 *mac_addr); | 582 | s32 bssidx, char *name, u8 *mac_addr); |
739 | extern void brcmf_del_if(struct brcmf_pub *drvr, int ifidx); | 583 | extern void brcmf_del_if(struct brcmf_pub *drvr, int ifidx); |
740 | 584 | ||
741 | #endif /* _BRCMF_H_ */ | 585 | #endif /* _BRCMF_H_ */ |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h index 265580f5b270..b8f248797f62 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h | |||
@@ -45,7 +45,6 @@ struct brcmf_bus_dcmd { | |||
45 | 45 | ||
46 | /* interface structure between common and bus layer */ | 46 | /* interface structure between common and bus layer */ |
47 | struct brcmf_bus { | 47 | struct brcmf_bus { |
48 | u8 type; /* bus type */ | ||
49 | union { | 48 | union { |
50 | struct brcmf_sdio_dev *sdio; | 49 | struct brcmf_sdio_dev *sdio; |
51 | struct brcmf_usbdev *usb; | 50 | struct brcmf_usbdev *usb; |
@@ -85,7 +84,7 @@ extern bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, | |||
85 | struct sk_buff *pkt, int prec); | 84 | struct sk_buff *pkt, int prec); |
86 | 85 | ||
87 | /* Receive frame for delivery to OS. Callee disposes of rxp. */ | 86 | /* Receive frame for delivery to OS. Callee disposes of rxp. */ |
88 | extern void brcmf_rx_frame(struct device *dev, int ifidx, | 87 | extern void brcmf_rx_frame(struct device *dev, u8 ifidx, |
89 | struct sk_buff_head *rxlist); | 88 | struct sk_buff_head *rxlist); |
90 | static inline void brcmf_rx_packet(struct device *dev, int ifidx, | 89 | static inline void brcmf_rx_packet(struct device *dev, int ifidx, |
91 | struct sk_buff *pkt) | 90 | struct sk_buff *pkt) |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c index b9d8a5adfd43..87536d38a4ca 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c | |||
@@ -23,8 +23,6 @@ | |||
23 | 23 | ||
24 | #include <linux/types.h> | 24 | #include <linux/types.h> |
25 | #include <linux/netdevice.h> | 25 | #include <linux/netdevice.h> |
26 | #include <linux/sched.h> | ||
27 | #include <defs.h> | ||
28 | 26 | ||
29 | #include <brcmu_utils.h> | 27 | #include <brcmu_utils.h> |
30 | #include <brcmu_wifi.h> | 28 | #include <brcmu_wifi.h> |
@@ -277,76 +275,6 @@ done: | |||
277 | return ret; | 275 | return ret; |
278 | } | 276 | } |
279 | 277 | ||
280 | int | ||
281 | brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx, struct brcmf_dcmd *dcmd, | ||
282 | int len) | ||
283 | { | ||
284 | struct brcmf_proto *prot = drvr->prot; | ||
285 | int ret = -1; | ||
286 | |||
287 | if (drvr->bus_if->state == BRCMF_BUS_DOWN) { | ||
288 | brcmf_dbg(ERROR, "bus is down. we have nothing to do.\n"); | ||
289 | return ret; | ||
290 | } | ||
291 | mutex_lock(&drvr->proto_block); | ||
292 | |||
293 | brcmf_dbg(TRACE, "Enter\n"); | ||
294 | |||
295 | if (len > BRCMF_DCMD_MAXLEN) | ||
296 | goto done; | ||
297 | |||
298 | if (prot->pending == true) { | ||
299 | brcmf_dbg(TRACE, "CDC packet is pending!!!! cmd=0x%x (%lu) lastcmd=0x%x (%lu)\n", | ||
300 | dcmd->cmd, (unsigned long)dcmd->cmd, prot->lastcmd, | ||
301 | (unsigned long)prot->lastcmd); | ||
302 | if (dcmd->cmd == BRCMF_C_SET_VAR || | ||
303 | dcmd->cmd == BRCMF_C_GET_VAR) | ||
304 | brcmf_dbg(TRACE, "iovar cmd=%s\n", (char *)dcmd->buf); | ||
305 | |||
306 | goto done; | ||
307 | } | ||
308 | |||
309 | prot->pending = true; | ||
310 | prot->lastcmd = dcmd->cmd; | ||
311 | if (dcmd->set) | ||
312 | ret = brcmf_proto_cdc_set_dcmd(drvr, ifidx, dcmd->cmd, | ||
313 | dcmd->buf, len); | ||
314 | else { | ||
315 | ret = brcmf_proto_cdc_query_dcmd(drvr, ifidx, dcmd->cmd, | ||
316 | dcmd->buf, len); | ||
317 | if (ret > 0) | ||
318 | dcmd->used = ret - | ||
319 | sizeof(struct brcmf_proto_cdc_dcmd); | ||
320 | } | ||
321 | |||
322 | if (ret >= 0) | ||
323 | ret = 0; | ||
324 | else { | ||
325 | struct brcmf_proto_cdc_dcmd *msg = &prot->msg; | ||
326 | /* len == needed when set/query fails from dongle */ | ||
327 | dcmd->needed = le32_to_cpu(msg->len); | ||
328 | } | ||
329 | |||
330 | /* Intercept the wme_dp dongle cmd here */ | ||
331 | if (!ret && dcmd->cmd == BRCMF_C_SET_VAR && | ||
332 | !strcmp(dcmd->buf, "wme_dp")) { | ||
333 | int slen; | ||
334 | __le32 val = 0; | ||
335 | |||
336 | slen = strlen("wme_dp") + 1; | ||
337 | if (len >= (int)(slen + sizeof(int))) | ||
338 | memcpy(&val, (char *)dcmd->buf + slen, sizeof(int)); | ||
339 | drvr->wme_dp = (u8) le32_to_cpu(val); | ||
340 | } | ||
341 | |||
342 | prot->pending = false; | ||
343 | |||
344 | done: | ||
345 | mutex_unlock(&drvr->proto_block); | ||
346 | |||
347 | return ret; | ||
348 | } | ||
349 | |||
350 | static bool pkt_sum_needed(struct sk_buff *skb) | 278 | static bool pkt_sum_needed(struct sk_buff *skb) |
351 | { | 279 | { |
352 | return skb->ip_summed == CHECKSUM_PARTIAL; | 280 | return skb->ip_summed == CHECKSUM_PARTIAL; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index 866b66995bb0..eee7175f1515 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c | |||
@@ -18,10 +18,7 @@ | |||
18 | 18 | ||
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/string.h> | 20 | #include <linux/string.h> |
21 | #include <linux/sched.h> | ||
22 | #include <linux/netdevice.h> | 21 | #include <linux/netdevice.h> |
23 | #include <asm/unaligned.h> | ||
24 | #include <defs.h> | ||
25 | #include <brcmu_wifi.h> | 22 | #include <brcmu_wifi.h> |
26 | #include <brcmu_utils.h> | 23 | #include <brcmu_utils.h> |
27 | #include "dhd.h" | 24 | #include "dhd.h" |
@@ -30,9 +27,6 @@ | |||
30 | #include "dhd_dbg.h" | 27 | #include "dhd_dbg.h" |
31 | #include "fwil.h" | 28 | #include "fwil.h" |
32 | 29 | ||
33 | #define BRCM_OUI "\x00\x10\x18" | ||
34 | #define DOT11_OUI_LEN 3 | ||
35 | #define BCMILCP_BCM_SUBTYPE_EVENT 1 | ||
36 | #define PKTFILTER_BUF_SIZE 128 | 30 | #define PKTFILTER_BUF_SIZE 128 |
37 | #define BRCMF_ARPOL_MODE 0xb /* agent|snoop|peer_autoreply */ | 31 | #define BRCMF_ARPOL_MODE 0xb /* agent|snoop|peer_autoreply */ |
38 | #define BRCMF_DEFAULT_BCN_TIMEOUT 3 | 32 | #define BRCMF_DEFAULT_BCN_TIMEOUT 3 |
@@ -40,12 +34,6 @@ | |||
40 | #define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40 | 34 | #define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40 |
41 | #define BRCMF_DEFAULT_PACKET_FILTER "100 0 0 0 0x01 0x00" | 35 | #define BRCMF_DEFAULT_PACKET_FILTER "100 0 0 0 0x01 0x00" |
42 | 36 | ||
43 | #define MSGTRACE_VERSION 1 | ||
44 | |||
45 | #define BRCMF_PKT_FILTER_FIXED_LEN offsetof(struct brcmf_pkt_filter_le, u) | ||
46 | #define BRCMF_PKT_FILTER_PATTERN_FIXED_LEN \ | ||
47 | offsetof(struct brcmf_pkt_filter_pattern_le, mask_and_pattern) | ||
48 | |||
49 | #ifdef DEBUG | 37 | #ifdef DEBUG |
50 | static const char brcmf_version[] = | 38 | static const char brcmf_version[] = |
51 | "Dongle Host Driver, version " BRCMF_VERSION_STR "\nCompiled on " | 39 | "Dongle Host Driver, version " BRCMF_VERSION_STR "\nCompiled on " |
@@ -55,43 +43,6 @@ static const char brcmf_version[] = | |||
55 | "Dongle Host Driver, version " BRCMF_VERSION_STR; | 43 | "Dongle Host Driver, version " BRCMF_VERSION_STR; |
56 | #endif | 44 | #endif |
57 | 45 | ||
58 | /* Message trace header */ | ||
59 | struct msgtrace_hdr { | ||
60 | u8 version; | ||
61 | u8 spare; | ||
62 | __be16 len; /* Len of the trace */ | ||
63 | __be32 seqnum; /* Sequence number of message. Useful | ||
64 | * if the messsage has been lost | ||
65 | * because of DMA error or a bus reset | ||
66 | * (ex: SDIO Func2) | ||
67 | */ | ||
68 | __be32 discarded_bytes; /* Number of discarded bytes because of | ||
69 | trace overflow */ | ||
70 | __be32 discarded_printf; /* Number of discarded printf | ||
71 | because of trace overflow */ | ||
72 | } __packed; | ||
73 | |||
74 | |||
75 | uint | ||
76 | brcmf_c_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen) | ||
77 | { | ||
78 | uint len; | ||
79 | |||
80 | len = strlen(name) + 1; | ||
81 | |||
82 | if ((len + datalen) > buflen) | ||
83 | return 0; | ||
84 | |||
85 | strncpy(buf, name, buflen); | ||
86 | |||
87 | /* append data onto the end of the name string */ | ||
88 | if (data && datalen) { | ||
89 | memcpy(&buf[len], data, datalen); | ||
90 | len += datalen; | ||
91 | } | ||
92 | |||
93 | return len; | ||
94 | } | ||
95 | 46 | ||
96 | bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, | 47 | bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, |
97 | struct sk_buff *pkt, int prec) | 48 | struct sk_buff *pkt, int prec) |
@@ -143,405 +94,6 @@ bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, | |||
143 | return p != NULL; | 94 | return p != NULL; |
144 | } | 95 | } |
145 | 96 | ||
146 | #ifdef DEBUG | ||
147 | static void | ||
148 | brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data) | ||
149 | { | ||
150 | uint i, status, reason; | ||
151 | bool group = false, flush_txq = false, link = false; | ||
152 | char *auth_str, *event_name; | ||
153 | unsigned char *buf; | ||
154 | char err_msg[256], eabuf[ETHER_ADDR_STR_LEN]; | ||
155 | static struct { | ||
156 | uint event; | ||
157 | char *event_name; | ||
158 | } event_names[] = { | ||
159 | { | ||
160 | BRCMF_E_SET_SSID, "SET_SSID"}, { | ||
161 | BRCMF_E_JOIN, "JOIN"}, { | ||
162 | BRCMF_E_START, "START"}, { | ||
163 | BRCMF_E_AUTH, "AUTH"}, { | ||
164 | BRCMF_E_AUTH_IND, "AUTH_IND"}, { | ||
165 | BRCMF_E_DEAUTH, "DEAUTH"}, { | ||
166 | BRCMF_E_DEAUTH_IND, "DEAUTH_IND"}, { | ||
167 | BRCMF_E_ASSOC, "ASSOC"}, { | ||
168 | BRCMF_E_ASSOC_IND, "ASSOC_IND"}, { | ||
169 | BRCMF_E_REASSOC, "REASSOC"}, { | ||
170 | BRCMF_E_REASSOC_IND, "REASSOC_IND"}, { | ||
171 | BRCMF_E_DISASSOC, "DISASSOC"}, { | ||
172 | BRCMF_E_DISASSOC_IND, "DISASSOC_IND"}, { | ||
173 | BRCMF_E_QUIET_START, "START_QUIET"}, { | ||
174 | BRCMF_E_QUIET_END, "END_QUIET"}, { | ||
175 | BRCMF_E_BEACON_RX, "BEACON_RX"}, { | ||
176 | BRCMF_E_LINK, "LINK"}, { | ||
177 | BRCMF_E_MIC_ERROR, "MIC_ERROR"}, { | ||
178 | BRCMF_E_NDIS_LINK, "NDIS_LINK"}, { | ||
179 | BRCMF_E_ROAM, "ROAM"}, { | ||
180 | BRCMF_E_TXFAIL, "TXFAIL"}, { | ||
181 | BRCMF_E_PMKID_CACHE, "PMKID_CACHE"}, { | ||
182 | BRCMF_E_RETROGRADE_TSF, "RETROGRADE_TSF"}, { | ||
183 | BRCMF_E_PRUNE, "PRUNE"}, { | ||
184 | BRCMF_E_AUTOAUTH, "AUTOAUTH"}, { | ||
185 | BRCMF_E_EAPOL_MSG, "EAPOL_MSG"}, { | ||
186 | BRCMF_E_SCAN_COMPLETE, "SCAN_COMPLETE"}, { | ||
187 | BRCMF_E_ADDTS_IND, "ADDTS_IND"}, { | ||
188 | BRCMF_E_DELTS_IND, "DELTS_IND"}, { | ||
189 | BRCMF_E_BCNSENT_IND, "BCNSENT_IND"}, { | ||
190 | BRCMF_E_BCNRX_MSG, "BCNRX_MSG"}, { | ||
191 | BRCMF_E_BCNLOST_MSG, "BCNLOST_MSG"}, { | ||
192 | BRCMF_E_ROAM_PREP, "ROAM_PREP"}, { | ||
193 | BRCMF_E_PFN_NET_FOUND, "PNO_NET_FOUND"}, { | ||
194 | BRCMF_E_PFN_NET_LOST, "PNO_NET_LOST"}, { | ||
195 | BRCMF_E_RESET_COMPLETE, "RESET_COMPLETE"}, { | ||
196 | BRCMF_E_JOIN_START, "JOIN_START"}, { | ||
197 | BRCMF_E_ROAM_START, "ROAM_START"}, { | ||
198 | BRCMF_E_ASSOC_START, "ASSOC_START"}, { | ||
199 | BRCMF_E_IBSS_ASSOC, "IBSS_ASSOC"}, { | ||
200 | BRCMF_E_RADIO, "RADIO"}, { | ||
201 | BRCMF_E_PSM_WATCHDOG, "PSM_WATCHDOG"}, { | ||
202 | BRCMF_E_PROBREQ_MSG, "PROBREQ_MSG"}, { | ||
203 | BRCMF_E_SCAN_CONFIRM_IND, "SCAN_CONFIRM_IND"}, { | ||
204 | BRCMF_E_PSK_SUP, "PSK_SUP"}, { | ||
205 | BRCMF_E_COUNTRY_CODE_CHANGED, "COUNTRY_CODE_CHANGED"}, { | ||
206 | BRCMF_E_EXCEEDED_MEDIUM_TIME, "EXCEEDED_MEDIUM_TIME"}, { | ||
207 | BRCMF_E_ICV_ERROR, "ICV_ERROR"}, { | ||
208 | BRCMF_E_UNICAST_DECODE_ERROR, "UNICAST_DECODE_ERROR"}, { | ||
209 | BRCMF_E_MULTICAST_DECODE_ERROR, "MULTICAST_DECODE_ERROR"}, { | ||
210 | BRCMF_E_TRACE, "TRACE"}, { | ||
211 | BRCMF_E_ACTION_FRAME, "ACTION FRAME"}, { | ||
212 | BRCMF_E_ACTION_FRAME_COMPLETE, "ACTION FRAME TX COMPLETE"}, { | ||
213 | BRCMF_E_IF, "IF"}, { | ||
214 | BRCMF_E_RSSI, "RSSI"}, { | ||
215 | BRCMF_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE"}, { | ||
216 | BRCMF_E_ESCAN_RESULT, "ESCAN_RESULT"} | ||
217 | }; | ||
218 | uint event_type, flags, auth_type, datalen; | ||
219 | static u32 seqnum_prev; | ||
220 | struct msgtrace_hdr hdr; | ||
221 | u32 nblost; | ||
222 | char *s, *p; | ||
223 | |||
224 | event_type = be32_to_cpu(event->event_type); | ||
225 | flags = be16_to_cpu(event->flags); | ||
226 | status = be32_to_cpu(event->status); | ||
227 | reason = be32_to_cpu(event->reason); | ||
228 | auth_type = be32_to_cpu(event->auth_type); | ||
229 | datalen = be32_to_cpu(event->datalen); | ||
230 | /* debug dump of event messages */ | ||
231 | sprintf(eabuf, "%pM", event->addr); | ||
232 | |||
233 | event_name = "UNKNOWN"; | ||
234 | for (i = 0; i < ARRAY_SIZE(event_names); i++) { | ||
235 | if (event_names[i].event == event_type) | ||
236 | event_name = event_names[i].event_name; | ||
237 | } | ||
238 | |||
239 | brcmf_dbg(EVENT, "EVENT: %s, event ID = %d\n", event_name, event_type); | ||
240 | brcmf_dbg(EVENT, "flags 0x%04x, status %d, reason %d, auth_type %d MAC %s\n", | ||
241 | flags, status, reason, auth_type, eabuf); | ||
242 | |||
243 | if (flags & BRCMF_EVENT_MSG_LINK) | ||
244 | link = true; | ||
245 | if (flags & BRCMF_EVENT_MSG_GROUP) | ||
246 | group = true; | ||
247 | if (flags & BRCMF_EVENT_MSG_FLUSHTXQ) | ||
248 | flush_txq = true; | ||
249 | |||
250 | switch (event_type) { | ||
251 | case BRCMF_E_START: | ||
252 | case BRCMF_E_DEAUTH: | ||
253 | case BRCMF_E_DISASSOC: | ||
254 | brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf); | ||
255 | break; | ||
256 | |||
257 | case BRCMF_E_ASSOC_IND: | ||
258 | case BRCMF_E_REASSOC_IND: | ||
259 | brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf); | ||
260 | break; | ||
261 | |||
262 | case BRCMF_E_ASSOC: | ||
263 | case BRCMF_E_REASSOC: | ||
264 | if (status == BRCMF_E_STATUS_SUCCESS) | ||
265 | brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, SUCCESS\n", | ||
266 | event_name, eabuf); | ||
267 | else if (status == BRCMF_E_STATUS_TIMEOUT) | ||
268 | brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, TIMEOUT\n", | ||
269 | event_name, eabuf); | ||
270 | else if (status == BRCMF_E_STATUS_FAIL) | ||
271 | brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, FAILURE, reason %d\n", | ||
272 | event_name, eabuf, (int)reason); | ||
273 | else | ||
274 | brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, unexpected status %d\n", | ||
275 | event_name, eabuf, (int)status); | ||
276 | break; | ||
277 | |||
278 | case BRCMF_E_DEAUTH_IND: | ||
279 | case BRCMF_E_DISASSOC_IND: | ||
280 | brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, reason %d\n", | ||
281 | event_name, eabuf, (int)reason); | ||
282 | break; | ||
283 | |||
284 | case BRCMF_E_AUTH: | ||
285 | case BRCMF_E_AUTH_IND: | ||
286 | if (auth_type == WLAN_AUTH_OPEN) | ||
287 | auth_str = "Open System"; | ||
288 | else if (auth_type == WLAN_AUTH_SHARED_KEY) | ||
289 | auth_str = "Shared Key"; | ||
290 | else { | ||
291 | sprintf(err_msg, "AUTH unknown: %d", (int)auth_type); | ||
292 | auth_str = err_msg; | ||
293 | } | ||
294 | if (event_type == BRCMF_E_AUTH_IND) | ||
295 | brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s\n", | ||
296 | event_name, eabuf, auth_str); | ||
297 | else if (status == BRCMF_E_STATUS_SUCCESS) | ||
298 | brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, SUCCESS\n", | ||
299 | event_name, eabuf, auth_str); | ||
300 | else if (status == BRCMF_E_STATUS_TIMEOUT) | ||
301 | brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, TIMEOUT\n", | ||
302 | event_name, eabuf, auth_str); | ||
303 | else if (status == BRCMF_E_STATUS_FAIL) { | ||
304 | brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, FAILURE, reason %d\n", | ||
305 | event_name, eabuf, auth_str, (int)reason); | ||
306 | } | ||
307 | |||
308 | break; | ||
309 | |||
310 | case BRCMF_E_JOIN: | ||
311 | case BRCMF_E_ROAM: | ||
312 | case BRCMF_E_SET_SSID: | ||
313 | if (status == BRCMF_E_STATUS_SUCCESS) | ||
314 | brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", | ||
315 | event_name, eabuf); | ||
316 | else if (status == BRCMF_E_STATUS_FAIL) | ||
317 | brcmf_dbg(EVENT, "MACEVENT: %s, failed\n", event_name); | ||
318 | else if (status == BRCMF_E_STATUS_NO_NETWORKS) | ||
319 | brcmf_dbg(EVENT, "MACEVENT: %s, no networks found\n", | ||
320 | event_name); | ||
321 | else | ||
322 | brcmf_dbg(EVENT, "MACEVENT: %s, unexpected status %d\n", | ||
323 | event_name, (int)status); | ||
324 | break; | ||
325 | |||
326 | case BRCMF_E_BEACON_RX: | ||
327 | if (status == BRCMF_E_STATUS_SUCCESS) | ||
328 | brcmf_dbg(EVENT, "MACEVENT: %s, SUCCESS\n", event_name); | ||
329 | else if (status == BRCMF_E_STATUS_FAIL) | ||
330 | brcmf_dbg(EVENT, "MACEVENT: %s, FAIL\n", event_name); | ||
331 | else | ||
332 | brcmf_dbg(EVENT, "MACEVENT: %s, status %d\n", | ||
333 | event_name, status); | ||
334 | break; | ||
335 | |||
336 | case BRCMF_E_LINK: | ||
337 | brcmf_dbg(EVENT, "MACEVENT: %s %s\n", | ||
338 | event_name, link ? "UP" : "DOWN"); | ||
339 | break; | ||
340 | |||
341 | case BRCMF_E_MIC_ERROR: | ||
342 | brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, Group %d, Flush %d\n", | ||
343 | event_name, eabuf, group, flush_txq); | ||
344 | break; | ||
345 | |||
346 | case BRCMF_E_ICV_ERROR: | ||
347 | case BRCMF_E_UNICAST_DECODE_ERROR: | ||
348 | case BRCMF_E_MULTICAST_DECODE_ERROR: | ||
349 | brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf); | ||
350 | break; | ||
351 | |||
352 | case BRCMF_E_TXFAIL: | ||
353 | brcmf_dbg(EVENT, "MACEVENT: %s, RA %s\n", event_name, eabuf); | ||
354 | break; | ||
355 | |||
356 | case BRCMF_E_SCAN_COMPLETE: | ||
357 | case BRCMF_E_PMKID_CACHE: | ||
358 | brcmf_dbg(EVENT, "MACEVENT: %s\n", event_name); | ||
359 | break; | ||
360 | |||
361 | case BRCMF_E_ESCAN_RESULT: | ||
362 | brcmf_dbg(EVENT, "MACEVENT: %s\n", event_name); | ||
363 | datalen = 0; | ||
364 | break; | ||
365 | |||
366 | case BRCMF_E_PFN_NET_FOUND: | ||
367 | case BRCMF_E_PFN_NET_LOST: | ||
368 | case BRCMF_E_PFN_SCAN_COMPLETE: | ||
369 | brcmf_dbg(EVENT, "PNOEVENT: %s\n", event_name); | ||
370 | break; | ||
371 | |||
372 | case BRCMF_E_PSK_SUP: | ||
373 | case BRCMF_E_PRUNE: | ||
374 | brcmf_dbg(EVENT, "MACEVENT: %s, status %d, reason %d\n", | ||
375 | event_name, (int)status, (int)reason); | ||
376 | break; | ||
377 | |||
378 | case BRCMF_E_TRACE: | ||
379 | buf = (unsigned char *) event_data; | ||
380 | memcpy(&hdr, buf, sizeof(struct msgtrace_hdr)); | ||
381 | |||
382 | if (hdr.version != MSGTRACE_VERSION) { | ||
383 | brcmf_dbg(ERROR, | ||
384 | "MACEVENT: %s [unsupported version --> brcmf" | ||
385 | " version:%d dongle version:%d]\n", | ||
386 | event_name, MSGTRACE_VERSION, hdr.version); | ||
387 | /* Reset datalen to avoid display below */ | ||
388 | datalen = 0; | ||
389 | break; | ||
390 | } | ||
391 | |||
392 | /* There are 2 bytes available at the end of data */ | ||
393 | *(buf + sizeof(struct msgtrace_hdr) | ||
394 | + be16_to_cpu(hdr.len)) = '\0'; | ||
395 | |||
396 | if (be32_to_cpu(hdr.discarded_bytes) | ||
397 | || be32_to_cpu(hdr.discarded_printf)) | ||
398 | brcmf_dbg(ERROR, | ||
399 | "WLC_E_TRACE: [Discarded traces in dongle -->" | ||
400 | " discarded_bytes %d discarded_printf %d]\n", | ||
401 | be32_to_cpu(hdr.discarded_bytes), | ||
402 | be32_to_cpu(hdr.discarded_printf)); | ||
403 | |||
404 | nblost = be32_to_cpu(hdr.seqnum) - seqnum_prev - 1; | ||
405 | if (nblost > 0) | ||
406 | brcmf_dbg(ERROR, "WLC_E_TRACE: [Event lost --> seqnum " | ||
407 | " %d nblost %d\n", be32_to_cpu(hdr.seqnum), | ||
408 | nblost); | ||
409 | seqnum_prev = be32_to_cpu(hdr.seqnum); | ||
410 | |||
411 | /* Display the trace buffer. Advance from \n to \n to | ||
412 | * avoid display big | ||
413 | * printf (issue with Linux printk ) | ||
414 | */ | ||
415 | p = (char *)&buf[sizeof(struct msgtrace_hdr)]; | ||
416 | while ((s = strstr(p, "\n")) != NULL) { | ||
417 | *s = '\0'; | ||
418 | pr_debug("%s\n", p); | ||
419 | p = s + 1; | ||
420 | } | ||
421 | pr_debug("%s\n", p); | ||
422 | |||
423 | /* Reset datalen to avoid display below */ | ||
424 | datalen = 0; | ||
425 | break; | ||
426 | |||
427 | case BRCMF_E_RSSI: | ||
428 | brcmf_dbg(EVENT, "MACEVENT: %s %d\n", | ||
429 | event_name, be32_to_cpu(*((__be32 *)event_data))); | ||
430 | break; | ||
431 | |||
432 | default: | ||
433 | brcmf_dbg(EVENT, | ||
434 | "MACEVENT: %s %d, MAC %s, status %d, reason %d, " | ||
435 | "auth %d\n", event_name, event_type, eabuf, | ||
436 | (int)status, (int)reason, (int)auth_type); | ||
437 | break; | ||
438 | } | ||
439 | |||
440 | /* show any appended data */ | ||
441 | brcmf_dbg_hex_dump(datalen, event_data, datalen, "Received data"); | ||
442 | } | ||
443 | #endif /* DEBUG */ | ||
444 | |||
445 | int | ||
446 | brcmf_c_host_event(struct brcmf_pub *drvr, int *ifidx, void *pktdata, | ||
447 | struct brcmf_event_msg *event, void **data_ptr) | ||
448 | { | ||
449 | /* check whether packet is a BRCM event pkt */ | ||
450 | struct brcmf_event *pvt_data = (struct brcmf_event *) pktdata; | ||
451 | struct brcmf_if_event *ifevent; | ||
452 | struct brcmf_if *ifp; | ||
453 | char *event_data; | ||
454 | u32 type, status; | ||
455 | u16 flags; | ||
456 | int evlen; | ||
457 | |||
458 | if (memcmp(BRCM_OUI, &pvt_data->hdr.oui[0], DOT11_OUI_LEN)) { | ||
459 | brcmf_dbg(ERROR, "mismatched OUI, bailing\n"); | ||
460 | return -EBADE; | ||
461 | } | ||
462 | |||
463 | /* BRCM event pkt may be unaligned - use xxx_ua to load user_subtype. */ | ||
464 | if (get_unaligned_be16(&pvt_data->hdr.usr_subtype) != | ||
465 | BCMILCP_BCM_SUBTYPE_EVENT) { | ||
466 | brcmf_dbg(ERROR, "mismatched subtype, bailing\n"); | ||
467 | return -EBADE; | ||
468 | } | ||
469 | |||
470 | *data_ptr = &pvt_data[1]; | ||
471 | event_data = *data_ptr; | ||
472 | |||
473 | /* memcpy since BRCM event pkt may be unaligned. */ | ||
474 | memcpy(event, &pvt_data->msg, sizeof(struct brcmf_event_msg)); | ||
475 | |||
476 | type = get_unaligned_be32(&event->event_type); | ||
477 | flags = get_unaligned_be16(&event->flags); | ||
478 | status = get_unaligned_be32(&event->status); | ||
479 | evlen = get_unaligned_be32(&event->datalen) + | ||
480 | sizeof(struct brcmf_event); | ||
481 | |||
482 | switch (type) { | ||
483 | case BRCMF_E_IF: | ||
484 | ifevent = (struct brcmf_if_event *) event_data; | ||
485 | brcmf_dbg(TRACE, "if event\n"); | ||
486 | |||
487 | if (ifevent->ifidx > 0 && ifevent->ifidx < BRCMF_MAX_IFS) { | ||
488 | if (ifevent->action == BRCMF_E_IF_ADD) { | ||
489 | ifp = brcmf_add_if(drvr->dev, ifevent->ifidx, | ||
490 | ifevent->bssidx, | ||
491 | event->ifname, | ||
492 | pvt_data->eth.h_dest); | ||
493 | if (IS_ERR(ifp)) | ||
494 | return PTR_ERR(ifp); | ||
495 | brcmf_net_attach(ifp); | ||
496 | } else { | ||
497 | brcmf_del_if(drvr, ifevent->ifidx); | ||
498 | } | ||
499 | } else { | ||
500 | brcmf_dbg(ERROR, "Invalid ifidx %d for %s\n", | ||
501 | ifevent->ifidx, event->ifname); | ||
502 | } | ||
503 | |||
504 | /* send up the if event: btamp user needs it */ | ||
505 | *ifidx = brcmf_ifname2idx(drvr, event->ifname); | ||
506 | break; | ||
507 | |||
508 | /* These are what external supplicant/authenticator wants */ | ||
509 | case BRCMF_E_LINK: | ||
510 | case BRCMF_E_ASSOC_IND: | ||
511 | case BRCMF_E_REASSOC_IND: | ||
512 | case BRCMF_E_DISASSOC_IND: | ||
513 | case BRCMF_E_MIC_ERROR: | ||
514 | default: | ||
515 | /* Fall through: this should get _everything_ */ | ||
516 | |||
517 | *ifidx = brcmf_ifname2idx(drvr, event->ifname); | ||
518 | brcmf_dbg(TRACE, "MAC event %d, flags %x, status %x\n", | ||
519 | type, flags, status); | ||
520 | |||
521 | /* put it back to BRCMF_E_NDIS_LINK */ | ||
522 | if (type == BRCMF_E_NDIS_LINK) { | ||
523 | u32 temp1; | ||
524 | __be32 temp2; | ||
525 | |||
526 | temp1 = get_unaligned_be32(&event->event_type); | ||
527 | brcmf_dbg(TRACE, "Converted to WLC_E_LINK type %d\n", | ||
528 | temp1); | ||
529 | |||
530 | temp2 = cpu_to_be32(BRCMF_E_NDIS_LINK); | ||
531 | memcpy((void *)(&pvt_data->msg.event_type), &temp2, | ||
532 | sizeof(pvt_data->msg.event_type)); | ||
533 | } | ||
534 | break; | ||
535 | } | ||
536 | |||
537 | #ifdef DEBUG | ||
538 | if (BRCMF_EVENT_ON()) | ||
539 | brcmf_c_show_host_event(event, event_data); | ||
540 | #endif /* DEBUG */ | ||
541 | |||
542 | return 0; | ||
543 | } | ||
544 | |||
545 | /* Convert user's input in hex pattern to byte-size mask */ | 97 | /* Convert user's input in hex pattern to byte-size mask */ |
546 | static int brcmf_c_pattern_atoh(char *src, char *dst) | 98 | static int brcmf_c_pattern_atoh(char *src, char *dst) |
547 | { | 99 | { |
@@ -686,8 +238,8 @@ static void brcmf_c_pktfilter_offload_set(struct brcmf_if *ifp, char *arg) | |||
686 | } | 238 | } |
687 | 239 | ||
688 | pkt_filter->u.pattern.size_bytes = cpu_to_le32(mask_size); | 240 | pkt_filter->u.pattern.size_bytes = cpu_to_le32(mask_size); |
689 | buf_len = sizeof(*pkt_filter); | 241 | buf_len = offsetof(struct brcmf_pkt_filter_le, |
690 | buf_len -= sizeof(pkt_filter->u.pattern.mask_and_pattern); | 242 | u.pattern.mask_and_pattern); |
691 | buf_len += mask_size + pattern_size; | 243 | buf_len += mask_size + pattern_size; |
692 | 244 | ||
693 | err = brcmf_fil_iovar_data_set(ifp, "pkt_filter_add", pkt_filter, | 245 | err = brcmf_fil_iovar_data_set(ifp, "pkt_filter_add", pkt_filter, |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c index 862d2acb7a16..7e58e8ce9aba 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c | |||
@@ -14,18 +14,12 @@ | |||
14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
15 | */ | 15 | */ |
16 | #include <linux/debugfs.h> | 16 | #include <linux/debugfs.h> |
17 | #include <linux/if_ether.h> | ||
18 | #include <linux/if.h> | ||
19 | #include <linux/netdevice.h> | 17 | #include <linux/netdevice.h> |
20 | #include <linux/ieee80211.h> | ||
21 | #include <linux/module.h> | 18 | #include <linux/module.h> |
22 | #include <linux/netdevice.h> | ||
23 | 19 | ||
24 | #include <defs.h> | ||
25 | #include <brcmu_wifi.h> | 20 | #include <brcmu_wifi.h> |
26 | #include <brcmu_utils.h> | 21 | #include <brcmu_utils.h> |
27 | #include "dhd.h" | 22 | #include "dhd.h" |
28 | #include "dhd_bus.h" | ||
29 | #include "dhd_dbg.h" | 23 | #include "dhd_dbg.h" |
30 | 24 | ||
31 | static struct dentry *root_folder; | 25 | static struct dentry *root_folder; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h index eefa6c2560cc..a0e18a1ceb4b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h | |||
@@ -27,11 +27,11 @@ | |||
27 | #define BRCMF_HDRS_VAL 0x0040 | 27 | #define BRCMF_HDRS_VAL 0x0040 |
28 | #define BRCMF_BYTES_VAL 0x0080 | 28 | #define BRCMF_BYTES_VAL 0x0080 |
29 | #define BRCMF_INTR_VAL 0x0100 | 29 | #define BRCMF_INTR_VAL 0x0100 |
30 | #define BRCMF_GLOM_VAL 0x0400 | 30 | #define BRCMF_GLOM_VAL 0x0200 |
31 | #define BRCMF_EVENT_VAL 0x0800 | 31 | #define BRCMF_EVENT_VAL 0x0400 |
32 | #define BRCMF_BTA_VAL 0x1000 | 32 | #define BRCMF_BTA_VAL 0x0800 |
33 | #define BRCMF_ISCAN_VAL 0x2000 | 33 | #define BRCMF_FIL_VAL 0x1000 |
34 | #define BRCMF_FIL_VAL 0x4000 | 34 | #define BRCMF_USB_VAL 0x2000 |
35 | 35 | ||
36 | #if defined(DEBUG) | 36 | #if defined(DEBUG) |
37 | 37 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 297652339fda..b6c86b046c15 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | |||
@@ -16,27 +16,11 @@ | |||
16 | 16 | ||
17 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 17 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
18 | 18 | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
21 | #include <linux/kthread.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/skbuff.h> | ||
24 | #include <linux/netdevice.h> | ||
25 | #include <linux/etherdevice.h> | 20 | #include <linux/etherdevice.h> |
26 | #include <linux/mmc/sdio_func.h> | ||
27 | #include <linux/random.h> | ||
28 | #include <linux/spinlock.h> | ||
29 | #include <linux/ethtool.h> | ||
30 | #include <linux/fcntl.h> | ||
31 | #include <linux/fs.h> | ||
32 | #include <linux/uaccess.h> | ||
33 | #include <linux/hardirq.h> | ||
34 | #include <linux/mutex.h> | ||
35 | #include <linux/wait.h> | ||
36 | #include <linux/module.h> | 21 | #include <linux/module.h> |
37 | #include <net/cfg80211.h> | 22 | #include <net/cfg80211.h> |
38 | #include <net/rtnetlink.h> | 23 | #include <net/rtnetlink.h> |
39 | #include <defs.h> | ||
40 | #include <brcmu_utils.h> | 24 | #include <brcmu_utils.h> |
41 | #include <brcmu_wifi.h> | 25 | #include <brcmu_wifi.h> |
42 | 26 | ||
@@ -45,35 +29,19 @@ | |||
45 | #include "dhd_proto.h" | 29 | #include "dhd_proto.h" |
46 | #include "dhd_dbg.h" | 30 | #include "dhd_dbg.h" |
47 | #include "wl_cfg80211.h" | 31 | #include "wl_cfg80211.h" |
32 | #include "fwil.h" | ||
48 | 33 | ||
49 | MODULE_AUTHOR("Broadcom Corporation"); | 34 | MODULE_AUTHOR("Broadcom Corporation"); |
50 | MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac driver."); | 35 | MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); |
51 | MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac cards"); | 36 | MODULE_SUPPORTED_DEVICE("Broadcom 802.11 WLAN fullmac cards"); |
52 | MODULE_LICENSE("Dual BSD/GPL"); | 37 | MODULE_LICENSE("Dual BSD/GPL"); |
53 | 38 | ||
39 | #define MAX_WAIT_FOR_8021X_TX 50 /* msecs */ | ||
54 | 40 | ||
55 | /* Error bits */ | 41 | /* Error bits */ |
56 | int brcmf_msg_level = BRCMF_ERROR_VAL; | 42 | int brcmf_msg_level = BRCMF_ERROR_VAL; |
57 | module_param(brcmf_msg_level, int, 0); | 43 | module_param(brcmf_msg_level, int, 0); |
58 | 44 | ||
59 | int brcmf_ifname2idx(struct brcmf_pub *drvr, char *name) | ||
60 | { | ||
61 | int i = BRCMF_MAX_IFS; | ||
62 | struct brcmf_if *ifp; | ||
63 | |||
64 | if (name == NULL || *name == '\0') | ||
65 | return 0; | ||
66 | |||
67 | while (--i > 0) { | ||
68 | ifp = drvr->iflist[i]; | ||
69 | if (ifp && !strncmp(ifp->ndev->name, name, IFNAMSIZ)) | ||
70 | break; | ||
71 | } | ||
72 | |||
73 | brcmf_dbg(TRACE, "return idx %d for \"%s\"\n", i, name); | ||
74 | |||
75 | return i; /* default - the primary interface */ | ||
76 | } | ||
77 | 45 | ||
78 | char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx) | 46 | char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx) |
79 | { | 47 | { |
@@ -95,38 +63,33 @@ char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx) | |||
95 | 63 | ||
96 | static void _brcmf_set_multicast_list(struct work_struct *work) | 64 | static void _brcmf_set_multicast_list(struct work_struct *work) |
97 | { | 65 | { |
66 | struct brcmf_if *ifp; | ||
98 | struct net_device *ndev; | 67 | struct net_device *ndev; |
99 | struct netdev_hw_addr *ha; | 68 | struct netdev_hw_addr *ha; |
100 | u32 dcmd_value, cnt; | 69 | u32 cmd_value, cnt; |
101 | __le32 cnt_le; | 70 | __le32 cnt_le; |
102 | __le32 dcmd_le_value; | ||
103 | |||
104 | struct brcmf_dcmd dcmd; | ||
105 | char *buf, *bufp; | 71 | char *buf, *bufp; |
106 | uint buflen; | 72 | u32 buflen; |
107 | int ret; | 73 | s32 err; |
108 | 74 | ||
109 | struct brcmf_pub *drvr = container_of(work, struct brcmf_pub, | 75 | brcmf_dbg(TRACE, "enter\n"); |
110 | multicast_work); | ||
111 | 76 | ||
112 | ndev = drvr->iflist[0]->ndev; | 77 | ifp = container_of(work, struct brcmf_if, multicast_work); |
113 | cnt = netdev_mc_count(ndev); | 78 | ndev = ifp->ndev; |
114 | 79 | ||
115 | /* Determine initial value of allmulti flag */ | 80 | /* Determine initial value of allmulti flag */ |
116 | dcmd_value = (ndev->flags & IFF_ALLMULTI) ? true : false; | 81 | cmd_value = (ndev->flags & IFF_ALLMULTI) ? true : false; |
117 | 82 | ||
118 | /* Send down the multicast list first. */ | 83 | /* Send down the multicast list first. */ |
119 | 84 | cnt = netdev_mc_count(ndev); | |
120 | buflen = sizeof("mcast_list") + sizeof(cnt) + (cnt * ETH_ALEN); | 85 | buflen = sizeof(cnt) + (cnt * ETH_ALEN); |
121 | bufp = buf = kmalloc(buflen, GFP_ATOMIC); | 86 | buf = kmalloc(buflen, GFP_ATOMIC); |
122 | if (!bufp) | 87 | if (!buf) |
123 | return; | 88 | return; |
124 | 89 | bufp = buf; | |
125 | strcpy(bufp, "mcast_list"); | ||
126 | bufp += strlen("mcast_list") + 1; | ||
127 | 90 | ||
128 | cnt_le = cpu_to_le32(cnt); | 91 | cnt_le = cpu_to_le32(cnt); |
129 | memcpy(bufp, &cnt_le, sizeof(cnt)); | 92 | memcpy(bufp, &cnt_le, sizeof(cnt_le)); |
130 | bufp += sizeof(cnt_le); | 93 | bufp += sizeof(cnt_le); |
131 | 94 | ||
132 | netdev_for_each_mc_addr(ha, ndev) { | 95 | netdev_for_each_mc_addr(ha, ndev) { |
@@ -137,129 +100,66 @@ static void _brcmf_set_multicast_list(struct work_struct *work) | |||
137 | cnt--; | 100 | cnt--; |
138 | } | 101 | } |
139 | 102 | ||
140 | memset(&dcmd, 0, sizeof(dcmd)); | 103 | err = brcmf_fil_iovar_data_set(ifp, "mcast_list", buf, buflen); |
141 | dcmd.cmd = BRCMF_C_SET_VAR; | 104 | if (err < 0) { |
142 | dcmd.buf = buf; | 105 | brcmf_dbg(ERROR, "Setting mcast_list failed, %d\n", err); |
143 | dcmd.len = buflen; | 106 | cmd_value = cnt ? true : cmd_value; |
144 | dcmd.set = true; | ||
145 | |||
146 | ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len); | ||
147 | if (ret < 0) { | ||
148 | brcmf_dbg(ERROR, "%s: set mcast_list failed, cnt %d\n", | ||
149 | brcmf_ifname(drvr, 0), cnt); | ||
150 | dcmd_value = cnt ? true : dcmd_value; | ||
151 | } | 107 | } |
152 | 108 | ||
153 | kfree(buf); | 109 | kfree(buf); |
154 | 110 | ||
155 | /* Now send the allmulti setting. This is based on the setting in the | 111 | /* |
112 | * Now send the allmulti setting. This is based on the setting in the | ||
156 | * net_device flags, but might be modified above to be turned on if we | 113 | * net_device flags, but might be modified above to be turned on if we |
157 | * were trying to set some addresses and dongle rejected it... | 114 | * were trying to set some addresses and dongle rejected it... |
158 | */ | 115 | */ |
159 | 116 | err = brcmf_fil_iovar_int_set(ifp, "allmulti", cmd_value); | |
160 | buflen = sizeof("allmulti") + sizeof(dcmd_value); | 117 | if (err < 0) |
161 | buf = kmalloc(buflen, GFP_ATOMIC); | 118 | brcmf_dbg(ERROR, "Setting allmulti failed, %d\n", err); |
162 | if (!buf) | 119 | |
163 | return; | 120 | /*Finally, pick up the PROMISC flag */ |
164 | 121 | cmd_value = (ndev->flags & IFF_PROMISC) ? true : false; | |
165 | dcmd_le_value = cpu_to_le32(dcmd_value); | 122 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PROMISC, cmd_value); |
166 | 123 | if (err < 0) | |
167 | if (!brcmf_c_mkiovar | 124 | brcmf_dbg(ERROR, "Setting BRCMF_C_SET_PROMISC failed, %d\n", |
168 | ("allmulti", (void *)&dcmd_le_value, | 125 | err); |
169 | sizeof(dcmd_le_value), buf, buflen)) { | ||
170 | brcmf_dbg(ERROR, "%s: mkiovar failed for allmulti, datalen %d buflen %u\n", | ||
171 | brcmf_ifname(drvr, 0), | ||
172 | (int)sizeof(dcmd_value), buflen); | ||
173 | kfree(buf); | ||
174 | return; | ||
175 | } | ||
176 | |||
177 | memset(&dcmd, 0, sizeof(dcmd)); | ||
178 | dcmd.cmd = BRCMF_C_SET_VAR; | ||
179 | dcmd.buf = buf; | ||
180 | dcmd.len = buflen; | ||
181 | dcmd.set = true; | ||
182 | |||
183 | ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len); | ||
184 | if (ret < 0) { | ||
185 | brcmf_dbg(ERROR, "%s: set allmulti %d failed\n", | ||
186 | brcmf_ifname(drvr, 0), | ||
187 | le32_to_cpu(dcmd_le_value)); | ||
188 | } | ||
189 | |||
190 | kfree(buf); | ||
191 | |||
192 | /* Finally, pick up the PROMISC flag as well, like the NIC | ||
193 | driver does */ | ||
194 | |||
195 | dcmd_value = (ndev->flags & IFF_PROMISC) ? true : false; | ||
196 | dcmd_le_value = cpu_to_le32(dcmd_value); | ||
197 | |||
198 | memset(&dcmd, 0, sizeof(dcmd)); | ||
199 | dcmd.cmd = BRCMF_C_SET_PROMISC; | ||
200 | dcmd.buf = &dcmd_le_value; | ||
201 | dcmd.len = sizeof(dcmd_le_value); | ||
202 | dcmd.set = true; | ||
203 | |||
204 | ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len); | ||
205 | if (ret < 0) { | ||
206 | brcmf_dbg(ERROR, "%s: set promisc %d failed\n", | ||
207 | brcmf_ifname(drvr, 0), | ||
208 | le32_to_cpu(dcmd_le_value)); | ||
209 | } | ||
210 | } | 126 | } |
211 | 127 | ||
212 | static void | 128 | static void |
213 | _brcmf_set_mac_address(struct work_struct *work) | 129 | _brcmf_set_mac_address(struct work_struct *work) |
214 | { | 130 | { |
215 | char buf[32]; | 131 | struct brcmf_if *ifp; |
216 | struct brcmf_dcmd dcmd; | 132 | s32 err; |
217 | int ret; | ||
218 | |||
219 | struct brcmf_pub *drvr = container_of(work, struct brcmf_pub, | ||
220 | setmacaddr_work); | ||
221 | 133 | ||
222 | brcmf_dbg(TRACE, "enter\n"); | 134 | brcmf_dbg(TRACE, "enter\n"); |
223 | if (!brcmf_c_mkiovar("cur_etheraddr", (char *)drvr->macvalue, | ||
224 | ETH_ALEN, buf, 32)) { | ||
225 | brcmf_dbg(ERROR, "%s: mkiovar failed for cur_etheraddr\n", | ||
226 | brcmf_ifname(drvr, 0)); | ||
227 | return; | ||
228 | } | ||
229 | memset(&dcmd, 0, sizeof(dcmd)); | ||
230 | dcmd.cmd = BRCMF_C_SET_VAR; | ||
231 | dcmd.buf = buf; | ||
232 | dcmd.len = 32; | ||
233 | dcmd.set = true; | ||
234 | 135 | ||
235 | ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len); | 136 | ifp = container_of(work, struct brcmf_if, setmacaddr_work); |
236 | if (ret < 0) | 137 | err = brcmf_fil_iovar_data_set(ifp, "cur_etheraddr", ifp->mac_addr, |
237 | brcmf_dbg(ERROR, "%s: set cur_etheraddr failed\n", | 138 | ETH_ALEN); |
238 | brcmf_ifname(drvr, 0)); | 139 | if (err < 0) { |
239 | else | 140 | brcmf_dbg(ERROR, "Setting cur_etheraddr failed, %d\n", err); |
240 | memcpy(drvr->iflist[0]->ndev->dev_addr, | 141 | } else { |
241 | drvr->macvalue, ETH_ALEN); | 142 | brcmf_dbg(TRACE, "MAC address updated to %pM\n", |
242 | 143 | ifp->mac_addr); | |
243 | return; | 144 | memcpy(ifp->ndev->dev_addr, ifp->mac_addr, ETH_ALEN); |
145 | } | ||
244 | } | 146 | } |
245 | 147 | ||
246 | static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr) | 148 | static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr) |
247 | { | 149 | { |
248 | struct brcmf_if *ifp = netdev_priv(ndev); | 150 | struct brcmf_if *ifp = netdev_priv(ndev); |
249 | struct brcmf_pub *drvr = ifp->drvr; | ||
250 | struct sockaddr *sa = (struct sockaddr *)addr; | 151 | struct sockaddr *sa = (struct sockaddr *)addr; |
251 | 152 | ||
252 | memcpy(&drvr->macvalue, sa->sa_data, ETH_ALEN); | 153 | memcpy(&ifp->mac_addr, sa->sa_data, ETH_ALEN); |
253 | schedule_work(&drvr->setmacaddr_work); | 154 | schedule_work(&ifp->setmacaddr_work); |
254 | return 0; | 155 | return 0; |
255 | } | 156 | } |
256 | 157 | ||
257 | static void brcmf_netdev_set_multicast_list(struct net_device *ndev) | 158 | static void brcmf_netdev_set_multicast_list(struct net_device *ndev) |
258 | { | 159 | { |
259 | struct brcmf_if *ifp = netdev_priv(ndev); | 160 | struct brcmf_if *ifp = netdev_priv(ndev); |
260 | struct brcmf_pub *drvr = ifp->drvr; | ||
261 | 161 | ||
262 | schedule_work(&drvr->multicast_work); | 162 | schedule_work(&ifp->multicast_work); |
263 | } | 163 | } |
264 | 164 | ||
265 | static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) | 165 | static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) |
@@ -272,7 +172,7 @@ static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
272 | 172 | ||
273 | /* Reject if down */ | 173 | /* Reject if down */ |
274 | if (!drvr->bus_if->drvr_up || | 174 | if (!drvr->bus_if->drvr_up || |
275 | (drvr->bus_if->state == BRCMF_BUS_DOWN)) { | 175 | (drvr->bus_if->state != BRCMF_BUS_DATA)) { |
276 | brcmf_dbg(ERROR, "xmit rejected drvup=%d state=%d\n", | 176 | brcmf_dbg(ERROR, "xmit rejected drvup=%d state=%d\n", |
277 | drvr->bus_if->drvr_up, | 177 | drvr->bus_if->drvr_up, |
278 | drvr->bus_if->state); | 178 | drvr->bus_if->state); |
@@ -350,32 +250,13 @@ void brcmf_txflowblock(struct device *dev, bool state) | |||
350 | } | 250 | } |
351 | } | 251 | } |
352 | 252 | ||
353 | static int brcmf_host_event(struct brcmf_pub *drvr, int *ifidx, | 253 | void brcmf_rx_frame(struct device *dev, u8 ifidx, |
354 | void *pktdata, struct brcmf_event_msg *event, | ||
355 | void **data) | ||
356 | { | ||
357 | int bcmerror = 0; | ||
358 | |||
359 | bcmerror = brcmf_c_host_event(drvr, ifidx, pktdata, event, data); | ||
360 | if (bcmerror != 0) | ||
361 | return bcmerror; | ||
362 | |||
363 | if (drvr->iflist[*ifidx]->ndev) | ||
364 | brcmf_cfg80211_event(drvr->iflist[*ifidx]->ndev, | ||
365 | event, *data); | ||
366 | |||
367 | return bcmerror; | ||
368 | } | ||
369 | |||
370 | void brcmf_rx_frame(struct device *dev, int ifidx, | ||
371 | struct sk_buff_head *skb_list) | 254 | struct sk_buff_head *skb_list) |
372 | { | 255 | { |
373 | unsigned char *eth; | 256 | unsigned char *eth; |
374 | uint len; | 257 | uint len; |
375 | void *data; | ||
376 | struct sk_buff *skb, *pnext; | 258 | struct sk_buff *skb, *pnext; |
377 | struct brcmf_if *ifp; | 259 | struct brcmf_if *ifp; |
378 | struct brcmf_event_msg event; | ||
379 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | 260 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); |
380 | struct brcmf_pub *drvr = bus_if->drvr; | 261 | struct brcmf_pub *drvr = bus_if->drvr; |
381 | 262 | ||
@@ -422,10 +303,7 @@ void brcmf_rx_frame(struct device *dev, int ifidx, | |||
422 | skb_pull(skb, ETH_HLEN); | 303 | skb_pull(skb, ETH_HLEN); |
423 | 304 | ||
424 | /* Process special event packets and then discard them */ | 305 | /* Process special event packets and then discard them */ |
425 | if (ntohs(skb->protocol) == ETH_P_LINK_CTL) | 306 | brcmf_fweh_process_skb(drvr, skb, &ifidx); |
426 | brcmf_host_event(drvr, &ifidx, | ||
427 | skb_mac_header(skb), | ||
428 | &event, &data); | ||
429 | 307 | ||
430 | if (drvr->iflist[ifidx]) { | 308 | if (drvr->iflist[ifidx]) { |
431 | ifp = drvr->iflist[ifidx]; | 309 | ifp = drvr->iflist[ifidx]; |
@@ -461,9 +339,11 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success) | |||
461 | eh = (struct ethhdr *)(txp->data); | 339 | eh = (struct ethhdr *)(txp->data); |
462 | type = ntohs(eh->h_proto); | 340 | type = ntohs(eh->h_proto); |
463 | 341 | ||
464 | if (type == ETH_P_PAE) | 342 | if (type == ETH_P_PAE) { |
465 | atomic_dec(&drvr->pend_8021x_cnt); | 343 | atomic_dec(&drvr->pend_8021x_cnt); |
466 | 344 | if (waitqueue_active(&drvr->pend_8021x_wait)) | |
345 | wake_up(&drvr->pend_8021x_wait); | ||
346 | } | ||
467 | } | 347 | } |
468 | 348 | ||
469 | static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) | 349 | static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) |
@@ -487,83 +367,26 @@ static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) | |||
487 | return &ifp->stats; | 367 | return &ifp->stats; |
488 | } | 368 | } |
489 | 369 | ||
490 | /* Retrieve current toe component enables, which are kept | 370 | /* |
491 | as a bitmap in toe_ol iovar */ | 371 | * Set current toe component enables in toe_ol iovar, |
492 | static int brcmf_toe_get(struct brcmf_pub *drvr, int ifidx, u32 *toe_ol) | 372 | * and set toe global enable iovar |
493 | { | 373 | */ |
494 | struct brcmf_dcmd dcmd; | 374 | static int brcmf_toe_set(struct brcmf_if *ifp, u32 toe_ol) |
495 | __le32 toe_le; | ||
496 | char buf[32]; | ||
497 | int ret; | ||
498 | |||
499 | memset(&dcmd, 0, sizeof(dcmd)); | ||
500 | |||
501 | dcmd.cmd = BRCMF_C_GET_VAR; | ||
502 | dcmd.buf = buf; | ||
503 | dcmd.len = (uint) sizeof(buf); | ||
504 | dcmd.set = false; | ||
505 | |||
506 | strcpy(buf, "toe_ol"); | ||
507 | ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len); | ||
508 | if (ret < 0) { | ||
509 | /* Check for older dongle image that doesn't support toe_ol */ | ||
510 | if (ret == -EIO) { | ||
511 | brcmf_dbg(ERROR, "%s: toe not supported by device\n", | ||
512 | brcmf_ifname(drvr, ifidx)); | ||
513 | return -EOPNOTSUPP; | ||
514 | } | ||
515 | |||
516 | brcmf_dbg(INFO, "%s: could not get toe_ol: ret=%d\n", | ||
517 | brcmf_ifname(drvr, ifidx), ret); | ||
518 | return ret; | ||
519 | } | ||
520 | |||
521 | memcpy(&toe_le, buf, sizeof(u32)); | ||
522 | *toe_ol = le32_to_cpu(toe_le); | ||
523 | return 0; | ||
524 | } | ||
525 | |||
526 | /* Set current toe component enables in toe_ol iovar, | ||
527 | and set toe global enable iovar */ | ||
528 | static int brcmf_toe_set(struct brcmf_pub *drvr, int ifidx, u32 toe_ol) | ||
529 | { | 375 | { |
530 | struct brcmf_dcmd dcmd; | 376 | s32 err; |
531 | char buf[32]; | ||
532 | int ret; | ||
533 | __le32 toe_le = cpu_to_le32(toe_ol); | ||
534 | |||
535 | memset(&dcmd, 0, sizeof(dcmd)); | ||
536 | 377 | ||
537 | dcmd.cmd = BRCMF_C_SET_VAR; | 378 | err = brcmf_fil_iovar_int_set(ifp, "toe_ol", toe_ol); |
538 | dcmd.buf = buf; | 379 | if (err < 0) { |
539 | dcmd.len = (uint) sizeof(buf); | 380 | brcmf_dbg(ERROR, "Setting toe_ol failed, %d\n", err); |
540 | dcmd.set = true; | 381 | return err; |
541 | |||
542 | /* Set toe_ol as requested */ | ||
543 | strcpy(buf, "toe_ol"); | ||
544 | memcpy(&buf[sizeof("toe_ol")], &toe_le, sizeof(u32)); | ||
545 | |||
546 | ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len); | ||
547 | if (ret < 0) { | ||
548 | brcmf_dbg(ERROR, "%s: could not set toe_ol: ret=%d\n", | ||
549 | brcmf_ifname(drvr, ifidx), ret); | ||
550 | return ret; | ||
551 | } | 382 | } |
552 | 383 | ||
553 | /* Enable toe globally only if any components are enabled. */ | 384 | err = brcmf_fil_iovar_int_set(ifp, "toe", (toe_ol != 0)); |
554 | toe_le = cpu_to_le32(toe_ol != 0); | 385 | if (err < 0) |
386 | brcmf_dbg(ERROR, "Setting toe failed, %d\n", err); | ||
555 | 387 | ||
556 | strcpy(buf, "toe"); | 388 | return err; |
557 | memcpy(&buf[sizeof("toe")], &toe_le, sizeof(u32)); | ||
558 | 389 | ||
559 | ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len); | ||
560 | if (ret < 0) { | ||
561 | brcmf_dbg(ERROR, "%s: could not set toe: ret=%d\n", | ||
562 | brcmf_ifname(drvr, ifidx), ret); | ||
563 | return ret; | ||
564 | } | ||
565 | |||
566 | return 0; | ||
567 | } | 390 | } |
568 | 391 | ||
569 | static void brcmf_ethtool_get_drvinfo(struct net_device *ndev, | 392 | static void brcmf_ethtool_get_drvinfo(struct net_device *ndev, |
@@ -581,8 +404,9 @@ static const struct ethtool_ops brcmf_ethtool_ops = { | |||
581 | .get_drvinfo = brcmf_ethtool_get_drvinfo, | 404 | .get_drvinfo = brcmf_ethtool_get_drvinfo, |
582 | }; | 405 | }; |
583 | 406 | ||
584 | static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr) | 407 | static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr) |
585 | { | 408 | { |
409 | struct brcmf_pub *drvr = ifp->drvr; | ||
586 | struct ethtool_drvinfo info; | 410 | struct ethtool_drvinfo info; |
587 | char drvname[sizeof(info.driver)]; | 411 | char drvname[sizeof(info.driver)]; |
588 | u32 cmd; | 412 | u32 cmd; |
@@ -633,7 +457,7 @@ static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr) | |||
633 | /* Get toe offload components from dongle */ | 457 | /* Get toe offload components from dongle */ |
634 | case ETHTOOL_GRXCSUM: | 458 | case ETHTOOL_GRXCSUM: |
635 | case ETHTOOL_GTXCSUM: | 459 | case ETHTOOL_GTXCSUM: |
636 | ret = brcmf_toe_get(drvr, 0, &toe_cmpnt); | 460 | ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt); |
637 | if (ret < 0) | 461 | if (ret < 0) |
638 | return ret; | 462 | return ret; |
639 | 463 | ||
@@ -654,7 +478,7 @@ static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr) | |||
654 | return -EFAULT; | 478 | return -EFAULT; |
655 | 479 | ||
656 | /* Read the current settings, update and write back */ | 480 | /* Read the current settings, update and write back */ |
657 | ret = brcmf_toe_get(drvr, 0, &toe_cmpnt); | 481 | ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt); |
658 | if (ret < 0) | 482 | if (ret < 0) |
659 | return ret; | 483 | return ret; |
660 | 484 | ||
@@ -666,18 +490,16 @@ static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr) | |||
666 | else | 490 | else |
667 | toe_cmpnt &= ~csum_dir; | 491 | toe_cmpnt &= ~csum_dir; |
668 | 492 | ||
669 | ret = brcmf_toe_set(drvr, 0, toe_cmpnt); | 493 | ret = brcmf_toe_set(ifp, toe_cmpnt); |
670 | if (ret < 0) | 494 | if (ret < 0) |
671 | return ret; | 495 | return ret; |
672 | 496 | ||
673 | /* If setting TX checksum mode, tell Linux the new mode */ | 497 | /* If setting TX checksum mode, tell Linux the new mode */ |
674 | if (cmd == ETHTOOL_STXCSUM) { | 498 | if (cmd == ETHTOOL_STXCSUM) { |
675 | if (edata.data) | 499 | if (edata.data) |
676 | drvr->iflist[0]->ndev->features |= | 500 | ifp->ndev->features |= NETIF_F_IP_CSUM; |
677 | NETIF_F_IP_CSUM; | ||
678 | else | 501 | else |
679 | drvr->iflist[0]->ndev->features &= | 502 | ifp->ndev->features &= ~NETIF_F_IP_CSUM; |
680 | ~NETIF_F_IP_CSUM; | ||
681 | } | 503 | } |
682 | 504 | ||
683 | break; | 505 | break; |
@@ -701,7 +523,7 @@ static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr, | |||
701 | return -1; | 523 | return -1; |
702 | 524 | ||
703 | if (cmd == SIOCETHTOOL) | 525 | if (cmd == SIOCETHTOOL) |
704 | return brcmf_ethtool(drvr, ifr->ifr_data); | 526 | return brcmf_ethtool(ifp, ifr->ifr_data); |
705 | 527 | ||
706 | return -EOPNOTSUPP; | 528 | return -EOPNOTSUPP; |
707 | } | 529 | } |
@@ -712,10 +534,12 @@ static int brcmf_netdev_stop(struct net_device *ndev) | |||
712 | struct brcmf_pub *drvr = ifp->drvr; | 534 | struct brcmf_pub *drvr = ifp->drvr; |
713 | 535 | ||
714 | brcmf_dbg(TRACE, "Enter\n"); | 536 | brcmf_dbg(TRACE, "Enter\n"); |
715 | brcmf_cfg80211_down(drvr->config); | 537 | |
716 | if (drvr->bus_if->drvr_up == 0) | 538 | if (drvr->bus_if->drvr_up == 0) |
717 | return 0; | 539 | return 0; |
718 | 540 | ||
541 | brcmf_cfg80211_down(ndev); | ||
542 | |||
719 | /* Set state and stop OS transmissions */ | 543 | /* Set state and stop OS transmissions */ |
720 | drvr->bus_if->drvr_up = false; | 544 | drvr->bus_if->drvr_up = false; |
721 | netif_stop_queue(ndev); | 545 | netif_stop_queue(ndev); |
@@ -730,38 +554,35 @@ static int brcmf_netdev_open(struct net_device *ndev) | |||
730 | struct brcmf_bus *bus_if = drvr->bus_if; | 554 | struct brcmf_bus *bus_if = drvr->bus_if; |
731 | u32 toe_ol; | 555 | u32 toe_ol; |
732 | s32 ret = 0; | 556 | s32 ret = 0; |
733 | uint up = 0; | ||
734 | 557 | ||
735 | brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx); | 558 | brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx); |
736 | 559 | ||
737 | if (ifp->idx == 0) { /* do it only for primary eth0 */ | 560 | /* If bus is not ready, can't continue */ |
738 | /* If bus is not ready, can't continue */ | 561 | if (bus_if->state != BRCMF_BUS_DATA) { |
739 | if (bus_if->state != BRCMF_BUS_DATA) { | 562 | brcmf_dbg(ERROR, "failed bus is not ready\n"); |
740 | brcmf_dbg(ERROR, "failed bus is not ready\n"); | 563 | return -EAGAIN; |
741 | return -EAGAIN; | 564 | } |
742 | } | ||
743 | 565 | ||
744 | atomic_set(&drvr->pend_8021x_cnt, 0); | 566 | atomic_set(&drvr->pend_8021x_cnt, 0); |
745 | 567 | ||
746 | memcpy(ndev->dev_addr, drvr->mac, ETH_ALEN); | 568 | memcpy(ndev->dev_addr, drvr->mac, ETH_ALEN); |
747 | 569 | ||
748 | /* Get current TOE mode from dongle */ | 570 | /* Get current TOE mode from dongle */ |
749 | if (brcmf_toe_get(drvr, ifp->idx, &toe_ol) >= 0 | 571 | if (brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_ol) >= 0 |
750 | && (toe_ol & TOE_TX_CSUM_OL) != 0) | 572 | && (toe_ol & TOE_TX_CSUM_OL) != 0) |
751 | drvr->iflist[ifp->idx]->ndev->features |= | 573 | drvr->iflist[ifp->idx]->ndev->features |= |
752 | NETIF_F_IP_CSUM; | 574 | NETIF_F_IP_CSUM; |
753 | else | 575 | else |
754 | drvr->iflist[ifp->idx]->ndev->features &= | 576 | drvr->iflist[ifp->idx]->ndev->features &= |
755 | ~NETIF_F_IP_CSUM; | 577 | ~NETIF_F_IP_CSUM; |
756 | } | ||
757 | 578 | ||
758 | /* make sure RF is ready for work */ | 579 | /* make sure RF is ready for work */ |
759 | brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_UP, (char *)&up, sizeof(up)); | 580 | brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0); |
760 | 581 | ||
761 | /* Allow transmit calls */ | 582 | /* Allow transmit calls */ |
762 | netif_start_queue(ndev); | 583 | netif_start_queue(ndev); |
763 | drvr->bus_if->drvr_up = true; | 584 | drvr->bus_if->drvr_up = true; |
764 | if (brcmf_cfg80211_up(drvr->config)) { | 585 | if (brcmf_cfg80211_up(ndev)) { |
765 | brcmf_dbg(ERROR, "failed to bring up cfg80211\n"); | 586 | brcmf_dbg(ERROR, "failed to bring up cfg80211\n"); |
766 | return -1; | 587 | return -1; |
767 | } | 588 | } |
@@ -779,39 +600,38 @@ static const struct net_device_ops brcmf_netdev_ops_pri = { | |||
779 | .ndo_set_rx_mode = brcmf_netdev_set_multicast_list | 600 | .ndo_set_rx_mode = brcmf_netdev_set_multicast_list |
780 | }; | 601 | }; |
781 | 602 | ||
603 | static const struct net_device_ops brcmf_netdev_ops_virt = { | ||
604 | .ndo_open = brcmf_cfg80211_up, | ||
605 | .ndo_stop = brcmf_cfg80211_down, | ||
606 | .ndo_get_stats = brcmf_netdev_get_stats, | ||
607 | .ndo_do_ioctl = brcmf_netdev_ioctl_entry, | ||
608 | .ndo_start_xmit = brcmf_netdev_start_xmit, | ||
609 | .ndo_set_mac_address = brcmf_netdev_set_mac_address, | ||
610 | .ndo_set_rx_mode = brcmf_netdev_set_multicast_list | ||
611 | }; | ||
612 | |||
782 | int brcmf_net_attach(struct brcmf_if *ifp) | 613 | int brcmf_net_attach(struct brcmf_if *ifp) |
783 | { | 614 | { |
784 | struct brcmf_pub *drvr = ifp->drvr; | 615 | struct brcmf_pub *drvr = ifp->drvr; |
785 | struct net_device *ndev; | 616 | struct net_device *ndev; |
786 | u8 temp_addr[ETH_ALEN]; | ||
787 | |||
788 | brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx); | ||
789 | 617 | ||
790 | ndev = drvr->iflist[ifp->idx]->ndev; | 618 | brcmf_dbg(TRACE, "ifidx %d mac %pM\n", ifp->idx, ifp->mac_addr); |
791 | ndev->netdev_ops = &brcmf_netdev_ops_pri; | 619 | ndev = ifp->ndev; |
792 | 620 | ||
793 | /* | 621 | /* set appropriate operations */ |
794 | * determine mac address to use | 622 | if (!ifp->idx) |
795 | */ | 623 | ndev->netdev_ops = &brcmf_netdev_ops_pri; |
796 | if (is_valid_ether_addr(ifp->mac_addr)) | ||
797 | memcpy(temp_addr, ifp->mac_addr, ETH_ALEN); | ||
798 | else | 624 | else |
799 | memcpy(temp_addr, drvr->mac, ETH_ALEN); | 625 | ndev->netdev_ops = &brcmf_netdev_ops_virt; |
800 | |||
801 | if (ifp->idx == 1) { | ||
802 | brcmf_dbg(TRACE, "ACCESS POINT MAC:\n"); | ||
803 | /* ACCESSPOINT INTERFACE CASE */ | ||
804 | temp_addr[0] |= 0X02; /* set bit 2 , | ||
805 | - Locally Administered address */ | ||
806 | 626 | ||
807 | } | ||
808 | ndev->hard_header_len = ETH_HLEN + drvr->hdrlen; | 627 | ndev->hard_header_len = ETH_HLEN + drvr->hdrlen; |
809 | ndev->ethtool_ops = &brcmf_ethtool_ops; | 628 | ndev->ethtool_ops = &brcmf_ethtool_ops; |
810 | 629 | ||
811 | drvr->rxsz = ndev->mtu + ndev->hard_header_len + | 630 | drvr->rxsz = ndev->mtu + ndev->hard_header_len + |
812 | drvr->hdrlen; | 631 | drvr->hdrlen; |
813 | 632 | ||
814 | memcpy(ndev->dev_addr, temp_addr, ETH_ALEN); | 633 | /* set the mac address */ |
634 | memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN); | ||
815 | 635 | ||
816 | if (register_netdev(ndev) != 0) { | 636 | if (register_netdev(ndev) != 0) { |
817 | brcmf_dbg(ERROR, "couldn't register the net device\n"); | 637 | brcmf_dbg(ERROR, "couldn't register the net device\n"); |
@@ -824,17 +644,15 @@ int brcmf_net_attach(struct brcmf_if *ifp) | |||
824 | 644 | ||
825 | fail: | 645 | fail: |
826 | ndev->netdev_ops = NULL; | 646 | ndev->netdev_ops = NULL; |
827 | free_netdev(ndev); | ||
828 | return -EBADE; | 647 | return -EBADE; |
829 | } | 648 | } |
830 | 649 | ||
831 | struct brcmf_if *brcmf_add_if(struct device *dev, int ifidx, s32 bssidx, | 650 | struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, int ifidx, s32 bssidx, |
832 | char *name, u8 *mac_addr) | 651 | char *name, u8 *addr_mask) |
833 | { | 652 | { |
834 | struct brcmf_if *ifp; | 653 | struct brcmf_if *ifp; |
835 | struct net_device *ndev; | 654 | struct net_device *ndev; |
836 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | 655 | int i; |
837 | struct brcmf_pub *drvr = bus_if->drvr; | ||
838 | 656 | ||
839 | brcmf_dbg(TRACE, "idx %d\n", ifidx); | 657 | brcmf_dbg(TRACE, "idx %d\n", ifidx); |
840 | 658 | ||
@@ -844,12 +662,17 @@ struct brcmf_if *brcmf_add_if(struct device *dev, int ifidx, s32 bssidx, | |||
844 | * in case we missed the BRCMF_E_IF_DEL event. | 662 | * in case we missed the BRCMF_E_IF_DEL event. |
845 | */ | 663 | */ |
846 | if (ifp) { | 664 | if (ifp) { |
847 | brcmf_dbg(ERROR, "ERROR: netdev:%s already exists, try free & unregister\n", | 665 | brcmf_dbg(ERROR, "ERROR: netdev:%s already exists\n", |
848 | ifp->ndev->name); | 666 | ifp->ndev->name); |
849 | netif_stop_queue(ifp->ndev); | 667 | if (ifidx) { |
850 | unregister_netdev(ifp->ndev); | 668 | netif_stop_queue(ifp->ndev); |
851 | free_netdev(ifp->ndev); | 669 | unregister_netdev(ifp->ndev); |
852 | drvr->iflist[ifidx] = NULL; | 670 | free_netdev(ifp->ndev); |
671 | drvr->iflist[ifidx] = NULL; | ||
672 | } else { | ||
673 | brcmf_dbg(ERROR, "ignore IF event\n"); | ||
674 | return ERR_PTR(-EINVAL); | ||
675 | } | ||
853 | } | 676 | } |
854 | 677 | ||
855 | /* Allocate netdev, including space for private structure */ | 678 | /* Allocate netdev, including space for private structure */ |
@@ -865,11 +688,16 @@ struct brcmf_if *brcmf_add_if(struct device *dev, int ifidx, s32 bssidx, | |||
865 | drvr->iflist[ifidx] = ifp; | 688 | drvr->iflist[ifidx] = ifp; |
866 | ifp->idx = ifidx; | 689 | ifp->idx = ifidx; |
867 | ifp->bssidx = bssidx; | 690 | ifp->bssidx = bssidx; |
868 | if (mac_addr != NULL) | ||
869 | memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN); | ||
870 | 691 | ||
871 | brcmf_dbg(TRACE, " ==== pid:%x, net_device for if:%s created ===\n", | 692 | INIT_WORK(&ifp->setmacaddr_work, _brcmf_set_mac_address); |
872 | current->pid, ifp->ndev->name); | 693 | INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list); |
694 | |||
695 | if (addr_mask != NULL) | ||
696 | for (i = 0; i < ETH_ALEN; i++) | ||
697 | ifp->mac_addr[i] = drvr->mac[i] ^ addr_mask[i]; | ||
698 | |||
699 | brcmf_dbg(TRACE, " ==== pid:%x, if:%s (%pM) created ===\n", | ||
700 | current->pid, ifp->ndev->name, ifp->mac_addr); | ||
873 | 701 | ||
874 | return ifp; | 702 | return ifp; |
875 | } | 703 | } |
@@ -896,6 +724,9 @@ void brcmf_del_if(struct brcmf_pub *drvr, int ifidx) | |||
896 | netif_stop_queue(ifp->ndev); | 724 | netif_stop_queue(ifp->ndev); |
897 | } | 725 | } |
898 | 726 | ||
727 | cancel_work_sync(&ifp->setmacaddr_work); | ||
728 | cancel_work_sync(&ifp->multicast_work); | ||
729 | |||
899 | unregister_netdev(ifp->ndev); | 730 | unregister_netdev(ifp->ndev); |
900 | drvr->iflist[ifidx] = NULL; | 731 | drvr->iflist[ifidx] = NULL; |
901 | if (ifidx == 0) | 732 | if (ifidx == 0) |
@@ -934,11 +765,13 @@ int brcmf_attach(uint bus_hdrlen, struct device *dev) | |||
934 | goto fail; | 765 | goto fail; |
935 | } | 766 | } |
936 | 767 | ||
937 | INIT_WORK(&drvr->setmacaddr_work, _brcmf_set_mac_address); | 768 | /* attach firmware event handler */ |
938 | INIT_WORK(&drvr->multicast_work, _brcmf_set_multicast_list); | 769 | brcmf_fweh_attach(drvr); |
939 | 770 | ||
940 | INIT_LIST_HEAD(&drvr->bus_if->dcmd_list); | 771 | INIT_LIST_HEAD(&drvr->bus_if->dcmd_list); |
941 | 772 | ||
773 | init_waitqueue_head(&drvr->pend_8021x_wait); | ||
774 | |||
942 | return ret; | 775 | return ret; |
943 | 776 | ||
944 | fail: | 777 | fail: |
@@ -964,7 +797,7 @@ int brcmf_bus_start(struct device *dev) | |||
964 | } | 797 | } |
965 | 798 | ||
966 | /* add primary networking interface */ | 799 | /* add primary networking interface */ |
967 | ifp = brcmf_add_if(dev, 0, 0, "wlan%d", NULL); | 800 | ifp = brcmf_add_if(drvr, 0, 0, "wlan%d", NULL); |
968 | if (IS_ERR(ifp)) | 801 | if (IS_ERR(ifp)) |
969 | return PTR_ERR(ifp); | 802 | return PTR_ERR(ifp); |
970 | 803 | ||
@@ -974,15 +807,25 @@ int brcmf_bus_start(struct device *dev) | |||
974 | /* Bus is ready, do any initialization */ | 807 | /* Bus is ready, do any initialization */ |
975 | ret = brcmf_c_preinit_dcmds(ifp); | 808 | ret = brcmf_c_preinit_dcmds(ifp); |
976 | if (ret < 0) | 809 | if (ret < 0) |
977 | return ret; | 810 | goto fail; |
978 | 811 | ||
979 | drvr->config = brcmf_cfg80211_attach(drvr); | 812 | drvr->config = brcmf_cfg80211_attach(drvr); |
980 | if (drvr->config == NULL) | 813 | if (drvr->config == NULL) { |
981 | return -ENOMEM; | 814 | ret = -ENOMEM; |
815 | goto fail; | ||
816 | } | ||
817 | |||
818 | ret = brcmf_fweh_activate_events(ifp); | ||
819 | if (ret < 0) | ||
820 | goto fail; | ||
982 | 821 | ||
983 | ret = brcmf_net_attach(ifp); | 822 | ret = brcmf_net_attach(ifp); |
823 | fail: | ||
984 | if (ret < 0) { | 824 | if (ret < 0) { |
985 | brcmf_dbg(ERROR, "brcmf_net_attach failed"); | 825 | brcmf_dbg(ERROR, "failed: %d\n", ret); |
826 | if (drvr->config) | ||
827 | brcmf_cfg80211_detach(drvr->config); | ||
828 | free_netdev(drvr->iflist[0]->ndev); | ||
986 | drvr->iflist[0] = NULL; | 829 | drvr->iflist[0] = NULL; |
987 | return ret; | 830 | return ret; |
988 | } | 831 | } |
@@ -1011,6 +854,11 @@ void brcmf_detach(struct device *dev) | |||
1011 | 854 | ||
1012 | brcmf_dbg(TRACE, "Enter\n"); | 855 | brcmf_dbg(TRACE, "Enter\n"); |
1013 | 856 | ||
857 | if (drvr == NULL) | ||
858 | return; | ||
859 | |||
860 | /* stop firmware event handling */ | ||
861 | brcmf_fweh_detach(drvr); | ||
1014 | 862 | ||
1015 | /* make sure primary interface removed last */ | 863 | /* make sure primary interface removed last */ |
1016 | for (i = BRCMF_MAX_IFS-1; i > -1; i--) | 864 | for (i = BRCMF_MAX_IFS-1; i > -1; i--) |
@@ -1020,8 +868,6 @@ void brcmf_detach(struct device *dev) | |||
1020 | brcmf_bus_detach(drvr); | 868 | brcmf_bus_detach(drvr); |
1021 | 869 | ||
1022 | if (drvr->prot) { | 870 | if (drvr->prot) { |
1023 | cancel_work_sync(&drvr->setmacaddr_work); | ||
1024 | cancel_work_sync(&drvr->multicast_work); | ||
1025 | brcmf_proto_detach(drvr); | 871 | brcmf_proto_detach(drvr); |
1026 | } | 872 | } |
1027 | 873 | ||
@@ -1035,26 +881,19 @@ static int brcmf_get_pend_8021x_cnt(struct brcmf_pub *drvr) | |||
1035 | return atomic_read(&drvr->pend_8021x_cnt); | 881 | return atomic_read(&drvr->pend_8021x_cnt); |
1036 | } | 882 | } |
1037 | 883 | ||
1038 | #define MAX_WAIT_FOR_8021X_TX 10 | ||
1039 | |||
1040 | int brcmf_netdev_wait_pend8021x(struct net_device *ndev) | 884 | int brcmf_netdev_wait_pend8021x(struct net_device *ndev) |
1041 | { | 885 | { |
1042 | struct brcmf_if *ifp = netdev_priv(ndev); | 886 | struct brcmf_if *ifp = netdev_priv(ndev); |
1043 | struct brcmf_pub *drvr = ifp->drvr; | 887 | struct brcmf_pub *drvr = ifp->drvr; |
1044 | int timeout = 10 * HZ / 1000; | 888 | int err; |
1045 | int ntimes = MAX_WAIT_FOR_8021X_TX; | 889 | |
1046 | int pend = brcmf_get_pend_8021x_cnt(drvr); | 890 | err = wait_event_timeout(drvr->pend_8021x_wait, |
1047 | 891 | !brcmf_get_pend_8021x_cnt(drvr), | |
1048 | while (ntimes && pend) { | 892 | msecs_to_jiffies(MAX_WAIT_FOR_8021X_TX)); |
1049 | if (pend) { | 893 | |
1050 | set_current_state(TASK_INTERRUPTIBLE); | 894 | WARN_ON(!err); |
1051 | schedule_timeout(timeout); | 895 | |
1052 | set_current_state(TASK_RUNNING); | 896 | return !err; |
1053 | ntimes--; | ||
1054 | } | ||
1055 | pend = brcmf_get_pend_8021x_cnt(drvr); | ||
1056 | } | ||
1057 | return pend; | ||
1058 | } | 897 | } |
1059 | 898 | ||
1060 | static void brcmf_driver_init(struct work_struct *work) | 899 | static void brcmf_driver_init(struct work_struct *work) |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h index 7fe6779b90cf..48fa70302192 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h | |||
@@ -36,14 +36,7 @@ extern void brcmf_proto_stop(struct brcmf_pub *drvr); | |||
36 | extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx, | 36 | extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx, |
37 | struct sk_buff *txp); | 37 | struct sk_buff *txp); |
38 | 38 | ||
39 | /* Use protocol to issue command to dongle */ | ||
40 | extern int brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx, | ||
41 | struct brcmf_dcmd *dcmd, int len); | ||
42 | |||
43 | /* Sets dongle media info (drv_version, mac address). */ | 39 | /* Sets dongle media info (drv_version, mac address). */ |
44 | extern int brcmf_c_preinit_dcmds(struct brcmf_if *ifp); | 40 | extern int brcmf_c_preinit_dcmds(struct brcmf_if *ifp); |
45 | 41 | ||
46 | extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, | ||
47 | uint cmd, void *buf, uint len); | ||
48 | |||
49 | #endif /* _BRCMF_PROTO_H_ */ | 42 | #endif /* _BRCMF_PROTO_H_ */ |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 415f2be36375..45725454714d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | |||
@@ -533,9 +533,11 @@ struct brcmf_sdio { | |||
533 | u8 *rxbuf; /* Buffer for receiving control packets */ | 533 | u8 *rxbuf; /* Buffer for receiving control packets */ |
534 | uint rxblen; /* Allocated length of rxbuf */ | 534 | uint rxblen; /* Allocated length of rxbuf */ |
535 | u8 *rxctl; /* Aligned pointer into rxbuf */ | 535 | u8 *rxctl; /* Aligned pointer into rxbuf */ |
536 | u8 *rxctl_orig; /* pointer for freeing rxctl */ | ||
536 | u8 *databuf; /* Buffer for receiving big glom packet */ | 537 | u8 *databuf; /* Buffer for receiving big glom packet */ |
537 | u8 *dataptr; /* Aligned pointer into databuf */ | 538 | u8 *dataptr; /* Aligned pointer into databuf */ |
538 | uint rxlen; /* Length of valid data in buffer */ | 539 | uint rxlen; /* Length of valid data in buffer */ |
540 | spinlock_t rxctl_lock; /* protection lock for ctrl frame resources */ | ||
539 | 541 | ||
540 | u8 sdpcm_ver; /* Bus protocol reported by dongle */ | 542 | u8 sdpcm_ver; /* Bus protocol reported by dongle */ |
541 | 543 | ||
@@ -582,8 +584,6 @@ struct brcmf_sdio { | |||
582 | struct list_head dpc_tsklst; | 584 | struct list_head dpc_tsklst; |
583 | spinlock_t dpc_tl_lock; | 585 | spinlock_t dpc_tl_lock; |
584 | 586 | ||
585 | struct semaphore sdsem; | ||
586 | |||
587 | const struct firmware *firmware; | 587 | const struct firmware *firmware; |
588 | u32 fw_ptr; | 588 | u32 fw_ptr; |
589 | 589 | ||
@@ -1037,9 +1037,9 @@ static void brcmf_sdbrcm_free_glom(struct brcmf_sdio *bus) | |||
1037 | } | 1037 | } |
1038 | } | 1038 | } |
1039 | 1039 | ||
1040 | static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, | 1040 | static int brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, |
1041 | struct brcmf_sdio_read *rd, | 1041 | struct brcmf_sdio_read *rd, |
1042 | enum brcmf_sdio_frmtype type) | 1042 | enum brcmf_sdio_frmtype type) |
1043 | { | 1043 | { |
1044 | u16 len, checksum; | 1044 | u16 len, checksum; |
1045 | u8 rx_seq, fc, tx_seq_max; | 1045 | u8 rx_seq, fc, tx_seq_max; |
@@ -1054,26 +1054,26 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, | |||
1054 | /* All zero means no more to read */ | 1054 | /* All zero means no more to read */ |
1055 | if (!(len | checksum)) { | 1055 | if (!(len | checksum)) { |
1056 | bus->rxpending = false; | 1056 | bus->rxpending = false; |
1057 | return false; | 1057 | return -ENODATA; |
1058 | } | 1058 | } |
1059 | if ((u16)(~(len ^ checksum))) { | 1059 | if ((u16)(~(len ^ checksum))) { |
1060 | brcmf_dbg(ERROR, "HW header checksum error\n"); | 1060 | brcmf_dbg(ERROR, "HW header checksum error\n"); |
1061 | bus->sdcnt.rx_badhdr++; | 1061 | bus->sdcnt.rx_badhdr++; |
1062 | brcmf_sdbrcm_rxfail(bus, false, false); | 1062 | brcmf_sdbrcm_rxfail(bus, false, false); |
1063 | return false; | 1063 | return -EIO; |
1064 | } | 1064 | } |
1065 | if (len < SDPCM_HDRLEN) { | 1065 | if (len < SDPCM_HDRLEN) { |
1066 | brcmf_dbg(ERROR, "HW header length error\n"); | 1066 | brcmf_dbg(ERROR, "HW header length error\n"); |
1067 | return false; | 1067 | return -EPROTO; |
1068 | } | 1068 | } |
1069 | if (type == BRCMF_SDIO_FT_SUPER && | 1069 | if (type == BRCMF_SDIO_FT_SUPER && |
1070 | (roundup(len, bus->blocksize) != rd->len)) { | 1070 | (roundup(len, bus->blocksize) != rd->len)) { |
1071 | brcmf_dbg(ERROR, "HW superframe header length error\n"); | 1071 | brcmf_dbg(ERROR, "HW superframe header length error\n"); |
1072 | return false; | 1072 | return -EPROTO; |
1073 | } | 1073 | } |
1074 | if (type == BRCMF_SDIO_FT_SUB && len > rd->len) { | 1074 | if (type == BRCMF_SDIO_FT_SUB && len > rd->len) { |
1075 | brcmf_dbg(ERROR, "HW subframe header length error\n"); | 1075 | brcmf_dbg(ERROR, "HW subframe header length error\n"); |
1076 | return false; | 1076 | return -EPROTO; |
1077 | } | 1077 | } |
1078 | rd->len = len; | 1078 | rd->len = len; |
1079 | 1079 | ||
@@ -1091,7 +1091,7 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, | |||
1091 | SDPCM_GLOMDESC(&header[SDPCM_FRAMETAG_LEN])) { | 1091 | SDPCM_GLOMDESC(&header[SDPCM_FRAMETAG_LEN])) { |
1092 | brcmf_dbg(ERROR, "Glom descriptor found in superframe head\n"); | 1092 | brcmf_dbg(ERROR, "Glom descriptor found in superframe head\n"); |
1093 | rd->len = 0; | 1093 | rd->len = 0; |
1094 | return false; | 1094 | return -EINVAL; |
1095 | } | 1095 | } |
1096 | rx_seq = SDPCM_PACKET_SEQUENCE(&header[SDPCM_FRAMETAG_LEN]); | 1096 | rx_seq = SDPCM_PACKET_SEQUENCE(&header[SDPCM_FRAMETAG_LEN]); |
1097 | rd->channel = SDPCM_PACKET_CHANNEL(&header[SDPCM_FRAMETAG_LEN]); | 1097 | rd->channel = SDPCM_PACKET_CHANNEL(&header[SDPCM_FRAMETAG_LEN]); |
@@ -1102,18 +1102,18 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, | |||
1102 | bus->sdcnt.rx_toolong++; | 1102 | bus->sdcnt.rx_toolong++; |
1103 | brcmf_sdbrcm_rxfail(bus, false, false); | 1103 | brcmf_sdbrcm_rxfail(bus, false, false); |
1104 | rd->len = 0; | 1104 | rd->len = 0; |
1105 | return false; | 1105 | return -EPROTO; |
1106 | } | 1106 | } |
1107 | if (type == BRCMF_SDIO_FT_SUPER && rd->channel != SDPCM_GLOM_CHANNEL) { | 1107 | if (type == BRCMF_SDIO_FT_SUPER && rd->channel != SDPCM_GLOM_CHANNEL) { |
1108 | brcmf_dbg(ERROR, "Wrong channel for superframe\n"); | 1108 | brcmf_dbg(ERROR, "Wrong channel for superframe\n"); |
1109 | rd->len = 0; | 1109 | rd->len = 0; |
1110 | return false; | 1110 | return -EINVAL; |
1111 | } | 1111 | } |
1112 | if (type == BRCMF_SDIO_FT_SUB && rd->channel != SDPCM_DATA_CHANNEL && | 1112 | if (type == BRCMF_SDIO_FT_SUB && rd->channel != SDPCM_DATA_CHANNEL && |
1113 | rd->channel != SDPCM_EVENT_CHANNEL) { | 1113 | rd->channel != SDPCM_EVENT_CHANNEL) { |
1114 | brcmf_dbg(ERROR, "Wrong channel for subframe\n"); | 1114 | brcmf_dbg(ERROR, "Wrong channel for subframe\n"); |
1115 | rd->len = 0; | 1115 | rd->len = 0; |
1116 | return false; | 1116 | return -EINVAL; |
1117 | } | 1117 | } |
1118 | rd->dat_offset = SDPCM_DOFFSET_VALUE(&header[SDPCM_FRAMETAG_LEN]); | 1118 | rd->dat_offset = SDPCM_DOFFSET_VALUE(&header[SDPCM_FRAMETAG_LEN]); |
1119 | if (rd->dat_offset < SDPCM_HDRLEN || rd->dat_offset > rd->len) { | 1119 | if (rd->dat_offset < SDPCM_HDRLEN || rd->dat_offset > rd->len) { |
@@ -1121,7 +1121,7 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, | |||
1121 | bus->sdcnt.rx_badhdr++; | 1121 | bus->sdcnt.rx_badhdr++; |
1122 | brcmf_sdbrcm_rxfail(bus, false, false); | 1122 | brcmf_sdbrcm_rxfail(bus, false, false); |
1123 | rd->len = 0; | 1123 | rd->len = 0; |
1124 | return false; | 1124 | return -ENXIO; |
1125 | } | 1125 | } |
1126 | if (rd->seq_num != rx_seq) { | 1126 | if (rd->seq_num != rx_seq) { |
1127 | brcmf_dbg(ERROR, "seq %d: sequence number error, expect %d\n", | 1127 | brcmf_dbg(ERROR, "seq %d: sequence number error, expect %d\n", |
@@ -1131,7 +1131,7 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, | |||
1131 | } | 1131 | } |
1132 | /* no need to check the reset for subframe */ | 1132 | /* no need to check the reset for subframe */ |
1133 | if (type == BRCMF_SDIO_FT_SUB) | 1133 | if (type == BRCMF_SDIO_FT_SUB) |
1134 | return true; | 1134 | return 0; |
1135 | rd->len_nxtfrm = header[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; | 1135 | rd->len_nxtfrm = header[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; |
1136 | if (rd->len_nxtfrm << 4 > MAX_RX_DATASZ) { | 1136 | if (rd->len_nxtfrm << 4 > MAX_RX_DATASZ) { |
1137 | /* only warm for NON glom packet */ | 1137 | /* only warm for NON glom packet */ |
@@ -1155,7 +1155,7 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, | |||
1155 | } | 1155 | } |
1156 | bus->tx_max = tx_seq_max; | 1156 | bus->tx_max = tx_seq_max; |
1157 | 1157 | ||
1158 | return true; | 1158 | return 0; |
1159 | } | 1159 | } |
1160 | 1160 | ||
1161 | static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) | 1161 | static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) |
@@ -1272,6 +1272,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) | |||
1272 | * read directly into the chained packet, or allocate a large | 1272 | * read directly into the chained packet, or allocate a large |
1273 | * packet and and copy into the chain. | 1273 | * packet and and copy into the chain. |
1274 | */ | 1274 | */ |
1275 | sdio_claim_host(bus->sdiodev->func[1]); | ||
1275 | if (usechain) { | 1276 | if (usechain) { |
1276 | errcode = brcmf_sdcard_recv_chain(bus->sdiodev, | 1277 | errcode = brcmf_sdcard_recv_chain(bus->sdiodev, |
1277 | bus->sdiodev->sbwad, | 1278 | bus->sdiodev->sbwad, |
@@ -1293,6 +1294,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) | |||
1293 | dlen); | 1294 | dlen); |
1294 | errcode = -1; | 1295 | errcode = -1; |
1295 | } | 1296 | } |
1297 | sdio_release_host(bus->sdiodev->func[1]); | ||
1296 | bus->sdcnt.f2rxdata++; | 1298 | bus->sdcnt.f2rxdata++; |
1297 | 1299 | ||
1298 | /* On failure, kill the superframe, allow a couple retries */ | 1300 | /* On failure, kill the superframe, allow a couple retries */ |
@@ -1301,6 +1303,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) | |||
1301 | dlen, errcode); | 1303 | dlen, errcode); |
1302 | bus->sdiodev->bus_if->dstats.rx_errors++; | 1304 | bus->sdiodev->bus_if->dstats.rx_errors++; |
1303 | 1305 | ||
1306 | sdio_claim_host(bus->sdiodev->func[1]); | ||
1304 | if (bus->glomerr++ < 3) { | 1307 | if (bus->glomerr++ < 3) { |
1305 | brcmf_sdbrcm_rxfail(bus, true, true); | 1308 | brcmf_sdbrcm_rxfail(bus, true, true); |
1306 | } else { | 1309 | } else { |
@@ -1309,6 +1312,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) | |||
1309 | bus->sdcnt.rxglomfail++; | 1312 | bus->sdcnt.rxglomfail++; |
1310 | brcmf_sdbrcm_free_glom(bus); | 1313 | brcmf_sdbrcm_free_glom(bus); |
1311 | } | 1314 | } |
1315 | sdio_release_host(bus->sdiodev->func[1]); | ||
1312 | return 0; | 1316 | return 0; |
1313 | } | 1317 | } |
1314 | 1318 | ||
@@ -1318,8 +1322,10 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) | |||
1318 | 1322 | ||
1319 | rd_new.seq_num = rxseq; | 1323 | rd_new.seq_num = rxseq; |
1320 | rd_new.len = dlen; | 1324 | rd_new.len = dlen; |
1321 | errcode = -!brcmf_sdio_hdparser(bus, pfirst->data, &rd_new, | 1325 | sdio_claim_host(bus->sdiodev->func[1]); |
1322 | BRCMF_SDIO_FT_SUPER); | 1326 | errcode = brcmf_sdio_hdparser(bus, pfirst->data, &rd_new, |
1327 | BRCMF_SDIO_FT_SUPER); | ||
1328 | sdio_release_host(bus->sdiodev->func[1]); | ||
1323 | bus->cur_read.len = rd_new.len_nxtfrm << 4; | 1329 | bus->cur_read.len = rd_new.len_nxtfrm << 4; |
1324 | 1330 | ||
1325 | /* Remove superframe header, remember offset */ | 1331 | /* Remove superframe header, remember offset */ |
@@ -1335,9 +1341,10 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) | |||
1335 | 1341 | ||
1336 | rd_new.len = pnext->len; | 1342 | rd_new.len = pnext->len; |
1337 | rd_new.seq_num = rxseq++; | 1343 | rd_new.seq_num = rxseq++; |
1338 | errcode = -!brcmf_sdio_hdparser(bus, pnext->data, | 1344 | sdio_claim_host(bus->sdiodev->func[1]); |
1339 | &rd_new, | 1345 | errcode = brcmf_sdio_hdparser(bus, pnext->data, &rd_new, |
1340 | BRCMF_SDIO_FT_SUB); | 1346 | BRCMF_SDIO_FT_SUB); |
1347 | sdio_release_host(bus->sdiodev->func[1]); | ||
1341 | brcmf_dbg_hex_dump(BRCMF_GLOM_ON(), | 1348 | brcmf_dbg_hex_dump(BRCMF_GLOM_ON(), |
1342 | pnext->data, 32, "subframe:\n"); | 1349 | pnext->data, 32, "subframe:\n"); |
1343 | 1350 | ||
@@ -1347,6 +1354,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) | |||
1347 | if (errcode) { | 1354 | if (errcode) { |
1348 | /* Terminate frame on error, request | 1355 | /* Terminate frame on error, request |
1349 | a couple retries */ | 1356 | a couple retries */ |
1357 | sdio_claim_host(bus->sdiodev->func[1]); | ||
1350 | if (bus->glomerr++ < 3) { | 1358 | if (bus->glomerr++ < 3) { |
1351 | /* Restore superframe header space */ | 1359 | /* Restore superframe header space */ |
1352 | skb_push(pfirst, sfdoff); | 1360 | skb_push(pfirst, sfdoff); |
@@ -1357,6 +1365,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) | |||
1357 | bus->sdcnt.rxglomfail++; | 1365 | bus->sdcnt.rxglomfail++; |
1358 | brcmf_sdbrcm_free_glom(bus); | 1366 | brcmf_sdbrcm_free_glom(bus); |
1359 | } | 1367 | } |
1368 | sdio_release_host(bus->sdiodev->func[1]); | ||
1360 | bus->cur_read.len = 0; | 1369 | bus->cur_read.len = 0; |
1361 | return 0; | 1370 | return 0; |
1362 | } | 1371 | } |
@@ -1397,11 +1406,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) | |||
1397 | pfirst->prev); | 1406 | pfirst->prev); |
1398 | } | 1407 | } |
1399 | /* sent any remaining packets up */ | 1408 | /* sent any remaining packets up */ |
1400 | if (bus->glom.qlen) { | 1409 | if (bus->glom.qlen) |
1401 | up(&bus->sdsem); | ||
1402 | brcmf_rx_frame(bus->sdiodev->dev, ifidx, &bus->glom); | 1410 | brcmf_rx_frame(bus->sdiodev->dev, ifidx, &bus->glom); |
1403 | down(&bus->sdsem); | ||
1404 | } | ||
1405 | 1411 | ||
1406 | bus->sdcnt.rxglomframes++; | 1412 | bus->sdcnt.rxglomframes++; |
1407 | bus->sdcnt.rxglompkts += bus->glom.qlen; | 1413 | bus->sdcnt.rxglompkts += bus->glom.qlen; |
@@ -1442,21 +1448,24 @@ static void | |||
1442 | brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) | 1448 | brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) |
1443 | { | 1449 | { |
1444 | uint rdlen, pad; | 1450 | uint rdlen, pad; |
1445 | 1451 | u8 *buf = NULL, *rbuf; | |
1446 | int sdret; | 1452 | int sdret; |
1447 | 1453 | ||
1448 | brcmf_dbg(TRACE, "Enter\n"); | 1454 | brcmf_dbg(TRACE, "Enter\n"); |
1449 | 1455 | ||
1450 | /* Set rxctl for frame (w/optional alignment) */ | 1456 | if (bus->rxblen) |
1451 | bus->rxctl = bus->rxbuf; | 1457 | buf = vzalloc(bus->rxblen); |
1452 | bus->rxctl += BRCMF_FIRSTREAD; | 1458 | if (!buf) { |
1453 | pad = ((unsigned long)bus->rxctl % BRCMF_SDALIGN); | 1459 | brcmf_dbg(ERROR, "no memory for control frame\n"); |
1460 | goto done; | ||
1461 | } | ||
1462 | rbuf = bus->rxbuf; | ||
1463 | pad = ((unsigned long)rbuf % BRCMF_SDALIGN); | ||
1454 | if (pad) | 1464 | if (pad) |
1455 | bus->rxctl += (BRCMF_SDALIGN - pad); | 1465 | rbuf += (BRCMF_SDALIGN - pad); |
1456 | bus->rxctl -= BRCMF_FIRSTREAD; | ||
1457 | 1466 | ||
1458 | /* Copy the already-read portion over */ | 1467 | /* Copy the already-read portion over */ |
1459 | memcpy(bus->rxctl, hdr, BRCMF_FIRSTREAD); | 1468 | memcpy(buf, hdr, BRCMF_FIRSTREAD); |
1460 | if (len <= BRCMF_FIRSTREAD) | 1469 | if (len <= BRCMF_FIRSTREAD) |
1461 | goto gotpkt; | 1470 | goto gotpkt; |
1462 | 1471 | ||
@@ -1493,11 +1502,11 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) | |||
1493 | goto done; | 1502 | goto done; |
1494 | } | 1503 | } |
1495 | 1504 | ||
1496 | /* Read remainder of frame body into the rxctl buffer */ | 1505 | /* Read remain of frame body */ |
1497 | sdret = brcmf_sdcard_recv_buf(bus->sdiodev, | 1506 | sdret = brcmf_sdcard_recv_buf(bus->sdiodev, |
1498 | bus->sdiodev->sbwad, | 1507 | bus->sdiodev->sbwad, |
1499 | SDIO_FUNC_2, | 1508 | SDIO_FUNC_2, |
1500 | F2SYNC, (bus->rxctl + BRCMF_FIRSTREAD), rdlen); | 1509 | F2SYNC, rbuf, rdlen); |
1501 | bus->sdcnt.f2rxdata++; | 1510 | bus->sdcnt.f2rxdata++; |
1502 | 1511 | ||
1503 | /* Control frame failures need retransmission */ | 1512 | /* Control frame failures need retransmission */ |
@@ -1507,16 +1516,26 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) | |||
1507 | bus->sdcnt.rxc_errors++; | 1516 | bus->sdcnt.rxc_errors++; |
1508 | brcmf_sdbrcm_rxfail(bus, true, true); | 1517 | brcmf_sdbrcm_rxfail(bus, true, true); |
1509 | goto done; | 1518 | goto done; |
1510 | } | 1519 | } else |
1520 | memcpy(buf + BRCMF_FIRSTREAD, rbuf, rdlen); | ||
1511 | 1521 | ||
1512 | gotpkt: | 1522 | gotpkt: |
1513 | 1523 | ||
1514 | brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(), | 1524 | brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(), |
1515 | bus->rxctl, len, "RxCtrl:\n"); | 1525 | buf, len, "RxCtrl:\n"); |
1516 | 1526 | ||
1517 | /* Point to valid data and indicate its length */ | 1527 | /* Point to valid data and indicate its length */ |
1518 | bus->rxctl += doff; | 1528 | spin_lock_bh(&bus->rxctl_lock); |
1529 | if (bus->rxctl) { | ||
1530 | brcmf_dbg(ERROR, "last control frame is being processed.\n"); | ||
1531 | spin_unlock_bh(&bus->rxctl_lock); | ||
1532 | vfree(buf); | ||
1533 | goto done; | ||
1534 | } | ||
1535 | bus->rxctl = buf + doff; | ||
1536 | bus->rxctl_orig = buf; | ||
1519 | bus->rxlen = len - doff; | 1537 | bus->rxlen = len - doff; |
1538 | spin_unlock_bh(&bus->rxctl_lock); | ||
1520 | 1539 | ||
1521 | done: | 1540 | done: |
1522 | /* Awake any waiters */ | 1541 | /* Awake any waiters */ |
@@ -1571,6 +1590,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) | |||
1571 | 1590 | ||
1572 | rd->len_left = rd->len; | 1591 | rd->len_left = rd->len; |
1573 | /* read header first for unknow frame length */ | 1592 | /* read header first for unknow frame length */ |
1593 | sdio_claim_host(bus->sdiodev->func[1]); | ||
1574 | if (!rd->len) { | 1594 | if (!rd->len) { |
1575 | sdret = brcmf_sdcard_recv_buf(bus->sdiodev, | 1595 | sdret = brcmf_sdcard_recv_buf(bus->sdiodev, |
1576 | bus->sdiodev->sbwad, | 1596 | bus->sdiodev->sbwad, |
@@ -1583,6 +1603,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) | |||
1583 | sdret); | 1603 | sdret); |
1584 | bus->sdcnt.rx_hdrfail++; | 1604 | bus->sdcnt.rx_hdrfail++; |
1585 | brcmf_sdbrcm_rxfail(bus, true, true); | 1605 | brcmf_sdbrcm_rxfail(bus, true, true); |
1606 | sdio_release_host(bus->sdiodev->func[1]); | ||
1586 | continue; | 1607 | continue; |
1587 | } | 1608 | } |
1588 | 1609 | ||
@@ -1590,8 +1611,9 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) | |||
1590 | bus->rxhdr, SDPCM_HDRLEN, | 1611 | bus->rxhdr, SDPCM_HDRLEN, |
1591 | "RxHdr:\n"); | 1612 | "RxHdr:\n"); |
1592 | 1613 | ||
1593 | if (!brcmf_sdio_hdparser(bus, bus->rxhdr, rd, | 1614 | if (brcmf_sdio_hdparser(bus, bus->rxhdr, rd, |
1594 | BRCMF_SDIO_FT_NORMAL)) { | 1615 | BRCMF_SDIO_FT_NORMAL)) { |
1616 | sdio_release_host(bus->sdiodev->func[1]); | ||
1595 | if (!bus->rxpending) | 1617 | if (!bus->rxpending) |
1596 | break; | 1618 | break; |
1597 | else | 1619 | else |
@@ -1607,6 +1629,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) | |||
1607 | rd->len_nxtfrm = 0; | 1629 | rd->len_nxtfrm = 0; |
1608 | /* treat all packet as event if we don't know */ | 1630 | /* treat all packet as event if we don't know */ |
1609 | rd->channel = SDPCM_EVENT_CHANNEL; | 1631 | rd->channel = SDPCM_EVENT_CHANNEL; |
1632 | sdio_release_host(bus->sdiodev->func[1]); | ||
1610 | continue; | 1633 | continue; |
1611 | } | 1634 | } |
1612 | rd->len_left = rd->len > BRCMF_FIRSTREAD ? | 1635 | rd->len_left = rd->len > BRCMF_FIRSTREAD ? |
@@ -1624,6 +1647,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) | |||
1624 | bus->sdiodev->bus_if->dstats.rx_dropped++; | 1647 | bus->sdiodev->bus_if->dstats.rx_dropped++; |
1625 | brcmf_sdbrcm_rxfail(bus, false, | 1648 | brcmf_sdbrcm_rxfail(bus, false, |
1626 | RETRYCHAN(rd->channel)); | 1649 | RETRYCHAN(rd->channel)); |
1650 | sdio_release_host(bus->sdiodev->func[1]); | ||
1627 | continue; | 1651 | continue; |
1628 | } | 1652 | } |
1629 | skb_pull(pkt, head_read); | 1653 | skb_pull(pkt, head_read); |
@@ -1632,14 +1656,17 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) | |||
1632 | sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad, | 1656 | sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad, |
1633 | SDIO_FUNC_2, F2SYNC, pkt); | 1657 | SDIO_FUNC_2, F2SYNC, pkt); |
1634 | bus->sdcnt.f2rxdata++; | 1658 | bus->sdcnt.f2rxdata++; |
1659 | sdio_release_host(bus->sdiodev->func[1]); | ||
1635 | 1660 | ||
1636 | if (sdret < 0) { | 1661 | if (sdret < 0) { |
1637 | brcmf_dbg(ERROR, "read %d bytes from channel %d failed: %d\n", | 1662 | brcmf_dbg(ERROR, "read %d bytes from channel %d failed: %d\n", |
1638 | rd->len, rd->channel, sdret); | 1663 | rd->len, rd->channel, sdret); |
1639 | brcmu_pkt_buf_free_skb(pkt); | 1664 | brcmu_pkt_buf_free_skb(pkt); |
1640 | bus->sdiodev->bus_if->dstats.rx_errors++; | 1665 | bus->sdiodev->bus_if->dstats.rx_errors++; |
1666 | sdio_claim_host(bus->sdiodev->func[1]); | ||
1641 | brcmf_sdbrcm_rxfail(bus, true, | 1667 | brcmf_sdbrcm_rxfail(bus, true, |
1642 | RETRYCHAN(rd->channel)); | 1668 | RETRYCHAN(rd->channel)); |
1669 | sdio_release_host(bus->sdiodev->func[1]); | ||
1643 | continue; | 1670 | continue; |
1644 | } | 1671 | } |
1645 | 1672 | ||
@@ -1650,8 +1677,9 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) | |||
1650 | } else { | 1677 | } else { |
1651 | memcpy(bus->rxhdr, pkt->data, SDPCM_HDRLEN); | 1678 | memcpy(bus->rxhdr, pkt->data, SDPCM_HDRLEN); |
1652 | rd_new.seq_num = rd->seq_num; | 1679 | rd_new.seq_num = rd->seq_num; |
1653 | if (!brcmf_sdio_hdparser(bus, bus->rxhdr, &rd_new, | 1680 | sdio_claim_host(bus->sdiodev->func[1]); |
1654 | BRCMF_SDIO_FT_NORMAL)) { | 1681 | if (brcmf_sdio_hdparser(bus, bus->rxhdr, &rd_new, |
1682 | BRCMF_SDIO_FT_NORMAL)) { | ||
1655 | rd->len = 0; | 1683 | rd->len = 0; |
1656 | brcmu_pkt_buf_free_skb(pkt); | 1684 | brcmu_pkt_buf_free_skb(pkt); |
1657 | } | 1685 | } |
@@ -1662,9 +1690,11 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) | |||
1662 | roundup(rd_new.len, 16) >> 4); | 1690 | roundup(rd_new.len, 16) >> 4); |
1663 | rd->len = 0; | 1691 | rd->len = 0; |
1664 | brcmf_sdbrcm_rxfail(bus, true, true); | 1692 | brcmf_sdbrcm_rxfail(bus, true, true); |
1693 | sdio_release_host(bus->sdiodev->func[1]); | ||
1665 | brcmu_pkt_buf_free_skb(pkt); | 1694 | brcmu_pkt_buf_free_skb(pkt); |
1666 | continue; | 1695 | continue; |
1667 | } | 1696 | } |
1697 | sdio_release_host(bus->sdiodev->func[1]); | ||
1668 | rd->len_nxtfrm = rd_new.len_nxtfrm; | 1698 | rd->len_nxtfrm = rd_new.len_nxtfrm; |
1669 | rd->channel = rd_new.channel; | 1699 | rd->channel = rd_new.channel; |
1670 | rd->dat_offset = rd_new.dat_offset; | 1700 | rd->dat_offset = rd_new.dat_offset; |
@@ -1680,7 +1710,9 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) | |||
1680 | rd_new.seq_num); | 1710 | rd_new.seq_num); |
1681 | /* Force retry w/normal header read */ | 1711 | /* Force retry w/normal header read */ |
1682 | rd->len = 0; | 1712 | rd->len = 0; |
1713 | sdio_claim_host(bus->sdiodev->func[1]); | ||
1683 | brcmf_sdbrcm_rxfail(bus, false, true); | 1714 | brcmf_sdbrcm_rxfail(bus, false, true); |
1715 | sdio_release_host(bus->sdiodev->func[1]); | ||
1684 | brcmu_pkt_buf_free_skb(pkt); | 1716 | brcmu_pkt_buf_free_skb(pkt); |
1685 | continue; | 1717 | continue; |
1686 | } | 1718 | } |
@@ -1703,7 +1735,9 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) | |||
1703 | } else { | 1735 | } else { |
1704 | brcmf_dbg(ERROR, "%s: glom superframe w/o " | 1736 | brcmf_dbg(ERROR, "%s: glom superframe w/o " |
1705 | "descriptor!\n", __func__); | 1737 | "descriptor!\n", __func__); |
1738 | sdio_claim_host(bus->sdiodev->func[1]); | ||
1706 | brcmf_sdbrcm_rxfail(bus, false, false); | 1739 | brcmf_sdbrcm_rxfail(bus, false, false); |
1740 | sdio_release_host(bus->sdiodev->func[1]); | ||
1707 | } | 1741 | } |
1708 | /* prepare the descriptor for the next read */ | 1742 | /* prepare the descriptor for the next read */ |
1709 | rd->len = rd->len_nxtfrm << 4; | 1743 | rd->len = rd->len_nxtfrm << 4; |
@@ -1734,10 +1768,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) | |||
1734 | continue; | 1768 | continue; |
1735 | } | 1769 | } |
1736 | 1770 | ||
1737 | /* Unlock during rx call */ | ||
1738 | up(&bus->sdsem); | ||
1739 | brcmf_rx_packet(bus->sdiodev->dev, ifidx, pkt); | 1771 | brcmf_rx_packet(bus->sdiodev->dev, ifidx, pkt); |
1740 | down(&bus->sdsem); | ||
1741 | } | 1772 | } |
1742 | 1773 | ||
1743 | rxcount = maxframes - rxleft; | 1774 | rxcount = maxframes - rxleft; |
@@ -1755,15 +1786,6 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) | |||
1755 | } | 1786 | } |
1756 | 1787 | ||
1757 | static void | 1788 | static void |
1758 | brcmf_sdbrcm_wait_for_event(struct brcmf_sdio *bus, bool *lockvar) | ||
1759 | { | ||
1760 | up(&bus->sdsem); | ||
1761 | wait_event_interruptible_timeout(bus->ctrl_wait, !*lockvar, HZ * 2); | ||
1762 | down(&bus->sdsem); | ||
1763 | return; | ||
1764 | } | ||
1765 | |||
1766 | static void | ||
1767 | brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus) | 1789 | brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus) |
1768 | { | 1790 | { |
1769 | if (waitqueue_active(&bus->ctrl_wait)) | 1791 | if (waitqueue_active(&bus->ctrl_wait)) |
@@ -1864,6 +1886,7 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, | |||
1864 | if (len & (ALIGNMENT - 1)) | 1886 | if (len & (ALIGNMENT - 1)) |
1865 | len = roundup(len, ALIGNMENT); | 1887 | len = roundup(len, ALIGNMENT); |
1866 | 1888 | ||
1889 | sdio_claim_host(bus->sdiodev->func[1]); | ||
1867 | ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad, | 1890 | ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad, |
1868 | SDIO_FUNC_2, F2SYNC, pkt); | 1891 | SDIO_FUNC_2, F2SYNC, pkt); |
1869 | bus->sdcnt.f2txdata++; | 1892 | bus->sdcnt.f2txdata++; |
@@ -1891,15 +1914,14 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, | |||
1891 | } | 1914 | } |
1892 | 1915 | ||
1893 | } | 1916 | } |
1917 | sdio_release_host(bus->sdiodev->func[1]); | ||
1894 | if (ret == 0) | 1918 | if (ret == 0) |
1895 | bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; | 1919 | bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; |
1896 | 1920 | ||
1897 | done: | 1921 | done: |
1898 | /* restore pkt buffer pointer before calling tx complete routine */ | 1922 | /* restore pkt buffer pointer before calling tx complete routine */ |
1899 | skb_pull(pkt, SDPCM_HDRLEN + pad); | 1923 | skb_pull(pkt, SDPCM_HDRLEN + pad); |
1900 | up(&bus->sdsem); | ||
1901 | brcmf_txcomplete(bus->sdiodev->dev, pkt, ret != 0); | 1924 | brcmf_txcomplete(bus->sdiodev->dev, pkt, ret != 0); |
1902 | down(&bus->sdsem); | ||
1903 | 1925 | ||
1904 | if (free_pkt) | 1926 | if (free_pkt) |
1905 | brcmu_pkt_buf_free_skb(pkt); | 1927 | brcmu_pkt_buf_free_skb(pkt); |
@@ -1940,9 +1962,11 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes) | |||
1940 | /* In poll mode, need to check for other events */ | 1962 | /* In poll mode, need to check for other events */ |
1941 | if (!bus->intr && cnt) { | 1963 | if (!bus->intr && cnt) { |
1942 | /* Check device status, signal pending interrupt */ | 1964 | /* Check device status, signal pending interrupt */ |
1965 | sdio_claim_host(bus->sdiodev->func[1]); | ||
1943 | ret = r_sdreg32(bus, &intstatus, | 1966 | ret = r_sdreg32(bus, &intstatus, |
1944 | offsetof(struct sdpcmd_regs, | 1967 | offsetof(struct sdpcmd_regs, |
1945 | intstatus)); | 1968 | intstatus)); |
1969 | sdio_release_host(bus->sdiodev->func[1]); | ||
1946 | bus->sdcnt.f2txdata++; | 1970 | bus->sdcnt.f2txdata++; |
1947 | if (ret != 0) | 1971 | if (ret != 0) |
1948 | break; | 1972 | break; |
@@ -1979,7 +2003,7 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev) | |||
1979 | bus->watchdog_tsk = NULL; | 2003 | bus->watchdog_tsk = NULL; |
1980 | } | 2004 | } |
1981 | 2005 | ||
1982 | down(&bus->sdsem); | 2006 | sdio_claim_host(bus->sdiodev->func[1]); |
1983 | 2007 | ||
1984 | /* Enable clock for device interrupts */ | 2008 | /* Enable clock for device interrupts */ |
1985 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); | 2009 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); |
@@ -2013,6 +2037,7 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev) | |||
2013 | 2037 | ||
2014 | /* Turn off the backplane clock (only) */ | 2038 | /* Turn off the backplane clock (only) */ |
2015 | brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); | 2039 | brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); |
2040 | sdio_release_host(bus->sdiodev->func[1]); | ||
2016 | 2041 | ||
2017 | /* Clear the data packet queues */ | 2042 | /* Clear the data packet queues */ |
2018 | brcmu_pktq_flush(&bus->txq, true, NULL, NULL); | 2043 | brcmu_pktq_flush(&bus->txq, true, NULL, NULL); |
@@ -2023,14 +2048,14 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev) | |||
2023 | brcmf_sdbrcm_free_glom(bus); | 2048 | brcmf_sdbrcm_free_glom(bus); |
2024 | 2049 | ||
2025 | /* Clear rx control and wake any waiters */ | 2050 | /* Clear rx control and wake any waiters */ |
2051 | spin_lock_bh(&bus->rxctl_lock); | ||
2026 | bus->rxlen = 0; | 2052 | bus->rxlen = 0; |
2053 | spin_unlock_bh(&bus->rxctl_lock); | ||
2027 | brcmf_sdbrcm_dcmd_resp_wake(bus); | 2054 | brcmf_sdbrcm_dcmd_resp_wake(bus); |
2028 | 2055 | ||
2029 | /* Reset some F2 state stuff */ | 2056 | /* Reset some F2 state stuff */ |
2030 | bus->rxskip = false; | 2057 | bus->rxskip = false; |
2031 | bus->tx_seq = bus->rx_seq = 0; | 2058 | bus->tx_seq = bus->rx_seq = 0; |
2032 | |||
2033 | up(&bus->sdsem); | ||
2034 | } | 2059 | } |
2035 | 2060 | ||
2036 | #ifdef CONFIG_BRCMFMAC_SDIO_OOB | 2061 | #ifdef CONFIG_BRCMFMAC_SDIO_OOB |
@@ -2114,7 +2139,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) | |||
2114 | 2139 | ||
2115 | brcmf_dbg(TRACE, "Enter\n"); | 2140 | brcmf_dbg(TRACE, "Enter\n"); |
2116 | 2141 | ||
2117 | down(&bus->sdsem); | 2142 | sdio_claim_host(bus->sdiodev->func[1]); |
2118 | 2143 | ||
2119 | /* If waiting for HTAVAIL, check status */ | 2144 | /* If waiting for HTAVAIL, check status */ |
2120 | if (bus->clkstate == CLK_PENDING) { | 2145 | if (bus->clkstate == CLK_PENDING) { |
@@ -2168,9 +2193,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) | |||
2168 | /* Pending interrupt indicates new device status */ | 2193 | /* Pending interrupt indicates new device status */ |
2169 | if (atomic_read(&bus->ipend) > 0) { | 2194 | if (atomic_read(&bus->ipend) > 0) { |
2170 | atomic_set(&bus->ipend, 0); | 2195 | atomic_set(&bus->ipend, 0); |
2171 | sdio_claim_host(bus->sdiodev->func[1]); | ||
2172 | err = brcmf_sdio_intr_rstatus(bus); | 2196 | err = brcmf_sdio_intr_rstatus(bus); |
2173 | sdio_release_host(bus->sdiodev->func[1]); | ||
2174 | } | 2197 | } |
2175 | 2198 | ||
2176 | /* Start with leftover status bits */ | 2199 | /* Start with leftover status bits */ |
@@ -2199,6 +2222,8 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) | |||
2199 | intstatus |= brcmf_sdbrcm_hostmail(bus); | 2222 | intstatus |= brcmf_sdbrcm_hostmail(bus); |
2200 | } | 2223 | } |
2201 | 2224 | ||
2225 | sdio_release_host(bus->sdiodev->func[1]); | ||
2226 | |||
2202 | /* Generally don't ask for these, can get CRC errors... */ | 2227 | /* Generally don't ask for these, can get CRC errors... */ |
2203 | if (intstatus & I_WR_OOSYNC) { | 2228 | if (intstatus & I_WR_OOSYNC) { |
2204 | brcmf_dbg(ERROR, "Dongle reports WR_OOSYNC\n"); | 2229 | brcmf_dbg(ERROR, "Dongle reports WR_OOSYNC\n"); |
@@ -2245,6 +2270,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) | |||
2245 | (bus->clkstate == CLK_AVAIL)) { | 2270 | (bus->clkstate == CLK_AVAIL)) { |
2246 | int i; | 2271 | int i; |
2247 | 2272 | ||
2273 | sdio_claim_host(bus->sdiodev->func[1]); | ||
2248 | err = brcmf_sdcard_send_buf(bus->sdiodev, bus->sdiodev->sbwad, | 2274 | err = brcmf_sdcard_send_buf(bus->sdiodev, bus->sdiodev->sbwad, |
2249 | SDIO_FUNC_2, F2SYNC, bus->ctrl_frame_buf, | 2275 | SDIO_FUNC_2, F2SYNC, bus->ctrl_frame_buf, |
2250 | (u32) bus->ctrl_frame_len); | 2276 | (u32) bus->ctrl_frame_len); |
@@ -2278,6 +2304,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) | |||
2278 | } else { | 2304 | } else { |
2279 | bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; | 2305 | bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; |
2280 | } | 2306 | } |
2307 | sdio_release_host(bus->sdiodev->func[1]); | ||
2281 | bus->ctrl_frame_stat = false; | 2308 | bus->ctrl_frame_stat = false; |
2282 | brcmf_sdbrcm_wait_event_wakeup(bus); | 2309 | brcmf_sdbrcm_wait_event_wakeup(bus); |
2283 | } | 2310 | } |
@@ -2307,10 +2334,10 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) | |||
2307 | if ((bus->clkstate != CLK_PENDING) | 2334 | if ((bus->clkstate != CLK_PENDING) |
2308 | && bus->idletime == BRCMF_IDLE_IMMEDIATE) { | 2335 | && bus->idletime == BRCMF_IDLE_IMMEDIATE) { |
2309 | bus->activity = false; | 2336 | bus->activity = false; |
2337 | sdio_claim_host(bus->sdiodev->func[1]); | ||
2310 | brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); | 2338 | brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); |
2339 | sdio_release_host(bus->sdiodev->func[1]); | ||
2311 | } | 2340 | } |
2312 | |||
2313 | up(&bus->sdsem); | ||
2314 | } | 2341 | } |
2315 | 2342 | ||
2316 | static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) | 2343 | static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) |
@@ -2601,11 +2628,10 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) | |||
2601 | 2628 | ||
2602 | /* precondition: IS_ALIGNED((unsigned long)frame, 2) */ | 2629 | /* precondition: IS_ALIGNED((unsigned long)frame, 2) */ |
2603 | 2630 | ||
2604 | /* Need to lock here to protect txseq and SDIO tx calls */ | ||
2605 | down(&bus->sdsem); | ||
2606 | |||
2607 | /* Make sure backplane clock is on */ | 2631 | /* Make sure backplane clock is on */ |
2632 | sdio_claim_host(bus->sdiodev->func[1]); | ||
2608 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); | 2633 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); |
2634 | sdio_release_host(bus->sdiodev->func[1]); | ||
2609 | 2635 | ||
2610 | /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */ | 2636 | /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */ |
2611 | *(__le16 *) frame = cpu_to_le16((u16) msglen); | 2637 | *(__le16 *) frame = cpu_to_le16((u16) msglen); |
@@ -2628,7 +2654,9 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) | |||
2628 | bus->ctrl_frame_buf = frame; | 2654 | bus->ctrl_frame_buf = frame; |
2629 | bus->ctrl_frame_len = len; | 2655 | bus->ctrl_frame_len = len; |
2630 | 2656 | ||
2631 | brcmf_sdbrcm_wait_for_event(bus, &bus->ctrl_frame_stat); | 2657 | wait_event_interruptible_timeout(bus->ctrl_wait, |
2658 | !bus->ctrl_frame_stat, | ||
2659 | msecs_to_jiffies(2000)); | ||
2632 | 2660 | ||
2633 | if (!bus->ctrl_frame_stat) { | 2661 | if (!bus->ctrl_frame_stat) { |
2634 | brcmf_dbg(INFO, "ctrl_frame_stat == false\n"); | 2662 | brcmf_dbg(INFO, "ctrl_frame_stat == false\n"); |
@@ -2647,7 +2675,9 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) | |||
2647 | frame, min_t(u16, len, 16), "TxHdr:\n"); | 2675 | frame, min_t(u16, len, 16), "TxHdr:\n"); |
2648 | 2676 | ||
2649 | do { | 2677 | do { |
2678 | sdio_claim_host(bus->sdiodev->func[1]); | ||
2650 | ret = brcmf_tx_frame(bus, frame, len); | 2679 | ret = brcmf_tx_frame(bus, frame, len); |
2680 | sdio_release_host(bus->sdiodev->func[1]); | ||
2651 | } while (ret < 0 && retries++ < TXRETRIES); | 2681 | } while (ret < 0 && retries++ < TXRETRIES); |
2652 | } | 2682 | } |
2653 | 2683 | ||
@@ -2657,13 +2687,13 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) | |||
2657 | spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); | 2687 | spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); |
2658 | 2688 | ||
2659 | bus->activity = false; | 2689 | bus->activity = false; |
2690 | sdio_claim_host(bus->sdiodev->func[1]); | ||
2660 | brcmf_sdbrcm_clkctl(bus, CLK_NONE, true); | 2691 | brcmf_sdbrcm_clkctl(bus, CLK_NONE, true); |
2692 | sdio_release_host(bus->sdiodev->func[1]); | ||
2661 | } else { | 2693 | } else { |
2662 | spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); | 2694 | spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); |
2663 | } | 2695 | } |
2664 | 2696 | ||
2665 | up(&bus->sdsem); | ||
2666 | |||
2667 | if (ret) | 2697 | if (ret) |
2668 | bus->sdcnt.tx_ctlerrs++; | 2698 | bus->sdcnt.tx_ctlerrs++; |
2669 | else | 2699 | else |
@@ -2693,8 +2723,10 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus, | |||
2693 | * Read last word in socram to determine | 2723 | * Read last word in socram to determine |
2694 | * address of sdpcm_shared structure | 2724 | * address of sdpcm_shared structure |
2695 | */ | 2725 | */ |
2726 | sdio_claim_host(bus->sdiodev->func[1]); | ||
2696 | rv = brcmf_sdbrcm_membytes(bus, false, shaddr, | 2727 | rv = brcmf_sdbrcm_membytes(bus, false, shaddr, |
2697 | (u8 *)&addr_le, 4); | 2728 | (u8 *)&addr_le, 4); |
2729 | sdio_claim_host(bus->sdiodev->func[1]); | ||
2698 | if (rv < 0) | 2730 | if (rv < 0) |
2699 | return rv; | 2731 | return rv; |
2700 | 2732 | ||
@@ -2713,8 +2745,10 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus, | |||
2713 | } | 2745 | } |
2714 | 2746 | ||
2715 | /* Read hndrte_shared structure */ | 2747 | /* Read hndrte_shared structure */ |
2748 | sdio_claim_host(bus->sdiodev->func[1]); | ||
2716 | rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&sh_le, | 2749 | rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&sh_le, |
2717 | sizeof(struct sdpcm_shared_le)); | 2750 | sizeof(struct sdpcm_shared_le)); |
2751 | sdio_release_host(bus->sdiodev->func[1]); | ||
2718 | if (rv < 0) | 2752 | if (rv < 0) |
2719 | return rv; | 2753 | return rv; |
2720 | 2754 | ||
@@ -2817,12 +2851,14 @@ static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh, | |||
2817 | if ((sh->flags & SDPCM_SHARED_TRAP) == 0) | 2851 | if ((sh->flags & SDPCM_SHARED_TRAP) == 0) |
2818 | return 0; | 2852 | return 0; |
2819 | 2853 | ||
2854 | sdio_claim_host(bus->sdiodev->func[1]); | ||
2820 | error = brcmf_sdbrcm_membytes(bus, false, sh->trap_addr, (u8 *)&tr, | 2855 | error = brcmf_sdbrcm_membytes(bus, false, sh->trap_addr, (u8 *)&tr, |
2821 | sizeof(struct brcmf_trap_info)); | 2856 | sizeof(struct brcmf_trap_info)); |
2822 | if (error < 0) | 2857 | if (error < 0) |
2823 | return error; | 2858 | return error; |
2824 | 2859 | ||
2825 | nbytes = brcmf_sdio_dump_console(bus, sh, data, count); | 2860 | nbytes = brcmf_sdio_dump_console(bus, sh, data, count); |
2861 | sdio_release_host(bus->sdiodev->func[1]); | ||
2826 | if (nbytes < 0) | 2862 | if (nbytes < 0) |
2827 | return nbytes; | 2863 | return nbytes; |
2828 | 2864 | ||
@@ -2868,6 +2904,7 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus, | |||
2868 | return 0; | 2904 | return 0; |
2869 | } | 2905 | } |
2870 | 2906 | ||
2907 | sdio_claim_host(bus->sdiodev->func[1]); | ||
2871 | if (sh->assert_file_addr != 0) { | 2908 | if (sh->assert_file_addr != 0) { |
2872 | error = brcmf_sdbrcm_membytes(bus, false, sh->assert_file_addr, | 2909 | error = brcmf_sdbrcm_membytes(bus, false, sh->assert_file_addr, |
2873 | (u8 *)file, 80); | 2910 | (u8 *)file, 80); |
@@ -2880,6 +2917,7 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus, | |||
2880 | if (error < 0) | 2917 | if (error < 0) |
2881 | return error; | 2918 | return error; |
2882 | } | 2919 | } |
2920 | sdio_release_host(bus->sdiodev->func[1]); | ||
2883 | 2921 | ||
2884 | res = scnprintf(buf, sizeof(buf), | 2922 | res = scnprintf(buf, sizeof(buf), |
2885 | "dongle assert: %s:%d: assert(%s)\n", | 2923 | "dongle assert: %s:%d: assert(%s)\n", |
@@ -2892,9 +2930,7 @@ static int brcmf_sdbrcm_checkdied(struct brcmf_sdio *bus) | |||
2892 | int error; | 2930 | int error; |
2893 | struct sdpcm_shared sh; | 2931 | struct sdpcm_shared sh; |
2894 | 2932 | ||
2895 | down(&bus->sdsem); | ||
2896 | error = brcmf_sdio_readshared(bus, &sh); | 2933 | error = brcmf_sdio_readshared(bus, &sh); |
2897 | up(&bus->sdsem); | ||
2898 | 2934 | ||
2899 | if (error < 0) | 2935 | if (error < 0) |
2900 | return error; | 2936 | return error; |
@@ -2921,7 +2957,6 @@ static int brcmf_sdbrcm_died_dump(struct brcmf_sdio *bus, char __user *data, | |||
2921 | if (pos != 0) | 2957 | if (pos != 0) |
2922 | return 0; | 2958 | return 0; |
2923 | 2959 | ||
2924 | down(&bus->sdsem); | ||
2925 | error = brcmf_sdio_readshared(bus, &sh); | 2960 | error = brcmf_sdio_readshared(bus, &sh); |
2926 | if (error < 0) | 2961 | if (error < 0) |
2927 | goto done; | 2962 | goto done; |
@@ -2938,7 +2973,6 @@ static int brcmf_sdbrcm_died_dump(struct brcmf_sdio *bus, char __user *data, | |||
2938 | error += nbytes; | 2973 | error += nbytes; |
2939 | *ppos += error; | 2974 | *ppos += error; |
2940 | done: | 2975 | done: |
2941 | up(&bus->sdsem); | ||
2942 | return error; | 2976 | return error; |
2943 | } | 2977 | } |
2944 | 2978 | ||
@@ -2989,6 +3023,7 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) | |||
2989 | int timeleft; | 3023 | int timeleft; |
2990 | uint rxlen = 0; | 3024 | uint rxlen = 0; |
2991 | bool pending; | 3025 | bool pending; |
3026 | u8 *buf; | ||
2992 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | 3027 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); |
2993 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; | 3028 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; |
2994 | struct brcmf_sdio *bus = sdiodev->bus; | 3029 | struct brcmf_sdio *bus = sdiodev->bus; |
@@ -2998,11 +3033,15 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) | |||
2998 | /* Wait until control frame is available */ | 3033 | /* Wait until control frame is available */ |
2999 | timeleft = brcmf_sdbrcm_dcmd_resp_wait(bus, &bus->rxlen, &pending); | 3034 | timeleft = brcmf_sdbrcm_dcmd_resp_wait(bus, &bus->rxlen, &pending); |
3000 | 3035 | ||
3001 | down(&bus->sdsem); | 3036 | spin_lock_bh(&bus->rxctl_lock); |
3002 | rxlen = bus->rxlen; | 3037 | rxlen = bus->rxlen; |
3003 | memcpy(msg, bus->rxctl, min(msglen, rxlen)); | 3038 | memcpy(msg, bus->rxctl, min(msglen, rxlen)); |
3039 | bus->rxctl = NULL; | ||
3040 | buf = bus->rxctl_orig; | ||
3041 | bus->rxctl_orig = NULL; | ||
3004 | bus->rxlen = 0; | 3042 | bus->rxlen = 0; |
3005 | up(&bus->sdsem); | 3043 | spin_unlock_bh(&bus->rxctl_lock); |
3044 | vfree(buf); | ||
3006 | 3045 | ||
3007 | if (rxlen) { | 3046 | if (rxlen) { |
3008 | brcmf_dbg(CTL, "resumed on rxctl frame, got %d expected %d\n", | 3047 | brcmf_dbg(CTL, "resumed on rxctl frame, got %d expected %d\n", |
@@ -3338,13 +3377,16 @@ brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus) | |||
3338 | { | 3377 | { |
3339 | bool ret; | 3378 | bool ret; |
3340 | 3379 | ||
3341 | /* Download the firmware */ | 3380 | sdio_claim_host(bus->sdiodev->func[1]); |
3381 | |||
3342 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); | 3382 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); |
3343 | 3383 | ||
3344 | ret = _brcmf_sdbrcm_download_firmware(bus) == 0; | 3384 | ret = _brcmf_sdbrcm_download_firmware(bus) == 0; |
3345 | 3385 | ||
3346 | brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); | 3386 | brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); |
3347 | 3387 | ||
3388 | sdio_release_host(bus->sdiodev->func[1]); | ||
3389 | |||
3348 | return ret; | 3390 | return ret; |
3349 | } | 3391 | } |
3350 | 3392 | ||
@@ -3373,7 +3415,7 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) | |||
3373 | bus->sdcnt.tickcnt = 0; | 3415 | bus->sdcnt.tickcnt = 0; |
3374 | brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); | 3416 | brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); |
3375 | 3417 | ||
3376 | down(&bus->sdsem); | 3418 | sdio_claim_host(bus->sdiodev->func[1]); |
3377 | 3419 | ||
3378 | /* Make sure backplane clock is on, needed to generate F2 interrupt */ | 3420 | /* Make sure backplane clock is on, needed to generate F2 interrupt */ |
3379 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); | 3421 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); |
@@ -3442,7 +3484,7 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) | |||
3442 | brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); | 3484 | brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); |
3443 | 3485 | ||
3444 | exit: | 3486 | exit: |
3445 | up(&bus->sdsem); | 3487 | sdio_release_host(bus->sdiodev->func[1]); |
3446 | 3488 | ||
3447 | return ret; | 3489 | return ret; |
3448 | } | 3490 | } |
@@ -3489,8 +3531,6 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) | |||
3489 | 3531 | ||
3490 | brcmf_dbg(TIMER, "Enter\n"); | 3532 | brcmf_dbg(TIMER, "Enter\n"); |
3491 | 3533 | ||
3492 | down(&bus->sdsem); | ||
3493 | |||
3494 | /* Poll period: check device if appropriate. */ | 3534 | /* Poll period: check device if appropriate. */ |
3495 | if (bus->poll && (++bus->polltick >= bus->pollrate)) { | 3535 | if (bus->poll && (++bus->polltick >= bus->pollrate)) { |
3496 | u32 intstatus = 0; | 3536 | u32 intstatus = 0; |
@@ -3507,9 +3547,11 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) | |||
3507 | u8 devpend; | 3547 | u8 devpend; |
3508 | spin_unlock_irqrestore(&bus->dpc_tl_lock, | 3548 | spin_unlock_irqrestore(&bus->dpc_tl_lock, |
3509 | flags); | 3549 | flags); |
3550 | sdio_claim_host(bus->sdiodev->func[1]); | ||
3510 | devpend = brcmf_sdio_regrb(bus->sdiodev, | 3551 | devpend = brcmf_sdio_regrb(bus->sdiodev, |
3511 | SDIO_CCCR_INTx, | 3552 | SDIO_CCCR_INTx, |
3512 | NULL); | 3553 | NULL); |
3554 | sdio_release_host(bus->sdiodev->func[1]); | ||
3513 | intstatus = | 3555 | intstatus = |
3514 | devpend & (INTR_STATUS_FUNC1 | | 3556 | devpend & (INTR_STATUS_FUNC1 | |
3515 | INTR_STATUS_FUNC2); | 3557 | INTR_STATUS_FUNC2); |
@@ -3534,16 +3576,18 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) | |||
3534 | } | 3576 | } |
3535 | #ifdef DEBUG | 3577 | #ifdef DEBUG |
3536 | /* Poll for console output periodically */ | 3578 | /* Poll for console output periodically */ |
3537 | if (bus_if->state == BRCMF_BUS_DATA && | 3579 | if (bus_if && bus_if->state == BRCMF_BUS_DATA && |
3538 | bus->console_interval != 0) { | 3580 | bus->console_interval != 0) { |
3539 | bus->console.count += BRCMF_WD_POLL_MS; | 3581 | bus->console.count += BRCMF_WD_POLL_MS; |
3540 | if (bus->console.count >= bus->console_interval) { | 3582 | if (bus->console.count >= bus->console_interval) { |
3541 | bus->console.count -= bus->console_interval; | 3583 | bus->console.count -= bus->console_interval; |
3584 | sdio_claim_host(bus->sdiodev->func[1]); | ||
3542 | /* Make sure backplane clock is on */ | 3585 | /* Make sure backplane clock is on */ |
3543 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); | 3586 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); |
3544 | if (brcmf_sdbrcm_readconsole(bus) < 0) | 3587 | if (brcmf_sdbrcm_readconsole(bus) < 0) |
3545 | /* stop on error */ | 3588 | /* stop on error */ |
3546 | bus->console_interval = 0; | 3589 | bus->console_interval = 0; |
3590 | sdio_release_host(bus->sdiodev->func[1]); | ||
3547 | } | 3591 | } |
3548 | } | 3592 | } |
3549 | #endif /* DEBUG */ | 3593 | #endif /* DEBUG */ |
@@ -3556,13 +3600,13 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) | |||
3556 | bus->activity = false; | 3600 | bus->activity = false; |
3557 | brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); | 3601 | brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); |
3558 | } else { | 3602 | } else { |
3603 | sdio_claim_host(bus->sdiodev->func[1]); | ||
3559 | brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); | 3604 | brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); |
3605 | sdio_release_host(bus->sdiodev->func[1]); | ||
3560 | } | 3606 | } |
3561 | } | 3607 | } |
3562 | } | 3608 | } |
3563 | 3609 | ||
3564 | up(&bus->sdsem); | ||
3565 | |||
3566 | return (atomic_read(&bus->ipend) > 0); | 3610 | return (atomic_read(&bus->ipend) > 0); |
3567 | } | 3611 | } |
3568 | 3612 | ||
@@ -3657,6 +3701,8 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva) | |||
3657 | 3701 | ||
3658 | bus->alp_only = true; | 3702 | bus->alp_only = true; |
3659 | 3703 | ||
3704 | sdio_claim_host(bus->sdiodev->func[1]); | ||
3705 | |||
3660 | pr_debug("F1 signature read @0x18000000=0x%4x\n", | 3706 | pr_debug("F1 signature read @0x18000000=0x%4x\n", |
3661 | brcmf_sdio_regrl(bus->sdiodev, SI_ENUM_BASE, NULL)); | 3707 | brcmf_sdio_regrl(bus->sdiodev, SI_ENUM_BASE, NULL)); |
3662 | 3708 | ||
@@ -3704,6 +3750,8 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva) | |||
3704 | reg_val = brcmf_sdio_regrl(bus->sdiodev, reg_addr, NULL); | 3750 | reg_val = brcmf_sdio_regrl(bus->sdiodev, reg_addr, NULL); |
3705 | brcmf_sdio_regwl(bus->sdiodev, reg_addr, reg_val | CC_BPRESEN, NULL); | 3751 | brcmf_sdio_regwl(bus->sdiodev, reg_addr, reg_val | CC_BPRESEN, NULL); |
3706 | 3752 | ||
3753 | sdio_release_host(bus->sdiodev->func[1]); | ||
3754 | |||
3707 | brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN); | 3755 | brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN); |
3708 | 3756 | ||
3709 | /* Locate an appropriately-aligned portion of hdrbuf */ | 3757 | /* Locate an appropriately-aligned portion of hdrbuf */ |
@@ -3719,6 +3767,7 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva) | |||
3719 | return true; | 3767 | return true; |
3720 | 3768 | ||
3721 | fail: | 3769 | fail: |
3770 | sdio_release_host(bus->sdiodev->func[1]); | ||
3722 | return false; | 3771 | return false; |
3723 | } | 3772 | } |
3724 | 3773 | ||
@@ -3726,6 +3775,8 @@ static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus) | |||
3726 | { | 3775 | { |
3727 | brcmf_dbg(TRACE, "Enter\n"); | 3776 | brcmf_dbg(TRACE, "Enter\n"); |
3728 | 3777 | ||
3778 | sdio_claim_host(bus->sdiodev->func[1]); | ||
3779 | |||
3729 | /* Disable F2 to clear any intermediate frame state on the dongle */ | 3780 | /* Disable F2 to clear any intermediate frame state on the dongle */ |
3730 | brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, | 3781 | brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, |
3731 | SDIO_FUNC_ENABLE_1, NULL); | 3782 | SDIO_FUNC_ENABLE_1, NULL); |
@@ -3736,6 +3787,8 @@ static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus) | |||
3736 | /* Done with backplane-dependent accesses, can drop clock... */ | 3787 | /* Done with backplane-dependent accesses, can drop clock... */ |
3737 | brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); | 3788 | brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); |
3738 | 3789 | ||
3790 | sdio_release_host(bus->sdiodev->func[1]); | ||
3791 | |||
3739 | /* ...and initialize clock/power states */ | 3792 | /* ...and initialize clock/power states */ |
3740 | bus->clkstate = CLK_SDONLY; | 3793 | bus->clkstate = CLK_SDONLY; |
3741 | bus->idletime = BRCMF_IDLE_INTERVAL; | 3794 | bus->idletime = BRCMF_IDLE_INTERVAL; |
@@ -3791,8 +3844,10 @@ static void brcmf_sdbrcm_release_dongle(struct brcmf_sdio *bus) | |||
3791 | brcmf_dbg(TRACE, "Enter\n"); | 3844 | brcmf_dbg(TRACE, "Enter\n"); |
3792 | 3845 | ||
3793 | if (bus->ci) { | 3846 | if (bus->ci) { |
3847 | sdio_claim_host(bus->sdiodev->func[1]); | ||
3794 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); | 3848 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); |
3795 | brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); | 3849 | brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); |
3850 | sdio_release_host(bus->sdiodev->func[1]); | ||
3796 | brcmf_sdio_chip_detach(&bus->ci); | 3851 | brcmf_sdio_chip_detach(&bus->ci); |
3797 | if (bus->vars && bus->varsz) | 3852 | if (bus->vars && bus->varsz) |
3798 | kfree(bus->vars); | 3853 | kfree(bus->vars); |
@@ -3812,7 +3867,8 @@ static void brcmf_sdbrcm_release(struct brcmf_sdio *bus) | |||
3812 | brcmf_sdio_intr_unregister(bus->sdiodev); | 3867 | brcmf_sdio_intr_unregister(bus->sdiodev); |
3813 | 3868 | ||
3814 | cancel_work_sync(&bus->datawork); | 3869 | cancel_work_sync(&bus->datawork); |
3815 | destroy_workqueue(bus->brcmf_wq); | 3870 | if (bus->brcmf_wq) |
3871 | destroy_workqueue(bus->brcmf_wq); | ||
3816 | 3872 | ||
3817 | if (bus->sdiodev->bus_if->drvr) { | 3873 | if (bus->sdiodev->bus_if->drvr) { |
3818 | brcmf_detach(bus->sdiodev->dev); | 3874 | brcmf_detach(bus->sdiodev->dev); |
@@ -3854,31 +3910,29 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) | |||
3854 | bus->txminmax = BRCMF_TXMINMAX; | 3910 | bus->txminmax = BRCMF_TXMINMAX; |
3855 | bus->tx_seq = SDPCM_SEQUENCE_WRAP - 1; | 3911 | bus->tx_seq = SDPCM_SEQUENCE_WRAP - 1; |
3856 | 3912 | ||
3913 | INIT_WORK(&bus->datawork, brcmf_sdio_dataworker); | ||
3914 | bus->brcmf_wq = create_singlethread_workqueue("brcmf_wq"); | ||
3915 | if (bus->brcmf_wq == NULL) { | ||
3916 | brcmf_dbg(ERROR, "insufficient memory to create txworkqueue\n"); | ||
3917 | goto fail; | ||
3918 | } | ||
3919 | |||
3857 | /* attempt to attach to the dongle */ | 3920 | /* attempt to attach to the dongle */ |
3858 | if (!(brcmf_sdbrcm_probe_attach(bus, regsva))) { | 3921 | if (!(brcmf_sdbrcm_probe_attach(bus, regsva))) { |
3859 | brcmf_dbg(ERROR, "brcmf_sdbrcm_probe_attach failed\n"); | 3922 | brcmf_dbg(ERROR, "brcmf_sdbrcm_probe_attach failed\n"); |
3860 | goto fail; | 3923 | goto fail; |
3861 | } | 3924 | } |
3862 | 3925 | ||
3926 | spin_lock_init(&bus->rxctl_lock); | ||
3863 | spin_lock_init(&bus->txqlock); | 3927 | spin_lock_init(&bus->txqlock); |
3864 | init_waitqueue_head(&bus->ctrl_wait); | 3928 | init_waitqueue_head(&bus->ctrl_wait); |
3865 | init_waitqueue_head(&bus->dcmd_resp_wait); | 3929 | init_waitqueue_head(&bus->dcmd_resp_wait); |
3866 | 3930 | ||
3867 | bus->brcmf_wq = create_singlethread_workqueue("brcmf_wq"); | ||
3868 | if (bus->brcmf_wq == NULL) { | ||
3869 | brcmf_dbg(ERROR, "insufficient memory to create txworkqueue\n"); | ||
3870 | goto fail; | ||
3871 | } | ||
3872 | INIT_WORK(&bus->datawork, brcmf_sdio_dataworker); | ||
3873 | |||
3874 | /* Set up the watchdog timer */ | 3931 | /* Set up the watchdog timer */ |
3875 | init_timer(&bus->timer); | 3932 | init_timer(&bus->timer); |
3876 | bus->timer.data = (unsigned long)bus; | 3933 | bus->timer.data = (unsigned long)bus; |
3877 | bus->timer.function = brcmf_sdbrcm_watchdog; | 3934 | bus->timer.function = brcmf_sdbrcm_watchdog; |
3878 | 3935 | ||
3879 | /* Initialize thread based operation and lock */ | ||
3880 | sema_init(&bus->sdsem, 1); | ||
3881 | |||
3882 | /* Initialize watchdog thread */ | 3936 | /* Initialize watchdog thread */ |
3883 | init_completion(&bus->watchdog_wait); | 3937 | init_completion(&bus->watchdog_wait); |
3884 | bus->watchdog_tsk = kthread_run(brcmf_sdbrcm_watchdog_thread, | 3938 | bus->watchdog_tsk = kthread_run(brcmf_sdbrcm_watchdog_thread, |
@@ -3941,10 +3995,8 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) | |||
3941 | /* if firmware path present try to download and bring up bus */ | 3995 | /* if firmware path present try to download and bring up bus */ |
3942 | ret = brcmf_bus_start(bus->sdiodev->dev); | 3996 | ret = brcmf_bus_start(bus->sdiodev->dev); |
3943 | if (ret != 0) { | 3997 | if (ret != 0) { |
3944 | if (ret == -ENOLINK) { | 3998 | brcmf_dbg(ERROR, "dongle is not responding\n"); |
3945 | brcmf_dbg(ERROR, "dongle is not responding\n"); | 3999 | goto fail; |
3946 | goto fail; | ||
3947 | } | ||
3948 | } | 4000 | } |
3949 | 4001 | ||
3950 | return bus; | 4002 | return bus; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c new file mode 100644 index 000000000000..fa8fc4433417 --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c | |||
@@ -0,0 +1,509 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012 Broadcom Corporation | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
11 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | ||
13 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||
14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | #include <linux/netdevice.h> | ||
17 | |||
18 | #include "brcmu_wifi.h" | ||
19 | #include "brcmu_utils.h" | ||
20 | |||
21 | #include "dhd.h" | ||
22 | #include "dhd_dbg.h" | ||
23 | #include "fweh.h" | ||
24 | #include "fwil.h" | ||
25 | |||
26 | /** | ||
27 | * struct brcm_ethhdr - broadcom specific ether header. | ||
28 | * | ||
29 | * @subtype: subtype for this packet. | ||
30 | * @length: TODO: length of appended data. | ||
31 | * @version: version indication. | ||
32 | * @oui: OUI of this packet. | ||
33 | * @usr_subtype: subtype for this OUI. | ||
34 | */ | ||
35 | struct brcm_ethhdr { | ||
36 | __be16 subtype; | ||
37 | __be16 length; | ||
38 | u8 version; | ||
39 | u8 oui[3]; | ||
40 | __be16 usr_subtype; | ||
41 | } __packed; | ||
42 | |||
43 | struct brcmf_event_msg_be { | ||
44 | __be16 version; | ||
45 | __be16 flags; | ||
46 | __be32 event_type; | ||
47 | __be32 status; | ||
48 | __be32 reason; | ||
49 | __be32 auth_type; | ||
50 | __be32 datalen; | ||
51 | u8 addr[ETH_ALEN]; | ||
52 | char ifname[IFNAMSIZ]; | ||
53 | u8 ifidx; | ||
54 | u8 bsscfgidx; | ||
55 | } __packed; | ||
56 | |||
57 | /** | ||
58 | * struct brcmf_event - contents of broadcom event packet. | ||
59 | * | ||
60 | * @eth: standard ether header. | ||
61 | * @hdr: broadcom specific ether header. | ||
62 | * @msg: common part of the actual event message. | ||
63 | */ | ||
64 | struct brcmf_event { | ||
65 | struct ethhdr eth; | ||
66 | struct brcm_ethhdr hdr; | ||
67 | struct brcmf_event_msg_be msg; | ||
68 | } __packed; | ||
69 | |||
70 | /** | ||
71 | * struct brcmf_fweh_queue_item - event item on event queue. | ||
72 | * | ||
73 | * @q: list element for queuing. | ||
74 | * @code: event code. | ||
75 | * @ifidx: interface index related to this event. | ||
76 | * @ifaddr: ethernet address for interface. | ||
77 | * @emsg: common parameters of the firmware event message. | ||
78 | * @data: event specific data part of the firmware event. | ||
79 | */ | ||
80 | struct brcmf_fweh_queue_item { | ||
81 | struct list_head q; | ||
82 | enum brcmf_fweh_event_code code; | ||
83 | u8 ifidx; | ||
84 | u8 ifaddr[ETH_ALEN]; | ||
85 | struct brcmf_event_msg_be emsg; | ||
86 | u8 data[0]; | ||
87 | }; | ||
88 | |||
89 | /** | ||
90 | * struct brcmf_fweh_event_name - code, name mapping entry. | ||
91 | */ | ||
92 | struct brcmf_fweh_event_name { | ||
93 | enum brcmf_fweh_event_code code; | ||
94 | const char *name; | ||
95 | }; | ||
96 | |||
97 | #ifdef DEBUG | ||
98 | /* array for mapping code to event name */ | ||
99 | static struct brcmf_fweh_event_name fweh_event_names[] = { | ||
100 | { BRCMF_E_SET_SSID, "SET_SSID" }, | ||
101 | { BRCMF_E_JOIN, "JOIN" }, | ||
102 | { BRCMF_E_START, "START" }, | ||
103 | { BRCMF_E_AUTH, "AUTH" }, | ||
104 | { BRCMF_E_AUTH_IND, "AUTH_IND" }, | ||
105 | { BRCMF_E_DEAUTH, "DEAUTH" }, | ||
106 | { BRCMF_E_DEAUTH_IND, "DEAUTH_IND" }, | ||
107 | { BRCMF_E_ASSOC, "ASSOC" }, | ||
108 | { BRCMF_E_ASSOC_IND, "ASSOC_IND" }, | ||
109 | { BRCMF_E_REASSOC, "REASSOC" }, | ||
110 | { BRCMF_E_REASSOC_IND, "REASSOC_IND" }, | ||
111 | { BRCMF_E_DISASSOC, "DISASSOC" }, | ||
112 | { BRCMF_E_DISASSOC_IND, "DISASSOC_IND" }, | ||
113 | { BRCMF_E_QUIET_START, "START_QUIET" }, | ||
114 | { BRCMF_E_QUIET_END, "END_QUIET" }, | ||
115 | { BRCMF_E_BEACON_RX, "BEACON_RX" }, | ||
116 | { BRCMF_E_LINK, "LINK" }, | ||
117 | { BRCMF_E_MIC_ERROR, "MIC_ERROR" }, | ||
118 | { BRCMF_E_NDIS_LINK, "NDIS_LINK" }, | ||
119 | { BRCMF_E_ROAM, "ROAM" }, | ||
120 | { BRCMF_E_TXFAIL, "TXFAIL" }, | ||
121 | { BRCMF_E_PMKID_CACHE, "PMKID_CACHE" }, | ||
122 | { BRCMF_E_RETROGRADE_TSF, "RETROGRADE_TSF" }, | ||
123 | { BRCMF_E_PRUNE, "PRUNE" }, | ||
124 | { BRCMF_E_AUTOAUTH, "AUTOAUTH" }, | ||
125 | { BRCMF_E_EAPOL_MSG, "EAPOL_MSG" }, | ||
126 | { BRCMF_E_SCAN_COMPLETE, "SCAN_COMPLETE" }, | ||
127 | { BRCMF_E_ADDTS_IND, "ADDTS_IND" }, | ||
128 | { BRCMF_E_DELTS_IND, "DELTS_IND" }, | ||
129 | { BRCMF_E_BCNSENT_IND, "BCNSENT_IND" }, | ||
130 | { BRCMF_E_BCNRX_MSG, "BCNRX_MSG" }, | ||
131 | { BRCMF_E_BCNLOST_MSG, "BCNLOST_MSG" }, | ||
132 | { BRCMF_E_ROAM_PREP, "ROAM_PREP" }, | ||
133 | { BRCMF_E_PFN_NET_FOUND, "PNO_NET_FOUND" }, | ||
134 | { BRCMF_E_PFN_NET_LOST, "PNO_NET_LOST" }, | ||
135 | { BRCMF_E_RESET_COMPLETE, "RESET_COMPLETE" }, | ||
136 | { BRCMF_E_JOIN_START, "JOIN_START" }, | ||
137 | { BRCMF_E_ROAM_START, "ROAM_START" }, | ||
138 | { BRCMF_E_ASSOC_START, "ASSOC_START" }, | ||
139 | { BRCMF_E_IBSS_ASSOC, "IBSS_ASSOC" }, | ||
140 | { BRCMF_E_RADIO, "RADIO" }, | ||
141 | { BRCMF_E_PSM_WATCHDOG, "PSM_WATCHDOG" }, | ||
142 | { BRCMF_E_PROBREQ_MSG, "PROBREQ_MSG" }, | ||
143 | { BRCMF_E_SCAN_CONFIRM_IND, "SCAN_CONFIRM_IND" }, | ||
144 | { BRCMF_E_PSK_SUP, "PSK_SUP" }, | ||
145 | { BRCMF_E_COUNTRY_CODE_CHANGED, "COUNTRY_CODE_CHANGED" }, | ||
146 | { BRCMF_E_EXCEEDED_MEDIUM_TIME, "EXCEEDED_MEDIUM_TIME" }, | ||
147 | { BRCMF_E_ICV_ERROR, "ICV_ERROR" }, | ||
148 | { BRCMF_E_UNICAST_DECODE_ERROR, "UNICAST_DECODE_ERROR" }, | ||
149 | { BRCMF_E_MULTICAST_DECODE_ERROR, "MULTICAST_DECODE_ERROR" }, | ||
150 | { BRCMF_E_TRACE, "TRACE" }, | ||
151 | { BRCMF_E_IF, "IF" }, | ||
152 | { BRCMF_E_RSSI, "RSSI" }, | ||
153 | { BRCMF_E_PFN_SCAN_COMPLETE, "PFN_SCAN_COMPLETE" }, | ||
154 | { BRCMF_E_EXTLOG_MSG, "EXTLOG_MSG" }, | ||
155 | { BRCMF_E_ACTION_FRAME, "ACTION_FRAME" }, | ||
156 | { BRCMF_E_ACTION_FRAME_COMPLETE, "ACTION_FRAME_COMPLETE" }, | ||
157 | { BRCMF_E_PRE_ASSOC_IND, "PRE_ASSOC_IND" }, | ||
158 | { BRCMF_E_PRE_REASSOC_IND, "PRE_REASSOC_IND" }, | ||
159 | { BRCMF_E_CHANNEL_ADOPTED, "CHANNEL_ADOPTED" }, | ||
160 | { BRCMF_E_AP_STARTED, "AP_STARTED" }, | ||
161 | { BRCMF_E_DFS_AP_STOP, "DFS_AP_STOP" }, | ||
162 | { BRCMF_E_DFS_AP_RESUME, "DFS_AP_RESUME" }, | ||
163 | { BRCMF_E_ESCAN_RESULT, "ESCAN_RESULT" }, | ||
164 | { BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE, "ACTION_FRM_OFF_CHAN_CMPLT" }, | ||
165 | { BRCMF_E_DCS_REQUEST, "DCS_REQUEST" }, | ||
166 | { BRCMF_E_FIFO_CREDIT_MAP, "FIFO_CREDIT_MAP"} | ||
167 | }; | ||
168 | |||
169 | /** | ||
170 | * brcmf_fweh_event_name() - returns name for given event code. | ||
171 | * | ||
172 | * @code: code to lookup. | ||
173 | */ | ||
174 | static const char *brcmf_fweh_event_name(enum brcmf_fweh_event_code code) | ||
175 | { | ||
176 | int i; | ||
177 | for (i = 0; i < ARRAY_SIZE(fweh_event_names); i++) { | ||
178 | if (fweh_event_names[i].code == code) | ||
179 | return fweh_event_names[i].name; | ||
180 | } | ||
181 | return "unknown"; | ||
182 | } | ||
183 | #else | ||
184 | static const char *brcmf_fweh_event_name(enum brcmf_fweh_event_code code) | ||
185 | { | ||
186 | return "nodebug"; | ||
187 | } | ||
188 | #endif | ||
189 | |||
190 | /** | ||
191 | * brcmf_fweh_queue_event() - create and queue event. | ||
192 | * | ||
193 | * @fweh: firmware event handling info. | ||
194 | * @event: event queue entry. | ||
195 | */ | ||
196 | static void brcmf_fweh_queue_event(struct brcmf_fweh_info *fweh, | ||
197 | struct brcmf_fweh_queue_item *event) | ||
198 | { | ||
199 | ulong flags; | ||
200 | |||
201 | spin_lock_irqsave(&fweh->evt_q_lock, flags); | ||
202 | list_add_tail(&event->q, &fweh->event_q); | ||
203 | spin_unlock_irqrestore(&fweh->evt_q_lock, flags); | ||
204 | schedule_work(&fweh->event_work); | ||
205 | } | ||
206 | |||
207 | static int brcmf_fweh_call_event_handler(struct brcmf_if *ifp, | ||
208 | enum brcmf_fweh_event_code code, | ||
209 | struct brcmf_event_msg *emsg, | ||
210 | void *data) | ||
211 | { | ||
212 | struct brcmf_fweh_info *fweh; | ||
213 | int err = -EINVAL; | ||
214 | |||
215 | if (ifp) { | ||
216 | fweh = &ifp->drvr->fweh; | ||
217 | |||
218 | /* handle the event if valid interface and handler */ | ||
219 | if (ifp->ndev && fweh->evt_handler[code]) | ||
220 | err = fweh->evt_handler[code](ifp, emsg, data); | ||
221 | else | ||
222 | brcmf_dbg(ERROR, "unhandled event %d ignored\n", code); | ||
223 | } else { | ||
224 | brcmf_dbg(ERROR, "no interface object\n"); | ||
225 | } | ||
226 | return err; | ||
227 | } | ||
228 | |||
229 | /** | ||
230 | * brcmf_fweh_handle_if_event() - handle IF event. | ||
231 | * | ||
232 | * @drvr: driver information object. | ||
233 | * @item: queue entry. | ||
234 | * @ifpp: interface object (may change upon ADD action). | ||
235 | */ | ||
236 | static void brcmf_fweh_handle_if_event(struct brcmf_pub *drvr, | ||
237 | struct brcmf_event_msg *emsg, | ||
238 | void *data) | ||
239 | { | ||
240 | struct brcmf_if_event *ifevent = data; | ||
241 | struct brcmf_if *ifp; | ||
242 | int err = 0; | ||
243 | |||
244 | brcmf_dbg(EVENT, "action: %u idx: %u bsscfg: %u flags: %u\n", | ||
245 | ifevent->action, ifevent->ifidx, | ||
246 | ifevent->bssidx, ifevent->flags); | ||
247 | |||
248 | if (ifevent->ifidx >= BRCMF_MAX_IFS) { | ||
249 | brcmf_dbg(ERROR, "invalid interface index: %u\n", | ||
250 | ifevent->ifidx); | ||
251 | return; | ||
252 | } | ||
253 | |||
254 | ifp = drvr->iflist[ifevent->ifidx]; | ||
255 | |||
256 | if (ifevent->action == BRCMF_E_IF_ADD) { | ||
257 | brcmf_dbg(EVENT, "adding %s (%pM)\n", emsg->ifname, | ||
258 | emsg->addr); | ||
259 | ifp = brcmf_add_if(drvr, ifevent->ifidx, ifevent->bssidx, | ||
260 | emsg->ifname, emsg->addr); | ||
261 | if (IS_ERR(ifp)) | ||
262 | return; | ||
263 | |||
264 | if (!drvr->fweh.evt_handler[BRCMF_E_IF]) | ||
265 | err = brcmf_net_attach(ifp); | ||
266 | } | ||
267 | |||
268 | err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data); | ||
269 | |||
270 | if (ifevent->action == BRCMF_E_IF_DEL) | ||
271 | brcmf_del_if(drvr, ifevent->ifidx); | ||
272 | } | ||
273 | |||
274 | /** | ||
275 | * brcmf_fweh_dequeue_event() - get event from the queue. | ||
276 | * | ||
277 | * @fweh: firmware event handling info. | ||
278 | */ | ||
279 | static struct brcmf_fweh_queue_item * | ||
280 | brcmf_fweh_dequeue_event(struct brcmf_fweh_info *fweh) | ||
281 | { | ||
282 | struct brcmf_fweh_queue_item *event = NULL; | ||
283 | ulong flags; | ||
284 | |||
285 | spin_lock_irqsave(&fweh->evt_q_lock, flags); | ||
286 | if (!list_empty(&fweh->event_q)) { | ||
287 | event = list_first_entry(&fweh->event_q, | ||
288 | struct brcmf_fweh_queue_item, q); | ||
289 | list_del(&event->q); | ||
290 | } | ||
291 | spin_unlock_irqrestore(&fweh->evt_q_lock, flags); | ||
292 | |||
293 | return event; | ||
294 | } | ||
295 | |||
296 | /** | ||
297 | * brcmf_fweh_event_worker() - firmware event worker. | ||
298 | * | ||
299 | * @work: worker object. | ||
300 | */ | ||
301 | static void brcmf_fweh_event_worker(struct work_struct *work) | ||
302 | { | ||
303 | struct brcmf_pub *drvr; | ||
304 | struct brcmf_if *ifp; | ||
305 | struct brcmf_fweh_info *fweh; | ||
306 | struct brcmf_fweh_queue_item *event; | ||
307 | int err = 0; | ||
308 | struct brcmf_event_msg_be *emsg_be; | ||
309 | struct brcmf_event_msg emsg; | ||
310 | |||
311 | fweh = container_of(work, struct brcmf_fweh_info, event_work); | ||
312 | drvr = container_of(fweh, struct brcmf_pub, fweh); | ||
313 | |||
314 | while ((event = brcmf_fweh_dequeue_event(fweh))) { | ||
315 | ifp = drvr->iflist[event->ifidx]; | ||
316 | |||
317 | brcmf_dbg(EVENT, "event %s (%u) ifidx %u bsscfg %u addr %pM:\n", | ||
318 | brcmf_fweh_event_name(event->code), event->code, | ||
319 | event->emsg.ifidx, event->emsg.bsscfgidx, | ||
320 | event->emsg.addr); | ||
321 | |||
322 | /* convert event message */ | ||
323 | emsg_be = &event->emsg; | ||
324 | emsg.version = be16_to_cpu(emsg_be->version); | ||
325 | emsg.flags = be16_to_cpu(emsg_be->flags); | ||
326 | emsg.event_code = event->code; | ||
327 | emsg.status = be32_to_cpu(emsg_be->status); | ||
328 | emsg.reason = be32_to_cpu(emsg_be->reason); | ||
329 | emsg.auth_type = be32_to_cpu(emsg_be->auth_type); | ||
330 | emsg.datalen = be32_to_cpu(emsg_be->datalen); | ||
331 | memcpy(emsg.addr, emsg_be->addr, ETH_ALEN); | ||
332 | memcpy(emsg.ifname, emsg_be->ifname, sizeof(emsg.ifname)); | ||
333 | emsg.ifidx = emsg_be->ifidx; | ||
334 | emsg.bsscfgidx = emsg_be->bsscfgidx; | ||
335 | |||
336 | brcmf_dbg(EVENT, " version %u flags %u status %u reason %u\n", | ||
337 | emsg.version, emsg.flags, emsg.status, emsg.reason); | ||
338 | brcmf_dbg_hex_dump(BRCMF_EVENT_ON(), event->data, | ||
339 | min_t(u32, emsg.datalen, 64), | ||
340 | "appended:"); | ||
341 | |||
342 | /* special handling of interface event */ | ||
343 | if (event->code == BRCMF_E_IF) { | ||
344 | brcmf_fweh_handle_if_event(drvr, &emsg, event->data); | ||
345 | goto event_free; | ||
346 | } | ||
347 | |||
348 | err = brcmf_fweh_call_event_handler(ifp, event->code, &emsg, | ||
349 | event->data); | ||
350 | if (err) { | ||
351 | brcmf_dbg(ERROR, "event handler failed (%d)\n", | ||
352 | event->code); | ||
353 | err = 0; | ||
354 | } | ||
355 | event_free: | ||
356 | kfree(event); | ||
357 | } | ||
358 | } | ||
359 | |||
360 | /** | ||
361 | * brcmf_fweh_attach() - initialize firmware event handling. | ||
362 | * | ||
363 | * @drvr: driver information object. | ||
364 | */ | ||
365 | void brcmf_fweh_attach(struct brcmf_pub *drvr) | ||
366 | { | ||
367 | struct brcmf_fweh_info *fweh = &drvr->fweh; | ||
368 | INIT_WORK(&fweh->event_work, brcmf_fweh_event_worker); | ||
369 | spin_lock_init(&fweh->evt_q_lock); | ||
370 | INIT_LIST_HEAD(&fweh->event_q); | ||
371 | } | ||
372 | |||
373 | /** | ||
374 | * brcmf_fweh_detach() - cleanup firmware event handling. | ||
375 | * | ||
376 | * @drvr: driver information object. | ||
377 | */ | ||
378 | void brcmf_fweh_detach(struct brcmf_pub *drvr) | ||
379 | { | ||
380 | struct brcmf_fweh_info *fweh = &drvr->fweh; | ||
381 | struct brcmf_if *ifp = drvr->iflist[0]; | ||
382 | s8 eventmask[BRCMF_EVENTING_MASK_LEN]; | ||
383 | |||
384 | if (ifp) { | ||
385 | /* clear all events */ | ||
386 | memset(eventmask, 0, BRCMF_EVENTING_MASK_LEN); | ||
387 | (void)brcmf_fil_iovar_data_set(ifp, "event_msgs", | ||
388 | eventmask, | ||
389 | BRCMF_EVENTING_MASK_LEN); | ||
390 | } | ||
391 | /* cancel the worker */ | ||
392 | cancel_work_sync(&fweh->event_work); | ||
393 | WARN_ON(!list_empty(&fweh->event_q)); | ||
394 | memset(fweh->evt_handler, 0, sizeof(fweh->evt_handler)); | ||
395 | } | ||
396 | |||
397 | /** | ||
398 | * brcmf_fweh_register() - register handler for given event code. | ||
399 | * | ||
400 | * @drvr: driver information object. | ||
401 | * @code: event code. | ||
402 | * @handler: handler for the given event code. | ||
403 | */ | ||
404 | int brcmf_fweh_register(struct brcmf_pub *drvr, enum brcmf_fweh_event_code code, | ||
405 | brcmf_fweh_handler_t handler) | ||
406 | { | ||
407 | if (drvr->fweh.evt_handler[code]) { | ||
408 | brcmf_dbg(ERROR, "event code %d already registered\n", code); | ||
409 | return -ENOSPC; | ||
410 | } | ||
411 | drvr->fweh.evt_handler[code] = handler; | ||
412 | brcmf_dbg(TRACE, "event handler registered for %s\n", | ||
413 | brcmf_fweh_event_name(code)); | ||
414 | return 0; | ||
415 | } | ||
416 | |||
417 | /** | ||
418 | * brcmf_fweh_unregister() - remove handler for given code. | ||
419 | * | ||
420 | * @drvr: driver information object. | ||
421 | * @code: event code. | ||
422 | */ | ||
423 | void brcmf_fweh_unregister(struct brcmf_pub *drvr, | ||
424 | enum brcmf_fweh_event_code code) | ||
425 | { | ||
426 | brcmf_dbg(TRACE, "event handler cleared for %s\n", | ||
427 | brcmf_fweh_event_name(code)); | ||
428 | drvr->fweh.evt_handler[code] = NULL; | ||
429 | } | ||
430 | |||
431 | /** | ||
432 | * brcmf_fweh_activate_events() - enables firmware events registered. | ||
433 | * | ||
434 | * @ifp: primary interface object. | ||
435 | */ | ||
436 | int brcmf_fweh_activate_events(struct brcmf_if *ifp) | ||
437 | { | ||
438 | int i, err; | ||
439 | s8 eventmask[BRCMF_EVENTING_MASK_LEN]; | ||
440 | |||
441 | for (i = 0; i < BRCMF_E_LAST; i++) { | ||
442 | if (ifp->drvr->fweh.evt_handler[i]) { | ||
443 | brcmf_dbg(EVENT, "enable event %s\n", | ||
444 | brcmf_fweh_event_name(i)); | ||
445 | setbit(eventmask, i); | ||
446 | } | ||
447 | } | ||
448 | |||
449 | /* want to handle IF event as well */ | ||
450 | brcmf_dbg(EVENT, "enable event IF\n"); | ||
451 | setbit(eventmask, BRCMF_E_IF); | ||
452 | |||
453 | err = brcmf_fil_iovar_data_set(ifp, "event_msgs", | ||
454 | eventmask, BRCMF_EVENTING_MASK_LEN); | ||
455 | if (err) | ||
456 | brcmf_dbg(ERROR, "Set event_msgs error (%d)\n", err); | ||
457 | |||
458 | return err; | ||
459 | } | ||
460 | |||
461 | /** | ||
462 | * brcmf_fweh_process_event() - process skb as firmware event. | ||
463 | * | ||
464 | * @drvr: driver information object. | ||
465 | * @event_packet: event packet to process. | ||
466 | * @ifidx: index of the firmware interface (may change). | ||
467 | * | ||
468 | * If the packet buffer contains a firmware event message it will | ||
469 | * dispatch the event to a registered handler (using worker). | ||
470 | */ | ||
471 | void brcmf_fweh_process_event(struct brcmf_pub *drvr, | ||
472 | struct brcmf_event *event_packet, u8 *ifidx) | ||
473 | { | ||
474 | enum brcmf_fweh_event_code code; | ||
475 | struct brcmf_fweh_info *fweh = &drvr->fweh; | ||
476 | struct brcmf_fweh_queue_item *event; | ||
477 | gfp_t alloc_flag = GFP_KERNEL; | ||
478 | void *data; | ||
479 | u32 datalen; | ||
480 | |||
481 | /* get event info */ | ||
482 | code = get_unaligned_be32(&event_packet->msg.event_type); | ||
483 | datalen = get_unaligned_be32(&event_packet->msg.datalen); | ||
484 | *ifidx = event_packet->msg.ifidx; | ||
485 | data = &event_packet[1]; | ||
486 | |||
487 | if (code >= BRCMF_E_LAST) | ||
488 | return; | ||
489 | |||
490 | if (code != BRCMF_E_IF && !fweh->evt_handler[code]) | ||
491 | return; | ||
492 | |||
493 | if (in_interrupt()) | ||
494 | alloc_flag = GFP_ATOMIC; | ||
495 | |||
496 | event = kzalloc(sizeof(*event) + datalen, alloc_flag); | ||
497 | if (!event) | ||
498 | return; | ||
499 | |||
500 | event->code = code; | ||
501 | event->ifidx = *ifidx; | ||
502 | |||
503 | /* use memcpy to get aligned event message */ | ||
504 | memcpy(&event->emsg, &event_packet->msg, sizeof(event->emsg)); | ||
505 | memcpy(event->data, data, datalen); | ||
506 | memcpy(event->ifaddr, event_packet->eth.h_dest, ETH_ALEN); | ||
507 | |||
508 | brcmf_fweh_queue_event(fweh, event); | ||
509 | } | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h new file mode 100644 index 000000000000..b39246a630df --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h | |||
@@ -0,0 +1,207 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012 Broadcom Corporation | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
11 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | ||
13 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||
14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | |||
18 | #ifndef FWEH_H_ | ||
19 | #define FWEH_H_ | ||
20 | |||
21 | #include <asm/unaligned.h> | ||
22 | #include <linux/skbuff.h> | ||
23 | #include <linux/if_ether.h> | ||
24 | #include <linux/if.h> | ||
25 | |||
26 | /* formward declarations */ | ||
27 | struct brcmf_pub; | ||
28 | struct brcmf_if; | ||
29 | struct brcmf_cfg80211_info; | ||
30 | struct brcmf_event; | ||
31 | |||
32 | /* firmware event codes sent by the dongle */ | ||
33 | enum brcmf_fweh_event_code { | ||
34 | BRCMF_E_SET_SSID = 0, | ||
35 | BRCMF_E_JOIN = 1, | ||
36 | BRCMF_E_START = 2, | ||
37 | BRCMF_E_AUTH = 3, | ||
38 | BRCMF_E_AUTH_IND = 4, | ||
39 | BRCMF_E_DEAUTH = 5, | ||
40 | BRCMF_E_DEAUTH_IND = 6, | ||
41 | BRCMF_E_ASSOC = 7, | ||
42 | BRCMF_E_ASSOC_IND = 8, | ||
43 | BRCMF_E_REASSOC = 9, | ||
44 | BRCMF_E_REASSOC_IND = 10, | ||
45 | BRCMF_E_DISASSOC = 11, | ||
46 | BRCMF_E_DISASSOC_IND = 12, | ||
47 | BRCMF_E_QUIET_START = 13, | ||
48 | BRCMF_E_QUIET_END = 14, | ||
49 | BRCMF_E_BEACON_RX = 15, | ||
50 | BRCMF_E_LINK = 16, | ||
51 | BRCMF_E_MIC_ERROR = 17, | ||
52 | BRCMF_E_NDIS_LINK = 18, | ||
53 | BRCMF_E_ROAM = 19, | ||
54 | BRCMF_E_TXFAIL = 20, | ||
55 | BRCMF_E_PMKID_CACHE = 21, | ||
56 | BRCMF_E_RETROGRADE_TSF = 22, | ||
57 | BRCMF_E_PRUNE = 23, | ||
58 | BRCMF_E_AUTOAUTH = 24, | ||
59 | BRCMF_E_EAPOL_MSG = 25, | ||
60 | BRCMF_E_SCAN_COMPLETE = 26, | ||
61 | BRCMF_E_ADDTS_IND = 27, | ||
62 | BRCMF_E_DELTS_IND = 28, | ||
63 | BRCMF_E_BCNSENT_IND = 29, | ||
64 | BRCMF_E_BCNRX_MSG = 30, | ||
65 | BRCMF_E_BCNLOST_MSG = 31, | ||
66 | BRCMF_E_ROAM_PREP = 32, | ||
67 | BRCMF_E_PFN_NET_FOUND = 33, | ||
68 | BRCMF_E_PFN_NET_LOST = 34, | ||
69 | BRCMF_E_RESET_COMPLETE = 35, | ||
70 | BRCMF_E_JOIN_START = 36, | ||
71 | BRCMF_E_ROAM_START = 37, | ||
72 | BRCMF_E_ASSOC_START = 38, | ||
73 | BRCMF_E_IBSS_ASSOC = 39, | ||
74 | BRCMF_E_RADIO = 40, | ||
75 | BRCMF_E_PSM_WATCHDOG = 41, | ||
76 | BRCMF_E_PROBREQ_MSG = 44, | ||
77 | BRCMF_E_SCAN_CONFIRM_IND = 45, | ||
78 | BRCMF_E_PSK_SUP = 46, | ||
79 | BRCMF_E_COUNTRY_CODE_CHANGED = 47, | ||
80 | BRCMF_E_EXCEEDED_MEDIUM_TIME = 48, | ||
81 | BRCMF_E_ICV_ERROR = 49, | ||
82 | BRCMF_E_UNICAST_DECODE_ERROR = 50, | ||
83 | BRCMF_E_MULTICAST_DECODE_ERROR = 51, | ||
84 | BRCMF_E_TRACE = 52, | ||
85 | BRCMF_E_IF = 54, | ||
86 | BRCMF_E_RSSI = 56, | ||
87 | BRCMF_E_PFN_SCAN_COMPLETE = 57, | ||
88 | BRCMF_E_EXTLOG_MSG = 58, | ||
89 | BRCMF_E_ACTION_FRAME = 59, | ||
90 | BRCMF_E_ACTION_FRAME_COMPLETE = 60, | ||
91 | BRCMF_E_PRE_ASSOC_IND = 61, | ||
92 | BRCMF_E_PRE_REASSOC_IND = 62, | ||
93 | BRCMF_E_CHANNEL_ADOPTED = 63, | ||
94 | BRCMF_E_AP_STARTED = 64, | ||
95 | BRCMF_E_DFS_AP_STOP = 65, | ||
96 | BRCMF_E_DFS_AP_RESUME = 66, | ||
97 | BRCMF_E_ESCAN_RESULT = 69, | ||
98 | BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE = 70, | ||
99 | BRCMF_E_DCS_REQUEST = 73, | ||
100 | BRCMF_E_FIFO_CREDIT_MAP = 74, | ||
101 | BRCMF_E_LAST | ||
102 | }; | ||
103 | |||
104 | /* flags field values in struct brcmf_event_msg */ | ||
105 | #define BRCMF_EVENT_MSG_LINK 0x01 | ||
106 | #define BRCMF_EVENT_MSG_FLUSHTXQ 0x02 | ||
107 | #define BRCMF_EVENT_MSG_GROUP 0x04 | ||
108 | |||
109 | /** | ||
110 | * definitions for event packet validation. | ||
111 | */ | ||
112 | #define BRCMF_EVENT_OUI_OFFSET 19 | ||
113 | #define BRCM_OUI "\x00\x10\x18" | ||
114 | #define DOT11_OUI_LEN 3 | ||
115 | #define BCMILCP_BCM_SUBTYPE_EVENT 1 | ||
116 | |||
117 | |||
118 | /** | ||
119 | * struct brcmf_event_msg - firmware event message. | ||
120 | * | ||
121 | * @version: version information. | ||
122 | * @flags: event flags. | ||
123 | * @event_code: firmware event code. | ||
124 | * @status: status information. | ||
125 | * @reason: reason code. | ||
126 | * @auth_type: authentication type. | ||
127 | * @datalen: lenght of event data buffer. | ||
128 | * @addr: ether address. | ||
129 | * @ifname: interface name. | ||
130 | * @ifidx: interface index. | ||
131 | * @bsscfgidx: bsscfg index. | ||
132 | */ | ||
133 | struct brcmf_event_msg { | ||
134 | u16 version; | ||
135 | u16 flags; | ||
136 | u32 event_code; | ||
137 | u32 status; | ||
138 | u32 reason; | ||
139 | s32 auth_type; | ||
140 | u32 datalen; | ||
141 | u8 addr[ETH_ALEN]; | ||
142 | char ifname[IFNAMSIZ]; | ||
143 | u8 ifidx; | ||
144 | u8 bsscfgidx; | ||
145 | }; | ||
146 | |||
147 | typedef int (*brcmf_fweh_handler_t)(struct brcmf_if *ifp, | ||
148 | const struct brcmf_event_msg *evtmsg, | ||
149 | void *data); | ||
150 | |||
151 | /** | ||
152 | * struct brcmf_fweh_info - firmware event handling information. | ||
153 | * | ||
154 | * @event_work: event worker. | ||
155 | * @evt_q_lock: lock for event queue protection. | ||
156 | * @event_q: event queue. | ||
157 | * @evt_handler: registered event handlers. | ||
158 | */ | ||
159 | struct brcmf_fweh_info { | ||
160 | struct work_struct event_work; | ||
161 | struct spinlock evt_q_lock; | ||
162 | struct list_head event_q; | ||
163 | int (*evt_handler[BRCMF_E_LAST])(struct brcmf_if *ifp, | ||
164 | const struct brcmf_event_msg *evtmsg, | ||
165 | void *data); | ||
166 | }; | ||
167 | |||
168 | void brcmf_fweh_attach(struct brcmf_pub *drvr); | ||
169 | void brcmf_fweh_detach(struct brcmf_pub *drvr); | ||
170 | int brcmf_fweh_register(struct brcmf_pub *drvr, enum brcmf_fweh_event_code code, | ||
171 | int (*handler)(struct brcmf_if *ifp, | ||
172 | const struct brcmf_event_msg *evtmsg, | ||
173 | void *data)); | ||
174 | void brcmf_fweh_unregister(struct brcmf_pub *drvr, | ||
175 | enum brcmf_fweh_event_code code); | ||
176 | int brcmf_fweh_activate_events(struct brcmf_if *ifp); | ||
177 | void brcmf_fweh_process_event(struct brcmf_pub *drvr, | ||
178 | struct brcmf_event *event_packet, u8 *ifidx); | ||
179 | |||
180 | static inline void brcmf_fweh_process_skb(struct brcmf_pub *drvr, | ||
181 | struct sk_buff *skb, u8 *ifidx) | ||
182 | { | ||
183 | struct brcmf_event *event_packet; | ||
184 | u8 *data; | ||
185 | u16 usr_stype; | ||
186 | |||
187 | /* only process events when protocol matches */ | ||
188 | if (skb->protocol != cpu_to_be16(ETH_P_LINK_CTL)) | ||
189 | return; | ||
190 | |||
191 | /* check for BRCM oui match */ | ||
192 | event_packet = (struct brcmf_event *)skb_mac_header(skb); | ||
193 | data = (u8 *)event_packet; | ||
194 | data += BRCMF_EVENT_OUI_OFFSET; | ||
195 | if (memcmp(BRCM_OUI, data, DOT11_OUI_LEN)) | ||
196 | return; | ||
197 | |||
198 | /* final match on usr_subtype */ | ||
199 | data += DOT11_OUI_LEN; | ||
200 | usr_stype = get_unaligned_be16(data); | ||
201 | if (usr_stype != BCMILCP_BCM_SUBTYPE_EVENT) | ||
202 | return; | ||
203 | |||
204 | brcmf_fweh_process_event(drvr, event_packet, ifidx); | ||
205 | } | ||
206 | |||
207 | #endif /* FWEH_H_ */ | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c index 4b272c3d237c..51a14505197a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c | |||
@@ -20,7 +20,6 @@ | |||
20 | 20 | ||
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/netdevice.h> | 22 | #include <linux/netdevice.h> |
23 | #include <defs.h> | ||
24 | #include <brcmu_utils.h> | 23 | #include <brcmu_utils.h> |
25 | #include <brcmu_wifi.h> | 24 | #include <brcmu_wifi.h> |
26 | #include "dhd.h" | 25 | #include "dhd.h" |
@@ -29,13 +28,16 @@ | |||
29 | #include "fwil.h" | 28 | #include "fwil.h" |
30 | 29 | ||
31 | 30 | ||
31 | #define MAX_HEX_DUMP_LEN 64 | ||
32 | |||
33 | |||
32 | static s32 | 34 | static s32 |
33 | brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set) | 35 | brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set) |
34 | { | 36 | { |
35 | struct brcmf_pub *drvr = ifp->drvr; | 37 | struct brcmf_pub *drvr = ifp->drvr; |
36 | s32 err; | 38 | s32 err; |
37 | 39 | ||
38 | if (drvr->bus_if->state == BRCMF_BUS_DOWN) { | 40 | if (drvr->bus_if->state != BRCMF_BUS_DATA) { |
39 | brcmf_dbg(ERROR, "bus is down. we have nothing to do.\n"); | 41 | brcmf_dbg(ERROR, "bus is down. we have nothing to do.\n"); |
40 | return -EIO; | 42 | return -EIO; |
41 | } | 43 | } |
@@ -64,7 +66,8 @@ brcmf_fil_cmd_data_set(struct brcmf_if *ifp, u32 cmd, void *data, u32 len) | |||
64 | mutex_lock(&ifp->drvr->proto_block); | 66 | mutex_lock(&ifp->drvr->proto_block); |
65 | 67 | ||
66 | brcmf_dbg(FIL, "cmd=%d, len=%d\n", cmd, len); | 68 | brcmf_dbg(FIL, "cmd=%d, len=%d\n", cmd, len); |
67 | brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data"); | 69 | brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, |
70 | min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); | ||
68 | 71 | ||
69 | err = brcmf_fil_cmd_data(ifp, cmd, data, len, true); | 72 | err = brcmf_fil_cmd_data(ifp, cmd, data, len, true); |
70 | mutex_unlock(&ifp->drvr->proto_block); | 73 | mutex_unlock(&ifp->drvr->proto_block); |
@@ -81,7 +84,8 @@ brcmf_fil_cmd_data_get(struct brcmf_if *ifp, u32 cmd, void *data, u32 len) | |||
81 | err = brcmf_fil_cmd_data(ifp, cmd, data, len, false); | 84 | err = brcmf_fil_cmd_data(ifp, cmd, data, len, false); |
82 | 85 | ||
83 | brcmf_dbg(FIL, "cmd=%d, len=%d\n", cmd, len); | 86 | brcmf_dbg(FIL, "cmd=%d, len=%d\n", cmd, len); |
84 | brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data"); | 87 | brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, |
88 | min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); | ||
85 | 89 | ||
86 | mutex_unlock(&ifp->drvr->proto_block); | 90 | mutex_unlock(&ifp->drvr->proto_block); |
87 | 91 | ||
@@ -147,7 +151,8 @@ brcmf_fil_iovar_data_set(struct brcmf_if *ifp, char *name, void *data, | |||
147 | mutex_lock(&drvr->proto_block); | 151 | mutex_lock(&drvr->proto_block); |
148 | 152 | ||
149 | brcmf_dbg(FIL, "name=%s, len=%d\n", name, len); | 153 | brcmf_dbg(FIL, "name=%s, len=%d\n", name, len); |
150 | brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data"); | 154 | brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, |
155 | min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); | ||
151 | 156 | ||
152 | buflen = brcmf_create_iovar(name, data, len, drvr->proto_buf, | 157 | buflen = brcmf_create_iovar(name, data, len, drvr->proto_buf, |
153 | sizeof(drvr->proto_buf)); | 158 | sizeof(drvr->proto_buf)); |
@@ -186,7 +191,8 @@ brcmf_fil_iovar_data_get(struct brcmf_if *ifp, char *name, void *data, | |||
186 | } | 191 | } |
187 | 192 | ||
188 | brcmf_dbg(FIL, "name=%s, len=%d\n", name, len); | 193 | brcmf_dbg(FIL, "name=%s, len=%d\n", name, len); |
189 | brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data"); | 194 | brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, |
195 | min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); | ||
190 | 196 | ||
191 | mutex_unlock(&drvr->proto_block); | 197 | mutex_unlock(&drvr->proto_block); |
192 | return err; | 198 | return err; |
@@ -268,7 +274,8 @@ brcmf_fil_bsscfg_data_set(struct brcmf_if *ifp, char *name, | |||
268 | mutex_lock(&drvr->proto_block); | 274 | mutex_lock(&drvr->proto_block); |
269 | 275 | ||
270 | brcmf_dbg(FIL, "bssidx=%d, name=%s, len=%d\n", ifp->bssidx, name, len); | 276 | brcmf_dbg(FIL, "bssidx=%d, name=%s, len=%d\n", ifp->bssidx, name, len); |
271 | brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data"); | 277 | brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, |
278 | min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); | ||
272 | 279 | ||
273 | buflen = brcmf_create_bsscfg(ifp->bssidx, name, data, len, | 280 | buflen = brcmf_create_bsscfg(ifp->bssidx, name, data, len, |
274 | drvr->proto_buf, sizeof(drvr->proto_buf)); | 281 | drvr->proto_buf, sizeof(drvr->proto_buf)); |
@@ -294,7 +301,7 @@ brcmf_fil_bsscfg_data_get(struct brcmf_if *ifp, char *name, | |||
294 | 301 | ||
295 | mutex_lock(&drvr->proto_block); | 302 | mutex_lock(&drvr->proto_block); |
296 | 303 | ||
297 | buflen = brcmf_create_bsscfg(ifp->bssidx, name, NULL, len, | 304 | buflen = brcmf_create_bsscfg(ifp->bssidx, name, data, len, |
298 | drvr->proto_buf, sizeof(drvr->proto_buf)); | 305 | drvr->proto_buf, sizeof(drvr->proto_buf)); |
299 | if (buflen) { | 306 | if (buflen) { |
300 | err = brcmf_fil_cmd_data(ifp, BRCMF_C_GET_VAR, drvr->proto_buf, | 307 | err = brcmf_fil_cmd_data(ifp, BRCMF_C_GET_VAR, drvr->proto_buf, |
@@ -306,7 +313,8 @@ brcmf_fil_bsscfg_data_get(struct brcmf_if *ifp, char *name, | |||
306 | brcmf_dbg(ERROR, "Creating bsscfg failed\n"); | 313 | brcmf_dbg(ERROR, "Creating bsscfg failed\n"); |
307 | } | 314 | } |
308 | brcmf_dbg(FIL, "bssidx=%d, name=%s, len=%d\n", ifp->bssidx, name, len); | 315 | brcmf_dbg(FIL, "bssidx=%d, name=%s, len=%d\n", ifp->bssidx, name, len); |
309 | brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data"); | 316 | brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, |
317 | min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); | ||
310 | 318 | ||
311 | mutex_unlock(&drvr->proto_block); | 319 | mutex_unlock(&drvr->proto_block); |
312 | return err; | 320 | return err; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index 484a6e4f23a2..39a5baa92f21 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c | |||
@@ -14,24 +14,12 @@ | |||
14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
19 | #include <linux/module.h> | 18 | #include <linux/module.h> |
20 | #include <linux/kthread.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/skbuff.h> | ||
23 | #include <linux/netdevice.h> | ||
24 | #include <linux/spinlock.h> | ||
25 | #include <linux/ethtool.h> | ||
26 | #include <linux/fcntl.h> | ||
27 | #include <linux/fs.h> | ||
28 | #include <linux/uaccess.h> | ||
29 | #include <linux/firmware.h> | 19 | #include <linux/firmware.h> |
30 | #include <linux/usb.h> | 20 | #include <linux/usb.h> |
31 | #include <linux/vmalloc.h> | 21 | #include <linux/vmalloc.h> |
32 | #include <net/cfg80211.h> | ||
33 | 22 | ||
34 | #include <defs.h> | ||
35 | #include <brcmu_utils.h> | 23 | #include <brcmu_utils.h> |
36 | #include <brcmu_wifi.h> | 24 | #include <brcmu_wifi.h> |
37 | #include <dhd_bus.h> | 25 | #include <dhd_bus.h> |
@@ -42,13 +30,11 @@ | |||
42 | 30 | ||
43 | #define IOCTL_RESP_TIMEOUT 2000 | 31 | #define IOCTL_RESP_TIMEOUT 2000 |
44 | 32 | ||
45 | #define BRCMF_USB_DLIMAGE_SPINWAIT 100 /* in unit of ms */ | 33 | #define BRCMF_USB_RESET_GETVER_SPINWAIT 100 /* in unit of ms */ |
46 | #define BRCMF_USB_DLIMAGE_LIMIT 500 /* spinwait limit (ms) */ | 34 | #define BRCMF_USB_RESET_GETVER_LOOP_CNT 10 |
47 | 35 | ||
48 | #define BRCMF_POSTBOOT_ID 0xA123 /* ID to detect if dongle | 36 | #define BRCMF_POSTBOOT_ID 0xA123 /* ID to detect if dongle |
49 | has boot up */ | 37 | has boot up */ |
50 | #define BRCMF_USB_RESETCFG_SPINWAIT 1 /* wait after resetcfg (ms) */ | ||
51 | |||
52 | #define BRCMF_USB_NRXQ 50 | 38 | #define BRCMF_USB_NRXQ 50 |
53 | #define BRCMF_USB_NTXQ 50 | 39 | #define BRCMF_USB_NTXQ 50 |
54 | 40 | ||
@@ -69,16 +55,6 @@ | |||
69 | #define BRCMF_USB_43236_FW_NAME "brcm/brcmfmac43236b.bin" | 55 | #define BRCMF_USB_43236_FW_NAME "brcm/brcmfmac43236b.bin" |
70 | #define BRCMF_USB_43242_FW_NAME "brcm/brcmfmac43242a.bin" | 56 | #define BRCMF_USB_43242_FW_NAME "brcm/brcmfmac43242a.bin" |
71 | 57 | ||
72 | enum usbdev_suspend_state { | ||
73 | USBOS_SUSPEND_STATE_DEVICE_ACTIVE = 0, /* Device is busy, won't allow | ||
74 | suspend */ | ||
75 | USBOS_SUSPEND_STATE_SUSPEND_PENDING, /* Device is idle, can be | ||
76 | * suspended. Wating PM to | ||
77 | * suspend the device | ||
78 | */ | ||
79 | USBOS_SUSPEND_STATE_SUSPENDED /* Device suspended */ | ||
80 | }; | ||
81 | |||
82 | struct brcmf_usb_image { | 58 | struct brcmf_usb_image { |
83 | struct list_head list; | 59 | struct list_head list; |
84 | s8 *fwname; | 60 | s8 *fwname; |
@@ -99,10 +75,8 @@ struct brcmf_usbdev_info { | |||
99 | struct list_head rx_postq; | 75 | struct list_head rx_postq; |
100 | struct list_head tx_freeq; | 76 | struct list_head tx_freeq; |
101 | struct list_head tx_postq; | 77 | struct list_head tx_postq; |
102 | enum usbdev_suspend_state suspend_state; | ||
103 | uint rx_pipe, tx_pipe, intr_pipe, rx_pipe2; | 78 | uint rx_pipe, tx_pipe, intr_pipe, rx_pipe2; |
104 | 79 | ||
105 | bool activity; | ||
106 | int rx_low_watermark; | 80 | int rx_low_watermark; |
107 | int tx_low_watermark; | 81 | int tx_low_watermark; |
108 | int tx_high_watermark; | 82 | int tx_high_watermark; |
@@ -170,6 +144,7 @@ static void brcmf_usb_ioctl_resp_wake(struct brcmf_usbdev_info *devinfo) | |||
170 | static void | 144 | static void |
171 | brcmf_usb_ctl_complete(struct brcmf_usbdev_info *devinfo, int type, int status) | 145 | brcmf_usb_ctl_complete(struct brcmf_usbdev_info *devinfo, int type, int status) |
172 | { | 146 | { |
147 | brcmf_dbg(USB, "Enter, status=%d\n", status); | ||
173 | 148 | ||
174 | if (unlikely(devinfo == NULL)) | 149 | if (unlikely(devinfo == NULL)) |
175 | return; | 150 | return; |
@@ -197,6 +172,7 @@ brcmf_usb_ctlread_complete(struct urb *urb) | |||
197 | struct brcmf_usbdev_info *devinfo = | 172 | struct brcmf_usbdev_info *devinfo = |
198 | (struct brcmf_usbdev_info *)urb->context; | 173 | (struct brcmf_usbdev_info *)urb->context; |
199 | 174 | ||
175 | brcmf_dbg(USB, "Enter\n"); | ||
200 | devinfo->ctl_urb_actual_length = urb->actual_length; | 176 | devinfo->ctl_urb_actual_length = urb->actual_length; |
201 | brcmf_usb_ctl_complete(devinfo, BRCMF_USB_CBCTL_READ, | 177 | brcmf_usb_ctl_complete(devinfo, BRCMF_USB_CBCTL_READ, |
202 | urb->status); | 178 | urb->status); |
@@ -208,33 +184,22 @@ brcmf_usb_ctlwrite_complete(struct urb *urb) | |||
208 | struct brcmf_usbdev_info *devinfo = | 184 | struct brcmf_usbdev_info *devinfo = |
209 | (struct brcmf_usbdev_info *)urb->context; | 185 | (struct brcmf_usbdev_info *)urb->context; |
210 | 186 | ||
187 | brcmf_dbg(USB, "Enter\n"); | ||
211 | brcmf_usb_ctl_complete(devinfo, BRCMF_USB_CBCTL_WRITE, | 188 | brcmf_usb_ctl_complete(devinfo, BRCMF_USB_CBCTL_WRITE, |
212 | urb->status); | 189 | urb->status); |
213 | } | 190 | } |
214 | 191 | ||
215 | static int brcmf_usb_pnp(struct brcmf_usbdev_info *devinfo, uint state) | ||
216 | { | ||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | static int | 192 | static int |
221 | brcmf_usb_send_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len) | 193 | brcmf_usb_send_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len) |
222 | { | 194 | { |
223 | int ret; | 195 | int ret; |
224 | u16 size; | 196 | u16 size; |
225 | 197 | ||
198 | brcmf_dbg(USB, "Enter\n"); | ||
226 | if (devinfo == NULL || buf == NULL || | 199 | if (devinfo == NULL || buf == NULL || |
227 | len == 0 || devinfo->ctl_urb == NULL) | 200 | len == 0 || devinfo->ctl_urb == NULL) |
228 | return -EINVAL; | 201 | return -EINVAL; |
229 | 202 | ||
230 | /* If the USB/HSIC bus in sleep state, wake it up */ | ||
231 | if (devinfo->suspend_state == USBOS_SUSPEND_STATE_SUSPENDED) | ||
232 | if (brcmf_usb_pnp(devinfo, BCMFMAC_USB_PNP_RESUME) != 0) { | ||
233 | brcmf_dbg(ERROR, "Could not Resume the bus!\n"); | ||
234 | return -EIO; | ||
235 | } | ||
236 | |||
237 | devinfo->activity = true; | ||
238 | size = len; | 203 | size = len; |
239 | devinfo->ctl_write.wLength = cpu_to_le16p(&size); | 204 | devinfo->ctl_write.wLength = cpu_to_le16p(&size); |
240 | devinfo->ctl_urb->transfer_buffer_length = size; | 205 | devinfo->ctl_urb->transfer_buffer_length = size; |
@@ -262,6 +227,7 @@ brcmf_usb_recv_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len) | |||
262 | int ret; | 227 | int ret; |
263 | u16 size; | 228 | u16 size; |
264 | 229 | ||
230 | brcmf_dbg(USB, "Enter\n"); | ||
265 | if ((devinfo == NULL) || (buf == NULL) || (len == 0) | 231 | if ((devinfo == NULL) || (buf == NULL) || (len == 0) |
266 | || (devinfo->ctl_urb == NULL)) | 232 | || (devinfo->ctl_urb == NULL)) |
267 | return -EINVAL; | 233 | return -EINVAL; |
@@ -295,10 +261,9 @@ static int brcmf_usb_tx_ctlpkt(struct device *dev, u8 *buf, u32 len) | |||
295 | int timeout = 0; | 261 | int timeout = 0; |
296 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); | 262 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); |
297 | 263 | ||
298 | if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { | 264 | brcmf_dbg(USB, "Enter\n"); |
299 | /* TODO: handle suspend/resume */ | 265 | if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) |
300 | return -EIO; | 266 | return -EIO; |
301 | } | ||
302 | 267 | ||
303 | if (test_and_set_bit(0, &devinfo->ctl_op)) | 268 | if (test_and_set_bit(0, &devinfo->ctl_op)) |
304 | return -EIO; | 269 | return -EIO; |
@@ -325,10 +290,10 @@ static int brcmf_usb_rx_ctlpkt(struct device *dev, u8 *buf, u32 len) | |||
325 | int timeout = 0; | 290 | int timeout = 0; |
326 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); | 291 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); |
327 | 292 | ||
328 | if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { | 293 | brcmf_dbg(USB, "Enter\n"); |
329 | /* TODO: handle suspend/resume */ | 294 | if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) |
330 | return -EIO; | 295 | return -EIO; |
331 | } | 296 | |
332 | if (test_and_set_bit(0, &devinfo->ctl_op)) | 297 | if (test_and_set_bit(0, &devinfo->ctl_op)) |
333 | return -EIO; | 298 | return -EIO; |
334 | 299 | ||
@@ -453,6 +418,8 @@ static void brcmf_usb_tx_complete(struct urb *urb) | |||
453 | struct brcmf_usbreq *req = (struct brcmf_usbreq *)urb->context; | 418 | struct brcmf_usbreq *req = (struct brcmf_usbreq *)urb->context; |
454 | struct brcmf_usbdev_info *devinfo = req->devinfo; | 419 | struct brcmf_usbdev_info *devinfo = req->devinfo; |
455 | 420 | ||
421 | brcmf_dbg(USB, "Enter, urb->status=%d, skb=%p\n", urb->status, | ||
422 | req->skb); | ||
456 | brcmf_usb_del_fromq(devinfo, req); | 423 | brcmf_usb_del_fromq(devinfo, req); |
457 | if (urb->status == 0) | 424 | if (urb->status == 0) |
458 | devinfo->bus_pub.bus->dstats.tx_packets++; | 425 | devinfo->bus_pub.bus->dstats.tx_packets++; |
@@ -478,6 +445,7 @@ static void brcmf_usb_rx_complete(struct urb *urb) | |||
478 | struct sk_buff *skb; | 445 | struct sk_buff *skb; |
479 | int ifidx = 0; | 446 | int ifidx = 0; |
480 | 447 | ||
448 | brcmf_dbg(USB, "Enter, urb->status=%d\n", urb->status); | ||
481 | brcmf_usb_del_fromq(devinfo, req); | 449 | brcmf_usb_del_fromq(devinfo, req); |
482 | skb = req->skb; | 450 | skb = req->skb; |
483 | req->skb = NULL; | 451 | req->skb = NULL; |
@@ -491,7 +459,7 @@ static void brcmf_usb_rx_complete(struct urb *urb) | |||
491 | return; | 459 | return; |
492 | } | 460 | } |
493 | 461 | ||
494 | if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP) { | 462 | if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) { |
495 | skb_put(skb, urb->actual_length); | 463 | skb_put(skb, urb->actual_length); |
496 | if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) { | 464 | if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) { |
497 | brcmf_dbg(ERROR, "rx protocol error\n"); | 465 | brcmf_dbg(ERROR, "rx protocol error\n"); |
@@ -544,8 +512,8 @@ static void brcmf_usb_rx_fill_all(struct brcmf_usbdev_info *devinfo) | |||
544 | { | 512 | { |
545 | struct brcmf_usbreq *req; | 513 | struct brcmf_usbreq *req; |
546 | 514 | ||
547 | if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { | 515 | if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) { |
548 | brcmf_dbg(ERROR, "bus is not up\n"); | 516 | brcmf_dbg(ERROR, "bus is not up=%d\n", devinfo->bus_pub.state); |
549 | return; | 517 | return; |
550 | } | 518 | } |
551 | while ((req = brcmf_usb_deq(devinfo, &devinfo->rx_freeq, NULL)) != NULL) | 519 | while ((req = brcmf_usb_deq(devinfo, &devinfo->rx_freeq, NULL)) != NULL) |
@@ -558,29 +526,24 @@ brcmf_usb_state_change(struct brcmf_usbdev_info *devinfo, int state) | |||
558 | struct brcmf_bus *bcmf_bus = devinfo->bus_pub.bus; | 526 | struct brcmf_bus *bcmf_bus = devinfo->bus_pub.bus; |
559 | int old_state; | 527 | int old_state; |
560 | 528 | ||
529 | brcmf_dbg(USB, "Enter, current state=%d, new state=%d\n", | ||
530 | devinfo->bus_pub.state, state); | ||
561 | 531 | ||
562 | if (devinfo->bus_pub.state == state) | 532 | if (devinfo->bus_pub.state == state) |
563 | return; | 533 | return; |
564 | 534 | ||
565 | old_state = devinfo->bus_pub.state; | 535 | old_state = devinfo->bus_pub.state; |
566 | brcmf_dbg(TRACE, "dbus state change from %d to to %d\n", | 536 | devinfo->bus_pub.state = state; |
567 | old_state, state); | ||
568 | |||
569 | /* Don't update state if it's PnP firmware re-download */ | ||
570 | if (state != BCMFMAC_USB_STATE_PNP_FWDL) /* TODO */ | ||
571 | devinfo->bus_pub.state = state; | ||
572 | |||
573 | if ((old_state == BCMFMAC_USB_STATE_SLEEP) | ||
574 | && (state == BCMFMAC_USB_STATE_UP)) { | ||
575 | brcmf_usb_rx_fill_all(devinfo); | ||
576 | } | ||
577 | 537 | ||
578 | /* update state of upper layer */ | 538 | /* update state of upper layer */ |
579 | if (state == BCMFMAC_USB_STATE_DOWN) { | 539 | if (state == BRCMFMAC_USB_STATE_DOWN) { |
580 | brcmf_dbg(INFO, "DBUS is down\n"); | 540 | brcmf_dbg(USB, "DBUS is down\n"); |
581 | bcmf_bus->state = BRCMF_BUS_DOWN; | 541 | bcmf_bus->state = BRCMF_BUS_DOWN; |
542 | } else if (state == BRCMFMAC_USB_STATE_UP) { | ||
543 | brcmf_dbg(USB, "DBUS is up\n"); | ||
544 | bcmf_bus->state = BRCMF_BUS_DATA; | ||
582 | } else { | 545 | } else { |
583 | brcmf_dbg(INFO, "DBUS current state=%d\n", state); | 546 | brcmf_dbg(USB, "DBUS current state=%d\n", state); |
584 | } | 547 | } |
585 | } | 548 | } |
586 | 549 | ||
@@ -589,30 +552,32 @@ brcmf_usb_intr_complete(struct urb *urb) | |||
589 | { | 552 | { |
590 | struct brcmf_usbdev_info *devinfo = | 553 | struct brcmf_usbdev_info *devinfo = |
591 | (struct brcmf_usbdev_info *)urb->context; | 554 | (struct brcmf_usbdev_info *)urb->context; |
592 | bool killed; | 555 | int err; |
556 | |||
557 | brcmf_dbg(USB, "Enter, urb->status=%d\n", urb->status); | ||
593 | 558 | ||
594 | if (devinfo == NULL) | 559 | if (devinfo == NULL) |
595 | return; | 560 | return; |
596 | 561 | ||
597 | if (unlikely(urb->status)) { | 562 | if (unlikely(urb->status)) { |
598 | if (devinfo->suspend_state == | 563 | if (urb->status == -ENOENT || |
599 | USBOS_SUSPEND_STATE_SUSPEND_PENDING) | 564 | urb->status == -ESHUTDOWN || |
600 | killed = true; | 565 | urb->status == -ENODEV) { |
601 | 566 | brcmf_usb_state_change(devinfo, | |
602 | if ((urb->status == -ENOENT && (!killed)) | 567 | BRCMFMAC_USB_STATE_DOWN); |
603 | || urb->status == -ESHUTDOWN || | ||
604 | urb->status == -ENODEV) { | ||
605 | brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_DOWN); | ||
606 | } | 568 | } |
607 | } | 569 | } |
608 | 570 | ||
609 | if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_DOWN) { | 571 | if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_DOWN) { |
610 | brcmf_dbg(ERROR, "intr cb when DBUS down, ignoring\n"); | 572 | brcmf_dbg(ERROR, "intr cb when DBUS down, ignoring\n"); |
611 | return; | 573 | return; |
612 | } | 574 | } |
613 | 575 | ||
614 | if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP) | 576 | if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) { |
615 | usb_submit_urb(devinfo->intr_urb, GFP_ATOMIC); | 577 | err = usb_submit_urb(devinfo->intr_urb, GFP_ATOMIC); |
578 | if (err) | ||
579 | brcmf_dbg(ERROR, "usb_submit_urb, err=%d\n", err); | ||
580 | } | ||
616 | } | 581 | } |
617 | 582 | ||
618 | static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb) | 583 | static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb) |
@@ -621,10 +586,9 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb) | |||
621 | struct brcmf_usbreq *req; | 586 | struct brcmf_usbreq *req; |
622 | int ret; | 587 | int ret; |
623 | 588 | ||
624 | if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { | 589 | brcmf_dbg(USB, "Enter, skb=%p\n", skb); |
625 | /* TODO: handle suspend/resume */ | 590 | if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) |
626 | return -EIO; | 591 | return -EIO; |
627 | } | ||
628 | 592 | ||
629 | req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq, | 593 | req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq, |
630 | &devinfo->tx_freecount); | 594 | &devinfo->tx_freecount); |
@@ -664,25 +628,16 @@ static int brcmf_usb_up(struct device *dev) | |||
664 | { | 628 | { |
665 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); | 629 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); |
666 | u16 ifnum; | 630 | u16 ifnum; |
631 | int ret; | ||
667 | 632 | ||
668 | if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP) | 633 | brcmf_dbg(USB, "Enter\n"); |
634 | if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) | ||
669 | return 0; | 635 | return 0; |
670 | 636 | ||
671 | /* If the USB/HSIC bus in sleep state, wake it up */ | ||
672 | if (devinfo->suspend_state == USBOS_SUSPEND_STATE_SUSPENDED) { | ||
673 | if (brcmf_usb_pnp(devinfo, BCMFMAC_USB_PNP_RESUME) != 0) { | ||
674 | brcmf_dbg(ERROR, "Could not Resume the bus!\n"); | ||
675 | return -EIO; | ||
676 | } | ||
677 | } | ||
678 | devinfo->activity = true; | ||
679 | |||
680 | /* Success, indicate devinfo is fully up */ | 637 | /* Success, indicate devinfo is fully up */ |
681 | brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_UP); | 638 | brcmf_usb_state_change(devinfo, BRCMFMAC_USB_STATE_UP); |
682 | 639 | ||
683 | if (devinfo->intr_urb) { | 640 | if (devinfo->intr_urb) { |
684 | int ret; | ||
685 | |||
686 | usb_fill_int_urb(devinfo->intr_urb, devinfo->usbdev, | 641 | usb_fill_int_urb(devinfo->intr_urb, devinfo->usbdev, |
687 | devinfo->intr_pipe, | 642 | devinfo->intr_pipe, |
688 | &devinfo->intr, | 643 | &devinfo->intr, |
@@ -727,14 +682,14 @@ static void brcmf_usb_down(struct device *dev) | |||
727 | { | 682 | { |
728 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); | 683 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); |
729 | 684 | ||
685 | brcmf_dbg(USB, "Enter\n"); | ||
730 | if (devinfo == NULL) | 686 | if (devinfo == NULL) |
731 | return; | 687 | return; |
732 | 688 | ||
733 | brcmf_dbg(TRACE, "enter\n"); | 689 | if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_DOWN) |
734 | if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_DOWN) | ||
735 | return; | 690 | return; |
736 | 691 | ||
737 | brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_DOWN); | 692 | brcmf_usb_state_change(devinfo, BRCMFMAC_USB_STATE_DOWN); |
738 | if (devinfo->intr_urb) | 693 | if (devinfo->intr_urb) |
739 | usb_kill_urb(devinfo->intr_urb); | 694 | usb_kill_urb(devinfo->intr_urb); |
740 | 695 | ||
@@ -808,27 +763,25 @@ brcmf_usb_dlneeded(struct brcmf_usbdev_info *devinfo) | |||
808 | struct bootrom_id_le id; | 763 | struct bootrom_id_le id; |
809 | u32 chipid, chiprev; | 764 | u32 chipid, chiprev; |
810 | 765 | ||
811 | brcmf_dbg(TRACE, "enter\n"); | 766 | brcmf_dbg(USB, "Enter\n"); |
812 | 767 | ||
813 | if (devinfo == NULL) | 768 | if (devinfo == NULL) |
814 | return false; | 769 | return false; |
815 | 770 | ||
816 | /* Check if firmware downloaded already by querying runtime ID */ | 771 | /* Check if firmware downloaded already by querying runtime ID */ |
817 | id.chip = cpu_to_le32(0xDEAD); | 772 | id.chip = cpu_to_le32(0xDEAD); |
818 | brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id, | 773 | brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id, sizeof(id)); |
819 | sizeof(struct bootrom_id_le)); | ||
820 | 774 | ||
821 | chipid = le32_to_cpu(id.chip); | 775 | chipid = le32_to_cpu(id.chip); |
822 | chiprev = le32_to_cpu(id.chiprev); | 776 | chiprev = le32_to_cpu(id.chiprev); |
823 | 777 | ||
824 | if ((chipid & 0x4300) == 0x4300) | 778 | if ((chipid & 0x4300) == 0x4300) |
825 | brcmf_dbg(INFO, "chip %x rev 0x%x\n", chipid, chiprev); | 779 | brcmf_dbg(USB, "chip %x rev 0x%x\n", chipid, chiprev); |
826 | else | 780 | else |
827 | brcmf_dbg(INFO, "chip %d rev 0x%x\n", chipid, chiprev); | 781 | brcmf_dbg(USB, "chip %d rev 0x%x\n", chipid, chiprev); |
828 | if (chipid == BRCMF_POSTBOOT_ID) { | 782 | if (chipid == BRCMF_POSTBOOT_ID) { |
829 | brcmf_dbg(INFO, "firmware already downloaded\n"); | 783 | brcmf_dbg(USB, "firmware already downloaded\n"); |
830 | brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id, | 784 | brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id, sizeof(id)); |
831 | sizeof(struct bootrom_id_le)); | ||
832 | return false; | 785 | return false; |
833 | } else { | 786 | } else { |
834 | devinfo->bus_pub.devid = chipid; | 787 | devinfo->bus_pub.devid = chipid; |
@@ -841,38 +794,29 @@ static int | |||
841 | brcmf_usb_resetcfg(struct brcmf_usbdev_info *devinfo) | 794 | brcmf_usb_resetcfg(struct brcmf_usbdev_info *devinfo) |
842 | { | 795 | { |
843 | struct bootrom_id_le id; | 796 | struct bootrom_id_le id; |
844 | u16 wait = 0, wait_time; | 797 | u32 loop_cnt; |
845 | 798 | ||
846 | brcmf_dbg(TRACE, "enter\n"); | 799 | brcmf_dbg(USB, "Enter\n"); |
847 | |||
848 | if (devinfo == NULL) | ||
849 | return -EINVAL; | ||
850 | 800 | ||
851 | /* Give dongle chance to boot */ | 801 | loop_cnt = 0; |
852 | wait_time = BRCMF_USB_DLIMAGE_SPINWAIT; | 802 | do { |
853 | while (wait < BRCMF_USB_DLIMAGE_LIMIT) { | 803 | mdelay(BRCMF_USB_RESET_GETVER_SPINWAIT); |
854 | mdelay(wait_time); | 804 | loop_cnt++; |
855 | wait += wait_time; | ||
856 | id.chip = cpu_to_le32(0xDEAD); /* Get the ID */ | 805 | id.chip = cpu_to_le32(0xDEAD); /* Get the ID */ |
857 | brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id, | 806 | brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id, sizeof(id)); |
858 | sizeof(struct bootrom_id_le)); | ||
859 | if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID)) | 807 | if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID)) |
860 | break; | 808 | break; |
861 | } | 809 | } while (loop_cnt < BRCMF_USB_RESET_GETVER_LOOP_CNT); |
862 | 810 | ||
863 | if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID)) { | 811 | if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID)) { |
864 | brcmf_dbg(INFO, "download done %d ms postboot chip 0x%x/rev 0x%x\n", | 812 | brcmf_dbg(USB, "postboot chip 0x%x/rev 0x%x\n", |
865 | wait, le32_to_cpu(id.chip), le32_to_cpu(id.chiprev)); | 813 | le32_to_cpu(id.chip), le32_to_cpu(id.chiprev)); |
866 | |||
867 | brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id, | ||
868 | sizeof(struct bootrom_id_le)); | ||
869 | 814 | ||
870 | /* XXX this wait may not be necessary */ | 815 | brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id, sizeof(id)); |
871 | mdelay(BRCMF_USB_RESETCFG_SPINWAIT); | ||
872 | return 0; | 816 | return 0; |
873 | } else { | 817 | } else { |
874 | brcmf_dbg(ERROR, "Cannot talk to Dongle. Firmware is not UP, %d ms\n", | 818 | brcmf_dbg(ERROR, "Cannot talk to Dongle. Firmware is not UP, %d ms\n", |
875 | wait); | 819 | BRCMF_USB_RESET_GETVER_SPINWAIT * loop_cnt); |
876 | return -EINVAL; | 820 | return -EINVAL; |
877 | } | 821 | } |
878 | } | 822 | } |
@@ -911,7 +855,8 @@ brcmf_usb_dl_writeimage(struct brcmf_usbdev_info *devinfo, u8 *fw, int fwlen) | |||
911 | struct rdl_state_le state; | 855 | struct rdl_state_le state; |
912 | u32 rdlstate, rdlbytes; | 856 | u32 rdlstate, rdlbytes; |
913 | int err = 0; | 857 | int err = 0; |
914 | brcmf_dbg(TRACE, "fw %p, len %d\n", fw, fwlen); | 858 | |
859 | brcmf_dbg(USB, "Enter, fw %p, len %d\n", fw, fwlen); | ||
915 | 860 | ||
916 | bulkchunk = kmalloc(RDL_CHUNK, GFP_ATOMIC); | 861 | bulkchunk = kmalloc(RDL_CHUNK, GFP_ATOMIC); |
917 | if (bulkchunk == NULL) { | 862 | if (bulkchunk == NULL) { |
@@ -986,7 +931,7 @@ brcmf_usb_dl_writeimage(struct brcmf_usbdev_info *devinfo, u8 *fw, int fwlen) | |||
986 | 931 | ||
987 | fail: | 932 | fail: |
988 | kfree(bulkchunk); | 933 | kfree(bulkchunk); |
989 | brcmf_dbg(TRACE, "err=%d\n", err); | 934 | brcmf_dbg(USB, "Exit, err=%d\n", err); |
990 | return err; | 935 | return err; |
991 | } | 936 | } |
992 | 937 | ||
@@ -994,7 +939,7 @@ static int brcmf_usb_dlstart(struct brcmf_usbdev_info *devinfo, u8 *fw, int len) | |||
994 | { | 939 | { |
995 | int err; | 940 | int err; |
996 | 941 | ||
997 | brcmf_dbg(TRACE, "enter\n"); | 942 | brcmf_dbg(USB, "Enter\n"); |
998 | 943 | ||
999 | if (devinfo == NULL) | 944 | if (devinfo == NULL) |
1000 | return -EINVAL; | 945 | return -EINVAL; |
@@ -1004,10 +949,10 @@ static int brcmf_usb_dlstart(struct brcmf_usbdev_info *devinfo, u8 *fw, int len) | |||
1004 | 949 | ||
1005 | err = brcmf_usb_dl_writeimage(devinfo, fw, len); | 950 | err = brcmf_usb_dl_writeimage(devinfo, fw, len); |
1006 | if (err == 0) | 951 | if (err == 0) |
1007 | devinfo->bus_pub.state = BCMFMAC_USB_STATE_DL_DONE; | 952 | devinfo->bus_pub.state = BRCMFMAC_USB_STATE_DL_DONE; |
1008 | else | 953 | else |
1009 | devinfo->bus_pub.state = BCMFMAC_USB_STATE_DL_PENDING; | 954 | devinfo->bus_pub.state = BRCMFMAC_USB_STATE_DL_FAIL; |
1010 | brcmf_dbg(TRACE, "exit: err=%d\n", err); | 955 | brcmf_dbg(USB, "Exit, err=%d\n", err); |
1011 | 956 | ||
1012 | return err; | 957 | return err; |
1013 | } | 958 | } |
@@ -1016,7 +961,7 @@ static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo) | |||
1016 | { | 961 | { |
1017 | struct rdl_state_le state; | 962 | struct rdl_state_le state; |
1018 | 963 | ||
1019 | brcmf_dbg(TRACE, "enter\n"); | 964 | brcmf_dbg(USB, "Enter\n"); |
1020 | if (!devinfo) | 965 | if (!devinfo) |
1021 | return -EINVAL; | 966 | return -EINVAL; |
1022 | 967 | ||
@@ -1039,7 +984,7 @@ static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo) | |||
1039 | brcmf_dbg(ERROR, "Dongle not runnable\n"); | 984 | brcmf_dbg(ERROR, "Dongle not runnable\n"); |
1040 | return -EINVAL; | 985 | return -EINVAL; |
1041 | } | 986 | } |
1042 | brcmf_dbg(TRACE, "exit\n"); | 987 | brcmf_dbg(USB, "Exit\n"); |
1043 | return 0; | 988 | return 0; |
1044 | } | 989 | } |
1045 | 990 | ||
@@ -1066,7 +1011,7 @@ brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo) | |||
1066 | int devid, chiprev; | 1011 | int devid, chiprev; |
1067 | int err; | 1012 | int err; |
1068 | 1013 | ||
1069 | brcmf_dbg(TRACE, "enter\n"); | 1014 | brcmf_dbg(USB, "Enter\n"); |
1070 | if (devinfo == NULL) | 1015 | if (devinfo == NULL) |
1071 | return -ENODEV; | 1016 | return -ENODEV; |
1072 | 1017 | ||
@@ -1094,7 +1039,7 @@ brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo) | |||
1094 | 1039 | ||
1095 | static void brcmf_usb_detach(struct brcmf_usbdev_info *devinfo) | 1040 | static void brcmf_usb_detach(struct brcmf_usbdev_info *devinfo) |
1096 | { | 1041 | { |
1097 | brcmf_dbg(TRACE, "devinfo %p\n", devinfo); | 1042 | brcmf_dbg(USB, "Enter, devinfo %p\n", devinfo); |
1098 | 1043 | ||
1099 | /* free the URBS */ | 1044 | /* free the URBS */ |
1100 | brcmf_usb_free_q(&devinfo->rx_freeq, false); | 1045 | brcmf_usb_free_q(&devinfo->rx_freeq, false); |
@@ -1129,6 +1074,7 @@ static int check_file(const u8 *headers) | |||
1129 | struct trx_header_le *trx; | 1074 | struct trx_header_le *trx; |
1130 | int actual_len = -1; | 1075 | int actual_len = -1; |
1131 | 1076 | ||
1077 | brcmf_dbg(USB, "Enter\n"); | ||
1132 | /* Extract trx header */ | 1078 | /* Extract trx header */ |
1133 | trx = (struct trx_header_le *) headers; | 1079 | trx = (struct trx_header_le *) headers; |
1134 | if (trx->magic != cpu_to_le32(TRX_MAGIC)) | 1080 | if (trx->magic != cpu_to_le32(TRX_MAGIC)) |
@@ -1150,6 +1096,7 @@ static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo) | |||
1150 | struct brcmf_usb_image *fw_image; | 1096 | struct brcmf_usb_image *fw_image; |
1151 | int err; | 1097 | int err; |
1152 | 1098 | ||
1099 | brcmf_dbg(USB, "Enter\n"); | ||
1153 | switch (devinfo->bus_pub.devid) { | 1100 | switch (devinfo->bus_pub.devid) { |
1154 | case 43143: | 1101 | case 43143: |
1155 | fwname = BRCMF_USB_43143_FW_NAME; | 1102 | fwname = BRCMF_USB_43143_FW_NAME; |
@@ -1166,7 +1113,7 @@ static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo) | |||
1166 | return -EINVAL; | 1113 | return -EINVAL; |
1167 | break; | 1114 | break; |
1168 | } | 1115 | } |
1169 | 1116 | brcmf_dbg(USB, "Loading FW %s\n", fwname); | |
1170 | list_for_each_entry(fw_image, &fw_image_list, list) { | 1117 | list_for_each_entry(fw_image, &fw_image_list, list) { |
1171 | if (fw_image->fwname == fwname) { | 1118 | if (fw_image->fwname == fwname) { |
1172 | devinfo->image = fw_image->image; | 1119 | devinfo->image = fw_image->image; |
@@ -1211,10 +1158,13 @@ static | |||
1211 | struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo, | 1158 | struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo, |
1212 | int nrxq, int ntxq) | 1159 | int nrxq, int ntxq) |
1213 | { | 1160 | { |
1161 | brcmf_dbg(USB, "Enter\n"); | ||
1162 | |||
1214 | devinfo->bus_pub.nrxq = nrxq; | 1163 | devinfo->bus_pub.nrxq = nrxq; |
1215 | devinfo->rx_low_watermark = nrxq / 2; | 1164 | devinfo->rx_low_watermark = nrxq / 2; |
1216 | devinfo->bus_pub.devinfo = devinfo; | 1165 | devinfo->bus_pub.devinfo = devinfo; |
1217 | devinfo->bus_pub.ntxq = ntxq; | 1166 | devinfo->bus_pub.ntxq = ntxq; |
1167 | devinfo->bus_pub.state = BRCMFMAC_USB_STATE_DOWN; | ||
1218 | 1168 | ||
1219 | /* flow control when too many tx urbs posted */ | 1169 | /* flow control when too many tx urbs posted */ |
1220 | devinfo->tx_low_watermark = ntxq / 4; | 1170 | devinfo->tx_low_watermark = ntxq / 4; |
@@ -1263,7 +1213,7 @@ struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo, | |||
1263 | if (!brcmf_usb_dlneeded(devinfo)) | 1213 | if (!brcmf_usb_dlneeded(devinfo)) |
1264 | return &devinfo->bus_pub; | 1214 | return &devinfo->bus_pub; |
1265 | 1215 | ||
1266 | brcmf_dbg(TRACE, "start fw downloading\n"); | 1216 | brcmf_dbg(USB, "Start fw downloading\n"); |
1267 | if (brcmf_usb_get_fw(devinfo)) | 1217 | if (brcmf_usb_get_fw(devinfo)) |
1268 | goto error; | 1218 | goto error; |
1269 | 1219 | ||
@@ -1278,14 +1228,14 @@ error: | |||
1278 | return NULL; | 1228 | return NULL; |
1279 | } | 1229 | } |
1280 | 1230 | ||
1281 | static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo, | 1231 | static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo) |
1282 | const char *desc, u32 bustype, u32 hdrlen) | ||
1283 | { | 1232 | { |
1284 | struct brcmf_bus *bus = NULL; | 1233 | struct brcmf_bus *bus = NULL; |
1285 | struct brcmf_usbdev *bus_pub = NULL; | 1234 | struct brcmf_usbdev *bus_pub = NULL; |
1286 | int ret; | 1235 | int ret; |
1287 | struct device *dev = devinfo->dev; | 1236 | struct device *dev = devinfo->dev; |
1288 | 1237 | ||
1238 | brcmf_dbg(USB, "Enter\n"); | ||
1289 | bus_pub = brcmf_usb_attach(devinfo, BRCMF_USB_NRXQ, BRCMF_USB_NTXQ); | 1239 | bus_pub = brcmf_usb_attach(devinfo, BRCMF_USB_NRXQ, BRCMF_USB_NTXQ); |
1290 | if (!bus_pub) | 1240 | if (!bus_pub) |
1291 | return -ENODEV; | 1241 | return -ENODEV; |
@@ -1302,14 +1252,13 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo, | |||
1302 | bus->brcmf_bus_stop = brcmf_usb_down; | 1252 | bus->brcmf_bus_stop = brcmf_usb_down; |
1303 | bus->brcmf_bus_txctl = brcmf_usb_tx_ctlpkt; | 1253 | bus->brcmf_bus_txctl = brcmf_usb_tx_ctlpkt; |
1304 | bus->brcmf_bus_rxctl = brcmf_usb_rx_ctlpkt; | 1254 | bus->brcmf_bus_rxctl = brcmf_usb_rx_ctlpkt; |
1305 | bus->type = bustype; | ||
1306 | bus->bus_priv.usb = bus_pub; | 1255 | bus->bus_priv.usb = bus_pub; |
1307 | dev_set_drvdata(dev, bus); | 1256 | dev_set_drvdata(dev, bus); |
1308 | 1257 | ||
1309 | /* Attach to the common driver interface */ | 1258 | /* Attach to the common driver interface */ |
1310 | ret = brcmf_attach(hdrlen, dev); | 1259 | ret = brcmf_attach(0, dev); |
1311 | if (ret) { | 1260 | if (ret) { |
1312 | brcmf_dbg(ERROR, "dhd_attach failed\n"); | 1261 | brcmf_dbg(ERROR, "brcmf_attach failed\n"); |
1313 | goto fail; | 1262 | goto fail; |
1314 | } | 1263 | } |
1315 | 1264 | ||
@@ -1333,7 +1282,7 @@ brcmf_usb_disconnect_cb(struct brcmf_usbdev_info *devinfo) | |||
1333 | { | 1282 | { |
1334 | if (!devinfo) | 1283 | if (!devinfo) |
1335 | return; | 1284 | return; |
1336 | brcmf_dbg(TRACE, "enter: bus_pub %p\n", devinfo); | 1285 | brcmf_dbg(USB, "Enter, bus_pub %p\n", devinfo); |
1337 | 1286 | ||
1338 | brcmf_detach(devinfo->dev); | 1287 | brcmf_detach(devinfo->dev); |
1339 | kfree(devinfo->bus_pub.bus); | 1288 | kfree(devinfo->bus_pub.bus); |
@@ -1351,7 +1300,7 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1351 | u8 endpoint_num; | 1300 | u8 endpoint_num; |
1352 | struct brcmf_usbdev_info *devinfo; | 1301 | struct brcmf_usbdev_info *devinfo; |
1353 | 1302 | ||
1354 | brcmf_dbg(TRACE, "enter\n"); | 1303 | brcmf_dbg(USB, "Enter\n"); |
1355 | 1304 | ||
1356 | devinfo = kzalloc(sizeof(*devinfo), GFP_ATOMIC); | 1305 | devinfo = kzalloc(sizeof(*devinfo), GFP_ATOMIC); |
1357 | if (devinfo == NULL) | 1306 | if (devinfo == NULL) |
@@ -1452,11 +1401,11 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1452 | devinfo->interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval; | 1401 | devinfo->interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval; |
1453 | 1402 | ||
1454 | if (usb->speed == USB_SPEED_HIGH) | 1403 | if (usb->speed == USB_SPEED_HIGH) |
1455 | brcmf_dbg(INFO, "Broadcom high speed USB wireless device detected\n"); | 1404 | brcmf_dbg(USB, "Broadcom high speed USB wireless device detected\n"); |
1456 | else | 1405 | else |
1457 | brcmf_dbg(INFO, "Broadcom full speed USB wireless device detected\n"); | 1406 | brcmf_dbg(USB, "Broadcom full speed USB wireless device detected\n"); |
1458 | 1407 | ||
1459 | ret = brcmf_usb_probe_cb(devinfo, "", USB_BUS, 0); | 1408 | ret = brcmf_usb_probe_cb(devinfo); |
1460 | if (ret) | 1409 | if (ret) |
1461 | goto fail; | 1410 | goto fail; |
1462 | 1411 | ||
@@ -1476,40 +1425,55 @@ brcmf_usb_disconnect(struct usb_interface *intf) | |||
1476 | { | 1425 | { |
1477 | struct brcmf_usbdev_info *devinfo; | 1426 | struct brcmf_usbdev_info *devinfo; |
1478 | 1427 | ||
1479 | brcmf_dbg(TRACE, "enter\n"); | 1428 | brcmf_dbg(USB, "Enter\n"); |
1480 | devinfo = (struct brcmf_usbdev_info *)usb_get_intfdata(intf); | 1429 | devinfo = (struct brcmf_usbdev_info *)usb_get_intfdata(intf); |
1481 | brcmf_usb_disconnect_cb(devinfo); | 1430 | brcmf_usb_disconnect_cb(devinfo); |
1482 | kfree(devinfo); | 1431 | kfree(devinfo); |
1432 | brcmf_dbg(USB, "Exit\n"); | ||
1483 | } | 1433 | } |
1484 | 1434 | ||
1485 | /* | 1435 | /* |
1486 | * only need to signal the bus being down and update the suspend state. | 1436 | * only need to signal the bus being down and update the state. |
1487 | */ | 1437 | */ |
1488 | static int brcmf_usb_suspend(struct usb_interface *intf, pm_message_t state) | 1438 | static int brcmf_usb_suspend(struct usb_interface *intf, pm_message_t state) |
1489 | { | 1439 | { |
1490 | struct usb_device *usb = interface_to_usbdev(intf); | 1440 | struct usb_device *usb = interface_to_usbdev(intf); |
1491 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); | 1441 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); |
1492 | 1442 | ||
1493 | brcmf_dbg(TRACE, "enter\n"); | 1443 | brcmf_dbg(USB, "Enter\n"); |
1494 | devinfo->bus_pub.state = BCMFMAC_USB_STATE_DOWN; | 1444 | devinfo->bus_pub.state = BRCMFMAC_USB_STATE_SLEEP; |
1495 | devinfo->suspend_state = USBOS_SUSPEND_STATE_SUSPENDED; | 1445 | brcmf_detach(&usb->dev); |
1496 | return 0; | 1446 | return 0; |
1497 | } | 1447 | } |
1498 | 1448 | ||
1499 | /* | 1449 | /* |
1500 | * mark suspend state active and crank up the bus. | 1450 | * (re-) start the bus. |
1501 | */ | 1451 | */ |
1502 | static int brcmf_usb_resume(struct usb_interface *intf) | 1452 | static int brcmf_usb_resume(struct usb_interface *intf) |
1503 | { | 1453 | { |
1504 | struct usb_device *usb = interface_to_usbdev(intf); | 1454 | struct usb_device *usb = interface_to_usbdev(intf); |
1505 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); | 1455 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); |
1506 | 1456 | ||
1507 | brcmf_dbg(TRACE, "enter\n"); | 1457 | brcmf_dbg(USB, "Enter\n"); |
1508 | devinfo->suspend_state = USBOS_SUSPEND_STATE_DEVICE_ACTIVE; | 1458 | if (!brcmf_attach(0, devinfo->dev)) |
1509 | brcmf_bus_start(&usb->dev); | 1459 | return brcmf_bus_start(&usb->dev); |
1460 | |||
1510 | return 0; | 1461 | return 0; |
1511 | } | 1462 | } |
1512 | 1463 | ||
1464 | static int brcmf_usb_reset_resume(struct usb_interface *intf) | ||
1465 | { | ||
1466 | struct usb_device *usb = interface_to_usbdev(intf); | ||
1467 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); | ||
1468 | |||
1469 | brcmf_dbg(USB, "Enter\n"); | ||
1470 | |||
1471 | if (!brcmf_usb_fw_download(devinfo)) | ||
1472 | return brcmf_usb_resume(intf); | ||
1473 | |||
1474 | return -EIO; | ||
1475 | } | ||
1476 | |||
1513 | #define BRCMF_USB_VENDOR_ID_BROADCOM 0x0a5c | 1477 | #define BRCMF_USB_VENDOR_ID_BROADCOM 0x0a5c |
1514 | #define BRCMF_USB_DEVICE_ID_43143 0xbd1e | 1478 | #define BRCMF_USB_DEVICE_ID_43143 0xbd1e |
1515 | #define BRCMF_USB_DEVICE_ID_43236 0xbd17 | 1479 | #define BRCMF_USB_DEVICE_ID_43236 0xbd17 |
@@ -1529,7 +1493,6 @@ MODULE_FIRMWARE(BRCMF_USB_43143_FW_NAME); | |||
1529 | MODULE_FIRMWARE(BRCMF_USB_43236_FW_NAME); | 1493 | MODULE_FIRMWARE(BRCMF_USB_43236_FW_NAME); |
1530 | MODULE_FIRMWARE(BRCMF_USB_43242_FW_NAME); | 1494 | MODULE_FIRMWARE(BRCMF_USB_43242_FW_NAME); |
1531 | 1495 | ||
1532 | /* TODO: suspend and resume entries */ | ||
1533 | static struct usb_driver brcmf_usbdrvr = { | 1496 | static struct usb_driver brcmf_usbdrvr = { |
1534 | .name = KBUILD_MODNAME, | 1497 | .name = KBUILD_MODNAME, |
1535 | .probe = brcmf_usb_probe, | 1498 | .probe = brcmf_usb_probe, |
@@ -1537,6 +1500,7 @@ static struct usb_driver brcmf_usbdrvr = { | |||
1537 | .id_table = brcmf_usb_devid_table, | 1500 | .id_table = brcmf_usb_devid_table, |
1538 | .suspend = brcmf_usb_suspend, | 1501 | .suspend = brcmf_usb_suspend, |
1539 | .resume = brcmf_usb_resume, | 1502 | .resume = brcmf_usb_resume, |
1503 | .reset_resume = brcmf_usb_reset_resume, | ||
1540 | .supports_autosuspend = 1, | 1504 | .supports_autosuspend = 1, |
1541 | .disable_hub_initiated_lpm = 1, | 1505 | .disable_hub_initiated_lpm = 1, |
1542 | }; | 1506 | }; |
@@ -1554,12 +1518,14 @@ static void brcmf_release_fw(struct list_head *q) | |||
1554 | 1518 | ||
1555 | void brcmf_usb_exit(void) | 1519 | void brcmf_usb_exit(void) |
1556 | { | 1520 | { |
1521 | brcmf_dbg(USB, "Enter\n"); | ||
1557 | usb_deregister(&brcmf_usbdrvr); | 1522 | usb_deregister(&brcmf_usbdrvr); |
1558 | brcmf_release_fw(&fw_image_list); | 1523 | brcmf_release_fw(&fw_image_list); |
1559 | } | 1524 | } |
1560 | 1525 | ||
1561 | void brcmf_usb_init(void) | 1526 | void brcmf_usb_init(void) |
1562 | { | 1527 | { |
1528 | brcmf_dbg(USB, "Enter\n"); | ||
1563 | INIT_LIST_HEAD(&fw_image_list); | 1529 | INIT_LIST_HEAD(&fw_image_list); |
1564 | usb_register(&brcmf_usbdrvr); | 1530 | usb_register(&brcmf_usbdrvr); |
1565 | } | 1531 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.h b/drivers/net/wireless/brcm80211/brcmfmac/usb.h index acfa5e89872f..f483a8c9945b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.h | |||
@@ -17,19 +17,11 @@ | |||
17 | #define BRCMFMAC_USB_H | 17 | #define BRCMFMAC_USB_H |
18 | 18 | ||
19 | enum brcmf_usb_state { | 19 | enum brcmf_usb_state { |
20 | BCMFMAC_USB_STATE_DL_PENDING, | 20 | BRCMFMAC_USB_STATE_DOWN, |
21 | BCMFMAC_USB_STATE_DL_DONE, | 21 | BRCMFMAC_USB_STATE_DL_FAIL, |
22 | BCMFMAC_USB_STATE_UP, | 22 | BRCMFMAC_USB_STATE_DL_DONE, |
23 | BCMFMAC_USB_STATE_DOWN, | 23 | BRCMFMAC_USB_STATE_UP, |
24 | BCMFMAC_USB_STATE_PNP_FWDL, | 24 | BRCMFMAC_USB_STATE_SLEEP |
25 | BCMFMAC_USB_STATE_DISCONNECT, | ||
26 | BCMFMAC_USB_STATE_SLEEP | ||
27 | }; | ||
28 | |||
29 | enum brcmf_usb_pnp_state { | ||
30 | BCMFMAC_USB_PNP_DISCONNECT, | ||
31 | BCMFMAC_USB_PNP_SLEEP, | ||
32 | BCMFMAC_USB_PNP_RESUME, | ||
33 | }; | 25 | }; |
34 | 26 | ||
35 | struct brcmf_stats { | 27 | struct brcmf_stats { |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 6d554249394f..2044fdb55558 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | |||
@@ -19,14 +19,7 @@ | |||
19 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 19 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
20 | 20 | ||
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/if_arp.h> | ||
23 | #include <linux/sched.h> | ||
24 | #include <linux/kthread.h> | ||
25 | #include <linux/netdevice.h> | ||
26 | #include <linux/bitops.h> | ||
27 | #include <linux/etherdevice.h> | 22 | #include <linux/etherdevice.h> |
28 | #include <linux/ieee80211.h> | ||
29 | #include <linux/uaccess.h> | ||
30 | #include <net/cfg80211.h> | 23 | #include <net/cfg80211.h> |
31 | #include <net/netlink.h> | 24 | #include <net/netlink.h> |
32 | 25 | ||
@@ -486,13 +479,6 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, | |||
486 | 479 | ||
487 | if (ap) { | 480 | if (ap) { |
488 | set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state); | 481 | set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state); |
489 | if (!cfg->ap_info) | ||
490 | cfg->ap_info = kzalloc(sizeof(*cfg->ap_info), | ||
491 | GFP_KERNEL); | ||
492 | if (!cfg->ap_info) { | ||
493 | err = -ENOMEM; | ||
494 | goto done; | ||
495 | } | ||
496 | WL_INFO("IF Type = AP\n"); | 482 | WL_INFO("IF Type = AP\n"); |
497 | } else { | 483 | } else { |
498 | err = brcmf_fil_cmd_int_set(netdev_priv(ndev), | 484 | err = brcmf_fil_cmd_int_set(netdev_priv(ndev), |
@@ -529,185 +515,6 @@ static void brcmf_set_mpc(struct net_device *ndev, int mpc) | |||
529 | } | 515 | } |
530 | } | 516 | } |
531 | 517 | ||
532 | static void brcmf_iscan_prep(struct brcmf_scan_params_le *params_le, | ||
533 | struct brcmf_ssid *ssid) | ||
534 | { | ||
535 | memset(params_le->bssid, 0xFF, ETH_ALEN); | ||
536 | params_le->bss_type = DOT11_BSSTYPE_ANY; | ||
537 | params_le->scan_type = 0; | ||
538 | params_le->channel_num = 0; | ||
539 | params_le->nprobes = cpu_to_le32(-1); | ||
540 | params_le->active_time = cpu_to_le32(-1); | ||
541 | params_le->passive_time = cpu_to_le32(-1); | ||
542 | params_le->home_time = cpu_to_le32(-1); | ||
543 | if (ssid && ssid->SSID_len) { | ||
544 | params_le->ssid_le.SSID_len = cpu_to_le32(ssid->SSID_len); | ||
545 | memcpy(¶ms_le->ssid_le.SSID, ssid->SSID, ssid->SSID_len); | ||
546 | } | ||
547 | } | ||
548 | |||
549 | static s32 | ||
550 | brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan, | ||
551 | struct brcmf_ssid *ssid, u16 action) | ||
552 | { | ||
553 | s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE + | ||
554 | offsetof(struct brcmf_iscan_params_le, params_le); | ||
555 | struct brcmf_iscan_params_le *params; | ||
556 | s32 err = 0; | ||
557 | |||
558 | if (ssid && ssid->SSID_len) | ||
559 | params_size += sizeof(struct brcmf_ssid); | ||
560 | params = kzalloc(params_size, GFP_KERNEL); | ||
561 | if (!params) | ||
562 | return -ENOMEM; | ||
563 | BUG_ON(params_size >= BRCMF_DCMD_SMLEN); | ||
564 | |||
565 | brcmf_iscan_prep(¶ms->params_le, ssid); | ||
566 | |||
567 | params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION); | ||
568 | params->action = cpu_to_le16(action); | ||
569 | params->scan_duration = cpu_to_le16(0); | ||
570 | |||
571 | err = brcmf_fil_iovar_data_set(netdev_priv(iscan->ndev), "iscan", | ||
572 | params, params_size); | ||
573 | if (err) { | ||
574 | if (err == -EBUSY) | ||
575 | WL_INFO("system busy : iscan canceled\n"); | ||
576 | else | ||
577 | WL_ERR("error (%d)\n", err); | ||
578 | } | ||
579 | |||
580 | kfree(params); | ||
581 | return err; | ||
582 | } | ||
583 | |||
584 | static s32 brcmf_do_iscan(struct brcmf_cfg80211_info *cfg) | ||
585 | { | ||
586 | struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg); | ||
587 | struct net_device *ndev = cfg_to_ndev(cfg); | ||
588 | struct brcmf_ssid ssid; | ||
589 | u32 passive_scan; | ||
590 | s32 err = 0; | ||
591 | |||
592 | /* Broadcast scan by default */ | ||
593 | memset(&ssid, 0, sizeof(ssid)); | ||
594 | |||
595 | iscan->state = WL_ISCAN_STATE_SCANING; | ||
596 | |||
597 | passive_scan = cfg->active_scan ? 0 : 1; | ||
598 | err = brcmf_fil_cmd_int_set(netdev_priv(ndev), | ||
599 | BRCMF_C_SET_PASSIVE_SCAN, passive_scan); | ||
600 | if (err) { | ||
601 | WL_ERR("error (%d)\n", err); | ||
602 | return err; | ||
603 | } | ||
604 | brcmf_set_mpc(ndev, 0); | ||
605 | cfg->iscan_kickstart = true; | ||
606 | err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START); | ||
607 | if (err) { | ||
608 | brcmf_set_mpc(ndev, 1); | ||
609 | cfg->iscan_kickstart = false; | ||
610 | return err; | ||
611 | } | ||
612 | mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000); | ||
613 | iscan->timer_on = 1; | ||
614 | return err; | ||
615 | } | ||
616 | |||
617 | static s32 | ||
618 | brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev, | ||
619 | struct cfg80211_scan_request *request, | ||
620 | struct cfg80211_ssid *this_ssid) | ||
621 | { | ||
622 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
623 | struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); | ||
624 | struct cfg80211_ssid *ssids; | ||
625 | struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int; | ||
626 | u32 passive_scan; | ||
627 | bool iscan_req; | ||
628 | bool spec_scan; | ||
629 | s32 err = 0; | ||
630 | u32 SSID_len; | ||
631 | |||
632 | if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { | ||
633 | WL_ERR("Scanning already: status (%lu)\n", cfg->scan_status); | ||
634 | return -EAGAIN; | ||
635 | } | ||
636 | if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) { | ||
637 | WL_ERR("Scanning being aborted: status (%lu)\n", | ||
638 | cfg->scan_status); | ||
639 | return -EAGAIN; | ||
640 | } | ||
641 | if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) { | ||
642 | WL_ERR("Connecting: status (%lu)\n", ifp->vif->sme_state); | ||
643 | return -EAGAIN; | ||
644 | } | ||
645 | |||
646 | iscan_req = false; | ||
647 | spec_scan = false; | ||
648 | if (request) { | ||
649 | /* scan bss */ | ||
650 | ssids = request->ssids; | ||
651 | if (cfg->iscan_on && (!ssids || !ssids->ssid_len)) | ||
652 | iscan_req = true; | ||
653 | } else { | ||
654 | /* scan in ibss */ | ||
655 | /* we don't do iscan in ibss */ | ||
656 | ssids = this_ssid; | ||
657 | } | ||
658 | |||
659 | cfg->scan_request = request; | ||
660 | set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); | ||
661 | if (iscan_req) { | ||
662 | err = brcmf_do_iscan(cfg); | ||
663 | if (!err) | ||
664 | return err; | ||
665 | else | ||
666 | goto scan_out; | ||
667 | } else { | ||
668 | WL_SCAN("ssid \"%s\", ssid_len (%d)\n", | ||
669 | ssids->ssid, ssids->ssid_len); | ||
670 | memset(&sr->ssid_le, 0, sizeof(sr->ssid_le)); | ||
671 | SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len); | ||
672 | sr->ssid_le.SSID_len = cpu_to_le32(0); | ||
673 | if (SSID_len) { | ||
674 | memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len); | ||
675 | sr->ssid_le.SSID_len = cpu_to_le32(SSID_len); | ||
676 | spec_scan = true; | ||
677 | } else { | ||
678 | WL_SCAN("Broadcast scan\n"); | ||
679 | } | ||
680 | |||
681 | passive_scan = cfg->active_scan ? 0 : 1; | ||
682 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN, | ||
683 | passive_scan); | ||
684 | if (err) { | ||
685 | WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err); | ||
686 | goto scan_out; | ||
687 | } | ||
688 | brcmf_set_mpc(ndev, 0); | ||
689 | err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN, | ||
690 | &sr->ssid_le, sizeof(sr->ssid_le)); | ||
691 | if (err) { | ||
692 | if (err == -EBUSY) | ||
693 | WL_INFO("system busy : scan for \"%s\" " | ||
694 | "canceled\n", sr->ssid_le.SSID); | ||
695 | else | ||
696 | WL_ERR("WLC_SCAN error (%d)\n", err); | ||
697 | |||
698 | brcmf_set_mpc(ndev, 1); | ||
699 | goto scan_out; | ||
700 | } | ||
701 | } | ||
702 | |||
703 | return 0; | ||
704 | |||
705 | scan_out: | ||
706 | clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); | ||
707 | cfg->scan_request = NULL; | ||
708 | return err; | ||
709 | } | ||
710 | |||
711 | static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le, | 518 | static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le, |
712 | struct cfg80211_scan_request *request) | 519 | struct cfg80211_scan_request *request) |
713 | { | 520 | { |
@@ -931,7 +738,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev, | |||
931 | struct brcmf_if *ifp = netdev_priv(ndev); | 738 | struct brcmf_if *ifp = netdev_priv(ndev); |
932 | struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); | 739 | struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); |
933 | struct cfg80211_ssid *ssids; | 740 | struct cfg80211_ssid *ssids; |
934 | struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int; | 741 | struct brcmf_cfg80211_scan_req *sr = &cfg->scan_req_int; |
935 | u32 passive_scan; | 742 | u32 passive_scan; |
936 | bool escan_req; | 743 | bool escan_req; |
937 | bool spec_scan; | 744 | bool spec_scan; |
@@ -973,9 +780,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev, | |||
973 | set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); | 780 | set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); |
974 | if (escan_req) { | 781 | if (escan_req) { |
975 | err = brcmf_do_escan(cfg, wiphy, ndev, request); | 782 | err = brcmf_do_escan(cfg, wiphy, ndev, request); |
976 | if (!err) | 783 | if (err) |
977 | return err; | ||
978 | else | ||
979 | goto scan_out; | 784 | goto scan_out; |
980 | } else { | 785 | } else { |
981 | WL_SCAN("ssid \"%s\", ssid_len (%d)\n", | 786 | WL_SCAN("ssid \"%s\", ssid_len (%d)\n", |
@@ -1027,7 +832,6 @@ static s32 | |||
1027 | brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) | 832 | brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) |
1028 | { | 833 | { |
1029 | struct net_device *ndev = request->wdev->netdev; | 834 | struct net_device *ndev = request->wdev->netdev; |
1030 | struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); | ||
1031 | s32 err = 0; | 835 | s32 err = 0; |
1032 | 836 | ||
1033 | WL_TRACE("Enter\n"); | 837 | WL_TRACE("Enter\n"); |
@@ -1036,10 +840,7 @@ brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) | |||
1036 | struct brcmf_cfg80211_vif, wdev))) | 840 | struct brcmf_cfg80211_vif, wdev))) |
1037 | return -EIO; | 841 | return -EIO; |
1038 | 842 | ||
1039 | if (cfg->iscan_on) | 843 | err = brcmf_cfg80211_escan(wiphy, ndev, request, NULL); |
1040 | err = brcmf_cfg80211_iscan(wiphy, ndev, request, NULL); | ||
1041 | else if (cfg->escan_on) | ||
1042 | err = brcmf_cfg80211_escan(wiphy, ndev, request, NULL); | ||
1043 | 844 | ||
1044 | if (err) | 845 | if (err) |
1045 | WL_ERR("scan error (%d)\n", err); | 846 | WL_ERR("scan error (%d)\n", err); |
@@ -1075,7 +876,7 @@ static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold) | |||
1075 | static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l) | 876 | static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l) |
1076 | { | 877 | { |
1077 | s32 err = 0; | 878 | s32 err = 0; |
1078 | u32 cmd = (l ? BRCM_SET_LRL : BRCM_SET_SRL); | 879 | u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL); |
1079 | 880 | ||
1080 | err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry); | 881 | err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry); |
1081 | if (err) { | 882 | if (err) { |
@@ -1212,8 +1013,8 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, | |||
1212 | else | 1013 | else |
1213 | WL_CONN("No BSSID specified\n"); | 1014 | WL_CONN("No BSSID specified\n"); |
1214 | 1015 | ||
1215 | if (params->channel) | 1016 | if (params->chandef.chan) |
1216 | WL_CONN("channel: %d\n", params->channel->center_freq); | 1017 | WL_CONN("channel: %d\n", params->chandef.chan->center_freq); |
1217 | else | 1018 | else |
1218 | WL_CONN("no channel specified\n"); | 1019 | WL_CONN("no channel specified\n"); |
1219 | 1020 | ||
@@ -1258,7 +1059,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, | |||
1258 | else | 1059 | else |
1259 | bcnprd = 100; | 1060 | bcnprd = 100; |
1260 | 1061 | ||
1261 | err = brcmf_fil_cmd_int_set(ifp, BRCM_SET_BCNPRD, bcnprd); | 1062 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd); |
1262 | if (err) { | 1063 | if (err) { |
1263 | WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err); | 1064 | WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err); |
1264 | goto done; | 1065 | goto done; |
@@ -1286,12 +1087,12 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, | |||
1286 | } | 1087 | } |
1287 | 1088 | ||
1288 | /* Channel */ | 1089 | /* Channel */ |
1289 | if (params->channel) { | 1090 | if (params->chandef.chan) { |
1290 | u32 target_channel; | 1091 | u32 target_channel; |
1291 | 1092 | ||
1292 | cfg->channel = | 1093 | cfg->channel = |
1293 | ieee80211_frequency_to_channel( | 1094 | ieee80211_frequency_to_channel( |
1294 | params->channel->center_freq); | 1095 | params->chandef.chan->center_freq); |
1295 | if (params->channel_fixed) { | 1096 | if (params->channel_fixed) { |
1296 | /* adding chanspec */ | 1097 | /* adding chanspec */ |
1297 | brcmf_ch_to_chanspec(cfg->channel, | 1098 | brcmf_ch_to_chanspec(cfg->channel, |
@@ -1300,7 +1101,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, | |||
1300 | 1101 | ||
1301 | /* set channel for starter */ | 1102 | /* set channel for starter */ |
1302 | target_channel = cfg->channel; | 1103 | target_channel = cfg->channel; |
1303 | err = brcmf_fil_cmd_int_set(ifp, BRCM_SET_CHANNEL, | 1104 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL, |
1304 | target_channel); | 1105 | target_channel); |
1305 | if (err) { | 1106 | if (err) { |
1306 | WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err); | 1107 | WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err); |
@@ -1721,7 +1522,7 @@ brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, | |||
1721 | } | 1522 | } |
1722 | 1523 | ||
1723 | static s32 | 1524 | static s32 |
1724 | brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, | 1525 | brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, |
1725 | enum nl80211_tx_power_setting type, s32 mbm) | 1526 | enum nl80211_tx_power_setting type, s32 mbm) |
1726 | { | 1527 | { |
1727 | 1528 | ||
@@ -1770,7 +1571,9 @@ done: | |||
1770 | return err; | 1571 | return err; |
1771 | } | 1572 | } |
1772 | 1573 | ||
1773 | static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm) | 1574 | static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, |
1575 | struct wireless_dev *wdev, | ||
1576 | s32 *dbm) | ||
1774 | { | 1577 | { |
1775 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | 1578 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |
1776 | struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); | 1579 | struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); |
@@ -2014,6 +1817,12 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, | |||
2014 | if (!check_vif_up(ifp->vif)) | 1817 | if (!check_vif_up(ifp->vif)) |
2015 | return -EIO; | 1818 | return -EIO; |
2016 | 1819 | ||
1820 | if (key_idx >= DOT11_MAX_DEFAULT_KEYS) { | ||
1821 | /* we ignore this key index in this case */ | ||
1822 | WL_ERR("invalid key index (%d)\n", key_idx); | ||
1823 | return -EINVAL; | ||
1824 | } | ||
1825 | |||
2017 | memset(&key, 0, sizeof(key)); | 1826 | memset(&key, 0, sizeof(key)); |
2018 | 1827 | ||
2019 | key.index = (u32) key_idx; | 1828 | key.index = (u32) key_idx; |
@@ -2024,15 +1833,6 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, | |||
2024 | 1833 | ||
2025 | /* Set the new key/index */ | 1834 | /* Set the new key/index */ |
2026 | err = send_key_to_dongle(ndev, &key); | 1835 | err = send_key_to_dongle(ndev, &key); |
2027 | if (err) { | ||
2028 | if (err == -EINVAL) { | ||
2029 | if (key.index >= DOT11_MAX_DEFAULT_KEYS) | ||
2030 | /* we ignore this key index in this case */ | ||
2031 | WL_ERR("invalid key index (%d)\n", key_idx); | ||
2032 | } | ||
2033 | /* Ignore this error, may happen during DISASSOC */ | ||
2034 | err = -EAGAIN; | ||
2035 | } | ||
2036 | 1836 | ||
2037 | WL_TRACE("Exit\n"); | 1837 | WL_TRACE("Exit\n"); |
2038 | return err; | 1838 | return err; |
@@ -2239,7 +2039,7 @@ brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev, | |||
2239 | 2039 | ||
2240 | /* addr param is always NULL. ignore it */ | 2040 | /* addr param is always NULL. ignore it */ |
2241 | /* Get current rateset */ | 2041 | /* Get current rateset */ |
2242 | err = brcmf_fil_cmd_data_get(ifp, BRCM_GET_CURR_RATESET, | 2042 | err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_CURR_RATESET, |
2243 | &rateset_le, sizeof(rateset_le)); | 2043 | &rateset_le, sizeof(rateset_le)); |
2244 | if (err) { | 2044 | if (err) { |
2245 | WL_ERR("could not get current rateset (%d)\n", err); | 2045 | WL_ERR("could not get current rateset (%d)\n", err); |
@@ -2354,13 +2154,14 @@ static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg) | |||
2354 | int i; | 2154 | int i; |
2355 | 2155 | ||
2356 | bss_list = cfg->bss_list; | 2156 | bss_list = cfg->bss_list; |
2357 | if (bss_list->version != BRCMF_BSS_INFO_VERSION) { | 2157 | if (bss_list->count != 0 && |
2158 | bss_list->version != BRCMF_BSS_INFO_VERSION) { | ||
2358 | WL_ERR("Version %d != WL_BSS_INFO_VERSION\n", | 2159 | WL_ERR("Version %d != WL_BSS_INFO_VERSION\n", |
2359 | bss_list->version); | 2160 | bss_list->version); |
2360 | return -EOPNOTSUPP; | 2161 | return -EOPNOTSUPP; |
2361 | } | 2162 | } |
2362 | WL_SCAN("scanned AP count (%d)\n", bss_list->count); | 2163 | WL_SCAN("scanned AP count (%d)\n", bss_list->count); |
2363 | for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) { | 2164 | for (i = 0; i < bss_list->count; i++) { |
2364 | bi = next_bss_le(bss_list, bi); | 2165 | bi = next_bss_le(bss_list, bi); |
2365 | err = brcmf_inform_single_bss(cfg, bi); | 2166 | err = brcmf_inform_single_bss(cfg, bi); |
2366 | if (err) | 2167 | if (err) |
@@ -2582,33 +2383,10 @@ update_bss_info_out: | |||
2582 | 2383 | ||
2583 | static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg) | 2384 | static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg) |
2584 | { | 2385 | { |
2585 | struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg); | ||
2586 | struct escan_info *escan = &cfg->escan_info; | 2386 | struct escan_info *escan = &cfg->escan_info; |
2587 | struct brcmf_ssid ssid; | ||
2588 | 2387 | ||
2589 | set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status); | 2388 | set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status); |
2590 | if (cfg->iscan_on) { | 2389 | if (cfg->scan_request) { |
2591 | iscan->state = WL_ISCAN_STATE_IDLE; | ||
2592 | |||
2593 | if (iscan->timer_on) { | ||
2594 | del_timer_sync(&iscan->timer); | ||
2595 | iscan->timer_on = 0; | ||
2596 | } | ||
2597 | |||
2598 | cancel_work_sync(&iscan->work); | ||
2599 | |||
2600 | /* Abort iscan running in FW */ | ||
2601 | memset(&ssid, 0, sizeof(ssid)); | ||
2602 | brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT); | ||
2603 | |||
2604 | if (cfg->scan_request) { | ||
2605 | /* Indidate scan abort to cfg80211 layer */ | ||
2606 | WL_INFO("Terminating scan in progress\n"); | ||
2607 | cfg80211_scan_done(cfg->scan_request, true); | ||
2608 | cfg->scan_request = NULL; | ||
2609 | } | ||
2610 | } | ||
2611 | if (cfg->escan_on && cfg->scan_request) { | ||
2612 | escan->escan_state = WL_ESCAN_STATE_IDLE; | 2390 | escan->escan_state = WL_ESCAN_STATE_IDLE; |
2613 | brcmf_notify_escan_complete(cfg, escan->ndev, true, true); | 2391 | brcmf_notify_escan_complete(cfg, escan->ndev, true, true); |
2614 | } | 2392 | } |
@@ -2616,198 +2394,6 @@ static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg) | |||
2616 | clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status); | 2394 | clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status); |
2617 | } | 2395 | } |
2618 | 2396 | ||
2619 | static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan, | ||
2620 | bool aborted) | ||
2621 | { | ||
2622 | struct brcmf_cfg80211_info *cfg = iscan_to_cfg(iscan); | ||
2623 | struct net_device *ndev = cfg_to_ndev(cfg); | ||
2624 | |||
2625 | if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { | ||
2626 | WL_ERR("Scan complete while device not scanning\n"); | ||
2627 | return; | ||
2628 | } | ||
2629 | if (cfg->scan_request) { | ||
2630 | WL_SCAN("ISCAN Completed scan: %s\n", | ||
2631 | aborted ? "Aborted" : "Done"); | ||
2632 | cfg80211_scan_done(cfg->scan_request, aborted); | ||
2633 | brcmf_set_mpc(ndev, 1); | ||
2634 | cfg->scan_request = NULL; | ||
2635 | } | ||
2636 | cfg->iscan_kickstart = false; | ||
2637 | } | ||
2638 | |||
2639 | static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan) | ||
2640 | { | ||
2641 | if (iscan->state != WL_ISCAN_STATE_IDLE) { | ||
2642 | WL_SCAN("wake up iscan\n"); | ||
2643 | schedule_work(&iscan->work); | ||
2644 | return 0; | ||
2645 | } | ||
2646 | |||
2647 | return -EIO; | ||
2648 | } | ||
2649 | |||
2650 | static s32 | ||
2651 | brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status, | ||
2652 | struct brcmf_scan_results **bss_list) | ||
2653 | { | ||
2654 | struct brcmf_scan_results *results; | ||
2655 | struct brcmf_scan_results_le *results_le; | ||
2656 | struct brcmf_iscan_results *list_buf; | ||
2657 | s32 err = 0; | ||
2658 | |||
2659 | memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX); | ||
2660 | list_buf = (struct brcmf_iscan_results *)iscan->scan_buf; | ||
2661 | results = &list_buf->results; | ||
2662 | results_le = &list_buf->results_le; | ||
2663 | results_le->buflen = cpu_to_le32(sizeof(iscan->scan_buf)); | ||
2664 | results_le->version = 0; | ||
2665 | results_le->count = 0; | ||
2666 | |||
2667 | err = brcmf_fil_iovar_data_get(netdev_priv(iscan->ndev), "iscanresults", | ||
2668 | iscan->scan_buf, | ||
2669 | sizeof(iscan->scan_buf)); | ||
2670 | if (err) { | ||
2671 | WL_ERR("error (%d)\n", err); | ||
2672 | return err; | ||
2673 | } | ||
2674 | results->buflen = le32_to_cpu(results_le->buflen); | ||
2675 | results->version = le32_to_cpu(results_le->version); | ||
2676 | results->count = le32_to_cpu(results_le->count); | ||
2677 | WL_SCAN("results->count = %d\n", results_le->count); | ||
2678 | WL_SCAN("results->buflen = %d\n", results_le->buflen); | ||
2679 | *status = le32_to_cpu(list_buf->status_le); | ||
2680 | WL_SCAN("status = %d\n", *status); | ||
2681 | *bss_list = results; | ||
2682 | |||
2683 | return err; | ||
2684 | } | ||
2685 | |||
2686 | static s32 brcmf_iscan_done(struct brcmf_cfg80211_info *cfg) | ||
2687 | { | ||
2688 | struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan; | ||
2689 | s32 err = 0; | ||
2690 | |||
2691 | iscan->state = WL_ISCAN_STATE_IDLE; | ||
2692 | brcmf_inform_bss(cfg); | ||
2693 | brcmf_notify_iscan_complete(iscan, false); | ||
2694 | |||
2695 | return err; | ||
2696 | } | ||
2697 | |||
2698 | static s32 brcmf_iscan_pending(struct brcmf_cfg80211_info *cfg) | ||
2699 | { | ||
2700 | struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan; | ||
2701 | s32 err = 0; | ||
2702 | |||
2703 | /* Reschedule the timer */ | ||
2704 | mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000); | ||
2705 | iscan->timer_on = 1; | ||
2706 | |||
2707 | return err; | ||
2708 | } | ||
2709 | |||
2710 | static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_info *cfg) | ||
2711 | { | ||
2712 | struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan; | ||
2713 | s32 err = 0; | ||
2714 | |||
2715 | brcmf_inform_bss(cfg); | ||
2716 | brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE); | ||
2717 | /* Reschedule the timer */ | ||
2718 | mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000); | ||
2719 | iscan->timer_on = 1; | ||
2720 | |||
2721 | return err; | ||
2722 | } | ||
2723 | |||
2724 | static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_info *cfg) | ||
2725 | { | ||
2726 | struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan; | ||
2727 | s32 err = 0; | ||
2728 | |||
2729 | iscan->state = WL_ISCAN_STATE_IDLE; | ||
2730 | brcmf_notify_iscan_complete(iscan, true); | ||
2731 | |||
2732 | return err; | ||
2733 | } | ||
2734 | |||
2735 | static void brcmf_cfg80211_iscan_handler(struct work_struct *work) | ||
2736 | { | ||
2737 | struct brcmf_cfg80211_iscan_ctrl *iscan = | ||
2738 | container_of(work, struct brcmf_cfg80211_iscan_ctrl, | ||
2739 | work); | ||
2740 | struct brcmf_cfg80211_info *cfg = iscan_to_cfg(iscan); | ||
2741 | struct brcmf_cfg80211_iscan_eloop *el = &iscan->el; | ||
2742 | u32 status = BRCMF_SCAN_RESULTS_PARTIAL; | ||
2743 | |||
2744 | if (iscan->timer_on) { | ||
2745 | del_timer_sync(&iscan->timer); | ||
2746 | iscan->timer_on = 0; | ||
2747 | } | ||
2748 | |||
2749 | if (brcmf_get_iscan_results(iscan, &status, &cfg->bss_list)) { | ||
2750 | status = BRCMF_SCAN_RESULTS_ABORTED; | ||
2751 | WL_ERR("Abort iscan\n"); | ||
2752 | } | ||
2753 | |||
2754 | el->handler[status](cfg); | ||
2755 | } | ||
2756 | |||
2757 | static void brcmf_iscan_timer(unsigned long data) | ||
2758 | { | ||
2759 | struct brcmf_cfg80211_iscan_ctrl *iscan = | ||
2760 | (struct brcmf_cfg80211_iscan_ctrl *)data; | ||
2761 | |||
2762 | if (iscan) { | ||
2763 | iscan->timer_on = 0; | ||
2764 | WL_SCAN("timer expired\n"); | ||
2765 | brcmf_wakeup_iscan(iscan); | ||
2766 | } | ||
2767 | } | ||
2768 | |||
2769 | static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_info *cfg) | ||
2770 | { | ||
2771 | struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg); | ||
2772 | |||
2773 | if (cfg->iscan_on) { | ||
2774 | iscan->state = WL_ISCAN_STATE_IDLE; | ||
2775 | INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler); | ||
2776 | } | ||
2777 | |||
2778 | return 0; | ||
2779 | } | ||
2780 | |||
2781 | static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el) | ||
2782 | { | ||
2783 | memset(el, 0, sizeof(*el)); | ||
2784 | el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done; | ||
2785 | el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress; | ||
2786 | el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending; | ||
2787 | el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted; | ||
2788 | el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted; | ||
2789 | } | ||
2790 | |||
2791 | static s32 brcmf_init_iscan(struct brcmf_cfg80211_info *cfg) | ||
2792 | { | ||
2793 | struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg); | ||
2794 | int err = 0; | ||
2795 | |||
2796 | if (cfg->iscan_on) { | ||
2797 | iscan->ndev = cfg_to_ndev(cfg); | ||
2798 | brcmf_init_iscan_eloop(&iscan->el); | ||
2799 | iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS; | ||
2800 | init_timer(&iscan->timer); | ||
2801 | iscan->timer.data = (unsigned long) iscan; | ||
2802 | iscan->timer.function = brcmf_iscan_timer; | ||
2803 | err = brcmf_invoke_iscan(cfg); | ||
2804 | if (!err) | ||
2805 | iscan->data = cfg; | ||
2806 | } | ||
2807 | |||
2808 | return err; | ||
2809 | } | ||
2810 | |||
2811 | static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work) | 2397 | static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work) |
2812 | { | 2398 | { |
2813 | struct brcmf_cfg80211_info *cfg = | 2399 | struct brcmf_cfg80211_info *cfg = |
@@ -2825,8 +2411,7 @@ static void brcmf_escan_timeout(unsigned long data) | |||
2825 | 2411 | ||
2826 | if (cfg->scan_request) { | 2412 | if (cfg->scan_request) { |
2827 | WL_ERR("timer expired\n"); | 2413 | WL_ERR("timer expired\n"); |
2828 | if (cfg->escan_on) | 2414 | schedule_work(&cfg->escan_timeout_work); |
2829 | schedule_work(&cfg->escan_timeout_work); | ||
2830 | } | 2415 | } |
2831 | } | 2416 | } |
2832 | 2417 | ||
@@ -2863,10 +2448,11 @@ brcmf_compare_update_same_bss(struct brcmf_bss_info_le *bss, | |||
2863 | } | 2448 | } |
2864 | 2449 | ||
2865 | static s32 | 2450 | static s32 |
2866 | brcmf_cfg80211_escan_handler(struct brcmf_cfg80211_info *cfg, | 2451 | brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, |
2867 | struct net_device *ndev, | ||
2868 | const struct brcmf_event_msg *e, void *data) | 2452 | const struct brcmf_event_msg *e, void *data) |
2869 | { | 2453 | { |
2454 | struct brcmf_cfg80211_info *cfg = ifp->drvr->config; | ||
2455 | struct net_device *ndev = ifp->ndev; | ||
2870 | s32 status; | 2456 | s32 status; |
2871 | s32 err = 0; | 2457 | s32 err = 0; |
2872 | struct brcmf_escan_result_le *escan_result_le; | 2458 | struct brcmf_escan_result_le *escan_result_le; |
@@ -2877,13 +2463,11 @@ brcmf_cfg80211_escan_handler(struct brcmf_cfg80211_info *cfg, | |||
2877 | u32 i; | 2463 | u32 i; |
2878 | bool aborted; | 2464 | bool aborted; |
2879 | 2465 | ||
2880 | status = be32_to_cpu(e->status); | 2466 | status = e->status; |
2881 | 2467 | ||
2882 | if (!ndev || !cfg->escan_on || | 2468 | if (!ndev || !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { |
2883 | !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { | 2469 | WL_ERR("scan not ready ndev %p drv_status %x\n", ndev, |
2884 | WL_ERR("scan not ready ndev %p wl->escan_on %d drv_status %x\n", | 2470 | !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)); |
2885 | ndev, cfg->escan_on, | ||
2886 | !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)); | ||
2887 | return -EPERM; | 2471 | return -EPERM; |
2888 | } | 2472 | } |
2889 | 2473 | ||
@@ -2960,18 +2544,15 @@ exit: | |||
2960 | 2544 | ||
2961 | static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg) | 2545 | static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg) |
2962 | { | 2546 | { |
2963 | 2547 | brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT, | |
2964 | if (cfg->escan_on) { | 2548 | brcmf_cfg80211_escan_handler); |
2965 | cfg->el.handler[BRCMF_E_ESCAN_RESULT] = | 2549 | cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE; |
2966 | brcmf_cfg80211_escan_handler; | 2550 | /* Init scan_timeout timer */ |
2967 | cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE; | 2551 | init_timer(&cfg->escan_timeout); |
2968 | /* Init scan_timeout timer */ | 2552 | cfg->escan_timeout.data = (unsigned long) cfg; |
2969 | init_timer(&cfg->escan_timeout); | 2553 | cfg->escan_timeout.function = brcmf_escan_timeout; |
2970 | cfg->escan_timeout.data = (unsigned long) cfg; | 2554 | INIT_WORK(&cfg->escan_timeout_work, |
2971 | cfg->escan_timeout.function = brcmf_escan_timeout; | 2555 | brcmf_cfg80211_escan_timeout_worker); |
2972 | INIT_WORK(&cfg->escan_timeout_work, | ||
2973 | brcmf_cfg80211_escan_timeout_worker); | ||
2974 | } | ||
2975 | } | 2556 | } |
2976 | 2557 | ||
2977 | static __always_inline void brcmf_delay(u32 ms) | 2558 | static __always_inline void brcmf_delay(u32 ms) |
@@ -2986,20 +2567,8 @@ static __always_inline void brcmf_delay(u32 ms) | |||
2986 | 2567 | ||
2987 | static s32 brcmf_cfg80211_resume(struct wiphy *wiphy) | 2568 | static s32 brcmf_cfg80211_resume(struct wiphy *wiphy) |
2988 | { | 2569 | { |
2989 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | ||
2990 | struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); | ||
2991 | |||
2992 | /* | ||
2993 | * Check for BRCMF_VIF_STATUS_READY before any function call which | ||
2994 | * could result is bus access. Don't block the resume for | ||
2995 | * any driver error conditions | ||
2996 | */ | ||
2997 | WL_TRACE("Enter\n"); | 2570 | WL_TRACE("Enter\n"); |
2998 | 2571 | ||
2999 | if (check_vif_up(ifp->vif)) | ||
3000 | brcmf_invoke_iscan(cfg); | ||
3001 | |||
3002 | WL_TRACE("Exit\n"); | ||
3003 | return 0; | 2572 | return 0; |
3004 | } | 2573 | } |
3005 | 2574 | ||
@@ -3198,10 +2767,11 @@ brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev) | |||
3198 | * cfg80211_scan_request one out of the received PNO event. | 2767 | * cfg80211_scan_request one out of the received PNO event. |
3199 | */ | 2768 | */ |
3200 | static s32 | 2769 | static s32 |
3201 | brcmf_notify_sched_scan_results(struct brcmf_cfg80211_info *cfg, | 2770 | brcmf_notify_sched_scan_results(struct brcmf_if *ifp, |
3202 | struct net_device *ndev, | ||
3203 | const struct brcmf_event_msg *e, void *data) | 2771 | const struct brcmf_event_msg *e, void *data) |
3204 | { | 2772 | { |
2773 | struct brcmf_cfg80211_info *cfg = ifp->drvr->config; | ||
2774 | struct net_device *ndev = ifp->ndev; | ||
3205 | struct brcmf_pno_net_info_le *netinfo, *netinfo_start; | 2775 | struct brcmf_pno_net_info_le *netinfo, *netinfo_start; |
3206 | struct cfg80211_scan_request *request = NULL; | 2776 | struct cfg80211_scan_request *request = NULL; |
3207 | struct cfg80211_ssid *ssid = NULL; | 2777 | struct cfg80211_ssid *ssid = NULL; |
@@ -3216,7 +2786,7 @@ brcmf_notify_sched_scan_results(struct brcmf_cfg80211_info *cfg, | |||
3216 | 2786 | ||
3217 | WL_SCAN("Enter\n"); | 2787 | WL_SCAN("Enter\n"); |
3218 | 2788 | ||
3219 | if (e->event_type == cpu_to_be32(BRCMF_E_PFN_NET_LOST)) { | 2789 | if (e->event_code == BRCMF_E_PFN_NET_LOST) { |
3220 | WL_SCAN("PFN NET LOST event. Do Nothing\n"); | 2790 | WL_SCAN("PFN NET LOST event. Do Nothing\n"); |
3221 | return 0; | 2791 | return 0; |
3222 | } | 2792 | } |
@@ -3309,7 +2879,6 @@ out_err: | |||
3309 | return err; | 2879 | return err; |
3310 | } | 2880 | } |
3311 | 2881 | ||
3312 | #ifndef CONFIG_BRCMISCAN | ||
3313 | static int brcmf_dev_pno_clean(struct net_device *ndev) | 2882 | static int brcmf_dev_pno_clean(struct net_device *ndev) |
3314 | { | 2883 | { |
3315 | int ret; | 2884 | int ret; |
@@ -3446,7 +3015,6 @@ static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy, | |||
3446 | brcmf_notify_escan_complete(cfg, ndev, true, true); | 3015 | brcmf_notify_escan_complete(cfg, ndev, true, true); |
3447 | return 0; | 3016 | return 0; |
3448 | } | 3017 | } |
3449 | #endif /* CONFIG_BRCMISCAN */ | ||
3450 | 3018 | ||
3451 | #ifdef CONFIG_NL80211_TESTMODE | 3019 | #ifdef CONFIG_NL80211_TESTMODE |
3452 | static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len) | 3020 | static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len) |
@@ -3512,7 +3080,7 @@ static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie) | |||
3512 | 3080 | ||
3513 | static s32 | 3081 | static s32 |
3514 | brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie, | 3082 | brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie, |
3515 | bool is_rsn_ie, s32 bssidx) | 3083 | bool is_rsn_ie) |
3516 | { | 3084 | { |
3517 | struct brcmf_if *ifp = netdev_priv(ndev); | 3085 | struct brcmf_if *ifp = netdev_priv(ndev); |
3518 | u32 auth = 0; /* d11 open authentication */ | 3086 | u32 auth = 0; /* d11 open authentication */ |
@@ -3689,7 +3257,7 @@ exit: | |||
3689 | } | 3257 | } |
3690 | 3258 | ||
3691 | static s32 | 3259 | static s32 |
3692 | brcmf_parse_vndr_ies(u8 *vndr_ie_buf, u32 vndr_ie_len, | 3260 | brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len, |
3693 | struct parsed_vndr_ies *vndr_ies) | 3261 | struct parsed_vndr_ies *vndr_ies) |
3694 | { | 3262 | { |
3695 | s32 err = 0; | 3263 | s32 err = 0; |
@@ -3768,13 +3336,12 @@ brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd) | |||
3768 | return ie_len + VNDR_IE_HDR_SIZE; | 3336 | return ie_len + VNDR_IE_HDR_SIZE; |
3769 | } | 3337 | } |
3770 | 3338 | ||
3771 | static s32 | 3339 | static |
3772 | brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg, | 3340 | s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, |
3773 | struct net_device *ndev, s32 pktflag, | 3341 | const u8 *vndr_ie_buf, u32 vndr_ie_len) |
3774 | u8 *vndr_ie_buf, u32 vndr_ie_len) | ||
3775 | { | 3342 | { |
3776 | struct brcmf_if *ifp = netdev_priv(ndev); | 3343 | struct brcmf_if *ifp; |
3777 | struct vif_saved_ie *saved_ie = &ifp->vif->saved_ie; | 3344 | struct vif_saved_ie *saved_ie; |
3778 | s32 err = 0; | 3345 | s32 err = 0; |
3779 | u8 *iovar_ie_buf; | 3346 | u8 *iovar_ie_buf; |
3780 | u8 *curr_ie_buf; | 3347 | u8 *curr_ie_buf; |
@@ -3791,8 +3358,12 @@ brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg, | |||
3791 | u8 *ptr; | 3358 | u8 *ptr; |
3792 | int remained_buf_len; | 3359 | int remained_buf_len; |
3793 | 3360 | ||
3794 | WL_TRACE("bssidx %d, pktflag : 0x%02X\n", | 3361 | if (!vif) |
3795 | brcmf_ndev_bssidx(ndev), pktflag); | 3362 | return -ENODEV; |
3363 | ifp = vif->ifp; | ||
3364 | saved_ie = &vif->saved_ie; | ||
3365 | |||
3366 | WL_TRACE("bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag); | ||
3796 | iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); | 3367 | iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); |
3797 | if (!iovar_ie_buf) | 3368 | if (!iovar_ie_buf) |
3798 | return -ENOMEM; | 3369 | return -ENOMEM; |
@@ -3932,13 +3503,13 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, | |||
3932 | struct brcmf_tlv *rsn_ie; | 3503 | struct brcmf_tlv *rsn_ie; |
3933 | struct brcmf_vs_tlv *wpa_ie; | 3504 | struct brcmf_vs_tlv *wpa_ie; |
3934 | struct brcmf_join_params join_params; | 3505 | struct brcmf_join_params join_params; |
3935 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | ||
3936 | s32 bssidx = 0; | 3506 | s32 bssidx = 0; |
3937 | 3507 | ||
3938 | WL_TRACE("channel_type=%d, beacon_interval=%d, dtim_period=%d,\n", | 3508 | WL_TRACE("channel_type=%d, beacon_interval=%d, dtim_period=%d,\n", |
3939 | settings->channel_type, settings->beacon_interval, | 3509 | cfg80211_get_chandef_type(&settings->chandef), |
3510 | settings->beacon_interval, | ||
3940 | settings->dtim_period); | 3511 | settings->dtim_period); |
3941 | WL_TRACE("ssid=%s(%d), auth_type=%d, inactivity_timeout=%d\n", | 3512 | WL_TRACE("ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n", |
3942 | settings->ssid, settings->ssid_len, settings->auth_type, | 3513 | settings->ssid, settings->ssid_len, settings->auth_type, |
3943 | settings->inactivity_timeout); | 3514 | settings->inactivity_timeout); |
3944 | 3515 | ||
@@ -3990,55 +3561,39 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, | |||
3990 | wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail, | 3561 | wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail, |
3991 | settings->beacon.tail_len); | 3562 | settings->beacon.tail_len); |
3992 | 3563 | ||
3993 | kfree(cfg->ap_info->rsn_ie); | ||
3994 | cfg->ap_info->rsn_ie = NULL; | ||
3995 | kfree(cfg->ap_info->wpa_ie); | ||
3996 | cfg->ap_info->wpa_ie = NULL; | ||
3997 | |||
3998 | if ((wpa_ie != NULL || rsn_ie != NULL)) { | 3564 | if ((wpa_ie != NULL || rsn_ie != NULL)) { |
3999 | WL_TRACE("WPA(2) IE is found\n"); | 3565 | WL_TRACE("WPA(2) IE is found\n"); |
4000 | if (wpa_ie != NULL) { | 3566 | if (wpa_ie != NULL) { |
4001 | /* WPA IE */ | 3567 | /* WPA IE */ |
4002 | err = brcmf_configure_wpaie(ndev, wpa_ie, false, | 3568 | err = brcmf_configure_wpaie(ndev, wpa_ie, false); |
4003 | bssidx); | ||
4004 | if (err < 0) | 3569 | if (err < 0) |
4005 | goto exit; | 3570 | goto exit; |
4006 | cfg->ap_info->wpa_ie = kmemdup(wpa_ie, | ||
4007 | wpa_ie->len + | ||
4008 | TLV_HDR_LEN, | ||
4009 | GFP_KERNEL); | ||
4010 | } else { | 3571 | } else { |
4011 | /* RSN IE */ | 3572 | /* RSN IE */ |
4012 | err = brcmf_configure_wpaie(ndev, | 3573 | err = brcmf_configure_wpaie(ndev, |
4013 | (struct brcmf_vs_tlv *)rsn_ie, true, bssidx); | 3574 | (struct brcmf_vs_tlv *)rsn_ie, true); |
4014 | if (err < 0) | 3575 | if (err < 0) |
4015 | goto exit; | 3576 | goto exit; |
4016 | cfg->ap_info->rsn_ie = kmemdup(rsn_ie, | ||
4017 | rsn_ie->len + | ||
4018 | TLV_HDR_LEN, | ||
4019 | GFP_KERNEL); | ||
4020 | } | 3577 | } |
4021 | cfg->ap_info->security_mode = true; | ||
4022 | } else { | 3578 | } else { |
4023 | WL_TRACE("No WPA(2) IEs found\n"); | 3579 | WL_TRACE("No WPA(2) IEs found\n"); |
4024 | brcmf_configure_opensecurity(ndev, bssidx); | 3580 | brcmf_configure_opensecurity(ndev, bssidx); |
4025 | cfg->ap_info->security_mode = false; | ||
4026 | } | 3581 | } |
4027 | /* Set Beacon IEs to FW */ | 3582 | /* Set Beacon IEs to FW */ |
4028 | err = brcmf_set_management_ie(cfg, ndev, | 3583 | err = brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev), |
4029 | VNDR_IE_BEACON_FLAG, | 3584 | VNDR_IE_BEACON_FLAG, |
4030 | (u8 *)settings->beacon.tail, | 3585 | settings->beacon.tail, |
4031 | settings->beacon.tail_len); | 3586 | settings->beacon.tail_len); |
4032 | if (err) | 3587 | if (err) |
4033 | WL_ERR("Set Beacon IE Failed\n"); | 3588 | WL_ERR("Set Beacon IE Failed\n"); |
4034 | else | 3589 | else |
4035 | WL_TRACE("Applied Vndr IEs for Beacon\n"); | 3590 | WL_TRACE("Applied Vndr IEs for Beacon\n"); |
4036 | 3591 | ||
4037 | /* Set Probe Response IEs to FW */ | 3592 | /* Set Probe Response IEs to FW */ |
4038 | err = brcmf_set_management_ie(cfg, ndev, | 3593 | err = brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev), |
4039 | VNDR_IE_PRBRSP_FLAG, | 3594 | VNDR_IE_PRBRSP_FLAG, |
4040 | (u8 *)settings->beacon.proberesp_ies, | 3595 | settings->beacon.proberesp_ies, |
4041 | settings->beacon.proberesp_ies_len); | 3596 | settings->beacon.proberesp_ies_len); |
4042 | if (err) | 3597 | if (err) |
4043 | WL_ERR("Set Probe Resp IE Failed\n"); | 3598 | WL_ERR("Set Probe Resp IE Failed\n"); |
4044 | else | 3599 | else |
@@ -4169,11 +3724,8 @@ static struct cfg80211_ops wl_cfg80211_ops = { | |||
4169 | .start_ap = brcmf_cfg80211_start_ap, | 3724 | .start_ap = brcmf_cfg80211_start_ap, |
4170 | .stop_ap = brcmf_cfg80211_stop_ap, | 3725 | .stop_ap = brcmf_cfg80211_stop_ap, |
4171 | .del_station = brcmf_cfg80211_del_station, | 3726 | .del_station = brcmf_cfg80211_del_station, |
4172 | #ifndef CONFIG_BRCMISCAN | ||
4173 | /* scheduled scan need e-scan, which is mutual exclusive with i-scan */ | ||
4174 | .sched_scan_start = brcmf_cfg80211_sched_scan_start, | 3727 | .sched_scan_start = brcmf_cfg80211_sched_scan_start, |
4175 | .sched_scan_stop = brcmf_cfg80211_sched_scan_stop, | 3728 | .sched_scan_stop = brcmf_cfg80211_sched_scan_stop, |
4176 | #endif | ||
4177 | #ifdef CONFIG_NL80211_TESTMODE | 3729 | #ifdef CONFIG_NL80211_TESTMODE |
4178 | .testmode_cmd = brcmf_cfg80211_testmode | 3730 | .testmode_cmd = brcmf_cfg80211_testmode |
4179 | #endif | 3731 | #endif |
@@ -4197,13 +3749,11 @@ static s32 brcmf_mode_to_nl80211_iftype(s32 mode) | |||
4197 | 3749 | ||
4198 | static void brcmf_wiphy_pno_params(struct wiphy *wiphy) | 3750 | static void brcmf_wiphy_pno_params(struct wiphy *wiphy) |
4199 | { | 3751 | { |
4200 | #ifndef CONFIG_BRCMISCAN | ||
4201 | /* scheduled scan settings */ | 3752 | /* scheduled scan settings */ |
4202 | wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT; | 3753 | wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT; |
4203 | wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT; | 3754 | wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT; |
4204 | wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX; | 3755 | wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX; |
4205 | wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; | 3756 | wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; |
4206 | #endif | ||
4207 | } | 3757 | } |
4208 | 3758 | ||
4209 | static struct wiphy *brcmf_setup_wiphy(struct device *phydev) | 3759 | static struct wiphy *brcmf_setup_wiphy(struct device *phydev) |
@@ -4302,8 +3852,8 @@ static void brcmf_free_vif(struct brcmf_cfg80211_vif *vif) | |||
4302 | static bool brcmf_is_linkup(struct brcmf_cfg80211_info *cfg, | 3852 | static bool brcmf_is_linkup(struct brcmf_cfg80211_info *cfg, |
4303 | const struct brcmf_event_msg *e) | 3853 | const struct brcmf_event_msg *e) |
4304 | { | 3854 | { |
4305 | u32 event = be32_to_cpu(e->event_type); | 3855 | u32 event = e->event_code; |
4306 | u32 status = be32_to_cpu(e->status); | 3856 | u32 status = e->status; |
4307 | 3857 | ||
4308 | if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) { | 3858 | if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) { |
4309 | WL_CONN("Processing set ssid\n"); | 3859 | WL_CONN("Processing set ssid\n"); |
@@ -4317,8 +3867,8 @@ static bool brcmf_is_linkup(struct brcmf_cfg80211_info *cfg, | |||
4317 | static bool brcmf_is_linkdown(struct brcmf_cfg80211_info *cfg, | 3867 | static bool brcmf_is_linkdown(struct brcmf_cfg80211_info *cfg, |
4318 | const struct brcmf_event_msg *e) | 3868 | const struct brcmf_event_msg *e) |
4319 | { | 3869 | { |
4320 | u32 event = be32_to_cpu(e->event_type); | 3870 | u32 event = e->event_code; |
4321 | u16 flags = be16_to_cpu(e->flags); | 3871 | u16 flags = e->flags; |
4322 | 3872 | ||
4323 | if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) { | 3873 | if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) { |
4324 | WL_CONN("Processing link down\n"); | 3874 | WL_CONN("Processing link down\n"); |
@@ -4330,13 +3880,12 @@ static bool brcmf_is_linkdown(struct brcmf_cfg80211_info *cfg, | |||
4330 | static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg, | 3880 | static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg, |
4331 | const struct brcmf_event_msg *e) | 3881 | const struct brcmf_event_msg *e) |
4332 | { | 3882 | { |
4333 | u32 event = be32_to_cpu(e->event_type); | 3883 | u32 event = e->event_code; |
4334 | u32 status = be32_to_cpu(e->status); | 3884 | u32 status = e->status; |
4335 | 3885 | ||
4336 | if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) { | 3886 | if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) { |
4337 | WL_CONN("Processing Link %s & no network found\n", | 3887 | WL_CONN("Processing Link %s & no network found\n", |
4338 | be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ? | 3888 | e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down"); |
4339 | "up" : "down"); | ||
4340 | return true; | 3889 | return true; |
4341 | } | 3890 | } |
4342 | 3891 | ||
@@ -4524,9 +4073,9 @@ brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg, | |||
4524 | const struct brcmf_event_msg *e, void *data) | 4073 | const struct brcmf_event_msg *e, void *data) |
4525 | { | 4074 | { |
4526 | s32 err = 0; | 4075 | s32 err = 0; |
4527 | u32 event = be32_to_cpu(e->event_type); | 4076 | u32 event = e->event_code; |
4528 | u32 reason = be32_to_cpu(e->reason); | 4077 | u32 reason = e->reason; |
4529 | u32 len = be32_to_cpu(e->datalen); | 4078 | u32 len = e->datalen; |
4530 | static int generation; | 4079 | static int generation; |
4531 | 4080 | ||
4532 | struct station_info sinfo; | 4081 | struct station_info sinfo; |
@@ -4558,11 +4107,11 @@ brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg, | |||
4558 | } | 4107 | } |
4559 | 4108 | ||
4560 | static s32 | 4109 | static s32 |
4561 | brcmf_notify_connect_status(struct brcmf_cfg80211_info *cfg, | 4110 | brcmf_notify_connect_status(struct brcmf_if *ifp, |
4562 | struct net_device *ndev, | ||
4563 | const struct brcmf_event_msg *e, void *data) | 4111 | const struct brcmf_event_msg *e, void *data) |
4564 | { | 4112 | { |
4565 | struct brcmf_if *ifp = netdev_priv(ndev); | 4113 | struct brcmf_cfg80211_info *cfg = ifp->drvr->config; |
4114 | struct net_device *ndev = ifp->ndev; | ||
4566 | struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; | 4115 | struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; |
4567 | s32 err = 0; | 4116 | s32 err = 0; |
4568 | 4117 | ||
@@ -4610,31 +4159,29 @@ brcmf_notify_connect_status(struct brcmf_cfg80211_info *cfg, | |||
4610 | } | 4159 | } |
4611 | 4160 | ||
4612 | static s32 | 4161 | static s32 |
4613 | brcmf_notify_roaming_status(struct brcmf_cfg80211_info *cfg, | 4162 | brcmf_notify_roaming_status(struct brcmf_if *ifp, |
4614 | struct net_device *ndev, | ||
4615 | const struct brcmf_event_msg *e, void *data) | 4163 | const struct brcmf_event_msg *e, void *data) |
4616 | { | 4164 | { |
4617 | struct brcmf_if *ifp = netdev_priv(ndev); | 4165 | struct brcmf_cfg80211_info *cfg = ifp->drvr->config; |
4618 | s32 err = 0; | 4166 | s32 err = 0; |
4619 | u32 event = be32_to_cpu(e->event_type); | 4167 | u32 event = e->event_code; |
4620 | u32 status = be32_to_cpu(e->status); | 4168 | u32 status = e->status; |
4621 | 4169 | ||
4622 | if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) { | 4170 | if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) { |
4623 | if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state)) | 4171 | if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state)) |
4624 | brcmf_bss_roaming_done(cfg, ndev, e); | 4172 | brcmf_bss_roaming_done(cfg, ifp->ndev, e); |
4625 | else | 4173 | else |
4626 | brcmf_bss_connect_done(cfg, ndev, e, true); | 4174 | brcmf_bss_connect_done(cfg, ifp->ndev, e, true); |
4627 | } | 4175 | } |
4628 | 4176 | ||
4629 | return err; | 4177 | return err; |
4630 | } | 4178 | } |
4631 | 4179 | ||
4632 | static s32 | 4180 | static s32 |
4633 | brcmf_notify_mic_status(struct brcmf_cfg80211_info *cfg, | 4181 | brcmf_notify_mic_status(struct brcmf_if *ifp, |
4634 | struct net_device *ndev, | ||
4635 | const struct brcmf_event_msg *e, void *data) | 4182 | const struct brcmf_event_msg *e, void *data) |
4636 | { | 4183 | { |
4637 | u16 flags = be16_to_cpu(e->flags); | 4184 | u16 flags = e->flags; |
4638 | enum nl80211_key_type key_type; | 4185 | enum nl80211_key_type key_type; |
4639 | 4186 | ||
4640 | if (flags & BRCMF_EVENT_MSG_GROUP) | 4187 | if (flags & BRCMF_EVENT_MSG_GROUP) |
@@ -4642,84 +4189,12 @@ brcmf_notify_mic_status(struct brcmf_cfg80211_info *cfg, | |||
4642 | else | 4189 | else |
4643 | key_type = NL80211_KEYTYPE_PAIRWISE; | 4190 | key_type = NL80211_KEYTYPE_PAIRWISE; |
4644 | 4191 | ||
4645 | cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1, | 4192 | cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1, |
4646 | NULL, GFP_KERNEL); | 4193 | NULL, GFP_KERNEL); |
4647 | 4194 | ||
4648 | return 0; | 4195 | return 0; |
4649 | } | 4196 | } |
4650 | 4197 | ||
4651 | static s32 | ||
4652 | brcmf_notify_scan_status(struct brcmf_cfg80211_info *cfg, | ||
4653 | struct net_device *ndev, | ||
4654 | const struct brcmf_event_msg *e, void *data) | ||
4655 | { | ||
4656 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
4657 | struct brcmf_channel_info_le channel_inform_le; | ||
4658 | struct brcmf_scan_results_le *bss_list_le; | ||
4659 | u32 len = WL_SCAN_BUF_MAX; | ||
4660 | s32 err = 0; | ||
4661 | bool scan_abort = false; | ||
4662 | u32 scan_channel; | ||
4663 | |||
4664 | WL_TRACE("Enter\n"); | ||
4665 | |||
4666 | if (cfg->iscan_on && cfg->iscan_kickstart) { | ||
4667 | WL_TRACE("Exit\n"); | ||
4668 | return brcmf_wakeup_iscan(cfg_to_iscan(cfg)); | ||
4669 | } | ||
4670 | |||
4671 | if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { | ||
4672 | WL_ERR("Scan complete while device not scanning\n"); | ||
4673 | scan_abort = true; | ||
4674 | err = -EINVAL; | ||
4675 | goto scan_done_out; | ||
4676 | } | ||
4677 | |||
4678 | err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_CHANNEL, | ||
4679 | &channel_inform_le, | ||
4680 | sizeof(channel_inform_le)); | ||
4681 | if (err) { | ||
4682 | WL_ERR("scan busy (%d)\n", err); | ||
4683 | scan_abort = true; | ||
4684 | goto scan_done_out; | ||
4685 | } | ||
4686 | scan_channel = le32_to_cpu(channel_inform_le.scan_channel); | ||
4687 | if (scan_channel) | ||
4688 | WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel); | ||
4689 | cfg->bss_list = cfg->scan_results; | ||
4690 | bss_list_le = (struct brcmf_scan_results_le *) cfg->bss_list; | ||
4691 | |||
4692 | memset(cfg->scan_results, 0, len); | ||
4693 | bss_list_le->buflen = cpu_to_le32(len); | ||
4694 | err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_SCAN_RESULTS, | ||
4695 | cfg->scan_results, len); | ||
4696 | if (err) { | ||
4697 | WL_ERR("%s Scan_results error (%d)\n", ndev->name, err); | ||
4698 | err = -EINVAL; | ||
4699 | scan_abort = true; | ||
4700 | goto scan_done_out; | ||
4701 | } | ||
4702 | cfg->scan_results->buflen = le32_to_cpu(bss_list_le->buflen); | ||
4703 | cfg->scan_results->version = le32_to_cpu(bss_list_le->version); | ||
4704 | cfg->scan_results->count = le32_to_cpu(bss_list_le->count); | ||
4705 | |||
4706 | err = brcmf_inform_bss(cfg); | ||
4707 | if (err) | ||
4708 | scan_abort = true; | ||
4709 | |||
4710 | scan_done_out: | ||
4711 | if (cfg->scan_request) { | ||
4712 | WL_SCAN("calling cfg80211_scan_done\n"); | ||
4713 | cfg80211_scan_done(cfg->scan_request, scan_abort); | ||
4714 | brcmf_set_mpc(ndev, 1); | ||
4715 | cfg->scan_request = NULL; | ||
4716 | } | ||
4717 | |||
4718 | WL_TRACE("Exit\n"); | ||
4719 | |||
4720 | return err; | ||
4721 | } | ||
4722 | |||
4723 | static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf) | 4198 | static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf) |
4724 | { | 4199 | { |
4725 | conf->mode = (u32)-1; | 4200 | conf->mode = (u32)-1; |
@@ -4730,77 +4205,53 @@ static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf) | |||
4730 | conf->tx_power = -1; | 4205 | conf->tx_power = -1; |
4731 | } | 4206 | } |
4732 | 4207 | ||
4733 | static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el) | 4208 | static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg) |
4734 | { | 4209 | { |
4735 | memset(el, 0, sizeof(*el)); | 4210 | brcmf_fweh_register(cfg->pub, BRCMF_E_LINK, |
4736 | el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status; | 4211 | brcmf_notify_connect_status); |
4737 | el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status; | 4212 | brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND, |
4738 | el->handler[BRCMF_E_DEAUTH_IND] = brcmf_notify_connect_status; | 4213 | brcmf_notify_connect_status); |
4739 | el->handler[BRCMF_E_DEAUTH] = brcmf_notify_connect_status; | 4214 | brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH, |
4740 | el->handler[BRCMF_E_DISASSOC_IND] = brcmf_notify_connect_status; | 4215 | brcmf_notify_connect_status); |
4741 | el->handler[BRCMF_E_ASSOC_IND] = brcmf_notify_connect_status; | 4216 | brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND, |
4742 | el->handler[BRCMF_E_REASSOC_IND] = brcmf_notify_connect_status; | 4217 | brcmf_notify_connect_status); |
4743 | el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status; | 4218 | brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND, |
4744 | el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status; | 4219 | brcmf_notify_connect_status); |
4745 | el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status; | 4220 | brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND, |
4746 | el->handler[BRCMF_E_PFN_NET_FOUND] = brcmf_notify_sched_scan_results; | 4221 | brcmf_notify_connect_status); |
4222 | brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM, | ||
4223 | brcmf_notify_roaming_status); | ||
4224 | brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR, | ||
4225 | brcmf_notify_mic_status); | ||
4226 | brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID, | ||
4227 | brcmf_notify_connect_status); | ||
4228 | brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND, | ||
4229 | brcmf_notify_sched_scan_results); | ||
4747 | } | 4230 | } |
4748 | 4231 | ||
4749 | static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg) | 4232 | static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg) |
4750 | { | 4233 | { |
4751 | kfree(cfg->scan_results); | ||
4752 | cfg->scan_results = NULL; | ||
4753 | kfree(cfg->bss_info); | ||
4754 | cfg->bss_info = NULL; | ||
4755 | kfree(cfg->conf); | 4234 | kfree(cfg->conf); |
4756 | cfg->conf = NULL; | 4235 | cfg->conf = NULL; |
4757 | kfree(cfg->scan_req_int); | ||
4758 | cfg->scan_req_int = NULL; | ||
4759 | kfree(cfg->escan_ioctl_buf); | 4236 | kfree(cfg->escan_ioctl_buf); |
4760 | cfg->escan_ioctl_buf = NULL; | 4237 | cfg->escan_ioctl_buf = NULL; |
4761 | kfree(cfg->dcmd_buf); | ||
4762 | cfg->dcmd_buf = NULL; | ||
4763 | kfree(cfg->extra_buf); | 4238 | kfree(cfg->extra_buf); |
4764 | cfg->extra_buf = NULL; | 4239 | cfg->extra_buf = NULL; |
4765 | kfree(cfg->iscan); | ||
4766 | cfg->iscan = NULL; | ||
4767 | kfree(cfg->pmk_list); | 4240 | kfree(cfg->pmk_list); |
4768 | cfg->pmk_list = NULL; | 4241 | cfg->pmk_list = NULL; |
4769 | if (cfg->ap_info) { | ||
4770 | kfree(cfg->ap_info->wpa_ie); | ||
4771 | kfree(cfg->ap_info->rsn_ie); | ||
4772 | kfree(cfg->ap_info); | ||
4773 | cfg->ap_info = NULL; | ||
4774 | } | ||
4775 | } | 4242 | } |
4776 | 4243 | ||
4777 | static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg) | 4244 | static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg) |
4778 | { | 4245 | { |
4779 | cfg->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL); | ||
4780 | if (!cfg->scan_results) | ||
4781 | goto init_priv_mem_out; | ||
4782 | cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL); | 4246 | cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL); |
4783 | if (!cfg->conf) | 4247 | if (!cfg->conf) |
4784 | goto init_priv_mem_out; | 4248 | goto init_priv_mem_out; |
4785 | cfg->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL); | ||
4786 | if (!cfg->bss_info) | ||
4787 | goto init_priv_mem_out; | ||
4788 | cfg->scan_req_int = kzalloc(sizeof(*cfg->scan_req_int), | ||
4789 | GFP_KERNEL); | ||
4790 | if (!cfg->scan_req_int) | ||
4791 | goto init_priv_mem_out; | ||
4792 | cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL); | 4249 | cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL); |
4793 | if (!cfg->escan_ioctl_buf) | 4250 | if (!cfg->escan_ioctl_buf) |
4794 | goto init_priv_mem_out; | 4251 | goto init_priv_mem_out; |
4795 | cfg->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL); | ||
4796 | if (!cfg->dcmd_buf) | ||
4797 | goto init_priv_mem_out; | ||
4798 | cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); | 4252 | cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); |
4799 | if (!cfg->extra_buf) | 4253 | if (!cfg->extra_buf) |
4800 | goto init_priv_mem_out; | 4254 | goto init_priv_mem_out; |
4801 | cfg->iscan = kzalloc(sizeof(*cfg->iscan), GFP_KERNEL); | ||
4802 | if (!cfg->iscan) | ||
4803 | goto init_priv_mem_out; | ||
4804 | cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL); | 4255 | cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL); |
4805 | if (!cfg->pmk_list) | 4256 | if (!cfg->pmk_list) |
4806 | goto init_priv_mem_out; | 4257 | goto init_priv_mem_out; |
@@ -4813,149 +4264,22 @@ init_priv_mem_out: | |||
4813 | return -ENOMEM; | 4264 | return -ENOMEM; |
4814 | } | 4265 | } |
4815 | 4266 | ||
4816 | /* | ||
4817 | * retrieve first queued event from head | ||
4818 | */ | ||
4819 | |||
4820 | static struct brcmf_cfg80211_event_q *brcmf_deq_event( | ||
4821 | struct brcmf_cfg80211_info *cfg) | ||
4822 | { | ||
4823 | struct brcmf_cfg80211_event_q *e = NULL; | ||
4824 | |||
4825 | spin_lock_irq(&cfg->evt_q_lock); | ||
4826 | if (!list_empty(&cfg->evt_q_list)) { | ||
4827 | e = list_first_entry(&cfg->evt_q_list, | ||
4828 | struct brcmf_cfg80211_event_q, evt_q_list); | ||
4829 | list_del(&e->evt_q_list); | ||
4830 | } | ||
4831 | spin_unlock_irq(&cfg->evt_q_lock); | ||
4832 | |||
4833 | return e; | ||
4834 | } | ||
4835 | |||
4836 | /* | ||
4837 | * push event to tail of the queue | ||
4838 | * | ||
4839 | * remark: this function may not sleep as it is called in atomic context. | ||
4840 | */ | ||
4841 | |||
4842 | static s32 | ||
4843 | brcmf_enq_event(struct brcmf_cfg80211_info *cfg, u32 event, | ||
4844 | const struct brcmf_event_msg *msg, void *data) | ||
4845 | { | ||
4846 | struct brcmf_cfg80211_event_q *e; | ||
4847 | s32 err = 0; | ||
4848 | ulong flags; | ||
4849 | u32 data_len; | ||
4850 | u32 total_len; | ||
4851 | |||
4852 | total_len = sizeof(struct brcmf_cfg80211_event_q); | ||
4853 | if (data) | ||
4854 | data_len = be32_to_cpu(msg->datalen); | ||
4855 | else | ||
4856 | data_len = 0; | ||
4857 | total_len += data_len; | ||
4858 | e = kzalloc(total_len, GFP_ATOMIC); | ||
4859 | if (!e) | ||
4860 | return -ENOMEM; | ||
4861 | |||
4862 | e->etype = event; | ||
4863 | memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg)); | ||
4864 | if (data) | ||
4865 | memcpy(&e->edata, data, data_len); | ||
4866 | |||
4867 | spin_lock_irqsave(&cfg->evt_q_lock, flags); | ||
4868 | list_add_tail(&e->evt_q_list, &cfg->evt_q_list); | ||
4869 | spin_unlock_irqrestore(&cfg->evt_q_lock, flags); | ||
4870 | |||
4871 | return err; | ||
4872 | } | ||
4873 | |||
4874 | static void brcmf_put_event(struct brcmf_cfg80211_event_q *e) | ||
4875 | { | ||
4876 | kfree(e); | ||
4877 | } | ||
4878 | |||
4879 | static void brcmf_cfg80211_event_handler(struct work_struct *work) | ||
4880 | { | ||
4881 | struct brcmf_cfg80211_info *cfg = | ||
4882 | container_of(work, struct brcmf_cfg80211_info, | ||
4883 | event_work); | ||
4884 | struct brcmf_cfg80211_event_q *e; | ||
4885 | |||
4886 | e = brcmf_deq_event(cfg); | ||
4887 | if (unlikely(!e)) { | ||
4888 | WL_ERR("event queue empty...\n"); | ||
4889 | return; | ||
4890 | } | ||
4891 | |||
4892 | do { | ||
4893 | WL_INFO("event type (%d)\n", e->etype); | ||
4894 | if (cfg->el.handler[e->etype]) | ||
4895 | cfg->el.handler[e->etype](cfg, | ||
4896 | cfg_to_ndev(cfg), | ||
4897 | &e->emsg, e->edata); | ||
4898 | else | ||
4899 | WL_INFO("Unknown Event (%d): ignoring\n", e->etype); | ||
4900 | brcmf_put_event(e); | ||
4901 | } while ((e = brcmf_deq_event(cfg))); | ||
4902 | |||
4903 | } | ||
4904 | |||
4905 | static void brcmf_init_eq(struct brcmf_cfg80211_info *cfg) | ||
4906 | { | ||
4907 | spin_lock_init(&cfg->evt_q_lock); | ||
4908 | INIT_LIST_HEAD(&cfg->evt_q_list); | ||
4909 | } | ||
4910 | |||
4911 | static void brcmf_flush_eq(struct brcmf_cfg80211_info *cfg) | ||
4912 | { | ||
4913 | struct brcmf_cfg80211_event_q *e; | ||
4914 | |||
4915 | spin_lock_irq(&cfg->evt_q_lock); | ||
4916 | while (!list_empty(&cfg->evt_q_list)) { | ||
4917 | e = list_first_entry(&cfg->evt_q_list, | ||
4918 | struct brcmf_cfg80211_event_q, evt_q_list); | ||
4919 | list_del(&e->evt_q_list); | ||
4920 | kfree(e); | ||
4921 | } | ||
4922 | spin_unlock_irq(&cfg->evt_q_lock); | ||
4923 | } | ||
4924 | |||
4925 | static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg) | 4267 | static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg) |
4926 | { | 4268 | { |
4927 | s32 err = 0; | 4269 | s32 err = 0; |
4928 | 4270 | ||
4929 | cfg->scan_request = NULL; | 4271 | cfg->scan_request = NULL; |
4930 | cfg->pwr_save = true; | 4272 | cfg->pwr_save = true; |
4931 | #ifdef CONFIG_BRCMISCAN | ||
4932 | cfg->iscan_on = true; /* iscan on & off switch. | ||
4933 | we enable iscan per default */ | ||
4934 | cfg->escan_on = false; /* escan on & off switch. | ||
4935 | we disable escan per default */ | ||
4936 | #else | ||
4937 | cfg->iscan_on = false; /* iscan on & off switch. | ||
4938 | we disable iscan per default */ | ||
4939 | cfg->escan_on = true; /* escan on & off switch. | ||
4940 | we enable escan per default */ | ||
4941 | #endif | ||
4942 | cfg->roam_on = true; /* roam on & off switch. | 4273 | cfg->roam_on = true; /* roam on & off switch. |
4943 | we enable roam per default */ | 4274 | we enable roam per default */ |
4944 | |||
4945 | cfg->iscan_kickstart = false; | ||
4946 | cfg->active_scan = true; /* we do active scan for | 4275 | cfg->active_scan = true; /* we do active scan for |
4947 | specific scan per default */ | 4276 | specific scan per default */ |
4948 | cfg->dongle_up = false; /* dongle is not up yet */ | 4277 | cfg->dongle_up = false; /* dongle is not up yet */ |
4949 | brcmf_init_eq(cfg); | ||
4950 | err = brcmf_init_priv_mem(cfg); | 4278 | err = brcmf_init_priv_mem(cfg); |
4951 | if (err) | 4279 | if (err) |
4952 | return err; | 4280 | return err; |
4953 | INIT_WORK(&cfg->event_work, brcmf_cfg80211_event_handler); | 4281 | brcmf_register_event_handlers(cfg); |
4954 | brcmf_init_eloop_handler(&cfg->el); | ||
4955 | mutex_init(&cfg->usr_sync); | 4282 | mutex_init(&cfg->usr_sync); |
4956 | err = brcmf_init_iscan(cfg); | ||
4957 | if (err) | ||
4958 | return err; | ||
4959 | brcmf_init_escan(cfg); | 4283 | brcmf_init_escan(cfg); |
4960 | brcmf_init_conf(cfg->conf); | 4284 | brcmf_init_conf(cfg->conf); |
4961 | brcmf_link_down(cfg); | 4285 | brcmf_link_down(cfg); |
@@ -4965,9 +4289,7 @@ static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg) | |||
4965 | 4289 | ||
4966 | static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg) | 4290 | static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg) |
4967 | { | 4291 | { |
4968 | cancel_work_sync(&cfg->event_work); | ||
4969 | cfg->dongle_up = false; /* dongle down */ | 4292 | cfg->dongle_up = false; /* dongle down */ |
4970 | brcmf_flush_eq(cfg); | ||
4971 | brcmf_link_down(cfg); | 4293 | brcmf_link_down(cfg); |
4972 | brcmf_abort_scanning(cfg); | 4294 | brcmf_abort_scanning(cfg); |
4973 | brcmf_deinit_priv_mem(cfg); | 4295 | brcmf_deinit_priv_mem(cfg); |
@@ -5029,66 +4351,6 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg) | |||
5029 | } | 4351 | } |
5030 | } | 4352 | } |
5031 | 4353 | ||
5032 | void | ||
5033 | brcmf_cfg80211_event(struct net_device *ndev, | ||
5034 | const struct brcmf_event_msg *e, void *data) | ||
5035 | { | ||
5036 | u32 event_type = be32_to_cpu(e->event_type); | ||
5037 | struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); | ||
5038 | |||
5039 | if (!brcmf_enq_event(cfg, event_type, e, data)) | ||
5040 | schedule_work(&cfg->event_work); | ||
5041 | } | ||
5042 | |||
5043 | static s32 brcmf_dongle_eventmsg(struct net_device *ndev) | ||
5044 | { | ||
5045 | s8 eventmask[BRCMF_EVENTING_MASK_LEN]; | ||
5046 | s32 err = 0; | ||
5047 | |||
5048 | WL_TRACE("Enter\n"); | ||
5049 | |||
5050 | /* Setup event_msgs */ | ||
5051 | err = brcmf_fil_iovar_data_get(netdev_priv(ndev), "event_msgs", | ||
5052 | eventmask, BRCMF_EVENTING_MASK_LEN); | ||
5053 | if (err) { | ||
5054 | WL_ERR("Get event_msgs error (%d)\n", err); | ||
5055 | goto dongle_eventmsg_out; | ||
5056 | } | ||
5057 | |||
5058 | setbit(eventmask, BRCMF_E_SET_SSID); | ||
5059 | setbit(eventmask, BRCMF_E_ROAM); | ||
5060 | setbit(eventmask, BRCMF_E_PRUNE); | ||
5061 | setbit(eventmask, BRCMF_E_AUTH); | ||
5062 | setbit(eventmask, BRCMF_E_REASSOC); | ||
5063 | setbit(eventmask, BRCMF_E_REASSOC_IND); | ||
5064 | setbit(eventmask, BRCMF_E_DEAUTH_IND); | ||
5065 | setbit(eventmask, BRCMF_E_DISASSOC_IND); | ||
5066 | setbit(eventmask, BRCMF_E_DISASSOC); | ||
5067 | setbit(eventmask, BRCMF_E_JOIN); | ||
5068 | setbit(eventmask, BRCMF_E_ASSOC_IND); | ||
5069 | setbit(eventmask, BRCMF_E_PSK_SUP); | ||
5070 | setbit(eventmask, BRCMF_E_LINK); | ||
5071 | setbit(eventmask, BRCMF_E_NDIS_LINK); | ||
5072 | setbit(eventmask, BRCMF_E_MIC_ERROR); | ||
5073 | setbit(eventmask, BRCMF_E_PMKID_CACHE); | ||
5074 | setbit(eventmask, BRCMF_E_TXFAIL); | ||
5075 | setbit(eventmask, BRCMF_E_JOIN_START); | ||
5076 | setbit(eventmask, BRCMF_E_SCAN_COMPLETE); | ||
5077 | setbit(eventmask, BRCMF_E_ESCAN_RESULT); | ||
5078 | setbit(eventmask, BRCMF_E_PFN_NET_FOUND); | ||
5079 | |||
5080 | err = brcmf_fil_iovar_data_set(netdev_priv(ndev), "event_msgs", | ||
5081 | eventmask, BRCMF_EVENTING_MASK_LEN); | ||
5082 | if (err) { | ||
5083 | WL_ERR("Set event_msgs error (%d)\n", err); | ||
5084 | goto dongle_eventmsg_out; | ||
5085 | } | ||
5086 | |||
5087 | dongle_eventmsg_out: | ||
5088 | WL_TRACE("Exit\n"); | ||
5089 | return err; | ||
5090 | } | ||
5091 | |||
5092 | static s32 | 4354 | static s32 |
5093 | brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout) | 4355 | brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout) |
5094 | { | 4356 | { |
@@ -5190,7 +4452,7 @@ static s32 wl_update_wiphybands(struct brcmf_cfg80211_info *cfg) | |||
5190 | s8 phy; | 4452 | s8 phy; |
5191 | s32 err = 0; | 4453 | s32 err = 0; |
5192 | 4454 | ||
5193 | err = brcmf_fil_cmd_data_get(ifp, BRCM_GET_PHYLIST, | 4455 | err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST, |
5194 | &phy_list, sizeof(phy_list)); | 4456 | &phy_list, sizeof(phy_list)); |
5195 | if (err) { | 4457 | if (err) { |
5196 | WL_ERR("error (%d)\n", err); | 4458 | WL_ERR("error (%d)\n", err); |
@@ -5228,10 +4490,6 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) | |||
5228 | brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME, | 4490 | brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME, |
5229 | WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME); | 4491 | WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME); |
5230 | 4492 | ||
5231 | err = brcmf_dongle_eventmsg(ndev); | ||
5232 | if (err) | ||
5233 | goto default_conf_out; | ||
5234 | |||
5235 | power_mode = cfg->pwr_save ? PM_FAST : PM_OFF; | 4493 | power_mode = cfg->pwr_save ? PM_FAST : PM_OFF; |
5236 | err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PM, | 4494 | err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PM, |
5237 | power_mode); | 4495 | power_mode); |
@@ -5262,26 +4520,18 @@ default_conf_out: | |||
5262 | 4520 | ||
5263 | } | 4521 | } |
5264 | 4522 | ||
5265 | static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg) | 4523 | static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp) |
5266 | { | 4524 | { |
5267 | struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); | ||
5268 | s32 err = 0; | ||
5269 | |||
5270 | set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state); | 4525 | set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state); |
4526 | if (ifp->idx) | ||
4527 | return 0; | ||
5271 | 4528 | ||
5272 | err = brcmf_config_dongle(cfg); | 4529 | return brcmf_config_dongle(ifp->drvr->config); |
5273 | if (err) | ||
5274 | return err; | ||
5275 | |||
5276 | brcmf_invoke_iscan(cfg); | ||
5277 | |||
5278 | return err; | ||
5279 | } | 4530 | } |
5280 | 4531 | ||
5281 | static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg) | 4532 | static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp) |
5282 | { | 4533 | { |
5283 | struct net_device *ndev = cfg_to_ndev(cfg); | 4534 | struct brcmf_cfg80211_info *cfg = ifp->drvr->config; |
5284 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
5285 | 4535 | ||
5286 | /* | 4536 | /* |
5287 | * While going down, if associated with AP disassociate | 4537 | * While going down, if associated with AP disassociate |
@@ -5306,23 +4556,27 @@ static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg) | |||
5306 | return 0; | 4556 | return 0; |
5307 | } | 4557 | } |
5308 | 4558 | ||
5309 | s32 brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg) | 4559 | s32 brcmf_cfg80211_up(struct net_device *ndev) |
5310 | { | 4560 | { |
4561 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
4562 | struct brcmf_cfg80211_info *cfg = ifp->drvr->config; | ||
5311 | s32 err = 0; | 4563 | s32 err = 0; |
5312 | 4564 | ||
5313 | mutex_lock(&cfg->usr_sync); | 4565 | mutex_lock(&cfg->usr_sync); |
5314 | err = __brcmf_cfg80211_up(cfg); | 4566 | err = __brcmf_cfg80211_up(ifp); |
5315 | mutex_unlock(&cfg->usr_sync); | 4567 | mutex_unlock(&cfg->usr_sync); |
5316 | 4568 | ||
5317 | return err; | 4569 | return err; |
5318 | } | 4570 | } |
5319 | 4571 | ||
5320 | s32 brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg) | 4572 | s32 brcmf_cfg80211_down(struct net_device *ndev) |
5321 | { | 4573 | { |
4574 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
4575 | struct brcmf_cfg80211_info *cfg = ifp->drvr->config; | ||
5322 | s32 err = 0; | 4576 | s32 err = 0; |
5323 | 4577 | ||
5324 | mutex_lock(&cfg->usr_sync); | 4578 | mutex_lock(&cfg->usr_sync); |
5325 | err = __brcmf_cfg80211_down(cfg); | 4579 | err = __brcmf_cfg80211_down(ifp); |
5326 | mutex_unlock(&cfg->usr_sync); | 4580 | mutex_unlock(&cfg->usr_sync); |
5327 | 4581 | ||
5328 | return err; | 4582 | return err; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h index 1dd96f148ef7..e2ef8519ea84 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h | |||
@@ -84,31 +84,12 @@ do { \ | |||
84 | #define WL_CONN(fmt, args...) | 84 | #define WL_CONN(fmt, args...) |
85 | #endif /* (defined DEBUG) */ | 85 | #endif /* (defined DEBUG) */ |
86 | 86 | ||
87 | #define WL_NUM_SCAN_MAX 1 | 87 | #define WL_NUM_SCAN_MAX 10 |
88 | #define WL_NUM_PMKIDS_MAX MAXPMKID /* will be used | 88 | #define WL_NUM_PMKIDS_MAX MAXPMKID |
89 | * for 2.6.33 kernel | ||
90 | * or later | ||
91 | */ | ||
92 | #define WL_SCAN_BUF_MAX (1024 * 8) | ||
93 | #define WL_TLV_INFO_MAX 1024 | 89 | #define WL_TLV_INFO_MAX 1024 |
94 | #define WL_BSS_INFO_MAX 2048 | 90 | #define WL_BSS_INFO_MAX 2048 |
95 | #define WL_ASSOC_INFO_MAX 512 /* | 91 | #define WL_ASSOC_INFO_MAX 512 /* assoc related fil max buf */ |
96 | * needs to grab assoc info from dongle to | 92 | #define WL_EXTRA_BUF_MAX 2048 |
97 | * report it to cfg80211 through "connect" | ||
98 | * event | ||
99 | */ | ||
100 | #define WL_DCMD_LEN_MAX 1024 | ||
101 | #define WL_EXTRA_BUF_MAX 2048 | ||
102 | #define WL_ISCAN_BUF_MAX 2048 /* | ||
103 | * the buf length can be BRCMF_DCMD_MAXLEN | ||
104 | * to reduce iteration | ||
105 | */ | ||
106 | #define WL_ISCAN_TIMER_INTERVAL_MS 3000 | ||
107 | #define WL_SCAN_ERSULTS_LAST (BRCMF_SCAN_RESULTS_NO_MEM+1) | ||
108 | #define WL_AP_MAX 256 /* virtually unlimitted as long | ||
109 | * as kernel memory allows | ||
110 | */ | ||
111 | |||
112 | #define WL_ROAM_TRIGGER_LEVEL -75 | 93 | #define WL_ROAM_TRIGGER_LEVEL -75 |
113 | #define WL_ROAM_DELTA 20 | 94 | #define WL_ROAM_DELTA 20 |
114 | #define WL_BEACON_TIMEOUT 3 | 95 | #define WL_BEACON_TIMEOUT 3 |
@@ -145,12 +126,6 @@ enum wl_mode { | |||
145 | WL_MODE_AP | 126 | WL_MODE_AP |
146 | }; | 127 | }; |
147 | 128 | ||
148 | /* dongle iscan state */ | ||
149 | enum wl_iscan_state { | ||
150 | WL_ISCAN_STATE_IDLE, | ||
151 | WL_ISCAN_STATE_SCANING | ||
152 | }; | ||
153 | |||
154 | /* dongle configuration */ | 129 | /* dongle configuration */ |
155 | struct brcmf_cfg80211_conf { | 130 | struct brcmf_cfg80211_conf { |
156 | u32 mode; /* adhoc , infrastructure or ap */ | 131 | u32 mode; /* adhoc , infrastructure or ap */ |
@@ -162,17 +137,6 @@ struct brcmf_cfg80211_conf { | |||
162 | struct ieee80211_channel channel; | 137 | struct ieee80211_channel channel; |
163 | }; | 138 | }; |
164 | 139 | ||
165 | /* forward declaration */ | ||
166 | struct brcmf_cfg80211_info; | ||
167 | |||
168 | /* cfg80211 main event loop */ | ||
169 | struct brcmf_cfg80211_event_loop { | ||
170 | s32(*handler[BRCMF_E_LAST]) (struct brcmf_cfg80211_info *cfg, | ||
171 | struct net_device *ndev, | ||
172 | const struct brcmf_event_msg *e, | ||
173 | void *data); | ||
174 | }; | ||
175 | |||
176 | /* basic structure of scan request */ | 140 | /* basic structure of scan request */ |
177 | struct brcmf_cfg80211_scan_req { | 141 | struct brcmf_cfg80211_scan_req { |
178 | struct brcmf_ssid_le ssid_le; | 142 | struct brcmf_ssid_le ssid_le; |
@@ -184,14 +148,6 @@ struct brcmf_cfg80211_ie { | |||
184 | u8 buf[WL_TLV_INFO_MAX]; | 148 | u8 buf[WL_TLV_INFO_MAX]; |
185 | }; | 149 | }; |
186 | 150 | ||
187 | /* event queue for cfg80211 main event */ | ||
188 | struct brcmf_cfg80211_event_q { | ||
189 | struct list_head evt_q_list; | ||
190 | u32 etype; | ||
191 | struct brcmf_event_msg emsg; | ||
192 | s8 edata[1]; | ||
193 | }; | ||
194 | |||
195 | /* security information with currently associated ap */ | 151 | /* security information with currently associated ap */ |
196 | struct brcmf_cfg80211_security { | 152 | struct brcmf_cfg80211_security { |
197 | u32 wpa_versions; | 153 | u32 wpa_versions; |
@@ -270,26 +226,6 @@ struct brcmf_cfg80211_vif { | |||
270 | struct list_head list; | 226 | struct list_head list; |
271 | }; | 227 | }; |
272 | 228 | ||
273 | /* dongle iscan event loop */ | ||
274 | struct brcmf_cfg80211_iscan_eloop { | ||
275 | s32 (*handler[WL_SCAN_ERSULTS_LAST]) | ||
276 | (struct brcmf_cfg80211_info *cfg); | ||
277 | }; | ||
278 | |||
279 | /* dongle iscan controller */ | ||
280 | struct brcmf_cfg80211_iscan_ctrl { | ||
281 | struct net_device *ndev; | ||
282 | struct timer_list timer; | ||
283 | u32 timer_ms; | ||
284 | u32 timer_on; | ||
285 | s32 state; | ||
286 | struct work_struct work; | ||
287 | struct brcmf_cfg80211_iscan_eloop el; | ||
288 | void *data; | ||
289 | s8 dcmd_buf[BRCMF_DCMD_SMLEN]; | ||
290 | s8 scan_buf[WL_ISCAN_BUF_MAX]; | ||
291 | }; | ||
292 | |||
293 | /* association inform */ | 229 | /* association inform */ |
294 | struct brcmf_cfg80211_connect_info { | 230 | struct brcmf_cfg80211_connect_info { |
295 | u8 *req_ie; | 231 | u8 *req_ie; |
@@ -323,17 +259,6 @@ struct escan_info { | |||
323 | struct net_device *ndev; | 259 | struct net_device *ndev; |
324 | }; | 260 | }; |
325 | 261 | ||
326 | /* Structure to hold WPS, WPA IEs for a AP */ | ||
327 | struct ap_info { | ||
328 | u8 probe_res_ie[IE_MAX_LEN]; | ||
329 | u8 beacon_ie[IE_MAX_LEN]; | ||
330 | u32 probe_res_ie_len; | ||
331 | u32 beacon_ie_len; | ||
332 | u8 *wpa_ie; | ||
333 | u8 *rsn_ie; | ||
334 | bool security_mode; | ||
335 | }; | ||
336 | |||
337 | /** | 262 | /** |
338 | * struct brcmf_pno_param_le - PNO scan configuration parameters | 263 | * struct brcmf_pno_param_le - PNO scan configuration parameters |
339 | * | 264 | * |
@@ -421,24 +346,16 @@ struct brcmf_pno_scanresults_le { | |||
421 | * @wiphy: wiphy object for cfg80211 interface. | 346 | * @wiphy: wiphy object for cfg80211 interface. |
422 | * @conf: dongle configuration. | 347 | * @conf: dongle configuration. |
423 | * @scan_request: cfg80211 scan request object. | 348 | * @scan_request: cfg80211 scan request object. |
424 | * @el: main event loop. | ||
425 | * @evt_q_list: used for event queue. | ||
426 | * @evt_q_lock: for event queue synchronization. | ||
427 | * @usr_sync: mainly for dongle up/down synchronization. | 349 | * @usr_sync: mainly for dongle up/down synchronization. |
428 | * @bss_list: bss_list holding scanned ap information. | 350 | * @bss_list: bss_list holding scanned ap information. |
429 | * @scan_results: results of the last scan. | ||
430 | * @scan_req_int: internal scan request object. | 351 | * @scan_req_int: internal scan request object. |
431 | * @bss_info: bss information for cfg80211 layer. | 352 | * @bss_info: bss information for cfg80211 layer. |
432 | * @ie: information element object for internal purpose. | 353 | * @ie: information element object for internal purpose. |
433 | * @iscan: iscan controller information. | ||
434 | * @conn_info: association info. | 354 | * @conn_info: association info. |
435 | * @pmk_list: wpa2 pmk list. | 355 | * @pmk_list: wpa2 pmk list. |
436 | * @event_work: event handler work struct. | ||
437 | * @scan_status: scan activity on the dongle. | 356 | * @scan_status: scan activity on the dongle. |
438 | * @pub: common driver information. | 357 | * @pub: common driver information. |
439 | * @channel: current channel. | 358 | * @channel: current channel. |
440 | * @iscan_on: iscan on/off switch. | ||
441 | * @iscan_kickstart: indicate iscan already started. | ||
442 | * @active_scan: current scan mode. | 359 | * @active_scan: current scan mode. |
443 | * @sched_escan: e-scan for scheduled scan support running. | 360 | * @sched_escan: e-scan for scheduled scan support running. |
444 | * @ibss_starter: indicates this sta is ibss starter. | 361 | * @ibss_starter: indicates this sta is ibss starter. |
@@ -450,12 +367,10 @@ struct brcmf_pno_scanresults_le { | |||
450 | * @dcmd_buf: dcmd buffer. | 367 | * @dcmd_buf: dcmd buffer. |
451 | * @extra_buf: mainly to grab assoc information. | 368 | * @extra_buf: mainly to grab assoc information. |
452 | * @debugfsdir: debugfs folder for this device. | 369 | * @debugfsdir: debugfs folder for this device. |
453 | * @escan_on: escan on/off switch. | ||
454 | * @escan_info: escan information. | 370 | * @escan_info: escan information. |
455 | * @escan_timeout: Timer for catch scan timeout. | 371 | * @escan_timeout: Timer for catch scan timeout. |
456 | * @escan_timeout_work: scan timeout worker. | 372 | * @escan_timeout_work: scan timeout worker. |
457 | * @escan_ioctl_buf: dongle command buffer for escan commands. | 373 | * @escan_ioctl_buf: dongle command buffer for escan commands. |
458 | * @ap_info: host ap information. | ||
459 | * @vif_list: linked list of vif instances. | 374 | * @vif_list: linked list of vif instances. |
460 | * @vif_cnt: number of vif instances. | 375 | * @vif_cnt: number of vif instances. |
461 | */ | 376 | */ |
@@ -463,24 +378,16 @@ struct brcmf_cfg80211_info { | |||
463 | struct wiphy *wiphy; | 378 | struct wiphy *wiphy; |
464 | struct brcmf_cfg80211_conf *conf; | 379 | struct brcmf_cfg80211_conf *conf; |
465 | struct cfg80211_scan_request *scan_request; | 380 | struct cfg80211_scan_request *scan_request; |
466 | struct brcmf_cfg80211_event_loop el; | ||
467 | struct list_head evt_q_list; | ||
468 | spinlock_t evt_q_lock; | ||
469 | struct mutex usr_sync; | 381 | struct mutex usr_sync; |
470 | struct brcmf_scan_results *bss_list; | 382 | struct brcmf_scan_results *bss_list; |
471 | struct brcmf_scan_results *scan_results; | 383 | struct brcmf_cfg80211_scan_req scan_req_int; |
472 | struct brcmf_cfg80211_scan_req *scan_req_int; | ||
473 | struct wl_cfg80211_bss_info *bss_info; | 384 | struct wl_cfg80211_bss_info *bss_info; |
474 | struct brcmf_cfg80211_ie ie; | 385 | struct brcmf_cfg80211_ie ie; |
475 | struct brcmf_cfg80211_iscan_ctrl *iscan; | ||
476 | struct brcmf_cfg80211_connect_info conn_info; | 386 | struct brcmf_cfg80211_connect_info conn_info; |
477 | struct brcmf_cfg80211_pmk_list *pmk_list; | 387 | struct brcmf_cfg80211_pmk_list *pmk_list; |
478 | struct work_struct event_work; | ||
479 | unsigned long scan_status; | 388 | unsigned long scan_status; |
480 | struct brcmf_pub *pub; | 389 | struct brcmf_pub *pub; |
481 | u32 channel; | 390 | u32 channel; |
482 | bool iscan_on; | ||
483 | bool iscan_kickstart; | ||
484 | bool active_scan; | 391 | bool active_scan; |
485 | bool sched_escan; | 392 | bool sched_escan; |
486 | bool ibss_starter; | 393 | bool ibss_starter; |
@@ -492,12 +399,10 @@ struct brcmf_cfg80211_info { | |||
492 | u8 *dcmd_buf; | 399 | u8 *dcmd_buf; |
493 | u8 *extra_buf; | 400 | u8 *extra_buf; |
494 | struct dentry *debugfsdir; | 401 | struct dentry *debugfsdir; |
495 | bool escan_on; | ||
496 | struct escan_info escan_info; | 402 | struct escan_info escan_info; |
497 | struct timer_list escan_timeout; | 403 | struct timer_list escan_timeout; |
498 | struct work_struct escan_timeout_work; | 404 | struct work_struct escan_timeout_work; |
499 | u8 *escan_ioctl_buf; | 405 | u8 *escan_ioctl_buf; |
500 | struct ap_info *ap_info; | ||
501 | struct list_head vif_list; | 406 | struct list_head vif_list; |
502 | u8 vif_cnt; | 407 | u8 vif_cnt; |
503 | }; | 408 | }; |
@@ -536,8 +441,11 @@ static inline struct brcmf_cfg80211_profile *ndev_to_prof(struct net_device *nd) | |||
536 | return &ifp->vif->profile; | 441 | return &ifp->vif->profile; |
537 | } | 442 | } |
538 | 443 | ||
539 | #define iscan_to_cfg(i) ((struct brcmf_cfg80211_info *)(i->data)) | 444 | static inline struct brcmf_cfg80211_vif *ndev_to_vif(struct net_device *ndev) |
540 | #define cfg_to_iscan(w) (w->iscan) | 445 | { |
446 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
447 | return ifp->vif; | ||
448 | } | ||
541 | 449 | ||
542 | static inline struct | 450 | static inline struct |
543 | brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_info *cfg) | 451 | brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_info *cfg) |
@@ -547,11 +455,7 @@ brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_info *cfg) | |||
547 | 455 | ||
548 | struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr); | 456 | struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr); |
549 | void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg); | 457 | void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg); |
550 | 458 | s32 brcmf_cfg80211_up(struct net_device *ndev); | |
551 | /* event handler from dongle */ | 459 | s32 brcmf_cfg80211_down(struct net_device *ndev); |
552 | void brcmf_cfg80211_event(struct net_device *ndev, | ||
553 | const struct brcmf_event_msg *e, void *data); | ||
554 | s32 brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg); | ||
555 | s32 brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg); | ||
556 | 460 | ||
557 | #endif /* _wl_cfg80211_h_ */ | 461 | #endif /* _wl_cfg80211_h_ */ |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/Makefile b/drivers/net/wireless/brcm80211/brcmsmac/Makefile index e227c4c68ef9..d3d4151c3eda 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/Makefile +++ b/drivers/net/wireless/brcm80211/brcmsmac/Makefile | |||
@@ -40,7 +40,8 @@ BRCMSMAC_OFILES := \ | |||
40 | phy/phytbl_n.o \ | 40 | phy/phytbl_n.o \ |
41 | phy/phy_qmath.o \ | 41 | phy/phy_qmath.o \ |
42 | dma.o \ | 42 | dma.o \ |
43 | brcms_trace_events.o | 43 | brcms_trace_events.o \ |
44 | debug.o | ||
44 | 45 | ||
45 | MODULEPFX := brcmsmac | 46 | MODULEPFX := brcmsmac |
46 | 47 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c index be5bcfb9153b..1de94f30564f 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | |||
@@ -21,6 +21,8 @@ | |||
21 | #include "antsel.h" | 21 | #include "antsel.h" |
22 | #include "main.h" | 22 | #include "main.h" |
23 | #include "ampdu.h" | 23 | #include "ampdu.h" |
24 | #include "debug.h" | ||
25 | #include "brcms_trace_events.h" | ||
24 | 26 | ||
25 | /* max number of mpdus in an ampdu */ | 27 | /* max number of mpdus in an ampdu */ |
26 | #define AMPDU_MAX_MPDU 32 | 28 | #define AMPDU_MAX_MPDU 32 |
@@ -40,8 +42,6 @@ | |||
40 | #define AMPDU_DEF_RETRY_LIMIT 5 | 42 | #define AMPDU_DEF_RETRY_LIMIT 5 |
41 | /* default tx retry limit at reg rate */ | 43 | /* default tx retry limit at reg rate */ |
42 | #define AMPDU_DEF_RR_RETRY_LIMIT 2 | 44 | #define AMPDU_DEF_RR_RETRY_LIMIT 2 |
43 | /* default weight of ampdu in txfifo */ | ||
44 | #define AMPDU_DEF_TXPKT_WEIGHT 2 | ||
45 | /* default ffpld reserved bytes */ | 45 | /* default ffpld reserved bytes */ |
46 | #define AMPDU_DEF_FFPLD_RSVD 2048 | 46 | #define AMPDU_DEF_FFPLD_RSVD 2048 |
47 | /* # of inis to be freed on detach */ | 47 | /* # of inis to be freed on detach */ |
@@ -114,7 +114,6 @@ struct brcms_fifo_info { | |||
114 | * mpdu_density: min mpdu spacing (0-7) ==> 2^(x-1)/8 usec | 114 | * mpdu_density: min mpdu spacing (0-7) ==> 2^(x-1)/8 usec |
115 | * max_pdu: max pdus allowed in ampdu | 115 | * max_pdu: max pdus allowed in ampdu |
116 | * dur: max duration of an ampdu (in msec) | 116 | * dur: max duration of an ampdu (in msec) |
117 | * txpkt_weight: weight of ampdu in txfifo; reduces rate lag | ||
118 | * rx_factor: maximum rx ampdu factor (0-3) ==> 2^(13+x) bytes | 117 | * rx_factor: maximum rx ampdu factor (0-3) ==> 2^(13+x) bytes |
119 | * ffpld_rsvd: number of bytes to reserve for preload | 118 | * ffpld_rsvd: number of bytes to reserve for preload |
120 | * max_txlen: max size of ampdu per mcs, bw and sgi | 119 | * max_txlen: max size of ampdu per mcs, bw and sgi |
@@ -136,7 +135,6 @@ struct ampdu_info { | |||
136 | u8 mpdu_density; | 135 | u8 mpdu_density; |
137 | s8 max_pdu; | 136 | s8 max_pdu; |
138 | u8 dur; | 137 | u8 dur; |
139 | u8 txpkt_weight; | ||
140 | u8 rx_factor; | 138 | u8 rx_factor; |
141 | u32 ffpld_rsvd; | 139 | u32 ffpld_rsvd; |
142 | u32 max_txlen[MCS_TABLE_SIZE][2][2]; | 140 | u32 max_txlen[MCS_TABLE_SIZE][2][2]; |
@@ -183,18 +181,19 @@ static bool brcms_c_ampdu_cap(struct ampdu_info *ampdu) | |||
183 | static int brcms_c_ampdu_set(struct ampdu_info *ampdu, bool on) | 181 | static int brcms_c_ampdu_set(struct ampdu_info *ampdu, bool on) |
184 | { | 182 | { |
185 | struct brcms_c_info *wlc = ampdu->wlc; | 183 | struct brcms_c_info *wlc = ampdu->wlc; |
184 | struct bcma_device *core = wlc->hw->d11core; | ||
186 | 185 | ||
187 | wlc->pub->_ampdu = false; | 186 | wlc->pub->_ampdu = false; |
188 | 187 | ||
189 | if (on) { | 188 | if (on) { |
190 | if (!(wlc->pub->_n_enab & SUPPORT_11N)) { | 189 | if (!(wlc->pub->_n_enab & SUPPORT_11N)) { |
191 | wiphy_err(ampdu->wlc->wiphy, "wl%d: driver not " | 190 | brcms_err(core, "wl%d: driver not nmode enabled\n", |
192 | "nmode enabled\n", wlc->pub->unit); | 191 | wlc->pub->unit); |
193 | return -ENOTSUPP; | 192 | return -ENOTSUPP; |
194 | } | 193 | } |
195 | if (!brcms_c_ampdu_cap(ampdu)) { | 194 | if (!brcms_c_ampdu_cap(ampdu)) { |
196 | wiphy_err(ampdu->wlc->wiphy, "wl%d: device not " | 195 | brcms_err(core, "wl%d: device not ampdu capable\n", |
197 | "ampdu capable\n", wlc->pub->unit); | 196 | wlc->pub->unit); |
198 | return -ENOTSUPP; | 197 | return -ENOTSUPP; |
199 | } | 198 | } |
200 | wlc->pub->_ampdu = on; | 199 | wlc->pub->_ampdu = on; |
@@ -247,7 +246,6 @@ struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc) | |||
247 | ampdu->mpdu_density = AMPDU_DEF_MPDU_DENSITY; | 246 | ampdu->mpdu_density = AMPDU_DEF_MPDU_DENSITY; |
248 | ampdu->max_pdu = AUTO; | 247 | ampdu->max_pdu = AUTO; |
249 | ampdu->dur = AMPDU_MAX_DUR; | 248 | ampdu->dur = AMPDU_MAX_DUR; |
250 | ampdu->txpkt_weight = AMPDU_DEF_TXPKT_WEIGHT; | ||
251 | 249 | ||
252 | ampdu->ffpld_rsvd = AMPDU_DEF_FFPLD_RSVD; | 250 | ampdu->ffpld_rsvd = AMPDU_DEF_FFPLD_RSVD; |
253 | /* | 251 | /* |
@@ -374,7 +372,8 @@ static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid) | |||
374 | offsetof(struct macstat, txfunfl[fid])); | 372 | offsetof(struct macstat, txfunfl[fid])); |
375 | new_txunfl = (u16) (cur_txunfl - fifo->prev_txfunfl); | 373 | new_txunfl = (u16) (cur_txunfl - fifo->prev_txfunfl); |
376 | if (new_txunfl == 0) { | 374 | if (new_txunfl == 0) { |
377 | BCMMSG(wlc->wiphy, "TX status FRAG set but no tx underflows\n"); | 375 | brcms_dbg_ht(wlc->hw->d11core, |
376 | "TX status FRAG set but no tx underflows\n"); | ||
378 | return -1; | 377 | return -1; |
379 | } | 378 | } |
380 | fifo->prev_txfunfl = cur_txunfl; | 379 | fifo->prev_txfunfl = cur_txunfl; |
@@ -396,8 +395,8 @@ static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid) | |||
396 | if (fifo->accum_txfunfl < 10) | 395 | if (fifo->accum_txfunfl < 10) |
397 | return 0; | 396 | return 0; |
398 | 397 | ||
399 | BCMMSG(wlc->wiphy, "ampdu_count %d tx_underflows %d\n", | 398 | brcms_dbg_ht(wlc->hw->d11core, "ampdu_count %d tx_underflows %d\n", |
400 | current_ampdu_cnt, fifo->accum_txfunfl); | 399 | current_ampdu_cnt, fifo->accum_txfunfl); |
401 | 400 | ||
402 | /* | 401 | /* |
403 | compute the current ratio of tx unfl per ampdu. | 402 | compute the current ratio of tx unfl per ampdu. |
@@ -450,9 +449,10 @@ static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid) | |||
450 | (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size)) | 449 | (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size)) |
451 | / (max_mpdu * FFPLD_MPDU_SIZE)) * 100; | 450 | / (max_mpdu * FFPLD_MPDU_SIZE)) * 100; |
452 | 451 | ||
453 | BCMMSG(wlc->wiphy, "DMA estimated transfer rate %d; " | 452 | brcms_dbg_ht(wlc->hw->d11core, |
454 | "pre-load size %d\n", | 453 | "DMA estimated transfer rate %d; " |
455 | fifo->dmaxferrate, fifo->ampdu_pld_size); | 454 | "pre-load size %d\n", |
455 | fifo->dmaxferrate, fifo->ampdu_pld_size); | ||
456 | } else { | 456 | } else { |
457 | 457 | ||
458 | /* decrease ampdu size */ | 458 | /* decrease ampdu size */ |
@@ -486,7 +486,7 @@ brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid, | |||
486 | scb_ampdu = &scb->scb_ampdu; | 486 | scb_ampdu = &scb->scb_ampdu; |
487 | 487 | ||
488 | if (!ampdu->ini_enable[tid]) { | 488 | if (!ampdu->ini_enable[tid]) { |
489 | wiphy_err(ampdu->wlc->wiphy, "%s: Rejecting tid %d\n", | 489 | brcms_err(wlc->hw->d11core, "%s: Rejecting tid %d\n", |
490 | __func__, tid); | 490 | __func__, tid); |
491 | return; | 491 | return; |
492 | } | 492 | } |
@@ -498,378 +498,324 @@ brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid, | |||
498 | scb_ampdu->max_rx_ampdu_bytes = max_rx_ampdu_bytes; | 498 | scb_ampdu->max_rx_ampdu_bytes = max_rx_ampdu_bytes; |
499 | } | 499 | } |
500 | 500 | ||
501 | int | 501 | void brcms_c_ampdu_reset_session(struct brcms_ampdu_session *session, |
502 | brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi, | 502 | struct brcms_c_info *wlc) |
503 | struct sk_buff **pdu, int prec) | ||
504 | { | 503 | { |
505 | struct brcms_c_info *wlc; | 504 | session->wlc = wlc; |
506 | struct sk_buff *p, *pkt[AMPDU_MAX_MPDU]; | 505 | skb_queue_head_init(&session->skb_list); |
507 | u8 tid, ndelim; | 506 | session->max_ampdu_len = 0; /* determined from first MPDU */ |
508 | int err = 0; | 507 | session->max_ampdu_frames = 0; /* determined from first MPDU */ |
509 | u8 preamble_type = BRCMS_GF_PREAMBLE; | 508 | session->ampdu_len = 0; |
510 | u8 fbr_preamble_type = BRCMS_GF_PREAMBLE; | 509 | session->dma_len = 0; |
511 | u8 rts_preamble_type = BRCMS_LONG_PREAMBLE; | 510 | } |
512 | u8 rts_fbr_preamble_type = BRCMS_LONG_PREAMBLE; | ||
513 | 511 | ||
514 | bool rr = true, fbr = false; | 512 | /* |
515 | uint i, count = 0, fifo, seg_cnt = 0; | 513 | * Preps the given packet for AMPDU based on the session data. If the |
516 | u16 plen, len, seq = 0, mcl, mch, index, frameid, dma_len = 0; | 514 | * frame cannot be accomodated in the current session, -ENOSPC is |
517 | u32 ampdu_len, max_ampdu_bytes = 0; | 515 | * returned. |
518 | struct d11txh *txh = NULL; | 516 | */ |
517 | int brcms_c_ampdu_add_frame(struct brcms_ampdu_session *session, | ||
518 | struct sk_buff *p) | ||
519 | { | ||
520 | struct brcms_c_info *wlc = session->wlc; | ||
521 | struct ampdu_info *ampdu = wlc->ampdu; | ||
522 | struct scb *scb = &wlc->pri_scb; | ||
523 | struct scb_ampdu *scb_ampdu = &scb->scb_ampdu; | ||
524 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p); | ||
525 | struct ieee80211_tx_rate *txrate = tx_info->status.rates; | ||
526 | struct d11txh *txh = (struct d11txh *)p->data; | ||
527 | unsigned ampdu_frames; | ||
528 | u8 ndelim, tid; | ||
519 | u8 *plcp; | 529 | u8 *plcp; |
520 | struct ieee80211_hdr *h; | 530 | uint len; |
521 | struct scb *scb; | 531 | u16 mcl; |
522 | struct scb_ampdu *scb_ampdu; | ||
523 | struct scb_ampdu_tid_ini *ini; | ||
524 | u8 mcs = 0; | ||
525 | bool use_rts = false, use_cts = false; | ||
526 | u32 rspec = 0, rspec_fallback = 0; | ||
527 | u32 rts_rspec = 0, rts_rspec_fallback = 0; | ||
528 | u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ; | ||
529 | struct ieee80211_rts *rts; | ||
530 | u8 rr_retry_limit; | ||
531 | struct brcms_fifo_info *f; | ||
532 | bool fbr_iscck; | 532 | bool fbr_iscck; |
533 | struct ieee80211_tx_info *tx_info; | 533 | bool rr; |
534 | u16 qlen; | ||
535 | struct wiphy *wiphy; | ||
536 | |||
537 | wlc = ampdu->wlc; | ||
538 | wiphy = wlc->wiphy; | ||
539 | p = *pdu; | ||
540 | |||
541 | tid = (u8) (p->priority); | ||
542 | 534 | ||
543 | f = ampdu->fifo_tb + prio2fifo[tid]; | 535 | ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM]; |
536 | plcp = (u8 *)(txh + 1); | ||
537 | fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x03); | ||
538 | len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) : | ||
539 | BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback); | ||
540 | len = roundup(len, 4) + (ndelim + 1) * AMPDU_DELIMITER_LEN; | ||
544 | 541 | ||
545 | scb = &wlc->pri_scb; | 542 | ampdu_frames = skb_queue_len(&session->skb_list); |
546 | scb_ampdu = &scb->scb_ampdu; | 543 | if (ampdu_frames != 0) { |
547 | ini = &scb_ampdu->ini[tid]; | 544 | struct sk_buff *first; |
548 | 545 | ||
549 | /* Let pressure continue to build ... */ | 546 | if (ampdu_frames + 1 > session->max_ampdu_frames || |
550 | qlen = pktq_plen(&qi->q, prec); | 547 | session->ampdu_len + len > session->max_ampdu_len) |
551 | if (ini->tx_in_transit > 0 && | 548 | return -ENOSPC; |
552 | qlen < min(scb_ampdu->max_pdu, ini->ba_wsize)) | ||
553 | /* Collect multiple MPDU's to be sent in the next AMPDU */ | ||
554 | return -EBUSY; | ||
555 | 549 | ||
556 | /* at this point we intend to transmit an AMPDU */ | 550 | /* |
557 | rr_retry_limit = ampdu->rr_retry_limit_tid[tid]; | 551 | * We aren't really out of space if the new frame is of |
558 | ampdu_len = 0; | 552 | * a different priority, but we want the same behaviour |
559 | dma_len = 0; | 553 | * so return -ENOSPC anyway. |
560 | while (p) { | 554 | * |
561 | struct ieee80211_tx_rate *txrate; | 555 | * XXX: The old AMPDU code did this, but is it really |
562 | 556 | * necessary? | |
563 | tx_info = IEEE80211_SKB_CB(p); | 557 | */ |
564 | txrate = tx_info->status.rates; | 558 | first = skb_peek(&session->skb_list); |
559 | if (p->priority != first->priority) | ||
560 | return -ENOSPC; | ||
561 | } | ||
565 | 562 | ||
566 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { | 563 | /* |
567 | err = brcms_c_prep_pdu(wlc, p, &fifo); | 564 | * Now that we're sure this frame can be accomodated, update the |
568 | } else { | 565 | * session information. |
569 | wiphy_err(wiphy, "%s: AMPDU flag is off!\n", __func__); | 566 | */ |
570 | *pdu = NULL; | 567 | session->ampdu_len += len; |
571 | err = 0; | 568 | session->dma_len += p->len; |
572 | break; | ||
573 | } | ||
574 | 569 | ||
575 | if (err) { | 570 | tid = (u8)p->priority; |
576 | if (err == -EBUSY) { | ||
577 | wiphy_err(wiphy, "wl%d: sendampdu: " | ||
578 | "prep_xdu retry; seq 0x%x\n", | ||
579 | wlc->pub->unit, seq); | ||
580 | *pdu = p; | ||
581 | break; | ||
582 | } | ||
583 | 571 | ||
584 | /* error in the packet; reject it */ | 572 | /* Handle retry limits */ |
585 | wiphy_err(wiphy, "wl%d: sendampdu: prep_xdu " | 573 | if (txrate[0].count <= ampdu->rr_retry_limit_tid[tid]) { |
586 | "rejected; seq 0x%x\n", wlc->pub->unit, seq); | 574 | txrate[0].count++; |
587 | *pdu = NULL; | 575 | rr = true; |
588 | break; | 576 | } else { |
589 | } | 577 | txrate[1].count++; |
578 | rr = false; | ||
579 | } | ||
590 | 580 | ||
591 | /* pkt is good to be aggregated */ | 581 | if (ampdu_frames == 0) { |
592 | txh = (struct d11txh *) p->data; | 582 | u8 plcp0, plcp3, is40, sgi, mcs; |
593 | plcp = (u8 *) (txh + 1); | 583 | uint fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK; |
594 | h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN); | 584 | struct brcms_fifo_info *f = &du->fifo_tb[fifo]; |
595 | seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT; | ||
596 | index = TX_SEQ_TO_INDEX(seq); | ||
597 | 585 | ||
598 | /* check mcl fields and test whether it can be agg'd */ | 586 | if (rr) { |
599 | mcl = le16_to_cpu(txh->MacTxControlLow); | 587 | plcp0 = plcp[0]; |
600 | mcl &= ~TXC_AMPDU_MASK; | 588 | plcp3 = plcp[3]; |
601 | fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x3); | ||
602 | txh->PreloadSize = 0; /* always default to 0 */ | ||
603 | |||
604 | /* Handle retry limits */ | ||
605 | if (txrate[0].count <= rr_retry_limit) { | ||
606 | txrate[0].count++; | ||
607 | rr = true; | ||
608 | fbr = false; | ||
609 | } else { | 589 | } else { |
610 | fbr = true; | 590 | plcp0 = txh->FragPLCPFallback[0]; |
611 | rr = false; | 591 | plcp3 = txh->FragPLCPFallback[3]; |
612 | txrate[1].count++; | ||
613 | } | ||
614 | |||
615 | /* extract the length info */ | ||
616 | len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) | ||
617 | : BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback); | ||
618 | |||
619 | /* retrieve null delimiter count */ | ||
620 | ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM]; | ||
621 | seg_cnt += 1; | ||
622 | 592 | ||
623 | BCMMSG(wlc->wiphy, "wl%d: mpdu %d plcp_len %d\n", | ||
624 | wlc->pub->unit, count, len); | ||
625 | |||
626 | /* | ||
627 | * aggregateable mpdu. For ucode/hw agg, | ||
628 | * test whether need to break or change the epoch | ||
629 | */ | ||
630 | if (count == 0) { | ||
631 | mcl |= (TXC_AMPDU_FIRST << TXC_AMPDU_SHIFT); | ||
632 | /* refill the bits since might be a retx mpdu */ | ||
633 | mcl |= TXC_STARTMSDU; | ||
634 | rts = (struct ieee80211_rts *)&txh->rts_frame; | ||
635 | |||
636 | if (ieee80211_is_rts(rts->frame_control)) { | ||
637 | mcl |= TXC_SENDRTS; | ||
638 | use_rts = true; | ||
639 | } | ||
640 | if (ieee80211_is_cts(rts->frame_control)) { | ||
641 | mcl |= TXC_SENDCTS; | ||
642 | use_cts = true; | ||
643 | } | ||
644 | } else { | ||
645 | mcl |= (TXC_AMPDU_MIDDLE << TXC_AMPDU_SHIFT); | ||
646 | mcl &= ~(TXC_STARTMSDU | TXC_SENDRTS | TXC_SENDCTS); | ||
647 | } | 593 | } |
648 | 594 | ||
649 | len = roundup(len, 4); | 595 | /* Limit AMPDU size based on MCS */ |
650 | ampdu_len += (len + (ndelim + 1) * AMPDU_DELIMITER_LEN); | 596 | is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0; |
597 | sgi = plcp3_issgi(plcp3) ? 1 : 0; | ||
598 | mcs = plcp0 & ~MIMO_PLCP_40MHZ; | ||
599 | session->max_ampdu_len = min(scb_ampdu->max_rx_ampdu_bytes, | ||
600 | ampdu->max_txlen[mcs][is40][sgi]); | ||
651 | 601 | ||
652 | dma_len += (u16) p->len; | 602 | session->max_ampdu_frames = scb_ampdu->max_pdu; |
603 | if (mcs_2_rate(mcs, true, false) >= f->dmaxferrate) { | ||
604 | session->max_ampdu_frames = | ||
605 | min_t(u16, f->mcs2ampdu_table[mcs], | ||
606 | session->max_ampdu_frames); | ||
607 | } | ||
608 | } | ||
653 | 609 | ||
654 | BCMMSG(wlc->wiphy, "wl%d: ampdu_len %d" | 610 | /* |
655 | " seg_cnt %d null delim %d\n", | 611 | * Treat all frames as "middle" frames of AMPDU here. First and |
656 | wlc->pub->unit, ampdu_len, seg_cnt, ndelim); | 612 | * last frames must be fixed up after all MPDUs have been prepped. |
613 | */ | ||
614 | mcl = le16_to_cpu(txh->MacTxControlLow); | ||
615 | mcl &= ~TXC_AMPDU_MASK; | ||
616 | mcl |= (TXC_AMPDU_MIDDLE << TXC_AMPDU_SHIFT); | ||
617 | mcl &= ~(TXC_STARTMSDU | TXC_SENDRTS | TXC_SENDCTS); | ||
618 | txh->MacTxControlLow = cpu_to_le16(mcl); | ||
619 | txh->PreloadSize = 0; /* always default to 0 */ | ||
657 | 620 | ||
658 | txh->MacTxControlLow = cpu_to_le16(mcl); | 621 | skb_queue_tail(&session->skb_list, p); |
659 | 622 | ||
660 | /* this packet is added */ | 623 | return 0; |
661 | pkt[count++] = p; | 624 | } |
662 | 625 | ||
663 | /* patch the first MPDU */ | 626 | void brcms_c_ampdu_finalize(struct brcms_ampdu_session *session) |
664 | if (count == 1) { | 627 | { |
665 | u8 plcp0, plcp3, is40, sgi; | 628 | struct brcms_c_info *wlc = session->wlc; |
629 | struct ampdu_info *ampdu = wlc->ampdu; | ||
630 | struct sk_buff *first, *last; | ||
631 | struct d11txh *txh; | ||
632 | struct ieee80211_tx_info *tx_info; | ||
633 | struct ieee80211_tx_rate *txrate; | ||
634 | u8 ndelim; | ||
635 | u8 *plcp; | ||
636 | uint len; | ||
637 | uint fifo; | ||
638 | struct brcms_fifo_info *f; | ||
639 | u16 mcl; | ||
640 | bool fbr; | ||
641 | bool fbr_iscck; | ||
642 | struct ieee80211_rts *rts; | ||
643 | bool use_rts = false, use_cts = false; | ||
644 | u16 dma_len = session->dma_len; | ||
645 | u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ; | ||
646 | u32 rspec = 0, rspec_fallback = 0; | ||
647 | u32 rts_rspec = 0, rts_rspec_fallback = 0; | ||
648 | u8 plcp0, plcp3, is40, sgi, mcs; | ||
649 | u16 mch; | ||
650 | u8 preamble_type = BRCMS_GF_PREAMBLE; | ||
651 | u8 fbr_preamble_type = BRCMS_GF_PREAMBLE; | ||
652 | u8 rts_preamble_type = BRCMS_LONG_PREAMBLE; | ||
653 | u8 rts_fbr_preamble_type = BRCMS_LONG_PREAMBLE; | ||
666 | 654 | ||
667 | if (rr) { | 655 | if (skb_queue_empty(&session->skb_list)) |
668 | plcp0 = plcp[0]; | 656 | return; |
669 | plcp3 = plcp[3]; | ||
670 | } else { | ||
671 | plcp0 = txh->FragPLCPFallback[0]; | ||
672 | plcp3 = txh->FragPLCPFallback[3]; | ||
673 | 657 | ||
674 | } | 658 | first = skb_peek(&session->skb_list); |
675 | is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0; | 659 | last = skb_peek_tail(&session->skb_list); |
676 | sgi = plcp3_issgi(plcp3) ? 1 : 0; | 660 | |
677 | mcs = plcp0 & ~MIMO_PLCP_40MHZ; | 661 | /* Need to fix up last MPDU first to adjust AMPDU length */ |
678 | max_ampdu_bytes = | 662 | txh = (struct d11txh *)last->data; |
679 | min(scb_ampdu->max_rx_ampdu_bytes, | 663 | fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK; |
680 | ampdu->max_txlen[mcs][is40][sgi]); | 664 | f = &du->fifo_tb[fifo]; |
681 | 665 | ||
682 | if (is40) | 666 | mcl = le16_to_cpu(txh->MacTxControlLow); |
683 | mimo_ctlchbw = | 667 | mcl &= ~TXC_AMPDU_MASK; |
684 | CHSPEC_SB_UPPER(wlc_phy_chanspec_get( | 668 | mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT); |
685 | wlc->band->pi)) | 669 | txh->MacTxControlLow = cpu_to_le16(mcl); |
686 | ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ; | 670 | |
687 | 671 | /* remove the null delimiter after last mpdu */ | |
688 | /* rebuild the rspec and rspec_fallback */ | 672 | ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM]; |
689 | rspec = RSPEC_MIMORATE; | 673 | txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = 0; |
690 | rspec |= plcp[0] & ~MIMO_PLCP_40MHZ; | 674 | session->ampdu_len -= ndelim * AMPDU_DELIMITER_LEN; |
691 | if (plcp[0] & MIMO_PLCP_40MHZ) | 675 | |
692 | rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT); | 676 | /* remove the pad len from last mpdu */ |
693 | 677 | fbr_iscck = ((le16_to_cpu(txh->XtraFrameTypes) & 0x3) == 0); | |
694 | if (fbr_iscck) /* CCK */ | 678 | len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) : |
695 | rspec_fallback = cck_rspec(cck_phy2mac_rate | 679 | BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback); |
696 | (txh->FragPLCPFallback[0])); | 680 | session->ampdu_len -= roundup(len, 4) - len; |
697 | else { /* MIMO */ | 681 | |
698 | rspec_fallback = RSPEC_MIMORATE; | 682 | /* Now fix up the first MPDU */ |
699 | rspec_fallback |= | 683 | tx_info = IEEE80211_SKB_CB(first); |
700 | txh->FragPLCPFallback[0] & ~MIMO_PLCP_40MHZ; | 684 | txrate = tx_info->status.rates; |
701 | if (txh->FragPLCPFallback[0] & MIMO_PLCP_40MHZ) | 685 | txh = (struct d11txh *)first->data; |
702 | rspec_fallback |= | 686 | plcp = (u8 *)(txh + 1); |
703 | (PHY_TXC1_BW_40MHZ << | 687 | rts = (struct ieee80211_rts *)&txh->rts_frame; |
704 | RSPEC_BW_SHIFT); | 688 | |
705 | } | 689 | mcl = le16_to_cpu(txh->MacTxControlLow); |
690 | /* If only one MPDU leave it marked as last */ | ||
691 | if (first != last) { | ||
692 | mcl &= ~TXC_AMPDU_MASK; | ||
693 | mcl |= (TXC_AMPDU_FIRST << TXC_AMPDU_SHIFT); | ||
694 | } | ||
695 | mcl |= TXC_STARTMSDU; | ||
696 | if (ieee80211_is_rts(rts->frame_control)) { | ||
697 | mcl |= TXC_SENDRTS; | ||
698 | use_rts = true; | ||
699 | } | ||
700 | if (ieee80211_is_cts(rts->frame_control)) { | ||
701 | mcl |= TXC_SENDCTS; | ||
702 | use_cts = true; | ||
703 | } | ||
704 | txh->MacTxControlLow = cpu_to_le16(mcl); | ||
706 | 705 | ||
707 | if (use_rts || use_cts) { | 706 | fbr = txrate[1].count > 0; |
708 | rts_rspec = | 707 | if (!fbr) { |
709 | brcms_c_rspec_to_rts_rspec(wlc, | 708 | plcp0 = plcp[0]; |
710 | rspec, false, mimo_ctlchbw); | 709 | plcp3 = plcp[3]; |
711 | rts_rspec_fallback = | 710 | } else { |
712 | brcms_c_rspec_to_rts_rspec(wlc, | 711 | plcp0 = txh->FragPLCPFallback[0]; |
713 | rspec_fallback, false, mimo_ctlchbw); | 712 | plcp3 = txh->FragPLCPFallback[3]; |
714 | } | 713 | } |
715 | } | 714 | is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0; |
715 | sgi = plcp3_issgi(plcp3) ? 1 : 0; | ||
716 | mcs = plcp0 & ~MIMO_PLCP_40MHZ; | ||
717 | |||
718 | if (is40) { | ||
719 | if (CHSPEC_SB_UPPER(wlc_phy_chanspec_get(wlc->band->pi))) | ||
720 | mimo_ctlchbw = PHY_TXC1_BW_20MHZ_UP; | ||
721 | else | ||
722 | mimo_ctlchbw = PHY_TXC1_BW_20MHZ; | ||
723 | } | ||
716 | 724 | ||
717 | /* if (first mpdu for host agg) */ | 725 | /* rebuild the rspec and rspec_fallback */ |
718 | /* test whether to add more */ | 726 | rspec = RSPEC_MIMORATE; |
719 | if ((mcs_2_rate(mcs, true, false) >= f->dmaxferrate) && | 727 | rspec |= plcp[0] & ~MIMO_PLCP_40MHZ; |
720 | (count == f->mcs2ampdu_table[mcs])) { | 728 | if (plcp[0] & MIMO_PLCP_40MHZ) |
721 | BCMMSG(wlc->wiphy, "wl%d: PR 37644: stopping" | 729 | rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT); |
722 | " ampdu at %d for mcs %d\n", | ||
723 | wlc->pub->unit, count, mcs); | ||
724 | break; | ||
725 | } | ||
726 | 730 | ||
727 | if (count == scb_ampdu->max_pdu) | 731 | fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x03); |
728 | break; | 732 | if (fbr_iscck) { |
733 | rspec_fallback = | ||
734 | cck_rspec(cck_phy2mac_rate(txh->FragPLCPFallback[0])); | ||
735 | } else { | ||
736 | rspec_fallback = RSPEC_MIMORATE; | ||
737 | rspec_fallback |= txh->FragPLCPFallback[0] & ~MIMO_PLCP_40MHZ; | ||
738 | if (txh->FragPLCPFallback[0] & MIMO_PLCP_40MHZ) | ||
739 | rspec_fallback |= PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT; | ||
740 | } | ||
729 | 741 | ||
730 | /* | 742 | if (use_rts || use_cts) { |
731 | * check to see if the next pkt is | 743 | rts_rspec = |
732 | * a candidate for aggregation | 744 | brcms_c_rspec_to_rts_rspec(wlc, rspec, |
733 | */ | 745 | false, mimo_ctlchbw); |
734 | p = pktq_ppeek(&qi->q, prec); | 746 | rts_rspec_fallback = |
735 | if (p) { | 747 | brcms_c_rspec_to_rts_rspec(wlc, rspec_fallback, |
736 | tx_info = IEEE80211_SKB_CB(p); | 748 | false, mimo_ctlchbw); |
737 | if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && | 749 | } |
738 | ((u8) (p->priority) == tid)) { | ||
739 | plen = p->len + AMPDU_MAX_MPDU_OVERHEAD; | ||
740 | plen = max(scb_ampdu->min_len, plen); | ||
741 | 750 | ||
742 | if ((plen + ampdu_len) > max_ampdu_bytes) { | 751 | BRCMS_SET_MIMO_PLCP_LEN(plcp, session->ampdu_len); |
743 | p = NULL; | 752 | /* mark plcp to indicate ampdu */ |
744 | continue; | 753 | BRCMS_SET_MIMO_PLCP_AMPDU(plcp); |
745 | } | ||
746 | 754 | ||
747 | /* | 755 | /* reset the mixed mode header durations */ |
748 | * check if there are enough | 756 | if (txh->MModeLen) { |
749 | * descriptors available | 757 | u16 mmodelen = brcms_c_calc_lsig_len(wlc, rspec, |
750 | */ | 758 | session->ampdu_len); |
751 | if (*wlc->core->txavail[fifo] <= seg_cnt + 1) { | 759 | txh->MModeLen = cpu_to_le16(mmodelen); |
752 | wiphy_err(wiphy, "%s: No fifo space " | 760 | preamble_type = BRCMS_MM_PREAMBLE; |
753 | "!!\n", __func__); | 761 | } |
754 | p = NULL; | 762 | if (txh->MModeFbrLen) { |
755 | continue; | 763 | u16 mmfbrlen = brcms_c_calc_lsig_len(wlc, rspec_fallback, |
756 | } | 764 | session->ampdu_len); |
757 | /* next packet fit for aggregation so dequeue */ | 765 | txh->MModeFbrLen = cpu_to_le16(mmfbrlen); |
758 | p = brcmu_pktq_pdeq(&qi->q, prec); | 766 | fbr_preamble_type = BRCMS_MM_PREAMBLE; |
759 | } else { | 767 | } |
760 | p = NULL; | ||
761 | } | ||
762 | } | ||
763 | } /* end while(p) */ | ||
764 | 768 | ||
765 | ini->tx_in_transit += count; | 769 | /* set the preload length */ |
770 | if (mcs_2_rate(mcs, true, false) >= f->dmaxferrate) { | ||
771 | dma_len = min(dma_len, f->ampdu_pld_size); | ||
772 | txh->PreloadSize = cpu_to_le16(dma_len); | ||
773 | } else { | ||
774 | txh->PreloadSize = 0; | ||
775 | } | ||
766 | 776 | ||
767 | if (count) { | 777 | mch = le16_to_cpu(txh->MacTxControlHigh); |
768 | /* patch up the last txh */ | ||
769 | txh = (struct d11txh *) pkt[count - 1]->data; | ||
770 | mcl = le16_to_cpu(txh->MacTxControlLow); | ||
771 | mcl &= ~TXC_AMPDU_MASK; | ||
772 | mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT); | ||
773 | txh->MacTxControlLow = cpu_to_le16(mcl); | ||
774 | |||
775 | /* remove the null delimiter after last mpdu */ | ||
776 | ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM]; | ||
777 | txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = 0; | ||
778 | ampdu_len -= ndelim * AMPDU_DELIMITER_LEN; | ||
779 | |||
780 | /* remove the pad len from last mpdu */ | ||
781 | fbr_iscck = ((le16_to_cpu(txh->XtraFrameTypes) & 0x3) == 0); | ||
782 | len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) | ||
783 | : BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback); | ||
784 | ampdu_len -= roundup(len, 4) - len; | ||
785 | |||
786 | /* patch up the first txh & plcp */ | ||
787 | txh = (struct d11txh *) pkt[0]->data; | ||
788 | plcp = (u8 *) (txh + 1); | ||
789 | 778 | ||
790 | BRCMS_SET_MIMO_PLCP_LEN(plcp, ampdu_len); | 779 | /* update RTS dur fields */ |
791 | /* mark plcp to indicate ampdu */ | 780 | if (use_rts || use_cts) { |
792 | BRCMS_SET_MIMO_PLCP_AMPDU(plcp); | 781 | u16 durid; |
782 | if ((mch & TXC_PREAMBLE_RTS_MAIN_SHORT) == | ||
783 | TXC_PREAMBLE_RTS_MAIN_SHORT) | ||
784 | rts_preamble_type = BRCMS_SHORT_PREAMBLE; | ||
793 | 785 | ||
794 | /* reset the mixed mode header durations */ | 786 | if ((mch & TXC_PREAMBLE_RTS_FB_SHORT) == |
795 | if (txh->MModeLen) { | 787 | TXC_PREAMBLE_RTS_FB_SHORT) |
796 | u16 mmodelen = | 788 | rts_fbr_preamble_type = BRCMS_SHORT_PREAMBLE; |
797 | brcms_c_calc_lsig_len(wlc, rspec, ampdu_len); | ||
798 | txh->MModeLen = cpu_to_le16(mmodelen); | ||
799 | preamble_type = BRCMS_MM_PREAMBLE; | ||
800 | } | ||
801 | if (txh->MModeFbrLen) { | ||
802 | u16 mmfbrlen = | ||
803 | brcms_c_calc_lsig_len(wlc, rspec_fallback, | ||
804 | ampdu_len); | ||
805 | txh->MModeFbrLen = cpu_to_le16(mmfbrlen); | ||
806 | fbr_preamble_type = BRCMS_MM_PREAMBLE; | ||
807 | } | ||
808 | 789 | ||
809 | /* set the preload length */ | 790 | durid = brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec, |
810 | if (mcs_2_rate(mcs, true, false) >= f->dmaxferrate) { | ||
811 | dma_len = min(dma_len, f->ampdu_pld_size); | ||
812 | txh->PreloadSize = cpu_to_le16(dma_len); | ||
813 | } else | ||
814 | txh->PreloadSize = 0; | ||
815 | |||
816 | mch = le16_to_cpu(txh->MacTxControlHigh); | ||
817 | |||
818 | /* update RTS dur fields */ | ||
819 | if (use_rts || use_cts) { | ||
820 | u16 durid; | ||
821 | rts = (struct ieee80211_rts *)&txh->rts_frame; | ||
822 | if ((mch & TXC_PREAMBLE_RTS_MAIN_SHORT) == | ||
823 | TXC_PREAMBLE_RTS_MAIN_SHORT) | ||
824 | rts_preamble_type = BRCMS_SHORT_PREAMBLE; | ||
825 | |||
826 | if ((mch & TXC_PREAMBLE_RTS_FB_SHORT) == | ||
827 | TXC_PREAMBLE_RTS_FB_SHORT) | ||
828 | rts_fbr_preamble_type = BRCMS_SHORT_PREAMBLE; | ||
829 | |||
830 | durid = | ||
831 | brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec, | ||
832 | rspec, rts_preamble_type, | 791 | rspec, rts_preamble_type, |
833 | preamble_type, ampdu_len, | 792 | preamble_type, |
834 | true); | 793 | session->ampdu_len, true); |
835 | rts->duration = cpu_to_le16(durid); | 794 | rts->duration = cpu_to_le16(durid); |
836 | durid = brcms_c_compute_rtscts_dur(wlc, use_cts, | 795 | durid = brcms_c_compute_rtscts_dur(wlc, use_cts, |
837 | rts_rspec_fallback, | 796 | rts_rspec_fallback, |
838 | rspec_fallback, | 797 | rspec_fallback, |
839 | rts_fbr_preamble_type, | 798 | rts_fbr_preamble_type, |
840 | fbr_preamble_type, | 799 | fbr_preamble_type, |
841 | ampdu_len, true); | 800 | session->ampdu_len, true); |
842 | txh->RTSDurFallback = cpu_to_le16(durid); | 801 | txh->RTSDurFallback = cpu_to_le16(durid); |
843 | /* set TxFesTimeNormal */ | 802 | /* set TxFesTimeNormal */ |
844 | txh->TxFesTimeNormal = rts->duration; | 803 | txh->TxFesTimeNormal = rts->duration; |
845 | /* set fallback rate version of TxFesTimeNormal */ | 804 | /* set fallback rate version of TxFesTimeNormal */ |
846 | txh->TxFesTimeFallback = txh->RTSDurFallback; | 805 | txh->TxFesTimeFallback = txh->RTSDurFallback; |
847 | } | 806 | } |
848 | |||
849 | /* set flag and plcp for fallback rate */ | ||
850 | if (fbr) { | ||
851 | mch |= TXC_AMPDU_FBR; | ||
852 | txh->MacTxControlHigh = cpu_to_le16(mch); | ||
853 | BRCMS_SET_MIMO_PLCP_AMPDU(plcp); | ||
854 | BRCMS_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback); | ||
855 | } | ||
856 | |||
857 | BCMMSG(wlc->wiphy, "wl%d: count %d ampdu_len %d\n", | ||
858 | wlc->pub->unit, count, ampdu_len); | ||
859 | |||
860 | /* inform rate_sel if it this is a rate probe pkt */ | ||
861 | frameid = le16_to_cpu(txh->TxFrameID); | ||
862 | if (frameid & TXFID_RATE_PROBE_MASK) | ||
863 | wiphy_err(wiphy, "%s: XXX what to do with " | ||
864 | "TXFID_RATE_PROBE_MASK!?\n", __func__); | ||
865 | |||
866 | for (i = 0; i < count; i++) | ||
867 | brcms_c_txfifo(wlc, fifo, pkt[i], i == (count - 1), | ||
868 | ampdu->txpkt_weight); | ||
869 | 807 | ||
808 | /* set flag and plcp for fallback rate */ | ||
809 | if (fbr) { | ||
810 | mch |= TXC_AMPDU_FBR; | ||
811 | txh->MacTxControlHigh = cpu_to_le16(mch); | ||
812 | BRCMS_SET_MIMO_PLCP_AMPDU(plcp); | ||
813 | BRCMS_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback); | ||
870 | } | 814 | } |
871 | /* endif (count) */ | 815 | |
872 | return err; | 816 | brcms_dbg_ht(wlc->hw->d11core, "wl%d: count %d ampdu_len %d\n", |
817 | wlc->pub->unit, skb_queue_len(&session->skb_list), | ||
818 | session->ampdu_len); | ||
873 | } | 819 | } |
874 | 820 | ||
875 | static void | 821 | static void |
@@ -909,7 +855,6 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, | |||
909 | u8 antselid = 0; | 855 | u8 antselid = 0; |
910 | u8 retry_limit, rr_retry_limit; | 856 | u8 retry_limit, rr_retry_limit; |
911 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p); | 857 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p); |
912 | struct wiphy *wiphy = wlc->wiphy; | ||
913 | 858 | ||
914 | #ifdef DEBUG | 859 | #ifdef DEBUG |
915 | u8 hole[AMPDU_MAX_MPDU]; | 860 | u8 hole[AMPDU_MAX_MPDU]; |
@@ -955,13 +900,14 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, | |||
955 | if (supr_status) { | 900 | if (supr_status) { |
956 | update_rate = false; | 901 | update_rate = false; |
957 | if (supr_status == TX_STATUS_SUPR_BADCH) { | 902 | if (supr_status == TX_STATUS_SUPR_BADCH) { |
958 | wiphy_err(wiphy, | 903 | brcms_err(wlc->hw->d11core, |
959 | "%s: Pkt tx suppressed, illegal channel possibly %d\n", | 904 | "%s: Pkt tx suppressed, illegal channel possibly %d\n", |
960 | __func__, CHSPEC_CHANNEL( | 905 | __func__, CHSPEC_CHANNEL( |
961 | wlc->default_bss->chanspec)); | 906 | wlc->default_bss->chanspec)); |
962 | } else { | 907 | } else { |
963 | if (supr_status != TX_STATUS_SUPR_FRAG) | 908 | if (supr_status != TX_STATUS_SUPR_FRAG) |
964 | wiphy_err(wiphy, "%s: supr_status 0x%x\n", | 909 | brcms_err(wlc->hw->d11core, |
910 | "%s: supr_status 0x%x\n", | ||
965 | __func__, supr_status); | 911 | __func__, supr_status); |
966 | } | 912 | } |
967 | /* no need to retry for badch; will fail again */ | 913 | /* no need to retry for badch; will fail again */ |
@@ -977,20 +923,14 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, | |||
977 | * if there were underflows, but pre-loading | 923 | * if there were underflows, but pre-loading |
978 | * is not active, notify rate adaptation. | 924 | * is not active, notify rate adaptation. |
979 | */ | 925 | */ |
980 | if (brcms_c_ffpld_check_txfunfl(wlc, | 926 | if (brcms_c_ffpld_check_txfunfl(wlc, queue) > 0) |
981 | prio2fifo[tid]) > 0) | ||
982 | tx_error = true; | 927 | tx_error = true; |
983 | } | 928 | } |
984 | } else if (txs->phyerr) { | 929 | } else if (txs->phyerr) { |
985 | update_rate = false; | 930 | update_rate = false; |
986 | wiphy_err(wiphy, "%s: ampdu tx phy error (0x%x)\n", | 931 | brcms_err(wlc->hw->d11core, |
932 | "%s: ampdu tx phy error (0x%x)\n", | ||
987 | __func__, txs->phyerr); | 933 | __func__, txs->phyerr); |
988 | |||
989 | if (brcm_msg_level & LOG_ERROR_VAL) { | ||
990 | brcmu_prpkt("txpkt (AMPDU)", p); | ||
991 | brcms_c_print_txdesc((struct d11txh *) p->data); | ||
992 | } | ||
993 | brcms_c_print_txstatus(txs); | ||
994 | } | 934 | } |
995 | } | 935 | } |
996 | 936 | ||
@@ -1003,6 +943,8 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, | |||
1003 | h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN); | 943 | h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN); |
1004 | seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT; | 944 | seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT; |
1005 | 945 | ||
946 | trace_brcms_txdesc(&wlc->hw->d11core->dev, txh, sizeof(*txh)); | ||
947 | |||
1006 | if (tot_mpdu == 0) { | 948 | if (tot_mpdu == 0) { |
1007 | mcs = plcp[0] & MIMO_PLCP_MCS_MASK; | 949 | mcs = plcp[0] & MIMO_PLCP_MCS_MASK; |
1008 | mimoantsel = le16_to_cpu(txh->ABI_MimoAntSel); | 950 | mimoantsel = le16_to_cpu(txh->ABI_MimoAntSel); |
@@ -1012,10 +954,10 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, | |||
1012 | ack_recd = false; | 954 | ack_recd = false; |
1013 | if (ba_recd) { | 955 | if (ba_recd) { |
1014 | bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX); | 956 | bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX); |
1015 | BCMMSG(wiphy, | 957 | brcms_dbg_ht(wlc->hw->d11core, |
1016 | "tid %d seq %d, start_seq %d, bindex %d set %d, index %d\n", | 958 | "tid %d seq %d, start_seq %d, bindex %d set %d, index %d\n", |
1017 | tid, seq, start_seq, bindex, | 959 | tid, seq, start_seq, bindex, |
1018 | isset(bitmap, bindex), index); | 960 | isset(bitmap, bindex), index); |
1019 | /* if acked then clear bit and free packet */ | 961 | /* if acked then clear bit and free packet */ |
1020 | if ((bindex < AMPDU_TX_BA_MAX_WSIZE) | 962 | if ((bindex < AMPDU_TX_BA_MAX_WSIZE) |
1021 | && isset(bitmap, bindex)) { | 963 | && isset(bitmap, bindex)) { |
@@ -1046,14 +988,16 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, | |||
1046 | /* either retransmit or send bar if ack not recd */ | 988 | /* either retransmit or send bar if ack not recd */ |
1047 | if (!ack_recd) { | 989 | if (!ack_recd) { |
1048 | if (retry && (ini->txretry[index] < (int)retry_limit)) { | 990 | if (retry && (ini->txretry[index] < (int)retry_limit)) { |
991 | int ret; | ||
1049 | ini->txretry[index]++; | 992 | ini->txretry[index]++; |
1050 | ini->tx_in_transit--; | 993 | ini->tx_in_transit--; |
994 | ret = brcms_c_txfifo(wlc, queue, p); | ||
1051 | /* | 995 | /* |
1052 | * Use high prededence for retransmit to | 996 | * We shouldn't be out of space in the DMA |
1053 | * give some punch | 997 | * ring here since we're reinserting a frame |
998 | * that was just pulled out. | ||
1054 | */ | 999 | */ |
1055 | brcms_c_txq_enq(wlc, scb, p, | 1000 | WARN_ONCE(ret, "queue %d out of txds\n", queue); |
1056 | BRCMS_PRIO_TO_HI_PREC(tid)); | ||
1057 | } else { | 1001 | } else { |
1058 | /* Retry timeout */ | 1002 | /* Retry timeout */ |
1059 | ini->tx_in_transit--; | 1003 | ini->tx_in_transit--; |
@@ -1064,9 +1008,9 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, | |||
1064 | IEEE80211_TX_STAT_AMPDU_NO_BACK; | 1008 | IEEE80211_TX_STAT_AMPDU_NO_BACK; |
1065 | skb_pull(p, D11_PHY_HDR_LEN); | 1009 | skb_pull(p, D11_PHY_HDR_LEN); |
1066 | skb_pull(p, D11_TXH_LEN); | 1010 | skb_pull(p, D11_TXH_LEN); |
1067 | BCMMSG(wiphy, | 1011 | brcms_dbg_ht(wlc->hw->d11core, |
1068 | "BA Timeout, seq %d, in_transit %d\n", | 1012 | "BA Timeout, seq %d, in_transit %d\n", |
1069 | seq, ini->tx_in_transit); | 1013 | seq, ini->tx_in_transit); |
1070 | ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, | 1014 | ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, |
1071 | p); | 1015 | p); |
1072 | } | 1016 | } |
@@ -1080,12 +1024,9 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, | |||
1080 | 1024 | ||
1081 | p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED); | 1025 | p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED); |
1082 | } | 1026 | } |
1083 | brcms_c_send_q(wlc); | ||
1084 | 1027 | ||
1085 | /* update rate state */ | 1028 | /* update rate state */ |
1086 | antselid = brcms_c_antsel_antsel2id(wlc->asi, mimoantsel); | 1029 | antselid = brcms_c_antsel_antsel2id(wlc->asi, mimoantsel); |
1087 | |||
1088 | brcms_c_txfifo_complete(wlc, queue, ampdu->txpkt_weight); | ||
1089 | } | 1030 | } |
1090 | 1031 | ||
1091 | void | 1032 | void |
@@ -1133,6 +1074,8 @@ brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, | |||
1133 | while (p) { | 1074 | while (p) { |
1134 | tx_info = IEEE80211_SKB_CB(p); | 1075 | tx_info = IEEE80211_SKB_CB(p); |
1135 | txh = (struct d11txh *) p->data; | 1076 | txh = (struct d11txh *) p->data; |
1077 | trace_brcms_txdesc(&wlc->hw->d11core->dev, txh, | ||
1078 | sizeof(*txh)); | ||
1136 | mcl = le16_to_cpu(txh->MacTxControlLow); | 1079 | mcl = le16_to_cpu(txh->MacTxControlLow); |
1137 | brcmu_pkt_buf_free_skb(p); | 1080 | brcmu_pkt_buf_free_skb(p); |
1138 | /* break out if last packet of ampdu */ | 1081 | /* break out if last packet of ampdu */ |
@@ -1142,7 +1085,6 @@ brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, | |||
1142 | p = dma_getnexttxp(wlc->hw->di[queue], | 1085 | p = dma_getnexttxp(wlc->hw->di[queue], |
1143 | DMA_RANGE_TRANSMITTED); | 1086 | DMA_RANGE_TRANSMITTED); |
1144 | } | 1087 | } |
1145 | brcms_c_txfifo_complete(wlc, queue, ampdu->txpkt_weight); | ||
1146 | } | 1088 | } |
1147 | } | 1089 | } |
1148 | 1090 | ||
@@ -1182,23 +1124,6 @@ void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu) | |||
1182 | } | 1124 | } |
1183 | 1125 | ||
1184 | /* | 1126 | /* |
1185 | * callback function that helps flushing ampdu packets from a priority queue | ||
1186 | */ | ||
1187 | static bool cb_del_ampdu_pkt(struct sk_buff *mpdu, void *arg_a) | ||
1188 | { | ||
1189 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(mpdu); | ||
1190 | struct cb_del_ampdu_pars *ampdu_pars = | ||
1191 | (struct cb_del_ampdu_pars *)arg_a; | ||
1192 | bool rc; | ||
1193 | |||
1194 | rc = tx_info->flags & IEEE80211_TX_CTL_AMPDU ? true : false; | ||
1195 | rc = rc && (tx_info->rate_driver_data[0] == NULL || ampdu_pars->sta == NULL || | ||
1196 | tx_info->rate_driver_data[0] == ampdu_pars->sta); | ||
1197 | rc = rc && ((u8)(mpdu->priority) == ampdu_pars->tid); | ||
1198 | return rc; | ||
1199 | } | ||
1200 | |||
1201 | /* | ||
1202 | * callback function that helps invalidating ampdu packets in a DMA queue | 1127 | * callback function that helps invalidating ampdu packets in a DMA queue |
1203 | */ | 1128 | */ |
1204 | static void dma_cb_fn_ampdu(void *txi, void *arg_a) | 1129 | static void dma_cb_fn_ampdu(void *txi, void *arg_a) |
@@ -1218,15 +1143,5 @@ static void dma_cb_fn_ampdu(void *txi, void *arg_a) | |||
1218 | void brcms_c_ampdu_flush(struct brcms_c_info *wlc, | 1143 | void brcms_c_ampdu_flush(struct brcms_c_info *wlc, |
1219 | struct ieee80211_sta *sta, u16 tid) | 1144 | struct ieee80211_sta *sta, u16 tid) |
1220 | { | 1145 | { |
1221 | struct brcms_txq_info *qi = wlc->pkt_queue; | ||
1222 | struct pktq *pq = &qi->q; | ||
1223 | int prec; | ||
1224 | struct cb_del_ampdu_pars ampdu_pars; | ||
1225 | |||
1226 | ampdu_pars.sta = sta; | ||
1227 | ampdu_pars.tid = tid; | ||
1228 | for (prec = 0; prec < pq->num_prec; prec++) | ||
1229 | brcmu_pktq_pflush(pq, prec, true, cb_del_ampdu_pkt, | ||
1230 | (void *)&du_pars); | ||
1231 | brcms_c_inval_dma_pkts(wlc->hw, sta, dma_cb_fn_ampdu); | 1146 | brcms_c_inval_dma_pkts(wlc->hw, sta, dma_cb_fn_ampdu); |
1232 | } | 1147 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h index 421f4ba7c63c..73d01e586109 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h | |||
@@ -17,11 +17,34 @@ | |||
17 | #ifndef _BRCM_AMPDU_H_ | 17 | #ifndef _BRCM_AMPDU_H_ |
18 | #define _BRCM_AMPDU_H_ | 18 | #define _BRCM_AMPDU_H_ |
19 | 19 | ||
20 | /* | ||
21 | * Data structure representing an in-progress session for accumulating | ||
22 | * frames for AMPDU. | ||
23 | * | ||
24 | * wlc: pointer to common driver data | ||
25 | * skb_list: queue of skb's for AMPDU | ||
26 | * max_ampdu_len: maximum length for this AMPDU | ||
27 | * max_ampdu_frames: maximum number of frames for this AMPDU | ||
28 | * ampdu_len: total number of bytes accumulated for this AMPDU | ||
29 | * dma_len: DMA length of this AMPDU | ||
30 | */ | ||
31 | struct brcms_ampdu_session { | ||
32 | struct brcms_c_info *wlc; | ||
33 | struct sk_buff_head skb_list; | ||
34 | unsigned max_ampdu_len; | ||
35 | u16 max_ampdu_frames; | ||
36 | u16 ampdu_len; | ||
37 | u16 dma_len; | ||
38 | }; | ||
39 | |||
40 | extern void brcms_c_ampdu_reset_session(struct brcms_ampdu_session *session, | ||
41 | struct brcms_c_info *wlc); | ||
42 | extern int brcms_c_ampdu_add_frame(struct brcms_ampdu_session *session, | ||
43 | struct sk_buff *p); | ||
44 | extern void brcms_c_ampdu_finalize(struct brcms_ampdu_session *session); | ||
45 | |||
20 | extern struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc); | 46 | extern struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc); |
21 | extern void brcms_c_ampdu_detach(struct ampdu_info *ampdu); | 47 | extern void brcms_c_ampdu_detach(struct ampdu_info *ampdu); |
22 | extern int brcms_c_sendampdu(struct ampdu_info *ampdu, | ||
23 | struct brcms_txq_info *qi, | ||
24 | struct sk_buff **aggp, int prec); | ||
25 | extern void brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, | 48 | extern void brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, |
26 | struct sk_buff *p, struct tx_status *txs); | 49 | struct sk_buff *p, struct tx_status *txs); |
27 | extern void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc); | 50 | extern void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc); |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/antsel.c b/drivers/net/wireless/brcm80211/brcmsmac/antsel.c index 55e12c327911..54c616919590 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/antsel.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/antsel.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include "main.h" | 21 | #include "main.h" |
22 | #include "phy_shim.h" | 22 | #include "phy_shim.h" |
23 | #include "antsel.h" | 23 | #include "antsel.h" |
24 | #include "debug.h" | ||
24 | 25 | ||
25 | #define ANT_SELCFG_AUTO 0x80 /* bit indicates antenna sel AUTO */ | 26 | #define ANT_SELCFG_AUTO 0x80 /* bit indicates antenna sel AUTO */ |
26 | #define ANT_SELCFG_MASK 0x33 /* antenna configuration mask */ | 27 | #define ANT_SELCFG_MASK 0x33 /* antenna configuration mask */ |
@@ -137,7 +138,8 @@ struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc) | |||
137 | asi->antsel_avail = false; | 138 | asi->antsel_avail = false; |
138 | } else { | 139 | } else { |
139 | asi->antsel_avail = false; | 140 | asi->antsel_avail = false; |
140 | wiphy_err(wlc->wiphy, "antsel_attach: 2o3 " | 141 | brcms_err(wlc->hw->d11core, |
142 | "antsel_attach: 2o3 " | ||
141 | "board cfg invalid\n"); | 143 | "board cfg invalid\n"); |
142 | } | 144 | } |
143 | 145 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h index 27dd73eef56d..871781e6a713 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h | |||
@@ -14,22 +14,29 @@ | |||
14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #undef TRACE_SYSTEM | ||
18 | #define TRACE_SYSTEM brcmsmac | ||
19 | |||
20 | #if !defined(__TRACE_BRCMSMAC_H) || defined(TRACE_HEADER_MULTI_READ) | 17 | #if !defined(__TRACE_BRCMSMAC_H) || defined(TRACE_HEADER_MULTI_READ) |
21 | 18 | ||
22 | #define __TRACE_BRCMSMAC_H | 19 | #define __TRACE_BRCMSMAC_H |
23 | 20 | ||
21 | #include <linux/types.h> | ||
22 | #include <linux/device.h> | ||
24 | #include <linux/tracepoint.h> | 23 | #include <linux/tracepoint.h> |
25 | #include "mac80211_if.h" | 24 | #include "mac80211_if.h" |
26 | 25 | ||
27 | #ifndef CONFIG_BRCMDBG | 26 | #ifndef CONFIG_BRCM_TRACING |
28 | #undef TRACE_EVENT | 27 | #undef TRACE_EVENT |
29 | #define TRACE_EVENT(name, proto, ...) \ | 28 | #define TRACE_EVENT(name, proto, ...) \ |
30 | static inline void trace_ ## name(proto) {} | 29 | static inline void trace_ ## name(proto) {} |
30 | #undef DECLARE_EVENT_CLASS | ||
31 | #define DECLARE_EVENT_CLASS(...) | ||
32 | #undef DEFINE_EVENT | ||
33 | #define DEFINE_EVENT(evt_class, name, proto, ...) \ | ||
34 | static inline void trace_ ## name(proto) {} | ||
31 | #endif | 35 | #endif |
32 | 36 | ||
37 | #undef TRACE_SYSTEM | ||
38 | #define TRACE_SYSTEM brcmsmac | ||
39 | |||
33 | /* | 40 | /* |
34 | * We define a tracepoint, its arguments, its printk format and its | 41 | * We define a tracepoint, its arguments, its printk format and its |
35 | * 'fast binary record' layout. | 42 | * 'fast binary record' layout. |
@@ -78,9 +85,165 @@ TRACE_EVENT(brcms_dpc, | |||
78 | ) | 85 | ) |
79 | ); | 86 | ); |
80 | 87 | ||
88 | TRACE_EVENT(brcms_macintstatus, | ||
89 | TP_PROTO(const struct device *dev, int in_isr, u32 macintstatus, | ||
90 | u32 mask), | ||
91 | TP_ARGS(dev, in_isr, macintstatus, mask), | ||
92 | TP_STRUCT__entry( | ||
93 | __string(dev, dev_name(dev)) | ||
94 | __field(int, in_isr) | ||
95 | __field(u32, macintstatus) | ||
96 | __field(u32, mask) | ||
97 | ), | ||
98 | TP_fast_assign( | ||
99 | __assign_str(dev, dev_name(dev)); | ||
100 | __entry->in_isr = in_isr; | ||
101 | __entry->macintstatus = macintstatus; | ||
102 | __entry->mask = mask; | ||
103 | ), | ||
104 | TP_printk("[%s] in_isr=%d macintstatus=%#x mask=%#x", __get_str(dev), | ||
105 | __entry->in_isr, __entry->macintstatus, __entry->mask) | ||
106 | ); | ||
107 | |||
108 | #undef TRACE_SYSTEM | ||
109 | #define TRACE_SYSTEM brcmsmac_tx | ||
110 | |||
111 | TRACE_EVENT(brcms_txdesc, | ||
112 | TP_PROTO(const struct device *dev, | ||
113 | void *txh, size_t txh_len), | ||
114 | TP_ARGS(dev, txh, txh_len), | ||
115 | TP_STRUCT__entry( | ||
116 | __string(dev, dev_name(dev)) | ||
117 | __dynamic_array(u8, txh, txh_len) | ||
118 | ), | ||
119 | TP_fast_assign( | ||
120 | __assign_str(dev, dev_name(dev)); | ||
121 | memcpy(__get_dynamic_array(txh), txh, txh_len); | ||
122 | ), | ||
123 | TP_printk("[%s] txdesc", __get_str(dev)) | ||
124 | ); | ||
125 | |||
126 | TRACE_EVENT(brcms_txstatus, | ||
127 | TP_PROTO(const struct device *dev, u16 framelen, u16 frameid, | ||
128 | u16 status, u16 lasttxtime, u16 sequence, u16 phyerr, | ||
129 | u16 ackphyrxsh), | ||
130 | TP_ARGS(dev, framelen, frameid, status, lasttxtime, sequence, phyerr, | ||
131 | ackphyrxsh), | ||
132 | TP_STRUCT__entry( | ||
133 | __string(dev, dev_name(dev)) | ||
134 | __field(u16, framelen) | ||
135 | __field(u16, frameid) | ||
136 | __field(u16, status) | ||
137 | __field(u16, lasttxtime) | ||
138 | __field(u16, sequence) | ||
139 | __field(u16, phyerr) | ||
140 | __field(u16, ackphyrxsh) | ||
141 | ), | ||
142 | TP_fast_assign( | ||
143 | __assign_str(dev, dev_name(dev)); | ||
144 | __entry->framelen = framelen; | ||
145 | __entry->frameid = frameid; | ||
146 | __entry->status = status; | ||
147 | __entry->lasttxtime = lasttxtime; | ||
148 | __entry->sequence = sequence; | ||
149 | __entry->phyerr = phyerr; | ||
150 | __entry->ackphyrxsh = ackphyrxsh; | ||
151 | ), | ||
152 | TP_printk("[%s] FrameId %#04x TxStatus %#04x LastTxTime %#04x " | ||
153 | "Seq %#04x PHYTxStatus %#04x RxAck %#04x", | ||
154 | __get_str(dev), __entry->frameid, __entry->status, | ||
155 | __entry->lasttxtime, __entry->sequence, __entry->phyerr, | ||
156 | __entry->ackphyrxsh) | ||
157 | ); | ||
158 | |||
159 | TRACE_EVENT(brcms_ampdu_session, | ||
160 | TP_PROTO(const struct device *dev, unsigned max_ampdu_len, | ||
161 | u16 max_ampdu_frames, u16 ampdu_len, u16 ampdu_frames, | ||
162 | u16 dma_len), | ||
163 | TP_ARGS(dev, max_ampdu_len, max_ampdu_frames, ampdu_len, ampdu_frames, | ||
164 | dma_len), | ||
165 | TP_STRUCT__entry( | ||
166 | __string(dev, dev_name(dev)) | ||
167 | __field(unsigned, max_ampdu_len) | ||
168 | __field(u16, max_ampdu_frames) | ||
169 | __field(u16, ampdu_len) | ||
170 | __field(u16, ampdu_frames) | ||
171 | __field(u16, dma_len) | ||
172 | ), | ||
173 | TP_fast_assign( | ||
174 | __assign_str(dev, dev_name(dev)); | ||
175 | __entry->max_ampdu_len = max_ampdu_len; | ||
176 | __entry->max_ampdu_frames = max_ampdu_frames; | ||
177 | __entry->ampdu_len = ampdu_len; | ||
178 | __entry->ampdu_frames = ampdu_frames; | ||
179 | __entry->dma_len = dma_len; | ||
180 | ), | ||
181 | TP_printk("[%s] ampdu session max_len=%u max_frames=%u len=%u frames=%u dma_len=%u", | ||
182 | __get_str(dev), __entry->max_ampdu_len, | ||
183 | __entry->max_ampdu_frames, __entry->ampdu_len, | ||
184 | __entry->ampdu_frames, __entry->dma_len) | ||
185 | ); | ||
186 | |||
187 | #undef TRACE_SYSTEM | ||
188 | #define TRACE_SYSTEM brcmsmac_msg | ||
189 | |||
190 | #define MAX_MSG_LEN 100 | ||
191 | |||
192 | DECLARE_EVENT_CLASS(brcms_msg_event, | ||
193 | TP_PROTO(struct va_format *vaf), | ||
194 | TP_ARGS(vaf), | ||
195 | TP_STRUCT__entry( | ||
196 | __dynamic_array(char, msg, MAX_MSG_LEN) | ||
197 | ), | ||
198 | TP_fast_assign( | ||
199 | WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), | ||
200 | MAX_MSG_LEN, vaf->fmt, | ||
201 | *vaf->va) >= MAX_MSG_LEN); | ||
202 | ), | ||
203 | TP_printk("%s", __get_str(msg)) | ||
204 | ); | ||
205 | |||
206 | DEFINE_EVENT(brcms_msg_event, brcms_info, | ||
207 | TP_PROTO(struct va_format *vaf), | ||
208 | TP_ARGS(vaf) | ||
209 | ); | ||
210 | |||
211 | DEFINE_EVENT(brcms_msg_event, brcms_warn, | ||
212 | TP_PROTO(struct va_format *vaf), | ||
213 | TP_ARGS(vaf) | ||
214 | ); | ||
215 | |||
216 | DEFINE_EVENT(brcms_msg_event, brcms_err, | ||
217 | TP_PROTO(struct va_format *vaf), | ||
218 | TP_ARGS(vaf) | ||
219 | ); | ||
220 | |||
221 | DEFINE_EVENT(brcms_msg_event, brcms_crit, | ||
222 | TP_PROTO(struct va_format *vaf), | ||
223 | TP_ARGS(vaf) | ||
224 | ); | ||
225 | |||
226 | TRACE_EVENT(brcms_dbg, | ||
227 | TP_PROTO(u32 level, const char *func, struct va_format *vaf), | ||
228 | TP_ARGS(level, func, vaf), | ||
229 | TP_STRUCT__entry( | ||
230 | __field(u32, level) | ||
231 | __string(func, func) | ||
232 | __dynamic_array(char, msg, MAX_MSG_LEN) | ||
233 | ), | ||
234 | TP_fast_assign( | ||
235 | __entry->level = level; | ||
236 | __assign_str(func, func); | ||
237 | WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), | ||
238 | MAX_MSG_LEN, vaf->fmt, | ||
239 | *vaf->va) >= MAX_MSG_LEN); | ||
240 | ), | ||
241 | TP_printk("%s: %s", __get_str(func), __get_str(msg)) | ||
242 | ); | ||
243 | |||
81 | #endif /* __TRACE_BRCMSMAC_H */ | 244 | #endif /* __TRACE_BRCMSMAC_H */ |
82 | 245 | ||
83 | #ifdef CONFIG_BRCMDBG | 246 | #ifdef CONFIG_BRCM_TRACING |
84 | 247 | ||
85 | #undef TRACE_INCLUDE_PATH | 248 | #undef TRACE_INCLUDE_PATH |
86 | #define TRACE_INCLUDE_PATH . | 249 | #define TRACE_INCLUDE_PATH . |
@@ -89,4 +252,4 @@ TRACE_EVENT(brcms_dpc, | |||
89 | 252 | ||
90 | #include <trace/define_trace.h> | 253 | #include <trace/define_trace.h> |
91 | 254 | ||
92 | #endif /* CONFIG_BRCMDBG */ | 255 | #endif /* CONFIG_BRCM_TRACING */ |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c index 64a48f06d68b..a90b72202ec5 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include "stf.h" | 26 | #include "stf.h" |
27 | #include "channel.h" | 27 | #include "channel.h" |
28 | #include "mac80211_if.h" | 28 | #include "mac80211_if.h" |
29 | #include "debug.h" | ||
29 | 30 | ||
30 | /* QDB() macro takes a dB value and converts to a quarter dB value */ | 31 | /* QDB() macro takes a dB value and converts to a quarter dB value */ |
31 | #define QDB(n) ((n) * BRCMS_TXPWR_DB_FACTOR) | 32 | #define QDB(n) ((n) * BRCMS_TXPWR_DB_FACTOR) |
@@ -336,8 +337,6 @@ struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc) | |||
336 | const char *ccode = sprom->alpha2; | 337 | const char *ccode = sprom->alpha2; |
337 | int ccode_len = sizeof(sprom->alpha2); | 338 | int ccode_len = sizeof(sprom->alpha2); |
338 | 339 | ||
339 | BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); | ||
340 | |||
341 | wlc_cm = kzalloc(sizeof(struct brcms_cm_info), GFP_ATOMIC); | 340 | wlc_cm = kzalloc(sizeof(struct brcms_cm_info), GFP_ATOMIC); |
342 | if (wlc_cm == NULL) | 341 | if (wlc_cm == NULL) |
343 | return NULL; | 342 | return NULL; |
@@ -615,8 +614,8 @@ brcms_c_valid_chanspec_ext(struct brcms_cm_info *wlc_cm, u16 chspec) | |||
615 | 614 | ||
616 | /* check the chanspec */ | 615 | /* check the chanspec */ |
617 | if (brcms_c_chspec_malformed(chspec)) { | 616 | if (brcms_c_chspec_malformed(chspec)) { |
618 | wiphy_err(wlc->wiphy, "wl%d: malformed chanspec 0x%x\n", | 617 | brcms_err(wlc->hw->d11core, "wl%d: malformed chanspec 0x%x\n", |
619 | wlc->pub->unit, chspec); | 618 | wlc->pub->unit, chspec); |
620 | return false; | 619 | return false; |
621 | } | 620 | } |
622 | 621 | ||
@@ -738,7 +737,8 @@ static int brcms_reg_notifier(struct wiphy *wiphy, | |||
738 | mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); | 737 | mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); |
739 | } else { | 738 | } else { |
740 | mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); | 739 | mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); |
741 | wiphy_err(wlc->wiphy, "wl%d: %s: no valid channel for \"%s\"\n", | 740 | brcms_err(wlc->hw->d11core, |
741 | "wl%d: %s: no valid channel for \"%s\"\n", | ||
742 | wlc->pub->unit, __func__, request->alpha2); | 742 | wlc->pub->unit, __func__, request->alpha2); |
743 | } | 743 | } |
744 | 744 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/debug.c b/drivers/net/wireless/brcm80211/brcmsmac/debug.c new file mode 100644 index 000000000000..6ba4136c7cf6 --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmsmac/debug.c | |||
@@ -0,0 +1,44 @@ | |||
1 | #include <linux/net.h> | ||
2 | #include "types.h" | ||
3 | #include "debug.h" | ||
4 | #include "brcms_trace_events.h" | ||
5 | |||
6 | #define __brcms_fn(fn) \ | ||
7 | void __brcms_ ##fn(struct device *dev, const char *fmt, ...) \ | ||
8 | { \ | ||
9 | struct va_format vaf = { \ | ||
10 | .fmt = fmt, \ | ||
11 | }; \ | ||
12 | va_list args; \ | ||
13 | \ | ||
14 | va_start(args, fmt); \ | ||
15 | vaf.va = &args; \ | ||
16 | dev_ ##fn(dev, "%pV", &vaf); \ | ||
17 | trace_brcms_ ##fn(&vaf); \ | ||
18 | va_end(args); \ | ||
19 | } | ||
20 | |||
21 | __brcms_fn(info) | ||
22 | __brcms_fn(warn) | ||
23 | __brcms_fn(err) | ||
24 | __brcms_fn(crit) | ||
25 | |||
26 | #if defined(CONFIG_BRCMDBG) || defined(CONFIG_BRCM_TRACING) | ||
27 | void __brcms_dbg(struct device *dev, u32 level, const char *func, | ||
28 | const char *fmt, ...) | ||
29 | { | ||
30 | struct va_format vaf = { | ||
31 | .fmt = fmt, | ||
32 | }; | ||
33 | va_list args; | ||
34 | |||
35 | va_start(args, fmt); | ||
36 | vaf.va = &args; | ||
37 | #ifdef CONFIG_BRCMDBG | ||
38 | if ((brcm_msg_level & level) && net_ratelimit()) | ||
39 | dev_err(dev, "%s %pV", func, &vaf); | ||
40 | #endif | ||
41 | trace_brcms_dbg(level, func, &vaf); | ||
42 | va_end(args); | ||
43 | } | ||
44 | #endif | ||
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/debug.h b/drivers/net/wireless/brcm80211/brcmsmac/debug.h new file mode 100644 index 000000000000..f77066bda9d2 --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmsmac/debug.h | |||
@@ -0,0 +1,52 @@ | |||
1 | #ifndef _BRCMS_DEBUG_H_ | ||
2 | #define _BRCMS_DEBUG_H_ | ||
3 | |||
4 | #include <linux/device.h> | ||
5 | #include <linux/bcma/bcma.h> | ||
6 | #include <net/cfg80211.h> | ||
7 | #include <net/mac80211.h> | ||
8 | #include "main.h" | ||
9 | #include "mac80211_if.h" | ||
10 | |||
11 | __printf(2, 3) | ||
12 | void __brcms_info(struct device *dev, const char *fmt, ...); | ||
13 | __printf(2, 3) | ||
14 | void __brcms_warn(struct device *dev, const char *fmt, ...); | ||
15 | __printf(2, 3) | ||
16 | void __brcms_err(struct device *dev, const char *fmt, ...); | ||
17 | __printf(2, 3) | ||
18 | void __brcms_crit(struct device *dev, const char *fmt, ...); | ||
19 | |||
20 | #if defined(CONFIG_BRCMDBG) || defined(CONFIG_BRCM_TRACING) | ||
21 | __printf(4, 5) | ||
22 | void __brcms_dbg(struct device *dev, u32 level, const char *func, | ||
23 | const char *fmt, ...); | ||
24 | #else | ||
25 | static inline __printf(4, 5) | ||
26 | void __brcms_dbg(struct device *dev, u32 level, const char *func, | ||
27 | const char *fmt, ...) | ||
28 | { | ||
29 | } | ||
30 | #endif | ||
31 | |||
32 | /* | ||
33 | * Debug macros cannot be used when wlc is uninitialized. Generally | ||
34 | * this means any code that could run before brcms_c_attach() has | ||
35 | * returned successfully probably shouldn't use the following macros. | ||
36 | */ | ||
37 | |||
38 | #define brcms_dbg(core, l, f, a...) __brcms_dbg(&(core)->dev, l, __func__, f, ##a) | ||
39 | #define brcms_info(core, f, a...) __brcms_info(&(core)->dev, f, ##a) | ||
40 | #define brcms_warn(core, f, a...) __brcms_warn(&(core)->dev, f, ##a) | ||
41 | #define brcms_err(core, f, a...) __brcms_err(&(core)->dev, f, ##a) | ||
42 | #define brcms_crit(core, f, a...) __brcms_crit(&(core)->dev, f, ##a) | ||
43 | |||
44 | #define brcms_dbg_info(core, f, a...) brcms_dbg(core, BRCM_DL_INFO, f, ##a) | ||
45 | #define brcms_dbg_mac80211(core, f, a...) brcms_dbg(core, BRCM_DL_MAC80211, f, ##a) | ||
46 | #define brcms_dbg_rx(core, f, a...) brcms_dbg(core, BRCM_DL_RX, f, ##a) | ||
47 | #define brcms_dbg_tx(core, f, a...) brcms_dbg(core, BRCM_DL_TX, f, ##a) | ||
48 | #define brcms_dbg_int(core, f, a...) brcms_dbg(core, BRCM_DL_INT, f, ##a) | ||
49 | #define brcms_dbg_dma(core, f, a...) brcms_dbg(core, BRCM_DL_DMA, f, ##a) | ||
50 | #define brcms_dbg_ht(core, f, a...) brcms_dbg(core, BRCM_DL_HT, f, ##a) | ||
51 | |||
52 | #endif /* _BRCMS_DEBUG_H_ */ | ||
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c index 5e53305bd9a9..511e45775c33 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c | |||
@@ -14,17 +14,22 @@ | |||
14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
18 | |||
19 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
20 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
21 | #include <linux/pci.h> | 19 | #include <linux/pci.h> |
20 | #include <net/cfg80211.h> | ||
21 | #include <net/mac80211.h> | ||
22 | 22 | ||
23 | #include <brcmu_utils.h> | 23 | #include <brcmu_utils.h> |
24 | #include <aiutils.h> | 24 | #include <aiutils.h> |
25 | #include "types.h" | 25 | #include "types.h" |
26 | #include "main.h" | ||
26 | #include "dma.h" | 27 | #include "dma.h" |
27 | #include "soc.h" | 28 | #include "soc.h" |
29 | #include "scb.h" | ||
30 | #include "ampdu.h" | ||
31 | #include "debug.h" | ||
32 | #include "brcms_trace_events.h" | ||
28 | 33 | ||
29 | /* | 34 | /* |
30 | * dma register field offset calculation | 35 | * dma register field offset calculation |
@@ -176,28 +181,6 @@ | |||
176 | 181 | ||
177 | #define BCMEXTRAHDROOM 172 | 182 | #define BCMEXTRAHDROOM 172 |
178 | 183 | ||
179 | /* debug/trace */ | ||
180 | #ifdef DEBUG | ||
181 | #define DMA_ERROR(fmt, ...) \ | ||
182 | do { \ | ||
183 | if (*di->msg_level & 1) \ | ||
184 | pr_debug("%s: " fmt, __func__, ##__VA_ARGS__); \ | ||
185 | } while (0) | ||
186 | #define DMA_TRACE(fmt, ...) \ | ||
187 | do { \ | ||
188 | if (*di->msg_level & 2) \ | ||
189 | pr_debug("%s: " fmt, __func__, ##__VA_ARGS__); \ | ||
190 | } while (0) | ||
191 | #else | ||
192 | #define DMA_ERROR(fmt, ...) \ | ||
193 | no_printk(fmt, ##__VA_ARGS__) | ||
194 | #define DMA_TRACE(fmt, ...) \ | ||
195 | no_printk(fmt, ##__VA_ARGS__) | ||
196 | #endif /* DEBUG */ | ||
197 | |||
198 | #define DMA_NONE(fmt, ...) \ | ||
199 | no_printk(fmt, ##__VA_ARGS__) | ||
200 | |||
201 | #define MAXNAMEL 8 /* 8 char names */ | 184 | #define MAXNAMEL 8 /* 8 char names */ |
202 | 185 | ||
203 | /* macros to convert between byte offsets and indexes */ | 186 | /* macros to convert between byte offsets and indexes */ |
@@ -224,12 +207,14 @@ struct dma64desc { | |||
224 | /* dma engine software state */ | 207 | /* dma engine software state */ |
225 | struct dma_info { | 208 | struct dma_info { |
226 | struct dma_pub dma; /* exported structure */ | 209 | struct dma_pub dma; /* exported structure */ |
227 | uint *msg_level; /* message level pointer */ | ||
228 | char name[MAXNAMEL]; /* callers name for diag msgs */ | 210 | char name[MAXNAMEL]; /* callers name for diag msgs */ |
229 | 211 | ||
230 | struct bcma_device *core; | 212 | struct bcma_device *core; |
231 | struct device *dmadev; | 213 | struct device *dmadev; |
232 | 214 | ||
215 | /* session information for AMPDU */ | ||
216 | struct brcms_ampdu_session ampdu_session; | ||
217 | |||
233 | bool dma64; /* this dma engine is operating in 64-bit mode */ | 218 | bool dma64; /* this dma engine is operating in 64-bit mode */ |
234 | bool addrext; /* this dma engine supports DmaExtendedAddrChanges */ | 219 | bool addrext; /* this dma engine supports DmaExtendedAddrChanges */ |
235 | 220 | ||
@@ -298,12 +283,6 @@ struct dma_info { | |||
298 | bool aligndesc_4k; | 283 | bool aligndesc_4k; |
299 | }; | 284 | }; |
300 | 285 | ||
301 | /* | ||
302 | * default dma message level (if input msg_level | ||
303 | * pointer is null in dma_attach()) | ||
304 | */ | ||
305 | static uint dma_msg_level; | ||
306 | |||
307 | /* Check for odd number of 1's */ | 286 | /* Check for odd number of 1's */ |
308 | static u32 parity32(__le32 data) | 287 | static u32 parity32(__le32 data) |
309 | { | 288 | { |
@@ -353,7 +332,7 @@ static uint prevtxd(struct dma_info *di, uint i) | |||
353 | 332 | ||
354 | static uint nextrxd(struct dma_info *di, uint i) | 333 | static uint nextrxd(struct dma_info *di, uint i) |
355 | { | 334 | { |
356 | return txd(di, i + 1); | 335 | return rxd(di, i + 1); |
357 | } | 336 | } |
358 | 337 | ||
359 | static uint ntxdactive(struct dma_info *di, uint h, uint t) | 338 | static uint ntxdactive(struct dma_info *di, uint h, uint t) |
@@ -371,7 +350,7 @@ static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags) | |||
371 | uint dmactrlflags; | 350 | uint dmactrlflags; |
372 | 351 | ||
373 | if (di == NULL) { | 352 | if (di == NULL) { |
374 | DMA_ERROR("NULL dma handle\n"); | 353 | brcms_dbg_dma(di->core, "NULL dma handle\n"); |
375 | return 0; | 354 | return 0; |
376 | } | 355 | } |
377 | 356 | ||
@@ -423,13 +402,15 @@ static bool _dma_isaddrext(struct dma_info *di) | |||
423 | /* not all tx or rx channel are available */ | 402 | /* not all tx or rx channel are available */ |
424 | if (di->d64txregbase != 0) { | 403 | if (di->d64txregbase != 0) { |
425 | if (!_dma64_addrext(di, DMA64TXREGOFFS(di, control))) | 404 | if (!_dma64_addrext(di, DMA64TXREGOFFS(di, control))) |
426 | DMA_ERROR("%s: DMA64 tx doesn't have AE set\n", | 405 | brcms_dbg_dma(di->core, |
427 | di->name); | 406 | "%s: DMA64 tx doesn't have AE set\n", |
407 | di->name); | ||
428 | return true; | 408 | return true; |
429 | } else if (di->d64rxregbase != 0) { | 409 | } else if (di->d64rxregbase != 0) { |
430 | if (!_dma64_addrext(di, DMA64RXREGOFFS(di, control))) | 410 | if (!_dma64_addrext(di, DMA64RXREGOFFS(di, control))) |
431 | DMA_ERROR("%s: DMA64 rx doesn't have AE set\n", | 411 | brcms_dbg_dma(di->core, |
432 | di->name); | 412 | "%s: DMA64 rx doesn't have AE set\n", |
413 | di->name); | ||
433 | return true; | 414 | return true; |
434 | } | 415 | } |
435 | 416 | ||
@@ -530,8 +511,9 @@ static bool dma64_alloc(struct dma_info *di, uint direction) | |||
530 | va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits, | 511 | va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits, |
531 | &alloced, &di->txdpaorig); | 512 | &alloced, &di->txdpaorig); |
532 | if (va == NULL) { | 513 | if (va == NULL) { |
533 | DMA_ERROR("%s: DMA_ALLOC_CONSISTENT(ntxd) failed\n", | 514 | brcms_dbg_dma(di->core, |
534 | di->name); | 515 | "%s: DMA_ALLOC_CONSISTENT(ntxd) failed\n", |
516 | di->name); | ||
535 | return false; | 517 | return false; |
536 | } | 518 | } |
537 | align = (1 << align_bits); | 519 | align = (1 << align_bits); |
@@ -544,8 +526,9 @@ static bool dma64_alloc(struct dma_info *di, uint direction) | |||
544 | va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits, | 526 | va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits, |
545 | &alloced, &di->rxdpaorig); | 527 | &alloced, &di->rxdpaorig); |
546 | if (va == NULL) { | 528 | if (va == NULL) { |
547 | DMA_ERROR("%s: DMA_ALLOC_CONSISTENT(nrxd) failed\n", | 529 | brcms_dbg_dma(di->core, |
548 | di->name); | 530 | "%s: DMA_ALLOC_CONSISTENT(nrxd) failed\n", |
531 | di->name); | ||
549 | return false; | 532 | return false; |
550 | } | 533 | } |
551 | align = (1 << align_bits); | 534 | align = (1 << align_bits); |
@@ -564,12 +547,13 @@ static bool _dma_alloc(struct dma_info *di, uint direction) | |||
564 | return dma64_alloc(di, direction); | 547 | return dma64_alloc(di, direction); |
565 | } | 548 | } |
566 | 549 | ||
567 | struct dma_pub *dma_attach(char *name, struct si_pub *sih, | 550 | struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc, |
568 | struct bcma_device *core, | ||
569 | uint txregbase, uint rxregbase, uint ntxd, uint nrxd, | 551 | uint txregbase, uint rxregbase, uint ntxd, uint nrxd, |
570 | uint rxbufsize, int rxextheadroom, | 552 | uint rxbufsize, int rxextheadroom, |
571 | uint nrxpost, uint rxoffset, uint *msg_level) | 553 | uint nrxpost, uint rxoffset) |
572 | { | 554 | { |
555 | struct si_pub *sih = wlc->hw->sih; | ||
556 | struct bcma_device *core = wlc->hw->d11core; | ||
573 | struct dma_info *di; | 557 | struct dma_info *di; |
574 | u8 rev = core->id.rev; | 558 | u8 rev = core->id.rev; |
575 | uint size; | 559 | uint size; |
@@ -580,9 +564,6 @@ struct dma_pub *dma_attach(char *name, struct si_pub *sih, | |||
580 | if (di == NULL) | 564 | if (di == NULL) |
581 | return NULL; | 565 | return NULL; |
582 | 566 | ||
583 | di->msg_level = msg_level ? msg_level : &dma_msg_level; | ||
584 | |||
585 | |||
586 | di->dma64 = | 567 | di->dma64 = |
587 | ((bcma_aread32(core, BCMA_IOST) & SISF_DMA64) == SISF_DMA64); | 568 | ((bcma_aread32(core, BCMA_IOST) & SISF_DMA64) == SISF_DMA64); |
588 | 569 | ||
@@ -598,11 +579,11 @@ struct dma_pub *dma_attach(char *name, struct si_pub *sih, | |||
598 | */ | 579 | */ |
599 | _dma_ctrlflags(di, DMA_CTRL_ROC | DMA_CTRL_PEN, 0); | 580 | _dma_ctrlflags(di, DMA_CTRL_ROC | DMA_CTRL_PEN, 0); |
600 | 581 | ||
601 | DMA_TRACE("%s: %s flags 0x%x ntxd %d nrxd %d " | 582 | brcms_dbg_dma(di->core, "%s: %s flags 0x%x ntxd %d nrxd %d " |
602 | "rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d " | 583 | "rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d " |
603 | "txregbase %u rxregbase %u\n", name, "DMA64", | 584 | "txregbase %u rxregbase %u\n", name, "DMA64", |
604 | di->dma.dmactrlflags, ntxd, nrxd, rxbufsize, | 585 | di->dma.dmactrlflags, ntxd, nrxd, rxbufsize, |
605 | rxextheadroom, nrxpost, rxoffset, txregbase, rxregbase); | 586 | rxextheadroom, nrxpost, rxoffset, txregbase, rxregbase); |
606 | 587 | ||
607 | /* make a private copy of our callers name */ | 588 | /* make a private copy of our callers name */ |
608 | strncpy(di->name, name, MAXNAMEL); | 589 | strncpy(di->name, name, MAXNAMEL); |
@@ -664,8 +645,8 @@ struct dma_pub *dma_attach(char *name, struct si_pub *sih, | |||
664 | di->dmadesc_align = 4; /* 16 byte alignment */ | 645 | di->dmadesc_align = 4; /* 16 byte alignment */ |
665 | } | 646 | } |
666 | 647 | ||
667 | DMA_NONE("DMA descriptor align_needed %d, align %d\n", | 648 | brcms_dbg_dma(di->core, "DMA descriptor align_needed %d, align %d\n", |
668 | di->aligndesc_4k, di->dmadesc_align); | 649 | di->aligndesc_4k, di->dmadesc_align); |
669 | 650 | ||
670 | /* allocate tx packet pointer vector */ | 651 | /* allocate tx packet pointer vector */ |
671 | if (ntxd) { | 652 | if (ntxd) { |
@@ -703,21 +684,27 @@ struct dma_pub *dma_attach(char *name, struct si_pub *sih, | |||
703 | 684 | ||
704 | if ((di->ddoffsetlow != 0) && !di->addrext) { | 685 | if ((di->ddoffsetlow != 0) && !di->addrext) { |
705 | if (di->txdpa > SI_PCI_DMA_SZ) { | 686 | if (di->txdpa > SI_PCI_DMA_SZ) { |
706 | DMA_ERROR("%s: txdpa 0x%x: addrext not supported\n", | 687 | brcms_dbg_dma(di->core, |
707 | di->name, (u32)di->txdpa); | 688 | "%s: txdpa 0x%x: addrext not supported\n", |
689 | di->name, (u32)di->txdpa); | ||
708 | goto fail; | 690 | goto fail; |
709 | } | 691 | } |
710 | if (di->rxdpa > SI_PCI_DMA_SZ) { | 692 | if (di->rxdpa > SI_PCI_DMA_SZ) { |
711 | DMA_ERROR("%s: rxdpa 0x%x: addrext not supported\n", | 693 | brcms_dbg_dma(di->core, |
712 | di->name, (u32)di->rxdpa); | 694 | "%s: rxdpa 0x%x: addrext not supported\n", |
695 | di->name, (u32)di->rxdpa); | ||
713 | goto fail; | 696 | goto fail; |
714 | } | 697 | } |
715 | } | 698 | } |
716 | 699 | ||
717 | DMA_TRACE("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh 0x%x addrext %d\n", | 700 | /* Initialize AMPDU session */ |
718 | di->ddoffsetlow, di->ddoffsethigh, | 701 | brcms_c_ampdu_reset_session(&di->ampdu_session, wlc); |
719 | di->dataoffsetlow, di->dataoffsethigh, | 702 | |
720 | di->addrext); | 703 | brcms_dbg_dma(di->core, |
704 | "ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh 0x%x addrext %d\n", | ||
705 | di->ddoffsetlow, di->ddoffsethigh, | ||
706 | di->dataoffsetlow, di->dataoffsethigh, | ||
707 | di->addrext); | ||
721 | 708 | ||
722 | return (struct dma_pub *) di; | 709 | return (struct dma_pub *) di; |
723 | 710 | ||
@@ -763,7 +750,7 @@ void dma_detach(struct dma_pub *pub) | |||
763 | { | 750 | { |
764 | struct dma_info *di = (struct dma_info *)pub; | 751 | struct dma_info *di = (struct dma_info *)pub; |
765 | 752 | ||
766 | DMA_TRACE("%s:\n", di->name); | 753 | brcms_dbg_dma(di->core, "%s:\n", di->name); |
767 | 754 | ||
768 | /* free dma descriptor rings */ | 755 | /* free dma descriptor rings */ |
769 | if (di->txd64) | 756 | if (di->txd64) |
@@ -839,7 +826,7 @@ static void _dma_rxenable(struct dma_info *di) | |||
839 | uint dmactrlflags = di->dma.dmactrlflags; | 826 | uint dmactrlflags = di->dma.dmactrlflags; |
840 | u32 control; | 827 | u32 control; |
841 | 828 | ||
842 | DMA_TRACE("%s:\n", di->name); | 829 | brcms_dbg_dma(di->core, "%s:\n", di->name); |
843 | 830 | ||
844 | control = D64_RC_RE | (bcma_read32(di->core, | 831 | control = D64_RC_RE | (bcma_read32(di->core, |
845 | DMA64RXREGOFFS(di, control)) & | 832 | DMA64RXREGOFFS(di, control)) & |
@@ -859,7 +846,7 @@ void dma_rxinit(struct dma_pub *pub) | |||
859 | { | 846 | { |
860 | struct dma_info *di = (struct dma_info *)pub; | 847 | struct dma_info *di = (struct dma_info *)pub; |
861 | 848 | ||
862 | DMA_TRACE("%s:\n", di->name); | 849 | brcms_dbg_dma(di->core, "%s:\n", di->name); |
863 | 850 | ||
864 | if (di->nrxd == 0) | 851 | if (di->nrxd == 0) |
865 | return; | 852 | return; |
@@ -954,7 +941,7 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list) | |||
954 | return 0; | 941 | return 0; |
955 | 942 | ||
956 | len = le16_to_cpu(*(__le16 *) (p->data)); | 943 | len = le16_to_cpu(*(__le16 *) (p->data)); |
957 | DMA_TRACE("%s: dma_rx len %d\n", di->name, len); | 944 | brcms_dbg_dma(di->core, "%s: dma_rx len %d\n", di->name, len); |
958 | dma_spin_for_len(len, p); | 945 | dma_spin_for_len(len, p); |
959 | 946 | ||
960 | /* set actual length */ | 947 | /* set actual length */ |
@@ -981,14 +968,15 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list) | |||
981 | DMA64RXREGOFFS(di, status0)) & | 968 | DMA64RXREGOFFS(di, status0)) & |
982 | D64_RS0_CD_MASK) - di->rcvptrbase) & | 969 | D64_RS0_CD_MASK) - di->rcvptrbase) & |
983 | D64_RS0_CD_MASK, struct dma64desc); | 970 | D64_RS0_CD_MASK, struct dma64desc); |
984 | DMA_ERROR("rxin %d rxout %d, hw_curr %d\n", | 971 | brcms_dbg_dma(di->core, |
985 | di->rxin, di->rxout, cur); | 972 | "rxin %d rxout %d, hw_curr %d\n", |
973 | di->rxin, di->rxout, cur); | ||
986 | } | 974 | } |
987 | #endif /* DEBUG */ | 975 | #endif /* DEBUG */ |
988 | 976 | ||
989 | if ((di->dma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) { | 977 | if ((di->dma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) { |
990 | DMA_ERROR("%s: bad frame length (%d)\n", | 978 | brcms_dbg_dma(di->core, "%s: bad frame length (%d)\n", |
991 | di->name, len); | 979 | di->name, len); |
992 | skb_queue_walk_safe(&dma_frames, p, next) { | 980 | skb_queue_walk_safe(&dma_frames, p, next) { |
993 | skb_unlink(p, &dma_frames); | 981 | skb_unlink(p, &dma_frames); |
994 | brcmu_pkt_buf_free_skb(p); | 982 | brcmu_pkt_buf_free_skb(p); |
@@ -1005,7 +993,7 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list) | |||
1005 | 993 | ||
1006 | static bool dma64_rxidle(struct dma_info *di) | 994 | static bool dma64_rxidle(struct dma_info *di) |
1007 | { | 995 | { |
1008 | DMA_TRACE("%s:\n", di->name); | 996 | brcms_dbg_dma(di->core, "%s:\n", di->name); |
1009 | 997 | ||
1010 | if (di->nrxd == 0) | 998 | if (di->nrxd == 0) |
1011 | return true; | 999 | return true; |
@@ -1016,6 +1004,17 @@ static bool dma64_rxidle(struct dma_info *di) | |||
1016 | D64_RS0_CD_MASK)); | 1004 | D64_RS0_CD_MASK)); |
1017 | } | 1005 | } |
1018 | 1006 | ||
1007 | static bool dma64_txidle(struct dma_info *di) | ||
1008 | { | ||
1009 | if (di->ntxd == 0) | ||
1010 | return true; | ||
1011 | |||
1012 | return ((bcma_read32(di->core, | ||
1013 | DMA64TXREGOFFS(di, status0)) & D64_XS0_CD_MASK) == | ||
1014 | (bcma_read32(di->core, DMA64TXREGOFFS(di, ptr)) & | ||
1015 | D64_XS0_CD_MASK)); | ||
1016 | } | ||
1017 | |||
1019 | /* | 1018 | /* |
1020 | * post receive buffers | 1019 | * post receive buffers |
1021 | * return false is refill failed completely and ring is empty this will stall | 1020 | * return false is refill failed completely and ring is empty this will stall |
@@ -1047,7 +1046,7 @@ bool dma_rxfill(struct dma_pub *pub) | |||
1047 | 1046 | ||
1048 | n = di->nrxpost - nrxdactive(di, rxin, rxout); | 1047 | n = di->nrxpost - nrxdactive(di, rxin, rxout); |
1049 | 1048 | ||
1050 | DMA_TRACE("%s: post %d\n", di->name, n); | 1049 | brcms_dbg_dma(di->core, "%s: post %d\n", di->name, n); |
1051 | 1050 | ||
1052 | if (di->rxbufsize > BCMEXTRAHDROOM) | 1051 | if (di->rxbufsize > BCMEXTRAHDROOM) |
1053 | extra_offset = di->rxextrahdrroom; | 1052 | extra_offset = di->rxextrahdrroom; |
@@ -1060,9 +1059,11 @@ bool dma_rxfill(struct dma_pub *pub) | |||
1060 | p = brcmu_pkt_buf_get_skb(di->rxbufsize + extra_offset); | 1059 | p = brcmu_pkt_buf_get_skb(di->rxbufsize + extra_offset); |
1061 | 1060 | ||
1062 | if (p == NULL) { | 1061 | if (p == NULL) { |
1063 | DMA_ERROR("%s: out of rxbufs\n", di->name); | 1062 | brcms_dbg_dma(di->core, "%s: out of rxbufs\n", |
1063 | di->name); | ||
1064 | if (i == 0 && dma64_rxidle(di)) { | 1064 | if (i == 0 && dma64_rxidle(di)) { |
1065 | DMA_ERROR("%s: ring is empty !\n", di->name); | 1065 | brcms_dbg_dma(di->core, "%s: ring is empty !\n", |
1066 | di->name); | ||
1066 | ring_empty = true; | 1067 | ring_empty = true; |
1067 | } | 1068 | } |
1068 | di->dma.rxnobuf++; | 1069 | di->dma.rxnobuf++; |
@@ -1107,7 +1108,7 @@ void dma_rxreclaim(struct dma_pub *pub) | |||
1107 | struct dma_info *di = (struct dma_info *)pub; | 1108 | struct dma_info *di = (struct dma_info *)pub; |
1108 | struct sk_buff *p; | 1109 | struct sk_buff *p; |
1109 | 1110 | ||
1110 | DMA_TRACE("%s:\n", di->name); | 1111 | brcms_dbg_dma(di->core, "%s:\n", di->name); |
1111 | 1112 | ||
1112 | while ((p = _dma_getnextrxp(di, true))) | 1113 | while ((p = _dma_getnextrxp(di, true))) |
1113 | brcmu_pkt_buf_free_skb(p); | 1114 | brcmu_pkt_buf_free_skb(p); |
@@ -1138,7 +1139,7 @@ void dma_txinit(struct dma_pub *pub) | |||
1138 | struct dma_info *di = (struct dma_info *)pub; | 1139 | struct dma_info *di = (struct dma_info *)pub; |
1139 | u32 control = D64_XC_XE; | 1140 | u32 control = D64_XC_XE; |
1140 | 1141 | ||
1141 | DMA_TRACE("%s:\n", di->name); | 1142 | brcms_dbg_dma(di->core, "%s:\n", di->name); |
1142 | 1143 | ||
1143 | if (di->ntxd == 0) | 1144 | if (di->ntxd == 0) |
1144 | return; | 1145 | return; |
@@ -1170,7 +1171,7 @@ void dma_txsuspend(struct dma_pub *pub) | |||
1170 | { | 1171 | { |
1171 | struct dma_info *di = (struct dma_info *)pub; | 1172 | struct dma_info *di = (struct dma_info *)pub; |
1172 | 1173 | ||
1173 | DMA_TRACE("%s:\n", di->name); | 1174 | brcms_dbg_dma(di->core, "%s:\n", di->name); |
1174 | 1175 | ||
1175 | if (di->ntxd == 0) | 1176 | if (di->ntxd == 0) |
1176 | return; | 1177 | return; |
@@ -1182,7 +1183,7 @@ void dma_txresume(struct dma_pub *pub) | |||
1182 | { | 1183 | { |
1183 | struct dma_info *di = (struct dma_info *)pub; | 1184 | struct dma_info *di = (struct dma_info *)pub; |
1184 | 1185 | ||
1185 | DMA_TRACE("%s:\n", di->name); | 1186 | brcms_dbg_dma(di->core, "%s:\n", di->name); |
1186 | 1187 | ||
1187 | if (di->ntxd == 0) | 1188 | if (di->ntxd == 0) |
1188 | return; | 1189 | return; |
@@ -1205,11 +1206,11 @@ void dma_txreclaim(struct dma_pub *pub, enum txd_range range) | |||
1205 | struct dma_info *di = (struct dma_info *)pub; | 1206 | struct dma_info *di = (struct dma_info *)pub; |
1206 | struct sk_buff *p; | 1207 | struct sk_buff *p; |
1207 | 1208 | ||
1208 | DMA_TRACE("%s: %s\n", | 1209 | brcms_dbg_dma(di->core, "%s: %s\n", |
1209 | di->name, | 1210 | di->name, |
1210 | range == DMA_RANGE_ALL ? "all" : | 1211 | range == DMA_RANGE_ALL ? "all" : |
1211 | range == DMA_RANGE_TRANSMITTED ? "transmitted" : | 1212 | range == DMA_RANGE_TRANSMITTED ? "transmitted" : |
1212 | "transferred"); | 1213 | "transferred"); |
1213 | 1214 | ||
1214 | if (di->txin == di->txout) | 1215 | if (di->txin == di->txout) |
1215 | return; | 1216 | return; |
@@ -1264,39 +1265,25 @@ bool dma_rxreset(struct dma_pub *pub) | |||
1264 | return status == D64_RS0_RS_DISABLED; | 1265 | return status == D64_RS0_RS_DISABLED; |
1265 | } | 1266 | } |
1266 | 1267 | ||
1267 | /* | 1268 | static void dma_txenq(struct dma_info *di, struct sk_buff *p) |
1268 | * !! tx entry routine | ||
1269 | * WARNING: call must check the return value for error. | ||
1270 | * the error(toss frames) could be fatal and cause many subsequent hard | ||
1271 | * to debug problems | ||
1272 | */ | ||
1273 | int dma_txfast(struct dma_pub *pub, struct sk_buff *p, bool commit) | ||
1274 | { | 1269 | { |
1275 | struct dma_info *di = (struct dma_info *)pub; | ||
1276 | unsigned char *data; | 1270 | unsigned char *data; |
1277 | uint len; | 1271 | uint len; |
1278 | u16 txout; | 1272 | u16 txout; |
1279 | u32 flags = 0; | 1273 | u32 flags = 0; |
1280 | dma_addr_t pa; | 1274 | dma_addr_t pa; |
1281 | 1275 | ||
1282 | DMA_TRACE("%s:\n", di->name); | ||
1283 | |||
1284 | txout = di->txout; | 1276 | txout = di->txout; |
1285 | 1277 | ||
1278 | if (WARN_ON(nexttxd(di, txout) == di->txin)) | ||
1279 | return; | ||
1280 | |||
1286 | /* | 1281 | /* |
1287 | * obtain and initialize transmit descriptor entry. | 1282 | * obtain and initialize transmit descriptor entry. |
1288 | */ | 1283 | */ |
1289 | data = p->data; | 1284 | data = p->data; |
1290 | len = p->len; | 1285 | len = p->len; |
1291 | 1286 | ||
1292 | /* no use to transmit a zero length packet */ | ||
1293 | if (len == 0) | ||
1294 | return 0; | ||
1295 | |||
1296 | /* return nonzero if out of tx descriptors */ | ||
1297 | if (nexttxd(di, txout) == di->txin) | ||
1298 | goto outoftxd; | ||
1299 | |||
1300 | /* get physical address of buffer start */ | 1287 | /* get physical address of buffer start */ |
1301 | pa = dma_map_single(di->dmadev, data, len, DMA_TO_DEVICE); | 1288 | pa = dma_map_single(di->dmadev, data, len, DMA_TO_DEVICE); |
1302 | 1289 | ||
@@ -1318,23 +1305,147 @@ int dma_txfast(struct dma_pub *pub, struct sk_buff *p, bool commit) | |||
1318 | 1305 | ||
1319 | /* bump the tx descriptor index */ | 1306 | /* bump the tx descriptor index */ |
1320 | di->txout = txout; | 1307 | di->txout = txout; |
1308 | } | ||
1321 | 1309 | ||
1322 | /* kick the chip */ | 1310 | static void ampdu_finalize(struct dma_info *di) |
1323 | if (commit) | 1311 | { |
1324 | bcma_write32(di->core, DMA64TXREGOFFS(di, ptr), | 1312 | struct brcms_ampdu_session *session = &di->ampdu_session; |
1325 | di->xmtptrbase + I2B(txout, struct dma64desc)); | 1313 | struct sk_buff *p; |
1314 | |||
1315 | trace_brcms_ampdu_session(&session->wlc->hw->d11core->dev, | ||
1316 | session->max_ampdu_len, | ||
1317 | session->max_ampdu_frames, | ||
1318 | session->ampdu_len, | ||
1319 | skb_queue_len(&session->skb_list), | ||
1320 | session->dma_len); | ||
1321 | |||
1322 | if (WARN_ON(skb_queue_empty(&session->skb_list))) | ||
1323 | return; | ||
1324 | |||
1325 | brcms_c_ampdu_finalize(session); | ||
1326 | |||
1327 | while (!skb_queue_empty(&session->skb_list)) { | ||
1328 | p = skb_dequeue(&session->skb_list); | ||
1329 | dma_txenq(di, p); | ||
1330 | } | ||
1331 | |||
1332 | bcma_write32(di->core, DMA64TXREGOFFS(di, ptr), | ||
1333 | di->xmtptrbase + I2B(di->txout, struct dma64desc)); | ||
1334 | brcms_c_ampdu_reset_session(session, session->wlc); | ||
1335 | } | ||
1336 | |||
1337 | static void prep_ampdu_frame(struct dma_info *di, struct sk_buff *p) | ||
1338 | { | ||
1339 | struct brcms_ampdu_session *session = &di->ampdu_session; | ||
1340 | int ret; | ||
1341 | |||
1342 | ret = brcms_c_ampdu_add_frame(session, p); | ||
1343 | if (ret == -ENOSPC) { | ||
1344 | /* | ||
1345 | * AMPDU cannot accomodate this frame. Close out the in- | ||
1346 | * progress AMPDU session and start a new one. | ||
1347 | */ | ||
1348 | ampdu_finalize(di); | ||
1349 | ret = brcms_c_ampdu_add_frame(session, p); | ||
1350 | } | ||
1351 | |||
1352 | WARN_ON(ret); | ||
1353 | } | ||
1354 | |||
1355 | /* Update count of available tx descriptors based on current DMA state */ | ||
1356 | static void dma_update_txavail(struct dma_info *di) | ||
1357 | { | ||
1358 | /* | ||
1359 | * Available space is number of descriptors less the number of | ||
1360 | * active descriptors and the number of queued AMPDU frames. | ||
1361 | */ | ||
1362 | di->dma.txavail = di->ntxd - ntxdactive(di, di->txin, di->txout) - | ||
1363 | skb_queue_len(&di->ampdu_session.skb_list) - 1; | ||
1364 | } | ||
1365 | |||
1366 | /* | ||
1367 | * !! tx entry routine | ||
1368 | * WARNING: call must check the return value for error. | ||
1369 | * the error(toss frames) could be fatal and cause many subsequent hard | ||
1370 | * to debug problems | ||
1371 | */ | ||
1372 | int dma_txfast(struct brcms_c_info *wlc, struct dma_pub *pub, | ||
1373 | struct sk_buff *p) | ||
1374 | { | ||
1375 | struct dma_info *di = (struct dma_info *)pub; | ||
1376 | struct brcms_ampdu_session *session = &di->ampdu_session; | ||
1377 | struct ieee80211_tx_info *tx_info; | ||
1378 | bool is_ampdu; | ||
1379 | |||
1380 | /* no use to transmit a zero length packet */ | ||
1381 | if (p->len == 0) | ||
1382 | return 0; | ||
1383 | |||
1384 | /* return nonzero if out of tx descriptors */ | ||
1385 | if (di->dma.txavail == 0 || nexttxd(di, di->txout) == di->txin) | ||
1386 | goto outoftxd; | ||
1387 | |||
1388 | tx_info = IEEE80211_SKB_CB(p); | ||
1389 | is_ampdu = tx_info->flags & IEEE80211_TX_CTL_AMPDU; | ||
1390 | if (is_ampdu) | ||
1391 | prep_ampdu_frame(di, p); | ||
1392 | else | ||
1393 | dma_txenq(di, p); | ||
1326 | 1394 | ||
1327 | /* tx flow control */ | 1395 | /* tx flow control */ |
1328 | di->dma.txavail = di->ntxd - ntxdactive(di, di->txin, di->txout) - 1; | 1396 | dma_update_txavail(di); |
1397 | |||
1398 | /* kick the chip */ | ||
1399 | if (is_ampdu) { | ||
1400 | /* | ||
1401 | * Start sending data if we've got a full AMPDU, there's | ||
1402 | * no more space in the DMA ring, or the ring isn't | ||
1403 | * currently transmitting. | ||
1404 | */ | ||
1405 | if (skb_queue_len(&session->skb_list) == session->max_ampdu_frames || | ||
1406 | di->dma.txavail == 0 || dma64_txidle(di)) | ||
1407 | ampdu_finalize(di); | ||
1408 | } else { | ||
1409 | bcma_write32(di->core, DMA64TXREGOFFS(di, ptr), | ||
1410 | di->xmtptrbase + I2B(di->txout, struct dma64desc)); | ||
1411 | } | ||
1329 | 1412 | ||
1330 | return 0; | 1413 | return 0; |
1331 | 1414 | ||
1332 | outoftxd: | 1415 | outoftxd: |
1333 | DMA_ERROR("%s: out of txds !!!\n", di->name); | 1416 | brcms_dbg_dma(di->core, "%s: out of txds !!!\n", di->name); |
1334 | brcmu_pkt_buf_free_skb(p); | 1417 | brcmu_pkt_buf_free_skb(p); |
1335 | di->dma.txavail = 0; | 1418 | di->dma.txavail = 0; |
1336 | di->dma.txnobuf++; | 1419 | di->dma.txnobuf++; |
1337 | return -1; | 1420 | return -ENOSPC; |
1421 | } | ||
1422 | |||
1423 | void dma_txflush(struct dma_pub *pub) | ||
1424 | { | ||
1425 | struct dma_info *di = (struct dma_info *)pub; | ||
1426 | struct brcms_ampdu_session *session = &di->ampdu_session; | ||
1427 | |||
1428 | if (!skb_queue_empty(&session->skb_list)) | ||
1429 | ampdu_finalize(di); | ||
1430 | } | ||
1431 | |||
1432 | int dma_txpending(struct dma_pub *pub) | ||
1433 | { | ||
1434 | struct dma_info *di = (struct dma_info *)pub; | ||
1435 | return ntxdactive(di, di->txin, di->txout); | ||
1436 | } | ||
1437 | |||
1438 | /* | ||
1439 | * If we have an active AMPDU session and are not transmitting, | ||
1440 | * this function will force tx to start. | ||
1441 | */ | ||
1442 | void dma_kick_tx(struct dma_pub *pub) | ||
1443 | { | ||
1444 | struct dma_info *di = (struct dma_info *)pub; | ||
1445 | struct brcms_ampdu_session *session = &di->ampdu_session; | ||
1446 | |||
1447 | if (!skb_queue_empty(&session->skb_list) && dma64_txidle(di)) | ||
1448 | ampdu_finalize(di); | ||
1338 | } | 1449 | } |
1339 | 1450 | ||
1340 | /* | 1451 | /* |
@@ -1354,11 +1465,11 @@ struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range) | |||
1354 | u16 active_desc; | 1465 | u16 active_desc; |
1355 | struct sk_buff *txp; | 1466 | struct sk_buff *txp; |
1356 | 1467 | ||
1357 | DMA_TRACE("%s: %s\n", | 1468 | brcms_dbg_dma(di->core, "%s: %s\n", |
1358 | di->name, | 1469 | di->name, |
1359 | range == DMA_RANGE_ALL ? "all" : | 1470 | range == DMA_RANGE_ALL ? "all" : |
1360 | range == DMA_RANGE_TRANSMITTED ? "transmitted" : | 1471 | range == DMA_RANGE_TRANSMITTED ? "transmitted" : |
1361 | "transferred"); | 1472 | "transferred"); |
1362 | 1473 | ||
1363 | if (di->ntxd == 0) | 1474 | if (di->ntxd == 0) |
1364 | return NULL; | 1475 | return NULL; |
@@ -1412,13 +1523,13 @@ struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range) | |||
1412 | di->txin = i; | 1523 | di->txin = i; |
1413 | 1524 | ||
1414 | /* tx flow control */ | 1525 | /* tx flow control */ |
1415 | di->dma.txavail = di->ntxd - ntxdactive(di, di->txin, di->txout) - 1; | 1526 | dma_update_txavail(di); |
1416 | 1527 | ||
1417 | return txp; | 1528 | return txp; |
1418 | 1529 | ||
1419 | bogus: | 1530 | bogus: |
1420 | DMA_NONE("bogus curr: start %d end %d txout %d\n", | 1531 | brcms_dbg_dma(di->core, "bogus curr: start %d end %d txout %d\n", |
1421 | start, end, di->txout); | 1532 | start, end, di->txout); |
1422 | return NULL; | 1533 | return NULL; |
1423 | } | 1534 | } |
1424 | 1535 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.h b/drivers/net/wireless/brcm80211/brcmsmac/dma.h index cc269ee5c499..ff5b80b09046 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/dma.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.h | |||
@@ -74,12 +74,11 @@ struct dma_pub { | |||
74 | uint txnobuf; /* tx out of dma descriptors */ | 74 | uint txnobuf; /* tx out of dma descriptors */ |
75 | }; | 75 | }; |
76 | 76 | ||
77 | extern struct dma_pub *dma_attach(char *name, struct si_pub *sih, | 77 | extern struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc, |
78 | struct bcma_device *d11core, | ||
79 | uint txregbase, uint rxregbase, | 78 | uint txregbase, uint rxregbase, |
80 | uint ntxd, uint nrxd, | 79 | uint ntxd, uint nrxd, |
81 | uint rxbufsize, int rxextheadroom, | 80 | uint rxbufsize, int rxextheadroom, |
82 | uint nrxpost, uint rxoffset, uint *msg_level); | 81 | uint nrxpost, uint rxoffset); |
83 | 82 | ||
84 | void dma_rxinit(struct dma_pub *pub); | 83 | void dma_rxinit(struct dma_pub *pub); |
85 | int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list); | 84 | int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list); |
@@ -87,7 +86,11 @@ bool dma_rxfill(struct dma_pub *pub); | |||
87 | bool dma_rxreset(struct dma_pub *pub); | 86 | bool dma_rxreset(struct dma_pub *pub); |
88 | bool dma_txreset(struct dma_pub *pub); | 87 | bool dma_txreset(struct dma_pub *pub); |
89 | void dma_txinit(struct dma_pub *pub); | 88 | void dma_txinit(struct dma_pub *pub); |
90 | int dma_txfast(struct dma_pub *pub, struct sk_buff *p0, bool commit); | 89 | int dma_txfast(struct brcms_c_info *wlc, struct dma_pub *pub, |
90 | struct sk_buff *p0); | ||
91 | void dma_txflush(struct dma_pub *pub); | ||
92 | int dma_txpending(struct dma_pub *pub); | ||
93 | void dma_kick_tx(struct dma_pub *pub); | ||
91 | void dma_txsuspend(struct dma_pub *pub); | 94 | void dma_txsuspend(struct dma_pub *pub); |
92 | bool dma_txsuspended(struct dma_pub *pub); | 95 | bool dma_txsuspended(struct dma_pub *pub); |
93 | void dma_txresume(struct dma_pub *pub); | 96 | void dma_txresume(struct dma_pub *pub); |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index a744ea5a9559..1710ccba8bac 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include "ucode_loader.h" | 33 | #include "ucode_loader.h" |
34 | #include "mac80211_if.h" | 34 | #include "mac80211_if.h" |
35 | #include "main.h" | 35 | #include "main.h" |
36 | #include "debug.h" | ||
36 | 37 | ||
37 | #define N_TX_QUEUES 4 /* #tx queues on mac80211<->driver interface */ | 38 | #define N_TX_QUEUES 4 /* #tx queues on mac80211<->driver interface */ |
38 | 39 | ||
@@ -98,10 +99,14 @@ static struct bcma_device_id brcms_coreid_table[] = { | |||
98 | }; | 99 | }; |
99 | MODULE_DEVICE_TABLE(bcma, brcms_coreid_table); | 100 | MODULE_DEVICE_TABLE(bcma, brcms_coreid_table); |
100 | 101 | ||
101 | #ifdef DEBUG | 102 | #if defined(CONFIG_BRCMDBG) |
102 | static int msglevel = 0xdeadbeef; | 103 | /* |
103 | module_param(msglevel, int, 0); | 104 | * Module parameter for setting the debug message level. Available |
104 | #endif /* DEBUG */ | 105 | * flags are specified by the BRCM_DL_* macros in |
106 | * drivers/net/wireless/brcm80211/include/defs.h. | ||
107 | */ | ||
108 | module_param_named(debug, brcm_msg_level, uint, S_IRUGO | S_IWUSR); | ||
109 | #endif | ||
105 | 110 | ||
106 | static struct ieee80211_channel brcms_2ghz_chantable[] = { | 111 | static struct ieee80211_channel brcms_2ghz_chantable[] = { |
107 | CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS), | 112 | CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS), |
@@ -276,7 +281,7 @@ static void brcms_ops_tx(struct ieee80211_hw *hw, | |||
276 | 281 | ||
277 | spin_lock_bh(&wl->lock); | 282 | spin_lock_bh(&wl->lock); |
278 | if (!wl->pub->up) { | 283 | if (!wl->pub->up) { |
279 | wiphy_err(wl->wiphy, "ops->tx called while down\n"); | 284 | brcms_err(wl->wlc->hw->d11core, "ops->tx called while down\n"); |
280 | kfree_skb(skb); | 285 | kfree_skb(skb); |
281 | goto done; | 286 | goto done; |
282 | } | 287 | } |
@@ -313,8 +318,8 @@ static int brcms_ops_start(struct ieee80211_hw *hw) | |||
313 | spin_unlock_bh(&wl->lock); | 318 | spin_unlock_bh(&wl->lock); |
314 | 319 | ||
315 | if (err != 0) | 320 | if (err != 0) |
316 | wiphy_err(hw->wiphy, "%s: brcms_up() returned %d\n", __func__, | 321 | brcms_err(wl->wlc->hw->d11core, "%s: brcms_up() returned %d\n", |
317 | err); | 322 | __func__, err); |
318 | return err; | 323 | return err; |
319 | } | 324 | } |
320 | 325 | ||
@@ -332,7 +337,7 @@ static void brcms_ops_stop(struct ieee80211_hw *hw) | |||
332 | status = brcms_c_chipmatch(wl->wlc->hw->d11core); | 337 | status = brcms_c_chipmatch(wl->wlc->hw->d11core); |
333 | spin_unlock_bh(&wl->lock); | 338 | spin_unlock_bh(&wl->lock); |
334 | if (!status) { | 339 | if (!status) { |
335 | wiphy_err(wl->wiphy, | 340 | brcms_err(wl->wlc->hw->d11core, |
336 | "wl: brcms_ops_stop: chipmatch failed\n"); | 341 | "wl: brcms_ops_stop: chipmatch failed\n"); |
337 | return; | 342 | return; |
338 | } | 343 | } |
@@ -350,8 +355,9 @@ brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | |||
350 | 355 | ||
351 | /* Just STA for now */ | 356 | /* Just STA for now */ |
352 | if (vif->type != NL80211_IFTYPE_STATION) { | 357 | if (vif->type != NL80211_IFTYPE_STATION) { |
353 | wiphy_err(hw->wiphy, "%s: Attempt to add type %d, only" | 358 | brcms_err(wl->wlc->hw->d11core, |
354 | " STA for now\n", __func__, vif->type); | 359 | "%s: Attempt to add type %d, only STA for now\n", |
360 | __func__, vif->type); | ||
355 | return -EOPNOTSUPP; | 361 | return -EOPNOTSUPP; |
356 | } | 362 | } |
357 | 363 | ||
@@ -370,9 +376,9 @@ static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed) | |||
370 | { | 376 | { |
371 | struct ieee80211_conf *conf = &hw->conf; | 377 | struct ieee80211_conf *conf = &hw->conf; |
372 | struct brcms_info *wl = hw->priv; | 378 | struct brcms_info *wl = hw->priv; |
379 | struct bcma_device *core = wl->wlc->hw->d11core; | ||
373 | int err = 0; | 380 | int err = 0; |
374 | int new_int; | 381 | int new_int; |
375 | struct wiphy *wiphy = hw->wiphy; | ||
376 | 382 | ||
377 | spin_lock_bh(&wl->lock); | 383 | spin_lock_bh(&wl->lock); |
378 | if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { | 384 | if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { |
@@ -380,25 +386,26 @@ static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed) | |||
380 | conf->listen_interval); | 386 | conf->listen_interval); |
381 | } | 387 | } |
382 | if (changed & IEEE80211_CONF_CHANGE_MONITOR) | 388 | if (changed & IEEE80211_CONF_CHANGE_MONITOR) |
383 | wiphy_dbg(wiphy, "%s: change monitor mode: %s\n", | 389 | brcms_dbg_info(core, "%s: change monitor mode: %s\n", |
384 | __func__, conf->flags & IEEE80211_CONF_MONITOR ? | 390 | __func__, conf->flags & IEEE80211_CONF_MONITOR ? |
385 | "true" : "false"); | 391 | "true" : "false"); |
386 | if (changed & IEEE80211_CONF_CHANGE_PS) | 392 | if (changed & IEEE80211_CONF_CHANGE_PS) |
387 | wiphy_err(wiphy, "%s: change power-save mode: %s (implement)\n", | 393 | brcms_err(core, "%s: change power-save mode: %s (implement)\n", |
388 | __func__, conf->flags & IEEE80211_CONF_PS ? | 394 | __func__, conf->flags & IEEE80211_CONF_PS ? |
389 | "true" : "false"); | 395 | "true" : "false"); |
390 | 396 | ||
391 | if (changed & IEEE80211_CONF_CHANGE_POWER) { | 397 | if (changed & IEEE80211_CONF_CHANGE_POWER) { |
392 | err = brcms_c_set_tx_power(wl->wlc, conf->power_level); | 398 | err = brcms_c_set_tx_power(wl->wlc, conf->power_level); |
393 | if (err < 0) { | 399 | if (err < 0) { |
394 | wiphy_err(wiphy, "%s: Error setting power_level\n", | 400 | brcms_err(core, "%s: Error setting power_level\n", |
395 | __func__); | 401 | __func__); |
396 | goto config_out; | 402 | goto config_out; |
397 | } | 403 | } |
398 | new_int = brcms_c_get_tx_power(wl->wlc); | 404 | new_int = brcms_c_get_tx_power(wl->wlc); |
399 | if (new_int != conf->power_level) | 405 | if (new_int != conf->power_level) |
400 | wiphy_err(wiphy, "%s: Power level req != actual, %d %d" | 406 | brcms_err(core, |
401 | "\n", __func__, conf->power_level, | 407 | "%s: Power level req != actual, %d %d\n", |
408 | __func__, conf->power_level, | ||
402 | new_int); | 409 | new_int); |
403 | } | 410 | } |
404 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | 411 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { |
@@ -425,13 +432,13 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw, | |||
425 | struct ieee80211_bss_conf *info, u32 changed) | 432 | struct ieee80211_bss_conf *info, u32 changed) |
426 | { | 433 | { |
427 | struct brcms_info *wl = hw->priv; | 434 | struct brcms_info *wl = hw->priv; |
428 | struct wiphy *wiphy = hw->wiphy; | 435 | struct bcma_device *core = wl->wlc->hw->d11core; |
429 | 436 | ||
430 | if (changed & BSS_CHANGED_ASSOC) { | 437 | if (changed & BSS_CHANGED_ASSOC) { |
431 | /* association status changed (associated/disassociated) | 438 | /* association status changed (associated/disassociated) |
432 | * also implies a change in the AID. | 439 | * also implies a change in the AID. |
433 | */ | 440 | */ |
434 | wiphy_err(wiphy, "%s: %s: %sassociated\n", KBUILD_MODNAME, | 441 | brcms_err(core, "%s: %s: %sassociated\n", KBUILD_MODNAME, |
435 | __func__, info->assoc ? "" : "dis"); | 442 | __func__, info->assoc ? "" : "dis"); |
436 | spin_lock_bh(&wl->lock); | 443 | spin_lock_bh(&wl->lock); |
437 | brcms_c_associate_upd(wl->wlc, info->assoc); | 444 | brcms_c_associate_upd(wl->wlc, info->assoc); |
@@ -491,7 +498,7 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw, | |||
491 | error = brcms_c_set_rateset(wl->wlc, &rs); | 498 | error = brcms_c_set_rateset(wl->wlc, &rs); |
492 | spin_unlock_bh(&wl->lock); | 499 | spin_unlock_bh(&wl->lock); |
493 | if (error) | 500 | if (error) |
494 | wiphy_err(wiphy, "changing basic rates failed: %d\n", | 501 | brcms_err(core, "changing basic rates failed: %d\n", |
495 | error); | 502 | error); |
496 | } | 503 | } |
497 | if (changed & BSS_CHANGED_BEACON_INT) { | 504 | if (changed & BSS_CHANGED_BEACON_INT) { |
@@ -508,30 +515,30 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw, | |||
508 | } | 515 | } |
509 | if (changed & BSS_CHANGED_BEACON) | 516 | if (changed & BSS_CHANGED_BEACON) |
510 | /* Beacon data changed, retrieve new beacon (beaconing modes) */ | 517 | /* Beacon data changed, retrieve new beacon (beaconing modes) */ |
511 | wiphy_err(wiphy, "%s: beacon changed\n", __func__); | 518 | brcms_err(core, "%s: beacon changed\n", __func__); |
512 | 519 | ||
513 | if (changed & BSS_CHANGED_BEACON_ENABLED) { | 520 | if (changed & BSS_CHANGED_BEACON_ENABLED) { |
514 | /* Beaconing should be enabled/disabled (beaconing modes) */ | 521 | /* Beaconing should be enabled/disabled (beaconing modes) */ |
515 | wiphy_err(wiphy, "%s: Beacon enabled: %s\n", __func__, | 522 | brcms_err(core, "%s: Beacon enabled: %s\n", __func__, |
516 | info->enable_beacon ? "true" : "false"); | 523 | info->enable_beacon ? "true" : "false"); |
517 | } | 524 | } |
518 | 525 | ||
519 | if (changed & BSS_CHANGED_CQM) { | 526 | if (changed & BSS_CHANGED_CQM) { |
520 | /* Connection quality monitor config changed */ | 527 | /* Connection quality monitor config changed */ |
521 | wiphy_err(wiphy, "%s: cqm change: threshold %d, hys %d " | 528 | brcms_err(core, "%s: cqm change: threshold %d, hys %d " |
522 | " (implement)\n", __func__, info->cqm_rssi_thold, | 529 | " (implement)\n", __func__, info->cqm_rssi_thold, |
523 | info->cqm_rssi_hyst); | 530 | info->cqm_rssi_hyst); |
524 | } | 531 | } |
525 | 532 | ||
526 | if (changed & BSS_CHANGED_IBSS) { | 533 | if (changed & BSS_CHANGED_IBSS) { |
527 | /* IBSS join status changed */ | 534 | /* IBSS join status changed */ |
528 | wiphy_err(wiphy, "%s: IBSS joined: %s (implement)\n", __func__, | 535 | brcms_err(core, "%s: IBSS joined: %s (implement)\n", |
529 | info->ibss_joined ? "true" : "false"); | 536 | __func__, info->ibss_joined ? "true" : "false"); |
530 | } | 537 | } |
531 | 538 | ||
532 | if (changed & BSS_CHANGED_ARP_FILTER) { | 539 | if (changed & BSS_CHANGED_ARP_FILTER) { |
533 | /* Hardware ARP filter address list or state changed */ | 540 | /* Hardware ARP filter address list or state changed */ |
534 | wiphy_err(wiphy, "%s: arp filtering: enabled %s, count %d" | 541 | brcms_err(core, "%s: arp filtering: enabled %s, count %d" |
535 | " (implement)\n", __func__, info->arp_filter_enabled ? | 542 | " (implement)\n", __func__, info->arp_filter_enabled ? |
536 | "true" : "false", info->arp_addr_cnt); | 543 | "true" : "false", info->arp_addr_cnt); |
537 | } | 544 | } |
@@ -541,8 +548,8 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw, | |||
541 | * QoS for this association was enabled/disabled. | 548 | * QoS for this association was enabled/disabled. |
542 | * Note that it is only ever disabled for station mode. | 549 | * Note that it is only ever disabled for station mode. |
543 | */ | 550 | */ |
544 | wiphy_err(wiphy, "%s: qos enabled: %s (implement)\n", __func__, | 551 | brcms_err(core, "%s: qos enabled: %s (implement)\n", |
545 | info->qos ? "true" : "false"); | 552 | __func__, info->qos ? "true" : "false"); |
546 | } | 553 | } |
547 | return; | 554 | return; |
548 | } | 555 | } |
@@ -553,25 +560,25 @@ brcms_ops_configure_filter(struct ieee80211_hw *hw, | |||
553 | unsigned int *total_flags, u64 multicast) | 560 | unsigned int *total_flags, u64 multicast) |
554 | { | 561 | { |
555 | struct brcms_info *wl = hw->priv; | 562 | struct brcms_info *wl = hw->priv; |
556 | struct wiphy *wiphy = hw->wiphy; | 563 | struct bcma_device *core = wl->wlc->hw->d11core; |
557 | 564 | ||
558 | changed_flags &= MAC_FILTERS; | 565 | changed_flags &= MAC_FILTERS; |
559 | *total_flags &= MAC_FILTERS; | 566 | *total_flags &= MAC_FILTERS; |
560 | 567 | ||
561 | if (changed_flags & FIF_PROMISC_IN_BSS) | 568 | if (changed_flags & FIF_PROMISC_IN_BSS) |
562 | wiphy_dbg(wiphy, "FIF_PROMISC_IN_BSS\n"); | 569 | brcms_dbg_info(core, "FIF_PROMISC_IN_BSS\n"); |
563 | if (changed_flags & FIF_ALLMULTI) | 570 | if (changed_flags & FIF_ALLMULTI) |
564 | wiphy_dbg(wiphy, "FIF_ALLMULTI\n"); | 571 | brcms_dbg_info(core, "FIF_ALLMULTI\n"); |
565 | if (changed_flags & FIF_FCSFAIL) | 572 | if (changed_flags & FIF_FCSFAIL) |
566 | wiphy_dbg(wiphy, "FIF_FCSFAIL\n"); | 573 | brcms_dbg_info(core, "FIF_FCSFAIL\n"); |
567 | if (changed_flags & FIF_CONTROL) | 574 | if (changed_flags & FIF_CONTROL) |
568 | wiphy_dbg(wiphy, "FIF_CONTROL\n"); | 575 | brcms_dbg_info(core, "FIF_CONTROL\n"); |
569 | if (changed_flags & FIF_OTHER_BSS) | 576 | if (changed_flags & FIF_OTHER_BSS) |
570 | wiphy_dbg(wiphy, "FIF_OTHER_BSS\n"); | 577 | brcms_dbg_info(core, "FIF_OTHER_BSS\n"); |
571 | if (changed_flags & FIF_PSPOLL) | 578 | if (changed_flags & FIF_PSPOLL) |
572 | wiphy_dbg(wiphy, "FIF_PSPOLL\n"); | 579 | brcms_dbg_info(core, "FIF_PSPOLL\n"); |
573 | if (changed_flags & FIF_BCN_PRBRESP_PROMISC) | 580 | if (changed_flags & FIF_BCN_PRBRESP_PROMISC) |
574 | wiphy_dbg(wiphy, "FIF_BCN_PRBRESP_PROMISC\n"); | 581 | brcms_dbg_info(core, "FIF_BCN_PRBRESP_PROMISC\n"); |
575 | 582 | ||
576 | spin_lock_bh(&wl->lock); | 583 | spin_lock_bh(&wl->lock); |
577 | brcms_c_mac_promisc(wl->wlc, *total_flags); | 584 | brcms_c_mac_promisc(wl->wlc, *total_flags); |
@@ -653,8 +660,8 @@ brcms_ops_ampdu_action(struct ieee80211_hw *hw, | |||
653 | status = brcms_c_aggregatable(wl->wlc, tid); | 660 | status = brcms_c_aggregatable(wl->wlc, tid); |
654 | spin_unlock_bh(&wl->lock); | 661 | spin_unlock_bh(&wl->lock); |
655 | if (!status) { | 662 | if (!status) { |
656 | wiphy_err(wl->wiphy, "START: tid %d is not agg\'able\n", | 663 | brcms_err(wl->wlc->hw->d11core, |
657 | tid); | 664 | "START: tid %d is not agg\'able\n", tid); |
658 | return -EINVAL; | 665 | return -EINVAL; |
659 | } | 666 | } |
660 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); | 667 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
@@ -681,8 +688,8 @@ brcms_ops_ampdu_action(struct ieee80211_hw *hw, | |||
681 | /* Power save wakeup */ | 688 | /* Power save wakeup */ |
682 | break; | 689 | break; |
683 | default: | 690 | default: |
684 | wiphy_err(wl->wiphy, "%s: Invalid command, ignoring\n", | 691 | brcms_err(wl->wlc->hw->d11core, |
685 | __func__); | 692 | "%s: Invalid command, ignoring\n", __func__); |
686 | } | 693 | } |
687 | 694 | ||
688 | return 0; | 695 | return 0; |
@@ -1144,14 +1151,13 @@ static int brcms_suspend(struct bcma_device *pdev) | |||
1144 | wl->pub->hw_up = false; | 1151 | wl->pub->hw_up = false; |
1145 | spin_unlock_bh(&wl->lock); | 1152 | spin_unlock_bh(&wl->lock); |
1146 | 1153 | ||
1147 | pr_debug("brcms_suspend ok\n"); | 1154 | brcms_dbg_info(wl->wlc->hw->d11core, "brcms_suspend ok\n"); |
1148 | 1155 | ||
1149 | return 0; | 1156 | return 0; |
1150 | } | 1157 | } |
1151 | 1158 | ||
1152 | static int brcms_resume(struct bcma_device *pdev) | 1159 | static int brcms_resume(struct bcma_device *pdev) |
1153 | { | 1160 | { |
1154 | pr_debug("brcms_resume ok\n"); | ||
1155 | return 0; | 1161 | return 0; |
1156 | } | 1162 | } |
1157 | 1163 | ||
@@ -1184,10 +1190,6 @@ static DECLARE_WORK(brcms_driver_work, brcms_driver_init); | |||
1184 | 1190 | ||
1185 | static int __init brcms_module_init(void) | 1191 | static int __init brcms_module_init(void) |
1186 | { | 1192 | { |
1187 | #ifdef DEBUG | ||
1188 | if (msglevel != 0xdeadbeef) | ||
1189 | brcm_msg_level = msglevel; | ||
1190 | #endif | ||
1191 | if (!schedule_work(&brcms_driver_work)) | 1193 | if (!schedule_work(&brcms_driver_work)) |
1192 | return -EBUSY; | 1194 | return -EBUSY; |
1193 | 1195 | ||
@@ -1216,7 +1218,7 @@ module_exit(brcms_module_exit); | |||
1216 | void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif, | 1218 | void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif, |
1217 | bool state, int prio) | 1219 | bool state, int prio) |
1218 | { | 1220 | { |
1219 | wiphy_err(wl->wiphy, "Shouldn't be here %s\n", __func__); | 1221 | brcms_err(wl->wlc->hw->d11core, "Shouldn't be here %s\n", __func__); |
1220 | } | 1222 | } |
1221 | 1223 | ||
1222 | /* | 1224 | /* |
@@ -1224,7 +1226,8 @@ void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif, | |||
1224 | */ | 1226 | */ |
1225 | void brcms_init(struct brcms_info *wl) | 1227 | void brcms_init(struct brcms_info *wl) |
1226 | { | 1228 | { |
1227 | BCMMSG(wl->pub->ieee_hw->wiphy, "wl%d\n", wl->pub->unit); | 1229 | brcms_dbg_info(wl->wlc->hw->d11core, "Initializing wl%d\n", |
1230 | wl->pub->unit); | ||
1228 | brcms_reset(wl); | 1231 | brcms_reset(wl); |
1229 | brcms_c_init(wl->wlc, wl->mute_tx); | 1232 | brcms_c_init(wl->wlc, wl->mute_tx); |
1230 | } | 1233 | } |
@@ -1234,7 +1237,7 @@ void brcms_init(struct brcms_info *wl) | |||
1234 | */ | 1237 | */ |
1235 | uint brcms_reset(struct brcms_info *wl) | 1238 | uint brcms_reset(struct brcms_info *wl) |
1236 | { | 1239 | { |
1237 | BCMMSG(wl->pub->ieee_hw->wiphy, "wl%d\n", wl->pub->unit); | 1240 | brcms_dbg_info(wl->wlc->hw->d11core, "Resetting wl%d\n", wl->pub->unit); |
1238 | brcms_c_reset(wl->wlc); | 1241 | brcms_c_reset(wl->wlc); |
1239 | 1242 | ||
1240 | /* dpc will not be rescheduled */ | 1243 | /* dpc will not be rescheduled */ |
@@ -1248,7 +1251,7 @@ uint brcms_reset(struct brcms_info *wl) | |||
1248 | 1251 | ||
1249 | void brcms_fatal_error(struct brcms_info *wl) | 1252 | void brcms_fatal_error(struct brcms_info *wl) |
1250 | { | 1253 | { |
1251 | wiphy_err(wl->wlc->wiphy, "wl%d: fatal error, reinitializing\n", | 1254 | brcms_err(wl->wlc->hw->d11core, "wl%d: fatal error, reinitializing\n", |
1252 | wl->wlc->pub->unit); | 1255 | wl->wlc->pub->unit); |
1253 | brcms_reset(wl); | 1256 | brcms_reset(wl); |
1254 | ieee80211_restart_hw(wl->pub->ieee_hw); | 1257 | ieee80211_restart_hw(wl->pub->ieee_hw); |
@@ -1396,8 +1399,9 @@ void brcms_add_timer(struct brcms_timer *t, uint ms, int periodic) | |||
1396 | 1399 | ||
1397 | #ifdef DEBUG | 1400 | #ifdef DEBUG |
1398 | if (t->set) | 1401 | if (t->set) |
1399 | wiphy_err(hw->wiphy, "%s: Already set. Name: %s, per %d\n", | 1402 | brcms_dbg_info(t->wl->wlc->hw->d11core, |
1400 | __func__, t->name, periodic); | 1403 | "%s: Already set. Name: %s, per %d\n", |
1404 | __func__, t->name, periodic); | ||
1401 | #endif | 1405 | #endif |
1402 | t->ms = ms; | 1406 | t->ms = ms; |
1403 | t->periodic = (bool) periodic; | 1407 | t->periodic = (bool) periodic; |
@@ -1486,8 +1490,8 @@ int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, u32 idx) | |||
1486 | } | 1490 | } |
1487 | } | 1491 | } |
1488 | } | 1492 | } |
1489 | wiphy_err(wl->wiphy, "ERROR: ucode buf tag:%d can not be found!\n", | 1493 | brcms_err(wl->wlc->hw->d11core, |
1490 | idx); | 1494 | "ERROR: ucode buf tag:%d can not be found!\n", idx); |
1491 | *pbuf = NULL; | 1495 | *pbuf = NULL; |
1492 | fail: | 1496 | fail: |
1493 | return -ENODATA; | 1497 | return -ENODATA; |
@@ -1510,7 +1514,7 @@ int brcms_ucode_init_uint(struct brcms_info *wl, size_t *n_bytes, u32 idx) | |||
1510 | pdata = wl->fw.fw_bin[i]->data + | 1514 | pdata = wl->fw.fw_bin[i]->data + |
1511 | le32_to_cpu(hdr->offset); | 1515 | le32_to_cpu(hdr->offset); |
1512 | if (le32_to_cpu(hdr->len) != 4) { | 1516 | if (le32_to_cpu(hdr->len) != 4) { |
1513 | wiphy_err(wl->wiphy, | 1517 | brcms_err(wl->wlc->hw->d11core, |
1514 | "ERROR: fw hdr len\n"); | 1518 | "ERROR: fw hdr len\n"); |
1515 | return -ENOMSG; | 1519 | return -ENOMSG; |
1516 | } | 1520 | } |
@@ -1519,7 +1523,8 @@ int brcms_ucode_init_uint(struct brcms_info *wl, size_t *n_bytes, u32 idx) | |||
1519 | } | 1523 | } |
1520 | } | 1524 | } |
1521 | } | 1525 | } |
1522 | wiphy_err(wl->wiphy, "ERROR: ucode tag:%d can not be found!\n", idx); | 1526 | brcms_err(wl->wlc->hw->d11core, |
1527 | "ERROR: ucode tag:%d can not be found!\n", idx); | ||
1523 | return -ENOMSG; | 1528 | return -ENOMSG; |
1524 | } | 1529 | } |
1525 | 1530 | ||
@@ -1560,8 +1565,8 @@ int brcms_check_firmwares(struct brcms_info *wl) | |||
1560 | sizeof(struct firmware_hdr)); | 1565 | sizeof(struct firmware_hdr)); |
1561 | rc = -EBADF; | 1566 | rc = -EBADF; |
1562 | } else if (fw->size < MIN_FW_SIZE || fw->size > MAX_FW_SIZE) { | 1567 | } else if (fw->size < MIN_FW_SIZE || fw->size > MAX_FW_SIZE) { |
1563 | wiphy_err(wl->wiphy, "%s: out of bounds fw file size " | 1568 | wiphy_err(wl->wiphy, "%s: out of bounds fw file size %zu\n", |
1564 | "%zu\n", __func__, fw->size); | 1569 | __func__, fw->size); |
1565 | rc = -EBADF; | 1570 | rc = -EBADF; |
1566 | } else { | 1571 | } else { |
1567 | /* check if ucode section overruns firmware image */ | 1572 | /* check if ucode section overruns firmware image */ |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 565c15abbed5..2a44593f1e37 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c | |||
@@ -34,12 +34,9 @@ | |||
34 | #include "ucode_loader.h" | 34 | #include "ucode_loader.h" |
35 | #include "main.h" | 35 | #include "main.h" |
36 | #include "soc.h" | 36 | #include "soc.h" |
37 | 37 | #include "dma.h" | |
38 | /* | 38 | #include "debug.h" |
39 | * Indication for txflowcontrol that all priority bits in | 39 | #include "brcms_trace_events.h" |
40 | * TXQ_STOP_FOR_PRIOFC_MASK are to be considered. | ||
41 | */ | ||
42 | #define ALLPRIO -1 | ||
43 | 40 | ||
44 | /* watchdog timer, in unit of ms */ | 41 | /* watchdog timer, in unit of ms */ |
45 | #define TIMER_INTERVAL_WATCHDOG 1000 | 42 | #define TIMER_INTERVAL_WATCHDOG 1000 |
@@ -126,21 +123,6 @@ | |||
126 | 123 | ||
127 | #define BRCMS_TEMPSENSE_PERIOD 10 /* 10 second timeout */ | 124 | #define BRCMS_TEMPSENSE_PERIOD 10 /* 10 second timeout */ |
128 | 125 | ||
129 | /* precedences numbers for wlc queues. These are twice as may levels as | ||
130 | * 802.1D priorities. | ||
131 | * Odd numbers are used for HI priority traffic at same precedence levels | ||
132 | * These constants are used ONLY by wlc_prio2prec_map. Do not use them | ||
133 | * elsewhere. | ||
134 | */ | ||
135 | #define _BRCMS_PREC_NONE 0 /* None = - */ | ||
136 | #define _BRCMS_PREC_BK 2 /* BK - Background */ | ||
137 | #define _BRCMS_PREC_BE 4 /* BE - Best-effort */ | ||
138 | #define _BRCMS_PREC_EE 6 /* EE - Excellent-effort */ | ||
139 | #define _BRCMS_PREC_CL 8 /* CL - Controlled Load */ | ||
140 | #define _BRCMS_PREC_VI 10 /* Vi - Video */ | ||
141 | #define _BRCMS_PREC_VO 12 /* Vo - Voice */ | ||
142 | #define _BRCMS_PREC_NC 14 /* NC - Network Control */ | ||
143 | |||
144 | /* synthpu_dly times in us */ | 126 | /* synthpu_dly times in us */ |
145 | #define SYNTHPU_DLY_APHY_US 3700 | 127 | #define SYNTHPU_DLY_APHY_US 3700 |
146 | #define SYNTHPU_DLY_BPHY_US 1050 | 128 | #define SYNTHPU_DLY_BPHY_US 1050 |
@@ -237,17 +219,17 @@ | |||
237 | 219 | ||
238 | #define MAX_DMA_SEGS 4 | 220 | #define MAX_DMA_SEGS 4 |
239 | 221 | ||
240 | /* Max # of entries in Tx FIFO based on 4kb page size */ | 222 | /* # of entries in Tx FIFO */ |
241 | #define NTXD 256 | 223 | #define NTXD 64 |
242 | /* Max # of entries in Rx FIFO based on 4kb page size */ | 224 | /* Max # of entries in Rx FIFO based on 4kb page size */ |
243 | #define NRXD 256 | 225 | #define NRXD 256 |
244 | 226 | ||
227 | /* Amount of headroom to leave in Tx FIFO */ | ||
228 | #define TX_HEADROOM 4 | ||
229 | |||
245 | /* try to keep this # rbufs posted to the chip */ | 230 | /* try to keep this # rbufs posted to the chip */ |
246 | #define NRXBUFPOST 32 | 231 | #define NRXBUFPOST 32 |
247 | 232 | ||
248 | /* data msg txq hiwat mark */ | ||
249 | #define BRCMS_DATAHIWAT 50 | ||
250 | |||
251 | /* max # frames to process in brcms_c_recv() */ | 233 | /* max # frames to process in brcms_c_recv() */ |
252 | #define RXBND 8 | 234 | #define RXBND 8 |
253 | /* max # tx status to process in wlc_txstatus() */ | 235 | /* max # tx status to process in wlc_txstatus() */ |
@@ -283,24 +265,8 @@ struct edcf_acparam { | |||
283 | u16 TXOP; | 265 | u16 TXOP; |
284 | } __packed; | 266 | } __packed; |
285 | 267 | ||
286 | const u8 prio2fifo[NUMPRIO] = { | ||
287 | TX_AC_BE_FIFO, /* 0 BE AC_BE Best Effort */ | ||
288 | TX_AC_BK_FIFO, /* 1 BK AC_BK Background */ | ||
289 | TX_AC_BK_FIFO, /* 2 -- AC_BK Background */ | ||
290 | TX_AC_BE_FIFO, /* 3 EE AC_BE Best Effort */ | ||
291 | TX_AC_VI_FIFO, /* 4 CL AC_VI Video */ | ||
292 | TX_AC_VI_FIFO, /* 5 VI AC_VI Video */ | ||
293 | TX_AC_VO_FIFO, /* 6 VO AC_VO Voice */ | ||
294 | TX_AC_VO_FIFO /* 7 NC AC_VO Voice */ | ||
295 | }; | ||
296 | |||
297 | /* debug/trace */ | 268 | /* debug/trace */ |
298 | uint brcm_msg_level = | 269 | uint brcm_msg_level; |
299 | #if defined(DEBUG) | ||
300 | LOG_ERROR_VAL; | ||
301 | #else | ||
302 | 0; | ||
303 | #endif /* DEBUG */ | ||
304 | 270 | ||
305 | /* TX FIFO number to WME/802.1E Access Category */ | 271 | /* TX FIFO number to WME/802.1E Access Category */ |
306 | static const u8 wme_fifo2ac[] = { | 272 | static const u8 wme_fifo2ac[] = { |
@@ -320,18 +286,6 @@ static const u8 wme_ac2fifo[] = { | |||
320 | TX_AC_BK_FIFO | 286 | TX_AC_BK_FIFO |
321 | }; | 287 | }; |
322 | 288 | ||
323 | /* 802.1D Priority to precedence queue mapping */ | ||
324 | const u8 wlc_prio2prec_map[] = { | ||
325 | _BRCMS_PREC_BE, /* 0 BE - Best-effort */ | ||
326 | _BRCMS_PREC_BK, /* 1 BK - Background */ | ||
327 | _BRCMS_PREC_NONE, /* 2 None = - */ | ||
328 | _BRCMS_PREC_EE, /* 3 EE - Excellent-effort */ | ||
329 | _BRCMS_PREC_CL, /* 4 CL - Controlled Load */ | ||
330 | _BRCMS_PREC_VI, /* 5 Vi - Video */ | ||
331 | _BRCMS_PREC_VO, /* 6 Vo - Voice */ | ||
332 | _BRCMS_PREC_NC, /* 7 NC - Network Control */ | ||
333 | }; | ||
334 | |||
335 | static const u16 xmtfifo_sz[][NFIFO] = { | 289 | static const u16 xmtfifo_sz[][NFIFO] = { |
336 | /* corerev 17: 5120, 49152, 49152, 5376, 4352, 1280 */ | 290 | /* corerev 17: 5120, 49152, 49152, 5376, 4352, 1280 */ |
337 | {20, 192, 192, 21, 17, 5}, | 291 | {20, 192, 192, 21, 17, 5}, |
@@ -371,6 +325,36 @@ static const char fifo_names[6][0]; | |||
371 | static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL); | 325 | static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL); |
372 | #endif | 326 | #endif |
373 | 327 | ||
328 | /* Mapping of ieee80211 AC numbers to tx fifos */ | ||
329 | static const u8 ac_to_fifo_mapping[IEEE80211_NUM_ACS] = { | ||
330 | [IEEE80211_AC_VO] = TX_AC_VO_FIFO, | ||
331 | [IEEE80211_AC_VI] = TX_AC_VI_FIFO, | ||
332 | [IEEE80211_AC_BE] = TX_AC_BE_FIFO, | ||
333 | [IEEE80211_AC_BK] = TX_AC_BK_FIFO, | ||
334 | }; | ||
335 | |||
336 | /* Mapping of tx fifos to ieee80211 AC numbers */ | ||
337 | static const u8 fifo_to_ac_mapping[IEEE80211_NUM_ACS] = { | ||
338 | [TX_AC_BK_FIFO] = IEEE80211_AC_BK, | ||
339 | [TX_AC_BE_FIFO] = IEEE80211_AC_BE, | ||
340 | [TX_AC_VI_FIFO] = IEEE80211_AC_VI, | ||
341 | [TX_AC_VO_FIFO] = IEEE80211_AC_VO, | ||
342 | }; | ||
343 | |||
344 | static u8 brcms_ac_to_fifo(u8 ac) | ||
345 | { | ||
346 | if (ac >= ARRAY_SIZE(ac_to_fifo_mapping)) | ||
347 | return TX_AC_BE_FIFO; | ||
348 | return ac_to_fifo_mapping[ac]; | ||
349 | } | ||
350 | |||
351 | static u8 brcms_fifo_to_ac(u8 fifo) | ||
352 | { | ||
353 | if (fifo >= ARRAY_SIZE(fifo_to_ac_mapping)) | ||
354 | return IEEE80211_AC_BE; | ||
355 | return fifo_to_ac_mapping[fifo]; | ||
356 | } | ||
357 | |||
374 | /* Find basic rate for a given rate */ | 358 | /* Find basic rate for a given rate */ |
375 | static u8 brcms_basic_rate(struct brcms_c_info *wlc, u32 rspec) | 359 | static u8 brcms_basic_rate(struct brcms_c_info *wlc, u32 rspec) |
376 | { | 360 | { |
@@ -415,10 +399,15 @@ static bool brcms_deviceremoved(struct brcms_c_info *wlc) | |||
415 | } | 399 | } |
416 | 400 | ||
417 | /* sum the individual fifo tx pending packet counts */ | 401 | /* sum the individual fifo tx pending packet counts */ |
418 | static s16 brcms_txpktpendtot(struct brcms_c_info *wlc) | 402 | static int brcms_txpktpendtot(struct brcms_c_info *wlc) |
419 | { | 403 | { |
420 | return wlc->core->txpktpend[0] + wlc->core->txpktpend[1] + | 404 | int i; |
421 | wlc->core->txpktpend[2] + wlc->core->txpktpend[3]; | 405 | int pending = 0; |
406 | |||
407 | for (i = 0; i < ARRAY_SIZE(wlc->hw->di); i++) | ||
408 | if (wlc->hw->di[i]) | ||
409 | pending += dma_txpending(wlc->hw->di[i]); | ||
410 | return pending; | ||
422 | } | 411 | } |
423 | 412 | ||
424 | static bool brcms_is_mband_unlocked(struct brcms_c_info *wlc) | 413 | static bool brcms_is_mband_unlocked(struct brcms_c_info *wlc) |
@@ -626,14 +615,11 @@ static uint brcms_c_calc_frame_time(struct brcms_c_info *wlc, u32 ratespec, | |||
626 | uint rate = rspec2rate(ratespec); | 615 | uint rate = rspec2rate(ratespec); |
627 | 616 | ||
628 | if (rate == 0) { | 617 | if (rate == 0) { |
629 | wiphy_err(wlc->wiphy, "wl%d: WAR: using rate of 1 mbps\n", | 618 | brcms_err(wlc->hw->d11core, "wl%d: WAR: using rate of 1 mbps\n", |
630 | wlc->pub->unit); | 619 | wlc->pub->unit); |
631 | rate = BRCM_RATE_1M; | 620 | rate = BRCM_RATE_1M; |
632 | } | 621 | } |
633 | 622 | ||
634 | BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, len%d\n", | ||
635 | wlc->pub->unit, ratespec, preamble_type, mac_len); | ||
636 | |||
637 | if (is_mcs_rate(ratespec)) { | 623 | if (is_mcs_rate(ratespec)) { |
638 | uint mcs = ratespec & RSPEC_RATE_MASK; | 624 | uint mcs = ratespec & RSPEC_RATE_MASK; |
639 | int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec); | 625 | int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec); |
@@ -696,7 +682,7 @@ static void brcms_c_write_inits(struct brcms_hardware *wlc_hw, | |||
696 | u16 size; | 682 | u16 size; |
697 | u32 value; | 683 | u32 value; |
698 | 684 | ||
699 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | 685 | brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit); |
700 | 686 | ||
701 | for (i = 0; inits[i].addr != cpu_to_le16(0xffff); i++) { | 687 | for (i = 0; inits[i].addr != cpu_to_le16(0xffff); i++) { |
702 | size = le16_to_cpu(inits[i].size); | 688 | size = le16_to_cpu(inits[i].size); |
@@ -725,7 +711,6 @@ static void brcms_c_write_mhf(struct brcms_hardware *wlc_hw, u16 *mhfs) | |||
725 | 711 | ||
726 | static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw) | 712 | static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw) |
727 | { | 713 | { |
728 | struct wiphy *wiphy = wlc_hw->wlc->wiphy; | ||
729 | struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode; | 714 | struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode; |
730 | 715 | ||
731 | /* init microcode host flags */ | 716 | /* init microcode host flags */ |
@@ -736,8 +721,9 @@ static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw) | |||
736 | if (BRCMS_ISNPHY(wlc_hw->band)) | 721 | if (BRCMS_ISNPHY(wlc_hw->band)) |
737 | brcms_c_write_inits(wlc_hw, ucode->d11n0bsinitvals16); | 722 | brcms_c_write_inits(wlc_hw, ucode->d11n0bsinitvals16); |
738 | else | 723 | else |
739 | wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev" | 724 | brcms_err(wlc_hw->d11core, |
740 | " %d\n", __func__, wlc_hw->unit, | 725 | "%s: wl%d: unsupported phy in corerev %d\n", |
726 | __func__, wlc_hw->unit, | ||
741 | wlc_hw->corerev); | 727 | wlc_hw->corerev); |
742 | } else { | 728 | } else { |
743 | if (D11REV_IS(wlc_hw->corerev, 24)) { | 729 | if (D11REV_IS(wlc_hw->corerev, 24)) { |
@@ -745,12 +731,14 @@ static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw) | |||
745 | brcms_c_write_inits(wlc_hw, | 731 | brcms_c_write_inits(wlc_hw, |
746 | ucode->d11lcn0bsinitvals24); | 732 | ucode->d11lcn0bsinitvals24); |
747 | else | 733 | else |
748 | wiphy_err(wiphy, "%s: wl%d: unsupported phy in" | 734 | brcms_err(wlc_hw->d11core, |
749 | " core rev %d\n", __func__, | 735 | "%s: wl%d: unsupported phy in core rev %d\n", |
750 | wlc_hw->unit, wlc_hw->corerev); | 736 | __func__, wlc_hw->unit, |
737 | wlc_hw->corerev); | ||
751 | } else { | 738 | } else { |
752 | wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n", | 739 | brcms_err(wlc_hw->d11core, |
753 | __func__, wlc_hw->unit, wlc_hw->corerev); | 740 | "%s: wl%d: unsupported corerev %d\n", |
741 | __func__, wlc_hw->unit, wlc_hw->corerev); | ||
754 | } | 742 | } |
755 | } | 743 | } |
756 | } | 744 | } |
@@ -765,7 +753,7 @@ static void brcms_b_core_ioctl(struct brcms_hardware *wlc_hw, u32 m, u32 v) | |||
765 | 753 | ||
766 | static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk) | 754 | static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk) |
767 | { | 755 | { |
768 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d: clk %d\n", wlc_hw->unit, clk); | 756 | brcms_dbg_info(wlc_hw->d11core, "wl%d: clk %d\n", wlc_hw->unit, clk); |
769 | 757 | ||
770 | wlc_hw->phyclk = clk; | 758 | wlc_hw->phyclk = clk; |
771 | 759 | ||
@@ -790,8 +778,8 @@ static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk) | |||
790 | /* low-level band switch utility routine */ | 778 | /* low-level band switch utility routine */ |
791 | static void brcms_c_setxband(struct brcms_hardware *wlc_hw, uint bandunit) | 779 | static void brcms_c_setxband(struct brcms_hardware *wlc_hw, uint bandunit) |
792 | { | 780 | { |
793 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, | 781 | brcms_dbg_mac80211(wlc_hw->d11core, "wl%d: bandunit %d\n", wlc_hw->unit, |
794 | bandunit); | 782 | bandunit); |
795 | 783 | ||
796 | wlc_hw->band = wlc_hw->bandstate[bandunit]; | 784 | wlc_hw->band = wlc_hw->bandstate[bandunit]; |
797 | 785 | ||
@@ -819,7 +807,7 @@ static u32 brcms_c_setband_inact(struct brcms_c_info *wlc, uint bandunit) | |||
819 | u32 macintmask; | 807 | u32 macintmask; |
820 | u32 macctrl; | 808 | u32 macctrl; |
821 | 809 | ||
822 | BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); | 810 | brcms_dbg_mac80211(wlc_hw->d11core, "wl%d\n", wlc_hw->unit); |
823 | macctrl = bcma_read32(wlc_hw->d11core, | 811 | macctrl = bcma_read32(wlc_hw->d11core, |
824 | D11REGOFFS(maccontrol)); | 812 | D11REGOFFS(maccontrol)); |
825 | WARN_ON((macctrl & MCTL_EN_MAC) != 0); | 813 | WARN_ON((macctrl & MCTL_EN_MAC) != 0); |
@@ -841,9 +829,10 @@ static u32 brcms_c_setband_inact(struct brcms_c_info *wlc, uint bandunit) | |||
841 | static bool | 829 | static bool |
842 | brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) | 830 | brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) |
843 | { | 831 | { |
844 | struct sk_buff *p; | 832 | struct sk_buff *p = NULL; |
845 | uint queue; | 833 | uint queue = NFIFO; |
846 | struct d11txh *txh; | 834 | struct dma_pub *dma = NULL; |
835 | struct d11txh *txh = NULL; | ||
847 | struct scb *scb = NULL; | 836 | struct scb *scb = NULL; |
848 | bool free_pdu; | 837 | bool free_pdu; |
849 | int tx_rts, tx_frame_count, tx_rts_count; | 838 | int tx_rts, tx_frame_count, tx_rts_count; |
@@ -854,6 +843,11 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) | |||
854 | struct ieee80211_tx_info *tx_info; | 843 | struct ieee80211_tx_info *tx_info; |
855 | struct ieee80211_tx_rate *txrate; | 844 | struct ieee80211_tx_rate *txrate; |
856 | int i; | 845 | int i; |
846 | bool fatal = true; | ||
847 | |||
848 | trace_brcms_txstatus(&wlc->hw->d11core->dev, txs->framelen, | ||
849 | txs->frameid, txs->status, txs->lasttxtime, | ||
850 | txs->sequence, txs->phyerr, txs->ackphyrxsh); | ||
857 | 851 | ||
858 | /* discard intermediate indications for ucode with one legitimate case: | 852 | /* discard intermediate indications for ucode with one legitimate case: |
859 | * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, | 853 | * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, |
@@ -862,34 +856,36 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) | |||
862 | */ | 856 | */ |
863 | if (!(txs->status & TX_STATUS_AMPDU) | 857 | if (!(txs->status & TX_STATUS_AMPDU) |
864 | && (txs->status & TX_STATUS_INTERMEDIATE)) { | 858 | && (txs->status & TX_STATUS_INTERMEDIATE)) { |
865 | BCMMSG(wlc->wiphy, "INTERMEDIATE but not AMPDU\n"); | 859 | brcms_dbg_tx(wlc->hw->d11core, "INTERMEDIATE but not AMPDU\n"); |
866 | return false; | 860 | fatal = false; |
861 | goto out; | ||
867 | } | 862 | } |
868 | 863 | ||
869 | queue = txs->frameid & TXFID_QUEUE_MASK; | 864 | queue = txs->frameid & TXFID_QUEUE_MASK; |
870 | if (queue >= NFIFO) { | 865 | if (queue >= NFIFO) { |
871 | p = NULL; | 866 | brcms_err(wlc->hw->d11core, "queue %u >= NFIFO\n", queue); |
872 | goto fatal; | 867 | goto out; |
873 | } | 868 | } |
874 | 869 | ||
870 | dma = wlc->hw->di[queue]; | ||
871 | |||
875 | p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED); | 872 | p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED); |
876 | if (p == NULL) | 873 | if (p == NULL) { |
877 | goto fatal; | 874 | brcms_err(wlc->hw->d11core, "dma_getnexttxp returned null!\n"); |
875 | goto out; | ||
876 | } | ||
878 | 877 | ||
879 | txh = (struct d11txh *) (p->data); | 878 | txh = (struct d11txh *) (p->data); |
880 | mcl = le16_to_cpu(txh->MacTxControlLow); | 879 | mcl = le16_to_cpu(txh->MacTxControlLow); |
881 | 880 | ||
882 | if (txs->phyerr) { | 881 | if (txs->phyerr) |
883 | if (brcm_msg_level & LOG_ERROR_VAL) { | 882 | brcms_err(wlc->hw->d11core, "phyerr 0x%x, rate 0x%x\n", |
884 | wiphy_err(wlc->wiphy, "phyerr 0x%x, rate 0x%x\n", | 883 | txs->phyerr, txh->MainRates); |
885 | txs->phyerr, txh->MainRates); | ||
886 | brcms_c_print_txdesc(txh); | ||
887 | } | ||
888 | brcms_c_print_txstatus(txs); | ||
889 | } | ||
890 | 884 | ||
891 | if (txs->frameid != le16_to_cpu(txh->TxFrameID)) | 885 | if (txs->frameid != le16_to_cpu(txh->TxFrameID)) { |
892 | goto fatal; | 886 | brcms_err(wlc->hw->d11core, "frameid != txh->TxFrameID\n"); |
887 | goto out; | ||
888 | } | ||
893 | tx_info = IEEE80211_SKB_CB(p); | 889 | tx_info = IEEE80211_SKB_CB(p); |
894 | h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); | 890 | h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); |
895 | 891 | ||
@@ -898,14 +894,24 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) | |||
898 | 894 | ||
899 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { | 895 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { |
900 | brcms_c_ampdu_dotxstatus(wlc->ampdu, scb, p, txs); | 896 | brcms_c_ampdu_dotxstatus(wlc->ampdu, scb, p, txs); |
901 | return false; | 897 | fatal = false; |
898 | goto out; | ||
902 | } | 899 | } |
903 | 900 | ||
901 | /* | ||
902 | * brcms_c_ampdu_dotxstatus() will trace tx descriptors for AMPDU | ||
903 | * frames; this traces them for the rest. | ||
904 | */ | ||
905 | trace_brcms_txdesc(&wlc->hw->d11core->dev, txh, sizeof(*txh)); | ||
906 | |||
904 | supr_status = txs->status & TX_STATUS_SUPR_MASK; | 907 | supr_status = txs->status & TX_STATUS_SUPR_MASK; |
905 | if (supr_status == TX_STATUS_SUPR_BADCH) | 908 | if (supr_status == TX_STATUS_SUPR_BADCH) { |
906 | BCMMSG(wlc->wiphy, | 909 | unsigned xfts = le16_to_cpu(txh->XtraFrameTypes); |
907 | "%s: Pkt tx suppressed, possibly channel %d\n", | 910 | brcms_dbg_tx(wlc->hw->d11core, |
908 | __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec)); | 911 | "Pkt tx suppressed, dest chan %u, current %d\n", |
912 | (xfts >> XFTS_CHANNEL_SHIFT) & 0xff, | ||
913 | CHSPEC_CHANNEL(wlc->default_bss->chanspec)); | ||
914 | } | ||
909 | 915 | ||
910 | tx_rts = le16_to_cpu(txh->MacTxControlLow) & TXC_SENDRTS; | 916 | tx_rts = le16_to_cpu(txh->MacTxControlLow) & TXC_SENDRTS; |
911 | tx_frame_count = | 917 | tx_frame_count = |
@@ -916,7 +922,7 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) | |||
916 | lastframe = !ieee80211_has_morefrags(h->frame_control); | 922 | lastframe = !ieee80211_has_morefrags(h->frame_control); |
917 | 923 | ||
918 | if (!lastframe) { | 924 | if (!lastframe) { |
919 | wiphy_err(wlc->wiphy, "Not last frame!\n"); | 925 | brcms_err(wlc->hw->d11core, "Not last frame!\n"); |
920 | } else { | 926 | } else { |
921 | /* | 927 | /* |
922 | * Set information to be consumed by Minstrel ht. | 928 | * Set information to be consumed by Minstrel ht. |
@@ -982,26 +988,37 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) | |||
982 | totlen = p->len; | 988 | totlen = p->len; |
983 | free_pdu = true; | 989 | free_pdu = true; |
984 | 990 | ||
985 | brcms_c_txfifo_complete(wlc, queue, 1); | ||
986 | |||
987 | if (lastframe) { | 991 | if (lastframe) { |
988 | /* remove PLCP & Broadcom tx descriptor header */ | 992 | /* remove PLCP & Broadcom tx descriptor header */ |
989 | skb_pull(p, D11_PHY_HDR_LEN); | 993 | skb_pull(p, D11_PHY_HDR_LEN); |
990 | skb_pull(p, D11_TXH_LEN); | 994 | skb_pull(p, D11_TXH_LEN); |
991 | ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p); | 995 | ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p); |
992 | } else { | 996 | } else { |
993 | wiphy_err(wlc->wiphy, "%s: Not last frame => not calling " | 997 | brcms_err(wlc->hw->d11core, |
994 | "tx_status\n", __func__); | 998 | "%s: Not last frame => not calling tx_status\n", |
999 | __func__); | ||
995 | } | 1000 | } |
996 | 1001 | ||
997 | return false; | 1002 | fatal = false; |
998 | 1003 | ||
999 | fatal: | 1004 | out: |
1000 | if (p) | 1005 | if (fatal) { |
1001 | brcmu_pkt_buf_free_skb(p); | 1006 | if (txh) |
1007 | trace_brcms_txdesc(&wlc->hw->d11core->dev, txh, | ||
1008 | sizeof(*txh)); | ||
1009 | if (p) | ||
1010 | brcmu_pkt_buf_free_skb(p); | ||
1011 | } | ||
1002 | 1012 | ||
1003 | return true; | 1013 | if (dma && queue < NFIFO) { |
1014 | u16 ac_queue = brcms_fifo_to_ac(queue); | ||
1015 | if (dma->txavail > TX_HEADROOM && queue < TX_BCMC_FIFO && | ||
1016 | ieee80211_queue_stopped(wlc->pub->ieee_hw, ac_queue)) | ||
1017 | ieee80211_wake_queue(wlc->pub->ieee_hw, ac_queue); | ||
1018 | dma_kick_tx(dma); | ||
1019 | } | ||
1004 | 1020 | ||
1021 | return fatal; | ||
1005 | } | 1022 | } |
1006 | 1023 | ||
1007 | /* process tx completion events in BMAC | 1024 | /* process tx completion events in BMAC |
@@ -1011,7 +1028,6 @@ static bool | |||
1011 | brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) | 1028 | brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) |
1012 | { | 1029 | { |
1013 | bool morepending = false; | 1030 | bool morepending = false; |
1014 | struct brcms_c_info *wlc = wlc_hw->wlc; | ||
1015 | struct bcma_device *core; | 1031 | struct bcma_device *core; |
1016 | struct tx_status txstatus, *txs; | 1032 | struct tx_status txstatus, *txs; |
1017 | u32 s1, s2; | 1033 | u32 s1, s2; |
@@ -1022,8 +1038,6 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) | |||
1022 | */ | 1038 | */ |
1023 | uint max_tx_num = bound ? TXSBND : -1; | 1039 | uint max_tx_num = bound ? TXSBND : -1; |
1024 | 1040 | ||
1025 | BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); | ||
1026 | |||
1027 | txs = &txstatus; | 1041 | txs = &txstatus; |
1028 | core = wlc_hw->d11core; | 1042 | core = wlc_hw->d11core; |
1029 | *fatal = false; | 1043 | *fatal = false; |
@@ -1032,8 +1046,8 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) | |||
1032 | && (s1 & TXS_V)) { | 1046 | && (s1 & TXS_V)) { |
1033 | 1047 | ||
1034 | if (s1 == 0xffffffff) { | 1048 | if (s1 == 0xffffffff) { |
1035 | wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", | 1049 | brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, |
1036 | wlc_hw->unit, __func__); | 1050 | __func__); |
1037 | return morepending; | 1051 | return morepending; |
1038 | } | 1052 | } |
1039 | s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2)); | 1053 | s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2)); |
@@ -1058,9 +1072,6 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) | |||
1058 | if (n >= max_tx_num) | 1072 | if (n >= max_tx_num) |
1059 | morepending = true; | 1073 | morepending = true; |
1060 | 1074 | ||
1061 | if (!pktq_empty(&wlc->pkt_queue->q)) | ||
1062 | brcms_c_send_q(wlc); | ||
1063 | |||
1064 | return morepending; | 1075 | return morepending; |
1065 | } | 1076 | } |
1066 | 1077 | ||
@@ -1112,7 +1123,6 @@ static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme) | |||
1112 | u16 pio_mhf2 = 0; | 1123 | u16 pio_mhf2 = 0; |
1113 | struct brcms_hardware *wlc_hw = wlc->hw; | 1124 | struct brcms_hardware *wlc_hw = wlc->hw; |
1114 | uint unit = wlc_hw->unit; | 1125 | uint unit = wlc_hw->unit; |
1115 | struct wiphy *wiphy = wlc->wiphy; | ||
1116 | 1126 | ||
1117 | /* name and offsets for dma_attach */ | 1127 | /* name and offsets for dma_attach */ |
1118 | snprintf(name, sizeof(name), "wl%d", unit); | 1128 | snprintf(name, sizeof(name), "wl%d", unit); |
@@ -1125,12 +1135,12 @@ static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme) | |||
1125 | * TX: TX_AC_BK_FIFO (TX AC Background data packets) | 1135 | * TX: TX_AC_BK_FIFO (TX AC Background data packets) |
1126 | * RX: RX_FIFO (RX data packets) | 1136 | * RX: RX_FIFO (RX data packets) |
1127 | */ | 1137 | */ |
1128 | wlc_hw->di[0] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core, | 1138 | wlc_hw->di[0] = dma_attach(name, wlc, |
1129 | (wme ? dmareg(DMA_TX, 0) : 0), | 1139 | (wme ? dmareg(DMA_TX, 0) : 0), |
1130 | dmareg(DMA_RX, 0), | 1140 | dmareg(DMA_RX, 0), |
1131 | (wme ? NTXD : 0), NRXD, | 1141 | (wme ? NTXD : 0), NRXD, |
1132 | RXBUFSZ, -1, NRXBUFPOST, | 1142 | RXBUFSZ, -1, NRXBUFPOST, |
1133 | BRCMS_HWRXOFF, &brcm_msg_level); | 1143 | BRCMS_HWRXOFF); |
1134 | dma_attach_err |= (NULL == wlc_hw->di[0]); | 1144 | dma_attach_err |= (NULL == wlc_hw->di[0]); |
1135 | 1145 | ||
1136 | /* | 1146 | /* |
@@ -1139,10 +1149,9 @@ static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme) | |||
1139 | * (legacy) TX_DATA_FIFO (TX data packets) | 1149 | * (legacy) TX_DATA_FIFO (TX data packets) |
1140 | * RX: UNUSED | 1150 | * RX: UNUSED |
1141 | */ | 1151 | */ |
1142 | wlc_hw->di[1] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core, | 1152 | wlc_hw->di[1] = dma_attach(name, wlc, |
1143 | dmareg(DMA_TX, 1), 0, | 1153 | dmareg(DMA_TX, 1), 0, |
1144 | NTXD, 0, 0, -1, 0, 0, | 1154 | NTXD, 0, 0, -1, 0, 0); |
1145 | &brcm_msg_level); | ||
1146 | dma_attach_err |= (NULL == wlc_hw->di[1]); | 1155 | dma_attach_err |= (NULL == wlc_hw->di[1]); |
1147 | 1156 | ||
1148 | /* | 1157 | /* |
@@ -1150,26 +1159,26 @@ static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme) | |||
1150 | * TX: TX_AC_VI_FIFO (TX AC Video data packets) | 1159 | * TX: TX_AC_VI_FIFO (TX AC Video data packets) |
1151 | * RX: UNUSED | 1160 | * RX: UNUSED |
1152 | */ | 1161 | */ |
1153 | wlc_hw->di[2] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core, | 1162 | wlc_hw->di[2] = dma_attach(name, wlc, |
1154 | dmareg(DMA_TX, 2), 0, | 1163 | dmareg(DMA_TX, 2), 0, |
1155 | NTXD, 0, 0, -1, 0, 0, | 1164 | NTXD, 0, 0, -1, 0, 0); |
1156 | &brcm_msg_level); | ||
1157 | dma_attach_err |= (NULL == wlc_hw->di[2]); | 1165 | dma_attach_err |= (NULL == wlc_hw->di[2]); |
1158 | /* | 1166 | /* |
1159 | * FIFO 3 | 1167 | * FIFO 3 |
1160 | * TX: TX_AC_VO_FIFO (TX AC Voice data packets) | 1168 | * TX: TX_AC_VO_FIFO (TX AC Voice data packets) |
1161 | * (legacy) TX_CTL_FIFO (TX control & mgmt packets) | 1169 | * (legacy) TX_CTL_FIFO (TX control & mgmt packets) |
1162 | */ | 1170 | */ |
1163 | wlc_hw->di[3] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core, | 1171 | wlc_hw->di[3] = dma_attach(name, wlc, |
1164 | dmareg(DMA_TX, 3), | 1172 | dmareg(DMA_TX, 3), |
1165 | 0, NTXD, 0, 0, -1, | 1173 | 0, NTXD, 0, 0, -1, |
1166 | 0, 0, &brcm_msg_level); | 1174 | 0, 0); |
1167 | dma_attach_err |= (NULL == wlc_hw->di[3]); | 1175 | dma_attach_err |= (NULL == wlc_hw->di[3]); |
1168 | /* Cleaner to leave this as if with AP defined */ | 1176 | /* Cleaner to leave this as if with AP defined */ |
1169 | 1177 | ||
1170 | if (dma_attach_err) { | 1178 | if (dma_attach_err) { |
1171 | wiphy_err(wiphy, "wl%d: wlc_attach: dma_attach failed" | 1179 | brcms_err(wlc_hw->d11core, |
1172 | "\n", unit); | 1180 | "wl%d: wlc_attach: dma_attach failed\n", |
1181 | unit); | ||
1173 | return false; | 1182 | return false; |
1174 | } | 1183 | } |
1175 | 1184 | ||
@@ -1503,8 +1512,7 @@ brcms_b_set_addrmatch(struct brcms_hardware *wlc_hw, int match_reg_offset, | |||
1503 | u16 mac_m; | 1512 | u16 mac_m; |
1504 | u16 mac_h; | 1513 | u16 mac_h; |
1505 | 1514 | ||
1506 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d: brcms_b_set_addrmatch\n", | 1515 | brcms_dbg_rx(core, "wl%d: brcms_b_set_addrmatch\n", wlc_hw->unit); |
1507 | wlc_hw->unit); | ||
1508 | 1516 | ||
1509 | mac_l = addr[0] | (addr[1] << 8); | 1517 | mac_l = addr[0] | (addr[1] << 8); |
1510 | mac_m = addr[2] | (addr[3] << 8); | 1518 | mac_m = addr[2] | (addr[3] << 8); |
@@ -1527,7 +1535,7 @@ brcms_b_write_template_ram(struct brcms_hardware *wlc_hw, int offset, int len, | |||
1527 | __le32 word_le; | 1535 | __le32 word_le; |
1528 | __be32 word_be; | 1536 | __be32 word_be; |
1529 | bool be_bit; | 1537 | bool be_bit; |
1530 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | 1538 | brcms_dbg_info(core, "wl%d\n", wlc_hw->unit); |
1531 | 1539 | ||
1532 | bcma_write32(core, D11REGOFFS(tplatewrptr), offset); | 1540 | bcma_write32(core, D11REGOFFS(tplatewrptr), offset); |
1533 | 1541 | ||
@@ -1700,8 +1708,8 @@ static void brcms_b_bsinit(struct brcms_c_info *wlc, u16 chanspec) | |||
1700 | { | 1708 | { |
1701 | struct brcms_hardware *wlc_hw = wlc->hw; | 1709 | struct brcms_hardware *wlc_hw = wlc->hw; |
1702 | 1710 | ||
1703 | BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, | 1711 | brcms_dbg_mac80211(wlc_hw->d11core, "wl%d: bandunit %d\n", wlc_hw->unit, |
1704 | wlc_hw->band->bandunit); | 1712 | wlc_hw->band->bandunit); |
1705 | 1713 | ||
1706 | brcms_c_ucode_bsinit(wlc_hw); | 1714 | brcms_c_ucode_bsinit(wlc_hw); |
1707 | 1715 | ||
@@ -1736,8 +1744,6 @@ static void brcms_b_bsinit(struct brcms_c_info *wlc, u16 chanspec) | |||
1736 | /* Perform a soft reset of the PHY PLL */ | 1744 | /* Perform a soft reset of the PHY PLL */ |
1737 | void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw) | 1745 | void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw) |
1738 | { | 1746 | { |
1739 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | ||
1740 | |||
1741 | ai_cc_reg(wlc_hw->sih, offsetof(struct chipcregs, chipcontrol_addr), | 1747 | ai_cc_reg(wlc_hw->sih, offsetof(struct chipcregs, chipcontrol_addr), |
1742 | ~0, 0); | 1748 | ~0, 0); |
1743 | udelay(1); | 1749 | udelay(1); |
@@ -1782,7 +1788,7 @@ void brcms_b_phy_reset(struct brcms_hardware *wlc_hw) | |||
1782 | u32 phy_bw_clkbits; | 1788 | u32 phy_bw_clkbits; |
1783 | bool phy_in_reset = false; | 1789 | bool phy_in_reset = false; |
1784 | 1790 | ||
1785 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | 1791 | brcms_dbg_info(wlc_hw->d11core, "wl%d: reset phy\n", wlc_hw->unit); |
1786 | 1792 | ||
1787 | if (pih == NULL) | 1793 | if (pih == NULL) |
1788 | return; | 1794 | return; |
@@ -1916,7 +1922,7 @@ static void brcms_c_get_macaddr(struct brcms_hardware *wlc_hw, u8 etheraddr[ETH_ | |||
1916 | /* power both the pll and external oscillator on/off */ | 1922 | /* power both the pll and external oscillator on/off */ |
1917 | static void brcms_b_xtal(struct brcms_hardware *wlc_hw, bool want) | 1923 | static void brcms_b_xtal(struct brcms_hardware *wlc_hw, bool want) |
1918 | { | 1924 | { |
1919 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d: want %d\n", wlc_hw->unit, want); | 1925 | brcms_dbg_info(wlc_hw->d11core, "wl%d: want %d\n", wlc_hw->unit, want); |
1920 | 1926 | ||
1921 | /* | 1927 | /* |
1922 | * dont power down if plldown is false or | 1928 | * dont power down if plldown is false or |
@@ -2005,7 +2011,7 @@ void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags) | |||
2005 | if (flags == BRCMS_USE_COREFLAGS) | 2011 | if (flags == BRCMS_USE_COREFLAGS) |
2006 | flags = (wlc_hw->band->pi ? wlc_hw->band->core_flags : 0); | 2012 | flags = (wlc_hw->band->pi ? wlc_hw->band->core_flags : 0); |
2007 | 2013 | ||
2008 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | 2014 | brcms_dbg_info(wlc_hw->d11core, "wl%d: core reset\n", wlc_hw->unit); |
2009 | 2015 | ||
2010 | /* request FAST clock if not on */ | 2016 | /* request FAST clock if not on */ |
2011 | fastclk = wlc_hw->forcefastclk; | 2017 | fastclk = wlc_hw->forcefastclk; |
@@ -2016,13 +2022,13 @@ void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags) | |||
2016 | if (bcma_core_is_enabled(wlc_hw->d11core)) { | 2022 | if (bcma_core_is_enabled(wlc_hw->d11core)) { |
2017 | for (i = 0; i < NFIFO; i++) | 2023 | for (i = 0; i < NFIFO; i++) |
2018 | if ((wlc_hw->di[i]) && (!dma_txreset(wlc_hw->di[i]))) | 2024 | if ((wlc_hw->di[i]) && (!dma_txreset(wlc_hw->di[i]))) |
2019 | wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: " | 2025 | brcms_err(wlc_hw->d11core, "wl%d: %s: " |
2020 | "dma_txreset[%d]: cannot stop dma\n", | 2026 | "dma_txreset[%d]: cannot stop dma\n", |
2021 | wlc_hw->unit, __func__, i); | 2027 | wlc_hw->unit, __func__, i); |
2022 | 2028 | ||
2023 | if ((wlc_hw->di[RX_FIFO]) | 2029 | if ((wlc_hw->di[RX_FIFO]) |
2024 | && (!wlc_dma_rxreset(wlc_hw, RX_FIFO))) | 2030 | && (!wlc_dma_rxreset(wlc_hw, RX_FIFO))) |
2025 | wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: dma_rxreset" | 2031 | brcms_err(wlc_hw->d11core, "wl%d: %s: dma_rxreset" |
2026 | "[%d]: cannot stop dma\n", | 2032 | "[%d]: cannot stop dma\n", |
2027 | wlc_hw->unit, __func__, RX_FIFO); | 2033 | wlc_hw->unit, __func__, RX_FIFO); |
2028 | } | 2034 | } |
@@ -2235,7 +2241,7 @@ static void brcms_ucode_write(struct brcms_hardware *wlc_hw, | |||
2235 | uint i; | 2241 | uint i; |
2236 | uint count; | 2242 | uint count; |
2237 | 2243 | ||
2238 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | 2244 | brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit); |
2239 | 2245 | ||
2240 | count = (nbytes / sizeof(u32)); | 2246 | count = (nbytes / sizeof(u32)); |
2241 | 2247 | ||
@@ -2263,8 +2269,8 @@ static void brcms_ucode_download(struct brcms_hardware *wlc_hw) | |||
2263 | ucode->bcm43xx_16_mimosz); | 2269 | ucode->bcm43xx_16_mimosz); |
2264 | wlc_hw->ucode_loaded = true; | 2270 | wlc_hw->ucode_loaded = true; |
2265 | } else | 2271 | } else |
2266 | wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in " | 2272 | brcms_err(wlc_hw->d11core, |
2267 | "corerev %d\n", | 2273 | "%s: wl%d: unsupported phy in corerev %d\n", |
2268 | __func__, wlc_hw->unit, wlc_hw->corerev); | 2274 | __func__, wlc_hw->unit, wlc_hw->corerev); |
2269 | } else if (D11REV_IS(wlc_hw->corerev, 24)) { | 2275 | } else if (D11REV_IS(wlc_hw->corerev, 24)) { |
2270 | if (BRCMS_ISLCNPHY(wlc_hw->band)) { | 2276 | if (BRCMS_ISLCNPHY(wlc_hw->band)) { |
@@ -2272,8 +2278,8 @@ static void brcms_ucode_download(struct brcms_hardware *wlc_hw) | |||
2272 | ucode->bcm43xx_24_lcnsz); | 2278 | ucode->bcm43xx_24_lcnsz); |
2273 | wlc_hw->ucode_loaded = true; | 2279 | wlc_hw->ucode_loaded = true; |
2274 | } else { | 2280 | } else { |
2275 | wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in " | 2281 | brcms_err(wlc_hw->d11core, |
2276 | "corerev %d\n", | 2282 | "%s: wl%d: unsupported phy in corerev %d\n", |
2277 | __func__, wlc_hw->unit, wlc_hw->corerev); | 2283 | __func__, wlc_hw->unit, wlc_hw->corerev); |
2278 | } | 2284 | } |
2279 | } | 2285 | } |
@@ -2310,7 +2316,6 @@ static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw) | |||
2310 | uint unit; | 2316 | uint unit; |
2311 | uint intstatus, idx; | 2317 | uint intstatus, idx; |
2312 | struct bcma_device *core = wlc_hw->d11core; | 2318 | struct bcma_device *core = wlc_hw->d11core; |
2313 | struct wiphy *wiphy = wlc_hw->wlc->wiphy; | ||
2314 | 2319 | ||
2315 | unit = wlc_hw->unit; | 2320 | unit = wlc_hw->unit; |
2316 | 2321 | ||
@@ -2323,39 +2328,39 @@ static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw) | |||
2323 | if (!intstatus) | 2328 | if (!intstatus) |
2324 | continue; | 2329 | continue; |
2325 | 2330 | ||
2326 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d: intstatus%d 0x%x\n", | 2331 | brcms_dbg_int(core, "wl%d: intstatus%d 0x%x\n", |
2327 | unit, idx, intstatus); | 2332 | unit, idx, intstatus); |
2328 | 2333 | ||
2329 | if (intstatus & I_RO) { | 2334 | if (intstatus & I_RO) { |
2330 | wiphy_err(wiphy, "wl%d: fifo %d: receive fifo " | 2335 | brcms_err(core, "wl%d: fifo %d: receive fifo " |
2331 | "overflow\n", unit, idx); | 2336 | "overflow\n", unit, idx); |
2332 | fatal = true; | 2337 | fatal = true; |
2333 | } | 2338 | } |
2334 | 2339 | ||
2335 | if (intstatus & I_PC) { | 2340 | if (intstatus & I_PC) { |
2336 | wiphy_err(wiphy, "wl%d: fifo %d: descriptor error\n", | 2341 | brcms_err(core, "wl%d: fifo %d: descriptor error\n", |
2337 | unit, idx); | 2342 | unit, idx); |
2338 | fatal = true; | 2343 | fatal = true; |
2339 | } | 2344 | } |
2340 | 2345 | ||
2341 | if (intstatus & I_PD) { | 2346 | if (intstatus & I_PD) { |
2342 | wiphy_err(wiphy, "wl%d: fifo %d: data error\n", unit, | 2347 | brcms_err(core, "wl%d: fifo %d: data error\n", unit, |
2343 | idx); | 2348 | idx); |
2344 | fatal = true; | 2349 | fatal = true; |
2345 | } | 2350 | } |
2346 | 2351 | ||
2347 | if (intstatus & I_DE) { | 2352 | if (intstatus & I_DE) { |
2348 | wiphy_err(wiphy, "wl%d: fifo %d: descriptor protocol " | 2353 | brcms_err(core, "wl%d: fifo %d: descriptor protocol " |
2349 | "error\n", unit, idx); | 2354 | "error\n", unit, idx); |
2350 | fatal = true; | 2355 | fatal = true; |
2351 | } | 2356 | } |
2352 | 2357 | ||
2353 | if (intstatus & I_RU) | 2358 | if (intstatus & I_RU) |
2354 | wiphy_err(wiphy, "wl%d: fifo %d: receive descriptor " | 2359 | brcms_err(core, "wl%d: fifo %d: receive descriptor " |
2355 | "underflow\n", idx, unit); | 2360 | "underflow\n", idx, unit); |
2356 | 2361 | ||
2357 | if (intstatus & I_XU) { | 2362 | if (intstatus & I_XU) { |
2358 | wiphy_err(wiphy, "wl%d: fifo %d: transmit fifo " | 2363 | brcms_err(core, "wl%d: fifo %d: transmit fifo " |
2359 | "underflow\n", idx, unit); | 2364 | "underflow\n", idx, unit); |
2360 | fatal = true; | 2365 | fatal = true; |
2361 | } | 2366 | } |
@@ -2516,13 +2521,13 @@ static inline u32 wlc_intstatus(struct brcms_c_info *wlc, bool in_isr) | |||
2516 | { | 2521 | { |
2517 | struct brcms_hardware *wlc_hw = wlc->hw; | 2522 | struct brcms_hardware *wlc_hw = wlc->hw; |
2518 | struct bcma_device *core = wlc_hw->d11core; | 2523 | struct bcma_device *core = wlc_hw->d11core; |
2519 | u32 macintstatus; | 2524 | u32 macintstatus, mask; |
2520 | 2525 | ||
2521 | /* macintstatus includes a DMA interrupt summary bit */ | 2526 | /* macintstatus includes a DMA interrupt summary bit */ |
2522 | macintstatus = bcma_read32(core, D11REGOFFS(macintstatus)); | 2527 | macintstatus = bcma_read32(core, D11REGOFFS(macintstatus)); |
2528 | mask = in_isr ? wlc->macintmask : wlc->defmacintmask; | ||
2523 | 2529 | ||
2524 | BCMMSG(wlc->wiphy, "wl%d: macintstatus: 0x%x\n", wlc_hw->unit, | 2530 | trace_brcms_macintstatus(&core->dev, in_isr, macintstatus, mask); |
2525 | macintstatus); | ||
2526 | 2531 | ||
2527 | /* detect cardbus removed, in power down(suspend) and in reset */ | 2532 | /* detect cardbus removed, in power down(suspend) and in reset */ |
2528 | if (brcms_deviceremoved(wlc)) | 2533 | if (brcms_deviceremoved(wlc)) |
@@ -2535,7 +2540,7 @@ static inline u32 wlc_intstatus(struct brcms_c_info *wlc, bool in_isr) | |||
2535 | return 0; | 2540 | return 0; |
2536 | 2541 | ||
2537 | /* defer unsolicited interrupts */ | 2542 | /* defer unsolicited interrupts */ |
2538 | macintstatus &= (in_isr ? wlc->macintmask : wlc->defmacintmask); | 2543 | macintstatus &= mask; |
2539 | 2544 | ||
2540 | /* if not for us */ | 2545 | /* if not for us */ |
2541 | if (macintstatus == 0) | 2546 | if (macintstatus == 0) |
@@ -2605,8 +2610,8 @@ bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc) | |||
2605 | macintstatus = wlc_intstatus(wlc, true); | 2610 | macintstatus = wlc_intstatus(wlc, true); |
2606 | 2611 | ||
2607 | if (macintstatus == 0xffffffff) | 2612 | if (macintstatus == 0xffffffff) |
2608 | wiphy_err(wlc->wiphy, "DEVICEREMOVED detected in the ISR code" | 2613 | brcms_err(wlc_hw->d11core, |
2609 | " path\n"); | 2614 | "DEVICEREMOVED detected in the ISR code path\n"); |
2610 | 2615 | ||
2611 | /* it is not for us */ | 2616 | /* it is not for us */ |
2612 | if (macintstatus == 0) | 2617 | if (macintstatus == 0) |
@@ -2626,10 +2631,9 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc) | |||
2626 | struct brcms_hardware *wlc_hw = wlc->hw; | 2631 | struct brcms_hardware *wlc_hw = wlc->hw; |
2627 | struct bcma_device *core = wlc_hw->d11core; | 2632 | struct bcma_device *core = wlc_hw->d11core; |
2628 | u32 mc, mi; | 2633 | u32 mc, mi; |
2629 | struct wiphy *wiphy = wlc->wiphy; | ||
2630 | 2634 | ||
2631 | BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, | 2635 | brcms_dbg_mac80211(core, "wl%d: bandunit %d\n", wlc_hw->unit, |
2632 | wlc_hw->band->bandunit); | 2636 | wlc_hw->band->bandunit); |
2633 | 2637 | ||
2634 | /* | 2638 | /* |
2635 | * Track overlapping suspend requests | 2639 | * Track overlapping suspend requests |
@@ -2644,7 +2648,7 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc) | |||
2644 | mc = bcma_read32(core, D11REGOFFS(maccontrol)); | 2648 | mc = bcma_read32(core, D11REGOFFS(maccontrol)); |
2645 | 2649 | ||
2646 | if (mc == 0xffffffff) { | 2650 | if (mc == 0xffffffff) { |
2647 | wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, | 2651 | brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, |
2648 | __func__); | 2652 | __func__); |
2649 | brcms_down(wlc->wl); | 2653 | brcms_down(wlc->wl); |
2650 | return; | 2654 | return; |
@@ -2655,7 +2659,7 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc) | |||
2655 | 2659 | ||
2656 | mi = bcma_read32(core, D11REGOFFS(macintstatus)); | 2660 | mi = bcma_read32(core, D11REGOFFS(macintstatus)); |
2657 | if (mi == 0xffffffff) { | 2661 | if (mi == 0xffffffff) { |
2658 | wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, | 2662 | brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, |
2659 | __func__); | 2663 | __func__); |
2660 | brcms_down(wlc->wl); | 2664 | brcms_down(wlc->wl); |
2661 | return; | 2665 | return; |
@@ -2668,10 +2672,10 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc) | |||
2668 | BRCMS_MAX_MAC_SUSPEND); | 2672 | BRCMS_MAX_MAC_SUSPEND); |
2669 | 2673 | ||
2670 | if (!(bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD)) { | 2674 | if (!(bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD)) { |
2671 | wiphy_err(wiphy, "wl%d: wlc_suspend_mac_and_wait: waited %d uS" | 2675 | brcms_err(core, "wl%d: wlc_suspend_mac_and_wait: waited %d uS" |
2672 | " and MI_MACSSPNDD is still not on.\n", | 2676 | " and MI_MACSSPNDD is still not on.\n", |
2673 | wlc_hw->unit, BRCMS_MAX_MAC_SUSPEND); | 2677 | wlc_hw->unit, BRCMS_MAX_MAC_SUSPEND); |
2674 | wiphy_err(wiphy, "wl%d: psmdebug 0x%08x, phydebug 0x%08x, " | 2678 | brcms_err(core, "wl%d: psmdebug 0x%08x, phydebug 0x%08x, " |
2675 | "psm_brc 0x%04x\n", wlc_hw->unit, | 2679 | "psm_brc 0x%04x\n", wlc_hw->unit, |
2676 | bcma_read32(core, D11REGOFFS(psmdebug)), | 2680 | bcma_read32(core, D11REGOFFS(psmdebug)), |
2677 | bcma_read32(core, D11REGOFFS(phydebug)), | 2681 | bcma_read32(core, D11REGOFFS(phydebug)), |
@@ -2680,7 +2684,7 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc) | |||
2680 | 2684 | ||
2681 | mc = bcma_read32(core, D11REGOFFS(maccontrol)); | 2685 | mc = bcma_read32(core, D11REGOFFS(maccontrol)); |
2682 | if (mc == 0xffffffff) { | 2686 | if (mc == 0xffffffff) { |
2683 | wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, | 2687 | brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, |
2684 | __func__); | 2688 | __func__); |
2685 | brcms_down(wlc->wl); | 2689 | brcms_down(wlc->wl); |
2686 | return; | 2690 | return; |
@@ -2696,8 +2700,8 @@ void brcms_c_enable_mac(struct brcms_c_info *wlc) | |||
2696 | struct bcma_device *core = wlc_hw->d11core; | 2700 | struct bcma_device *core = wlc_hw->d11core; |
2697 | u32 mc, mi; | 2701 | u32 mc, mi; |
2698 | 2702 | ||
2699 | BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, | 2703 | brcms_dbg_mac80211(core, "wl%d: bandunit %d\n", wlc_hw->unit, |
2700 | wlc->band->bandunit); | 2704 | wlc->band->bandunit); |
2701 | 2705 | ||
2702 | /* | 2706 | /* |
2703 | * Track overlapping suspend requests | 2707 | * Track overlapping suspend requests |
@@ -2740,8 +2744,6 @@ static bool brcms_b_validate_chip_access(struct brcms_hardware *wlc_hw) | |||
2740 | u32 w, val; | 2744 | u32 w, val; |
2741 | struct wiphy *wiphy = wlc_hw->wlc->wiphy; | 2745 | struct wiphy *wiphy = wlc_hw->wlc->wiphy; |
2742 | 2746 | ||
2743 | BCMMSG(wiphy, "wl%d\n", wlc_hw->unit); | ||
2744 | |||
2745 | /* Validate dchip register access */ | 2747 | /* Validate dchip register access */ |
2746 | 2748 | ||
2747 | bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0); | 2749 | bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0); |
@@ -2802,7 +2804,7 @@ void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on) | |||
2802 | struct bcma_device *core = wlc_hw->d11core; | 2804 | struct bcma_device *core = wlc_hw->d11core; |
2803 | u32 tmp; | 2805 | u32 tmp; |
2804 | 2806 | ||
2805 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | 2807 | brcms_dbg_info(core, "wl%d\n", wlc_hw->unit); |
2806 | 2808 | ||
2807 | tmp = 0; | 2809 | tmp = 0; |
2808 | 2810 | ||
@@ -2818,8 +2820,8 @@ void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on) | |||
2818 | 2820 | ||
2819 | tmp = bcma_read32(core, D11REGOFFS(clk_ctl_st)); | 2821 | tmp = bcma_read32(core, D11REGOFFS(clk_ctl_st)); |
2820 | if ((tmp & CCS_ERSRC_AVAIL_HT) != CCS_ERSRC_AVAIL_HT) | 2822 | if ((tmp & CCS_ERSRC_AVAIL_HT) != CCS_ERSRC_AVAIL_HT) |
2821 | wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on PHY" | 2823 | brcms_err(core, "%s: turn on PHY PLL failed\n", |
2822 | " PLL failed\n", __func__); | 2824 | __func__); |
2823 | } else { | 2825 | } else { |
2824 | bcma_set32(core, D11REGOFFS(clk_ctl_st), | 2826 | bcma_set32(core, D11REGOFFS(clk_ctl_st), |
2825 | tmp | CCS_ERSRC_REQ_D11PLL | | 2827 | tmp | CCS_ERSRC_REQ_D11PLL | |
@@ -2835,8 +2837,8 @@ void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on) | |||
2835 | (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) | 2837 | (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) |
2836 | != | 2838 | != |
2837 | (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) | 2839 | (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) |
2838 | wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on " | 2840 | brcms_err(core, "%s: turn on PHY PLL failed\n", |
2839 | "PHY PLL failed\n", __func__); | 2841 | __func__); |
2840 | } | 2842 | } |
2841 | } else { | 2843 | } else { |
2842 | /* | 2844 | /* |
@@ -2854,7 +2856,7 @@ static void brcms_c_coredisable(struct brcms_hardware *wlc_hw) | |||
2854 | { | 2856 | { |
2855 | bool dev_gone; | 2857 | bool dev_gone; |
2856 | 2858 | ||
2857 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | 2859 | brcms_dbg_info(wlc_hw->d11core, "wl%d: disable core\n", wlc_hw->unit); |
2858 | 2860 | ||
2859 | dev_gone = brcms_deviceremoved(wlc_hw->wlc); | 2861 | dev_gone = brcms_deviceremoved(wlc_hw->wlc); |
2860 | 2862 | ||
@@ -2884,12 +2886,14 @@ static void brcms_c_flushqueues(struct brcms_c_info *wlc) | |||
2884 | uint i; | 2886 | uint i; |
2885 | 2887 | ||
2886 | /* free any posted tx packets */ | 2888 | /* free any posted tx packets */ |
2887 | for (i = 0; i < NFIFO; i++) | 2889 | for (i = 0; i < NFIFO; i++) { |
2888 | if (wlc_hw->di[i]) { | 2890 | if (wlc_hw->di[i]) { |
2889 | dma_txreclaim(wlc_hw->di[i], DMA_RANGE_ALL); | 2891 | dma_txreclaim(wlc_hw->di[i], DMA_RANGE_ALL); |
2890 | wlc->core->txpktpend[i] = 0; | 2892 | if (i < TX_BCMC_FIFO) |
2891 | BCMMSG(wlc->wiphy, "pktpend fifo %d clrd\n", i); | 2893 | ieee80211_wake_queue(wlc->pub->ieee_hw, |
2894 | brcms_fifo_to_ac(i)); | ||
2892 | } | 2895 | } |
2896 | } | ||
2893 | 2897 | ||
2894 | /* free any posted rx packets */ | 2898 | /* free any posted rx packets */ |
2895 | dma_rxreclaim(wlc_hw->di[RX_FIFO]); | 2899 | dma_rxreclaim(wlc_hw->di[RX_FIFO]); |
@@ -3109,7 +3113,7 @@ static void brcms_c_statsupd(struct brcms_c_info *wlc) | |||
3109 | /* check for rx fifo 0 overflow */ | 3113 | /* check for rx fifo 0 overflow */ |
3110 | delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl); | 3114 | delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl); |
3111 | if (delta) | 3115 | if (delta) |
3112 | wiphy_err(wlc->wiphy, "wl%d: %u rx fifo 0 overflows!\n", | 3116 | brcms_err(wlc->hw->d11core, "wl%d: %u rx fifo 0 overflows!\n", |
3113 | wlc->pub->unit, delta); | 3117 | wlc->pub->unit, delta); |
3114 | 3118 | ||
3115 | /* check for tx fifo underflows */ | 3119 | /* check for tx fifo underflows */ |
@@ -3118,8 +3122,9 @@ static void brcms_c_statsupd(struct brcms_c_info *wlc) | |||
3118 | (u16) (wlc->core->macstat_snapshot->txfunfl[i] - | 3122 | (u16) (wlc->core->macstat_snapshot->txfunfl[i] - |
3119 | txfunfl[i]); | 3123 | txfunfl[i]); |
3120 | if (delta) | 3124 | if (delta) |
3121 | wiphy_err(wlc->wiphy, "wl%d: %u tx fifo %d underflows!" | 3125 | brcms_err(wlc->hw->d11core, |
3122 | "\n", wlc->pub->unit, delta, i); | 3126 | "wl%d: %u tx fifo %d underflows!\n", |
3127 | wlc->pub->unit, delta, i); | ||
3123 | } | 3128 | } |
3124 | #endif /* DEBUG */ | 3129 | #endif /* DEBUG */ |
3125 | 3130 | ||
@@ -3132,8 +3137,6 @@ static void brcms_c_statsupd(struct brcms_c_info *wlc) | |||
3132 | 3137 | ||
3133 | static void brcms_b_reset(struct brcms_hardware *wlc_hw) | 3138 | static void brcms_b_reset(struct brcms_hardware *wlc_hw) |
3134 | { | 3139 | { |
3135 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | ||
3136 | |||
3137 | /* reset the core */ | 3140 | /* reset the core */ |
3138 | if (!brcms_deviceremoved(wlc_hw->wlc)) | 3141 | if (!brcms_deviceremoved(wlc_hw->wlc)) |
3139 | brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS); | 3142 | brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS); |
@@ -3144,7 +3147,7 @@ static void brcms_b_reset(struct brcms_hardware *wlc_hw) | |||
3144 | 3147 | ||
3145 | void brcms_c_reset(struct brcms_c_info *wlc) | 3148 | void brcms_c_reset(struct brcms_c_info *wlc) |
3146 | { | 3149 | { |
3147 | BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); | 3150 | brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit); |
3148 | 3151 | ||
3149 | /* slurp up hw mac counters before core reset */ | 3152 | /* slurp up hw mac counters before core reset */ |
3150 | brcms_c_statsupd(wlc); | 3153 | brcms_c_statsupd(wlc); |
@@ -3189,10 +3192,9 @@ static void brcms_b_coreinit(struct brcms_c_info *wlc) | |||
3189 | bool fifosz_fixup = false; | 3192 | bool fifosz_fixup = false; |
3190 | int err = 0; | 3193 | int err = 0; |
3191 | u16 buf[NFIFO]; | 3194 | u16 buf[NFIFO]; |
3192 | struct wiphy *wiphy = wlc->wiphy; | ||
3193 | struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode; | 3195 | struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode; |
3194 | 3196 | ||
3195 | BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); | 3197 | brcms_dbg_info(core, "wl%d: core init\n", wlc_hw->unit); |
3196 | 3198 | ||
3197 | /* reset PSM */ | 3199 | /* reset PSM */ |
3198 | brcms_b_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE)); | 3200 | brcms_b_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE)); |
@@ -3212,7 +3214,7 @@ static void brcms_b_coreinit(struct brcms_c_info *wlc) | |||
3212 | SPINWAIT(((bcma_read32(core, D11REGOFFS(macintstatus)) & | 3214 | SPINWAIT(((bcma_read32(core, D11REGOFFS(macintstatus)) & |
3213 | MI_MACSSPNDD) == 0), 1000 * 1000); | 3215 | MI_MACSSPNDD) == 0), 1000 * 1000); |
3214 | if ((bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD) == 0) | 3216 | if ((bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD) == 0) |
3215 | wiphy_err(wiphy, "wl%d: wlc_coreinit: ucode did not self-" | 3217 | brcms_err(core, "wl%d: wlc_coreinit: ucode did not self-" |
3216 | "suspend!\n", wlc_hw->unit); | 3218 | "suspend!\n", wlc_hw->unit); |
3217 | 3219 | ||
3218 | brcms_c_gpio_init(wlc); | 3220 | brcms_c_gpio_init(wlc); |
@@ -3223,18 +3225,18 @@ static void brcms_b_coreinit(struct brcms_c_info *wlc) | |||
3223 | if (BRCMS_ISNPHY(wlc_hw->band)) | 3225 | if (BRCMS_ISNPHY(wlc_hw->band)) |
3224 | brcms_c_write_inits(wlc_hw, ucode->d11n0initvals16); | 3226 | brcms_c_write_inits(wlc_hw, ucode->d11n0initvals16); |
3225 | else | 3227 | else |
3226 | wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev" | 3228 | brcms_err(core, "%s: wl%d: unsupported phy in corerev" |
3227 | " %d\n", __func__, wlc_hw->unit, | 3229 | " %d\n", __func__, wlc_hw->unit, |
3228 | wlc_hw->corerev); | 3230 | wlc_hw->corerev); |
3229 | } else if (D11REV_IS(wlc_hw->corerev, 24)) { | 3231 | } else if (D11REV_IS(wlc_hw->corerev, 24)) { |
3230 | if (BRCMS_ISLCNPHY(wlc_hw->band)) | 3232 | if (BRCMS_ISLCNPHY(wlc_hw->band)) |
3231 | brcms_c_write_inits(wlc_hw, ucode->d11lcn0initvals24); | 3233 | brcms_c_write_inits(wlc_hw, ucode->d11lcn0initvals24); |
3232 | else | 3234 | else |
3233 | wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev" | 3235 | brcms_err(core, "%s: wl%d: unsupported phy in corerev" |
3234 | " %d\n", __func__, wlc_hw->unit, | 3236 | " %d\n", __func__, wlc_hw->unit, |
3235 | wlc_hw->corerev); | 3237 | wlc_hw->corerev); |
3236 | } else { | 3238 | } else { |
3237 | wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n", | 3239 | brcms_err(core, "%s: wl%d: unsupported corerev %d\n", |
3238 | __func__, wlc_hw->unit, wlc_hw->corerev); | 3240 | __func__, wlc_hw->unit, wlc_hw->corerev); |
3239 | } | 3241 | } |
3240 | 3242 | ||
@@ -3276,7 +3278,7 @@ static void brcms_b_coreinit(struct brcms_c_info *wlc) | |||
3276 | err = -1; | 3278 | err = -1; |
3277 | } | 3279 | } |
3278 | if (err != 0) | 3280 | if (err != 0) |
3279 | wiphy_err(wiphy, "wlc_coreinit: txfifo mismatch: ucode size %d" | 3281 | brcms_err(core, "wlc_coreinit: txfifo mismatch: ucode size %d" |
3280 | " driver size %d index %d\n", buf[i], | 3282 | " driver size %d index %d\n", buf[i], |
3281 | wlc_hw->xmtfifo_sz[i], i); | 3283 | wlc_hw->xmtfifo_sz[i], i); |
3282 | 3284 | ||
@@ -3359,8 +3361,6 @@ static brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec) { | |||
3359 | bool fastclk; | 3361 | bool fastclk; |
3360 | struct brcms_c_info *wlc = wlc_hw->wlc; | 3362 | struct brcms_c_info *wlc = wlc_hw->wlc; |
3361 | 3363 | ||
3362 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | ||
3363 | |||
3364 | /* request FAST clock if not on */ | 3364 | /* request FAST clock if not on */ |
3365 | fastclk = wlc_hw->forcefastclk; | 3365 | fastclk = wlc_hw->forcefastclk; |
3366 | if (!fastclk) | 3366 | if (!fastclk) |
@@ -3453,7 +3453,7 @@ static void brcms_c_rate_lookup_init(struct brcms_c_info *wlc, | |||
3453 | rate = (rateset->rates[i] & BRCMS_RATE_MASK); | 3453 | rate = (rateset->rates[i] & BRCMS_RATE_MASK); |
3454 | 3454 | ||
3455 | if (rate > BRCM_MAXRATE) { | 3455 | if (rate > BRCM_MAXRATE) { |
3456 | wiphy_err(wlc->wiphy, "brcms_c_rate_lookup_init: " | 3456 | brcms_err(wlc->hw->d11core, "brcms_c_rate_lookup_init: " |
3457 | "invalid rate 0x%X in rate set\n", | 3457 | "invalid rate 0x%X in rate set\n", |
3458 | rateset->rates[i]); | 3458 | rateset->rates[i]); |
3459 | continue; | 3459 | continue; |
@@ -3529,7 +3529,6 @@ static void brcms_c_bandinit_ordered(struct brcms_c_info *wlc, | |||
3529 | uint parkband; | 3529 | uint parkband; |
3530 | uint i, band_order[2]; | 3530 | uint i, band_order[2]; |
3531 | 3531 | ||
3532 | BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); | ||
3533 | /* | 3532 | /* |
3534 | * We might have been bandlocked during down and the chip | 3533 | * We might have been bandlocked during down and the chip |
3535 | * power-cycled (hibernate). Figure out the right band to park on | 3534 | * power-cycled (hibernate). Figure out the right band to park on |
@@ -3710,8 +3709,8 @@ static void brcms_c_set_ratetable(struct brcms_c_info *wlc) | |||
3710 | /* band-specific init */ | 3709 | /* band-specific init */ |
3711 | static void brcms_c_bsinit(struct brcms_c_info *wlc) | 3710 | static void brcms_c_bsinit(struct brcms_c_info *wlc) |
3712 | { | 3711 | { |
3713 | BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", | 3712 | brcms_dbg_info(wlc->hw->d11core, "wl%d: bandunit %d\n", |
3714 | wlc->pub->unit, wlc->band->bandunit); | 3713 | wlc->pub->unit, wlc->band->bandunit); |
3715 | 3714 | ||
3716 | /* write ucode ACK/CTS rate table */ | 3715 | /* write ucode ACK/CTS rate table */ |
3717 | brcms_c_set_ratetable(wlc); | 3716 | brcms_c_set_ratetable(wlc); |
@@ -3734,7 +3733,8 @@ brcms_c_duty_cycle_set(struct brcms_c_info *wlc, int duty_cycle, bool isOFDM, | |||
3734 | isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM : | 3733 | isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM : |
3735 | M_TX_IDLE_BUSY_RATIO_X_16_CCK; | 3734 | M_TX_IDLE_BUSY_RATIO_X_16_CCK; |
3736 | if (duty_cycle > 100 || duty_cycle < 0) { | 3735 | if (duty_cycle > 100 || duty_cycle < 0) { |
3737 | wiphy_err(wlc->wiphy, "wl%d: duty cycle value off limit\n", | 3736 | brcms_err(wlc->hw->d11core, |
3737 | "wl%d: duty cycle value off limit\n", | ||
3738 | wlc->pub->unit); | 3738 | wlc->pub->unit); |
3739 | return -EINVAL; | 3739 | return -EINVAL; |
3740 | } | 3740 | } |
@@ -3752,40 +3752,6 @@ brcms_c_duty_cycle_set(struct brcms_c_info *wlc, int duty_cycle, bool isOFDM, | |||
3752 | return 0; | 3752 | return 0; |
3753 | } | 3753 | } |
3754 | 3754 | ||
3755 | /* | ||
3756 | * Initialize the base precedence map for dequeueing | ||
3757 | * from txq based on WME settings | ||
3758 | */ | ||
3759 | static void brcms_c_tx_prec_map_init(struct brcms_c_info *wlc) | ||
3760 | { | ||
3761 | wlc->tx_prec_map = BRCMS_PREC_BMP_ALL; | ||
3762 | memset(wlc->fifo2prec_map, 0, NFIFO * sizeof(u16)); | ||
3763 | |||
3764 | wlc->fifo2prec_map[TX_AC_BK_FIFO] = BRCMS_PREC_BMP_AC_BK; | ||
3765 | wlc->fifo2prec_map[TX_AC_BE_FIFO] = BRCMS_PREC_BMP_AC_BE; | ||
3766 | wlc->fifo2prec_map[TX_AC_VI_FIFO] = BRCMS_PREC_BMP_AC_VI; | ||
3767 | wlc->fifo2prec_map[TX_AC_VO_FIFO] = BRCMS_PREC_BMP_AC_VO; | ||
3768 | } | ||
3769 | |||
3770 | static void | ||
3771 | brcms_c_txflowcontrol_signal(struct brcms_c_info *wlc, | ||
3772 | struct brcms_txq_info *qi, bool on, int prio) | ||
3773 | { | ||
3774 | /* transmit flowcontrol is not yet implemented */ | ||
3775 | } | ||
3776 | |||
3777 | static void brcms_c_txflowcontrol_reset(struct brcms_c_info *wlc) | ||
3778 | { | ||
3779 | struct brcms_txq_info *qi; | ||
3780 | |||
3781 | for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) { | ||
3782 | if (qi->stopped) { | ||
3783 | brcms_c_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO); | ||
3784 | qi->stopped = 0; | ||
3785 | } | ||
3786 | } | ||
3787 | } | ||
3788 | |||
3789 | /* push sw hps and wake state through hardware */ | 3755 | /* push sw hps and wake state through hardware */ |
3790 | static void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc) | 3756 | static void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc) |
3791 | { | 3757 | { |
@@ -3795,7 +3761,8 @@ static void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc) | |||
3795 | 3761 | ||
3796 | hps = brcms_c_ps_allowed(wlc); | 3762 | hps = brcms_c_ps_allowed(wlc); |
3797 | 3763 | ||
3798 | BCMMSG(wlc->wiphy, "wl%d: hps %d\n", wlc->pub->unit, hps); | 3764 | brcms_dbg_mac80211(wlc->hw->d11core, "wl%d: hps %d\n", wlc->pub->unit, |
3765 | hps); | ||
3799 | 3766 | ||
3800 | v1 = bcma_read32(wlc->hw->d11core, D11REGOFFS(maccontrol)); | 3767 | v1 = bcma_read32(wlc->hw->d11core, D11REGOFFS(maccontrol)); |
3801 | v2 = MCTL_WAKE; | 3768 | v2 = MCTL_WAKE; |
@@ -3881,7 +3848,8 @@ brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec, | |||
3881 | { | 3848 | { |
3882 | uint bandunit; | 3849 | uint bandunit; |
3883 | 3850 | ||
3884 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d: 0x%x\n", wlc_hw->unit, chanspec); | 3851 | brcms_dbg_mac80211(wlc_hw->d11core, "wl%d: 0x%x\n", wlc_hw->unit, |
3852 | chanspec); | ||
3885 | 3853 | ||
3886 | wlc_hw->chanspec = chanspec; | 3854 | wlc_hw->chanspec = chanspec; |
3887 | 3855 | ||
@@ -3942,7 +3910,7 @@ static void brcms_c_set_chanspec(struct brcms_c_info *wlc, u16 chanspec) | |||
3942 | u16 old_chanspec = wlc->chanspec; | 3910 | u16 old_chanspec = wlc->chanspec; |
3943 | 3911 | ||
3944 | if (!brcms_c_valid_chanspec_db(wlc->cmi, chanspec)) { | 3912 | if (!brcms_c_valid_chanspec_db(wlc->cmi, chanspec)) { |
3945 | wiphy_err(wlc->wiphy, "wl%d: %s: Bad channel %d\n", | 3913 | brcms_err(wlc->hw->d11core, "wl%d: %s: Bad channel %d\n", |
3946 | wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec)); | 3914 | wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec)); |
3947 | return; | 3915 | return; |
3948 | } | 3916 | } |
@@ -3953,8 +3921,8 @@ static void brcms_c_set_chanspec(struct brcms_c_info *wlc, u16 chanspec) | |||
3953 | if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) { | 3921 | if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) { |
3954 | switchband = true; | 3922 | switchband = true; |
3955 | if (wlc->bandlocked) { | 3923 | if (wlc->bandlocked) { |
3956 | wiphy_err(wlc->wiphy, "wl%d: %s: chspec %d " | 3924 | brcms_err(wlc->hw->d11core, |
3957 | "band is locked!\n", | 3925 | "wl%d: %s: chspec %d band is locked!\n", |
3958 | wlc->pub->unit, __func__, | 3926 | wlc->pub->unit, __func__, |
3959 | CHSPEC_CHANNEL(chanspec)); | 3927 | CHSPEC_CHANNEL(chanspec)); |
3960 | return; | 3928 | return; |
@@ -4018,6 +3986,10 @@ void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc, | |||
4018 | */ | 3986 | */ |
4019 | void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx, int val) | 3987 | void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx, int val) |
4020 | { | 3988 | { |
3989 | /* | ||
3990 | * Cannot use brcms_dbg_* here because this function is called | ||
3991 | * before wlc is sufficiently initialized. | ||
3992 | */ | ||
4021 | BCMMSG(wlc->wiphy, "idx %d, val %d\n", idx, val); | 3993 | BCMMSG(wlc->wiphy, "idx %d, val %d\n", idx, val); |
4022 | 3994 | ||
4023 | switch (idx) { | 3995 | switch (idx) { |
@@ -4090,8 +4062,8 @@ void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci, | |||
4090 | 4062 | ||
4091 | /* Only apply params if the core is out of reset and has clocks */ | 4063 | /* Only apply params if the core is out of reset and has clocks */ |
4092 | if (!wlc->clk) { | 4064 | if (!wlc->clk) { |
4093 | wiphy_err(wlc->wiphy, "wl%d: %s : no-clock\n", wlc->pub->unit, | 4065 | brcms_err(wlc->hw->d11core, "wl%d: %s : no-clock\n", |
4094 | __func__); | 4066 | wlc->pub->unit, __func__); |
4095 | return; | 4067 | return; |
4096 | } | 4068 | } |
4097 | 4069 | ||
@@ -4109,7 +4081,7 @@ void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci, | |||
4109 | 4081 | ||
4110 | if (acp_shm.aifs < EDCF_AIFSN_MIN | 4082 | if (acp_shm.aifs < EDCF_AIFSN_MIN |
4111 | || acp_shm.aifs > EDCF_AIFSN_MAX) { | 4083 | || acp_shm.aifs > EDCF_AIFSN_MAX) { |
4112 | wiphy_err(wlc->wiphy, "wl%d: edcf_setparams: bad " | 4084 | brcms_err(wlc->hw->d11core, "wl%d: edcf_setparams: bad " |
4113 | "aifs %d\n", wlc->pub->unit, acp_shm.aifs); | 4085 | "aifs %d\n", wlc->pub->unit, acp_shm.aifs); |
4114 | } else { | 4086 | } else { |
4115 | acp_shm.cwmin = params->cw_min; | 4087 | acp_shm.cwmin = params->cw_min; |
@@ -4224,8 +4196,8 @@ static void brcms_c_radio_timer(void *arg) | |||
4224 | struct brcms_c_info *wlc = (struct brcms_c_info *) arg; | 4196 | struct brcms_c_info *wlc = (struct brcms_c_info *) arg; |
4225 | 4197 | ||
4226 | if (brcms_deviceremoved(wlc)) { | 4198 | if (brcms_deviceremoved(wlc)) { |
4227 | wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit, | 4199 | brcms_err(wlc->hw->d11core, "wl%d: %s: dead chip\n", |
4228 | __func__); | 4200 | wlc->pub->unit, __func__); |
4229 | brcms_down(wlc->wl); | 4201 | brcms_down(wlc->wl); |
4230 | return; | 4202 | return; |
4231 | } | 4203 | } |
@@ -4238,8 +4210,6 @@ static void brcms_b_watchdog(struct brcms_c_info *wlc) | |||
4238 | { | 4210 | { |
4239 | struct brcms_hardware *wlc_hw = wlc->hw; | 4211 | struct brcms_hardware *wlc_hw = wlc->hw; |
4240 | 4212 | ||
4241 | BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); | ||
4242 | |||
4243 | if (!wlc_hw->up) | 4213 | if (!wlc_hw->up) |
4244 | return; | 4214 | return; |
4245 | 4215 | ||
@@ -4258,14 +4228,14 @@ static void brcms_b_watchdog(struct brcms_c_info *wlc) | |||
4258 | /* common watchdog code */ | 4228 | /* common watchdog code */ |
4259 | static void brcms_c_watchdog(struct brcms_c_info *wlc) | 4229 | static void brcms_c_watchdog(struct brcms_c_info *wlc) |
4260 | { | 4230 | { |
4261 | BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); | 4231 | brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit); |
4262 | 4232 | ||
4263 | if (!wlc->pub->up) | 4233 | if (!wlc->pub->up) |
4264 | return; | 4234 | return; |
4265 | 4235 | ||
4266 | if (brcms_deviceremoved(wlc)) { | 4236 | if (brcms_deviceremoved(wlc)) { |
4267 | wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit, | 4237 | brcms_err(wlc->hw->d11core, "wl%d: %s: dead chip\n", |
4268 | __func__); | 4238 | wlc->pub->unit, __func__); |
4269 | brcms_down(wlc->wl); | 4239 | brcms_down(wlc->wl); |
4270 | return; | 4240 | return; |
4271 | } | 4241 | } |
@@ -4437,13 +4407,13 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core, | |||
4437 | struct ssb_sprom *sprom = &core->bus->sprom; | 4407 | struct ssb_sprom *sprom = &core->bus->sprom; |
4438 | 4408 | ||
4439 | if (core->bus->hosttype == BCMA_HOSTTYPE_PCI) | 4409 | if (core->bus->hosttype == BCMA_HOSTTYPE_PCI) |
4440 | BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit, | 4410 | brcms_dbg_info(core, "wl%d: vendor 0x%x device 0x%x\n", unit, |
4441 | pcidev->vendor, | 4411 | pcidev->vendor, |
4442 | pcidev->device); | 4412 | pcidev->device); |
4443 | else | 4413 | else |
4444 | BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit, | 4414 | brcms_dbg_info(core, "wl%d: vendor 0x%x device 0x%x\n", unit, |
4445 | core->bus->boardinfo.vendor, | 4415 | core->bus->boardinfo.vendor, |
4446 | core->bus->boardinfo.type); | 4416 | core->bus->boardinfo.type); |
4447 | 4417 | ||
4448 | wme = true; | 4418 | wme = true; |
4449 | 4419 | ||
@@ -4715,8 +4685,9 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core, | |||
4715 | goto fail; | 4685 | goto fail; |
4716 | } | 4686 | } |
4717 | 4687 | ||
4718 | BCMMSG(wlc->wiphy, "deviceid 0x%x nbands %d board 0x%x\n", | 4688 | brcms_dbg_info(wlc_hw->d11core, "deviceid 0x%x nbands %d board 0x%x\n", |
4719 | wlc_hw->deviceid, wlc_hw->_nbands, ai_get_boardtype(wlc_hw->sih)); | 4689 | wlc_hw->deviceid, wlc_hw->_nbands, |
4690 | ai_get_boardtype(wlc_hw->sih)); | ||
4720 | 4691 | ||
4721 | return err; | 4692 | return err; |
4722 | 4693 | ||
@@ -4836,56 +4807,6 @@ static void brcms_c_bss_default_init(struct brcms_c_info *wlc) | |||
4836 | bi->flags |= BRCMS_BSS_HT; | 4807 | bi->flags |= BRCMS_BSS_HT; |
4837 | } | 4808 | } |
4838 | 4809 | ||
4839 | static struct brcms_txq_info *brcms_c_txq_alloc(struct brcms_c_info *wlc) | ||
4840 | { | ||
4841 | struct brcms_txq_info *qi, *p; | ||
4842 | |||
4843 | qi = kzalloc(sizeof(struct brcms_txq_info), GFP_ATOMIC); | ||
4844 | if (qi != NULL) { | ||
4845 | /* | ||
4846 | * Have enough room for control packets along with HI watermark | ||
4847 | * Also, add room to txq for total psq packets if all the SCBs | ||
4848 | * leave PS mode. The watermark for flowcontrol to OS packets | ||
4849 | * will remain the same | ||
4850 | */ | ||
4851 | brcmu_pktq_init(&qi->q, BRCMS_PREC_COUNT, | ||
4852 | 2 * BRCMS_DATAHIWAT + PKTQ_LEN_DEFAULT); | ||
4853 | |||
4854 | /* add this queue to the the global list */ | ||
4855 | p = wlc->tx_queues; | ||
4856 | if (p == NULL) { | ||
4857 | wlc->tx_queues = qi; | ||
4858 | } else { | ||
4859 | while (p->next != NULL) | ||
4860 | p = p->next; | ||
4861 | p->next = qi; | ||
4862 | } | ||
4863 | } | ||
4864 | return qi; | ||
4865 | } | ||
4866 | |||
4867 | static void brcms_c_txq_free(struct brcms_c_info *wlc, | ||
4868 | struct brcms_txq_info *qi) | ||
4869 | { | ||
4870 | struct brcms_txq_info *p; | ||
4871 | |||
4872 | if (qi == NULL) | ||
4873 | return; | ||
4874 | |||
4875 | /* remove the queue from the linked list */ | ||
4876 | p = wlc->tx_queues; | ||
4877 | if (p == qi) | ||
4878 | wlc->tx_queues = p->next; | ||
4879 | else { | ||
4880 | while (p != NULL && p->next != qi) | ||
4881 | p = p->next; | ||
4882 | if (p != NULL) | ||
4883 | p->next = p->next->next; | ||
4884 | } | ||
4885 | |||
4886 | kfree(qi); | ||
4887 | } | ||
4888 | |||
4889 | static void brcms_c_update_mimo_band_bwcap(struct brcms_c_info *wlc, u8 bwcap) | 4810 | static void brcms_c_update_mimo_band_bwcap(struct brcms_c_info *wlc, u8 bwcap) |
4890 | { | 4811 | { |
4891 | uint i; | 4812 | uint i; |
@@ -4991,8 +4912,6 @@ uint brcms_c_detach(struct brcms_c_info *wlc) | |||
4991 | if (wlc == NULL) | 4912 | if (wlc == NULL) |
4992 | return 0; | 4913 | return 0; |
4993 | 4914 | ||
4994 | BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); | ||
4995 | |||
4996 | callbacks += brcms_b_detach(wlc); | 4915 | callbacks += brcms_b_detach(wlc); |
4997 | 4916 | ||
4998 | /* delete software timers */ | 4917 | /* delete software timers */ |
@@ -5005,10 +4924,6 @@ uint brcms_c_detach(struct brcms_c_info *wlc) | |||
5005 | 4924 | ||
5006 | brcms_c_detach_module(wlc); | 4925 | brcms_c_detach_module(wlc); |
5007 | 4926 | ||
5008 | |||
5009 | while (wlc->tx_queues != NULL) | ||
5010 | brcms_c_txq_free(wlc, wlc->tx_queues); | ||
5011 | |||
5012 | brcms_c_detach_mfree(wlc); | 4927 | brcms_c_detach_mfree(wlc); |
5013 | return callbacks; | 4928 | return callbacks; |
5014 | } | 4929 | } |
@@ -5026,7 +4941,7 @@ static void brcms_b_hw_up(struct brcms_hardware *wlc_hw) | |||
5026 | if (wlc_hw->wlc->pub->hw_up) | 4941 | if (wlc_hw->wlc->pub->hw_up) |
5027 | return; | 4942 | return; |
5028 | 4943 | ||
5029 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | 4944 | brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit); |
5030 | 4945 | ||
5031 | /* | 4946 | /* |
5032 | * Enable pll and xtal, initialize the power control registers, | 4947 | * Enable pll and xtal, initialize the power control registers, |
@@ -5063,7 +4978,7 @@ static void brcms_b_hw_up(struct brcms_hardware *wlc_hw) | |||
5063 | 4978 | ||
5064 | static int brcms_b_up_prep(struct brcms_hardware *wlc_hw) | 4979 | static int brcms_b_up_prep(struct brcms_hardware *wlc_hw) |
5065 | { | 4980 | { |
5066 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | 4981 | brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit); |
5067 | 4982 | ||
5068 | /* | 4983 | /* |
5069 | * Enable pll and xtal, initialize the power control registers, | 4984 | * Enable pll and xtal, initialize the power control registers, |
@@ -5102,8 +5017,6 @@ static int brcms_b_up_prep(struct brcms_hardware *wlc_hw) | |||
5102 | 5017 | ||
5103 | static int brcms_b_up_finish(struct brcms_hardware *wlc_hw) | 5018 | static int brcms_b_up_finish(struct brcms_hardware *wlc_hw) |
5104 | { | 5019 | { |
5105 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | ||
5106 | |||
5107 | wlc_hw->up = true; | 5020 | wlc_hw->up = true; |
5108 | wlc_phy_hw_state_upd(wlc_hw->band->pi, true); | 5021 | wlc_phy_hw_state_upd(wlc_hw->band->pi, true); |
5109 | 5022 | ||
@@ -5135,7 +5048,7 @@ int brcms_c_up(struct brcms_c_info *wlc) | |||
5135 | { | 5048 | { |
5136 | struct ieee80211_channel *ch; | 5049 | struct ieee80211_channel *ch; |
5137 | 5050 | ||
5138 | BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); | 5051 | brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit); |
5139 | 5052 | ||
5140 | /* HW is turned off so don't try to access it */ | 5053 | /* HW is turned off so don't try to access it */ |
5141 | if (wlc->pub->hw_off || brcms_deviceremoved(wlc)) | 5054 | if (wlc->pub->hw_off || brcms_deviceremoved(wlc)) |
@@ -5176,8 +5089,8 @@ int brcms_c_up(struct brcms_c_info *wlc) | |||
5176 | WL_RADIO_HW_DISABLE); | 5089 | WL_RADIO_HW_DISABLE); |
5177 | 5090 | ||
5178 | if (bsscfg->enable && bsscfg->BSS) | 5091 | if (bsscfg->enable && bsscfg->BSS) |
5179 | wiphy_err(wlc->wiphy, "wl%d: up" | 5092 | brcms_err(wlc->hw->d11core, |
5180 | ": rfdisable -> " | 5093 | "wl%d: up: rfdisable -> " |
5181 | "bsscfg_disable()\n", | 5094 | "bsscfg_disable()\n", |
5182 | wlc->pub->unit); | 5095 | wlc->pub->unit); |
5183 | } | 5096 | } |
@@ -5237,8 +5150,6 @@ static int brcms_b_bmac_down_prep(struct brcms_hardware *wlc_hw) | |||
5237 | bool dev_gone; | 5150 | bool dev_gone; |
5238 | uint callbacks = 0; | 5151 | uint callbacks = 0; |
5239 | 5152 | ||
5240 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | ||
5241 | |||
5242 | if (!wlc_hw->up) | 5153 | if (!wlc_hw->up) |
5243 | return callbacks; | 5154 | return callbacks; |
5244 | 5155 | ||
@@ -5265,8 +5176,6 @@ static int brcms_b_down_finish(struct brcms_hardware *wlc_hw) | |||
5265 | uint callbacks = 0; | 5176 | uint callbacks = 0; |
5266 | bool dev_gone; | 5177 | bool dev_gone; |
5267 | 5178 | ||
5268 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | ||
5269 | |||
5270 | if (!wlc_hw->up) | 5179 | if (!wlc_hw->up) |
5271 | return callbacks; | 5180 | return callbacks; |
5272 | 5181 | ||
@@ -5314,14 +5223,14 @@ uint brcms_c_down(struct brcms_c_info *wlc) | |||
5314 | uint callbacks = 0; | 5223 | uint callbacks = 0; |
5315 | int i; | 5224 | int i; |
5316 | bool dev_gone = false; | 5225 | bool dev_gone = false; |
5317 | struct brcms_txq_info *qi; | ||
5318 | 5226 | ||
5319 | BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); | 5227 | brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit); |
5320 | 5228 | ||
5321 | /* check if we are already in the going down path */ | 5229 | /* check if we are already in the going down path */ |
5322 | if (wlc->going_down) { | 5230 | if (wlc->going_down) { |
5323 | wiphy_err(wlc->wiphy, "wl%d: %s: Driver going down so return" | 5231 | brcms_err(wlc->hw->d11core, |
5324 | "\n", wlc->pub->unit, __func__); | 5232 | "wl%d: %s: Driver going down so return\n", |
5233 | wlc->pub->unit, __func__); | ||
5325 | return 0; | 5234 | return 0; |
5326 | } | 5235 | } |
5327 | if (!wlc->pub->up) | 5236 | if (!wlc->pub->up) |
@@ -5353,13 +5262,6 @@ uint brcms_c_down(struct brcms_c_info *wlc) | |||
5353 | 5262 | ||
5354 | wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL); | 5263 | wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL); |
5355 | 5264 | ||
5356 | /* clear txq flow control */ | ||
5357 | brcms_c_txflowcontrol_reset(wlc); | ||
5358 | |||
5359 | /* flush tx queues */ | ||
5360 | for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) | ||
5361 | brcmu_pktq_flush(&qi->q, true, NULL, NULL); | ||
5362 | |||
5363 | callbacks += brcms_b_down_finish(wlc->hw); | 5265 | callbacks += brcms_b_down_finish(wlc->hw); |
5364 | 5266 | ||
5365 | /* brcms_b_down_finish has done brcms_c_coredisable(). so clk is off */ | 5267 | /* brcms_b_down_finish has done brcms_c_coredisable(). so clk is off */ |
@@ -5441,7 +5343,7 @@ int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config) | |||
5441 | 5343 | ||
5442 | default: | 5344 | default: |
5443 | /* Error */ | 5345 | /* Error */ |
5444 | wiphy_err(wlc->wiphy, "wl%d: %s: invalid gmode %d\n", | 5346 | brcms_err(wlc->hw->d11core, "wl%d: %s: invalid gmode %d\n", |
5445 | wlc->pub->unit, __func__, gmode); | 5347 | wlc->pub->unit, __func__, gmode); |
5446 | return -ENOTSUPP; | 5348 | return -ENOTSUPP; |
5447 | } | 5349 | } |
@@ -5745,45 +5647,6 @@ int brcms_c_module_unregister(struct brcms_pub *pub, const char *name, | |||
5745 | return -ENODATA; | 5647 | return -ENODATA; |
5746 | } | 5648 | } |
5747 | 5649 | ||
5748 | void brcms_c_print_txstatus(struct tx_status *txs) | ||
5749 | { | ||
5750 | pr_debug("\ntxpkt (MPDU) Complete\n"); | ||
5751 | |||
5752 | pr_debug("FrameID: %04x TxStatus: %04x\n", txs->frameid, txs->status); | ||
5753 | |||
5754 | pr_debug("[15:12] %d frame attempts\n", | ||
5755 | (txs->status & TX_STATUS_FRM_RTX_MASK) >> | ||
5756 | TX_STATUS_FRM_RTX_SHIFT); | ||
5757 | pr_debug(" [11:8] %d rts attempts\n", | ||
5758 | (txs->status & TX_STATUS_RTS_RTX_MASK) >> | ||
5759 | TX_STATUS_RTS_RTX_SHIFT); | ||
5760 | pr_debug(" [7] %d PM mode indicated\n", | ||
5761 | txs->status & TX_STATUS_PMINDCTD ? 1 : 0); | ||
5762 | pr_debug(" [6] %d intermediate status\n", | ||
5763 | txs->status & TX_STATUS_INTERMEDIATE ? 1 : 0); | ||
5764 | pr_debug(" [5] %d AMPDU\n", | ||
5765 | txs->status & TX_STATUS_AMPDU ? 1 : 0); | ||
5766 | pr_debug(" [4:2] %d Frame Suppressed Reason (%s)\n", | ||
5767 | (txs->status & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT, | ||
5768 | (const char *[]) { | ||
5769 | "None", | ||
5770 | "PMQ Entry", | ||
5771 | "Flush request", | ||
5772 | "Previous frag failure", | ||
5773 | "Channel mismatch", | ||
5774 | "Lifetime Expiry", | ||
5775 | "Underflow" | ||
5776 | } [(txs->status & TX_STATUS_SUPR_MASK) >> | ||
5777 | TX_STATUS_SUPR_SHIFT]); | ||
5778 | pr_debug(" [1] %d acked\n", | ||
5779 | txs->status & TX_STATUS_ACK_RCV ? 1 : 0); | ||
5780 | |||
5781 | pr_debug("LastTxTime: %04x Seq: %04x PHYTxStatus: %04x RxAckRSSI: %04x RxAckSQ: %04x\n", | ||
5782 | txs->lasttxtime, txs->sequence, txs->phyerr, | ||
5783 | (txs->ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT, | ||
5784 | (txs->ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT); | ||
5785 | } | ||
5786 | |||
5787 | static bool brcms_c_chipmatch_pci(struct bcma_device *core) | 5650 | static bool brcms_c_chipmatch_pci(struct bcma_device *core) |
5788 | { | 5651 | { |
5789 | struct pci_dev *pcidev = core->bus->host_pci; | 5652 | struct pci_dev *pcidev = core->bus->host_pci; |
@@ -5832,184 +5695,6 @@ bool brcms_c_chipmatch(struct bcma_device *core) | |||
5832 | } | 5695 | } |
5833 | } | 5696 | } |
5834 | 5697 | ||
5835 | #if defined(DEBUG) | ||
5836 | void brcms_c_print_txdesc(struct d11txh *txh) | ||
5837 | { | ||
5838 | u16 mtcl = le16_to_cpu(txh->MacTxControlLow); | ||
5839 | u16 mtch = le16_to_cpu(txh->MacTxControlHigh); | ||
5840 | u16 mfc = le16_to_cpu(txh->MacFrameControl); | ||
5841 | u16 tfest = le16_to_cpu(txh->TxFesTimeNormal); | ||
5842 | u16 ptcw = le16_to_cpu(txh->PhyTxControlWord); | ||
5843 | u16 ptcw_1 = le16_to_cpu(txh->PhyTxControlWord_1); | ||
5844 | u16 ptcw_1_Fbr = le16_to_cpu(txh->PhyTxControlWord_1_Fbr); | ||
5845 | u16 ptcw_1_Rts = le16_to_cpu(txh->PhyTxControlWord_1_Rts); | ||
5846 | u16 ptcw_1_FbrRts = le16_to_cpu(txh->PhyTxControlWord_1_FbrRts); | ||
5847 | u16 mainrates = le16_to_cpu(txh->MainRates); | ||
5848 | u16 xtraft = le16_to_cpu(txh->XtraFrameTypes); | ||
5849 | u8 *iv = txh->IV; | ||
5850 | u8 *ra = txh->TxFrameRA; | ||
5851 | u16 tfestfb = le16_to_cpu(txh->TxFesTimeFallback); | ||
5852 | u8 *rtspfb = txh->RTSPLCPFallback; | ||
5853 | u16 rtsdfb = le16_to_cpu(txh->RTSDurFallback); | ||
5854 | u8 *fragpfb = txh->FragPLCPFallback; | ||
5855 | u16 fragdfb = le16_to_cpu(txh->FragDurFallback); | ||
5856 | u16 mmodelen = le16_to_cpu(txh->MModeLen); | ||
5857 | u16 mmodefbrlen = le16_to_cpu(txh->MModeFbrLen); | ||
5858 | u16 tfid = le16_to_cpu(txh->TxFrameID); | ||
5859 | u16 txs = le16_to_cpu(txh->TxStatus); | ||
5860 | u16 mnmpdu = le16_to_cpu(txh->MaxNMpdus); | ||
5861 | u16 mabyte = le16_to_cpu(txh->MaxABytes_MRT); | ||
5862 | u16 mabyte_f = le16_to_cpu(txh->MaxABytes_FBR); | ||
5863 | u16 mmbyte = le16_to_cpu(txh->MinMBytes); | ||
5864 | |||
5865 | u8 *rtsph = txh->RTSPhyHeader; | ||
5866 | struct ieee80211_rts rts = txh->rts_frame; | ||
5867 | |||
5868 | /* add plcp header along with txh descriptor */ | ||
5869 | brcmu_dbg_hex_dump(txh, sizeof(struct d11txh) + 48, | ||
5870 | "Raw TxDesc + plcp header:\n"); | ||
5871 | |||
5872 | pr_debug("TxCtlLow: %04x ", mtcl); | ||
5873 | pr_debug("TxCtlHigh: %04x ", mtch); | ||
5874 | pr_debug("FC: %04x ", mfc); | ||
5875 | pr_debug("FES Time: %04x\n", tfest); | ||
5876 | pr_debug("PhyCtl: %04x%s ", ptcw, | ||
5877 | (ptcw & PHY_TXC_SHORT_HDR) ? " short" : ""); | ||
5878 | pr_debug("PhyCtl_1: %04x ", ptcw_1); | ||
5879 | pr_debug("PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr); | ||
5880 | pr_debug("PhyCtl_1_Rts: %04x ", ptcw_1_Rts); | ||
5881 | pr_debug("PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts); | ||
5882 | pr_debug("MainRates: %04x ", mainrates); | ||
5883 | pr_debug("XtraFrameTypes: %04x ", xtraft); | ||
5884 | pr_debug("\n"); | ||
5885 | |||
5886 | print_hex_dump_bytes("SecIV:", DUMP_PREFIX_OFFSET, iv, sizeof(txh->IV)); | ||
5887 | print_hex_dump_bytes("RA:", DUMP_PREFIX_OFFSET, | ||
5888 | ra, sizeof(txh->TxFrameRA)); | ||
5889 | |||
5890 | pr_debug("Fb FES Time: %04x ", tfestfb); | ||
5891 | print_hex_dump_bytes("Fb RTS PLCP:", DUMP_PREFIX_OFFSET, | ||
5892 | rtspfb, sizeof(txh->RTSPLCPFallback)); | ||
5893 | pr_debug("RTS DUR: %04x ", rtsdfb); | ||
5894 | print_hex_dump_bytes("PLCP:", DUMP_PREFIX_OFFSET, | ||
5895 | fragpfb, sizeof(txh->FragPLCPFallback)); | ||
5896 | pr_debug("DUR: %04x", fragdfb); | ||
5897 | pr_debug("\n"); | ||
5898 | |||
5899 | pr_debug("MModeLen: %04x ", mmodelen); | ||
5900 | pr_debug("MModeFbrLen: %04x\n", mmodefbrlen); | ||
5901 | |||
5902 | pr_debug("FrameID: %04x\n", tfid); | ||
5903 | pr_debug("TxStatus: %04x\n", txs); | ||
5904 | |||
5905 | pr_debug("MaxNumMpdu: %04x\n", mnmpdu); | ||
5906 | pr_debug("MaxAggbyte: %04x\n", mabyte); | ||
5907 | pr_debug("MaxAggbyte_fb: %04x\n", mabyte_f); | ||
5908 | pr_debug("MinByte: %04x\n", mmbyte); | ||
5909 | |||
5910 | print_hex_dump_bytes("RTS PLCP:", DUMP_PREFIX_OFFSET, | ||
5911 | rtsph, sizeof(txh->RTSPhyHeader)); | ||
5912 | print_hex_dump_bytes("RTS Frame:", DUMP_PREFIX_OFFSET, | ||
5913 | (u8 *)&rts, sizeof(txh->rts_frame)); | ||
5914 | pr_debug("\n"); | ||
5915 | } | ||
5916 | #endif /* defined(DEBUG) */ | ||
5917 | |||
5918 | #if defined(DEBUG) | ||
5919 | static int | ||
5920 | brcms_c_format_flags(const struct brcms_c_bit_desc *bd, u32 flags, char *buf, | ||
5921 | int len) | ||
5922 | { | ||
5923 | int i; | ||
5924 | char *p = buf; | ||
5925 | char hexstr[16]; | ||
5926 | int slen = 0, nlen = 0; | ||
5927 | u32 bit; | ||
5928 | const char *name; | ||
5929 | |||
5930 | if (len < 2 || !buf) | ||
5931 | return 0; | ||
5932 | |||
5933 | buf[0] = '\0'; | ||
5934 | |||
5935 | for (i = 0; flags != 0; i++) { | ||
5936 | bit = bd[i].bit; | ||
5937 | name = bd[i].name; | ||
5938 | if (bit == 0 && flags != 0) { | ||
5939 | /* print any unnamed bits */ | ||
5940 | snprintf(hexstr, 16, "0x%X", flags); | ||
5941 | name = hexstr; | ||
5942 | flags = 0; /* exit loop */ | ||
5943 | } else if ((flags & bit) == 0) | ||
5944 | continue; | ||
5945 | flags &= ~bit; | ||
5946 | nlen = strlen(name); | ||
5947 | slen += nlen; | ||
5948 | /* count btwn flag space */ | ||
5949 | if (flags != 0) | ||
5950 | slen += 1; | ||
5951 | /* need NULL char as well */ | ||
5952 | if (len <= slen) | ||
5953 | break; | ||
5954 | /* copy NULL char but don't count it */ | ||
5955 | strncpy(p, name, nlen + 1); | ||
5956 | p += nlen; | ||
5957 | /* copy btwn flag space and NULL char */ | ||
5958 | if (flags != 0) | ||
5959 | p += snprintf(p, 2, " "); | ||
5960 | len -= slen; | ||
5961 | } | ||
5962 | |||
5963 | /* indicate the str was too short */ | ||
5964 | if (flags != 0) { | ||
5965 | if (len < 2) | ||
5966 | p -= 2 - len; /* overwrite last char */ | ||
5967 | p += snprintf(p, 2, ">"); | ||
5968 | } | ||
5969 | |||
5970 | return (int)(p - buf); | ||
5971 | } | ||
5972 | #endif /* defined(DEBUG) */ | ||
5973 | |||
5974 | #if defined(DEBUG) | ||
5975 | void brcms_c_print_rxh(struct d11rxhdr *rxh) | ||
5976 | { | ||
5977 | u16 len = rxh->RxFrameSize; | ||
5978 | u16 phystatus_0 = rxh->PhyRxStatus_0; | ||
5979 | u16 phystatus_1 = rxh->PhyRxStatus_1; | ||
5980 | u16 phystatus_2 = rxh->PhyRxStatus_2; | ||
5981 | u16 phystatus_3 = rxh->PhyRxStatus_3; | ||
5982 | u16 macstatus1 = rxh->RxStatus1; | ||
5983 | u16 macstatus2 = rxh->RxStatus2; | ||
5984 | char flagstr[64]; | ||
5985 | char lenbuf[20]; | ||
5986 | static const struct brcms_c_bit_desc macstat_flags[] = { | ||
5987 | {RXS_FCSERR, "FCSErr"}, | ||
5988 | {RXS_RESPFRAMETX, "Reply"}, | ||
5989 | {RXS_PBPRES, "PADDING"}, | ||
5990 | {RXS_DECATMPT, "DeCr"}, | ||
5991 | {RXS_DECERR, "DeCrErr"}, | ||
5992 | {RXS_BCNSENT, "Bcn"}, | ||
5993 | {0, NULL} | ||
5994 | }; | ||
5995 | |||
5996 | brcmu_dbg_hex_dump(rxh, sizeof(struct d11rxhdr), "Raw RxDesc:\n"); | ||
5997 | |||
5998 | brcms_c_format_flags(macstat_flags, macstatus1, flagstr, 64); | ||
5999 | |||
6000 | snprintf(lenbuf, sizeof(lenbuf), "0x%x", len); | ||
6001 | |||
6002 | pr_debug("RxFrameSize: %6s (%d)%s\n", lenbuf, len, | ||
6003 | (rxh->PhyRxStatus_0 & PRXS0_SHORTH) ? " short preamble" : ""); | ||
6004 | pr_debug("RxPHYStatus: %04x %04x %04x %04x\n", | ||
6005 | phystatus_0, phystatus_1, phystatus_2, phystatus_3); | ||
6006 | pr_debug("RxMACStatus: %x %s\n", macstatus1, flagstr); | ||
6007 | pr_debug("RXMACaggtype: %x\n", | ||
6008 | (macstatus2 & RXS_AGGTYPE_MASK)); | ||
6009 | pr_debug("RxTSFTime: %04x\n", rxh->RxTSFTime); | ||
6010 | } | ||
6011 | #endif /* defined(DEBUG) */ | ||
6012 | |||
6013 | u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate) | 5698 | u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate) |
6014 | { | 5699 | { |
6015 | u16 table_ptr; | 5700 | u16 table_ptr; |
@@ -6033,86 +5718,6 @@ u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate) | |||
6033 | return 2 * brcms_b_read_shm(wlc_hw, table_ptr + (index * 2)); | 5718 | return 2 * brcms_b_read_shm(wlc_hw, table_ptr + (index * 2)); |
6034 | } | 5719 | } |
6035 | 5720 | ||
6036 | static bool | ||
6037 | brcms_c_prec_enq_head(struct brcms_c_info *wlc, struct pktq *q, | ||
6038 | struct sk_buff *pkt, int prec, bool head) | ||
6039 | { | ||
6040 | struct sk_buff *p; | ||
6041 | int eprec = -1; /* precedence to evict from */ | ||
6042 | |||
6043 | /* Determine precedence from which to evict packet, if any */ | ||
6044 | if (pktq_pfull(q, prec)) | ||
6045 | eprec = prec; | ||
6046 | else if (pktq_full(q)) { | ||
6047 | p = brcmu_pktq_peek_tail(q, &eprec); | ||
6048 | if (eprec > prec) { | ||
6049 | wiphy_err(wlc->wiphy, "%s: Failing: eprec %d > prec %d" | ||
6050 | "\n", __func__, eprec, prec); | ||
6051 | return false; | ||
6052 | } | ||
6053 | } | ||
6054 | |||
6055 | /* Evict if needed */ | ||
6056 | if (eprec >= 0) { | ||
6057 | bool discard_oldest; | ||
6058 | |||
6059 | discard_oldest = ac_bitmap_tst(0, eprec); | ||
6060 | |||
6061 | /* Refuse newer packet unless configured to discard oldest */ | ||
6062 | if (eprec == prec && !discard_oldest) { | ||
6063 | wiphy_err(wlc->wiphy, "%s: No where to go, prec == %d" | ||
6064 | "\n", __func__, prec); | ||
6065 | return false; | ||
6066 | } | ||
6067 | |||
6068 | /* Evict packet according to discard policy */ | ||
6069 | p = discard_oldest ? brcmu_pktq_pdeq(q, eprec) : | ||
6070 | brcmu_pktq_pdeq_tail(q, eprec); | ||
6071 | brcmu_pkt_buf_free_skb(p); | ||
6072 | } | ||
6073 | |||
6074 | /* Enqueue */ | ||
6075 | if (head) | ||
6076 | p = brcmu_pktq_penq_head(q, prec, pkt); | ||
6077 | else | ||
6078 | p = brcmu_pktq_penq(q, prec, pkt); | ||
6079 | |||
6080 | return true; | ||
6081 | } | ||
6082 | |||
6083 | /* | ||
6084 | * Attempts to queue a packet onto a multiple-precedence queue, | ||
6085 | * if necessary evicting a lower precedence packet from the queue. | ||
6086 | * | ||
6087 | * 'prec' is the precedence number that has already been mapped | ||
6088 | * from the packet priority. | ||
6089 | * | ||
6090 | * Returns true if packet consumed (queued), false if not. | ||
6091 | */ | ||
6092 | static bool brcms_c_prec_enq(struct brcms_c_info *wlc, struct pktq *q, | ||
6093 | struct sk_buff *pkt, int prec) | ||
6094 | { | ||
6095 | return brcms_c_prec_enq_head(wlc, q, pkt, prec, false); | ||
6096 | } | ||
6097 | |||
6098 | void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb, | ||
6099 | struct sk_buff *sdu, uint prec) | ||
6100 | { | ||
6101 | struct brcms_txq_info *qi = wlc->pkt_queue; /* Check me */ | ||
6102 | struct pktq *q = &qi->q; | ||
6103 | int prio; | ||
6104 | |||
6105 | prio = sdu->priority; | ||
6106 | |||
6107 | if (!brcms_c_prec_enq(wlc, q, sdu, prec)) { | ||
6108 | /* | ||
6109 | * we might hit this condtion in case | ||
6110 | * packet flooding from mac80211 stack | ||
6111 | */ | ||
6112 | brcmu_pkt_buf_free_skb(sdu); | ||
6113 | } | ||
6114 | } | ||
6115 | |||
6116 | /* | 5721 | /* |
6117 | * bcmc_fid_generate: | 5722 | * bcmc_fid_generate: |
6118 | * Generate frame ID for a BCMC packet. The frag field is not used | 5723 | * Generate frame ID for a BCMC packet. The frag field is not used |
@@ -6140,8 +5745,6 @@ brcms_c_calc_ack_time(struct brcms_c_info *wlc, u32 rspec, | |||
6140 | { | 5745 | { |
6141 | uint dur = 0; | 5746 | uint dur = 0; |
6142 | 5747 | ||
6143 | BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d\n", | ||
6144 | wlc->pub->unit, rspec, preamble_type); | ||
6145 | /* | 5748 | /* |
6146 | * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that | 5749 | * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that |
6147 | * is less than or equal to the rate of the immediately previous | 5750 | * is less than or equal to the rate of the immediately previous |
@@ -6159,8 +5762,6 @@ static uint | |||
6159 | brcms_c_calc_cts_time(struct brcms_c_info *wlc, u32 rspec, | 5762 | brcms_c_calc_cts_time(struct brcms_c_info *wlc, u32 rspec, |
6160 | u8 preamble_type) | 5763 | u8 preamble_type) |
6161 | { | 5764 | { |
6162 | BCMMSG(wlc->wiphy, "wl%d: ratespec 0x%x, preamble_type %d\n", | ||
6163 | wlc->pub->unit, rspec, preamble_type); | ||
6164 | return brcms_c_calc_ack_time(wlc, rspec, preamble_type); | 5765 | return brcms_c_calc_ack_time(wlc, rspec, preamble_type); |
6165 | } | 5766 | } |
6166 | 5767 | ||
@@ -6168,8 +5769,6 @@ static uint | |||
6168 | brcms_c_calc_ba_time(struct brcms_c_info *wlc, u32 rspec, | 5769 | brcms_c_calc_ba_time(struct brcms_c_info *wlc, u32 rspec, |
6169 | u8 preamble_type) | 5770 | u8 preamble_type) |
6170 | { | 5771 | { |
6171 | BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, " | ||
6172 | "preamble_type %d\n", wlc->pub->unit, rspec, preamble_type); | ||
6173 | /* | 5772 | /* |
6174 | * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that | 5773 | * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that |
6175 | * is less than or equal to the rate of the immediately previous | 5774 | * is less than or equal to the rate of the immediately previous |
@@ -6223,9 +5822,6 @@ brcms_c_calc_frame_len(struct brcms_c_info *wlc, u32 ratespec, | |||
6223 | uint nsyms, mac_len, Ndps, kNdps; | 5822 | uint nsyms, mac_len, Ndps, kNdps; |
6224 | uint rate = rspec2rate(ratespec); | 5823 | uint rate = rspec2rate(ratespec); |
6225 | 5824 | ||
6226 | BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, dur %d\n", | ||
6227 | wlc->pub->unit, ratespec, preamble_type, dur); | ||
6228 | |||
6229 | if (is_mcs_rate(ratespec)) { | 5825 | if (is_mcs_rate(ratespec)) { |
6230 | uint mcs = ratespec & RSPEC_RATE_MASK; | 5826 | uint mcs = ratespec & RSPEC_RATE_MASK; |
6231 | int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec); | 5827 | int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec); |
@@ -6292,7 +5888,7 @@ static bool brcms_c_valid_rate(struct brcms_c_info *wlc, u32 rspec, int band, | |||
6292 | return true; | 5888 | return true; |
6293 | error: | 5889 | error: |
6294 | if (verbose) | 5890 | if (verbose) |
6295 | wiphy_err(wlc->wiphy, "wl%d: valid_rate: rate spec 0x%x " | 5891 | brcms_err(wlc->hw->d11core, "wl%d: valid_rate: rate spec 0x%x " |
6296 | "not in hw_rateset\n", wlc->pub->unit, rspec); | 5892 | "not in hw_rateset\n", wlc->pub->unit, rspec); |
6297 | 5893 | ||
6298 | return false; | 5894 | return false; |
@@ -6302,6 +5898,7 @@ static u32 | |||
6302 | mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, | 5898 | mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, |
6303 | u32 int_val) | 5899 | u32 int_val) |
6304 | { | 5900 | { |
5901 | struct bcma_device *core = wlc->hw->d11core; | ||
6305 | u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT; | 5902 | u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT; |
6306 | u8 rate = int_val & NRATE_RATE_MASK; | 5903 | u8 rate = int_val & NRATE_RATE_MASK; |
6307 | u32 rspec; | 5904 | u32 rspec; |
@@ -6318,7 +5915,7 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, | |||
6318 | if ((wlc->pub->_n_enab & SUPPORT_11N) && ismcs) { | 5915 | if ((wlc->pub->_n_enab & SUPPORT_11N) && ismcs) { |
6319 | /* mcs only allowed when nmode */ | 5916 | /* mcs only allowed when nmode */ |
6320 | if (stf > PHY_TXC1_MODE_SDM) { | 5917 | if (stf > PHY_TXC1_MODE_SDM) { |
6321 | wiphy_err(wlc->wiphy, "wl%d: %s: Invalid stf\n", | 5918 | brcms_err(core, "wl%d: %s: Invalid stf\n", |
6322 | wlc->pub->unit, __func__); | 5919 | wlc->pub->unit, __func__); |
6323 | bcmerror = -EINVAL; | 5920 | bcmerror = -EINVAL; |
6324 | goto done; | 5921 | goto done; |
@@ -6329,8 +5926,8 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, | |||
6329 | if (!CHSPEC_IS40(wlc->home_chanspec) || | 5926 | if (!CHSPEC_IS40(wlc->home_chanspec) || |
6330 | ((stf != PHY_TXC1_MODE_SISO) | 5927 | ((stf != PHY_TXC1_MODE_SISO) |
6331 | && (stf != PHY_TXC1_MODE_CDD))) { | 5928 | && (stf != PHY_TXC1_MODE_CDD))) { |
6332 | wiphy_err(wlc->wiphy, "wl%d: %s: Invalid mcs " | 5929 | brcms_err(core, "wl%d: %s: Invalid mcs 32\n", |
6333 | "32\n", wlc->pub->unit, __func__); | 5930 | wlc->pub->unit, __func__); |
6334 | bcmerror = -EINVAL; | 5931 | bcmerror = -EINVAL; |
6335 | goto done; | 5932 | goto done; |
6336 | } | 5933 | } |
@@ -6338,9 +5935,9 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, | |||
6338 | } else if (rate > HIGHEST_SINGLE_STREAM_MCS) { | 5935 | } else if (rate > HIGHEST_SINGLE_STREAM_MCS) { |
6339 | /* mcs > 7 must use stf SDM */ | 5936 | /* mcs > 7 must use stf SDM */ |
6340 | if (stf != PHY_TXC1_MODE_SDM) { | 5937 | if (stf != PHY_TXC1_MODE_SDM) { |
6341 | BCMMSG(wlc->wiphy, "wl%d: enabling " | 5938 | brcms_dbg_mac80211(core, "wl%d: enabling " |
6342 | "SDM mode for mcs %d\n", | 5939 | "SDM mode for mcs %d\n", |
6343 | wlc->pub->unit, rate); | 5940 | wlc->pub->unit, rate); |
6344 | stf = PHY_TXC1_MODE_SDM; | 5941 | stf = PHY_TXC1_MODE_SDM; |
6345 | } | 5942 | } |
6346 | } else { | 5943 | } else { |
@@ -6351,15 +5948,15 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, | |||
6351 | if ((stf > PHY_TXC1_MODE_STBC) || | 5948 | if ((stf > PHY_TXC1_MODE_STBC) || |
6352 | (!BRCMS_STBC_CAP_PHY(wlc) | 5949 | (!BRCMS_STBC_CAP_PHY(wlc) |
6353 | && (stf == PHY_TXC1_MODE_STBC))) { | 5950 | && (stf == PHY_TXC1_MODE_STBC))) { |
6354 | wiphy_err(wlc->wiphy, "wl%d: %s: Invalid STBC" | 5951 | brcms_err(core, "wl%d: %s: Invalid STBC\n", |
6355 | "\n", wlc->pub->unit, __func__); | 5952 | wlc->pub->unit, __func__); |
6356 | bcmerror = -EINVAL; | 5953 | bcmerror = -EINVAL; |
6357 | goto done; | 5954 | goto done; |
6358 | } | 5955 | } |
6359 | } | 5956 | } |
6360 | } else if (is_ofdm_rate(rate)) { | 5957 | } else if (is_ofdm_rate(rate)) { |
6361 | if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) { | 5958 | if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) { |
6362 | wiphy_err(wlc->wiphy, "wl%d: %s: Invalid OFDM\n", | 5959 | brcms_err(core, "wl%d: %s: Invalid OFDM\n", |
6363 | wlc->pub->unit, __func__); | 5960 | wlc->pub->unit, __func__); |
6364 | bcmerror = -EINVAL; | 5961 | bcmerror = -EINVAL; |
6365 | goto done; | 5962 | goto done; |
@@ -6367,20 +5964,20 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, | |||
6367 | } else if (is_cck_rate(rate)) { | 5964 | } else if (is_cck_rate(rate)) { |
6368 | if ((cur_band->bandtype != BRCM_BAND_2G) | 5965 | if ((cur_band->bandtype != BRCM_BAND_2G) |
6369 | || (stf != PHY_TXC1_MODE_SISO)) { | 5966 | || (stf != PHY_TXC1_MODE_SISO)) { |
6370 | wiphy_err(wlc->wiphy, "wl%d: %s: Invalid CCK\n", | 5967 | brcms_err(core, "wl%d: %s: Invalid CCK\n", |
6371 | wlc->pub->unit, __func__); | 5968 | wlc->pub->unit, __func__); |
6372 | bcmerror = -EINVAL; | 5969 | bcmerror = -EINVAL; |
6373 | goto done; | 5970 | goto done; |
6374 | } | 5971 | } |
6375 | } else { | 5972 | } else { |
6376 | wiphy_err(wlc->wiphy, "wl%d: %s: Unknown rate type\n", | 5973 | brcms_err(core, "wl%d: %s: Unknown rate type\n", |
6377 | wlc->pub->unit, __func__); | 5974 | wlc->pub->unit, __func__); |
6378 | bcmerror = -EINVAL; | 5975 | bcmerror = -EINVAL; |
6379 | goto done; | 5976 | goto done; |
6380 | } | 5977 | } |
6381 | /* make sure multiple antennae are available for non-siso rates */ | 5978 | /* make sure multiple antennae are available for non-siso rates */ |
6382 | if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) { | 5979 | if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) { |
6383 | wiphy_err(wlc->wiphy, "wl%d: %s: SISO antenna but !SISO " | 5980 | brcms_err(core, "wl%d: %s: SISO antenna but !SISO " |
6384 | "request\n", wlc->pub->unit, __func__); | 5981 | "request\n", wlc->pub->unit, __func__); |
6385 | bcmerror = -EINVAL; | 5982 | bcmerror = -EINVAL; |
6386 | goto done; | 5983 | goto done; |
@@ -6449,7 +6046,7 @@ static void brcms_c_cck_plcp_set(struct brcms_c_info *wlc, int rate_500, | |||
6449 | break; | 6046 | break; |
6450 | 6047 | ||
6451 | default: | 6048 | default: |
6452 | wiphy_err(wlc->wiphy, | 6049 | brcms_err(wlc->hw->d11core, |
6453 | "brcms_c_cck_plcp_set: unsupported rate %d\n", | 6050 | "brcms_c_cck_plcp_set: unsupported rate %d\n", |
6454 | rate_500); | 6051 | rate_500); |
6455 | rate_500 = BRCM_RATE_1M; | 6052 | rate_500 = BRCM_RATE_1M; |
@@ -6582,7 +6179,7 @@ static u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, u32 rspec) | |||
6582 | bw = rspec_get_bw(rspec); | 6179 | bw = rspec_get_bw(rspec); |
6583 | /* 10Mhz is not supported yet */ | 6180 | /* 10Mhz is not supported yet */ |
6584 | if (bw < PHY_TXC1_BW_20MHZ) { | 6181 | if (bw < PHY_TXC1_BW_20MHZ) { |
6585 | wiphy_err(wlc->wiphy, "phytxctl1_calc: bw %d is " | 6182 | brcms_err(wlc->hw->d11core, "phytxctl1_calc: bw %d is " |
6586 | "not supported yet, set to 20L\n", bw); | 6183 | "not supported yet, set to 20L\n", bw); |
6587 | bw = PHY_TXC1_BW_20MHZ; | 6184 | bw = PHY_TXC1_BW_20MHZ; |
6588 | } | 6185 | } |
@@ -6609,7 +6206,7 @@ static u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, u32 rspec) | |||
6609 | /* get the phyctl byte from rate phycfg table */ | 6206 | /* get the phyctl byte from rate phycfg table */ |
6610 | phycfg = brcms_c_rate_legacy_phyctl(rspec2rate(rspec)); | 6207 | phycfg = brcms_c_rate_legacy_phyctl(rspec2rate(rspec)); |
6611 | if (phycfg == -1) { | 6208 | if (phycfg == -1) { |
6612 | wiphy_err(wlc->wiphy, "phytxctl1_calc: wrong " | 6209 | brcms_err(wlc->hw->d11core, "phytxctl1_calc: wrong " |
6613 | "legacy OFDM/CCK rate\n"); | 6210 | "legacy OFDM/CCK rate\n"); |
6614 | phycfg = 0; | 6211 | phycfg = 0; |
6615 | } | 6212 | } |
@@ -6689,8 +6286,9 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, | |||
6689 | if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { | 6286 | if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { |
6690 | /* non-AP STA should never use BCMC queue */ | 6287 | /* non-AP STA should never use BCMC queue */ |
6691 | if (queue == TX_BCMC_FIFO) { | 6288 | if (queue == TX_BCMC_FIFO) { |
6692 | wiphy_err(wlc->wiphy, "wl%d: %s: ASSERT queue == " | 6289 | brcms_err(wlc->hw->d11core, |
6693 | "TX_BCMC!\n", wlc->pub->unit, __func__); | 6290 | "wl%d: %s: ASSERT queue == TX_BCMC!\n", |
6291 | wlc->pub->unit, __func__); | ||
6694 | frameid = bcmc_fid_generate(wlc, NULL, txh); | 6292 | frameid = bcmc_fid_generate(wlc, NULL, txh); |
6695 | } else { | 6293 | } else { |
6696 | /* Increment the counter for first fragment */ | 6294 | /* Increment the counter for first fragment */ |
@@ -6860,7 +6458,8 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, | |||
6860 | 6458 | ||
6861 | if ((txrate[k]->flags & IEEE80211_TX_RC_MCS) | 6459 | if ((txrate[k]->flags & IEEE80211_TX_RC_MCS) |
6862 | && (!is_mcs_rate(rspec[k]))) { | 6460 | && (!is_mcs_rate(rspec[k]))) { |
6863 | wiphy_err(wlc->wiphy, "wl%d: %s: IEEE80211_TX_" | 6461 | brcms_err(wlc->hw->d11core, |
6462 | "wl%d: %s: IEEE80211_TX_" | ||
6864 | "RC_MCS != is_mcs_rate(rspec)\n", | 6463 | "RC_MCS != is_mcs_rate(rspec)\n", |
6865 | wlc->pub->unit, __func__); | 6464 | wlc->pub->unit, __func__); |
6866 | } | 6465 | } |
@@ -7254,14 +6853,16 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, | |||
7254 | wlc->fragthresh[queue] = | 6853 | wlc->fragthresh[queue] = |
7255 | (u16) newfragthresh; | 6854 | (u16) newfragthresh; |
7256 | } else { | 6855 | } else { |
7257 | wiphy_err(wlc->wiphy, "wl%d: %s txop invalid " | 6856 | brcms_err(wlc->hw->d11core, |
6857 | "wl%d: %s txop invalid " | ||
7258 | "for rate %d\n", | 6858 | "for rate %d\n", |
7259 | wlc->pub->unit, fifo_names[queue], | 6859 | wlc->pub->unit, fifo_names[queue], |
7260 | rspec2rate(rspec[0])); | 6860 | rspec2rate(rspec[0])); |
7261 | } | 6861 | } |
7262 | 6862 | ||
7263 | if (dur > wlc->edcf_txop[ac]) | 6863 | if (dur > wlc->edcf_txop[ac]) |
7264 | wiphy_err(wlc->wiphy, "wl%d: %s: %s txop " | 6864 | brcms_err(wlc->hw->d11core, |
6865 | "wl%d: %s: %s txop " | ||
7265 | "exceeded phylen %d/%d dur %d/%d\n", | 6866 | "exceeded phylen %d/%d dur %d/%d\n", |
7266 | wlc->pub->unit, __func__, | 6867 | wlc->pub->unit, __func__, |
7267 | fifo_names[queue], | 6868 | fifo_names[queue], |
@@ -7273,79 +6874,33 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, | |||
7273 | return 0; | 6874 | return 0; |
7274 | } | 6875 | } |
7275 | 6876 | ||
7276 | void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu, | 6877 | static int brcms_c_tx(struct brcms_c_info *wlc, struct sk_buff *skb) |
7277 | struct ieee80211_hw *hw) | ||
7278 | { | 6878 | { |
7279 | u8 prio; | 6879 | struct dma_pub *dma; |
7280 | uint fifo; | 6880 | int fifo, ret = -ENOSPC; |
7281 | struct scb *scb = &wlc->pri_scb; | 6881 | struct d11txh *txh; |
7282 | struct ieee80211_hdr *d11_header = (struct ieee80211_hdr *)(sdu->data); | 6882 | u16 frameid = INVALIDFID; |
7283 | |||
7284 | /* | ||
7285 | * 802.11 standard requires management traffic | ||
7286 | * to go at highest priority | ||
7287 | */ | ||
7288 | prio = ieee80211_is_data(d11_header->frame_control) ? sdu->priority : | ||
7289 | MAXPRIO; | ||
7290 | fifo = prio2fifo[prio]; | ||
7291 | if (brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0)) | ||
7292 | return; | ||
7293 | brcms_c_txq_enq(wlc, scb, sdu, BRCMS_PRIO_TO_PREC(prio)); | ||
7294 | brcms_c_send_q(wlc); | ||
7295 | } | ||
7296 | |||
7297 | void brcms_c_send_q(struct brcms_c_info *wlc) | ||
7298 | { | ||
7299 | struct sk_buff *pkt[DOT11_MAXNUMFRAGS]; | ||
7300 | int prec; | ||
7301 | u16 prec_map; | ||
7302 | int err = 0, i, count; | ||
7303 | uint fifo; | ||
7304 | struct brcms_txq_info *qi = wlc->pkt_queue; | ||
7305 | struct pktq *q = &qi->q; | ||
7306 | struct ieee80211_tx_info *tx_info; | ||
7307 | |||
7308 | prec_map = wlc->tx_prec_map; | ||
7309 | 6883 | ||
7310 | /* Send all the enq'd pkts that we can. | 6884 | fifo = brcms_ac_to_fifo(skb_get_queue_mapping(skb)); |
7311 | * Dequeue packets with precedence with empty HW fifo only | 6885 | dma = wlc->hw->di[fifo]; |
7312 | */ | 6886 | txh = (struct d11txh *)(skb->data); |
7313 | while (prec_map && (pkt[0] = brcmu_pktq_mdeq(q, prec_map, &prec))) { | ||
7314 | tx_info = IEEE80211_SKB_CB(pkt[0]); | ||
7315 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { | ||
7316 | err = brcms_c_sendampdu(wlc->ampdu, qi, pkt, prec); | ||
7317 | } else { | ||
7318 | count = 1; | ||
7319 | err = brcms_c_prep_pdu(wlc, pkt[0], &fifo); | ||
7320 | if (!err) { | ||
7321 | for (i = 0; i < count; i++) | ||
7322 | brcms_c_txfifo(wlc, fifo, pkt[i], true, | ||
7323 | 1); | ||
7324 | } | ||
7325 | } | ||
7326 | 6887 | ||
7327 | if (err == -EBUSY) { | 6888 | if (dma->txavail == 0) { |
7328 | brcmu_pktq_penq_head(q, prec, pkt[0]); | 6889 | /* |
7329 | /* | 6890 | * We sometimes get a frame from mac80211 after stopping |
7330 | * If send failed due to any other reason than a | 6891 | * the queues. This only ever seems to be a single frame |
7331 | * change in HW FIFO condition, quit. Otherwise, | 6892 | * and is seems likely to be a race. TX_HEADROOM should |
7332 | * read the new prec_map! | 6893 | * ensure that we have enough space to handle these stray |
7333 | */ | 6894 | * packets, so warn if there isn't. If we're out of space |
7334 | if (prec_map == wlc->tx_prec_map) | 6895 | * in the tx ring and the tx queue isn't stopped then |
7335 | break; | 6896 | * we've really got a bug; warn loudly if that happens. |
7336 | prec_map = wlc->tx_prec_map; | 6897 | */ |
7337 | } | 6898 | brcms_warn(wlc->hw->d11core, |
6899 | "Received frame for tx with no space in DMA ring\n"); | ||
6900 | WARN_ON(!ieee80211_queue_stopped(wlc->pub->ieee_hw, | ||
6901 | skb_get_queue_mapping(skb))); | ||
6902 | return -ENOSPC; | ||
7338 | } | 6903 | } |
7339 | } | ||
7340 | |||
7341 | void | ||
7342 | brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p, | ||
7343 | bool commit, s8 txpktpend) | ||
7344 | { | ||
7345 | u16 frameid = INVALIDFID; | ||
7346 | struct d11txh *txh; | ||
7347 | |||
7348 | txh = (struct d11txh *) (p->data); | ||
7349 | 6904 | ||
7350 | /* When a BC/MC frame is being committed to the BCMC fifo | 6905 | /* When a BC/MC frame is being committed to the BCMC fifo |
7351 | * via DMA (NOT PIO), update ucode or BSS info as appropriate. | 6906 | * via DMA (NOT PIO), update ucode or BSS info as appropriate. |
@@ -7353,16 +6908,6 @@ brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p, | |||
7353 | if (fifo == TX_BCMC_FIFO) | 6908 | if (fifo == TX_BCMC_FIFO) |
7354 | frameid = le16_to_cpu(txh->TxFrameID); | 6909 | frameid = le16_to_cpu(txh->TxFrameID); |
7355 | 6910 | ||
7356 | /* | ||
7357 | * Bump up pending count for if not using rpc. If rpc is | ||
7358 | * used, this will be handled in brcms_b_txfifo() | ||
7359 | */ | ||
7360 | if (commit) { | ||
7361 | wlc->core->txpktpend[fifo] += txpktpend; | ||
7362 | BCMMSG(wlc->wiphy, "pktpend inc %d to %d\n", | ||
7363 | txpktpend, wlc->core->txpktpend[fifo]); | ||
7364 | } | ||
7365 | |||
7366 | /* Commit BCMC sequence number in the SHM frame ID location */ | 6911 | /* Commit BCMC sequence number in the SHM frame ID location */ |
7367 | if (frameid != INVALIDFID) { | 6912 | if (frameid != INVALIDFID) { |
7368 | /* | 6913 | /* |
@@ -7372,8 +6917,52 @@ brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p, | |||
7372 | brcms_b_write_shm(wlc->hw, M_BCMC_FID, frameid); | 6917 | brcms_b_write_shm(wlc->hw, M_BCMC_FID, frameid); |
7373 | } | 6918 | } |
7374 | 6919 | ||
7375 | if (dma_txfast(wlc->hw->di[fifo], p, commit) < 0) | 6920 | ret = brcms_c_txfifo(wlc, fifo, skb); |
6921 | /* | ||
6922 | * The only reason for brcms_c_txfifo to fail is because | ||
6923 | * there weren't any DMA descriptors, but we've already | ||
6924 | * checked for that. So if it does fail yell loudly. | ||
6925 | */ | ||
6926 | WARN_ON_ONCE(ret); | ||
6927 | |||
6928 | return ret; | ||
6929 | } | ||
6930 | |||
6931 | void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu, | ||
6932 | struct ieee80211_hw *hw) | ||
6933 | { | ||
6934 | uint fifo; | ||
6935 | struct scb *scb = &wlc->pri_scb; | ||
6936 | |||
6937 | fifo = brcms_ac_to_fifo(skb_get_queue_mapping(sdu)); | ||
6938 | if (brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0)) | ||
6939 | return; | ||
6940 | if (brcms_c_tx(wlc, sdu)) | ||
6941 | dev_kfree_skb_any(sdu); | ||
6942 | } | ||
6943 | |||
6944 | int | ||
6945 | brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p) | ||
6946 | { | ||
6947 | struct dma_pub *dma = wlc->hw->di[fifo]; | ||
6948 | int ret; | ||
6949 | u16 queue; | ||
6950 | |||
6951 | ret = dma_txfast(wlc, dma, p); | ||
6952 | if (ret < 0) | ||
7376 | wiphy_err(wlc->wiphy, "txfifo: fatal, toss frames !!!\n"); | 6953 | wiphy_err(wlc->wiphy, "txfifo: fatal, toss frames !!!\n"); |
6954 | |||
6955 | /* | ||
6956 | * Stop queue if DMA ring is full. Reserve some free descriptors, | ||
6957 | * as we sometimes receive a frame from mac80211 after the queues | ||
6958 | * are stopped. | ||
6959 | */ | ||
6960 | queue = skb_get_queue_mapping(p); | ||
6961 | if (dma->txavail <= TX_HEADROOM && fifo < TX_BCMC_FIFO && | ||
6962 | !ieee80211_queue_stopped(wlc->pub->ieee_hw, queue)) | ||
6963 | ieee80211_stop_queue(wlc->pub->ieee_hw, queue); | ||
6964 | |||
6965 | return ret; | ||
7377 | } | 6966 | } |
7378 | 6967 | ||
7379 | u32 | 6968 | u32 |
@@ -7423,19 +7012,6 @@ brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, u32 rspec, | |||
7423 | return rts_rspec; | 7012 | return rts_rspec; |
7424 | } | 7013 | } |
7425 | 7014 | ||
7426 | void | ||
7427 | brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo, s8 txpktpend) | ||
7428 | { | ||
7429 | wlc->core->txpktpend[fifo] -= txpktpend; | ||
7430 | BCMMSG(wlc->wiphy, "pktpend dec %d to %d\n", txpktpend, | ||
7431 | wlc->core->txpktpend[fifo]); | ||
7432 | |||
7433 | /* There is more room; mark precedences related to this FIFO sendable */ | ||
7434 | wlc->tx_prec_map |= wlc->fifo2prec_map[fifo]; | ||
7435 | |||
7436 | /* figure out which bsscfg is being worked on... */ | ||
7437 | } | ||
7438 | |||
7439 | /* Update beacon listen interval in shared memory */ | 7015 | /* Update beacon listen interval in shared memory */ |
7440 | static void brcms_c_bcn_li_upd(struct brcms_c_info *wlc) | 7016 | static void brcms_c_bcn_li_upd(struct brcms_c_info *wlc) |
7441 | { | 7017 | { |
@@ -7508,7 +7084,7 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh, | |||
7508 | 7084 | ||
7509 | /* fill in TSF and flag its presence */ | 7085 | /* fill in TSF and flag its presence */ |
7510 | rx_status->mactime = brcms_c_recover_tsf64(wlc, rxh); | 7086 | rx_status->mactime = brcms_c_recover_tsf64(wlc, rxh); |
7511 | rx_status->flag |= RX_FLAG_MACTIME_MPDU; | 7087 | rx_status->flag |= RX_FLAG_MACTIME_START; |
7512 | 7088 | ||
7513 | channel = BRCMS_CHAN_CHANNEL(rxh->RxChan); | 7089 | channel = BRCMS_CHAN_CHANNEL(rxh->RxChan); |
7514 | 7090 | ||
@@ -7571,7 +7147,8 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh, | |||
7571 | rx_status->rate_idx = 11; | 7147 | rx_status->rate_idx = 11; |
7572 | break; | 7148 | break; |
7573 | default: | 7149 | default: |
7574 | wiphy_err(wlc->wiphy, "%s: Unknown rate\n", __func__); | 7150 | brcms_err(wlc->hw->d11core, |
7151 | "%s: Unknown rate\n", __func__); | ||
7575 | } | 7152 | } |
7576 | 7153 | ||
7577 | /* | 7154 | /* |
@@ -7590,7 +7167,7 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh, | |||
7590 | } else if (is_ofdm_rate(rspec)) { | 7167 | } else if (is_ofdm_rate(rspec)) { |
7591 | rx_status->flag |= RX_FLAG_SHORTPRE; | 7168 | rx_status->flag |= RX_FLAG_SHORTPRE; |
7592 | } else { | 7169 | } else { |
7593 | wiphy_err(wlc->wiphy, "%s: Unknown modulation\n", | 7170 | brcms_err(wlc->hw->d11core, "%s: Unknown modulation\n", |
7594 | __func__); | 7171 | __func__); |
7595 | } | 7172 | } |
7596 | } | 7173 | } |
@@ -7600,12 +7177,12 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh, | |||
7600 | 7177 | ||
7601 | if (rxh->RxStatus1 & RXS_DECERR) { | 7178 | if (rxh->RxStatus1 & RXS_DECERR) { |
7602 | rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC; | 7179 | rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC; |
7603 | wiphy_err(wlc->wiphy, "%s: RX_FLAG_FAILED_PLCP_CRC\n", | 7180 | brcms_err(wlc->hw->d11core, "%s: RX_FLAG_FAILED_PLCP_CRC\n", |
7604 | __func__); | 7181 | __func__); |
7605 | } | 7182 | } |
7606 | if (rxh->RxStatus1 & RXS_FCSERR) { | 7183 | if (rxh->RxStatus1 & RXS_FCSERR) { |
7607 | rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; | 7184 | rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; |
7608 | wiphy_err(wlc->wiphy, "%s: RX_FLAG_FAILED_FCS_CRC\n", | 7185 | brcms_err(wlc->hw->d11core, "%s: RX_FLAG_FAILED_FCS_CRC\n", |
7609 | __func__); | 7186 | __func__); |
7610 | } | 7187 | } |
7611 | } | 7188 | } |
@@ -7649,9 +7226,6 @@ brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec, | |||
7649 | { | 7226 | { |
7650 | uint nsyms, len = 0, kNdps; | 7227 | uint nsyms, len = 0, kNdps; |
7651 | 7228 | ||
7652 | BCMMSG(wlc->wiphy, "wl%d: rate %d, len%d\n", | ||
7653 | wlc->pub->unit, rspec2rate(ratespec), mac_len); | ||
7654 | |||
7655 | if (is_mcs_rate(ratespec)) { | 7229 | if (is_mcs_rate(ratespec)) { |
7656 | uint mcs = ratespec & RSPEC_RATE_MASK; | 7230 | uint mcs = ratespec & RSPEC_RATE_MASK; |
7657 | int tot_streams = (mcs_2_txstreams(mcs) + 1) + | 7231 | int tot_streams = (mcs_2_txstreams(mcs) + 1) + |
@@ -7883,35 +7457,6 @@ void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend) | |||
7883 | brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend); | 7457 | brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend); |
7884 | } | 7458 | } |
7885 | 7459 | ||
7886 | /* prepares pdu for transmission. returns BCM error codes */ | ||
7887 | int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu, uint *fifop) | ||
7888 | { | ||
7889 | uint fifo; | ||
7890 | struct d11txh *txh; | ||
7891 | struct ieee80211_hdr *h; | ||
7892 | struct scb *scb; | ||
7893 | |||
7894 | txh = (struct d11txh *) (pdu->data); | ||
7895 | h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); | ||
7896 | |||
7897 | /* get the pkt queue info. This was put at brcms_c_sendctl or | ||
7898 | * brcms_c_send for PDU */ | ||
7899 | fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK; | ||
7900 | |||
7901 | scb = NULL; | ||
7902 | |||
7903 | *fifop = fifo; | ||
7904 | |||
7905 | /* return if insufficient dma resources */ | ||
7906 | if (*wlc->core->txavail[fifo] < MAX_DMA_SEGS) { | ||
7907 | /* Mark precedences related to this FIFO, unsendable */ | ||
7908 | /* A fifo is full. Clear precedences related to that FIFO */ | ||
7909 | wlc->tx_prec_map &= ~(wlc->fifo2prec_map[fifo]); | ||
7910 | return -EBUSY; | ||
7911 | } | ||
7912 | return 0; | ||
7913 | } | ||
7914 | |||
7915 | int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, | 7460 | int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, |
7916 | uint *blocks) | 7461 | uint *blocks) |
7917 | { | 7462 | { |
@@ -7977,13 +7522,15 @@ int brcms_c_get_curband(struct brcms_c_info *wlc) | |||
7977 | void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop) | 7522 | void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop) |
7978 | { | 7523 | { |
7979 | int timeout = 20; | 7524 | int timeout = 20; |
7525 | int i; | ||
7980 | 7526 | ||
7981 | /* flush packet queue when requested */ | 7527 | /* Kick DMA to send any pending AMPDU */ |
7982 | if (drop) | 7528 | for (i = 0; i < ARRAY_SIZE(wlc->hw->di); i++) |
7983 | brcmu_pktq_flush(&wlc->pkt_queue->q, false, NULL, NULL); | 7529 | if (wlc->hw->di[i]) |
7530 | dma_txflush(wlc->hw->di[i]); | ||
7984 | 7531 | ||
7985 | /* wait for queue and DMA fifos to run dry */ | 7532 | /* wait for queue and DMA fifos to run dry */ |
7986 | while (!pktq_empty(&wlc->pkt_queue->q) || brcms_txpktpendtot(wlc) > 0) { | 7533 | while (brcms_txpktpendtot(wlc) > 0) { |
7987 | brcms_msleep(wlc->wl, 1); | 7534 | brcms_msleep(wlc->wl, 1); |
7988 | 7535 | ||
7989 | if (--timeout == 0) | 7536 | if (--timeout == 0) |
@@ -8032,8 +7579,6 @@ static void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p) | |||
8032 | uint len; | 7579 | uint len; |
8033 | bool is_amsdu; | 7580 | bool is_amsdu; |
8034 | 7581 | ||
8035 | BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); | ||
8036 | |||
8037 | /* frame starts with rxhdr */ | 7582 | /* frame starts with rxhdr */ |
8038 | rxh = (struct d11rxhdr *) (p->data); | 7583 | rxh = (struct d11rxhdr *) (p->data); |
8039 | 7584 | ||
@@ -8043,8 +7588,9 @@ static void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p) | |||
8043 | /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */ | 7588 | /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */ |
8044 | if (rxh->RxStatus1 & RXS_PBPRES) { | 7589 | if (rxh->RxStatus1 & RXS_PBPRES) { |
8045 | if (p->len < 2) { | 7590 | if (p->len < 2) { |
8046 | wiphy_err(wlc->wiphy, "wl%d: recv: rcvd runt of " | 7591 | brcms_err(wlc->hw->d11core, |
8047 | "len %d\n", wlc->pub->unit, p->len); | 7592 | "wl%d: recv: rcvd runt of len %d\n", |
7593 | wlc->pub->unit, p->len); | ||
8048 | goto toss; | 7594 | goto toss; |
8049 | } | 7595 | } |
8050 | skb_pull(p, 2); | 7596 | skb_pull(p, 2); |
@@ -8089,7 +7635,6 @@ brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound) | |||
8089 | uint n = 0; | 7635 | uint n = 0; |
8090 | uint bound_limit = bound ? RXBND : -1; | 7636 | uint bound_limit = bound ? RXBND : -1; |
8091 | 7637 | ||
8092 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | ||
8093 | skb_queue_head_init(&recv_frames); | 7638 | skb_queue_head_init(&recv_frames); |
8094 | 7639 | ||
8095 | /* gather received frames */ | 7640 | /* gather received frames */ |
@@ -8140,10 +7685,9 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) | |||
8140 | u32 macintstatus; | 7685 | u32 macintstatus; |
8141 | struct brcms_hardware *wlc_hw = wlc->hw; | 7686 | struct brcms_hardware *wlc_hw = wlc->hw; |
8142 | struct bcma_device *core = wlc_hw->d11core; | 7687 | struct bcma_device *core = wlc_hw->d11core; |
8143 | struct wiphy *wiphy = wlc->wiphy; | ||
8144 | 7688 | ||
8145 | if (brcms_deviceremoved(wlc)) { | 7689 | if (brcms_deviceremoved(wlc)) { |
8146 | wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, | 7690 | brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, |
8147 | __func__); | 7691 | __func__); |
8148 | brcms_down(wlc->wl); | 7692 | brcms_down(wlc->wl); |
8149 | return false; | 7693 | return false; |
@@ -8153,8 +7697,8 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) | |||
8153 | macintstatus = wlc->macintstatus; | 7697 | macintstatus = wlc->macintstatus; |
8154 | wlc->macintstatus = 0; | 7698 | wlc->macintstatus = 0; |
8155 | 7699 | ||
8156 | BCMMSG(wlc->wiphy, "wl%d: macintstatus 0x%x\n", | 7700 | brcms_dbg_int(core, "wl%d: macintstatus 0x%x\n", |
8157 | wlc_hw->unit, macintstatus); | 7701 | wlc_hw->unit, macintstatus); |
8158 | 7702 | ||
8159 | WARN_ON(macintstatus & MI_PRQ); /* PRQ Interrupt in non-MBSS */ | 7703 | WARN_ON(macintstatus & MI_PRQ); /* PRQ Interrupt in non-MBSS */ |
8160 | 7704 | ||
@@ -8164,7 +7708,7 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) | |||
8164 | if (brcms_b_txstatus(wlc->hw, bounded, &fatal)) | 7708 | if (brcms_b_txstatus(wlc->hw, bounded, &fatal)) |
8165 | wlc->macintstatus |= MI_TFS; | 7709 | wlc->macintstatus |= MI_TFS; |
8166 | if (fatal) { | 7710 | if (fatal) { |
8167 | wiphy_err(wiphy, "MI_TFS: fatal\n"); | 7711 | brcms_err(core, "MI_TFS: fatal\n"); |
8168 | goto fatal; | 7712 | goto fatal; |
8169 | } | 7713 | } |
8170 | } | 7714 | } |
@@ -8174,7 +7718,7 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) | |||
8174 | 7718 | ||
8175 | /* ATIM window end */ | 7719 | /* ATIM window end */ |
8176 | if (macintstatus & MI_ATIMWINEND) { | 7720 | if (macintstatus & MI_ATIMWINEND) { |
8177 | BCMMSG(wlc->wiphy, "end of ATIM window\n"); | 7721 | brcms_dbg_info(core, "end of ATIM window\n"); |
8178 | bcma_set32(core, D11REGOFFS(maccommand), wlc->qvalid); | 7722 | bcma_set32(core, D11REGOFFS(maccommand), wlc->qvalid); |
8179 | wlc->qvalid = 0; | 7723 | wlc->qvalid = 0; |
8180 | } | 7724 | } |
@@ -8192,7 +7736,7 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) | |||
8192 | wlc_phy_noise_sample_intr(wlc_hw->band->pi); | 7736 | wlc_phy_noise_sample_intr(wlc_hw->band->pi); |
8193 | 7737 | ||
8194 | if (macintstatus & MI_GP0) { | 7738 | if (macintstatus & MI_GP0) { |
8195 | wiphy_err(wiphy, "wl%d: PSM microcode watchdog fired at %d " | 7739 | brcms_err(core, "wl%d: PSM microcode watchdog fired at %d " |
8196 | "(seconds). Resetting.\n", wlc_hw->unit, wlc_hw->now); | 7740 | "(seconds). Resetting.\n", wlc_hw->unit, wlc_hw->now); |
8197 | 7741 | ||
8198 | printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", | 7742 | printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", |
@@ -8206,15 +7750,11 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) | |||
8206 | bcma_write32(core, D11REGOFFS(gptimer), 0); | 7750 | bcma_write32(core, D11REGOFFS(gptimer), 0); |
8207 | 7751 | ||
8208 | if (macintstatus & MI_RFDISABLE) { | 7752 | if (macintstatus & MI_RFDISABLE) { |
8209 | BCMMSG(wlc->wiphy, "wl%d: BMAC Detected a change on the" | 7753 | brcms_dbg_info(core, "wl%d: BMAC Detected a change on the" |
8210 | " RF Disable Input\n", wlc_hw->unit); | 7754 | " RF Disable Input\n", wlc_hw->unit); |
8211 | brcms_rfkill_set_hw_state(wlc->wl); | 7755 | brcms_rfkill_set_hw_state(wlc->wl); |
8212 | } | 7756 | } |
8213 | 7757 | ||
8214 | /* send any enq'd tx packets. Just makes sure to jump start tx */ | ||
8215 | if (!pktq_empty(&wlc->pkt_queue->q)) | ||
8216 | brcms_c_send_q(wlc); | ||
8217 | |||
8218 | /* it isn't done and needs to be resched if macintstatus is non-zero */ | 7758 | /* it isn't done and needs to be resched if macintstatus is non-zero */ |
8219 | return wlc->macintstatus != 0; | 7759 | return wlc->macintstatus != 0; |
8220 | 7760 | ||
@@ -8229,7 +7769,7 @@ void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx) | |||
8229 | struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel; | 7769 | struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel; |
8230 | u16 chanspec; | 7770 | u16 chanspec; |
8231 | 7771 | ||
8232 | BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); | 7772 | brcms_dbg_info(core, "wl%d\n", wlc->pub->unit); |
8233 | 7773 | ||
8234 | chanspec = ch20mhz_chspec(ch->hw_value); | 7774 | chanspec = ch20mhz_chspec(ch->hw_value); |
8235 | 7775 | ||
@@ -8286,9 +7826,6 @@ void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx) | |||
8286 | bcma_set16(core, D11REGOFFS(ifs_ctl), IFS_USEEDCF); | 7826 | bcma_set16(core, D11REGOFFS(ifs_ctl), IFS_USEEDCF); |
8287 | brcms_c_edcf_setparams(wlc, false); | 7827 | brcms_c_edcf_setparams(wlc, false); |
8288 | 7828 | ||
8289 | /* Init precedence maps for empty FIFOs */ | ||
8290 | brcms_c_tx_prec_map_init(wlc); | ||
8291 | |||
8292 | /* read the ucode version if we have not yet done so */ | 7829 | /* read the ucode version if we have not yet done so */ |
8293 | if (wlc->ucode_rev == 0) { | 7830 | if (wlc->ucode_rev == 0) { |
8294 | wlc->ucode_rev = | 7831 | wlc->ucode_rev = |
@@ -8303,9 +7840,6 @@ void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx) | |||
8303 | if (mute_tx) | 7840 | if (mute_tx) |
8304 | brcms_b_mute(wlc->hw, true); | 7841 | brcms_b_mute(wlc->hw, true); |
8305 | 7842 | ||
8306 | /* clear tx flow control */ | ||
8307 | brcms_c_txflowcontrol_reset(wlc); | ||
8308 | |||
8309 | /* enable the RF Disable Delay timer */ | 7843 | /* enable the RF Disable Delay timer */ |
8310 | bcma_write32(core, D11REGOFFS(rfdisabledly), RFDISABLE_DEFAULT); | 7844 | bcma_write32(core, D11REGOFFS(rfdisabledly), RFDISABLE_DEFAULT); |
8311 | 7845 | ||
@@ -8464,15 +7998,6 @@ brcms_c_attach(struct brcms_info *wl, struct bcma_device *core, uint unit, | |||
8464 | * Complete the wlc default state initializations.. | 7998 | * Complete the wlc default state initializations.. |
8465 | */ | 7999 | */ |
8466 | 8000 | ||
8467 | /* allocate our initial queue */ | ||
8468 | wlc->pkt_queue = brcms_c_txq_alloc(wlc); | ||
8469 | if (wlc->pkt_queue == NULL) { | ||
8470 | wiphy_err(wl->wiphy, "wl%d: %s: failed to malloc tx queue\n", | ||
8471 | unit, __func__); | ||
8472 | err = 100; | ||
8473 | goto fail; | ||
8474 | } | ||
8475 | |||
8476 | wlc->bsscfg->wlc = wlc; | 8001 | wlc->bsscfg->wlc = wlc; |
8477 | 8002 | ||
8478 | wlc->mimoft = FT_HT; | 8003 | wlc->mimoft = FT_HT; |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.h b/drivers/net/wireless/brcm80211/brcmsmac/main.h index 8debc74c54e1..fb447747c2c6 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h | |||
@@ -101,9 +101,6 @@ | |||
101 | 101 | ||
102 | #define DATA_BLOCK_TX_SUPR (1 << 4) | 102 | #define DATA_BLOCK_TX_SUPR (1 << 4) |
103 | 103 | ||
104 | /* 802.1D Priority to TX FIFO number for wme */ | ||
105 | extern const u8 prio2fifo[]; | ||
106 | |||
107 | /* Ucode MCTL_WAKE override bits */ | 104 | /* Ucode MCTL_WAKE override bits */ |
108 | #define BRCMS_WAKE_OVERRIDE_CLKCTL 0x01 | 105 | #define BRCMS_WAKE_OVERRIDE_CLKCTL 0x01 |
109 | #define BRCMS_WAKE_OVERRIDE_PHYREG 0x02 | 106 | #define BRCMS_WAKE_OVERRIDE_PHYREG 0x02 |
@@ -242,7 +239,6 @@ struct brcms_core { | |||
242 | 239 | ||
243 | /* fifo */ | 240 | /* fifo */ |
244 | uint *txavail[NFIFO]; /* # tx descriptors available */ | 241 | uint *txavail[NFIFO]; /* # tx descriptors available */ |
245 | s16 txpktpend[NFIFO]; /* tx admission control */ | ||
246 | 242 | ||
247 | struct macstat *macstat_snapshot; /* mac hw prev read values */ | 243 | struct macstat *macstat_snapshot; /* mac hw prev read values */ |
248 | }; | 244 | }; |
@@ -382,19 +378,6 @@ struct brcms_hardware { | |||
382 | */ | 378 | */ |
383 | }; | 379 | }; |
384 | 380 | ||
385 | /* TX Queue information | ||
386 | * | ||
387 | * Each flow of traffic out of the device has a TX Queue with independent | ||
388 | * flow control. Several interfaces may be associated with a single TX Queue | ||
389 | * if they belong to the same flow of traffic from the device. For multi-channel | ||
390 | * operation there are independent TX Queues for each channel. | ||
391 | */ | ||
392 | struct brcms_txq_info { | ||
393 | struct brcms_txq_info *next; | ||
394 | struct pktq q; | ||
395 | uint stopped; /* tx flow control bits */ | ||
396 | }; | ||
397 | |||
398 | /* | 381 | /* |
399 | * Principal common driver data structure. | 382 | * Principal common driver data structure. |
400 | * | 383 | * |
@@ -435,11 +418,8 @@ struct brcms_txq_info { | |||
435 | * WDlast: last time wlc_watchdog() was called. | 418 | * WDlast: last time wlc_watchdog() was called. |
436 | * edcf_txop[IEEE80211_NUM_ACS]: current txop for each ac. | 419 | * edcf_txop[IEEE80211_NUM_ACS]: current txop for each ac. |
437 | * wme_retries: per-AC retry limits. | 420 | * wme_retries: per-AC retry limits. |
438 | * tx_prec_map: Precedence map based on HW FIFO space. | ||
439 | * fifo2prec_map[NFIFO]: pointer to fifo2_prec map based on WME. | ||
440 | * bsscfg: set of BSS configurations, idx 0 is default and always valid. | 421 | * bsscfg: set of BSS configurations, idx 0 is default and always valid. |
441 | * cfg: the primary bsscfg (can be AP or STA). | 422 | * cfg: the primary bsscfg (can be AP or STA). |
442 | * tx_queues: common TX Queue list. | ||
443 | * modulecb: | 423 | * modulecb: |
444 | * mimoft: SIGN or 11N. | 424 | * mimoft: SIGN or 11N. |
445 | * cck_40txbw: 11N, cck tx b/w override when in 40MHZ mode. | 425 | * cck_40txbw: 11N, cck tx b/w override when in 40MHZ mode. |
@@ -469,7 +449,6 @@ struct brcms_txq_info { | |||
469 | * tempsense_lasttime; | 449 | * tempsense_lasttime; |
470 | * tx_duty_cycle_ofdm: maximum allowed duty cycle for OFDM. | 450 | * tx_duty_cycle_ofdm: maximum allowed duty cycle for OFDM. |
471 | * tx_duty_cycle_cck: maximum allowed duty cycle for CCK. | 451 | * tx_duty_cycle_cck: maximum allowed duty cycle for CCK. |
472 | * pkt_queue: txq for transmit packets. | ||
473 | * wiphy: | 452 | * wiphy: |
474 | * pri_scb: primary Station Control Block | 453 | * pri_scb: primary Station Control Block |
475 | */ | 454 | */ |
@@ -533,14 +512,9 @@ struct brcms_c_info { | |||
533 | u16 edcf_txop[IEEE80211_NUM_ACS]; | 512 | u16 edcf_txop[IEEE80211_NUM_ACS]; |
534 | 513 | ||
535 | u16 wme_retries[IEEE80211_NUM_ACS]; | 514 | u16 wme_retries[IEEE80211_NUM_ACS]; |
536 | u16 tx_prec_map; | ||
537 | u16 fifo2prec_map[NFIFO]; | ||
538 | 515 | ||
539 | struct brcms_bss_cfg *bsscfg; | 516 | struct brcms_bss_cfg *bsscfg; |
540 | 517 | ||
541 | /* tx queue */ | ||
542 | struct brcms_txq_info *tx_queues; | ||
543 | |||
544 | struct modulecb *modulecb; | 518 | struct modulecb *modulecb; |
545 | 519 | ||
546 | u8 mimoft; | 520 | u8 mimoft; |
@@ -585,7 +559,6 @@ struct brcms_c_info { | |||
585 | u16 tx_duty_cycle_ofdm; | 559 | u16 tx_duty_cycle_ofdm; |
586 | u16 tx_duty_cycle_cck; | 560 | u16 tx_duty_cycle_cck; |
587 | 561 | ||
588 | struct brcms_txq_info *pkt_queue; | ||
589 | struct wiphy *wiphy; | 562 | struct wiphy *wiphy; |
590 | struct scb pri_scb; | 563 | struct scb pri_scb; |
591 | }; | 564 | }; |
@@ -637,30 +610,13 @@ struct brcms_bss_cfg { | |||
637 | struct brcms_bss_info *current_bss; | 610 | struct brcms_bss_info *current_bss; |
638 | }; | 611 | }; |
639 | 612 | ||
640 | extern void brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, | 613 | extern int brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, |
641 | struct sk_buff *p, | 614 | struct sk_buff *p); |
642 | bool commit, s8 txpktpend); | ||
643 | extern void brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo, | ||
644 | s8 txpktpend); | ||
645 | extern void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb, | ||
646 | struct sk_buff *sdu, uint prec); | ||
647 | extern void brcms_c_print_txstatus(struct tx_status *txs); | ||
648 | extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, | 615 | extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, |
649 | uint *blocks); | 616 | uint *blocks); |
650 | 617 | ||
651 | #if defined(DEBUG) | ||
652 | extern void brcms_c_print_txdesc(struct d11txh *txh); | ||
653 | #else | ||
654 | static inline void brcms_c_print_txdesc(struct d11txh *txh) | ||
655 | { | ||
656 | } | ||
657 | #endif | ||
658 | |||
659 | extern int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config); | 618 | extern int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config); |
660 | extern void brcms_c_mac_promisc(struct brcms_c_info *wlc, uint filter_flags); | 619 | extern void brcms_c_mac_promisc(struct brcms_c_info *wlc, uint filter_flags); |
661 | extern void brcms_c_send_q(struct brcms_c_info *wlc); | ||
662 | extern int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu, | ||
663 | uint *fifo); | ||
664 | extern u16 brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec, | 620 | extern u16 brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec, |
665 | uint mac_len); | 621 | uint mac_len); |
666 | extern u32 brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, | 622 | extern u32 brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pub.h b/drivers/net/wireless/brcm80211/brcmsmac/pub.h index 5855f4fd16dc..0148dec104f0 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h | |||
@@ -200,43 +200,6 @@ enum wlc_par_id { | |||
200 | /* WL11N Support */ | 200 | /* WL11N Support */ |
201 | #define AMPDU_AGG_HOST 1 | 201 | #define AMPDU_AGG_HOST 1 |
202 | 202 | ||
203 | /* pri is priority encoded in the packet. This maps the Packet priority to | ||
204 | * enqueue precedence as defined in wlc_prec_map | ||
205 | */ | ||
206 | extern const u8 wlc_prio2prec_map[]; | ||
207 | #define BRCMS_PRIO_TO_PREC(pri) wlc_prio2prec_map[(pri) & 7] | ||
208 | |||
209 | #define BRCMS_PREC_COUNT 16 /* Max precedence level implemented */ | ||
210 | |||
211 | /* Mask to describe all precedence levels */ | ||
212 | #define BRCMS_PREC_BMP_ALL MAXBITVAL(BRCMS_PREC_COUNT) | ||
213 | |||
214 | /* | ||
215 | * This maps priority to one precedence higher - Used by PS-Poll response | ||
216 | * packets to simulate enqueue-at-head operation, but still maintain the | ||
217 | * order on the queue | ||
218 | */ | ||
219 | #define BRCMS_PRIO_TO_HI_PREC(pri) min(BRCMS_PRIO_TO_PREC(pri) + 1,\ | ||
220 | BRCMS_PREC_COUNT - 1) | ||
221 | |||
222 | /* Define a bitmap of precedences comprised by each AC */ | ||
223 | #define BRCMS_PREC_BMP_AC_BE (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BE)) | \ | ||
224 | NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BE)) | \ | ||
225 | NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_EE)) | \ | ||
226 | NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_EE))) | ||
227 | #define BRCMS_PREC_BMP_AC_BK (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BK)) | \ | ||
228 | NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BK)) | \ | ||
229 | NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NONE)) | \ | ||
230 | NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NONE))) | ||
231 | #define BRCMS_PREC_BMP_AC_VI (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_CL)) | \ | ||
232 | NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_CL)) | \ | ||
233 | NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VI)) | \ | ||
234 | NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VI))) | ||
235 | #define BRCMS_PREC_BMP_AC_VO (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VO)) | \ | ||
236 | NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VO)) | \ | ||
237 | NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NC)) | \ | ||
238 | NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NC))) | ||
239 | |||
240 | /* network protection config */ | 203 | /* network protection config */ |
241 | #define BRCMS_PROT_G_SPEC 1 /* SPEC g protection */ | 204 | #define BRCMS_PROT_G_SPEC 1 /* SPEC g protection */ |
242 | #define BRCMS_PROT_G_OVR 2 /* SPEC g prot override */ | 205 | #define BRCMS_PROT_G_OVR 2 /* SPEC g prot override */ |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/stf.c b/drivers/net/wireless/brcm80211/brcmsmac/stf.c index ed1d1aa71d2d..dd9162722495 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/stf.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/stf.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include "channel.h" | 23 | #include "channel.h" |
24 | #include "main.h" | 24 | #include "main.h" |
25 | #include "stf.h" | 25 | #include "stf.h" |
26 | #include "debug.h" | ||
26 | 27 | ||
27 | #define MIN_SPATIAL_EXPANSION 0 | 28 | #define MIN_SPATIAL_EXPANSION 0 |
28 | #define MAX_SPATIAL_EXPANSION 1 | 29 | #define MAX_SPATIAL_EXPANSION 1 |
@@ -160,8 +161,8 @@ bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val) | |||
160 | static int brcms_c_stf_txcore_set(struct brcms_c_info *wlc, u8 Nsts, | 161 | static int brcms_c_stf_txcore_set(struct brcms_c_info *wlc, u8 Nsts, |
161 | u8 core_mask) | 162 | u8 core_mask) |
162 | { | 163 | { |
163 | BCMMSG(wlc->wiphy, "wl%d: Nsts %d core_mask %x\n", | 164 | brcms_dbg_ht(wlc->hw->d11core, "wl%d: Nsts %d core_mask %x\n", |
164 | wlc->pub->unit, Nsts, core_mask); | 165 | wlc->pub->unit, Nsts, core_mask); |
165 | 166 | ||
166 | if (hweight8(core_mask) > wlc->stf->txstreams) | 167 | if (hweight8(core_mask) > wlc->stf->txstreams) |
167 | core_mask = 0; | 168 | core_mask = 0; |
@@ -194,7 +195,8 @@ static int brcms_c_stf_spatial_policy_set(struct brcms_c_info *wlc, int val) | |||
194 | int i; | 195 | int i; |
195 | u8 core_mask = 0; | 196 | u8 core_mask = 0; |
196 | 197 | ||
197 | BCMMSG(wlc->wiphy, "wl%d: val %x\n", wlc->pub->unit, val); | 198 | brcms_dbg_ht(wlc->hw->d11core, "wl%d: val %x\n", wlc->pub->unit, |
199 | val); | ||
198 | 200 | ||
199 | wlc->stf->spatial_policy = (s8) val; | 201 | wlc->stf->spatial_policy = (s8) val; |
200 | for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) { | 202 | for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) { |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/types.h b/drivers/net/wireless/brcm80211/brcmsmac/types.h index e11ae83111e4..ae1f3ad40d45 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/types.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/types.h | |||
@@ -246,7 +246,7 @@ | |||
246 | 246 | ||
247 | #define BCMMSG(dev, fmt, args...) \ | 247 | #define BCMMSG(dev, fmt, args...) \ |
248 | do { \ | 248 | do { \ |
249 | if (brcm_msg_level & LOG_TRACE_VAL) \ | 249 | if (brcm_msg_level & BRCM_DL_INFO) \ |
250 | wiphy_err(dev, "%s: " fmt, __func__, ##args); \ | 250 | wiphy_err(dev, "%s: " fmt, __func__, ##args); \ |
251 | } while (0) | 251 | } while (0) |
252 | 252 | ||
@@ -281,7 +281,6 @@ struct ieee80211_tx_queue_params; | |||
281 | struct brcms_info; | 281 | struct brcms_info; |
282 | struct brcms_c_info; | 282 | struct brcms_c_info; |
283 | struct brcms_hardware; | 283 | struct brcms_hardware; |
284 | struct brcms_txq_info; | ||
285 | struct brcms_band; | 284 | struct brcms_band; |
286 | struct dma_pub; | 285 | struct dma_pub; |
287 | struct si_pub; | 286 | struct si_pub; |
diff --git a/drivers/net/wireless/brcm80211/include/defs.h b/drivers/net/wireless/brcm80211/include/defs.h index f0d8c04a9c8c..fb7cbcf81179 100644 --- a/drivers/net/wireless/brcm80211/include/defs.h +++ b/drivers/net/wireless/brcm80211/include/defs.h | |||
@@ -78,9 +78,14 @@ | |||
78 | #define PM_OFF 0 | 78 | #define PM_OFF 0 |
79 | #define PM_MAX 1 | 79 | #define PM_MAX 1 |
80 | 80 | ||
81 | /* Message levels */ | 81 | /* Debug levels */ |
82 | #define LOG_ERROR_VAL 0x00000001 | 82 | #define BRCM_DL_INFO 0x00000001 |
83 | #define LOG_TRACE_VAL 0x00000002 | 83 | #define BRCM_DL_MAC80211 0x00000002 |
84 | #define BRCM_DL_RX 0x00000004 | ||
85 | #define BRCM_DL_TX 0x00000008 | ||
86 | #define BRCM_DL_INT 0x00000010 | ||
87 | #define BRCM_DL_DMA 0x00000020 | ||
88 | #define BRCM_DL_HT 0x00000040 | ||
84 | 89 | ||
85 | #define PM_OFF 0 | 90 | #define PM_OFF 0 |
86 | #define PM_MAX 1 | 91 | #define PM_MAX 1 |
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 29b8fa1adefd..46938bc9886d 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c | |||
@@ -1788,10 +1788,7 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred) | |||
1788 | } | 1788 | } |
1789 | 1789 | ||
1790 | /* Initialize the geo */ | 1790 | /* Initialize the geo */ |
1791 | if (libipw_set_geo(priv->ieee, &ipw_geos[0])) { | 1791 | libipw_set_geo(priv->ieee, &ipw_geos[0]); |
1792 | printk(KERN_WARNING DRV_NAME "Could not set geo\n"); | ||
1793 | return 0; | ||
1794 | } | ||
1795 | priv->ieee->freq_band = LIBIPW_24GHZ_BAND; | 1792 | priv->ieee->freq_band = LIBIPW_24GHZ_BAND; |
1796 | 1793 | ||
1797 | lock = LOCK_NONE; | 1794 | lock = LOCK_NONE; |
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c index 768bf612533e..482f505f3f35 100644 --- a/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/ipw2x00/ipw2200.c | |||
@@ -11269,10 +11269,31 @@ static const struct libipw_geo ipw_geos[] = { | |||
11269 | } | 11269 | } |
11270 | }; | 11270 | }; |
11271 | 11271 | ||
11272 | static void ipw_set_geo(struct ipw_priv *priv) | ||
11273 | { | ||
11274 | int j; | ||
11275 | |||
11276 | for (j = 0; j < ARRAY_SIZE(ipw_geos); j++) { | ||
11277 | if (!memcmp(&priv->eeprom[EEPROM_COUNTRY_CODE], | ||
11278 | ipw_geos[j].name, 3)) | ||
11279 | break; | ||
11280 | } | ||
11281 | |||
11282 | if (j == ARRAY_SIZE(ipw_geos)) { | ||
11283 | IPW_WARNING("SKU [%c%c%c] not recognized.\n", | ||
11284 | priv->eeprom[EEPROM_COUNTRY_CODE + 0], | ||
11285 | priv->eeprom[EEPROM_COUNTRY_CODE + 1], | ||
11286 | priv->eeprom[EEPROM_COUNTRY_CODE + 2]); | ||
11287 | j = 0; | ||
11288 | } | ||
11289 | |||
11290 | libipw_set_geo(priv->ieee, &ipw_geos[j]); | ||
11291 | } | ||
11292 | |||
11272 | #define MAX_HW_RESTARTS 5 | 11293 | #define MAX_HW_RESTARTS 5 |
11273 | static int ipw_up(struct ipw_priv *priv) | 11294 | static int ipw_up(struct ipw_priv *priv) |
11274 | { | 11295 | { |
11275 | int rc, i, j; | 11296 | int rc, i; |
11276 | 11297 | ||
11277 | /* Age scan list entries found before suspend */ | 11298 | /* Age scan list entries found before suspend */ |
11278 | if (priv->suspend_time) { | 11299 | if (priv->suspend_time) { |
@@ -11310,22 +11331,7 @@ static int ipw_up(struct ipw_priv *priv) | |||
11310 | memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN); | 11331 | memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN); |
11311 | memcpy(priv->net_dev->perm_addr, priv->mac_addr, ETH_ALEN); | 11332 | memcpy(priv->net_dev->perm_addr, priv->mac_addr, ETH_ALEN); |
11312 | 11333 | ||
11313 | for (j = 0; j < ARRAY_SIZE(ipw_geos); j++) { | 11334 | ipw_set_geo(priv); |
11314 | if (!memcmp(&priv->eeprom[EEPROM_COUNTRY_CODE], | ||
11315 | ipw_geos[j].name, 3)) | ||
11316 | break; | ||
11317 | } | ||
11318 | if (j == ARRAY_SIZE(ipw_geos)) { | ||
11319 | IPW_WARNING("SKU [%c%c%c] not recognized.\n", | ||
11320 | priv->eeprom[EEPROM_COUNTRY_CODE + 0], | ||
11321 | priv->eeprom[EEPROM_COUNTRY_CODE + 1], | ||
11322 | priv->eeprom[EEPROM_COUNTRY_CODE + 2]); | ||
11323 | j = 0; | ||
11324 | } | ||
11325 | if (libipw_set_geo(priv->ieee, &ipw_geos[j])) { | ||
11326 | IPW_WARNING("Could not set geography."); | ||
11327 | return 0; | ||
11328 | } | ||
11329 | 11335 | ||
11330 | if (priv->status & STATUS_RF_KILL_SW) { | 11336 | if (priv->status & STATUS_RF_KILL_SW) { |
11331 | IPW_WARNING("Radio disabled by module parameter.\n"); | 11337 | IPW_WARNING("Radio disabled by module parameter.\n"); |
diff --git a/drivers/net/wireless/ipw2x00/libipw.h b/drivers/net/wireless/ipw2x00/libipw.h index 0b22fb421735..6eede52ad8c0 100644 --- a/drivers/net/wireless/ipw2x00/libipw.h +++ b/drivers/net/wireless/ipw2x00/libipw.h | |||
@@ -978,7 +978,7 @@ extern void libipw_network_reset(struct libipw_network *network); | |||
978 | /* libipw_geo.c */ | 978 | /* libipw_geo.c */ |
979 | extern const struct libipw_geo *libipw_get_geo(struct libipw_device | 979 | extern const struct libipw_geo *libipw_get_geo(struct libipw_device |
980 | *ieee); | 980 | *ieee); |
981 | extern int libipw_set_geo(struct libipw_device *ieee, | 981 | extern void libipw_set_geo(struct libipw_device *ieee, |
982 | const struct libipw_geo *geo); | 982 | const struct libipw_geo *geo); |
983 | 983 | ||
984 | extern int libipw_is_valid_channel(struct libipw_device *ieee, | 984 | extern int libipw_is_valid_channel(struct libipw_device *ieee, |
diff --git a/drivers/net/wireless/ipw2x00/libipw_geo.c b/drivers/net/wireless/ipw2x00/libipw_geo.c index c9fe3c99cb00..218f2a32de21 100644 --- a/drivers/net/wireless/ipw2x00/libipw_geo.c +++ b/drivers/net/wireless/ipw2x00/libipw_geo.c | |||
@@ -132,7 +132,7 @@ u8 libipw_freq_to_channel(struct libipw_device * ieee, u32 freq) | |||
132 | return 0; | 132 | return 0; |
133 | } | 133 | } |
134 | 134 | ||
135 | int libipw_set_geo(struct libipw_device *ieee, | 135 | void libipw_set_geo(struct libipw_device *ieee, |
136 | const struct libipw_geo *geo) | 136 | const struct libipw_geo *geo) |
137 | { | 137 | { |
138 | memcpy(ieee->geo.name, geo->name, 3); | 138 | memcpy(ieee->geo.name, geo->name, 3); |
@@ -143,7 +143,6 @@ int libipw_set_geo(struct libipw_device *ieee, | |||
143 | sizeof(struct libipw_channel)); | 143 | sizeof(struct libipw_channel)); |
144 | memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels * | 144 | memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels * |
145 | sizeof(struct libipw_channel)); | 145 | sizeof(struct libipw_channel)); |
146 | return 0; | ||
147 | } | 146 | } |
148 | 147 | ||
149 | const struct libipw_geo *libipw_get_geo(struct libipw_device *ieee) | 148 | const struct libipw_geo *libipw_get_geo(struct libipw_device *ieee) |
diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c index 87e539894330..e0b9d7fa5de0 100644 --- a/drivers/net/wireless/iwlegacy/3945.c +++ b/drivers/net/wireless/iwlegacy/3945.c | |||
@@ -516,7 +516,7 @@ static void | |||
516 | il3945_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb) | 516 | il3945_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb) |
517 | { | 517 | { |
518 | struct ieee80211_hdr *header; | 518 | struct ieee80211_hdr *header; |
519 | struct ieee80211_rx_status rx_status; | 519 | struct ieee80211_rx_status rx_status = {}; |
520 | struct il_rx_pkt *pkt = rxb_addr(rxb); | 520 | struct il_rx_pkt *pkt = rxb_addr(rxb); |
521 | struct il3945_rx_frame_stats *rx_stats = IL_RX_STATS(pkt); | 521 | struct il3945_rx_frame_stats *rx_stats = IL_RX_STATS(pkt); |
522 | struct il3945_rx_frame_hdr *rx_hdr = IL_RX_HDR(pkt); | 522 | struct il3945_rx_frame_hdr *rx_hdr = IL_RX_HDR(pkt); |
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index eac4dc8bc879..07ffa575e3ef 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c | |||
@@ -613,7 +613,7 @@ void | |||
613 | il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb) | 613 | il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb) |
614 | { | 614 | { |
615 | struct ieee80211_hdr *header; | 615 | struct ieee80211_hdr *header; |
616 | struct ieee80211_rx_status rx_status; | 616 | struct ieee80211_rx_status rx_status = {}; |
617 | struct il_rx_pkt *pkt = rxb_addr(rxb); | 617 | struct il_rx_pkt *pkt = rxb_addr(rxb); |
618 | struct il_rx_phy_res *phy_res; | 618 | struct il_rx_phy_res *phy_res; |
619 | __le32 rx_pkt_status; | 619 | __le32 rx_pkt_status; |
@@ -686,7 +686,7 @@ il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb) | |||
686 | 686 | ||
687 | /* TSF isn't reliable. In order to allow smooth user experience, | 687 | /* TSF isn't reliable. In order to allow smooth user experience, |
688 | * this W/A doesn't propagate it to the mac80211 */ | 688 | * this W/A doesn't propagate it to the mac80211 */ |
689 | /*rx_status.flag |= RX_FLAG_MACTIME_MPDU; */ | 689 | /*rx_status.flag |= RX_FLAG_MACTIME_START; */ |
690 | 690 | ||
691 | il->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp); | 691 | il->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp); |
692 | 692 | ||
diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h index b4bb813362bd..e254cba4557a 100644 --- a/drivers/net/wireless/iwlegacy/common.h +++ b/drivers/net/wireless/iwlegacy/common.h | |||
@@ -2919,9 +2919,8 @@ do { \ | |||
2919 | #define IL_DBG(level, fmt, args...) \ | 2919 | #define IL_DBG(level, fmt, args...) \ |
2920 | do { \ | 2920 | do { \ |
2921 | if (il_get_debug_level(il) & level) \ | 2921 | if (il_get_debug_level(il) & level) \ |
2922 | dev_printk(KERN_ERR, &il->hw->wiphy->dev, \ | 2922 | dev_err(&il->hw->wiphy->dev, "%c %s " fmt, \ |
2923 | "%c %s " fmt, in_interrupt() ? 'I' : 'U', \ | 2923 | in_interrupt() ? 'I' : 'U', __func__ , ##args); \ |
2924 | __func__ , ## args); \ | ||
2925 | } while (0) | 2924 | } while (0) |
2926 | 2925 | ||
2927 | #define il_print_hex_dump(il, level, p, len) \ | 2926 | #define il_print_hex_dump(il, level, p, len) \ |
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index 727fbb5db9da..5cf43236421e 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig | |||
@@ -133,12 +133,3 @@ config IWLWIFI_P2P | |||
133 | support when it is loaded. | 133 | support when it is loaded. |
134 | 134 | ||
135 | Say Y only if you want to experiment with P2P. | 135 | Say Y only if you want to experiment with P2P. |
136 | |||
137 | config IWLWIFI_EXPERIMENTAL_MFP | ||
138 | bool "support MFP (802.11w) even if uCode doesn't advertise" | ||
139 | depends on IWLWIFI | ||
140 | help | ||
141 | This option enables experimental MFP (802.11W) support | ||
142 | even if the microcode doesn't advertise it. | ||
143 | |||
144 | Say Y only if you want to experiment with MFP. | ||
diff --git a/drivers/net/wireless/iwlwifi/dvm/agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h index 75e12f29d9eb..33b3ad2e546b 100644 --- a/drivers/net/wireless/iwlwifi/dvm/agn.h +++ b/drivers/net/wireless/iwlwifi/dvm/agn.h | |||
@@ -176,8 +176,8 @@ int iwlagn_hw_valid_rtc_data_addr(u32 addr); | |||
176 | /* lib */ | 176 | /* lib */ |
177 | int iwlagn_send_tx_power(struct iwl_priv *priv); | 177 | int iwlagn_send_tx_power(struct iwl_priv *priv); |
178 | void iwlagn_temperature(struct iwl_priv *priv); | 178 | void iwlagn_temperature(struct iwl_priv *priv); |
179 | int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control); | 179 | int iwlagn_txfifo_flush(struct iwl_priv *priv); |
180 | void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control); | 180 | void iwlagn_dev_txfifo_flush(struct iwl_priv *priv); |
181 | int iwlagn_send_beacon_cmd(struct iwl_priv *priv); | 181 | int iwlagn_send_beacon_cmd(struct iwl_priv *priv); |
182 | int iwl_send_statistics_request(struct iwl_priv *priv, | 182 | int iwl_send_statistics_request(struct iwl_priv *priv, |
183 | u8 flags, bool clear); | 183 | u8 flags, bool clear); |
diff --git a/drivers/net/wireless/iwlwifi/dvm/commands.h b/drivers/net/wireless/iwlwifi/dvm/commands.h index 01128c96b5d8..71ab76b2b39d 100644 --- a/drivers/net/wireless/iwlwifi/dvm/commands.h +++ b/drivers/net/wireless/iwlwifi/dvm/commands.h | |||
@@ -986,8 +986,7 @@ struct iwl_rem_sta_cmd { | |||
986 | 986 | ||
987 | #define IWL_AGG_TX_QUEUE_MSK cpu_to_le32(0xffc00) | 987 | #define IWL_AGG_TX_QUEUE_MSK cpu_to_le32(0xffc00) |
988 | 988 | ||
989 | #define IWL_DROP_SINGLE 0 | 989 | #define IWL_DROP_ALL BIT(1) |
990 | #define IWL_DROP_ALL (BIT(IWL_RXON_CTX_BSS) | BIT(IWL_RXON_CTX_PAN)) | ||
991 | 990 | ||
992 | /* | 991 | /* |
993 | * REPLY_TXFIFO_FLUSH = 0x1e(command and response) | 992 | * REPLY_TXFIFO_FLUSH = 0x1e(command and response) |
@@ -1004,14 +1003,14 @@ struct iwl_rem_sta_cmd { | |||
1004 | * the flush operation ends when both the scheduler DMA done and TXFIFO empty | 1003 | * the flush operation ends when both the scheduler DMA done and TXFIFO empty |
1005 | * are set. | 1004 | * are set. |
1006 | * | 1005 | * |
1007 | * @fifo_control: bit mask for which queues to flush | 1006 | * @queue_control: bit mask for which queues to flush |
1008 | * @flush_control: flush controls | 1007 | * @flush_control: flush controls |
1009 | * 0: Dump single MSDU | 1008 | * 0: Dump single MSDU |
1010 | * 1: Dump multiple MSDU according to PS, INVALID STA, TTL, TID disable. | 1009 | * 1: Dump multiple MSDU according to PS, INVALID STA, TTL, TID disable. |
1011 | * 2: Dump all FIFO | 1010 | * 2: Dump all FIFO |
1012 | */ | 1011 | */ |
1013 | struct iwl_txfifo_flush_cmd { | 1012 | struct iwl_txfifo_flush_cmd { |
1014 | __le32 fifo_control; | 1013 | __le32 queue_control; |
1015 | __le16 flush_control; | 1014 | __le16 flush_control; |
1016 | __le16 reserved; | 1015 | __le16 reserved; |
1017 | } __packed; | 1016 | } __packed; |
diff --git a/drivers/net/wireless/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/iwlwifi/dvm/debugfs.c index 1a98fa3ab06d..769a08bca86f 100644 --- a/drivers/net/wireless/iwlwifi/dvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/dvm/debugfs.c | |||
@@ -2101,7 +2101,7 @@ static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file, | |||
2101 | if (iwl_is_rfkill(priv)) | 2101 | if (iwl_is_rfkill(priv)) |
2102 | return -EFAULT; | 2102 | return -EFAULT; |
2103 | 2103 | ||
2104 | iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); | 2104 | iwlagn_dev_txfifo_flush(priv); |
2105 | 2105 | ||
2106 | return count; | 2106 | return count; |
2107 | } | 2107 | } |
diff --git a/drivers/net/wireless/iwlwifi/dvm/dev.h b/drivers/net/wireless/iwlwifi/dvm/dev.h index 8141f91c3725..29c571a56251 100644 --- a/drivers/net/wireless/iwlwifi/dvm/dev.h +++ b/drivers/net/wireless/iwlwifi/dvm/dev.h | |||
@@ -789,7 +789,6 @@ struct iwl_priv { | |||
789 | /* remain-on-channel offload support */ | 789 | /* remain-on-channel offload support */ |
790 | struct ieee80211_channel *hw_roc_channel; | 790 | struct ieee80211_channel *hw_roc_channel; |
791 | struct delayed_work hw_roc_disable_work; | 791 | struct delayed_work hw_roc_disable_work; |
792 | enum nl80211_channel_type hw_roc_chantype; | ||
793 | int hw_roc_duration; | 792 | int hw_roc_duration; |
794 | bool hw_roc_setup, hw_roc_start_notified; | 793 | bool hw_roc_setup, hw_roc_start_notified; |
795 | 794 | ||
diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c index bef88c1a2c9b..7e59be4b89b8 100644 --- a/drivers/net/wireless/iwlwifi/dvm/lib.c +++ b/drivers/net/wireless/iwlwifi/dvm/lib.c | |||
@@ -136,7 +136,7 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv, | |||
136 | * 1. acquire mutex before calling | 136 | * 1. acquire mutex before calling |
137 | * 2. make sure rf is on and not in exit state | 137 | * 2. make sure rf is on and not in exit state |
138 | */ | 138 | */ |
139 | int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control) | 139 | int iwlagn_txfifo_flush(struct iwl_priv *priv) |
140 | { | 140 | { |
141 | struct iwl_txfifo_flush_cmd flush_cmd; | 141 | struct iwl_txfifo_flush_cmd flush_cmd; |
142 | struct iwl_host_cmd cmd = { | 142 | struct iwl_host_cmd cmd = { |
@@ -146,35 +146,34 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control) | |||
146 | .data = { &flush_cmd, }, | 146 | .data = { &flush_cmd, }, |
147 | }; | 147 | }; |
148 | 148 | ||
149 | might_sleep(); | ||
150 | |||
151 | memset(&flush_cmd, 0, sizeof(flush_cmd)); | 149 | memset(&flush_cmd, 0, sizeof(flush_cmd)); |
152 | if (flush_control & BIT(IWL_RXON_CTX_BSS)) | 150 | |
153 | flush_cmd.fifo_control = IWL_SCD_VO_MSK | IWL_SCD_VI_MSK | | 151 | flush_cmd.queue_control = IWL_SCD_VO_MSK | IWL_SCD_VI_MSK | |
154 | IWL_SCD_BE_MSK | IWL_SCD_BK_MSK | | 152 | IWL_SCD_BE_MSK | IWL_SCD_BK_MSK | |
155 | IWL_SCD_MGMT_MSK; | 153 | IWL_SCD_MGMT_MSK; |
156 | if ((flush_control & BIT(IWL_RXON_CTX_PAN)) && | 154 | if ((priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))) |
157 | (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))) | 155 | flush_cmd.queue_control |= IWL_PAN_SCD_VO_MSK | |
158 | flush_cmd.fifo_control |= IWL_PAN_SCD_VO_MSK | | 156 | IWL_PAN_SCD_VI_MSK | |
159 | IWL_PAN_SCD_VI_MSK | IWL_PAN_SCD_BE_MSK | | 157 | IWL_PAN_SCD_BE_MSK | |
160 | IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK | | 158 | IWL_PAN_SCD_BK_MSK | |
161 | IWL_PAN_SCD_MULTICAST_MSK; | 159 | IWL_PAN_SCD_MGMT_MSK | |
160 | IWL_PAN_SCD_MULTICAST_MSK; | ||
162 | 161 | ||
163 | if (priv->eeprom_data->sku & EEPROM_SKU_CAP_11N_ENABLE) | 162 | if (priv->eeprom_data->sku & EEPROM_SKU_CAP_11N_ENABLE) |
164 | flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK; | 163 | flush_cmd.queue_control |= IWL_AGG_TX_QUEUE_MSK; |
165 | 164 | ||
166 | IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n", | 165 | IWL_DEBUG_INFO(priv, "queue control: 0x%x\n", |
167 | flush_cmd.fifo_control); | 166 | flush_cmd.queue_control); |
168 | flush_cmd.flush_control = cpu_to_le16(flush_control); | 167 | flush_cmd.flush_control = cpu_to_le16(IWL_DROP_ALL); |
169 | 168 | ||
170 | return iwl_dvm_send_cmd(priv, &cmd); | 169 | return iwl_dvm_send_cmd(priv, &cmd); |
171 | } | 170 | } |
172 | 171 | ||
173 | void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control) | 172 | void iwlagn_dev_txfifo_flush(struct iwl_priv *priv) |
174 | { | 173 | { |
175 | mutex_lock(&priv->mutex); | 174 | mutex_lock(&priv->mutex); |
176 | ieee80211_stop_queues(priv->hw); | 175 | ieee80211_stop_queues(priv->hw); |
177 | if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) { | 176 | if (iwlagn_txfifo_flush(priv)) { |
178 | IWL_ERR(priv, "flush request fail\n"); | 177 | IWL_ERR(priv, "flush request fail\n"); |
179 | goto done; | 178 | goto done; |
180 | } | 179 | } |
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index 2d9eee93c743..fb959b00b208 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c | |||
@@ -168,10 +168,13 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, | |||
168 | hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | | 168 | hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | |
169 | IEEE80211_HW_SUPPORTS_STATIC_SMPS; | 169 | IEEE80211_HW_SUPPORTS_STATIC_SMPS; |
170 | 170 | ||
171 | #ifndef CONFIG_IWLWIFI_EXPERIMENTAL_MFP | 171 | /* |
172 | /* enable 11w if the uCode advertise */ | 172 | * Enable 11w if advertised by firmware and software crypto |
173 | if (capa->flags & IWL_UCODE_TLV_FLAGS_MFP) | 173 | * is not enabled (as the firmware will interpret some mgmt |
174 | #endif /* !CONFIG_IWLWIFI_EXPERIMENTAL_MFP */ | 174 | * packets, so enabling it with software crypto isn't safe) |
175 | */ | ||
176 | if (priv->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_MFP && | ||
177 | !iwlwifi_mod_params.sw_crypto) | ||
175 | hw->flags |= IEEE80211_HW_MFP_CAPABLE; | 178 | hw->flags |= IEEE80211_HW_MFP_CAPABLE; |
176 | 179 | ||
177 | hw->sta_data_size = sizeof(struct iwl_station_priv); | 180 | hw->sta_data_size = sizeof(struct iwl_station_priv); |
@@ -1019,7 +1022,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) | |||
1019 | */ | 1022 | */ |
1020 | if (drop) { | 1023 | if (drop) { |
1021 | IWL_DEBUG_MAC80211(priv, "send flush command\n"); | 1024 | IWL_DEBUG_MAC80211(priv, "send flush command\n"); |
1022 | if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) { | 1025 | if (iwlagn_txfifo_flush(priv)) { |
1023 | IWL_ERR(priv, "flush request fail\n"); | 1026 | IWL_ERR(priv, "flush request fail\n"); |
1024 | goto done; | 1027 | goto done; |
1025 | } | 1028 | } |
@@ -1032,8 +1035,8 @@ done: | |||
1032 | } | 1035 | } |
1033 | 1036 | ||
1034 | static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw, | 1037 | static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw, |
1038 | struct ieee80211_vif *vif, | ||
1035 | struct ieee80211_channel *channel, | 1039 | struct ieee80211_channel *channel, |
1036 | enum nl80211_channel_type channel_type, | ||
1037 | int duration) | 1040 | int duration) |
1038 | { | 1041 | { |
1039 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 1042 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
@@ -1065,7 +1068,6 @@ static int iwlagn_mac_remain_on_channel(struct ieee80211_hw *hw, | |||
1065 | } | 1068 | } |
1066 | 1069 | ||
1067 | priv->hw_roc_channel = channel; | 1070 | priv->hw_roc_channel = channel; |
1068 | priv->hw_roc_chantype = channel_type; | ||
1069 | /* convert from ms to TU */ | 1071 | /* convert from ms to TU */ |
1070 | priv->hw_roc_duration = DIV_ROUND_UP(1000 * duration, 1024); | 1072 | priv->hw_roc_duration = DIV_ROUND_UP(1000 * duration, 1024); |
1071 | priv->hw_roc_start_notified = false; | 1073 | priv->hw_roc_start_notified = false; |
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c index 30e761d31e98..e3a07c916812 100644 --- a/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c | |||
@@ -511,7 +511,7 @@ static void iwl_bg_tx_flush(struct work_struct *work) | |||
511 | return; | 511 | return; |
512 | 512 | ||
513 | IWL_DEBUG_INFO(priv, "device request: flush all tx frames\n"); | 513 | IWL_DEBUG_INFO(priv, "device request: flush all tx frames\n"); |
514 | iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); | 514 | iwlagn_dev_txfifo_flush(priv); |
515 | } | 515 | } |
516 | 516 | ||
517 | /* | 517 | /* |
@@ -1191,8 +1191,6 @@ static void iwl_option_config(struct iwl_priv *priv) | |||
1191 | 1191 | ||
1192 | static int iwl_eeprom_init_hw_params(struct iwl_priv *priv) | 1192 | static int iwl_eeprom_init_hw_params(struct iwl_priv *priv) |
1193 | { | 1193 | { |
1194 | priv->eeprom_data->sku = priv->eeprom_data->sku; | ||
1195 | |||
1196 | if (priv->eeprom_data->sku & EEPROM_SKU_CAP_11N_ENABLE && | 1194 | if (priv->eeprom_data->sku & EEPROM_SKU_CAP_11N_ENABLE && |
1197 | !priv->cfg->ht_params) { | 1195 | !priv->cfg->ht_params) { |
1198 | IWL_ERR(priv, "Invalid 11n configuration\n"); | 1196 | IWL_ERR(priv, "Invalid 11n configuration\n"); |
@@ -1204,7 +1202,7 @@ static int iwl_eeprom_init_hw_params(struct iwl_priv *priv) | |||
1204 | return -EINVAL; | 1202 | return -EINVAL; |
1205 | } | 1203 | } |
1206 | 1204 | ||
1207 | IWL_INFO(priv, "Device SKU: 0x%X\n", priv->eeprom_data->sku); | 1205 | IWL_DEBUG_INFO(priv, "Device SKU: 0x%X\n", priv->eeprom_data->sku); |
1208 | 1206 | ||
1209 | priv->hw_params.tx_chains_num = | 1207 | priv->hw_params.tx_chains_num = |
1210 | num_of_ant(priv->eeprom_data->valid_tx_ant); | 1208 | num_of_ant(priv->eeprom_data->valid_tx_ant); |
@@ -1214,9 +1212,9 @@ static int iwl_eeprom_init_hw_params(struct iwl_priv *priv) | |||
1214 | priv->hw_params.rx_chains_num = | 1212 | priv->hw_params.rx_chains_num = |
1215 | num_of_ant(priv->eeprom_data->valid_rx_ant); | 1213 | num_of_ant(priv->eeprom_data->valid_rx_ant); |
1216 | 1214 | ||
1217 | IWL_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n", | 1215 | IWL_DEBUG_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n", |
1218 | priv->eeprom_data->valid_tx_ant, | 1216 | priv->eeprom_data->valid_tx_ant, |
1219 | priv->eeprom_data->valid_rx_ant); | 1217 | priv->eeprom_data->valid_rx_ant); |
1220 | 1218 | ||
1221 | return 0; | 1219 | return 0; |
1222 | } | 1220 | } |
@@ -1231,7 +1229,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, | |||
1231 | struct iwl_op_mode *op_mode; | 1229 | struct iwl_op_mode *op_mode; |
1232 | u16 num_mac; | 1230 | u16 num_mac; |
1233 | u32 ucode_flags; | 1231 | u32 ucode_flags; |
1234 | struct iwl_trans_config trans_cfg; | 1232 | struct iwl_trans_config trans_cfg = {}; |
1235 | static const u8 no_reclaim_cmds[] = { | 1233 | static const u8 no_reclaim_cmds[] = { |
1236 | REPLY_RX_PHY_CMD, | 1234 | REPLY_RX_PHY_CMD, |
1237 | REPLY_RX_MPDU_CMD, | 1235 | REPLY_RX_MPDU_CMD, |
@@ -1507,10 +1505,6 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) | |||
1507 | 1505 | ||
1508 | iwl_tt_exit(priv); | 1506 | iwl_tt_exit(priv); |
1509 | 1507 | ||
1510 | /*This will stop the queues, move the device to low power state */ | ||
1511 | priv->ucode_loaded = false; | ||
1512 | iwl_trans_stop_device(priv->trans); | ||
1513 | |||
1514 | kfree(priv->eeprom_blob); | 1508 | kfree(priv->eeprom_blob); |
1515 | iwl_free_eeprom_data(priv->eeprom_data); | 1509 | iwl_free_eeprom_data(priv->eeprom_data); |
1516 | 1510 | ||
@@ -1926,8 +1920,6 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) | |||
1926 | * commands by clearing the ready bit */ | 1920 | * commands by clearing the ready bit */ |
1927 | clear_bit(STATUS_READY, &priv->status); | 1921 | clear_bit(STATUS_READY, &priv->status); |
1928 | 1922 | ||
1929 | wake_up(&priv->trans->wait_command_queue); | ||
1930 | |||
1931 | if (!ondemand) { | 1923 | if (!ondemand) { |
1932 | /* | 1924 | /* |
1933 | * If firmware keep reloading, then it indicate something | 1925 | * If firmware keep reloading, then it indicate something |
diff --git a/drivers/net/wireless/iwlwifi/dvm/rx.c b/drivers/net/wireless/iwlwifi/dvm/rx.c index 5a9c325804f6..cac4f37cc427 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rx.c +++ b/drivers/net/wireless/iwlwifi/dvm/rx.c | |||
@@ -631,8 +631,6 @@ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv, | |||
631 | test_bit(STATUS_RF_KILL_HW, &priv->status))) | 631 | test_bit(STATUS_RF_KILL_HW, &priv->status))) |
632 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, | 632 | wiphy_rfkill_set_hw_state(priv->hw->wiphy, |
633 | test_bit(STATUS_RF_KILL_HW, &priv->status)); | 633 | test_bit(STATUS_RF_KILL_HW, &priv->status)); |
634 | else | ||
635 | wake_up(&priv->trans->wait_command_queue); | ||
636 | return 0; | 634 | return 0; |
637 | } | 635 | } |
638 | 636 | ||
@@ -901,7 +899,7 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv, | |||
901 | struct iwl_device_cmd *cmd) | 899 | struct iwl_device_cmd *cmd) |
902 | { | 900 | { |
903 | struct ieee80211_hdr *header; | 901 | struct ieee80211_hdr *header; |
904 | struct ieee80211_rx_status rx_status; | 902 | struct ieee80211_rx_status rx_status = {}; |
905 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 903 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
906 | struct iwl_rx_phy_res *phy_res; | 904 | struct iwl_rx_phy_res *phy_res; |
907 | __le32 rx_pkt_status; | 905 | __le32 rx_pkt_status; |
@@ -951,7 +949,7 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv, | |||
951 | 949 | ||
952 | /* TSF isn't reliable. In order to allow smooth user experience, | 950 | /* TSF isn't reliable. In order to allow smooth user experience, |
953 | * this W/A doesn't propagate it to the mac80211 */ | 951 | * this W/A doesn't propagate it to the mac80211 */ |
954 | /*rx_status.flag |= RX_FLAG_MACTIME_MPDU;*/ | 952 | /*rx_status.flag |= RX_FLAG_MACTIME_START;*/ |
955 | 953 | ||
956 | priv->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp); | 954 | priv->ucode_beacon_time = le32_to_cpu(phy_res->beacon_time_stamp); |
957 | 955 | ||
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index f5ca73a89870..4ae031f6726b 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c | |||
@@ -1075,14 +1075,11 @@ static void iwlagn_count_tx_err_status(struct iwl_priv *priv, u16 status) | |||
1075 | 1075 | ||
1076 | static void iwlagn_set_tx_status(struct iwl_priv *priv, | 1076 | static void iwlagn_set_tx_status(struct iwl_priv *priv, |
1077 | struct ieee80211_tx_info *info, | 1077 | struct ieee80211_tx_info *info, |
1078 | struct iwlagn_tx_resp *tx_resp, | 1078 | struct iwlagn_tx_resp *tx_resp) |
1079 | bool is_agg) | ||
1080 | { | 1079 | { |
1081 | u16 status = le16_to_cpu(tx_resp->status.status); | 1080 | u16 status = le16_to_cpu(tx_resp->status.status); |
1082 | 1081 | ||
1083 | info->status.rates[0].count = tx_resp->failure_frame + 1; | 1082 | info->status.rates[0].count = tx_resp->failure_frame + 1; |
1084 | if (is_agg) | ||
1085 | info->flags &= ~IEEE80211_TX_CTL_AMPDU; | ||
1086 | info->flags |= iwl_tx_status_to_mac80211(status); | 1083 | info->flags |= iwl_tx_status_to_mac80211(status); |
1087 | iwlagn_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags), | 1084 | iwlagn_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags), |
1088 | info); | 1085 | info); |
@@ -1231,7 +1228,7 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, | |||
1231 | if (is_agg && !iwl_is_tx_success(status)) | 1228 | if (is_agg && !iwl_is_tx_success(status)) |
1232 | info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; | 1229 | info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; |
1233 | iwlagn_set_tx_status(priv, IEEE80211_SKB_CB(skb), | 1230 | iwlagn_set_tx_status(priv, IEEE80211_SKB_CB(skb), |
1234 | tx_resp, is_agg); | 1231 | tx_resp); |
1235 | if (!is_agg) | 1232 | if (!is_agg) |
1236 | iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1); | 1233 | iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1); |
1237 | 1234 | ||
diff --git a/drivers/net/wireless/iwlwifi/dvm/ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c index 2cb1efbc5ed1..95e6d33f5159 100644 --- a/drivers/net/wireless/iwlwifi/dvm/ucode.c +++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c | |||
@@ -254,7 +254,7 @@ static int iwl_alive_notify(struct iwl_priv *priv) | |||
254 | int ret; | 254 | int ret; |
255 | int i; | 255 | int i; |
256 | 256 | ||
257 | iwl_trans_fw_alive(priv->trans); | 257 | iwl_trans_fw_alive(priv->trans, 0); |
258 | 258 | ||
259 | if (priv->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN && | 259 | if (priv->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN && |
260 | priv->eeprom_data->sku & EEPROM_SKU_CAP_IPAN_ENABLE) { | 260 | priv->eeprom_data->sku & EEPROM_SKU_CAP_IPAN_ENABLE) { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h index 87f465a49df1..196266aa5a9d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/iwlwifi/iwl-config.h | |||
@@ -150,7 +150,7 @@ enum iwl_led_mode { | |||
150 | struct iwl_base_params { | 150 | struct iwl_base_params { |
151 | int eeprom_size; | 151 | int eeprom_size; |
152 | int num_of_queues; /* def: HW dependent */ | 152 | int num_of_queues; /* def: HW dependent */ |
153 | /* for iwl_apm_init() */ | 153 | /* for iwl_pcie_apm_init() */ |
154 | u32 pll_cfg_val; | 154 | u32 pll_cfg_val; |
155 | 155 | ||
156 | const u16 max_ll_items; | 156 | const u16 max_ll_items; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index 678717bf62eb..b3fde5f7b9bc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h | |||
@@ -306,7 +306,7 @@ TRACE_EVENT(iwlwifi_dev_rx_data, | |||
306 | memcpy(__get_dynamic_array(data), | 306 | memcpy(__get_dynamic_array(data), |
307 | ((u8 *)rxbuf) + offs, len - offs); | 307 | ((u8 *)rxbuf) + offs, len - offs); |
308 | ), | 308 | ), |
309 | TP_printk("[%s] TX frame data", __get_str(dev)) | 309 | TP_printk("[%s] RX frame data", __get_str(dev)) |
310 | ); | 310 | ); |
311 | 311 | ||
312 | #undef TRACE_SYSTEM | 312 | #undef TRACE_SYSTEM |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c index f10170fe8799..4a9dc9629efe 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c | |||
@@ -889,8 +889,8 @@ int iwl_eeprom_check_version(struct iwl_eeprom_data *data, | |||
889 | { | 889 | { |
890 | if (data->eeprom_version >= trans->cfg->eeprom_ver || | 890 | if (data->eeprom_version >= trans->cfg->eeprom_ver || |
891 | data->calib_version >= trans->cfg->eeprom_calib_ver) { | 891 | data->calib_version >= trans->cfg->eeprom_calib_ver) { |
892 | IWL_INFO(trans, "device EEPROM VER=0x%x, CALIB=0x%x\n", | 892 | IWL_DEBUG_INFO(trans, "device EEPROM VER=0x%x, CALIB=0x%x\n", |
893 | data->eeprom_version, data->calib_version); | 893 | data->eeprom_version, data->calib_version); |
894 | return 0; | 894 | return 0; |
895 | } | 895 | } |
896 | 896 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index 806046641747..ec48563d3c6a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h | |||
@@ -267,7 +267,7 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl) | |||
267 | 267 | ||
268 | #define FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS (20) | 268 | #define FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS (20) |
269 | #define FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS (4) | 269 | #define FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS (4) |
270 | #define RX_RB_TIMEOUT (0x10) | 270 | #define RX_RB_TIMEOUT (0x11) |
271 | 271 | ||
272 | #define FH_RCSR_RX_CONFIG_CHNL_EN_PAUSE_VAL (0x00000000) | 272 | #define FH_RCSR_RX_CONFIG_CHNL_EN_PAUSE_VAL (0x00000000) |
273 | #define FH_RCSR_RX_CONFIG_CHNL_EN_PAUSE_EOF_VAL (0x40000000) | 273 | #define FH_RCSR_RX_CONFIG_CHNL_EN_PAUSE_EOF_VAL (0x40000000) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index f75ea6d73ffc..e378ea6dca9c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
@@ -221,14 +221,21 @@ struct iwl_device_cmd { | |||
221 | /** | 221 | /** |
222 | * struct iwl_hcmd_dataflag - flag for each one of the chunks of the command | 222 | * struct iwl_hcmd_dataflag - flag for each one of the chunks of the command |
223 | * | 223 | * |
224 | * IWL_HCMD_DFL_NOCOPY: By default, the command is copied to the host command's | 224 | * @IWL_HCMD_DFL_NOCOPY: By default, the command is copied to the host command's |
225 | * ring. The transport layer doesn't map the command's buffer to DMA, but | 225 | * ring. The transport layer doesn't map the command's buffer to DMA, but |
226 | * rather copies it to an previously allocated DMA buffer. This flag tells | 226 | * rather copies it to an previously allocated DMA buffer. This flag tells |
227 | * the transport layer not to copy the command, but to map the existing | 227 | * the transport layer not to copy the command, but to map the existing |
228 | * buffer. This can save memcpy and is worth with very big comamnds. | 228 | * buffer (that is passed in) instead. This saves the memcpy and allows |
229 | * commands that are bigger than the fixed buffer to be submitted. | ||
230 | * Note that a TFD entry after a NOCOPY one cannot be a normal copied one. | ||
231 | * @IWL_HCMD_DFL_DUP: Only valid without NOCOPY, duplicate the memory for this | ||
232 | * chunk internally and free it again after the command completes. This | ||
233 | * can (currently) be used only once per command. | ||
234 | * Note that a TFD entry after a DUP one cannot be a normal copied one. | ||
229 | */ | 235 | */ |
230 | enum iwl_hcmd_dataflag { | 236 | enum iwl_hcmd_dataflag { |
231 | IWL_HCMD_DFL_NOCOPY = BIT(0), | 237 | IWL_HCMD_DFL_NOCOPY = BIT(0), |
238 | IWL_HCMD_DFL_DUP = BIT(1), | ||
232 | }; | 239 | }; |
233 | 240 | ||
234 | /** | 241 | /** |
@@ -348,14 +355,17 @@ struct iwl_trans; | |||
348 | * @start_fw: allocates and inits all the resources for the transport | 355 | * @start_fw: allocates and inits all the resources for the transport |
349 | * layer. Also kick a fw image. | 356 | * layer. Also kick a fw image. |
350 | * May sleep | 357 | * May sleep |
351 | * @fw_alive: called when the fw sends alive notification | 358 | * @fw_alive: called when the fw sends alive notification. If the fw provides |
359 | * the SCD base address in SRAM, then provide it here, or 0 otherwise. | ||
352 | * May sleep | 360 | * May sleep |
353 | * @stop_device:stops the whole device (embedded CPU put to reset) | 361 | * @stop_device:stops the whole device (embedded CPU put to reset) |
354 | * May sleep | 362 | * May sleep |
355 | * @wowlan_suspend: put the device into the correct mode for WoWLAN during | 363 | * @wowlan_suspend: put the device into the correct mode for WoWLAN during |
356 | * suspend. This is optional, if not implemented WoWLAN will not be | 364 | * suspend. This is optional, if not implemented WoWLAN will not be |
357 | * supported. This callback may sleep. | 365 | * supported. This callback may sleep. |
358 | * @send_cmd:send a host command | 366 | * @send_cmd:send a host command. Must return -ERFKILL if RFkill is asserted. |
367 | * If RFkill is asserted in the middle of a SYNC host command, it must | ||
368 | * return -ERFKILL straight away. | ||
359 | * May sleep only if CMD_SYNC is set | 369 | * May sleep only if CMD_SYNC is set |
360 | * @tx: send an skb | 370 | * @tx: send an skb |
361 | * Must be atomic | 371 | * Must be atomic |
@@ -385,7 +395,7 @@ struct iwl_trans_ops { | |||
385 | int (*start_hw)(struct iwl_trans *iwl_trans); | 395 | int (*start_hw)(struct iwl_trans *iwl_trans); |
386 | void (*stop_hw)(struct iwl_trans *iwl_trans, bool op_mode_leaving); | 396 | void (*stop_hw)(struct iwl_trans *iwl_trans, bool op_mode_leaving); |
387 | int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw); | 397 | int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw); |
388 | void (*fw_alive)(struct iwl_trans *trans); | 398 | void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr); |
389 | void (*stop_device)(struct iwl_trans *trans); | 399 | void (*stop_device)(struct iwl_trans *trans); |
390 | 400 | ||
391 | void (*wowlan_suspend)(struct iwl_trans *trans); | 401 | void (*wowlan_suspend)(struct iwl_trans *trans); |
@@ -438,7 +448,6 @@ enum iwl_trans_state { | |||
438 | * Set during transport allocation. | 448 | * Set during transport allocation. |
439 | * @hw_id_str: a string with info about HW ID. Set during transport allocation. | 449 | * @hw_id_str: a string with info about HW ID. Set during transport allocation. |
440 | * @pm_support: set to true in start_hw if link pm is supported | 450 | * @pm_support: set to true in start_hw if link pm is supported |
441 | * @wait_command_queue: the wait_queue for SYNC host commands | ||
442 | * @dev_cmd_pool: pool for Tx cmd allocation - for internal use only. | 451 | * @dev_cmd_pool: pool for Tx cmd allocation - for internal use only. |
443 | * The user should use iwl_trans_{alloc,free}_tx_cmd. | 452 | * The user should use iwl_trans_{alloc,free}_tx_cmd. |
444 | * @dev_cmd_headroom: room needed for the transport's private use before the | 453 | * @dev_cmd_headroom: room needed for the transport's private use before the |
@@ -465,8 +474,6 @@ struct iwl_trans { | |||
465 | 474 | ||
466 | bool pm_support; | 475 | bool pm_support; |
467 | 476 | ||
468 | wait_queue_head_t wait_command_queue; | ||
469 | |||
470 | /* The following fields are internal only */ | 477 | /* The following fields are internal only */ |
471 | struct kmem_cache *dev_cmd_pool; | 478 | struct kmem_cache *dev_cmd_pool; |
472 | size_t dev_cmd_headroom; | 479 | size_t dev_cmd_headroom; |
@@ -508,13 +515,13 @@ static inline void iwl_trans_stop_hw(struct iwl_trans *trans, | |||
508 | trans->state = IWL_TRANS_NO_FW; | 515 | trans->state = IWL_TRANS_NO_FW; |
509 | } | 516 | } |
510 | 517 | ||
511 | static inline void iwl_trans_fw_alive(struct iwl_trans *trans) | 518 | static inline void iwl_trans_fw_alive(struct iwl_trans *trans, u32 scd_addr) |
512 | { | 519 | { |
513 | might_sleep(); | 520 | might_sleep(); |
514 | 521 | ||
515 | trans->state = IWL_TRANS_FW_ALIVE; | 522 | trans->state = IWL_TRANS_FW_ALIVE; |
516 | 523 | ||
517 | trans->ops->fw_alive(trans); | 524 | trans->ops->fw_alive(trans, scd_addr); |
518 | } | 525 | } |
519 | 526 | ||
520 | static inline int iwl_trans_start_fw(struct iwl_trans *trans, | 527 | static inline int iwl_trans_start_fw(struct iwl_trans *trans, |
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index 2a4675396707..956fe6c370bc 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c | |||
@@ -69,7 +69,6 @@ | |||
69 | 69 | ||
70 | #include "iwl-trans.h" | 70 | #include "iwl-trans.h" |
71 | #include "iwl-drv.h" | 71 | #include "iwl-drv.h" |
72 | #include "iwl-trans.h" | ||
73 | 72 | ||
74 | #include "cfg.h" | 73 | #include "cfg.h" |
75 | #include "internal.h" | 74 | #include "internal.h" |
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index 401178f44a3b..d91d2e8c62f5 100644 --- a/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h | |||
@@ -73,7 +73,7 @@ struct isr_statistics { | |||
73 | }; | 73 | }; |
74 | 74 | ||
75 | /** | 75 | /** |
76 | * struct iwl_rx_queue - Rx queue | 76 | * struct iwl_rxq - Rx queue |
77 | * @bd: driver's pointer to buffer of receive buffer descriptors (rbd) | 77 | * @bd: driver's pointer to buffer of receive buffer descriptors (rbd) |
78 | * @bd_dma: bus address of buffer of receive buffer descriptors (rbd) | 78 | * @bd_dma: bus address of buffer of receive buffer descriptors (rbd) |
79 | * @pool: | 79 | * @pool: |
@@ -91,7 +91,7 @@ struct isr_statistics { | |||
91 | * | 91 | * |
92 | * NOTE: rx_free and rx_used are used as a FIFO for iwl_rx_mem_buffers | 92 | * NOTE: rx_free and rx_used are used as a FIFO for iwl_rx_mem_buffers |
93 | */ | 93 | */ |
94 | struct iwl_rx_queue { | 94 | struct iwl_rxq { |
95 | __le32 *bd; | 95 | __le32 *bd; |
96 | dma_addr_t bd_dma; | 96 | dma_addr_t bd_dma; |
97 | struct iwl_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS]; | 97 | struct iwl_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS]; |
@@ -157,8 +157,8 @@ struct iwl_cmd_meta { | |||
157 | * 32 since we don't need so many commands pending. Since the HW | 157 | * 32 since we don't need so many commands pending. Since the HW |
158 | * still uses 256 BDs for DMA though, n_bd stays 256. As a result, | 158 | * still uses 256 BDs for DMA though, n_bd stays 256. As a result, |
159 | * the software buffers (in the variables @meta, @txb in struct | 159 | * the software buffers (in the variables @meta, @txb in struct |
160 | * iwl_tx_queue) only have 32 entries, while the HW buffers (@tfds | 160 | * iwl_txq) only have 32 entries, while the HW buffers (@tfds in |
161 | * in the same struct) have 256. | 161 | * the same struct) have 256. |
162 | * This means that we end up with the following: | 162 | * This means that we end up with the following: |
163 | * HW entries: | 0 | ... | N * 32 | ... | N * 32 + 31 | ... | 255 | | 163 | * HW entries: | 0 | ... | N * 32 | ... | N * 32 + 31 | ... | 255 | |
164 | * SW entries: | 0 | ... | 31 | | 164 | * SW entries: | 0 | ... | 31 | |
@@ -182,15 +182,17 @@ struct iwl_queue { | |||
182 | #define TFD_TX_CMD_SLOTS 256 | 182 | #define TFD_TX_CMD_SLOTS 256 |
183 | #define TFD_CMD_SLOTS 32 | 183 | #define TFD_CMD_SLOTS 32 |
184 | 184 | ||
185 | struct iwl_pcie_tx_queue_entry { | 185 | struct iwl_pcie_txq_entry { |
186 | struct iwl_device_cmd *cmd; | 186 | struct iwl_device_cmd *cmd; |
187 | struct iwl_device_cmd *copy_cmd; | 187 | struct iwl_device_cmd *copy_cmd; |
188 | struct sk_buff *skb; | 188 | struct sk_buff *skb; |
189 | /* buffer to free after command completes */ | ||
190 | const void *free_buf; | ||
189 | struct iwl_cmd_meta meta; | 191 | struct iwl_cmd_meta meta; |
190 | }; | 192 | }; |
191 | 193 | ||
192 | /** | 194 | /** |
193 | * struct iwl_tx_queue - Tx Queue for DMA | 195 | * struct iwl_txq - Tx Queue for DMA |
194 | * @q: generic Rx/Tx queue descriptor | 196 | * @q: generic Rx/Tx queue descriptor |
195 | * @tfds: transmit frame descriptors (DMA memory) | 197 | * @tfds: transmit frame descriptors (DMA memory) |
196 | * @entries: transmit entries (driver state) | 198 | * @entries: transmit entries (driver state) |
@@ -203,10 +205,10 @@ struct iwl_pcie_tx_queue_entry { | |||
203 | * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame | 205 | * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame |
204 | * descriptors) and required locking structures. | 206 | * descriptors) and required locking structures. |
205 | */ | 207 | */ |
206 | struct iwl_tx_queue { | 208 | struct iwl_txq { |
207 | struct iwl_queue q; | 209 | struct iwl_queue q; |
208 | struct iwl_tfd *tfds; | 210 | struct iwl_tfd *tfds; |
209 | struct iwl_pcie_tx_queue_entry *entries; | 211 | struct iwl_pcie_txq_entry *entries; |
210 | spinlock_t lock; | 212 | spinlock_t lock; |
211 | struct timer_list stuck_timer; | 213 | struct timer_list stuck_timer; |
212 | struct iwl_trans_pcie *trans_pcie; | 214 | struct iwl_trans_pcie *trans_pcie; |
@@ -236,7 +238,7 @@ struct iwl_tx_queue { | |||
236 | * @wd_timeout: queue watchdog timeout (jiffies) | 238 | * @wd_timeout: queue watchdog timeout (jiffies) |
237 | */ | 239 | */ |
238 | struct iwl_trans_pcie { | 240 | struct iwl_trans_pcie { |
239 | struct iwl_rx_queue rxq; | 241 | struct iwl_rxq rxq; |
240 | struct work_struct rx_replenish; | 242 | struct work_struct rx_replenish; |
241 | struct iwl_trans *trans; | 243 | struct iwl_trans *trans; |
242 | struct iwl_drv *drv; | 244 | struct iwl_drv *drv; |
@@ -258,7 +260,7 @@ struct iwl_trans_pcie { | |||
258 | struct iwl_dma_ptr scd_bc_tbls; | 260 | struct iwl_dma_ptr scd_bc_tbls; |
259 | struct iwl_dma_ptr kw; | 261 | struct iwl_dma_ptr kw; |
260 | 262 | ||
261 | struct iwl_tx_queue *txq; | 263 | struct iwl_txq *txq; |
262 | unsigned long queue_used[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)]; | 264 | unsigned long queue_used[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)]; |
263 | unsigned long queue_stopped[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)]; | 265 | unsigned long queue_stopped[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)]; |
264 | 266 | ||
@@ -268,6 +270,8 @@ struct iwl_trans_pcie { | |||
268 | 270 | ||
269 | bool ucode_write_complete; | 271 | bool ucode_write_complete; |
270 | wait_queue_head_t ucode_write_waitq; | 272 | wait_queue_head_t ucode_write_waitq; |
273 | wait_queue_head_t wait_command_queue; | ||
274 | |||
271 | unsigned long status; | 275 | unsigned long status; |
272 | u8 cmd_queue; | 276 | u8 cmd_queue; |
273 | u8 cmd_fifo; | 277 | u8 cmd_fifo; |
@@ -283,13 +287,23 @@ struct iwl_trans_pcie { | |||
283 | unsigned long wd_timeout; | 287 | unsigned long wd_timeout; |
284 | }; | 288 | }; |
285 | 289 | ||
286 | /***************************************************** | 290 | /** |
287 | * DRIVER STATUS FUNCTIONS | 291 | * enum iwl_pcie_status: status of the PCIe transport |
288 | ******************************************************/ | 292 | * @STATUS_HCMD_ACTIVE: a SYNC command is being processed |
289 | #define STATUS_HCMD_ACTIVE 0 | 293 | * @STATUS_DEVICE_ENABLED: APM is enabled |
290 | #define STATUS_DEVICE_ENABLED 1 | 294 | * @STATUS_TPOWER_PMI: the device might be asleep (need to wake it up) |
291 | #define STATUS_TPOWER_PMI 2 | 295 | * @STATUS_INT_ENABLED: interrupts are enabled |
292 | #define STATUS_INT_ENABLED 3 | 296 | * @STATUS_RFKILL: the HW RFkill switch is in KILL position |
297 | * @STATUS_FW_ERROR: the fw is in error state | ||
298 | */ | ||
299 | enum iwl_pcie_status { | ||
300 | STATUS_HCMD_ACTIVE, | ||
301 | STATUS_DEVICE_ENABLED, | ||
302 | STATUS_TPOWER_PMI, | ||
303 | STATUS_INT_ENABLED, | ||
304 | STATUS_RFKILL, | ||
305 | STATUS_FW_ERROR, | ||
306 | }; | ||
293 | 307 | ||
294 | #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ | 308 | #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ |
295 | ((struct iwl_trans_pcie *) ((_iwl_trans)->trans_specific)) | 309 | ((struct iwl_trans_pcie *) ((_iwl_trans)->trans_specific)) |
@@ -301,6 +315,10 @@ iwl_trans_pcie_get_trans(struct iwl_trans_pcie *trans_pcie) | |||
301 | trans_specific); | 315 | trans_specific); |
302 | } | 316 | } |
303 | 317 | ||
318 | /* | ||
319 | * Convention: trans API functions: iwl_trans_pcie_XXX | ||
320 | * Other functions: iwl_pcie_XXX | ||
321 | */ | ||
304 | struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | 322 | struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, |
305 | const struct pci_device_id *ent, | 323 | const struct pci_device_id *ent, |
306 | const struct iwl_cfg *cfg); | 324 | const struct iwl_cfg *cfg); |
@@ -309,50 +327,43 @@ void iwl_trans_pcie_free(struct iwl_trans *trans); | |||
309 | /***************************************************** | 327 | /***************************************************** |
310 | * RX | 328 | * RX |
311 | ******************************************************/ | 329 | ******************************************************/ |
312 | void iwl_bg_rx_replenish(struct work_struct *data); | 330 | int iwl_pcie_rx_init(struct iwl_trans *trans); |
313 | void iwl_irq_tasklet(struct iwl_trans *trans); | 331 | void iwl_pcie_tasklet(struct iwl_trans *trans); |
314 | void iwl_rx_replenish(struct iwl_trans *trans); | 332 | int iwl_pcie_rx_stop(struct iwl_trans *trans); |
315 | void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans, | 333 | void iwl_pcie_rx_free(struct iwl_trans *trans); |
316 | struct iwl_rx_queue *q); | ||
317 | 334 | ||
318 | /***************************************************** | 335 | /***************************************************** |
319 | * ICT | 336 | * ICT - interrupt handling |
320 | ******************************************************/ | 337 | ******************************************************/ |
321 | void iwl_reset_ict(struct iwl_trans *trans); | 338 | irqreturn_t iwl_pcie_isr_ict(int irq, void *data); |
322 | void iwl_disable_ict(struct iwl_trans *trans); | 339 | int iwl_pcie_alloc_ict(struct iwl_trans *trans); |
323 | int iwl_alloc_isr_ict(struct iwl_trans *trans); | 340 | void iwl_pcie_free_ict(struct iwl_trans *trans); |
324 | void iwl_free_isr_ict(struct iwl_trans *trans); | 341 | void iwl_pcie_reset_ict(struct iwl_trans *trans); |
325 | irqreturn_t iwl_isr_ict(int irq, void *data); | 342 | void iwl_pcie_disable_ict(struct iwl_trans *trans); |
326 | 343 | ||
327 | /***************************************************** | 344 | /***************************************************** |
328 | * TX / HCMD | 345 | * TX / HCMD |
329 | ******************************************************/ | 346 | ******************************************************/ |
330 | void iwl_txq_update_write_ptr(struct iwl_trans *trans, | 347 | int iwl_pcie_tx_init(struct iwl_trans *trans); |
331 | struct iwl_tx_queue *txq); | 348 | void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr); |
332 | int iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans, | 349 | int iwl_pcie_tx_stop(struct iwl_trans *trans); |
333 | struct iwl_tx_queue *txq, | 350 | void iwl_pcie_tx_free(struct iwl_trans *trans); |
334 | dma_addr_t addr, u16 len, u8 reset); | ||
335 | int iwl_queue_init(struct iwl_queue *q, int count, int slots_num, u32 id); | ||
336 | int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd); | ||
337 | void iwl_tx_cmd_complete(struct iwl_trans *trans, | ||
338 | struct iwl_rx_cmd_buffer *rxb, int handler_status); | ||
339 | void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, | ||
340 | struct iwl_tx_queue *txq, | ||
341 | u16 byte_cnt); | ||
342 | void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, | 351 | void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, |
343 | int sta_id, int tid, int frame_limit, u16 ssn); | 352 | int sta_id, int tid, int frame_limit, u16 ssn); |
344 | void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int queue); | 353 | void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int queue); |
345 | void iwl_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, | 354 | int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, |
346 | enum dma_data_direction dma_dir); | 355 | struct iwl_device_cmd *dev_cmd, int txq_id); |
347 | int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, | 356 | void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_txq *txq); |
348 | struct sk_buff_head *skbs); | 357 | int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd); |
349 | int iwl_queue_space(const struct iwl_queue *q); | 358 | void iwl_pcie_hcmd_complete(struct iwl_trans *trans, |
350 | 359 | struct iwl_rx_cmd_buffer *rxb, int handler_status); | |
360 | void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, | ||
361 | struct sk_buff_head *skbs); | ||
351 | /***************************************************** | 362 | /***************************************************** |
352 | * Error handling | 363 | * Error handling |
353 | ******************************************************/ | 364 | ******************************************************/ |
354 | int iwl_dump_fh(struct iwl_trans *trans, char **buf); | 365 | int iwl_pcie_dump_fh(struct iwl_trans *trans, char **buf); |
355 | void iwl_dump_csr(struct iwl_trans *trans); | 366 | void iwl_pcie_dump_csr(struct iwl_trans *trans); |
356 | 367 | ||
357 | /***************************************************** | 368 | /***************************************************** |
358 | * Helpers | 369 | * Helpers |
@@ -388,7 +399,7 @@ static inline void iwl_enable_rfkill_int(struct iwl_trans *trans) | |||
388 | } | 399 | } |
389 | 400 | ||
390 | static inline void iwl_wake_queue(struct iwl_trans *trans, | 401 | static inline void iwl_wake_queue(struct iwl_trans *trans, |
391 | struct iwl_tx_queue *txq) | 402 | struct iwl_txq *txq) |
392 | { | 403 | { |
393 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 404 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
394 | 405 | ||
@@ -399,7 +410,7 @@ static inline void iwl_wake_queue(struct iwl_trans *trans, | |||
399 | } | 410 | } |
400 | 411 | ||
401 | static inline void iwl_stop_queue(struct iwl_trans *trans, | 412 | static inline void iwl_stop_queue(struct iwl_trans *trans, |
402 | struct iwl_tx_queue *txq) | 413 | struct iwl_txq *txq) |
403 | { | 414 | { |
404 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 415 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
405 | 416 | ||
@@ -411,7 +422,7 @@ static inline void iwl_stop_queue(struct iwl_trans *trans, | |||
411 | txq->q.id); | 422 | txq->q.id); |
412 | } | 423 | } |
413 | 424 | ||
414 | static inline int iwl_queue_used(const struct iwl_queue *q, int i) | 425 | static inline bool iwl_queue_used(const struct iwl_queue *q, int i) |
415 | { | 426 | { |
416 | return q->write_ptr >= q->read_ptr ? | 427 | return q->write_ptr >= q->read_ptr ? |
417 | (i >= q->read_ptr && i < q->write_ptr) : | 428 | (i >= q->read_ptr && i < q->write_ptr) : |
@@ -423,8 +434,8 @@ static inline u8 get_cmd_index(struct iwl_queue *q, u32 index) | |||
423 | return index & (q->n_window - 1); | 434 | return index & (q->n_window - 1); |
424 | } | 435 | } |
425 | 436 | ||
426 | static inline const char * | 437 | static inline const char *get_cmd_string(struct iwl_trans_pcie *trans_pcie, |
427 | trans_pcie_get_cmd_string(struct iwl_trans_pcie *trans_pcie, u8 cmd) | 438 | u8 cmd) |
428 | { | 439 | { |
429 | if (!trans_pcie->command_names || !trans_pcie->command_names[cmd]) | 440 | if (!trans_pcie->command_names || !trans_pcie->command_names[cmd]) |
430 | return "UNKNOWN"; | 441 | return "UNKNOWN"; |
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index 41d821fbdb92..bb32510fdd62 100644 --- a/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c | |||
@@ -76,7 +76,7 @@ | |||
76 | * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free. When | 76 | * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free. When |
77 | * iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled | 77 | * iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled |
78 | * to replenish the iwl->rxq->rx_free. | 78 | * to replenish the iwl->rxq->rx_free. |
79 | * + In iwl_rx_replenish (scheduled) if 'processed' != 'read' then the | 79 | * + In iwl_pcie_rx_replenish (scheduled) if 'processed' != 'read' then the |
80 | * iwl->rxq is replenished and the READ INDEX is updated (updating the | 80 | * iwl->rxq is replenished and the READ INDEX is updated (updating the |
81 | * 'processed' and 'read' driver indexes as well) | 81 | * 'processed' and 'read' driver indexes as well) |
82 | * + A received packet is processed and handed to the kernel network stack, | 82 | * + A received packet is processed and handed to the kernel network stack, |
@@ -89,28 +89,28 @@ | |||
89 | * | 89 | * |
90 | * Driver sequence: | 90 | * Driver sequence: |
91 | * | 91 | * |
92 | * iwl_rx_queue_alloc() Allocates rx_free | 92 | * iwl_rxq_alloc() Allocates rx_free |
93 | * iwl_rx_replenish() Replenishes rx_free list from rx_used, and calls | 93 | * iwl_pcie_rx_replenish() Replenishes rx_free list from rx_used, and calls |
94 | * iwl_rx_queue_restock | 94 | * iwl_pcie_rxq_restock |
95 | * iwl_rx_queue_restock() Moves available buffers from rx_free into Rx | 95 | * iwl_pcie_rxq_restock() Moves available buffers from rx_free into Rx |
96 | * queue, updates firmware pointers, and updates | 96 | * queue, updates firmware pointers, and updates |
97 | * the WRITE index. If insufficient rx_free buffers | 97 | * the WRITE index. If insufficient rx_free buffers |
98 | * are available, schedules iwl_rx_replenish | 98 | * are available, schedules iwl_pcie_rx_replenish |
99 | * | 99 | * |
100 | * -- enable interrupts -- | 100 | * -- enable interrupts -- |
101 | * ISR - iwl_rx() Detach iwl_rx_mem_buffers from pool up to the | 101 | * ISR - iwl_rx() Detach iwl_rx_mem_buffers from pool up to the |
102 | * READ INDEX, detaching the SKB from the pool. | 102 | * READ INDEX, detaching the SKB from the pool. |
103 | * Moves the packet buffer from queue to rx_used. | 103 | * Moves the packet buffer from queue to rx_used. |
104 | * Calls iwl_rx_queue_restock to refill any empty | 104 | * Calls iwl_pcie_rxq_restock to refill any empty |
105 | * slots. | 105 | * slots. |
106 | * ... | 106 | * ... |
107 | * | 107 | * |
108 | */ | 108 | */ |
109 | 109 | ||
110 | /** | 110 | /* |
111 | * iwl_rx_queue_space - Return number of free slots available in queue. | 111 | * iwl_rxq_space - Return number of free slots available in queue. |
112 | */ | 112 | */ |
113 | static int iwl_rx_queue_space(const struct iwl_rx_queue *q) | 113 | static int iwl_rxq_space(const struct iwl_rxq *q) |
114 | { | 114 | { |
115 | int s = q->read - q->write; | 115 | int s = q->read - q->write; |
116 | if (s <= 0) | 116 | if (s <= 0) |
@@ -122,11 +122,28 @@ static int iwl_rx_queue_space(const struct iwl_rx_queue *q) | |||
122 | return s; | 122 | return s; |
123 | } | 123 | } |
124 | 124 | ||
125 | /** | 125 | /* |
126 | * iwl_rx_queue_update_write_ptr - Update the write pointer for the RX queue | 126 | * iwl_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr |
127 | */ | ||
128 | static inline __le32 iwl_pcie_dma_addr2rbd_ptr(dma_addr_t dma_addr) | ||
129 | { | ||
130 | return cpu_to_le32((u32)(dma_addr >> 8)); | ||
131 | } | ||
132 | |||
133 | /* | ||
134 | * iwl_pcie_rx_stop - stops the Rx DMA | ||
135 | */ | ||
136 | int iwl_pcie_rx_stop(struct iwl_trans *trans) | ||
137 | { | ||
138 | iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); | ||
139 | return iwl_poll_direct_bit(trans, FH_MEM_RSSR_RX_STATUS_REG, | ||
140 | FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | * iwl_pcie_rxq_inc_wr_ptr - Update the write pointer for the RX queue | ||
127 | */ | 145 | */ |
128 | void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans, | 146 | static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_rxq *q) |
129 | struct iwl_rx_queue *q) | ||
130 | { | 147 | { |
131 | unsigned long flags; | 148 | unsigned long flags; |
132 | u32 reg; | 149 | u32 reg; |
@@ -176,16 +193,8 @@ void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans, | |||
176 | spin_unlock_irqrestore(&q->lock, flags); | 193 | spin_unlock_irqrestore(&q->lock, flags); |
177 | } | 194 | } |
178 | 195 | ||
179 | /** | 196 | /* |
180 | * iwl_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr | 197 | * iwl_pcie_rxq_restock - refill RX queue from pre-allocated pool |
181 | */ | ||
182 | static inline __le32 iwl_dma_addr2rbd_ptr(dma_addr_t dma_addr) | ||
183 | { | ||
184 | return cpu_to_le32((u32)(dma_addr >> 8)); | ||
185 | } | ||
186 | |||
187 | /** | ||
188 | * iwl_rx_queue_restock - refill RX queue from pre-allocated pool | ||
189 | * | 198 | * |
190 | * If there are slots in the RX queue that need to be restocked, | 199 | * If there are slots in the RX queue that need to be restocked, |
191 | * and we have free pre-allocated buffers, fill the ranks as much | 200 | * and we have free pre-allocated buffers, fill the ranks as much |
@@ -195,11 +204,10 @@ static inline __le32 iwl_dma_addr2rbd_ptr(dma_addr_t dma_addr) | |||
195 | * also updates the memory address in the firmware to reference the new | 204 | * also updates the memory address in the firmware to reference the new |
196 | * target buffer. | 205 | * target buffer. |
197 | */ | 206 | */ |
198 | static void iwl_rx_queue_restock(struct iwl_trans *trans) | 207 | static void iwl_pcie_rxq_restock(struct iwl_trans *trans) |
199 | { | 208 | { |
200 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 209 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
201 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; | 210 | struct iwl_rxq *rxq = &trans_pcie->rxq; |
202 | struct list_head *element; | ||
203 | struct iwl_rx_mem_buffer *rxb; | 211 | struct iwl_rx_mem_buffer *rxb; |
204 | unsigned long flags; | 212 | unsigned long flags; |
205 | 213 | ||
@@ -215,18 +223,18 @@ static void iwl_rx_queue_restock(struct iwl_trans *trans) | |||
215 | return; | 223 | return; |
216 | 224 | ||
217 | spin_lock_irqsave(&rxq->lock, flags); | 225 | spin_lock_irqsave(&rxq->lock, flags); |
218 | while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) { | 226 | while ((iwl_rxq_space(rxq) > 0) && (rxq->free_count)) { |
219 | /* The overwritten rxb must be a used one */ | 227 | /* The overwritten rxb must be a used one */ |
220 | rxb = rxq->queue[rxq->write]; | 228 | rxb = rxq->queue[rxq->write]; |
221 | BUG_ON(rxb && rxb->page); | 229 | BUG_ON(rxb && rxb->page); |
222 | 230 | ||
223 | /* Get next free Rx buffer, remove from free list */ | 231 | /* Get next free Rx buffer, remove from free list */ |
224 | element = rxq->rx_free.next; | 232 | rxb = list_first_entry(&rxq->rx_free, struct iwl_rx_mem_buffer, |
225 | rxb = list_entry(element, struct iwl_rx_mem_buffer, list); | 233 | list); |
226 | list_del(element); | 234 | list_del(&rxb->list); |
227 | 235 | ||
228 | /* Point to Rx buffer via next RBD in circular buffer */ | 236 | /* Point to Rx buffer via next RBD in circular buffer */ |
229 | rxq->bd[rxq->write] = iwl_dma_addr2rbd_ptr(rxb->page_dma); | 237 | rxq->bd[rxq->write] = iwl_pcie_dma_addr2rbd_ptr(rxb->page_dma); |
230 | rxq->queue[rxq->write] = rxb; | 238 | rxq->queue[rxq->write] = rxb; |
231 | rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; | 239 | rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; |
232 | rxq->free_count--; | 240 | rxq->free_count--; |
@@ -243,24 +251,23 @@ static void iwl_rx_queue_restock(struct iwl_trans *trans) | |||
243 | spin_lock_irqsave(&rxq->lock, flags); | 251 | spin_lock_irqsave(&rxq->lock, flags); |
244 | rxq->need_update = 1; | 252 | rxq->need_update = 1; |
245 | spin_unlock_irqrestore(&rxq->lock, flags); | 253 | spin_unlock_irqrestore(&rxq->lock, flags); |
246 | iwl_rx_queue_update_write_ptr(trans, rxq); | 254 | iwl_pcie_rxq_inc_wr_ptr(trans, rxq); |
247 | } | 255 | } |
248 | } | 256 | } |
249 | 257 | ||
250 | /* | 258 | /* |
251 | * iwl_rx_allocate - allocate a page for each used RBD | 259 | * iwl_pcie_rxq_alloc_rbs - allocate a page for each used RBD |
252 | * | 260 | * |
253 | * A used RBD is an Rx buffer that has been given to the stack. To use it again | 261 | * A used RBD is an Rx buffer that has been given to the stack. To use it again |
254 | * a page must be allocated and the RBD must point to the page. This function | 262 | * a page must be allocated and the RBD must point to the page. This function |
255 | * doesn't change the HW pointer but handles the list of pages that is used by | 263 | * doesn't change the HW pointer but handles the list of pages that is used by |
256 | * iwl_rx_queue_restock. The latter function will update the HW to use the newly | 264 | * iwl_pcie_rxq_restock. The latter function will update the HW to use the newly |
257 | * allocated buffers. | 265 | * allocated buffers. |
258 | */ | 266 | */ |
259 | static void iwl_rx_allocate(struct iwl_trans *trans, gfp_t priority) | 267 | static void iwl_pcie_rxq_alloc_rbs(struct iwl_trans *trans, gfp_t priority) |
260 | { | 268 | { |
261 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 269 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
262 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; | 270 | struct iwl_rxq *rxq = &trans_pcie->rxq; |
263 | struct list_head *element; | ||
264 | struct iwl_rx_mem_buffer *rxb; | 271 | struct iwl_rx_mem_buffer *rxb; |
265 | struct page *page; | 272 | struct page *page; |
266 | unsigned long flags; | 273 | unsigned long flags; |
@@ -308,10 +315,9 @@ static void iwl_rx_allocate(struct iwl_trans *trans, gfp_t priority) | |||
308 | __free_pages(page, trans_pcie->rx_page_order); | 315 | __free_pages(page, trans_pcie->rx_page_order); |
309 | return; | 316 | return; |
310 | } | 317 | } |
311 | element = rxq->rx_used.next; | 318 | rxb = list_first_entry(&rxq->rx_used, struct iwl_rx_mem_buffer, |
312 | rxb = list_entry(element, struct iwl_rx_mem_buffer, list); | 319 | list); |
313 | list_del(element); | 320 | list_del(&rxb->list); |
314 | |||
315 | spin_unlock_irqrestore(&rxq->lock, flags); | 321 | spin_unlock_irqrestore(&rxq->lock, flags); |
316 | 322 | ||
317 | BUG_ON(rxb->page); | 323 | BUG_ON(rxb->page); |
@@ -343,47 +349,227 @@ static void iwl_rx_allocate(struct iwl_trans *trans, gfp_t priority) | |||
343 | } | 349 | } |
344 | } | 350 | } |
345 | 351 | ||
352 | static void iwl_pcie_rxq_free_rbs(struct iwl_trans *trans) | ||
353 | { | ||
354 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
355 | struct iwl_rxq *rxq = &trans_pcie->rxq; | ||
356 | int i; | ||
357 | |||
358 | /* Fill the rx_used queue with _all_ of the Rx buffers */ | ||
359 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { | ||
360 | /* In the reset function, these buffers may have been allocated | ||
361 | * to an SKB, so we need to unmap and free potential storage */ | ||
362 | if (rxq->pool[i].page != NULL) { | ||
363 | dma_unmap_page(trans->dev, rxq->pool[i].page_dma, | ||
364 | PAGE_SIZE << trans_pcie->rx_page_order, | ||
365 | DMA_FROM_DEVICE); | ||
366 | __free_pages(rxq->pool[i].page, | ||
367 | trans_pcie->rx_page_order); | ||
368 | rxq->pool[i].page = NULL; | ||
369 | } | ||
370 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); | ||
371 | } | ||
372 | } | ||
373 | |||
346 | /* | 374 | /* |
347 | * iwl_rx_replenish - Move all used buffers from rx_used to rx_free | 375 | * iwl_pcie_rx_replenish - Move all used buffers from rx_used to rx_free |
348 | * | 376 | * |
349 | * When moving to rx_free an page is allocated for the slot. | 377 | * When moving to rx_free an page is allocated for the slot. |
350 | * | 378 | * |
351 | * Also restock the Rx queue via iwl_rx_queue_restock. | 379 | * Also restock the Rx queue via iwl_pcie_rxq_restock. |
352 | * This is called as a scheduled work item (except for during initialization) | 380 | * This is called as a scheduled work item (except for during initialization) |
353 | */ | 381 | */ |
354 | void iwl_rx_replenish(struct iwl_trans *trans) | 382 | static void iwl_pcie_rx_replenish(struct iwl_trans *trans) |
355 | { | 383 | { |
356 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 384 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
357 | unsigned long flags; | 385 | unsigned long flags; |
358 | 386 | ||
359 | iwl_rx_allocate(trans, GFP_KERNEL); | 387 | iwl_pcie_rxq_alloc_rbs(trans, GFP_KERNEL); |
360 | 388 | ||
361 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | 389 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); |
362 | iwl_rx_queue_restock(trans); | 390 | iwl_pcie_rxq_restock(trans); |
363 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 391 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); |
364 | } | 392 | } |
365 | 393 | ||
366 | static void iwl_rx_replenish_now(struct iwl_trans *trans) | 394 | static void iwl_pcie_rx_replenish_now(struct iwl_trans *trans) |
367 | { | 395 | { |
368 | iwl_rx_allocate(trans, GFP_ATOMIC); | 396 | iwl_pcie_rxq_alloc_rbs(trans, GFP_ATOMIC); |
369 | 397 | ||
370 | iwl_rx_queue_restock(trans); | 398 | iwl_pcie_rxq_restock(trans); |
371 | } | 399 | } |
372 | 400 | ||
373 | void iwl_bg_rx_replenish(struct work_struct *data) | 401 | static void iwl_pcie_rx_replenish_work(struct work_struct *data) |
374 | { | 402 | { |
375 | struct iwl_trans_pcie *trans_pcie = | 403 | struct iwl_trans_pcie *trans_pcie = |
376 | container_of(data, struct iwl_trans_pcie, rx_replenish); | 404 | container_of(data, struct iwl_trans_pcie, rx_replenish); |
377 | 405 | ||
378 | iwl_rx_replenish(trans_pcie->trans); | 406 | iwl_pcie_rx_replenish(trans_pcie->trans); |
407 | } | ||
408 | |||
409 | static int iwl_pcie_rx_alloc(struct iwl_trans *trans) | ||
410 | { | ||
411 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
412 | struct iwl_rxq *rxq = &trans_pcie->rxq; | ||
413 | struct device *dev = trans->dev; | ||
414 | |||
415 | memset(&trans_pcie->rxq, 0, sizeof(trans_pcie->rxq)); | ||
416 | |||
417 | spin_lock_init(&rxq->lock); | ||
418 | |||
419 | if (WARN_ON(rxq->bd || rxq->rb_stts)) | ||
420 | return -EINVAL; | ||
421 | |||
422 | /* Allocate the circular buffer of Read Buffer Descriptors (RBDs) */ | ||
423 | rxq->bd = dma_zalloc_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE, | ||
424 | &rxq->bd_dma, GFP_KERNEL); | ||
425 | if (!rxq->bd) | ||
426 | goto err_bd; | ||
427 | |||
428 | /*Allocate the driver's pointer to receive buffer status */ | ||
429 | rxq->rb_stts = dma_zalloc_coherent(dev, sizeof(*rxq->rb_stts), | ||
430 | &rxq->rb_stts_dma, GFP_KERNEL); | ||
431 | if (!rxq->rb_stts) | ||
432 | goto err_rb_stts; | ||
433 | |||
434 | return 0; | ||
435 | |||
436 | err_rb_stts: | ||
437 | dma_free_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE, | ||
438 | rxq->bd, rxq->bd_dma); | ||
439 | memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma)); | ||
440 | rxq->bd = NULL; | ||
441 | err_bd: | ||
442 | return -ENOMEM; | ||
443 | } | ||
444 | |||
445 | static void iwl_pcie_rx_hw_init(struct iwl_trans *trans, struct iwl_rxq *rxq) | ||
446 | { | ||
447 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
448 | u32 rb_size; | ||
449 | const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */ | ||
450 | |||
451 | if (trans_pcie->rx_buf_size_8k) | ||
452 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K; | ||
453 | else | ||
454 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; | ||
455 | |||
456 | /* Stop Rx DMA */ | ||
457 | iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); | ||
458 | |||
459 | /* Reset driver's Rx queue write index */ | ||
460 | iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); | ||
461 | |||
462 | /* Tell device where to find RBD circular buffer in DRAM */ | ||
463 | iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_BASE_REG, | ||
464 | (u32)(rxq->bd_dma >> 8)); | ||
465 | |||
466 | /* Tell device where in DRAM to update its Rx status */ | ||
467 | iwl_write_direct32(trans, FH_RSCSR_CHNL0_STTS_WPTR_REG, | ||
468 | rxq->rb_stts_dma >> 4); | ||
469 | |||
470 | /* Enable Rx DMA | ||
471 | * FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set because of HW bug in | ||
472 | * the credit mechanism in 5000 HW RX FIFO | ||
473 | * Direct rx interrupts to hosts | ||
474 | * Rx buffer size 4 or 8k | ||
475 | * RB timeout 0x10 | ||
476 | * 256 RBDs | ||
477 | */ | ||
478 | iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, | ||
479 | FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | | ||
480 | FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY | | ||
481 | FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | | ||
482 | rb_size| | ||
483 | (RX_RB_TIMEOUT << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)| | ||
484 | (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS)); | ||
485 | |||
486 | /* Set interrupt coalescing timer to default (2048 usecs) */ | ||
487 | iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF); | ||
488 | } | ||
489 | |||
490 | int iwl_pcie_rx_init(struct iwl_trans *trans) | ||
491 | { | ||
492 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
493 | struct iwl_rxq *rxq = &trans_pcie->rxq; | ||
494 | |||
495 | int i, err; | ||
496 | unsigned long flags; | ||
497 | |||
498 | if (!rxq->bd) { | ||
499 | err = iwl_pcie_rx_alloc(trans); | ||
500 | if (err) | ||
501 | return err; | ||
502 | } | ||
503 | |||
504 | spin_lock_irqsave(&rxq->lock, flags); | ||
505 | INIT_LIST_HEAD(&rxq->rx_free); | ||
506 | INIT_LIST_HEAD(&rxq->rx_used); | ||
507 | |||
508 | INIT_WORK(&trans_pcie->rx_replenish, | ||
509 | iwl_pcie_rx_replenish_work); | ||
510 | |||
511 | iwl_pcie_rxq_free_rbs(trans); | ||
512 | |||
513 | for (i = 0; i < RX_QUEUE_SIZE; i++) | ||
514 | rxq->queue[i] = NULL; | ||
515 | |||
516 | /* Set us so that we have processed and used all buffers, but have | ||
517 | * not restocked the Rx queue with fresh buffers */ | ||
518 | rxq->read = rxq->write = 0; | ||
519 | rxq->write_actual = 0; | ||
520 | rxq->free_count = 0; | ||
521 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
522 | |||
523 | iwl_pcie_rx_replenish(trans); | ||
524 | |||
525 | iwl_pcie_rx_hw_init(trans, rxq); | ||
526 | |||
527 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | ||
528 | rxq->need_update = 1; | ||
529 | iwl_pcie_rxq_inc_wr_ptr(trans, rxq); | ||
530 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | ||
531 | |||
532 | return 0; | ||
533 | } | ||
534 | |||
535 | void iwl_pcie_rx_free(struct iwl_trans *trans) | ||
536 | { | ||
537 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
538 | struct iwl_rxq *rxq = &trans_pcie->rxq; | ||
539 | unsigned long flags; | ||
540 | |||
541 | /*if rxq->bd is NULL, it means that nothing has been allocated, | ||
542 | * exit now */ | ||
543 | if (!rxq->bd) { | ||
544 | IWL_DEBUG_INFO(trans, "Free NULL rx context\n"); | ||
545 | return; | ||
546 | } | ||
547 | |||
548 | spin_lock_irqsave(&rxq->lock, flags); | ||
549 | iwl_pcie_rxq_free_rbs(trans); | ||
550 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
551 | |||
552 | dma_free_coherent(trans->dev, sizeof(__le32) * RX_QUEUE_SIZE, | ||
553 | rxq->bd, rxq->bd_dma); | ||
554 | memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma)); | ||
555 | rxq->bd = NULL; | ||
556 | |||
557 | if (rxq->rb_stts) | ||
558 | dma_free_coherent(trans->dev, | ||
559 | sizeof(struct iwl_rb_status), | ||
560 | rxq->rb_stts, rxq->rb_stts_dma); | ||
561 | else | ||
562 | IWL_DEBUG_INFO(trans, "Free rxq->rb_stts which is NULL\n"); | ||
563 | memset(&rxq->rb_stts_dma, 0, sizeof(rxq->rb_stts_dma)); | ||
564 | rxq->rb_stts = NULL; | ||
379 | } | 565 | } |
380 | 566 | ||
381 | static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, | 567 | static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, |
382 | struct iwl_rx_mem_buffer *rxb) | 568 | struct iwl_rx_mem_buffer *rxb) |
383 | { | 569 | { |
384 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 570 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
385 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; | 571 | struct iwl_rxq *rxq = &trans_pcie->rxq; |
386 | struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; | 572 | struct iwl_txq *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; |
387 | unsigned long flags; | 573 | unsigned long flags; |
388 | bool page_stolen = false; | 574 | bool page_stolen = false; |
389 | int max_len = PAGE_SIZE << trans_pcie->rx_page_order; | 575 | int max_len = PAGE_SIZE << trans_pcie->rx_page_order; |
@@ -413,8 +599,7 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, | |||
413 | break; | 599 | break; |
414 | 600 | ||
415 | IWL_DEBUG_RX(trans, "cmd at offset %d: %s (0x%.2x)\n", | 601 | IWL_DEBUG_RX(trans, "cmd at offset %d: %s (0x%.2x)\n", |
416 | rxcb._offset, | 602 | rxcb._offset, get_cmd_string(trans_pcie, pkt->hdr.cmd), |
417 | trans_pcie_get_cmd_string(trans_pcie, pkt->hdr.cmd), | ||
418 | pkt->hdr.cmd); | 603 | pkt->hdr.cmd); |
419 | 604 | ||
420 | len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; | 605 | len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; |
@@ -446,7 +631,7 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, | |||
446 | cmd_index = get_cmd_index(&txq->q, index); | 631 | cmd_index = get_cmd_index(&txq->q, index); |
447 | 632 | ||
448 | if (reclaim) { | 633 | if (reclaim) { |
449 | struct iwl_pcie_tx_queue_entry *ent; | 634 | struct iwl_pcie_txq_entry *ent; |
450 | ent = &txq->entries[cmd_index]; | 635 | ent = &txq->entries[cmd_index]; |
451 | cmd = ent->copy_cmd; | 636 | cmd = ent->copy_cmd; |
452 | WARN_ON_ONCE(!cmd && ent->meta.flags & CMD_WANT_HCMD); | 637 | WARN_ON_ONCE(!cmd && ent->meta.flags & CMD_WANT_HCMD); |
@@ -460,6 +645,9 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, | |||
460 | /* The original command isn't needed any more */ | 645 | /* The original command isn't needed any more */ |
461 | kfree(txq->entries[cmd_index].copy_cmd); | 646 | kfree(txq->entries[cmd_index].copy_cmd); |
462 | txq->entries[cmd_index].copy_cmd = NULL; | 647 | txq->entries[cmd_index].copy_cmd = NULL; |
648 | /* nor is the duplicated part of the command */ | ||
649 | kfree(txq->entries[cmd_index].free_buf); | ||
650 | txq->entries[cmd_index].free_buf = NULL; | ||
463 | } | 651 | } |
464 | 652 | ||
465 | /* | 653 | /* |
@@ -473,7 +661,7 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, | |||
473 | * iwl_trans_send_cmd() | 661 | * iwl_trans_send_cmd() |
474 | * as we reclaim the driver command queue */ | 662 | * as we reclaim the driver command queue */ |
475 | if (!rxcb._page_stolen) | 663 | if (!rxcb._page_stolen) |
476 | iwl_tx_cmd_complete(trans, &rxcb, err); | 664 | iwl_pcie_hcmd_complete(trans, &rxcb, err); |
477 | else | 665 | else |
478 | IWL_WARN(trans, "Claim null rxb?\n"); | 666 | IWL_WARN(trans, "Claim null rxb?\n"); |
479 | } | 667 | } |
@@ -515,17 +703,13 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, | |||
515 | spin_unlock_irqrestore(&rxq->lock, flags); | 703 | spin_unlock_irqrestore(&rxq->lock, flags); |
516 | } | 704 | } |
517 | 705 | ||
518 | /** | 706 | /* |
519 | * iwl_rx_handle - Main entry function for receiving responses from uCode | 707 | * iwl_pcie_rx_handle - Main entry function for receiving responses from fw |
520 | * | ||
521 | * Uses the priv->rx_handlers callback function array to invoke | ||
522 | * the appropriate handlers, including command responses, | ||
523 | * frame-received notifications, and other notifications. | ||
524 | */ | 708 | */ |
525 | static void iwl_rx_handle(struct iwl_trans *trans) | 709 | static void iwl_pcie_rx_handle(struct iwl_trans *trans) |
526 | { | 710 | { |
527 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 711 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
528 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; | 712 | struct iwl_rxq *rxq = &trans_pcie->rxq; |
529 | u32 r, i; | 713 | u32 r, i; |
530 | u8 fill_rx = 0; | 714 | u8 fill_rx = 0; |
531 | u32 count = 8; | 715 | u32 count = 8; |
@@ -556,7 +740,7 @@ static void iwl_rx_handle(struct iwl_trans *trans) | |||
556 | 740 | ||
557 | IWL_DEBUG_RX(trans, "rxbuf: HW = %d, SW = %d (%p)\n", | 741 | IWL_DEBUG_RX(trans, "rxbuf: HW = %d, SW = %d (%p)\n", |
558 | r, i, rxb); | 742 | r, i, rxb); |
559 | iwl_rx_handle_rxbuf(trans, rxb); | 743 | iwl_pcie_rx_handle_rb(trans, rxb); |
560 | 744 | ||
561 | i = (i + 1) & RX_QUEUE_MASK; | 745 | i = (i + 1) & RX_QUEUE_MASK; |
562 | /* If there are a lot of unused frames, | 746 | /* If there are a lot of unused frames, |
@@ -565,7 +749,7 @@ static void iwl_rx_handle(struct iwl_trans *trans) | |||
565 | count++; | 749 | count++; |
566 | if (count >= 8) { | 750 | if (count >= 8) { |
567 | rxq->read = i; | 751 | rxq->read = i; |
568 | iwl_rx_replenish_now(trans); | 752 | iwl_pcie_rx_replenish_now(trans); |
569 | count = 0; | 753 | count = 0; |
570 | } | 754 | } |
571 | } | 755 | } |
@@ -574,39 +758,41 @@ static void iwl_rx_handle(struct iwl_trans *trans) | |||
574 | /* Backtrack one entry */ | 758 | /* Backtrack one entry */ |
575 | rxq->read = i; | 759 | rxq->read = i; |
576 | if (fill_rx) | 760 | if (fill_rx) |
577 | iwl_rx_replenish_now(trans); | 761 | iwl_pcie_rx_replenish_now(trans); |
578 | else | 762 | else |
579 | iwl_rx_queue_restock(trans); | 763 | iwl_pcie_rxq_restock(trans); |
580 | } | 764 | } |
581 | 765 | ||
582 | /** | 766 | /* |
583 | * iwl_irq_handle_error - called for HW or SW error interrupt from card | 767 | * iwl_pcie_irq_handle_error - called for HW or SW error interrupt from card |
584 | */ | 768 | */ |
585 | static void iwl_irq_handle_error(struct iwl_trans *trans) | 769 | static void iwl_pcie_irq_handle_error(struct iwl_trans *trans) |
586 | { | 770 | { |
771 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
772 | |||
587 | /* W/A for WiFi/WiMAX coex and WiMAX own the RF */ | 773 | /* W/A for WiFi/WiMAX coex and WiMAX own the RF */ |
588 | if (trans->cfg->internal_wimax_coex && | 774 | if (trans->cfg->internal_wimax_coex && |
589 | (!(iwl_read_prph(trans, APMG_CLK_CTRL_REG) & | 775 | (!(iwl_read_prph(trans, APMG_CLK_CTRL_REG) & |
590 | APMS_CLK_VAL_MRB_FUNC_MODE) || | 776 | APMS_CLK_VAL_MRB_FUNC_MODE) || |
591 | (iwl_read_prph(trans, APMG_PS_CTRL_REG) & | 777 | (iwl_read_prph(trans, APMG_PS_CTRL_REG) & |
592 | APMG_PS_CTRL_VAL_RESET_REQ))) { | 778 | APMG_PS_CTRL_VAL_RESET_REQ))) { |
593 | struct iwl_trans_pcie *trans_pcie = | ||
594 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
595 | |||
596 | clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); | 779 | clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); |
597 | iwl_op_mode_wimax_active(trans->op_mode); | 780 | iwl_op_mode_wimax_active(trans->op_mode); |
598 | wake_up(&trans->wait_command_queue); | 781 | wake_up(&trans_pcie->wait_command_queue); |
599 | return; | 782 | return; |
600 | } | 783 | } |
601 | 784 | ||
602 | iwl_dump_csr(trans); | 785 | iwl_pcie_dump_csr(trans); |
603 | iwl_dump_fh(trans, NULL); | 786 | iwl_pcie_dump_fh(trans, NULL); |
787 | |||
788 | set_bit(STATUS_FW_ERROR, &trans_pcie->status); | ||
789 | clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); | ||
790 | wake_up(&trans_pcie->wait_command_queue); | ||
604 | 791 | ||
605 | iwl_op_mode_nic_error(trans->op_mode); | 792 | iwl_op_mode_nic_error(trans->op_mode); |
606 | } | 793 | } |
607 | 794 | ||
608 | /* tasklet for iwlagn interrupt */ | 795 | void iwl_pcie_tasklet(struct iwl_trans *trans) |
609 | void iwl_irq_tasklet(struct iwl_trans *trans) | ||
610 | { | 796 | { |
611 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 797 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
612 | struct isr_statistics *isr_stats = &trans_pcie->isr_stats; | 798 | struct isr_statistics *isr_stats = &trans_pcie->isr_stats; |
@@ -658,7 +844,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
658 | iwl_disable_interrupts(trans); | 844 | iwl_disable_interrupts(trans); |
659 | 845 | ||
660 | isr_stats->hw++; | 846 | isr_stats->hw++; |
661 | iwl_irq_handle_error(trans); | 847 | iwl_pcie_irq_handle_error(trans); |
662 | 848 | ||
663 | handled |= CSR_INT_BIT_HW_ERR; | 849 | handled |= CSR_INT_BIT_HW_ERR; |
664 | 850 | ||
@@ -695,6 +881,16 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
695 | isr_stats->rfkill++; | 881 | isr_stats->rfkill++; |
696 | 882 | ||
697 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); | 883 | iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); |
884 | if (hw_rfkill) { | ||
885 | set_bit(STATUS_RFKILL, &trans_pcie->status); | ||
886 | if (test_and_clear_bit(STATUS_HCMD_ACTIVE, | ||
887 | &trans_pcie->status)) | ||
888 | IWL_DEBUG_RF_KILL(trans, | ||
889 | "Rfkill while SYNC HCMD in flight\n"); | ||
890 | wake_up(&trans_pcie->wait_command_queue); | ||
891 | } else { | ||
892 | clear_bit(STATUS_RFKILL, &trans_pcie->status); | ||
893 | } | ||
698 | 894 | ||
699 | handled |= CSR_INT_BIT_RF_KILL; | 895 | handled |= CSR_INT_BIT_RF_KILL; |
700 | } | 896 | } |
@@ -711,17 +907,16 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
711 | IWL_ERR(trans, "Microcode SW error detected. " | 907 | IWL_ERR(trans, "Microcode SW error detected. " |
712 | " Restarting 0x%X.\n", inta); | 908 | " Restarting 0x%X.\n", inta); |
713 | isr_stats->sw++; | 909 | isr_stats->sw++; |
714 | iwl_irq_handle_error(trans); | 910 | iwl_pcie_irq_handle_error(trans); |
715 | handled |= CSR_INT_BIT_SW_ERR; | 911 | handled |= CSR_INT_BIT_SW_ERR; |
716 | } | 912 | } |
717 | 913 | ||
718 | /* uCode wakes up after power-down sleep */ | 914 | /* uCode wakes up after power-down sleep */ |
719 | if (inta & CSR_INT_BIT_WAKEUP) { | 915 | if (inta & CSR_INT_BIT_WAKEUP) { |
720 | IWL_DEBUG_ISR(trans, "Wakeup interrupt\n"); | 916 | IWL_DEBUG_ISR(trans, "Wakeup interrupt\n"); |
721 | iwl_rx_queue_update_write_ptr(trans, &trans_pcie->rxq); | 917 | iwl_pcie_rxq_inc_wr_ptr(trans, &trans_pcie->rxq); |
722 | for (i = 0; i < trans->cfg->base_params->num_of_queues; i++) | 918 | for (i = 0; i < trans->cfg->base_params->num_of_queues; i++) |
723 | iwl_txq_update_write_ptr(trans, | 919 | iwl_pcie_txq_inc_wr_ptr(trans, &trans_pcie->txq[i]); |
724 | &trans_pcie->txq[i]); | ||
725 | 920 | ||
726 | isr_stats->wakeup++; | 921 | isr_stats->wakeup++; |
727 | 922 | ||
@@ -759,7 +954,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
759 | iwl_write8(trans, CSR_INT_PERIODIC_REG, | 954 | iwl_write8(trans, CSR_INT_PERIODIC_REG, |
760 | CSR_INT_PERIODIC_DIS); | 955 | CSR_INT_PERIODIC_DIS); |
761 | 956 | ||
762 | iwl_rx_handle(trans); | 957 | iwl_pcie_rx_handle(trans); |
763 | 958 | ||
764 | /* | 959 | /* |
765 | * Enable periodic interrupt in 8 msec only if we received | 960 | * Enable periodic interrupt in 8 msec only if we received |
@@ -817,7 +1012,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) | |||
817 | #define ICT_COUNT (ICT_SIZE / sizeof(u32)) | 1012 | #define ICT_COUNT (ICT_SIZE / sizeof(u32)) |
818 | 1013 | ||
819 | /* Free dram table */ | 1014 | /* Free dram table */ |
820 | void iwl_free_isr_ict(struct iwl_trans *trans) | 1015 | void iwl_pcie_free_ict(struct iwl_trans *trans) |
821 | { | 1016 | { |
822 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1017 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
823 | 1018 | ||
@@ -830,13 +1025,12 @@ void iwl_free_isr_ict(struct iwl_trans *trans) | |||
830 | } | 1025 | } |
831 | } | 1026 | } |
832 | 1027 | ||
833 | |||
834 | /* | 1028 | /* |
835 | * allocate dram shared table, it is an aligned memory | 1029 | * allocate dram shared table, it is an aligned memory |
836 | * block of ICT_SIZE. | 1030 | * block of ICT_SIZE. |
837 | * also reset all data related to ICT table interrupt. | 1031 | * also reset all data related to ICT table interrupt. |
838 | */ | 1032 | */ |
839 | int iwl_alloc_isr_ict(struct iwl_trans *trans) | 1033 | int iwl_pcie_alloc_ict(struct iwl_trans *trans) |
840 | { | 1034 | { |
841 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1035 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
842 | 1036 | ||
@@ -849,7 +1043,7 @@ int iwl_alloc_isr_ict(struct iwl_trans *trans) | |||
849 | 1043 | ||
850 | /* just an API sanity check ... it is guaranteed to be aligned */ | 1044 | /* just an API sanity check ... it is guaranteed to be aligned */ |
851 | if (WARN_ON(trans_pcie->ict_tbl_dma & (ICT_SIZE - 1))) { | 1045 | if (WARN_ON(trans_pcie->ict_tbl_dma & (ICT_SIZE - 1))) { |
852 | iwl_free_isr_ict(trans); | 1046 | iwl_pcie_free_ict(trans); |
853 | return -EINVAL; | 1047 | return -EINVAL; |
854 | } | 1048 | } |
855 | 1049 | ||
@@ -870,7 +1064,7 @@ int iwl_alloc_isr_ict(struct iwl_trans *trans) | |||
870 | /* Device is going up inform it about using ICT interrupt table, | 1064 | /* Device is going up inform it about using ICT interrupt table, |
871 | * also we need to tell the driver to start using ICT interrupt. | 1065 | * also we need to tell the driver to start using ICT interrupt. |
872 | */ | 1066 | */ |
873 | void iwl_reset_ict(struct iwl_trans *trans) | 1067 | void iwl_pcie_reset_ict(struct iwl_trans *trans) |
874 | { | 1068 | { |
875 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1069 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
876 | u32 val; | 1070 | u32 val; |
@@ -900,7 +1094,7 @@ void iwl_reset_ict(struct iwl_trans *trans) | |||
900 | } | 1094 | } |
901 | 1095 | ||
902 | /* Device is going down disable ict interrupt usage */ | 1096 | /* Device is going down disable ict interrupt usage */ |
903 | void iwl_disable_ict(struct iwl_trans *trans) | 1097 | void iwl_pcie_disable_ict(struct iwl_trans *trans) |
904 | { | 1098 | { |
905 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1099 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
906 | unsigned long flags; | 1100 | unsigned long flags; |
@@ -911,7 +1105,7 @@ void iwl_disable_ict(struct iwl_trans *trans) | |||
911 | } | 1105 | } |
912 | 1106 | ||
913 | /* legacy (non-ICT) ISR. Assumes that trans_pcie->irq_lock is held */ | 1107 | /* legacy (non-ICT) ISR. Assumes that trans_pcie->irq_lock is held */ |
914 | static irqreturn_t iwl_isr(int irq, void *data) | 1108 | static irqreturn_t iwl_pcie_isr(int irq, void *data) |
915 | { | 1109 | { |
916 | struct iwl_trans *trans = data; | 1110 | struct iwl_trans *trans = data; |
917 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1111 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
@@ -958,7 +1152,7 @@ static irqreturn_t iwl_isr(int irq, void *data) | |||
958 | #endif | 1152 | #endif |
959 | 1153 | ||
960 | trans_pcie->inta |= inta; | 1154 | trans_pcie->inta |= inta; |
961 | /* iwl_irq_tasklet() will service interrupts and re-enable them */ | 1155 | /* iwl_pcie_tasklet() will service interrupts and re-enable them */ |
962 | if (likely(inta)) | 1156 | if (likely(inta)) |
963 | tasklet_schedule(&trans_pcie->irq_tasklet); | 1157 | tasklet_schedule(&trans_pcie->irq_tasklet); |
964 | else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && | 1158 | else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && |
@@ -983,7 +1177,7 @@ none: | |||
983 | * the interrupt we need to service, driver will set the entries back to 0 and | 1177 | * the interrupt we need to service, driver will set the entries back to 0 and |
984 | * set index. | 1178 | * set index. |
985 | */ | 1179 | */ |
986 | irqreturn_t iwl_isr_ict(int irq, void *data) | 1180 | irqreturn_t iwl_pcie_isr_ict(int irq, void *data) |
987 | { | 1181 | { |
988 | struct iwl_trans *trans = data; | 1182 | struct iwl_trans *trans = data; |
989 | struct iwl_trans_pcie *trans_pcie; | 1183 | struct iwl_trans_pcie *trans_pcie; |
@@ -1003,14 +1197,13 @@ irqreturn_t iwl_isr_ict(int irq, void *data) | |||
1003 | * use legacy interrupt. | 1197 | * use legacy interrupt. |
1004 | */ | 1198 | */ |
1005 | if (unlikely(!trans_pcie->use_ict)) { | 1199 | if (unlikely(!trans_pcie->use_ict)) { |
1006 | irqreturn_t ret = iwl_isr(irq, data); | 1200 | irqreturn_t ret = iwl_pcie_isr(irq, data); |
1007 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 1201 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); |
1008 | return ret; | 1202 | return ret; |
1009 | } | 1203 | } |
1010 | 1204 | ||
1011 | trace_iwlwifi_dev_irq(trans->dev); | 1205 | trace_iwlwifi_dev_irq(trans->dev); |
1012 | 1206 | ||
1013 | |||
1014 | /* Disable (but don't clear!) interrupts here to avoid | 1207 | /* Disable (but don't clear!) interrupts here to avoid |
1015 | * back-to-back ISRs and sporadic interrupts from our NIC. | 1208 | * back-to-back ISRs and sporadic interrupts from our NIC. |
1016 | * If we have something to service, the tasklet will re-enable ints. | 1209 | * If we have something to service, the tasklet will re-enable ints. |
@@ -1019,7 +1212,6 @@ irqreturn_t iwl_isr_ict(int irq, void *data) | |||
1019 | inta_mask = iwl_read32(trans, CSR_INT_MASK); /* just for debug */ | 1212 | inta_mask = iwl_read32(trans, CSR_INT_MASK); /* just for debug */ |
1020 | iwl_write32(trans, CSR_INT_MASK, 0x00000000); | 1213 | iwl_write32(trans, CSR_INT_MASK, 0x00000000); |
1021 | 1214 | ||
1022 | |||
1023 | /* Ignore interrupt if there's nothing in NIC to service. | 1215 | /* Ignore interrupt if there's nothing in NIC to service. |
1024 | * This may be due to IRQ shared with another device, | 1216 | * This may be due to IRQ shared with another device, |
1025 | * or due to sporadic interrupts thrown from our NIC. */ | 1217 | * or due to sporadic interrupts thrown from our NIC. */ |
@@ -1068,7 +1260,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) | |||
1068 | inta &= trans_pcie->inta_mask; | 1260 | inta &= trans_pcie->inta_mask; |
1069 | trans_pcie->inta |= inta; | 1261 | trans_pcie->inta |= inta; |
1070 | 1262 | ||
1071 | /* iwl_irq_tasklet() will service interrupts and re-enable them */ | 1263 | /* iwl_pcie_tasklet() will service interrupts and re-enable them */ |
1072 | if (likely(inta)) | 1264 | if (likely(inta)) |
1073 | tasklet_schedule(&trans_pcie->irq_tasklet); | 1265 | tasklet_schedule(&trans_pcie->irq_tasklet); |
1074 | else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && | 1266 | else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && |
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index f95d88df7772..f6c21e7edaf2 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c | |||
@@ -74,584 +74,8 @@ | |||
74 | #include "iwl-prph.h" | 74 | #include "iwl-prph.h" |
75 | #include "iwl-agn-hw.h" | 75 | #include "iwl-agn-hw.h" |
76 | #include "internal.h" | 76 | #include "internal.h" |
77 | /* FIXME: need to abstract out TX command (once we know what it looks like) */ | ||
78 | #include "dvm/commands.h" | ||
79 | 77 | ||
80 | #define SCD_QUEUECHAIN_SEL_ALL(trans, trans_pcie) \ | 78 | static void iwl_pcie_set_pwr_vmain(struct iwl_trans *trans) |
81 | (((1<<trans->cfg->base_params->num_of_queues) - 1) &\ | ||
82 | (~(1<<(trans_pcie)->cmd_queue))) | ||
83 | |||
84 | static int iwl_trans_rx_alloc(struct iwl_trans *trans) | ||
85 | { | ||
86 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
87 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; | ||
88 | struct device *dev = trans->dev; | ||
89 | |||
90 | memset(&trans_pcie->rxq, 0, sizeof(trans_pcie->rxq)); | ||
91 | |||
92 | spin_lock_init(&rxq->lock); | ||
93 | |||
94 | if (WARN_ON(rxq->bd || rxq->rb_stts)) | ||
95 | return -EINVAL; | ||
96 | |||
97 | /* Allocate the circular buffer of Read Buffer Descriptors (RBDs) */ | ||
98 | rxq->bd = dma_zalloc_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE, | ||
99 | &rxq->bd_dma, GFP_KERNEL); | ||
100 | if (!rxq->bd) | ||
101 | goto err_bd; | ||
102 | |||
103 | /*Allocate the driver's pointer to receive buffer status */ | ||
104 | rxq->rb_stts = dma_zalloc_coherent(dev, sizeof(*rxq->rb_stts), | ||
105 | &rxq->rb_stts_dma, GFP_KERNEL); | ||
106 | if (!rxq->rb_stts) | ||
107 | goto err_rb_stts; | ||
108 | |||
109 | return 0; | ||
110 | |||
111 | err_rb_stts: | ||
112 | dma_free_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE, | ||
113 | rxq->bd, rxq->bd_dma); | ||
114 | memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma)); | ||
115 | rxq->bd = NULL; | ||
116 | err_bd: | ||
117 | return -ENOMEM; | ||
118 | } | ||
119 | |||
120 | static void iwl_trans_rxq_free_rx_bufs(struct iwl_trans *trans) | ||
121 | { | ||
122 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
123 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; | ||
124 | int i; | ||
125 | |||
126 | /* Fill the rx_used queue with _all_ of the Rx buffers */ | ||
127 | for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { | ||
128 | /* In the reset function, these buffers may have been allocated | ||
129 | * to an SKB, so we need to unmap and free potential storage */ | ||
130 | if (rxq->pool[i].page != NULL) { | ||
131 | dma_unmap_page(trans->dev, rxq->pool[i].page_dma, | ||
132 | PAGE_SIZE << trans_pcie->rx_page_order, | ||
133 | DMA_FROM_DEVICE); | ||
134 | __free_pages(rxq->pool[i].page, | ||
135 | trans_pcie->rx_page_order); | ||
136 | rxq->pool[i].page = NULL; | ||
137 | } | ||
138 | list_add_tail(&rxq->pool[i].list, &rxq->rx_used); | ||
139 | } | ||
140 | } | ||
141 | |||
142 | static void iwl_trans_rx_hw_init(struct iwl_trans *trans, | ||
143 | struct iwl_rx_queue *rxq) | ||
144 | { | ||
145 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
146 | u32 rb_size; | ||
147 | const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */ | ||
148 | u32 rb_timeout = RX_RB_TIMEOUT; /* FIXME: RX_RB_TIMEOUT for all devices? */ | ||
149 | |||
150 | if (trans_pcie->rx_buf_size_8k) | ||
151 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K; | ||
152 | else | ||
153 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; | ||
154 | |||
155 | /* Stop Rx DMA */ | ||
156 | iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); | ||
157 | |||
158 | /* Reset driver's Rx queue write index */ | ||
159 | iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); | ||
160 | |||
161 | /* Tell device where to find RBD circular buffer in DRAM */ | ||
162 | iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_BASE_REG, | ||
163 | (u32)(rxq->bd_dma >> 8)); | ||
164 | |||
165 | /* Tell device where in DRAM to update its Rx status */ | ||
166 | iwl_write_direct32(trans, FH_RSCSR_CHNL0_STTS_WPTR_REG, | ||
167 | rxq->rb_stts_dma >> 4); | ||
168 | |||
169 | /* Enable Rx DMA | ||
170 | * FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set because of HW bug in | ||
171 | * the credit mechanism in 5000 HW RX FIFO | ||
172 | * Direct rx interrupts to hosts | ||
173 | * Rx buffer size 4 or 8k | ||
174 | * RB timeout 0x10 | ||
175 | * 256 RBDs | ||
176 | */ | ||
177 | iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, | ||
178 | FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | | ||
179 | FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY | | ||
180 | FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | | ||
181 | rb_size| | ||
182 | (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)| | ||
183 | (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS)); | ||
184 | |||
185 | /* Set interrupt coalescing timer to default (2048 usecs) */ | ||
186 | iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF); | ||
187 | } | ||
188 | |||
189 | static int iwl_rx_init(struct iwl_trans *trans) | ||
190 | { | ||
191 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
192 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; | ||
193 | |||
194 | int i, err; | ||
195 | unsigned long flags; | ||
196 | |||
197 | if (!rxq->bd) { | ||
198 | err = iwl_trans_rx_alloc(trans); | ||
199 | if (err) | ||
200 | return err; | ||
201 | } | ||
202 | |||
203 | spin_lock_irqsave(&rxq->lock, flags); | ||
204 | INIT_LIST_HEAD(&rxq->rx_free); | ||
205 | INIT_LIST_HEAD(&rxq->rx_used); | ||
206 | |||
207 | iwl_trans_rxq_free_rx_bufs(trans); | ||
208 | |||
209 | for (i = 0; i < RX_QUEUE_SIZE; i++) | ||
210 | rxq->queue[i] = NULL; | ||
211 | |||
212 | /* Set us so that we have processed and used all buffers, but have | ||
213 | * not restocked the Rx queue with fresh buffers */ | ||
214 | rxq->read = rxq->write = 0; | ||
215 | rxq->write_actual = 0; | ||
216 | rxq->free_count = 0; | ||
217 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
218 | |||
219 | iwl_rx_replenish(trans); | ||
220 | |||
221 | iwl_trans_rx_hw_init(trans, rxq); | ||
222 | |||
223 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | ||
224 | rxq->need_update = 1; | ||
225 | iwl_rx_queue_update_write_ptr(trans, rxq); | ||
226 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | ||
227 | |||
228 | return 0; | ||
229 | } | ||
230 | |||
231 | static void iwl_trans_pcie_rx_free(struct iwl_trans *trans) | ||
232 | { | ||
233 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
234 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; | ||
235 | unsigned long flags; | ||
236 | |||
237 | /*if rxq->bd is NULL, it means that nothing has been allocated, | ||
238 | * exit now */ | ||
239 | if (!rxq->bd) { | ||
240 | IWL_DEBUG_INFO(trans, "Free NULL rx context\n"); | ||
241 | return; | ||
242 | } | ||
243 | |||
244 | spin_lock_irqsave(&rxq->lock, flags); | ||
245 | iwl_trans_rxq_free_rx_bufs(trans); | ||
246 | spin_unlock_irqrestore(&rxq->lock, flags); | ||
247 | |||
248 | dma_free_coherent(trans->dev, sizeof(__le32) * RX_QUEUE_SIZE, | ||
249 | rxq->bd, rxq->bd_dma); | ||
250 | memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma)); | ||
251 | rxq->bd = NULL; | ||
252 | |||
253 | if (rxq->rb_stts) | ||
254 | dma_free_coherent(trans->dev, | ||
255 | sizeof(struct iwl_rb_status), | ||
256 | rxq->rb_stts, rxq->rb_stts_dma); | ||
257 | else | ||
258 | IWL_DEBUG_INFO(trans, "Free rxq->rb_stts which is NULL\n"); | ||
259 | memset(&rxq->rb_stts_dma, 0, sizeof(rxq->rb_stts_dma)); | ||
260 | rxq->rb_stts = NULL; | ||
261 | } | ||
262 | |||
263 | static int iwl_trans_rx_stop(struct iwl_trans *trans) | ||
264 | { | ||
265 | |||
266 | /* stop Rx DMA */ | ||
267 | iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); | ||
268 | return iwl_poll_direct_bit(trans, FH_MEM_RSSR_RX_STATUS_REG, | ||
269 | FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); | ||
270 | } | ||
271 | |||
272 | static int iwlagn_alloc_dma_ptr(struct iwl_trans *trans, | ||
273 | struct iwl_dma_ptr *ptr, size_t size) | ||
274 | { | ||
275 | if (WARN_ON(ptr->addr)) | ||
276 | return -EINVAL; | ||
277 | |||
278 | ptr->addr = dma_alloc_coherent(trans->dev, size, | ||
279 | &ptr->dma, GFP_KERNEL); | ||
280 | if (!ptr->addr) | ||
281 | return -ENOMEM; | ||
282 | ptr->size = size; | ||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | static void iwlagn_free_dma_ptr(struct iwl_trans *trans, | ||
287 | struct iwl_dma_ptr *ptr) | ||
288 | { | ||
289 | if (unlikely(!ptr->addr)) | ||
290 | return; | ||
291 | |||
292 | dma_free_coherent(trans->dev, ptr->size, ptr->addr, ptr->dma); | ||
293 | memset(ptr, 0, sizeof(*ptr)); | ||
294 | } | ||
295 | |||
296 | static void iwl_trans_pcie_queue_stuck_timer(unsigned long data) | ||
297 | { | ||
298 | struct iwl_tx_queue *txq = (void *)data; | ||
299 | struct iwl_queue *q = &txq->q; | ||
300 | struct iwl_trans_pcie *trans_pcie = txq->trans_pcie; | ||
301 | struct iwl_trans *trans = iwl_trans_pcie_get_trans(trans_pcie); | ||
302 | u32 scd_sram_addr = trans_pcie->scd_base_addr + | ||
303 | SCD_TX_STTS_QUEUE_OFFSET(txq->q.id); | ||
304 | u8 buf[16]; | ||
305 | int i; | ||
306 | |||
307 | spin_lock(&txq->lock); | ||
308 | /* check if triggered erroneously */ | ||
309 | if (txq->q.read_ptr == txq->q.write_ptr) { | ||
310 | spin_unlock(&txq->lock); | ||
311 | return; | ||
312 | } | ||
313 | spin_unlock(&txq->lock); | ||
314 | |||
315 | IWL_ERR(trans, "Queue %d stuck for %u ms.\n", txq->q.id, | ||
316 | jiffies_to_msecs(trans_pcie->wd_timeout)); | ||
317 | IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n", | ||
318 | txq->q.read_ptr, txq->q.write_ptr); | ||
319 | |||
320 | iwl_read_targ_mem_bytes(trans, scd_sram_addr, buf, sizeof(buf)); | ||
321 | |||
322 | iwl_print_hex_error(trans, buf, sizeof(buf)); | ||
323 | |||
324 | for (i = 0; i < FH_TCSR_CHNL_NUM; i++) | ||
325 | IWL_ERR(trans, "FH TRBs(%d) = 0x%08x\n", i, | ||
326 | iwl_read_direct32(trans, FH_TX_TRB_REG(i))); | ||
327 | |||
328 | for (i = 0; i < trans->cfg->base_params->num_of_queues; i++) { | ||
329 | u32 status = iwl_read_prph(trans, SCD_QUEUE_STATUS_BITS(i)); | ||
330 | u8 fifo = (status >> SCD_QUEUE_STTS_REG_POS_TXF) & 0x7; | ||
331 | bool active = !!(status & BIT(SCD_QUEUE_STTS_REG_POS_ACTIVE)); | ||
332 | u32 tbl_dw = | ||
333 | iwl_read_targ_mem(trans, | ||
334 | trans_pcie->scd_base_addr + | ||
335 | SCD_TRANS_TBL_OFFSET_QUEUE(i)); | ||
336 | |||
337 | if (i & 0x1) | ||
338 | tbl_dw = (tbl_dw & 0xFFFF0000) >> 16; | ||
339 | else | ||
340 | tbl_dw = tbl_dw & 0x0000FFFF; | ||
341 | |||
342 | IWL_ERR(trans, | ||
343 | "Q %d is %sactive and mapped to fifo %d ra_tid 0x%04x [%d,%d]\n", | ||
344 | i, active ? "" : "in", fifo, tbl_dw, | ||
345 | iwl_read_prph(trans, | ||
346 | SCD_QUEUE_RDPTR(i)) & (txq->q.n_bd - 1), | ||
347 | iwl_read_prph(trans, SCD_QUEUE_WRPTR(i))); | ||
348 | } | ||
349 | |||
350 | for (i = q->read_ptr; i != q->write_ptr; | ||
351 | i = iwl_queue_inc_wrap(i, q->n_bd)) { | ||
352 | struct iwl_tx_cmd *tx_cmd = | ||
353 | (struct iwl_tx_cmd *)txq->entries[i].cmd->payload; | ||
354 | IWL_ERR(trans, "scratch %d = 0x%08x\n", i, | ||
355 | get_unaligned_le32(&tx_cmd->scratch)); | ||
356 | } | ||
357 | |||
358 | iwl_op_mode_nic_error(trans->op_mode); | ||
359 | } | ||
360 | |||
361 | static int iwl_trans_txq_alloc(struct iwl_trans *trans, | ||
362 | struct iwl_tx_queue *txq, int slots_num, | ||
363 | u32 txq_id) | ||
364 | { | ||
365 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
366 | size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX; | ||
367 | int i; | ||
368 | |||
369 | if (WARN_ON(txq->entries || txq->tfds)) | ||
370 | return -EINVAL; | ||
371 | |||
372 | setup_timer(&txq->stuck_timer, iwl_trans_pcie_queue_stuck_timer, | ||
373 | (unsigned long)txq); | ||
374 | txq->trans_pcie = trans_pcie; | ||
375 | |||
376 | txq->q.n_window = slots_num; | ||
377 | |||
378 | txq->entries = kcalloc(slots_num, | ||
379 | sizeof(struct iwl_pcie_tx_queue_entry), | ||
380 | GFP_KERNEL); | ||
381 | |||
382 | if (!txq->entries) | ||
383 | goto error; | ||
384 | |||
385 | if (txq_id == trans_pcie->cmd_queue) | ||
386 | for (i = 0; i < slots_num; i++) { | ||
387 | txq->entries[i].cmd = | ||
388 | kmalloc(sizeof(struct iwl_device_cmd), | ||
389 | GFP_KERNEL); | ||
390 | if (!txq->entries[i].cmd) | ||
391 | goto error; | ||
392 | } | ||
393 | |||
394 | /* Circular buffer of transmit frame descriptors (TFDs), | ||
395 | * shared with device */ | ||
396 | txq->tfds = dma_alloc_coherent(trans->dev, tfd_sz, | ||
397 | &txq->q.dma_addr, GFP_KERNEL); | ||
398 | if (!txq->tfds) { | ||
399 | IWL_ERR(trans, "dma_alloc_coherent(%zd) failed\n", tfd_sz); | ||
400 | goto error; | ||
401 | } | ||
402 | txq->q.id = txq_id; | ||
403 | |||
404 | return 0; | ||
405 | error: | ||
406 | if (txq->entries && txq_id == trans_pcie->cmd_queue) | ||
407 | for (i = 0; i < slots_num; i++) | ||
408 | kfree(txq->entries[i].cmd); | ||
409 | kfree(txq->entries); | ||
410 | txq->entries = NULL; | ||
411 | |||
412 | return -ENOMEM; | ||
413 | |||
414 | } | ||
415 | |||
416 | static int iwl_trans_txq_init(struct iwl_trans *trans, struct iwl_tx_queue *txq, | ||
417 | int slots_num, u32 txq_id) | ||
418 | { | ||
419 | int ret; | ||
420 | |||
421 | txq->need_update = 0; | ||
422 | |||
423 | /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise | ||
424 | * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */ | ||
425 | BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); | ||
426 | |||
427 | /* Initialize queue's high/low-water marks, and head/tail indexes */ | ||
428 | ret = iwl_queue_init(&txq->q, TFD_QUEUE_SIZE_MAX, slots_num, | ||
429 | txq_id); | ||
430 | if (ret) | ||
431 | return ret; | ||
432 | |||
433 | spin_lock_init(&txq->lock); | ||
434 | |||
435 | /* | ||
436 | * Tell nic where to find circular buffer of Tx Frame Descriptors for | ||
437 | * given Tx queue, and enable the DMA channel used for that queue. | ||
438 | * Circular buffer (TFD queue in DRAM) physical base address */ | ||
439 | iwl_write_direct32(trans, FH_MEM_CBBC_QUEUE(txq_id), | ||
440 | txq->q.dma_addr >> 8); | ||
441 | |||
442 | return 0; | ||
443 | } | ||
444 | |||
445 | /** | ||
446 | * iwl_tx_queue_unmap - Unmap any remaining DMA mappings and free skb's | ||
447 | */ | ||
448 | static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id) | ||
449 | { | ||
450 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
451 | struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; | ||
452 | struct iwl_queue *q = &txq->q; | ||
453 | enum dma_data_direction dma_dir; | ||
454 | |||
455 | if (!q->n_bd) | ||
456 | return; | ||
457 | |||
458 | /* In the command queue, all the TBs are mapped as BIDI | ||
459 | * so unmap them as such. | ||
460 | */ | ||
461 | if (txq_id == trans_pcie->cmd_queue) | ||
462 | dma_dir = DMA_BIDIRECTIONAL; | ||
463 | else | ||
464 | dma_dir = DMA_TO_DEVICE; | ||
465 | |||
466 | spin_lock_bh(&txq->lock); | ||
467 | while (q->write_ptr != q->read_ptr) { | ||
468 | iwl_txq_free_tfd(trans, txq, dma_dir); | ||
469 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); | ||
470 | } | ||
471 | spin_unlock_bh(&txq->lock); | ||
472 | } | ||
473 | |||
474 | /** | ||
475 | * iwl_tx_queue_free - Deallocate DMA queue. | ||
476 | * @txq: Transmit queue to deallocate. | ||
477 | * | ||
478 | * Empty queue by removing and destroying all BD's. | ||
479 | * Free all buffers. | ||
480 | * 0-fill, but do not free "txq" descriptor structure. | ||
481 | */ | ||
482 | static void iwl_tx_queue_free(struct iwl_trans *trans, int txq_id) | ||
483 | { | ||
484 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
485 | struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; | ||
486 | struct device *dev = trans->dev; | ||
487 | int i; | ||
488 | |||
489 | if (WARN_ON(!txq)) | ||
490 | return; | ||
491 | |||
492 | iwl_tx_queue_unmap(trans, txq_id); | ||
493 | |||
494 | /* De-alloc array of command/tx buffers */ | ||
495 | if (txq_id == trans_pcie->cmd_queue) | ||
496 | for (i = 0; i < txq->q.n_window; i++) { | ||
497 | kfree(txq->entries[i].cmd); | ||
498 | kfree(txq->entries[i].copy_cmd); | ||
499 | } | ||
500 | |||
501 | /* De-alloc circular buffer of TFDs */ | ||
502 | if (txq->q.n_bd) { | ||
503 | dma_free_coherent(dev, sizeof(struct iwl_tfd) * | ||
504 | txq->q.n_bd, txq->tfds, txq->q.dma_addr); | ||
505 | memset(&txq->q.dma_addr, 0, sizeof(txq->q.dma_addr)); | ||
506 | } | ||
507 | |||
508 | kfree(txq->entries); | ||
509 | txq->entries = NULL; | ||
510 | |||
511 | del_timer_sync(&txq->stuck_timer); | ||
512 | |||
513 | /* 0-fill queue descriptor structure */ | ||
514 | memset(txq, 0, sizeof(*txq)); | ||
515 | } | ||
516 | |||
517 | /** | ||
518 | * iwl_trans_tx_free - Free TXQ Context | ||
519 | * | ||
520 | * Destroy all TX DMA queues and structures | ||
521 | */ | ||
522 | static void iwl_trans_pcie_tx_free(struct iwl_trans *trans) | ||
523 | { | ||
524 | int txq_id; | ||
525 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
526 | |||
527 | /* Tx queues */ | ||
528 | if (trans_pcie->txq) { | ||
529 | for (txq_id = 0; | ||
530 | txq_id < trans->cfg->base_params->num_of_queues; txq_id++) | ||
531 | iwl_tx_queue_free(trans, txq_id); | ||
532 | } | ||
533 | |||
534 | kfree(trans_pcie->txq); | ||
535 | trans_pcie->txq = NULL; | ||
536 | |||
537 | iwlagn_free_dma_ptr(trans, &trans_pcie->kw); | ||
538 | |||
539 | iwlagn_free_dma_ptr(trans, &trans_pcie->scd_bc_tbls); | ||
540 | } | ||
541 | |||
542 | /** | ||
543 | * iwl_trans_tx_alloc - allocate TX context | ||
544 | * Allocate all Tx DMA structures and initialize them | ||
545 | * | ||
546 | * @param priv | ||
547 | * @return error code | ||
548 | */ | ||
549 | static int iwl_trans_tx_alloc(struct iwl_trans *trans) | ||
550 | { | ||
551 | int ret; | ||
552 | int txq_id, slots_num; | ||
553 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
554 | |||
555 | u16 scd_bc_tbls_size = trans->cfg->base_params->num_of_queues * | ||
556 | sizeof(struct iwlagn_scd_bc_tbl); | ||
557 | |||
558 | /*It is not allowed to alloc twice, so warn when this happens. | ||
559 | * We cannot rely on the previous allocation, so free and fail */ | ||
560 | if (WARN_ON(trans_pcie->txq)) { | ||
561 | ret = -EINVAL; | ||
562 | goto error; | ||
563 | } | ||
564 | |||
565 | ret = iwlagn_alloc_dma_ptr(trans, &trans_pcie->scd_bc_tbls, | ||
566 | scd_bc_tbls_size); | ||
567 | if (ret) { | ||
568 | IWL_ERR(trans, "Scheduler BC Table allocation failed\n"); | ||
569 | goto error; | ||
570 | } | ||
571 | |||
572 | /* Alloc keep-warm buffer */ | ||
573 | ret = iwlagn_alloc_dma_ptr(trans, &trans_pcie->kw, IWL_KW_SIZE); | ||
574 | if (ret) { | ||
575 | IWL_ERR(trans, "Keep Warm allocation failed\n"); | ||
576 | goto error; | ||
577 | } | ||
578 | |||
579 | trans_pcie->txq = kcalloc(trans->cfg->base_params->num_of_queues, | ||
580 | sizeof(struct iwl_tx_queue), GFP_KERNEL); | ||
581 | if (!trans_pcie->txq) { | ||
582 | IWL_ERR(trans, "Not enough memory for txq\n"); | ||
583 | ret = ENOMEM; | ||
584 | goto error; | ||
585 | } | ||
586 | |||
587 | /* Alloc and init all Tx queues, including the command queue (#4/#9) */ | ||
588 | for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues; | ||
589 | txq_id++) { | ||
590 | slots_num = (txq_id == trans_pcie->cmd_queue) ? | ||
591 | TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; | ||
592 | ret = iwl_trans_txq_alloc(trans, &trans_pcie->txq[txq_id], | ||
593 | slots_num, txq_id); | ||
594 | if (ret) { | ||
595 | IWL_ERR(trans, "Tx %d queue alloc failed\n", txq_id); | ||
596 | goto error; | ||
597 | } | ||
598 | } | ||
599 | |||
600 | return 0; | ||
601 | |||
602 | error: | ||
603 | iwl_trans_pcie_tx_free(trans); | ||
604 | |||
605 | return ret; | ||
606 | } | ||
607 | static int iwl_tx_init(struct iwl_trans *trans) | ||
608 | { | ||
609 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
610 | int ret; | ||
611 | int txq_id, slots_num; | ||
612 | unsigned long flags; | ||
613 | bool alloc = false; | ||
614 | |||
615 | if (!trans_pcie->txq) { | ||
616 | ret = iwl_trans_tx_alloc(trans); | ||
617 | if (ret) | ||
618 | goto error; | ||
619 | alloc = true; | ||
620 | } | ||
621 | |||
622 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | ||
623 | |||
624 | /* Turn off all Tx DMA fifos */ | ||
625 | iwl_write_prph(trans, SCD_TXFACT, 0); | ||
626 | |||
627 | /* Tell NIC where to find the "keep warm" buffer */ | ||
628 | iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG, | ||
629 | trans_pcie->kw.dma >> 4); | ||
630 | |||
631 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | ||
632 | |||
633 | /* Alloc and init all Tx queues, including the command queue (#4/#9) */ | ||
634 | for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues; | ||
635 | txq_id++) { | ||
636 | slots_num = (txq_id == trans_pcie->cmd_queue) ? | ||
637 | TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; | ||
638 | ret = iwl_trans_txq_init(trans, &trans_pcie->txq[txq_id], | ||
639 | slots_num, txq_id); | ||
640 | if (ret) { | ||
641 | IWL_ERR(trans, "Tx %d queue init failed\n", txq_id); | ||
642 | goto error; | ||
643 | } | ||
644 | } | ||
645 | |||
646 | return 0; | ||
647 | error: | ||
648 | /*Upon error, free only if we allocated something */ | ||
649 | if (alloc) | ||
650 | iwl_trans_pcie_tx_free(trans); | ||
651 | return ret; | ||
652 | } | ||
653 | |||
654 | static void iwl_set_pwr_vmain(struct iwl_trans *trans) | ||
655 | { | 79 | { |
656 | /* | 80 | /* |
657 | * (for documentation purposes) | 81 | * (for documentation purposes) |
@@ -673,18 +97,11 @@ static void iwl_set_pwr_vmain(struct iwl_trans *trans) | |||
673 | #define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01 | 97 | #define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01 |
674 | #define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02 | 98 | #define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02 |
675 | 99 | ||
676 | static u16 iwl_pciexp_link_ctrl(struct iwl_trans *trans) | 100 | static void iwl_pcie_apm_config(struct iwl_trans *trans) |
677 | { | 101 | { |
678 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 102 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
679 | u16 pci_lnk_ctl; | 103 | u16 lctl; |
680 | |||
681 | pcie_capability_read_word(trans_pcie->pci_dev, PCI_EXP_LNKCTL, | ||
682 | &pci_lnk_ctl); | ||
683 | return pci_lnk_ctl; | ||
684 | } | ||
685 | 104 | ||
686 | static void iwl_apm_config(struct iwl_trans *trans) | ||
687 | { | ||
688 | /* | 105 | /* |
689 | * HW bug W/A for instability in PCIe bus L0S->L1 transition. | 106 | * HW bug W/A for instability in PCIe bus L0S->L1 transition. |
690 | * Check if BIOS (or OS) enabled L1-ASPM on this device. | 107 | * Check if BIOS (or OS) enabled L1-ASPM on this device. |
@@ -693,29 +110,27 @@ static void iwl_apm_config(struct iwl_trans *trans) | |||
693 | * If not (unlikely), enable L0S, so there is at least some | 110 | * If not (unlikely), enable L0S, so there is at least some |
694 | * power savings, even without L1. | 111 | * power savings, even without L1. |
695 | */ | 112 | */ |
696 | u16 lctl = iwl_pciexp_link_ctrl(trans); | 113 | pcie_capability_read_word(trans_pcie->pci_dev, PCI_EXP_LNKCTL, &lctl); |
697 | 114 | ||
698 | if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == | 115 | if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == |
699 | PCI_CFG_LINK_CTRL_VAL_L1_EN) { | 116 | PCI_CFG_LINK_CTRL_VAL_L1_EN) { |
700 | /* L1-ASPM enabled; disable(!) L0S */ | 117 | /* L1-ASPM enabled; disable(!) L0S */ |
701 | iwl_set_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); | 118 | iwl_set_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); |
702 | dev_printk(KERN_INFO, trans->dev, | 119 | dev_info(trans->dev, "L1 Enabled; Disabling L0S\n"); |
703 | "L1 Enabled; Disabling L0S\n"); | ||
704 | } else { | 120 | } else { |
705 | /* L1-ASPM disabled; enable(!) L0S */ | 121 | /* L1-ASPM disabled; enable(!) L0S */ |
706 | iwl_clear_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); | 122 | iwl_clear_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); |
707 | dev_printk(KERN_INFO, trans->dev, | 123 | dev_info(trans->dev, "L1 Disabled; Enabling L0S\n"); |
708 | "L1 Disabled; Enabling L0S\n"); | ||
709 | } | 124 | } |
710 | trans->pm_support = !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN); | 125 | trans->pm_support = !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN); |
711 | } | 126 | } |
712 | 127 | ||
713 | /* | 128 | /* |
714 | * Start up NIC's basic functionality after it has been reset | 129 | * Start up NIC's basic functionality after it has been reset |
715 | * (e.g. after platform boot, or shutdown via iwl_apm_stop()) | 130 | * (e.g. after platform boot, or shutdown via iwl_pcie_apm_stop()) |
716 | * NOTE: This does not load uCode nor start the embedded processor | 131 | * NOTE: This does not load uCode nor start the embedded processor |
717 | */ | 132 | */ |
718 | static int iwl_apm_init(struct iwl_trans *trans) | 133 | static int iwl_pcie_apm_init(struct iwl_trans *trans) |
719 | { | 134 | { |
720 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 135 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
721 | int ret = 0; | 136 | int ret = 0; |
@@ -747,7 +162,7 @@ static int iwl_apm_init(struct iwl_trans *trans) | |||
747 | iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, | 162 | iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, |
748 | CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); | 163 | CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); |
749 | 164 | ||
750 | iwl_apm_config(trans); | 165 | iwl_pcie_apm_config(trans); |
751 | 166 | ||
752 | /* Configure analog phase-lock-loop before activating to D0A */ | 167 | /* Configure analog phase-lock-loop before activating to D0A */ |
753 | if (trans->cfg->base_params->pll_cfg_val) | 168 | if (trans->cfg->base_params->pll_cfg_val) |
@@ -793,7 +208,7 @@ out: | |||
793 | return ret; | 208 | return ret; |
794 | } | 209 | } |
795 | 210 | ||
796 | static int iwl_apm_stop_master(struct iwl_trans *trans) | 211 | static int iwl_pcie_apm_stop_master(struct iwl_trans *trans) |
797 | { | 212 | { |
798 | int ret = 0; | 213 | int ret = 0; |
799 | 214 | ||
@@ -811,7 +226,7 @@ static int iwl_apm_stop_master(struct iwl_trans *trans) | |||
811 | return ret; | 226 | return ret; |
812 | } | 227 | } |
813 | 228 | ||
814 | static void iwl_apm_stop(struct iwl_trans *trans) | 229 | static void iwl_pcie_apm_stop(struct iwl_trans *trans) |
815 | { | 230 | { |
816 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 231 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
817 | IWL_DEBUG_INFO(trans, "Stop card, put in low power state\n"); | 232 | IWL_DEBUG_INFO(trans, "Stop card, put in low power state\n"); |
@@ -819,7 +234,7 @@ static void iwl_apm_stop(struct iwl_trans *trans) | |||
819 | clear_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status); | 234 | clear_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status); |
820 | 235 | ||
821 | /* Stop device's DMA activity */ | 236 | /* Stop device's DMA activity */ |
822 | iwl_apm_stop_master(trans); | 237 | iwl_pcie_apm_stop_master(trans); |
823 | 238 | ||
824 | /* Reset the entire device */ | 239 | /* Reset the entire device */ |
825 | iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); | 240 | iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); |
@@ -834,29 +249,29 @@ static void iwl_apm_stop(struct iwl_trans *trans) | |||
834 | CSR_GP_CNTRL_REG_FLAG_INIT_DONE); | 249 | CSR_GP_CNTRL_REG_FLAG_INIT_DONE); |
835 | } | 250 | } |
836 | 251 | ||
837 | static int iwl_nic_init(struct iwl_trans *trans) | 252 | static int iwl_pcie_nic_init(struct iwl_trans *trans) |
838 | { | 253 | { |
839 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 254 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
840 | unsigned long flags; | 255 | unsigned long flags; |
841 | 256 | ||
842 | /* nic_init */ | 257 | /* nic_init */ |
843 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | 258 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); |
844 | iwl_apm_init(trans); | 259 | iwl_pcie_apm_init(trans); |
845 | 260 | ||
846 | /* Set interrupt coalescing calibration timer to default (512 usecs) */ | 261 | /* Set interrupt coalescing calibration timer to default (512 usecs) */ |
847 | iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF); | 262 | iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF); |
848 | 263 | ||
849 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 264 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); |
850 | 265 | ||
851 | iwl_set_pwr_vmain(trans); | 266 | iwl_pcie_set_pwr_vmain(trans); |
852 | 267 | ||
853 | iwl_op_mode_nic_config(trans->op_mode); | 268 | iwl_op_mode_nic_config(trans->op_mode); |
854 | 269 | ||
855 | /* Allocate the RX queue, or reset if it is already allocated */ | 270 | /* Allocate the RX queue, or reset if it is already allocated */ |
856 | iwl_rx_init(trans); | 271 | iwl_pcie_rx_init(trans); |
857 | 272 | ||
858 | /* Allocate or reset and init all Tx and Command queues */ | 273 | /* Allocate or reset and init all Tx and Command queues */ |
859 | if (iwl_tx_init(trans)) | 274 | if (iwl_pcie_tx_init(trans)) |
860 | return -ENOMEM; | 275 | return -ENOMEM; |
861 | 276 | ||
862 | if (trans->cfg->base_params->shadow_reg_enable) { | 277 | if (trans->cfg->base_params->shadow_reg_enable) { |
@@ -871,7 +286,7 @@ static int iwl_nic_init(struct iwl_trans *trans) | |||
871 | #define HW_READY_TIMEOUT (50) | 286 | #define HW_READY_TIMEOUT (50) |
872 | 287 | ||
873 | /* Note: returns poll_bit return value, which is >= 0 if success */ | 288 | /* Note: returns poll_bit return value, which is >= 0 if success */ |
874 | static int iwl_set_hw_ready(struct iwl_trans *trans) | 289 | static int iwl_pcie_set_hw_ready(struct iwl_trans *trans) |
875 | { | 290 | { |
876 | int ret; | 291 | int ret; |
877 | 292 | ||
@@ -889,14 +304,14 @@ static int iwl_set_hw_ready(struct iwl_trans *trans) | |||
889 | } | 304 | } |
890 | 305 | ||
891 | /* Note: returns standard 0/-ERROR code */ | 306 | /* Note: returns standard 0/-ERROR code */ |
892 | static int iwl_prepare_card_hw(struct iwl_trans *trans) | 307 | static int iwl_pcie_prepare_card_hw(struct iwl_trans *trans) |
893 | { | 308 | { |
894 | int ret; | 309 | int ret; |
895 | int t = 0; | 310 | int t = 0; |
896 | 311 | ||
897 | IWL_DEBUG_INFO(trans, "iwl_trans_prepare_card_hw enter\n"); | 312 | IWL_DEBUG_INFO(trans, "iwl_trans_prepare_card_hw enter\n"); |
898 | 313 | ||
899 | ret = iwl_set_hw_ready(trans); | 314 | ret = iwl_pcie_set_hw_ready(trans); |
900 | /* If the card is ready, exit 0 */ | 315 | /* If the card is ready, exit 0 */ |
901 | if (ret >= 0) | 316 | if (ret >= 0) |
902 | return 0; | 317 | return 0; |
@@ -906,7 +321,7 @@ static int iwl_prepare_card_hw(struct iwl_trans *trans) | |||
906 | CSR_HW_IF_CONFIG_REG_PREPARE); | 321 | CSR_HW_IF_CONFIG_REG_PREPARE); |
907 | 322 | ||
908 | do { | 323 | do { |
909 | ret = iwl_set_hw_ready(trans); | 324 | ret = iwl_pcie_set_hw_ready(trans); |
910 | if (ret >= 0) | 325 | if (ret >= 0) |
911 | return 0; | 326 | return 0; |
912 | 327 | ||
@@ -920,7 +335,7 @@ static int iwl_prepare_card_hw(struct iwl_trans *trans) | |||
920 | /* | 335 | /* |
921 | * ucode | 336 | * ucode |
922 | */ | 337 | */ |
923 | static int iwl_load_firmware_chunk(struct iwl_trans *trans, u32 dst_addr, | 338 | static int iwl_pcie_load_firmware_chunk(struct iwl_trans *trans, u32 dst_addr, |
924 | dma_addr_t phy_addr, u32 byte_cnt) | 339 | dma_addr_t phy_addr, u32 byte_cnt) |
925 | { | 340 | { |
926 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 341 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
@@ -967,7 +382,7 @@ static int iwl_load_firmware_chunk(struct iwl_trans *trans, u32 dst_addr, | |||
967 | return 0; | 382 | return 0; |
968 | } | 383 | } |
969 | 384 | ||
970 | static int iwl_load_section(struct iwl_trans *trans, u8 section_num, | 385 | static int iwl_pcie_load_section(struct iwl_trans *trans, u8 section_num, |
971 | const struct fw_desc *section) | 386 | const struct fw_desc *section) |
972 | { | 387 | { |
973 | u8 *v_addr; | 388 | u8 *v_addr; |
@@ -988,8 +403,9 @@ static int iwl_load_section(struct iwl_trans *trans, u8 section_num, | |||
988 | copy_size = min_t(u32, PAGE_SIZE, section->len - offset); | 403 | copy_size = min_t(u32, PAGE_SIZE, section->len - offset); |
989 | 404 | ||
990 | memcpy(v_addr, (u8 *)section->data + offset, copy_size); | 405 | memcpy(v_addr, (u8 *)section->data + offset, copy_size); |
991 | ret = iwl_load_firmware_chunk(trans, section->offset + offset, | 406 | ret = iwl_pcie_load_firmware_chunk(trans, |
992 | p_addr, copy_size); | 407 | section->offset + offset, |
408 | p_addr, copy_size); | ||
993 | if (ret) { | 409 | if (ret) { |
994 | IWL_ERR(trans, | 410 | IWL_ERR(trans, |
995 | "Could not load the [%d] uCode section\n", | 411 | "Could not load the [%d] uCode section\n", |
@@ -1002,7 +418,7 @@ static int iwl_load_section(struct iwl_trans *trans, u8 section_num, | |||
1002 | return ret; | 418 | return ret; |
1003 | } | 419 | } |
1004 | 420 | ||
1005 | static int iwl_load_given_ucode(struct iwl_trans *trans, | 421 | static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, |
1006 | const struct fw_img *image) | 422 | const struct fw_img *image) |
1007 | { | 423 | { |
1008 | int i, ret = 0; | 424 | int i, ret = 0; |
@@ -1011,7 +427,7 @@ static int iwl_load_given_ucode(struct iwl_trans *trans, | |||
1011 | if (!image->sec[i].data) | 427 | if (!image->sec[i].data) |
1012 | break; | 428 | break; |
1013 | 429 | ||
1014 | ret = iwl_load_section(trans, i, &image->sec[i]); | 430 | ret = iwl_pcie_load_section(trans, i, &image->sec[i]); |
1015 | if (ret) | 431 | if (ret) |
1016 | return ret; | 432 | return ret; |
1017 | } | 433 | } |
@@ -1025,15 +441,18 @@ static int iwl_load_given_ucode(struct iwl_trans *trans, | |||
1025 | static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, | 441 | static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, |
1026 | const struct fw_img *fw) | 442 | const struct fw_img *fw) |
1027 | { | 443 | { |
444 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1028 | int ret; | 445 | int ret; |
1029 | bool hw_rfkill; | 446 | bool hw_rfkill; |
1030 | 447 | ||
1031 | /* This may fail if AMT took ownership of the device */ | 448 | /* This may fail if AMT took ownership of the device */ |
1032 | if (iwl_prepare_card_hw(trans)) { | 449 | if (iwl_pcie_prepare_card_hw(trans)) { |
1033 | IWL_WARN(trans, "Exit HW not ready\n"); | 450 | IWL_WARN(trans, "Exit HW not ready\n"); |
1034 | return -EIO; | 451 | return -EIO; |
1035 | } | 452 | } |
1036 | 453 | ||
454 | clear_bit(STATUS_FW_ERROR, &trans_pcie->status); | ||
455 | |||
1037 | iwl_enable_rfkill_int(trans); | 456 | iwl_enable_rfkill_int(trans); |
1038 | 457 | ||
1039 | /* If platform's RF_KILL switch is NOT set to KILL */ | 458 | /* If platform's RF_KILL switch is NOT set to KILL */ |
@@ -1044,7 +463,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, | |||
1044 | 463 | ||
1045 | iwl_write32(trans, CSR_INT, 0xFFFFFFFF); | 464 | iwl_write32(trans, CSR_INT, 0xFFFFFFFF); |
1046 | 465 | ||
1047 | ret = iwl_nic_init(trans); | 466 | ret = iwl_pcie_nic_init(trans); |
1048 | if (ret) { | 467 | if (ret) { |
1049 | IWL_ERR(trans, "Unable to init nic\n"); | 468 | IWL_ERR(trans, "Unable to init nic\n"); |
1050 | return ret; | 469 | return ret; |
@@ -1064,125 +483,13 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, | |||
1064 | iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | 483 | iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); |
1065 | 484 | ||
1066 | /* Load the given image to the HW */ | 485 | /* Load the given image to the HW */ |
1067 | return iwl_load_given_ucode(trans, fw); | 486 | return iwl_pcie_load_given_ucode(trans, fw); |
1068 | } | 487 | } |
1069 | 488 | ||
1070 | /* | 489 | static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans, u32 scd_addr) |
1071 | * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask | ||
1072 | */ | ||
1073 | static void iwl_trans_txq_set_sched(struct iwl_trans *trans, u32 mask) | ||
1074 | { | 490 | { |
1075 | struct iwl_trans_pcie __maybe_unused *trans_pcie = | 491 | iwl_pcie_reset_ict(trans); |
1076 | IWL_TRANS_GET_PCIE_TRANS(trans); | 492 | iwl_pcie_tx_start(trans, scd_addr); |
1077 | |||
1078 | iwl_write_prph(trans, SCD_TXFACT, mask); | ||
1079 | } | ||
1080 | |||
1081 | static void iwl_tx_start(struct iwl_trans *trans) | ||
1082 | { | ||
1083 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1084 | u32 a; | ||
1085 | int chan; | ||
1086 | u32 reg_val; | ||
1087 | |||
1088 | /* make sure all queue are not stopped/used */ | ||
1089 | memset(trans_pcie->queue_stopped, 0, sizeof(trans_pcie->queue_stopped)); | ||
1090 | memset(trans_pcie->queue_used, 0, sizeof(trans_pcie->queue_used)); | ||
1091 | |||
1092 | trans_pcie->scd_base_addr = | ||
1093 | iwl_read_prph(trans, SCD_SRAM_BASE_ADDR); | ||
1094 | a = trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_LOWER_BOUND; | ||
1095 | /* reset conext data memory */ | ||
1096 | for (; a < trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_UPPER_BOUND; | ||
1097 | a += 4) | ||
1098 | iwl_write_targ_mem(trans, a, 0); | ||
1099 | /* reset tx status memory */ | ||
1100 | for (; a < trans_pcie->scd_base_addr + SCD_TX_STTS_MEM_UPPER_BOUND; | ||
1101 | a += 4) | ||
1102 | iwl_write_targ_mem(trans, a, 0); | ||
1103 | for (; a < trans_pcie->scd_base_addr + | ||
1104 | SCD_TRANS_TBL_OFFSET_QUEUE( | ||
1105 | trans->cfg->base_params->num_of_queues); | ||
1106 | a += 4) | ||
1107 | iwl_write_targ_mem(trans, a, 0); | ||
1108 | |||
1109 | iwl_write_prph(trans, SCD_DRAM_BASE_ADDR, | ||
1110 | trans_pcie->scd_bc_tbls.dma >> 10); | ||
1111 | |||
1112 | /* The chain extension of the SCD doesn't work well. This feature is | ||
1113 | * enabled by default by the HW, so we need to disable it manually. | ||
1114 | */ | ||
1115 | iwl_write_prph(trans, SCD_CHAINEXT_EN, 0); | ||
1116 | |||
1117 | iwl_trans_ac_txq_enable(trans, trans_pcie->cmd_queue, | ||
1118 | trans_pcie->cmd_fifo); | ||
1119 | |||
1120 | /* Activate all Tx DMA/FIFO channels */ | ||
1121 | iwl_trans_txq_set_sched(trans, IWL_MASK(0, 7)); | ||
1122 | |||
1123 | /* Enable DMA channel */ | ||
1124 | for (chan = 0; chan < FH_TCSR_CHNL_NUM ; chan++) | ||
1125 | iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(chan), | ||
1126 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | | ||
1127 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE); | ||
1128 | |||
1129 | /* Update FH chicken bits */ | ||
1130 | reg_val = iwl_read_direct32(trans, FH_TX_CHICKEN_BITS_REG); | ||
1131 | iwl_write_direct32(trans, FH_TX_CHICKEN_BITS_REG, | ||
1132 | reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); | ||
1133 | |||
1134 | /* Enable L1-Active */ | ||
1135 | iwl_clear_bits_prph(trans, APMG_PCIDEV_STT_REG, | ||
1136 | APMG_PCIDEV_STT_VAL_L1_ACT_DIS); | ||
1137 | } | ||
1138 | |||
1139 | static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans) | ||
1140 | { | ||
1141 | iwl_reset_ict(trans); | ||
1142 | iwl_tx_start(trans); | ||
1143 | } | ||
1144 | |||
1145 | /** | ||
1146 | * iwlagn_txq_ctx_stop - Stop all Tx DMA channels | ||
1147 | */ | ||
1148 | static int iwl_trans_tx_stop(struct iwl_trans *trans) | ||
1149 | { | ||
1150 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1151 | int ch, txq_id, ret; | ||
1152 | unsigned long flags; | ||
1153 | |||
1154 | /* Turn off all Tx DMA fifos */ | ||
1155 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | ||
1156 | |||
1157 | iwl_trans_txq_set_sched(trans, 0); | ||
1158 | |||
1159 | /* Stop each Tx DMA channel, and wait for it to be idle */ | ||
1160 | for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) { | ||
1161 | iwl_write_direct32(trans, | ||
1162 | FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0); | ||
1163 | ret = iwl_poll_direct_bit(trans, FH_TSSR_TX_STATUS_REG, | ||
1164 | FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), 1000); | ||
1165 | if (ret < 0) | ||
1166 | IWL_ERR(trans, | ||
1167 | "Failing on timeout while stopping DMA channel %d [0x%08x]\n", | ||
1168 | ch, | ||
1169 | iwl_read_direct32(trans, | ||
1170 | FH_TSSR_TX_STATUS_REG)); | ||
1171 | } | ||
1172 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | ||
1173 | |||
1174 | if (!trans_pcie->txq) { | ||
1175 | IWL_WARN(trans, | ||
1176 | "Stopping tx queues that aren't allocated...\n"); | ||
1177 | return 0; | ||
1178 | } | ||
1179 | |||
1180 | /* Unmap DMA from host system and free skb's */ | ||
1181 | for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues; | ||
1182 | txq_id++) | ||
1183 | iwl_tx_queue_unmap(trans, txq_id); | ||
1184 | |||
1185 | return 0; | ||
1186 | } | 493 | } |
1187 | 494 | ||
1188 | static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | 495 | static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) |
@@ -1196,7 +503,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
1196 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 503 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); |
1197 | 504 | ||
1198 | /* device going down, Stop using ICT table */ | 505 | /* device going down, Stop using ICT table */ |
1199 | iwl_disable_ict(trans); | 506 | iwl_pcie_disable_ict(trans); |
1200 | 507 | ||
1201 | /* | 508 | /* |
1202 | * If a HW restart happens during firmware loading, | 509 | * If a HW restart happens during firmware loading, |
@@ -1206,8 +513,8 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
1206 | * already dead. | 513 | * already dead. |
1207 | */ | 514 | */ |
1208 | if (test_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status)) { | 515 | if (test_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status)) { |
1209 | iwl_trans_tx_stop(trans); | 516 | iwl_pcie_tx_stop(trans); |
1210 | iwl_trans_rx_stop(trans); | 517 | iwl_pcie_rx_stop(trans); |
1211 | 518 | ||
1212 | /* Power-down device's busmaster DMA clocks */ | 519 | /* Power-down device's busmaster DMA clocks */ |
1213 | iwl_write_prph(trans, APMG_CLK_DIS_REG, | 520 | iwl_write_prph(trans, APMG_CLK_DIS_REG, |
@@ -1220,7 +527,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
1220 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | 527 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
1221 | 528 | ||
1222 | /* Stop the device, and put it in low power state */ | 529 | /* Stop the device, and put it in low power state */ |
1223 | iwl_apm_stop(trans); | 530 | iwl_pcie_apm_stop(trans); |
1224 | 531 | ||
1225 | /* Upon stop, the APM issues an interrupt if HW RF kill is set. | 532 | /* Upon stop, the APM issues an interrupt if HW RF kill is set. |
1226 | * Clean again the interrupt here | 533 | * Clean again the interrupt here |
@@ -1245,6 +552,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) | |||
1245 | clear_bit(STATUS_INT_ENABLED, &trans_pcie->status); | 552 | clear_bit(STATUS_INT_ENABLED, &trans_pcie->status); |
1246 | clear_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status); | 553 | clear_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status); |
1247 | clear_bit(STATUS_TPOWER_PMI, &trans_pcie->status); | 554 | clear_bit(STATUS_TPOWER_PMI, &trans_pcie->status); |
555 | clear_bit(STATUS_RFKILL, &trans_pcie->status); | ||
1248 | } | 556 | } |
1249 | 557 | ||
1250 | static void iwl_trans_pcie_wowlan_suspend(struct iwl_trans *trans) | 558 | static void iwl_trans_pcie_wowlan_suspend(struct iwl_trans *trans) |
@@ -1258,171 +566,6 @@ static void iwl_trans_pcie_wowlan_suspend(struct iwl_trans *trans) | |||
1258 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | 566 | CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); |
1259 | } | 567 | } |
1260 | 568 | ||
1261 | static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | ||
1262 | struct iwl_device_cmd *dev_cmd, int txq_id) | ||
1263 | { | ||
1264 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1265 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
1266 | struct iwl_tx_cmd *tx_cmd = (struct iwl_tx_cmd *) dev_cmd->payload; | ||
1267 | struct iwl_cmd_meta *out_meta; | ||
1268 | struct iwl_tx_queue *txq; | ||
1269 | struct iwl_queue *q; | ||
1270 | dma_addr_t phys_addr = 0; | ||
1271 | dma_addr_t txcmd_phys; | ||
1272 | dma_addr_t scratch_phys; | ||
1273 | u16 len, firstlen, secondlen; | ||
1274 | u8 wait_write_ptr = 0; | ||
1275 | __le16 fc = hdr->frame_control; | ||
1276 | u8 hdr_len = ieee80211_hdrlen(fc); | ||
1277 | u16 __maybe_unused wifi_seq; | ||
1278 | |||
1279 | txq = &trans_pcie->txq[txq_id]; | ||
1280 | q = &txq->q; | ||
1281 | |||
1282 | if (unlikely(!test_bit(txq_id, trans_pcie->queue_used))) { | ||
1283 | WARN_ON_ONCE(1); | ||
1284 | return -EINVAL; | ||
1285 | } | ||
1286 | |||
1287 | spin_lock(&txq->lock); | ||
1288 | |||
1289 | /* In AGG mode, the index in the ring must correspond to the WiFi | ||
1290 | * sequence number. This is a HW requirements to help the SCD to parse | ||
1291 | * the BA. | ||
1292 | * Check here that the packets are in the right place on the ring. | ||
1293 | */ | ||
1294 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
1295 | wifi_seq = SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl)); | ||
1296 | WARN_ONCE((iwl_read_prph(trans, SCD_AGGR_SEL) & BIT(txq_id)) && | ||
1297 | ((wifi_seq & 0xff) != q->write_ptr), | ||
1298 | "Q: %d WiFi Seq %d tfdNum %d", | ||
1299 | txq_id, wifi_seq, q->write_ptr); | ||
1300 | #endif | ||
1301 | |||
1302 | /* Set up driver data for this TFD */ | ||
1303 | txq->entries[q->write_ptr].skb = skb; | ||
1304 | txq->entries[q->write_ptr].cmd = dev_cmd; | ||
1305 | |||
1306 | dev_cmd->hdr.cmd = REPLY_TX; | ||
1307 | dev_cmd->hdr.sequence = | ||
1308 | cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | | ||
1309 | INDEX_TO_SEQ(q->write_ptr))); | ||
1310 | |||
1311 | /* Set up first empty entry in queue's array of Tx/cmd buffers */ | ||
1312 | out_meta = &txq->entries[q->write_ptr].meta; | ||
1313 | |||
1314 | /* | ||
1315 | * Use the first empty entry in this queue's command buffer array | ||
1316 | * to contain the Tx command and MAC header concatenated together | ||
1317 | * (payload data will be in another buffer). | ||
1318 | * Size of this varies, due to varying MAC header length. | ||
1319 | * If end is not dword aligned, we'll have 2 extra bytes at the end | ||
1320 | * of the MAC header (device reads on dword boundaries). | ||
1321 | * We'll tell device about this padding later. | ||
1322 | */ | ||
1323 | len = sizeof(struct iwl_tx_cmd) + | ||
1324 | sizeof(struct iwl_cmd_header) + hdr_len; | ||
1325 | firstlen = (len + 3) & ~3; | ||
1326 | |||
1327 | /* Tell NIC about any 2-byte padding after MAC header */ | ||
1328 | if (firstlen != len) | ||
1329 | tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK; | ||
1330 | |||
1331 | /* Physical address of this Tx command's header (not MAC header!), | ||
1332 | * within command buffer array. */ | ||
1333 | txcmd_phys = dma_map_single(trans->dev, | ||
1334 | &dev_cmd->hdr, firstlen, | ||
1335 | DMA_BIDIRECTIONAL); | ||
1336 | if (unlikely(dma_mapping_error(trans->dev, txcmd_phys))) | ||
1337 | goto out_err; | ||
1338 | dma_unmap_addr_set(out_meta, mapping, txcmd_phys); | ||
1339 | dma_unmap_len_set(out_meta, len, firstlen); | ||
1340 | |||
1341 | if (!ieee80211_has_morefrags(fc)) { | ||
1342 | txq->need_update = 1; | ||
1343 | } else { | ||
1344 | wait_write_ptr = 1; | ||
1345 | txq->need_update = 0; | ||
1346 | } | ||
1347 | |||
1348 | /* Set up TFD's 2nd entry to point directly to remainder of skb, | ||
1349 | * if any (802.11 null frames have no payload). */ | ||
1350 | secondlen = skb->len - hdr_len; | ||
1351 | if (secondlen > 0) { | ||
1352 | phys_addr = dma_map_single(trans->dev, skb->data + hdr_len, | ||
1353 | secondlen, DMA_TO_DEVICE); | ||
1354 | if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { | ||
1355 | dma_unmap_single(trans->dev, | ||
1356 | dma_unmap_addr(out_meta, mapping), | ||
1357 | dma_unmap_len(out_meta, len), | ||
1358 | DMA_BIDIRECTIONAL); | ||
1359 | goto out_err; | ||
1360 | } | ||
1361 | } | ||
1362 | |||
1363 | /* Attach buffers to TFD */ | ||
1364 | iwlagn_txq_attach_buf_to_tfd(trans, txq, txcmd_phys, firstlen, 1); | ||
1365 | if (secondlen > 0) | ||
1366 | iwlagn_txq_attach_buf_to_tfd(trans, txq, phys_addr, | ||
1367 | secondlen, 0); | ||
1368 | |||
1369 | scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) + | ||
1370 | offsetof(struct iwl_tx_cmd, scratch); | ||
1371 | |||
1372 | /* take back ownership of DMA buffer to enable update */ | ||
1373 | dma_sync_single_for_cpu(trans->dev, txcmd_phys, firstlen, | ||
1374 | DMA_BIDIRECTIONAL); | ||
1375 | tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); | ||
1376 | tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); | ||
1377 | |||
1378 | IWL_DEBUG_TX(trans, "sequence nr = 0X%x\n", | ||
1379 | le16_to_cpu(dev_cmd->hdr.sequence)); | ||
1380 | IWL_DEBUG_TX(trans, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags)); | ||
1381 | |||
1382 | /* Set up entry for this TFD in Tx byte-count array */ | ||
1383 | iwl_trans_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); | ||
1384 | |||
1385 | dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen, | ||
1386 | DMA_BIDIRECTIONAL); | ||
1387 | |||
1388 | trace_iwlwifi_dev_tx(trans->dev, skb, | ||
1389 | &txq->tfds[txq->q.write_ptr], | ||
1390 | sizeof(struct iwl_tfd), | ||
1391 | &dev_cmd->hdr, firstlen, | ||
1392 | skb->data + hdr_len, secondlen); | ||
1393 | trace_iwlwifi_dev_tx_data(trans->dev, skb, | ||
1394 | skb->data + hdr_len, secondlen); | ||
1395 | |||
1396 | /* start timer if queue currently empty */ | ||
1397 | if (txq->need_update && q->read_ptr == q->write_ptr && | ||
1398 | trans_pcie->wd_timeout) | ||
1399 | mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); | ||
1400 | |||
1401 | /* Tell device the write index *just past* this latest filled TFD */ | ||
1402 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); | ||
1403 | iwl_txq_update_write_ptr(trans, txq); | ||
1404 | |||
1405 | /* | ||
1406 | * At this point the frame is "transmitted" successfully | ||
1407 | * and we will get a TX status notification eventually, | ||
1408 | * regardless of the value of ret. "ret" only indicates | ||
1409 | * whether or not we should update the write pointer. | ||
1410 | */ | ||
1411 | if (iwl_queue_space(q) < q->high_mark) { | ||
1412 | if (wait_write_ptr) { | ||
1413 | txq->need_update = 1; | ||
1414 | iwl_txq_update_write_ptr(trans, txq); | ||
1415 | } else { | ||
1416 | iwl_stop_queue(trans, txq); | ||
1417 | } | ||
1418 | } | ||
1419 | spin_unlock(&txq->lock); | ||
1420 | return 0; | ||
1421 | out_err: | ||
1422 | spin_unlock(&txq->lock); | ||
1423 | return -1; | ||
1424 | } | ||
1425 | |||
1426 | static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) | 569 | static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) |
1427 | { | 570 | { |
1428 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 571 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
@@ -1433,29 +576,28 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) | |||
1433 | 576 | ||
1434 | if (!trans_pcie->irq_requested) { | 577 | if (!trans_pcie->irq_requested) { |
1435 | tasklet_init(&trans_pcie->irq_tasklet, (void (*)(unsigned long)) | 578 | tasklet_init(&trans_pcie->irq_tasklet, (void (*)(unsigned long)) |
1436 | iwl_irq_tasklet, (unsigned long)trans); | 579 | iwl_pcie_tasklet, (unsigned long)trans); |
1437 | 580 | ||
1438 | iwl_alloc_isr_ict(trans); | 581 | iwl_pcie_alloc_ict(trans); |
1439 | 582 | ||
1440 | err = request_irq(trans_pcie->irq, iwl_isr_ict, IRQF_SHARED, | 583 | err = request_irq(trans_pcie->irq, iwl_pcie_isr_ict, |
1441 | DRV_NAME, trans); | 584 | IRQF_SHARED, DRV_NAME, trans); |
1442 | if (err) { | 585 | if (err) { |
1443 | IWL_ERR(trans, "Error allocating IRQ %d\n", | 586 | IWL_ERR(trans, "Error allocating IRQ %d\n", |
1444 | trans_pcie->irq); | 587 | trans_pcie->irq); |
1445 | goto error; | 588 | goto error; |
1446 | } | 589 | } |
1447 | 590 | ||
1448 | INIT_WORK(&trans_pcie->rx_replenish, iwl_bg_rx_replenish); | ||
1449 | trans_pcie->irq_requested = true; | 591 | trans_pcie->irq_requested = true; |
1450 | } | 592 | } |
1451 | 593 | ||
1452 | err = iwl_prepare_card_hw(trans); | 594 | err = iwl_pcie_prepare_card_hw(trans); |
1453 | if (err) { | 595 | if (err) { |
1454 | IWL_ERR(trans, "Error while preparing HW: %d\n", err); | 596 | IWL_ERR(trans, "Error while preparing HW: %d\n", err); |
1455 | goto err_free_irq; | 597 | goto err_free_irq; |
1456 | } | 598 | } |
1457 | 599 | ||
1458 | iwl_apm_init(trans); | 600 | iwl_pcie_apm_init(trans); |
1459 | 601 | ||
1460 | /* From now on, the op_mode will be kept updated about RF kill state */ | 602 | /* From now on, the op_mode will be kept updated about RF kill state */ |
1461 | iwl_enable_rfkill_int(trans); | 603 | iwl_enable_rfkill_int(trans); |
@@ -1469,7 +611,7 @@ err_free_irq: | |||
1469 | trans_pcie->irq_requested = false; | 611 | trans_pcie->irq_requested = false; |
1470 | free_irq(trans_pcie->irq, trans); | 612 | free_irq(trans_pcie->irq, trans); |
1471 | error: | 613 | error: |
1472 | iwl_free_isr_ict(trans); | 614 | iwl_pcie_free_ict(trans); |
1473 | tasklet_kill(&trans_pcie->irq_tasklet); | 615 | tasklet_kill(&trans_pcie->irq_tasklet); |
1474 | return err; | 616 | return err; |
1475 | } | 617 | } |
@@ -1485,7 +627,7 @@ static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans, | |||
1485 | iwl_disable_interrupts(trans); | 627 | iwl_disable_interrupts(trans); |
1486 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | 628 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); |
1487 | 629 | ||
1488 | iwl_apm_stop(trans); | 630 | iwl_pcie_apm_stop(trans); |
1489 | 631 | ||
1490 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | 632 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); |
1491 | iwl_disable_interrupts(trans); | 633 | iwl_disable_interrupts(trans); |
@@ -1509,27 +651,6 @@ static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans, | |||
1509 | } | 651 | } |
1510 | } | 652 | } |
1511 | 653 | ||
1512 | static void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, | ||
1513 | struct sk_buff_head *skbs) | ||
1514 | { | ||
1515 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1516 | struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; | ||
1517 | /* n_bd is usually 256 => n_bd - 1 = 0xff */ | ||
1518 | int tfd_num = ssn & (txq->q.n_bd - 1); | ||
1519 | |||
1520 | spin_lock(&txq->lock); | ||
1521 | |||
1522 | if (txq->q.read_ptr != tfd_num) { | ||
1523 | IWL_DEBUG_TX_REPLY(trans, "[Q %d] %d -> %d (%d)\n", | ||
1524 | txq_id, txq->q.read_ptr, tfd_num, ssn); | ||
1525 | iwl_tx_queue_reclaim(trans, txq_id, tfd_num, skbs); | ||
1526 | if (iwl_queue_space(&txq->q) > txq->q.low_mark) | ||
1527 | iwl_wake_queue(trans, txq); | ||
1528 | } | ||
1529 | |||
1530 | spin_unlock(&txq->lock); | ||
1531 | } | ||
1532 | |||
1533 | static void iwl_trans_pcie_write8(struct iwl_trans *trans, u32 ofs, u8 val) | 654 | static void iwl_trans_pcie_write8(struct iwl_trans *trans, u32 ofs, u8 val) |
1534 | { | 655 | { |
1535 | writeb(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); | 656 | writeb(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); |
@@ -1576,12 +697,12 @@ void iwl_trans_pcie_free(struct iwl_trans *trans) | |||
1576 | { | 697 | { |
1577 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 698 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1578 | 699 | ||
1579 | iwl_trans_pcie_tx_free(trans); | 700 | iwl_pcie_tx_free(trans); |
1580 | iwl_trans_pcie_rx_free(trans); | 701 | iwl_pcie_rx_free(trans); |
1581 | 702 | ||
1582 | if (trans_pcie->irq_requested == true) { | 703 | if (trans_pcie->irq_requested == true) { |
1583 | free_irq(trans_pcie->irq, trans); | 704 | free_irq(trans_pcie->irq, trans); |
1584 | iwl_free_isr_ict(trans); | 705 | iwl_pcie_free_ict(trans); |
1585 | } | 706 | } |
1586 | 707 | ||
1587 | pci_disable_msi(trans_pcie->pci_dev); | 708 | pci_disable_msi(trans_pcie->pci_dev); |
@@ -1627,10 +748,10 @@ static int iwl_trans_pcie_resume(struct iwl_trans *trans) | |||
1627 | 748 | ||
1628 | #define IWL_FLUSH_WAIT_MS 2000 | 749 | #define IWL_FLUSH_WAIT_MS 2000 |
1629 | 750 | ||
1630 | static int iwl_trans_pcie_wait_tx_queue_empty(struct iwl_trans *trans) | 751 | static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans) |
1631 | { | 752 | { |
1632 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 753 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1633 | struct iwl_tx_queue *txq; | 754 | struct iwl_txq *txq; |
1634 | struct iwl_queue *q; | 755 | struct iwl_queue *q; |
1635 | int cnt; | 756 | int cnt; |
1636 | unsigned long now = jiffies; | 757 | unsigned long now = jiffies; |
@@ -1674,7 +795,7 @@ static const char *get_fh_string(int cmd) | |||
1674 | #undef IWL_CMD | 795 | #undef IWL_CMD |
1675 | } | 796 | } |
1676 | 797 | ||
1677 | int iwl_dump_fh(struct iwl_trans *trans, char **buf) | 798 | int iwl_pcie_dump_fh(struct iwl_trans *trans, char **buf) |
1678 | { | 799 | { |
1679 | int i; | 800 | int i; |
1680 | static const u32 fh_tbl[] = { | 801 | static const u32 fh_tbl[] = { |
@@ -1753,7 +874,7 @@ static const char *get_csr_string(int cmd) | |||
1753 | #undef IWL_CMD | 874 | #undef IWL_CMD |
1754 | } | 875 | } |
1755 | 876 | ||
1756 | void iwl_dump_csr(struct iwl_trans *trans) | 877 | void iwl_pcie_dump_csr(struct iwl_trans *trans) |
1757 | { | 878 | { |
1758 | int i; | 879 | int i; |
1759 | static const u32 csr_tbl[] = { | 880 | static const u32 csr_tbl[] = { |
@@ -1810,7 +931,6 @@ static ssize_t iwl_dbgfs_##name##_write(struct file *file, \ | |||
1810 | const char __user *user_buf, \ | 931 | const char __user *user_buf, \ |
1811 | size_t count, loff_t *ppos); | 932 | size_t count, loff_t *ppos); |
1812 | 933 | ||
1813 | |||
1814 | #define DEBUGFS_READ_FILE_OPS(name) \ | 934 | #define DEBUGFS_READ_FILE_OPS(name) \ |
1815 | DEBUGFS_READ_FUNC(name); \ | 935 | DEBUGFS_READ_FUNC(name); \ |
1816 | static const struct file_operations iwl_dbgfs_##name##_ops = { \ | 936 | static const struct file_operations iwl_dbgfs_##name##_ops = { \ |
@@ -1843,7 +963,7 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, | |||
1843 | { | 963 | { |
1844 | struct iwl_trans *trans = file->private_data; | 964 | struct iwl_trans *trans = file->private_data; |
1845 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 965 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1846 | struct iwl_tx_queue *txq; | 966 | struct iwl_txq *txq; |
1847 | struct iwl_queue *q; | 967 | struct iwl_queue *q; |
1848 | char *buf; | 968 | char *buf; |
1849 | int pos = 0; | 969 | int pos = 0; |
@@ -1880,7 +1000,7 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file, | |||
1880 | { | 1000 | { |
1881 | struct iwl_trans *trans = file->private_data; | 1001 | struct iwl_trans *trans = file->private_data; |
1882 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1002 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
1883 | struct iwl_rx_queue *rxq = &trans_pcie->rxq; | 1003 | struct iwl_rxq *rxq = &trans_pcie->rxq; |
1884 | char buf[256]; | 1004 | char buf[256]; |
1885 | int pos = 0; | 1005 | int pos = 0; |
1886 | const size_t bufsz = sizeof(buf); | 1006 | const size_t bufsz = sizeof(buf); |
@@ -1999,7 +1119,7 @@ static ssize_t iwl_dbgfs_csr_write(struct file *file, | |||
1999 | if (sscanf(buf, "%d", &csr) != 1) | 1119 | if (sscanf(buf, "%d", &csr) != 1) |
2000 | return -EFAULT; | 1120 | return -EFAULT; |
2001 | 1121 | ||
2002 | iwl_dump_csr(trans); | 1122 | iwl_pcie_dump_csr(trans); |
2003 | 1123 | ||
2004 | return count; | 1124 | return count; |
2005 | } | 1125 | } |
@@ -2013,7 +1133,7 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file, | |||
2013 | int pos = 0; | 1133 | int pos = 0; |
2014 | ssize_t ret = -EFAULT; | 1134 | ssize_t ret = -EFAULT; |
2015 | 1135 | ||
2016 | ret = pos = iwl_dump_fh(trans, &buf); | 1136 | ret = pos = iwl_pcie_dump_fh(trans, &buf); |
2017 | if (buf) { | 1137 | if (buf) { |
2018 | ret = simple_read_from_buffer(user_buf, | 1138 | ret = simple_read_from_buffer(user_buf, |
2019 | count, ppos, buf, pos); | 1139 | count, ppos, buf, pos); |
@@ -2082,7 +1202,7 @@ static const struct iwl_trans_ops trans_ops_pcie = { | |||
2082 | 1202 | ||
2083 | .wowlan_suspend = iwl_trans_pcie_wowlan_suspend, | 1203 | .wowlan_suspend = iwl_trans_pcie_wowlan_suspend, |
2084 | 1204 | ||
2085 | .send_cmd = iwl_trans_pcie_send_cmd, | 1205 | .send_cmd = iwl_trans_pcie_send_hcmd, |
2086 | 1206 | ||
2087 | .tx = iwl_trans_pcie_tx, | 1207 | .tx = iwl_trans_pcie_tx, |
2088 | .reclaim = iwl_trans_pcie_reclaim, | 1208 | .reclaim = iwl_trans_pcie_reclaim, |
@@ -2092,7 +1212,7 @@ static const struct iwl_trans_ops trans_ops_pcie = { | |||
2092 | 1212 | ||
2093 | .dbgfs_register = iwl_trans_pcie_dbgfs_register, | 1213 | .dbgfs_register = iwl_trans_pcie_dbgfs_register, |
2094 | 1214 | ||
2095 | .wait_tx_queue_empty = iwl_trans_pcie_wait_tx_queue_empty, | 1215 | .wait_tx_queue_empty = iwl_trans_pcie_wait_txq_empty, |
2096 | 1216 | ||
2097 | #ifdef CONFIG_PM_SLEEP | 1217 | #ifdef CONFIG_PM_SLEEP |
2098 | .suspend = iwl_trans_pcie_suspend, | 1218 | .suspend = iwl_trans_pcie_suspend, |
@@ -2117,7 +1237,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
2117 | trans = kzalloc(sizeof(struct iwl_trans) + | 1237 | trans = kzalloc(sizeof(struct iwl_trans) + |
2118 | sizeof(struct iwl_trans_pcie), GFP_KERNEL); | 1238 | sizeof(struct iwl_trans_pcie), GFP_KERNEL); |
2119 | 1239 | ||
2120 | if (WARN_ON(!trans)) | 1240 | if (!trans) |
2121 | return NULL; | 1241 | return NULL; |
2122 | 1242 | ||
2123 | trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1243 | trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
@@ -2150,43 +1270,38 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
2150 | DMA_BIT_MASK(32)); | 1270 | DMA_BIT_MASK(32)); |
2151 | /* both attempts failed: */ | 1271 | /* both attempts failed: */ |
2152 | if (err) { | 1272 | if (err) { |
2153 | dev_printk(KERN_ERR, &pdev->dev, | 1273 | dev_err(&pdev->dev, "No suitable DMA available\n"); |
2154 | "No suitable DMA available.\n"); | ||
2155 | goto out_pci_disable_device; | 1274 | goto out_pci_disable_device; |
2156 | } | 1275 | } |
2157 | } | 1276 | } |
2158 | 1277 | ||
2159 | err = pci_request_regions(pdev, DRV_NAME); | 1278 | err = pci_request_regions(pdev, DRV_NAME); |
2160 | if (err) { | 1279 | if (err) { |
2161 | dev_printk(KERN_ERR, &pdev->dev, | 1280 | dev_err(&pdev->dev, "pci_request_regions failed\n"); |
2162 | "pci_request_regions failed\n"); | ||
2163 | goto out_pci_disable_device; | 1281 | goto out_pci_disable_device; |
2164 | } | 1282 | } |
2165 | 1283 | ||
2166 | trans_pcie->hw_base = pci_ioremap_bar(pdev, 0); | 1284 | trans_pcie->hw_base = pci_ioremap_bar(pdev, 0); |
2167 | if (!trans_pcie->hw_base) { | 1285 | if (!trans_pcie->hw_base) { |
2168 | dev_printk(KERN_ERR, &pdev->dev, "pci_ioremap_bar failed\n"); | 1286 | dev_err(&pdev->dev, "pci_ioremap_bar failed\n"); |
2169 | err = -ENODEV; | 1287 | err = -ENODEV; |
2170 | goto out_pci_release_regions; | 1288 | goto out_pci_release_regions; |
2171 | } | 1289 | } |
2172 | 1290 | ||
2173 | dev_printk(KERN_INFO, &pdev->dev, | ||
2174 | "pci_resource_len = 0x%08llx\n", | ||
2175 | (unsigned long long) pci_resource_len(pdev, 0)); | ||
2176 | dev_printk(KERN_INFO, &pdev->dev, | ||
2177 | "pci_resource_base = %p\n", trans_pcie->hw_base); | ||
2178 | |||
2179 | dev_printk(KERN_INFO, &pdev->dev, | ||
2180 | "HW Revision ID = 0x%X\n", pdev->revision); | ||
2181 | |||
2182 | /* We disable the RETRY_TIMEOUT register (0x41) to keep | 1291 | /* We disable the RETRY_TIMEOUT register (0x41) to keep |
2183 | * PCI Tx retries from interfering with C3 CPU state */ | 1292 | * PCI Tx retries from interfering with C3 CPU state */ |
2184 | pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); | 1293 | pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); |
2185 | 1294 | ||
2186 | err = pci_enable_msi(pdev); | 1295 | err = pci_enable_msi(pdev); |
2187 | if (err) | 1296 | if (err) { |
2188 | dev_printk(KERN_ERR, &pdev->dev, | 1297 | dev_err(&pdev->dev, "pci_enable_msi failed(0X%x)\n", err); |
2189 | "pci_enable_msi failed(0X%x)\n", err); | 1298 | /* enable rfkill interrupt: hw bug w/a */ |
1299 | pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd); | ||
1300 | if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { | ||
1301 | pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; | ||
1302 | pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); | ||
1303 | } | ||
1304 | } | ||
2190 | 1305 | ||
2191 | trans->dev = &pdev->dev; | 1306 | trans->dev = &pdev->dev; |
2192 | trans_pcie->irq = pdev->irq; | 1307 | trans_pcie->irq = pdev->irq; |
@@ -2196,16 +1311,8 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
2196 | snprintf(trans->hw_id_str, sizeof(trans->hw_id_str), | 1311 | snprintf(trans->hw_id_str, sizeof(trans->hw_id_str), |
2197 | "PCI ID: 0x%04X:0x%04X", pdev->device, pdev->subsystem_device); | 1312 | "PCI ID: 0x%04X:0x%04X", pdev->device, pdev->subsystem_device); |
2198 | 1313 | ||
2199 | /* TODO: Move this away, not needed if not MSI */ | ||
2200 | /* enable rfkill interrupt: hw bug w/a */ | ||
2201 | pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd); | ||
2202 | if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { | ||
2203 | pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; | ||
2204 | pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); | ||
2205 | } | ||
2206 | |||
2207 | /* Initialize the wait queue for commands */ | 1314 | /* Initialize the wait queue for commands */ |
2208 | init_waitqueue_head(&trans->wait_command_queue); | 1315 | init_waitqueue_head(&trans_pcie->wait_command_queue); |
2209 | spin_lock_init(&trans->reg_lock); | 1316 | spin_lock_init(&trans->reg_lock); |
2210 | 1317 | ||
2211 | snprintf(trans->dev_cmd_pool_name, sizeof(trans->dev_cmd_pool_name), | 1318 | snprintf(trans->dev_cmd_pool_name, sizeof(trans->dev_cmd_pool_name), |
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index db3efbb84d92..6c5b867c353a 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c | |||
@@ -42,12 +42,170 @@ | |||
42 | #define IWL_TX_CRC_SIZE 4 | 42 | #define IWL_TX_CRC_SIZE 4 |
43 | #define IWL_TX_DELIMITER_SIZE 4 | 43 | #define IWL_TX_DELIMITER_SIZE 4 |
44 | 44 | ||
45 | /** | 45 | /*************** DMA-QUEUE-GENERAL-FUNCTIONS ***** |
46 | * iwl_trans_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array | 46 | * DMA services |
47 | * | ||
48 | * Theory of operation | ||
49 | * | ||
50 | * A Tx or Rx queue resides in host DRAM, and is comprised of a circular buffer | ||
51 | * of buffer descriptors, each of which points to one or more data buffers for | ||
52 | * the device to read from or fill. Driver and device exchange status of each | ||
53 | * queue via "read" and "write" pointers. Driver keeps minimum of 2 empty | ||
54 | * entries in each circular buffer, to protect against confusing empty and full | ||
55 | * queue states. | ||
56 | * | ||
57 | * The device reads or writes the data in the queues via the device's several | ||
58 | * DMA/FIFO channels. Each queue is mapped to a single DMA channel. | ||
59 | * | ||
60 | * For Tx queue, there are low mark and high mark limits. If, after queuing | ||
61 | * the packet for Tx, free space become < low mark, Tx queue stopped. When | ||
62 | * reclaiming packets (on 'tx done IRQ), if free space become > high mark, | ||
63 | * Tx queue resumed. | ||
64 | * | ||
65 | ***************************************************/ | ||
66 | static int iwl_queue_space(const struct iwl_queue *q) | ||
67 | { | ||
68 | int s = q->read_ptr - q->write_ptr; | ||
69 | |||
70 | if (q->read_ptr > q->write_ptr) | ||
71 | s -= q->n_bd; | ||
72 | |||
73 | if (s <= 0) | ||
74 | s += q->n_window; | ||
75 | /* keep some reserve to not confuse empty and full situations */ | ||
76 | s -= 2; | ||
77 | if (s < 0) | ||
78 | s = 0; | ||
79 | return s; | ||
80 | } | ||
81 | |||
82 | /* | ||
83 | * iwl_queue_init - Initialize queue's high/low-water and read/write indexes | ||
84 | */ | ||
85 | static int iwl_queue_init(struct iwl_queue *q, int count, int slots_num, u32 id) | ||
86 | { | ||
87 | q->n_bd = count; | ||
88 | q->n_window = slots_num; | ||
89 | q->id = id; | ||
90 | |||
91 | /* count must be power-of-two size, otherwise iwl_queue_inc_wrap | ||
92 | * and iwl_queue_dec_wrap are broken. */ | ||
93 | if (WARN_ON(!is_power_of_2(count))) | ||
94 | return -EINVAL; | ||
95 | |||
96 | /* slots_num must be power-of-two size, otherwise | ||
97 | * get_cmd_index is broken. */ | ||
98 | if (WARN_ON(!is_power_of_2(slots_num))) | ||
99 | return -EINVAL; | ||
100 | |||
101 | q->low_mark = q->n_window / 4; | ||
102 | if (q->low_mark < 4) | ||
103 | q->low_mark = 4; | ||
104 | |||
105 | q->high_mark = q->n_window / 8; | ||
106 | if (q->high_mark < 2) | ||
107 | q->high_mark = 2; | ||
108 | |||
109 | q->write_ptr = 0; | ||
110 | q->read_ptr = 0; | ||
111 | |||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | static int iwl_pcie_alloc_dma_ptr(struct iwl_trans *trans, | ||
116 | struct iwl_dma_ptr *ptr, size_t size) | ||
117 | { | ||
118 | if (WARN_ON(ptr->addr)) | ||
119 | return -EINVAL; | ||
120 | |||
121 | ptr->addr = dma_alloc_coherent(trans->dev, size, | ||
122 | &ptr->dma, GFP_KERNEL); | ||
123 | if (!ptr->addr) | ||
124 | return -ENOMEM; | ||
125 | ptr->size = size; | ||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static void iwl_pcie_free_dma_ptr(struct iwl_trans *trans, | ||
130 | struct iwl_dma_ptr *ptr) | ||
131 | { | ||
132 | if (unlikely(!ptr->addr)) | ||
133 | return; | ||
134 | |||
135 | dma_free_coherent(trans->dev, ptr->size, ptr->addr, ptr->dma); | ||
136 | memset(ptr, 0, sizeof(*ptr)); | ||
137 | } | ||
138 | |||
139 | static void iwl_pcie_txq_stuck_timer(unsigned long data) | ||
140 | { | ||
141 | struct iwl_txq *txq = (void *)data; | ||
142 | struct iwl_queue *q = &txq->q; | ||
143 | struct iwl_trans_pcie *trans_pcie = txq->trans_pcie; | ||
144 | struct iwl_trans *trans = iwl_trans_pcie_get_trans(trans_pcie); | ||
145 | u32 scd_sram_addr = trans_pcie->scd_base_addr + | ||
146 | SCD_TX_STTS_QUEUE_OFFSET(txq->q.id); | ||
147 | u8 buf[16]; | ||
148 | int i; | ||
149 | |||
150 | spin_lock(&txq->lock); | ||
151 | /* check if triggered erroneously */ | ||
152 | if (txq->q.read_ptr == txq->q.write_ptr) { | ||
153 | spin_unlock(&txq->lock); | ||
154 | return; | ||
155 | } | ||
156 | spin_unlock(&txq->lock); | ||
157 | |||
158 | IWL_ERR(trans, "Queue %d stuck for %u ms.\n", txq->q.id, | ||
159 | jiffies_to_msecs(trans_pcie->wd_timeout)); | ||
160 | IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n", | ||
161 | txq->q.read_ptr, txq->q.write_ptr); | ||
162 | |||
163 | iwl_read_targ_mem_bytes(trans, scd_sram_addr, buf, sizeof(buf)); | ||
164 | |||
165 | iwl_print_hex_error(trans, buf, sizeof(buf)); | ||
166 | |||
167 | for (i = 0; i < FH_TCSR_CHNL_NUM; i++) | ||
168 | IWL_ERR(trans, "FH TRBs(%d) = 0x%08x\n", i, | ||
169 | iwl_read_direct32(trans, FH_TX_TRB_REG(i))); | ||
170 | |||
171 | for (i = 0; i < trans->cfg->base_params->num_of_queues; i++) { | ||
172 | u32 status = iwl_read_prph(trans, SCD_QUEUE_STATUS_BITS(i)); | ||
173 | u8 fifo = (status >> SCD_QUEUE_STTS_REG_POS_TXF) & 0x7; | ||
174 | bool active = !!(status & BIT(SCD_QUEUE_STTS_REG_POS_ACTIVE)); | ||
175 | u32 tbl_dw = | ||
176 | iwl_read_targ_mem(trans, | ||
177 | trans_pcie->scd_base_addr + | ||
178 | SCD_TRANS_TBL_OFFSET_QUEUE(i)); | ||
179 | |||
180 | if (i & 0x1) | ||
181 | tbl_dw = (tbl_dw & 0xFFFF0000) >> 16; | ||
182 | else | ||
183 | tbl_dw = tbl_dw & 0x0000FFFF; | ||
184 | |||
185 | IWL_ERR(trans, | ||
186 | "Q %d is %sactive and mapped to fifo %d ra_tid 0x%04x [%d,%d]\n", | ||
187 | i, active ? "" : "in", fifo, tbl_dw, | ||
188 | iwl_read_prph(trans, | ||
189 | SCD_QUEUE_RDPTR(i)) & (txq->q.n_bd - 1), | ||
190 | iwl_read_prph(trans, SCD_QUEUE_WRPTR(i))); | ||
191 | } | ||
192 | |||
193 | for (i = q->read_ptr; i != q->write_ptr; | ||
194 | i = iwl_queue_inc_wrap(i, q->n_bd)) { | ||
195 | struct iwl_tx_cmd *tx_cmd = | ||
196 | (struct iwl_tx_cmd *)txq->entries[i].cmd->payload; | ||
197 | IWL_ERR(trans, "scratch %d = 0x%08x\n", i, | ||
198 | get_unaligned_le32(&tx_cmd->scratch)); | ||
199 | } | ||
200 | |||
201 | iwl_op_mode_nic_error(trans->op_mode); | ||
202 | } | ||
203 | |||
204 | /* | ||
205 | * iwl_pcie_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array | ||
47 | */ | 206 | */ |
48 | void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, | 207 | static void iwl_pcie_txq_update_byte_cnt_tbl(struct iwl_trans *trans, |
49 | struct iwl_tx_queue *txq, | 208 | struct iwl_txq *txq, u16 byte_cnt) |
50 | u16 byte_cnt) | ||
51 | { | 209 | { |
52 | struct iwlagn_scd_bc_tbl *scd_bc_tbl; | 210 | struct iwlagn_scd_bc_tbl *scd_bc_tbl; |
53 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 211 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
@@ -88,10 +246,36 @@ void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, | |||
88 | tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent; | 246 | tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent; |
89 | } | 247 | } |
90 | 248 | ||
91 | /** | 249 | static void iwl_pcie_txq_inval_byte_cnt_tbl(struct iwl_trans *trans, |
92 | * iwl_txq_update_write_ptr - Send new write index to hardware | 250 | struct iwl_txq *txq) |
251 | { | ||
252 | struct iwl_trans_pcie *trans_pcie = | ||
253 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
254 | struct iwlagn_scd_bc_tbl *scd_bc_tbl = trans_pcie->scd_bc_tbls.addr; | ||
255 | int txq_id = txq->q.id; | ||
256 | int read_ptr = txq->q.read_ptr; | ||
257 | u8 sta_id = 0; | ||
258 | __le16 bc_ent; | ||
259 | struct iwl_tx_cmd *tx_cmd = | ||
260 | (void *)txq->entries[txq->q.read_ptr].cmd->payload; | ||
261 | |||
262 | WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX); | ||
263 | |||
264 | if (txq_id != trans_pcie->cmd_queue) | ||
265 | sta_id = tx_cmd->sta_id; | ||
266 | |||
267 | bc_ent = cpu_to_le16(1 | (sta_id << 12)); | ||
268 | scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent; | ||
269 | |||
270 | if (read_ptr < TFD_QUEUE_SIZE_BC_DUP) | ||
271 | scd_bc_tbl[txq_id]. | ||
272 | tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent; | ||
273 | } | ||
274 | |||
275 | /* | ||
276 | * iwl_pcie_txq_inc_wr_ptr - Send new write index to hardware | ||
93 | */ | 277 | */ |
94 | void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq) | 278 | void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_txq *txq) |
95 | { | 279 | { |
96 | u32 reg = 0; | 280 | u32 reg = 0; |
97 | int txq_id = txq->q.id; | 281 | int txq_id = txq->q.id; |
@@ -137,7 +321,7 @@ void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq) | |||
137 | txq->need_update = 0; | 321 | txq->need_update = 0; |
138 | } | 322 | } |
139 | 323 | ||
140 | static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx) | 324 | static inline dma_addr_t iwl_pcie_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx) |
141 | { | 325 | { |
142 | struct iwl_tfd_tb *tb = &tfd->tbs[idx]; | 326 | struct iwl_tfd_tb *tb = &tfd->tbs[idx]; |
143 | 327 | ||
@@ -149,15 +333,15 @@ static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx) | |||
149 | return addr; | 333 | return addr; |
150 | } | 334 | } |
151 | 335 | ||
152 | static inline u16 iwl_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx) | 336 | static inline u16 iwl_pcie_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx) |
153 | { | 337 | { |
154 | struct iwl_tfd_tb *tb = &tfd->tbs[idx]; | 338 | struct iwl_tfd_tb *tb = &tfd->tbs[idx]; |
155 | 339 | ||
156 | return le16_to_cpu(tb->hi_n_len) >> 4; | 340 | return le16_to_cpu(tb->hi_n_len) >> 4; |
157 | } | 341 | } |
158 | 342 | ||
159 | static inline void iwl_tfd_set_tb(struct iwl_tfd *tfd, u8 idx, | 343 | static inline void iwl_pcie_tfd_set_tb(struct iwl_tfd *tfd, u8 idx, |
160 | dma_addr_t addr, u16 len) | 344 | dma_addr_t addr, u16 len) |
161 | { | 345 | { |
162 | struct iwl_tfd_tb *tb = &tfd->tbs[idx]; | 346 | struct iwl_tfd_tb *tb = &tfd->tbs[idx]; |
163 | u16 hi_n_len = len << 4; | 347 | u16 hi_n_len = len << 4; |
@@ -171,19 +355,20 @@ static inline void iwl_tfd_set_tb(struct iwl_tfd *tfd, u8 idx, | |||
171 | tfd->num_tbs = idx + 1; | 355 | tfd->num_tbs = idx + 1; |
172 | } | 356 | } |
173 | 357 | ||
174 | static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd) | 358 | static inline u8 iwl_pcie_tfd_get_num_tbs(struct iwl_tfd *tfd) |
175 | { | 359 | { |
176 | return tfd->num_tbs & 0x1f; | 360 | return tfd->num_tbs & 0x1f; |
177 | } | 361 | } |
178 | 362 | ||
179 | static void iwl_unmap_tfd(struct iwl_trans *trans, struct iwl_cmd_meta *meta, | 363 | static void iwl_pcie_tfd_unmap(struct iwl_trans *trans, |
180 | struct iwl_tfd *tfd, enum dma_data_direction dma_dir) | 364 | struct iwl_cmd_meta *meta, struct iwl_tfd *tfd, |
365 | enum dma_data_direction dma_dir) | ||
181 | { | 366 | { |
182 | int i; | 367 | int i; |
183 | int num_tbs; | 368 | int num_tbs; |
184 | 369 | ||
185 | /* Sanity check on number of chunks */ | 370 | /* Sanity check on number of chunks */ |
186 | num_tbs = iwl_tfd_get_num_tbs(tfd); | 371 | num_tbs = iwl_pcie_tfd_get_num_tbs(tfd); |
187 | 372 | ||
188 | if (num_tbs >= IWL_NUM_OF_TBS) { | 373 | if (num_tbs >= IWL_NUM_OF_TBS) { |
189 | IWL_ERR(trans, "Too many chunks: %i\n", num_tbs); | 374 | IWL_ERR(trans, "Too many chunks: %i\n", num_tbs); |
@@ -200,14 +385,14 @@ static void iwl_unmap_tfd(struct iwl_trans *trans, struct iwl_cmd_meta *meta, | |||
200 | 385 | ||
201 | /* Unmap chunks, if any. */ | 386 | /* Unmap chunks, if any. */ |
202 | for (i = 1; i < num_tbs; i++) | 387 | for (i = 1; i < num_tbs; i++) |
203 | dma_unmap_single(trans->dev, iwl_tfd_tb_get_addr(tfd, i), | 388 | dma_unmap_single(trans->dev, iwl_pcie_tfd_tb_get_addr(tfd, i), |
204 | iwl_tfd_tb_get_len(tfd, i), dma_dir); | 389 | iwl_pcie_tfd_tb_get_len(tfd, i), dma_dir); |
205 | 390 | ||
206 | tfd->num_tbs = 0; | 391 | tfd->num_tbs = 0; |
207 | } | 392 | } |
208 | 393 | ||
209 | /** | 394 | /* |
210 | * iwl_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] | 395 | * iwl_pcie_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] |
211 | * @trans - transport private data | 396 | * @trans - transport private data |
212 | * @txq - tx queue | 397 | * @txq - tx queue |
213 | * @dma_dir - the direction of the DMA mapping | 398 | * @dma_dir - the direction of the DMA mapping |
@@ -215,8 +400,8 @@ static void iwl_unmap_tfd(struct iwl_trans *trans, struct iwl_cmd_meta *meta, | |||
215 | * Does NOT advance any TFD circular buffer read/write indexes | 400 | * Does NOT advance any TFD circular buffer read/write indexes |
216 | * Does NOT free the TFD itself (which is within circular buffer) | 401 | * Does NOT free the TFD itself (which is within circular buffer) |
217 | */ | 402 | */ |
218 | void iwl_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, | 403 | static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq, |
219 | enum dma_data_direction dma_dir) | 404 | enum dma_data_direction dma_dir) |
220 | { | 405 | { |
221 | struct iwl_tfd *tfd_tmp = txq->tfds; | 406 | struct iwl_tfd *tfd_tmp = txq->tfds; |
222 | 407 | ||
@@ -227,8 +412,8 @@ void iwl_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, | |||
227 | lockdep_assert_held(&txq->lock); | 412 | lockdep_assert_held(&txq->lock); |
228 | 413 | ||
229 | /* We have only q->n_window txq->entries, but we use q->n_bd tfds */ | 414 | /* We have only q->n_window txq->entries, but we use q->n_bd tfds */ |
230 | iwl_unmap_tfd(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr], | 415 | iwl_pcie_tfd_unmap(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr], |
231 | dma_dir); | 416 | dma_dir); |
232 | 417 | ||
233 | /* free SKB */ | 418 | /* free SKB */ |
234 | if (txq->entries) { | 419 | if (txq->entries) { |
@@ -247,10 +432,8 @@ void iwl_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, | |||
247 | } | 432 | } |
248 | } | 433 | } |
249 | 434 | ||
250 | int iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans, | 435 | static int iwl_pcie_txq_build_tfd(struct iwl_trans *trans, struct iwl_txq *txq, |
251 | struct iwl_tx_queue *txq, | 436 | dma_addr_t addr, u16 len, u8 reset) |
252 | dma_addr_t addr, u16 len, | ||
253 | u8 reset) | ||
254 | { | 437 | { |
255 | struct iwl_queue *q; | 438 | struct iwl_queue *q; |
256 | struct iwl_tfd *tfd, *tfd_tmp; | 439 | struct iwl_tfd *tfd, *tfd_tmp; |
@@ -263,7 +446,7 @@ int iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans, | |||
263 | if (reset) | 446 | if (reset) |
264 | memset(tfd, 0, sizeof(*tfd)); | 447 | memset(tfd, 0, sizeof(*tfd)); |
265 | 448 | ||
266 | num_tbs = iwl_tfd_get_num_tbs(tfd); | 449 | num_tbs = iwl_pcie_tfd_get_num_tbs(tfd); |
267 | 450 | ||
268 | /* Each TFD can point to a maximum 20 Tx buffers */ | 451 | /* Each TFD can point to a maximum 20 Tx buffers */ |
269 | if (num_tbs >= IWL_NUM_OF_TBS) { | 452 | if (num_tbs >= IWL_NUM_OF_TBS) { |
@@ -279,108 +462,534 @@ int iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans, | |||
279 | IWL_ERR(trans, "Unaligned address = %llx\n", | 462 | IWL_ERR(trans, "Unaligned address = %llx\n", |
280 | (unsigned long long)addr); | 463 | (unsigned long long)addr); |
281 | 464 | ||
282 | iwl_tfd_set_tb(tfd, num_tbs, addr, len); | 465 | iwl_pcie_tfd_set_tb(tfd, num_tbs, addr, len); |
283 | 466 | ||
284 | return 0; | 467 | return 0; |
285 | } | 468 | } |
286 | 469 | ||
287 | /*************** DMA-QUEUE-GENERAL-FUNCTIONS ***** | 470 | static int iwl_pcie_txq_alloc(struct iwl_trans *trans, |
288 | * DMA services | 471 | struct iwl_txq *txq, int slots_num, |
289 | * | 472 | u32 txq_id) |
290 | * Theory of operation | 473 | { |
291 | * | 474 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
292 | * A Tx or Rx queue resides in host DRAM, and is comprised of a circular buffer | 475 | size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX; |
293 | * of buffer descriptors, each of which points to one or more data buffers for | 476 | int i; |
294 | * the device to read from or fill. Driver and device exchange status of each | 477 | |
295 | * queue via "read" and "write" pointers. Driver keeps minimum of 2 empty | 478 | if (WARN_ON(txq->entries || txq->tfds)) |
296 | * entries in each circular buffer, to protect against confusing empty and full | 479 | return -EINVAL; |
297 | * queue states. | 480 | |
298 | * | 481 | setup_timer(&txq->stuck_timer, iwl_pcie_txq_stuck_timer, |
299 | * The device reads or writes the data in the queues via the device's several | 482 | (unsigned long)txq); |
300 | * DMA/FIFO channels. Each queue is mapped to a single DMA channel. | 483 | txq->trans_pcie = trans_pcie; |
301 | * | 484 | |
302 | * For Tx queue, there are low mark and high mark limits. If, after queuing | 485 | txq->q.n_window = slots_num; |
303 | * the packet for Tx, free space become < low mark, Tx queue stopped. When | 486 | |
304 | * reclaiming packets (on 'tx done IRQ), if free space become > high mark, | 487 | txq->entries = kcalloc(slots_num, |
305 | * Tx queue resumed. | 488 | sizeof(struct iwl_pcie_txq_entry), |
489 | GFP_KERNEL); | ||
490 | |||
491 | if (!txq->entries) | ||
492 | goto error; | ||
493 | |||
494 | if (txq_id == trans_pcie->cmd_queue) | ||
495 | for (i = 0; i < slots_num; i++) { | ||
496 | txq->entries[i].cmd = | ||
497 | kmalloc(sizeof(struct iwl_device_cmd), | ||
498 | GFP_KERNEL); | ||
499 | if (!txq->entries[i].cmd) | ||
500 | goto error; | ||
501 | } | ||
502 | |||
503 | /* Circular buffer of transmit frame descriptors (TFDs), | ||
504 | * shared with device */ | ||
505 | txq->tfds = dma_alloc_coherent(trans->dev, tfd_sz, | ||
506 | &txq->q.dma_addr, GFP_KERNEL); | ||
507 | if (!txq->tfds) { | ||
508 | IWL_ERR(trans, "dma_alloc_coherent(%zd) failed\n", tfd_sz); | ||
509 | goto error; | ||
510 | } | ||
511 | txq->q.id = txq_id; | ||
512 | |||
513 | return 0; | ||
514 | error: | ||
515 | if (txq->entries && txq_id == trans_pcie->cmd_queue) | ||
516 | for (i = 0; i < slots_num; i++) | ||
517 | kfree(txq->entries[i].cmd); | ||
518 | kfree(txq->entries); | ||
519 | txq->entries = NULL; | ||
520 | |||
521 | return -ENOMEM; | ||
522 | |||
523 | } | ||
524 | |||
525 | static int iwl_pcie_txq_init(struct iwl_trans *trans, struct iwl_txq *txq, | ||
526 | int slots_num, u32 txq_id) | ||
527 | { | ||
528 | int ret; | ||
529 | |||
530 | txq->need_update = 0; | ||
531 | |||
532 | /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise | ||
533 | * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */ | ||
534 | BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); | ||
535 | |||
536 | /* Initialize queue's high/low-water marks, and head/tail indexes */ | ||
537 | ret = iwl_queue_init(&txq->q, TFD_QUEUE_SIZE_MAX, slots_num, | ||
538 | txq_id); | ||
539 | if (ret) | ||
540 | return ret; | ||
541 | |||
542 | spin_lock_init(&txq->lock); | ||
543 | |||
544 | /* | ||
545 | * Tell nic where to find circular buffer of Tx Frame Descriptors for | ||
546 | * given Tx queue, and enable the DMA channel used for that queue. | ||
547 | * Circular buffer (TFD queue in DRAM) physical base address */ | ||
548 | iwl_write_direct32(trans, FH_MEM_CBBC_QUEUE(txq_id), | ||
549 | txq->q.dma_addr >> 8); | ||
550 | |||
551 | return 0; | ||
552 | } | ||
553 | |||
554 | /* | ||
555 | * iwl_pcie_txq_unmap - Unmap any remaining DMA mappings and free skb's | ||
556 | */ | ||
557 | static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id) | ||
558 | { | ||
559 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
560 | struct iwl_txq *txq = &trans_pcie->txq[txq_id]; | ||
561 | struct iwl_queue *q = &txq->q; | ||
562 | enum dma_data_direction dma_dir; | ||
563 | |||
564 | if (!q->n_bd) | ||
565 | return; | ||
566 | |||
567 | /* In the command queue, all the TBs are mapped as BIDI | ||
568 | * so unmap them as such. | ||
569 | */ | ||
570 | if (txq_id == trans_pcie->cmd_queue) | ||
571 | dma_dir = DMA_BIDIRECTIONAL; | ||
572 | else | ||
573 | dma_dir = DMA_TO_DEVICE; | ||
574 | |||
575 | spin_lock_bh(&txq->lock); | ||
576 | while (q->write_ptr != q->read_ptr) { | ||
577 | iwl_pcie_txq_free_tfd(trans, txq, dma_dir); | ||
578 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); | ||
579 | } | ||
580 | spin_unlock_bh(&txq->lock); | ||
581 | } | ||
582 | |||
583 | /* | ||
584 | * iwl_pcie_txq_free - Deallocate DMA queue. | ||
585 | * @txq: Transmit queue to deallocate. | ||
306 | * | 586 | * |
307 | ***************************************************/ | 587 | * Empty queue by removing and destroying all BD's. |
588 | * Free all buffers. | ||
589 | * 0-fill, but do not free "txq" descriptor structure. | ||
590 | */ | ||
591 | static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id) | ||
592 | { | ||
593 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
594 | struct iwl_txq *txq = &trans_pcie->txq[txq_id]; | ||
595 | struct device *dev = trans->dev; | ||
596 | int i; | ||
308 | 597 | ||
309 | int iwl_queue_space(const struct iwl_queue *q) | 598 | if (WARN_ON(!txq)) |
599 | return; | ||
600 | |||
601 | iwl_pcie_txq_unmap(trans, txq_id); | ||
602 | |||
603 | /* De-alloc array of command/tx buffers */ | ||
604 | if (txq_id == trans_pcie->cmd_queue) | ||
605 | for (i = 0; i < txq->q.n_window; i++) { | ||
606 | kfree(txq->entries[i].cmd); | ||
607 | kfree(txq->entries[i].copy_cmd); | ||
608 | kfree(txq->entries[i].free_buf); | ||
609 | } | ||
610 | |||
611 | /* De-alloc circular buffer of TFDs */ | ||
612 | if (txq->q.n_bd) { | ||
613 | dma_free_coherent(dev, sizeof(struct iwl_tfd) * | ||
614 | txq->q.n_bd, txq->tfds, txq->q.dma_addr); | ||
615 | memset(&txq->q.dma_addr, 0, sizeof(txq->q.dma_addr)); | ||
616 | } | ||
617 | |||
618 | kfree(txq->entries); | ||
619 | txq->entries = NULL; | ||
620 | |||
621 | del_timer_sync(&txq->stuck_timer); | ||
622 | |||
623 | /* 0-fill queue descriptor structure */ | ||
624 | memset(txq, 0, sizeof(*txq)); | ||
625 | } | ||
626 | |||
627 | /* | ||
628 | * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask | ||
629 | */ | ||
630 | static void iwl_pcie_txq_set_sched(struct iwl_trans *trans, u32 mask) | ||
310 | { | 631 | { |
311 | int s = q->read_ptr - q->write_ptr; | 632 | struct iwl_trans_pcie __maybe_unused *trans_pcie = |
633 | IWL_TRANS_GET_PCIE_TRANS(trans); | ||
312 | 634 | ||
313 | if (q->read_ptr > q->write_ptr) | 635 | iwl_write_prph(trans, SCD_TXFACT, mask); |
314 | s -= q->n_bd; | 636 | } |
315 | 637 | ||
316 | if (s <= 0) | 638 | void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) |
317 | s += q->n_window; | 639 | { |
318 | /* keep some reserve to not confuse empty and full situations */ | 640 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
319 | s -= 2; | 641 | u32 a; |
320 | if (s < 0) | 642 | int chan; |
321 | s = 0; | 643 | u32 reg_val; |
322 | return s; | 644 | |
645 | /* make sure all queue are not stopped/used */ | ||
646 | memset(trans_pcie->queue_stopped, 0, sizeof(trans_pcie->queue_stopped)); | ||
647 | memset(trans_pcie->queue_used, 0, sizeof(trans_pcie->queue_used)); | ||
648 | |||
649 | trans_pcie->scd_base_addr = | ||
650 | iwl_read_prph(trans, SCD_SRAM_BASE_ADDR); | ||
651 | |||
652 | WARN_ON(scd_base_addr != 0 && | ||
653 | scd_base_addr != trans_pcie->scd_base_addr); | ||
654 | |||
655 | a = trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_LOWER_BOUND; | ||
656 | /* reset conext data memory */ | ||
657 | for (; a < trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_UPPER_BOUND; | ||
658 | a += 4) | ||
659 | iwl_write_targ_mem(trans, a, 0); | ||
660 | /* reset tx status memory */ | ||
661 | for (; a < trans_pcie->scd_base_addr + SCD_TX_STTS_MEM_UPPER_BOUND; | ||
662 | a += 4) | ||
663 | iwl_write_targ_mem(trans, a, 0); | ||
664 | for (; a < trans_pcie->scd_base_addr + | ||
665 | SCD_TRANS_TBL_OFFSET_QUEUE( | ||
666 | trans->cfg->base_params->num_of_queues); | ||
667 | a += 4) | ||
668 | iwl_write_targ_mem(trans, a, 0); | ||
669 | |||
670 | iwl_write_prph(trans, SCD_DRAM_BASE_ADDR, | ||
671 | trans_pcie->scd_bc_tbls.dma >> 10); | ||
672 | |||
673 | /* The chain extension of the SCD doesn't work well. This feature is | ||
674 | * enabled by default by the HW, so we need to disable it manually. | ||
675 | */ | ||
676 | iwl_write_prph(trans, SCD_CHAINEXT_EN, 0); | ||
677 | |||
678 | iwl_trans_ac_txq_enable(trans, trans_pcie->cmd_queue, | ||
679 | trans_pcie->cmd_fifo); | ||
680 | |||
681 | /* Activate all Tx DMA/FIFO channels */ | ||
682 | iwl_pcie_txq_set_sched(trans, IWL_MASK(0, 7)); | ||
683 | |||
684 | /* Enable DMA channel */ | ||
685 | for (chan = 0; chan < FH_TCSR_CHNL_NUM; chan++) | ||
686 | iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(chan), | ||
687 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | | ||
688 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE); | ||
689 | |||
690 | /* Update FH chicken bits */ | ||
691 | reg_val = iwl_read_direct32(trans, FH_TX_CHICKEN_BITS_REG); | ||
692 | iwl_write_direct32(trans, FH_TX_CHICKEN_BITS_REG, | ||
693 | reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); | ||
694 | |||
695 | /* Enable L1-Active */ | ||
696 | iwl_clear_bits_prph(trans, APMG_PCIDEV_STT_REG, | ||
697 | APMG_PCIDEV_STT_VAL_L1_ACT_DIS); | ||
323 | } | 698 | } |
324 | 699 | ||
325 | /** | 700 | /* |
326 | * iwl_queue_init - Initialize queue's high/low-water and read/write indexes | 701 | * iwl_pcie_tx_stop - Stop all Tx DMA channels |
327 | */ | 702 | */ |
328 | int iwl_queue_init(struct iwl_queue *q, int count, int slots_num, u32 id) | 703 | int iwl_pcie_tx_stop(struct iwl_trans *trans) |
329 | { | 704 | { |
330 | q->n_bd = count; | 705 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
331 | q->n_window = slots_num; | 706 | int ch, txq_id, ret; |
332 | q->id = id; | 707 | unsigned long flags; |
333 | 708 | ||
334 | /* count must be power-of-two size, otherwise iwl_queue_inc_wrap | 709 | /* Turn off all Tx DMA fifos */ |
335 | * and iwl_queue_dec_wrap are broken. */ | 710 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); |
336 | if (WARN_ON(!is_power_of_2(count))) | ||
337 | return -EINVAL; | ||
338 | 711 | ||
339 | /* slots_num must be power-of-two size, otherwise | 712 | iwl_pcie_txq_set_sched(trans, 0); |
340 | * get_cmd_index is broken. */ | ||
341 | if (WARN_ON(!is_power_of_2(slots_num))) | ||
342 | return -EINVAL; | ||
343 | 713 | ||
344 | q->low_mark = q->n_window / 4; | 714 | /* Stop each Tx DMA channel, and wait for it to be idle */ |
345 | if (q->low_mark < 4) | 715 | for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) { |
346 | q->low_mark = 4; | 716 | iwl_write_direct32(trans, |
717 | FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0); | ||
718 | ret = iwl_poll_direct_bit(trans, FH_TSSR_TX_STATUS_REG, | ||
719 | FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), 1000); | ||
720 | if (ret < 0) | ||
721 | IWL_ERR(trans, | ||
722 | "Failing on timeout while stopping DMA channel %d [0x%08x]\n", | ||
723 | ch, | ||
724 | iwl_read_direct32(trans, | ||
725 | FH_TSSR_TX_STATUS_REG)); | ||
726 | } | ||
727 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | ||
347 | 728 | ||
348 | q->high_mark = q->n_window / 8; | 729 | if (!trans_pcie->txq) { |
349 | if (q->high_mark < 2) | 730 | IWL_WARN(trans, |
350 | q->high_mark = 2; | 731 | "Stopping tx queues that aren't allocated...\n"); |
732 | return 0; | ||
733 | } | ||
351 | 734 | ||
352 | q->write_ptr = q->read_ptr = 0; | 735 | /* Unmap DMA from host system and free skb's */ |
736 | for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues; | ||
737 | txq_id++) | ||
738 | iwl_pcie_txq_unmap(trans, txq_id); | ||
353 | 739 | ||
354 | return 0; | 740 | return 0; |
355 | } | 741 | } |
356 | 742 | ||
357 | static void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_trans *trans, | 743 | /* |
358 | struct iwl_tx_queue *txq) | 744 | * iwl_trans_tx_free - Free TXQ Context |
745 | * | ||
746 | * Destroy all TX DMA queues and structures | ||
747 | */ | ||
748 | void iwl_pcie_tx_free(struct iwl_trans *trans) | ||
359 | { | 749 | { |
360 | struct iwl_trans_pcie *trans_pcie = | 750 | int txq_id; |
361 | IWL_TRANS_GET_PCIE_TRANS(trans); | 751 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
362 | struct iwlagn_scd_bc_tbl *scd_bc_tbl = trans_pcie->scd_bc_tbls.addr; | ||
363 | int txq_id = txq->q.id; | ||
364 | int read_ptr = txq->q.read_ptr; | ||
365 | u8 sta_id = 0; | ||
366 | __le16 bc_ent; | ||
367 | struct iwl_tx_cmd *tx_cmd = | ||
368 | (void *)txq->entries[txq->q.read_ptr].cmd->payload; | ||
369 | 752 | ||
370 | WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX); | 753 | /* Tx queues */ |
754 | if (trans_pcie->txq) { | ||
755 | for (txq_id = 0; | ||
756 | txq_id < trans->cfg->base_params->num_of_queues; txq_id++) | ||
757 | iwl_pcie_txq_free(trans, txq_id); | ||
758 | } | ||
371 | 759 | ||
372 | if (txq_id != trans_pcie->cmd_queue) | 760 | kfree(trans_pcie->txq); |
373 | sta_id = tx_cmd->sta_id; | 761 | trans_pcie->txq = NULL; |
374 | 762 | ||
375 | bc_ent = cpu_to_le16(1 | (sta_id << 12)); | 763 | iwl_pcie_free_dma_ptr(trans, &trans_pcie->kw); |
376 | scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent; | ||
377 | 764 | ||
378 | if (read_ptr < TFD_QUEUE_SIZE_BC_DUP) | 765 | iwl_pcie_free_dma_ptr(trans, &trans_pcie->scd_bc_tbls); |
379 | scd_bc_tbl[txq_id]. | 766 | } |
380 | tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent; | 767 | |
768 | /* | ||
769 | * iwl_pcie_tx_alloc - allocate TX context | ||
770 | * Allocate all Tx DMA structures and initialize them | ||
771 | */ | ||
772 | static int iwl_pcie_tx_alloc(struct iwl_trans *trans) | ||
773 | { | ||
774 | int ret; | ||
775 | int txq_id, slots_num; | ||
776 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
777 | |||
778 | u16 scd_bc_tbls_size = trans->cfg->base_params->num_of_queues * | ||
779 | sizeof(struct iwlagn_scd_bc_tbl); | ||
780 | |||
781 | /*It is not allowed to alloc twice, so warn when this happens. | ||
782 | * We cannot rely on the previous allocation, so free and fail */ | ||
783 | if (WARN_ON(trans_pcie->txq)) { | ||
784 | ret = -EINVAL; | ||
785 | goto error; | ||
786 | } | ||
787 | |||
788 | ret = iwl_pcie_alloc_dma_ptr(trans, &trans_pcie->scd_bc_tbls, | ||
789 | scd_bc_tbls_size); | ||
790 | if (ret) { | ||
791 | IWL_ERR(trans, "Scheduler BC Table allocation failed\n"); | ||
792 | goto error; | ||
793 | } | ||
794 | |||
795 | /* Alloc keep-warm buffer */ | ||
796 | ret = iwl_pcie_alloc_dma_ptr(trans, &trans_pcie->kw, IWL_KW_SIZE); | ||
797 | if (ret) { | ||
798 | IWL_ERR(trans, "Keep Warm allocation failed\n"); | ||
799 | goto error; | ||
800 | } | ||
801 | |||
802 | trans_pcie->txq = kcalloc(trans->cfg->base_params->num_of_queues, | ||
803 | sizeof(struct iwl_txq), GFP_KERNEL); | ||
804 | if (!trans_pcie->txq) { | ||
805 | IWL_ERR(trans, "Not enough memory for txq\n"); | ||
806 | ret = ENOMEM; | ||
807 | goto error; | ||
808 | } | ||
809 | |||
810 | /* Alloc and init all Tx queues, including the command queue (#4/#9) */ | ||
811 | for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues; | ||
812 | txq_id++) { | ||
813 | slots_num = (txq_id == trans_pcie->cmd_queue) ? | ||
814 | TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; | ||
815 | ret = iwl_pcie_txq_alloc(trans, &trans_pcie->txq[txq_id], | ||
816 | slots_num, txq_id); | ||
817 | if (ret) { | ||
818 | IWL_ERR(trans, "Tx %d queue alloc failed\n", txq_id); | ||
819 | goto error; | ||
820 | } | ||
821 | } | ||
822 | |||
823 | return 0; | ||
824 | |||
825 | error: | ||
826 | iwl_pcie_tx_free(trans); | ||
827 | |||
828 | return ret; | ||
829 | } | ||
830 | int iwl_pcie_tx_init(struct iwl_trans *trans) | ||
831 | { | ||
832 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
833 | int ret; | ||
834 | int txq_id, slots_num; | ||
835 | unsigned long flags; | ||
836 | bool alloc = false; | ||
837 | |||
838 | if (!trans_pcie->txq) { | ||
839 | ret = iwl_pcie_tx_alloc(trans); | ||
840 | if (ret) | ||
841 | goto error; | ||
842 | alloc = true; | ||
843 | } | ||
844 | |||
845 | spin_lock_irqsave(&trans_pcie->irq_lock, flags); | ||
846 | |||
847 | /* Turn off all Tx DMA fifos */ | ||
848 | iwl_write_prph(trans, SCD_TXFACT, 0); | ||
849 | |||
850 | /* Tell NIC where to find the "keep warm" buffer */ | ||
851 | iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG, | ||
852 | trans_pcie->kw.dma >> 4); | ||
853 | |||
854 | spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); | ||
855 | |||
856 | /* Alloc and init all Tx queues, including the command queue (#4/#9) */ | ||
857 | for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues; | ||
858 | txq_id++) { | ||
859 | slots_num = (txq_id == trans_pcie->cmd_queue) ? | ||
860 | TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; | ||
861 | ret = iwl_pcie_txq_init(trans, &trans_pcie->txq[txq_id], | ||
862 | slots_num, txq_id); | ||
863 | if (ret) { | ||
864 | IWL_ERR(trans, "Tx %d queue init failed\n", txq_id); | ||
865 | goto error; | ||
866 | } | ||
867 | } | ||
868 | |||
869 | return 0; | ||
870 | error: | ||
871 | /*Upon error, free only if we allocated something */ | ||
872 | if (alloc) | ||
873 | iwl_pcie_tx_free(trans); | ||
874 | return ret; | ||
875 | } | ||
876 | |||
877 | static inline void iwl_pcie_txq_progress(struct iwl_trans_pcie *trans_pcie, | ||
878 | struct iwl_txq *txq) | ||
879 | { | ||
880 | if (!trans_pcie->wd_timeout) | ||
881 | return; | ||
882 | |||
883 | /* | ||
884 | * if empty delete timer, otherwise move timer forward | ||
885 | * since we're making progress on this queue | ||
886 | */ | ||
887 | if (txq->q.read_ptr == txq->q.write_ptr) | ||
888 | del_timer(&txq->stuck_timer); | ||
889 | else | ||
890 | mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); | ||
891 | } | ||
892 | |||
893 | /* Frees buffers until index _not_ inclusive */ | ||
894 | void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, | ||
895 | struct sk_buff_head *skbs) | ||
896 | { | ||
897 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
898 | struct iwl_txq *txq = &trans_pcie->txq[txq_id]; | ||
899 | /* n_bd is usually 256 => n_bd - 1 = 0xff */ | ||
900 | int tfd_num = ssn & (txq->q.n_bd - 1); | ||
901 | struct iwl_queue *q = &txq->q; | ||
902 | int last_to_free; | ||
903 | |||
904 | /* This function is not meant to release cmd queue*/ | ||
905 | if (WARN_ON(txq_id == trans_pcie->cmd_queue)) | ||
906 | return; | ||
907 | |||
908 | spin_lock(&txq->lock); | ||
909 | |||
910 | if (txq->q.read_ptr == tfd_num) | ||
911 | goto out; | ||
912 | |||
913 | IWL_DEBUG_TX_REPLY(trans, "[Q %d] %d -> %d (%d)\n", | ||
914 | txq_id, txq->q.read_ptr, tfd_num, ssn); | ||
915 | |||
916 | /*Since we free until index _not_ inclusive, the one before index is | ||
917 | * the last we will free. This one must be used */ | ||
918 | last_to_free = iwl_queue_dec_wrap(tfd_num, q->n_bd); | ||
919 | |||
920 | if (!iwl_queue_used(q, last_to_free)) { | ||
921 | IWL_ERR(trans, | ||
922 | "%s: Read index for DMA queue txq id (%d), last_to_free %d is out of range [0-%d] %d %d.\n", | ||
923 | __func__, txq_id, last_to_free, q->n_bd, | ||
924 | q->write_ptr, q->read_ptr); | ||
925 | goto out; | ||
926 | } | ||
927 | |||
928 | if (WARN_ON(!skb_queue_empty(skbs))) | ||
929 | goto out; | ||
930 | |||
931 | for (; | ||
932 | q->read_ptr != tfd_num; | ||
933 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { | ||
934 | |||
935 | if (WARN_ON_ONCE(txq->entries[txq->q.read_ptr].skb == NULL)) | ||
936 | continue; | ||
937 | |||
938 | __skb_queue_tail(skbs, txq->entries[txq->q.read_ptr].skb); | ||
939 | |||
940 | txq->entries[txq->q.read_ptr].skb = NULL; | ||
941 | |||
942 | iwl_pcie_txq_inval_byte_cnt_tbl(trans, txq); | ||
943 | |||
944 | iwl_pcie_txq_free_tfd(trans, txq, DMA_TO_DEVICE); | ||
945 | } | ||
946 | |||
947 | iwl_pcie_txq_progress(trans_pcie, txq); | ||
948 | |||
949 | if (iwl_queue_space(&txq->q) > txq->q.low_mark) | ||
950 | iwl_wake_queue(trans, txq); | ||
951 | out: | ||
952 | spin_unlock(&txq->lock); | ||
953 | } | ||
954 | |||
955 | /* | ||
956 | * iwl_pcie_cmdq_reclaim - Reclaim TX command queue entries already Tx'd | ||
957 | * | ||
958 | * When FW advances 'R' index, all entries between old and new 'R' index | ||
959 | * need to be reclaimed. As result, some free space forms. If there is | ||
960 | * enough free space (> low mark), wake the stack that feeds us. | ||
961 | */ | ||
962 | static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx) | ||
963 | { | ||
964 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
965 | struct iwl_txq *txq = &trans_pcie->txq[txq_id]; | ||
966 | struct iwl_queue *q = &txq->q; | ||
967 | int nfreed = 0; | ||
968 | |||
969 | lockdep_assert_held(&txq->lock); | ||
970 | |||
971 | if ((idx >= q->n_bd) || (!iwl_queue_used(q, idx))) { | ||
972 | IWL_ERR(trans, | ||
973 | "%s: Read index for DMA queue txq id (%d), index %d is out of range [0-%d] %d %d.\n", | ||
974 | __func__, txq_id, idx, q->n_bd, | ||
975 | q->write_ptr, q->read_ptr); | ||
976 | return; | ||
977 | } | ||
978 | |||
979 | for (idx = iwl_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx; | ||
980 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { | ||
981 | |||
982 | if (nfreed++ > 0) { | ||
983 | IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n", | ||
984 | idx, q->write_ptr, q->read_ptr); | ||
985 | iwl_op_mode_nic_error(trans->op_mode); | ||
986 | } | ||
987 | } | ||
988 | |||
989 | iwl_pcie_txq_progress(trans_pcie, txq); | ||
381 | } | 990 | } |
382 | 991 | ||
383 | static int iwl_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid, | 992 | static int iwl_pcie_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid, |
384 | u16 txq_id) | 993 | u16 txq_id) |
385 | { | 994 | { |
386 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 995 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
@@ -405,7 +1014,8 @@ static int iwl_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid, | |||
405 | return 0; | 1014 | return 0; |
406 | } | 1015 | } |
407 | 1016 | ||
408 | static inline void iwl_txq_set_inactive(struct iwl_trans *trans, u16 txq_id) | 1017 | static inline void iwl_pcie_txq_set_inactive(struct iwl_trans *trans, |
1018 | u16 txq_id) | ||
409 | { | 1019 | { |
410 | /* Simply stop the queue, but don't change any configuration; | 1020 | /* Simply stop the queue, but don't change any configuration; |
411 | * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */ | 1021 | * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */ |
@@ -424,7 +1034,7 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, | |||
424 | WARN_ONCE(1, "queue %d already used - expect issues", txq_id); | 1034 | WARN_ONCE(1, "queue %d already used - expect issues", txq_id); |
425 | 1035 | ||
426 | /* Stop this Tx queue before configuring it */ | 1036 | /* Stop this Tx queue before configuring it */ |
427 | iwl_txq_set_inactive(trans, txq_id); | 1037 | iwl_pcie_txq_set_inactive(trans, txq_id); |
428 | 1038 | ||
429 | /* Set this queue as a chain-building queue unless it is CMD queue */ | 1039 | /* Set this queue as a chain-building queue unless it is CMD queue */ |
430 | if (txq_id != trans_pcie->cmd_queue) | 1040 | if (txq_id != trans_pcie->cmd_queue) |
@@ -435,7 +1045,7 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, | |||
435 | u16 ra_tid = BUILD_RAxTID(sta_id, tid); | 1045 | u16 ra_tid = BUILD_RAxTID(sta_id, tid); |
436 | 1046 | ||
437 | /* Map receiver-address / traffic-ID to this queue */ | 1047 | /* Map receiver-address / traffic-ID to this queue */ |
438 | iwl_txq_set_ratid_map(trans, ra_tid, txq_id); | 1048 | iwl_pcie_txq_set_ratid_map(trans, ra_tid, txq_id); |
439 | 1049 | ||
440 | /* enable aggregations for the queue */ | 1050 | /* enable aggregations for the queue */ |
441 | iwl_set_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); | 1051 | iwl_set_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); |
@@ -489,18 +1099,20 @@ void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) | |||
489 | return; | 1099 | return; |
490 | } | 1100 | } |
491 | 1101 | ||
492 | iwl_txq_set_inactive(trans, txq_id); | 1102 | iwl_pcie_txq_set_inactive(trans, txq_id); |
493 | 1103 | ||
494 | _iwl_write_targ_mem_dwords(trans, stts_addr, | 1104 | _iwl_write_targ_mem_dwords(trans, stts_addr, |
495 | zero_val, ARRAY_SIZE(zero_val)); | 1105 | zero_val, ARRAY_SIZE(zero_val)); |
496 | 1106 | ||
1107 | iwl_pcie_txq_unmap(trans, txq_id); | ||
1108 | |||
497 | IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id); | 1109 | IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id); |
498 | } | 1110 | } |
499 | 1111 | ||
500 | /*************** HOST COMMAND QUEUE FUNCTIONS *****/ | 1112 | /*************** HOST COMMAND QUEUE FUNCTIONS *****/ |
501 | 1113 | ||
502 | /** | 1114 | /* |
503 | * iwl_enqueue_hcmd - enqueue a uCode command | 1115 | * iwl_pcie_enqueue_hcmd - enqueue a uCode command |
504 | * @priv: device private data point | 1116 | * @priv: device private data point |
505 | * @cmd: a point to the ucode command structure | 1117 | * @cmd: a point to the ucode command structure |
506 | * | 1118 | * |
@@ -508,15 +1120,17 @@ void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) | |||
508 | * failed. On success, it turns the index (> 0) of command in the | 1120 | * failed. On success, it turns the index (> 0) of command in the |
509 | * command queue. | 1121 | * command queue. |
510 | */ | 1122 | */ |
511 | static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | 1123 | static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, |
1124 | struct iwl_host_cmd *cmd) | ||
512 | { | 1125 | { |
513 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1126 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
514 | struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; | 1127 | struct iwl_txq *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; |
515 | struct iwl_queue *q = &txq->q; | 1128 | struct iwl_queue *q = &txq->q; |
516 | struct iwl_device_cmd *out_cmd; | 1129 | struct iwl_device_cmd *out_cmd; |
517 | struct iwl_cmd_meta *out_meta; | 1130 | struct iwl_cmd_meta *out_meta; |
1131 | void *dup_buf = NULL; | ||
518 | dma_addr_t phys_addr; | 1132 | dma_addr_t phys_addr; |
519 | u32 idx; | 1133 | int idx; |
520 | u16 copy_size, cmd_size; | 1134 | u16 copy_size, cmd_size; |
521 | bool had_nocopy = false; | 1135 | bool had_nocopy = false; |
522 | int i; | 1136 | int i; |
@@ -533,10 +1147,33 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
533 | continue; | 1147 | continue; |
534 | if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) { | 1148 | if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) { |
535 | had_nocopy = true; | 1149 | had_nocopy = true; |
1150 | if (WARN_ON(cmd->dataflags[i] & IWL_HCMD_DFL_DUP)) { | ||
1151 | idx = -EINVAL; | ||
1152 | goto free_dup_buf; | ||
1153 | } | ||
1154 | } else if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP) { | ||
1155 | /* | ||
1156 | * This is also a chunk that isn't copied | ||
1157 | * to the static buffer so set had_nocopy. | ||
1158 | */ | ||
1159 | had_nocopy = true; | ||
1160 | |||
1161 | /* only allowed once */ | ||
1162 | if (WARN_ON(dup_buf)) { | ||
1163 | idx = -EINVAL; | ||
1164 | goto free_dup_buf; | ||
1165 | } | ||
1166 | |||
1167 | dup_buf = kmemdup(cmd->data[i], cmd->len[i], | ||
1168 | GFP_ATOMIC); | ||
1169 | if (!dup_buf) | ||
1170 | return -ENOMEM; | ||
536 | } else { | 1171 | } else { |
537 | /* NOCOPY must not be followed by normal! */ | 1172 | /* NOCOPY must not be followed by normal! */ |
538 | if (WARN_ON(had_nocopy)) | 1173 | if (WARN_ON(had_nocopy)) { |
539 | return -EINVAL; | 1174 | idx = -EINVAL; |
1175 | goto free_dup_buf; | ||
1176 | } | ||
540 | copy_size += cmd->len[i]; | 1177 | copy_size += cmd->len[i]; |
541 | } | 1178 | } |
542 | cmd_size += cmd->len[i]; | 1179 | cmd_size += cmd->len[i]; |
@@ -550,9 +1187,10 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
550 | */ | 1187 | */ |
551 | if (WARN(copy_size > TFD_MAX_PAYLOAD_SIZE, | 1188 | if (WARN(copy_size > TFD_MAX_PAYLOAD_SIZE, |
552 | "Command %s (%#x) is too large (%d bytes)\n", | 1189 | "Command %s (%#x) is too large (%d bytes)\n", |
553 | trans_pcie_get_cmd_string(trans_pcie, cmd->id), | 1190 | get_cmd_string(trans_pcie, cmd->id), cmd->id, copy_size)) { |
554 | cmd->id, copy_size)) | 1191 | idx = -EINVAL; |
555 | return -EINVAL; | 1192 | goto free_dup_buf; |
1193 | } | ||
556 | 1194 | ||
557 | spin_lock_bh(&txq->lock); | 1195 | spin_lock_bh(&txq->lock); |
558 | 1196 | ||
@@ -561,7 +1199,8 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
561 | 1199 | ||
562 | IWL_ERR(trans, "No space in command queue\n"); | 1200 | IWL_ERR(trans, "No space in command queue\n"); |
563 | iwl_op_mode_cmd_queue_full(trans->op_mode); | 1201 | iwl_op_mode_cmd_queue_full(trans->op_mode); |
564 | return -ENOSPC; | 1202 | idx = -ENOSPC; |
1203 | goto free_dup_buf; | ||
565 | } | 1204 | } |
566 | 1205 | ||
567 | idx = get_cmd_index(q, q->write_ptr); | 1206 | idx = get_cmd_index(q, q->write_ptr); |
@@ -585,7 +1224,8 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
585 | for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { | 1224 | for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { |
586 | if (!cmd->len[i]) | 1225 | if (!cmd->len[i]) |
587 | continue; | 1226 | continue; |
588 | if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) | 1227 | if (cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY | |
1228 | IWL_HCMD_DFL_DUP)) | ||
589 | break; | 1229 | break; |
590 | memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], cmd->len[i]); | 1230 | memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], cmd->len[i]); |
591 | cmd_pos += cmd->len[i]; | 1231 | cmd_pos += cmd->len[i]; |
@@ -610,7 +1250,7 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
610 | 1250 | ||
611 | IWL_DEBUG_HC(trans, | 1251 | IWL_DEBUG_HC(trans, |
612 | "Sending command %s (#%x), seq: 0x%04X, %d bytes at %d[%d]:%d\n", | 1252 | "Sending command %s (#%x), seq: 0x%04X, %d bytes at %d[%d]:%d\n", |
613 | trans_pcie_get_cmd_string(trans_pcie, out_cmd->hdr.cmd), | 1253 | get_cmd_string(trans_pcie, out_cmd->hdr.cmd), |
614 | out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), | 1254 | out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), |
615 | cmd_size, q->write_ptr, idx, trans_pcie->cmd_queue); | 1255 | cmd_size, q->write_ptr, idx, trans_pcie->cmd_queue); |
616 | 1256 | ||
@@ -624,28 +1264,35 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
624 | dma_unmap_addr_set(out_meta, mapping, phys_addr); | 1264 | dma_unmap_addr_set(out_meta, mapping, phys_addr); |
625 | dma_unmap_len_set(out_meta, len, copy_size); | 1265 | dma_unmap_len_set(out_meta, len, copy_size); |
626 | 1266 | ||
627 | iwlagn_txq_attach_buf_to_tfd(trans, txq, phys_addr, copy_size, 1); | 1267 | iwl_pcie_txq_build_tfd(trans, txq, phys_addr, copy_size, 1); |
628 | 1268 | ||
629 | for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { | 1269 | for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { |
1270 | const void *data = cmd->data[i]; | ||
1271 | |||
630 | if (!cmd->len[i]) | 1272 | if (!cmd->len[i]) |
631 | continue; | 1273 | continue; |
632 | if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)) | 1274 | if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY | |
1275 | IWL_HCMD_DFL_DUP))) | ||
633 | continue; | 1276 | continue; |
634 | phys_addr = dma_map_single(trans->dev, (void *)cmd->data[i], | 1277 | if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP) |
1278 | data = dup_buf; | ||
1279 | phys_addr = dma_map_single(trans->dev, (void *)data, | ||
635 | cmd->len[i], DMA_BIDIRECTIONAL); | 1280 | cmd->len[i], DMA_BIDIRECTIONAL); |
636 | if (dma_mapping_error(trans->dev, phys_addr)) { | 1281 | if (dma_mapping_error(trans->dev, phys_addr)) { |
637 | iwl_unmap_tfd(trans, out_meta, | 1282 | iwl_pcie_tfd_unmap(trans, out_meta, |
638 | &txq->tfds[q->write_ptr], | 1283 | &txq->tfds[q->write_ptr], |
639 | DMA_BIDIRECTIONAL); | 1284 | DMA_BIDIRECTIONAL); |
640 | idx = -ENOMEM; | 1285 | idx = -ENOMEM; |
641 | goto out; | 1286 | goto out; |
642 | } | 1287 | } |
643 | 1288 | ||
644 | iwlagn_txq_attach_buf_to_tfd(trans, txq, phys_addr, | 1289 | iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmd->len[i], 0); |
645 | cmd->len[i], 0); | ||
646 | } | 1290 | } |
647 | 1291 | ||
648 | out_meta->flags = cmd->flags; | 1292 | out_meta->flags = cmd->flags; |
1293 | if (WARN_ON_ONCE(txq->entries[idx].free_buf)) | ||
1294 | kfree(txq->entries[idx].free_buf); | ||
1295 | txq->entries[idx].free_buf = dup_buf; | ||
649 | 1296 | ||
650 | txq->need_update = 1; | 1297 | txq->need_update = 1; |
651 | 1298 | ||
@@ -658,70 +1305,18 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
658 | 1305 | ||
659 | /* Increment and update queue's write index */ | 1306 | /* Increment and update queue's write index */ |
660 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); | 1307 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); |
661 | iwl_txq_update_write_ptr(trans, txq); | 1308 | iwl_pcie_txq_inc_wr_ptr(trans, txq); |
662 | 1309 | ||
663 | out: | 1310 | out: |
664 | spin_unlock_bh(&txq->lock); | 1311 | spin_unlock_bh(&txq->lock); |
1312 | free_dup_buf: | ||
1313 | if (idx < 0) | ||
1314 | kfree(dup_buf); | ||
665 | return idx; | 1315 | return idx; |
666 | } | 1316 | } |
667 | 1317 | ||
668 | static inline void iwl_queue_progress(struct iwl_trans_pcie *trans_pcie, | 1318 | /* |
669 | struct iwl_tx_queue *txq) | 1319 | * iwl_pcie_hcmd_complete - Pull unused buffers off the queue and reclaim them |
670 | { | ||
671 | if (!trans_pcie->wd_timeout) | ||
672 | return; | ||
673 | |||
674 | /* | ||
675 | * if empty delete timer, otherwise move timer forward | ||
676 | * since we're making progress on this queue | ||
677 | */ | ||
678 | if (txq->q.read_ptr == txq->q.write_ptr) | ||
679 | del_timer(&txq->stuck_timer); | ||
680 | else | ||
681 | mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); | ||
682 | } | ||
683 | |||
684 | /** | ||
685 | * iwl_hcmd_queue_reclaim - Reclaim TX command queue entries already Tx'd | ||
686 | * | ||
687 | * When FW advances 'R' index, all entries between old and new 'R' index | ||
688 | * need to be reclaimed. As result, some free space forms. If there is | ||
689 | * enough free space (> low mark), wake the stack that feeds us. | ||
690 | */ | ||
691 | static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id, | ||
692 | int idx) | ||
693 | { | ||
694 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
695 | struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; | ||
696 | struct iwl_queue *q = &txq->q; | ||
697 | int nfreed = 0; | ||
698 | |||
699 | lockdep_assert_held(&txq->lock); | ||
700 | |||
701 | if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) { | ||
702 | IWL_ERR(trans, | ||
703 | "%s: Read index for DMA queue txq id (%d), index %d is out of range [0-%d] %d %d.\n", | ||
704 | __func__, txq_id, idx, q->n_bd, | ||
705 | q->write_ptr, q->read_ptr); | ||
706 | return; | ||
707 | } | ||
708 | |||
709 | for (idx = iwl_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx; | ||
710 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { | ||
711 | |||
712 | if (nfreed++ > 0) { | ||
713 | IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n", | ||
714 | idx, q->write_ptr, q->read_ptr); | ||
715 | iwl_op_mode_nic_error(trans->op_mode); | ||
716 | } | ||
717 | |||
718 | } | ||
719 | |||
720 | iwl_queue_progress(trans_pcie, txq); | ||
721 | } | ||
722 | |||
723 | /** | ||
724 | * iwl_tx_cmd_complete - Pull unused buffers off the queue and reclaim them | ||
725 | * @rxb: Rx buffer to reclaim | 1320 | * @rxb: Rx buffer to reclaim |
726 | * @handler_status: return value of the handler of the command | 1321 | * @handler_status: return value of the handler of the command |
727 | * (put in setup_rx_handlers) | 1322 | * (put in setup_rx_handlers) |
@@ -730,8 +1325,8 @@ static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id, | |||
730 | * will be executed. The attached skb (if present) will only be freed | 1325 | * will be executed. The attached skb (if present) will only be freed |
731 | * if the callback returns 1 | 1326 | * if the callback returns 1 |
732 | */ | 1327 | */ |
733 | void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb, | 1328 | void iwl_pcie_hcmd_complete(struct iwl_trans *trans, |
734 | int handler_status) | 1329 | struct iwl_rx_cmd_buffer *rxb, int handler_status) |
735 | { | 1330 | { |
736 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 1331 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
737 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); | 1332 | u16 sequence = le16_to_cpu(pkt->hdr.sequence); |
@@ -741,7 +1336,7 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb, | |||
741 | struct iwl_device_cmd *cmd; | 1336 | struct iwl_device_cmd *cmd; |
742 | struct iwl_cmd_meta *meta; | 1337 | struct iwl_cmd_meta *meta; |
743 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1338 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
744 | struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; | 1339 | struct iwl_txq *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; |
745 | 1340 | ||
746 | /* If a Tx command is being handled and it isn't in the actual | 1341 | /* If a Tx command is being handled and it isn't in the actual |
747 | * command queue then there a command routing bug has been introduced | 1342 | * command queue then there a command routing bug has been introduced |
@@ -761,7 +1356,7 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb, | |||
761 | cmd = txq->entries[cmd_index].cmd; | 1356 | cmd = txq->entries[cmd_index].cmd; |
762 | meta = &txq->entries[cmd_index].meta; | 1357 | meta = &txq->entries[cmd_index].meta; |
763 | 1358 | ||
764 | iwl_unmap_tfd(trans, meta, &txq->tfds[index], DMA_BIDIRECTIONAL); | 1359 | iwl_pcie_tfd_unmap(trans, meta, &txq->tfds[index], DMA_BIDIRECTIONAL); |
765 | 1360 | ||
766 | /* Input error checking is done when commands are added to queue. */ | 1361 | /* Input error checking is done when commands are added to queue. */ |
767 | if (meta->flags & CMD_WANT_SKB) { | 1362 | if (meta->flags & CMD_WANT_SKB) { |
@@ -773,20 +1368,18 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb, | |||
773 | meta->source->handler_status = handler_status; | 1368 | meta->source->handler_status = handler_status; |
774 | } | 1369 | } |
775 | 1370 | ||
776 | iwl_hcmd_queue_reclaim(trans, txq_id, index); | 1371 | iwl_pcie_cmdq_reclaim(trans, txq_id, index); |
777 | 1372 | ||
778 | if (!(meta->flags & CMD_ASYNC)) { | 1373 | if (!(meta->flags & CMD_ASYNC)) { |
779 | if (!test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) { | 1374 | if (!test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) { |
780 | IWL_WARN(trans, | 1375 | IWL_WARN(trans, |
781 | "HCMD_ACTIVE already clear for command %s\n", | 1376 | "HCMD_ACTIVE already clear for command %s\n", |
782 | trans_pcie_get_cmd_string(trans_pcie, | 1377 | get_cmd_string(trans_pcie, cmd->hdr.cmd)); |
783 | cmd->hdr.cmd)); | ||
784 | } | 1378 | } |
785 | clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); | 1379 | clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); |
786 | IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n", | 1380 | IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n", |
787 | trans_pcie_get_cmd_string(trans_pcie, | 1381 | get_cmd_string(trans_pcie, cmd->hdr.cmd)); |
788 | cmd->hdr.cmd)); | 1382 | wake_up(&trans_pcie->wait_command_queue); |
789 | wake_up(&trans->wait_command_queue); | ||
790 | } | 1383 | } |
791 | 1384 | ||
792 | meta->flags = 0; | 1385 | meta->flags = 0; |
@@ -796,7 +1389,8 @@ void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb, | |||
796 | 1389 | ||
797 | #define HOST_COMPLETE_TIMEOUT (2 * HZ) | 1390 | #define HOST_COMPLETE_TIMEOUT (2 * HZ) |
798 | 1391 | ||
799 | static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | 1392 | static int iwl_pcie_send_hcmd_async(struct iwl_trans *trans, |
1393 | struct iwl_host_cmd *cmd) | ||
800 | { | 1394 | { |
801 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1395 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
802 | int ret; | 1396 | int ret; |
@@ -805,59 +1399,59 @@ static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
805 | if (WARN_ON(cmd->flags & CMD_WANT_SKB)) | 1399 | if (WARN_ON(cmd->flags & CMD_WANT_SKB)) |
806 | return -EINVAL; | 1400 | return -EINVAL; |
807 | 1401 | ||
808 | 1402 | ret = iwl_pcie_enqueue_hcmd(trans, cmd); | |
809 | ret = iwl_enqueue_hcmd(trans, cmd); | ||
810 | if (ret < 0) { | 1403 | if (ret < 0) { |
811 | IWL_ERR(trans, | 1404 | IWL_ERR(trans, |
812 | "Error sending %s: enqueue_hcmd failed: %d\n", | 1405 | "Error sending %s: enqueue_hcmd failed: %d\n", |
813 | trans_pcie_get_cmd_string(trans_pcie, cmd->id), ret); | 1406 | get_cmd_string(trans_pcie, cmd->id), ret); |
814 | return ret; | 1407 | return ret; |
815 | } | 1408 | } |
816 | return 0; | 1409 | return 0; |
817 | } | 1410 | } |
818 | 1411 | ||
819 | static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | 1412 | static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans, |
1413 | struct iwl_host_cmd *cmd) | ||
820 | { | 1414 | { |
821 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1415 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
822 | int cmd_idx; | 1416 | int cmd_idx; |
823 | int ret; | 1417 | int ret; |
824 | 1418 | ||
825 | IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", | 1419 | IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", |
826 | trans_pcie_get_cmd_string(trans_pcie, cmd->id)); | 1420 | get_cmd_string(trans_pcie, cmd->id)); |
827 | 1421 | ||
828 | if (WARN_ON(test_and_set_bit(STATUS_HCMD_ACTIVE, | 1422 | if (WARN_ON(test_and_set_bit(STATUS_HCMD_ACTIVE, |
829 | &trans_pcie->status))) { | 1423 | &trans_pcie->status))) { |
830 | IWL_ERR(trans, "Command %s: a command is already active!\n", | 1424 | IWL_ERR(trans, "Command %s: a command is already active!\n", |
831 | trans_pcie_get_cmd_string(trans_pcie, cmd->id)); | 1425 | get_cmd_string(trans_pcie, cmd->id)); |
832 | return -EIO; | 1426 | return -EIO; |
833 | } | 1427 | } |
834 | 1428 | ||
835 | IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", | 1429 | IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", |
836 | trans_pcie_get_cmd_string(trans_pcie, cmd->id)); | 1430 | get_cmd_string(trans_pcie, cmd->id)); |
837 | 1431 | ||
838 | cmd_idx = iwl_enqueue_hcmd(trans, cmd); | 1432 | cmd_idx = iwl_pcie_enqueue_hcmd(trans, cmd); |
839 | if (cmd_idx < 0) { | 1433 | if (cmd_idx < 0) { |
840 | ret = cmd_idx; | 1434 | ret = cmd_idx; |
841 | clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); | 1435 | clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); |
842 | IWL_ERR(trans, | 1436 | IWL_ERR(trans, |
843 | "Error sending %s: enqueue_hcmd failed: %d\n", | 1437 | "Error sending %s: enqueue_hcmd failed: %d\n", |
844 | trans_pcie_get_cmd_string(trans_pcie, cmd->id), ret); | 1438 | get_cmd_string(trans_pcie, cmd->id), ret); |
845 | return ret; | 1439 | return ret; |
846 | } | 1440 | } |
847 | 1441 | ||
848 | ret = wait_event_timeout(trans->wait_command_queue, | 1442 | ret = wait_event_timeout(trans_pcie->wait_command_queue, |
849 | !test_bit(STATUS_HCMD_ACTIVE, | 1443 | !test_bit(STATUS_HCMD_ACTIVE, |
850 | &trans_pcie->status), | 1444 | &trans_pcie->status), |
851 | HOST_COMPLETE_TIMEOUT); | 1445 | HOST_COMPLETE_TIMEOUT); |
852 | if (!ret) { | 1446 | if (!ret) { |
853 | if (test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) { | 1447 | if (test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) { |
854 | struct iwl_tx_queue *txq = | 1448 | struct iwl_txq *txq = |
855 | &trans_pcie->txq[trans_pcie->cmd_queue]; | 1449 | &trans_pcie->txq[trans_pcie->cmd_queue]; |
856 | struct iwl_queue *q = &txq->q; | 1450 | struct iwl_queue *q = &txq->q; |
857 | 1451 | ||
858 | IWL_ERR(trans, | 1452 | IWL_ERR(trans, |
859 | "Error sending %s: time out after %dms.\n", | 1453 | "Error sending %s: time out after %dms.\n", |
860 | trans_pcie_get_cmd_string(trans_pcie, cmd->id), | 1454 | get_cmd_string(trans_pcie, cmd->id), |
861 | jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); | 1455 | jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); |
862 | 1456 | ||
863 | IWL_ERR(trans, | 1457 | IWL_ERR(trans, |
@@ -867,16 +1461,28 @@ static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | |||
867 | clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); | 1461 | clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); |
868 | IWL_DEBUG_INFO(trans, | 1462 | IWL_DEBUG_INFO(trans, |
869 | "Clearing HCMD_ACTIVE for command %s\n", | 1463 | "Clearing HCMD_ACTIVE for command %s\n", |
870 | trans_pcie_get_cmd_string(trans_pcie, | 1464 | get_cmd_string(trans_pcie, cmd->id)); |
871 | cmd->id)); | ||
872 | ret = -ETIMEDOUT; | 1465 | ret = -ETIMEDOUT; |
873 | goto cancel; | 1466 | goto cancel; |
874 | } | 1467 | } |
875 | } | 1468 | } |
876 | 1469 | ||
1470 | if (test_bit(STATUS_FW_ERROR, &trans_pcie->status)) { | ||
1471 | IWL_ERR(trans, "FW error in SYNC CMD %s\n", | ||
1472 | get_cmd_string(trans_pcie, cmd->id)); | ||
1473 | ret = -EIO; | ||
1474 | goto cancel; | ||
1475 | } | ||
1476 | |||
1477 | if (test_bit(STATUS_RFKILL, &trans_pcie->status)) { | ||
1478 | IWL_DEBUG_RF_KILL(trans, "RFKILL in SYNC CMD... no rsp\n"); | ||
1479 | ret = -ERFKILL; | ||
1480 | goto cancel; | ||
1481 | } | ||
1482 | |||
877 | if ((cmd->flags & CMD_WANT_SKB) && !cmd->resp_pkt) { | 1483 | if ((cmd->flags & CMD_WANT_SKB) && !cmd->resp_pkt) { |
878 | IWL_ERR(trans, "Error: Response NULL in '%s'\n", | 1484 | IWL_ERR(trans, "Error: Response NULL in '%s'\n", |
879 | trans_pcie_get_cmd_string(trans_pcie, cmd->id)); | 1485 | get_cmd_string(trans_pcie, cmd->id)); |
880 | ret = -EIO; | 1486 | ret = -EIO; |
881 | goto cancel; | 1487 | goto cancel; |
882 | } | 1488 | } |
@@ -903,64 +1509,183 @@ cancel: | |||
903 | return ret; | 1509 | return ret; |
904 | } | 1510 | } |
905 | 1511 | ||
906 | int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) | 1512 | int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) |
907 | { | 1513 | { |
1514 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
1515 | |||
1516 | if (test_bit(STATUS_FW_ERROR, &trans_pcie->status)) | ||
1517 | return -EIO; | ||
1518 | |||
1519 | if (test_bit(STATUS_RFKILL, &trans_pcie->status)) | ||
1520 | return -ERFKILL; | ||
1521 | |||
908 | if (cmd->flags & CMD_ASYNC) | 1522 | if (cmd->flags & CMD_ASYNC) |
909 | return iwl_send_cmd_async(trans, cmd); | 1523 | return iwl_pcie_send_hcmd_async(trans, cmd); |
910 | 1524 | ||
911 | return iwl_send_cmd_sync(trans, cmd); | 1525 | /* We still can fail on RFKILL that can be asserted while we wait */ |
1526 | return iwl_pcie_send_hcmd_sync(trans, cmd); | ||
912 | } | 1527 | } |
913 | 1528 | ||
914 | /* Frees buffers until index _not_ inclusive */ | 1529 | int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, |
915 | int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, | 1530 | struct iwl_device_cmd *dev_cmd, int txq_id) |
916 | struct sk_buff_head *skbs) | ||
917 | { | 1531 | { |
918 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | 1532 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); |
919 | struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; | 1533 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
920 | struct iwl_queue *q = &txq->q; | 1534 | struct iwl_tx_cmd *tx_cmd = (struct iwl_tx_cmd *)dev_cmd->payload; |
921 | int last_to_free; | 1535 | struct iwl_cmd_meta *out_meta; |
922 | int freed = 0; | 1536 | struct iwl_txq *txq; |
1537 | struct iwl_queue *q; | ||
1538 | dma_addr_t phys_addr = 0; | ||
1539 | dma_addr_t txcmd_phys; | ||
1540 | dma_addr_t scratch_phys; | ||
1541 | u16 len, firstlen, secondlen; | ||
1542 | u8 wait_write_ptr = 0; | ||
1543 | __le16 fc = hdr->frame_control; | ||
1544 | u8 hdr_len = ieee80211_hdrlen(fc); | ||
1545 | u16 __maybe_unused wifi_seq; | ||
1546 | |||
1547 | txq = &trans_pcie->txq[txq_id]; | ||
1548 | q = &txq->q; | ||
923 | 1549 | ||
924 | /* This function is not meant to release cmd queue*/ | 1550 | if (unlikely(!test_bit(txq_id, trans_pcie->queue_used))) { |
925 | if (WARN_ON(txq_id == trans_pcie->cmd_queue)) | 1551 | WARN_ON_ONCE(1); |
926 | return 0; | 1552 | return -EINVAL; |
1553 | } | ||
927 | 1554 | ||
928 | lockdep_assert_held(&txq->lock); | 1555 | spin_lock(&txq->lock); |
929 | 1556 | ||
930 | /*Since we free until index _not_ inclusive, the one before index is | 1557 | /* In AGG mode, the index in the ring must correspond to the WiFi |
931 | * the last we will free. This one must be used */ | 1558 | * sequence number. This is a HW requirements to help the SCD to parse |
932 | last_to_free = iwl_queue_dec_wrap(index, q->n_bd); | 1559 | * the BA. |
1560 | * Check here that the packets are in the right place on the ring. | ||
1561 | */ | ||
1562 | #ifdef CONFIG_IWLWIFI_DEBUG | ||
1563 | wifi_seq = SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl)); | ||
1564 | WARN_ONCE((iwl_read_prph(trans, SCD_AGGR_SEL) & BIT(txq_id)) && | ||
1565 | ((wifi_seq & 0xff) != q->write_ptr), | ||
1566 | "Q: %d WiFi Seq %d tfdNum %d", | ||
1567 | txq_id, wifi_seq, q->write_ptr); | ||
1568 | #endif | ||
1569 | |||
1570 | /* Set up driver data for this TFD */ | ||
1571 | txq->entries[q->write_ptr].skb = skb; | ||
1572 | txq->entries[q->write_ptr].cmd = dev_cmd; | ||
1573 | |||
1574 | dev_cmd->hdr.cmd = REPLY_TX; | ||
1575 | dev_cmd->hdr.sequence = | ||
1576 | cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | | ||
1577 | INDEX_TO_SEQ(q->write_ptr))); | ||
1578 | |||
1579 | /* Set up first empty entry in queue's array of Tx/cmd buffers */ | ||
1580 | out_meta = &txq->entries[q->write_ptr].meta; | ||
933 | 1581 | ||
934 | if ((index >= q->n_bd) || | 1582 | /* |
935 | (iwl_queue_used(q, last_to_free) == 0)) { | 1583 | * Use the first empty entry in this queue's command buffer array |
936 | IWL_ERR(trans, | 1584 | * to contain the Tx command and MAC header concatenated together |
937 | "%s: Read index for DMA queue txq id (%d), last_to_free %d is out of range [0-%d] %d %d.\n", | 1585 | * (payload data will be in another buffer). |
938 | __func__, txq_id, last_to_free, q->n_bd, | 1586 | * Size of this varies, due to varying MAC header length. |
939 | q->write_ptr, q->read_ptr); | 1587 | * If end is not dword aligned, we'll have 2 extra bytes at the end |
940 | return 0; | 1588 | * of the MAC header (device reads on dword boundaries). |
1589 | * We'll tell device about this padding later. | ||
1590 | */ | ||
1591 | len = sizeof(struct iwl_tx_cmd) + | ||
1592 | sizeof(struct iwl_cmd_header) + hdr_len; | ||
1593 | firstlen = (len + 3) & ~3; | ||
1594 | |||
1595 | /* Tell NIC about any 2-byte padding after MAC header */ | ||
1596 | if (firstlen != len) | ||
1597 | tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK; | ||
1598 | |||
1599 | /* Physical address of this Tx command's header (not MAC header!), | ||
1600 | * within command buffer array. */ | ||
1601 | txcmd_phys = dma_map_single(trans->dev, | ||
1602 | &dev_cmd->hdr, firstlen, | ||
1603 | DMA_BIDIRECTIONAL); | ||
1604 | if (unlikely(dma_mapping_error(trans->dev, txcmd_phys))) | ||
1605 | goto out_err; | ||
1606 | dma_unmap_addr_set(out_meta, mapping, txcmd_phys); | ||
1607 | dma_unmap_len_set(out_meta, len, firstlen); | ||
1608 | |||
1609 | if (!ieee80211_has_morefrags(fc)) { | ||
1610 | txq->need_update = 1; | ||
1611 | } else { | ||
1612 | wait_write_ptr = 1; | ||
1613 | txq->need_update = 0; | ||
941 | } | 1614 | } |
942 | 1615 | ||
943 | if (WARN_ON(!skb_queue_empty(skbs))) | 1616 | /* Set up TFD's 2nd entry to point directly to remainder of skb, |
944 | return 0; | 1617 | * if any (802.11 null frames have no payload). */ |
1618 | secondlen = skb->len - hdr_len; | ||
1619 | if (secondlen > 0) { | ||
1620 | phys_addr = dma_map_single(trans->dev, skb->data + hdr_len, | ||
1621 | secondlen, DMA_TO_DEVICE); | ||
1622 | if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { | ||
1623 | dma_unmap_single(trans->dev, | ||
1624 | dma_unmap_addr(out_meta, mapping), | ||
1625 | dma_unmap_len(out_meta, len), | ||
1626 | DMA_BIDIRECTIONAL); | ||
1627 | goto out_err; | ||
1628 | } | ||
1629 | } | ||
945 | 1630 | ||
946 | for (; | 1631 | /* Attach buffers to TFD */ |
947 | q->read_ptr != index; | 1632 | iwl_pcie_txq_build_tfd(trans, txq, txcmd_phys, firstlen, 1); |
948 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { | 1633 | if (secondlen > 0) |
1634 | iwl_pcie_txq_build_tfd(trans, txq, phys_addr, secondlen, 0); | ||
949 | 1635 | ||
950 | if (WARN_ON_ONCE(txq->entries[txq->q.read_ptr].skb == NULL)) | 1636 | scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) + |
951 | continue; | 1637 | offsetof(struct iwl_tx_cmd, scratch); |
952 | 1638 | ||
953 | __skb_queue_tail(skbs, txq->entries[txq->q.read_ptr].skb); | 1639 | /* take back ownership of DMA buffer to enable update */ |
1640 | dma_sync_single_for_cpu(trans->dev, txcmd_phys, firstlen, | ||
1641 | DMA_BIDIRECTIONAL); | ||
1642 | tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); | ||
1643 | tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); | ||
954 | 1644 | ||
955 | txq->entries[txq->q.read_ptr].skb = NULL; | 1645 | IWL_DEBUG_TX(trans, "sequence nr = 0X%x\n", |
1646 | le16_to_cpu(dev_cmd->hdr.sequence)); | ||
1647 | IWL_DEBUG_TX(trans, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags)); | ||
956 | 1648 | ||
957 | iwlagn_txq_inval_byte_cnt_tbl(trans, txq); | 1649 | /* Set up entry for this TFD in Tx byte-count array */ |
1650 | iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); | ||
958 | 1651 | ||
959 | iwl_txq_free_tfd(trans, txq, DMA_TO_DEVICE); | 1652 | dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen, |
960 | freed++; | 1653 | DMA_BIDIRECTIONAL); |
961 | } | 1654 | |
1655 | trace_iwlwifi_dev_tx(trans->dev, skb, | ||
1656 | &txq->tfds[txq->q.write_ptr], | ||
1657 | sizeof(struct iwl_tfd), | ||
1658 | &dev_cmd->hdr, firstlen, | ||
1659 | skb->data + hdr_len, secondlen); | ||
1660 | trace_iwlwifi_dev_tx_data(trans->dev, skb, | ||
1661 | skb->data + hdr_len, secondlen); | ||
962 | 1662 | ||
963 | iwl_queue_progress(trans_pcie, txq); | 1663 | /* start timer if queue currently empty */ |
1664 | if (txq->need_update && q->read_ptr == q->write_ptr && | ||
1665 | trans_pcie->wd_timeout) | ||
1666 | mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); | ||
1667 | |||
1668 | /* Tell device the write index *just past* this latest filled TFD */ | ||
1669 | q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); | ||
1670 | iwl_pcie_txq_inc_wr_ptr(trans, txq); | ||
964 | 1671 | ||
965 | return freed; | 1672 | /* |
1673 | * At this point the frame is "transmitted" successfully | ||
1674 | * and we will get a TX status notification eventually, | ||
1675 | * regardless of the value of ret. "ret" only indicates | ||
1676 | * whether or not we should update the write pointer. | ||
1677 | */ | ||
1678 | if (iwl_queue_space(q) < q->high_mark) { | ||
1679 | if (wait_write_ptr) { | ||
1680 | txq->need_update = 1; | ||
1681 | iwl_pcie_txq_inc_wr_ptr(trans, txq); | ||
1682 | } else { | ||
1683 | iwl_stop_queue(trans, txq); | ||
1684 | } | ||
1685 | } | ||
1686 | spin_unlock(&txq->lock); | ||
1687 | return 0; | ||
1688 | out_err: | ||
1689 | spin_unlock(&txq->lock); | ||
1690 | return -1; | ||
966 | } | 1691 | } |
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 1c10b542ab23..ec36868f6fc5 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c | |||
@@ -436,19 +436,19 @@ static int lbs_add_wpa_tlv(u8 *tlv, const u8 *ie, u8 ie_len) | |||
436 | */ | 436 | */ |
437 | 437 | ||
438 | static int lbs_cfg_set_monitor_channel(struct wiphy *wiphy, | 438 | static int lbs_cfg_set_monitor_channel(struct wiphy *wiphy, |
439 | struct ieee80211_channel *channel, | 439 | struct cfg80211_chan_def *chandef) |
440 | enum nl80211_channel_type channel_type) | ||
441 | { | 440 | { |
442 | struct lbs_private *priv = wiphy_priv(wiphy); | 441 | struct lbs_private *priv = wiphy_priv(wiphy); |
443 | int ret = -ENOTSUPP; | 442 | int ret = -ENOTSUPP; |
444 | 443 | ||
445 | lbs_deb_enter_args(LBS_DEB_CFG80211, "freq %d, type %d", | 444 | lbs_deb_enter_args(LBS_DEB_CFG80211, "freq %d, type %d", |
446 | channel->center_freq, channel_type); | 445 | chandef->chan->center_freq, |
446 | cfg80211_get_chandef_type(chandef)); | ||
447 | 447 | ||
448 | if (channel_type != NL80211_CHAN_NO_HT) | 448 | if (cfg80211_get_chandef_type(chandef) != NL80211_CHAN_NO_HT) |
449 | goto out; | 449 | goto out; |
450 | 450 | ||
451 | ret = lbs_set_channel(priv, channel->hw_value); | 451 | ret = lbs_set_channel(priv, chandef->chan->hw_value); |
452 | 452 | ||
453 | out: | 453 | out: |
454 | lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); | 454 | lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret); |
@@ -1734,7 +1734,7 @@ static void lbs_join_post(struct lbs_private *priv, | |||
1734 | /* Fake DS channel IE */ | 1734 | /* Fake DS channel IE */ |
1735 | *fake++ = WLAN_EID_DS_PARAMS; | 1735 | *fake++ = WLAN_EID_DS_PARAMS; |
1736 | *fake++ = 1; | 1736 | *fake++ = 1; |
1737 | *fake++ = params->channel->hw_value; | 1737 | *fake++ = params->chandef.chan->hw_value; |
1738 | /* Fake IBSS params IE */ | 1738 | /* Fake IBSS params IE */ |
1739 | *fake++ = WLAN_EID_IBSS_PARAMS; | 1739 | *fake++ = WLAN_EID_IBSS_PARAMS; |
1740 | *fake++ = 2; | 1740 | *fake++ = 2; |
@@ -1755,7 +1755,7 @@ static void lbs_join_post(struct lbs_private *priv, | |||
1755 | lbs_deb_hex(LBS_DEB_CFG80211, "IE", fake_ie, fake - fake_ie); | 1755 | lbs_deb_hex(LBS_DEB_CFG80211, "IE", fake_ie, fake - fake_ie); |
1756 | 1756 | ||
1757 | bss = cfg80211_inform_bss(priv->wdev->wiphy, | 1757 | bss = cfg80211_inform_bss(priv->wdev->wiphy, |
1758 | params->channel, | 1758 | params->chandef.chan, |
1759 | bssid, | 1759 | bssid, |
1760 | 0, | 1760 | 0, |
1761 | capability, | 1761 | capability, |
@@ -1833,7 +1833,7 @@ static int lbs_ibss_join_existing(struct lbs_private *priv, | |||
1833 | cmd.bss.beaconperiod = cpu_to_le16(params->beacon_interval); | 1833 | cmd.bss.beaconperiod = cpu_to_le16(params->beacon_interval); |
1834 | cmd.bss.ds.header.id = WLAN_EID_DS_PARAMS; | 1834 | cmd.bss.ds.header.id = WLAN_EID_DS_PARAMS; |
1835 | cmd.bss.ds.header.len = 1; | 1835 | cmd.bss.ds.header.len = 1; |
1836 | cmd.bss.ds.channel = params->channel->hw_value; | 1836 | cmd.bss.ds.channel = params->chandef.chan->hw_value; |
1837 | cmd.bss.ibss.header.id = WLAN_EID_IBSS_PARAMS; | 1837 | cmd.bss.ibss.header.id = WLAN_EID_IBSS_PARAMS; |
1838 | cmd.bss.ibss.header.len = 2; | 1838 | cmd.bss.ibss.header.len = 2; |
1839 | cmd.bss.ibss.atimwindow = 0; | 1839 | cmd.bss.ibss.atimwindow = 0; |
@@ -1942,7 +1942,7 @@ static int lbs_ibss_start_new(struct lbs_private *priv, | |||
1942 | cmd.ibss.atimwindow = 0; | 1942 | cmd.ibss.atimwindow = 0; |
1943 | cmd.ds.header.id = WLAN_EID_DS_PARAMS; | 1943 | cmd.ds.header.id = WLAN_EID_DS_PARAMS; |
1944 | cmd.ds.header.len = 1; | 1944 | cmd.ds.header.len = 1; |
1945 | cmd.ds.channel = params->channel->hw_value; | 1945 | cmd.ds.channel = params->chandef.chan->hw_value; |
1946 | /* Only v8 and below support setting probe delay */ | 1946 | /* Only v8 and below support setting probe delay */ |
1947 | if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) | 1947 | if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) |
1948 | cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME); | 1948 | cmd.probedelay = cpu_to_le16(CMD_SCAN_PROBE_DELAY_TIME); |
@@ -1987,18 +1987,18 @@ static int lbs_join_ibss(struct wiphy *wiphy, struct net_device *dev, | |||
1987 | 1987 | ||
1988 | lbs_deb_enter(LBS_DEB_CFG80211); | 1988 | lbs_deb_enter(LBS_DEB_CFG80211); |
1989 | 1989 | ||
1990 | if (!params->channel) { | 1990 | if (!params->chandef.chan) { |
1991 | ret = -ENOTSUPP; | 1991 | ret = -ENOTSUPP; |
1992 | goto out; | 1992 | goto out; |
1993 | } | 1993 | } |
1994 | 1994 | ||
1995 | ret = lbs_set_channel(priv, params->channel->hw_value); | 1995 | ret = lbs_set_channel(priv, params->chandef.chan->hw_value); |
1996 | if (ret) | 1996 | if (ret) |
1997 | goto out; | 1997 | goto out; |
1998 | 1998 | ||
1999 | /* Search if someone is beaconing. This assumes that the | 1999 | /* Search if someone is beaconing. This assumes that the |
2000 | * bss list is populated already */ | 2000 | * bss list is populated already */ |
2001 | bss = cfg80211_get_bss(wiphy, params->channel, params->bssid, | 2001 | bss = cfg80211_get_bss(wiphy, params->chandef.chan, params->bssid, |
2002 | params->ssid, params->ssid_len, | 2002 | params->ssid, params->ssid_len, |
2003 | WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS); | 2003 | WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS); |
2004 | 2004 | ||
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index 4cb234349fbf..739309e70d8b 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c | |||
@@ -588,17 +588,38 @@ static int if_sdio_prog_real(struct if_sdio_card *card, | |||
588 | size = fw->size; | 588 | size = fw->size; |
589 | 589 | ||
590 | while (size) { | 590 | while (size) { |
591 | ret = if_sdio_wait_status(card, FW_DL_READY_STATUS); | 591 | timeout = jiffies + HZ; |
592 | if (ret) | 592 | while (1) { |
593 | goto release; | 593 | ret = if_sdio_wait_status(card, FW_DL_READY_STATUS); |
594 | if (ret) | ||
595 | goto release; | ||
594 | 596 | ||
595 | req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, &ret); | 597 | req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, |
596 | if (ret) | 598 | &ret); |
597 | goto release; | 599 | if (ret) |
600 | goto release; | ||
601 | |||
602 | req_size |= sdio_readb(card->func, IF_SDIO_RD_BASE + 1, | ||
603 | &ret) << 8; | ||
604 | if (ret) | ||
605 | goto release; | ||
606 | |||
607 | /* | ||
608 | * For SD8688 wait until the length is not 0, 1 or 2 | ||
609 | * before downloading the first FW block, | ||
610 | * since BOOT code writes the register to indicate the | ||
611 | * helper/FW download winner, | ||
612 | * the value could be 1 or 2 (Func1 or Func2). | ||
613 | */ | ||
614 | if ((size != fw->size) || (req_size > 2)) | ||
615 | break; | ||
616 | if (time_after(jiffies, timeout)) { | ||
617 | ret = -ETIMEDOUT; | ||
618 | goto release; | ||
619 | } | ||
620 | mdelay(1); | ||
621 | } | ||
598 | 622 | ||
599 | req_size |= sdio_readb(card->func, IF_SDIO_RD_BASE + 1, &ret) << 8; | ||
600 | if (ret) | ||
601 | goto release; | ||
602 | /* | 623 | /* |
603 | lbs_deb_sdio("firmware wants %d bytes\n", (int)req_size); | 624 | lbs_deb_sdio("firmware wants %d bytes\n", (int)req_size); |
604 | */ | 625 | */ |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 429ca3215fdb..2aa8a1aa1184 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -44,9 +44,9 @@ static int radios = 2; | |||
44 | module_param(radios, int, 0444); | 44 | module_param(radios, int, 0444); |
45 | MODULE_PARM_DESC(radios, "Number of simulated radios"); | 45 | MODULE_PARM_DESC(radios, "Number of simulated radios"); |
46 | 46 | ||
47 | static bool fake_hw_scan; | 47 | static int channels = 1; |
48 | module_param(fake_hw_scan, bool, 0444); | 48 | module_param(channels, int, 0444); |
49 | MODULE_PARM_DESC(fake_hw_scan, "Install fake (no-op) hw-scan handler"); | 49 | MODULE_PARM_DESC(channels, "Number of concurrent channels"); |
50 | 50 | ||
51 | /** | 51 | /** |
52 | * enum hwsim_regtest - the type of regulatory tests we offer | 52 | * enum hwsim_regtest - the type of regulatory tests we offer |
@@ -166,7 +166,9 @@ struct hwsim_vif_priv { | |||
166 | static inline void hwsim_check_magic(struct ieee80211_vif *vif) | 166 | static inline void hwsim_check_magic(struct ieee80211_vif *vif) |
167 | { | 167 | { |
168 | struct hwsim_vif_priv *vp = (void *)vif->drv_priv; | 168 | struct hwsim_vif_priv *vp = (void *)vif->drv_priv; |
169 | WARN_ON(vp->magic != HWSIM_VIF_MAGIC); | 169 | WARN(vp->magic != HWSIM_VIF_MAGIC, |
170 | "Invalid VIF (%p) magic %#x, %pM, %d/%d\n", | ||
171 | vif, vp->magic, vif->addr, vif->type, vif->p2p); | ||
170 | } | 172 | } |
171 | 173 | ||
172 | static inline void hwsim_set_magic(struct ieee80211_vif *vif) | 174 | static inline void hwsim_set_magic(struct ieee80211_vif *vif) |
@@ -185,7 +187,7 @@ struct hwsim_sta_priv { | |||
185 | u32 magic; | 187 | u32 magic; |
186 | }; | 188 | }; |
187 | 189 | ||
188 | #define HWSIM_STA_MAGIC 0x6d537748 | 190 | #define HWSIM_STA_MAGIC 0x6d537749 |
189 | 191 | ||
190 | static inline void hwsim_check_sta_magic(struct ieee80211_sta *sta) | 192 | static inline void hwsim_check_sta_magic(struct ieee80211_sta *sta) |
191 | { | 193 | { |
@@ -205,6 +207,30 @@ static inline void hwsim_clear_sta_magic(struct ieee80211_sta *sta) | |||
205 | sp->magic = 0; | 207 | sp->magic = 0; |
206 | } | 208 | } |
207 | 209 | ||
210 | struct hwsim_chanctx_priv { | ||
211 | u32 magic; | ||
212 | }; | ||
213 | |||
214 | #define HWSIM_CHANCTX_MAGIC 0x6d53774a | ||
215 | |||
216 | static inline void hwsim_check_chanctx_magic(struct ieee80211_chanctx_conf *c) | ||
217 | { | ||
218 | struct hwsim_chanctx_priv *cp = (void *)c->drv_priv; | ||
219 | WARN_ON(cp->magic != HWSIM_CHANCTX_MAGIC); | ||
220 | } | ||
221 | |||
222 | static inline void hwsim_set_chanctx_magic(struct ieee80211_chanctx_conf *c) | ||
223 | { | ||
224 | struct hwsim_chanctx_priv *cp = (void *)c->drv_priv; | ||
225 | cp->magic = HWSIM_CHANCTX_MAGIC; | ||
226 | } | ||
227 | |||
228 | static inline void hwsim_clear_chanctx_magic(struct ieee80211_chanctx_conf *c) | ||
229 | { | ||
230 | struct hwsim_chanctx_priv *cp = (void *)c->drv_priv; | ||
231 | cp->magic = 0; | ||
232 | } | ||
233 | |||
208 | static struct class *hwsim_class; | 234 | static struct class *hwsim_class; |
209 | 235 | ||
210 | static struct net_device *hwsim_mon; /* global monitor netdev */ | 236 | static struct net_device *hwsim_mon; /* global monitor netdev */ |
@@ -299,6 +325,13 @@ struct mac80211_hwsim_data { | |||
299 | 325 | ||
300 | struct mac_address addresses[2]; | 326 | struct mac_address addresses[2]; |
301 | 327 | ||
328 | struct ieee80211_channel *tmp_chan; | ||
329 | struct delayed_work roc_done; | ||
330 | struct delayed_work hw_scan; | ||
331 | struct cfg80211_scan_request *hw_scan_request; | ||
332 | struct ieee80211_vif *hw_scan_vif; | ||
333 | int scan_chan_idx; | ||
334 | |||
302 | struct ieee80211_channel *channel; | 335 | struct ieee80211_channel *channel; |
303 | unsigned long beacon_int; /* in jiffies unit */ | 336 | unsigned long beacon_int; /* in jiffies unit */ |
304 | unsigned int rx_filter; | 337 | unsigned int rx_filter; |
@@ -396,7 +429,8 @@ static void mac80211_hwsim_set_tsf(struct ieee80211_hw *hw, | |||
396 | } | 429 | } |
397 | 430 | ||
398 | static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, | 431 | static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, |
399 | struct sk_buff *tx_skb) | 432 | struct sk_buff *tx_skb, |
433 | struct ieee80211_channel *chan) | ||
400 | { | 434 | { |
401 | struct mac80211_hwsim_data *data = hw->priv; | 435 | struct mac80211_hwsim_data *data = hw->priv; |
402 | struct sk_buff *skb; | 436 | struct sk_buff *skb; |
@@ -423,7 +457,7 @@ static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, | |||
423 | hdr->rt_tsft = __mac80211_hwsim_get_tsf(data); | 457 | hdr->rt_tsft = __mac80211_hwsim_get_tsf(data); |
424 | hdr->rt_flags = 0; | 458 | hdr->rt_flags = 0; |
425 | hdr->rt_rate = txrate->bitrate / 5; | 459 | hdr->rt_rate = txrate->bitrate / 5; |
426 | hdr->rt_channel = cpu_to_le16(data->channel->center_freq); | 460 | hdr->rt_channel = cpu_to_le16(chan->center_freq); |
427 | flags = IEEE80211_CHAN_2GHZ; | 461 | flags = IEEE80211_CHAN_2GHZ; |
428 | if (txrate->flags & IEEE80211_RATE_ERP_G) | 462 | if (txrate->flags & IEEE80211_RATE_ERP_G) |
429 | flags |= IEEE80211_CHAN_OFDM; | 463 | flags |= IEEE80211_CHAN_OFDM; |
@@ -441,9 +475,9 @@ static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, | |||
441 | } | 475 | } |
442 | 476 | ||
443 | 477 | ||
444 | static void mac80211_hwsim_monitor_ack(struct ieee80211_hw *hw, const u8 *addr) | 478 | static void mac80211_hwsim_monitor_ack(struct ieee80211_channel *chan, |
479 | const u8 *addr) | ||
445 | { | 480 | { |
446 | struct mac80211_hwsim_data *data = hw->priv; | ||
447 | struct sk_buff *skb; | 481 | struct sk_buff *skb; |
448 | struct hwsim_radiotap_hdr *hdr; | 482 | struct hwsim_radiotap_hdr *hdr; |
449 | u16 flags; | 483 | u16 flags; |
@@ -464,7 +498,7 @@ static void mac80211_hwsim_monitor_ack(struct ieee80211_hw *hw, const u8 *addr) | |||
464 | (1 << IEEE80211_RADIOTAP_CHANNEL)); | 498 | (1 << IEEE80211_RADIOTAP_CHANNEL)); |
465 | hdr->rt_flags = 0; | 499 | hdr->rt_flags = 0; |
466 | hdr->rt_rate = 0; | 500 | hdr->rt_rate = 0; |
467 | hdr->rt_channel = cpu_to_le16(data->channel->center_freq); | 501 | hdr->rt_channel = cpu_to_le16(chan->center_freq); |
468 | flags = IEEE80211_CHAN_2GHZ; | 502 | flags = IEEE80211_CHAN_2GHZ; |
469 | hdr->rt_chbitmask = cpu_to_le16(flags); | 503 | hdr->rt_chbitmask = cpu_to_le16(flags); |
470 | 504 | ||
@@ -537,6 +571,7 @@ static bool mac80211_hwsim_addr_match(struct mac80211_hwsim_data *data, | |||
537 | md.ret = false; | 571 | md.ret = false; |
538 | md.addr = addr; | 572 | md.addr = addr; |
539 | ieee80211_iterate_active_interfaces_atomic(data->hw, | 573 | ieee80211_iterate_active_interfaces_atomic(data->hw, |
574 | IEEE80211_IFACE_ITER_NORMAL, | ||
540 | mac80211_hwsim_addr_iter, | 575 | mac80211_hwsim_addr_iter, |
541 | &md); | 576 | &md); |
542 | 577 | ||
@@ -556,12 +591,6 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, | |||
556 | int i; | 591 | int i; |
557 | struct hwsim_tx_rate tx_attempts[IEEE80211_TX_MAX_RATES]; | 592 | struct hwsim_tx_rate tx_attempts[IEEE80211_TX_MAX_RATES]; |
558 | 593 | ||
559 | if (data->idle) { | ||
560 | wiphy_debug(hw->wiphy, "Trying to TX when idle - reject\n"); | ||
561 | dev_kfree_skb(my_skb); | ||
562 | return; | ||
563 | } | ||
564 | |||
565 | if (data->ps != PS_DISABLED) | 594 | if (data->ps != PS_DISABLED) |
566 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); | 595 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); |
567 | /* If the queue contains MAX_QUEUE skb's drop some */ | 596 | /* If the queue contains MAX_QUEUE skb's drop some */ |
@@ -629,8 +658,38 @@ nla_put_failure: | |||
629 | printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__); | 658 | printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__); |
630 | } | 659 | } |
631 | 660 | ||
661 | static bool hwsim_chans_compat(struct ieee80211_channel *c1, | ||
662 | struct ieee80211_channel *c2) | ||
663 | { | ||
664 | if (!c1 || !c2) | ||
665 | return false; | ||
666 | |||
667 | return c1->center_freq == c2->center_freq; | ||
668 | } | ||
669 | |||
670 | struct tx_iter_data { | ||
671 | struct ieee80211_channel *channel; | ||
672 | bool receive; | ||
673 | }; | ||
674 | |||
675 | static void mac80211_hwsim_tx_iter(void *_data, u8 *addr, | ||
676 | struct ieee80211_vif *vif) | ||
677 | { | ||
678 | struct tx_iter_data *data = _data; | ||
679 | |||
680 | if (!vif->chanctx_conf) | ||
681 | return; | ||
682 | |||
683 | if (!hwsim_chans_compat(data->channel, | ||
684 | rcu_dereference(vif->chanctx_conf)->def.chan)) | ||
685 | return; | ||
686 | |||
687 | data->receive = true; | ||
688 | } | ||
689 | |||
632 | static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, | 690 | static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, |
633 | struct sk_buff *skb) | 691 | struct sk_buff *skb, |
692 | struct ieee80211_channel *chan) | ||
634 | { | 693 | { |
635 | struct mac80211_hwsim_data *data = hw->priv, *data2; | 694 | struct mac80211_hwsim_data *data = hw->priv, *data2; |
636 | bool ack = false; | 695 | bool ack = false; |
@@ -639,15 +698,10 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, | |||
639 | struct ieee80211_rx_status rx_status; | 698 | struct ieee80211_rx_status rx_status; |
640 | struct ieee80211_rate *txrate = ieee80211_get_tx_rate(hw, info); | 699 | struct ieee80211_rate *txrate = ieee80211_get_tx_rate(hw, info); |
641 | 700 | ||
642 | if (data->idle) { | ||
643 | wiphy_debug(hw->wiphy, "Trying to TX when idle - reject\n"); | ||
644 | return false; | ||
645 | } | ||
646 | |||
647 | memset(&rx_status, 0, sizeof(rx_status)); | 701 | memset(&rx_status, 0, sizeof(rx_status)); |
648 | rx_status.flag |= RX_FLAG_MACTIME_MPDU; | 702 | rx_status.flag |= RX_FLAG_MACTIME_START; |
649 | rx_status.freq = data->channel->center_freq; | 703 | rx_status.freq = chan->center_freq; |
650 | rx_status.band = data->channel->band; | 704 | rx_status.band = chan->band; |
651 | rx_status.rate_idx = info->control.rates[0].idx; | 705 | rx_status.rate_idx = info->control.rates[0].idx; |
652 | if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS) | 706 | if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS) |
653 | rx_status.flag |= RX_FLAG_HT; | 707 | rx_status.flag |= RX_FLAG_HT; |
@@ -673,17 +727,35 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, | |||
673 | list_for_each_entry(data2, &hwsim_radios, list) { | 727 | list_for_each_entry(data2, &hwsim_radios, list) { |
674 | struct sk_buff *nskb; | 728 | struct sk_buff *nskb; |
675 | struct ieee80211_mgmt *mgmt; | 729 | struct ieee80211_mgmt *mgmt; |
730 | struct tx_iter_data tx_iter_data = { | ||
731 | .receive = false, | ||
732 | .channel = chan, | ||
733 | }; | ||
676 | 734 | ||
677 | if (data == data2) | 735 | if (data == data2) |
678 | continue; | 736 | continue; |
679 | 737 | ||
680 | if (data2->idle || !data2->started || | 738 | if (!data2->started || (data2->idle && !data2->tmp_chan) || |
681 | !hwsim_ps_rx_ok(data2, skb) || !data2->channel || | 739 | !hwsim_ps_rx_ok(data2, skb)) |
682 | data->channel->center_freq != data2->channel->center_freq || | ||
683 | !(data->group & data2->group)) | ||
684 | continue; | 740 | continue; |
685 | 741 | ||
686 | nskb = skb_copy(skb, GFP_ATOMIC); | 742 | if (!(data->group & data2->group)) |
743 | continue; | ||
744 | |||
745 | if (!hwsim_chans_compat(chan, data2->tmp_chan) && | ||
746 | !hwsim_chans_compat(chan, data2->channel)) { | ||
747 | ieee80211_iterate_active_interfaces_atomic( | ||
748 | data2->hw, IEEE80211_IFACE_ITER_NORMAL, | ||
749 | mac80211_hwsim_tx_iter, &tx_iter_data); | ||
750 | if (!tx_iter_data.receive) | ||
751 | continue; | ||
752 | } | ||
753 | |||
754 | /* | ||
755 | * reserve some space for our vendor and the normal | ||
756 | * radiotap header, since we're copying anyway | ||
757 | */ | ||
758 | nskb = skb_copy_expand(skb, 64, 0, GFP_ATOMIC); | ||
687 | if (nskb == NULL) | 759 | if (nskb == NULL) |
688 | continue; | 760 | continue; |
689 | 761 | ||
@@ -701,6 +773,33 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, | |||
701 | (data->tsf_offset - data2->tsf_offset) + | 773 | (data->tsf_offset - data2->tsf_offset) + |
702 | 24 * 8 * 10 / txrate->bitrate); | 774 | 24 * 8 * 10 / txrate->bitrate); |
703 | 775 | ||
776 | #if 0 | ||
777 | /* | ||
778 | * Don't enable this code by default as the OUI 00:00:00 | ||
779 | * is registered to Xerox so we shouldn't use it here, it | ||
780 | * might find its way into pcap files. | ||
781 | * Note that this code requires the headroom in the SKB | ||
782 | * that was allocated earlier. | ||
783 | */ | ||
784 | rx_status.vendor_radiotap_oui[0] = 0x00; | ||
785 | rx_status.vendor_radiotap_oui[1] = 0x00; | ||
786 | rx_status.vendor_radiotap_oui[2] = 0x00; | ||
787 | rx_status.vendor_radiotap_subns = 127; | ||
788 | /* | ||
789 | * Radiotap vendor namespaces can (and should) also be | ||
790 | * split into fields by using the standard radiotap | ||
791 | * presence bitmap mechanism. Use just BIT(0) here for | ||
792 | * the presence bitmap. | ||
793 | */ | ||
794 | rx_status.vendor_radiotap_bitmap = BIT(0); | ||
795 | /* We have 8 bytes of (dummy) data */ | ||
796 | rx_status.vendor_radiotap_len = 8; | ||
797 | /* For testing, also require it to be aligned */ | ||
798 | rx_status.vendor_radiotap_align = 8; | ||
799 | /* push the data */ | ||
800 | memcpy(skb_push(nskb, 8), "ABCDEFGH", 8); | ||
801 | #endif | ||
802 | |||
704 | memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status)); | 803 | memcpy(IEEE80211_SKB_RXCB(nskb), &rx_status, sizeof(rx_status)); |
705 | ieee80211_rx_irqsafe(data2->hw, nskb); | 804 | ieee80211_rx_irqsafe(data2->hw, nskb); |
706 | } | 805 | } |
@@ -713,18 +812,51 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, | |||
713 | struct ieee80211_tx_control *control, | 812 | struct ieee80211_tx_control *control, |
714 | struct sk_buff *skb) | 813 | struct sk_buff *skb) |
715 | { | 814 | { |
815 | struct mac80211_hwsim_data *data = hw->priv; | ||
816 | struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(skb); | ||
817 | struct ieee80211_chanctx_conf *chanctx_conf; | ||
818 | struct ieee80211_channel *channel; | ||
716 | bool ack; | 819 | bool ack; |
717 | struct ieee80211_tx_info *txi; | ||
718 | u32 _portid; | 820 | u32 _portid; |
719 | 821 | ||
720 | mac80211_hwsim_monitor_rx(hw, skb); | 822 | if (WARN_ON(skb->len < 10)) { |
721 | |||
722 | if (skb->len < 10) { | ||
723 | /* Should not happen; just a sanity check for addr1 use */ | 823 | /* Should not happen; just a sanity check for addr1 use */ |
724 | dev_kfree_skb(skb); | 824 | dev_kfree_skb(skb); |
725 | return; | 825 | return; |
726 | } | 826 | } |
727 | 827 | ||
828 | if (channels == 1) { | ||
829 | channel = data->channel; | ||
830 | } else if (txi->hw_queue == 4) { | ||
831 | channel = data->tmp_chan; | ||
832 | } else { | ||
833 | chanctx_conf = rcu_dereference(txi->control.vif->chanctx_conf); | ||
834 | if (chanctx_conf) | ||
835 | channel = chanctx_conf->def.chan; | ||
836 | else | ||
837 | channel = NULL; | ||
838 | } | ||
839 | |||
840 | if (WARN(!channel, "TX w/o channel - queue = %d\n", txi->hw_queue)) { | ||
841 | dev_kfree_skb(skb); | ||
842 | return; | ||
843 | } | ||
844 | |||
845 | if (data->idle && !data->tmp_chan) { | ||
846 | wiphy_debug(hw->wiphy, "Trying to TX when idle - reject\n"); | ||
847 | dev_kfree_skb(skb); | ||
848 | return; | ||
849 | } | ||
850 | |||
851 | if (txi->control.vif) | ||
852 | hwsim_check_magic(txi->control.vif); | ||
853 | if (control->sta) | ||
854 | hwsim_check_sta_magic(control->sta); | ||
855 | |||
856 | txi->rate_driver_data[0] = channel; | ||
857 | |||
858 | mac80211_hwsim_monitor_rx(hw, skb, channel); | ||
859 | |||
728 | /* wmediumd mode check */ | 860 | /* wmediumd mode check */ |
729 | _portid = ACCESS_ONCE(wmediumd_portid); | 861 | _portid = ACCESS_ONCE(wmediumd_portid); |
730 | 862 | ||
@@ -732,15 +864,13 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, | |||
732 | return mac80211_hwsim_tx_frame_nl(hw, skb, _portid); | 864 | return mac80211_hwsim_tx_frame_nl(hw, skb, _portid); |
733 | 865 | ||
734 | /* NO wmediumd detected, perfect medium simulation */ | 866 | /* NO wmediumd detected, perfect medium simulation */ |
735 | ack = mac80211_hwsim_tx_frame_no_nl(hw, skb); | 867 | ack = mac80211_hwsim_tx_frame_no_nl(hw, skb, channel); |
736 | 868 | ||
737 | if (ack && skb->len >= 16) { | 869 | if (ack && skb->len >= 16) { |
738 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 870 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
739 | mac80211_hwsim_monitor_ack(hw, hdr->addr2); | 871 | mac80211_hwsim_monitor_ack(channel, hdr->addr2); |
740 | } | 872 | } |
741 | 873 | ||
742 | txi = IEEE80211_SKB_CB(skb); | ||
743 | |||
744 | ieee80211_tx_info_clear_status(txi); | 874 | ieee80211_tx_info_clear_status(txi); |
745 | 875 | ||
746 | /* frame was transmitted at most favorable rate at first attempt */ | 876 | /* frame was transmitted at most favorable rate at first attempt */ |
@@ -778,6 +908,13 @@ static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw, | |||
778 | __func__, ieee80211_vif_type_p2p(vif), | 908 | __func__, ieee80211_vif_type_p2p(vif), |
779 | vif->addr); | 909 | vif->addr); |
780 | hwsim_set_magic(vif); | 910 | hwsim_set_magic(vif); |
911 | |||
912 | vif->cab_queue = 0; | ||
913 | vif->hw_queue[IEEE80211_AC_VO] = 0; | ||
914 | vif->hw_queue[IEEE80211_AC_VI] = 1; | ||
915 | vif->hw_queue[IEEE80211_AC_BE] = 2; | ||
916 | vif->hw_queue[IEEE80211_AC_BK] = 3; | ||
917 | |||
781 | return 0; | 918 | return 0; |
782 | } | 919 | } |
783 | 920 | ||
@@ -807,14 +944,26 @@ static void mac80211_hwsim_remove_interface( | |||
807 | hwsim_clear_magic(vif); | 944 | hwsim_clear_magic(vif); |
808 | } | 945 | } |
809 | 946 | ||
947 | static void mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, | ||
948 | struct sk_buff *skb, | ||
949 | struct ieee80211_channel *chan) | ||
950 | { | ||
951 | u32 _pid = ACCESS_ONCE(wmediumd_portid); | ||
952 | |||
953 | mac80211_hwsim_monitor_rx(hw, skb, chan); | ||
954 | |||
955 | if (_pid) | ||
956 | return mac80211_hwsim_tx_frame_nl(hw, skb, _pid); | ||
957 | |||
958 | mac80211_hwsim_tx_frame_no_nl(hw, skb, chan); | ||
959 | dev_kfree_skb(skb); | ||
960 | } | ||
810 | 961 | ||
811 | static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, | 962 | static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, |
812 | struct ieee80211_vif *vif) | 963 | struct ieee80211_vif *vif) |
813 | { | 964 | { |
814 | struct ieee80211_hw *hw = arg; | 965 | struct ieee80211_hw *hw = arg; |
815 | struct sk_buff *skb; | 966 | struct sk_buff *skb; |
816 | struct ieee80211_tx_info *info; | ||
817 | u32 _portid; | ||
818 | 967 | ||
819 | hwsim_check_magic(vif); | 968 | hwsim_check_magic(vif); |
820 | 969 | ||
@@ -826,18 +975,9 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, | |||
826 | skb = ieee80211_beacon_get(hw, vif); | 975 | skb = ieee80211_beacon_get(hw, vif); |
827 | if (skb == NULL) | 976 | if (skb == NULL) |
828 | return; | 977 | return; |
829 | info = IEEE80211_SKB_CB(skb); | ||
830 | |||
831 | mac80211_hwsim_monitor_rx(hw, skb); | ||
832 | |||
833 | /* wmediumd mode check */ | ||
834 | _portid = ACCESS_ONCE(wmediumd_portid); | ||
835 | |||
836 | if (_portid) | ||
837 | return mac80211_hwsim_tx_frame_nl(hw, skb, _portid); | ||
838 | 978 | ||
839 | mac80211_hwsim_tx_frame_no_nl(hw, skb); | 979 | mac80211_hwsim_tx_frame(hw, skb, |
840 | dev_kfree_skb(skb); | 980 | rcu_dereference(vif->chanctx_conf)->def.chan); |
841 | } | 981 | } |
842 | 982 | ||
843 | 983 | ||
@@ -850,7 +990,8 @@ static void mac80211_hwsim_beacon(unsigned long arg) | |||
850 | return; | 990 | return; |
851 | 991 | ||
852 | ieee80211_iterate_active_interfaces_atomic( | 992 | ieee80211_iterate_active_interfaces_atomic( |
853 | hw, mac80211_hwsim_beacon_tx, hw); | 993 | hw, IEEE80211_IFACE_ITER_NORMAL, |
994 | mac80211_hwsim_beacon_tx, hw); | ||
854 | 995 | ||
855 | data->beacon_timer.expires = jiffies + data->beacon_int; | 996 | data->beacon_timer.expires = jiffies + data->beacon_int; |
856 | add_timer(&data->beacon_timer); | 997 | add_timer(&data->beacon_timer); |
@@ -877,7 +1018,7 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed) | |||
877 | wiphy_debug(hw->wiphy, | 1018 | wiphy_debug(hw->wiphy, |
878 | "%s (freq=%d/%s idle=%d ps=%d smps=%s)\n", | 1019 | "%s (freq=%d/%s idle=%d ps=%d smps=%s)\n", |
879 | __func__, | 1020 | __func__, |
880 | conf->channel->center_freq, | 1021 | conf->channel ? conf->channel->center_freq : 0, |
881 | hwsim_chantypes[conf->channel_type], | 1022 | hwsim_chantypes[conf->channel_type], |
882 | !!(conf->flags & IEEE80211_CONF_IDLE), | 1023 | !!(conf->flags & IEEE80211_CONF_IDLE), |
883 | !!(conf->flags & IEEE80211_CONF_PS), | 1024 | !!(conf->flags & IEEE80211_CONF_PS), |
@@ -886,6 +1027,9 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed) | |||
886 | data->idle = !!(conf->flags & IEEE80211_CONF_IDLE); | 1027 | data->idle = !!(conf->flags & IEEE80211_CONF_IDLE); |
887 | 1028 | ||
888 | data->channel = conf->channel; | 1029 | data->channel = conf->channel; |
1030 | |||
1031 | WARN_ON(data->channel && channels > 1); | ||
1032 | |||
889 | data->power_level = conf->power_level; | 1033 | data->power_level = conf->power_level; |
890 | if (!data->started || !data->beacon_int) | 1034 | if (!data->started || !data->beacon_int) |
891 | del_timer(&data->beacon_timer); | 1035 | del_timer(&data->beacon_timer); |
@@ -963,15 +1107,17 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, | |||
963 | } | 1107 | } |
964 | 1108 | ||
965 | if (changed & BSS_CHANGED_HT) { | 1109 | if (changed & BSS_CHANGED_HT) { |
966 | wiphy_debug(hw->wiphy, " HT: op_mode=0x%x, chantype=%s\n", | 1110 | wiphy_debug(hw->wiphy, " HT: op_mode=0x%x\n", |
967 | info->ht_operation_mode, | 1111 | info->ht_operation_mode); |
968 | hwsim_chantypes[info->channel_type]); | ||
969 | } | 1112 | } |
970 | 1113 | ||
971 | if (changed & BSS_CHANGED_BASIC_RATES) { | 1114 | if (changed & BSS_CHANGED_BASIC_RATES) { |
972 | wiphy_debug(hw->wiphy, " BASIC_RATES: 0x%llx\n", | 1115 | wiphy_debug(hw->wiphy, " BASIC_RATES: 0x%llx\n", |
973 | (unsigned long long) info->basic_rates); | 1116 | (unsigned long long) info->basic_rates); |
974 | } | 1117 | } |
1118 | |||
1119 | if (changed & BSS_CHANGED_TXPOWER) | ||
1120 | wiphy_debug(hw->wiphy, " TX Power: %d dBm\n", info->txpower); | ||
975 | } | 1121 | } |
976 | 1122 | ||
977 | static int mac80211_hwsim_sta_add(struct ieee80211_hw *hw, | 1123 | static int mac80211_hwsim_sta_add(struct ieee80211_hw *hw, |
@@ -1166,45 +1312,96 @@ static void mac80211_hwsim_flush(struct ieee80211_hw *hw, bool drop) | |||
1166 | /* Not implemented, queues only on kernel side */ | 1312 | /* Not implemented, queues only on kernel side */ |
1167 | } | 1313 | } |
1168 | 1314 | ||
1169 | struct hw_scan_done { | 1315 | static void hw_scan_work(struct work_struct *work) |
1170 | struct delayed_work w; | ||
1171 | struct ieee80211_hw *hw; | ||
1172 | }; | ||
1173 | |||
1174 | static void hw_scan_done(struct work_struct *work) | ||
1175 | { | 1316 | { |
1176 | struct hw_scan_done *hsd = | 1317 | struct mac80211_hwsim_data *hwsim = |
1177 | container_of(work, struct hw_scan_done, w.work); | 1318 | container_of(work, struct mac80211_hwsim_data, hw_scan.work); |
1319 | struct cfg80211_scan_request *req = hwsim->hw_scan_request; | ||
1320 | int dwell, i; | ||
1321 | |||
1322 | mutex_lock(&hwsim->mutex); | ||
1323 | if (hwsim->scan_chan_idx >= req->n_channels) { | ||
1324 | wiphy_debug(hwsim->hw->wiphy, "hw scan complete\n"); | ||
1325 | ieee80211_scan_completed(hwsim->hw, false); | ||
1326 | hwsim->hw_scan_request = NULL; | ||
1327 | hwsim->hw_scan_vif = NULL; | ||
1328 | hwsim->tmp_chan = NULL; | ||
1329 | mutex_unlock(&hwsim->mutex); | ||
1330 | return; | ||
1331 | } | ||
1178 | 1332 | ||
1179 | ieee80211_scan_completed(hsd->hw, false); | 1333 | wiphy_debug(hwsim->hw->wiphy, "hw scan %d MHz\n", |
1180 | kfree(hsd); | 1334 | req->channels[hwsim->scan_chan_idx]->center_freq); |
1335 | |||
1336 | hwsim->tmp_chan = req->channels[hwsim->scan_chan_idx]; | ||
1337 | if (hwsim->tmp_chan->flags & IEEE80211_CHAN_PASSIVE_SCAN || | ||
1338 | !req->n_ssids) { | ||
1339 | dwell = 120; | ||
1340 | } else { | ||
1341 | dwell = 30; | ||
1342 | /* send probes */ | ||
1343 | for (i = 0; i < req->n_ssids; i++) { | ||
1344 | struct sk_buff *probe; | ||
1345 | |||
1346 | probe = ieee80211_probereq_get(hwsim->hw, | ||
1347 | hwsim->hw_scan_vif, | ||
1348 | req->ssids[i].ssid, | ||
1349 | req->ssids[i].ssid_len, | ||
1350 | req->ie, req->ie_len); | ||
1351 | if (!probe) | ||
1352 | continue; | ||
1353 | local_bh_disable(); | ||
1354 | mac80211_hwsim_tx_frame(hwsim->hw, probe, | ||
1355 | hwsim->tmp_chan); | ||
1356 | local_bh_enable(); | ||
1357 | } | ||
1358 | } | ||
1359 | ieee80211_queue_delayed_work(hwsim->hw, &hwsim->hw_scan, | ||
1360 | msecs_to_jiffies(dwell)); | ||
1361 | hwsim->scan_chan_idx++; | ||
1362 | mutex_unlock(&hwsim->mutex); | ||
1181 | } | 1363 | } |
1182 | 1364 | ||
1183 | static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw, | 1365 | static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw, |
1184 | struct ieee80211_vif *vif, | 1366 | struct ieee80211_vif *vif, |
1185 | struct cfg80211_scan_request *req) | 1367 | struct cfg80211_scan_request *req) |
1186 | { | 1368 | { |
1187 | struct hw_scan_done *hsd = kzalloc(sizeof(*hsd), GFP_KERNEL); | 1369 | struct mac80211_hwsim_data *hwsim = hw->priv; |
1188 | int i; | ||
1189 | |||
1190 | if (!hsd) | ||
1191 | return -ENOMEM; | ||
1192 | 1370 | ||
1193 | hsd->hw = hw; | 1371 | mutex_lock(&hwsim->mutex); |
1194 | INIT_DELAYED_WORK(&hsd->w, hw_scan_done); | 1372 | if (WARN_ON(hwsim->tmp_chan || hwsim->hw_scan_request)) { |
1373 | mutex_unlock(&hwsim->mutex); | ||
1374 | return -EBUSY; | ||
1375 | } | ||
1376 | hwsim->hw_scan_request = req; | ||
1377 | hwsim->hw_scan_vif = vif; | ||
1378 | hwsim->scan_chan_idx = 0; | ||
1379 | mutex_unlock(&hwsim->mutex); | ||
1195 | 1380 | ||
1196 | printk(KERN_DEBUG "hwsim hw_scan request\n"); | 1381 | wiphy_debug(hw->wiphy, "hwsim hw_scan request\n"); |
1197 | for (i = 0; i < req->n_channels; i++) | ||
1198 | printk(KERN_DEBUG "hwsim hw_scan freq %d\n", | ||
1199 | req->channels[i]->center_freq); | ||
1200 | print_hex_dump(KERN_DEBUG, "scan IEs: ", DUMP_PREFIX_OFFSET, | ||
1201 | 16, 1, req->ie, req->ie_len, 1); | ||
1202 | 1382 | ||
1203 | ieee80211_queue_delayed_work(hw, &hsd->w, 2 * HZ); | 1383 | ieee80211_queue_delayed_work(hwsim->hw, &hwsim->hw_scan, 0); |
1204 | 1384 | ||
1205 | return 0; | 1385 | return 0; |
1206 | } | 1386 | } |
1207 | 1387 | ||
1388 | static void mac80211_hwsim_cancel_hw_scan(struct ieee80211_hw *hw, | ||
1389 | struct ieee80211_vif *vif) | ||
1390 | { | ||
1391 | struct mac80211_hwsim_data *hwsim = hw->priv; | ||
1392 | |||
1393 | wiphy_debug(hw->wiphy, "hwsim cancel_hw_scan\n"); | ||
1394 | |||
1395 | cancel_delayed_work_sync(&hwsim->hw_scan); | ||
1396 | |||
1397 | mutex_lock(&hwsim->mutex); | ||
1398 | ieee80211_scan_completed(hwsim->hw, true); | ||
1399 | hwsim->tmp_chan = NULL; | ||
1400 | hwsim->hw_scan_request = NULL; | ||
1401 | hwsim->hw_scan_vif = NULL; | ||
1402 | mutex_unlock(&hwsim->mutex); | ||
1403 | } | ||
1404 | |||
1208 | static void mac80211_hwsim_sw_scan(struct ieee80211_hw *hw) | 1405 | static void mac80211_hwsim_sw_scan(struct ieee80211_hw *hw) |
1209 | { | 1406 | { |
1210 | struct mac80211_hwsim_data *hwsim = hw->priv; | 1407 | struct mac80211_hwsim_data *hwsim = hw->priv; |
@@ -1235,6 +1432,111 @@ static void mac80211_hwsim_sw_scan_complete(struct ieee80211_hw *hw) | |||
1235 | mutex_unlock(&hwsim->mutex); | 1432 | mutex_unlock(&hwsim->mutex); |
1236 | } | 1433 | } |
1237 | 1434 | ||
1435 | static void hw_roc_done(struct work_struct *work) | ||
1436 | { | ||
1437 | struct mac80211_hwsim_data *hwsim = | ||
1438 | container_of(work, struct mac80211_hwsim_data, roc_done.work); | ||
1439 | |||
1440 | mutex_lock(&hwsim->mutex); | ||
1441 | ieee80211_remain_on_channel_expired(hwsim->hw); | ||
1442 | hwsim->tmp_chan = NULL; | ||
1443 | mutex_unlock(&hwsim->mutex); | ||
1444 | |||
1445 | wiphy_debug(hwsim->hw->wiphy, "hwsim ROC expired\n"); | ||
1446 | } | ||
1447 | |||
1448 | static int mac80211_hwsim_roc(struct ieee80211_hw *hw, | ||
1449 | struct ieee80211_vif *vif, | ||
1450 | struct ieee80211_channel *chan, | ||
1451 | int duration) | ||
1452 | { | ||
1453 | struct mac80211_hwsim_data *hwsim = hw->priv; | ||
1454 | |||
1455 | mutex_lock(&hwsim->mutex); | ||
1456 | if (WARN_ON(hwsim->tmp_chan || hwsim->hw_scan_request)) { | ||
1457 | mutex_unlock(&hwsim->mutex); | ||
1458 | return -EBUSY; | ||
1459 | } | ||
1460 | |||
1461 | hwsim->tmp_chan = chan; | ||
1462 | mutex_unlock(&hwsim->mutex); | ||
1463 | |||
1464 | wiphy_debug(hw->wiphy, "hwsim ROC (%d MHz, %d ms)\n", | ||
1465 | chan->center_freq, duration); | ||
1466 | |||
1467 | ieee80211_ready_on_channel(hw); | ||
1468 | |||
1469 | ieee80211_queue_delayed_work(hw, &hwsim->roc_done, | ||
1470 | msecs_to_jiffies(duration)); | ||
1471 | return 0; | ||
1472 | } | ||
1473 | |||
1474 | static int mac80211_hwsim_croc(struct ieee80211_hw *hw) | ||
1475 | { | ||
1476 | struct mac80211_hwsim_data *hwsim = hw->priv; | ||
1477 | |||
1478 | cancel_delayed_work_sync(&hwsim->roc_done); | ||
1479 | |||
1480 | mutex_lock(&hwsim->mutex); | ||
1481 | hwsim->tmp_chan = NULL; | ||
1482 | mutex_unlock(&hwsim->mutex); | ||
1483 | |||
1484 | wiphy_debug(hw->wiphy, "hwsim ROC canceled\n"); | ||
1485 | |||
1486 | return 0; | ||
1487 | } | ||
1488 | |||
1489 | static int mac80211_hwsim_add_chanctx(struct ieee80211_hw *hw, | ||
1490 | struct ieee80211_chanctx_conf *ctx) | ||
1491 | { | ||
1492 | hwsim_set_chanctx_magic(ctx); | ||
1493 | wiphy_debug(hw->wiphy, | ||
1494 | "add channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n", | ||
1495 | ctx->def.chan->center_freq, ctx->def.width, | ||
1496 | ctx->def.center_freq1, ctx->def.center_freq2); | ||
1497 | return 0; | ||
1498 | } | ||
1499 | |||
1500 | static void mac80211_hwsim_remove_chanctx(struct ieee80211_hw *hw, | ||
1501 | struct ieee80211_chanctx_conf *ctx) | ||
1502 | { | ||
1503 | wiphy_debug(hw->wiphy, | ||
1504 | "remove channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n", | ||
1505 | ctx->def.chan->center_freq, ctx->def.width, | ||
1506 | ctx->def.center_freq1, ctx->def.center_freq2); | ||
1507 | hwsim_check_chanctx_magic(ctx); | ||
1508 | hwsim_clear_chanctx_magic(ctx); | ||
1509 | } | ||
1510 | |||
1511 | static void mac80211_hwsim_change_chanctx(struct ieee80211_hw *hw, | ||
1512 | struct ieee80211_chanctx_conf *ctx, | ||
1513 | u32 changed) | ||
1514 | { | ||
1515 | hwsim_check_chanctx_magic(ctx); | ||
1516 | wiphy_debug(hw->wiphy, | ||
1517 | "change channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n", | ||
1518 | ctx->def.chan->center_freq, ctx->def.width, | ||
1519 | ctx->def.center_freq1, ctx->def.center_freq2); | ||
1520 | } | ||
1521 | |||
1522 | static int mac80211_hwsim_assign_vif_chanctx(struct ieee80211_hw *hw, | ||
1523 | struct ieee80211_vif *vif, | ||
1524 | struct ieee80211_chanctx_conf *ctx) | ||
1525 | { | ||
1526 | hwsim_check_magic(vif); | ||
1527 | hwsim_check_chanctx_magic(ctx); | ||
1528 | |||
1529 | return 0; | ||
1530 | } | ||
1531 | |||
1532 | static void mac80211_hwsim_unassign_vif_chanctx(struct ieee80211_hw *hw, | ||
1533 | struct ieee80211_vif *vif, | ||
1534 | struct ieee80211_chanctx_conf *ctx) | ||
1535 | { | ||
1536 | hwsim_check_magic(vif); | ||
1537 | hwsim_check_chanctx_magic(ctx); | ||
1538 | } | ||
1539 | |||
1238 | static struct ieee80211_ops mac80211_hwsim_ops = | 1540 | static struct ieee80211_ops mac80211_hwsim_ops = |
1239 | { | 1541 | { |
1240 | .tx = mac80211_hwsim_tx, | 1542 | .tx = mac80211_hwsim_tx, |
@@ -1315,7 +1617,6 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif) | |||
1315 | struct hwsim_vif_priv *vp = (void *)vif->drv_priv; | 1617 | struct hwsim_vif_priv *vp = (void *)vif->drv_priv; |
1316 | struct sk_buff *skb; | 1618 | struct sk_buff *skb; |
1317 | struct ieee80211_pspoll *pspoll; | 1619 | struct ieee80211_pspoll *pspoll; |
1318 | u32 _portid; | ||
1319 | 1620 | ||
1320 | if (!vp->assoc) | 1621 | if (!vp->assoc) |
1321 | return; | 1622 | return; |
@@ -1335,25 +1636,18 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif) | |||
1335 | memcpy(pspoll->bssid, vp->bssid, ETH_ALEN); | 1636 | memcpy(pspoll->bssid, vp->bssid, ETH_ALEN); |
1336 | memcpy(pspoll->ta, mac, ETH_ALEN); | 1637 | memcpy(pspoll->ta, mac, ETH_ALEN); |
1337 | 1638 | ||
1338 | /* wmediumd mode check */ | 1639 | rcu_read_lock(); |
1339 | _portid = ACCESS_ONCE(wmediumd_portid); | 1640 | mac80211_hwsim_tx_frame(data->hw, skb, |
1340 | 1641 | rcu_dereference(vif->chanctx_conf)->def.chan); | |
1341 | if (_portid) | 1642 | rcu_read_unlock(); |
1342 | return mac80211_hwsim_tx_frame_nl(data->hw, skb, _portid); | ||
1343 | |||
1344 | if (!mac80211_hwsim_tx_frame_no_nl(data->hw, skb)) | ||
1345 | printk(KERN_DEBUG "%s: PS-poll frame not ack'ed\n", __func__); | ||
1346 | dev_kfree_skb(skb); | ||
1347 | } | 1643 | } |
1348 | 1644 | ||
1349 | |||
1350 | static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac, | 1645 | static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac, |
1351 | struct ieee80211_vif *vif, int ps) | 1646 | struct ieee80211_vif *vif, int ps) |
1352 | { | 1647 | { |
1353 | struct hwsim_vif_priv *vp = (void *)vif->drv_priv; | 1648 | struct hwsim_vif_priv *vp = (void *)vif->drv_priv; |
1354 | struct sk_buff *skb; | 1649 | struct sk_buff *skb; |
1355 | struct ieee80211_hdr *hdr; | 1650 | struct ieee80211_hdr *hdr; |
1356 | u32 _portid; | ||
1357 | 1651 | ||
1358 | if (!vp->assoc) | 1652 | if (!vp->assoc) |
1359 | return; | 1653 | return; |
@@ -1374,15 +1668,10 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac, | |||
1374 | memcpy(hdr->addr2, mac, ETH_ALEN); | 1668 | memcpy(hdr->addr2, mac, ETH_ALEN); |
1375 | memcpy(hdr->addr3, vp->bssid, ETH_ALEN); | 1669 | memcpy(hdr->addr3, vp->bssid, ETH_ALEN); |
1376 | 1670 | ||
1377 | /* wmediumd mode check */ | 1671 | rcu_read_lock(); |
1378 | _portid = ACCESS_ONCE(wmediumd_portid); | 1672 | mac80211_hwsim_tx_frame(data->hw, skb, |
1379 | 1673 | rcu_dereference(vif->chanctx_conf)->def.chan); | |
1380 | if (_portid) | 1674 | rcu_read_unlock(); |
1381 | return mac80211_hwsim_tx_frame_nl(data->hw, skb, _portid); | ||
1382 | |||
1383 | if (!mac80211_hwsim_tx_frame_no_nl(data->hw, skb)) | ||
1384 | printk(KERN_DEBUG "%s: nullfunc frame not ack'ed\n", __func__); | ||
1385 | dev_kfree_skb(skb); | ||
1386 | } | 1675 | } |
1387 | 1676 | ||
1388 | 1677 | ||
@@ -1423,14 +1712,17 @@ static int hwsim_fops_ps_write(void *dat, u64 val) | |||
1423 | 1712 | ||
1424 | if (val == PS_MANUAL_POLL) { | 1713 | if (val == PS_MANUAL_POLL) { |
1425 | ieee80211_iterate_active_interfaces(data->hw, | 1714 | ieee80211_iterate_active_interfaces(data->hw, |
1715 | IEEE80211_IFACE_ITER_NORMAL, | ||
1426 | hwsim_send_ps_poll, data); | 1716 | hwsim_send_ps_poll, data); |
1427 | data->ps_poll_pending = true; | 1717 | data->ps_poll_pending = true; |
1428 | } else if (old_ps == PS_DISABLED && val != PS_DISABLED) { | 1718 | } else if (old_ps == PS_DISABLED && val != PS_DISABLED) { |
1429 | ieee80211_iterate_active_interfaces(data->hw, | 1719 | ieee80211_iterate_active_interfaces(data->hw, |
1720 | IEEE80211_IFACE_ITER_NORMAL, | ||
1430 | hwsim_send_nullfunc_ps, | 1721 | hwsim_send_nullfunc_ps, |
1431 | data); | 1722 | data); |
1432 | } else if (old_ps != PS_DISABLED && val == PS_DISABLED) { | 1723 | } else if (old_ps != PS_DISABLED && val == PS_DISABLED) { |
1433 | ieee80211_iterate_active_interfaces(data->hw, | 1724 | ieee80211_iterate_active_interfaces(data->hw, |
1725 | IEEE80211_IFACE_ITER_NORMAL, | ||
1434 | hwsim_send_nullfunc_no_ps, | 1726 | hwsim_send_nullfunc_no_ps, |
1435 | data); | 1727 | data); |
1436 | } | 1728 | } |
@@ -1551,7 +1843,8 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2, | |||
1551 | (hwsim_flags & HWSIM_TX_STAT_ACK)) { | 1843 | (hwsim_flags & HWSIM_TX_STAT_ACK)) { |
1552 | if (skb->len >= 16) { | 1844 | if (skb->len >= 16) { |
1553 | hdr = (struct ieee80211_hdr *) skb->data; | 1845 | hdr = (struct ieee80211_hdr *) skb->data; |
1554 | mac80211_hwsim_monitor_ack(data2->hw, hdr->addr2); | 1846 | mac80211_hwsim_monitor_ack(txi->rate_driver_data[0], |
1847 | hdr->addr2); | ||
1555 | } | 1848 | } |
1556 | txi->flags |= IEEE80211_TX_STAT_ACK; | 1849 | txi->flags |= IEEE80211_TX_STAT_ACK; |
1557 | } | 1850 | } |
@@ -1566,7 +1859,7 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2, | |||
1566 | struct genl_info *info) | 1859 | struct genl_info *info) |
1567 | { | 1860 | { |
1568 | 1861 | ||
1569 | struct mac80211_hwsim_data *data2; | 1862 | struct mac80211_hwsim_data *data2; |
1570 | struct ieee80211_rx_status rx_status; | 1863 | struct ieee80211_rx_status rx_status; |
1571 | struct mac_address *dst; | 1864 | struct mac_address *dst; |
1572 | int frame_data_len; | 1865 | int frame_data_len; |
@@ -1574,9 +1867,9 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2, | |||
1574 | struct sk_buff *skb = NULL; | 1867 | struct sk_buff *skb = NULL; |
1575 | 1868 | ||
1576 | if (!info->attrs[HWSIM_ATTR_ADDR_RECEIVER] || | 1869 | if (!info->attrs[HWSIM_ATTR_ADDR_RECEIVER] || |
1577 | !info->attrs[HWSIM_ATTR_FRAME] || | 1870 | !info->attrs[HWSIM_ATTR_FRAME] || |
1578 | !info->attrs[HWSIM_ATTR_RX_RATE] || | 1871 | !info->attrs[HWSIM_ATTR_RX_RATE] || |
1579 | !info->attrs[HWSIM_ATTR_SIGNAL]) | 1872 | !info->attrs[HWSIM_ATTR_SIGNAL]) |
1580 | goto out; | 1873 | goto out; |
1581 | 1874 | ||
1582 | dst = (struct mac_address *)nla_data( | 1875 | dst = (struct mac_address *)nla_data( |
@@ -1604,7 +1897,7 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2, | |||
1604 | 1897 | ||
1605 | /* check if radio is configured properly */ | 1898 | /* check if radio is configured properly */ |
1606 | 1899 | ||
1607 | if (data2->idle || !data2->started || !data2->channel) | 1900 | if (data2->idle || !data2->started) |
1608 | goto out; | 1901 | goto out; |
1609 | 1902 | ||
1610 | /*A frame is received from user space*/ | 1903 | /*A frame is received from user space*/ |
@@ -1688,6 +1981,11 @@ static struct notifier_block hwsim_netlink_notifier = { | |||
1688 | static int hwsim_init_netlink(void) | 1981 | static int hwsim_init_netlink(void) |
1689 | { | 1982 | { |
1690 | int rc; | 1983 | int rc; |
1984 | |||
1985 | /* userspace test API hasn't been adjusted for multi-channel */ | ||
1986 | if (channels > 1) | ||
1987 | return 0; | ||
1988 | |||
1691 | printk(KERN_INFO "mac80211_hwsim: initializing netlink\n"); | 1989 | printk(KERN_INFO "mac80211_hwsim: initializing netlink\n"); |
1692 | 1990 | ||
1693 | rc = genl_register_family_with_ops(&hwsim_genl_family, | 1991 | rc = genl_register_family_with_ops(&hwsim_genl_family, |
@@ -1710,6 +2008,10 @@ static void hwsim_exit_netlink(void) | |||
1710 | { | 2008 | { |
1711 | int ret; | 2009 | int ret; |
1712 | 2010 | ||
2011 | /* userspace test API hasn't been adjusted for multi-channel */ | ||
2012 | if (channels > 1) | ||
2013 | return; | ||
2014 | |||
1713 | printk(KERN_INFO "mac80211_hwsim: closing netlink\n"); | 2015 | printk(KERN_INFO "mac80211_hwsim: closing netlink\n"); |
1714 | /* unregister the notifier */ | 2016 | /* unregister the notifier */ |
1715 | netlink_unregister_notifier(&hwsim_netlink_notifier); | 2017 | netlink_unregister_notifier(&hwsim_netlink_notifier); |
@@ -1732,7 +2034,7 @@ static const struct ieee80211_iface_limit hwsim_if_limits[] = { | |||
1732 | { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_DEVICE) }, | 2034 | { .max = 1, .types = BIT(NL80211_IFTYPE_P2P_DEVICE) }, |
1733 | }; | 2035 | }; |
1734 | 2036 | ||
1735 | static const struct ieee80211_iface_combination hwsim_if_comb = { | 2037 | static struct ieee80211_iface_combination hwsim_if_comb = { |
1736 | .limits = hwsim_if_limits, | 2038 | .limits = hwsim_if_limits, |
1737 | .n_limits = ARRAY_SIZE(hwsim_if_limits), | 2039 | .n_limits = ARRAY_SIZE(hwsim_if_limits), |
1738 | .max_interfaces = 2048, | 2040 | .max_interfaces = 2048, |
@@ -1750,10 +2052,30 @@ static int __init init_mac80211_hwsim(void) | |||
1750 | if (radios < 1 || radios > 100) | 2052 | if (radios < 1 || radios > 100) |
1751 | return -EINVAL; | 2053 | return -EINVAL; |
1752 | 2054 | ||
1753 | if (fake_hw_scan) { | 2055 | if (channels < 1) |
2056 | return -EINVAL; | ||
2057 | |||
2058 | if (channels > 1) { | ||
2059 | hwsim_if_comb.num_different_channels = channels; | ||
1754 | mac80211_hwsim_ops.hw_scan = mac80211_hwsim_hw_scan; | 2060 | mac80211_hwsim_ops.hw_scan = mac80211_hwsim_hw_scan; |
2061 | mac80211_hwsim_ops.cancel_hw_scan = | ||
2062 | mac80211_hwsim_cancel_hw_scan; | ||
1755 | mac80211_hwsim_ops.sw_scan_start = NULL; | 2063 | mac80211_hwsim_ops.sw_scan_start = NULL; |
1756 | mac80211_hwsim_ops.sw_scan_complete = NULL; | 2064 | mac80211_hwsim_ops.sw_scan_complete = NULL; |
2065 | mac80211_hwsim_ops.remain_on_channel = | ||
2066 | mac80211_hwsim_roc; | ||
2067 | mac80211_hwsim_ops.cancel_remain_on_channel = | ||
2068 | mac80211_hwsim_croc; | ||
2069 | mac80211_hwsim_ops.add_chanctx = | ||
2070 | mac80211_hwsim_add_chanctx; | ||
2071 | mac80211_hwsim_ops.remove_chanctx = | ||
2072 | mac80211_hwsim_remove_chanctx; | ||
2073 | mac80211_hwsim_ops.change_chanctx = | ||
2074 | mac80211_hwsim_change_chanctx; | ||
2075 | mac80211_hwsim_ops.assign_vif_chanctx = | ||
2076 | mac80211_hwsim_assign_vif_chanctx; | ||
2077 | mac80211_hwsim_ops.unassign_vif_chanctx = | ||
2078 | mac80211_hwsim_unassign_vif_chanctx; | ||
1757 | } | 2079 | } |
1758 | 2080 | ||
1759 | spin_lock_init(&hwsim_radio_lock); | 2081 | spin_lock_init(&hwsim_radio_lock); |
@@ -1803,13 +2125,18 @@ static int __init init_mac80211_hwsim(void) | |||
1803 | hw->wiphy->iface_combinations = &hwsim_if_comb; | 2125 | hw->wiphy->iface_combinations = &hwsim_if_comb; |
1804 | hw->wiphy->n_iface_combinations = 1; | 2126 | hw->wiphy->n_iface_combinations = 1; |
1805 | 2127 | ||
1806 | if (fake_hw_scan) { | 2128 | if (channels > 1) { |
1807 | hw->wiphy->max_scan_ssids = 255; | 2129 | hw->wiphy->max_scan_ssids = 255; |
1808 | hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; | 2130 | hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; |
2131 | hw->wiphy->max_remain_on_channel_duration = 1000; | ||
1809 | } | 2132 | } |
1810 | 2133 | ||
2134 | INIT_DELAYED_WORK(&data->roc_done, hw_roc_done); | ||
2135 | INIT_DELAYED_WORK(&data->hw_scan, hw_scan_work); | ||
2136 | |||
1811 | hw->channel_change_time = 1; | 2137 | hw->channel_change_time = 1; |
1812 | hw->queues = 4; | 2138 | hw->queues = 5; |
2139 | hw->offchannel_tx_hw_queue = 4; | ||
1813 | hw->wiphy->interface_modes = | 2140 | hw->wiphy->interface_modes = |
1814 | BIT(NL80211_IFTYPE_STATION) | | 2141 | BIT(NL80211_IFTYPE_STATION) | |
1815 | BIT(NL80211_IFTYPE_AP) | | 2142 | BIT(NL80211_IFTYPE_AP) | |
@@ -1824,7 +2151,8 @@ static int __init init_mac80211_hwsim(void) | |||
1824 | IEEE80211_HW_SUPPORTS_STATIC_SMPS | | 2151 | IEEE80211_HW_SUPPORTS_STATIC_SMPS | |
1825 | IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | | 2152 | IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | |
1826 | IEEE80211_HW_AMPDU_AGGREGATION | | 2153 | IEEE80211_HW_AMPDU_AGGREGATION | |
1827 | IEEE80211_HW_WANT_MONITOR_VIF; | 2154 | IEEE80211_HW_WANT_MONITOR_VIF | |
2155 | IEEE80211_HW_QUEUE_CONTROL; | ||
1828 | 2156 | ||
1829 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS | | 2157 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS | |
1830 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; | 2158 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; |
@@ -1874,6 +2202,34 @@ static int __init init_mac80211_hwsim(void) | |||
1874 | sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; | 2202 | sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; |
1875 | 2203 | ||
1876 | hw->wiphy->bands[band] = sband; | 2204 | hw->wiphy->bands[band] = sband; |
2205 | |||
2206 | if (channels == 1) | ||
2207 | continue; | ||
2208 | |||
2209 | sband->vht_cap.vht_supported = true; | ||
2210 | sband->vht_cap.cap = | ||
2211 | IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 | | ||
2212 | IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ | | ||
2213 | IEEE80211_VHT_CAP_RXLDPC | | ||
2214 | IEEE80211_VHT_CAP_SHORT_GI_80 | | ||
2215 | IEEE80211_VHT_CAP_SHORT_GI_160 | | ||
2216 | IEEE80211_VHT_CAP_TXSTBC | | ||
2217 | IEEE80211_VHT_CAP_RXSTBC_1 | | ||
2218 | IEEE80211_VHT_CAP_RXSTBC_2 | | ||
2219 | IEEE80211_VHT_CAP_RXSTBC_3 | | ||
2220 | IEEE80211_VHT_CAP_RXSTBC_4 | | ||
2221 | IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT; | ||
2222 | sband->vht_cap.vht_mcs.rx_mcs_map = | ||
2223 | cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_8 << 0 | | ||
2224 | IEEE80211_VHT_MCS_SUPPORT_0_8 << 2 | | ||
2225 | IEEE80211_VHT_MCS_SUPPORT_0_9 << 4 | | ||
2226 | IEEE80211_VHT_MCS_SUPPORT_0_8 << 6 | | ||
2227 | IEEE80211_VHT_MCS_SUPPORT_0_8 << 8 | | ||
2228 | IEEE80211_VHT_MCS_SUPPORT_0_9 << 10 | | ||
2229 | IEEE80211_VHT_MCS_SUPPORT_0_9 << 12 | | ||
2230 | IEEE80211_VHT_MCS_SUPPORT_0_8 << 14); | ||
2231 | sband->vht_cap.vht_mcs.tx_mcs_map = | ||
2232 | sband->vht_cap.vht_mcs.rx_mcs_map; | ||
1877 | } | 2233 | } |
1878 | /* By default all radios are belonging to the first group */ | 2234 | /* By default all radios are belonging to the first group */ |
1879 | data->group = 1; | 2235 | data->group = 1; |
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c index 395f1bfd4102..68d52cfc1ebd 100644 --- a/drivers/net/wireless/mwifiex/11n_aggr.c +++ b/drivers/net/wireless/mwifiex/11n_aggr.c | |||
@@ -197,7 +197,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, | |||
197 | ra_list_flags); | 197 | ra_list_flags); |
198 | mwifiex_11n_form_amsdu_pkt(skb_aggr, skb_src, &pad); | 198 | mwifiex_11n_form_amsdu_pkt(skb_aggr, skb_src, &pad); |
199 | 199 | ||
200 | mwifiex_write_data_complete(adapter, skb_src, 0); | 200 | mwifiex_write_data_complete(adapter, skb_src, 0, 0); |
201 | 201 | ||
202 | spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags); | 202 | spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags); |
203 | 203 | ||
@@ -256,7 +256,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, | |||
256 | if (!mwifiex_is_ralist_valid(priv, pra_list, ptrindex)) { | 256 | if (!mwifiex_is_ralist_valid(priv, pra_list, ptrindex)) { |
257 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, | 257 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, |
258 | ra_list_flags); | 258 | ra_list_flags); |
259 | mwifiex_write_data_complete(adapter, skb_aggr, -1); | 259 | mwifiex_write_data_complete(adapter, skb_aggr, 1, -1); |
260 | return -1; | 260 | return -1; |
261 | } | 261 | } |
262 | if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA && | 262 | if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA && |
@@ -282,13 +282,13 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, | |||
282 | dev_err(adapter->dev, "%s: host_to_card failed: %#x\n", | 282 | dev_err(adapter->dev, "%s: host_to_card failed: %#x\n", |
283 | __func__, ret); | 283 | __func__, ret); |
284 | adapter->dbg.num_tx_host_to_card_failure++; | 284 | adapter->dbg.num_tx_host_to_card_failure++; |
285 | mwifiex_write_data_complete(adapter, skb_aggr, ret); | 285 | mwifiex_write_data_complete(adapter, skb_aggr, 1, ret); |
286 | return 0; | 286 | return 0; |
287 | case -EINPROGRESS: | 287 | case -EINPROGRESS: |
288 | adapter->data_sent = false; | 288 | adapter->data_sent = false; |
289 | break; | 289 | break; |
290 | case 0: | 290 | case 0: |
291 | mwifiex_write_data_complete(adapter, skb_aggr, ret); | 291 | mwifiex_write_data_complete(adapter, skb_aggr, 1, ret); |
292 | break; | 292 | break; |
293 | default: | 293 | default: |
294 | break; | 294 | break; |
diff --git a/drivers/net/wireless/mwifiex/Kconfig b/drivers/net/wireless/mwifiex/Kconfig index 8e384fae3e68..b2e27723f801 100644 --- a/drivers/net/wireless/mwifiex/Kconfig +++ b/drivers/net/wireless/mwifiex/Kconfig | |||
@@ -1,7 +1,6 @@ | |||
1 | config MWIFIEX | 1 | config MWIFIEX |
2 | tristate "Marvell WiFi-Ex Driver" | 2 | tristate "Marvell WiFi-Ex Driver" |
3 | depends on CFG80211 | 3 | depends on CFG80211 |
4 | select LIB80211 | ||
5 | ---help--- | 4 | ---help--- |
6 | This adds support for wireless adapters based on Marvell | 5 | This adds support for wireless adapters based on Marvell |
7 | 802.11n chipsets. | 6 | 802.11n chipsets. |
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index fdb1eb861021..3b1c27712ad9 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
@@ -180,10 +180,8 @@ mwifiex_form_mgmt_frame(struct sk_buff *skb, const u8 *buf, size_t len) | |||
180 | static int | 180 | static int |
181 | mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, | 181 | mwifiex_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, |
182 | struct ieee80211_channel *chan, bool offchan, | 182 | struct ieee80211_channel *chan, bool offchan, |
183 | enum nl80211_channel_type channel_type, | 183 | unsigned int wait, const u8 *buf, size_t len, |
184 | bool channel_type_valid, unsigned int wait, | 184 | bool no_cck, bool dont_wait_for_ack, u64 *cookie) |
185 | const u8 *buf, size_t len, bool no_cck, | ||
186 | bool dont_wait_for_ack, u64 *cookie) | ||
187 | { | 185 | { |
188 | struct sk_buff *skb; | 186 | struct sk_buff *skb; |
189 | u16 pkt_len; | 187 | u16 pkt_len; |
@@ -253,7 +251,6 @@ static int | |||
253 | mwifiex_cfg80211_remain_on_channel(struct wiphy *wiphy, | 251 | mwifiex_cfg80211_remain_on_channel(struct wiphy *wiphy, |
254 | struct wireless_dev *wdev, | 252 | struct wireless_dev *wdev, |
255 | struct ieee80211_channel *chan, | 253 | struct ieee80211_channel *chan, |
256 | enum nl80211_channel_type channel_type, | ||
257 | unsigned int duration, u64 *cookie) | 254 | unsigned int duration, u64 *cookie) |
258 | { | 255 | { |
259 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev); | 256 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev); |
@@ -271,15 +268,14 @@ mwifiex_cfg80211_remain_on_channel(struct wiphy *wiphy, | |||
271 | } | 268 | } |
272 | 269 | ||
273 | ret = mwifiex_remain_on_chan_cfg(priv, HostCmd_ACT_GEN_SET, chan, | 270 | ret = mwifiex_remain_on_chan_cfg(priv, HostCmd_ACT_GEN_SET, chan, |
274 | &channel_type, duration); | 271 | duration); |
275 | 272 | ||
276 | if (!ret) { | 273 | if (!ret) { |
277 | *cookie = random32() | 1; | 274 | *cookie = random32() | 1; |
278 | priv->roc_cfg.cookie = *cookie; | 275 | priv->roc_cfg.cookie = *cookie; |
279 | priv->roc_cfg.chan = *chan; | 276 | priv->roc_cfg.chan = *chan; |
280 | priv->roc_cfg.chan_type = channel_type; | ||
281 | 277 | ||
282 | cfg80211_ready_on_channel(wdev, *cookie, chan, channel_type, | 278 | cfg80211_ready_on_channel(wdev, *cookie, chan, |
283 | duration, GFP_ATOMIC); | 279 | duration, GFP_ATOMIC); |
284 | 280 | ||
285 | wiphy_dbg(wiphy, "info: ROC, cookie = 0x%llx\n", *cookie); | 281 | wiphy_dbg(wiphy, "info: ROC, cookie = 0x%llx\n", *cookie); |
@@ -302,13 +298,11 @@ mwifiex_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, | |||
302 | return -ENOENT; | 298 | return -ENOENT; |
303 | 299 | ||
304 | ret = mwifiex_remain_on_chan_cfg(priv, HostCmd_ACT_GEN_REMOVE, | 300 | ret = mwifiex_remain_on_chan_cfg(priv, HostCmd_ACT_GEN_REMOVE, |
305 | &priv->roc_cfg.chan, | 301 | &priv->roc_cfg.chan, 0); |
306 | &priv->roc_cfg.chan_type, 0); | ||
307 | 302 | ||
308 | if (!ret) { | 303 | if (!ret) { |
309 | cfg80211_remain_on_channel_expired(wdev, cookie, | 304 | cfg80211_remain_on_channel_expired(wdev, cookie, |
310 | &priv->roc_cfg.chan, | 305 | &priv->roc_cfg.chan, |
311 | priv->roc_cfg.chan_type, | ||
312 | GFP_ATOMIC); | 306 | GFP_ATOMIC); |
313 | 307 | ||
314 | memset(&priv->roc_cfg, 0, sizeof(struct mwifiex_roc_cfg)); | 308 | memset(&priv->roc_cfg, 0, sizeof(struct mwifiex_roc_cfg)); |
@@ -324,6 +318,7 @@ mwifiex_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy, | |||
324 | */ | 318 | */ |
325 | static int | 319 | static int |
326 | mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy, | 320 | mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy, |
321 | struct wireless_dev *wdev, | ||
327 | enum nl80211_tx_power_setting type, | 322 | enum nl80211_tx_power_setting type, |
328 | int mbm) | 323 | int mbm) |
329 | { | 324 | { |
@@ -1296,21 +1291,23 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, | |||
1296 | return -EINVAL; | 1291 | return -EINVAL; |
1297 | } | 1292 | } |
1298 | 1293 | ||
1299 | bss_cfg->channel = | 1294 | bss_cfg->channel = ieee80211_frequency_to_channel( |
1300 | (u8)ieee80211_frequency_to_channel(params->channel->center_freq); | 1295 | params->chandef.chan->center_freq); |
1301 | 1296 | ||
1302 | /* Set appropriate bands */ | 1297 | /* Set appropriate bands */ |
1303 | if (params->channel->band == IEEE80211_BAND_2GHZ) { | 1298 | if (params->chandef.chan->band == IEEE80211_BAND_2GHZ) { |
1304 | bss_cfg->band_cfg = BAND_CONFIG_BG; | 1299 | bss_cfg->band_cfg = BAND_CONFIG_BG; |
1305 | 1300 | ||
1306 | if (params->channel_type == NL80211_CHAN_NO_HT) | 1301 | if (cfg80211_get_chandef_type(¶ms->chandef) == |
1302 | NL80211_CHAN_NO_HT) | ||
1307 | config_bands = BAND_B | BAND_G; | 1303 | config_bands = BAND_B | BAND_G; |
1308 | else | 1304 | else |
1309 | config_bands = BAND_B | BAND_G | BAND_GN; | 1305 | config_bands = BAND_B | BAND_G | BAND_GN; |
1310 | } else { | 1306 | } else { |
1311 | bss_cfg->band_cfg = BAND_CONFIG_A; | 1307 | bss_cfg->band_cfg = BAND_CONFIG_A; |
1312 | 1308 | ||
1313 | if (params->channel_type == NL80211_CHAN_NO_HT) | 1309 | if (cfg80211_get_chandef_type(¶ms->chandef) == |
1310 | NL80211_CHAN_NO_HT) | ||
1314 | config_bands = BAND_A; | 1311 | config_bands = BAND_A; |
1315 | else | 1312 | else |
1316 | config_bands = BAND_AN | BAND_A; | 1313 | config_bands = BAND_AN | BAND_A; |
@@ -1683,7 +1680,7 @@ static int mwifiex_set_ibss_params(struct mwifiex_private *priv, | |||
1683 | int index = 0, i; | 1680 | int index = 0, i; |
1684 | u8 config_bands = 0; | 1681 | u8 config_bands = 0; |
1685 | 1682 | ||
1686 | if (params->channel->band == IEEE80211_BAND_2GHZ) { | 1683 | if (params->chandef.chan->band == IEEE80211_BAND_2GHZ) { |
1687 | if (!params->basic_rates) { | 1684 | if (!params->basic_rates) { |
1688 | config_bands = BAND_B | BAND_G; | 1685 | config_bands = BAND_B | BAND_G; |
1689 | } else { | 1686 | } else { |
@@ -1708,10 +1705,12 @@ static int mwifiex_set_ibss_params(struct mwifiex_private *priv, | |||
1708 | } | 1705 | } |
1709 | } | 1706 | } |
1710 | 1707 | ||
1711 | if (params->channel_type != NL80211_CHAN_NO_HT) | 1708 | if (cfg80211_get_chandef_type(¶ms->chandef) != |
1709 | NL80211_CHAN_NO_HT) | ||
1712 | config_bands |= BAND_GN; | 1710 | config_bands |= BAND_GN; |
1713 | } else { | 1711 | } else { |
1714 | if (params->channel_type == NL80211_CHAN_NO_HT) | 1712 | if (cfg80211_get_chandef_type(¶ms->chandef) != |
1713 | NL80211_CHAN_NO_HT) | ||
1715 | config_bands = BAND_A; | 1714 | config_bands = BAND_A; |
1716 | else | 1715 | else |
1717 | config_bands = BAND_AN | BAND_A; | 1716 | config_bands = BAND_AN | BAND_A; |
@@ -1728,9 +1727,10 @@ static int mwifiex_set_ibss_params(struct mwifiex_private *priv, | |||
1728 | } | 1727 | } |
1729 | 1728 | ||
1730 | adapter->sec_chan_offset = | 1729 | adapter->sec_chan_offset = |
1731 | mwifiex_chan_type_to_sec_chan_offset(params->channel_type); | 1730 | mwifiex_chan_type_to_sec_chan_offset( |
1732 | priv->adhoc_channel = | 1731 | cfg80211_get_chandef_type(¶ms->chandef)); |
1733 | ieee80211_frequency_to_channel(params->channel->center_freq); | 1732 | priv->adhoc_channel = ieee80211_frequency_to_channel( |
1733 | params->chandef.chan->center_freq); | ||
1734 | 1734 | ||
1735 | wiphy_dbg(wiphy, "info: set ibss band %d, chan %d, chan offset %d\n", | 1735 | wiphy_dbg(wiphy, "info: set ibss band %d, chan %d, chan offset %d\n", |
1736 | config_bands, priv->adhoc_channel, adapter->sec_chan_offset); | 1736 | config_bands, priv->adhoc_channel, adapter->sec_chan_offset); |
@@ -1764,7 +1764,8 @@ mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, | |||
1764 | 1764 | ||
1765 | ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid, | 1765 | ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid, |
1766 | params->bssid, priv->bss_mode, | 1766 | params->bssid, priv->bss_mode, |
1767 | params->channel, NULL, params->privacy); | 1767 | params->chandef.chan, NULL, |
1768 | params->privacy); | ||
1768 | done: | 1769 | done: |
1769 | if (!ret) { | 1770 | if (!ret) { |
1770 | cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL); | 1771 | cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL); |
@@ -2080,8 +2081,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, | |||
2080 | return ERR_PTR(-EINVAL); | 2081 | return ERR_PTR(-EINVAL); |
2081 | } | 2082 | } |
2082 | 2083 | ||
2083 | dev = alloc_netdev_mq(sizeof(struct mwifiex_private *), name, | 2084 | dev = alloc_netdev_mqs(sizeof(struct mwifiex_private *), name, |
2084 | ether_setup, 1); | 2085 | ether_setup, IEEE80211_NUM_ACS, 1); |
2085 | if (!dev) { | 2086 | if (!dev) { |
2086 | wiphy_err(wiphy, "no memory available for netdevice\n"); | 2087 | wiphy_err(wiphy, "no memory available for netdevice\n"); |
2087 | priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; | 2088 | priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; |
@@ -2143,8 +2144,7 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev) | |||
2143 | mwifiex_dev_debugfs_remove(priv); | 2144 | mwifiex_dev_debugfs_remove(priv); |
2144 | #endif | 2145 | #endif |
2145 | 2146 | ||
2146 | if (!netif_queue_stopped(priv->netdev)) | 2147 | mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter); |
2147 | netif_stop_queue(priv->netdev); | ||
2148 | 2148 | ||
2149 | if (netif_carrier_ok(priv->netdev)) | 2149 | if (netif_carrier_ok(priv->netdev)) |
2150 | netif_carrier_off(priv->netdev); | 2150 | netif_carrier_off(priv->netdev); |
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index be52a0a8d645..5f438e6c2155 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c | |||
@@ -949,6 +949,9 @@ mwifiex_cmd_timeout_func(unsigned long function_context) | |||
949 | } | 949 | } |
950 | if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) | 950 | if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) |
951 | mwifiex_init_fw_complete(adapter); | 951 | mwifiex_init_fw_complete(adapter); |
952 | |||
953 | if (adapter->if_ops.card_reset) | ||
954 | adapter->if_ops.card_reset(adapter); | ||
952 | } | 955 | } |
953 | 956 | ||
954 | /* | 957 | /* |
diff --git a/drivers/net/wireless/mwifiex/debugfs.c b/drivers/net/wireless/mwifiex/debugfs.c index a870b5885c09..46e34aa65d1c 100644 --- a/drivers/net/wireless/mwifiex/debugfs.c +++ b/drivers/net/wireless/mwifiex/debugfs.c | |||
@@ -178,6 +178,7 @@ mwifiex_info_read(struct file *file, char __user *ubuf, | |||
178 | (struct mwifiex_private *) file->private_data; | 178 | (struct mwifiex_private *) file->private_data; |
179 | struct net_device *netdev = priv->netdev; | 179 | struct net_device *netdev = priv->netdev; |
180 | struct netdev_hw_addr *ha; | 180 | struct netdev_hw_addr *ha; |
181 | struct netdev_queue *txq; | ||
181 | unsigned long page = get_zeroed_page(GFP_KERNEL); | 182 | unsigned long page = get_zeroed_page(GFP_KERNEL); |
182 | char *p = (char *) page, fmt[64]; | 183 | char *p = (char *) page, fmt[64]; |
183 | struct mwifiex_bss_info info; | 184 | struct mwifiex_bss_info info; |
@@ -229,8 +230,13 @@ mwifiex_info_read(struct file *file, char __user *ubuf, | |||
229 | p += sprintf(p, "num_rx_pkts_err = %lu\n", priv->stats.rx_errors); | 230 | p += sprintf(p, "num_rx_pkts_err = %lu\n", priv->stats.rx_errors); |
230 | p += sprintf(p, "carrier %s\n", ((netif_carrier_ok(priv->netdev)) | 231 | p += sprintf(p, "carrier %s\n", ((netif_carrier_ok(priv->netdev)) |
231 | ? "on" : "off")); | 232 | ? "on" : "off")); |
232 | p += sprintf(p, "tx queue %s\n", ((netif_queue_stopped(priv->netdev)) | 233 | p += sprintf(p, "tx queue"); |
233 | ? "stopped" : "started")); | 234 | for (i = 0; i < netdev->num_tx_queues; i++) { |
235 | txq = netdev_get_tx_queue(netdev, i); | ||
236 | p += sprintf(p, " %d:%s", i, netif_tx_queue_stopped(txq) ? | ||
237 | "stopped" : "started"); | ||
238 | } | ||
239 | p += sprintf(p, "\n"); | ||
234 | 240 | ||
235 | ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page, | 241 | ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page, |
236 | (unsigned long) p - page); | 242 | (unsigned long) p - page); |
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index 482faace7900..39f03ce5a5b1 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c | |||
@@ -388,9 +388,17 @@ void mwifiex_wake_up_net_dev_queue(struct net_device *netdev, | |||
388 | struct mwifiex_adapter *adapter) | 388 | struct mwifiex_adapter *adapter) |
389 | { | 389 | { |
390 | unsigned long dev_queue_flags; | 390 | unsigned long dev_queue_flags; |
391 | unsigned int i; | ||
391 | 392 | ||
392 | spin_lock_irqsave(&adapter->queue_lock, dev_queue_flags); | 393 | spin_lock_irqsave(&adapter->queue_lock, dev_queue_flags); |
393 | netif_tx_wake_all_queues(netdev); | 394 | |
395 | for (i = 0; i < netdev->num_tx_queues; i++) { | ||
396 | struct netdev_queue *txq = netdev_get_tx_queue(netdev, i); | ||
397 | |||
398 | if (netif_tx_queue_stopped(txq)) | ||
399 | netif_tx_wake_queue(txq); | ||
400 | } | ||
401 | |||
394 | spin_unlock_irqrestore(&adapter->queue_lock, dev_queue_flags); | 402 | spin_unlock_irqrestore(&adapter->queue_lock, dev_queue_flags); |
395 | } | 403 | } |
396 | 404 | ||
@@ -401,9 +409,17 @@ void mwifiex_stop_net_dev_queue(struct net_device *netdev, | |||
401 | struct mwifiex_adapter *adapter) | 409 | struct mwifiex_adapter *adapter) |
402 | { | 410 | { |
403 | unsigned long dev_queue_flags; | 411 | unsigned long dev_queue_flags; |
412 | unsigned int i; | ||
404 | 413 | ||
405 | spin_lock_irqsave(&adapter->queue_lock, dev_queue_flags); | 414 | spin_lock_irqsave(&adapter->queue_lock, dev_queue_flags); |
406 | netif_tx_stop_all_queues(netdev); | 415 | |
416 | for (i = 0; i < netdev->num_tx_queues; i++) { | ||
417 | struct netdev_queue *txq = netdev_get_tx_queue(netdev, i); | ||
418 | |||
419 | if (!netif_tx_queue_stopped(txq)) | ||
420 | netif_tx_stop_queue(txq); | ||
421 | } | ||
422 | |||
407 | spin_unlock_irqrestore(&adapter->queue_lock, dev_queue_flags); | 423 | spin_unlock_irqrestore(&adapter->queue_lock, dev_queue_flags); |
408 | } | 424 | } |
409 | 425 | ||
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 7b0858af8f5d..88664ae667ba 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c | |||
@@ -721,8 +721,7 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, | |||
721 | 721 | ||
722 | if (!netif_carrier_ok(priv->netdev)) | 722 | if (!netif_carrier_ok(priv->netdev)) |
723 | netif_carrier_on(priv->netdev); | 723 | netif_carrier_on(priv->netdev); |
724 | if (netif_queue_stopped(priv->netdev)) | 724 | mwifiex_wake_up_net_dev_queue(priv->netdev, adapter); |
725 | netif_wake_queue(priv->netdev); | ||
726 | 725 | ||
727 | if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled) | 726 | if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled) |
728 | priv->scan_block = true; | 727 | priv->scan_block = true; |
@@ -1238,8 +1237,7 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, | |||
1238 | 1237 | ||
1239 | if (!netif_carrier_ok(priv->netdev)) | 1238 | if (!netif_carrier_ok(priv->netdev)) |
1240 | netif_carrier_on(priv->netdev); | 1239 | netif_carrier_on(priv->netdev); |
1241 | if (netif_queue_stopped(priv->netdev)) | 1240 | mwifiex_wake_up_net_dev_queue(priv->netdev, adapter); |
1242 | netif_wake_queue(priv->netdev); | ||
1243 | 1241 | ||
1244 | mwifiex_save_curr_bcn(priv); | 1242 | mwifiex_save_curr_bcn(priv); |
1245 | 1243 | ||
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 1df767bc8b6e..9c802ede9c3b 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c | |||
@@ -282,6 +282,7 @@ exit_main_proc: | |||
282 | mwifiex_shutdown_drv(adapter); | 282 | mwifiex_shutdown_drv(adapter); |
283 | return ret; | 283 | return ret; |
284 | } | 284 | } |
285 | EXPORT_SYMBOL_GPL(mwifiex_main_process); | ||
285 | 286 | ||
286 | /* | 287 | /* |
287 | * This function frees the adapter structure. | 288 | * This function frees the adapter structure. |
@@ -412,49 +413,6 @@ static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter) | |||
412 | } | 413 | } |
413 | 414 | ||
414 | /* | 415 | /* |
415 | * This function fills a driver buffer. | ||
416 | * | ||
417 | * The function associates a given SKB with the provided driver buffer | ||
418 | * and also updates some of the SKB parameters, including IP header, | ||
419 | * priority and timestamp. | ||
420 | */ | ||
421 | static void | ||
422 | mwifiex_fill_buffer(struct sk_buff *skb) | ||
423 | { | ||
424 | struct ethhdr *eth; | ||
425 | struct iphdr *iph; | ||
426 | struct timeval tv; | ||
427 | u8 tid = 0; | ||
428 | |||
429 | eth = (struct ethhdr *) skb->data; | ||
430 | switch (eth->h_proto) { | ||
431 | case __constant_htons(ETH_P_IP): | ||
432 | iph = ip_hdr(skb); | ||
433 | tid = IPTOS_PREC(iph->tos); | ||
434 | pr_debug("data: packet type ETH_P_IP: %04x, tid=%#x prio=%#x\n", | ||
435 | eth->h_proto, tid, skb->priority); | ||
436 | break; | ||
437 | case __constant_htons(ETH_P_ARP): | ||
438 | pr_debug("data: ARP packet: %04x\n", eth->h_proto); | ||
439 | default: | ||
440 | break; | ||
441 | } | ||
442 | /* Offset for TOS field in the IP header */ | ||
443 | #define IPTOS_OFFSET 5 | ||
444 | tid = (tid >> IPTOS_OFFSET); | ||
445 | skb->priority = tid; | ||
446 | /* Record the current time the packet was queued; used to | ||
447 | determine the amount of time the packet was queued in | ||
448 | the driver before it was sent to the firmware. | ||
449 | The delay is then sent along with the packet to the | ||
450 | firmware for aggregate delay calculation for stats and | ||
451 | MSDU lifetime expiry. | ||
452 | */ | ||
453 | do_gettimeofday(&tv); | ||
454 | skb->tstamp = timeval_to_ktime(tv); | ||
455 | } | ||
456 | |||
457 | /* | ||
458 | * CFG802.11 network device handler for open. | 416 | * CFG802.11 network device handler for open. |
459 | * | 417 | * |
460 | * Starts the data queue. | 418 | * Starts the data queue. |
@@ -488,17 +446,23 @@ mwifiex_close(struct net_device *dev) | |||
488 | */ | 446 | */ |
489 | int mwifiex_queue_tx_pkt(struct mwifiex_private *priv, struct sk_buff *skb) | 447 | int mwifiex_queue_tx_pkt(struct mwifiex_private *priv, struct sk_buff *skb) |
490 | { | 448 | { |
491 | mwifiex_wmm_add_buf_txqueue(priv, skb); | 449 | struct netdev_queue *txq; |
450 | int index = mwifiex_1d_to_wmm_queue[skb->priority]; | ||
451 | |||
452 | if (atomic_inc_return(&priv->wmm_tx_pending[index]) >= MAX_TX_PENDING) { | ||
453 | txq = netdev_get_tx_queue(priv->netdev, index); | ||
454 | if (!netif_tx_queue_stopped(txq)) { | ||
455 | netif_tx_stop_queue(txq); | ||
456 | dev_dbg(priv->adapter->dev, "stop queue: %d\n", index); | ||
457 | } | ||
458 | } | ||
459 | |||
492 | atomic_inc(&priv->adapter->tx_pending); | 460 | atomic_inc(&priv->adapter->tx_pending); |
461 | mwifiex_wmm_add_buf_txqueue(priv, skb); | ||
493 | 462 | ||
494 | if (priv->adapter->scan_delay_cnt) | 463 | if (priv->adapter->scan_delay_cnt) |
495 | atomic_set(&priv->adapter->is_tx_received, true); | 464 | atomic_set(&priv->adapter->is_tx_received, true); |
496 | 465 | ||
497 | if (atomic_read(&priv->adapter->tx_pending) >= MAX_TX_PENDING) { | ||
498 | mwifiex_set_trans_start(priv->netdev); | ||
499 | mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter); | ||
500 | } | ||
501 | |||
502 | queue_work(priv->adapter->workqueue, &priv->adapter->main_work); | 466 | queue_work(priv->adapter->workqueue, &priv->adapter->main_work); |
503 | 467 | ||
504 | return 0; | 468 | return 0; |
@@ -513,6 +477,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
513 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); | 477 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); |
514 | struct sk_buff *new_skb; | 478 | struct sk_buff *new_skb; |
515 | struct mwifiex_txinfo *tx_info; | 479 | struct mwifiex_txinfo *tx_info; |
480 | struct timeval tv; | ||
516 | 481 | ||
517 | dev_dbg(priv->adapter->dev, "data: %lu BSS(%d-%d): Data <= kernel\n", | 482 | dev_dbg(priv->adapter->dev, "data: %lu BSS(%d-%d): Data <= kernel\n", |
518 | jiffies, priv->bss_type, priv->bss_num); | 483 | jiffies, priv->bss_type, priv->bss_num); |
@@ -550,7 +515,16 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
550 | tx_info = MWIFIEX_SKB_TXCB(skb); | 515 | tx_info = MWIFIEX_SKB_TXCB(skb); |
551 | tx_info->bss_num = priv->bss_num; | 516 | tx_info->bss_num = priv->bss_num; |
552 | tx_info->bss_type = priv->bss_type; | 517 | tx_info->bss_type = priv->bss_type; |
553 | mwifiex_fill_buffer(skb); | 518 | |
519 | /* Record the current time the packet was queued; used to | ||
520 | * determine the amount of time the packet was queued in | ||
521 | * the driver before it was sent to the firmware. | ||
522 | * The delay is then sent along with the packet to the | ||
523 | * firmware for aggregate delay calculation for stats and | ||
524 | * MSDU lifetime expiry. | ||
525 | */ | ||
526 | do_gettimeofday(&tv); | ||
527 | skb->tstamp = timeval_to_ktime(tv); | ||
554 | 528 | ||
555 | mwifiex_queue_tx_pkt(priv, skb); | 529 | mwifiex_queue_tx_pkt(priv, skb); |
556 | 530 | ||
@@ -630,6 +604,13 @@ static struct net_device_stats *mwifiex_get_stats(struct net_device *dev) | |||
630 | return &priv->stats; | 604 | return &priv->stats; |
631 | } | 605 | } |
632 | 606 | ||
607 | static u16 | ||
608 | mwifiex_netdev_select_wmm_queue(struct net_device *dev, struct sk_buff *skb) | ||
609 | { | ||
610 | skb->priority = cfg80211_classify8021d(skb); | ||
611 | return mwifiex_1d_to_wmm_queue[skb->priority]; | ||
612 | } | ||
613 | |||
633 | /* Network device handlers */ | 614 | /* Network device handlers */ |
634 | static const struct net_device_ops mwifiex_netdev_ops = { | 615 | static const struct net_device_ops mwifiex_netdev_ops = { |
635 | .ndo_open = mwifiex_open, | 616 | .ndo_open = mwifiex_open, |
@@ -639,6 +620,7 @@ static const struct net_device_ops mwifiex_netdev_ops = { | |||
639 | .ndo_tx_timeout = mwifiex_tx_timeout, | 620 | .ndo_tx_timeout = mwifiex_tx_timeout, |
640 | .ndo_get_stats = mwifiex_get_stats, | 621 | .ndo_get_stats = mwifiex_get_stats, |
641 | .ndo_set_rx_mode = mwifiex_set_multicast_list, | 622 | .ndo_set_rx_mode = mwifiex_set_multicast_list, |
623 | .ndo_select_queue = mwifiex_netdev_select_wmm_queue, | ||
642 | }; | 624 | }; |
643 | 625 | ||
644 | /* | 626 | /* |
@@ -838,9 +820,7 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem) | |||
838 | for (i = 0; i < adapter->priv_num; i++) { | 820 | for (i = 0; i < adapter->priv_num; i++) { |
839 | priv = adapter->priv[i]; | 821 | priv = adapter->priv[i]; |
840 | if (priv && priv->netdev) { | 822 | if (priv && priv->netdev) { |
841 | if (!netif_queue_stopped(priv->netdev)) | 823 | mwifiex_stop_net_dev_queue(priv->netdev, adapter); |
842 | mwifiex_stop_net_dev_queue(priv->netdev, | ||
843 | adapter); | ||
844 | if (netif_carrier_ok(priv->netdev)) | 824 | if (netif_carrier_ok(priv->netdev)) |
845 | netif_carrier_off(priv->netdev); | 825 | netif_carrier_off(priv->netdev); |
846 | } | 826 | } |
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 81f8772dcb07..1b3cfc821940 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h | |||
@@ -371,7 +371,6 @@ struct wps { | |||
371 | struct mwifiex_roc_cfg { | 371 | struct mwifiex_roc_cfg { |
372 | u64 cookie; | 372 | u64 cookie; |
373 | struct ieee80211_channel chan; | 373 | struct ieee80211_channel chan; |
374 | enum nl80211_channel_type chan_type; | ||
375 | }; | 374 | }; |
376 | 375 | ||
377 | struct mwifiex_adapter; | 376 | struct mwifiex_adapter; |
@@ -440,6 +439,7 @@ struct mwifiex_private { | |||
440 | u8 wmm_enabled; | 439 | u8 wmm_enabled; |
441 | u8 wmm_qosinfo; | 440 | u8 wmm_qosinfo; |
442 | struct mwifiex_wmm_desc wmm; | 441 | struct mwifiex_wmm_desc wmm; |
442 | atomic_t wmm_tx_pending[IEEE80211_NUM_ACS]; | ||
443 | struct list_head sta_list; | 443 | struct list_head sta_list; |
444 | /* spin lock for associated station list */ | 444 | /* spin lock for associated station list */ |
445 | spinlock_t sta_list_spinlock; | 445 | spinlock_t sta_list_spinlock; |
@@ -600,6 +600,7 @@ struct mwifiex_if_ops { | |||
600 | int (*event_complete) (struct mwifiex_adapter *, struct sk_buff *); | 600 | int (*event_complete) (struct mwifiex_adapter *, struct sk_buff *); |
601 | int (*data_complete) (struct mwifiex_adapter *, struct sk_buff *); | 601 | int (*data_complete) (struct mwifiex_adapter *, struct sk_buff *); |
602 | int (*dnld_fw) (struct mwifiex_adapter *, struct mwifiex_fw_image *); | 602 | int (*dnld_fw) (struct mwifiex_adapter *, struct mwifiex_fw_image *); |
603 | void (*card_reset) (struct mwifiex_adapter *); | ||
603 | }; | 604 | }; |
604 | 605 | ||
605 | struct mwifiex_adapter { | 606 | struct mwifiex_adapter { |
@@ -788,7 +789,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, | |||
788 | struct mwifiex_tx_param *tx_param); | 789 | struct mwifiex_tx_param *tx_param); |
789 | int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags); | 790 | int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags); |
790 | int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, | 791 | int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, |
791 | struct sk_buff *skb, int status); | 792 | struct sk_buff *skb, int aggr, int status); |
792 | void mwifiex_clean_txrx(struct mwifiex_private *priv); | 793 | void mwifiex_clean_txrx(struct mwifiex_private *priv); |
793 | u8 mwifiex_check_last_packet_indication(struct mwifiex_private *priv); | 794 | u8 mwifiex_check_last_packet_indication(struct mwifiex_private *priv); |
794 | void mwifiex_check_ps_cond(struct mwifiex_adapter *adapter); | 795 | void mwifiex_check_ps_cond(struct mwifiex_adapter *adapter); |
@@ -1016,7 +1017,6 @@ int mwifiex_get_ver_ext(struct mwifiex_private *priv); | |||
1016 | 1017 | ||
1017 | int mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action, | 1018 | int mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action, |
1018 | struct ieee80211_channel *chan, | 1019 | struct ieee80211_channel *chan, |
1019 | enum nl80211_channel_type *channel_type, | ||
1020 | unsigned int duration); | 1020 | unsigned int duration); |
1021 | 1021 | ||
1022 | int mwifiex_set_bss_role(struct mwifiex_private *priv, u8 bss_role); | 1022 | int mwifiex_set_bss_role(struct mwifiex_private *priv, u8 bss_role); |
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index 82cf0fa2d9f6..5a1c1d0e5599 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c | |||
@@ -906,8 +906,8 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter) | |||
906 | /* | 906 | /* |
907 | * SDIO interrupt handler. | 907 | * SDIO interrupt handler. |
908 | * | 908 | * |
909 | * This function reads the interrupt status from firmware and assigns | 909 | * This function reads the interrupt status from firmware and handles |
910 | * the main process in workqueue which will handle the interrupt. | 910 | * the interrupt in current thread (ksdioirqd) right away. |
911 | */ | 911 | */ |
912 | static void | 912 | static void |
913 | mwifiex_sdio_interrupt(struct sdio_func *func) | 913 | mwifiex_sdio_interrupt(struct sdio_func *func) |
@@ -930,7 +930,7 @@ mwifiex_sdio_interrupt(struct sdio_func *func) | |||
930 | adapter->ps_state = PS_STATE_AWAKE; | 930 | adapter->ps_state = PS_STATE_AWAKE; |
931 | 931 | ||
932 | mwifiex_interrupt_status(adapter); | 932 | mwifiex_interrupt_status(adapter); |
933 | queue_work(adapter->workqueue, &adapter->main_work); | 933 | mwifiex_main_process(adapter); |
934 | } | 934 | } |
935 | 935 | ||
936 | /* | 936 | /* |
@@ -1749,6 +1749,37 @@ mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port) | |||
1749 | port, card->mp_data_port_mask); | 1749 | port, card->mp_data_port_mask); |
1750 | } | 1750 | } |
1751 | 1751 | ||
1752 | static struct mmc_host *reset_host; | ||
1753 | static void sdio_card_reset_worker(struct work_struct *work) | ||
1754 | { | ||
1755 | /* The actual reset operation must be run outside of driver thread. | ||
1756 | * This is because mmc_remove_host() will cause the device to be | ||
1757 | * instantly destroyed, and the driver then needs to end its thread, | ||
1758 | * leading to a deadlock. | ||
1759 | * | ||
1760 | * We run it in a totally independent workqueue. | ||
1761 | */ | ||
1762 | |||
1763 | pr_err("Resetting card...\n"); | ||
1764 | mmc_remove_host(reset_host); | ||
1765 | /* 20ms delay is based on experiment with sdhci controller */ | ||
1766 | mdelay(20); | ||
1767 | mmc_add_host(reset_host); | ||
1768 | } | ||
1769 | static DECLARE_WORK(card_reset_work, sdio_card_reset_worker); | ||
1770 | |||
1771 | /* This function resets the card */ | ||
1772 | static void mwifiex_sdio_card_reset(struct mwifiex_adapter *adapter) | ||
1773 | { | ||
1774 | struct sdio_mmc_card *card = adapter->card; | ||
1775 | |||
1776 | if (work_pending(&card_reset_work)) | ||
1777 | return; | ||
1778 | |||
1779 | reset_host = card->func->card->host; | ||
1780 | schedule_work(&card_reset_work); | ||
1781 | } | ||
1782 | |||
1752 | static struct mwifiex_if_ops sdio_ops = { | 1783 | static struct mwifiex_if_ops sdio_ops = { |
1753 | .init_if = mwifiex_init_sdio, | 1784 | .init_if = mwifiex_init_sdio, |
1754 | .cleanup_if = mwifiex_cleanup_sdio, | 1785 | .cleanup_if = mwifiex_cleanup_sdio, |
@@ -1767,6 +1798,7 @@ static struct mwifiex_if_ops sdio_ops = { | |||
1767 | .cleanup_mpa_buf = mwifiex_cleanup_mpa_buf, | 1798 | .cleanup_mpa_buf = mwifiex_cleanup_mpa_buf, |
1768 | .cmdrsp_complete = mwifiex_sdio_cmdrsp_complete, | 1799 | .cmdrsp_complete = mwifiex_sdio_cmdrsp_complete, |
1769 | .event_complete = mwifiex_sdio_event_complete, | 1800 | .event_complete = mwifiex_sdio_event_complete, |
1801 | .card_reset = mwifiex_sdio_card_reset, | ||
1770 | }; | 1802 | }; |
1771 | 1803 | ||
1772 | /* | 1804 | /* |
@@ -1804,6 +1836,7 @@ mwifiex_sdio_cleanup_module(void) | |||
1804 | /* Set the flag as user is removing this module. */ | 1836 | /* Set the flag as user is removing this module. */ |
1805 | user_rmmod = 1; | 1837 | user_rmmod = 1; |
1806 | 1838 | ||
1839 | cancel_work_sync(&card_reset_work); | ||
1807 | sdio_unregister_driver(&mwifiex_sdio); | 1840 | sdio_unregister_driver(&mwifiex_sdio); |
1808 | } | 1841 | } |
1809 | 1842 | ||
diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h index 21033738ef0c..8cc5468654b4 100644 --- a/drivers/net/wireless/mwifiex/sdio.h +++ b/drivers/net/wireless/mwifiex/sdio.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/mmc/sdio_ids.h> | 25 | #include <linux/mmc/sdio_ids.h> |
26 | #include <linux/mmc/sdio_func.h> | 26 | #include <linux/mmc/sdio_func.h> |
27 | #include <linux/mmc/card.h> | 27 | #include <linux/mmc/card.h> |
28 | #include <linux/mmc/host.h> | ||
28 | 29 | ||
29 | #include "main.h" | 30 | #include "main.h" |
30 | 31 | ||
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c index 8132119e1a21..41aafc7454ed 100644 --- a/drivers/net/wireless/mwifiex/sta_event.c +++ b/drivers/net/wireless/mwifiex/sta_event.c | |||
@@ -124,8 +124,7 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code) | |||
124 | } | 124 | } |
125 | memset(priv->cfg_bssid, 0, ETH_ALEN); | 125 | memset(priv->cfg_bssid, 0, ETH_ALEN); |
126 | 126 | ||
127 | if (!netif_queue_stopped(priv->netdev)) | 127 | mwifiex_stop_net_dev_queue(priv->netdev, adapter); |
128 | mwifiex_stop_net_dev_queue(priv->netdev, adapter); | ||
129 | if (netif_carrier_ok(priv->netdev)) | 128 | if (netif_carrier_ok(priv->netdev)) |
130 | netif_carrier_off(priv->netdev); | 129 | netif_carrier_off(priv->netdev); |
131 | } | 130 | } |
@@ -197,8 +196,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) | |||
197 | dev_dbg(adapter->dev, "event: LINK_SENSED\n"); | 196 | dev_dbg(adapter->dev, "event: LINK_SENSED\n"); |
198 | if (!netif_carrier_ok(priv->netdev)) | 197 | if (!netif_carrier_ok(priv->netdev)) |
199 | netif_carrier_on(priv->netdev); | 198 | netif_carrier_on(priv->netdev); |
200 | if (netif_queue_stopped(priv->netdev)) | 199 | mwifiex_wake_up_net_dev_queue(priv->netdev, adapter); |
201 | mwifiex_wake_up_net_dev_queue(priv->netdev, adapter); | ||
202 | break; | 200 | break; |
203 | 201 | ||
204 | case EVENT_DEAUTHENTICATED: | 202 | case EVENT_DEAUTHENTICATED: |
@@ -306,8 +304,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) | |||
306 | dev_dbg(adapter->dev, "event: ADHOC_BCN_LOST\n"); | 304 | dev_dbg(adapter->dev, "event: ADHOC_BCN_LOST\n"); |
307 | priv->adhoc_is_link_sensed = false; | 305 | priv->adhoc_is_link_sensed = false; |
308 | mwifiex_clean_txrx(priv); | 306 | mwifiex_clean_txrx(priv); |
309 | if (!netif_queue_stopped(priv->netdev)) | 307 | mwifiex_stop_net_dev_queue(priv->netdev, adapter); |
310 | mwifiex_stop_net_dev_queue(priv->netdev, adapter); | ||
311 | if (netif_carrier_ok(priv->netdev)) | 308 | if (netif_carrier_ok(priv->netdev)) |
312 | netif_carrier_off(priv->netdev); | 309 | netif_carrier_off(priv->netdev); |
313 | break; | 310 | break; |
@@ -424,7 +421,6 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) | |||
424 | cfg80211_remain_on_channel_expired(priv->wdev, | 421 | cfg80211_remain_on_channel_expired(priv->wdev, |
425 | priv->roc_cfg.cookie, | 422 | priv->roc_cfg.cookie, |
426 | &priv->roc_cfg.chan, | 423 | &priv->roc_cfg.chan, |
427 | priv->roc_cfg.chan_type, | ||
428 | GFP_ATOMIC); | 424 | GFP_ATOMIC); |
429 | 425 | ||
430 | memset(&priv->roc_cfg, 0x00, sizeof(struct mwifiex_roc_cfg)); | 426 | memset(&priv->roc_cfg, 0x00, sizeof(struct mwifiex_roc_cfg)); |
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 552d72ed055a..237c8d2ba9f2 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c | |||
@@ -276,8 +276,7 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, | |||
276 | dev_dbg(adapter->dev, "info: SSID found in scan list ... " | 276 | dev_dbg(adapter->dev, "info: SSID found in scan list ... " |
277 | "associating...\n"); | 277 | "associating...\n"); |
278 | 278 | ||
279 | if (!netif_queue_stopped(priv->netdev)) | 279 | mwifiex_stop_net_dev_queue(priv->netdev, adapter); |
280 | mwifiex_stop_net_dev_queue(priv->netdev, adapter); | ||
281 | if (netif_carrier_ok(priv->netdev)) | 280 | if (netif_carrier_ok(priv->netdev)) |
282 | netif_carrier_off(priv->netdev); | 281 | netif_carrier_off(priv->netdev); |
283 | 282 | ||
@@ -318,8 +317,7 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, | |||
318 | 317 | ||
319 | ret = mwifiex_check_network_compatibility(priv, bss_desc); | 318 | ret = mwifiex_check_network_compatibility(priv, bss_desc); |
320 | 319 | ||
321 | if (!netif_queue_stopped(priv->netdev)) | 320 | mwifiex_stop_net_dev_queue(priv->netdev, adapter); |
322 | mwifiex_stop_net_dev_queue(priv->netdev, adapter); | ||
323 | if (netif_carrier_ok(priv->netdev)) | 321 | if (netif_carrier_ok(priv->netdev)) |
324 | netif_carrier_off(priv->netdev); | 322 | netif_carrier_off(priv->netdev); |
325 | 323 | ||
@@ -1046,7 +1044,6 @@ mwifiex_get_ver_ext(struct mwifiex_private *priv) | |||
1046 | int | 1044 | int |
1047 | mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action, | 1045 | mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action, |
1048 | struct ieee80211_channel *chan, | 1046 | struct ieee80211_channel *chan, |
1049 | enum nl80211_channel_type *ct, | ||
1050 | unsigned int duration) | 1047 | unsigned int duration) |
1051 | { | 1048 | { |
1052 | struct host_cmd_ds_remain_on_chan roc_cfg; | 1049 | struct host_cmd_ds_remain_on_chan roc_cfg; |
@@ -1056,7 +1053,7 @@ mwifiex_remain_on_chan_cfg(struct mwifiex_private *priv, u16 action, | |||
1056 | roc_cfg.action = cpu_to_le16(action); | 1053 | roc_cfg.action = cpu_to_le16(action); |
1057 | if (action == HostCmd_ACT_GEN_SET) { | 1054 | if (action == HostCmd_ACT_GEN_SET) { |
1058 | roc_cfg.band_cfg = chan->band; | 1055 | roc_cfg.band_cfg = chan->band; |
1059 | sc = mwifiex_chan_type_to_sec_chan_offset(*ct); | 1056 | sc = mwifiex_chan_type_to_sec_chan_offset(NL80211_CHAN_NO_HT); |
1060 | roc_cfg.band_cfg |= (sc << 2); | 1057 | roc_cfg.band_cfg |= (sc << 2); |
1061 | 1058 | ||
1062 | roc_cfg.channel = | 1059 | roc_cfg.channel = |
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c index 5cb3f7af8749..8c80024c30ff 100644 --- a/drivers/net/wireless/mwifiex/txrx.c +++ b/drivers/net/wireless/mwifiex/txrx.c | |||
@@ -121,13 +121,13 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, | |||
121 | dev_err(adapter->dev, "mwifiex_write_data_async failed: 0x%X\n", | 121 | dev_err(adapter->dev, "mwifiex_write_data_async failed: 0x%X\n", |
122 | ret); | 122 | ret); |
123 | adapter->dbg.num_tx_host_to_card_failure++; | 123 | adapter->dbg.num_tx_host_to_card_failure++; |
124 | mwifiex_write_data_complete(adapter, skb, ret); | 124 | mwifiex_write_data_complete(adapter, skb, 0, ret); |
125 | break; | 125 | break; |
126 | case -EINPROGRESS: | 126 | case -EINPROGRESS: |
127 | adapter->data_sent = false; | 127 | adapter->data_sent = false; |
128 | break; | 128 | break; |
129 | case 0: | 129 | case 0: |
130 | mwifiex_write_data_complete(adapter, skb, ret); | 130 | mwifiex_write_data_complete(adapter, skb, 0, ret); |
131 | break; | 131 | break; |
132 | default: | 132 | default: |
133 | break; | 133 | break; |
@@ -144,11 +144,12 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, | |||
144 | * wakes up stalled traffic queue if required, and then frees the buffer. | 144 | * wakes up stalled traffic queue if required, and then frees the buffer. |
145 | */ | 145 | */ |
146 | int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, | 146 | int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, |
147 | struct sk_buff *skb, int status) | 147 | struct sk_buff *skb, int aggr, int status) |
148 | { | 148 | { |
149 | struct mwifiex_private *priv, *tpriv; | 149 | struct mwifiex_private *priv; |
150 | struct mwifiex_txinfo *tx_info; | 150 | struct mwifiex_txinfo *tx_info; |
151 | int i; | 151 | struct netdev_queue *txq; |
152 | int index; | ||
152 | 153 | ||
153 | if (!skb) | 154 | if (!skb) |
154 | return 0; | 155 | return 0; |
@@ -172,15 +173,20 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, | |||
172 | 173 | ||
173 | if (tx_info->flags & MWIFIEX_BUF_FLAG_BRIDGED_PKT) | 174 | if (tx_info->flags & MWIFIEX_BUF_FLAG_BRIDGED_PKT) |
174 | atomic_dec_return(&adapter->pending_bridged_pkts); | 175 | atomic_dec_return(&adapter->pending_bridged_pkts); |
175 | if (atomic_dec_return(&adapter->tx_pending) >= LOW_TX_PENDING) | 176 | |
177 | if (aggr) | ||
178 | /* For skb_aggr, do not wake up tx queue */ | ||
176 | goto done; | 179 | goto done; |
177 | 180 | ||
178 | for (i = 0; i < adapter->priv_num; i++) { | 181 | atomic_dec(&adapter->tx_pending); |
179 | tpriv = adapter->priv[i]; | ||
180 | 182 | ||
181 | if (tpriv->media_connected && | 183 | index = mwifiex_1d_to_wmm_queue[skb->priority]; |
182 | netif_queue_stopped(tpriv->netdev)) | 184 | if (atomic_dec_return(&priv->wmm_tx_pending[index]) < LOW_TX_PENDING) { |
183 | mwifiex_wake_up_net_dev_queue(tpriv->netdev, adapter); | 185 | txq = netdev_get_tx_queue(priv->netdev, index); |
186 | if (netif_tx_queue_stopped(txq)) { | ||
187 | netif_tx_wake_queue(txq); | ||
188 | dev_dbg(adapter->dev, "wake queue: %d\n", index); | ||
189 | } | ||
184 | } | 190 | } |
185 | done: | 191 | done: |
186 | dev_kfree_skb_any(skb); | 192 | dev_kfree_skb_any(skb); |
diff --git a/drivers/net/wireless/mwifiex/uap_event.c b/drivers/net/wireless/mwifiex/uap_event.c index a33fa394e349..21c640d3b579 100644 --- a/drivers/net/wireless/mwifiex/uap_event.c +++ b/drivers/net/wireless/mwifiex/uap_event.c | |||
@@ -235,11 +235,18 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv) | |||
235 | break; | 235 | break; |
236 | case EVENT_UAP_BSS_IDLE: | 236 | case EVENT_UAP_BSS_IDLE: |
237 | priv->media_connected = false; | 237 | priv->media_connected = false; |
238 | if (netif_carrier_ok(priv->netdev)) | ||
239 | netif_carrier_off(priv->netdev); | ||
240 | mwifiex_stop_net_dev_queue(priv->netdev, adapter); | ||
241 | |||
238 | mwifiex_clean_txrx(priv); | 242 | mwifiex_clean_txrx(priv); |
239 | mwifiex_del_all_sta_list(priv); | 243 | mwifiex_del_all_sta_list(priv); |
240 | break; | 244 | break; |
241 | case EVENT_UAP_BSS_ACTIVE: | 245 | case EVENT_UAP_BSS_ACTIVE: |
242 | priv->media_connected = true; | 246 | priv->media_connected = true; |
247 | if (!netif_carrier_ok(priv->netdev)) | ||
248 | netif_carrier_on(priv->netdev); | ||
249 | mwifiex_wake_up_net_dev_queue(priv->netdev, adapter); | ||
243 | break; | 250 | break; |
244 | case EVENT_UAP_BSS_START: | 251 | case EVENT_UAP_BSS_START: |
245 | dev_dbg(adapter->dev, "AP EVENT: event id: %#x\n", eventcause); | 252 | dev_dbg(adapter->dev, "AP EVENT: event id: %#x\n", eventcause); |
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c index 22a5916564b8..bbe1f3518e4b 100644 --- a/drivers/net/wireless/mwifiex/usb.c +++ b/drivers/net/wireless/mwifiex/usb.c | |||
@@ -238,7 +238,7 @@ static void mwifiex_usb_tx_complete(struct urb *urb) | |||
238 | } else { | 238 | } else { |
239 | dev_dbg(adapter->dev, "%s: DATA\n", __func__); | 239 | dev_dbg(adapter->dev, "%s: DATA\n", __func__); |
240 | atomic_dec(&card->tx_data_urb_pending); | 240 | atomic_dec(&card->tx_data_urb_pending); |
241 | mwifiex_write_data_complete(adapter, context->skb, | 241 | mwifiex_write_data_complete(adapter, context->skb, 0, |
242 | urb->status ? -1 : 0); | 242 | urb->status ? -1 : 0); |
243 | } | 243 | } |
244 | 244 | ||
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 600d8194610e..818f871ae987 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c | |||
@@ -483,7 +483,7 @@ mwifiex_wmm_del_pkts_in_ralist_node(struct mwifiex_private *priv, | |||
483 | struct sk_buff *skb, *tmp; | 483 | struct sk_buff *skb, *tmp; |
484 | 484 | ||
485 | skb_queue_walk_safe(&ra_list->skb_head, skb, tmp) | 485 | skb_queue_walk_safe(&ra_list->skb_head, skb, tmp) |
486 | mwifiex_write_data_complete(adapter, skb, -1); | 486 | mwifiex_write_data_complete(adapter, skb, 0, -1); |
487 | } | 487 | } |
488 | 488 | ||
489 | /* | 489 | /* |
@@ -650,7 +650,7 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv, | |||
650 | 650 | ||
651 | if (!priv->media_connected && !mwifiex_is_skb_mgmt_frame(skb)) { | 651 | if (!priv->media_connected && !mwifiex_is_skb_mgmt_frame(skb)) { |
652 | dev_dbg(adapter->dev, "data: drop packet in disconnect\n"); | 652 | dev_dbg(adapter->dev, "data: drop packet in disconnect\n"); |
653 | mwifiex_write_data_complete(adapter, skb, -1); | 653 | mwifiex_write_data_complete(adapter, skb, 0, -1); |
654 | return; | 654 | return; |
655 | } | 655 | } |
656 | 656 | ||
@@ -680,7 +680,7 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv, | |||
680 | 680 | ||
681 | if (!ra_list) { | 681 | if (!ra_list) { |
682 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); | 682 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); |
683 | mwifiex_write_data_complete(adapter, skb, -1); | 683 | mwifiex_write_data_complete(adapter, skb, 0, -1); |
684 | return; | 684 | return; |
685 | } | 685 | } |
686 | 686 | ||
@@ -1090,7 +1090,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv, | |||
1090 | if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) { | 1090 | if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) { |
1091 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, | 1091 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, |
1092 | ra_list_flags); | 1092 | ra_list_flags); |
1093 | mwifiex_write_data_complete(adapter, skb, -1); | 1093 | mwifiex_write_data_complete(adapter, skb, 0, -1); |
1094 | return; | 1094 | return; |
1095 | } | 1095 | } |
1096 | 1096 | ||
@@ -1195,7 +1195,7 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv, | |||
1195 | if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) { | 1195 | if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) { |
1196 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, | 1196 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, |
1197 | ra_list_flags); | 1197 | ra_list_flags); |
1198 | mwifiex_write_data_complete(adapter, skb, -1); | 1198 | mwifiex_write_data_complete(adapter, skb, 0, -1); |
1199 | return; | 1199 | return; |
1200 | } | 1200 | } |
1201 | 1201 | ||
@@ -1209,7 +1209,7 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv, | |||
1209 | adapter->data_sent = false; | 1209 | adapter->data_sent = false; |
1210 | dev_err(adapter->dev, "host_to_card failed: %#x\n", ret); | 1210 | dev_err(adapter->dev, "host_to_card failed: %#x\n", ret); |
1211 | adapter->dbg.num_tx_host_to_card_failure++; | 1211 | adapter->dbg.num_tx_host_to_card_failure++; |
1212 | mwifiex_write_data_complete(adapter, skb, ret); | 1212 | mwifiex_write_data_complete(adapter, skb, 0, ret); |
1213 | break; | 1213 | break; |
1214 | case -EINPROGRESS: | 1214 | case -EINPROGRESS: |
1215 | adapter->data_sent = false; | 1215 | adapter->data_sent = false; |
diff --git a/drivers/net/wireless/mwifiex/wmm.h b/drivers/net/wireless/mwifiex/wmm.h index ec839952d2e7..b92f39d8963b 100644 --- a/drivers/net/wireless/mwifiex/wmm.h +++ b/drivers/net/wireless/mwifiex/wmm.h | |||
@@ -31,6 +31,8 @@ enum ieee_types_wmm_ecw_bitmasks { | |||
31 | MWIFIEX_ECW_MAX = (BIT(4) | BIT(5) | BIT(6) | BIT(7)), | 31 | MWIFIEX_ECW_MAX = (BIT(4) | BIT(5) | BIT(6) | BIT(7)), |
32 | }; | 32 | }; |
33 | 33 | ||
34 | static const u16 mwifiex_1d_to_wmm_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 }; | ||
35 | |||
34 | /* | 36 | /* |
35 | * This function retrieves the TID of the given RA list. | 37 | * This function retrieves the TID of the given RA list. |
36 | */ | 38 | */ |
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index 5099e5375cb3..0cdae6632735 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c | |||
@@ -1851,6 +1851,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, | |||
1851 | bool start_ba_session = false; | 1851 | bool start_ba_session = false; |
1852 | bool mgmtframe = false; | 1852 | bool mgmtframe = false; |
1853 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; | 1853 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; |
1854 | bool eapol_frame = false; | ||
1854 | 1855 | ||
1855 | wh = (struct ieee80211_hdr *)skb->data; | 1856 | wh = (struct ieee80211_hdr *)skb->data; |
1856 | if (ieee80211_is_data_qos(wh->frame_control)) | 1857 | if (ieee80211_is_data_qos(wh->frame_control)) |
@@ -1858,6 +1859,9 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, | |||
1858 | else | 1859 | else |
1859 | qos = 0; | 1860 | qos = 0; |
1860 | 1861 | ||
1862 | if (skb->protocol == cpu_to_be16(ETH_P_PAE)) | ||
1863 | eapol_frame = true; | ||
1864 | |||
1861 | if (ieee80211_is_mgmt(wh->frame_control)) | 1865 | if (ieee80211_is_mgmt(wh->frame_control)) |
1862 | mgmtframe = true; | 1866 | mgmtframe = true; |
1863 | 1867 | ||
@@ -1916,9 +1920,8 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, | |||
1916 | 1920 | ||
1917 | txpriority = index; | 1921 | txpriority = index; |
1918 | 1922 | ||
1919 | if (priv->ap_fw && sta && sta->ht_cap.ht_supported | 1923 | if (priv->ap_fw && sta && sta->ht_cap.ht_supported && !eapol_frame && |
1920 | && skb->protocol != cpu_to_be16(ETH_P_PAE) | 1924 | ieee80211_is_data_qos(wh->frame_control)) { |
1921 | && ieee80211_is_data_qos(wh->frame_control)) { | ||
1922 | tid = qos & 0xf; | 1925 | tid = qos & 0xf; |
1923 | mwl8k_tx_count_packet(sta, tid); | 1926 | mwl8k_tx_count_packet(sta, tid); |
1924 | spin_lock(&priv->stream_lock); | 1927 | spin_lock(&priv->stream_lock); |
@@ -2005,6 +2008,8 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, | |||
2005 | spin_unlock(&priv->stream_lock); | 2008 | spin_unlock(&priv->stream_lock); |
2006 | } | 2009 | } |
2007 | spin_unlock_bh(&priv->tx_lock); | 2010 | spin_unlock_bh(&priv->tx_lock); |
2011 | pci_unmap_single(priv->pdev, dma, skb->len, | ||
2012 | PCI_DMA_TODEVICE); | ||
2008 | dev_kfree_skb(skb); | 2013 | dev_kfree_skb(skb); |
2009 | return; | 2014 | return; |
2010 | } | 2015 | } |
@@ -2025,9 +2030,11 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, | |||
2025 | else | 2030 | else |
2026 | tx->peer_id = 0; | 2031 | tx->peer_id = 0; |
2027 | 2032 | ||
2028 | if (priv->ap_fw) | 2033 | if (priv->ap_fw && ieee80211_is_data(wh->frame_control) && !eapol_frame) |
2029 | tx->timestamp = cpu_to_le32(ioread32(priv->regs + | 2034 | tx->timestamp = cpu_to_le32(ioread32(priv->regs + |
2030 | MWL8K_HW_TIMER_REGISTER)); | 2035 | MWL8K_HW_TIMER_REGISTER)); |
2036 | else | ||
2037 | tx->timestamp = 0; | ||
2031 | 2038 | ||
2032 | wmb(); | 2039 | wmb(); |
2033 | tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus); | 2040 | tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus); |
@@ -3679,7 +3686,8 @@ struct mwl8k_cmd_bastream { | |||
3679 | } __packed; | 3686 | } __packed; |
3680 | 3687 | ||
3681 | static int | 3688 | static int |
3682 | mwl8k_check_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream) | 3689 | mwl8k_check_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream, |
3690 | struct ieee80211_vif *vif) | ||
3683 | { | 3691 | { |
3684 | struct mwl8k_cmd_bastream *cmd; | 3692 | struct mwl8k_cmd_bastream *cmd; |
3685 | int rc; | 3693 | int rc; |
@@ -3702,7 +3710,7 @@ mwl8k_check_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream) | |||
3702 | cpu_to_le32(BASTREAM_FLAG_IMMEDIATE_TYPE) | | 3710 | cpu_to_le32(BASTREAM_FLAG_IMMEDIATE_TYPE) | |
3703 | cpu_to_le32(BASTREAM_FLAG_DIRECTION_UPSTREAM); | 3711 | cpu_to_le32(BASTREAM_FLAG_DIRECTION_UPSTREAM); |
3704 | 3712 | ||
3705 | rc = mwl8k_post_cmd(hw, &cmd->header); | 3713 | rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); |
3706 | 3714 | ||
3707 | kfree(cmd); | 3715 | kfree(cmd); |
3708 | 3716 | ||
@@ -3711,7 +3719,7 @@ mwl8k_check_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream) | |||
3711 | 3719 | ||
3712 | static int | 3720 | static int |
3713 | mwl8k_create_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream, | 3721 | mwl8k_create_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream, |
3714 | u8 buf_size) | 3722 | u8 buf_size, struct ieee80211_vif *vif) |
3715 | { | 3723 | { |
3716 | struct mwl8k_cmd_bastream *cmd; | 3724 | struct mwl8k_cmd_bastream *cmd; |
3717 | int rc; | 3725 | int rc; |
@@ -3745,7 +3753,7 @@ mwl8k_create_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream, | |||
3745 | cpu_to_le32(BASTREAM_FLAG_IMMEDIATE_TYPE | | 3753 | cpu_to_le32(BASTREAM_FLAG_IMMEDIATE_TYPE | |
3746 | BASTREAM_FLAG_DIRECTION_UPSTREAM); | 3754 | BASTREAM_FLAG_DIRECTION_UPSTREAM); |
3747 | 3755 | ||
3748 | rc = mwl8k_post_cmd(hw, &cmd->header); | 3756 | rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); |
3749 | 3757 | ||
3750 | wiphy_debug(hw->wiphy, "Created a BA stream for %pM : tid %d\n", | 3758 | wiphy_debug(hw->wiphy, "Created a BA stream for %pM : tid %d\n", |
3751 | stream->sta->addr, stream->tid); | 3759 | stream->sta->addr, stream->tid); |
@@ -5085,6 +5093,7 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
5085 | struct mwl8k_priv *priv = hw->priv; | 5093 | struct mwl8k_priv *priv = hw->priv; |
5086 | struct mwl8k_ampdu_stream *stream; | 5094 | struct mwl8k_ampdu_stream *stream; |
5087 | u8 *addr = sta->addr; | 5095 | u8 *addr = sta->addr; |
5096 | struct mwl8k_sta *sta_info = MWL8K_STA(sta); | ||
5088 | 5097 | ||
5089 | if (!(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION)) | 5098 | if (!(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION)) |
5090 | return -ENOTSUPP; | 5099 | return -ENOTSUPP; |
@@ -5127,7 +5136,16 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
5127 | /* Release the lock before we do the time consuming stuff */ | 5136 | /* Release the lock before we do the time consuming stuff */ |
5128 | spin_unlock(&priv->stream_lock); | 5137 | spin_unlock(&priv->stream_lock); |
5129 | for (i = 0; i < MAX_AMPDU_ATTEMPTS; i++) { | 5138 | for (i = 0; i < MAX_AMPDU_ATTEMPTS; i++) { |
5130 | rc = mwl8k_check_ba(hw, stream); | 5139 | |
5140 | /* Check if link is still valid */ | ||
5141 | if (!sta_info->is_ampdu_allowed) { | ||
5142 | spin_lock(&priv->stream_lock); | ||
5143 | mwl8k_remove_stream(hw, stream); | ||
5144 | spin_unlock(&priv->stream_lock); | ||
5145 | return -EBUSY; | ||
5146 | } | ||
5147 | |||
5148 | rc = mwl8k_check_ba(hw, stream, vif); | ||
5131 | 5149 | ||
5132 | /* If HW restart is in progress mwl8k_post_cmd will | 5150 | /* If HW restart is in progress mwl8k_post_cmd will |
5133 | * return -EBUSY. Avoid retrying mwl8k_check_ba in | 5151 | * return -EBUSY. Avoid retrying mwl8k_check_ba in |
@@ -5167,7 +5185,7 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
5167 | BUG_ON(stream == NULL); | 5185 | BUG_ON(stream == NULL); |
5168 | BUG_ON(stream->state != AMPDU_STREAM_IN_PROGRESS); | 5186 | BUG_ON(stream->state != AMPDU_STREAM_IN_PROGRESS); |
5169 | spin_unlock(&priv->stream_lock); | 5187 | spin_unlock(&priv->stream_lock); |
5170 | rc = mwl8k_create_ba(hw, stream, buf_size); | 5188 | rc = mwl8k_create_ba(hw, stream, buf_size, vif); |
5171 | spin_lock(&priv->stream_lock); | 5189 | spin_lock(&priv->stream_lock); |
5172 | if (!rc) | 5190 | if (!rc) |
5173 | stream->state = AMPDU_STREAM_ACTIVE; | 5191 | stream->state = AMPDU_STREAM_ACTIVE; |
@@ -5617,6 +5635,18 @@ fail: | |||
5617 | return rc; | 5635 | return rc; |
5618 | } | 5636 | } |
5619 | 5637 | ||
5638 | static const struct ieee80211_iface_limit ap_if_limits[] = { | ||
5639 | { .max = 8, .types = BIT(NL80211_IFTYPE_AP) }, | ||
5640 | }; | ||
5641 | |||
5642 | static const struct ieee80211_iface_combination ap_if_comb = { | ||
5643 | .limits = ap_if_limits, | ||
5644 | .n_limits = ARRAY_SIZE(ap_if_limits), | ||
5645 | .max_interfaces = 8, | ||
5646 | .num_different_channels = 1, | ||
5647 | }; | ||
5648 | |||
5649 | |||
5620 | static int mwl8k_firmware_load_success(struct mwl8k_priv *priv) | 5650 | static int mwl8k_firmware_load_success(struct mwl8k_priv *priv) |
5621 | { | 5651 | { |
5622 | struct ieee80211_hw *hw = priv->hw; | 5652 | struct ieee80211_hw *hw = priv->hw; |
@@ -5696,8 +5726,13 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv) | |||
5696 | goto err_free_cookie; | 5726 | goto err_free_cookie; |
5697 | 5727 | ||
5698 | hw->wiphy->interface_modes = 0; | 5728 | hw->wiphy->interface_modes = 0; |
5699 | if (priv->ap_macids_supported || priv->device_info->fw_image_ap) | 5729 | |
5730 | if (priv->ap_macids_supported || priv->device_info->fw_image_ap) { | ||
5700 | hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP); | 5731 | hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP); |
5732 | hw->wiphy->iface_combinations = &ap_if_comb; | ||
5733 | hw->wiphy->n_iface_combinations = 1; | ||
5734 | } | ||
5735 | |||
5701 | if (priv->sta_macids_supported || priv->device_info->fw_image_sta) | 5736 | if (priv->sta_macids_supported || priv->device_info->fw_image_sta) |
5702 | hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION); | 5737 | hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION); |
5703 | 5738 | ||
diff --git a/drivers/net/wireless/orinoco/cfg.c b/drivers/net/wireless/orinoco/cfg.c index 7b751fba7e1f..d01edd2c50c5 100644 --- a/drivers/net/wireless/orinoco/cfg.c +++ b/drivers/net/wireless/orinoco/cfg.c | |||
@@ -161,24 +161,23 @@ static int orinoco_scan(struct wiphy *wiphy, | |||
161 | } | 161 | } |
162 | 162 | ||
163 | static int orinoco_set_monitor_channel(struct wiphy *wiphy, | 163 | static int orinoco_set_monitor_channel(struct wiphy *wiphy, |
164 | struct ieee80211_channel *chan, | 164 | struct cfg80211_chan_def *chandef) |
165 | enum nl80211_channel_type channel_type) | ||
166 | { | 165 | { |
167 | struct orinoco_private *priv = wiphy_priv(wiphy); | 166 | struct orinoco_private *priv = wiphy_priv(wiphy); |
168 | int err = 0; | 167 | int err = 0; |
169 | unsigned long flags; | 168 | unsigned long flags; |
170 | int channel; | 169 | int channel; |
171 | 170 | ||
172 | if (!chan) | 171 | if (!chandef->chan) |
173 | return -EINVAL; | 172 | return -EINVAL; |
174 | 173 | ||
175 | if (channel_type != NL80211_CHAN_NO_HT) | 174 | if (cfg80211_get_chandef_type(chandef) != NL80211_CHAN_NO_HT) |
176 | return -EINVAL; | 175 | return -EINVAL; |
177 | 176 | ||
178 | if (chan->band != IEEE80211_BAND_2GHZ) | 177 | if (chandef->chan->band != IEEE80211_BAND_2GHZ) |
179 | return -EINVAL; | 178 | return -EINVAL; |
180 | 179 | ||
181 | channel = ieee80211_freq_to_dsss_chan(chan->center_freq); | 180 | channel = ieee80211_freq_to_dsss_chan(chandef->chan->center_freq); |
182 | 181 | ||
183 | if ((channel < 1) || (channel > NUM_CHANNELS) || | 182 | if ((channel < 1) || (channel > NUM_CHANNELS) || |
184 | !(priv->channel_mask & (1 << (channel - 1)))) | 183 | !(priv->channel_mask & (1 << (channel - 1)))) |
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c index 5861e13a6fd8..12f0a34477f2 100644 --- a/drivers/net/wireless/p54/txrx.c +++ b/drivers/net/wireless/p54/txrx.c | |||
@@ -369,7 +369,11 @@ static int p54_rx_data(struct p54_common *priv, struct sk_buff *skb) | |||
369 | rx_status->mactime = ((u64)priv->tsf_high32) << 32 | tsf32; | 369 | rx_status->mactime = ((u64)priv->tsf_high32) << 32 | tsf32; |
370 | priv->tsf_low32 = tsf32; | 370 | priv->tsf_low32 = tsf32; |
371 | 371 | ||
372 | rx_status->flag |= RX_FLAG_MACTIME_MPDU; | 372 | /* LMAC API Page 10/29 - s_lm_data_in - clock |
373 | * "usec accurate timestamp of hardware clock | ||
374 | * at end of frame (before OFDM SIFS EOF padding" | ||
375 | */ | ||
376 | rx_status->flag |= RX_FLAG_MACTIME_END; | ||
373 | 377 | ||
374 | if (hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_ALIGN)) | 378 | if (hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_ALIGN)) |
375 | header_len += hdr->align[0]; | 379 | header_len += hdr->align[0]; |
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index bd1f0cb56085..abe1d039be81 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
@@ -490,9 +490,12 @@ static int rndis_scan(struct wiphy *wiphy, | |||
490 | static int rndis_set_wiphy_params(struct wiphy *wiphy, u32 changed); | 490 | static int rndis_set_wiphy_params(struct wiphy *wiphy, u32 changed); |
491 | 491 | ||
492 | static int rndis_set_tx_power(struct wiphy *wiphy, | 492 | static int rndis_set_tx_power(struct wiphy *wiphy, |
493 | struct wireless_dev *wdev, | ||
493 | enum nl80211_tx_power_setting type, | 494 | enum nl80211_tx_power_setting type, |
494 | int mbm); | 495 | int mbm); |
495 | static int rndis_get_tx_power(struct wiphy *wiphy, int *dbm); | 496 | static int rndis_get_tx_power(struct wiphy *wiphy, |
497 | struct wireless_dev *wdev, | ||
498 | int *dbm); | ||
496 | 499 | ||
497 | static int rndis_connect(struct wiphy *wiphy, struct net_device *dev, | 500 | static int rndis_connect(struct wiphy *wiphy, struct net_device *dev, |
498 | struct cfg80211_connect_params *sme); | 501 | struct cfg80211_connect_params *sme); |
@@ -1903,6 +1906,7 @@ static int rndis_set_wiphy_params(struct wiphy *wiphy, u32 changed) | |||
1903 | } | 1906 | } |
1904 | 1907 | ||
1905 | static int rndis_set_tx_power(struct wiphy *wiphy, | 1908 | static int rndis_set_tx_power(struct wiphy *wiphy, |
1909 | struct wireless_dev *wdev, | ||
1906 | enum nl80211_tx_power_setting type, | 1910 | enum nl80211_tx_power_setting type, |
1907 | int mbm) | 1911 | int mbm) |
1908 | { | 1912 | { |
@@ -1930,7 +1934,9 @@ static int rndis_set_tx_power(struct wiphy *wiphy, | |||
1930 | return -ENOTSUPP; | 1934 | return -ENOTSUPP; |
1931 | } | 1935 | } |
1932 | 1936 | ||
1933 | static int rndis_get_tx_power(struct wiphy *wiphy, int *dbm) | 1937 | static int rndis_get_tx_power(struct wiphy *wiphy, |
1938 | struct wireless_dev *wdev, | ||
1939 | int *dbm) | ||
1934 | { | 1940 | { |
1935 | struct rndis_wlan_private *priv = wiphy_priv(wiphy); | 1941 | struct rndis_wlan_private *priv = wiphy_priv(wiphy); |
1936 | struct usbnet *usbdev = priv->usbdev; | 1942 | struct usbnet *usbdev = priv->usbdev; |
@@ -2287,7 +2293,7 @@ static int rndis_join_ibss(struct wiphy *wiphy, struct net_device *dev, | |||
2287 | { | 2293 | { |
2288 | struct rndis_wlan_private *priv = wiphy_priv(wiphy); | 2294 | struct rndis_wlan_private *priv = wiphy_priv(wiphy); |
2289 | struct usbnet *usbdev = priv->usbdev; | 2295 | struct usbnet *usbdev = priv->usbdev; |
2290 | struct ieee80211_channel *channel = params->channel; | 2296 | struct ieee80211_channel *channel = params->chandef.chan; |
2291 | struct ndis_80211_ssid ssid; | 2297 | struct ndis_80211_ssid ssid; |
2292 | enum nl80211_auth_type auth_type; | 2298 | enum nl80211_auth_type auth_type; |
2293 | int ret, alg, length, chan = -1; | 2299 | int ret, alg, length, chan = -1; |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 3b8fb5a603f2..023081286e0c 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -1096,6 +1096,7 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
1096 | { USB_DEVICE(0x177f, 0x0153) }, | 1096 | { USB_DEVICE(0x177f, 0x0153) }, |
1097 | { USB_DEVICE(0x177f, 0x0302) }, | 1097 | { USB_DEVICE(0x177f, 0x0302) }, |
1098 | { USB_DEVICE(0x177f, 0x0313) }, | 1098 | { USB_DEVICE(0x177f, 0x0313) }, |
1099 | { USB_DEVICE(0x177f, 0x0323) }, | ||
1099 | /* U-Media */ | 1100 | /* U-Media */ |
1100 | { USB_DEVICE(0x157e, 0x300e) }, | 1101 | { USB_DEVICE(0x157e, 0x300e) }, |
1101 | { USB_DEVICE(0x157e, 0x3013) }, | 1102 | { USB_DEVICE(0x157e, 0x3013) }, |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 69097d1faeb6..67d167993d45 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -157,6 +157,7 @@ static void rt2x00lib_intf_scheduled(struct work_struct *work) | |||
157 | * requested configurations. | 157 | * requested configurations. |
158 | */ | 158 | */ |
159 | ieee80211_iterate_active_interfaces(rt2x00dev->hw, | 159 | ieee80211_iterate_active_interfaces(rt2x00dev->hw, |
160 | IEEE80211_IFACE_ITER_RESUME_ALL, | ||
160 | rt2x00lib_intf_scheduled_iter, | 161 | rt2x00lib_intf_scheduled_iter, |
161 | rt2x00dev); | 162 | rt2x00dev); |
162 | } | 163 | } |
@@ -225,9 +226,9 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) | |||
225 | return; | 226 | return; |
226 | 227 | ||
227 | /* send buffered bc/mc frames out for every bssid */ | 228 | /* send buffered bc/mc frames out for every bssid */ |
228 | ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw, | 229 | ieee80211_iterate_active_interfaces_atomic( |
229 | rt2x00lib_bc_buffer_iter, | 230 | rt2x00dev->hw, IEEE80211_IFACE_ITER_RESUME_ALL, |
230 | rt2x00dev); | 231 | rt2x00lib_bc_buffer_iter, rt2x00dev); |
231 | /* | 232 | /* |
232 | * Devices with pre tbtt interrupt don't need to update the beacon | 233 | * Devices with pre tbtt interrupt don't need to update the beacon |
233 | * here as they will fetch the next beacon directly prior to | 234 | * here as they will fetch the next beacon directly prior to |
@@ -237,9 +238,9 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) | |||
237 | return; | 238 | return; |
238 | 239 | ||
239 | /* fetch next beacon */ | 240 | /* fetch next beacon */ |
240 | ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw, | 241 | ieee80211_iterate_active_interfaces_atomic( |
241 | rt2x00lib_beaconupdate_iter, | 242 | rt2x00dev->hw, IEEE80211_IFACE_ITER_RESUME_ALL, |
242 | rt2x00dev); | 243 | rt2x00lib_beaconupdate_iter, rt2x00dev); |
243 | } | 244 | } |
244 | EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); | 245 | EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); |
245 | 246 | ||
@@ -249,9 +250,9 @@ void rt2x00lib_pretbtt(struct rt2x00_dev *rt2x00dev) | |||
249 | return; | 250 | return; |
250 | 251 | ||
251 | /* fetch next beacon */ | 252 | /* fetch next beacon */ |
252 | ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw, | 253 | ieee80211_iterate_active_interfaces_atomic( |
253 | rt2x00lib_beaconupdate_iter, | 254 | rt2x00dev->hw, IEEE80211_IFACE_ITER_RESUME_ALL, |
254 | rt2x00dev); | 255 | rt2x00lib_beaconupdate_iter, rt2x00dev); |
255 | } | 256 | } |
256 | EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt); | 257 | EXPORT_SYMBOL_GPL(rt2x00lib_pretbtt); |
257 | 258 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 98a9e48f8e4a..ed7a1bb3f245 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -424,9 +424,9 @@ int rt2x00mac_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, | |||
424 | if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) | 424 | if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) |
425 | return 0; | 425 | return 0; |
426 | 426 | ||
427 | ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw, | 427 | ieee80211_iterate_active_interfaces_atomic( |
428 | rt2x00mac_set_tim_iter, | 428 | rt2x00dev->hw, IEEE80211_IFACE_ITER_RESUME_ALL, |
429 | rt2x00dev); | 429 | rt2x00mac_set_tim_iter, rt2x00dev); |
430 | 430 | ||
431 | /* queue work to upodate the beacon template */ | 431 | /* queue work to upodate the beacon template */ |
432 | ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->intf_work); | 432 | ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->intf_work); |
diff --git a/drivers/net/wireless/rtl818x/rtl8180/dev.c b/drivers/net/wireless/rtl818x/rtl8180/dev.c index 021d83e1b1d3..b4218a5f2066 100644 --- a/drivers/net/wireless/rtl818x/rtl8180/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180/dev.c | |||
@@ -150,7 +150,7 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) | |||
150 | rx_status.freq = dev->conf.channel->center_freq; | 150 | rx_status.freq = dev->conf.channel->center_freq; |
151 | rx_status.band = dev->conf.channel->band; | 151 | rx_status.band = dev->conf.channel->band; |
152 | rx_status.mactime = le64_to_cpu(entry->tsft); | 152 | rx_status.mactime = le64_to_cpu(entry->tsft); |
153 | rx_status.flag |= RX_FLAG_MACTIME_MPDU; | 153 | rx_status.flag |= RX_FLAG_MACTIME_START; |
154 | if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR) | 154 | if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR) |
155 | rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; | 155 | rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; |
156 | 156 | ||
diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c index 7811b6315973..52e6bebcf089 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c | |||
@@ -381,7 +381,7 @@ static void rtl8187_rx_cb(struct urb *urb) | |||
381 | rx_status.rate_idx = rate; | 381 | rx_status.rate_idx = rate; |
382 | rx_status.freq = dev->conf.channel->center_freq; | 382 | rx_status.freq = dev->conf.channel->center_freq; |
383 | rx_status.band = dev->conf.channel->band; | 383 | rx_status.band = dev->conf.channel->band; |
384 | rx_status.flag |= RX_FLAG_MACTIME_MPDU; | 384 | rx_status.flag |= RX_FLAG_MACTIME_START; |
385 | if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR) | 385 | if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR) |
386 | rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; | 386 | rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; |
387 | memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); | 387 | memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); |
diff --git a/drivers/net/wireless/rtlwifi/Kconfig b/drivers/net/wireless/rtlwifi/Kconfig index 6b28e92d1d21..21b1bbb93a7e 100644 --- a/drivers/net/wireless/rtlwifi/Kconfig +++ b/drivers/net/wireless/rtlwifi/Kconfig | |||
@@ -32,6 +32,17 @@ config RTL8192DE | |||
32 | 32 | ||
33 | If you choose to build it as a module, it will be called rtl8192de | 33 | If you choose to build it as a module, it will be called rtl8192de |
34 | 34 | ||
35 | config RTL8723AE | ||
36 | tristate "Realtek RTL8723AE PCIe Wireless Network Adapter" | ||
37 | depends on MAC80211 && PCI && EXPERIMENTAL | ||
38 | select FW_LOADER | ||
39 | select RTLWIFI | ||
40 | ---help--- | ||
41 | This is the driver for Realtek RTL8723AE 802.11n PCIe | ||
42 | wireless network adapters. | ||
43 | |||
44 | If you choose to build it as a module, it will be called rtl8723ae | ||
45 | |||
35 | config RTL8192CU | 46 | config RTL8192CU |
36 | tristate "Realtek RTL8192CU/RTL8188CU USB Wireless Network Adapter" | 47 | tristate "Realtek RTL8192CU/RTL8188CU USB Wireless Network Adapter" |
37 | depends on MAC80211 && USB | 48 | depends on MAC80211 && USB |
diff --git a/drivers/net/wireless/rtlwifi/Makefile b/drivers/net/wireless/rtlwifi/Makefile index 97935c565bab..3b1cbac741e3 100644 --- a/drivers/net/wireless/rtlwifi/Makefile +++ b/drivers/net/wireless/rtlwifi/Makefile | |||
@@ -7,7 +7,8 @@ rtlwifi-objs := \ | |||
7 | efuse.o \ | 7 | efuse.o \ |
8 | ps.o \ | 8 | ps.o \ |
9 | rc.o \ | 9 | rc.o \ |
10 | regd.o | 10 | regd.o \ |
11 | stats.o | ||
11 | 12 | ||
12 | rtl8192c_common-objs += \ | 13 | rtl8192c_common-objs += \ |
13 | 14 | ||
@@ -24,5 +25,6 @@ obj-$(CONFIG_RTL8192CE) += rtl8192ce/ | |||
24 | obj-$(CONFIG_RTL8192CU) += rtl8192cu/ | 25 | obj-$(CONFIG_RTL8192CU) += rtl8192cu/ |
25 | obj-$(CONFIG_RTL8192SE) += rtl8192se/ | 26 | obj-$(CONFIG_RTL8192SE) += rtl8192se/ |
26 | obj-$(CONFIG_RTL8192DE) += rtl8192de/ | 27 | obj-$(CONFIG_RTL8192DE) += rtl8192de/ |
28 | obj-$(CONFIG_RTL8723AE) += rtl8723ae/ | ||
27 | 29 | ||
28 | ccflags-y += -D__CHECK_ENDIAN__ | 30 | ccflags-y += -D__CHECK_ENDIAN__ |
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index 59381fe8ed06..4494d130b37c 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c | |||
@@ -826,6 +826,30 @@ int rtlwifi_rate_mapping(struct ieee80211_hw *hw, | |||
826 | } | 826 | } |
827 | EXPORT_SYMBOL(rtlwifi_rate_mapping); | 827 | EXPORT_SYMBOL(rtlwifi_rate_mapping); |
828 | 828 | ||
829 | bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
830 | { | ||
831 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
832 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
833 | __le16 fc = rtl_get_fc(skb); | ||
834 | |||
835 | if (rtlpriv->dm.supp_phymode_switch && | ||
836 | mac->link_state < MAC80211_LINKED && | ||
837 | (ieee80211_is_auth(fc) || ieee80211_is_probe_req(fc))) { | ||
838 | if (rtlpriv->cfg->ops->check_switch_to_dmdp) | ||
839 | rtlpriv->cfg->ops->check_switch_to_dmdp(hw); | ||
840 | } | ||
841 | if (ieee80211_is_auth(fc)) { | ||
842 | RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); | ||
843 | rtl_ips_nic_on(hw); | ||
844 | |||
845 | mac->link_state = MAC80211_LINKING; | ||
846 | /* Dual mac */ | ||
847 | rtlpriv->phy.need_iqk = true; | ||
848 | } | ||
849 | |||
850 | return true; | ||
851 | } | ||
852 | |||
829 | void rtl_get_tcb_desc(struct ieee80211_hw *hw, | 853 | void rtl_get_tcb_desc(struct ieee80211_hw *hw, |
830 | struct ieee80211_tx_info *info, | 854 | struct ieee80211_tx_info *info, |
831 | struct ieee80211_sta *sta, | 855 | struct ieee80211_sta *sta, |
diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/rtlwifi/base.h index f35af0fdaaf0..5a8c80e259f7 100644 --- a/drivers/net/wireless/rtlwifi/base.h +++ b/drivers/net/wireless/rtlwifi/base.h | |||
@@ -142,4 +142,6 @@ u8 rtl_tid_to_ac(u8 tid); | |||
142 | extern struct attribute_group rtl_attribute_group; | 142 | extern struct attribute_group rtl_attribute_group; |
143 | int rtlwifi_rate_mapping(struct ieee80211_hw *hw, | 143 | int rtlwifi_rate_mapping(struct ieee80211_hw *hw, |
144 | bool isht, u8 desc_rate, bool first_ampdu); | 144 | bool isht, u8 desc_rate, bool first_ampdu); |
145 | bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb); | ||
146 | |||
145 | #endif | 147 | #endif |
diff --git a/drivers/net/wireless/rtlwifi/cam.c b/drivers/net/wireless/rtlwifi/cam.c index ca69e35e50f1..0e510f73041a 100644 --- a/drivers/net/wireless/rtlwifi/cam.c +++ b/drivers/net/wireless/rtlwifi/cam.c | |||
@@ -337,7 +337,7 @@ void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr) | |||
337 | if (((bitmap & BIT(0)) == BIT(0)) && | 337 | if (((bitmap & BIT(0)) == BIT(0)) && |
338 | (memcmp(addr, sta_addr, ETH_ALEN) == 0)) { | 338 | (memcmp(addr, sta_addr, ETH_ALEN) == 0)) { |
339 | /* Remove from HW Security CAM */ | 339 | /* Remove from HW Security CAM */ |
340 | memset(rtlpriv->sec.hwsec_cam_sta_addr[i], 0, ETH_ALEN); | 340 | eth_zero_addr(rtlpriv->sec.hwsec_cam_sta_addr[i]); |
341 | rtlpriv->sec.hwsec_cam_bitmap &= ~(BIT(0) << i); | 341 | rtlpriv->sec.hwsec_cam_bitmap &= ~(BIT(0) << i); |
342 | RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, | 342 | RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, |
343 | "del CAM entry %d\n", i); | 343 | "del CAM entry %d\n", i); |
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index a7c0e52869ba..be33aa14c8af 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c | |||
@@ -962,7 +962,6 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
962 | int err = 0; | 962 | int err = 0; |
963 | u8 mac_addr[ETH_ALEN]; | 963 | u8 mac_addr[ETH_ALEN]; |
964 | u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; | 964 | u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; |
965 | u8 zero_addr[ETH_ALEN] = { 0 }; | ||
966 | 965 | ||
967 | if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { | 966 | if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { |
968 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | 967 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, |
@@ -1057,7 +1056,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
1057 | memcpy(rtlpriv->sec.key_buf[key_idx], | 1056 | memcpy(rtlpriv->sec.key_buf[key_idx], |
1058 | key->key, key->keylen); | 1057 | key->key, key->keylen); |
1059 | rtlpriv->sec.key_len[key_idx] = key->keylen; | 1058 | rtlpriv->sec.key_len[key_idx] = key->keylen; |
1060 | memcpy(mac_addr, zero_addr, ETH_ALEN); | 1059 | eth_zero_addr(mac_addr); |
1061 | } else if (group_key) { /* group key */ | 1060 | } else if (group_key) { /* group key */ |
1062 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | 1061 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, |
1063 | "set group key\n"); | 1062 | "set group key\n"); |
@@ -1108,7 +1107,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
1108 | } | 1107 | } |
1109 | memset(rtlpriv->sec.key_buf[key_idx], 0, key->keylen); | 1108 | memset(rtlpriv->sec.key_buf[key_idx], 0, key->keylen); |
1110 | rtlpriv->sec.key_len[key_idx] = 0; | 1109 | rtlpriv->sec.key_len[key_idx] = 0; |
1111 | memcpy(mac_addr, zero_addr, ETH_ALEN); | 1110 | eth_zero_addr(mac_addr); |
1112 | /* | 1111 | /* |
1113 | *mac80211 will delete entrys one by one, | 1112 | *mac80211 will delete entrys one by one, |
1114 | *so don't use rtl_cam_reset_all_entry | 1113 | *so don't use rtl_cam_reset_all_entry |
diff --git a/drivers/net/wireless/rtlwifi/debug.h b/drivers/net/wireless/rtlwifi/debug.h index 07493d2957f2..fd3269f47685 100644 --- a/drivers/net/wireless/rtlwifi/debug.h +++ b/drivers/net/wireless/rtlwifi/debug.h | |||
@@ -106,6 +106,8 @@ | |||
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 | #define COMP_USB BIT(29) |
109 | #define COMP_EASY_CONCURRENT COMP_USB /* reuse of this bit is OK */ | ||
110 | #define COMP_BT_COEXIST BIT(30) | ||
109 | 111 | ||
110 | /*-------------------------------------------------------------- | 112 | /*-------------------------------------------------------------- |
111 | Define the rt_print components | 113 | Define the rt_print components |
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index abc306b502ac..f38e30a947bc 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c | |||
@@ -1309,6 +1309,7 @@ static bool rtl_pci_tx_chk_waitq_insert(struct ieee80211_hw *hw, | |||
1309 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1309 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
1310 | struct rtl_sta_info *sta_entry = NULL; | 1310 | struct rtl_sta_info *sta_entry = NULL; |
1311 | u8 tid = rtl_get_tid(skb); | 1311 | u8 tid = rtl_get_tid(skb); |
1312 | __le16 fc = rtl_get_fc(skb); | ||
1312 | 1313 | ||
1313 | if (!sta) | 1314 | if (!sta) |
1314 | return false; | 1315 | return false; |
@@ -1316,6 +1317,12 @@ static bool rtl_pci_tx_chk_waitq_insert(struct ieee80211_hw *hw, | |||
1316 | 1317 | ||
1317 | if (!rtlpriv->rtlhal.earlymode_enable) | 1318 | if (!rtlpriv->rtlhal.earlymode_enable) |
1318 | return false; | 1319 | return false; |
1320 | if (ieee80211_is_nullfunc(fc)) | ||
1321 | return false; | ||
1322 | if (ieee80211_is_qos_nullfunc(fc)) | ||
1323 | return false; | ||
1324 | if (ieee80211_is_pspoll(fc)) | ||
1325 | return false; | ||
1319 | if (sta_entry->tids[tid].agg.agg_state != RTL_AGG_OPERATIONAL) | 1326 | if (sta_entry->tids[tid].agg.agg_state != RTL_AGG_OPERATIONAL) |
1320 | return false; | 1327 | return false; |
1321 | if (_rtl_mac_to_hwqueue(hw, skb) > VO_QUEUE) | 1328 | if (_rtl_mac_to_hwqueue(hw, skb) > VO_QUEUE) |
@@ -1357,10 +1364,8 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, | |||
1357 | u8 own; | 1364 | u8 own; |
1358 | u8 temp_one = 1; | 1365 | u8 temp_one = 1; |
1359 | 1366 | ||
1360 | if (ieee80211_is_auth(fc)) { | 1367 | if (ieee80211_is_mgmt(fc)) |
1361 | RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); | 1368 | rtl_tx_mgmt_proc(hw, skb); |
1362 | rtl_ips_nic_on(hw); | ||
1363 | } | ||
1364 | 1369 | ||
1365 | if (rtlpriv->psc.sw_ps_enabled) { | 1370 | if (rtlpriv->psc.sw_ps_enabled) { |
1366 | if (ieee80211_is_data(fc) && !ieee80211_is_nullfunc(fc) && | 1371 | if (ieee80211_is_data(fc) && !ieee80211_is_nullfunc(fc) && |
@@ -1628,7 +1633,7 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, | |||
1628 | "8192 PCI-E is found - vid/did=%x/%x\n", | 1633 | "8192 PCI-E is found - vid/did=%x/%x\n", |
1629 | venderid, deviceid); | 1634 | venderid, deviceid); |
1630 | rtlhal->hw_type = HARDWARE_TYPE_RTL8192E; | 1635 | rtlhal->hw_type = HARDWARE_TYPE_RTL8192E; |
1631 | break; | 1636 | return false; |
1632 | case RTL_PCI_REVISION_ID_8192SE: | 1637 | case RTL_PCI_REVISION_ID_8192SE: |
1633 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | 1638 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, |
1634 | "8192SE is found - vid/did=%x/%x\n", | 1639 | "8192SE is found - vid/did=%x/%x\n", |
@@ -1643,6 +1648,11 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, | |||
1643 | break; | 1648 | break; |
1644 | 1649 | ||
1645 | } | 1650 | } |
1651 | } else if (deviceid == RTL_PCI_8723AE_DID) { | ||
1652 | rtlhal->hw_type = HARDWARE_TYPE_RTL8723AE; | ||
1653 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
1654 | "8723AE PCI-E is found - " | ||
1655 | "vid/did=%x/%x\n", venderid, deviceid); | ||
1646 | } else if (deviceid == RTL_PCI_8192CET_DID || | 1656 | } else if (deviceid == RTL_PCI_8192CET_DID || |
1647 | deviceid == RTL_PCI_8192CE_DID || | 1657 | deviceid == RTL_PCI_8192CE_DID || |
1648 | deviceid == RTL_PCI_8191CE_DID || | 1658 | deviceid == RTL_PCI_8191CE_DID || |
diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h index 241448fc9ed5..f71b12aa8cb4 100644 --- a/drivers/net/wireless/rtlwifi/pci.h +++ b/drivers/net/wireless/rtlwifi/pci.h | |||
@@ -79,6 +79,7 @@ | |||
79 | #define RTL_PCI_8173_DID 0x8173 /*8191 SE Crab */ | 79 | #define RTL_PCI_8173_DID 0x8173 /*8191 SE Crab */ |
80 | #define RTL_PCI_8172_DID 0x8172 /*8191 SE RE */ | 80 | #define RTL_PCI_8172_DID 0x8172 /*8191 SE RE */ |
81 | #define RTL_PCI_8171_DID 0x8171 /*8191 SE Unicron */ | 81 | #define RTL_PCI_8171_DID 0x8171 /*8191 SE Unicron */ |
82 | #define RTL_PCI_8723AE_DID 0x8723 /*8723AE */ | ||
82 | #define RTL_PCI_0045_DID 0x0045 /*8190 PCI for Ceraga */ | 83 | #define RTL_PCI_0045_DID 0x0045 /*8190 PCI for Ceraga */ |
83 | #define RTL_PCI_0046_DID 0x0046 /*8190 Cardbus for Ceraga */ | 84 | #define RTL_PCI_0046_DID 0x0046 /*8190 Cardbus for Ceraga */ |
84 | #define RTL_PCI_0044_DID 0x0044 /*8192e PCIE for Ceraga */ | 85 | #define RTL_PCI_0044_DID 0x0044 /*8192e PCIE for Ceraga */ |
@@ -152,6 +153,7 @@ struct rtl8192_rx_ring { | |||
152 | 153 | ||
153 | struct rtl_pci { | 154 | struct rtl_pci { |
154 | struct pci_dev *pdev; | 155 | struct pci_dev *pdev; |
156 | bool irq_enabled; | ||
155 | 157 | ||
156 | bool driver_is_goingto_unload; | 158 | bool driver_is_goingto_unload; |
157 | bool up_first_time; | 159 | bool up_first_time; |
diff --git a/drivers/net/wireless/rtlwifi/rc.c b/drivers/net/wireless/rtlwifi/rc.c index d5cbf01da8ac..c1e065f136ba 100644 --- a/drivers/net/wireless/rtlwifi/rc.c +++ b/drivers/net/wireless/rtlwifi/rc.c | |||
@@ -55,7 +55,8 @@ static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv, | |||
55 | * 1M we will not use FW rate but user rate. | 55 | * 1M we will not use FW rate but user rate. |
56 | */ | 56 | */ |
57 | if (rtlmac->opmode == NL80211_IFTYPE_AP || | 57 | if (rtlmac->opmode == NL80211_IFTYPE_AP || |
58 | rtlmac->opmode == NL80211_IFTYPE_ADHOC) { | 58 | rtlmac->opmode == NL80211_IFTYPE_ADHOC || |
59 | rtlmac->opmode == NL80211_IFTYPE_MESH_POINT) { | ||
59 | if (sta) { | 60 | if (sta) { |
60 | sta_entry = (struct rtl_sta_info *) sta->drv_priv; | 61 | sta_entry = (struct rtl_sta_info *) sta->drv_priv; |
61 | wireless_mode = sta_entry->wireless_mode; | 62 | wireless_mode = sta_entry->wireless_mode; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index d7e1f0a7e48f..173424756149 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | |||
@@ -559,7 +559,7 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw, | |||
559 | if (GET_RX_DESC_RXHT(pdesc)) | 559 | if (GET_RX_DESC_RXHT(pdesc)) |
560 | rx_status->flag |= RX_FLAG_HT; | 560 | rx_status->flag |= RX_FLAG_HT; |
561 | 561 | ||
562 | rx_status->flag |= RX_FLAG_MACTIME_MPDU; | 562 | rx_status->flag |= RX_FLAG_MACTIME_START; |
563 | 563 | ||
564 | if (stats->decrypted) | 564 | if (stats->decrypted) |
565 | rx_status->flag |= RX_FLAG_DECRYPTED; | 565 | rx_status->flag |= RX_FLAG_DECRYPTED; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index 6e66f04c363f..b6222eedb835 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | |||
@@ -334,7 +334,7 @@ bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw, | |||
334 | rx_status->flag |= RX_FLAG_40MHZ; | 334 | rx_status->flag |= RX_FLAG_40MHZ; |
335 | if (GET_RX_DESC_RX_HT(pdesc)) | 335 | if (GET_RX_DESC_RX_HT(pdesc)) |
336 | rx_status->flag |= RX_FLAG_HT; | 336 | rx_status->flag |= RX_FLAG_HT; |
337 | rx_status->flag |= RX_FLAG_MACTIME_MPDU; | 337 | rx_status->flag |= RX_FLAG_MACTIME_START; |
338 | if (stats->decrypted) | 338 | if (stats->decrypted) |
339 | rx_status->flag |= RX_FLAG_DECRYPTED; | 339 | rx_status->flag |= RX_FLAG_DECRYPTED; |
340 | rx_status->rate_idx = rtlwifi_rate_mapping(hw, | 340 | rx_status->rate_idx = rtlwifi_rate_mapping(hw, |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c index 35bb9da6196a..f9f3861046c1 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c | |||
@@ -509,7 +509,7 @@ bool rtl92de_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats, | |||
509 | rx_status->flag |= RX_FLAG_40MHZ; | 509 | rx_status->flag |= RX_FLAG_40MHZ; |
510 | if (GET_RX_DESC_RXHT(pdesc)) | 510 | if (GET_RX_DESC_RXHT(pdesc)) |
511 | rx_status->flag |= RX_FLAG_HT; | 511 | rx_status->flag |= RX_FLAG_HT; |
512 | rx_status->flag |= RX_FLAG_MACTIME_MPDU; | 512 | rx_status->flag |= RX_FLAG_MACTIME_START; |
513 | if (stats->decrypted) | 513 | if (stats->decrypted) |
514 | rx_status->flag |= RX_FLAG_DECRYPTED; | 514 | rx_status->flag |= RX_FLAG_DECRYPTED; |
515 | rx_status->rate_idx = rtlwifi_rate_mapping(hw, | 515 | rx_status->rate_idx = rtlwifi_rate_mapping(hw, |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c index 1ad51e711a32..0e9f6ebf078a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c | |||
@@ -553,7 +553,7 @@ bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats, | |||
553 | if (stats->is_ht) | 553 | if (stats->is_ht) |
554 | rx_status->flag |= RX_FLAG_HT; | 554 | rx_status->flag |= RX_FLAG_HT; |
555 | 555 | ||
556 | rx_status->flag |= RX_FLAG_MACTIME_MPDU; | 556 | rx_status->flag |= RX_FLAG_MACTIME_START; |
557 | 557 | ||
558 | /* hw will set stats->decrypted true, if it finds the | 558 | /* hw will set stats->decrypted true, if it finds the |
559 | * frame is open data frame or mgmt frame, | 559 | * frame is open data frame or mgmt frame, |
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/Makefile b/drivers/net/wireless/rtlwifi/rtl8723ae/Makefile new file mode 100644 index 000000000000..4ed731f09b1f --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/Makefile | |||
@@ -0,0 +1,22 @@ | |||
1 | obj-m := rtl8723ae.o | ||
2 | |||
3 | |||
4 | rtl8723ae-objs := \ | ||
5 | dm.o \ | ||
6 | fw.o \ | ||
7 | hal_btc.o \ | ||
8 | hal_bt_coexist.o\ | ||
9 | hw.o \ | ||
10 | led.o \ | ||
11 | phy.o \ | ||
12 | pwrseq.o \ | ||
13 | pwrseqcmd.o \ | ||
14 | rf.o \ | ||
15 | sw.o \ | ||
16 | table.o \ | ||
17 | trx.o \ | ||
18 | |||
19 | |||
20 | obj-$(CONFIG_RTL8723AE) += rtl8723ae.o | ||
21 | |||
22 | ccflags-y += -D__CHECK_ENDIAN__ | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/btc.h b/drivers/net/wireless/rtlwifi/rtl8723ae/btc.h new file mode 100644 index 000000000000..417afeed36af --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/btc.h | |||
@@ -0,0 +1,41 @@ | |||
1 | /****************************************************************************** | ||
2 | ** | ||
3 | ** Copyright(c) 2009-2012 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 | ** Larry Finger <Larry.Finger@lwfinger.net> | ||
26 | ** | ||
27 | ***************************************************************************** | ||
28 | */ | ||
29 | |||
30 | #ifndef __RTL8723E_BTC_H__ | ||
31 | #define __RTL8723E_BTC_H__ | ||
32 | |||
33 | #include "../wifi.h" | ||
34 | #include "hal_bt_coexist.h" | ||
35 | |||
36 | struct bt_coexist_c2h_info { | ||
37 | u8 no_parse_c2h; | ||
38 | u8 has_c2h; | ||
39 | }; | ||
40 | |||
41 | #endif | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/def.h b/drivers/net/wireless/rtlwifi/rtl8723ae/def.h new file mode 100644 index 000000000000..8c110356dff9 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/def.h | |||
@@ -0,0 +1,163 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 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 | |||
31 | #ifndef __RTL8723E_DEF_H__ | ||
32 | #define __RTL8723E_DEF_H__ | ||
33 | |||
34 | #define HAL_PRIME_CHNL_OFFSET_LOWER 1 | ||
35 | |||
36 | #define RX_MPDU_QUEUE 0 | ||
37 | |||
38 | #define CHIP_8723 BIT(0) | ||
39 | #define NORMAL_CHIP BIT(3) | ||
40 | #define RF_TYPE_1T2R BIT(4) | ||
41 | #define RF_TYPE_2T2R BIT(5) | ||
42 | #define CHIP_VENDOR_UMC BIT(7) | ||
43 | #define B_CUT_VERSION BIT(12) | ||
44 | #define C_CUT_VERSION BIT(13) | ||
45 | #define D_CUT_VERSION ((BIT(12)|BIT(13))) | ||
46 | #define E_CUT_VERSION BIT(14) | ||
47 | #define RF_RL_ID (BIT(31)|BIT(30)|BIT(29)|BIT(28)) | ||
48 | |||
49 | enum version_8723e { | ||
50 | VERSION_TEST_UMC_CHIP_8723 = 0x0081, | ||
51 | VERSION_NORMAL_UMC_CHIP_8723_1T1R_A_CUT = 0x0089, | ||
52 | VERSION_NORMAL_UMC_CHIP_8723_1T1R_B_CUT = 0x1089, | ||
53 | }; | ||
54 | |||
55 | /* MASK */ | ||
56 | #define IC_TYPE_MASK (BIT(0)|BIT(1)|BIT(2)) | ||
57 | #define CHIP_TYPE_MASK BIT(3) | ||
58 | #define RF_TYPE_MASK (BIT(4)|BIT(5)|BIT(6)) | ||
59 | #define MANUFACTUER_MASK BIT(7) | ||
60 | #define ROM_VERSION_MASK (BIT(11)|BIT(10)|BIT(9)|BIT(8)) | ||
61 | #define CUT_VERSION_MASK (BIT(15)|BIT(14)|BIT(13)|BIT(12)) | ||
62 | |||
63 | /* Get element */ | ||
64 | #define GET_CVID_IC_TYPE(version) ((version) & IC_TYPE_MASK) | ||
65 | #define GET_CVID_MANUFACTUER(version) ((version) & MANUFACTUER_MASK) | ||
66 | #define GET_CVID_CUT_VERSION(version) ((version) & CUT_VERSION_MASK) | ||
67 | |||
68 | #define IS_81XXC(version) ((GET_CVID_IC_TYPE(version) == 0) ?\ | ||
69 | true : false) | ||
70 | #define IS_8723_SERIES(version) \ | ||
71 | ((GET_CVID_IC_TYPE(version) == CHIP_8723) ? true : false) | ||
72 | #define IS_CHIP_VENDOR_UMC(version) \ | ||
73 | ((GET_CVID_MANUFACTUER(version)) ? true : false) | ||
74 | |||
75 | #define IS_VENDOR_UMC_A_CUT(version) ((IS_CHIP_VENDOR_UMC(version)) ? \ | ||
76 | ((GET_CVID_CUT_VERSION(version)) ? false : true) : false) | ||
77 | #define IS_VENDOR_8723_A_CUT(version) ((IS_8723_SERIES(version)) ? \ | ||
78 | ((GET_CVID_CUT_VERSION(version)) ? false : true) : false) | ||
79 | #define IS_81xxC_VENDOR_UMC_B_CUT(version) ((IS_CHIP_VENDOR_UMC(version)) \ | ||
80 | ? ((GET_CVID_CUT_VERSION(version) == B_CUT_VERSION) ? \ | ||
81 | true : false) : false) | ||
82 | |||
83 | enum rf_optype { | ||
84 | RF_OP_BY_SW_3WIRE = 0, | ||
85 | RF_OP_BY_FW, | ||
86 | RF_OP_MAX | ||
87 | }; | ||
88 | |||
89 | enum rf_power_state { | ||
90 | RF_ON, | ||
91 | RF_OFF, | ||
92 | RF_SLEEP, | ||
93 | RF_SHUT_DOWN, | ||
94 | }; | ||
95 | |||
96 | enum power_save_mode { | ||
97 | POWER_SAVE_MODE_ACTIVE, | ||
98 | POWER_SAVE_MODE_SAVE, | ||
99 | }; | ||
100 | |||
101 | enum power_polocy_config { | ||
102 | POWERCFG_MAX_POWER_SAVINGS, | ||
103 | POWERCFG_GLOBAL_POWER_SAVINGS, | ||
104 | POWERCFG_LOCAL_POWER_SAVINGS, | ||
105 | POWERCFG_LENOVO, | ||
106 | }; | ||
107 | |||
108 | enum interface_select_pci { | ||
109 | INTF_SEL1_MINICARD = 0, | ||
110 | INTF_SEL0_PCIE = 1, | ||
111 | INTF_SEL2_RSV = 2, | ||
112 | INTF_SEL3_RSV = 3, | ||
113 | }; | ||
114 | |||
115 | enum hal_fw_c2h_cmd_id { | ||
116 | HAL_FW_C2H_CMD_Read_MACREG = 0, | ||
117 | HAL_FW_C2H_CMD_Read_BBREG = 1, | ||
118 | HAL_FW_C2H_CMD_Read_RFREG = 2, | ||
119 | HAL_FW_C2H_CMD_Read_EEPROM = 3, | ||
120 | HAL_FW_C2H_CMD_Read_EFUSE = 4, | ||
121 | HAL_FW_C2H_CMD_Read_CAM = 5, | ||
122 | HAL_FW_C2H_CMD_Get_BasicRate = 6, | ||
123 | HAL_FW_C2H_CMD_Get_DataRate = 7, | ||
124 | HAL_FW_C2H_CMD_Survey = 8, | ||
125 | HAL_FW_C2H_CMD_SurveyDone = 9, | ||
126 | HAL_FW_C2H_CMD_JoinBss = 10, | ||
127 | HAL_FW_C2H_CMD_AddSTA = 11, | ||
128 | HAL_FW_C2H_CMD_DelSTA = 12, | ||
129 | HAL_FW_C2H_CMD_AtimDone = 13, | ||
130 | HAL_FW_C2H_CMD_TX_Report = 14, | ||
131 | HAL_FW_C2H_CMD_CCX_Report = 15, | ||
132 | HAL_FW_C2H_CMD_DTM_Report = 16, | ||
133 | HAL_FW_C2H_CMD_TX_Rate_Statistics = 17, | ||
134 | HAL_FW_C2H_CMD_C2HLBK = 18, | ||
135 | HAL_FW_C2H_CMD_C2HDBG = 19, | ||
136 | HAL_FW_C2H_CMD_C2HFEEDBACK = 20, | ||
137 | HAL_FW_C2H_CMD_MAX | ||
138 | }; | ||
139 | |||
140 | enum rtl_desc_qsel { | ||
141 | QSLT_BK = 0x2, | ||
142 | QSLT_BE = 0x0, | ||
143 | QSLT_VI = 0x5, | ||
144 | QSLT_VO = 0x7, | ||
145 | QSLT_BEACON = 0x10, | ||
146 | QSLT_HIGH = 0x11, | ||
147 | QSLT_MGNT = 0x12, | ||
148 | QSLT_CMD = 0x13, | ||
149 | }; | ||
150 | |||
151 | struct phy_sts_cck_8723e_t { | ||
152 | u8 adc_pwdb_X[4]; | ||
153 | u8 sq_rpt; | ||
154 | u8 cck_agc_rpt; | ||
155 | }; | ||
156 | |||
157 | struct h2c_cmd_8723e { | ||
158 | u8 element_id; | ||
159 | u32 cmd_len; | ||
160 | u8 *p_cmdbuffer; | ||
161 | }; | ||
162 | |||
163 | #endif | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c new file mode 100644 index 000000000000..12e2a3cb0701 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c | |||
@@ -0,0 +1,920 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 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 | |||
31 | #include "../wifi.h" | ||
32 | #include "../base.h" | ||
33 | #include "../pci.h" | ||
34 | #include "reg.h" | ||
35 | #include "def.h" | ||
36 | #include "phy.h" | ||
37 | #include "dm.h" | ||
38 | #include "fw.h" | ||
39 | #include "hal_btc.h" | ||
40 | |||
41 | static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = { | ||
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 rtl8723ae_dm_diginit(struct ieee80211_hw *hw) | ||
154 | { | ||
155 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
156 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; | ||
157 | |||
158 | dm_digtable->dig_enable_flag = true; | ||
159 | dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; | ||
160 | dm_digtable->cur_igvalue = 0x20; | ||
161 | dm_digtable->pre_igvalue = 0x0; | ||
162 | dm_digtable->cursta_cstate = DIG_STA_DISCONNECT; | ||
163 | dm_digtable->presta_cstate = DIG_STA_DISCONNECT; | ||
164 | dm_digtable->curmultista_cstate = DIG_MULTISTA_DISCONNECT; | ||
165 | dm_digtable->rssi_lowthresh = DM_DIG_THRESH_LOW; | ||
166 | dm_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH; | ||
167 | dm_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW; | ||
168 | dm_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH; | ||
169 | dm_digtable->rx_gain_range_max = DM_DIG_MAX; | ||
170 | dm_digtable->rx_gain_range_min = DM_DIG_MIN; | ||
171 | dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT; | ||
172 | dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX; | ||
173 | dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN; | ||
174 | dm_digtable->pre_cck_pd_state = CCK_PD_STAGE_MAX; | ||
175 | dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX; | ||
176 | } | ||
177 | |||
178 | static u8 rtl_init_gain_min_pwdb(struct ieee80211_hw *hw) | ||
179 | { | ||
180 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
181 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; | ||
182 | long rssi_val_min = 0; | ||
183 | |||
184 | if ((dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) && | ||
185 | (dm_digtable->cursta_cstate == DIG_STA_CONNECT)) { | ||
186 | if (rtlpriv->dm.entry_min_undec_sm_pwdb != 0) | ||
187 | rssi_val_min = | ||
188 | (rtlpriv->dm.entry_min_undec_sm_pwdb > | ||
189 | rtlpriv->dm.undec_sm_pwdb) ? | ||
190 | rtlpriv->dm.undec_sm_pwdb : | ||
191 | rtlpriv->dm.entry_min_undec_sm_pwdb; | ||
192 | else | ||
193 | rssi_val_min = rtlpriv->dm.undec_sm_pwdb; | ||
194 | } else if (dm_digtable->cursta_cstate == DIG_STA_CONNECT || | ||
195 | dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT) { | ||
196 | rssi_val_min = rtlpriv->dm.undec_sm_pwdb; | ||
197 | } else if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) { | ||
198 | rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb; | ||
199 | } | ||
200 | |||
201 | return (u8) rssi_val_min; | ||
202 | } | ||
203 | |||
204 | static void rtl8723ae_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) | ||
205 | { | ||
206 | u32 ret_value; | ||
207 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
208 | struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); | ||
209 | |||
210 | ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD); | ||
211 | falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16); | ||
212 | |||
213 | ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD); | ||
214 | falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff); | ||
215 | falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16); | ||
216 | |||
217 | ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD); | ||
218 | falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff); | ||
219 | falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail + | ||
220 | falsealm_cnt->cnt_rate_illegal + | ||
221 | falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail; | ||
222 | |||
223 | rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1); | ||
224 | ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0); | ||
225 | falsealm_cnt->cnt_cck_fail = ret_value; | ||
226 | |||
227 | ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3); | ||
228 | falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8; | ||
229 | falsealm_cnt->cnt_all = (falsealm_cnt->cnt_parity_fail + | ||
230 | falsealm_cnt->cnt_rate_illegal + | ||
231 | falsealm_cnt->cnt_crc8_fail + | ||
232 | falsealm_cnt->cnt_mcs_fail + | ||
233 | falsealm_cnt->cnt_cck_fail); | ||
234 | |||
235 | rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1); | ||
236 | rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0); | ||
237 | rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0); | ||
238 | rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2); | ||
239 | |||
240 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, | ||
241 | "cnt_parity_fail = %d, cnt_rate_illegal = %d, " | ||
242 | "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n", | ||
243 | falsealm_cnt->cnt_parity_fail, | ||
244 | falsealm_cnt->cnt_rate_illegal, | ||
245 | falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail); | ||
246 | |||
247 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, | ||
248 | "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n", | ||
249 | falsealm_cnt->cnt_ofdm_fail, | ||
250 | falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all); | ||
251 | } | ||
252 | |||
253 | static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw) | ||
254 | { | ||
255 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
256 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; | ||
257 | u8 value_igi = dm_digtable->cur_igvalue; | ||
258 | |||
259 | if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0) | ||
260 | value_igi--; | ||
261 | else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1) | ||
262 | value_igi += 0; | ||
263 | else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH2) | ||
264 | value_igi++; | ||
265 | else | ||
266 | value_igi += 2; | ||
267 | |||
268 | value_igi = clamp(value_igi, (u8)DM_DIG_FA_LOWER, (u8)DM_DIG_FA_UPPER); | ||
269 | if (rtlpriv->falsealm_cnt.cnt_all > 10000) | ||
270 | value_igi = 0x32; | ||
271 | |||
272 | dm_digtable->cur_igvalue = value_igi; | ||
273 | rtl8723ae_dm_write_dig(hw); | ||
274 | } | ||
275 | |||
276 | static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw) | ||
277 | { | ||
278 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
279 | struct dig_t *dgtbl = &rtlpriv->dm_digtable; | ||
280 | |||
281 | if (rtlpriv->falsealm_cnt.cnt_all > dgtbl->fa_highthresh) { | ||
282 | if ((dgtbl->back_val - 2) < dgtbl->back_range_min) | ||
283 | dgtbl->back_val = dgtbl->back_range_min; | ||
284 | else | ||
285 | dgtbl->back_val -= 2; | ||
286 | } else if (rtlpriv->falsealm_cnt.cnt_all < dgtbl->fa_lowthresh) { | ||
287 | if ((dgtbl->back_val + 2) > dgtbl->back_range_max) | ||
288 | dgtbl->back_val = dgtbl->back_range_max; | ||
289 | else | ||
290 | dgtbl->back_val += 2; | ||
291 | } | ||
292 | |||
293 | if ((dgtbl->rssi_val_min + 10 - dgtbl->back_val) > | ||
294 | dgtbl->rx_gain_range_max) | ||
295 | dgtbl->cur_igvalue = dgtbl->rx_gain_range_max; | ||
296 | else if ((dgtbl->rssi_val_min + 10 - | ||
297 | dgtbl->back_val) < dgtbl->rx_gain_range_min) | ||
298 | dgtbl->cur_igvalue = dgtbl->rx_gain_range_min; | ||
299 | else | ||
300 | dgtbl->cur_igvalue = dgtbl->rssi_val_min + 10 - dgtbl->back_val; | ||
301 | |||
302 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, | ||
303 | "rssi_val_min = %x back_val %x\n", | ||
304 | dgtbl->rssi_val_min, dgtbl->back_val); | ||
305 | |||
306 | rtl8723ae_dm_write_dig(hw); | ||
307 | } | ||
308 | |||
309 | static void rtl8723ae_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) | ||
310 | { | ||
311 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
312 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
313 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; | ||
314 | long rssi_strength = rtlpriv->dm.entry_min_undec_sm_pwdb; | ||
315 | bool multi_sta = false; | ||
316 | |||
317 | if (mac->opmode == NL80211_IFTYPE_ADHOC) | ||
318 | multi_sta = true; | ||
319 | |||
320 | if ((!multi_sta) || | ||
321 | (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT)) { | ||
322 | rtlpriv->initialized = false; | ||
323 | dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; | ||
324 | return; | ||
325 | } else if (!rtlpriv->initialized) { | ||
326 | rtlpriv->initialized = true; | ||
327 | dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; | ||
328 | dm_digtable->cur_igvalue = 0x20; | ||
329 | rtl8723ae_dm_write_dig(hw); | ||
330 | } | ||
331 | |||
332 | if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) { | ||
333 | if ((rssi_strength < dm_digtable->rssi_lowthresh) && | ||
334 | (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) { | ||
335 | |||
336 | if (dm_digtable->dig_ext_port_stage == | ||
337 | DIG_EXT_PORT_STAGE_2) { | ||
338 | dm_digtable->cur_igvalue = 0x20; | ||
339 | rtl8723ae_dm_write_dig(hw); | ||
340 | } | ||
341 | |||
342 | dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_1; | ||
343 | } else if (rssi_strength > dm_digtable->rssi_highthresh) { | ||
344 | dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_2; | ||
345 | rtl92c_dm_ctrl_initgain_by_fa(hw); | ||
346 | } | ||
347 | } else if (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_0) { | ||
348 | dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; | ||
349 | dm_digtable->cur_igvalue = 0x20; | ||
350 | rtl8723ae_dm_write_dig(hw); | ||
351 | } | ||
352 | |||
353 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, | ||
354 | "curmultista_cstate = %x dig_ext_port_stage %x\n", | ||
355 | dm_digtable->curmultista_cstate, | ||
356 | dm_digtable->dig_ext_port_stage); | ||
357 | } | ||
358 | |||
359 | static void rtl8723ae_dm_initial_gain_sta(struct ieee80211_hw *hw) | ||
360 | { | ||
361 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
362 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; | ||
363 | |||
364 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, | ||
365 | "presta_cstate = %x, cursta_cstate = %x\n", | ||
366 | dm_digtable->presta_cstate, | ||
367 | dm_digtable->cursta_cstate); | ||
368 | |||
369 | if (dm_digtable->presta_cstate == dm_digtable->cursta_cstate || | ||
370 | dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT || | ||
371 | dm_digtable->cursta_cstate == DIG_STA_CONNECT) { | ||
372 | |||
373 | if (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) { | ||
374 | dm_digtable->rssi_val_min = rtl_init_gain_min_pwdb(hw); | ||
375 | rtl92c_dm_ctrl_initgain_by_rssi(hw); | ||
376 | } | ||
377 | } else { | ||
378 | dm_digtable->rssi_val_min = 0; | ||
379 | dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; | ||
380 | dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT; | ||
381 | dm_digtable->cur_igvalue = 0x20; | ||
382 | dm_digtable->pre_igvalue = 0; | ||
383 | rtl8723ae_dm_write_dig(hw); | ||
384 | } | ||
385 | } | ||
386 | static void rtl8723ae_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) | ||
387 | { | ||
388 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
389 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; | ||
390 | |||
391 | if (dm_digtable->cursta_cstate == DIG_STA_CONNECT) { | ||
392 | dm_digtable->rssi_val_min = rtl_init_gain_min_pwdb(hw); | ||
393 | |||
394 | if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LowRssi) { | ||
395 | if (dm_digtable->rssi_val_min <= 25) | ||
396 | dm_digtable->cur_cck_pd_state = | ||
397 | CCK_PD_STAGE_LowRssi; | ||
398 | else | ||
399 | dm_digtable->cur_cck_pd_state = | ||
400 | CCK_PD_STAGE_HighRssi; | ||
401 | } else { | ||
402 | if (dm_digtable->rssi_val_min <= 20) | ||
403 | dm_digtable->cur_cck_pd_state = | ||
404 | CCK_PD_STAGE_LowRssi; | ||
405 | else | ||
406 | dm_digtable->cur_cck_pd_state = | ||
407 | CCK_PD_STAGE_HighRssi; | ||
408 | } | ||
409 | } else { | ||
410 | dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX; | ||
411 | } | ||
412 | |||
413 | if (dm_digtable->pre_cck_pd_state != dm_digtable->cur_cck_pd_state) { | ||
414 | if (dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LowRssi) { | ||
415 | if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800) | ||
416 | dm_digtable->cur_cck_fa_state = | ||
417 | CCK_FA_STAGE_High; | ||
418 | else | ||
419 | dm_digtable->cur_cck_fa_state = | ||
420 | CCK_FA_STAGE_Low; | ||
421 | |||
422 | if (dm_digtable->pre_cck_fa_state != | ||
423 | dm_digtable->cur_cck_fa_state) { | ||
424 | if (dm_digtable->cur_cck_fa_state == | ||
425 | CCK_FA_STAGE_Low) | ||
426 | rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, | ||
427 | 0x83); | ||
428 | else | ||
429 | rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, | ||
430 | 0xcd); | ||
431 | |||
432 | dm_digtable->pre_cck_fa_state = | ||
433 | dm_digtable->cur_cck_fa_state; | ||
434 | } | ||
435 | |||
436 | rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40); | ||
437 | |||
438 | } else { | ||
439 | rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); | ||
440 | rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47); | ||
441 | |||
442 | } | ||
443 | dm_digtable->pre_cck_pd_state = dm_digtable->cur_cck_pd_state; | ||
444 | } | ||
445 | |||
446 | RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, | ||
447 | "CCKPDStage=%x\n", dm_digtable->cur_cck_pd_state); | ||
448 | |||
449 | } | ||
450 | |||
451 | static void rtl8723ae_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) | ||
452 | { | ||
453 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
454 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
455 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; | ||
456 | |||
457 | if (mac->act_scanning == true) | ||
458 | return; | ||
459 | |||
460 | if (mac->link_state >= MAC80211_LINKED) | ||
461 | dm_digtable->cursta_cstate = DIG_STA_CONNECT; | ||
462 | else | ||
463 | dm_digtable->cursta_cstate = DIG_STA_DISCONNECT; | ||
464 | |||
465 | rtl8723ae_dm_initial_gain_sta(hw); | ||
466 | rtl8723ae_dm_initial_gain_multi_sta(hw); | ||
467 | rtl8723ae_dm_cck_packet_detection_thresh(hw); | ||
468 | |||
469 | dm_digtable->presta_cstate = dm_digtable->cursta_cstate; | ||
470 | |||
471 | } | ||
472 | |||
473 | static void rtl8723ae_dm_dig(struct ieee80211_hw *hw) | ||
474 | { | ||
475 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
476 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; | ||
477 | |||
478 | if (rtlpriv->dm.dm_initialgain_enable == false) | ||
479 | return; | ||
480 | if (dm_digtable->dig_enable_flag == false) | ||
481 | return; | ||
482 | |||
483 | rtl8723ae_dm_ctrl_initgain_by_twoport(hw); | ||
484 | } | ||
485 | |||
486 | static void rtl8723ae_dm_init_dynamic_txpower(struct ieee80211_hw *hw) | ||
487 | { | ||
488 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
489 | |||
490 | rtlpriv->dm.dynamic_txpower_enable = false; | ||
491 | |||
492 | rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; | ||
493 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; | ||
494 | } | ||
495 | |||
496 | static void rtl8723ae_dm_dynamic_txpower(struct ieee80211_hw *hw) | ||
497 | { | ||
498 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
499 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
500 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
501 | long undec_sm_pwdb; | ||
502 | |||
503 | if (!rtlpriv->dm.dynamic_txpower_enable) | ||
504 | return; | ||
505 | |||
506 | if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) { | ||
507 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; | ||
508 | return; | ||
509 | } | ||
510 | |||
511 | if ((mac->link_state < MAC80211_LINKED) && | ||
512 | (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { | ||
513 | RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, | ||
514 | "Not connected\n"); | ||
515 | |||
516 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; | ||
517 | |||
518 | rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; | ||
519 | return; | ||
520 | } | ||
521 | |||
522 | if (mac->link_state >= MAC80211_LINKED) { | ||
523 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { | ||
524 | undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; | ||
525 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
526 | "AP Client PWDB = 0x%lx\n", | ||
527 | undec_sm_pwdb); | ||
528 | } else { | ||
529 | undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; | ||
530 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
531 | "STA Default Port PWDB = 0x%lx\n", | ||
532 | undec_sm_pwdb); | ||
533 | } | ||
534 | } else { | ||
535 | undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; | ||
536 | |||
537 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
538 | "AP Ext Port PWDB = 0x%lx\n", | ||
539 | undec_sm_pwdb); | ||
540 | } | ||
541 | |||
542 | if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { | ||
543 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; | ||
544 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
545 | "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); | ||
546 | } else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && | ||
547 | (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL1)) { | ||
548 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; | ||
549 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
550 | "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); | ||
551 | } else if (undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { | ||
552 | rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; | ||
553 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
554 | "TXHIGHPWRLEVEL_NORMAL\n"); | ||
555 | } | ||
556 | |||
557 | if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) { | ||
558 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
559 | "PHY_SetTxPowerLevel8192S() Channel = %d\n", | ||
560 | rtlphy->current_channel); | ||
561 | rtl8723ae_phy_set_txpower_level(hw, rtlphy->current_channel); | ||
562 | } | ||
563 | |||
564 | rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; | ||
565 | } | ||
566 | |||
567 | void rtl8723ae_dm_write_dig(struct ieee80211_hw *hw) | ||
568 | { | ||
569 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
570 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; | ||
571 | |||
572 | RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, | ||
573 | "cur_igvalue = 0x%x, " | ||
574 | "pre_igvalue = 0x%x, back_val = %d\n", | ||
575 | dm_digtable->cur_igvalue, dm_digtable->pre_igvalue, | ||
576 | dm_digtable->back_val); | ||
577 | |||
578 | if (dm_digtable->pre_igvalue != dm_digtable->cur_igvalue) { | ||
579 | rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, | ||
580 | dm_digtable->cur_igvalue); | ||
581 | rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f, | ||
582 | dm_digtable->cur_igvalue); | ||
583 | |||
584 | dm_digtable->pre_igvalue = dm_digtable->cur_igvalue; | ||
585 | } | ||
586 | } | ||
587 | |||
588 | static void rtl8723ae_dm_pwdmonitor(struct ieee80211_hw *hw) | ||
589 | { | ||
590 | } | ||
591 | |||
592 | void rtl8723ae_dm_init_edca_turbo(struct ieee80211_hw *hw) | ||
593 | { | ||
594 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
595 | |||
596 | rtlpriv->dm.current_turbo_edca = false; | ||
597 | rtlpriv->dm.is_any_nonbepkts = false; | ||
598 | rtlpriv->dm.is_cur_rdlstate = false; | ||
599 | } | ||
600 | |||
601 | static void rtl8723ae_dm_check_edca_turbo(struct ieee80211_hw *hw) | ||
602 | { | ||
603 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
604 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
605 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
606 | |||
607 | u64 cur_txok_cnt = 0; | ||
608 | u64 cur_rxok_cnt = 0; | ||
609 | u32 edca_be_ul = 0x5ea42b; | ||
610 | u32 edca_be_dl = 0x5ea42b; | ||
611 | bool bt_change_edca = false; | ||
612 | |||
613 | if ((mac->last_bt_edca_ul != rtlpcipriv->bt_coexist.bt_edca_ul) || | ||
614 | (mac->last_bt_edca_dl != rtlpcipriv->bt_coexist.bt_edca_dl)) { | ||
615 | rtlpriv->dm.current_turbo_edca = false; | ||
616 | mac->last_bt_edca_ul = rtlpcipriv->bt_coexist.bt_edca_ul; | ||
617 | mac->last_bt_edca_dl = rtlpcipriv->bt_coexist.bt_edca_dl; | ||
618 | } | ||
619 | |||
620 | if (rtlpcipriv->bt_coexist.bt_edca_ul != 0) { | ||
621 | edca_be_ul = rtlpcipriv->bt_coexist.bt_edca_ul; | ||
622 | bt_change_edca = true; | ||
623 | } | ||
624 | |||
625 | if (rtlpcipriv->bt_coexist.bt_edca_dl != 0) { | ||
626 | edca_be_ul = rtlpcipriv->bt_coexist.bt_edca_dl; | ||
627 | bt_change_edca = true; | ||
628 | } | ||
629 | |||
630 | if (mac->link_state != MAC80211_LINKED) { | ||
631 | rtlpriv->dm.current_turbo_edca = false; | ||
632 | return; | ||
633 | } | ||
634 | |||
635 | if ((!mac->ht_enable) && (!rtlpcipriv->bt_coexist.bt_coexistence)) { | ||
636 | if (!(edca_be_ul & 0xffff0000)) | ||
637 | edca_be_ul |= 0x005e0000; | ||
638 | |||
639 | if (!(edca_be_dl & 0xffff0000)) | ||
640 | edca_be_dl |= 0x005e0000; | ||
641 | } | ||
642 | |||
643 | if ((bt_change_edca) || ((!rtlpriv->dm.is_any_nonbepkts) && | ||
644 | (!rtlpriv->dm.disable_framebursting))) { | ||
645 | |||
646 | cur_txok_cnt = rtlpriv->stats.txbytesunicast - | ||
647 | mac->last_txok_cnt; | ||
648 | cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - | ||
649 | mac->last_rxok_cnt; | ||
650 | |||
651 | if (cur_rxok_cnt > 4 * cur_txok_cnt) { | ||
652 | if (!rtlpriv->dm.is_cur_rdlstate || | ||
653 | !rtlpriv->dm.current_turbo_edca) { | ||
654 | rtl_write_dword(rtlpriv, | ||
655 | REG_EDCA_BE_PARAM, | ||
656 | edca_be_dl); | ||
657 | rtlpriv->dm.is_cur_rdlstate = true; | ||
658 | } | ||
659 | } else { | ||
660 | if (rtlpriv->dm.is_cur_rdlstate || | ||
661 | !rtlpriv->dm.current_turbo_edca) { | ||
662 | rtl_write_dword(rtlpriv, | ||
663 | REG_EDCA_BE_PARAM, | ||
664 | edca_be_ul); | ||
665 | rtlpriv->dm.is_cur_rdlstate = false; | ||
666 | } | ||
667 | } | ||
668 | rtlpriv->dm.current_turbo_edca = true; | ||
669 | } else { | ||
670 | if (rtlpriv->dm.current_turbo_edca) { | ||
671 | u8 tmp = AC0_BE; | ||
672 | rtlpriv->cfg->ops->set_hw_reg(hw, | ||
673 | HW_VAR_AC_PARAM, | ||
674 | (u8 *) (&tmp)); | ||
675 | rtlpriv->dm.current_turbo_edca = false; | ||
676 | } | ||
677 | } | ||
678 | |||
679 | rtlpriv->dm.is_any_nonbepkts = false; | ||
680 | mac->last_txok_cnt = rtlpriv->stats.txbytesunicast; | ||
681 | mac->last_rxok_cnt = rtlpriv->stats.rxbytesunicast; | ||
682 | } | ||
683 | |||
684 | static void rtl8723ae_dm_initialize_txpower_tracking(struct ieee80211_hw *hw) | ||
685 | { | ||
686 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
687 | |||
688 | rtlpriv->dm.txpower_tracking = true; | ||
689 | rtlpriv->dm.txpower_trackinginit = false; | ||
690 | |||
691 | RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, | ||
692 | "pMgntInfo->txpower_tracking = %d\n", | ||
693 | rtlpriv->dm.txpower_tracking); | ||
694 | } | ||
695 | |||
696 | void rtl8723ae_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) | ||
697 | { | ||
698 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
699 | struct rate_adaptive *p_ra = &(rtlpriv->ra); | ||
700 | |||
701 | p_ra->ratr_state = DM_RATR_STA_INIT; | ||
702 | p_ra->pre_ratr_state = DM_RATR_STA_INIT; | ||
703 | |||
704 | if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) | ||
705 | rtlpriv->dm.useramask = true; | ||
706 | else | ||
707 | rtlpriv->dm.useramask = false; | ||
708 | } | ||
709 | |||
710 | static void rtl8723ae_dm_init_dynamic_bpowersaving(struct ieee80211_hw *hw) | ||
711 | { | ||
712 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
713 | |||
714 | rtlpriv->dm_pstable.pre_ccastate = CCA_MAX; | ||
715 | rtlpriv->dm_pstable.cur_ccasate = CCA_MAX; | ||
716 | rtlpriv->dm_pstable.pre_rfstate = RF_MAX; | ||
717 | rtlpriv->dm_pstable.cur_rfstate = RF_MAX; | ||
718 | rtlpriv->dm_pstable.rssi_val_min = 0; | ||
719 | } | ||
720 | |||
721 | void rtl8723ae_dm_rf_saving(struct ieee80211_hw *hw, u8 force_in_normal) | ||
722 | { | ||
723 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
724 | struct ps_t *dm_pstable = &rtlpriv->dm_pstable; | ||
725 | |||
726 | if (!rtlpriv->reg_init) { | ||
727 | rtlpriv->reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, | ||
728 | MASKDWORD) & 0x1CC000) >> 14; | ||
729 | |||
730 | rtlpriv->reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1, | ||
731 | MASKDWORD) & BIT(3)) >> 3; | ||
732 | |||
733 | rtlpriv->reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, | ||
734 | MASKDWORD) & 0xFF000000) >> 24; | ||
735 | |||
736 | rtlpriv->reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & | ||
737 | 0xF000) >> 12; | ||
738 | |||
739 | rtlpriv->reg_init = true; | ||
740 | } | ||
741 | |||
742 | if (!force_in_normal) { | ||
743 | if (dm_pstable->rssi_val_min != 0) { | ||
744 | if (dm_pstable->pre_rfstate == RF_NORMAL) { | ||
745 | if (dm_pstable->rssi_val_min >= 30) | ||
746 | dm_pstable->cur_rfstate = RF_SAVE; | ||
747 | else | ||
748 | dm_pstable->cur_rfstate = RF_NORMAL; | ||
749 | } else { | ||
750 | if (dm_pstable->rssi_val_min <= 25) | ||
751 | dm_pstable->cur_rfstate = RF_NORMAL; | ||
752 | else | ||
753 | dm_pstable->cur_rfstate = RF_SAVE; | ||
754 | } | ||
755 | } else { | ||
756 | dm_pstable->cur_rfstate = RF_MAX; | ||
757 | } | ||
758 | } else { | ||
759 | dm_pstable->cur_rfstate = RF_NORMAL; | ||
760 | } | ||
761 | |||
762 | if (dm_pstable->pre_rfstate != dm_pstable->cur_rfstate) { | ||
763 | if (dm_pstable->cur_rfstate == RF_SAVE) { | ||
764 | |||
765 | rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, | ||
766 | BIT(5), 0x1); | ||
767 | rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, | ||
768 | 0x1C0000, 0x2); | ||
769 | rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 0); | ||
770 | rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, | ||
771 | 0xFF000000, 0x63); | ||
772 | rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, | ||
773 | 0xC000, 0x2); | ||
774 | rtl_set_bbreg(hw, 0xa74, 0xF000, 0x3); | ||
775 | rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); | ||
776 | rtl_set_bbreg(hw, 0x818, BIT(28), 0x1); | ||
777 | } else { | ||
778 | rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, | ||
779 | 0x1CC000, rtlpriv->reg_874); | ||
780 | rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), | ||
781 | rtlpriv->reg_c70); | ||
782 | rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000, | ||
783 | rtlpriv->reg_85c); | ||
784 | rtl_set_bbreg(hw, 0xa74, 0xF000, rtlpriv->reg_a74); | ||
785 | rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); | ||
786 | rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, | ||
787 | BIT(5), 0x0); | ||
788 | } | ||
789 | |||
790 | dm_pstable->pre_rfstate = dm_pstable->cur_rfstate; | ||
791 | } | ||
792 | } | ||
793 | |||
794 | static void rtl8723ae_dm_dynamic_bpowersaving(struct ieee80211_hw *hw) | ||
795 | { | ||
796 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
797 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
798 | struct ps_t *dm_pstable = &rtlpriv->dm_pstable; | ||
799 | |||
800 | if (((mac->link_state == MAC80211_NOLINK)) && | ||
801 | (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { | ||
802 | dm_pstable->rssi_val_min = 0; | ||
803 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, | ||
804 | "Not connected to any\n"); | ||
805 | } | ||
806 | |||
807 | if (mac->link_state == MAC80211_LINKED) { | ||
808 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { | ||
809 | dm_pstable->rssi_val_min = | ||
810 | rtlpriv->dm.entry_min_undec_sm_pwdb; | ||
811 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, | ||
812 | "AP Client PWDB = 0x%lx\n", | ||
813 | dm_pstable->rssi_val_min); | ||
814 | } else { | ||
815 | dm_pstable->rssi_val_min = rtlpriv->dm.undec_sm_pwdb; | ||
816 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, | ||
817 | "STA Default Port PWDB = 0x%lx\n", | ||
818 | dm_pstable->rssi_val_min); | ||
819 | } | ||
820 | } else { | ||
821 | dm_pstable->rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb; | ||
822 | |||
823 | RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, | ||
824 | "AP Ext Port PWDB = 0x%lx\n", | ||
825 | dm_pstable->rssi_val_min); | ||
826 | } | ||
827 | |||
828 | rtl8723ae_dm_rf_saving(hw, false); | ||
829 | } | ||
830 | |||
831 | void rtl8723ae_dm_init(struct ieee80211_hw *hw) | ||
832 | { | ||
833 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
834 | |||
835 | rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; | ||
836 | rtl8723ae_dm_diginit(hw); | ||
837 | rtl8723ae_dm_init_dynamic_txpower(hw); | ||
838 | rtl8723ae_dm_init_edca_turbo(hw); | ||
839 | rtl8723ae_dm_init_rate_adaptive_mask(hw); | ||
840 | rtl8723ae_dm_initialize_txpower_tracking(hw); | ||
841 | rtl8723ae_dm_init_dynamic_bpowersaving(hw); | ||
842 | } | ||
843 | |||
844 | void rtl8723ae_dm_watchdog(struct ieee80211_hw *hw) | ||
845 | { | ||
846 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
847 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
848 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
849 | bool fw_current_inpsmode = false; | ||
850 | bool fw_ps_awake = true; | ||
851 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, | ||
852 | (u8 *) (&fw_current_inpsmode)); | ||
853 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, | ||
854 | (u8 *) (&fw_ps_awake)); | ||
855 | |||
856 | if ((ppsc->rfpwr_state == ERFON) && | ||
857 | ((!fw_current_inpsmode) && fw_ps_awake) && | ||
858 | (!ppsc->rfchange_inprogress)) { | ||
859 | rtl8723ae_dm_pwdmonitor(hw); | ||
860 | rtl8723ae_dm_dig(hw); | ||
861 | rtl8723ae_dm_false_alarm_counter_statistics(hw); | ||
862 | rtl8723ae_dm_dynamic_bpowersaving(hw); | ||
863 | rtl8723ae_dm_dynamic_txpower(hw); | ||
864 | /* rtl92c_dm_refresh_rate_adaptive_mask(hw); */ | ||
865 | rtl8723ae_dm_bt_coexist(hw); | ||
866 | rtl8723ae_dm_check_edca_turbo(hw); | ||
867 | } | ||
868 | if (rtlpcipriv->bt_coexist.init_set) | ||
869 | rtl_write_byte(rtlpriv, 0x76e, 0xc); | ||
870 | } | ||
871 | |||
872 | static void rtl8723ae_dm_init_bt_coexist(struct ieee80211_hw *hw) | ||
873 | { | ||
874 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
875 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
876 | |||
877 | rtlpcipriv->bt_coexist.bt_rfreg_origin_1e | ||
878 | = rtl_get_rfreg(hw, (enum radio_path)0, RF_RCK1, 0xfffff); | ||
879 | rtlpcipriv->bt_coexist.bt_rfreg_origin_1f | ||
880 | = rtl_get_rfreg(hw, (enum radio_path)0, RF_RCK2, 0xf0); | ||
881 | |||
882 | rtlpcipriv->bt_coexist.cstate = 0; | ||
883 | rtlpcipriv->bt_coexist.previous_state = 0; | ||
884 | rtlpcipriv->bt_coexist.cstate_h = 0; | ||
885 | rtlpcipriv->bt_coexist.previous_state_h = 0; | ||
886 | rtlpcipriv->bt_coexist.lps_counter = 0; | ||
887 | |||
888 | /* Enable counter statistics */ | ||
889 | rtl_write_byte(rtlpriv, 0x76e, 0x4); | ||
890 | rtl_write_byte(rtlpriv, 0x778, 0x3); | ||
891 | rtl_write_byte(rtlpriv, 0x40, 0x20); | ||
892 | |||
893 | rtlpcipriv->bt_coexist.init_set = true; | ||
894 | } | ||
895 | |||
896 | void rtl8723ae_dm_bt_coexist(struct ieee80211_hw *hw) | ||
897 | { | ||
898 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
899 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
900 | u8 tmp_byte = 0; | ||
901 | if (!rtlpcipriv->bt_coexist.bt_coexistence) { | ||
902 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, | ||
903 | "[DM]{BT], BT not exist!!\n"); | ||
904 | return; | ||
905 | } | ||
906 | |||
907 | if (!rtlpcipriv->bt_coexist.init_set) { | ||
908 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, | ||
909 | "[DM][BT], rtl8723ae_dm_bt_coexist()\n"); | ||
910 | |||
911 | rtl8723ae_dm_init_bt_coexist(hw); | ||
912 | } | ||
913 | |||
914 | tmp_byte = rtl_read_byte(rtlpriv, 0x40); | ||
915 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, | ||
916 | "[DM][BT], 0x40 is 0x%x", tmp_byte); | ||
917 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
918 | "[DM][BT], bt_dm_coexist start"); | ||
919 | rtl8723ae_dm_bt_coexist_8723(hw); | ||
920 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h new file mode 100644 index 000000000000..39d246196247 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h | |||
@@ -0,0 +1,149 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 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 | |||
31 | #ifndef __RTL8723E_DM_H__ | ||
32 | #define __RTL8723E_DM_H__ | ||
33 | |||
34 | #define HAL_DM_HIPWR_DISABLE BIT(1) | ||
35 | |||
36 | #define OFDM_TABLE_SIZE 37 | ||
37 | #define CCK_TABLE_SIZE 33 | ||
38 | |||
39 | #define DM_DIG_THRESH_HIGH 40 | ||
40 | #define DM_DIG_THRESH_LOW 35 | ||
41 | |||
42 | #define DM_FALSEALARM_THRESH_LOW 400 | ||
43 | #define DM_FALSEALARM_THRESH_HIGH 1000 | ||
44 | |||
45 | #define DM_DIG_MAX 0x3e | ||
46 | #define DM_DIG_MIN 0x1e | ||
47 | |||
48 | #define DM_DIG_FA_UPPER 0x32 | ||
49 | #define DM_DIG_FA_LOWER 0x20 | ||
50 | #define DM_DIG_FA_TH0 0x20 | ||
51 | #define DM_DIG_FA_TH1 0x100 | ||
52 | #define DM_DIG_FA_TH2 0x200 | ||
53 | |||
54 | #define DM_DIG_BACKOFF_MAX 12 | ||
55 | #define DM_DIG_BACKOFF_MIN -4 | ||
56 | #define DM_DIG_BACKOFF_DEFAULT 10 | ||
57 | |||
58 | #define DM_RATR_STA_INIT 0 | ||
59 | |||
60 | #define TXHIGHPWRLEVEL_NORMAL 0 | ||
61 | #define TXHIGHPWRLEVEL_LEVEL1 1 | ||
62 | #define TXHIGHPWRLEVEL_LEVEL2 2 | ||
63 | #define TXHIGHPWRLEVEL_BT1 3 | ||
64 | #define TXHIGHPWRLEVEL_BT2 4 | ||
65 | |||
66 | #define DM_TYPE_BYDRIVER 1 | ||
67 | |||
68 | #define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 | ||
69 | #define TX_POWER_NEAR_FIELD_THRESH_LVL1 67 | ||
70 | |||
71 | struct swat_t { | ||
72 | u8 failure_cnt; | ||
73 | u8 try_flag; | ||
74 | u8 stop_trying; | ||
75 | long pre_rssi; | ||
76 | long trying_threshold; | ||
77 | u8 cur_antenna; | ||
78 | u8 pre_antenna; | ||
79 | }; | ||
80 | |||
81 | enum tag_dynamic_init_gain_operation_type_definition { | ||
82 | DIG_TYPE_THRESH_HIGH = 0, | ||
83 | DIG_TYPE_THRESH_LOW = 1, | ||
84 | DIG_TYPE_BACKOFF = 2, | ||
85 | DIG_TYPE_RX_GAIN_MIN = 3, | ||
86 | DIG_TYPE_RX_GAIN_MAX = 4, | ||
87 | DIG_TYPE_ENABLE = 5, | ||
88 | DIG_TYPE_DISABLE = 6, | ||
89 | DIG_OP_TYPE_MAX | ||
90 | }; | ||
91 | |||
92 | enum tag_cck_packet_detection_threshold_type_definition { | ||
93 | CCK_PD_STAGE_LowRssi = 0, | ||
94 | CCK_PD_STAGE_HighRssi = 1, | ||
95 | CCK_FA_STAGE_Low = 2, | ||
96 | CCK_FA_STAGE_High = 3, | ||
97 | CCK_PD_STAGE_MAX = 4, | ||
98 | }; | ||
99 | |||
100 | enum dm_1r_cca_e { | ||
101 | CCA_1R = 0, | ||
102 | CCA_2R = 1, | ||
103 | CCA_MAX = 2, | ||
104 | }; | ||
105 | |||
106 | enum dm_rf_e { | ||
107 | RF_SAVE = 0, | ||
108 | RF_NORMAL = 1, | ||
109 | RF_MAX = 2, | ||
110 | }; | ||
111 | |||
112 | enum dm_sw_ant_switch_e { | ||
113 | ANS_ANTENNA_B = 1, | ||
114 | ANS_ANTENNA_A = 2, | ||
115 | ANS_ANTENNA_MAX = 3, | ||
116 | }; | ||
117 | |||
118 | enum dm_dig_ext_port_alg_e { | ||
119 | DIG_EXT_PORT_STAGE_0 = 0, | ||
120 | DIG_EXT_PORT_STAGE_1 = 1, | ||
121 | DIG_EXT_PORT_STAGE_2 = 2, | ||
122 | DIG_EXT_PORT_STAGE_3 = 3, | ||
123 | DIG_EXT_PORT_STAGE_MAX = 4, | ||
124 | }; | ||
125 | |||
126 | enum dm_dig_connect_e { | ||
127 | DIG_STA_DISCONNECT = 0, | ||
128 | DIG_STA_CONNECT = 1, | ||
129 | DIG_STA_BEFORE_CONNECT = 2, | ||
130 | DIG_MULTISTA_DISCONNECT = 3, | ||
131 | DIG_MULTISTA_CONNECT = 4, | ||
132 | DIG_CONNECT_MAX | ||
133 | }; | ||
134 | |||
135 | #define GET_UNDECORATED_AVERAGE_RSSI(_priv) \ | ||
136 | ((((struct rtl_priv *)(_priv))->mac80211.opmode == \ | ||
137 | NL80211_IFTYPE_ADHOC) ? \ | ||
138 | (((struct rtl_priv *)(_priv))->dm.entry_min_undec_sm_pwdb) \ | ||
139 | : (((struct rtl_priv *)(_priv))->dm.undec_sm_pwdb)) | ||
140 | |||
141 | void rtl8723ae_dm_init(struct ieee80211_hw *hw); | ||
142 | void rtl8723ae_dm_watchdog(struct ieee80211_hw *hw); | ||
143 | void rtl8723ae_dm_write_dig(struct ieee80211_hw *hw); | ||
144 | void rtl8723ae_dm_init_edca_turbo(struct ieee80211_hw *hw); | ||
145 | void rtl8723ae_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw); | ||
146 | void rtl8723ae_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal); | ||
147 | void rtl8723ae_dm_bt_coexist(struct ieee80211_hw *hw); | ||
148 | |||
149 | #endif | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c new file mode 100644 index 000000000000..f55b1767ef57 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c | |||
@@ -0,0 +1,745 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 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 | |||
31 | #include "../wifi.h" | ||
32 | #include "../pci.h" | ||
33 | #include "../base.h" | ||
34 | #include "reg.h" | ||
35 | #include "def.h" | ||
36 | #include "fw.h" | ||
37 | |||
38 | static void _rtl8723ae_enable_fw_download(struct ieee80211_hw *hw, bool enable) | ||
39 | { | ||
40 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
41 | u8 tmp; | ||
42 | if (enable) { | ||
43 | tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); | ||
44 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp | 0x04); | ||
45 | |||
46 | tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); | ||
47 | rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01); | ||
48 | |||
49 | tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2); | ||
50 | rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7); | ||
51 | } else { | ||
52 | tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); | ||
53 | rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe); | ||
54 | |||
55 | rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00); | ||
56 | } | ||
57 | } | ||
58 | |||
59 | static void _rtl8723ae_fw_block_write(struct ieee80211_hw *hw, | ||
60 | const u8 *buffer, u32 size) | ||
61 | { | ||
62 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
63 | u32 blockSize = sizeof(u32); | ||
64 | u8 *bufferPtr = (u8 *) buffer; | ||
65 | u32 *pu4BytePtr = (u32 *) buffer; | ||
66 | u32 i, offset, blockCount, remainSize; | ||
67 | |||
68 | blockCount = size / blockSize; | ||
69 | remainSize = size % blockSize; | ||
70 | |||
71 | for (i = 0; i < blockCount; i++) { | ||
72 | offset = i * blockSize; | ||
73 | rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset), | ||
74 | *(pu4BytePtr + i)); | ||
75 | } | ||
76 | |||
77 | if (remainSize) { | ||
78 | offset = blockCount * blockSize; | ||
79 | bufferPtr += offset; | ||
80 | for (i = 0; i < remainSize; i++) { | ||
81 | rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS + | ||
82 | offset + i), *(bufferPtr + i)); | ||
83 | } | ||
84 | } | ||
85 | } | ||
86 | |||
87 | static void _rtl8723ae_fw_page_write(struct ieee80211_hw *hw, | ||
88 | u32 page, const u8 *buffer, u32 size) | ||
89 | { | ||
90 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
91 | u8 value8; | ||
92 | u8 u8page = (u8) (page & 0x07); | ||
93 | |||
94 | value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page; | ||
95 | |||
96 | rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8); | ||
97 | _rtl8723ae_fw_block_write(hw, buffer, size); | ||
98 | } | ||
99 | |||
100 | static void _rtl8723ae_write_fw(struct ieee80211_hw *hw, | ||
101 | enum version_8723e version, u8 *buffer, | ||
102 | u32 size) | ||
103 | { | ||
104 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
105 | u8 *bufferPtr = (u8 *) buffer; | ||
106 | u32 page_nums, remain_size; | ||
107 | u32 page, offset; | ||
108 | |||
109 | RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size); | ||
110 | |||
111 | page_nums = size / FW_8192C_PAGE_SIZE; | ||
112 | remain_size = size % FW_8192C_PAGE_SIZE; | ||
113 | |||
114 | if (page_nums > 6) { | ||
115 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
116 | "Page numbers should not be greater then 6\n"); | ||
117 | } | ||
118 | |||
119 | for (page = 0; page < page_nums; page++) { | ||
120 | offset = page * FW_8192C_PAGE_SIZE; | ||
121 | _rtl8723ae_fw_page_write(hw, page, (bufferPtr + offset), | ||
122 | FW_8192C_PAGE_SIZE); | ||
123 | } | ||
124 | |||
125 | if (remain_size) { | ||
126 | offset = page_nums * FW_8192C_PAGE_SIZE; | ||
127 | page = page_nums; | ||
128 | _rtl8723ae_fw_page_write(hw, page, (bufferPtr + offset), | ||
129 | remain_size); | ||
130 | } | ||
131 | |||
132 | RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW write done.\n"); | ||
133 | } | ||
134 | |||
135 | static int _rtl8723ae_fw_free_to_go(struct ieee80211_hw *hw) | ||
136 | { | ||
137 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
138 | int err = -EIO; | ||
139 | u32 counter = 0; | ||
140 | u32 value32; | ||
141 | |||
142 | do { | ||
143 | value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); | ||
144 | } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) && | ||
145 | (!(value32 & FWDL_ChkSum_rpt))); | ||
146 | |||
147 | if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) { | ||
148 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
149 | "chksum report faill ! REG_MCUFWDL:0x%08x .\n", | ||
150 | value32); | ||
151 | goto exit; | ||
152 | } | ||
153 | |||
154 | RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, | ||
155 | "Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32); | ||
156 | |||
157 | value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); | ||
158 | value32 |= MCUFWDL_RDY; | ||
159 | value32 &= ~WINTINI_RDY; | ||
160 | rtl_write_dword(rtlpriv, REG_MCUFWDL, value32); | ||
161 | |||
162 | counter = 0; | ||
163 | |||
164 | do { | ||
165 | value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); | ||
166 | if (value32 & WINTINI_RDY) { | ||
167 | RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, | ||
168 | "Polling FW ready success!! REG_MCUFWDL:0x%08x .\n", | ||
169 | value32); | ||
170 | err = 0; | ||
171 | goto exit; | ||
172 | } | ||
173 | |||
174 | mdelay(FW_8192C_POLLING_DELAY); | ||
175 | |||
176 | } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT); | ||
177 | |||
178 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
179 | "Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32); | ||
180 | |||
181 | exit: | ||
182 | return err; | ||
183 | } | ||
184 | |||
185 | int rtl8723ae_download_fw(struct ieee80211_hw *hw) | ||
186 | { | ||
187 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
188 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
189 | struct rtl8723ae_firmware_header *pfwheader; | ||
190 | u8 *pfwdata; | ||
191 | u32 fwsize; | ||
192 | int err; | ||
193 | enum version_8723e version = rtlhal->version; | ||
194 | |||
195 | if (!rtlhal->pfirmware) | ||
196 | return 1; | ||
197 | |||
198 | pfwheader = (struct rtl8723ae_firmware_header *)rtlhal->pfirmware; | ||
199 | pfwdata = (u8 *) rtlhal->pfirmware; | ||
200 | fwsize = rtlhal->fwsize; | ||
201 | |||
202 | if (IS_FW_HEADER_EXIST(pfwheader)) { | ||
203 | RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, | ||
204 | "Firmware Version(%d), Signature(%#x),Size(%d)\n", | ||
205 | pfwheader->version, pfwheader->signature, | ||
206 | (int)sizeof(struct rtl8723ae_firmware_header)); | ||
207 | |||
208 | pfwdata = pfwdata + sizeof(struct rtl8723ae_firmware_header); | ||
209 | fwsize = fwsize - sizeof(struct rtl8723ae_firmware_header); | ||
210 | } | ||
211 | |||
212 | if (rtl_read_byte(rtlpriv, REG_MCUFWDL)&BIT(7)) { | ||
213 | rtl8723ae_firmware_selfreset(hw); | ||
214 | rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); | ||
215 | } | ||
216 | _rtl8723ae_enable_fw_download(hw, true); | ||
217 | _rtl8723ae_write_fw(hw, version, pfwdata, fwsize); | ||
218 | _rtl8723ae_enable_fw_download(hw, false); | ||
219 | |||
220 | err = _rtl8723ae_fw_free_to_go(hw); | ||
221 | if (err) { | ||
222 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
223 | "Firmware is not ready to run!\n"); | ||
224 | } else { | ||
225 | RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, | ||
226 | "Firmware is ready to run!\n"); | ||
227 | } | ||
228 | return 0; | ||
229 | } | ||
230 | |||
231 | static bool rtl8723ae_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum) | ||
232 | { | ||
233 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
234 | u8 val_hmetfr, val_mcutst_1; | ||
235 | bool result = false; | ||
236 | |||
237 | val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR); | ||
238 | val_mcutst_1 = rtl_read_byte(rtlpriv, (REG_MCUTST_1 + boxnum)); | ||
239 | |||
240 | if (((val_hmetfr >> boxnum) & BIT(0)) == 0 && val_mcutst_1 == 0) | ||
241 | result = true; | ||
242 | return result; | ||
243 | } | ||
244 | |||
245 | static void _rtl8723ae_fill_h2c_command(struct ieee80211_hw *hw, | ||
246 | u8 element_id, u32 cmd_len, | ||
247 | u8 *p_cmdbuffer) | ||
248 | { | ||
249 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
250 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
251 | u8 boxnum; | ||
252 | u16 box_reg = 0, box_extreg = 0; | ||
253 | u8 u1tmp; | ||
254 | bool isfw_rd = false; | ||
255 | bool bwrite_sucess = false; | ||
256 | u8 wait_h2c_limmit = 100; | ||
257 | u8 wait_writeh2c_limmit = 100; | ||
258 | u8 boxcontent[4], boxextcontent[2]; | ||
259 | u32 h2c_waitcounter = 0; | ||
260 | unsigned long flag; | ||
261 | u8 idx; | ||
262 | |||
263 | RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n"); | ||
264 | |||
265 | while (true) { | ||
266 | spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); | ||
267 | if (rtlhal->h2c_setinprogress) { | ||
268 | RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, | ||
269 | "H2C set in progress! Wait to set..element_id(%d).\n", | ||
270 | element_id); | ||
271 | |||
272 | while (rtlhal->h2c_setinprogress) { | ||
273 | spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, | ||
274 | flag); | ||
275 | h2c_waitcounter++; | ||
276 | RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, | ||
277 | "Wait 100 us (%d times)...\n", | ||
278 | h2c_waitcounter); | ||
279 | udelay(100); | ||
280 | |||
281 | if (h2c_waitcounter > 1000) | ||
282 | return; | ||
283 | spin_lock_irqsave(&rtlpriv->locks.h2c_lock, | ||
284 | flag); | ||
285 | } | ||
286 | spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); | ||
287 | } else { | ||
288 | rtlhal->h2c_setinprogress = true; | ||
289 | spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); | ||
290 | break; | ||
291 | } | ||
292 | } | ||
293 | |||
294 | while (!bwrite_sucess) { | ||
295 | wait_writeh2c_limmit--; | ||
296 | if (wait_writeh2c_limmit == 0) { | ||
297 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
298 | "Write H2C fail because no trigger " | ||
299 | "for FW INT!\n"); | ||
300 | break; | ||
301 | } | ||
302 | |||
303 | boxnum = rtlhal->last_hmeboxnum; | ||
304 | switch (boxnum) { | ||
305 | case 0: | ||
306 | box_reg = REG_HMEBOX_0; | ||
307 | box_extreg = REG_HMEBOX_EXT_0; | ||
308 | break; | ||
309 | case 1: | ||
310 | box_reg = REG_HMEBOX_1; | ||
311 | box_extreg = REG_HMEBOX_EXT_1; | ||
312 | break; | ||
313 | case 2: | ||
314 | box_reg = REG_HMEBOX_2; | ||
315 | box_extreg = REG_HMEBOX_EXT_2; | ||
316 | break; | ||
317 | case 3: | ||
318 | box_reg = REG_HMEBOX_3; | ||
319 | box_extreg = REG_HMEBOX_EXT_3; | ||
320 | break; | ||
321 | default: | ||
322 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
323 | "switch case not processed\n"); | ||
324 | break; | ||
325 | } | ||
326 | |||
327 | isfw_rd = rtl8723ae_check_fw_read_last_h2c(hw, boxnum); | ||
328 | while (!isfw_rd) { | ||
329 | |||
330 | wait_h2c_limmit--; | ||
331 | if (wait_h2c_limmit == 0) { | ||
332 | RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, | ||
333 | "Wating too long for FW read clear HMEBox(%d)!\n", | ||
334 | boxnum); | ||
335 | break; | ||
336 | } | ||
337 | |||
338 | udelay(10); | ||
339 | |||
340 | isfw_rd = rtl8723ae_check_fw_read_last_h2c(hw, boxnum); | ||
341 | u1tmp = rtl_read_byte(rtlpriv, 0x1BF); | ||
342 | RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, | ||
343 | "Wating for FW read clear HMEBox(%d)!!! " | ||
344 | "0x1BF = %2x\n", boxnum, u1tmp); | ||
345 | } | ||
346 | |||
347 | if (!isfw_rd) { | ||
348 | RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, | ||
349 | "Write H2C register BOX[%d] fail!!!!! " | ||
350 | "Fw do not read.\n", boxnum); | ||
351 | break; | ||
352 | } | ||
353 | |||
354 | memset(boxcontent, 0, sizeof(boxcontent)); | ||
355 | memset(boxextcontent, 0, sizeof(boxextcontent)); | ||
356 | boxcontent[0] = element_id; | ||
357 | RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, | ||
358 | "Write element_id box_reg(%4x) = %2x\n", | ||
359 | box_reg, element_id); | ||
360 | |||
361 | switch (cmd_len) { | ||
362 | case 1: | ||
363 | boxcontent[0] &= ~(BIT(7)); | ||
364 | memcpy((u8 *) (boxcontent) + 1, | ||
365 | p_cmdbuffer, 1); | ||
366 | |||
367 | for (idx = 0; idx < 4; idx++) { | ||
368 | rtl_write_byte(rtlpriv, box_reg + idx, | ||
369 | boxcontent[idx]); | ||
370 | } | ||
371 | break; | ||
372 | case 2: | ||
373 | boxcontent[0] &= ~(BIT(7)); | ||
374 | memcpy((u8 *) (boxcontent) + 1, | ||
375 | p_cmdbuffer, 2); | ||
376 | |||
377 | for (idx = 0; idx < 4; idx++) { | ||
378 | rtl_write_byte(rtlpriv, box_reg + idx, | ||
379 | boxcontent[idx]); | ||
380 | } | ||
381 | break; | ||
382 | case 3: | ||
383 | boxcontent[0] &= ~(BIT(7)); | ||
384 | memcpy((u8 *) (boxcontent) + 1, | ||
385 | p_cmdbuffer, 3); | ||
386 | |||
387 | for (idx = 0; idx < 4; idx++) { | ||
388 | rtl_write_byte(rtlpriv, box_reg + idx, | ||
389 | boxcontent[idx]); | ||
390 | } | ||
391 | break; | ||
392 | case 4: | ||
393 | boxcontent[0] |= (BIT(7)); | ||
394 | memcpy((u8 *) (boxextcontent), | ||
395 | p_cmdbuffer, 2); | ||
396 | memcpy((u8 *) (boxcontent) + 1, | ||
397 | p_cmdbuffer + 2, 2); | ||
398 | |||
399 | for (idx = 0; idx < 2; idx++) { | ||
400 | rtl_write_byte(rtlpriv, box_extreg + idx, | ||
401 | boxextcontent[idx]); | ||
402 | } | ||
403 | |||
404 | for (idx = 0; idx < 4; idx++) { | ||
405 | rtl_write_byte(rtlpriv, box_reg + idx, | ||
406 | boxcontent[idx]); | ||
407 | } | ||
408 | break; | ||
409 | case 5: | ||
410 | boxcontent[0] |= (BIT(7)); | ||
411 | memcpy((u8 *) (boxextcontent), | ||
412 | p_cmdbuffer, 2); | ||
413 | memcpy((u8 *) (boxcontent) + 1, | ||
414 | p_cmdbuffer + 2, 3); | ||
415 | |||
416 | for (idx = 0; idx < 2; idx++) { | ||
417 | rtl_write_byte(rtlpriv, box_extreg + idx, | ||
418 | boxextcontent[idx]); | ||
419 | } | ||
420 | |||
421 | for (idx = 0; idx < 4; idx++) { | ||
422 | rtl_write_byte(rtlpriv, box_reg + idx, | ||
423 | boxcontent[idx]); | ||
424 | } | ||
425 | break; | ||
426 | default: | ||
427 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
428 | "switch case not process\n"); | ||
429 | break; | ||
430 | } | ||
431 | |||
432 | bwrite_sucess = true; | ||
433 | |||
434 | rtlhal->last_hmeboxnum = boxnum + 1; | ||
435 | if (rtlhal->last_hmeboxnum == 4) | ||
436 | rtlhal->last_hmeboxnum = 0; | ||
437 | |||
438 | RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, | ||
439 | "pHalData->last_hmeboxnum = %d\n", | ||
440 | rtlhal->last_hmeboxnum); | ||
441 | } | ||
442 | |||
443 | spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); | ||
444 | rtlhal->h2c_setinprogress = false; | ||
445 | spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); | ||
446 | |||
447 | RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n"); | ||
448 | } | ||
449 | |||
450 | void rtl8723ae_fill_h2c_cmd(struct ieee80211_hw *hw, | ||
451 | u8 element_id, u32 cmd_len, u8 *p_cmdbuffer) | ||
452 | { | ||
453 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
454 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | ||
455 | |||
456 | if (rtlhal->fw_ready == false) { | ||
457 | RT_ASSERT(false, | ||
458 | "return H2C cmd because of Fw download fail!!!\n"); | ||
459 | return; | ||
460 | } | ||
461 | |||
462 | _rtl8723ae_fill_h2c_command(hw, element_id, cmd_len, p_cmdbuffer); | ||
463 | return; | ||
464 | } | ||
465 | |||
466 | void rtl8723ae_firmware_selfreset(struct ieee80211_hw *hw) | ||
467 | { | ||
468 | u8 u1tmp; | ||
469 | u8 delay = 100; | ||
470 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
471 | |||
472 | rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20); | ||
473 | u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); | ||
474 | |||
475 | while (u1tmp & BIT(2)) { | ||
476 | delay--; | ||
477 | if (delay == 0) | ||
478 | break; | ||
479 | udelay(50); | ||
480 | u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); | ||
481 | } | ||
482 | if (delay == 0) { | ||
483 | u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); | ||
484 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, u1tmp&(~BIT(2))); | ||
485 | } | ||
486 | } | ||
487 | |||
488 | void rtl8723ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) | ||
489 | { | ||
490 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
491 | u8 u1_h2c_set_pwrmode[3] = { 0 }; | ||
492 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
493 | |||
494 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode); | ||
495 | |||
496 | SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode); | ||
497 | SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1); | ||
498 | SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode, | ||
499 | ppsc->reg_max_lps_awakeintvl); | ||
500 | |||
501 | RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, | ||
502 | "rtl8723ae_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n", | ||
503 | u1_h2c_set_pwrmode, 3); | ||
504 | rtl8723ae_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode); | ||
505 | |||
506 | } | ||
507 | |||
508 | static bool _rtl8723ae_cmd_send_packet(struct ieee80211_hw *hw, | ||
509 | struct sk_buff *skb) | ||
510 | { | ||
511 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
512 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
513 | struct rtl8192_tx_ring *ring; | ||
514 | struct rtl_tx_desc *pdesc; | ||
515 | u8 own; | ||
516 | unsigned long flags; | ||
517 | struct sk_buff *pskb = NULL; | ||
518 | |||
519 | ring = &rtlpci->tx_ring[BEACON_QUEUE]; | ||
520 | |||
521 | pskb = __skb_dequeue(&ring->queue); | ||
522 | if (pskb) | ||
523 | kfree_skb(pskb); | ||
524 | |||
525 | spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); | ||
526 | |||
527 | pdesc = &ring->desc[0]; | ||
528 | own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN); | ||
529 | |||
530 | rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb); | ||
531 | |||
532 | __skb_queue_tail(&ring->queue, skb); | ||
533 | |||
534 | spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); | ||
535 | |||
536 | rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE); | ||
537 | |||
538 | return true; | ||
539 | } | ||
540 | |||
541 | static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = { | ||
542 | /* page 0 beacon */ | ||
543 | 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, | ||
544 | 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, | ||
545 | 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08, | ||
546 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
547 | 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, | ||
548 | 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, | ||
549 | 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, | ||
550 | 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, | ||
551 | 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, | ||
552 | 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, | ||
553 | 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
554 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
555 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
556 | 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, | ||
557 | 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
558 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
559 | |||
560 | /* page 1 beacon */ | ||
561 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
562 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
563 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
564 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
565 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
566 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
567 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
568 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
569 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
570 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
571 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
572 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
573 | 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00, | ||
574 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
575 | 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
576 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
577 | |||
578 | /* page 2 ps-poll */ | ||
579 | 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10, | ||
580 | 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, | ||
581 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
582 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
583 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
584 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
585 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
586 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
587 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
588 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
589 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
590 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
591 | 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00, | ||
592 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, | ||
593 | 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
594 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
595 | |||
596 | /* page 3 null */ | ||
597 | 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, | ||
598 | 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, | ||
599 | 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, | ||
600 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
601 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
602 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
603 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
604 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
605 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
606 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
607 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
608 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
609 | 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00, | ||
610 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, | ||
611 | 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
612 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
613 | |||
614 | /* page 4 probe_resp */ | ||
615 | 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, | ||
616 | 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, | ||
617 | 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, | ||
618 | 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00, | ||
619 | 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, | ||
620 | 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, | ||
621 | 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, | ||
622 | 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, | ||
623 | 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, | ||
624 | 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, | ||
625 | 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
626 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
627 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
628 | 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, | ||
629 | 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
630 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
631 | |||
632 | /* page 5 probe_resp */ | ||
633 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
634 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
635 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
636 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
637 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
638 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
639 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
640 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
641 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
642 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
643 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
644 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
645 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
646 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
647 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
648 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
649 | }; | ||
650 | |||
651 | void rtl8723ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished) | ||
652 | { | ||
653 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
654 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
655 | struct sk_buff *skb = NULL; | ||
656 | |||
657 | u32 totalpacketlen; | ||
658 | bool rtstatus; | ||
659 | u8 u1RsvdPageLoc[3] = { 0 }; | ||
660 | bool dlok = false; | ||
661 | |||
662 | u8 *beacon; | ||
663 | u8 *p_pspoll; | ||
664 | u8 *nullfunc; | ||
665 | u8 *p_probersp; | ||
666 | /*--------------------------------------------------------- | ||
667 | (1) beacon | ||
668 | --------------------------------------------------------- | ||
669 | */ | ||
670 | beacon = &reserved_page_packet[BEACON_PG * 128]; | ||
671 | SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr); | ||
672 | SET_80211_HDR_ADDRESS3(beacon, mac->bssid); | ||
673 | |||
674 | /*------------------------------------------------------- | ||
675 | (2) ps-poll | ||
676 | -------------------------------------------------------- | ||
677 | */ | ||
678 | p_pspoll = &reserved_page_packet[PSPOLL_PG * 128]; | ||
679 | SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000)); | ||
680 | SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid); | ||
681 | SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr); | ||
682 | |||
683 | SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG); | ||
684 | |||
685 | /*-------------------------------------------------------- | ||
686 | (3) null data | ||
687 | ---------------------------------------------------------i | ||
688 | */ | ||
689 | nullfunc = &reserved_page_packet[NULL_PG * 128]; | ||
690 | SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid); | ||
691 | SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr); | ||
692 | SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid); | ||
693 | |||
694 | SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc, NULL_PG); | ||
695 | |||
696 | /*--------------------------------------------------------- | ||
697 | (4) probe response | ||
698 | ---------------------------------------------------------- | ||
699 | */ | ||
700 | p_probersp = &reserved_page_packet[PROBERSP_PG * 128]; | ||
701 | SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid); | ||
702 | SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr); | ||
703 | SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid); | ||
704 | |||
705 | SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG); | ||
706 | |||
707 | totalpacketlen = TOTAL_RESERVED_PKT_LEN; | ||
708 | |||
709 | RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, | ||
710 | "rtl8723ae_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", | ||
711 | &reserved_page_packet[0], totalpacketlen); | ||
712 | RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, | ||
713 | "rtl8723ae_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", | ||
714 | u1RsvdPageLoc, 3); | ||
715 | |||
716 | skb = dev_alloc_skb(totalpacketlen); | ||
717 | memcpy((u8 *) skb_put(skb, totalpacketlen), | ||
718 | &reserved_page_packet, totalpacketlen); | ||
719 | |||
720 | rtstatus = _rtl8723ae_cmd_send_packet(hw, skb); | ||
721 | |||
722 | if (rtstatus) | ||
723 | dlok = true; | ||
724 | |||
725 | if (dlok) { | ||
726 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
727 | "Set RSVD page location to Fw.\n"); | ||
728 | RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, | ||
729 | "H2C_RSVDPAGE:\n", | ||
730 | u1RsvdPageLoc, 3); | ||
731 | rtl8723ae_fill_h2c_cmd(hw, H2C_RSVDPAGE, | ||
732 | sizeof(u1RsvdPageLoc), u1RsvdPageLoc); | ||
733 | } else | ||
734 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | ||
735 | "Set RSVD page location to Fw FAIL!!!!!!.\n"); | ||
736 | } | ||
737 | |||
738 | void rtl8723ae_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus) | ||
739 | { | ||
740 | u8 u1_joinbssrpt_parm[1] = { 0 }; | ||
741 | |||
742 | SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus); | ||
743 | |||
744 | rtl8723ae_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm); | ||
745 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h new file mode 100644 index 000000000000..89994e16dc83 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h | |||
@@ -0,0 +1,101 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 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 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
26 | * | ||
27 | **************************************************************************** | ||
28 | */ | ||
29 | |||
30 | #ifndef __RTL92C__FW__H__ | ||
31 | #define __RTL92C__FW__H__ | ||
32 | |||
33 | #define FW_8192C_START_ADDRESS 0x1000 | ||
34 | #define FW_8192C_END_ADDRESS 0x3FFF | ||
35 | #define FW_8192C_PAGE_SIZE 4096 | ||
36 | #define FW_8192C_POLLING_DELAY 5 | ||
37 | #define FW_8192C_POLLING_TIMEOUT_COUNT 1000 | ||
38 | |||
39 | #define BEACON_PG 0 | ||
40 | #define PSPOLL_PG 2 | ||
41 | #define NULL_PG 3 | ||
42 | #define PROBERSP_PG 4 /* ->5 */ | ||
43 | |||
44 | #define TOTAL_RESERVED_PKT_LEN 768 | ||
45 | |||
46 | #define IS_FW_HEADER_EXIST(_pfwhdr) \ | ||
47 | ((_pfwhdr->signature&0xFF00) == 0x2300) | ||
48 | |||
49 | struct rtl8723ae_firmware_header { | ||
50 | u16 signature; | ||
51 | u8 category; | ||
52 | u8 function; | ||
53 | u16 version; | ||
54 | u8 subversion; | ||
55 | u8 rsvd1; | ||
56 | u8 month; | ||
57 | u8 date; | ||
58 | u8 hour; | ||
59 | u8 minute; | ||
60 | u16 ramcodeSize; | ||
61 | u16 rsvd2; | ||
62 | u32 svnindex; | ||
63 | u32 rsvd3; | ||
64 | u32 rsvd4; | ||
65 | u32 rsvd5; | ||
66 | }; | ||
67 | |||
68 | enum rtl8192c_h2c_cmd { | ||
69 | H2C_AP_OFFLOAD = 0, | ||
70 | H2C_SETPWRMODE = 1, | ||
71 | H2C_JOINBSSRPT = 2, | ||
72 | H2C_RSVDPAGE = 3, | ||
73 | H2C_RSSI_REPORT = 5, | ||
74 | H2C_RA_MASK = 6, | ||
75 | MAX_H2CCMD | ||
76 | }; | ||
77 | |||
78 | #define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \ | ||
79 | SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) | ||
80 | #define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__ph2ccmd, __val) \ | ||
81 | SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val) | ||
82 | #define SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__ph2ccmd, __val) \ | ||
83 | SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val) | ||
84 | #define SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(__ph2ccmd, __val) \ | ||
85 | SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) | ||
86 | #define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val) \ | ||
87 | SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) | ||
88 | #define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val) \ | ||
89 | SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val) | ||
90 | #define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \ | ||
91 | SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val) | ||
92 | |||
93 | int rtl8723ae_download_fw(struct ieee80211_hw *hw); | ||
94 | void rtl8723ae_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, | ||
95 | u32 cmd_len, u8 *p_cmdbuffer); | ||
96 | void rtl8723ae_firmware_selfreset(struct ieee80211_hw *hw); | ||
97 | void rtl8723ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); | ||
98 | void rtl8723ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished); | ||
99 | void rtl8723ae_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus); | ||
100 | |||
101 | #endif | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c new file mode 100644 index 000000000000..3d092e4b0b7f --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c | |||
@@ -0,0 +1,542 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 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 "hal_bt_coexist.h" | ||
31 | #include "../pci.h" | ||
32 | #include "dm.h" | ||
33 | #include "fw.h" | ||
34 | #include "phy.h" | ||
35 | #include "reg.h" | ||
36 | #include "hal_btc.h" | ||
37 | |||
38 | void rtl8723ae_dm_bt_reject_ap_aggregated_packet(struct ieee80211_hw *hw, | ||
39 | bool reject) | ||
40 | { | ||
41 | } | ||
42 | |||
43 | void _rtl8723_dm_bt_check_wifi_state(struct ieee80211_hw *hw) | ||
44 | { | ||
45 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
46 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
47 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
48 | |||
49 | if (rtlpriv->link_info.busytraffic) { | ||
50 | rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_IDLE; | ||
51 | |||
52 | if (rtlpriv->link_info.tx_busy_traffic) | ||
53 | rtlpcipriv->bt_coexist.cstate |= | ||
54 | BT_COEX_STATE_WIFI_UPLINK; | ||
55 | else | ||
56 | rtlpcipriv->bt_coexist.cstate &= | ||
57 | ~BT_COEX_STATE_WIFI_UPLINK; | ||
58 | |||
59 | if (rtlpriv->link_info.rx_busy_traffic) | ||
60 | rtlpcipriv->bt_coexist.cstate |= | ||
61 | BT_COEX_STATE_WIFI_DOWNLINK; | ||
62 | else | ||
63 | rtlpcipriv->bt_coexist.cstate &= | ||
64 | ~BT_COEX_STATE_WIFI_DOWNLINK; | ||
65 | } else { | ||
66 | rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_WIFI_IDLE; | ||
67 | rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_UPLINK; | ||
68 | rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_DOWNLINK; | ||
69 | } | ||
70 | |||
71 | if (rtlpriv->mac80211.mode == WIRELESS_MODE_G || | ||
72 | rtlpriv->mac80211.mode == WIRELESS_MODE_B) { | ||
73 | rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_WIFI_LEGACY; | ||
74 | rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_HT20; | ||
75 | rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_HT40; | ||
76 | } else { | ||
77 | rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_LEGACY; | ||
78 | if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { | ||
79 | rtlpcipriv->bt_coexist.cstate |= | ||
80 | BT_COEX_STATE_WIFI_HT40; | ||
81 | rtlpcipriv->bt_coexist.cstate &= | ||
82 | ~BT_COEX_STATE_WIFI_HT20; | ||
83 | } else { | ||
84 | rtlpcipriv->bt_coexist.cstate |= | ||
85 | BT_COEX_STATE_WIFI_HT20; | ||
86 | rtlpcipriv->bt_coexist.cstate &= | ||
87 | ~BT_COEX_STATE_WIFI_HT40; | ||
88 | } | ||
89 | } | ||
90 | |||
91 | if (rtlpriv->bt_operation_on) | ||
92 | rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_BT30; | ||
93 | else | ||
94 | rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_BT30; | ||
95 | } | ||
96 | |||
97 | u8 rtl8723ae_dm_bt_check_coex_rssi_state1(struct ieee80211_hw *hw, | ||
98 | u8 level_num, u8 rssi_thresh, | ||
99 | u8 rssi_thresh1) | ||
100 | |||
101 | { | ||
102 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
103 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
104 | long smooth; | ||
105 | u8 bt_rssi_state = 0; | ||
106 | |||
107 | smooth = rtl8723ae_dm_bt_get_rx_ss(hw); | ||
108 | |||
109 | if (level_num == 2) { | ||
110 | rtlpcipriv->bt_coexist.cstate &= | ||
111 | ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM; | ||
112 | |||
113 | if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state == | ||
114 | BT_RSSI_STATE_LOW) || | ||
115 | (rtlpcipriv->bt_coexist.bt_pre_rssi_state == | ||
116 | BT_RSSI_STATE_STAY_LOW)) { | ||
117 | if (smooth >= (rssi_thresh + | ||
118 | BT_FW_COEX_THRESH_TOL)) { | ||
119 | bt_rssi_state = BT_RSSI_STATE_HIGH; | ||
120 | rtlpcipriv->bt_coexist.cstate |= | ||
121 | BT_COEX_STATE_WIFI_RSSI_1_HIGH; | ||
122 | rtlpcipriv->bt_coexist.cstate &= | ||
123 | ~BT_COEX_STATE_WIFI_RSSI_1_LOW; | ||
124 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
125 | "[DM][BT], RSSI_1 state switch to High\n"); | ||
126 | } else { | ||
127 | bt_rssi_state = BT_RSSI_STATE_STAY_LOW; | ||
128 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
129 | "[DM][BT], RSSI_1 state stay at Low\n"); | ||
130 | } | ||
131 | } else { | ||
132 | if (smooth < rssi_thresh) { | ||
133 | bt_rssi_state = BT_RSSI_STATE_LOW; | ||
134 | rtlpcipriv->bt_coexist.cstate |= | ||
135 | BT_COEX_STATE_WIFI_RSSI_1_LOW; | ||
136 | rtlpcipriv->bt_coexist.cstate &= | ||
137 | ~BT_COEX_STATE_WIFI_RSSI_1_HIGH; | ||
138 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
139 | "[DM][BT], RSSI_1 state switch to Low\n"); | ||
140 | } else { | ||
141 | bt_rssi_state = BT_RSSI_STATE_STAY_HIGH; | ||
142 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
143 | "[DM][BT], RSSI_1 state stay at High\n"); | ||
144 | } | ||
145 | } | ||
146 | } else if (level_num == 3) { | ||
147 | if (rssi_thresh > rssi_thresh1) { | ||
148 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
149 | "[DM][BT], RSSI_1 thresh error!!\n"); | ||
150 | return rtlpcipriv->bt_coexist.bt_pre_rssi_state; | ||
151 | } | ||
152 | |||
153 | if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state == | ||
154 | BT_RSSI_STATE_LOW) || | ||
155 | (rtlpcipriv->bt_coexist.bt_pre_rssi_state == | ||
156 | BT_RSSI_STATE_STAY_LOW)) { | ||
157 | if (smooth >= | ||
158 | (rssi_thresh+BT_FW_COEX_THRESH_TOL)) { | ||
159 | bt_rssi_state = BT_RSSI_STATE_MEDIUM; | ||
160 | rtlpcipriv->bt_coexist.cstate |= | ||
161 | BT_COEX_STATE_WIFI_RSSI_1_MEDIUM; | ||
162 | rtlpcipriv->bt_coexist.cstate &= | ||
163 | ~BT_COEX_STATE_WIFI_RSSI_1_LOW; | ||
164 | rtlpcipriv->bt_coexist.cstate &= | ||
165 | ~BT_COEX_STATE_WIFI_RSSI_1_HIGH; | ||
166 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
167 | "[DM][BT], RSSI_1 state switch to Medium\n"); | ||
168 | } else { | ||
169 | bt_rssi_state = BT_RSSI_STATE_STAY_LOW; | ||
170 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
171 | "[DM][BT], RSSI_1 state stay at Low\n"); | ||
172 | } | ||
173 | } else if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state == | ||
174 | BT_RSSI_STATE_MEDIUM) || | ||
175 | (rtlpcipriv->bt_coexist.bt_pre_rssi_state == | ||
176 | BT_RSSI_STATE_STAY_MEDIUM)) { | ||
177 | if (smooth >= (rssi_thresh1 + | ||
178 | BT_FW_COEX_THRESH_TOL)) { | ||
179 | bt_rssi_state = BT_RSSI_STATE_HIGH; | ||
180 | rtlpcipriv->bt_coexist.cstate |= | ||
181 | BT_COEX_STATE_WIFI_RSSI_1_HIGH; | ||
182 | rtlpcipriv->bt_coexist.cstate &= | ||
183 | ~BT_COEX_STATE_WIFI_RSSI_1_LOW; | ||
184 | rtlpcipriv->bt_coexist.cstate &= | ||
185 | ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM; | ||
186 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
187 | "[DM][BT], RSSI_1 state switch to High\n"); | ||
188 | } else if (smooth < rssi_thresh) { | ||
189 | bt_rssi_state = BT_RSSI_STATE_LOW; | ||
190 | rtlpcipriv->bt_coexist.cstate |= | ||
191 | BT_COEX_STATE_WIFI_RSSI_1_LOW; | ||
192 | rtlpcipriv->bt_coexist.cstate &= | ||
193 | ~BT_COEX_STATE_WIFI_RSSI_1_HIGH; | ||
194 | rtlpcipriv->bt_coexist.cstate &= | ||
195 | ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM; | ||
196 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
197 | "[DM][BT], RSSI_1 state switch to Low\n"); | ||
198 | } else { | ||
199 | bt_rssi_state = BT_RSSI_STATE_STAY_MEDIUM; | ||
200 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
201 | "[DM][BT], RSSI_1 state stay at Medium\n"); | ||
202 | } | ||
203 | } else { | ||
204 | if (smooth < rssi_thresh1) { | ||
205 | bt_rssi_state = BT_RSSI_STATE_MEDIUM; | ||
206 | rtlpcipriv->bt_coexist.cstate |= | ||
207 | BT_COEX_STATE_WIFI_RSSI_1_MEDIUM; | ||
208 | rtlpcipriv->bt_coexist.cstate &= | ||
209 | ~BT_COEX_STATE_WIFI_RSSI_1_HIGH; | ||
210 | rtlpcipriv->bt_coexist.cstate &= | ||
211 | ~BT_COEX_STATE_WIFI_RSSI_1_LOW; | ||
212 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
213 | "[DM][BT], RSSI_1 state switch to Medium\n"); | ||
214 | } else { | ||
215 | bt_rssi_state = BT_RSSI_STATE_STAY_HIGH; | ||
216 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
217 | "[DM][BT], RSSI_1 state stay at High\n"); | ||
218 | } | ||
219 | } | ||
220 | } | ||
221 | |||
222 | rtlpcipriv->bt_coexist.bt_pre_rssi_state1 = bt_rssi_state; | ||
223 | |||
224 | return bt_rssi_state; | ||
225 | } | ||
226 | |||
227 | u8 rtl8723ae_dm_bt_check_coex_rssi_state(struct ieee80211_hw *hw, | ||
228 | u8 level_num, u8 rssi_thresh, | ||
229 | u8 rssi_thresh1) | ||
230 | { | ||
231 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
232 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
233 | long smooth; | ||
234 | u8 bt_rssi_state = 0; | ||
235 | |||
236 | smooth = rtl8723ae_dm_bt_get_rx_ss(hw); | ||
237 | |||
238 | if (level_num == 2) { | ||
239 | rtlpcipriv->bt_coexist.cstate &= | ||
240 | ~BT_COEX_STATE_WIFI_RSSI_MEDIUM; | ||
241 | |||
242 | if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state == | ||
243 | BT_RSSI_STATE_LOW) || | ||
244 | (rtlpcipriv->bt_coexist.bt_pre_rssi_state == | ||
245 | BT_RSSI_STATE_STAY_LOW)){ | ||
246 | if (smooth >= | ||
247 | (rssi_thresh + BT_FW_COEX_THRESH_TOL)) { | ||
248 | bt_rssi_state = BT_RSSI_STATE_HIGH; | ||
249 | rtlpcipriv->bt_coexist.cstate |= | ||
250 | BT_COEX_STATE_WIFI_RSSI_HIGH; | ||
251 | rtlpcipriv->bt_coexist.cstate &= | ||
252 | ~BT_COEX_STATE_WIFI_RSSI_LOW; | ||
253 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
254 | "[DM][BT], RSSI state switch to High\n"); | ||
255 | } else { | ||
256 | bt_rssi_state = BT_RSSI_STATE_STAY_LOW; | ||
257 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
258 | "[DM][BT], RSSI state stay at Low\n"); | ||
259 | } | ||
260 | } else { | ||
261 | if (smooth < rssi_thresh) { | ||
262 | bt_rssi_state = BT_RSSI_STATE_LOW; | ||
263 | rtlpcipriv->bt_coexist.cstate |= | ||
264 | BT_COEX_STATE_WIFI_RSSI_LOW; | ||
265 | rtlpcipriv->bt_coexist.cstate &= | ||
266 | ~BT_COEX_STATE_WIFI_RSSI_HIGH; | ||
267 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
268 | "[DM][BT], RSSI state switch to Low\n"); | ||
269 | } else { | ||
270 | bt_rssi_state = BT_RSSI_STATE_STAY_HIGH; | ||
271 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
272 | "[DM][BT], RSSI state stay at High\n"); | ||
273 | } | ||
274 | } | ||
275 | } else if (level_num == 3) { | ||
276 | if (rssi_thresh > rssi_thresh1) { | ||
277 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
278 | "[DM][BT], RSSI thresh error!!\n"); | ||
279 | return rtlpcipriv->bt_coexist.bt_pre_rssi_state; | ||
280 | } | ||
281 | if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state == | ||
282 | BT_RSSI_STATE_LOW) || | ||
283 | (rtlpcipriv->bt_coexist.bt_pre_rssi_state == | ||
284 | BT_RSSI_STATE_STAY_LOW)) { | ||
285 | if (smooth >= | ||
286 | (rssi_thresh + BT_FW_COEX_THRESH_TOL)) { | ||
287 | bt_rssi_state = BT_RSSI_STATE_MEDIUM; | ||
288 | rtlpcipriv->bt_coexist.cstate | ||
289 | |= BT_COEX_STATE_WIFI_RSSI_MEDIUM; | ||
290 | rtlpcipriv->bt_coexist.cstate | ||
291 | &= ~BT_COEX_STATE_WIFI_RSSI_LOW; | ||
292 | rtlpcipriv->bt_coexist.cstate | ||
293 | &= ~BT_COEX_STATE_WIFI_RSSI_HIGH; | ||
294 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
295 | "[DM][BT], RSSI state switch to Medium\n"); | ||
296 | } else { | ||
297 | bt_rssi_state = BT_RSSI_STATE_STAY_LOW; | ||
298 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
299 | "[DM][BT], RSSI state stay at Low\n"); | ||
300 | } | ||
301 | } else if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state == | ||
302 | BT_RSSI_STATE_MEDIUM) || | ||
303 | (rtlpcipriv->bt_coexist.bt_pre_rssi_state == | ||
304 | BT_RSSI_STATE_STAY_MEDIUM)) { | ||
305 | if (smooth >= | ||
306 | (rssi_thresh1 + BT_FW_COEX_THRESH_TOL)) { | ||
307 | bt_rssi_state = BT_RSSI_STATE_HIGH; | ||
308 | rtlpcipriv->bt_coexist.cstate | ||
309 | |= BT_COEX_STATE_WIFI_RSSI_HIGH; | ||
310 | rtlpcipriv->bt_coexist.cstate | ||
311 | &= ~BT_COEX_STATE_WIFI_RSSI_LOW; | ||
312 | rtlpcipriv->bt_coexist.cstate | ||
313 | &= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM; | ||
314 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
315 | "[DM][BT], RSSI state switch to High\n"); | ||
316 | } else if (smooth < rssi_thresh) { | ||
317 | bt_rssi_state = BT_RSSI_STATE_LOW; | ||
318 | rtlpcipriv->bt_coexist.cstate | ||
319 | |= BT_COEX_STATE_WIFI_RSSI_LOW; | ||
320 | rtlpcipriv->bt_coexist.cstate | ||
321 | &= ~BT_COEX_STATE_WIFI_RSSI_HIGH; | ||
322 | rtlpcipriv->bt_coexist.cstate | ||
323 | &= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM; | ||
324 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
325 | "[DM][BT], RSSI state switch to Low\n"); | ||
326 | } else { | ||
327 | bt_rssi_state = BT_RSSI_STATE_STAY_MEDIUM; | ||
328 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
329 | "[DM][BT], RSSI state stay at Medium\n"); | ||
330 | } | ||
331 | } else { | ||
332 | if (smooth < rssi_thresh1) { | ||
333 | bt_rssi_state = BT_RSSI_STATE_MEDIUM; | ||
334 | rtlpcipriv->bt_coexist.cstate | ||
335 | |= BT_COEX_STATE_WIFI_RSSI_MEDIUM; | ||
336 | rtlpcipriv->bt_coexist.cstate | ||
337 | &= ~BT_COEX_STATE_WIFI_RSSI_HIGH; | ||
338 | rtlpcipriv->bt_coexist.cstate | ||
339 | &= ~BT_COEX_STATE_WIFI_RSSI_LOW; | ||
340 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
341 | "[DM][BT], RSSI state switch to Medium\n"); | ||
342 | } else { | ||
343 | bt_rssi_state = BT_RSSI_STATE_STAY_HIGH; | ||
344 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
345 | "[DM][BT], RSSI state stay at High\n"); | ||
346 | } | ||
347 | } | ||
348 | } | ||
349 | |||
350 | rtlpcipriv->bt_coexist.bt_pre_rssi_state = bt_rssi_state; | ||
351 | return bt_rssi_state; | ||
352 | } | ||
353 | |||
354 | long rtl8723ae_dm_bt_get_rx_ss(struct ieee80211_hw *hw) | ||
355 | { | ||
356 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
357 | long smooth = 0; | ||
358 | |||
359 | if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) | ||
360 | smooth = GET_UNDECORATED_AVERAGE_RSSI(rtlpriv); | ||
361 | else | ||
362 | smooth = rtlpriv->dm.entry_min_undec_sm_pwdb; | ||
363 | |||
364 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
365 | "rtl8723ae_dm_bt_get_rx_ss() = %ld\n", smooth); | ||
366 | |||
367 | return smooth; | ||
368 | } | ||
369 | |||
370 | void rtl8723ae_dm_bt_balance(struct ieee80211_hw *hw, | ||
371 | bool balance_on, u8 ms0, u8 ms1) | ||
372 | { | ||
373 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
374 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
375 | u8 h2c_parameter[3] = {0}; | ||
376 | |||
377 | if (balance_on) { | ||
378 | h2c_parameter[2] = 1; | ||
379 | h2c_parameter[1] = ms1; | ||
380 | h2c_parameter[0] = ms0; | ||
381 | rtlpcipriv->bt_coexist.fw_coexist_all_off = false; | ||
382 | } else { | ||
383 | h2c_parameter[2] = 0; | ||
384 | h2c_parameter[1] = 0; | ||
385 | h2c_parameter[0] = 0; | ||
386 | } | ||
387 | rtlpcipriv->bt_coexist.balance_on = balance_on; | ||
388 | |||
389 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
390 | "[DM][BT], Balance=[%s:%dms:%dms], write 0xc=0x%x\n", | ||
391 | balance_on ? "ON" : "OFF", ms0, ms1, | ||
392 | h2c_parameter[0]<<16 | h2c_parameter[1]<<8 | h2c_parameter[2]); | ||
393 | |||
394 | rtl8723ae_fill_h2c_cmd(hw, 0xc, 3, h2c_parameter); | ||
395 | } | ||
396 | |||
397 | |||
398 | void rtl8723ae_dm_bt_agc_table(struct ieee80211_hw *hw, u8 type) | ||
399 | { | ||
400 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
401 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
402 | |||
403 | if (type == BT_AGCTABLE_OFF) { | ||
404 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
405 | "[BT]AGCTable Off!\n"); | ||
406 | rtl_write_dword(rtlpriv, 0xc78, 0x641c0001); | ||
407 | rtl_write_dword(rtlpriv, 0xc78, 0x631d0001); | ||
408 | rtl_write_dword(rtlpriv, 0xc78, 0x621e0001); | ||
409 | rtl_write_dword(rtlpriv, 0xc78, 0x611f0001); | ||
410 | rtl_write_dword(rtlpriv, 0xc78, 0x60200001); | ||
411 | |||
412 | rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, | ||
413 | RF_RX_AGC_HP, 0xfffff, 0x32000); | ||
414 | rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, | ||
415 | RF_RX_AGC_HP, 0xfffff, 0x71000); | ||
416 | rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, | ||
417 | RF_RX_AGC_HP, 0xfffff, 0xb0000); | ||
418 | rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, | ||
419 | RF_RX_AGC_HP, 0xfffff, 0xfc000); | ||
420 | rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, | ||
421 | RF_RX_G1, 0xfffff, 0x30355); | ||
422 | } else if (type == BT_AGCTABLE_ON) { | ||
423 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
424 | "[BT]AGCTable On!\n"); | ||
425 | rtl_write_dword(rtlpriv, 0xc78, 0x4e1c0001); | ||
426 | rtl_write_dword(rtlpriv, 0xc78, 0x4d1d0001); | ||
427 | rtl_write_dword(rtlpriv, 0xc78, 0x4c1e0001); | ||
428 | rtl_write_dword(rtlpriv, 0xc78, 0x4b1f0001); | ||
429 | rtl_write_dword(rtlpriv, 0xc78, 0x4a200001); | ||
430 | |||
431 | rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, | ||
432 | RF_RX_AGC_HP, 0xfffff, 0xdc000); | ||
433 | rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, | ||
434 | RF_RX_AGC_HP, 0xfffff, 0x90000); | ||
435 | rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, | ||
436 | RF_RX_AGC_HP, 0xfffff, 0x51000); | ||
437 | rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, | ||
438 | RF_RX_AGC_HP, 0xfffff, 0x12000); | ||
439 | rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, | ||
440 | RF_RX_G1, 0xfffff, 0x00355); | ||
441 | |||
442 | rtlpcipriv->bt_coexist.sw_coexist_all_off = false; | ||
443 | } | ||
444 | } | ||
445 | |||
446 | void rtl8723ae_dm_bt_bback_off_level(struct ieee80211_hw *hw, u8 type) | ||
447 | { | ||
448 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
449 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
450 | |||
451 | if (type == BT_BB_BACKOFF_OFF) { | ||
452 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
453 | "[BT]BBBackOffLevel Off!\n"); | ||
454 | rtl_write_dword(rtlpriv, 0xc04, 0x3a05611); | ||
455 | } else if (type == BT_BB_BACKOFF_ON) { | ||
456 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
457 | "[BT]BBBackOffLevel On!\n"); | ||
458 | rtl_write_dword(rtlpriv, 0xc04, 0x3a07611); | ||
459 | rtlpcipriv->bt_coexist.sw_coexist_all_off = false; | ||
460 | } | ||
461 | } | ||
462 | |||
463 | void rtl8723ae_dm_bt_fw_coex_all_off(struct ieee80211_hw *hw) | ||
464 | { | ||
465 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
466 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
467 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
468 | "rtl8723ae_dm_bt_fw_coex_all_off()\n"); | ||
469 | |||
470 | if (rtlpcipriv->bt_coexist.fw_coexist_all_off) | ||
471 | return; | ||
472 | |||
473 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
474 | "rtl8723ae_dm_bt_fw_coex_all_off(), real Do\n"); | ||
475 | rtl8723ae_dm_bt_fw_coex_all_off_8723a(hw); | ||
476 | rtlpcipriv->bt_coexist.fw_coexist_all_off = true; | ||
477 | } | ||
478 | |||
479 | void rtl8723ae_dm_bt_sw_coex_all_off(struct ieee80211_hw *hw) | ||
480 | { | ||
481 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
482 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
483 | |||
484 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
485 | "rtl8723ae_dm_bt_sw_coex_all_off()\n"); | ||
486 | |||
487 | if (rtlpcipriv->bt_coexist.sw_coexist_all_off) | ||
488 | return; | ||
489 | |||
490 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
491 | "rtl8723ae_dm_bt_sw_coex_all_off(), real Do\n"); | ||
492 | rtl8723ae_dm_bt_sw_coex_all_off_8723a(hw); | ||
493 | rtlpcipriv->bt_coexist.sw_coexist_all_off = true; | ||
494 | } | ||
495 | |||
496 | void rtl8723ae_dm_bt_hw_coex_all_off(struct ieee80211_hw *hw) | ||
497 | { | ||
498 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
499 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
500 | |||
501 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
502 | "rtl8723ae_dm_bt_hw_coex_all_off()\n"); | ||
503 | |||
504 | if (rtlpcipriv->bt_coexist.hw_coexist_all_off) | ||
505 | return; | ||
506 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
507 | "rtl8723ae_dm_bt_hw_coex_all_off(), real Do\n"); | ||
508 | |||
509 | rtl8723ae_dm_bt_hw_coex_all_off_8723a(hw); | ||
510 | |||
511 | rtlpcipriv->bt_coexist.hw_coexist_all_off = true; | ||
512 | } | ||
513 | |||
514 | void rtl8723ae_btdm_coex_all_off(struct ieee80211_hw *hw) | ||
515 | { | ||
516 | rtl8723ae_dm_bt_fw_coex_all_off(hw); | ||
517 | rtl8723ae_dm_bt_sw_coex_all_off(hw); | ||
518 | rtl8723ae_dm_bt_hw_coex_all_off(hw); | ||
519 | } | ||
520 | |||
521 | bool rtl8723ae_dm_bt_is_coexist_state_changed(struct ieee80211_hw *hw) | ||
522 | { | ||
523 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
524 | |||
525 | if ((rtlpcipriv->bt_coexist.previous_state == | ||
526 | rtlpcipriv->bt_coexist.cstate) && | ||
527 | (rtlpcipriv->bt_coexist.previous_state_h == | ||
528 | rtlpcipriv->bt_coexist.cstate_h)) | ||
529 | return false; | ||
530 | else | ||
531 | return true; | ||
532 | } | ||
533 | |||
534 | bool rtl8723ae_dm_bt_is_wifi_up_link(struct ieee80211_hw *hw) | ||
535 | { | ||
536 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
537 | |||
538 | if (rtlpriv->link_info.tx_busy_traffic) | ||
539 | return true; | ||
540 | else | ||
541 | return false; | ||
542 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.h b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.h new file mode 100644 index 000000000000..76f4d122dbc1 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.h | |||
@@ -0,0 +1,160 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 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 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
26 | * | ||
27 | *****************************************************************************/ | ||
28 | |||
29 | #ifndef __RTL8723E_HAL_BT_COEXIST_H__ | ||
30 | #define __RTL8723E_HAL_BT_COEXIST_H__ | ||
31 | |||
32 | #include "../wifi.h" | ||
33 | |||
34 | /* The reg define is for 8723 */ | ||
35 | #define REG_HIGH_PRIORITY_TXRX 0x770 | ||
36 | #define REG_LOW_PRIORITY_TXRX 0x774 | ||
37 | |||
38 | #define BT_FW_COEX_THRESH_TOL 6 | ||
39 | #define BT_FW_COEX_THRESH_20 20 | ||
40 | #define BT_FW_COEX_THRESH_23 23 | ||
41 | #define BT_FW_COEX_THRESH_25 25 | ||
42 | #define BT_FW_COEX_THRESH_30 30 | ||
43 | #define BT_FW_COEX_THRESH_35 35 | ||
44 | #define BT_FW_COEX_THRESH_40 40 | ||
45 | #define BT_FW_COEX_THRESH_45 45 | ||
46 | #define BT_FW_COEX_THRESH_47 47 | ||
47 | #define BT_FW_COEX_THRESH_50 50 | ||
48 | #define BT_FW_COEX_THRESH_55 55 | ||
49 | |||
50 | #define BT_COEX_STATE_BT30 BIT(0) | ||
51 | #define BT_COEX_STATE_WIFI_HT20 BIT(1) | ||
52 | #define BT_COEX_STATE_WIFI_HT40 BIT(2) | ||
53 | #define BT_COEX_STATE_WIFI_LEGACY BIT(3) | ||
54 | |||
55 | #define BT_COEX_STATE_WIFI_RSSI_LOW BIT(4) | ||
56 | #define BT_COEX_STATE_WIFI_RSSI_MEDIUM BIT(5) | ||
57 | #define BT_COEX_STATE_WIFI_RSSI_HIGH BIT(6) | ||
58 | #define BT_COEX_STATE_DEC_BT_POWER BIT(7) | ||
59 | |||
60 | #define BT_COEX_STATE_WIFI_IDLE BIT(8) | ||
61 | #define BT_COEX_STATE_WIFI_UPLINK BIT(9) | ||
62 | #define BT_COEX_STATE_WIFI_DOWNLINK BIT(10) | ||
63 | |||
64 | #define BT_COEX_STATE_BT_INQ_PAGE BIT(11) | ||
65 | #define BT_COEX_STATE_BT_IDLE BIT(12) | ||
66 | #define BT_COEX_STATE_BT_UPLINK BIT(13) | ||
67 | #define BT_COEX_STATE_BT_DOWNLINK BIT(14) | ||
68 | |||
69 | #define BT_COEX_STATE_HOLD_FOR_BT_OPERATION BIT(15) | ||
70 | #define BT_COEX_STATE_BT_RSSI_LOW BIT(19) | ||
71 | |||
72 | #define BT_COEX_STATE_PROFILE_HID BIT(20) | ||
73 | #define BT_COEX_STATE_PROFILE_A2DP BIT(21) | ||
74 | #define BT_COEX_STATE_PROFILE_PAN BIT(22) | ||
75 | #define BT_COEX_STATE_PROFILE_SCO BIT(23) | ||
76 | |||
77 | #define BT_COEX_STATE_WIFI_RSSI_1_LOW BIT(24) | ||
78 | #define BT_COEX_STATE_WIFI_RSSI_1_MEDIUM BIT(25) | ||
79 | #define BT_COEX_STATE_WIFI_RSSI_1_HIGH BIT(26) | ||
80 | |||
81 | #define BT_COEX_STATE_BTINFO_COMMON BIT(30) | ||
82 | #define BT_COEX_STATE_BTINFO_B_HID_SCOESCO BIT(31) | ||
83 | #define BT_COEX_STATE_BTINFO_B_FTP_A2DP BIT(29) | ||
84 | |||
85 | #define BT_COEX_STATE_BT_CNT_LEVEL_0 BIT(0) | ||
86 | #define BT_COEX_STATE_BT_CNT_LEVEL_1 BIT(1) | ||
87 | #define BT_COEX_STATE_BT_CNT_LEVEL_2 BIT(2) | ||
88 | #define BT_COEX_STATE_BT_CNT_LEVEL_3 BIT(3) | ||
89 | |||
90 | #define BT_RSSI_STATE_HIGH 0 | ||
91 | #define BT_RSSI_STATE_MEDIUM 1 | ||
92 | #define BT_RSSI_STATE_LOW 2 | ||
93 | #define BT_RSSI_STATE_STAY_HIGH 3 | ||
94 | #define BT_RSSI_STATE_STAY_MEDIUM 4 | ||
95 | #define BT_RSSI_STATE_STAY_LOW 5 | ||
96 | |||
97 | #define BT_AGCTABLE_OFF 0 | ||
98 | #define BT_AGCTABLE_ON 1 | ||
99 | #define BT_BB_BACKOFF_OFF 0 | ||
100 | #define BT_BB_BACKOFF_ON 1 | ||
101 | #define BT_FW_NAV_OFF 0 | ||
102 | #define BT_FW_NAV_ON 1 | ||
103 | |||
104 | #define BT_COEX_MECH_NONE 0 | ||
105 | #define BT_COEX_MECH_SCO 1 | ||
106 | #define BT_COEX_MECH_HID 2 | ||
107 | #define BT_COEX_MECH_A2DP 3 | ||
108 | #define BT_COEX_MECH_PAN 4 | ||
109 | #define BT_COEX_MECH_HID_A2DP 5 | ||
110 | #define BT_COEX_MECH_HID_PAN 6 | ||
111 | #define BT_COEX_MECH_PAN_A2DP 7 | ||
112 | #define BT_COEX_MECH_HID_SCO_ESCO 8 | ||
113 | #define BT_COEX_MECH_FTP_A2DP 9 | ||
114 | #define BT_COEX_MECH_COMMON 10 | ||
115 | #define BT_COEX_MECH_MAX 11 | ||
116 | |||
117 | #define BT_DBG_PROFILE_NONE 0 | ||
118 | #define BT_DBG_PROFILE_SCO 1 | ||
119 | #define BT_DBG_PROFILE_HID 2 | ||
120 | #define BT_DBG_PROFILE_A2DP 3 | ||
121 | #define BT_DBG_PROFILE_PAN 4 | ||
122 | #define BT_DBG_PROFILE_HID_A2DP 5 | ||
123 | #define BT_DBG_PROFILE_HID_PAN 6 | ||
124 | #define BT_DBG_PROFILE_PAN_A2DP 7 | ||
125 | #define BT_DBG_PROFILE_MAX 9 | ||
126 | |||
127 | #define BTINFO_B_FTP BIT(7) | ||
128 | #define BTINFO_B_A2DP BIT(6) | ||
129 | #define BTINFO_B_HID BIT(5) | ||
130 | #define BTINFO_B_SCO_BUSY BIT(4) | ||
131 | #define BTINFO_B_ACL_BUSY BIT(3) | ||
132 | #define BTINFO_B_INQ_PAGE BIT(2) | ||
133 | #define BTINFO_B_SCO_ESCO BIT(1) | ||
134 | #define BTINFO_B_CONNECTION BIT(0) | ||
135 | |||
136 | |||
137 | void rtl8723ae_btdm_coex_all_off(struct ieee80211_hw *hw); | ||
138 | void rtl8723ae_dm_bt_fw_coex_all_off(struct ieee80211_hw *hw); | ||
139 | |||
140 | void rtl8723ae_dm_bt_sw_coex_all_off(struct ieee80211_hw *hw); | ||
141 | void rtl8723ae_dm_bt_hw_coex_all_off(struct ieee80211_hw *hw); | ||
142 | long rtl8723ae_dm_bt_get_rx_ss(struct ieee80211_hw *hw); | ||
143 | void rtl8723ae_dm_bt_balance(struct ieee80211_hw *hw, | ||
144 | bool balance_on, u8 ms0, u8 ms1); | ||
145 | void rtl8723ae_dm_bt_agc_table(struct ieee80211_hw *hw, u8 type); | ||
146 | void rtl8723ae_dm_bt_bback_off_level(struct ieee80211_hw *hw, u8 type); | ||
147 | u8 rtl8723ae_dm_bt_check_coex_rssi_state(struct ieee80211_hw *hw, | ||
148 | u8 level_num, u8 rssi_thresh, | ||
149 | u8 rssi_thresh1); | ||
150 | u8 rtl8723ae_dm_bt_check_coex_rssi_state1(struct ieee80211_hw *hw, | ||
151 | u8 level_num, u8 rssi_thresh, | ||
152 | u8 rssi_thresh1); | ||
153 | void _rtl8723_dm_bt_check_wifi_state(struct ieee80211_hw *hw); | ||
154 | void rtl8723ae_dm_bt_reject_ap_aggregated_packet(struct ieee80211_hw *hw, | ||
155 | bool reject); | ||
156 | |||
157 | bool rtl8723ae_dm_bt_is_coexist_state_changed(struct ieee80211_hw *hw); | ||
158 | bool rtl8723ae_dm_bt_is_wifi_up_link(struct ieee80211_hw *hw); | ||
159 | |||
160 | #endif | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c new file mode 100644 index 000000000000..887d521fe690 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c | |||
@@ -0,0 +1,1786 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 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 "hal_btc.h" | ||
31 | #include "../pci.h" | ||
32 | #include "phy.h" | ||
33 | #include "fw.h" | ||
34 | #include "reg.h" | ||
35 | #include "def.h" | ||
36 | |||
37 | void rtl8723ae_bt_coex_off_before_lps(struct ieee80211_hw *hw) | ||
38 | { | ||
39 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
40 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
41 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
42 | |||
43 | if (!rtlpcipriv->bt_coexist.bt_coexistence) | ||
44 | return; | ||
45 | |||
46 | if (ppsc->inactiveps) { | ||
47 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
48 | "[BT][DM], Before enter IPS, turn off all Coexist DM\n"); | ||
49 | rtlpcipriv->bt_coexist.cstate = 0; | ||
50 | rtlpcipriv->bt_coexist.previous_state = 0; | ||
51 | rtlpcipriv->bt_coexist.cstate_h = 0; | ||
52 | rtlpcipriv->bt_coexist.previous_state_h = 0; | ||
53 | rtl8723ae_btdm_coex_all_off(hw); | ||
54 | } | ||
55 | } | ||
56 | |||
57 | static enum _RT_MEDIA_STATUS mgnt_link_status_query(struct ieee80211_hw *hw) | ||
58 | { | ||
59 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
60 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
61 | enum _RT_MEDIA_STATUS m_status = RT_MEDIA_DISCONNECT; | ||
62 | |||
63 | u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0; | ||
64 | |||
65 | if (bibss || rtlpriv->mac80211.link_state >= MAC80211_LINKED) | ||
66 | m_status = RT_MEDIA_CONNECT; | ||
67 | |||
68 | return m_status; | ||
69 | } | ||
70 | |||
71 | void rtl_8723e_bt_wifi_media_status_notify(struct ieee80211_hw *hw, | ||
72 | bool mstatus) | ||
73 | { | ||
74 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
75 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
76 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
77 | u8 h2c_parameter[3] = {0}; | ||
78 | u8 chnl; | ||
79 | |||
80 | if (!rtlpcipriv->bt_coexist.bt_coexistence) | ||
81 | return; | ||
82 | |||
83 | if (RT_MEDIA_CONNECT == mstatus) | ||
84 | h2c_parameter[0] = 0x1; /* 0: disconnected, 1:connected */ | ||
85 | else | ||
86 | h2c_parameter[0] = 0x0; | ||
87 | |||
88 | if (mgnt_link_status_query(hw)) { | ||
89 | chnl = rtlphy->current_channel; | ||
90 | h2c_parameter[1] = chnl; | ||
91 | } | ||
92 | |||
93 | if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) | ||
94 | h2c_parameter[2] = 0x30; | ||
95 | else | ||
96 | h2c_parameter[2] = 0x20; | ||
97 | |||
98 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
99 | "[BTCoex], FW write 0x19 = 0x%x\n", | ||
100 | h2c_parameter[0]<<16|h2c_parameter[1]<<8|h2c_parameter[2]); | ||
101 | |||
102 | rtl8723ae_fill_h2c_cmd(hw, 0x19, 3, h2c_parameter); | ||
103 | |||
104 | } | ||
105 | |||
106 | static bool rtl8723ae_dm_bt_is_wifi_busy(struct ieee80211_hw *hw) | ||
107 | { | ||
108 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
109 | if (rtlpriv->link_info.busytraffic || | ||
110 | rtlpriv->link_info.rx_busy_traffic || | ||
111 | rtlpriv->link_info.tx_busy_traffic) | ||
112 | return true; | ||
113 | else | ||
114 | return false; | ||
115 | } | ||
116 | |||
117 | static void rtl8723ae_dm_bt_set_fw_3a(struct ieee80211_hw *hw, | ||
118 | u8 byte1, u8 byte2, u8 byte3, | ||
119 | u8 byte4, u8 byte5) | ||
120 | { | ||
121 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
122 | u8 h2c_parameter[5] = {0}; | ||
123 | |||
124 | h2c_parameter[0] = byte1; | ||
125 | h2c_parameter[1] = byte2; | ||
126 | h2c_parameter[2] = byte3; | ||
127 | h2c_parameter[3] = byte4; | ||
128 | h2c_parameter[4] = byte5; | ||
129 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
130 | "[BTCoex], FW write 0x3a(4bytes) = 0x%x%8x\n", | ||
131 | h2c_parameter[0], h2c_parameter[1]<<24 | h2c_parameter[2]<<16 | | ||
132 | h2c_parameter[3]<<8 | h2c_parameter[4]); | ||
133 | rtl8723ae_fill_h2c_cmd(hw, 0x3a, 5, h2c_parameter); | ||
134 | } | ||
135 | |||
136 | static bool rtl8723ae_dm_bt_need_to_dec_bt_pwr(struct ieee80211_hw *hw) | ||
137 | { | ||
138 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
139 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
140 | |||
141 | if (mgnt_link_status_query(hw) == RT_MEDIA_CONNECT) { | ||
142 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
143 | "Need to decrease bt power\n"); | ||
144 | rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_DEC_BT_POWER; | ||
145 | return true; | ||
146 | } | ||
147 | |||
148 | rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_DEC_BT_POWER; | ||
149 | return false; | ||
150 | } | ||
151 | |||
152 | static bool rtl8723ae_dm_bt_is_same_coexist_state(struct ieee80211_hw *hw) | ||
153 | { | ||
154 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
155 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
156 | |||
157 | if ((rtlpcipriv->bt_coexist.previous_state == | ||
158 | rtlpcipriv->bt_coexist.cstate) && | ||
159 | (rtlpcipriv->bt_coexist.previous_state_h == | ||
160 | rtlpcipriv->bt_coexist.cstate_h)) { | ||
161 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
162 | "[DM][BT], Coexist state do not chang!!\n"); | ||
163 | return true; | ||
164 | } else { | ||
165 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
166 | "[DM][BT], Coexist state changed!!\n"); | ||
167 | return false; | ||
168 | } | ||
169 | } | ||
170 | |||
171 | static void rtl8723ae_dm_bt_set_coex_table(struct ieee80211_hw *hw, | ||
172 | u32 val_0x6c0, u32 val_0x6c8, | ||
173 | u32 val_0x6cc) | ||
174 | { | ||
175 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
176 | |||
177 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
178 | "set coex table, set 0x6c0 = 0x%x\n", val_0x6c0); | ||
179 | rtl_write_dword(rtlpriv, 0x6c0, val_0x6c0); | ||
180 | |||
181 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
182 | "set coex table, set 0x6c8 = 0x%x\n", val_0x6c8); | ||
183 | rtl_write_dword(rtlpriv, 0x6c8, val_0x6c8); | ||
184 | |||
185 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
186 | "set coex table, set 0x6cc = 0x%x\n", val_0x6cc); | ||
187 | rtl_write_byte(rtlpriv, 0x6cc, val_0x6cc); | ||
188 | } | ||
189 | |||
190 | static void rtl8723ae_dm_bt_set_hw_pta_mode(struct ieee80211_hw *hw, bool mode) | ||
191 | { | ||
192 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
193 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
194 | |||
195 | if (BT_PTA_MODE_ON == mode) { | ||
196 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, "PTA mode on, "); | ||
197 | /* Enable GPIO 0/1/2/3/8 pins for bt */ | ||
198 | rtl_write_byte(rtlpriv, 0x40, 0x20); | ||
199 | rtlpcipriv->bt_coexist.hw_coexist_all_off = false; | ||
200 | } else { | ||
201 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, "PTA mode off\n"); | ||
202 | rtl_write_byte(rtlpriv, 0x40, 0x0); | ||
203 | } | ||
204 | } | ||
205 | |||
206 | static void rtl8723ae_dm_bt_set_sw_rf_rx_lpf_corner(struct ieee80211_hw *hw, | ||
207 | u8 type) | ||
208 | { | ||
209 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
210 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
211 | |||
212 | if (BT_RF_RX_LPF_CORNER_SHRINK == type) { | ||
213 | /* Shrink RF Rx LPF corner, 0x1e[7:4]=1111 ==> [11:4] by Jenyu*/ | ||
214 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
215 | "Shrink RF Rx LPF corner!!\n"); | ||
216 | rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, 0x1e, 0xfffff, | ||
217 | 0xf0ff7); | ||
218 | rtlpcipriv->bt_coexist.sw_coexist_all_off = false; | ||
219 | } else if (BT_RF_RX_LPF_CORNER_RESUME == type) { | ||
220 | /*Resume RF Rx LPF corner*/ | ||
221 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
222 | "Resume RF Rx LPF corner!!\n"); | ||
223 | rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, 0x1e, 0xfffff, | ||
224 | rtlpcipriv->bt_coexist.bt_rfreg_origin_1e); | ||
225 | } | ||
226 | } | ||
227 | |||
228 | static void rtl8723ae_bt_set_penalty_tx_rate_adap(struct ieee80211_hw *hw, | ||
229 | u8 ra_type) | ||
230 | { | ||
231 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
232 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
233 | u8 tmu1; | ||
234 | |||
235 | tmu1 = rtl_read_byte(rtlpriv, 0x4fd); | ||
236 | tmu1 |= BIT(0); | ||
237 | if (BT_TX_RATE_ADAPTIVE_LOW_PENALTY == ra_type) { | ||
238 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
239 | "Tx rate adaptive, set low penalty!!\n"); | ||
240 | tmu1 &= ~BIT(2); | ||
241 | rtlpcipriv->bt_coexist.sw_coexist_all_off = false; | ||
242 | } else if (BT_TX_RATE_ADAPTIVE_NORMAL == ra_type) { | ||
243 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
244 | "Tx rate adaptive, set normal!!\n"); | ||
245 | tmu1 |= BIT(2); | ||
246 | } | ||
247 | rtl_write_byte(rtlpriv, 0x4fd, tmu1); | ||
248 | } | ||
249 | |||
250 | static void rtl8723ae_dm_bt_btdm_structure_reload(struct ieee80211_hw *hw, | ||
251 | struct btdm_8723 *btdm) | ||
252 | { | ||
253 | btdm->all_off = false; | ||
254 | btdm->agc_table_en = false; | ||
255 | btdm->adc_back_off_on = false; | ||
256 | btdm->b2_ant_hid_en = false; | ||
257 | btdm->low_penalty_rate_adaptive = false; | ||
258 | btdm->rf_rx_lpf_shrink = false; | ||
259 | btdm->reject_aggre_pkt = false; | ||
260 | |||
261 | btdm->tdma_on = false; | ||
262 | btdm->tdma_ant = TDMA_2ANT; | ||
263 | btdm->tdma_nav = TDMA_NAV_OFF; | ||
264 | btdm->tdma_dac_swing = TDMA_DAC_SWING_OFF; | ||
265 | btdm->fw_dac_swing_lvl = 0x20; | ||
266 | |||
267 | btdm->tra_tdma_on = false; | ||
268 | btdm->tra_tdma_ant = TDMA_2ANT; | ||
269 | btdm->tra_tdma_nav = TDMA_NAV_OFF; | ||
270 | btdm->ignore_wlan_act = false; | ||
271 | |||
272 | btdm->ps_tdma_on = false; | ||
273 | btdm->ps_tdma_byte[0] = 0x0; | ||
274 | btdm->ps_tdma_byte[1] = 0x0; | ||
275 | btdm->ps_tdma_byte[2] = 0x0; | ||
276 | btdm->ps_tdma_byte[3] = 0x8; | ||
277 | btdm->ps_tdma_byte[4] = 0x0; | ||
278 | |||
279 | btdm->pta_on = true; | ||
280 | btdm->val_0x6c0 = 0x5a5aaaaa; | ||
281 | btdm->val_0x6c8 = 0xcc; | ||
282 | btdm->val_0x6cc = 0x3; | ||
283 | |||
284 | btdm->sw_dac_swing_on = false; | ||
285 | btdm->sw_dac_swing_lvl = 0xc0; | ||
286 | btdm->wlan_act_hi = 0x20; | ||
287 | btdm->wlan_act_lo = 0x10; | ||
288 | btdm->bt_retry_index = 2; | ||
289 | |||
290 | btdm->dec_bt_pwr = false; | ||
291 | } | ||
292 | |||
293 | static void dm_bt_btdm_structure_reload_all_off(struct ieee80211_hw *hw, | ||
294 | struct btdm_8723 *btdm) | ||
295 | { | ||
296 | rtl8723ae_dm_bt_btdm_structure_reload(hw, btdm); | ||
297 | btdm->all_off = true; | ||
298 | btdm->pta_on = false; | ||
299 | btdm->wlan_act_hi = 0x10; | ||
300 | } | ||
301 | |||
302 | static bool rtl8723ae_dm_bt_is_2_ant_common_action(struct ieee80211_hw *hw) | ||
303 | { | ||
304 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
305 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
306 | struct btdm_8723 btdm8723; | ||
307 | bool common = false; | ||
308 | |||
309 | rtl8723ae_dm_bt_btdm_structure_reload(hw, &btdm8723); | ||
310 | |||
311 | if (!rtl8723ae_dm_bt_is_wifi_busy(hw) | ||
312 | && !rtlpcipriv->bt_coexist.bt_busy) { | ||
313 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
314 | "Wifi idle + Bt idle, bt coex mechanism always off!!\n"); | ||
315 | dm_bt_btdm_structure_reload_all_off(hw, &btdm8723); | ||
316 | common = true; | ||
317 | } else if (rtl8723ae_dm_bt_is_wifi_busy(hw) | ||
318 | && !rtlpcipriv->bt_coexist.bt_busy) { | ||
319 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
320 | "Wifi non-idle + Bt disabled/idle!!\n"); | ||
321 | btdm8723.low_penalty_rate_adaptive = true; | ||
322 | btdm8723.rf_rx_lpf_shrink = false; | ||
323 | btdm8723.reject_aggre_pkt = false; | ||
324 | |||
325 | /* sw mechanism */ | ||
326 | btdm8723.agc_table_en = false; | ||
327 | btdm8723.adc_back_off_on = false; | ||
328 | btdm8723.sw_dac_swing_on = false; | ||
329 | |||
330 | btdm8723.pta_on = true; | ||
331 | btdm8723.val_0x6c0 = 0x5a5aaaaa; | ||
332 | btdm8723.val_0x6c8 = 0xcccc; | ||
333 | btdm8723.val_0x6cc = 0x3; | ||
334 | |||
335 | btdm8723.tdma_on = false; | ||
336 | btdm8723.tdma_dac_swing = TDMA_DAC_SWING_OFF; | ||
337 | btdm8723.b2_ant_hid_en = false; | ||
338 | |||
339 | common = true; | ||
340 | } else if (rtlpcipriv->bt_coexist.bt_busy) { | ||
341 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
342 | "Bt non-idle!\n"); | ||
343 | if (mgnt_link_status_query(hw) == RT_MEDIA_CONNECT) { | ||
344 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
345 | "Wifi connection exist\n"); | ||
346 | common = false; | ||
347 | } else { | ||
348 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
349 | "No Wifi connection!\n"); | ||
350 | btdm8723.rf_rx_lpf_shrink = true; | ||
351 | btdm8723.low_penalty_rate_adaptive = false; | ||
352 | btdm8723.reject_aggre_pkt = false; | ||
353 | |||
354 | /* sw mechanism */ | ||
355 | btdm8723.agc_table_en = false; | ||
356 | btdm8723.adc_back_off_on = false; | ||
357 | btdm8723.sw_dac_swing_on = false; | ||
358 | |||
359 | btdm8723.pta_on = true; | ||
360 | btdm8723.val_0x6c0 = 0x55555555; | ||
361 | btdm8723.val_0x6c8 = 0x0000ffff; | ||
362 | btdm8723.val_0x6cc = 0x3; | ||
363 | |||
364 | btdm8723.tdma_on = false; | ||
365 | btdm8723.tdma_dac_swing = TDMA_DAC_SWING_OFF; | ||
366 | btdm8723.b2_ant_hid_en = false; | ||
367 | |||
368 | common = true; | ||
369 | } | ||
370 | } | ||
371 | |||
372 | if (rtl8723ae_dm_bt_need_to_dec_bt_pwr(hw)) | ||
373 | btdm8723.dec_bt_pwr = true; | ||
374 | |||
375 | if (common) | ||
376 | rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_BTINFO_COMMON; | ||
377 | |||
378 | if (common && rtl8723ae_dm_bt_is_coexist_state_changed(hw)) | ||
379 | rtl8723ae_dm_bt_set_bt_dm(hw, &btdm8723); | ||
380 | |||
381 | return common; | ||
382 | } | ||
383 | |||
384 | static void rtl8723ae_dm_bt_set_sw_full_time_dac_swing(struct ieee80211_hw *hw, | ||
385 | bool sw_dac_swing_on, | ||
386 | u32 sw_dac_swing_lvl) | ||
387 | { | ||
388 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
389 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
390 | |||
391 | if (sw_dac_swing_on) { | ||
392 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
393 | "[BTCoex], SwDacSwing = 0x%x\n", sw_dac_swing_lvl); | ||
394 | rtl8723ae_phy_set_bb_reg(hw, 0x880, 0xff000000, | ||
395 | sw_dac_swing_lvl); | ||
396 | rtlpcipriv->bt_coexist.sw_coexist_all_off = false; | ||
397 | } else { | ||
398 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
399 | "[BTCoex], SwDacSwing Off!\n"); | ||
400 | rtl8723ae_phy_set_bb_reg(hw, 0x880, 0xff000000, 0xc0); | ||
401 | } | ||
402 | } | ||
403 | |||
404 | static void rtl8723ae_dm_bt_set_fw_dec_bt_pwr(struct ieee80211_hw *hw, | ||
405 | bool dec_bt_pwr) | ||
406 | { | ||
407 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
408 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
409 | u8 h2c_parameter[1] = {0}; | ||
410 | |||
411 | h2c_parameter[0] = 0; | ||
412 | |||
413 | if (dec_bt_pwr) { | ||
414 | h2c_parameter[0] |= BIT(1); | ||
415 | rtlpcipriv->bt_coexist.fw_coexist_all_off = false; | ||
416 | } | ||
417 | |||
418 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
419 | "[BTCoex], decrease Bt Power : %s, write 0x21 = 0x%x\n", | ||
420 | (dec_bt_pwr ? "Yes!!" : "No!!"), h2c_parameter[0]); | ||
421 | |||
422 | rtl8723ae_fill_h2c_cmd(hw, 0x21, 1, h2c_parameter); | ||
423 | } | ||
424 | |||
425 | static void rtl8723ae_dm_bt_set_fw_2_ant_hid(struct ieee80211_hw *hw, | ||
426 | bool enable, bool dac_swing_on) | ||
427 | { | ||
428 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
429 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
430 | u8 h2c_parameter[1] = {0}; | ||
431 | |||
432 | if (enable) { | ||
433 | h2c_parameter[0] |= BIT(0); | ||
434 | rtlpcipriv->bt_coexist.fw_coexist_all_off = false; | ||
435 | } | ||
436 | if (dac_swing_on) | ||
437 | h2c_parameter[0] |= BIT(1); /* Dac Swing default enable */ | ||
438 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
439 | "[BTCoex], turn 2-Ant+HID mode %s, DACSwing:%s, write 0x15 = 0x%x\n", | ||
440 | (enable ? "ON!!" : "OFF!!"), (dac_swing_on ? "ON" : "OFF"), | ||
441 | h2c_parameter[0]); | ||
442 | |||
443 | rtl8723ae_fill_h2c_cmd(hw, 0x15, 1, h2c_parameter); | ||
444 | } | ||
445 | |||
446 | static void rtl8723ae_dm_bt_set_fw_tdma_ctrl(struct ieee80211_hw *hw, | ||
447 | bool enable, u8 ant_num, u8 nav_en, | ||
448 | u8 dac_swing_en) | ||
449 | { | ||
450 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
451 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
452 | u8 h2c_parameter[1] = {0}; | ||
453 | u8 h2c_parameter1[1] = {0}; | ||
454 | |||
455 | h2c_parameter[0] = 0; | ||
456 | h2c_parameter1[0] = 0; | ||
457 | |||
458 | if (enable) { | ||
459 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
460 | "[BTCoex], set BT PTA update manager to trigger update!!\n"); | ||
461 | h2c_parameter1[0] |= BIT(0); | ||
462 | |||
463 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
464 | "[BTCoex], turn TDMA mode ON!!\n"); | ||
465 | h2c_parameter[0] |= BIT(0); /* function enable */ | ||
466 | if (TDMA_1ANT == ant_num) { | ||
467 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
468 | "[BTCoex], TDMA_1ANT\n"); | ||
469 | h2c_parameter[0] |= BIT(1); | ||
470 | } else if (TDMA_2ANT == ant_num) { | ||
471 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
472 | "[BTCoex], TDMA_2ANT\n"); | ||
473 | } else { | ||
474 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
475 | "[BTCoex], Unknown Ant\n"); | ||
476 | } | ||
477 | |||
478 | if (TDMA_NAV_OFF == nav_en) { | ||
479 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
480 | "[BTCoex], TDMA_NAV_OFF\n"); | ||
481 | } else if (TDMA_NAV_ON == nav_en) { | ||
482 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
483 | "[BTCoex], TDMA_NAV_ON\n"); | ||
484 | h2c_parameter[0] |= BIT(2); | ||
485 | } | ||
486 | |||
487 | if (TDMA_DAC_SWING_OFF == dac_swing_en) { | ||
488 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
489 | "[BTCoex], TDMA_DAC_SWING_OFF\n"); | ||
490 | } else if (TDMA_DAC_SWING_ON == dac_swing_en) { | ||
491 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
492 | "[BTCoex], TDMA_DAC_SWING_ON\n"); | ||
493 | h2c_parameter[0] |= BIT(4); | ||
494 | } | ||
495 | rtlpcipriv->bt_coexist.fw_coexist_all_off = false; | ||
496 | } else { | ||
497 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
498 | "[BTCoex], set BT PTA update manager to no update!!\n"); | ||
499 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
500 | "[BTCoex], turn TDMA mode OFF!!\n"); | ||
501 | } | ||
502 | |||
503 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
504 | "[BTCoex], FW2AntTDMA, write 0x26 = 0x%x\n", | ||
505 | h2c_parameter1[0]); | ||
506 | rtl8723ae_fill_h2c_cmd(hw, 0x26, 1, h2c_parameter1); | ||
507 | |||
508 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
509 | "[BTCoex], FW2AntTDMA, write 0x14 = 0x%x\n", h2c_parameter[0]); | ||
510 | rtl8723ae_fill_h2c_cmd(hw, 0x14, 1, h2c_parameter); | ||
511 | } | ||
512 | |||
513 | static void rtl8723ae_dm_bt_set_fw_ignore_wlan_act(struct ieee80211_hw *hw, | ||
514 | bool enable) | ||
515 | { | ||
516 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
517 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
518 | u8 h2c_parameter[1] = {0}; | ||
519 | |||
520 | if (enable) { | ||
521 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
522 | "[BTCoex], BT Ignore Wlan_Act !!\n"); | ||
523 | h2c_parameter[0] |= BIT(0); /* function enable */ | ||
524 | rtlpcipriv->bt_coexist.fw_coexist_all_off = false; | ||
525 | } else { | ||
526 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
527 | "[BTCoex], BT don't ignore Wlan_Act !!\n"); | ||
528 | } | ||
529 | |||
530 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
531 | "[BTCoex], set FW for BT Ignore Wlan_Act, write 0x25 = 0x%x\n", | ||
532 | h2c_parameter[0]); | ||
533 | |||
534 | rtl8723ae_fill_h2c_cmd(hw, 0x25, 1, h2c_parameter); | ||
535 | } | ||
536 | |||
537 | static void rtl8723ae_dm_bt_set_fw_tra_tdma_ctrl(struct ieee80211_hw *hw, | ||
538 | bool enable, u8 ant_num, | ||
539 | u8 nav_en) | ||
540 | { | ||
541 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
542 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
543 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
544 | u8 h2c_parameter[2] = {0}; | ||
545 | |||
546 | /* Only 8723 B cut should do this */ | ||
547 | if (IS_VENDOR_8723_A_CUT(rtlhal->version)) { | ||
548 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
549 | "[BTCoex], not 8723B cut, don't set Traditional TDMA!!\n"); | ||
550 | return; | ||
551 | } | ||
552 | |||
553 | if (enable) { | ||
554 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
555 | "[BTCoex], turn TTDMA mode ON!!\n"); | ||
556 | h2c_parameter[0] |= BIT(0); /* function enable */ | ||
557 | if (TDMA_1ANT == ant_num) { | ||
558 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
559 | "[BTCoex], TTDMA_1ANT\n"); | ||
560 | h2c_parameter[0] |= BIT(1); | ||
561 | } else if (TDMA_2ANT == ant_num) { | ||
562 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
563 | "[BTCoex], TTDMA_2ANT\n"); | ||
564 | } else { | ||
565 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
566 | "[BTCoex], Unknown Ant\n"); | ||
567 | } | ||
568 | |||
569 | if (TDMA_NAV_OFF == nav_en) { | ||
570 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
571 | "[BTCoex], TTDMA_NAV_OFF\n"); | ||
572 | } else if (TDMA_NAV_ON == nav_en) { | ||
573 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
574 | "[BTCoex], TTDMA_NAV_ON\n"); | ||
575 | h2c_parameter[1] |= BIT(0); | ||
576 | } | ||
577 | |||
578 | rtlpcipriv->bt_coexist.fw_coexist_all_off = false; | ||
579 | } else { | ||
580 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
581 | "[BTCoex], turn TTDMA mode OFF!!\n"); | ||
582 | } | ||
583 | |||
584 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
585 | "[BTCoex], FW Traditional TDMA, write 0x33 = 0x%x\n", | ||
586 | h2c_parameter[0] << 8 | h2c_parameter[1]); | ||
587 | |||
588 | rtl8723ae_fill_h2c_cmd(hw, 0x33, 2, h2c_parameter); | ||
589 | } | ||
590 | |||
591 | static void rtl8723ae_dm_bt_set_fw_dac_swing_level(struct ieee80211_hw *hw, | ||
592 | u8 dac_swing_lvl) | ||
593 | { | ||
594 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
595 | u8 h2c_parameter[1] = {0}; | ||
596 | |||
597 | h2c_parameter[0] = dac_swing_lvl; | ||
598 | |||
599 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
600 | "[BTCoex], Set Dac Swing Level = 0x%x\n", dac_swing_lvl); | ||
601 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
602 | "[BTCoex], write 0x29 = 0x%x\n", h2c_parameter[0]); | ||
603 | |||
604 | rtl8723ae_fill_h2c_cmd(hw, 0x29, 1, h2c_parameter); | ||
605 | } | ||
606 | |||
607 | static void rtl8723ae_dm_bt_set_fw_bt_hid_info(struct ieee80211_hw *hw, | ||
608 | bool enable) | ||
609 | { | ||
610 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
611 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
612 | u8 h2c_parameter[1] = {0}; | ||
613 | |||
614 | h2c_parameter[0] = 0; | ||
615 | |||
616 | if (enable) { | ||
617 | h2c_parameter[0] |= BIT(0); | ||
618 | rtlpcipriv->bt_coexist.fw_coexist_all_off = false; | ||
619 | } | ||
620 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
621 | "[BTCoex], Set BT HID information = 0x%x\n", enable); | ||
622 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
623 | "[BTCoex], write 0x24 = 0x%x\n", h2c_parameter[0]); | ||
624 | |||
625 | rtl8723ae_fill_h2c_cmd(hw, 0x24, 1, h2c_parameter); | ||
626 | } | ||
627 | |||
628 | static void rtl8723ae_dm_bt_set_fw_bt_retry_index(struct ieee80211_hw *hw, | ||
629 | u8 retry_index) | ||
630 | { | ||
631 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
632 | u8 h2c_parameter[1] = {0}; | ||
633 | |||
634 | h2c_parameter[0] = retry_index; | ||
635 | |||
636 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
637 | "[BTCoex], Set BT Retry Index=%d\n", retry_index); | ||
638 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
639 | "[BTCoex], write 0x23 = 0x%x\n", h2c_parameter[0]); | ||
640 | |||
641 | rtl8723ae_fill_h2c_cmd(hw, 0x23, 1, h2c_parameter); | ||
642 | } | ||
643 | |||
644 | static void rtl8723ae_dm_bt_set_fw_wlan_act(struct ieee80211_hw *hw, | ||
645 | u8 wlan_act_hi, u8 wlan_act_lo) | ||
646 | { | ||
647 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
648 | u8 h2c_parameter_hi[1] = {0}; | ||
649 | u8 h2c_parameter_lo[1] = {0}; | ||
650 | |||
651 | h2c_parameter_hi[0] = wlan_act_hi; | ||
652 | h2c_parameter_lo[0] = wlan_act_lo; | ||
653 | |||
654 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
655 | "[BTCoex], Set WLAN_ACT Hi:Lo = 0x%x/0x%x\n", wlan_act_hi, | ||
656 | wlan_act_lo); | ||
657 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
658 | "[BTCoex], write 0x22 = 0x%x\n", h2c_parameter_hi[0]); | ||
659 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
660 | "[BTCoex], write 0x11 = 0x%x\n", h2c_parameter_lo[0]); | ||
661 | |||
662 | /* WLAN_ACT = High duration, unit:ms */ | ||
663 | rtl8723ae_fill_h2c_cmd(hw, 0x22, 1, h2c_parameter_hi); | ||
664 | /* WLAN_ACT = Low duration, unit:3*625us */ | ||
665 | rtl8723ae_fill_h2c_cmd(hw, 0x11, 1, h2c_parameter_lo); | ||
666 | } | ||
667 | |||
668 | void rtl8723ae_dm_bt_set_bt_dm(struct ieee80211_hw *hw, struct btdm_8723 *btdm) | ||
669 | { | ||
670 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
671 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
672 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | ||
673 | struct btdm_8723 *btdm_8723 = &rtlhal->hal_coex_8723.btdm; | ||
674 | u8 i; | ||
675 | bool fw_current_inpsmode = false; | ||
676 | bool fw_ps_awake = true; | ||
677 | |||
678 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, | ||
679 | (u8 *)(&fw_current_inpsmode)); | ||
680 | rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, | ||
681 | (u8 *)(&fw_ps_awake)); | ||
682 | |||
683 | /* check new setting is different than the old one, | ||
684 | * if all the same, don't do the setting again. | ||
685 | */ | ||
686 | if (memcmp(btdm_8723, btdm, sizeof(struct btdm_8723)) == 0) { | ||
687 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
688 | "[BTCoex], the same coexist setting, return!!\n"); | ||
689 | return; | ||
690 | } else { /* save the new coexist setting */ | ||
691 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
692 | "[BTCoex], UPDATE TO NEW COEX SETTING!!\n"); | ||
693 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
694 | "[BTCoex], original/new bAllOff = 0x%x/ 0x%x\n", | ||
695 | btdm_8723->all_off, btdm->all_off); | ||
696 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
697 | "[BTCoex], original/new agc_table_en = 0x%x/ 0x%x\n", | ||
698 | btdm_8723->agc_table_en, btdm->agc_table_en); | ||
699 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
700 | "[BTCoex], original/new adc_back_off_on = 0x%x/ 0x%x\n", | ||
701 | btdm_8723->adc_back_off_on, btdm->adc_back_off_on); | ||
702 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
703 | "[BTCoex], original/new b2_ant_hid_en = 0x%x/ 0x%x\n", | ||
704 | btdm_8723->b2_ant_hid_en, btdm->b2_ant_hid_en); | ||
705 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
706 | "[BTCoex], original/new bLowPenaltyRateAdaptive = 0x%x/ 0x%x\n", | ||
707 | btdm_8723->low_penalty_rate_adaptive, | ||
708 | btdm->low_penalty_rate_adaptive); | ||
709 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
710 | "[BTCoex], original/new bRfRxLpfShrink = 0x%x/ 0x%x\n", | ||
711 | btdm_8723->rf_rx_lpf_shrink, btdm->rf_rx_lpf_shrink); | ||
712 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
713 | "[BTCoex], original/new bRejectAggrePkt = 0x%x/ 0x%x\n", | ||
714 | btdm_8723->reject_aggre_pkt, btdm->reject_aggre_pkt); | ||
715 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
716 | "[BTCoex], original/new tdma_on = 0x%x/ 0x%x\n", | ||
717 | btdm_8723->tdma_on, btdm->tdma_on); | ||
718 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
719 | "[BTCoex], original/new tdmaAnt = 0x%x/ 0x%x\n", | ||
720 | btdm_8723->tdma_ant, btdm->tdma_ant); | ||
721 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
722 | "[BTCoex], original/new tdmaNav = 0x%x/ 0x%x\n", | ||
723 | btdm_8723->tdma_nav, btdm->tdma_nav); | ||
724 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
725 | "[BTCoex], original/new tdma_dac_swing = 0x%x/ 0x%x\n", | ||
726 | btdm_8723->tdma_dac_swing, btdm->tdma_dac_swing); | ||
727 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
728 | "[BTCoex], original/new fwDacSwingLvl = 0x%x/ 0x%x\n", | ||
729 | btdm_8723->fw_dac_swing_lvl, btdm->fw_dac_swing_lvl); | ||
730 | |||
731 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
732 | "[BTCoex], original/new bTraTdmaOn = 0x%x/ 0x%x\n", | ||
733 | btdm_8723->tra_tdma_on, btdm->tra_tdma_on); | ||
734 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
735 | "[BTCoex], original/new traTdmaAnt = 0x%x/ 0x%x\n", | ||
736 | btdm_8723->tra_tdma_ant, btdm->tra_tdma_ant); | ||
737 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
738 | "[BTCoex], original/new traTdmaNav = 0x%x/ 0x%x\n", | ||
739 | btdm_8723->tra_tdma_nav, btdm->tra_tdma_nav); | ||
740 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
741 | "[BTCoex], original/new bPsTdmaOn = 0x%x/ 0x%x\n", | ||
742 | btdm_8723->ps_tdma_on, btdm->ps_tdma_on); | ||
743 | for (i = 0; i < 5; i++) { | ||
744 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
745 | "[BTCoex], original/new psTdmaByte[i] = 0x%x/ 0x%x\n", | ||
746 | btdm_8723->ps_tdma_byte[i], | ||
747 | btdm->ps_tdma_byte[i]); | ||
748 | } | ||
749 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
750 | "[BTCoex], original/new bIgnoreWlanAct = 0x%x/ 0x%x\n", | ||
751 | btdm_8723->ignore_wlan_act, btdm->ignore_wlan_act); | ||
752 | |||
753 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
754 | "[BTCoex], original/new bPtaOn = 0x%x/ 0x%x\n", | ||
755 | btdm_8723->pta_on, btdm->pta_on); | ||
756 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
757 | "[BTCoex], original/new val_0x6c0 = 0x%x/ 0x%x\n", | ||
758 | btdm_8723->val_0x6c0, btdm->val_0x6c0); | ||
759 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
760 | "[BTCoex], original/new val_0x6c8 = 0x%x/ 0x%x\n", | ||
761 | btdm_8723->val_0x6c8, btdm->val_0x6c8); | ||
762 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
763 | "[BTCoex], original/new val_0x6cc = 0x%x/ 0x%x\n", | ||
764 | btdm_8723->val_0x6cc, btdm->val_0x6cc); | ||
765 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
766 | "[BTCoex], original/new sw_dac_swing_on = 0x%x/ 0x%x\n", | ||
767 | btdm_8723->sw_dac_swing_on, btdm->sw_dac_swing_on); | ||
768 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
769 | "[BTCoex], original/new sw_dac_swing_lvl = 0x%x/ 0x%x\n", | ||
770 | btdm_8723->sw_dac_swing_lvl, | ||
771 | btdm->sw_dac_swing_lvl); | ||
772 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
773 | "[BTCoex], original/new wlanActHi = 0x%x/ 0x%x\n", | ||
774 | btdm_8723->wlan_act_hi, btdm->wlan_act_hi); | ||
775 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
776 | "[BTCoex], original/new wlanActLo = 0x%x/ 0x%x\n", | ||
777 | btdm_8723->wlan_act_lo, btdm->wlan_act_lo); | ||
778 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
779 | "[BTCoex], original/new btRetryIndex = 0x%x/ 0x%x\n", | ||
780 | btdm_8723->bt_retry_index, btdm->bt_retry_index); | ||
781 | |||
782 | memcpy(btdm_8723, btdm, sizeof(struct btdm_8723)); | ||
783 | } | ||
784 | /* | ||
785 | * Here we only consider when Bt Operation | ||
786 | * inquiry/paging/pairing is ON | ||
787 | * we only need to turn off TDMA | ||
788 | */ | ||
789 | |||
790 | if (rtlpcipriv->bt_coexist.hold_for_bt_operation) { | ||
791 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
792 | "[BTCoex], set to ignore wlanAct for BT OP!!\n"); | ||
793 | rtl8723ae_dm_bt_set_fw_ignore_wlan_act(hw, true); | ||
794 | return; | ||
795 | } | ||
796 | |||
797 | if (btdm->all_off) { | ||
798 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
799 | "[BTCoex], disable all coexist mechanism !!\n"); | ||
800 | rtl8723ae_btdm_coex_all_off(hw); | ||
801 | return; | ||
802 | } | ||
803 | |||
804 | rtl8723ae_dm_bt_reject_ap_aggregated_packet(hw, btdm->reject_aggre_pkt); | ||
805 | |||
806 | if (btdm->low_penalty_rate_adaptive) | ||
807 | rtl8723ae_bt_set_penalty_tx_rate_adap(hw, | ||
808 | BT_TX_RATE_ADAPTIVE_LOW_PENALTY); | ||
809 | else | ||
810 | rtl8723ae_bt_set_penalty_tx_rate_adap(hw, | ||
811 | BT_TX_RATE_ADAPTIVE_NORMAL); | ||
812 | |||
813 | if (btdm->rf_rx_lpf_shrink) | ||
814 | rtl8723ae_dm_bt_set_sw_rf_rx_lpf_corner(hw, | ||
815 | BT_RF_RX_LPF_CORNER_SHRINK); | ||
816 | else | ||
817 | rtl8723ae_dm_bt_set_sw_rf_rx_lpf_corner(hw, | ||
818 | BT_RF_RX_LPF_CORNER_RESUME); | ||
819 | |||
820 | if (btdm->agc_table_en) | ||
821 | rtl8723ae_dm_bt_agc_table(hw, BT_AGCTABLE_ON); | ||
822 | else | ||
823 | rtl8723ae_dm_bt_agc_table(hw, BT_AGCTABLE_OFF); | ||
824 | |||
825 | if (btdm->adc_back_off_on) | ||
826 | rtl8723ae_dm_bt_bback_off_level(hw, BT_BB_BACKOFF_ON); | ||
827 | else | ||
828 | rtl8723ae_dm_bt_bback_off_level(hw, BT_BB_BACKOFF_OFF); | ||
829 | |||
830 | rtl8723ae_dm_bt_set_fw_bt_retry_index(hw, btdm->bt_retry_index); | ||
831 | |||
832 | rtl8723ae_dm_bt_set_fw_dac_swing_level(hw, btdm->fw_dac_swing_lvl); | ||
833 | rtl8723ae_dm_bt_set_fw_wlan_act(hw, btdm->wlan_act_hi, | ||
834 | btdm->wlan_act_lo); | ||
835 | |||
836 | rtl8723ae_dm_bt_set_coex_table(hw, btdm->val_0x6c0, | ||
837 | btdm->val_0x6c8, btdm->val_0x6cc); | ||
838 | rtl8723ae_dm_bt_set_hw_pta_mode(hw, btdm->pta_on); | ||
839 | |||
840 | /* Note: There is a constraint between TDMA and 2AntHID | ||
841 | * Only one of 2AntHid and tdma can be turned on | ||
842 | * We should turn off those mechanisms first | ||
843 | * and then turn on them on. | ||
844 | */ | ||
845 | if (btdm->b2_ant_hid_en) { | ||
846 | /* turn off tdma */ | ||
847 | rtl8723ae_dm_bt_set_fw_tra_tdma_ctrl(hw, btdm->tra_tdma_on, | ||
848 | btdm->tra_tdma_ant, | ||
849 | btdm->tra_tdma_nav); | ||
850 | rtl8723ae_dm_bt_set_fw_tdma_ctrl(hw, false, btdm->tdma_ant, | ||
851 | btdm->tdma_nav, | ||
852 | btdm->tdma_dac_swing); | ||
853 | |||
854 | /* turn off Pstdma */ | ||
855 | rtl8723ae_dm_bt_set_fw_ignore_wlan_act(hw, | ||
856 | btdm->ignore_wlan_act); | ||
857 | /* Antenna control by PTA, 0x870 = 0x300. */ | ||
858 | rtl8723ae_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0); | ||
859 | |||
860 | /* turn on 2AntHid */ | ||
861 | rtl8723ae_dm_bt_set_fw_bt_hid_info(hw, true); | ||
862 | rtl8723ae_dm_bt_set_fw_2_ant_hid(hw, true, true); | ||
863 | } else if (btdm->tdma_on) { | ||
864 | /* turn off 2AntHid */ | ||
865 | rtl8723ae_dm_bt_set_fw_bt_hid_info(hw, false); | ||
866 | rtl8723ae_dm_bt_set_fw_2_ant_hid(hw, false, false); | ||
867 | |||
868 | /* turn off pstdma */ | ||
869 | rtl8723ae_dm_bt_set_fw_ignore_wlan_act(hw, | ||
870 | btdm->ignore_wlan_act); | ||
871 | /* Antenna control by PTA, 0x870 = 0x300. */ | ||
872 | rtl8723ae_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0); | ||
873 | |||
874 | /* turn on tdma */ | ||
875 | rtl8723ae_dm_bt_set_fw_tra_tdma_ctrl(hw, btdm->tra_tdma_on, | ||
876 | btdm->tra_tdma_ant, btdm->tra_tdma_nav); | ||
877 | rtl8723ae_dm_bt_set_fw_tdma_ctrl(hw, true, btdm->tdma_ant, | ||
878 | btdm->tdma_nav, btdm->tdma_dac_swing); | ||
879 | } else if (btdm->ps_tdma_on) { | ||
880 | /* turn off 2AntHid */ | ||
881 | rtl8723ae_dm_bt_set_fw_bt_hid_info(hw, false); | ||
882 | rtl8723ae_dm_bt_set_fw_2_ant_hid(hw, false, false); | ||
883 | |||
884 | /* turn off tdma */ | ||
885 | rtl8723ae_dm_bt_set_fw_tra_tdma_ctrl(hw, btdm->tra_tdma_on, | ||
886 | btdm->tra_tdma_ant, btdm->tra_tdma_nav); | ||
887 | rtl8723ae_dm_bt_set_fw_tdma_ctrl(hw, false, btdm->tdma_ant, | ||
888 | btdm->tdma_nav, btdm->tdma_dac_swing); | ||
889 | |||
890 | /* turn on pstdma */ | ||
891 | rtl8723ae_dm_bt_set_fw_ignore_wlan_act(hw, | ||
892 | btdm->ignore_wlan_act); | ||
893 | rtl8723ae_dm_bt_set_fw_3a(hw, | ||
894 | btdm->ps_tdma_byte[0], | ||
895 | btdm->ps_tdma_byte[1], | ||
896 | btdm->ps_tdma_byte[2], | ||
897 | btdm->ps_tdma_byte[3], | ||
898 | btdm->ps_tdma_byte[4]); | ||
899 | } else { | ||
900 | /* turn off 2AntHid */ | ||
901 | rtl8723ae_dm_bt_set_fw_bt_hid_info(hw, false); | ||
902 | rtl8723ae_dm_bt_set_fw_2_ant_hid(hw, false, false); | ||
903 | |||
904 | /* turn off tdma */ | ||
905 | rtl8723ae_dm_bt_set_fw_tra_tdma_ctrl(hw, btdm->tra_tdma_on, | ||
906 | btdm->tra_tdma_ant, btdm->tra_tdma_nav); | ||
907 | rtl8723ae_dm_bt_set_fw_tdma_ctrl(hw, false, btdm->tdma_ant, | ||
908 | btdm->tdma_nav, btdm->tdma_dac_swing); | ||
909 | |||
910 | /* turn off pstdma */ | ||
911 | rtl8723ae_dm_bt_set_fw_ignore_wlan_act(hw, | ||
912 | btdm->ignore_wlan_act); | ||
913 | /* Antenna control by PTA, 0x870 = 0x300. */ | ||
914 | rtl8723ae_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0); | ||
915 | } | ||
916 | |||
917 | /* Note: | ||
918 | * We should add delay for making sure sw DacSwing can be set | ||
919 | * sucessfully. Because of that rtl8723ae_dm_bt_set_fw_2_ant_hid() | ||
920 | * and rtl8723ae_dm_bt_set_fw_tdma_ctrl() | ||
921 | * will overwrite the reg 0x880. | ||
922 | */ | ||
923 | mdelay(30); | ||
924 | rtl8723ae_dm_bt_set_sw_full_time_dac_swing(hw, | ||
925 | btdm->sw_dac_swing_on, btdm->sw_dac_swing_lvl); | ||
926 | rtl8723ae_dm_bt_set_fw_dec_bt_pwr(hw, btdm->dec_bt_pwr); | ||
927 | } | ||
928 | |||
929 | /*============================================================ | ||
930 | * extern function start with BTDM_ | ||
931 | *============================================================ | ||
932 | */ | ||
933 | static u32 rtl8723ae_dm_bt_tx_rx_couter_h(struct ieee80211_hw *hw) | ||
934 | { | ||
935 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
936 | u32 counters = 0; | ||
937 | |||
938 | counters = rtlhal->hal_coex_8723.high_priority_tx + | ||
939 | rtlhal->hal_coex_8723.high_priority_rx; | ||
940 | return counters; | ||
941 | } | ||
942 | |||
943 | static u32 rtl8723ae_dm_bt_tx_rx_couter_l(struct ieee80211_hw *hw) | ||
944 | { | ||
945 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
946 | |||
947 | return rtlhal->hal_coex_8723.low_priority_tx + | ||
948 | rtlhal->hal_coex_8723.low_priority_rx; | ||
949 | } | ||
950 | |||
951 | static u8 rtl8723ae_dm_bt_bt_tx_rx_counter_level(struct ieee80211_hw *hw) | ||
952 | { | ||
953 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
954 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
955 | u32 bt_tx_rx_cnt = 0; | ||
956 | u8 bt_tx_rx_cnt_lvl = 0; | ||
957 | |||
958 | bt_tx_rx_cnt = rtl8723ae_dm_bt_tx_rx_couter_h(hw) + | ||
959 | rtl8723ae_dm_bt_tx_rx_couter_l(hw); | ||
960 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
961 | "[BTCoex], BT TxRx Counters = %d\n", bt_tx_rx_cnt); | ||
962 | |||
963 | rtlpcipriv->bt_coexist.cstate_h &= | ||
964 | ~(BT_COEX_STATE_BT_CNT_LEVEL_0 | BT_COEX_STATE_BT_CNT_LEVEL_1 | | ||
965 | BT_COEX_STATE_BT_CNT_LEVEL_2); | ||
966 | |||
967 | if (bt_tx_rx_cnt >= BT_TXRX_CNT_THRES_3) { | ||
968 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
969 | "[BTCoex], BT TxRx Counters at level 3\n"); | ||
970 | bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_3; | ||
971 | rtlpcipriv->bt_coexist.cstate_h |= BT_COEX_STATE_BT_CNT_LEVEL_3; | ||
972 | } else if (bt_tx_rx_cnt >= BT_TXRX_CNT_THRES_2) { | ||
973 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
974 | "[BTCoex], BT TxRx Counters at level 2\n"); | ||
975 | bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_2; | ||
976 | rtlpcipriv->bt_coexist.cstate_h |= BT_COEX_STATE_BT_CNT_LEVEL_2; | ||
977 | } else if (bt_tx_rx_cnt >= BT_TXRX_CNT_THRES_1) { | ||
978 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
979 | "[BTCoex], BT TxRx Counters at level 1\n"); | ||
980 | bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_1; | ||
981 | rtlpcipriv->bt_coexist.cstate_h |= BT_COEX_STATE_BT_CNT_LEVEL_1; | ||
982 | } else { | ||
983 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
984 | "[BTCoex], BT TxRx Counters at level 0\n"); | ||
985 | bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_0; | ||
986 | rtlpcipriv->bt_coexist.cstate_h |= BT_COEX_STATE_BT_CNT_LEVEL_0; | ||
987 | } | ||
988 | return bt_tx_rx_cnt_lvl; | ||
989 | } | ||
990 | |||
991 | static void rtl8723ae_dm_bt_2_ant_hid_sco_esco(struct ieee80211_hw *hw) | ||
992 | { | ||
993 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
994 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | ||
995 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
996 | struct btdm_8723 btdm8723; | ||
997 | u8 bt_rssi_state, bt_rssi_state1; | ||
998 | u8 bt_tx_rx_cnt_lvl; | ||
999 | |||
1000 | rtl8723ae_dm_bt_btdm_structure_reload(hw, &btdm8723); | ||
1001 | |||
1002 | btdm8723.rf_rx_lpf_shrink = true; | ||
1003 | btdm8723.low_penalty_rate_adaptive = true; | ||
1004 | btdm8723.reject_aggre_pkt = false; | ||
1005 | |||
1006 | bt_tx_rx_cnt_lvl = rtl8723ae_dm_bt_bt_tx_rx_counter_level(hw); | ||
1007 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1008 | "[BTCoex], BT TxRx Counters = %d\n", bt_tx_rx_cnt_lvl); | ||
1009 | |||
1010 | if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { | ||
1011 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, "HT40\n"); | ||
1012 | /* coex table */ | ||
1013 | btdm8723.val_0x6c0 = 0x55555555; | ||
1014 | btdm8723.val_0x6c8 = 0xffff; | ||
1015 | btdm8723.val_0x6cc = 0x3; | ||
1016 | |||
1017 | /* sw mechanism */ | ||
1018 | btdm8723.agc_table_en = false; | ||
1019 | btdm8723.adc_back_off_on = false; | ||
1020 | btdm8723.sw_dac_swing_on = false; | ||
1021 | |||
1022 | /* fw mechanism */ | ||
1023 | btdm8723.ps_tdma_on = true; | ||
1024 | if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) { | ||
1025 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1026 | "[BTCoex], BT TxRx Counters >= 1400\n"); | ||
1027 | btdm8723.ps_tdma_byte[0] = 0xa3; | ||
1028 | btdm8723.ps_tdma_byte[1] = 0x5; | ||
1029 | btdm8723.ps_tdma_byte[2] = 0x5; | ||
1030 | btdm8723.ps_tdma_byte[3] = 0x2; | ||
1031 | btdm8723.ps_tdma_byte[4] = 0x80; | ||
1032 | } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) { | ||
1033 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1034 | "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"); | ||
1035 | btdm8723.ps_tdma_byte[0] = 0xa3; | ||
1036 | btdm8723.ps_tdma_byte[1] = 0xa; | ||
1037 | btdm8723.ps_tdma_byte[2] = 0xa; | ||
1038 | btdm8723.ps_tdma_byte[3] = 0x2; | ||
1039 | btdm8723.ps_tdma_byte[4] = 0x80; | ||
1040 | } else { | ||
1041 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1042 | "[BTCoex], BT TxRx Counters < 1200\n"); | ||
1043 | btdm8723.ps_tdma_byte[0] = 0xa3; | ||
1044 | btdm8723.ps_tdma_byte[1] = 0xf; | ||
1045 | btdm8723.ps_tdma_byte[2] = 0xf; | ||
1046 | btdm8723.ps_tdma_byte[3] = 0x2; | ||
1047 | btdm8723.ps_tdma_byte[4] = 0x80; | ||
1048 | } | ||
1049 | } else { | ||
1050 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1051 | "HT20 or Legacy\n"); | ||
1052 | bt_rssi_state = rtl8723ae_dm_bt_check_coex_rssi_state(hw, 2, | ||
1053 | 47, 0); | ||
1054 | bt_rssi_state1 = rtl8723ae_dm_bt_check_coex_rssi_state1(hw, 2, | ||
1055 | 27, 0); | ||
1056 | |||
1057 | /* coex table */ | ||
1058 | btdm8723.val_0x6c0 = 0x55555555; | ||
1059 | btdm8723.val_0x6c8 = 0xffff; | ||
1060 | btdm8723.val_0x6cc = 0x3; | ||
1061 | |||
1062 | /* sw mechanism */ | ||
1063 | if ((bt_rssi_state == BT_RSSI_STATE_HIGH) || | ||
1064 | (bt_rssi_state == BT_RSSI_STATE_STAY_HIGH)) { | ||
1065 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1066 | "Wifi rssi high\n"); | ||
1067 | btdm8723.agc_table_en = true; | ||
1068 | btdm8723.adc_back_off_on = true; | ||
1069 | btdm8723.sw_dac_swing_on = false; | ||
1070 | } else { | ||
1071 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1072 | "Wifi rssi low\n"); | ||
1073 | btdm8723.agc_table_en = false; | ||
1074 | btdm8723.adc_back_off_on = false; | ||
1075 | btdm8723.sw_dac_swing_on = false; | ||
1076 | } | ||
1077 | |||
1078 | /* fw mechanism */ | ||
1079 | btdm8723.ps_tdma_on = true; | ||
1080 | if ((bt_rssi_state1 == BT_RSSI_STATE_HIGH) || | ||
1081 | (bt_rssi_state1 == BT_RSSI_STATE_STAY_HIGH)) { | ||
1082 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1083 | "Wifi rssi-1 high\n"); | ||
1084 | /* only rssi high we need to do this, | ||
1085 | * when rssi low, the value will modified by fw | ||
1086 | */ | ||
1087 | rtl_write_byte(rtlpriv, 0x883, 0x40); | ||
1088 | if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) { | ||
1089 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1090 | "[BTCoex], BT TxRx Counters >= 1400\n"); | ||
1091 | btdm8723.ps_tdma_byte[0] = 0xa3; | ||
1092 | btdm8723.ps_tdma_byte[1] = 0x5; | ||
1093 | btdm8723.ps_tdma_byte[2] = 0x5; | ||
1094 | btdm8723.ps_tdma_byte[3] = 0x83; | ||
1095 | btdm8723.ps_tdma_byte[4] = 0x80; | ||
1096 | } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) { | ||
1097 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1098 | "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"); | ||
1099 | btdm8723.ps_tdma_byte[0] = 0xa3; | ||
1100 | btdm8723.ps_tdma_byte[1] = 0xa; | ||
1101 | btdm8723.ps_tdma_byte[2] = 0xa; | ||
1102 | btdm8723.ps_tdma_byte[3] = 0x83; | ||
1103 | btdm8723.ps_tdma_byte[4] = 0x80; | ||
1104 | } else { | ||
1105 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1106 | "[BTCoex], BT TxRx Counters < 1200\n"); | ||
1107 | btdm8723.ps_tdma_byte[0] = 0xa3; | ||
1108 | btdm8723.ps_tdma_byte[1] = 0xf; | ||
1109 | btdm8723.ps_tdma_byte[2] = 0xf; | ||
1110 | btdm8723.ps_tdma_byte[3] = 0x83; | ||
1111 | btdm8723.ps_tdma_byte[4] = 0x80; | ||
1112 | } | ||
1113 | } else { | ||
1114 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1115 | "Wifi rssi-1 low\n"); | ||
1116 | if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) { | ||
1117 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1118 | "[BTCoex], BT TxRx Counters >= 1400\n"); | ||
1119 | btdm8723.ps_tdma_byte[0] = 0xa3; | ||
1120 | btdm8723.ps_tdma_byte[1] = 0x5; | ||
1121 | btdm8723.ps_tdma_byte[2] = 0x5; | ||
1122 | btdm8723.ps_tdma_byte[3] = 0x2; | ||
1123 | btdm8723.ps_tdma_byte[4] = 0x80; | ||
1124 | } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) { | ||
1125 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1126 | "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"); | ||
1127 | btdm8723.ps_tdma_byte[0] = 0xa3; | ||
1128 | btdm8723.ps_tdma_byte[1] = 0xa; | ||
1129 | btdm8723.ps_tdma_byte[2] = 0xa; | ||
1130 | btdm8723.ps_tdma_byte[3] = 0x2; | ||
1131 | btdm8723.ps_tdma_byte[4] = 0x80; | ||
1132 | } else { | ||
1133 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1134 | "[BTCoex], BT TxRx Counters < 1200\n"); | ||
1135 | btdm8723.ps_tdma_byte[0] = 0xa3; | ||
1136 | btdm8723.ps_tdma_byte[1] = 0xf; | ||
1137 | btdm8723.ps_tdma_byte[2] = 0xf; | ||
1138 | btdm8723.ps_tdma_byte[3] = 0x2; | ||
1139 | btdm8723.ps_tdma_byte[4] = 0x80; | ||
1140 | } | ||
1141 | } | ||
1142 | } | ||
1143 | |||
1144 | if (rtl8723ae_dm_bt_need_to_dec_bt_pwr(hw)) | ||
1145 | btdm8723.dec_bt_pwr = true; | ||
1146 | |||
1147 | /* Always ignore WlanAct if bHid|bSCOBusy|bSCOeSCO */ | ||
1148 | |||
1149 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1150 | "[BTCoex], BT btInqPageStartTime = 0x%x, btTxRxCntLvl = %d\n", | ||
1151 | rtlhal->hal_coex_8723.bt_inq_page_start_time, | ||
1152 | bt_tx_rx_cnt_lvl); | ||
1153 | if ((rtlhal->hal_coex_8723.bt_inq_page_start_time) || | ||
1154 | (BT_TXRX_CNT_LEVEL_3 == bt_tx_rx_cnt_lvl)) { | ||
1155 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1156 | "[BTCoex], Set BT inquiry / page scan 0x3a setting\n"); | ||
1157 | btdm8723.ps_tdma_on = true; | ||
1158 | btdm8723.ps_tdma_byte[0] = 0xa3; | ||
1159 | btdm8723.ps_tdma_byte[1] = 0x5; | ||
1160 | btdm8723.ps_tdma_byte[2] = 0x5; | ||
1161 | btdm8723.ps_tdma_byte[3] = 0x2; | ||
1162 | btdm8723.ps_tdma_byte[4] = 0x80; | ||
1163 | } | ||
1164 | |||
1165 | if (rtl8723ae_dm_bt_is_coexist_state_changed(hw)) | ||
1166 | rtl8723ae_dm_bt_set_bt_dm(hw, &btdm8723); | ||
1167 | } | ||
1168 | |||
1169 | static void rtl8723ae_dm_bt_2_ant_fta2dp(struct ieee80211_hw *hw) | ||
1170 | { | ||
1171 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1172 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | ||
1173 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1174 | struct btdm_8723 btdm8723; | ||
1175 | u8 bt_rssi_state, bt_rssi_state1; | ||
1176 | u32 bt_tx_rx_cnt_lvl; | ||
1177 | |||
1178 | rtl8723ae_dm_bt_btdm_structure_reload(hw, &btdm8723); | ||
1179 | btdm8723.rf_rx_lpf_shrink = true; | ||
1180 | btdm8723.low_penalty_rate_adaptive = true; | ||
1181 | btdm8723.reject_aggre_pkt = false; | ||
1182 | |||
1183 | bt_tx_rx_cnt_lvl = rtl8723ae_dm_bt_bt_tx_rx_counter_level(hw); | ||
1184 | |||
1185 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1186 | "[BTCoex], BT TxRx Counters = %d\n", bt_tx_rx_cnt_lvl); | ||
1187 | |||
1188 | if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { | ||
1189 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, "HT40\n"); | ||
1190 | bt_rssi_state = rtl8723ae_dm_bt_check_coex_rssi_state(hw, 2, | ||
1191 | 37, 0); | ||
1192 | |||
1193 | /* coex table */ | ||
1194 | btdm8723.val_0x6c0 = 0x55555555; | ||
1195 | btdm8723.val_0x6c8 = 0xffff; | ||
1196 | btdm8723.val_0x6cc = 0x3; | ||
1197 | |||
1198 | /* sw mechanism */ | ||
1199 | btdm8723.agc_table_en = false; | ||
1200 | btdm8723.adc_back_off_on = true; | ||
1201 | btdm8723.sw_dac_swing_on = false; | ||
1202 | |||
1203 | /* fw mechanism */ | ||
1204 | btdm8723.ps_tdma_on = true; | ||
1205 | if ((bt_rssi_state == BT_RSSI_STATE_HIGH) || | ||
1206 | (bt_rssi_state == BT_RSSI_STATE_STAY_HIGH)) { | ||
1207 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1208 | "Wifi rssi high\n"); | ||
1209 | if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) { | ||
1210 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1211 | "[BTCoex], BT TxRx Counters >= 1400\n"); | ||
1212 | btdm8723.ps_tdma_byte[0] = 0xa3; | ||
1213 | btdm8723.ps_tdma_byte[1] = 0x5; | ||
1214 | btdm8723.ps_tdma_byte[2] = 0x5; | ||
1215 | btdm8723.ps_tdma_byte[3] = 0x81; | ||
1216 | btdm8723.ps_tdma_byte[4] = 0x80; | ||
1217 | } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) { | ||
1218 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1219 | "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"); | ||
1220 | btdm8723.ps_tdma_byte[0] = 0xa3; | ||
1221 | btdm8723.ps_tdma_byte[1] = 0xa; | ||
1222 | btdm8723.ps_tdma_byte[2] = 0xa; | ||
1223 | btdm8723.ps_tdma_byte[3] = 0x81; | ||
1224 | btdm8723.ps_tdma_byte[4] = 0x80; | ||
1225 | } else { | ||
1226 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1227 | "[BTCoex], BT TxRx Counters < 1200\n"); | ||
1228 | btdm8723.ps_tdma_byte[0] = 0xa3; | ||
1229 | btdm8723.ps_tdma_byte[1] = 0xf; | ||
1230 | btdm8723.ps_tdma_byte[2] = 0xf; | ||
1231 | btdm8723.ps_tdma_byte[3] = 0x81; | ||
1232 | btdm8723.ps_tdma_byte[4] = 0x80; | ||
1233 | } | ||
1234 | } else { | ||
1235 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1236 | "Wifi rssi low\n"); | ||
1237 | if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) { | ||
1238 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1239 | "[BTCoex], BT TxRx Counters >= 1400\n"); | ||
1240 | btdm8723.ps_tdma_byte[0] = 0xa3; | ||
1241 | btdm8723.ps_tdma_byte[1] = 0x5; | ||
1242 | btdm8723.ps_tdma_byte[2] = 0x5; | ||
1243 | btdm8723.ps_tdma_byte[3] = 0x0; | ||
1244 | btdm8723.ps_tdma_byte[4] = 0x80; | ||
1245 | } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) { | ||
1246 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1247 | "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"); | ||
1248 | btdm8723.ps_tdma_byte[0] = 0xa3; | ||
1249 | btdm8723.ps_tdma_byte[1] = 0xa; | ||
1250 | btdm8723.ps_tdma_byte[2] = 0xa; | ||
1251 | btdm8723.ps_tdma_byte[3] = 0x0; | ||
1252 | btdm8723.ps_tdma_byte[4] = 0x80; | ||
1253 | } else { | ||
1254 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1255 | "[BTCoex], BT TxRx Counters < 1200\n"); | ||
1256 | btdm8723.ps_tdma_byte[0] = 0xa3; | ||
1257 | btdm8723.ps_tdma_byte[1] = 0xf; | ||
1258 | btdm8723.ps_tdma_byte[2] = 0xf; | ||
1259 | btdm8723.ps_tdma_byte[3] = 0x0; | ||
1260 | btdm8723.ps_tdma_byte[4] = 0x80; | ||
1261 | } | ||
1262 | } | ||
1263 | } else { | ||
1264 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1265 | "HT20 or Legacy\n"); | ||
1266 | bt_rssi_state = rtl8723ae_dm_bt_check_coex_rssi_state(hw, 2, | ||
1267 | 47, 0); | ||
1268 | bt_rssi_state1 = rtl8723ae_dm_bt_check_coex_rssi_state1(hw, 2, | ||
1269 | 27, 0); | ||
1270 | |||
1271 | /* coex table */ | ||
1272 | btdm8723.val_0x6c0 = 0x55555555; | ||
1273 | btdm8723.val_0x6c8 = 0xffff; | ||
1274 | btdm8723.val_0x6cc = 0x3; | ||
1275 | |||
1276 | /* sw mechanism */ | ||
1277 | if ((bt_rssi_state == BT_RSSI_STATE_HIGH) || | ||
1278 | (bt_rssi_state == BT_RSSI_STATE_STAY_HIGH)) { | ||
1279 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1280 | "Wifi rssi high\n"); | ||
1281 | btdm8723.agc_table_en = true; | ||
1282 | btdm8723.adc_back_off_on = true; | ||
1283 | btdm8723.sw_dac_swing_on = false; | ||
1284 | } else { | ||
1285 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1286 | "Wifi rssi low\n"); | ||
1287 | btdm8723.agc_table_en = false; | ||
1288 | btdm8723.adc_back_off_on = false; | ||
1289 | btdm8723.sw_dac_swing_on = false; | ||
1290 | } | ||
1291 | |||
1292 | /* fw mechanism */ | ||
1293 | btdm8723.ps_tdma_on = true; | ||
1294 | if ((bt_rssi_state1 == BT_RSSI_STATE_HIGH) || | ||
1295 | (bt_rssi_state1 == BT_RSSI_STATE_STAY_HIGH)) { | ||
1296 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1297 | "Wifi rssi-1 high\n"); | ||
1298 | /* only rssi high we need to do this, | ||
1299 | * when rssi low, the value will modified by fw | ||
1300 | */ | ||
1301 | rtl_write_byte(rtlpriv, 0x883, 0x40); | ||
1302 | if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) { | ||
1303 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1304 | "[BTCoex], BT TxRx Counters >= 1400\n"); | ||
1305 | btdm8723.ps_tdma_byte[0] = 0xa3; | ||
1306 | btdm8723.ps_tdma_byte[1] = 0x5; | ||
1307 | btdm8723.ps_tdma_byte[2] = 0x5; | ||
1308 | btdm8723.ps_tdma_byte[3] = 0x81; | ||
1309 | btdm8723.ps_tdma_byte[4] = 0x80; | ||
1310 | } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) { | ||
1311 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1312 | "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"); | ||
1313 | btdm8723.ps_tdma_byte[0] = 0xa3; | ||
1314 | btdm8723.ps_tdma_byte[1] = 0xa; | ||
1315 | btdm8723.ps_tdma_byte[2] = 0xa; | ||
1316 | btdm8723.ps_tdma_byte[3] = 0x81; | ||
1317 | btdm8723.ps_tdma_byte[4] = 0x80; | ||
1318 | } else { | ||
1319 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1320 | "[BTCoex], BT TxRx Counters < 1200\n"); | ||
1321 | btdm8723.ps_tdma_byte[0] = 0xa3; | ||
1322 | btdm8723.ps_tdma_byte[1] = 0xf; | ||
1323 | btdm8723.ps_tdma_byte[2] = 0xf; | ||
1324 | btdm8723.ps_tdma_byte[3] = 0x81; | ||
1325 | btdm8723.ps_tdma_byte[4] = 0x80; | ||
1326 | } | ||
1327 | } else { | ||
1328 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1329 | "Wifi rssi-1 low\n"); | ||
1330 | if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) { | ||
1331 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1332 | "[BTCoex], BT TxRx Counters >= 1400\n"); | ||
1333 | btdm8723.ps_tdma_byte[0] = 0xa3; | ||
1334 | btdm8723.ps_tdma_byte[1] = 0x5; | ||
1335 | btdm8723.ps_tdma_byte[2] = 0x5; | ||
1336 | btdm8723.ps_tdma_byte[3] = 0x0; | ||
1337 | btdm8723.ps_tdma_byte[4] = 0x80; | ||
1338 | } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) { | ||
1339 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1340 | "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"); | ||
1341 | btdm8723.ps_tdma_byte[0] = 0xa3; | ||
1342 | btdm8723.ps_tdma_byte[1] = 0xa; | ||
1343 | btdm8723.ps_tdma_byte[2] = 0xa; | ||
1344 | btdm8723.ps_tdma_byte[3] = 0x0; | ||
1345 | btdm8723.ps_tdma_byte[4] = 0x80; | ||
1346 | } else { | ||
1347 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1348 | "[BTCoex], BT TxRx Counters < 1200\n"); | ||
1349 | btdm8723.ps_tdma_byte[0] = 0xa3; | ||
1350 | btdm8723.ps_tdma_byte[1] = 0xf; | ||
1351 | btdm8723.ps_tdma_byte[2] = 0xf; | ||
1352 | btdm8723.ps_tdma_byte[3] = 0x0; | ||
1353 | btdm8723.ps_tdma_byte[4] = 0x80; | ||
1354 | } | ||
1355 | } | ||
1356 | } | ||
1357 | |||
1358 | if (rtl8723ae_dm_bt_need_to_dec_bt_pwr(hw)) | ||
1359 | btdm8723.dec_bt_pwr = true; | ||
1360 | |||
1361 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1362 | "[BTCoex], BT btInqPageStartTime = 0x%x, btTxRxCntLvl = %d\n", | ||
1363 | rtlhal->hal_coex_8723.bt_inq_page_start_time, | ||
1364 | bt_tx_rx_cnt_lvl); | ||
1365 | |||
1366 | if ((rtlhal->hal_coex_8723.bt_inq_page_start_time) || | ||
1367 | (BT_TXRX_CNT_LEVEL_3 == bt_tx_rx_cnt_lvl)) { | ||
1368 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1369 | "[BTCoex], Set BT inquiry / page scan 0x3a setting\n"); | ||
1370 | btdm8723.ps_tdma_on = true; | ||
1371 | btdm8723.ps_tdma_byte[0] = 0xa3; | ||
1372 | btdm8723.ps_tdma_byte[1] = 0x5; | ||
1373 | btdm8723.ps_tdma_byte[2] = 0x5; | ||
1374 | btdm8723.ps_tdma_byte[3] = 0x83; | ||
1375 | btdm8723.ps_tdma_byte[4] = 0x80; | ||
1376 | } | ||
1377 | |||
1378 | if (rtl8723ae_dm_bt_is_coexist_state_changed(hw)) | ||
1379 | rtl8723ae_dm_bt_set_bt_dm(hw, &btdm8723); | ||
1380 | } | ||
1381 | |||
1382 | static void rtl8723ae_dm_bt_inq_page_monitor(struct ieee80211_hw *hw) | ||
1383 | { | ||
1384 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
1385 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1386 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | ||
1387 | u32 cur_time = jiffies; | ||
1388 | |||
1389 | if (rtlhal->hal_coex_8723.c2h_bt_inquiry_page) { | ||
1390 | /* bt inquiry or page is started. */ | ||
1391 | if (rtlhal->hal_coex_8723.bt_inq_page_start_time == 0) { | ||
1392 | rtlpcipriv->bt_coexist.cstate |= | ||
1393 | BT_COEX_STATE_BT_INQ_PAGE; | ||
1394 | rtlhal->hal_coex_8723.bt_inq_page_start_time = cur_time; | ||
1395 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1396 | "[BTCoex], BT Inquiry/page is started at time : 0x%x\n", | ||
1397 | rtlhal->hal_coex_8723.bt_inq_page_start_time); | ||
1398 | } | ||
1399 | } | ||
1400 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1401 | "[BTCoex], BT Inquiry/page started time : 0x%x, cur_time : 0x%x\n", | ||
1402 | rtlhal->hal_coex_8723.bt_inq_page_start_time, cur_time); | ||
1403 | |||
1404 | if (rtlhal->hal_coex_8723.bt_inq_page_start_time) { | ||
1405 | if ((((long)cur_time - | ||
1406 | (long)rtlhal->hal_coex_8723.bt_inq_page_start_time) / HZ) >= | ||
1407 | 10) { | ||
1408 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1409 | "[BTCoex], BT Inquiry/page >= 10sec!!!"); | ||
1410 | rtlhal->hal_coex_8723.bt_inq_page_start_time = 0; | ||
1411 | rtlpcipriv->bt_coexist.cstate &= | ||
1412 | ~BT_COEX_STATE_BT_INQ_PAGE; | ||
1413 | } | ||
1414 | } | ||
1415 | } | ||
1416 | |||
1417 | static void rtl8723ae_dm_bt_reset_action_profile_state(struct ieee80211_hw *hw) | ||
1418 | { | ||
1419 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
1420 | |||
1421 | rtlpcipriv->bt_coexist.cstate &= | ||
1422 | ~(BT_COEX_STATE_PROFILE_HID | BT_COEX_STATE_PROFILE_A2DP | | ||
1423 | BT_COEX_STATE_PROFILE_PAN | BT_COEX_STATE_PROFILE_SCO); | ||
1424 | |||
1425 | rtlpcipriv->bt_coexist.cstate &= | ||
1426 | ~(BT_COEX_STATE_BTINFO_COMMON | | ||
1427 | BT_COEX_STATE_BTINFO_B_HID_SCOESCO | | ||
1428 | BT_COEX_STATE_BTINFO_B_FTP_A2DP); | ||
1429 | } | ||
1430 | |||
1431 | static void _rtl8723ae_dm_bt_coexist_2_ant(struct ieee80211_hw *hw) | ||
1432 | { | ||
1433 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1434 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | ||
1435 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
1436 | u8 bt_retry_cnt; | ||
1437 | u8 bt_info_original; | ||
1438 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1439 | "[BTCoex] Get bt info by fw!!\n"); | ||
1440 | |||
1441 | _rtl8723_dm_bt_check_wifi_state(hw); | ||
1442 | |||
1443 | if (rtlhal->hal_coex_8723.c2h_bt_info_req_sent) { | ||
1444 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
1445 | "[BTCoex] c2h for btInfo not rcvd yet!!\n"); | ||
1446 | } | ||
1447 | |||
1448 | bt_retry_cnt = rtlhal->hal_coex_8723.bt_retry_cnt; | ||
1449 | bt_info_original = rtlhal->hal_coex_8723.c2h_bt_info_original; | ||
1450 | |||
1451 | /* when bt inquiry or page scan, we have to set h2c 0x25 | ||
1452 | * ignore wlanact for continuous 4x2secs | ||
1453 | */ | ||
1454 | rtl8723ae_dm_bt_inq_page_monitor(hw); | ||
1455 | rtl8723ae_dm_bt_reset_action_profile_state(hw); | ||
1456 | |||
1457 | if (rtl8723ae_dm_bt_is_2_ant_common_action(hw)) { | ||
1458 | rtlpcipriv->bt_coexist.bt_profile_case = BT_COEX_MECH_COMMON; | ||
1459 | rtlpcipriv->bt_coexist.bt_profile_action = BT_COEX_MECH_COMMON; | ||
1460 | |||
1461 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1462 | "Action 2-Ant common.\n"); | ||
1463 | } else { | ||
1464 | if ((bt_info_original & BTINFO_B_HID) || | ||
1465 | (bt_info_original & BTINFO_B_SCO_BUSY) || | ||
1466 | (bt_info_original & BTINFO_B_SCO_ESCO)) { | ||
1467 | rtlpcipriv->bt_coexist.cstate |= | ||
1468 | BT_COEX_STATE_BTINFO_B_HID_SCOESCO; | ||
1469 | rtlpcipriv->bt_coexist.bt_profile_case = | ||
1470 | BT_COEX_MECH_HID_SCO_ESCO; | ||
1471 | rtlpcipriv->bt_coexist.bt_profile_action = | ||
1472 | BT_COEX_MECH_HID_SCO_ESCO; | ||
1473 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1474 | "[BTCoex], BTInfo: bHid|bSCOBusy|bSCOeSCO\n"); | ||
1475 | rtl8723ae_dm_bt_2_ant_hid_sco_esco(hw); | ||
1476 | } else if ((bt_info_original & BTINFO_B_FTP) || | ||
1477 | (bt_info_original & BTINFO_B_A2DP)) { | ||
1478 | rtlpcipriv->bt_coexist.cstate |= | ||
1479 | BT_COEX_STATE_BTINFO_B_FTP_A2DP; | ||
1480 | rtlpcipriv->bt_coexist.bt_profile_case = | ||
1481 | BT_COEX_MECH_FTP_A2DP; | ||
1482 | rtlpcipriv->bt_coexist.bt_profile_action = | ||
1483 | BT_COEX_MECH_FTP_A2DP; | ||
1484 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1485 | "BTInfo: bFTP|bA2DP\n"); | ||
1486 | rtl8723ae_dm_bt_2_ant_fta2dp(hw); | ||
1487 | } else { | ||
1488 | rtlpcipriv->bt_coexist.cstate |= | ||
1489 | BT_COEX_STATE_BTINFO_B_HID_SCOESCO; | ||
1490 | rtlpcipriv->bt_coexist.bt_profile_case = | ||
1491 | BT_COEX_MECH_NONE; | ||
1492 | rtlpcipriv->bt_coexist.bt_profile_action = | ||
1493 | BT_COEX_MECH_NONE; | ||
1494 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1495 | "[BTCoex], BTInfo: undefined case!!!!\n"); | ||
1496 | rtl8723ae_dm_bt_2_ant_hid_sco_esco(hw); | ||
1497 | } | ||
1498 | } | ||
1499 | } | ||
1500 | |||
1501 | static void _rtl8723ae_dm_bt_coexist_1_ant(struct ieee80211_hw *hw) | ||
1502 | { | ||
1503 | } | ||
1504 | |||
1505 | void rtl8723ae_dm_bt_hw_coex_all_off_8723a(struct ieee80211_hw *hw) | ||
1506 | { | ||
1507 | rtl8723ae_dm_bt_set_coex_table(hw, 0x5a5aaaaa, 0xcc, 0x3); | ||
1508 | rtl8723ae_dm_bt_set_hw_pta_mode(hw, true); | ||
1509 | } | ||
1510 | |||
1511 | void rtl8723ae_dm_bt_fw_coex_all_off_8723a(struct ieee80211_hw *hw) | ||
1512 | { | ||
1513 | rtl8723ae_dm_bt_set_fw_ignore_wlan_act(hw, false); | ||
1514 | rtl8723ae_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0); | ||
1515 | rtl8723ae_dm_bt_set_fw_2_ant_hid(hw, false, false); | ||
1516 | rtl8723ae_dm_bt_set_fw_tra_tdma_ctrl(hw, false, | ||
1517 | TDMA_2ANT, TDMA_NAV_OFF); | ||
1518 | rtl8723ae_dm_bt_set_fw_tdma_ctrl(hw, false, TDMA_2ANT, | ||
1519 | TDMA_NAV_OFF, TDMA_DAC_SWING_OFF); | ||
1520 | rtl8723ae_dm_bt_set_fw_dac_swing_level(hw, 0); | ||
1521 | rtl8723ae_dm_bt_set_fw_bt_hid_info(hw, false); | ||
1522 | rtl8723ae_dm_bt_set_fw_bt_retry_index(hw, 2); | ||
1523 | rtl8723ae_dm_bt_set_fw_wlan_act(hw, 0x10, 0x10); | ||
1524 | rtl8723ae_dm_bt_set_fw_dec_bt_pwr(hw, false); | ||
1525 | } | ||
1526 | |||
1527 | void rtl8723ae_dm_bt_sw_coex_all_off_8723a(struct ieee80211_hw *hw) | ||
1528 | { | ||
1529 | rtl8723ae_dm_bt_agc_table(hw, BT_AGCTABLE_OFF); | ||
1530 | rtl8723ae_dm_bt_bback_off_level(hw, BT_BB_BACKOFF_OFF); | ||
1531 | rtl8723ae_dm_bt_reject_ap_aggregated_packet(hw, false); | ||
1532 | |||
1533 | rtl8723ae_bt_set_penalty_tx_rate_adap(hw, BT_TX_RATE_ADAPTIVE_NORMAL); | ||
1534 | rtl8723ae_dm_bt_set_sw_rf_rx_lpf_corner(hw, BT_RF_RX_LPF_CORNER_RESUME); | ||
1535 | rtl8723ae_dm_bt_set_sw_full_time_dac_swing(hw, false, 0xc0); | ||
1536 | } | ||
1537 | |||
1538 | static void rtl8723ae_dm_bt_query_bt_information(struct ieee80211_hw *hw) | ||
1539 | { | ||
1540 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1541 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | ||
1542 | u8 h2c_parameter[1] = {0}; | ||
1543 | |||
1544 | rtlhal->hal_coex_8723.c2h_bt_info_req_sent = true; | ||
1545 | |||
1546 | h2c_parameter[0] |= BIT(0); | ||
1547 | |||
1548 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
1549 | "Query Bt information, write 0x38 = 0x%x\n", | ||
1550 | h2c_parameter[0]); | ||
1551 | |||
1552 | rtl8723ae_fill_h2c_cmd(hw, 0x38, 1, h2c_parameter); | ||
1553 | } | ||
1554 | |||
1555 | static void rtl8723ae_dm_bt_bt_hw_counters_monitor(struct ieee80211_hw *hw) | ||
1556 | { | ||
1557 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1558 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | ||
1559 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
1560 | u32 reg_htx_rx, reg_ltx_rx, u32_tmp; | ||
1561 | u32 reg_htx, reg_hrx, reg_ltx, reg_lrx; | ||
1562 | |||
1563 | reg_htx_rx = REG_HIGH_PRIORITY_TXRX; | ||
1564 | reg_ltx_rx = REG_LOW_PRIORITY_TXRX; | ||
1565 | |||
1566 | u32_tmp = rtl_read_dword(rtlpriv, reg_htx_rx); | ||
1567 | reg_htx = u32_tmp & MASKLWORD; | ||
1568 | reg_hrx = (u32_tmp & MASKHWORD)>>16; | ||
1569 | |||
1570 | u32_tmp = rtl_read_dword(rtlpriv, reg_ltx_rx); | ||
1571 | reg_ltx = u32_tmp & MASKLWORD; | ||
1572 | reg_lrx = (u32_tmp & MASKHWORD)>>16; | ||
1573 | |||
1574 | if (rtlpcipriv->bt_coexist.lps_counter > 1) { | ||
1575 | reg_htx %= rtlpcipriv->bt_coexist.lps_counter; | ||
1576 | reg_hrx %= rtlpcipriv->bt_coexist.lps_counter; | ||
1577 | reg_ltx %= rtlpcipriv->bt_coexist.lps_counter; | ||
1578 | reg_lrx %= rtlpcipriv->bt_coexist.lps_counter; | ||
1579 | } | ||
1580 | |||
1581 | rtlhal->hal_coex_8723.high_priority_tx = reg_htx; | ||
1582 | rtlhal->hal_coex_8723.high_priority_rx = reg_hrx; | ||
1583 | rtlhal->hal_coex_8723.low_priority_tx = reg_ltx; | ||
1584 | rtlhal->hal_coex_8723.low_priority_rx = reg_lrx; | ||
1585 | |||
1586 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1587 | "High Priority Tx/Rx (reg 0x%x)=%x(%d)/%x(%d)\n", | ||
1588 | reg_htx_rx, reg_htx, reg_htx, reg_hrx, reg_hrx); | ||
1589 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1590 | "Low Priority Tx/Rx (reg 0x%x)=%x(%d)/%x(%d)\n", | ||
1591 | reg_ltx_rx, reg_ltx, reg_ltx, reg_lrx, reg_lrx); | ||
1592 | rtlpcipriv->bt_coexist.lps_counter = 0; | ||
1593 | } | ||
1594 | |||
1595 | static void rtl8723ae_dm_bt_bt_enable_disable_check(struct ieee80211_hw *hw) | ||
1596 | { | ||
1597 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1598 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | ||
1599 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
1600 | bool bt_alife = true; | ||
1601 | |||
1602 | if (rtlhal->hal_coex_8723.high_priority_tx == 0 && | ||
1603 | rtlhal->hal_coex_8723.high_priority_rx == 0 && | ||
1604 | rtlhal->hal_coex_8723.low_priority_tx == 0 && | ||
1605 | rtlhal->hal_coex_8723.low_priority_rx == 0) | ||
1606 | bt_alife = false; | ||
1607 | if (rtlhal->hal_coex_8723.high_priority_tx == 0xeaea && | ||
1608 | rtlhal->hal_coex_8723.high_priority_rx == 0xeaea && | ||
1609 | rtlhal->hal_coex_8723.low_priority_tx == 0xeaea && | ||
1610 | rtlhal->hal_coex_8723.low_priority_rx == 0xeaea) | ||
1611 | bt_alife = false; | ||
1612 | if (rtlhal->hal_coex_8723.high_priority_tx == 0xffff && | ||
1613 | rtlhal->hal_coex_8723.high_priority_rx == 0xffff && | ||
1614 | rtlhal->hal_coex_8723.low_priority_tx == 0xffff && | ||
1615 | rtlhal->hal_coex_8723.low_priority_rx == 0xffff) | ||
1616 | bt_alife = false; | ||
1617 | if (bt_alife) { | ||
1618 | rtlpcipriv->bt_coexist.bt_active_zero_cnt = 0; | ||
1619 | rtlpcipriv->bt_coexist.cur_bt_disabled = false; | ||
1620 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
1621 | "8723A BT is enabled !!\n"); | ||
1622 | } else { | ||
1623 | rtlpcipriv->bt_coexist.bt_active_zero_cnt++; | ||
1624 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
1625 | "8723A bt all counters = 0, %d times!!\n", | ||
1626 | rtlpcipriv->bt_coexist.bt_active_zero_cnt); | ||
1627 | if (rtlpcipriv->bt_coexist.bt_active_zero_cnt >= 2) { | ||
1628 | rtlpcipriv->bt_coexist.cur_bt_disabled = true; | ||
1629 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
1630 | "8723A BT is disabled !!\n"); | ||
1631 | } | ||
1632 | } | ||
1633 | if (rtlpcipriv->bt_coexist.pre_bt_disabled != | ||
1634 | rtlpcipriv->bt_coexist.cur_bt_disabled) { | ||
1635 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
1636 | "8723A BT is from %s to %s!!\n", | ||
1637 | (rtlpcipriv->bt_coexist.pre_bt_disabled ? | ||
1638 | "disabled" : "enabled"), | ||
1639 | (rtlpcipriv->bt_coexist.cur_bt_disabled ? | ||
1640 | "disabled" : "enabled")); | ||
1641 | rtlpcipriv->bt_coexist.pre_bt_disabled | ||
1642 | = rtlpcipriv->bt_coexist.cur_bt_disabled; | ||
1643 | } | ||
1644 | } | ||
1645 | |||
1646 | |||
1647 | void rtl8723ae_dm_bt_coexist_8723(struct ieee80211_hw *hw) | ||
1648 | { | ||
1649 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1650 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
1651 | |||
1652 | rtl8723ae_dm_bt_query_bt_information(hw); | ||
1653 | rtl8723ae_dm_bt_bt_hw_counters_monitor(hw); | ||
1654 | rtl8723ae_dm_bt_bt_enable_disable_check(hw); | ||
1655 | |||
1656 | if (rtlpcipriv->bt_coexist.bt_ant_num == ANT_X2) { | ||
1657 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1658 | "[BTCoex], 2 Ant mechanism\n"); | ||
1659 | _rtl8723ae_dm_bt_coexist_2_ant(hw); | ||
1660 | } else { | ||
1661 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
1662 | "[BTCoex], 1 Ant mechanism\n"); | ||
1663 | _rtl8723ae_dm_bt_coexist_1_ant(hw); | ||
1664 | } | ||
1665 | |||
1666 | if (!rtl8723ae_dm_bt_is_same_coexist_state(hw)) { | ||
1667 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1668 | "[BTCoex], Coexist State[bitMap] change from 0x%x%8x to 0x%x%8x\n", | ||
1669 | rtlpcipriv->bt_coexist.previous_state_h, | ||
1670 | rtlpcipriv->bt_coexist.previous_state, | ||
1671 | rtlpcipriv->bt_coexist.cstate_h, | ||
1672 | rtlpcipriv->bt_coexist.cstate); | ||
1673 | rtlpcipriv->bt_coexist.previous_state | ||
1674 | = rtlpcipriv->bt_coexist.cstate; | ||
1675 | rtlpcipriv->bt_coexist.previous_state_h | ||
1676 | = rtlpcipriv->bt_coexist.cstate_h; | ||
1677 | } | ||
1678 | } | ||
1679 | |||
1680 | static void rtl8723ae_dm_bt_parse_bt_info(struct ieee80211_hw *hw, | ||
1681 | u8 *tmbuf, u8 len) | ||
1682 | { | ||
1683 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1684 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | ||
1685 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | ||
1686 | u8 bt_info; | ||
1687 | u8 i; | ||
1688 | |||
1689 | rtlhal->hal_coex_8723.c2h_bt_info_req_sent = false; | ||
1690 | rtlhal->hal_coex_8723.bt_retry_cnt = 0; | ||
1691 | for (i = 0; i < len; i++) { | ||
1692 | if (i == 0) | ||
1693 | rtlhal->hal_coex_8723.c2h_bt_info_original = tmbuf[i]; | ||
1694 | else if (i == 1) | ||
1695 | rtlhal->hal_coex_8723.bt_retry_cnt = tmbuf[i]; | ||
1696 | if (i == len-1) { | ||
1697 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
1698 | "0x%2x]", tmbuf[i]); | ||
1699 | } else { | ||
1700 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
1701 | "0x%2x, ", tmbuf[i]); | ||
1702 | } | ||
1703 | } | ||
1704 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1705 | "BT info bt_info (Data)= 0x%x\n", | ||
1706 | rtlhal->hal_coex_8723.c2h_bt_info_original); | ||
1707 | bt_info = rtlhal->hal_coex_8723.c2h_bt_info_original; | ||
1708 | |||
1709 | if (bt_info & BIT(2)) | ||
1710 | rtlhal->hal_coex_8723.c2h_bt_inquiry_page = true; | ||
1711 | else | ||
1712 | rtlhal->hal_coex_8723.c2h_bt_inquiry_page = false; | ||
1713 | |||
1714 | if (bt_info & BTINFO_B_CONNECTION) { | ||
1715 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1716 | "[BTC2H], BTInfo: bConnect=true\n"); | ||
1717 | rtlpcipriv->bt_coexist.bt_busy = true; | ||
1718 | rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_BT_IDLE; | ||
1719 | } else { | ||
1720 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, | ||
1721 | "[BTC2H], BTInfo: bConnect=false\n"); | ||
1722 | rtlpcipriv->bt_coexist.bt_busy = false; | ||
1723 | rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_BT_IDLE; | ||
1724 | } | ||
1725 | } | ||
1726 | void rtl_8723e_c2h_command_handle(struct ieee80211_hw *hw) | ||
1727 | { | ||
1728 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1729 | struct c2h_evt_hdr c2h_event; | ||
1730 | u8 *ptmbuf; | ||
1731 | u8 index; | ||
1732 | u8 u1tmp; | ||
1733 | |||
1734 | memset(&c2h_event, 0, sizeof(c2h_event)); | ||
1735 | u1tmp = rtl_read_byte(rtlpriv, REG_C2HEVT_MSG_NORMAL); | ||
1736 | RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, | ||
1737 | "&&&&&&: REG_C2HEVT_MSG_NORMAL is 0x%x\n", u1tmp); | ||
1738 | c2h_event.cmd_id = u1tmp & 0xF; | ||
1739 | c2h_event.cmd_len = (u1tmp & 0xF0) >> 4; | ||
1740 | c2h_event.cmd_seq = rtl_read_byte(rtlpriv, REG_C2HEVT_MSG_NORMAL + 1); | ||
1741 | RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, | ||
1742 | "cmd_id: %d, cmd_len: %d, cmd_seq: %d\n", | ||
1743 | c2h_event.cmd_id , c2h_event.cmd_len, c2h_event.cmd_seq); | ||
1744 | u1tmp = rtl_read_byte(rtlpriv, 0x01AF); | ||
1745 | if (u1tmp == C2H_EVT_HOST_CLOSE) { | ||
1746 | return; | ||
1747 | } else if (u1tmp != C2H_EVT_FW_CLOSE) { | ||
1748 | rtl_write_byte(rtlpriv, 0x1AF, 0x00); | ||
1749 | return; | ||
1750 | } | ||
1751 | ptmbuf = kmalloc(c2h_event.cmd_len, GFP_KERNEL); | ||
1752 | if (ptmbuf == NULL) { | ||
1753 | RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, | ||
1754 | "malloc cmd buf failed\n"); | ||
1755 | return; | ||
1756 | } | ||
1757 | |||
1758 | /* Read the content */ | ||
1759 | for (index = 0; index < c2h_event.cmd_len; index++) | ||
1760 | ptmbuf[index] = rtl_read_byte(rtlpriv, REG_C2HEVT_MSG_NORMAL + | ||
1761 | 2 + index); | ||
1762 | |||
1763 | switch (c2h_event.cmd_id) { | ||
1764 | case C2H_BT_RSSI: | ||
1765 | break; | ||
1766 | |||
1767 | case C2H_BT_OP_MODE: | ||
1768 | break; | ||
1769 | |||
1770 | case BT_INFO: | ||
1771 | RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, | ||
1772 | "BT info Byte[0] (ID) is 0x%x\n", c2h_event.cmd_id); | ||
1773 | RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, | ||
1774 | "BT info Byte[1] (Seq) is 0x%x\n", c2h_event.cmd_seq); | ||
1775 | RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, | ||
1776 | "BT info Byte[2] (Data)= 0x%x\n", ptmbuf[0]); | ||
1777 | |||
1778 | rtl8723ae_dm_bt_parse_bt_info(hw, ptmbuf, c2h_event.cmd_len); | ||
1779 | break; | ||
1780 | default: | ||
1781 | break; | ||
1782 | } | ||
1783 | kfree(ptmbuf); | ||
1784 | |||
1785 | rtl_write_byte(rtlpriv, 0x01AF, C2H_EVT_HOST_CLOSE); | ||
1786 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.h b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.h new file mode 100644 index 000000000000..4325ecd58f0c --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.h | |||
@@ -0,0 +1,151 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 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 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
26 | * | ||
27 | **************************************************************************** | ||
28 | */ | ||
29 | |||
30 | #ifndef __RTL8723E_HAL_BTC_H__ | ||
31 | #define __RTL8723E_HAL_BTC_H__ | ||
32 | |||
33 | #include "../wifi.h" | ||
34 | #include "btc.h" | ||
35 | #include "hal_bt_coexist.h" | ||
36 | |||
37 | #define BT_TXRX_CNT_THRES_1 1200 | ||
38 | #define BT_TXRX_CNT_THRES_2 1400 | ||
39 | #define BT_TXRX_CNT_THRES_3 3000 | ||
40 | #define BT_TXRX_CNT_LEVEL_0 0 /* < 1200 */ | ||
41 | #define BT_TXRX_CNT_LEVEL_1 1 /* >= 1200 && < 1400 */ | ||
42 | #define BT_TXRX_CNT_LEVEL_2 2 /* >= 1400 */ | ||
43 | #define BT_TXRX_CNT_LEVEL_3 3 | ||
44 | |||
45 | /* TDMA mode definition */ | ||
46 | #define TDMA_2ANT 0 | ||
47 | #define TDMA_1ANT 1 | ||
48 | #define TDMA_NAV_OFF 0 | ||
49 | #define TDMA_NAV_ON 1 | ||
50 | #define TDMA_DAC_SWING_OFF 0 | ||
51 | #define TDMA_DAC_SWING_ON 1 | ||
52 | |||
53 | /* PTA mode related definition */ | ||
54 | #define BT_PTA_MODE_OFF 0 | ||
55 | #define BT_PTA_MODE_ON 1 | ||
56 | |||
57 | /* Penalty Tx Rate Adaptive */ | ||
58 | #define BT_TX_RATE_ADAPTIVE_NORMAL 0 | ||
59 | #define BT_TX_RATE_ADAPTIVE_LOW_PENALTY 1 | ||
60 | |||
61 | /* RF Corner */ | ||
62 | #define BT_RF_RX_LPF_CORNER_RESUME 0 | ||
63 | #define BT_RF_RX_LPF_CORNER_SHRINK 1 | ||
64 | |||
65 | #define C2H_EVT_HOST_CLOSE 0x00 | ||
66 | #define C2H_EVT_FW_CLOSE 0xFF | ||
67 | |||
68 | enum bt_traffic_mode { | ||
69 | BT_MOTOR_EXT_BE = 0x00, | ||
70 | BT_MOTOR_EXT_GUL = 0x01, | ||
71 | BT_MOTOR_EXT_GUB = 0x02, | ||
72 | BT_MOTOR_EXT_GULB = 0x03 | ||
73 | }; | ||
74 | |||
75 | enum bt_traffic_mode_profile { | ||
76 | BT_PROFILE_NONE, | ||
77 | BT_PROFILE_A2DP, | ||
78 | BT_PROFILE_PAN, | ||
79 | BT_PROFILE_HID, | ||
80 | BT_PROFILE_SCO | ||
81 | }; | ||
82 | |||
83 | enum hci_ext_bt_operation { | ||
84 | HCI_BT_OP_NONE = 0x0, | ||
85 | HCI_BT_OP_INQUIRE_START = 0x1, | ||
86 | HCI_BT_OP_INQUIRE_FINISH = 0x2, | ||
87 | HCI_BT_OP_PAGING_START = 0x3, | ||
88 | HCI_BT_OP_PAGING_SUCCESS = 0x4, | ||
89 | HCI_BT_OP_PAGING_UNSUCCESS = 0x5, | ||
90 | HCI_BT_OP_PAIRING_START = 0x6, | ||
91 | HCI_BT_OP_PAIRING_FINISH = 0x7, | ||
92 | HCI_BT_OP_BT_DEV_ENABLE = 0x8, | ||
93 | HCI_BT_OP_BT_DEV_DISABLE = 0x9, | ||
94 | HCI_BT_OP_MAX, | ||
95 | }; | ||
96 | |||
97 | enum bt_spec { | ||
98 | BT_SPEC_1_0_b = 0x00, | ||
99 | BT_SPEC_1_1 = 0x01, | ||
100 | BT_SPEC_1_2 = 0x02, | ||
101 | BT_SPEC_2_0_EDR = 0x03, | ||
102 | BT_SPEC_2_1_EDR = 0x04, | ||
103 | BT_SPEC_3_0_HS = 0x05, | ||
104 | BT_SPEC_4_0 = 0x06 | ||
105 | }; | ||
106 | |||
107 | struct c2h_evt_hdr { | ||
108 | u8 cmd_id; | ||
109 | u8 cmd_len; | ||
110 | u8 cmd_seq; | ||
111 | }; | ||
112 | |||
113 | enum bt_state { | ||
114 | BT_INFO_STATE_DISABLED = 0, | ||
115 | BT_INFO_STATE_NO_CONNECTION = 1, | ||
116 | BT_INFO_STATE_CONNECT_IDLE = 2, | ||
117 | BT_INFO_STATE_INQ_OR_PAG = 3, | ||
118 | BT_INFO_STATE_ACL_ONLY_BUSY = 4, | ||
119 | BT_INFO_STATE_SCO_ONLY_BUSY = 5, | ||
120 | BT_INFO_STATE_ACL_SCO_BUSY = 6, | ||
121 | BT_INFO_STATE_HID_BUSY = 7, | ||
122 | BT_INFO_STATE_HID_SCO_BUSY = 8, | ||
123 | BT_INFO_STATE_MAX = 7 | ||
124 | }; | ||
125 | |||
126 | enum rtl8723ae_c2h_evt { | ||
127 | C2H_DBG = 0, | ||
128 | C2H_TSF = 1, | ||
129 | C2H_AP_RPT_RSP = 2, | ||
130 | C2H_CCX_TX_RPT = 3, /* The FW notify the report of the specific */ | ||
131 | /* tx packet. */ | ||
132 | C2H_BT_RSSI = 4, | ||
133 | C2H_BT_OP_MODE = 5, | ||
134 | C2H_HW_INFO_EXCH = 10, | ||
135 | C2H_C2H_H2C_TEST = 11, | ||
136 | BT_INFO = 12, | ||
137 | MAX_C2HEVENT | ||
138 | }; | ||
139 | |||
140 | void rtl8723ae_dm_bt_fw_coex_all_off_8723a(struct ieee80211_hw *hw); | ||
141 | void rtl8723ae_dm_bt_sw_coex_all_off_8723a(struct ieee80211_hw *hw); | ||
142 | void rtl8723ae_dm_bt_hw_coex_all_off_8723a(struct ieee80211_hw *hw); | ||
143 | void rtl8723ae_dm_bt_coexist_8723(struct ieee80211_hw *hw); | ||
144 | void rtl8723ae_dm_bt_set_bt_dm(struct ieee80211_hw *hw, | ||
145 | struct btdm_8723 *p_btdm); | ||
146 | void rtl_8723e_c2h_command_handle(struct ieee80211_hw *hw); | ||
147 | void rtl_8723e_bt_wifi_media_status_notify(struct ieee80211_hw *hw, | ||
148 | bool mstatus); | ||
149 | void rtl8723ae_bt_coex_off_before_lps(struct ieee80211_hw *hw); | ||
150 | |||
151 | #endif | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c new file mode 100644 index 000000000000..0a8c03863fb2 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c | |||
@@ -0,0 +1,2380 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 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 "../efuse.h" | ||
32 | #include "../base.h" | ||
33 | #include "../regd.h" | ||
34 | #include "../cam.h" | ||
35 | #include "../ps.h" | ||
36 | #include "../pci.h" | ||
37 | #include "reg.h" | ||
38 | #include "def.h" | ||
39 | #include "phy.h" | ||
40 | #include "dm.h" | ||
41 | #include "fw.h" | ||
42 | #include "led.h" | ||
43 | #include "hw.h" | ||
44 | #include "pwrseqcmd.h" | ||
45 | #include "pwrseq.h" | ||
46 | #include "btc.h" | ||
47 | |||
48 | static void _rtl8723ae_set_bcn_ctrl_reg(struct ieee80211_hw *hw, | ||
49 | u8 set_bits, u8 clear_bits) | ||
50 | { | ||
51 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
52 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
53 | |||
54 | rtlpci->reg_bcn_ctrl_val |= set_bits; | ||
55 | rtlpci->reg_bcn_ctrl_val &= ~clear_bits; | ||
56 | |||
57 | rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8) rtlpci->reg_bcn_ctrl_val); | ||
58 | } | ||
59 | |||
60 | static void _rtl8723ae_stop_tx_beacon(struct ieee80211_hw *hw) | ||
61 | { | ||
62 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
63 | u8 tmp1byte; | ||
64 | |||
65 | tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); | ||
66 | rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6))); | ||
67 | rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64); | ||
68 | tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); | ||
69 | tmp1byte &= ~(BIT(0)); | ||
70 | rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); | ||
71 | } | ||
72 | |||
73 | static void _rtl8723ae_resume_tx_beacon(struct ieee80211_hw *hw) | ||
74 | { | ||
75 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
76 | u8 tmp1byte; | ||
77 | |||
78 | tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); | ||
79 | rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6)); | ||
80 | rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); | ||
81 | tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); | ||
82 | tmp1byte |= BIT(1); | ||
83 | rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); | ||
84 | } | ||
85 | |||
86 | static void _rtl8723ae_enable_bcn_sufunc(struct ieee80211_hw *hw) | ||
87 | { | ||
88 | _rtl8723ae_set_bcn_ctrl_reg(hw, 0, BIT(1)); | ||
89 | } | ||
90 | |||
91 | static void _rtl8723ae_disable_bcn_sufunc(struct ieee80211_hw *hw) | ||
92 | { | ||
93 | _rtl8723ae_set_bcn_ctrl_reg(hw, BIT(1), 0); | ||
94 | } | ||
95 | |||
96 | void rtl8723ae_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | ||
97 | { | ||
98 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
99 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
100 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
101 | |||
102 | switch (variable) { | ||
103 | case HW_VAR_RCR: | ||
104 | *((u32 *) (val)) = rtlpci->receive_config; | ||
105 | break; | ||
106 | case HW_VAR_RF_STATE: | ||
107 | *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state; | ||
108 | break; | ||
109 | case HW_VAR_FWLPS_RF_ON:{ | ||
110 | enum rf_pwrstate rfState; | ||
111 | u32 val_rcr; | ||
112 | |||
113 | rtlpriv->cfg->ops->get_hw_reg(hw, | ||
114 | HW_VAR_RF_STATE, | ||
115 | (u8 *) (&rfState)); | ||
116 | if (rfState == ERFOFF) { | ||
117 | *((bool *) (val)) = true; | ||
118 | } else { | ||
119 | val_rcr = rtl_read_dword(rtlpriv, REG_RCR); | ||
120 | val_rcr &= 0x00070000; | ||
121 | if (val_rcr) | ||
122 | *((bool *) (val)) = false; | ||
123 | else | ||
124 | *((bool *) (val)) = true; | ||
125 | } | ||
126 | break; } | ||
127 | case HW_VAR_FW_PSMODE_STATUS: | ||
128 | *((bool *) (val)) = ppsc->fw_current_inpsmode; | ||
129 | break; | ||
130 | case HW_VAR_CORRECT_TSF:{ | ||
131 | u64 tsf; | ||
132 | u32 *ptsf_low = (u32 *)&tsf; | ||
133 | u32 *ptsf_high = ((u32 *)&tsf) + 1; | ||
134 | |||
135 | *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4)); | ||
136 | *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); | ||
137 | |||
138 | *((u64 *) (val)) = tsf; | ||
139 | |||
140 | break; } | ||
141 | default: | ||
142 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
143 | "switch case not process\n"); | ||
144 | break; | ||
145 | } | ||
146 | } | ||
147 | |||
148 | void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) | ||
149 | { | ||
150 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
151 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); | ||
152 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
153 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
154 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
155 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
156 | u8 idx; | ||
157 | |||
158 | switch (variable) { | ||
159 | case HW_VAR_ETHER_ADDR: | ||
160 | for (idx = 0; idx < ETH_ALEN; idx++) { | ||
161 | rtl_write_byte(rtlpriv, (REG_MACID + idx), | ||
162 | val[idx]); | ||
163 | } | ||
164 | break; | ||
165 | case HW_VAR_BASIC_RATE:{ | ||
166 | u16 rate_cfg = ((u16 *) val)[0]; | ||
167 | u8 rate_index = 0; | ||
168 | rate_cfg = rate_cfg & 0x15f; | ||
169 | rate_cfg |= 0x01; | ||
170 | rtl_write_byte(rtlpriv, REG_RRSR, rate_cfg & 0xff); | ||
171 | rtl_write_byte(rtlpriv, REG_RRSR + 1, | ||
172 | (rate_cfg >> 8) & 0xff); | ||
173 | while (rate_cfg > 0x1) { | ||
174 | rate_cfg = (rate_cfg >> 1); | ||
175 | rate_index++; | ||
176 | } | ||
177 | rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, | ||
178 | rate_index); | ||
179 | break; } | ||
180 | case HW_VAR_BSSID: | ||
181 | for (idx = 0; idx < ETH_ALEN; idx++) { | ||
182 | rtl_write_byte(rtlpriv, (REG_BSSID + idx), | ||
183 | val[idx]); | ||
184 | } | ||
185 | break; | ||
186 | case HW_VAR_SIFS: | ||
187 | rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]); | ||
188 | rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]); | ||
189 | |||
190 | rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]); | ||
191 | rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]); | ||
192 | |||
193 | if (!mac->ht_enable) | ||
194 | rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, | ||
195 | 0x0e0e); | ||
196 | else | ||
197 | rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, | ||
198 | *((u16 *) val)); | ||
199 | break; | ||
200 | case HW_VAR_SLOT_TIME:{ | ||
201 | u8 e_aci; | ||
202 | |||
203 | RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, | ||
204 | "HW_VAR_SLOT_TIME %x\n", val[0]); | ||
205 | |||
206 | rtl_write_byte(rtlpriv, REG_SLOT, val[0]); | ||
207 | |||
208 | for (e_aci = 0; e_aci < AC_MAX; e_aci++) { | ||
209 | rtlpriv->cfg->ops->set_hw_reg(hw, | ||
210 | HW_VAR_AC_PARAM, | ||
211 | (u8 *) (&e_aci)); | ||
212 | } | ||
213 | break; } | ||
214 | case HW_VAR_ACK_PREAMBLE:{ | ||
215 | u8 reg_tmp; | ||
216 | u8 short_preamble = (bool) (*(u8 *) val); | ||
217 | reg_tmp = (mac->cur_40_prime_sc) << 5; | ||
218 | if (short_preamble) | ||
219 | reg_tmp |= 0x80; | ||
220 | |||
221 | rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_tmp); | ||
222 | break; } | ||
223 | case HW_VAR_AMPDU_MIN_SPACE:{ | ||
224 | u8 min_spacing_to_set; | ||
225 | u8 sec_min_space; | ||
226 | |||
227 | min_spacing_to_set = *((u8 *) val); | ||
228 | if (min_spacing_to_set <= 7) { | ||
229 | sec_min_space = 0; | ||
230 | |||
231 | if (min_spacing_to_set < sec_min_space) | ||
232 | min_spacing_to_set = sec_min_space; | ||
233 | |||
234 | mac->min_space_cfg = ((mac->min_space_cfg & | ||
235 | 0xf8) | | ||
236 | min_spacing_to_set); | ||
237 | |||
238 | *val = min_spacing_to_set; | ||
239 | |||
240 | RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, | ||
241 | "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", | ||
242 | mac->min_space_cfg); | ||
243 | |||
244 | rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, | ||
245 | mac->min_space_cfg); | ||
246 | } | ||
247 | break; } | ||
248 | case HW_VAR_SHORTGI_DENSITY:{ | ||
249 | u8 density_to_set; | ||
250 | |||
251 | density_to_set = *((u8 *) val); | ||
252 | mac->min_space_cfg |= (density_to_set << 3); | ||
253 | |||
254 | RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, | ||
255 | "Set HW_VAR_SHORTGI_DENSITY: %#x\n", | ||
256 | mac->min_space_cfg); | ||
257 | |||
258 | rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, | ||
259 | mac->min_space_cfg); | ||
260 | |||
261 | break; } | ||
262 | case HW_VAR_AMPDU_FACTOR:{ | ||
263 | u8 regtoset_normal[4] = {0x41, 0xa8, 0x72, 0xb9}; | ||
264 | u8 regtoset_bt[4] = {0x31, 0x74, 0x42, 0x97}; | ||
265 | u8 factor_toset; | ||
266 | u8 *p_regtoset = NULL; | ||
267 | u8 index; | ||
268 | |||
269 | if ((pcipriv->bt_coexist.bt_coexistence) && | ||
270 | (pcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4)) | ||
271 | p_regtoset = regtoset_bt; | ||
272 | else | ||
273 | p_regtoset = regtoset_normal; | ||
274 | |||
275 | factor_toset = *((u8 *) val); | ||
276 | if (factor_toset <= 3) { | ||
277 | factor_toset = (1 << (factor_toset + 2)); | ||
278 | if (factor_toset > 0xf) | ||
279 | factor_toset = 0xf; | ||
280 | |||
281 | for (index = 0; index < 4; index++) { | ||
282 | if ((p_regtoset[index] & 0xf0) > | ||
283 | (factor_toset << 4)) | ||
284 | p_regtoset[index] = | ||
285 | (p_regtoset[index] & 0x0f) | | ||
286 | (factor_toset << 4); | ||
287 | |||
288 | if ((p_regtoset[index] & 0x0f) > | ||
289 | factor_toset) | ||
290 | p_regtoset[index] = | ||
291 | (p_regtoset[index] & 0xf0) | | ||
292 | (factor_toset); | ||
293 | |||
294 | rtl_write_byte(rtlpriv, | ||
295 | (REG_AGGLEN_LMT + index), | ||
296 | p_regtoset[index]); | ||
297 | |||
298 | } | ||
299 | |||
300 | RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, | ||
301 | "Set HW_VAR_AMPDU_FACTOR: %#x\n", | ||
302 | factor_toset); | ||
303 | } | ||
304 | break; } | ||
305 | case HW_VAR_AC_PARAM:{ | ||
306 | u8 e_aci = *((u8 *) val); | ||
307 | rtl8723ae_dm_init_edca_turbo(hw); | ||
308 | |||
309 | if (rtlpci->acm_method != eAcmWay2_SW) | ||
310 | rtlpriv->cfg->ops->set_hw_reg(hw, | ||
311 | HW_VAR_ACM_CTRL, | ||
312 | (u8 *) (&e_aci)); | ||
313 | break; } | ||
314 | case HW_VAR_ACM_CTRL:{ | ||
315 | u8 e_aci = *((u8 *) val); | ||
316 | union aci_aifsn *p_aci_aifsn = | ||
317 | (union aci_aifsn *)(&(mac->ac[0].aifs)); | ||
318 | u8 acm = p_aci_aifsn->f.acm; | ||
319 | u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL); | ||
320 | |||
321 | acm_ctrl |= ((rtlpci->acm_method == 2) ? 0x0 : 0x1); | ||
322 | |||
323 | if (acm) { | ||
324 | switch (e_aci) { | ||
325 | case AC0_BE: | ||
326 | acm_ctrl |= AcmHw_BeqEn; | ||
327 | break; | ||
328 | case AC2_VI: | ||
329 | acm_ctrl |= AcmHw_ViqEn; | ||
330 | break; | ||
331 | case AC3_VO: | ||
332 | acm_ctrl |= AcmHw_VoqEn; | ||
333 | break; | ||
334 | default: | ||
335 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | ||
336 | "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", | ||
337 | acm); | ||
338 | break; | ||
339 | } | ||
340 | } else { | ||
341 | switch (e_aci) { | ||
342 | case AC0_BE: | ||
343 | acm_ctrl &= (~AcmHw_BeqEn); | ||
344 | break; | ||
345 | case AC2_VI: | ||
346 | acm_ctrl &= (~AcmHw_ViqEn); | ||
347 | break; | ||
348 | case AC3_VO: | ||
349 | acm_ctrl &= (~AcmHw_BeqEn); | ||
350 | break; | ||
351 | default: | ||
352 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
353 | "switch case not processed\n"); | ||
354 | break; | ||
355 | } | ||
356 | } | ||
357 | |||
358 | RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE, | ||
359 | "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", | ||
360 | acm_ctrl); | ||
361 | rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl); | ||
362 | break; } | ||
363 | case HW_VAR_RCR: | ||
364 | rtl_write_dword(rtlpriv, REG_RCR, ((u32 *) (val))[0]); | ||
365 | rtlpci->receive_config = ((u32 *) (val))[0]; | ||
366 | break; | ||
367 | case HW_VAR_RETRY_LIMIT:{ | ||
368 | u8 retry_limit = ((u8 *) (val))[0]; | ||
369 | |||
370 | rtl_write_word(rtlpriv, REG_RL, | ||
371 | retry_limit << RETRY_LIMIT_SHORT_SHIFT | | ||
372 | retry_limit << RETRY_LIMIT_LONG_SHIFT); | ||
373 | break; } | ||
374 | case HW_VAR_DUAL_TSF_RST: | ||
375 | rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1))); | ||
376 | break; | ||
377 | case HW_VAR_EFUSE_BYTES: | ||
378 | rtlefuse->efuse_usedbytes = *((u16 *) val); | ||
379 | break; | ||
380 | case HW_VAR_EFUSE_USAGE: | ||
381 | rtlefuse->efuse_usedpercentage = *((u8 *) val); | ||
382 | break; | ||
383 | case HW_VAR_IO_CMD: | ||
384 | rtl8723ae_phy_set_io_cmd(hw, (*(enum io_type *)val)); | ||
385 | break; | ||
386 | case HW_VAR_WPA_CONFIG: | ||
387 | rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *) val)); | ||
388 | break; | ||
389 | case HW_VAR_SET_RPWM:{ | ||
390 | u8 rpwm_val; | ||
391 | |||
392 | rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM); | ||
393 | udelay(1); | ||
394 | |||
395 | if (rpwm_val & BIT(7)) { | ||
396 | rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, | ||
397 | (*(u8 *) val)); | ||
398 | } else { | ||
399 | rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, | ||
400 | ((*(u8 *) val) | BIT(7))); | ||
401 | } | ||
402 | |||
403 | break; } | ||
404 | case HW_VAR_H2C_FW_PWRMODE:{ | ||
405 | u8 psmode = (*(u8 *) val); | ||
406 | |||
407 | if (psmode != FW_PS_ACTIVE_MODE) | ||
408 | rtl8723ae_dm_rf_saving(hw, true); | ||
409 | |||
410 | rtl8723ae_set_fw_pwrmode_cmd(hw, (*(u8 *) val)); | ||
411 | break; } | ||
412 | case HW_VAR_FW_PSMODE_STATUS: | ||
413 | ppsc->fw_current_inpsmode = *((bool *) val); | ||
414 | break; | ||
415 | case HW_VAR_H2C_FW_JOINBSSRPT:{ | ||
416 | u8 mstatus = (*(u8 *) val); | ||
417 | u8 tmp_regcr, tmp_reg422; | ||
418 | bool recover = false; | ||
419 | |||
420 | if (mstatus == RT_MEDIA_CONNECT) { | ||
421 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, NULL); | ||
422 | |||
423 | tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1); | ||
424 | rtl_write_byte(rtlpriv, REG_CR + 1, | ||
425 | (tmp_regcr | BIT(0))); | ||
426 | |||
427 | _rtl8723ae_set_bcn_ctrl_reg(hw, 0, BIT(3)); | ||
428 | _rtl8723ae_set_bcn_ctrl_reg(hw, BIT(4), 0); | ||
429 | |||
430 | tmp_reg422 = rtl_read_byte(rtlpriv, | ||
431 | REG_FWHW_TXQ_CTRL + 2); | ||
432 | if (tmp_reg422 & BIT(6)) | ||
433 | recover = true; | ||
434 | rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, | ||
435 | tmp_reg422 & (~BIT(6))); | ||
436 | |||
437 | rtl8723ae_set_fw_rsvdpagepkt(hw, 0); | ||
438 | |||
439 | _rtl8723ae_set_bcn_ctrl_reg(hw, BIT(3), 0); | ||
440 | _rtl8723ae_set_bcn_ctrl_reg(hw, 0, BIT(4)); | ||
441 | |||
442 | if (recover) | ||
443 | rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, | ||
444 | tmp_reg422); | ||
445 | |||
446 | rtl_write_byte(rtlpriv, REG_CR + 1, | ||
447 | (tmp_regcr & ~(BIT(0)))); | ||
448 | } | ||
449 | rtl8723ae_set_fw_joinbss_report_cmd(hw, (*(u8 *) val)); | ||
450 | |||
451 | break; } | ||
452 | case HW_VAR_AID:{ | ||
453 | u16 u2btmp; | ||
454 | u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT); | ||
455 | u2btmp &= 0xC000; | ||
456 | rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, (u2btmp | | ||
457 | mac->assoc_id)); | ||
458 | break; } | ||
459 | case HW_VAR_CORRECT_TSF:{ | ||
460 | u8 btype_ibss = ((u8 *) (val))[0]; | ||
461 | |||
462 | if (btype_ibss == true) | ||
463 | _rtl8723ae_stop_tx_beacon(hw); | ||
464 | |||
465 | _rtl8723ae_set_bcn_ctrl_reg(hw, 0, BIT(3)); | ||
466 | |||
467 | rtl_write_dword(rtlpriv, REG_TSFTR, | ||
468 | (u32) (mac->tsf & 0xffffffff)); | ||
469 | rtl_write_dword(rtlpriv, REG_TSFTR + 4, | ||
470 | (u32) ((mac->tsf >> 32) & 0xffffffff)); | ||
471 | |||
472 | _rtl8723ae_set_bcn_ctrl_reg(hw, BIT(3), 0); | ||
473 | |||
474 | if (btype_ibss == true) | ||
475 | _rtl8723ae_resume_tx_beacon(hw); | ||
476 | break; } | ||
477 | default: | ||
478 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
479 | "switch case not processed\n"); | ||
480 | break; | ||
481 | } | ||
482 | } | ||
483 | |||
484 | static bool _rtl8723ae_llt_write(struct ieee80211_hw *hw, u32 address, u32 data) | ||
485 | { | ||
486 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
487 | bool status = true; | ||
488 | long count = 0; | ||
489 | u32 value = _LLT_INIT_ADDR(address) | | ||
490 | _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS); | ||
491 | |||
492 | rtl_write_dword(rtlpriv, REG_LLT_INIT, value); | ||
493 | |||
494 | do { | ||
495 | value = rtl_read_dword(rtlpriv, REG_LLT_INIT); | ||
496 | if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) | ||
497 | break; | ||
498 | |||
499 | if (count > POLLING_LLT_THRESHOLD) { | ||
500 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
501 | "Failed to polling write LLT done at address %d!\n", | ||
502 | address); | ||
503 | status = false; | ||
504 | break; | ||
505 | } | ||
506 | } while (++count); | ||
507 | |||
508 | return status; | ||
509 | } | ||
510 | |||
511 | static bool _rtl8723ae_llt_table_init(struct ieee80211_hw *hw) | ||
512 | { | ||
513 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
514 | unsigned short i; | ||
515 | u8 txpktbuf_bndy; | ||
516 | u8 maxPage; | ||
517 | bool status; | ||
518 | u8 ubyte; | ||
519 | |||
520 | maxPage = 255; | ||
521 | txpktbuf_bndy = 246; | ||
522 | |||
523 | rtl_write_byte(rtlpriv, REG_CR, 0x8B); | ||
524 | |||
525 | rtl_write_word(rtlpriv, REG_RQPN_NPQ, 0x0000); | ||
526 | |||
527 | rtl_write_dword(rtlpriv, REG_RQPN, 0x80ac1c29); | ||
528 | rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x03); | ||
529 | |||
530 | rtl_write_dword(rtlpriv, REG_TRXFF_BNDY, (0x27FF0000 | txpktbuf_bndy)); | ||
531 | rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy); | ||
532 | |||
533 | rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy); | ||
534 | rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy); | ||
535 | |||
536 | rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy); | ||
537 | rtl_write_byte(rtlpriv, REG_PBP, 0x11); | ||
538 | rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4); | ||
539 | |||
540 | for (i = 0; i < (txpktbuf_bndy - 1); i++) { | ||
541 | status = _rtl8723ae_llt_write(hw, i, i + 1); | ||
542 | if (true != status) | ||
543 | return status; | ||
544 | } | ||
545 | |||
546 | status = _rtl8723ae_llt_write(hw, (txpktbuf_bndy - 1), 0xFF); | ||
547 | if (true != status) | ||
548 | return status; | ||
549 | |||
550 | for (i = txpktbuf_bndy; i < maxPage; i++) { | ||
551 | status = _rtl8723ae_llt_write(hw, i, (i + 1)); | ||
552 | if (true != status) | ||
553 | return status; | ||
554 | } | ||
555 | |||
556 | status = _rtl8723ae_llt_write(hw, maxPage, txpktbuf_bndy); | ||
557 | if (true != status) | ||
558 | return status; | ||
559 | |||
560 | rtl_write_byte(rtlpriv, REG_CR, 0xff); | ||
561 | ubyte = rtl_read_byte(rtlpriv, REG_RQPN + 3); | ||
562 | rtl_write_byte(rtlpriv, REG_RQPN + 3, ubyte | BIT(7)); | ||
563 | |||
564 | return true; | ||
565 | } | ||
566 | |||
567 | static void _rtl8723ae_gen_refresh_led_state(struct ieee80211_hw *hw) | ||
568 | { | ||
569 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
570 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); | ||
571 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
572 | struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0); | ||
573 | |||
574 | if (rtlpriv->rtlhal.up_first_time) | ||
575 | return; | ||
576 | |||
577 | if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) | ||
578 | rtl8723ae_sw_led_on(hw, pLed0); | ||
579 | else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT) | ||
580 | rtl8723ae_sw_led_on(hw, pLed0); | ||
581 | else | ||
582 | rtl8723ae_sw_led_off(hw, pLed0); | ||
583 | } | ||
584 | |||
585 | static bool _rtl8712e_init_mac(struct ieee80211_hw *hw) | ||
586 | { | ||
587 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
588 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
589 | unsigned char bytetmp; | ||
590 | unsigned short wordtmp; | ||
591 | u16 retry = 0; | ||
592 | u16 tmpu2b; | ||
593 | bool mac_func_enable; | ||
594 | |||
595 | rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00); | ||
596 | bytetmp = rtl_read_byte(rtlpriv, REG_CR); | ||
597 | if (bytetmp == 0xFF) | ||
598 | mac_func_enable = true; | ||
599 | else | ||
600 | mac_func_enable = false; | ||
601 | |||
602 | |||
603 | /* HW Power on sequence */ | ||
604 | if (!rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, | ||
605 | PWR_INTF_PCI_MSK, Rtl8723_NIC_ENABLE_FLOW)) | ||
606 | return false; | ||
607 | |||
608 | bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG+2); | ||
609 | rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG+2, bytetmp | BIT(4)); | ||
610 | |||
611 | /* eMAC time out function enable, 0x369[7]=1 */ | ||
612 | bytetmp = rtl_read_byte(rtlpriv, 0x369); | ||
613 | rtl_write_byte(rtlpriv, 0x369, bytetmp | BIT(7)); | ||
614 | |||
615 | /* ePHY reg 0x1e bit[4]=1 using MDIO interface, | ||
616 | * we should do this before Enabling ASPM backdoor. | ||
617 | */ | ||
618 | do { | ||
619 | rtl_write_word(rtlpriv, 0x358, 0x5e); | ||
620 | udelay(100); | ||
621 | rtl_write_word(rtlpriv, 0x356, 0xc280); | ||
622 | rtl_write_word(rtlpriv, 0x354, 0xc290); | ||
623 | rtl_write_word(rtlpriv, 0x358, 0x3e); | ||
624 | udelay(100); | ||
625 | rtl_write_word(rtlpriv, 0x358, 0x5e); | ||
626 | udelay(100); | ||
627 | tmpu2b = rtl_read_word(rtlpriv, 0x356); | ||
628 | retry++; | ||
629 | } while (tmpu2b != 0xc290 && retry < 100); | ||
630 | |||
631 | if (retry >= 100) { | ||
632 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, | ||
633 | "InitMAC(): ePHY configure fail!!!\n"); | ||
634 | return false; | ||
635 | } | ||
636 | |||
637 | rtl_write_word(rtlpriv, REG_CR, 0x2ff); | ||
638 | rtl_write_word(rtlpriv, REG_CR + 1, 0x06); | ||
639 | |||
640 | if (!mac_func_enable) { | ||
641 | if (_rtl8723ae_llt_table_init(hw) == false) | ||
642 | return false; | ||
643 | } | ||
644 | |||
645 | rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff); | ||
646 | rtl_write_byte(rtlpriv, REG_HISRE, 0xff); | ||
647 | |||
648 | rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, 0x27ff); | ||
649 | |||
650 | wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL) & 0xf; | ||
651 | wordtmp |= 0xF771; | ||
652 | rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp); | ||
653 | |||
654 | rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F); | ||
655 | rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); | ||
656 | rtl_write_word(rtlpriv, REG_RXFLTMAP2, 0xFFFF); | ||
657 | rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config); | ||
658 | |||
659 | rtl_write_byte(rtlpriv, 0x4d0, 0x0); | ||
660 | |||
661 | rtl_write_dword(rtlpriv, REG_BCNQ_DESA, | ||
662 | ((u64) rtlpci->tx_ring[BEACON_QUEUE].dma) & | ||
663 | DMA_BIT_MASK(32)); | ||
664 | rtl_write_dword(rtlpriv, REG_MGQ_DESA, | ||
665 | (u64) rtlpci->tx_ring[MGNT_QUEUE].dma & | ||
666 | DMA_BIT_MASK(32)); | ||
667 | rtl_write_dword(rtlpriv, REG_VOQ_DESA, | ||
668 | (u64) rtlpci->tx_ring[VO_QUEUE].dma & DMA_BIT_MASK(32)); | ||
669 | rtl_write_dword(rtlpriv, REG_VIQ_DESA, | ||
670 | (u64) rtlpci->tx_ring[VI_QUEUE].dma & DMA_BIT_MASK(32)); | ||
671 | rtl_write_dword(rtlpriv, REG_BEQ_DESA, | ||
672 | (u64) rtlpci->tx_ring[BE_QUEUE].dma & DMA_BIT_MASK(32)); | ||
673 | rtl_write_dword(rtlpriv, REG_BKQ_DESA, | ||
674 | (u64) rtlpci->tx_ring[BK_QUEUE].dma & DMA_BIT_MASK(32)); | ||
675 | rtl_write_dword(rtlpriv, REG_HQ_DESA, | ||
676 | (u64) rtlpci->tx_ring[HIGH_QUEUE].dma & | ||
677 | DMA_BIT_MASK(32)); | ||
678 | rtl_write_dword(rtlpriv, REG_RX_DESA, | ||
679 | (u64) rtlpci->rx_ring[RX_MPDU_QUEUE].dma & | ||
680 | DMA_BIT_MASK(32)); | ||
681 | |||
682 | rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, 0x74); | ||
683 | |||
684 | rtl_write_dword(rtlpriv, REG_INT_MIG, 0); | ||
685 | |||
686 | bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL); | ||
687 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, bytetmp & ~BIT(6)); | ||
688 | do { | ||
689 | retry++; | ||
690 | bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL); | ||
691 | } while ((retry < 200) && (bytetmp & BIT(7))); | ||
692 | |||
693 | _rtl8723ae_gen_refresh_led_state(hw); | ||
694 | |||
695 | rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0); | ||
696 | |||
697 | return true; | ||
698 | } | ||
699 | |||
700 | static void _rtl8723ae_hw_configure(struct ieee80211_hw *hw) | ||
701 | { | ||
702 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
703 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
704 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); | ||
705 | u8 reg_bw_opmode; | ||
706 | u32 reg_ratr, reg_prsr; | ||
707 | |||
708 | reg_bw_opmode = BW_OPMODE_20MHZ; | ||
709 | reg_ratr = RATE_ALL_CCK | RATE_ALL_OFDM_AG | | ||
710 | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; | ||
711 | reg_prsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG; | ||
712 | |||
713 | rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, 0x8); | ||
714 | |||
715 | rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); | ||
716 | |||
717 | rtl_write_dword(rtlpriv, REG_RRSR, reg_prsr); | ||
718 | |||
719 | rtl_write_byte(rtlpriv, REG_SLOT, 0x09); | ||
720 | |||
721 | rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, 0x0); | ||
722 | |||
723 | rtl_write_word(rtlpriv, REG_FWHW_TXQ_CTRL, 0x1F80); | ||
724 | |||
725 | rtl_write_word(rtlpriv, REG_RL, 0x0707); | ||
726 | |||
727 | rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0x02012802); | ||
728 | |||
729 | rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF); | ||
730 | |||
731 | rtl_write_dword(rtlpriv, REG_DARFRC, 0x01000000); | ||
732 | rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x07060504); | ||
733 | rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000); | ||
734 | rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504); | ||
735 | |||
736 | if ((pcipriv->bt_coexist.bt_coexistence) && | ||
737 | (pcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4)) | ||
738 | rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0x97427431); | ||
739 | else | ||
740 | rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0xb972a841); | ||
741 | |||
742 | rtl_write_byte(rtlpriv, REG_ATIMWND, 0x2); | ||
743 | |||
744 | rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xff); | ||
745 | |||
746 | rtlpci->reg_bcn_ctrl_val = 0x1f; | ||
747 | rtl_write_byte(rtlpriv, REG_BCN_CTRL, rtlpci->reg_bcn_ctrl_val); | ||
748 | |||
749 | rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); | ||
750 | |||
751 | rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); | ||
752 | |||
753 | rtl_write_byte(rtlpriv, REG_PIFS, 0x1C); | ||
754 | rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16); | ||
755 | |||
756 | if ((pcipriv->bt_coexist.bt_coexistence) && | ||
757 | (pcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4)) { | ||
758 | rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); | ||
759 | rtl_write_word(rtlpriv, REG_PROT_MODE_CTRL, 0x0402); | ||
760 | } else { | ||
761 | rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); | ||
762 | rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); | ||
763 | } | ||
764 | |||
765 | if ((pcipriv->bt_coexist.bt_coexistence) && | ||
766 | (pcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4)) | ||
767 | rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x03086666); | ||
768 | else | ||
769 | rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x086666); | ||
770 | |||
771 | rtl_write_byte(rtlpriv, REG_ACKTO, 0x40); | ||
772 | |||
773 | rtl_write_word(rtlpriv, REG_SPEC_SIFS, 0x1010); | ||
774 | rtl_write_word(rtlpriv, REG_MAC_SPEC_SIFS, 0x1010); | ||
775 | |||
776 | rtl_write_word(rtlpriv, REG_SIFS_CTX, 0x1010); | ||
777 | |||
778 | rtl_write_word(rtlpriv, REG_SIFS_TRX, 0x1010); | ||
779 | |||
780 | rtl_write_dword(rtlpriv, REG_MAR, 0xffffffff); | ||
781 | rtl_write_dword(rtlpriv, REG_MAR + 4, 0xffffffff); | ||
782 | |||
783 | rtl_write_dword(rtlpriv, 0x394, 0x1); | ||
784 | } | ||
785 | |||
786 | static void _rtl8723ae_enable_aspm_back_door(struct ieee80211_hw *hw) | ||
787 | { | ||
788 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
789 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
790 | |||
791 | rtl_write_byte(rtlpriv, 0x34b, 0x93); | ||
792 | rtl_write_word(rtlpriv, 0x350, 0x870c); | ||
793 | rtl_write_byte(rtlpriv, 0x352, 0x1); | ||
794 | |||
795 | if (ppsc->support_backdoor) | ||
796 | rtl_write_byte(rtlpriv, 0x349, 0x1b); | ||
797 | else | ||
798 | rtl_write_byte(rtlpriv, 0x349, 0x03); | ||
799 | |||
800 | rtl_write_word(rtlpriv, 0x350, 0x2718); | ||
801 | rtl_write_byte(rtlpriv, 0x352, 0x1); | ||
802 | } | ||
803 | |||
804 | void rtl8723ae_enable_hw_security_config(struct ieee80211_hw *hw) | ||
805 | { | ||
806 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
807 | u8 sec_reg_value; | ||
808 | |||
809 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
810 | "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", | ||
811 | rtlpriv->sec.pairwise_enc_algorithm, | ||
812 | rtlpriv->sec.group_enc_algorithm); | ||
813 | |||
814 | if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { | ||
815 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | ||
816 | "not open hw encryption\n"); | ||
817 | return; | ||
818 | } | ||
819 | |||
820 | sec_reg_value = SCR_TxEncEnable | SCR_RxDecEnable; | ||
821 | |||
822 | if (rtlpriv->sec.use_defaultkey) { | ||
823 | sec_reg_value |= SCR_TxUseDK; | ||
824 | sec_reg_value |= SCR_RxUseDK; | ||
825 | } | ||
826 | |||
827 | sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK); | ||
828 | |||
829 | rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); | ||
830 | |||
831 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | ||
832 | "The SECR-value %x\n", sec_reg_value); | ||
833 | |||
834 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); | ||
835 | |||
836 | } | ||
837 | |||
838 | int rtl8723ae_hw_init(struct ieee80211_hw *hw) | ||
839 | { | ||
840 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
841 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
842 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
843 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
844 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
845 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
846 | bool rtstatus = true; | ||
847 | int err; | ||
848 | u8 tmp_u1b; | ||
849 | |||
850 | rtlpriv->rtlhal.being_init_adapter = true; | ||
851 | rtlpriv->intf_ops->disable_aspm(hw); | ||
852 | rtstatus = _rtl8712e_init_mac(hw); | ||
853 | if (rtstatus != true) { | ||
854 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n"); | ||
855 | err = 1; | ||
856 | return err; | ||
857 | } | ||
858 | |||
859 | err = rtl8723ae_download_fw(hw); | ||
860 | if (err) { | ||
861 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | ||
862 | "Failed to download FW. Init HW without FW now..\n"); | ||
863 | err = 1; | ||
864 | rtlhal->fw_ready = false; | ||
865 | return err; | ||
866 | } else { | ||
867 | rtlhal->fw_ready = true; | ||
868 | } | ||
869 | |||
870 | rtlhal->last_hmeboxnum = 0; | ||
871 | rtl8723ae_phy_mac_config(hw); | ||
872 | /* because the last function modifies RCR, we update | ||
873 | * rcr var here, or TP will be unstable as ther receive_config | ||
874 | * is wrong, RX RCR_ACRC32 will cause TP unstable & Rx | ||
875 | * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252 | ||
876 | */ | ||
877 | rtlpci->receive_config = rtl_read_dword(rtlpriv, REG_RCR); | ||
878 | rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV); | ||
879 | rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); | ||
880 | |||
881 | rtl8723ae_phy_bb_config(hw); | ||
882 | rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; | ||
883 | rtl8723ae_phy_rf_config(hw); | ||
884 | if (IS_VENDOR_UMC_A_CUT(rtlhal->version)) { | ||
885 | rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, 0x30255); | ||
886 | rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G2, MASKDWORD, 0x50a00); | ||
887 | } else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) { | ||
888 | rtl_set_rfreg(hw, RF90_PATH_A, 0x0C, MASKDWORD, 0x894AE); | ||
889 | rtl_set_rfreg(hw, RF90_PATH_A, 0x0A, MASKDWORD, 0x1AF31); | ||
890 | rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, MASKDWORD, 0x8F425); | ||
891 | rtl_set_rfreg(hw, RF90_PATH_A, RF_SYN_G2, MASKDWORD, 0x4F200); | ||
892 | rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK1, MASKDWORD, 0x44053); | ||
893 | rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK2, MASKDWORD, 0x80201); | ||
894 | } | ||
895 | rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0, | ||
896 | RF_CHNLBW, RFREG_OFFSET_MASK); | ||
897 | rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1, | ||
898 | RF_CHNLBW, RFREG_OFFSET_MASK); | ||
899 | rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1); | ||
900 | rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1); | ||
901 | rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); | ||
902 | _rtl8723ae_hw_configure(hw); | ||
903 | rtl_cam_reset_all_entry(hw); | ||
904 | rtl8723ae_enable_hw_security_config(hw); | ||
905 | |||
906 | ppsc->rfpwr_state = ERFON; | ||
907 | |||
908 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); | ||
909 | _rtl8723ae_enable_aspm_back_door(hw); | ||
910 | rtlpriv->intf_ops->enable_aspm(hw); | ||
911 | |||
912 | rtl8723ae_bt_hw_init(hw); | ||
913 | |||
914 | if (ppsc->rfpwr_state == ERFON) { | ||
915 | rtl8723ae_phy_set_rfpath_switch(hw, 1); | ||
916 | if (rtlphy->iqk_initialized) { | ||
917 | rtl8723ae_phy_iq_calibrate(hw, true); | ||
918 | } else { | ||
919 | rtl8723ae_phy_iq_calibrate(hw, false); | ||
920 | rtlphy->iqk_initialized = true; | ||
921 | } | ||
922 | |||
923 | rtl8723ae_phy_lc_calibrate(hw); | ||
924 | } | ||
925 | |||
926 | tmp_u1b = efuse_read_1byte(hw, 0x1FA); | ||
927 | if (!(tmp_u1b & BIT(0))) { | ||
928 | rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0F, 0x05); | ||
929 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "PA BIAS path A\n"); | ||
930 | } | ||
931 | |||
932 | if (!(tmp_u1b & BIT(4))) { | ||
933 | tmp_u1b = rtl_read_byte(rtlpriv, 0x16) & 0x0F; | ||
934 | rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x80); | ||
935 | udelay(10); | ||
936 | rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x90); | ||
937 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n"); | ||
938 | } | ||
939 | rtl8723ae_dm_init(hw); | ||
940 | rtlpriv->rtlhal.being_init_adapter = false; | ||
941 | return err; | ||
942 | } | ||
943 | |||
944 | static enum version_8723e _rtl8723ae_read_chip_version(struct ieee80211_hw *hw) | ||
945 | { | ||
946 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
947 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
948 | enum version_8723e version = 0x0000; | ||
949 | u32 value32; | ||
950 | |||
951 | value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG); | ||
952 | if (value32 & TRP_VAUX_EN) { | ||
953 | version = (enum version_8723e)(version | | ||
954 | ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : 0)); | ||
955 | /* RTL8723 with BT function. */ | ||
956 | version = (enum version_8723e)(version | | ||
957 | ((value32 & BT_FUNC) ? CHIP_8723 : 0)); | ||
958 | |||
959 | } else { | ||
960 | /* Normal mass production chip. */ | ||
961 | version = (enum version_8723e) NORMAL_CHIP; | ||
962 | version = (enum version_8723e)(version | | ||
963 | ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : 0)); | ||
964 | /* RTL8723 with BT function. */ | ||
965 | version = (enum version_8723e)(version | | ||
966 | ((value32 & BT_FUNC) ? CHIP_8723 : 0)); | ||
967 | if (IS_CHIP_VENDOR_UMC(version)) | ||
968 | version = (enum version_8723e)(version | | ||
969 | ((value32 & CHIP_VER_RTL_MASK)));/* IC version (CUT) */ | ||
970 | if (IS_8723_SERIES(version)) { | ||
971 | value32 = rtl_read_dword(rtlpriv, REG_GPIO_OUTSTS); | ||
972 | /* ROM code version */ | ||
973 | version = (enum version_8723e)(version | | ||
974 | ((value32 & RF_RL_ID)>>20)); | ||
975 | } | ||
976 | } | ||
977 | |||
978 | if (IS_8723_SERIES(version)) { | ||
979 | value32 = rtl_read_dword(rtlpriv, REG_MULTI_FUNC_CTRL); | ||
980 | rtlphy->polarity_ctl = ((value32 & WL_HWPDN_SL) ? | ||
981 | RT_POLARITY_HIGH_ACT : | ||
982 | RT_POLARITY_LOW_ACT); | ||
983 | } | ||
984 | switch (version) { | ||
985 | case VERSION_TEST_UMC_CHIP_8723: | ||
986 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
987 | "Chip Version ID: VERSION_TEST_UMC_CHIP_8723.\n"); | ||
988 | break; | ||
989 | case VERSION_NORMAL_UMC_CHIP_8723_1T1R_A_CUT: | ||
990 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
991 | "Chip Version ID: VERSION_NORMAL_UMC_CHIP_8723_1T1R_A_CUT.\n"); | ||
992 | break; | ||
993 | case VERSION_NORMAL_UMC_CHIP_8723_1T1R_B_CUT: | ||
994 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
995 | "Chip Version ID: VERSION_NORMAL_UMC_CHIP_8723_1T1R_B_CUT.\n"); | ||
996 | break; | ||
997 | default: | ||
998 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
999 | "Chip Version ID: Unknown. Bug?\n"); | ||
1000 | break; | ||
1001 | } | ||
1002 | |||
1003 | if (IS_8723_SERIES(version)) | ||
1004 | rtlphy->rf_type = RF_1T1R; | ||
1005 | |||
1006 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Chip RF Type: %s\n", | ||
1007 | (rtlphy->rf_type == RF_2T2R) ? "RF_2T2R" : "RF_1T1R"); | ||
1008 | |||
1009 | return version; | ||
1010 | } | ||
1011 | |||
1012 | static int _rtl8723ae_set_media_status(struct ieee80211_hw *hw, | ||
1013 | enum nl80211_iftype type) | ||
1014 | { | ||
1015 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1016 | u8 bt_msr = rtl_read_byte(rtlpriv, MSR) & 0xfc; | ||
1017 | enum led_ctl_mode ledaction = LED_CTL_NO_LINK; | ||
1018 | |||
1019 | rtl_write_dword(rtlpriv, REG_BCN_CTRL, 0); | ||
1020 | RT_TRACE(rtlpriv, COMP_BEACON, DBG_LOUD, | ||
1021 | "clear 0x550 when set HW_VAR_MEDIA_STATUS\n"); | ||
1022 | |||
1023 | if (type == NL80211_IFTYPE_UNSPECIFIED || | ||
1024 | type == NL80211_IFTYPE_STATION) { | ||
1025 | _rtl8723ae_stop_tx_beacon(hw); | ||
1026 | _rtl8723ae_enable_bcn_sufunc(hw); | ||
1027 | } else if (type == NL80211_IFTYPE_ADHOC || | ||
1028 | type == NL80211_IFTYPE_AP) { | ||
1029 | _rtl8723ae_resume_tx_beacon(hw); | ||
1030 | _rtl8723ae_disable_bcn_sufunc(hw); | ||
1031 | } else { | ||
1032 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | ||
1033 | "Set HW_VAR_MEDIA_STATUS: No such media status(%x).\n", | ||
1034 | type); | ||
1035 | } | ||
1036 | |||
1037 | switch (type) { | ||
1038 | case NL80211_IFTYPE_UNSPECIFIED: | ||
1039 | bt_msr |= MSR_NOLINK; | ||
1040 | ledaction = LED_CTL_LINK; | ||
1041 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
1042 | "Set Network type to NO LINK!\n"); | ||
1043 | break; | ||
1044 | case NL80211_IFTYPE_ADHOC: | ||
1045 | bt_msr |= MSR_ADHOC; | ||
1046 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
1047 | "Set Network type to Ad Hoc!\n"); | ||
1048 | break; | ||
1049 | case NL80211_IFTYPE_STATION: | ||
1050 | bt_msr |= MSR_INFRA; | ||
1051 | ledaction = LED_CTL_LINK; | ||
1052 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
1053 | "Set Network type to STA!\n"); | ||
1054 | break; | ||
1055 | case NL80211_IFTYPE_AP: | ||
1056 | bt_msr |= MSR_AP; | ||
1057 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
1058 | "Set Network type to AP!\n"); | ||
1059 | break; | ||
1060 | default: | ||
1061 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
1062 | "Network type %d not supported!\n", | ||
1063 | type); | ||
1064 | return 1; | ||
1065 | break; | ||
1066 | |||
1067 | } | ||
1068 | |||
1069 | rtl_write_byte(rtlpriv, (MSR), bt_msr); | ||
1070 | rtlpriv->cfg->ops->led_control(hw, ledaction); | ||
1071 | if ((bt_msr & 0x03) == MSR_AP) | ||
1072 | rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); | ||
1073 | else | ||
1074 | rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66); | ||
1075 | return 0; | ||
1076 | } | ||
1077 | |||
1078 | void rtl8723ae_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) | ||
1079 | { | ||
1080 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1081 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
1082 | u32 reg_rcr = rtlpci->receive_config; | ||
1083 | |||
1084 | if (rtlpriv->psc.rfpwr_state != ERFON) | ||
1085 | return; | ||
1086 | |||
1087 | if (check_bssid == true) { | ||
1088 | reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); | ||
1089 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, | ||
1090 | (u8 *)(®_rcr)); | ||
1091 | _rtl8723ae_set_bcn_ctrl_reg(hw, 0, BIT(4)); | ||
1092 | } else if (check_bssid == false) { | ||
1093 | reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); | ||
1094 | _rtl8723ae_set_bcn_ctrl_reg(hw, BIT(4), 0); | ||
1095 | rtlpriv->cfg->ops->set_hw_reg(hw, | ||
1096 | HW_VAR_RCR, (u8 *) (®_rcr)); | ||
1097 | } | ||
1098 | } | ||
1099 | |||
1100 | int rtl8723ae_set_network_type(struct ieee80211_hw *hw, | ||
1101 | enum nl80211_iftype type) | ||
1102 | { | ||
1103 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1104 | |||
1105 | if (_rtl8723ae_set_media_status(hw, type)) | ||
1106 | return -EOPNOTSUPP; | ||
1107 | |||
1108 | if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { | ||
1109 | if (type != NL80211_IFTYPE_AP) | ||
1110 | rtl8723ae_set_check_bssid(hw, true); | ||
1111 | } else { | ||
1112 | rtl8723ae_set_check_bssid(hw, false); | ||
1113 | } | ||
1114 | return 0; | ||
1115 | } | ||
1116 | |||
1117 | /* don't set REG_EDCA_BE_PARAM here because mac80211 will send pkt when scan */ | ||
1118 | void rtl8723ae_set_qos(struct ieee80211_hw *hw, int aci) | ||
1119 | { | ||
1120 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1121 | |||
1122 | rtl8723ae_dm_init_edca_turbo(hw); | ||
1123 | switch (aci) { | ||
1124 | case AC1_BK: | ||
1125 | rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f); | ||
1126 | break; | ||
1127 | case AC0_BE: | ||
1128 | /* rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, u4ac_param); */ | ||
1129 | break; | ||
1130 | case AC2_VI: | ||
1131 | rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322); | ||
1132 | break; | ||
1133 | case AC3_VO: | ||
1134 | rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222); | ||
1135 | break; | ||
1136 | default: | ||
1137 | RT_ASSERT(false, "invalid aci: %d !\n", aci); | ||
1138 | break; | ||
1139 | } | ||
1140 | } | ||
1141 | |||
1142 | void rtl8723ae_enable_interrupt(struct ieee80211_hw *hw) | ||
1143 | { | ||
1144 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1145 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
1146 | |||
1147 | rtl_write_dword(rtlpriv, 0x3a8, rtlpci->irq_mask[0] & 0xFFFFFFFF); | ||
1148 | rtl_write_dword(rtlpriv, 0x3ac, rtlpci->irq_mask[1] & 0xFFFFFFFF); | ||
1149 | rtlpci->irq_enabled = true; | ||
1150 | } | ||
1151 | |||
1152 | void rtl8723ae_disable_interrupt(struct ieee80211_hw *hw) | ||
1153 | { | ||
1154 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1155 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
1156 | |||
1157 | rtl_write_dword(rtlpriv, 0x3a8, IMR8190_DISABLED); | ||
1158 | rtl_write_dword(rtlpriv, 0x3ac, IMR8190_DISABLED); | ||
1159 | rtlpci->irq_enabled = false; | ||
1160 | synchronize_irq(rtlpci->pdev->irq); | ||
1161 | } | ||
1162 | |||
1163 | static void _rtl8723ae_poweroff_adapter(struct ieee80211_hw *hw) | ||
1164 | { | ||
1165 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1166 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1167 | u8 u1tmp; | ||
1168 | |||
1169 | /* Combo (PCIe + USB) Card and PCIe-MF Card */ | ||
1170 | /* 1. Run LPS WL RFOFF flow */ | ||
1171 | rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, | ||
1172 | PWR_INTF_PCI_MSK, Rtl8723_NIC_LPS_ENTER_FLOW); | ||
1173 | |||
1174 | /* 2. 0x1F[7:0] = 0 */ | ||
1175 | /* turn off RF */ | ||
1176 | rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00); | ||
1177 | if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && rtlhal->fw_ready) | ||
1178 | rtl8723ae_firmware_selfreset(hw); | ||
1179 | |||
1180 | /* Reset MCU. Suggested by Filen. */ | ||
1181 | u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN+1); | ||
1182 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN+1, (u1tmp & (~BIT(2)))); | ||
1183 | |||
1184 | /* g. MCUFWDL 0x80[1:0]=0 */ | ||
1185 | /* reset MCU ready status */ | ||
1186 | rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); | ||
1187 | |||
1188 | /* HW card disable configuration. */ | ||
1189 | rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, | ||
1190 | PWR_INTF_PCI_MSK, Rtl8723_NIC_DISABLE_FLOW); | ||
1191 | |||
1192 | /* Reset MCU IO Wrapper */ | ||
1193 | u1tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1); | ||
1194 | rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1tmp & (~BIT(0)))); | ||
1195 | u1tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1); | ||
1196 | rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, u1tmp | BIT(0)); | ||
1197 | |||
1198 | /* 7. RSV_CTRL 0x1C[7:0] = 0x0E */ | ||
1199 | /* lock ISO/CLK/Power control register */ | ||
1200 | rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e); | ||
1201 | } | ||
1202 | |||
1203 | void rtl8723ae_card_disable(struct ieee80211_hw *hw) | ||
1204 | { | ||
1205 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1206 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
1207 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
1208 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
1209 | enum nl80211_iftype opmode; | ||
1210 | |||
1211 | mac->link_state = MAC80211_NOLINK; | ||
1212 | opmode = NL80211_IFTYPE_UNSPECIFIED; | ||
1213 | _rtl8723ae_set_media_status(hw, opmode); | ||
1214 | if (rtlpci->driver_is_goingto_unload || | ||
1215 | ppsc->rfoff_reason > RF_CHANGE_BY_PS) | ||
1216 | rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); | ||
1217 | RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); | ||
1218 | _rtl8723ae_poweroff_adapter(hw); | ||
1219 | |||
1220 | /* after power off we should do iqk again */ | ||
1221 | rtlpriv->phy.iqk_initialized = false; | ||
1222 | } | ||
1223 | |||
1224 | void rtl8723ae_interrupt_recognized(struct ieee80211_hw *hw, | ||
1225 | u32 *p_inta, u32 *p_intb) | ||
1226 | { | ||
1227 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1228 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
1229 | |||
1230 | *p_inta = rtl_read_dword(rtlpriv, 0x3a0) & rtlpci->irq_mask[0]; | ||
1231 | rtl_write_dword(rtlpriv, 0x3a0, *p_inta); | ||
1232 | } | ||
1233 | |||
1234 | void rtl8723ae_set_beacon_related_registers(struct ieee80211_hw *hw) | ||
1235 | { | ||
1236 | |||
1237 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1238 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
1239 | u16 bcn_interval, atim_window; | ||
1240 | |||
1241 | bcn_interval = mac->beacon_interval; | ||
1242 | atim_window = 2; /*FIX MERGE */ | ||
1243 | rtl8723ae_disable_interrupt(hw); | ||
1244 | rtl_write_word(rtlpriv, REG_ATIMWND, atim_window); | ||
1245 | rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); | ||
1246 | rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f); | ||
1247 | rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18); | ||
1248 | rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18); | ||
1249 | rtl_write_byte(rtlpriv, 0x606, 0x30); | ||
1250 | rtl8723ae_enable_interrupt(hw); | ||
1251 | } | ||
1252 | |||
1253 | void rtl8723ae_set_beacon_interval(struct ieee80211_hw *hw) | ||
1254 | { | ||
1255 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1256 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
1257 | u16 bcn_interval = mac->beacon_interval; | ||
1258 | |||
1259 | RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, | ||
1260 | "beacon_interval:%d\n", bcn_interval); | ||
1261 | rtl8723ae_disable_interrupt(hw); | ||
1262 | rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); | ||
1263 | rtl8723ae_enable_interrupt(hw); | ||
1264 | } | ||
1265 | |||
1266 | void rtl8723ae_update_interrupt_mask(struct ieee80211_hw *hw, | ||
1267 | u32 add_msr, u32 rm_msr) | ||
1268 | { | ||
1269 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1270 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
1271 | |||
1272 | RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, | ||
1273 | "add_msr:%x, rm_msr:%x\n", add_msr, rm_msr); | ||
1274 | |||
1275 | if (add_msr) | ||
1276 | rtlpci->irq_mask[0] |= add_msr; | ||
1277 | if (rm_msr) | ||
1278 | rtlpci->irq_mask[0] &= (~rm_msr); | ||
1279 | rtl8723ae_disable_interrupt(hw); | ||
1280 | rtl8723ae_enable_interrupt(hw); | ||
1281 | } | ||
1282 | |||
1283 | static u8 _rtl8723ae_get_chnl_group(u8 chnl) | ||
1284 | { | ||
1285 | u8 group; | ||
1286 | |||
1287 | if (chnl < 3) | ||
1288 | group = 0; | ||
1289 | else if (chnl < 9) | ||
1290 | group = 1; | ||
1291 | else | ||
1292 | group = 2; | ||
1293 | return group; | ||
1294 | } | ||
1295 | |||
1296 | static void _rtl8723ae_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, | ||
1297 | bool autoload_fail, | ||
1298 | u8 *hwinfo) | ||
1299 | { | ||
1300 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1301 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
1302 | u8 rf_path, index, tempval; | ||
1303 | u16 i; | ||
1304 | |||
1305 | for (rf_path = 0; rf_path < 1; rf_path++) { | ||
1306 | for (i = 0; i < 3; i++) { | ||
1307 | if (!autoload_fail) { | ||
1308 | rtlefuse->eeprom_chnlarea_txpwr_cck | ||
1309 | [rf_path][i] = | ||
1310 | hwinfo[EEPROM_TXPOWERCCK + rf_path * 3 + i]; | ||
1311 | rtlefuse->eeprom_chnlarea_txpwr_ht40_1s | ||
1312 | [rf_path][i] = | ||
1313 | hwinfo[EEPROM_TXPOWERHT40_1S + rf_path * | ||
1314 | 3 + i]; | ||
1315 | } else { | ||
1316 | rtlefuse->eeprom_chnlarea_txpwr_cck | ||
1317 | [rf_path][i] = | ||
1318 | EEPROM_DEFAULT_TXPOWERLEVEL; | ||
1319 | rtlefuse->eeprom_chnlarea_txpwr_ht40_1s | ||
1320 | [rf_path][i] = | ||
1321 | EEPROM_DEFAULT_TXPOWERLEVEL; | ||
1322 | } | ||
1323 | } | ||
1324 | } | ||
1325 | |||
1326 | for (i = 0; i < 3; i++) { | ||
1327 | if (!autoload_fail) | ||
1328 | tempval = hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i]; | ||
1329 | else | ||
1330 | tempval = EEPROM_DEFAULT_HT40_2SDIFF; | ||
1331 | rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_A][i] = | ||
1332 | (tempval & 0xf); | ||
1333 | rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_B][i] = | ||
1334 | ((tempval & 0xf0) >> 4); | ||
1335 | } | ||
1336 | |||
1337 | for (rf_path = 0; rf_path < 2; rf_path++) | ||
1338 | for (i = 0; i < 3; i++) | ||
1339 | RTPRINT(rtlpriv, FINIT, INIT_EEPROM, | ||
1340 | "RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path, | ||
1341 | i, rtlefuse->eeprom_chnlarea_txpwr_cck | ||
1342 | [rf_path][i]); | ||
1343 | for (rf_path = 0; rf_path < 2; rf_path++) | ||
1344 | for (i = 0; i < 3; i++) | ||
1345 | RTPRINT(rtlpriv, FINIT, INIT_EEPROM, | ||
1346 | "RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", | ||
1347 | rf_path, i, | ||
1348 | rtlefuse->eeprom_chnlarea_txpwr_ht40_1s | ||
1349 | [rf_path][i]); | ||
1350 | for (rf_path = 0; rf_path < 2; rf_path++) | ||
1351 | for (i = 0; i < 3; i++) | ||
1352 | RTPRINT(rtlpriv, FINIT, INIT_EEPROM, | ||
1353 | "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", | ||
1354 | rf_path, i, | ||
1355 | rtlefuse->eprom_chnl_txpwr_ht40_2sdf | ||
1356 | [rf_path][i]); | ||
1357 | |||
1358 | for (rf_path = 0; rf_path < 2; rf_path++) { | ||
1359 | for (i = 0; i < 14; i++) { | ||
1360 | index = _rtl8723ae_get_chnl_group((u8) i); | ||
1361 | |||
1362 | rtlefuse->txpwrlevel_cck[rf_path][i] = | ||
1363 | rtlefuse->eeprom_chnlarea_txpwr_cck | ||
1364 | [rf_path][index]; | ||
1365 | rtlefuse->txpwrlevel_ht40_1s[rf_path][i] = | ||
1366 | rtlefuse->eeprom_chnlarea_txpwr_ht40_1s | ||
1367 | [rf_path][index]; | ||
1368 | |||
1369 | if ((rtlefuse->eeprom_chnlarea_txpwr_ht40_1s | ||
1370 | [rf_path][index] - | ||
1371 | rtlefuse->eprom_chnl_txpwr_ht40_2sdf[rf_path] | ||
1372 | [index]) > 0) { | ||
1373 | rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = | ||
1374 | rtlefuse->eeprom_chnlarea_txpwr_ht40_1s | ||
1375 | [rf_path][index] - | ||
1376 | rtlefuse->eprom_chnl_txpwr_ht40_2sdf | ||
1377 | [rf_path][index]; | ||
1378 | } else { | ||
1379 | rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 0; | ||
1380 | } | ||
1381 | } | ||
1382 | |||
1383 | for (i = 0; i < 14; i++) { | ||
1384 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | ||
1385 | "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = " | ||
1386 | "[0x%x / 0x%x / 0x%x]\n", rf_path, i, | ||
1387 | rtlefuse->txpwrlevel_cck[rf_path][i], | ||
1388 | rtlefuse->txpwrlevel_ht40_1s[rf_path][i], | ||
1389 | rtlefuse->txpwrlevel_ht40_2s[rf_path][i]); | ||
1390 | } | ||
1391 | } | ||
1392 | |||
1393 | for (i = 0; i < 3; i++) { | ||
1394 | if (!autoload_fail) { | ||
1395 | rtlefuse->eeprom_pwrlimit_ht40[i] = | ||
1396 | hwinfo[EEPROM_TXPWR_GROUP + i]; | ||
1397 | rtlefuse->eeprom_pwrlimit_ht20[i] = | ||
1398 | hwinfo[EEPROM_TXPWR_GROUP + 3 + i]; | ||
1399 | } else { | ||
1400 | rtlefuse->eeprom_pwrlimit_ht40[i] = 0; | ||
1401 | rtlefuse->eeprom_pwrlimit_ht20[i] = 0; | ||
1402 | } | ||
1403 | } | ||
1404 | |||
1405 | for (rf_path = 0; rf_path < 2; rf_path++) { | ||
1406 | for (i = 0; i < 14; i++) { | ||
1407 | index = _rtl8723ae_get_chnl_group((u8) i); | ||
1408 | |||
1409 | if (rf_path == RF90_PATH_A) { | ||
1410 | rtlefuse->pwrgroup_ht20[rf_path][i] = | ||
1411 | (rtlefuse->eeprom_pwrlimit_ht20[index] & | ||
1412 | 0xf); | ||
1413 | rtlefuse->pwrgroup_ht40[rf_path][i] = | ||
1414 | (rtlefuse->eeprom_pwrlimit_ht40[index] & | ||
1415 | 0xf); | ||
1416 | } else if (rf_path == RF90_PATH_B) { | ||
1417 | rtlefuse->pwrgroup_ht20[rf_path][i] = | ||
1418 | ((rtlefuse->eeprom_pwrlimit_ht20[index] & | ||
1419 | 0xf0) >> 4); | ||
1420 | rtlefuse->pwrgroup_ht40[rf_path][i] = | ||
1421 | ((rtlefuse->eeprom_pwrlimit_ht40[index] & | ||
1422 | 0xf0) >> 4); | ||
1423 | } | ||
1424 | |||
1425 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | ||
1426 | "RF-%d pwrgroup_ht20[%d] = 0x%x\n", rf_path, i, | ||
1427 | rtlefuse->pwrgroup_ht20[rf_path][i]); | ||
1428 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | ||
1429 | "RF-%d pwrgroup_ht40[%d] = 0x%x\n", rf_path, i, | ||
1430 | rtlefuse->pwrgroup_ht40[rf_path][i]); | ||
1431 | } | ||
1432 | } | ||
1433 | |||
1434 | for (i = 0; i < 14; i++) { | ||
1435 | index = _rtl8723ae_get_chnl_group((u8) i); | ||
1436 | |||
1437 | if (!autoload_fail) | ||
1438 | tempval = hwinfo[EEPROM_TXPOWERHT20DIFF + index]; | ||
1439 | else | ||
1440 | tempval = EEPROM_DEFAULT_HT20_DIFF; | ||
1441 | |||
1442 | rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] = (tempval & 0xF); | ||
1443 | rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] = | ||
1444 | ((tempval >> 4) & 0xF); | ||
1445 | |||
1446 | if (rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] & BIT(3)) | ||
1447 | rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] |= 0xF0; | ||
1448 | |||
1449 | if (rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] & BIT(3)) | ||
1450 | rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] |= 0xF0; | ||
1451 | |||
1452 | index = _rtl8723ae_get_chnl_group((u8) i); | ||
1453 | |||
1454 | if (!autoload_fail) | ||
1455 | tempval = hwinfo[EEPROM_TXPOWER_OFDMDIFF + index]; | ||
1456 | else | ||
1457 | tempval = EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF; | ||
1458 | |||
1459 | rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i] = (tempval & 0xF); | ||
1460 | rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i] = | ||
1461 | ((tempval >> 4) & 0xF); | ||
1462 | } | ||
1463 | |||
1464 | rtlefuse->legacy_ht_txpowerdiff = | ||
1465 | rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][7]; | ||
1466 | |||
1467 | for (i = 0; i < 14; i++) | ||
1468 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | ||
1469 | "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i, | ||
1470 | rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]); | ||
1471 | for (i = 0; i < 14; i++) | ||
1472 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | ||
1473 | "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i, | ||
1474 | rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]); | ||
1475 | for (i = 0; i < 14; i++) | ||
1476 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | ||
1477 | "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i, | ||
1478 | rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]); | ||
1479 | for (i = 0; i < 14; i++) | ||
1480 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | ||
1481 | "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i, | ||
1482 | rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]); | ||
1483 | |||
1484 | if (!autoload_fail) | ||
1485 | rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7); | ||
1486 | else | ||
1487 | rtlefuse->eeprom_regulatory = 0; | ||
1488 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | ||
1489 | "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); | ||
1490 | |||
1491 | if (!autoload_fail) | ||
1492 | rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A]; | ||
1493 | else | ||
1494 | rtlefuse->eeprom_tssi[RF90_PATH_A] = EEPROM_DEFAULT_TSSI; | ||
1495 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | ||
1496 | "TSSI_A = 0x%x, TSSI_B = 0x%x\n", | ||
1497 | rtlefuse->eeprom_tssi[RF90_PATH_A], | ||
1498 | rtlefuse->eeprom_tssi[RF90_PATH_B]); | ||
1499 | |||
1500 | if (!autoload_fail) | ||
1501 | tempval = hwinfo[EEPROM_THERMAL_METER]; | ||
1502 | else | ||
1503 | tempval = EEPROM_DEFAULT_THERMALMETER; | ||
1504 | rtlefuse->eeprom_thermalmeter = (tempval & 0x1f); | ||
1505 | |||
1506 | if (rtlefuse->eeprom_thermalmeter == 0x1f || autoload_fail) | ||
1507 | rtlefuse->apk_thermalmeterignore = true; | ||
1508 | |||
1509 | rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; | ||
1510 | RTPRINT(rtlpriv, FINIT, INIT_TxPower, | ||
1511 | "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); | ||
1512 | } | ||
1513 | |||
1514 | static void _rtl8723ae_read_adapter_info(struct ieee80211_hw *hw, | ||
1515 | bool pseudo_test) | ||
1516 | { | ||
1517 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1518 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
1519 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1520 | u16 i, usvalue; | ||
1521 | u8 hwinfo[HWSET_MAX_SIZE]; | ||
1522 | u16 eeprom_id; | ||
1523 | |||
1524 | if (pseudo_test) { | ||
1525 | /* need add */ | ||
1526 | return; | ||
1527 | } | ||
1528 | if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) { | ||
1529 | rtl_efuse_shadow_map_update(hw); | ||
1530 | |||
1531 | memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], | ||
1532 | HWSET_MAX_SIZE); | ||
1533 | } else if (rtlefuse->epromtype == EEPROM_93C46) { | ||
1534 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
1535 | "RTL819X Not boot from eeprom, check it !!"); | ||
1536 | } | ||
1537 | |||
1538 | RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"), | ||
1539 | hwinfo, HWSET_MAX_SIZE); | ||
1540 | |||
1541 | eeprom_id = *((u16 *)&hwinfo[0]); | ||
1542 | if (eeprom_id != RTL8190_EEPROM_ID) { | ||
1543 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | ||
1544 | "EEPROM ID(%#x) is invalid!!\n", eeprom_id); | ||
1545 | rtlefuse->autoload_failflag = true; | ||
1546 | } else { | ||
1547 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); | ||
1548 | rtlefuse->autoload_failflag = false; | ||
1549 | } | ||
1550 | |||
1551 | if (rtlefuse->autoload_failflag == true) | ||
1552 | return; | ||
1553 | |||
1554 | rtlefuse->eeprom_vid = *(u16 *) &hwinfo[EEPROM_VID]; | ||
1555 | rtlefuse->eeprom_did = *(u16 *) &hwinfo[EEPROM_DID]; | ||
1556 | rtlefuse->eeprom_svid = *(u16 *) &hwinfo[EEPROM_SVID]; | ||
1557 | rtlefuse->eeprom_smid = *(u16 *) &hwinfo[EEPROM_SMID]; | ||
1558 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, | ||
1559 | "EEPROMId = 0x%4x\n", eeprom_id); | ||
1560 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, | ||
1561 | "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid); | ||
1562 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, | ||
1563 | "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did); | ||
1564 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, | ||
1565 | "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid); | ||
1566 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, | ||
1567 | "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid); | ||
1568 | |||
1569 | for (i = 0; i < 6; i += 2) { | ||
1570 | usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i]; | ||
1571 | *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue; | ||
1572 | } | ||
1573 | |||
1574 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
1575 | "dev_addr: %pM\n", rtlefuse->dev_addr); | ||
1576 | |||
1577 | _rtl8723ae_read_txpower_info_from_hwpg(hw, | ||
1578 | rtlefuse->autoload_failflag, hwinfo); | ||
1579 | |||
1580 | rtl8723ae_read_bt_coexist_info_from_hwpg(hw, | ||
1581 | rtlefuse->autoload_failflag, hwinfo); | ||
1582 | |||
1583 | rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; | ||
1584 | rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; | ||
1585 | rtlefuse->txpwr_fromeprom = true; | ||
1586 | rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; | ||
1587 | |||
1588 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, | ||
1589 | "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid); | ||
1590 | |||
1591 | /* set channel paln to world wide 13 */ | ||
1592 | rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13; | ||
1593 | |||
1594 | if (rtlhal->oem_id == RT_CID_DEFAULT) { | ||
1595 | switch (rtlefuse->eeprom_oemid) { | ||
1596 | case EEPROM_CID_DEFAULT: | ||
1597 | if (rtlefuse->eeprom_did == 0x8176) { | ||
1598 | if (CHK_SVID_SMID(0x10EC, 0x6151) || | ||
1599 | CHK_SVID_SMID(0x10EC, 0x6152) || | ||
1600 | CHK_SVID_SMID(0x10EC, 0x6154) || | ||
1601 | CHK_SVID_SMID(0x10EC, 0x6155) || | ||
1602 | CHK_SVID_SMID(0x10EC, 0x6177) || | ||
1603 | CHK_SVID_SMID(0x10EC, 0x6178) || | ||
1604 | CHK_SVID_SMID(0x10EC, 0x6179) || | ||
1605 | CHK_SVID_SMID(0x10EC, 0x6180) || | ||
1606 | CHK_SVID_SMID(0x10EC, 0x8151) || | ||
1607 | CHK_SVID_SMID(0x10EC, 0x8152) || | ||
1608 | CHK_SVID_SMID(0x10EC, 0x8154) || | ||
1609 | CHK_SVID_SMID(0x10EC, 0x8155) || | ||
1610 | CHK_SVID_SMID(0x10EC, 0x8181) || | ||
1611 | CHK_SVID_SMID(0x10EC, 0x8182) || | ||
1612 | CHK_SVID_SMID(0x10EC, 0x8184) || | ||
1613 | CHK_SVID_SMID(0x10EC, 0x8185) || | ||
1614 | CHK_SVID_SMID(0x10EC, 0x9151) || | ||
1615 | CHK_SVID_SMID(0x10EC, 0x9152) || | ||
1616 | CHK_SVID_SMID(0x10EC, 0x9154) || | ||
1617 | CHK_SVID_SMID(0x10EC, 0x9155) || | ||
1618 | CHK_SVID_SMID(0x10EC, 0x9181) || | ||
1619 | CHK_SVID_SMID(0x10EC, 0x9182) || | ||
1620 | CHK_SVID_SMID(0x10EC, 0x9184) || | ||
1621 | CHK_SVID_SMID(0x10EC, 0x9185)) | ||
1622 | rtlhal->oem_id = RT_CID_TOSHIBA; | ||
1623 | else if (rtlefuse->eeprom_svid == 0x1025) | ||
1624 | rtlhal->oem_id = RT_CID_819x_Acer; | ||
1625 | else if (CHK_SVID_SMID(0x10EC, 0x6191) || | ||
1626 | CHK_SVID_SMID(0x10EC, 0x6192) || | ||
1627 | CHK_SVID_SMID(0x10EC, 0x6193) || | ||
1628 | CHK_SVID_SMID(0x10EC, 0x7191) || | ||
1629 | CHK_SVID_SMID(0x10EC, 0x7192) || | ||
1630 | CHK_SVID_SMID(0x10EC, 0x7193) || | ||
1631 | CHK_SVID_SMID(0x10EC, 0x8191) || | ||
1632 | CHK_SVID_SMID(0x10EC, 0x8192) || | ||
1633 | CHK_SVID_SMID(0x10EC, 0x8193)) | ||
1634 | rtlhal->oem_id = RT_CID_819x_SAMSUNG; | ||
1635 | else if (CHK_SVID_SMID(0x10EC, 0x8195) || | ||
1636 | CHK_SVID_SMID(0x10EC, 0x9195) || | ||
1637 | CHK_SVID_SMID(0x10EC, 0x7194) || | ||
1638 | CHK_SVID_SMID(0x10EC, 0x8200) || | ||
1639 | CHK_SVID_SMID(0x10EC, 0x8201) || | ||
1640 | CHK_SVID_SMID(0x10EC, 0x8202) || | ||
1641 | CHK_SVID_SMID(0x10EC, 0x9200)) | ||
1642 | rtlhal->oem_id = RT_CID_819x_Lenovo; | ||
1643 | else if (CHK_SVID_SMID(0x10EC, 0x8197) || | ||
1644 | CHK_SVID_SMID(0x10EC, 0x9196)) | ||
1645 | rtlhal->oem_id = RT_CID_819x_CLEVO; | ||
1646 | else if (CHK_SVID_SMID(0x1028, 0x8194) || | ||
1647 | CHK_SVID_SMID(0x1028, 0x8198) || | ||
1648 | CHK_SVID_SMID(0x1028, 0x9197) || | ||
1649 | CHK_SVID_SMID(0x1028, 0x9198)) | ||
1650 | rtlhal->oem_id = RT_CID_819x_DELL; | ||
1651 | else if (CHK_SVID_SMID(0x103C, 0x1629)) | ||
1652 | rtlhal->oem_id = RT_CID_819x_HP; | ||
1653 | else if (CHK_SVID_SMID(0x1A32, 0x2315)) | ||
1654 | rtlhal->oem_id = RT_CID_819x_QMI; | ||
1655 | else if (CHK_SVID_SMID(0x10EC, 0x8203)) | ||
1656 | rtlhal->oem_id = RT_CID_819x_PRONETS; | ||
1657 | else if (CHK_SVID_SMID(0x1043, 0x84B5)) | ||
1658 | rtlhal->oem_id = | ||
1659 | RT_CID_819x_Edimax_ASUS; | ||
1660 | else | ||
1661 | rtlhal->oem_id = RT_CID_DEFAULT; | ||
1662 | } else if (rtlefuse->eeprom_did == 0x8178) { | ||
1663 | if (CHK_SVID_SMID(0x10EC, 0x6181) || | ||
1664 | CHK_SVID_SMID(0x10EC, 0x6182) || | ||
1665 | CHK_SVID_SMID(0x10EC, 0x6184) || | ||
1666 | CHK_SVID_SMID(0x10EC, 0x6185) || | ||
1667 | CHK_SVID_SMID(0x10EC, 0x7181) || | ||
1668 | CHK_SVID_SMID(0x10EC, 0x7182) || | ||
1669 | CHK_SVID_SMID(0x10EC, 0x7184) || | ||
1670 | CHK_SVID_SMID(0x10EC, 0x7185) || | ||
1671 | CHK_SVID_SMID(0x10EC, 0x8181) || | ||
1672 | CHK_SVID_SMID(0x10EC, 0x8182) || | ||
1673 | CHK_SVID_SMID(0x10EC, 0x8184) || | ||
1674 | CHK_SVID_SMID(0x10EC, 0x8185) || | ||
1675 | CHK_SVID_SMID(0x10EC, 0x9181) || | ||
1676 | CHK_SVID_SMID(0x10EC, 0x9182) || | ||
1677 | CHK_SVID_SMID(0x10EC, 0x9184) || | ||
1678 | CHK_SVID_SMID(0x10EC, 0x9185)) | ||
1679 | rtlhal->oem_id = RT_CID_TOSHIBA; | ||
1680 | else if (rtlefuse->eeprom_svid == 0x1025) | ||
1681 | rtlhal->oem_id = RT_CID_819x_Acer; | ||
1682 | else if (CHK_SVID_SMID(0x10EC, 0x8186)) | ||
1683 | rtlhal->oem_id = RT_CID_819x_PRONETS; | ||
1684 | else if (CHK_SVID_SMID(0x1043, 0x8486)) | ||
1685 | rtlhal->oem_id = | ||
1686 | RT_CID_819x_Edimax_ASUS; | ||
1687 | else | ||
1688 | rtlhal->oem_id = RT_CID_DEFAULT; | ||
1689 | } else { | ||
1690 | rtlhal->oem_id = RT_CID_DEFAULT; | ||
1691 | } | ||
1692 | break; | ||
1693 | case EEPROM_CID_TOSHIBA: | ||
1694 | rtlhal->oem_id = RT_CID_TOSHIBA; | ||
1695 | break; | ||
1696 | case EEPROM_CID_CCX: | ||
1697 | rtlhal->oem_id = RT_CID_CCX; | ||
1698 | break; | ||
1699 | case EEPROM_CID_QMI: | ||
1700 | rtlhal->oem_id = RT_CID_819x_QMI; | ||
1701 | break; | ||
1702 | case EEPROM_CID_WHQL: | ||
1703 | break; | ||
1704 | default: | ||
1705 | rtlhal->oem_id = RT_CID_DEFAULT; | ||
1706 | break; | ||
1707 | |||
1708 | } | ||
1709 | } | ||
1710 | } | ||
1711 | |||
1712 | static void _rtl8723ae_hal_customized_behavior(struct ieee80211_hw *hw) | ||
1713 | { | ||
1714 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1715 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); | ||
1716 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1717 | |||
1718 | switch (rtlhal->oem_id) { | ||
1719 | case RT_CID_819x_HP: | ||
1720 | pcipriv->ledctl.led_opendrain = true; | ||
1721 | break; | ||
1722 | case RT_CID_819x_Lenovo: | ||
1723 | case RT_CID_DEFAULT: | ||
1724 | case RT_CID_TOSHIBA: | ||
1725 | case RT_CID_CCX: | ||
1726 | case RT_CID_819x_Acer: | ||
1727 | case RT_CID_WHQL: | ||
1728 | default: | ||
1729 | break; | ||
1730 | } | ||
1731 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
1732 | "RT Customized ID: 0x%02X\n", rtlhal->oem_id); | ||
1733 | } | ||
1734 | |||
1735 | void rtl8723ae_read_eeprom_info(struct ieee80211_hw *hw) | ||
1736 | { | ||
1737 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1738 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
1739 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1740 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1741 | u8 tmp_u1b; | ||
1742 | u32 value32; | ||
1743 | |||
1744 | value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST]); | ||
1745 | value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0); | ||
1746 | rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST], value32); | ||
1747 | |||
1748 | rtlhal->version = _rtl8723ae_read_chip_version(hw); | ||
1749 | |||
1750 | if (get_rf_type(rtlphy) == RF_1T1R) | ||
1751 | rtlpriv->dm.rfpath_rxenable[0] = true; | ||
1752 | else | ||
1753 | rtlpriv->dm.rfpath_rxenable[0] = | ||
1754 | rtlpriv->dm.rfpath_rxenable[1] = true; | ||
1755 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n", | ||
1756 | rtlhal->version); | ||
1757 | |||
1758 | tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); | ||
1759 | if (tmp_u1b & BIT(4)) { | ||
1760 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n"); | ||
1761 | rtlefuse->epromtype = EEPROM_93C46; | ||
1762 | } else { | ||
1763 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n"); | ||
1764 | rtlefuse->epromtype = EEPROM_BOOT_EFUSE; | ||
1765 | } | ||
1766 | if (tmp_u1b & BIT(5)) { | ||
1767 | RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); | ||
1768 | rtlefuse->autoload_failflag = false; | ||
1769 | _rtl8723ae_read_adapter_info(hw, false); | ||
1770 | } else { | ||
1771 | rtlefuse->autoload_failflag = true; | ||
1772 | _rtl8723ae_read_adapter_info(hw, false); | ||
1773 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Autoload ERR!!\n"); | ||
1774 | } | ||
1775 | _rtl8723ae_hal_customized_behavior(hw); | ||
1776 | } | ||
1777 | |||
1778 | static void rtl8723ae_update_hal_rate_table(struct ieee80211_hw *hw, | ||
1779 | struct ieee80211_sta *sta) | ||
1780 | { | ||
1781 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1782 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); | ||
1783 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1784 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
1785 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1786 | u32 ratr_value; | ||
1787 | u8 ratr_index = 0; | ||
1788 | u8 nmode = mac->ht_enable; | ||
1789 | u8 mimo_ps = IEEE80211_SMPS_OFF; | ||
1790 | u8 curtxbw_40mhz = mac->bw_40; | ||
1791 | u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? | ||
1792 | 1 : 0; | ||
1793 | u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? | ||
1794 | 1 : 0; | ||
1795 | enum wireless_mode wirelessmode = mac->mode; | ||
1796 | |||
1797 | if (rtlhal->current_bandtype == BAND_ON_5G) | ||
1798 | ratr_value = sta->supp_rates[1] << 4; | ||
1799 | else | ||
1800 | ratr_value = sta->supp_rates[0]; | ||
1801 | if (mac->opmode == NL80211_IFTYPE_ADHOC) | ||
1802 | ratr_value = 0xfff; | ||
1803 | ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 | | ||
1804 | sta->ht_cap.mcs.rx_mask[0] << 12); | ||
1805 | switch (wirelessmode) { | ||
1806 | case WIRELESS_MODE_B: | ||
1807 | if (ratr_value & 0x0000000c) | ||
1808 | ratr_value &= 0x0000000d; | ||
1809 | else | ||
1810 | ratr_value &= 0x0000000f; | ||
1811 | break; | ||
1812 | case WIRELESS_MODE_G: | ||
1813 | ratr_value &= 0x00000FF5; | ||
1814 | break; | ||
1815 | case WIRELESS_MODE_N_24G: | ||
1816 | case WIRELESS_MODE_N_5G: | ||
1817 | nmode = 1; | ||
1818 | if (mimo_ps == IEEE80211_SMPS_STATIC) { | ||
1819 | ratr_value &= 0x0007F005; | ||
1820 | } else { | ||
1821 | u32 ratr_mask; | ||
1822 | |||
1823 | if (get_rf_type(rtlphy) == RF_1T2R || | ||
1824 | get_rf_type(rtlphy) == RF_1T1R) | ||
1825 | ratr_mask = 0x000ff005; | ||
1826 | else | ||
1827 | ratr_mask = 0x0f0ff005; | ||
1828 | |||
1829 | ratr_value &= ratr_mask; | ||
1830 | } | ||
1831 | break; | ||
1832 | default: | ||
1833 | if (rtlphy->rf_type == RF_1T2R) | ||
1834 | ratr_value &= 0x000ff0ff; | ||
1835 | else | ||
1836 | ratr_value &= 0x0f0ff0ff; | ||
1837 | |||
1838 | break; | ||
1839 | } | ||
1840 | |||
1841 | if ((pcipriv->bt_coexist.bt_coexistence) && | ||
1842 | (pcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4) && | ||
1843 | (pcipriv->bt_coexist.bt_cur_state) && | ||
1844 | (pcipriv->bt_coexist.bt_ant_isolation) && | ||
1845 | ((pcipriv->bt_coexist.bt_service == BT_SCO) || | ||
1846 | (pcipriv->bt_coexist.bt_service == BT_BUSY))) | ||
1847 | ratr_value &= 0x0fffcfc0; | ||
1848 | else | ||
1849 | ratr_value &= 0x0FFFFFFF; | ||
1850 | |||
1851 | if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) || | ||
1852 | (!curtxbw_40mhz && curshortgi_20mhz))) | ||
1853 | ratr_value |= 0x10000000; | ||
1854 | |||
1855 | rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); | ||
1856 | |||
1857 | RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, | ||
1858 | "%x\n", rtl_read_dword(rtlpriv, REG_ARFR0)); | ||
1859 | } | ||
1860 | |||
1861 | static void rtl8723ae_update_hal_rate_mask(struct ieee80211_hw *hw, | ||
1862 | struct ieee80211_sta *sta, u8 rssi_level) | ||
1863 | { | ||
1864 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1865 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1866 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
1867 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1868 | struct rtl_sta_info *sta_entry = NULL; | ||
1869 | u32 ratr_bitmap; | ||
1870 | u8 ratr_index; | ||
1871 | u8 curtxbw_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) | ||
1872 | ? 1 : 0; | ||
1873 | u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? | ||
1874 | 1 : 0; | ||
1875 | u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? | ||
1876 | 1 : 0; | ||
1877 | enum wireless_mode wirelessmode = 0; | ||
1878 | bool shortgi = false; | ||
1879 | u8 rate_mask[5]; | ||
1880 | u8 macid = 0; | ||
1881 | u8 mimo_ps = IEEE80211_SMPS_OFF; | ||
1882 | |||
1883 | sta_entry = (struct rtl_sta_info *) sta->drv_priv; | ||
1884 | wirelessmode = sta_entry->wireless_mode; | ||
1885 | if (mac->opmode == NL80211_IFTYPE_STATION) | ||
1886 | curtxbw_40mhz = mac->bw_40; | ||
1887 | else if (mac->opmode == NL80211_IFTYPE_AP || | ||
1888 | mac->opmode == NL80211_IFTYPE_ADHOC) | ||
1889 | macid = sta->aid + 1; | ||
1890 | |||
1891 | if (rtlhal->current_bandtype == BAND_ON_5G) | ||
1892 | ratr_bitmap = sta->supp_rates[1] << 4; | ||
1893 | else | ||
1894 | ratr_bitmap = sta->supp_rates[0]; | ||
1895 | if (mac->opmode == NL80211_IFTYPE_ADHOC) | ||
1896 | ratr_bitmap = 0xfff; | ||
1897 | ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 | | ||
1898 | sta->ht_cap.mcs.rx_mask[0] << 12); | ||
1899 | switch (wirelessmode) { | ||
1900 | case WIRELESS_MODE_B: | ||
1901 | ratr_index = RATR_INX_WIRELESS_B; | ||
1902 | if (ratr_bitmap & 0x0000000c) | ||
1903 | ratr_bitmap &= 0x0000000d; | ||
1904 | else | ||
1905 | ratr_bitmap &= 0x0000000f; | ||
1906 | break; | ||
1907 | case WIRELESS_MODE_G: | ||
1908 | ratr_index = RATR_INX_WIRELESS_GB; | ||
1909 | |||
1910 | if (rssi_level == 1) | ||
1911 | ratr_bitmap &= 0x00000f00; | ||
1912 | else if (rssi_level == 2) | ||
1913 | ratr_bitmap &= 0x00000ff0; | ||
1914 | else | ||
1915 | ratr_bitmap &= 0x00000ff5; | ||
1916 | break; | ||
1917 | case WIRELESS_MODE_A: | ||
1918 | ratr_index = RATR_INX_WIRELESS_A; | ||
1919 | ratr_bitmap &= 0x00000ff0; | ||
1920 | break; | ||
1921 | case WIRELESS_MODE_N_24G: | ||
1922 | case WIRELESS_MODE_N_5G: | ||
1923 | ratr_index = RATR_INX_WIRELESS_NGB; | ||
1924 | |||
1925 | if (mimo_ps == IEEE80211_SMPS_STATIC) { | ||
1926 | if (rssi_level == 1) | ||
1927 | ratr_bitmap &= 0x00070000; | ||
1928 | else if (rssi_level == 2) | ||
1929 | ratr_bitmap &= 0x0007f000; | ||
1930 | else | ||
1931 | ratr_bitmap &= 0x0007f005; | ||
1932 | } else { | ||
1933 | if (rtlphy->rf_type == RF_1T2R || | ||
1934 | rtlphy->rf_type == RF_1T1R) { | ||
1935 | if (curtxbw_40mhz) { | ||
1936 | if (rssi_level == 1) | ||
1937 | ratr_bitmap &= 0x000f0000; | ||
1938 | else if (rssi_level == 2) | ||
1939 | ratr_bitmap &= 0x000ff000; | ||
1940 | else | ||
1941 | ratr_bitmap &= 0x000ff015; | ||
1942 | } else { | ||
1943 | if (rssi_level == 1) | ||
1944 | ratr_bitmap &= 0x000f0000; | ||
1945 | else if (rssi_level == 2) | ||
1946 | ratr_bitmap &= 0x000ff000; | ||
1947 | else | ||
1948 | ratr_bitmap &= 0x000ff005; | ||
1949 | } | ||
1950 | } else { | ||
1951 | if (curtxbw_40mhz) { | ||
1952 | if (rssi_level == 1) | ||
1953 | ratr_bitmap &= 0x0f0f0000; | ||
1954 | else if (rssi_level == 2) | ||
1955 | ratr_bitmap &= 0x0f0ff000; | ||
1956 | else | ||
1957 | ratr_bitmap &= 0x0f0ff015; | ||
1958 | } else { | ||
1959 | if (rssi_level == 1) | ||
1960 | ratr_bitmap &= 0x0f0f0000; | ||
1961 | else if (rssi_level == 2) | ||
1962 | ratr_bitmap &= 0x0f0ff000; | ||
1963 | else | ||
1964 | ratr_bitmap &= 0x0f0ff005; | ||
1965 | } | ||
1966 | } | ||
1967 | } | ||
1968 | |||
1969 | if ((curtxbw_40mhz && curshortgi_40mhz) || | ||
1970 | (!curtxbw_40mhz && curshortgi_20mhz)) { | ||
1971 | if (macid == 0) | ||
1972 | shortgi = true; | ||
1973 | else if (macid == 1) | ||
1974 | shortgi = false; | ||
1975 | } | ||
1976 | break; | ||
1977 | default: | ||
1978 | ratr_index = RATR_INX_WIRELESS_NGB; | ||
1979 | |||
1980 | if (rtlphy->rf_type == RF_1T2R) | ||
1981 | ratr_bitmap &= 0x000ff0ff; | ||
1982 | else | ||
1983 | ratr_bitmap &= 0x0f0ff0ff; | ||
1984 | break; | ||
1985 | } | ||
1986 | sta_entry->ratr_index = ratr_index; | ||
1987 | |||
1988 | RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, | ||
1989 | "ratr_bitmap :%x\n", ratr_bitmap); | ||
1990 | /* convert ratr_bitmap to le byte array */ | ||
1991 | rate_mask[0] = ratr_bitmap; | ||
1992 | rate_mask[1] = (ratr_bitmap >>= 8); | ||
1993 | rate_mask[2] = (ratr_bitmap >>= 8); | ||
1994 | rate_mask[3] = ((ratr_bitmap >> 8) & 0x0f) | (ratr_index << 4); | ||
1995 | rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; | ||
1996 | RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, | ||
1997 | "Rate_index:%x, ratr_bitmap: %*phC\n", | ||
1998 | ratr_index, 5, rate_mask); | ||
1999 | rtl8723ae_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask); | ||
2000 | } | ||
2001 | |||
2002 | void rtl8723ae_update_hal_rate_tbl(struct ieee80211_hw *hw, | ||
2003 | struct ieee80211_sta *sta, u8 rssi_level) | ||
2004 | { | ||
2005 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2006 | |||
2007 | if (rtlpriv->dm.useramask) | ||
2008 | rtl8723ae_update_hal_rate_mask(hw, sta, rssi_level); | ||
2009 | else | ||
2010 | rtl8723ae_update_hal_rate_table(hw, sta); | ||
2011 | } | ||
2012 | |||
2013 | void rtl8723ae_update_channel_access_setting(struct ieee80211_hw *hw) | ||
2014 | { | ||
2015 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2016 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
2017 | u16 sifs_timer; | ||
2018 | |||
2019 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, | ||
2020 | (u8 *)&mac->slot_time); | ||
2021 | if (!mac->ht_enable) | ||
2022 | sifs_timer = 0x0a0a; | ||
2023 | else | ||
2024 | sifs_timer = 0x1010; | ||
2025 | rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); | ||
2026 | } | ||
2027 | |||
2028 | bool rtl8723ae_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) | ||
2029 | { | ||
2030 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2031 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
2032 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
2033 | enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate; | ||
2034 | u8 u1tmp; | ||
2035 | bool actuallyset = false; | ||
2036 | |||
2037 | if (rtlpriv->rtlhal.being_init_adapter) | ||
2038 | return false; | ||
2039 | |||
2040 | if (ppsc->swrf_processing) | ||
2041 | return false; | ||
2042 | |||
2043 | spin_lock(&rtlpriv->locks.rf_ps_lock); | ||
2044 | if (ppsc->rfchange_inprogress) { | ||
2045 | spin_unlock(&rtlpriv->locks.rf_ps_lock); | ||
2046 | return false; | ||
2047 | } else { | ||
2048 | ppsc->rfchange_inprogress = true; | ||
2049 | spin_unlock(&rtlpriv->locks.rf_ps_lock); | ||
2050 | } | ||
2051 | |||
2052 | cur_rfstate = ppsc->rfpwr_state; | ||
2053 | |||
2054 | rtl_write_byte(rtlpriv, REG_GPIO_IO_SEL_2, | ||
2055 | rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL_2)&~(BIT(1))); | ||
2056 | |||
2057 | u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL_2); | ||
2058 | |||
2059 | if (rtlphy->polarity_ctl) | ||
2060 | e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFOFF : ERFON; | ||
2061 | else | ||
2062 | e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFON : ERFOFF; | ||
2063 | |||
2064 | if ((ppsc->hwradiooff == true) && (e_rfpowerstate_toset == ERFON)) { | ||
2065 | RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, | ||
2066 | "GPIOChangeRF - HW Radio ON, RF ON\n"); | ||
2067 | |||
2068 | e_rfpowerstate_toset = ERFON; | ||
2069 | ppsc->hwradiooff = false; | ||
2070 | actuallyset = true; | ||
2071 | } else if ((ppsc->hwradiooff == false) | ||
2072 | && (e_rfpowerstate_toset == ERFOFF)) { | ||
2073 | RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, | ||
2074 | "GPIOChangeRF - HW Radio OFF, RF OFF\n"); | ||
2075 | |||
2076 | e_rfpowerstate_toset = ERFOFF; | ||
2077 | ppsc->hwradiooff = true; | ||
2078 | actuallyset = true; | ||
2079 | } | ||
2080 | |||
2081 | if (actuallyset) { | ||
2082 | spin_lock(&rtlpriv->locks.rf_ps_lock); | ||
2083 | ppsc->rfchange_inprogress = false; | ||
2084 | spin_unlock(&rtlpriv->locks.rf_ps_lock); | ||
2085 | } else { | ||
2086 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) | ||
2087 | RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); | ||
2088 | |||
2089 | spin_lock(&rtlpriv->locks.rf_ps_lock); | ||
2090 | ppsc->rfchange_inprogress = false; | ||
2091 | spin_unlock(&rtlpriv->locks.rf_ps_lock); | ||
2092 | } | ||
2093 | |||
2094 | *valid = 1; | ||
2095 | return !ppsc->hwradiooff; | ||
2096 | } | ||
2097 | |||
2098 | void rtl8723ae_set_key(struct ieee80211_hw *hw, u32 key_index, | ||
2099 | u8 *p_macaddr, bool is_group, u8 enc_algo, | ||
2100 | bool is_wepkey, bool clear_all) | ||
2101 | { | ||
2102 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2103 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
2104 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
2105 | u8 *macaddr = p_macaddr; | ||
2106 | u32 entry_id = 0; | ||
2107 | bool is_pairwise = false; | ||
2108 | static u8 cam_const_addr[4][6] = { | ||
2109 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, | ||
2110 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, | ||
2111 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, | ||
2112 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} | ||
2113 | }; | ||
2114 | static u8 cam_const_broad[] = { | ||
2115 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff | ||
2116 | }; | ||
2117 | |||
2118 | if (clear_all) { | ||
2119 | u8 idx = 0; | ||
2120 | u8 cam_offset = 0; | ||
2121 | u8 clear_number = 5; | ||
2122 | |||
2123 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); | ||
2124 | |||
2125 | for (idx = 0; idx < clear_number; idx++) { | ||
2126 | rtl_cam_mark_invalid(hw, cam_offset + idx); | ||
2127 | rtl_cam_empty_entry(hw, cam_offset + idx); | ||
2128 | |||
2129 | if (idx < 5) { | ||
2130 | memset(rtlpriv->sec.key_buf[idx], 0, | ||
2131 | MAX_KEY_LEN); | ||
2132 | rtlpriv->sec.key_len[idx] = 0; | ||
2133 | } | ||
2134 | } | ||
2135 | } else { | ||
2136 | switch (enc_algo) { | ||
2137 | case WEP40_ENCRYPTION: | ||
2138 | enc_algo = CAM_WEP40; | ||
2139 | break; | ||
2140 | case WEP104_ENCRYPTION: | ||
2141 | enc_algo = CAM_WEP104; | ||
2142 | break; | ||
2143 | case TKIP_ENCRYPTION: | ||
2144 | enc_algo = CAM_TKIP; | ||
2145 | break; | ||
2146 | case AESCCMP_ENCRYPTION: | ||
2147 | enc_algo = CAM_AES; | ||
2148 | break; | ||
2149 | default: | ||
2150 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
2151 | "switch case not processed\n"); | ||
2152 | enc_algo = CAM_TKIP; | ||
2153 | break; | ||
2154 | } | ||
2155 | |||
2156 | if (is_wepkey || rtlpriv->sec.use_defaultkey) { | ||
2157 | macaddr = cam_const_addr[key_index]; | ||
2158 | entry_id = key_index; | ||
2159 | } else { | ||
2160 | if (is_group) { | ||
2161 | macaddr = cam_const_broad; | ||
2162 | entry_id = key_index; | ||
2163 | } else { | ||
2164 | if (mac->opmode == NL80211_IFTYPE_AP) { | ||
2165 | entry_id = rtl_cam_get_free_entry(hw, | ||
2166 | macaddr); | ||
2167 | if (entry_id >= TOTAL_CAM_ENTRY) { | ||
2168 | RT_TRACE(rtlpriv, COMP_SEC, | ||
2169 | DBG_EMERG, | ||
2170 | "Can not find free hw security cam entry\n"); | ||
2171 | return; | ||
2172 | } | ||
2173 | } else { | ||
2174 | entry_id = CAM_PAIRWISE_KEY_POSITION; | ||
2175 | } | ||
2176 | |||
2177 | key_index = PAIRWISE_KEYIDX; | ||
2178 | is_pairwise = true; | ||
2179 | } | ||
2180 | } | ||
2181 | |||
2182 | if (rtlpriv->sec.key_len[key_index] == 0) { | ||
2183 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | ||
2184 | "delete one entry, entry_id is %d\n", | ||
2185 | entry_id); | ||
2186 | if (mac->opmode == NL80211_IFTYPE_AP) | ||
2187 | rtl_cam_del_entry(hw, p_macaddr); | ||
2188 | rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); | ||
2189 | } else { | ||
2190 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | ||
2191 | "add one entry\n"); | ||
2192 | if (is_pairwise) { | ||
2193 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | ||
2194 | "set Pairwiase key\n"); | ||
2195 | |||
2196 | rtl_cam_add_one_entry(hw, macaddr, key_index, | ||
2197 | entry_id, enc_algo, | ||
2198 | CAM_CONFIG_NO_USEDK, | ||
2199 | rtlpriv->sec.key_buf[key_index]); | ||
2200 | } else { | ||
2201 | RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, | ||
2202 | "set group key\n"); | ||
2203 | |||
2204 | if (mac->opmode == NL80211_IFTYPE_ADHOC) { | ||
2205 | rtl_cam_add_one_entry(hw, | ||
2206 | rtlefuse->dev_addr, | ||
2207 | PAIRWISE_KEYIDX, | ||
2208 | CAM_PAIRWISE_KEY_POSITION, | ||
2209 | enc_algo, | ||
2210 | CAM_CONFIG_NO_USEDK, | ||
2211 | rtlpriv->sec.key_buf | ||
2212 | [entry_id]); | ||
2213 | } | ||
2214 | |||
2215 | rtl_cam_add_one_entry(hw, macaddr, key_index, | ||
2216 | entry_id, enc_algo, | ||
2217 | CAM_CONFIG_NO_USEDK, | ||
2218 | rtlpriv->sec.key_buf[entry_id]); | ||
2219 | } | ||
2220 | |||
2221 | } | ||
2222 | } | ||
2223 | } | ||
2224 | |||
2225 | static void rtl8723ae_bt_var_init(struct ieee80211_hw *hw) | ||
2226 | { | ||
2227 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); | ||
2228 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2229 | |||
2230 | pcipriv->bt_coexist.bt_coexistence = | ||
2231 | pcipriv->bt_coexist.eeprom_bt_coexist; | ||
2232 | pcipriv->bt_coexist.bt_ant_num = | ||
2233 | pcipriv->bt_coexist.eeprom_bt_ant_num; | ||
2234 | pcipriv->bt_coexist.bt_coexist_type = | ||
2235 | pcipriv->bt_coexist.eeprom_bt_type; | ||
2236 | |||
2237 | pcipriv->bt_coexist.bt_ant_isolation = | ||
2238 | pcipriv->bt_coexist.eeprom_bt_ant_isol; | ||
2239 | |||
2240 | pcipriv->bt_coexist.bt_radio_shared_type = | ||
2241 | pcipriv->bt_coexist.eeprom_bt_radio_shared; | ||
2242 | |||
2243 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
2244 | "BT Coexistance = 0x%x\n", | ||
2245 | pcipriv->bt_coexist.bt_coexistence); | ||
2246 | |||
2247 | if (pcipriv->bt_coexist.bt_coexistence) { | ||
2248 | pcipriv->bt_coexist.bt_busy_traffic = false; | ||
2249 | pcipriv->bt_coexist.bt_traffic_mode_set = false; | ||
2250 | pcipriv->bt_coexist.bt_non_traffic_mode_set = false; | ||
2251 | |||
2252 | pcipriv->bt_coexist.cstate = 0; | ||
2253 | pcipriv->bt_coexist.previous_state = 0; | ||
2254 | |||
2255 | if (pcipriv->bt_coexist.bt_ant_num == ANT_X2) { | ||
2256 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
2257 | "BlueTooth BT_Ant_Num = Antx2\n"); | ||
2258 | } else if (pcipriv->bt_coexist.bt_ant_num == ANT_X1) { | ||
2259 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
2260 | "BlueTooth BT_Ant_Num = Antx1\n"); | ||
2261 | } | ||
2262 | |||
2263 | switch (pcipriv->bt_coexist.bt_coexist_type) { | ||
2264 | case BT_2WIRE: | ||
2265 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
2266 | "BlueTooth BT_CoexistType = BT_2Wire\n"); | ||
2267 | break; | ||
2268 | case BT_ISSC_3WIRE: | ||
2269 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
2270 | "BlueTooth BT_CoexistType = BT_ISSC_3Wire\n"); | ||
2271 | break; | ||
2272 | case BT_ACCEL: | ||
2273 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
2274 | "BlueTooth BT_CoexistType = BT_ACCEL\n"); | ||
2275 | break; | ||
2276 | case BT_CSR_BC4: | ||
2277 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
2278 | "BlueTooth BT_CoexistType = BT_CSR_BC4\n"); | ||
2279 | break; | ||
2280 | case BT_CSR_BC8: | ||
2281 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
2282 | "BlueTooth BT_CoexistType = BT_CSR_BC8\n"); | ||
2283 | break; | ||
2284 | case BT_RTL8756: | ||
2285 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
2286 | "BlueTooth BT_CoexistType = BT_RTL8756\n"); | ||
2287 | break; | ||
2288 | default: | ||
2289 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
2290 | "BlueTooth BT_CoexistType = Unknown\n"); | ||
2291 | break; | ||
2292 | } | ||
2293 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
2294 | "BlueTooth BT_Ant_isolation = %d\n", | ||
2295 | pcipriv->bt_coexist.bt_ant_isolation); | ||
2296 | RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, | ||
2297 | "BT_RadioSharedType = 0x%x\n", | ||
2298 | pcipriv->bt_coexist.bt_radio_shared_type); | ||
2299 | pcipriv->bt_coexist.bt_active_zero_cnt = 0; | ||
2300 | pcipriv->bt_coexist.cur_bt_disabled = false; | ||
2301 | pcipriv->bt_coexist.pre_bt_disabled = false; | ||
2302 | } | ||
2303 | } | ||
2304 | |||
2305 | void rtl8723ae_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, | ||
2306 | bool auto_load_fail, u8 *hwinfo) | ||
2307 | { | ||
2308 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); | ||
2309 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2310 | u8 value; | ||
2311 | u32 tmpu_32; | ||
2312 | |||
2313 | if (!auto_load_fail) { | ||
2314 | tmpu_32 = rtl_read_dword(rtlpriv, REG_MULTI_FUNC_CTRL); | ||
2315 | if (tmpu_32 & BIT(18)) | ||
2316 | pcipriv->bt_coexist.eeprom_bt_coexist = 1; | ||
2317 | else | ||
2318 | pcipriv->bt_coexist.eeprom_bt_coexist = 0; | ||
2319 | value = hwinfo[RF_OPTION4]; | ||
2320 | pcipriv->bt_coexist.eeprom_bt_type = BT_RTL8723A; | ||
2321 | pcipriv->bt_coexist.eeprom_bt_ant_num = (value & 0x1); | ||
2322 | pcipriv->bt_coexist.eeprom_bt_ant_isol = ((value & 0x10) >> 4); | ||
2323 | pcipriv->bt_coexist.eeprom_bt_radio_shared = | ||
2324 | ((value & 0x20) >> 5); | ||
2325 | } else { | ||
2326 | pcipriv->bt_coexist.eeprom_bt_coexist = 0; | ||
2327 | pcipriv->bt_coexist.eeprom_bt_type = BT_RTL8723A; | ||
2328 | pcipriv->bt_coexist.eeprom_bt_ant_num = ANT_X2; | ||
2329 | pcipriv->bt_coexist.eeprom_bt_ant_isol = 0; | ||
2330 | pcipriv->bt_coexist.eeprom_bt_radio_shared = BT_RADIO_SHARED; | ||
2331 | } | ||
2332 | |||
2333 | rtl8723ae_bt_var_init(hw); | ||
2334 | } | ||
2335 | |||
2336 | void rtl8723ae_bt_reg_init(struct ieee80211_hw *hw) | ||
2337 | { | ||
2338 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); | ||
2339 | |||
2340 | /* 0:Low, 1:High, 2:From Efuse. */ | ||
2341 | pcipriv->bt_coexist.reg_bt_iso = 2; | ||
2342 | /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */ | ||
2343 | pcipriv->bt_coexist.reg_bt_sco = 3; | ||
2344 | /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */ | ||
2345 | pcipriv->bt_coexist.reg_bt_sco = 0; | ||
2346 | } | ||
2347 | |||
2348 | |||
2349 | void rtl8723ae_bt_hw_init(struct ieee80211_hw *hw) | ||
2350 | { | ||
2351 | } | ||
2352 | |||
2353 | void rtl8723ae_suspend(struct ieee80211_hw *hw) | ||
2354 | { | ||
2355 | } | ||
2356 | |||
2357 | void rtl8723ae_resume(struct ieee80211_hw *hw) | ||
2358 | { | ||
2359 | } | ||
2360 | |||
2361 | /* Turn on AAP (RCR:bit 0) for promicuous mode. */ | ||
2362 | void rtl8723ae_allow_all_destaddr(struct ieee80211_hw *hw, | ||
2363 | bool allow_all_da, bool write_into_reg) | ||
2364 | { | ||
2365 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2366 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
2367 | |||
2368 | if (allow_all_da) /* Set BIT0 */ | ||
2369 | rtlpci->receive_config |= RCR_AAP; | ||
2370 | else /* Clear BIT0 */ | ||
2371 | rtlpci->receive_config &= ~RCR_AAP; | ||
2372 | |||
2373 | if (write_into_reg) | ||
2374 | rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); | ||
2375 | |||
2376 | |||
2377 | RT_TRACE(rtlpriv, COMP_TURBO | COMP_INIT, DBG_LOUD, | ||
2378 | "receive_config=0x%08X, write_into_reg=%d\n", | ||
2379 | rtlpci->receive_config, write_into_reg); | ||
2380 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.h b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.h new file mode 100644 index 000000000000..6fa24f79b1d7 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.h | |||
@@ -0,0 +1,73 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 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 __RTL8723E_HW_H__ | ||
31 | #define __RTL8723E_HW_H__ | ||
32 | |||
33 | #define CHK_SVID_SMID(_val1, _val2) \ | ||
34 | ((rtlefuse->eeprom_svid == (_val1)) && \ | ||
35 | (rtlefuse->eeprom_smid == (_val2))) | ||
36 | |||
37 | void rtl8723ae_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); | ||
38 | void rtl8723ae_read_eeprom_info(struct ieee80211_hw *hw); | ||
39 | |||
40 | void rtl8723ae_interrupt_recognized(struct ieee80211_hw *hw, | ||
41 | u32 *p_inta, u32 *p_intb); | ||
42 | int rtl8723ae_hw_init(struct ieee80211_hw *hw); | ||
43 | void rtl8723ae_card_disable(struct ieee80211_hw *hw); | ||
44 | void rtl8723ae_enable_interrupt(struct ieee80211_hw *hw); | ||
45 | void rtl8723ae_disable_interrupt(struct ieee80211_hw *hw); | ||
46 | int rtl8723ae_set_network_type(struct ieee80211_hw *hw, | ||
47 | enum nl80211_iftype type); | ||
48 | void rtl8723ae_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid); | ||
49 | void rtl8723ae_set_qos(struct ieee80211_hw *hw, int aci); | ||
50 | void rtl8723ae_set_beacon_related_registers(struct ieee80211_hw *hw); | ||
51 | void rtl8723ae_set_beacon_interval(struct ieee80211_hw *hw); | ||
52 | void rtl8723ae_update_interrupt_mask(struct ieee80211_hw *hw, | ||
53 | u32 add_msr, u32 rm_msr); | ||
54 | void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); | ||
55 | void rtl8723ae_update_hal_rate_tbl(struct ieee80211_hw *hw, | ||
56 | struct ieee80211_sta *sta, u8 rssi_level); | ||
57 | void rtl8723ae_update_channel_access_setting(struct ieee80211_hw *hw); | ||
58 | bool rtl8723ae_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid); | ||
59 | void rtl8723ae_enable_hw_security_config(struct ieee80211_hw *hw); | ||
60 | void rtl8723ae_set_key(struct ieee80211_hw *hw, u32 key_index, | ||
61 | u8 *p_macaddr, bool is_group, u8 enc_algo, | ||
62 | bool is_wepkey, bool clear_all); | ||
63 | |||
64 | void rtl8723ae_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, | ||
65 | bool autoload_fail, u8 *hwinfo); | ||
66 | void rtl8723ae_bt_reg_init(struct ieee80211_hw *hw); | ||
67 | void rtl8723ae_bt_hw_init(struct ieee80211_hw *hw); | ||
68 | void rtl8723ae_suspend(struct ieee80211_hw *hw); | ||
69 | void rtl8723ae_resume(struct ieee80211_hw *hw); | ||
70 | void rtl8723ae_allow_all_destaddr(struct ieee80211_hw *hw, | ||
71 | bool allow_all_da, bool write_into_reg); | ||
72 | |||
73 | #endif | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/led.c b/drivers/net/wireless/rtlwifi/rtl8723ae/led.c new file mode 100644 index 000000000000..9c4e1d811187 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/led.c | |||
@@ -0,0 +1,151 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 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 "reg.h" | ||
33 | #include "led.h" | ||
34 | |||
35 | static void _rtl8723ae_init_led(struct ieee80211_hw *hw, | ||
36 | struct rtl_led *pled, enum rtl_led_pin ledpin) | ||
37 | { | ||
38 | pled->hw = hw; | ||
39 | pled->ledpin = ledpin; | ||
40 | pled->ledon = false; | ||
41 | } | ||
42 | |||
43 | void rtl8723ae_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) | ||
44 | { | ||
45 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
46 | u8 ledcfg; | ||
47 | |||
48 | RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, | ||
49 | "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin); | ||
50 | |||
51 | ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); | ||
52 | |||
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 processed\n"); | ||
66 | break; | ||
67 | } | ||
68 | pled->ledon = true; | ||
69 | } | ||
70 | |||
71 | void rtl8723ae_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) | ||
72 | { | ||
73 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
74 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); | ||
75 | u8 ledcfg; | ||
76 | |||
77 | RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, | ||
78 | "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin); | ||
79 | |||
80 | ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); | ||
81 | |||
82 | switch (pled->ledpin) { | ||
83 | case LED_PIN_GPIO0: | ||
84 | break; | ||
85 | case LED_PIN_LED0: | ||
86 | ledcfg &= 0xf0; | ||
87 | if (pcipriv->ledctl.led_opendrain) | ||
88 | rtl_write_byte(rtlpriv, REG_LEDCFG2, | ||
89 | (ledcfg | BIT(1) | BIT(5) | BIT(6))); | ||
90 | else | ||
91 | rtl_write_byte(rtlpriv, REG_LEDCFG2, | ||
92 | (ledcfg | BIT(3) | BIT(5) | BIT(6))); | ||
93 | break; | ||
94 | case LED_PIN_LED1: | ||
95 | ledcfg &= 0x0f; | ||
96 | rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(3))); | ||
97 | break; | ||
98 | default: | ||
99 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
100 | "switch case not processed\n"); | ||
101 | break; | ||
102 | } | ||
103 | pled->ledon = false; | ||
104 | } | ||
105 | |||
106 | void rtl8723ae_init_sw_leds(struct ieee80211_hw *hw) | ||
107 | { | ||
108 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); | ||
109 | |||
110 | _rtl8723ae_init_led(hw, &(pcipriv->ledctl.sw_led0), LED_PIN_LED0); | ||
111 | _rtl8723ae_init_led(hw, &(pcipriv->ledctl.sw_led1), LED_PIN_LED1); | ||
112 | } | ||
113 | |||
114 | static void _rtl8723ae_sw_led_control(struct ieee80211_hw *hw, | ||
115 | enum led_ctl_mode ledaction) | ||
116 | { | ||
117 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); | ||
118 | struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0); | ||
119 | |||
120 | switch (ledaction) { | ||
121 | case LED_CTL_POWER_ON: | ||
122 | case LED_CTL_LINK: | ||
123 | case LED_CTL_NO_LINK: | ||
124 | rtl8723ae_sw_led_on(hw, pLed0); | ||
125 | break; | ||
126 | case LED_CTL_POWER_OFF: | ||
127 | rtl8723ae_sw_led_off(hw, pLed0); | ||
128 | break; | ||
129 | default: | ||
130 | break; | ||
131 | } | ||
132 | } | ||
133 | |||
134 | void rtl8723ae_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction) | ||
135 | { | ||
136 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
137 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
138 | |||
139 | if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) && | ||
140 | (ledaction == LED_CTL_TX || | ||
141 | ledaction == LED_CTL_RX || | ||
142 | ledaction == LED_CTL_SITE_SURVEY || | ||
143 | ledaction == LED_CTL_LINK || | ||
144 | ledaction == LED_CTL_NO_LINK || | ||
145 | ledaction == LED_CTL_START_TO_LINK || | ||
146 | ledaction == LED_CTL_POWER_ON)) { | ||
147 | return; | ||
148 | } | ||
149 | RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d,\n", ledaction); | ||
150 | _rtl8723ae_sw_led_control(hw, ledaction); | ||
151 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/led.h b/drivers/net/wireless/rtlwifi/rtl8723ae/led.h new file mode 100644 index 000000000000..2cb88e78f62a --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/led.h | |||
@@ -0,0 +1,39 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 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 __RTL92CE_LED_H__ | ||
31 | #define __RTL92CE_LED_H__ | ||
32 | |||
33 | void rtl8723ae_init_sw_leds(struct ieee80211_hw *hw); | ||
34 | void rtl8723ae_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled); | ||
35 | void rtl8723ae_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled); | ||
36 | void rtl8723ae_led_control(struct ieee80211_hw *hw, | ||
37 | enum led_ctl_mode ledaction); | ||
38 | |||
39 | #endif | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c b/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c new file mode 100644 index 000000000000..39cc7938eedf --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c | |||
@@ -0,0 +1,2044 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 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 | /* static forward definitions */ | ||
41 | static u32 _phy_fw_rf_serial_read(struct ieee80211_hw *hw, | ||
42 | enum radio_path rfpath, u32 offset); | ||
43 | static void _phy_fw_rf_serial_write(struct ieee80211_hw *hw, | ||
44 | enum radio_path rfpath, | ||
45 | u32 offset, u32 data); | ||
46 | static u32 _phy_rf_serial_read(struct ieee80211_hw *hw, | ||
47 | enum radio_path rfpath, u32 offset); | ||
48 | static void _phy_rf_serial_write(struct ieee80211_hw *hw, | ||
49 | enum radio_path rfpath, u32 offset, u32 data); | ||
50 | static u32 _phy_calculate_bit_shift(u32 bitmask); | ||
51 | static bool _phy_bb8192c_config_parafile(struct ieee80211_hw *hw); | ||
52 | static bool _phy_cfg_mac_w_header(struct ieee80211_hw *hw); | ||
53 | static bool _phy_cfg_bb_w_header(struct ieee80211_hw *hw, u8 configtype); | ||
54 | static bool _phy_cfg_bb_w_pgheader(struct ieee80211_hw *hw, u8 configtype); | ||
55 | static void _phy_init_bb_rf_reg_def(struct ieee80211_hw *hw); | ||
56 | static bool _phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, | ||
57 | u32 cmdtableidx, u32 cmdtablesz, | ||
58 | enum swchnlcmd_id cmdid, | ||
59 | u32 para1, u32 para2, | ||
60 | u32 msdelay); | ||
61 | static bool _phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, u8 channel, | ||
62 | u8 *stage, u8 *step, u32 *delay); | ||
63 | static u8 _phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, | ||
64 | enum wireless_mode wirelessmode, | ||
65 | long power_indbm); | ||
66 | static long _phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, | ||
67 | enum wireless_mode wirelessmode, u8 txpwridx); | ||
68 | static void rtl8723ae_phy_set_io(struct ieee80211_hw *hw); | ||
69 | |||
70 | u32 rtl8723ae_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, | ||
71 | u32 bitmask) | ||
72 | { | ||
73 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
74 | u32 returnvalue, originalvalue, bitshift; | ||
75 | |||
76 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, | ||
77 | "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask); | ||
78 | originalvalue = rtl_read_dword(rtlpriv, regaddr); | ||
79 | bitshift = _phy_calculate_bit_shift(bitmask); | ||
80 | returnvalue = (originalvalue & bitmask) >> bitshift; | ||
81 | |||
82 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, | ||
83 | "BBR MASK=0x%x Addr[0x%x]=0x%x\n", bitmask, regaddr, | ||
84 | originalvalue); | ||
85 | |||
86 | return returnvalue; | ||
87 | } | ||
88 | |||
89 | void rtl8723ae_phy_set_bb_reg(struct ieee80211_hw *hw, | ||
90 | u32 regaddr, u32 bitmask, u32 data) | ||
91 | { | ||
92 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
93 | u32 originalvalue, bitshift; | ||
94 | |||
95 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, | ||
96 | "regaddr(%#x), bitmask(%#x), data(%#x)\n", regaddr, | ||
97 | bitmask, data); | ||
98 | |||
99 | if (bitmask != MASKDWORD) { | ||
100 | originalvalue = rtl_read_dword(rtlpriv, regaddr); | ||
101 | bitshift = _phy_calculate_bit_shift(bitmask); | ||
102 | data = ((originalvalue & (~bitmask)) | (data << bitshift)); | ||
103 | } | ||
104 | |||
105 | rtl_write_dword(rtlpriv, regaddr, data); | ||
106 | |||
107 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, | ||
108 | "regaddr(%#x), bitmask(%#x), data(%#x)\n", | ||
109 | regaddr, bitmask, data); | ||
110 | } | ||
111 | |||
112 | u32 rtl8723ae_phy_query_rf_reg(struct ieee80211_hw *hw, | ||
113 | enum radio_path rfpath, u32 regaddr, u32 bitmask) | ||
114 | { | ||
115 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
116 | u32 original_value, readback_value, bitshift; | ||
117 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
118 | unsigned long flags; | ||
119 | |||
120 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, | ||
121 | "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", | ||
122 | regaddr, rfpath, bitmask); | ||
123 | |||
124 | spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); | ||
125 | |||
126 | if (rtlphy->rf_mode != RF_OP_BY_FW) | ||
127 | original_value = _phy_rf_serial_read(hw, rfpath, regaddr); | ||
128 | else | ||
129 | original_value = _phy_fw_rf_serial_read(hw, rfpath, regaddr); | ||
130 | |||
131 | bitshift = _phy_calculate_bit_shift(bitmask); | ||
132 | readback_value = (original_value & bitmask) >> bitshift; | ||
133 | |||
134 | spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); | ||
135 | |||
136 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, | ||
137 | "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", | ||
138 | regaddr, rfpath, bitmask, original_value); | ||
139 | |||
140 | return readback_value; | ||
141 | } | ||
142 | |||
143 | void rtl8723ae_phy_set_rf_reg(struct ieee80211_hw *hw, | ||
144 | enum radio_path rfpath, | ||
145 | u32 regaddr, u32 bitmask, u32 data) | ||
146 | { | ||
147 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
148 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
149 | u32 original_value, bitshift; | ||
150 | unsigned long flags; | ||
151 | |||
152 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, | ||
153 | "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", | ||
154 | regaddr, bitmask, data, rfpath); | ||
155 | |||
156 | spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); | ||
157 | |||
158 | if (rtlphy->rf_mode != RF_OP_BY_FW) { | ||
159 | if (bitmask != RFREG_OFFSET_MASK) { | ||
160 | original_value = _phy_rf_serial_read(hw, rfpath, | ||
161 | regaddr); | ||
162 | bitshift = _phy_calculate_bit_shift(bitmask); | ||
163 | data = ((original_value & (~bitmask)) | | ||
164 | (data << bitshift)); | ||
165 | } | ||
166 | |||
167 | _phy_rf_serial_write(hw, rfpath, regaddr, data); | ||
168 | } else { | ||
169 | if (bitmask != RFREG_OFFSET_MASK) { | ||
170 | original_value = _phy_fw_rf_serial_read(hw, rfpath, | ||
171 | regaddr); | ||
172 | bitshift = _phy_calculate_bit_shift(bitmask); | ||
173 | data = ((original_value & (~bitmask)) | | ||
174 | (data << bitshift)); | ||
175 | } | ||
176 | _phy_fw_rf_serial_write(hw, rfpath, regaddr, data); | ||
177 | } | ||
178 | |||
179 | spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); | ||
180 | |||
181 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, | ||
182 | "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", | ||
183 | regaddr, bitmask, data, rfpath); | ||
184 | } | ||
185 | |||
186 | static u32 _phy_fw_rf_serial_read(struct ieee80211_hw *hw, | ||
187 | enum radio_path rfpath, u32 offset) | ||
188 | { | ||
189 | RT_ASSERT(false, "deprecated!\n"); | ||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | static void _phy_fw_rf_serial_write(struct ieee80211_hw *hw, | ||
194 | enum radio_path rfpath, | ||
195 | u32 offset, u32 data) | ||
196 | { | ||
197 | RT_ASSERT(false, "deprecated!\n"); | ||
198 | } | ||
199 | |||
200 | static u32 _phy_rf_serial_read(struct ieee80211_hw *hw, | ||
201 | enum radio_path rfpath, u32 offset) | ||
202 | { | ||
203 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
204 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
205 | struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; | ||
206 | u32 newoffset; | ||
207 | u32 tmplong, tmplong2; | ||
208 | u8 rfpi_enable = 0; | ||
209 | u32 retvalue; | ||
210 | |||
211 | offset &= 0x3f; | ||
212 | newoffset = offset; | ||
213 | if (RT_CANNOT_IO(hw)) { | ||
214 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "return all one\n"); | ||
215 | return 0xFFFFFFFF; | ||
216 | } | ||
217 | tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD); | ||
218 | if (rfpath == RF90_PATH_A) | ||
219 | tmplong2 = tmplong; | ||
220 | else | ||
221 | tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD); | ||
222 | tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) | | ||
223 | (newoffset << 23) | BLSSIREADEDGE; | ||
224 | rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, | ||
225 | tmplong & (~BLSSIREADEDGE)); | ||
226 | mdelay(1); | ||
227 | rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2); | ||
228 | mdelay(1); | ||
229 | rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, | ||
230 | tmplong | BLSSIREADEDGE); | ||
231 | mdelay(1); | ||
232 | if (rfpath == RF90_PATH_A) | ||
233 | rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, | ||
234 | BIT(8)); | ||
235 | else if (rfpath == RF90_PATH_B) | ||
236 | rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, | ||
237 | BIT(8)); | ||
238 | if (rfpi_enable) | ||
239 | retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi, | ||
240 | BLSSIREADBACKDATA); | ||
241 | else | ||
242 | retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb, | ||
243 | BLSSIREADBACKDATA); | ||
244 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n", | ||
245 | rfpath, pphyreg->rf_rb, retvalue); | ||
246 | return retvalue; | ||
247 | } | ||
248 | |||
249 | static void _phy_rf_serial_write(struct ieee80211_hw *hw, | ||
250 | enum radio_path rfpath, u32 offset, u32 data) | ||
251 | { | ||
252 | u32 data_and_addr; | ||
253 | u32 newoffset; | ||
254 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
255 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
256 | struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; | ||
257 | |||
258 | if (RT_CANNOT_IO(hw)) { | ||
259 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "stop\n"); | ||
260 | return; | ||
261 | } | ||
262 | offset &= 0x3f; | ||
263 | newoffset = offset; | ||
264 | data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; | ||
265 | rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); | ||
266 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n", | ||
267 | rfpath, pphyreg->rf3wire_offset, data_and_addr); | ||
268 | } | ||
269 | |||
270 | static u32 _phy_calculate_bit_shift(u32 bitmask) | ||
271 | { | ||
272 | u32 i; | ||
273 | |||
274 | for (i = 0; i <= 31; i++) { | ||
275 | if (((bitmask >> i) & 0x1) == 1) | ||
276 | break; | ||
277 | } | ||
278 | return i; | ||
279 | } | ||
280 | |||
281 | static void _rtl8723ae_phy_bb_config_1t(struct ieee80211_hw *hw) | ||
282 | { | ||
283 | rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2); | ||
284 | rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022); | ||
285 | rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45); | ||
286 | rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23); | ||
287 | rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1); | ||
288 | rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2); | ||
289 | rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2); | ||
290 | rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2); | ||
291 | rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2); | ||
292 | rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2); | ||
293 | } | ||
294 | |||
295 | bool rtl8723ae_phy_mac_config(struct ieee80211_hw *hw) | ||
296 | { | ||
297 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
298 | bool rtstatus = _phy_cfg_mac_w_header(hw); | ||
299 | rtl_write_byte(rtlpriv, 0x04CA, 0x0A); | ||
300 | return rtstatus; | ||
301 | } | ||
302 | |||
303 | bool rtl8723ae_phy_bb_config(struct ieee80211_hw *hw) | ||
304 | { | ||
305 | bool rtstatus = true; | ||
306 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
307 | u8 tmpu1b; | ||
308 | u8 reg_hwparafile = 1; | ||
309 | |||
310 | _phy_init_bb_rf_reg_def(hw); | ||
311 | |||
312 | /* 1. 0x28[1] = 1 */ | ||
313 | tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_PLL_CTRL); | ||
314 | udelay(2); | ||
315 | rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, (tmpu1b|BIT(1))); | ||
316 | udelay(2); | ||
317 | /* 2. 0x29[7:0] = 0xFF */ | ||
318 | rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL+1, 0xff); | ||
319 | udelay(2); | ||
320 | |||
321 | /* 3. 0x02[1:0] = 2b'11 */ | ||
322 | tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN); | ||
323 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, (tmpu1b | | ||
324 | FEN_BB_GLB_RSTn | FEN_BBRSTB)); | ||
325 | |||
326 | /* 4. 0x25[6] = 0 */ | ||
327 | tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+1); | ||
328 | rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+1, (tmpu1b&(~BIT(6)))); | ||
329 | |||
330 | /* 5. 0x24[20] = 0 Advised by SD3 Alex Wang. 2011.02.09. */ | ||
331 | tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+2); | ||
332 | rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+2, (tmpu1b&(~BIT(4)))); | ||
333 | |||
334 | /* 6. 0x1f[7:0] = 0x07 */ | ||
335 | rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x07); | ||
336 | |||
337 | if (reg_hwparafile == 1) | ||
338 | rtstatus = _phy_bb8192c_config_parafile(hw); | ||
339 | return rtstatus; | ||
340 | } | ||
341 | |||
342 | bool rtl8723ae_phy_rf_config(struct ieee80211_hw *hw) | ||
343 | { | ||
344 | return rtl8723ae_phy_rf6052_config(hw); | ||
345 | } | ||
346 | |||
347 | static bool _phy_bb8192c_config_parafile(struct ieee80211_hw *hw) | ||
348 | { | ||
349 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
350 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
351 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
352 | bool rtstatus; | ||
353 | |||
354 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "==>\n"); | ||
355 | rtstatus = _phy_cfg_bb_w_header(hw, BASEBAND_CONFIG_PHY_REG); | ||
356 | if (rtstatus != true) { | ||
357 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!"); | ||
358 | return false; | ||
359 | } | ||
360 | |||
361 | if (rtlphy->rf_type == RF_1T2R) { | ||
362 | _rtl8723ae_phy_bb_config_1t(hw); | ||
363 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n"); | ||
364 | } | ||
365 | if (rtlefuse->autoload_failflag == false) { | ||
366 | rtlphy->pwrgroup_cnt = 0; | ||
367 | rtstatus = _phy_cfg_bb_w_pgheader(hw, BASEBAND_CONFIG_PHY_REG); | ||
368 | } | ||
369 | if (rtstatus != true) { | ||
370 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!"); | ||
371 | return false; | ||
372 | } | ||
373 | rtstatus = _phy_cfg_bb_w_header(hw, BASEBAND_CONFIG_AGC_TAB); | ||
374 | if (rtstatus != true) { | ||
375 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n"); | ||
376 | return false; | ||
377 | } | ||
378 | rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw, | ||
379 | RFPGA0_XA_HSSIPARAMETER2, 0x200)); | ||
380 | return true; | ||
381 | } | ||
382 | |||
383 | static bool _phy_cfg_mac_w_header(struct ieee80211_hw *hw) | ||
384 | { | ||
385 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
386 | u32 i; | ||
387 | u32 arraylength; | ||
388 | u32 *ptrarray; | ||
389 | |||
390 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl723MACPHY_Array\n"); | ||
391 | arraylength = RTL8723E_MACARRAYLENGTH; | ||
392 | ptrarray = RTL8723EMAC_ARRAY; | ||
393 | |||
394 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
395 | "Img:RTL8192CEMAC_2T_ARRAY\n"); | ||
396 | for (i = 0; i < arraylength; i = i + 2) | ||
397 | rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]); | ||
398 | return true; | ||
399 | } | ||
400 | |||
401 | static bool _phy_cfg_bb_w_header(struct ieee80211_hw *hw, u8 configtype) | ||
402 | { | ||
403 | int i; | ||
404 | u32 *phy_regarray_table; | ||
405 | u32 *agctab_array_table; | ||
406 | u16 phy_reg_arraylen, agctab_arraylen; | ||
407 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
408 | |||
409 | agctab_arraylen = RTL8723E_AGCTAB_1TARRAYLENGTH; | ||
410 | agctab_array_table = RTL8723EAGCTAB_1TARRAY; | ||
411 | phy_reg_arraylen = RTL8723E_PHY_REG_1TARRAY_LENGTH; | ||
412 | phy_regarray_table = RTL8723EPHY_REG_1TARRAY; | ||
413 | if (configtype == BASEBAND_CONFIG_PHY_REG) { | ||
414 | for (i = 0; i < phy_reg_arraylen; i = i + 2) { | ||
415 | if (phy_regarray_table[i] == 0xfe) | ||
416 | mdelay(50); | ||
417 | else if (phy_regarray_table[i] == 0xfd) | ||
418 | mdelay(5); | ||
419 | else if (phy_regarray_table[i] == 0xfc) | ||
420 | mdelay(1); | ||
421 | else if (phy_regarray_table[i] == 0xfb) | ||
422 | udelay(50); | ||
423 | else if (phy_regarray_table[i] == 0xfa) | ||
424 | udelay(5); | ||
425 | else if (phy_regarray_table[i] == 0xf9) | ||
426 | udelay(1); | ||
427 | rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD, | ||
428 | phy_regarray_table[i + 1]); | ||
429 | udelay(1); | ||
430 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
431 | "The phy_regarray_table[0] is %x" | ||
432 | " Rtl819XPHY_REGArray[1] is %x\n", | ||
433 | phy_regarray_table[i], | ||
434 | phy_regarray_table[i + 1]); | ||
435 | } | ||
436 | } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { | ||
437 | for (i = 0; i < agctab_arraylen; i = i + 2) { | ||
438 | rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD, | ||
439 | agctab_array_table[i + 1]); | ||
440 | udelay(1); | ||
441 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
442 | "The agctab_array_table[0] is " | ||
443 | "%x Rtl819XPHY_REGArray[1] is %x\n", | ||
444 | agctab_array_table[i], | ||
445 | agctab_array_table[i + 1]); | ||
446 | } | ||
447 | } | ||
448 | return true; | ||
449 | } | ||
450 | |||
451 | static void _st_pwrIdx_dfrate_off(struct ieee80211_hw *hw, u32 regaddr, | ||
452 | u32 bitmask, u32 data) | ||
453 | { | ||
454 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
455 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
456 | |||
457 | switch (regaddr) { | ||
458 | case RTXAGC_A_RATE18_06: | ||
459 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][0] = data; | ||
460 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
461 | "MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n", | ||
462 | rtlphy->pwrgroup_cnt, | ||
463 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][0]); | ||
464 | break; | ||
465 | case RTXAGC_A_RATE54_24: | ||
466 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][1] = data; | ||
467 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
468 | "MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n", | ||
469 | rtlphy->pwrgroup_cnt, | ||
470 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][1]); | ||
471 | break; | ||
472 | case RTXAGC_A_CCK1_MCS32: | ||
473 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][6] = data; | ||
474 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
475 | "MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n", | ||
476 | rtlphy->pwrgroup_cnt, | ||
477 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][6]); | ||
478 | break; | ||
479 | case RTXAGC_B_CCK11_A_CCK2_11: | ||
480 | if (bitmask == 0xffffff00) { | ||
481 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][7] = data; | ||
482 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
483 | "MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n", | ||
484 | rtlphy->pwrgroup_cnt, | ||
485 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][7]); | ||
486 | } | ||
487 | if (bitmask == 0x000000ff) { | ||
488 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][15] = data; | ||
489 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
490 | "MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n", | ||
491 | rtlphy->pwrgroup_cnt, | ||
492 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][15]); | ||
493 | } | ||
494 | break; | ||
495 | case RTXAGC_A_MCS03_MCS00: | ||
496 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][2] = data; | ||
497 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
498 | "MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n", | ||
499 | rtlphy->pwrgroup_cnt, | ||
500 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][2]); | ||
501 | break; | ||
502 | case RTXAGC_A_MCS07_MCS04: | ||
503 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][3] = data; | ||
504 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
505 | "MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n", | ||
506 | rtlphy->pwrgroup_cnt, | ||
507 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][3]); | ||
508 | break; | ||
509 | case RTXAGC_A_MCS11_MCS08: | ||
510 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][4] = data; | ||
511 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
512 | "MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n", | ||
513 | rtlphy->pwrgroup_cnt, | ||
514 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][4]); | ||
515 | break; | ||
516 | case RTXAGC_A_MCS15_MCS12: | ||
517 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][5] = data; | ||
518 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
519 | "MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n", | ||
520 | rtlphy->pwrgroup_cnt, | ||
521 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][5]); | ||
522 | break; | ||
523 | case RTXAGC_B_RATE18_06: | ||
524 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][8] = data; | ||
525 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
526 | "MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n", | ||
527 | rtlphy->pwrgroup_cnt, | ||
528 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][8]); | ||
529 | break; | ||
530 | case RTXAGC_B_RATE54_24: | ||
531 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][9] = data; | ||
532 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
533 | "MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n", | ||
534 | rtlphy->pwrgroup_cnt, | ||
535 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][9]); | ||
536 | break; | ||
537 | case RTXAGC_B_CCK1_55_MCS32: | ||
538 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][14] = data; | ||
539 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
540 | "MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n", | ||
541 | rtlphy->pwrgroup_cnt, | ||
542 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][14]); | ||
543 | break; | ||
544 | case RTXAGC_B_MCS03_MCS00: | ||
545 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][10] = data; | ||
546 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
547 | "MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n", | ||
548 | rtlphy->pwrgroup_cnt, | ||
549 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][10]); | ||
550 | break; | ||
551 | case RTXAGC_B_MCS07_MCS04: | ||
552 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][11] = data; | ||
553 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
554 | "MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n", | ||
555 | rtlphy->pwrgroup_cnt, | ||
556 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][11]); | ||
557 | break; | ||
558 | case RTXAGC_B_MCS11_MCS08: | ||
559 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][12] = data; | ||
560 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
561 | "MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n", | ||
562 | rtlphy->pwrgroup_cnt, | ||
563 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][12]); | ||
564 | break; | ||
565 | case RTXAGC_B_MCS15_MCS12: | ||
566 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][13] = data; | ||
567 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
568 | "MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n", | ||
569 | rtlphy->pwrgroup_cnt, | ||
570 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][13]); | ||
571 | rtlphy->pwrgroup_cnt++; | ||
572 | break; | ||
573 | } | ||
574 | } | ||
575 | |||
576 | static bool _phy_cfg_bb_w_pgheader(struct ieee80211_hw *hw, u8 configtype) | ||
577 | { | ||
578 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
579 | int i; | ||
580 | u32 *phy_regarray_table_pg; | ||
581 | u16 phy_regarray_pg_len; | ||
582 | |||
583 | phy_regarray_pg_len = RTL8723E_PHY_REG_ARRAY_PGLENGTH; | ||
584 | phy_regarray_table_pg = RTL8723EPHY_REG_ARRAY_PG; | ||
585 | |||
586 | if (configtype == BASEBAND_CONFIG_PHY_REG) { | ||
587 | for (i = 0; i < phy_regarray_pg_len; i = i + 3) { | ||
588 | if (phy_regarray_table_pg[i] == 0xfe) | ||
589 | mdelay(50); | ||
590 | else if (phy_regarray_table_pg[i] == 0xfd) | ||
591 | mdelay(5); | ||
592 | else if (phy_regarray_table_pg[i] == 0xfc) | ||
593 | mdelay(1); | ||
594 | else if (phy_regarray_table_pg[i] == 0xfb) | ||
595 | udelay(50); | ||
596 | else if (phy_regarray_table_pg[i] == 0xfa) | ||
597 | udelay(5); | ||
598 | else if (phy_regarray_table_pg[i] == 0xf9) | ||
599 | udelay(1); | ||
600 | |||
601 | _st_pwrIdx_dfrate_off(hw, phy_regarray_table_pg[i], | ||
602 | phy_regarray_table_pg[i + 1], | ||
603 | phy_regarray_table_pg[i + 2]); | ||
604 | } | ||
605 | } else { | ||
606 | RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, | ||
607 | "configtype != BaseBand_Config_PHY_REG\n"); | ||
608 | } | ||
609 | return true; | ||
610 | } | ||
611 | |||
612 | bool rtl8723ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, | ||
613 | enum radio_path rfpath) | ||
614 | { | ||
615 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
616 | int i; | ||
617 | bool rtstatus = true; | ||
618 | u32 *radioa_array_table; | ||
619 | u32 *radiob_array_table; | ||
620 | u16 radioa_arraylen, radiob_arraylen; | ||
621 | |||
622 | radioa_arraylen = Rtl8723ERADIOA_1TARRAYLENGTH; | ||
623 | radioa_array_table = RTL8723E_RADIOA_1TARRAY; | ||
624 | radiob_arraylen = RTL8723E_RADIOB_1TARRAYLENGTH; | ||
625 | radiob_array_table = RTL8723E_RADIOB_1TARRAY; | ||
626 | |||
627 | rtstatus = true; | ||
628 | |||
629 | switch (rfpath) { | ||
630 | case RF90_PATH_A: | ||
631 | for (i = 0; i < radioa_arraylen; i = i + 2) { | ||
632 | if (radioa_array_table[i] == 0xfe) | ||
633 | mdelay(50); | ||
634 | else if (radioa_array_table[i] == 0xfd) | ||
635 | mdelay(5); | ||
636 | else if (radioa_array_table[i] == 0xfc) | ||
637 | mdelay(1); | ||
638 | else if (radioa_array_table[i] == 0xfb) | ||
639 | udelay(50); | ||
640 | else if (radioa_array_table[i] == 0xfa) | ||
641 | udelay(5); | ||
642 | else if (radioa_array_table[i] == 0xf9) | ||
643 | udelay(1); | ||
644 | else { | ||
645 | rtl_set_rfreg(hw, rfpath, radioa_array_table[i], | ||
646 | RFREG_OFFSET_MASK, | ||
647 | radioa_array_table[i + 1]); | ||
648 | udelay(1); | ||
649 | } | ||
650 | } | ||
651 | break; | ||
652 | case RF90_PATH_B: | ||
653 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
654 | "switch case not process\n"); | ||
655 | break; | ||
656 | case RF90_PATH_C: | ||
657 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
658 | "switch case not process\n"); | ||
659 | break; | ||
660 | case RF90_PATH_D: | ||
661 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
662 | "switch case not process\n"); | ||
663 | break; | ||
664 | } | ||
665 | return true; | ||
666 | } | ||
667 | |||
668 | void rtl8723ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) | ||
669 | { | ||
670 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
671 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
672 | |||
673 | rtlphy->default_initialgain[0] = | ||
674 | (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); | ||
675 | rtlphy->default_initialgain[1] = | ||
676 | (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); | ||
677 | rtlphy->default_initialgain[2] = | ||
678 | (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0); | ||
679 | rtlphy->default_initialgain[3] = | ||
680 | (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); | ||
681 | |||
682 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
683 | "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n", | ||
684 | rtlphy->default_initialgain[0], | ||
685 | rtlphy->default_initialgain[1], | ||
686 | rtlphy->default_initialgain[2], | ||
687 | rtlphy->default_initialgain[3]); | ||
688 | |||
689 | rtlphy->framesync = (u8) rtl_get_bbreg(hw, | ||
690 | ROFDM0_RXDETECTOR3, MASKBYTE0); | ||
691 | rtlphy->framesync_c34 = rtl_get_bbreg(hw, | ||
692 | ROFDM0_RXDETECTOR2, MASKDWORD); | ||
693 | |||
694 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
695 | "Default framesync (0x%x) = 0x%x\n", | ||
696 | ROFDM0_RXDETECTOR3, rtlphy->framesync); | ||
697 | } | ||
698 | |||
699 | static void _phy_init_bb_rf_reg_def(struct ieee80211_hw *hw) | ||
700 | { | ||
701 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
702 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
703 | |||
704 | rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; | ||
705 | rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; | ||
706 | rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW; | ||
707 | rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW; | ||
708 | |||
709 | rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB; | ||
710 | rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB; | ||
711 | rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB; | ||
712 | rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB; | ||
713 | |||
714 | rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; | ||
715 | rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; | ||
716 | |||
717 | rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; | ||
718 | rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; | ||
719 | |||
720 | rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = | ||
721 | RFPGA0_XA_LSSIPARAMETER; | ||
722 | rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = | ||
723 | RFPGA0_XB_LSSIPARAMETER; | ||
724 | |||
725 | rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = rFPGA0_XAB_RFPARAMETER; | ||
726 | rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = rFPGA0_XAB_RFPARAMETER; | ||
727 | rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = rFPGA0_XCD_RFPARAMETER; | ||
728 | rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = rFPGA0_XCD_RFPARAMETER; | ||
729 | |||
730 | rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE; | ||
731 | rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE; | ||
732 | rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE; | ||
733 | rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE; | ||
734 | |||
735 | rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1; | ||
736 | rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1; | ||
737 | |||
738 | rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; | ||
739 | rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; | ||
740 | |||
741 | rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; | ||
742 | rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; | ||
743 | rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; | ||
744 | rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; | ||
745 | |||
746 | rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; | ||
747 | rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1; | ||
748 | rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1; | ||
749 | rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1; | ||
750 | |||
751 | rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2; | ||
752 | rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2; | ||
753 | rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2; | ||
754 | rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; | ||
755 | |||
756 | rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE; | ||
757 | rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE; | ||
758 | rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBANLANCE; | ||
759 | rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE; | ||
760 | |||
761 | rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; | ||
762 | rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE; | ||
763 | rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE; | ||
764 | rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; | ||
765 | |||
766 | rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE; | ||
767 | rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE; | ||
768 | rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE; | ||
769 | rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE; | ||
770 | |||
771 | rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; | ||
772 | rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE; | ||
773 | rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE; | ||
774 | rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE; | ||
775 | |||
776 | rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK; | ||
777 | rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK; | ||
778 | rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK; | ||
779 | rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK; | ||
780 | |||
781 | rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVEA_HSPI_READBACK; | ||
782 | rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVEB_HSPI_READBACK; | ||
783 | } | ||
784 | |||
785 | void rtl8723ae_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel) | ||
786 | { | ||
787 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
788 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
789 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
790 | u8 txpwr_level; | ||
791 | long txpwr_dbm; | ||
792 | |||
793 | txpwr_level = rtlphy->cur_cck_txpwridx; | ||
794 | txpwr_dbm = _phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B, txpwr_level); | ||
795 | txpwr_level = rtlphy->cur_ofdm24g_txpwridx + | ||
796 | rtlefuse->legacy_ht_txpowerdiff; | ||
797 | if (_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) > txpwr_dbm) | ||
798 | txpwr_dbm = _phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, | ||
799 | txpwr_level); | ||
800 | txpwr_level = rtlphy->cur_ofdm24g_txpwridx; | ||
801 | if (_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, txpwr_level) > | ||
802 | txpwr_dbm) | ||
803 | txpwr_dbm = _phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, | ||
804 | txpwr_level); | ||
805 | *powerlevel = txpwr_dbm; | ||
806 | } | ||
807 | |||
808 | static void _rtl8723ae_get_txpower_index(struct ieee80211_hw *hw, u8 channel, | ||
809 | u8 *cckpowerlevel, u8 *ofdmpowerlevel) | ||
810 | { | ||
811 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
812 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
813 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
814 | u8 index = (channel - 1); | ||
815 | |||
816 | cckpowerlevel[RF90_PATH_A] = | ||
817 | rtlefuse->txpwrlevel_cck[RF90_PATH_A][index]; | ||
818 | cckpowerlevel[RF90_PATH_B] = | ||
819 | rtlefuse->txpwrlevel_cck[RF90_PATH_B][index]; | ||
820 | if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) { | ||
821 | ofdmpowerlevel[RF90_PATH_A] = | ||
822 | rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index]; | ||
823 | ofdmpowerlevel[RF90_PATH_B] = | ||
824 | rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index]; | ||
825 | } else if (get_rf_type(rtlphy) == RF_2T2R) { | ||
826 | ofdmpowerlevel[RF90_PATH_A] = | ||
827 | rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index]; | ||
828 | ofdmpowerlevel[RF90_PATH_B] = | ||
829 | rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index]; | ||
830 | } | ||
831 | } | ||
832 | |||
833 | static void _rtl8723ae_ccxpower_index_check(struct ieee80211_hw *hw, | ||
834 | u8 channel, u8 *cckpowerlevel, | ||
835 | u8 *ofdmpowerlevel) | ||
836 | { | ||
837 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
838 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
839 | |||
840 | rtlphy->cur_cck_txpwridx = cckpowerlevel[0]; | ||
841 | rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0]; | ||
842 | } | ||
843 | |||
844 | void rtl8723ae_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) | ||
845 | { | ||
846 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
847 | u8 cckpowerlevel[2], ofdmpowerlevel[2]; | ||
848 | |||
849 | if (rtlefuse->txpwr_fromeprom == false) | ||
850 | return; | ||
851 | _rtl8723ae_get_txpower_index(hw, channel, &cckpowerlevel[0], | ||
852 | &ofdmpowerlevel[0]); | ||
853 | _rtl8723ae_ccxpower_index_check(hw, channel, &cckpowerlevel[0], | ||
854 | &ofdmpowerlevel[0]); | ||
855 | rtl8723ae_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]); | ||
856 | rtl8723ae_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel); | ||
857 | } | ||
858 | |||
859 | bool rtl8723ae_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm) | ||
860 | { | ||
861 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
862 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
863 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
864 | u8 idx; | ||
865 | u8 rf_path; | ||
866 | u8 ccktxpwridx = _phy_dbm_to_txpwr_Idx(hw, WIRELESS_MODE_B, | ||
867 | power_indbm); | ||
868 | u8 ofdmtxpwridx = _phy_dbm_to_txpwr_Idx(hw, WIRELESS_MODE_N_24G, | ||
869 | power_indbm); | ||
870 | if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0) | ||
871 | ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff; | ||
872 | else | ||
873 | ofdmtxpwridx = 0; | ||
874 | RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE, | ||
875 | "%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n", | ||
876 | power_indbm, ccktxpwridx, ofdmtxpwridx); | ||
877 | for (idx = 0; idx < 14; idx++) { | ||
878 | for (rf_path = 0; rf_path < 2; rf_path++) { | ||
879 | rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx; | ||
880 | rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] = | ||
881 | ofdmtxpwridx; | ||
882 | rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] = | ||
883 | ofdmtxpwridx; | ||
884 | } | ||
885 | } | ||
886 | rtl8723ae_phy_set_txpower_level(hw, rtlphy->current_channel); | ||
887 | return true; | ||
888 | } | ||
889 | |||
890 | static u8 _phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, | ||
891 | enum wireless_mode wirelessmode, | ||
892 | long power_indbm) | ||
893 | { | ||
894 | u8 txpwridx; | ||
895 | long offset; | ||
896 | |||
897 | switch (wirelessmode) { | ||
898 | case WIRELESS_MODE_B: | ||
899 | offset = -7; | ||
900 | break; | ||
901 | case WIRELESS_MODE_G: | ||
902 | case WIRELESS_MODE_N_24G: | ||
903 | offset = -8; | ||
904 | break; | ||
905 | default: | ||
906 | offset = -8; | ||
907 | break; | ||
908 | } | ||
909 | |||
910 | if ((power_indbm - offset) > 0) | ||
911 | txpwridx = (u8) ((power_indbm - offset) * 2); | ||
912 | else | ||
913 | txpwridx = 0; | ||
914 | |||
915 | if (txpwridx > MAX_TXPWR_IDX_NMODE_92S) | ||
916 | txpwridx = MAX_TXPWR_IDX_NMODE_92S; | ||
917 | |||
918 | return txpwridx; | ||
919 | } | ||
920 | |||
921 | static long _phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, | ||
922 | enum wireless_mode wirelessmode, u8 txpwridx) | ||
923 | { | ||
924 | long offset; | ||
925 | long pwrout_dbm; | ||
926 | |||
927 | switch (wirelessmode) { | ||
928 | case WIRELESS_MODE_B: | ||
929 | offset = -7; | ||
930 | break; | ||
931 | case WIRELESS_MODE_G: | ||
932 | case WIRELESS_MODE_N_24G: | ||
933 | offset = -8; | ||
934 | break; | ||
935 | default: | ||
936 | offset = -8; | ||
937 | break; | ||
938 | } | ||
939 | pwrout_dbm = txpwridx / 2 + offset; | ||
940 | return pwrout_dbm; | ||
941 | } | ||
942 | |||
943 | void rtl8723ae_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) | ||
944 | { | ||
945 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
946 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
947 | enum io_type iotype; | ||
948 | |||
949 | if (!is_hal_stop(rtlhal)) { | ||
950 | switch (operation) { | ||
951 | case SCAN_OPT_BACKUP: | ||
952 | iotype = IO_CMD_PAUSE_DM_BY_SCAN; | ||
953 | rtlpriv->cfg->ops->set_hw_reg(hw, | ||
954 | HW_VAR_IO_CMD, | ||
955 | (u8 *)&iotype); | ||
956 | |||
957 | break; | ||
958 | case SCAN_OPT_RESTORE: | ||
959 | iotype = IO_CMD_RESUME_DM_BY_SCAN; | ||
960 | rtlpriv->cfg->ops->set_hw_reg(hw, | ||
961 | HW_VAR_IO_CMD, | ||
962 | (u8 *)&iotype); | ||
963 | break; | ||
964 | default: | ||
965 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
966 | "Unknown Scan Backup operation.\n"); | ||
967 | break; | ||
968 | } | ||
969 | } | ||
970 | } | ||
971 | |||
972 | void rtl8723ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw) | ||
973 | { | ||
974 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
975 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
976 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
977 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
978 | u8 reg_bw_opmode; | ||
979 | u8 reg_prsr_rsc; | ||
980 | |||
981 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, | ||
982 | "Switch to %s bandwidth\n", | ||
983 | rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? | ||
984 | "20MHz" : "40MHz"); | ||
985 | |||
986 | if (is_hal_stop(rtlhal)) { | ||
987 | rtlphy->set_bwmode_inprogress = false; | ||
988 | return; | ||
989 | } | ||
990 | |||
991 | reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); | ||
992 | reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); | ||
993 | |||
994 | switch (rtlphy->current_chan_bw) { | ||
995 | case HT_CHANNEL_WIDTH_20: | ||
996 | reg_bw_opmode |= BW_OPMODE_20MHZ; | ||
997 | rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); | ||
998 | break; | ||
999 | case HT_CHANNEL_WIDTH_20_40: | ||
1000 | reg_bw_opmode &= ~BW_OPMODE_20MHZ; | ||
1001 | rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); | ||
1002 | reg_prsr_rsc = | ||
1003 | (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5); | ||
1004 | rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc); | ||
1005 | break; | ||
1006 | default: | ||
1007 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
1008 | "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); | ||
1009 | break; | ||
1010 | } | ||
1011 | |||
1012 | switch (rtlphy->current_chan_bw) { | ||
1013 | case HT_CHANNEL_WIDTH_20: | ||
1014 | rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); | ||
1015 | rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); | ||
1016 | rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); | ||
1017 | break; | ||
1018 | case HT_CHANNEL_WIDTH_20_40: | ||
1019 | rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); | ||
1020 | rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); | ||
1021 | |||
1022 | rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND, | ||
1023 | (mac->cur_40_prime_sc >> 1)); | ||
1024 | rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc); | ||
1025 | rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0); | ||
1026 | |||
1027 | rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)), | ||
1028 | (mac->cur_40_prime_sc == | ||
1029 | HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); | ||
1030 | break; | ||
1031 | default: | ||
1032 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
1033 | "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); | ||
1034 | break; | ||
1035 | } | ||
1036 | rtl8723ae_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); | ||
1037 | rtlphy->set_bwmode_inprogress = false; | ||
1038 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); | ||
1039 | } | ||
1040 | |||
1041 | void rtl8723ae_phy_set_bw_mode(struct ieee80211_hw *hw, | ||
1042 | enum nl80211_channel_type ch_type) | ||
1043 | { | ||
1044 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1045 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1046 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1047 | u8 tmp_bw = rtlphy->current_chan_bw; | ||
1048 | |||
1049 | if (rtlphy->set_bwmode_inprogress) | ||
1050 | return; | ||
1051 | rtlphy->set_bwmode_inprogress = true; | ||
1052 | if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { | ||
1053 | rtl8723ae_phy_set_bw_mode_callback(hw); | ||
1054 | } else { | ||
1055 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | ||
1056 | "FALSE driver sleep or unload\n"); | ||
1057 | rtlphy->set_bwmode_inprogress = false; | ||
1058 | rtlphy->current_chan_bw = tmp_bw; | ||
1059 | } | ||
1060 | } | ||
1061 | |||
1062 | void rtl8723ae_phy_sw_chnl_callback(struct ieee80211_hw *hw) | ||
1063 | { | ||
1064 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1065 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1066 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1067 | u32 delay; | ||
1068 | |||
1069 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, | ||
1070 | "switch to channel%d\n", rtlphy->current_channel); | ||
1071 | if (is_hal_stop(rtlhal)) | ||
1072 | return; | ||
1073 | do { | ||
1074 | if (!rtlphy->sw_chnl_inprogress) | ||
1075 | break; | ||
1076 | if (!_phy_sw_chnl_step_by_step | ||
1077 | (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage, | ||
1078 | &rtlphy->sw_chnl_step, &delay)) { | ||
1079 | if (delay > 0) | ||
1080 | mdelay(delay); | ||
1081 | else | ||
1082 | continue; | ||
1083 | } else { | ||
1084 | rtlphy->sw_chnl_inprogress = false; | ||
1085 | } | ||
1086 | break; | ||
1087 | } while (true); | ||
1088 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); | ||
1089 | } | ||
1090 | |||
1091 | u8 rtl8723ae_phy_sw_chnl(struct ieee80211_hw *hw) | ||
1092 | { | ||
1093 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1094 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1095 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1096 | |||
1097 | if (rtlphy->sw_chnl_inprogress) | ||
1098 | return 0; | ||
1099 | if (rtlphy->set_bwmode_inprogress) | ||
1100 | return 0; | ||
1101 | RT_ASSERT((rtlphy->current_channel <= 14), | ||
1102 | "WIRELESS_MODE_G but channel>14"); | ||
1103 | rtlphy->sw_chnl_inprogress = true; | ||
1104 | rtlphy->sw_chnl_stage = 0; | ||
1105 | rtlphy->sw_chnl_step = 0; | ||
1106 | if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { | ||
1107 | rtl8723ae_phy_sw_chnl_callback(hw); | ||
1108 | RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, | ||
1109 | "sw_chnl_inprogress false schdule workitem\n"); | ||
1110 | rtlphy->sw_chnl_inprogress = false; | ||
1111 | } else { | ||
1112 | RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, | ||
1113 | "sw_chnl_inprogress false driver sleep or unload\n"); | ||
1114 | rtlphy->sw_chnl_inprogress = false; | ||
1115 | } | ||
1116 | return 1; | ||
1117 | } | ||
1118 | |||
1119 | static void _rtl8723ae_phy_sw_rf_seting(struct ieee80211_hw *hw, u8 channel) | ||
1120 | { | ||
1121 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1122 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1123 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1124 | |||
1125 | if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) { | ||
1126 | if (channel == 6 && rtlphy->current_chan_bw == | ||
1127 | HT_CHANNEL_WIDTH_20) | ||
1128 | rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, | ||
1129 | 0x00255); | ||
1130 | else{ | ||
1131 | u32 backupRF0x1A = (u32)rtl_get_rfreg(hw, RF90_PATH_A, | ||
1132 | RF_RX_G1, RFREG_OFFSET_MASK); | ||
1133 | rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, | ||
1134 | backupRF0x1A); | ||
1135 | } | ||
1136 | } | ||
1137 | } | ||
1138 | |||
1139 | static bool _phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, u8 channel, | ||
1140 | u8 *stage, u8 *step, u32 *delay) | ||
1141 | { | ||
1142 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1143 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1144 | struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; | ||
1145 | u32 precommoncmdcnt; | ||
1146 | struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; | ||
1147 | u32 postcommoncmdcnt; | ||
1148 | struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT]; | ||
1149 | u32 rfdependcmdcnt; | ||
1150 | struct swchnlcmd *currentcmd = NULL; | ||
1151 | u8 rfpath; | ||
1152 | u8 num_total_rfpath = rtlphy->num_total_rfpath; | ||
1153 | |||
1154 | precommoncmdcnt = 0; | ||
1155 | _phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, | ||
1156 | MAX_PRECMD_CNT, CMDID_SET_TXPOWEROWER_LEVEL, | ||
1157 | 0, 0, 0); | ||
1158 | _phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, | ||
1159 | MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); | ||
1160 | postcommoncmdcnt = 0; | ||
1161 | |||
1162 | _phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, | ||
1163 | MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0); | ||
1164 | rfdependcmdcnt = 0; | ||
1165 | |||
1166 | RT_ASSERT((channel >= 1 && channel <= 14), | ||
1167 | "illegal channel for Zebra: %d\n", channel); | ||
1168 | |||
1169 | _phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, | ||
1170 | MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, | ||
1171 | RF_CHNLBW, channel, 10); | ||
1172 | |||
1173 | _phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, | ||
1174 | MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, 0); | ||
1175 | |||
1176 | do { | ||
1177 | switch (*stage) { | ||
1178 | case 0: | ||
1179 | currentcmd = &precommoncmd[*step]; | ||
1180 | break; | ||
1181 | case 1: | ||
1182 | currentcmd = &rfdependcmd[*step]; | ||
1183 | break; | ||
1184 | case 2: | ||
1185 | currentcmd = &postcommoncmd[*step]; | ||
1186 | break; | ||
1187 | } | ||
1188 | |||
1189 | if (currentcmd->cmdid == CMDID_END) { | ||
1190 | if ((*stage) == 2) { | ||
1191 | return true; | ||
1192 | } else { | ||
1193 | (*stage)++; | ||
1194 | (*step) = 0; | ||
1195 | continue; | ||
1196 | } | ||
1197 | } | ||
1198 | |||
1199 | switch (currentcmd->cmdid) { | ||
1200 | case CMDID_SET_TXPOWEROWER_LEVEL: | ||
1201 | rtl8723ae_phy_set_txpower_level(hw, channel); | ||
1202 | break; | ||
1203 | case CMDID_WRITEPORT_ULONG: | ||
1204 | rtl_write_dword(rtlpriv, currentcmd->para1, | ||
1205 | currentcmd->para2); | ||
1206 | break; | ||
1207 | case CMDID_WRITEPORT_USHORT: | ||
1208 | rtl_write_word(rtlpriv, currentcmd->para1, | ||
1209 | (u16) currentcmd->para2); | ||
1210 | break; | ||
1211 | case CMDID_WRITEPORT_UCHAR: | ||
1212 | rtl_write_byte(rtlpriv, currentcmd->para1, | ||
1213 | (u8) currentcmd->para2); | ||
1214 | break; | ||
1215 | case CMDID_RF_WRITEREG: | ||
1216 | for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { | ||
1217 | rtlphy->rfreg_chnlval[rfpath] = | ||
1218 | ((rtlphy->rfreg_chnlval[rfpath] & | ||
1219 | 0xfffffc00) | currentcmd->para2); | ||
1220 | |||
1221 | rtl_set_rfreg(hw, (enum radio_path)rfpath, | ||
1222 | currentcmd->para1, | ||
1223 | RFREG_OFFSET_MASK, | ||
1224 | rtlphy->rfreg_chnlval[rfpath]); | ||
1225 | } | ||
1226 | _rtl8723ae_phy_sw_rf_seting(hw, channel); | ||
1227 | break; | ||
1228 | default: | ||
1229 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
1230 | "switch case not process\n"); | ||
1231 | break; | ||
1232 | } | ||
1233 | |||
1234 | break; | ||
1235 | } while (true); | ||
1236 | |||
1237 | (*delay) = currentcmd->msdelay; | ||
1238 | (*step)++; | ||
1239 | return false; | ||
1240 | } | ||
1241 | |||
1242 | static bool _phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, | ||
1243 | u32 cmdtableidx, u32 cmdtablesz, | ||
1244 | enum swchnlcmd_id cmdid, u32 para1, | ||
1245 | u32 para2, u32 msdelay) | ||
1246 | { | ||
1247 | struct swchnlcmd *pcmd; | ||
1248 | |||
1249 | if (cmdtable == NULL) { | ||
1250 | RT_ASSERT(false, "cmdtable cannot be NULL.\n"); | ||
1251 | return false; | ||
1252 | } | ||
1253 | |||
1254 | if (cmdtableidx >= cmdtablesz) | ||
1255 | return false; | ||
1256 | |||
1257 | pcmd = cmdtable + cmdtableidx; | ||
1258 | pcmd->cmdid = cmdid; | ||
1259 | pcmd->para1 = para1; | ||
1260 | pcmd->para2 = para2; | ||
1261 | pcmd->msdelay = msdelay; | ||
1262 | return true; | ||
1263 | } | ||
1264 | |||
1265 | static u8 _rtl8723ae_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb) | ||
1266 | { | ||
1267 | u32 reg_eac, reg_e94, reg_e9c, reg_ea4; | ||
1268 | u8 result = 0x00; | ||
1269 | |||
1270 | rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f); | ||
1271 | rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f); | ||
1272 | rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102); | ||
1273 | rtl_set_bbreg(hw, 0xe3c, MASKDWORD, | ||
1274 | config_pathb ? 0x28160202 : 0x28160502); | ||
1275 | |||
1276 | if (config_pathb) { | ||
1277 | rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22); | ||
1278 | rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22); | ||
1279 | rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102); | ||
1280 | rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202); | ||
1281 | } | ||
1282 | |||
1283 | rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1); | ||
1284 | rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000); | ||
1285 | rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000); | ||
1286 | |||
1287 | mdelay(IQK_DELAY_TIME); | ||
1288 | |||
1289 | reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); | ||
1290 | reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD); | ||
1291 | reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD); | ||
1292 | reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD); | ||
1293 | |||
1294 | if (!(reg_eac & BIT(28)) && | ||
1295 | (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && | ||
1296 | (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) | ||
1297 | result |= 0x01; | ||
1298 | else | ||
1299 | return result; | ||
1300 | |||
1301 | if (!(reg_eac & BIT(27)) && | ||
1302 | (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) && | ||
1303 | (((reg_eac & 0x03FF0000) >> 16) != 0x36)) | ||
1304 | result |= 0x02; | ||
1305 | return result; | ||
1306 | } | ||
1307 | |||
1308 | static u8 _rtl8723ae_phy_path_b_iqk(struct ieee80211_hw *hw) | ||
1309 | { | ||
1310 | u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc; | ||
1311 | u8 result = 0x00; | ||
1312 | |||
1313 | rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002); | ||
1314 | rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000); | ||
1315 | mdelay(IQK_DELAY_TIME); | ||
1316 | reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); | ||
1317 | reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD); | ||
1318 | reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD); | ||
1319 | reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD); | ||
1320 | reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD); | ||
1321 | |||
1322 | if (!(reg_eac & BIT(31)) && | ||
1323 | (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) && | ||
1324 | (((reg_ebc & 0x03FF0000) >> 16) != 0x42)) | ||
1325 | result |= 0x01; | ||
1326 | else | ||
1327 | return result; | ||
1328 | if (!(reg_eac & BIT(30)) && | ||
1329 | (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) && | ||
1330 | (((reg_ecc & 0x03FF0000) >> 16) != 0x36)) | ||
1331 | result |= 0x02; | ||
1332 | return result; | ||
1333 | } | ||
1334 | |||
1335 | static void phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw, bool iqk_ok, | ||
1336 | long result[][8], u8 final_candidate, | ||
1337 | bool btxonly) | ||
1338 | { | ||
1339 | u32 oldval_0, x, tx0_a, reg; | ||
1340 | long y, tx0_c; | ||
1341 | |||
1342 | if (final_candidate == 0xFF) { | ||
1343 | return; | ||
1344 | } else if (iqk_ok) { | ||
1345 | oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, | ||
1346 | MASKDWORD) >> 22) & 0x3FF; | ||
1347 | x = result[final_candidate][0]; | ||
1348 | if ((x & 0x00000200) != 0) | ||
1349 | x = x | 0xFFFFFC00; | ||
1350 | tx0_a = (x * oldval_0) >> 8; | ||
1351 | rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a); | ||
1352 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31), | ||
1353 | ((x * oldval_0 >> 7) & 0x1)); | ||
1354 | y = result[final_candidate][1]; | ||
1355 | if ((y & 0x00000200) != 0) | ||
1356 | y = y | 0xFFFFFC00; | ||
1357 | tx0_c = (y * oldval_0) >> 8; | ||
1358 | rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000, | ||
1359 | ((tx0_c & 0x3C0) >> 6)); | ||
1360 | rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000, | ||
1361 | (tx0_c & 0x3F)); | ||
1362 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29), | ||
1363 | ((y * oldval_0 >> 7) & 0x1)); | ||
1364 | if (btxonly) | ||
1365 | return; | ||
1366 | reg = result[final_candidate][2]; | ||
1367 | rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg); | ||
1368 | reg = result[final_candidate][3] & 0x3F; | ||
1369 | rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg); | ||
1370 | reg = (result[final_candidate][3] >> 6) & 0xF; | ||
1371 | rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); | ||
1372 | } | ||
1373 | } | ||
1374 | |||
1375 | static void phy_save_adda_regs(struct ieee80211_hw *hw, | ||
1376 | u32 *addareg, u32 *addabackup, | ||
1377 | u32 registernum) | ||
1378 | { | ||
1379 | u32 i; | ||
1380 | |||
1381 | for (i = 0; i < registernum; i++) | ||
1382 | addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD); | ||
1383 | } | ||
1384 | |||
1385 | static void phy_save_mac_regs(struct ieee80211_hw *hw, u32 *macreg, | ||
1386 | u32 *macbackup) | ||
1387 | { | ||
1388 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1389 | u32 i; | ||
1390 | |||
1391 | for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) | ||
1392 | macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]); | ||
1393 | macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]); | ||
1394 | } | ||
1395 | |||
1396 | static void phy_reload_adda_regs(struct ieee80211_hw *hw, u32 *addareg, | ||
1397 | u32 *addabackup, u32 regiesternum) | ||
1398 | { | ||
1399 | u32 i; | ||
1400 | |||
1401 | for (i = 0; i < regiesternum; i++) | ||
1402 | rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]); | ||
1403 | } | ||
1404 | |||
1405 | static void phy_reload_mac_regs(struct ieee80211_hw *hw, u32 *macreg, | ||
1406 | u32 *macbackup) | ||
1407 | { | ||
1408 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1409 | u32 i; | ||
1410 | |||
1411 | for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) | ||
1412 | rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]); | ||
1413 | rtl_write_dword(rtlpriv, macreg[i], macbackup[i]); | ||
1414 | } | ||
1415 | |||
1416 | static void _rtl8723ae_phy_path_adda_on(struct ieee80211_hw *hw, | ||
1417 | u32 *addareg, bool is_patha_on, | ||
1418 | bool is2t) | ||
1419 | { | ||
1420 | u32 pathOn; | ||
1421 | u32 i; | ||
1422 | |||
1423 | pathOn = is_patha_on ? 0x04db25a4 : 0x0b1b25a4; | ||
1424 | if (false == is2t) { | ||
1425 | pathOn = 0x0bdb25a0; | ||
1426 | rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0); | ||
1427 | } else { | ||
1428 | rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathOn); | ||
1429 | } | ||
1430 | |||
1431 | for (i = 1; i < IQK_ADDA_REG_NUM; i++) | ||
1432 | rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathOn); | ||
1433 | } | ||
1434 | |||
1435 | static void _rtl8723ae_phy_mac_setting_calibration(struct ieee80211_hw *hw, | ||
1436 | u32 *macreg, u32 *macbackup) | ||
1437 | { | ||
1438 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1439 | u32 i = 0; | ||
1440 | |||
1441 | rtl_write_byte(rtlpriv, macreg[i], 0x3F); | ||
1442 | |||
1443 | for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) | ||
1444 | rtl_write_byte(rtlpriv, macreg[i], | ||
1445 | (u8) (macbackup[i] & (~BIT(3)))); | ||
1446 | rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5)))); | ||
1447 | } | ||
1448 | |||
1449 | static void _rtl8723ae_phy_path_a_standby(struct ieee80211_hw *hw) | ||
1450 | { | ||
1451 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0); | ||
1452 | rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); | ||
1453 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); | ||
1454 | } | ||
1455 | |||
1456 | static void _rtl8723ae_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode) | ||
1457 | { | ||
1458 | u32 mode; | ||
1459 | |||
1460 | mode = pi_mode ? 0x01000100 : 0x01000000; | ||
1461 | rtl_set_bbreg(hw, 0x820, MASKDWORD, mode); | ||
1462 | rtl_set_bbreg(hw, 0x828, MASKDWORD, mode); | ||
1463 | } | ||
1464 | |||
1465 | static bool phy_simularity_comp(struct ieee80211_hw *hw, long result[][8], | ||
1466 | u8 c1, u8 c2) | ||
1467 | { | ||
1468 | u32 i, j, diff, simularity_bitmap, bound; | ||
1469 | |||
1470 | u8 final_candidate[2] = { 0xFF, 0xFF }; | ||
1471 | bool bresult = true; | ||
1472 | |||
1473 | bound = 4; | ||
1474 | |||
1475 | simularity_bitmap = 0; | ||
1476 | |||
1477 | for (i = 0; i < bound; i++) { | ||
1478 | diff = (result[c1][i] > result[c2][i]) ? | ||
1479 | (result[c1][i] - result[c2][i]) : | ||
1480 | (result[c2][i] - result[c1][i]); | ||
1481 | |||
1482 | if (diff > MAX_TOLERANCE) { | ||
1483 | if ((i == 2 || i == 6) && !simularity_bitmap) { | ||
1484 | if (result[c1][i] + result[c1][i + 1] == 0) | ||
1485 | final_candidate[(i / 4)] = c2; | ||
1486 | else if (result[c2][i] + result[c2][i + 1] == 0) | ||
1487 | final_candidate[(i / 4)] = c1; | ||
1488 | else | ||
1489 | simularity_bitmap = simularity_bitmap | | ||
1490 | (1 << i); | ||
1491 | } else | ||
1492 | simularity_bitmap = | ||
1493 | simularity_bitmap | (1 << i); | ||
1494 | } | ||
1495 | } | ||
1496 | |||
1497 | if (simularity_bitmap == 0) { | ||
1498 | for (i = 0; i < (bound / 4); i++) { | ||
1499 | if (final_candidate[i] != 0xFF) { | ||
1500 | for (j = i * 4; j < (i + 1) * 4 - 2; j++) | ||
1501 | result[3][j] = | ||
1502 | result[final_candidate[i]][j]; | ||
1503 | bresult = false; | ||
1504 | } | ||
1505 | } | ||
1506 | return bresult; | ||
1507 | } else if (!(simularity_bitmap & 0x0F)) { | ||
1508 | for (i = 0; i < 4; i++) | ||
1509 | result[3][i] = result[c1][i]; | ||
1510 | return false; | ||
1511 | } else { | ||
1512 | return false; | ||
1513 | } | ||
1514 | |||
1515 | } | ||
1516 | |||
1517 | static void _rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, | ||
1518 | long result[][8], u8 t, bool is2t) | ||
1519 | { | ||
1520 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1521 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1522 | u32 i; | ||
1523 | u8 patha_ok, pathb_ok; | ||
1524 | u32 adda_reg[IQK_ADDA_REG_NUM] = { | ||
1525 | 0x85c, 0xe6c, 0xe70, 0xe74, | ||
1526 | 0xe78, 0xe7c, 0xe80, 0xe84, | ||
1527 | 0xe88, 0xe8c, 0xed0, 0xed4, | ||
1528 | 0xed8, 0xedc, 0xee0, 0xeec | ||
1529 | }; | ||
1530 | u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { | ||
1531 | 0x522, 0x550, 0x551, 0x040 | ||
1532 | }; | ||
1533 | const u32 retrycount = 2; | ||
1534 | u32 bbvalue; | ||
1535 | |||
1536 | if (t == 0) { | ||
1537 | bbvalue = rtl_get_bbreg(hw, 0x800, MASKDWORD); | ||
1538 | |||
1539 | phy_save_adda_regs(hw, adda_reg, rtlphy->adda_backup, 16); | ||
1540 | phy_save_mac_regs(hw, iqk_mac_reg, rtlphy->iqk_mac_backup); | ||
1541 | } | ||
1542 | _rtl8723ae_phy_path_adda_on(hw, adda_reg, true, is2t); | ||
1543 | if (t == 0) { | ||
1544 | rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw, | ||
1545 | RFPGA0_XA_HSSIPARAMETER1, | ||
1546 | BIT(8)); | ||
1547 | } | ||
1548 | |||
1549 | if (!rtlphy->rfpi_enable) | ||
1550 | _rtl8723ae_phy_pi_mode_switch(hw, true); | ||
1551 | if (t == 0) { | ||
1552 | rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD); | ||
1553 | rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD); | ||
1554 | rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD); | ||
1555 | } | ||
1556 | rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600); | ||
1557 | rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4); | ||
1558 | rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000); | ||
1559 | if (is2t) { | ||
1560 | rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); | ||
1561 | rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000); | ||
1562 | } | ||
1563 | _rtl8723ae_phy_mac_setting_calibration(hw, iqk_mac_reg, | ||
1564 | rtlphy->iqk_mac_backup); | ||
1565 | rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000); | ||
1566 | if (is2t) | ||
1567 | rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000); | ||
1568 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); | ||
1569 | rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00); | ||
1570 | rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800); | ||
1571 | for (i = 0; i < retrycount; i++) { | ||
1572 | patha_ok = _rtl8723ae_phy_path_a_iqk(hw, is2t); | ||
1573 | if (patha_ok == 0x03) { | ||
1574 | result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) & | ||
1575 | 0x3FF0000) >> 16; | ||
1576 | result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & | ||
1577 | 0x3FF0000) >> 16; | ||
1578 | result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) & | ||
1579 | 0x3FF0000) >> 16; | ||
1580 | result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) & | ||
1581 | 0x3FF0000) >> 16; | ||
1582 | break; | ||
1583 | } else if (i == (retrycount - 1) && patha_ok == 0x01) | ||
1584 | |||
1585 | result[t][0] = (rtl_get_bbreg(hw, 0xe94, | ||
1586 | MASKDWORD) & 0x3FF0000) >> 16; | ||
1587 | result[t][1] = | ||
1588 | (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16; | ||
1589 | |||
1590 | } | ||
1591 | |||
1592 | if (is2t) { | ||
1593 | _rtl8723ae_phy_path_a_standby(hw); | ||
1594 | _rtl8723ae_phy_path_adda_on(hw, adda_reg, false, is2t); | ||
1595 | for (i = 0; i < retrycount; i++) { | ||
1596 | pathb_ok = _rtl8723ae_phy_path_b_iqk(hw); | ||
1597 | if (pathb_ok == 0x03) { | ||
1598 | result[t][4] = | ||
1599 | (rtl_get_bbreg(hw, 0xeb4, MASKDWORD) & | ||
1600 | 0x3FF0000) >> 16; | ||
1601 | result[t][5] = | ||
1602 | (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & | ||
1603 | 0x3FF0000) >> 16; | ||
1604 | result[t][6] = | ||
1605 | (rtl_get_bbreg(hw, 0xec4, MASKDWORD) & | ||
1606 | 0x3FF0000) >> 16; | ||
1607 | result[t][7] = | ||
1608 | (rtl_get_bbreg(hw, 0xecc, MASKDWORD) & | ||
1609 | 0x3FF0000) >> 16; | ||
1610 | break; | ||
1611 | } else if (i == (retrycount - 1) && pathb_ok == 0x01) { | ||
1612 | result[t][4] = | ||
1613 | (rtl_get_bbreg(hw, 0xeb4, MASKDWORD) & | ||
1614 | 0x3FF0000) >> 16; | ||
1615 | } | ||
1616 | result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & | ||
1617 | 0x3FF0000) >> 16; | ||
1618 | } | ||
1619 | } | ||
1620 | rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04); | ||
1621 | rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874); | ||
1622 | rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08); | ||
1623 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0); | ||
1624 | rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3); | ||
1625 | if (is2t) | ||
1626 | rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3); | ||
1627 | if (t != 0) { | ||
1628 | if (!rtlphy->rfpi_enable) | ||
1629 | _rtl8723ae_phy_pi_mode_switch(hw, false); | ||
1630 | phy_reload_adda_regs(hw, adda_reg, rtlphy->adda_backup, 16); | ||
1631 | phy_reload_mac_regs(hw, iqk_mac_reg, rtlphy->iqk_mac_backup); | ||
1632 | } | ||
1633 | } | ||
1634 | |||
1635 | static void _rtl8723ae_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) | ||
1636 | { | ||
1637 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1638 | u8 tmpreg; | ||
1639 | u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal; | ||
1640 | |||
1641 | tmpreg = rtl_read_byte(rtlpriv, 0xd03); | ||
1642 | |||
1643 | if ((tmpreg & 0x70) != 0) | ||
1644 | rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F); | ||
1645 | else | ||
1646 | rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); | ||
1647 | |||
1648 | if ((tmpreg & 0x70) != 0) { | ||
1649 | rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS); | ||
1650 | |||
1651 | if (is2t) | ||
1652 | rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00, | ||
1653 | MASK12BITS); | ||
1654 | |||
1655 | rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, | ||
1656 | (rf_a_mode & 0x8FFFF) | 0x10000); | ||
1657 | |||
1658 | if (is2t) | ||
1659 | rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, | ||
1660 | (rf_b_mode & 0x8FFFF) | 0x10000); | ||
1661 | } | ||
1662 | lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS); | ||
1663 | |||
1664 | rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000); | ||
1665 | |||
1666 | mdelay(100); | ||
1667 | |||
1668 | if ((tmpreg & 0x70) != 0) { | ||
1669 | rtl_write_byte(rtlpriv, 0xd03, tmpreg); | ||
1670 | rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode); | ||
1671 | |||
1672 | if (is2t) | ||
1673 | rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, | ||
1674 | rf_b_mode); | ||
1675 | } else { | ||
1676 | rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); | ||
1677 | } | ||
1678 | } | ||
1679 | |||
1680 | static void _rtl8723ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, | ||
1681 | bool bmain, bool is2t) | ||
1682 | { | ||
1683 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1684 | |||
1685 | if (is_hal_stop(rtlhal)) { | ||
1686 | rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01); | ||
1687 | rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01); | ||
1688 | } | ||
1689 | if (is2t) { | ||
1690 | if (bmain) | ||
1691 | rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, | ||
1692 | BIT(5) | BIT(6), 0x1); | ||
1693 | else | ||
1694 | rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, | ||
1695 | BIT(5) | BIT(6), 0x2); | ||
1696 | } else { | ||
1697 | if (bmain) | ||
1698 | rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2); | ||
1699 | else | ||
1700 | rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1); | ||
1701 | |||
1702 | } | ||
1703 | } | ||
1704 | |||
1705 | #undef IQK_ADDA_REG_NUM | ||
1706 | #undef IQK_DELAY_TIME | ||
1707 | |||
1708 | void rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery) | ||
1709 | { | ||
1710 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1711 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1712 | long result[4][8]; | ||
1713 | u8 i, final_candidate; | ||
1714 | bool patha_ok, pathb_ok; | ||
1715 | long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4, | ||
1716 | reg_ecc, reg_tmp = 0; | ||
1717 | bool is12simular, is13simular, is23simular; | ||
1718 | bool start_conttx = false, singletone = false; | ||
1719 | u32 iqk_bb_reg[10] = { | ||
1720 | ROFDM0_XARXIQIMBALANCE, | ||
1721 | ROFDM0_XBRXIQIMBALANCE, | ||
1722 | ROFDM0_ECCATHRESHOLD, | ||
1723 | ROFDM0_AGCRSSITABLE, | ||
1724 | ROFDM0_XATXIQIMBALANCE, | ||
1725 | ROFDM0_XBTXIQIMBALANCE, | ||
1726 | ROFDM0_XCTXIQIMBALANCE, | ||
1727 | ROFDM0_XCTXAFE, | ||
1728 | ROFDM0_XDTXAFE, | ||
1729 | ROFDM0_RXIQEXTANTA | ||
1730 | }; | ||
1731 | |||
1732 | if (recovery) { | ||
1733 | phy_reload_adda_regs(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 10); | ||
1734 | return; | ||
1735 | } | ||
1736 | if (start_conttx || singletone) | ||
1737 | return; | ||
1738 | for (i = 0; i < 8; i++) { | ||
1739 | result[0][i] = 0; | ||
1740 | result[1][i] = 0; | ||
1741 | result[2][i] = 0; | ||
1742 | result[3][i] = 0; | ||
1743 | } | ||
1744 | final_candidate = 0xff; | ||
1745 | patha_ok = false; | ||
1746 | pathb_ok = false; | ||
1747 | is12simular = false; | ||
1748 | is23simular = false; | ||
1749 | is13simular = false; | ||
1750 | for (i = 0; i < 3; i++) { | ||
1751 | _rtl8723ae_phy_iq_calibrate(hw, result, i, false); | ||
1752 | if (i == 1) { | ||
1753 | is12simular = phy_simularity_comp(hw, result, 0, 1); | ||
1754 | if (is12simular) { | ||
1755 | final_candidate = 0; | ||
1756 | break; | ||
1757 | } | ||
1758 | } | ||
1759 | if (i == 2) { | ||
1760 | is13simular = phy_simularity_comp(hw, result, 0, 2); | ||
1761 | if (is13simular) { | ||
1762 | final_candidate = 0; | ||
1763 | break; | ||
1764 | } | ||
1765 | is23simular = phy_simularity_comp(hw, result, 1, 2); | ||
1766 | if (is23simular) { | ||
1767 | final_candidate = 1; | ||
1768 | } else { | ||
1769 | for (i = 0; i < 8; i++) | ||
1770 | reg_tmp += result[3][i]; | ||
1771 | |||
1772 | if (reg_tmp != 0) | ||
1773 | final_candidate = 3; | ||
1774 | else | ||
1775 | final_candidate = 0xFF; | ||
1776 | } | ||
1777 | } | ||
1778 | } | ||
1779 | for (i = 0; i < 4; i++) { | ||
1780 | reg_e94 = result[i][0]; | ||
1781 | reg_e9c = result[i][1]; | ||
1782 | reg_ea4 = result[i][2]; | ||
1783 | reg_eac = result[i][3]; | ||
1784 | reg_eb4 = result[i][4]; | ||
1785 | reg_ebc = result[i][5]; | ||
1786 | reg_ec4 = result[i][6]; | ||
1787 | reg_ecc = result[i][7]; | ||
1788 | } | ||
1789 | if (final_candidate != 0xff) { | ||
1790 | rtlphy->reg_e94 = reg_e94 = result[final_candidate][0]; | ||
1791 | rtlphy->reg_e9c = reg_e9c = result[final_candidate][1]; | ||
1792 | reg_ea4 = result[final_candidate][2]; | ||
1793 | reg_eac = result[final_candidate][3]; | ||
1794 | rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4]; | ||
1795 | rtlphy->reg_ebc = reg_ebc = result[final_candidate][5]; | ||
1796 | reg_ec4 = result[final_candidate][6]; | ||
1797 | reg_ecc = result[final_candidate][7]; | ||
1798 | patha_ok = pathb_ok = true; | ||
1799 | } else { | ||
1800 | rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; | ||
1801 | rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0; | ||
1802 | } | ||
1803 | if (reg_e94 != 0) /*&&(reg_ea4 != 0) */ | ||
1804 | phy_path_a_fill_iqk_matrix(hw, patha_ok, result, | ||
1805 | final_candidate, (reg_ea4 == 0)); | ||
1806 | phy_save_adda_regs(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 10); | ||
1807 | } | ||
1808 | |||
1809 | void rtl8723ae_phy_lc_calibrate(struct ieee80211_hw *hw) | ||
1810 | { | ||
1811 | bool start_conttx = false, singletone = false; | ||
1812 | |||
1813 | if (start_conttx || singletone) | ||
1814 | return; | ||
1815 | _rtl8723ae_phy_lc_calibrate(hw, false); | ||
1816 | } | ||
1817 | |||
1818 | void rtl8723ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain) | ||
1819 | { | ||
1820 | _rtl8723ae_phy_set_rfpath_switch(hw, bmain, false); | ||
1821 | } | ||
1822 | |||
1823 | bool rtl8723ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) | ||
1824 | { | ||
1825 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1826 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1827 | bool postprocessing = false; | ||
1828 | |||
1829 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, | ||
1830 | "-->IO Cmd(%#x), set_io_inprogress(%d)\n", | ||
1831 | iotype, rtlphy->set_io_inprogress); | ||
1832 | do { | ||
1833 | switch (iotype) { | ||
1834 | case IO_CMD_RESUME_DM_BY_SCAN: | ||
1835 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, | ||
1836 | "[IO CMD] Resume DM after scan.\n"); | ||
1837 | postprocessing = true; | ||
1838 | break; | ||
1839 | case IO_CMD_PAUSE_DM_BY_SCAN: | ||
1840 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, | ||
1841 | "[IO CMD] Pause DM before scan.\n"); | ||
1842 | postprocessing = true; | ||
1843 | break; | ||
1844 | default: | ||
1845 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
1846 | "switch case not process\n"); | ||
1847 | break; | ||
1848 | } | ||
1849 | } while (false); | ||
1850 | if (postprocessing && !rtlphy->set_io_inprogress) { | ||
1851 | rtlphy->set_io_inprogress = true; | ||
1852 | rtlphy->current_io_type = iotype; | ||
1853 | } else { | ||
1854 | return false; | ||
1855 | } | ||
1856 | rtl8723ae_phy_set_io(hw); | ||
1857 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<--IO Type(%#x)\n", iotype); | ||
1858 | return true; | ||
1859 | } | ||
1860 | |||
1861 | static void rtl8723ae_phy_set_io(struct ieee80211_hw *hw) | ||
1862 | { | ||
1863 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1864 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1865 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; | ||
1866 | |||
1867 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, | ||
1868 | "--->Cmd(%#x), set_io_inprogress(%d)\n", | ||
1869 | rtlphy->current_io_type, rtlphy->set_io_inprogress); | ||
1870 | switch (rtlphy->current_io_type) { | ||
1871 | case IO_CMD_RESUME_DM_BY_SCAN: | ||
1872 | dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1; | ||
1873 | rtl8723ae_dm_write_dig(hw); | ||
1874 | rtl8723ae_phy_set_txpower_level(hw, rtlphy->current_channel); | ||
1875 | break; | ||
1876 | case IO_CMD_PAUSE_DM_BY_SCAN: | ||
1877 | rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue; | ||
1878 | dm_digtable->cur_igvalue = 0x17; | ||
1879 | rtl8723ae_dm_write_dig(hw); | ||
1880 | break; | ||
1881 | default: | ||
1882 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
1883 | "switch case not process\n"); | ||
1884 | break; | ||
1885 | } | ||
1886 | rtlphy->set_io_inprogress = false; | ||
1887 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, | ||
1888 | "<---(%#x)\n", rtlphy->current_io_type); | ||
1889 | } | ||
1890 | |||
1891 | static void rtl8723ae_phy_set_rf_on(struct ieee80211_hw *hw) | ||
1892 | { | ||
1893 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1894 | |||
1895 | rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); | ||
1896 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); | ||
1897 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); | ||
1898 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); | ||
1899 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); | ||
1900 | rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); | ||
1901 | } | ||
1902 | |||
1903 | static void _rtl8723ae_phy_set_rf_sleep(struct ieee80211_hw *hw) | ||
1904 | { | ||
1905 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1906 | u32 u4b_tmp; | ||
1907 | u8 delay = 5; | ||
1908 | |||
1909 | rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); | ||
1910 | rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); | ||
1911 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); | ||
1912 | u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); | ||
1913 | while (u4b_tmp != 0 && delay > 0) { | ||
1914 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0); | ||
1915 | rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); | ||
1916 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); | ||
1917 | u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); | ||
1918 | delay--; | ||
1919 | } | ||
1920 | if (delay == 0) { | ||
1921 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); | ||
1922 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); | ||
1923 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); | ||
1924 | rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); | ||
1925 | RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, | ||
1926 | "Switch RF timeout !!!.\n"); | ||
1927 | return; | ||
1928 | } | ||
1929 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); | ||
1930 | rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); | ||
1931 | } | ||
1932 | |||
1933 | static bool _rtl8723ae_phy_set_rf_power_state(struct ieee80211_hw *hw, | ||
1934 | enum rf_pwrstate rfpwr_state) | ||
1935 | { | ||
1936 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1937 | struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); | ||
1938 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
1939 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
1940 | struct rtl8192_tx_ring *ring = NULL; | ||
1941 | bool bresult = true; | ||
1942 | u8 i, queue_id; | ||
1943 | |||
1944 | switch (rfpwr_state) { | ||
1945 | case ERFON: | ||
1946 | if ((ppsc->rfpwr_state == ERFOFF) && | ||
1947 | RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { | ||
1948 | bool rtstatus; | ||
1949 | u32 InitializeCount = 0; | ||
1950 | do { | ||
1951 | InitializeCount++; | ||
1952 | RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, | ||
1953 | "IPS Set eRf nic enable\n"); | ||
1954 | rtstatus = rtl_ps_enable_nic(hw); | ||
1955 | } while ((rtstatus != true) && (InitializeCount < 10)); | ||
1956 | RT_CLEAR_PS_LEVEL(ppsc, | ||
1957 | RT_RF_OFF_LEVL_HALT_NIC); | ||
1958 | } else { | ||
1959 | RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, | ||
1960 | "Set ERFON sleeped:%d ms\n", | ||
1961 | jiffies_to_msecs(jiffies - | ||
1962 | ppsc->last_sleep_jiffies)); | ||
1963 | ppsc->last_awake_jiffies = jiffies; | ||
1964 | rtl8723ae_phy_set_rf_on(hw); | ||
1965 | } | ||
1966 | if (mac->link_state == MAC80211_LINKED) { | ||
1967 | rtlpriv->cfg->ops->led_control(hw, | ||
1968 | LED_CTL_LINK); | ||
1969 | } else { | ||
1970 | rtlpriv->cfg->ops->led_control(hw, | ||
1971 | LED_CTL_NO_LINK); | ||
1972 | } | ||
1973 | break; | ||
1974 | case ERFOFF: | ||
1975 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { | ||
1976 | RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, | ||
1977 | "IPS Set eRf nic disable\n"); | ||
1978 | rtl_ps_disable_nic(hw); | ||
1979 | RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); | ||
1980 | } else { | ||
1981 | if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) { | ||
1982 | rtlpriv->cfg->ops->led_control(hw, | ||
1983 | LED_CTL_NO_LINK); | ||
1984 | } else { | ||
1985 | rtlpriv->cfg->ops->led_control(hw, | ||
1986 | LED_CTL_POWER_OFF); | ||
1987 | } | ||
1988 | } | ||
1989 | break; | ||
1990 | case ERFSLEEP: | ||
1991 | if (ppsc->rfpwr_state == ERFOFF) | ||
1992 | break; | ||
1993 | for (queue_id = 0, i = 0; | ||
1994 | queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { | ||
1995 | ring = &pcipriv->dev.tx_ring[queue_id]; | ||
1996 | if (skb_queue_len(&ring->queue) == 0) { | ||
1997 | queue_id++; | ||
1998 | continue; | ||
1999 | } else { | ||
2000 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | ||
2001 | "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", | ||
2002 | (i + 1), queue_id, | ||
2003 | skb_queue_len(&ring->queue)); | ||
2004 | |||
2005 | udelay(10); | ||
2006 | i++; | ||
2007 | } | ||
2008 | if (i >= MAX_DOZE_WAITING_TIMES_9x) { | ||
2009 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | ||
2010 | "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", | ||
2011 | MAX_DOZE_WAITING_TIMES_9x, | ||
2012 | queue_id, | ||
2013 | skb_queue_len(&ring->queue)); | ||
2014 | break; | ||
2015 | } | ||
2016 | } | ||
2017 | RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, | ||
2018 | "Set ERFSLEEP awaked:%d ms\n", | ||
2019 | jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies)); | ||
2020 | ppsc->last_sleep_jiffies = jiffies; | ||
2021 | _rtl8723ae_phy_set_rf_sleep(hw); | ||
2022 | break; | ||
2023 | default: | ||
2024 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
2025 | "switch case not processed\n"); | ||
2026 | bresult = false; | ||
2027 | break; | ||
2028 | } | ||
2029 | if (bresult) | ||
2030 | ppsc->rfpwr_state = rfpwr_state; | ||
2031 | return bresult; | ||
2032 | } | ||
2033 | |||
2034 | bool rtl8723ae_phy_set_rf_power_state(struct ieee80211_hw *hw, | ||
2035 | enum rf_pwrstate rfpwr_state) | ||
2036 | { | ||
2037 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
2038 | bool bresult = false; | ||
2039 | |||
2040 | if (rfpwr_state == ppsc->rfpwr_state) | ||
2041 | return bresult; | ||
2042 | bresult = _rtl8723ae_phy_set_rf_power_state(hw, rfpwr_state); | ||
2043 | return bresult; | ||
2044 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h b/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h new file mode 100644 index 000000000000..e7a59eba351a --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h | |||
@@ -0,0 +1,224 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 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 __RTL92C_PHY_H__ | ||
31 | #define __RTL92C_PHY_H__ | ||
32 | |||
33 | #define MAX_PRECMD_CNT 16 | ||
34 | #define MAX_RFDEPENDCMD_CNT 16 | ||
35 | #define MAX_POSTCMD_CNT 16 | ||
36 | |||
37 | #define MAX_DOZE_WAITING_TIMES_9x 64 | ||
38 | |||
39 | #define RT_CANNOT_IO(hw) false | ||
40 | #define HIGHPOWER_RADIOA_ARRAYLEN 22 | ||
41 | |||
42 | #define MAX_TOLERANCE 5 | ||
43 | #define IQK_DELAY_TIME 1 | ||
44 | |||
45 | #define APK_BB_REG_NUM 5 | ||
46 | #define APK_AFE_REG_NUM 16 | ||
47 | #define APK_CURVE_REG_NUM 4 | ||
48 | #define PATH_NUM 2 | ||
49 | |||
50 | #define LOOP_LIMIT 5 | ||
51 | #define MAX_STALL_TIME 50 | ||
52 | #define AntennaDiversityValue 0x80 | ||
53 | #define MAX_TXPWR_IDX_NMODE_92S 63 | ||
54 | #define Reset_Cnt_Limit 3 | ||
55 | |||
56 | #define IQK_MAC_REG_NUM 4 | ||
57 | |||
58 | #define RF6052_MAX_PATH 2 | ||
59 | |||
60 | #define CT_OFFSET_MAC_ADDR 0X16 | ||
61 | |||
62 | #define CT_OFFSET_CCK_TX_PWR_IDX 0x5A | ||
63 | #define CT_OFFSET_HT401S_TX_PWR_IDX 0x60 | ||
64 | #define CT_OFFSET_HT402S_TX_PWR_IDX_DIFF 0x66 | ||
65 | #define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69 | ||
66 | #define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C | ||
67 | |||
68 | #define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F | ||
69 | #define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72 | ||
70 | |||
71 | #define CT_OFFSET_CHANNEL_PLAH 0x75 | ||
72 | #define CT_OFFSET_THERMAL_METER 0x78 | ||
73 | #define CT_OFFSET_RF_OPTION 0x79 | ||
74 | #define CT_OFFSET_VERSION 0x7E | ||
75 | #define CT_OFFSET_CUSTOMER_ID 0x7F | ||
76 | |||
77 | #define RTL92C_MAX_PATH_NUM 2 | ||
78 | |||
79 | enum swchnlcmd_id { | ||
80 | CMDID_END, | ||
81 | CMDID_SET_TXPOWEROWER_LEVEL, | ||
82 | CMDID_BBREGWRITE10, | ||
83 | CMDID_WRITEPORT_ULONG, | ||
84 | CMDID_WRITEPORT_USHORT, | ||
85 | CMDID_WRITEPORT_UCHAR, | ||
86 | CMDID_RF_WRITEREG, | ||
87 | }; | ||
88 | |||
89 | struct swchnlcmd { | ||
90 | enum swchnlcmd_id cmdid; | ||
91 | u32 para1; | ||
92 | u32 para2; | ||
93 | u32 msdelay; | ||
94 | }; | ||
95 | |||
96 | enum hw90_block_e { | ||
97 | HW90_BLOCK_MAC = 0, | ||
98 | HW90_BLOCK_PHY0 = 1, | ||
99 | HW90_BLOCK_PHY1 = 2, | ||
100 | HW90_BLOCK_RF = 3, | ||
101 | HW90_BLOCK_MAXIMUM = 4, | ||
102 | }; | ||
103 | |||
104 | enum baseband_config_type { | ||
105 | BASEBAND_CONFIG_PHY_REG = 0, | ||
106 | BASEBAND_CONFIG_AGC_TAB = 1, | ||
107 | }; | ||
108 | |||
109 | enum ra_offset_area { | ||
110 | RA_OFFSET_LEGACY_OFDM1, | ||
111 | RA_OFFSET_LEGACY_OFDM2, | ||
112 | RA_OFFSET_HT_OFDM1, | ||
113 | RA_OFFSET_HT_OFDM2, | ||
114 | RA_OFFSET_HT_OFDM3, | ||
115 | RA_OFFSET_HT_OFDM4, | ||
116 | RA_OFFSET_HT_CCK, | ||
117 | }; | ||
118 | |||
119 | enum antenna_path { | ||
120 | ANTENNA_NONE, | ||
121 | ANTENNA_D, | ||
122 | ANTENNA_C, | ||
123 | ANTENNA_CD, | ||
124 | ANTENNA_B, | ||
125 | ANTENNA_BD, | ||
126 | ANTENNA_BC, | ||
127 | ANTENNA_BCD, | ||
128 | ANTENNA_A, | ||
129 | ANTENNA_AD, | ||
130 | ANTENNA_AC, | ||
131 | ANTENNA_ACD, | ||
132 | ANTENNA_AB, | ||
133 | ANTENNA_ABD, | ||
134 | ANTENNA_ABC, | ||
135 | ANTENNA_ABCD | ||
136 | }; | ||
137 | |||
138 | struct r_antenna_select_ofdm { | ||
139 | u32 r_tx_antenna:4; | ||
140 | u32 r_ant_l:4; | ||
141 | u32 r_ant_non_ht:4; | ||
142 | u32 r_ant_ht1:4; | ||
143 | u32 r_ant_ht2:4; | ||
144 | u32 r_ant_ht_s1:4; | ||
145 | u32 r_ant_non_ht_s1:4; | ||
146 | u32 ofdm_txsc:2; | ||
147 | u32 reserved:2; | ||
148 | }; | ||
149 | |||
150 | struct r_antenna_select_cck { | ||
151 | u8 r_cckrx_enable_2:2; | ||
152 | u8 r_cckrx_enable:2; | ||
153 | u8 r_ccktx_enable:4; | ||
154 | }; | ||
155 | |||
156 | struct efuse_contents { | ||
157 | u8 mac_addr[ETH_ALEN]; | ||
158 | u8 cck_tx_power_idx[6]; | ||
159 | u8 ht40_1s_tx_power_idx[6]; | ||
160 | u8 ht40_2s_tx_power_idx_diff[3]; | ||
161 | u8 ht20_tx_power_idx_diff[3]; | ||
162 | u8 ofdm_tx_power_idx_diff[3]; | ||
163 | u8 ht40_max_power_offset[3]; | ||
164 | u8 ht20_max_power_offset[3]; | ||
165 | u8 channel_plan; | ||
166 | u8 thermal_meter; | ||
167 | u8 rf_option[5]; | ||
168 | u8 version; | ||
169 | u8 oem_id; | ||
170 | u8 regulatory; | ||
171 | }; | ||
172 | |||
173 | struct tx_power_struct { | ||
174 | u8 cck[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; | ||
175 | u8 ht40_1s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; | ||
176 | u8 ht40_2s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; | ||
177 | u8 ht20_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; | ||
178 | u8 legacy_ht_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; | ||
179 | u8 legacy_ht_txpowerdiff; | ||
180 | u8 groupht20[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; | ||
181 | u8 groupht40[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; | ||
182 | u8 pwrgroup_cnt; | ||
183 | u32 mcs_original_offset[4][16]; | ||
184 | }; | ||
185 | |||
186 | extern u32 rtl8723ae_phy_query_bb_reg(struct ieee80211_hw *hw, | ||
187 | u32 regaddr, u32 bitmask); | ||
188 | extern void rtl8723ae_phy_set_bb_reg(struct ieee80211_hw *hw, | ||
189 | u32 regaddr, u32 bitmask, u32 data); | ||
190 | extern u32 rtl8723ae_phy_query_rf_reg(struct ieee80211_hw *hw, | ||
191 | enum radio_path rfpath, u32 regaddr, | ||
192 | u32 bitmask); | ||
193 | extern void rtl8723ae_phy_set_rf_reg(struct ieee80211_hw *hw, | ||
194 | enum radio_path rfpath, u32 regaddr, | ||
195 | u32 bitmask, u32 data); | ||
196 | extern bool rtl8723ae_phy_mac_config(struct ieee80211_hw *hw); | ||
197 | extern bool rtl8723ae_phy_bb_config(struct ieee80211_hw *hw); | ||
198 | extern bool rtl8723ae_phy_rf_config(struct ieee80211_hw *hw); | ||
199 | extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, | ||
200 | enum radio_path rfpath); | ||
201 | extern void rtl8723ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); | ||
202 | extern void rtl8723ae_phy_get_txpower_level(struct ieee80211_hw *hw, | ||
203 | long *powerlevel); | ||
204 | extern void rtl8723ae_phy_set_txpower_level(struct ieee80211_hw *hw, | ||
205 | u8 channel); | ||
206 | extern bool rtl8723ae_phy_update_txpower_dbm(struct ieee80211_hw *hw, | ||
207 | long power_indbm); | ||
208 | extern void rtl8723ae_phy_scan_operation_backup(struct ieee80211_hw *hw, | ||
209 | u8 operation); | ||
210 | extern void rtl8723ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw); | ||
211 | extern void rtl8723ae_phy_set_bw_mode(struct ieee80211_hw *hw, | ||
212 | enum nl80211_channel_type ch_type); | ||
213 | extern void rtl8723ae_phy_sw_chnl_callback(struct ieee80211_hw *hw); | ||
214 | extern u8 rtl8723ae_phy_sw_chnl(struct ieee80211_hw *hw); | ||
215 | extern void rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery); | ||
216 | void rtl8723ae_phy_lc_calibrate(struct ieee80211_hw *hw); | ||
217 | void rtl8723ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain); | ||
218 | bool rtl8723ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, | ||
219 | enum radio_path rfpath); | ||
220 | bool rtl8723ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); | ||
221 | extern bool rtl8723ae_phy_set_rf_power_state(struct ieee80211_hw *hw, | ||
222 | enum rf_pwrstate rfpwr_state); | ||
223 | |||
224 | #endif | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.c b/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.c new file mode 100644 index 000000000000..df6ca9a57f7f --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.c | |||
@@ -0,0 +1,109 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 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 "pwrseqcmd.h" | ||
31 | #include "pwrseq.h" | ||
32 | |||
33 | /* drivers should parse arrays below and do the corresponding actions */ | ||
34 | |||
35 | /*3 Power on Array*/ | ||
36 | struct wlan_pwr_cfg rtl8723A_power_on_flow[RTL8723A_TRANS_CARDEMU_TO_ACT_STPS | ||
37 | + RTL8723A_TRANS_END_STPS] = { | ||
38 | RTL8723A_TRANS_CARDEMU_TO_ACT, | ||
39 | RTL8723A_TRANS_END | ||
40 | }; | ||
41 | |||
42 | /*3Radio off GPIO Array */ | ||
43 | struct wlan_pwr_cfg rtl8723A_radio_off_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS | ||
44 | + RTL8723A_TRANS_END_STPS] = { | ||
45 | RTL8723A_TRANS_ACT_TO_CARDEMU, | ||
46 | RTL8723A_TRANS_END | ||
47 | }; | ||
48 | |||
49 | /*3Card Disable Array*/ | ||
50 | struct wlan_pwr_cfg | ||
51 | rtl8723A_card_disable_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS | ||
52 | + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS | ||
53 | + RTL8723A_TRANS_END_STPS] = { | ||
54 | RTL8723A_TRANS_ACT_TO_CARDEMU, | ||
55 | RTL8723A_TRANS_CARDEMU_TO_CARDDIS, | ||
56 | RTL8723A_TRANS_END | ||
57 | }; | ||
58 | |||
59 | /*3 Card Enable Array*/ | ||
60 | struct wlan_pwr_cfg rtl8723A_card_enable_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS | ||
61 | + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS | ||
62 | + RTL8723A_TRANS_END_STPS] = { | ||
63 | RTL8723A_TRANS_CARDDIS_TO_CARDEMU, | ||
64 | RTL8723A_TRANS_CARDEMU_TO_ACT, | ||
65 | RTL8723A_TRANS_END | ||
66 | }; | ||
67 | |||
68 | /*3Suspend Array*/ | ||
69 | struct wlan_pwr_cfg rtl8723A_suspend_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS | ||
70 | + RTL8723A_TRANS_CARDEMU_TO_SUS_STPS | ||
71 | + RTL8723A_TRANS_END_STPS] = { | ||
72 | RTL8723A_TRANS_ACT_TO_CARDEMU, | ||
73 | RTL8723A_TRANS_CARDEMU_TO_SUS, | ||
74 | RTL8723A_TRANS_END | ||
75 | }; | ||
76 | |||
77 | /*3 Resume Array*/ | ||
78 | struct wlan_pwr_cfg rtl8723A_resume_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS | ||
79 | + RTL8723A_TRANS_CARDEMU_TO_SUS_STPS | ||
80 | + RTL8723A_TRANS_END_STPS] = { | ||
81 | RTL8723A_TRANS_SUS_TO_CARDEMU, | ||
82 | RTL8723A_TRANS_CARDEMU_TO_ACT, | ||
83 | RTL8723A_TRANS_END | ||
84 | }; | ||
85 | |||
86 | /*3HWPDN Array*/ | ||
87 | struct wlan_pwr_cfg rtl8723A_hwpdn_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS | ||
88 | + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS | ||
89 | + RTL8723A_TRANS_END_STPS] = { | ||
90 | RTL8723A_TRANS_ACT_TO_CARDEMU, | ||
91 | RTL8723A_TRANS_CARDEMU_TO_PDN, | ||
92 | RTL8723A_TRANS_END | ||
93 | }; | ||
94 | |||
95 | /*3 Enter LPS */ | ||
96 | struct wlan_pwr_cfg rtl8723A_enter_lps_flow[RTL8723A_TRANS_ACT_TO_LPS_STPS | ||
97 | + RTL8723A_TRANS_END_STPS] = { | ||
98 | /*FW behavior*/ | ||
99 | RTL8723A_TRANS_ACT_TO_LPS, | ||
100 | RTL8723A_TRANS_END | ||
101 | }; | ||
102 | |||
103 | /*3 Leave LPS */ | ||
104 | struct wlan_pwr_cfg rtl8723A_leave_lps_flow[RTL8723A_TRANS_LPS_TO_ACT_STPS | ||
105 | + RTL8723A_TRANS_END_STPS] = { | ||
106 | /*FW behavior*/ | ||
107 | RTL8723A_TRANS_LPS_TO_ACT, | ||
108 | RTL8723A_TRANS_END | ||
109 | }; | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h b/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h new file mode 100644 index 000000000000..7a46f9fdf558 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h | |||
@@ -0,0 +1,322 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 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 __RTL8723E_PWRSEQ_H__ | ||
31 | #define __RTL8723E_PWRSEQ_H__ | ||
32 | |||
33 | #include "pwrseqcmd.h" | ||
34 | /* | ||
35 | Check document WM-20110607-Paul-RTL8723A_Power_Architecture-R02.vsd | ||
36 | There are 6 HW Power States: | ||
37 | 0: POFF--Power Off | ||
38 | 1: PDN--Power Down | ||
39 | 2: CARDEMU--Card Emulation | ||
40 | 3: ACT--Active Mode | ||
41 | 4: LPS--Low Power State | ||
42 | 5: SUS--Suspend | ||
43 | |||
44 | The transision from different states are defined below | ||
45 | TRANS_CARDEMU_TO_ACT | ||
46 | TRANS_ACT_TO_CARDEMU | ||
47 | TRANS_CARDEMU_TO_SUS | ||
48 | TRANS_SUS_TO_CARDEMU | ||
49 | TRANS_CARDEMU_TO_PDN | ||
50 | TRANS_ACT_TO_LPS | ||
51 | TRANS_LPS_TO_ACT | ||
52 | |||
53 | TRANS_END | ||
54 | */ | ||
55 | |||
56 | #define RTL8723A_TRANS_CARDEMU_TO_ACT_STPS 10 | ||
57 | #define RTL8723A_TRANS_ACT_TO_CARDEMU_STPS 10 | ||
58 | #define RTL8723A_TRANS_CARDEMU_TO_SUS_STPS 10 | ||
59 | #define RTL8723A_TRANS_SUS_TO_CARDEMU_STPS 10 | ||
60 | #define RTL8723A_TRANS_CARDEMU_TO_PDN_STPS 10 | ||
61 | #define RTL8723A_TRANS_PDN_TO_CARDEMU_STPS 10 | ||
62 | #define RTL8723A_TRANS_ACT_TO_LPS_STPS 15 | ||
63 | #define RTL8723A_TRANS_LPS_TO_ACT_STPS 15 | ||
64 | #define RTL8723A_TRANS_END_STPS 1 | ||
65 | |||
66 | |||
67 | #define RTL8723A_TRANS_CARDEMU_TO_ACT \ | ||
68 | /* format */ \ | ||
69 | /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, \ | ||
70 | * comments here*/ \ | ||
71 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
72 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(2), 0}, \ | ||
73 | /* disable SW LPS 0x04[10]=0*/ \ | ||
74 | {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
75 | PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), BIT(1)}, \ | ||
76 | /* wait till 0x04[17] = 1 power ready*/ \ | ||
77 | {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
78 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, \ | ||
79 | /* release WLON reset 0x04[16]=1*/ \ | ||
80 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
81 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0}, \ | ||
82 | /* disable HWPDN 0x04[15]=0*/ \ | ||
83 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
84 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, (BIT(4)|BIT(3)), 0}, \ | ||
85 | /* disable WL suspend*/ \ | ||
86 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
87 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, \ | ||
88 | /* polling until return 0*/ \ | ||
89 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
90 | PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(0), 0} | ||
91 | |||
92 | #define RTL8723A_TRANS_ACT_TO_CARDEMU \ | ||
93 | /* format */ \ | ||
94 | /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, \ | ||
95 | * comments here*/ \ | ||
96 | {0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
97 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0}, \ | ||
98 | /*0x1F[7:0] = 0 turn off RF*/ \ | ||
99 | {0x004E, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
100 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0}, \ | ||
101 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
102 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, \ | ||
103 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
104 | PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), 0} | ||
105 | |||
106 | #define RTL8723A_TRANS_CARDEMU_TO_SUS \ | ||
107 | /* format */ \ | ||
108 | /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, \ | ||
109 | * comments here*/ \ | ||
110 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \ | ||
111 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4)|BIT(3), \ | ||
112 | (BIT(4)|BIT(3))}, \ | ||
113 | /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \ | ||
114 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK | \ | ||
115 | PWR_INTF_SDIO_MSK, \ | ||
116 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)},\ | ||
117 | /*0x04[12:11] = 2b'01 enable WL suspend*/ \ | ||
118 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \ | ||
119 | PWR_BASEADDR_MAC, \ | ||
120 | PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)|BIT(4)}, \ | ||
121 | /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \ | ||
122 | {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ | ||
123 | PWR_BASEADDR_SDIO, \ | ||
124 | PWR_CMD_WRITE, BIT(0), BIT(0)}, \ | ||
125 | /*Set SDIO suspend local register*/ \ | ||
126 | {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ | ||
127 | PWR_BASEADDR_SDIO, \ | ||
128 | PWR_CMD_POLLING, BIT(1), 0} \ | ||
129 | /*wait power state to suspend*/ | ||
130 | |||
131 | #define RTL8723A_TRANS_SUS_TO_CARDEMU \ | ||
132 | /* format */ \ | ||
133 | /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ | ||
134 | {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ | ||
135 | PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0}, \ | ||
136 | /*Set SDIO suspend local register*/ \ | ||
137 | {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ | ||
138 | PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1)}, \ | ||
139 | /*wait power state to suspend*/ \ | ||
140 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
141 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0} \ | ||
142 | /*0x04[12:11] = 2b'01enable WL suspend*/ | ||
143 | |||
144 | #define RTL8723A_TRANS_CARDEMU_TO_CARDDIS \ | ||
145 | /* format */ \ | ||
146 | /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ | ||
147 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ | ||
148 | PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, \ | ||
149 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)},\ | ||
150 | /*0x04[12:11] = 2b'01 enable WL suspend*/ \ | ||
151 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \ | ||
152 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(2), BIT(2)}, \ | ||
153 | /*0x04[10] = 1, enable SW LPS*/ \ | ||
154 | {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ | ||
155 | PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), BIT(0)}, \ | ||
156 | /*Set SDIO suspend local register*/ \ | ||
157 | {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ | ||
158 | PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), 0} \ | ||
159 | /*wait power state to suspend*/ | ||
160 | |||
161 | #define RTL8723A_TRANS_CARDDIS_TO_CARDEMU \ | ||
162 | /* format */ \ | ||
163 | /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ | ||
164 | {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ | ||
165 | PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0}, \ | ||
166 | /*Set SDIO suspend local register*/ \ | ||
167 | {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ | ||
168 | PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1)}, \ | ||
169 | /*wait power state to suspend*/ \ | ||
170 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
171 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, \ | ||
172 | /*0x04[12:11] = 2b'00enable WL suspend*/ \ | ||
173 | {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
174 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0} \ | ||
175 | /*PCIe DMA start*/ | ||
176 | |||
177 | #define RTL8723A_TRANS_CARDEMU_TO_PDN \ | ||
178 | /* format */ \ | ||
179 | /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ | ||
180 | {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
181 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, \ | ||
182 | /* 0x04[16] = 0*/\ | ||
183 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
184 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), BIT(7)} \ | ||
185 | /* 0x04[15] = 1*/ | ||
186 | |||
187 | #define RTL8723A_TRANS_PDN_TO_CARDEMU \ | ||
188 | /* format */ \ | ||
189 | /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ | ||
190 | {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
191 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0} \ | ||
192 | /* 0x04[15] = 0*/ | ||
193 | |||
194 | #define RTL8723A_TRANS_ACT_TO_LPS \ | ||
195 | /* format */ \ | ||
196 | /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ | ||
197 | {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
198 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF}, \ | ||
199 | /*PCIe DMA stop*/ \ | ||
200 | {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
201 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x7F}, \ | ||
202 | /*Tx Pause*/ \ | ||
203 | {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
204 | PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \ | ||
205 | /*Should be zero if no packet is transmitting*/ \ | ||
206 | {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
207 | PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \ | ||
208 | /*Should be zero if no packet is transmitting*/ \ | ||
209 | {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
210 | PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \ | ||
211 | /*Should be zero if no packet is transmitting*/ \ | ||
212 | {0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
213 | PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \ | ||
214 | /*Should be zero if no packet is transmitting*/ \ | ||
215 | {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
216 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, \ | ||
217 | /*CCK and OFDM are disabled,and clock are gated*/ \ | ||
218 | {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
219 | PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US}, \ | ||
220 | /*Delay 1us*/ \ | ||
221 | {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
222 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0}, \ | ||
223 | /*Whole BB is reset*/ \ | ||
224 | {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
225 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x3F}, \ | ||
226 | /*Reset MAC TRX*/ \ | ||
227 | {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
228 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0}, \ | ||
229 | /*check if removed later*/ \ | ||
230 | {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
231 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), BIT(5)} \ | ||
232 | /*Respond TxOK to scheduler*/ | ||
233 | |||
234 | #define RTL8723A_TRANS_LPS_TO_ACT \ | ||
235 | /* format */ \ | ||
236 | /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ | ||
237 | {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ | ||
238 | PWR_BASEADDR_SDIO, PWR_CMD_WRITE, 0xFF, 0x84}, \ | ||
239 | /*SDIO RPWM*/ \ | ||
240 | {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, \ | ||
241 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84}, \ | ||
242 | /*USB RPWM*/ \ | ||
243 | {0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \ | ||
244 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84}, \ | ||
245 | /*PCIe RPWM*/ \ | ||
246 | {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
247 | PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, \ | ||
248 | /*Delay*/ \ | ||
249 | {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
250 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, \ | ||
251 | /* 0x08[4] = 0 switch TSF to 40M*/ \ | ||
252 | {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
253 | PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(7), 0}, \ | ||
254 | /*Polling 0x109[7]=0 TSF in 40M*/ \ | ||
255 | {0x0029, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
256 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(6)|BIT(7), 0}, \ | ||
257 | /*. 0x29[7:6] = 2b'00 enable BB clock*/ \ | ||
258 | {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
259 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, \ | ||
260 | /*. 0x101[1] = 1*/ \ | ||
261 | {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
262 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF}, \ | ||
263 | /* 0x100[7:0] = 0xFF enable WMAC TRX*/ \ | ||
264 | {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
265 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1)|BIT(0), \ | ||
266 | BIT(1)|BIT(0)}, \ | ||
267 | /* 0x02[1:0] = 2b'11 enable BB macro*/ \ | ||
268 | {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
269 | PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0} \ | ||
270 | /*. 0x522 = 0*/ | ||
271 | |||
272 | #define RTL8723A_TRANS_END \ | ||
273 | /* format */ \ | ||
274 | /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ | ||
275 | {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ | ||
276 | 0, PWR_CMD_END, 0, 0} | ||
277 | |||
278 | extern struct | ||
279 | wlan_pwr_cfg rtl8723A_power_on_flow[RTL8723A_TRANS_CARDEMU_TO_ACT_STPS | ||
280 | + RTL8723A_TRANS_END_STPS]; | ||
281 | extern struct | ||
282 | wlan_pwr_cfg rtl8723A_radio_off_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS | ||
283 | + RTL8723A_TRANS_END_STPS]; | ||
284 | extern struct | ||
285 | wlan_pwr_cfg rtl8723A_card_disable_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS | ||
286 | + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS | ||
287 | + RTL8723A_TRANS_END_STPS]; | ||
288 | extern struct | ||
289 | wlan_pwr_cfg rtl8723A_card_enable_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS | ||
290 | + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS | ||
291 | + RTL8723A_TRANS_END_STPS]; | ||
292 | extern struct | ||
293 | wlan_pwr_cfg rtl8723A_suspend_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS | ||
294 | + RTL8723A_TRANS_CARDEMU_TO_SUS_STPS | ||
295 | + RTL8723A_TRANS_END_STPS]; | ||
296 | extern struct | ||
297 | wlan_pwr_cfg rtl8723A_resume_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS | ||
298 | + RTL8723A_TRANS_CARDEMU_TO_SUS_STPS | ||
299 | + RTL8723A_TRANS_END_STPS]; | ||
300 | extern struct | ||
301 | wlan_pwr_cfg rtl8723A_hwpdn_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS | ||
302 | + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS | ||
303 | + RTL8723A_TRANS_END_STPS]; | ||
304 | extern struct | ||
305 | wlan_pwr_cfg rtl8723A_enter_lps_flow[RTL8723A_TRANS_ACT_TO_LPS_STPS | ||
306 | + RTL8723A_TRANS_END_STPS]; | ||
307 | extern struct | ||
308 | wlan_pwr_cfg rtl8723A_leave_lps_flow[RTL8723A_TRANS_LPS_TO_ACT_STPS | ||
309 | + RTL8723A_TRANS_END_STPS]; | ||
310 | |||
311 | /* RTL8723 Power Configuration CMDs for PCIe interface */ | ||
312 | #define Rtl8723_NIC_PWR_ON_FLOW rtl8723A_power_on_flow | ||
313 | #define Rtl8723_NIC_RF_OFF_FLOW rtl8723A_radio_off_flow | ||
314 | #define Rtl8723_NIC_DISABLE_FLOW rtl8723A_card_disable_flow | ||
315 | #define Rtl8723_NIC_ENABLE_FLOW rtl8723A_card_enable_flow | ||
316 | #define Rtl8723_NIC_SUSPEND_FLOW rtl8723A_suspend_flow | ||
317 | #define Rtl8723_NIC_RESUME_FLOW rtl8723A_resume_flow | ||
318 | #define Rtl8723_NIC_PDN_FLOW rtl8723A_hwpdn_flow | ||
319 | #define Rtl8723_NIC_LPS_ENTER_FLOW rtl8723A_enter_lps_flow | ||
320 | #define Rtl8723_NIC_LPS_LEAVE_FLOW rtl8723A_leave_lps_flow | ||
321 | |||
322 | #endif | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.c b/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.c new file mode 100644 index 000000000000..2044b5936b7f --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.c | |||
@@ -0,0 +1,129 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 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 "pwrseq.h" | ||
31 | |||
32 | /* Description: | ||
33 | * This routine deals with the Power Configuration CMD | ||
34 | * parsing for RTL8723/RTL8188E Series IC. | ||
35 | * Assumption: | ||
36 | * We should follow specific format that was released from HW SD. | ||
37 | */ | ||
38 | bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version, | ||
39 | u8 faversion, u8 interface_type, | ||
40 | struct wlan_pwr_cfg pwrcfgcmd[]) | ||
41 | { | ||
42 | struct wlan_pwr_cfg cfg_cmd = {0}; | ||
43 | bool polling_bit = false; | ||
44 | u32 ary_idx = 0; | ||
45 | u8 value = 0; | ||
46 | u32 offset = 0; | ||
47 | u32 polling_count = 0; | ||
48 | u32 max_polling_cnt = 5000; | ||
49 | |||
50 | do { | ||
51 | cfg_cmd = pwrcfgcmd[ary_idx]; | ||
52 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
53 | "rtl_hal_pwrseqcmdparsing(): offset(%#x),cut_msk(%#x), famsk(%#x)," | ||
54 | "interface_msk(%#x), base(%#x), cmd(%#x), msk(%#x), value(%#x)\n", | ||
55 | GET_PWR_CFG_OFFSET(cfg_cmd), | ||
56 | GET_PWR_CFG_CUT_MASK(cfg_cmd), | ||
57 | GET_PWR_CFG_FAB_MASK(cfg_cmd), | ||
58 | GET_PWR_CFG_INTF_MASK(cfg_cmd), | ||
59 | GET_PWR_CFG_BASE(cfg_cmd), GET_PWR_CFG_CMD(cfg_cmd), | ||
60 | GET_PWR_CFG_MASK(cfg_cmd), GET_PWR_CFG_VALUE(cfg_cmd)); | ||
61 | |||
62 | if ((GET_PWR_CFG_FAB_MASK(cfg_cmd)&faversion) && | ||
63 | (GET_PWR_CFG_CUT_MASK(cfg_cmd)&cut_version) && | ||
64 | (GET_PWR_CFG_INTF_MASK(cfg_cmd)&interface_type)) { | ||
65 | switch (GET_PWR_CFG_CMD(cfg_cmd)) { | ||
66 | case PWR_CMD_READ: | ||
67 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
68 | "rtl_hal_pwrseqcmdparsing(): PWR_CMD_READ\n"); | ||
69 | break; | ||
70 | case PWR_CMD_WRITE: | ||
71 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
72 | "rtl_hal_pwrseqcmdparsing(): PWR_CMD_WRITE\n"); | ||
73 | offset = GET_PWR_CFG_OFFSET(cfg_cmd); | ||
74 | |||
75 | /*Read the value from system register*/ | ||
76 | value = rtl_read_byte(rtlpriv, offset); | ||
77 | value &= (~(GET_PWR_CFG_MASK(cfg_cmd))); | ||
78 | value |= (GET_PWR_CFG_VALUE(cfg_cmd) & | ||
79 | GET_PWR_CFG_MASK(cfg_cmd)); | ||
80 | |||
81 | /*Write the value back to sytem register*/ | ||
82 | rtl_write_byte(rtlpriv, offset, value); | ||
83 | break; | ||
84 | case PWR_CMD_POLLING: | ||
85 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
86 | "rtl_hal_pwrseqcmdparsing(): PWR_CMD_POLLING\n"); | ||
87 | polling_bit = false; | ||
88 | offset = GET_PWR_CFG_OFFSET(cfg_cmd); | ||
89 | |||
90 | do { | ||
91 | value = rtl_read_byte(rtlpriv, offset); | ||
92 | |||
93 | value &= GET_PWR_CFG_MASK(cfg_cmd); | ||
94 | if (value == | ||
95 | (GET_PWR_CFG_VALUE(cfg_cmd) | ||
96 | & GET_PWR_CFG_MASK(cfg_cmd))) | ||
97 | polling_bit = true; | ||
98 | else | ||
99 | udelay(10); | ||
100 | |||
101 | if (polling_count++ > max_polling_cnt) | ||
102 | return false; | ||
103 | } while (!polling_bit); | ||
104 | break; | ||
105 | case PWR_CMD_DELAY: | ||
106 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
107 | "rtl_hal_pwrseqcmdparsing(): PWR_CMD_DELAY\n"); | ||
108 | if (GET_PWR_CFG_VALUE(cfg_cmd) == | ||
109 | PWRSEQ_DELAY_US) | ||
110 | udelay(GET_PWR_CFG_OFFSET(cfg_cmd)); | ||
111 | else | ||
112 | mdelay(GET_PWR_CFG_OFFSET(cfg_cmd)); | ||
113 | break; | ||
114 | case PWR_CMD_END: | ||
115 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
116 | "rtl_hal_pwrseqcmdparsing(): PWR_CMD_END\n"); | ||
117 | return true; | ||
118 | default: | ||
119 | RT_ASSERT(false, | ||
120 | "rtl_hal_pwrseqcmdparsing(): Unknown CMD!!\n"); | ||
121 | break; | ||
122 | } | ||
123 | |||
124 | } | ||
125 | ary_idx++; | ||
126 | } while (1); | ||
127 | |||
128 | return true; | ||
129 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.h b/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.h new file mode 100644 index 000000000000..6e0f3ea37ec0 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.h | |||
@@ -0,0 +1,98 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 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 __RTL8723E_PWRSEQCMD_H__ | ||
31 | #define __RTL8723E_PWRSEQCMD_H__ | ||
32 | |||
33 | #include "../wifi.h" | ||
34 | /*--------------------------------------------- | ||
35 | * 3 The value of cmd: 4 bits | ||
36 | *--------------------------------------------- | ||
37 | */ | ||
38 | #define PWR_CMD_READ 0x00 | ||
39 | #define PWR_CMD_WRITE 0x01 | ||
40 | #define PWR_CMD_POLLING 0x02 | ||
41 | #define PWR_CMD_DELAY 0x03 | ||
42 | #define PWR_CMD_END 0x04 | ||
43 | |||
44 | /* define the base address of each block */ | ||
45 | #define PWR_BASEADDR_MAC 0x00 | ||
46 | #define PWR_BASEADDR_USB 0x01 | ||
47 | #define PWR_BASEADDR_PCIE 0x02 | ||
48 | #define PWR_BASEADDR_SDIO 0x03 | ||
49 | |||
50 | #define PWR_INTF_SDIO_MSK BIT(0) | ||
51 | #define PWR_INTF_USB_MSK BIT(1) | ||
52 | #define PWR_INTF_PCI_MSK BIT(2) | ||
53 | #define PWR_INTF_ALL_MSK (BIT(0)|BIT(1)|BIT(2)|BIT(3)) | ||
54 | |||
55 | #define PWR_FAB_TSMC_MSK BIT(0) | ||
56 | #define PWR_FAB_UMC_MSK BIT(1) | ||
57 | #define PWR_FAB_ALL_MSK (BIT(0)|BIT(1)|BIT(2)|BIT(3)) | ||
58 | |||
59 | #define PWR_CUT_TESTCHIP_MSK BIT(0) | ||
60 | #define PWR_CUT_A_MSK BIT(1) | ||
61 | #define PWR_CUT_B_MSK BIT(2) | ||
62 | #define PWR_CUT_C_MSK BIT(3) | ||
63 | #define PWR_CUT_D_MSK BIT(4) | ||
64 | #define PWR_CUT_E_MSK BIT(5) | ||
65 | #define PWR_CUT_F_MSK BIT(6) | ||
66 | #define PWR_CUT_G_MSK BIT(7) | ||
67 | #define PWR_CUT_ALL_MSK 0xFF | ||
68 | |||
69 | enum pwrseq_delay_unit { | ||
70 | PWRSEQ_DELAY_US, | ||
71 | PWRSEQ_DELAY_MS, | ||
72 | }; | ||
73 | |||
74 | struct wlan_pwr_cfg { | ||
75 | u16 offset; | ||
76 | u8 cut_msk; | ||
77 | u8 fab_msk:4; | ||
78 | u8 interface_msk:4; | ||
79 | u8 base:4; | ||
80 | u8 cmd:4; | ||
81 | u8 msk; | ||
82 | u8 value; | ||
83 | }; | ||
84 | |||
85 | #define GET_PWR_CFG_OFFSET(__PWR_CMD) (__PWR_CMD.offset) | ||
86 | #define GET_PWR_CFG_CUT_MASK(__PWR_CMD) (__PWR_CMD.cut_msk) | ||
87 | #define GET_PWR_CFG_FAB_MASK(__PWR_CMD) (__PWR_CMD.fab_msk) | ||
88 | #define GET_PWR_CFG_INTF_MASK(__PWR_CMD) (__PWR_CMD.interface_msk) | ||
89 | #define GET_PWR_CFG_BASE(__PWR_CMD) (__PWR_CMD.base) | ||
90 | #define GET_PWR_CFG_CMD(__PWR_CMD) (__PWR_CMD.cmd) | ||
91 | #define GET_PWR_CFG_MASK(__PWR_CMD) (__PWR_CMD.msk) | ||
92 | #define GET_PWR_CFG_VALUE(__PWR_CMD) (__PWR_CMD.value) | ||
93 | |||
94 | bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version, | ||
95 | u8 fab_version, u8 interface_type, | ||
96 | struct wlan_pwr_cfg pwrcfgcmd[]); | ||
97 | |||
98 | #endif | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h b/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h new file mode 100644 index 000000000000..199da366c6da --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h | |||
@@ -0,0 +1,2097 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 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 __RTL8723E_REG_H__ | ||
31 | #define __RTL8723E_REG_H__ | ||
32 | |||
33 | #define REG_SYS_ISO_CTRL 0x0000 | ||
34 | #define REG_SYS_FUNC_EN 0x0002 | ||
35 | #define REG_APS_FSMCO 0x0004 | ||
36 | #define REG_SYS_CLKR 0x0008 | ||
37 | #define REG_9346CR 0x000A | ||
38 | #define REG_EE_VPD 0x000C | ||
39 | #define REG_AFE_MISC 0x0010 | ||
40 | #define REG_SPS0_CTRL 0x0011 | ||
41 | #define REG_SPS_OCP_CFG 0x0018 | ||
42 | #define REG_RSV_CTRL 0x001C | ||
43 | #define REG_RF_CTRL 0x001F | ||
44 | #define REG_LDOA15_CTRL 0x0020 | ||
45 | #define REG_LDOV12D_CTRL 0x0021 | ||
46 | #define REG_LDOHCI12_CTRL 0x0022 | ||
47 | #define REG_LPLDO_CTRL 0x0023 | ||
48 | #define REG_AFE_XTAL_CTRL 0x0024 | ||
49 | #define REG_AFE_PLL_CTRL 0x0028 | ||
50 | #define REG_EFUSE_CTRL 0x0030 | ||
51 | #define REG_EFUSE_TEST 0x0034 | ||
52 | #define REG_PWR_DATA 0x0038 | ||
53 | #define REG_CAL_TIMER 0x003C | ||
54 | #define REG_ACLK_MON 0x003E | ||
55 | #define REG_GPIO_MUXCFG 0x0040 | ||
56 | #define REG_GPIO_IO_SEL 0x0042 | ||
57 | #define REG_MAC_PINMUX_CFG 0x0043 | ||
58 | #define REG_GPIO_PIN_CTRL 0x0044 | ||
59 | #define REG_GPIO_INTM 0x0048 | ||
60 | #define REG_LEDCFG0 0x004C | ||
61 | #define REG_LEDCFG1 0x004D | ||
62 | #define REG_LEDCFG2 0x004E | ||
63 | #define REG_LEDCFG3 0x004F | ||
64 | #define REG_FSIMR 0x0050 | ||
65 | #define REG_FSISR 0x0054 | ||
66 | #define REG_GPIO_PIN_CTRL_2 0x0060 | ||
67 | #define REG_GPIO_IO_SEL_2 0x0062 | ||
68 | #define REG_MULTI_FUNC_CTRL 0x0068 | ||
69 | |||
70 | #define REG_MCUFWDL 0x0080 | ||
71 | |||
72 | #define REG_HMEBOX_EXT_0 0x0088 | ||
73 | #define REG_HMEBOX_EXT_1 0x008A | ||
74 | #define REG_HMEBOX_EXT_2 0x008C | ||
75 | #define REG_HMEBOX_EXT_3 0x008E | ||
76 | |||
77 | #define REG_BIST_SCAN 0x00D0 | ||
78 | #define REG_BIST_RPT 0x00D4 | ||
79 | #define REG_BIST_ROM_RPT 0x00D8 | ||
80 | #define REG_USB_SIE_INTF 0x00E0 | ||
81 | #define REG_PCIE_MIO_INTF 0x00E4 | ||
82 | #define REG_PCIE_MIO_INTD 0x00E8 | ||
83 | #define REG_SYS_CFG 0x00F0 | ||
84 | #define REG_GPIO_OUTSTS 0x00F4 | ||
85 | |||
86 | #define REG_CR 0x0100 | ||
87 | #define REG_PBP 0x0104 | ||
88 | #define REG_TRXDMA_CTRL 0x010C | ||
89 | #define REG_TRXFF_BNDY 0x0114 | ||
90 | #define REG_TRXFF_STATUS 0x0118 | ||
91 | #define REG_RXFF_PTR 0x011C | ||
92 | #define REG_HIMR 0x0120 | ||
93 | #define REG_HISR 0x0124 | ||
94 | #define REG_HIMRE 0x0128 | ||
95 | #define REG_HISRE 0x012C | ||
96 | #define REG_CPWM 0x012F | ||
97 | #define REG_FWIMR 0x0130 | ||
98 | #define REG_FWISR 0x0134 | ||
99 | #define REG_PKTBUF_DBG_CTRL 0x0140 | ||
100 | #define REG_PKTBUF_DBG_DATA_L 0x0144 | ||
101 | #define REG_PKTBUF_DBG_DATA_H 0x0148 | ||
102 | |||
103 | #define REG_TC0_CTRL 0x0150 | ||
104 | #define REG_TC1_CTRL 0x0154 | ||
105 | #define REG_TC2_CTRL 0x0158 | ||
106 | #define REG_TC3_CTRL 0x015C | ||
107 | #define REG_TC4_CTRL 0x0160 | ||
108 | #define REG_TCUNIT_BASE 0x0164 | ||
109 | #define REG_MBIST_START 0x0174 | ||
110 | #define REG_MBIST_DONE 0x0178 | ||
111 | #define REG_MBIST_FAIL 0x017C | ||
112 | #define REG_C2HEVT_MSG_NORMAL 0x01A0 | ||
113 | #define REG_C2HEVT_MSG_TEST 0x01B8 | ||
114 | #define REG_MCUTST_1 0x01c0 | ||
115 | #define REG_FMETHR 0x01C8 | ||
116 | #define REG_HMETFR 0x01CC | ||
117 | #define REG_HMEBOX_0 0x01D0 | ||
118 | #define REG_HMEBOX_1 0x01D4 | ||
119 | #define REG_HMEBOX_2 0x01D8 | ||
120 | #define REG_HMEBOX_3 0x01DC | ||
121 | |||
122 | #define REG_LLT_INIT 0x01E0 | ||
123 | #define REG_BB_ACCEESS_CTRL 0x01E8 | ||
124 | #define REG_BB_ACCESS_DATA 0x01EC | ||
125 | |||
126 | #define REG_RQPN 0x0200 | ||
127 | #define REG_FIFOPAGE 0x0204 | ||
128 | #define REG_TDECTRL 0x0208 | ||
129 | #define REG_TXDMA_OFFSET_CHK 0x020C | ||
130 | #define REG_TXDMA_STATUS 0x0210 | ||
131 | #define REG_RQPN_NPQ 0x0214 | ||
132 | |||
133 | #define REG_RXDMA_AGG_PG_TH 0x0280 | ||
134 | #define REG_RXPKT_NUM 0x0284 | ||
135 | #define REG_RXDMA_STATUS 0x0288 | ||
136 | |||
137 | #define REG_PCIE_CTRL_REG 0x0300 | ||
138 | #define REG_INT_MIG 0x0304 | ||
139 | #define REG_BCNQ_DESA 0x0308 | ||
140 | #define REG_HQ_DESA 0x0310 | ||
141 | #define REG_MGQ_DESA 0x0318 | ||
142 | #define REG_VOQ_DESA 0x0320 | ||
143 | #define REG_VIQ_DESA 0x0328 | ||
144 | #define REG_BEQ_DESA 0x0330 | ||
145 | #define REG_BKQ_DESA 0x0338 | ||
146 | #define REG_RX_DESA 0x0340 | ||
147 | #define REG_DBI 0x0348 | ||
148 | #define REG_MDIO 0x0354 | ||
149 | #define REG_DBG_SEL 0x0360 | ||
150 | #define REG_PCIE_HRPWM 0x0361 | ||
151 | #define REG_PCIE_HCPWM 0x0363 | ||
152 | #define REG_UART_CTRL 0x0364 | ||
153 | #define REG_UART_TX_DESA 0x0370 | ||
154 | #define REG_UART_RX_DESA 0x0378 | ||
155 | |||
156 | #define REG_HDAQ_DESA_NODEF 0x0000 | ||
157 | #define REG_CMDQ_DESA_NODEF 0x0000 | ||
158 | |||
159 | #define REG_VOQ_INFORMATION 0x0400 | ||
160 | #define REG_VIQ_INFORMATION 0x0404 | ||
161 | #define REG_BEQ_INFORMATION 0x0408 | ||
162 | #define REG_BKQ_INFORMATION 0x040C | ||
163 | #define REG_MGQ_INFORMATION 0x0410 | ||
164 | #define REG_HGQ_INFORMATION 0x0414 | ||
165 | #define REG_BCNQ_INFORMATION 0x0418 | ||
166 | |||
167 | #define REG_CPU_MGQ_INFORMATION 0x041C | ||
168 | #define REG_FWHW_TXQ_CTRL 0x0420 | ||
169 | #define REG_HWSEQ_CTRL 0x0423 | ||
170 | #define REG_TXPKTBUF_BCNQ_BDNY 0x0424 | ||
171 | #define REG_TXPKTBUF_MGQ_BDNY 0x0425 | ||
172 | #define REG_MULTI_BCNQ_EN 0x0426 | ||
173 | #define REG_MULTI_BCNQ_OFFSET 0x0427 | ||
174 | #define REG_SPEC_SIFS 0x0428 | ||
175 | #define REG_RL 0x042A | ||
176 | #define REG_DARFRC 0x0430 | ||
177 | #define REG_RARFRC 0x0438 | ||
178 | #define REG_RRSR 0x0440 | ||
179 | #define REG_ARFR0 0x0444 | ||
180 | #define REG_ARFR1 0x0448 | ||
181 | #define REG_ARFR2 0x044C | ||
182 | #define REG_ARFR3 0x0450 | ||
183 | #define REG_AGGLEN_LMT 0x0458 | ||
184 | #define REG_AMPDU_MIN_SPACE 0x045C | ||
185 | #define REG_TXPKTBUF_WMAC_LBK_BF_HD 0x045D | ||
186 | #define REG_FAST_EDCA_CTRL 0x0460 | ||
187 | #define REG_RD_RESP_PKT_TH 0x0463 | ||
188 | #define REG_INIRTS_RATE_SEL 0x0480 | ||
189 | #define REG_INIDATA_RATE_SEL 0x0484 | ||
190 | #define REG_POWER_STATUS 0x04A4 | ||
191 | #define REG_POWER_STAGE1 0x04B4 | ||
192 | #define REG_POWER_STAGE2 0x04B8 | ||
193 | #define REG_PKT_LIFE_TIME 0x04C0 | ||
194 | #define REG_STBC_SETTING 0x04C4 | ||
195 | #define REG_PROT_MODE_CTRL 0x04C8 | ||
196 | #define REG_BAR_MODE_CTRL 0x04CC | ||
197 | #define REG_RA_TRY_RATE_AGG_LMT 0x04CF | ||
198 | #define REG_NQOS_SEQ 0x04DC | ||
199 | #define REG_QOS_SEQ 0x04DE | ||
200 | #define REG_NEED_CPU_HANDLE 0x04E0 | ||
201 | #define REG_PKT_LOSE_RPT 0x04E1 | ||
202 | #define REG_PTCL_ERR_STATUS 0x04E2 | ||
203 | #define REG_DUMMY 0x04FC | ||
204 | |||
205 | #define REG_EDCA_VO_PARAM 0x0500 | ||
206 | #define REG_EDCA_VI_PARAM 0x0504 | ||
207 | #define REG_EDCA_BE_PARAM 0x0508 | ||
208 | #define REG_EDCA_BK_PARAM 0x050C | ||
209 | #define REG_BCNTCFG 0x0510 | ||
210 | #define REG_PIFS 0x0512 | ||
211 | #define REG_RDG_PIFS 0x0513 | ||
212 | #define REG_SIFS_CTX 0x0514 | ||
213 | #define REG_SIFS_TRX 0x0516 | ||
214 | #define REG_AGGR_BREAK_TIME 0x051A | ||
215 | #define REG_SLOT 0x051B | ||
216 | #define REG_TX_PTCL_CTRL 0x0520 | ||
217 | #define REG_TXPAUSE 0x0522 | ||
218 | #define REG_DIS_TXREQ_CLR 0x0523 | ||
219 | #define REG_RD_CTRL 0x0524 | ||
220 | #define REG_TBTT_PROHIBIT 0x0540 | ||
221 | #define REG_RD_NAV_NXT 0x0544 | ||
222 | #define REG_NAV_PROT_LEN 0x0546 | ||
223 | #define REG_BCN_CTRL 0x0550 | ||
224 | #define REG_USTIME_TSF 0x0551 | ||
225 | #define REG_MBID_NUM 0x0552 | ||
226 | #define REG_DUAL_TSF_RST 0x0553 | ||
227 | #define REG_BCN_INTERVAL 0x0554 | ||
228 | #define REG_MBSSID_BCN_SPACE 0x0554 | ||
229 | #define REG_DRVERLYINT 0x0558 | ||
230 | #define REG_BCNDMATIM 0x0559 | ||
231 | #define REG_ATIMWND 0x055A | ||
232 | #define REG_BCN_MAX_ERR 0x055D | ||
233 | #define REG_RXTSF_OFFSET_CCK 0x055E | ||
234 | #define REG_RXTSF_OFFSET_OFDM 0x055F | ||
235 | #define REG_TSFTR 0x0560 | ||
236 | #define REG_INIT_TSFTR 0x0564 | ||
237 | #define REG_PSTIMER 0x0580 | ||
238 | #define REG_TIMER0 0x0584 | ||
239 | #define REG_TIMER1 0x0588 | ||
240 | #define REG_ACMHWCTRL 0x05C0 | ||
241 | #define REG_ACMRSTCTRL 0x05C1 | ||
242 | #define REG_ACMAVG 0x05C2 | ||
243 | #define REG_VO_ADMTIME 0x05C4 | ||
244 | #define REG_VI_ADMTIME 0x05C6 | ||
245 | #define REG_BE_ADMTIME 0x05C8 | ||
246 | #define REG_EDCA_RANDOM_GEN 0x05CC | ||
247 | #define REG_SCH_TXCMD 0x05D0 | ||
248 | |||
249 | #define REG_APSD_CTRL 0x0600 | ||
250 | #define REG_BWOPMODE 0x0603 | ||
251 | #define REG_TCR 0x0604 | ||
252 | #define REG_RCR 0x0608 | ||
253 | #define REG_RX_PKT_LIMIT 0x060C | ||
254 | #define REG_RX_DLK_TIME 0x060D | ||
255 | #define REG_RX_DRVINFO_SZ 0x060F | ||
256 | |||
257 | #define REG_MACID 0x0610 | ||
258 | #define REG_BSSID 0x0618 | ||
259 | #define REG_MAR 0x0620 | ||
260 | #define REG_MBIDCAMCFG 0x0628 | ||
261 | |||
262 | #define REG_USTIME_EDCA 0x0638 | ||
263 | #define REG_MAC_SPEC_SIFS 0x063A | ||
264 | #define REG_RESP_SIFS_CCK 0x063C | ||
265 | #define REG_RESP_SIFS_OFDM 0x063E | ||
266 | #define REG_ACKTO 0x0640 | ||
267 | #define REG_CTS2TO 0x0641 | ||
268 | #define REG_EIFS 0x0642 | ||
269 | |||
270 | #define REG_NAV_CTRL 0x0650 | ||
271 | #define REG_BACAMCMD 0x0654 | ||
272 | #define REG_BACAMCONTENT 0x0658 | ||
273 | #define REG_LBDLY 0x0660 | ||
274 | #define REG_FWDLY 0x0661 | ||
275 | #define REG_RXERR_RPT 0x0664 | ||
276 | #define REG_WMAC_TRXPTCL_CTL 0x0668 | ||
277 | |||
278 | #define REG_CAMCMD 0x0670 | ||
279 | #define REG_CAMWRITE 0x0674 | ||
280 | #define REG_CAMREAD 0x0678 | ||
281 | #define REG_CAMDBG 0x067C | ||
282 | #define REG_SECCFG 0x0680 | ||
283 | |||
284 | #define REG_WOW_CTRL 0x0690 | ||
285 | #define REG_PSSTATUS 0x0691 | ||
286 | #define REG_PS_RX_INFO 0x0692 | ||
287 | #define REG_LPNAV_CTRL 0x0694 | ||
288 | #define REG_WKFMCAM_CMD 0x0698 | ||
289 | #define REG_WKFMCAM_RWD 0x069C | ||
290 | #define REG_RXFLTMAP0 0x06A0 | ||
291 | #define REG_RXFLTMAP1 0x06A2 | ||
292 | #define REG_RXFLTMAP2 0x06A4 | ||
293 | #define REG_BCN_PSR_RPT 0x06A8 | ||
294 | #define REG_CALB32K_CTRL 0x06AC | ||
295 | #define REG_PKT_MON_CTRL 0x06B4 | ||
296 | #define REG_BT_COEX_TABLE 0x06C0 | ||
297 | #define REG_WMAC_RESP_TXINFO 0x06D8 | ||
298 | |||
299 | #define REG_USB_INFO 0xFE17 | ||
300 | #define REG_USB_SPECIAL_OPTION 0xFE55 | ||
301 | #define REG_USB_DMA_AGG_TO 0xFE5B | ||
302 | #define REG_USB_AGG_TO 0xFE5C | ||
303 | #define REG_USB_AGG_TH 0xFE5D | ||
304 | |||
305 | #define REG_TEST_USB_TXQS 0xFE48 | ||
306 | #define REG_TEST_SIE_VID 0xFE60 | ||
307 | #define REG_TEST_SIE_PID 0xFE62 | ||
308 | #define REG_TEST_SIE_OPTIONAL 0xFE64 | ||
309 | #define REG_TEST_SIE_CHIRP_K 0xFE65 | ||
310 | #define REG_TEST_SIE_PHY 0xFE66 | ||
311 | #define REG_TEST_SIE_MAC_ADDR 0xFE70 | ||
312 | #define REG_TEST_SIE_STRING 0xFE80 | ||
313 | |||
314 | #define REG_NORMAL_SIE_VID 0xFE60 | ||
315 | #define REG_NORMAL_SIE_PID 0xFE62 | ||
316 | #define REG_NORMAL_SIE_OPTIONAL 0xFE64 | ||
317 | #define REG_NORMAL_SIE_EP 0xFE65 | ||
318 | #define REG_NORMAL_SIE_PHY 0xFE68 | ||
319 | #define REG_NORMAL_SIE_MAC_ADDR 0xFE70 | ||
320 | #define REG_NORMAL_SIE_STRING 0xFE80 | ||
321 | |||
322 | #define CR9346 REG_9346CR | ||
323 | #define MSR (REG_CR + 2) | ||
324 | #define ISR REG_HISR | ||
325 | #define TSFR REG_TSFTR | ||
326 | |||
327 | #define MACIDR0 REG_MACID | ||
328 | #define MACIDR4 (REG_MACID + 4) | ||
329 | |||
330 | #define PBP REG_PBP | ||
331 | |||
332 | #define IDR0 MACIDR0 | ||
333 | #define IDR4 MACIDR4 | ||
334 | |||
335 | #define UNUSED_REGISTER 0x1BF | ||
336 | #define DCAM UNUSED_REGISTER | ||
337 | #define PSR UNUSED_REGISTER | ||
338 | #define BBADDR UNUSED_REGISTER | ||
339 | #define PHYDATAR UNUSED_REGISTER | ||
340 | |||
341 | #define INVALID_BBRF_VALUE 0x12345678 | ||
342 | |||
343 | #define MAX_MSS_DENSITY_2T 0x13 | ||
344 | #define MAX_MSS_DENSITY_1T 0x0A | ||
345 | |||
346 | #define CMDEEPROM_EN BIT(5) | ||
347 | #define CMDEEPROM_SEL BIT(4) | ||
348 | #define CMD9346CR_9356SEL BIT(4) | ||
349 | #define AUTOLOAD_EEPROM (CMDEEPROM_EN|CMDEEPROM_SEL) | ||
350 | #define AUTOLOAD_EFUSE CMDEEPROM_EN | ||
351 | |||
352 | #define GPIOSEL_GPIO 0 | ||
353 | #define GPIOSEL_ENBT BIT(5) | ||
354 | |||
355 | #define GPIO_IN REG_GPIO_PIN_CTRL | ||
356 | #define GPIO_OUT (REG_GPIO_PIN_CTRL+1) | ||
357 | #define GPIO_IO_SEL (REG_GPIO_PIN_CTRL+2) | ||
358 | #define GPIO_MOD (REG_GPIO_PIN_CTRL+3) | ||
359 | |||
360 | #define MSR_NOLINK 0x00 | ||
361 | #define MSR_ADHOC 0x01 | ||
362 | #define MSR_INFRA 0x02 | ||
363 | #define MSR_AP 0x03 | ||
364 | |||
365 | #define RRSR_RSC_OFFSET 21 | ||
366 | #define RRSR_SHORT_OFFSET 23 | ||
367 | #define RRSR_RSC_BW_40M 0x600000 | ||
368 | #define RRSR_RSC_UPSUBCHNL 0x400000 | ||
369 | #define RRSR_RSC_LOWSUBCHNL 0x200000 | ||
370 | #define RRSR_SHORT 0x800000 | ||
371 | #define RRSR_1M BIT(0) | ||
372 | #define RRSR_2M BIT(1) | ||
373 | #define RRSR_5_5M BIT(2) | ||
374 | #define RRSR_11M BIT(3) | ||
375 | #define RRSR_6M BIT(4) | ||
376 | #define RRSR_9M BIT(5) | ||
377 | #define RRSR_12M BIT(6) | ||
378 | #define RRSR_18M BIT(7) | ||
379 | #define RRSR_24M BIT(8) | ||
380 | #define RRSR_36M BIT(9) | ||
381 | #define RRSR_48M BIT(10) | ||
382 | #define RRSR_54M BIT(11) | ||
383 | #define RRSR_MCS0 BIT(12) | ||
384 | #define RRSR_MCS1 BIT(13) | ||
385 | #define RRSR_MCS2 BIT(14) | ||
386 | #define RRSR_MCS3 BIT(15) | ||
387 | #define RRSR_MCS4 BIT(16) | ||
388 | #define RRSR_MCS5 BIT(17) | ||
389 | #define RRSR_MCS6 BIT(18) | ||
390 | #define RRSR_MCS7 BIT(19) | ||
391 | #define BRSR_ACKSHORTPMB BIT(23) | ||
392 | |||
393 | #define RATR_1M 0x00000001 | ||
394 | #define RATR_2M 0x00000002 | ||
395 | #define RATR_55M 0x00000004 | ||
396 | #define RATR_11M 0x00000008 | ||
397 | #define RATR_6M 0x00000010 | ||
398 | #define RATR_9M 0x00000020 | ||
399 | #define RATR_12M 0x00000040 | ||
400 | #define RATR_18M 0x00000080 | ||
401 | #define RATR_24M 0x00000100 | ||
402 | #define RATR_36M 0x00000200 | ||
403 | #define RATR_48M 0x00000400 | ||
404 | #define RATR_54M 0x00000800 | ||
405 | #define RATR_MCS0 0x00001000 | ||
406 | #define RATR_MCS1 0x00002000 | ||
407 | #define RATR_MCS2 0x00004000 | ||
408 | #define RATR_MCS3 0x00008000 | ||
409 | #define RATR_MCS4 0x00010000 | ||
410 | #define RATR_MCS5 0x00020000 | ||
411 | #define RATR_MCS6 0x00040000 | ||
412 | #define RATR_MCS7 0x00080000 | ||
413 | #define RATR_MCS8 0x00100000 | ||
414 | #define RATR_MCS9 0x00200000 | ||
415 | #define RATR_MCS10 0x00400000 | ||
416 | #define RATR_MCS11 0x00800000 | ||
417 | #define RATR_MCS12 0x01000000 | ||
418 | #define RATR_MCS13 0x02000000 | ||
419 | #define RATR_MCS14 0x04000000 | ||
420 | #define RATR_MCS15 0x08000000 | ||
421 | |||
422 | #define RATE_ALL_CCK (RATR_1M | RATR_2M | RATR_55M | RATR_11M) | ||
423 | #define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | RATR_12M | RATR_18M |\ | ||
424 | RATR_24M | RATR_36M | RATR_48M | RATR_54M) | ||
425 | #define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 |\ | ||
426 | RATR_MCS3 | RATR_MCS4 | RATR_MCS5 |\ | ||
427 | RATR_MCS6 | RATR_MCS7) | ||
428 | #define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 |\ | ||
429 | RATR_MCS11 | RATR_MCS12 | RATR_MCS13 |\ | ||
430 | RATR_MCS14 | RATR_MCS15) | ||
431 | |||
432 | #define BW_OPMODE_20MHZ BIT(2) | ||
433 | #define BW_OPMODE_5G BIT(1) | ||
434 | #define BW_OPMODE_11J BIT(0) | ||
435 | |||
436 | #define CAM_VALID BIT(15) | ||
437 | #define CAM_NOTVALID 0x0000 | ||
438 | #define CAM_USEDK BIT(5) | ||
439 | |||
440 | #define CAM_NONE 0x0 | ||
441 | #define CAM_WEP40 0x01 | ||
442 | #define CAM_TKIP 0x02 | ||
443 | #define CAM_AES 0x04 | ||
444 | #define CAM_WEP104 0x05 | ||
445 | |||
446 | #define TOTAL_CAM_ENTRY 32 | ||
447 | #define HALF_CAM_ENTRY 16 | ||
448 | |||
449 | #define CAM_WRITE BIT(16) | ||
450 | #define CAM_READ 0x00000000 | ||
451 | #define CAM_POLLINIG BIT(31) | ||
452 | |||
453 | #define SCR_USEDK 0x01 | ||
454 | #define SCR_TXSEC_ENABLE 0x02 | ||
455 | #define SCR_RXSEC_ENABLE 0x04 | ||
456 | |||
457 | #define WOW_PMEN BIT(0) | ||
458 | #define WOW_WOMEN BIT(1) | ||
459 | #define WOW_MAGIC BIT(2) | ||
460 | #define WOW_UWF BIT(3) | ||
461 | |||
462 | #define IMR8190_DISABLED 0x0 | ||
463 | #define IMR_BCNDMAINT6 BIT(31) | ||
464 | #define IMR_BCNDMAINT5 BIT(30) | ||
465 | #define IMR_BCNDMAINT4 BIT(29) | ||
466 | #define IMR_BCNDMAINT3 BIT(28) | ||
467 | #define IMR_BCNDMAINT2 BIT(27) | ||
468 | #define IMR_BCNDMAINT1 BIT(26) | ||
469 | #define IMR_BCNDOK8 BIT(25) | ||
470 | #define IMR_BCNDOK7 BIT(24) | ||
471 | #define IMR_BCNDOK6 BIT(23) | ||
472 | #define IMR_BCNDOK5 BIT(22) | ||
473 | #define IMR_BCNDOK4 BIT(21) | ||
474 | #define IMR_BCNDOK3 BIT(20) | ||
475 | #define IMR_BCNDOK2 BIT(19) | ||
476 | #define IMR_BCNDOK1 BIT(18) | ||
477 | #define IMR_TIMEOUT2 BIT(17) | ||
478 | #define IMR_TIMEOUT1 BIT(16) | ||
479 | #define IMR_TXFOVW BIT(15) | ||
480 | #define IMR_PSTIMEOUT BIT(14) | ||
481 | #define IMR_BCNINT BIT(13) | ||
482 | #define IMR_RXFOVW BIT(12) | ||
483 | #define IMR_RDU BIT(11) | ||
484 | #define IMR_ATIMEND BIT(10) | ||
485 | #define IMR_BDOK BIT(9) | ||
486 | #define IMR_HIGHDOK BIT(8) | ||
487 | #define IMR_TBDOK BIT(7) | ||
488 | #define IMR_MGNTDOK BIT(6) | ||
489 | #define IMR_TBDER BIT(5) | ||
490 | #define IMR_BKDOK BIT(4) | ||
491 | #define IMR_BEDOK BIT(3) | ||
492 | #define IMR_VIDOK BIT(2) | ||
493 | #define IMR_VODOK BIT(1) | ||
494 | #define IMR_ROK BIT(0) | ||
495 | |||
496 | #define IMR_TXERR BIT(11) | ||
497 | #define IMR_RXERR BIT(10) | ||
498 | #define IMR_CPWM BIT(8) | ||
499 | #define IMR_OCPINT BIT(1) | ||
500 | #define IMR_WLANOFF BIT(0) | ||
501 | |||
502 | /* 8723E series PCIE Host IMR/ISR bit */ | ||
503 | /* IMR DW0 Bit 0-31 */ | ||
504 | #define PHIMR_TIMEOUT2 BIT(31) | ||
505 | #define PHIMR_TIMEOUT1 BIT(30) | ||
506 | #define PHIMR_PSTIMEOUT BIT(29) | ||
507 | #define PHIMR_GTINT4 BIT(28) | ||
508 | #define PHIMR_GTINT3 BIT(27) | ||
509 | #define PHIMR_TXBCNERR BIT(26) | ||
510 | #define PHIMR_TXBCNOK BIT(25) | ||
511 | #define PHIMR_TSF_BIT32_TOGGLE BIT(24) | ||
512 | #define PHIMR_BCNDMAINT3 BIT(23) | ||
513 | #define PHIMR_BCNDMAINT2 BIT(22) | ||
514 | #define PHIMR_BCNDMAINT1 BIT(21) | ||
515 | #define PHIMR_BCNDMAINT0 BIT(20) | ||
516 | #define PHIMR_BCNDOK3 BIT(19) | ||
517 | #define PHIMR_BCNDOK2 BIT(18) | ||
518 | #define PHIMR_BCNDOK1 BIT(17) | ||
519 | #define PHIMR_BCNDOK0 BIT(16) | ||
520 | #define PHIMR_HSISR_IND_ON BIT(15) | ||
521 | #define PHIMR_BCNDMAINT_E BIT(14) | ||
522 | #define PHIMR_ATIMEND_E BIT(13) | ||
523 | #define PHIMR_ATIM_CTW_END BIT(12) | ||
524 | #define PHIMR_HISRE_IND BIT(11) | ||
525 | #define PHIMR_C2HCMD BIT(10) | ||
526 | #define PHIMR_CPWM2 BIT(9) | ||
527 | #define PHIMR_CPWM BIT(8) | ||
528 | #define PHIMR_HIGHDOK BIT(7) | ||
529 | #define PHIMR_MGNTDOK BIT(6) | ||
530 | #define PHIMR_BKDOK BIT(5) | ||
531 | #define PHIMR_BEDOK BIT(4) | ||
532 | #define PHIMR_VIDOK BIT(3) | ||
533 | #define PHIMR_VODOK BIT(2) | ||
534 | #define PHIMR_RDU BIT(1) | ||
535 | #define PHIMR_ROK BIT(0) | ||
536 | |||
537 | /* PCIE Host Interrupt Status Extension bit */ | ||
538 | #define PHIMR_BCNDMAINT7 BIT(23) | ||
539 | #define PHIMR_BCNDMAINT6 BIT(22) | ||
540 | #define PHIMR_BCNDMAINT5 BIT(21) | ||
541 | #define PHIMR_BCNDMAINT4 BIT(20) | ||
542 | #define PHIMR_BCNDOK7 BIT(19) | ||
543 | #define PHIMR_BCNDOK6 BIT(18) | ||
544 | #define PHIMR_BCNDOK5 BIT(17) | ||
545 | #define PHIMR_BCNDOK4 BIT(16) | ||
546 | /* bit12-15: RSVD */ | ||
547 | #define PHIMR_TXERR BIT(11) | ||
548 | #define PHIMR_RXERR BIT(10) | ||
549 | #define PHIMR_TXFOVW BIT(9) | ||
550 | #define PHIMR_RXFOVW BIT(8) | ||
551 | /* bit2-7: RSV */ | ||
552 | #define PHIMR_OCPINT BIT(1) | ||
553 | |||
554 | #define HWSET_MAX_SIZE 256 | ||
555 | #define EFUSE_MAX_SECTION 32 | ||
556 | #define EFUSE_REAL_CONTENT_LEN 512 | ||
557 | #define EFUSE_OOB_PROTECT_BYTES 15 | ||
558 | |||
559 | #define EEPROM_DEFAULT_TSSI 0x0 | ||
560 | #define EEPROM_DEFAULT_TXPOWERDIFF 0x0 | ||
561 | #define EEPROM_DEFAULT_CRYSTALCAP 0x5 | ||
562 | #define EEPROM_DEFAULT_BOARDTYPE 0x02 | ||
563 | #define EEPROM_DEFAULT_TXPOWER 0x1010 | ||
564 | #define EEPROM_DEFAULT_HT2T_TXPWR 0x10 | ||
565 | |||
566 | #define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3 | ||
567 | #define EEPROM_DEFAULT_THERMALMETER 0x12 | ||
568 | #define EEPROM_DEFAULT_ANTTXPOWERDIFF 0x0 | ||
569 | #define EEPROM_DEFAULT_TXPWDIFF_CRYSTALCAP 0x5 | ||
570 | #define EEPROM_DEFAULT_TXPOWERLEVEL 0x22 | ||
571 | #define EEPROM_DEFAULT_HT40_2SDIFF 0x0 | ||
572 | #define EEPROM_DEFAULT_HT20_DIFF 2 | ||
573 | #define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3 | ||
574 | #define EEPROM_DEFAULT_HT40_PWRMAXOFFSET 0 | ||
575 | #define EEPROM_DEFAULT_HT20_PWRMAXOFFSET 0 | ||
576 | |||
577 | |||
578 | #define EEPROM_DEFAULT_PID 0x1234 | ||
579 | #define EEPROM_DEFAULT_VID 0x5678 | ||
580 | #define EEPROM_DEFAULT_CUSTOMERID 0xAB | ||
581 | #define EEPROM_DEFAULT_SUBCUSTOMERID 0xCD | ||
582 | #define EEPROM_DEFAULT_VERSION 0 | ||
583 | |||
584 | #define EEPROM_CHANNEL_PLAN_FCC 0x0 | ||
585 | #define EEPROM_CHANNEL_PLAN_IC 0x1 | ||
586 | #define EEPROM_CHANNEL_PLAN_ETSI 0x2 | ||
587 | #define EEPROM_CHANNEL_PLAN_SPAIN 0x3 | ||
588 | #define EEPROM_CHANNEL_PLAN_FRANCE 0x4 | ||
589 | #define EEPROM_CHANNEL_PLAN_MKK 0x5 | ||
590 | #define EEPROM_CHANNEL_PLAN_MKK1 0x6 | ||
591 | #define EEPROM_CHANNEL_PLAN_ISRAEL 0x7 | ||
592 | #define EEPROM_CHANNEL_PLAN_TELEC 0x8 | ||
593 | #define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9 | ||
594 | #define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA | ||
595 | #define EEPROM_CHANNEL_PLAN_NCC 0xB | ||
596 | #define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80 | ||
597 | |||
598 | #define EEPROM_CID_DEFAULT 0x0 | ||
599 | #define EEPROM_CID_TOSHIBA 0x4 | ||
600 | #define EEPROM_CID_CCX 0x10 | ||
601 | #define EEPROM_CID_QMI 0x0D | ||
602 | #define EEPROM_CID_WHQL 0xFE | ||
603 | |||
604 | #define RTL8192_EEPROM_ID 0x8129 | ||
605 | |||
606 | #define RTL8190_EEPROM_ID 0x8129 | ||
607 | #define EEPROM_HPON 0x02 | ||
608 | #define EEPROM_CLK 0x06 | ||
609 | #define EEPROM_TESTR 0x08 | ||
610 | |||
611 | #define EEPROM_VID 0x49 | ||
612 | #define EEPROM_DID 0x4B | ||
613 | #define EEPROM_SVID 0x4D | ||
614 | #define EEPROM_SMID 0x4F | ||
615 | |||
616 | #define EEPROM_MAC_ADDR 0x67 | ||
617 | |||
618 | #define EEPROM_CCK_TX_PWR_INX 0x5A | ||
619 | #define EEPROM_HT40_1S_TX_PWR_INX 0x60 | ||
620 | #define EEPROM_HT40_2S_TX_PWR_INX_DIFF 0x66 | ||
621 | #define EEPROM_HT20_TX_PWR_INX_DIFF 0x69 | ||
622 | #define EEPROM_OFDM_TX_PWR_INX_DIFF 0x6C | ||
623 | #define EEPROM_HT40_MAX_PWR_OFFSET 0x25 | ||
624 | #define EEPROM_HT20_MAX_PWR_OFFSET 0x22 | ||
625 | |||
626 | #define EEPROM_THERMAL_METER 0x2a | ||
627 | #define EEPROM_XTAL_K 0x78 | ||
628 | #define EEPROM_RF_OPT1 0x79 | ||
629 | #define EEPROM_RF_OPT2 0x7A | ||
630 | #define EEPROM_RF_OPT3 0x7B | ||
631 | #define EEPROM_RF_OPT4 0x7C | ||
632 | #define EEPROM_CHANNEL_PLAN 0x28 | ||
633 | #define EEPROM_VERSION 0x30 | ||
634 | #define EEPROM_CUSTOMER_ID 0x31 | ||
635 | |||
636 | #define EEPROM_PWRDIFF 0x54 | ||
637 | |||
638 | #define EEPROM_TXPOWERCCK 0x10 | ||
639 | #define EEPROM_TXPOWERHT40_1S 0x16 | ||
640 | #define EEPROM_TXPOWERHT40_2SDIFF 0x66 | ||
641 | #define EEPROM_TXPOWERHT20DIFF 0x1C | ||
642 | #define EEPROM_TXPOWER_OFDMDIFF 0x1F | ||
643 | |||
644 | #define EEPROM_TXPWR_GROUP 0x22 | ||
645 | |||
646 | #define EEPROM_TSSI_A 0x29 | ||
647 | #define EEPROM_TSSI_B 0x77 | ||
648 | |||
649 | #define EEPROM_CHANNELPLAN 0x28 | ||
650 | |||
651 | #define RF_OPTION1 0x2B | ||
652 | #define RF_OPTION2 0x2C | ||
653 | #define RF_OPTION3 0x2D | ||
654 | #define RF_OPTION4 0x2E | ||
655 | |||
656 | #define STOPBECON BIT(6) | ||
657 | #define STOPHIGHT BIT(5) | ||
658 | #define STOPMGT BIT(4) | ||
659 | #define STOPVO BIT(3) | ||
660 | #define STOPVI BIT(2) | ||
661 | #define STOPBE BIT(1) | ||
662 | #define STOPBK BIT(0) | ||
663 | |||
664 | #define RCR_APPFCS BIT(31) | ||
665 | #define RCR_APP_MIC BIT(30) | ||
666 | #define RCR_APP_ICV BIT(29) | ||
667 | #define RCR_APP_PHYST_RXFF BIT(28) | ||
668 | #define RCR_APP_BA_SSN BIT(27) | ||
669 | #define RCR_ENMBID BIT(24) | ||
670 | #define RCR_LSIGEN BIT(23) | ||
671 | #define RCR_MFBEN BIT(22) | ||
672 | #define RCR_HTC_LOC_CTRL BIT(14) | ||
673 | #define RCR_AMF BIT(13) | ||
674 | #define RCR_ACF BIT(12) | ||
675 | #define RCR_ADF BIT(11) | ||
676 | #define RCR_AICV BIT(9) | ||
677 | #define RCR_ACRC32 BIT(8) | ||
678 | #define RCR_CBSSID_BCN BIT(7) | ||
679 | #define RCR_CBSSID_DATA BIT(6) | ||
680 | #define RCR_CBSSID RCR_CBSSID_DATA | ||
681 | #define RCR_APWRMGT BIT(5) | ||
682 | #define RCR_ADD3 BIT(4) | ||
683 | #define RCR_AB BIT(3) | ||
684 | #define RCR_AM BIT(2) | ||
685 | #define RCR_APM BIT(1) | ||
686 | #define RCR_AAP BIT(0) | ||
687 | #define RCR_MXDMA_OFFSET 8 | ||
688 | #define RCR_FIFO_OFFSET 13 | ||
689 | |||
690 | #define RSV_CTRL 0x001C | ||
691 | #define RD_CTRL 0x0524 | ||
692 | |||
693 | #define REG_USB_INFO 0xFE17 | ||
694 | #define REG_USB_SPECIAL_OPTION 0xFE55 | ||
695 | #define REG_USB_DMA_AGG_TO 0xFE5B | ||
696 | #define REG_USB_AGG_TO 0xFE5C | ||
697 | #define REG_USB_AGG_TH 0xFE5D | ||
698 | |||
699 | #define REG_USB_VID 0xFE60 | ||
700 | #define REG_USB_PID 0xFE62 | ||
701 | #define REG_USB_OPTIONAL 0xFE64 | ||
702 | #define REG_USB_CHIRP_K 0xFE65 | ||
703 | #define REG_USB_PHY 0xFE66 | ||
704 | #define REG_USB_MAC_ADDR 0xFE70 | ||
705 | #define REG_USB_HRPWM 0xFE58 | ||
706 | #define REG_USB_HCPWM 0xFE57 | ||
707 | |||
708 | #define SW18_FPWM BIT(3) | ||
709 | |||
710 | #define ISO_MD2PP BIT(0) | ||
711 | #define ISO_UA2USB BIT(1) | ||
712 | #define ISO_UD2CORE BIT(2) | ||
713 | #define ISO_PA2PCIE BIT(3) | ||
714 | #define ISO_PD2CORE BIT(4) | ||
715 | #define ISO_IP2MAC BIT(5) | ||
716 | #define ISO_DIOP BIT(6) | ||
717 | #define ISO_DIOE BIT(7) | ||
718 | #define ISO_EB2CORE BIT(8) | ||
719 | #define ISO_DIOR BIT(9) | ||
720 | |||
721 | #define PWC_EV25V BIT(14) | ||
722 | #define PWC_EV12V BIT(15) | ||
723 | |||
724 | #define FEN_BBRSTB BIT(0) | ||
725 | #define FEN_BB_GLB_RSTn BIT(1) | ||
726 | #define FEN_USBA BIT(2) | ||
727 | #define FEN_UPLL BIT(3) | ||
728 | #define FEN_USBD BIT(4) | ||
729 | #define FEN_DIO_PCIE BIT(5) | ||
730 | #define FEN_PCIEA BIT(6) | ||
731 | #define FEN_PPLL BIT(7) | ||
732 | #define FEN_PCIED BIT(8) | ||
733 | #define FEN_DIOE BIT(9) | ||
734 | #define FEN_CPUEN BIT(10) | ||
735 | #define FEN_DCORE BIT(11) | ||
736 | #define FEN_ELDR BIT(12) | ||
737 | #define FEN_DIO_RF BIT(13) | ||
738 | #define FEN_HWPDN BIT(14) | ||
739 | #define FEN_MREGEN BIT(15) | ||
740 | |||
741 | #define PFM_LDALL BIT(0) | ||
742 | #define PFM_ALDN BIT(1) | ||
743 | #define PFM_LDKP BIT(2) | ||
744 | #define PFM_WOWL BIT(3) | ||
745 | #define EnPDN BIT(4) | ||
746 | #define PDN_PL BIT(5) | ||
747 | #define APFM_ONMAC BIT(8) | ||
748 | #define APFM_OFF BIT(9) | ||
749 | #define APFM_RSM BIT(10) | ||
750 | #define AFSM_HSUS BIT(11) | ||
751 | #define AFSM_PCIE BIT(12) | ||
752 | #define APDM_MAC BIT(13) | ||
753 | #define APDM_HOST BIT(14) | ||
754 | #define APDM_HPDN BIT(15) | ||
755 | #define RDY_MACON BIT(16) | ||
756 | #define SUS_HOST BIT(17) | ||
757 | #define ROP_ALD BIT(20) | ||
758 | #define ROP_PWR BIT(21) | ||
759 | #define ROP_SPS BIT(22) | ||
760 | #define SOP_MRST BIT(25) | ||
761 | #define SOP_FUSE BIT(26) | ||
762 | #define SOP_ABG BIT(27) | ||
763 | #define SOP_AMB BIT(28) | ||
764 | #define SOP_RCK BIT(29) | ||
765 | #define SOP_A8M BIT(30) | ||
766 | #define XOP_BTCK BIT(31) | ||
767 | |||
768 | #define ANAD16V_EN BIT(0) | ||
769 | #define ANA8M BIT(1) | ||
770 | #define MACSLP BIT(4) | ||
771 | #define LOADER_CLK_EN BIT(5) | ||
772 | #define _80M_SSC_DIS BIT(7) | ||
773 | #define _80M_SSC_EN_HO BIT(8) | ||
774 | #define PHY_SSC_RSTB BIT(9) | ||
775 | #define SEC_CLK_EN BIT(10) | ||
776 | #define MAC_CLK_EN BIT(11) | ||
777 | #define SYS_CLK_EN BIT(12) | ||
778 | #define RING_CLK_EN BIT(13) | ||
779 | |||
780 | #define BOOT_FROM_EEPROM BIT(4) | ||
781 | #define EEPROM_EN BIT(5) | ||
782 | |||
783 | #define AFE_BGEN BIT(0) | ||
784 | #define AFE_MBEN BIT(1) | ||
785 | #define MAC_ID_EN BIT(7) | ||
786 | |||
787 | #define WLOCK_ALL BIT(0) | ||
788 | #define WLOCK_00 BIT(1) | ||
789 | #define WLOCK_04 BIT(2) | ||
790 | #define WLOCK_08 BIT(3) | ||
791 | #define WLOCK_40 BIT(4) | ||
792 | #define R_DIS_PRST_0 BIT(5) | ||
793 | #define R_DIS_PRST_1 BIT(6) | ||
794 | #define LOCK_ALL_EN BIT(7) | ||
795 | |||
796 | #define RF_EN BIT(0) | ||
797 | #define RF_RSTB BIT(1) | ||
798 | #define RF_SDMRSTB BIT(2) | ||
799 | |||
800 | #define LDA15_EN BIT(0) | ||
801 | #define LDA15_STBY BIT(1) | ||
802 | #define LDA15_OBUF BIT(2) | ||
803 | #define LDA15_REG_VOS BIT(3) | ||
804 | #define _LDA15_VOADJ(x) (((x) & 0x7) << 4) | ||
805 | |||
806 | #define LDV12_EN BIT(0) | ||
807 | #define LDV12_SDBY BIT(1) | ||
808 | #define LPLDO_HSM BIT(2) | ||
809 | #define LPLDO_LSM_DIS BIT(3) | ||
810 | #define _LDV12_VADJ(x) (((x) & 0xF) << 4) | ||
811 | |||
812 | #define XTAL_EN BIT(0) | ||
813 | #define XTAL_BSEL BIT(1) | ||
814 | #define _XTAL_BOSC(x) (((x) & 0x3) << 2) | ||
815 | #define _XTAL_CADJ(x) (((x) & 0xF) << 4) | ||
816 | #define XTAL_GATE_USB BIT(8) | ||
817 | #define _XTAL_USB_DRV(x) (((x) & 0x3) << 9) | ||
818 | #define XTAL_GATE_AFE BIT(11) | ||
819 | #define _XTAL_AFE_DRV(x) (((x) & 0x3) << 12) | ||
820 | #define XTAL_RF_GATE BIT(14) | ||
821 | #define _XTAL_RF_DRV(x) (((x) & 0x3) << 15) | ||
822 | #define XTAL_GATE_DIG BIT(17) | ||
823 | #define _XTAL_DIG_DRV(x) (((x) & 0x3) << 18) | ||
824 | #define XTAL_BT_GATE BIT(20) | ||
825 | #define _XTAL_BT_DRV(x) (((x) & 0x3) << 21) | ||
826 | #define _XTAL_GPIO(x) (((x) & 0x7) << 23) | ||
827 | |||
828 | #define CKDLY_AFE BIT(26) | ||
829 | #define CKDLY_USB BIT(27) | ||
830 | #define CKDLY_DIG BIT(28) | ||
831 | #define CKDLY_BT BIT(29) | ||
832 | |||
833 | #define APLL_EN BIT(0) | ||
834 | #define APLL_320_EN BIT(1) | ||
835 | #define APLL_FREF_SEL BIT(2) | ||
836 | #define APLL_EDGE_SEL BIT(3) | ||
837 | #define APLL_WDOGB BIT(4) | ||
838 | #define APLL_LPFEN BIT(5) | ||
839 | |||
840 | #define APLL_REF_CLK_13MHZ 0x1 | ||
841 | #define APLL_REF_CLK_19_2MHZ 0x2 | ||
842 | #define APLL_REF_CLK_20MHZ 0x3 | ||
843 | #define APLL_REF_CLK_25MHZ 0x4 | ||
844 | #define APLL_REF_CLK_26MHZ 0x5 | ||
845 | #define APLL_REF_CLK_38_4MHZ 0x6 | ||
846 | #define APLL_REF_CLK_40MHZ 0x7 | ||
847 | |||
848 | #define APLL_320EN BIT(14) | ||
849 | #define APLL_80EN BIT(15) | ||
850 | #define APLL_1MEN BIT(24) | ||
851 | |||
852 | #define ALD_EN BIT(18) | ||
853 | #define EF_PD BIT(19) | ||
854 | #define EF_FLAG BIT(31) | ||
855 | |||
856 | #define EF_TRPT BIT(7) | ||
857 | #define LDOE25_EN BIT(31) | ||
858 | |||
859 | #define RSM_EN BIT(0) | ||
860 | #define Timer_EN BIT(4) | ||
861 | |||
862 | #define TRSW0EN BIT(2) | ||
863 | #define TRSW1EN BIT(3) | ||
864 | #define EROM_EN BIT(4) | ||
865 | #define EnBT BIT(5) | ||
866 | #define EnUart BIT(8) | ||
867 | #define Uart_910 BIT(9) | ||
868 | #define EnPMAC BIT(10) | ||
869 | #define SIC_SWRST BIT(11) | ||
870 | #define EnSIC BIT(12) | ||
871 | #define SIC_23 BIT(13) | ||
872 | #define EnHDP BIT(14) | ||
873 | #define SIC_LBK BIT(15) | ||
874 | |||
875 | #define LED0PL BIT(4) | ||
876 | #define LED1PL BIT(12) | ||
877 | #define LED0DIS BIT(7) | ||
878 | |||
879 | #define MCUFWDL_EN BIT(0) | ||
880 | #define MCUFWDL_RDY BIT(1) | ||
881 | #define FWDL_ChkSum_rpt BIT(2) | ||
882 | #define MACINI_RDY BIT(3) | ||
883 | #define BBINI_RDY BIT(4) | ||
884 | #define RFINI_RDY BIT(5) | ||
885 | #define WINTINI_RDY BIT(6) | ||
886 | #define CPRST BIT(23) | ||
887 | |||
888 | #define XCLK_VLD BIT(0) | ||
889 | #define ACLK_VLD BIT(1) | ||
890 | #define UCLK_VLD BIT(2) | ||
891 | #define PCLK_VLD BIT(3) | ||
892 | #define PCIRSTB BIT(4) | ||
893 | #define V15_VLD BIT(5) | ||
894 | #define TRP_B15V_EN BIT(7) | ||
895 | #define SIC_IDLE BIT(8) | ||
896 | #define BD_MAC2 BIT(9) | ||
897 | #define BD_MAC1 BIT(10) | ||
898 | #define IC_MACPHY_MODE BIT(11) | ||
899 | #define BT_FUNC BIT(16) | ||
900 | #define VENDOR_ID BIT(19) | ||
901 | #define PAD_HWPD_IDN BIT(22) | ||
902 | #define TRP_VAUX_EN BIT(23) | ||
903 | #define TRP_BT_EN BIT(24) | ||
904 | #define BD_PKG_SEL BIT(25) | ||
905 | #define BD_HCI_SEL BIT(26) | ||
906 | #define TYPE_ID BIT(27) | ||
907 | |||
908 | #define CHIP_VER_RTL_MASK 0xF000 | ||
909 | #define CHIP_VER_RTL_SHIFT 12 | ||
910 | |||
911 | #define REG_LBMODE (REG_CR + 3) | ||
912 | |||
913 | #define HCI_TXDMA_EN BIT(0) | ||
914 | #define HCI_RXDMA_EN BIT(1) | ||
915 | #define TXDMA_EN BIT(2) | ||
916 | #define RXDMA_EN BIT(3) | ||
917 | #define PROTOCOL_EN BIT(4) | ||
918 | #define SCHEDULE_EN BIT(5) | ||
919 | #define MACTXEN BIT(6) | ||
920 | #define MACRXEN BIT(7) | ||
921 | #define ENSWBCN BIT(8) | ||
922 | #define ENSEC BIT(9) | ||
923 | |||
924 | #define _NETTYPE(x) (((x) & 0x3) << 16) | ||
925 | #define MASK_NETTYPE 0x30000 | ||
926 | #define NT_NO_LINK 0x0 | ||
927 | #define NT_LINK_AD_HOC 0x1 | ||
928 | #define NT_LINK_AP 0x2 | ||
929 | #define NT_AS_AP 0x3 | ||
930 | |||
931 | #define _LBMODE(x) (((x) & 0xF) << 24) | ||
932 | #define MASK_LBMODE 0xF000000 | ||
933 | #define LOOPBACK_NORMAL 0x0 | ||
934 | #define LOOPBACK_IMMEDIATELY 0xB | ||
935 | #define LOOPBACK_MAC_DELAY 0x3 | ||
936 | #define LOOPBACK_PHY 0x1 | ||
937 | #define LOOPBACK_DMA 0x7 | ||
938 | |||
939 | #define GET_RX_PAGE_SIZE(value) ((value) & 0xF) | ||
940 | #define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4) | ||
941 | #define _PSRX_MASK 0xF | ||
942 | #define _PSTX_MASK 0xF0 | ||
943 | #define _PSRX(x) (x) | ||
944 | #define _PSTX(x) ((x) << 4) | ||
945 | |||
946 | #define PBP_64 0x0 | ||
947 | #define PBP_128 0x1 | ||
948 | #define PBP_256 0x2 | ||
949 | #define PBP_512 0x3 | ||
950 | #define PBP_1024 0x4 | ||
951 | |||
952 | #define RXDMA_ARBBW_EN BIT(0) | ||
953 | #define RXSHFT_EN BIT(1) | ||
954 | #define RXDMA_AGG_EN BIT(2) | ||
955 | #define QS_VO_QUEUE BIT(8) | ||
956 | #define QS_VI_QUEUE BIT(9) | ||
957 | #define QS_BE_QUEUE BIT(10) | ||
958 | #define QS_BK_QUEUE BIT(11) | ||
959 | #define QS_MANAGER_QUEUE BIT(12) | ||
960 | #define QS_HIGH_QUEUE BIT(13) | ||
961 | |||
962 | #define HQSEL_VOQ BIT(0) | ||
963 | #define HQSEL_VIQ BIT(1) | ||
964 | #define HQSEL_BEQ BIT(2) | ||
965 | #define HQSEL_BKQ BIT(3) | ||
966 | #define HQSEL_MGTQ BIT(4) | ||
967 | #define HQSEL_HIQ BIT(5) | ||
968 | |||
969 | #define _TXDMA_HIQ_MAP(x) (((x)&0x3) << 14) | ||
970 | #define _TXDMA_MGQ_MAP(x) (((x)&0x3) << 12) | ||
971 | #define _TXDMA_BKQ_MAP(x) (((x)&0x3) << 10) | ||
972 | #define _TXDMA_BEQ_MAP(x) (((x)&0x3) << 8) | ||
973 | #define _TXDMA_VIQ_MAP(x) (((x)&0x3) << 6) | ||
974 | #define _TXDMA_VOQ_MAP(x) (((x)&0x3) << 4) | ||
975 | |||
976 | #define QUEUE_LOW 1 | ||
977 | #define QUEUE_NORMAL 2 | ||
978 | #define QUEUE_HIGH 3 | ||
979 | |||
980 | #define _LLT_NO_ACTIVE 0x0 | ||
981 | #define _LLT_WRITE_ACCESS 0x1 | ||
982 | #define _LLT_READ_ACCESS 0x2 | ||
983 | |||
984 | #define _LLT_INIT_DATA(x) ((x) & 0xFF) | ||
985 | #define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8) | ||
986 | #define _LLT_OP(x) (((x) & 0x3) << 30) | ||
987 | #define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3) | ||
988 | |||
989 | #define BB_WRITE_READ_MASK (BIT(31) | BIT(30)) | ||
990 | #define BB_WRITE_EN BIT(30) | ||
991 | #define BB_READ_EN BIT(31) | ||
992 | |||
993 | #define _HPQ(x) ((x) & 0xFF) | ||
994 | #define _LPQ(x) (((x) & 0xFF) << 8) | ||
995 | #define _PUBQ(x) (((x) & 0xFF) << 16) | ||
996 | #define _NPQ(x) ((x) & 0xFF) | ||
997 | |||
998 | #define HPQ_PUBLIC_DIS BIT(24) | ||
999 | #define LPQ_PUBLIC_DIS BIT(25) | ||
1000 | #define LD_RQPN BIT(31) | ||
1001 | |||
1002 | #define BCN_VALID BIT(16) | ||
1003 | #define BCN_HEAD(x) (((x) & 0xFF) << 8) | ||
1004 | #define BCN_HEAD_MASK 0xFF00 | ||
1005 | |||
1006 | #define BLK_DESC_NUM_SHIFT 4 | ||
1007 | #define BLK_DESC_NUM_MASK 0xF | ||
1008 | |||
1009 | #define DROP_DATA_EN BIT(9) | ||
1010 | |||
1011 | #define EN_AMPDU_RTY_NEW BIT(7) | ||
1012 | |||
1013 | #define _INIRTSMCS_SEL(x) ((x) & 0x3F) | ||
1014 | |||
1015 | #define _SPEC_SIFS_CCK(x) ((x) & 0xFF) | ||
1016 | #define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8) | ||
1017 | |||
1018 | #define RATE_REG_BITMAP_ALL 0xFFFFF | ||
1019 | |||
1020 | #define _RRSC_BITMAP(x) ((x) & 0xFFFFF) | ||
1021 | |||
1022 | #define _RRSR_RSC(x) (((x) & 0x3) << 21) | ||
1023 | #define RRSR_RSC_RESERVED 0x0 | ||
1024 | #define RRSR_RSC_UPPER_SUBCHANNEL 0x1 | ||
1025 | #define RRSR_RSC_LOWER_SUBCHANNEL 0x2 | ||
1026 | #define RRSR_RSC_DUPLICATE_MODE 0x3 | ||
1027 | |||
1028 | #define USE_SHORT_G1 BIT(20) | ||
1029 | |||
1030 | #define _AGGLMT_MCS0(x) ((x) & 0xF) | ||
1031 | #define _AGGLMT_MCS1(x) (((x) & 0xF) << 4) | ||
1032 | #define _AGGLMT_MCS2(x) (((x) & 0xF) << 8) | ||
1033 | #define _AGGLMT_MCS3(x) (((x) & 0xF) << 12) | ||
1034 | #define _AGGLMT_MCS4(x) (((x) & 0xF) << 16) | ||
1035 | #define _AGGLMT_MCS5(x) (((x) & 0xF) << 20) | ||
1036 | #define _AGGLMT_MCS6(x) (((x) & 0xF) << 24) | ||
1037 | #define _AGGLMT_MCS7(x) (((x) & 0xF) << 28) | ||
1038 | |||
1039 | #define RETRY_LIMIT_SHORT_SHIFT 8 | ||
1040 | #define RETRY_LIMIT_LONG_SHIFT 0 | ||
1041 | |||
1042 | #define _DARF_RC1(x) ((x) & 0x1F) | ||
1043 | #define _DARF_RC2(x) (((x) & 0x1F) << 8) | ||
1044 | #define _DARF_RC3(x) (((x) & 0x1F) << 16) | ||
1045 | #define _DARF_RC4(x) (((x) & 0x1F) << 24) | ||
1046 | #define _DARF_RC5(x) ((x) & 0x1F) | ||
1047 | #define _DARF_RC6(x) (((x) & 0x1F) << 8) | ||
1048 | #define _DARF_RC7(x) (((x) & 0x1F) << 16) | ||
1049 | #define _DARF_RC8(x) (((x) & 0x1F) << 24) | ||
1050 | |||
1051 | #define _RARF_RC1(x) ((x) & 0x1F) | ||
1052 | #define _RARF_RC2(x) (((x) & 0x1F) << 8) | ||
1053 | #define _RARF_RC3(x) (((x) & 0x1F) << 16) | ||
1054 | #define _RARF_RC4(x) (((x) & 0x1F) << 24) | ||
1055 | #define _RARF_RC5(x) ((x) & 0x1F) | ||
1056 | #define _RARF_RC6(x) (((x) & 0x1F) << 8) | ||
1057 | #define _RARF_RC7(x) (((x) & 0x1F) << 16) | ||
1058 | #define _RARF_RC8(x) (((x) & 0x1F) << 24) | ||
1059 | |||
1060 | #define AC_PARAM_TXOP_LIMIT_OFFSET 16 | ||
1061 | #define AC_PARAM_ECW_MAX_OFFSET 12 | ||
1062 | #define AC_PARAM_ECW_MIN_OFFSET 8 | ||
1063 | #define AC_PARAM_AIFS_OFFSET 0 | ||
1064 | |||
1065 | #define _AIFS(x) (x) | ||
1066 | #define _ECW_MAX_MIN(x) ((x) << 8) | ||
1067 | #define _TXOP_LIMIT(x) ((x) << 16) | ||
1068 | |||
1069 | #define _BCNIFS(x) ((x) & 0xFF) | ||
1070 | #define _BCNECW(x) ((((x) & 0xF)) << 8) | ||
1071 | |||
1072 | #define _LRL(x) ((x) & 0x3F) | ||
1073 | #define _SRL(x) (((x) & 0x3F) << 8) | ||
1074 | |||
1075 | #define _SIFS_CCK_CTX(x) ((x) & 0xFF) | ||
1076 | #define _SIFS_CCK_TRX(x) (((x) & 0xFF) << 8); | ||
1077 | |||
1078 | #define _SIFS_OFDM_CTX(x) ((x) & 0xFF) | ||
1079 | #define _SIFS_OFDM_TRX(x) (((x) & 0xFF) << 8); | ||
1080 | |||
1081 | #define _TBTT_PROHIBIT_HOLD(x) (((x) & 0xFF) << 8) | ||
1082 | |||
1083 | #define DIS_EDCA_CNT_DWN BIT(11) | ||
1084 | |||
1085 | #define EN_MBSSID BIT(1) | ||
1086 | #define EN_TXBCN_RPT BIT(2) | ||
1087 | #define EN_BCN_FUNCTION BIT(3) | ||
1088 | |||
1089 | #define TSFTR_RST BIT(0) | ||
1090 | #define TSFTR1_RST BIT(1) | ||
1091 | |||
1092 | #define STOP_BCNQ BIT(6) | ||
1093 | |||
1094 | #define DIS_TSF_UDT0_NORMAL_CHIP BIT(4) | ||
1095 | #define DIS_TSF_UDT0_TEST_CHIP BIT(5) | ||
1096 | |||
1097 | #define AcmHw_HwEn BIT(0) | ||
1098 | #define AcmHw_BeqEn BIT(1) | ||
1099 | #define AcmHw_ViqEn BIT(2) | ||
1100 | #define AcmHw_VoqEn BIT(3) | ||
1101 | #define AcmHw_BeqStatus BIT(4) | ||
1102 | #define AcmHw_ViqStatus BIT(5) | ||
1103 | #define AcmHw_VoqStatus BIT(6) | ||
1104 | |||
1105 | #define APSDOFF BIT(6) | ||
1106 | #define APSDOFF_STATUS BIT(7) | ||
1107 | |||
1108 | #define BW_20MHZ BIT(2) | ||
1109 | |||
1110 | #define RATE_BITMAP_ALL 0xFFFFF | ||
1111 | |||
1112 | #define RATE_RRSR_CCK_ONLY_1M 0xFFFF1 | ||
1113 | |||
1114 | #define TSFRST BIT(0) | ||
1115 | #define DIS_GCLK BIT(1) | ||
1116 | #define PAD_SEL BIT(2) | ||
1117 | #define PWR_ST BIT(6) | ||
1118 | #define PWRBIT_OW_EN BIT(7) | ||
1119 | #define ACRC BIT(8) | ||
1120 | #define CFENDFORM BIT(9) | ||
1121 | #define ICV BIT(10) | ||
1122 | |||
1123 | #define AAP BIT(0) | ||
1124 | #define APM BIT(1) | ||
1125 | #define AM BIT(2) | ||
1126 | #define AB BIT(3) | ||
1127 | #define ADD3 BIT(4) | ||
1128 | #define APWRMGT BIT(5) | ||
1129 | #define CBSSID BIT(6) | ||
1130 | #define CBSSID_DATA BIT(6) | ||
1131 | #define CBSSID_BCN BIT(7) | ||
1132 | #define ACRC32 BIT(8) | ||
1133 | #define AICV BIT(9) | ||
1134 | #define ADF BIT(11) | ||
1135 | #define ACF BIT(12) | ||
1136 | #define AMF BIT(13) | ||
1137 | #define HTC_LOC_CTRL BIT(14) | ||
1138 | #define UC_DATA_EN BIT(16) | ||
1139 | #define BM_DATA_EN BIT(17) | ||
1140 | #define MFBEN BIT(22) | ||
1141 | #define LSIGEN BIT(23) | ||
1142 | #define EnMBID BIT(24) | ||
1143 | #define APP_BASSN BIT(27) | ||
1144 | #define APP_PHYSTS BIT(28) | ||
1145 | #define APP_ICV BIT(29) | ||
1146 | #define APP_MIC BIT(30) | ||
1147 | #define APP_FCS BIT(31) | ||
1148 | |||
1149 | #define _MIN_SPACE(x) ((x) & 0x7) | ||
1150 | #define _SHORT_GI_PADDING(x) (((x) & 0x1F) << 3) | ||
1151 | |||
1152 | #define RXERR_TYPE_OFDM_PPDU 0 | ||
1153 | #define RXERR_TYPE_OFDM_FALSE_ALARM 1 | ||
1154 | #define RXERR_TYPE_OFDM_MPDU_OK 2 | ||
1155 | #define RXERR_TYPE_OFDM_MPDU_FAIL 3 | ||
1156 | #define RXERR_TYPE_CCK_PPDU 4 | ||
1157 | #define RXERR_TYPE_CCK_FALSE_ALARM 5 | ||
1158 | #define RXERR_TYPE_CCK_MPDU_OK 6 | ||
1159 | #define RXERR_TYPE_CCK_MPDU_FAIL 7 | ||
1160 | #define RXERR_TYPE_HT_PPDU 8 | ||
1161 | #define RXERR_TYPE_HT_FALSE_ALARM 9 | ||
1162 | #define RXERR_TYPE_HT_MPDU_TOTAL 10 | ||
1163 | #define RXERR_TYPE_HT_MPDU_OK 11 | ||
1164 | #define RXERR_TYPE_HT_MPDU_FAIL 12 | ||
1165 | #define RXERR_TYPE_RX_FULL_DROP 15 | ||
1166 | |||
1167 | #define RXERR_COUNTER_MASK 0xFFFFF | ||
1168 | #define RXERR_RPT_RST BIT(27) | ||
1169 | #define _RXERR_RPT_SEL(type) ((type) << 28) | ||
1170 | |||
1171 | #define SCR_TxUseDK BIT(0) | ||
1172 | #define SCR_RxUseDK BIT(1) | ||
1173 | #define SCR_TxEncEnable BIT(2) | ||
1174 | #define SCR_RxDecEnable BIT(3) | ||
1175 | #define SCR_SKByA2 BIT(4) | ||
1176 | #define SCR_NoSKMC BIT(5) | ||
1177 | #define SCR_TXBCUSEDK BIT(6) | ||
1178 | #define SCR_RXBCUSEDK BIT(7) | ||
1179 | |||
1180 | #define USB_IS_HIGH_SPEED 0 | ||
1181 | #define USB_IS_FULL_SPEED 1 | ||
1182 | #define USB_SPEED_MASK BIT(5) | ||
1183 | |||
1184 | #define USB_NORMAL_SIE_EP_MASK 0xF | ||
1185 | #define USB_NORMAL_SIE_EP_SHIFT 4 | ||
1186 | |||
1187 | #define USB_TEST_EP_MASK 0x30 | ||
1188 | #define USB_TEST_EP_SHIFT 4 | ||
1189 | |||
1190 | #define USB_AGG_EN BIT(3) | ||
1191 | |||
1192 | #define MAC_ADDR_LEN 6 | ||
1193 | #define LAST_ENTRY_OF_TX_PKT_BUFFER 255 | ||
1194 | |||
1195 | #define POLLING_LLT_THRESHOLD 20 | ||
1196 | #define POLLING_READY_TIMEOUT_COUNT 1000 | ||
1197 | |||
1198 | #define MAX_MSS_DENSITY_2T 0x13 | ||
1199 | #define MAX_MSS_DENSITY_1T 0x0A | ||
1200 | |||
1201 | #define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6)) | ||
1202 | #define EPROM_CMD_CONFIG 0x3 | ||
1203 | #define EPROM_CMD_LOAD 1 | ||
1204 | |||
1205 | #define HWSET_MAX_SIZE_92S HWSET_MAX_SIZE | ||
1206 | |||
1207 | #define HAL_8192C_HW_GPIO_WPS_BIT BIT(2) | ||
1208 | |||
1209 | #define RPMAC_RESET 0x100 | ||
1210 | #define RPMAC_TXSTART 0x104 | ||
1211 | #define RPMAC_TXLEGACYSIG 0x108 | ||
1212 | #define RPMAC_TXHTSIG1 0x10c | ||
1213 | #define RPMAC_TXHTSIG2 0x110 | ||
1214 | #define RPMAC_PHYDEBUG 0x114 | ||
1215 | #define RPMAC_TXPACKETNUM 0x118 | ||
1216 | #define RPMAC_TXIDLE 0x11c | ||
1217 | #define RPMAC_TXMACHEADER0 0x120 | ||
1218 | #define RPMAC_TXMACHEADER1 0x124 | ||
1219 | #define RPMAC_TXMACHEADER2 0x128 | ||
1220 | #define RPMAC_TXMACHEADER3 0x12c | ||
1221 | #define RPMAC_TXMACHEADER4 0x130 | ||
1222 | #define RPMAC_TXMACHEADER5 0x134 | ||
1223 | #define RPMAC_TXDADATYPE 0x138 | ||
1224 | #define RPMAC_TXRANDOMSEED 0x13c | ||
1225 | #define RPMAC_CCKPLCPPREAMBLE 0x140 | ||
1226 | #define RPMAC_CCKPLCPHEADER 0x144 | ||
1227 | #define RPMAC_CCKCRC16 0x148 | ||
1228 | #define RPMAC_OFDMRXCRC32OK 0x170 | ||
1229 | #define RPMAC_OFDMRXCRC32Er 0x174 | ||
1230 | #define RPMAC_OFDMRXPARITYER 0x178 | ||
1231 | #define RPMAC_OFDMRXCRC8ER 0x17c | ||
1232 | #define RPMAC_CCKCRXRC16ER 0x180 | ||
1233 | #define RPMAC_CCKCRXRC32ER 0x184 | ||
1234 | #define RPMAC_CCKCRXRC32OK 0x188 | ||
1235 | #define RPMAC_TXSTATUS 0x18c | ||
1236 | |||
1237 | #define RFPGA0_RFMOD 0x800 | ||
1238 | |||
1239 | #define RFPGA0_TXINFO 0x804 | ||
1240 | #define RFPGA0_PSDFUNCTION 0x808 | ||
1241 | |||
1242 | #define RFPGA0_TXGAINSTAGE 0x80c | ||
1243 | |||
1244 | #define RFPGA0_RFTIMING1 0x810 | ||
1245 | #define RFPGA0_RFTIMING2 0x814 | ||
1246 | |||
1247 | #define RFPGA0_XA_HSSIPARAMETER1 0x820 | ||
1248 | #define RFPGA0_XA_HSSIPARAMETER2 0x824 | ||
1249 | #define RFPGA0_XB_HSSIPARAMETER1 0x828 | ||
1250 | #define RFPGA0_XB_HSSIPARAMETER2 0x82c | ||
1251 | |||
1252 | #define RFPGA0_XA_LSSIPARAMETER 0x840 | ||
1253 | #define RFPGA0_XB_LSSIPARAMETER 0x844 | ||
1254 | |||
1255 | #define RFPGA0_RFWAKEUPPARAMETER 0x850 | ||
1256 | #define RFPGA0_RFSLEEPUPPARAMETER 0x854 | ||
1257 | |||
1258 | #define RFPGA0_XAB_SWITCHCONTROL 0x858 | ||
1259 | #define RFPGA0_XCD_SWITCHCONTROL 0x85c | ||
1260 | |||
1261 | #define RFPGA0_XA_RFINTERFACEOE 0x860 | ||
1262 | #define RFPGA0_XB_RFINTERFACEOE 0x864 | ||
1263 | |||
1264 | #define RFPGA0_XAB_RFINTERFACESW 0x870 | ||
1265 | #define RFPGA0_XCD_RFINTERFACESW 0x874 | ||
1266 | |||
1267 | #define rFPGA0_XAB_RFPARAMETER 0x878 | ||
1268 | #define rFPGA0_XCD_RFPARAMETER 0x87c | ||
1269 | |||
1270 | #define RFPGA0_ANALOGPARAMETER1 0x880 | ||
1271 | #define RFPGA0_ANALOGPARAMETER2 0x884 | ||
1272 | #define RFPGA0_ANALOGPARAMETER3 0x888 | ||
1273 | #define RFPGA0_ANALOGPARAMETER4 0x88c | ||
1274 | |||
1275 | #define RFPGA0_XA_LSSIREADBACK 0x8a0 | ||
1276 | #define RFPGA0_XB_LSSIREADBACK 0x8a4 | ||
1277 | #define RFPGA0_XC_LSSIREADBACK 0x8a8 | ||
1278 | #define RFPGA0_XD_LSSIREADBACK 0x8ac | ||
1279 | |||
1280 | #define RFPGA0_PSDREPORT 0x8b4 | ||
1281 | #define TRANSCEIVEA_HSPI_READBACK 0x8b8 | ||
1282 | #define TRANSCEIVEB_HSPI_READBACK 0x8bc | ||
1283 | #define RFPGA0_XAB_RFINTERFACERB 0x8e0 | ||
1284 | #define RFPGA0_XCD_RFINTERFACERB 0x8e4 | ||
1285 | |||
1286 | #define RFPGA1_RFMOD 0x900 | ||
1287 | |||
1288 | #define RFPGA1_TXBLOCK 0x904 | ||
1289 | #define RFPGA1_DEBUGSELECT 0x908 | ||
1290 | #define RFPGA1_TXINFO 0x90c | ||
1291 | |||
1292 | #define RCCK0_SYSTEM 0xa00 | ||
1293 | |||
1294 | #define RCCK0_AFESETTING 0xa04 | ||
1295 | #define RCCK0_CCA 0xa08 | ||
1296 | |||
1297 | #define RCCK0_RXAGC1 0xa0c | ||
1298 | #define RCCK0_RXAGC2 0xa10 | ||
1299 | |||
1300 | #define RCCK0_RXHP 0xa14 | ||
1301 | |||
1302 | #define RCCK0_DSPPARAMETER1 0xa18 | ||
1303 | #define RCCK0_DSPPARAMETER2 0xa1c | ||
1304 | |||
1305 | #define RCCK0_TXFILTER1 0xa20 | ||
1306 | #define RCCK0_TXFILTER2 0xa24 | ||
1307 | #define RCCK0_DEBUGPORT 0xa28 | ||
1308 | #define RCCK0_FALSEALARMREPORT 0xa2c | ||
1309 | #define RCCK0_TRSSIREPORT 0xa50 | ||
1310 | #define RCCK0_RXREPORT 0xa54 | ||
1311 | #define RCCK0_FACOUNTERLOWER 0xa5c | ||
1312 | #define RCCK0_FACOUNTERUPPER 0xa58 | ||
1313 | |||
1314 | #define ROFDM0_LSTF 0xc00 | ||
1315 | |||
1316 | #define ROFDM0_TRXPATHENABLE 0xc04 | ||
1317 | #define ROFDM0_TRMUXPAR 0xc08 | ||
1318 | #define ROFDM0_TRSWISOLATION 0xc0c | ||
1319 | |||
1320 | #define ROFDM0_XARXAFE 0xc10 | ||
1321 | #define ROFDM0_XARXIQIMBALANCE 0xc14 | ||
1322 | #define ROFDM0_XBRXAFE 0xc18 | ||
1323 | #define ROFDM0_XBRXIQIMBALANCE 0xc1c | ||
1324 | #define ROFDM0_XCRXAFE 0xc20 | ||
1325 | #define ROFDM0_XCRXIQIMBANLANCE 0xc24 | ||
1326 | #define ROFDM0_XDRXAFE 0xc28 | ||
1327 | #define ROFDM0_XDRXIQIMBALANCE 0xc2c | ||
1328 | |||
1329 | #define ROFDM0_RXDETECTOR1 0xc30 | ||
1330 | #define ROFDM0_RXDETECTOR2 0xc34 | ||
1331 | #define ROFDM0_RXDETECTOR3 0xc38 | ||
1332 | #define ROFDM0_RXDETECTOR4 0xc3c | ||
1333 | |||
1334 | #define ROFDM0_RXDSP 0xc40 | ||
1335 | #define ROFDM0_CFOANDDAGC 0xc44 | ||
1336 | #define ROFDM0_CCADROPTHRESHOLD 0xc48 | ||
1337 | #define ROFDM0_ECCATHRESHOLD 0xc4c | ||
1338 | |||
1339 | #define ROFDM0_XAAGCCORE1 0xc50 | ||
1340 | #define ROFDM0_XAAGCCORE2 0xc54 | ||
1341 | #define ROFDM0_XBAGCCORE1 0xc58 | ||
1342 | #define ROFDM0_XBAGCCORE2 0xc5c | ||
1343 | #define ROFDM0_XCAGCCORE1 0xc60 | ||
1344 | #define ROFDM0_XCAGCCORE2 0xc64 | ||
1345 | #define ROFDM0_XDAGCCORE1 0xc68 | ||
1346 | #define ROFDM0_XDAGCCORE2 0xc6c | ||
1347 | |||
1348 | #define ROFDM0_AGCPARAMETER1 0xc70 | ||
1349 | #define ROFDM0_AGCPARAMETER2 0xc74 | ||
1350 | #define ROFDM0_AGCRSSITABLE 0xc78 | ||
1351 | #define ROFDM0_HTSTFAGC 0xc7c | ||
1352 | |||
1353 | #define ROFDM0_XATXIQIMBALANCE 0xc80 | ||
1354 | #define ROFDM0_XATXAFE 0xc84 | ||
1355 | #define ROFDM0_XBTXIQIMBALANCE 0xc88 | ||
1356 | #define ROFDM0_XBTXAFE 0xc8c | ||
1357 | #define ROFDM0_XCTXIQIMBALANCE 0xc90 | ||
1358 | #define ROFDM0_XCTXAFE 0xc94 | ||
1359 | #define ROFDM0_XDTXIQIMBALANCE 0xc98 | ||
1360 | #define ROFDM0_XDTXAFE 0xc9c | ||
1361 | |||
1362 | #define ROFDM0_RXIQEXTANTA 0xca0 | ||
1363 | |||
1364 | #define ROFDM0_RXHPPARAMETER 0xce0 | ||
1365 | #define ROFDM0_TXPSEUDONOISEWGT 0xce4 | ||
1366 | #define ROFDM0_FRAMESYNC 0xcf0 | ||
1367 | #define ROFDM0_DFSREPORT 0xcf4 | ||
1368 | #define ROFDM0_TXCOEFF1 0xca4 | ||
1369 | #define ROFDM0_TXCOEFF2 0xca8 | ||
1370 | #define ROFDM0_TXCOEFF3 0xcac | ||
1371 | #define ROFDM0_TXCOEFF4 0xcb0 | ||
1372 | #define ROFDM0_TXCOEFF5 0xcb4 | ||
1373 | #define ROFDM0_TXCOEFF6 0xcb8 | ||
1374 | |||
1375 | #define ROFDM1_LSTF 0xd00 | ||
1376 | #define ROFDM1_TRXPATHENABLE 0xd04 | ||
1377 | |||
1378 | #define ROFDM1_CF0 0xd08 | ||
1379 | #define ROFDM1_CSI1 0xd10 | ||
1380 | #define ROFDM1_SBD 0xd14 | ||
1381 | #define ROFDM1_CSI2 0xd18 | ||
1382 | #define ROFDM1_CFOTRACKING 0xd2c | ||
1383 | #define ROFDM1_TRXMESAURE1 0xd34 | ||
1384 | #define ROFDM1_INTFDET 0xd3c | ||
1385 | #define ROFDM1_PSEUDONOISESTATEAB 0xd50 | ||
1386 | #define ROFDM1_PSEUDONOISESTATECD 0xd54 | ||
1387 | #define ROFDM1_RXPSEUDONOISEWGT 0xd58 | ||
1388 | |||
1389 | #define ROFDM_PHYCOUNTER1 0xda0 | ||
1390 | #define ROFDM_PHYCOUNTER2 0xda4 | ||
1391 | #define ROFDM_PHYCOUNTER3 0xda8 | ||
1392 | |||
1393 | #define ROFDM_SHORTCFOAB 0xdac | ||
1394 | #define ROFDM_SHORTCFOCD 0xdb0 | ||
1395 | #define ROFDM_LONGCFOAB 0xdb4 | ||
1396 | #define ROFDM_LONGCFOCD 0xdb8 | ||
1397 | #define ROFDM_TAILCF0AB 0xdbc | ||
1398 | #define ROFDM_TAILCF0CD 0xdc0 | ||
1399 | #define ROFDM_PWMEASURE1 0xdc4 | ||
1400 | #define ROFDM_PWMEASURE2 0xdc8 | ||
1401 | #define ROFDM_BWREPORT 0xdcc | ||
1402 | #define ROFDM_AGCREPORT 0xdd0 | ||
1403 | #define ROFDM_RXSNR 0xdd4 | ||
1404 | #define ROFDM_RXEVMCSI 0xdd8 | ||
1405 | #define ROFDM_SIGREPORT 0xddc | ||
1406 | |||
1407 | #define RTXAGC_A_RATE18_06 0xe00 | ||
1408 | #define RTXAGC_A_RATE54_24 0xe04 | ||
1409 | #define RTXAGC_A_CCK1_MCS32 0xe08 | ||
1410 | #define RTXAGC_A_MCS03_MCS00 0xe10 | ||
1411 | #define RTXAGC_A_MCS07_MCS04 0xe14 | ||
1412 | #define RTXAGC_A_MCS11_MCS08 0xe18 | ||
1413 | #define RTXAGC_A_MCS15_MCS12 0xe1c | ||
1414 | |||
1415 | #define RTXAGC_B_RATE18_06 0x830 | ||
1416 | #define RTXAGC_B_RATE54_24 0x834 | ||
1417 | #define RTXAGC_B_CCK1_55_MCS32 0x838 | ||
1418 | #define RTXAGC_B_MCS03_MCS00 0x83c | ||
1419 | #define RTXAGC_B_MCS07_MCS04 0x848 | ||
1420 | #define RTXAGC_B_MCS11_MCS08 0x84c | ||
1421 | #define RTXAGC_B_MCS15_MCS12 0x868 | ||
1422 | #define RTXAGC_B_CCK11_A_CCK2_11 0x86c | ||
1423 | |||
1424 | #define RZEBRA1_HSSIENABLE 0x0 | ||
1425 | #define RZEBRA1_TRXENABLE1 0x1 | ||
1426 | #define RZEBRA1_TRXENABLE2 0x2 | ||
1427 | #define RZEBRA1_AGC 0x4 | ||
1428 | #define RZEBRA1_CHARGEPUMP 0x5 | ||
1429 | #define RZEBRA1_CHANNEL 0x7 | ||
1430 | |||
1431 | #define RZEBRA1_TXGAIN 0x8 | ||
1432 | #define RZEBRA1_TXLPF 0x9 | ||
1433 | #define RZEBRA1_RXLPF 0xb | ||
1434 | #define RZEBRA1_RXHPFCORNER 0xc | ||
1435 | |||
1436 | #define RGLOBALCTRL 0 | ||
1437 | #define RRTL8256_TXLPF 19 | ||
1438 | #define RRTL8256_RXLPF 11 | ||
1439 | #define RRTL8258_TXLPF 0x11 | ||
1440 | #define RRTL8258_RXLPF 0x13 | ||
1441 | #define RRTL8258_RSSILPF 0xa | ||
1442 | |||
1443 | #define RF_AC 0x00 | ||
1444 | |||
1445 | #define RF_IQADJ_G1 0x01 | ||
1446 | #define RF_IQADJ_G2 0x02 | ||
1447 | #define RF_POW_TRSW 0x05 | ||
1448 | |||
1449 | #define RF_GAIN_RX 0x06 | ||
1450 | #define RF_GAIN_TX 0x07 | ||
1451 | |||
1452 | #define RF_TXM_IDAC 0x08 | ||
1453 | #define RF_BS_IQGEN 0x0F | ||
1454 | |||
1455 | #define RF_MODE1 0x10 | ||
1456 | #define RF_MODE2 0x11 | ||
1457 | |||
1458 | #define RF_RX_AGC_HP 0x12 | ||
1459 | #define RF_TX_AGC 0x13 | ||
1460 | #define RF_BIAS 0x14 | ||
1461 | #define RF_IPA 0x15 | ||
1462 | #define RF_POW_ABILITY 0x17 | ||
1463 | #define RF_MODE_AG 0x18 | ||
1464 | #define RRFCHANNEL 0x18 | ||
1465 | #define RF_CHNLBW 0x18 | ||
1466 | #define RF_TOP 0x19 | ||
1467 | |||
1468 | #define RF_RX_G1 0x1A | ||
1469 | #define RF_RX_G2 0x1B | ||
1470 | |||
1471 | #define RF_RX_BB2 0x1C | ||
1472 | #define RF_RX_BB1 0x1D | ||
1473 | |||
1474 | #define RF_RCK1 0x1E | ||
1475 | #define RF_RCK2 0x1F | ||
1476 | |||
1477 | #define RF_TX_G1 0x20 | ||
1478 | #define RF_TX_G2 0x21 | ||
1479 | #define RF_TX_G3 0x22 | ||
1480 | |||
1481 | #define RF_TX_BB1 0x23 | ||
1482 | #define RF_T_METER 0x24 | ||
1483 | |||
1484 | #define RF_SYN_G1 0x25 | ||
1485 | #define RF_SYN_G2 0x26 | ||
1486 | #define RF_SYN_G3 0x27 | ||
1487 | #define RF_SYN_G4 0x28 | ||
1488 | #define RF_SYN_G5 0x29 | ||
1489 | #define RF_SYN_G6 0x2A | ||
1490 | #define RF_SYN_G7 0x2B | ||
1491 | #define RF_SYN_G8 0x2C | ||
1492 | |||
1493 | #define RF_RCK_OS 0x30 | ||
1494 | #define RF_TXPA_G1 0x31 | ||
1495 | #define RF_TXPA_G2 0x32 | ||
1496 | #define RF_TXPA_G3 0x33 | ||
1497 | |||
1498 | #define BBBRESETB 0x100 | ||
1499 | #define BGLOBALRESETB 0x200 | ||
1500 | #define BOFDMTXSTART 0x4 | ||
1501 | #define BCCKTXSTART 0x8 | ||
1502 | #define BCRC32DEBUG 0x100 | ||
1503 | #define BPMACLOOPBACK 0x10 | ||
1504 | #define BTXLSIG 0xffffff | ||
1505 | #define BOFDMTXRATE 0xf | ||
1506 | #define BOFDMTXRESERVED 0x10 | ||
1507 | #define BOFDMTXLENGTH 0x1ffe0 | ||
1508 | #define BOFDMTXPARITY 0x20000 | ||
1509 | #define BTXHTSIG1 0xffffff | ||
1510 | #define BTXHTMCSRATE 0x7f | ||
1511 | #define BTXHTBW 0x80 | ||
1512 | #define BTXHTLENGTH 0xffff00 | ||
1513 | #define BTXHTSIG2 0xffffff | ||
1514 | #define BTXHTSMOOTHING 0x1 | ||
1515 | #define BTXHTSOUNDING 0x2 | ||
1516 | #define BTXHTRESERVED 0x4 | ||
1517 | #define BTXHTAGGREATION 0x8 | ||
1518 | #define BTXHTSTBC 0x30 | ||
1519 | #define BTXHTADVANCECODING 0x40 | ||
1520 | #define BTXHTSHORTGI 0x80 | ||
1521 | #define BTXHTNUMBERHT_LTF 0x300 | ||
1522 | #define BTXHTCRC8 0x3fc00 | ||
1523 | #define BCOUNTERRESET 0x10000 | ||
1524 | #define BNUMOFOFDMTX 0xffff | ||
1525 | #define BNUMOFCCKTX 0xffff0000 | ||
1526 | #define BTXIDLEINTERVAL 0xffff | ||
1527 | #define BOFDMSERVICE 0xffff0000 | ||
1528 | #define BTXMACHEADER 0xffffffff | ||
1529 | #define BTXDATAINIT 0xff | ||
1530 | #define BTXHTMODE 0x100 | ||
1531 | #define BTXDATATYPE 0x30000 | ||
1532 | #define BTXRANDOMSEED 0xffffffff | ||
1533 | #define BCCKTXPREAMBLE 0x1 | ||
1534 | #define BCCKTXSFD 0xffff0000 | ||
1535 | #define BCCKTXSIG 0xff | ||
1536 | #define BCCKTXSERVICE 0xff00 | ||
1537 | #define BCCKLENGTHEXT 0x8000 | ||
1538 | #define BCCKTXLENGHT 0xffff0000 | ||
1539 | #define BCCKTXCRC16 0xffff | ||
1540 | #define BCCKTXSTATUS 0x1 | ||
1541 | #define BOFDMTXSTATUS 0x2 | ||
1542 | #define IS_BB_REG_OFFSET_92S(_Offset) \ | ||
1543 | ((_Offset >= 0x800) && (_Offset <= 0xfff)) | ||
1544 | |||
1545 | #define BRFMOD 0x1 | ||
1546 | #define BJAPANMODE 0x2 | ||
1547 | #define BCCKTXSC 0x30 | ||
1548 | #define BCCKEN 0x1000000 | ||
1549 | #define BOFDMEN 0x2000000 | ||
1550 | |||
1551 | #define BOFDMRXADCPHASE 0x10000 | ||
1552 | #define BOFDMTXDACPHASE 0x40000 | ||
1553 | #define BXATXAGC 0x3f | ||
1554 | |||
1555 | #define BXBTXAGC 0xf00 | ||
1556 | #define BXCTXAGC 0xf000 | ||
1557 | #define BXDTXAGC 0xf0000 | ||
1558 | |||
1559 | #define BPASTART 0xf0000000 | ||
1560 | #define BTRSTART 0x00f00000 | ||
1561 | #define BRFSTART 0x0000f000 | ||
1562 | #define BBBSTART 0x000000f0 | ||
1563 | #define BBBCCKSTART 0x0000000f | ||
1564 | #define BPAEND 0xf | ||
1565 | #define BTREND 0x0f000000 | ||
1566 | #define BRFEND 0x000f0000 | ||
1567 | #define BCCAMASK 0x000000f0 | ||
1568 | #define BR2RCCAMASK 0x00000f00 | ||
1569 | #define BHSSI_R2TDELAY 0xf8000000 | ||
1570 | #define BHSSI_T2RDELAY 0xf80000 | ||
1571 | #define BCONTXHSSI 0x400 | ||
1572 | #define BIGFROMCCK 0x200 | ||
1573 | #define BAGCADDRESS 0x3f | ||
1574 | #define BRXHPTX 0x7000 | ||
1575 | #define BRXHP2RX 0x38000 | ||
1576 | #define BRXHPCCKINI 0xc0000 | ||
1577 | #define BAGCTXCODE 0xc00000 | ||
1578 | #define BAGCRXCODE 0x300000 | ||
1579 | |||
1580 | #define B3WIREDATALENGTH 0x800 | ||
1581 | #define B3WIREADDREAALENGTH 0x400 | ||
1582 | |||
1583 | #define B3WIRERFPOWERDOWN 0x1 | ||
1584 | #define B5GPAPEPOLARITY 0x40000000 | ||
1585 | #define B2GPAPEPOLARITY 0x80000000 | ||
1586 | #define BRFSW_TXDEFAULTANT 0x3 | ||
1587 | #define BRFSW_TXOPTIONANT 0x30 | ||
1588 | #define BRFSW_RXDEFAULTANT 0x300 | ||
1589 | #define BRFSW_RXOPTIONANT 0x3000 | ||
1590 | #define BRFSI_3WIREDATA 0x1 | ||
1591 | #define BRFSI_3WIRECLOCK 0x2 | ||
1592 | #define BRFSI_3WIRELOAD 0x4 | ||
1593 | #define BRFSI_3WIRERW 0x8 | ||
1594 | #define BRFSI_3WIRE 0xf | ||
1595 | |||
1596 | #define BRFSI_RFENV 0x10 | ||
1597 | |||
1598 | #define BRFSI_TRSW 0x20 | ||
1599 | #define BRFSI_TRSWB 0x40 | ||
1600 | #define BRFSI_ANTSW 0x100 | ||
1601 | #define BRFSI_ANTSWB 0x200 | ||
1602 | #define BRFSI_PAPE 0x400 | ||
1603 | #define BRFSI_PAPE5G 0x800 | ||
1604 | #define BBANDSELECT 0x1 | ||
1605 | #define BHTSIG2_GI 0x80 | ||
1606 | #define BHTSIG2_SMOOTHING 0x01 | ||
1607 | #define BHTSIG2_SOUNDING 0x02 | ||
1608 | #define BHTSIG2_AGGREATON 0x08 | ||
1609 | #define BHTSIG2_STBC 0x30 | ||
1610 | #define BHTSIG2_ADVCODING 0x40 | ||
1611 | #define BHTSIG2_NUMOFHTLTF 0x300 | ||
1612 | #define BHTSIG2_CRC8 0x3fc | ||
1613 | #define BHTSIG1_MCS 0x7f | ||
1614 | #define BHTSIG1_BANDWIDTH 0x80 | ||
1615 | #define BHTSIG1_HTLENGTH 0xffff | ||
1616 | #define BLSIG_RATE 0xf | ||
1617 | #define BLSIG_RESERVED 0x10 | ||
1618 | #define BLSIG_LENGTH 0x1fffe | ||
1619 | #define BLSIG_PARITY 0x20 | ||
1620 | #define BCCKRXPHASE 0x4 | ||
1621 | |||
1622 | #define BLSSIREADADDRESS 0x7f800000 | ||
1623 | #define BLSSIREADEDGE 0x80000000 | ||
1624 | |||
1625 | #define BLSSIREADBACKDATA 0xfffff | ||
1626 | |||
1627 | #define BLSSIREADOKFLAG 0x1000 | ||
1628 | #define BCCKSAMPLERATE 0x8 | ||
1629 | #define BREGULATOR0STANDBY 0x1 | ||
1630 | #define BREGULATORPLLSTANDBY 0x2 | ||
1631 | #define BREGULATOR1STANDBY 0x4 | ||
1632 | #define BPLLPOWERUP 0x8 | ||
1633 | #define BDPLLPOWERUP 0x10 | ||
1634 | #define BDA10POWERUP 0x20 | ||
1635 | #define BAD7POWERUP 0x200 | ||
1636 | #define BDA6POWERUP 0x2000 | ||
1637 | #define BXTALPOWERUP 0x4000 | ||
1638 | #define B40MDCLKPOWERUP 0x8000 | ||
1639 | #define BDA6DEBUGMODE 0x20000 | ||
1640 | #define BDA6SWING 0x380000 | ||
1641 | |||
1642 | #define BADCLKPHASE 0x4000000 | ||
1643 | #define B80MCLKDELAY 0x18000000 | ||
1644 | #define BAFEWATCHDOGENABLE 0x20000000 | ||
1645 | |||
1646 | #define BXTALCAP01 0xc0000000 | ||
1647 | #define BXTALCAP23 0x3 | ||
1648 | #define BXTALCAP92X 0x0f000000 | ||
1649 | #define BXTALCAP 0x0f000000 | ||
1650 | |||
1651 | #define BINTDIFCLKENABLE 0x400 | ||
1652 | #define BEXTSIGCLKENABLE 0x800 | ||
1653 | #define BBANDGAP_MBIAS_POWERUP 0x10000 | ||
1654 | #define BAD11SH_GAIN 0xc0000 | ||
1655 | #define BAD11NPUT_RANGE 0x700000 | ||
1656 | #define BAD110P_CURRENT 0x3800000 | ||
1657 | #define BLPATH_LOOPBACK 0x4000000 | ||
1658 | #define BQPATH_LOOPBACK 0x8000000 | ||
1659 | #define BAFE_LOOPBACK 0x10000000 | ||
1660 | #define BDA10_SWING 0x7e0 | ||
1661 | #define BDA10_REVERSE 0x800 | ||
1662 | #define BDA_CLK_SOURCE 0x1000 | ||
1663 | #define BDA7INPUT_RANGE 0x6000 | ||
1664 | #define BDA7_GAIN 0x38000 | ||
1665 | #define BDA7OUTPUT_CM_MODE 0x40000 | ||
1666 | #define BDA7INPUT_CM_MODE 0x380000 | ||
1667 | #define BDA7CURRENT 0xc00000 | ||
1668 | #define BREGULATOR_ADJUST 0x7000000 | ||
1669 | #define BAD11POWERUP_ATTX 0x1 | ||
1670 | #define BDA10PS_ATTX 0x10 | ||
1671 | #define BAD11POWERUP_ATRX 0x100 | ||
1672 | #define BDA10PS_ATRX 0x1000 | ||
1673 | #define BCCKRX_AGC_FORMAT 0x200 | ||
1674 | #define BPSDFFT_SAMPLE_POINT 0xc000 | ||
1675 | #define BPSD_AVERAGE_NUM 0x3000 | ||
1676 | #define BIQPATH_CONTROL 0xc00 | ||
1677 | #define BPSD_FREQ 0x3ff | ||
1678 | #define BPSD_ANTENNA_PATH 0x30 | ||
1679 | #define BPSD_IQ_SWITCH 0x40 | ||
1680 | #define BPSD_RX_TRIGGER 0x400000 | ||
1681 | #define BPSD_TX_TRIGGER 0x80000000 | ||
1682 | #define BPSD_SINE_TONE_SCALE 0x7f000000 | ||
1683 | #define BPSD_REPORT 0xffff | ||
1684 | |||
1685 | #define BOFDM_TXSC 0x30000000 | ||
1686 | #define BCCK_TXON 0x1 | ||
1687 | #define BOFDM_TXON 0x2 | ||
1688 | #define BDEBUG_PAGE 0xfff | ||
1689 | #define BDEBUG_ITEM 0xff | ||
1690 | #define BANTL 0x10 | ||
1691 | #define BANT_NONHT 0x100 | ||
1692 | #define BANT_HT1 0x1000 | ||
1693 | #define BANT_HT2 0x10000 | ||
1694 | #define BANT_HT1S1 0x100000 | ||
1695 | #define BANT_NONHTS1 0x1000000 | ||
1696 | |||
1697 | #define BCCK_BBMODE 0x3 | ||
1698 | #define BCCK_TXPOWERSAVING 0x80 | ||
1699 | #define BCCK_RXPOWERSAVING 0x40 | ||
1700 | |||
1701 | #define BCCK_SIDEBAND 0x10 | ||
1702 | |||
1703 | #define BCCK_SCRAMBLE 0x8 | ||
1704 | #define BCCK_ANTDIVERSITY 0x8000 | ||
1705 | #define BCCK_CARRIER_RECOVERY 0x4000 | ||
1706 | #define BCCK_TXRATE 0x3000 | ||
1707 | #define BCCK_DCCANCEL 0x0800 | ||
1708 | #define BCCK_ISICANCEL 0x0400 | ||
1709 | #define BCCK_MATCH_FILTER 0x0200 | ||
1710 | #define BCCK_EQUALIZER 0x0100 | ||
1711 | #define BCCK_PREAMBLE_DETECT 0x800000 | ||
1712 | #define BCCK_FAST_FALSECCAi 0x400000 | ||
1713 | #define BCCK_CH_ESTSTARTi 0x300000 | ||
1714 | #define BCCK_CCA_COUNTi 0x080000 | ||
1715 | #define BCCK_CS_LIM 0x070000 | ||
1716 | #define BCCK_BIST_MODEi 0x80000000 | ||
1717 | #define BCCK_CCAMASK 0x40000000 | ||
1718 | #define BCCK_TX_DAC_PHASE 0x4 | ||
1719 | #define BCCK_RX_ADC_PHASE 0x20000000 | ||
1720 | #define BCCKR_CP_MODE 0x0100 | ||
1721 | #define BCCK_TXDC_OFFSET 0xf0 | ||
1722 | #define BCCK_RXDC_OFFSET 0xf | ||
1723 | #define BCCK_CCA_MODE 0xc000 | ||
1724 | #define BCCK_FALSECS_LIM 0x3f00 | ||
1725 | #define BCCK_CS_RATIO 0xc00000 | ||
1726 | #define BCCK_CORGBIT_SEL 0x300000 | ||
1727 | #define BCCK_PD_LIM 0x0f0000 | ||
1728 | #define BCCK_NEWCCA 0x80000000 | ||
1729 | #define BCCK_RXHP_OF_IG 0x8000 | ||
1730 | #define BCCK_RXIG 0x7f00 | ||
1731 | #define BCCK_LNA_POLARITY 0x800000 | ||
1732 | #define BCCK_RX1ST_BAIN 0x7f0000 | ||
1733 | #define BCCK_RF_EXTEND 0x20000000 | ||
1734 | #define BCCK_RXAGC_SATLEVEL 0x1f000000 | ||
1735 | #define BCCK_RXAGC_SATCOUNT 0xe0 | ||
1736 | #define bCCKRxRFSettle 0x1f | ||
1737 | #define BCCK_FIXED_RXAGC 0x8000 | ||
1738 | #define BCCK_ANTENNA_POLARITY 0x2000 | ||
1739 | #define BCCK_TXFILTER_TYPE 0x0c00 | ||
1740 | #define BCCK_RXAGC_REPORTTYPE 0x0300 | ||
1741 | #define BCCK_RXDAGC_EN 0x80000000 | ||
1742 | #define BCCK_RXDAGC_PERIOD 0x20000000 | ||
1743 | #define BCCK_RXDAGC_SATLEVEL 0x1f000000 | ||
1744 | #define BCCK_TIMING_RECOVERY 0x800000 | ||
1745 | #define BCCK_TXC0 0x3f0000 | ||
1746 | #define BCCK_TXC1 0x3f000000 | ||
1747 | #define BCCK_TXC2 0x3f | ||
1748 | #define BCCK_TXC3 0x3f00 | ||
1749 | #define BCCK_TXC4 0x3f0000 | ||
1750 | #define BCCK_TXC5 0x3f000000 | ||
1751 | #define BCCK_TXC6 0x3f | ||
1752 | #define BCCK_TXC7 0x3f00 | ||
1753 | #define BCCK_DEBUGPORT 0xff0000 | ||
1754 | #define BCCK_DAC_DEBUG 0x0f000000 | ||
1755 | #define BCCK_FALSEALARM_ENABLE 0x8000 | ||
1756 | #define BCCK_FALSEALARM_READ 0x4000 | ||
1757 | #define BCCK_TRSSI 0x7f | ||
1758 | #define BCCK_RXAGC_REPORT 0xfe | ||
1759 | #define BCCK_RXREPORT_ANTSEL 0x80000000 | ||
1760 | #define BCCK_RXREPORT_MFOFF 0x40000000 | ||
1761 | #define BCCK_RXREPORT_SQLOSS 0x20000000 | ||
1762 | #define BCCK_RXREPORT_PKTLOSS 0x10000000 | ||
1763 | #define BCCK_RXREPORT_LOCKEDBIT 0x08000000 | ||
1764 | #define BCCK_RXREPORT_RATEERROR 0x04000000 | ||
1765 | #define BCCK_RXREPORT_RXRATE 0x03000000 | ||
1766 | #define BCCK_RXFA_COUNTER_LOWER 0xff | ||
1767 | #define BCCK_RXFA_COUNTER_UPPER 0xff000000 | ||
1768 | #define BCCK_RXHPAGC_START 0xe000 | ||
1769 | #define BCCK_RXHPAGC_FINAL 0x1c00 | ||
1770 | #define BCCK_RXFALSEALARM_ENABLE 0x8000 | ||
1771 | #define BCCK_FACOUNTER_FREEZE 0x4000 | ||
1772 | #define BCCK_TXPATH_SEL 0x10000000 | ||
1773 | #define BCCK_DEFAULT_RXPATH 0xc000000 | ||
1774 | #define BCCK_OPTION_RXPATH 0x3000000 | ||
1775 | |||
1776 | #define BNUM_OFSTF 0x3 | ||
1777 | #define BSHIFT_L 0xc0 | ||
1778 | #define BGI_TH 0xc | ||
1779 | #define BRXPATH_A 0x1 | ||
1780 | #define BRXPATH_B 0x2 | ||
1781 | #define BRXPATH_C 0x4 | ||
1782 | #define BRXPATH_D 0x8 | ||
1783 | #define BTXPATH_A 0x1 | ||
1784 | #define BTXPATH_B 0x2 | ||
1785 | #define BTXPATH_C 0x4 | ||
1786 | #define BTXPATH_D 0x8 | ||
1787 | #define BTRSSI_FREQ 0x200 | ||
1788 | #define BADC_BACKOFF 0x3000 | ||
1789 | #define BDFIR_BACKOFF 0xc000 | ||
1790 | #define BTRSSI_LATCH_PHASE 0x10000 | ||
1791 | #define BRX_LDC_OFFSET 0xff | ||
1792 | #define BRX_QDC_OFFSET 0xff00 | ||
1793 | #define BRX_DFIR_MODE 0x1800000 | ||
1794 | #define BRX_DCNF_TYPE 0xe000000 | ||
1795 | #define BRXIQIMB_A 0x3ff | ||
1796 | #define BRXIQIMB_B 0xfc00 | ||
1797 | #define BRXIQIMB_C 0x3f0000 | ||
1798 | #define BRXIQIMB_D 0xffc00000 | ||
1799 | #define BDC_DC_NOTCH 0x60000 | ||
1800 | #define BRXNB_NOTCH 0x1f000000 | ||
1801 | #define BPD_TH 0xf | ||
1802 | #define BPD_TH_OPT2 0xc000 | ||
1803 | #define BPWED_TH 0x700 | ||
1804 | #define BIFMF_WIN_L 0x800 | ||
1805 | #define BPD_OPTION 0x1000 | ||
1806 | #define BMF_WIN_L 0xe000 | ||
1807 | #define BBW_SEARCH_L 0x30000 | ||
1808 | #define BWIN_ENH_L 0xc0000 | ||
1809 | #define BBW_TH 0x700000 | ||
1810 | #define BED_TH2 0x3800000 | ||
1811 | #define BBW_OPTION 0x4000000 | ||
1812 | #define BRADIO_TH 0x18000000 | ||
1813 | #define BWINDOW_L 0xe0000000 | ||
1814 | #define BSBD_OPTION 0x1 | ||
1815 | #define BFRAME_TH 0x1c | ||
1816 | #define BFS_OPTION 0x60 | ||
1817 | #define BDC_SLOPE_CHECK 0x80 | ||
1818 | #define BFGUARD_COUNTER_DC_L 0xe00 | ||
1819 | #define BFRAME_WEIGHT_SHORT 0x7000 | ||
1820 | #define BSUB_TUNE 0xe00000 | ||
1821 | #define BFRAME_DC_LENGTH 0xe000000 | ||
1822 | #define BSBD_START_OFFSET 0x30000000 | ||
1823 | #define BFRAME_TH_2 0x7 | ||
1824 | #define BFRAME_GI2_TH 0x38 | ||
1825 | #define BGI2_SYNC_EN 0x40 | ||
1826 | #define BSARCH_SHORT_EARLY 0x300 | ||
1827 | #define BSARCH_SHORT_LATE 0xc00 | ||
1828 | #define BSARCH_GI2_LATE 0x70000 | ||
1829 | #define BCFOANTSUM 0x1 | ||
1830 | #define BCFOACC 0x2 | ||
1831 | #define BCFOSTARTOFFSET 0xc | ||
1832 | #define BCFOLOOPBACK 0x70 | ||
1833 | #define BCFOSUMWEIGHT 0x80 | ||
1834 | #define BDAGCENABLE 0x10000 | ||
1835 | #define BTXIQIMB_A 0x3ff | ||
1836 | #define BTXIQIMB_b 0xfc00 | ||
1837 | #define BTXIQIMB_C 0x3f0000 | ||
1838 | #define BTXIQIMB_D 0xffc00000 | ||
1839 | #define BTXIDCOFFSET 0xff | ||
1840 | #define BTXIQDCOFFSET 0xff00 | ||
1841 | #define BTXDFIRMODE 0x10000 | ||
1842 | #define BTXPESUDO_NOISEON 0x4000000 | ||
1843 | #define BTXPESUDO_NOISE_A 0xff | ||
1844 | #define BTXPESUDO_NOISE_B 0xff00 | ||
1845 | #define BTXPESUDO_NOISE_C 0xff0000 | ||
1846 | #define BTXPESUDO_NOISE_D 0xff000000 | ||
1847 | #define BCCA_DROPOPTION 0x20000 | ||
1848 | #define BCCA_DROPTHRES 0xfff00000 | ||
1849 | #define BEDCCA_H 0xf | ||
1850 | #define BEDCCA_L 0xf0 | ||
1851 | #define BLAMBDA_ED 0x300 | ||
1852 | #define BRX_INITIALGAIN 0x7f | ||
1853 | #define BRX_ANTDIV_EN 0x80 | ||
1854 | #define BRX_AGC_ADDRESS_FOR_LNA 0x7f00 | ||
1855 | #define BRX_HIGHPOWER_FLOW 0x8000 | ||
1856 | #define BRX_AGC_FREEZE_THRES 0xc0000 | ||
1857 | #define BRX_FREEZESTEP_AGC1 0x300000 | ||
1858 | #define BRX_FREEZESTEP_AGC2 0xc00000 | ||
1859 | #define BRX_FREEZESTEP_AGC3 0x3000000 | ||
1860 | #define BRX_FREEZESTEP_AGC0 0xc000000 | ||
1861 | #define BRXRSSI_CMP_EN 0x10000000 | ||
1862 | #define BRXQUICK_AGCEN 0x20000000 | ||
1863 | #define BRXAGC_FREEZE_THRES_MODE 0x40000000 | ||
1864 | #define BRX_OVERFLOW_CHECKTYPE 0x80000000 | ||
1865 | #define BRX_AGCSHIFT 0x7f | ||
1866 | #define BTRSW_TRI_ONLY 0x80 | ||
1867 | #define BPOWER_THRES 0x300 | ||
1868 | #define BRXAGC_EN 0x1 | ||
1869 | #define BRXAGC_TOGETHER_EN 0x2 | ||
1870 | #define BRXAGC_MIN 0x4 | ||
1871 | #define BRXHP_INI 0x7 | ||
1872 | #define BRXHP_TRLNA 0x70 | ||
1873 | #define BRXHP_RSSI 0x700 | ||
1874 | #define BRXHP_BBP1 0x7000 | ||
1875 | #define BRXHP_BBP2 0x70000 | ||
1876 | #define BRXHP_BBP3 0x700000 | ||
1877 | #define BRSSI_H 0x7f0000 | ||
1878 | #define BRSSI_GEN 0x7f000000 | ||
1879 | #define BRXSETTLE_TRSW 0x7 | ||
1880 | #define BRXSETTLE_LNA 0x38 | ||
1881 | #define BRXSETTLE_RSSI 0x1c0 | ||
1882 | #define BRXSETTLE_BBP 0xe00 | ||
1883 | #define BRXSETTLE_RXHP 0x7000 | ||
1884 | #define BRXSETTLE_ANTSW_RSSI 0x38000 | ||
1885 | #define BRXSETTLE_ANTSW 0xc0000 | ||
1886 | #define BRXPROCESS_TIME_DAGC 0x300000 | ||
1887 | #define BRXSETTLE_HSSI 0x400000 | ||
1888 | #define BRXPROCESS_TIME_BBPPW 0x800000 | ||
1889 | #define BRXANTENNA_POWER_SHIFT 0x3000000 | ||
1890 | #define BRSSI_TABLE_SELECT 0xc000000 | ||
1891 | #define BRXHP_FINAL 0x7000000 | ||
1892 | #define BRXHPSETTLE_BBP 0x7 | ||
1893 | #define BRXHTSETTLE_HSSI 0x8 | ||
1894 | #define BRXHTSETTLE_RXHP 0x70 | ||
1895 | #define BRXHTSETTLE_BBPPW 0x80 | ||
1896 | #define BRXHTSETTLE_IDLE 0x300 | ||
1897 | #define BRXHTSETTLE_RESERVED 0x1c00 | ||
1898 | #define BRXHT_RXHP_EN 0x8000 | ||
1899 | #define BRXAGC_FREEZE_THRES 0x30000 | ||
1900 | #define BRXAGC_TOGETHEREN 0x40000 | ||
1901 | #define BRXHTAGC_MIN 0x80000 | ||
1902 | #define BRXHTAGC_EN 0x100000 | ||
1903 | #define BRXHTDAGC_EN 0x200000 | ||
1904 | #define BRXHT_RXHP_BBP 0x1c00000 | ||
1905 | #define BRXHT_RXHP_FINAL 0xe0000000 | ||
1906 | #define BRXPW_RADIO_TH 0x3 | ||
1907 | #define BRXPW_RADIO_EN 0x4 | ||
1908 | #define BRXMF_HOLD 0x3800 | ||
1909 | #define BRXPD_DELAY_TH1 0x38 | ||
1910 | #define BRXPD_DELAY_TH2 0x1c0 | ||
1911 | #define BRXPD_DC_COUNT_MAX 0x600 | ||
1912 | #define BRXPD_DELAY_TH 0x8000 | ||
1913 | #define BRXPROCESS_DELAY 0xf0000 | ||
1914 | #define BRXSEARCHRANGE_GI2_EARLY 0x700000 | ||
1915 | #define BRXFRAME_FUARD_COUNTER_L 0x3800000 | ||
1916 | #define BRXSGI_GUARD_L 0xc000000 | ||
1917 | #define BRXSGI_SEARCH_L 0x30000000 | ||
1918 | #define BRXSGI_TH 0xc0000000 | ||
1919 | #define BDFSCNT0 0xff | ||
1920 | #define BDFSCNT1 0xff00 | ||
1921 | #define BDFSFLAG 0xf0000 | ||
1922 | #define BMF_WEIGHT_SUM 0x300000 | ||
1923 | #define BMINIDX_TH 0x7f000000 | ||
1924 | #define BDAFORMAT 0x40000 | ||
1925 | #define BTXCH_EMU_ENABLE 0x01000000 | ||
1926 | #define BTRSW_ISOLATION_A 0x7f | ||
1927 | #define BTRSW_ISOLATION_B 0x7f00 | ||
1928 | #define BTRSW_ISOLATION_C 0x7f0000 | ||
1929 | #define BTRSW_ISOLATION_D 0x7f000000 | ||
1930 | #define BEXT_LNA_GAIN 0x7c00 | ||
1931 | |||
1932 | #define BSTBC_EN 0x4 | ||
1933 | #define BANTENNA_MAPPING 0x10 | ||
1934 | #define BNSS 0x20 | ||
1935 | #define BCFO_ANTSUM_ID 0x200 | ||
1936 | #define BPHY_COUNTER_RESET 0x8000000 | ||
1937 | #define BCFO_REPORT_GET 0x4000000 | ||
1938 | #define BOFDM_CONTINUE_TX 0x10000000 | ||
1939 | #define BOFDM_SINGLE_CARRIER 0x20000000 | ||
1940 | #define BOFDM_SINGLE_TONE 0x40000000 | ||
1941 | #define BHT_DETECT 0x100 | ||
1942 | #define BCFOEN 0x10000 | ||
1943 | #define BCFOVALUE 0xfff00000 | ||
1944 | #define BSIGTONE_RE 0x3f | ||
1945 | #define BSIGTONE_IM 0x7f00 | ||
1946 | #define BCOUNTER_CCA 0xffff | ||
1947 | #define BCOUNTER_PARITYFAIL 0xffff0000 | ||
1948 | #define BCOUNTER_RATEILLEGAL 0xffff | ||
1949 | #define BCOUNTER_CRC8FAIL 0xffff0000 | ||
1950 | #define BCOUNTER_MCSNOSUPPORT 0xffff | ||
1951 | #define BCOUNTER_FASTSYNC 0xffff | ||
1952 | #define BSHORTCFO 0xfff | ||
1953 | #define BSHORTCFOT_LENGTH 12 | ||
1954 | #define BSHORTCFOF_LENGTH 11 | ||
1955 | #define BLONGCFO 0x7ff | ||
1956 | #define BLONGCFOT_LENGTH 11 | ||
1957 | #define BLONGCFOF_LENGTH 11 | ||
1958 | #define BTAILCFO 0x1fff | ||
1959 | #define BTAILCFOT_LENGTH 13 | ||
1960 | #define BTAILCFOF_LENGTH 12 | ||
1961 | #define BNOISE_EN_PWDB 0xffff | ||
1962 | #define BCC_POWER_DB 0xffff0000 | ||
1963 | #define BMOISE_PWDB 0xffff | ||
1964 | #define BPOWERMEAST_LENGTH 10 | ||
1965 | #define BPOWERMEASF_LENGTH 3 | ||
1966 | #define BRX_HT_BW 0x1 | ||
1967 | #define BRXSC 0x6 | ||
1968 | #define BRX_HT 0x8 | ||
1969 | #define BNB_INTF_DET_ON 0x1 | ||
1970 | #define BINTF_WIN_LEN_CFG 0x30 | ||
1971 | #define BNB_INTF_TH_CFG 0x1c0 | ||
1972 | #define BRFGAIN 0x3f | ||
1973 | #define BTABLESEL 0x40 | ||
1974 | #define BTRSW 0x80 | ||
1975 | #define BRXSNR_A 0xff | ||
1976 | #define BRXSNR_B 0xff00 | ||
1977 | #define BRXSNR_C 0xff0000 | ||
1978 | #define BRXSNR_D 0xff000000 | ||
1979 | #define BSNR_EVMT_LENGTH 8 | ||
1980 | #define BSNR_EVMF_LENGTH 1 | ||
1981 | #define BCSI1ST 0xff | ||
1982 | #define BCSI2ND 0xff00 | ||
1983 | #define BRXEVM1ST 0xff0000 | ||
1984 | #define BRXEVM2ND 0xff000000 | ||
1985 | #define BSIGEVM 0xff | ||
1986 | #define BPWDB 0xff00 | ||
1987 | #define BSGIEN 0x10000 | ||
1988 | |||
1989 | #define BSFACTOR_QMA1 0xf | ||
1990 | #define BSFACTOR_QMA2 0xf0 | ||
1991 | #define BSFACTOR_QMA3 0xf00 | ||
1992 | #define BSFACTOR_QMA4 0xf000 | ||
1993 | #define BSFACTOR_QMA5 0xf0000 | ||
1994 | #define BSFACTOR_QMA6 0xf0000 | ||
1995 | #define BSFACTOR_QMA7 0xf00000 | ||
1996 | #define BSFACTOR_QMA8 0xf000000 | ||
1997 | #define BSFACTOR_QMA9 0xf0000000 | ||
1998 | #define BCSI_SCHEME 0x100000 | ||
1999 | |||
2000 | #define BNOISE_LVL_TOP_SET 0x3 | ||
2001 | #define BCHSMOOTH 0x4 | ||
2002 | #define BCHSMOOTH_CFG1 0x38 | ||
2003 | #define BCHSMOOTH_CFG2 0x1c0 | ||
2004 | #define BCHSMOOTH_CFG3 0xe00 | ||
2005 | #define BCHSMOOTH_CFG4 0x7000 | ||
2006 | #define BMRCMODE 0x800000 | ||
2007 | #define BTHEVMCFG 0x7000000 | ||
2008 | |||
2009 | #define BLOOP_FIT_TYPE 0x1 | ||
2010 | #define BUPD_CFO 0x40 | ||
2011 | #define BUPD_CFO_OFFDATA 0x80 | ||
2012 | #define BADV_UPD_CFO 0x100 | ||
2013 | #define BADV_TIME_CTRL 0x800 | ||
2014 | #define BUPD_CLKO 0x1000 | ||
2015 | #define BFC 0x6000 | ||
2016 | #define BTRACKING_MODE 0x8000 | ||
2017 | #define BPHCMP_ENABLE 0x10000 | ||
2018 | #define BUPD_CLKO_LTF 0x20000 | ||
2019 | #define BCOM_CH_CFO 0x40000 | ||
2020 | #define BCSI_ESTI_MODE 0x80000 | ||
2021 | #define BADV_UPD_EQZ 0x100000 | ||
2022 | #define BUCHCFG 0x7000000 | ||
2023 | #define BUPDEQZ 0x8000000 | ||
2024 | |||
2025 | #define BRX_PESUDO_NOISE_ON 0x20000000 | ||
2026 | #define BRX_PESUDO_NOISE_A 0xff | ||
2027 | #define BRX_PESUDO_NOISE_B 0xff00 | ||
2028 | #define BRX_PESUDO_NOISE_C 0xff0000 | ||
2029 | #define BRX_PESUDO_NOISE_D 0xff000000 | ||
2030 | #define BRX_PESUDO_NOISESTATE_A 0xffff | ||
2031 | #define BRX_PESUDO_NOISESTATE_B 0xffff0000 | ||
2032 | #define BRX_PESUDO_NOISESTATE_C 0xffff | ||
2033 | #define BRX_PESUDO_NOISESTATE_D 0xffff0000 | ||
2034 | |||
2035 | #define BZEBRA1_HSSIENABLE 0x8 | ||
2036 | #define BZEBRA1_TRXCONTROL 0xc00 | ||
2037 | #define BZEBRA1_TRXGAINSETTING 0x07f | ||
2038 | #define BZEBRA1_RXCOUNTER 0xc00 | ||
2039 | #define BZEBRA1_TXCHANGEPUMP 0x38 | ||
2040 | #define BZEBRA1_RXCHANGEPUMP 0x7 | ||
2041 | #define BZEBRA1_CHANNEL_NUM 0xf80 | ||
2042 | #define BZEBRA1_TXLPFBW 0x400 | ||
2043 | #define BZEBRA1_RXLPFBW 0x600 | ||
2044 | |||
2045 | #define BRTL8256REG_MODE_CTRL1 0x100 | ||
2046 | #define BRTL8256REG_MODE_CTRL0 0x40 | ||
2047 | #define BRTL8256REG_TXLPFBW 0x18 | ||
2048 | #define BRTL8256REG_RXLPFBW 0x600 | ||
2049 | |||
2050 | #define BRTL8258_TXLPFBW 0xc | ||
2051 | #define BRTL8258_RXLPFBW 0xc00 | ||
2052 | #define BRTL8258_RSSILPFBW 0xc0 | ||
2053 | |||
2054 | #define BBYTE0 0x1 | ||
2055 | #define BBYTE1 0x2 | ||
2056 | #define BBYTE2 0x4 | ||
2057 | #define BBYTE3 0x8 | ||
2058 | #define BWORD0 0x3 | ||
2059 | #define BWORD1 0xc | ||
2060 | #define BWORD 0xf | ||
2061 | |||
2062 | #define MASKBYTE0 0xff | ||
2063 | #define MASKBYTE1 0xff00 | ||
2064 | #define MASKBYTE2 0xff0000 | ||
2065 | #define MASKBYTE3 0xff000000 | ||
2066 | #define MASKHWORD 0xffff0000 | ||
2067 | #define MASKLWORD 0x0000ffff | ||
2068 | #define MASKDWORD 0xffffffff | ||
2069 | #define MASK12BITS 0xfff | ||
2070 | #define MASKH4BITS 0xf0000000 | ||
2071 | #define MASKOFDM_D 0xffc00000 | ||
2072 | #define MASKCCK 0x3f3f3f3f | ||
2073 | |||
2074 | #define MASK4BITS 0x0f | ||
2075 | #define MASK20BITS 0xfffff | ||
2076 | #define RFREG_OFFSET_MASK 0xfffff | ||
2077 | |||
2078 | #define BENABLE 0x1 | ||
2079 | #define BDISABLE 0x0 | ||
2080 | |||
2081 | #define LEFT_ANTENNA 0x0 | ||
2082 | #define RIGHT_ANTENNA 0x1 | ||
2083 | |||
2084 | #define TCHECK_TXSTATUS 500 | ||
2085 | #define TUPDATE_RXCOUNTER 100 | ||
2086 | |||
2087 | /* 2 EFUSE_TEST (For RTL8723 partially) */ | ||
2088 | #define EFUSE_SEL(x) (((x) & 0x3) << 8) | ||
2089 | #define EFUSE_SEL_MASK 0x300 | ||
2090 | #define EFUSE_WIFI_SEL_0 0x0 | ||
2091 | |||
2092 | /* Enable GPIO[9] as WiFi HW PDn source*/ | ||
2093 | #define WL_HWPDN_EN BIT(0) | ||
2094 | /* WiFi HW PDn polarity control*/ | ||
2095 | #define WL_HWPDN_SL BIT(1) | ||
2096 | |||
2097 | #endif | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/rf.c b/drivers/net/wireless/rtlwifi/rtl8723ae/rf.c new file mode 100644 index 000000000000..50dd2fb2c93d --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/rf.c | |||
@@ -0,0 +1,505 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 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 | void rtl8723ae_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) | ||
38 | { | ||
39 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
40 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
41 | |||
42 | switch (bandwidth) { | ||
43 | case HT_CHANNEL_WIDTH_20: | ||
44 | rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & | ||
45 | 0xfffff3ff) | 0x0400); | ||
46 | rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, | ||
47 | rtlphy->rfreg_chnlval[0]); | ||
48 | break; | ||
49 | case HT_CHANNEL_WIDTH_20_40: | ||
50 | rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & | ||
51 | 0xfffff3ff)); | ||
52 | rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, | ||
53 | rtlphy->rfreg_chnlval[0]); | ||
54 | break; | ||
55 | default: | ||
56 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
57 | "unknown bandwidth: %#X\n", bandwidth); | ||
58 | break; | ||
59 | } | ||
60 | } | ||
61 | |||
62 | void rtl8723ae_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, | ||
63 | u8 *ppowerlevel) | ||
64 | { | ||
65 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
66 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
67 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
68 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
69 | u32 tx_agc[2] = {0, 0}, tmpval; | ||
70 | bool turbo_scanoff = false; | ||
71 | u8 idx1, idx2; | ||
72 | u8 *ptr; | ||
73 | |||
74 | if (rtlefuse->eeprom_regulatory != 0) | ||
75 | turbo_scanoff = true; | ||
76 | |||
77 | if (mac->act_scanning == true) { | ||
78 | tx_agc[RF90_PATH_A] = 0x3f3f3f3f; | ||
79 | tx_agc[RF90_PATH_B] = 0x3f3f3f3f; | ||
80 | |||
81 | if (turbo_scanoff) { | ||
82 | for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { | ||
83 | tx_agc[idx1] = ppowerlevel[idx1] | | ||
84 | (ppowerlevel[idx1] << 8) | | ||
85 | (ppowerlevel[idx1] << 16) | | ||
86 | (ppowerlevel[idx1] << 24); | ||
87 | } | ||
88 | } | ||
89 | } else { | ||
90 | for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { | ||
91 | tx_agc[idx1] = ppowerlevel[idx1] | | ||
92 | (ppowerlevel[idx1] << 8) | | ||
93 | (ppowerlevel[idx1] << 16) | | ||
94 | (ppowerlevel[idx1] << 24); | ||
95 | } | ||
96 | |||
97 | if (rtlefuse->eeprom_regulatory == 0) { | ||
98 | tmpval = (rtlphy->mcs_offset[0][6]) + | ||
99 | (rtlphy->mcs_offset[0][7] << 8); | ||
100 | tx_agc[RF90_PATH_A] += tmpval; | ||
101 | |||
102 | tmpval = (rtlphy->mcs_offset[0][14]) + | ||
103 | (rtlphy->mcs_offset[0][15] << 24); | ||
104 | tx_agc[RF90_PATH_B] += tmpval; | ||
105 | } | ||
106 | } | ||
107 | |||
108 | for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { | ||
109 | ptr = (u8 *) (&(tx_agc[idx1])); | ||
110 | for (idx2 = 0; idx2 < 4; idx2++) { | ||
111 | if (*ptr > RF6052_MAX_TX_PWR) | ||
112 | *ptr = RF6052_MAX_TX_PWR; | ||
113 | ptr++; | ||
114 | } | ||
115 | } | ||
116 | |||
117 | tmpval = tx_agc[RF90_PATH_A] & 0xff; | ||
118 | rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval); | ||
119 | |||
120 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | ||
121 | "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, | ||
122 | RTXAGC_A_CCK1_MCS32); | ||
123 | |||
124 | tmpval = tx_agc[RF90_PATH_A] >> 8; | ||
125 | |||
126 | tmpval = tmpval & 0xff00ffff; | ||
127 | |||
128 | rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); | ||
129 | |||
130 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | ||
131 | "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, | ||
132 | RTXAGC_B_CCK11_A_CCK2_11); | ||
133 | |||
134 | tmpval = tx_agc[RF90_PATH_B] >> 24; | ||
135 | rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval); | ||
136 | |||
137 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | ||
138 | "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, | ||
139 | RTXAGC_B_CCK11_A_CCK2_11); | ||
140 | |||
141 | tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff; | ||
142 | rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval); | ||
143 | |||
144 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | ||
145 | "CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, | ||
146 | RTXAGC_B_CCK1_55_MCS32); | ||
147 | } | ||
148 | |||
149 | static void rtl8723ae_phy_get_power_base(struct ieee80211_hw *hw, | ||
150 | u8 *ppowerlevel, u8 channel, | ||
151 | u32 *ofdmbase, u32 *mcsbase) | ||
152 | { | ||
153 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
154 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
155 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
156 | u32 powerBase0, powerBase1; | ||
157 | u8 legacy_pwrdiff, ht20_pwrdiff; | ||
158 | u8 i, powerlevel[2]; | ||
159 | |||
160 | for (i = 0; i < 2; i++) { | ||
161 | powerlevel[i] = ppowerlevel[i]; | ||
162 | legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff[i][channel - 1]; | ||
163 | powerBase0 = powerlevel[i] + legacy_pwrdiff; | ||
164 | |||
165 | powerBase0 = (powerBase0 << 24) | (powerBase0 << 16) | | ||
166 | (powerBase0 << 8) | powerBase0; | ||
167 | *(ofdmbase + i) = powerBase0; | ||
168 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | ||
169 | " [OFDM power base index rf(%c) = 0x%x]\n", | ||
170 | ((i == 0) ? 'A' : 'B'), *(ofdmbase + i)); | ||
171 | } | ||
172 | |||
173 | for (i = 0; i < 2; i++) { | ||
174 | if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) { | ||
175 | ht20_pwrdiff = rtlefuse->txpwr_ht20diff[i][channel - 1]; | ||
176 | powerlevel[i] += ht20_pwrdiff; | ||
177 | } | ||
178 | powerBase1 = powerlevel[i]; | ||
179 | powerBase1 = (powerBase1 << 24) | | ||
180 | (powerBase1 << 16) | (powerBase1 << 8) | powerBase1; | ||
181 | |||
182 | *(mcsbase + i) = powerBase1; | ||
183 | |||
184 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | ||
185 | " [MCS power base index rf(%c) = 0x%x]\n", | ||
186 | ((i == 0) ? 'A' : 'B'), *(mcsbase + i)); | ||
187 | } | ||
188 | } | ||
189 | |||
190 | static void rtl8723ae_get_txpwr_val_by_reg(struct ieee80211_hw *hw, | ||
191 | u8 channel, u8 index, | ||
192 | u32 *powerBase0, | ||
193 | u32 *powerBase1, | ||
194 | u32 *p_outwriteval) | ||
195 | { | ||
196 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
197 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
198 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
199 | u8 i, chnlgroup = 0, pwr_diff_limit[4]; | ||
200 | u32 writeVal, customer_limit, rf; | ||
201 | |||
202 | for (rf = 0; rf < 2; rf++) { | ||
203 | switch (rtlefuse->eeprom_regulatory) { | ||
204 | case 0: | ||
205 | chnlgroup = 0; | ||
206 | |||
207 | writeVal = rtlphy->mcs_offset[chnlgroup] | ||
208 | [index + (rf ? 8 : 0)] + | ||
209 | ((index < 2) ? powerBase0[rf] : | ||
210 | powerBase1[rf]); | ||
211 | |||
212 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | ||
213 | "RTK better performance, " | ||
214 | "writeVal(%c) = 0x%x\n", | ||
215 | ((rf == 0) ? 'A' : 'B'), writeVal); | ||
216 | break; | ||
217 | case 1: | ||
218 | if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { | ||
219 | writeVal = ((index < 2) ? powerBase0[rf] : | ||
220 | powerBase1[rf]); | ||
221 | |||
222 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | ||
223 | "Realtek regulatory, 40MHz, " | ||
224 | "writeVal(%c) = 0x%x\n", | ||
225 | ((rf == 0) ? 'A' : 'B'), writeVal); | ||
226 | } else { | ||
227 | if (rtlphy->pwrgroup_cnt == 1) | ||
228 | chnlgroup = 0; | ||
229 | if (rtlphy->pwrgroup_cnt >= 3) { | ||
230 | if (channel <= 3) | ||
231 | chnlgroup = 0; | ||
232 | else if (channel >= 4 && channel <= 9) | ||
233 | chnlgroup = 1; | ||
234 | else if (channel > 9) | ||
235 | chnlgroup = 2; | ||
236 | if (rtlphy->current_chan_bw == | ||
237 | HT_CHANNEL_WIDTH_20) | ||
238 | chnlgroup++; | ||
239 | else | ||
240 | chnlgroup += 4; | ||
241 | } | ||
242 | |||
243 | writeVal = rtlphy->mcs_offset[chnlgroup] | ||
244 | [index + (rf ? 8 : 0)] + ((index < 2) ? | ||
245 | powerBase0[rf] : | ||
246 | powerBase1[rf]); | ||
247 | |||
248 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | ||
249 | "Realtek regulatory, 20MHz, writeVal(%c) = 0x%x\n", | ||
250 | ((rf == 0) ? 'A' : 'B'), writeVal); | ||
251 | } | ||
252 | break; | ||
253 | case 2: | ||
254 | writeVal = | ||
255 | ((index < 2) ? powerBase0[rf] : powerBase1[rf]); | ||
256 | |||
257 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | ||
258 | "Better regulatory, writeVal(%c) = 0x%x\n", | ||
259 | ((rf == 0) ? 'A' : 'B'), writeVal); | ||
260 | break; | ||
261 | case 3: | ||
262 | chnlgroup = 0; | ||
263 | |||
264 | if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { | ||
265 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | ||
266 | "customer's limit, 40MHz rf(%c) = 0x%x\n", | ||
267 | ((rf == 0) ? 'A' : 'B'), | ||
268 | rtlefuse->pwrgroup_ht40[rf][channel-1]); | ||
269 | } else { | ||
270 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | ||
271 | "customer's limit, 20MHz rf(%c) = 0x%x\n", | ||
272 | ((rf == 0) ? 'A' : 'B'), | ||
273 | rtlefuse->pwrgroup_ht20[rf][channel-1]); | ||
274 | } | ||
275 | for (i = 0; i < 4; i++) { | ||
276 | pwr_diff_limit[i] = | ||
277 | (u8) ((rtlphy->mcs_offset | ||
278 | [chnlgroup][index + (rf ? 8 : 0)] & | ||
279 | (0x7f << (i * 8))) >> (i * 8)); | ||
280 | |||
281 | if (rtlphy->current_chan_bw == | ||
282 | HT_CHANNEL_WIDTH_20_40) { | ||
283 | if (pwr_diff_limit[i] > | ||
284 | rtlefuse-> | ||
285 | pwrgroup_ht40[rf][channel - 1]) | ||
286 | pwr_diff_limit[i] = | ||
287 | rtlefuse->pwrgroup_ht40[rf] | ||
288 | [channel - 1]; | ||
289 | } else { | ||
290 | if (pwr_diff_limit[i] > | ||
291 | rtlefuse-> | ||
292 | pwrgroup_ht20[rf][channel - 1]) | ||
293 | pwr_diff_limit[i] = | ||
294 | rtlefuse->pwrgroup_ht20[rf] | ||
295 | [channel - 1]; | ||
296 | } | ||
297 | } | ||
298 | |||
299 | customer_limit = (pwr_diff_limit[3] << 24) | | ||
300 | (pwr_diff_limit[2] << 16) | | ||
301 | (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]); | ||
302 | |||
303 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | ||
304 | "Customer's limit rf(%c) = 0x%x\n", | ||
305 | ((rf == 0) ? 'A' : 'B'), customer_limit); | ||
306 | |||
307 | writeVal = customer_limit + | ||
308 | ((index < 2) ? powerBase0[rf] : powerBase1[rf]); | ||
309 | |||
310 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | ||
311 | "Customer, writeVal rf(%c)= 0x%x\n", | ||
312 | ((rf == 0) ? 'A' : 'B'), writeVal); | ||
313 | break; | ||
314 | default: | ||
315 | chnlgroup = 0; | ||
316 | writeVal = rtlphy->mcs_offset[chnlgroup][index + | ||
317 | (rf ? 8 : 0)] + ((index < 2) ? powerBase0[rf] : | ||
318 | powerBase1[rf]); | ||
319 | |||
320 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | ||
321 | "RTK better performance, writeVal rf(%c) = 0x%x\n", | ||
322 | ((rf == 0) ? 'A' : 'B'), writeVal); | ||
323 | break; | ||
324 | } | ||
325 | |||
326 | if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1) | ||
327 | writeVal = writeVal - 0x06060606; | ||
328 | else if (rtlpriv->dm.dynamic_txhighpower_lvl == | ||
329 | TXHIGHPWRLEVEL_BT2) | ||
330 | writeVal = writeVal - 0x0c0c0c0c; | ||
331 | *(p_outwriteval + rf) = writeVal; | ||
332 | } | ||
333 | } | ||
334 | |||
335 | static void _rtl8723ae_write_ofdm_power_reg(struct ieee80211_hw *hw, | ||
336 | u8 index, u32 *pValue) | ||
337 | { | ||
338 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
339 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
340 | |||
341 | u16 regoffset_a[6] = { | ||
342 | RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24, | ||
343 | RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04, | ||
344 | RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12 | ||
345 | }; | ||
346 | u16 regoffset_b[6] = { | ||
347 | RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24, | ||
348 | RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04, | ||
349 | RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12 | ||
350 | }; | ||
351 | u8 i, rf, pwr_val[4]; | ||
352 | u32 writeVal; | ||
353 | u16 regoffset; | ||
354 | |||
355 | for (rf = 0; rf < 2; rf++) { | ||
356 | writeVal = pValue[rf]; | ||
357 | for (i = 0; i < 4; i++) { | ||
358 | pwr_val[i] = (u8) ((writeVal & (0x7f << | ||
359 | (i * 8))) >> (i * 8)); | ||
360 | |||
361 | if (pwr_val[i] > RF6052_MAX_TX_PWR) | ||
362 | pwr_val[i] = RF6052_MAX_TX_PWR; | ||
363 | } | ||
364 | writeVal = (pwr_val[3] << 24) | (pwr_val[2] << 16) | | ||
365 | (pwr_val[1] << 8) | pwr_val[0]; | ||
366 | |||
367 | if (rf == 0) | ||
368 | regoffset = regoffset_a[index]; | ||
369 | else | ||
370 | regoffset = regoffset_b[index]; | ||
371 | rtl_set_bbreg(hw, regoffset, MASKDWORD, writeVal); | ||
372 | |||
373 | RTPRINT(rtlpriv, FPHY, PHY_TXPWR, | ||
374 | "Set 0x%x = %08x\n", regoffset, writeVal); | ||
375 | |||
376 | if (((get_rf_type(rtlphy) == RF_2T2R) && | ||
377 | (regoffset == RTXAGC_A_MCS15_MCS12 || | ||
378 | regoffset == RTXAGC_B_MCS15_MCS12)) || | ||
379 | ((get_rf_type(rtlphy) != RF_2T2R) && | ||
380 | (regoffset == RTXAGC_A_MCS07_MCS04 || | ||
381 | regoffset == RTXAGC_B_MCS07_MCS04))) { | ||
382 | |||
383 | writeVal = pwr_val[3]; | ||
384 | if (regoffset == RTXAGC_A_MCS15_MCS12 || | ||
385 | regoffset == RTXAGC_A_MCS07_MCS04) | ||
386 | regoffset = 0xc90; | ||
387 | if (regoffset == RTXAGC_B_MCS15_MCS12 || | ||
388 | regoffset == RTXAGC_B_MCS07_MCS04) | ||
389 | regoffset = 0xc98; | ||
390 | |||
391 | for (i = 0; i < 3; i++) { | ||
392 | writeVal = (writeVal > 6) ? (writeVal - 6) : 0; | ||
393 | rtl_write_byte(rtlpriv, (u32) (regoffset + i), | ||
394 | (u8) writeVal); | ||
395 | } | ||
396 | } | ||
397 | } | ||
398 | } | ||
399 | |||
400 | void rtl8723ae_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, | ||
401 | u8 *ppowerlevel, u8 channel) | ||
402 | { | ||
403 | u32 writeVal[2], powerBase0[2], powerBase1[2]; | ||
404 | u8 index; | ||
405 | |||
406 | rtl8723ae_phy_get_power_base(hw, ppowerlevel, | ||
407 | channel, &powerBase0[0], &powerBase1[0]); | ||
408 | |||
409 | for (index = 0; index < 6; index++) { | ||
410 | rtl8723ae_get_txpwr_val_by_reg(hw, channel, index, | ||
411 | &powerBase0[0], | ||
412 | &powerBase1[0], | ||
413 | &writeVal[0]); | ||
414 | |||
415 | _rtl8723ae_write_ofdm_power_reg(hw, index, &writeVal[0]); | ||
416 | } | ||
417 | } | ||
418 | |||
419 | static bool _rtl8723ae_phy_rf6052_config_parafile(struct ieee80211_hw *hw) | ||
420 | { | ||
421 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
422 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
423 | u32 u4_regvalue = 0; | ||
424 | u8 rfpath; | ||
425 | bool rtstatus = true; | ||
426 | struct bb_reg_def *pphyreg; | ||
427 | |||
428 | for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { | ||
429 | |||
430 | pphyreg = &rtlphy->phyreg_def[rfpath]; | ||
431 | |||
432 | switch (rfpath) { | ||
433 | case RF90_PATH_A: | ||
434 | case RF90_PATH_C: | ||
435 | u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, | ||
436 | BRFSI_RFENV); | ||
437 | break; | ||
438 | case RF90_PATH_B: | ||
439 | case RF90_PATH_D: | ||
440 | u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, | ||
441 | BRFSI_RFENV << 16); | ||
442 | break; | ||
443 | } | ||
444 | |||
445 | rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1); | ||
446 | udelay(1); | ||
447 | |||
448 | rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1); | ||
449 | udelay(1); | ||
450 | |||
451 | rtl_set_bbreg(hw, pphyreg->rfhssi_para2, | ||
452 | B3WIREADDREAALENGTH, 0x0); | ||
453 | udelay(1); | ||
454 | |||
455 | rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0); | ||
456 | udelay(1); | ||
457 | |||
458 | switch (rfpath) { | ||
459 | case RF90_PATH_A: | ||
460 | rtstatus = rtl8723ae_phy_config_rf_with_headerfile(hw, | ||
461 | (enum radio_path)rfpath); | ||
462 | break; | ||
463 | case RF90_PATH_B: | ||
464 | rtstatus = rtl8723ae_phy_config_rf_with_headerfile(hw, | ||
465 | (enum radio_path)rfpath); | ||
466 | break; | ||
467 | case RF90_PATH_C: | ||
468 | break; | ||
469 | case RF90_PATH_D: | ||
470 | break; | ||
471 | } | ||
472 | switch (rfpath) { | ||
473 | case RF90_PATH_A: | ||
474 | case RF90_PATH_C: | ||
475 | rtl_set_bbreg(hw, pphyreg->rfintfs, | ||
476 | BRFSI_RFENV, u4_regvalue); | ||
477 | break; | ||
478 | case RF90_PATH_B: | ||
479 | case RF90_PATH_D: | ||
480 | rtl_set_bbreg(hw, pphyreg->rfintfs, | ||
481 | BRFSI_RFENV << 16, u4_regvalue); | ||
482 | break; | ||
483 | } | ||
484 | if (rtstatus != true) { | ||
485 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
486 | "Radio[%d] Fail!!", rfpath); | ||
487 | return false; | ||
488 | } | ||
489 | } | ||
490 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n"); | ||
491 | return rtstatus; | ||
492 | } | ||
493 | |||
494 | bool rtl8723ae_phy_rf6052_config(struct ieee80211_hw *hw) | ||
495 | { | ||
496 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
497 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
498 | |||
499 | if (rtlphy->rf_type == RF_1T1R) | ||
500 | rtlphy->num_total_rfpath = 1; | ||
501 | else | ||
502 | rtlphy->num_total_rfpath = 2; | ||
503 | |||
504 | return _rtl8723ae_phy_rf6052_config_parafile(hw); | ||
505 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h b/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h new file mode 100644 index 000000000000..d0f9dd79abea --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h | |||
@@ -0,0 +1,43 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 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 __RTL8723E_RF_H__ | ||
31 | #define __RTL8723E_RF_H__ | ||
32 | |||
33 | #define RF6052_MAX_TX_PWR 0x3F | ||
34 | |||
35 | extern void rtl8723ae_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, | ||
36 | u8 bandwidth); | ||
37 | extern void rtl8723ae_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, | ||
38 | u8 *ppowerlevel); | ||
39 | extern void rtl8723ae_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, | ||
40 | u8 *ppowerlevel, u8 channel); | ||
41 | extern bool rtl8723ae_phy_rf6052_config(struct ieee80211_hw *hw); | ||
42 | |||
43 | #endif | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c new file mode 100644 index 000000000000..0afdc240f2fd --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c | |||
@@ -0,0 +1,387 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 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 <linux/vmalloc.h> | ||
32 | #include <linux/module.h> | ||
33 | |||
34 | #include "../core.h" | ||
35 | #include "../pci.h" | ||
36 | #include "reg.h" | ||
37 | #include "def.h" | ||
38 | #include "phy.h" | ||
39 | #include "dm.h" | ||
40 | #include "hw.h" | ||
41 | #include "sw.h" | ||
42 | #include "trx.h" | ||
43 | #include "led.h" | ||
44 | #include "table.h" | ||
45 | #include "hal_btc.h" | ||
46 | |||
47 | static void rtl8723ae_init_aspm_vars(struct ieee80211_hw *hw) | ||
48 | { | ||
49 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
50 | |||
51 | /*close ASPM for AMD defaultly */ | ||
52 | rtlpci->const_amdpci_aspm = 0; | ||
53 | |||
54 | /* ASPM PS mode. | ||
55 | * 0 - Disable ASPM, | ||
56 | * 1 - Enable ASPM without Clock Req, | ||
57 | * 2 - Enable ASPM with Clock Req, | ||
58 | * 3 - Alwyas Enable ASPM with Clock Req, | ||
59 | * 4 - Always Enable ASPM without Clock Req. | ||
60 | * set defult to RTL8192CE:3 RTL8192E:2 | ||
61 | */ | ||
62 | rtlpci->const_pci_aspm = 3; | ||
63 | |||
64 | /*Setting for PCI-E device */ | ||
65 | rtlpci->const_devicepci_aspm_setting = 0x03; | ||
66 | |||
67 | /*Setting for PCI-E bridge */ | ||
68 | rtlpci->const_hostpci_aspm_setting = 0x02; | ||
69 | |||
70 | /* In Hw/Sw Radio Off situation. | ||
71 | * 0 - Default, | ||
72 | * 1 - From ASPM setting without low Mac Pwr, | ||
73 | * 2 - From ASPM setting with low Mac Pwr, | ||
74 | * 3 - Bus D3 | ||
75 | * set default to RTL8192CE:0 RTL8192SE:2 | ||
76 | */ | ||
77 | rtlpci->const_hwsw_rfoff_d3 = 0; | ||
78 | |||
79 | /* This setting works for those device with | ||
80 | * backdoor ASPM setting such as EPHY setting. | ||
81 | * 0 - Not support ASPM, | ||
82 | * 1 - Support ASPM, | ||
83 | * 2 - According to chipset. | ||
84 | */ | ||
85 | rtlpci->const_support_pciaspm = 1; | ||
86 | } | ||
87 | |||
88 | int rtl8723ae_init_sw_vars(struct ieee80211_hw *hw) | ||
89 | { | ||
90 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
91 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
92 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
93 | int err; | ||
94 | |||
95 | rtl8723ae_bt_reg_init(hw); | ||
96 | rtlpriv->dm.dm_initialgain_enable = 1; | ||
97 | rtlpriv->dm.dm_flag = 0; | ||
98 | rtlpriv->dm.disable_framebursting = 0; | ||
99 | rtlpriv->dm.thermalvalue = 0; | ||
100 | rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13); | ||
101 | |||
102 | /* compatible 5G band 88ce just 2.4G band & smsp */ | ||
103 | rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G; | ||
104 | rtlpriv->rtlhal.bandset = BAND_ON_2_4G; | ||
105 | rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY; | ||
106 | |||
107 | rtlpci->receive_config = (RCR_APPFCS | | ||
108 | RCR_APP_MIC | | ||
109 | RCR_APP_ICV | | ||
110 | RCR_APP_PHYST_RXFF | | ||
111 | RCR_HTC_LOC_CTRL | | ||
112 | RCR_AMF | | ||
113 | RCR_ACF | | ||
114 | RCR_ADF | | ||
115 | RCR_AICV | | ||
116 | RCR_AB | | ||
117 | RCR_AM | | ||
118 | RCR_APM | | ||
119 | 0); | ||
120 | |||
121 | rtlpci->irq_mask[0] = | ||
122 | (u32) (PHIMR_ROK | | ||
123 | PHIMR_RDU | | ||
124 | PHIMR_VODOK | | ||
125 | PHIMR_VIDOK | | ||
126 | PHIMR_BEDOK | | ||
127 | PHIMR_BKDOK | | ||
128 | PHIMR_MGNTDOK | | ||
129 | PHIMR_HIGHDOK | | ||
130 | PHIMR_C2HCMD | | ||
131 | PHIMR_HISRE_IND | | ||
132 | PHIMR_TSF_BIT32_TOGGLE | | ||
133 | PHIMR_TXBCNOK | | ||
134 | PHIMR_PSTIMEOUT | | ||
135 | 0); | ||
136 | |||
137 | rtlpci->irq_mask[1] = (u32)(PHIMR_RXFOVW | 0); | ||
138 | |||
139 | /* for debug level */ | ||
140 | rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug; | ||
141 | /* for LPS & IPS */ | ||
142 | rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; | ||
143 | rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; | ||
144 | rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps; | ||
145 | rtlpriv->psc.reg_fwctrl_lps = 3; | ||
146 | rtlpriv->psc.reg_max_lps_awakeintvl = 5; | ||
147 | /* for ASPM, you can close aspm through | ||
148 | * set const_support_pciaspm = 0 | ||
149 | */ | ||
150 | rtl8723ae_init_aspm_vars(hw); | ||
151 | |||
152 | if (rtlpriv->psc.reg_fwctrl_lps == 1) | ||
153 | rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE; | ||
154 | else if (rtlpriv->psc.reg_fwctrl_lps == 2) | ||
155 | rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE; | ||
156 | else if (rtlpriv->psc.reg_fwctrl_lps == 3) | ||
157 | rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE; | ||
158 | |||
159 | /* for firmware buf */ | ||
160 | rtlpriv->rtlhal.pfirmware = vmalloc(0x6000); | ||
161 | if (!rtlpriv->rtlhal.pfirmware) { | ||
162 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
163 | "Can't alloc buffer for fw.\n"); | ||
164 | return 1; | ||
165 | } | ||
166 | |||
167 | if (IS_VENDOR_8723_A_CUT(rtlhal->version)) | ||
168 | rtlpriv->cfg->fw_name = "rtlwifi/rtl8723fw.bin"; | ||
169 | else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) | ||
170 | rtlpriv->cfg->fw_name = "rtlwifi/rtl8723fw_B.bin"; | ||
171 | |||
172 | rtlpriv->max_fw_size = 0x6000; | ||
173 | pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name); | ||
174 | err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, | ||
175 | rtlpriv->io.dev, GFP_KERNEL, hw, | ||
176 | rtl_fw_cb); | ||
177 | if (err) { | ||
178 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
179 | "Failed to request firmware!\n"); | ||
180 | return 1; | ||
181 | } | ||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | void rtl8723ae_deinit_sw_vars(struct ieee80211_hw *hw) | ||
186 | { | ||
187 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
188 | |||
189 | if (rtlpriv->rtlhal.pfirmware) { | ||
190 | vfree(rtlpriv->rtlhal.pfirmware); | ||
191 | rtlpriv->rtlhal.pfirmware = NULL; | ||
192 | } | ||
193 | } | ||
194 | |||
195 | static struct rtl_hal_ops rtl8723ae_hal_ops = { | ||
196 | .init_sw_vars = rtl8723ae_init_sw_vars, | ||
197 | .deinit_sw_vars = rtl8723ae_deinit_sw_vars, | ||
198 | .read_eeprom_info = rtl8723ae_read_eeprom_info, | ||
199 | .interrupt_recognized = rtl8723ae_interrupt_recognized, | ||
200 | .hw_init = rtl8723ae_hw_init, | ||
201 | .hw_disable = rtl8723ae_card_disable, | ||
202 | .hw_suspend = rtl8723ae_suspend, | ||
203 | .hw_resume = rtl8723ae_resume, | ||
204 | .enable_interrupt = rtl8723ae_enable_interrupt, | ||
205 | .disable_interrupt = rtl8723ae_disable_interrupt, | ||
206 | .set_network_type = rtl8723ae_set_network_type, | ||
207 | .set_chk_bssid = rtl8723ae_set_check_bssid, | ||
208 | .set_qos = rtl8723ae_set_qos, | ||
209 | .set_bcn_reg = rtl8723ae_set_beacon_related_registers, | ||
210 | .set_bcn_intv = rtl8723ae_set_beacon_interval, | ||
211 | .update_interrupt_mask = rtl8723ae_update_interrupt_mask, | ||
212 | .get_hw_reg = rtl8723ae_get_hw_reg, | ||
213 | .set_hw_reg = rtl8723ae_set_hw_reg, | ||
214 | .update_rate_tbl = rtl8723ae_update_hal_rate_tbl, | ||
215 | .fill_tx_desc = rtl8723ae_tx_fill_desc, | ||
216 | .fill_tx_cmddesc = rtl8723ae_tx_fill_cmddesc, | ||
217 | .query_rx_desc = rtl8723ae_rx_query_desc, | ||
218 | .set_channel_access = rtl8723ae_update_channel_access_setting, | ||
219 | .radio_onoff_checking = rtl8723ae_gpio_radio_on_off_checking, | ||
220 | .set_bw_mode = rtl8723ae_phy_set_bw_mode, | ||
221 | .switch_channel = rtl8723ae_phy_sw_chnl, | ||
222 | .dm_watchdog = rtl8723ae_dm_watchdog, | ||
223 | .scan_operation_backup = rtl8723ae_phy_scan_operation_backup, | ||
224 | .set_rf_power_state = rtl8723ae_phy_set_rf_power_state, | ||
225 | .led_control = rtl8723ae_led_control, | ||
226 | .set_desc = rtl8723ae_set_desc, | ||
227 | .get_desc = rtl8723ae_get_desc, | ||
228 | .tx_polling = rtl8723ae_tx_polling, | ||
229 | .enable_hw_sec = rtl8723ae_enable_hw_security_config, | ||
230 | .set_key = rtl8723ae_set_key, | ||
231 | .init_sw_leds = rtl8723ae_init_sw_leds, | ||
232 | .allow_all_destaddr = rtl8723ae_allow_all_destaddr, | ||
233 | .get_bbreg = rtl8723ae_phy_query_bb_reg, | ||
234 | .set_bbreg = rtl8723ae_phy_set_bb_reg, | ||
235 | .get_rfreg = rtl8723ae_phy_query_rf_reg, | ||
236 | .set_rfreg = rtl8723ae_phy_set_rf_reg, | ||
237 | .c2h_command_handle = rtl_8723e_c2h_command_handle, | ||
238 | .bt_wifi_media_status_notify = rtl_8723e_bt_wifi_media_status_notify, | ||
239 | .bt_coex_off_before_lps = rtl8723ae_bt_coex_off_before_lps, | ||
240 | }; | ||
241 | |||
242 | static struct rtl_mod_params rtl8723ae_mod_params = { | ||
243 | .sw_crypto = false, | ||
244 | .inactiveps = true, | ||
245 | .swctrl_lps = false, | ||
246 | .fwctrl_lps = true, | ||
247 | .debug = DBG_EMERG, | ||
248 | }; | ||
249 | |||
250 | static struct rtl_hal_cfg rtl8723ae_hal_cfg = { | ||
251 | .bar_id = 2, | ||
252 | .write_readback = true, | ||
253 | .name = "rtl8723ae_pci", | ||
254 | .fw_name = "rtlwifi/rtl8723aefw.bin", | ||
255 | .ops = &rtl8723ae_hal_ops, | ||
256 | .mod_params = &rtl8723ae_mod_params, | ||
257 | .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, | ||
258 | .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN, | ||
259 | .maps[SYS_CLK] = REG_SYS_CLKR, | ||
260 | .maps[MAC_RCR_AM] = AM, | ||
261 | .maps[MAC_RCR_AB] = AB, | ||
262 | .maps[MAC_RCR_ACRC32] = ACRC32, | ||
263 | .maps[MAC_RCR_ACF] = ACF, | ||
264 | .maps[MAC_RCR_AAP] = AAP, | ||
265 | .maps[EFUSE_TEST] = REG_EFUSE_TEST, | ||
266 | .maps[EFUSE_CTRL] = REG_EFUSE_CTRL, | ||
267 | .maps[EFUSE_CLK] = 0, | ||
268 | .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL, | ||
269 | .maps[EFUSE_PWC_EV12V] = PWC_EV12V, | ||
270 | .maps[EFUSE_FEN_ELDR] = FEN_ELDR, | ||
271 | .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN, | ||
272 | .maps[EFUSE_ANA8M] = ANA8M, | ||
273 | .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE, | ||
274 | .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION, | ||
275 | .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN, | ||
276 | .maps[EFUSE_OOB_PROTECT_BYTES_LEN] = EFUSE_OOB_PROTECT_BYTES, | ||
277 | |||
278 | .maps[RWCAM] = REG_CAMCMD, | ||
279 | .maps[WCAMI] = REG_CAMWRITE, | ||
280 | .maps[RCAMO] = REG_CAMREAD, | ||
281 | .maps[CAMDBG] = REG_CAMDBG, | ||
282 | .maps[SECR] = REG_SECCFG, | ||
283 | .maps[SEC_CAM_NONE] = CAM_NONE, | ||
284 | .maps[SEC_CAM_WEP40] = CAM_WEP40, | ||
285 | .maps[SEC_CAM_TKIP] = CAM_TKIP, | ||
286 | .maps[SEC_CAM_AES] = CAM_AES, | ||
287 | .maps[SEC_CAM_WEP104] = CAM_WEP104, | ||
288 | |||
289 | .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6, | ||
290 | .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5, | ||
291 | .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4, | ||
292 | .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3, | ||
293 | .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2, | ||
294 | .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1, | ||
295 | .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8, | ||
296 | .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7, | ||
297 | .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6, | ||
298 | .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5, | ||
299 | .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4, | ||
300 | .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3, | ||
301 | .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2, | ||
302 | .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1, | ||
303 | .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2, | ||
304 | .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1, | ||
305 | |||
306 | .maps[RTL_IMR_TXFOVW] = PHIMR_TXFOVW, | ||
307 | .maps[RTL_IMR_PSTIMEOUT] = PHIMR_PSTIMEOUT, | ||
308 | .maps[RTL_IMR_BcnInt] = PHIMR_BCNDMAINT0, | ||
309 | .maps[RTL_IMR_RXFOVW] = PHIMR_RXFOVW, | ||
310 | .maps[RTL_IMR_RDU] = PHIMR_RDU, | ||
311 | .maps[RTL_IMR_ATIMEND] = PHIMR_ATIMEND_E, | ||
312 | .maps[RTL_IMR_BDOK] = PHIMR_BCNDOK0, | ||
313 | .maps[RTL_IMR_MGNTDOK] = PHIMR_MGNTDOK, | ||
314 | .maps[RTL_IMR_TBDER] = PHIMR_TXBCNERR, | ||
315 | .maps[RTL_IMR_HIGHDOK] = PHIMR_HIGHDOK, | ||
316 | .maps[RTL_IMR_TBDOK] = PHIMR_TXBCNOK, | ||
317 | .maps[RTL_IMR_BKDOK] = PHIMR_BKDOK, | ||
318 | .maps[RTL_IMR_BEDOK] = PHIMR_BEDOK, | ||
319 | .maps[RTL_IMR_VIDOK] = PHIMR_VIDOK, | ||
320 | .maps[RTL_IMR_VODOK] = PHIMR_VODOK, | ||
321 | .maps[RTL_IMR_ROK] = PHIMR_ROK, | ||
322 | .maps[RTL_IBSS_INT_MASKS] = (PHIMR_BCNDMAINT0 | | ||
323 | PHIMR_TXBCNOK | PHIMR_TXBCNERR), | ||
324 | .maps[RTL_IMR_C2HCMD] = PHIMR_C2HCMD, | ||
325 | |||
326 | |||
327 | .maps[RTL_RC_CCK_RATE1M] = DESC92_RATE1M, | ||
328 | .maps[RTL_RC_CCK_RATE2M] = DESC92_RATE2M, | ||
329 | .maps[RTL_RC_CCK_RATE5_5M] = DESC92_RATE5_5M, | ||
330 | .maps[RTL_RC_CCK_RATE11M] = DESC92_RATE11M, | ||
331 | .maps[RTL_RC_OFDM_RATE6M] = DESC92_RATE6M, | ||
332 | .maps[RTL_RC_OFDM_RATE9M] = DESC92_RATE9M, | ||
333 | .maps[RTL_RC_OFDM_RATE12M] = DESC92_RATE12M, | ||
334 | .maps[RTL_RC_OFDM_RATE18M] = DESC92_RATE18M, | ||
335 | .maps[RTL_RC_OFDM_RATE24M] = DESC92_RATE24M, | ||
336 | .maps[RTL_RC_OFDM_RATE36M] = DESC92_RATE36M, | ||
337 | .maps[RTL_RC_OFDM_RATE48M] = DESC92_RATE48M, | ||
338 | .maps[RTL_RC_OFDM_RATE54M] = DESC92_RATE54M, | ||
339 | |||
340 | .maps[RTL_RC_HT_RATEMCS7] = DESC92_RATEMCS7, | ||
341 | .maps[RTL_RC_HT_RATEMCS15] = DESC92_RATEMCS15, | ||
342 | }; | ||
343 | |||
344 | static struct pci_device_id rtl8723ae_pci_ids[] __devinitdata = { | ||
345 | {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8723, rtl8723ae_hal_cfg)}, | ||
346 | {}, | ||
347 | }; | ||
348 | |||
349 | MODULE_DEVICE_TABLE(pci, rtl8723ae_pci_ids); | ||
350 | |||
351 | MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>"); | ||
352 | MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>"); | ||
353 | MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>"); | ||
354 | MODULE_LICENSE("GPL"); | ||
355 | MODULE_DESCRIPTION("Realtek 8723E 802.11n PCI wireless"); | ||
356 | MODULE_FIRMWARE("rtlwifi/rtl8723aefw.bin"); | ||
357 | MODULE_FIRMWARE("rtlwifi/rtl8723aefw_B.bin"); | ||
358 | |||
359 | module_param_named(swenc, rtl8723ae_mod_params.sw_crypto, bool, 0444); | ||
360 | module_param_named(debug, rtl8723ae_mod_params.debug, int, 0444); | ||
361 | module_param_named(ips, rtl8723ae_mod_params.inactiveps, bool, 0444); | ||
362 | module_param_named(swlps, rtl8723ae_mod_params.swctrl_lps, bool, 0444); | ||
363 | module_param_named(fwlps, rtl8723ae_mod_params.fwctrl_lps, bool, 0444); | ||
364 | MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n"); | ||
365 | MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n"); | ||
366 | MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n"); | ||
367 | MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); | ||
368 | MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); | ||
369 | |||
370 | static const struct dev_pm_ops rtlwifi_pm_ops = { | ||
371 | .suspend = rtl_pci_suspend, | ||
372 | .resume = rtl_pci_resume, | ||
373 | .freeze = rtl_pci_suspend, | ||
374 | .thaw = rtl_pci_resume, | ||
375 | .poweroff = rtl_pci_suspend, | ||
376 | .restore = rtl_pci_resume, | ||
377 | }; | ||
378 | |||
379 | static struct pci_driver rtl8723ae_driver = { | ||
380 | .name = KBUILD_MODNAME, | ||
381 | .id_table = rtl8723ae_pci_ids, | ||
382 | .probe = rtl_pci_probe, | ||
383 | .remove = rtl_pci_disconnect, | ||
384 | .driver.pm = &rtlwifi_pm_ops, | ||
385 | }; | ||
386 | |||
387 | module_pci_driver(rtl8723ae_driver); | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/sw.h b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.h new file mode 100644 index 000000000000..fc4fde5e3eb5 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.h | |||
@@ -0,0 +1,37 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 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 __RTL8723E_SW_H__ | ||
31 | #define __RTL8723E_SW_H__ | ||
32 | |||
33 | int rtl8723ae_init_sw_vars(struct ieee80211_hw *hw); | ||
34 | void rtl8723ae_deinit_sw_vars(struct ieee80211_hw *hw); | ||
35 | void rtl8723ae_init_var_map(struct ieee80211_hw *hw); | ||
36 | |||
37 | #endif | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/table.c b/drivers/net/wireless/rtlwifi/rtl8723ae/table.c new file mode 100644 index 000000000000..9b0b50cc4ade --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/table.c | |||
@@ -0,0 +1,738 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 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 | * Created on 2010/ 5/18, 1:41 | ||
27 | * | ||
28 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
29 | * | ||
30 | *****************************************************************************/ | ||
31 | |||
32 | #include "table.h" | ||
33 | |||
34 | u32 RTL8723EPHY_REG_1TARRAY[RTL8723E_PHY_REG_1TARRAY_LENGTH] = { | ||
35 | 0x800, 0x80040000, | ||
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, 0x00000000, | ||
46 | 0x82c, 0x00000000, | ||
47 | 0x830, 0x00000000, | ||
48 | 0x834, 0x00000000, | ||
49 | 0x838, 0x00000000, | ||
50 | 0x83c, 0x00000000, | ||
51 | 0x840, 0x00010000, | ||
52 | 0x844, 0x00000000, | ||
53 | 0x848, 0x00000000, | ||
54 | 0x84c, 0x00000000, | ||
55 | 0x850, 0x00000000, | ||
56 | 0x854, 0x00000000, | ||
57 | 0x858, 0x569a569a, | ||
58 | 0x85c, 0x001b25a4, | ||
59 | 0x860, 0x66f60110, | ||
60 | 0x864, 0x061f0130, | ||
61 | 0x868, 0x00000000, | ||
62 | 0x86c, 0x32323200, | ||
63 | 0x870, 0x07000760, | ||
64 | 0x874, 0x22004000, | ||
65 | 0x878, 0x00000808, | ||
66 | 0x87c, 0x00000000, | ||
67 | 0x880, 0xc0083070, | ||
68 | 0x884, 0x000004d5, | ||
69 | 0x888, 0x00000000, | ||
70 | 0x88c, 0xccc000c0, | ||
71 | 0x890, 0x00000800, | ||
72 | 0x894, 0xfffffffe, | ||
73 | 0x898, 0x40302010, | ||
74 | 0x89c, 0x00706050, | ||
75 | 0x900, 0x00000000, | ||
76 | 0x904, 0x00000023, | ||
77 | 0x908, 0x00000000, | ||
78 | 0x90c, 0x81121111, | ||
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 | 0xa78, 0x00000900, | ||
94 | 0xc00, 0x48071d40, | ||
95 | 0xc04, 0x03a05611, | ||
96 | 0xc08, 0x000000e4, | ||
97 | 0xc0c, 0x6c6c6c6c, | ||
98 | 0xc10, 0x08800000, | ||
99 | 0xc14, 0x40000100, | ||
100 | 0xc18, 0x08800000, | ||
101 | 0xc1c, 0x40000100, | ||
102 | 0xc20, 0x00000000, | ||
103 | 0xc24, 0x00000000, | ||
104 | 0xc28, 0x00000000, | ||
105 | 0xc2c, 0x00000000, | ||
106 | 0xc30, 0x69e9ac44, | ||
107 | 0xc34, 0x469652cf, | ||
108 | 0xc38, 0x49795994, | ||
109 | 0xc3c, 0x0a97971c, | ||
110 | 0xc40, 0x1f7c403f, | ||
111 | 0xc44, 0x000100b7, | ||
112 | 0xc48, 0xec020107, | ||
113 | 0xc4c, 0x007f037f, | ||
114 | 0xc50, 0x69543420, | ||
115 | 0xc54, 0x43bc0094, | ||
116 | 0xc58, 0x69543420, | ||
117 | 0xc5c, 0x433c0094, | ||
118 | 0xc60, 0x00000000, | ||
119 | 0xc64, 0x7116848b, | ||
120 | 0xc68, 0x47c00bff, | ||
121 | 0xc6c, 0x00000036, | ||
122 | 0xc70, 0x2c7f000d, | ||
123 | 0xc74, 0x018610db, | ||
124 | 0xc78, 0x0000001f, | ||
125 | 0xc7c, 0x00b91612, | ||
126 | 0xc80, 0x40000100, | ||
127 | 0xc84, 0x20f60000, | ||
128 | 0xc88, 0x40000100, | ||
129 | 0xc8c, 0x20200000, | ||
130 | 0xc90, 0x00121820, | ||
131 | 0xc94, 0x00000000, | ||
132 | 0xc98, 0x00121820, | ||
133 | 0xc9c, 0x00007f7f, | ||
134 | 0xca0, 0x00000000, | ||
135 | 0xca4, 0x00000080, | ||
136 | 0xca8, 0x00000000, | ||
137 | 0xcac, 0x00000000, | ||
138 | 0xcb0, 0x00000000, | ||
139 | 0xcb4, 0x00000000, | ||
140 | 0xcb8, 0x00000000, | ||
141 | 0xcbc, 0x28000000, | ||
142 | 0xcc0, 0x00000000, | ||
143 | 0xcc4, 0x00000000, | ||
144 | 0xcc8, 0x00000000, | ||
145 | 0xccc, 0x00000000, | ||
146 | 0xcd0, 0x00000000, | ||
147 | 0xcd4, 0x00000000, | ||
148 | 0xcd8, 0x64b22427, | ||
149 | 0xcdc, 0x00766932, | ||
150 | 0xce0, 0x00222222, | ||
151 | 0xce4, 0x00000000, | ||
152 | 0xce8, 0x37644302, | ||
153 | 0xcec, 0x2f97d40c, | ||
154 | 0xd00, 0x00080740, | ||
155 | 0xd04, 0x00020401, | ||
156 | 0xd08, 0x0000907f, | ||
157 | 0xd0c, 0x20010201, | ||
158 | 0xd10, 0xa0633333, | ||
159 | 0xd14, 0x3333bc43, | ||
160 | 0xd18, 0x7a8f5b6b, | ||
161 | 0xd2c, 0xcc979975, | ||
162 | 0xd30, 0x00000000, | ||
163 | 0xd34, 0x80608000, | ||
164 | 0xd38, 0x00000000, | ||
165 | 0xd3c, 0x00027293, | ||
166 | 0xd40, 0x00000000, | ||
167 | 0xd44, 0x00000000, | ||
168 | 0xd48, 0x00000000, | ||
169 | 0xd4c, 0x00000000, | ||
170 | 0xd50, 0x6437140a, | ||
171 | 0xd54, 0x00000000, | ||
172 | 0xd58, 0x00000000, | ||
173 | 0xd5c, 0x30032064, | ||
174 | 0xd60, 0x4653de68, | ||
175 | 0xd64, 0x04518a3c, | ||
176 | 0xd68, 0x00002101, | ||
177 | 0xd6c, 0x2a201c16, | ||
178 | 0xd70, 0x1812362e, | ||
179 | 0xd74, 0x322c2220, | ||
180 | 0xd78, 0x000e3c24, | ||
181 | 0xe00, 0x2a2a2a2a, | ||
182 | 0xe04, 0x2a2a2a2a, | ||
183 | 0xe08, 0x03902a2a, | ||
184 | 0xe10, 0x2a2a2a2a, | ||
185 | 0xe14, 0x2a2a2a2a, | ||
186 | 0xe18, 0x2a2a2a2a, | ||
187 | 0xe1c, 0x2a2a2a2a, | ||
188 | 0xe28, 0x00000000, | ||
189 | 0xe30, 0x1000dc1f, | ||
190 | 0xe34, 0x10008c1f, | ||
191 | 0xe38, 0x02140102, | ||
192 | 0xe3c, 0x681604c2, | ||
193 | 0xe40, 0x01007c00, | ||
194 | 0xe44, 0x01004800, | ||
195 | 0xe48, 0xfb000000, | ||
196 | 0xe4c, 0x000028d1, | ||
197 | 0xe50, 0x1000dc1f, | ||
198 | 0xe54, 0x10008c1f, | ||
199 | 0xe58, 0x02140102, | ||
200 | 0xe5c, 0x28160d05, | ||
201 | 0xe60, 0x00000008, | ||
202 | 0xe68, 0x001b25a4, | ||
203 | 0xe6c, 0x631b25a0, | ||
204 | 0xe70, 0x631b25a0, | ||
205 | 0xe74, 0x081b25a0, | ||
206 | 0xe78, 0x081b25a0, | ||
207 | 0xe7c, 0x081b25a0, | ||
208 | 0xe80, 0x081b25a0, | ||
209 | 0xe84, 0x631b25a0, | ||
210 | 0xe88, 0x081b25a0, | ||
211 | 0xe8c, 0x631b25a0, | ||
212 | 0xed0, 0x631b25a0, | ||
213 | 0xed4, 0x631b25a0, | ||
214 | 0xed8, 0x631b25a0, | ||
215 | 0xedc, 0x001b25a0, | ||
216 | 0xee0, 0x001b25a0, | ||
217 | 0xeec, 0x6b1b25a0, | ||
218 | 0xf14, 0x00000003, | ||
219 | 0xf4c, 0x00000000, | ||
220 | 0xf00, 0x00000300, | ||
221 | }; | ||
222 | |||
223 | u32 RTL8723EPHY_REG_ARRAY_PG[RTL8723E_PHY_REG_ARRAY_PGLENGTH] = { | ||
224 | 0xe00, 0xffffffff, 0x0a0c0c0c, | ||
225 | 0xe04, 0xffffffff, 0x02040608, | ||
226 | 0xe08, 0x0000ff00, 0x00000000, | ||
227 | 0x86c, 0xffffff00, 0x00000000, | ||
228 | 0xe10, 0xffffffff, 0x0a0c0d0e, | ||
229 | 0xe14, 0xffffffff, 0x02040608, | ||
230 | 0xe18, 0xffffffff, 0x0a0c0d0e, | ||
231 | 0xe1c, 0xffffffff, 0x02040608, | ||
232 | 0x830, 0xffffffff, 0x0a0c0c0c, | ||
233 | 0x834, 0xffffffff, 0x02040608, | ||
234 | 0x838, 0xffffff00, 0x00000000, | ||
235 | 0x86c, 0x000000ff, 0x00000000, | ||
236 | 0x83c, 0xffffffff, 0x0a0c0d0e, | ||
237 | 0x848, 0xffffffff, 0x02040608, | ||
238 | 0x84c, 0xffffffff, 0x0a0c0d0e, | ||
239 | 0x868, 0xffffffff, 0x02040608, | ||
240 | 0xe00, 0xffffffff, 0x00000000, | ||
241 | 0xe04, 0xffffffff, 0x00000000, | ||
242 | 0xe08, 0x0000ff00, 0x00000000, | ||
243 | 0x86c, 0xffffff00, 0x00000000, | ||
244 | 0xe10, 0xffffffff, 0x00000000, | ||
245 | 0xe14, 0xffffffff, 0x00000000, | ||
246 | 0xe18, 0xffffffff, 0x00000000, | ||
247 | 0xe1c, 0xffffffff, 0x00000000, | ||
248 | 0x830, 0xffffffff, 0x00000000, | ||
249 | 0x834, 0xffffffff, 0x00000000, | ||
250 | 0x838, 0xffffff00, 0x00000000, | ||
251 | 0x86c, 0x000000ff, 0x00000000, | ||
252 | 0x83c, 0xffffffff, 0x00000000, | ||
253 | 0x848, 0xffffffff, 0x00000000, | ||
254 | 0x84c, 0xffffffff, 0x00000000, | ||
255 | 0x868, 0xffffffff, 0x00000000, | ||
256 | 0xe00, 0xffffffff, 0x04040404, | ||
257 | 0xe04, 0xffffffff, 0x00020204, | ||
258 | 0xe08, 0x0000ff00, 0x00000000, | ||
259 | 0x86c, 0xffffff00, 0x00000000, | ||
260 | 0xe10, 0xffffffff, 0x06060606, | ||
261 | 0xe14, 0xffffffff, 0x00020406, | ||
262 | 0xe18, 0xffffffff, 0x00000000, | ||
263 | 0xe1c, 0xffffffff, 0x00000000, | ||
264 | 0x830, 0xffffffff, 0x04040404, | ||
265 | 0x834, 0xffffffff, 0x00020204, | ||
266 | 0x838, 0xffffff00, 0x00000000, | ||
267 | 0x86c, 0x000000ff, 0x00000000, | ||
268 | 0x83c, 0xffffffff, 0x06060606, | ||
269 | 0x848, 0xffffffff, 0x00020406, | ||
270 | 0x84c, 0xffffffff, 0x00000000, | ||
271 | 0x868, 0xffffffff, 0x00000000, | ||
272 | 0xe00, 0xffffffff, 0x00000000, | ||
273 | 0xe04, 0xffffffff, 0x00000000, | ||
274 | 0xe08, 0x0000ff00, 0x00000000, | ||
275 | 0x86c, 0xffffff00, 0x00000000, | ||
276 | 0xe10, 0xffffffff, 0x00000000, | ||
277 | 0xe14, 0xffffffff, 0x00000000, | ||
278 | 0xe18, 0xffffffff, 0x00000000, | ||
279 | 0xe1c, 0xffffffff, 0x00000000, | ||
280 | 0x830, 0xffffffff, 0x00000000, | ||
281 | 0x834, 0xffffffff, 0x00000000, | ||
282 | 0x838, 0xffffff00, 0x00000000, | ||
283 | 0x86c, 0x000000ff, 0x00000000, | ||
284 | 0x83c, 0xffffffff, 0x00000000, | ||
285 | 0x848, 0xffffffff, 0x00000000, | ||
286 | 0x84c, 0xffffffff, 0x00000000, | ||
287 | 0x868, 0xffffffff, 0x00000000, | ||
288 | 0xe00, 0xffffffff, 0x00000000, | ||
289 | 0xe04, 0xffffffff, 0x00000000, | ||
290 | 0xe08, 0x0000ff00, 0x00000000, | ||
291 | 0x86c, 0xffffff00, 0x00000000, | ||
292 | 0xe10, 0xffffffff, 0x00000000, | ||
293 | 0xe14, 0xffffffff, 0x00000000, | ||
294 | 0xe18, 0xffffffff, 0x00000000, | ||
295 | 0xe1c, 0xffffffff, 0x00000000, | ||
296 | 0x830, 0xffffffff, 0x00000000, | ||
297 | 0x834, 0xffffffff, 0x00000000, | ||
298 | 0x838, 0xffffff00, 0x00000000, | ||
299 | 0x86c, 0x000000ff, 0x00000000, | ||
300 | 0x83c, 0xffffffff, 0x00000000, | ||
301 | 0x848, 0xffffffff, 0x00000000, | ||
302 | 0x84c, 0xffffffff, 0x00000000, | ||
303 | 0x868, 0xffffffff, 0x00000000, | ||
304 | 0xe00, 0xffffffff, 0x04040404, | ||
305 | 0xe04, 0xffffffff, 0x00020204, | ||
306 | 0xe08, 0x0000ff00, 0x00000000, | ||
307 | 0x86c, 0xffffff00, 0x00000000, | ||
308 | 0xe10, 0xffffffff, 0x00000000, | ||
309 | 0xe14, 0xffffffff, 0x00000000, | ||
310 | 0xe18, 0xffffffff, 0x00000000, | ||
311 | 0xe1c, 0xffffffff, 0x00000000, | ||
312 | 0x830, 0xffffffff, 0x04040404, | ||
313 | 0x834, 0xffffffff, 0x00020204, | ||
314 | 0x838, 0xffffff00, 0x00000000, | ||
315 | 0x86c, 0x000000ff, 0x00000000, | ||
316 | 0x83c, 0xffffffff, 0x00000000, | ||
317 | 0x848, 0xffffffff, 0x00000000, | ||
318 | 0x84c, 0xffffffff, 0x00000000, | ||
319 | 0x868, 0xffffffff, 0x00000000, | ||
320 | 0xe00, 0xffffffff, 0x00000000, | ||
321 | 0xe04, 0xffffffff, 0x00000000, | ||
322 | 0xe08, 0x0000ff00, 0x00000000, | ||
323 | 0x86c, 0xffffff00, 0x00000000, | ||
324 | 0xe10, 0xffffffff, 0x00000000, | ||
325 | 0xe14, 0xffffffff, 0x00000000, | ||
326 | 0xe18, 0xffffffff, 0x00000000, | ||
327 | 0xe1c, 0xffffffff, 0x00000000, | ||
328 | 0x830, 0xffffffff, 0x00000000, | ||
329 | 0x834, 0xffffffff, 0x00000000, | ||
330 | 0x838, 0xffffff00, 0x00000000, | ||
331 | 0x86c, 0x000000ff, 0x00000000, | ||
332 | 0x83c, 0xffffffff, 0x00000000, | ||
333 | 0x848, 0xffffffff, 0x00000000, | ||
334 | 0x84c, 0xffffffff, 0x00000000, | ||
335 | 0x868, 0xffffffff, 0x00000000, | ||
336 | }; | ||
337 | |||
338 | u32 RTL8723E_RADIOA_1TARRAY[Rtl8723ERADIOA_1TARRAYLENGTH] = { | ||
339 | 0x000, 0x00030159, | ||
340 | 0x001, 0x00031284, | ||
341 | 0x002, 0x00098000, | ||
342 | 0x003, 0x00018c63, | ||
343 | 0x004, 0x000210e7, | ||
344 | 0x009, 0x0002044f, | ||
345 | 0x00a, 0x0001a3f1, | ||
346 | 0x00b, 0x00014787, | ||
347 | 0x00c, 0x000896fe, | ||
348 | 0x00d, 0x0000e02c, | ||
349 | 0x00e, 0x00039ce7, | ||
350 | 0x00f, 0x00000451, | ||
351 | 0x019, 0x00000000, | ||
352 | 0x01a, 0x00030355, | ||
353 | 0x01b, 0x00060a00, | ||
354 | 0x01c, 0x000fc378, | ||
355 | 0x01d, 0x000a1250, | ||
356 | 0x01e, 0x0004445f, | ||
357 | 0x01f, 0x00080001, | ||
358 | 0x020, 0x0000b614, | ||
359 | 0x021, 0x0006c000, | ||
360 | 0x022, 0x00000000, | ||
361 | 0x023, 0x00001558, | ||
362 | 0x024, 0x00000060, | ||
363 | 0x025, 0x00000483, | ||
364 | 0x026, 0x0004f000, | ||
365 | 0x027, 0x000ec7d9, | ||
366 | 0x028, 0x00057730, | ||
367 | 0x029, 0x00004783, | ||
368 | 0x02a, 0x00000001, | ||
369 | 0x02b, 0x00021334, | ||
370 | 0x02a, 0x00000000, | ||
371 | 0x02b, 0x00000054, | ||
372 | 0x02a, 0x00000001, | ||
373 | 0x02b, 0x00000808, | ||
374 | 0x02b, 0x00053333, | ||
375 | 0x02c, 0x0000000c, | ||
376 | 0x02a, 0x00000002, | ||
377 | 0x02b, 0x00000808, | ||
378 | 0x02b, 0x0005b333, | ||
379 | 0x02c, 0x0000000d, | ||
380 | 0x02a, 0x00000003, | ||
381 | 0x02b, 0x00000808, | ||
382 | 0x02b, 0x00063333, | ||
383 | 0x02c, 0x0000000d, | ||
384 | 0x02a, 0x00000004, | ||
385 | 0x02b, 0x00000808, | ||
386 | 0x02b, 0x0006b333, | ||
387 | 0x02c, 0x0000000d, | ||
388 | 0x02a, 0x00000005, | ||
389 | 0x02b, 0x00000808, | ||
390 | 0x02b, 0x00073333, | ||
391 | 0x02c, 0x0000000d, | ||
392 | 0x02a, 0x00000006, | ||
393 | 0x02b, 0x00000709, | ||
394 | 0x02b, 0x0005b333, | ||
395 | 0x02c, 0x0000000d, | ||
396 | 0x02a, 0x00000007, | ||
397 | 0x02b, 0x00000709, | ||
398 | 0x02b, 0x00063333, | ||
399 | 0x02c, 0x0000000d, | ||
400 | 0x02a, 0x00000008, | ||
401 | 0x02b, 0x0000060a, | ||
402 | 0x02b, 0x0004b333, | ||
403 | 0x02c, 0x0000000d, | ||
404 | 0x02a, 0x00000009, | ||
405 | 0x02b, 0x0000060a, | ||
406 | 0x02b, 0x00053333, | ||
407 | 0x02c, 0x0000000d, | ||
408 | 0x02a, 0x0000000a, | ||
409 | 0x02b, 0x0000060a, | ||
410 | 0x02b, 0x0005b333, | ||
411 | 0x02c, 0x0000000d, | ||
412 | 0x02a, 0x0000000b, | ||
413 | 0x02b, 0x0000060a, | ||
414 | 0x02b, 0x00063333, | ||
415 | 0x02c, 0x0000000d, | ||
416 | 0x02a, 0x0000000c, | ||
417 | 0x02b, 0x0000060a, | ||
418 | 0x02b, 0x0006b333, | ||
419 | 0x02c, 0x0000000d, | ||
420 | 0x02a, 0x0000000d, | ||
421 | 0x02b, 0x0000060a, | ||
422 | 0x02b, 0x00073333, | ||
423 | 0x02c, 0x0000000d, | ||
424 | 0x02a, 0x0000000e, | ||
425 | 0x02b, 0x0000050b, | ||
426 | 0x02b, 0x00066666, | ||
427 | 0x02c, 0x0000001a, | ||
428 | 0x02a, 0x000e0000, | ||
429 | 0x010, 0x0004000f, | ||
430 | 0x011, 0x000e31fc, | ||
431 | 0x010, 0x0006000f, | ||
432 | 0x011, 0x000ff9f8, | ||
433 | 0x010, 0x0002000f, | ||
434 | 0x011, 0x000203f9, | ||
435 | 0x010, 0x0003000f, | ||
436 | 0x011, 0x000ff500, | ||
437 | 0x010, 0x00000000, | ||
438 | 0x011, 0x00000000, | ||
439 | 0x010, 0x0008000f, | ||
440 | 0x011, 0x0003f100, | ||
441 | 0x010, 0x0009000f, | ||
442 | 0x011, 0x00023100, | ||
443 | 0x012, 0x00032000, | ||
444 | 0x012, 0x00071000, | ||
445 | 0x012, 0x000b0000, | ||
446 | 0x012, 0x000fc000, | ||
447 | 0x013, 0x000287b3, | ||
448 | 0x013, 0x000244b7, | ||
449 | 0x013, 0x000204ab, | ||
450 | 0x013, 0x0001c49f, | ||
451 | 0x013, 0x00018493, | ||
452 | 0x013, 0x0001429b, | ||
453 | 0x013, 0x00010299, | ||
454 | 0x013, 0x0000c29c, | ||
455 | 0x013, 0x000081a0, | ||
456 | 0x013, 0x000040ac, | ||
457 | 0x013, 0x00000020, | ||
458 | 0x014, 0x0001944c, | ||
459 | 0x014, 0x00059444, | ||
460 | 0x014, 0x0009944c, | ||
461 | 0x014, 0x000d9444, | ||
462 | 0x015, 0x0000f424, | ||
463 | 0x015, 0x0004f407, | ||
464 | 0x015, 0x0008f424, | ||
465 | 0x015, 0x000cf424, | ||
466 | 0x016, 0x00000339, | ||
467 | 0x016, 0x00040339, | ||
468 | 0x016, 0x00080339, | ||
469 | 0x016, 0x000c0336, | ||
470 | 0x000, 0x00010159, | ||
471 | 0x018, 0x0000f401, | ||
472 | 0x0fe, 0x00000000, | ||
473 | 0x0fe, 0x00000000, | ||
474 | 0x01f, 0x00080003, | ||
475 | 0x0fe, 0x00000000, | ||
476 | 0x0fe, 0x00000000, | ||
477 | 0x01e, 0x00044457, | ||
478 | 0x01f, 0x00080000, | ||
479 | 0x000, 0x00030159, | ||
480 | }; | ||
481 | |||
482 | |||
483 | u32 RTL8723E_RADIOB_1TARRAY[RTL8723E_RADIOB_1TARRAYLENGTH] = { | ||
484 | 0x0, | ||
485 | }; | ||
486 | |||
487 | |||
488 | u32 RTL8723EMAC_ARRAY[RTL8723E_MACARRAYLENGTH] = { | ||
489 | 0x420, 0x00000080, | ||
490 | 0x423, 0x00000000, | ||
491 | 0x430, 0x00000000, | ||
492 | 0x431, 0x00000000, | ||
493 | 0x432, 0x00000000, | ||
494 | 0x433, 0x00000001, | ||
495 | 0x434, 0x00000004, | ||
496 | 0x435, 0x00000005, | ||
497 | 0x436, 0x00000006, | ||
498 | 0x437, 0x00000007, | ||
499 | 0x438, 0x00000000, | ||
500 | 0x439, 0x00000000, | ||
501 | 0x43a, 0x00000000, | ||
502 | 0x43b, 0x00000001, | ||
503 | 0x43c, 0x00000004, | ||
504 | 0x43d, 0x00000005, | ||
505 | 0x43e, 0x00000006, | ||
506 | 0x43f, 0x00000007, | ||
507 | 0x440, 0x0000005d, | ||
508 | 0x441, 0x00000001, | ||
509 | 0x442, 0x00000000, | ||
510 | 0x444, 0x00000015, | ||
511 | 0x445, 0x000000f0, | ||
512 | 0x446, 0x0000000f, | ||
513 | 0x447, 0x00000000, | ||
514 | 0x458, 0x00000041, | ||
515 | 0x459, 0x000000a8, | ||
516 | 0x45a, 0x00000072, | ||
517 | 0x45b, 0x000000b9, | ||
518 | 0x460, 0x00000066, | ||
519 | 0x461, 0x00000066, | ||
520 | 0x462, 0x00000008, | ||
521 | 0x463, 0x00000003, | ||
522 | 0x4c8, 0x000000ff, | ||
523 | 0x4c9, 0x00000008, | ||
524 | 0x4cc, 0x000000ff, | ||
525 | 0x4cd, 0x000000ff, | ||
526 | 0x4ce, 0x00000001, | ||
527 | 0x500, 0x00000026, | ||
528 | 0x501, 0x000000a2, | ||
529 | 0x502, 0x0000002f, | ||
530 | 0x503, 0x00000000, | ||
531 | 0x504, 0x00000028, | ||
532 | 0x505, 0x000000a3, | ||
533 | 0x506, 0x0000005e, | ||
534 | 0x507, 0x00000000, | ||
535 | 0x508, 0x0000002b, | ||
536 | 0x509, 0x000000a4, | ||
537 | 0x50a, 0x0000005e, | ||
538 | 0x50b, 0x00000000, | ||
539 | 0x50c, 0x0000004f, | ||
540 | 0x50d, 0x000000a4, | ||
541 | 0x50e, 0x00000000, | ||
542 | 0x50f, 0x00000000, | ||
543 | 0x512, 0x0000001c, | ||
544 | 0x514, 0x0000000a, | ||
545 | 0x515, 0x00000010, | ||
546 | 0x516, 0x0000000a, | ||
547 | 0x517, 0x00000010, | ||
548 | 0x51a, 0x00000016, | ||
549 | 0x524, 0x0000000f, | ||
550 | 0x525, 0x0000004f, | ||
551 | 0x546, 0x00000040, | ||
552 | 0x547, 0x00000000, | ||
553 | 0x550, 0x00000010, | ||
554 | 0x551, 0x00000010, | ||
555 | 0x559, 0x00000002, | ||
556 | 0x55a, 0x00000002, | ||
557 | 0x55d, 0x000000ff, | ||
558 | 0x605, 0x00000030, | ||
559 | 0x608, 0x0000000e, | ||
560 | 0x609, 0x0000002a, | ||
561 | 0x652, 0x00000020, | ||
562 | 0x63c, 0x0000000a, | ||
563 | 0x63d, 0x0000000e, | ||
564 | 0x63e, 0x0000000a, | ||
565 | 0x63f, 0x0000000e, | ||
566 | 0x66e, 0x00000005, | ||
567 | 0x700, 0x00000021, | ||
568 | 0x701, 0x00000043, | ||
569 | 0x702, 0x00000065, | ||
570 | 0x703, 0x00000087, | ||
571 | 0x708, 0x00000021, | ||
572 | 0x709, 0x00000043, | ||
573 | 0x70a, 0x00000065, | ||
574 | 0x70b, 0x00000087, | ||
575 | }; | ||
576 | |||
577 | u32 RTL8723EAGCTAB_1TARRAY[RTL8723E_AGCTAB_1TARRAYLENGTH] = { | ||
578 | 0xc78, 0x7b000001, | ||
579 | 0xc78, 0x7b010001, | ||
580 | 0xc78, 0x7b020001, | ||
581 | 0xc78, 0x7b030001, | ||
582 | 0xc78, 0x7b040001, | ||
583 | 0xc78, 0x7b050001, | ||
584 | 0xc78, 0x7a060001, | ||
585 | 0xc78, 0x79070001, | ||
586 | 0xc78, 0x78080001, | ||
587 | 0xc78, 0x77090001, | ||
588 | 0xc78, 0x760a0001, | ||
589 | 0xc78, 0x750b0001, | ||
590 | 0xc78, 0x740c0001, | ||
591 | 0xc78, 0x730d0001, | ||
592 | 0xc78, 0x720e0001, | ||
593 | 0xc78, 0x710f0001, | ||
594 | 0xc78, 0x70100001, | ||
595 | 0xc78, 0x6f110001, | ||
596 | 0xc78, 0x6e120001, | ||
597 | 0xc78, 0x6d130001, | ||
598 | 0xc78, 0x6c140001, | ||
599 | 0xc78, 0x6b150001, | ||
600 | 0xc78, 0x6a160001, | ||
601 | 0xc78, 0x69170001, | ||
602 | 0xc78, 0x68180001, | ||
603 | 0xc78, 0x67190001, | ||
604 | 0xc78, 0x661a0001, | ||
605 | 0xc78, 0x651b0001, | ||
606 | 0xc78, 0x641c0001, | ||
607 | 0xc78, 0x631d0001, | ||
608 | 0xc78, 0x621e0001, | ||
609 | 0xc78, 0x611f0001, | ||
610 | 0xc78, 0x60200001, | ||
611 | 0xc78, 0x49210001, | ||
612 | 0xc78, 0x48220001, | ||
613 | 0xc78, 0x47230001, | ||
614 | 0xc78, 0x46240001, | ||
615 | 0xc78, 0x45250001, | ||
616 | 0xc78, 0x44260001, | ||
617 | 0xc78, 0x43270001, | ||
618 | 0xc78, 0x42280001, | ||
619 | 0xc78, 0x41290001, | ||
620 | 0xc78, 0x402a0001, | ||
621 | 0xc78, 0x262b0001, | ||
622 | 0xc78, 0x252c0001, | ||
623 | 0xc78, 0x242d0001, | ||
624 | 0xc78, 0x232e0001, | ||
625 | 0xc78, 0x222f0001, | ||
626 | 0xc78, 0x21300001, | ||
627 | 0xc78, 0x20310001, | ||
628 | 0xc78, 0x06320001, | ||
629 | 0xc78, 0x05330001, | ||
630 | 0xc78, 0x04340001, | ||
631 | 0xc78, 0x03350001, | ||
632 | 0xc78, 0x02360001, | ||
633 | 0xc78, 0x01370001, | ||
634 | 0xc78, 0x00380001, | ||
635 | 0xc78, 0x00390001, | ||
636 | 0xc78, 0x003a0001, | ||
637 | 0xc78, 0x003b0001, | ||
638 | 0xc78, 0x003c0001, | ||
639 | 0xc78, 0x003d0001, | ||
640 | 0xc78, 0x003e0001, | ||
641 | 0xc78, 0x003f0001, | ||
642 | 0xc78, 0x7b400001, | ||
643 | 0xc78, 0x7b410001, | ||
644 | 0xc78, 0x7b420001, | ||
645 | 0xc78, 0x7b430001, | ||
646 | 0xc78, 0x7b440001, | ||
647 | 0xc78, 0x7b450001, | ||
648 | 0xc78, 0x7a460001, | ||
649 | 0xc78, 0x79470001, | ||
650 | 0xc78, 0x78480001, | ||
651 | 0xc78, 0x77490001, | ||
652 | 0xc78, 0x764a0001, | ||
653 | 0xc78, 0x754b0001, | ||
654 | 0xc78, 0x744c0001, | ||
655 | 0xc78, 0x734d0001, | ||
656 | 0xc78, 0x724e0001, | ||
657 | 0xc78, 0x714f0001, | ||
658 | 0xc78, 0x70500001, | ||
659 | 0xc78, 0x6f510001, | ||
660 | 0xc78, 0x6e520001, | ||
661 | 0xc78, 0x6d530001, | ||
662 | 0xc78, 0x6c540001, | ||
663 | 0xc78, 0x6b550001, | ||
664 | 0xc78, 0x6a560001, | ||
665 | 0xc78, 0x69570001, | ||
666 | 0xc78, 0x68580001, | ||
667 | 0xc78, 0x67590001, | ||
668 | 0xc78, 0x665a0001, | ||
669 | 0xc78, 0x655b0001, | ||
670 | 0xc78, 0x645c0001, | ||
671 | 0xc78, 0x635d0001, | ||
672 | 0xc78, 0x625e0001, | ||
673 | 0xc78, 0x615f0001, | ||
674 | 0xc78, 0x60600001, | ||
675 | 0xc78, 0x49610001, | ||
676 | 0xc78, 0x48620001, | ||
677 | 0xc78, 0x47630001, | ||
678 | 0xc78, 0x46640001, | ||
679 | 0xc78, 0x45650001, | ||
680 | 0xc78, 0x44660001, | ||
681 | 0xc78, 0x43670001, | ||
682 | 0xc78, 0x42680001, | ||
683 | 0xc78, 0x41690001, | ||
684 | 0xc78, 0x406a0001, | ||
685 | 0xc78, 0x266b0001, | ||
686 | 0xc78, 0x256c0001, | ||
687 | 0xc78, 0x246d0001, | ||
688 | 0xc78, 0x236e0001, | ||
689 | 0xc78, 0x226f0001, | ||
690 | 0xc78, 0x21700001, | ||
691 | 0xc78, 0x20710001, | ||
692 | 0xc78, 0x06720001, | ||
693 | 0xc78, 0x05730001, | ||
694 | 0xc78, 0x04740001, | ||
695 | 0xc78, 0x03750001, | ||
696 | 0xc78, 0x02760001, | ||
697 | 0xc78, 0x01770001, | ||
698 | 0xc78, 0x00780001, | ||
699 | 0xc78, 0x00790001, | ||
700 | 0xc78, 0x007a0001, | ||
701 | 0xc78, 0x007b0001, | ||
702 | 0xc78, 0x007c0001, | ||
703 | 0xc78, 0x007d0001, | ||
704 | 0xc78, 0x007e0001, | ||
705 | 0xc78, 0x007f0001, | ||
706 | 0xc78, 0x3800001e, | ||
707 | 0xc78, 0x3801001e, | ||
708 | 0xc78, 0x3802001e, | ||
709 | 0xc78, 0x3803001e, | ||
710 | 0xc78, 0x3804001e, | ||
711 | 0xc78, 0x3805001e, | ||
712 | 0xc78, 0x3806001e, | ||
713 | 0xc78, 0x3807001e, | ||
714 | 0xc78, 0x3808001e, | ||
715 | 0xc78, 0x3c09001e, | ||
716 | 0xc78, 0x3e0a001e, | ||
717 | 0xc78, 0x400b001e, | ||
718 | 0xc78, 0x440c001e, | ||
719 | 0xc78, 0x480d001e, | ||
720 | 0xc78, 0x4c0e001e, | ||
721 | 0xc78, 0x500f001e, | ||
722 | 0xc78, 0x5210001e, | ||
723 | 0xc78, 0x5611001e, | ||
724 | 0xc78, 0x5a12001e, | ||
725 | 0xc78, 0x5e13001e, | ||
726 | 0xc78, 0x6014001e, | ||
727 | 0xc78, 0x6015001e, | ||
728 | 0xc78, 0x6016001e, | ||
729 | 0xc78, 0x6217001e, | ||
730 | 0xc78, 0x6218001e, | ||
731 | 0xc78, 0x6219001e, | ||
732 | 0xc78, 0x621a001e, | ||
733 | 0xc78, 0x621b001e, | ||
734 | 0xc78, 0x621c001e, | ||
735 | 0xc78, 0x621d001e, | ||
736 | 0xc78, 0x621e001e, | ||
737 | 0xc78, 0x621f001e, | ||
738 | }; | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/table.h b/drivers/net/wireless/rtlwifi/rtl8723ae/table.h new file mode 100644 index 000000000000..f5ce71375c20 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/table.h | |||
@@ -0,0 +1,50 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 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 | * Created on 2010/ 5/18, 1:41 | ||
27 | * | ||
28 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
29 | * | ||
30 | *****************************************************************************/ | ||
31 | |||
32 | #ifndef __RTL8723E_TABLE__H_ | ||
33 | #define __RTL8723E_TABLE__H_ | ||
34 | |||
35 | #include <linux/types.h> | ||
36 | |||
37 | #define RTL8723E_PHY_REG_1TARRAY_LENGTH 372 | ||
38 | extern u32 RTL8723EPHY_REG_1TARRAY[RTL8723E_PHY_REG_1TARRAY_LENGTH]; | ||
39 | #define RTL8723E_PHY_REG_ARRAY_PGLENGTH 336 | ||
40 | extern u32 RTL8723EPHY_REG_ARRAY_PG[RTL8723E_PHY_REG_ARRAY_PGLENGTH]; | ||
41 | #define Rtl8723ERADIOA_1TARRAYLENGTH 282 | ||
42 | extern u32 RTL8723E_RADIOA_1TARRAY[Rtl8723ERADIOA_1TARRAYLENGTH]; | ||
43 | #define RTL8723E_RADIOB_1TARRAYLENGTH 1 | ||
44 | extern u32 RTL8723E_RADIOB_1TARRAY[RTL8723E_RADIOB_1TARRAYLENGTH]; | ||
45 | #define RTL8723E_MACARRAYLENGTH 172 | ||
46 | extern u32 RTL8723EMAC_ARRAY[RTL8723E_MACARRAYLENGTH]; | ||
47 | #define RTL8723E_AGCTAB_1TARRAYLENGTH 320 | ||
48 | extern u32 RTL8723EAGCTAB_1TARRAY[RTL8723E_AGCTAB_1TARRAYLENGTH]; | ||
49 | |||
50 | #endif | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c new file mode 100644 index 000000000000..87331d826d73 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c | |||
@@ -0,0 +1,670 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 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 "../base.h" | ||
33 | #include "../stats.h" | ||
34 | #include "reg.h" | ||
35 | #include "def.h" | ||
36 | #include "phy.h" | ||
37 | #include "trx.h" | ||
38 | #include "led.h" | ||
39 | |||
40 | static u8 _rtl8723ae_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue) | ||
41 | { | ||
42 | __le16 fc = rtl_get_fc(skb); | ||
43 | |||
44 | if (unlikely(ieee80211_is_beacon(fc))) | ||
45 | return QSLT_BEACON; | ||
46 | if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc)) | ||
47 | return QSLT_MGNT; | ||
48 | |||
49 | return skb->priority; | ||
50 | } | ||
51 | |||
52 | static void _rtl8723ae_query_rxphystatus(struct ieee80211_hw *hw, | ||
53 | struct rtl_stats *pstatus, u8 *pdesc, | ||
54 | struct rx_fwinfo_8723e *p_drvinfo, | ||
55 | bool bpacket_match_bssid, | ||
56 | bool bpacket_toself, bool packet_beacon) | ||
57 | { | ||
58 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
59 | struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv); | ||
60 | struct phy_sts_cck_8723e_t *cck_buf; | ||
61 | s8 rx_pwr_all, rx_pwr[4]; | ||
62 | u8 rf_rx_num = 0, evm, pwdb_all; | ||
63 | u8 i, max_spatial_stream; | ||
64 | u32 rssi, total_rssi = 0; | ||
65 | bool is_cck = pstatus->is_cck; | ||
66 | |||
67 | /* Record it for next packet processing */ | ||
68 | pstatus->packet_matchbssid = bpacket_match_bssid; | ||
69 | pstatus->packet_toself = bpacket_toself; | ||
70 | pstatus->packet_beacon = packet_beacon; | ||
71 | pstatus->rx_mimo_sig_qual[0] = -1; | ||
72 | pstatus->rx_mimo_sig_qual[1] = -1; | ||
73 | |||
74 | if (is_cck) { | ||
75 | u8 report, cck_highpwr; | ||
76 | |||
77 | /* CCK Driver info Structure is not the same as OFDM packet. */ | ||
78 | cck_buf = (struct phy_sts_cck_8723e_t *)p_drvinfo; | ||
79 | |||
80 | /* (1)Hardware does not provide RSSI for CCK | ||
81 | * (2)PWDB, Average PWDB cacluated by | ||
82 | * hardware (for rate adaptive) | ||
83 | */ | ||
84 | if (ppsc->rfpwr_state == ERFON) | ||
85 | cck_highpwr = (u8) rtl_get_bbreg(hw, | ||
86 | RFPGA0_XA_HSSIPARAMETER2, | ||
87 | BIT(9)); | ||
88 | else | ||
89 | cck_highpwr = false; | ||
90 | |||
91 | if (!cck_highpwr) { | ||
92 | u8 cck_agc_rpt = cck_buf->cck_agc_rpt; | ||
93 | report = cck_buf->cck_agc_rpt & 0xc0; | ||
94 | report = report >> 6; | ||
95 | switch (report) { | ||
96 | case 0x3: | ||
97 | rx_pwr_all = -46 - (cck_agc_rpt & 0x3e); | ||
98 | break; | ||
99 | case 0x2: | ||
100 | rx_pwr_all = -26 - (cck_agc_rpt & 0x3e); | ||
101 | break; | ||
102 | case 0x1: | ||
103 | rx_pwr_all = -12 - (cck_agc_rpt & 0x3e); | ||
104 | break; | ||
105 | case 0x0: | ||
106 | rx_pwr_all = 16 - (cck_agc_rpt & 0x3e); | ||
107 | break; | ||
108 | } | ||
109 | } else { | ||
110 | u8 cck_agc_rpt = cck_buf->cck_agc_rpt; | ||
111 | report = p_drvinfo->cfosho[0] & 0x60; | ||
112 | report = report >> 5; | ||
113 | switch (report) { | ||
114 | case 0x3: | ||
115 | rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1); | ||
116 | break; | ||
117 | case 0x2: | ||
118 | rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1); | ||
119 | break; | ||
120 | case 0x1: | ||
121 | rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1); | ||
122 | break; | ||
123 | case 0x0: | ||
124 | rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1); | ||
125 | break; | ||
126 | } | ||
127 | } | ||
128 | |||
129 | pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all); | ||
130 | /* CCK gain is smaller than OFDM/MCS gain, | ||
131 | * so we add gain diff. From experience, the val is 6 | ||
132 | */ | ||
133 | pwdb_all += 6; | ||
134 | if (pwdb_all > 100) | ||
135 | pwdb_all = 100; | ||
136 | /* modify the offset to make the same | ||
137 | * gain index with OFDM. | ||
138 | */ | ||
139 | if (pwdb_all > 34 && pwdb_all <= 42) | ||
140 | pwdb_all -= 2; | ||
141 | else if (pwdb_all > 26 && pwdb_all <= 34) | ||
142 | pwdb_all -= 6; | ||
143 | else if (pwdb_all > 14 && pwdb_all <= 26) | ||
144 | pwdb_all -= 8; | ||
145 | else if (pwdb_all > 4 && pwdb_all <= 14) | ||
146 | pwdb_all -= 4; | ||
147 | |||
148 | pstatus->rx_pwdb_all = pwdb_all; | ||
149 | pstatus->recvsignalpower = rx_pwr_all; | ||
150 | |||
151 | /* (3) Get Signal Quality (EVM) */ | ||
152 | if (bpacket_match_bssid) { | ||
153 | u8 sq; | ||
154 | |||
155 | if (pstatus->rx_pwdb_all > 40) { | ||
156 | sq = 100; | ||
157 | } else { | ||
158 | sq = cck_buf->sq_rpt; | ||
159 | if (sq > 64) | ||
160 | sq = 0; | ||
161 | else if (sq < 20) | ||
162 | sq = 100; | ||
163 | else | ||
164 | sq = ((64 - sq) * 100) / 44; | ||
165 | } | ||
166 | |||
167 | pstatus->signalquality = sq; | ||
168 | pstatus->rx_mimo_sig_qual[0] = sq; | ||
169 | pstatus->rx_mimo_sig_qual[1] = -1; | ||
170 | } | ||
171 | } else { | ||
172 | rtlpriv->dm.rfpath_rxenable[0] = | ||
173 | rtlpriv->dm.rfpath_rxenable[1] = true; | ||
174 | |||
175 | /* (1)Get RSSI for HT rate */ | ||
176 | for (i = RF90_PATH_A; i < RF6052_MAX_PATH; i++) { | ||
177 | |||
178 | /* we will judge RF RX path now. */ | ||
179 | if (rtlpriv->dm.rfpath_rxenable[i]) | ||
180 | rf_rx_num++; | ||
181 | |||
182 | rx_pwr[i] = ((p_drvinfo->gain_trsw[i] & 0x3f)*2) - 110; | ||
183 | |||
184 | /* Translate DBM to percentage. */ | ||
185 | rssi = rtl_query_rxpwrpercentage(rx_pwr[i]); | ||
186 | total_rssi += rssi; | ||
187 | |||
188 | /* Get Rx snr value in DB */ | ||
189 | rtlpriv->stats.rx_snr_db[i] = (p_drvinfo->rxsnr[i] / 2); | ||
190 | |||
191 | /* Record Signal Strength for next packet */ | ||
192 | if (bpacket_match_bssid) | ||
193 | pstatus->rx_mimo_signalstrength[i] = (u8) rssi; | ||
194 | } | ||
195 | |||
196 | /* (2)PWDB, Average PWDB cacluated by | ||
197 | * hardware (for rate adaptive) | ||
198 | */ | ||
199 | rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110; | ||
200 | |||
201 | pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all); | ||
202 | pstatus->rx_pwdb_all = pwdb_all; | ||
203 | pstatus->rxpower = rx_pwr_all; | ||
204 | pstatus->recvsignalpower = rx_pwr_all; | ||
205 | |||
206 | /* (3)EVM of HT rate */ | ||
207 | if (pstatus->is_ht && pstatus->rate >= DESC92_RATEMCS8 && | ||
208 | pstatus->rate <= DESC92_RATEMCS15) | ||
209 | max_spatial_stream = 2; | ||
210 | else | ||
211 | max_spatial_stream = 1; | ||
212 | |||
213 | for (i = 0; i < max_spatial_stream; i++) { | ||
214 | evm = rtl_evm_db_to_percentage(p_drvinfo->rxevm[i]); | ||
215 | |||
216 | if (bpacket_match_bssid) { | ||
217 | /* Fill value in RFD, Get the first | ||
218 | * spatial stream only | ||
219 | */ | ||
220 | if (i == 0) | ||
221 | pstatus->signalquality = (evm & 0xff); | ||
222 | pstatus->rx_mimo_sig_qual[i] = (evm & 0xff); | ||
223 | } | ||
224 | } | ||
225 | } | ||
226 | |||
227 | /* UI BSS List signal strength(in percentage), | ||
228 | * make it good looking, from 0~100. | ||
229 | */ | ||
230 | if (is_cck) | ||
231 | pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw, | ||
232 | pwdb_all)); | ||
233 | else if (rf_rx_num != 0) | ||
234 | pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw, | ||
235 | total_rssi /= rf_rx_num)); | ||
236 | } | ||
237 | |||
238 | static void _rtl8723ae_translate_rx_signal_stuff(struct ieee80211_hw *hw, | ||
239 | struct sk_buff *skb, struct rtl_stats *pstatus, | ||
240 | u8 *pdesc, struct rx_fwinfo_8723e *p_drvinfo) | ||
241 | { | ||
242 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
243 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
244 | struct ieee80211_hdr *hdr; | ||
245 | u8 *tmp_buf; | ||
246 | u8 *praddr; | ||
247 | u8 *psaddr; | ||
248 | __le16 fc; | ||
249 | u16 type; | ||
250 | bool packet_matchbssid, packet_toself, packet_beacon; | ||
251 | |||
252 | tmp_buf = skb->data + pstatus->rx_drvinfo_size + pstatus->rx_bufshift; | ||
253 | |||
254 | hdr = (struct ieee80211_hdr *)tmp_buf; | ||
255 | fc = hdr->frame_control; | ||
256 | type = WLAN_FC_GET_TYPE(fc); | ||
257 | praddr = hdr->addr1; | ||
258 | psaddr = ieee80211_get_SA(hdr); | ||
259 | |||
260 | packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) && | ||
261 | (!compare_ether_addr(mac->bssid, | ||
262 | (le16_to_cpu(fc) & IEEE80211_FCTL_TODS) ? | ||
263 | hdr->addr1 : (le16_to_cpu(fc) & | ||
264 | IEEE80211_FCTL_FROMDS) ? | ||
265 | hdr->addr2 : hdr->addr3)) && (!pstatus->hwerror) && | ||
266 | (!pstatus->crc) && (!pstatus->icv)); | ||
267 | |||
268 | packet_toself = packet_matchbssid && | ||
269 | (!compare_ether_addr(praddr, rtlefuse->dev_addr)); | ||
270 | |||
271 | if (ieee80211_is_beacon(fc)) | ||
272 | packet_beacon = true; | ||
273 | |||
274 | _rtl8723ae_query_rxphystatus(hw, pstatus, pdesc, p_drvinfo, | ||
275 | packet_matchbssid, packet_toself, | ||
276 | packet_beacon); | ||
277 | |||
278 | rtl_process_phyinfo(hw, tmp_buf, pstatus); | ||
279 | } | ||
280 | |||
281 | bool rtl8723ae_rx_query_desc(struct ieee80211_hw *hw, | ||
282 | struct rtl_stats *status, | ||
283 | struct ieee80211_rx_status *rx_status, | ||
284 | u8 *pdesc, struct sk_buff *skb) | ||
285 | { | ||
286 | struct rx_fwinfo_8723e *p_drvinfo; | ||
287 | struct ieee80211_hdr *hdr; | ||
288 | u32 phystatus = GET_RX_DESC_PHYST(pdesc); | ||
289 | |||
290 | status->length = (u16) GET_RX_DESC_PKT_LEN(pdesc); | ||
291 | status->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) * | ||
292 | RX_DRV_INFO_SIZE_UNIT; | ||
293 | status->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03); | ||
294 | status->icv = (u16) GET_RX_DESC_ICV(pdesc); | ||
295 | status->crc = (u16) GET_RX_DESC_CRC32(pdesc); | ||
296 | status->hwerror = (status->crc | status->icv); | ||
297 | status->decrypted = !GET_RX_DESC_SWDEC(pdesc); | ||
298 | status->rate = (u8) GET_RX_DESC_RXMCS(pdesc); | ||
299 | status->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc); | ||
300 | status->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1); | ||
301 | status->isfirst_ampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1) | ||
302 | && (GET_RX_DESC_FAGGR(pdesc) == 1)); | ||
303 | status->timestamp_low = GET_RX_DESC_TSFL(pdesc); | ||
304 | status->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc); | ||
305 | status->is_ht = (bool)GET_RX_DESC_RXHT(pdesc); | ||
306 | |||
307 | status->is_cck = RTL8723E_RX_HAL_IS_CCK_RATE(status->rate); | ||
308 | |||
309 | rx_status->freq = hw->conf.channel->center_freq; | ||
310 | rx_status->band = hw->conf.channel->band; | ||
311 | |||
312 | hdr = (struct ieee80211_hdr *)(skb->data + status->rx_drvinfo_size | ||
313 | + status->rx_bufshift); | ||
314 | |||
315 | if (status->crc) | ||
316 | rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; | ||
317 | |||
318 | if (status->rx_is40Mhzpacket) | ||
319 | rx_status->flag |= RX_FLAG_40MHZ; | ||
320 | |||
321 | if (status->is_ht) | ||
322 | rx_status->flag |= RX_FLAG_HT; | ||
323 | |||
324 | rx_status->flag |= RX_FLAG_MACTIME_START; | ||
325 | |||
326 | /* hw will set status->decrypted true, if it finds the | ||
327 | * frame is open data frame or mgmt frame. | ||
328 | * Thus hw will not decrypt a robust managment frame | ||
329 | * for IEEE80211w but still set status->decrypted | ||
330 | * true, so here we should set it back to undecrypted | ||
331 | * for IEEE80211w frame, and mac80211 sw will help | ||
332 | * to decrypt it | ||
333 | */ | ||
334 | if (status->decrypted) { | ||
335 | if ((ieee80211_is_robust_mgmt_frame(hdr)) && | ||
336 | (ieee80211_has_protected(hdr->frame_control))) | ||
337 | rx_status->flag &= ~RX_FLAG_DECRYPTED; | ||
338 | else | ||
339 | rx_status->flag |= RX_FLAG_DECRYPTED; | ||
340 | } | ||
341 | |||
342 | /* rate_idx: index of data rate into band's | ||
343 | * supported rates or MCS index if HT rates | ||
344 | * are use (RX_FLAG_HT) | ||
345 | */ | ||
346 | rx_status->rate_idx = rtlwifi_rate_mapping(hw, status->is_ht, | ||
347 | status->rate, false); | ||
348 | |||
349 | rx_status->mactime = status->timestamp_low; | ||
350 | if (phystatus == true) { | ||
351 | p_drvinfo = (struct rx_fwinfo_8723e *)(skb->data + | ||
352 | status->rx_bufshift); | ||
353 | |||
354 | _rtl8723ae_translate_rx_signal_stuff(hw, | ||
355 | skb, status, pdesc, p_drvinfo); | ||
356 | } | ||
357 | |||
358 | /*rx_status->qual = status->signal; */ | ||
359 | rx_status->signal = status->recvsignalpower + 10; | ||
360 | /*rx_status->noise = -status->noise; */ | ||
361 | |||
362 | return true; | ||
363 | } | ||
364 | |||
365 | void rtl8723ae_tx_fill_desc(struct ieee80211_hw *hw, | ||
366 | struct ieee80211_hdr *hdr, u8 *pdesc_tx, | ||
367 | struct ieee80211_tx_info *info, | ||
368 | struct ieee80211_sta *sta, | ||
369 | struct sk_buff *skb, u8 hw_queue, | ||
370 | struct rtl_tcb_desc *ptcdesc) | ||
371 | { | ||
372 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
373 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
374 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
375 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | ||
376 | bool defaultadapter = true; | ||
377 | u8 *pdesc = (u8 *) pdesc_tx; | ||
378 | u16 seq_number; | ||
379 | __le16 fc = hdr->frame_control; | ||
380 | u8 fw_qsel = _rtl8723ae_map_hwqueue_to_fwqueue(skb, hw_queue); | ||
381 | bool firstseg = ((hdr->seq_ctrl & | ||
382 | cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0); | ||
383 | bool lastseg = ((hdr->frame_control & | ||
384 | cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0); | ||
385 | dma_addr_t mapping = pci_map_single(rtlpci->pdev, | ||
386 | skb->data, skb->len, | ||
387 | PCI_DMA_TODEVICE); | ||
388 | u8 bw_40 = 0; | ||
389 | |||
390 | if (mac->opmode == NL80211_IFTYPE_STATION) { | ||
391 | bw_40 = mac->bw_40; | ||
392 | } else if (mac->opmode == NL80211_IFTYPE_AP || | ||
393 | mac->opmode == NL80211_IFTYPE_ADHOC) { | ||
394 | if (sta) | ||
395 | bw_40 = sta->ht_cap.cap & | ||
396 | IEEE80211_HT_CAP_SUP_WIDTH_20_40; | ||
397 | } | ||
398 | |||
399 | seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; | ||
400 | |||
401 | rtl_get_tcb_desc(hw, info, sta, skb, ptcdesc); | ||
402 | |||
403 | CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_8723e)); | ||
404 | |||
405 | if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) { | ||
406 | firstseg = true; | ||
407 | lastseg = true; | ||
408 | } | ||
409 | |||
410 | if (firstseg) { | ||
411 | SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); | ||
412 | |||
413 | SET_TX_DESC_TX_RATE(pdesc, ptcdesc->hw_rate); | ||
414 | |||
415 | if (ptcdesc->use_shortgi || ptcdesc->use_shortpreamble) | ||
416 | SET_TX_DESC_DATA_SHORTGI(pdesc, 1); | ||
417 | |||
418 | if (info->flags & IEEE80211_TX_CTL_AMPDU) { | ||
419 | SET_TX_DESC_AGG_BREAK(pdesc, 1); | ||
420 | SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14); | ||
421 | } | ||
422 | SET_TX_DESC_SEQ(pdesc, seq_number); | ||
423 | |||
424 | SET_TX_DESC_RTS_ENABLE(pdesc, ((ptcdesc->rts_enable && | ||
425 | !ptcdesc-> | ||
426 | cts_enable) ? 1 : 0)); | ||
427 | SET_TX_DESC_HW_RTS_ENABLE(pdesc, | ||
428 | ((ptcdesc->rts_enable | ||
429 | || ptcdesc->cts_enable) ? 1 : 0)); | ||
430 | SET_TX_DESC_CTS2SELF(pdesc, ((ptcdesc->cts_enable) ? 1 : 0)); | ||
431 | SET_TX_DESC_RTS_STBC(pdesc, ((ptcdesc->rts_stbc) ? 1 : 0)); | ||
432 | |||
433 | SET_TX_DESC_RTS_RATE(pdesc, ptcdesc->rts_rate); | ||
434 | SET_TX_DESC_RTS_BW(pdesc, 0); | ||
435 | SET_TX_DESC_RTS_SC(pdesc, ptcdesc->rts_sc); | ||
436 | SET_TX_DESC_RTS_SHORT(pdesc, | ||
437 | ((ptcdesc->rts_rate <= DESC92_RATE54M) ? | ||
438 | (ptcdesc->rts_use_shortpreamble ? 1 : 0) | ||
439 | : (ptcdesc->rts_use_shortgi ? 1 : 0))); | ||
440 | |||
441 | if (bw_40) { | ||
442 | if (ptcdesc->packet_bw) { | ||
443 | SET_TX_DESC_DATA_BW(pdesc, 1); | ||
444 | SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3); | ||
445 | } else { | ||
446 | SET_TX_DESC_DATA_BW(pdesc, 0); | ||
447 | SET_TX_DESC_TX_SUB_CARRIER(pdesc, | ||
448 | mac->cur_40_prime_sc); | ||
449 | } | ||
450 | } else { | ||
451 | SET_TX_DESC_DATA_BW(pdesc, 0); | ||
452 | SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0); | ||
453 | } | ||
454 | |||
455 | SET_TX_DESC_LINIP(pdesc, 0); | ||
456 | SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len); | ||
457 | |||
458 | if (sta) { | ||
459 | u8 ampdu_density = sta->ht_cap.ampdu_density; | ||
460 | SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density); | ||
461 | } | ||
462 | |||
463 | if (info->control.hw_key) { | ||
464 | struct ieee80211_key_conf *keyconf = | ||
465 | info->control.hw_key; | ||
466 | |||
467 | switch (keyconf->cipher) { | ||
468 | case WLAN_CIPHER_SUITE_WEP40: | ||
469 | case WLAN_CIPHER_SUITE_WEP104: | ||
470 | case WLAN_CIPHER_SUITE_TKIP: | ||
471 | SET_TX_DESC_SEC_TYPE(pdesc, 0x1); | ||
472 | break; | ||
473 | case WLAN_CIPHER_SUITE_CCMP: | ||
474 | SET_TX_DESC_SEC_TYPE(pdesc, 0x3); | ||
475 | break; | ||
476 | default: | ||
477 | SET_TX_DESC_SEC_TYPE(pdesc, 0x0); | ||
478 | break; | ||
479 | } | ||
480 | } | ||
481 | |||
482 | SET_TX_DESC_PKT_ID(pdesc, 0); | ||
483 | SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel); | ||
484 | |||
485 | SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F); | ||
486 | SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF); | ||
487 | SET_TX_DESC_DISABLE_FB(pdesc, 0); | ||
488 | SET_TX_DESC_USE_RATE(pdesc, ptcdesc->use_driver_rate ? 1 : 0); | ||
489 | |||
490 | if (ieee80211_is_data_qos(fc)) { | ||
491 | if (mac->rdg_en) { | ||
492 | RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, | ||
493 | "Enable RDG function.\n"); | ||
494 | SET_TX_DESC_RDG_ENABLE(pdesc, 1); | ||
495 | SET_TX_DESC_HTC(pdesc, 1); | ||
496 | } | ||
497 | } | ||
498 | } | ||
499 | |||
500 | SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0)); | ||
501 | SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0)); | ||
502 | |||
503 | SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len); | ||
504 | |||
505 | SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping); | ||
506 | |||
507 | if (rtlpriv->dm.useramask) { | ||
508 | SET_TX_DESC_RATE_ID(pdesc, ptcdesc->ratr_index); | ||
509 | SET_TX_DESC_MACID(pdesc, ptcdesc->mac_id); | ||
510 | } else { | ||
511 | SET_TX_DESC_RATE_ID(pdesc, 0xC + ptcdesc->ratr_index); | ||
512 | SET_TX_DESC_MACID(pdesc, ptcdesc->ratr_index); | ||
513 | } | ||
514 | |||
515 | if ((!ieee80211_is_data_qos(fc)) && ppsc->fwctrl_lps) { | ||
516 | SET_TX_DESC_HWSEQ_EN_8723(pdesc, 1); | ||
517 | |||
518 | if (!defaultadapter) | ||
519 | SET_TX_DESC_HWSEQ_SEL_8723(pdesc, 1); | ||
520 | } | ||
521 | |||
522 | SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1)); | ||
523 | |||
524 | if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) || | ||
525 | is_broadcast_ether_addr(ieee80211_get_DA(hdr))) { | ||
526 | SET_TX_DESC_BMC(pdesc, 1); | ||
527 | } | ||
528 | |||
529 | RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n"); | ||
530 | } | ||
531 | |||
532 | void rtl8723ae_tx_fill_cmddesc(struct ieee80211_hw *hw, | ||
533 | u8 *pdesc, bool firstseg, | ||
534 | bool lastseg, struct sk_buff *skb) | ||
535 | { | ||
536 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
537 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | ||
538 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); | ||
539 | u8 fw_queue = QSLT_BEACON; | ||
540 | dma_addr_t mapping = pci_map_single(rtlpci->pdev, | ||
541 | skb->data, skb->len, | ||
542 | PCI_DMA_TODEVICE); | ||
543 | __le16 fc = hdr->frame_control; | ||
544 | |||
545 | CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE); | ||
546 | |||
547 | if (firstseg) | ||
548 | SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); | ||
549 | |||
550 | SET_TX_DESC_TX_RATE(pdesc, DESC92_RATE1M); | ||
551 | |||
552 | SET_TX_DESC_SEQ(pdesc, 0); | ||
553 | |||
554 | SET_TX_DESC_LINIP(pdesc, 0); | ||
555 | |||
556 | SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue); | ||
557 | |||
558 | SET_TX_DESC_FIRST_SEG(pdesc, 1); | ||
559 | SET_TX_DESC_LAST_SEG(pdesc, 1); | ||
560 | |||
561 | SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len)); | ||
562 | |||
563 | SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping); | ||
564 | |||
565 | SET_TX_DESC_RATE_ID(pdesc, 7); | ||
566 | SET_TX_DESC_MACID(pdesc, 0); | ||
567 | |||
568 | SET_TX_DESC_OWN(pdesc, 1); | ||
569 | |||
570 | SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len)); | ||
571 | |||
572 | SET_TX_DESC_FIRST_SEG(pdesc, 1); | ||
573 | SET_TX_DESC_LAST_SEG(pdesc, 1); | ||
574 | |||
575 | SET_TX_DESC_OFFSET(pdesc, 0x20); | ||
576 | |||
577 | SET_TX_DESC_USE_RATE(pdesc, 1); | ||
578 | |||
579 | if (!ieee80211_is_data_qos(fc)) { | ||
580 | SET_TX_DESC_HWSEQ_EN_8723(pdesc, 1); | ||
581 | /* SET_TX_DESC_HWSEQ_EN(pdesc, 1); */ | ||
582 | /* SET_TX_DESC_PKT_ID(pdesc, 8); */ | ||
583 | } | ||
584 | |||
585 | RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, | ||
586 | "H2C Tx Cmd Content\n", | ||
587 | pdesc, TX_DESC_SIZE); | ||
588 | } | ||
589 | |||
590 | void rtl8723ae_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) | ||
591 | { | ||
592 | if (istx == true) { | ||
593 | switch (desc_name) { | ||
594 | case HW_DESC_OWN: | ||
595 | SET_TX_DESC_OWN(pdesc, 1); | ||
596 | break; | ||
597 | case HW_DESC_TX_NEXTDESC_ADDR: | ||
598 | SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val); | ||
599 | break; | ||
600 | default: | ||
601 | RT_ASSERT(false, "ERR txdesc :%d not process\n", | ||
602 | desc_name); | ||
603 | break; | ||
604 | } | ||
605 | } else { | ||
606 | switch (desc_name) { | ||
607 | case HW_DESC_RXOWN: | ||
608 | SET_RX_DESC_OWN(pdesc, 1); | ||
609 | break; | ||
610 | case HW_DESC_RXBUFF_ADDR: | ||
611 | SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *) val); | ||
612 | break; | ||
613 | case HW_DESC_RXPKT_LEN: | ||
614 | SET_RX_DESC_PKT_LEN(pdesc, *(u32 *) val); | ||
615 | break; | ||
616 | case HW_DESC_RXERO: | ||
617 | SET_RX_DESC_EOR(pdesc, 1); | ||
618 | break; | ||
619 | default: | ||
620 | RT_ASSERT(false, "ERR rxdesc :%d not process\n", | ||
621 | desc_name); | ||
622 | break; | ||
623 | } | ||
624 | } | ||
625 | } | ||
626 | |||
627 | u32 rtl8723ae_get_desc(u8 *pdesc, bool istx, u8 desc_name) | ||
628 | { | ||
629 | u32 ret = 0; | ||
630 | |||
631 | if (istx == true) { | ||
632 | switch (desc_name) { | ||
633 | case HW_DESC_OWN: | ||
634 | ret = GET_TX_DESC_OWN(pdesc); | ||
635 | break; | ||
636 | case HW_DESC_TXBUFF_ADDR: | ||
637 | ret = GET_TX_DESC_TX_BUFFER_ADDRESS(pdesc); | ||
638 | break; | ||
639 | default: | ||
640 | RT_ASSERT(false, "ERR txdesc :%d not process\n", | ||
641 | desc_name); | ||
642 | break; | ||
643 | } | ||
644 | } else { | ||
645 | switch (desc_name) { | ||
646 | case HW_DESC_OWN: | ||
647 | ret = GET_RX_DESC_OWN(pdesc); | ||
648 | break; | ||
649 | case HW_DESC_RXPKT_LEN: | ||
650 | ret = GET_RX_DESC_PKT_LEN(pdesc); | ||
651 | break; | ||
652 | default: | ||
653 | RT_ASSERT(false, "ERR rxdesc :%d not process\n", | ||
654 | desc_name); | ||
655 | break; | ||
656 | } | ||
657 | } | ||
658 | return ret; | ||
659 | } | ||
660 | |||
661 | void rtl8723ae_tx_polling(struct ieee80211_hw *hw, u8 hw_queue) | ||
662 | { | ||
663 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
664 | if (hw_queue == BEACON_QUEUE) { | ||
665 | rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4)); | ||
666 | } else { | ||
667 | rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, | ||
668 | BIT(0) << (hw_queue)); | ||
669 | } | ||
670 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/trx.h b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.h new file mode 100644 index 000000000000..ad05b54bc0f1 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/trx.h | |||
@@ -0,0 +1,725 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 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 __RTL8723E_TRX_H__ | ||
31 | #define __RTL8723E_TRX_H__ | ||
32 | |||
33 | #define TX_DESC_SIZE 64 | ||
34 | #define TX_DESC_AGGR_SUBFRAME_SIZE 32 | ||
35 | |||
36 | #define RX_DESC_SIZE 32 | ||
37 | #define RX_DRV_INFO_SIZE_UNIT 8 | ||
38 | |||
39 | #define TX_DESC_NEXT_DESC_OFFSET 40 | ||
40 | #define USB_HWDESC_HEADER_LEN 32 | ||
41 | #define CRCLENGTH 4 | ||
42 | |||
43 | #define SET_TX_DESC_PKT_SIZE(__pdesc, __val) \ | ||
44 | SET_BITS_TO_LE_4BYTE(__pdesc, 0, 16, __val) | ||
45 | #define SET_TX_DESC_OFFSET(__pdesc, __val) \ | ||
46 | SET_BITS_TO_LE_4BYTE(__pdesc, 16, 8, __val) | ||
47 | #define SET_TX_DESC_BMC(__pdesc, __val) \ | ||
48 | SET_BITS_TO_LE_4BYTE(__pdesc, 24, 1, __val) | ||
49 | #define SET_TX_DESC_HTC(__pdesc, __val) \ | ||
50 | SET_BITS_TO_LE_4BYTE(__pdesc, 25, 1, __val) | ||
51 | #define SET_TX_DESC_LAST_SEG(__pdesc, __val) \ | ||
52 | SET_BITS_TO_LE_4BYTE(__pdesc, 26, 1, __val) | ||
53 | #define SET_TX_DESC_FIRST_SEG(__pdesc, __val) \ | ||
54 | SET_BITS_TO_LE_4BYTE(__pdesc, 27, 1, __val) | ||
55 | #define SET_TX_DESC_LINIP(__pdesc, __val) \ | ||
56 | SET_BITS_TO_LE_4BYTE(__pdesc, 28, 1, __val) | ||
57 | #define SET_TX_DESC_NO_ACM(__pdesc, __val) \ | ||
58 | SET_BITS_TO_LE_4BYTE(__pdesc, 29, 1, __val) | ||
59 | #define SET_TX_DESC_GF(__pdesc, __val) \ | ||
60 | SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val) | ||
61 | #define SET_TX_DESC_OWN(__pdesc, __val) \ | ||
62 | SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val) | ||
63 | |||
64 | #define GET_TX_DESC_PKT_SIZE(__pdesc) \ | ||
65 | LE_BITS_TO_4BYTE(__pdesc, 0, 16) | ||
66 | #define GET_TX_DESC_OFFSET(__pdesc) \ | ||
67 | LE_BITS_TO_4BYTE(__pdesc, 16, 8) | ||
68 | #define GET_TX_DESC_BMC(__pdesc) \ | ||
69 | LE_BITS_TO_4BYTE(__pdesc, 24, 1) | ||
70 | #define GET_TX_DESC_HTC(__pdesc) \ | ||
71 | LE_BITS_TO_4BYTE(__pdesc, 25, 1) | ||
72 | #define GET_TX_DESC_LAST_SEG(__pdesc) \ | ||
73 | LE_BITS_TO_4BYTE(__pdesc, 26, 1) | ||
74 | #define GET_TX_DESC_FIRST_SEG(__pdesc) \ | ||
75 | LE_BITS_TO_4BYTE(__pdesc, 27, 1) | ||
76 | #define GET_TX_DESC_LINIP(__pdesc) \ | ||
77 | LE_BITS_TO_4BYTE(__pdesc, 28, 1) | ||
78 | #define GET_TX_DESC_NO_ACM(__pdesc) \ | ||
79 | LE_BITS_TO_4BYTE(__pdesc, 29, 1) | ||
80 | #define GET_TX_DESC_GF(__pdesc) \ | ||
81 | LE_BITS_TO_4BYTE(__pdesc, 30, 1) | ||
82 | #define GET_TX_DESC_OWN(__pdesc) \ | ||
83 | LE_BITS_TO_4BYTE(__pdesc, 31, 1) | ||
84 | |||
85 | #define SET_TX_DESC_MACID(__pdesc, __val) \ | ||
86 | SET_BITS_TO_LE_4BYTE(__pdesc+4, 0, 5, __val) | ||
87 | #define SET_TX_DESC_AGG_BREAK(__pdesc, __val) \ | ||
88 | SET_BITS_TO_LE_4BYTE(__pdesc+4, 5, 1, __val) | ||
89 | #define SET_TX_DESC_BK(__pdesc, __val) \ | ||
90 | SET_BITS_TO_LE_4BYTE(__pdesc+4, 6, 1, __val) | ||
91 | #define SET_TX_DESC_RDG_ENABLE(__pdesc, __val) \ | ||
92 | SET_BITS_TO_LE_4BYTE(__pdesc+4, 7, 1, __val) | ||
93 | #define SET_TX_DESC_QUEUE_SEL(__pdesc, __val) \ | ||
94 | SET_BITS_TO_LE_4BYTE(__pdesc+4, 8, 5, __val) | ||
95 | #define SET_TX_DESC_RDG_NAV_EXT(__pdesc, __val) \ | ||
96 | SET_BITS_TO_LE_4BYTE(__pdesc+4, 13, 1, __val) | ||
97 | #define SET_TX_DESC_LSIG_TXOP_EN(__pdesc, __val) \ | ||
98 | SET_BITS_TO_LE_4BYTE(__pdesc+4, 14, 1, __val) | ||
99 | #define SET_TX_DESC_PIFS(__pdesc, __val) \ | ||
100 | SET_BITS_TO_LE_4BYTE(__pdesc+4, 15, 1, __val) | ||
101 | #define SET_TX_DESC_RATE_ID(__pdesc, __val) \ | ||
102 | SET_BITS_TO_LE_4BYTE(__pdesc+4, 16, 4, __val) | ||
103 | #define SET_TX_DESC_NAV_USE_HDR(__pdesc, __val) \ | ||
104 | SET_BITS_TO_LE_4BYTE(__pdesc+4, 20, 1, __val) | ||
105 | #define SET_TX_DESC_EN_DESC_ID(__pdesc, __val) \ | ||
106 | SET_BITS_TO_LE_4BYTE(__pdesc+4, 21, 1, __val) | ||
107 | #define SET_TX_DESC_SEC_TYPE(__pdesc, __val) \ | ||
108 | SET_BITS_TO_LE_4BYTE(__pdesc+4, 22, 2, __val) | ||
109 | #define SET_TX_DESC_PKT_OFFSET(__pdesc, __val) \ | ||
110 | SET_BITS_TO_LE_4BYTE(__pdesc+4, 24, 8, __val) | ||
111 | |||
112 | #define GET_TX_DESC_MACID(__pdesc) \ | ||
113 | LE_BITS_TO_4BYTE(__pdesc+4, 0, 5) | ||
114 | #define GET_TX_DESC_AGG_ENABLE(__pdesc) \ | ||
115 | LE_BITS_TO_4BYTE(__pdesc+4, 5, 1) | ||
116 | #define GET_TX_DESC_AGG_BREAK(__pdesc) \ | ||
117 | LE_BITS_TO_4BYTE(__pdesc+4, 6, 1) | ||
118 | #define GET_TX_DESC_RDG_ENABLE(__pdesc) \ | ||
119 | LE_BITS_TO_4BYTE(__pdesc+4, 7, 1) | ||
120 | #define GET_TX_DESC_QUEUE_SEL(__pdesc) \ | ||
121 | LE_BITS_TO_4BYTE(__pdesc+4, 8, 5) | ||
122 | #define GET_TX_DESC_RDG_NAV_EXT(__pdesc) \ | ||
123 | LE_BITS_TO_4BYTE(__pdesc+4, 13, 1) | ||
124 | #define GET_TX_DESC_LSIG_TXOP_EN(__pdesc) \ | ||
125 | LE_BITS_TO_4BYTE(__pdesc+4, 14, 1) | ||
126 | #define GET_TX_DESC_PIFS(__pdesc) \ | ||
127 | LE_BITS_TO_4BYTE(__pdesc+4, 15, 1) | ||
128 | #define GET_TX_DESC_RATE_ID(__pdesc) \ | ||
129 | LE_BITS_TO_4BYTE(__pdesc+4, 16, 4) | ||
130 | #define GET_TX_DESC_NAV_USE_HDR(__pdesc) \ | ||
131 | LE_BITS_TO_4BYTE(__pdesc+4, 20, 1) | ||
132 | #define GET_TX_DESC_EN_DESC_ID(__pdesc) \ | ||
133 | LE_BITS_TO_4BYTE(__pdesc+4, 21, 1) | ||
134 | #define GET_TX_DESC_SEC_TYPE(__pdesc) \ | ||
135 | LE_BITS_TO_4BYTE(__pdesc+4, 22, 2) | ||
136 | #define GET_TX_DESC_PKT_OFFSET(__pdesc) \ | ||
137 | LE_BITS_TO_4BYTE(__pdesc+4, 24, 8) | ||
138 | |||
139 | #define SET_TX_DESC_RTS_RC(__pdesc, __val) \ | ||
140 | SET_BITS_TO_LE_4BYTE(__pdesc+8, 0, 6, __val) | ||
141 | #define SET_TX_DESC_DATA_RC(__pdesc, __val) \ | ||
142 | SET_BITS_TO_LE_4BYTE(__pdesc+8, 6, 6, __val) | ||
143 | #define SET_TX_DESC_BAR_RTY_TH(__pdesc, __val) \ | ||
144 | SET_BITS_TO_LE_4BYTE(__pdesc+8, 14, 2, __val) | ||
145 | #define SET_TX_DESC_MORE_FRAG(__pdesc, __val) \ | ||
146 | SET_BITS_TO_LE_4BYTE(__pdesc+8, 17, 1, __val) | ||
147 | #define SET_TX_DESC_RAW(__pdesc, __val) \ | ||
148 | SET_BITS_TO_LE_4BYTE(__pdesc+8, 18, 1, __val) | ||
149 | #define SET_TX_DESC_CCX(__pdesc, __val) \ | ||
150 | SET_BITS_TO_LE_4BYTE(__pdesc+8, 19, 1, __val) | ||
151 | #define SET_TX_DESC_AMPDU_DENSITY(__pdesc, __val) \ | ||
152 | SET_BITS_TO_LE_4BYTE(__pdesc+8, 20, 3, __val) | ||
153 | #define SET_TX_DESC_ANTSEL_A(__pdesc, __val) \ | ||
154 | SET_BITS_TO_LE_4BYTE(__pdesc+8, 24, 1, __val) | ||
155 | #define SET_TX_DESC_ANTSEL_B(__pdesc, __val) \ | ||
156 | SET_BITS_TO_LE_4BYTE(__pdesc+8, 25, 1, __val) | ||
157 | #define SET_TX_DESC_TX_ANT_CCK(__pdesc, __val) \ | ||
158 | SET_BITS_TO_LE_4BYTE(__pdesc+8, 26, 2, __val) | ||
159 | #define SET_TX_DESC_TX_ANTL(__pdesc, __val) \ | ||
160 | SET_BITS_TO_LE_4BYTE(__pdesc+8, 28, 2, __val) | ||
161 | #define SET_TX_DESC_TX_ANT_HT(__pdesc, __val) \ | ||
162 | SET_BITS_TO_LE_4BYTE(__pdesc+8, 30, 2, __val) | ||
163 | |||
164 | #define GET_TX_DESC_RTS_RC(__pdesc) \ | ||
165 | LE_BITS_TO_4BYTE(__pdesc+8, 0, 6) | ||
166 | #define GET_TX_DESC_DATA_RC(__pdesc) \ | ||
167 | LE_BITS_TO_4BYTE(__pdesc+8, 6, 6) | ||
168 | #define GET_TX_DESC_BAR_RTY_TH(__pdesc) \ | ||
169 | LE_BITS_TO_4BYTE(__pdesc+8, 14, 2) | ||
170 | #define GET_TX_DESC_MORE_FRAG(__pdesc) \ | ||
171 | LE_BITS_TO_4BYTE(__pdesc+8, 17, 1) | ||
172 | #define GET_TX_DESC_RAW(__pdesc) \ | ||
173 | LE_BITS_TO_4BYTE(__pdesc+8, 18, 1) | ||
174 | #define GET_TX_DESC_CCX(__pdesc) \ | ||
175 | LE_BITS_TO_4BYTE(__pdesc+8, 19, 1) | ||
176 | #define GET_TX_DESC_AMPDU_DENSITY(__pdesc) \ | ||
177 | LE_BITS_TO_4BYTE(__pdesc+8, 20, 3) | ||
178 | #define GET_TX_DESC_ANTSEL_A(__pdesc) \ | ||
179 | LE_BITS_TO_4BYTE(__pdesc+8, 24, 1) | ||
180 | #define GET_TX_DESC_ANTSEL_B(__pdesc) \ | ||
181 | LE_BITS_TO_4BYTE(__pdesc+8, 25, 1) | ||
182 | #define GET_TX_DESC_TX_ANT_CCK(__pdesc) \ | ||
183 | LE_BITS_TO_4BYTE(__pdesc+8, 26, 2) | ||
184 | #define GET_TX_DESC_TX_ANTL(__pdesc) \ | ||
185 | LE_BITS_TO_4BYTE(__pdesc+8, 28, 2) | ||
186 | #define GET_TX_DESC_TX_ANT_HT(__pdesc) \ | ||
187 | LE_BITS_TO_4BYTE(__pdesc+8, 30, 2) | ||
188 | |||
189 | #define SET_TX_DESC_NEXT_HEAP_PAGE(__pdesc, __val) \ | ||
190 | SET_BITS_TO_LE_4BYTE(__pdesc+12, 0, 8, __val) | ||
191 | #define SET_TX_DESC_TAIL_PAGE(__pdesc, __val) \ | ||
192 | SET_BITS_TO_LE_4BYTE(__pdesc+12, 8, 8, __val) | ||
193 | #define SET_TX_DESC_SEQ(__pdesc, __val) \ | ||
194 | SET_BITS_TO_LE_4BYTE(__pdesc+12, 16, 12, __val) | ||
195 | #define SET_TX_DESC_PKT_ID(__pdesc, __val) \ | ||
196 | SET_BITS_TO_LE_4BYTE(__pdesc+12, 28, 4, __val) | ||
197 | |||
198 | #define GET_TX_DESC_NEXT_HEAP_PAGE(__pdesc) \ | ||
199 | LE_BITS_TO_4BYTE(__pdesc+12, 0, 8) | ||
200 | #define GET_TX_DESC_TAIL_PAGE(__pdesc) \ | ||
201 | LE_BITS_TO_4BYTE(__pdesc+12, 8, 8) | ||
202 | #define GET_TX_DESC_SEQ(__pdesc) \ | ||
203 | LE_BITS_TO_4BYTE(__pdesc+12, 16, 12) | ||
204 | #define GET_TX_DESC_PKT_ID(__pdesc) \ | ||
205 | LE_BITS_TO_4BYTE(__pdesc+12, 28, 4) | ||
206 | |||
207 | /* For RTL8723 */ | ||
208 | #define SET_TX_DESC_TRIGGER_INT(__pdesc, __val) \ | ||
209 | SET_BITS_TO_LE_4BYTE(__pdesc+12, 30, 1, __val) | ||
210 | #define SET_TX_DESC_HWSEQ_EN_8723(__pdesc, __val) \ | ||
211 | SET_BITS_TO_LE_4BYTE(__pdesc+12, 31, 1, __val) | ||
212 | #define SET_TX_DESC_HWSEQ_SEL_8723(__pTxDesc, __Value) \ | ||
213 | SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 6, 2, __Value) | ||
214 | |||
215 | #define SET_TX_DESC_RTS_RATE(__pdesc, __val) \ | ||
216 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 0, 5, __val) | ||
217 | #define SET_TX_DESC_AP_DCFE(__pdesc, __val) \ | ||
218 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 5, 1, __val) | ||
219 | #define SET_TX_DESC_QOS(__pdesc, __val) \ | ||
220 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 6, 1, __val) | ||
221 | #define SET_TX_DESC_HWSEQ_EN(__pdesc, __val) \ | ||
222 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 7, 1, __val) | ||
223 | #define SET_TX_DESC_USE_RATE(__pdesc, __val) \ | ||
224 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 8, 1, __val) | ||
225 | #define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val) \ | ||
226 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 9, 1, __val) | ||
227 | #define SET_TX_DESC_DISABLE_FB(__pdesc, __val) \ | ||
228 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 10, 1, __val) | ||
229 | #define SET_TX_DESC_CTS2SELF(__pdesc, __val) \ | ||
230 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 11, 1, __val) | ||
231 | #define SET_TX_DESC_RTS_ENABLE(__pdesc, __val) \ | ||
232 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 12, 1, __val) | ||
233 | #define SET_TX_DESC_HW_RTS_ENABLE(__pdesc, __val) \ | ||
234 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 13, 1, __val) | ||
235 | #define SET_TX_DESC_PORT_ID(__pdesc, __val) \ | ||
236 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 14, 1, __val) | ||
237 | #define SET_TX_DESC_WAIT_DCTS(__pdesc, __val) \ | ||
238 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 18, 1, __val) | ||
239 | #define SET_TX_DESC_CTS2AP_EN(__pdesc, __val) \ | ||
240 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 19, 1, __val) | ||
241 | #define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val) \ | ||
242 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 20, 2, __val) | ||
243 | #define SET_TX_DESC_TX_STBC(__pdesc, __val) \ | ||
244 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 22, 2, __val) | ||
245 | #define SET_TX_DESC_DATA_SHORT(__pdesc, __val) \ | ||
246 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 24, 1, __val) | ||
247 | #define SET_TX_DESC_DATA_BW(__pdesc, __val) \ | ||
248 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 25, 1, __val) | ||
249 | #define SET_TX_DESC_RTS_SHORT(__pdesc, __val) \ | ||
250 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 26, 1, __val) | ||
251 | #define SET_TX_DESC_RTS_BW(__pdesc, __val) \ | ||
252 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 27, 1, __val) | ||
253 | #define SET_TX_DESC_RTS_SC(__pdesc, __val) \ | ||
254 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 28, 2, __val) | ||
255 | #define SET_TX_DESC_RTS_STBC(__pdesc, __val) \ | ||
256 | SET_BITS_TO_LE_4BYTE(__pdesc+16, 30, 2, __val) | ||
257 | |||
258 | #define GET_TX_DESC_RTS_RATE(__pdesc) \ | ||
259 | LE_BITS_TO_4BYTE(__pdesc+16, 0, 5) | ||
260 | #define GET_TX_DESC_AP_DCFE(__pdesc) \ | ||
261 | LE_BITS_TO_4BYTE(__pdesc+16, 5, 1) | ||
262 | #define GET_TX_DESC_QOS(__pdesc) \ | ||
263 | LE_BITS_TO_4BYTE(__pdesc+16, 6, 1) | ||
264 | #define GET_TX_DESC_HWSEQ_EN(__pdesc) \ | ||
265 | LE_BITS_TO_4BYTE(__pdesc+16, 7, 1) | ||
266 | #define GET_TX_DESC_USE_RATE(__pdesc) \ | ||
267 | LE_BITS_TO_4BYTE(__pdesc+16, 8, 1) | ||
268 | #define GET_TX_DESC_DISABLE_RTS_FB(__pdesc) \ | ||
269 | LE_BITS_TO_4BYTE(__pdesc+16, 9, 1) | ||
270 | #define GET_TX_DESC_DISABLE_FB(__pdesc) \ | ||
271 | LE_BITS_TO_4BYTE(__pdesc+16, 10, 1) | ||
272 | #define GET_TX_DESC_CTS2SELF(__pdesc) \ | ||
273 | LE_BITS_TO_4BYTE(__pdesc+16, 11, 1) | ||
274 | #define GET_TX_DESC_RTS_ENABLE(__pdesc) \ | ||
275 | LE_BITS_TO_4BYTE(__pdesc+16, 12, 1) | ||
276 | #define GET_TX_DESC_HW_RTS_ENABLE(__pdesc) \ | ||
277 | LE_BITS_TO_4BYTE(__pdesc+16, 13, 1) | ||
278 | #define GET_TX_DESC_PORT_ID(__pdesc) \ | ||
279 | LE_BITS_TO_4BYTE(__pdesc+16, 14, 1) | ||
280 | #define GET_TX_DESC_WAIT_DCTS(__pdesc) \ | ||
281 | LE_BITS_TO_4BYTE(__pdesc+16, 18, 1) | ||
282 | #define GET_TX_DESC_CTS2AP_EN(__pdesc) \ | ||
283 | LE_BITS_TO_4BYTE(__pdesc+16, 19, 1) | ||
284 | #define GET_TX_DESC_TX_SUB_CARRIER(__pdesc) \ | ||
285 | LE_BITS_TO_4BYTE(__pdesc+16, 20, 2) | ||
286 | #define GET_TX_DESC_TX_STBC(__pdesc) \ | ||
287 | LE_BITS_TO_4BYTE(__pdesc+16, 22, 2) | ||
288 | #define GET_TX_DESC_DATA_SHORT(__pdesc) \ | ||
289 | LE_BITS_TO_4BYTE(__pdesc+16, 24, 1) | ||
290 | #define GET_TX_DESC_DATA_BW(__pdesc) \ | ||
291 | LE_BITS_TO_4BYTE(__pdesc+16, 25, 1) | ||
292 | #define GET_TX_DESC_RTS_SHORT(__pdesc) \ | ||
293 | LE_BITS_TO_4BYTE(__pdesc+16, 26, 1) | ||
294 | #define GET_TX_DESC_RTS_BW(__pdesc) \ | ||
295 | LE_BITS_TO_4BYTE(__pdesc+16, 27, 1) | ||
296 | #define GET_TX_DESC_RTS_SC(__pdesc) \ | ||
297 | LE_BITS_TO_4BYTE(__pdesc+16, 28, 2) | ||
298 | #define GET_TX_DESC_RTS_STBC(__pdesc) \ | ||
299 | LE_BITS_TO_4BYTE(__pdesc+16, 30, 2) | ||
300 | |||
301 | #define SET_TX_DESC_TX_RATE(__pdesc, __val) \ | ||
302 | SET_BITS_TO_LE_4BYTE(__pdesc+20, 0, 6, __val) | ||
303 | #define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val) \ | ||
304 | SET_BITS_TO_LE_4BYTE(__pdesc+20, 6, 1, __val) | ||
305 | #define SET_TX_DESC_CCX_TAG(__pdesc, __val) \ | ||
306 | SET_BITS_TO_LE_4BYTE(__pdesc+20, 7, 1, __val) | ||
307 | #define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val) \ | ||
308 | SET_BITS_TO_LE_4BYTE(__pdesc+20, 8, 5, __val) | ||
309 | #define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val) \ | ||
310 | SET_BITS_TO_LE_4BYTE(__pdesc+20, 13, 4, __val) | ||
311 | #define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val) \ | ||
312 | SET_BITS_TO_LE_4BYTE(__pdesc+20, 17, 1, __val) | ||
313 | #define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val) \ | ||
314 | SET_BITS_TO_LE_4BYTE(__pdesc+20, 18, 6, __val) | ||
315 | #define SET_TX_DESC_USB_TXAGG_NUM(__pdesc, __val) \ | ||
316 | SET_BITS_TO_LE_4BYTE(__pdesc+20, 24, 8, __val) | ||
317 | |||
318 | #define GET_TX_DESC_TX_RATE(__pdesc) \ | ||
319 | LE_BITS_TO_4BYTE(__pdesc+20, 0, 6) | ||
320 | #define GET_TX_DESC_DATA_SHORTGI(__pdesc) \ | ||
321 | LE_BITS_TO_4BYTE(__pdesc+20, 6, 1) | ||
322 | #define GET_TX_DESC_CCX_TAG(__pdesc) \ | ||
323 | LE_BITS_TO_4BYTE(__pdesc+20, 7, 1) | ||
324 | #define GET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc) \ | ||
325 | LE_BITS_TO_4BYTE(__pdesc+20, 8, 5) | ||
326 | #define GET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc) \ | ||
327 | LE_BITS_TO_4BYTE(__pdesc+20, 13, 4) | ||
328 | #define GET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc) \ | ||
329 | LE_BITS_TO_4BYTE(__pdesc+20, 17, 1) | ||
330 | #define GET_TX_DESC_DATA_RETRY_LIMIT(__pdesc) \ | ||
331 | LE_BITS_TO_4BYTE(__pdesc+20, 18, 6) | ||
332 | #define GET_TX_DESC_USB_TXAGG_NUM(__pdesc) \ | ||
333 | LE_BITS_TO_4BYTE(__pdesc+20, 24, 8) | ||
334 | |||
335 | #define SET_TX_DESC_TXAGC_A(__pdesc, __val) \ | ||
336 | SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 5, __val) | ||
337 | #define SET_TX_DESC_TXAGC_B(__pdesc, __val) \ | ||
338 | SET_BITS_TO_LE_4BYTE(__pdesc+24, 5, 5, __val) | ||
339 | #define SET_TX_DESC_USE_MAX_LEN(__pdesc, __val) \ | ||
340 | SET_BITS_TO_LE_4BYTE(__pdesc+24, 10, 1, __val) | ||
341 | #define SET_TX_DESC_MAX_AGG_NUM(__pdesc, __val) \ | ||
342 | SET_BITS_TO_LE_4BYTE(__pdesc+24, 11, 5, __val) | ||
343 | #define SET_TX_DESC_MCSG1_MAX_LEN(__pdesc, __val) \ | ||
344 | SET_BITS_TO_LE_4BYTE(__pdesc+24, 16, 4, __val) | ||
345 | #define SET_TX_DESC_MCSG2_MAX_LEN(__pdesc, __val) \ | ||
346 | SET_BITS_TO_LE_4BYTE(__pdesc+24, 20, 4, __val) | ||
347 | #define SET_TX_DESC_MCSG3_MAX_LEN(__pdesc, __val) \ | ||
348 | SET_BITS_TO_LE_4BYTE(__pdesc+24, 24, 4, __val) | ||
349 | #define SET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc, __val)\ | ||
350 | SET_BITS_TO_LE_4BYTE(__pdesc+24, 28, 4, __val) | ||
351 | |||
352 | #define GET_TX_DESC_TXAGC_A(__pdesc) \ | ||
353 | LE_BITS_TO_4BYTE(__pdesc+24, 0, 5) | ||
354 | #define GET_TX_DESC_TXAGC_B(__pdesc) \ | ||
355 | LE_BITS_TO_4BYTE(__pdesc+24, 5, 5) | ||
356 | #define GET_TX_DESC_USE_MAX_LEN(__pdesc) \ | ||
357 | LE_BITS_TO_4BYTE(__pdesc+24, 10, 1) | ||
358 | #define GET_TX_DESC_MAX_AGG_NUM(__pdesc) \ | ||
359 | LE_BITS_TO_4BYTE(__pdesc+24, 11, 5) | ||
360 | #define GET_TX_DESC_MCSG1_MAX_LEN(__pdesc) \ | ||
361 | LE_BITS_TO_4BYTE(__pdesc+24, 16, 4) | ||
362 | #define GET_TX_DESC_MCSG2_MAX_LEN(__pdesc) \ | ||
363 | LE_BITS_TO_4BYTE(__pdesc+24, 20, 4) | ||
364 | #define GET_TX_DESC_MCSG3_MAX_LEN(__pdesc) \ | ||
365 | LE_BITS_TO_4BYTE(__pdesc+24, 24, 4) | ||
366 | #define GET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc) \ | ||
367 | LE_BITS_TO_4BYTE(__pdesc+24, 28, 4) | ||
368 | |||
369 | #define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val) \ | ||
370 | SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 16, __val) | ||
371 | #define SET_TX_DESC_MCSG4_MAX_LEN(__pdesc, __val) \ | ||
372 | SET_BITS_TO_LE_4BYTE(__pdesc+28, 16, 4, __val) | ||
373 | #define SET_TX_DESC_MCSG5_MAX_LEN(__pdesc, __val) \ | ||
374 | SET_BITS_TO_LE_4BYTE(__pdesc+28, 20, 4, __val) | ||
375 | #define SET_TX_DESC_MCSG6_MAX_LEN(__pdesc, __val) \ | ||
376 | SET_BITS_TO_LE_4BYTE(__pdesc+28, 24, 4, __val) | ||
377 | #define SET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc, __val) \ | ||
378 | SET_BITS_TO_LE_4BYTE(__pdesc+28, 28, 4, __val) | ||
379 | |||
380 | #define GET_TX_DESC_TX_BUFFER_SIZE(__pdesc) \ | ||
381 | LE_BITS_TO_4BYTE(__pdesc+28, 0, 16) | ||
382 | #define GET_TX_DESC_MCSG4_MAX_LEN(__pdesc) \ | ||
383 | LE_BITS_TO_4BYTE(__pdesc+28, 16, 4) | ||
384 | #define GET_TX_DESC_MCSG5_MAX_LEN(__pdesc) \ | ||
385 | LE_BITS_TO_4BYTE(__pdesc+28, 20, 4) | ||
386 | #define GET_TX_DESC_MCSG6_MAX_LEN(__pdesc) \ | ||
387 | LE_BITS_TO_4BYTE(__pdesc+28, 24, 4) | ||
388 | #define GET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc) \ | ||
389 | LE_BITS_TO_4BYTE(__pdesc+28, 28, 4) | ||
390 | |||
391 | #define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val) \ | ||
392 | SET_BITS_TO_LE_4BYTE(__pdesc+32, 0, 32, __val) | ||
393 | #define SET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc, __val) \ | ||
394 | SET_BITS_TO_LE_4BYTE(__pdesc+36, 0, 32, __val) | ||
395 | |||
396 | #define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc) \ | ||
397 | LE_BITS_TO_4BYTE(__pdesc+32, 0, 32) | ||
398 | #define GET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc) \ | ||
399 | LE_BITS_TO_4BYTE(__pdesc+36, 0, 32) | ||
400 | |||
401 | #define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val) \ | ||
402 | SET_BITS_TO_LE_4BYTE(__pdesc+40, 0, 32, __val) | ||
403 | #define SET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc, __val) \ | ||
404 | SET_BITS_TO_LE_4BYTE(__pdesc+44, 0, 32, __val) | ||
405 | |||
406 | #define GET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc) \ | ||
407 | LE_BITS_TO_4BYTE(__pdesc+40, 0, 32) | ||
408 | #define GET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc) \ | ||
409 | LE_BITS_TO_4BYTE(__pdesc+44, 0, 32) | ||
410 | |||
411 | #define GET_RX_DESC_PKT_LEN(__pdesc) \ | ||
412 | LE_BITS_TO_4BYTE(__pdesc, 0, 14) | ||
413 | #define GET_RX_DESC_CRC32(__pdesc) \ | ||
414 | LE_BITS_TO_4BYTE(__pdesc, 14, 1) | ||
415 | #define GET_RX_DESC_ICV(__pdesc) \ | ||
416 | LE_BITS_TO_4BYTE(__pdesc, 15, 1) | ||
417 | #define GET_RX_DESC_DRV_INFO_SIZE(__pdesc) \ | ||
418 | LE_BITS_TO_4BYTE(__pdesc, 16, 4) | ||
419 | #define GET_RX_DESC_SECURITY(__pdesc) \ | ||
420 | LE_BITS_TO_4BYTE(__pdesc, 20, 3) | ||
421 | #define GET_RX_DESC_QOS(__pdesc) \ | ||
422 | LE_BITS_TO_4BYTE(__pdesc, 23, 1) | ||
423 | #define GET_RX_DESC_SHIFT(__pdesc) \ | ||
424 | LE_BITS_TO_4BYTE(__pdesc, 24, 2) | ||
425 | #define GET_RX_DESC_PHYST(__pdesc) \ | ||
426 | LE_BITS_TO_4BYTE(__pdesc, 26, 1) | ||
427 | #define GET_RX_DESC_SWDEC(__pdesc) \ | ||
428 | LE_BITS_TO_4BYTE(__pdesc, 27, 1) | ||
429 | #define GET_RX_DESC_LS(__pdesc) \ | ||
430 | LE_BITS_TO_4BYTE(__pdesc, 28, 1) | ||
431 | #define GET_RX_DESC_FS(__pdesc) \ | ||
432 | LE_BITS_TO_4BYTE(__pdesc, 29, 1) | ||
433 | #define GET_RX_DESC_EOR(__pdesc) \ | ||
434 | LE_BITS_TO_4BYTE(__pdesc, 30, 1) | ||
435 | #define GET_RX_DESC_OWN(__pdesc) \ | ||
436 | LE_BITS_TO_4BYTE(__pdesc, 31, 1) | ||
437 | |||
438 | #define SET_RX_DESC_PKT_LEN(__pdesc, __val) \ | ||
439 | SET_BITS_TO_LE_4BYTE(__pdesc, 0, 14, __val) | ||
440 | #define SET_RX_DESC_EOR(__pdesc, __val) \ | ||
441 | SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val) | ||
442 | #define SET_RX_DESC_OWN(__pdesc, __val) \ | ||
443 | SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val) | ||
444 | |||
445 | #define GET_RX_DESC_MACID(__pdesc) \ | ||
446 | LE_BITS_TO_4BYTE(__pdesc+4, 0, 5) | ||
447 | #define GET_RX_DESC_TID(__pdesc) \ | ||
448 | LE_BITS_TO_4BYTE(__pdesc+4, 5, 4) | ||
449 | #define GET_RX_DESC_HWRSVD(__pdesc) \ | ||
450 | LE_BITS_TO_4BYTE(__pdesc+4, 9, 5) | ||
451 | #define GET_RX_DESC_PAGGR(__pdesc) \ | ||
452 | LE_BITS_TO_4BYTE(__pdesc+4, 14, 1) | ||
453 | #define GET_RX_DESC_FAGGR(__pdesc) \ | ||
454 | LE_BITS_TO_4BYTE(__pdesc+4, 15, 1) | ||
455 | #define GET_RX_DESC_A1_FIT(__pdesc) \ | ||
456 | LE_BITS_TO_4BYTE(__pdesc+4, 16, 4) | ||
457 | #define GET_RX_DESC_A2_FIT(__pdesc) \ | ||
458 | LE_BITS_TO_4BYTE(__pdesc+4, 20, 4) | ||
459 | #define GET_RX_DESC_PAM(__pdesc) \ | ||
460 | LE_BITS_TO_4BYTE(__pdesc+4, 24, 1) | ||
461 | #define GET_RX_DESC_PWR(__pdesc) \ | ||
462 | LE_BITS_TO_4BYTE(__pdesc+4, 25, 1) | ||
463 | #define GET_RX_DESC_MD(__pdesc) \ | ||
464 | LE_BITS_TO_4BYTE(__pdesc+4, 26, 1) | ||
465 | #define GET_RX_DESC_MF(__pdesc) \ | ||
466 | LE_BITS_TO_4BYTE(__pdesc+4, 27, 1) | ||
467 | #define GET_RX_DESC_TYPE(__pdesc) \ | ||
468 | LE_BITS_TO_4BYTE(__pdesc+4, 28, 2) | ||
469 | #define GET_RX_DESC_MC(__pdesc) \ | ||
470 | LE_BITS_TO_4BYTE(__pdesc+4, 30, 1) | ||
471 | #define GET_RX_DESC_BC(__pdesc) \ | ||
472 | LE_BITS_TO_4BYTE(__pdesc+4, 31, 1) | ||
473 | #define GET_RX_DESC_SEQ(__pdesc) \ | ||
474 | LE_BITS_TO_4BYTE(__pdesc+8, 0, 12) | ||
475 | #define GET_RX_DESC_FRAG(__pdesc) \ | ||
476 | LE_BITS_TO_4BYTE(__pdesc+8, 12, 4) | ||
477 | #define GET_RX_DESC_NEXT_PKT_LEN(__pdesc) \ | ||
478 | LE_BITS_TO_4BYTE(__pdesc+8, 16, 14) | ||
479 | #define GET_RX_DESC_NEXT_IND(__pdesc) \ | ||
480 | LE_BITS_TO_4BYTE(__pdesc+8, 30, 1) | ||
481 | #define GET_RX_DESC_RSVD(__pdesc) \ | ||
482 | LE_BITS_TO_4BYTE(__pdesc+8, 31, 1) | ||
483 | |||
484 | #define GET_RX_DESC_RXMCS(__pdesc) \ | ||
485 | LE_BITS_TO_4BYTE(__pdesc+12, 0, 6) | ||
486 | #define GET_RX_DESC_RXHT(__pdesc) \ | ||
487 | LE_BITS_TO_4BYTE(__pdesc+12, 6, 1) | ||
488 | #define GET_RX_DESC_SPLCP(__pdesc) \ | ||
489 | LE_BITS_TO_4BYTE(__pdesc+12, 8, 1) | ||
490 | #define GET_RX_DESC_BW(__pdesc) \ | ||
491 | LE_BITS_TO_4BYTE(__pdesc+12, 9, 1) | ||
492 | #define GET_RX_DESC_HTC(__pdesc) \ | ||
493 | LE_BITS_TO_4BYTE(__pdesc+12, 10, 1) | ||
494 | #define GET_RX_DESC_HWPC_ERR(__pdesc) \ | ||
495 | LE_BITS_TO_4BYTE(__pdesc+12, 14, 1) | ||
496 | #define GET_RX_DESC_HWPC_IND(__pdesc) \ | ||
497 | LE_BITS_TO_4BYTE(__pdesc+12, 15, 1) | ||
498 | #define GET_RX_DESC_IV0(__pdesc) \ | ||
499 | LE_BITS_TO_4BYTE(__pdesc+12, 16, 16) | ||
500 | |||
501 | #define GET_RX_DESC_IV1(__pdesc) \ | ||
502 | LE_BITS_TO_4BYTE(__pdesc+16, 0, 32) | ||
503 | #define GET_RX_DESC_TSFL(__pdesc) \ | ||
504 | LE_BITS_TO_4BYTE(__pdesc+20, 0, 32) | ||
505 | |||
506 | #define GET_RX_DESC_BUFF_ADDR(__pdesc) \ | ||
507 | LE_BITS_TO_4BYTE(__pdesc+24, 0, 32) | ||
508 | #define GET_RX_DESC_BUFF_ADDR64(__pdesc) \ | ||
509 | LE_BITS_TO_4BYTE(__pdesc+28, 0, 32) | ||
510 | |||
511 | #define SET_RX_DESC_BUFF_ADDR(__pdesc, __val) \ | ||
512 | SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 32, __val) | ||
513 | #define SET_RX_DESC_BUFF_ADDR64(__pdesc, __val) \ | ||
514 | SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 32, __val) | ||
515 | |||
516 | #define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \ | ||
517 | do { \ | ||
518 | if (_size > TX_DESC_NEXT_DESC_OFFSET) \ | ||
519 | memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); \ | ||
520 | else \ | ||
521 | memset(__pdesc, 0, _size); \ | ||
522 | } while (0) | ||
523 | |||
524 | #define RTL8723E_RX_HAL_IS_CCK_RATE(rxmcs) \ | ||
525 | ((rxmcs) == DESC92_RATE1M || \ | ||
526 | (rxmcs) == DESC92_RATE2M || \ | ||
527 | (rxmcs) == DESC92_RATE5_5M || \ | ||
528 | (rxmcs) == DESC92_RATE11M) | ||
529 | |||
530 | struct rx_fwinfo_8723e { | ||
531 | u8 gain_trsw[4]; | ||
532 | u8 pwdb_all; | ||
533 | u8 cfosho[4]; | ||
534 | u8 cfotail[4]; | ||
535 | char rxevm[2]; | ||
536 | char rxsnr[4]; | ||
537 | u8 pdsnr[2]; | ||
538 | u8 csi_current[2]; | ||
539 | u8 csi_target[2]; | ||
540 | u8 sigevm; | ||
541 | u8 max_ex_pwr; | ||
542 | u8 ex_intf_flag:1; | ||
543 | u8 sgi_en:1; | ||
544 | u8 rxsc:2; | ||
545 | u8 reserve:4; | ||
546 | } __packed; | ||
547 | |||
548 | struct tx_desc_8723e { | ||
549 | u32 pktsize:16; | ||
550 | u32 offset:8; | ||
551 | u32 bmc:1; | ||
552 | u32 htc:1; | ||
553 | u32 lastseg:1; | ||
554 | u32 firstseg:1; | ||
555 | u32 linip:1; | ||
556 | u32 noacm:1; | ||
557 | u32 gf:1; | ||
558 | u32 own:1; | ||
559 | |||
560 | u32 macid:5; | ||
561 | u32 agg_en:1; | ||
562 | u32 bk:1; | ||
563 | u32 rdg_en:1; | ||
564 | u32 queuesel:5; | ||
565 | u32 rd_nav_ext:1; | ||
566 | u32 lsig_txop_en:1; | ||
567 | u32 pifs:1; | ||
568 | u32 rateid:4; | ||
569 | u32 nav_usehdr:1; | ||
570 | u32 en_descid:1; | ||
571 | u32 sectype:2; | ||
572 | u32 pktoffset:8; | ||
573 | |||
574 | u32 rts_rc:6; | ||
575 | u32 data_rc:6; | ||
576 | u32 rsvd0:2; | ||
577 | u32 bar_retryht:2; | ||
578 | u32 rsvd1:1; | ||
579 | u32 morefrag:1; | ||
580 | u32 raw:1; | ||
581 | u32 ccx:1; | ||
582 | u32 ampdudensity:3; | ||
583 | u32 rsvd2:1; | ||
584 | u32 ant_sela:1; | ||
585 | u32 ant_selb:1; | ||
586 | u32 txant_cck:2; | ||
587 | u32 txant_l:2; | ||
588 | u32 txant_ht:2; | ||
589 | |||
590 | u32 nextheadpage:8; | ||
591 | u32 tailpage:8; | ||
592 | u32 seq:12; | ||
593 | u32 pktid:4; | ||
594 | |||
595 | u32 rtsrate:5; | ||
596 | u32 apdcfe:1; | ||
597 | u32 qos:1; | ||
598 | u32 hwseq_enable:1; | ||
599 | u32 userrate:1; | ||
600 | u32 dis_rtsfb:1; | ||
601 | u32 dis_datafb:1; | ||
602 | u32 cts2self:1; | ||
603 | u32 rts_en:1; | ||
604 | u32 hwrts_en:1; | ||
605 | u32 portid:1; | ||
606 | u32 rsvd3:3; | ||
607 | u32 waitdcts:1; | ||
608 | u32 cts2ap_en:1; | ||
609 | u32 txsc:2; | ||
610 | u32 stbc:2; | ||
611 | u32 txshort:1; | ||
612 | u32 txbw:1; | ||
613 | u32 rtsshort:1; | ||
614 | u32 rtsbw:1; | ||
615 | u32 rtssc:2; | ||
616 | u32 rtsstbc:2; | ||
617 | |||
618 | u32 txrate:6; | ||
619 | u32 shortgi:1; | ||
620 | u32 ccxt:1; | ||
621 | u32 txrate_fb_lmt:5; | ||
622 | u32 rtsrate_fb_lmt:4; | ||
623 | u32 retrylmt_en:1; | ||
624 | u32 txretrylmt:6; | ||
625 | u32 usb_txaggnum:8; | ||
626 | |||
627 | u32 txagca:5; | ||
628 | u32 txagcb:5; | ||
629 | u32 usemaxlen:1; | ||
630 | u32 maxaggnum:5; | ||
631 | u32 mcsg1maxlen:4; | ||
632 | u32 mcsg2maxlen:4; | ||
633 | u32 mcsg3maxlen:4; | ||
634 | u32 mcs7sgimaxlen:4; | ||
635 | |||
636 | u32 txbuffersize:16; | ||
637 | u32 mcsg4maxlen:4; | ||
638 | u32 mcsg5maxlen:4; | ||
639 | u32 mcsg6maxlen:4; | ||
640 | u32 mcsg15sgimaxlen:4; | ||
641 | |||
642 | u32 txbuffaddr; | ||
643 | u32 txbufferaddr64; | ||
644 | u32 nextdescaddress; | ||
645 | u32 nextdescaddress64; | ||
646 | |||
647 | u32 reserve_pass_pcie_mm_limit[4]; | ||
648 | } __packed; | ||
649 | |||
650 | struct rx_desc_8723e { | ||
651 | u32 length:14; | ||
652 | u32 crc32:1; | ||
653 | u32 icverror:1; | ||
654 | u32 drv_infosize:4; | ||
655 | u32 security:3; | ||
656 | u32 qos:1; | ||
657 | u32 shift:2; | ||
658 | u32 phystatus:1; | ||
659 | u32 swdec:1; | ||
660 | u32 lastseg:1; | ||
661 | u32 firstseg:1; | ||
662 | u32 eor:1; | ||
663 | u32 own:1; | ||
664 | |||
665 | u32 macid:5; | ||
666 | u32 tid:4; | ||
667 | u32 hwrsvd:5; | ||
668 | u32 paggr:1; | ||
669 | u32 faggr:1; | ||
670 | u32 a1_fit:4; | ||
671 | u32 a2_fit:4; | ||
672 | u32 pam:1; | ||
673 | u32 pwr:1; | ||
674 | u32 moredata:1; | ||
675 | u32 morefrag:1; | ||
676 | u32 type:2; | ||
677 | u32 mc:1; | ||
678 | u32 bc:1; | ||
679 | |||
680 | u32 seq:12; | ||
681 | u32 frag:4; | ||
682 | u32 nextpktlen:14; | ||
683 | u32 nextind:1; | ||
684 | u32 rsvd:1; | ||
685 | |||
686 | u32 rxmcs:6; | ||
687 | u32 rxht:1; | ||
688 | u32 amsdu:1; | ||
689 | u32 splcp:1; | ||
690 | u32 bandwidth:1; | ||
691 | u32 htc:1; | ||
692 | u32 tcpchk_rpt:1; | ||
693 | u32 ipcchk_rpt:1; | ||
694 | u32 tcpchk_valid:1; | ||
695 | u32 hwpcerr:1; | ||
696 | u32 hwpcind:1; | ||
697 | u32 iv0:16; | ||
698 | |||
699 | u32 iv1; | ||
700 | |||
701 | u32 tsfl; | ||
702 | |||
703 | u32 bufferaddress; | ||
704 | u32 bufferaddress64; | ||
705 | |||
706 | } __packed; | ||
707 | |||
708 | void rtl8723ae_tx_fill_desc(struct ieee80211_hw *hw, | ||
709 | struct ieee80211_hdr *hdr, u8 *pdesc_tx, | ||
710 | struct ieee80211_tx_info *info, | ||
711 | struct ieee80211_sta *sta, | ||
712 | struct sk_buff *skb, u8 hw_queue, | ||
713 | struct rtl_tcb_desc *ptcb_desc); | ||
714 | bool rtl8723ae_rx_query_desc(struct ieee80211_hw *hw, | ||
715 | struct rtl_stats *status, | ||
716 | struct ieee80211_rx_status *rx_status, | ||
717 | u8 *pdesc, struct sk_buff *skb); | ||
718 | void rtl8723ae_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val); | ||
719 | u32 rtl8723ae_get_desc(u8 *pdesc, bool istx, u8 desc_name); | ||
720 | void rtl8723ae_tx_polling(struct ieee80211_hw *hw, u8 hw_queue); | ||
721 | void rtl8723ae_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, | ||
722 | bool b_firstseg, bool b_lastseg, | ||
723 | struct sk_buff *skb); | ||
724 | |||
725 | #endif | ||
diff --git a/drivers/net/wireless/rtlwifi/stats.c b/drivers/net/wireless/rtlwifi/stats.c new file mode 100644 index 000000000000..8ed31744a054 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/stats.c | |||
@@ -0,0 +1,268 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 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 | #include "wifi.h" | ||
30 | #include "stats.h" | ||
31 | #include <linux/export.h> | ||
32 | |||
33 | u8 rtl_query_rxpwrpercentage(char antpower) | ||
34 | { | ||
35 | if ((antpower <= -100) || (antpower >= 20)) | ||
36 | return 0; | ||
37 | else if (antpower >= 0) | ||
38 | return 100; | ||
39 | else | ||
40 | return 100 + antpower; | ||
41 | } | ||
42 | EXPORT_SYMBOL(rtl_query_rxpwrpercentage); | ||
43 | |||
44 | u8 rtl_evm_db_to_percentage(char value) | ||
45 | { | ||
46 | char ret_val; | ||
47 | ret_val = value; | ||
48 | |||
49 | if (ret_val >= 0) | ||
50 | ret_val = 0; | ||
51 | if (ret_val <= -33) | ||
52 | ret_val = -33; | ||
53 | ret_val = 0 - ret_val; | ||
54 | ret_val *= 3; | ||
55 | if (ret_val == 99) | ||
56 | ret_val = 100; | ||
57 | |||
58 | return ret_val; | ||
59 | } | ||
60 | EXPORT_SYMBOL(rtl_evm_db_to_percentage); | ||
61 | |||
62 | static long rtl_translate_todbm(struct ieee80211_hw *hw, | ||
63 | u8 signal_strength_index) | ||
64 | { | ||
65 | long signal_power; | ||
66 | |||
67 | signal_power = (long)((signal_strength_index + 1) >> 1); | ||
68 | signal_power -= 95; | ||
69 | return signal_power; | ||
70 | } | ||
71 | |||
72 | long rtl_signal_scale_mapping(struct ieee80211_hw *hw, long currsig) | ||
73 | { | ||
74 | long retsig; | ||
75 | |||
76 | if (currsig >= 61 && currsig <= 100) | ||
77 | retsig = 90 + ((currsig - 60) / 4); | ||
78 | else if (currsig >= 41 && currsig <= 60) | ||
79 | retsig = 78 + ((currsig - 40) / 2); | ||
80 | else if (currsig >= 31 && currsig <= 40) | ||
81 | retsig = 66 + (currsig - 30); | ||
82 | else if (currsig >= 21 && currsig <= 30) | ||
83 | retsig = 54 + (currsig - 20); | ||
84 | else if (currsig >= 5 && currsig <= 20) | ||
85 | retsig = 42 + (((currsig - 5) * 2) / 3); | ||
86 | else if (currsig == 4) | ||
87 | retsig = 36; | ||
88 | else if (currsig == 3) | ||
89 | retsig = 27; | ||
90 | else if (currsig == 2) | ||
91 | retsig = 18; | ||
92 | else if (currsig == 1) | ||
93 | retsig = 9; | ||
94 | else | ||
95 | retsig = currsig; | ||
96 | |||
97 | return retsig; | ||
98 | } | ||
99 | EXPORT_SYMBOL(rtl_signal_scale_mapping); | ||
100 | |||
101 | static void rtl_process_ui_rssi(struct ieee80211_hw *hw, | ||
102 | struct rtl_stats *pstatus) | ||
103 | { | ||
104 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
105 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
106 | u8 rfpath; | ||
107 | u32 last_rssi, tmpval; | ||
108 | |||
109 | rtlpriv->stats.rssi_calculate_cnt++; | ||
110 | |||
111 | if (rtlpriv->stats.ui_rssi.total_num++ >= PHY_RSSI_SLID_WIN_MAX) { | ||
112 | rtlpriv->stats.ui_rssi.total_num = PHY_RSSI_SLID_WIN_MAX; | ||
113 | last_rssi = rtlpriv->stats.ui_rssi.elements[ | ||
114 | rtlpriv->stats.ui_rssi.index]; | ||
115 | rtlpriv->stats.ui_rssi.total_val -= last_rssi; | ||
116 | } | ||
117 | rtlpriv->stats.ui_rssi.total_val += pstatus->signalstrength; | ||
118 | rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi.index++] = | ||
119 | pstatus->signalstrength; | ||
120 | if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX) | ||
121 | rtlpriv->stats.ui_rssi.index = 0; | ||
122 | tmpval = rtlpriv->stats.ui_rssi.total_val / | ||
123 | rtlpriv->stats.ui_rssi.total_num; | ||
124 | rtlpriv->stats.signal_strength = rtl_translate_todbm(hw, | ||
125 | (u8) tmpval); | ||
126 | pstatus->rssi = rtlpriv->stats.signal_strength; | ||
127 | |||
128 | if (pstatus->is_cck) | ||
129 | return; | ||
130 | |||
131 | for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; | ||
132 | rfpath++) { | ||
133 | if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) { | ||
134 | rtlpriv->stats.rx_rssi_percentage[rfpath] = | ||
135 | pstatus->rx_mimo_signalstrength[rfpath]; | ||
136 | |||
137 | } | ||
138 | if (pstatus->rx_mimo_signalstrength[rfpath] > | ||
139 | rtlpriv->stats.rx_rssi_percentage[rfpath]) { | ||
140 | rtlpriv->stats.rx_rssi_percentage[rfpath] = | ||
141 | ((rtlpriv->stats.rx_rssi_percentage[rfpath] * | ||
142 | (RX_SMOOTH_FACTOR - 1)) + | ||
143 | (pstatus->rx_mimo_signalstrength[rfpath])) / | ||
144 | (RX_SMOOTH_FACTOR); | ||
145 | rtlpriv->stats.rx_rssi_percentage[rfpath] = | ||
146 | rtlpriv->stats.rx_rssi_percentage[rfpath] + 1; | ||
147 | } else { | ||
148 | rtlpriv->stats.rx_rssi_percentage[rfpath] = | ||
149 | ((rtlpriv->stats.rx_rssi_percentage[rfpath] * | ||
150 | (RX_SMOOTH_FACTOR - 1)) + | ||
151 | (pstatus->rx_mimo_signalstrength[rfpath])) / | ||
152 | (RX_SMOOTH_FACTOR); | ||
153 | } | ||
154 | } | ||
155 | } | ||
156 | |||
157 | static void rtl_update_rxsignalstatistics(struct ieee80211_hw *hw, | ||
158 | struct rtl_stats *pstatus) | ||
159 | { | ||
160 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
161 | int weighting = 0; | ||
162 | |||
163 | if (rtlpriv->stats.recv_signal_power == 0) | ||
164 | rtlpriv->stats.recv_signal_power = pstatus->recvsignalpower; | ||
165 | if (pstatus->recvsignalpower > rtlpriv->stats.recv_signal_power) | ||
166 | weighting = 5; | ||
167 | else if (pstatus->recvsignalpower < rtlpriv->stats.recv_signal_power) | ||
168 | weighting = (-5); | ||
169 | rtlpriv->stats.recv_signal_power = (rtlpriv->stats.recv_signal_power * | ||
170 | 5 + pstatus->recvsignalpower + weighting) / 6; | ||
171 | } | ||
172 | |||
173 | static void rtl_process_pwdb(struct ieee80211_hw *hw, struct rtl_stats *pstatus) | ||
174 | { | ||
175 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
176 | struct rtl_sta_info *drv_priv = NULL; | ||
177 | struct ieee80211_sta *sta = NULL; | ||
178 | long undec_sm_pwdb; | ||
179 | |||
180 | rcu_read_lock(); | ||
181 | if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION) | ||
182 | sta = rtl_find_sta(hw, pstatus->psaddr); | ||
183 | |||
184 | /* adhoc or ap mode */ | ||
185 | if (sta) { | ||
186 | drv_priv = (struct rtl_sta_info *) sta->drv_priv; | ||
187 | undec_sm_pwdb = drv_priv->rssi_stat.undec_sm_pwdb; | ||
188 | } else { | ||
189 | undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; | ||
190 | } | ||
191 | |||
192 | if (undec_sm_pwdb < 0) | ||
193 | undec_sm_pwdb = pstatus->rx_pwdb_all; | ||
194 | if (pstatus->rx_pwdb_all > (u32) undec_sm_pwdb) { | ||
195 | undec_sm_pwdb = (((undec_sm_pwdb) * | ||
196 | (RX_SMOOTH_FACTOR - 1)) + | ||
197 | (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); | ||
198 | undec_sm_pwdb = undec_sm_pwdb + 1; | ||
199 | } else { | ||
200 | undec_sm_pwdb = (((undec_sm_pwdb) * (RX_SMOOTH_FACTOR - 1)) + | ||
201 | (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); | ||
202 | } | ||
203 | |||
204 | if (sta) { | ||
205 | drv_priv->rssi_stat.undec_sm_pwdb = undec_sm_pwdb; | ||
206 | } else { | ||
207 | rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb; | ||
208 | } | ||
209 | rcu_read_unlock(); | ||
210 | |||
211 | rtl_update_rxsignalstatistics(hw, pstatus); | ||
212 | } | ||
213 | |||
214 | static void rtl_process_ui_link_quality(struct ieee80211_hw *hw, | ||
215 | struct rtl_stats *pstatus) | ||
216 | { | ||
217 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
218 | u32 last_evm, n_stream, tmpval; | ||
219 | |||
220 | if (pstatus->signalquality == 0) | ||
221 | return; | ||
222 | |||
223 | if (rtlpriv->stats.ui_link_quality.total_num++ >= | ||
224 | PHY_LINKQUALITY_SLID_WIN_MAX) { | ||
225 | rtlpriv->stats.ui_link_quality.total_num = | ||
226 | PHY_LINKQUALITY_SLID_WIN_MAX; | ||
227 | last_evm = rtlpriv->stats.ui_link_quality.elements[ | ||
228 | rtlpriv->stats.ui_link_quality.index]; | ||
229 | rtlpriv->stats.ui_link_quality.total_val -= last_evm; | ||
230 | } | ||
231 | rtlpriv->stats.ui_link_quality.total_val += pstatus->signalquality; | ||
232 | rtlpriv->stats.ui_link_quality.elements[ | ||
233 | rtlpriv->stats.ui_link_quality.index++] = | ||
234 | pstatus->signalquality; | ||
235 | if (rtlpriv->stats.ui_link_quality.index >= | ||
236 | PHY_LINKQUALITY_SLID_WIN_MAX) | ||
237 | rtlpriv->stats.ui_link_quality.index = 0; | ||
238 | tmpval = rtlpriv->stats.ui_link_quality.total_val / | ||
239 | rtlpriv->stats.ui_link_quality.total_num; | ||
240 | rtlpriv->stats.signal_quality = tmpval; | ||
241 | rtlpriv->stats.last_sigstrength_inpercent = tmpval; | ||
242 | for (n_stream = 0; n_stream < 2; n_stream++) { | ||
243 | if (pstatus->rx_mimo_sig_qual[n_stream] != -1) { | ||
244 | if (rtlpriv->stats.rx_evm_percentage[n_stream] == 0) { | ||
245 | rtlpriv->stats.rx_evm_percentage[n_stream] = | ||
246 | pstatus->rx_mimo_sig_qual[n_stream]; | ||
247 | } | ||
248 | rtlpriv->stats.rx_evm_percentage[n_stream] = | ||
249 | ((rtlpriv->stats.rx_evm_percentage[n_stream] | ||
250 | * (RX_SMOOTH_FACTOR - 1)) + | ||
251 | (pstatus->rx_mimo_sig_qual[n_stream] * 1)) / | ||
252 | (RX_SMOOTH_FACTOR); | ||
253 | } | ||
254 | } | ||
255 | } | ||
256 | |||
257 | void rtl_process_phyinfo(struct ieee80211_hw *hw, u8 *buffer, | ||
258 | struct rtl_stats *pstatus) | ||
259 | { | ||
260 | |||
261 | if (!pstatus->packet_matchbssid) | ||
262 | return; | ||
263 | |||
264 | rtl_process_ui_rssi(hw, pstatus); | ||
265 | rtl_process_pwdb(hw, pstatus); | ||
266 | rtl_process_ui_link_quality(hw, pstatus); | ||
267 | } | ||
268 | EXPORT_SYMBOL(rtl_process_phyinfo); | ||
diff --git a/drivers/net/wireless/rtlwifi/stats.h b/drivers/net/wireless/rtlwifi/stats.h new file mode 100644 index 000000000000..0dbdc5203830 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/stats.h | |||
@@ -0,0 +1,46 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2012 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 __RTL_STATS_H__ | ||
31 | #define __RTL_STATS_H__ | ||
32 | |||
33 | #define PHY_RSSI_SLID_WIN_MAX 100 | ||
34 | #define PHY_LINKQUALITY_SLID_WIN_MAX 20 | ||
35 | #define PHY_BEACON_RSSI_SLID_WIN_MAX 10 | ||
36 | |||
37 | /* Rx smooth factor */ | ||
38 | #define RX_SMOOTH_FACTOR 20 | ||
39 | |||
40 | u8 rtl_query_rxpwrpercentage(char antpower); | ||
41 | u8 rtl_evm_db_to_percentage(char value); | ||
42 | long rtl_signal_scale_mapping(struct ieee80211_hw *hw, long currsig); | ||
43 | void rtl_process_phyinfo(struct ieee80211_hw *hw, u8 *buffer, | ||
44 | struct rtl_stats *pstatus); | ||
45 | |||
46 | #endif | ||
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 6794b688dd7d..21a5f4f4a135 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h | |||
@@ -350,6 +350,11 @@ enum rt_oem_id { | |||
350 | RT_CID_819x_WNC_COREGA = 31, | 350 | RT_CID_819x_WNC_COREGA = 31, |
351 | RT_CID_819x_Foxcoon = 32, | 351 | RT_CID_819x_Foxcoon = 32, |
352 | RT_CID_819x_DELL = 33, | 352 | RT_CID_819x_DELL = 33, |
353 | RT_CID_819x_PRONETS = 34, | ||
354 | RT_CID_819x_Edimax_ASUS = 35, | ||
355 | RT_CID_NETGEAR = 36, | ||
356 | RT_CID_PLANEX = 37, | ||
357 | RT_CID_CC_C = 38, | ||
353 | }; | 358 | }; |
354 | 359 | ||
355 | enum hw_descs { | 360 | enum hw_descs { |
@@ -505,6 +510,7 @@ enum rtl_var_map { | |||
505 | RTL_IMR_ROK, /*Receive DMA OK Interrupt */ | 510 | RTL_IMR_ROK, /*Receive DMA OK Interrupt */ |
506 | RTL_IBSS_INT_MASKS, /*(RTL_IMR_BcnInt | RTL_IMR_TBDOK | | 511 | RTL_IBSS_INT_MASKS, /*(RTL_IMR_BcnInt | RTL_IMR_TBDOK | |
507 | * RTL_IMR_TBDER) */ | 512 | * RTL_IMR_TBDER) */ |
513 | RTL_IMR_C2HCMD, /*fw interrupt*/ | ||
508 | 514 | ||
509 | /*CCK Rates, TxHT = 0 */ | 515 | /*CCK Rates, TxHT = 0 */ |
510 | RTL_RC_CCK_RATE1M, | 516 | RTL_RC_CCK_RATE1M, |
@@ -661,6 +667,11 @@ enum ba_action { | |||
661 | ACT_DELBA = 2, | 667 | ACT_DELBA = 2, |
662 | }; | 668 | }; |
663 | 669 | ||
670 | enum rt_polarity_ctl { | ||
671 | RT_POLARITY_LOW_ACT = 0, | ||
672 | RT_POLARITY_HIGH_ACT = 1, | ||
673 | }; | ||
674 | |||
664 | struct octet_string { | 675 | struct octet_string { |
665 | u8 *octet; | 676 | u8 *octet; |
666 | u16 length; | 677 | u16 length; |
@@ -903,6 +914,8 @@ struct rtl_phy { | |||
903 | u8 num_total_rfpath; | 914 | u8 num_total_rfpath; |
904 | struct phy_parameters hwparam_tables[MAX_TAB]; | 915 | struct phy_parameters hwparam_tables[MAX_TAB]; |
905 | u16 rf_pathmap; | 916 | u16 rf_pathmap; |
917 | |||
918 | enum rt_polarity_ctl polarity_ctl; | ||
906 | }; | 919 | }; |
907 | 920 | ||
908 | #define MAX_TID_COUNT 9 | 921 | #define MAX_TID_COUNT 9 |
@@ -1042,13 +1055,64 @@ struct rtl_mac { | |||
1042 | /*QOS & EDCA */ | 1055 | /*QOS & EDCA */ |
1043 | struct ieee80211_tx_queue_params edca_param[RTL_MAC80211_NUM_QUEUE]; | 1056 | struct ieee80211_tx_queue_params edca_param[RTL_MAC80211_NUM_QUEUE]; |
1044 | struct rtl_qos_parameters ac[AC_MAX]; | 1057 | struct rtl_qos_parameters ac[AC_MAX]; |
1058 | |||
1059 | /* counters */ | ||
1060 | u64 last_txok_cnt; | ||
1061 | u64 last_rxok_cnt; | ||
1062 | u32 last_bt_edca_ul; | ||
1063 | u32 last_bt_edca_dl; | ||
1064 | }; | ||
1065 | |||
1066 | struct btdm_8723 { | ||
1067 | bool all_off; | ||
1068 | bool agc_table_en; | ||
1069 | bool adc_back_off_on; | ||
1070 | bool b2_ant_hid_en; | ||
1071 | bool low_penalty_rate_adaptive; | ||
1072 | bool rf_rx_lpf_shrink; | ||
1073 | bool reject_aggre_pkt; | ||
1074 | bool tra_tdma_on; | ||
1075 | u8 tra_tdma_nav; | ||
1076 | u8 tra_tdma_ant; | ||
1077 | bool tdma_on; | ||
1078 | u8 tdma_ant; | ||
1079 | u8 tdma_nav; | ||
1080 | u8 tdma_dac_swing; | ||
1081 | u8 fw_dac_swing_lvl; | ||
1082 | bool ps_tdma_on; | ||
1083 | u8 ps_tdma_byte[5]; | ||
1084 | bool pta_on; | ||
1085 | u32 val_0x6c0; | ||
1086 | u32 val_0x6c8; | ||
1087 | u32 val_0x6cc; | ||
1088 | bool sw_dac_swing_on; | ||
1089 | u32 sw_dac_swing_lvl; | ||
1090 | u32 wlan_act_hi; | ||
1091 | u32 wlan_act_lo; | ||
1092 | u32 bt_retry_index; | ||
1093 | bool dec_bt_pwr; | ||
1094 | bool ignore_wlan_act; | ||
1095 | }; | ||
1096 | |||
1097 | struct bt_coexist_8723 { | ||
1098 | u32 high_priority_tx; | ||
1099 | u32 high_priority_rx; | ||
1100 | u32 low_priority_tx; | ||
1101 | u32 low_priority_rx; | ||
1102 | u8 c2h_bt_info; | ||
1103 | bool c2h_bt_info_req_sent; | ||
1104 | bool c2h_bt_inquiry_page; | ||
1105 | u32 bt_inq_page_start_time; | ||
1106 | u8 bt_retry_cnt; | ||
1107 | u8 c2h_bt_info_original; | ||
1108 | u8 bt_inquiry_page_cnt; | ||
1109 | struct btdm_8723 btdm; | ||
1045 | }; | 1110 | }; |
1046 | 1111 | ||
1047 | struct rtl_hal { | 1112 | struct rtl_hal { |
1048 | struct ieee80211_hw *hw; | 1113 | struct ieee80211_hw *hw; |
1049 | 1114 | struct bt_coexist_8723 hal_coex_8723; | |
1050 | bool up_first_time; | 1115 | bool up_first_time; |
1051 | bool first_init; | ||
1052 | bool being_init_adapter; | 1116 | bool being_init_adapter; |
1053 | bool bbrf_ready; | 1117 | bool bbrf_ready; |
1054 | 1118 | ||
@@ -1312,6 +1376,7 @@ struct rtl_ps_ctl { | |||
1312 | }; | 1376 | }; |
1313 | 1377 | ||
1314 | struct rtl_stats { | 1378 | struct rtl_stats { |
1379 | u8 psaddr[ETH_ALEN]; | ||
1315 | u32 mac_time[2]; | 1380 | u32 mac_time[2]; |
1316 | s8 rssi; | 1381 | s8 rssi; |
1317 | u8 signal; | 1382 | u8 signal; |
@@ -1503,6 +1568,7 @@ struct rtl_hal_ops { | |||
1503 | void (*phy_lc_calibrate) (struct ieee80211_hw *hw, bool is2t); | 1568 | void (*phy_lc_calibrate) (struct ieee80211_hw *hw, bool is2t); |
1504 | void (*phy_set_bw_mode_callback) (struct ieee80211_hw *hw); | 1569 | void (*phy_set_bw_mode_callback) (struct ieee80211_hw *hw); |
1505 | void (*dm_dynamic_txpower) (struct ieee80211_hw *hw); | 1570 | void (*dm_dynamic_txpower) (struct ieee80211_hw *hw); |
1571 | void (*c2h_command_handle) (struct ieee80211_hw *hw); | ||
1506 | void (*bt_wifi_media_status_notify) (struct ieee80211_hw *hw, | 1572 | void (*bt_wifi_media_status_notify) (struct ieee80211_hw *hw, |
1507 | bool mstate); | 1573 | bool mstate); |
1508 | void (*bt_coex_off_before_lps) (struct ieee80211_hw *hw); | 1574 | void (*bt_coex_off_before_lps) (struct ieee80211_hw *hw); |
@@ -1784,9 +1850,22 @@ struct rtl_priv { | |||
1784 | struct dig_t dm_digtable; | 1850 | struct dig_t dm_digtable; |
1785 | struct ps_t dm_pstable; | 1851 | struct ps_t dm_pstable; |
1786 | 1852 | ||
1787 | /* data buffer pointer for USB reads */ | 1853 | /* section shared by individual drivers */ |
1788 | __le32 *usb_data; | 1854 | union { |
1789 | int usb_data_index; | 1855 | struct { /* data buffer pointer for USB reads */ |
1856 | __le32 *usb_data; | ||
1857 | int usb_data_index; | ||
1858 | bool initialized; | ||
1859 | }; | ||
1860 | struct { /* section for 8723ae */ | ||
1861 | bool reg_init; /* true if regs saved */ | ||
1862 | u32 reg_874; | ||
1863 | u32 reg_c70; | ||
1864 | u32 reg_85c; | ||
1865 | u32 reg_a74; | ||
1866 | bool bt_operation_on; | ||
1867 | }; | ||
1868 | }; | ||
1790 | 1869 | ||
1791 | /*This must be the last item so | 1870 | /*This must be the last item so |
1792 | that it points to the data allocated | 1871 | that it points to the data allocated |
@@ -1818,6 +1897,7 @@ enum bt_co_type { | |||
1818 | BT_CSR_BC4 = 3, | 1897 | BT_CSR_BC4 = 3, |
1819 | BT_CSR_BC8 = 4, | 1898 | BT_CSR_BC8 = 4, |
1820 | BT_RTL8756 = 5, | 1899 | BT_RTL8756 = 5, |
1900 | BT_RTL8723A = 6, | ||
1821 | }; | 1901 | }; |
1822 | 1902 | ||
1823 | enum bt_cur_state { | 1903 | enum bt_cur_state { |
@@ -1876,13 +1956,27 @@ struct bt_coexist_info { | |||
1876 | 1956 | ||
1877 | bool fw_coexist_all_off; | 1957 | bool fw_coexist_all_off; |
1878 | bool sw_coexist_all_off; | 1958 | bool sw_coexist_all_off; |
1879 | u32 current_state; | 1959 | bool hw_coexist_all_off; |
1960 | u32 cstate; | ||
1880 | u32 previous_state; | 1961 | u32 previous_state; |
1962 | u32 cstate_h; | ||
1963 | u32 previous_state_h; | ||
1964 | |||
1881 | u8 bt_pre_rssi_state; | 1965 | u8 bt_pre_rssi_state; |
1966 | u8 bt_pre_rssi_state1; | ||
1882 | 1967 | ||
1883 | u8 reg_bt_iso; | 1968 | u8 reg_bt_iso; |
1884 | u8 reg_bt_sco; | 1969 | u8 reg_bt_sco; |
1885 | 1970 | bool balance_on; | |
1971 | u8 bt_active_zero_cnt; | ||
1972 | bool cur_bt_disabled; | ||
1973 | bool pre_bt_disabled; | ||
1974 | |||
1975 | u8 bt_profile_case; | ||
1976 | u8 bt_profile_action; | ||
1977 | bool bt_busy; | ||
1978 | bool hold_for_bt_operation; | ||
1979 | u8 lps_counter; | ||
1886 | }; | 1980 | }; |
1887 | 1981 | ||
1888 | 1982 | ||
diff --git a/drivers/net/wireless/ti/wl1251/rx.c b/drivers/net/wireless/ti/wl1251/rx.c index 6af35265c900..23289d49dd31 100644 --- a/drivers/net/wireless/ti/wl1251/rx.c +++ b/drivers/net/wireless/ti/wl1251/rx.c | |||
@@ -81,7 +81,7 @@ static void wl1251_rx_status(struct wl1251 *wl, | |||
81 | status->freq = ieee80211_channel_to_frequency(desc->channel, | 81 | status->freq = ieee80211_channel_to_frequency(desc->channel, |
82 | status->band); | 82 | status->band); |
83 | 83 | ||
84 | status->flag |= RX_FLAG_MACTIME_MPDU; | 84 | status->flag |= RX_FLAG_MACTIME_START; |
85 | 85 | ||
86 | if (desc->flags & RX_DESC_ENCRYPTION_MASK) { | 86 | if (desc->flags & RX_DESC_ENCRYPTION_MASK) { |
87 | status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED; | 87 | status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED; |
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 25530c8760cb..4f1a05b92d2d 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c | |||
@@ -677,7 +677,7 @@ static void wl12xx_get_vif_count(struct ieee80211_hw *hw, | |||
677 | memset(data, 0, sizeof(*data)); | 677 | memset(data, 0, sizeof(*data)); |
678 | data->cur_vif = cur_vif; | 678 | data->cur_vif = cur_vif; |
679 | 679 | ||
680 | ieee80211_iterate_active_interfaces(hw, | 680 | ieee80211_iterate_active_interfaces(hw, IEEE80211_IFACE_ITER_RESUME_ALL, |
681 | wl12xx_vif_count_iter, data); | 681 | wl12xx_vif_count_iter, data); |
682 | } | 682 | } |
683 | 683 | ||
@@ -3791,7 +3791,7 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl, | |||
3791 | 3791 | ||
3792 | /* Handle HT information change */ | 3792 | /* Handle HT information change */ |
3793 | if ((changed & BSS_CHANGED_HT) && | 3793 | if ((changed & BSS_CHANGED_HT) && |
3794 | (bss_conf->channel_type != NL80211_CHAN_NO_HT)) { | 3794 | (bss_conf->chandef.width != NL80211_CHAN_WIDTH_20_NOHT)) { |
3795 | ret = wl1271_acx_set_ht_information(wl, wlvif, | 3795 | ret = wl1271_acx_set_ht_information(wl, wlvif, |
3796 | bss_conf->ht_operation_mode); | 3796 | bss_conf->ht_operation_mode); |
3797 | if (ret < 0) { | 3797 | if (ret < 0) { |
@@ -3905,7 +3905,8 @@ sta_not_found: | |||
3905 | u32 rates; | 3905 | u32 rates; |
3906 | int ieoffset; | 3906 | int ieoffset; |
3907 | wlvif->aid = bss_conf->aid; | 3907 | wlvif->aid = bss_conf->aid; |
3908 | wlvif->channel_type = bss_conf->channel_type; | 3908 | wlvif->channel_type = |
3909 | cfg80211_get_chandef_type(&bss_conf->chandef); | ||
3909 | wlvif->beacon_int = bss_conf->beacon_int; | 3910 | wlvif->beacon_int = bss_conf->beacon_int; |
3910 | do_join = true; | 3911 | do_join = true; |
3911 | set_assoc = true; | 3912 | set_assoc = true; |
@@ -4071,7 +4072,7 @@ sta_not_found: | |||
4071 | /* Handle new association with HT. Do this after join. */ | 4072 | /* Handle new association with HT. Do this after join. */ |
4072 | if (sta_exists) { | 4073 | if (sta_exists) { |
4073 | if ((changed & BSS_CHANGED_HT) && | 4074 | if ((changed & BSS_CHANGED_HT) && |
4074 | (bss_conf->channel_type != NL80211_CHAN_NO_HT)) { | 4075 | (bss_conf->chandef.width != NL80211_CHAN_WIDTH_20_NOHT)) { |
4075 | ret = wl1271_acx_set_ht_capabilities(wl, | 4076 | ret = wl1271_acx_set_ht_capabilities(wl, |
4076 | &sta_ht_cap, | 4077 | &sta_ht_cap, |
4077 | true, | 4078 | true, |
@@ -4098,7 +4099,7 @@ sta_not_found: | |||
4098 | 4099 | ||
4099 | /* Handle HT information change. Done after join. */ | 4100 | /* Handle HT information change. Done after join. */ |
4100 | if ((changed & BSS_CHANGED_HT) && | 4101 | if ((changed & BSS_CHANGED_HT) && |
4101 | (bss_conf->channel_type != NL80211_CHAN_NO_HT)) { | 4102 | (bss_conf->chandef.width != NL80211_CHAN_WIDTH_20_NOHT)) { |
4102 | ret = wl1271_acx_set_ht_information(wl, wlvif, | 4103 | ret = wl1271_acx_set_ht_information(wl, wlvif, |
4103 | bss_conf->ht_operation_mode); | 4104 | bss_conf->ht_operation_mode); |
4104 | if (ret < 0) { | 4105 | if (ret < 0) { |