diff --git a/[refs] b/[refs] index 1a6b85617da2..59fa78a80471 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 55cb0797fa779e36f62876a8aa44cbf3984e8d59 +refs/heads/master: 9f5e8f6efc7c2601136b27d9c7325c245f8fd19a diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 46ce7c6d527d..568ea9373091 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -1658,9 +1658,10 @@ F: drivers/net/ethernet/broadcom/tg3.* BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER M: Brett Rudley +M: Roland Vossen M: Arend van Spriel M: Franky (Zhenhui) Lin -M: Hante Meuleman +M: Kan Yan L: linux-wireless@vger.kernel.org L: brcm80211-dev-list@broadcom.com S: Supported @@ -5066,7 +5067,6 @@ F: net/nfc/ F: include/linux/nfc.h F: include/net/nfc/ F: drivers/nfc/ -F: include/linux/platform_data/pn544.h NFS, SUNRPC, AND LOCKD CLIENTS M: Trond Myklebust diff --git a/trunk/drivers/bcma/driver_pci_host.c b/trunk/drivers/bcma/driver_pci_host.c index e6b5c89469dc..e56449506695 100644 --- a/trunk/drivers/bcma/driver_pci_host.c +++ b/trunk/drivers/bcma/driver_pci_host.c @@ -538,7 +538,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_pcibridge); static void bcma_core_pci_fixup_addresses(struct pci_dev *dev) { struct resource *res; - int pos, err; + int pos; if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) { /* This is not a device on the PCI-core bridge. */ @@ -551,12 +551,8 @@ static void bcma_core_pci_fixup_addresses(struct pci_dev *dev) for (pos = 0; pos < 6; pos++) { res = &dev->resource[pos]; - if (res->flags & (IORESOURCE_IO | IORESOURCE_MEM)) { - err = pci_assign_resource(dev, pos); - if (err) - pr_err("PCI: Problem fixing up the addresses on %s\n", - pci_name(dev)); - } + if (res->flags & (IORESOURCE_IO | IORESOURCE_MEM)) + pci_assign_resource(dev, pos); } } DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_addresses); diff --git a/trunk/drivers/bluetooth/ath3k.c b/trunk/drivers/bluetooth/ath3k.c index b00000e8aef6..fc2de5528dcc 100644 --- a/trunk/drivers/bluetooth/ath3k.c +++ b/trunk/drivers/bluetooth/ath3k.c @@ -67,7 +67,6 @@ static struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x13d3, 0x3304) }, { USB_DEVICE(0x0930, 0x0215) }, { USB_DEVICE(0x0489, 0xE03D) }, - { USB_DEVICE(0x0489, 0xE027) }, /* Atheros AR9285 Malbec with sflash firmware */ { USB_DEVICE(0x03F0, 0x311D) }, diff --git a/trunk/drivers/bluetooth/btusb.c b/trunk/drivers/bluetooth/btusb.c index a1d4ede5b892..debda27df9b0 100644 --- a/trunk/drivers/bluetooth/btusb.c +++ b/trunk/drivers/bluetooth/btusb.c @@ -96,7 +96,6 @@ static struct usb_device_id btusb_table[] = { { USB_DEVICE(0x0c10, 0x0000) }, /* Broadcom BCM20702A0 */ - { USB_DEVICE(0x0b05, 0x17b5) }, { USB_DEVICE(0x04ca, 0x2003) }, { USB_DEVICE(0x0489, 0xe042) }, { USB_DEVICE(0x413c, 0x8197) }, @@ -125,7 +124,6 @@ static struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE }, - { USB_DEVICE(0x0489, 0xe027), .driver_info = BTUSB_IGNORE }, /* Atheros AR9285 Malbec with sflash firmware */ { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, diff --git a/trunk/drivers/net/wireless/at76c50x-usb.c b/trunk/drivers/net/wireless/at76c50x-usb.c index 77fa4286e5e9..99b9ddf21273 100644 --- a/trunk/drivers/net/wireless/at76c50x-usb.c +++ b/trunk/drivers/net/wireless/at76c50x-usb.c @@ -379,7 +379,7 @@ static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size, manifest_sync_timeout); if (!size) { - dev_err(&udev->dev, "FW buffer length invalid!\n"); + dev_printk(KERN_ERR, &udev->dev, "FW buffer length invalid!\n"); return -EINVAL; } @@ -391,8 +391,8 @@ static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size, if (need_dfu_state) { ret = at76_dfu_get_state(udev, &dfu_state); if (ret < 0) { - dev_err(&udev->dev, - "cannot get DFU state: %d\n", ret); + dev_printk(KERN_ERR, &udev->dev, + "cannot get DFU state: %d\n", ret); goto exit; } need_dfu_state = 0; @@ -407,9 +407,9 @@ static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size, dfu_timeout = at76_get_timeout(&dfu_stat_buf); need_dfu_state = 0; } else - dev_err(&udev->dev, - "at76_dfu_get_status returned %d\n", - ret); + dev_printk(KERN_ERR, &udev->dev, + "at76_dfu_get_status returned %d\n", + ret); break; case STATE_DFU_DOWNLOAD_BUSY: @@ -438,9 +438,9 @@ static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size, blockno++; if (ret != bsize) - dev_err(&udev->dev, - "at76_load_int_fw_block returned %d\n", - ret); + dev_printk(KERN_ERR, &udev->dev, + "at76_load_int_fw_block " + "returned %d\n", ret); need_dfu_state = 1; break; @@ -1255,7 +1255,8 @@ static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe) at76_dbg(DBG_DEVSTART, "opmode %d", op_mode); if (op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) { - dev_err(&udev->dev, "unexpected opmode %d\n", op_mode); + dev_printk(KERN_ERR, &udev->dev, "unexpected opmode %d\n", + op_mode); return -EINVAL; } @@ -1274,9 +1275,9 @@ static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe) size, bsize, blockno); ret = at76_load_ext_fw_block(udev, blockno, block, bsize); if (ret != bsize) { - dev_err(&udev->dev, - "loading %dth firmware block failed: %d\n", - blockno, ret); + dev_printk(KERN_ERR, &udev->dev, + "loading %dth firmware block failed: %d\n", + blockno, ret); goto exit; } buf += bsize; @@ -1292,8 +1293,8 @@ static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe) exit: kfree(block); if (ret < 0) - dev_err(&udev->dev, - "downloading external firmware failed: %d\n", ret); + dev_printk(KERN_ERR, &udev->dev, + "downloading external firmware failed: %d\n", ret); return ret; } @@ -1307,8 +1308,8 @@ static int at76_load_internal_fw(struct usb_device *udev, struct fwentry *fwe) need_remap ? 0 : 2 * HZ); if (ret < 0) { - dev_err(&udev->dev, - "downloading internal fw failed with %d\n", ret); + dev_printk(KERN_ERR, &udev->dev, + "downloading internal fw failed with %d\n", ret); goto exit; } @@ -1318,8 +1319,8 @@ static int at76_load_internal_fw(struct usb_device *udev, struct fwentry *fwe) if (need_remap) { ret = at76_remap(udev); if (ret < 0) { - dev_err(&udev->dev, - "sending REMAP failed with %d\n", ret); + dev_printk(KERN_ERR, &udev->dev, + "sending REMAP failed with %d\n", ret); goto exit; } } @@ -1554,10 +1555,11 @@ static struct fwentry *at76_load_firmware(struct usb_device *udev, at76_dbg(DBG_FW, "downloading firmware %s", fwe->fwname); ret = request_firmware(&fwe->fw, fwe->fwname, &udev->dev); if (ret < 0) { - dev_err(&udev->dev, "firmware %s not found!\n", - fwe->fwname); - dev_err(&udev->dev, - "you may need to download the firmware from http://developer.berlios.de/projects/at76c503a/\n"); + dev_printk(KERN_ERR, &udev->dev, "firmware %s not found!\n", + fwe->fwname); + dev_printk(KERN_ERR, &udev->dev, + "you may need to download the firmware from " + "http://developer.berlios.de/projects/at76c503a/\n"); goto exit; } @@ -1565,17 +1567,17 @@ static struct fwentry *at76_load_firmware(struct usb_device *udev, fwh = (struct at76_fw_header *)(fwe->fw->data); if (fwe->fw->size <= sizeof(*fwh)) { - dev_err(&udev->dev, - "firmware is too short (0x%zx)\n", fwe->fw->size); + dev_printk(KERN_ERR, &udev->dev, + "firmware is too short (0x%zx)\n", fwe->fw->size); goto exit; } /* CRC currently not checked */ fwe->board_type = le32_to_cpu(fwh->board_type); if (fwe->board_type != board_type) { - dev_err(&udev->dev, - "board type mismatch, requested %u, got %u\n", - board_type, fwe->board_type); + dev_printk(KERN_ERR, &udev->dev, + "board type mismatch, requested %u, got %u\n", + board_type, fwe->board_type); goto exit; } @@ -2148,7 +2150,8 @@ static int at76_alloc_urbs(struct at76_priv *priv, } if (!ep_in || !ep_out) { - dev_err(&interface->dev, "bulk endpoints missing\n"); + dev_printk(KERN_ERR, &interface->dev, + "bulk endpoints missing\n"); return -ENXIO; } @@ -2158,14 +2161,15 @@ static int at76_alloc_urbs(struct at76_priv *priv, priv->rx_urb = usb_alloc_urb(0, GFP_KERNEL); priv->tx_urb = usb_alloc_urb(0, GFP_KERNEL); if (!priv->rx_urb || !priv->tx_urb) { - dev_err(&interface->dev, "cannot allocate URB\n"); + dev_printk(KERN_ERR, &interface->dev, "cannot allocate URB\n"); return -ENOMEM; } buffer_size = sizeof(struct at76_tx_buffer) + MAX_PADDING_SIZE; priv->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL); if (!priv->bulk_out_buffer) { - dev_err(&interface->dev, "cannot allocate output buffer\n"); + dev_printk(KERN_ERR, &interface->dev, + "cannot allocate output buffer\n"); return -ENOMEM; } @@ -2226,7 +2230,8 @@ static int at76_init_new_device(struct at76_priv *priv, /* MAC address */ ret = at76_get_hw_config(priv); if (ret < 0) { - dev_err(&interface->dev, "cannot get MAC address\n"); + dev_printk(KERN_ERR, &interface->dev, + "cannot get MAC address\n"); goto exit; } @@ -2353,8 +2358,8 @@ static int at76_probe(struct usb_interface *interface, we get 204 with 2.4.23, Fiberline FL-WL240u (505A+RFMD2958) ??? */ if (op_mode == OPMODE_HW_CONFIG_MODE) { - dev_err(&interface->dev, - "cannot handle a device in HW_CONFIG_MODE\n"); + dev_printk(KERN_ERR, &interface->dev, + "cannot handle a device in HW_CONFIG_MODE\n"); ret = -EBUSY; goto error; } @@ -2366,9 +2371,9 @@ static int at76_probe(struct usb_interface *interface, "downloading internal firmware\n"); ret = at76_load_internal_fw(udev, fwe); if (ret < 0) { - dev_err(&interface->dev, - "error %d downloading internal firmware\n", - ret); + dev_printk(KERN_ERR, &interface->dev, + "error %d downloading internal firmware\n", + ret); goto error; } usb_put_dev(udev); @@ -2403,8 +2408,8 @@ static int at76_probe(struct usb_interface *interface, /* Re-check firmware version */ ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv)); if (ret < 0) { - dev_err(&interface->dev, - "error %d getting firmware version\n", ret); + dev_printk(KERN_ERR, &interface->dev, + "error %d getting firmware version\n", ret); goto error; } } @@ -2444,7 +2449,7 @@ static void at76_disconnect(struct usb_interface *interface) wiphy_info(priv->hw->wiphy, "disconnecting\n"); at76_delete_device(priv); - dev_info(&interface->dev, "disconnected\n"); + dev_printk(KERN_INFO, &interface->dev, "disconnected\n"); } /* Structure for registering this driver with the USB subsystem */ diff --git a/trunk/drivers/net/wireless/ath/Kconfig b/trunk/drivers/net/wireless/ath/Kconfig index 1a67a4f829fe..c25dcf192fec 100644 --- a/trunk/drivers/net/wireless/ath/Kconfig +++ b/trunk/drivers/net/wireless/ath/Kconfig @@ -1,7 +1,4 @@ -config ATH_COMMON - tristate - -menuconfig ATH_CARDS +menuconfig ATH_COMMON tristate "Atheros Wireless Cards" depends on CFG80211 && (!UML || BROKEN) ---help--- @@ -17,7 +14,7 @@ menuconfig ATH_CARDS http://wireless.kernel.org/en/users/Drivers/Atheros -if ATH_CARDS +if ATH_COMMON config ATH_DEBUG bool "Atheros wireless debugging" diff --git a/trunk/drivers/net/wireless/ath/ar5523/Kconfig b/trunk/drivers/net/wireless/ath/ar5523/Kconfig index 0d320cc7769b..11d99ee8de51 100644 --- a/trunk/drivers/net/wireless/ath/ar5523/Kconfig +++ b/trunk/drivers/net/wireless/ath/ar5523/Kconfig @@ -1,7 +1,6 @@ config AR5523 tristate "Atheros AR5523 wireless driver support" depends on MAC80211 && USB - select ATH_COMMON select FW_LOADER ---help--- This module add support for AR5523 based USB dongles such as D-Link diff --git a/trunk/drivers/net/wireless/ath/ar5523/ar5523.c b/trunk/drivers/net/wireless/ath/ar5523/ar5523.c index 7157f7d311c5..f782b6e502bf 100644 --- a/trunk/drivers/net/wireless/ath/ar5523/ar5523.c +++ b/trunk/drivers/net/wireless/ath/ar5523/ar5523.c @@ -50,19 +50,18 @@ static void ar5523_read_reply(struct ar5523 *ar, struct ar5523_cmd_hdr *hdr, struct ar5523_tx_cmd *cmd) { int dlen, olen; - __be32 *rp; + u32 *rp; - dlen = be32_to_cpu(hdr->len) - sizeof(*hdr); + dlen = hdr->len - sizeof(*hdr); if (dlen < 0) { WARN_ON(1); goto out; } - ar5523_dbg(ar, "Code = %d len = %d\n", be32_to_cpu(hdr->code) & 0xff, - dlen); + ar5523_dbg(ar, "Code = %d len = %d\n", hdr->code & 0xff, dlen); - rp = (__be32 *)(hdr + 1); + rp = (u32 *)(hdr + 1); if (dlen >= sizeof(u32)) { olen = be32_to_cpu(rp[0]); dlen -= sizeof(u32); @@ -96,7 +95,6 @@ static void ar5523_cmd_rx_cb(struct urb *urb) struct ar5523_tx_cmd *cmd = &ar->tx_cmd; struct ar5523_cmd_hdr *hdr = ar->rx_cmd_buf; int dlen; - u32 code, hdrlen; if (urb->status) { if (urb->status != -ESHUTDOWN) @@ -112,15 +110,15 @@ static void ar5523_cmd_rx_cb(struct urb *urb) ar5523_dbg(ar, "%s code %02x priv %d\n", __func__, be32_to_cpu(hdr->code) & 0xff, hdr->priv); - code = be32_to_cpu(hdr->code); - hdrlen = be32_to_cpu(hdr->len); + hdr->code = be32_to_cpu(hdr->code); + hdr->len = be32_to_cpu(hdr->len); - switch (code & 0xff) { + switch (hdr->code & 0xff) { default: /* reply to a read command */ if (hdr->priv != AR5523_CMD_ID) { ar5523_err(ar, "Unexpected command id: %02x\n", - code & 0xff); + hdr->code & 0xff); goto skip; } ar5523_read_reply(ar, hdr, cmd); @@ -149,7 +147,7 @@ static void ar5523_cmd_rx_cb(struct urb *urb) case WDCMSG_TARGET_START: /* This command returns a bogus id so it needs special handling */ - dlen = hdrlen - sizeof(*hdr); + dlen = hdr->len - sizeof(*hdr); if (dlen != (int)sizeof(u32)) { ar5523_err(ar, "Invalid reply to WDCMSG_TARGET_START"); return; @@ -305,7 +303,7 @@ static int ar5523_config(struct ar5523 *ar, u32 reg, u32 val) write.reg = cpu_to_be32(reg); write.len = cpu_to_be32(0); /* 0 = single write */ - *(__be32 *)write.data = cpu_to_be32(val); + *(u32 *)write.data = cpu_to_be32(val); error = ar5523_cmd_write(ar, WDCMSG_TARGET_SET_CONFIG, &write, 3 * sizeof(u32), 0); @@ -337,30 +335,29 @@ static int ar5523_get_status(struct ar5523 *ar, u32 which, void *odata, int olen) { int error; - __be32 which_be; - which_be = cpu_to_be32(which); + which = cpu_to_be32(which); error = ar5523_cmd_read(ar, WDCMSG_TARGET_GET_STATUS, - &which_be, sizeof(which_be), odata, olen, AR5523_CMD_FLAG_MAGIC); + &which, sizeof(which), odata, olen, AR5523_CMD_FLAG_MAGIC); if (error != 0) - ar5523_err(ar, "could not read EEPROM offset 0x%02x\n", which); + ar5523_err(ar, "could not read EEPROM offset 0x%02x\n", + be32_to_cpu(which)); return error; } static int ar5523_get_capability(struct ar5523 *ar, u32 cap, u32 *val) { int error; - __be32 cap_be, val_be; - cap_be = cpu_to_be32(cap); - error = ar5523_cmd_read(ar, WDCMSG_TARGET_GET_CAPABILITY, &cap_be, - sizeof(cap_be), &val_be, sizeof(__be32), - AR5523_CMD_FLAG_MAGIC); + cap = cpu_to_be32(cap); + error = ar5523_cmd_read(ar, WDCMSG_TARGET_GET_CAPABILITY, + &cap, sizeof(cap), val, sizeof(u32), AR5523_CMD_FLAG_MAGIC); if (error != 0) { - ar5523_err(ar, "could not read capability %u\n", cap); + ar5523_err(ar, "could not read capability %u\n", + be32_to_cpu(cap)); return error; } - *val = be32_to_cpu(val_be); + *val = be32_to_cpu(*val); return error; } @@ -1196,8 +1193,8 @@ static void ar5523_create_rateset(struct ar5523 *ar, if (!sta) { ar5523_info(ar, "STA not found. Cannot set rates\n"); sta_rate_set = bss_conf->basic_rates; - } else - sta_rate_set = sta->supp_rates[ar->hw->conf.channel->band]; + } + sta_rate_set = sta->supp_rates[ar->hw->conf.channel->band]; ar5523_dbg(ar, "sta rate_set = %08x\n", sta_rate_set); @@ -1792,7 +1789,18 @@ static struct usb_driver ar5523_driver = { .disconnect = ar5523_disconnect, }; -module_usb_driver(ar5523_driver); +static int __init ar5523_init(void) +{ + return usb_register(&ar5523_driver); +} + +static void __exit ar5523_exit(void) +{ + usb_deregister(&ar5523_driver); +} MODULE_LICENSE("Dual BSD/GPL"); MODULE_FIRMWARE(AR5523_FIRMWARE_FILE); + +module_init(ar5523_init); +module_exit(ar5523_exit); diff --git a/trunk/drivers/net/wireless/ath/ar5523/ar5523.h b/trunk/drivers/net/wireless/ath/ar5523/ar5523.h index 00c6fd346d48..6086ba3fb543 100644 --- a/trunk/drivers/net/wireless/ath/ar5523/ar5523.h +++ b/trunk/drivers/net/wireless/ath/ar5523/ar5523.h @@ -122,7 +122,7 @@ struct ar5523 { struct work_struct rx_refill_work; - unsigned int rxbufsz; + int rxbufsz; u8 serial[16]; struct ieee80211_channel channels[14]; diff --git a/trunk/drivers/net/wireless/ath/ar5523/ar5523_hw.h b/trunk/drivers/net/wireless/ath/ar5523/ar5523_hw.h index 0fe2c803f48f..a0e8bf460316 100644 --- a/trunk/drivers/net/wireless/ath/ar5523/ar5523_hw.h +++ b/trunk/drivers/net/wireless/ath/ar5523/ar5523_hw.h @@ -161,7 +161,7 @@ struct ar5523_rx_desc { struct ar5523_tx_desc { __be32 msglen; - u32 msgid; /* msg id (supplied by host) */ + __be32 msgid; /* msg id (supplied by host) */ __be32 type; /* opcode: WDMSG_SEND or WDCMSG_FLUSH */ __be32 txqid; /* tx queue id and flags */ #define UATH_TXQID_MASK 0x0f diff --git a/trunk/drivers/net/wireless/ath/ath5k/Kconfig b/trunk/drivers/net/wireless/ath/ath5k/Kconfig index c9f81a388f15..338c5c42357d 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/Kconfig +++ b/trunk/drivers/net/wireless/ath/ath5k/Kconfig @@ -1,7 +1,6 @@ config ATH5K tristate "Atheros 5xxx wireless cards support" depends on (PCI || ATHEROS_AR231X) && MAC80211 - select ATH_COMMON select MAC80211_LEDS select LEDS_CLASS select NEW_LEDS diff --git a/trunk/drivers/net/wireless/ath/ath5k/ahb.c b/trunk/drivers/net/wireless/ath/ath5k/ahb.c index 8e8bcc7a4805..aec33cc207fd 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/ahb.c +++ b/trunk/drivers/net/wireless/ath/ath5k/ahb.c @@ -236,4 +236,17 @@ static struct platform_driver ath_ahb_driver = { }, }; -module_platform_driver(ath_ahb_driver); +static int __init +ath5k_ahb_init(void) +{ + return platform_driver_register(&ath_ahb_driver); +} + +static void __exit +ath5k_ahb_exit(void) +{ + platform_driver_unregister(&ath_ahb_driver); +} + +module_init(ath5k_ahb_init); +module_exit(ath5k_ahb_exit); diff --git a/trunk/drivers/net/wireless/ath/ath5k/reset.c b/trunk/drivers/net/wireless/ath/ath5k/reset.c index 4084b1076286..0c2dd4771c36 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/reset.c +++ b/trunk/drivers/net/wireless/ath/ath5k/reset.c @@ -789,9 +789,9 @@ ath5k_hw_nic_wakeup(struct ath5k_hw *ah, struct ieee80211_channel *channel) * (I don't think it supports 44MHz) */ /* On 2425 initvals TURBO_SHORT is not present */ if (ah->ah_bwmode == AR5K_BWMODE_40MHZ) { - turbo = AR5K_PHY_TURBO_MODE; - if (ah->ah_radio != AR5K_RF2425) - turbo |= AR5K_PHY_TURBO_SHORT; + turbo = AR5K_PHY_TURBO_MODE | + (ah->ah_radio == AR5K_RF2425) ? 0 : + AR5K_PHY_TURBO_SHORT; } else if (ah->ah_bwmode != AR5K_BWMODE_DEFAULT) { if (ah->ah_radio == AR5K_RF5413) { mode |= (ah->ah_bwmode == AR5K_BWMODE_10MHZ) ? diff --git a/trunk/drivers/net/wireless/ath/ath6kl/Kconfig b/trunk/drivers/net/wireless/ath/ath6kl/Kconfig index 26c4b7220859..d755a5e7ed20 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/Kconfig +++ b/trunk/drivers/net/wireless/ath/ath6kl/Kconfig @@ -30,12 +30,3 @@ config ATH6KL_DEBUG depends on ATH6KL ---help--- Enables debug support - -config ATH6KL_REGDOMAIN - bool "Atheros ath6kl regdomain support" - depends on ATH6KL - depends on CFG80211_CERTIFICATION_ONUS - ---help--- - Enabling this makes it possible to change the regdomain in - the firmware. This can be only enabled if regulatory requirements - are taken into account. diff --git a/trunk/drivers/net/wireless/ath/ath6kl/Makefile b/trunk/drivers/net/wireless/ath/ath6kl/Makefile index cab0ec0d5380..8cae8886f17d 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/Makefile +++ b/trunk/drivers/net/wireless/ath/ath6kl/Makefile @@ -34,7 +34,6 @@ ath6kl_core-y += main.o ath6kl_core-y += txrx.o ath6kl_core-y += wmi.o ath6kl_core-y += core.o -ath6kl_core-y += recovery.o ath6kl_core-$(CONFIG_NL80211_TESTMODE) += testmode.o obj-$(CONFIG_ATH6KL_SDIO) += ath6kl_sdio.o diff --git a/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.c b/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.c index 5516a8ccc3c6..51bbe85c574c 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -147,15 +147,15 @@ static bool __ath6kl_cfg80211_sscan_stop(struct ath6kl_vif *vif) { struct ath6kl *ar = vif->ar; - if (!test_and_clear_bit(SCHED_SCANNING, &vif->flags)) + if (ar->state != ATH6KL_STATE_SCHED_SCAN) return false; del_timer_sync(&vif->sched_scan_timer); - if (ar->state == ATH6KL_STATE_RECOVERY) - return true; + ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, + ATH6KL_HOST_MODE_AWAKE); - ath6kl_wmi_enable_sched_scan_cmd(ar->wmi, vif->fw_vif_idx, false); + ar->state = ATH6KL_STATE_ON; return true; } @@ -369,13 +369,17 @@ static int ath6kl_nliftype_to_drv_iftype(enum nl80211_iftype type, u8 *nw_type) { switch (type) { case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_P2P_CLIENT: *nw_type = INFRA_NETWORK; break; case NL80211_IFTYPE_ADHOC: *nw_type = ADHOC_NETWORK; break; case NL80211_IFTYPE_AP: + *nw_type = AP_NETWORK; + break; + case NL80211_IFTYPE_P2P_CLIENT: + *nw_type = INFRA_NETWORK; + break; case NL80211_IFTYPE_P2P_GO: *nw_type = AP_NETWORK; break; @@ -1027,15 +1031,30 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, vif->scan_req = request; - ret = ath6kl_wmi_beginscan_cmd(ar->wmi, vif->fw_vif_idx, - WMI_LONG_SCAN, force_fg_scan, - false, 0, - ATH6KL_FG_SCAN_INTERVAL, - n_channels, channels, - request->no_cck, - request->rates); + if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX, + ar->fw_capabilities)) { + /* + * If capable of doing P2P mgmt operations using + * station interface, send additional information like + * supported rates to advertise and xmit rates for + * probe requests + */ + ret = ath6kl_wmi_beginscan_cmd(ar->wmi, vif->fw_vif_idx, + WMI_LONG_SCAN, force_fg_scan, + false, 0, + ATH6KL_FG_SCAN_INTERVAL, + n_channels, channels, + request->no_cck, + request->rates); + } else { + ret = ath6kl_wmi_startscan_cmd(ar->wmi, vif->fw_vif_idx, + WMI_LONG_SCAN, force_fg_scan, + false, 0, + ATH6KL_FG_SCAN_INTERVAL, + n_channels, channels); + } if (ret) { - ath6kl_err("failed to start scan: %d\n", ret); + ath6kl_err("wmi_startscan_cmd failed\n"); vif->scan_req = NULL; } @@ -1872,7 +1891,7 @@ static int ath6kl_wow_usr(struct ath6kl *ar, struct ath6kl_vif *vif, struct cfg80211_wowlan *wow, u32 *filter) { int ret, pos; - u8 mask[WOW_PATTERN_SIZE]; + u8 mask[WOW_MASK_SIZE]; u16 i; /* Configure the patterns that we received from the user. */ @@ -2090,16 +2109,33 @@ static int ath6kl_cfg80211_host_sleep(struct ath6kl *ar, struct ath6kl_vif *vif) return ret; } -static int ath6kl_wow_suspend_vif(struct ath6kl_vif *vif, - struct cfg80211_wowlan *wow, u32 *filter) +static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) { - struct ath6kl *ar = vif->ar; struct in_device *in_dev; struct in_ifaddr *ifa; + struct ath6kl_vif *vif; int ret; + u32 filter = 0; u16 i, bmiss_time; - __be32 ips[MAX_IP_ADDRS]; u8 index = 0; + __be32 ips[MAX_IP_ADDRS]; + + /* The FW currently can't support multi-vif WoW properly. */ + if (ar->num_vif > 1) + return -EIO; + + vif = ath6kl_vif_first(ar); + if (!vif) + return -EIO; + + if (!ath6kl_cfg80211_ready(vif)) + return -EIO; + + if (!test_bit(CONNECTED, &vif->flags)) + return -ENOTCONN; + + if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST)) + return -EINVAL; if (!test_bit(NETDEV_MCAST_ALL_ON, &vif->flags) && test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER, @@ -2121,7 +2157,7 @@ static int ath6kl_wow_suspend_vif(struct ath6kl_vif *vif, * the user. */ if (wow) - ret = ath6kl_wow_usr(ar, vif, wow, filter); + ret = ath6kl_wow_usr(ar, vif, wow, &filter); else if (vif->nw_type == AP_NETWORK) ret = ath6kl_wow_ap(ar, vif); else @@ -2156,10 +2192,12 @@ static int ath6kl_wow_suspend_vif(struct ath6kl_vif *vif, return ret; } + ar->state = ATH6KL_STATE_SUSPENDING; + /* Setup own IP addr for ARP agent. */ in_dev = __in_dev_get_rtnl(vif->ndev); if (!in_dev) - return 0; + goto skip_arp; ifa = in_dev->ifa_list; memset(&ips, 0, sizeof(ips)); @@ -2182,61 +2220,41 @@ static int ath6kl_wow_suspend_vif(struct ath6kl_vif *vif, return ret; } - return ret; -} - -static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) -{ - struct ath6kl_vif *first_vif, *vif; - int ret = 0; - u32 filter = 0; - bool connected = false; - - /* enter / leave wow suspend on first vif always */ - first_vif = ath6kl_vif_first(ar); - if (WARN_ON(unlikely(!first_vif)) || - !ath6kl_cfg80211_ready(first_vif)) - return -EIO; - - if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST)) - return -EINVAL; - - /* install filters for each connected vif */ - spin_lock_bh(&ar->list_lock); - list_for_each_entry(vif, &ar->vif_list, list) { - if (!test_bit(CONNECTED, &vif->flags) || - !ath6kl_cfg80211_ready(vif)) - continue; - connected = true; - - ret = ath6kl_wow_suspend_vif(vif, wow, &filter); - if (ret) - break; - } - spin_unlock_bh(&ar->list_lock); - - if (!connected) - return -ENOTCONN; - else if (ret) - return ret; - - ar->state = ATH6KL_STATE_SUSPENDING; - - ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, first_vif->fw_vif_idx, +skip_arp: + ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx, ATH6KL_WOW_MODE_ENABLE, filter, WOW_HOST_REQ_DELAY); if (ret) return ret; - return ath6kl_cfg80211_host_sleep(ar, first_vif); + ret = ath6kl_cfg80211_host_sleep(ar, vif); + if (ret) + return ret; + + return 0; } -static int ath6kl_wow_resume_vif(struct ath6kl_vif *vif) +static int ath6kl_wow_resume(struct ath6kl *ar) { - struct ath6kl *ar = vif->ar; + struct ath6kl_vif *vif; int ret; + vif = ath6kl_vif_first(ar); + if (!vif) + return -EIO; + + ar->state = ATH6KL_STATE_RESUMING; + + ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, + ATH6KL_HOST_MODE_AWAKE); + if (ret) { + ath6kl_warn("Failed to configure host sleep mode for wow resume: %d\n", + ret); + ar->state = ATH6KL_STATE_WOW; + return ret; + } + if (vif->nw_type != AP_NETWORK) { ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0); @@ -2254,11 +2272,13 @@ static int ath6kl_wow_resume_vif(struct ath6kl_vif *vif) return ret; } + ar->state = ATH6KL_STATE_ON; + if (!test_bit(NETDEV_MCAST_ALL_OFF, &vif->flags) && test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER, ar->fw_capabilities)) { ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, - vif->fw_vif_idx, true); + vif->fw_vif_idx, true); if (ret) return ret; } @@ -2268,48 +2288,6 @@ static int ath6kl_wow_resume_vif(struct ath6kl_vif *vif) return 0; } -static int ath6kl_wow_resume(struct ath6kl *ar) -{ - struct ath6kl_vif *vif; - int ret; - - vif = ath6kl_vif_first(ar); - if (WARN_ON(unlikely(!vif)) || - !ath6kl_cfg80211_ready(vif)) - return -EIO; - - ar->state = ATH6KL_STATE_RESUMING; - - ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, - ATH6KL_HOST_MODE_AWAKE); - if (ret) { - ath6kl_warn("Failed to configure host sleep mode for wow resume: %d\n", - ret); - goto cleanup; - } - - spin_lock_bh(&ar->list_lock); - list_for_each_entry(vif, &ar->vif_list, list) { - if (!test_bit(CONNECTED, &vif->flags) || - !ath6kl_cfg80211_ready(vif)) - continue; - ret = ath6kl_wow_resume_vif(vif); - if (ret) - break; - } - spin_unlock_bh(&ar->list_lock); - - if (ret) - goto cleanup; - - ar->state = ATH6KL_STATE_ON; - return 0; - -cleanup: - ar->state = ATH6KL_STATE_WOW; - return ret; -} - static int ath6kl_cfg80211_deepsleep_suspend(struct ath6kl *ar) { struct ath6kl_vif *vif; @@ -2446,6 +2424,13 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar, break; + case ATH6KL_CFG_SUSPEND_SCHED_SCAN: + /* + * Nothing needed for schedule scan, firmware is already in + * wow mode and sleeping most of the time. + */ + break; + default: break; } @@ -2493,6 +2478,9 @@ int ath6kl_cfg80211_resume(struct ath6kl *ar) } break; + case ATH6KL_STATE_SCHED_SCAN: + break; + default: break; } @@ -2509,23 +2497,14 @@ static int __ath6kl_cfg80211_suspend(struct wiphy *wiphy, { struct ath6kl *ar = wiphy_priv(wiphy); - ath6kl_recovery_suspend(ar); - return ath6kl_hif_suspend(ar, wow); } static int __ath6kl_cfg80211_resume(struct wiphy *wiphy) { struct ath6kl *ar = wiphy_priv(wiphy); - int err; - - err = ath6kl_hif_resume(ar); - if (err) - return err; - - ath6kl_recovery_resume(ar); - return 0; + return ath6kl_hif_resume(ar); } /* @@ -2762,7 +2741,6 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev, int res; int i, ret; u16 rsn_capab = 0; - int inactivity_timeout = 0; ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s:\n", __func__); @@ -2899,15 +2877,8 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev, } if (info->inactivity_timeout) { - - inactivity_timeout = info->inactivity_timeout; - - if (ar->hw.flags & ATH6KL_HW_AP_INACTIVITY_MINS) - inactivity_timeout = DIV_ROUND_UP(inactivity_timeout, - 60); - res = ath6kl_wmi_set_inact_period(ar->wmi, vif->fw_vif_idx, - inactivity_timeout); + info->inactivity_timeout); if (res < 0) return res; } @@ -2930,7 +2901,6 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev, WLAN_EID_RSN, WMI_RSN_IE_CAPB, (const u8 *) &rsn_capab, sizeof(rsn_capab)); - vif->rsn_capab = rsn_capab; if (res < 0) return res; } @@ -3241,7 +3211,7 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy, struct ath6kl *ar = ath6kl_priv(dev); struct ath6kl_vif *vif = netdev_priv(dev); u16 interval; - int ret, rssi_thold; + int ret; if (ar->state != ATH6KL_STATE_ON) return -EIO; @@ -3249,6 +3219,10 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy, if (vif->sme_state != SME_DISCONNECTED) return -EBUSY; + /* The FW currently can't support multi-vif WoW properly. */ + if (ar->num_vif > 1) + return -EIO; + ath6kl_cfg80211_scan_complete_event(vif, true); ret = ath6kl_set_probed_ssids(ar, vif, request->ssids, @@ -3270,23 +3244,6 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy, return ret; } - if (test_bit(ATH6KL_FW_CAPABILITY_RSSI_SCAN_THOLD, - ar->fw_capabilities)) { - if (request->rssi_thold <= NL80211_SCAN_RSSI_THOLD_OFF) - rssi_thold = 0; - else if (request->rssi_thold < -127) - rssi_thold = -127; - else - rssi_thold = request->rssi_thold; - - ret = ath6kl_wmi_set_rssi_filter_cmd(ar->wmi, vif->fw_vif_idx, - rssi_thold); - if (ret) { - ath6kl_err("failed to set RSSI threshold for scan\n"); - return ret; - } - } - /* fw uses seconds, also make sure that it's >0 */ interval = max_t(u16, 1, request->interval / 1000); @@ -3294,6 +3251,15 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy, interval, interval, vif->bg_scan_period, 0, 0, 0, 3, 0, 0, 0); + ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx, + ATH6KL_WOW_MODE_ENABLE, + WOW_FILTER_SSID, + WOW_HOST_REQ_DELAY); + if (ret) { + ath6kl_warn("Failed to enable wow with ssid filter: %d\n", ret); + return ret; + } + /* this also clears IE in fw if it's not set */ ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx, WMI_FRAME_PROBE_REQ, @@ -3304,13 +3270,17 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy, return ret; } - ret = ath6kl_wmi_enable_sched_scan_cmd(ar->wmi, vif->fw_vif_idx, true); - if (ret) + ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, + ATH6KL_HOST_MODE_ASLEEP); + if (ret) { + ath6kl_warn("Failed to enable host sleep mode for sched scan: %d\n", + ret); return ret; + } - set_bit(SCHED_SCANNING, &vif->flags); + ar->state = ATH6KL_STATE_SCHED_SCAN; - return 0; + return ret; } static int ath6kl_cfg80211_sscan_stop(struct wiphy *wiphy, @@ -3339,27 +3309,6 @@ static int ath6kl_cfg80211_set_bitrate(struct wiphy *wiphy, mask); } -static int ath6kl_cfg80211_set_txe_config(struct wiphy *wiphy, - struct net_device *dev, - u32 rate, u32 pkts, u32 intvl) -{ - struct ath6kl *ar = ath6kl_priv(dev); - struct ath6kl_vif *vif = netdev_priv(dev); - - if (vif->nw_type != INFRA_NETWORK || - !test_bit(ATH6KL_FW_CAPABILITY_TX_ERR_NOTIFY, ar->fw_capabilities)) - return -EOPNOTSUPP; - - if (vif->sme_state != SME_CONNECTED) - return -ENOTCONN; - - /* save this since the firmware won't report the interval */ - vif->txe_intvl = intvl; - - return ath6kl_wmi_set_txe_notify(ar->wmi, vif->fw_vif_idx, - rate, pkts, intvl); -} - static const struct ieee80211_txrx_stypes ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = { [NL80211_IFTYPE_STATION] = { @@ -3426,7 +3375,6 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = { .sched_scan_start = ath6kl_cfg80211_sscan_start, .sched_scan_stop = ath6kl_cfg80211_sscan_stop, .set_bitrate_mask = ath6kl_cfg80211_set_bitrate, - .set_cqm_txe_config = ath6kl_cfg80211_set_txe_config, }; void ath6kl_cfg80211_stop(struct ath6kl_vif *vif) @@ -3447,22 +3395,16 @@ void ath6kl_cfg80211_stop(struct ath6kl_vif *vif) break; } - if (vif->ar->state != ATH6KL_STATE_RECOVERY && - (test_bit(CONNECTED, &vif->flags) || - test_bit(CONNECT_PEND, &vif->flags))) + if (test_bit(CONNECTED, &vif->flags) || + test_bit(CONNECT_PEND, &vif->flags)) ath6kl_wmi_disconnect_cmd(vif->ar->wmi, vif->fw_vif_idx); vif->sme_state = SME_DISCONNECTED; clear_bit(CONNECTED, &vif->flags); clear_bit(CONNECT_PEND, &vif->flags); - /* Stop netdev queues, needed during recovery */ - netif_stop_queue(vif->ndev); - netif_carrier_off(vif->ndev); - /* disable scanning */ - if (vif->ar->state != ATH6KL_STATE_RECOVERY && - ath6kl_wmi_scanparams_cmd(vif->ar->wmi, vif->fw_vif_idx, 0xFFFF, + if (ath6kl_wmi_scanparams_cmd(vif->ar->wmi, vif->fw_vif_idx, 0xFFFF, 0, 0, 0, 0, 0, 0, 0, 0, 0) != 0) ath6kl_warn("failed to disable scan during stop\n"); @@ -3474,7 +3416,7 @@ void ath6kl_cfg80211_stop_all(struct ath6kl *ar) struct ath6kl_vif *vif; vif = ath6kl_vif_first(ar); - if (!vif && ar->state != ATH6KL_STATE_RECOVERY) { + if (!vif) { /* save the current power mode before enabling power save */ ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode; @@ -3492,56 +3434,6 @@ void ath6kl_cfg80211_stop_all(struct ath6kl *ar) ath6kl_cfg80211_stop(vif); } -static int ath6kl_cfg80211_reg_notify(struct wiphy *wiphy, - struct regulatory_request *request) -{ - struct ath6kl *ar = wiphy_priv(wiphy); - u32 rates[IEEE80211_NUM_BANDS]; - int ret, i; - - ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, - "cfg reg_notify %c%c%s%s initiator %d hint_type %d\n", - request->alpha2[0], request->alpha2[1], - request->intersect ? " intersect" : "", - request->processed ? " processed" : "", - request->initiator, request->user_reg_hint_type); - - /* - * As firmware is not able intersect regdoms, we can only listen to - * cellular hints. - */ - if (request->user_reg_hint_type != NL80211_USER_REG_HINT_CELL_BASE) - return -EOPNOTSUPP; - - ret = ath6kl_wmi_set_regdomain_cmd(ar->wmi, request->alpha2); - if (ret) { - ath6kl_err("failed to set regdomain: %d\n", ret); - return ret; - } - - /* - * Firmware will apply the regdomain change only after a scan is - * issued and it will send a WMI_REGDOMAIN_EVENTID when it has been - * changed. - */ - - for (i = 0; i < IEEE80211_NUM_BANDS; i++) - if (wiphy->bands[i]) - rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1; - - - ret = ath6kl_wmi_beginscan_cmd(ar->wmi, 0, WMI_LONG_SCAN, false, - false, 0, ATH6KL_FG_SCAN_INTERVAL, - 0, NULL, false, rates); - if (ret) { - ath6kl_err("failed to start scan for a regdomain change: %d\n", - ret); - return ret; - } - - return 0; -} - static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif) { vif->aggr_cntxt = aggr_init(vif); @@ -3614,13 +3506,9 @@ struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name, vif->htcap[IEEE80211_BAND_5GHZ].ht_enable = true; memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN); - if (fw_vif_idx != 0) { + if (fw_vif_idx != 0) ndev->dev_addr[0] = (ndev->dev_addr[0] ^ (1 << fw_vif_idx)) | 0x2; - if (test_bit(ATH6KL_FW_CAPABILITY_CUSTOM_MAC_ADDR, - ar->fw_capabilities)) - ndev->dev_addr[4] ^= 0x80; - } init_netdev(ndev); @@ -3674,12 +3562,6 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) BIT(NL80211_IFTYPE_P2P_CLIENT); } - if (config_enabled(CONFIG_ATH6KL_REGDOMAIN) && - test_bit(ATH6KL_FW_CAPABILITY_REGDOMAIN, ar->fw_capabilities)) { - wiphy->reg_notifier = ath6kl_cfg80211_reg_notify; - ar->wiphy->features |= NL80211_FEATURE_CELL_BASE_REG_HINTS; - } - /* max num of ssids that can be probed during scanning */ wiphy->max_scan_ssids = MAX_PROBED_SSIDS; @@ -3725,7 +3607,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) ath6kl_band_5ghz.ht_cap.ht_supported = false; } - if (ar->hw.flags & ATH6KL_HW_64BIT_RATES) { + if (ar->hw.flags & ATH6KL_HW_FLAG_64BIT_RATES) { ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff; ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff; ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff; @@ -3764,7 +3646,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; - if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, ar->fw_capabilities)) + if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN, ar->fw_capabilities)) ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; if (test_bit(ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT, diff --git a/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.h b/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.h index e5e70f3a8ca8..780f77775a91 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.h +++ b/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.h @@ -22,6 +22,7 @@ enum ath6kl_cfg_suspend_mode { ATH6KL_CFG_SUSPEND_DEEPSLEEP, ATH6KL_CFG_SUSPEND_CUTPOWER, ATH6KL_CFG_SUSPEND_WOW, + ATH6KL_CFG_SUSPEND_SCHED_SCAN, }; struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name, diff --git a/trunk/drivers/net/wireless/ath/ath6kl/core.c b/trunk/drivers/net/wireless/ath/ath6kl/core.c index 4b46adbe8c92..82c4dd2a960e 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/core.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/core.c @@ -33,8 +33,6 @@ static unsigned int wow_mode; static unsigned int uart_debug; static unsigned int ath6kl_p2p; static unsigned int testmode; -static unsigned int recovery_enable; -static unsigned int heart_beat_poll; module_param(debug_mask, uint, 0644); module_param(suspend_mode, uint, 0644); @@ -42,12 +40,6 @@ module_param(wow_mode, uint, 0644); module_param(uart_debug, uint, 0644); module_param(ath6kl_p2p, uint, 0644); module_param(testmode, uint, 0644); -module_param(recovery_enable, uint, 0644); -module_param(heart_beat_poll, uint, 0644); -MODULE_PARM_DESC(recovery_enable, "Enable recovery from firmware error"); -MODULE_PARM_DESC(heart_beat_poll, "Enable fw error detection periodic" \ - "polling. This also specifies the polling interval in" \ - "msecs. Set reocvery_enable for this to be effective"); void ath6kl_core_tx_complete(struct ath6kl *ar, struct sk_buff *skb) { @@ -210,17 +202,6 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type) ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n", __func__, wdev->netdev->name, wdev->netdev, ar); - ar->fw_recovery.enable = !!recovery_enable; - if (!ar->fw_recovery.enable) - return ret; - - if (heart_beat_poll && - test_bit(ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL, - ar->fw_capabilities)) - ar->fw_recovery.hb_poll = heart_beat_poll; - - ath6kl_recovery_init(ar); - return ret; err_rxbuf_cleanup: @@ -310,8 +291,6 @@ void ath6kl_core_cleanup(struct ath6kl *ar) { ath6kl_hif_power_off(ar); - ath6kl_recovery_cleanup(ar); - destroy_workqueue(ar->ath6kl_wq); if (ar->htc_target) diff --git a/trunk/drivers/net/wireless/ath/ath6kl/core.h b/trunk/drivers/net/wireless/ath/ath6kl/core.h index 189d8faf8c87..cec49a31029a 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/core.h +++ b/trunk/drivers/net/wireless/ath/ath6kl/core.h @@ -115,27 +115,6 @@ enum ath6kl_fw_capability { */ ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST, - /* Firmware supports filtering BSS results by RSSI */ - ATH6KL_FW_CAPABILITY_RSSI_SCAN_THOLD, - - /* FW sets mac_addr[4] ^= 0x80 for newly created interfaces */ - ATH6KL_FW_CAPABILITY_CUSTOM_MAC_ADDR, - - /* Firmware supports TX error rate notification */ - ATH6KL_FW_CAPABILITY_TX_ERR_NOTIFY, - - /* supports WMI_SET_REGDOMAIN_CMDID command */ - ATH6KL_FW_CAPABILITY_REGDOMAIN, - - /* Firmware supports sched scan decoupled from host sleep */ - ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, - - /* - * Firmware capability for hang detection through heart beat - * challenge messages. - */ - ATH6KL_FW_CAPABILITY_HEART_BEAT_POLL, - /* this needs to be last */ ATH6KL_FW_CAPABILITY_MAX, }; @@ -149,15 +128,11 @@ struct ath6kl_fw_ie { }; enum ath6kl_hw_flags { - ATH6KL_HW_64BIT_RATES = BIT(0), - ATH6KL_HW_AP_INACTIVITY_MINS = BIT(1), - ATH6KL_HW_MAP_LP_ENDPOINT = BIT(2), - ATH6KL_HW_SDIO_CRC_ERROR_WAR = BIT(3), + ATH6KL_HW_FLAG_64BIT_RATES = BIT(0), }; #define ATH6KL_FW_API2_FILE "fw-2.bin" #define ATH6KL_FW_API3_FILE "fw-3.bin" -#define ATH6KL_FW_API4_FILE "fw-4.bin" /* AR6003 1.0 definitions */ #define AR6003_HW_1_0_VERSION 0x300002ba @@ -211,13 +186,6 @@ enum ath6kl_hw_flags { #define AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE \ AR6004_HW_1_2_FW_DIR "/bdata.bin" -/* AR6004 1.3 definitions */ -#define AR6004_HW_1_3_VERSION 0x31c8088a -#define AR6004_HW_1_3_FW_DIR "ath6k/AR6004/hw1.3" -#define AR6004_HW_1_3_FIRMWARE_FILE "fw.ram.bin" -#define AR6004_HW_1_3_BOARD_DATA_FILE "ath6k/AR6004/hw1.3/bdata.bin" -#define AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE "ath6k/AR6004/hw1.3/bdata.bin" - /* Per STA data, used in AP mode */ #define STA_PS_AWAKE BIT(0) #define STA_PS_SLEEP BIT(1) @@ -568,7 +536,6 @@ enum ath6kl_vif_state { HOST_SLEEP_MODE_CMD_PROCESSED, NETDEV_MCAST_ALL_ON, NETDEV_MCAST_ALL_OFF, - SCHED_SCANNING, }; struct ath6kl_vif { @@ -613,13 +580,11 @@ struct ath6kl_vif { u16 assoc_bss_beacon_int; u16 listen_intvl_t; u16 bmiss_time_t; - u32 txe_intvl; u16 bg_scan_period; u8 assoc_bss_dtim_period; struct net_device_stats net_stats; struct target_stats target_stats; struct wmi_connect_cmd profile; - u16 rsn_capab; struct list_head mc_filter; }; @@ -644,7 +609,6 @@ enum ath6kl_dev_state { SKIP_SCAN, ROAM_TBL_PEND, FIRST_BOOT, - RECOVERY_CLEANUP, }; enum ath6kl_state { @@ -655,16 +619,7 @@ enum ath6kl_state { ATH6KL_STATE_DEEPSLEEP, ATH6KL_STATE_CUTPOWER, ATH6KL_STATE_WOW, - ATH6KL_STATE_RECOVERY, -}; - -/* Fw error recovery */ -#define ATH6KL_HB_RESP_MISS_THRES 5 - -enum ath6kl_fw_err { - ATH6KL_FW_ASSERT, - ATH6KL_FW_HB_RESP_FAILURE, - ATH6KL_FW_EP_FULL, + ATH6KL_STATE_SCHED_SCAN, }; struct ath6kl { @@ -724,7 +679,6 @@ struct ath6kl { struct ath6kl_req_key ap_mode_bkey; struct sk_buff_head mcastpsq; u32 want_ch_switch; - u16 last_ch; /* * FIXME: protects access to mcastpsq but is actually useless as @@ -810,17 +764,6 @@ struct ath6kl { bool wiphy_registered; - struct ath6kl_fw_recovery { - struct work_struct recovery_work; - unsigned long err_reason; - unsigned long hb_poll; - struct timer_list hb_timer; - u32 seq_num; - bool hb_pending; - u8 hb_misscnt; - bool enable; - } fw_recovery; - #ifdef CONFIG_ATH6KL_DEBUG struct { struct sk_buff_head fwlog_queue; @@ -956,12 +899,4 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type); void ath6kl_core_cleanup(struct ath6kl *ar); void ath6kl_core_destroy(struct ath6kl *ar); -/* Fw error recovery */ -void ath6kl_init_hw_restart(struct ath6kl *ar); -void ath6kl_recovery_err_notify(struct ath6kl *ar, enum ath6kl_fw_err reason); -void ath6kl_recovery_hb_event(struct ath6kl *ar, u32 cookie); -void ath6kl_recovery_init(struct ath6kl *ar); -void ath6kl_recovery_cleanup(struct ath6kl *ar); -void ath6kl_recovery_suspend(struct ath6kl *ar); -void ath6kl_recovery_resume(struct ath6kl *ar); #endif /* CORE_H */ diff --git a/trunk/drivers/net/wireless/ath/ath6kl/debug.h b/trunk/drivers/net/wireless/ath/ath6kl/debug.h index f97cd4ead543..49639d8266c2 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/debug.h +++ b/trunk/drivers/net/wireless/ath/ath6kl/debug.h @@ -44,7 +44,6 @@ enum ATH6K_DEBUG_MASK { ATH6KL_DBG_SUSPEND = BIT(20), ATH6KL_DBG_USB = BIT(21), ATH6KL_DBG_USB_BULK = BIT(22), - ATH6KL_DBG_RECOVERY = BIT(23), ATH6KL_DBG_ANY = 0xffffffff /* enable all logs */ }; diff --git a/trunk/drivers/net/wireless/ath/ath6kl/hif.c b/trunk/drivers/net/wireless/ath/ath6kl/hif.c index a6b614421fa4..68ed6c2665b7 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/hif.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/hif.c @@ -136,7 +136,6 @@ static int ath6kl_hif_proc_dbg_intr(struct ath6kl_device *dev) ath6kl_hif_dump_fw_crash(dev->ar); ath6kl_read_fwlogs(dev->ar); - ath6kl_recovery_err_notify(dev->ar, ATH6KL_FW_ASSERT); return ret; } @@ -339,7 +338,8 @@ static int ath6kl_hif_proc_err_intr(struct ath6kl_device *dev) status = hif_read_write_sync(dev->ar, ERROR_INT_STATUS_ADDRESS, reg_buf, 4, HIF_WR_SYNC_BYTE_FIX); - WARN_ON(status); + if (status) + WARN_ON(1); return status; } @@ -383,7 +383,8 @@ static int ath6kl_hif_proc_cpu_intr(struct ath6kl_device *dev) status = hif_read_write_sync(dev->ar, CPU_INT_STATUS_ADDRESS, reg_buf, 4, HIF_WR_SYNC_BYTE_FIX); - WARN_ON(status); + if (status) + WARN_ON(1); return status; } @@ -694,6 +695,11 @@ int ath6kl_hif_setup(struct ath6kl_device *dev) ath6kl_dbg(ATH6KL_DBG_HIF, "hif block size %d mbox addr 0x%x\n", dev->htc_cnxt->block_sz, dev->ar->mbox_info.htc_addr); + /* usb doesn't support enabling interrupts */ + /* FIXME: remove check once USB support is implemented */ + if (dev->ar->hif_type == ATH6KL_HIF_TYPE_USB) + return 0; + status = ath6kl_hif_disable_intrs(dev); fail_setup: diff --git a/trunk/drivers/net/wireless/ath/ath6kl/htc_mbox.c b/trunk/drivers/net/wireless/ath/ath6kl/htc_mbox.c index fbb78dfe078f..cd0e1ba410d6 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/htc_mbox.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/htc_mbox.c @@ -2492,8 +2492,7 @@ static int ath6kl_htc_mbox_conn_service(struct htc_target *target, max_msg_sz = le16_to_cpu(resp_msg->max_msg_sz); } - if (WARN_ON_ONCE(assigned_ep == ENDPOINT_UNUSED || - assigned_ep >= ENDPOINT_MAX || !max_msg_sz)) { + if (assigned_ep >= ENDPOINT_MAX || !max_msg_sz) { status = -ENOMEM; goto fail_tx; } @@ -2656,6 +2655,12 @@ static int ath6kl_htc_mbox_wait_target(struct htc_target *target) struct htc_service_connect_resp resp; int status; + /* FIXME: remove once USB support is implemented */ + if (target->dev->ar->hif_type == ATH6KL_HIF_TYPE_USB) { + ath6kl_err("HTC doesn't support USB yet. Patience!\n"); + return -EOPNOTSUPP; + } + /* we should be getting 1 control message that the target is ready */ packet = htc_wait_for_ctrl_msg(target); @@ -2885,7 +2890,9 @@ static void ath6kl_htc_mbox_cleanup(struct htc_target *target) { struct htc_packet *packet, *tmp_packet; - ath6kl_hif_cleanup_scatter(target->dev->ar); + /* FIXME: remove check once USB support is implemented */ + if (target->dev->ar->hif_type != ATH6KL_HIF_TYPE_USB) + ath6kl_hif_cleanup_scatter(target->dev->ar); list_for_each_entry_safe(packet, tmp_packet, &target->free_ctrl_txbuf, list) { diff --git a/trunk/drivers/net/wireless/ath/ath6kl/htc_pipe.c b/trunk/drivers/net/wireless/ath/ath6kl/htc_pipe.c index ba6bd497b787..f9626c723693 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/htc_pipe.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/htc_pipe.c @@ -374,8 +374,9 @@ static enum htc_send_queue_result htc_try_send(struct htc_target *target, packet = list_first_entry(txq, struct htc_packet, list); - /* move to local queue */ - list_move_tail(&packet->list, &send_queue); + list_del(&packet->list); + /* insert into local queue */ + list_add_tail(&packet->list, &send_queue); } /* @@ -398,10 +399,11 @@ static enum htc_send_queue_result htc_try_send(struct htc_target *target, * for cleanup */ } else { /* callback wants to keep this packet, - * move from caller's queue to the send - * queue */ - list_move_tail(&packet->list, - &send_queue); + * remove from caller's queue */ + list_del(&packet->list); + /* put it in the send queue */ + list_add_tail(&packet->list, + &send_queue); } } diff --git a/trunk/drivers/net/wireless/ath/ath6kl/init.c b/trunk/drivers/net/wireless/ath/ath6kl/init.c index f21fa322e5ca..f90b5db741cf 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/init.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/init.c @@ -42,7 +42,7 @@ static const struct ath6kl_hw hw_list[] = { .reserved_ram_size = 6912, .refclk_hz = 26000000, .uarttx_pin = 8, - .flags = ATH6KL_HW_SDIO_CRC_ERROR_WAR, + .flags = 0, /* hw2.0 needs override address hardcoded */ .app_start_override_addr = 0x944C00, @@ -68,7 +68,7 @@ static const struct ath6kl_hw hw_list[] = { .refclk_hz = 26000000, .uarttx_pin = 8, .testscript_addr = 0x57ef74, - .flags = ATH6KL_HW_SDIO_CRC_ERROR_WAR, + .flags = 0, .fw = { .dir = AR6003_HW_2_1_1_FW_DIR, @@ -93,8 +93,7 @@ static const struct ath6kl_hw hw_list[] = { .board_addr = 0x433900, .refclk_hz = 26000000, .uarttx_pin = 11, - .flags = ATH6KL_HW_64BIT_RATES | - ATH6KL_HW_AP_INACTIVITY_MINS, + .flags = ATH6KL_HW_FLAG_64BIT_RATES, .fw = { .dir = AR6004_HW_1_0_FW_DIR, @@ -114,8 +113,8 @@ static const struct ath6kl_hw hw_list[] = { .board_addr = 0x43d400, .refclk_hz = 40000000, .uarttx_pin = 11, - .flags = ATH6KL_HW_64BIT_RATES | - ATH6KL_HW_AP_INACTIVITY_MINS, + .flags = ATH6KL_HW_FLAG_64BIT_RATES, + .fw = { .dir = AR6004_HW_1_1_FW_DIR, .fw = AR6004_HW_1_1_FIRMWARE_FILE, @@ -134,8 +133,7 @@ static const struct ath6kl_hw hw_list[] = { .board_addr = 0x435c00, .refclk_hz = 40000000, .uarttx_pin = 11, - .flags = ATH6KL_HW_64BIT_RATES | - ATH6KL_HW_AP_INACTIVITY_MINS, + .flags = ATH6KL_HW_FLAG_64BIT_RATES, .fw = { .dir = AR6004_HW_1_2_FW_DIR, @@ -144,28 +142,6 @@ static const struct ath6kl_hw hw_list[] = { .fw_board = AR6004_HW_1_2_BOARD_DATA_FILE, .fw_default_board = AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE, }, - { - .id = AR6004_HW_1_3_VERSION, - .name = "ar6004 hw 1.3", - .dataset_patch_addr = 0x437860, - .app_load_addr = 0x1234, - .board_ext_data_addr = 0x437000, - .reserved_ram_size = 7168, - .board_addr = 0x436400, - .refclk_hz = 40000000, - .uarttx_pin = 11, - .flags = ATH6KL_HW_64BIT_RATES | - ATH6KL_HW_AP_INACTIVITY_MINS | - ATH6KL_HW_MAP_LP_ENDPOINT, - - .fw = { - .dir = AR6004_HW_1_3_FW_DIR, - .fw = AR6004_HW_1_3_FIRMWARE_FILE, - }, - - .fw_board = AR6004_HW_1_3_BOARD_DATA_FILE, - .fw_default_board = AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE, - }, }; /* @@ -361,7 +337,7 @@ static int ath6kl_init_service_ep(struct ath6kl *ar) if (ath6kl_connectservice(ar, &connect, "WMI DATA BK")) return -EIO; - /* connect to Video service, map this to HI PRI */ + /* connect to Video service, map this to to HI PRI */ connect.svc_id = WMI_DATA_VI_SVC; if (ath6kl_connectservice(ar, &connect, "WMI DATA VI")) return -EIO; @@ -1112,12 +1088,6 @@ int ath6kl_init_fetch_firmwares(struct ath6kl *ar) if (ret) return ret; - ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API4_FILE); - if (ret == 0) { - ar->fw_api = 4; - goto out; - } - ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API3_FILE); if (ret == 0) { ar->fw_api = 3; @@ -1431,7 +1401,8 @@ static int ath6kl_init_upload(struct ath6kl *ar) return status; /* WAR to avoid SDIO CRC err */ - if (ar->hw.flags & ATH6KL_HW_SDIO_CRC_ERROR_WAR) { + if (ar->version.target_ver == AR6003_HW_2_0_VERSION || + ar->version.target_ver == AR6003_HW_2_1_1_VERSION) { ath6kl_err("temporary war to avoid sdio crc error\n"); param = 0x28; @@ -1549,7 +1520,7 @@ static const char *ath6kl_init_get_hif_name(enum ath6kl_hif_type type) return NULL; } -static int __ath6kl_init_hw_start(struct ath6kl *ar) +int ath6kl_init_hw_start(struct ath6kl *ar) { long timeleft; int ret, i; @@ -1645,6 +1616,8 @@ static int __ath6kl_init_hw_start(struct ath6kl *ar) goto err_htc_stop; } + ar->state = ATH6KL_STATE_ON; + return 0; err_htc_stop: @@ -1657,18 +1630,7 @@ static int __ath6kl_init_hw_start(struct ath6kl *ar) return ret; } -int ath6kl_init_hw_start(struct ath6kl *ar) -{ - int err; - - err = __ath6kl_init_hw_start(ar); - if (err) - return err; - ar->state = ATH6KL_STATE_ON; - return 0; -} - -static int __ath6kl_init_hw_stop(struct ath6kl *ar) +int ath6kl_init_hw_stop(struct ath6kl *ar) { int ret; @@ -1684,35 +1646,9 @@ static int __ath6kl_init_hw_stop(struct ath6kl *ar) if (ret) ath6kl_warn("failed to power off hif: %d\n", ret); - return 0; -} - -int ath6kl_init_hw_stop(struct ath6kl *ar) -{ - int err; - - err = __ath6kl_init_hw_stop(ar); - if (err) - return err; ar->state = ATH6KL_STATE_OFF; - return 0; -} -void ath6kl_init_hw_restart(struct ath6kl *ar) -{ - clear_bit(WMI_READY, &ar->flag); - - ath6kl_cfg80211_stop_all(ar); - - if (__ath6kl_init_hw_stop(ar)) { - ath6kl_dbg(ATH6KL_DBG_RECOVERY, "Failed to stop during fw error recovery\n"); - return; - } - - if (__ath6kl_init_hw_start(ar)) { - ath6kl_dbg(ATH6KL_DBG_RECOVERY, "Failed to restart during fw error recovery\n"); - return; - } + return 0; } /* FIXME: move this to cfg80211.c and rename to ath6kl_cfg80211_vif_stop() */ diff --git a/trunk/drivers/net/wireless/ath/ath6kl/main.c b/trunk/drivers/net/wireless/ath/ath6kl/main.c index bd50b6b7b492..c189e28e86a9 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/main.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/main.c @@ -293,17 +293,13 @@ int ath6kl_read_fwlogs(struct ath6kl *ar) } address = TARG_VTOP(ar->target_type, debug_hdr_addr); - ret = ath6kl_diag_read(ar, address, &debug_hdr, sizeof(debug_hdr)); - if (ret) - goto out; + ath6kl_diag_read(ar, address, &debug_hdr, sizeof(debug_hdr)); address = TARG_VTOP(ar->target_type, le32_to_cpu(debug_hdr.dbuf_addr)); firstbuf = address; dropped = le32_to_cpu(debug_hdr.dropped); - ret = ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf)); - if (ret) - goto out; + ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf)); loop = 100; @@ -326,8 +322,7 @@ int ath6kl_read_fwlogs(struct ath6kl *ar) address = TARG_VTOP(ar->target_type, le32_to_cpu(debug_buf.next)); - ret = ath6kl_diag_read(ar, address, &debug_buf, - sizeof(debug_buf)); + ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf)); if (ret) goto out; @@ -441,9 +436,12 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel) break; } - if (ar->last_ch != channel) + if (ar->want_ch_switch & (1 << vif->fw_vif_idx)) { + ar->want_ch_switch &= ~(1 << vif->fw_vif_idx); /* we actually don't know the phymode, default to HT20 */ - ath6kl_cfg80211_ch_switch_notify(vif, channel, WMI_11G_HT20); + ath6kl_cfg80211_ch_switch_notify(vif, channel, + WMI_11G_HT20); + } ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, NONE_BSS_FILTER, 0); set_bit(CONNECTED, &vif->flags); @@ -608,18 +606,6 @@ static int ath6kl_commit_ch_switch(struct ath6kl_vif *vif, u16 channel) switch (vif->nw_type) { case AP_NETWORK: - /* - * reconfigure any saved RSN IE capabilites in the beacon / - * probe response to stay in sync with the supplicant. - */ - if (vif->rsn_capab && - test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE, - ar->fw_capabilities)) - ath6kl_wmi_set_ie_cmd(ar->wmi, vif->fw_vif_idx, - WLAN_EID_RSN, WMI_RSN_IE_CAPB, - (const u8 *) &vif->rsn_capab, - sizeof(vif->rsn_capab)); - return ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &vif->profile); default: @@ -642,9 +628,6 @@ static void ath6kl_check_ch_switch(struct ath6kl *ar, u16 channel) if (ar->want_ch_switch & (1 << vif->fw_vif_idx)) res = ath6kl_commit_ch_switch(vif, channel); - /* if channel switch failed, oh well we tried */ - ar->want_ch_switch &= ~(1 << vif->fw_vif_idx); - if (res) ath6kl_err("channel switch failed nw_type %d res %d\n", vif->nw_type, res); @@ -998,25 +981,8 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid, if (vif->nw_type == AP_NETWORK) { /* disconnect due to other STA vif switching channels */ if (reason == BSS_DISCONNECTED && - prot_reason_status == WMI_AP_REASON_STA_ROAM) { + prot_reason_status == WMI_AP_REASON_STA_ROAM) ar->want_ch_switch |= 1 << vif->fw_vif_idx; - /* bail back to this channel if STA vif fails connect */ - ar->last_ch = le16_to_cpu(vif->profile.ch); - } - - if (prot_reason_status == WMI_AP_REASON_MAX_STA) { - /* send max client reached notification to user space */ - cfg80211_conn_failed(vif->ndev, bssid, - NL80211_CONN_FAIL_MAX_CLIENTS, - GFP_KERNEL); - } - - if (prot_reason_status == WMI_AP_REASON_ACL) { - /* send blocked client notification to user space */ - cfg80211_conn_failed(vif->ndev, bssid, - NL80211_CONN_FAIL_BLOCKED_CLIENT, - GFP_KERNEL); - } if (!ath6kl_remove_sta(ar, bssid, prot_reason_status)) return; @@ -1075,9 +1041,6 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid, } } - /* restart disconnected concurrent vifs waiting for new channel */ - ath6kl_check_ch_switch(ar, ar->last_ch); - /* update connect & link status atomically */ spin_lock_bh(&vif->if_lock); clear_bit(CONNECTED, &vif->flags); diff --git a/trunk/drivers/net/wireless/ath/ath6kl/recovery.c b/trunk/drivers/net/wireless/ath/ath6kl/recovery.c deleted file mode 100644 index 3a8d5e97dc8e..000000000000 --- a/trunk/drivers/net/wireless/ath/ath6kl/recovery.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (c) 2012 Qualcomm Atheros, Inc. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "core.h" -#include "cfg80211.h" -#include "debug.h" - -static void ath6kl_recovery_work(struct work_struct *work) -{ - struct ath6kl *ar = container_of(work, struct ath6kl, - fw_recovery.recovery_work); - - ar->state = ATH6KL_STATE_RECOVERY; - - del_timer_sync(&ar->fw_recovery.hb_timer); - - ath6kl_init_hw_restart(ar); - - ar->state = ATH6KL_STATE_ON; - clear_bit(WMI_CTRL_EP_FULL, &ar->flag); - - ar->fw_recovery.err_reason = 0; - - if (ar->fw_recovery.hb_poll) - mod_timer(&ar->fw_recovery.hb_timer, jiffies + - msecs_to_jiffies(ar->fw_recovery.hb_poll)); -} - -void ath6kl_recovery_err_notify(struct ath6kl *ar, enum ath6kl_fw_err reason) -{ - if (!ar->fw_recovery.enable) - return; - - ath6kl_dbg(ATH6KL_DBG_RECOVERY, "Fw error detected, reason:%d\n", - reason); - - set_bit(reason, &ar->fw_recovery.err_reason); - - if (!test_bit(RECOVERY_CLEANUP, &ar->flag) && - ar->state != ATH6KL_STATE_RECOVERY) - queue_work(ar->ath6kl_wq, &ar->fw_recovery.recovery_work); -} - -void ath6kl_recovery_hb_event(struct ath6kl *ar, u32 cookie) -{ - if (cookie == ar->fw_recovery.seq_num) - ar->fw_recovery.hb_pending = false; -} - -static void ath6kl_recovery_hb_timer(unsigned long data) -{ - struct ath6kl *ar = (struct ath6kl *) data; - int err; - - if (test_bit(RECOVERY_CLEANUP, &ar->flag) || - (ar->state == ATH6KL_STATE_RECOVERY)) - return; - - if (ar->fw_recovery.hb_pending) - ar->fw_recovery.hb_misscnt++; - else - ar->fw_recovery.hb_misscnt = 0; - - if (ar->fw_recovery.hb_misscnt > ATH6KL_HB_RESP_MISS_THRES) { - ar->fw_recovery.hb_misscnt = 0; - ar->fw_recovery.seq_num = 0; - ar->fw_recovery.hb_pending = false; - ath6kl_recovery_err_notify(ar, ATH6KL_FW_HB_RESP_FAILURE); - return; - } - - ar->fw_recovery.seq_num++; - ar->fw_recovery.hb_pending = true; - - err = ath6kl_wmi_get_challenge_resp_cmd(ar->wmi, - ar->fw_recovery.seq_num, 0); - if (err) - ath6kl_warn("Failed to send hb challenge request, err:%d\n", - err); - - mod_timer(&ar->fw_recovery.hb_timer, jiffies + - msecs_to_jiffies(ar->fw_recovery.hb_poll)); -} - -void ath6kl_recovery_init(struct ath6kl *ar) -{ - struct ath6kl_fw_recovery *recovery = &ar->fw_recovery; - - clear_bit(RECOVERY_CLEANUP, &ar->flag); - INIT_WORK(&recovery->recovery_work, ath6kl_recovery_work); - recovery->seq_num = 0; - recovery->hb_misscnt = 0; - ar->fw_recovery.hb_pending = false; - ar->fw_recovery.hb_timer.function = ath6kl_recovery_hb_timer; - ar->fw_recovery.hb_timer.data = (unsigned long) ar; - init_timer_deferrable(&ar->fw_recovery.hb_timer); - - if (ar->fw_recovery.hb_poll) - mod_timer(&ar->fw_recovery.hb_timer, jiffies + - msecs_to_jiffies(ar->fw_recovery.hb_poll)); -} - -void ath6kl_recovery_cleanup(struct ath6kl *ar) -{ - if (!ar->fw_recovery.enable) - return; - - set_bit(RECOVERY_CLEANUP, &ar->flag); - - del_timer_sync(&ar->fw_recovery.hb_timer); - cancel_work_sync(&ar->fw_recovery.recovery_work); -} - -void ath6kl_recovery_suspend(struct ath6kl *ar) -{ - if (!ar->fw_recovery.enable) - return; - - ath6kl_recovery_cleanup(ar); - - if (!ar->fw_recovery.err_reason) - return; - - /* Process pending fw error detection */ - ar->fw_recovery.err_reason = 0; - WARN_ON(ar->state != ATH6KL_STATE_ON); - ar->state = ATH6KL_STATE_RECOVERY; - ath6kl_init_hw_restart(ar); - ar->state = ATH6KL_STATE_ON; -} - -void ath6kl_recovery_resume(struct ath6kl *ar) -{ - if (!ar->fw_recovery.enable) - return; - - clear_bit(RECOVERY_CLEANUP, &ar->flag); - - if (!ar->fw_recovery.hb_poll) - return; - - ar->fw_recovery.hb_pending = false; - ar->fw_recovery.seq_num = 0; - ar->fw_recovery.hb_misscnt = 0; - mod_timer(&ar->fw_recovery.hb_timer, - jiffies + msecs_to_jiffies(ar->fw_recovery.hb_poll)); -} diff --git a/trunk/drivers/net/wireless/ath/ath6kl/sdio.c b/trunk/drivers/net/wireless/ath/ath6kl/sdio.c index d111980d44c0..05b95405f7b5 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/sdio.c @@ -709,7 +709,7 @@ static int ath6kl_sdio_enable_scatter(struct ath6kl *ar) { struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); struct htc_target *target = ar->htc_target; - int ret = 0; + int ret; bool virt_scat = false; if (ar_sdio->scatter_enabled) @@ -844,6 +844,22 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) bool try_deepsleep = false; int ret; + if (ar->state == ATH6KL_STATE_SCHED_SCAN) { + ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sched scan is in progress\n"); + + ret = ath6kl_set_sdio_pm_caps(ar); + if (ret) + goto cut_pwr; + + ret = ath6kl_cfg80211_suspend(ar, + ATH6KL_CFG_SUSPEND_SCHED_SCAN, + NULL); + if (ret) + goto cut_pwr; + + return 0; + } + if (ar->suspend_mode == WLAN_POWER_STATE_WOW || (!ar->suspend_mode && wow)) { @@ -926,13 +942,13 @@ static int ath6kl_sdio_resume(struct ath6kl *ar) case ATH6KL_STATE_WOW: break; - case ATH6KL_STATE_SUSPENDING: + case ATH6KL_STATE_SCHED_SCAN: break; - case ATH6KL_STATE_RESUMING: + case ATH6KL_STATE_SUSPENDING: break; - case ATH6KL_STATE_RECOVERY: + case ATH6KL_STATE_RESUMING: break; } @@ -1446,6 +1462,3 @@ MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE); MODULE_FIRMWARE(AR6004_HW_1_2_FW_DIR "/" AR6004_HW_1_2_FIRMWARE_FILE); MODULE_FIRMWARE(AR6004_HW_1_2_BOARD_DATA_FILE); MODULE_FIRMWARE(AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE); -MODULE_FIRMWARE(AR6004_HW_1_3_FW_DIR "/" AR6004_HW_1_3_FIRMWARE_FILE); -MODULE_FIRMWARE(AR6004_HW_1_3_BOARD_DATA_FILE); -MODULE_FIRMWARE(AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE); diff --git a/trunk/drivers/net/wireless/ath/ath6kl/txrx.c b/trunk/drivers/net/wireless/ath/ath6kl/txrx.c index 78b369286579..7dfa0fd86d7b 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/txrx.c @@ -288,16 +288,8 @@ int ath6kl_control_tx(void *devt, struct sk_buff *skb, int status = 0; struct ath6kl_cookie *cookie = NULL; - if (WARN_ON_ONCE(ar->state == ATH6KL_STATE_WOW)) { - dev_kfree_skb(skb); + if (WARN_ON_ONCE(ar->state == ATH6KL_STATE_WOW)) return -EACCES; - } - - if (WARN_ON_ONCE(eid == ENDPOINT_UNUSED || - eid >= ENDPOINT_MAX)) { - status = -EINVAL; - goto fail_ctrl_tx; - } spin_lock_bh(&ar->lock); @@ -599,7 +591,6 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target, */ set_bit(WMI_CTRL_EP_FULL, &ar->flag); ath6kl_err("wmi ctrl ep is full\n"); - ath6kl_recovery_err_notify(ar, ATH6KL_FW_EP_FULL); return action; } @@ -704,31 +695,22 @@ void ath6kl_tx_complete(struct htc_target *target, list); list_del(&packet->list); - if (WARN_ON_ONCE(packet->endpoint == ENDPOINT_UNUSED || - packet->endpoint >= ENDPOINT_MAX)) - continue; - ath6kl_cookie = (struct ath6kl_cookie *)packet->pkt_cntxt; - if (WARN_ON_ONCE(!ath6kl_cookie)) - continue; + if (!ath6kl_cookie) + goto fatal; status = packet->status; skb = ath6kl_cookie->skb; eid = packet->endpoint; map_no = ath6kl_cookie->map_no; - if (WARN_ON_ONCE(!skb || !skb->data)) { - dev_kfree_skb(skb); - ath6kl_free_cookie(ar, ath6kl_cookie); - continue; - } + if (!skb || !skb->data) + goto fatal; __skb_queue_tail(&skb_queue, skb); - if (WARN_ON_ONCE(!status && (packet->act_len != skb->len))) { - ath6kl_free_cookie(ar, ath6kl_cookie); - continue; - } + if (!status && (packet->act_len != skb->len)) + goto fatal; ar->tx_pending[eid]--; @@ -810,6 +792,11 @@ void ath6kl_tx_complete(struct htc_target *target, wake_up(&ar->event_wq); return; + +fatal: + WARN_ON(1); + spin_unlock_bh(&ar->lock); + return; } void ath6kl_tx_data_cleanup(struct ath6kl *ar) @@ -898,11 +885,8 @@ void ath6kl_rx_refill(struct htc_target *target, enum htc_endpoint_id endpoint) break; packet = (struct htc_packet *) skb->head; - if (!IS_ALIGNED((unsigned long) skb->data, 4)) { - size_t len = skb_headlen(skb); + if (!IS_ALIGNED((unsigned long) skb->data, 4)) skb->data = PTR_ALIGN(skb->data - 4, 4); - skb_set_tail_pointer(skb, len); - } set_htc_rxpkt_info(packet, skb, skb->data, ATH6KL_BUFFER_SIZE, endpoint); packet->skb = skb; @@ -924,11 +908,8 @@ void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count) return; packet = (struct htc_packet *) skb->head; - if (!IS_ALIGNED((unsigned long) skb->data, 4)) { - size_t len = skb_headlen(skb); + if (!IS_ALIGNED((unsigned long) skb->data, 4)) skb->data = PTR_ALIGN(skb->data - 4, 4); - skb_set_tail_pointer(skb, len); - } set_htc_rxpkt_info(packet, skb, skb->data, ATH6KL_AMSDU_BUFFER_SIZE, 0); packet->skb = skb; diff --git a/trunk/drivers/net/wireless/ath/ath6kl/usb.c b/trunk/drivers/net/wireless/ath/ath6kl/usb.c index 62bcc0d5bc23..3740c3d6ab88 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/usb.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/usb.c @@ -185,10 +185,9 @@ static int ath6kl_usb_alloc_pipe_resources(struct ath6kl_usb_pipe *pipe, for (i = 0; i < urb_cnt; i++) { urb_context = kzalloc(sizeof(struct ath6kl_urb_context), GFP_KERNEL); - if (urb_context == NULL) { - status = -ENOMEM; - goto fail_alloc_pipe_resources; - } + if (urb_context == NULL) + /* FIXME: set status to -ENOMEM */ + break; urb_context->pipe = pipe; @@ -205,7 +204,6 @@ static int ath6kl_usb_alloc_pipe_resources(struct ath6kl_usb_pipe *pipe, pipe->logical_pipe_num, pipe->usb_pipe_handle, pipe->urb_alloc); -fail_alloc_pipe_resources: return status; } @@ -805,11 +803,7 @@ static int ath6kl_usb_map_service_pipe(struct ath6kl *ar, u16 svc_id, *dl_pipe = ATH6KL_USB_PIPE_RX_DATA; break; case WMI_DATA_VI_SVC: - - if (ar->hw.flags & ATH6KL_HW_MAP_LP_ENDPOINT) - *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_LP; - else - *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_MP; + *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_MP; /* * Disable rxdata2 directly, it will be enabled * if FW enable rxdata2 @@ -817,11 +811,7 @@ static int ath6kl_usb_map_service_pipe(struct ath6kl *ar, u16 svc_id, *dl_pipe = ATH6KL_USB_PIPE_RX_DATA; break; case WMI_DATA_VO_SVC: - - if (ar->hw.flags & ATH6KL_HW_MAP_LP_ENDPOINT) - *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_LP; - else - *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_MP; + *ul_pipe = ATH6KL_USB_PIPE_TX_DATA_HP; /* * Disable rxdata2 directly, it will be enabled * if FW enable rxdata2 @@ -1206,14 +1196,7 @@ static struct usb_driver ath6kl_usb_driver = { static int ath6kl_usb_init(void) { - int ret; - - ret = usb_register(&ath6kl_usb_driver); - if (ret) { - ath6kl_err("usb registration failed: %d\n", ret); - return ret; - } - + usb_register(&ath6kl_usb_driver); return 0; } @@ -1237,6 +1220,3 @@ MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE); MODULE_FIRMWARE(AR6004_HW_1_2_FIRMWARE_FILE); MODULE_FIRMWARE(AR6004_HW_1_2_BOARD_DATA_FILE); MODULE_FIRMWARE(AR6004_HW_1_2_DEFAULT_BOARD_DATA_FILE); -MODULE_FIRMWARE(AR6004_HW_1_3_FW_DIR "/" AR6004_HW_1_3_FIRMWARE_FILE); -MODULE_FIRMWARE(AR6004_HW_1_3_BOARD_DATA_FILE); -MODULE_FIRMWARE(AR6004_HW_1_3_DEFAULT_BOARD_DATA_FILE); diff --git a/trunk/drivers/net/wireless/ath/ath6kl/wmi.c b/trunk/drivers/net/wireless/ath/ath6kl/wmi.c index 998f8b0f62fd..0e05c41cdcfc 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/wmi.c @@ -935,12 +935,8 @@ static void ath6kl_wmi_regdomain_event(struct wmi *wmi, u8 *datap, int len) regpair = ath6kl_get_regpair((u16) reg_code); country = ath6kl_regd_find_country_by_rd((u16) reg_code); - if (regpair) - ath6kl_dbg(ATH6KL_DBG_WMI, "Regpair used: 0x%0x\n", - regpair->regDmnEnum); - else - ath6kl_warn("Regpair not found reg_code 0x%0x\n", - reg_code); + ath6kl_dbg(ATH6KL_DBG_WMI, "Regpair used: 0x%0x\n", + regpair->regDmnEnum); } if (country && wmi->parent_dev->wiphy_registered) { @@ -1119,7 +1115,7 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len, * the timer would not ever fire if the scan interval is short * enough. */ - if (test_bit(SCHED_SCANNING, &vif->flags) && + if (ar->state == ATH6KL_STATE_SCHED_SCAN && !timer_pending(&vif->sched_scan_timer)) { mod_timer(&vif->sched_scan_timer, jiffies + msecs_to_jiffies(ATH6KL_SCHED_SCAN_RESULT_DELAY)); @@ -1173,9 +1169,6 @@ static int ath6kl_wmi_bitrate_reply_rx(struct wmi *wmi, u8 *datap, int len) rate = RATE_AUTO; } else { index = reply->rate_index & 0x7f; - if (WARN_ON_ONCE(index > (RATE_MCS_7_40 + 1))) - return -EINVAL; - sgi = (reply->rate_index & 0x80) ? 1 : 0; rate = wmi_rate_tbl[index][sgi]; } @@ -1537,68 +1530,6 @@ static int ath6kl_wmi_cac_event_rx(struct wmi *wmi, u8 *datap, int len, return 0; } -static int ath6kl_wmi_txe_notify_event_rx(struct wmi *wmi, u8 *datap, int len, - struct ath6kl_vif *vif) -{ - struct wmi_txe_notify_event *ev; - u32 rate, pkts; - - if (len < sizeof(*ev)) - return -EINVAL; - - if (vif->sme_state != SME_CONNECTED) - return -ENOTCONN; - - ev = (struct wmi_txe_notify_event *) datap; - rate = le32_to_cpu(ev->rate); - pkts = le32_to_cpu(ev->pkts); - - ath6kl_dbg(ATH6KL_DBG_WMI, "TXE notify event: peer %pM rate %d% pkts %d intvl %ds\n", - vif->bssid, rate, pkts, vif->txe_intvl); - - cfg80211_cqm_txe_notify(vif->ndev, vif->bssid, pkts, - rate, vif->txe_intvl, GFP_KERNEL); - - return 0; -} - -int ath6kl_wmi_set_txe_notify(struct wmi *wmi, u8 idx, - u32 rate, u32 pkts, u32 intvl) -{ - struct sk_buff *skb; - struct wmi_txe_notify_cmd *cmd; - - skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); - if (!skb) - return -ENOMEM; - - cmd = (struct wmi_txe_notify_cmd *) skb->data; - cmd->rate = cpu_to_le32(rate); - cmd->pkts = cpu_to_le32(pkts); - cmd->intvl = cpu_to_le32(intvl); - - return ath6kl_wmi_cmd_send(wmi, idx, skb, WMI_SET_TXE_NOTIFY_CMDID, - NO_SYNC_WMIFLAG); -} - -int ath6kl_wmi_set_rssi_filter_cmd(struct wmi *wmi, u8 if_idx, s8 rssi) -{ - struct sk_buff *skb; - struct wmi_set_rssi_filter_cmd *cmd; - int ret; - - skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); - if (!skb) - return -ENOMEM; - - cmd = (struct wmi_set_rssi_filter_cmd *) skb->data; - cmd->rssi = rssi; - - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_RSSI_FILTER_CMDID, - NO_SYNC_WMIFLAG); - return ret; -} - static int ath6kl_wmi_send_snr_threshold_params(struct wmi *wmi, struct wmi_snr_threshold_params_cmd *snr_cmd) { @@ -1745,11 +1676,8 @@ int ath6kl_wmi_cmd_send(struct wmi *wmi, u8 if_idx, struct sk_buff *skb, int ret; u16 info1; - if (WARN_ON(skb == NULL || - (if_idx > (wmi->parent_dev->vif_max - 1)))) { - dev_kfree_skb(skb); + if (WARN_ON(skb == NULL || (if_idx > (wmi->parent_dev->vif_max - 1)))) return -EINVAL; - } ath6kl_dbg(ATH6KL_DBG_WMI, "wmi tx id %d len %d flag %d\n", cmd_id, skb->len, sync_flag); @@ -1904,59 +1832,6 @@ int ath6kl_wmi_disconnect_cmd(struct wmi *wmi, u8 if_idx) return ret; } -/* ath6kl_wmi_start_scan_cmd is to be deprecated. Use - * ath6kl_wmi_begin_scan_cmd instead. The new function supports P2P - * mgmt operations using station interface. - */ -static int ath6kl_wmi_startscan_cmd(struct wmi *wmi, u8 if_idx, - enum wmi_scan_type scan_type, - u32 force_fgscan, u32 is_legacy, - u32 home_dwell_time, - u32 force_scan_interval, - s8 num_chan, u16 *ch_list) -{ - struct sk_buff *skb; - struct wmi_start_scan_cmd *sc; - s8 size; - int i, ret; - - size = sizeof(struct wmi_start_scan_cmd); - - if ((scan_type != WMI_LONG_SCAN) && (scan_type != WMI_SHORT_SCAN)) - return -EINVAL; - - if (num_chan > WMI_MAX_CHANNELS) - return -EINVAL; - - if (num_chan) - size += sizeof(u16) * (num_chan - 1); - - skb = ath6kl_wmi_get_new_buf(size); - if (!skb) - return -ENOMEM; - - sc = (struct wmi_start_scan_cmd *) skb->data; - sc->scan_type = scan_type; - sc->force_fg_scan = cpu_to_le32(force_fgscan); - sc->is_legacy = cpu_to_le32(is_legacy); - sc->home_dwell_time = cpu_to_le32(home_dwell_time); - sc->force_scan_intvl = cpu_to_le32(force_scan_interval); - sc->num_ch = num_chan; - - for (i = 0; i < num_chan; i++) - sc->ch_list[i] = cpu_to_le16(ch_list[i]); - - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_START_SCAN_CMDID, - NO_SYNC_WMIFLAG); - - return ret; -} - -/* - * beginscan supports (compared to old startscan) P2P mgmt operations using - * station interface, send additional information like supported rates to - * advertise and xmit rates for probe requests - */ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx, enum wmi_scan_type scan_type, u32 force_fgscan, u32 is_legacy, @@ -1972,15 +1847,6 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx, int num_rates; u32 ratemask; - if (!test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX, - ar->fw_capabilities)) { - return ath6kl_wmi_startscan_cmd(wmi, if_idx, - scan_type, force_fgscan, - is_legacy, home_dwell_time, - force_scan_interval, - num_chan, ch_list); - } - size = sizeof(struct wmi_begin_scan_cmd); if ((scan_type != WMI_LONG_SCAN) && (scan_type != WMI_SHORT_SCAN)) @@ -2033,24 +1899,50 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx, return ret; } -int ath6kl_wmi_enable_sched_scan_cmd(struct wmi *wmi, u8 if_idx, bool enable) +/* ath6kl_wmi_start_scan_cmd is to be deprecated. Use + * ath6kl_wmi_begin_scan_cmd instead. The new function supports P2P + * mgmt operations using station interface. + */ +int ath6kl_wmi_startscan_cmd(struct wmi *wmi, u8 if_idx, + enum wmi_scan_type scan_type, + u32 force_fgscan, u32 is_legacy, + u32 home_dwell_time, u32 force_scan_interval, + s8 num_chan, u16 *ch_list) { struct sk_buff *skb; - struct wmi_enable_sched_scan_cmd *sc; - int ret; + struct wmi_start_scan_cmd *sc; + s8 size; + int i, ret; - skb = ath6kl_wmi_get_new_buf(sizeof(*sc)); + size = sizeof(struct wmi_start_scan_cmd); + + if ((scan_type != WMI_LONG_SCAN) && (scan_type != WMI_SHORT_SCAN)) + return -EINVAL; + + if (num_chan > WMI_MAX_CHANNELS) + return -EINVAL; + + if (num_chan) + size += sizeof(u16) * (num_chan - 1); + + skb = ath6kl_wmi_get_new_buf(size); if (!skb) return -ENOMEM; - ath6kl_dbg(ATH6KL_DBG_WMI, "%s scheduled scan on vif %d\n", - enable ? "enabling" : "disabling", if_idx); - sc = (struct wmi_enable_sched_scan_cmd *) skb->data; - sc->enable = enable ? 1 : 0; + sc = (struct wmi_start_scan_cmd *) skb->data; + sc->scan_type = scan_type; + sc->force_fg_scan = cpu_to_le32(force_fgscan); + sc->is_legacy = cpu_to_le32(is_legacy); + sc->home_dwell_time = cpu_to_le32(home_dwell_time); + sc->force_scan_intvl = cpu_to_le32(force_scan_interval); + sc->num_ch = num_chan; - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, - WMI_ENABLE_SCHED_SCAN_CMDID, + for (i = 0; i < num_chan; i++) + sc->ch_list[i] = cpu_to_le16(ch_list[i]); + + ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_START_SCAN_CMDID, NO_SYNC_WMIFLAG); + return ret; } @@ -2382,10 +2274,8 @@ static int ath6kl_wmi_data_sync_send(struct wmi *wmi, struct sk_buff *skb, struct wmi_data_hdr *data_hdr; int ret; - if (WARN_ON(skb == NULL || ep_id == wmi->ep_id)) { - dev_kfree_skb(skb); + if (WARN_ON(skb == NULL || ep_id == wmi->ep_id)) return -EINVAL; - } skb_push(skb, sizeof(struct wmi_data_hdr)); @@ -2422,8 +2312,10 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx) spin_unlock_bh(&wmi->lock); skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); - if (!skb) - return -ENOMEM; + if (!skb) { + ret = -ENOMEM; + goto free_skb; + } cmd = (struct wmi_sync_cmd *) skb->data; @@ -2446,7 +2338,7 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx) * then do not send the Synchronize cmd on the control ep */ if (ret) - goto free_cmd_skb; + goto free_skb; /* * Send sync cmd followed by sync data messages on all @@ -2456,12 +2348,15 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx) NO_SYNC_WMIFLAG); if (ret) - goto free_data_skb; + goto free_skb; + + /* cmd buffer sent, we no longer own it */ + skb = NULL; for (index = 0; index < num_pri_streams; index++) { if (WARN_ON(!data_sync_bufs[index].skb)) - goto free_data_skb; + break; ep_id = ath6kl_ac2_endpoint_id(wmi->parent_dev, data_sync_bufs[index]. @@ -2470,20 +2365,17 @@ static int ath6kl_wmi_sync_point(struct wmi *wmi, u8 if_idx) ath6kl_wmi_data_sync_send(wmi, data_sync_bufs[index].skb, ep_id, if_idx); - data_sync_bufs[index].skb = NULL; - if (ret) - goto free_data_skb; - } + break; - return 0; + data_sync_bufs[index].skb = NULL; + } -free_cmd_skb: +free_skb: /* free up any resources left over (possibly due to an error) */ if (skb) dev_kfree_skb(skb); -free_data_skb: for (index = 0; index < num_pri_streams; index++) { if (data_sync_bufs[index].skb != NULL) { dev_kfree_skb((struct sk_buff *)data_sync_bufs[index]. @@ -2725,13 +2617,11 @@ static int ath6kl_set_bitrate_mask64(struct wmi *wmi, u8 if_idx, { struct sk_buff *skb; int ret, mode, band; - u64 mcsrate, ratemask[ATH6KL_NUM_BANDS]; + u64 mcsrate, ratemask[IEEE80211_NUM_BANDS]; struct wmi_set_tx_select_rates64_cmd *cmd; memset(&ratemask, 0, sizeof(ratemask)); - - /* only check 2.4 and 5 GHz bands, skip the rest */ - for (band = 0; band <= IEEE80211_BAND_5GHZ; band++) { + for (band = 0; band < IEEE80211_NUM_BANDS; band++) { /* copy legacy rate mask */ ratemask[band] = mask->control[band].legacy; if (band == IEEE80211_BAND_5GHZ) @@ -2777,13 +2667,11 @@ static int ath6kl_set_bitrate_mask32(struct wmi *wmi, u8 if_idx, { struct sk_buff *skb; int ret, mode, band; - u32 mcsrate, ratemask[ATH6KL_NUM_BANDS]; + u32 mcsrate, ratemask[IEEE80211_NUM_BANDS]; struct wmi_set_tx_select_rates32_cmd *cmd; memset(&ratemask, 0, sizeof(ratemask)); - - /* only check 2.4 and 5 GHz bands, skip the rest */ - for (band = 0; band <= IEEE80211_BAND_5GHZ; band++) { + for (band = 0; band < IEEE80211_NUM_BANDS; band++) { /* copy legacy rate mask */ ratemask[band] = mask->control[band].legacy; if (band == IEEE80211_BAND_5GHZ) @@ -2827,7 +2715,7 @@ int ath6kl_wmi_set_bitrate_mask(struct wmi *wmi, u8 if_idx, { struct ath6kl *ar = wmi->parent_dev; - if (ar->hw.flags & ATH6KL_HW_64BIT_RATES) + if (ar->hw.flags & ATH6KL_HW_FLAG_64BIT_RATES) return ath6kl_set_bitrate_mask64(wmi, if_idx, mask); else return ath6kl_set_bitrate_mask32(wmi, if_idx, mask); @@ -3250,40 +3138,12 @@ int ath6kl_wmi_sta_bmiss_enhance_cmd(struct wmi *wmi, u8 if_idx, bool enhance) return ret; } -int ath6kl_wmi_set_regdomain_cmd(struct wmi *wmi, const char *alpha2) -{ - struct sk_buff *skb; - struct wmi_set_regdomain_cmd *cmd; - - skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); - if (!skb) - return -ENOMEM; - - cmd = (struct wmi_set_regdomain_cmd *) skb->data; - memcpy(cmd->iso_name, alpha2, 2); - - return ath6kl_wmi_cmd_send(wmi, 0, skb, - WMI_SET_REGDOMAIN_CMDID, - NO_SYNC_WMIFLAG); -} - s32 ath6kl_wmi_get_rate(s8 rate_index) { - u8 sgi = 0; - if (rate_index == RATE_AUTO) return 0; - /* SGI is stored as the MSB of the rate_index */ - if (rate_index & RATE_INDEX_MSB) { - rate_index &= RATE_INDEX_WITHOUT_SGI_MASK; - sgi = 1; - } - - if (WARN_ON(rate_index > RATE_MCS_7_40)) - rate_index = RATE_MCS_7_40; - - return wmi_rate_tbl[(u32) rate_index][sgi]; + return wmi_rate_tbl[(u32) rate_index][0]; } static int ath6kl_wmi_get_pmkid_list_event_rx(struct wmi *wmi, u8 *datap, @@ -3773,19 +3633,6 @@ int ath6kl_wmi_set_inact_period(struct wmi *wmi, u8 if_idx, int inact_timeout) NO_SYNC_WMIFLAG); } -static void ath6kl_wmi_hb_challenge_resp_event(struct wmi *wmi, u8 *datap, - int len) -{ - struct wmix_hb_challenge_resp_cmd *cmd; - - if (len < sizeof(struct wmix_hb_challenge_resp_cmd)) - return; - - cmd = (struct wmix_hb_challenge_resp_cmd *) datap; - ath6kl_recovery_hb_event(wmi->parent_dev, - le32_to_cpu(cmd->cookie)); -} - static int ath6kl_wmi_control_rx_xtnd(struct wmi *wmi, struct sk_buff *skb) { struct wmix_cmd_hdr *cmd; @@ -3810,7 +3657,6 @@ static int ath6kl_wmi_control_rx_xtnd(struct wmi *wmi, struct sk_buff *skb) switch (id) { case WMIX_HB_CHALLENGE_RESP_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "wmi event hb challenge resp\n"); - ath6kl_wmi_hb_challenge_resp_event(wmi, datap, len); break; case WMIX_DBGLOG_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "wmi event dbglog len %d\n", len); @@ -3903,9 +3749,6 @@ static int ath6kl_wmi_proc_events_vif(struct wmi *wmi, u16 if_idx, u16 cmd_id, case WMI_RX_ACTION_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RX_ACTION_EVENTID\n"); return ath6kl_wmi_rx_action_event_rx(wmi, datap, len, vif); - case WMI_TXE_NOTIFY_EVENTID: - ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TXE_NOTIFY_EVENTID\n"); - return ath6kl_wmi_txe_notify_event_rx(wmi, datap, len, vif); default: ath6kl_dbg(ATH6KL_DBG_WMI, "unknown cmd id 0x%x\n", cmd_id); return -EINVAL; diff --git a/trunk/drivers/net/wireless/ath/ath6kl/wmi.h b/trunk/drivers/net/wireless/ath/ath6kl/wmi.h index 98b1755e67f4..43339aca585d 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/trunk/drivers/net/wireless/ath/ath6kl/wmi.h @@ -48,7 +48,7 @@ #define A_BAND_24GHZ 0 #define A_BAND_5GHZ 1 -#define ATH6KL_NUM_BANDS 2 +#define A_NUM_BANDS 2 /* in ms */ #define WMI_IMPLICIT_PSTREAM_INACTIVITY_INT 5000 @@ -628,20 +628,6 @@ enum wmi_cmd_id { WMI_SET_MCASTRATE, WMI_STA_BMISS_ENHANCE_CMDID, - - WMI_SET_REGDOMAIN_CMDID, - - WMI_SET_RSSI_FILTER_CMDID, - - WMI_SET_KEEP_ALIVE_EXT, - - WMI_VOICE_DETECTION_ENABLE_CMDID, - - WMI_SET_TXE_NOTIFY_CMDID, - - WMI_SET_RECOVERY_TEST_PARAMETER_CMDID, /*0xf094*/ - - WMI_ENABLE_SCHED_SCAN_CMDID, }; enum wmi_mgmt_frame_type { @@ -857,7 +843,7 @@ struct wmi_begin_scan_cmd { u8 scan_type; /* Supported rates to advertise in the probe request frames */ - struct wmi_supp_rates supp_rates[ATH6KL_NUM_BANDS]; + struct wmi_supp_rates supp_rates[IEEE80211_NUM_BANDS]; /* how many channels follow */ u8 num_ch; @@ -955,11 +941,6 @@ struct wmi_scan_params_cmd { __le32 max_dfsch_act_time; } __packed; -/* WMI_ENABLE_SCHED_SCAN_CMDID */ -struct wmi_enable_sched_scan_cmd { - u8 enable; -} __packed; - /* WMI_SET_BSS_FILTER_CMDID */ enum wmi_bss_filter { /* no beacons forwarded */ @@ -1051,11 +1032,6 @@ struct wmi_sta_bmiss_enhance_cmd { u8 enable; } __packed; -struct wmi_set_regdomain_cmd { - u8 length; - u8 iso_name[2]; -} __packed; - /* WMI_SET_POWER_MODE_CMDID */ enum wmi_power_mode { REC_POWER = 0x01, @@ -1300,11 +1276,6 @@ struct wmi_snr_threshold_params_cmd { u8 reserved[3]; } __packed; -/* Don't report BSSs with signal (RSSI) below this threshold */ -struct wmi_set_rssi_filter_cmd { - s8 rssi; -} __packed; - enum wmi_preamble_policy { WMI_IGNORE_BARKER_IN_ERP = 0, WMI_FOLLOW_BARKER_IN_ERP, @@ -1484,20 +1455,6 @@ enum wmi_event_id { WMI_P2P_CAPABILITIES_EVENTID, WMI_RX_ACTION_EVENTID, WMI_P2P_INFO_EVENTID, - - /* WPS Events */ - WMI_WPS_GET_STATUS_EVENTID, - WMI_WPS_PROFILE_EVENTID, - - /* more P2P events */ - WMI_NOA_INFO_EVENTID, - WMI_OPPPS_INFO_EVENTID, - WMI_PORT_STATUS_EVENTID, - - /* 802.11w */ - WMI_GET_RSN_CAP_EVENTID, - - WMI_TXE_NOTIFY_EVENTID, }; struct wmi_ready_event_2 { @@ -1792,9 +1749,6 @@ struct rx_stats { a_sle32 ucast_rate; } __packed; -#define RATE_INDEX_WITHOUT_SGI_MASK 0x7f -#define RATE_INDEX_MSB 0x80 - struct tkip_ccmp_stats { __le32 tkip_local_mic_fail; __le32 tkip_cnter_measures_invoked; @@ -2065,6 +2019,7 @@ struct wmi_set_ie_cmd { #define WOW_MAX_FILTERS_PER_LIST 4 #define WOW_PATTERN_SIZE 64 +#define WOW_MASK_SIZE 64 #define MAC_MAX_FILTERS_PER_LIST 4 @@ -2073,7 +2028,7 @@ struct wow_filter { u8 wow_filter_id; u8 wow_filter_size; u8 wow_filter_offset; - u8 wow_filter_mask[WOW_PATTERN_SIZE]; + u8 wow_filter_mask[WOW_MASK_SIZE]; u8 wow_filter_pattern[WOW_PATTERN_SIZE]; } __packed; @@ -2132,19 +2087,6 @@ struct wmi_del_wow_pattern_cmd { __le16 filter_id; } __packed; -/* WMI_SET_TXE_NOTIFY_CMDID */ -struct wmi_txe_notify_cmd { - __le32 rate; - __le32 pkts; - __le32 intvl; -} __packed; - -/* WMI_TXE_NOTIFY_EVENTID */ -struct wmi_txe_notify_event { - __le32 rate; - __le32 pkts; -} __packed; - /* WMI_SET_AKMP_PARAMS_CMD */ struct wmi_pmkid { @@ -2563,6 +2505,11 @@ int ath6kl_wmi_connect_cmd(struct wmi *wmi, u8 if_idx, int ath6kl_wmi_reconnect_cmd(struct wmi *wmi, u8 if_idx, u8 *bssid, u16 channel); int ath6kl_wmi_disconnect_cmd(struct wmi *wmi, u8 if_idx); +int ath6kl_wmi_startscan_cmd(struct wmi *wmi, u8 if_idx, + enum wmi_scan_type scan_type, + u32 force_fgscan, u32 is_legacy, + u32 home_dwell_time, u32 force_scan_interval, + s8 num_chan, u16 *ch_list); int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx, enum wmi_scan_type scan_type, @@ -2570,7 +2517,6 @@ int ath6kl_wmi_beginscan_cmd(struct wmi *wmi, u8 if_idx, u32 home_dwell_time, u32 force_scan_interval, s8 num_chan, u16 *ch_list, u32 no_cck, u32 *rates); -int ath6kl_wmi_enable_sched_scan_cmd(struct wmi *wmi, u8 if_idx, bool enable); int ath6kl_wmi_scanparams_cmd(struct wmi *wmi, u8 if_idx, u16 fg_start_sec, u16 fg_end_sec, u16 bg_sec, @@ -2646,7 +2592,6 @@ int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, const u8 *mask); int ath6kl_wmi_del_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, u16 list_id, u16 filter_id); -int ath6kl_wmi_set_rssi_filter_cmd(struct wmi *wmi, u8 if_idx, s8 rssi); int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi); int ath6kl_wmi_ap_set_dtim_cmd(struct wmi *wmi, u8 if_idx, u32 dtim_period); int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid); @@ -2655,9 +2600,6 @@ int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on); int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, u8 *filter, bool add_filter); int ath6kl_wmi_sta_bmiss_enhance_cmd(struct wmi *wmi, u8 if_idx, bool enable); -int ath6kl_wmi_set_txe_notify(struct wmi *wmi, u8 idx, - u32 rate, u32 pkts, u32 intvl); -int ath6kl_wmi_set_regdomain_cmd(struct wmi *wmi, const char *alpha2); /* AP mode uAPSD */ int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable); @@ -2716,8 +2658,6 @@ int ath6kl_wmi_set_inact_period(struct wmi *wmi, u8 if_idx, int inact_timeout); void ath6kl_wmi_sscan_timer(unsigned long ptr); -int ath6kl_wmi_get_challenge_resp_cmd(struct wmi *wmi, u32 cookie, u32 source); - struct ath6kl_vif *ath6kl_get_vif_by_index(struct ath6kl *ar, u8 if_idx); void *ath6kl_wmi_init(struct ath6kl *devt); void ath6kl_wmi_shutdown(struct wmi *wmi); diff --git a/trunk/drivers/net/wireless/ath/ath9k/Kconfig b/trunk/drivers/net/wireless/ath/ath9k/Kconfig index 5fc15bf8be09..c7aa6646123e 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/Kconfig +++ b/trunk/drivers/net/wireless/ath/ath9k/Kconfig @@ -17,7 +17,6 @@ config ATH9K_BTCOEX_SUPPORT config ATH9K tristate "Atheros 802.11n wireless cards support" depends on MAC80211 - select ATH_COMMON select ATH9K_HW select MAC80211_LEDS select LEDS_CLASS diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 8b0d8dcd7625..162401f22f8c 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -891,74 +891,6 @@ static void ar9003_hw_tx_iq_cal_reload(struct ath_hw *ah) AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1); } -static void ar9003_hw_manual_peak_cal(struct ath_hw *ah, u8 chain, bool is_2g) -{ - int offset[8], total = 0, test; - int agc_out, i; - - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain), - AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE, 0x1); - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain), - AR_PHY_65NM_RXRF_GAINSTAGES_LNAON_CALDC, 0x0); - if (is_2g) - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain), - AR_PHY_65NM_RXRF_GAINSTAGES_LNA2G_GAIN_OVR, 0x0); - else - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain), - AR_PHY_65NM_RXRF_GAINSTAGES_LNA5G_GAIN_OVR, 0x0); - - REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain), - AR_PHY_65NM_RXTX2_RXON_OVR, 0x1); - REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain), - AR_PHY_65NM_RXTX2_RXON, 0x0); - - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), - AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE, 0x1); - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), - AR_PHY_65NM_RXRF_AGC_AGC_ON_OVR, 0x1); - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), - AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0x1); - if (is_2g) - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), - AR_PHY_65NM_RXRF_AGC_AGC2G_DBDAC_OVR, 0x0); - else - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), - AR_PHY_65NM_RXRF_AGC_AGC5G_DBDAC_OVR, 0x0); - - for (i = 6; i > 0; i--) { - offset[i] = BIT(i - 1); - test = total + offset[i]; - - if (is_2g) - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), - AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR, - test); - else - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), - AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR, - test); - udelay(100); - agc_out = REG_READ_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), - AR_PHY_65NM_RXRF_AGC_AGC_OUT); - offset[i] = (agc_out) ? 0 : 1; - total += (offset[i] << (i - 1)); - } - - if (is_2g) - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), - AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR, total); - else - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), - AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR, total); - - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_GAINSTAGES(chain), - AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE, 0); - REG_RMW_FIELD(ah, AR_PHY_65NM_RXTX2(chain), - AR_PHY_65NM_RXTX2_RXON_OVR, 0); - REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain), - AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR, 0); -} - static bool ar9003_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) { @@ -1057,14 +989,6 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT); - if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { - for (i = 0; i < AR9300_MAX_CHAINS; i++) { - if (!(ah->rxchainmask & (1 << i))) - continue; - ar9003_hw_manual_peak_cal(ah, i, - IS_CHAN_2GHZ(chan)); - } - } } if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal) diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 74fd3977feeb..0693cd95b746 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -35,6 +35,12 @@ */ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) { +#define AR9462_BB_CTX_COEFJ(x) \ + ar9462_##x##_baseband_core_txfir_coeff_japan_2484 + +#define AR9462_BBC_TXIFR_COEFFJ \ + ar9462_2p0_baseband_core_txfir_coeff_japan_2484 + if (AR_SREV_9330_11(ah)) { /* mac */ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], @@ -64,10 +70,6 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) INIT_INI_ARRAY(&ah->iniModesTxGain, ar9331_modes_lowest_ob_db_tx_gain_1p1); - /* Japan 2484 Mhz CCK */ - INIT_INI_ARRAY(&ah->iniCckfirJapan2484, - ar9331_1p1_baseband_core_txfir_coeff_japan_2484); - /* additional clock settings */ if (ah->is_clk_25mhz) INIT_INI_ARRAY(&ah->iniAdditional, @@ -104,10 +106,6 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) INIT_INI_ARRAY(&ah->iniModesTxGain, ar9331_modes_lowest_ob_db_tx_gain_1p2); - /* Japan 2484 Mhz CCK */ - INIT_INI_ARRAY(&ah->iniCckfirJapan2484, - ar9331_1p2_baseband_core_txfir_coeff_japan_2484); - /* additional clock settings */ if (ah->is_clk_25mhz) INIT_INI_ARRAY(&ah->iniAdditional, @@ -182,10 +180,6 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) INIT_INI_ARRAY(&ah->iniModesTxGain, ar9485_modes_lowest_ob_db_tx_gain_1_1); - /* Japan 2484 Mhz CCK */ - INIT_INI_ARRAY(&ah->iniCckfirJapan2484, - ar9485_1_1_baseband_core_txfir_coeff_japan_2484); - /* Load PCIE SERDES settings from INI */ /* Awake Setting */ @@ -235,7 +229,9 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) ar9462_modes_fast_clock_2p0); INIT_INI_ARRAY(&ah->iniCckfirJapan2484, - ar9462_2p0_baseband_core_txfir_coeff_japan_2484); + AR9462_BB_CTX_COEFJ(2p0)); + + INIT_INI_ARRAY(&ah->ini_japan2484, AR9462_BBC_TXIFR_COEFFJ); } else if (AR_SREV_9550(ah)) { /* mac */ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_mci.c index 8dd069259e7b..42b4412d6794 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_mci.c @@ -714,6 +714,7 @@ bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan) return true; } +EXPORT_SYMBOL(ar9003_mci_start_reset); int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, struct ath9k_hw_cal_data *caldata) diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.c index ce19c09fa8e8..759f5f5a7154 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -784,7 +784,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, REG_WRITE_ARRAY(&ah->iniAdditional, 1, regWrites); if (chan->channel == 2484) - ar9003_hw_prog_ini(ah, &ah->iniCckfirJapan2484, 1); + ar9003_hw_prog_ini(ah, &ah->ini_japan2484, 1); if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) REG_WRITE(ah, AR_GLB_SWREG_DISCONT_MODE, diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 4c3d06de7111..8f585233a788 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -698,6 +698,13 @@ #define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT 0x0000ff00 #define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT_S 8 +#define AR_PHY_65NM_CH0_RXTX1 0x16100 +#define AR_PHY_65NM_CH0_RXTX2 0x16104 +#define AR_PHY_65NM_CH1_RXTX1 0x16500 +#define AR_PHY_65NM_CH1_RXTX2 0x16504 +#define AR_PHY_65NM_CH2_RXTX1 0x16900 +#define AR_PHY_65NM_CH2_RXTX2 0x16904 + #define AR_CH0_TOP2 (AR_SREV_9300(ah) ? 0x1628c : \ (AR_SREV_9462(ah) ? 0x16290 : 0x16284)) #define AR_CH0_TOP2_XPABIASLVL 0xf000 @@ -1279,43 +1286,4 @@ #define AR_BTCOEX_WL_LNADIV_BT_INACTIVE_THRESHOLD 0xFC000000 #define AR_BTCOEX_WL_LNADIV_BT_INACTIVE_THRESHOLD_S 26 -/* Manual Peak detector calibration */ -#define AR_PHY_65NM_BASE 0x16000 -#define AR_PHY_65NM_RXRF_GAINSTAGES(i) (AR_PHY_65NM_BASE + \ - (i * 0x400) + 0x8) -#define AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE 0x80000000 -#define AR_PHY_65NM_RXRF_GAINSTAGES_RX_OVERRIDE_S 31 -#define AR_PHY_65NM_RXRF_GAINSTAGES_LNAON_CALDC 0x00000002 -#define AR_PHY_65NM_RXRF_GAINSTAGES_LNAON_CALDC_S 1 -#define AR_PHY_65NM_RXRF_GAINSTAGES_LNA2G_GAIN_OVR 0x70000000 -#define AR_PHY_65NM_RXRF_GAINSTAGES_LNA2G_GAIN_OVR_S 28 -#define AR_PHY_65NM_RXRF_GAINSTAGES_LNA5G_GAIN_OVR 0x03800000 -#define AR_PHY_65NM_RXRF_GAINSTAGES_LNA5G_GAIN_OVR_S 23 - -#define AR_PHY_65NM_RXTX2(i) (AR_PHY_65NM_BASE + \ - (i * 0x400) + 0x104) -#define AR_PHY_65NM_RXTX2_RXON_OVR 0x00001000 -#define AR_PHY_65NM_RXTX2_RXON_OVR_S 12 -#define AR_PHY_65NM_RXTX2_RXON 0x00000800 -#define AR_PHY_65NM_RXTX2_RXON_S 11 - -#define AR_PHY_65NM_RXRF_AGC(i) (AR_PHY_65NM_BASE + \ - (i * 0x400) + 0xc) -#define AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE 0x80000000 -#define AR_PHY_65NM_RXRF_AGC_AGC_OVERRIDE_S 31 -#define AR_PHY_65NM_RXRF_AGC_AGC_ON_OVR 0x40000000 -#define AR_PHY_65NM_RXRF_AGC_AGC_ON_OVR_S 30 -#define AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR 0x20000000 -#define AR_PHY_65NM_RXRF_AGC_AGC_CAL_OVR_S 29 -#define AR_PHY_65NM_RXRF_AGC_AGC2G_DBDAC_OVR 0x1E000000 -#define AR_PHY_65NM_RXRF_AGC_AGC2G_DBDAC_OVR_S 25 -#define AR_PHY_65NM_RXRF_AGC_AGC5G_DBDAC_OVR 0x00078000 -#define AR_PHY_65NM_RXRF_AGC_AGC5G_DBDAC_OVR_S 15 -#define AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR 0x01F80000 -#define AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR_S 19 -#define AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR 0x00007e00 -#define AR_PHY_65NM_RXRF_AGC_AGC5G_CALDAC_OVR_S 9 -#define AR_PHY_65NM_RXRF_AGC_AGC_OUT 0x00000004 -#define AR_PHY_65NM_RXRF_AGC_AGC_OUT_S 2 - #endif /* AR9003_PHY_H */ diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/trunk/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h index ccc42a71b436..58f30f65c6b6 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h @@ -78,7 +78,7 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = { {0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150}, {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110}, {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222}, - {0x0000a2c4, 0x00058d18, 0x00058d18, 0x00058d18, 0x00058d18}, + {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, {0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982}, {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b}, {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/trunk/drivers/net/wireless/ath/ath9k/ar9485_initvals.h index a3710f3bb90c..fb4497fc7a3d 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9485_initvals.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9485_initvals.h @@ -18,7 +18,7 @@ #ifndef INITVALS_9485_H #define INITVALS_9485_H -/* AR9485 1.1 */ +/* AR9485 1.0 */ #define ar9485_1_1_mac_postamble ar9300_2p2_mac_postamble @@ -31,11 +31,6 @@ static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1[][2] = { static const u32 ar9485Common_wo_xlna_rx_gain_1_1[][2] = { /* Addr allmodes */ - {0x00009e00, 0x037216a0}, - {0x00009e04, 0x00182020}, - {0x00009e18, 0x00000000}, - {0x00009e2c, 0x00004121}, - {0x00009e44, 0x02282324}, {0x0000a000, 0x00060005}, {0x0000a004, 0x00810080}, {0x0000a008, 0x00830082}, @@ -169,11 +164,6 @@ static const u32 ar9485Common_wo_xlna_rx_gain_1_1[][2] = { static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, - {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0x7999a83a, 0x7999a83a}, - {0x0000a2dc, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, - {0x0000a2e0, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, - {0x0000a2e4, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, - {0x0000a2e8, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, @@ -208,22 +198,6 @@ static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = { {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a580, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a584, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a588, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a58c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a590, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a594, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a598, 0x00000000, 0x00000000, 0x01404501, 0x01404501}, - {0x0000a59c, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02}, - {0x0000a5a0, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02}, - {0x0000a5a4, 0x00000000, 0x00000000, 0x02808803, 0x02808803}, - {0x0000a5a8, 0x00000000, 0x00000000, 0x04c14b04, 0x04c14b04}, - {0x0000a5ac, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5b0, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5b4, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5b8, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5bc, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, @@ -260,193 +234,9 @@ static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = { {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, }; -static const u32 ar9485Modes_high_ob_db_tx_gain_1_1[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, - {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0x7999a83a, 0x7999a83a}, - {0x0000a2dc, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, - {0x0000a2e0, 0x00000000, 0x00000000, 0xffc63a84, 0xffc63a84}, - {0x0000a2e4, 0x00000000, 0x00000000, 0xfe0fc000, 0xfe0fc000}, - {0x0000a2e8, 0x00000000, 0x00000000, 0xfff00000, 0xfff00000}, - {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, - {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, - {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, - {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, - {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, - {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, - {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, - {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, - {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, - {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603}, - {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605}, - {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03}, - {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04}, - {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20}, - {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21}, - {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62}, - {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63}, - {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65}, - {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66}, - {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645}, - {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, - {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, - {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, - {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, - {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, - {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, - {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a580, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a584, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a588, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a58c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a590, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a594, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a598, 0x00000000, 0x00000000, 0x01404501, 0x01404501}, - {0x0000a59c, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02}, - {0x0000a5a0, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02}, - {0x0000a5a4, 0x00000000, 0x00000000, 0x02808803, 0x02808803}, - {0x0000a5a8, 0x00000000, 0x00000000, 0x04c14b04, 0x04c14b04}, - {0x0000a5ac, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5b0, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5b4, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5b8, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5bc, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db}, - {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, -}; +#define ar9485Modes_high_ob_db_tx_gain_1_1 ar9485Modes_high_power_tx_gain_1_1 -static const u32 ar9485Modes_low_ob_db_tx_gain_1_1[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, - {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0x7999a83a, 0x7999a83a}, - {0x0000a2dc, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, - {0x0000a2e0, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, - {0x0000a2e4, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, - {0x0000a2e8, 0x00000000, 0x00000000, 0xfe2d3552, 0xfe2d3552}, - {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, - {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, - {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, - {0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, - {0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200}, - {0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202}, - {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400}, - {0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402}, - {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404}, - {0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603}, - {0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605}, - {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03}, - {0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04}, - {0x0000a530, 0x48023ec6, 0x48023ec6, 0x34000e20, 0x34000e20}, - {0x0000a534, 0x4d023f01, 0x4d023f01, 0x35000e21, 0x35000e21}, - {0x0000a538, 0x53023f4b, 0x53023f4b, 0x43000e62, 0x43000e62}, - {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x45000e63, 0x45000e63}, - {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x49000e65, 0x49000e65}, - {0x0000a544, 0x6502feca, 0x6502feca, 0x4b000e66, 0x4b000e66}, - {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x4d001645, 0x4d001645}, - {0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865}, - {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86}, - {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9}, - {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb}, - {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb}, - {0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb}, - {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x5e001eeb, 0x5e001eeb}, - {0x0000a580, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a584, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a588, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a58c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a590, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a594, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a598, 0x00000000, 0x00000000, 0x01404501, 0x01404501}, - {0x0000a59c, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02}, - {0x0000a5a0, 0x00000000, 0x00000000, 0x02808a02, 0x02808a02}, - {0x0000a5a4, 0x00000000, 0x00000000, 0x02808803, 0x02808803}, - {0x0000a5a8, 0x00000000, 0x00000000, 0x04c14b04, 0x04c14b04}, - {0x0000a5ac, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5b0, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5b4, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5b8, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000a5bc, 0x00000000, 0x00000000, 0x04c15305, 0x04c15305}, - {0x0000b500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b504, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b508, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b50c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b510, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b514, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b518, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b51c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b520, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b524, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b528, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b52c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b530, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b534, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b538, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b53c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b540, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b544, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b548, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b54c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b550, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b554, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b558, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b55c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b560, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b564, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b568, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b56c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b570, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b574, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b578, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000b57c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db}, - {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, -}; +#define ar9485Modes_low_ob_db_tx_gain_1_1 ar9485Modes_high_ob_db_tx_gain_1_1 #define ar9485_modes_lowest_ob_db_tx_gain_1_1 ar9485Modes_low_ob_db_tx_gain_1_1 @@ -455,19 +245,19 @@ static const u32 ar9485_1_1[][2] = { {0x0000a580, 0x00000000}, {0x0000a584, 0x00000000}, {0x0000a588, 0x00000000}, - {0x0000a58c, 0x01804000}, - {0x0000a590, 0x02808a02}, - {0x0000a594, 0x0340ca02}, - {0x0000a598, 0x0340cd03}, - {0x0000a59c, 0x0340cd03}, - {0x0000a5a0, 0x06415304}, - {0x0000a5a4, 0x04c11905}, - {0x0000a5a8, 0x06415905}, - {0x0000a5ac, 0x06415905}, - {0x0000a5b0, 0x06415905}, - {0x0000a5b4, 0x06415905}, - {0x0000a5b8, 0x06415905}, - {0x0000a5bc, 0x06415905}, + {0x0000a58c, 0x00000000}, + {0x0000a590, 0x00000000}, + {0x0000a594, 0x00000000}, + {0x0000a598, 0x00000000}, + {0x0000a59c, 0x00000000}, + {0x0000a5a0, 0x00000000}, + {0x0000a5a4, 0x00000000}, + {0x0000a5a8, 0x00000000}, + {0x0000a5ac, 0x00000000}, + {0x0000a5b0, 0x00000000}, + {0x0000a5b4, 0x00000000}, + {0x0000a5b8, 0x00000000}, + {0x0000a5bc, 0x00000000}, }; static const u32 ar9485_1_1_radio_core[][2] = { @@ -550,7 +340,7 @@ static const u32 ar9485_1_1_baseband_core[][2] = { {0x00009880, 0x201fff00}, {0x00009884, 0x00001042}, {0x000098a4, 0x00200400}, - {0x000098b0, 0x32840bbe}, + {0x000098b0, 0x52440bbe}, {0x000098d0, 0x004b6a8e}, {0x000098d4, 0x00000820}, {0x000098dc, 0x00000000}, @@ -572,7 +362,7 @@ static const u32 ar9485_1_1_baseband_core[][2] = { {0x00009d18, 0x00000000}, {0x00009d1c, 0x00000000}, {0x00009e08, 0x0038233c}, - {0x00009e24, 0x992bb515}, + {0x00009e24, 0x9927b515}, {0x00009e28, 0x12ef0200}, {0x00009e30, 0x06336f77}, {0x00009e34, 0x6af6532f}, @@ -637,7 +427,7 @@ static const u32 ar9485_1_1_baseband_core[][2] = { {0x0000a408, 0x0e79e5c6}, {0x0000a40c, 0x00820820}, {0x0000a414, 0x1ce739cf}, - {0x0000a418, 0x2d0021ce}, + {0x0000a418, 0x2d0019ce}, {0x0000a41c, 0x1ce739ce}, {0x0000a420, 0x000001ce}, {0x0000a424, 0x1ce739ce}, @@ -653,8 +443,8 @@ static const u32 ar9485_1_1_baseband_core[][2] = { {0x0000a44c, 0x00000001}, {0x0000a450, 0x00010000}, {0x0000a5c4, 0xbfad9d74}, - {0x0000a5c8, 0x00480605}, - {0x0000a5cc, 0x00002e37}, + {0x0000a5c8, 0x0048060a}, + {0x0000a5cc, 0x00000637}, {0x0000a760, 0x03020100}, {0x0000a764, 0x09080504}, {0x0000a768, 0x0d0c0b0a}, @@ -674,22 +464,17 @@ static const u32 ar9485_1_1_baseband_core[][2] = { static const u32 ar9485_common_rx_gain_1_1[][2] = { /* Addr allmodes */ - {0x00009e00, 0x03721b20}, - {0x00009e04, 0x00082020}, - {0x00009e18, 0x0300501e}, - {0x00009e2c, 0x00002e21}, - {0x00009e44, 0x02182324}, - {0x0000a000, 0x00060005}, - {0x0000a004, 0x00810080}, - {0x0000a008, 0x00830082}, - {0x0000a00c, 0x00850084}, - {0x0000a010, 0x01820181}, - {0x0000a014, 0x01840183}, - {0x0000a018, 0x01880185}, - {0x0000a01c, 0x018a0189}, - {0x0000a020, 0x02850284}, - {0x0000a024, 0x02890288}, - {0x0000a028, 0x028b028a}, + {0x0000a000, 0x00010000}, + {0x0000a004, 0x00030002}, + {0x0000a008, 0x00050004}, + {0x0000a00c, 0x00810080}, + {0x0000a010, 0x01800082}, + {0x0000a014, 0x01820181}, + {0x0000a018, 0x01840183}, + {0x0000a01c, 0x01880185}, + {0x0000a020, 0x018a0189}, + {0x0000a024, 0x02850284}, + {0x0000a028, 0x02890288}, {0x0000a02c, 0x03850384}, {0x0000a030, 0x03890388}, {0x0000a034, 0x038b038a}, @@ -711,15 +496,15 @@ static const u32 ar9485_common_rx_gain_1_1[][2] = { {0x0000a074, 0x00000000}, {0x0000a078, 0x00000000}, {0x0000a07c, 0x00000000}, - {0x0000a080, 0x18181818}, - {0x0000a084, 0x18181818}, - {0x0000a088, 0x18181818}, - {0x0000a08c, 0x18181818}, - {0x0000a090, 0x18181818}, - {0x0000a094, 0x18181818}, - {0x0000a098, 0x17181818}, - {0x0000a09c, 0x02020b0b}, - {0x0000a0a0, 0x02020202}, + {0x0000a080, 0x28282828}, + {0x0000a084, 0x28282828}, + {0x0000a088, 0x28282828}, + {0x0000a08c, 0x28282828}, + {0x0000a090, 0x28282828}, + {0x0000a094, 0x21212128}, + {0x0000a098, 0x171c1c1c}, + {0x0000a09c, 0x02020212}, + {0x0000a0a0, 0x00000202}, {0x0000a0a4, 0x00000000}, {0x0000a0a8, 0x00000000}, {0x0000a0ac, 0x00000000}, @@ -727,22 +512,22 @@ static const u32 ar9485_common_rx_gain_1_1[][2] = { {0x0000a0b4, 0x00000000}, {0x0000a0b8, 0x00000000}, {0x0000a0bc, 0x00000000}, - {0x0000a0c0, 0x22072208}, - {0x0000a0c4, 0x22052206}, - {0x0000a0c8, 0x22032204}, - {0x0000a0cc, 0x22012202}, - {0x0000a0d0, 0x221f2200}, - {0x0000a0d4, 0x221d221e}, - {0x0000a0d8, 0x33023303}, - {0x0000a0dc, 0x33003301}, - {0x0000a0e0, 0x331e331f}, - {0x0000a0e4, 0x4402331d}, - {0x0000a0e8, 0x44004401}, - {0x0000a0ec, 0x441e441f}, - {0x0000a0f0, 0x55025503}, - {0x0000a0f4, 0x55005501}, - {0x0000a0f8, 0x551e551f}, - {0x0000a0fc, 0x6602551d}, + {0x0000a0c0, 0x001f0000}, + {0x0000a0c4, 0x111f1100}, + {0x0000a0c8, 0x111d111e}, + {0x0000a0cc, 0x111b111c}, + {0x0000a0d0, 0x22032204}, + {0x0000a0d4, 0x22012202}, + {0x0000a0d8, 0x221f2200}, + {0x0000a0dc, 0x221d221e}, + {0x0000a0e0, 0x33013302}, + {0x0000a0e4, 0x331f3300}, + {0x0000a0e8, 0x4402331e}, + {0x0000a0ec, 0x44004401}, + {0x0000a0f0, 0x441e441f}, + {0x0000a0f4, 0x55015502}, + {0x0000a0f8, 0x551f5500}, + {0x0000a0fc, 0x6602551e}, {0x0000a100, 0x66006601}, {0x0000a104, 0x661e661f}, {0x0000a108, 0x7703661d}, @@ -851,12 +636,17 @@ static const u32 ar9485_1_1_baseband_postamble[][5] = { {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c}, {0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044}, + {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0}, + {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020}, {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec80d2e, 0x7ec80d2e}, - {0x00009e14, 0x31395d53, 0x31396053, 0x312e6053, 0x312e5d53}, + {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e}, + {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, + {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, {0x00009e3c, 0xcf946220, 0xcf946220, 0xcf946222, 0xcf946222}, + {0x00009e44, 0x02321e27, 0x02321e27, 0x02282324, 0x02282324}, {0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010}, {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, {0x0000a204, 0x01303fc0, 0x01303fc4, 0x01303fc4, 0x01303fc0}, @@ -1060,6 +850,4 @@ static const u32 ar9485_1_1_mac_core[][2] = { {0x000083d0, 0x000301ff}, }; -#define ar9485_1_1_baseband_core_txfir_coeff_japan_2484 ar9462_2p0_baseband_core_txfir_coeff_japan_2484 - #endif /* INITVALS_9485_H */ diff --git a/trunk/drivers/net/wireless/ath/ath9k/ath9k.h b/trunk/drivers/net/wireless/ath/ath9k/ath9k.h index 86e26a19efda..4e125d8904a0 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ath9k.h @@ -129,10 +129,10 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd, #define ATH_TXMAXTRY 13 #define TID_TO_WME_AC(_tid) \ - ((((_tid) == 0) || ((_tid) == 3)) ? IEEE80211_AC_BE : \ - (((_tid) == 1) || ((_tid) == 2)) ? IEEE80211_AC_BK : \ - (((_tid) == 4) || ((_tid) == 5)) ? IEEE80211_AC_VI : \ - IEEE80211_AC_VO) + ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \ + (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \ + (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \ + WME_AC_VO) #define ATH_AGGR_DELIM_SZ 4 #define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */ @@ -259,21 +259,19 @@ struct ath_atx_tid { }; struct ath_node { - struct ath_softc *sc; +#ifdef CONFIG_ATH9K_DEBUGFS + struct list_head list; /* for sc->nodes */ +#endif struct ieee80211_sta *sta; /* station struct we're part of */ struct ieee80211_vif *vif; /* interface with which we're associated */ - struct ath_atx_tid tid[IEEE80211_NUM_TIDS]; - struct ath_atx_ac ac[IEEE80211_NUM_ACS]; + struct ath_atx_tid tid[WME_NUM_TID]; + struct ath_atx_ac ac[WME_NUM_AC]; int ps_key; u16 maxampdu; u8 mpdudensity; bool sleeping; - -#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS) - struct dentry *node_stat; -#endif }; #define AGGR_CLEANUP BIT(1) @@ -301,9 +299,9 @@ struct ath_tx { struct list_head txbuf; struct ath_txq txq[ATH9K_NUM_TX_QUEUES]; struct ath_descdma txdma; - struct ath_txq *txq_map[IEEE80211_NUM_ACS]; - u32 txq_max_pending[IEEE80211_NUM_ACS]; - u16 max_aggr_framelen[IEEE80211_NUM_ACS][4][32]; + struct ath_txq *txq_map[WME_NUM_AC]; + u32 txq_max_pending[WME_NUM_AC]; + u16 max_aggr_framelen[WME_NUM_AC][4][32]; }; struct ath_rx_edma { @@ -463,12 +461,6 @@ void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type); /* BTCOEX */ /**********/ -#define ATH_DUMP_BTCOEX(_s, _val) \ - do { \ - len += snprintf(buf + len, size - len, \ - "%20s : %10d\n", _s, (_val)); \ - } while (0) - enum bt_op_flags { BT_OP_PRIORITY_DETECTED, BT_OP_SCAN, @@ -490,7 +482,6 @@ struct ath_btcoex { int rssi_count; struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */ struct ath_mci_profile mci; - u8 stomp_audio; }; #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT @@ -503,7 +494,7 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc); void ath9k_btcoex_handle_interrupt(struct ath_softc *sc, u32 status); u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen); void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc); -int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, u32 size); +int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, u32 len, u32 size); #else static inline int ath9k_init_btcoex(struct ath_softc *sc) { @@ -530,7 +521,8 @@ static inline u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, static inline void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc) { } -static inline int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, u32 size) +static inline int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, + u32 len, u32 size) { return 0; } @@ -725,6 +717,9 @@ struct ath_softc { #ifdef CONFIG_ATH9K_DEBUGFS struct ath9k_debug debug; + spinlock_t nodes_lock; + struct list_head nodes; /* basically, stations */ + unsigned int tx_complete_poll_work_seen; #endif struct ath_beacon_config cur_beacon_conf; struct delayed_work tx_complete_work; diff --git a/trunk/drivers/net/wireless/ath/ath9k/beacon.c b/trunk/drivers/net/wireless/ath/ath9k/beacon.c index 531fffd801a3..1b48414dca95 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/beacon.c +++ b/trunk/drivers/net/wireless/ath/ath9k/beacon.c @@ -46,7 +46,7 @@ static void ath9k_beaconq_config(struct ath_softc *sc) qi.tqi_cwmax = 0; } else { /* Adhoc mode; important thing is to use 2x cwmin. */ - txq = sc->tx.txq_map[IEEE80211_AC_BE]; + txq = sc->tx.txq_map[WME_AC_BE]; ath9k_hw_get_txq_props(ah, txq->axq_qnum, &qi_be); qi.tqi_aifs = qi_be.tqi_aifs; if (ah->slottime == ATH9K_SLOT_TIME_20) diff --git a/trunk/drivers/net/wireless/ath/ath9k/btcoex.c b/trunk/drivers/net/wireless/ath/ath9k/btcoex.c index 9963b0bf9f72..c90e9bc4b026 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/btcoex.c +++ b/trunk/drivers/net/wireless/ath/ath9k/btcoex.c @@ -49,7 +49,6 @@ static const u32 mci_wlan_weights[ATH_BTCOEX_STOMP_MAX] { 0x01017d01, 0x3b3b3b01, 0x3b3b3b01, 0x3b3b3b3b }, /* STOMP_LOW */ { 0x01017d01, 0x01010101, 0x01010101, 0x01010101 }, /* STOMP_NONE */ { 0x01017d01, 0x013b0101, 0x3b3b0101, 0x3b3b013b }, /* STOMP_LOW_FTP */ - { 0xffffff01, 0xffffffff, 0xffffff01, 0xffffffff }, /* STOMP_AUDIO */ }; void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum) diff --git a/trunk/drivers/net/wireless/ath/ath9k/btcoex.h b/trunk/drivers/net/wireless/ath/ath9k/btcoex.h index 6de26ea5d5fa..2f84ab273d0c 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/btcoex.h +++ b/trunk/drivers/net/wireless/ath/ath9k/btcoex.h @@ -50,7 +50,6 @@ enum ath_stomp_type { ATH_BTCOEX_STOMP_LOW, ATH_BTCOEX_STOMP_NONE, ATH_BTCOEX_STOMP_LOW_FTP, - ATH_BTCOEX_STOMP_AUDIO, ATH_BTCOEX_STOMP_MAX }; diff --git a/trunk/drivers/net/wireless/ath/ath9k/common.h b/trunk/drivers/net/wireless/ath/ath9k/common.h index 5f845beeb18b..ad14fecc76c6 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/common.h +++ b/trunk/drivers/net/wireless/ath/ath9k/common.h @@ -23,10 +23,18 @@ /* Common header for Atheros 802.11n base driver cores */ +#define WME_NUM_TID 16 #define WME_BA_BMP_SIZE 64 #define WME_MAX_BA WME_BA_BMP_SIZE #define ATH_TID_MAX_BUFS (2 * WME_MAX_BA) +/* These must match mac80211 skb queue mapping numbers */ +#define WME_AC_VO 0 +#define WME_AC_VI 1 +#define WME_AC_BE 2 +#define WME_AC_BK 3 +#define WME_NUM_AC 4 + #define ATH_RSSI_DUMMY_MARKER 0x127 #define ATH_RSSI_LPF_LEN 10 #define RSSI_LPF_THRESHOLD -20 diff --git a/trunk/drivers/net/wireless/ath/ath9k/debug.c b/trunk/drivers/net/wireless/ath/ath9k/debug.c index 13ff9edc2401..a8be94b2a53a 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/debug.c +++ b/trunk/drivers/net/wireless/ath/ath9k/debug.c @@ -512,19 +512,62 @@ static const struct file_operations fops_interrupt = { .llseek = default_llseek, }; +#define PR_QNUM(_n) sc->tx.txq_map[_n]->axq_qnum +#define PR(str, elem) \ + do { \ + len += snprintf(buf + len, size - len, \ + "%s%13u%11u%10u%10u\n", str, \ + sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].elem, \ + sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].elem, \ + sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].elem, \ + sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].elem); \ + if (len >= size) \ + goto done; \ +} while(0) + +#define PRX(str, elem) \ +do { \ + len += snprintf(buf + len, size - len, \ + "%s%13u%11u%10u%10u\n", str, \ + (unsigned int)(sc->tx.txq_map[WME_AC_BE]->elem), \ + (unsigned int)(sc->tx.txq_map[WME_AC_BK]->elem), \ + (unsigned int)(sc->tx.txq_map[WME_AC_VI]->elem), \ + (unsigned int)(sc->tx.txq_map[WME_AC_VO]->elem)); \ + if (len >= size) \ + goto done; \ +} while(0) + +#define PRQLE(str, elem) \ +do { \ + len += snprintf(buf + len, size - len, \ + "%s%13i%11i%10i%10i\n", str, \ + list_empty(&sc->tx.txq_map[WME_AC_BE]->elem), \ + list_empty(&sc->tx.txq_map[WME_AC_BK]->elem), \ + list_empty(&sc->tx.txq_map[WME_AC_VI]->elem), \ + list_empty(&sc->tx.txq_map[WME_AC_VO]->elem)); \ + if (len >= size) \ + goto done; \ +} while (0) + static ssize_t read_file_xmit(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct ath_softc *sc = file->private_data; char *buf; - unsigned int len = 0, size = 2048; + unsigned int len = 0, size = 8000; + int i; ssize_t retval = 0; + char tmp[32]; buf = kzalloc(size, GFP_KERNEL); if (buf == NULL) return -ENOMEM; - len += sprintf(buf, "%30s %10s%10s%10s\n\n", + len += sprintf(buf, "Num-Tx-Queues: %i tx-queues-setup: 0x%x" + " poll-work-seen: %u\n" + "%30s %10s%10s%10s\n\n", + ATH9K_NUM_TX_QUEUES, sc->tx.txqsetup, + sc->tx_complete_poll_work_seen, "BE", "BK", "VI", "VO"); PR("MPDUs Queued: ", queued); @@ -544,11 +587,62 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, PR("DELIM Underrun: ", delim_underrun); PR("TX-Pkts-All: ", tx_pkts_all); PR("TX-Bytes-All: ", tx_bytes_all); - PR("HW-put-tx-buf: ", puttxbuf); - PR("HW-tx-start: ", txstart); - PR("HW-tx-proc-desc: ", txprocdesc); + PR("hw-put-tx-buf: ", puttxbuf); + PR("hw-tx-start: ", txstart); + PR("hw-tx-proc-desc: ", txprocdesc); PR("TX-Failed: ", txfailed); + len += snprintf(buf + len, size - len, + "%s%11p%11p%10p%10p\n", "txq-memory-address:", + sc->tx.txq_map[WME_AC_BE], + sc->tx.txq_map[WME_AC_BK], + sc->tx.txq_map[WME_AC_VI], + sc->tx.txq_map[WME_AC_VO]); + if (len >= size) + goto done; + + PRX("axq-qnum: ", axq_qnum); + PRX("axq-depth: ", axq_depth); + PRX("axq-ampdu_depth: ", axq_ampdu_depth); + PRX("axq-stopped ", stopped); + PRX("tx-in-progress ", axq_tx_inprogress); + PRX("pending-frames ", pending_frames); + PRX("txq_headidx: ", txq_headidx); + PRX("txq_tailidx: ", txq_headidx); + + PRQLE("axq_q empty: ", axq_q); + PRQLE("axq_acq empty: ", axq_acq); + for (i = 0; i < ATH_TXFIFO_DEPTH; i++) { + snprintf(tmp, sizeof(tmp) - 1, "txq_fifo[%i] empty: ", i); + PRQLE(tmp, txq_fifo[i]); + } + /* Print out more detailed queue-info */ + for (i = 0; i <= WME_AC_BK; i++) { + struct ath_txq *txq = &(sc->tx.txq[i]); + struct ath_atx_ac *ac; + struct ath_atx_tid *tid; + if (len >= size) + goto done; + spin_lock_bh(&txq->axq_lock); + if (!list_empty(&txq->axq_acq)) { + ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, + list); + len += snprintf(buf + len, size - len, + "txq[%i] first-ac: %p sched: %i\n", + i, ac, ac->sched); + if (list_empty(&ac->tid_q) || (len >= size)) + goto done_for; + tid = list_first_entry(&ac->tid_q, struct ath_atx_tid, + list); + len += snprintf(buf + len, size - len, + " first-tid: %p sched: %i paused: %i\n", + tid, tid->sched, tid->paused); + } + done_for: + spin_unlock_bh(&txq->axq_lock); + } + +done: if (len > size) len = size; @@ -558,41 +652,62 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, return retval; } -static ssize_t read_file_queues(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) +static ssize_t read_file_stations(struct file *file, char __user *user_buf, + size_t count, loff_t *ppos) { struct ath_softc *sc = file->private_data; - struct ath_txq *txq; char *buf; - unsigned int len = 0, size = 1024; + unsigned int len = 0, size = 64000; + struct ath_node *an = NULL; ssize_t retval = 0; - int i; - char *qname[4] = {"VO", "VI", "BE", "BK"}; + int q; buf = kzalloc(size, GFP_KERNEL); if (buf == NULL) return -ENOMEM; - for (i = 0; i < IEEE80211_NUM_ACS; i++) { - txq = sc->tx.txq_map[i]; - len += snprintf(buf + len, size - len, "(%s): ", qname[i]); - - ath_txq_lock(sc, txq); - - len += snprintf(buf + len, size - len, "%s: %d ", - "qnum", txq->axq_qnum); - len += snprintf(buf + len, size - len, "%s: %2d ", - "qdepth", txq->axq_depth); - len += snprintf(buf + len, size - len, "%s: %2d ", - "ampdu-depth", txq->axq_ampdu_depth); - len += snprintf(buf + len, size - len, "%s: %3d ", - "pending", txq->pending_frames); - len += snprintf(buf + len, size - len, "%s: %d\n", - "stopped", txq->stopped); + len += snprintf(buf + len, size - len, + "Stations:\n" + " tid: addr sched paused buf_q-empty an ac baw\n" + " ac: addr sched tid_q-empty txq\n"); + + spin_lock(&sc->nodes_lock); + list_for_each_entry(an, &sc->nodes, list) { + unsigned short ma = an->maxampdu; + if (ma == 0) + ma = 65535; /* see ath_lookup_rate */ + len += snprintf(buf + len, size - len, + "iface: %pM sta: %pM max-ampdu: %hu mpdu-density: %uus\n", + an->vif->addr, an->sta->addr, ma, + (unsigned int)(an->mpdudensity)); + if (len >= size) + goto done; + + for (q = 0; q < WME_NUM_TID; q++) { + struct ath_atx_tid *tid = &(an->tid[q]); + len += snprintf(buf + len, size - len, + " tid: %p %s %s %i %p %p %hu\n", + tid, tid->sched ? "sched" : "idle", + tid->paused ? "paused" : "running", + skb_queue_empty(&tid->buf_q), + tid->an, tid->ac, tid->baw_size); + if (len >= size) + goto done; + } - ath_txq_unlock(sc, txq); + for (q = 0; q < WME_NUM_AC; q++) { + struct ath_atx_ac *ac = &(an->ac[q]); + len += snprintf(buf + len, size - len, + " ac: %p %s %i %p\n", + ac, ac->sched ? "sched" : "idle", + list_empty(&ac->tid_q), ac->txq); + if (len >= size) + goto done; + } } +done: + spin_unlock(&sc->nodes_lock); if (len > size) len = size; @@ -722,9 +837,6 @@ static ssize_t read_file_reset(struct file *file, char __user *user_buf, len += snprintf(buf + len, sizeof(buf) - len, "%17s: %2d\n", "PLL RX Hang", sc->debug.stats.reset[RESET_TYPE_PLL_HANG]); - len += snprintf(buf + len, sizeof(buf) - len, - "%17s: %2d\n", "MCI Reset", - sc->debug.stats.reset[RESET_TYPE_MCI]); if (len > sizeof(buf)) len = sizeof(buf); @@ -807,8 +919,8 @@ static const struct file_operations fops_xmit = { .llseek = default_llseek, }; -static const struct file_operations fops_queues = { - .read = read_file_queues, +static const struct file_operations fops_stations = { + .read = read_file_stations, .open = simple_open, .owner = THIS_MODULE, .llseek = default_llseek, @@ -1487,14 +1599,8 @@ static ssize_t read_file_btcoex(struct file *file, char __user *user_buf, if (buf == NULL) return -ENOMEM; - if (!sc->sc_ah->common.btcoex_enabled) { - len = snprintf(buf, size, "%s\n", - "BTCOEX is disabled"); - goto exit; - } + len = ath9k_dump_btcoex(sc, buf, len, size); - len = ath9k_dump_btcoex(sc, buf, size); -exit: retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); kfree(buf); @@ -1509,215 +1615,6 @@ static const struct file_operations fops_btcoex = { }; #endif -static ssize_t read_file_node_stat(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct ath_node *an = file->private_data; - struct ath_softc *sc = an->sc; - struct ath_atx_tid *tid; - struct ath_atx_ac *ac; - struct ath_txq *txq; - u32 len = 0, size = 4096; - char *buf; - size_t retval; - int tidno, acno; - - buf = kzalloc(size, GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - - if (!an->sta->ht_cap.ht_supported) { - len = snprintf(buf, size, "%s\n", - "HT not supported"); - goto exit; - } - - len = snprintf(buf, size, "Max-AMPDU: %d\n", - an->maxampdu); - len += snprintf(buf + len, size - len, "MPDU Density: %d\n\n", - an->mpdudensity); - - len += snprintf(buf + len, size - len, - "%2s%7s\n", "AC", "SCHED"); - - for (acno = 0, ac = &an->ac[acno]; - acno < IEEE80211_NUM_ACS; acno++, ac++) { - txq = ac->txq; - ath_txq_lock(sc, txq); - len += snprintf(buf + len, size - len, - "%2d%7d\n", - acno, ac->sched); - ath_txq_unlock(sc, txq); - } - - len += snprintf(buf + len, size - len, - "\n%3s%11s%10s%10s%10s%10s%9s%6s%8s\n", - "TID", "SEQ_START", "SEQ_NEXT", "BAW_SIZE", - "BAW_HEAD", "BAW_TAIL", "BAR_IDX", "SCHED", "PAUSED"); - - for (tidno = 0, tid = &an->tid[tidno]; - tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { - txq = tid->ac->txq; - ath_txq_lock(sc, txq); - len += snprintf(buf + len, size - len, - "%3d%11d%10d%10d%10d%10d%9d%6d%8d\n", - tid->tidno, tid->seq_start, tid->seq_next, - tid->baw_size, tid->baw_head, tid->baw_tail, - tid->bar_index, tid->sched, tid->paused); - ath_txq_unlock(sc, txq); - } -exit: - retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); - kfree(buf); - - return retval; -} - -static const struct file_operations fops_node_stat = { - .read = read_file_node_stat, - .open = simple_open, - .owner = THIS_MODULE, - .llseek = default_llseek, -}; - -void ath9k_sta_add_debugfs(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - struct dentry *dir) -{ - struct ath_node *an = (struct ath_node *)sta->drv_priv; - an->node_stat = debugfs_create_file("node_stat", S_IRUGO, - dir, an, &fops_node_stat); -} - -void ath9k_sta_remove_debugfs(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - struct dentry *dir) -{ - struct ath_node *an = (struct ath_node *)sta->drv_priv; - debugfs_remove(an->node_stat); -} - -/* Ethtool support for get-stats */ - -#define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO" -static const char ath9k_gstrings_stats[][ETH_GSTRING_LEN] = { - "tx_pkts_nic", - "tx_bytes_nic", - "rx_pkts_nic", - "rx_bytes_nic", - AMKSTR(d_tx_pkts), - AMKSTR(d_tx_bytes), - AMKSTR(d_tx_mpdus_queued), - AMKSTR(d_tx_mpdus_completed), - AMKSTR(d_tx_mpdu_xretries), - AMKSTR(d_tx_aggregates), - AMKSTR(d_tx_ampdus_queued_hw), - AMKSTR(d_tx_ampdus_queued_sw), - AMKSTR(d_tx_ampdus_completed), - AMKSTR(d_tx_ampdu_retries), - AMKSTR(d_tx_ampdu_xretries), - AMKSTR(d_tx_fifo_underrun), - AMKSTR(d_tx_op_exceeded), - AMKSTR(d_tx_timer_expiry), - AMKSTR(d_tx_desc_cfg_err), - AMKSTR(d_tx_data_underrun), - AMKSTR(d_tx_delim_underrun), - "d_rx_decrypt_crc_err", - "d_rx_phy_err", - "d_rx_mic_err", - "d_rx_pre_delim_crc_err", - "d_rx_post_delim_crc_err", - "d_rx_decrypt_busy_err", - - "d_rx_phyerr_radar", - "d_rx_phyerr_ofdm_timing", - "d_rx_phyerr_cck_timing", - -}; -#define ATH9K_SSTATS_LEN ARRAY_SIZE(ath9k_gstrings_stats) - -void ath9k_get_et_strings(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - u32 sset, u8 *data) -{ - if (sset == ETH_SS_STATS) - memcpy(data, *ath9k_gstrings_stats, - sizeof(ath9k_gstrings_stats)); -} - -int ath9k_get_et_sset_count(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, int sset) -{ - if (sset == ETH_SS_STATS) - return ATH9K_SSTATS_LEN; - return 0; -} - -#define AWDATA(elem) \ - do { \ - data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].elem; \ - data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].elem; \ - data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].elem; \ - data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].elem; \ - } while (0) - -#define AWDATA_RX(elem) \ - do { \ - data[i++] = sc->debug.stats.rxstats.elem; \ - } while (0) - -void ath9k_get_et_stats(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ethtool_stats *stats, u64 *data) -{ - struct ath_softc *sc = hw->priv; - int i = 0; - - data[i++] = (sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_pkts_all + - sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].tx_pkts_all + - sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].tx_pkts_all + - sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].tx_pkts_all); - data[i++] = (sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_bytes_all + - sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].tx_bytes_all + - sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].tx_bytes_all + - sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].tx_bytes_all); - AWDATA_RX(rx_pkts_all); - AWDATA_RX(rx_bytes_all); - - AWDATA(tx_pkts_all); - AWDATA(tx_bytes_all); - AWDATA(queued); - AWDATA(completed); - AWDATA(xretries); - AWDATA(a_aggr); - AWDATA(a_queued_hw); - AWDATA(a_queued_sw); - AWDATA(a_completed); - AWDATA(a_retries); - AWDATA(a_xretries); - AWDATA(fifo_underrun); - AWDATA(xtxop); - AWDATA(timer_exp); - AWDATA(desc_cfg_err); - AWDATA(data_underrun); - AWDATA(delim_underrun); - - AWDATA_RX(decrypt_crc_err); - AWDATA_RX(phy_err); - AWDATA_RX(mic_err); - AWDATA_RX(pre_delim_crc_err); - AWDATA_RX(post_delim_crc_err); - AWDATA_RX(decrypt_busy_err); - - AWDATA_RX(phy_err_stats[ATH9K_PHYERR_RADAR]); - AWDATA_RX(phy_err_stats[ATH9K_PHYERR_OFDM_TIMING]); - AWDATA_RX(phy_err_stats[ATH9K_PHYERR_CCK_TIMING]); - - WARN_ON(i != ATH9K_SSTATS_LEN); -} - int ath9k_init_debug(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); @@ -1741,16 +1638,16 @@ int ath9k_init_debug(struct ath_hw *ah) &fops_interrupt); debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, sc, &fops_xmit); - debugfs_create_file("queues", S_IRUSR, sc->debug.debugfs_phy, sc, - &fops_queues); debugfs_create_u32("qlen_bk", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, - &sc->tx.txq_max_pending[IEEE80211_AC_BK]); + &sc->tx.txq_max_pending[WME_AC_BK]); debugfs_create_u32("qlen_be", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, - &sc->tx.txq_max_pending[IEEE80211_AC_BE]); + &sc->tx.txq_max_pending[WME_AC_BE]); debugfs_create_u32("qlen_vi", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, - &sc->tx.txq_max_pending[IEEE80211_AC_VI]); + &sc->tx.txq_max_pending[WME_AC_VI]); debugfs_create_u32("qlen_vo", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, - &sc->tx.txq_max_pending[IEEE80211_AC_VO]); + &sc->tx.txq_max_pending[WME_AC_VO]); + debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy, sc, + &fops_stations); debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc, &fops_misc); debugfs_create_file("reset", S_IRUSR, sc->debug.debugfs_phy, sc, diff --git a/trunk/drivers/net/wireless/ath/ath9k/debug.h b/trunk/drivers/net/wireless/ath/ath9k/debug.h index 72d4893311b1..2ed9785a38fa 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/debug.h +++ b/trunk/drivers/net/wireless/ath/ath9k/debug.h @@ -41,7 +41,6 @@ enum ath_reset_type { RESET_TYPE_PLL_HANG, RESET_TYPE_MAC_HANG, RESET_TYPE_BEACON_STUCK, - RESET_TYPE_MCI, __RESET_TYPE_MAX }; @@ -179,21 +178,6 @@ struct ath_tx_stats { u32 txfailed; }; -/* - * Various utility macros to print TX/Queue counters. - */ -#define PR_QNUM(_n) sc->tx.txq_map[_n]->axq_qnum -#define TXSTATS sc->debug.stats.txstats -#define PR(str, elem) \ - do { \ - len += snprintf(buf + len, size - len, \ - "%s%13u%11u%10u%10u\n", str, \ - TXSTATS[PR_QNUM(IEEE80211_AC_BE)].elem, \ - TXSTATS[PR_QNUM(IEEE80211_AC_BK)].elem, \ - TXSTATS[PR_QNUM(IEEE80211_AC_VI)].elem, \ - TXSTATS[PR_QNUM(IEEE80211_AC_VO)].elem); \ - } while(0) - #define RX_STAT_INC(c) (sc->debug.stats.rxstats.c++) /** @@ -242,7 +226,7 @@ struct ath_rx_stats { struct ath_stats { struct ath_interrupt_stats istats; - struct ath_tx_stats txstats[IEEE80211_NUM_ACS]; + struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES]; struct ath_rx_stats rxstats; struct ath_dfs_stats dfs_stats; u32 reset[__RESET_TYPE_MAX]; @@ -307,22 +291,7 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, struct ath_tx_status *ts, struct ath_txq *txq, unsigned int flags); void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs); -int ath9k_get_et_sset_count(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, int sset); -void ath9k_get_et_stats(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ethtool_stats *stats, u64 *data); -void ath9k_get_et_strings(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - u32 sset, u8 *data); -void ath9k_sta_add_debugfs(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - struct dentry *dir); -void ath9k_sta_remove_debugfs(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - struct dentry *dir); + #else #define RX_STAT_INC(c) /* NOP */ diff --git a/trunk/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c b/trunk/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c index 24877b00cbf4..ea2a6cf7ef23 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c +++ b/trunk/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.c @@ -42,15 +42,10 @@ struct radar_types { #define MIN_PPB_THRESH 50 #define PPB_THRESH(PPB) ((PPB * MIN_PPB_THRESH + 50) / 100) #define PRF2PRI(PRF) ((1000000 + PRF / 2) / PRF) -/* percentage of pulse width tolerance */ -#define WIDTH_TOLERANCE 5 -#define WIDTH_LOWER(X) ((X*(100-WIDTH_TOLERANCE)+50)/100) -#define WIDTH_UPPER(X) ((X*(100+WIDTH_TOLERANCE)+50)/100) #define ETSI_PATTERN(ID, WMIN, WMAX, PMIN, PMAX, PRF, PPB) \ { \ - ID, WIDTH_LOWER(WMIN), WIDTH_UPPER(WMAX), \ - (PRF2PRI(PMAX) - PRI_TOLERANCE), \ + ID, WMIN, WMAX, (PRF2PRI(PMAX) - PRI_TOLERANCE), \ (PRF2PRI(PMIN) * PRF + PRI_TOLERANCE), PRF, PPB * PRF, \ PPB_THRESH(PPB), PRI_TOLERANCE, \ } @@ -279,7 +274,7 @@ static bool dpd_set_domain(struct dfs_pattern_detector *dpd, static struct dfs_pattern_detector default_dpd = { .exit = dpd_exit, - .set_dfs_domain = dpd_set_domain, + .set_domain = dpd_set_domain, .add_pulse = dpd_add_pulse, .region = NL80211_DFS_UNSET, }; @@ -296,11 +291,10 @@ dfs_pattern_detector_init(enum nl80211_dfs_regions region) *dpd = default_dpd; INIT_LIST_HEAD(&dpd->channel_detectors); - if (dpd->set_dfs_domain(dpd, region)) + if (dpd->set_domain(dpd, region)) return dpd; pr_err("Could not set DFS domain to %d. ", region); - kfree(dpd); return NULL; } EXPORT_SYMBOL(dfs_pattern_detector_init); diff --git a/trunk/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.h b/trunk/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.h index cda52f39f28a..fd0328a30995 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.h +++ b/trunk/drivers/net/wireless/ath/ath9k/dfs_pattern_detector.h @@ -62,7 +62,7 @@ struct radar_detector_specs { /** * struct dfs_pattern_detector - DFS pattern detector * @exit(): destructor - * @set_dfs_domain(): set DFS domain, resets detector lines upon domain changes + * @set_domain(): set DFS domain, resets detector lines upon domain changes * @add_pulse(): add radar pulse to detector, returns true on detection * @region: active DFS region, NL80211_DFS_UNSET until set * @num_radar_types: number of different radar types @@ -72,7 +72,7 @@ struct radar_detector_specs { */ struct dfs_pattern_detector { void (*exit)(struct dfs_pattern_detector *dpd); - bool (*set_dfs_domain)(struct dfs_pattern_detector *dpd, + bool (*set_domain)(struct dfs_pattern_detector *dpd, enum nl80211_dfs_regions region); bool (*add_pulse)(struct dfs_pattern_detector *dpd, struct pulse_event *pe); diff --git a/trunk/drivers/net/wireless/ath/ath9k/gpio.c b/trunk/drivers/net/wireless/ath/ath9k/gpio.c index 4b412aaf4f36..a8ea57b9f49c 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/gpio.c +++ b/trunk/drivers/net/wireless/ath/ath9k/gpio.c @@ -247,9 +247,6 @@ static void ath_btcoex_period_timer(unsigned long data) stomp_type = ATH_BTCOEX_STOMP_ALL; timer_period = btcoex->btscan_no_stomp; } - } else if (btcoex->stomp_audio >= 5) { - stomp_type = ATH_BTCOEX_STOMP_AUDIO; - btcoex->stomp_audio = 0; } ath9k_hw_btcoex_bt_stomp(ah, stomp_type); @@ -298,7 +295,7 @@ static void ath_btcoex_no_stomp_timer(void *arg) (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && test_bit(BT_OP_SCAN, &btcoex->op_flags))) ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); - else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) + else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW); ath9k_hw_btcoex_enable(ah); @@ -474,7 +471,7 @@ int ath9k_init_btcoex(struct ath_softc *sc) r = ath_init_btcoex_timer(sc); if (r) return -1; - txq = sc->tx.txq_map[IEEE80211_AC_BE]; + txq = sc->tx.txq_map[WME_AC_BE]; ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum); sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; if (ath9k_hw_mci_is_enabled(ah)) { @@ -497,31 +494,35 @@ int ath9k_init_btcoex(struct ath_softc *sc) return 0; } -static int ath9k_dump_mci_btcoex(struct ath_softc *sc, u8 *buf, u32 size) +int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, u32 len, u32 size) { +#define ATH_DUMP_BTCOEX(_s, _val) \ + do { \ + len += snprintf(buf + len, size - len, \ + "%20s : %10d\n", _s, (_val)); \ + } while (0) + struct ath_btcoex *btcoex = &sc->btcoex; struct ath_mci_profile *mci = &btcoex->mci; struct ath_hw *ah = sc->sc_ah; struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; - u32 len = 0; int i; ATH_DUMP_BTCOEX("Total BT profiles", NUM_PROF(mci)); - ATH_DUMP_BTCOEX("MGMT", mci->num_mgmt); - ATH_DUMP_BTCOEX("SCO", mci->num_sco); - ATH_DUMP_BTCOEX("A2DP", mci->num_a2dp); - ATH_DUMP_BTCOEX("HID", mci->num_hid); - ATH_DUMP_BTCOEX("PAN", mci->num_pan); - ATH_DUMP_BTCOEX("ACL", mci->num_other_acl); - ATH_DUMP_BTCOEX("BDR", mci->num_bdr); + ATH_DUMP_BTCOEX("Number of MGMT", mci->num_mgmt); + ATH_DUMP_BTCOEX("Number of SCO", mci->num_sco); + ATH_DUMP_BTCOEX("Number of A2DP", mci->num_a2dp); + ATH_DUMP_BTCOEX("Number of HID", mci->num_hid); + ATH_DUMP_BTCOEX("Number of PAN", mci->num_pan); + ATH_DUMP_BTCOEX("Number of ACL", mci->num_other_acl); + ATH_DUMP_BTCOEX("Number of BDR", mci->num_bdr); ATH_DUMP_BTCOEX("Aggr. Limit", mci->aggr_limit); ATH_DUMP_BTCOEX("Stomp Type", btcoex->bt_stomp_type); ATH_DUMP_BTCOEX("BTCoex Period (msec)", btcoex->btcoex_period); ATH_DUMP_BTCOEX("Duty Cycle", btcoex->duty_cycle); ATH_DUMP_BTCOEX("BT Wait time", btcoex->bt_wait_time); ATH_DUMP_BTCOEX("Concurrent Tx", btcoex_hw->mci.concur_tx); - ATH_DUMP_BTCOEX("Concurrent RSSI cnt", btcoex->rssi_count); - + ATH_DUMP_BTCOEX("Concur RSSI count", btcoex->rssi_count); len += snprintf(buf + len, size - len, "BT Weights: "); for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++) len += snprintf(buf + len, size - len, "%08x ", @@ -536,32 +537,9 @@ static int ath9k_dump_mci_btcoex(struct ath_softc *sc, u8 *buf, u32 size) for (i = 0; i < ATH_BTCOEX_STOMP_MAX; i++) len += snprintf(buf + len, size - len, "%08x ", btcoex_hw->tx_prio[i]); - len += snprintf(buf + len, size - len, "\n"); +#undef ATH_DUMP_BTCOEX return len; } - -static int ath9k_dump_legacy_btcoex(struct ath_softc *sc, u8 *buf, u32 size) -{ - - struct ath_btcoex *btcoex = &sc->btcoex; - u32 len = 0; - - ATH_DUMP_BTCOEX("Stomp Type", btcoex->bt_stomp_type); - ATH_DUMP_BTCOEX("BTCoex Period (msec)", btcoex->btcoex_period); - ATH_DUMP_BTCOEX("Duty Cycle", btcoex->duty_cycle); - ATH_DUMP_BTCOEX("BT Wait time", btcoex->bt_wait_time); - - return len; -} - -int ath9k_dump_btcoex(struct ath_softc *sc, u8 *buf, u32 size) -{ - if (ath9k_hw_mci_is_enabled(sc->sc_ah)) - return ath9k_dump_mci_btcoex(sc, buf, size); - else - return ath9k_dump_legacy_btcoex(sc, buf, size); -} - #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc.h b/trunk/drivers/net/wireless/ath/ath9k/htc.h index 96bfb18078fa..b30596fcf73a 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc.h +++ b/trunk/drivers/net/wireless/ath/ath9k/htc.h @@ -331,7 +331,7 @@ struct ath_tx_stats { u32 skb_success; u32 skb_failed; u32 cab_queued; - u32 queue_stats[IEEE80211_NUM_ACS]; + u32 queue_stats[WME_NUM_AC]; }; struct ath_rx_stats { @@ -493,7 +493,7 @@ struct ath9k_htc_priv { int beaconq; int cabq; - int hwq_map[IEEE80211_NUM_ACS]; + int hwq_map[WME_NUM_AC]; #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT struct ath_btcoex btcoex; diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index d0ce1f5bba10..1318d79f5c44 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -33,7 +33,7 @@ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv) qi.tqi_cwmin = 0; qi.tqi_cwmax = 0; } else if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) { - int qnum = priv->hwq_map[IEEE80211_AC_BE]; + int qnum = priv->hwq_map[WME_AC_BE]; ath9k_hw_get_txq_props(ah, qnum, &qi_be); diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_debug.c index 87110de577ef..3035deb7a0cd 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_debug.c +++ b/trunk/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, len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", "BE queued", - priv->debug.tx_stats.queue_stats[IEEE80211_AC_BE]); + priv->debug.tx_stats.queue_stats[WME_AC_BE]); len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", "BK queued", - priv->debug.tx_stats.queue_stats[IEEE80211_AC_BK]); + priv->debug.tx_stats.queue_stats[WME_AC_BK]); len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", "VI queued", - priv->debug.tx_stats.queue_stats[IEEE80211_AC_VI]); + priv->debug.tx_stats.queue_stats[WME_AC_VI]); len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n", "VO queued", - priv->debug.tx_stats.queue_stats[IEEE80211_AC_VO]); + priv->debug.tx_stats.queue_stats[WME_AC_VO]); if (len > sizeof(buf)) len = sizeof(buf); diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c index 105582d6b714..0eacfc13c915 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c +++ b/trunk/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) priv->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; ath9k_hw_btcoex_init_3wire(priv->ah); ath_htc_init_btcoex_work(priv); - qnum = priv->hwq_map[IEEE80211_AC_BE]; + qnum = priv->hwq_map[WME_AC_BE]; ath9k_hw_init_btcoex_hw(priv->ah, qnum); break; default: diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 05d5ba66cac3..5ecf1287dddd 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -549,20 +549,20 @@ static int ath9k_init_queues(struct ath9k_htc_priv *priv) goto err; } - if (!ath9k_htc_txq_setup(priv, IEEE80211_AC_BE)) { + if (!ath9k_htc_txq_setup(priv, WME_AC_BE)) { ath_err(common, "Unable to setup xmit queue for BE traffic\n"); goto err; } - if (!ath9k_htc_txq_setup(priv, IEEE80211_AC_BK)) { + if (!ath9k_htc_txq_setup(priv, WME_AC_BK)) { ath_err(common, "Unable to setup xmit queue for BK traffic\n"); goto err; } - if (!ath9k_htc_txq_setup(priv, IEEE80211_AC_VI)) { + if (!ath9k_htc_txq_setup(priv, WME_AC_VI)) { ath_err(common, "Unable to setup xmit queue for VI traffic\n"); goto err; } - if (!ath9k_htc_txq_setup(priv, IEEE80211_AC_VO)) { + if (!ath9k_htc_txq_setup(priv, WME_AC_VO)) { ath_err(common, "Unable to setup xmit queue for VO traffic\n"); goto err; } diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 9c07a8fa5134..02cce95331d8 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1349,7 +1349,7 @@ static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, struct ath9k_tx_queue_info qi; int ret = 0, qnum; - if (queue >= IEEE80211_NUM_ACS) + if (queue >= WME_NUM_AC) return 0; mutex_lock(&priv->mutex); @@ -1376,7 +1376,7 @@ static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, } if ((priv->ah->opmode == NL80211_IFTYPE_ADHOC) && - (qnum == priv->hwq_map[IEEE80211_AC_BE])) + (qnum == priv->hwq_map[WME_AC_BE])) ath9k_htc_beaconq_config(priv); out: ath9k_htc_ps_restore(priv); diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index 28cd50ee521a..e4ec98332988 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -21,10 +21,10 @@ /******/ static const int subtype_txq_to_hwq[] = { - [IEEE80211_AC_BE] = ATH_TXQ_AC_BE, - [IEEE80211_AC_BK] = ATH_TXQ_AC_BK, - [IEEE80211_AC_VI] = ATH_TXQ_AC_VI, - [IEEE80211_AC_VO] = ATH_TXQ_AC_VO, + [WME_AC_BE] = ATH_TXQ_AC_BE, + [WME_AC_BK] = ATH_TXQ_AC_BK, + [WME_AC_VI] = ATH_TXQ_AC_VI, + [WME_AC_VO] = ATH_TXQ_AC_VO, }; #define ATH9K_HTC_INIT_TXQ(subtype) do { \ @@ -41,15 +41,15 @@ int get_hw_qnum(u16 queue, int *hwq_map) { switch (queue) { case 0: - return hwq_map[IEEE80211_AC_VO]; + return hwq_map[WME_AC_VO]; case 1: - return hwq_map[IEEE80211_AC_VI]; + return hwq_map[WME_AC_VI]; case 2: - return hwq_map[IEEE80211_AC_BE]; + return hwq_map[WME_AC_BE]; case 3: - return hwq_map[IEEE80211_AC_BK]; + return hwq_map[WME_AC_BK]; default: - return hwq_map[IEEE80211_AC_BE]; + return hwq_map[WME_AC_BE]; } } @@ -106,20 +106,20 @@ static inline enum htc_endpoint_id get_htc_epid(struct ath9k_htc_priv *priv, switch (qnum) { case 0: - TX_QSTAT_INC(IEEE80211_AC_VO); + TX_QSTAT_INC(WME_AC_VO); epid = priv->data_vo_ep; break; case 1: - TX_QSTAT_INC(IEEE80211_AC_VI); + TX_QSTAT_INC(WME_AC_VI); epid = priv->data_vi_ep; break; case 2: - TX_QSTAT_INC(IEEE80211_AC_BE); + TX_QSTAT_INC(WME_AC_BE); epid = priv->data_be_ep; break; case 3: default: - TX_QSTAT_INC(IEEE80211_AC_BK); + TX_QSTAT_INC(WME_AC_BK); epid = priv->data_bk_ep; break; } diff --git a/trunk/drivers/net/wireless/ath/ath9k/hw.c b/trunk/drivers/net/wireless/ath/ath9k/hw.c index e06bcec655a7..71cd9f0c96af 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hw.c +++ b/trunk/drivers/net/wireless/ath/ath9k/hw.c @@ -1456,7 +1456,7 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type) switch (type) { case ATH9K_RESET_POWER_ON: ret = ath9k_hw_set_reset_power_on(ah); - if (ret) + if (!ret) ah->reset_power_on = true; break; case ATH9K_RESET_WARM: @@ -2561,6 +2561,11 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) pCap->hw_caps |= ATH9K_HW_CAP_ANT_DIV_COMB; } + if (AR_SREV_9485_10(ah)) { + pCap->pcie_lcr_extsync_en = true; + pCap->pcie_lcr_offset = 0x80; + } + if (ath9k_hw_dfs_tested(ah)) pCap->hw_caps |= ATH9K_HW_CAP_DFS; diff --git a/trunk/drivers/net/wireless/ath/ath9k/hw.h b/trunk/drivers/net/wireless/ath/ath9k/hw.h index 3636dabf03e1..3e73bfe2315e 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hw.h +++ b/trunk/drivers/net/wireless/ath/ath9k/hw.h @@ -273,6 +273,8 @@ struct ath9k_hw_capabilities { u8 rx_status_len; u8 tx_desc_len; u8 txs_len; + u16 pcie_lcr_offset; + bool pcie_lcr_extsync_en; }; struct ath9k_ops_config { @@ -875,6 +877,7 @@ struct ath_hw { struct ar5416IniArray iniModesTxGain; struct ar5416IniArray iniCckfirNormal; struct ar5416IniArray iniCckfirJapan2484; + struct ar5416IniArray ini_japan2484; struct ar5416IniArray iniModes_9271_ANI_reg; struct ar5416IniArray ini_radio_post_sys2ant; @@ -927,6 +930,7 @@ struct ath_bus_ops { void (*read_cachesize)(struct ath_common *common, int *csz); bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); void (*bt_coex_prep)(struct ath_common *common); + void (*extn_synch_en)(struct ath_common *common); void (*aspm_init)(struct ath_common *common); }; diff --git a/trunk/drivers/net/wireless/ath/ath9k/init.c b/trunk/drivers/net/wireless/ath/ath9k/init.c index 80cae53a33e5..546bae93647b 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/init.c +++ b/trunk/drivers/net/wireless/ath/ath9k/init.c @@ -435,7 +435,7 @@ static int ath9k_init_queues(struct ath_softc *sc) sc->config.cabqReadytime = ATH_CABQ_READY_TIME; ath_cabq_update(sc); - for (i = 0; i < IEEE80211_NUM_ACS; i++) { + for (i = 0; i < WME_NUM_AC; i++) { sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i); sc->tx.txq_map[i]->mac80211_qnum = i; sc->tx.txq_max_pending[i] = ATH_MAX_QDEPTH; @@ -563,6 +563,10 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, spin_lock_init(&sc->sc_serial_rw); spin_lock_init(&sc->sc_pm_lock); mutex_init(&sc->mutex); +#ifdef CONFIG_ATH9K_DEBUGFS + spin_lock_init(&sc->nodes_lock); + INIT_LIST_HEAD(&sc->nodes); +#endif #ifdef CONFIG_ATH9K_MAC_DEBUG spin_lock_init(&sc->debug.samp_lock); #endif diff --git a/trunk/drivers/net/wireless/ath/ath9k/link.c b/trunk/drivers/net/wireless/ath/ath9k/link.c index fc6b075ad635..223b9693527e 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/link.c +++ b/trunk/drivers/net/wireless/ath/ath9k/link.c @@ -27,6 +27,9 @@ void ath_tx_complete_poll_work(struct work_struct *work) struct ath_txq *txq; int i; bool needreset = false; +#ifdef CONFIG_ATH9K_DEBUGFS + sc->tx_complete_poll_work_seen++; +#endif for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) if (ATH_TXQ_SETUP(sc, i)) { @@ -208,7 +211,7 @@ static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int int time_left; memset(&txctl, 0, sizeof(txctl)); - txctl.txq = sc->tx.txq_map[IEEE80211_AC_BE]; + txctl.txq = sc->tx.txq_map[WME_AC_BE]; memset(tx_info, 0, sizeof(*tx_info)); tx_info->band = hw->conf.channel->band; diff --git a/trunk/drivers/net/wireless/ath/ath9k/main.c b/trunk/drivers/net/wireless/ath/ath9k/main.c index be30a9af1528..c084532291a1 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/main.c +++ b/trunk/drivers/net/wireless/ath/ath9k/main.c @@ -331,7 +331,11 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, u8 density; an = (struct ath_node *)sta->drv_priv; - an->sc = sc; +#ifdef CONFIG_ATH9K_DEBUGFS + spin_lock(&sc->nodes_lock); + list_add(&an->list, &sc->nodes); + spin_unlock(&sc->nodes_lock); +#endif an->sta = sta; an->vif = vif; @@ -348,6 +352,13 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) { struct ath_node *an = (struct ath_node *)sta->drv_priv; +#ifdef CONFIG_ATH9K_DEBUGFS + spin_lock(&sc->nodes_lock); + list_del(&an->list); + spin_unlock(&sc->nodes_lock); + an->sta = NULL; +#endif + if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) ath_tx_node_cleanup(sc, an); } @@ -483,6 +494,17 @@ irqreturn_t ath_isr(int irq, void *dev) if (status & SCHED_INTR) sched = true; +#ifdef CONFIG_PM_SLEEP + if (status & ATH9K_INT_BMISS) { + if (atomic_read(&sc->wow_sleep_proc_intr) == 0) { + ath_dbg(common, ANY, "during WoW we got a BMISS\n"); + atomic_inc(&sc->wow_got_bmiss_intr); + atomic_dec(&sc->wow_sleep_proc_intr); + } + ath_dbg(common, INTERRUPT, "beacon miss interrupt\n"); + } +#endif + /* * If a FATAL or RXORN interrupt is received, we have to reset the * chip immediately. @@ -501,15 +523,7 @@ irqreturn_t ath_isr(int irq, void *dev) goto chip_reset; } -#ifdef CONFIG_PM_SLEEP - if (status & ATH9K_INT_BMISS) { - if (atomic_read(&sc->wow_sleep_proc_intr) == 0) { - ath_dbg(common, ANY, "during WoW we got a BMISS\n"); - atomic_inc(&sc->wow_got_bmiss_intr); - atomic_dec(&sc->wow_sleep_proc_intr); - } - } -#endif + if (status & ATH9K_INT_SWBA) tasklet_schedule(&sc->bcon_tasklet); @@ -672,6 +686,9 @@ static int ath9k_start(struct ieee80211_hw *hw) spin_unlock_bh(&sc->sc_pcu_lock); + if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en) + common->bus_ops->extn_synch_en(common); + mutex_unlock(&sc->mutex); ath9k_ps_restore(sc); @@ -1314,7 +1331,7 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, struct ath9k_tx_queue_info qi; int ret = 0; - if (queue >= IEEE80211_NUM_ACS) + if (queue >= WME_NUM_AC) return 0; txq = sc->tx.txq_map[queue]; @@ -1883,6 +1900,134 @@ static int ath9k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) return 0; } +#ifdef CONFIG_ATH9K_DEBUGFS + +/* Ethtool support for get-stats */ + +#define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO" +static const char ath9k_gstrings_stats[][ETH_GSTRING_LEN] = { + "tx_pkts_nic", + "tx_bytes_nic", + "rx_pkts_nic", + "rx_bytes_nic", + AMKSTR(d_tx_pkts), + AMKSTR(d_tx_bytes), + AMKSTR(d_tx_mpdus_queued), + AMKSTR(d_tx_mpdus_completed), + AMKSTR(d_tx_mpdu_xretries), + AMKSTR(d_tx_aggregates), + AMKSTR(d_tx_ampdus_queued_hw), + AMKSTR(d_tx_ampdus_queued_sw), + AMKSTR(d_tx_ampdus_completed), + AMKSTR(d_tx_ampdu_retries), + AMKSTR(d_tx_ampdu_xretries), + AMKSTR(d_tx_fifo_underrun), + AMKSTR(d_tx_op_exceeded), + AMKSTR(d_tx_timer_expiry), + AMKSTR(d_tx_desc_cfg_err), + AMKSTR(d_tx_data_underrun), + AMKSTR(d_tx_delim_underrun), + + "d_rx_decrypt_crc_err", + "d_rx_phy_err", + "d_rx_mic_err", + "d_rx_pre_delim_crc_err", + "d_rx_post_delim_crc_err", + "d_rx_decrypt_busy_err", + + "d_rx_phyerr_radar", + "d_rx_phyerr_ofdm_timing", + "d_rx_phyerr_cck_timing", + +}; +#define ATH9K_SSTATS_LEN ARRAY_SIZE(ath9k_gstrings_stats) + +static void ath9k_get_et_strings(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + u32 sset, u8 *data) +{ + if (sset == ETH_SS_STATS) + memcpy(data, *ath9k_gstrings_stats, + sizeof(ath9k_gstrings_stats)); +} + +static int ath9k_get_et_sset_count(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, int sset) +{ + if (sset == ETH_SS_STATS) + return ATH9K_SSTATS_LEN; + return 0; +} + +#define PR_QNUM(_n) (sc->tx.txq_map[_n]->axq_qnum) +#define AWDATA(elem) \ + do { \ + data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].elem; \ + data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].elem; \ + data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].elem; \ + data[i++] = sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].elem; \ + } while (0) + +#define AWDATA_RX(elem) \ + do { \ + data[i++] = sc->debug.stats.rxstats.elem; \ + } while (0) + +static void ath9k_get_et_stats(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ethtool_stats *stats, u64 *data) +{ + struct ath_softc *sc = hw->priv; + int i = 0; + + data[i++] = (sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].tx_pkts_all + + sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].tx_pkts_all + + sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].tx_pkts_all + + sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].tx_pkts_all); + data[i++] = (sc->debug.stats.txstats[PR_QNUM(WME_AC_BE)].tx_bytes_all + + sc->debug.stats.txstats[PR_QNUM(WME_AC_BK)].tx_bytes_all + + sc->debug.stats.txstats[PR_QNUM(WME_AC_VI)].tx_bytes_all + + sc->debug.stats.txstats[PR_QNUM(WME_AC_VO)].tx_bytes_all); + AWDATA_RX(rx_pkts_all); + AWDATA_RX(rx_bytes_all); + + AWDATA(tx_pkts_all); + AWDATA(tx_bytes_all); + AWDATA(queued); + AWDATA(completed); + AWDATA(xretries); + AWDATA(a_aggr); + AWDATA(a_queued_hw); + AWDATA(a_queued_sw); + AWDATA(a_completed); + AWDATA(a_retries); + AWDATA(a_xretries); + AWDATA(fifo_underrun); + AWDATA(xtxop); + AWDATA(timer_exp); + AWDATA(desc_cfg_err); + AWDATA(data_underrun); + AWDATA(delim_underrun); + + AWDATA_RX(decrypt_crc_err); + AWDATA_RX(phy_err); + AWDATA_RX(mic_err); + AWDATA_RX(pre_delim_crc_err); + AWDATA_RX(post_delim_crc_err); + AWDATA_RX(decrypt_busy_err); + + AWDATA_RX(phy_err_stats[ATH9K_PHYERR_RADAR]); + AWDATA_RX(phy_err_stats[ATH9K_PHYERR_OFDM_TIMING]); + AWDATA_RX(phy_err_stats[ATH9K_PHYERR_CCK_TIMING]); + + WARN_ON(i != ATH9K_SSTATS_LEN); +} + +/* End of ethtool get-stats functions */ + +#endif + + #ifdef CONFIG_PM_SLEEP static void ath9k_wow_map_triggers(struct ath_softc *sc, @@ -2276,12 +2421,7 @@ struct ieee80211_ops ath9k_ops = { #ifdef CONFIG_ATH9K_DEBUGFS .get_et_sset_count = ath9k_get_et_sset_count, - .get_et_stats = ath9k_get_et_stats, - .get_et_strings = ath9k_get_et_strings, -#endif - -#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS) - .sta_add_debugfs = ath9k_sta_add_debugfs, - .sta_remove_debugfs = ath9k_sta_remove_debugfs, + .get_et_stats = ath9k_get_et_stats, + .get_et_strings = ath9k_get_et_strings, #endif }; diff --git a/trunk/drivers/net/wireless/ath/ath9k/mci.c b/trunk/drivers/net/wireless/ath/ath9k/mci.c index 5c02702f21e7..0dd2cbb52d65 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/mci.c +++ b/trunk/drivers/net/wireless/ath/ath9k/mci.c @@ -207,6 +207,23 @@ static void ath_mci_update_scheme(struct ath_softc *sc) ath9k_btcoex_timer_resume(sc); } +static void ath_mci_wait_btcal_done(struct ath_softc *sc) +{ + struct ath_hw *ah = sc->sc_ah; + + /* Stop tx & rx */ + ieee80211_stop_queues(sc->hw); + ath_stoprecv(sc); + ath_drain_all_txq(sc, false); + + /* Wait for cal done */ + ar9003_mci_start_reset(ah, ah->curchan); + + /* Resume tx & rx */ + ath_startrecv(sc); + ieee80211_wake_queues(sc->hw); +} + static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) { struct ath_hw *ah = sc->sc_ah; @@ -218,7 +235,7 @@ static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) case MCI_GPM_BT_CAL_REQ: if (mci_hw->bt_state == MCI_BT_AWAKE) { mci_hw->bt_state = MCI_BT_CAL_START; - ath9k_queue_reset(sc, RESET_TYPE_MCI); + ath_mci_wait_btcal_done(sc); } ath_dbg(common, MCI, "MCI State : %d\n", mci_hw->bt_state); break; @@ -257,9 +274,8 @@ static void ath_mci_set_concur_txprio(struct ath_softc *sc) { struct ath_btcoex *btcoex = &sc->btcoex; struct ath_mci_profile *mci = &btcoex->mci; - u8 stomp_txprio[ATH_BTCOEX_STOMP_MAX]; + u8 stomp_txprio[] = { 0, 0, 0, 0 }; /* all, low, none, low_ftp */ - memset(stomp_txprio, 0, sizeof(stomp_txprio)); if (mci->num_mgmt) { stomp_txprio[ATH_BTCOEX_STOMP_ALL] = ATH_MCI_INQUIRY_PRIO; if (!mci->num_pan && !mci->num_other_acl) @@ -562,8 +578,6 @@ void ath_mci_intr(struct ath_softc *sc) mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_GPM; while (more_data == MCI_GPM_MORE) { - if (test_bit(SC_OP_HW_RESET, &sc->sc_flags)) - return; pgpm = mci->gpm_buf.bf_addr; offset = ar9003_mci_get_next_gpm_offset(ah, false, @@ -730,30 +744,12 @@ void ath9k_mci_set_txpower(struct ath_softc *sc, bool setchannel, ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit, false); } -static void ath9k_mci_stomp_audio(struct ath_softc *sc) -{ - struct ath_hw *ah = sc->sc_ah; - struct ath_btcoex *btcoex = &sc->btcoex; - struct ath_mci_profile *mci = &btcoex->mci; - - if (!mci->num_sco && !mci->num_a2dp) - return; - - if (ah->stats.avgbrssi > 25) { - btcoex->stomp_audio = 0; - return; - } - - btcoex->stomp_audio++; -} void ath9k_mci_update_rssi(struct ath_softc *sc) { struct ath_hw *ah = sc->sc_ah; struct ath_btcoex *btcoex = &sc->btcoex; struct ath9k_hw_mci *mci_hw = &sc->sc_ah->btcoex_hw.mci; - ath9k_mci_stomp_audio(sc); - if (!(mci_hw->config & ATH_MCI_CONFIG_CONCUR_TX)) return; diff --git a/trunk/drivers/net/wireless/ath/ath9k/pci.c b/trunk/drivers/net/wireless/ath/ath9k/pci.c index 8e9b826f878b..f088f4bf9a26 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/pci.c +++ b/trunk/drivers/net/wireless/ath/ath9k/pci.c @@ -96,6 +96,17 @@ static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data) return true; } +static void ath_pci_extn_synch_enable(struct ath_common *common) +{ + struct ath_softc *sc = (struct ath_softc *) common->priv; + struct pci_dev *pdev = to_pci_dev(sc->dev); + u8 lnkctl; + + pci_read_config_byte(pdev, sc->sc_ah->caps.pcie_lcr_offset, &lnkctl); + lnkctl |= PCI_EXP_LNKCTL_ES; + pci_write_config_byte(pdev, sc->sc_ah->caps.pcie_lcr_offset, lnkctl); +} + /* Need to be called after we discover btcoex capabilities */ static void ath_pci_aspm_init(struct ath_common *common) { @@ -142,6 +153,7 @@ static const struct ath_bus_ops ath_pci_bus_ops = { .ath_bus_type = ATH_PCI, .read_cachesize = ath_pci_read_cachesize, .eeprom_read = ath_pci_eeprom_read, + .extn_synch_en = ath_pci_extn_synch_enable, .aspm_init = ath_pci_aspm_init, }; @@ -287,7 +299,7 @@ static void ath_pci_remove(struct pci_dev *pdev) pci_release_region(pdev, 0); } -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_PM static int ath_pci_suspend(struct device *device) { @@ -333,15 +345,22 @@ static int ath_pci_resume(struct device *device) return 0; } -static SIMPLE_DEV_PM_OPS(ath9k_pm_ops, ath_pci_suspend, ath_pci_resume); +static const struct dev_pm_ops ath9k_pm_ops = { + .suspend = ath_pci_suspend, + .resume = ath_pci_resume, + .freeze = ath_pci_suspend, + .thaw = ath_pci_resume, + .poweroff = ath_pci_suspend, + .restore = ath_pci_resume, +}; #define ATH9K_PM_OPS (&ath9k_pm_ops) -#else /* !CONFIG_PM_SLEEP */ +#else /* !CONFIG_PM */ #define ATH9K_PM_OPS NULL -#endif /* !CONFIG_PM_SLEEP */ +#endif /* !CONFIG_PM */ MODULE_DEVICE_TABLE(pci, ath_pci_id_table); diff --git a/trunk/drivers/net/wireless/ath/ath9k/rc.c b/trunk/drivers/net/wireless/ath/ath9k/rc.c index 714558d1ba78..27ed80b54881 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/rc.c +++ b/trunk/drivers/net/wireless/ath/ath9k/rc.c @@ -982,6 +982,16 @@ static void ath_rc_update_per(struct ath_softc *sc, } } +static void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix, + int xretries, int retries, u8 per) +{ + struct ath_rc_stats *stats = &rc->rcstats[rix]; + + stats->xretries += xretries; + stats->retries += retries; + stats->per = per; +} + static void ath_rc_update_ht(struct ath_softc *sc, struct ath_rate_priv *ath_rc_priv, struct ieee80211_tx_info *tx_info, @@ -1055,6 +1065,14 @@ static void ath_rc_update_ht(struct ath_softc *sc, } +static void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate) +{ + struct ath_rc_stats *stats; + + stats = &rc->rcstats[final_rate]; + stats->success++; +} + static void ath_rc_tx_status(struct ath_softc *sc, struct ath_rate_priv *ath_rc_priv, struct sk_buff *skb) @@ -1332,25 +1350,7 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, } } -#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS) - -void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate) -{ - struct ath_rc_stats *stats; - - stats = &rc->rcstats[final_rate]; - stats->success++; -} - -void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix, - int xretries, int retries, u8 per) -{ - struct ath_rc_stats *stats = &rc->rcstats[rix]; - - stats->xretries += xretries; - stats->retries += retries; - stats->per = per; -} +#ifdef CONFIG_ATH9K_DEBUGFS static ssize_t read_file_rcstat(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -1428,17 +1428,10 @@ static void ath_rate_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir) { struct ath_rate_priv *rc = priv_sta; - rc->debugfs_rcstats = debugfs_create_file("rc_stats", S_IRUGO, - dir, rc, &fops_rcstat); -} - -static void ath_rate_remove_sta_debugfs(void *priv, void *priv_sta) -{ - struct ath_rate_priv *rc = priv_sta; - debugfs_remove(rc->debugfs_rcstats); + debugfs_create_file("rc_stats", S_IRUGO, dir, rc, &fops_rcstat); } -#endif /* CONFIG_MAC80211_DEBUGFS && CONFIG_ATH9K_DEBUGFS */ +#endif /* CONFIG_ATH9K_DEBUGFS */ static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) { @@ -1483,10 +1476,8 @@ static struct rate_control_ops ath_rate_ops = { .free = ath_rate_free, .alloc_sta = ath_rate_alloc_sta, .free_sta = ath_rate_free_sta, - -#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS) +#ifdef CONFIG_ATH9K_DEBUGFS .add_sta_debugfs = ath_rate_add_sta_debugfs, - .remove_sta_debugfs = ath_rate_remove_sta_debugfs, #endif }; diff --git a/trunk/drivers/net/wireless/ath/ath9k/rc.h b/trunk/drivers/net/wireless/ath/ath9k/rc.h index 267dbfcfaa96..268e67dc5fb2 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/rc.h +++ b/trunk/drivers/net/wireless/ath/ath9k/rc.h @@ -211,26 +211,10 @@ struct ath_rate_priv { struct ath_rateset neg_ht_rates; const struct ath_rate_table *rate_table; -#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS) struct dentry *debugfs_rcstats; struct ath_rc_stats rcstats[RATE_TABLE_SIZE]; -#endif }; -#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS) -void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate); -void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix, - int xretries, int retries, u8 per); -#else -static inline void ath_debug_stat_rc(struct ath_rate_priv *rc, int final_rate) -{ -} -static inline void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix, - int xretries, int retries, u8 per) -{ -} -#endif - #ifdef CONFIG_ATH9K_RATE_CONTROL int ath_rate_control_register(void); void ath_rate_control_unregister(void); diff --git a/trunk/drivers/net/wireless/ath/ath9k/xmit.c b/trunk/drivers/net/wireless/ath/ath9k/xmit.c index 90e48a0fafe5..1ffca7511fa8 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/xmit.c +++ b/trunk/drivers/net/wireless/ath/ath9k/xmit.c @@ -312,6 +312,7 @@ static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc) } bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list); + bf->bf_next = NULL; list_del(&bf->list); spin_unlock_bh(&sc->tx.txbuflock); @@ -393,7 +394,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0, seq_first; u32 ba[WME_BA_BMP_SIZE >> 5]; int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; - bool rc_update = true, isba; + bool rc_update = true; struct ieee80211_tx_rate rates[4]; struct ath_frame_info *fi; int nframes; @@ -437,17 +438,13 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; tid = ATH_AN_2_TID(an, tidno); seq_first = tid->seq_start; - isba = ts->ts_flags & ATH9K_TX_BA; /* * The hardware occasionally sends a tx status for the wrong TID. * In this case, the BA status cannot be considered valid and all * subframes need to be retransmitted - * - * Only BlockAcks have a TID and therefore normal Acks cannot be - * checked */ - if (isba && tidno != ts->tid) + if (tidno != ts->tid) txok = false; isaggr = bf_isaggr(bf); @@ -1262,7 +1259,7 @@ void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc, int tidno; for (tidno = 0, tid = &an->tid[tidno]; - tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { + tidno < WME_NUM_TID; tidno++, tid++) { if (!tid->sched) continue; @@ -1296,7 +1293,7 @@ void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an) int tidno; for (tidno = 0, tid = &an->tid[tidno]; - tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { + tidno < WME_NUM_TID; tidno++, tid++) { ac = tid->ac; txq = ac->txq; @@ -1353,10 +1350,10 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) struct ath_hw *ah = sc->sc_ah; struct ath9k_tx_queue_info qi; static const int subtype_txq_to_hwq[] = { - [IEEE80211_AC_BE] = ATH_TXQ_AC_BE, - [IEEE80211_AC_BK] = ATH_TXQ_AC_BK, - [IEEE80211_AC_VI] = ATH_TXQ_AC_VI, - [IEEE80211_AC_VO] = ATH_TXQ_AC_VO, + [WME_AC_BE] = ATH_TXQ_AC_BE, + [WME_AC_BK] = ATH_TXQ_AC_BK, + [WME_AC_VI] = ATH_TXQ_AC_VI, + [WME_AC_VO] = ATH_TXQ_AC_VO, }; int axq_qnum, i; @@ -2318,8 +2315,6 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) ath_txq_lock(sc, txq); - TX_STAT_INC(txq->axq_qnum, txprocdesc); - if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) { ath_txq_unlock(sc, txq); return; @@ -2447,7 +2442,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) int tidno, acno; for (tidno = 0, tid = &an->tid[tidno]; - tidno < IEEE80211_NUM_TIDS; + tidno < WME_NUM_TID; tidno++, tid++) { tid->an = an; tid->tidno = tidno; @@ -2465,7 +2460,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) } for (acno = 0, ac = &an->ac[acno]; - acno < IEEE80211_NUM_ACS; acno++, ac++) { + acno < WME_NUM_AC; acno++, ac++) { ac->sched = false; ac->txq = sc->tx.txq_map[acno]; INIT_LIST_HEAD(&ac->tid_q); @@ -2480,7 +2475,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an) int tidno; for (tidno = 0, tid = &an->tid[tidno]; - tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { + tidno < WME_NUM_TID; tidno++, tid++) { ac = tid->ac; txq = ac->txq; diff --git a/trunk/drivers/net/wireless/ath/carl9170/Kconfig b/trunk/drivers/net/wireless/ath/carl9170/Kconfig index 13a204598766..267d5dcf82dc 100644 --- a/trunk/drivers/net/wireless/ath/carl9170/Kconfig +++ b/trunk/drivers/net/wireless/ath/carl9170/Kconfig @@ -1,7 +1,6 @@ config CARL9170 tristate "Linux Community AR9170 802.11n USB support" depends on USB && MAC80211 && EXPERIMENTAL - select ATH_COMMON select FW_LOADER select CRC32 help diff --git a/trunk/drivers/net/wireless/ath/carl9170/fw.c b/trunk/drivers/net/wireless/ath/carl9170/fw.c index aaebecd19e59..24ac2876a733 100644 --- a/trunk/drivers/net/wireless/ath/carl9170/fw.c +++ b/trunk/drivers/net/wireless/ath/carl9170/fw.c @@ -28,6 +28,11 @@ #include "fwcmd.h" #include "version.h" +#define MAKE_STR(symbol) #symbol +#define TO_STR(symbol) MAKE_STR(symbol) +#define CARL9170FW_API_VER_STR TO_STR(CARL9170FW_API_MAX_VER) +MODULE_VERSION(CARL9170FW_API_VER_STR ":" CARL9170FW_VERSION_GIT); + static const u8 otus_magic[4] = { OTUS_MAGIC }; static const void *carl9170_fw_find_desc(struct ar9170 *ar, const u8 descid[4], diff --git a/trunk/drivers/net/wireless/ath/carl9170/rx.c b/trunk/drivers/net/wireless/ath/carl9170/rx.c index 876a773fd0b4..6d22382875bc 100644 --- a/trunk/drivers/net/wireless/ath/carl9170/rx.c +++ b/trunk/drivers/net/wireless/ath/carl9170/rx.c @@ -814,8 +814,6 @@ static void carl9170_rx_untie_data(struct ar9170 *ar, u8 *buf, int len) if (phy) carl9170_rx_phy_status(ar, phy, &status); - else - status.flag |= RX_FLAG_NO_SIGNAL_VAL; if (carl9170_handle_mpdu(ar, buf, mpdu_len, &status)) goto drop; diff --git a/trunk/drivers/net/wireless/brcm80211/Kconfig b/trunk/drivers/net/wireless/brcm80211/Kconfig index 1d92d874ebb6..c9d811eb6556 100644 --- a/trunk/drivers/net/wireless/brcm80211/Kconfig +++ b/trunk/drivers/net/wireless/brcm80211/Kconfig @@ -55,16 +55,13 @@ config BRCMFMAC_USB IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to use the driver for an USB wireless card. -config BRCM_TRACING - bool "Broadcom device tracing" - depends on BRCMSMAC || BRCMFMAC +config BRCMISCAN + bool "Broadcom I-Scan (OBSOLETE)" + depends on BRCMFMAC ---help--- - If you say Y here, the Broadcom wireless drivers will register - with ftrace to dump event information into the trace ringbuffer. - Tracing can be enabled at runtime to aid in debugging wireless - issues. This option adds a small amount of overhead when tracing - is disabled. If unsure, say Y to allow developers to better help - you when wireless problems occur. + This option enables the I-Scan method. By default fullmac uses the + new E-Scan method which uses less memory in firmware and gives no + limitation on the number of scan results. config BRCMDBG bool "Broadcom driver debug functions" diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/trunk/drivers/net/wireless/brcm80211/brcmfmac/Makefile index 1a6661a9f008..fe80b637c519 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/Makefile +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/Makefile @@ -25,7 +25,6 @@ obj-$(CONFIG_BRCMFMAC) += brcmfmac.o brcmfmac-objs += \ wl_cfg80211.o \ fwil.o \ - fweh.o \ dhd_cdc.o \ dhd_common.o \ dhd_linux.o diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 334ddab4a8c5..3b2c4c20e7fc 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -42,8 +42,7 @@ #ifdef CONFIG_BRCMFMAC_SDIO_OOB static irqreturn_t brcmf_sdio_irqhandler(int irq, void *dev_id) { - struct brcmf_bus *bus_if = dev_get_drvdata(dev_id); - struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; + struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(dev_id); brcmf_dbg(INTR, "oob intr triggered\n"); @@ -72,7 +71,7 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev) brcmf_dbg(ERROR, "requesting irq %d\n", sdiodev->irq); ret = request_irq(sdiodev->irq, brcmf_sdio_irqhandler, sdiodev->irq_flags, "brcmf_oob_intr", - &sdiodev->func[1]->dev); + &sdiodev->func[1]->card->dev); if (ret != 0) return ret; spin_lock_init(&sdiodev->irq_en_lock); @@ -85,8 +84,6 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev) return ret; sdiodev->irq_wake = true; - sdio_claim_host(sdiodev->func[1]); - /* must configure SDIO_CCCR_IENx to enable irq */ data = brcmf_sdio_regrb(sdiodev, SDIO_CCCR_IENx, &ret); data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1; @@ -98,8 +95,6 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev) data |= SDIO_SEPINT_ACT_HI; brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret); - sdio_release_host(sdiodev->func[1]); - return 0; } @@ -107,16 +102,14 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev) { brcmf_dbg(TRACE, "Entering\n"); - sdio_claim_host(sdiodev->func[1]); brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL); brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL); - sdio_release_host(sdiodev->func[1]); if (sdiodev->irq_wake) { disable_irq_wake(sdiodev->irq); sdiodev->irq_wake = false; } - free_irq(sdiodev->irq, &sdiodev->func[1]->dev); + free_irq(sdiodev->irq, &sdiodev->func[1]->card->dev); sdiodev->irq_en = false; return 0; @@ -124,8 +117,7 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev) #else /* CONFIG_BRCMFMAC_SDIO_OOB */ static void brcmf_sdio_irqhandler(struct sdio_func *func) { - struct brcmf_bus *bus_if = dev_get_drvdata(&func->dev); - struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; + struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev); brcmf_dbg(INTR, "ib intr triggered\n"); @@ -257,7 +249,9 @@ u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) int retval; brcmf_dbg(INFO, "addr:0x%08x\n", addr); + sdio_claim_host(sdiodev->func[1]); retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false); + sdio_release_host(sdiodev->func[1]); brcmf_dbg(INFO, "data:0x%02x\n", data); if (ret) @@ -272,7 +266,9 @@ u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) int retval; brcmf_dbg(INFO, "addr:0x%08x\n", addr); + sdio_claim_host(sdiodev->func[1]); retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false); + sdio_release_host(sdiodev->func[1]); brcmf_dbg(INFO, "data:0x%08x\n", data); if (ret) @@ -287,7 +283,9 @@ void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr, int retval; brcmf_dbg(INFO, "addr:0x%08x, data:0x%02x\n", addr, data); + sdio_claim_host(sdiodev->func[1]); retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true); + sdio_release_host(sdiodev->func[1]); if (ret) *ret = retval; @@ -299,7 +297,9 @@ void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, int retval; brcmf_dbg(INFO, "addr:0x%08x, data:0x%08x\n", addr, data); + sdio_claim_host(sdiodev->func[1]); retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true); + sdio_release_host(sdiodev->func[1]); if (ret) *ret = retval; @@ -364,6 +364,8 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", fn, addr, pkt->len); + sdio_claim_host(sdiodev->func[1]); + width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr); if (err) @@ -374,6 +376,8 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, fn, addr, pkt); done: + sdio_release_host(sdiodev->func[1]); + return err; } @@ -387,6 +391,8 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", fn, addr, pktq->qlen); + sdio_claim_host(sdiodev->func[1]); + width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr); if (err) @@ -397,6 +403,8 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, pktq); done: + sdio_release_host(sdiodev->func[1]); + return err; } @@ -438,6 +446,8 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, if (flags & SDIO_REQ_ASYNC) return -ENOTSUPP; + sdio_claim_host(sdiodev->func[1]); + if (bar0 != sdiodev->sbwad) { err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0); if (err) @@ -457,6 +467,8 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, addr, pkt); done: + sdio_release_host(sdiodev->func[1]); + return err; } @@ -498,8 +510,10 @@ int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn) brcmf_dbg(TRACE, "Enter\n"); /* issue abort cmd52 command through F0 */ + sdio_claim_host(sdiodev->func[1]); brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, SDIO_FUNC_0, SDIO_CCCR_ABORT, &t_func); + sdio_release_host(sdiodev->func[1]); brcmf_dbg(TRACE, "Exit\n"); return 0; @@ -516,6 +530,9 @@ int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) regs = SI_ENUM_BASE; + /* Report the BAR, to fix if needed */ + sdiodev->sbwad = SI_ENUM_BASE; + /* try to attach to the target device */ sdiodev->bus = brcmf_sdbrcm_probe(regs, sdiodev); if (!sdiodev->bus) { @@ -534,8 +551,6 @@ EXPORT_SYMBOL(brcmf_sdio_probe); int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev) { - sdiodev->bus_if->state = BRCMF_BUS_DOWN; - if (sdiodev->bus) { brcmf_sdbrcm_disconnect(sdiodev->bus); sdiodev->bus = NULL; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index a80050223710..c3247d5b3c22 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -372,7 +372,9 @@ static int brcmf_sdioh_enablefuncs(struct brcmf_sdio_dev *sdiodev) } /* Enable Function 1 */ + sdio_claim_host(sdiodev->func[1]); err_ret = sdio_enable_func(sdiodev->func[1]); + sdio_release_host(sdiodev->func[1]); if (err_ret) brcmf_dbg(ERROR, "Failed to enable F1 Err: 0x%08x\n", err_ret); @@ -391,14 +393,16 @@ int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev) sdiodev->num_funcs = 2; sdio_claim_host(sdiodev->func[1]); - err_ret = sdio_set_block_size(sdiodev->func[1], SDIO_FUNC1_BLOCKSIZE); + sdio_release_host(sdiodev->func[1]); if (err_ret) { brcmf_dbg(ERROR, "Failed to set F1 blocksize\n"); goto out; } + sdio_claim_host(sdiodev->func[2]); err_ret = sdio_set_block_size(sdiodev->func[2], SDIO_FUNC2_BLOCKSIZE); + sdio_release_host(sdiodev->func[2]); if (err_ret) { brcmf_dbg(ERROR, "Failed to set F2 blocksize\n"); goto out; @@ -407,7 +411,6 @@ int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev) brcmf_sdioh_enablefuncs(sdiodev); out: - sdio_release_host(sdiodev->func[1]); brcmf_dbg(TRACE, "Done\n"); return err_ret; } @@ -456,106 +459,95 @@ static inline int brcmf_sdio_getintrcfg(struct brcmf_sdio_dev *sdiodev) #endif /* CONFIG_BRCMFMAC_SDIO_OOB */ static int brcmf_ops_sdio_probe(struct sdio_func *func, - const struct sdio_device_id *id) + const struct sdio_device_id *id) { - int err; + int ret = 0; struct brcmf_sdio_dev *sdiodev; struct brcmf_bus *bus_if; brcmf_dbg(TRACE, "Enter\n"); - brcmf_dbg(TRACE, "Class=%x\n", func->class); - brcmf_dbg(TRACE, "sdio vendor ID: 0x%04x\n", func->vendor); - brcmf_dbg(TRACE, "sdio device ID: 0x%04x\n", func->device); - brcmf_dbg(TRACE, "Function#: %d\n", func->num); - - /* Consume func num 1 but dont do anything with it. */ - if (func->num == 1) - return 0; - - /* Ignore anything but func 2 */ - if (func->num != 2) - return -ENODEV; - - bus_if = kzalloc(sizeof(struct brcmf_bus), GFP_KERNEL); - if (!bus_if) - return -ENOMEM; - sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL); - if (!sdiodev) { - kfree(bus_if); - return -ENOMEM; + brcmf_dbg(TRACE, "func->class=%x\n", func->class); + brcmf_dbg(TRACE, "sdio_vendor: 0x%04x\n", func->vendor); + brcmf_dbg(TRACE, "sdio_device: 0x%04x\n", func->device); + brcmf_dbg(TRACE, "Function#: 0x%04x\n", func->num); + + if (func->num == 1) { + if (dev_get_drvdata(&func->card->dev)) { + brcmf_dbg(ERROR, "card private drvdata occupied\n"); + return -ENXIO; + } + bus_if = kzalloc(sizeof(struct brcmf_bus), GFP_KERNEL); + if (!bus_if) + return -ENOMEM; + sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL); + if (!sdiodev) { + kfree(bus_if); + return -ENOMEM; + } + sdiodev->func[0] = func; + sdiodev->func[1] = func; + sdiodev->bus_if = bus_if; + bus_if->bus_priv.sdio = sdiodev; + bus_if->type = SDIO_BUS; + bus_if->align = BRCMF_SDALIGN; + dev_set_drvdata(&func->card->dev, sdiodev); + + atomic_set(&sdiodev->suspend, false); + init_waitqueue_head(&sdiodev->request_byte_wait); + init_waitqueue_head(&sdiodev->request_word_wait); + init_waitqueue_head(&sdiodev->request_chain_wait); + init_waitqueue_head(&sdiodev->request_buffer_wait); } - sdiodev->func[0] = func->card->sdio_func[0]; - sdiodev->func[1] = func->card->sdio_func[0]; - sdiodev->func[2] = func; + if (func->num == 2) { + sdiodev = dev_get_drvdata(&func->card->dev); + if ((!sdiodev) || (sdiodev->func[1]->card != func->card)) + return -ENODEV; - sdiodev->bus_if = bus_if; - bus_if->bus_priv.sdio = sdiodev; - bus_if->align = BRCMF_SDALIGN; - dev_set_drvdata(&func->dev, bus_if); - dev_set_drvdata(&sdiodev->func[1]->dev, bus_if); - sdiodev->dev = &sdiodev->func[1]->dev; + ret = brcmf_sdio_getintrcfg(sdiodev); + if (ret) + return ret; + sdiodev->func[2] = func; - atomic_set(&sdiodev->suspend, false); - init_waitqueue_head(&sdiodev->request_byte_wait); - init_waitqueue_head(&sdiodev->request_word_wait); - init_waitqueue_head(&sdiodev->request_chain_wait); - init_waitqueue_head(&sdiodev->request_buffer_wait); - err = brcmf_sdio_getintrcfg(sdiodev); - if (err) - goto fail; - - brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_probe...\n"); - err = brcmf_sdio_probe(sdiodev); - if (err) { - brcmf_dbg(ERROR, "F2 error, probe failed %d...\n", err); - goto fail; + bus_if = sdiodev->bus_if; + sdiodev->dev = &func->dev; + dev_set_drvdata(&func->dev, bus_if); + + brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_probe...\n"); + ret = brcmf_sdio_probe(sdiodev); } - brcmf_dbg(TRACE, "F2 init completed...\n"); - return 0; -fail: - dev_set_drvdata(&func->dev, NULL); - dev_set_drvdata(&sdiodev->func[1]->dev, NULL); - kfree(sdiodev); - kfree(bus_if); - return err; + return ret; } static void brcmf_ops_sdio_remove(struct sdio_func *func) { struct brcmf_bus *bus_if; struct brcmf_sdio_dev *sdiodev; - brcmf_dbg(TRACE, "Enter\n"); - brcmf_dbg(TRACE, "sdio vendor ID: 0x%04x\n", func->vendor); - brcmf_dbg(TRACE, "sdio device ID: 0x%04x\n", func->device); - brcmf_dbg(TRACE, "Function: %d\n", func->num); + brcmf_dbg(INFO, "func->class=%x\n", func->class); + brcmf_dbg(INFO, "sdio_vendor: 0x%04x\n", func->vendor); + brcmf_dbg(INFO, "sdio_device: 0x%04x\n", func->device); + brcmf_dbg(INFO, "Function#: 0x%04x\n", func->num); - if (func->num != 1 && func->num != 2) - return; - - bus_if = dev_get_drvdata(&func->dev); - if (bus_if) { + if (func->num == 2) { + bus_if = dev_get_drvdata(&func->dev); sdiodev = bus_if->bus_priv.sdio; + brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_remove...\n"); brcmf_sdio_remove(sdiodev); - - dev_set_drvdata(&sdiodev->func[1]->dev, NULL); - dev_set_drvdata(&sdiodev->func[2]->dev, NULL); - + dev_set_drvdata(&func->card->dev, NULL); + dev_set_drvdata(&func->dev, NULL); kfree(bus_if); kfree(sdiodev); } - - brcmf_dbg(TRACE, "Exit\n"); } #ifdef CONFIG_PM_SLEEP static int brcmf_sdio_suspend(struct device *dev) { mmc_pm_flag_t sdio_flags; - struct brcmf_bus *bus_if = dev_get_drvdata(dev); - struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; + struct sdio_func *func = dev_to_sdio_func(dev); + struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev); int ret = 0; brcmf_dbg(TRACE, "\n"); @@ -581,8 +573,8 @@ static int brcmf_sdio_suspend(struct device *dev) static int brcmf_sdio_resume(struct device *dev) { - struct brcmf_bus *bus_if = dev_get_drvdata(dev); - struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; + struct sdio_func *func = dev_to_sdio_func(dev); + struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev); brcmf_sdio_wdtmr_enable(sdiodev, true); atomic_set(&sdiodev->suspend, false); diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index 24bc4e3e162b..8704daa2758f 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd.h @@ -23,8 +23,6 @@ #define BRCMF_VERSION_STR "4.218.248.5" -#include "fweh.h" - /******************************************************************************* * IO codes that are interpreted by dongle firmware ******************************************************************************/ @@ -40,11 +38,8 @@ #define BRCMF_C_GET_SSID 25 #define BRCMF_C_SET_SSID 26 #define BRCMF_C_GET_CHANNEL 29 -#define BRCMF_C_SET_CHANNEL 30 #define BRCMF_C_GET_SRL 31 -#define BRCMF_C_SET_SRL 32 #define BRCMF_C_GET_LRL 33 -#define BRCMF_C_SET_LRL 34 #define BRCMF_C_GET_RADIO 37 #define BRCMF_C_SET_RADIO 38 #define BRCMF_C_GET_PHYTYPE 39 @@ -63,7 +58,6 @@ #define BRCMF_C_SET_COUNTRY 84 #define BRCMF_C_GET_PM 85 #define BRCMF_C_SET_PM 86 -#define BRCMF_C_GET_CURR_RATESET 114 #define BRCMF_C_GET_AP 117 #define BRCMF_C_SET_AP 118 #define BRCMF_C_GET_RSSI 127 @@ -71,7 +65,6 @@ #define BRCMF_C_SET_WSEC 134 #define BRCMF_C_GET_PHY_NOISE 135 #define BRCMF_C_GET_BSS_INFO 136 -#define BRCMF_C_GET_PHYLIST 180 #define BRCMF_C_SET_SCAN_CHANNEL_TIME 185 #define BRCMF_C_SET_SCAN_UNASSOC_TIME 187 #define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON 201 @@ -107,8 +100,29 @@ #define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff #define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16 +#define BRCMF_SCAN_ACTION_START 1 +#define BRCMF_SCAN_ACTION_CONTINUE 2 +#define WL_SCAN_ACTION_ABORT 3 + +#define BRCMF_ISCAN_REQ_VERSION 1 + +/* brcmf_iscan_results status values */ +#define BRCMF_SCAN_RESULTS_SUCCESS 0 +#define BRCMF_SCAN_RESULTS_PARTIAL 1 +#define BRCMF_SCAN_RESULTS_PENDING 2 +#define BRCMF_SCAN_RESULTS_ABORTED 3 +#define BRCMF_SCAN_RESULTS_NO_MEM 4 + +/* Indicates this key is using soft encrypt */ +#define WL_SOFT_KEY (1 << 0) /* primary (ie tx) key */ #define BRCMF_PRIMARY_KEY (1 << 1) +/* Reserved for backward compat */ +#define WL_KF_RES_4 (1 << 4) +/* Reserved for backward compat */ +#define WL_KF_RES_5 (1 << 5) +/* Indicates a group key for a IBSS PEER */ +#define WL_IBSS_PEER_GROUP_KEY (1 << 6) /* For supporting multiple interfaces */ #define BRCMF_MAX_IFS 16 @@ -116,6 +130,10 @@ #define DOT11_BSSTYPE_ANY 2 #define DOT11_MAX_DEFAULT_KEYS 4 +#define BRCMF_EVENT_MSG_LINK 0x01 +#define BRCMF_EVENT_MSG_FLUSHTXQ 0x02 +#define BRCMF_EVENT_MSG_GROUP 0x04 + #define BRCMF_ESCAN_REQ_VERSION 1 #define WLC_BSS_RSSI_ON_CHANNEL 0x0002 @@ -123,6 +141,108 @@ #define BRCMF_MAXRATES_IN_SET 16 /* max # of rates in rateset */ #define BRCMF_STA_ASSOC 0x10 /* Associated */ +struct brcmf_event_msg { + __be16 version; + __be16 flags; + __be32 event_type; + __be32 status; + __be32 reason; + __be32 auth_type; + __be32 datalen; + u8 addr[ETH_ALEN]; + char ifname[IFNAMSIZ]; + u8 ifidx; + u8 bsscfgidx; +} __packed; + +struct brcm_ethhdr { + u16 subtype; + u16 length; + u8 version; + u8 oui[3]; + u16 usr_subtype; +} __packed; + +struct brcmf_event { + struct ethhdr eth; + struct brcm_ethhdr hdr; + struct brcmf_event_msg msg; +} __packed; + +/* event codes sent by the dongle to this driver */ +#define BRCMF_E_SET_SSID 0 +#define BRCMF_E_JOIN 1 +#define BRCMF_E_START 2 +#define BRCMF_E_AUTH 3 +#define BRCMF_E_AUTH_IND 4 +#define BRCMF_E_DEAUTH 5 +#define BRCMF_E_DEAUTH_IND 6 +#define BRCMF_E_ASSOC 7 +#define BRCMF_E_ASSOC_IND 8 +#define BRCMF_E_REASSOC 9 +#define BRCMF_E_REASSOC_IND 10 +#define BRCMF_E_DISASSOC 11 +#define BRCMF_E_DISASSOC_IND 12 +#define BRCMF_E_QUIET_START 13 +#define BRCMF_E_QUIET_END 14 +#define BRCMF_E_BEACON_RX 15 +#define BRCMF_E_LINK 16 +#define BRCMF_E_MIC_ERROR 17 +#define BRCMF_E_NDIS_LINK 18 +#define BRCMF_E_ROAM 19 +#define BRCMF_E_TXFAIL 20 +#define BRCMF_E_PMKID_CACHE 21 +#define BRCMF_E_RETROGRADE_TSF 22 +#define BRCMF_E_PRUNE 23 +#define BRCMF_E_AUTOAUTH 24 +#define BRCMF_E_EAPOL_MSG 25 +#define BRCMF_E_SCAN_COMPLETE 26 +#define BRCMF_E_ADDTS_IND 27 +#define BRCMF_E_DELTS_IND 28 +#define BRCMF_E_BCNSENT_IND 29 +#define BRCMF_E_BCNRX_MSG 30 +#define BRCMF_E_BCNLOST_MSG 31 +#define BRCMF_E_ROAM_PREP 32 +#define BRCMF_E_PFN_NET_FOUND 33 +#define BRCMF_E_PFN_NET_LOST 34 +#define BRCMF_E_RESET_COMPLETE 35 +#define BRCMF_E_JOIN_START 36 +#define BRCMF_E_ROAM_START 37 +#define BRCMF_E_ASSOC_START 38 +#define BRCMF_E_IBSS_ASSOC 39 +#define BRCMF_E_RADIO 40 +#define BRCMF_E_PSM_WATCHDOG 41 +#define BRCMF_E_PROBREQ_MSG 44 +#define BRCMF_E_SCAN_CONFIRM_IND 45 +#define BRCMF_E_PSK_SUP 46 +#define BRCMF_E_COUNTRY_CODE_CHANGED 47 +#define BRCMF_E_EXCEEDED_MEDIUM_TIME 48 +#define BRCMF_E_ICV_ERROR 49 +#define BRCMF_E_UNICAST_DECODE_ERROR 50 +#define BRCMF_E_MULTICAST_DECODE_ERROR 51 +#define BRCMF_E_TRACE 52 +#define BRCMF_E_IF 54 +#define BRCMF_E_RSSI 56 +#define BRCMF_E_PFN_SCAN_COMPLETE 57 +#define BRCMF_E_EXTLOG_MSG 58 +#define BRCMF_E_ACTION_FRAME 59 +#define BRCMF_E_ACTION_FRAME_COMPLETE 60 +#define BRCMF_E_PRE_ASSOC_IND 61 +#define BRCMF_E_PRE_REASSOC_IND 62 +#define BRCMF_E_CHANNEL_ADOPTED 63 +#define BRCMF_E_AP_STARTED 64 +#define BRCMF_E_DFS_AP_STOP 65 +#define BRCMF_E_DFS_AP_RESUME 66 +#define BRCMF_E_RESERVED1 67 +#define BRCMF_E_RESERVED2 68 +#define BRCMF_E_ESCAN_RESULT 69 +#define BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE 70 +#define BRCMF_E_DCS_REQUEST 73 + +#define BRCMF_E_FIFO_CREDIT_MAP 74 + +#define BRCMF_E_LAST 75 + #define BRCMF_E_STATUS_SUCCESS 0 #define BRCMF_E_STATUS_FAIL 1 #define BRCMF_E_STATUS_TIMEOUT 2 @@ -283,7 +403,7 @@ struct brcm_rateset_le { /* # rates in this set */ __le32 count; /* rates in 500kbps units w/hi bit set if basic */ - u8 rates[BRCMF_MAXRATES_IN_SET]; + u8 rates[WL_NUMRATES]; }; struct brcmf_ssid { @@ -332,6 +452,14 @@ struct brcmf_scan_params_le { __le16 channel_list[1]; /* list of chanspecs */ }; +/* incremental scan struct */ +struct brcmf_iscan_params_le { + __le32 version; + __le16 action; + __le16 scan_duration; + struct brcmf_scan_params_le params_le; +}; + struct brcmf_scan_results { u32 buflen; u32 version; @@ -339,6 +467,12 @@ struct brcmf_scan_results { struct brcmf_bss_info_le bss_info_le[]; }; +struct brcmf_scan_results_le { + __le32 buflen; + __le32 version; + __le32 count; +}; + struct brcmf_escan_params_le { __le32 version; __le16 action; @@ -374,6 +508,23 @@ struct brcmf_join_params { struct brcmf_assoc_params_le params_le; }; +/* incremental scan results struct */ +struct brcmf_iscan_results { + union { + u32 status; + __le32 status_le; + }; + union { + struct brcmf_scan_results results; + struct brcmf_scan_results_le results_le; + }; +}; + +/* size of brcmf_iscan_results not including variable length array */ +#define BRCMF_ISCAN_RESULTS_FIXED_SIZE \ + (sizeof(struct brcmf_scan_results) + \ + offsetof(struct brcmf_iscan_results, results)) + struct brcmf_wsec_key { u32 index; /* key index */ u32 len; /* key length */ @@ -510,11 +661,10 @@ struct brcmf_pub { struct mutex proto_block; unsigned char proto_buf[BRCMF_DCMD_MAXLEN]; + struct work_struct setmacaddr_work; + struct work_struct multicast_work; u8 macvalue[ETH_ALEN]; atomic_t pend_8021x_cnt; - wait_queue_head_t pend_8021x_wait; - - struct brcmf_fweh_info fweh; #ifdef DEBUG struct dentry *dbgfs_dir; #endif @@ -551,8 +701,6 @@ struct brcmf_if { struct brcmf_cfg80211_vif *vif; struct net_device *ndev; struct net_device_stats stats; - struct work_struct setmacaddr_work; - struct work_struct multicast_work; int idx; s32 bssidx; u8 mac_addr[ETH_ALEN]; @@ -566,6 +714,9 @@ static inline s32 brcmf_ndev_bssidx(struct net_device *ndev) extern const struct bcmevent_name bcmevent_names[]; +extern uint brcmf_c_mkiovar(char *name, char *data, uint datalen, + char *buf, uint len); + extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev); /* Return pointer to interface name */ @@ -577,9 +728,14 @@ extern int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf, uint len); +extern int brcmf_ifname2idx(struct brcmf_pub *drvr, char *name); +extern int brcmf_c_host_event(struct brcmf_pub *drvr, int *idx, + void *pktdata, struct brcmf_event_msg *, + void **data_ptr); + extern int brcmf_net_attach(struct brcmf_if *ifp); -extern struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, int ifidx, - s32 bssidx, char *name, u8 *mac_addr); +extern struct brcmf_if *brcmf_add_if(struct device *dev, int ifidx, s32 bssidx, + char *name, u8 *mac_addr); extern void brcmf_del_if(struct brcmf_pub *drvr, int ifidx); #endif /* _BRCMF_H_ */ diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h index b8f248797f62..265580f5b270 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h @@ -45,6 +45,7 @@ struct brcmf_bus_dcmd { /* interface structure between common and bus layer */ struct brcmf_bus { + u8 type; /* bus type */ union { struct brcmf_sdio_dev *sdio; struct brcmf_usbdev *usb; @@ -84,7 +85,7 @@ extern bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, struct sk_buff *pkt, int prec); /* Receive frame for delivery to OS. Callee disposes of rxp. */ -extern void brcmf_rx_frame(struct device *dev, u8 ifidx, +extern void brcmf_rx_frame(struct device *dev, int ifidx, struct sk_buff_head *rxlist); static inline void brcmf_rx_packet(struct device *dev, int ifidx, struct sk_buff *pkt) diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c index 87536d38a4ca..b9d8a5adfd43 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c @@ -23,6 +23,8 @@ #include #include +#include +#include #include #include @@ -275,6 +277,76 @@ int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, return ret; } +int +brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx, struct brcmf_dcmd *dcmd, + int len) +{ + struct brcmf_proto *prot = drvr->prot; + int ret = -1; + + if (drvr->bus_if->state == BRCMF_BUS_DOWN) { + brcmf_dbg(ERROR, "bus is down. we have nothing to do.\n"); + return ret; + } + mutex_lock(&drvr->proto_block); + + brcmf_dbg(TRACE, "Enter\n"); + + if (len > BRCMF_DCMD_MAXLEN) + goto done; + + if (prot->pending == true) { + brcmf_dbg(TRACE, "CDC packet is pending!!!! cmd=0x%x (%lu) lastcmd=0x%x (%lu)\n", + dcmd->cmd, (unsigned long)dcmd->cmd, prot->lastcmd, + (unsigned long)prot->lastcmd); + if (dcmd->cmd == BRCMF_C_SET_VAR || + dcmd->cmd == BRCMF_C_GET_VAR) + brcmf_dbg(TRACE, "iovar cmd=%s\n", (char *)dcmd->buf); + + goto done; + } + + prot->pending = true; + prot->lastcmd = dcmd->cmd; + if (dcmd->set) + ret = brcmf_proto_cdc_set_dcmd(drvr, ifidx, dcmd->cmd, + dcmd->buf, len); + else { + ret = brcmf_proto_cdc_query_dcmd(drvr, ifidx, dcmd->cmd, + dcmd->buf, len); + if (ret > 0) + dcmd->used = ret - + sizeof(struct brcmf_proto_cdc_dcmd); + } + + if (ret >= 0) + ret = 0; + else { + struct brcmf_proto_cdc_dcmd *msg = &prot->msg; + /* len == needed when set/query fails from dongle */ + dcmd->needed = le32_to_cpu(msg->len); + } + + /* Intercept the wme_dp dongle cmd here */ + if (!ret && dcmd->cmd == BRCMF_C_SET_VAR && + !strcmp(dcmd->buf, "wme_dp")) { + int slen; + __le32 val = 0; + + slen = strlen("wme_dp") + 1; + if (len >= (int)(slen + sizeof(int))) + memcpy(&val, (char *)dcmd->buf + slen, sizeof(int)); + drvr->wme_dp = (u8) le32_to_cpu(val); + } + + prot->pending = false; + +done: + mutex_unlock(&drvr->proto_block); + + return ret; +} + static bool pkt_sum_needed(struct sk_buff *skb) { return skb->ip_summed == CHECKSUM_PARTIAL; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index eee7175f1515..866b66995bb0 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c @@ -18,7 +18,10 @@ #include #include +#include #include +#include +#include #include #include #include "dhd.h" @@ -27,6 +30,9 @@ #include "dhd_dbg.h" #include "fwil.h" +#define BRCM_OUI "\x00\x10\x18" +#define DOT11_OUI_LEN 3 +#define BCMILCP_BCM_SUBTYPE_EVENT 1 #define PKTFILTER_BUF_SIZE 128 #define BRCMF_ARPOL_MODE 0xb /* agent|snoop|peer_autoreply */ #define BRCMF_DEFAULT_BCN_TIMEOUT 3 @@ -34,6 +40,12 @@ #define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40 #define BRCMF_DEFAULT_PACKET_FILTER "100 0 0 0 0x01 0x00" +#define MSGTRACE_VERSION 1 + +#define BRCMF_PKT_FILTER_FIXED_LEN offsetof(struct brcmf_pkt_filter_le, u) +#define BRCMF_PKT_FILTER_PATTERN_FIXED_LEN \ + offsetof(struct brcmf_pkt_filter_pattern_le, mask_and_pattern) + #ifdef DEBUG static const char brcmf_version[] = "Dongle Host Driver, version " BRCMF_VERSION_STR "\nCompiled on " @@ -43,6 +55,43 @@ static const char brcmf_version[] = "Dongle Host Driver, version " BRCMF_VERSION_STR; #endif +/* Message trace header */ +struct msgtrace_hdr { + u8 version; + u8 spare; + __be16 len; /* Len of the trace */ + __be32 seqnum; /* Sequence number of message. Useful + * if the messsage has been lost + * because of DMA error or a bus reset + * (ex: SDIO Func2) + */ + __be32 discarded_bytes; /* Number of discarded bytes because of + trace overflow */ + __be32 discarded_printf; /* Number of discarded printf + because of trace overflow */ +} __packed; + + +uint +brcmf_c_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen) +{ + uint len; + + len = strlen(name) + 1; + + if ((len + datalen) > buflen) + return 0; + + strncpy(buf, name, buflen); + + /* append data onto the end of the name string */ + if (data && datalen) { + memcpy(&buf[len], data, datalen); + len += datalen; + } + + return len; +} bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, struct sk_buff *pkt, int prec) @@ -94,6 +143,405 @@ bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, return p != NULL; } +#ifdef DEBUG +static void +brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data) +{ + uint i, status, reason; + bool group = false, flush_txq = false, link = false; + char *auth_str, *event_name; + unsigned char *buf; + char err_msg[256], eabuf[ETHER_ADDR_STR_LEN]; + static struct { + uint event; + char *event_name; + } event_names[] = { + { + BRCMF_E_SET_SSID, "SET_SSID"}, { + BRCMF_E_JOIN, "JOIN"}, { + BRCMF_E_START, "START"}, { + BRCMF_E_AUTH, "AUTH"}, { + BRCMF_E_AUTH_IND, "AUTH_IND"}, { + BRCMF_E_DEAUTH, "DEAUTH"}, { + BRCMF_E_DEAUTH_IND, "DEAUTH_IND"}, { + BRCMF_E_ASSOC, "ASSOC"}, { + BRCMF_E_ASSOC_IND, "ASSOC_IND"}, { + BRCMF_E_REASSOC, "REASSOC"}, { + BRCMF_E_REASSOC_IND, "REASSOC_IND"}, { + BRCMF_E_DISASSOC, "DISASSOC"}, { + BRCMF_E_DISASSOC_IND, "DISASSOC_IND"}, { + BRCMF_E_QUIET_START, "START_QUIET"}, { + BRCMF_E_QUIET_END, "END_QUIET"}, { + BRCMF_E_BEACON_RX, "BEACON_RX"}, { + BRCMF_E_LINK, "LINK"}, { + BRCMF_E_MIC_ERROR, "MIC_ERROR"}, { + BRCMF_E_NDIS_LINK, "NDIS_LINK"}, { + BRCMF_E_ROAM, "ROAM"}, { + BRCMF_E_TXFAIL, "TXFAIL"}, { + BRCMF_E_PMKID_CACHE, "PMKID_CACHE"}, { + BRCMF_E_RETROGRADE_TSF, "RETROGRADE_TSF"}, { + BRCMF_E_PRUNE, "PRUNE"}, { + BRCMF_E_AUTOAUTH, "AUTOAUTH"}, { + BRCMF_E_EAPOL_MSG, "EAPOL_MSG"}, { + BRCMF_E_SCAN_COMPLETE, "SCAN_COMPLETE"}, { + BRCMF_E_ADDTS_IND, "ADDTS_IND"}, { + BRCMF_E_DELTS_IND, "DELTS_IND"}, { + BRCMF_E_BCNSENT_IND, "BCNSENT_IND"}, { + BRCMF_E_BCNRX_MSG, "BCNRX_MSG"}, { + BRCMF_E_BCNLOST_MSG, "BCNLOST_MSG"}, { + BRCMF_E_ROAM_PREP, "ROAM_PREP"}, { + BRCMF_E_PFN_NET_FOUND, "PNO_NET_FOUND"}, { + BRCMF_E_PFN_NET_LOST, "PNO_NET_LOST"}, { + BRCMF_E_RESET_COMPLETE, "RESET_COMPLETE"}, { + BRCMF_E_JOIN_START, "JOIN_START"}, { + BRCMF_E_ROAM_START, "ROAM_START"}, { + BRCMF_E_ASSOC_START, "ASSOC_START"}, { + BRCMF_E_IBSS_ASSOC, "IBSS_ASSOC"}, { + BRCMF_E_RADIO, "RADIO"}, { + BRCMF_E_PSM_WATCHDOG, "PSM_WATCHDOG"}, { + BRCMF_E_PROBREQ_MSG, "PROBREQ_MSG"}, { + BRCMF_E_SCAN_CONFIRM_IND, "SCAN_CONFIRM_IND"}, { + BRCMF_E_PSK_SUP, "PSK_SUP"}, { + BRCMF_E_COUNTRY_CODE_CHANGED, "COUNTRY_CODE_CHANGED"}, { + BRCMF_E_EXCEEDED_MEDIUM_TIME, "EXCEEDED_MEDIUM_TIME"}, { + BRCMF_E_ICV_ERROR, "ICV_ERROR"}, { + BRCMF_E_UNICAST_DECODE_ERROR, "UNICAST_DECODE_ERROR"}, { + BRCMF_E_MULTICAST_DECODE_ERROR, "MULTICAST_DECODE_ERROR"}, { + BRCMF_E_TRACE, "TRACE"}, { + BRCMF_E_ACTION_FRAME, "ACTION FRAME"}, { + BRCMF_E_ACTION_FRAME_COMPLETE, "ACTION FRAME TX COMPLETE"}, { + BRCMF_E_IF, "IF"}, { + BRCMF_E_RSSI, "RSSI"}, { + BRCMF_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE"}, { + BRCMF_E_ESCAN_RESULT, "ESCAN_RESULT"} + }; + uint event_type, flags, auth_type, datalen; + static u32 seqnum_prev; + struct msgtrace_hdr hdr; + u32 nblost; + char *s, *p; + + event_type = be32_to_cpu(event->event_type); + flags = be16_to_cpu(event->flags); + status = be32_to_cpu(event->status); + reason = be32_to_cpu(event->reason); + auth_type = be32_to_cpu(event->auth_type); + datalen = be32_to_cpu(event->datalen); + /* debug dump of event messages */ + sprintf(eabuf, "%pM", event->addr); + + event_name = "UNKNOWN"; + for (i = 0; i < ARRAY_SIZE(event_names); i++) { + if (event_names[i].event == event_type) + event_name = event_names[i].event_name; + } + + brcmf_dbg(EVENT, "EVENT: %s, event ID = %d\n", event_name, event_type); + brcmf_dbg(EVENT, "flags 0x%04x, status %d, reason %d, auth_type %d MAC %s\n", + flags, status, reason, auth_type, eabuf); + + if (flags & BRCMF_EVENT_MSG_LINK) + link = true; + if (flags & BRCMF_EVENT_MSG_GROUP) + group = true; + if (flags & BRCMF_EVENT_MSG_FLUSHTXQ) + flush_txq = true; + + switch (event_type) { + case BRCMF_E_START: + case BRCMF_E_DEAUTH: + case BRCMF_E_DISASSOC: + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf); + break; + + case BRCMF_E_ASSOC_IND: + case BRCMF_E_REASSOC_IND: + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf); + break; + + case BRCMF_E_ASSOC: + case BRCMF_E_REASSOC: + if (status == BRCMF_E_STATUS_SUCCESS) + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, SUCCESS\n", + event_name, eabuf); + else if (status == BRCMF_E_STATUS_TIMEOUT) + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, TIMEOUT\n", + event_name, eabuf); + else if (status == BRCMF_E_STATUS_FAIL) + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, FAILURE, reason %d\n", + event_name, eabuf, (int)reason); + else + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, unexpected status %d\n", + event_name, eabuf, (int)status); + break; + + case BRCMF_E_DEAUTH_IND: + case BRCMF_E_DISASSOC_IND: + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, reason %d\n", + event_name, eabuf, (int)reason); + break; + + case BRCMF_E_AUTH: + case BRCMF_E_AUTH_IND: + if (auth_type == WLAN_AUTH_OPEN) + auth_str = "Open System"; + else if (auth_type == WLAN_AUTH_SHARED_KEY) + auth_str = "Shared Key"; + else { + sprintf(err_msg, "AUTH unknown: %d", (int)auth_type); + auth_str = err_msg; + } + if (event_type == BRCMF_E_AUTH_IND) + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s\n", + event_name, eabuf, auth_str); + else if (status == BRCMF_E_STATUS_SUCCESS) + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, SUCCESS\n", + event_name, eabuf, auth_str); + else if (status == BRCMF_E_STATUS_TIMEOUT) + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, TIMEOUT\n", + event_name, eabuf, auth_str); + else if (status == BRCMF_E_STATUS_FAIL) { + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, FAILURE, reason %d\n", + event_name, eabuf, auth_str, (int)reason); + } + + break; + + case BRCMF_E_JOIN: + case BRCMF_E_ROAM: + case BRCMF_E_SET_SSID: + if (status == BRCMF_E_STATUS_SUCCESS) + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", + event_name, eabuf); + else if (status == BRCMF_E_STATUS_FAIL) + brcmf_dbg(EVENT, "MACEVENT: %s, failed\n", event_name); + else if (status == BRCMF_E_STATUS_NO_NETWORKS) + brcmf_dbg(EVENT, "MACEVENT: %s, no networks found\n", + event_name); + else + brcmf_dbg(EVENT, "MACEVENT: %s, unexpected status %d\n", + event_name, (int)status); + break; + + case BRCMF_E_BEACON_RX: + if (status == BRCMF_E_STATUS_SUCCESS) + brcmf_dbg(EVENT, "MACEVENT: %s, SUCCESS\n", event_name); + else if (status == BRCMF_E_STATUS_FAIL) + brcmf_dbg(EVENT, "MACEVENT: %s, FAIL\n", event_name); + else + brcmf_dbg(EVENT, "MACEVENT: %s, status %d\n", + event_name, status); + break; + + case BRCMF_E_LINK: + brcmf_dbg(EVENT, "MACEVENT: %s %s\n", + event_name, link ? "UP" : "DOWN"); + break; + + case BRCMF_E_MIC_ERROR: + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, Group %d, Flush %d\n", + event_name, eabuf, group, flush_txq); + break; + + case BRCMF_E_ICV_ERROR: + case BRCMF_E_UNICAST_DECODE_ERROR: + case BRCMF_E_MULTICAST_DECODE_ERROR: + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf); + break; + + case BRCMF_E_TXFAIL: + brcmf_dbg(EVENT, "MACEVENT: %s, RA %s\n", event_name, eabuf); + break; + + case BRCMF_E_SCAN_COMPLETE: + case BRCMF_E_PMKID_CACHE: + brcmf_dbg(EVENT, "MACEVENT: %s\n", event_name); + break; + + case BRCMF_E_ESCAN_RESULT: + brcmf_dbg(EVENT, "MACEVENT: %s\n", event_name); + datalen = 0; + break; + + case BRCMF_E_PFN_NET_FOUND: + case BRCMF_E_PFN_NET_LOST: + case BRCMF_E_PFN_SCAN_COMPLETE: + brcmf_dbg(EVENT, "PNOEVENT: %s\n", event_name); + break; + + case BRCMF_E_PSK_SUP: + case BRCMF_E_PRUNE: + brcmf_dbg(EVENT, "MACEVENT: %s, status %d, reason %d\n", + event_name, (int)status, (int)reason); + break; + + case BRCMF_E_TRACE: + buf = (unsigned char *) event_data; + memcpy(&hdr, buf, sizeof(struct msgtrace_hdr)); + + if (hdr.version != MSGTRACE_VERSION) { + brcmf_dbg(ERROR, + "MACEVENT: %s [unsupported version --> brcmf" + " version:%d dongle version:%d]\n", + event_name, MSGTRACE_VERSION, hdr.version); + /* Reset datalen to avoid display below */ + datalen = 0; + break; + } + + /* There are 2 bytes available at the end of data */ + *(buf + sizeof(struct msgtrace_hdr) + + be16_to_cpu(hdr.len)) = '\0'; + + if (be32_to_cpu(hdr.discarded_bytes) + || be32_to_cpu(hdr.discarded_printf)) + brcmf_dbg(ERROR, + "WLC_E_TRACE: [Discarded traces in dongle -->" + " discarded_bytes %d discarded_printf %d]\n", + be32_to_cpu(hdr.discarded_bytes), + be32_to_cpu(hdr.discarded_printf)); + + nblost = be32_to_cpu(hdr.seqnum) - seqnum_prev - 1; + if (nblost > 0) + brcmf_dbg(ERROR, "WLC_E_TRACE: [Event lost --> seqnum " + " %d nblost %d\n", be32_to_cpu(hdr.seqnum), + nblost); + seqnum_prev = be32_to_cpu(hdr.seqnum); + + /* Display the trace buffer. Advance from \n to \n to + * avoid display big + * printf (issue with Linux printk ) + */ + p = (char *)&buf[sizeof(struct msgtrace_hdr)]; + while ((s = strstr(p, "\n")) != NULL) { + *s = '\0'; + pr_debug("%s\n", p); + p = s + 1; + } + pr_debug("%s\n", p); + + /* Reset datalen to avoid display below */ + datalen = 0; + break; + + case BRCMF_E_RSSI: + brcmf_dbg(EVENT, "MACEVENT: %s %d\n", + event_name, be32_to_cpu(*((__be32 *)event_data))); + break; + + default: + brcmf_dbg(EVENT, + "MACEVENT: %s %d, MAC %s, status %d, reason %d, " + "auth %d\n", event_name, event_type, eabuf, + (int)status, (int)reason, (int)auth_type); + break; + } + + /* show any appended data */ + brcmf_dbg_hex_dump(datalen, event_data, datalen, "Received data"); +} +#endif /* DEBUG */ + +int +brcmf_c_host_event(struct brcmf_pub *drvr, int *ifidx, void *pktdata, + struct brcmf_event_msg *event, void **data_ptr) +{ + /* check whether packet is a BRCM event pkt */ + struct brcmf_event *pvt_data = (struct brcmf_event *) pktdata; + struct brcmf_if_event *ifevent; + struct brcmf_if *ifp; + char *event_data; + u32 type, status; + u16 flags; + int evlen; + + if (memcmp(BRCM_OUI, &pvt_data->hdr.oui[0], DOT11_OUI_LEN)) { + brcmf_dbg(ERROR, "mismatched OUI, bailing\n"); + return -EBADE; + } + + /* BRCM event pkt may be unaligned - use xxx_ua to load user_subtype. */ + if (get_unaligned_be16(&pvt_data->hdr.usr_subtype) != + BCMILCP_BCM_SUBTYPE_EVENT) { + brcmf_dbg(ERROR, "mismatched subtype, bailing\n"); + return -EBADE; + } + + *data_ptr = &pvt_data[1]; + event_data = *data_ptr; + + /* memcpy since BRCM event pkt may be unaligned. */ + memcpy(event, &pvt_data->msg, sizeof(struct brcmf_event_msg)); + + type = get_unaligned_be32(&event->event_type); + flags = get_unaligned_be16(&event->flags); + status = get_unaligned_be32(&event->status); + evlen = get_unaligned_be32(&event->datalen) + + sizeof(struct brcmf_event); + + switch (type) { + case BRCMF_E_IF: + ifevent = (struct brcmf_if_event *) event_data; + brcmf_dbg(TRACE, "if event\n"); + + if (ifevent->ifidx > 0 && ifevent->ifidx < BRCMF_MAX_IFS) { + if (ifevent->action == BRCMF_E_IF_ADD) { + ifp = brcmf_add_if(drvr->dev, ifevent->ifidx, + ifevent->bssidx, + event->ifname, + pvt_data->eth.h_dest); + if (IS_ERR(ifp)) + return PTR_ERR(ifp); + brcmf_net_attach(ifp); + } else { + brcmf_del_if(drvr, ifevent->ifidx); + } + } else { + brcmf_dbg(ERROR, "Invalid ifidx %d for %s\n", + ifevent->ifidx, event->ifname); + } + + /* send up the if event: btamp user needs it */ + *ifidx = brcmf_ifname2idx(drvr, event->ifname); + break; + + /* These are what external supplicant/authenticator wants */ + case BRCMF_E_LINK: + case BRCMF_E_ASSOC_IND: + case BRCMF_E_REASSOC_IND: + case BRCMF_E_DISASSOC_IND: + case BRCMF_E_MIC_ERROR: + default: + /* Fall through: this should get _everything_ */ + + *ifidx = brcmf_ifname2idx(drvr, event->ifname); + brcmf_dbg(TRACE, "MAC event %d, flags %x, status %x\n", + type, flags, status); + + /* put it back to BRCMF_E_NDIS_LINK */ + if (type == BRCMF_E_NDIS_LINK) { + u32 temp1; + __be32 temp2; + + temp1 = get_unaligned_be32(&event->event_type); + brcmf_dbg(TRACE, "Converted to WLC_E_LINK type %d\n", + temp1); + + temp2 = cpu_to_be32(BRCMF_E_NDIS_LINK); + memcpy((void *)(&pvt_data->msg.event_type), &temp2, + sizeof(pvt_data->msg.event_type)); + } + break; + } + +#ifdef DEBUG + if (BRCMF_EVENT_ON()) + brcmf_c_show_host_event(event, event_data); +#endif /* DEBUG */ + + return 0; +} + /* Convert user's input in hex pattern to byte-size mask */ static int brcmf_c_pattern_atoh(char *src, char *dst) { @@ -238,8 +686,8 @@ static void brcmf_c_pktfilter_offload_set(struct brcmf_if *ifp, char *arg) } pkt_filter->u.pattern.size_bytes = cpu_to_le32(mask_size); - buf_len = offsetof(struct brcmf_pkt_filter_le, - u.pattern.mask_and_pattern); + buf_len = sizeof(*pkt_filter); + buf_len -= sizeof(pkt_filter->u.pattern.mask_and_pattern); buf_len += mask_size + pattern_size; err = brcmf_fil_iovar_data_set(ifp, "pkt_filter_add", pkt_filter, diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c index 7e58e8ce9aba..862d2acb7a16 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c @@ -14,12 +14,18 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include +#include +#include #include +#include #include +#include +#include #include #include #include "dhd.h" +#include "dhd_bus.h" #include "dhd_dbg.h" static struct dentry *root_folder; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h index a0e18a1ceb4b..eefa6c2560cc 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h @@ -27,11 +27,11 @@ #define BRCMF_HDRS_VAL 0x0040 #define BRCMF_BYTES_VAL 0x0080 #define BRCMF_INTR_VAL 0x0100 -#define BRCMF_GLOM_VAL 0x0200 -#define BRCMF_EVENT_VAL 0x0400 -#define BRCMF_BTA_VAL 0x0800 -#define BRCMF_FIL_VAL 0x1000 -#define BRCMF_USB_VAL 0x2000 +#define BRCMF_GLOM_VAL 0x0400 +#define BRCMF_EVENT_VAL 0x0800 +#define BRCMF_BTA_VAL 0x1000 +#define BRCMF_ISCAN_VAL 0x2000 +#define BRCMF_FIL_VAL 0x4000 #if defined(DEBUG) diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index b6c86b046c15..297652339fda 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -16,11 +16,27 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include #include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include +#include #include #include @@ -29,19 +45,35 @@ #include "dhd_proto.h" #include "dhd_dbg.h" #include "wl_cfg80211.h" -#include "fwil.h" MODULE_AUTHOR("Broadcom Corporation"); -MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); -MODULE_SUPPORTED_DEVICE("Broadcom 802.11 WLAN fullmac cards"); +MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac driver."); +MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac cards"); MODULE_LICENSE("Dual BSD/GPL"); -#define MAX_WAIT_FOR_8021X_TX 50 /* msecs */ /* Error bits */ int brcmf_msg_level = BRCMF_ERROR_VAL; module_param(brcmf_msg_level, int, 0); +int brcmf_ifname2idx(struct brcmf_pub *drvr, char *name) +{ + int i = BRCMF_MAX_IFS; + struct brcmf_if *ifp; + + if (name == NULL || *name == '\0') + return 0; + + while (--i > 0) { + ifp = drvr->iflist[i]; + if (ifp && !strncmp(ifp->ndev->name, name, IFNAMSIZ)) + break; + } + + brcmf_dbg(TRACE, "return idx %d for \"%s\"\n", i, name); + + return i; /* default - the primary interface */ +} char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx) { @@ -63,33 +95,38 @@ char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx) static void _brcmf_set_multicast_list(struct work_struct *work) { - struct brcmf_if *ifp; struct net_device *ndev; struct netdev_hw_addr *ha; - u32 cmd_value, cnt; + u32 dcmd_value, cnt; __le32 cnt_le; + __le32 dcmd_le_value; + + struct brcmf_dcmd dcmd; char *buf, *bufp; - u32 buflen; - s32 err; + uint buflen; + int ret; - brcmf_dbg(TRACE, "enter\n"); + struct brcmf_pub *drvr = container_of(work, struct brcmf_pub, + multicast_work); - ifp = container_of(work, struct brcmf_if, multicast_work); - ndev = ifp->ndev; + ndev = drvr->iflist[0]->ndev; + cnt = netdev_mc_count(ndev); /* Determine initial value of allmulti flag */ - cmd_value = (ndev->flags & IFF_ALLMULTI) ? true : false; + dcmd_value = (ndev->flags & IFF_ALLMULTI) ? true : false; /* Send down the multicast list first. */ - cnt = netdev_mc_count(ndev); - buflen = sizeof(cnt) + (cnt * ETH_ALEN); - buf = kmalloc(buflen, GFP_ATOMIC); - if (!buf) + + buflen = sizeof("mcast_list") + sizeof(cnt) + (cnt * ETH_ALEN); + bufp = buf = kmalloc(buflen, GFP_ATOMIC); + if (!bufp) return; - bufp = buf; + + strcpy(bufp, "mcast_list"); + bufp += strlen("mcast_list") + 1; cnt_le = cpu_to_le32(cnt); - memcpy(bufp, &cnt_le, sizeof(cnt_le)); + memcpy(bufp, &cnt_le, sizeof(cnt)); bufp += sizeof(cnt_le); netdev_for_each_mc_addr(ha, ndev) { @@ -100,66 +137,129 @@ static void _brcmf_set_multicast_list(struct work_struct *work) cnt--; } - err = brcmf_fil_iovar_data_set(ifp, "mcast_list", buf, buflen); - if (err < 0) { - brcmf_dbg(ERROR, "Setting mcast_list failed, %d\n", err); - cmd_value = cnt ? true : cmd_value; + memset(&dcmd, 0, sizeof(dcmd)); + dcmd.cmd = BRCMF_C_SET_VAR; + dcmd.buf = buf; + dcmd.len = buflen; + dcmd.set = true; + + ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len); + if (ret < 0) { + brcmf_dbg(ERROR, "%s: set mcast_list failed, cnt %d\n", + brcmf_ifname(drvr, 0), cnt); + dcmd_value = cnt ? true : dcmd_value; } kfree(buf); - /* - * Now send the allmulti setting. This is based on the setting in the + /* Now send the allmulti setting. This is based on the setting in the * net_device flags, but might be modified above to be turned on if we * were trying to set some addresses and dongle rejected it... */ - err = brcmf_fil_iovar_int_set(ifp, "allmulti", cmd_value); - if (err < 0) - brcmf_dbg(ERROR, "Setting allmulti failed, %d\n", err); - - /*Finally, pick up the PROMISC flag */ - cmd_value = (ndev->flags & IFF_PROMISC) ? true : false; - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PROMISC, cmd_value); - if (err < 0) - brcmf_dbg(ERROR, "Setting BRCMF_C_SET_PROMISC failed, %d\n", - err); + + buflen = sizeof("allmulti") + sizeof(dcmd_value); + buf = kmalloc(buflen, GFP_ATOMIC); + if (!buf) + return; + + dcmd_le_value = cpu_to_le32(dcmd_value); + + if (!brcmf_c_mkiovar + ("allmulti", (void *)&dcmd_le_value, + sizeof(dcmd_le_value), buf, buflen)) { + brcmf_dbg(ERROR, "%s: mkiovar failed for allmulti, datalen %d buflen %u\n", + brcmf_ifname(drvr, 0), + (int)sizeof(dcmd_value), buflen); + kfree(buf); + return; + } + + memset(&dcmd, 0, sizeof(dcmd)); + dcmd.cmd = BRCMF_C_SET_VAR; + dcmd.buf = buf; + dcmd.len = buflen; + dcmd.set = true; + + ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len); + if (ret < 0) { + brcmf_dbg(ERROR, "%s: set allmulti %d failed\n", + brcmf_ifname(drvr, 0), + le32_to_cpu(dcmd_le_value)); + } + + kfree(buf); + + /* Finally, pick up the PROMISC flag as well, like the NIC + driver does */ + + dcmd_value = (ndev->flags & IFF_PROMISC) ? true : false; + dcmd_le_value = cpu_to_le32(dcmd_value); + + memset(&dcmd, 0, sizeof(dcmd)); + dcmd.cmd = BRCMF_C_SET_PROMISC; + dcmd.buf = &dcmd_le_value; + dcmd.len = sizeof(dcmd_le_value); + dcmd.set = true; + + ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len); + if (ret < 0) { + brcmf_dbg(ERROR, "%s: set promisc %d failed\n", + brcmf_ifname(drvr, 0), + le32_to_cpu(dcmd_le_value)); + } } static void _brcmf_set_mac_address(struct work_struct *work) { - struct brcmf_if *ifp; - s32 err; + char buf[32]; + struct brcmf_dcmd dcmd; + int ret; - brcmf_dbg(TRACE, "enter\n"); + struct brcmf_pub *drvr = container_of(work, struct brcmf_pub, + setmacaddr_work); - ifp = container_of(work, struct brcmf_if, setmacaddr_work); - err = brcmf_fil_iovar_data_set(ifp, "cur_etheraddr", ifp->mac_addr, - ETH_ALEN); - if (err < 0) { - brcmf_dbg(ERROR, "Setting cur_etheraddr failed, %d\n", err); - } else { - brcmf_dbg(TRACE, "MAC address updated to %pM\n", - ifp->mac_addr); - memcpy(ifp->ndev->dev_addr, ifp->mac_addr, ETH_ALEN); + brcmf_dbg(TRACE, "enter\n"); + if (!brcmf_c_mkiovar("cur_etheraddr", (char *)drvr->macvalue, + ETH_ALEN, buf, 32)) { + brcmf_dbg(ERROR, "%s: mkiovar failed for cur_etheraddr\n", + brcmf_ifname(drvr, 0)); + return; } + memset(&dcmd, 0, sizeof(dcmd)); + dcmd.cmd = BRCMF_C_SET_VAR; + dcmd.buf = buf; + dcmd.len = 32; + dcmd.set = true; + + ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len); + if (ret < 0) + brcmf_dbg(ERROR, "%s: set cur_etheraddr failed\n", + brcmf_ifname(drvr, 0)); + else + memcpy(drvr->iflist[0]->ndev->dev_addr, + drvr->macvalue, ETH_ALEN); + + return; } static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr) { struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_pub *drvr = ifp->drvr; struct sockaddr *sa = (struct sockaddr *)addr; - memcpy(&ifp->mac_addr, sa->sa_data, ETH_ALEN); - schedule_work(&ifp->setmacaddr_work); + memcpy(&drvr->macvalue, sa->sa_data, ETH_ALEN); + schedule_work(&drvr->setmacaddr_work); return 0; } static void brcmf_netdev_set_multicast_list(struct net_device *ndev) { struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_pub *drvr = ifp->drvr; - schedule_work(&ifp->multicast_work); + schedule_work(&drvr->multicast_work); } static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) @@ -172,7 +272,7 @@ static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) /* Reject if down */ if (!drvr->bus_if->drvr_up || - (drvr->bus_if->state != BRCMF_BUS_DATA)) { + (drvr->bus_if->state == BRCMF_BUS_DOWN)) { brcmf_dbg(ERROR, "xmit rejected drvup=%d state=%d\n", drvr->bus_if->drvr_up, drvr->bus_if->state); @@ -250,13 +350,32 @@ void brcmf_txflowblock(struct device *dev, bool state) } } -void brcmf_rx_frame(struct device *dev, u8 ifidx, +static int brcmf_host_event(struct brcmf_pub *drvr, int *ifidx, + void *pktdata, struct brcmf_event_msg *event, + void **data) +{ + int bcmerror = 0; + + bcmerror = brcmf_c_host_event(drvr, ifidx, pktdata, event, data); + if (bcmerror != 0) + return bcmerror; + + if (drvr->iflist[*ifidx]->ndev) + brcmf_cfg80211_event(drvr->iflist[*ifidx]->ndev, + event, *data); + + return bcmerror; +} + +void brcmf_rx_frame(struct device *dev, int ifidx, struct sk_buff_head *skb_list) { unsigned char *eth; uint len; + void *data; struct sk_buff *skb, *pnext; struct brcmf_if *ifp; + struct brcmf_event_msg event; struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_pub *drvr = bus_if->drvr; @@ -303,7 +422,10 @@ void brcmf_rx_frame(struct device *dev, u8 ifidx, skb_pull(skb, ETH_HLEN); /* Process special event packets and then discard them */ - brcmf_fweh_process_skb(drvr, skb, &ifidx); + if (ntohs(skb->protocol) == ETH_P_LINK_CTL) + brcmf_host_event(drvr, &ifidx, + skb_mac_header(skb), + &event, &data); if (drvr->iflist[ifidx]) { ifp = drvr->iflist[ifidx]; @@ -339,11 +461,9 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success) eh = (struct ethhdr *)(txp->data); type = ntohs(eh->h_proto); - if (type == ETH_P_PAE) { + if (type == ETH_P_PAE) atomic_dec(&drvr->pend_8021x_cnt); - if (waitqueue_active(&drvr->pend_8021x_wait)) - wake_up(&drvr->pend_8021x_wait); - } + } static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) @@ -367,26 +487,83 @@ static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) return &ifp->stats; } -/* - * Set current toe component enables in toe_ol iovar, - * and set toe global enable iovar - */ -static int brcmf_toe_set(struct brcmf_if *ifp, u32 toe_ol) +/* Retrieve current toe component enables, which are kept + as a bitmap in toe_ol iovar */ +static int brcmf_toe_get(struct brcmf_pub *drvr, int ifidx, u32 *toe_ol) { - s32 err; + struct brcmf_dcmd dcmd; + __le32 toe_le; + char buf[32]; + int ret; + + memset(&dcmd, 0, sizeof(dcmd)); + + dcmd.cmd = BRCMF_C_GET_VAR; + dcmd.buf = buf; + dcmd.len = (uint) sizeof(buf); + dcmd.set = false; - err = brcmf_fil_iovar_int_set(ifp, "toe_ol", toe_ol); - if (err < 0) { - brcmf_dbg(ERROR, "Setting toe_ol failed, %d\n", err); - return err; + strcpy(buf, "toe_ol"); + ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len); + if (ret < 0) { + /* Check for older dongle image that doesn't support toe_ol */ + if (ret == -EIO) { + brcmf_dbg(ERROR, "%s: toe not supported by device\n", + brcmf_ifname(drvr, ifidx)); + return -EOPNOTSUPP; + } + + brcmf_dbg(INFO, "%s: could not get toe_ol: ret=%d\n", + brcmf_ifname(drvr, ifidx), ret); + return ret; } - err = brcmf_fil_iovar_int_set(ifp, "toe", (toe_ol != 0)); - if (err < 0) - brcmf_dbg(ERROR, "Setting toe failed, %d\n", err); + memcpy(&toe_le, buf, sizeof(u32)); + *toe_ol = le32_to_cpu(toe_le); + return 0; +} + +/* Set current toe component enables in toe_ol iovar, + and set toe global enable iovar */ +static int brcmf_toe_set(struct brcmf_pub *drvr, int ifidx, u32 toe_ol) +{ + struct brcmf_dcmd dcmd; + char buf[32]; + int ret; + __le32 toe_le = cpu_to_le32(toe_ol); + + memset(&dcmd, 0, sizeof(dcmd)); + + dcmd.cmd = BRCMF_C_SET_VAR; + dcmd.buf = buf; + dcmd.len = (uint) sizeof(buf); + dcmd.set = true; + + /* Set toe_ol as requested */ + strcpy(buf, "toe_ol"); + memcpy(&buf[sizeof("toe_ol")], &toe_le, sizeof(u32)); + + ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len); + if (ret < 0) { + brcmf_dbg(ERROR, "%s: could not set toe_ol: ret=%d\n", + brcmf_ifname(drvr, ifidx), ret); + return ret; + } - return err; + /* Enable toe globally only if any components are enabled. */ + toe_le = cpu_to_le32(toe_ol != 0); + strcpy(buf, "toe"); + memcpy(&buf[sizeof("toe")], &toe_le, sizeof(u32)); + + ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len); + if (ret < 0) { + brcmf_dbg(ERROR, "%s: could not set toe: ret=%d\n", + brcmf_ifname(drvr, ifidx), ret); + return ret; + } + + return 0; } static void brcmf_ethtool_get_drvinfo(struct net_device *ndev, @@ -404,9 +581,8 @@ static const struct ethtool_ops brcmf_ethtool_ops = { .get_drvinfo = brcmf_ethtool_get_drvinfo, }; -static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr) +static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr) { - struct brcmf_pub *drvr = ifp->drvr; struct ethtool_drvinfo info; char drvname[sizeof(info.driver)]; u32 cmd; @@ -457,7 +633,7 @@ static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr) /* Get toe offload components from dongle */ case ETHTOOL_GRXCSUM: case ETHTOOL_GTXCSUM: - ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt); + ret = brcmf_toe_get(drvr, 0, &toe_cmpnt); if (ret < 0) return ret; @@ -478,7 +654,7 @@ static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr) return -EFAULT; /* Read the current settings, update and write back */ - ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt); + ret = brcmf_toe_get(drvr, 0, &toe_cmpnt); if (ret < 0) return ret; @@ -490,16 +666,18 @@ static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr) else toe_cmpnt &= ~csum_dir; - ret = brcmf_toe_set(ifp, toe_cmpnt); + ret = brcmf_toe_set(drvr, 0, toe_cmpnt); if (ret < 0) return ret; /* If setting TX checksum mode, tell Linux the new mode */ if (cmd == ETHTOOL_STXCSUM) { if (edata.data) - ifp->ndev->features |= NETIF_F_IP_CSUM; + drvr->iflist[0]->ndev->features |= + NETIF_F_IP_CSUM; else - ifp->ndev->features &= ~NETIF_F_IP_CSUM; + drvr->iflist[0]->ndev->features &= + ~NETIF_F_IP_CSUM; } break; @@ -523,7 +701,7 @@ static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr, return -1; if (cmd == SIOCETHTOOL) - return brcmf_ethtool(ifp, ifr->ifr_data); + return brcmf_ethtool(drvr, ifr->ifr_data); return -EOPNOTSUPP; } @@ -534,12 +712,10 @@ static int brcmf_netdev_stop(struct net_device *ndev) struct brcmf_pub *drvr = ifp->drvr; brcmf_dbg(TRACE, "Enter\n"); - + brcmf_cfg80211_down(drvr->config); if (drvr->bus_if->drvr_up == 0) return 0; - brcmf_cfg80211_down(ndev); - /* Set state and stop OS transmissions */ drvr->bus_if->drvr_up = false; netif_stop_queue(ndev); @@ -554,35 +730,38 @@ static int brcmf_netdev_open(struct net_device *ndev) struct brcmf_bus *bus_if = drvr->bus_if; u32 toe_ol; s32 ret = 0; + uint up = 0; brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx); - /* If bus is not ready, can't continue */ - if (bus_if->state != BRCMF_BUS_DATA) { - brcmf_dbg(ERROR, "failed bus is not ready\n"); - return -EAGAIN; - } + if (ifp->idx == 0) { /* do it only for primary eth0 */ + /* If bus is not ready, can't continue */ + if (bus_if->state != BRCMF_BUS_DATA) { + brcmf_dbg(ERROR, "failed bus is not ready\n"); + return -EAGAIN; + } - atomic_set(&drvr->pend_8021x_cnt, 0); + atomic_set(&drvr->pend_8021x_cnt, 0); - memcpy(ndev->dev_addr, drvr->mac, ETH_ALEN); + memcpy(ndev->dev_addr, drvr->mac, ETH_ALEN); - /* Get current TOE mode from dongle */ - if (brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_ol) >= 0 - && (toe_ol & TOE_TX_CSUM_OL) != 0) - drvr->iflist[ifp->idx]->ndev->features |= - NETIF_F_IP_CSUM; - else - drvr->iflist[ifp->idx]->ndev->features &= - ~NETIF_F_IP_CSUM; + /* Get current TOE mode from dongle */ + if (brcmf_toe_get(drvr, ifp->idx, &toe_ol) >= 0 + && (toe_ol & TOE_TX_CSUM_OL) != 0) + drvr->iflist[ifp->idx]->ndev->features |= + NETIF_F_IP_CSUM; + else + drvr->iflist[ifp->idx]->ndev->features &= + ~NETIF_F_IP_CSUM; + } /* make sure RF is ready for work */ - brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0); + brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_UP, (char *)&up, sizeof(up)); /* Allow transmit calls */ netif_start_queue(ndev); drvr->bus_if->drvr_up = true; - if (brcmf_cfg80211_up(ndev)) { + if (brcmf_cfg80211_up(drvr->config)) { brcmf_dbg(ERROR, "failed to bring up cfg80211\n"); return -1; } @@ -600,38 +779,39 @@ static const struct net_device_ops brcmf_netdev_ops_pri = { .ndo_set_rx_mode = brcmf_netdev_set_multicast_list }; -static const struct net_device_ops brcmf_netdev_ops_virt = { - .ndo_open = brcmf_cfg80211_up, - .ndo_stop = brcmf_cfg80211_down, - .ndo_get_stats = brcmf_netdev_get_stats, - .ndo_do_ioctl = brcmf_netdev_ioctl_entry, - .ndo_start_xmit = brcmf_netdev_start_xmit, - .ndo_set_mac_address = brcmf_netdev_set_mac_address, - .ndo_set_rx_mode = brcmf_netdev_set_multicast_list -}; - int brcmf_net_attach(struct brcmf_if *ifp) { struct brcmf_pub *drvr = ifp->drvr; struct net_device *ndev; + u8 temp_addr[ETH_ALEN]; + + brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx); - brcmf_dbg(TRACE, "ifidx %d mac %pM\n", ifp->idx, ifp->mac_addr); - ndev = ifp->ndev; + ndev = drvr->iflist[ifp->idx]->ndev; + ndev->netdev_ops = &brcmf_netdev_ops_pri; - /* set appropriate operations */ - if (!ifp->idx) - ndev->netdev_ops = &brcmf_netdev_ops_pri; + /* + * determine mac address to use + */ + if (is_valid_ether_addr(ifp->mac_addr)) + memcpy(temp_addr, ifp->mac_addr, ETH_ALEN); else - ndev->netdev_ops = &brcmf_netdev_ops_virt; + memcpy(temp_addr, drvr->mac, ETH_ALEN); + + if (ifp->idx == 1) { + brcmf_dbg(TRACE, "ACCESS POINT MAC:\n"); + /* ACCESSPOINT INTERFACE CASE */ + temp_addr[0] |= 0X02; /* set bit 2 , + - Locally Administered address */ + } ndev->hard_header_len = ETH_HLEN + drvr->hdrlen; ndev->ethtool_ops = &brcmf_ethtool_ops; drvr->rxsz = ndev->mtu + ndev->hard_header_len + drvr->hdrlen; - /* set the mac address */ - memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN); + memcpy(ndev->dev_addr, temp_addr, ETH_ALEN); if (register_netdev(ndev) != 0) { brcmf_dbg(ERROR, "couldn't register the net device\n"); @@ -644,15 +824,17 @@ int brcmf_net_attach(struct brcmf_if *ifp) fail: ndev->netdev_ops = NULL; + free_netdev(ndev); return -EBADE; } -struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, int ifidx, s32 bssidx, - char *name, u8 *addr_mask) +struct brcmf_if *brcmf_add_if(struct device *dev, int ifidx, s32 bssidx, + char *name, u8 *mac_addr) { struct brcmf_if *ifp; struct net_device *ndev; - int i; + struct brcmf_bus *bus_if = dev_get_drvdata(dev); + struct brcmf_pub *drvr = bus_if->drvr; brcmf_dbg(TRACE, "idx %d\n", ifidx); @@ -662,17 +844,12 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, int ifidx, s32 bssidx, * in case we missed the BRCMF_E_IF_DEL event. */ if (ifp) { - brcmf_dbg(ERROR, "ERROR: netdev:%s already exists\n", + brcmf_dbg(ERROR, "ERROR: netdev:%s already exists, try free & unregister\n", ifp->ndev->name); - if (ifidx) { - netif_stop_queue(ifp->ndev); - unregister_netdev(ifp->ndev); - free_netdev(ifp->ndev); - drvr->iflist[ifidx] = NULL; - } else { - brcmf_dbg(ERROR, "ignore IF event\n"); - return ERR_PTR(-EINVAL); - } + netif_stop_queue(ifp->ndev); + unregister_netdev(ifp->ndev); + free_netdev(ifp->ndev); + drvr->iflist[ifidx] = NULL; } /* Allocate netdev, including space for private structure */ @@ -688,16 +865,11 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, int ifidx, s32 bssidx, drvr->iflist[ifidx] = ifp; ifp->idx = ifidx; ifp->bssidx = bssidx; + if (mac_addr != NULL) + memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN); - INIT_WORK(&ifp->setmacaddr_work, _brcmf_set_mac_address); - INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list); - - if (addr_mask != NULL) - for (i = 0; i < ETH_ALEN; i++) - ifp->mac_addr[i] = drvr->mac[i] ^ addr_mask[i]; - - brcmf_dbg(TRACE, " ==== pid:%x, if:%s (%pM) created ===\n", - current->pid, ifp->ndev->name, ifp->mac_addr); + brcmf_dbg(TRACE, " ==== pid:%x, net_device for if:%s created ===\n", + current->pid, ifp->ndev->name); return ifp; } @@ -724,9 +896,6 @@ void brcmf_del_if(struct brcmf_pub *drvr, int ifidx) netif_stop_queue(ifp->ndev); } - cancel_work_sync(&ifp->setmacaddr_work); - cancel_work_sync(&ifp->multicast_work); - unregister_netdev(ifp->ndev); drvr->iflist[ifidx] = NULL; if (ifidx == 0) @@ -765,13 +934,11 @@ int brcmf_attach(uint bus_hdrlen, struct device *dev) goto fail; } - /* attach firmware event handler */ - brcmf_fweh_attach(drvr); + INIT_WORK(&drvr->setmacaddr_work, _brcmf_set_mac_address); + INIT_WORK(&drvr->multicast_work, _brcmf_set_multicast_list); INIT_LIST_HEAD(&drvr->bus_if->dcmd_list); - init_waitqueue_head(&drvr->pend_8021x_wait); - return ret; fail: @@ -797,7 +964,7 @@ int brcmf_bus_start(struct device *dev) } /* add primary networking interface */ - ifp = brcmf_add_if(drvr, 0, 0, "wlan%d", NULL); + ifp = brcmf_add_if(dev, 0, 0, "wlan%d", NULL); if (IS_ERR(ifp)) return PTR_ERR(ifp); @@ -807,25 +974,15 @@ int brcmf_bus_start(struct device *dev) /* Bus is ready, do any initialization */ ret = brcmf_c_preinit_dcmds(ifp); if (ret < 0) - goto fail; + return ret; drvr->config = brcmf_cfg80211_attach(drvr); - if (drvr->config == NULL) { - ret = -ENOMEM; - goto fail; - } - - ret = brcmf_fweh_activate_events(ifp); - if (ret < 0) - goto fail; + if (drvr->config == NULL) + return -ENOMEM; ret = brcmf_net_attach(ifp); -fail: if (ret < 0) { - brcmf_dbg(ERROR, "failed: %d\n", ret); - if (drvr->config) - brcmf_cfg80211_detach(drvr->config); - free_netdev(drvr->iflist[0]->ndev); + brcmf_dbg(ERROR, "brcmf_net_attach failed"); drvr->iflist[0] = NULL; return ret; } @@ -854,11 +1011,6 @@ void brcmf_detach(struct device *dev) brcmf_dbg(TRACE, "Enter\n"); - if (drvr == NULL) - return; - - /* stop firmware event handling */ - brcmf_fweh_detach(drvr); /* make sure primary interface removed last */ for (i = BRCMF_MAX_IFS-1; i > -1; i--) @@ -868,6 +1020,8 @@ void brcmf_detach(struct device *dev) brcmf_bus_detach(drvr); if (drvr->prot) { + cancel_work_sync(&drvr->setmacaddr_work); + cancel_work_sync(&drvr->multicast_work); brcmf_proto_detach(drvr); } @@ -881,19 +1035,26 @@ static int brcmf_get_pend_8021x_cnt(struct brcmf_pub *drvr) return atomic_read(&drvr->pend_8021x_cnt); } +#define MAX_WAIT_FOR_8021X_TX 10 + int brcmf_netdev_wait_pend8021x(struct net_device *ndev) { struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_pub *drvr = ifp->drvr; - int err; - - err = wait_event_timeout(drvr->pend_8021x_wait, - !brcmf_get_pend_8021x_cnt(drvr), - msecs_to_jiffies(MAX_WAIT_FOR_8021X_TX)); - - WARN_ON(!err); - - return !err; + int timeout = 10 * HZ / 1000; + int ntimes = MAX_WAIT_FOR_8021X_TX; + int pend = brcmf_get_pend_8021x_cnt(drvr); + + while (ntimes && pend) { + if (pend) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(timeout); + set_current_state(TASK_RUNNING); + ntimes--; + } + pend = brcmf_get_pend_8021x_cnt(drvr); + } + return pend; } static void brcmf_driver_init(struct work_struct *work) diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h index 48fa70302192..7fe6779b90cf 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h @@ -36,7 +36,14 @@ extern void brcmf_proto_stop(struct brcmf_pub *drvr); extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx, struct sk_buff *txp); +/* Use protocol to issue command to dongle */ +extern int brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx, + struct brcmf_dcmd *dcmd, int len); + /* Sets dongle media info (drv_version, mac address). */ extern int brcmf_c_preinit_dcmds(struct brcmf_if *ifp); +extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, + uint cmd, void *buf, uint len); + #endif /* _BRCMF_PROTO_H_ */ diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 45725454714d..415f2be36375 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -533,11 +533,9 @@ struct brcmf_sdio { u8 *rxbuf; /* Buffer for receiving control packets */ uint rxblen; /* Allocated length of rxbuf */ u8 *rxctl; /* Aligned pointer into rxbuf */ - u8 *rxctl_orig; /* pointer for freeing rxctl */ u8 *databuf; /* Buffer for receiving big glom packet */ u8 *dataptr; /* Aligned pointer into databuf */ uint rxlen; /* Length of valid data in buffer */ - spinlock_t rxctl_lock; /* protection lock for ctrl frame resources */ u8 sdpcm_ver; /* Bus protocol reported by dongle */ @@ -584,6 +582,8 @@ struct brcmf_sdio { struct list_head dpc_tsklst; spinlock_t dpc_tl_lock; + struct semaphore sdsem; + const struct firmware *firmware; u32 fw_ptr; @@ -1037,9 +1037,9 @@ static void brcmf_sdbrcm_free_glom(struct brcmf_sdio *bus) } } -static int brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, - struct brcmf_sdio_read *rd, - enum brcmf_sdio_frmtype type) +static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, + struct brcmf_sdio_read *rd, + enum brcmf_sdio_frmtype type) { u16 len, checksum; u8 rx_seq, fc, tx_seq_max; @@ -1054,26 +1054,26 @@ static int brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, /* All zero means no more to read */ if (!(len | checksum)) { bus->rxpending = false; - return -ENODATA; + return false; } if ((u16)(~(len ^ checksum))) { brcmf_dbg(ERROR, "HW header checksum error\n"); bus->sdcnt.rx_badhdr++; brcmf_sdbrcm_rxfail(bus, false, false); - return -EIO; + return false; } if (len < SDPCM_HDRLEN) { brcmf_dbg(ERROR, "HW header length error\n"); - return -EPROTO; + return false; } if (type == BRCMF_SDIO_FT_SUPER && (roundup(len, bus->blocksize) != rd->len)) { brcmf_dbg(ERROR, "HW superframe header length error\n"); - return -EPROTO; + return false; } if (type == BRCMF_SDIO_FT_SUB && len > rd->len) { brcmf_dbg(ERROR, "HW subframe header length error\n"); - return -EPROTO; + return false; } rd->len = len; @@ -1091,7 +1091,7 @@ static int brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, SDPCM_GLOMDESC(&header[SDPCM_FRAMETAG_LEN])) { brcmf_dbg(ERROR, "Glom descriptor found in superframe head\n"); rd->len = 0; - return -EINVAL; + return false; } rx_seq = SDPCM_PACKET_SEQUENCE(&header[SDPCM_FRAMETAG_LEN]); rd->channel = SDPCM_PACKET_CHANNEL(&header[SDPCM_FRAMETAG_LEN]); @@ -1102,18 +1102,18 @@ static int brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, bus->sdcnt.rx_toolong++; brcmf_sdbrcm_rxfail(bus, false, false); rd->len = 0; - return -EPROTO; + return false; } if (type == BRCMF_SDIO_FT_SUPER && rd->channel != SDPCM_GLOM_CHANNEL) { brcmf_dbg(ERROR, "Wrong channel for superframe\n"); rd->len = 0; - return -EINVAL; + return false; } if (type == BRCMF_SDIO_FT_SUB && rd->channel != SDPCM_DATA_CHANNEL && rd->channel != SDPCM_EVENT_CHANNEL) { brcmf_dbg(ERROR, "Wrong channel for subframe\n"); rd->len = 0; - return -EINVAL; + return false; } rd->dat_offset = SDPCM_DOFFSET_VALUE(&header[SDPCM_FRAMETAG_LEN]); if (rd->dat_offset < SDPCM_HDRLEN || rd->dat_offset > rd->len) { @@ -1121,7 +1121,7 @@ static int brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, bus->sdcnt.rx_badhdr++; brcmf_sdbrcm_rxfail(bus, false, false); rd->len = 0; - return -ENXIO; + return false; } if (rd->seq_num != rx_seq) { brcmf_dbg(ERROR, "seq %d: sequence number error, expect %d\n", @@ -1131,7 +1131,7 @@ static int brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, } /* no need to check the reset for subframe */ if (type == BRCMF_SDIO_FT_SUB) - return 0; + return true; rd->len_nxtfrm = header[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; if (rd->len_nxtfrm << 4 > MAX_RX_DATASZ) { /* only warm for NON glom packet */ @@ -1155,7 +1155,7 @@ static int brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, } bus->tx_max = tx_seq_max; - return 0; + return true; } static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) @@ -1272,7 +1272,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) * read directly into the chained packet, or allocate a large * packet and and copy into the chain. */ - sdio_claim_host(bus->sdiodev->func[1]); if (usechain) { errcode = brcmf_sdcard_recv_chain(bus->sdiodev, bus->sdiodev->sbwad, @@ -1294,7 +1293,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) dlen); errcode = -1; } - sdio_release_host(bus->sdiodev->func[1]); bus->sdcnt.f2rxdata++; /* On failure, kill the superframe, allow a couple retries */ @@ -1303,7 +1301,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) dlen, errcode); bus->sdiodev->bus_if->dstats.rx_errors++; - sdio_claim_host(bus->sdiodev->func[1]); if (bus->glomerr++ < 3) { brcmf_sdbrcm_rxfail(bus, true, true); } else { @@ -1312,7 +1309,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) bus->sdcnt.rxglomfail++; brcmf_sdbrcm_free_glom(bus); } - sdio_release_host(bus->sdiodev->func[1]); return 0; } @@ -1322,10 +1318,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) rd_new.seq_num = rxseq; rd_new.len = dlen; - sdio_claim_host(bus->sdiodev->func[1]); - errcode = brcmf_sdio_hdparser(bus, pfirst->data, &rd_new, - BRCMF_SDIO_FT_SUPER); - sdio_release_host(bus->sdiodev->func[1]); + errcode = -!brcmf_sdio_hdparser(bus, pfirst->data, &rd_new, + BRCMF_SDIO_FT_SUPER); bus->cur_read.len = rd_new.len_nxtfrm << 4; /* Remove superframe header, remember offset */ @@ -1341,10 +1335,9 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) rd_new.len = pnext->len; rd_new.seq_num = rxseq++; - sdio_claim_host(bus->sdiodev->func[1]); - errcode = brcmf_sdio_hdparser(bus, pnext->data, &rd_new, - BRCMF_SDIO_FT_SUB); - sdio_release_host(bus->sdiodev->func[1]); + errcode = -!brcmf_sdio_hdparser(bus, pnext->data, + &rd_new, + BRCMF_SDIO_FT_SUB); brcmf_dbg_hex_dump(BRCMF_GLOM_ON(), pnext->data, 32, "subframe:\n"); @@ -1354,7 +1347,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) if (errcode) { /* Terminate frame on error, request a couple retries */ - sdio_claim_host(bus->sdiodev->func[1]); if (bus->glomerr++ < 3) { /* Restore superframe header space */ skb_push(pfirst, sfdoff); @@ -1365,7 +1357,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) bus->sdcnt.rxglomfail++; brcmf_sdbrcm_free_glom(bus); } - sdio_release_host(bus->sdiodev->func[1]); bus->cur_read.len = 0; return 0; } @@ -1406,8 +1397,11 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) pfirst->prev); } /* sent any remaining packets up */ - if (bus->glom.qlen) + if (bus->glom.qlen) { + up(&bus->sdsem); brcmf_rx_frame(bus->sdiodev->dev, ifidx, &bus->glom); + down(&bus->sdsem); + } bus->sdcnt.rxglomframes++; bus->sdcnt.rxglompkts += bus->glom.qlen; @@ -1448,24 +1442,21 @@ static void brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) { uint rdlen, pad; - u8 *buf = NULL, *rbuf; + int sdret; brcmf_dbg(TRACE, "Enter\n"); - if (bus->rxblen) - buf = vzalloc(bus->rxblen); - if (!buf) { - brcmf_dbg(ERROR, "no memory for control frame\n"); - goto done; - } - rbuf = bus->rxbuf; - pad = ((unsigned long)rbuf % BRCMF_SDALIGN); + /* Set rxctl for frame (w/optional alignment) */ + bus->rxctl = bus->rxbuf; + bus->rxctl += BRCMF_FIRSTREAD; + pad = ((unsigned long)bus->rxctl % BRCMF_SDALIGN); if (pad) - rbuf += (BRCMF_SDALIGN - pad); + bus->rxctl += (BRCMF_SDALIGN - pad); + bus->rxctl -= BRCMF_FIRSTREAD; /* Copy the already-read portion over */ - memcpy(buf, hdr, BRCMF_FIRSTREAD); + memcpy(bus->rxctl, hdr, BRCMF_FIRSTREAD); if (len <= BRCMF_FIRSTREAD) goto gotpkt; @@ -1502,11 +1493,11 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) goto done; } - /* Read remain of frame body */ + /* Read remainder of frame body into the rxctl buffer */ sdret = brcmf_sdcard_recv_buf(bus->sdiodev, bus->sdiodev->sbwad, SDIO_FUNC_2, - F2SYNC, rbuf, rdlen); + F2SYNC, (bus->rxctl + BRCMF_FIRSTREAD), rdlen); bus->sdcnt.f2rxdata++; /* Control frame failures need retransmission */ @@ -1516,26 +1507,16 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) bus->sdcnt.rxc_errors++; brcmf_sdbrcm_rxfail(bus, true, true); goto done; - } else - memcpy(buf + BRCMF_FIRSTREAD, rbuf, rdlen); + } gotpkt: brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(), - buf, len, "RxCtrl:\n"); + bus->rxctl, len, "RxCtrl:\n"); /* Point to valid data and indicate its length */ - spin_lock_bh(&bus->rxctl_lock); - if (bus->rxctl) { - brcmf_dbg(ERROR, "last control frame is being processed.\n"); - spin_unlock_bh(&bus->rxctl_lock); - vfree(buf); - goto done; - } - bus->rxctl = buf + doff; - bus->rxctl_orig = buf; + bus->rxctl += doff; bus->rxlen = len - doff; - spin_unlock_bh(&bus->rxctl_lock); done: /* Awake any waiters */ @@ -1590,7 +1571,6 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) rd->len_left = rd->len; /* read header first for unknow frame length */ - sdio_claim_host(bus->sdiodev->func[1]); if (!rd->len) { sdret = brcmf_sdcard_recv_buf(bus->sdiodev, bus->sdiodev->sbwad, @@ -1603,7 +1583,6 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) sdret); bus->sdcnt.rx_hdrfail++; brcmf_sdbrcm_rxfail(bus, true, true); - sdio_release_host(bus->sdiodev->func[1]); continue; } @@ -1611,9 +1590,8 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) bus->rxhdr, SDPCM_HDRLEN, "RxHdr:\n"); - if (brcmf_sdio_hdparser(bus, bus->rxhdr, rd, - BRCMF_SDIO_FT_NORMAL)) { - sdio_release_host(bus->sdiodev->func[1]); + if (!brcmf_sdio_hdparser(bus, bus->rxhdr, rd, + BRCMF_SDIO_FT_NORMAL)) { if (!bus->rxpending) break; else @@ -1629,7 +1607,6 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) rd->len_nxtfrm = 0; /* treat all packet as event if we don't know */ rd->channel = SDPCM_EVENT_CHANNEL; - sdio_release_host(bus->sdiodev->func[1]); continue; } rd->len_left = rd->len > BRCMF_FIRSTREAD ? @@ -1647,7 +1624,6 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) bus->sdiodev->bus_if->dstats.rx_dropped++; brcmf_sdbrcm_rxfail(bus, false, RETRYCHAN(rd->channel)); - sdio_release_host(bus->sdiodev->func[1]); continue; } skb_pull(pkt, head_read); @@ -1656,17 +1632,14 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad, SDIO_FUNC_2, F2SYNC, pkt); bus->sdcnt.f2rxdata++; - sdio_release_host(bus->sdiodev->func[1]); if (sdret < 0) { brcmf_dbg(ERROR, "read %d bytes from channel %d failed: %d\n", rd->len, rd->channel, sdret); brcmu_pkt_buf_free_skb(pkt); bus->sdiodev->bus_if->dstats.rx_errors++; - sdio_claim_host(bus->sdiodev->func[1]); brcmf_sdbrcm_rxfail(bus, true, RETRYCHAN(rd->channel)); - sdio_release_host(bus->sdiodev->func[1]); continue; } @@ -1677,9 +1650,8 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) } else { memcpy(bus->rxhdr, pkt->data, SDPCM_HDRLEN); rd_new.seq_num = rd->seq_num; - sdio_claim_host(bus->sdiodev->func[1]); - if (brcmf_sdio_hdparser(bus, bus->rxhdr, &rd_new, - BRCMF_SDIO_FT_NORMAL)) { + if (!brcmf_sdio_hdparser(bus, bus->rxhdr, &rd_new, + BRCMF_SDIO_FT_NORMAL)) { rd->len = 0; brcmu_pkt_buf_free_skb(pkt); } @@ -1690,11 +1662,9 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) roundup(rd_new.len, 16) >> 4); rd->len = 0; brcmf_sdbrcm_rxfail(bus, true, true); - sdio_release_host(bus->sdiodev->func[1]); brcmu_pkt_buf_free_skb(pkt); continue; } - sdio_release_host(bus->sdiodev->func[1]); rd->len_nxtfrm = rd_new.len_nxtfrm; rd->channel = rd_new.channel; rd->dat_offset = rd_new.dat_offset; @@ -1710,9 +1680,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) rd_new.seq_num); /* Force retry w/normal header read */ rd->len = 0; - sdio_claim_host(bus->sdiodev->func[1]); brcmf_sdbrcm_rxfail(bus, false, true); - sdio_release_host(bus->sdiodev->func[1]); brcmu_pkt_buf_free_skb(pkt); continue; } @@ -1735,9 +1703,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) } else { brcmf_dbg(ERROR, "%s: glom superframe w/o " "descriptor!\n", __func__); - sdio_claim_host(bus->sdiodev->func[1]); brcmf_sdbrcm_rxfail(bus, false, false); - sdio_release_host(bus->sdiodev->func[1]); } /* prepare the descriptor for the next read */ rd->len = rd->len_nxtfrm << 4; @@ -1768,7 +1734,10 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) continue; } + /* Unlock during rx call */ + up(&bus->sdsem); brcmf_rx_packet(bus->sdiodev->dev, ifidx, pkt); + down(&bus->sdsem); } rxcount = maxframes - rxleft; @@ -1785,6 +1754,15 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) return rxcount; } +static void +brcmf_sdbrcm_wait_for_event(struct brcmf_sdio *bus, bool *lockvar) +{ + up(&bus->sdsem); + wait_event_interruptible_timeout(bus->ctrl_wait, !*lockvar, HZ * 2); + down(&bus->sdsem); + return; +} + static void brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus) { @@ -1886,7 +1864,6 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, if (len & (ALIGNMENT - 1)) len = roundup(len, ALIGNMENT); - sdio_claim_host(bus->sdiodev->func[1]); ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad, SDIO_FUNC_2, F2SYNC, pkt); bus->sdcnt.f2txdata++; @@ -1914,14 +1891,15 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, } } - sdio_release_host(bus->sdiodev->func[1]); if (ret == 0) bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; done: /* restore pkt buffer pointer before calling tx complete routine */ skb_pull(pkt, SDPCM_HDRLEN + pad); + up(&bus->sdsem); brcmf_txcomplete(bus->sdiodev->dev, pkt, ret != 0); + down(&bus->sdsem); if (free_pkt) brcmu_pkt_buf_free_skb(pkt); @@ -1962,11 +1940,9 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes) /* In poll mode, need to check for other events */ if (!bus->intr && cnt) { /* Check device status, signal pending interrupt */ - sdio_claim_host(bus->sdiodev->func[1]); ret = r_sdreg32(bus, &intstatus, offsetof(struct sdpcmd_regs, intstatus)); - sdio_release_host(bus->sdiodev->func[1]); bus->sdcnt.f2txdata++; if (ret != 0) break; @@ -2003,7 +1979,7 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev) bus->watchdog_tsk = NULL; } - sdio_claim_host(bus->sdiodev->func[1]); + down(&bus->sdsem); /* Enable clock for device interrupts */ brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); @@ -2037,7 +2013,6 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev) /* Turn off the backplane clock (only) */ brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); - sdio_release_host(bus->sdiodev->func[1]); /* Clear the data packet queues */ brcmu_pktq_flush(&bus->txq, true, NULL, NULL); @@ -2048,14 +2023,14 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev) brcmf_sdbrcm_free_glom(bus); /* Clear rx control and wake any waiters */ - spin_lock_bh(&bus->rxctl_lock); bus->rxlen = 0; - spin_unlock_bh(&bus->rxctl_lock); brcmf_sdbrcm_dcmd_resp_wake(bus); /* Reset some F2 state stuff */ bus->rxskip = false; bus->tx_seq = bus->rx_seq = 0; + + up(&bus->sdsem); } #ifdef CONFIG_BRCMFMAC_SDIO_OOB @@ -2139,7 +2114,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) brcmf_dbg(TRACE, "Enter\n"); - sdio_claim_host(bus->sdiodev->func[1]); + down(&bus->sdsem); /* If waiting for HTAVAIL, check status */ if (bus->clkstate == CLK_PENDING) { @@ -2193,7 +2168,9 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) /* Pending interrupt indicates new device status */ if (atomic_read(&bus->ipend) > 0) { atomic_set(&bus->ipend, 0); + sdio_claim_host(bus->sdiodev->func[1]); err = brcmf_sdio_intr_rstatus(bus); + sdio_release_host(bus->sdiodev->func[1]); } /* Start with leftover status bits */ @@ -2222,8 +2199,6 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) intstatus |= brcmf_sdbrcm_hostmail(bus); } - sdio_release_host(bus->sdiodev->func[1]); - /* Generally don't ask for these, can get CRC errors... */ if (intstatus & I_WR_OOSYNC) { brcmf_dbg(ERROR, "Dongle reports WR_OOSYNC\n"); @@ -2270,7 +2245,6 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) (bus->clkstate == CLK_AVAIL)) { int i; - sdio_claim_host(bus->sdiodev->func[1]); err = brcmf_sdcard_send_buf(bus->sdiodev, bus->sdiodev->sbwad, SDIO_FUNC_2, F2SYNC, bus->ctrl_frame_buf, (u32) bus->ctrl_frame_len); @@ -2304,7 +2278,6 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) } else { bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; } - sdio_release_host(bus->sdiodev->func[1]); bus->ctrl_frame_stat = false; brcmf_sdbrcm_wait_event_wakeup(bus); } @@ -2334,10 +2307,10 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) if ((bus->clkstate != CLK_PENDING) && bus->idletime == BRCMF_IDLE_IMMEDIATE) { bus->activity = false; - sdio_claim_host(bus->sdiodev->func[1]); brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); - sdio_release_host(bus->sdiodev->func[1]); } + + up(&bus->sdsem); } static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) @@ -2628,10 +2601,11 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) /* precondition: IS_ALIGNED((unsigned long)frame, 2) */ + /* Need to lock here to protect txseq and SDIO tx calls */ + down(&bus->sdsem); + /* Make sure backplane clock is on */ - sdio_claim_host(bus->sdiodev->func[1]); brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); - sdio_release_host(bus->sdiodev->func[1]); /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */ *(__le16 *) frame = cpu_to_le16((u16) msglen); @@ -2654,9 +2628,7 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) bus->ctrl_frame_buf = frame; bus->ctrl_frame_len = len; - wait_event_interruptible_timeout(bus->ctrl_wait, - !bus->ctrl_frame_stat, - msecs_to_jiffies(2000)); + brcmf_sdbrcm_wait_for_event(bus, &bus->ctrl_frame_stat); if (!bus->ctrl_frame_stat) { brcmf_dbg(INFO, "ctrl_frame_stat == false\n"); @@ -2675,9 +2647,7 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) frame, min_t(u16, len, 16), "TxHdr:\n"); do { - sdio_claim_host(bus->sdiodev->func[1]); ret = brcmf_tx_frame(bus, frame, len); - sdio_release_host(bus->sdiodev->func[1]); } while (ret < 0 && retries++ < TXRETRIES); } @@ -2687,13 +2657,13 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); bus->activity = false; - sdio_claim_host(bus->sdiodev->func[1]); brcmf_sdbrcm_clkctl(bus, CLK_NONE, true); - sdio_release_host(bus->sdiodev->func[1]); } else { spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); } + up(&bus->sdsem); + if (ret) bus->sdcnt.tx_ctlerrs++; else @@ -2723,10 +2693,8 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus, * Read last word in socram to determine * address of sdpcm_shared structure */ - sdio_claim_host(bus->sdiodev->func[1]); rv = brcmf_sdbrcm_membytes(bus, false, shaddr, (u8 *)&addr_le, 4); - sdio_claim_host(bus->sdiodev->func[1]); if (rv < 0) return rv; @@ -2745,10 +2713,8 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus, } /* Read hndrte_shared structure */ - sdio_claim_host(bus->sdiodev->func[1]); rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&sh_le, sizeof(struct sdpcm_shared_le)); - sdio_release_host(bus->sdiodev->func[1]); if (rv < 0) return rv; @@ -2851,14 +2817,12 @@ static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh, if ((sh->flags & SDPCM_SHARED_TRAP) == 0) return 0; - sdio_claim_host(bus->sdiodev->func[1]); error = brcmf_sdbrcm_membytes(bus, false, sh->trap_addr, (u8 *)&tr, sizeof(struct brcmf_trap_info)); if (error < 0) return error; nbytes = brcmf_sdio_dump_console(bus, sh, data, count); - sdio_release_host(bus->sdiodev->func[1]); if (nbytes < 0) return nbytes; @@ -2904,7 +2868,6 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus, return 0; } - sdio_claim_host(bus->sdiodev->func[1]); if (sh->assert_file_addr != 0) { error = brcmf_sdbrcm_membytes(bus, false, sh->assert_file_addr, (u8 *)file, 80); @@ -2917,7 +2880,6 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus, if (error < 0) return error; } - sdio_release_host(bus->sdiodev->func[1]); res = scnprintf(buf, sizeof(buf), "dongle assert: %s:%d: assert(%s)\n", @@ -2930,7 +2892,9 @@ static int brcmf_sdbrcm_checkdied(struct brcmf_sdio *bus) int error; struct sdpcm_shared sh; + down(&bus->sdsem); error = brcmf_sdio_readshared(bus, &sh); + up(&bus->sdsem); if (error < 0) return error; @@ -2957,6 +2921,7 @@ static int brcmf_sdbrcm_died_dump(struct brcmf_sdio *bus, char __user *data, if (pos != 0) return 0; + down(&bus->sdsem); error = brcmf_sdio_readshared(bus, &sh); if (error < 0) goto done; @@ -2973,6 +2938,7 @@ static int brcmf_sdbrcm_died_dump(struct brcmf_sdio *bus, char __user *data, error += nbytes; *ppos += error; done: + up(&bus->sdsem); return error; } @@ -3023,7 +2989,6 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) int timeleft; uint rxlen = 0; bool pending; - u8 *buf; struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; struct brcmf_sdio *bus = sdiodev->bus; @@ -3033,15 +2998,11 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) /* Wait until control frame is available */ timeleft = brcmf_sdbrcm_dcmd_resp_wait(bus, &bus->rxlen, &pending); - spin_lock_bh(&bus->rxctl_lock); + down(&bus->sdsem); rxlen = bus->rxlen; memcpy(msg, bus->rxctl, min(msglen, rxlen)); - bus->rxctl = NULL; - buf = bus->rxctl_orig; - bus->rxctl_orig = NULL; bus->rxlen = 0; - spin_unlock_bh(&bus->rxctl_lock); - vfree(buf); + up(&bus->sdsem); if (rxlen) { brcmf_dbg(CTL, "resumed on rxctl frame, got %d expected %d\n", @@ -3377,16 +3338,13 @@ brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus) { bool ret; - sdio_claim_host(bus->sdiodev->func[1]); - + /* Download the firmware */ brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); ret = _brcmf_sdbrcm_download_firmware(bus) == 0; brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); - sdio_release_host(bus->sdiodev->func[1]); - return ret; } @@ -3415,7 +3373,7 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) bus->sdcnt.tickcnt = 0; brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); - sdio_claim_host(bus->sdiodev->func[1]); + down(&bus->sdsem); /* Make sure backplane clock is on, needed to generate F2 interrupt */ brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); @@ -3484,7 +3442,7 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); exit: - sdio_release_host(bus->sdiodev->func[1]); + up(&bus->sdsem); return ret; } @@ -3531,6 +3489,8 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) brcmf_dbg(TIMER, "Enter\n"); + down(&bus->sdsem); + /* Poll period: check device if appropriate. */ if (bus->poll && (++bus->polltick >= bus->pollrate)) { u32 intstatus = 0; @@ -3547,11 +3507,9 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) u8 devpend; spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); - sdio_claim_host(bus->sdiodev->func[1]); devpend = brcmf_sdio_regrb(bus->sdiodev, SDIO_CCCR_INTx, NULL); - sdio_release_host(bus->sdiodev->func[1]); intstatus = devpend & (INTR_STATUS_FUNC1 | INTR_STATUS_FUNC2); @@ -3576,18 +3534,16 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) } #ifdef DEBUG /* Poll for console output periodically */ - if (bus_if && bus_if->state == BRCMF_BUS_DATA && + if (bus_if->state == BRCMF_BUS_DATA && bus->console_interval != 0) { bus->console.count += BRCMF_WD_POLL_MS; if (bus->console.count >= bus->console_interval) { bus->console.count -= bus->console_interval; - sdio_claim_host(bus->sdiodev->func[1]); /* Make sure backplane clock is on */ brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); if (brcmf_sdbrcm_readconsole(bus) < 0) /* stop on error */ bus->console_interval = 0; - sdio_release_host(bus->sdiodev->func[1]); } } #endif /* DEBUG */ @@ -3600,13 +3556,13 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) bus->activity = false; brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); } else { - sdio_claim_host(bus->sdiodev->func[1]); brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); - sdio_release_host(bus->sdiodev->func[1]); } } } + up(&bus->sdsem); + return (atomic_read(&bus->ipend) > 0); } @@ -3701,8 +3657,6 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva) bus->alp_only = true; - sdio_claim_host(bus->sdiodev->func[1]); - pr_debug("F1 signature read @0x18000000=0x%4x\n", brcmf_sdio_regrl(bus->sdiodev, SI_ENUM_BASE, NULL)); @@ -3750,8 +3704,6 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva) reg_val = brcmf_sdio_regrl(bus->sdiodev, reg_addr, NULL); brcmf_sdio_regwl(bus->sdiodev, reg_addr, reg_val | CC_BPRESEN, NULL); - sdio_release_host(bus->sdiodev->func[1]); - brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN); /* Locate an appropriately-aligned portion of hdrbuf */ @@ -3767,7 +3719,6 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva) return true; fail: - sdio_release_host(bus->sdiodev->func[1]); return false; } @@ -3775,8 +3726,6 @@ static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus) { brcmf_dbg(TRACE, "Enter\n"); - sdio_claim_host(bus->sdiodev->func[1]); - /* Disable F2 to clear any intermediate frame state on the dongle */ brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, SDIO_FUNC_ENABLE_1, NULL); @@ -3787,8 +3736,6 @@ static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus) /* Done with backplane-dependent accesses, can drop clock... */ brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); - sdio_release_host(bus->sdiodev->func[1]); - /* ...and initialize clock/power states */ bus->clkstate = CLK_SDONLY; bus->idletime = BRCMF_IDLE_INTERVAL; @@ -3844,10 +3791,8 @@ static void brcmf_sdbrcm_release_dongle(struct brcmf_sdio *bus) brcmf_dbg(TRACE, "Enter\n"); if (bus->ci) { - sdio_claim_host(bus->sdiodev->func[1]); brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); - sdio_release_host(bus->sdiodev->func[1]); brcmf_sdio_chip_detach(&bus->ci); if (bus->vars && bus->varsz) kfree(bus->vars); @@ -3867,8 +3812,7 @@ static void brcmf_sdbrcm_release(struct brcmf_sdio *bus) brcmf_sdio_intr_unregister(bus->sdiodev); cancel_work_sync(&bus->datawork); - if (bus->brcmf_wq) - destroy_workqueue(bus->brcmf_wq); + destroy_workqueue(bus->brcmf_wq); if (bus->sdiodev->bus_if->drvr) { brcmf_detach(bus->sdiodev->dev); @@ -3910,29 +3854,31 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) bus->txminmax = BRCMF_TXMINMAX; bus->tx_seq = SDPCM_SEQUENCE_WRAP - 1; - INIT_WORK(&bus->datawork, brcmf_sdio_dataworker); - bus->brcmf_wq = create_singlethread_workqueue("brcmf_wq"); - if (bus->brcmf_wq == NULL) { - brcmf_dbg(ERROR, "insufficient memory to create txworkqueue\n"); - goto fail; - } - /* attempt to attach to the dongle */ if (!(brcmf_sdbrcm_probe_attach(bus, regsva))) { brcmf_dbg(ERROR, "brcmf_sdbrcm_probe_attach failed\n"); goto fail; } - spin_lock_init(&bus->rxctl_lock); spin_lock_init(&bus->txqlock); init_waitqueue_head(&bus->ctrl_wait); init_waitqueue_head(&bus->dcmd_resp_wait); + bus->brcmf_wq = create_singlethread_workqueue("brcmf_wq"); + if (bus->brcmf_wq == NULL) { + brcmf_dbg(ERROR, "insufficient memory to create txworkqueue\n"); + goto fail; + } + INIT_WORK(&bus->datawork, brcmf_sdio_dataworker); + /* Set up the watchdog timer */ init_timer(&bus->timer); bus->timer.data = (unsigned long)bus; bus->timer.function = brcmf_sdbrcm_watchdog; + /* Initialize thread based operation and lock */ + sema_init(&bus->sdsem, 1); + /* Initialize watchdog thread */ init_completion(&bus->watchdog_wait); bus->watchdog_tsk = kthread_run(brcmf_sdbrcm_watchdog_thread, @@ -3995,8 +3941,10 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) /* if firmware path present try to download and bring up bus */ ret = brcmf_bus_start(bus->sdiodev->dev); if (ret != 0) { - brcmf_dbg(ERROR, "dongle is not responding\n"); - goto fail; + if (ret == -ENOLINK) { + brcmf_dbg(ERROR, "dongle is not responding\n"); + goto fail; + } } return bus; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/fweh.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/fweh.c deleted file mode 100644 index 7a00c4614baf..000000000000 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/fweh.c +++ /dev/null @@ -1,509 +0,0 @@ -/* - * Copyright (c) 2012 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#include - -#include "brcmu_wifi.h" -#include "brcmu_utils.h" - -#include "dhd.h" -#include "dhd_dbg.h" -#include "fweh.h" -#include "fwil.h" - -/** - * struct brcm_ethhdr - broadcom specific ether header. - * - * @subtype: subtype for this packet. - * @length: TODO: length of appended data. - * @version: version indication. - * @oui: OUI of this packet. - * @usr_subtype: subtype for this OUI. - */ -struct brcm_ethhdr { - __be16 subtype; - __be16 length; - u8 version; - u8 oui[3]; - __be16 usr_subtype; -} __packed; - -struct brcmf_event_msg_be { - __be16 version; - __be16 flags; - __be32 event_type; - __be32 status; - __be32 reason; - __be32 auth_type; - __be32 datalen; - u8 addr[ETH_ALEN]; - char ifname[IFNAMSIZ]; - u8 ifidx; - u8 bsscfgidx; -} __packed; - -/** - * struct brcmf_event - contents of broadcom event packet. - * - * @eth: standard ether header. - * @hdr: broadcom specific ether header. - * @msg: common part of the actual event message. - */ -struct brcmf_event { - struct ethhdr eth; - struct brcm_ethhdr hdr; - struct brcmf_event_msg_be msg; -} __packed; - -/** - * struct brcmf_fweh_queue_item - event item on event queue. - * - * @q: list element for queuing. - * @code: event code. - * @ifidx: interface index related to this event. - * @ifaddr: ethernet address for interface. - * @emsg: common parameters of the firmware event message. - * @data: event specific data part of the firmware event. - */ -struct brcmf_fweh_queue_item { - struct list_head q; - enum brcmf_fweh_event_code code; - u8 ifidx; - u8 ifaddr[ETH_ALEN]; - struct brcmf_event_msg_be emsg; - u8 data[0]; -}; - -/** - * struct brcmf_fweh_event_name - code, name mapping entry. - */ -struct brcmf_fweh_event_name { - enum brcmf_fweh_event_code code; - const char *name; -}; - -#ifdef DEBUG -/* array for mapping code to event name */ -static struct brcmf_fweh_event_name fweh_event_names[] = { - { BRCMF_E_SET_SSID, "SET_SSID" }, - { BRCMF_E_JOIN, "JOIN" }, - { BRCMF_E_START, "START" }, - { BRCMF_E_AUTH, "AUTH" }, - { BRCMF_E_AUTH_IND, "AUTH_IND" }, - { BRCMF_E_DEAUTH, "DEAUTH" }, - { BRCMF_E_DEAUTH_IND, "DEAUTH_IND" }, - { BRCMF_E_ASSOC, "ASSOC" }, - { BRCMF_E_ASSOC_IND, "ASSOC_IND" }, - { BRCMF_E_REASSOC, "REASSOC" }, - { BRCMF_E_REASSOC_IND, "REASSOC_IND" }, - { BRCMF_E_DISASSOC, "DISASSOC" }, - { BRCMF_E_DISASSOC_IND, "DISASSOC_IND" }, - { BRCMF_E_QUIET_START, "START_QUIET" }, - { BRCMF_E_QUIET_END, "END_QUIET" }, - { BRCMF_E_BEACON_RX, "BEACON_RX" }, - { BRCMF_E_LINK, "LINK" }, - { BRCMF_E_MIC_ERROR, "MIC_ERROR" }, - { BRCMF_E_NDIS_LINK, "NDIS_LINK" }, - { BRCMF_E_ROAM, "ROAM" }, - { BRCMF_E_TXFAIL, "TXFAIL" }, - { BRCMF_E_PMKID_CACHE, "PMKID_CACHE" }, - { BRCMF_E_RETROGRADE_TSF, "RETROGRADE_TSF" }, - { BRCMF_E_PRUNE, "PRUNE" }, - { BRCMF_E_AUTOAUTH, "AUTOAUTH" }, - { BRCMF_E_EAPOL_MSG, "EAPOL_MSG" }, - { BRCMF_E_SCAN_COMPLETE, "SCAN_COMPLETE" }, - { BRCMF_E_ADDTS_IND, "ADDTS_IND" }, - { BRCMF_E_DELTS_IND, "DELTS_IND" }, - { BRCMF_E_BCNSENT_IND, "BCNSENT_IND" }, - { BRCMF_E_BCNRX_MSG, "BCNRX_MSG" }, - { BRCMF_E_BCNLOST_MSG, "BCNLOST_MSG" }, - { BRCMF_E_ROAM_PREP, "ROAM_PREP" }, - { BRCMF_E_PFN_NET_FOUND, "PNO_NET_FOUND" }, - { BRCMF_E_PFN_NET_LOST, "PNO_NET_LOST" }, - { BRCMF_E_RESET_COMPLETE, "RESET_COMPLETE" }, - { BRCMF_E_JOIN_START, "JOIN_START" }, - { BRCMF_E_ROAM_START, "ROAM_START" }, - { BRCMF_E_ASSOC_START, "ASSOC_START" }, - { BRCMF_E_IBSS_ASSOC, "IBSS_ASSOC" }, - { BRCMF_E_RADIO, "RADIO" }, - { BRCMF_E_PSM_WATCHDOG, "PSM_WATCHDOG" }, - { BRCMF_E_PROBREQ_MSG, "PROBREQ_MSG" }, - { BRCMF_E_SCAN_CONFIRM_IND, "SCAN_CONFIRM_IND" }, - { BRCMF_E_PSK_SUP, "PSK_SUP" }, - { BRCMF_E_COUNTRY_CODE_CHANGED, "COUNTRY_CODE_CHANGED" }, - { BRCMF_E_EXCEEDED_MEDIUM_TIME, "EXCEEDED_MEDIUM_TIME" }, - { BRCMF_E_ICV_ERROR, "ICV_ERROR" }, - { BRCMF_E_UNICAST_DECODE_ERROR, "UNICAST_DECODE_ERROR" }, - { BRCMF_E_MULTICAST_DECODE_ERROR, "MULTICAST_DECODE_ERROR" }, - { BRCMF_E_TRACE, "TRACE" }, - { BRCMF_E_IF, "IF" }, - { BRCMF_E_RSSI, "RSSI" }, - { BRCMF_E_PFN_SCAN_COMPLETE, "PFN_SCAN_COMPLETE" }, - { BRCMF_E_EXTLOG_MSG, "EXTLOG_MSG" }, - { BRCMF_E_ACTION_FRAME, "ACTION_FRAME" }, - { BRCMF_E_ACTION_FRAME_COMPLETE, "ACTION_FRAME_COMPLETE" }, - { BRCMF_E_PRE_ASSOC_IND, "PRE_ASSOC_IND" }, - { BRCMF_E_PRE_REASSOC_IND, "PRE_REASSOC_IND" }, - { BRCMF_E_CHANNEL_ADOPTED, "CHANNEL_ADOPTED" }, - { BRCMF_E_AP_STARTED, "AP_STARTED" }, - { BRCMF_E_DFS_AP_STOP, "DFS_AP_STOP" }, - { BRCMF_E_DFS_AP_RESUME, "DFS_AP_RESUME" }, - { BRCMF_E_ESCAN_RESULT, "ESCAN_RESULT" }, - { BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE, "ACTION_FRM_OFF_CHAN_CMPLT" }, - { BRCMF_E_DCS_REQUEST, "DCS_REQUEST" }, - { BRCMF_E_FIFO_CREDIT_MAP, "FIFO_CREDIT_MAP"} -}; - -/** - * brcmf_fweh_event_name() - returns name for given event code. - * - * @code: code to lookup. - */ -static const char *brcmf_fweh_event_name(enum brcmf_fweh_event_code code) -{ - int i; - for (i = 0; i < ARRAY_SIZE(fweh_event_names); i++) { - if (fweh_event_names[i].code == code) - return fweh_event_names[i].name; - } - return "unknown"; -} -#else -static const char *brcmf_fweh_event_name(enum brcmf_fweh_event_code code) -{ - return "nodebug"; -} -#endif - -/** - * brcmf_fweh_queue_event() - create and queue event. - * - * @fweh: firmware event handling info. - * @event: event queue entry. - */ -static void brcmf_fweh_queue_event(struct brcmf_fweh_info *fweh, - struct brcmf_fweh_queue_item *event) -{ - ulong flags; - - spin_lock_irqsave(&fweh->evt_q_lock, flags); - list_add_tail(&event->q, &fweh->event_q); - spin_unlock_irqrestore(&fweh->evt_q_lock, flags); - schedule_work(&fweh->event_work); -} - -static int brcmf_fweh_call_event_handler(struct brcmf_if *ifp, - enum brcmf_fweh_event_code code, - struct brcmf_event_msg *emsg, - void *data) -{ - struct brcmf_fweh_info *fweh; - int err = -EINVAL; - - if (ifp) { - fweh = &ifp->drvr->fweh; - - /* handle the event if valid interface and handler */ - if (ifp->ndev && fweh->evt_handler[code]) - err = fweh->evt_handler[code](ifp, emsg, data); - else - brcmf_dbg(ERROR, "unhandled event %d ignored\n", code); - } else { - brcmf_dbg(ERROR, "no interface object\n"); - } - return err; -} - -/** - * brcmf_fweh_handle_if_event() - handle IF event. - * - * @drvr: driver information object. - * @item: queue entry. - * @ifpp: interface object (may change upon ADD action). - */ -static void brcmf_fweh_handle_if_event(struct brcmf_pub *drvr, - struct brcmf_event_msg *emsg, - void *data) -{ - struct brcmf_if_event *ifevent = data; - struct brcmf_if *ifp; - int err = 0; - - brcmf_dbg(EVENT, "action: %u idx: %u bsscfg: %u flags: %u\n", - ifevent->action, ifevent->ifidx, - ifevent->bssidx, ifevent->flags); - - if (ifevent->ifidx >= BRCMF_MAX_IFS) { - brcmf_dbg(ERROR, "invalid interface index: %u\n", - ifevent->ifidx); - return; - } - - ifp = drvr->iflist[ifevent->ifidx]; - - if (ifevent->action == BRCMF_E_IF_ADD) { - brcmf_dbg(EVENT, "adding %s (%pM)\n", emsg->ifname, - emsg->addr); - ifp = brcmf_add_if(drvr, ifevent->ifidx, ifevent->bssidx, - emsg->ifname, emsg->addr); - if (IS_ERR(ifp)) - return; - - if (!drvr->fweh.evt_handler[BRCMF_E_IF]) - err = brcmf_net_attach(ifp); - } - - err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data); - - if (ifevent->action == BRCMF_E_IF_DEL) - brcmf_del_if(drvr, ifevent->ifidx); -} - -/** - * brcmf_fweh_dequeue_event() - get event from the queue. - * - * @fweh: firmware event handling info. - */ -static struct brcmf_fweh_queue_item * -brcmf_fweh_dequeue_event(struct brcmf_fweh_info *fweh) -{ - struct brcmf_fweh_queue_item *event = NULL; - ulong flags; - - spin_lock_irqsave(&fweh->evt_q_lock, flags); - if (!list_empty(&fweh->event_q)) { - event = list_first_entry(&fweh->event_q, - struct brcmf_fweh_queue_item, q); - list_del(&event->q); - } - spin_unlock_irqrestore(&fweh->evt_q_lock, flags); - - return event; -} - -/** - * brcmf_fweh_event_worker() - firmware event worker. - * - * @work: worker object. - */ -static void brcmf_fweh_event_worker(struct work_struct *work) -{ - struct brcmf_pub *drvr; - struct brcmf_if *ifp; - struct brcmf_fweh_info *fweh; - struct brcmf_fweh_queue_item *event; - int err = 0; - struct brcmf_event_msg_be *emsg_be; - struct brcmf_event_msg emsg; - - fweh = container_of(work, struct brcmf_fweh_info, event_work); - drvr = container_of(fweh, struct brcmf_pub, fweh); - - while ((event = brcmf_fweh_dequeue_event(fweh))) { - ifp = drvr->iflist[event->ifidx]; - - brcmf_dbg(EVENT, "event %s (%u) ifidx %u bsscfg %u addr %pM\n", - brcmf_fweh_event_name(event->code), event->code, - event->emsg.ifidx, event->emsg.bsscfgidx, - event->emsg.addr); - - /* convert event message */ - emsg_be = &event->emsg; - emsg.version = be16_to_cpu(emsg_be->version); - emsg.flags = be16_to_cpu(emsg_be->flags); - emsg.event_code = event->code; - emsg.status = be32_to_cpu(emsg_be->status); - emsg.reason = be32_to_cpu(emsg_be->reason); - emsg.auth_type = be32_to_cpu(emsg_be->auth_type); - emsg.datalen = be32_to_cpu(emsg_be->datalen); - memcpy(emsg.addr, emsg_be->addr, ETH_ALEN); - memcpy(emsg.ifname, emsg_be->ifname, sizeof(emsg.ifname)); - emsg.ifidx = emsg_be->ifidx; - emsg.bsscfgidx = emsg_be->bsscfgidx; - - brcmf_dbg(EVENT, " version %u flags %u status %u reason %u\n", - emsg.version, emsg.flags, emsg.status, emsg.reason); - brcmf_dbg_hex_dump(BRCMF_EVENT_ON(), event->data, - min_t(u32, emsg.datalen, 64), - "event payload, len=%d\n", emsg.datalen); - - /* special handling of interface event */ - if (event->code == BRCMF_E_IF) { - brcmf_fweh_handle_if_event(drvr, &emsg, event->data); - goto event_free; - } - - err = brcmf_fweh_call_event_handler(ifp, event->code, &emsg, - event->data); - if (err) { - brcmf_dbg(ERROR, "event handler failed (%d)\n", - event->code); - err = 0; - } -event_free: - kfree(event); - } -} - -/** - * brcmf_fweh_attach() - initialize firmware event handling. - * - * @drvr: driver information object. - */ -void brcmf_fweh_attach(struct brcmf_pub *drvr) -{ - struct brcmf_fweh_info *fweh = &drvr->fweh; - INIT_WORK(&fweh->event_work, brcmf_fweh_event_worker); - spin_lock_init(&fweh->evt_q_lock); - INIT_LIST_HEAD(&fweh->event_q); -} - -/** - * brcmf_fweh_detach() - cleanup firmware event handling. - * - * @drvr: driver information object. - */ -void brcmf_fweh_detach(struct brcmf_pub *drvr) -{ - struct brcmf_fweh_info *fweh = &drvr->fweh; - struct brcmf_if *ifp = drvr->iflist[0]; - s8 eventmask[BRCMF_EVENTING_MASK_LEN]; - - if (ifp) { - /* clear all events */ - memset(eventmask, 0, BRCMF_EVENTING_MASK_LEN); - (void)brcmf_fil_iovar_data_set(ifp, "event_msgs", - eventmask, - BRCMF_EVENTING_MASK_LEN); - } - /* cancel the worker */ - cancel_work_sync(&fweh->event_work); - WARN_ON(!list_empty(&fweh->event_q)); - memset(fweh->evt_handler, 0, sizeof(fweh->evt_handler)); -} - -/** - * brcmf_fweh_register() - register handler for given event code. - * - * @drvr: driver information object. - * @code: event code. - * @handler: handler for the given event code. - */ -int brcmf_fweh_register(struct brcmf_pub *drvr, enum brcmf_fweh_event_code code, - brcmf_fweh_handler_t handler) -{ - if (drvr->fweh.evt_handler[code]) { - brcmf_dbg(ERROR, "event code %d already registered\n", code); - return -ENOSPC; - } - drvr->fweh.evt_handler[code] = handler; - brcmf_dbg(TRACE, "event handler registered for %s\n", - brcmf_fweh_event_name(code)); - return 0; -} - -/** - * brcmf_fweh_unregister() - remove handler for given code. - * - * @drvr: driver information object. - * @code: event code. - */ -void brcmf_fweh_unregister(struct brcmf_pub *drvr, - enum brcmf_fweh_event_code code) -{ - brcmf_dbg(TRACE, "event handler cleared for %s\n", - brcmf_fweh_event_name(code)); - drvr->fweh.evt_handler[code] = NULL; -} - -/** - * brcmf_fweh_activate_events() - enables firmware events registered. - * - * @ifp: primary interface object. - */ -int brcmf_fweh_activate_events(struct brcmf_if *ifp) -{ - int i, err; - s8 eventmask[BRCMF_EVENTING_MASK_LEN]; - - for (i = 0; i < BRCMF_E_LAST; i++) { - if (ifp->drvr->fweh.evt_handler[i]) { - brcmf_dbg(EVENT, "enable event %s\n", - brcmf_fweh_event_name(i)); - setbit(eventmask, i); - } - } - - /* want to handle IF event as well */ - brcmf_dbg(EVENT, "enable event IF\n"); - setbit(eventmask, BRCMF_E_IF); - - err = brcmf_fil_iovar_data_set(ifp, "event_msgs", - eventmask, BRCMF_EVENTING_MASK_LEN); - if (err) - brcmf_dbg(ERROR, "Set event_msgs error (%d)\n", err); - - return err; -} - -/** - * brcmf_fweh_process_event() - process skb as firmware event. - * - * @drvr: driver information object. - * @event_packet: event packet to process. - * @ifidx: index of the firmware interface (may change). - * - * If the packet buffer contains a firmware event message it will - * dispatch the event to a registered handler (using worker). - */ -void brcmf_fweh_process_event(struct brcmf_pub *drvr, - struct brcmf_event *event_packet, u8 *ifidx) -{ - enum brcmf_fweh_event_code code; - struct brcmf_fweh_info *fweh = &drvr->fweh; - struct brcmf_fweh_queue_item *event; - gfp_t alloc_flag = GFP_KERNEL; - void *data; - u32 datalen; - - /* get event info */ - code = get_unaligned_be32(&event_packet->msg.event_type); - datalen = get_unaligned_be32(&event_packet->msg.datalen); - *ifidx = event_packet->msg.ifidx; - data = &event_packet[1]; - - if (code >= BRCMF_E_LAST) - return; - - if (code != BRCMF_E_IF && !fweh->evt_handler[code]) - return; - - if (in_interrupt()) - alloc_flag = GFP_ATOMIC; - - event = kzalloc(sizeof(*event) + datalen, alloc_flag); - if (!event) - return; - - event->code = code; - event->ifidx = *ifidx; - - /* use memcpy to get aligned event message */ - memcpy(&event->emsg, &event_packet->msg, sizeof(event->emsg)); - memcpy(event->data, data, datalen); - memcpy(event->ifaddr, event_packet->eth.h_dest, ETH_ALEN); - - brcmf_fweh_queue_event(fweh, event); -} diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/fweh.h b/trunk/drivers/net/wireless/brcm80211/brcmfmac/fweh.h deleted file mode 100644 index b39246a630df..000000000000 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/fweh.h +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (c) 2012 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - - -#ifndef FWEH_H_ -#define FWEH_H_ - -#include -#include -#include -#include - -/* formward declarations */ -struct brcmf_pub; -struct brcmf_if; -struct brcmf_cfg80211_info; -struct brcmf_event; - -/* firmware event codes sent by the dongle */ -enum brcmf_fweh_event_code { - BRCMF_E_SET_SSID = 0, - BRCMF_E_JOIN = 1, - BRCMF_E_START = 2, - BRCMF_E_AUTH = 3, - BRCMF_E_AUTH_IND = 4, - BRCMF_E_DEAUTH = 5, - BRCMF_E_DEAUTH_IND = 6, - BRCMF_E_ASSOC = 7, - BRCMF_E_ASSOC_IND = 8, - BRCMF_E_REASSOC = 9, - BRCMF_E_REASSOC_IND = 10, - BRCMF_E_DISASSOC = 11, - BRCMF_E_DISASSOC_IND = 12, - BRCMF_E_QUIET_START = 13, - BRCMF_E_QUIET_END = 14, - BRCMF_E_BEACON_RX = 15, - BRCMF_E_LINK = 16, - BRCMF_E_MIC_ERROR = 17, - BRCMF_E_NDIS_LINK = 18, - BRCMF_E_ROAM = 19, - BRCMF_E_TXFAIL = 20, - BRCMF_E_PMKID_CACHE = 21, - BRCMF_E_RETROGRADE_TSF = 22, - BRCMF_E_PRUNE = 23, - BRCMF_E_AUTOAUTH = 24, - BRCMF_E_EAPOL_MSG = 25, - BRCMF_E_SCAN_COMPLETE = 26, - BRCMF_E_ADDTS_IND = 27, - BRCMF_E_DELTS_IND = 28, - BRCMF_E_BCNSENT_IND = 29, - BRCMF_E_BCNRX_MSG = 30, - BRCMF_E_BCNLOST_MSG = 31, - BRCMF_E_ROAM_PREP = 32, - BRCMF_E_PFN_NET_FOUND = 33, - BRCMF_E_PFN_NET_LOST = 34, - BRCMF_E_RESET_COMPLETE = 35, - BRCMF_E_JOIN_START = 36, - BRCMF_E_ROAM_START = 37, - BRCMF_E_ASSOC_START = 38, - BRCMF_E_IBSS_ASSOC = 39, - BRCMF_E_RADIO = 40, - BRCMF_E_PSM_WATCHDOG = 41, - BRCMF_E_PROBREQ_MSG = 44, - BRCMF_E_SCAN_CONFIRM_IND = 45, - BRCMF_E_PSK_SUP = 46, - BRCMF_E_COUNTRY_CODE_CHANGED = 47, - BRCMF_E_EXCEEDED_MEDIUM_TIME = 48, - BRCMF_E_ICV_ERROR = 49, - BRCMF_E_UNICAST_DECODE_ERROR = 50, - BRCMF_E_MULTICAST_DECODE_ERROR = 51, - BRCMF_E_TRACE = 52, - BRCMF_E_IF = 54, - BRCMF_E_RSSI = 56, - BRCMF_E_PFN_SCAN_COMPLETE = 57, - BRCMF_E_EXTLOG_MSG = 58, - BRCMF_E_ACTION_FRAME = 59, - BRCMF_E_ACTION_FRAME_COMPLETE = 60, - BRCMF_E_PRE_ASSOC_IND = 61, - BRCMF_E_PRE_REASSOC_IND = 62, - BRCMF_E_CHANNEL_ADOPTED = 63, - BRCMF_E_AP_STARTED = 64, - BRCMF_E_DFS_AP_STOP = 65, - BRCMF_E_DFS_AP_RESUME = 66, - BRCMF_E_ESCAN_RESULT = 69, - BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE = 70, - BRCMF_E_DCS_REQUEST = 73, - BRCMF_E_FIFO_CREDIT_MAP = 74, - BRCMF_E_LAST -}; - -/* flags field values in struct brcmf_event_msg */ -#define BRCMF_EVENT_MSG_LINK 0x01 -#define BRCMF_EVENT_MSG_FLUSHTXQ 0x02 -#define BRCMF_EVENT_MSG_GROUP 0x04 - -/** - * definitions for event packet validation. - */ -#define BRCMF_EVENT_OUI_OFFSET 19 -#define BRCM_OUI "\x00\x10\x18" -#define DOT11_OUI_LEN 3 -#define BCMILCP_BCM_SUBTYPE_EVENT 1 - - -/** - * struct brcmf_event_msg - firmware event message. - * - * @version: version information. - * @flags: event flags. - * @event_code: firmware event code. - * @status: status information. - * @reason: reason code. - * @auth_type: authentication type. - * @datalen: lenght of event data buffer. - * @addr: ether address. - * @ifname: interface name. - * @ifidx: interface index. - * @bsscfgidx: bsscfg index. - */ -struct brcmf_event_msg { - u16 version; - u16 flags; - u32 event_code; - u32 status; - u32 reason; - s32 auth_type; - u32 datalen; - u8 addr[ETH_ALEN]; - char ifname[IFNAMSIZ]; - u8 ifidx; - u8 bsscfgidx; -}; - -typedef int (*brcmf_fweh_handler_t)(struct brcmf_if *ifp, - const struct brcmf_event_msg *evtmsg, - void *data); - -/** - * struct brcmf_fweh_info - firmware event handling information. - * - * @event_work: event worker. - * @evt_q_lock: lock for event queue protection. - * @event_q: event queue. - * @evt_handler: registered event handlers. - */ -struct brcmf_fweh_info { - struct work_struct event_work; - struct spinlock evt_q_lock; - struct list_head event_q; - int (*evt_handler[BRCMF_E_LAST])(struct brcmf_if *ifp, - const struct brcmf_event_msg *evtmsg, - void *data); -}; - -void brcmf_fweh_attach(struct brcmf_pub *drvr); -void brcmf_fweh_detach(struct brcmf_pub *drvr); -int brcmf_fweh_register(struct brcmf_pub *drvr, enum brcmf_fweh_event_code code, - int (*handler)(struct brcmf_if *ifp, - const struct brcmf_event_msg *evtmsg, - void *data)); -void brcmf_fweh_unregister(struct brcmf_pub *drvr, - enum brcmf_fweh_event_code code); -int brcmf_fweh_activate_events(struct brcmf_if *ifp); -void brcmf_fweh_process_event(struct brcmf_pub *drvr, - struct brcmf_event *event_packet, u8 *ifidx); - -static inline void brcmf_fweh_process_skb(struct brcmf_pub *drvr, - struct sk_buff *skb, u8 *ifidx) -{ - struct brcmf_event *event_packet; - u8 *data; - u16 usr_stype; - - /* only process events when protocol matches */ - if (skb->protocol != cpu_to_be16(ETH_P_LINK_CTL)) - return; - - /* check for BRCM oui match */ - event_packet = (struct brcmf_event *)skb_mac_header(skb); - data = (u8 *)event_packet; - data += BRCMF_EVENT_OUI_OFFSET; - if (memcmp(BRCM_OUI, data, DOT11_OUI_LEN)) - return; - - /* final match on usr_subtype */ - data += DOT11_OUI_LEN; - usr_stype = get_unaligned_be16(data); - if (usr_stype != BCMILCP_BCM_SUBTYPE_EVENT) - return; - - brcmf_fweh_process_event(drvr, event_packet, ifidx); -} - -#endif /* FWEH_H_ */ diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/fwil.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/fwil.c index 51a14505197a..4b272c3d237c 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/fwil.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/fwil.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include "dhd.h" @@ -28,16 +29,13 @@ #include "fwil.h" -#define MAX_HEX_DUMP_LEN 64 - - static s32 brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set) { struct brcmf_pub *drvr = ifp->drvr; s32 err; - if (drvr->bus_if->state != BRCMF_BUS_DATA) { + if (drvr->bus_if->state == BRCMF_BUS_DOWN) { brcmf_dbg(ERROR, "bus is down. we have nothing to do.\n"); return -EIO; } @@ -66,8 +64,7 @@ brcmf_fil_cmd_data_set(struct brcmf_if *ifp, u32 cmd, void *data, u32 len) mutex_lock(&ifp->drvr->proto_block); brcmf_dbg(FIL, "cmd=%d, len=%d\n", cmd, len); - brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, - min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); + brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data"); err = brcmf_fil_cmd_data(ifp, cmd, data, len, true); mutex_unlock(&ifp->drvr->proto_block); @@ -84,8 +81,7 @@ brcmf_fil_cmd_data_get(struct brcmf_if *ifp, u32 cmd, void *data, u32 len) err = brcmf_fil_cmd_data(ifp, cmd, data, len, false); brcmf_dbg(FIL, "cmd=%d, len=%d\n", cmd, len); - brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, - min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); + brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data"); mutex_unlock(&ifp->drvr->proto_block); @@ -151,8 +147,7 @@ brcmf_fil_iovar_data_set(struct brcmf_if *ifp, char *name, void *data, mutex_lock(&drvr->proto_block); brcmf_dbg(FIL, "name=%s, len=%d\n", name, len); - brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, - min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); + brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data"); buflen = brcmf_create_iovar(name, data, len, drvr->proto_buf, sizeof(drvr->proto_buf)); @@ -191,8 +186,7 @@ brcmf_fil_iovar_data_get(struct brcmf_if *ifp, char *name, void *data, } brcmf_dbg(FIL, "name=%s, len=%d\n", name, len); - brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, - min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); + brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data"); mutex_unlock(&drvr->proto_block); return err; @@ -274,8 +268,7 @@ brcmf_fil_bsscfg_data_set(struct brcmf_if *ifp, char *name, mutex_lock(&drvr->proto_block); brcmf_dbg(FIL, "bssidx=%d, name=%s, len=%d\n", ifp->bssidx, name, len); - brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, - min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); + brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data"); buflen = brcmf_create_bsscfg(ifp->bssidx, name, data, len, drvr->proto_buf, sizeof(drvr->proto_buf)); @@ -301,7 +294,7 @@ brcmf_fil_bsscfg_data_get(struct brcmf_if *ifp, char *name, mutex_lock(&drvr->proto_block); - buflen = brcmf_create_bsscfg(ifp->bssidx, name, data, len, + buflen = brcmf_create_bsscfg(ifp->bssidx, name, NULL, len, drvr->proto_buf, sizeof(drvr->proto_buf)); if (buflen) { err = brcmf_fil_cmd_data(ifp, BRCMF_C_GET_VAR, drvr->proto_buf, @@ -313,8 +306,7 @@ brcmf_fil_bsscfg_data_get(struct brcmf_if *ifp, char *name, brcmf_dbg(ERROR, "Creating bsscfg failed\n"); } brcmf_dbg(FIL, "bssidx=%d, name=%s, len=%d\n", ifp->bssidx, name, len); - brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, - min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); + brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data"); mutex_unlock(&drvr->proto_block); return err; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/usb.c index 39a5baa92f21..484a6e4f23a2 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/usb.c @@ -14,12 +14,24 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include +#include +#include #include #include #include @@ -30,11 +42,13 @@ #define IOCTL_RESP_TIMEOUT 2000 -#define BRCMF_USB_RESET_GETVER_SPINWAIT 100 /* in unit of ms */ -#define BRCMF_USB_RESET_GETVER_LOOP_CNT 10 +#define BRCMF_USB_DLIMAGE_SPINWAIT 100 /* in unit of ms */ +#define BRCMF_USB_DLIMAGE_LIMIT 500 /* spinwait limit (ms) */ #define BRCMF_POSTBOOT_ID 0xA123 /* ID to detect if dongle has boot up */ +#define BRCMF_USB_RESETCFG_SPINWAIT 1 /* wait after resetcfg (ms) */ + #define BRCMF_USB_NRXQ 50 #define BRCMF_USB_NTXQ 50 @@ -55,6 +69,16 @@ #define BRCMF_USB_43236_FW_NAME "brcm/brcmfmac43236b.bin" #define BRCMF_USB_43242_FW_NAME "brcm/brcmfmac43242a.bin" +enum usbdev_suspend_state { + USBOS_SUSPEND_STATE_DEVICE_ACTIVE = 0, /* Device is busy, won't allow + suspend */ + USBOS_SUSPEND_STATE_SUSPEND_PENDING, /* Device is idle, can be + * suspended. Wating PM to + * suspend the device + */ + USBOS_SUSPEND_STATE_SUSPENDED /* Device suspended */ +}; + struct brcmf_usb_image { struct list_head list; s8 *fwname; @@ -75,8 +99,10 @@ struct brcmf_usbdev_info { struct list_head rx_postq; struct list_head tx_freeq; struct list_head tx_postq; + enum usbdev_suspend_state suspend_state; uint rx_pipe, tx_pipe, intr_pipe, rx_pipe2; + bool activity; int rx_low_watermark; int tx_low_watermark; int tx_high_watermark; @@ -144,7 +170,6 @@ static void brcmf_usb_ioctl_resp_wake(struct brcmf_usbdev_info *devinfo) static void brcmf_usb_ctl_complete(struct brcmf_usbdev_info *devinfo, int type, int status) { - brcmf_dbg(USB, "Enter, status=%d\n", status); if (unlikely(devinfo == NULL)) return; @@ -172,7 +197,6 @@ brcmf_usb_ctlread_complete(struct urb *urb) struct brcmf_usbdev_info *devinfo = (struct brcmf_usbdev_info *)urb->context; - brcmf_dbg(USB, "Enter\n"); devinfo->ctl_urb_actual_length = urb->actual_length; brcmf_usb_ctl_complete(devinfo, BRCMF_USB_CBCTL_READ, urb->status); @@ -184,22 +208,33 @@ brcmf_usb_ctlwrite_complete(struct urb *urb) struct brcmf_usbdev_info *devinfo = (struct brcmf_usbdev_info *)urb->context; - brcmf_dbg(USB, "Enter\n"); brcmf_usb_ctl_complete(devinfo, BRCMF_USB_CBCTL_WRITE, urb->status); } +static int brcmf_usb_pnp(struct brcmf_usbdev_info *devinfo, uint state) +{ + return 0; +} + static int brcmf_usb_send_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len) { int ret; u16 size; - brcmf_dbg(USB, "Enter\n"); if (devinfo == NULL || buf == NULL || len == 0 || devinfo->ctl_urb == NULL) return -EINVAL; + /* If the USB/HSIC bus in sleep state, wake it up */ + if (devinfo->suspend_state == USBOS_SUSPEND_STATE_SUSPENDED) + if (brcmf_usb_pnp(devinfo, BCMFMAC_USB_PNP_RESUME) != 0) { + brcmf_dbg(ERROR, "Could not Resume the bus!\n"); + return -EIO; + } + + devinfo->activity = true; size = len; devinfo->ctl_write.wLength = cpu_to_le16p(&size); devinfo->ctl_urb->transfer_buffer_length = size; @@ -227,7 +262,6 @@ brcmf_usb_recv_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len) int ret; u16 size; - brcmf_dbg(USB, "Enter\n"); if ((devinfo == NULL) || (buf == NULL) || (len == 0) || (devinfo->ctl_urb == NULL)) return -EINVAL; @@ -261,9 +295,10 @@ static int brcmf_usb_tx_ctlpkt(struct device *dev, u8 *buf, u32 len) int timeout = 0; struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); - brcmf_dbg(USB, "Enter\n"); - if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) + if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { + /* TODO: handle suspend/resume */ return -EIO; + } if (test_and_set_bit(0, &devinfo->ctl_op)) return -EIO; @@ -290,10 +325,10 @@ static int brcmf_usb_rx_ctlpkt(struct device *dev, u8 *buf, u32 len) int timeout = 0; struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); - brcmf_dbg(USB, "Enter\n"); - if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) + if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { + /* TODO: handle suspend/resume */ return -EIO; - + } if (test_and_set_bit(0, &devinfo->ctl_op)) return -EIO; @@ -418,8 +453,6 @@ static void brcmf_usb_tx_complete(struct urb *urb) struct brcmf_usbreq *req = (struct brcmf_usbreq *)urb->context; struct brcmf_usbdev_info *devinfo = req->devinfo; - brcmf_dbg(USB, "Enter, urb->status=%d, skb=%p\n", urb->status, - req->skb); brcmf_usb_del_fromq(devinfo, req); if (urb->status == 0) devinfo->bus_pub.bus->dstats.tx_packets++; @@ -445,7 +478,6 @@ static void brcmf_usb_rx_complete(struct urb *urb) struct sk_buff *skb; int ifidx = 0; - brcmf_dbg(USB, "Enter, urb->status=%d\n", urb->status); brcmf_usb_del_fromq(devinfo, req); skb = req->skb; req->skb = NULL; @@ -459,7 +491,7 @@ static void brcmf_usb_rx_complete(struct urb *urb) return; } - if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) { + if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP) { skb_put(skb, urb->actual_length); if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) { brcmf_dbg(ERROR, "rx protocol error\n"); @@ -512,8 +544,8 @@ static void brcmf_usb_rx_fill_all(struct brcmf_usbdev_info *devinfo) { struct brcmf_usbreq *req; - if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) { - brcmf_dbg(ERROR, "bus is not up=%d\n", devinfo->bus_pub.state); + if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { + brcmf_dbg(ERROR, "bus is not up\n"); return; } while ((req = brcmf_usb_deq(devinfo, &devinfo->rx_freeq, NULL)) != NULL) @@ -526,24 +558,29 @@ brcmf_usb_state_change(struct brcmf_usbdev_info *devinfo, int state) struct brcmf_bus *bcmf_bus = devinfo->bus_pub.bus; int old_state; - brcmf_dbg(USB, "Enter, current state=%d, new state=%d\n", - devinfo->bus_pub.state, state); if (devinfo->bus_pub.state == state) return; old_state = devinfo->bus_pub.state; - devinfo->bus_pub.state = state; + brcmf_dbg(TRACE, "dbus state change from %d to to %d\n", + old_state, state); + + /* Don't update state if it's PnP firmware re-download */ + if (state != BCMFMAC_USB_STATE_PNP_FWDL) /* TODO */ + devinfo->bus_pub.state = state; + + if ((old_state == BCMFMAC_USB_STATE_SLEEP) + && (state == BCMFMAC_USB_STATE_UP)) { + brcmf_usb_rx_fill_all(devinfo); + } /* update state of upper layer */ - if (state == BRCMFMAC_USB_STATE_DOWN) { - brcmf_dbg(USB, "DBUS is down\n"); + if (state == BCMFMAC_USB_STATE_DOWN) { + brcmf_dbg(INFO, "DBUS is down\n"); bcmf_bus->state = BRCMF_BUS_DOWN; - } else if (state == BRCMFMAC_USB_STATE_UP) { - brcmf_dbg(USB, "DBUS is up\n"); - bcmf_bus->state = BRCMF_BUS_DATA; } else { - brcmf_dbg(USB, "DBUS current state=%d\n", state); + brcmf_dbg(INFO, "DBUS current state=%d\n", state); } } @@ -552,32 +589,30 @@ brcmf_usb_intr_complete(struct urb *urb) { struct brcmf_usbdev_info *devinfo = (struct brcmf_usbdev_info *)urb->context; - int err; - - brcmf_dbg(USB, "Enter, urb->status=%d\n", urb->status); + bool killed; if (devinfo == NULL) return; if (unlikely(urb->status)) { - if (urb->status == -ENOENT || - urb->status == -ESHUTDOWN || - urb->status == -ENODEV) { - brcmf_usb_state_change(devinfo, - BRCMFMAC_USB_STATE_DOWN); + if (devinfo->suspend_state == + USBOS_SUSPEND_STATE_SUSPEND_PENDING) + killed = true; + + if ((urb->status == -ENOENT && (!killed)) + || urb->status == -ESHUTDOWN || + urb->status == -ENODEV) { + brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_DOWN); } } - if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_DOWN) { + if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_DOWN) { brcmf_dbg(ERROR, "intr cb when DBUS down, ignoring\n"); return; } - if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) { - err = usb_submit_urb(devinfo->intr_urb, GFP_ATOMIC); - if (err) - brcmf_dbg(ERROR, "usb_submit_urb, err=%d\n", err); - } + if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP) + usb_submit_urb(devinfo->intr_urb, GFP_ATOMIC); } static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb) @@ -586,9 +621,10 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb) struct brcmf_usbreq *req; int ret; - brcmf_dbg(USB, "Enter, skb=%p\n", skb); - if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) + if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { + /* TODO: handle suspend/resume */ return -EIO; + } req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq, &devinfo->tx_freecount); @@ -628,16 +664,25 @@ static int brcmf_usb_up(struct device *dev) { struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); u16 ifnum; - int ret; - brcmf_dbg(USB, "Enter\n"); - if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) + if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP) return 0; + /* If the USB/HSIC bus in sleep state, wake it up */ + if (devinfo->suspend_state == USBOS_SUSPEND_STATE_SUSPENDED) { + if (brcmf_usb_pnp(devinfo, BCMFMAC_USB_PNP_RESUME) != 0) { + brcmf_dbg(ERROR, "Could not Resume the bus!\n"); + return -EIO; + } + } + devinfo->activity = true; + /* Success, indicate devinfo is fully up */ - brcmf_usb_state_change(devinfo, BRCMFMAC_USB_STATE_UP); + brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_UP); if (devinfo->intr_urb) { + int ret; + usb_fill_int_urb(devinfo->intr_urb, devinfo->usbdev, devinfo->intr_pipe, &devinfo->intr, @@ -682,14 +727,14 @@ static void brcmf_usb_down(struct device *dev) { struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); - brcmf_dbg(USB, "Enter\n"); if (devinfo == NULL) return; - if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_DOWN) + brcmf_dbg(TRACE, "enter\n"); + if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_DOWN) return; - brcmf_usb_state_change(devinfo, BRCMFMAC_USB_STATE_DOWN); + brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_DOWN); if (devinfo->intr_urb) usb_kill_urb(devinfo->intr_urb); @@ -763,25 +808,27 @@ brcmf_usb_dlneeded(struct brcmf_usbdev_info *devinfo) struct bootrom_id_le id; u32 chipid, chiprev; - brcmf_dbg(USB, "Enter\n"); + brcmf_dbg(TRACE, "enter\n"); if (devinfo == NULL) return false; /* Check if firmware downloaded already by querying runtime ID */ id.chip = cpu_to_le32(0xDEAD); - brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id, sizeof(id)); + brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id, + sizeof(struct bootrom_id_le)); chipid = le32_to_cpu(id.chip); chiprev = le32_to_cpu(id.chiprev); if ((chipid & 0x4300) == 0x4300) - brcmf_dbg(USB, "chip %x rev 0x%x\n", chipid, chiprev); + brcmf_dbg(INFO, "chip %x rev 0x%x\n", chipid, chiprev); else - brcmf_dbg(USB, "chip %d rev 0x%x\n", chipid, chiprev); + brcmf_dbg(INFO, "chip %d rev 0x%x\n", chipid, chiprev); if (chipid == BRCMF_POSTBOOT_ID) { - brcmf_dbg(USB, "firmware already downloaded\n"); - brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id, sizeof(id)); + brcmf_dbg(INFO, "firmware already downloaded\n"); + brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id, + sizeof(struct bootrom_id_le)); return false; } else { devinfo->bus_pub.devid = chipid; @@ -794,29 +841,38 @@ static int brcmf_usb_resetcfg(struct brcmf_usbdev_info *devinfo) { struct bootrom_id_le id; - u32 loop_cnt; + u16 wait = 0, wait_time; - brcmf_dbg(USB, "Enter\n"); + brcmf_dbg(TRACE, "enter\n"); + + if (devinfo == NULL) + return -EINVAL; - loop_cnt = 0; - do { - mdelay(BRCMF_USB_RESET_GETVER_SPINWAIT); - loop_cnt++; + /* Give dongle chance to boot */ + wait_time = BRCMF_USB_DLIMAGE_SPINWAIT; + while (wait < BRCMF_USB_DLIMAGE_LIMIT) { + mdelay(wait_time); + wait += wait_time; id.chip = cpu_to_le32(0xDEAD); /* Get the ID */ - brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id, sizeof(id)); + brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id, + sizeof(struct bootrom_id_le)); if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID)) break; - } while (loop_cnt < BRCMF_USB_RESET_GETVER_LOOP_CNT); + } if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID)) { - brcmf_dbg(USB, "postboot chip 0x%x/rev 0x%x\n", - le32_to_cpu(id.chip), le32_to_cpu(id.chiprev)); + brcmf_dbg(INFO, "download done %d ms postboot chip 0x%x/rev 0x%x\n", + wait, le32_to_cpu(id.chip), le32_to_cpu(id.chiprev)); + + brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id, + sizeof(struct bootrom_id_le)); - brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id, sizeof(id)); + /* XXX this wait may not be necessary */ + mdelay(BRCMF_USB_RESETCFG_SPINWAIT); return 0; } else { brcmf_dbg(ERROR, "Cannot talk to Dongle. Firmware is not UP, %d ms\n", - BRCMF_USB_RESET_GETVER_SPINWAIT * loop_cnt); + wait); return -EINVAL; } } @@ -855,8 +911,7 @@ brcmf_usb_dl_writeimage(struct brcmf_usbdev_info *devinfo, u8 *fw, int fwlen) struct rdl_state_le state; u32 rdlstate, rdlbytes; int err = 0; - - brcmf_dbg(USB, "Enter, fw %p, len %d\n", fw, fwlen); + brcmf_dbg(TRACE, "fw %p, len %d\n", fw, fwlen); bulkchunk = kmalloc(RDL_CHUNK, GFP_ATOMIC); if (bulkchunk == NULL) { @@ -931,7 +986,7 @@ brcmf_usb_dl_writeimage(struct brcmf_usbdev_info *devinfo, u8 *fw, int fwlen) fail: kfree(bulkchunk); - brcmf_dbg(USB, "Exit, err=%d\n", err); + brcmf_dbg(TRACE, "err=%d\n", err); return err; } @@ -939,7 +994,7 @@ static int brcmf_usb_dlstart(struct brcmf_usbdev_info *devinfo, u8 *fw, int len) { int err; - brcmf_dbg(USB, "Enter\n"); + brcmf_dbg(TRACE, "enter\n"); if (devinfo == NULL) return -EINVAL; @@ -949,10 +1004,10 @@ static int brcmf_usb_dlstart(struct brcmf_usbdev_info *devinfo, u8 *fw, int len) err = brcmf_usb_dl_writeimage(devinfo, fw, len); if (err == 0) - devinfo->bus_pub.state = BRCMFMAC_USB_STATE_DL_DONE; + devinfo->bus_pub.state = BCMFMAC_USB_STATE_DL_DONE; else - devinfo->bus_pub.state = BRCMFMAC_USB_STATE_DL_FAIL; - brcmf_dbg(USB, "Exit, err=%d\n", err); + devinfo->bus_pub.state = BCMFMAC_USB_STATE_DL_PENDING; + brcmf_dbg(TRACE, "exit: err=%d\n", err); return err; } @@ -961,7 +1016,7 @@ static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo) { struct rdl_state_le state; - brcmf_dbg(USB, "Enter\n"); + brcmf_dbg(TRACE, "enter\n"); if (!devinfo) return -EINVAL; @@ -984,7 +1039,7 @@ static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo) brcmf_dbg(ERROR, "Dongle not runnable\n"); return -EINVAL; } - brcmf_dbg(USB, "Exit\n"); + brcmf_dbg(TRACE, "exit\n"); return 0; } @@ -1011,7 +1066,7 @@ brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo) int devid, chiprev; int err; - brcmf_dbg(USB, "Enter\n"); + brcmf_dbg(TRACE, "enter\n"); if (devinfo == NULL) return -ENODEV; @@ -1039,7 +1094,7 @@ brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo) static void brcmf_usb_detach(struct brcmf_usbdev_info *devinfo) { - brcmf_dbg(USB, "Enter, devinfo %p\n", devinfo); + brcmf_dbg(TRACE, "devinfo %p\n", devinfo); /* free the URBS */ brcmf_usb_free_q(&devinfo->rx_freeq, false); @@ -1074,7 +1129,6 @@ static int check_file(const u8 *headers) struct trx_header_le *trx; int actual_len = -1; - brcmf_dbg(USB, "Enter\n"); /* Extract trx header */ trx = (struct trx_header_le *) headers; if (trx->magic != cpu_to_le32(TRX_MAGIC)) @@ -1096,7 +1150,6 @@ static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo) struct brcmf_usb_image *fw_image; int err; - brcmf_dbg(USB, "Enter\n"); switch (devinfo->bus_pub.devid) { case 43143: fwname = BRCMF_USB_43143_FW_NAME; @@ -1113,7 +1166,7 @@ static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo) return -EINVAL; break; } - brcmf_dbg(USB, "Loading FW %s\n", fwname); + list_for_each_entry(fw_image, &fw_image_list, list) { if (fw_image->fwname == fwname) { devinfo->image = fw_image->image; @@ -1158,13 +1211,10 @@ static struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo, int nrxq, int ntxq) { - brcmf_dbg(USB, "Enter\n"); - devinfo->bus_pub.nrxq = nrxq; devinfo->rx_low_watermark = nrxq / 2; devinfo->bus_pub.devinfo = devinfo; devinfo->bus_pub.ntxq = ntxq; - devinfo->bus_pub.state = BRCMFMAC_USB_STATE_DOWN; /* flow control when too many tx urbs posted */ devinfo->tx_low_watermark = ntxq / 4; @@ -1213,7 +1263,7 @@ struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo, if (!brcmf_usb_dlneeded(devinfo)) return &devinfo->bus_pub; - brcmf_dbg(USB, "Start fw downloading\n"); + brcmf_dbg(TRACE, "start fw downloading\n"); if (brcmf_usb_get_fw(devinfo)) goto error; @@ -1228,14 +1278,14 @@ struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo, return NULL; } -static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo) +static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo, + const char *desc, u32 bustype, u32 hdrlen) { struct brcmf_bus *bus = NULL; struct brcmf_usbdev *bus_pub = NULL; int ret; struct device *dev = devinfo->dev; - brcmf_dbg(USB, "Enter\n"); bus_pub = brcmf_usb_attach(devinfo, BRCMF_USB_NRXQ, BRCMF_USB_NTXQ); if (!bus_pub) return -ENODEV; @@ -1252,13 +1302,14 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo) bus->brcmf_bus_stop = brcmf_usb_down; bus->brcmf_bus_txctl = brcmf_usb_tx_ctlpkt; bus->brcmf_bus_rxctl = brcmf_usb_rx_ctlpkt; + bus->type = bustype; bus->bus_priv.usb = bus_pub; dev_set_drvdata(dev, bus); /* Attach to the common driver interface */ - ret = brcmf_attach(0, dev); + ret = brcmf_attach(hdrlen, dev); if (ret) { - brcmf_dbg(ERROR, "brcmf_attach failed\n"); + brcmf_dbg(ERROR, "dhd_attach failed\n"); goto fail; } @@ -1282,7 +1333,7 @@ brcmf_usb_disconnect_cb(struct brcmf_usbdev_info *devinfo) { if (!devinfo) return; - brcmf_dbg(USB, "Enter, bus_pub %p\n", devinfo); + brcmf_dbg(TRACE, "enter: bus_pub %p\n", devinfo); brcmf_detach(devinfo->dev); kfree(devinfo->bus_pub.bus); @@ -1300,7 +1351,7 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) u8 endpoint_num; struct brcmf_usbdev_info *devinfo; - brcmf_dbg(USB, "Enter\n"); + brcmf_dbg(TRACE, "enter\n"); devinfo = kzalloc(sizeof(*devinfo), GFP_ATOMIC); if (devinfo == NULL) @@ -1401,11 +1452,11 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) devinfo->interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval; if (usb->speed == USB_SPEED_HIGH) - brcmf_dbg(USB, "Broadcom high speed USB wireless device detected\n"); + brcmf_dbg(INFO, "Broadcom high speed USB wireless device detected\n"); else - brcmf_dbg(USB, "Broadcom full speed USB wireless device detected\n"); + brcmf_dbg(INFO, "Broadcom full speed USB wireless device detected\n"); - ret = brcmf_usb_probe_cb(devinfo); + ret = brcmf_usb_probe_cb(devinfo, "", USB_BUS, 0); if (ret) goto fail; @@ -1425,55 +1476,40 @@ brcmf_usb_disconnect(struct usb_interface *intf) { struct brcmf_usbdev_info *devinfo; - brcmf_dbg(USB, "Enter\n"); + brcmf_dbg(TRACE, "enter\n"); devinfo = (struct brcmf_usbdev_info *)usb_get_intfdata(intf); brcmf_usb_disconnect_cb(devinfo); kfree(devinfo); - brcmf_dbg(USB, "Exit\n"); } /* - * only need to signal the bus being down and update the state. + * only need to signal the bus being down and update the suspend state. */ static int brcmf_usb_suspend(struct usb_interface *intf, pm_message_t state) { struct usb_device *usb = interface_to_usbdev(intf); struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); - brcmf_dbg(USB, "Enter\n"); - devinfo->bus_pub.state = BRCMFMAC_USB_STATE_SLEEP; - brcmf_detach(&usb->dev); + brcmf_dbg(TRACE, "enter\n"); + devinfo->bus_pub.state = BCMFMAC_USB_STATE_DOWN; + devinfo->suspend_state = USBOS_SUSPEND_STATE_SUSPENDED; return 0; } /* - * (re-) start the bus. + * mark suspend state active and crank up the bus. */ static int brcmf_usb_resume(struct usb_interface *intf) { struct usb_device *usb = interface_to_usbdev(intf); struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); - brcmf_dbg(USB, "Enter\n"); - if (!brcmf_attach(0, devinfo->dev)) - return brcmf_bus_start(&usb->dev); - + brcmf_dbg(TRACE, "enter\n"); + devinfo->suspend_state = USBOS_SUSPEND_STATE_DEVICE_ACTIVE; + brcmf_bus_start(&usb->dev); return 0; } -static int brcmf_usb_reset_resume(struct usb_interface *intf) -{ - struct usb_device *usb = interface_to_usbdev(intf); - struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); - - brcmf_dbg(USB, "Enter\n"); - - if (!brcmf_usb_fw_download(devinfo)) - return brcmf_usb_resume(intf); - - return -EIO; -} - #define BRCMF_USB_VENDOR_ID_BROADCOM 0x0a5c #define BRCMF_USB_DEVICE_ID_43143 0xbd1e #define BRCMF_USB_DEVICE_ID_43236 0xbd17 @@ -1493,6 +1529,7 @@ MODULE_FIRMWARE(BRCMF_USB_43143_FW_NAME); MODULE_FIRMWARE(BRCMF_USB_43236_FW_NAME); MODULE_FIRMWARE(BRCMF_USB_43242_FW_NAME); +/* TODO: suspend and resume entries */ static struct usb_driver brcmf_usbdrvr = { .name = KBUILD_MODNAME, .probe = brcmf_usb_probe, @@ -1500,7 +1537,6 @@ static struct usb_driver brcmf_usbdrvr = { .id_table = brcmf_usb_devid_table, .suspend = brcmf_usb_suspend, .resume = brcmf_usb_resume, - .reset_resume = brcmf_usb_reset_resume, .supports_autosuspend = 1, .disable_hub_initiated_lpm = 1, }; @@ -1518,14 +1554,12 @@ static void brcmf_release_fw(struct list_head *q) void brcmf_usb_exit(void) { - brcmf_dbg(USB, "Enter\n"); usb_deregister(&brcmf_usbdrvr); brcmf_release_fw(&fw_image_list); } void brcmf_usb_init(void) { - brcmf_dbg(USB, "Enter\n"); INIT_LIST_HEAD(&fw_image_list); usb_register(&brcmf_usbdrvr); } diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/usb.h b/trunk/drivers/net/wireless/brcm80211/brcmfmac/usb.h index f483a8c9945b..acfa5e89872f 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/usb.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/usb.h @@ -17,11 +17,19 @@ #define BRCMFMAC_USB_H enum brcmf_usb_state { - BRCMFMAC_USB_STATE_DOWN, - BRCMFMAC_USB_STATE_DL_FAIL, - BRCMFMAC_USB_STATE_DL_DONE, - BRCMFMAC_USB_STATE_UP, - BRCMFMAC_USB_STATE_SLEEP + BCMFMAC_USB_STATE_DL_PENDING, + BCMFMAC_USB_STATE_DL_DONE, + BCMFMAC_USB_STATE_UP, + BCMFMAC_USB_STATE_DOWN, + BCMFMAC_USB_STATE_PNP_FWDL, + BCMFMAC_USB_STATE_DISCONNECT, + BCMFMAC_USB_STATE_SLEEP +}; + +enum brcmf_usb_pnp_state { + BCMFMAC_USB_PNP_DISCONNECT, + BCMFMAC_USB_PNP_SLEEP, + BCMFMAC_USB_PNP_RESUME, }; struct brcmf_stats { diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 96bc349d7f6c..b596ca4f22bd 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -19,7 +19,14 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include +#include +#include +#include +#include +#include #include +#include +#include #include #include @@ -447,7 +454,7 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, struct vif_params *params) { struct brcmf_if *ifp = netdev_priv(ndev); - struct brcmf_cfg80211_vif *vif = ifp->vif; + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); s32 infra = 0; s32 ap = 0; s32 err = 0; @@ -461,15 +468,15 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, type); return -EOPNOTSUPP; case NL80211_IFTYPE_ADHOC: - vif->mode = WL_MODE_IBSS; + cfg->conf->mode = WL_MODE_IBSS; infra = 0; break; case NL80211_IFTYPE_STATION: - vif->mode = WL_MODE_BSS; + cfg->conf->mode = WL_MODE_BSS; infra = 1; break; case NL80211_IFTYPE_AP: - vif->mode = WL_MODE_AP; + cfg->conf->mode = WL_MODE_AP; ap = 1; break; default: @@ -478,16 +485,25 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, } if (ap) { - set_bit(BRCMF_VIF_STATUS_AP_CREATING, &vif->sme_state); + set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state); + if (!cfg->ap_info) + cfg->ap_info = kzalloc(sizeof(*cfg->ap_info), + GFP_KERNEL); + if (!cfg->ap_info) { + err = -ENOMEM; + goto done; + } WL_INFO("IF Type = AP\n"); } else { - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra); + err = brcmf_fil_cmd_int_set(netdev_priv(ndev), + BRCMF_C_SET_INFRA, infra); if (err) { WL_ERR("WLC_SET_INFRA error (%d)\n", err); err = -EAGAIN; goto done; } - WL_INFO("IF Type = %s\n", (vif->mode == WL_MODE_IBSS) ? + WL_INFO("IF Type = %s\n", + (cfg->conf->mode == WL_MODE_IBSS) ? "Adhoc" : "Infra"); } ndev->ieee80211_ptr->iftype = type; @@ -513,6 +529,185 @@ static void brcmf_set_mpc(struct net_device *ndev, int mpc) } } +static void brcmf_iscan_prep(struct brcmf_scan_params_le *params_le, + struct brcmf_ssid *ssid) +{ + memset(params_le->bssid, 0xFF, ETH_ALEN); + params_le->bss_type = DOT11_BSSTYPE_ANY; + params_le->scan_type = 0; + params_le->channel_num = 0; + params_le->nprobes = cpu_to_le32(-1); + params_le->active_time = cpu_to_le32(-1); + params_le->passive_time = cpu_to_le32(-1); + params_le->home_time = cpu_to_le32(-1); + if (ssid && ssid->SSID_len) { + params_le->ssid_le.SSID_len = cpu_to_le32(ssid->SSID_len); + memcpy(¶ms_le->ssid_le.SSID, ssid->SSID, ssid->SSID_len); + } +} + +static s32 +brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan, + struct brcmf_ssid *ssid, u16 action) +{ + s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE + + offsetof(struct brcmf_iscan_params_le, params_le); + struct brcmf_iscan_params_le *params; + s32 err = 0; + + if (ssid && ssid->SSID_len) + params_size += sizeof(struct brcmf_ssid); + params = kzalloc(params_size, GFP_KERNEL); + if (!params) + return -ENOMEM; + BUG_ON(params_size >= BRCMF_DCMD_SMLEN); + + brcmf_iscan_prep(¶ms->params_le, ssid); + + params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION); + params->action = cpu_to_le16(action); + params->scan_duration = cpu_to_le16(0); + + err = brcmf_fil_iovar_data_set(netdev_priv(iscan->ndev), "iscan", + params, params_size); + if (err) { + if (err == -EBUSY) + WL_INFO("system busy : iscan canceled\n"); + else + WL_ERR("error (%d)\n", err); + } + + kfree(params); + return err; +} + +static s32 brcmf_do_iscan(struct brcmf_cfg80211_info *cfg) +{ + struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg); + struct net_device *ndev = cfg_to_ndev(cfg); + struct brcmf_ssid ssid; + u32 passive_scan; + s32 err = 0; + + /* Broadcast scan by default */ + memset(&ssid, 0, sizeof(ssid)); + + iscan->state = WL_ISCAN_STATE_SCANING; + + passive_scan = cfg->active_scan ? 0 : 1; + err = brcmf_fil_cmd_int_set(netdev_priv(ndev), + BRCMF_C_SET_PASSIVE_SCAN, passive_scan); + if (err) { + WL_ERR("error (%d)\n", err); + return err; + } + brcmf_set_mpc(ndev, 0); + cfg->iscan_kickstart = true; + err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START); + if (err) { + brcmf_set_mpc(ndev, 1); + cfg->iscan_kickstart = false; + return err; + } + mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000); + iscan->timer_on = 1; + return err; +} + +static s32 +brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev, + struct cfg80211_scan_request *request, + struct cfg80211_ssid *this_ssid) +{ + struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); + struct cfg80211_ssid *ssids; + struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int; + u32 passive_scan; + bool iscan_req; + bool spec_scan; + s32 err = 0; + u32 SSID_len; + + if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { + WL_ERR("Scanning already: status (%lu)\n", cfg->scan_status); + return -EAGAIN; + } + if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) { + WL_ERR("Scanning being aborted: status (%lu)\n", + cfg->scan_status); + return -EAGAIN; + } + if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) { + WL_ERR("Connecting: status (%lu)\n", ifp->vif->sme_state); + return -EAGAIN; + } + + iscan_req = false; + spec_scan = false; + if (request) { + /* scan bss */ + ssids = request->ssids; + if (cfg->iscan_on && (!ssids || !ssids->ssid_len)) + iscan_req = true; + } else { + /* scan in ibss */ + /* we don't do iscan in ibss */ + ssids = this_ssid; + } + + cfg->scan_request = request; + set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); + if (iscan_req) { + err = brcmf_do_iscan(cfg); + if (!err) + return err; + else + goto scan_out; + } else { + WL_SCAN("ssid \"%s\", ssid_len (%d)\n", + ssids->ssid, ssids->ssid_len); + memset(&sr->ssid_le, 0, sizeof(sr->ssid_le)); + SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len); + sr->ssid_le.SSID_len = cpu_to_le32(0); + if (SSID_len) { + memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len); + sr->ssid_le.SSID_len = cpu_to_le32(SSID_len); + spec_scan = true; + } else { + WL_SCAN("Broadcast scan\n"); + } + + passive_scan = cfg->active_scan ? 0 : 1; + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN, + passive_scan); + if (err) { + WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err); + goto scan_out; + } + brcmf_set_mpc(ndev, 0); + err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN, + &sr->ssid_le, sizeof(sr->ssid_le)); + if (err) { + if (err == -EBUSY) + WL_INFO("system busy : scan for \"%s\" " + "canceled\n", sr->ssid_le.SSID); + else + WL_ERR("WLC_SCAN error (%d)\n", err); + + brcmf_set_mpc(ndev, 1); + goto scan_out; + } + } + + return 0; + +scan_out: + clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); + cfg->scan_request = NULL; + return err; +} + static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le, struct cfg80211_scan_request *request) { @@ -736,7 +931,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev, struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); struct cfg80211_ssid *ssids; - struct brcmf_cfg80211_scan_req *sr = &cfg->scan_req_int; + struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int; u32 passive_scan; bool escan_req; bool spec_scan; @@ -778,7 +973,9 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev, set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); if (escan_req) { err = brcmf_do_escan(cfg, wiphy, ndev, request); - if (err) + if (!err) + return err; + else goto scan_out; } else { WL_SCAN("ssid \"%s\", ssid_len (%d)\n", @@ -830,6 +1027,7 @@ static s32 brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) { struct net_device *ndev = request->wdev->netdev; + struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); s32 err = 0; WL_TRACE("Enter\n"); @@ -838,7 +1036,10 @@ brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) struct brcmf_cfg80211_vif, wdev))) return -EIO; - err = brcmf_cfg80211_escan(wiphy, ndev, request, NULL); + if (cfg->iscan_on) + err = brcmf_cfg80211_iscan(wiphy, ndev, request, NULL); + else if (cfg->escan_on) + err = brcmf_cfg80211_escan(wiphy, ndev, request, NULL); if (err) WL_ERR("scan error (%d)\n", err); @@ -874,7 +1075,7 @@ static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold) static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l) { s32 err = 0; - u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL); + u32 cmd = (l ? BRCM_SET_LRL : BRCM_SET_SRL); err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry); if (err) { @@ -961,21 +1162,22 @@ static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params, } } -static void brcmf_link_down(struct brcmf_cfg80211_vif *vif) +static void brcmf_link_down(struct brcmf_cfg80211_info *cfg) { + struct net_device *ndev = NULL; s32 err = 0; WL_TRACE("Enter\n"); - if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) { + if (cfg->link_up) { + ndev = cfg_to_ndev(cfg); WL_INFO("Call WLC_DISASSOC to stop excess roaming\n "); - err = brcmf_fil_cmd_data_set(vif->ifp, + err = brcmf_fil_cmd_data_set(netdev_priv(ndev), BRCMF_C_DISASSOC, NULL, 0); if (err) WL_ERR("WLC_DISASSOC failed (%d)\n", err); - clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state); + cfg->link_up = false; } - clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state); WL_TRACE("Exit\n"); } @@ -1056,7 +1258,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, else bcnprd = 100; - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd); + err = brcmf_fil_cmd_int_set(ifp, BRCM_SET_BCNPRD, bcnprd); if (err) { WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err); goto done; @@ -1098,7 +1300,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, /* set channel for starter */ target_channel = cfg->channel; - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL, + err = brcmf_fil_cmd_int_set(ifp, BRCM_SET_CHANNEL, target_channel); if (err) { WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err); @@ -1127,6 +1329,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, static s32 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev) { + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); struct brcmf_if *ifp = netdev_priv(ndev); s32 err = 0; @@ -1134,7 +1337,7 @@ brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev) if (!check_vif_up(ifp->vif)) return -EIO; - brcmf_link_down(ifp->vif); + brcmf_link_down(cfg); WL_TRACE("Exit\n"); @@ -1492,6 +1695,7 @@ static s32 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, u16 reason_code) { + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; struct brcmf_scb_val_le scbval; @@ -1510,6 +1714,8 @@ brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, if (err) WL_ERR("error (%d)\n", err); + cfg->link_up = false; + WL_TRACE("Exit\n"); return err; } @@ -1709,6 +1915,7 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_idx, bool pairwise, const u8 *mac_addr, struct key_params *params) { + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_wsec_key key; s32 val; @@ -1750,7 +1957,7 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, WL_CONN("WLAN_CIPHER_SUITE_WEP104\n"); break; case WLAN_CIPHER_SUITE_TKIP: - if (ifp->vif->mode != WL_MODE_AP) { + if (cfg->conf->mode != WL_MODE_AP) { WL_CONN("Swapping key\n"); memcpy(keybuf, &key.data[24], sizeof(keybuf)); memcpy(&key.data[24], &key.data[16], sizeof(keybuf)); @@ -1809,12 +2016,6 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, if (!check_vif_up(ifp->vif)) return -EIO; - if (key_idx >= DOT11_MAX_DEFAULT_KEYS) { - /* we ignore this key index in this case */ - WL_ERR("invalid key index (%d)\n", key_idx); - return -EINVAL; - } - memset(&key, 0, sizeof(key)); key.index = (u32) key_idx; @@ -1825,6 +2026,15 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, /* Set the new key/index */ err = send_key_to_dongle(ndev, &key); + if (err) { + if (err == -EINVAL) { + if (key.index >= DOT11_MAX_DEFAULT_KEYS) + /* we ignore this key index in this case */ + WL_ERR("invalid key index (%d)\n", key_idx); + } + /* Ignore this error, may happen during DISASSOC */ + err = -EAGAIN; + } WL_TRACE("Exit\n"); return err; @@ -1900,6 +2110,7 @@ static s32 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, u8 *mac, struct station_info *sinfo) { + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; struct brcmf_scb_val_le scb_val; @@ -1913,7 +2124,7 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, if (!check_vif_up(ifp->vif)) return -EIO; - if (ifp->vif->mode == WL_MODE_AP) { + if (cfg->conf->mode == WL_MODE_AP) { memcpy(&sta_info_le, mac, ETH_ALEN); err = brcmf_fil_iovar_data_get(ifp, "sta_info", &sta_info_le, @@ -1930,7 +2141,7 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, } WL_TRACE("STA idle time : %d ms, connected time :%d sec\n", sinfo->inactive_time, sinfo->connected_time); - } else if (ifp->vif->mode == WL_MODE_BSS) { + } else if (cfg->conf->mode == WL_MODE_BSS) { if (memcmp(mac, bssid, ETH_ALEN)) { WL_ERR("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n", mac, bssid); @@ -2030,7 +2241,7 @@ brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev, /* addr param is always NULL. ignore it */ /* Get current rateset */ - err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_CURR_RATESET, + err = brcmf_fil_cmd_data_get(ifp, BRCM_GET_CURR_RATESET, &rateset_le, sizeof(rateset_le)); if (err) { WL_ERR("could not get current rateset (%d)\n", err); @@ -2145,14 +2356,13 @@ static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg) int i; bss_list = cfg->bss_list; - if (bss_list->count != 0 && - bss_list->version != BRCMF_BSS_INFO_VERSION) { + if (bss_list->version != BRCMF_BSS_INFO_VERSION) { WL_ERR("Version %d != WL_BSS_INFO_VERSION\n", bss_list->version); return -EOPNOTSUPP; } WL_SCAN("scanned AP count (%d)\n", bss_list->count); - for (i = 0; i < bss_list->count; i++) { + for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) { bi = next_bss_le(bss_list, bi); err = brcmf_inform_single_bss(cfg, bi); if (err) @@ -2240,9 +2450,9 @@ static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg, return err; } -static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif) +static bool brcmf_is_ibssmode(struct brcmf_cfg80211_info *cfg) { - return vif->mode == WL_MODE_IBSS; + return cfg->conf->mode == WL_MODE_IBSS; } /* @@ -2327,7 +2537,7 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg) s32 err = 0; WL_TRACE("Enter\n"); - if (brcmf_is_ibssmode(ifp->vif)) + if (brcmf_is_ibssmode(cfg)) return err; ssid = &profile->ssid; @@ -2374,10 +2584,33 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg) static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg) { + struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg); struct escan_info *escan = &cfg->escan_info; + struct brcmf_ssid ssid; set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status); - if (cfg->scan_request) { + if (cfg->iscan_on) { + iscan->state = WL_ISCAN_STATE_IDLE; + + if (iscan->timer_on) { + del_timer_sync(&iscan->timer); + iscan->timer_on = 0; + } + + cancel_work_sync(&iscan->work); + + /* Abort iscan running in FW */ + memset(&ssid, 0, sizeof(ssid)); + brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT); + + if (cfg->scan_request) { + /* Indidate scan abort to cfg80211 layer */ + WL_INFO("Terminating scan in progress\n"); + cfg80211_scan_done(cfg->scan_request, true); + cfg->scan_request = NULL; + } + } + if (cfg->escan_on && cfg->scan_request) { escan->escan_state = WL_ESCAN_STATE_IDLE; brcmf_notify_escan_complete(cfg, escan->ndev, true, true); } @@ -2385,6 +2618,198 @@ static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg) clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status); } +static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan, + bool aborted) +{ + struct brcmf_cfg80211_info *cfg = iscan_to_cfg(iscan); + struct net_device *ndev = cfg_to_ndev(cfg); + + if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { + WL_ERR("Scan complete while device not scanning\n"); + return; + } + if (cfg->scan_request) { + WL_SCAN("ISCAN Completed scan: %s\n", + aborted ? "Aborted" : "Done"); + cfg80211_scan_done(cfg->scan_request, aborted); + brcmf_set_mpc(ndev, 1); + cfg->scan_request = NULL; + } + cfg->iscan_kickstart = false; +} + +static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan) +{ + if (iscan->state != WL_ISCAN_STATE_IDLE) { + WL_SCAN("wake up iscan\n"); + schedule_work(&iscan->work); + return 0; + } + + return -EIO; +} + +static s32 +brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status, + struct brcmf_scan_results **bss_list) +{ + struct brcmf_scan_results *results; + struct brcmf_scan_results_le *results_le; + struct brcmf_iscan_results *list_buf; + s32 err = 0; + + memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX); + list_buf = (struct brcmf_iscan_results *)iscan->scan_buf; + results = &list_buf->results; + results_le = &list_buf->results_le; + results_le->buflen = cpu_to_le32(sizeof(iscan->scan_buf)); + results_le->version = 0; + results_le->count = 0; + + err = brcmf_fil_iovar_data_get(netdev_priv(iscan->ndev), "iscanresults", + iscan->scan_buf, + sizeof(iscan->scan_buf)); + if (err) { + WL_ERR("error (%d)\n", err); + return err; + } + results->buflen = le32_to_cpu(results_le->buflen); + results->version = le32_to_cpu(results_le->version); + results->count = le32_to_cpu(results_le->count); + WL_SCAN("results->count = %d\n", results_le->count); + WL_SCAN("results->buflen = %d\n", results_le->buflen); + *status = le32_to_cpu(list_buf->status_le); + WL_SCAN("status = %d\n", *status); + *bss_list = results; + + return err; +} + +static s32 brcmf_iscan_done(struct brcmf_cfg80211_info *cfg) +{ + struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan; + s32 err = 0; + + iscan->state = WL_ISCAN_STATE_IDLE; + brcmf_inform_bss(cfg); + brcmf_notify_iscan_complete(iscan, false); + + return err; +} + +static s32 brcmf_iscan_pending(struct brcmf_cfg80211_info *cfg) +{ + struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan; + s32 err = 0; + + /* Reschedule the timer */ + mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000); + iscan->timer_on = 1; + + return err; +} + +static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_info *cfg) +{ + struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan; + s32 err = 0; + + brcmf_inform_bss(cfg); + brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE); + /* Reschedule the timer */ + mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000); + iscan->timer_on = 1; + + return err; +} + +static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_info *cfg) +{ + struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan; + s32 err = 0; + + iscan->state = WL_ISCAN_STATE_IDLE; + brcmf_notify_iscan_complete(iscan, true); + + return err; +} + +static void brcmf_cfg80211_iscan_handler(struct work_struct *work) +{ + struct brcmf_cfg80211_iscan_ctrl *iscan = + container_of(work, struct brcmf_cfg80211_iscan_ctrl, + work); + struct brcmf_cfg80211_info *cfg = iscan_to_cfg(iscan); + struct brcmf_cfg80211_iscan_eloop *el = &iscan->el; + u32 status = BRCMF_SCAN_RESULTS_PARTIAL; + + if (iscan->timer_on) { + del_timer_sync(&iscan->timer); + iscan->timer_on = 0; + } + + if (brcmf_get_iscan_results(iscan, &status, &cfg->bss_list)) { + status = BRCMF_SCAN_RESULTS_ABORTED; + WL_ERR("Abort iscan\n"); + } + + el->handler[status](cfg); +} + +static void brcmf_iscan_timer(unsigned long data) +{ + struct brcmf_cfg80211_iscan_ctrl *iscan = + (struct brcmf_cfg80211_iscan_ctrl *)data; + + if (iscan) { + iscan->timer_on = 0; + WL_SCAN("timer expired\n"); + brcmf_wakeup_iscan(iscan); + } +} + +static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_info *cfg) +{ + struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg); + + if (cfg->iscan_on) { + iscan->state = WL_ISCAN_STATE_IDLE; + INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler); + } + + return 0; +} + +static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el) +{ + memset(el, 0, sizeof(*el)); + el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done; + el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress; + el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending; + el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted; + el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted; +} + +static s32 brcmf_init_iscan(struct brcmf_cfg80211_info *cfg) +{ + struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg); + int err = 0; + + if (cfg->iscan_on) { + iscan->ndev = cfg_to_ndev(cfg); + brcmf_init_iscan_eloop(&iscan->el); + iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS; + init_timer(&iscan->timer); + iscan->timer.data = (unsigned long) iscan; + iscan->timer.function = brcmf_iscan_timer; + err = brcmf_invoke_iscan(cfg); + if (!err) + iscan->data = cfg; + } + + return err; +} + static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work) { struct brcmf_cfg80211_info *cfg = @@ -2402,7 +2827,8 @@ static void brcmf_escan_timeout(unsigned long data) if (cfg->scan_request) { WL_ERR("timer expired\n"); - schedule_work(&cfg->escan_timeout_work); + if (cfg->escan_on) + schedule_work(&cfg->escan_timeout_work); } } @@ -2439,11 +2865,10 @@ brcmf_compare_update_same_bss(struct brcmf_bss_info_le *bss, } static s32 -brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, +brcmf_cfg80211_escan_handler(struct brcmf_cfg80211_info *cfg, + struct net_device *ndev, const struct brcmf_event_msg *e, void *data) { - struct brcmf_cfg80211_info *cfg = ifp->drvr->config; - struct net_device *ndev = ifp->ndev; s32 status; s32 err = 0; struct brcmf_escan_result_le *escan_result_le; @@ -2454,11 +2879,13 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, u32 i; bool aborted; - status = e->status; + status = be32_to_cpu(e->status); - if (!ndev || !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { - WL_ERR("scan not ready ndev %p drv_status %x\n", ndev, - !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)); + if (!ndev || !cfg->escan_on || + !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { + WL_ERR("scan not ready ndev %p wl->escan_on %d drv_status %x\n", + ndev, cfg->escan_on, + !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)); return -EPERM; } @@ -2535,15 +2962,18 @@ brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg) { - brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT, - brcmf_cfg80211_escan_handler); - cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE; - /* Init scan_timeout timer */ - init_timer(&cfg->escan_timeout); - cfg->escan_timeout.data = (unsigned long) cfg; - cfg->escan_timeout.function = brcmf_escan_timeout; - INIT_WORK(&cfg->escan_timeout_work, - brcmf_cfg80211_escan_timeout_worker); + + if (cfg->escan_on) { + cfg->el.handler[BRCMF_E_ESCAN_RESULT] = + brcmf_cfg80211_escan_handler; + cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE; + /* Init scan_timeout timer */ + init_timer(&cfg->escan_timeout); + cfg->escan_timeout.data = (unsigned long) cfg; + cfg->escan_timeout.function = brcmf_escan_timeout; + INIT_WORK(&cfg->escan_timeout_work, + brcmf_cfg80211_escan_timeout_worker); + } } static __always_inline void brcmf_delay(u32 ms) @@ -2558,8 +2988,20 @@ static __always_inline void brcmf_delay(u32 ms) static s32 brcmf_cfg80211_resume(struct wiphy *wiphy) { + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); + + /* + * Check for BRCMF_VIF_STATUS_READY before any function call which + * could result is bus access. Don't block the resume for + * any driver error conditions + */ WL_TRACE("Enter\n"); + if (check_vif_up(ifp->vif)) + brcmf_invoke_iscan(cfg); + + WL_TRACE("Exit\n"); return 0; } @@ -2587,13 +3029,17 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy, * While going to suspend if associated with AP disassociate * from AP to save power while system is in suspended state */ - brcmf_link_down(vif); - - /* Make sure WPA_Supplicant receives all the event - * generated due to DISASSOC call to the fw to keep - * the state fw and WPA_Supplicant state consistent - */ - brcmf_delay(500); + if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state) || + test_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state)) { + WL_INFO("Disassociating from AP before suspend\n"); + brcmf_link_down(cfg); + + /* Make sure WPA_Supplicant receives all the event + * generated due to DISASSOC call to the fw to keep + * the state fw and WPA_Supplicant state consistent + */ + brcmf_delay(500); + } } /* end any scanning */ @@ -2754,11 +3200,10 @@ brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev) * cfg80211_scan_request one out of the received PNO event. */ static s32 -brcmf_notify_sched_scan_results(struct brcmf_if *ifp, +brcmf_notify_sched_scan_results(struct brcmf_cfg80211_info *cfg, + struct net_device *ndev, const struct brcmf_event_msg *e, void *data) { - struct brcmf_cfg80211_info *cfg = ifp->drvr->config; - struct net_device *ndev = ifp->ndev; struct brcmf_pno_net_info_le *netinfo, *netinfo_start; struct cfg80211_scan_request *request = NULL; struct cfg80211_ssid *ssid = NULL; @@ -2773,7 +3218,7 @@ brcmf_notify_sched_scan_results(struct brcmf_if *ifp, WL_SCAN("Enter\n"); - if (e->event_code == BRCMF_E_PFN_NET_LOST) { + if (e->event_type == cpu_to_be32(BRCMF_E_PFN_NET_LOST)) { WL_SCAN("PFN NET LOST event. Do Nothing\n"); return 0; } @@ -2866,6 +3311,7 @@ brcmf_notify_sched_scan_results(struct brcmf_if *ifp, return err; } +#ifndef CONFIG_BRCMISCAN static int brcmf_dev_pno_clean(struct net_device *ndev) { int ret; @@ -3002,6 +3448,7 @@ static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy, brcmf_notify_escan_complete(cfg, ndev, true, true); return 0; } +#endif /* CONFIG_BRCMISCAN */ #ifdef CONFIG_NL80211_TESTMODE static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len) @@ -3067,7 +3514,7 @@ static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie) static s32 brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie, - bool is_rsn_ie) + bool is_rsn_ie, s32 bssidx) { struct brcmf_if *ifp = netdev_priv(ndev); u32 auth = 0; /* d11 open authentication */ @@ -3244,7 +3691,7 @@ brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie, } static s32 -brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len, +brcmf_parse_vndr_ies(u8 *vndr_ie_buf, u32 vndr_ie_len, struct parsed_vndr_ies *vndr_ies) { s32 err = 0; @@ -3293,12 +3740,11 @@ brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len, if (vndr_ies->count >= MAX_VNDR_IE_NUMBER) break; next: - remaining_len -= (ie->len + TLV_HDR_LEN); - if (remaining_len <= TLV_HDR_LEN) + remaining_len -= ie->len; + if (remaining_len <= 2) ie = NULL; else - ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len + - TLV_HDR_LEN); + ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len); } return err; } @@ -3324,12 +3770,13 @@ brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd) return ie_len + VNDR_IE_HDR_SIZE; } -static -s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, - const u8 *vndr_ie_buf, u32 vndr_ie_len) +static s32 +brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg, + struct net_device *ndev, s32 pktflag, + u8 *vndr_ie_buf, u32 vndr_ie_len) { - struct brcmf_if *ifp; - struct vif_saved_ie *saved_ie; + struct brcmf_if *ifp = netdev_priv(ndev); + struct vif_saved_ie *saved_ie = &ifp->vif->saved_ie; s32 err = 0; u8 *iovar_ie_buf; u8 *curr_ie_buf; @@ -3346,12 +3793,8 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, u8 *ptr; int remained_buf_len; - if (!vif) - return -ENODEV; - ifp = vif->ifp; - saved_ie = &vif->saved_ie; - - WL_TRACE("bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag); + WL_TRACE("bssidx %d, pktflag : 0x%02X\n", + brcmf_ndev_bssidx(ndev), pktflag); iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); if (!iovar_ie_buf) return -ENOMEM; @@ -3397,11 +3840,11 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, } } - if (mgmt_ie_buf && *mgmt_ie_len) { + if (mgmt_ie_buf != NULL) { if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) && (memcmp(mgmt_ie_buf, curr_ie_buf, parsed_ie_buf_len) == 0)) { - WL_TRACE("Previous mgmt IE equals to current IE\n"); + WL_TRACE("Previous mgmt IE is equals to current IE"); goto exit; } @@ -3439,16 +3882,6 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, for (i = 0; i < new_vndr_ies.count; i++) { vndrie_info = &new_vndr_ies.ie_info[i]; - /* verify remained buf size before copy data */ - if (remained_buf_len < (vndrie_info->vndrie.len + - VNDR_IE_VSIE_OFFSET)) { - WL_ERR("no space in mgmt_ie_buf: len left %d", - remained_buf_len); - break; - } - remained_buf_len -= (vndrie_info->ie_len + - VNDR_IE_VSIE_OFFSET); - WL_TRACE("ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n", vndrie_info->vndrie.id, vndrie_info->vndrie.len, @@ -3460,6 +3893,13 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, vndrie_info->ie_ptr, vndrie_info->ie_len, "add"); + /* verify remained buf size before copy data */ + remained_buf_len -= vndrie_info->ie_len; + if (remained_buf_len < 0) { + WL_ERR("no space in mgmt_ie_buf: len left %d", + remained_buf_len); + break; + } /* save the parsed IE in wl struct */ memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr, @@ -3494,13 +3934,14 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, struct brcmf_tlv *rsn_ie; struct brcmf_vs_tlv *wpa_ie; struct brcmf_join_params join_params; + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); s32 bssidx = 0; WL_TRACE("channel_type=%d, beacon_interval=%d, dtim_period=%d,\n", cfg80211_get_chandef_type(&settings->chandef), settings->beacon_interval, settings->dtim_period); - WL_TRACE("ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n", + WL_TRACE("ssid=%s(%d), auth_type=%d, inactivity_timeout=%d\n", settings->ssid, settings->ssid_len, settings->auth_type, settings->inactivity_timeout); @@ -3552,39 +3993,55 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail, settings->beacon.tail_len); + kfree(cfg->ap_info->rsn_ie); + cfg->ap_info->rsn_ie = NULL; + kfree(cfg->ap_info->wpa_ie); + cfg->ap_info->wpa_ie = NULL; + if ((wpa_ie != NULL || rsn_ie != NULL)) { WL_TRACE("WPA(2) IE is found\n"); if (wpa_ie != NULL) { /* WPA IE */ - err = brcmf_configure_wpaie(ndev, wpa_ie, false); + err = brcmf_configure_wpaie(ndev, wpa_ie, false, + bssidx); if (err < 0) goto exit; + cfg->ap_info->wpa_ie = kmemdup(wpa_ie, + wpa_ie->len + + TLV_HDR_LEN, + GFP_KERNEL); } else { /* RSN IE */ err = brcmf_configure_wpaie(ndev, - (struct brcmf_vs_tlv *)rsn_ie, true); + (struct brcmf_vs_tlv *)rsn_ie, true, bssidx); if (err < 0) goto exit; + cfg->ap_info->rsn_ie = kmemdup(rsn_ie, + rsn_ie->len + + TLV_HDR_LEN, + GFP_KERNEL); } + cfg->ap_info->security_mode = true; } else { WL_TRACE("No WPA(2) IEs found\n"); brcmf_configure_opensecurity(ndev, bssidx); + cfg->ap_info->security_mode = false; } /* Set Beacon IEs to FW */ - err = brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev), - VNDR_IE_BEACON_FLAG, - settings->beacon.tail, - settings->beacon.tail_len); + err = brcmf_set_management_ie(cfg, ndev, + VNDR_IE_BEACON_FLAG, + (u8 *)settings->beacon.tail, + settings->beacon.tail_len); if (err) WL_ERR("Set Beacon IE Failed\n"); else WL_TRACE("Applied Vndr IEs for Beacon\n"); /* Set Probe Response IEs to FW */ - err = brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev), - VNDR_IE_PRBRSP_FLAG, - settings->beacon.proberesp_ies, - settings->beacon.proberesp_ies_len); + err = brcmf_set_management_ie(cfg, ndev, + VNDR_IE_PRBRSP_FLAG, + (u8 *)settings->beacon.proberesp_ies, + settings->beacon.proberesp_ies_len); if (err) WL_ERR("Set Probe Resp IE Failed\n"); else @@ -3634,20 +4091,22 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev) { struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); s32 err = -EPERM; WL_TRACE("Enter\n"); - if (ifp->vif->mode == WL_MODE_AP) { + if (cfg->conf->mode == WL_MODE_AP) { /* Due to most likely deauths outstanding we sleep */ /* first to make sure they get processed by fw. */ msleep(400); - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0); + err = brcmf_fil_cmd_int_set(netdev_priv(ndev), + BRCMF_C_SET_AP, 0); if (err < 0) { WL_ERR("setting AP mode failed %d\n", err); goto exit; } - err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0); + err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_UP, 0); if (err < 0) { WL_ERR("BRCMF_C_UP error %d\n", err); goto exit; @@ -3713,8 +4172,11 @@ static struct cfg80211_ops wl_cfg80211_ops = { .start_ap = brcmf_cfg80211_start_ap, .stop_ap = brcmf_cfg80211_stop_ap, .del_station = brcmf_cfg80211_del_station, +#ifndef CONFIG_BRCMISCAN + /* scheduled scan need e-scan, which is mutual exclusive with i-scan */ .sched_scan_start = brcmf_cfg80211_sched_scan_start, .sched_scan_stop = brcmf_cfg80211_sched_scan_stop, +#endif #ifdef CONFIG_NL80211_TESTMODE .testmode_cmd = brcmf_cfg80211_testmode #endif @@ -3738,11 +4200,13 @@ static s32 brcmf_mode_to_nl80211_iftype(s32 mode) static void brcmf_wiphy_pno_params(struct wiphy *wiphy) { +#ifndef CONFIG_BRCMFISCAN /* scheduled scan settings */ wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT; wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT; wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX; wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; +#endif } static struct wiphy *brcmf_setup_wiphy(struct device *phydev) @@ -3838,23 +4302,26 @@ static void brcmf_free_vif(struct brcmf_cfg80211_vif *vif) } } -static bool brcmf_is_linkup(const struct brcmf_event_msg *e) +static bool brcmf_is_linkup(struct brcmf_cfg80211_info *cfg, + const struct brcmf_event_msg *e) { - u32 event = e->event_code; - u32 status = e->status; + u32 event = be32_to_cpu(e->event_type); + u32 status = be32_to_cpu(e->status); if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) { WL_CONN("Processing set ssid\n"); + cfg->link_up = true; return true; } return false; } -static bool brcmf_is_linkdown(const struct brcmf_event_msg *e) +static bool brcmf_is_linkdown(struct brcmf_cfg80211_info *cfg, + const struct brcmf_event_msg *e) { - u32 event = e->event_code; - u16 flags = e->flags; + u32 event = be32_to_cpu(e->event_type); + u16 flags = be16_to_cpu(e->flags); if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) { WL_CONN("Processing link down\n"); @@ -3866,12 +4333,13 @@ static bool brcmf_is_linkdown(const struct brcmf_event_msg *e) static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg, const struct brcmf_event_msg *e) { - u32 event = e->event_code; - u32 status = e->status; + u32 event = be32_to_cpu(e->event_type); + u32 status = be32_to_cpu(e->status); if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) { WL_CONN("Processing Link %s & no network found\n", - e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down"); + be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ? + "up" : "down"); return true; } @@ -4059,9 +4527,9 @@ brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg, const struct brcmf_event_msg *e, void *data) { s32 err = 0; - u32 event = e->event_code; - u32 reason = e->reason; - u32 len = e->datalen; + u32 event = be32_to_cpu(e->event_type); + u32 reason = be32_to_cpu(e->reason); + u32 len = be32_to_cpu(e->datalen); static int generation; struct station_info sinfo; @@ -4093,19 +4561,19 @@ brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg, } static s32 -brcmf_notify_connect_status(struct brcmf_if *ifp, +brcmf_notify_connect_status(struct brcmf_cfg80211_info *cfg, + struct net_device *ndev, const struct brcmf_event_msg *e, void *data) { - struct brcmf_cfg80211_info *cfg = ifp->drvr->config; - struct net_device *ndev = ifp->ndev; + struct brcmf_if *ifp = netdev_priv(ndev); struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; s32 err = 0; - if (ifp->vif->mode == WL_MODE_AP) { + if (cfg->conf->mode == WL_MODE_AP) { err = brcmf_notify_connect_status_ap(cfg, ndev, e, data); - } else if (brcmf_is_linkup(e)) { + } else if (brcmf_is_linkup(cfg, e)) { WL_CONN("Linkup\n"); - if (brcmf_is_ibssmode(ifp->vif)) { + if (brcmf_is_ibssmode(cfg)) { memcpy(profile->bssid, e->addr, ETH_ALEN); wl_inform_ibss(cfg, ndev, e->addr); cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL); @@ -4115,19 +4583,26 @@ brcmf_notify_connect_status(struct brcmf_if *ifp, &ifp->vif->sme_state); } else brcmf_bss_connect_done(cfg, ndev, e, true); - } else if (brcmf_is_linkdown(e)) { + } else if (brcmf_is_linkdown(cfg, e)) { WL_CONN("Linkdown\n"); - if (!brcmf_is_ibssmode(ifp->vif)) { - brcmf_bss_connect_done(cfg, ndev, e, false); + if (brcmf_is_ibssmode(cfg)) { + clear_bit(BRCMF_VIF_STATUS_CONNECTING, + &ifp->vif->sme_state); if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state)) + brcmf_link_down(cfg); + } else { + brcmf_bss_connect_done(cfg, ndev, e, false); + if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED, + &ifp->vif->sme_state)) { cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL); + brcmf_link_down(cfg); + } } - brcmf_link_down(ifp->vif); brcmf_init_prof(ndev_to_prof(ndev)); } else if (brcmf_is_nonetwork(cfg, e)) { - if (brcmf_is_ibssmode(ifp->vif)) + if (brcmf_is_ibssmode(cfg)) clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state); else @@ -4138,29 +4613,31 @@ brcmf_notify_connect_status(struct brcmf_if *ifp, } static s32 -brcmf_notify_roaming_status(struct brcmf_if *ifp, +brcmf_notify_roaming_status(struct brcmf_cfg80211_info *cfg, + struct net_device *ndev, const struct brcmf_event_msg *e, void *data) { - struct brcmf_cfg80211_info *cfg = ifp->drvr->config; + struct brcmf_if *ifp = netdev_priv(ndev); s32 err = 0; - u32 event = e->event_code; - u32 status = e->status; + u32 event = be32_to_cpu(e->event_type); + u32 status = be32_to_cpu(e->status); if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) { if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state)) - brcmf_bss_roaming_done(cfg, ifp->ndev, e); + brcmf_bss_roaming_done(cfg, ndev, e); else - brcmf_bss_connect_done(cfg, ifp->ndev, e, true); + brcmf_bss_connect_done(cfg, ndev, e, true); } return err; } static s32 -brcmf_notify_mic_status(struct brcmf_if *ifp, +brcmf_notify_mic_status(struct brcmf_cfg80211_info *cfg, + struct net_device *ndev, const struct brcmf_event_msg *e, void *data) { - u16 flags = e->flags; + u16 flags = be16_to_cpu(e->flags); enum nl80211_key_type key_type; if (flags & BRCMF_EVENT_MSG_GROUP) @@ -4168,14 +4645,87 @@ brcmf_notify_mic_status(struct brcmf_if *ifp, else key_type = NL80211_KEYTYPE_PAIRWISE; - cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1, + cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1, NULL, GFP_KERNEL); return 0; } +static s32 +brcmf_notify_scan_status(struct brcmf_cfg80211_info *cfg, + struct net_device *ndev, + const struct brcmf_event_msg *e, void *data) +{ + struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_channel_info_le channel_inform_le; + struct brcmf_scan_results_le *bss_list_le; + u32 len = WL_SCAN_BUF_MAX; + s32 err = 0; + bool scan_abort = false; + u32 scan_channel; + + WL_TRACE("Enter\n"); + + if (cfg->iscan_on && cfg->iscan_kickstart) { + WL_TRACE("Exit\n"); + return brcmf_wakeup_iscan(cfg_to_iscan(cfg)); + } + + if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { + WL_ERR("Scan complete while device not scanning\n"); + scan_abort = true; + err = -EINVAL; + goto scan_done_out; + } + + err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_CHANNEL, + &channel_inform_le, + sizeof(channel_inform_le)); + if (err) { + WL_ERR("scan busy (%d)\n", err); + scan_abort = true; + goto scan_done_out; + } + scan_channel = le32_to_cpu(channel_inform_le.scan_channel); + if (scan_channel) + WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel); + cfg->bss_list = cfg->scan_results; + bss_list_le = (struct brcmf_scan_results_le *) cfg->bss_list; + + memset(cfg->scan_results, 0, len); + bss_list_le->buflen = cpu_to_le32(len); + err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_SCAN_RESULTS, + cfg->scan_results, len); + if (err) { + WL_ERR("%s Scan_results error (%d)\n", ndev->name, err); + err = -EINVAL; + scan_abort = true; + goto scan_done_out; + } + cfg->scan_results->buflen = le32_to_cpu(bss_list_le->buflen); + cfg->scan_results->version = le32_to_cpu(bss_list_le->version); + cfg->scan_results->count = le32_to_cpu(bss_list_le->count); + + err = brcmf_inform_bss(cfg); + if (err) + scan_abort = true; + +scan_done_out: + if (cfg->scan_request) { + WL_SCAN("calling cfg80211_scan_done\n"); + cfg80211_scan_done(cfg->scan_request, scan_abort); + brcmf_set_mpc(ndev, 1); + cfg->scan_request = NULL; + } + + WL_TRACE("Exit\n"); + + return err; +} + static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf) { + conf->mode = (u32)-1; conf->frag_threshold = (u32)-1; conf->rts_threshold = (u32)-1; conf->retry_short = (u32)-1; @@ -4183,53 +4733,77 @@ static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf) conf->tx_power = -1; } -static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg) -{ - brcmf_fweh_register(cfg->pub, BRCMF_E_LINK, - brcmf_notify_connect_status); - brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND, - brcmf_notify_connect_status); - brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH, - brcmf_notify_connect_status); - brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND, - brcmf_notify_connect_status); - brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND, - brcmf_notify_connect_status); - brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND, - brcmf_notify_connect_status); - brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM, - brcmf_notify_roaming_status); - brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR, - brcmf_notify_mic_status); - brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID, - brcmf_notify_connect_status); - brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND, - brcmf_notify_sched_scan_results); +static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el) +{ + memset(el, 0, sizeof(*el)); + el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status; + el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status; + el->handler[BRCMF_E_DEAUTH_IND] = brcmf_notify_connect_status; + el->handler[BRCMF_E_DEAUTH] = brcmf_notify_connect_status; + el->handler[BRCMF_E_DISASSOC_IND] = brcmf_notify_connect_status; + el->handler[BRCMF_E_ASSOC_IND] = brcmf_notify_connect_status; + el->handler[BRCMF_E_REASSOC_IND] = brcmf_notify_connect_status; + el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status; + el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status; + el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status; + el->handler[BRCMF_E_PFN_NET_FOUND] = brcmf_notify_sched_scan_results; } static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg) { + kfree(cfg->scan_results); + cfg->scan_results = NULL; + kfree(cfg->bss_info); + cfg->bss_info = NULL; kfree(cfg->conf); cfg->conf = NULL; + kfree(cfg->scan_req_int); + cfg->scan_req_int = NULL; kfree(cfg->escan_ioctl_buf); cfg->escan_ioctl_buf = NULL; + kfree(cfg->dcmd_buf); + cfg->dcmd_buf = NULL; kfree(cfg->extra_buf); cfg->extra_buf = NULL; + kfree(cfg->iscan); + cfg->iscan = NULL; kfree(cfg->pmk_list); cfg->pmk_list = NULL; + if (cfg->ap_info) { + kfree(cfg->ap_info->wpa_ie); + kfree(cfg->ap_info->rsn_ie); + kfree(cfg->ap_info); + cfg->ap_info = NULL; + } } static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg) { + cfg->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL); + if (!cfg->scan_results) + goto init_priv_mem_out; cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL); if (!cfg->conf) goto init_priv_mem_out; + cfg->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL); + if (!cfg->bss_info) + goto init_priv_mem_out; + cfg->scan_req_int = kzalloc(sizeof(*cfg->scan_req_int), + GFP_KERNEL); + if (!cfg->scan_req_int) + goto init_priv_mem_out; cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL); if (!cfg->escan_ioctl_buf) goto init_priv_mem_out; + cfg->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL); + if (!cfg->dcmd_buf) + goto init_priv_mem_out; cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); if (!cfg->extra_buf) goto init_priv_mem_out; + cfg->iscan = kzalloc(sizeof(*cfg->iscan), GFP_KERNEL); + if (!cfg->iscan) + goto init_priv_mem_out; cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL); if (!cfg->pmk_list) goto init_priv_mem_out; @@ -4242,31 +4816,162 @@ static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg) return -ENOMEM; } +/* +* retrieve first queued event from head +*/ + +static struct brcmf_cfg80211_event_q *brcmf_deq_event( + struct brcmf_cfg80211_info *cfg) +{ + struct brcmf_cfg80211_event_q *e = NULL; + + spin_lock_irq(&cfg->evt_q_lock); + if (!list_empty(&cfg->evt_q_list)) { + e = list_first_entry(&cfg->evt_q_list, + struct brcmf_cfg80211_event_q, evt_q_list); + list_del(&e->evt_q_list); + } + spin_unlock_irq(&cfg->evt_q_lock); + + return e; +} + +/* +* push event to tail of the queue +* +* remark: this function may not sleep as it is called in atomic context. +*/ + +static s32 +brcmf_enq_event(struct brcmf_cfg80211_info *cfg, u32 event, + const struct brcmf_event_msg *msg, void *data) +{ + struct brcmf_cfg80211_event_q *e; + s32 err = 0; + ulong flags; + u32 data_len; + u32 total_len; + + total_len = sizeof(struct brcmf_cfg80211_event_q); + if (data) + data_len = be32_to_cpu(msg->datalen); + else + data_len = 0; + total_len += data_len; + e = kzalloc(total_len, GFP_ATOMIC); + if (!e) + return -ENOMEM; + + e->etype = event; + memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg)); + if (data) + memcpy(&e->edata, data, data_len); + + spin_lock_irqsave(&cfg->evt_q_lock, flags); + list_add_tail(&e->evt_q_list, &cfg->evt_q_list); + spin_unlock_irqrestore(&cfg->evt_q_lock, flags); + + return err; +} + +static void brcmf_put_event(struct brcmf_cfg80211_event_q *e) +{ + kfree(e); +} + +static void brcmf_cfg80211_event_handler(struct work_struct *work) +{ + struct brcmf_cfg80211_info *cfg = + container_of(work, struct brcmf_cfg80211_info, + event_work); + struct brcmf_cfg80211_event_q *e; + + e = brcmf_deq_event(cfg); + if (unlikely(!e)) { + WL_ERR("event queue empty...\n"); + return; + } + + do { + WL_INFO("event type (%d)\n", e->etype); + if (cfg->el.handler[e->etype]) + cfg->el.handler[e->etype](cfg, + cfg_to_ndev(cfg), + &e->emsg, e->edata); + else + WL_INFO("Unknown Event (%d): ignoring\n", e->etype); + brcmf_put_event(e); + } while ((e = brcmf_deq_event(cfg))); + +} + +static void brcmf_init_eq(struct brcmf_cfg80211_info *cfg) +{ + spin_lock_init(&cfg->evt_q_lock); + INIT_LIST_HEAD(&cfg->evt_q_list); +} + +static void brcmf_flush_eq(struct brcmf_cfg80211_info *cfg) +{ + struct brcmf_cfg80211_event_q *e; + + spin_lock_irq(&cfg->evt_q_lock); + while (!list_empty(&cfg->evt_q_list)) { + e = list_first_entry(&cfg->evt_q_list, + struct brcmf_cfg80211_event_q, evt_q_list); + list_del(&e->evt_q_list); + kfree(e); + } + spin_unlock_irq(&cfg->evt_q_lock); +} + static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg) { s32 err = 0; cfg->scan_request = NULL; cfg->pwr_save = true; +#ifdef CONFIG_BRCMISCAN + cfg->iscan_on = true; /* iscan on & off switch. + we enable iscan per default */ + cfg->escan_on = false; /* escan on & off switch. + we disable escan per default */ +#else + cfg->iscan_on = false; /* iscan on & off switch. + we disable iscan per default */ + cfg->escan_on = true; /* escan on & off switch. + we enable escan per default */ +#endif cfg->roam_on = true; /* roam on & off switch. we enable roam per default */ + + cfg->iscan_kickstart = false; cfg->active_scan = true; /* we do active scan for specific scan per default */ cfg->dongle_up = false; /* dongle is not up yet */ + brcmf_init_eq(cfg); err = brcmf_init_priv_mem(cfg); if (err) return err; - brcmf_register_event_handlers(cfg); + INIT_WORK(&cfg->event_work, brcmf_cfg80211_event_handler); + brcmf_init_eloop_handler(&cfg->el); mutex_init(&cfg->usr_sync); + err = brcmf_init_iscan(cfg); + if (err) + return err; brcmf_init_escan(cfg); brcmf_init_conf(cfg->conf); + brcmf_link_down(cfg); return err; } static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg) { + cancel_work_sync(&cfg->event_work); cfg->dongle_up = false; /* dongle down */ + brcmf_flush_eq(cfg); + brcmf_link_down(cfg); brcmf_abort_scanning(cfg); brcmf_deinit_priv_mem(cfg); } @@ -4327,6 +5032,66 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg) } } +void +brcmf_cfg80211_event(struct net_device *ndev, + const struct brcmf_event_msg *e, void *data) +{ + u32 event_type = be32_to_cpu(e->event_type); + struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); + + if (!brcmf_enq_event(cfg, event_type, e, data)) + schedule_work(&cfg->event_work); +} + +static s32 brcmf_dongle_eventmsg(struct net_device *ndev) +{ + s8 eventmask[BRCMF_EVENTING_MASK_LEN]; + s32 err = 0; + + WL_TRACE("Enter\n"); + + /* Setup event_msgs */ + err = brcmf_fil_iovar_data_get(netdev_priv(ndev), "event_msgs", + eventmask, BRCMF_EVENTING_MASK_LEN); + if (err) { + WL_ERR("Get event_msgs error (%d)\n", err); + goto dongle_eventmsg_out; + } + + setbit(eventmask, BRCMF_E_SET_SSID); + setbit(eventmask, BRCMF_E_ROAM); + setbit(eventmask, BRCMF_E_PRUNE); + setbit(eventmask, BRCMF_E_AUTH); + setbit(eventmask, BRCMF_E_REASSOC); + setbit(eventmask, BRCMF_E_REASSOC_IND); + setbit(eventmask, BRCMF_E_DEAUTH_IND); + setbit(eventmask, BRCMF_E_DISASSOC_IND); + setbit(eventmask, BRCMF_E_DISASSOC); + setbit(eventmask, BRCMF_E_JOIN); + setbit(eventmask, BRCMF_E_ASSOC_IND); + setbit(eventmask, BRCMF_E_PSK_SUP); + setbit(eventmask, BRCMF_E_LINK); + setbit(eventmask, BRCMF_E_NDIS_LINK); + setbit(eventmask, BRCMF_E_MIC_ERROR); + setbit(eventmask, BRCMF_E_PMKID_CACHE); + setbit(eventmask, BRCMF_E_TXFAIL); + setbit(eventmask, BRCMF_E_JOIN_START); + setbit(eventmask, BRCMF_E_SCAN_COMPLETE); + setbit(eventmask, BRCMF_E_ESCAN_RESULT); + setbit(eventmask, BRCMF_E_PFN_NET_FOUND); + + err = brcmf_fil_iovar_data_set(netdev_priv(ndev), "event_msgs", + eventmask, BRCMF_EVENTING_MASK_LEN); + if (err) { + WL_ERR("Set event_msgs error (%d)\n", err); + goto dongle_eventmsg_out; + } + +dongle_eventmsg_out: + WL_TRACE("Exit\n"); + return err; +} + static s32 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout) { @@ -4428,7 +5193,7 @@ static s32 wl_update_wiphybands(struct brcmf_cfg80211_info *cfg) s8 phy; s32 err = 0; - err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST, + err = brcmf_fil_cmd_data_get(ifp, BRCM_GET_PHYLIST, &phy_list, sizeof(phy_list)); if (err) { WL_ERR("error (%d)\n", err); @@ -4466,6 +5231,10 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME, WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME); + err = brcmf_dongle_eventmsg(ndev); + if (err) + goto default_conf_out; + power_mode = cfg->pwr_save ? PM_FAST : PM_OFF; err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PM, power_mode); @@ -4496,25 +5265,36 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) } -static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp) +static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg) { + struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); + s32 err = 0; + set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state); - if (ifp->idx) - return 0; - return brcmf_config_dongle(ifp->drvr->config); + err = brcmf_config_dongle(cfg); + if (err) + return err; + + brcmf_invoke_iscan(cfg); + + return err; } -static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp) +static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg) { - struct brcmf_cfg80211_info *cfg = ifp->drvr->config; + struct net_device *ndev = cfg_to_ndev(cfg); + struct brcmf_if *ifp = netdev_priv(ndev); /* * While going down, if associated with AP disassociate * from AP to save power */ - if (check_vif_up(ifp->vif)) { - brcmf_link_down(ifp->vif); + if ((test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state) || + test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) && + check_vif_up(ifp->vif)) { + WL_INFO("Disassociating from AP"); + brcmf_link_down(cfg); /* Make sure WPA_Supplicant receives all the event generated due to DISASSOC call to the fw to keep @@ -4529,27 +5309,23 @@ static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp) return 0; } -s32 brcmf_cfg80211_up(struct net_device *ndev) +s32 brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg) { - struct brcmf_if *ifp = netdev_priv(ndev); - struct brcmf_cfg80211_info *cfg = ifp->drvr->config; s32 err = 0; mutex_lock(&cfg->usr_sync); - err = __brcmf_cfg80211_up(ifp); + err = __brcmf_cfg80211_up(cfg); mutex_unlock(&cfg->usr_sync); return err; } -s32 brcmf_cfg80211_down(struct net_device *ndev) +s32 brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg) { - struct brcmf_if *ifp = netdev_priv(ndev); - struct brcmf_cfg80211_info *cfg = ifp->drvr->config; s32 err = 0; mutex_lock(&cfg->usr_sync); - err = __brcmf_cfg80211_down(ifp); + err = __brcmf_cfg80211_down(cfg); mutex_unlock(&cfg->usr_sync); return err; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h index d60de187e7d9..1dd96f148ef7 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h @@ -84,12 +84,31 @@ do { \ #define WL_CONN(fmt, args...) #endif /* (defined DEBUG) */ -#define WL_NUM_SCAN_MAX 10 -#define WL_NUM_PMKIDS_MAX MAXPMKID +#define WL_NUM_SCAN_MAX 1 +#define WL_NUM_PMKIDS_MAX MAXPMKID /* will be used + * for 2.6.33 kernel + * or later + */ +#define WL_SCAN_BUF_MAX (1024 * 8) #define WL_TLV_INFO_MAX 1024 #define WL_BSS_INFO_MAX 2048 -#define WL_ASSOC_INFO_MAX 512 /* assoc related fil max buf */ -#define WL_EXTRA_BUF_MAX 2048 +#define WL_ASSOC_INFO_MAX 512 /* + * needs to grab assoc info from dongle to + * report it to cfg80211 through "connect" + * event + */ +#define WL_DCMD_LEN_MAX 1024 +#define WL_EXTRA_BUF_MAX 2048 +#define WL_ISCAN_BUF_MAX 2048 /* + * the buf length can be BRCMF_DCMD_MAXLEN + * to reduce iteration + */ +#define WL_ISCAN_TIMER_INTERVAL_MS 3000 +#define WL_SCAN_ERSULTS_LAST (BRCMF_SCAN_RESULTS_NO_MEM+1) +#define WL_AP_MAX 256 /* virtually unlimitted as long + * as kernel memory allows + */ + #define WL_ROAM_TRIGGER_LEVEL -75 #define WL_ROAM_DELTA 20 #define WL_BEACON_TIMEOUT 3 @@ -126,8 +145,15 @@ enum wl_mode { WL_MODE_AP }; +/* dongle iscan state */ +enum wl_iscan_state { + WL_ISCAN_STATE_IDLE, + WL_ISCAN_STATE_SCANING +}; + /* dongle configuration */ struct brcmf_cfg80211_conf { + u32 mode; /* adhoc , infrastructure or ap */ u32 frag_threshold; u32 rts_threshold; u32 retry_short; @@ -136,6 +162,17 @@ struct brcmf_cfg80211_conf { struct ieee80211_channel channel; }; +/* forward declaration */ +struct brcmf_cfg80211_info; + +/* cfg80211 main event loop */ +struct brcmf_cfg80211_event_loop { + s32(*handler[BRCMF_E_LAST]) (struct brcmf_cfg80211_info *cfg, + struct net_device *ndev, + const struct brcmf_event_msg *e, + void *data); +}; + /* basic structure of scan request */ struct brcmf_cfg80211_scan_req { struct brcmf_ssid_le ssid_le; @@ -147,6 +184,14 @@ struct brcmf_cfg80211_ie { u8 buf[WL_TLV_INFO_MAX]; }; +/* event queue for cfg80211 main event */ +struct brcmf_cfg80211_event_q { + struct list_head evt_q_list; + u32 etype; + struct brcmf_event_msg emsg; + s8 edata[1]; +}; + /* security information with currently associated ap */ struct brcmf_cfg80211_security { u32 wpa_versions; @@ -225,6 +270,26 @@ struct brcmf_cfg80211_vif { struct list_head list; }; +/* dongle iscan event loop */ +struct brcmf_cfg80211_iscan_eloop { + s32 (*handler[WL_SCAN_ERSULTS_LAST]) + (struct brcmf_cfg80211_info *cfg); +}; + +/* dongle iscan controller */ +struct brcmf_cfg80211_iscan_ctrl { + struct net_device *ndev; + struct timer_list timer; + u32 timer_ms; + u32 timer_on; + s32 state; + struct work_struct work; + struct brcmf_cfg80211_iscan_eloop el; + void *data; + s8 dcmd_buf[BRCMF_DCMD_SMLEN]; + s8 scan_buf[WL_ISCAN_BUF_MAX]; +}; + /* association inform */ struct brcmf_cfg80211_connect_info { u8 *req_ie; @@ -258,6 +323,17 @@ struct escan_info { struct net_device *ndev; }; +/* Structure to hold WPS, WPA IEs for a AP */ +struct ap_info { + u8 probe_res_ie[IE_MAX_LEN]; + u8 beacon_ie[IE_MAX_LEN]; + u32 probe_res_ie_len; + u32 beacon_ie_len; + u8 *wpa_ie; + u8 *rsn_ie; + bool security_mode; +}; + /** * struct brcmf_pno_param_le - PNO scan configuration parameters * @@ -345,19 +421,28 @@ struct brcmf_pno_scanresults_le { * @wiphy: wiphy object for cfg80211 interface. * @conf: dongle configuration. * @scan_request: cfg80211 scan request object. + * @el: main event loop. + * @evt_q_list: used for event queue. + * @evt_q_lock: for event queue synchronization. * @usr_sync: mainly for dongle up/down synchronization. * @bss_list: bss_list holding scanned ap information. + * @scan_results: results of the last scan. * @scan_req_int: internal scan request object. * @bss_info: bss information for cfg80211 layer. * @ie: information element object for internal purpose. + * @iscan: iscan controller information. * @conn_info: association info. * @pmk_list: wpa2 pmk list. + * @event_work: event handler work struct. * @scan_status: scan activity on the dongle. * @pub: common driver information. * @channel: current channel. + * @iscan_on: iscan on/off switch. + * @iscan_kickstart: indicate iscan already started. * @active_scan: current scan mode. * @sched_escan: e-scan for scheduled scan support running. * @ibss_starter: indicates this sta is ibss starter. + * @link_up: link/connection up flag. * @pwr_save: indicate whether dongle to support power save mode. * @dongle_up: indicate whether dongle up or not. * @roam_on: on/off switch for dongle self-roaming. @@ -365,10 +450,12 @@ struct brcmf_pno_scanresults_le { * @dcmd_buf: dcmd buffer. * @extra_buf: mainly to grab assoc information. * @debugfsdir: debugfs folder for this device. + * @escan_on: escan on/off switch. * @escan_info: escan information. * @escan_timeout: Timer for catch scan timeout. * @escan_timeout_work: scan timeout worker. * @escan_ioctl_buf: dongle command buffer for escan commands. + * @ap_info: host ap information. * @vif_list: linked list of vif instances. * @vif_cnt: number of vif instances. */ @@ -376,19 +463,28 @@ struct brcmf_cfg80211_info { struct wiphy *wiphy; struct brcmf_cfg80211_conf *conf; struct cfg80211_scan_request *scan_request; + struct brcmf_cfg80211_event_loop el; + struct list_head evt_q_list; + spinlock_t evt_q_lock; struct mutex usr_sync; struct brcmf_scan_results *bss_list; - struct brcmf_cfg80211_scan_req scan_req_int; + struct brcmf_scan_results *scan_results; + struct brcmf_cfg80211_scan_req *scan_req_int; struct wl_cfg80211_bss_info *bss_info; struct brcmf_cfg80211_ie ie; + struct brcmf_cfg80211_iscan_ctrl *iscan; struct brcmf_cfg80211_connect_info conn_info; struct brcmf_cfg80211_pmk_list *pmk_list; + struct work_struct event_work; unsigned long scan_status; struct brcmf_pub *pub; u32 channel; + bool iscan_on; + bool iscan_kickstart; bool active_scan; bool sched_escan; bool ibss_starter; + bool link_up; bool pwr_save; bool dongle_up; bool roam_on; @@ -396,10 +492,12 @@ struct brcmf_cfg80211_info { u8 *dcmd_buf; u8 *extra_buf; struct dentry *debugfsdir; + bool escan_on; struct escan_info escan_info; struct timer_list escan_timeout; struct work_struct escan_timeout_work; u8 *escan_ioctl_buf; + struct ap_info *ap_info; struct list_head vif_list; u8 vif_cnt; }; @@ -438,11 +536,8 @@ static inline struct brcmf_cfg80211_profile *ndev_to_prof(struct net_device *nd) return &ifp->vif->profile; } -static inline struct brcmf_cfg80211_vif *ndev_to_vif(struct net_device *ndev) -{ - struct brcmf_if *ifp = netdev_priv(ndev); - return ifp->vif; -} +#define iscan_to_cfg(i) ((struct brcmf_cfg80211_info *)(i->data)) +#define cfg_to_iscan(w) (w->iscan) static inline struct brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_info *cfg) @@ -452,7 +547,11 @@ brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_info *cfg) struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr); void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg); -s32 brcmf_cfg80211_up(struct net_device *ndev); -s32 brcmf_cfg80211_down(struct net_device *ndev); + +/* event handler from dongle */ +void brcmf_cfg80211_event(struct net_device *ndev, + const struct brcmf_event_msg *e, void *data); +s32 brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg); +s32 brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg); #endif /* _wl_cfg80211_h_ */ diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/Makefile b/trunk/drivers/net/wireless/brcm80211/brcmsmac/Makefile index d3d4151c3eda..e227c4c68ef9 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/Makefile +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/Makefile @@ -40,8 +40,7 @@ BRCMSMAC_OFILES := \ phy/phytbl_n.o \ phy/phy_qmath.o \ dma.o \ - brcms_trace_events.o \ - debug.o + brcms_trace_events.o MODULEPFX := brcmsmac diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c index 1de94f30564f..be5bcfb9153b 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c @@ -21,8 +21,6 @@ #include "antsel.h" #include "main.h" #include "ampdu.h" -#include "debug.h" -#include "brcms_trace_events.h" /* max number of mpdus in an ampdu */ #define AMPDU_MAX_MPDU 32 @@ -42,6 +40,8 @@ #define AMPDU_DEF_RETRY_LIMIT 5 /* default tx retry limit at reg rate */ #define AMPDU_DEF_RR_RETRY_LIMIT 2 +/* default weight of ampdu in txfifo */ +#define AMPDU_DEF_TXPKT_WEIGHT 2 /* default ffpld reserved bytes */ #define AMPDU_DEF_FFPLD_RSVD 2048 /* # of inis to be freed on detach */ @@ -114,6 +114,7 @@ struct brcms_fifo_info { * mpdu_density: min mpdu spacing (0-7) ==> 2^(x-1)/8 usec * max_pdu: max pdus allowed in ampdu * dur: max duration of an ampdu (in msec) + * txpkt_weight: weight of ampdu in txfifo; reduces rate lag * rx_factor: maximum rx ampdu factor (0-3) ==> 2^(13+x) bytes * ffpld_rsvd: number of bytes to reserve for preload * max_txlen: max size of ampdu per mcs, bw and sgi @@ -135,6 +136,7 @@ struct ampdu_info { u8 mpdu_density; s8 max_pdu; u8 dur; + u8 txpkt_weight; u8 rx_factor; u32 ffpld_rsvd; u32 max_txlen[MCS_TABLE_SIZE][2][2]; @@ -181,19 +183,18 @@ static bool brcms_c_ampdu_cap(struct ampdu_info *ampdu) static int brcms_c_ampdu_set(struct ampdu_info *ampdu, bool on) { struct brcms_c_info *wlc = ampdu->wlc; - struct bcma_device *core = wlc->hw->d11core; wlc->pub->_ampdu = false; if (on) { if (!(wlc->pub->_n_enab & SUPPORT_11N)) { - brcms_err(core, "wl%d: driver not nmode enabled\n", - wlc->pub->unit); + wiphy_err(ampdu->wlc->wiphy, "wl%d: driver not " + "nmode enabled\n", wlc->pub->unit); return -ENOTSUPP; } if (!brcms_c_ampdu_cap(ampdu)) { - brcms_err(core, "wl%d: device not ampdu capable\n", - wlc->pub->unit); + wiphy_err(ampdu->wlc->wiphy, "wl%d: device not " + "ampdu capable\n", wlc->pub->unit); return -ENOTSUPP; } wlc->pub->_ampdu = on; @@ -246,6 +247,7 @@ struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc) ampdu->mpdu_density = AMPDU_DEF_MPDU_DENSITY; ampdu->max_pdu = AUTO; ampdu->dur = AMPDU_MAX_DUR; + ampdu->txpkt_weight = AMPDU_DEF_TXPKT_WEIGHT; ampdu->ffpld_rsvd = AMPDU_DEF_FFPLD_RSVD; /* @@ -372,8 +374,7 @@ static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid) offsetof(struct macstat, txfunfl[fid])); new_txunfl = (u16) (cur_txunfl - fifo->prev_txfunfl); if (new_txunfl == 0) { - brcms_dbg_ht(wlc->hw->d11core, - "TX status FRAG set but no tx underflows\n"); + BCMMSG(wlc->wiphy, "TX status FRAG set but no tx underflows\n"); return -1; } fifo->prev_txfunfl = cur_txunfl; @@ -395,8 +396,8 @@ static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid) if (fifo->accum_txfunfl < 10) return 0; - brcms_dbg_ht(wlc->hw->d11core, "ampdu_count %d tx_underflows %d\n", - current_ampdu_cnt, fifo->accum_txfunfl); + BCMMSG(wlc->wiphy, "ampdu_count %d tx_underflows %d\n", + current_ampdu_cnt, fifo->accum_txfunfl); /* compute the current ratio of tx unfl per ampdu. @@ -449,10 +450,9 @@ static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid) (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size)) / (max_mpdu * FFPLD_MPDU_SIZE)) * 100; - brcms_dbg_ht(wlc->hw->d11core, - "DMA estimated transfer rate %d; " - "pre-load size %d\n", - fifo->dmaxferrate, fifo->ampdu_pld_size); + BCMMSG(wlc->wiphy, "DMA estimated transfer rate %d; " + "pre-load size %d\n", + fifo->dmaxferrate, fifo->ampdu_pld_size); } else { /* decrease ampdu size */ @@ -486,7 +486,7 @@ brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid, scb_ampdu = &scb->scb_ampdu; if (!ampdu->ini_enable[tid]) { - brcms_err(wlc->hw->d11core, "%s: Rejecting tid %d\n", + wiphy_err(ampdu->wlc->wiphy, "%s: Rejecting tid %d\n", __func__, tid); return; } @@ -498,324 +498,378 @@ brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid, scb_ampdu->max_rx_ampdu_bytes = max_rx_ampdu_bytes; } -void brcms_c_ampdu_reset_session(struct brcms_ampdu_session *session, - struct brcms_c_info *wlc) +int +brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi, + struct sk_buff **pdu, int prec) { - session->wlc = wlc; - skb_queue_head_init(&session->skb_list); - session->max_ampdu_len = 0; /* determined from first MPDU */ - session->max_ampdu_frames = 0; /* determined from first MPDU */ - session->ampdu_len = 0; - session->dma_len = 0; -} + struct brcms_c_info *wlc; + struct sk_buff *p, *pkt[AMPDU_MAX_MPDU]; + u8 tid, ndelim; + int err = 0; + u8 preamble_type = BRCMS_GF_PREAMBLE; + u8 fbr_preamble_type = BRCMS_GF_PREAMBLE; + u8 rts_preamble_type = BRCMS_LONG_PREAMBLE; + u8 rts_fbr_preamble_type = BRCMS_LONG_PREAMBLE; -/* - * Preps the given packet for AMPDU based on the session data. If the - * frame cannot be accomodated in the current session, -ENOSPC is - * returned. - */ -int brcms_c_ampdu_add_frame(struct brcms_ampdu_session *session, - struct sk_buff *p) -{ - struct brcms_c_info *wlc = session->wlc; - struct ampdu_info *ampdu = wlc->ampdu; - struct scb *scb = &wlc->pri_scb; - struct scb_ampdu *scb_ampdu = &scb->scb_ampdu; - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p); - struct ieee80211_tx_rate *txrate = tx_info->status.rates; - struct d11txh *txh = (struct d11txh *)p->data; - unsigned ampdu_frames; - u8 ndelim, tid; + bool rr = true, fbr = false; + uint i, count = 0, fifo, seg_cnt = 0; + u16 plen, len, seq = 0, mcl, mch, index, frameid, dma_len = 0; + u32 ampdu_len, max_ampdu_bytes = 0; + struct d11txh *txh = NULL; u8 *plcp; - uint len; - u16 mcl; + struct ieee80211_hdr *h; + struct scb *scb; + struct scb_ampdu *scb_ampdu; + struct scb_ampdu_tid_ini *ini; + u8 mcs = 0; + bool use_rts = false, use_cts = false; + u32 rspec = 0, rspec_fallback = 0; + u32 rts_rspec = 0, rts_rspec_fallback = 0; + u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ; + struct ieee80211_rts *rts; + u8 rr_retry_limit; + struct brcms_fifo_info *f; bool fbr_iscck; - bool rr; - - ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM]; - plcp = (u8 *)(txh + 1); - fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x03); - len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) : - BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback); - len = roundup(len, 4) + (ndelim + 1) * AMPDU_DELIMITER_LEN; + struct ieee80211_tx_info *tx_info; + u16 qlen; + struct wiphy *wiphy; - ampdu_frames = skb_queue_len(&session->skb_list); - if (ampdu_frames != 0) { - struct sk_buff *first; + wlc = ampdu->wlc; + wiphy = wlc->wiphy; + p = *pdu; - if (ampdu_frames + 1 > session->max_ampdu_frames || - session->ampdu_len + len > session->max_ampdu_len) - return -ENOSPC; + tid = (u8) (p->priority); - /* - * We aren't really out of space if the new frame is of - * a different priority, but we want the same behaviour - * so return -ENOSPC anyway. - * - * XXX: The old AMPDU code did this, but is it really - * necessary? - */ - first = skb_peek(&session->skb_list); - if (p->priority != first->priority) - return -ENOSPC; - } + f = ampdu->fifo_tb + prio2fifo[tid]; - /* - * Now that we're sure this frame can be accomodated, update the - * session information. - */ - session->ampdu_len += len; - session->dma_len += p->len; + scb = &wlc->pri_scb; + scb_ampdu = &scb->scb_ampdu; + ini = &scb_ampdu->ini[tid]; - tid = (u8)p->priority; + /* Let pressure continue to build ... */ + qlen = pktq_plen(&qi->q, prec); + if (ini->tx_in_transit > 0 && + qlen < min(scb_ampdu->max_pdu, ini->ba_wsize)) + /* Collect multiple MPDU's to be sent in the next AMPDU */ + return -EBUSY; - /* Handle retry limits */ - if (txrate[0].count <= ampdu->rr_retry_limit_tid[tid]) { - txrate[0].count++; - rr = true; - } else { - txrate[1].count++; - rr = false; - } + /* at this point we intend to transmit an AMPDU */ + rr_retry_limit = ampdu->rr_retry_limit_tid[tid]; + ampdu_len = 0; + dma_len = 0; + while (p) { + struct ieee80211_tx_rate *txrate; - if (ampdu_frames == 0) { - u8 plcp0, plcp3, is40, sgi, mcs; - uint fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK; - struct brcms_fifo_info *f = &du->fifo_tb[fifo]; + tx_info = IEEE80211_SKB_CB(p); + txrate = tx_info->status.rates; - if (rr) { - plcp0 = plcp[0]; - plcp3 = plcp[3]; + if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { + err = brcms_c_prep_pdu(wlc, p, &fifo); } else { - plcp0 = txh->FragPLCPFallback[0]; - plcp3 = txh->FragPLCPFallback[3]; + wiphy_err(wiphy, "%s: AMPDU flag is off!\n", __func__); + *pdu = NULL; + err = 0; + break; + } + + if (err) { + if (err == -EBUSY) { + wiphy_err(wiphy, "wl%d: sendampdu: " + "prep_xdu retry; seq 0x%x\n", + wlc->pub->unit, seq); + *pdu = p; + break; + } + /* error in the packet; reject it */ + wiphy_err(wiphy, "wl%d: sendampdu: prep_xdu " + "rejected; seq 0x%x\n", wlc->pub->unit, seq); + *pdu = NULL; + break; } - /* Limit AMPDU size based on MCS */ - is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0; - sgi = plcp3_issgi(plcp3) ? 1 : 0; - mcs = plcp0 & ~MIMO_PLCP_40MHZ; - session->max_ampdu_len = min(scb_ampdu->max_rx_ampdu_bytes, - ampdu->max_txlen[mcs][is40][sgi]); + /* pkt is good to be aggregated */ + txh = (struct d11txh *) p->data; + plcp = (u8 *) (txh + 1); + h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN); + seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT; + index = TX_SEQ_TO_INDEX(seq); - session->max_ampdu_frames = scb_ampdu->max_pdu; - if (mcs_2_rate(mcs, true, false) >= f->dmaxferrate) { - session->max_ampdu_frames = - min_t(u16, f->mcs2ampdu_table[mcs], - session->max_ampdu_frames); + /* check mcl fields and test whether it can be agg'd */ + mcl = le16_to_cpu(txh->MacTxControlLow); + mcl &= ~TXC_AMPDU_MASK; + fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x3); + txh->PreloadSize = 0; /* always default to 0 */ + + /* Handle retry limits */ + if (txrate[0].count <= rr_retry_limit) { + txrate[0].count++; + rr = true; + fbr = false; + } else { + fbr = true; + rr = false; + txrate[1].count++; } - } - /* - * Treat all frames as "middle" frames of AMPDU here. First and - * last frames must be fixed up after all MPDUs have been prepped. - */ - mcl = le16_to_cpu(txh->MacTxControlLow); - mcl &= ~TXC_AMPDU_MASK; - mcl |= (TXC_AMPDU_MIDDLE << TXC_AMPDU_SHIFT); - mcl &= ~(TXC_STARTMSDU | TXC_SENDRTS | TXC_SENDCTS); - txh->MacTxControlLow = cpu_to_le16(mcl); - txh->PreloadSize = 0; /* always default to 0 */ + /* extract the length info */ + len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) + : BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback); - skb_queue_tail(&session->skb_list, p); + /* retrieve null delimiter count */ + ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM]; + seg_cnt += 1; - return 0; -} + BCMMSG(wlc->wiphy, "wl%d: mpdu %d plcp_len %d\n", + wlc->pub->unit, count, len); -void brcms_c_ampdu_finalize(struct brcms_ampdu_session *session) -{ - struct brcms_c_info *wlc = session->wlc; - struct ampdu_info *ampdu = wlc->ampdu; - struct sk_buff *first, *last; - struct d11txh *txh; - struct ieee80211_tx_info *tx_info; - struct ieee80211_tx_rate *txrate; - u8 ndelim; - u8 *plcp; - uint len; - uint fifo; - struct brcms_fifo_info *f; - u16 mcl; - bool fbr; - bool fbr_iscck; - struct ieee80211_rts *rts; - bool use_rts = false, use_cts = false; - u16 dma_len = session->dma_len; - u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ; - u32 rspec = 0, rspec_fallback = 0; - u32 rts_rspec = 0, rts_rspec_fallback = 0; - u8 plcp0, plcp3, is40, sgi, mcs; - u16 mch; - u8 preamble_type = BRCMS_GF_PREAMBLE; - u8 fbr_preamble_type = BRCMS_GF_PREAMBLE; - u8 rts_preamble_type = BRCMS_LONG_PREAMBLE; - u8 rts_fbr_preamble_type = BRCMS_LONG_PREAMBLE; + /* + * aggregateable mpdu. For ucode/hw agg, + * test whether need to break or change the epoch + */ + if (count == 0) { + mcl |= (TXC_AMPDU_FIRST << TXC_AMPDU_SHIFT); + /* refill the bits since might be a retx mpdu */ + mcl |= TXC_STARTMSDU; + rts = (struct ieee80211_rts *)&txh->rts_frame; + + if (ieee80211_is_rts(rts->frame_control)) { + mcl |= TXC_SENDRTS; + use_rts = true; + } + if (ieee80211_is_cts(rts->frame_control)) { + mcl |= TXC_SENDCTS; + use_cts = true; + } + } else { + mcl |= (TXC_AMPDU_MIDDLE << TXC_AMPDU_SHIFT); + mcl &= ~(TXC_STARTMSDU | TXC_SENDRTS | TXC_SENDCTS); + } - if (skb_queue_empty(&session->skb_list)) - return; + len = roundup(len, 4); + ampdu_len += (len + (ndelim + 1) * AMPDU_DELIMITER_LEN); - first = skb_peek(&session->skb_list); - last = skb_peek_tail(&session->skb_list); - - /* Need to fix up last MPDU first to adjust AMPDU length */ - txh = (struct d11txh *)last->data; - fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK; - f = &du->fifo_tb[fifo]; - - mcl = le16_to_cpu(txh->MacTxControlLow); - mcl &= ~TXC_AMPDU_MASK; - mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT); - txh->MacTxControlLow = cpu_to_le16(mcl); - - /* remove the null delimiter after last mpdu */ - ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM]; - txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = 0; - session->ampdu_len -= ndelim * AMPDU_DELIMITER_LEN; - - /* remove the pad len from last mpdu */ - fbr_iscck = ((le16_to_cpu(txh->XtraFrameTypes) & 0x3) == 0); - len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) : - BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback); - session->ampdu_len -= roundup(len, 4) - len; - - /* Now fix up the first MPDU */ - tx_info = IEEE80211_SKB_CB(first); - txrate = tx_info->status.rates; - txh = (struct d11txh *)first->data; - plcp = (u8 *)(txh + 1); - rts = (struct ieee80211_rts *)&txh->rts_frame; - - mcl = le16_to_cpu(txh->MacTxControlLow); - /* If only one MPDU leave it marked as last */ - if (first != last) { - mcl &= ~TXC_AMPDU_MASK; - mcl |= (TXC_AMPDU_FIRST << TXC_AMPDU_SHIFT); - } - mcl |= TXC_STARTMSDU; - if (ieee80211_is_rts(rts->frame_control)) { - mcl |= TXC_SENDRTS; - use_rts = true; - } - if (ieee80211_is_cts(rts->frame_control)) { - mcl |= TXC_SENDCTS; - use_cts = true; - } - txh->MacTxControlLow = cpu_to_le16(mcl); + dma_len += (u16) p->len; - fbr = txrate[1].count > 0; - if (!fbr) { - plcp0 = plcp[0]; - plcp3 = plcp[3]; - } else { - plcp0 = txh->FragPLCPFallback[0]; - plcp3 = txh->FragPLCPFallback[3]; - } - is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0; - sgi = plcp3_issgi(plcp3) ? 1 : 0; - mcs = plcp0 & ~MIMO_PLCP_40MHZ; - - if (is40) { - if (CHSPEC_SB_UPPER(wlc_phy_chanspec_get(wlc->band->pi))) - mimo_ctlchbw = PHY_TXC1_BW_20MHZ_UP; - else - mimo_ctlchbw = PHY_TXC1_BW_20MHZ; - } + BCMMSG(wlc->wiphy, "wl%d: ampdu_len %d" + " seg_cnt %d null delim %d\n", + wlc->pub->unit, ampdu_len, seg_cnt, ndelim); - /* rebuild the rspec and rspec_fallback */ - rspec = RSPEC_MIMORATE; - rspec |= plcp[0] & ~MIMO_PLCP_40MHZ; - if (plcp[0] & MIMO_PLCP_40MHZ) - rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT); + txh->MacTxControlLow = cpu_to_le16(mcl); - fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x03); - if (fbr_iscck) { - rspec_fallback = - cck_rspec(cck_phy2mac_rate(txh->FragPLCPFallback[0])); - } else { - rspec_fallback = RSPEC_MIMORATE; - rspec_fallback |= txh->FragPLCPFallback[0] & ~MIMO_PLCP_40MHZ; - if (txh->FragPLCPFallback[0] & MIMO_PLCP_40MHZ) - rspec_fallback |= PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT; - } + /* this packet is added */ + pkt[count++] = p; - if (use_rts || use_cts) { - rts_rspec = - brcms_c_rspec_to_rts_rspec(wlc, rspec, - false, mimo_ctlchbw); - rts_rspec_fallback = - brcms_c_rspec_to_rts_rspec(wlc, rspec_fallback, - false, mimo_ctlchbw); - } + /* patch the first MPDU */ + if (count == 1) { + u8 plcp0, plcp3, is40, sgi; - BRCMS_SET_MIMO_PLCP_LEN(plcp, session->ampdu_len); - /* mark plcp to indicate ampdu */ - BRCMS_SET_MIMO_PLCP_AMPDU(plcp); + if (rr) { + plcp0 = plcp[0]; + plcp3 = plcp[3]; + } else { + plcp0 = txh->FragPLCPFallback[0]; + plcp3 = txh->FragPLCPFallback[3]; - /* reset the mixed mode header durations */ - if (txh->MModeLen) { - u16 mmodelen = brcms_c_calc_lsig_len(wlc, rspec, - session->ampdu_len); - txh->MModeLen = cpu_to_le16(mmodelen); - preamble_type = BRCMS_MM_PREAMBLE; - } - if (txh->MModeFbrLen) { - u16 mmfbrlen = brcms_c_calc_lsig_len(wlc, rspec_fallback, - session->ampdu_len); - txh->MModeFbrLen = cpu_to_le16(mmfbrlen); - fbr_preamble_type = BRCMS_MM_PREAMBLE; - } + } + is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0; + sgi = plcp3_issgi(plcp3) ? 1 : 0; + mcs = plcp0 & ~MIMO_PLCP_40MHZ; + max_ampdu_bytes = + min(scb_ampdu->max_rx_ampdu_bytes, + ampdu->max_txlen[mcs][is40][sgi]); + + if (is40) + mimo_ctlchbw = + CHSPEC_SB_UPPER(wlc_phy_chanspec_get( + wlc->band->pi)) + ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ; + + /* rebuild the rspec and rspec_fallback */ + rspec = RSPEC_MIMORATE; + rspec |= plcp[0] & ~MIMO_PLCP_40MHZ; + if (plcp[0] & MIMO_PLCP_40MHZ) + rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT); + + if (fbr_iscck) /* CCK */ + rspec_fallback = cck_rspec(cck_phy2mac_rate + (txh->FragPLCPFallback[0])); + else { /* MIMO */ + rspec_fallback = RSPEC_MIMORATE; + rspec_fallback |= + txh->FragPLCPFallback[0] & ~MIMO_PLCP_40MHZ; + if (txh->FragPLCPFallback[0] & MIMO_PLCP_40MHZ) + rspec_fallback |= + (PHY_TXC1_BW_40MHZ << + RSPEC_BW_SHIFT); + } - /* set the preload length */ - if (mcs_2_rate(mcs, true, false) >= f->dmaxferrate) { - dma_len = min(dma_len, f->ampdu_pld_size); - txh->PreloadSize = cpu_to_le16(dma_len); - } else { - txh->PreloadSize = 0; - } + if (use_rts || use_cts) { + rts_rspec = + brcms_c_rspec_to_rts_rspec(wlc, + rspec, false, mimo_ctlchbw); + rts_rspec_fallback = + brcms_c_rspec_to_rts_rspec(wlc, + rspec_fallback, false, mimo_ctlchbw); + } + } + + /* if (first mpdu for host agg) */ + /* test whether to add more */ + if ((mcs_2_rate(mcs, true, false) >= f->dmaxferrate) && + (count == f->mcs2ampdu_table[mcs])) { + BCMMSG(wlc->wiphy, "wl%d: PR 37644: stopping" + " ampdu at %d for mcs %d\n", + wlc->pub->unit, count, mcs); + break; + } + + if (count == scb_ampdu->max_pdu) + break; + + /* + * check to see if the next pkt is + * a candidate for aggregation + */ + p = pktq_ppeek(&qi->q, prec); + if (p) { + tx_info = IEEE80211_SKB_CB(p); + if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && + ((u8) (p->priority) == tid)) { + plen = p->len + AMPDU_MAX_MPDU_OVERHEAD; + plen = max(scb_ampdu->min_len, plen); - mch = le16_to_cpu(txh->MacTxControlHigh); + if ((plen + ampdu_len) > max_ampdu_bytes) { + p = NULL; + continue; + } - /* update RTS dur fields */ - if (use_rts || use_cts) { - u16 durid; - if ((mch & TXC_PREAMBLE_RTS_MAIN_SHORT) == - TXC_PREAMBLE_RTS_MAIN_SHORT) - rts_preamble_type = BRCMS_SHORT_PREAMBLE; + /* + * check if there are enough + * descriptors available + */ + if (*wlc->core->txavail[fifo] <= seg_cnt + 1) { + wiphy_err(wiphy, "%s: No fifo space " + "!!\n", __func__); + p = NULL; + continue; + } + /* next packet fit for aggregation so dequeue */ + p = brcmu_pktq_pdeq(&qi->q, prec); + } else { + p = NULL; + } + } + } /* end while(p) */ - if ((mch & TXC_PREAMBLE_RTS_FB_SHORT) == - TXC_PREAMBLE_RTS_FB_SHORT) - rts_fbr_preamble_type = BRCMS_SHORT_PREAMBLE; + ini->tx_in_transit += count; - durid = brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec, - rspec, rts_preamble_type, - preamble_type, - session->ampdu_len, true); - rts->duration = cpu_to_le16(durid); - durid = brcms_c_compute_rtscts_dur(wlc, use_cts, - rts_rspec_fallback, - rspec_fallback, - rts_fbr_preamble_type, - fbr_preamble_type, - session->ampdu_len, true); - txh->RTSDurFallback = cpu_to_le16(durid); - /* set TxFesTimeNormal */ - txh->TxFesTimeNormal = rts->duration; - /* set fallback rate version of TxFesTimeNormal */ - txh->TxFesTimeFallback = txh->RTSDurFallback; - } + if (count) { + /* patch up the last txh */ + txh = (struct d11txh *) pkt[count - 1]->data; + mcl = le16_to_cpu(txh->MacTxControlLow); + mcl &= ~TXC_AMPDU_MASK; + mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT); + txh->MacTxControlLow = cpu_to_le16(mcl); + + /* remove the null delimiter after last mpdu */ + ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM]; + txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = 0; + ampdu_len -= ndelim * AMPDU_DELIMITER_LEN; + + /* remove the pad len from last mpdu */ + fbr_iscck = ((le16_to_cpu(txh->XtraFrameTypes) & 0x3) == 0); + len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) + : BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback); + ampdu_len -= roundup(len, 4) - len; + + /* patch up the first txh & plcp */ + txh = (struct d11txh *) pkt[0]->data; + plcp = (u8 *) (txh + 1); - /* set flag and plcp for fallback rate */ - if (fbr) { - mch |= TXC_AMPDU_FBR; - txh->MacTxControlHigh = cpu_to_le16(mch); + BRCMS_SET_MIMO_PLCP_LEN(plcp, ampdu_len); + /* mark plcp to indicate ampdu */ BRCMS_SET_MIMO_PLCP_AMPDU(plcp); - BRCMS_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback); - } - brcms_dbg_ht(wlc->hw->d11core, "wl%d: count %d ampdu_len %d\n", - wlc->pub->unit, skb_queue_len(&session->skb_list), - session->ampdu_len); + /* reset the mixed mode header durations */ + if (txh->MModeLen) { + u16 mmodelen = + brcms_c_calc_lsig_len(wlc, rspec, ampdu_len); + txh->MModeLen = cpu_to_le16(mmodelen); + preamble_type = BRCMS_MM_PREAMBLE; + } + if (txh->MModeFbrLen) { + u16 mmfbrlen = + brcms_c_calc_lsig_len(wlc, rspec_fallback, + ampdu_len); + txh->MModeFbrLen = cpu_to_le16(mmfbrlen); + fbr_preamble_type = BRCMS_MM_PREAMBLE; + } + + /* set the preload length */ + if (mcs_2_rate(mcs, true, false) >= f->dmaxferrate) { + dma_len = min(dma_len, f->ampdu_pld_size); + txh->PreloadSize = cpu_to_le16(dma_len); + } else + txh->PreloadSize = 0; + + mch = le16_to_cpu(txh->MacTxControlHigh); + + /* update RTS dur fields */ + if (use_rts || use_cts) { + u16 durid; + rts = (struct ieee80211_rts *)&txh->rts_frame; + if ((mch & TXC_PREAMBLE_RTS_MAIN_SHORT) == + TXC_PREAMBLE_RTS_MAIN_SHORT) + rts_preamble_type = BRCMS_SHORT_PREAMBLE; + + if ((mch & TXC_PREAMBLE_RTS_FB_SHORT) == + TXC_PREAMBLE_RTS_FB_SHORT) + rts_fbr_preamble_type = BRCMS_SHORT_PREAMBLE; + + durid = + brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec, + rspec, rts_preamble_type, + preamble_type, ampdu_len, + true); + rts->duration = cpu_to_le16(durid); + durid = brcms_c_compute_rtscts_dur(wlc, use_cts, + rts_rspec_fallback, + rspec_fallback, + rts_fbr_preamble_type, + fbr_preamble_type, + ampdu_len, true); + txh->RTSDurFallback = cpu_to_le16(durid); + /* set TxFesTimeNormal */ + txh->TxFesTimeNormal = rts->duration; + /* set fallback rate version of TxFesTimeNormal */ + txh->TxFesTimeFallback = txh->RTSDurFallback; + } + + /* set flag and plcp for fallback rate */ + if (fbr) { + mch |= TXC_AMPDU_FBR; + txh->MacTxControlHigh = cpu_to_le16(mch); + BRCMS_SET_MIMO_PLCP_AMPDU(plcp); + BRCMS_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback); + } + + BCMMSG(wlc->wiphy, "wl%d: count %d ampdu_len %d\n", + wlc->pub->unit, count, ampdu_len); + + /* inform rate_sel if it this is a rate probe pkt */ + frameid = le16_to_cpu(txh->TxFrameID); + if (frameid & TXFID_RATE_PROBE_MASK) + wiphy_err(wiphy, "%s: XXX what to do with " + "TXFID_RATE_PROBE_MASK!?\n", __func__); + + for (i = 0; i < count; i++) + brcms_c_txfifo(wlc, fifo, pkt[i], i == (count - 1), + ampdu->txpkt_weight); + + } + /* endif (count) */ + return err; } static void @@ -855,6 +909,7 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, u8 antselid = 0; u8 retry_limit, rr_retry_limit; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p); + struct wiphy *wiphy = wlc->wiphy; #ifdef DEBUG u8 hole[AMPDU_MAX_MPDU]; @@ -900,14 +955,13 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, if (supr_status) { update_rate = false; if (supr_status == TX_STATUS_SUPR_BADCH) { - brcms_err(wlc->hw->d11core, + wiphy_err(wiphy, "%s: Pkt tx suppressed, illegal channel possibly %d\n", __func__, CHSPEC_CHANNEL( wlc->default_bss->chanspec)); } else { if (supr_status != TX_STATUS_SUPR_FRAG) - brcms_err(wlc->hw->d11core, - "%s: supr_status 0x%x\n", + wiphy_err(wiphy, "%s: supr_status 0x%x\n", __func__, supr_status); } /* no need to retry for badch; will fail again */ @@ -923,14 +977,20 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, * if there were underflows, but pre-loading * is not active, notify rate adaptation. */ - if (brcms_c_ffpld_check_txfunfl(wlc, queue) > 0) + if (brcms_c_ffpld_check_txfunfl(wlc, + prio2fifo[tid]) > 0) tx_error = true; } } else if (txs->phyerr) { update_rate = false; - brcms_err(wlc->hw->d11core, - "%s: ampdu tx phy error (0x%x)\n", + wiphy_err(wiphy, "%s: ampdu tx phy error (0x%x)\n", __func__, txs->phyerr); + + if (brcm_msg_level & LOG_ERROR_VAL) { + brcmu_prpkt("txpkt (AMPDU)", p); + brcms_c_print_txdesc((struct d11txh *) p->data); + } + brcms_c_print_txstatus(txs); } } @@ -943,8 +1003,6 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN); seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT; - trace_brcms_txdesc(&wlc->hw->d11core->dev, txh, sizeof(*txh)); - if (tot_mpdu == 0) { mcs = plcp[0] & MIMO_PLCP_MCS_MASK; mimoantsel = le16_to_cpu(txh->ABI_MimoAntSel); @@ -954,10 +1012,10 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, ack_recd = false; if (ba_recd) { bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX); - brcms_dbg_ht(wlc->hw->d11core, - "tid %d seq %d, start_seq %d, bindex %d set %d, index %d\n", - tid, seq, start_seq, bindex, - isset(bitmap, bindex), index); + BCMMSG(wiphy, + "tid %d seq %d, start_seq %d, bindex %d set %d, index %d\n", + tid, seq, start_seq, bindex, + isset(bitmap, bindex), index); /* if acked then clear bit and free packet */ if ((bindex < AMPDU_TX_BA_MAX_WSIZE) && isset(bitmap, bindex)) { @@ -988,16 +1046,14 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, /* either retransmit or send bar if ack not recd */ if (!ack_recd) { if (retry && (ini->txretry[index] < (int)retry_limit)) { - int ret; ini->txretry[index]++; ini->tx_in_transit--; - ret = brcms_c_txfifo(wlc, queue, p); /* - * We shouldn't be out of space in the DMA - * ring here since we're reinserting a frame - * that was just pulled out. + * Use high prededence for retransmit to + * give some punch */ - WARN_ONCE(ret, "queue %d out of txds\n", queue); + brcms_c_txq_enq(wlc, scb, p, + BRCMS_PRIO_TO_HI_PREC(tid)); } else { /* Retry timeout */ ini->tx_in_transit--; @@ -1008,9 +1064,9 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, IEEE80211_TX_STAT_AMPDU_NO_BACK; skb_pull(p, D11_PHY_HDR_LEN); skb_pull(p, D11_TXH_LEN); - brcms_dbg_ht(wlc->hw->d11core, - "BA Timeout, seq %d, in_transit %d\n", - seq, ini->tx_in_transit); + BCMMSG(wiphy, + "BA Timeout, seq %d, in_transit %d\n", + seq, ini->tx_in_transit); ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p); } @@ -1024,9 +1080,12 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED); } + brcms_c_send_q(wlc); /* update rate state */ antselid = brcms_c_antsel_antsel2id(wlc->asi, mimoantsel); + + brcms_c_txfifo_complete(wlc, queue, ampdu->txpkt_weight); } void @@ -1074,8 +1133,6 @@ brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, while (p) { tx_info = IEEE80211_SKB_CB(p); txh = (struct d11txh *) p->data; - trace_brcms_txdesc(&wlc->hw->d11core->dev, txh, - sizeof(*txh)); mcl = le16_to_cpu(txh->MacTxControlLow); brcmu_pkt_buf_free_skb(p); /* break out if last packet of ampdu */ @@ -1085,6 +1142,7 @@ brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED); } + brcms_c_txfifo_complete(wlc, queue, ampdu->txpkt_weight); } } @@ -1123,6 +1181,23 @@ void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu) } } +/* + * callback function that helps flushing ampdu packets from a priority queue + */ +static bool cb_del_ampdu_pkt(struct sk_buff *mpdu, void *arg_a) +{ + struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(mpdu); + struct cb_del_ampdu_pars *ampdu_pars = + (struct cb_del_ampdu_pars *)arg_a; + bool rc; + + rc = tx_info->flags & IEEE80211_TX_CTL_AMPDU ? true : false; + rc = rc && (tx_info->rate_driver_data[0] == NULL || ampdu_pars->sta == NULL || + tx_info->rate_driver_data[0] == ampdu_pars->sta); + rc = rc && ((u8)(mpdu->priority) == ampdu_pars->tid); + return rc; +} + /* * callback function that helps invalidating ampdu packets in a DMA queue */ @@ -1143,5 +1218,15 @@ static void dma_cb_fn_ampdu(void *txi, void *arg_a) void brcms_c_ampdu_flush(struct brcms_c_info *wlc, struct ieee80211_sta *sta, u16 tid) { + struct brcms_txq_info *qi = wlc->pkt_queue; + struct pktq *pq = &qi->q; + int prec; + struct cb_del_ampdu_pars ampdu_pars; + + ampdu_pars.sta = sta; + ampdu_pars.tid = tid; + for (prec = 0; prec < pq->num_prec; prec++) + brcmu_pktq_pflush(pq, prec, true, cb_del_ampdu_pkt, + (void *)&du_pars); brcms_c_inval_dma_pkts(wlc->hw, sta, dma_cb_fn_ampdu); } diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h b/trunk/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h index 73d01e586109..421f4ba7c63c 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h @@ -17,34 +17,11 @@ #ifndef _BRCM_AMPDU_H_ #define _BRCM_AMPDU_H_ -/* - * Data structure representing an in-progress session for accumulating - * frames for AMPDU. - * - * wlc: pointer to common driver data - * skb_list: queue of skb's for AMPDU - * max_ampdu_len: maximum length for this AMPDU - * max_ampdu_frames: maximum number of frames for this AMPDU - * ampdu_len: total number of bytes accumulated for this AMPDU - * dma_len: DMA length of this AMPDU - */ -struct brcms_ampdu_session { - struct brcms_c_info *wlc; - struct sk_buff_head skb_list; - unsigned max_ampdu_len; - u16 max_ampdu_frames; - u16 ampdu_len; - u16 dma_len; -}; - -extern void brcms_c_ampdu_reset_session(struct brcms_ampdu_session *session, - struct brcms_c_info *wlc); -extern int brcms_c_ampdu_add_frame(struct brcms_ampdu_session *session, - struct sk_buff *p); -extern void brcms_c_ampdu_finalize(struct brcms_ampdu_session *session); - extern struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc); extern void brcms_c_ampdu_detach(struct ampdu_info *ampdu); +extern int brcms_c_sendampdu(struct ampdu_info *ampdu, + struct brcms_txq_info *qi, + struct sk_buff **aggp, int prec); extern void brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, struct sk_buff *p, struct tx_status *txs); extern void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc); diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/antsel.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/antsel.c index 54c616919590..55e12c327911 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/antsel.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/antsel.c @@ -21,7 +21,6 @@ #include "main.h" #include "phy_shim.h" #include "antsel.h" -#include "debug.h" #define ANT_SELCFG_AUTO 0x80 /* bit indicates antenna sel AUTO */ #define ANT_SELCFG_MASK 0x33 /* antenna configuration mask */ @@ -138,8 +137,7 @@ struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc) asi->antsel_avail = false; } else { asi->antsel_avail = false; - brcms_err(wlc->hw->d11core, - "antsel_attach: 2o3 " + wiphy_err(wlc->wiphy, "antsel_attach: 2o3 " "board cfg invalid\n"); } diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h b/trunk/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h index 871781e6a713..27dd73eef56d 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h @@ -14,29 +14,22 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM brcmsmac + #if !defined(__TRACE_BRCMSMAC_H) || defined(TRACE_HEADER_MULTI_READ) #define __TRACE_BRCMSMAC_H -#include -#include #include #include "mac80211_if.h" -#ifndef CONFIG_BRCM_TRACING +#ifndef CONFIG_BRCMDBG #undef TRACE_EVENT #define TRACE_EVENT(name, proto, ...) \ static inline void trace_ ## name(proto) {} -#undef DECLARE_EVENT_CLASS -#define DECLARE_EVENT_CLASS(...) -#undef DEFINE_EVENT -#define DEFINE_EVENT(evt_class, name, proto, ...) \ -static inline void trace_ ## name(proto) {} #endif -#undef TRACE_SYSTEM -#define TRACE_SYSTEM brcmsmac - /* * We define a tracepoint, its arguments, its printk format and its * 'fast binary record' layout. @@ -85,165 +78,9 @@ TRACE_EVENT(brcms_dpc, ) ); -TRACE_EVENT(brcms_macintstatus, - TP_PROTO(const struct device *dev, int in_isr, u32 macintstatus, - u32 mask), - TP_ARGS(dev, in_isr, macintstatus, mask), - TP_STRUCT__entry( - __string(dev, dev_name(dev)) - __field(int, in_isr) - __field(u32, macintstatus) - __field(u32, mask) - ), - TP_fast_assign( - __assign_str(dev, dev_name(dev)); - __entry->in_isr = in_isr; - __entry->macintstatus = macintstatus; - __entry->mask = mask; - ), - TP_printk("[%s] in_isr=%d macintstatus=%#x mask=%#x", __get_str(dev), - __entry->in_isr, __entry->macintstatus, __entry->mask) -); - -#undef TRACE_SYSTEM -#define TRACE_SYSTEM brcmsmac_tx - -TRACE_EVENT(brcms_txdesc, - TP_PROTO(const struct device *dev, - void *txh, size_t txh_len), - TP_ARGS(dev, txh, txh_len), - TP_STRUCT__entry( - __string(dev, dev_name(dev)) - __dynamic_array(u8, txh, txh_len) - ), - TP_fast_assign( - __assign_str(dev, dev_name(dev)); - memcpy(__get_dynamic_array(txh), txh, txh_len); - ), - TP_printk("[%s] txdesc", __get_str(dev)) -); - -TRACE_EVENT(brcms_txstatus, - TP_PROTO(const struct device *dev, u16 framelen, u16 frameid, - u16 status, u16 lasttxtime, u16 sequence, u16 phyerr, - u16 ackphyrxsh), - TP_ARGS(dev, framelen, frameid, status, lasttxtime, sequence, phyerr, - ackphyrxsh), - TP_STRUCT__entry( - __string(dev, dev_name(dev)) - __field(u16, framelen) - __field(u16, frameid) - __field(u16, status) - __field(u16, lasttxtime) - __field(u16, sequence) - __field(u16, phyerr) - __field(u16, ackphyrxsh) - ), - TP_fast_assign( - __assign_str(dev, dev_name(dev)); - __entry->framelen = framelen; - __entry->frameid = frameid; - __entry->status = status; - __entry->lasttxtime = lasttxtime; - __entry->sequence = sequence; - __entry->phyerr = phyerr; - __entry->ackphyrxsh = ackphyrxsh; - ), - TP_printk("[%s] FrameId %#04x TxStatus %#04x LastTxTime %#04x " - "Seq %#04x PHYTxStatus %#04x RxAck %#04x", - __get_str(dev), __entry->frameid, __entry->status, - __entry->lasttxtime, __entry->sequence, __entry->phyerr, - __entry->ackphyrxsh) -); - -TRACE_EVENT(brcms_ampdu_session, - TP_PROTO(const struct device *dev, unsigned max_ampdu_len, - u16 max_ampdu_frames, u16 ampdu_len, u16 ampdu_frames, - u16 dma_len), - TP_ARGS(dev, max_ampdu_len, max_ampdu_frames, ampdu_len, ampdu_frames, - dma_len), - TP_STRUCT__entry( - __string(dev, dev_name(dev)) - __field(unsigned, max_ampdu_len) - __field(u16, max_ampdu_frames) - __field(u16, ampdu_len) - __field(u16, ampdu_frames) - __field(u16, dma_len) - ), - TP_fast_assign( - __assign_str(dev, dev_name(dev)); - __entry->max_ampdu_len = max_ampdu_len; - __entry->max_ampdu_frames = max_ampdu_frames; - __entry->ampdu_len = ampdu_len; - __entry->ampdu_frames = ampdu_frames; - __entry->dma_len = dma_len; - ), - TP_printk("[%s] ampdu session max_len=%u max_frames=%u len=%u frames=%u dma_len=%u", - __get_str(dev), __entry->max_ampdu_len, - __entry->max_ampdu_frames, __entry->ampdu_len, - __entry->ampdu_frames, __entry->dma_len) -); - -#undef TRACE_SYSTEM -#define TRACE_SYSTEM brcmsmac_msg - -#define MAX_MSG_LEN 100 - -DECLARE_EVENT_CLASS(brcms_msg_event, - TP_PROTO(struct va_format *vaf), - TP_ARGS(vaf), - TP_STRUCT__entry( - __dynamic_array(char, msg, MAX_MSG_LEN) - ), - TP_fast_assign( - WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), - MAX_MSG_LEN, vaf->fmt, - *vaf->va) >= MAX_MSG_LEN); - ), - TP_printk("%s", __get_str(msg)) -); - -DEFINE_EVENT(brcms_msg_event, brcms_info, - TP_PROTO(struct va_format *vaf), - TP_ARGS(vaf) -); - -DEFINE_EVENT(brcms_msg_event, brcms_warn, - TP_PROTO(struct va_format *vaf), - TP_ARGS(vaf) -); - -DEFINE_EVENT(brcms_msg_event, brcms_err, - TP_PROTO(struct va_format *vaf), - TP_ARGS(vaf) -); - -DEFINE_EVENT(brcms_msg_event, brcms_crit, - TP_PROTO(struct va_format *vaf), - TP_ARGS(vaf) -); - -TRACE_EVENT(brcms_dbg, - TP_PROTO(u32 level, const char *func, struct va_format *vaf), - TP_ARGS(level, func, vaf), - TP_STRUCT__entry( - __field(u32, level) - __string(func, func) - __dynamic_array(char, msg, MAX_MSG_LEN) - ), - TP_fast_assign( - __entry->level = level; - __assign_str(func, func); - WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), - MAX_MSG_LEN, vaf->fmt, - *vaf->va) >= MAX_MSG_LEN); - ), - TP_printk("%s: %s", __get_str(func), __get_str(msg)) -); - #endif /* __TRACE_BRCMSMAC_H */ -#ifdef CONFIG_BRCM_TRACING +#ifdef CONFIG_BRCMDBG #undef TRACE_INCLUDE_PATH #define TRACE_INCLUDE_PATH . @@ -252,4 +89,4 @@ TRACE_EVENT(brcms_dbg, #include -#endif /* CONFIG_BRCM_TRACING */ +#endif /* CONFIG_BRCMDBG */ diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/channel.c index a90b72202ec5..64a48f06d68b 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/channel.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/channel.c @@ -26,7 +26,6 @@ #include "stf.h" #include "channel.h" #include "mac80211_if.h" -#include "debug.h" /* QDB() macro takes a dB value and converts to a quarter dB value */ #define QDB(n) ((n) * BRCMS_TXPWR_DB_FACTOR) @@ -337,6 +336,8 @@ struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc) const char *ccode = sprom->alpha2; int ccode_len = sizeof(sprom->alpha2); + BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); + wlc_cm = kzalloc(sizeof(struct brcms_cm_info), GFP_ATOMIC); if (wlc_cm == NULL) return NULL; @@ -614,8 +615,8 @@ brcms_c_valid_chanspec_ext(struct brcms_cm_info *wlc_cm, u16 chspec) /* check the chanspec */ if (brcms_c_chspec_malformed(chspec)) { - brcms_err(wlc->hw->d11core, "wl%d: malformed chanspec 0x%x\n", - wlc->pub->unit, chspec); + wiphy_err(wlc->wiphy, "wl%d: malformed chanspec 0x%x\n", + wlc->pub->unit, chspec); return false; } @@ -737,8 +738,7 @@ static int brcms_reg_notifier(struct wiphy *wiphy, mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); } else { mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); - brcms_err(wlc->hw->d11core, - "wl%d: %s: no valid channel for \"%s\"\n", + wiphy_err(wlc->wiphy, "wl%d: %s: no valid channel for \"%s\"\n", wlc->pub->unit, __func__, request->alpha2); } diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/debug.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/debug.c deleted file mode 100644 index be84791857cb..000000000000 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/debug.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (c) 2012 Broadcom Corporation - * Copyright (c) 2012 Canonical Ltd. - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include "types.h" -#include "main.h" -#include "debug.h" -#include "brcms_trace_events.h" - -static struct dentry *root_folder; - -void brcms_debugfs_init(void) -{ - root_folder = debugfs_create_dir(KBUILD_MODNAME, NULL); - if (IS_ERR(root_folder)) - root_folder = NULL; -} - -void brcms_debugfs_exit(void) -{ - if (!root_folder) - return; - - debugfs_remove_recursive(root_folder); - root_folder = NULL; -} - -int brcms_debugfs_attach(struct brcms_pub *drvr) -{ - if (!root_folder) - return -ENODEV; - - drvr->dbgfs_dir = debugfs_create_dir( - dev_name(&drvr->wlc->hw->d11core->dev), root_folder); - return PTR_RET(drvr->dbgfs_dir); -} - -void brcms_debugfs_detach(struct brcms_pub *drvr) -{ - if (!IS_ERR_OR_NULL(drvr->dbgfs_dir)) - debugfs_remove_recursive(drvr->dbgfs_dir); -} - -struct dentry *brcms_debugfs_get_devdir(struct brcms_pub *drvr) -{ - return drvr->dbgfs_dir; -} - -static -ssize_t brcms_debugfs_hardware_read(struct file *f, char __user *data, - size_t count, loff_t *ppos) -{ - char buf[128]; - int res; - struct brcms_pub *drvr = f->private_data; - - /* only allow read from start */ - if (*ppos > 0) - return 0; - - res = scnprintf(buf, sizeof(buf), - "board vendor: %x\n" - "board type: %x\n" - "board revision: %x\n" - "board flags: %x\n" - "board flags2: %x\n" - "firmware revision: %x\n", - drvr->wlc->hw->d11core->bus->boardinfo.vendor, - drvr->wlc->hw->d11core->bus->boardinfo.type, - drvr->wlc->hw->boardrev, - drvr->wlc->hw->boardflags, - drvr->wlc->hw->boardflags2, - drvr->wlc->ucode_rev - ); - - return simple_read_from_buffer(data, count, ppos, buf, res); -} - -static const struct file_operations brcms_debugfs_hardware_ops = { - .owner = THIS_MODULE, - .open = simple_open, - .read = brcms_debugfs_hardware_read -}; - -void brcms_debugfs_create_files(struct brcms_pub *drvr) -{ - struct dentry *dentry = drvr->dbgfs_dir; - - if (!IS_ERR_OR_NULL(dentry)) - debugfs_create_file("hardware", S_IRUGO, dentry, - drvr, &brcms_debugfs_hardware_ops); -} - -#define __brcms_fn(fn) \ -void __brcms_ ##fn(struct device *dev, const char *fmt, ...) \ -{ \ - struct va_format vaf = { \ - .fmt = fmt, \ - }; \ - va_list args; \ - \ - va_start(args, fmt); \ - vaf.va = &args; \ - dev_ ##fn(dev, "%pV", &vaf); \ - trace_brcms_ ##fn(&vaf); \ - va_end(args); \ -} - -__brcms_fn(info) -__brcms_fn(warn) -__brcms_fn(err) -__brcms_fn(crit) - -#if defined(CONFIG_BRCMDBG) || defined(CONFIG_BRCM_TRACING) -void __brcms_dbg(struct device *dev, u32 level, const char *func, - const char *fmt, ...) -{ - struct va_format vaf = { - .fmt = fmt, - }; - va_list args; - - va_start(args, fmt); - vaf.va = &args; -#ifdef CONFIG_BRCMDBG - if ((brcm_msg_level & level) && net_ratelimit()) - dev_err(dev, "%s %pV", func, &vaf); -#endif - trace_brcms_dbg(level, func, &vaf); - va_end(args); -} -#endif diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/debug.h b/trunk/drivers/net/wireless/brcm80211/brcmsmac/debug.h deleted file mode 100644 index 796836b0f469..000000000000 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/debug.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2012 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#ifndef _BRCMS_DEBUG_H_ -#define _BRCMS_DEBUG_H_ - -#include -#include -#include -#include -#include "main.h" -#include "mac80211_if.h" - -__printf(2, 3) -void __brcms_info(struct device *dev, const char *fmt, ...); -__printf(2, 3) -void __brcms_warn(struct device *dev, const char *fmt, ...); -__printf(2, 3) -void __brcms_err(struct device *dev, const char *fmt, ...); -__printf(2, 3) -void __brcms_crit(struct device *dev, const char *fmt, ...); - -#if defined(CONFIG_BRCMDBG) || defined(CONFIG_BRCM_TRACING) -__printf(4, 5) -void __brcms_dbg(struct device *dev, u32 level, const char *func, - const char *fmt, ...); -#else -static inline __printf(4, 5) -void __brcms_dbg(struct device *dev, u32 level, const char *func, - const char *fmt, ...) -{ -} -#endif - -/* - * Debug macros cannot be used when wlc is uninitialized. Generally - * this means any code that could run before brcms_c_attach() has - * returned successfully probably shouldn't use the following macros. - */ - -#define brcms_dbg(core, l, f, a...) __brcms_dbg(&(core)->dev, l, __func__, f, ##a) -#define brcms_info(core, f, a...) __brcms_info(&(core)->dev, f, ##a) -#define brcms_warn(core, f, a...) __brcms_warn(&(core)->dev, f, ##a) -#define brcms_err(core, f, a...) __brcms_err(&(core)->dev, f, ##a) -#define brcms_crit(core, f, a...) __brcms_crit(&(core)->dev, f, ##a) - -#define brcms_dbg_info(core, f, a...) brcms_dbg(core, BRCM_DL_INFO, f, ##a) -#define brcms_dbg_mac80211(core, f, a...) brcms_dbg(core, BRCM_DL_MAC80211, f, ##a) -#define brcms_dbg_rx(core, f, a...) brcms_dbg(core, BRCM_DL_RX, f, ##a) -#define brcms_dbg_tx(core, f, a...) brcms_dbg(core, BRCM_DL_TX, f, ##a) -#define brcms_dbg_int(core, f, a...) brcms_dbg(core, BRCM_DL_INT, f, ##a) -#define brcms_dbg_dma(core, f, a...) brcms_dbg(core, BRCM_DL_DMA, f, ##a) -#define brcms_dbg_ht(core, f, a...) brcms_dbg(core, BRCM_DL_HT, f, ##a) - -struct brcms_pub; -void brcms_debugfs_init(void); -void brcms_debugfs_exit(void); -int brcms_debugfs_attach(struct brcms_pub *drvr); -void brcms_debugfs_detach(struct brcms_pub *drvr); -struct dentry *brcms_debugfs_get_devdir(struct brcms_pub *drvr); -void brcms_debugfs_create_files(struct brcms_pub *drvr); - -#endif /* _BRCMS_DEBUG_H_ */ diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/dma.c index 1860c572b3c4..5e53305bd9a9 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/dma.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/dma.c @@ -14,22 +14,17 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include -#include -#include #include #include #include "types.h" -#include "main.h" #include "dma.h" #include "soc.h" -#include "scb.h" -#include "ampdu.h" -#include "debug.h" -#include "brcms_trace_events.h" /* * dma register field offset calculation @@ -181,6 +176,28 @@ #define BCMEXTRAHDROOM 172 +/* debug/trace */ +#ifdef DEBUG +#define DMA_ERROR(fmt, ...) \ +do { \ + if (*di->msg_level & 1) \ + pr_debug("%s: " fmt, __func__, ##__VA_ARGS__); \ +} while (0) +#define DMA_TRACE(fmt, ...) \ +do { \ + if (*di->msg_level & 2) \ + pr_debug("%s: " fmt, __func__, ##__VA_ARGS__); \ +} while (0) +#else +#define DMA_ERROR(fmt, ...) \ + no_printk(fmt, ##__VA_ARGS__) +#define DMA_TRACE(fmt, ...) \ + no_printk(fmt, ##__VA_ARGS__) +#endif /* DEBUG */ + +#define DMA_NONE(fmt, ...) \ + no_printk(fmt, ##__VA_ARGS__) + #define MAXNAMEL 8 /* 8 char names */ /* macros to convert between byte offsets and indexes */ @@ -207,14 +224,12 @@ struct dma64desc { /* dma engine software state */ struct dma_info { struct dma_pub dma; /* exported structure */ + uint *msg_level; /* message level pointer */ char name[MAXNAMEL]; /* callers name for diag msgs */ struct bcma_device *core; struct device *dmadev; - /* session information for AMPDU */ - struct brcms_ampdu_session ampdu_session; - bool dma64; /* this dma engine is operating in 64-bit mode */ bool addrext; /* this dma engine supports DmaExtendedAddrChanges */ @@ -283,6 +298,12 @@ struct dma_info { bool aligndesc_4k; }; +/* + * default dma message level (if input msg_level + * pointer is null in dma_attach()) + */ +static uint dma_msg_level; + /* Check for odd number of 1's */ static u32 parity32(__le32 data) { @@ -332,7 +353,7 @@ static uint prevtxd(struct dma_info *di, uint i) static uint nextrxd(struct dma_info *di, uint i) { - return rxd(di, i + 1); + return txd(di, i + 1); } static uint ntxdactive(struct dma_info *di, uint h, uint t) @@ -349,8 +370,10 @@ static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags) { uint dmactrlflags; - if (di == NULL) + if (di == NULL) { + DMA_ERROR("NULL dma handle\n"); return 0; + } dmactrlflags = di->dma.dmactrlflags; dmactrlflags &= ~mask; @@ -400,15 +423,13 @@ static bool _dma_isaddrext(struct dma_info *di) /* not all tx or rx channel are available */ if (di->d64txregbase != 0) { if (!_dma64_addrext(di, DMA64TXREGOFFS(di, control))) - brcms_dbg_dma(di->core, - "%s: DMA64 tx doesn't have AE set\n", - di->name); + DMA_ERROR("%s: DMA64 tx doesn't have AE set\n", + di->name); return true; } else if (di->d64rxregbase != 0) { if (!_dma64_addrext(di, DMA64RXREGOFFS(di, control))) - brcms_dbg_dma(di->core, - "%s: DMA64 rx doesn't have AE set\n", - di->name); + DMA_ERROR("%s: DMA64 rx doesn't have AE set\n", + di->name); return true; } @@ -509,9 +530,8 @@ static bool dma64_alloc(struct dma_info *di, uint direction) va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits, &alloced, &di->txdpaorig); if (va == NULL) { - brcms_dbg_dma(di->core, - "%s: DMA_ALLOC_CONSISTENT(ntxd) failed\n", - di->name); + DMA_ERROR("%s: DMA_ALLOC_CONSISTENT(ntxd) failed\n", + di->name); return false; } align = (1 << align_bits); @@ -524,9 +544,8 @@ static bool dma64_alloc(struct dma_info *di, uint direction) va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits, &alloced, &di->rxdpaorig); if (va == NULL) { - brcms_dbg_dma(di->core, - "%s: DMA_ALLOC_CONSISTENT(nrxd) failed\n", - di->name); + DMA_ERROR("%s: DMA_ALLOC_CONSISTENT(nrxd) failed\n", + di->name); return false; } align = (1 << align_bits); @@ -545,13 +564,12 @@ static bool _dma_alloc(struct dma_info *di, uint direction) return dma64_alloc(di, direction); } -struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc, +struct dma_pub *dma_attach(char *name, struct si_pub *sih, + struct bcma_device *core, uint txregbase, uint rxregbase, uint ntxd, uint nrxd, uint rxbufsize, int rxextheadroom, - uint nrxpost, uint rxoffset) + uint nrxpost, uint rxoffset, uint *msg_level) { - struct si_pub *sih = wlc->hw->sih; - struct bcma_device *core = wlc->hw->d11core; struct dma_info *di; u8 rev = core->id.rev; uint size; @@ -562,6 +580,9 @@ struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc, if (di == NULL) return NULL; + di->msg_level = msg_level ? msg_level : &dma_msg_level; + + di->dma64 = ((bcma_aread32(core, BCMA_IOST) & SISF_DMA64) == SISF_DMA64); @@ -577,11 +598,11 @@ struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc, */ _dma_ctrlflags(di, DMA_CTRL_ROC | DMA_CTRL_PEN, 0); - brcms_dbg_dma(di->core, "%s: %s flags 0x%x ntxd %d nrxd %d " - "rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d " - "txregbase %u rxregbase %u\n", name, "DMA64", - di->dma.dmactrlflags, ntxd, nrxd, rxbufsize, - rxextheadroom, nrxpost, rxoffset, txregbase, rxregbase); + DMA_TRACE("%s: %s flags 0x%x ntxd %d nrxd %d " + "rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d " + "txregbase %u rxregbase %u\n", name, "DMA64", + di->dma.dmactrlflags, ntxd, nrxd, rxbufsize, + rxextheadroom, nrxpost, rxoffset, txregbase, rxregbase); /* make a private copy of our callers name */ strncpy(di->name, name, MAXNAMEL); @@ -643,8 +664,8 @@ struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc, di->dmadesc_align = 4; /* 16 byte alignment */ } - brcms_dbg_dma(di->core, "DMA descriptor align_needed %d, align %d\n", - di->aligndesc_4k, di->dmadesc_align); + DMA_NONE("DMA descriptor align_needed %d, align %d\n", + di->aligndesc_4k, di->dmadesc_align); /* allocate tx packet pointer vector */ if (ntxd) { @@ -682,27 +703,21 @@ struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc, if ((di->ddoffsetlow != 0) && !di->addrext) { if (di->txdpa > SI_PCI_DMA_SZ) { - brcms_dbg_dma(di->core, - "%s: txdpa 0x%x: addrext not supported\n", - di->name, (u32)di->txdpa); + DMA_ERROR("%s: txdpa 0x%x: addrext not supported\n", + di->name, (u32)di->txdpa); goto fail; } if (di->rxdpa > SI_PCI_DMA_SZ) { - brcms_dbg_dma(di->core, - "%s: rxdpa 0x%x: addrext not supported\n", - di->name, (u32)di->rxdpa); + DMA_ERROR("%s: rxdpa 0x%x: addrext not supported\n", + di->name, (u32)di->rxdpa); goto fail; } } - /* Initialize AMPDU session */ - brcms_c_ampdu_reset_session(&di->ampdu_session, wlc); - - brcms_dbg_dma(di->core, - "ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh 0x%x addrext %d\n", - di->ddoffsetlow, di->ddoffsethigh, - di->dataoffsetlow, di->dataoffsethigh, - di->addrext); + DMA_TRACE("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh 0x%x addrext %d\n", + di->ddoffsetlow, di->ddoffsethigh, + di->dataoffsetlow, di->dataoffsethigh, + di->addrext); return (struct dma_pub *) di; @@ -748,7 +763,7 @@ void dma_detach(struct dma_pub *pub) { struct dma_info *di = (struct dma_info *)pub; - brcms_dbg_dma(di->core, "%s:\n", di->name); + DMA_TRACE("%s:\n", di->name); /* free dma descriptor rings */ if (di->txd64) @@ -824,7 +839,7 @@ static void _dma_rxenable(struct dma_info *di) uint dmactrlflags = di->dma.dmactrlflags; u32 control; - brcms_dbg_dma(di->core, "%s:\n", di->name); + DMA_TRACE("%s:\n", di->name); control = D64_RC_RE | (bcma_read32(di->core, DMA64RXREGOFFS(di, control)) & @@ -844,7 +859,7 @@ void dma_rxinit(struct dma_pub *pub) { struct dma_info *di = (struct dma_info *)pub; - brcms_dbg_dma(di->core, "%s:\n", di->name); + DMA_TRACE("%s:\n", di->name); if (di->nrxd == 0) return; @@ -939,7 +954,7 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list) return 0; len = le16_to_cpu(*(__le16 *) (p->data)); - brcms_dbg_dma(di->core, "%s: dma_rx len %d\n", di->name, len); + DMA_TRACE("%s: dma_rx len %d\n", di->name, len); dma_spin_for_len(len, p); /* set actual length */ @@ -966,15 +981,14 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list) DMA64RXREGOFFS(di, status0)) & D64_RS0_CD_MASK) - di->rcvptrbase) & D64_RS0_CD_MASK, struct dma64desc); - brcms_dbg_dma(di->core, - "rxin %d rxout %d, hw_curr %d\n", - di->rxin, di->rxout, cur); + DMA_ERROR("rxin %d rxout %d, hw_curr %d\n", + di->rxin, di->rxout, cur); } #endif /* DEBUG */ if ((di->dma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) { - brcms_dbg_dma(di->core, "%s: bad frame length (%d)\n", - di->name, len); + DMA_ERROR("%s: bad frame length (%d)\n", + di->name, len); skb_queue_walk_safe(&dma_frames, p, next) { skb_unlink(p, &dma_frames); brcmu_pkt_buf_free_skb(p); @@ -991,7 +1005,7 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list) static bool dma64_rxidle(struct dma_info *di) { - brcms_dbg_dma(di->core, "%s:\n", di->name); + DMA_TRACE("%s:\n", di->name); if (di->nrxd == 0) return true; @@ -1002,17 +1016,6 @@ static bool dma64_rxidle(struct dma_info *di) D64_RS0_CD_MASK)); } -static bool dma64_txidle(struct dma_info *di) -{ - if (di->ntxd == 0) - return true; - - return ((bcma_read32(di->core, - DMA64TXREGOFFS(di, status0)) & D64_XS0_CD_MASK) == - (bcma_read32(di->core, DMA64TXREGOFFS(di, ptr)) & - D64_XS0_CD_MASK)); -} - /* * post receive buffers * return false is refill failed completely and ring is empty this will stall @@ -1044,7 +1047,7 @@ bool dma_rxfill(struct dma_pub *pub) n = di->nrxpost - nrxdactive(di, rxin, rxout); - brcms_dbg_dma(di->core, "%s: post %d\n", di->name, n); + DMA_TRACE("%s: post %d\n", di->name, n); if (di->rxbufsize > BCMEXTRAHDROOM) extra_offset = di->rxextrahdrroom; @@ -1057,11 +1060,9 @@ bool dma_rxfill(struct dma_pub *pub) p = brcmu_pkt_buf_get_skb(di->rxbufsize + extra_offset); if (p == NULL) { - brcms_dbg_dma(di->core, "%s: out of rxbufs\n", - di->name); + DMA_ERROR("%s: out of rxbufs\n", di->name); if (i == 0 && dma64_rxidle(di)) { - brcms_dbg_dma(di->core, "%s: ring is empty !\n", - di->name); + DMA_ERROR("%s: ring is empty !\n", di->name); ring_empty = true; } di->dma.rxnobuf++; @@ -1106,7 +1107,7 @@ void dma_rxreclaim(struct dma_pub *pub) struct dma_info *di = (struct dma_info *)pub; struct sk_buff *p; - brcms_dbg_dma(di->core, "%s:\n", di->name); + DMA_TRACE("%s:\n", di->name); while ((p = _dma_getnextrxp(di, true))) brcmu_pkt_buf_free_skb(p); @@ -1137,7 +1138,7 @@ void dma_txinit(struct dma_pub *pub) struct dma_info *di = (struct dma_info *)pub; u32 control = D64_XC_XE; - brcms_dbg_dma(di->core, "%s:\n", di->name); + DMA_TRACE("%s:\n", di->name); if (di->ntxd == 0) return; @@ -1169,7 +1170,7 @@ void dma_txsuspend(struct dma_pub *pub) { struct dma_info *di = (struct dma_info *)pub; - brcms_dbg_dma(di->core, "%s:\n", di->name); + DMA_TRACE("%s:\n", di->name); if (di->ntxd == 0) return; @@ -1181,7 +1182,7 @@ void dma_txresume(struct dma_pub *pub) { struct dma_info *di = (struct dma_info *)pub; - brcms_dbg_dma(di->core, "%s:\n", di->name); + DMA_TRACE("%s:\n", di->name); if (di->ntxd == 0) return; @@ -1204,11 +1205,11 @@ void dma_txreclaim(struct dma_pub *pub, enum txd_range range) struct dma_info *di = (struct dma_info *)pub; struct sk_buff *p; - brcms_dbg_dma(di->core, "%s: %s\n", - di->name, - range == DMA_RANGE_ALL ? "all" : - range == DMA_RANGE_TRANSMITTED ? "transmitted" : - "transferred"); + DMA_TRACE("%s: %s\n", + di->name, + range == DMA_RANGE_ALL ? "all" : + range == DMA_RANGE_TRANSMITTED ? "transmitted" : + "transferred"); if (di->txin == di->txout) return; @@ -1263,18 +1264,24 @@ bool dma_rxreset(struct dma_pub *pub) return status == D64_RS0_RS_DISABLED; } -static void dma_txenq(struct dma_info *di, struct sk_buff *p) +/* + * !! tx entry routine + * WARNING: call must check the return value for error. + * the error(toss frames) could be fatal and cause many subsequent hard + * to debug problems + */ +int dma_txfast(struct dma_pub *pub, struct sk_buff *p, bool commit) { + struct dma_info *di = (struct dma_info *)pub; unsigned char *data; uint len; u16 txout; u32 flags = 0; dma_addr_t pa; - txout = di->txout; + DMA_TRACE("%s:\n", di->name); - if (WARN_ON(nexttxd(di, txout) == di->txin)) - return; + txout = di->txout; /* * obtain and initialize transmit descriptor entry. @@ -1282,6 +1289,14 @@ static void dma_txenq(struct dma_info *di, struct sk_buff *p) data = p->data; len = p->len; + /* no use to transmit a zero length packet */ + if (len == 0) + return 0; + + /* return nonzero if out of tx descriptors */ + if (nexttxd(di, txout) == di->txin) + goto outoftxd; + /* get physical address of buffer start */ pa = dma_map_single(di->dmadev, data, len, DMA_TO_DEVICE); @@ -1303,147 +1318,23 @@ static void dma_txenq(struct dma_info *di, struct sk_buff *p) /* bump the tx descriptor index */ di->txout = txout; -} - -static void ampdu_finalize(struct dma_info *di) -{ - struct brcms_ampdu_session *session = &di->ampdu_session; - struct sk_buff *p; - - trace_brcms_ampdu_session(&session->wlc->hw->d11core->dev, - session->max_ampdu_len, - session->max_ampdu_frames, - session->ampdu_len, - skb_queue_len(&session->skb_list), - session->dma_len); - - if (WARN_ON(skb_queue_empty(&session->skb_list))) - return; - - brcms_c_ampdu_finalize(session); - - while (!skb_queue_empty(&session->skb_list)) { - p = skb_dequeue(&session->skb_list); - dma_txenq(di, p); - } - - bcma_write32(di->core, DMA64TXREGOFFS(di, ptr), - di->xmtptrbase + I2B(di->txout, struct dma64desc)); - brcms_c_ampdu_reset_session(session, session->wlc); -} - -static void prep_ampdu_frame(struct dma_info *di, struct sk_buff *p) -{ - struct brcms_ampdu_session *session = &di->ampdu_session; - int ret; - - ret = brcms_c_ampdu_add_frame(session, p); - if (ret == -ENOSPC) { - /* - * AMPDU cannot accomodate this frame. Close out the in- - * progress AMPDU session and start a new one. - */ - ampdu_finalize(di); - ret = brcms_c_ampdu_add_frame(session, p); - } - - WARN_ON(ret); -} - -/* Update count of available tx descriptors based on current DMA state */ -static void dma_update_txavail(struct dma_info *di) -{ - /* - * Available space is number of descriptors less the number of - * active descriptors and the number of queued AMPDU frames. - */ - di->dma.txavail = di->ntxd - ntxdactive(di, di->txin, di->txout) - - skb_queue_len(&di->ampdu_session.skb_list) - 1; -} - -/* - * !! tx entry routine - * WARNING: call must check the return value for error. - * the error(toss frames) could be fatal and cause many subsequent hard - * to debug problems - */ -int dma_txfast(struct brcms_c_info *wlc, struct dma_pub *pub, - struct sk_buff *p) -{ - struct dma_info *di = (struct dma_info *)pub; - struct brcms_ampdu_session *session = &di->ampdu_session; - struct ieee80211_tx_info *tx_info; - bool is_ampdu; - - /* no use to transmit a zero length packet */ - if (p->len == 0) - return 0; - - /* return nonzero if out of tx descriptors */ - if (di->dma.txavail == 0 || nexttxd(di, di->txout) == di->txin) - goto outoftxd; - - tx_info = IEEE80211_SKB_CB(p); - is_ampdu = tx_info->flags & IEEE80211_TX_CTL_AMPDU; - if (is_ampdu) - prep_ampdu_frame(di, p); - else - dma_txenq(di, p); - - /* tx flow control */ - dma_update_txavail(di); /* kick the chip */ - if (is_ampdu) { - /* - * Start sending data if we've got a full AMPDU, there's - * no more space in the DMA ring, or the ring isn't - * currently transmitting. - */ - if (skb_queue_len(&session->skb_list) == session->max_ampdu_frames || - di->dma.txavail == 0 || dma64_txidle(di)) - ampdu_finalize(di); - } else { + if (commit) bcma_write32(di->core, DMA64TXREGOFFS(di, ptr), - di->xmtptrbase + I2B(di->txout, struct dma64desc)); - } + di->xmtptrbase + I2B(txout, struct dma64desc)); + + /* tx flow control */ + di->dma.txavail = di->ntxd - ntxdactive(di, di->txin, di->txout) - 1; return 0; outoftxd: - brcms_dbg_dma(di->core, "%s: out of txds !!!\n", di->name); + DMA_ERROR("%s: out of txds !!!\n", di->name); brcmu_pkt_buf_free_skb(p); di->dma.txavail = 0; di->dma.txnobuf++; - return -ENOSPC; -} - -void dma_txflush(struct dma_pub *pub) -{ - struct dma_info *di = (struct dma_info *)pub; - struct brcms_ampdu_session *session = &di->ampdu_session; - - if (!skb_queue_empty(&session->skb_list)) - ampdu_finalize(di); -} - -int dma_txpending(struct dma_pub *pub) -{ - struct dma_info *di = (struct dma_info *)pub; - return ntxdactive(di, di->txin, di->txout); -} - -/* - * If we have an active AMPDU session and are not transmitting, - * this function will force tx to start. - */ -void dma_kick_tx(struct dma_pub *pub) -{ - struct dma_info *di = (struct dma_info *)pub; - struct brcms_ampdu_session *session = &di->ampdu_session; - - if (!skb_queue_empty(&session->skb_list) && dma64_txidle(di)) - ampdu_finalize(di); + return -1; } /* @@ -1463,11 +1354,11 @@ struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range) u16 active_desc; struct sk_buff *txp; - brcms_dbg_dma(di->core, "%s: %s\n", - di->name, - range == DMA_RANGE_ALL ? "all" : - range == DMA_RANGE_TRANSMITTED ? "transmitted" : - "transferred"); + DMA_TRACE("%s: %s\n", + di->name, + range == DMA_RANGE_ALL ? "all" : + range == DMA_RANGE_TRANSMITTED ? "transmitted" : + "transferred"); if (di->ntxd == 0) return NULL; @@ -1521,13 +1412,13 @@ struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range) di->txin = i; /* tx flow control */ - dma_update_txavail(di); + di->dma.txavail = di->ntxd - ntxdactive(di, di->txin, di->txout) - 1; return txp; bogus: - brcms_dbg_dma(di->core, "bogus curr: start %d end %d txout %d\n", - start, end, di->txout); + DMA_NONE("bogus curr: start %d end %d txout %d\n", + start, end, di->txout); return NULL; } diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/dma.h b/trunk/drivers/net/wireless/brcm80211/brcmsmac/dma.h index ff5b80b09046..cc269ee5c499 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/dma.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/dma.h @@ -74,11 +74,12 @@ struct dma_pub { uint txnobuf; /* tx out of dma descriptors */ }; -extern struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc, +extern struct dma_pub *dma_attach(char *name, struct si_pub *sih, + struct bcma_device *d11core, uint txregbase, uint rxregbase, uint ntxd, uint nrxd, uint rxbufsize, int rxextheadroom, - uint nrxpost, uint rxoffset); + uint nrxpost, uint rxoffset, uint *msg_level); void dma_rxinit(struct dma_pub *pub); int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list); @@ -86,11 +87,7 @@ bool dma_rxfill(struct dma_pub *pub); bool dma_rxreset(struct dma_pub *pub); bool dma_txreset(struct dma_pub *pub); void dma_txinit(struct dma_pub *pub); -int dma_txfast(struct brcms_c_info *wlc, struct dma_pub *pub, - struct sk_buff *p0); -void dma_txflush(struct dma_pub *pub); -int dma_txpending(struct dma_pub *pub); -void dma_kick_tx(struct dma_pub *pub); +int dma_txfast(struct dma_pub *pub, struct sk_buff *p0, bool commit); void dma_txsuspend(struct dma_pub *pub); bool dma_txsuspended(struct dma_pub *pub); void dma_txresume(struct dma_pub *pub); diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 85dbaf8ac997..a744ea5a9559 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c @@ -33,7 +33,6 @@ #include "ucode_loader.h" #include "mac80211_if.h" #include "main.h" -#include "debug.h" #define N_TX_QUEUES 4 /* #tx queues on mac80211<->driver interface */ @@ -99,14 +98,10 @@ static struct bcma_device_id brcms_coreid_table[] = { }; MODULE_DEVICE_TABLE(bcma, brcms_coreid_table); -#if defined(CONFIG_BRCMDBG) -/* - * Module parameter for setting the debug message level. Available - * flags are specified by the BRCM_DL_* macros in - * drivers/net/wireless/brcm80211/include/defs.h. - */ -module_param_named(debug, brcm_msg_level, uint, S_IRUGO | S_IWUSR); -#endif +#ifdef DEBUG +static int msglevel = 0xdeadbeef; +module_param(msglevel, int, 0); +#endif /* DEBUG */ static struct ieee80211_channel brcms_2ghz_chantable[] = { CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS), @@ -281,12 +276,12 @@ static void brcms_ops_tx(struct ieee80211_hw *hw, spin_lock_bh(&wl->lock); if (!wl->pub->up) { - brcms_err(wl->wlc->hw->d11core, "ops->tx called while down\n"); + wiphy_err(wl->wiphy, "ops->tx called while down\n"); kfree_skb(skb); goto done; } - if (brcms_c_sendpkt_mac80211(wl->wlc, skb, hw)) - tx_info->rate_driver_data[0] = control->sta; + brcms_c_sendpkt_mac80211(wl->wlc, skb, hw); + tx_info->rate_driver_data[0] = control->sta; done: spin_unlock_bh(&wl->lock); } @@ -318,8 +313,8 @@ static int brcms_ops_start(struct ieee80211_hw *hw) spin_unlock_bh(&wl->lock); if (err != 0) - brcms_err(wl->wlc->hw->d11core, "%s: brcms_up() returned %d\n", - __func__, err); + wiphy_err(hw->wiphy, "%s: brcms_up() returned %d\n", __func__, + err); return err; } @@ -337,7 +332,7 @@ static void brcms_ops_stop(struct ieee80211_hw *hw) status = brcms_c_chipmatch(wl->wlc->hw->d11core); spin_unlock_bh(&wl->lock); if (!status) { - brcms_err(wl->wlc->hw->d11core, + wiphy_err(wl->wiphy, "wl: brcms_ops_stop: chipmatch failed\n"); return; } @@ -355,9 +350,8 @@ brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) /* Just STA for now */ if (vif->type != NL80211_IFTYPE_STATION) { - brcms_err(wl->wlc->hw->d11core, - "%s: Attempt to add type %d, only STA for now\n", - __func__, vif->type); + wiphy_err(hw->wiphy, "%s: Attempt to add type %d, only" + " STA for now\n", __func__, vif->type); return -EOPNOTSUPP; } @@ -376,9 +370,9 @@ static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed) { struct ieee80211_conf *conf = &hw->conf; struct brcms_info *wl = hw->priv; - struct bcma_device *core = wl->wlc->hw->d11core; int err = 0; int new_int; + struct wiphy *wiphy = hw->wiphy; spin_lock_bh(&wl->lock); if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { @@ -386,26 +380,25 @@ static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed) conf->listen_interval); } if (changed & IEEE80211_CONF_CHANGE_MONITOR) - brcms_dbg_info(core, "%s: change monitor mode: %s\n", - __func__, conf->flags & IEEE80211_CONF_MONITOR ? - "true" : "false"); + wiphy_dbg(wiphy, "%s: change monitor mode: %s\n", + __func__, conf->flags & IEEE80211_CONF_MONITOR ? + "true" : "false"); if (changed & IEEE80211_CONF_CHANGE_PS) - brcms_err(core, "%s: change power-save mode: %s (implement)\n", + wiphy_err(wiphy, "%s: change power-save mode: %s (implement)\n", __func__, conf->flags & IEEE80211_CONF_PS ? "true" : "false"); if (changed & IEEE80211_CONF_CHANGE_POWER) { err = brcms_c_set_tx_power(wl->wlc, conf->power_level); if (err < 0) { - brcms_err(core, "%s: Error setting power_level\n", + wiphy_err(wiphy, "%s: Error setting power_level\n", __func__); goto config_out; } new_int = brcms_c_get_tx_power(wl->wlc); if (new_int != conf->power_level) - brcms_err(core, - "%s: Power level req != actual, %d %d\n", - __func__, conf->power_level, + wiphy_err(wiphy, "%s: Power level req != actual, %d %d" + "\n", __func__, conf->power_level, new_int); } if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { @@ -432,13 +425,13 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_bss_conf *info, u32 changed) { struct brcms_info *wl = hw->priv; - struct bcma_device *core = wl->wlc->hw->d11core; + struct wiphy *wiphy = hw->wiphy; if (changed & BSS_CHANGED_ASSOC) { /* association status changed (associated/disassociated) * also implies a change in the AID. */ - brcms_err(core, "%s: %s: %sassociated\n", KBUILD_MODNAME, + wiphy_err(wiphy, "%s: %s: %sassociated\n", KBUILD_MODNAME, __func__, info->assoc ? "" : "dis"); spin_lock_bh(&wl->lock); brcms_c_associate_upd(wl->wlc, info->assoc); @@ -498,7 +491,7 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw, error = brcms_c_set_rateset(wl->wlc, &rs); spin_unlock_bh(&wl->lock); if (error) - brcms_err(core, "changing basic rates failed: %d\n", + wiphy_err(wiphy, "changing basic rates failed: %d\n", error); } if (changed & BSS_CHANGED_BEACON_INT) { @@ -515,30 +508,30 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_BEACON) /* Beacon data changed, retrieve new beacon (beaconing modes) */ - brcms_err(core, "%s: beacon changed\n", __func__); + wiphy_err(wiphy, "%s: beacon changed\n", __func__); if (changed & BSS_CHANGED_BEACON_ENABLED) { /* Beaconing should be enabled/disabled (beaconing modes) */ - brcms_err(core, "%s: Beacon enabled: %s\n", __func__, + wiphy_err(wiphy, "%s: Beacon enabled: %s\n", __func__, info->enable_beacon ? "true" : "false"); } if (changed & BSS_CHANGED_CQM) { /* Connection quality monitor config changed */ - brcms_err(core, "%s: cqm change: threshold %d, hys %d " + wiphy_err(wiphy, "%s: cqm change: threshold %d, hys %d " " (implement)\n", __func__, info->cqm_rssi_thold, info->cqm_rssi_hyst); } if (changed & BSS_CHANGED_IBSS) { /* IBSS join status changed */ - brcms_err(core, "%s: IBSS joined: %s (implement)\n", - __func__, info->ibss_joined ? "true" : "false"); + wiphy_err(wiphy, "%s: IBSS joined: %s (implement)\n", __func__, + info->ibss_joined ? "true" : "false"); } if (changed & BSS_CHANGED_ARP_FILTER) { /* Hardware ARP filter address list or state changed */ - brcms_err(core, "%s: arp filtering: enabled %s, count %d" + wiphy_err(wiphy, "%s: arp filtering: enabled %s, count %d" " (implement)\n", __func__, info->arp_filter_enabled ? "true" : "false", info->arp_addr_cnt); } @@ -548,8 +541,8 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw, * QoS for this association was enabled/disabled. * Note that it is only ever disabled for station mode. */ - brcms_err(core, "%s: qos enabled: %s (implement)\n", - __func__, info->qos ? "true" : "false"); + wiphy_err(wiphy, "%s: qos enabled: %s (implement)\n", __func__, + info->qos ? "true" : "false"); } return; } @@ -560,25 +553,25 @@ brcms_ops_configure_filter(struct ieee80211_hw *hw, unsigned int *total_flags, u64 multicast) { struct brcms_info *wl = hw->priv; - struct bcma_device *core = wl->wlc->hw->d11core; + struct wiphy *wiphy = hw->wiphy; changed_flags &= MAC_FILTERS; *total_flags &= MAC_FILTERS; if (changed_flags & FIF_PROMISC_IN_BSS) - brcms_dbg_info(core, "FIF_PROMISC_IN_BSS\n"); + wiphy_dbg(wiphy, "FIF_PROMISC_IN_BSS\n"); if (changed_flags & FIF_ALLMULTI) - brcms_dbg_info(core, "FIF_ALLMULTI\n"); + wiphy_dbg(wiphy, "FIF_ALLMULTI\n"); if (changed_flags & FIF_FCSFAIL) - brcms_dbg_info(core, "FIF_FCSFAIL\n"); + wiphy_dbg(wiphy, "FIF_FCSFAIL\n"); if (changed_flags & FIF_CONTROL) - brcms_dbg_info(core, "FIF_CONTROL\n"); + wiphy_dbg(wiphy, "FIF_CONTROL\n"); if (changed_flags & FIF_OTHER_BSS) - brcms_dbg_info(core, "FIF_OTHER_BSS\n"); + wiphy_dbg(wiphy, "FIF_OTHER_BSS\n"); if (changed_flags & FIF_PSPOLL) - brcms_dbg_info(core, "FIF_PSPOLL\n"); + wiphy_dbg(wiphy, "FIF_PSPOLL\n"); if (changed_flags & FIF_BCN_PRBRESP_PROMISC) - brcms_dbg_info(core, "FIF_BCN_PRBRESP_PROMISC\n"); + wiphy_dbg(wiphy, "FIF_BCN_PRBRESP_PROMISC\n"); spin_lock_bh(&wl->lock); brcms_c_mac_promisc(wl->wlc, *total_flags); @@ -660,8 +653,8 @@ brcms_ops_ampdu_action(struct ieee80211_hw *hw, status = brcms_c_aggregatable(wl->wlc, tid); spin_unlock_bh(&wl->lock); if (!status) { - brcms_err(wl->wlc->hw->d11core, - "START: tid %d is not agg\'able\n", tid); + wiphy_err(wl->wiphy, "START: tid %d is not agg\'able\n", + tid); return -EINVAL; } ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); @@ -688,8 +681,8 @@ brcms_ops_ampdu_action(struct ieee80211_hw *hw, /* Power save wakeup */ break; default: - brcms_err(wl->wlc->hw->d11core, - "%s: Invalid command, ignoring\n", __func__); + wiphy_err(wl->wiphy, "%s: Invalid command, ignoring\n", + __func__); } return 0; @@ -846,10 +839,8 @@ static void brcms_free(struct brcms_info *wl) /* kill dpc */ tasklet_kill(&wl->tasklet); - if (wl->pub) { - brcms_debugfs_detach(wl->pub); + if (wl->pub) brcms_c_module_unregister(wl->pub, "linux", wl); - } /* free common resources */ if (wl->wlc) { @@ -898,22 +889,27 @@ static void brcms_remove(struct bcma_device *pdev) static irqreturn_t brcms_isr(int irq, void *dev_id) { struct brcms_info *wl; - irqreturn_t ret = IRQ_NONE; + bool ours, wantdpc; wl = (struct brcms_info *) dev_id; spin_lock(&wl->isr_lock); /* call common first level interrupt handler */ - if (brcms_c_isr(wl->wlc)) { - /* schedule second level handler */ - tasklet_schedule(&wl->tasklet); - ret = IRQ_HANDLED; + ours = brcms_c_isr(wl->wlc, &wantdpc); + if (ours) { + /* if more to do... */ + if (wantdpc) { + + /* ...and call the second level interrupt handler */ + /* schedule dpc */ + tasklet_schedule(&wl->tasklet); + } } spin_unlock(&wl->isr_lock); - return ret; + return IRQ_RETVAL(ours); } /* @@ -1079,8 +1075,6 @@ static struct brcms_info *brcms_attach(struct bcma_device *pdev) regulatory_hint(wl->wiphy, wl->pub->srom_ccode)) wiphy_err(wl->wiphy, "%s: regulatory hint failed\n", __func__); - brcms_debugfs_attach(wl->pub); - brcms_debugfs_create_files(wl->pub); n_adapters_found++; return wl; @@ -1150,13 +1144,14 @@ static int brcms_suspend(struct bcma_device *pdev) wl->pub->hw_up = false; spin_unlock_bh(&wl->lock); - brcms_dbg_info(wl->wlc->hw->d11core, "brcms_suspend ok\n"); + pr_debug("brcms_suspend ok\n"); return 0; } static int brcms_resume(struct bcma_device *pdev) { + pr_debug("brcms_resume ok\n"); return 0; } @@ -1189,7 +1184,10 @@ static DECLARE_WORK(brcms_driver_work, brcms_driver_init); static int __init brcms_module_init(void) { - brcms_debugfs_init(); +#ifdef DEBUG + if (msglevel != 0xdeadbeef) + brcm_msg_level = msglevel; +#endif if (!schedule_work(&brcms_driver_work)) return -EBUSY; @@ -1207,7 +1205,6 @@ static void __exit brcms_module_exit(void) { cancel_work_sync(&brcms_driver_work); bcma_driver_unregister(&brcms_bcma_driver); - brcms_debugfs_exit(); } module_init(brcms_module_init); @@ -1219,7 +1216,7 @@ module_exit(brcms_module_exit); void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif, bool state, int prio) { - brcms_err(wl->wlc->hw->d11core, "Shouldn't be here %s\n", __func__); + wiphy_err(wl->wiphy, "Shouldn't be here %s\n", __func__); } /* @@ -1227,8 +1224,7 @@ void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif, */ void brcms_init(struct brcms_info *wl) { - brcms_dbg_info(wl->wlc->hw->d11core, "Initializing wl%d\n", - wl->pub->unit); + BCMMSG(wl->pub->ieee_hw->wiphy, "wl%d\n", wl->pub->unit); brcms_reset(wl); brcms_c_init(wl->wlc, wl->mute_tx); } @@ -1238,7 +1234,7 @@ void brcms_init(struct brcms_info *wl) */ uint brcms_reset(struct brcms_info *wl) { - brcms_dbg_info(wl->wlc->hw->d11core, "Resetting wl%d\n", wl->pub->unit); + BCMMSG(wl->pub->ieee_hw->wiphy, "wl%d\n", wl->pub->unit); brcms_c_reset(wl->wlc); /* dpc will not be rescheduled */ @@ -1252,7 +1248,7 @@ uint brcms_reset(struct brcms_info *wl) void brcms_fatal_error(struct brcms_info *wl) { - brcms_err(wl->wlc->hw->d11core, "wl%d: fatal error, reinitializing\n", + wiphy_err(wl->wlc->wiphy, "wl%d: fatal error, reinitializing\n", wl->wlc->pub->unit); brcms_reset(wl); ieee80211_restart_hw(wl->pub->ieee_hw); @@ -1400,9 +1396,8 @@ void brcms_add_timer(struct brcms_timer *t, uint ms, int periodic) #ifdef DEBUG if (t->set) - brcms_dbg_info(t->wl->wlc->hw->d11core, - "%s: Already set. Name: %s, per %d\n", - __func__, t->name, periodic); + wiphy_err(hw->wiphy, "%s: Already set. Name: %s, per %d\n", + __func__, t->name, periodic); #endif t->ms = ms; t->periodic = (bool) periodic; @@ -1491,8 +1486,8 @@ int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, u32 idx) } } } - brcms_err(wl->wlc->hw->d11core, - "ERROR: ucode buf tag:%d can not be found!\n", idx); + wiphy_err(wl->wiphy, "ERROR: ucode buf tag:%d can not be found!\n", + idx); *pbuf = NULL; fail: return -ENODATA; @@ -1515,7 +1510,7 @@ int brcms_ucode_init_uint(struct brcms_info *wl, size_t *n_bytes, u32 idx) pdata = wl->fw.fw_bin[i]->data + le32_to_cpu(hdr->offset); if (le32_to_cpu(hdr->len) != 4) { - brcms_err(wl->wlc->hw->d11core, + wiphy_err(wl->wiphy, "ERROR: fw hdr len\n"); return -ENOMSG; } @@ -1524,8 +1519,7 @@ int brcms_ucode_init_uint(struct brcms_info *wl, size_t *n_bytes, u32 idx) } } } - brcms_err(wl->wlc->hw->d11core, - "ERROR: ucode tag:%d can not be found!\n", idx); + wiphy_err(wl->wiphy, "ERROR: ucode tag:%d can not be found!\n", idx); return -ENOMSG; } @@ -1566,8 +1560,8 @@ int brcms_check_firmwares(struct brcms_info *wl) sizeof(struct firmware_hdr)); rc = -EBADF; } else if (fw->size < MIN_FW_SIZE || fw->size > MAX_FW_SIZE) { - wiphy_err(wl->wiphy, "%s: out of bounds fw file size %zu\n", - __func__, fw->size); + wiphy_err(wl->wiphy, "%s: out of bounds fw file size " + "%zu\n", __func__, fw->size); rc = -EBADF; } else { /* check if ucode section overruns firmware image */ diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c index 8fce68751e47..02363f8afd77 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -34,9 +34,12 @@ #include "ucode_loader.h" #include "main.h" #include "soc.h" -#include "dma.h" -#include "debug.h" -#include "brcms_trace_events.h" + +/* + * Indication for txflowcontrol that all priority bits in + * TXQ_STOP_FOR_PRIOFC_MASK are to be considered. + */ +#define ALLPRIO -1 /* watchdog timer, in unit of ms */ #define TIMER_INTERVAL_WATCHDOG 1000 @@ -123,6 +126,21 @@ #define BRCMS_TEMPSENSE_PERIOD 10 /* 10 second timeout */ +/* precedences numbers for wlc queues. These are twice as may levels as + * 802.1D priorities. + * Odd numbers are used for HI priority traffic at same precedence levels + * These constants are used ONLY by wlc_prio2prec_map. Do not use them + * elsewhere. + */ +#define _BRCMS_PREC_NONE 0 /* None = - */ +#define _BRCMS_PREC_BK 2 /* BK - Background */ +#define _BRCMS_PREC_BE 4 /* BE - Best-effort */ +#define _BRCMS_PREC_EE 6 /* EE - Excellent-effort */ +#define _BRCMS_PREC_CL 8 /* CL - Controlled Load */ +#define _BRCMS_PREC_VI 10 /* Vi - Video */ +#define _BRCMS_PREC_VO 12 /* Vo - Voice */ +#define _BRCMS_PREC_NC 14 /* NC - Network Control */ + /* synthpu_dly times in us */ #define SYNTHPU_DLY_APHY_US 3700 #define SYNTHPU_DLY_BPHY_US 1050 @@ -219,17 +237,17 @@ #define MAX_DMA_SEGS 4 -/* # of entries in Tx FIFO */ -#define NTXD 64 +/* Max # of entries in Tx FIFO based on 4kb page size */ +#define NTXD 256 /* Max # of entries in Rx FIFO based on 4kb page size */ #define NRXD 256 -/* Amount of headroom to leave in Tx FIFO */ -#define TX_HEADROOM 4 - /* try to keep this # rbufs posted to the chip */ #define NRXBUFPOST 32 +/* data msg txq hiwat mark */ +#define BRCMS_DATAHIWAT 50 + /* max # frames to process in brcms_c_recv() */ #define RXBND 8 /* max # tx status to process in wlc_txstatus() */ @@ -265,8 +283,24 @@ struct edcf_acparam { u16 TXOP; } __packed; +const u8 prio2fifo[NUMPRIO] = { + TX_AC_BE_FIFO, /* 0 BE AC_BE Best Effort */ + TX_AC_BK_FIFO, /* 1 BK AC_BK Background */ + TX_AC_BK_FIFO, /* 2 -- AC_BK Background */ + TX_AC_BE_FIFO, /* 3 EE AC_BE Best Effort */ + TX_AC_VI_FIFO, /* 4 CL AC_VI Video */ + TX_AC_VI_FIFO, /* 5 VI AC_VI Video */ + TX_AC_VO_FIFO, /* 6 VO AC_VO Voice */ + TX_AC_VO_FIFO /* 7 NC AC_VO Voice */ +}; + /* debug/trace */ -uint brcm_msg_level; +uint brcm_msg_level = +#if defined(DEBUG) + LOG_ERROR_VAL; +#else + 0; +#endif /* DEBUG */ /* TX FIFO number to WME/802.1E Access Category */ static const u8 wme_fifo2ac[] = { @@ -286,6 +320,18 @@ static const u8 wme_ac2fifo[] = { TX_AC_BK_FIFO }; +/* 802.1D Priority to precedence queue mapping */ +const u8 wlc_prio2prec_map[] = { + _BRCMS_PREC_BE, /* 0 BE - Best-effort */ + _BRCMS_PREC_BK, /* 1 BK - Background */ + _BRCMS_PREC_NONE, /* 2 None = - */ + _BRCMS_PREC_EE, /* 3 EE - Excellent-effort */ + _BRCMS_PREC_CL, /* 4 CL - Controlled Load */ + _BRCMS_PREC_VI, /* 5 Vi - Video */ + _BRCMS_PREC_VO, /* 6 Vo - Voice */ + _BRCMS_PREC_NC, /* 7 NC - Network Control */ +}; + static const u16 xmtfifo_sz[][NFIFO] = { /* corerev 17: 5120, 49152, 49152, 5376, 4352, 1280 */ {20, 192, 192, 21, 17, 5}, @@ -325,36 +371,6 @@ static const char fifo_names[6][0]; static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL); #endif -/* Mapping of ieee80211 AC numbers to tx fifos */ -static const u8 ac_to_fifo_mapping[IEEE80211_NUM_ACS] = { - [IEEE80211_AC_VO] = TX_AC_VO_FIFO, - [IEEE80211_AC_VI] = TX_AC_VI_FIFO, - [IEEE80211_AC_BE] = TX_AC_BE_FIFO, - [IEEE80211_AC_BK] = TX_AC_BK_FIFO, -}; - -/* Mapping of tx fifos to ieee80211 AC numbers */ -static const u8 fifo_to_ac_mapping[IEEE80211_NUM_ACS] = { - [TX_AC_BK_FIFO] = IEEE80211_AC_BK, - [TX_AC_BE_FIFO] = IEEE80211_AC_BE, - [TX_AC_VI_FIFO] = IEEE80211_AC_VI, - [TX_AC_VO_FIFO] = IEEE80211_AC_VO, -}; - -static u8 brcms_ac_to_fifo(u8 ac) -{ - if (ac >= ARRAY_SIZE(ac_to_fifo_mapping)) - return TX_AC_BE_FIFO; - return ac_to_fifo_mapping[ac]; -} - -static u8 brcms_fifo_to_ac(u8 fifo) -{ - if (fifo >= ARRAY_SIZE(fifo_to_ac_mapping)) - return IEEE80211_AC_BE; - return fifo_to_ac_mapping[fifo]; -} - /* Find basic rate for a given rate */ static u8 brcms_basic_rate(struct brcms_c_info *wlc, u32 rspec) { @@ -399,15 +415,10 @@ static bool brcms_deviceremoved(struct brcms_c_info *wlc) } /* sum the individual fifo tx pending packet counts */ -static int brcms_txpktpendtot(struct brcms_c_info *wlc) +static s16 brcms_txpktpendtot(struct brcms_c_info *wlc) { - int i; - int pending = 0; - - for (i = 0; i < ARRAY_SIZE(wlc->hw->di); i++) - if (wlc->hw->di[i]) - pending += dma_txpending(wlc->hw->di[i]); - return pending; + return wlc->core->txpktpend[0] + wlc->core->txpktpend[1] + + wlc->core->txpktpend[2] + wlc->core->txpktpend[3]; } static bool brcms_is_mband_unlocked(struct brcms_c_info *wlc) @@ -615,11 +626,14 @@ static uint brcms_c_calc_frame_time(struct brcms_c_info *wlc, u32 ratespec, uint rate = rspec2rate(ratespec); if (rate == 0) { - brcms_err(wlc->hw->d11core, "wl%d: WAR: using rate of 1 mbps\n", + wiphy_err(wlc->wiphy, "wl%d: WAR: using rate of 1 mbps\n", wlc->pub->unit); rate = BRCM_RATE_1M; } + BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, len%d\n", + wlc->pub->unit, ratespec, preamble_type, mac_len); + if (is_mcs_rate(ratespec)) { uint mcs = ratespec & RSPEC_RATE_MASK; int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec); @@ -682,7 +696,7 @@ static void brcms_c_write_inits(struct brcms_hardware *wlc_hw, u16 size; u32 value; - brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); for (i = 0; inits[i].addr != cpu_to_le16(0xffff); i++) { size = le16_to_cpu(inits[i].size); @@ -711,6 +725,7 @@ static void brcms_c_write_mhf(struct brcms_hardware *wlc_hw, u16 *mhfs) static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw) { + struct wiphy *wiphy = wlc_hw->wlc->wiphy; struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode; /* init microcode host flags */ @@ -721,9 +736,8 @@ static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw) if (BRCMS_ISNPHY(wlc_hw->band)) brcms_c_write_inits(wlc_hw, ucode->d11n0bsinitvals16); else - brcms_err(wlc_hw->d11core, - "%s: wl%d: unsupported phy in corerev %d\n", - __func__, wlc_hw->unit, + wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev" + " %d\n", __func__, wlc_hw->unit, wlc_hw->corerev); } else { if (D11REV_IS(wlc_hw->corerev, 24)) { @@ -731,14 +745,12 @@ static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw) brcms_c_write_inits(wlc_hw, ucode->d11lcn0bsinitvals24); else - brcms_err(wlc_hw->d11core, - "%s: wl%d: unsupported phy in core rev %d\n", - __func__, wlc_hw->unit, - wlc_hw->corerev); + wiphy_err(wiphy, "%s: wl%d: unsupported phy in" + " core rev %d\n", __func__, + wlc_hw->unit, wlc_hw->corerev); } else { - brcms_err(wlc_hw->d11core, - "%s: wl%d: unsupported corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev); + wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); } } } @@ -753,7 +765,7 @@ static void brcms_b_core_ioctl(struct brcms_hardware *wlc_hw, u32 m, u32 v) static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk) { - brcms_dbg_info(wlc_hw->d11core, "wl%d: clk %d\n", wlc_hw->unit, clk); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d: clk %d\n", wlc_hw->unit, clk); wlc_hw->phyclk = clk; @@ -778,8 +790,8 @@ static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk) /* low-level band switch utility routine */ static void brcms_c_setxband(struct brcms_hardware *wlc_hw, uint bandunit) { - brcms_dbg_mac80211(wlc_hw->d11core, "wl%d: bandunit %d\n", wlc_hw->unit, - bandunit); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, + bandunit); wlc_hw->band = wlc_hw->bandstate[bandunit]; @@ -807,7 +819,7 @@ static u32 brcms_c_setband_inact(struct brcms_c_info *wlc, uint bandunit) u32 macintmask; u32 macctrl; - brcms_dbg_mac80211(wlc_hw->d11core, "wl%d\n", wlc_hw->unit); + BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); macctrl = bcma_read32(wlc_hw->d11core, D11REGOFFS(maccontrol)); WARN_ON((macctrl & MCTL_EN_MAC) != 0); @@ -829,10 +841,9 @@ static u32 brcms_c_setband_inact(struct brcms_c_info *wlc, uint bandunit) static bool brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) { - struct sk_buff *p = NULL; - uint queue = NFIFO; - struct dma_pub *dma = NULL; - struct d11txh *txh = NULL; + struct sk_buff *p; + uint queue; + struct d11txh *txh; struct scb *scb = NULL; bool free_pdu; int tx_rts, tx_frame_count, tx_rts_count; @@ -843,11 +854,6 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) struct ieee80211_tx_info *tx_info; struct ieee80211_tx_rate *txrate; int i; - bool fatal = true; - - trace_brcms_txstatus(&wlc->hw->d11core->dev, txs->framelen, - txs->frameid, txs->status, txs->lasttxtime, - txs->sequence, txs->phyerr, txs->ackphyrxsh); /* discard intermediate indications for ucode with one legitimate case: * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, @@ -856,36 +862,34 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) */ if (!(txs->status & TX_STATUS_AMPDU) && (txs->status & TX_STATUS_INTERMEDIATE)) { - brcms_dbg_tx(wlc->hw->d11core, "INTERMEDIATE but not AMPDU\n"); - fatal = false; - goto out; + BCMMSG(wlc->wiphy, "INTERMEDIATE but not AMPDU\n"); + return false; } queue = txs->frameid & TXFID_QUEUE_MASK; if (queue >= NFIFO) { - brcms_err(wlc->hw->d11core, "queue %u >= NFIFO\n", queue); - goto out; + p = NULL; + goto fatal; } - dma = wlc->hw->di[queue]; - p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED); - if (p == NULL) { - brcms_err(wlc->hw->d11core, "dma_getnexttxp returned null!\n"); - goto out; - } + if (p == NULL) + goto fatal; txh = (struct d11txh *) (p->data); mcl = le16_to_cpu(txh->MacTxControlLow); - if (txs->phyerr) - brcms_err(wlc->hw->d11core, "phyerr 0x%x, rate 0x%x\n", - txs->phyerr, txh->MainRates); - - if (txs->frameid != le16_to_cpu(txh->TxFrameID)) { - brcms_err(wlc->hw->d11core, "frameid != txh->TxFrameID\n"); - goto out; + if (txs->phyerr) { + if (brcm_msg_level & LOG_ERROR_VAL) { + wiphy_err(wlc->wiphy, "phyerr 0x%x, rate 0x%x\n", + txs->phyerr, txh->MainRates); + brcms_c_print_txdesc(txh); + } + brcms_c_print_txstatus(txs); } + + if (txs->frameid != le16_to_cpu(txh->TxFrameID)) + goto fatal; tx_info = IEEE80211_SKB_CB(p); h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); @@ -894,24 +898,14 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { brcms_c_ampdu_dotxstatus(wlc->ampdu, scb, p, txs); - fatal = false; - goto out; + return false; } - /* - * brcms_c_ampdu_dotxstatus() will trace tx descriptors for AMPDU - * frames; this traces them for the rest. - */ - trace_brcms_txdesc(&wlc->hw->d11core->dev, txh, sizeof(*txh)); - supr_status = txs->status & TX_STATUS_SUPR_MASK; - if (supr_status == TX_STATUS_SUPR_BADCH) { - unsigned xfts = le16_to_cpu(txh->XtraFrameTypes); - brcms_dbg_tx(wlc->hw->d11core, - "Pkt tx suppressed, dest chan %u, current %d\n", - (xfts >> XFTS_CHANNEL_SHIFT) & 0xff, - CHSPEC_CHANNEL(wlc->default_bss->chanspec)); - } + if (supr_status == TX_STATUS_SUPR_BADCH) + BCMMSG(wlc->wiphy, + "%s: Pkt tx suppressed, possibly channel %d\n", + __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec)); tx_rts = le16_to_cpu(txh->MacTxControlLow) & TXC_SENDRTS; tx_frame_count = @@ -922,7 +916,7 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) lastframe = !ieee80211_has_morefrags(h->frame_control); if (!lastframe) { - brcms_err(wlc->hw->d11core, "Not last frame!\n"); + wiphy_err(wlc->wiphy, "Not last frame!\n"); } else { /* * Set information to be consumed by Minstrel ht. @@ -988,37 +982,26 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) totlen = p->len; free_pdu = true; + brcms_c_txfifo_complete(wlc, queue, 1); + if (lastframe) { /* remove PLCP & Broadcom tx descriptor header */ skb_pull(p, D11_PHY_HDR_LEN); skb_pull(p, D11_TXH_LEN); ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p); } else { - brcms_err(wlc->hw->d11core, - "%s: Not last frame => not calling tx_status\n", - __func__); + wiphy_err(wlc->wiphy, "%s: Not last frame => not calling " + "tx_status\n", __func__); } - fatal = false; + return false; - out: - if (fatal) { - if (txh) - trace_brcms_txdesc(&wlc->hw->d11core->dev, txh, - sizeof(*txh)); - if (p) - brcmu_pkt_buf_free_skb(p); - } + fatal: + if (p) + brcmu_pkt_buf_free_skb(p); - if (dma && queue < NFIFO) { - u16 ac_queue = brcms_fifo_to_ac(queue); - if (dma->txavail > TX_HEADROOM && queue < TX_BCMC_FIFO && - ieee80211_queue_stopped(wlc->pub->ieee_hw, ac_queue)) - ieee80211_wake_queue(wlc->pub->ieee_hw, ac_queue); - dma_kick_tx(dma); - } + return true; - return fatal; } /* process tx completion events in BMAC @@ -1028,6 +1011,7 @@ static bool brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) { bool morepending = false; + struct brcms_c_info *wlc = wlc_hw->wlc; struct bcma_device *core; struct tx_status txstatus, *txs; u32 s1, s2; @@ -1038,23 +1022,19 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) */ uint max_tx_num = bound ? TXSBND : -1; + BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); + txs = &txstatus; core = wlc_hw->d11core; *fatal = false; s1 = bcma_read32(core, D11REGOFFS(frmtxstatus)); while (!(*fatal) && (s1 & TXS_V)) { - /* !give others some time to run! */ - if (n >= max_tx_num) { - morepending = true; - break; - } if (s1 == 0xffffffff) { - brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, - __func__); - *fatal = true; - return false; + wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", + wlc_hw->unit, __func__); + return morepending; } s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2)); @@ -1066,12 +1046,20 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) *fatal = brcms_c_dotxstatus(wlc_hw->wlc, txs); + /* !give others some time to run! */ + if (++n >= max_tx_num) + break; s1 = bcma_read32(core, D11REGOFFS(frmtxstatus)); - n++; } if (*fatal) - return false; + return 0; + + if (n >= max_tx_num) + morepending = true; + + if (!pktq_empty(&wlc->pkt_queue->q)) + brcms_c_send_q(wlc); return morepending; } @@ -1124,6 +1112,7 @@ static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme) u16 pio_mhf2 = 0; struct brcms_hardware *wlc_hw = wlc->hw; uint unit = wlc_hw->unit; + struct wiphy *wiphy = wlc->wiphy; /* name and offsets for dma_attach */ snprintf(name, sizeof(name), "wl%d", unit); @@ -1136,12 +1125,12 @@ static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme) * TX: TX_AC_BK_FIFO (TX AC Background data packets) * RX: RX_FIFO (RX data packets) */ - wlc_hw->di[0] = dma_attach(name, wlc, + wlc_hw->di[0] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core, (wme ? dmareg(DMA_TX, 0) : 0), dmareg(DMA_RX, 0), (wme ? NTXD : 0), NRXD, RXBUFSZ, -1, NRXBUFPOST, - BRCMS_HWRXOFF); + BRCMS_HWRXOFF, &brcm_msg_level); dma_attach_err |= (NULL == wlc_hw->di[0]); /* @@ -1150,9 +1139,10 @@ static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme) * (legacy) TX_DATA_FIFO (TX data packets) * RX: UNUSED */ - wlc_hw->di[1] = dma_attach(name, wlc, + wlc_hw->di[1] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core, dmareg(DMA_TX, 1), 0, - NTXD, 0, 0, -1, 0, 0); + NTXD, 0, 0, -1, 0, 0, + &brcm_msg_level); dma_attach_err |= (NULL == wlc_hw->di[1]); /* @@ -1160,26 +1150,26 @@ static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme) * TX: TX_AC_VI_FIFO (TX AC Video data packets) * RX: UNUSED */ - wlc_hw->di[2] = dma_attach(name, wlc, + wlc_hw->di[2] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core, dmareg(DMA_TX, 2), 0, - NTXD, 0, 0, -1, 0, 0); + NTXD, 0, 0, -1, 0, 0, + &brcm_msg_level); dma_attach_err |= (NULL == wlc_hw->di[2]); /* * FIFO 3 * TX: TX_AC_VO_FIFO (TX AC Voice data packets) * (legacy) TX_CTL_FIFO (TX control & mgmt packets) */ - wlc_hw->di[3] = dma_attach(name, wlc, + wlc_hw->di[3] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core, dmareg(DMA_TX, 3), 0, NTXD, 0, 0, -1, - 0, 0); + 0, 0, &brcm_msg_level); dma_attach_err |= (NULL == wlc_hw->di[3]); /* Cleaner to leave this as if with AP defined */ if (dma_attach_err) { - brcms_err(wlc_hw->d11core, - "wl%d: wlc_attach: dma_attach failed\n", - unit); + wiphy_err(wiphy, "wl%d: wlc_attach: dma_attach failed" + "\n", unit); return false; } @@ -1513,7 +1503,8 @@ brcms_b_set_addrmatch(struct brcms_hardware *wlc_hw, int match_reg_offset, u16 mac_m; u16 mac_h; - brcms_dbg_rx(core, "wl%d: brcms_b_set_addrmatch\n", wlc_hw->unit); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d: brcms_b_set_addrmatch\n", + wlc_hw->unit); mac_l = addr[0] | (addr[1] << 8); mac_m = addr[2] | (addr[3] << 8); @@ -1536,7 +1527,7 @@ brcms_b_write_template_ram(struct brcms_hardware *wlc_hw, int offset, int len, __le32 word_le; __be32 word_be; bool be_bit; - brcms_dbg_info(core, "wl%d\n", wlc_hw->unit); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); bcma_write32(core, D11REGOFFS(tplatewrptr), offset); @@ -1709,8 +1700,8 @@ static void brcms_b_bsinit(struct brcms_c_info *wlc, u16 chanspec) { struct brcms_hardware *wlc_hw = wlc->hw; - brcms_dbg_mac80211(wlc_hw->d11core, "wl%d: bandunit %d\n", wlc_hw->unit, - wlc_hw->band->bandunit); + BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, + wlc_hw->band->bandunit); brcms_c_ucode_bsinit(wlc_hw); @@ -1745,6 +1736,8 @@ static void brcms_b_bsinit(struct brcms_c_info *wlc, u16 chanspec) /* Perform a soft reset of the PHY PLL */ void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw) { + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); + ai_cc_reg(wlc_hw->sih, offsetof(struct chipcregs, chipcontrol_addr), ~0, 0); udelay(1); @@ -1789,7 +1782,7 @@ void brcms_b_phy_reset(struct brcms_hardware *wlc_hw) u32 phy_bw_clkbits; bool phy_in_reset = false; - brcms_dbg_info(wlc_hw->d11core, "wl%d: reset phy\n", wlc_hw->unit); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); if (pih == NULL) return; @@ -1923,7 +1916,7 @@ static void brcms_c_get_macaddr(struct brcms_hardware *wlc_hw, u8 etheraddr[ETH_ /* power both the pll and external oscillator on/off */ static void brcms_b_xtal(struct brcms_hardware *wlc_hw, bool want) { - brcms_dbg_info(wlc_hw->d11core, "wl%d: want %d\n", wlc_hw->unit, want); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d: want %d\n", wlc_hw->unit, want); /* * dont power down if plldown is false or @@ -2012,7 +2005,7 @@ void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags) if (flags == BRCMS_USE_COREFLAGS) flags = (wlc_hw->band->pi ? wlc_hw->band->core_flags : 0); - brcms_dbg_info(wlc_hw->d11core, "wl%d: core reset\n", wlc_hw->unit); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); /* request FAST clock if not on */ fastclk = wlc_hw->forcefastclk; @@ -2023,13 +2016,13 @@ void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags) if (bcma_core_is_enabled(wlc_hw->d11core)) { for (i = 0; i < NFIFO; i++) if ((wlc_hw->di[i]) && (!dma_txreset(wlc_hw->di[i]))) - brcms_err(wlc_hw->d11core, "wl%d: %s: " + wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: " "dma_txreset[%d]: cannot stop dma\n", wlc_hw->unit, __func__, i); if ((wlc_hw->di[RX_FIFO]) && (!wlc_dma_rxreset(wlc_hw, RX_FIFO))) - brcms_err(wlc_hw->d11core, "wl%d: %s: dma_rxreset" + wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: dma_rxreset" "[%d]: cannot stop dma\n", wlc_hw->unit, __func__, RX_FIFO); } @@ -2242,7 +2235,7 @@ static void brcms_ucode_write(struct brcms_hardware *wlc_hw, uint i; uint count; - brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); count = (nbytes / sizeof(u32)); @@ -2270,8 +2263,8 @@ static void brcms_ucode_download(struct brcms_hardware *wlc_hw) ucode->bcm43xx_16_mimosz); wlc_hw->ucode_loaded = true; } else - brcms_err(wlc_hw->d11core, - "%s: wl%d: unsupported phy in corerev %d\n", + wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in " + "corerev %d\n", __func__, wlc_hw->unit, wlc_hw->corerev); } else if (D11REV_IS(wlc_hw->corerev, 24)) { if (BRCMS_ISLCNPHY(wlc_hw->band)) { @@ -2279,8 +2272,8 @@ static void brcms_ucode_download(struct brcms_hardware *wlc_hw) ucode->bcm43xx_24_lcnsz); wlc_hw->ucode_loaded = true; } else { - brcms_err(wlc_hw->d11core, - "%s: wl%d: unsupported phy in corerev %d\n", + wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in " + "corerev %d\n", __func__, wlc_hw->unit, wlc_hw->corerev); } } @@ -2317,6 +2310,7 @@ static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw) uint unit; uint intstatus, idx; struct bcma_device *core = wlc_hw->d11core; + struct wiphy *wiphy = wlc_hw->wlc->wiphy; unit = wlc_hw->unit; @@ -2329,39 +2323,39 @@ static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw) if (!intstatus) continue; - brcms_dbg_int(core, "wl%d: intstatus%d 0x%x\n", - unit, idx, intstatus); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d: intstatus%d 0x%x\n", + unit, idx, intstatus); if (intstatus & I_RO) { - brcms_err(core, "wl%d: fifo %d: receive fifo " + wiphy_err(wiphy, "wl%d: fifo %d: receive fifo " "overflow\n", unit, idx); fatal = true; } if (intstatus & I_PC) { - brcms_err(core, "wl%d: fifo %d: descriptor error\n", - unit, idx); + wiphy_err(wiphy, "wl%d: fifo %d: descriptor error\n", + unit, idx); fatal = true; } if (intstatus & I_PD) { - brcms_err(core, "wl%d: fifo %d: data error\n", unit, + wiphy_err(wiphy, "wl%d: fifo %d: data error\n", unit, idx); fatal = true; } if (intstatus & I_DE) { - brcms_err(core, "wl%d: fifo %d: descriptor protocol " + wiphy_err(wiphy, "wl%d: fifo %d: descriptor protocol " "error\n", unit, idx); fatal = true; } if (intstatus & I_RU) - brcms_err(core, "wl%d: fifo %d: receive descriptor " + wiphy_err(wiphy, "wl%d: fifo %d: receive descriptor " "underflow\n", idx, unit); if (intstatus & I_XU) { - brcms_err(core, "wl%d: fifo %d: transmit fifo " + wiphy_err(wiphy, "wl%d: fifo %d: transmit fifo " "underflow\n", idx, unit); fatal = true; } @@ -2522,13 +2516,13 @@ static inline u32 wlc_intstatus(struct brcms_c_info *wlc, bool in_isr) { struct brcms_hardware *wlc_hw = wlc->hw; struct bcma_device *core = wlc_hw->d11core; - u32 macintstatus, mask; + u32 macintstatus; /* macintstatus includes a DMA interrupt summary bit */ macintstatus = bcma_read32(core, D11REGOFFS(macintstatus)); - mask = in_isr ? wlc->macintmask : wlc->defmacintmask; - trace_brcms_macintstatus(&core->dev, in_isr, macintstatus, mask); + BCMMSG(wlc->wiphy, "wl%d: macintstatus: 0x%x\n", wlc_hw->unit, + macintstatus); /* detect cardbus removed, in power down(suspend) and in reset */ if (brcms_deviceremoved(wlc)) @@ -2541,12 +2535,16 @@ static inline u32 wlc_intstatus(struct brcms_c_info *wlc, bool in_isr) return 0; /* defer unsolicited interrupts */ - macintstatus &= mask; + macintstatus &= (in_isr ? wlc->macintmask : wlc->defmacintmask); /* if not for us */ if (macintstatus == 0) return 0; + /* interrupts are already turned off for CFE build + * Caution: For CFE Turning off the interrupts again has some undesired + * consequences + */ /* turn off the interrupts */ bcma_write32(core, D11REGOFFS(macintmask), 0); (void)bcma_read32(core, D11REGOFFS(macintmask)); @@ -2589,31 +2587,33 @@ bool brcms_c_intrsupd(struct brcms_c_info *wlc) /* * First-level interrupt processing. - * Return true if this was our interrupt - * and if further brcms_c_dpc() processing is required, + * Return true if this was our interrupt, false otherwise. + * *wantdpc will be set to true if further brcms_c_dpc() processing is required, * false otherwise. */ -bool brcms_c_isr(struct brcms_c_info *wlc) +bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc) { struct brcms_hardware *wlc_hw = wlc->hw; u32 macintstatus; + *wantdpc = false; + if (!wlc_hw->up || !wlc->macintmask) return false; /* read and clear macintstatus and intstatus registers */ macintstatus = wlc_intstatus(wlc, true); - if (macintstatus == 0xffffffff) { - brcms_err(wlc_hw->d11core, - "DEVICEREMOVED detected in the ISR code path\n"); - return false; - } + if (macintstatus == 0xffffffff) + wiphy_err(wlc->wiphy, "DEVICEREMOVED detected in the ISR code" + " path\n"); /* it is not for us */ if (macintstatus == 0) return false; + *wantdpc = true; + /* save interrupt status bits */ wlc->macintstatus = macintstatus; @@ -2626,9 +2626,10 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc) struct brcms_hardware *wlc_hw = wlc->hw; struct bcma_device *core = wlc_hw->d11core; u32 mc, mi; + struct wiphy *wiphy = wlc->wiphy; - brcms_dbg_mac80211(core, "wl%d: bandunit %d\n", wlc_hw->unit, - wlc_hw->band->bandunit); + BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, + wlc_hw->band->bandunit); /* * Track overlapping suspend requests @@ -2643,7 +2644,7 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc) mc = bcma_read32(core, D11REGOFFS(maccontrol)); if (mc == 0xffffffff) { - brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, + wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, __func__); brcms_down(wlc->wl); return; @@ -2654,7 +2655,7 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc) mi = bcma_read32(core, D11REGOFFS(macintstatus)); if (mi == 0xffffffff) { - brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, + wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, __func__); brcms_down(wlc->wl); return; @@ -2667,10 +2668,10 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc) BRCMS_MAX_MAC_SUSPEND); if (!(bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD)) { - brcms_err(core, "wl%d: wlc_suspend_mac_and_wait: waited %d uS" + wiphy_err(wiphy, "wl%d: wlc_suspend_mac_and_wait: waited %d uS" " and MI_MACSSPNDD is still not on.\n", wlc_hw->unit, BRCMS_MAX_MAC_SUSPEND); - brcms_err(core, "wl%d: psmdebug 0x%08x, phydebug 0x%08x, " + wiphy_err(wiphy, "wl%d: psmdebug 0x%08x, phydebug 0x%08x, " "psm_brc 0x%04x\n", wlc_hw->unit, bcma_read32(core, D11REGOFFS(psmdebug)), bcma_read32(core, D11REGOFFS(phydebug)), @@ -2679,7 +2680,7 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc) mc = bcma_read32(core, D11REGOFFS(maccontrol)); if (mc == 0xffffffff) { - brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, + wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, __func__); brcms_down(wlc->wl); return; @@ -2695,8 +2696,8 @@ void brcms_c_enable_mac(struct brcms_c_info *wlc) struct bcma_device *core = wlc_hw->d11core; u32 mc, mi; - brcms_dbg_mac80211(core, "wl%d: bandunit %d\n", wlc_hw->unit, - wlc->band->bandunit); + BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, + wlc->band->bandunit); /* * Track overlapping suspend requests @@ -2739,6 +2740,8 @@ static bool brcms_b_validate_chip_access(struct brcms_hardware *wlc_hw) u32 w, val; struct wiphy *wiphy = wlc_hw->wlc->wiphy; + BCMMSG(wiphy, "wl%d\n", wlc_hw->unit); + /* Validate dchip register access */ bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0); @@ -2799,7 +2802,7 @@ void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on) struct bcma_device *core = wlc_hw->d11core; u32 tmp; - brcms_dbg_info(core, "wl%d\n", wlc_hw->unit); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); tmp = 0; @@ -2815,8 +2818,8 @@ void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on) tmp = bcma_read32(core, D11REGOFFS(clk_ctl_st)); if ((tmp & CCS_ERSRC_AVAIL_HT) != CCS_ERSRC_AVAIL_HT) - brcms_err(core, "%s: turn on PHY PLL failed\n", - __func__); + wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on PHY" + " PLL failed\n", __func__); } else { bcma_set32(core, D11REGOFFS(clk_ctl_st), tmp | CCS_ERSRC_REQ_D11PLL | @@ -2832,8 +2835,8 @@ void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on) (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) != (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) - brcms_err(core, "%s: turn on PHY PLL failed\n", - __func__); + wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on " + "PHY PLL failed\n", __func__); } } else { /* @@ -2851,7 +2854,7 @@ static void brcms_c_coredisable(struct brcms_hardware *wlc_hw) { bool dev_gone; - brcms_dbg_info(wlc_hw->d11core, "wl%d: disable core\n", wlc_hw->unit); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); dev_gone = brcms_deviceremoved(wlc_hw->wlc); @@ -2881,14 +2884,12 @@ static void brcms_c_flushqueues(struct brcms_c_info *wlc) uint i; /* free any posted tx packets */ - for (i = 0; i < NFIFO; i++) { + for (i = 0; i < NFIFO; i++) if (wlc_hw->di[i]) { dma_txreclaim(wlc_hw->di[i], DMA_RANGE_ALL); - if (i < TX_BCMC_FIFO) - ieee80211_wake_queue(wlc->pub->ieee_hw, - brcms_fifo_to_ac(i)); + wlc->core->txpktpend[i] = 0; + BCMMSG(wlc->wiphy, "pktpend fifo %d clrd\n", i); } - } /* free any posted rx packets */ dma_rxreclaim(wlc_hw->di[RX_FIFO]); @@ -3108,7 +3109,7 @@ static void brcms_c_statsupd(struct brcms_c_info *wlc) /* check for rx fifo 0 overflow */ delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl); if (delta) - brcms_err(wlc->hw->d11core, "wl%d: %u rx fifo 0 overflows!\n", + wiphy_err(wlc->wiphy, "wl%d: %u rx fifo 0 overflows!\n", wlc->pub->unit, delta); /* check for tx fifo underflows */ @@ -3117,9 +3118,8 @@ static void brcms_c_statsupd(struct brcms_c_info *wlc) (u16) (wlc->core->macstat_snapshot->txfunfl[i] - txfunfl[i]); if (delta) - brcms_err(wlc->hw->d11core, - "wl%d: %u tx fifo %d underflows!\n", - wlc->pub->unit, delta, i); + wiphy_err(wlc->wiphy, "wl%d: %u tx fifo %d underflows!" + "\n", wlc->pub->unit, delta, i); } #endif /* DEBUG */ @@ -3132,6 +3132,8 @@ static void brcms_c_statsupd(struct brcms_c_info *wlc) static void brcms_b_reset(struct brcms_hardware *wlc_hw) { + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); + /* reset the core */ if (!brcms_deviceremoved(wlc_hw->wlc)) brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS); @@ -3142,7 +3144,7 @@ static void brcms_b_reset(struct brcms_hardware *wlc_hw) void brcms_c_reset(struct brcms_c_info *wlc) { - brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit); + BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); /* slurp up hw mac counters before core reset */ brcms_c_statsupd(wlc); @@ -3187,9 +3189,10 @@ static void brcms_b_coreinit(struct brcms_c_info *wlc) bool fifosz_fixup = false; int err = 0; u16 buf[NFIFO]; + struct wiphy *wiphy = wlc->wiphy; struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode; - brcms_dbg_info(core, "wl%d: core init\n", wlc_hw->unit); + BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); /* reset PSM */ brcms_b_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE)); @@ -3209,7 +3212,7 @@ static void brcms_b_coreinit(struct brcms_c_info *wlc) SPINWAIT(((bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD) == 0), 1000 * 1000); if ((bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD) == 0) - brcms_err(core, "wl%d: wlc_coreinit: ucode did not self-" + wiphy_err(wiphy, "wl%d: wlc_coreinit: ucode did not self-" "suspend!\n", wlc_hw->unit); brcms_c_gpio_init(wlc); @@ -3220,18 +3223,18 @@ static void brcms_b_coreinit(struct brcms_c_info *wlc) if (BRCMS_ISNPHY(wlc_hw->band)) brcms_c_write_inits(wlc_hw, ucode->d11n0initvals16); else - brcms_err(core, "%s: wl%d: unsupported phy in corerev" + wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev" " %d\n", __func__, wlc_hw->unit, wlc_hw->corerev); } else if (D11REV_IS(wlc_hw->corerev, 24)) { if (BRCMS_ISLCNPHY(wlc_hw->band)) brcms_c_write_inits(wlc_hw, ucode->d11lcn0initvals24); else - brcms_err(core, "%s: wl%d: unsupported phy in corerev" + wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev" " %d\n", __func__, wlc_hw->unit, wlc_hw->corerev); } else { - brcms_err(core, "%s: wl%d: unsupported corerev %d\n", + wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n", __func__, wlc_hw->unit, wlc_hw->corerev); } @@ -3273,7 +3276,7 @@ static void brcms_b_coreinit(struct brcms_c_info *wlc) err = -1; } if (err != 0) - brcms_err(core, "wlc_coreinit: txfifo mismatch: ucode size %d" + wiphy_err(wiphy, "wlc_coreinit: txfifo mismatch: ucode size %d" " driver size %d index %d\n", buf[i], wlc_hw->xmtfifo_sz[i], i); @@ -3356,6 +3359,8 @@ static brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec) { bool fastclk; struct brcms_c_info *wlc = wlc_hw->wlc; + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); + /* request FAST clock if not on */ fastclk = wlc_hw->forcefastclk; if (!fastclk) @@ -3448,7 +3453,7 @@ static void brcms_c_rate_lookup_init(struct brcms_c_info *wlc, rate = (rateset->rates[i] & BRCMS_RATE_MASK); if (rate > BRCM_MAXRATE) { - brcms_err(wlc->hw->d11core, "brcms_c_rate_lookup_init: " + wiphy_err(wlc->wiphy, "brcms_c_rate_lookup_init: " "invalid rate 0x%X in rate set\n", rateset->rates[i]); continue; @@ -3524,6 +3529,7 @@ static void brcms_c_bandinit_ordered(struct brcms_c_info *wlc, uint parkband; uint i, band_order[2]; + BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); /* * We might have been bandlocked during down and the chip * power-cycled (hibernate). Figure out the right band to park on @@ -3704,8 +3710,8 @@ static void brcms_c_set_ratetable(struct brcms_c_info *wlc) /* band-specific init */ static void brcms_c_bsinit(struct brcms_c_info *wlc) { - brcms_dbg_info(wlc->hw->d11core, "wl%d: bandunit %d\n", - wlc->pub->unit, wlc->band->bandunit); + BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", + wlc->pub->unit, wlc->band->bandunit); /* write ucode ACK/CTS rate table */ brcms_c_set_ratetable(wlc); @@ -3728,8 +3734,7 @@ brcms_c_duty_cycle_set(struct brcms_c_info *wlc, int duty_cycle, bool isOFDM, isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM : M_TX_IDLE_BUSY_RATIO_X_16_CCK; if (duty_cycle > 100 || duty_cycle < 0) { - brcms_err(wlc->hw->d11core, - "wl%d: duty cycle value off limit\n", + wiphy_err(wlc->wiphy, "wl%d: duty cycle value off limit\n", wlc->pub->unit); return -EINVAL; } @@ -3747,6 +3752,40 @@ brcms_c_duty_cycle_set(struct brcms_c_info *wlc, int duty_cycle, bool isOFDM, return 0; } +/* + * Initialize the base precedence map for dequeueing + * from txq based on WME settings + */ +static void brcms_c_tx_prec_map_init(struct brcms_c_info *wlc) +{ + wlc->tx_prec_map = BRCMS_PREC_BMP_ALL; + memset(wlc->fifo2prec_map, 0, NFIFO * sizeof(u16)); + + wlc->fifo2prec_map[TX_AC_BK_FIFO] = BRCMS_PREC_BMP_AC_BK; + wlc->fifo2prec_map[TX_AC_BE_FIFO] = BRCMS_PREC_BMP_AC_BE; + wlc->fifo2prec_map[TX_AC_VI_FIFO] = BRCMS_PREC_BMP_AC_VI; + wlc->fifo2prec_map[TX_AC_VO_FIFO] = BRCMS_PREC_BMP_AC_VO; +} + +static void +brcms_c_txflowcontrol_signal(struct brcms_c_info *wlc, + struct brcms_txq_info *qi, bool on, int prio) +{ + /* transmit flowcontrol is not yet implemented */ +} + +static void brcms_c_txflowcontrol_reset(struct brcms_c_info *wlc) +{ + struct brcms_txq_info *qi; + + for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) { + if (qi->stopped) { + brcms_c_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO); + qi->stopped = 0; + } + } +} + /* push sw hps and wake state through hardware */ static void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc) { @@ -3756,8 +3795,7 @@ static void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc) hps = brcms_c_ps_allowed(wlc); - brcms_dbg_mac80211(wlc->hw->d11core, "wl%d: hps %d\n", wlc->pub->unit, - hps); + BCMMSG(wlc->wiphy, "wl%d: hps %d\n", wlc->pub->unit, hps); v1 = bcma_read32(wlc->hw->d11core, D11REGOFFS(maccontrol)); v2 = MCTL_WAKE; @@ -3843,8 +3881,7 @@ brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec, { uint bandunit; - brcms_dbg_mac80211(wlc_hw->d11core, "wl%d: 0x%x\n", wlc_hw->unit, - chanspec); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d: 0x%x\n", wlc_hw->unit, chanspec); wlc_hw->chanspec = chanspec; @@ -3905,7 +3942,7 @@ static void brcms_c_set_chanspec(struct brcms_c_info *wlc, u16 chanspec) u16 old_chanspec = wlc->chanspec; if (!brcms_c_valid_chanspec_db(wlc->cmi, chanspec)) { - brcms_err(wlc->hw->d11core, "wl%d: %s: Bad channel %d\n", + wiphy_err(wlc->wiphy, "wl%d: %s: Bad channel %d\n", wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec)); return; } @@ -3916,8 +3953,8 @@ static void brcms_c_set_chanspec(struct brcms_c_info *wlc, u16 chanspec) if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) { switchband = true; if (wlc->bandlocked) { - brcms_err(wlc->hw->d11core, - "wl%d: %s: chspec %d band is locked!\n", + wiphy_err(wlc->wiphy, "wl%d: %s: chspec %d " + "band is locked!\n", wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec)); return; @@ -3981,10 +4018,6 @@ void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc, */ void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx, int val) { - /* - * Cannot use brcms_dbg_* here because this function is called - * before wlc is sufficiently initialized. - */ BCMMSG(wlc->wiphy, "idx %d, val %d\n", idx, val); switch (idx) { @@ -4057,8 +4090,8 @@ void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci, /* Only apply params if the core is out of reset and has clocks */ if (!wlc->clk) { - brcms_err(wlc->hw->d11core, "wl%d: %s : no-clock\n", - wlc->pub->unit, __func__); + wiphy_err(wlc->wiphy, "wl%d: %s : no-clock\n", wlc->pub->unit, + __func__); return; } @@ -4076,7 +4109,7 @@ void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci, if (acp_shm.aifs < EDCF_AIFSN_MIN || acp_shm.aifs > EDCF_AIFSN_MAX) { - brcms_err(wlc->hw->d11core, "wl%d: edcf_setparams: bad " + wiphy_err(wlc->wiphy, "wl%d: edcf_setparams: bad " "aifs %d\n", wlc->pub->unit, acp_shm.aifs); } else { acp_shm.cwmin = params->cw_min; @@ -4191,8 +4224,8 @@ static void brcms_c_radio_timer(void *arg) struct brcms_c_info *wlc = (struct brcms_c_info *) arg; if (brcms_deviceremoved(wlc)) { - brcms_err(wlc->hw->d11core, "wl%d: %s: dead chip\n", - wlc->pub->unit, __func__); + wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit, + __func__); brcms_down(wlc->wl); return; } @@ -4205,6 +4238,8 @@ static void brcms_b_watchdog(struct brcms_c_info *wlc) { struct brcms_hardware *wlc_hw = wlc->hw; + BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); + if (!wlc_hw->up) return; @@ -4223,14 +4258,14 @@ static void brcms_b_watchdog(struct brcms_c_info *wlc) /* common watchdog code */ static void brcms_c_watchdog(struct brcms_c_info *wlc) { - brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit); + BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); if (!wlc->pub->up) return; if (brcms_deviceremoved(wlc)) { - brcms_err(wlc->hw->d11core, "wl%d: %s: dead chip\n", - wlc->pub->unit, __func__); + wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit, + __func__); brcms_down(wlc->wl); return; } @@ -4402,13 +4437,13 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core, struct ssb_sprom *sprom = &core->bus->sprom; if (core->bus->hosttype == BCMA_HOSTTYPE_PCI) - brcms_dbg_info(core, "wl%d: vendor 0x%x device 0x%x\n", unit, - pcidev->vendor, - pcidev->device); + BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit, + pcidev->vendor, + pcidev->device); else - brcms_dbg_info(core, "wl%d: vendor 0x%x device 0x%x\n", unit, - core->bus->boardinfo.vendor, - core->bus->boardinfo.type); + BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit, + core->bus->boardinfo.vendor, + core->bus->boardinfo.type); wme = true; @@ -4680,9 +4715,8 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core, goto fail; } - brcms_dbg_info(wlc_hw->d11core, "deviceid 0x%x nbands %d board 0x%x\n", - wlc_hw->deviceid, wlc_hw->_nbands, - ai_get_boardtype(wlc_hw->sih)); + BCMMSG(wlc->wiphy, "deviceid 0x%x nbands %d board 0x%x\n", + wlc_hw->deviceid, wlc_hw->_nbands, ai_get_boardtype(wlc_hw->sih)); return err; @@ -4802,6 +4836,56 @@ static void brcms_c_bss_default_init(struct brcms_c_info *wlc) bi->flags |= BRCMS_BSS_HT; } +static struct brcms_txq_info *brcms_c_txq_alloc(struct brcms_c_info *wlc) +{ + struct brcms_txq_info *qi, *p; + + qi = kzalloc(sizeof(struct brcms_txq_info), GFP_ATOMIC); + if (qi != NULL) { + /* + * Have enough room for control packets along with HI watermark + * Also, add room to txq for total psq packets if all the SCBs + * leave PS mode. The watermark for flowcontrol to OS packets + * will remain the same + */ + brcmu_pktq_init(&qi->q, BRCMS_PREC_COUNT, + 2 * BRCMS_DATAHIWAT + PKTQ_LEN_DEFAULT); + + /* add this queue to the the global list */ + p = wlc->tx_queues; + if (p == NULL) { + wlc->tx_queues = qi; + } else { + while (p->next != NULL) + p = p->next; + p->next = qi; + } + } + return qi; +} + +static void brcms_c_txq_free(struct brcms_c_info *wlc, + struct brcms_txq_info *qi) +{ + struct brcms_txq_info *p; + + if (qi == NULL) + return; + + /* remove the queue from the linked list */ + p = wlc->tx_queues; + if (p == qi) + wlc->tx_queues = p->next; + else { + while (p != NULL && p->next != qi) + p = p->next; + if (p != NULL) + p->next = p->next->next; + } + + kfree(qi); +} + static void brcms_c_update_mimo_band_bwcap(struct brcms_c_info *wlc, u8 bwcap) { uint i; @@ -4907,6 +4991,8 @@ uint brcms_c_detach(struct brcms_c_info *wlc) if (wlc == NULL) return 0; + BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); + callbacks += brcms_b_detach(wlc); /* delete software timers */ @@ -4919,6 +5005,10 @@ uint brcms_c_detach(struct brcms_c_info *wlc) brcms_c_detach_module(wlc); + + while (wlc->tx_queues != NULL) + brcms_c_txq_free(wlc, wlc->tx_queues); + brcms_c_detach_mfree(wlc); return callbacks; } @@ -4936,7 +5026,7 @@ static void brcms_b_hw_up(struct brcms_hardware *wlc_hw) if (wlc_hw->wlc->pub->hw_up) return; - brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); /* * Enable pll and xtal, initialize the power control registers, @@ -4973,7 +5063,7 @@ static void brcms_b_hw_up(struct brcms_hardware *wlc_hw) static int brcms_b_up_prep(struct brcms_hardware *wlc_hw) { - brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit); + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); /* * Enable pll and xtal, initialize the power control registers, @@ -5012,6 +5102,8 @@ static int brcms_b_up_prep(struct brcms_hardware *wlc_hw) static int brcms_b_up_finish(struct brcms_hardware *wlc_hw) { + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); + wlc_hw->up = true; wlc_phy_hw_state_upd(wlc_hw->band->pi, true); @@ -5043,7 +5135,7 @@ int brcms_c_up(struct brcms_c_info *wlc) { struct ieee80211_channel *ch; - brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit); + BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); /* HW is turned off so don't try to access it */ if (wlc->pub->hw_off || brcms_deviceremoved(wlc)) @@ -5084,8 +5176,8 @@ int brcms_c_up(struct brcms_c_info *wlc) WL_RADIO_HW_DISABLE); if (bsscfg->enable && bsscfg->BSS) - brcms_err(wlc->hw->d11core, - "wl%d: up: rfdisable -> " + wiphy_err(wlc->wiphy, "wl%d: up" + ": rfdisable -> " "bsscfg_disable()\n", wlc->pub->unit); } @@ -5145,6 +5237,8 @@ static int brcms_b_bmac_down_prep(struct brcms_hardware *wlc_hw) bool dev_gone; uint callbacks = 0; + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); + if (!wlc_hw->up) return callbacks; @@ -5171,6 +5265,8 @@ static int brcms_b_down_finish(struct brcms_hardware *wlc_hw) uint callbacks = 0; bool dev_gone; + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); + if (!wlc_hw->up) return callbacks; @@ -5218,14 +5314,14 @@ uint brcms_c_down(struct brcms_c_info *wlc) uint callbacks = 0; int i; bool dev_gone = false; + struct brcms_txq_info *qi; - brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit); + BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); /* check if we are already in the going down path */ if (wlc->going_down) { - brcms_err(wlc->hw->d11core, - "wl%d: %s: Driver going down so return\n", - wlc->pub->unit, __func__); + wiphy_err(wlc->wiphy, "wl%d: %s: Driver going down so return" + "\n", wlc->pub->unit, __func__); return 0; } if (!wlc->pub->up) @@ -5257,6 +5353,13 @@ uint brcms_c_down(struct brcms_c_info *wlc) wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL); + /* clear txq flow control */ + brcms_c_txflowcontrol_reset(wlc); + + /* flush tx queues */ + for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) + brcmu_pktq_flush(&qi->q, true, NULL, NULL); + callbacks += brcms_b_down_finish(wlc->hw); /* brcms_b_down_finish has done brcms_c_coredisable(). so clk is off */ @@ -5338,7 +5441,7 @@ int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config) default: /* Error */ - brcms_err(wlc->hw->d11core, "wl%d: %s: invalid gmode %d\n", + wiphy_err(wlc->wiphy, "wl%d: %s: invalid gmode %d\n", wlc->pub->unit, __func__, gmode); return -ENOTSUPP; } @@ -5642,6 +5745,45 @@ int brcms_c_module_unregister(struct brcms_pub *pub, const char *name, return -ENODATA; } +void brcms_c_print_txstatus(struct tx_status *txs) +{ + pr_debug("\ntxpkt (MPDU) Complete\n"); + + pr_debug("FrameID: %04x TxStatus: %04x\n", txs->frameid, txs->status); + + pr_debug("[15:12] %d frame attempts\n", + (txs->status & TX_STATUS_FRM_RTX_MASK) >> + TX_STATUS_FRM_RTX_SHIFT); + pr_debug(" [11:8] %d rts attempts\n", + (txs->status & TX_STATUS_RTS_RTX_MASK) >> + TX_STATUS_RTS_RTX_SHIFT); + pr_debug(" [7] %d PM mode indicated\n", + txs->status & TX_STATUS_PMINDCTD ? 1 : 0); + pr_debug(" [6] %d intermediate status\n", + txs->status & TX_STATUS_INTERMEDIATE ? 1 : 0); + pr_debug(" [5] %d AMPDU\n", + txs->status & TX_STATUS_AMPDU ? 1 : 0); + pr_debug(" [4:2] %d Frame Suppressed Reason (%s)\n", + (txs->status & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT, + (const char *[]) { + "None", + "PMQ Entry", + "Flush request", + "Previous frag failure", + "Channel mismatch", + "Lifetime Expiry", + "Underflow" + } [(txs->status & TX_STATUS_SUPR_MASK) >> + TX_STATUS_SUPR_SHIFT]); + pr_debug(" [1] %d acked\n", + txs->status & TX_STATUS_ACK_RCV ? 1 : 0); + + pr_debug("LastTxTime: %04x Seq: %04x PHYTxStatus: %04x RxAckRSSI: %04x RxAckSQ: %04x\n", + txs->lasttxtime, txs->sequence, txs->phyerr, + (txs->ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT, + (txs->ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT); +} + static bool brcms_c_chipmatch_pci(struct bcma_device *core) { struct pci_dev *pcidev = core->bus->host_pci; @@ -5690,6 +5832,184 @@ bool brcms_c_chipmatch(struct bcma_device *core) } } +#if defined(DEBUG) +void brcms_c_print_txdesc(struct d11txh *txh) +{ + u16 mtcl = le16_to_cpu(txh->MacTxControlLow); + u16 mtch = le16_to_cpu(txh->MacTxControlHigh); + u16 mfc = le16_to_cpu(txh->MacFrameControl); + u16 tfest = le16_to_cpu(txh->TxFesTimeNormal); + u16 ptcw = le16_to_cpu(txh->PhyTxControlWord); + u16 ptcw_1 = le16_to_cpu(txh->PhyTxControlWord_1); + u16 ptcw_1_Fbr = le16_to_cpu(txh->PhyTxControlWord_1_Fbr); + u16 ptcw_1_Rts = le16_to_cpu(txh->PhyTxControlWord_1_Rts); + u16 ptcw_1_FbrRts = le16_to_cpu(txh->PhyTxControlWord_1_FbrRts); + u16 mainrates = le16_to_cpu(txh->MainRates); + u16 xtraft = le16_to_cpu(txh->XtraFrameTypes); + u8 *iv = txh->IV; + u8 *ra = txh->TxFrameRA; + u16 tfestfb = le16_to_cpu(txh->TxFesTimeFallback); + u8 *rtspfb = txh->RTSPLCPFallback; + u16 rtsdfb = le16_to_cpu(txh->RTSDurFallback); + u8 *fragpfb = txh->FragPLCPFallback; + u16 fragdfb = le16_to_cpu(txh->FragDurFallback); + u16 mmodelen = le16_to_cpu(txh->MModeLen); + u16 mmodefbrlen = le16_to_cpu(txh->MModeFbrLen); + u16 tfid = le16_to_cpu(txh->TxFrameID); + u16 txs = le16_to_cpu(txh->TxStatus); + u16 mnmpdu = le16_to_cpu(txh->MaxNMpdus); + u16 mabyte = le16_to_cpu(txh->MaxABytes_MRT); + u16 mabyte_f = le16_to_cpu(txh->MaxABytes_FBR); + u16 mmbyte = le16_to_cpu(txh->MinMBytes); + + u8 *rtsph = txh->RTSPhyHeader; + struct ieee80211_rts rts = txh->rts_frame; + + /* add plcp header along with txh descriptor */ + brcmu_dbg_hex_dump(txh, sizeof(struct d11txh) + 48, + "Raw TxDesc + plcp header:\n"); + + pr_debug("TxCtlLow: %04x ", mtcl); + pr_debug("TxCtlHigh: %04x ", mtch); + pr_debug("FC: %04x ", mfc); + pr_debug("FES Time: %04x\n", tfest); + pr_debug("PhyCtl: %04x%s ", ptcw, + (ptcw & PHY_TXC_SHORT_HDR) ? " short" : ""); + pr_debug("PhyCtl_1: %04x ", ptcw_1); + pr_debug("PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr); + pr_debug("PhyCtl_1_Rts: %04x ", ptcw_1_Rts); + pr_debug("PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts); + pr_debug("MainRates: %04x ", mainrates); + pr_debug("XtraFrameTypes: %04x ", xtraft); + pr_debug("\n"); + + print_hex_dump_bytes("SecIV:", DUMP_PREFIX_OFFSET, iv, sizeof(txh->IV)); + print_hex_dump_bytes("RA:", DUMP_PREFIX_OFFSET, + ra, sizeof(txh->TxFrameRA)); + + pr_debug("Fb FES Time: %04x ", tfestfb); + print_hex_dump_bytes("Fb RTS PLCP:", DUMP_PREFIX_OFFSET, + rtspfb, sizeof(txh->RTSPLCPFallback)); + pr_debug("RTS DUR: %04x ", rtsdfb); + print_hex_dump_bytes("PLCP:", DUMP_PREFIX_OFFSET, + fragpfb, sizeof(txh->FragPLCPFallback)); + pr_debug("DUR: %04x", fragdfb); + pr_debug("\n"); + + pr_debug("MModeLen: %04x ", mmodelen); + pr_debug("MModeFbrLen: %04x\n", mmodefbrlen); + + pr_debug("FrameID: %04x\n", tfid); + pr_debug("TxStatus: %04x\n", txs); + + pr_debug("MaxNumMpdu: %04x\n", mnmpdu); + pr_debug("MaxAggbyte: %04x\n", mabyte); + pr_debug("MaxAggbyte_fb: %04x\n", mabyte_f); + pr_debug("MinByte: %04x\n", mmbyte); + + print_hex_dump_bytes("RTS PLCP:", DUMP_PREFIX_OFFSET, + rtsph, sizeof(txh->RTSPhyHeader)); + print_hex_dump_bytes("RTS Frame:", DUMP_PREFIX_OFFSET, + (u8 *)&rts, sizeof(txh->rts_frame)); + pr_debug("\n"); +} +#endif /* defined(DEBUG) */ + +#if defined(DEBUG) +static int +brcms_c_format_flags(const struct brcms_c_bit_desc *bd, u32 flags, char *buf, + int len) +{ + int i; + char *p = buf; + char hexstr[16]; + int slen = 0, nlen = 0; + u32 bit; + const char *name; + + if (len < 2 || !buf) + return 0; + + buf[0] = '\0'; + + for (i = 0; flags != 0; i++) { + bit = bd[i].bit; + name = bd[i].name; + if (bit == 0 && flags != 0) { + /* print any unnamed bits */ + snprintf(hexstr, 16, "0x%X", flags); + name = hexstr; + flags = 0; /* exit loop */ + } else if ((flags & bit) == 0) + continue; + flags &= ~bit; + nlen = strlen(name); + slen += nlen; + /* count btwn flag space */ + if (flags != 0) + slen += 1; + /* need NULL char as well */ + if (len <= slen) + break; + /* copy NULL char but don't count it */ + strncpy(p, name, nlen + 1); + p += nlen; + /* copy btwn flag space and NULL char */ + if (flags != 0) + p += snprintf(p, 2, " "); + len -= slen; + } + + /* indicate the str was too short */ + if (flags != 0) { + if (len < 2) + p -= 2 - len; /* overwrite last char */ + p += snprintf(p, 2, ">"); + } + + return (int)(p - buf); +} +#endif /* defined(DEBUG) */ + +#if defined(DEBUG) +void brcms_c_print_rxh(struct d11rxhdr *rxh) +{ + u16 len = rxh->RxFrameSize; + u16 phystatus_0 = rxh->PhyRxStatus_0; + u16 phystatus_1 = rxh->PhyRxStatus_1; + u16 phystatus_2 = rxh->PhyRxStatus_2; + u16 phystatus_3 = rxh->PhyRxStatus_3; + u16 macstatus1 = rxh->RxStatus1; + u16 macstatus2 = rxh->RxStatus2; + char flagstr[64]; + char lenbuf[20]; + static const struct brcms_c_bit_desc macstat_flags[] = { + {RXS_FCSERR, "FCSErr"}, + {RXS_RESPFRAMETX, "Reply"}, + {RXS_PBPRES, "PADDING"}, + {RXS_DECATMPT, "DeCr"}, + {RXS_DECERR, "DeCrErr"}, + {RXS_BCNSENT, "Bcn"}, + {0, NULL} + }; + + brcmu_dbg_hex_dump(rxh, sizeof(struct d11rxhdr), "Raw RxDesc:\n"); + + brcms_c_format_flags(macstat_flags, macstatus1, flagstr, 64); + + snprintf(lenbuf, sizeof(lenbuf), "0x%x", len); + + pr_debug("RxFrameSize: %6s (%d)%s\n", lenbuf, len, + (rxh->PhyRxStatus_0 & PRXS0_SHORTH) ? " short preamble" : ""); + pr_debug("RxPHYStatus: %04x %04x %04x %04x\n", + phystatus_0, phystatus_1, phystatus_2, phystatus_3); + pr_debug("RxMACStatus: %x %s\n", macstatus1, flagstr); + pr_debug("RXMACaggtype: %x\n", + (macstatus2 & RXS_AGGTYPE_MASK)); + pr_debug("RxTSFTime: %04x\n", rxh->RxTSFTime); +} +#endif /* defined(DEBUG) */ + u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate) { u16 table_ptr; @@ -5713,6 +6033,86 @@ u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate) return 2 * brcms_b_read_shm(wlc_hw, table_ptr + (index * 2)); } +static bool +brcms_c_prec_enq_head(struct brcms_c_info *wlc, struct pktq *q, + struct sk_buff *pkt, int prec, bool head) +{ + struct sk_buff *p; + int eprec = -1; /* precedence to evict from */ + + /* Determine precedence from which to evict packet, if any */ + if (pktq_pfull(q, prec)) + eprec = prec; + else if (pktq_full(q)) { + p = brcmu_pktq_peek_tail(q, &eprec); + if (eprec > prec) { + wiphy_err(wlc->wiphy, "%s: Failing: eprec %d > prec %d" + "\n", __func__, eprec, prec); + return false; + } + } + + /* Evict if needed */ + if (eprec >= 0) { + bool discard_oldest; + + discard_oldest = ac_bitmap_tst(0, eprec); + + /* Refuse newer packet unless configured to discard oldest */ + if (eprec == prec && !discard_oldest) { + wiphy_err(wlc->wiphy, "%s: No where to go, prec == %d" + "\n", __func__, prec); + return false; + } + + /* Evict packet according to discard policy */ + p = discard_oldest ? brcmu_pktq_pdeq(q, eprec) : + brcmu_pktq_pdeq_tail(q, eprec); + brcmu_pkt_buf_free_skb(p); + } + + /* Enqueue */ + if (head) + p = brcmu_pktq_penq_head(q, prec, pkt); + else + p = brcmu_pktq_penq(q, prec, pkt); + + return true; +} + +/* + * Attempts to queue a packet onto a multiple-precedence queue, + * if necessary evicting a lower precedence packet from the queue. + * + * 'prec' is the precedence number that has already been mapped + * from the packet priority. + * + * Returns true if packet consumed (queued), false if not. + */ +static bool brcms_c_prec_enq(struct brcms_c_info *wlc, struct pktq *q, + struct sk_buff *pkt, int prec) +{ + return brcms_c_prec_enq_head(wlc, q, pkt, prec, false); +} + +void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb, + struct sk_buff *sdu, uint prec) +{ + struct brcms_txq_info *qi = wlc->pkt_queue; /* Check me */ + struct pktq *q = &qi->q; + int prio; + + prio = sdu->priority; + + if (!brcms_c_prec_enq(wlc, q, sdu, prec)) { + /* + * we might hit this condtion in case + * packet flooding from mac80211 stack + */ + brcmu_pkt_buf_free_skb(sdu); + } +} + /* * bcmc_fid_generate: * Generate frame ID for a BCMC packet. The frag field is not used @@ -5740,6 +6140,8 @@ brcms_c_calc_ack_time(struct brcms_c_info *wlc, u32 rspec, { uint dur = 0; + BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d\n", + wlc->pub->unit, rspec, preamble_type); /* * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that * is less than or equal to the rate of the immediately previous @@ -5757,6 +6159,8 @@ static uint brcms_c_calc_cts_time(struct brcms_c_info *wlc, u32 rspec, u8 preamble_type) { + BCMMSG(wlc->wiphy, "wl%d: ratespec 0x%x, preamble_type %d\n", + wlc->pub->unit, rspec, preamble_type); return brcms_c_calc_ack_time(wlc, rspec, preamble_type); } @@ -5764,6 +6168,8 @@ static uint brcms_c_calc_ba_time(struct brcms_c_info *wlc, u32 rspec, u8 preamble_type) { + BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, " + "preamble_type %d\n", wlc->pub->unit, rspec, preamble_type); /* * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that * is less than or equal to the rate of the immediately previous @@ -5817,6 +6223,9 @@ brcms_c_calc_frame_len(struct brcms_c_info *wlc, u32 ratespec, uint nsyms, mac_len, Ndps, kNdps; uint rate = rspec2rate(ratespec); + BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, dur %d\n", + wlc->pub->unit, ratespec, preamble_type, dur); + if (is_mcs_rate(ratespec)) { uint mcs = ratespec & RSPEC_RATE_MASK; int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec); @@ -5883,7 +6292,7 @@ static bool brcms_c_valid_rate(struct brcms_c_info *wlc, u32 rspec, int band, return true; error: if (verbose) - brcms_err(wlc->hw->d11core, "wl%d: valid_rate: rate spec 0x%x " + wiphy_err(wlc->wiphy, "wl%d: valid_rate: rate spec 0x%x " "not in hw_rateset\n", wlc->pub->unit, rspec); return false; @@ -5893,7 +6302,6 @@ static u32 mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, u32 int_val) { - struct bcma_device *core = wlc->hw->d11core; u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT; u8 rate = int_val & NRATE_RATE_MASK; u32 rspec; @@ -5910,7 +6318,7 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, if ((wlc->pub->_n_enab & SUPPORT_11N) && ismcs) { /* mcs only allowed when nmode */ if (stf > PHY_TXC1_MODE_SDM) { - brcms_err(core, "wl%d: %s: Invalid stf\n", + wiphy_err(wlc->wiphy, "wl%d: %s: Invalid stf\n", wlc->pub->unit, __func__); bcmerror = -EINVAL; goto done; @@ -5921,8 +6329,8 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, if (!CHSPEC_IS40(wlc->home_chanspec) || ((stf != PHY_TXC1_MODE_SISO) && (stf != PHY_TXC1_MODE_CDD))) { - brcms_err(core, "wl%d: %s: Invalid mcs 32\n", - wlc->pub->unit, __func__); + wiphy_err(wlc->wiphy, "wl%d: %s: Invalid mcs " + "32\n", wlc->pub->unit, __func__); bcmerror = -EINVAL; goto done; } @@ -5930,9 +6338,9 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, } else if (rate > HIGHEST_SINGLE_STREAM_MCS) { /* mcs > 7 must use stf SDM */ if (stf != PHY_TXC1_MODE_SDM) { - brcms_dbg_mac80211(core, "wl%d: enabling " - "SDM mode for mcs %d\n", - wlc->pub->unit, rate); + BCMMSG(wlc->wiphy, "wl%d: enabling " + "SDM mode for mcs %d\n", + wlc->pub->unit, rate); stf = PHY_TXC1_MODE_SDM; } } else { @@ -5943,15 +6351,15 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, if ((stf > PHY_TXC1_MODE_STBC) || (!BRCMS_STBC_CAP_PHY(wlc) && (stf == PHY_TXC1_MODE_STBC))) { - brcms_err(core, "wl%d: %s: Invalid STBC\n", - wlc->pub->unit, __func__); + wiphy_err(wlc->wiphy, "wl%d: %s: Invalid STBC" + "\n", wlc->pub->unit, __func__); bcmerror = -EINVAL; goto done; } } } else if (is_ofdm_rate(rate)) { if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) { - brcms_err(core, "wl%d: %s: Invalid OFDM\n", + wiphy_err(wlc->wiphy, "wl%d: %s: Invalid OFDM\n", wlc->pub->unit, __func__); bcmerror = -EINVAL; goto done; @@ -5959,20 +6367,20 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, } else if (is_cck_rate(rate)) { if ((cur_band->bandtype != BRCM_BAND_2G) || (stf != PHY_TXC1_MODE_SISO)) { - brcms_err(core, "wl%d: %s: Invalid CCK\n", + wiphy_err(wlc->wiphy, "wl%d: %s: Invalid CCK\n", wlc->pub->unit, __func__); bcmerror = -EINVAL; goto done; } } else { - brcms_err(core, "wl%d: %s: Unknown rate type\n", + wiphy_err(wlc->wiphy, "wl%d: %s: Unknown rate type\n", wlc->pub->unit, __func__); bcmerror = -EINVAL; goto done; } /* make sure multiple antennae are available for non-siso rates */ if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) { - brcms_err(core, "wl%d: %s: SISO antenna but !SISO " + wiphy_err(wlc->wiphy, "wl%d: %s: SISO antenna but !SISO " "request\n", wlc->pub->unit, __func__); bcmerror = -EINVAL; goto done; @@ -6041,7 +6449,7 @@ static void brcms_c_cck_plcp_set(struct brcms_c_info *wlc, int rate_500, break; default: - brcms_err(wlc->hw->d11core, + wiphy_err(wlc->wiphy, "brcms_c_cck_plcp_set: unsupported rate %d\n", rate_500); rate_500 = BRCM_RATE_1M; @@ -6174,7 +6582,7 @@ static u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, u32 rspec) bw = rspec_get_bw(rspec); /* 10Mhz is not supported yet */ if (bw < PHY_TXC1_BW_20MHZ) { - brcms_err(wlc->hw->d11core, "phytxctl1_calc: bw %d is " + wiphy_err(wlc->wiphy, "phytxctl1_calc: bw %d is " "not supported yet, set to 20L\n", bw); bw = PHY_TXC1_BW_20MHZ; } @@ -6201,7 +6609,7 @@ static u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, u32 rspec) /* get the phyctl byte from rate phycfg table */ phycfg = brcms_c_rate_legacy_phyctl(rspec2rate(rspec)); if (phycfg == -1) { - brcms_err(wlc->hw->d11core, "phytxctl1_calc: wrong " + wiphy_err(wlc->wiphy, "phytxctl1_calc: wrong " "legacy OFDM/CCK rate\n"); phycfg = 0; } @@ -6281,9 +6689,8 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { /* non-AP STA should never use BCMC queue */ if (queue == TX_BCMC_FIFO) { - brcms_err(wlc->hw->d11core, - "wl%d: %s: ASSERT queue == TX_BCMC!\n", - wlc->pub->unit, __func__); + wiphy_err(wlc->wiphy, "wl%d: %s: ASSERT queue == " + "TX_BCMC!\n", wlc->pub->unit, __func__); frameid = bcmc_fid_generate(wlc, NULL, txh); } else { /* Increment the counter for first fragment */ @@ -6453,8 +6860,7 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, if ((txrate[k]->flags & IEEE80211_TX_RC_MCS) && (!is_mcs_rate(rspec[k]))) { - brcms_err(wlc->hw->d11core, - "wl%d: %s: IEEE80211_TX_" + wiphy_err(wlc->wiphy, "wl%d: %s: IEEE80211_TX_" "RC_MCS != is_mcs_rate(rspec)\n", wlc->pub->unit, __func__); } @@ -6848,16 +7254,14 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, wlc->fragthresh[queue] = (u16) newfragthresh; } else { - brcms_err(wlc->hw->d11core, - "wl%d: %s txop invalid " + wiphy_err(wlc->wiphy, "wl%d: %s txop invalid " "for rate %d\n", wlc->pub->unit, fifo_names[queue], rspec2rate(rspec[0])); } if (dur > wlc->edcf_txop[ac]) - brcms_err(wlc->hw->d11core, - "wl%d: %s: %s txop " + wiphy_err(wlc->wiphy, "wl%d: %s: %s txop " "exceeded phylen %d/%d dur %d/%d\n", wlc->pub->unit, __func__, fifo_names[queue], @@ -6869,33 +7273,79 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, return 0; } -static int brcms_c_tx(struct brcms_c_info *wlc, struct sk_buff *skb) +void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu, + struct ieee80211_hw *hw) { - struct dma_pub *dma; - int fifo, ret = -ENOSPC; - struct d11txh *txh; - u16 frameid = INVALIDFID; + u8 prio; + uint fifo; + struct scb *scb = &wlc->pri_scb; + struct ieee80211_hdr *d11_header = (struct ieee80211_hdr *)(sdu->data); - fifo = brcms_ac_to_fifo(skb_get_queue_mapping(skb)); - dma = wlc->hw->di[fifo]; - txh = (struct d11txh *)(skb->data); + /* + * 802.11 standard requires management traffic + * to go at highest priority + */ + prio = ieee80211_is_data(d11_header->frame_control) ? sdu->priority : + MAXPRIO; + fifo = prio2fifo[prio]; + if (brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0)) + return; + brcms_c_txq_enq(wlc, scb, sdu, BRCMS_PRIO_TO_PREC(prio)); + brcms_c_send_q(wlc); +} - if (dma->txavail == 0) { - /* - * We sometimes get a frame from mac80211 after stopping - * the queues. This only ever seems to be a single frame - * and is seems likely to be a race. TX_HEADROOM should - * ensure that we have enough space to handle these stray - * packets, so warn if there isn't. If we're out of space - * in the tx ring and the tx queue isn't stopped then - * we've really got a bug; warn loudly if that happens. - */ - brcms_warn(wlc->hw->d11core, - "Received frame for tx with no space in DMA ring\n"); - WARN_ON(!ieee80211_queue_stopped(wlc->pub->ieee_hw, - skb_get_queue_mapping(skb))); - return -ENOSPC; +void brcms_c_send_q(struct brcms_c_info *wlc) +{ + struct sk_buff *pkt[DOT11_MAXNUMFRAGS]; + int prec; + u16 prec_map; + int err = 0, i, count; + uint fifo; + struct brcms_txq_info *qi = wlc->pkt_queue; + struct pktq *q = &qi->q; + struct ieee80211_tx_info *tx_info; + + prec_map = wlc->tx_prec_map; + + /* Send all the enq'd pkts that we can. + * Dequeue packets with precedence with empty HW fifo only + */ + while (prec_map && (pkt[0] = brcmu_pktq_mdeq(q, prec_map, &prec))) { + tx_info = IEEE80211_SKB_CB(pkt[0]); + if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { + err = brcms_c_sendampdu(wlc->ampdu, qi, pkt, prec); + } else { + count = 1; + err = brcms_c_prep_pdu(wlc, pkt[0], &fifo); + if (!err) { + for (i = 0; i < count; i++) + brcms_c_txfifo(wlc, fifo, pkt[i], true, + 1); + } + } + + if (err == -EBUSY) { + brcmu_pktq_penq_head(q, prec, pkt[0]); + /* + * If send failed due to any other reason than a + * change in HW FIFO condition, quit. Otherwise, + * read the new prec_map! + */ + if (prec_map == wlc->tx_prec_map) + break; + prec_map = wlc->tx_prec_map; + } } +} + +void +brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p, + bool commit, s8 txpktpend) +{ + u16 frameid = INVALIDFID; + struct d11txh *txh; + + txh = (struct d11txh *) (p->data); /* When a BC/MC frame is being committed to the BCMC fifo * via DMA (NOT PIO), update ucode or BSS info as appropriate. @@ -6903,6 +7353,16 @@ static int brcms_c_tx(struct brcms_c_info *wlc, struct sk_buff *skb) if (fifo == TX_BCMC_FIFO) frameid = le16_to_cpu(txh->TxFrameID); + /* + * Bump up pending count for if not using rpc. If rpc is + * used, this will be handled in brcms_b_txfifo() + */ + if (commit) { + wlc->core->txpktpend[fifo] += txpktpend; + BCMMSG(wlc->wiphy, "pktpend inc %d to %d\n", + txpktpend, wlc->core->txpktpend[fifo]); + } + /* Commit BCMC sequence number in the SHM frame ID location */ if (frameid != INVALIDFID) { /* @@ -6912,55 +7372,8 @@ static int brcms_c_tx(struct brcms_c_info *wlc, struct sk_buff *skb) brcms_b_write_shm(wlc->hw, M_BCMC_FID, frameid); } - ret = brcms_c_txfifo(wlc, fifo, skb); - /* - * The only reason for brcms_c_txfifo to fail is because - * there weren't any DMA descriptors, but we've already - * checked for that. So if it does fail yell loudly. - */ - WARN_ON_ONCE(ret); - - return ret; -} - -bool brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu, - struct ieee80211_hw *hw) -{ - uint fifo; - struct scb *scb = &wlc->pri_scb; - - fifo = brcms_ac_to_fifo(skb_get_queue_mapping(sdu)); - brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0); - if (!brcms_c_tx(wlc, sdu)) - return true; - - /* packet discarded */ - dev_kfree_skb_any(sdu); - return false; -} - -int -brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p) -{ - struct dma_pub *dma = wlc->hw->di[fifo]; - int ret; - u16 queue; - - ret = dma_txfast(wlc, dma, p); - if (ret < 0) + if (dma_txfast(wlc->hw->di[fifo], p, commit) < 0) wiphy_err(wlc->wiphy, "txfifo: fatal, toss frames !!!\n"); - - /* - * Stop queue if DMA ring is full. Reserve some free descriptors, - * as we sometimes receive a frame from mac80211 after the queues - * are stopped. - */ - queue = skb_get_queue_mapping(p); - if (dma->txavail <= TX_HEADROOM && fifo < TX_BCMC_FIFO && - !ieee80211_queue_stopped(wlc->pub->ieee_hw, queue)) - ieee80211_stop_queue(wlc->pub->ieee_hw, queue); - - return ret; } u32 @@ -7010,6 +7423,19 @@ brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, u32 rspec, return rts_rspec; } +void +brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo, s8 txpktpend) +{ + wlc->core->txpktpend[fifo] -= txpktpend; + BCMMSG(wlc->wiphy, "pktpend dec %d to %d\n", txpktpend, + wlc->core->txpktpend[fifo]); + + /* There is more room; mark precedences related to this FIFO sendable */ + wlc->tx_prec_map |= wlc->fifo2prec_map[fifo]; + + /* figure out which bsscfg is being worked on... */ +} + /* Update beacon listen interval in shared memory */ static void brcms_c_bcn_li_upd(struct brcms_c_info *wlc) { @@ -7145,8 +7571,7 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh, rx_status->rate_idx = 11; break; default: - brcms_err(wlc->hw->d11core, - "%s: Unknown rate\n", __func__); + wiphy_err(wlc->wiphy, "%s: Unknown rate\n", __func__); } /* @@ -7165,7 +7590,7 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh, } else if (is_ofdm_rate(rspec)) { rx_status->flag |= RX_FLAG_SHORTPRE; } else { - brcms_err(wlc->hw->d11core, "%s: Unknown modulation\n", + wiphy_err(wlc->wiphy, "%s: Unknown modulation\n", __func__); } } @@ -7175,12 +7600,12 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh, if (rxh->RxStatus1 & RXS_DECERR) { rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC; - brcms_err(wlc->hw->d11core, "%s: RX_FLAG_FAILED_PLCP_CRC\n", + wiphy_err(wlc->wiphy, "%s: RX_FLAG_FAILED_PLCP_CRC\n", __func__); } if (rxh->RxStatus1 & RXS_FCSERR) { rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; - brcms_err(wlc->hw->d11core, "%s: RX_FLAG_FAILED_FCS_CRC\n", + wiphy_err(wlc->wiphy, "%s: RX_FLAG_FAILED_FCS_CRC\n", __func__); } } @@ -7224,6 +7649,9 @@ brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec, { uint nsyms, len = 0, kNdps; + BCMMSG(wlc->wiphy, "wl%d: rate %d, len%d\n", + wlc->pub->unit, rspec2rate(ratespec), mac_len); + if (is_mcs_rate(ratespec)) { uint mcs = ratespec & RSPEC_RATE_MASK; int tot_streams = (mcs_2_txstreams(mcs) + 1) + @@ -7455,6 +7883,35 @@ void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend) brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend); } +/* prepares pdu for transmission. returns BCM error codes */ +int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu, uint *fifop) +{ + uint fifo; + struct d11txh *txh; + struct ieee80211_hdr *h; + struct scb *scb; + + txh = (struct d11txh *) (pdu->data); + h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); + + /* get the pkt queue info. This was put at brcms_c_sendctl or + * brcms_c_send for PDU */ + fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK; + + scb = NULL; + + *fifop = fifo; + + /* return if insufficient dma resources */ + if (*wlc->core->txavail[fifo] < MAX_DMA_SEGS) { + /* Mark precedences related to this FIFO, unsendable */ + /* A fifo is full. Clear precedences related to that FIFO */ + wlc->tx_prec_map &= ~(wlc->fifo2prec_map[fifo]); + return -EBUSY; + } + return 0; +} + int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, uint *blocks) { @@ -7520,15 +7977,13 @@ int brcms_c_get_curband(struct brcms_c_info *wlc) void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop) { int timeout = 20; - int i; - /* Kick DMA to send any pending AMPDU */ - for (i = 0; i < ARRAY_SIZE(wlc->hw->di); i++) - if (wlc->hw->di[i]) - dma_txflush(wlc->hw->di[i]); + /* flush packet queue when requested */ + if (drop) + brcmu_pktq_flush(&wlc->pkt_queue->q, false, NULL, NULL); /* wait for queue and DMA fifos to run dry */ - while (brcms_txpktpendtot(wlc) > 0) { + while (!pktq_empty(&wlc->pkt_queue->q) || brcms_txpktpendtot(wlc) > 0) { brcms_msleep(wlc->wl, 1); if (--timeout == 0) @@ -7577,6 +8032,8 @@ static void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p) uint len; bool is_amsdu; + BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); + /* frame starts with rxhdr */ rxh = (struct d11rxhdr *) (p->data); @@ -7586,9 +8043,8 @@ static void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p) /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */ if (rxh->RxStatus1 & RXS_PBPRES) { if (p->len < 2) { - brcms_err(wlc->hw->d11core, - "wl%d: recv: rcvd runt of len %d\n", - wlc->pub->unit, p->len); + wiphy_err(wlc->wiphy, "wl%d: recv: rcvd runt of " + "len %d\n", wlc->pub->unit, p->len); goto toss; } skb_pull(p, 2); @@ -7632,19 +8088,17 @@ brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound) uint n = 0; uint bound_limit = bound ? RXBND : -1; - bool morepending; + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); skb_queue_head_init(&recv_frames); /* gather received frames */ - do { + while (dma_rx(wlc_hw->di[fifo], &recv_frames)) { + /* !give others some time to run! */ - if (n >= bound_limit) + if (++n >= bound_limit) break; - - morepending = dma_rx(wlc_hw->di[fifo], &recv_frames); - n++; - } while (morepending); + } /* post more rbufs */ dma_rxfill(wlc_hw->di[fifo]); @@ -7674,7 +8128,7 @@ brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound) brcms_c_recv(wlc_hw->wlc, p); } - return morepending; + return n >= bound_limit; } /* second-level interrupt processing @@ -7686,9 +8140,10 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) u32 macintstatus; struct brcms_hardware *wlc_hw = wlc->hw; struct bcma_device *core = wlc_hw->d11core; + struct wiphy *wiphy = wlc->wiphy; if (brcms_deviceremoved(wlc)) { - brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, + wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, __func__); brcms_down(wlc->wl); return false; @@ -7698,8 +8153,8 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) macintstatus = wlc->macintstatus; wlc->macintstatus = 0; - brcms_dbg_int(core, "wl%d: macintstatus 0x%x\n", - wlc_hw->unit, macintstatus); + BCMMSG(wlc->wiphy, "wl%d: macintstatus 0x%x\n", + wlc_hw->unit, macintstatus); WARN_ON(macintstatus & MI_PRQ); /* PRQ Interrupt in non-MBSS */ @@ -7709,7 +8164,7 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) if (brcms_b_txstatus(wlc->hw, bounded, &fatal)) wlc->macintstatus |= MI_TFS; if (fatal) { - brcms_err(core, "MI_TFS: fatal\n"); + wiphy_err(wiphy, "MI_TFS: fatal\n"); goto fatal; } } @@ -7719,7 +8174,7 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) /* ATIM window end */ if (macintstatus & MI_ATIMWINEND) { - brcms_dbg_info(core, "end of ATIM window\n"); + BCMMSG(wlc->wiphy, "end of ATIM window\n"); bcma_set32(core, D11REGOFFS(maccommand), wlc->qvalid); wlc->qvalid = 0; } @@ -7737,7 +8192,7 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) wlc_phy_noise_sample_intr(wlc_hw->band->pi); if (macintstatus & MI_GP0) { - brcms_err(core, "wl%d: PSM microcode watchdog fired at %d " + wiphy_err(wiphy, "wl%d: PSM microcode watchdog fired at %d " "(seconds). Resetting.\n", wlc_hw->unit, wlc_hw->now); printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", @@ -7751,11 +8206,15 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) bcma_write32(core, D11REGOFFS(gptimer), 0); if (macintstatus & MI_RFDISABLE) { - brcms_dbg_info(core, "wl%d: BMAC Detected a change on the" - " RF Disable Input\n", wlc_hw->unit); + BCMMSG(wlc->wiphy, "wl%d: BMAC Detected a change on the" + " RF Disable Input\n", wlc_hw->unit); brcms_rfkill_set_hw_state(wlc->wl); } + /* send any enq'd tx packets. Just makes sure to jump start tx */ + if (!pktq_empty(&wlc->pkt_queue->q)) + brcms_c_send_q(wlc); + /* it isn't done and needs to be resched if macintstatus is non-zero */ return wlc->macintstatus != 0; @@ -7770,7 +8229,7 @@ void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx) struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel; u16 chanspec; - brcms_dbg_info(core, "wl%d\n", wlc->pub->unit); + BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); chanspec = ch20mhz_chspec(ch->hw_value); @@ -7827,6 +8286,9 @@ void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx) bcma_set16(core, D11REGOFFS(ifs_ctl), IFS_USEEDCF); brcms_c_edcf_setparams(wlc, false); + /* Init precedence maps for empty FIFOs */ + brcms_c_tx_prec_map_init(wlc); + /* read the ucode version if we have not yet done so */ if (wlc->ucode_rev == 0) { wlc->ucode_rev = @@ -7841,6 +8303,9 @@ void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx) if (mute_tx) brcms_b_mute(wlc->hw, true); + /* clear tx flow control */ + brcms_c_txflowcontrol_reset(wlc); + /* enable the RF Disable Delay timer */ bcma_write32(core, D11REGOFFS(rfdisabledly), RFDISABLE_DEFAULT); @@ -7999,6 +8464,15 @@ brcms_c_attach(struct brcms_info *wl, struct bcma_device *core, uint unit, * Complete the wlc default state initializations.. */ + /* allocate our initial queue */ + wlc->pkt_queue = brcms_c_txq_alloc(wlc); + if (wlc->pkt_queue == NULL) { + wiphy_err(wl->wiphy, "wl%d: %s: failed to malloc tx queue\n", + unit, __func__); + err = 100; + goto fail; + } + wlc->bsscfg->wlc = wlc; wlc->mimoft = FT_HT; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.h b/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.h index fb447747c2c6..8debc74c54e1 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.h @@ -101,6 +101,9 @@ #define DATA_BLOCK_TX_SUPR (1 << 4) +/* 802.1D Priority to TX FIFO number for wme */ +extern const u8 prio2fifo[]; + /* Ucode MCTL_WAKE override bits */ #define BRCMS_WAKE_OVERRIDE_CLKCTL 0x01 #define BRCMS_WAKE_OVERRIDE_PHYREG 0x02 @@ -239,6 +242,7 @@ struct brcms_core { /* fifo */ uint *txavail[NFIFO]; /* # tx descriptors available */ + s16 txpktpend[NFIFO]; /* tx admission control */ struct macstat *macstat_snapshot; /* mac hw prev read values */ }; @@ -378,6 +382,19 @@ struct brcms_hardware { */ }; +/* TX Queue information + * + * Each flow of traffic out of the device has a TX Queue with independent + * flow control. Several interfaces may be associated with a single TX Queue + * if they belong to the same flow of traffic from the device. For multi-channel + * operation there are independent TX Queues for each channel. + */ +struct brcms_txq_info { + struct brcms_txq_info *next; + struct pktq q; + uint stopped; /* tx flow control bits */ +}; + /* * Principal common driver data structure. * @@ -418,8 +435,11 @@ struct brcms_hardware { * WDlast: last time wlc_watchdog() was called. * edcf_txop[IEEE80211_NUM_ACS]: current txop for each ac. * wme_retries: per-AC retry limits. + * tx_prec_map: Precedence map based on HW FIFO space. + * fifo2prec_map[NFIFO]: pointer to fifo2_prec map based on WME. * bsscfg: set of BSS configurations, idx 0 is default and always valid. * cfg: the primary bsscfg (can be AP or STA). + * tx_queues: common TX Queue list. * modulecb: * mimoft: SIGN or 11N. * cck_40txbw: 11N, cck tx b/w override when in 40MHZ mode. @@ -449,6 +469,7 @@ struct brcms_hardware { * tempsense_lasttime; * tx_duty_cycle_ofdm: maximum allowed duty cycle for OFDM. * tx_duty_cycle_cck: maximum allowed duty cycle for CCK. + * pkt_queue: txq for transmit packets. * wiphy: * pri_scb: primary Station Control Block */ @@ -512,9 +533,14 @@ struct brcms_c_info { u16 edcf_txop[IEEE80211_NUM_ACS]; u16 wme_retries[IEEE80211_NUM_ACS]; + u16 tx_prec_map; + u16 fifo2prec_map[NFIFO]; struct brcms_bss_cfg *bsscfg; + /* tx queue */ + struct brcms_txq_info *tx_queues; + struct modulecb *modulecb; u8 mimoft; @@ -559,6 +585,7 @@ struct brcms_c_info { u16 tx_duty_cycle_ofdm; u16 tx_duty_cycle_cck; + struct brcms_txq_info *pkt_queue; struct wiphy *wiphy; struct scb pri_scb; }; @@ -610,13 +637,30 @@ struct brcms_bss_cfg { struct brcms_bss_info *current_bss; }; -extern int brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, - struct sk_buff *p); +extern void brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, + struct sk_buff *p, + bool commit, s8 txpktpend); +extern void brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo, + s8 txpktpend); +extern void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb, + struct sk_buff *sdu, uint prec); +extern void brcms_c_print_txstatus(struct tx_status *txs); extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, uint *blocks); +#if defined(DEBUG) +extern void brcms_c_print_txdesc(struct d11txh *txh); +#else +static inline void brcms_c_print_txdesc(struct d11txh *txh) +{ +} +#endif + extern int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config); extern void brcms_c_mac_promisc(struct brcms_c_info *wlc, uint filter_flags); +extern void brcms_c_send_q(struct brcms_c_info *wlc); +extern int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu, + uint *fifo); extern u16 brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec, uint mac_len); extern u32 brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c index 606b534347bc..abfd78822fb8 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c @@ -1137,9 +1137,8 @@ wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi, gain0_15 = ((biq1 & 0xf) << 12) | ((tia & 0xf) << 8) | ((lna2 & 0x3) << 6) | - ((lna2 & 0x3) << 4) | - ((lna1 & 0x3) << 2) | - ((lna1 & 0x3) << 0); + ((lna2 & + 0x3) << 4) | ((lna1 & 0x3) << 2) | ((lna1 & 0x3) << 0); mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0); mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0); @@ -1157,8 +1156,6 @@ wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi, } mod_phy_reg(pi, 0x44d, (0x1 << 0), (!trsw) << 0); - mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11); - mod_phy_reg(pi, 0x4e6, (0x3 << 3), lna1 << 3); } @@ -1331,43 +1328,6 @@ static u32 wlc_lcnphy_measure_digital_power(struct brcms_phy *pi, u16 nsamples) return (iq_est.i_pwr + iq_est.q_pwr) / nsamples; } -static bool wlc_lcnphy_rx_iq_cal_gain(struct brcms_phy *pi, u16 biq1_gain, - u16 tia_gain, u16 lna2_gain) -{ - u32 i_thresh_l, q_thresh_l; - u32 i_thresh_h, q_thresh_h; - struct lcnphy_iq_est iq_est_h, iq_est_l; - - wlc_lcnphy_set_rx_gain_by_distribution(pi, 0, 0, 0, biq1_gain, tia_gain, - lna2_gain, 0); - - wlc_lcnphy_rx_gain_override_enable(pi, true); - wlc_lcnphy_start_tx_tone(pi, 2000, (40 >> 1), 0); - usleep_range(500, 500); - write_radio_reg(pi, RADIO_2064_REG112, 0); - if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_l)) - return false; - - wlc_lcnphy_start_tx_tone(pi, 2000, 40, 0); - usleep_range(500, 500); - write_radio_reg(pi, RADIO_2064_REG112, 0); - if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_h)) - return false; - - i_thresh_l = (iq_est_l.i_pwr << 1); - i_thresh_h = (iq_est_l.i_pwr << 2) + iq_est_l.i_pwr; - - q_thresh_l = (iq_est_l.q_pwr << 1); - q_thresh_h = (iq_est_l.q_pwr << 2) + iq_est_l.q_pwr; - if ((iq_est_h.i_pwr > i_thresh_l) && - (iq_est_h.i_pwr < i_thresh_h) && - (iq_est_h.q_pwr > q_thresh_l) && - (iq_est_h.q_pwr < q_thresh_h)) - return true; - - return false; -} - static bool wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi, const struct lcnphy_rx_iqcomp *iqcomp, @@ -1382,8 +1342,8 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi, RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old, rfoverride3_old, rfoverride3val_old, rfoverride4_old, rfoverride4val_old, afectrlovr_old, afectrlovrval_old; - int tia_gain, lna2_gain, biq1_gain; - bool set_gain; + int tia_gain; + u32 received_power, rx_pwr_threshold; u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl; u16 values_to_save[11]; s16 *ptr; @@ -1408,134 +1368,126 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi, goto cal_done; } - WARN_ON(module != 1); - tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); - wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); - - for (i = 0; i < 11; i++) - values_to_save[i] = - read_radio_reg(pi, rxiq_cal_rf_reg[i]); - Core1TxControl_old = read_phy_reg(pi, 0x631); - - or_phy_reg(pi, 0x631, 0x0015); - - RFOverride0_old = read_phy_reg(pi, 0x44c); - RFOverrideVal0_old = read_phy_reg(pi, 0x44d); - rfoverride2_old = read_phy_reg(pi, 0x4b0); - rfoverride2val_old = read_phy_reg(pi, 0x4b1); - rfoverride3_old = read_phy_reg(pi, 0x4f9); - rfoverride3val_old = read_phy_reg(pi, 0x4fa); - rfoverride4_old = read_phy_reg(pi, 0x938); - rfoverride4val_old = read_phy_reg(pi, 0x939); - afectrlovr_old = read_phy_reg(pi, 0x43b); - afectrlovrval_old = read_phy_reg(pi, 0x43c); - old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da); - old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db); - - tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi); - if (tx_gain_override_old) { - wlc_lcnphy_get_tx_gain(pi, &old_gains); - tx_gain_index_old = pi_lcn->lcnphy_current_index; - } - - wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx); + if (module == 1) { - mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0); - mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0); + tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); + wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); - mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1); - mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1); + for (i = 0; i < 11; i++) + values_to_save[i] = + read_radio_reg(pi, rxiq_cal_rf_reg[i]); + Core1TxControl_old = read_phy_reg(pi, 0x631); + + or_phy_reg(pi, 0x631, 0x0015); + + RFOverride0_old = read_phy_reg(pi, 0x44c); + RFOverrideVal0_old = read_phy_reg(pi, 0x44d); + rfoverride2_old = read_phy_reg(pi, 0x4b0); + rfoverride2val_old = read_phy_reg(pi, 0x4b1); + rfoverride3_old = read_phy_reg(pi, 0x4f9); + rfoverride3val_old = read_phy_reg(pi, 0x4fa); + rfoverride4_old = read_phy_reg(pi, 0x938); + rfoverride4val_old = read_phy_reg(pi, 0x939); + afectrlovr_old = read_phy_reg(pi, 0x43b); + afectrlovrval_old = read_phy_reg(pi, 0x43c); + old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da); + old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db); + + tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi); + if (tx_gain_override_old) { + wlc_lcnphy_get_tx_gain(pi, &old_gains); + tx_gain_index_old = pi_lcn->lcnphy_current_index; + } - write_radio_reg(pi, RADIO_2064_REG116, 0x06); - write_radio_reg(pi, RADIO_2064_REG12C, 0x07); - write_radio_reg(pi, RADIO_2064_REG06A, 0xd3); - write_radio_reg(pi, RADIO_2064_REG098, 0x03); - write_radio_reg(pi, RADIO_2064_REG00B, 0x7); - mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4); - write_radio_reg(pi, RADIO_2064_REG01D, 0x01); - write_radio_reg(pi, RADIO_2064_REG114, 0x01); - write_radio_reg(pi, RADIO_2064_REG02E, 0x10); - write_radio_reg(pi, RADIO_2064_REG12A, 0x08); - - mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0); - mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0); - mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1); - mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1); - mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2); - mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2); - mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3); - mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3); - mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5); - mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5); + wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx); - mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0); - mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0); + mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0); + mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0); - write_phy_reg(pi, 0x6da, 0xffff); - or_phy_reg(pi, 0x6db, 0x3); + mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1); + mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1); - wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch); - set_gain = false; - - lna2_gain = 3; - while ((lna2_gain >= 0) && !set_gain) { - tia_gain = 4; - - while ((tia_gain >= 0) && !set_gain) { - biq1_gain = 6; - - while ((biq1_gain >= 0) && !set_gain) { - set_gain = wlc_lcnphy_rx_iq_cal_gain(pi, - (u16) - biq1_gain, - (u16) - tia_gain, - (u16) - lna2_gain); - biq1_gain -= 1; - } + write_radio_reg(pi, RADIO_2064_REG116, 0x06); + write_radio_reg(pi, RADIO_2064_REG12C, 0x07); + write_radio_reg(pi, RADIO_2064_REG06A, 0xd3); + write_radio_reg(pi, RADIO_2064_REG098, 0x03); + write_radio_reg(pi, RADIO_2064_REG00B, 0x7); + mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4); + write_radio_reg(pi, RADIO_2064_REG01D, 0x01); + write_radio_reg(pi, RADIO_2064_REG114, 0x01); + write_radio_reg(pi, RADIO_2064_REG02E, 0x10); + write_radio_reg(pi, RADIO_2064_REG12A, 0x08); + + mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0); + mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0); + mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1); + mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1); + mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2); + mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2); + mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3); + mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3); + mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5); + mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5); + + mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0); + mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0); + + wlc_lcnphy_start_tx_tone(pi, 2000, 120, 0); + write_phy_reg(pi, 0x6da, 0xffff); + or_phy_reg(pi, 0x6db, 0x3); + wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch); + wlc_lcnphy_rx_gain_override_enable(pi, true); + + tia_gain = 8; + rx_pwr_threshold = 950; + while (tia_gain > 0) { tia_gain -= 1; + wlc_lcnphy_set_rx_gain_by_distribution(pi, + 0, 0, 2, 2, + (u16) + tia_gain, 1, 0); + udelay(500); + + received_power = + wlc_lcnphy_measure_digital_power(pi, 2000); + if (received_power < rx_pwr_threshold) + break; } - lna2_gain -= 1; - } + result = wlc_lcnphy_calc_rx_iq_comp(pi, 0xffff); - if (set_gain) - result = wlc_lcnphy_calc_rx_iq_comp(pi, 1024); - else - result = false; + wlc_lcnphy_stop_tx_tone(pi); - wlc_lcnphy_stop_tx_tone(pi); + write_phy_reg(pi, 0x631, Core1TxControl_old); - write_phy_reg(pi, 0x631, Core1TxControl_old); - - write_phy_reg(pi, 0x44c, RFOverrideVal0_old); - write_phy_reg(pi, 0x44d, RFOverrideVal0_old); - write_phy_reg(pi, 0x4b0, rfoverride2_old); - write_phy_reg(pi, 0x4b1, rfoverride2val_old); - write_phy_reg(pi, 0x4f9, rfoverride3_old); - write_phy_reg(pi, 0x4fa, rfoverride3val_old); - write_phy_reg(pi, 0x938, rfoverride4_old); - write_phy_reg(pi, 0x939, rfoverride4val_old); - write_phy_reg(pi, 0x43b, afectrlovr_old); - write_phy_reg(pi, 0x43c, afectrlovrval_old); - write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl); - write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl); + write_phy_reg(pi, 0x44c, RFOverrideVal0_old); + write_phy_reg(pi, 0x44d, RFOverrideVal0_old); + write_phy_reg(pi, 0x4b0, rfoverride2_old); + write_phy_reg(pi, 0x4b1, rfoverride2val_old); + write_phy_reg(pi, 0x4f9, rfoverride3_old); + write_phy_reg(pi, 0x4fa, rfoverride3val_old); + write_phy_reg(pi, 0x938, rfoverride4_old); + write_phy_reg(pi, 0x939, rfoverride4val_old); + write_phy_reg(pi, 0x43b, afectrlovr_old); + write_phy_reg(pi, 0x43c, afectrlovrval_old); + write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl); + write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl); - wlc_lcnphy_clear_trsw_override(pi); + wlc_lcnphy_clear_trsw_override(pi); - mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2); + mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2); - for (i = 0; i < 11; i++) - write_radio_reg(pi, rxiq_cal_rf_reg[i], - values_to_save[i]); + for (i = 0; i < 11; i++) + write_radio_reg(pi, rxiq_cal_rf_reg[i], + values_to_save[i]); - if (tx_gain_override_old) - wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old); - else - wlc_lcnphy_disable_tx_gain_override(pi); + if (tx_gain_override_old) + wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old); + else + wlc_lcnphy_disable_tx_gain_override(pi); - wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl); - wlc_lcnphy_rx_gain_override_enable(pi, false); + wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl); + wlc_lcnphy_rx_gain_override_enable(pi, false); + } cal_done: kfree(ptr); @@ -1829,17 +1781,6 @@ wlc_lcnphy_radio_2064_channel_tune_4313(struct brcms_phy *pi, u8 channel) write_radio_reg(pi, RADIO_2064_REG038, 3); write_radio_reg(pi, RADIO_2064_REG091, 7); } - - if (!(pi->sh->boardflags & BFL_FEM)) { - u8 reg038[14] = {0xd, 0xe, 0xd, 0xd, 0xd, 0xc, - 0xa, 0xb, 0xb, 0x3, 0x3, 0x2, 0x0, 0x0}; - - write_radio_reg(pi, RADIO_2064_REG02A, 0xf); - write_radio_reg(pi, RADIO_2064_REG091, 0x3); - write_radio_reg(pi, RADIO_2064_REG038, 0x3); - - write_radio_reg(pi, RADIO_2064_REG038, reg038[channel - 1]); - } } static int @@ -1919,6 +1860,41 @@ wlc_lcnphy_load_tx_iir_filter(struct brcms_phy *pi, bool is_ofdm, s16 filt_type) return (filt_index != -1) ? 0 : -1; } +void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, u16 chanspec) +{ + u8 channel = CHSPEC_CHANNEL(chanspec); + + wlc_phy_chanspec_radio_set((struct brcms_phy_pub *) pi, chanspec); + + wlc_lcnphy_set_chanspec_tweaks(pi, pi->radio_chanspec); + + or_phy_reg(pi, 0x44a, 0x44); + write_phy_reg(pi, 0x44a, 0x80); + + wlc_lcnphy_radio_2064_channel_tune_4313(pi, channel); + udelay(1000); + + wlc_lcnphy_toggle_afe_pwdn(pi); + + write_phy_reg(pi, 0x657, lcnphy_sfo_cfg[channel - 1].ptcentreTs20); + write_phy_reg(pi, 0x658, lcnphy_sfo_cfg[channel - 1].ptcentreFactor); + + if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) { + mod_phy_reg(pi, 0x448, (0x3 << 8), (2) << 8); + + wlc_lcnphy_load_tx_iir_filter(pi, false, 3); + } else { + mod_phy_reg(pi, 0x448, (0x3 << 8), (1) << 8); + + wlc_lcnphy_load_tx_iir_filter(pi, false, 2); + } + + wlc_lcnphy_load_tx_iir_filter(pi, true, 0); + + mod_phy_reg(pi, 0x4eb, (0x7 << 3), (1) << 3); + +} + static u16 wlc_lcnphy_get_pa_gain(struct brcms_phy *pi) { u16 pa_gain; @@ -1960,21 +1936,6 @@ static void wlc_lcnphy_set_tx_gain(struct brcms_phy *pi, wlc_lcnphy_enable_tx_gain_override(pi); } -static u8 wlc_lcnphy_get_bbmult(struct brcms_phy *pi) -{ - u16 m0m1; - struct phytbl_info tab; - - tab.tbl_ptr = &m0m1; - tab.tbl_len = 1; - tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL; - tab.tbl_offset = 87; - tab.tbl_width = 16; - wlc_lcnphy_read_table(pi, &tab); - - return (u8) ((m0m1 & 0xff00) >> 8); -} - static void wlc_lcnphy_set_bbmult(struct brcms_phy *pi, u8 m0) { u16 m0m1 = (u16) m0 << 8; @@ -2034,16 +1995,6 @@ wlc_lcnphy_set_tssi_mux(struct brcms_phy *pi, enum lcnphy_tssi_mode pos) } else { mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0x1); mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8); - mod_radio_reg(pi, RADIO_2064_REG028, 0x1, 0x0); - mod_radio_reg(pi, RADIO_2064_REG11A, 0x4, 1<<2); - mod_radio_reg(pi, RADIO_2064_REG036, 0x10, 0x0); - mod_radio_reg(pi, RADIO_2064_REG11A, 0x10, 1<<4); - mod_radio_reg(pi, RADIO_2064_REG036, 0x3, 0x0); - mod_radio_reg(pi, RADIO_2064_REG035, 0xff, 0x77); - mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0xe<<1); - mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 1<<7); - mod_radio_reg(pi, RADIO_2064_REG005, 0x7, 1<<1); - mod_radio_reg(pi, RADIO_2064_REG029, 0xf0, 0<<4); } } else { mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0x1) << 2); @@ -2130,14 +2081,12 @@ static void wlc_lcnphy_pwrctrl_rssiparams(struct brcms_phy *pi) (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12)); mod_radio_reg(pi, RADIO_2064_REG082, (1 << 5), (1 << 5)); - mod_radio_reg(pi, RADIO_2064_REG07C, (1 << 0), (1 << 0)); } static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi) { struct phytbl_info tab; u32 rfseq, ind; - u8 tssi_sel; tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; tab.tbl_width = 32; @@ -2159,13 +2108,7 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi) mod_phy_reg(pi, 0x503, (0x1 << 4), (1) << 4); - if (pi->sh->boardflags & BFL_FEM) { - tssi_sel = 0x1; - wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT); - } else { - tssi_sel = 0xe; - wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_POST_PA); - } + wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT); mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14); mod_phy_reg(pi, 0x4a4, (0x1 << 15), (1) << 15); @@ -2201,10 +2144,9 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi) mod_phy_reg(pi, 0x49a, (0x1ff << 0), (0xff) << 0); if (LCNREV_IS(pi->pubpi.phy_rev, 2)) { - mod_radio_reg(pi, RADIO_2064_REG028, 0xf, tssi_sel); + mod_radio_reg(pi, RADIO_2064_REG028, 0xf, 0xe); mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4); } else { - mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, tssi_sel << 1); mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1); mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 1 << 3); } @@ -2251,10 +2193,6 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi) mod_phy_reg(pi, 0x4d7, (0xf << 8), (0) << 8); - mod_radio_reg(pi, RADIO_2064_REG035, 0xff, 0x0); - mod_radio_reg(pi, RADIO_2064_REG036, 0x3, 0x0); - mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8); - wlc_lcnphy_pwrctrl_rssiparams(pi); } @@ -2873,8 +2811,6 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi) read_radio_reg(pi, RADIO_2064_REG007) & 1; u16 SAVE_jtag_auxpga = read_radio_reg(pi, RADIO_2064_REG0FF) & 0x10; u16 SAVE_iqadc_aux_en = read_radio_reg(pi, RADIO_2064_REG11F) & 4; - u8 SAVE_bbmult = wlc_lcnphy_get_bbmult(pi); - idleTssi = read_phy_reg(pi, 0x4ab); suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) & MCTL_EN_MAC)); @@ -2892,12 +2828,6 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi) mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 1 << 4); mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 1 << 2); wlc_lcnphy_tssi_setup(pi); - - mod_phy_reg(pi, 0x4d7, (0x1 << 0), (1 << 0)); - mod_phy_reg(pi, 0x4d7, (0x1 << 6), (1 << 6)); - - wlc_lcnphy_set_bbmult(pi, 0x0); - wlc_phy_do_dummy_tx(pi, true, OFF); idleTssi = ((read_phy_reg(pi, 0x4ab) & (0x1ff << 0)) >> 0); @@ -2919,7 +2849,6 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi) mod_phy_reg(pi, 0x44c, (0x1 << 12), (0) << 12); - wlc_lcnphy_set_bbmult(pi, SAVE_bbmult); wlc_lcnphy_set_tx_gain_override(pi, tx_gain_override_old); wlc_lcnphy_set_tx_gain(pi, &old_gains); wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl); @@ -3133,11 +3062,6 @@ static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi) wlc_lcnphy_write_table(pi, &tab); tab.tbl_offset++; } - mod_phy_reg(pi, 0x4d0, (0x1 << 0), (0) << 0); - mod_phy_reg(pi, 0x4d3, (0xff << 0), (0) << 0); - mod_phy_reg(pi, 0x4d3, (0xff << 8), (0) << 8); - mod_phy_reg(pi, 0x4d0, (0x1 << 4), (0) << 4); - mod_phy_reg(pi, 0x4d0, (0x1 << 2), (0) << 2); mod_phy_reg(pi, 0x410, (0x1 << 7), (0) << 7); @@ -3151,6 +3075,21 @@ static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi) wlapi_enable_mac(pi->sh->physhim); } +static u8 wlc_lcnphy_get_bbmult(struct brcms_phy *pi) +{ + u16 m0m1; + struct phytbl_info tab; + + tab.tbl_ptr = &m0m1; + tab.tbl_len = 1; + tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL; + tab.tbl_offset = 87; + tab.tbl_width = 16; + wlc_lcnphy_read_table(pi, &tab); + + return (u8) ((m0m1 & 0xff00) >> 8); +} + static void wlc_lcnphy_set_pa_gain(struct brcms_phy *pi, u16 gain) { mod_phy_reg(pi, 0x4fb, @@ -3939,6 +3878,7 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi) target_gains.pad_gain = 21; target_gains.dac_gain = 0; wlc_lcnphy_set_tx_gain(pi, &target_gains); + wlc_lcnphy_set_tx_pwr_by_index(pi, 16); if (LCNREV_IS(pi->pubpi.phy_rev, 1) || pi_lcn->lcnphy_hw_iqcal_en) { @@ -3949,7 +3889,6 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi) lcnphy_recal ? LCNPHY_CAL_RECAL : LCNPHY_CAL_FULL), false); } else { - wlc_lcnphy_set_tx_pwr_by_index(pi, 16); wlc_lcnphy_tx_iqlo_soft_cal_full(pi); } @@ -4374,22 +4313,17 @@ wlc_lcnphy_load_tx_gain_table(struct brcms_phy *pi, if (CHSPEC_IS5G(pi->radio_chanspec)) pa_gain = 0x70; else - pa_gain = 0x60; + pa_gain = 0x70; if (pi->sh->boardflags & BFL_FEM) pa_gain = 0x10; - tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; tab.tbl_width = 32; tab.tbl_len = 1; tab.tbl_ptr = &val; for (j = 0; j < 128; j++) { - if (pi->sh->boardflags & BFL_FEM) - gm_gain = gain_table[j].gm; - else - gm_gain = 15; - + gm_gain = gain_table[j].gm; val = (((u32) pa_gain << 24) | (gain_table[j].pad << 16) | (gain_table[j].pga << 8) | gm_gain); @@ -4600,10 +4534,7 @@ static void wlc_radio_2064_init(struct brcms_phy *pi) write_phy_reg(pi, 0x4ea, 0x4688); - if (pi->sh->boardflags & BFL_FEM) - mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0); - else - mod_phy_reg(pi, 0x4eb, (0x7 << 0), 3 << 0); + mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0); mod_phy_reg(pi, 0x4eb, (0x7 << 6), 0 << 6); @@ -4614,13 +4545,6 @@ static void wlc_radio_2064_init(struct brcms_phy *pi) wlc_lcnphy_rcal(pi); wlc_lcnphy_rc_cal(pi); - - if (!(pi->sh->boardflags & BFL_FEM)) { - write_radio_reg(pi, RADIO_2064_REG032, 0x6f); - write_radio_reg(pi, RADIO_2064_REG033, 0x19); - write_radio_reg(pi, RADIO_2064_REG039, 0xe); - } - } static void wlc_lcnphy_radio_init(struct brcms_phy *pi) @@ -4650,20 +4574,22 @@ static void wlc_lcnphy_tbl_init(struct brcms_phy *pi) wlc_lcnphy_write_table(pi, &tab); } - if (!(pi->sh->boardflags & BFL_FEM)) { - tab.tbl_id = LCNPHY_TBL_ID_RFSEQ; - tab.tbl_width = 16; - tab.tbl_ptr = &val; - tab.tbl_len = 1; + tab.tbl_id = LCNPHY_TBL_ID_RFSEQ; + tab.tbl_width = 16; + tab.tbl_ptr = &val; + tab.tbl_len = 1; - val = 150; - tab.tbl_offset = 0; - wlc_lcnphy_write_table(pi, &tab); + val = 114; + tab.tbl_offset = 0; + wlc_lcnphy_write_table(pi, &tab); - val = 220; - tab.tbl_offset = 1; - wlc_lcnphy_write_table(pi, &tab); - } + val = 130; + tab.tbl_offset = 1; + wlc_lcnphy_write_table(pi, &tab); + + val = 6; + tab.tbl_offset = 8; + wlc_lcnphy_write_table(pi, &tab); if (CHSPEC_IS2G(pi->radio_chanspec)) { if (pi->sh->boardflags & BFL_FEM) @@ -5020,44 +4946,6 @@ void wlc_phy_txpower_recalc_target_lcnphy(struct brcms_phy *pi) } } -void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, u16 chanspec) -{ - u8 channel = CHSPEC_CHANNEL(chanspec); - - wlc_phy_chanspec_radio_set((struct brcms_phy_pub *)pi, chanspec); - - wlc_lcnphy_set_chanspec_tweaks(pi, pi->radio_chanspec); - - or_phy_reg(pi, 0x44a, 0x44); - write_phy_reg(pi, 0x44a, 0x80); - - wlc_lcnphy_radio_2064_channel_tune_4313(pi, channel); - udelay(1000); - - wlc_lcnphy_toggle_afe_pwdn(pi); - - write_phy_reg(pi, 0x657, lcnphy_sfo_cfg[channel - 1].ptcentreTs20); - write_phy_reg(pi, 0x658, lcnphy_sfo_cfg[channel - 1].ptcentreFactor); - - if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) { - mod_phy_reg(pi, 0x448, (0x3 << 8), (2) << 8); - - wlc_lcnphy_load_tx_iir_filter(pi, false, 3); - } else { - mod_phy_reg(pi, 0x448, (0x3 << 8), (1) << 8); - - wlc_lcnphy_load_tx_iir_filter(pi, false, 2); - } - - if (pi->sh->boardflags & BFL_FEM) - wlc_lcnphy_load_tx_iir_filter(pi, true, 0); - else - wlc_lcnphy_load_tx_iir_filter(pi, true, 3); - - mod_phy_reg(pi, 0x4eb, (0x7 << 3), (1) << 3); - wlc_lcnphy_tssi_setup(pi); -} - void wlc_phy_detach_lcnphy(struct brcms_phy *pi) { kfree(pi->u.pi_lcnphy); @@ -5094,7 +4982,8 @@ bool wlc_phy_attach_lcnphy(struct brcms_phy *pi) if (!wlc_phy_txpwr_srom_read_lcnphy(pi)) return false; - if (LCNREV_IS(pi->pubpi.phy_rev, 1)) { + if ((pi->sh->boardflags & BFL_FEM) && + (LCNREV_IS(pi->pubpi.phy_rev, 1))) { if (pi_lcn->lcnphy_tempsense_option == 3) { pi->hwpwrctrl = true; pi->hwpwrctrl_capable = true; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c index b7e95acc2084..622c01ca72c5 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c @@ -1992,70 +1992,70 @@ static const u16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0[] = { }; static const u16 dot11lcn_sw_ctrl_tbl_4313_rev0[] = { - 0x0009, 0x000a, - 0x0005, - 0x0006, 0x0009, - 0x000a, - 0x0005, 0x0006, - 0x0009, - 0x000a, 0x0005, - 0x0006, - 0x0009, 0x000a, - 0x0005, - 0x0006, 0x0009, - 0x000a, - 0x0005, 0x0006, - 0x0009, - 0x000a, 0x0005, - 0x0006, - 0x0009, 0x000a, - 0x0005, - 0x0006, 0x0009, - 0x000a, - 0x0005, 0x0006, - 0x0009, - 0x000a, 0x0005, - 0x0006, - 0x0009, 0x000a, - 0x0005, - 0x0006, 0x0009, - 0x000a, - 0x0005, 0x0006, - 0x0009, - 0x000a, 0x0005, - 0x0006, + 0x000a, 0x0009, + 0x0006, + 0x0005, 0x000a, + 0x0009, + 0x0006, 0x0005, + 0x000a, + 0x0009, 0x0006, + 0x0005, + 0x000a, 0x0009, + 0x0006, + 0x0005, 0x000a, + 0x0009, + 0x0006, 0x0005, + 0x000a, + 0x0009, 0x0006, + 0x0005, + 0x000a, 0x0009, + 0x0006, + 0x0005, 0x000a, + 0x0009, + 0x0006, 0x0005, + 0x000a, + 0x0009, 0x0006, + 0x0005, + 0x000a, 0x0009, + 0x0006, + 0x0005, 0x000a, + 0x0009, + 0x0006, 0x0005, + 0x000a, + 0x0009, 0x0006, + 0x0005, }; static const u16 dot11lcn_sw_ctrl_tbl_rev0[] = { diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/pub.h b/trunk/drivers/net/wireless/brcm80211/brcmsmac/pub.h index 4fb2834f4e64..5855f4fd16dc 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/pub.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/pub.h @@ -176,7 +176,6 @@ struct brcms_pub { bool phy_11ncapable; /* the PHY/HW is capable of 802.11N */ struct wl_cnt *_cnt; /* low-level counters in driver */ - struct dentry *dbgfs_dir; }; enum wlc_par_id { @@ -201,6 +200,43 @@ enum wlc_par_id { /* WL11N Support */ #define AMPDU_AGG_HOST 1 +/* pri is priority encoded in the packet. This maps the Packet priority to + * enqueue precedence as defined in wlc_prec_map + */ +extern const u8 wlc_prio2prec_map[]; +#define BRCMS_PRIO_TO_PREC(pri) wlc_prio2prec_map[(pri) & 7] + +#define BRCMS_PREC_COUNT 16 /* Max precedence level implemented */ + +/* Mask to describe all precedence levels */ +#define BRCMS_PREC_BMP_ALL MAXBITVAL(BRCMS_PREC_COUNT) + +/* + * This maps priority to one precedence higher - Used by PS-Poll response + * packets to simulate enqueue-at-head operation, but still maintain the + * order on the queue + */ +#define BRCMS_PRIO_TO_HI_PREC(pri) min(BRCMS_PRIO_TO_PREC(pri) + 1,\ + BRCMS_PREC_COUNT - 1) + +/* Define a bitmap of precedences comprised by each AC */ +#define BRCMS_PREC_BMP_AC_BE (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BE)) | \ + NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BE)) | \ + NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_EE)) | \ + NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_EE))) +#define BRCMS_PREC_BMP_AC_BK (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BK)) | \ + NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BK)) | \ + NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NONE)) | \ + NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NONE))) +#define BRCMS_PREC_BMP_AC_VI (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_CL)) | \ + NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_CL)) | \ + NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VI)) | \ + NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VI))) +#define BRCMS_PREC_BMP_AC_VO (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VO)) | \ + NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VO)) | \ + NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NC)) | \ + NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NC))) + /* network protection config */ #define BRCMS_PROT_G_SPEC 1 /* SPEC g protection */ #define BRCMS_PROT_G_OVR 2 /* SPEC g prot override */ @@ -283,9 +319,9 @@ extern void brcms_c_intrson(struct brcms_c_info *wlc); extern u32 brcms_c_intrsoff(struct brcms_c_info *wlc); extern void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask); extern bool brcms_c_intrsupd(struct brcms_c_info *wlc); -extern bool brcms_c_isr(struct brcms_c_info *wlc); +extern bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc); extern bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded); -extern bool brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, +extern void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu, struct ieee80211_hw *hw); extern bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid); diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/stf.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/stf.c index dd9162722495..ed1d1aa71d2d 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/stf.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/stf.c @@ -23,7 +23,6 @@ #include "channel.h" #include "main.h" #include "stf.h" -#include "debug.h" #define MIN_SPATIAL_EXPANSION 0 #define MAX_SPATIAL_EXPANSION 1 @@ -161,8 +160,8 @@ bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val) static int brcms_c_stf_txcore_set(struct brcms_c_info *wlc, u8 Nsts, u8 core_mask) { - brcms_dbg_ht(wlc->hw->d11core, "wl%d: Nsts %d core_mask %x\n", - wlc->pub->unit, Nsts, core_mask); + BCMMSG(wlc->wiphy, "wl%d: Nsts %d core_mask %x\n", + wlc->pub->unit, Nsts, core_mask); if (hweight8(core_mask) > wlc->stf->txstreams) core_mask = 0; @@ -195,8 +194,7 @@ static int brcms_c_stf_spatial_policy_set(struct brcms_c_info *wlc, int val) int i; u8 core_mask = 0; - brcms_dbg_ht(wlc->hw->d11core, "wl%d: val %x\n", wlc->pub->unit, - val); + BCMMSG(wlc->wiphy, "wl%d: val %x\n", wlc->pub->unit, val); wlc->stf->spatial_policy = (s8) val; for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) { diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/types.h b/trunk/drivers/net/wireless/brcm80211/brcmsmac/types.h index ae1f3ad40d45..e11ae83111e4 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/types.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/types.h @@ -246,7 +246,7 @@ #define BCMMSG(dev, fmt, args...) \ do { \ - if (brcm_msg_level & BRCM_DL_INFO) \ + if (brcm_msg_level & LOG_TRACE_VAL) \ wiphy_err(dev, "%s: " fmt, __func__, ##args); \ } while (0) @@ -281,6 +281,7 @@ struct ieee80211_tx_queue_params; struct brcms_info; struct brcms_c_info; struct brcms_hardware; +struct brcms_txq_info; struct brcms_band; struct dma_pub; struct si_pub; diff --git a/trunk/drivers/net/wireless/brcm80211/include/defs.h b/trunk/drivers/net/wireless/brcm80211/include/defs.h index fb7cbcf81179..f0d8c04a9c8c 100644 --- a/trunk/drivers/net/wireless/brcm80211/include/defs.h +++ b/trunk/drivers/net/wireless/brcm80211/include/defs.h @@ -78,14 +78,9 @@ #define PM_OFF 0 #define PM_MAX 1 -/* Debug levels */ -#define BRCM_DL_INFO 0x00000001 -#define BRCM_DL_MAC80211 0x00000002 -#define BRCM_DL_RX 0x00000004 -#define BRCM_DL_TX 0x00000008 -#define BRCM_DL_INT 0x00000010 -#define BRCM_DL_DMA 0x00000020 -#define BRCM_DL_HT 0x00000040 +/* Message levels */ +#define LOG_ERROR_VAL 0x00000001 +#define LOG_TRACE_VAL 0x00000002 #define PM_OFF 0 #define PM_MAX 1 diff --git a/trunk/drivers/net/wireless/ipw2x00/ipw2100.c b/trunk/drivers/net/wireless/ipw2x00/ipw2100.c index 46938bc9886d..29b8fa1adefd 100644 --- a/trunk/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/trunk/drivers/net/wireless/ipw2x00/ipw2100.c @@ -1788,7 +1788,10 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred) } /* Initialize the geo */ - libipw_set_geo(priv->ieee, &ipw_geos[0]); + if (libipw_set_geo(priv->ieee, &ipw_geos[0])) { + printk(KERN_WARNING DRV_NAME "Could not set geo\n"); + return 0; + } priv->ieee->freq_band = LIBIPW_24GHZ_BAND; lock = LOCK_NONE; diff --git a/trunk/drivers/net/wireless/ipw2x00/ipw2200.c b/trunk/drivers/net/wireless/ipw2x00/ipw2200.c index 482f505f3f35..768bf612533e 100644 --- a/trunk/drivers/net/wireless/ipw2x00/ipw2200.c +++ b/trunk/drivers/net/wireless/ipw2x00/ipw2200.c @@ -11269,31 +11269,10 @@ static const struct libipw_geo ipw_geos[] = { } }; -static void ipw_set_geo(struct ipw_priv *priv) -{ - int j; - - for (j = 0; j < ARRAY_SIZE(ipw_geos); j++) { - if (!memcmp(&priv->eeprom[EEPROM_COUNTRY_CODE], - ipw_geos[j].name, 3)) - break; - } - - if (j == ARRAY_SIZE(ipw_geos)) { - IPW_WARNING("SKU [%c%c%c] not recognized.\n", - priv->eeprom[EEPROM_COUNTRY_CODE + 0], - priv->eeprom[EEPROM_COUNTRY_CODE + 1], - priv->eeprom[EEPROM_COUNTRY_CODE + 2]); - j = 0; - } - - libipw_set_geo(priv->ieee, &ipw_geos[j]); -} - #define MAX_HW_RESTARTS 5 static int ipw_up(struct ipw_priv *priv) { - int rc, i; + int rc, i, j; /* Age scan list entries found before suspend */ if (priv->suspend_time) { @@ -11331,7 +11310,22 @@ static int ipw_up(struct ipw_priv *priv) memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN); memcpy(priv->net_dev->perm_addr, priv->mac_addr, ETH_ALEN); - ipw_set_geo(priv); + for (j = 0; j < ARRAY_SIZE(ipw_geos); j++) { + if (!memcmp(&priv->eeprom[EEPROM_COUNTRY_CODE], + ipw_geos[j].name, 3)) + break; + } + if (j == ARRAY_SIZE(ipw_geos)) { + IPW_WARNING("SKU [%c%c%c] not recognized.\n", + priv->eeprom[EEPROM_COUNTRY_CODE + 0], + priv->eeprom[EEPROM_COUNTRY_CODE + 1], + priv->eeprom[EEPROM_COUNTRY_CODE + 2]); + j = 0; + } + if (libipw_set_geo(priv->ieee, &ipw_geos[j])) { + IPW_WARNING("Could not set geography."); + return 0; + } if (priv->status & STATUS_RF_KILL_SW) { IPW_WARNING("Radio disabled by module parameter.\n"); diff --git a/trunk/drivers/net/wireless/ipw2x00/libipw.h b/trunk/drivers/net/wireless/ipw2x00/libipw.h index 6eede52ad8c0..0b22fb421735 100644 --- a/trunk/drivers/net/wireless/ipw2x00/libipw.h +++ b/trunk/drivers/net/wireless/ipw2x00/libipw.h @@ -978,7 +978,7 @@ extern void libipw_network_reset(struct libipw_network *network); /* libipw_geo.c */ extern const struct libipw_geo *libipw_get_geo(struct libipw_device *ieee); -extern void libipw_set_geo(struct libipw_device *ieee, +extern int libipw_set_geo(struct libipw_device *ieee, const struct libipw_geo *geo); extern int libipw_is_valid_channel(struct libipw_device *ieee, diff --git a/trunk/drivers/net/wireless/ipw2x00/libipw_geo.c b/trunk/drivers/net/wireless/ipw2x00/libipw_geo.c index 218f2a32de21..c9fe3c99cb00 100644 --- a/trunk/drivers/net/wireless/ipw2x00/libipw_geo.c +++ b/trunk/drivers/net/wireless/ipw2x00/libipw_geo.c @@ -132,7 +132,7 @@ u8 libipw_freq_to_channel(struct libipw_device * ieee, u32 freq) return 0; } -void libipw_set_geo(struct libipw_device *ieee, +int libipw_set_geo(struct libipw_device *ieee, const struct libipw_geo *geo) { memcpy(ieee->geo.name, geo->name, 3); @@ -143,6 +143,7 @@ void libipw_set_geo(struct libipw_device *ieee, sizeof(struct libipw_channel)); memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels * sizeof(struct libipw_channel)); + return 0; } const struct libipw_geo *libipw_get_geo(struct libipw_device *ieee) diff --git a/trunk/drivers/net/wireless/iwlegacy/3945.c b/trunk/drivers/net/wireless/iwlegacy/3945.c index e0b9d7fa5de0..87e539894330 100644 --- a/trunk/drivers/net/wireless/iwlegacy/3945.c +++ b/trunk/drivers/net/wireless/iwlegacy/3945.c @@ -516,7 +516,7 @@ static void il3945_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb) { struct ieee80211_hdr *header; - struct ieee80211_rx_status rx_status = {}; + struct ieee80211_rx_status rx_status; struct il_rx_pkt *pkt = rxb_addr(rxb); struct il3945_rx_frame_stats *rx_stats = IL_RX_STATS(pkt); struct il3945_rx_frame_hdr *rx_hdr = IL_RX_HDR(pkt); diff --git a/trunk/drivers/net/wireless/iwlegacy/4965-mac.c b/trunk/drivers/net/wireless/iwlegacy/4965-mac.c index 07ffa575e3ef..ef68b7239955 100644 --- a/trunk/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/trunk/drivers/net/wireless/iwlegacy/4965-mac.c @@ -613,7 +613,7 @@ void il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb) { struct ieee80211_hdr *header; - struct ieee80211_rx_status rx_status = {}; + struct ieee80211_rx_status rx_status; struct il_rx_pkt *pkt = rxb_addr(rxb); struct il_rx_phy_res *phy_res; __le32 rx_pkt_status; diff --git a/trunk/drivers/net/wireless/iwlegacy/common.h b/trunk/drivers/net/wireless/iwlegacy/common.h index e254cba4557a..b4bb813362bd 100644 --- a/trunk/drivers/net/wireless/iwlegacy/common.h +++ b/trunk/drivers/net/wireless/iwlegacy/common.h @@ -2919,8 +2919,9 @@ do { \ #define IL_DBG(level, fmt, args...) \ do { \ if (il_get_debug_level(il) & level) \ - dev_err(&il->hw->wiphy->dev, "%c %s " fmt, \ - in_interrupt() ? 'I' : 'U', __func__ , ##args); \ + dev_printk(KERN_ERR, &il->hw->wiphy->dev, \ + "%c %s " fmt, in_interrupt() ? 'I' : 'U', \ + __func__ , ## args); \ } while (0) #define il_print_hex_dump(il, level, p, len) \ diff --git a/trunk/drivers/net/wireless/iwlwifi/Kconfig b/trunk/drivers/net/wireless/iwlwifi/Kconfig index 5cf43236421e..727fbb5db9da 100644 --- a/trunk/drivers/net/wireless/iwlwifi/Kconfig +++ b/trunk/drivers/net/wireless/iwlwifi/Kconfig @@ -133,3 +133,12 @@ config IWLWIFI_P2P support when it is loaded. Say Y only if you want to experiment with P2P. + +config IWLWIFI_EXPERIMENTAL_MFP + bool "support MFP (802.11w) even if uCode doesn't advertise" + depends on IWLWIFI + help + This option enables experimental MFP (802.11W) support + even if the microcode doesn't advertise it. + + Say Y only if you want to experiment with MFP. diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/agn.h b/trunk/drivers/net/wireless/iwlwifi/dvm/agn.h index 33b3ad2e546b..75e12f29d9eb 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/agn.h +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/agn.h @@ -176,8 +176,8 @@ int iwlagn_hw_valid_rtc_data_addr(u32 addr); /* lib */ int iwlagn_send_tx_power(struct iwl_priv *priv); void iwlagn_temperature(struct iwl_priv *priv); -int iwlagn_txfifo_flush(struct iwl_priv *priv); -void iwlagn_dev_txfifo_flush(struct iwl_priv *priv); +int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control); +void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control); int iwlagn_send_beacon_cmd(struct iwl_priv *priv); int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags, bool clear); diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/commands.h b/trunk/drivers/net/wireless/iwlwifi/dvm/commands.h index 71ab76b2b39d..01128c96b5d8 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/commands.h +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/commands.h @@ -986,7 +986,8 @@ struct iwl_rem_sta_cmd { #define IWL_AGG_TX_QUEUE_MSK cpu_to_le32(0xffc00) -#define IWL_DROP_ALL BIT(1) +#define IWL_DROP_SINGLE 0 +#define IWL_DROP_ALL (BIT(IWL_RXON_CTX_BSS) | BIT(IWL_RXON_CTX_PAN)) /* * REPLY_TXFIFO_FLUSH = 0x1e(command and response) @@ -1003,14 +1004,14 @@ struct iwl_rem_sta_cmd { * the flush operation ends when both the scheduler DMA done and TXFIFO empty * are set. * - * @queue_control: bit mask for which queues to flush + * @fifo_control: bit mask for which queues to flush * @flush_control: flush controls * 0: Dump single MSDU * 1: Dump multiple MSDU according to PS, INVALID STA, TTL, TID disable. * 2: Dump all FIFO */ struct iwl_txfifo_flush_cmd { - __le32 queue_control; + __le32 fifo_control; __le16 flush_control; __le16 reserved; } __packed; diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/debugfs.c b/trunk/drivers/net/wireless/iwlwifi/dvm/debugfs.c index 769a08bca86f..1a98fa3ab06d 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/debugfs.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/debugfs.c @@ -2101,7 +2101,7 @@ static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file, if (iwl_is_rfkill(priv)) return -EFAULT; - iwlagn_dev_txfifo_flush(priv); + iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); return count; } diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/lib.c b/trunk/drivers/net/wireless/iwlwifi/dvm/lib.c index 7e59be4b89b8..bef88c1a2c9b 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/lib.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/lib.c @@ -136,7 +136,7 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv, * 1. acquire mutex before calling * 2. make sure rf is on and not in exit state */ -int iwlagn_txfifo_flush(struct iwl_priv *priv) +int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control) { struct iwl_txfifo_flush_cmd flush_cmd; struct iwl_host_cmd cmd = { @@ -146,34 +146,35 @@ int iwlagn_txfifo_flush(struct iwl_priv *priv) .data = { &flush_cmd, }, }; - memset(&flush_cmd, 0, sizeof(flush_cmd)); + might_sleep(); - flush_cmd.queue_control = IWL_SCD_VO_MSK | IWL_SCD_VI_MSK | - IWL_SCD_BE_MSK | IWL_SCD_BK_MSK | - IWL_SCD_MGMT_MSK; - if ((priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))) - flush_cmd.queue_control |= IWL_PAN_SCD_VO_MSK | - IWL_PAN_SCD_VI_MSK | - IWL_PAN_SCD_BE_MSK | - IWL_PAN_SCD_BK_MSK | - IWL_PAN_SCD_MGMT_MSK | - IWL_PAN_SCD_MULTICAST_MSK; + memset(&flush_cmd, 0, sizeof(flush_cmd)); + if (flush_control & BIT(IWL_RXON_CTX_BSS)) + flush_cmd.fifo_control = IWL_SCD_VO_MSK | IWL_SCD_VI_MSK | + IWL_SCD_BE_MSK | IWL_SCD_BK_MSK | + IWL_SCD_MGMT_MSK; + if ((flush_control & BIT(IWL_RXON_CTX_PAN)) && + (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))) + flush_cmd.fifo_control |= IWL_PAN_SCD_VO_MSK | + IWL_PAN_SCD_VI_MSK | IWL_PAN_SCD_BE_MSK | + IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK | + IWL_PAN_SCD_MULTICAST_MSK; if (priv->eeprom_data->sku & EEPROM_SKU_CAP_11N_ENABLE) - flush_cmd.queue_control |= IWL_AGG_TX_QUEUE_MSK; + flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK; - IWL_DEBUG_INFO(priv, "queue control: 0x%x\n", - flush_cmd.queue_control); - flush_cmd.flush_control = cpu_to_le16(IWL_DROP_ALL); + IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n", + flush_cmd.fifo_control); + flush_cmd.flush_control = cpu_to_le16(flush_control); return iwl_dvm_send_cmd(priv, &cmd); } -void iwlagn_dev_txfifo_flush(struct iwl_priv *priv) +void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control) { mutex_lock(&priv->mutex); ieee80211_stop_queues(priv->hw); - if (iwlagn_txfifo_flush(priv)) { + if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) { IWL_ERR(priv, "flush request fail\n"); goto done; } diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/trunk/drivers/net/wireless/iwlwifi/dvm/mac80211.c index fb959b00b208..852edb02e5f6 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/mac80211.c @@ -168,13 +168,10 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | IEEE80211_HW_SUPPORTS_STATIC_SMPS; - /* - * Enable 11w if advertised by firmware and software crypto - * is not enabled (as the firmware will interpret some mgmt - * packets, so enabling it with software crypto isn't safe) - */ - if (priv->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_MFP && - !iwlwifi_mod_params.sw_crypto) +#ifndef CONFIG_IWLWIFI_EXPERIMENTAL_MFP + /* enable 11w if the uCode advertise */ + if (capa->flags & IWL_UCODE_TLV_FLAGS_MFP) +#endif /* !CONFIG_IWLWIFI_EXPERIMENTAL_MFP */ hw->flags |= IEEE80211_HW_MFP_CAPABLE; hw->sta_data_size = sizeof(struct iwl_station_priv); @@ -524,7 +521,7 @@ static void iwlagn_mac_tx(struct ieee80211_hw *hw, ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); if (iwlagn_tx_skb(priv, control->sta, skb)) - ieee80211_free_txskb(hw, skb); + dev_kfree_skb_any(skb); } static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, @@ -1022,7 +1019,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop) */ if (drop) { IWL_DEBUG_MAC80211(priv, "send flush command\n"); - if (iwlagn_txfifo_flush(priv)) { + if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) { IWL_ERR(priv, "flush request fail\n"); goto done; } @@ -1356,20 +1353,6 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw, vif_priv->ctx = ctx; ctx->vif = vif; - /* - * In SNIFFER device type, the firmware reports the FCS to - * the host, rather than snipping it off. Unfortunately, - * mac80211 doesn't (yet) provide a per-packet flag for - * this, so that we have to set the hardware flag based - * on the interfaces added. As the monitor interface can - * only be present by itself, and will be removed before - * other interfaces are added, this is safe. - */ - if (vif->type == NL80211_IFTYPE_MONITOR) - priv->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS; - else - priv->hw->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS; - err = iwl_setup_interface(priv, ctx); if (!err || reset) goto out; diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/main.c b/trunk/drivers/net/wireless/iwlwifi/dvm/main.c index e3a07c916812..475df45c8320 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/main.c @@ -511,7 +511,7 @@ static void iwl_bg_tx_flush(struct work_struct *work) return; IWL_DEBUG_INFO(priv, "device request: flush all tx frames\n"); - iwlagn_dev_txfifo_flush(priv); + iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); } /* @@ -1191,6 +1191,8 @@ static void iwl_option_config(struct iwl_priv *priv) static int iwl_eeprom_init_hw_params(struct iwl_priv *priv) { + priv->eeprom_data->sku = priv->eeprom_data->sku; + if (priv->eeprom_data->sku & EEPROM_SKU_CAP_11N_ENABLE && !priv->cfg->ht_params) { IWL_ERR(priv, "Invalid 11n configuration\n"); @@ -1202,7 +1204,7 @@ static int iwl_eeprom_init_hw_params(struct iwl_priv *priv) return -EINVAL; } - IWL_DEBUG_INFO(priv, "Device SKU: 0x%X\n", priv->eeprom_data->sku); + IWL_INFO(priv, "Device SKU: 0x%X\n", priv->eeprom_data->sku); priv->hw_params.tx_chains_num = num_of_ant(priv->eeprom_data->valid_tx_ant); @@ -1212,9 +1214,9 @@ static int iwl_eeprom_init_hw_params(struct iwl_priv *priv) priv->hw_params.rx_chains_num = num_of_ant(priv->eeprom_data->valid_rx_ant); - IWL_DEBUG_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n", - priv->eeprom_data->valid_tx_ant, - priv->eeprom_data->valid_rx_ant); + IWL_INFO(priv, "Valid Tx ant: 0x%X, Valid Rx ant: 0x%X\n", + priv->eeprom_data->valid_tx_ant, + priv->eeprom_data->valid_rx_ant); return 0; } @@ -1229,7 +1231,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, struct iwl_op_mode *op_mode; u16 num_mac; u32 ucode_flags; - struct iwl_trans_config trans_cfg = {}; + struct iwl_trans_config trans_cfg; static const u8 no_reclaim_cmds[] = { REPLY_RX_PHY_CMD, REPLY_RX_MPDU_CMD, @@ -1505,6 +1507,10 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode) iwl_tt_exit(priv); + /*This will stop the queues, move the device to low power state */ + priv->ucode_loaded = false; + iwl_trans_stop_device(priv->trans); + kfree(priv->eeprom_blob); iwl_free_eeprom_data(priv->eeprom_data); @@ -1920,6 +1926,8 @@ static void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) * commands by clearing the ready bit */ clear_bit(STATUS_READY, &priv->status); + wake_up(&priv->trans->wait_command_queue); + if (!ondemand) { /* * If firmware keep reloading, then it indicate something @@ -2105,7 +2113,7 @@ static void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) info = IEEE80211_SKB_CB(skb); iwl_trans_free_tx_cmd(priv->trans, info->driver_data[1]); - ieee80211_free_txskb(priv->hw, skb); + dev_kfree_skb_any(skb); } static void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/rx.c b/trunk/drivers/net/wireless/iwlwifi/dvm/rx.c index cac4f37cc427..ad50fb915831 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/rx.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/rx.c @@ -631,6 +631,8 @@ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv, test_bit(STATUS_RF_KILL_HW, &priv->status))) wiphy_rfkill_set_hw_state(priv->hw->wiphy, test_bit(STATUS_RF_KILL_HW, &priv->status)); + else + wake_up(&priv->trans->wait_command_queue); return 0; } @@ -899,7 +901,7 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv, struct iwl_device_cmd *cmd) { struct ieee80211_hdr *header; - struct ieee80211_rx_status rx_status = {}; + struct ieee80211_rx_status rx_status; struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_rx_phy_res *phy_res; __le32 rx_pkt_status; diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/rxon.c b/trunk/drivers/net/wireless/iwlwifi/dvm/rxon.c index 2830ea290502..10896393e5a0 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/rxon.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/rxon.c @@ -1012,12 +1012,12 @@ static void iwl_calc_basic_rates(struct iwl_priv *priv, * As a consequence, it's not as complicated as it sounds, just add * any lower rates to the ACK rate bitmap. */ - if (IWL_RATE_11M_INDEX < lowest_present_cck) - cck |= IWL_RATE_11M_MASK >> IWL_FIRST_CCK_RATE; - if (IWL_RATE_5M_INDEX < lowest_present_cck) - cck |= IWL_RATE_5M_MASK >> IWL_FIRST_CCK_RATE; - if (IWL_RATE_2M_INDEX < lowest_present_cck) - cck |= IWL_RATE_2M_MASK >> IWL_FIRST_CCK_RATE; + if (IWL_RATE_11M_INDEX < lowest_present_ofdm) + ofdm |= IWL_RATE_11M_MASK >> IWL_FIRST_CCK_RATE; + if (IWL_RATE_5M_INDEX < lowest_present_ofdm) + ofdm |= IWL_RATE_5M_MASK >> IWL_FIRST_CCK_RATE; + if (IWL_RATE_2M_INDEX < lowest_present_ofdm) + ofdm |= IWL_RATE_2M_MASK >> IWL_FIRST_CCK_RATE; /* 1M already there or needed so always add */ cck |= IWL_RATE_1M_MASK >> IWL_FIRST_CCK_RATE; diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/tx.c b/trunk/drivers/net/wireless/iwlwifi/dvm/tx.c index 4ae031f6726b..f5ca73a89870 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/tx.c @@ -1075,11 +1075,14 @@ static void iwlagn_count_tx_err_status(struct iwl_priv *priv, u16 status) static void iwlagn_set_tx_status(struct iwl_priv *priv, struct ieee80211_tx_info *info, - struct iwlagn_tx_resp *tx_resp) + struct iwlagn_tx_resp *tx_resp, + bool is_agg) { - u16 status = le16_to_cpu(tx_resp->status.status); + u16 status = le16_to_cpu(tx_resp->status.status); info->status.rates[0].count = tx_resp->failure_frame + 1; + if (is_agg) + info->flags &= ~IEEE80211_TX_CTL_AMPDU; info->flags |= iwl_tx_status_to_mac80211(status); iwlagn_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags), info); @@ -1228,7 +1231,7 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, if (is_agg && !iwl_is_tx_success(status)) info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; iwlagn_set_tx_status(priv, IEEE80211_SKB_CB(skb), - tx_resp); + tx_resp, is_agg); if (!is_agg) iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1); diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/ucode.c b/trunk/drivers/net/wireless/iwlwifi/dvm/ucode.c index 95e6d33f5159..2cb1efbc5ed1 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/ucode.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/ucode.c @@ -254,7 +254,7 @@ static int iwl_alive_notify(struct iwl_priv *priv) int ret; int i; - iwl_trans_fw_alive(priv->trans, 0); + iwl_trans_fw_alive(priv->trans); if (priv->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN && priv->eeprom_data->sku & EEPROM_SKU_CAP_IPAN_ENABLE) { diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-config.h b/trunk/drivers/net/wireless/iwlwifi/iwl-config.h index 196266aa5a9d..87f465a49df1 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-config.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-config.h @@ -150,7 +150,7 @@ enum iwl_led_mode { struct iwl_base_params { int eeprom_size; int num_of_queues; /* def: HW dependent */ - /* for iwl_pcie_apm_init() */ + /* for iwl_apm_init() */ u32 pll_cfg_val; const u16 max_ll_items; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/trunk/drivers/net/wireless/iwlwifi/iwl-devtrace.h index b3fde5f7b9bc..678717bf62eb 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-devtrace.h @@ -306,7 +306,7 @@ TRACE_EVENT(iwlwifi_dev_rx_data, memcpy(__get_dynamic_array(data), ((u8 *)rxbuf) + offs, len - offs); ), - TP_printk("[%s] RX frame data", __get_str(dev)) + TP_printk("[%s] TX frame data", __get_str(dev)) ); #undef TRACE_SYSTEM diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c index 4a9dc9629efe..f10170fe8799 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c @@ -889,8 +889,8 @@ int iwl_eeprom_check_version(struct iwl_eeprom_data *data, { if (data->eeprom_version >= trans->cfg->eeprom_ver || data->calib_version >= trans->cfg->eeprom_calib_ver) { - IWL_DEBUG_INFO(trans, "device EEPROM VER=0x%x, CALIB=0x%x\n", - data->eeprom_version, data->calib_version); + IWL_INFO(trans, "device EEPROM VER=0x%x, CALIB=0x%x\n", + data->eeprom_version, data->calib_version); return 0; } diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-fh.h b/trunk/drivers/net/wireless/iwlwifi/iwl-fh.h index ec48563d3c6a..806046641747 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-fh.h @@ -267,7 +267,7 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl) #define FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS (20) #define FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS (4) -#define RX_RB_TIMEOUT (0x11) +#define RX_RB_TIMEOUT (0x10) #define FH_RCSR_RX_CONFIG_CHNL_EN_PAUSE_VAL (0x00000000) #define FH_RCSR_RX_CONFIG_CHNL_EN_PAUSE_EOF_VAL (0x40000000) diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-trans.h b/trunk/drivers/net/wireless/iwlwifi/iwl-trans.h index e378ea6dca9c..f75ea6d73ffc 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -221,21 +221,14 @@ struct iwl_device_cmd { /** * struct iwl_hcmd_dataflag - flag for each one of the chunks of the command * - * @IWL_HCMD_DFL_NOCOPY: By default, the command is copied to the host command's + * IWL_HCMD_DFL_NOCOPY: By default, the command is copied to the host command's * ring. The transport layer doesn't map the command's buffer to DMA, but * rather copies it to an previously allocated DMA buffer. This flag tells * the transport layer not to copy the command, but to map the existing - * buffer (that is passed in) instead. This saves the memcpy and allows - * commands that are bigger than the fixed buffer to be submitted. - * Note that a TFD entry after a NOCOPY one cannot be a normal copied one. - * @IWL_HCMD_DFL_DUP: Only valid without NOCOPY, duplicate the memory for this - * chunk internally and free it again after the command completes. This - * can (currently) be used only once per command. - * Note that a TFD entry after a DUP one cannot be a normal copied one. + * buffer. This can save memcpy and is worth with very big comamnds. */ enum iwl_hcmd_dataflag { IWL_HCMD_DFL_NOCOPY = BIT(0), - IWL_HCMD_DFL_DUP = BIT(1), }; /** @@ -355,17 +348,14 @@ struct iwl_trans; * @start_fw: allocates and inits all the resources for the transport * layer. Also kick a fw image. * May sleep - * @fw_alive: called when the fw sends alive notification. If the fw provides - * the SCD base address in SRAM, then provide it here, or 0 otherwise. + * @fw_alive: called when the fw sends alive notification * May sleep * @stop_device:stops the whole device (embedded CPU put to reset) * May sleep * @wowlan_suspend: put the device into the correct mode for WoWLAN during * suspend. This is optional, if not implemented WoWLAN will not be * supported. This callback may sleep. - * @send_cmd:send a host command. Must return -ERFKILL if RFkill is asserted. - * If RFkill is asserted in the middle of a SYNC host command, it must - * return -ERFKILL straight away. + * @send_cmd:send a host command * May sleep only if CMD_SYNC is set * @tx: send an skb * Must be atomic @@ -395,7 +385,7 @@ struct iwl_trans_ops { int (*start_hw)(struct iwl_trans *iwl_trans); void (*stop_hw)(struct iwl_trans *iwl_trans, bool op_mode_leaving); int (*start_fw)(struct iwl_trans *trans, const struct fw_img *fw); - void (*fw_alive)(struct iwl_trans *trans, u32 scd_addr); + void (*fw_alive)(struct iwl_trans *trans); void (*stop_device)(struct iwl_trans *trans); void (*wowlan_suspend)(struct iwl_trans *trans); @@ -448,6 +438,7 @@ enum iwl_trans_state { * Set during transport allocation. * @hw_id_str: a string with info about HW ID. Set during transport allocation. * @pm_support: set to true in start_hw if link pm is supported + * @wait_command_queue: the wait_queue for SYNC host commands * @dev_cmd_pool: pool for Tx cmd allocation - for internal use only. * The user should use iwl_trans_{alloc,free}_tx_cmd. * @dev_cmd_headroom: room needed for the transport's private use before the @@ -474,6 +465,8 @@ struct iwl_trans { bool pm_support; + wait_queue_head_t wait_command_queue; + /* The following fields are internal only */ struct kmem_cache *dev_cmd_pool; size_t dev_cmd_headroom; @@ -515,13 +508,13 @@ static inline void iwl_trans_stop_hw(struct iwl_trans *trans, trans->state = IWL_TRANS_NO_FW; } -static inline void iwl_trans_fw_alive(struct iwl_trans *trans, u32 scd_addr) +static inline void iwl_trans_fw_alive(struct iwl_trans *trans) { might_sleep(); trans->state = IWL_TRANS_FW_ALIVE; - trans->ops->fw_alive(trans, scd_addr); + trans->ops->fw_alive(trans); } static inline int iwl_trans_start_fw(struct iwl_trans *trans, diff --git a/trunk/drivers/net/wireless/iwlwifi/pcie/drv.c b/trunk/drivers/net/wireless/iwlwifi/pcie/drv.c index 956fe6c370bc..2a4675396707 100644 --- a/trunk/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/trunk/drivers/net/wireless/iwlwifi/pcie/drv.c @@ -69,6 +69,7 @@ #include "iwl-trans.h" #include "iwl-drv.h" +#include "iwl-trans.h" #include "cfg.h" #include "internal.h" diff --git a/trunk/drivers/net/wireless/iwlwifi/pcie/internal.h b/trunk/drivers/net/wireless/iwlwifi/pcie/internal.h index d91d2e8c62f5..401178f44a3b 100644 --- a/trunk/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/trunk/drivers/net/wireless/iwlwifi/pcie/internal.h @@ -73,7 +73,7 @@ struct isr_statistics { }; /** - * struct iwl_rxq - Rx queue + * struct iwl_rx_queue - Rx queue * @bd: driver's pointer to buffer of receive buffer descriptors (rbd) * @bd_dma: bus address of buffer of receive buffer descriptors (rbd) * @pool: @@ -91,7 +91,7 @@ struct isr_statistics { * * NOTE: rx_free and rx_used are used as a FIFO for iwl_rx_mem_buffers */ -struct iwl_rxq { +struct iwl_rx_queue { __le32 *bd; dma_addr_t bd_dma; struct iwl_rx_mem_buffer pool[RX_QUEUE_SIZE + RX_FREE_BUFFERS]; @@ -157,8 +157,8 @@ struct iwl_cmd_meta { * 32 since we don't need so many commands pending. Since the HW * still uses 256 BDs for DMA though, n_bd stays 256. As a result, * the software buffers (in the variables @meta, @txb in struct - * iwl_txq) only have 32 entries, while the HW buffers (@tfds in - * the same struct) have 256. + * iwl_tx_queue) only have 32 entries, while the HW buffers (@tfds + * in the same struct) have 256. * This means that we end up with the following: * HW entries: | 0 | ... | N * 32 | ... | N * 32 + 31 | ... | 255 | * SW entries: | 0 | ... | 31 | @@ -182,17 +182,15 @@ struct iwl_queue { #define TFD_TX_CMD_SLOTS 256 #define TFD_CMD_SLOTS 32 -struct iwl_pcie_txq_entry { +struct iwl_pcie_tx_queue_entry { struct iwl_device_cmd *cmd; struct iwl_device_cmd *copy_cmd; struct sk_buff *skb; - /* buffer to free after command completes */ - const void *free_buf; struct iwl_cmd_meta meta; }; /** - * struct iwl_txq - Tx Queue for DMA + * struct iwl_tx_queue - Tx Queue for DMA * @q: generic Rx/Tx queue descriptor * @tfds: transmit frame descriptors (DMA memory) * @entries: transmit entries (driver state) @@ -205,10 +203,10 @@ struct iwl_pcie_txq_entry { * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame * descriptors) and required locking structures. */ -struct iwl_txq { +struct iwl_tx_queue { struct iwl_queue q; struct iwl_tfd *tfds; - struct iwl_pcie_txq_entry *entries; + struct iwl_pcie_tx_queue_entry *entries; spinlock_t lock; struct timer_list stuck_timer; struct iwl_trans_pcie *trans_pcie; @@ -238,7 +236,7 @@ struct iwl_txq { * @wd_timeout: queue watchdog timeout (jiffies) */ struct iwl_trans_pcie { - struct iwl_rxq rxq; + struct iwl_rx_queue rxq; struct work_struct rx_replenish; struct iwl_trans *trans; struct iwl_drv *drv; @@ -260,7 +258,7 @@ struct iwl_trans_pcie { struct iwl_dma_ptr scd_bc_tbls; struct iwl_dma_ptr kw; - struct iwl_txq *txq; + struct iwl_tx_queue *txq; unsigned long queue_used[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)]; unsigned long queue_stopped[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)]; @@ -270,8 +268,6 @@ struct iwl_trans_pcie { bool ucode_write_complete; wait_queue_head_t ucode_write_waitq; - wait_queue_head_t wait_command_queue; - unsigned long status; u8 cmd_queue; u8 cmd_fifo; @@ -287,23 +283,13 @@ struct iwl_trans_pcie { unsigned long wd_timeout; }; -/** - * enum iwl_pcie_status: status of the PCIe transport - * @STATUS_HCMD_ACTIVE: a SYNC command is being processed - * @STATUS_DEVICE_ENABLED: APM is enabled - * @STATUS_TPOWER_PMI: the device might be asleep (need to wake it up) - * @STATUS_INT_ENABLED: interrupts are enabled - * @STATUS_RFKILL: the HW RFkill switch is in KILL position - * @STATUS_FW_ERROR: the fw is in error state - */ -enum iwl_pcie_status { - STATUS_HCMD_ACTIVE, - STATUS_DEVICE_ENABLED, - STATUS_TPOWER_PMI, - STATUS_INT_ENABLED, - STATUS_RFKILL, - STATUS_FW_ERROR, -}; +/***************************************************** +* DRIVER STATUS FUNCTIONS +******************************************************/ +#define STATUS_HCMD_ACTIVE 0 +#define STATUS_DEVICE_ENABLED 1 +#define STATUS_TPOWER_PMI 2 +#define STATUS_INT_ENABLED 3 #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ ((struct iwl_trans_pcie *) ((_iwl_trans)->trans_specific)) @@ -315,10 +301,6 @@ iwl_trans_pcie_get_trans(struct iwl_trans_pcie *trans_pcie) trans_specific); } -/* - * Convention: trans API functions: iwl_trans_pcie_XXX - * Other functions: iwl_pcie_XXX - */ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, const struct pci_device_id *ent, const struct iwl_cfg *cfg); @@ -327,43 +309,50 @@ void iwl_trans_pcie_free(struct iwl_trans *trans); /***************************************************** * RX ******************************************************/ -int iwl_pcie_rx_init(struct iwl_trans *trans); -void iwl_pcie_tasklet(struct iwl_trans *trans); -int iwl_pcie_rx_stop(struct iwl_trans *trans); -void iwl_pcie_rx_free(struct iwl_trans *trans); +void iwl_bg_rx_replenish(struct work_struct *data); +void iwl_irq_tasklet(struct iwl_trans *trans); +void iwl_rx_replenish(struct iwl_trans *trans); +void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans, + struct iwl_rx_queue *q); /***************************************************** -* ICT - interrupt handling +* ICT ******************************************************/ -irqreturn_t iwl_pcie_isr_ict(int irq, void *data); -int iwl_pcie_alloc_ict(struct iwl_trans *trans); -void iwl_pcie_free_ict(struct iwl_trans *trans); -void iwl_pcie_reset_ict(struct iwl_trans *trans); -void iwl_pcie_disable_ict(struct iwl_trans *trans); +void iwl_reset_ict(struct iwl_trans *trans); +void iwl_disable_ict(struct iwl_trans *trans); +int iwl_alloc_isr_ict(struct iwl_trans *trans); +void iwl_free_isr_ict(struct iwl_trans *trans); +irqreturn_t iwl_isr_ict(int irq, void *data); /***************************************************** * TX / HCMD ******************************************************/ -int iwl_pcie_tx_init(struct iwl_trans *trans); -void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr); -int iwl_pcie_tx_stop(struct iwl_trans *trans); -void iwl_pcie_tx_free(struct iwl_trans *trans); +void iwl_txq_update_write_ptr(struct iwl_trans *trans, + struct iwl_tx_queue *txq); +int iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans, + struct iwl_tx_queue *txq, + dma_addr_t addr, u16 len, u8 reset); +int iwl_queue_init(struct iwl_queue *q, int count, int slots_num, u32 id); +int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd); +void iwl_tx_cmd_complete(struct iwl_trans *trans, + struct iwl_rx_cmd_buffer *rxb, int handler_status); +void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, + struct iwl_tx_queue *txq, + u16 byte_cnt); void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, int sta_id, int tid, int frame_limit, u16 ssn); void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int queue); -int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, - struct iwl_device_cmd *dev_cmd, int txq_id); -void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_txq *txq); -int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd); -void iwl_pcie_hcmd_complete(struct iwl_trans *trans, - struct iwl_rx_cmd_buffer *rxb, int handler_status); -void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, - struct sk_buff_head *skbs); +void iwl_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, + enum dma_data_direction dma_dir); +int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, + struct sk_buff_head *skbs); +int iwl_queue_space(const struct iwl_queue *q); + /***************************************************** * Error handling ******************************************************/ -int iwl_pcie_dump_fh(struct iwl_trans *trans, char **buf); -void iwl_pcie_dump_csr(struct iwl_trans *trans); +int iwl_dump_fh(struct iwl_trans *trans, char **buf); +void iwl_dump_csr(struct iwl_trans *trans); /***************************************************** * Helpers @@ -399,7 +388,7 @@ static inline void iwl_enable_rfkill_int(struct iwl_trans *trans) } static inline void iwl_wake_queue(struct iwl_trans *trans, - struct iwl_txq *txq) + struct iwl_tx_queue *txq) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); @@ -410,7 +399,7 @@ static inline void iwl_wake_queue(struct iwl_trans *trans, } static inline void iwl_stop_queue(struct iwl_trans *trans, - struct iwl_txq *txq) + struct iwl_tx_queue *txq) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); @@ -422,7 +411,7 @@ static inline void iwl_stop_queue(struct iwl_trans *trans, txq->q.id); } -static inline bool iwl_queue_used(const struct iwl_queue *q, int i) +static inline int iwl_queue_used(const struct iwl_queue *q, int i) { return q->write_ptr >= q->read_ptr ? (i >= q->read_ptr && i < q->write_ptr) : @@ -434,8 +423,8 @@ static inline u8 get_cmd_index(struct iwl_queue *q, u32 index) return index & (q->n_window - 1); } -static inline const char *get_cmd_string(struct iwl_trans_pcie *trans_pcie, - u8 cmd) +static inline const char * +trans_pcie_get_cmd_string(struct iwl_trans_pcie *trans_pcie, u8 cmd) { if (!trans_pcie->command_names || !trans_pcie->command_names[cmd]) return "UNKNOWN"; diff --git a/trunk/drivers/net/wireless/iwlwifi/pcie/rx.c b/trunk/drivers/net/wireless/iwlwifi/pcie/rx.c index bb32510fdd62..137af4c46a6c 100644 --- a/trunk/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/trunk/drivers/net/wireless/iwlwifi/pcie/rx.c @@ -76,7 +76,7 @@ * + A list of pre-allocated SKBs is stored in iwl->rxq->rx_free. When * iwl->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled * to replenish the iwl->rxq->rx_free. - * + In iwl_pcie_rx_replenish (scheduled) if 'processed' != 'read' then the + * + In iwl_rx_replenish (scheduled) if 'processed' != 'read' then the * iwl->rxq is replenished and the READ INDEX is updated (updating the * 'processed' and 'read' driver indexes as well) * + A received packet is processed and handed to the kernel network stack, @@ -89,28 +89,28 @@ * * Driver sequence: * - * iwl_rxq_alloc() Allocates rx_free - * iwl_pcie_rx_replenish() Replenishes rx_free list from rx_used, and calls - * iwl_pcie_rxq_restock - * iwl_pcie_rxq_restock() Moves available buffers from rx_free into Rx + * iwl_rx_queue_alloc() Allocates rx_free + * iwl_rx_replenish() Replenishes rx_free list from rx_used, and calls + * iwl_rx_queue_restock + * iwl_rx_queue_restock() Moves available buffers from rx_free into Rx * queue, updates firmware pointers, and updates * the WRITE index. If insufficient rx_free buffers - * are available, schedules iwl_pcie_rx_replenish + * are available, schedules iwl_rx_replenish * * -- enable interrupts -- - * ISR - iwl_rx() Detach iwl_rx_mem_buffers from pool up to the + * ISR - iwl_rx() Detach iwl_rx_mem_buffers from pool up to the * READ INDEX, detaching the SKB from the pool. * Moves the packet buffer from queue to rx_used. - * Calls iwl_pcie_rxq_restock to refill any empty + * Calls iwl_rx_queue_restock to refill any empty * slots. * ... * */ -/* - * iwl_rxq_space - Return number of free slots available in queue. +/** + * iwl_rx_queue_space - Return number of free slots available in queue. */ -static int iwl_rxq_space(const struct iwl_rxq *q) +static int iwl_rx_queue_space(const struct iwl_rx_queue *q) { int s = q->read - q->write; if (s <= 0) @@ -122,28 +122,11 @@ static int iwl_rxq_space(const struct iwl_rxq *q) return s; } -/* - * iwl_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr - */ -static inline __le32 iwl_pcie_dma_addr2rbd_ptr(dma_addr_t dma_addr) -{ - return cpu_to_le32((u32)(dma_addr >> 8)); -} - -/* - * iwl_pcie_rx_stop - stops the Rx DMA - */ -int iwl_pcie_rx_stop(struct iwl_trans *trans) -{ - iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); - return iwl_poll_direct_bit(trans, FH_MEM_RSSR_RX_STATUS_REG, - FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); -} - -/* - * iwl_pcie_rxq_inc_wr_ptr - Update the write pointer for the RX queue +/** + * iwl_rx_queue_update_write_ptr - Update the write pointer for the RX queue */ -static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_rxq *q) +void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans, + struct iwl_rx_queue *q) { unsigned long flags; u32 reg; @@ -193,8 +176,16 @@ static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_rxq *q) spin_unlock_irqrestore(&q->lock, flags); } -/* - * iwl_pcie_rxq_restock - refill RX queue from pre-allocated pool +/** + * iwl_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr + */ +static inline __le32 iwl_dma_addr2rbd_ptr(dma_addr_t dma_addr) +{ + return cpu_to_le32((u32)(dma_addr >> 8)); +} + +/** + * iwl_rx_queue_restock - refill RX queue from pre-allocated pool * * If there are slots in the RX queue that need to be restocked, * and we have free pre-allocated buffers, fill the ranks as much @@ -204,10 +195,11 @@ static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_rxq *q) * also updates the memory address in the firmware to reference the new * target buffer. */ -static void iwl_pcie_rxq_restock(struct iwl_trans *trans) +static void iwl_rx_queue_restock(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_rxq *rxq = &trans_pcie->rxq; + struct iwl_rx_queue *rxq = &trans_pcie->rxq; + struct list_head *element; struct iwl_rx_mem_buffer *rxb; unsigned long flags; @@ -223,18 +215,18 @@ static void iwl_pcie_rxq_restock(struct iwl_trans *trans) return; spin_lock_irqsave(&rxq->lock, flags); - while ((iwl_rxq_space(rxq) > 0) && (rxq->free_count)) { + while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) { /* The overwritten rxb must be a used one */ rxb = rxq->queue[rxq->write]; BUG_ON(rxb && rxb->page); /* Get next free Rx buffer, remove from free list */ - rxb = list_first_entry(&rxq->rx_free, struct iwl_rx_mem_buffer, - list); - list_del(&rxb->list); + element = rxq->rx_free.next; + rxb = list_entry(element, struct iwl_rx_mem_buffer, list); + list_del(element); /* Point to Rx buffer via next RBD in circular buffer */ - rxq->bd[rxq->write] = iwl_pcie_dma_addr2rbd_ptr(rxb->page_dma); + rxq->bd[rxq->write] = iwl_dma_addr2rbd_ptr(rxb->page_dma); rxq->queue[rxq->write] = rxb; rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; rxq->free_count--; @@ -251,23 +243,24 @@ static void iwl_pcie_rxq_restock(struct iwl_trans *trans) spin_lock_irqsave(&rxq->lock, flags); rxq->need_update = 1; spin_unlock_irqrestore(&rxq->lock, flags); - iwl_pcie_rxq_inc_wr_ptr(trans, rxq); + iwl_rx_queue_update_write_ptr(trans, rxq); } } /* - * iwl_pcie_rxq_alloc_rbs - allocate a page for each used RBD + * iwl_rx_allocate - allocate a page for each used RBD * * A used RBD is an Rx buffer that has been given to the stack. To use it again * a page must be allocated and the RBD must point to the page. This function * doesn't change the HW pointer but handles the list of pages that is used by - * iwl_pcie_rxq_restock. The latter function will update the HW to use the newly + * iwl_rx_queue_restock. The latter function will update the HW to use the newly * allocated buffers. */ -static void iwl_pcie_rxq_alloc_rbs(struct iwl_trans *trans, gfp_t priority) +static void iwl_rx_allocate(struct iwl_trans *trans, gfp_t priority) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_rxq *rxq = &trans_pcie->rxq; + struct iwl_rx_queue *rxq = &trans_pcie->rxq; + struct list_head *element; struct iwl_rx_mem_buffer *rxb; struct page *page; unsigned long flags; @@ -315,9 +308,10 @@ static void iwl_pcie_rxq_alloc_rbs(struct iwl_trans *trans, gfp_t priority) __free_pages(page, trans_pcie->rx_page_order); return; } - rxb = list_first_entry(&rxq->rx_used, struct iwl_rx_mem_buffer, - list); - list_del(&rxb->list); + element = rxq->rx_used.next; + rxb = list_entry(element, struct iwl_rx_mem_buffer, list); + list_del(element); + spin_unlock_irqrestore(&rxq->lock, flags); BUG_ON(rxb->page); @@ -327,14 +321,6 @@ static void iwl_pcie_rxq_alloc_rbs(struct iwl_trans *trans, gfp_t priority) dma_map_page(trans->dev, page, 0, PAGE_SIZE << trans_pcie->rx_page_order, DMA_FROM_DEVICE); - if (dma_mapping_error(trans->dev, rxb->page_dma)) { - rxb->page = NULL; - spin_lock_irqsave(&rxq->lock, flags); - list_add(&rxb->list, &rxq->rx_used); - spin_unlock_irqrestore(&rxq->lock, flags); - __free_pages(page, trans_pcie->rx_page_order); - return; - } /* dma address must be no more than 36 bits */ BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36)); /* and also 256 byte aligned! */ @@ -349,227 +335,47 @@ static void iwl_pcie_rxq_alloc_rbs(struct iwl_trans *trans, gfp_t priority) } } -static void iwl_pcie_rxq_free_rbs(struct iwl_trans *trans) -{ - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_rxq *rxq = &trans_pcie->rxq; - int i; - - /* Fill the rx_used queue with _all_ of the Rx buffers */ - for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { - /* In the reset function, these buffers may have been allocated - * to an SKB, so we need to unmap and free potential storage */ - if (rxq->pool[i].page != NULL) { - dma_unmap_page(trans->dev, rxq->pool[i].page_dma, - PAGE_SIZE << trans_pcie->rx_page_order, - DMA_FROM_DEVICE); - __free_pages(rxq->pool[i].page, - trans_pcie->rx_page_order); - rxq->pool[i].page = NULL; - } - list_add_tail(&rxq->pool[i].list, &rxq->rx_used); - } -} - /* - * iwl_pcie_rx_replenish - Move all used buffers from rx_used to rx_free + * iwl_rx_replenish - Move all used buffers from rx_used to rx_free * * When moving to rx_free an page is allocated for the slot. * - * Also restock the Rx queue via iwl_pcie_rxq_restock. + * Also restock the Rx queue via iwl_rx_queue_restock. * This is called as a scheduled work item (except for during initialization) */ -static void iwl_pcie_rx_replenish(struct iwl_trans *trans) +void iwl_rx_replenish(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); unsigned long flags; - iwl_pcie_rxq_alloc_rbs(trans, GFP_KERNEL); + iwl_rx_allocate(trans, GFP_KERNEL); spin_lock_irqsave(&trans_pcie->irq_lock, flags); - iwl_pcie_rxq_restock(trans); + iwl_rx_queue_restock(trans); spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); } -static void iwl_pcie_rx_replenish_now(struct iwl_trans *trans) +static void iwl_rx_replenish_now(struct iwl_trans *trans) { - iwl_pcie_rxq_alloc_rbs(trans, GFP_ATOMIC); + iwl_rx_allocate(trans, GFP_ATOMIC); - iwl_pcie_rxq_restock(trans); + iwl_rx_queue_restock(trans); } -static void iwl_pcie_rx_replenish_work(struct work_struct *data) +void iwl_bg_rx_replenish(struct work_struct *data) { struct iwl_trans_pcie *trans_pcie = container_of(data, struct iwl_trans_pcie, rx_replenish); - iwl_pcie_rx_replenish(trans_pcie->trans); -} - -static int iwl_pcie_rx_alloc(struct iwl_trans *trans) -{ - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_rxq *rxq = &trans_pcie->rxq; - struct device *dev = trans->dev; - - memset(&trans_pcie->rxq, 0, sizeof(trans_pcie->rxq)); - - spin_lock_init(&rxq->lock); - - if (WARN_ON(rxq->bd || rxq->rb_stts)) - return -EINVAL; - - /* Allocate the circular buffer of Read Buffer Descriptors (RBDs) */ - rxq->bd = dma_zalloc_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE, - &rxq->bd_dma, GFP_KERNEL); - if (!rxq->bd) - goto err_bd; - - /*Allocate the driver's pointer to receive buffer status */ - rxq->rb_stts = dma_zalloc_coherent(dev, sizeof(*rxq->rb_stts), - &rxq->rb_stts_dma, GFP_KERNEL); - if (!rxq->rb_stts) - goto err_rb_stts; - - return 0; - -err_rb_stts: - dma_free_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE, - rxq->bd, rxq->bd_dma); - memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma)); - rxq->bd = NULL; -err_bd: - return -ENOMEM; -} - -static void iwl_pcie_rx_hw_init(struct iwl_trans *trans, struct iwl_rxq *rxq) -{ - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - u32 rb_size; - const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */ - - if (trans_pcie->rx_buf_size_8k) - rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K; - else - rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; - - /* Stop Rx DMA */ - iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); - - /* Reset driver's Rx queue write index */ - iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); - - /* Tell device where to find RBD circular buffer in DRAM */ - iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_BASE_REG, - (u32)(rxq->bd_dma >> 8)); - - /* Tell device where in DRAM to update its Rx status */ - iwl_write_direct32(trans, FH_RSCSR_CHNL0_STTS_WPTR_REG, - rxq->rb_stts_dma >> 4); - - /* Enable Rx DMA - * FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set because of HW bug in - * the credit mechanism in 5000 HW RX FIFO - * Direct rx interrupts to hosts - * Rx buffer size 4 or 8k - * RB timeout 0x10 - * 256 RBDs - */ - iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, - FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | - FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY | - FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | - rb_size| - (RX_RB_TIMEOUT << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)| - (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS)); - - /* Set interrupt coalescing timer to default (2048 usecs) */ - iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF); -} - -int iwl_pcie_rx_init(struct iwl_trans *trans) -{ - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_rxq *rxq = &trans_pcie->rxq; - - int i, err; - unsigned long flags; - - if (!rxq->bd) { - err = iwl_pcie_rx_alloc(trans); - if (err) - return err; - } - - spin_lock_irqsave(&rxq->lock, flags); - INIT_LIST_HEAD(&rxq->rx_free); - INIT_LIST_HEAD(&rxq->rx_used); - - INIT_WORK(&trans_pcie->rx_replenish, - iwl_pcie_rx_replenish_work); - - iwl_pcie_rxq_free_rbs(trans); - - for (i = 0; i < RX_QUEUE_SIZE; i++) - rxq->queue[i] = NULL; - - /* Set us so that we have processed and used all buffers, but have - * not restocked the Rx queue with fresh buffers */ - rxq->read = rxq->write = 0; - rxq->write_actual = 0; - rxq->free_count = 0; - spin_unlock_irqrestore(&rxq->lock, flags); - - iwl_pcie_rx_replenish(trans); - - iwl_pcie_rx_hw_init(trans, rxq); - - spin_lock_irqsave(&trans_pcie->irq_lock, flags); - rxq->need_update = 1; - iwl_pcie_rxq_inc_wr_ptr(trans, rxq); - spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); - - return 0; -} - -void iwl_pcie_rx_free(struct iwl_trans *trans) -{ - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_rxq *rxq = &trans_pcie->rxq; - unsigned long flags; - - /*if rxq->bd is NULL, it means that nothing has been allocated, - * exit now */ - if (!rxq->bd) { - IWL_DEBUG_INFO(trans, "Free NULL rx context\n"); - return; - } - - spin_lock_irqsave(&rxq->lock, flags); - iwl_pcie_rxq_free_rbs(trans); - spin_unlock_irqrestore(&rxq->lock, flags); - - dma_free_coherent(trans->dev, sizeof(__le32) * RX_QUEUE_SIZE, - rxq->bd, rxq->bd_dma); - memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma)); - rxq->bd = NULL; - - if (rxq->rb_stts) - dma_free_coherent(trans->dev, - sizeof(struct iwl_rb_status), - rxq->rb_stts, rxq->rb_stts_dma); - else - IWL_DEBUG_INFO(trans, "Free rxq->rb_stts which is NULL\n"); - memset(&rxq->rb_stts_dma, 0, sizeof(rxq->rb_stts_dma)); - rxq->rb_stts = NULL; + iwl_rx_replenish(trans_pcie->trans); } -static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, +static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, struct iwl_rx_mem_buffer *rxb) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_rxq *rxq = &trans_pcie->rxq; - struct iwl_txq *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; + struct iwl_rx_queue *rxq = &trans_pcie->rxq; + struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; unsigned long flags; bool page_stolen = false; int max_len = PAGE_SIZE << trans_pcie->rx_page_order; @@ -599,7 +405,8 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, break; IWL_DEBUG_RX(trans, "cmd at offset %d: %s (0x%.2x)\n", - rxcb._offset, get_cmd_string(trans_pcie, pkt->hdr.cmd), + rxcb._offset, + trans_pcie_get_cmd_string(trans_pcie, pkt->hdr.cmd), pkt->hdr.cmd); len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK; @@ -631,7 +438,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, cmd_index = get_cmd_index(&txq->q, index); if (reclaim) { - struct iwl_pcie_txq_entry *ent; + struct iwl_pcie_tx_queue_entry *ent; ent = &txq->entries[cmd_index]; cmd = ent->copy_cmd; WARN_ON_ONCE(!cmd && ent->meta.flags & CMD_WANT_HCMD); @@ -645,9 +452,6 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, /* The original command isn't needed any more */ kfree(txq->entries[cmd_index].copy_cmd); txq->entries[cmd_index].copy_cmd = NULL; - /* nor is the duplicated part of the command */ - kfree(txq->entries[cmd_index].free_buf); - txq->entries[cmd_index].free_buf = NULL; } /* @@ -661,7 +465,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, * iwl_trans_send_cmd() * as we reclaim the driver command queue */ if (!rxcb._page_stolen) - iwl_pcie_hcmd_complete(trans, &rxcb, err); + iwl_tx_cmd_complete(trans, &rxcb, err); else IWL_WARN(trans, "Claim null rxb?\n"); } @@ -685,31 +489,24 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, dma_map_page(trans->dev, rxb->page, 0, PAGE_SIZE << trans_pcie->rx_page_order, DMA_FROM_DEVICE); - if (dma_mapping_error(trans->dev, rxb->page_dma)) { - /* - * free the page(s) as well to not break - * the invariant that the items on the used - * list have no page(s) - */ - __free_pages(rxb->page, trans_pcie->rx_page_order); - rxb->page = NULL; - list_add_tail(&rxb->list, &rxq->rx_used); - } else { - list_add_tail(&rxb->list, &rxq->rx_free); - rxq->free_count++; - } + list_add_tail(&rxb->list, &rxq->rx_free); + rxq->free_count++; } else list_add_tail(&rxb->list, &rxq->rx_used); spin_unlock_irqrestore(&rxq->lock, flags); } -/* - * iwl_pcie_rx_handle - Main entry function for receiving responses from fw +/** + * iwl_rx_handle - Main entry function for receiving responses from uCode + * + * Uses the priv->rx_handlers callback function array to invoke + * the appropriate handlers, including command responses, + * frame-received notifications, and other notifications. */ -static void iwl_pcie_rx_handle(struct iwl_trans *trans) +static void iwl_rx_handle(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_rxq *rxq = &trans_pcie->rxq; + struct iwl_rx_queue *rxq = &trans_pcie->rxq; u32 r, i; u8 fill_rx = 0; u32 count = 8; @@ -740,7 +537,7 @@ static void iwl_pcie_rx_handle(struct iwl_trans *trans) IWL_DEBUG_RX(trans, "rxbuf: HW = %d, SW = %d (%p)\n", r, i, rxb); - iwl_pcie_rx_handle_rb(trans, rxb); + iwl_rx_handle_rxbuf(trans, rxb); i = (i + 1) & RX_QUEUE_MASK; /* If there are a lot of unused frames, @@ -749,7 +546,7 @@ static void iwl_pcie_rx_handle(struct iwl_trans *trans) count++; if (count >= 8) { rxq->read = i; - iwl_pcie_rx_replenish_now(trans); + iwl_rx_replenish_now(trans); count = 0; } } @@ -758,41 +555,39 @@ static void iwl_pcie_rx_handle(struct iwl_trans *trans) /* Backtrack one entry */ rxq->read = i; if (fill_rx) - iwl_pcie_rx_replenish_now(trans); + iwl_rx_replenish_now(trans); else - iwl_pcie_rxq_restock(trans); + iwl_rx_queue_restock(trans); } -/* - * iwl_pcie_irq_handle_error - called for HW or SW error interrupt from card +/** + * iwl_irq_handle_error - called for HW or SW error interrupt from card */ -static void iwl_pcie_irq_handle_error(struct iwl_trans *trans) +static void iwl_irq_handle_error(struct iwl_trans *trans) { - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - /* W/A for WiFi/WiMAX coex and WiMAX own the RF */ if (trans->cfg->internal_wimax_coex && (!(iwl_read_prph(trans, APMG_CLK_CTRL_REG) & APMS_CLK_VAL_MRB_FUNC_MODE) || (iwl_read_prph(trans, APMG_PS_CTRL_REG) & APMG_PS_CTRL_VAL_RESET_REQ))) { + struct iwl_trans_pcie *trans_pcie = + IWL_TRANS_GET_PCIE_TRANS(trans); + clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); iwl_op_mode_wimax_active(trans->op_mode); - wake_up(&trans_pcie->wait_command_queue); + wake_up(&trans->wait_command_queue); return; } - iwl_pcie_dump_csr(trans); - iwl_pcie_dump_fh(trans, NULL); - - set_bit(STATUS_FW_ERROR, &trans_pcie->status); - clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); - wake_up(&trans_pcie->wait_command_queue); + iwl_dump_csr(trans); + iwl_dump_fh(trans, NULL); iwl_op_mode_nic_error(trans->op_mode); } -void iwl_pcie_tasklet(struct iwl_trans *trans) +/* tasklet for iwlagn interrupt */ +void iwl_irq_tasklet(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct isr_statistics *isr_stats = &trans_pcie->isr_stats; @@ -844,7 +639,7 @@ void iwl_pcie_tasklet(struct iwl_trans *trans) iwl_disable_interrupts(trans); isr_stats->hw++; - iwl_pcie_irq_handle_error(trans); + iwl_irq_handle_error(trans); handled |= CSR_INT_BIT_HW_ERR; @@ -881,16 +676,6 @@ void iwl_pcie_tasklet(struct iwl_trans *trans) isr_stats->rfkill++; iwl_op_mode_hw_rf_kill(trans->op_mode, hw_rfkill); - if (hw_rfkill) { - set_bit(STATUS_RFKILL, &trans_pcie->status); - if (test_and_clear_bit(STATUS_HCMD_ACTIVE, - &trans_pcie->status)) - IWL_DEBUG_RF_KILL(trans, - "Rfkill while SYNC HCMD in flight\n"); - wake_up(&trans_pcie->wait_command_queue); - } else { - clear_bit(STATUS_RFKILL, &trans_pcie->status); - } handled |= CSR_INT_BIT_RF_KILL; } @@ -907,16 +692,17 @@ void iwl_pcie_tasklet(struct iwl_trans *trans) IWL_ERR(trans, "Microcode SW error detected. " " Restarting 0x%X.\n", inta); isr_stats->sw++; - iwl_pcie_irq_handle_error(trans); + iwl_irq_handle_error(trans); handled |= CSR_INT_BIT_SW_ERR; } /* uCode wakes up after power-down sleep */ if (inta & CSR_INT_BIT_WAKEUP) { IWL_DEBUG_ISR(trans, "Wakeup interrupt\n"); - iwl_pcie_rxq_inc_wr_ptr(trans, &trans_pcie->rxq); + iwl_rx_queue_update_write_ptr(trans, &trans_pcie->rxq); for (i = 0; i < trans->cfg->base_params->num_of_queues; i++) - iwl_pcie_txq_inc_wr_ptr(trans, &trans_pcie->txq[i]); + iwl_txq_update_write_ptr(trans, + &trans_pcie->txq[i]); isr_stats->wakeup++; @@ -954,7 +740,7 @@ void iwl_pcie_tasklet(struct iwl_trans *trans) iwl_write8(trans, CSR_INT_PERIODIC_REG, CSR_INT_PERIODIC_DIS); - iwl_pcie_rx_handle(trans); + iwl_rx_handle(trans); /* * Enable periodic interrupt in 8 msec only if we received @@ -1012,7 +798,7 @@ void iwl_pcie_tasklet(struct iwl_trans *trans) #define ICT_COUNT (ICT_SIZE / sizeof(u32)) /* Free dram table */ -void iwl_pcie_free_ict(struct iwl_trans *trans) +void iwl_free_isr_ict(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); @@ -1025,12 +811,13 @@ void iwl_pcie_free_ict(struct iwl_trans *trans) } } + /* * allocate dram shared table, it is an aligned memory * block of ICT_SIZE. * also reset all data related to ICT table interrupt. */ -int iwl_pcie_alloc_ict(struct iwl_trans *trans) +int iwl_alloc_isr_ict(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); @@ -1043,7 +830,7 @@ int iwl_pcie_alloc_ict(struct iwl_trans *trans) /* just an API sanity check ... it is guaranteed to be aligned */ if (WARN_ON(trans_pcie->ict_tbl_dma & (ICT_SIZE - 1))) { - iwl_pcie_free_ict(trans); + iwl_free_isr_ict(trans); return -EINVAL; } @@ -1064,7 +851,7 @@ int iwl_pcie_alloc_ict(struct iwl_trans *trans) /* Device is going up inform it about using ICT interrupt table, * also we need to tell the driver to start using ICT interrupt. */ -void iwl_pcie_reset_ict(struct iwl_trans *trans) +void iwl_reset_ict(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); u32 val; @@ -1094,7 +881,7 @@ void iwl_pcie_reset_ict(struct iwl_trans *trans) } /* Device is going down disable ict interrupt usage */ -void iwl_pcie_disable_ict(struct iwl_trans *trans) +void iwl_disable_ict(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); unsigned long flags; @@ -1105,7 +892,7 @@ void iwl_pcie_disable_ict(struct iwl_trans *trans) } /* legacy (non-ICT) ISR. Assumes that trans_pcie->irq_lock is held */ -static irqreturn_t iwl_pcie_isr(int irq, void *data) +static irqreturn_t iwl_isr(int irq, void *data) { struct iwl_trans *trans = data; struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); @@ -1152,7 +939,7 @@ static irqreturn_t iwl_pcie_isr(int irq, void *data) #endif trans_pcie->inta |= inta; - /* iwl_pcie_tasklet() will service interrupts and re-enable them */ + /* iwl_irq_tasklet() will service interrupts and re-enable them */ if (likely(inta)) tasklet_schedule(&trans_pcie->irq_tasklet); else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && @@ -1177,7 +964,7 @@ static irqreturn_t iwl_pcie_isr(int irq, void *data) * the interrupt we need to service, driver will set the entries back to 0 and * set index. */ -irqreturn_t iwl_pcie_isr_ict(int irq, void *data) +irqreturn_t iwl_isr_ict(int irq, void *data) { struct iwl_trans *trans = data; struct iwl_trans_pcie *trans_pcie; @@ -1197,13 +984,14 @@ irqreturn_t iwl_pcie_isr_ict(int irq, void *data) * use legacy interrupt. */ if (unlikely(!trans_pcie->use_ict)) { - irqreturn_t ret = iwl_pcie_isr(irq, data); + irqreturn_t ret = iwl_isr(irq, data); spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); return ret; } trace_iwlwifi_dev_irq(trans->dev); + /* Disable (but don't clear!) interrupts here to avoid * back-to-back ISRs and sporadic interrupts from our NIC. * If we have something to service, the tasklet will re-enable ints. @@ -1212,6 +1000,7 @@ irqreturn_t iwl_pcie_isr_ict(int irq, void *data) inta_mask = iwl_read32(trans, CSR_INT_MASK); /* just for debug */ iwl_write32(trans, CSR_INT_MASK, 0x00000000); + /* Ignore interrupt if there's nothing in NIC to service. * This may be due to IRQ shared with another device, * or due to sporadic interrupts thrown from our NIC. */ @@ -1260,7 +1049,7 @@ irqreturn_t iwl_pcie_isr_ict(int irq, void *data) inta &= trans_pcie->inta_mask; trans_pcie->inta |= inta; - /* iwl_pcie_tasklet() will service interrupts and re-enable them */ + /* iwl_irq_tasklet() will service interrupts and re-enable them */ if (likely(inta)) tasklet_schedule(&trans_pcie->irq_tasklet); else if (test_bit(STATUS_INT_ENABLED, &trans_pcie->status) && diff --git a/trunk/drivers/net/wireless/iwlwifi/pcie/trans.c b/trunk/drivers/net/wireless/iwlwifi/pcie/trans.c index f6c21e7edaf2..f95d88df7772 100644 --- a/trunk/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/trunk/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -74,8 +74,584 @@ #include "iwl-prph.h" #include "iwl-agn-hw.h" #include "internal.h" +/* FIXME: need to abstract out TX command (once we know what it looks like) */ +#include "dvm/commands.h" -static void iwl_pcie_set_pwr_vmain(struct iwl_trans *trans) +#define SCD_QUEUECHAIN_SEL_ALL(trans, trans_pcie) \ + (((1<cfg->base_params->num_of_queues) - 1) &\ + (~(1<<(trans_pcie)->cmd_queue))) + +static int iwl_trans_rx_alloc(struct iwl_trans *trans) +{ + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_rx_queue *rxq = &trans_pcie->rxq; + struct device *dev = trans->dev; + + memset(&trans_pcie->rxq, 0, sizeof(trans_pcie->rxq)); + + spin_lock_init(&rxq->lock); + + if (WARN_ON(rxq->bd || rxq->rb_stts)) + return -EINVAL; + + /* Allocate the circular buffer of Read Buffer Descriptors (RBDs) */ + rxq->bd = dma_zalloc_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE, + &rxq->bd_dma, GFP_KERNEL); + if (!rxq->bd) + goto err_bd; + + /*Allocate the driver's pointer to receive buffer status */ + rxq->rb_stts = dma_zalloc_coherent(dev, sizeof(*rxq->rb_stts), + &rxq->rb_stts_dma, GFP_KERNEL); + if (!rxq->rb_stts) + goto err_rb_stts; + + return 0; + +err_rb_stts: + dma_free_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE, + rxq->bd, rxq->bd_dma); + memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma)); + rxq->bd = NULL; +err_bd: + return -ENOMEM; +} + +static void iwl_trans_rxq_free_rx_bufs(struct iwl_trans *trans) +{ + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_rx_queue *rxq = &trans_pcie->rxq; + int i; + + /* Fill the rx_used queue with _all_ of the Rx buffers */ + for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { + /* In the reset function, these buffers may have been allocated + * to an SKB, so we need to unmap and free potential storage */ + if (rxq->pool[i].page != NULL) { + dma_unmap_page(trans->dev, rxq->pool[i].page_dma, + PAGE_SIZE << trans_pcie->rx_page_order, + DMA_FROM_DEVICE); + __free_pages(rxq->pool[i].page, + trans_pcie->rx_page_order); + rxq->pool[i].page = NULL; + } + list_add_tail(&rxq->pool[i].list, &rxq->rx_used); + } +} + +static void iwl_trans_rx_hw_init(struct iwl_trans *trans, + struct iwl_rx_queue *rxq) +{ + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + u32 rb_size; + const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */ + u32 rb_timeout = RX_RB_TIMEOUT; /* FIXME: RX_RB_TIMEOUT for all devices? */ + + if (trans_pcie->rx_buf_size_8k) + rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K; + else + rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; + + /* Stop Rx DMA */ + iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); + + /* Reset driver's Rx queue write index */ + iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); + + /* Tell device where to find RBD circular buffer in DRAM */ + iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_BASE_REG, + (u32)(rxq->bd_dma >> 8)); + + /* Tell device where in DRAM to update its Rx status */ + iwl_write_direct32(trans, FH_RSCSR_CHNL0_STTS_WPTR_REG, + rxq->rb_stts_dma >> 4); + + /* Enable Rx DMA + * FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set because of HW bug in + * the credit mechanism in 5000 HW RX FIFO + * Direct rx interrupts to hosts + * Rx buffer size 4 or 8k + * RB timeout 0x10 + * 256 RBDs + */ + iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, + FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | + FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY | + FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | + rb_size| + (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)| + (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS)); + + /* Set interrupt coalescing timer to default (2048 usecs) */ + iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF); +} + +static int iwl_rx_init(struct iwl_trans *trans) +{ + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_rx_queue *rxq = &trans_pcie->rxq; + + int i, err; + unsigned long flags; + + if (!rxq->bd) { + err = iwl_trans_rx_alloc(trans); + if (err) + return err; + } + + spin_lock_irqsave(&rxq->lock, flags); + INIT_LIST_HEAD(&rxq->rx_free); + INIT_LIST_HEAD(&rxq->rx_used); + + iwl_trans_rxq_free_rx_bufs(trans); + + for (i = 0; i < RX_QUEUE_SIZE; i++) + rxq->queue[i] = NULL; + + /* Set us so that we have processed and used all buffers, but have + * not restocked the Rx queue with fresh buffers */ + rxq->read = rxq->write = 0; + rxq->write_actual = 0; + rxq->free_count = 0; + spin_unlock_irqrestore(&rxq->lock, flags); + + iwl_rx_replenish(trans); + + iwl_trans_rx_hw_init(trans, rxq); + + spin_lock_irqsave(&trans_pcie->irq_lock, flags); + rxq->need_update = 1; + iwl_rx_queue_update_write_ptr(trans, rxq); + spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); + + return 0; +} + +static void iwl_trans_pcie_rx_free(struct iwl_trans *trans) +{ + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_rx_queue *rxq = &trans_pcie->rxq; + unsigned long flags; + + /*if rxq->bd is NULL, it means that nothing has been allocated, + * exit now */ + if (!rxq->bd) { + IWL_DEBUG_INFO(trans, "Free NULL rx context\n"); + return; + } + + spin_lock_irqsave(&rxq->lock, flags); + iwl_trans_rxq_free_rx_bufs(trans); + spin_unlock_irqrestore(&rxq->lock, flags); + + dma_free_coherent(trans->dev, sizeof(__le32) * RX_QUEUE_SIZE, + rxq->bd, rxq->bd_dma); + memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma)); + rxq->bd = NULL; + + if (rxq->rb_stts) + dma_free_coherent(trans->dev, + sizeof(struct iwl_rb_status), + rxq->rb_stts, rxq->rb_stts_dma); + else + IWL_DEBUG_INFO(trans, "Free rxq->rb_stts which is NULL\n"); + memset(&rxq->rb_stts_dma, 0, sizeof(rxq->rb_stts_dma)); + rxq->rb_stts = NULL; +} + +static int iwl_trans_rx_stop(struct iwl_trans *trans) +{ + + /* stop Rx DMA */ + iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); + return iwl_poll_direct_bit(trans, FH_MEM_RSSR_RX_STATUS_REG, + FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); +} + +static int iwlagn_alloc_dma_ptr(struct iwl_trans *trans, + struct iwl_dma_ptr *ptr, size_t size) +{ + if (WARN_ON(ptr->addr)) + return -EINVAL; + + ptr->addr = dma_alloc_coherent(trans->dev, size, + &ptr->dma, GFP_KERNEL); + if (!ptr->addr) + return -ENOMEM; + ptr->size = size; + return 0; +} + +static void iwlagn_free_dma_ptr(struct iwl_trans *trans, + struct iwl_dma_ptr *ptr) +{ + if (unlikely(!ptr->addr)) + return; + + dma_free_coherent(trans->dev, ptr->size, ptr->addr, ptr->dma); + memset(ptr, 0, sizeof(*ptr)); +} + +static void iwl_trans_pcie_queue_stuck_timer(unsigned long data) +{ + struct iwl_tx_queue *txq = (void *)data; + struct iwl_queue *q = &txq->q; + struct iwl_trans_pcie *trans_pcie = txq->trans_pcie; + struct iwl_trans *trans = iwl_trans_pcie_get_trans(trans_pcie); + u32 scd_sram_addr = trans_pcie->scd_base_addr + + SCD_TX_STTS_QUEUE_OFFSET(txq->q.id); + u8 buf[16]; + int i; + + spin_lock(&txq->lock); + /* check if triggered erroneously */ + if (txq->q.read_ptr == txq->q.write_ptr) { + spin_unlock(&txq->lock); + return; + } + spin_unlock(&txq->lock); + + IWL_ERR(trans, "Queue %d stuck for %u ms.\n", txq->q.id, + jiffies_to_msecs(trans_pcie->wd_timeout)); + IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n", + txq->q.read_ptr, txq->q.write_ptr); + + iwl_read_targ_mem_bytes(trans, scd_sram_addr, buf, sizeof(buf)); + + iwl_print_hex_error(trans, buf, sizeof(buf)); + + for (i = 0; i < FH_TCSR_CHNL_NUM; i++) + IWL_ERR(trans, "FH TRBs(%d) = 0x%08x\n", i, + iwl_read_direct32(trans, FH_TX_TRB_REG(i))); + + for (i = 0; i < trans->cfg->base_params->num_of_queues; i++) { + u32 status = iwl_read_prph(trans, SCD_QUEUE_STATUS_BITS(i)); + u8 fifo = (status >> SCD_QUEUE_STTS_REG_POS_TXF) & 0x7; + bool active = !!(status & BIT(SCD_QUEUE_STTS_REG_POS_ACTIVE)); + u32 tbl_dw = + iwl_read_targ_mem(trans, + trans_pcie->scd_base_addr + + SCD_TRANS_TBL_OFFSET_QUEUE(i)); + + if (i & 0x1) + tbl_dw = (tbl_dw & 0xFFFF0000) >> 16; + else + tbl_dw = tbl_dw & 0x0000FFFF; + + IWL_ERR(trans, + "Q %d is %sactive and mapped to fifo %d ra_tid 0x%04x [%d,%d]\n", + i, active ? "" : "in", fifo, tbl_dw, + iwl_read_prph(trans, + SCD_QUEUE_RDPTR(i)) & (txq->q.n_bd - 1), + iwl_read_prph(trans, SCD_QUEUE_WRPTR(i))); + } + + for (i = q->read_ptr; i != q->write_ptr; + i = iwl_queue_inc_wrap(i, q->n_bd)) { + struct iwl_tx_cmd *tx_cmd = + (struct iwl_tx_cmd *)txq->entries[i].cmd->payload; + IWL_ERR(trans, "scratch %d = 0x%08x\n", i, + get_unaligned_le32(&tx_cmd->scratch)); + } + + iwl_op_mode_nic_error(trans->op_mode); +} + +static int iwl_trans_txq_alloc(struct iwl_trans *trans, + struct iwl_tx_queue *txq, int slots_num, + u32 txq_id) +{ + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX; + int i; + + if (WARN_ON(txq->entries || txq->tfds)) + return -EINVAL; + + setup_timer(&txq->stuck_timer, iwl_trans_pcie_queue_stuck_timer, + (unsigned long)txq); + txq->trans_pcie = trans_pcie; + + txq->q.n_window = slots_num; + + txq->entries = kcalloc(slots_num, + sizeof(struct iwl_pcie_tx_queue_entry), + GFP_KERNEL); + + if (!txq->entries) + goto error; + + if (txq_id == trans_pcie->cmd_queue) + for (i = 0; i < slots_num; i++) { + txq->entries[i].cmd = + kmalloc(sizeof(struct iwl_device_cmd), + GFP_KERNEL); + if (!txq->entries[i].cmd) + goto error; + } + + /* Circular buffer of transmit frame descriptors (TFDs), + * shared with device */ + txq->tfds = dma_alloc_coherent(trans->dev, tfd_sz, + &txq->q.dma_addr, GFP_KERNEL); + if (!txq->tfds) { + IWL_ERR(trans, "dma_alloc_coherent(%zd) failed\n", tfd_sz); + goto error; + } + txq->q.id = txq_id; + + return 0; +error: + if (txq->entries && txq_id == trans_pcie->cmd_queue) + for (i = 0; i < slots_num; i++) + kfree(txq->entries[i].cmd); + kfree(txq->entries); + txq->entries = NULL; + + return -ENOMEM; + +} + +static int iwl_trans_txq_init(struct iwl_trans *trans, struct iwl_tx_queue *txq, + int slots_num, u32 txq_id) +{ + int ret; + + txq->need_update = 0; + + /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise + * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */ + BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); + + /* Initialize queue's high/low-water marks, and head/tail indexes */ + ret = iwl_queue_init(&txq->q, TFD_QUEUE_SIZE_MAX, slots_num, + txq_id); + if (ret) + return ret; + + spin_lock_init(&txq->lock); + + /* + * Tell nic where to find circular buffer of Tx Frame Descriptors for + * given Tx queue, and enable the DMA channel used for that queue. + * Circular buffer (TFD queue in DRAM) physical base address */ + iwl_write_direct32(trans, FH_MEM_CBBC_QUEUE(txq_id), + txq->q.dma_addr >> 8); + + return 0; +} + +/** + * iwl_tx_queue_unmap - Unmap any remaining DMA mappings and free skb's + */ +static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id) +{ + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; + struct iwl_queue *q = &txq->q; + enum dma_data_direction dma_dir; + + if (!q->n_bd) + return; + + /* In the command queue, all the TBs are mapped as BIDI + * so unmap them as such. + */ + if (txq_id == trans_pcie->cmd_queue) + dma_dir = DMA_BIDIRECTIONAL; + else + dma_dir = DMA_TO_DEVICE; + + spin_lock_bh(&txq->lock); + while (q->write_ptr != q->read_ptr) { + iwl_txq_free_tfd(trans, txq, dma_dir); + q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); + } + spin_unlock_bh(&txq->lock); +} + +/** + * iwl_tx_queue_free - Deallocate DMA queue. + * @txq: Transmit queue to deallocate. + * + * Empty queue by removing and destroying all BD's. + * Free all buffers. + * 0-fill, but do not free "txq" descriptor structure. + */ +static void iwl_tx_queue_free(struct iwl_trans *trans, int txq_id) +{ + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; + struct device *dev = trans->dev; + int i; + + if (WARN_ON(!txq)) + return; + + iwl_tx_queue_unmap(trans, txq_id); + + /* De-alloc array of command/tx buffers */ + if (txq_id == trans_pcie->cmd_queue) + for (i = 0; i < txq->q.n_window; i++) { + kfree(txq->entries[i].cmd); + kfree(txq->entries[i].copy_cmd); + } + + /* De-alloc circular buffer of TFDs */ + if (txq->q.n_bd) { + dma_free_coherent(dev, sizeof(struct iwl_tfd) * + txq->q.n_bd, txq->tfds, txq->q.dma_addr); + memset(&txq->q.dma_addr, 0, sizeof(txq->q.dma_addr)); + } + + kfree(txq->entries); + txq->entries = NULL; + + del_timer_sync(&txq->stuck_timer); + + /* 0-fill queue descriptor structure */ + memset(txq, 0, sizeof(*txq)); +} + +/** + * iwl_trans_tx_free - Free TXQ Context + * + * Destroy all TX DMA queues and structures + */ +static void iwl_trans_pcie_tx_free(struct iwl_trans *trans) +{ + int txq_id; + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + + /* Tx queues */ + if (trans_pcie->txq) { + for (txq_id = 0; + txq_id < trans->cfg->base_params->num_of_queues; txq_id++) + iwl_tx_queue_free(trans, txq_id); + } + + kfree(trans_pcie->txq); + trans_pcie->txq = NULL; + + iwlagn_free_dma_ptr(trans, &trans_pcie->kw); + + iwlagn_free_dma_ptr(trans, &trans_pcie->scd_bc_tbls); +} + +/** + * iwl_trans_tx_alloc - allocate TX context + * Allocate all Tx DMA structures and initialize them + * + * @param priv + * @return error code + */ +static int iwl_trans_tx_alloc(struct iwl_trans *trans) +{ + int ret; + int txq_id, slots_num; + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + + u16 scd_bc_tbls_size = trans->cfg->base_params->num_of_queues * + sizeof(struct iwlagn_scd_bc_tbl); + + /*It is not allowed to alloc twice, so warn when this happens. + * We cannot rely on the previous allocation, so free and fail */ + if (WARN_ON(trans_pcie->txq)) { + ret = -EINVAL; + goto error; + } + + ret = iwlagn_alloc_dma_ptr(trans, &trans_pcie->scd_bc_tbls, + scd_bc_tbls_size); + if (ret) { + IWL_ERR(trans, "Scheduler BC Table allocation failed\n"); + goto error; + } + + /* Alloc keep-warm buffer */ + ret = iwlagn_alloc_dma_ptr(trans, &trans_pcie->kw, IWL_KW_SIZE); + if (ret) { + IWL_ERR(trans, "Keep Warm allocation failed\n"); + goto error; + } + + trans_pcie->txq = kcalloc(trans->cfg->base_params->num_of_queues, + sizeof(struct iwl_tx_queue), GFP_KERNEL); + if (!trans_pcie->txq) { + IWL_ERR(trans, "Not enough memory for txq\n"); + ret = ENOMEM; + goto error; + } + + /* Alloc and init all Tx queues, including the command queue (#4/#9) */ + for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues; + txq_id++) { + slots_num = (txq_id == trans_pcie->cmd_queue) ? + TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; + ret = iwl_trans_txq_alloc(trans, &trans_pcie->txq[txq_id], + slots_num, txq_id); + if (ret) { + IWL_ERR(trans, "Tx %d queue alloc failed\n", txq_id); + goto error; + } + } + + return 0; + +error: + iwl_trans_pcie_tx_free(trans); + + return ret; +} +static int iwl_tx_init(struct iwl_trans *trans) +{ + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + int ret; + int txq_id, slots_num; + unsigned long flags; + bool alloc = false; + + if (!trans_pcie->txq) { + ret = iwl_trans_tx_alloc(trans); + if (ret) + goto error; + alloc = true; + } + + spin_lock_irqsave(&trans_pcie->irq_lock, flags); + + /* Turn off all Tx DMA fifos */ + iwl_write_prph(trans, SCD_TXFACT, 0); + + /* Tell NIC where to find the "keep warm" buffer */ + iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG, + trans_pcie->kw.dma >> 4); + + spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); + + /* Alloc and init all Tx queues, including the command queue (#4/#9) */ + for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues; + txq_id++) { + slots_num = (txq_id == trans_pcie->cmd_queue) ? + TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; + ret = iwl_trans_txq_init(trans, &trans_pcie->txq[txq_id], + slots_num, txq_id); + if (ret) { + IWL_ERR(trans, "Tx %d queue init failed\n", txq_id); + goto error; + } + } + + return 0; +error: + /*Upon error, free only if we allocated something */ + if (alloc) + iwl_trans_pcie_tx_free(trans); + return ret; +} + +static void iwl_set_pwr_vmain(struct iwl_trans *trans) { /* * (for documentation purposes) @@ -97,11 +673,18 @@ static void iwl_pcie_set_pwr_vmain(struct iwl_trans *trans) #define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01 #define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02 -static void iwl_pcie_apm_config(struct iwl_trans *trans) +static u16 iwl_pciexp_link_ctrl(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - u16 lctl; + u16 pci_lnk_ctl; + + pcie_capability_read_word(trans_pcie->pci_dev, PCI_EXP_LNKCTL, + &pci_lnk_ctl); + return pci_lnk_ctl; +} +static void iwl_apm_config(struct iwl_trans *trans) +{ /* * HW bug W/A for instability in PCIe bus L0S->L1 transition. * Check if BIOS (or OS) enabled L1-ASPM on this device. @@ -110,27 +693,29 @@ static void iwl_pcie_apm_config(struct iwl_trans *trans) * If not (unlikely), enable L0S, so there is at least some * power savings, even without L1. */ - pcie_capability_read_word(trans_pcie->pci_dev, PCI_EXP_LNKCTL, &lctl); + u16 lctl = iwl_pciexp_link_ctrl(trans); if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN) { /* L1-ASPM enabled; disable(!) L0S */ iwl_set_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); - dev_info(trans->dev, "L1 Enabled; Disabling L0S\n"); + dev_printk(KERN_INFO, trans->dev, + "L1 Enabled; Disabling L0S\n"); } else { /* L1-ASPM disabled; enable(!) L0S */ iwl_clear_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); - dev_info(trans->dev, "L1 Disabled; Enabling L0S\n"); + dev_printk(KERN_INFO, trans->dev, + "L1 Disabled; Enabling L0S\n"); } trans->pm_support = !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN); } /* * Start up NIC's basic functionality after it has been reset - * (e.g. after platform boot, or shutdown via iwl_pcie_apm_stop()) + * (e.g. after platform boot, or shutdown via iwl_apm_stop()) * NOTE: This does not load uCode nor start the embedded processor */ -static int iwl_pcie_apm_init(struct iwl_trans *trans) +static int iwl_apm_init(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int ret = 0; @@ -162,7 +747,7 @@ static int iwl_pcie_apm_init(struct iwl_trans *trans) iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); - iwl_pcie_apm_config(trans); + iwl_apm_config(trans); /* Configure analog phase-lock-loop before activating to D0A */ if (trans->cfg->base_params->pll_cfg_val) @@ -208,7 +793,7 @@ static int iwl_pcie_apm_init(struct iwl_trans *trans) return ret; } -static int iwl_pcie_apm_stop_master(struct iwl_trans *trans) +static int iwl_apm_stop_master(struct iwl_trans *trans) { int ret = 0; @@ -226,7 +811,7 @@ static int iwl_pcie_apm_stop_master(struct iwl_trans *trans) return ret; } -static void iwl_pcie_apm_stop(struct iwl_trans *trans) +static void iwl_apm_stop(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); IWL_DEBUG_INFO(trans, "Stop card, put in low power state\n"); @@ -234,7 +819,7 @@ static void iwl_pcie_apm_stop(struct iwl_trans *trans) clear_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status); /* Stop device's DMA activity */ - iwl_pcie_apm_stop_master(trans); + iwl_apm_stop_master(trans); /* Reset the entire device */ iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); @@ -249,29 +834,29 @@ static void iwl_pcie_apm_stop(struct iwl_trans *trans) CSR_GP_CNTRL_REG_FLAG_INIT_DONE); } -static int iwl_pcie_nic_init(struct iwl_trans *trans) +static int iwl_nic_init(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); unsigned long flags; /* nic_init */ spin_lock_irqsave(&trans_pcie->irq_lock, flags); - iwl_pcie_apm_init(trans); + iwl_apm_init(trans); /* Set interrupt coalescing calibration timer to default (512 usecs) */ iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF); spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); - iwl_pcie_set_pwr_vmain(trans); + iwl_set_pwr_vmain(trans); iwl_op_mode_nic_config(trans->op_mode); /* Allocate the RX queue, or reset if it is already allocated */ - iwl_pcie_rx_init(trans); + iwl_rx_init(trans); /* Allocate or reset and init all Tx and Command queues */ - if (iwl_pcie_tx_init(trans)) + if (iwl_tx_init(trans)) return -ENOMEM; if (trans->cfg->base_params->shadow_reg_enable) { @@ -286,7 +871,7 @@ static int iwl_pcie_nic_init(struct iwl_trans *trans) #define HW_READY_TIMEOUT (50) /* Note: returns poll_bit return value, which is >= 0 if success */ -static int iwl_pcie_set_hw_ready(struct iwl_trans *trans) +static int iwl_set_hw_ready(struct iwl_trans *trans) { int ret; @@ -304,14 +889,14 @@ static int iwl_pcie_set_hw_ready(struct iwl_trans *trans) } /* Note: returns standard 0/-ERROR code */ -static int iwl_pcie_prepare_card_hw(struct iwl_trans *trans) +static int iwl_prepare_card_hw(struct iwl_trans *trans) { int ret; int t = 0; IWL_DEBUG_INFO(trans, "iwl_trans_prepare_card_hw enter\n"); - ret = iwl_pcie_set_hw_ready(trans); + ret = iwl_set_hw_ready(trans); /* If the card is ready, exit 0 */ if (ret >= 0) return 0; @@ -321,7 +906,7 @@ static int iwl_pcie_prepare_card_hw(struct iwl_trans *trans) CSR_HW_IF_CONFIG_REG_PREPARE); do { - ret = iwl_pcie_set_hw_ready(trans); + ret = iwl_set_hw_ready(trans); if (ret >= 0) return 0; @@ -335,7 +920,7 @@ static int iwl_pcie_prepare_card_hw(struct iwl_trans *trans) /* * ucode */ -static int iwl_pcie_load_firmware_chunk(struct iwl_trans *trans, u32 dst_addr, +static int iwl_load_firmware_chunk(struct iwl_trans *trans, u32 dst_addr, dma_addr_t phy_addr, u32 byte_cnt) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); @@ -382,7 +967,7 @@ static int iwl_pcie_load_firmware_chunk(struct iwl_trans *trans, u32 dst_addr, return 0; } -static int iwl_pcie_load_section(struct iwl_trans *trans, u8 section_num, +static int iwl_load_section(struct iwl_trans *trans, u8 section_num, const struct fw_desc *section) { u8 *v_addr; @@ -403,9 +988,8 @@ static int iwl_pcie_load_section(struct iwl_trans *trans, u8 section_num, copy_size = min_t(u32, PAGE_SIZE, section->len - offset); memcpy(v_addr, (u8 *)section->data + offset, copy_size); - ret = iwl_pcie_load_firmware_chunk(trans, - section->offset + offset, - p_addr, copy_size); + ret = iwl_load_firmware_chunk(trans, section->offset + offset, + p_addr, copy_size); if (ret) { IWL_ERR(trans, "Could not load the [%d] uCode section\n", @@ -418,7 +1002,7 @@ static int iwl_pcie_load_section(struct iwl_trans *trans, u8 section_num, return ret; } -static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, +static int iwl_load_given_ucode(struct iwl_trans *trans, const struct fw_img *image) { int i, ret = 0; @@ -427,7 +1011,7 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, if (!image->sec[i].data) break; - ret = iwl_pcie_load_section(trans, i, &image->sec[i]); + ret = iwl_load_section(trans, i, &image->sec[i]); if (ret) return ret; } @@ -441,18 +1025,15 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans, static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, const struct fw_img *fw) { - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int ret; bool hw_rfkill; /* This may fail if AMT took ownership of the device */ - if (iwl_pcie_prepare_card_hw(trans)) { + if (iwl_prepare_card_hw(trans)) { IWL_WARN(trans, "Exit HW not ready\n"); return -EIO; } - clear_bit(STATUS_FW_ERROR, &trans_pcie->status); - iwl_enable_rfkill_int(trans); /* If platform's RF_KILL switch is NOT set to KILL */ @@ -463,7 +1044,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, iwl_write32(trans, CSR_INT, 0xFFFFFFFF); - ret = iwl_pcie_nic_init(trans); + ret = iwl_nic_init(trans); if (ret) { IWL_ERR(trans, "Unable to init nic\n"); return ret; @@ -483,13 +1064,125 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); /* Load the given image to the HW */ - return iwl_pcie_load_given_ucode(trans, fw); + return iwl_load_given_ucode(trans, fw); } -static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans, u32 scd_addr) +/* + * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask + */ +static void iwl_trans_txq_set_sched(struct iwl_trans *trans, u32 mask) { - iwl_pcie_reset_ict(trans); - iwl_pcie_tx_start(trans, scd_addr); + struct iwl_trans_pcie __maybe_unused *trans_pcie = + IWL_TRANS_GET_PCIE_TRANS(trans); + + iwl_write_prph(trans, SCD_TXFACT, mask); +} + +static void iwl_tx_start(struct iwl_trans *trans) +{ + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + u32 a; + int chan; + u32 reg_val; + + /* make sure all queue are not stopped/used */ + memset(trans_pcie->queue_stopped, 0, sizeof(trans_pcie->queue_stopped)); + memset(trans_pcie->queue_used, 0, sizeof(trans_pcie->queue_used)); + + trans_pcie->scd_base_addr = + iwl_read_prph(trans, SCD_SRAM_BASE_ADDR); + a = trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_LOWER_BOUND; + /* reset conext data memory */ + for (; a < trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_UPPER_BOUND; + a += 4) + iwl_write_targ_mem(trans, a, 0); + /* reset tx status memory */ + for (; a < trans_pcie->scd_base_addr + SCD_TX_STTS_MEM_UPPER_BOUND; + a += 4) + iwl_write_targ_mem(trans, a, 0); + for (; a < trans_pcie->scd_base_addr + + SCD_TRANS_TBL_OFFSET_QUEUE( + trans->cfg->base_params->num_of_queues); + a += 4) + iwl_write_targ_mem(trans, a, 0); + + iwl_write_prph(trans, SCD_DRAM_BASE_ADDR, + trans_pcie->scd_bc_tbls.dma >> 10); + + /* The chain extension of the SCD doesn't work well. This feature is + * enabled by default by the HW, so we need to disable it manually. + */ + iwl_write_prph(trans, SCD_CHAINEXT_EN, 0); + + iwl_trans_ac_txq_enable(trans, trans_pcie->cmd_queue, + trans_pcie->cmd_fifo); + + /* Activate all Tx DMA/FIFO channels */ + iwl_trans_txq_set_sched(trans, IWL_MASK(0, 7)); + + /* Enable DMA channel */ + for (chan = 0; chan < FH_TCSR_CHNL_NUM ; chan++) + iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(chan), + FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | + FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE); + + /* Update FH chicken bits */ + reg_val = iwl_read_direct32(trans, FH_TX_CHICKEN_BITS_REG); + iwl_write_direct32(trans, FH_TX_CHICKEN_BITS_REG, + reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); + + /* Enable L1-Active */ + iwl_clear_bits_prph(trans, APMG_PCIDEV_STT_REG, + APMG_PCIDEV_STT_VAL_L1_ACT_DIS); +} + +static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans) +{ + iwl_reset_ict(trans); + iwl_tx_start(trans); +} + +/** + * iwlagn_txq_ctx_stop - Stop all Tx DMA channels + */ +static int iwl_trans_tx_stop(struct iwl_trans *trans) +{ + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + int ch, txq_id, ret; + unsigned long flags; + + /* Turn off all Tx DMA fifos */ + spin_lock_irqsave(&trans_pcie->irq_lock, flags); + + iwl_trans_txq_set_sched(trans, 0); + + /* Stop each Tx DMA channel, and wait for it to be idle */ + for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) { + iwl_write_direct32(trans, + FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0); + ret = iwl_poll_direct_bit(trans, FH_TSSR_TX_STATUS_REG, + FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), 1000); + if (ret < 0) + IWL_ERR(trans, + "Failing on timeout while stopping DMA channel %d [0x%08x]\n", + ch, + iwl_read_direct32(trans, + FH_TSSR_TX_STATUS_REG)); + } + spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); + + if (!trans_pcie->txq) { + IWL_WARN(trans, + "Stopping tx queues that aren't allocated...\n"); + return 0; + } + + /* Unmap DMA from host system and free skb's */ + for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues; + txq_id++) + iwl_tx_queue_unmap(trans, txq_id); + + return 0; } static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) @@ -503,7 +1196,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); /* device going down, Stop using ICT table */ - iwl_pcie_disable_ict(trans); + iwl_disable_ict(trans); /* * If a HW restart happens during firmware loading, @@ -513,8 +1206,8 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) * already dead. */ if (test_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status)) { - iwl_pcie_tx_stop(trans); - iwl_pcie_rx_stop(trans); + iwl_trans_tx_stop(trans); + iwl_trans_rx_stop(trans); /* Power-down device's busmaster DMA clocks */ iwl_write_prph(trans, APMG_CLK_DIS_REG, @@ -527,7 +1220,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); /* Stop the device, and put it in low power state */ - iwl_pcie_apm_stop(trans); + iwl_apm_stop(trans); /* Upon stop, the APM issues an interrupt if HW RF kill is set. * Clean again the interrupt here @@ -552,7 +1245,6 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) clear_bit(STATUS_INT_ENABLED, &trans_pcie->status); clear_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status); clear_bit(STATUS_TPOWER_PMI, &trans_pcie->status); - clear_bit(STATUS_RFKILL, &trans_pcie->status); } static void iwl_trans_pcie_wowlan_suspend(struct iwl_trans *trans) @@ -566,6 +1258,171 @@ static void iwl_trans_pcie_wowlan_suspend(struct iwl_trans *trans) CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); } +static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, + struct iwl_device_cmd *dev_cmd, int txq_id) +{ + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct iwl_tx_cmd *tx_cmd = (struct iwl_tx_cmd *) dev_cmd->payload; + struct iwl_cmd_meta *out_meta; + struct iwl_tx_queue *txq; + struct iwl_queue *q; + dma_addr_t phys_addr = 0; + dma_addr_t txcmd_phys; + dma_addr_t scratch_phys; + u16 len, firstlen, secondlen; + u8 wait_write_ptr = 0; + __le16 fc = hdr->frame_control; + u8 hdr_len = ieee80211_hdrlen(fc); + u16 __maybe_unused wifi_seq; + + txq = &trans_pcie->txq[txq_id]; + q = &txq->q; + + if (unlikely(!test_bit(txq_id, trans_pcie->queue_used))) { + WARN_ON_ONCE(1); + return -EINVAL; + } + + spin_lock(&txq->lock); + + /* In AGG mode, the index in the ring must correspond to the WiFi + * sequence number. This is a HW requirements to help the SCD to parse + * the BA. + * Check here that the packets are in the right place on the ring. + */ +#ifdef CONFIG_IWLWIFI_DEBUG + wifi_seq = SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl)); + WARN_ONCE((iwl_read_prph(trans, SCD_AGGR_SEL) & BIT(txq_id)) && + ((wifi_seq & 0xff) != q->write_ptr), + "Q: %d WiFi Seq %d tfdNum %d", + txq_id, wifi_seq, q->write_ptr); +#endif + + /* Set up driver data for this TFD */ + txq->entries[q->write_ptr].skb = skb; + txq->entries[q->write_ptr].cmd = dev_cmd; + + dev_cmd->hdr.cmd = REPLY_TX; + dev_cmd->hdr.sequence = + cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | + INDEX_TO_SEQ(q->write_ptr))); + + /* Set up first empty entry in queue's array of Tx/cmd buffers */ + out_meta = &txq->entries[q->write_ptr].meta; + + /* + * Use the first empty entry in this queue's command buffer array + * to contain the Tx command and MAC header concatenated together + * (payload data will be in another buffer). + * Size of this varies, due to varying MAC header length. + * If end is not dword aligned, we'll have 2 extra bytes at the end + * of the MAC header (device reads on dword boundaries). + * We'll tell device about this padding later. + */ + len = sizeof(struct iwl_tx_cmd) + + sizeof(struct iwl_cmd_header) + hdr_len; + firstlen = (len + 3) & ~3; + + /* Tell NIC about any 2-byte padding after MAC header */ + if (firstlen != len) + tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK; + + /* Physical address of this Tx command's header (not MAC header!), + * within command buffer array. */ + txcmd_phys = dma_map_single(trans->dev, + &dev_cmd->hdr, firstlen, + DMA_BIDIRECTIONAL); + if (unlikely(dma_mapping_error(trans->dev, txcmd_phys))) + goto out_err; + dma_unmap_addr_set(out_meta, mapping, txcmd_phys); + dma_unmap_len_set(out_meta, len, firstlen); + + if (!ieee80211_has_morefrags(fc)) { + txq->need_update = 1; + } else { + wait_write_ptr = 1; + txq->need_update = 0; + } + + /* Set up TFD's 2nd entry to point directly to remainder of skb, + * if any (802.11 null frames have no payload). */ + secondlen = skb->len - hdr_len; + if (secondlen > 0) { + phys_addr = dma_map_single(trans->dev, skb->data + hdr_len, + secondlen, DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { + dma_unmap_single(trans->dev, + dma_unmap_addr(out_meta, mapping), + dma_unmap_len(out_meta, len), + DMA_BIDIRECTIONAL); + goto out_err; + } + } + + /* Attach buffers to TFD */ + iwlagn_txq_attach_buf_to_tfd(trans, txq, txcmd_phys, firstlen, 1); + if (secondlen > 0) + iwlagn_txq_attach_buf_to_tfd(trans, txq, phys_addr, + secondlen, 0); + + scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) + + offsetof(struct iwl_tx_cmd, scratch); + + /* take back ownership of DMA buffer to enable update */ + dma_sync_single_for_cpu(trans->dev, txcmd_phys, firstlen, + DMA_BIDIRECTIONAL); + tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); + tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); + + IWL_DEBUG_TX(trans, "sequence nr = 0X%x\n", + le16_to_cpu(dev_cmd->hdr.sequence)); + IWL_DEBUG_TX(trans, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags)); + + /* Set up entry for this TFD in Tx byte-count array */ + iwl_trans_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); + + dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen, + DMA_BIDIRECTIONAL); + + trace_iwlwifi_dev_tx(trans->dev, skb, + &txq->tfds[txq->q.write_ptr], + sizeof(struct iwl_tfd), + &dev_cmd->hdr, firstlen, + skb->data + hdr_len, secondlen); + trace_iwlwifi_dev_tx_data(trans->dev, skb, + skb->data + hdr_len, secondlen); + + /* start timer if queue currently empty */ + if (txq->need_update && q->read_ptr == q->write_ptr && + trans_pcie->wd_timeout) + mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); + + /* Tell device the write index *just past* this latest filled TFD */ + q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); + iwl_txq_update_write_ptr(trans, txq); + + /* + * At this point the frame is "transmitted" successfully + * and we will get a TX status notification eventually, + * regardless of the value of ret. "ret" only indicates + * whether or not we should update the write pointer. + */ + if (iwl_queue_space(q) < q->high_mark) { + if (wait_write_ptr) { + txq->need_update = 1; + iwl_txq_update_write_ptr(trans, txq); + } else { + iwl_stop_queue(trans, txq); + } + } + spin_unlock(&txq->lock); + return 0; + out_err: + spin_unlock(&txq->lock); + return -1; +} + static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); @@ -576,28 +1433,29 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) if (!trans_pcie->irq_requested) { tasklet_init(&trans_pcie->irq_tasklet, (void (*)(unsigned long)) - iwl_pcie_tasklet, (unsigned long)trans); + iwl_irq_tasklet, (unsigned long)trans); - iwl_pcie_alloc_ict(trans); + iwl_alloc_isr_ict(trans); - err = request_irq(trans_pcie->irq, iwl_pcie_isr_ict, - IRQF_SHARED, DRV_NAME, trans); + err = request_irq(trans_pcie->irq, iwl_isr_ict, IRQF_SHARED, + DRV_NAME, trans); if (err) { IWL_ERR(trans, "Error allocating IRQ %d\n", trans_pcie->irq); goto error; } + INIT_WORK(&trans_pcie->rx_replenish, iwl_bg_rx_replenish); trans_pcie->irq_requested = true; } - err = iwl_pcie_prepare_card_hw(trans); + err = iwl_prepare_card_hw(trans); if (err) { IWL_ERR(trans, "Error while preparing HW: %d\n", err); goto err_free_irq; } - iwl_pcie_apm_init(trans); + iwl_apm_init(trans); /* From now on, the op_mode will be kept updated about RF kill state */ iwl_enable_rfkill_int(trans); @@ -611,7 +1469,7 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) trans_pcie->irq_requested = false; free_irq(trans_pcie->irq, trans); error: - iwl_pcie_free_ict(trans); + iwl_free_isr_ict(trans); tasklet_kill(&trans_pcie->irq_tasklet); return err; } @@ -627,7 +1485,7 @@ static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans, iwl_disable_interrupts(trans); spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); - iwl_pcie_apm_stop(trans); + iwl_apm_stop(trans); spin_lock_irqsave(&trans_pcie->irq_lock, flags); iwl_disable_interrupts(trans); @@ -651,6 +1509,27 @@ static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans, } } +static void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, + struct sk_buff_head *skbs) +{ + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; + /* n_bd is usually 256 => n_bd - 1 = 0xff */ + int tfd_num = ssn & (txq->q.n_bd - 1); + + spin_lock(&txq->lock); + + if (txq->q.read_ptr != tfd_num) { + IWL_DEBUG_TX_REPLY(trans, "[Q %d] %d -> %d (%d)\n", + txq_id, txq->q.read_ptr, tfd_num, ssn); + iwl_tx_queue_reclaim(trans, txq_id, tfd_num, skbs); + if (iwl_queue_space(&txq->q) > txq->q.low_mark) + iwl_wake_queue(trans, txq); + } + + spin_unlock(&txq->lock); +} + static void iwl_trans_pcie_write8(struct iwl_trans *trans, u32 ofs, u8 val) { writeb(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); @@ -697,12 +1576,12 @@ void iwl_trans_pcie_free(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - iwl_pcie_tx_free(trans); - iwl_pcie_rx_free(trans); + iwl_trans_pcie_tx_free(trans); + iwl_trans_pcie_rx_free(trans); if (trans_pcie->irq_requested == true) { free_irq(trans_pcie->irq, trans); - iwl_pcie_free_ict(trans); + iwl_free_isr_ict(trans); } pci_disable_msi(trans_pcie->pci_dev); @@ -748,10 +1627,10 @@ static int iwl_trans_pcie_resume(struct iwl_trans *trans) #define IWL_FLUSH_WAIT_MS 2000 -static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans) +static int iwl_trans_pcie_wait_tx_queue_empty(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_txq *txq; + struct iwl_tx_queue *txq; struct iwl_queue *q; int cnt; unsigned long now = jiffies; @@ -795,7 +1674,7 @@ static const char *get_fh_string(int cmd) #undef IWL_CMD } -int iwl_pcie_dump_fh(struct iwl_trans *trans, char **buf) +int iwl_dump_fh(struct iwl_trans *trans, char **buf) { int i; static const u32 fh_tbl[] = { @@ -874,7 +1753,7 @@ static const char *get_csr_string(int cmd) #undef IWL_CMD } -void iwl_pcie_dump_csr(struct iwl_trans *trans) +void iwl_dump_csr(struct iwl_trans *trans) { int i; static const u32 csr_tbl[] = { @@ -931,6 +1810,7 @@ static ssize_t iwl_dbgfs_##name##_write(struct file *file, \ const char __user *user_buf, \ size_t count, loff_t *ppos); + #define DEBUGFS_READ_FILE_OPS(name) \ DEBUGFS_READ_FUNC(name); \ static const struct file_operations iwl_dbgfs_##name##_ops = { \ @@ -963,7 +1843,7 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, { struct iwl_trans *trans = file->private_data; struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_txq *txq; + struct iwl_tx_queue *txq; struct iwl_queue *q; char *buf; int pos = 0; @@ -1000,7 +1880,7 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file, { struct iwl_trans *trans = file->private_data; struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_rxq *rxq = &trans_pcie->rxq; + struct iwl_rx_queue *rxq = &trans_pcie->rxq; char buf[256]; int pos = 0; const size_t bufsz = sizeof(buf); @@ -1119,7 +1999,7 @@ static ssize_t iwl_dbgfs_csr_write(struct file *file, if (sscanf(buf, "%d", &csr) != 1) return -EFAULT; - iwl_pcie_dump_csr(trans); + iwl_dump_csr(trans); return count; } @@ -1133,7 +2013,7 @@ static ssize_t iwl_dbgfs_fh_reg_read(struct file *file, int pos = 0; ssize_t ret = -EFAULT; - ret = pos = iwl_pcie_dump_fh(trans, &buf); + ret = pos = iwl_dump_fh(trans, &buf); if (buf) { ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); @@ -1202,7 +2082,7 @@ static const struct iwl_trans_ops trans_ops_pcie = { .wowlan_suspend = iwl_trans_pcie_wowlan_suspend, - .send_cmd = iwl_trans_pcie_send_hcmd, + .send_cmd = iwl_trans_pcie_send_cmd, .tx = iwl_trans_pcie_tx, .reclaim = iwl_trans_pcie_reclaim, @@ -1212,7 +2092,7 @@ static const struct iwl_trans_ops trans_ops_pcie = { .dbgfs_register = iwl_trans_pcie_dbgfs_register, - .wait_tx_queue_empty = iwl_trans_pcie_wait_txq_empty, + .wait_tx_queue_empty = iwl_trans_pcie_wait_tx_queue_empty, #ifdef CONFIG_PM_SLEEP .suspend = iwl_trans_pcie_suspend, @@ -1237,7 +2117,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, trans = kzalloc(sizeof(struct iwl_trans) + sizeof(struct iwl_trans_pcie), GFP_KERNEL); - if (!trans) + if (WARN_ON(!trans)) return NULL; trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); @@ -1270,38 +2150,43 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, DMA_BIT_MASK(32)); /* both attempts failed: */ if (err) { - dev_err(&pdev->dev, "No suitable DMA available\n"); + dev_printk(KERN_ERR, &pdev->dev, + "No suitable DMA available.\n"); goto out_pci_disable_device; } } err = pci_request_regions(pdev, DRV_NAME); if (err) { - dev_err(&pdev->dev, "pci_request_regions failed\n"); + dev_printk(KERN_ERR, &pdev->dev, + "pci_request_regions failed\n"); goto out_pci_disable_device; } trans_pcie->hw_base = pci_ioremap_bar(pdev, 0); if (!trans_pcie->hw_base) { - dev_err(&pdev->dev, "pci_ioremap_bar failed\n"); + dev_printk(KERN_ERR, &pdev->dev, "pci_ioremap_bar failed\n"); err = -ENODEV; goto out_pci_release_regions; } + dev_printk(KERN_INFO, &pdev->dev, + "pci_resource_len = 0x%08llx\n", + (unsigned long long) pci_resource_len(pdev, 0)); + dev_printk(KERN_INFO, &pdev->dev, + "pci_resource_base = %p\n", trans_pcie->hw_base); + + dev_printk(KERN_INFO, &pdev->dev, + "HW Revision ID = 0x%X\n", pdev->revision); + /* We disable the RETRY_TIMEOUT register (0x41) to keep * PCI Tx retries from interfering with C3 CPU state */ pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); err = pci_enable_msi(pdev); - if (err) { - dev_err(&pdev->dev, "pci_enable_msi failed(0X%x)\n", err); - /* enable rfkill interrupt: hw bug w/a */ - pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd); - if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { - pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; - pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); - } - } + if (err) + dev_printk(KERN_ERR, &pdev->dev, + "pci_enable_msi failed(0X%x)\n", err); trans->dev = &pdev->dev; trans_pcie->irq = pdev->irq; @@ -1311,8 +2196,16 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, snprintf(trans->hw_id_str, sizeof(trans->hw_id_str), "PCI ID: 0x%04X:0x%04X", pdev->device, pdev->subsystem_device); + /* TODO: Move this away, not needed if not MSI */ + /* enable rfkill interrupt: hw bug w/a */ + pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd); + if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { + pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; + pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); + } + /* Initialize the wait queue for commands */ - init_waitqueue_head(&trans_pcie->wait_command_queue); + init_waitqueue_head(&trans->wait_command_queue); spin_lock_init(&trans->reg_lock); snprintf(trans->dev_cmd_pool_name, sizeof(trans->dev_cmd_pool_name), diff --git a/trunk/drivers/net/wireless/iwlwifi/pcie/tx.c b/trunk/drivers/net/wireless/iwlwifi/pcie/tx.c index 6c5b867c353a..db3efbb84d92 100644 --- a/trunk/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/trunk/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -42,170 +42,12 @@ #define IWL_TX_CRC_SIZE 4 #define IWL_TX_DELIMITER_SIZE 4 -/*************** DMA-QUEUE-GENERAL-FUNCTIONS ***** - * DMA services - * - * Theory of operation - * - * A Tx or Rx queue resides in host DRAM, and is comprised of a circular buffer - * of buffer descriptors, each of which points to one or more data buffers for - * the device to read from or fill. Driver and device exchange status of each - * queue via "read" and "write" pointers. Driver keeps minimum of 2 empty - * entries in each circular buffer, to protect against confusing empty and full - * queue states. - * - * The device reads or writes the data in the queues via the device's several - * DMA/FIFO channels. Each queue is mapped to a single DMA channel. - * - * For Tx queue, there are low mark and high mark limits. If, after queuing - * the packet for Tx, free space become < low mark, Tx queue stopped. When - * reclaiming packets (on 'tx done IRQ), if free space become > high mark, - * Tx queue resumed. - * - ***************************************************/ -static int iwl_queue_space(const struct iwl_queue *q) -{ - int s = q->read_ptr - q->write_ptr; - - if (q->read_ptr > q->write_ptr) - s -= q->n_bd; - - if (s <= 0) - s += q->n_window; - /* keep some reserve to not confuse empty and full situations */ - s -= 2; - if (s < 0) - s = 0; - return s; -} - -/* - * iwl_queue_init - Initialize queue's high/low-water and read/write indexes +/** + * iwl_trans_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array */ -static int iwl_queue_init(struct iwl_queue *q, int count, int slots_num, u32 id) -{ - q->n_bd = count; - q->n_window = slots_num; - q->id = id; - - /* count must be power-of-two size, otherwise iwl_queue_inc_wrap - * and iwl_queue_dec_wrap are broken. */ - if (WARN_ON(!is_power_of_2(count))) - return -EINVAL; - - /* slots_num must be power-of-two size, otherwise - * get_cmd_index is broken. */ - if (WARN_ON(!is_power_of_2(slots_num))) - return -EINVAL; - - q->low_mark = q->n_window / 4; - if (q->low_mark < 4) - q->low_mark = 4; - - q->high_mark = q->n_window / 8; - if (q->high_mark < 2) - q->high_mark = 2; - - q->write_ptr = 0; - q->read_ptr = 0; - - return 0; -} - -static int iwl_pcie_alloc_dma_ptr(struct iwl_trans *trans, - struct iwl_dma_ptr *ptr, size_t size) -{ - if (WARN_ON(ptr->addr)) - return -EINVAL; - - ptr->addr = dma_alloc_coherent(trans->dev, size, - &ptr->dma, GFP_KERNEL); - if (!ptr->addr) - return -ENOMEM; - ptr->size = size; - return 0; -} - -static void iwl_pcie_free_dma_ptr(struct iwl_trans *trans, - struct iwl_dma_ptr *ptr) -{ - if (unlikely(!ptr->addr)) - return; - - dma_free_coherent(trans->dev, ptr->size, ptr->addr, ptr->dma); - memset(ptr, 0, sizeof(*ptr)); -} - -static void iwl_pcie_txq_stuck_timer(unsigned long data) -{ - struct iwl_txq *txq = (void *)data; - struct iwl_queue *q = &txq->q; - struct iwl_trans_pcie *trans_pcie = txq->trans_pcie; - struct iwl_trans *trans = iwl_trans_pcie_get_trans(trans_pcie); - u32 scd_sram_addr = trans_pcie->scd_base_addr + - SCD_TX_STTS_QUEUE_OFFSET(txq->q.id); - u8 buf[16]; - int i; - - spin_lock(&txq->lock); - /* check if triggered erroneously */ - if (txq->q.read_ptr == txq->q.write_ptr) { - spin_unlock(&txq->lock); - return; - } - spin_unlock(&txq->lock); - - IWL_ERR(trans, "Queue %d stuck for %u ms.\n", txq->q.id, - jiffies_to_msecs(trans_pcie->wd_timeout)); - IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n", - txq->q.read_ptr, txq->q.write_ptr); - - iwl_read_targ_mem_bytes(trans, scd_sram_addr, buf, sizeof(buf)); - - iwl_print_hex_error(trans, buf, sizeof(buf)); - - for (i = 0; i < FH_TCSR_CHNL_NUM; i++) - IWL_ERR(trans, "FH TRBs(%d) = 0x%08x\n", i, - iwl_read_direct32(trans, FH_TX_TRB_REG(i))); - - for (i = 0; i < trans->cfg->base_params->num_of_queues; i++) { - u32 status = iwl_read_prph(trans, SCD_QUEUE_STATUS_BITS(i)); - u8 fifo = (status >> SCD_QUEUE_STTS_REG_POS_TXF) & 0x7; - bool active = !!(status & BIT(SCD_QUEUE_STTS_REG_POS_ACTIVE)); - u32 tbl_dw = - iwl_read_targ_mem(trans, - trans_pcie->scd_base_addr + - SCD_TRANS_TBL_OFFSET_QUEUE(i)); - - if (i & 0x1) - tbl_dw = (tbl_dw & 0xFFFF0000) >> 16; - else - tbl_dw = tbl_dw & 0x0000FFFF; - - IWL_ERR(trans, - "Q %d is %sactive and mapped to fifo %d ra_tid 0x%04x [%d,%d]\n", - i, active ? "" : "in", fifo, tbl_dw, - iwl_read_prph(trans, - SCD_QUEUE_RDPTR(i)) & (txq->q.n_bd - 1), - iwl_read_prph(trans, SCD_QUEUE_WRPTR(i))); - } - - for (i = q->read_ptr; i != q->write_ptr; - i = iwl_queue_inc_wrap(i, q->n_bd)) { - struct iwl_tx_cmd *tx_cmd = - (struct iwl_tx_cmd *)txq->entries[i].cmd->payload; - IWL_ERR(trans, "scratch %d = 0x%08x\n", i, - get_unaligned_le32(&tx_cmd->scratch)); - } - - iwl_op_mode_nic_error(trans->op_mode); -} - -/* - * iwl_pcie_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array - */ -static void iwl_pcie_txq_update_byte_cnt_tbl(struct iwl_trans *trans, - struct iwl_txq *txq, u16 byte_cnt) +void iwl_trans_txq_update_byte_cnt_tbl(struct iwl_trans *trans, + struct iwl_tx_queue *txq, + u16 byte_cnt) { struct iwlagn_scd_bc_tbl *scd_bc_tbl; struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); @@ -246,36 +88,10 @@ static void iwl_pcie_txq_update_byte_cnt_tbl(struct iwl_trans *trans, tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent; } -static void iwl_pcie_txq_inval_byte_cnt_tbl(struct iwl_trans *trans, - struct iwl_txq *txq) -{ - struct iwl_trans_pcie *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwlagn_scd_bc_tbl *scd_bc_tbl = trans_pcie->scd_bc_tbls.addr; - int txq_id = txq->q.id; - int read_ptr = txq->q.read_ptr; - u8 sta_id = 0; - __le16 bc_ent; - struct iwl_tx_cmd *tx_cmd = - (void *)txq->entries[txq->q.read_ptr].cmd->payload; - - WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX); - - if (txq_id != trans_pcie->cmd_queue) - sta_id = tx_cmd->sta_id; - - bc_ent = cpu_to_le16(1 | (sta_id << 12)); - scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent; - - if (read_ptr < TFD_QUEUE_SIZE_BC_DUP) - scd_bc_tbl[txq_id]. - tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent; -} - -/* - * iwl_pcie_txq_inc_wr_ptr - Send new write index to hardware +/** + * iwl_txq_update_write_ptr - Send new write index to hardware */ -void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_txq *txq) +void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq) { u32 reg = 0; int txq_id = txq->q.id; @@ -321,7 +137,7 @@ void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_txq *txq) txq->need_update = 0; } -static inline dma_addr_t iwl_pcie_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx) +static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx) { struct iwl_tfd_tb *tb = &tfd->tbs[idx]; @@ -333,15 +149,15 @@ static inline dma_addr_t iwl_pcie_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx) return addr; } -static inline u16 iwl_pcie_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx) +static inline u16 iwl_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx) { struct iwl_tfd_tb *tb = &tfd->tbs[idx]; return le16_to_cpu(tb->hi_n_len) >> 4; } -static inline void iwl_pcie_tfd_set_tb(struct iwl_tfd *tfd, u8 idx, - dma_addr_t addr, u16 len) +static inline void iwl_tfd_set_tb(struct iwl_tfd *tfd, u8 idx, + dma_addr_t addr, u16 len) { struct iwl_tfd_tb *tb = &tfd->tbs[idx]; u16 hi_n_len = len << 4; @@ -355,20 +171,19 @@ static inline void iwl_pcie_tfd_set_tb(struct iwl_tfd *tfd, u8 idx, tfd->num_tbs = idx + 1; } -static inline u8 iwl_pcie_tfd_get_num_tbs(struct iwl_tfd *tfd) +static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd) { return tfd->num_tbs & 0x1f; } -static void iwl_pcie_tfd_unmap(struct iwl_trans *trans, - struct iwl_cmd_meta *meta, struct iwl_tfd *tfd, - enum dma_data_direction dma_dir) +static void iwl_unmap_tfd(struct iwl_trans *trans, struct iwl_cmd_meta *meta, + struct iwl_tfd *tfd, enum dma_data_direction dma_dir) { int i; int num_tbs; /* Sanity check on number of chunks */ - num_tbs = iwl_pcie_tfd_get_num_tbs(tfd); + num_tbs = iwl_tfd_get_num_tbs(tfd); if (num_tbs >= IWL_NUM_OF_TBS) { IWL_ERR(trans, "Too many chunks: %i\n", num_tbs); @@ -385,14 +200,14 @@ static void iwl_pcie_tfd_unmap(struct iwl_trans *trans, /* Unmap chunks, if any. */ for (i = 1; i < num_tbs; i++) - dma_unmap_single(trans->dev, iwl_pcie_tfd_tb_get_addr(tfd, i), - iwl_pcie_tfd_tb_get_len(tfd, i), dma_dir); + dma_unmap_single(trans->dev, iwl_tfd_tb_get_addr(tfd, i), + iwl_tfd_tb_get_len(tfd, i), dma_dir); tfd->num_tbs = 0; } -/* - * iwl_pcie_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] +/** + * iwl_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] * @trans - transport private data * @txq - tx queue * @dma_dir - the direction of the DMA mapping @@ -400,8 +215,8 @@ static void iwl_pcie_tfd_unmap(struct iwl_trans *trans, * Does NOT advance any TFD circular buffer read/write indexes * Does NOT free the TFD itself (which is within circular buffer) */ -static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq, - enum dma_data_direction dma_dir) +void iwl_txq_free_tfd(struct iwl_trans *trans, struct iwl_tx_queue *txq, + enum dma_data_direction dma_dir) { struct iwl_tfd *tfd_tmp = txq->tfds; @@ -412,8 +227,8 @@ static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq, lockdep_assert_held(&txq->lock); /* We have only q->n_window txq->entries, but we use q->n_bd tfds */ - iwl_pcie_tfd_unmap(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr], - dma_dir); + iwl_unmap_tfd(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr], + dma_dir); /* free SKB */ if (txq->entries) { @@ -432,8 +247,10 @@ static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq, } } -static int iwl_pcie_txq_build_tfd(struct iwl_trans *trans, struct iwl_txq *txq, - dma_addr_t addr, u16 len, u8 reset) +int iwlagn_txq_attach_buf_to_tfd(struct iwl_trans *trans, + struct iwl_tx_queue *txq, + dma_addr_t addr, u16 len, + u8 reset) { struct iwl_queue *q; struct iwl_tfd *tfd, *tfd_tmp; @@ -446,550 +263,124 @@ static int iwl_pcie_txq_build_tfd(struct iwl_trans *trans, struct iwl_txq *txq, if (reset) memset(tfd, 0, sizeof(*tfd)); - num_tbs = iwl_pcie_tfd_get_num_tbs(tfd); - - /* Each TFD can point to a maximum 20 Tx buffers */ - if (num_tbs >= IWL_NUM_OF_TBS) { - IWL_ERR(trans, "Error can not send more than %d chunks\n", - IWL_NUM_OF_TBS); - return -EINVAL; - } - - if (WARN_ON(addr & ~DMA_BIT_MASK(36))) - return -EINVAL; - - if (unlikely(addr & ~IWL_TX_DMA_MASK)) - IWL_ERR(trans, "Unaligned address = %llx\n", - (unsigned long long)addr); - - iwl_pcie_tfd_set_tb(tfd, num_tbs, addr, len); - - return 0; -} - -static int iwl_pcie_txq_alloc(struct iwl_trans *trans, - struct iwl_txq *txq, int slots_num, - u32 txq_id) -{ - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX; - int i; - - if (WARN_ON(txq->entries || txq->tfds)) - return -EINVAL; - - setup_timer(&txq->stuck_timer, iwl_pcie_txq_stuck_timer, - (unsigned long)txq); - txq->trans_pcie = trans_pcie; - - txq->q.n_window = slots_num; - - txq->entries = kcalloc(slots_num, - sizeof(struct iwl_pcie_txq_entry), - GFP_KERNEL); - - if (!txq->entries) - goto error; - - if (txq_id == trans_pcie->cmd_queue) - for (i = 0; i < slots_num; i++) { - txq->entries[i].cmd = - kmalloc(sizeof(struct iwl_device_cmd), - GFP_KERNEL); - if (!txq->entries[i].cmd) - goto error; - } - - /* Circular buffer of transmit frame descriptors (TFDs), - * shared with device */ - txq->tfds = dma_alloc_coherent(trans->dev, tfd_sz, - &txq->q.dma_addr, GFP_KERNEL); - if (!txq->tfds) { - IWL_ERR(trans, "dma_alloc_coherent(%zd) failed\n", tfd_sz); - goto error; - } - txq->q.id = txq_id; - - return 0; -error: - if (txq->entries && txq_id == trans_pcie->cmd_queue) - for (i = 0; i < slots_num; i++) - kfree(txq->entries[i].cmd); - kfree(txq->entries); - txq->entries = NULL; - - return -ENOMEM; - -} - -static int iwl_pcie_txq_init(struct iwl_trans *trans, struct iwl_txq *txq, - int slots_num, u32 txq_id) -{ - int ret; - - txq->need_update = 0; - - /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise - * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */ - BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); - - /* Initialize queue's high/low-water marks, and head/tail indexes */ - ret = iwl_queue_init(&txq->q, TFD_QUEUE_SIZE_MAX, slots_num, - txq_id); - if (ret) - return ret; - - spin_lock_init(&txq->lock); - - /* - * Tell nic where to find circular buffer of Tx Frame Descriptors for - * given Tx queue, and enable the DMA channel used for that queue. - * Circular buffer (TFD queue in DRAM) physical base address */ - iwl_write_direct32(trans, FH_MEM_CBBC_QUEUE(txq_id), - txq->q.dma_addr >> 8); - - return 0; -} - -/* - * iwl_pcie_txq_unmap - Unmap any remaining DMA mappings and free skb's - */ -static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id) -{ - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_txq *txq = &trans_pcie->txq[txq_id]; - struct iwl_queue *q = &txq->q; - enum dma_data_direction dma_dir; - - if (!q->n_bd) - return; - - /* In the command queue, all the TBs are mapped as BIDI - * so unmap them as such. - */ - if (txq_id == trans_pcie->cmd_queue) - dma_dir = DMA_BIDIRECTIONAL; - else - dma_dir = DMA_TO_DEVICE; - - spin_lock_bh(&txq->lock); - while (q->write_ptr != q->read_ptr) { - iwl_pcie_txq_free_tfd(trans, txq, dma_dir); - q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); - } - spin_unlock_bh(&txq->lock); -} - -/* - * iwl_pcie_txq_free - Deallocate DMA queue. - * @txq: Transmit queue to deallocate. - * - * Empty queue by removing and destroying all BD's. - * Free all buffers. - * 0-fill, but do not free "txq" descriptor structure. - */ -static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id) -{ - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_txq *txq = &trans_pcie->txq[txq_id]; - struct device *dev = trans->dev; - int i; - - if (WARN_ON(!txq)) - return; - - iwl_pcie_txq_unmap(trans, txq_id); - - /* De-alloc array of command/tx buffers */ - if (txq_id == trans_pcie->cmd_queue) - for (i = 0; i < txq->q.n_window; i++) { - kfree(txq->entries[i].cmd); - kfree(txq->entries[i].copy_cmd); - kfree(txq->entries[i].free_buf); - } - - /* De-alloc circular buffer of TFDs */ - if (txq->q.n_bd) { - dma_free_coherent(dev, sizeof(struct iwl_tfd) * - txq->q.n_bd, txq->tfds, txq->q.dma_addr); - memset(&txq->q.dma_addr, 0, sizeof(txq->q.dma_addr)); - } - - kfree(txq->entries); - txq->entries = NULL; - - del_timer_sync(&txq->stuck_timer); - - /* 0-fill queue descriptor structure */ - memset(txq, 0, sizeof(*txq)); -} - -/* - * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask - */ -static void iwl_pcie_txq_set_sched(struct iwl_trans *trans, u32 mask) -{ - struct iwl_trans_pcie __maybe_unused *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(trans); - - iwl_write_prph(trans, SCD_TXFACT, mask); -} - -void iwl_pcie_tx_start(struct iwl_trans *trans, u32 scd_base_addr) -{ - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - u32 a; - int chan; - u32 reg_val; - - /* make sure all queue are not stopped/used */ - memset(trans_pcie->queue_stopped, 0, sizeof(trans_pcie->queue_stopped)); - memset(trans_pcie->queue_used, 0, sizeof(trans_pcie->queue_used)); - - trans_pcie->scd_base_addr = - iwl_read_prph(trans, SCD_SRAM_BASE_ADDR); - - WARN_ON(scd_base_addr != 0 && - scd_base_addr != trans_pcie->scd_base_addr); - - a = trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_LOWER_BOUND; - /* reset conext data memory */ - for (; a < trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_UPPER_BOUND; - a += 4) - iwl_write_targ_mem(trans, a, 0); - /* reset tx status memory */ - for (; a < trans_pcie->scd_base_addr + SCD_TX_STTS_MEM_UPPER_BOUND; - a += 4) - iwl_write_targ_mem(trans, a, 0); - for (; a < trans_pcie->scd_base_addr + - SCD_TRANS_TBL_OFFSET_QUEUE( - trans->cfg->base_params->num_of_queues); - a += 4) - iwl_write_targ_mem(trans, a, 0); - - iwl_write_prph(trans, SCD_DRAM_BASE_ADDR, - trans_pcie->scd_bc_tbls.dma >> 10); - - /* The chain extension of the SCD doesn't work well. This feature is - * enabled by default by the HW, so we need to disable it manually. - */ - iwl_write_prph(trans, SCD_CHAINEXT_EN, 0); - - iwl_trans_ac_txq_enable(trans, trans_pcie->cmd_queue, - trans_pcie->cmd_fifo); - - /* Activate all Tx DMA/FIFO channels */ - iwl_pcie_txq_set_sched(trans, IWL_MASK(0, 7)); - - /* Enable DMA channel */ - for (chan = 0; chan < FH_TCSR_CHNL_NUM; chan++) - iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(chan), - FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | - FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE); - - /* Update FH chicken bits */ - reg_val = iwl_read_direct32(trans, FH_TX_CHICKEN_BITS_REG); - iwl_write_direct32(trans, FH_TX_CHICKEN_BITS_REG, - reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); - - /* Enable L1-Active */ - iwl_clear_bits_prph(trans, APMG_PCIDEV_STT_REG, - APMG_PCIDEV_STT_VAL_L1_ACT_DIS); -} - -/* - * iwl_pcie_tx_stop - Stop all Tx DMA channels - */ -int iwl_pcie_tx_stop(struct iwl_trans *trans) -{ - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - int ch, txq_id, ret; - unsigned long flags; - - /* Turn off all Tx DMA fifos */ - spin_lock_irqsave(&trans_pcie->irq_lock, flags); - - iwl_pcie_txq_set_sched(trans, 0); - - /* Stop each Tx DMA channel, and wait for it to be idle */ - for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) { - iwl_write_direct32(trans, - FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0); - ret = iwl_poll_direct_bit(trans, FH_TSSR_TX_STATUS_REG, - FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), 1000); - if (ret < 0) - IWL_ERR(trans, - "Failing on timeout while stopping DMA channel %d [0x%08x]\n", - ch, - iwl_read_direct32(trans, - FH_TSSR_TX_STATUS_REG)); - } - spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); - - if (!trans_pcie->txq) { - IWL_WARN(trans, - "Stopping tx queues that aren't allocated...\n"); - return 0; - } - - /* Unmap DMA from host system and free skb's */ - for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues; - txq_id++) - iwl_pcie_txq_unmap(trans, txq_id); - - return 0; -} - -/* - * iwl_trans_tx_free - Free TXQ Context - * - * Destroy all TX DMA queues and structures - */ -void iwl_pcie_tx_free(struct iwl_trans *trans) -{ - int txq_id; - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - - /* Tx queues */ - if (trans_pcie->txq) { - for (txq_id = 0; - txq_id < trans->cfg->base_params->num_of_queues; txq_id++) - iwl_pcie_txq_free(trans, txq_id); - } - - kfree(trans_pcie->txq); - trans_pcie->txq = NULL; - - iwl_pcie_free_dma_ptr(trans, &trans_pcie->kw); - - iwl_pcie_free_dma_ptr(trans, &trans_pcie->scd_bc_tbls); -} - -/* - * iwl_pcie_tx_alloc - allocate TX context - * Allocate all Tx DMA structures and initialize them - */ -static int iwl_pcie_tx_alloc(struct iwl_trans *trans) -{ - int ret; - int txq_id, slots_num; - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - - u16 scd_bc_tbls_size = trans->cfg->base_params->num_of_queues * - sizeof(struct iwlagn_scd_bc_tbl); - - /*It is not allowed to alloc twice, so warn when this happens. - * We cannot rely on the previous allocation, so free and fail */ - if (WARN_ON(trans_pcie->txq)) { - ret = -EINVAL; - goto error; - } - - ret = iwl_pcie_alloc_dma_ptr(trans, &trans_pcie->scd_bc_tbls, - scd_bc_tbls_size); - if (ret) { - IWL_ERR(trans, "Scheduler BC Table allocation failed\n"); - goto error; - } - - /* Alloc keep-warm buffer */ - ret = iwl_pcie_alloc_dma_ptr(trans, &trans_pcie->kw, IWL_KW_SIZE); - if (ret) { - IWL_ERR(trans, "Keep Warm allocation failed\n"); - goto error; - } - - trans_pcie->txq = kcalloc(trans->cfg->base_params->num_of_queues, - sizeof(struct iwl_txq), GFP_KERNEL); - if (!trans_pcie->txq) { - IWL_ERR(trans, "Not enough memory for txq\n"); - ret = ENOMEM; - goto error; - } - - /* Alloc and init all Tx queues, including the command queue (#4/#9) */ - for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues; - txq_id++) { - slots_num = (txq_id == trans_pcie->cmd_queue) ? - TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; - ret = iwl_pcie_txq_alloc(trans, &trans_pcie->txq[txq_id], - slots_num, txq_id); - if (ret) { - IWL_ERR(trans, "Tx %d queue alloc failed\n", txq_id); - goto error; - } - } - - return 0; - -error: - iwl_pcie_tx_free(trans); - - return ret; -} -int iwl_pcie_tx_init(struct iwl_trans *trans) -{ - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - int ret; - int txq_id, slots_num; - unsigned long flags; - bool alloc = false; - - if (!trans_pcie->txq) { - ret = iwl_pcie_tx_alloc(trans); - if (ret) - goto error; - alloc = true; - } - - spin_lock_irqsave(&trans_pcie->irq_lock, flags); - - /* Turn off all Tx DMA fifos */ - iwl_write_prph(trans, SCD_TXFACT, 0); - - /* Tell NIC where to find the "keep warm" buffer */ - iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG, - trans_pcie->kw.dma >> 4); - - spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); - - /* Alloc and init all Tx queues, including the command queue (#4/#9) */ - for (txq_id = 0; txq_id < trans->cfg->base_params->num_of_queues; - txq_id++) { - slots_num = (txq_id == trans_pcie->cmd_queue) ? - TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; - ret = iwl_pcie_txq_init(trans, &trans_pcie->txq[txq_id], - slots_num, txq_id); - if (ret) { - IWL_ERR(trans, "Tx %d queue init failed\n", txq_id); - goto error; - } - } - - return 0; -error: - /*Upon error, free only if we allocated something */ - if (alloc) - iwl_pcie_tx_free(trans); - return ret; -} - -static inline void iwl_pcie_txq_progress(struct iwl_trans_pcie *trans_pcie, - struct iwl_txq *txq) -{ - if (!trans_pcie->wd_timeout) - return; - - /* - * if empty delete timer, otherwise move timer forward - * since we're making progress on this queue - */ - if (txq->q.read_ptr == txq->q.write_ptr) - del_timer(&txq->stuck_timer); - else - mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); -} - -/* Frees buffers until index _not_ inclusive */ -void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, - struct sk_buff_head *skbs) -{ - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_txq *txq = &trans_pcie->txq[txq_id]; - /* n_bd is usually 256 => n_bd - 1 = 0xff */ - int tfd_num = ssn & (txq->q.n_bd - 1); - struct iwl_queue *q = &txq->q; - int last_to_free; + num_tbs = iwl_tfd_get_num_tbs(tfd); - /* This function is not meant to release cmd queue*/ - if (WARN_ON(txq_id == trans_pcie->cmd_queue)) - return; + /* Each TFD can point to a maximum 20 Tx buffers */ + if (num_tbs >= IWL_NUM_OF_TBS) { + IWL_ERR(trans, "Error can not send more than %d chunks\n", + IWL_NUM_OF_TBS); + return -EINVAL; + } - spin_lock(&txq->lock); + if (WARN_ON(addr & ~DMA_BIT_MASK(36))) + return -EINVAL; - if (txq->q.read_ptr == tfd_num) - goto out; + if (unlikely(addr & ~IWL_TX_DMA_MASK)) + IWL_ERR(trans, "Unaligned address = %llx\n", + (unsigned long long)addr); - IWL_DEBUG_TX_REPLY(trans, "[Q %d] %d -> %d (%d)\n", - txq_id, txq->q.read_ptr, tfd_num, ssn); + iwl_tfd_set_tb(tfd, num_tbs, addr, len); - /*Since we free until index _not_ inclusive, the one before index is - * the last we will free. This one must be used */ - last_to_free = iwl_queue_dec_wrap(tfd_num, q->n_bd); + return 0; +} - if (!iwl_queue_used(q, last_to_free)) { - IWL_ERR(trans, - "%s: Read index for DMA queue txq id (%d), last_to_free %d is out of range [0-%d] %d %d.\n", - __func__, txq_id, last_to_free, q->n_bd, - q->write_ptr, q->read_ptr); - goto out; - } +/*************** DMA-QUEUE-GENERAL-FUNCTIONS ***** + * DMA services + * + * Theory of operation + * + * A Tx or Rx queue resides in host DRAM, and is comprised of a circular buffer + * of buffer descriptors, each of which points to one or more data buffers for + * the device to read from or fill. Driver and device exchange status of each + * queue via "read" and "write" pointers. Driver keeps minimum of 2 empty + * entries in each circular buffer, to protect against confusing empty and full + * queue states. + * + * The device reads or writes the data in the queues via the device's several + * DMA/FIFO channels. Each queue is mapped to a single DMA channel. + * + * For Tx queue, there are low mark and high mark limits. If, after queuing + * the packet for Tx, free space become < low mark, Tx queue stopped. When + * reclaiming packets (on 'tx done IRQ), if free space become > high mark, + * Tx queue resumed. + * + ***************************************************/ - if (WARN_ON(!skb_queue_empty(skbs))) - goto out; +int iwl_queue_space(const struct iwl_queue *q) +{ + int s = q->read_ptr - q->write_ptr; - for (; - q->read_ptr != tfd_num; - q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { + if (q->read_ptr > q->write_ptr) + s -= q->n_bd; - if (WARN_ON_ONCE(txq->entries[txq->q.read_ptr].skb == NULL)) - continue; + if (s <= 0) + s += q->n_window; + /* keep some reserve to not confuse empty and full situations */ + s -= 2; + if (s < 0) + s = 0; + return s; +} - __skb_queue_tail(skbs, txq->entries[txq->q.read_ptr].skb); +/** + * iwl_queue_init - Initialize queue's high/low-water and read/write indexes + */ +int iwl_queue_init(struct iwl_queue *q, int count, int slots_num, u32 id) +{ + q->n_bd = count; + q->n_window = slots_num; + q->id = id; - txq->entries[txq->q.read_ptr].skb = NULL; + /* count must be power-of-two size, otherwise iwl_queue_inc_wrap + * and iwl_queue_dec_wrap are broken. */ + if (WARN_ON(!is_power_of_2(count))) + return -EINVAL; - iwl_pcie_txq_inval_byte_cnt_tbl(trans, txq); + /* slots_num must be power-of-two size, otherwise + * get_cmd_index is broken. */ + if (WARN_ON(!is_power_of_2(slots_num))) + return -EINVAL; - iwl_pcie_txq_free_tfd(trans, txq, DMA_TO_DEVICE); - } + q->low_mark = q->n_window / 4; + if (q->low_mark < 4) + q->low_mark = 4; + + q->high_mark = q->n_window / 8; + if (q->high_mark < 2) + q->high_mark = 2; - iwl_pcie_txq_progress(trans_pcie, txq); + q->write_ptr = q->read_ptr = 0; - if (iwl_queue_space(&txq->q) > txq->q.low_mark) - iwl_wake_queue(trans, txq); -out: - spin_unlock(&txq->lock); + return 0; } -/* - * iwl_pcie_cmdq_reclaim - Reclaim TX command queue entries already Tx'd - * - * When FW advances 'R' index, all entries between old and new 'R' index - * need to be reclaimed. As result, some free space forms. If there is - * enough free space (> low mark), wake the stack that feeds us. - */ -static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx) +static void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_trans *trans, + struct iwl_tx_queue *txq) { - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_txq *txq = &trans_pcie->txq[txq_id]; - struct iwl_queue *q = &txq->q; - int nfreed = 0; - - lockdep_assert_held(&txq->lock); + struct iwl_trans_pcie *trans_pcie = + IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwlagn_scd_bc_tbl *scd_bc_tbl = trans_pcie->scd_bc_tbls.addr; + int txq_id = txq->q.id; + int read_ptr = txq->q.read_ptr; + u8 sta_id = 0; + __le16 bc_ent; + struct iwl_tx_cmd *tx_cmd = + (void *)txq->entries[txq->q.read_ptr].cmd->payload; - if ((idx >= q->n_bd) || (!iwl_queue_used(q, idx))) { - IWL_ERR(trans, - "%s: Read index for DMA queue txq id (%d), index %d is out of range [0-%d] %d %d.\n", - __func__, txq_id, idx, q->n_bd, - q->write_ptr, q->read_ptr); - return; - } + WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX); - for (idx = iwl_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx; - q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { + if (txq_id != trans_pcie->cmd_queue) + sta_id = tx_cmd->sta_id; - if (nfreed++ > 0) { - IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n", - idx, q->write_ptr, q->read_ptr); - iwl_op_mode_nic_error(trans->op_mode); - } - } + bc_ent = cpu_to_le16(1 | (sta_id << 12)); + scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent; - iwl_pcie_txq_progress(trans_pcie, txq); + if (read_ptr < TFD_QUEUE_SIZE_BC_DUP) + scd_bc_tbl[txq_id]. + tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent; } -static int iwl_pcie_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid, +static int iwl_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid, u16 txq_id) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); @@ -1014,8 +405,7 @@ static int iwl_pcie_txq_set_ratid_map(struct iwl_trans *trans, u16 ra_tid, return 0; } -static inline void iwl_pcie_txq_set_inactive(struct iwl_trans *trans, - u16 txq_id) +static inline void iwl_txq_set_inactive(struct iwl_trans *trans, u16 txq_id) { /* Simply stop the queue, but don't change any configuration; * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */ @@ -1034,7 +424,7 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, WARN_ONCE(1, "queue %d already used - expect issues", txq_id); /* Stop this Tx queue before configuring it */ - iwl_pcie_txq_set_inactive(trans, txq_id); + iwl_txq_set_inactive(trans, txq_id); /* Set this queue as a chain-building queue unless it is CMD queue */ if (txq_id != trans_pcie->cmd_queue) @@ -1045,7 +435,7 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo, u16 ra_tid = BUILD_RAxTID(sta_id, tid); /* Map receiver-address / traffic-ID to this queue */ - iwl_pcie_txq_set_ratid_map(trans, ra_tid, txq_id); + iwl_txq_set_ratid_map(trans, ra_tid, txq_id); /* enable aggregations for the queue */ iwl_set_bits_prph(trans, SCD_AGGR_SEL, BIT(txq_id)); @@ -1099,20 +489,18 @@ void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) return; } - iwl_pcie_txq_set_inactive(trans, txq_id); + iwl_txq_set_inactive(trans, txq_id); _iwl_write_targ_mem_dwords(trans, stts_addr, zero_val, ARRAY_SIZE(zero_val)); - iwl_pcie_txq_unmap(trans, txq_id); - IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id); } /*************** HOST COMMAND QUEUE FUNCTIONS *****/ -/* - * iwl_pcie_enqueue_hcmd - enqueue a uCode command +/** + * iwl_enqueue_hcmd - enqueue a uCode command * @priv: device private data point * @cmd: a point to the ucode command structure * @@ -1120,17 +508,15 @@ void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id) * failed. On success, it turns the index (> 0) of command in the * command queue. */ -static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, - struct iwl_host_cmd *cmd) +static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_txq *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; + struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; struct iwl_queue *q = &txq->q; struct iwl_device_cmd *out_cmd; struct iwl_cmd_meta *out_meta; - void *dup_buf = NULL; dma_addr_t phys_addr; - int idx; + u32 idx; u16 copy_size, cmd_size; bool had_nocopy = false; int i; @@ -1147,33 +533,10 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, continue; if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) { had_nocopy = true; - if (WARN_ON(cmd->dataflags[i] & IWL_HCMD_DFL_DUP)) { - idx = -EINVAL; - goto free_dup_buf; - } - } else if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP) { - /* - * This is also a chunk that isn't copied - * to the static buffer so set had_nocopy. - */ - had_nocopy = true; - - /* only allowed once */ - if (WARN_ON(dup_buf)) { - idx = -EINVAL; - goto free_dup_buf; - } - - dup_buf = kmemdup(cmd->data[i], cmd->len[i], - GFP_ATOMIC); - if (!dup_buf) - return -ENOMEM; } else { /* NOCOPY must not be followed by normal! */ - if (WARN_ON(had_nocopy)) { - idx = -EINVAL; - goto free_dup_buf; - } + if (WARN_ON(had_nocopy)) + return -EINVAL; copy_size += cmd->len[i]; } cmd_size += cmd->len[i]; @@ -1187,10 +550,9 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, */ if (WARN(copy_size > TFD_MAX_PAYLOAD_SIZE, "Command %s (%#x) is too large (%d bytes)\n", - get_cmd_string(trans_pcie, cmd->id), cmd->id, copy_size)) { - idx = -EINVAL; - goto free_dup_buf; - } + trans_pcie_get_cmd_string(trans_pcie, cmd->id), + cmd->id, copy_size)) + return -EINVAL; spin_lock_bh(&txq->lock); @@ -1199,8 +561,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, IWL_ERR(trans, "No space in command queue\n"); iwl_op_mode_cmd_queue_full(trans->op_mode); - idx = -ENOSPC; - goto free_dup_buf; + return -ENOSPC; } idx = get_cmd_index(q, q->write_ptr); @@ -1224,8 +585,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { if (!cmd->len[i]) continue; - if (cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY | - IWL_HCMD_DFL_DUP)) + if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) break; memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], cmd->len[i]); cmd_pos += cmd->len[i]; @@ -1250,7 +610,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, IWL_DEBUG_HC(trans, "Sending command %s (#%x), seq: 0x%04X, %d bytes at %d[%d]:%d\n", - get_cmd_string(trans_pcie, out_cmd->hdr.cmd), + trans_pcie_get_cmd_string(trans_pcie, out_cmd->hdr.cmd), out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), cmd_size, q->write_ptr, idx, trans_pcie->cmd_queue); @@ -1264,35 +624,28 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, dma_unmap_addr_set(out_meta, mapping, phys_addr); dma_unmap_len_set(out_meta, len, copy_size); - iwl_pcie_txq_build_tfd(trans, txq, phys_addr, copy_size, 1); + iwlagn_txq_attach_buf_to_tfd(trans, txq, phys_addr, copy_size, 1); for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { - const void *data = cmd->data[i]; - if (!cmd->len[i]) continue; - if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY | - IWL_HCMD_DFL_DUP))) + if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)) continue; - if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP) - data = dup_buf; - phys_addr = dma_map_single(trans->dev, (void *)data, + phys_addr = dma_map_single(trans->dev, (void *)cmd->data[i], cmd->len[i], DMA_BIDIRECTIONAL); if (dma_mapping_error(trans->dev, phys_addr)) { - iwl_pcie_tfd_unmap(trans, out_meta, - &txq->tfds[q->write_ptr], - DMA_BIDIRECTIONAL); + iwl_unmap_tfd(trans, out_meta, + &txq->tfds[q->write_ptr], + DMA_BIDIRECTIONAL); idx = -ENOMEM; goto out; } - iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmd->len[i], 0); + iwlagn_txq_attach_buf_to_tfd(trans, txq, phys_addr, + cmd->len[i], 0); } out_meta->flags = cmd->flags; - if (WARN_ON_ONCE(txq->entries[idx].free_buf)) - kfree(txq->entries[idx].free_buf); - txq->entries[idx].free_buf = dup_buf; txq->need_update = 1; @@ -1305,18 +658,70 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, /* Increment and update queue's write index */ q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); - iwl_pcie_txq_inc_wr_ptr(trans, txq); + iwl_txq_update_write_ptr(trans, txq); out: spin_unlock_bh(&txq->lock); - free_dup_buf: - if (idx < 0) - kfree(dup_buf); return idx; } -/* - * iwl_pcie_hcmd_complete - Pull unused buffers off the queue and reclaim them +static inline void iwl_queue_progress(struct iwl_trans_pcie *trans_pcie, + struct iwl_tx_queue *txq) +{ + if (!trans_pcie->wd_timeout) + return; + + /* + * if empty delete timer, otherwise move timer forward + * since we're making progress on this queue + */ + if (txq->q.read_ptr == txq->q.write_ptr) + del_timer(&txq->stuck_timer); + else + mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); +} + +/** + * iwl_hcmd_queue_reclaim - Reclaim TX command queue entries already Tx'd + * + * When FW advances 'R' index, all entries between old and new 'R' index + * need to be reclaimed. As result, some free space forms. If there is + * enough free space (> low mark), wake the stack that feeds us. + */ +static void iwl_hcmd_queue_reclaim(struct iwl_trans *trans, int txq_id, + int idx) +{ + struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; + struct iwl_queue *q = &txq->q; + int nfreed = 0; + + lockdep_assert_held(&txq->lock); + + if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) { + IWL_ERR(trans, + "%s: Read index for DMA queue txq id (%d), index %d is out of range [0-%d] %d %d.\n", + __func__, txq_id, idx, q->n_bd, + q->write_ptr, q->read_ptr); + return; + } + + for (idx = iwl_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx; + q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { + + if (nfreed++ > 0) { + IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n", + idx, q->write_ptr, q->read_ptr); + iwl_op_mode_nic_error(trans->op_mode); + } + + } + + iwl_queue_progress(trans_pcie, txq); +} + +/** + * iwl_tx_cmd_complete - Pull unused buffers off the queue and reclaim them * @rxb: Rx buffer to reclaim * @handler_status: return value of the handler of the command * (put in setup_rx_handlers) @@ -1325,8 +730,8 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, * will be executed. The attached skb (if present) will only be freed * if the callback returns 1 */ -void iwl_pcie_hcmd_complete(struct iwl_trans *trans, - struct iwl_rx_cmd_buffer *rxb, int handler_status) +void iwl_tx_cmd_complete(struct iwl_trans *trans, struct iwl_rx_cmd_buffer *rxb, + int handler_status) { struct iwl_rx_packet *pkt = rxb_addr(rxb); u16 sequence = le16_to_cpu(pkt->hdr.sequence); @@ -1336,7 +741,7 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans, struct iwl_device_cmd *cmd; struct iwl_cmd_meta *meta; struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct iwl_txq *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; + struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; /* If a Tx command is being handled and it isn't in the actual * command queue then there a command routing bug has been introduced @@ -1356,7 +761,7 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans, cmd = txq->entries[cmd_index].cmd; meta = &txq->entries[cmd_index].meta; - iwl_pcie_tfd_unmap(trans, meta, &txq->tfds[index], DMA_BIDIRECTIONAL); + iwl_unmap_tfd(trans, meta, &txq->tfds[index], DMA_BIDIRECTIONAL); /* Input error checking is done when commands are added to queue. */ if (meta->flags & CMD_WANT_SKB) { @@ -1368,18 +773,20 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans, meta->source->handler_status = handler_status; } - iwl_pcie_cmdq_reclaim(trans, txq_id, index); + iwl_hcmd_queue_reclaim(trans, txq_id, index); if (!(meta->flags & CMD_ASYNC)) { if (!test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) { IWL_WARN(trans, "HCMD_ACTIVE already clear for command %s\n", - get_cmd_string(trans_pcie, cmd->hdr.cmd)); + trans_pcie_get_cmd_string(trans_pcie, + cmd->hdr.cmd)); } clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n", - get_cmd_string(trans_pcie, cmd->hdr.cmd)); - wake_up(&trans_pcie->wait_command_queue); + trans_pcie_get_cmd_string(trans_pcie, + cmd->hdr.cmd)); + wake_up(&trans->wait_command_queue); } meta->flags = 0; @@ -1389,8 +796,7 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans, #define HOST_COMPLETE_TIMEOUT (2 * HZ) -static int iwl_pcie_send_hcmd_async(struct iwl_trans *trans, - struct iwl_host_cmd *cmd) +static int iwl_send_cmd_async(struct iwl_trans *trans, struct iwl_host_cmd *cmd) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int ret; @@ -1399,59 +805,59 @@ static int iwl_pcie_send_hcmd_async(struct iwl_trans *trans, if (WARN_ON(cmd->flags & CMD_WANT_SKB)) return -EINVAL; - ret = iwl_pcie_enqueue_hcmd(trans, cmd); + + ret = iwl_enqueue_hcmd(trans, cmd); if (ret < 0) { IWL_ERR(trans, "Error sending %s: enqueue_hcmd failed: %d\n", - get_cmd_string(trans_pcie, cmd->id), ret); + trans_pcie_get_cmd_string(trans_pcie, cmd->id), ret); return ret; } return 0; } -static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans, - struct iwl_host_cmd *cmd) +static int iwl_send_cmd_sync(struct iwl_trans *trans, struct iwl_host_cmd *cmd) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int cmd_idx; int ret; IWL_DEBUG_INFO(trans, "Attempting to send sync command %s\n", - get_cmd_string(trans_pcie, cmd->id)); + trans_pcie_get_cmd_string(trans_pcie, cmd->id)); if (WARN_ON(test_and_set_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status))) { IWL_ERR(trans, "Command %s: a command is already active!\n", - get_cmd_string(trans_pcie, cmd->id)); + trans_pcie_get_cmd_string(trans_pcie, cmd->id)); return -EIO; } IWL_DEBUG_INFO(trans, "Setting HCMD_ACTIVE for command %s\n", - get_cmd_string(trans_pcie, cmd->id)); + trans_pcie_get_cmd_string(trans_pcie, cmd->id)); - cmd_idx = iwl_pcie_enqueue_hcmd(trans, cmd); + cmd_idx = iwl_enqueue_hcmd(trans, cmd); if (cmd_idx < 0) { ret = cmd_idx; clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); IWL_ERR(trans, "Error sending %s: enqueue_hcmd failed: %d\n", - get_cmd_string(trans_pcie, cmd->id), ret); + trans_pcie_get_cmd_string(trans_pcie, cmd->id), ret); return ret; } - ret = wait_event_timeout(trans_pcie->wait_command_queue, + ret = wait_event_timeout(trans->wait_command_queue, !test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status), HOST_COMPLETE_TIMEOUT); if (!ret) { if (test_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status)) { - struct iwl_txq *txq = + struct iwl_tx_queue *txq = &trans_pcie->txq[trans_pcie->cmd_queue]; struct iwl_queue *q = &txq->q; IWL_ERR(trans, "Error sending %s: time out after %dms.\n", - get_cmd_string(trans_pcie, cmd->id), + trans_pcie_get_cmd_string(trans_pcie, cmd->id), jiffies_to_msecs(HOST_COMPLETE_TIMEOUT)); IWL_ERR(trans, @@ -1461,28 +867,16 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans, clear_bit(STATUS_HCMD_ACTIVE, &trans_pcie->status); IWL_DEBUG_INFO(trans, "Clearing HCMD_ACTIVE for command %s\n", - get_cmd_string(trans_pcie, cmd->id)); + trans_pcie_get_cmd_string(trans_pcie, + cmd->id)); ret = -ETIMEDOUT; goto cancel; } } - if (test_bit(STATUS_FW_ERROR, &trans_pcie->status)) { - IWL_ERR(trans, "FW error in SYNC CMD %s\n", - get_cmd_string(trans_pcie, cmd->id)); - ret = -EIO; - goto cancel; - } - - if (test_bit(STATUS_RFKILL, &trans_pcie->status)) { - IWL_DEBUG_RF_KILL(trans, "RFKILL in SYNC CMD... no rsp\n"); - ret = -ERFKILL; - goto cancel; - } - if ((cmd->flags & CMD_WANT_SKB) && !cmd->resp_pkt) { IWL_ERR(trans, "Error: Response NULL in '%s'\n", - get_cmd_string(trans_pcie, cmd->id)); + trans_pcie_get_cmd_string(trans_pcie, cmd->id)); ret = -EIO; goto cancel; } @@ -1509,183 +903,64 @@ static int iwl_pcie_send_hcmd_sync(struct iwl_trans *trans, return ret; } -int iwl_trans_pcie_send_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) +int iwl_trans_pcie_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) { - struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - - if (test_bit(STATUS_FW_ERROR, &trans_pcie->status)) - return -EIO; - - if (test_bit(STATUS_RFKILL, &trans_pcie->status)) - return -ERFKILL; - if (cmd->flags & CMD_ASYNC) - return iwl_pcie_send_hcmd_async(trans, cmd); + return iwl_send_cmd_async(trans, cmd); - /* We still can fail on RFKILL that can be asserted while we wait */ - return iwl_pcie_send_hcmd_sync(trans, cmd); + return iwl_send_cmd_sync(trans, cmd); } -int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, - struct iwl_device_cmd *dev_cmd, int txq_id) +/* Frees buffers until index _not_ inclusive */ +int iwl_tx_queue_reclaim(struct iwl_trans *trans, int txq_id, int index, + struct sk_buff_head *skbs) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct iwl_tx_cmd *tx_cmd = (struct iwl_tx_cmd *)dev_cmd->payload; - struct iwl_cmd_meta *out_meta; - struct iwl_txq *txq; - struct iwl_queue *q; - dma_addr_t phys_addr = 0; - dma_addr_t txcmd_phys; - dma_addr_t scratch_phys; - u16 len, firstlen, secondlen; - u8 wait_write_ptr = 0; - __le16 fc = hdr->frame_control; - u8 hdr_len = ieee80211_hdrlen(fc); - u16 __maybe_unused wifi_seq; - - txq = &trans_pcie->txq[txq_id]; - q = &txq->q; - - if (unlikely(!test_bit(txq_id, trans_pcie->queue_used))) { - WARN_ON_ONCE(1); - return -EINVAL; - } + struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; + struct iwl_queue *q = &txq->q; + int last_to_free; + int freed = 0; - spin_lock(&txq->lock); + /* This function is not meant to release cmd queue*/ + if (WARN_ON(txq_id == trans_pcie->cmd_queue)) + return 0; - /* In AGG mode, the index in the ring must correspond to the WiFi - * sequence number. This is a HW requirements to help the SCD to parse - * the BA. - * Check here that the packets are in the right place on the ring. - */ -#ifdef CONFIG_IWLWIFI_DEBUG - wifi_seq = SEQ_TO_SN(le16_to_cpu(hdr->seq_ctrl)); - WARN_ONCE((iwl_read_prph(trans, SCD_AGGR_SEL) & BIT(txq_id)) && - ((wifi_seq & 0xff) != q->write_ptr), - "Q: %d WiFi Seq %d tfdNum %d", - txq_id, wifi_seq, q->write_ptr); -#endif - - /* Set up driver data for this TFD */ - txq->entries[q->write_ptr].skb = skb; - txq->entries[q->write_ptr].cmd = dev_cmd; - - dev_cmd->hdr.cmd = REPLY_TX; - dev_cmd->hdr.sequence = - cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | - INDEX_TO_SEQ(q->write_ptr))); - - /* Set up first empty entry in queue's array of Tx/cmd buffers */ - out_meta = &txq->entries[q->write_ptr].meta; + lockdep_assert_held(&txq->lock); - /* - * Use the first empty entry in this queue's command buffer array - * to contain the Tx command and MAC header concatenated together - * (payload data will be in another buffer). - * Size of this varies, due to varying MAC header length. - * If end is not dword aligned, we'll have 2 extra bytes at the end - * of the MAC header (device reads on dword boundaries). - * We'll tell device about this padding later. - */ - len = sizeof(struct iwl_tx_cmd) + - sizeof(struct iwl_cmd_header) + hdr_len; - firstlen = (len + 3) & ~3; - - /* Tell NIC about any 2-byte padding after MAC header */ - if (firstlen != len) - tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK; - - /* Physical address of this Tx command's header (not MAC header!), - * within command buffer array. */ - txcmd_phys = dma_map_single(trans->dev, - &dev_cmd->hdr, firstlen, - DMA_BIDIRECTIONAL); - if (unlikely(dma_mapping_error(trans->dev, txcmd_phys))) - goto out_err; - dma_unmap_addr_set(out_meta, mapping, txcmd_phys); - dma_unmap_len_set(out_meta, len, firstlen); - - if (!ieee80211_has_morefrags(fc)) { - txq->need_update = 1; - } else { - wait_write_ptr = 1; - txq->need_update = 0; - } + /*Since we free until index _not_ inclusive, the one before index is + * the last we will free. This one must be used */ + last_to_free = iwl_queue_dec_wrap(index, q->n_bd); - /* Set up TFD's 2nd entry to point directly to remainder of skb, - * if any (802.11 null frames have no payload). */ - secondlen = skb->len - hdr_len; - if (secondlen > 0) { - phys_addr = dma_map_single(trans->dev, skb->data + hdr_len, - secondlen, DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { - dma_unmap_single(trans->dev, - dma_unmap_addr(out_meta, mapping), - dma_unmap_len(out_meta, len), - DMA_BIDIRECTIONAL); - goto out_err; - } + if ((index >= q->n_bd) || + (iwl_queue_used(q, last_to_free) == 0)) { + IWL_ERR(trans, + "%s: Read index for DMA queue txq id (%d), last_to_free %d is out of range [0-%d] %d %d.\n", + __func__, txq_id, last_to_free, q->n_bd, + q->write_ptr, q->read_ptr); + return 0; } - /* Attach buffers to TFD */ - iwl_pcie_txq_build_tfd(trans, txq, txcmd_phys, firstlen, 1); - if (secondlen > 0) - iwl_pcie_txq_build_tfd(trans, txq, phys_addr, secondlen, 0); - - scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) + - offsetof(struct iwl_tx_cmd, scratch); + if (WARN_ON(!skb_queue_empty(skbs))) + return 0; - /* take back ownership of DMA buffer to enable update */ - dma_sync_single_for_cpu(trans->dev, txcmd_phys, firstlen, - DMA_BIDIRECTIONAL); - tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); - tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); + for (; + q->read_ptr != index; + q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { - IWL_DEBUG_TX(trans, "sequence nr = 0X%x\n", - le16_to_cpu(dev_cmd->hdr.sequence)); - IWL_DEBUG_TX(trans, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags)); + if (WARN_ON_ONCE(txq->entries[txq->q.read_ptr].skb == NULL)) + continue; - /* Set up entry for this TFD in Tx byte-count array */ - iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); + __skb_queue_tail(skbs, txq->entries[txq->q.read_ptr].skb); - dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen, - DMA_BIDIRECTIONAL); + txq->entries[txq->q.read_ptr].skb = NULL; - trace_iwlwifi_dev_tx(trans->dev, skb, - &txq->tfds[txq->q.write_ptr], - sizeof(struct iwl_tfd), - &dev_cmd->hdr, firstlen, - skb->data + hdr_len, secondlen); - trace_iwlwifi_dev_tx_data(trans->dev, skb, - skb->data + hdr_len, secondlen); + iwlagn_txq_inval_byte_cnt_tbl(trans, txq); - /* start timer if queue currently empty */ - if (txq->need_update && q->read_ptr == q->write_ptr && - trans_pcie->wd_timeout) - mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); + iwl_txq_free_tfd(trans, txq, DMA_TO_DEVICE); + freed++; + } - /* Tell device the write index *just past* this latest filled TFD */ - q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); - iwl_pcie_txq_inc_wr_ptr(trans, txq); + iwl_queue_progress(trans_pcie, txq); - /* - * At this point the frame is "transmitted" successfully - * and we will get a TX status notification eventually, - * regardless of the value of ret. "ret" only indicates - * whether or not we should update the write pointer. - */ - if (iwl_queue_space(q) < q->high_mark) { - if (wait_write_ptr) { - txq->need_update = 1; - iwl_pcie_txq_inc_wr_ptr(trans, txq); - } else { - iwl_stop_queue(trans, txq); - } - } - spin_unlock(&txq->lock); - return 0; -out_err: - spin_unlock(&txq->lock); - return -1; + return freed; } diff --git a/trunk/drivers/net/wireless/libertas/if_sdio.c b/trunk/drivers/net/wireless/libertas/if_sdio.c index 739309e70d8b..4cb234349fbf 100644 --- a/trunk/drivers/net/wireless/libertas/if_sdio.c +++ b/trunk/drivers/net/wireless/libertas/if_sdio.c @@ -588,38 +588,17 @@ static int if_sdio_prog_real(struct if_sdio_card *card, size = fw->size; while (size) { - timeout = jiffies + HZ; - while (1) { - ret = if_sdio_wait_status(card, FW_DL_READY_STATUS); - if (ret) - goto release; - - req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, - &ret); - if (ret) - goto release; - - req_size |= sdio_readb(card->func, IF_SDIO_RD_BASE + 1, - &ret) << 8; - if (ret) - goto release; + ret = if_sdio_wait_status(card, FW_DL_READY_STATUS); + if (ret) + goto release; - /* - * For SD8688 wait until the length is not 0, 1 or 2 - * before downloading the first FW block, - * since BOOT code writes the register to indicate the - * helper/FW download winner, - * the value could be 1 or 2 (Func1 or Func2). - */ - if ((size != fw->size) || (req_size > 2)) - break; - if (time_after(jiffies, timeout)) { - ret = -ETIMEDOUT; - goto release; - } - mdelay(1); - } + req_size = sdio_readb(card->func, IF_SDIO_RD_BASE, &ret); + if (ret) + goto release; + req_size |= sdio_readb(card->func, IF_SDIO_RD_BASE + 1, &ret) << 8; + if (ret) + goto release; /* lbs_deb_sdio("firmware wants %d bytes\n", (int)req_size); */ diff --git a/trunk/drivers/net/wireless/mwifiex/11n_aggr.c b/trunk/drivers/net/wireless/mwifiex/11n_aggr.c index 68d52cfc1ebd..395f1bfd4102 100644 --- a/trunk/drivers/net/wireless/mwifiex/11n_aggr.c +++ b/trunk/drivers/net/wireless/mwifiex/11n_aggr.c @@ -197,7 +197,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, ra_list_flags); mwifiex_11n_form_amsdu_pkt(skb_aggr, skb_src, &pad); - mwifiex_write_data_complete(adapter, skb_src, 0, 0); + mwifiex_write_data_complete(adapter, skb_src, 0); spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags); @@ -256,7 +256,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, if (!mwifiex_is_ralist_valid(priv, pra_list, ptrindex)) { spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags); - mwifiex_write_data_complete(adapter, skb_aggr, 1, -1); + mwifiex_write_data_complete(adapter, skb_aggr, -1); return -1; } if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA && @@ -282,13 +282,13 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, dev_err(adapter->dev, "%s: host_to_card failed: %#x\n", __func__, ret); adapter->dbg.num_tx_host_to_card_failure++; - mwifiex_write_data_complete(adapter, skb_aggr, 1, ret); + mwifiex_write_data_complete(adapter, skb_aggr, ret); return 0; case -EINPROGRESS: adapter->data_sent = false; break; case 0: - mwifiex_write_data_complete(adapter, skb_aggr, 1, ret); + mwifiex_write_data_complete(adapter, skb_aggr, ret); break; default: break; diff --git a/trunk/drivers/net/wireless/mwifiex/Kconfig b/trunk/drivers/net/wireless/mwifiex/Kconfig index b2e27723f801..8e384fae3e68 100644 --- a/trunk/drivers/net/wireless/mwifiex/Kconfig +++ b/trunk/drivers/net/wireless/mwifiex/Kconfig @@ -1,6 +1,7 @@ config MWIFIEX tristate "Marvell WiFi-Ex Driver" depends on CFG80211 + select LIB80211 ---help--- This adds support for wireless adapters based on Marvell 802.11n chipsets. diff --git a/trunk/drivers/net/wireless/mwifiex/cfg80211.c b/trunk/drivers/net/wireless/mwifiex/cfg80211.c index a875499f8945..42be612faf0f 100644 --- a/trunk/drivers/net/wireless/mwifiex/cfg80211.c +++ b/trunk/drivers/net/wireless/mwifiex/cfg80211.c @@ -1948,21 +1948,6 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info, else ht_info->cap &= ~IEEE80211_HT_CAP_TX_STBC; - if (ISSUPP_GREENFIELD(adapter->hw_dot_11n_dev_cap)) - ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD; - else - ht_info->cap &= ~IEEE80211_HT_CAP_GRN_FLD; - - if (ISENABLED_40MHZ_INTOLERANT(adapter->hw_dot_11n_dev_cap)) - ht_info->cap |= IEEE80211_HT_CAP_40MHZ_INTOLERANT; - else - ht_info->cap &= ~IEEE80211_HT_CAP_40MHZ_INTOLERANT; - - if (ISSUPP_RXLDPC(adapter->hw_dot_11n_dev_cap)) - ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING; - else - ht_info->cap &= ~IEEE80211_HT_CAP_LDPC_CODING; - ht_info->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU; ht_info->cap |= IEEE80211_HT_CAP_SM_PS; @@ -2096,8 +2081,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, return ERR_PTR(-EINVAL); } - dev = alloc_netdev_mqs(sizeof(struct mwifiex_private *), name, - ether_setup, IEEE80211_NUM_ACS, 1); + dev = alloc_netdev_mq(sizeof(struct mwifiex_private *), name, + ether_setup, 1); if (!dev) { wiphy_err(wiphy, "no memory available for netdevice\n"); priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; @@ -2159,7 +2144,8 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev) mwifiex_dev_debugfs_remove(priv); #endif - mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter); + if (!netif_queue_stopped(priv->netdev)) + netif_stop_queue(priv->netdev); if (netif_carrier_ok(priv->netdev)) netif_carrier_off(priv->netdev); diff --git a/trunk/drivers/net/wireless/mwifiex/cmdevt.c b/trunk/drivers/net/wireless/mwifiex/cmdevt.c index 5f438e6c2155..da6c49177fcc 100644 --- a/trunk/drivers/net/wireless/mwifiex/cmdevt.c +++ b/trunk/drivers/net/wireless/mwifiex/cmdevt.c @@ -890,6 +890,9 @@ mwifiex_cmd_timeout_func(unsigned long function_context) return; } cmd_node = adapter->curr_cmd; + if (cmd_node->wait_q_enabled) + adapter->cmd_wait_q.status = -ETIMEDOUT; + if (cmd_node) { adapter->dbg.timeout_cmd_id = adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index]; @@ -938,20 +941,9 @@ mwifiex_cmd_timeout_func(unsigned long function_context) dev_err(adapter->dev, "ps_mode=%d ps_state=%d\n", adapter->ps_mode, adapter->ps_state); - - if (cmd_node->wait_q_enabled) { - adapter->cmd_wait_q.status = -ETIMEDOUT; - wake_up_interruptible(&adapter->cmd_wait_q.wait); - mwifiex_cancel_pending_ioctl(adapter); - /* reset cmd_sent flag to unblock new commands */ - adapter->cmd_sent = false; - } } if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) mwifiex_init_fw_complete(adapter); - - if (adapter->if_ops.card_reset) - adapter->if_ops.card_reset(adapter); } /* diff --git a/trunk/drivers/net/wireless/mwifiex/debugfs.c b/trunk/drivers/net/wireless/mwifiex/debugfs.c index 46e34aa65d1c..a870b5885c09 100644 --- a/trunk/drivers/net/wireless/mwifiex/debugfs.c +++ b/trunk/drivers/net/wireless/mwifiex/debugfs.c @@ -178,7 +178,6 @@ mwifiex_info_read(struct file *file, char __user *ubuf, (struct mwifiex_private *) file->private_data; struct net_device *netdev = priv->netdev; struct netdev_hw_addr *ha; - struct netdev_queue *txq; unsigned long page = get_zeroed_page(GFP_KERNEL); char *p = (char *) page, fmt[64]; struct mwifiex_bss_info info; @@ -230,13 +229,8 @@ mwifiex_info_read(struct file *file, char __user *ubuf, p += sprintf(p, "num_rx_pkts_err = %lu\n", priv->stats.rx_errors); p += sprintf(p, "carrier %s\n", ((netif_carrier_ok(priv->netdev)) ? "on" : "off")); - p += sprintf(p, "tx queue"); - for (i = 0; i < netdev->num_tx_queues; i++) { - txq = netdev_get_tx_queue(netdev, i); - p += sprintf(p, " %d:%s", i, netif_tx_queue_stopped(txq) ? - "stopped" : "started"); - } - p += sprintf(p, "\n"); + p += sprintf(p, "tx queue %s\n", ((netif_queue_stopped(priv->netdev)) + ? "stopped" : "started")); ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page, (unsigned long) p - page); diff --git a/trunk/drivers/net/wireless/mwifiex/fw.h b/trunk/drivers/net/wireless/mwifiex/fw.h index 4dc8e2e9a889..dda588b35570 100644 --- a/trunk/drivers/net/wireless/mwifiex/fw.h +++ b/trunk/drivers/net/wireless/mwifiex/fw.h @@ -194,8 +194,6 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define ISSUPP_TXSTBC(Dot11nDevCap) (Dot11nDevCap & BIT(25)) #define ISSUPP_RXSTBC(Dot11nDevCap) (Dot11nDevCap & BIT(26)) #define ISSUPP_GREENFIELD(Dot11nDevCap) (Dot11nDevCap & BIT(29)) -#define ISENABLED_40MHZ_INTOLERANT(Dot11nDevCap) (Dot11nDevCap & BIT(8)) -#define ISSUPP_RXLDPC(Dot11nDevCap) (Dot11nDevCap & BIT(22)) /* httxcfg bitmap * 0 reserved diff --git a/trunk/drivers/net/wireless/mwifiex/init.c b/trunk/drivers/net/wireless/mwifiex/init.c index 39f03ce5a5b1..482faace7900 100644 --- a/trunk/drivers/net/wireless/mwifiex/init.c +++ b/trunk/drivers/net/wireless/mwifiex/init.c @@ -388,17 +388,9 @@ void mwifiex_wake_up_net_dev_queue(struct net_device *netdev, struct mwifiex_adapter *adapter) { unsigned long dev_queue_flags; - unsigned int i; spin_lock_irqsave(&adapter->queue_lock, dev_queue_flags); - - for (i = 0; i < netdev->num_tx_queues; i++) { - struct netdev_queue *txq = netdev_get_tx_queue(netdev, i); - - if (netif_tx_queue_stopped(txq)) - netif_tx_wake_queue(txq); - } - + netif_tx_wake_all_queues(netdev); spin_unlock_irqrestore(&adapter->queue_lock, dev_queue_flags); } @@ -409,17 +401,9 @@ void mwifiex_stop_net_dev_queue(struct net_device *netdev, struct mwifiex_adapter *adapter) { unsigned long dev_queue_flags; - unsigned int i; spin_lock_irqsave(&adapter->queue_lock, dev_queue_flags); - - for (i = 0; i < netdev->num_tx_queues; i++) { - struct netdev_queue *txq = netdev_get_tx_queue(netdev, i); - - if (!netif_tx_queue_stopped(txq)) - netif_tx_stop_queue(txq); - } - + netif_tx_stop_all_queues(netdev); spin_unlock_irqrestore(&adapter->queue_lock, dev_queue_flags); } diff --git a/trunk/drivers/net/wireless/mwifiex/join.c b/trunk/drivers/net/wireless/mwifiex/join.c index 88664ae667ba..7b0858af8f5d 100644 --- a/trunk/drivers/net/wireless/mwifiex/join.c +++ b/trunk/drivers/net/wireless/mwifiex/join.c @@ -721,7 +721,8 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, if (!netif_carrier_ok(priv->netdev)) netif_carrier_on(priv->netdev); - mwifiex_wake_up_net_dev_queue(priv->netdev, adapter); + if (netif_queue_stopped(priv->netdev)) + netif_wake_queue(priv->netdev); if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled) priv->scan_block = true; @@ -1237,7 +1238,8 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv, if (!netif_carrier_ok(priv->netdev)) netif_carrier_on(priv->netdev); - mwifiex_wake_up_net_dev_queue(priv->netdev, adapter); + if (netif_queue_stopped(priv->netdev)) + netif_wake_queue(priv->netdev); mwifiex_save_curr_bcn(priv); diff --git a/trunk/drivers/net/wireless/mwifiex/main.c b/trunk/drivers/net/wireless/mwifiex/main.c index 9c802ede9c3b..1df767bc8b6e 100644 --- a/trunk/drivers/net/wireless/mwifiex/main.c +++ b/trunk/drivers/net/wireless/mwifiex/main.c @@ -282,7 +282,6 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter) mwifiex_shutdown_drv(adapter); return ret; } -EXPORT_SYMBOL_GPL(mwifiex_main_process); /* * This function frees the adapter structure. @@ -412,6 +411,49 @@ static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter) return ret; } +/* + * This function fills a driver buffer. + * + * The function associates a given SKB with the provided driver buffer + * and also updates some of the SKB parameters, including IP header, + * priority and timestamp. + */ +static void +mwifiex_fill_buffer(struct sk_buff *skb) +{ + struct ethhdr *eth; + struct iphdr *iph; + struct timeval tv; + u8 tid = 0; + + eth = (struct ethhdr *) skb->data; + switch (eth->h_proto) { + case __constant_htons(ETH_P_IP): + iph = ip_hdr(skb); + tid = IPTOS_PREC(iph->tos); + pr_debug("data: packet type ETH_P_IP: %04x, tid=%#x prio=%#x\n", + eth->h_proto, tid, skb->priority); + break; + case __constant_htons(ETH_P_ARP): + pr_debug("data: ARP packet: %04x\n", eth->h_proto); + default: + break; + } +/* Offset for TOS field in the IP header */ +#define IPTOS_OFFSET 5 + tid = (tid >> IPTOS_OFFSET); + skb->priority = tid; + /* Record the current time the packet was queued; used to + determine the amount of time the packet was queued in + the driver before it was sent to the firmware. + The delay is then sent along with the packet to the + firmware for aggregate delay calculation for stats and + MSDU lifetime expiry. + */ + do_gettimeofday(&tv); + skb->tstamp = timeval_to_ktime(tv); +} + /* * CFG802.11 network device handler for open. * @@ -446,23 +488,17 @@ mwifiex_close(struct net_device *dev) */ int mwifiex_queue_tx_pkt(struct mwifiex_private *priv, struct sk_buff *skb) { - struct netdev_queue *txq; - int index = mwifiex_1d_to_wmm_queue[skb->priority]; - - if (atomic_inc_return(&priv->wmm_tx_pending[index]) >= MAX_TX_PENDING) { - txq = netdev_get_tx_queue(priv->netdev, index); - if (!netif_tx_queue_stopped(txq)) { - netif_tx_stop_queue(txq); - dev_dbg(priv->adapter->dev, "stop queue: %d\n", index); - } - } - - atomic_inc(&priv->adapter->tx_pending); mwifiex_wmm_add_buf_txqueue(priv, skb); + atomic_inc(&priv->adapter->tx_pending); if (priv->adapter->scan_delay_cnt) atomic_set(&priv->adapter->is_tx_received, true); + if (atomic_read(&priv->adapter->tx_pending) >= MAX_TX_PENDING) { + mwifiex_set_trans_start(priv->netdev); + mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter); + } + queue_work(priv->adapter->workqueue, &priv->adapter->main_work); return 0; @@ -477,7 +513,6 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); struct sk_buff *new_skb; struct mwifiex_txinfo *tx_info; - struct timeval tv; dev_dbg(priv->adapter->dev, "data: %lu BSS(%d-%d): Data <= kernel\n", jiffies, priv->bss_type, priv->bss_num); @@ -515,16 +550,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) tx_info = MWIFIEX_SKB_TXCB(skb); tx_info->bss_num = priv->bss_num; tx_info->bss_type = priv->bss_type; - - /* Record the current time the packet was queued; used to - * determine the amount of time the packet was queued in - * the driver before it was sent to the firmware. - * The delay is then sent along with the packet to the - * firmware for aggregate delay calculation for stats and - * MSDU lifetime expiry. - */ - do_gettimeofday(&tv); - skb->tstamp = timeval_to_ktime(tv); + mwifiex_fill_buffer(skb); mwifiex_queue_tx_pkt(priv, skb); @@ -604,13 +630,6 @@ static struct net_device_stats *mwifiex_get_stats(struct net_device *dev) return &priv->stats; } -static u16 -mwifiex_netdev_select_wmm_queue(struct net_device *dev, struct sk_buff *skb) -{ - skb->priority = cfg80211_classify8021d(skb); - return mwifiex_1d_to_wmm_queue[skb->priority]; -} - /* Network device handlers */ static const struct net_device_ops mwifiex_netdev_ops = { .ndo_open = mwifiex_open, @@ -620,7 +639,6 @@ static const struct net_device_ops mwifiex_netdev_ops = { .ndo_tx_timeout = mwifiex_tx_timeout, .ndo_get_stats = mwifiex_get_stats, .ndo_set_rx_mode = mwifiex_set_multicast_list, - .ndo_select_queue = mwifiex_netdev_select_wmm_queue, }; /* @@ -820,7 +838,9 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem) for (i = 0; i < adapter->priv_num; i++) { priv = adapter->priv[i]; if (priv && priv->netdev) { - mwifiex_stop_net_dev_queue(priv->netdev, adapter); + if (!netif_queue_stopped(priv->netdev)) + mwifiex_stop_net_dev_queue(priv->netdev, + adapter); if (netif_carrier_ok(priv->netdev)) netif_carrier_off(priv->netdev); } diff --git a/trunk/drivers/net/wireless/mwifiex/main.h b/trunk/drivers/net/wireless/mwifiex/main.h index 1b3cfc821940..771717df1c59 100644 --- a/trunk/drivers/net/wireless/mwifiex/main.h +++ b/trunk/drivers/net/wireless/mwifiex/main.h @@ -439,7 +439,6 @@ struct mwifiex_private { u8 wmm_enabled; u8 wmm_qosinfo; struct mwifiex_wmm_desc wmm; - atomic_t wmm_tx_pending[IEEE80211_NUM_ACS]; struct list_head sta_list; /* spin lock for associated station list */ spinlock_t sta_list_spinlock; @@ -600,7 +599,6 @@ struct mwifiex_if_ops { int (*event_complete) (struct mwifiex_adapter *, struct sk_buff *); int (*data_complete) (struct mwifiex_adapter *, struct sk_buff *); int (*dnld_fw) (struct mwifiex_adapter *, struct mwifiex_fw_image *); - void (*card_reset) (struct mwifiex_adapter *); }; struct mwifiex_adapter { @@ -789,7 +787,7 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, struct mwifiex_tx_param *tx_param); int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags); int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, - struct sk_buff *skb, int aggr, int status); + struct sk_buff *skb, int status); void mwifiex_clean_txrx(struct mwifiex_private *priv); u8 mwifiex_check_last_packet_indication(struct mwifiex_private *priv); void mwifiex_check_ps_cond(struct mwifiex_adapter *adapter); diff --git a/trunk/drivers/net/wireless/mwifiex/sdio.c b/trunk/drivers/net/wireless/mwifiex/sdio.c index 5a1c1d0e5599..fc8a9bfa1248 100644 --- a/trunk/drivers/net/wireless/mwifiex/sdio.c +++ b/trunk/drivers/net/wireless/mwifiex/sdio.c @@ -161,6 +161,7 @@ static int mwifiex_sdio_suspend(struct device *dev) struct sdio_mmc_card *card; struct mwifiex_adapter *adapter; mmc_pm_flag_t pm_flag = 0; + int hs_actived = 0; int i; int ret = 0; @@ -187,14 +188,12 @@ static int mwifiex_sdio_suspend(struct device *dev) adapter = card->adapter; /* Enable the Host Sleep */ - if (!mwifiex_enable_hs(adapter)) { - dev_err(adapter->dev, "cmd: failed to suspend\n"); - return -EFAULT; + hs_actived = mwifiex_enable_hs(adapter); + if (hs_actived) { + pr_debug("cmd: suspend with MMC_PM_KEEP_POWER\n"); + ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); } - dev_dbg(adapter->dev, "cmd: suspend with MMC_PM_KEEP_POWER\n"); - ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); - /* Indicate device suspended */ adapter->is_suspended = true; @@ -906,8 +905,8 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter) /* * SDIO interrupt handler. * - * This function reads the interrupt status from firmware and handles - * the interrupt in current thread (ksdioirqd) right away. + * This function reads the interrupt status from firmware and assigns + * the main process in workqueue which will handle the interrupt. */ static void mwifiex_sdio_interrupt(struct sdio_func *func) @@ -930,7 +929,7 @@ mwifiex_sdio_interrupt(struct sdio_func *func) adapter->ps_state = PS_STATE_AWAKE; mwifiex_interrupt_status(adapter); - mwifiex_main_process(adapter); + queue_work(adapter->workqueue, &adapter->main_work); } /* @@ -1749,37 +1748,6 @@ mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port) port, card->mp_data_port_mask); } -static struct mmc_host *reset_host; -static void sdio_card_reset_worker(struct work_struct *work) -{ - /* The actual reset operation must be run outside of driver thread. - * This is because mmc_remove_host() will cause the device to be - * instantly destroyed, and the driver then needs to end its thread, - * leading to a deadlock. - * - * We run it in a totally independent workqueue. - */ - - pr_err("Resetting card...\n"); - mmc_remove_host(reset_host); - /* 20ms delay is based on experiment with sdhci controller */ - mdelay(20); - mmc_add_host(reset_host); -} -static DECLARE_WORK(card_reset_work, sdio_card_reset_worker); - -/* This function resets the card */ -static void mwifiex_sdio_card_reset(struct mwifiex_adapter *adapter) -{ - struct sdio_mmc_card *card = adapter->card; - - if (work_pending(&card_reset_work)) - return; - - reset_host = card->func->card->host; - schedule_work(&card_reset_work); -} - static struct mwifiex_if_ops sdio_ops = { .init_if = mwifiex_init_sdio, .cleanup_if = mwifiex_cleanup_sdio, @@ -1798,7 +1766,6 @@ static struct mwifiex_if_ops sdio_ops = { .cleanup_mpa_buf = mwifiex_cleanup_mpa_buf, .cmdrsp_complete = mwifiex_sdio_cmdrsp_complete, .event_complete = mwifiex_sdio_event_complete, - .card_reset = mwifiex_sdio_card_reset, }; /* @@ -1836,7 +1803,6 @@ mwifiex_sdio_cleanup_module(void) /* Set the flag as user is removing this module. */ user_rmmod = 1; - cancel_work_sync(&card_reset_work); sdio_unregister_driver(&mwifiex_sdio); } diff --git a/trunk/drivers/net/wireless/mwifiex/sdio.h b/trunk/drivers/net/wireless/mwifiex/sdio.h index 8cc5468654b4..21033738ef0c 100644 --- a/trunk/drivers/net/wireless/mwifiex/sdio.h +++ b/trunk/drivers/net/wireless/mwifiex/sdio.h @@ -25,7 +25,6 @@ #include #include #include -#include #include "main.h" diff --git a/trunk/drivers/net/wireless/mwifiex/sta_event.c b/trunk/drivers/net/wireless/mwifiex/sta_event.c index 41aafc7454ed..78dfa31c908c 100644 --- a/trunk/drivers/net/wireless/mwifiex/sta_event.c +++ b/trunk/drivers/net/wireless/mwifiex/sta_event.c @@ -124,7 +124,8 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code) } memset(priv->cfg_bssid, 0, ETH_ALEN); - mwifiex_stop_net_dev_queue(priv->netdev, adapter); + if (!netif_queue_stopped(priv->netdev)) + mwifiex_stop_net_dev_queue(priv->netdev, adapter); if (netif_carrier_ok(priv->netdev)) netif_carrier_off(priv->netdev); } @@ -196,7 +197,8 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) dev_dbg(adapter->dev, "event: LINK_SENSED\n"); if (!netif_carrier_ok(priv->netdev)) netif_carrier_on(priv->netdev); - mwifiex_wake_up_net_dev_queue(priv->netdev, adapter); + if (netif_queue_stopped(priv->netdev)) + mwifiex_wake_up_net_dev_queue(priv->netdev, adapter); break; case EVENT_DEAUTHENTICATED: @@ -304,7 +306,8 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) dev_dbg(adapter->dev, "event: ADHOC_BCN_LOST\n"); priv->adhoc_is_link_sensed = false; mwifiex_clean_txrx(priv); - mwifiex_stop_net_dev_queue(priv->netdev, adapter); + if (!netif_queue_stopped(priv->netdev)) + mwifiex_stop_net_dev_queue(priv->netdev, adapter); if (netif_carrier_ok(priv->netdev)) netif_carrier_off(priv->netdev); break; diff --git a/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c b/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c index 95e3ab531c93..24af6ba7d8a1 100644 --- a/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -161,9 +161,8 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, int ret; u8 *beacon_ie; struct mwifiex_bss_priv *bss_priv = (void *)bss->priv; - size_t beacon_ie_len = bss->len_information_elements; - beacon_ie = kmemdup(bss->information_elements, beacon_ie_len, + beacon_ie = kmemdup(bss->information_elements, bss->len_beacon_ies, GFP_KERNEL); if (!beacon_ie) { dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n"); @@ -173,7 +172,7 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, memcpy(bss_desc->mac_address, bss->bssid, ETH_ALEN); bss_desc->rssi = bss->signal; bss_desc->beacon_buf = beacon_ie; - bss_desc->beacon_buf_size = beacon_ie_len; + bss_desc->beacon_buf_size = bss->len_beacon_ies; bss_desc->beacon_period = bss->beacon_interval; bss_desc->cap_info_bitmap = bss->capability; bss_desc->bss_band = bss_priv->band; @@ -277,7 +276,8 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, dev_dbg(adapter->dev, "info: SSID found in scan list ... " "associating...\n"); - mwifiex_stop_net_dev_queue(priv->netdev, adapter); + if (!netif_queue_stopped(priv->netdev)) + mwifiex_stop_net_dev_queue(priv->netdev, adapter); if (netif_carrier_ok(priv->netdev)) netif_carrier_off(priv->netdev); @@ -318,7 +318,8 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, ret = mwifiex_check_network_compatibility(priv, bss_desc); - mwifiex_stop_net_dev_queue(priv->netdev, adapter); + if (!netif_queue_stopped(priv->netdev)) + mwifiex_stop_net_dev_queue(priv->netdev, adapter); if (netif_carrier_ok(priv->netdev)) netif_carrier_off(priv->netdev); @@ -462,7 +463,7 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) } if (adapter->hs_activated) { - dev_dbg(adapter->dev, "cmd: HS Already activated\n"); + dev_dbg(adapter->dev, "cmd: HS Already actived\n"); return true; } diff --git a/trunk/drivers/net/wireless/mwifiex/txrx.c b/trunk/drivers/net/wireless/mwifiex/txrx.c index 8c80024c30ff..5cb3f7af8749 100644 --- a/trunk/drivers/net/wireless/mwifiex/txrx.c +++ b/trunk/drivers/net/wireless/mwifiex/txrx.c @@ -121,13 +121,13 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, dev_err(adapter->dev, "mwifiex_write_data_async failed: 0x%X\n", ret); adapter->dbg.num_tx_host_to_card_failure++; - mwifiex_write_data_complete(adapter, skb, 0, ret); + mwifiex_write_data_complete(adapter, skb, ret); break; case -EINPROGRESS: adapter->data_sent = false; break; case 0: - mwifiex_write_data_complete(adapter, skb, 0, ret); + mwifiex_write_data_complete(adapter, skb, ret); break; default: break; @@ -144,12 +144,11 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb, * wakes up stalled traffic queue if required, and then frees the buffer. */ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, - struct sk_buff *skb, int aggr, int status) + struct sk_buff *skb, int status) { - struct mwifiex_private *priv; + struct mwifiex_private *priv, *tpriv; struct mwifiex_txinfo *tx_info; - struct netdev_queue *txq; - int index; + int i; if (!skb) return 0; @@ -173,20 +172,15 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, if (tx_info->flags & MWIFIEX_BUF_FLAG_BRIDGED_PKT) atomic_dec_return(&adapter->pending_bridged_pkts); - - if (aggr) - /* For skb_aggr, do not wake up tx queue */ + if (atomic_dec_return(&adapter->tx_pending) >= LOW_TX_PENDING) goto done; - atomic_dec(&adapter->tx_pending); + for (i = 0; i < adapter->priv_num; i++) { + tpriv = adapter->priv[i]; - index = mwifiex_1d_to_wmm_queue[skb->priority]; - if (atomic_dec_return(&priv->wmm_tx_pending[index]) < LOW_TX_PENDING) { - txq = netdev_get_tx_queue(priv->netdev, index); - if (netif_tx_queue_stopped(txq)) { - netif_tx_wake_queue(txq); - dev_dbg(adapter->dev, "wake queue: %d\n", index); - } + if (tpriv->media_connected && + netif_queue_stopped(tpriv->netdev)) + mwifiex_wake_up_net_dev_queue(tpriv->netdev, adapter); } done: dev_kfree_skb_any(skb); diff --git a/trunk/drivers/net/wireless/mwifiex/uap_event.c b/trunk/drivers/net/wireless/mwifiex/uap_event.c index 21c640d3b579..a33fa394e349 100644 --- a/trunk/drivers/net/wireless/mwifiex/uap_event.c +++ b/trunk/drivers/net/wireless/mwifiex/uap_event.c @@ -235,18 +235,11 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv) break; case EVENT_UAP_BSS_IDLE: priv->media_connected = false; - if (netif_carrier_ok(priv->netdev)) - netif_carrier_off(priv->netdev); - mwifiex_stop_net_dev_queue(priv->netdev, adapter); - mwifiex_clean_txrx(priv); mwifiex_del_all_sta_list(priv); break; case EVENT_UAP_BSS_ACTIVE: priv->media_connected = true; - if (!netif_carrier_ok(priv->netdev)) - netif_carrier_on(priv->netdev); - mwifiex_wake_up_net_dev_queue(priv->netdev, adapter); break; case EVENT_UAP_BSS_START: dev_dbg(adapter->dev, "AP EVENT: event id: %#x\n", eventcause); diff --git a/trunk/drivers/net/wireless/mwifiex/usb.c b/trunk/drivers/net/wireless/mwifiex/usb.c index 63ac9f2d11ae..22a5916564b8 100644 --- a/trunk/drivers/net/wireless/mwifiex/usb.c +++ b/trunk/drivers/net/wireless/mwifiex/usb.c @@ -238,7 +238,7 @@ static void mwifiex_usb_tx_complete(struct urb *urb) } else { dev_dbg(adapter->dev, "%s: DATA\n", __func__); atomic_dec(&card->tx_data_urb_pending); - mwifiex_write_data_complete(adapter, context->skb, 0, + mwifiex_write_data_complete(adapter, context->skb, urb->status ? -1 : 0); } @@ -351,7 +351,7 @@ static int mwifiex_usb_probe(struct usb_interface *intf, card->udev = udev; card->intf = intf; - pr_debug("info: bcdUSB=%#x Device Class=%#x SubClass=%#x Protocol=%#x\n", + pr_debug("info: bcdUSB=%#x Device Class=%#x SubClass=%#x Protocl=%#x\n", udev->descriptor.bcdUSB, udev->descriptor.bDeviceClass, udev->descriptor.bDeviceSubClass, udev->descriptor.bDeviceProtocol); diff --git a/trunk/drivers/net/wireless/mwifiex/wmm.c b/trunk/drivers/net/wireless/mwifiex/wmm.c index 818f871ae987..600d8194610e 100644 --- a/trunk/drivers/net/wireless/mwifiex/wmm.c +++ b/trunk/drivers/net/wireless/mwifiex/wmm.c @@ -483,7 +483,7 @@ mwifiex_wmm_del_pkts_in_ralist_node(struct mwifiex_private *priv, struct sk_buff *skb, *tmp; skb_queue_walk_safe(&ra_list->skb_head, skb, tmp) - mwifiex_write_data_complete(adapter, skb, 0, -1); + mwifiex_write_data_complete(adapter, skb, -1); } /* @@ -650,7 +650,7 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv, if (!priv->media_connected && !mwifiex_is_skb_mgmt_frame(skb)) { dev_dbg(adapter->dev, "data: drop packet in disconnect\n"); - mwifiex_write_data_complete(adapter, skb, 0, -1); + mwifiex_write_data_complete(adapter, skb, -1); return; } @@ -680,7 +680,7 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv, if (!ra_list) { spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); - mwifiex_write_data_complete(adapter, skb, 0, -1); + mwifiex_write_data_complete(adapter, skb, -1); return; } @@ -1090,7 +1090,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv, if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) { spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags); - mwifiex_write_data_complete(adapter, skb, 0, -1); + mwifiex_write_data_complete(adapter, skb, -1); return; } @@ -1195,7 +1195,7 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv, if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) { spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags); - mwifiex_write_data_complete(adapter, skb, 0, -1); + mwifiex_write_data_complete(adapter, skb, -1); return; } @@ -1209,7 +1209,7 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv, adapter->data_sent = false; dev_err(adapter->dev, "host_to_card failed: %#x\n", ret); adapter->dbg.num_tx_host_to_card_failure++; - mwifiex_write_data_complete(adapter, skb, 0, ret); + mwifiex_write_data_complete(adapter, skb, ret); break; case -EINPROGRESS: adapter->data_sent = false; diff --git a/trunk/drivers/net/wireless/mwifiex/wmm.h b/trunk/drivers/net/wireless/mwifiex/wmm.h index b92f39d8963b..ec839952d2e7 100644 --- a/trunk/drivers/net/wireless/mwifiex/wmm.h +++ b/trunk/drivers/net/wireless/mwifiex/wmm.h @@ -31,8 +31,6 @@ enum ieee_types_wmm_ecw_bitmasks { MWIFIEX_ECW_MAX = (BIT(4) | BIT(5) | BIT(6) | BIT(7)), }; -static const u16 mwifiex_1d_to_wmm_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 }; - /* * This function retrieves the TID of the given RA list. */ diff --git a/trunk/drivers/net/wireless/mwl8k.c b/trunk/drivers/net/wireless/mwl8k.c index 434d508f9e3e..5099e5375cb3 100644 --- a/trunk/drivers/net/wireless/mwl8k.c +++ b/trunk/drivers/net/wireless/mwl8k.c @@ -1851,7 +1851,6 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, bool start_ba_session = false; bool mgmtframe = false; struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; - bool eapol_frame = false; wh = (struct ieee80211_hdr *)skb->data; if (ieee80211_is_data_qos(wh->frame_control)) @@ -1859,9 +1858,6 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, else qos = 0; - if (skb->protocol == cpu_to_be16(ETH_P_PAE)) - eapol_frame = true; - if (ieee80211_is_mgmt(wh->frame_control)) mgmtframe = true; @@ -1920,8 +1916,9 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, txpriority = index; - if (priv->ap_fw && sta && sta->ht_cap.ht_supported && !eapol_frame && - ieee80211_is_data_qos(wh->frame_control)) { + if (priv->ap_fw && sta && sta->ht_cap.ht_supported + && skb->protocol != cpu_to_be16(ETH_P_PAE) + && ieee80211_is_data_qos(wh->frame_control)) { tid = qos & 0xf; mwl8k_tx_count_packet(sta, tid); spin_lock(&priv->stream_lock); @@ -2008,8 +2005,6 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, spin_unlock(&priv->stream_lock); } spin_unlock_bh(&priv->tx_lock); - pci_unmap_single(priv->pdev, dma, skb->len, - PCI_DMA_TODEVICE); dev_kfree_skb(skb); return; } @@ -2030,11 +2025,9 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, else tx->peer_id = 0; - if (priv->ap_fw && ieee80211_is_data(wh->frame_control) && !eapol_frame) + if (priv->ap_fw) tx->timestamp = cpu_to_le32(ioread32(priv->regs + MWL8K_HW_TIMER_REGISTER)); - else - tx->timestamp = 0; wmb(); tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus); @@ -3686,8 +3679,7 @@ struct mwl8k_cmd_bastream { } __packed; static int -mwl8k_check_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream, - struct ieee80211_vif *vif) +mwl8k_check_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream) { struct mwl8k_cmd_bastream *cmd; int rc; @@ -3710,7 +3702,7 @@ mwl8k_check_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream, cpu_to_le32(BASTREAM_FLAG_IMMEDIATE_TYPE) | cpu_to_le32(BASTREAM_FLAG_DIRECTION_UPSTREAM); - rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); + rc = mwl8k_post_cmd(hw, &cmd->header); kfree(cmd); @@ -3719,7 +3711,7 @@ mwl8k_check_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream, static int mwl8k_create_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream, - u8 buf_size, struct ieee80211_vif *vif) + u8 buf_size) { struct mwl8k_cmd_bastream *cmd; int rc; @@ -3753,7 +3745,7 @@ mwl8k_create_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream, cpu_to_le32(BASTREAM_FLAG_IMMEDIATE_TYPE | BASTREAM_FLAG_DIRECTION_UPSTREAM); - rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header); + rc = mwl8k_post_cmd(hw, &cmd->header); wiphy_debug(hw->wiphy, "Created a BA stream for %pM : tid %d\n", stream->sta->addr, stream->tid); @@ -5093,7 +5085,6 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct mwl8k_priv *priv = hw->priv; struct mwl8k_ampdu_stream *stream; u8 *addr = sta->addr; - struct mwl8k_sta *sta_info = MWL8K_STA(sta); if (!(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION)) return -ENOTSUPP; @@ -5136,16 +5127,7 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, /* Release the lock before we do the time consuming stuff */ spin_unlock(&priv->stream_lock); for (i = 0; i < MAX_AMPDU_ATTEMPTS; i++) { - - /* Check if link is still valid */ - if (!sta_info->is_ampdu_allowed) { - spin_lock(&priv->stream_lock); - mwl8k_remove_stream(hw, stream); - spin_unlock(&priv->stream_lock); - return -EBUSY; - } - - rc = mwl8k_check_ba(hw, stream, vif); + rc = mwl8k_check_ba(hw, stream); /* If HW restart is in progress mwl8k_post_cmd will * return -EBUSY. Avoid retrying mwl8k_check_ba in @@ -5185,7 +5167,7 @@ mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, BUG_ON(stream == NULL); BUG_ON(stream->state != AMPDU_STREAM_IN_PROGRESS); spin_unlock(&priv->stream_lock); - rc = mwl8k_create_ba(hw, stream, buf_size, vif); + rc = mwl8k_create_ba(hw, stream, buf_size); spin_lock(&priv->stream_lock); if (!rc) stream->state = AMPDU_STREAM_ACTIVE; @@ -5635,18 +5617,6 @@ static int mwl8k_reload_firmware(struct ieee80211_hw *hw, char *fw_image) return rc; } -static const struct ieee80211_iface_limit ap_if_limits[] = { - { .max = 8, .types = BIT(NL80211_IFTYPE_AP) }, -}; - -static const struct ieee80211_iface_combination ap_if_comb = { - .limits = ap_if_limits, - .n_limits = ARRAY_SIZE(ap_if_limits), - .max_interfaces = 8, - .num_different_channels = 1, -}; - - static int mwl8k_firmware_load_success(struct mwl8k_priv *priv) { struct ieee80211_hw *hw = priv->hw; @@ -5726,13 +5696,8 @@ static int mwl8k_firmware_load_success(struct mwl8k_priv *priv) goto err_free_cookie; hw->wiphy->interface_modes = 0; - - if (priv->ap_macids_supported || priv->device_info->fw_image_ap) { + if (priv->ap_macids_supported || priv->device_info->fw_image_ap) hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP); - hw->wiphy->iface_combinations = &ap_if_comb; - hw->wiphy->n_iface_combinations = 1; - } - if (priv->sta_macids_supported || priv->device_info->fw_image_sta) hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION); @@ -5873,6 +5838,11 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, return rc; } +static void __devexit mwl8k_shutdown(struct pci_dev *pdev) +{ + printk(KERN_ERR "===>%s(%u)\n", __func__, __LINE__); +} + static void __devexit mwl8k_remove(struct pci_dev *pdev) { struct ieee80211_hw *hw = pci_get_drvdata(pdev); @@ -5926,6 +5896,7 @@ static struct pci_driver mwl8k_driver = { .id_table = mwl8k_pci_id_table, .probe = mwl8k_probe, .remove = __devexit_p(mwl8k_remove), + .shutdown = __devexit_p(mwl8k_shutdown), }; module_pci_driver(mwl8k_driver); diff --git a/trunk/drivers/net/wireless/p54/eeprom.c b/trunk/drivers/net/wireless/p54/eeprom.c index d43e3740e45d..1ef1bfe6a9d7 100644 --- a/trunk/drivers/net/wireless/p54/eeprom.c +++ b/trunk/drivers/net/wireless/p54/eeprom.c @@ -541,9 +541,8 @@ static int p54_parse_rssical(struct ieee80211_hw *dev, entries = (len - offset) / sizeof(struct pda_rssi_cal_ext_entry); - if (len < offset || - (len - offset) % sizeof(struct pda_rssi_cal_ext_entry) || - entries == 0) { + if ((len - offset) % sizeof(struct pda_rssi_cal_ext_entry) || + entries <= 0) { wiphy_err(dev->wiphy, "invalid rssi database.\n"); goto err_data; } diff --git a/trunk/drivers/net/wireless/p54/p54pci.c b/trunk/drivers/net/wireless/p54/p54pci.c index 810c343e4e30..b4390797d78c 100644 --- a/trunk/drivers/net/wireless/p54/p54pci.c +++ b/trunk/drivers/net/wireless/p54/p54pci.c @@ -659,7 +659,7 @@ static void __devexit p54p_remove(struct pci_dev *pdev) p54_free_common(dev); } -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_PM static int p54p_suspend(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); @@ -681,12 +681,19 @@ static int p54p_resume(struct device *device) return pci_set_power_state(pdev, PCI_D0); } -static SIMPLE_DEV_PM_OPS(p54pci_pm_ops, p54p_suspend, p54p_resume); +static const struct dev_pm_ops p54pci_pm_ops = { + .suspend = p54p_suspend, + .resume = p54p_resume, + .freeze = p54p_suspend, + .thaw = p54p_resume, + .poweroff = p54p_suspend, + .restore = p54p_resume, +}; #define P54P_PM_OPS (&p54pci_pm_ops) #else #define P54P_PM_OPS (NULL) -#endif /* CONFIG_PM_SLEEP */ +#endif /* CONFIG_PM */ static struct pci_driver p54p_driver = { .name = "p54pci", diff --git a/trunk/drivers/net/wireless/p54/txrx.c b/trunk/drivers/net/wireless/p54/txrx.c index 12f0a34477f2..8ae982bd7cf3 100644 --- a/trunk/drivers/net/wireless/p54/txrx.c +++ b/trunk/drivers/net/wireless/p54/txrx.c @@ -369,11 +369,7 @@ static int p54_rx_data(struct p54_common *priv, struct sk_buff *skb) rx_status->mactime = ((u64)priv->tsf_high32) << 32 | tsf32; priv->tsf_low32 = tsf32; - /* LMAC API Page 10/29 - s_lm_data_in - clock - * "usec accurate timestamp of hardware clock - * at end of frame (before OFDM SIFS EOF padding" - */ - rx_status->flag |= RX_FLAG_MACTIME_END; + rx_status->flag |= RX_FLAG_MACTIME_START; if (hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_ALIGN)) header_len += hdr->align[0]; diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800.h b/trunk/drivers/net/wireless/rt2x00/rt2800.h index 4db1088a847f..6d67c3ede651 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800.h +++ b/trunk/drivers/net/wireless/rt2x00/rt2800.h @@ -1993,10 +1993,8 @@ struct mac_iveiv_entry { */ #define RFCSR3_K FIELD8(0x0f) /* Bits [7-4] for RF3320 (RT3370/RT3390), on other chipsets reserved */ -#define RFCSR3_PA1_BIAS_CCK FIELD8(0x70) -#define RFCSR3_PA2_CASCODE_BIAS_CCKK FIELD8(0x80) -/* Bits for RF3290/RF5360/RF5370/RF5372/RF5390/RF5392 */ -#define RFCSR3_VCOCAL_EN FIELD8(0x80) +#define RFCSR3_PA1_BIAS_CCK FIELD8(0x70); +#define RFCSR3_PA2_CASCODE_BIAS_CCKK FIELD8(0x80); /* * FRCSR 5: diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800lib.c b/trunk/drivers/net/wireless/rt2x00/rt2800lib.c index d4d0c3664eb2..3bc206d06cd1 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2800lib.c @@ -2173,7 +2173,7 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev, rt2800_rfcsr_write(rt2x00dev, 59, r59_nonbt_rev[idx]); } else if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) { + rt2x00_rt(rt2x00dev, RT5392)) { static const char r59_non_bt[] = {0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8d, 0x8a, 0x88, 0x88, 0x87, 0x87, 0x86}; @@ -2243,7 +2243,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1); + rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); } @@ -2264,7 +2264,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, if (rf->channel <= 14) { if (!rt2x00_rt(rt2x00dev, RT5390) && - !rt2x00_rt(rt2x00dev, RT5392)) { + !rt2x00_rt(rt2x00dev, RT5392)) { if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags)) { rt2800_bbp_write(rt2x00dev, 82, 0x62); @@ -2449,7 +2449,7 @@ static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev) /* * Check if temperature compensation is supported. */ - if (tssi_bounds[4] == 0xff || step == 0xff) + if (tssi_bounds[4] == 0xff) return 0; /* @@ -2804,7 +2804,7 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev) case RF5390: case RF5392: rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1); + rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); break; default: @@ -3592,8 +3592,8 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D)) rt2800_bbp_write(rt2x00dev, 84, 0x19); else if (rt2x00_rt(rt2x00dev, RT3290) || - rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) + rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 84, 0x9a); else rt2800_bbp_write(rt2x00dev, 84, 0x99); @@ -3652,7 +3652,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) else if (rt2x00_rt(rt2x00dev, RT3352)) rt2800_bbp_write(rt2x00dev, 105, 0x34); else if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 105, 0x3c); else rt2800_bbp_write(rt2x00dev, 105, 0x05); @@ -3746,7 +3746,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) } if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) { + rt2x00_rt(rt2x00dev, RT5392)) { int ant, div_mode; rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); @@ -4220,66 +4220,66 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 61, 0xdd); rt2800_rfcsr_write(rt2x00dev, 62, 0x00); rt2800_rfcsr_write(rt2x00dev, 63, 0x00); - } else if (rt2x00_rt(rt2x00dev, RT5392)) { - rt2800_rfcsr_write(rt2x00dev, 1, 0x17); - rt2800_rfcsr_write(rt2x00dev, 2, 0x80); - rt2800_rfcsr_write(rt2x00dev, 3, 0x88); - rt2800_rfcsr_write(rt2x00dev, 5, 0x10); - rt2800_rfcsr_write(rt2x00dev, 6, 0xe0); - rt2800_rfcsr_write(rt2x00dev, 7, 0x00); - rt2800_rfcsr_write(rt2x00dev, 10, 0x53); - rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); - rt2800_rfcsr_write(rt2x00dev, 12, 0x46); - rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); - rt2800_rfcsr_write(rt2x00dev, 14, 0x00); - rt2800_rfcsr_write(rt2x00dev, 15, 0x00); - rt2800_rfcsr_write(rt2x00dev, 16, 0x00); - rt2800_rfcsr_write(rt2x00dev, 18, 0x03); - rt2800_rfcsr_write(rt2x00dev, 19, 0x4d); - rt2800_rfcsr_write(rt2x00dev, 20, 0x00); - rt2800_rfcsr_write(rt2x00dev, 21, 0x8d); - rt2800_rfcsr_write(rt2x00dev, 22, 0x20); - rt2800_rfcsr_write(rt2x00dev, 23, 0x0b); - rt2800_rfcsr_write(rt2x00dev, 24, 0x44); - rt2800_rfcsr_write(rt2x00dev, 25, 0x80); - rt2800_rfcsr_write(rt2x00dev, 26, 0x82); - rt2800_rfcsr_write(rt2x00dev, 27, 0x09); - rt2800_rfcsr_write(rt2x00dev, 28, 0x00); - rt2800_rfcsr_write(rt2x00dev, 29, 0x10); - rt2800_rfcsr_write(rt2x00dev, 30, 0x10); - rt2800_rfcsr_write(rt2x00dev, 31, 0x80); - rt2800_rfcsr_write(rt2x00dev, 32, 0x20); - rt2800_rfcsr_write(rt2x00dev, 33, 0xC0); - rt2800_rfcsr_write(rt2x00dev, 34, 0x07); - rt2800_rfcsr_write(rt2x00dev, 35, 0x12); - rt2800_rfcsr_write(rt2x00dev, 36, 0x00); - rt2800_rfcsr_write(rt2x00dev, 37, 0x08); - rt2800_rfcsr_write(rt2x00dev, 38, 0x89); - rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); - rt2800_rfcsr_write(rt2x00dev, 40, 0x0f); - rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); - rt2800_rfcsr_write(rt2x00dev, 42, 0xd5); - rt2800_rfcsr_write(rt2x00dev, 43, 0x9b); - rt2800_rfcsr_write(rt2x00dev, 44, 0x0e); - rt2800_rfcsr_write(rt2x00dev, 45, 0xa2); - rt2800_rfcsr_write(rt2x00dev, 46, 0x73); - rt2800_rfcsr_write(rt2x00dev, 47, 0x0c); - rt2800_rfcsr_write(rt2x00dev, 48, 0x10); - rt2800_rfcsr_write(rt2x00dev, 49, 0x94); - rt2800_rfcsr_write(rt2x00dev, 50, 0x94); - rt2800_rfcsr_write(rt2x00dev, 51, 0x3a); - rt2800_rfcsr_write(rt2x00dev, 52, 0x48); - rt2800_rfcsr_write(rt2x00dev, 53, 0x44); - rt2800_rfcsr_write(rt2x00dev, 54, 0x38); - rt2800_rfcsr_write(rt2x00dev, 55, 0x43); - rt2800_rfcsr_write(rt2x00dev, 56, 0xa1); - rt2800_rfcsr_write(rt2x00dev, 57, 0x00); - rt2800_rfcsr_write(rt2x00dev, 58, 0x39); - rt2800_rfcsr_write(rt2x00dev, 59, 0x07); - rt2800_rfcsr_write(rt2x00dev, 60, 0x45); - rt2800_rfcsr_write(rt2x00dev, 61, 0x91); - rt2800_rfcsr_write(rt2x00dev, 62, 0x39); - rt2800_rfcsr_write(rt2x00dev, 63, 0x07); + } else if (rt2x00_rt(rt2x00dev, RT5392)) { + rt2800_rfcsr_write(rt2x00dev, 1, 0x17); + rt2800_rfcsr_write(rt2x00dev, 2, 0x80); + rt2800_rfcsr_write(rt2x00dev, 3, 0x88); + rt2800_rfcsr_write(rt2x00dev, 5, 0x10); + rt2800_rfcsr_write(rt2x00dev, 6, 0xe0); + rt2800_rfcsr_write(rt2x00dev, 7, 0x00); + rt2800_rfcsr_write(rt2x00dev, 10, 0x53); + rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); + rt2800_rfcsr_write(rt2x00dev, 12, 0x46); + rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); + rt2800_rfcsr_write(rt2x00dev, 14, 0x00); + rt2800_rfcsr_write(rt2x00dev, 15, 0x00); + rt2800_rfcsr_write(rt2x00dev, 16, 0x00); + rt2800_rfcsr_write(rt2x00dev, 18, 0x03); + rt2800_rfcsr_write(rt2x00dev, 19, 0x4d); + rt2800_rfcsr_write(rt2x00dev, 20, 0x00); + rt2800_rfcsr_write(rt2x00dev, 21, 0x8d); + rt2800_rfcsr_write(rt2x00dev, 22, 0x20); + rt2800_rfcsr_write(rt2x00dev, 23, 0x0b); + rt2800_rfcsr_write(rt2x00dev, 24, 0x44); + rt2800_rfcsr_write(rt2x00dev, 25, 0x80); + rt2800_rfcsr_write(rt2x00dev, 26, 0x82); + rt2800_rfcsr_write(rt2x00dev, 27, 0x09); + rt2800_rfcsr_write(rt2x00dev, 28, 0x00); + rt2800_rfcsr_write(rt2x00dev, 29, 0x10); + rt2800_rfcsr_write(rt2x00dev, 30, 0x10); + rt2800_rfcsr_write(rt2x00dev, 31, 0x80); + rt2800_rfcsr_write(rt2x00dev, 32, 0x20); + rt2800_rfcsr_write(rt2x00dev, 33, 0xC0); + rt2800_rfcsr_write(rt2x00dev, 34, 0x07); + rt2800_rfcsr_write(rt2x00dev, 35, 0x12); + rt2800_rfcsr_write(rt2x00dev, 36, 0x00); + rt2800_rfcsr_write(rt2x00dev, 37, 0x08); + rt2800_rfcsr_write(rt2x00dev, 38, 0x89); + rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); + rt2800_rfcsr_write(rt2x00dev, 40, 0x0f); + rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); + rt2800_rfcsr_write(rt2x00dev, 42, 0xd5); + rt2800_rfcsr_write(rt2x00dev, 43, 0x9b); + rt2800_rfcsr_write(rt2x00dev, 44, 0x0e); + rt2800_rfcsr_write(rt2x00dev, 45, 0xa2); + rt2800_rfcsr_write(rt2x00dev, 46, 0x73); + rt2800_rfcsr_write(rt2x00dev, 47, 0x0c); + rt2800_rfcsr_write(rt2x00dev, 48, 0x10); + rt2800_rfcsr_write(rt2x00dev, 49, 0x94); + rt2800_rfcsr_write(rt2x00dev, 50, 0x94); + rt2800_rfcsr_write(rt2x00dev, 51, 0x3a); + rt2800_rfcsr_write(rt2x00dev, 52, 0x48); + rt2800_rfcsr_write(rt2x00dev, 53, 0x44); + rt2800_rfcsr_write(rt2x00dev, 54, 0x38); + rt2800_rfcsr_write(rt2x00dev, 55, 0x43); + rt2800_rfcsr_write(rt2x00dev, 56, 0xa1); + rt2800_rfcsr_write(rt2x00dev, 57, 0x00); + rt2800_rfcsr_write(rt2x00dev, 58, 0x39); + rt2800_rfcsr_write(rt2x00dev, 59, 0x07); + rt2800_rfcsr_write(rt2x00dev, 60, 0x45); + rt2800_rfcsr_write(rt2x00dev, 61, 0x91); + rt2800_rfcsr_write(rt2x00dev, 62, 0x39); + rt2800_rfcsr_write(rt2x00dev, 63, 0x07); } if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) { @@ -4356,7 +4356,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2800_bbp_read(rt2x00dev, 26, &drv_data->bbp26); if (!rt2x00_rt(rt2x00dev, RT5390) && - !rt2x00_rt(rt2x00dev, RT5392)) { + !rt2x00_rt(rt2x00dev, RT5392)) { /* * Set back to initial state */ @@ -4385,7 +4385,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2800_register_write(rt2x00dev, OPT_14_CSR, reg); if (!rt2x00_rt(rt2x00dev, RT5390) && - !rt2x00_rt(rt2x00dev, RT5392)) { + !rt2x00_rt(rt2x00dev, RT5392)) { rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0); if (rt2x00_rt(rt2x00dev, RT3070) || @@ -4457,7 +4457,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) } if (rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) { + rt2x00_rt(rt2x00dev, RT5392)) { rt2800_rfcsr_read(rt2x00dev, 38, &rfcsr); rt2x00_set_field8(&rfcsr, RFCSR38_RX_LO1_EN, 0); rt2800_rfcsr_write(rt2x00dev, 38, rfcsr); diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800usb.c b/trunk/drivers/net/wireless/rt2x00/rt2800usb.c index 023081286e0c..3b8fb5a603f2 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2800usb.c @@ -1096,7 +1096,6 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x177f, 0x0153) }, { USB_DEVICE(0x177f, 0x0302) }, { USB_DEVICE(0x177f, 0x0313) }, - { USB_DEVICE(0x177f, 0x0323) }, /* U-Media */ { USB_DEVICE(0x157e, 0x300e) }, { USB_DEVICE(0x157e, 0x3013) }, diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c b/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c index 66b3b17b16d2..67d167993d45 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -1182,13 +1182,6 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) */ rt2x00dev->hw->vif_data_size = sizeof(struct rt2x00_intf); - /* - * rt2x00 devices can only use the last n bits of the MAC address - * for virtual interfaces. - */ - rt2x00dev->hw->wiphy->addr_mask[ETH_ALEN - 1] = - (rt2x00dev->ops->max_ap_intf - 1); - /* * Determine which operating modes are supported, all modes * which require beaconing, depend on the availability of diff --git a/trunk/drivers/net/wireless/rtlwifi/Kconfig b/trunk/drivers/net/wireless/rtlwifi/Kconfig index 21b1bbb93a7e..6b28e92d1d21 100644 --- a/trunk/drivers/net/wireless/rtlwifi/Kconfig +++ b/trunk/drivers/net/wireless/rtlwifi/Kconfig @@ -32,17 +32,6 @@ config RTL8192DE If you choose to build it as a module, it will be called rtl8192de -config RTL8723AE - tristate "Realtek RTL8723AE PCIe Wireless Network Adapter" - depends on MAC80211 && PCI && EXPERIMENTAL - select FW_LOADER - select RTLWIFI - ---help--- - This is the driver for Realtek RTL8723AE 802.11n PCIe - wireless network adapters. - - If you choose to build it as a module, it will be called rtl8723ae - config RTL8192CU tristate "Realtek RTL8192CU/RTL8188CU USB Wireless Network Adapter" depends on MAC80211 && USB diff --git a/trunk/drivers/net/wireless/rtlwifi/Makefile b/trunk/drivers/net/wireless/rtlwifi/Makefile index 3b1cbac741e3..97935c565bab 100644 --- a/trunk/drivers/net/wireless/rtlwifi/Makefile +++ b/trunk/drivers/net/wireless/rtlwifi/Makefile @@ -7,8 +7,7 @@ rtlwifi-objs := \ efuse.o \ ps.o \ rc.o \ - regd.o \ - stats.o + regd.o rtl8192c_common-objs += \ @@ -25,6 +24,5 @@ obj-$(CONFIG_RTL8192CE) += rtl8192ce/ obj-$(CONFIG_RTL8192CU) += rtl8192cu/ obj-$(CONFIG_RTL8192SE) += rtl8192se/ obj-$(CONFIG_RTL8192DE) += rtl8192de/ -obj-$(CONFIG_RTL8723AE) += rtl8723ae/ ccflags-y += -D__CHECK_ENDIAN__ diff --git a/trunk/drivers/net/wireless/rtlwifi/base.c b/trunk/drivers/net/wireless/rtlwifi/base.c index 4494d130b37c..59381fe8ed06 100644 --- a/trunk/drivers/net/wireless/rtlwifi/base.c +++ b/trunk/drivers/net/wireless/rtlwifi/base.c @@ -826,30 +826,6 @@ int rtlwifi_rate_mapping(struct ieee80211_hw *hw, } EXPORT_SYMBOL(rtlwifi_rate_mapping); -bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb) -{ - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_priv *rtlpriv = rtl_priv(hw); - __le16 fc = rtl_get_fc(skb); - - if (rtlpriv->dm.supp_phymode_switch && - mac->link_state < MAC80211_LINKED && - (ieee80211_is_auth(fc) || ieee80211_is_probe_req(fc))) { - if (rtlpriv->cfg->ops->check_switch_to_dmdp) - rtlpriv->cfg->ops->check_switch_to_dmdp(hw); - } - if (ieee80211_is_auth(fc)) { - RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); - rtl_ips_nic_on(hw); - - mac->link_state = MAC80211_LINKING; - /* Dual mac */ - rtlpriv->phy.need_iqk = true; - } - - return true; -} - void rtl_get_tcb_desc(struct ieee80211_hw *hw, struct ieee80211_tx_info *info, struct ieee80211_sta *sta, diff --git a/trunk/drivers/net/wireless/rtlwifi/base.h b/trunk/drivers/net/wireless/rtlwifi/base.h index 5a8c80e259f7..f35af0fdaaf0 100644 --- a/trunk/drivers/net/wireless/rtlwifi/base.h +++ b/trunk/drivers/net/wireless/rtlwifi/base.h @@ -142,6 +142,4 @@ u8 rtl_tid_to_ac(u8 tid); extern struct attribute_group rtl_attribute_group; int rtlwifi_rate_mapping(struct ieee80211_hw *hw, bool isht, u8 desc_rate, bool first_ampdu); -bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb); - #endif diff --git a/trunk/drivers/net/wireless/rtlwifi/cam.c b/trunk/drivers/net/wireless/rtlwifi/cam.c index 0e510f73041a..ca69e35e50f1 100644 --- a/trunk/drivers/net/wireless/rtlwifi/cam.c +++ b/trunk/drivers/net/wireless/rtlwifi/cam.c @@ -337,7 +337,7 @@ void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr) if (((bitmap & BIT(0)) == BIT(0)) && (memcmp(addr, sta_addr, ETH_ALEN) == 0)) { /* Remove from HW Security CAM */ - eth_zero_addr(rtlpriv->sec.hwsec_cam_sta_addr[i]); + memset(rtlpriv->sec.hwsec_cam_sta_addr[i], 0, ETH_ALEN); rtlpriv->sec.hwsec_cam_bitmap &= ~(BIT(0) << i); RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "del CAM entry %d\n", i); diff --git a/trunk/drivers/net/wireless/rtlwifi/core.c b/trunk/drivers/net/wireless/rtlwifi/core.c index be33aa14c8af..a7c0e52869ba 100644 --- a/trunk/drivers/net/wireless/rtlwifi/core.c +++ b/trunk/drivers/net/wireless/rtlwifi/core.c @@ -962,6 +962,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, int err = 0; u8 mac_addr[ETH_ALEN]; u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + u8 zero_addr[ETH_ALEN] = { 0 }; if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, @@ -1056,7 +1057,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, memcpy(rtlpriv->sec.key_buf[key_idx], key->key, key->keylen); rtlpriv->sec.key_len[key_idx] = key->keylen; - eth_zero_addr(mac_addr); + memcpy(mac_addr, zero_addr, ETH_ALEN); } else if (group_key) { /* group key */ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "set group key\n"); @@ -1107,7 +1108,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, } memset(rtlpriv->sec.key_buf[key_idx], 0, key->keylen); rtlpriv->sec.key_len[key_idx] = 0; - eth_zero_addr(mac_addr); + memcpy(mac_addr, zero_addr, ETH_ALEN); /* *mac80211 will delete entrys one by one, *so don't use rtl_cam_reset_all_entry diff --git a/trunk/drivers/net/wireless/rtlwifi/debug.h b/trunk/drivers/net/wireless/rtlwifi/debug.h index fd3269f47685..07493d2957f2 100644 --- a/trunk/drivers/net/wireless/rtlwifi/debug.h +++ b/trunk/drivers/net/wireless/rtlwifi/debug.h @@ -106,8 +106,6 @@ #define COMP_REGD BIT(27) #define COMP_CHAN BIT(28) #define COMP_USB BIT(29) -#define COMP_EASY_CONCURRENT COMP_USB /* reuse of this bit is OK */ -#define COMP_BT_COEXIST BIT(30) /*-------------------------------------------------------------- Define the rt_print components diff --git a/trunk/drivers/net/wireless/rtlwifi/pci.c b/trunk/drivers/net/wireless/rtlwifi/pci.c index 086140cba026..abc306b502ac 100644 --- a/trunk/drivers/net/wireless/rtlwifi/pci.c +++ b/trunk/drivers/net/wireless/rtlwifi/pci.c @@ -1309,7 +1309,6 @@ static bool rtl_pci_tx_chk_waitq_insert(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_sta_info *sta_entry = NULL; u8 tid = rtl_get_tid(skb); - __le16 fc = rtl_get_fc(skb); if (!sta) return false; @@ -1317,12 +1316,6 @@ static bool rtl_pci_tx_chk_waitq_insert(struct ieee80211_hw *hw, if (!rtlpriv->rtlhal.earlymode_enable) return false; - if (ieee80211_is_nullfunc(fc)) - return false; - if (ieee80211_is_qos_nullfunc(fc)) - return false; - if (ieee80211_is_pspoll(fc)) - return false; if (sta_entry->tids[tid].agg.agg_state != RTL_AGG_OPERATIONAL) return false; if (_rtl_mac_to_hwqueue(hw, skb) > VO_QUEUE) @@ -1364,8 +1357,10 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, u8 own; u8 temp_one = 1; - if (ieee80211_is_mgmt(fc)) - rtl_tx_mgmt_proc(hw, skb); + if (ieee80211_is_auth(fc)) { + RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); + rtl_ips_nic_on(hw); + } if (rtlpriv->psc.sw_ps_enabled) { if (ieee80211_is_data(fc) && !ieee80211_is_nullfunc(fc) && @@ -1633,7 +1628,7 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, "8192 PCI-E is found - vid/did=%x/%x\n", venderid, deviceid); rtlhal->hw_type = HARDWARE_TYPE_RTL8192E; - return false; + break; case RTL_PCI_REVISION_ID_8192SE: RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "8192SE is found - vid/did=%x/%x\n", @@ -1648,11 +1643,6 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, break; } - } else if (deviceid == RTL_PCI_8723AE_DID) { - rtlhal->hw_type = HARDWARE_TYPE_RTL8723AE; - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "8723AE PCI-E is found - " - "vid/did=%x/%x\n", venderid, deviceid); } else if (deviceid == RTL_PCI_8192CET_DID || deviceid == RTL_PCI_8192CE_DID || deviceid == RTL_PCI_8191CE_DID || @@ -1982,7 +1972,6 @@ void rtl_pci_disconnect(struct pci_dev *pdev) } EXPORT_SYMBOL(rtl_pci_disconnect); -#ifdef CONFIG_PM_SLEEP /*************************************** kernel pci power state define: PCI_D0 ((pci_power_t __force) 0) @@ -2022,7 +2011,6 @@ int rtl_pci_resume(struct device *dev) return 0; } EXPORT_SYMBOL(rtl_pci_resume); -#endif /* CONFIG_PM_SLEEP */ struct rtl_intf_ops rtl_pci_ops = { .read_efuse_byte = read_efuse_byte, diff --git a/trunk/drivers/net/wireless/rtlwifi/pci.h b/trunk/drivers/net/wireless/rtlwifi/pci.h index 7ea50a32bafb..241448fc9ed5 100644 --- a/trunk/drivers/net/wireless/rtlwifi/pci.h +++ b/trunk/drivers/net/wireless/rtlwifi/pci.h @@ -79,7 +79,6 @@ #define RTL_PCI_8173_DID 0x8173 /*8191 SE Crab */ #define RTL_PCI_8172_DID 0x8172 /*8191 SE RE */ #define RTL_PCI_8171_DID 0x8171 /*8191 SE Unicron */ -#define RTL_PCI_8723AE_DID 0x8723 /*8723AE */ #define RTL_PCI_0045_DID 0x0045 /*8190 PCI for Ceraga */ #define RTL_PCI_0046_DID 0x0046 /*8190 Cardbus for Ceraga */ #define RTL_PCI_0044_DID 0x0044 /*8192e PCIE for Ceraga */ @@ -153,7 +152,6 @@ struct rtl8192_rx_ring { struct rtl_pci { struct pci_dev *pdev; - bool irq_enabled; bool driver_is_goingto_unload; bool up_first_time; @@ -239,10 +237,8 @@ extern struct rtl_intf_ops rtl_pci_ops; int __devinit rtl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id); void rtl_pci_disconnect(struct pci_dev *pdev); -#ifdef CONFIG_PM_SLEEP int rtl_pci_suspend(struct device *dev); int rtl_pci_resume(struct device *dev); -#endif /* CONFIG_PM_SLEEP */ static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr) { return readb((u8 __iomem *) rtlpriv->io.pci_mem_start + addr); diff --git a/trunk/drivers/net/wireless/rtlwifi/rc.c b/trunk/drivers/net/wireless/rtlwifi/rc.c index c1e065f136ba..d5cbf01da8ac 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rc.c +++ b/trunk/drivers/net/wireless/rtlwifi/rc.c @@ -55,8 +55,7 @@ static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv, * 1M we will not use FW rate but user rate. */ if (rtlmac->opmode == NL80211_IFTYPE_AP || - rtlmac->opmode == NL80211_IFTYPE_ADHOC || - rtlmac->opmode == NL80211_IFTYPE_MESH_POINT) { + rtlmac->opmode == NL80211_IFTYPE_ADHOC) { if (sta) { sta_entry = (struct rtl_sta_info *) sta->drv_priv; wireless_mode = sta_entry->wireless_mode; diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index 1cdf5a271c9f..1ca4e25c143b 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c @@ -43,8 +43,8 @@ #define GET_UNDECORATED_AVERAGE_RSSI(_priv) \ ((RTLPRIV(_priv))->mac80211.opmode == \ NL80211_IFTYPE_ADHOC) ? \ - ((RTLPRIV(_priv))->dm.entry_min_undec_sm_pwdb) : \ - ((RTLPRIV(_priv))->dm.undec_sm_pwdb) + ((RTLPRIV(_priv))->dm.entry_min_undecoratedsmoothed_pwdb) : \ + ((RTLPRIV(_priv))->dm.undecorated_smoothed_pwdb) static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = { 0x7f8001fe, @@ -167,18 +167,18 @@ static void rtl92c_dm_diginit(struct ieee80211_hw *hw) dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; dm_digtable->cur_igvalue = 0x20; dm_digtable->pre_igvalue = 0x0; - dm_digtable->cursta_cstate = DIG_STA_DISCONNECT; - dm_digtable->presta_cstate = DIG_STA_DISCONNECT; - dm_digtable->curmultista_cstate = DIG_MULTISTA_DISCONNECT; + dm_digtable->cursta_connectstate = DIG_STA_DISCONNECT; + dm_digtable->presta_connectstate = DIG_STA_DISCONNECT; + dm_digtable->curmultista_connectstate = DIG_MULTISTA_DISCONNECT; dm_digtable->rssi_lowthresh = DM_DIG_THRESH_LOW; dm_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH; dm_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW; dm_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH; dm_digtable->rx_gain_range_max = DM_DIG_MAX; dm_digtable->rx_gain_range_min = DM_DIG_MIN; - dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT; - dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX; - dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN; + dm_digtable->backoff_val = DM_DIG_BACKOFF_DEFAULT; + dm_digtable->backoff_val_range_max = DM_DIG_BACKOFF_MAX; + dm_digtable->backoff_val_range_min = DM_DIG_BACKOFF_MIN; dm_digtable->pre_cck_pd_state = CCK_PD_STAGE_MAX; dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX; } @@ -189,21 +189,22 @@ static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw) struct dig_t *dm_digtable = &rtlpriv->dm_digtable; long rssi_val_min = 0; - if ((dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) && - (dm_digtable->cursta_cstate == DIG_STA_CONNECT)) { - if (rtlpriv->dm.entry_min_undec_sm_pwdb != 0) + if ((dm_digtable->curmultista_connectstate == DIG_MULTISTA_CONNECT) && + (dm_digtable->cursta_connectstate == DIG_STA_CONNECT)) { + if (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb != 0) rssi_val_min = - (rtlpriv->dm.entry_min_undec_sm_pwdb > - rtlpriv->dm.undec_sm_pwdb) ? - rtlpriv->dm.undec_sm_pwdb : - rtlpriv->dm.entry_min_undec_sm_pwdb; + (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb > + rtlpriv->dm.undecorated_smoothed_pwdb) ? + rtlpriv->dm.undecorated_smoothed_pwdb : + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; else - rssi_val_min = rtlpriv->dm.undec_sm_pwdb; - } else if (dm_digtable->cursta_cstate == DIG_STA_CONNECT || - dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT) { - rssi_val_min = rtlpriv->dm.undec_sm_pwdb; - } else if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) { - rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb; + rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb; + } else if (dm_digtable->cursta_connectstate == DIG_STA_CONNECT || + dm_digtable->cursta_connectstate == DIG_STA_BEFORE_CONNECT) { + rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb; + } else if (dm_digtable->curmultista_connectstate == + DIG_MULTISTA_CONNECT) { + rssi_val_min = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; } return (u8) rssi_val_min; @@ -285,33 +286,37 @@ static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw) static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); - struct dig_t *digtable = &rtlpriv->dm_digtable; + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; - if (rtlpriv->falsealm_cnt.cnt_all > digtable->fa_highthresh) { - if ((digtable->back_val - 2) < digtable->back_range_min) - digtable->back_val = digtable->back_range_min; + if (rtlpriv->falsealm_cnt.cnt_all > dm_digtable->fa_highthresh) { + if ((dm_digtable->backoff_val - 2) < + dm_digtable->backoff_val_range_min) + dm_digtable->backoff_val = + dm_digtable->backoff_val_range_min; else - digtable->back_val -= 2; - } else if (rtlpriv->falsealm_cnt.cnt_all < digtable->fa_lowthresh) { - if ((digtable->back_val + 2) > digtable->back_range_max) - digtable->back_val = digtable->back_range_max; + dm_digtable->backoff_val -= 2; + } else if (rtlpriv->falsealm_cnt.cnt_all < dm_digtable->fa_lowthresh) { + if ((dm_digtable->backoff_val + 2) > + dm_digtable->backoff_val_range_max) + dm_digtable->backoff_val = + dm_digtable->backoff_val_range_max; else - digtable->back_val += 2; + dm_digtable->backoff_val += 2; } - if ((digtable->rssi_val_min + 10 - digtable->back_val) > - digtable->rx_gain_range_max) - digtable->cur_igvalue = digtable->rx_gain_range_max; - else if ((digtable->rssi_val_min + 10 - - digtable->back_val) < digtable->rx_gain_range_min) - digtable->cur_igvalue = digtable->rx_gain_range_min; + if ((dm_digtable->rssi_val_min + 10 - dm_digtable->backoff_val) > + dm_digtable->rx_gain_range_max) + dm_digtable->cur_igvalue = dm_digtable->rx_gain_range_max; + else if ((dm_digtable->rssi_val_min + 10 - + dm_digtable->backoff_val) < dm_digtable->rx_gain_range_min) + dm_digtable->cur_igvalue = dm_digtable->rx_gain_range_min; else - digtable->cur_igvalue = digtable->rssi_val_min + 10 - - digtable->back_val; + dm_digtable->cur_igvalue = dm_digtable->rssi_val_min + 10 - + dm_digtable->backoff_val; RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - "rssi_val_min = %x back_val %x\n", - digtable->rssi_val_min, digtable->back_val); + "rssi_val_min = %x backoff_val %x\n", + dm_digtable->rssi_val_min, dm_digtable->backoff_val); rtl92c_dm_write_dig(hw); } @@ -322,14 +327,14 @@ static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct dig_t *dm_digtable = &rtlpriv->dm_digtable; struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - long rssi_strength = rtlpriv->dm.entry_min_undec_sm_pwdb; + long rssi_strength = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; bool multi_sta = false; if (mac->opmode == NL80211_IFTYPE_ADHOC) multi_sta = true; if (!multi_sta || - dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) { + dm_digtable->cursta_connectstate != DIG_STA_DISCONNECT) { initialized = false; dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; return; @@ -340,7 +345,7 @@ static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) rtl92c_dm_write_dig(hw); } - if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) { + if (dm_digtable->curmultista_connectstate == DIG_MULTISTA_CONNECT) { if ((rssi_strength < dm_digtable->rssi_lowthresh) && (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) { @@ -362,8 +367,8 @@ static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) } RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - "curmultista_cstate = %x dig_ext_port_stage %x\n", - dm_digtable->curmultista_cstate, + "curmultista_connectstate = %x dig_ext_port_stage %x\n", + dm_digtable->curmultista_connectstate, dm_digtable->dig_ext_port_stage); } @@ -373,14 +378,15 @@ static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw) struct dig_t *dm_digtable = &rtlpriv->dm_digtable; RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - "presta_cstate = %x, cursta_cstate = %x\n", - dm_digtable->presta_cstate, dm_digtable->cursta_cstate); + "presta_connectstate = %x, cursta_connectstate = %x\n", + dm_digtable->presta_connectstate, + dm_digtable->cursta_connectstate); - if (dm_digtable->presta_cstate == dm_digtable->cursta_cstate || - dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT || - dm_digtable->cursta_cstate == DIG_STA_CONNECT) { + if (dm_digtable->presta_connectstate == dm_digtable->cursta_connectstate + || dm_digtable->cursta_connectstate == DIG_STA_BEFORE_CONNECT + || dm_digtable->cursta_connectstate == DIG_STA_CONNECT) { - if (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) { + if (dm_digtable->cursta_connectstate != DIG_STA_DISCONNECT) { dm_digtable->rssi_val_min = rtl92c_dm_initial_gain_min_pwdb(hw); rtl92c_dm_ctrl_initgain_by_rssi(hw); @@ -388,7 +394,7 @@ static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw) } else { dm_digtable->rssi_val_min = 0; dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; - dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT; + dm_digtable->backoff_val = DM_DIG_BACKOFF_DEFAULT; dm_digtable->cur_igvalue = 0x20; dm_digtable->pre_igvalue = 0; rtl92c_dm_write_dig(hw); @@ -401,7 +407,7 @@ static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); struct dig_t *dm_digtable = &rtlpriv->dm_digtable; - if (dm_digtable->cursta_cstate == DIG_STA_CONNECT) { + if (dm_digtable->cursta_connectstate == DIG_STA_CONNECT) { dm_digtable->rssi_val_min = rtl92c_dm_initial_gain_min_pwdb(hw); if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LowRssi) { @@ -478,15 +484,15 @@ static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) return; if (mac->link_state >= MAC80211_LINKED) - dm_digtable->cursta_cstate = DIG_STA_CONNECT; + dm_digtable->cursta_connectstate = DIG_STA_CONNECT; else - dm_digtable->cursta_cstate = DIG_STA_DISCONNECT; + dm_digtable->cursta_connectstate = DIG_STA_DISCONNECT; rtl92c_dm_initial_gain_sta(hw); rtl92c_dm_initial_gain_multi_sta(hw); rtl92c_dm_cck_packet_detection_thresh(hw); - dm_digtable->presta_cstate = dm_digtable->cursta_cstate; + dm_digtable->presta_connectstate = dm_digtable->cursta_connectstate; } @@ -520,9 +526,9 @@ void rtl92c_dm_write_dig(struct ieee80211_hw *hw) struct dig_t *dm_digtable = &rtlpriv->dm_digtable; RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - "cur_igvalue = 0x%x, pre_igvalue = 0x%x, back_val = %d\n", + "cur_igvalue = 0x%x, pre_igvalue = 0x%x, backoff_val = %d\n", dm_digtable->cur_igvalue, dm_digtable->pre_igvalue, - dm_digtable->back_val); + dm_digtable->backoff_val); dm_digtable->cur_igvalue += 2; if (dm_digtable->cur_igvalue > 0x3f) @@ -549,18 +555,20 @@ static void rtl92c_dm_pwdb_monitor(struct ieee80211_hw *hw) return; if (tmpentry_max_pwdb != 0) { - rtlpriv->dm.entry_max_undec_sm_pwdb = tmpentry_max_pwdb; + rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = + tmpentry_max_pwdb; } else { - rtlpriv->dm.entry_max_undec_sm_pwdb = 0; + rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = 0; } if (tmpentry_min_pwdb != 0xff) { - rtlpriv->dm.entry_min_undec_sm_pwdb = tmpentry_min_pwdb; + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = + tmpentry_min_pwdb; } else { - rtlpriv->dm.entry_min_undec_sm_pwdb = 0; + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = 0; } - h2c_parameter[2] = (u8) (rtlpriv->dm.undec_sm_pwdb & 0xFF); + h2c_parameter[2] = (u8) (rtlpriv->dm.undecorated_smoothed_pwdb & 0xFF); h2c_parameter[0] = 0; rtl92c_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, h2c_parameter); @@ -1152,7 +1160,7 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); struct rate_adaptive *p_ra = &(rtlpriv->ra); - u32 low_rssi_thresh, high_rssi_thresh; + u32 low_rssithresh_for_ra, high_rssithresh_for_ra; struct ieee80211_sta *sta = NULL; if (is_hal_stop(rtlhal)) { @@ -1171,33 +1179,35 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) mac->opmode == NL80211_IFTYPE_STATION) { switch (p_ra->pre_ratr_state) { case DM_RATR_STA_HIGH: - high_rssi_thresh = 50; - low_rssi_thresh = 20; + high_rssithresh_for_ra = 50; + low_rssithresh_for_ra = 20; break; case DM_RATR_STA_MIDDLE: - high_rssi_thresh = 55; - low_rssi_thresh = 20; + high_rssithresh_for_ra = 55; + low_rssithresh_for_ra = 20; break; case DM_RATR_STA_LOW: - high_rssi_thresh = 50; - low_rssi_thresh = 25; + high_rssithresh_for_ra = 50; + low_rssithresh_for_ra = 25; break; default: - high_rssi_thresh = 50; - low_rssi_thresh = 20; + high_rssithresh_for_ra = 50; + low_rssithresh_for_ra = 20; break; } - if (rtlpriv->dm.undec_sm_pwdb > (long)high_rssi_thresh) + if (rtlpriv->dm.undecorated_smoothed_pwdb > + (long)high_rssithresh_for_ra) p_ra->ratr_state = DM_RATR_STA_HIGH; - else if (rtlpriv->dm.undec_sm_pwdb > (long)low_rssi_thresh) + else if (rtlpriv->dm.undecorated_smoothed_pwdb > + (long)low_rssithresh_for_ra) p_ra->ratr_state = DM_RATR_STA_MIDDLE; else p_ra->ratr_state = DM_RATR_STA_LOW; if (p_ra->pre_ratr_state != p_ra->ratr_state) { RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, "RSSI = %ld\n", - rtlpriv->dm.undec_sm_pwdb); + rtlpriv->dm.undecorated_smoothed_pwdb); RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, "RSSI_LEVEL = %d\n", p_ra->ratr_state); RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, @@ -1305,7 +1315,7 @@ static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw) struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); if (((mac->link_state == MAC80211_NOLINK)) && - (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { + (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { dm_pstable->rssi_val_min = 0; RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, "Not connected to any\n"); } @@ -1313,19 +1323,20 @@ static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw) if (mac->link_state == MAC80211_LINKED) { if (mac->opmode == NL80211_IFTYPE_ADHOC) { dm_pstable->rssi_val_min = - rtlpriv->dm.entry_min_undec_sm_pwdb; + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, "AP Client PWDB = 0x%lx\n", dm_pstable->rssi_val_min); } else { - dm_pstable->rssi_val_min = rtlpriv->dm.undec_sm_pwdb; + dm_pstable->rssi_val_min = + rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, "STA Default Port PWDB = 0x%lx\n", dm_pstable->rssi_val_min); } } else { dm_pstable->rssi_val_min = - rtlpriv->dm.entry_min_undec_sm_pwdb; + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, "AP Ext Port PWDB = 0x%lx\n", @@ -1357,7 +1368,7 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - long undec_sm_pwdb; + long undecorated_smoothed_pwdb; if (!rtlpriv->dm.dynamic_txpower_enable) return; @@ -1368,7 +1379,7 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) } if ((mac->link_state < MAC80211_LINKED) && - (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { + (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, "Not connected to any\n"); @@ -1380,35 +1391,41 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) if (mac->link_state >= MAC80211_LINKED) { if (mac->opmode == NL80211_IFTYPE_ADHOC) { - undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "AP Client PWDB = 0x%lx\n", - undec_sm_pwdb); + undecorated_smoothed_pwdb); } else { - undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "STA Default Port PWDB = 0x%lx\n", - undec_sm_pwdb); + undecorated_smoothed_pwdb); } } else { - undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "AP Ext Port PWDB = 0x%lx\n", - undec_sm_pwdb); + undecorated_smoothed_pwdb); } - if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { + if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); - } else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && - (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL1)) { + } else if ((undecorated_smoothed_pwdb < + (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && + (undecorated_smoothed_pwdb >= + TX_POWER_NEAR_FIELD_THRESH_LVL1)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); - } else if (undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { + } else if (undecorated_smoothed_pwdb < + (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "TXHIGHPWRLEVEL_NORMAL\n"); @@ -1456,46 +1473,48 @@ u8 rtl92c_bt_rssi_state_change(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - long undec_sm_pwdb; + long undecorated_smoothed_pwdb; u8 curr_bt_rssi_state = 0x00; if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { - undec_sm_pwdb = GET_UNDECORATED_AVERAGE_RSSI(rtlpriv); + undecorated_smoothed_pwdb = + GET_UNDECORATED_AVERAGE_RSSI(rtlpriv); } else { - if (rtlpriv->dm.entry_min_undec_sm_pwdb == 0) - undec_sm_pwdb = 100; + if (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0) + undecorated_smoothed_pwdb = 100; else - undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; } /* Check RSSI to determine HighPower/NormalPower state for * BT coexistence. */ - if (undec_sm_pwdb >= 67) + if (undecorated_smoothed_pwdb >= 67) curr_bt_rssi_state &= (~BT_RSSI_STATE_NORMAL_POWER); - else if (undec_sm_pwdb < 62) + else if (undecorated_smoothed_pwdb < 62) curr_bt_rssi_state |= BT_RSSI_STATE_NORMAL_POWER; /* Check RSSI to determine AMPDU setting for BT coexistence. */ - if (undec_sm_pwdb >= 40) + if (undecorated_smoothed_pwdb >= 40) curr_bt_rssi_state &= (~BT_RSSI_STATE_AMDPU_OFF); - else if (undec_sm_pwdb <= 32) + else if (undecorated_smoothed_pwdb <= 32) curr_bt_rssi_state |= BT_RSSI_STATE_AMDPU_OFF; /* Marked RSSI state. It will be used to determine BT coexistence * setting later. */ - if (undec_sm_pwdb < 35) + if (undecorated_smoothed_pwdb < 35) curr_bt_rssi_state |= BT_RSSI_STATE_SPECIAL_LOW; else curr_bt_rssi_state &= (~BT_RSSI_STATE_SPECIAL_LOW); /* Set Tx Power according to BT status. */ - if (undec_sm_pwdb >= 30) + if (undecorated_smoothed_pwdb >= 30) curr_bt_rssi_state |= BT_RSSI_STATE_TXPOWER_LOW; - else if (undec_sm_pwdb < 25) + else if (undecorated_smoothed_pwdb < 25) curr_bt_rssi_state &= (~BT_RSSI_STATE_TXPOWER_LOW); /* Check BT state related to BT_Idle in B/G mode. */ - if (undec_sm_pwdb < 15) + if (undecorated_smoothed_pwdb < 15) curr_bt_rssi_state |= BT_RSSI_STATE_BG_EDCA_LOW; else curr_bt_rssi_state &= (~BT_RSSI_STATE_BG_EDCA_LOW); diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c index 1d5d3604e3e0..cdcad7d9f15e 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c @@ -34,6 +34,9 @@ #include "dm_common.h" #include "phy_common.h" +/* Define macro to shorten lines */ +#define MCS_TXPWR mcs_txpwrlevel_origoffset + u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -135,13 +138,13 @@ u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, BIT(8)); if (rfpi_enable) - retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi, + retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi, BLSSIREADBACKDATA); else - retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb, + retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, BLSSIREADBACKDATA); RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n", - rfpath, pphyreg->rf_rb, retvalue); + rfpath, pphyreg->rflssi_readback, retvalue); return retvalue; } EXPORT_SYMBOL(_rtl92c_phy_rf_serial_read); @@ -287,11 +290,11 @@ void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, else return; - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index] = data; + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][index] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "MCSTxPowerLevelOriginalOffset[%d][%d] = 0x%x\n", rtlphy->pwrgroup_cnt, index, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index]); + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][index]); if (index == 13) rtlphy->pwrgroup_cnt++; @@ -371,10 +374,14 @@ void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; - rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; - rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; - rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; - rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control = + RFPGA0_XAB_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control = + RFPGA0_XAB_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control = + RFPGA0_XCD_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control = + RFPGA0_XCD_SWITCHCONTROL; rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1; @@ -386,33 +393,47 @@ void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2; rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; - rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBANLANCE; - rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance = + ROFDM0_XARXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance = + ROFDM0_XBRXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance = + ROFDM0_XCRXIQIMBANLANCE; + rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance = + ROFDM0_XDRXIQIMBALANCE; rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE; rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE; rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; - rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance = + ROFDM0_XATXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance = + ROFDM0_XBTXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance = + ROFDM0_XCTXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance = + ROFDM0_XDTXIQIMBALANCE; rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE; rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE; rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE; - rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback = + RFPGA0_XA_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback = + RFPGA0_XB_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback = + RFPGA0_XC_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback = + RFPGA0_XD_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVEA_HSPI_READBACK; - rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVEB_HSPI_READBACK; + rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi = + TRANSCEIVEA_HSPI_READBACK; + rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi = + TRANSCEIVEB_HSPI_READBACK; } EXPORT_SYMBOL(_rtl92c_phy_init_bb_rf_register_definition); @@ -703,26 +724,6 @@ u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw) } EXPORT_SYMBOL(rtl92c_phy_sw_chnl); -static void _rtl92c_phy_sw_rf_setting(struct ieee80211_hw *hw, u8 channel) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) { - if (channel == 6 && rtlphy->current_chan_bw == - HT_CHANNEL_WIDTH_20) - rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, - 0x00255); - else{ - u32 backupRF0x1A = (u32)rtl_get_rfreg(hw, RF90_PATH_A, - RF_RX_G1, RFREG_OFFSET_MASK); - rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, - backupRF0x1A); - } - } -} - static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, u32 cmdtableidx, u32 cmdtablesz, enum swchnlcmd_id cmdid, @@ -836,7 +837,6 @@ bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, currentcmd->para1, RFREG_OFFSET_MASK, rtlphy->rfreg_chnlval[rfpath]); - _rtl92c_phy_sw_rf_setting(hw, channel); } break; default: diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/def.h b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/def.h index 3cfa1bb0f476..2925094b2d91 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/def.h +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/def.h @@ -116,9 +116,6 @@ LE_BITS_TO_4BYTE(((__pcmdfbhdr) + 4), 20, 12) #define CHIP_VER_B BIT(4) -#define CHIP_BONDING_IDENTIFIER(_value) (((_value) >> 22) & 0x3) -#define CHIP_BONDING_92C_1T2R 0x1 -#define RF_TYPE_1T2R BIT(1) #define CHIP_92C_BITMASK BIT(0) #define CHIP_UNKNOWN BIT(7) #define CHIP_92C_1T2R 0x03 diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c index 74f9c083b80d..27b3af880d96 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c @@ -41,7 +41,7 @@ void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - long undec_sm_pwdb; + long undecorated_smoothed_pwdb; if (!rtlpriv->dm.dynamic_txpower_enable) return; @@ -52,7 +52,7 @@ void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw) } if ((mac->link_state < MAC80211_LINKED) && - (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { + (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, "Not connected to any\n"); @@ -64,35 +64,41 @@ void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw) if (mac->link_state >= MAC80211_LINKED) { if (mac->opmode == NL80211_IFTYPE_ADHOC) { - undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "AP Client PWDB = 0x%lx\n", - undec_sm_pwdb); + undecorated_smoothed_pwdb); } else { - undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "STA Default Port PWDB = 0x%lx\n", - undec_sm_pwdb); + undecorated_smoothed_pwdb); } } else { - undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "AP Ext Port PWDB = 0x%lx\n", - undec_sm_pwdb); + undecorated_smoothed_pwdb); } - if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { + if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); - } else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && - (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL1)) { + } else if ((undecorated_smoothed_pwdb < + (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && + (undecorated_smoothed_pwdb >= + TX_POWER_NEAR_FIELD_THRESH_LVL1)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); - } else if (undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { + } else if (undecorated_smoothed_pwdb < + (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "TXHIGHPWRLEVEL_NORMAL\n"); diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index d1f34f6ffbdf..038c02c9afed 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -896,6 +896,7 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) struct rtl_phy *rtlphy = &(rtlpriv->phy); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); + static bool iqk_initialized; /* initialized to false */ bool rtstatus = true; bool is92c; int err; @@ -920,28 +921,9 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) rtlhal->last_hmeboxnum = 0; rtl92c_phy_mac_config(hw); - /* because last function modify RCR, so we update - * rcr var here, or TP will unstable for receive_config - * is wrong, RX RCR_ACRC32 will cause TP unstabel & Rx - * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252*/ - rtlpci->receive_config = rtl_read_dword(rtlpriv, REG_RCR); - rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV); - rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); rtl92c_phy_bb_config(hw); rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; rtl92c_phy_rf_config(hw); - if (IS_VENDOR_UMC_A_CUT(rtlhal->version) && - !IS_92C_SERIAL(rtlhal->version)) { - rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, 0x30255); - rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G2, MASKDWORD, 0x50a00); - } else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) { - rtl_set_rfreg(hw, RF90_PATH_A, 0x0C, MASKDWORD, 0x894AE); - rtl_set_rfreg(hw, RF90_PATH_A, 0x0A, MASKDWORD, 0x1AF31); - rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, MASKDWORD, 0x8F425); - rtl_set_rfreg(hw, RF90_PATH_A, RF_SYN_G2, MASKDWORD, 0x4F200); - rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK1, MASKDWORD, 0x44053); - rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK2, MASKDWORD, 0x80201); - } rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0, RF_CHNLBW, RFREG_OFFSET_MASK); rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1, @@ -963,11 +945,11 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) if (ppsc->rfpwr_state == ERFON) { rtl92c_phy_set_rfpath_switch(hw, 1); - if (rtlphy->iqk_initialized) { + if (iqk_initialized) { rtl92c_phy_iq_calibrate(hw, true); } else { rtl92c_phy_iq_calibrate(hw, false); - rtlphy->iqk_initialized = true; + iqk_initialized = true; } rtl92c_dm_check_txpower_tracking(hw); @@ -1022,13 +1004,6 @@ static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw) ? CHIP_VENDOR_UMC_B_CUT : CHIP_UNKNOWN) | CHIP_VENDOR_UMC)); } - if (IS_92C_SERIAL(version)) { - value32 = rtl_read_dword(rtlpriv, REG_HPON_FSM); - version = (enum version_8192c)(version | - ((CHIP_BONDING_IDENTIFIER(value32) - == CHIP_BONDING_92C_1T2R) ? - RF_TYPE_1T2R : 0)); - } } switch (version) { @@ -1044,30 +1019,12 @@ static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw) case VERSION_A_CHIP_88C: versionid = "A_CHIP_88C"; break; - case VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT: - versionid = "A_CUT_92C_1T2R"; - break; - case VERSION_NORMAL_UMC_CHIP_92C_A_CUT: - versionid = "A_CUT_92C"; - break; - case VERSION_NORMAL_UMC_CHIP_88C_A_CUT: - versionid = "A_CUT_88C"; - break; - case VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT: - versionid = "B_CUT_92C_1T2R"; - break; - case VERSION_NORMAL_UMC_CHIP_92C_B_CUT: - versionid = "B_CUT_92C"; - break; - case VERSION_NORMAL_UMC_CHIP_88C_B_CUT: - versionid = "B_CUT_88C"; - break; default: versionid = "Unknown. Bug?"; break; } - RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Chip Version ID: %s\n", versionid); switch (version & 0x3) { @@ -1240,7 +1197,6 @@ static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtlpriv); u8 u1b_tmp; u32 u4b_tmp; @@ -1269,8 +1225,7 @@ static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw) rtl_write_word(rtlpriv, REG_GPIO_IO_SEL, 0x0790); rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8080); rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x80); - if (!IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) - rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23); + rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23); if (rtlpcipriv->bt_coexist.bt_coexistence) { u4b_tmp = rtl_read_dword(rtlpriv, REG_AFE_XTAL_CTRL); u4b_tmp |= 0x03824800; @@ -1299,9 +1254,6 @@ void rtl92ce_card_disable(struct ieee80211_hw *hw) rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); _rtl92ce_poweroff_adapter(hw); - - /* after power off we should do iqk again */ - rtlpriv->phy.iqk_initialized = false; } void rtl92ce_interrupt_recognized(struct ieee80211_hw *hw, @@ -1403,9 +1355,9 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, tempval = hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i]; else tempval = EEPROM_DEFAULT_HT40_2SDIFF; - rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_A][i] = + rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[RF90_PATH_A][i] = (tempval & 0xf); - rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_B][i] = + rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[RF90_PATH_B][i] = ((tempval & 0xf0) >> 4); } @@ -1429,7 +1381,7 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", rf_path, i, rtlefuse-> - eprom_chnl_txpwr_ht40_2sdf[rf_path][i]); + eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) { for (i = 0; i < 14; i++) { @@ -1444,14 +1396,14 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, if ((rtlefuse-> eeprom_chnlarea_txpwr_ht40_1s[rf_path][index] - rtlefuse-> - eprom_chnl_txpwr_ht40_2sdf[rf_path][index]) + eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][index]) > 0) { rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = rtlefuse-> eeprom_chnlarea_txpwr_ht40_1s[rf_path] [index] - rtlefuse-> - eprom_chnl_txpwr_ht40_2sdf[rf_path] + eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path] [index]; } else { rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 0; @@ -1960,8 +1912,6 @@ static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, ratr_bitmap &= 0x0f0ff0ff; break; } - sta_entry->ratr_index = ratr_index; - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "ratr_bitmap :%x\n", ratr_bitmap); *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) | @@ -2224,7 +2174,7 @@ static void rtl8192ce_bt_var_init(struct ieee80211_hw *hw) if (rtlpcipriv->bt_coexist.reg_bt_iso == 2) rtlpcipriv->bt_coexist.bt_ant_isolation = - rtlpcipriv->bt_coexist.eeprom_bt_ant_isol; + rtlpcipriv->bt_coexist.eeprom_bt_ant_isolation; else rtlpcipriv->bt_coexist.bt_ant_isolation = rtlpcipriv->bt_coexist.reg_bt_iso; @@ -2255,22 +2205,23 @@ void rtl8192ce_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, bool auto_load_fail, u8 *hwinfo) { struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - u8 val; + u8 value; if (!auto_load_fail) { rtlpcipriv->bt_coexist.eeprom_bt_coexist = ((hwinfo[RF_OPTION1] & 0xe0) >> 5); - val = hwinfo[RF_OPTION4]; - rtlpcipriv->bt_coexist.eeprom_bt_type = ((val & 0xe) >> 1); - rtlpcipriv->bt_coexist.eeprom_bt_ant_num = (val & 0x1); - rtlpcipriv->bt_coexist.eeprom_bt_ant_isol = ((val & 0x10) >> 4); + value = hwinfo[RF_OPTION4]; + rtlpcipriv->bt_coexist.eeprom_bt_type = ((value & 0xe) >> 1); + rtlpcipriv->bt_coexist.eeprom_bt_ant_num = (value & 0x1); + rtlpcipriv->bt_coexist.eeprom_bt_ant_isolation = + ((value & 0x10) >> 4); rtlpcipriv->bt_coexist.eeprom_bt_radio_shared = - ((val & 0x20) >> 5); + ((value & 0x20) >> 5); } else { rtlpcipriv->bt_coexist.eeprom_bt_coexist = 0; rtlpcipriv->bt_coexist.eeprom_bt_type = BT_2WIRE; rtlpcipriv->bt_coexist.eeprom_bt_ant_num = ANT_X2; - rtlpcipriv->bt_coexist.eeprom_bt_ant_isol = 0; + rtlpcipriv->bt_coexist.eeprom_bt_ant_isolation = 0; rtlpcipriv->bt_coexist.eeprom_bt_radio_shared = BT_RADIO_SHARED; } diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c index 73262ca3864b..88deae67cc14 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c @@ -82,8 +82,6 @@ bool rtl92c_phy_mac_config(struct ieee80211_hw *hw) if (is92c) rtl_write_byte(rtlpriv, 0x14, 0x71); - else - rtl_write_byte(rtlpriv, 0x04CA, 0x0A); return rtstatus; } diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c index a9c406f33d0a..54c7614958a8 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c @@ -97,12 +97,15 @@ void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, } if (rtlefuse->eeprom_regulatory == 0) { - tmpval = (rtlphy->mcs_offset[0][6]) + - (rtlphy->mcs_offset[0][7] << 8); + tmpval = + (rtlphy->mcs_txpwrlevel_origoffset[0][6]) + + (rtlphy->mcs_txpwrlevel_origoffset[0][7] << + 8); tx_agc[RF90_PATH_A] += tmpval; - tmpval = (rtlphy->mcs_offset[0][14]) + - (rtlphy->mcs_offset[0][15] << 24); + tmpval = (rtlphy->mcs_txpwrlevel_origoffset[0][14]) + + (rtlphy->mcs_txpwrlevel_origoffset[0][15] << + 24); tx_agc[RF90_PATH_B] += tmpval; } } @@ -206,7 +209,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, case 0: chnlgroup = 0; - writeVal = rtlphy->mcs_offset[chnlgroup][index + + writeVal = + rtlphy->mcs_txpwrlevel_origoffset[chnlgroup][index + (rf ? 8 : 0)] + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); @@ -236,7 +240,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, chnlgroup++; } - writeVal = rtlphy->mcs_offset[chnlgroup] + writeVal = + rtlphy->mcs_txpwrlevel_origoffset[chnlgroup] [index + (rf ? 8 : 0)] + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); @@ -271,7 +276,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, 1]); } for (i = 0; i < 4; i++) { - pwr_diff_limit[i] = (u8) ((rtlphy->mcs_offset + pwr_diff_limit[i] = + (u8) ((rtlphy->mcs_txpwrlevel_origoffset [chnlgroup][index + (rf ? 8 : 0)] & (0x7f << (i * 8))) >> (i * 8)); @@ -311,7 +317,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, break; default: chnlgroup = 0; - writeVal = rtlphy->mcs_offset[chnlgroup] + writeVal = + rtlphy->mcs_txpwrlevel_origoffset[chnlgroup] [index + (rf ? 8 : 0)] + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index 49f663bd93ff..ea2e1bd847c8 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c @@ -162,10 +162,12 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw) /* request fw */ if (IS_VENDOR_UMC_A_CUT(rtlhal->version) && - !IS_92C_SERIAL(rtlhal->version)) + !IS_92C_SERIAL(rtlhal->version)) { rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU.bin"; - else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) + } else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) { rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU_B.bin"; + pr_info("****** This B_CUT device may not work with kernels 3.6 and earlier\n"); + } rtlpriv->max_fw_size = 0x4000; pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name); @@ -372,7 +374,14 @@ MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n"); MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); -static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume); +static const struct dev_pm_ops rtlwifi_pm_ops = { + .suspend = rtl_pci_suspend, + .resume = rtl_pci_resume, + .freeze = rtl_pci_suspend, + .thaw = rtl_pci_resume, + .poweroff = rtl_pci_suspend, + .restore = rtl_pci_resume, +}; static struct pci_driver rtl92ce_driver = { .name = KBUILD_MODNAME, diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 173424756149..a8fecd7638f6 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -127,11 +127,11 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, { struct rtl_priv *rtlpriv = rtl_priv(hw); struct phy_sts_cck_8192s_t *cck_buf; - struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv); s8 rx_pwr_all = 0, rx_pwr[4]; u8 evm, pwdb_all, rf_rx_num = 0; u8 i, max_spatial_stream; u32 rssi, total_rssi = 0; + bool in_powersavemode = false; bool is_cck_rate; is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc); @@ -140,14 +140,14 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, pstats->is_cck = is_cck_rate; pstats->packet_beacon = packet_beacon; pstats->is_cck = is_cck_rate; - pstats->rx_mimo_sig_qual[0] = -1; - pstats->rx_mimo_sig_qual[1] = -1; + pstats->rx_mimo_signalquality[0] = -1; + pstats->rx_mimo_signalquality[1] = -1; if (is_cck_rate) { u8 report, cck_highpwr; cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo; - if (ppsc->rfpwr_state == ERFON) + if (!in_powersavemode) cck_highpwr = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, BIT(9)); @@ -211,8 +211,8 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, } pstats->signalquality = sq; - pstats->rx_mimo_sig_qual[0] = sq; - pstats->rx_mimo_sig_qual[1] = -1; + pstats->rx_mimo_signalquality[0] = sq; + pstats->rx_mimo_signalquality[1] = -1; } } else { rtlpriv->dm.rfpath_rxenable[0] = @@ -251,7 +251,8 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw, if (i == 0) pstats->signalquality = (u8) (evm & 0xff); - pstats->rx_mimo_sig_qual[i] = (u8) (evm & 0xff); + pstats->rx_mimo_signalquality[i] = + (u8) (evm & 0xff); } } } @@ -361,31 +362,36 @@ static void _rtl92ce_process_pwdb(struct ieee80211_hw *hw, { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - long undec_sm_pwdb; + long undecorated_smoothed_pwdb; if (mac->opmode == NL80211_IFTYPE_ADHOC) { return; } else { - undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.undecorated_smoothed_pwdb; } if (pstats->packet_toself || pstats->packet_beacon) { - if (undec_sm_pwdb < 0) - undec_sm_pwdb = pstats->rx_pwdb_all; + if (undecorated_smoothed_pwdb < 0) + undecorated_smoothed_pwdb = pstats->rx_pwdb_all; - if (pstats->rx_pwdb_all > (u32) undec_sm_pwdb) { - undec_sm_pwdb = (((undec_sm_pwdb) * + if (pstats->rx_pwdb_all > (u32) undecorated_smoothed_pwdb) { + undecorated_smoothed_pwdb = + (((undecorated_smoothed_pwdb) * (RX_SMOOTH_FACTOR - 1)) + (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); - undec_sm_pwdb += 1; + undecorated_smoothed_pwdb = undecorated_smoothed_pwdb + + 1; } else { - undec_sm_pwdb = (((undec_sm_pwdb) * + undecorated_smoothed_pwdb = + (((undecorated_smoothed_pwdb) * (RX_SMOOTH_FACTOR - 1)) + (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); } - rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb; + rtlpriv->dm.undecorated_smoothed_pwdb = + undecorated_smoothed_pwdb; _rtl92ce_update_rxsignalstatistics(hw, pstats); } } @@ -432,14 +438,15 @@ static void _rtl92ce_process_ui_link_quality(struct ieee80211_hw *hw, for (n_spatialstream = 0; n_spatialstream < 2; n_spatialstream++) { if (pstats-> - rx_mimo_sig_qual[n_spatialstream] != -1) { + rx_mimo_signalquality[n_spatialstream] != + -1) { if (rtlpriv->stats. rx_evm_percentage[n_spatialstream] == 0) { rtlpriv->stats. rx_evm_percentage [n_spatialstream] = - pstats->rx_mimo_sig_qual + pstats->rx_mimo_signalquality [n_spatialstream]; } @@ -449,7 +456,8 @@ static void _rtl92ce_process_ui_link_quality(struct ieee80211_hw *hw, stats.rx_evm_percentage [n_spatialstream] * (RX_SMOOTH_FACTOR - 1)) + - (pstats->rx_mimo_sig_qual + (pstats-> + rx_mimo_signalquality [n_spatialstream] * 1)) / (RX_SMOOTH_FACTOR); } diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c index 16a0b9e59acf..6fd39eaf361e 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c @@ -39,7 +39,7 @@ void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - long undec_sm_pwdb; + long undecorated_smoothed_pwdb; if (!rtlpriv->dm.dynamic_txpower_enable) return; @@ -50,7 +50,7 @@ void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw) } if ((mac->link_state < MAC80211_LINKED) && - (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { + (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, "Not connected to any\n"); @@ -62,35 +62,41 @@ void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw) if (mac->link_state >= MAC80211_LINKED) { if (mac->opmode == NL80211_IFTYPE_ADHOC) { - undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "AP Client PWDB = 0x%lx\n", - undec_sm_pwdb); + undecorated_smoothed_pwdb); } else { - undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "STA Default Port PWDB = 0x%lx\n", - undec_sm_pwdb); + undecorated_smoothed_pwdb); } } else { - undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "AP Ext Port PWDB = 0x%lx\n", - undec_sm_pwdb); + undecorated_smoothed_pwdb); } - if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { + if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); - } else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && - (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL1)) { + } else if ((undecorated_smoothed_pwdb < + (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && + (undecorated_smoothed_pwdb >= + TX_POWER_NEAR_FIELD_THRESH_LVL1)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); - } else if (undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { + } else if (undecorated_smoothed_pwdb < + (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "TXHIGHPWRLEVEL_NORMAL\n"); diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index b1ccff474c79..7d36a94263b0 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -152,9 +152,9 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, tempval = hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i]; else tempval = EEPROM_DEFAULT_HT40_2SDIFF; - rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_A][i] = + rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[RF90_PATH_A][i] = (tempval & 0xf); - rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_B][i] = + rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[RF90_PATH_B][i] = ((tempval & 0xf0) >> 4); } for (rf_path = 0; rf_path < 2; rf_path++) @@ -177,7 +177,7 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", rf_path, i, rtlefuse-> - eprom_chnl_txpwr_ht40_2sdf[rf_path][i]); + eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) { for (i = 0; i < 14; i++) { index = _rtl92c_get_chnl_group((u8) i); @@ -189,13 +189,13 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, if ((rtlefuse-> eeprom_chnlarea_txpwr_ht40_1s[rf_path][index] - rtlefuse-> - eprom_chnl_txpwr_ht40_2sdf[rf_path][index]) + eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][index]) > 0) { rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = rtlefuse-> eeprom_chnlarea_txpwr_ht40_1s[rf_path] [index] - rtlefuse-> - eprom_chnl_txpwr_ht40_2sdf[rf_path] + eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path] [index]; } else { rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 0; diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c index 32ff959a0251..7e91c76582ec 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c @@ -46,7 +46,7 @@ #define LINK_Q ui_link_quality #define RX_EVM rx_evm_percentage -#define RX_SIGQ rx_mimo_sig_qual +#define RX_SIGQ rx_mimo_signalquality void rtl92c_read_chip_version(struct ieee80211_hw *hw) @@ -982,27 +982,32 @@ static void _rtl92c_process_pwdb(struct ieee80211_hw *hw, { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - long undec_sm_pwdb = 0; + long undecorated_smoothed_pwdb = 0; if (mac->opmode == NL80211_IFTYPE_ADHOC) { return; } else { - undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.undecorated_smoothed_pwdb; } if (pstats->packet_toself || pstats->packet_beacon) { - if (undec_sm_pwdb < 0) - undec_sm_pwdb = pstats->rx_pwdb_all; - if (pstats->rx_pwdb_all > (u32) undec_sm_pwdb) { - undec_sm_pwdb = (((undec_sm_pwdb) * + if (undecorated_smoothed_pwdb < 0) + undecorated_smoothed_pwdb = pstats->rx_pwdb_all; + if (pstats->rx_pwdb_all > (u32) undecorated_smoothed_pwdb) { + undecorated_smoothed_pwdb = + (((undecorated_smoothed_pwdb) * (RX_SMOOTH_FACTOR - 1)) + (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); - undec_sm_pwdb += 1; + undecorated_smoothed_pwdb = undecorated_smoothed_pwdb + + 1; } else { - undec_sm_pwdb = (((undec_sm_pwdb) * + undecorated_smoothed_pwdb = + (((undecorated_smoothed_pwdb) * (RX_SMOOTH_FACTOR - 1)) + (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); } - rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb; + rtlpriv->dm.undecorated_smoothed_pwdb = + undecorated_smoothed_pwdb; _rtl92c_update_rxsignalstatistics(hw, pstats); } } diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c index 953f1a0f8532..506b9a078ed1 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c @@ -115,11 +115,15 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, (ppowerlevel[idx1] << 24); } if (rtlefuse->eeprom_regulatory == 0) { - tmpval = (rtlphy->mcs_offset[0][6]) + - (rtlphy->mcs_offset[0][7] << 8); + tmpval = (rtlphy->mcs_txpwrlevel_origoffset + [0][6]) + + (rtlphy->mcs_txpwrlevel_origoffset + [0][7] << 8); tx_agc[RF90_PATH_A] += tmpval; - tmpval = (rtlphy->mcs_offset[0][14]) + - (rtlphy->mcs_offset[0][15] << 24); + tmpval = (rtlphy->mcs_txpwrlevel_origoffset + [0][14]) + + (rtlphy->mcs_txpwrlevel_origoffset + [0][15] << 24); tx_agc[RF90_PATH_B] += tmpval; } } @@ -211,7 +215,7 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, switch (rtlefuse->eeprom_regulatory) { case 0: chnlgroup = 0; - writeVal = rtlphy->mcs_offset + writeVal = rtlphy->mcs_txpwrlevel_origoffset [chnlgroup][index + (rf ? 8 : 0)] + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, @@ -234,7 +238,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, else chnlgroup += 4; } - writeVal = rtlphy->mcs_offset[chnlgroup][index + + writeVal = rtlphy->mcs_txpwrlevel_origoffset + [chnlgroup][index + (rf ? 8 : 0)] + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); @@ -266,7 +271,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, [channel - 1]); } for (i = 0; i < 4; i++) { - pwr_diff_limit[i] = (u8) ((rtlphy->mcs_offset + pwr_diff_limit[i] = + (u8) ((rtlphy->mcs_txpwrlevel_origoffset [chnlgroup][index + (rf ? 8 : 0)] & (0x7f << (i * 8))) >> (i * 8)); if (rtlphy->current_chan_bw == @@ -300,7 +306,7 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, break; default: chnlgroup = 0; - writeVal = rtlphy->mcs_offset[chnlgroup] + writeVal = rtlphy->mcs_txpwrlevel_origoffset[chnlgroup] [index + (rf ? 8 : 0)] + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index b7e6607e6b6d..9970c2b1b199 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -297,7 +297,6 @@ static struct usb_device_id rtl8192c_usb_ids[] = { /*=== Customer ID ===*/ /****** 8188CU ********/ {RTL_USB_DEVICE(0x050d, 0x1102, rtl92cu_hal_cfg)}, /*Belkin - Edimax*/ - {RTL_USB_DEVICE(0x050d, 0x11f2, rtl92cu_hal_cfg)}, /*Belkin - ISY*/ {RTL_USB_DEVICE(0x06f8, 0xe033, rtl92cu_hal_cfg)}, /*Hercules - Edimax*/ {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192de/dm.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192de/dm.c index fd8df233ff22..ed868c396c25 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192de/dm.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192de/dm.c @@ -35,7 +35,7 @@ #include "dm.h" #include "fw.h" -#define UNDEC_SM_PWDB entry_min_undec_sm_pwdb +#define UNDEC_SM_PWDB entry_min_undecoratedsmoothed_pwdb static const u32 ofdmswing_table[OFDM_TABLE_SIZE_92D] = { 0x7f8001fe, /* 0, +6.0dB */ @@ -164,18 +164,18 @@ static void rtl92d_dm_diginit(struct ieee80211_hw *hw) de_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; de_digtable->cur_igvalue = 0x20; de_digtable->pre_igvalue = 0x0; - de_digtable->cursta_cstate = DIG_STA_DISCONNECT; - de_digtable->presta_cstate = DIG_STA_DISCONNECT; - de_digtable->curmultista_cstate = DIG_MULTISTA_DISCONNECT; + de_digtable->cursta_connectstate = DIG_STA_DISCONNECT; + de_digtable->presta_connectstate = DIG_STA_DISCONNECT; + de_digtable->curmultista_connectstate = DIG_MULTISTA_DISCONNECT; de_digtable->rssi_lowthresh = DM_DIG_THRESH_LOW; de_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH; de_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW; de_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH; de_digtable->rx_gain_range_max = DM_DIG_FA_UPPER; de_digtable->rx_gain_range_min = DM_DIG_FA_LOWER; - de_digtable->back_val = DM_DIG_BACKOFF_DEFAULT; - de_digtable->back_range_max = DM_DIG_BACKOFF_MAX; - de_digtable->back_range_min = DM_DIG_BACKOFF_MIN; + de_digtable->backoff_val = DM_DIG_BACKOFF_DEFAULT; + de_digtable->backoff_val_range_max = DM_DIG_BACKOFF_MAX; + de_digtable->backoff_val_range_min = DM_DIG_BACKOFF_MIN; de_digtable->pre_cck_pd_state = CCK_PD_STAGE_LOWRSSI; de_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX; de_digtable->large_fa_hit = 0; @@ -273,34 +273,35 @@ static void rtl92d_dm_find_minimum_rssi(struct ieee80211_hw *hw) /* Determine the minimum RSSI */ if ((mac->link_state < MAC80211_LINKED) && (rtlpriv->dm.UNDEC_SM_PWDB == 0)) { - de_digtable->min_undec_pwdb_for_dm = 0; + de_digtable->min_undecorated_pwdb_for_dm = 0; RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, "Not connected to any\n"); } if (mac->link_state >= MAC80211_LINKED) { if (mac->opmode == NL80211_IFTYPE_AP || mac->opmode == NL80211_IFTYPE_ADHOC) { - de_digtable->min_undec_pwdb_for_dm = + de_digtable->min_undecorated_pwdb_for_dm = rtlpriv->dm.UNDEC_SM_PWDB; RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, "AP Client PWDB = 0x%lx\n", rtlpriv->dm.UNDEC_SM_PWDB); } else { - de_digtable->min_undec_pwdb_for_dm = - rtlpriv->dm.undec_sm_pwdb; + de_digtable->min_undecorated_pwdb_for_dm = + rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, "STA Default Port PWDB = 0x%x\n", - de_digtable->min_undec_pwdb_for_dm); + de_digtable->min_undecorated_pwdb_for_dm); } } else { - de_digtable->min_undec_pwdb_for_dm = rtlpriv->dm.UNDEC_SM_PWDB; + de_digtable->min_undecorated_pwdb_for_dm = + rtlpriv->dm.UNDEC_SM_PWDB; RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, "AP Ext Port or disconnect PWDB = 0x%x\n", - de_digtable->min_undec_pwdb_for_dm); + de_digtable->min_undecorated_pwdb_for_dm); } RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "MinUndecoratedPWDBForDM =%d\n", - de_digtable->min_undec_pwdb_for_dm); + de_digtable->min_undecorated_pwdb_for_dm); } static void rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) @@ -309,16 +310,16 @@ static void rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) struct dig_t *de_digtable = &rtlpriv->dm_digtable; unsigned long flag = 0; - if (de_digtable->cursta_cstate == DIG_STA_CONNECT) { + if (de_digtable->cursta_connectstate == DIG_STA_CONNECT) { if (de_digtable->pre_cck_pd_state == CCK_PD_STAGE_LOWRSSI) { - if (de_digtable->min_undec_pwdb_for_dm <= 25) + if (de_digtable->min_undecorated_pwdb_for_dm <= 25) de_digtable->cur_cck_pd_state = CCK_PD_STAGE_LOWRSSI; else de_digtable->cur_cck_pd_state = CCK_PD_STAGE_HIGHRSSI; } else { - if (de_digtable->min_undec_pwdb_for_dm <= 20) + if (de_digtable->min_undecorated_pwdb_for_dm <= 20) de_digtable->cur_cck_pd_state = CCK_PD_STAGE_LOWRSSI; else @@ -341,7 +342,7 @@ static void rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) de_digtable->pre_cck_pd_state = de_digtable->cur_cck_pd_state; } RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "CurSTAConnectState=%s\n", - de_digtable->cursta_cstate == DIG_STA_CONNECT ? + de_digtable->cursta_connectstate == DIG_STA_CONNECT ? "DIG_STA_CONNECT " : "DIG_STA_DISCONNECT"); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "CCKPDStage=%s\n", de_digtable->cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI ? @@ -357,9 +358,9 @@ void rtl92d_dm_write_dig(struct ieee80211_hw *hw) struct dig_t *de_digtable = &rtlpriv->dm_digtable; RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - "cur_igvalue = 0x%x, pre_igvalue = 0x%x, back_val = %d\n", + "cur_igvalue = 0x%x, pre_igvalue = 0x%x, backoff_val = %d\n", de_digtable->cur_igvalue, de_digtable->pre_igvalue, - de_digtable->back_val); + de_digtable->backoff_val); if (de_digtable->dig_enable_flag == false) { RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "DIG is disabled\n"); de_digtable->pre_igvalue = 0x17; @@ -381,13 +382,13 @@ static void rtl92d_early_mode_enabled(struct rtl_priv *rtlpriv) if ((rtlpriv->mac80211.link_state >= MAC80211_LINKED) && (rtlpriv->mac80211.vendor == PEER_CISCO)) { RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "IOT_PEER = CISCO\n"); - if (de_digtable->last_min_undec_pwdb_for_dm >= 50 - && de_digtable->min_undec_pwdb_for_dm < 50) { + if (de_digtable->last_min_undecorated_pwdb_for_dm >= 50 + && de_digtable->min_undecorated_pwdb_for_dm < 50) { rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x00); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "Early Mode Off\n"); - } else if (de_digtable->last_min_undec_pwdb_for_dm <= 55 && - de_digtable->min_undec_pwdb_for_dm > 55) { + } else if (de_digtable->last_min_undecorated_pwdb_for_dm <= 55 && + de_digtable->min_undecorated_pwdb_for_dm > 55) { rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x0f); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "Early Mode On\n"); @@ -408,8 +409,8 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw) RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "==>\n"); if (rtlpriv->rtlhal.earlymode_enable) { rtl92d_early_mode_enabled(rtlpriv); - de_digtable->last_min_undec_pwdb_for_dm = - de_digtable->min_undec_pwdb_for_dm; + de_digtable->last_min_undecorated_pwdb_for_dm = + de_digtable->min_undecorated_pwdb_for_dm; } if (!rtlpriv->dm.dm_initialgain_enable) return; @@ -427,9 +428,9 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw) RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "progress\n"); /* Decide the current status and if modify initial gain or not */ if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) - de_digtable->cursta_cstate = DIG_STA_CONNECT; + de_digtable->cursta_connectstate = DIG_STA_CONNECT; else - de_digtable->cursta_cstate = DIG_STA_DISCONNECT; + de_digtable->cursta_connectstate = DIG_STA_DISCONNECT; /* adjust initial gain according to false alarm counter */ if (falsealm_cnt->cnt_all < DM_DIG_FA_TH0) @@ -521,7 +522,7 @@ static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw) struct rtl_phy *rtlphy = &(rtlpriv->phy); struct rtl_hal *rtlhal = rtl_hal(rtlpriv); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - long undec_sm_pwdb; + long undecorated_smoothed_pwdb; if ((!rtlpriv->dm.dynamic_txpower_enable) || rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) { @@ -538,62 +539,62 @@ static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw) } if (mac->link_state >= MAC80211_LINKED) { if (mac->opmode == NL80211_IFTYPE_ADHOC) { - undec_sm_pwdb = + undecorated_smoothed_pwdb = rtlpriv->dm.UNDEC_SM_PWDB; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "IBSS Client PWDB = 0x%lx\n", - undec_sm_pwdb); + undecorated_smoothed_pwdb); } else { - undec_sm_pwdb = - rtlpriv->dm.undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "STA Default Port PWDB = 0x%lx\n", - undec_sm_pwdb); + undecorated_smoothed_pwdb); } } else { - undec_sm_pwdb = + undecorated_smoothed_pwdb = rtlpriv->dm.UNDEC_SM_PWDB; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "AP Ext Port PWDB = 0x%lx\n", - undec_sm_pwdb); + undecorated_smoothed_pwdb); } if (rtlhal->current_bandtype == BAND_ON_5G) { - if (undec_sm_pwdb >= 0x33) { + if (undecorated_smoothed_pwdb >= 0x33) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL2; RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD, "5G:TxHighPwrLevel_Level2 (TxPwr=0x0)\n"); - } else if ((undec_sm_pwdb < 0x33) - && (undec_sm_pwdb >= 0x2b)) { + } else if ((undecorated_smoothed_pwdb < 0x33) + && (undecorated_smoothed_pwdb >= 0x2b)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD, "5G:TxHighPwrLevel_Level1 (TxPwr=0x10)\n"); - } else if (undec_sm_pwdb < 0x2b) { + } else if (undecorated_smoothed_pwdb < 0x2b) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD, "5G:TxHighPwrLevel_Normal\n"); } } else { - if (undec_sm_pwdb >= + if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL2; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); } else - if ((undec_sm_pwdb < + if ((undecorated_smoothed_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) - && (undec_sm_pwdb >= + && (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL1)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); - } else if (undec_sm_pwdb < + } else if (undecorated_smoothed_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; @@ -619,7 +620,7 @@ static void rtl92d_dm_pwdb_monitor(struct ieee80211_hw *hw) return; /* Indicate Rx signal strength to FW. */ if (rtlpriv->dm.useramask) { - u32 temp = rtlpriv->dm.undec_sm_pwdb; + u32 temp = rtlpriv->dm.undecorated_smoothed_pwdb; temp <<= 16; temp |= 0x100; @@ -628,7 +629,7 @@ static void rtl92d_dm_pwdb_monitor(struct ieee80211_hw *hw) rtl92d_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, (u8 *) (&temp)); } else { rtl_write_byte(rtlpriv, 0x4fe, - (u8) rtlpriv->dm.undec_sm_pwdb); + (u8) rtlpriv->dm.undecorated_smoothed_pwdb); } } diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192de/phy.c index 33041bd4da81..db0086062d05 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192de/phy.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192de/phy.c @@ -298,13 +298,13 @@ static u32 _rtl92d_phy_rf_serial_read(struct ieee80211_hw *hw, rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, BIT(8)); if (rfpi_enable) - retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi, + retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi, BLSSIREADBACKDATA); else - retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb, + retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, BLSSIREADBACKDATA); RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x] = 0x%x\n", - rfpath, pphyreg->rf_rb, retvalue); + rfpath, pphyreg->rflssi_readback, retvalue); return retvalue; } @@ -478,10 +478,14 @@ static void _rtl92d_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) /* RF switch Control */ /* TR/Ant switch control */ - rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; - rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; - rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; - rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control = + RFPGA0_XAB_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control = + RFPGA0_XAB_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control = + RFPGA0_XCD_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control = + RFPGA0_XCD_SWITCHCONTROL; /* AGC control 1 */ rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; @@ -496,10 +500,14 @@ static void _rtl92d_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; /* RX AFE control 1 */ - rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance = + ROFDM0_XARXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance = + ROFDM0_XBRXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance = + ROFDM0_XCRXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance = + ROFDM0_XDRXIQIMBALANCE; /*RX AFE control 1 */ rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; @@ -508,10 +516,14 @@ static void _rtl92d_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; /* Tx AFE control 1 */ - rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATxIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTxIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTxIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTxIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance = + ROFDM0_XATxIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance = + ROFDM0_XBTxIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance = + ROFDM0_XCTxIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance = + ROFDM0_XDTxIQIMBALANCE; /* Tx AFE control 2 */ rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATxAFE; @@ -520,14 +532,20 @@ static void _rtl92d_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTxAFE; /* Tranceiver LSSI Readback SI mode */ - rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback = + RFPGA0_XA_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback = + RFPGA0_XB_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback = + RFPGA0_XC_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback = + RFPGA0_XD_LSSIREADBACK; /* Tranceiver LSSI Readback PI mode */ - rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVERA_HSPI_READBACK; - rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVERB_HSPI_READBACK; + rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi = + TRANSCEIVERA_HSPI_READBACK; + rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi = + TRANSCEIVERB_HSPI_READBACK; } static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, @@ -684,11 +702,12 @@ static void _rtl92d_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw, else return; - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index] = data; + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][index] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "MCSTxPowerLevelOriginalOffset[%d][%d] = 0x%ulx\n", rtlphy->pwrgroup_cnt, index, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index]); + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][index]); if (index == 13) rtlphy->pwrgroup_cnt++; } diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192de/rf.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192de/rf.c index 20144e0b4142..3066a7fb0b57 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192de/rf.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192de/rf.c @@ -106,11 +106,11 @@ void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, (ppowerlevel[idx1] << 24); } if (rtlefuse->eeprom_regulatory == 0) { - tmpval = (rtlphy->mcs_offset[0][6]) + - (rtlphy->mcs_offset[0][7] << 8); + tmpval = (rtlphy->mcs_txpwrlevel_origoffset[0][6]) + + (rtlphy->mcs_txpwrlevel_origoffset[0][7] << 8); tx_agc[RF90_PATH_A] += tmpval; - tmpval = (rtlphy->mcs_offset[0][14]) + - (rtlphy->mcs_offset[0][15] << 24); + tmpval = (rtlphy->mcs_txpwrlevel_origoffset[0][14]) + + (rtlphy->mcs_txpwrlevel_origoffset[0][15] << 24); tx_agc[RF90_PATH_B] += tmpval; } } @@ -227,7 +227,7 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, switch (rtlefuse->eeprom_regulatory) { case 0: chnlgroup = 0; - writeval = rtlphy->mcs_offset + writeval = rtlphy->mcs_txpwrlevel_origoffset [chnlgroup][index + (rf ? 8 : 0)] + ((index < 2) ? powerbase0[rf] : @@ -247,7 +247,7 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, chnlgroup++; else chnlgroup += 4; - writeval = rtlphy->mcs_offset + writeval = rtlphy->mcs_txpwrlevel_origoffset [chnlgroup][index + (rf ? 8 : 0)] + ((index < 2) ? powerbase0[rf] : @@ -280,7 +280,8 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, [channel - 1]); } for (i = 0; i < 4; i++) { - pwr_diff_limit[i] = (u8)((rtlphy->mcs_offset + pwr_diff_limit[i] = + (u8)((rtlphy->mcs_txpwrlevel_origoffset [chnlgroup][index + (rf ? 8 : 0)] & (0x7f << (i * 8))) >> (i * 8)); if (rtlphy->current_chan_bw == @@ -315,7 +316,8 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, break; default: chnlgroup = 0; - writeval = rtlphy->mcs_offset[chnlgroup][index + + writeval = rtlphy->mcs_txpwrlevel_origoffset + [chnlgroup][index + (rf ? 8 : 0)] + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192de/sw.c index e17f670d5c8e..480862c07f92 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192de/sw.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192de/sw.c @@ -378,7 +378,14 @@ MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n"); MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); -static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume); +static const struct dev_pm_ops rtlwifi_pm_ops = { + .suspend = rtl_pci_suspend, + .resume = rtl_pci_resume, + .freeze = rtl_pci_suspend, + .thaw = rtl_pci_resume, + .poweroff = rtl_pci_suspend, + .restore = rtl_pci_resume, +}; static struct pci_driver rtl92de_driver = { .name = KBUILD_MODNAME, diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192de/trx.c index f9f3861046c1..3baaf21abed4 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192de/trx.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192de/trx.c @@ -132,8 +132,8 @@ static void _rtl92de_query_rxphystatus(struct ieee80211_hw *hw, pstats->packet_toself = packet_toself; pstats->packet_beacon = packet_beacon; pstats->is_cck = is_cck_rate; - pstats->rx_mimo_sig_qual[0] = -1; - pstats->rx_mimo_sig_qual[1] = -1; + pstats->rx_mimo_signalquality[0] = -1; + pstats->rx_mimo_signalquality[1] = -1; if (is_cck_rate) { u8 report, cck_highpwr; @@ -212,8 +212,8 @@ static void _rtl92de_query_rxphystatus(struct ieee80211_hw *hw, sq = ((64 - sq) * 100) / 44; } pstats->signalquality = sq; - pstats->rx_mimo_sig_qual[0] = sq; - pstats->rx_mimo_sig_qual[1] = -1; + pstats->rx_mimo_signalquality[0] = sq; + pstats->rx_mimo_signalquality[1] = -1; } } else { rtlpriv->dm.rfpath_rxenable[0] = true; @@ -246,7 +246,7 @@ static void _rtl92de_query_rxphystatus(struct ieee80211_hw *hw, if (i == 0) pstats->signalquality = (u8)(evm & 0xff); - pstats->rx_mimo_sig_qual[i] = + pstats->rx_mimo_signalquality[i] = (u8)(evm & 0xff); } } @@ -345,28 +345,33 @@ static void _rtl92de_process_pwdb(struct ieee80211_hw *hw, { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - long undec_sm_pwdb; + long undecorated_smoothed_pwdb; if (mac->opmode == NL80211_IFTYPE_ADHOC || mac->opmode == NL80211_IFTYPE_AP) return; else - undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.undecorated_smoothed_pwdb; if (pstats->packet_toself || pstats->packet_beacon) { - if (undec_sm_pwdb < 0) - undec_sm_pwdb = pstats->rx_pwdb_all; - if (pstats->rx_pwdb_all > (u32) undec_sm_pwdb) { - undec_sm_pwdb = (((undec_sm_pwdb) * + if (undecorated_smoothed_pwdb < 0) + undecorated_smoothed_pwdb = pstats->rx_pwdb_all; + if (pstats->rx_pwdb_all > (u32) undecorated_smoothed_pwdb) { + undecorated_smoothed_pwdb = + (((undecorated_smoothed_pwdb) * (RX_SMOOTH_FACTOR - 1)) + (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); - undec_sm_pwdb = undec_sm_pwdb + 1; + undecorated_smoothed_pwdb = + undecorated_smoothed_pwdb + 1; } else { - undec_sm_pwdb = (((undec_sm_pwdb) * + undecorated_smoothed_pwdb = + (((undecorated_smoothed_pwdb) * (RX_SMOOTH_FACTOR - 1)) + (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); } - rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb; + rtlpriv->dm.undecorated_smoothed_pwdb = + undecorated_smoothed_pwdb; _rtl92de_update_rxsignalstatistics(hw, pstats); } } @@ -378,15 +383,15 @@ static void rtl92d_loop_over_streams(struct ieee80211_hw *hw, int stream; for (stream = 0; stream < 2; stream++) { - if (pstats->rx_mimo_sig_qual[stream] != -1) { + if (pstats->rx_mimo_signalquality[stream] != -1) { if (rtlpriv->stats.rx_evm_percentage[stream] == 0) { rtlpriv->stats.rx_evm_percentage[stream] = - pstats->rx_mimo_sig_qual[stream]; + pstats->rx_mimo_signalquality[stream]; } rtlpriv->stats.rx_evm_percentage[stream] = ((rtlpriv->stats.rx_evm_percentage[stream] * (RX_SMOOTH_FACTOR - 1)) + - (pstats->rx_mimo_sig_qual[stream] * 1)) / + (pstats->rx_mimo_signalquality[stream] * 1)) / (RX_SMOOTH_FACTOR); } } diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/def.h b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/def.h index 2d255e02d795..20afec62ce05 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/def.h +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/def.h @@ -522,7 +522,8 @@ enum fwcmd_iotype { FW_CMD_IQK_ENABLE = 30, }; -/* Driver info contain PHY status +/* + * Driver info contain PHY status * and other variabel size info * PHY Status content as below */ diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/dm.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/dm.c index e551fe5f9ccd..465f58157101 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/dm.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/dm.c @@ -267,12 +267,13 @@ static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw) break; } - if (rtlpriv->dm.undec_sm_pwdb > (long)high_rssi_thresh) { + if (rtlpriv->dm.undecorated_smoothed_pwdb > + (long)high_rssi_thresh) { ra->ratr_state = DM_RATR_STA_HIGH; - } else if (rtlpriv->dm.undec_sm_pwdb > + } else if (rtlpriv->dm.undecorated_smoothed_pwdb > (long)middle_rssi_thresh) { ra->ratr_state = DM_RATR_STA_LOW; - } else if (rtlpriv->dm.undec_sm_pwdb > + } else if (rtlpriv->dm.undecorated_smoothed_pwdb > (long)low_rssi_thresh) { ra->ratr_state = DM_RATR_STA_LOW; } else { @@ -282,7 +283,8 @@ static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw) if (ra->pre_ratr_state != ra->ratr_state) { RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, "RSSI = %ld RSSI_LEVEL = %d PreState = %d, CurState = %d\n", - rtlpriv->dm.undec_sm_pwdb, ra->ratr_state, + rtlpriv->dm.undecorated_smoothed_pwdb, + ra->ratr_state, ra->pre_ratr_state, ra->ratr_state); rtlpriv->cfg->ops->update_rate_tbl(hw, sta, @@ -314,7 +316,7 @@ static void _rtl92s_dm_switch_baseband_mrc(struct ieee80211_hw *hw) rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_MRC, (u8 *)(¤t_mrc)); if (mac->link_state >= MAC80211_LINKED) { - if (rtlpriv->dm.undec_sm_pwdb > tmpentry_maxpwdb) { + if (rtlpriv->dm.undecorated_smoothed_pwdb > tmpentry_maxpwdb) { rssi_a = rtlpriv->stats.rx_rssi_percentage[RF90_PATH_A]; rssi_b = rtlpriv->stats.rx_rssi_percentage[RF90_PATH_B]; } @@ -422,18 +424,18 @@ static void rtl92s_backoff_enable_flag(struct ieee80211_hw *hw) struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); if (falsealm_cnt->cnt_all > digtable->fa_highthresh) { - if ((digtable->back_val - 6) < + if ((digtable->backoff_val - 6) < digtable->backoffval_range_min) - digtable->back_val = digtable->backoffval_range_min; + digtable->backoff_val = digtable->backoffval_range_min; else - digtable->back_val -= 6; + digtable->backoff_val -= 6; } else if (falsealm_cnt->cnt_all < digtable->fa_lowthresh) { - if ((digtable->back_val + 6) > + if ((digtable->backoff_val + 6) > digtable->backoffval_range_max) - digtable->back_val = + digtable->backoff_val = digtable->backoffval_range_max; else - digtable->back_val += 6; + digtable->backoff_val += 6; } } @@ -445,28 +447,28 @@ static void _rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw *hw) static u8 initialized, force_write; u8 initial_gain = 0; - if ((digtable->pre_sta_cstate == digtable->cur_sta_cstate) || - (digtable->cur_sta_cstate == DIG_STA_BEFORE_CONNECT)) { - if (digtable->cur_sta_cstate == DIG_STA_BEFORE_CONNECT) { + if ((digtable->pre_sta_connectstate == digtable->cur_sta_connectstate) || + (digtable->cur_sta_connectstate == DIG_STA_BEFORE_CONNECT)) { + if (digtable->cur_sta_connectstate == DIG_STA_BEFORE_CONNECT) { if (rtlpriv->psc.rfpwr_state != ERFON) return; if (digtable->backoff_enable_flag) rtl92s_backoff_enable_flag(hw); else - digtable->back_val = DM_DIG_BACKOFF; + digtable->backoff_val = DM_DIG_BACKOFF; - if ((digtable->rssi_val + 10 - digtable->back_val) > + if ((digtable->rssi_val + 10 - digtable->backoff_val) > digtable->rx_gain_range_max) digtable->cur_igvalue = digtable->rx_gain_range_max; - else if ((digtable->rssi_val + 10 - digtable->back_val) + else if ((digtable->rssi_val + 10 - digtable->backoff_val) < digtable->rx_gain_range_min) digtable->cur_igvalue = digtable->rx_gain_range_min; else - digtable->cur_igvalue = digtable->rssi_val + 10 - - digtable->back_val; + digtable->cur_igvalue = digtable->rssi_val + 10 - + digtable->backoff_val; if (falsealm_cnt->cnt_all > 10000) digtable->cur_igvalue = @@ -488,7 +490,7 @@ static void _rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw *hw) digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_ENABLE); - digtable->back_val = DM_DIG_BACKOFF; + digtable->backoff_val = DM_DIG_BACKOFF; digtable->cur_igvalue = rtlpriv->phy.default_initialgain[0]; digtable->pre_igvalue = 0; return; @@ -518,7 +520,7 @@ static void _rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw *hw) static void _rtl92s_dm_ctrl_initgain_bytwoport(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); - struct dig_t *dig = &rtlpriv->dm_digtable; + struct dig_t *digtable = &rtlpriv->dm_digtable; if (rtlpriv->mac80211.act_scanning) return; @@ -526,17 +528,17 @@ static void _rtl92s_dm_ctrl_initgain_bytwoport(struct ieee80211_hw *hw) /* Decide the current status and if modify initial gain or not */ if (rtlpriv->mac80211.link_state >= MAC80211_LINKED || rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC) - dig->cur_sta_cstate = DIG_STA_CONNECT; + digtable->cur_sta_connectstate = DIG_STA_CONNECT; else - dig->cur_sta_cstate = DIG_STA_DISCONNECT; + digtable->cur_sta_connectstate = DIG_STA_DISCONNECT; - dig->rssi_val = rtlpriv->dm.undec_sm_pwdb; + digtable->rssi_val = rtlpriv->dm.undecorated_smoothed_pwdb; /* Change dig mode to rssi */ - if (dig->cur_sta_cstate != DIG_STA_DISCONNECT) { - if (dig->dig_twoport_algorithm == + if (digtable->cur_sta_connectstate != DIG_STA_DISCONNECT) { + if (digtable->dig_twoport_algorithm == DIG_TWO_PORT_ALGO_FALSE_ALARM) { - dig->dig_twoport_algorithm = DIG_TWO_PORT_ALGO_RSSI; + digtable->dig_twoport_algorithm = DIG_TWO_PORT_ALGO_RSSI; rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_MODE_SS); } } @@ -544,7 +546,7 @@ static void _rtl92s_dm_ctrl_initgain_bytwoport(struct ieee80211_hw *hw) _rtl92s_dm_false_alarm_counter_statistics(hw); _rtl92s_dm_initial_gain_sta_beforeconnect(hw); - dig->pre_sta_cstate = dig->cur_sta_cstate; + digtable->pre_sta_connectstate = digtable->cur_sta_connectstate; } static void _rtl92s_dm_ctrl_initgain_byrssi(struct ieee80211_hw *hw) @@ -571,7 +573,7 @@ static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_phy *rtlphy = &(rtlpriv->phy); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - long undec_sm_pwdb; + long undecorated_smoothed_pwdb; long txpwr_threshold_lv1, txpwr_threshold_lv2; /* 2T2R TP issue */ @@ -585,7 +587,7 @@ static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw) } if ((mac->link_state < MAC80211_LINKED) && - (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { + (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, "Not connected to any\n"); @@ -597,22 +599,25 @@ static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw) if (mac->link_state >= MAC80211_LINKED) { if (mac->opmode == NL80211_IFTYPE_ADHOC) { - undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "AP Client PWDB = 0x%lx\n", - undec_sm_pwdb); + undecorated_smoothed_pwdb); } else { - undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "STA Default Port PWDB = 0x%lx\n", - undec_sm_pwdb); + undecorated_smoothed_pwdb); } } else { - undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; + undecorated_smoothed_pwdb = + rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "AP Ext Port PWDB = 0x%lx\n", - undec_sm_pwdb); + undecorated_smoothed_pwdb); } txpwr_threshold_lv2 = TX_POWER_NEAR_FIELD_THRESH_LVL2; @@ -620,12 +625,12 @@ static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw) if (rtl_get_bbreg(hw, 0xc90, MASKBYTE0) == 1) rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL; - else if (undec_sm_pwdb >= txpwr_threshold_lv2) + else if (undecorated_smoothed_pwdb >= txpwr_threshold_lv2) rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL2; - else if ((undec_sm_pwdb < (txpwr_threshold_lv2 - 3)) && - (undec_sm_pwdb >= txpwr_threshold_lv1)) + else if ((undecorated_smoothed_pwdb < (txpwr_threshold_lv2 - 3)) && + (undecorated_smoothed_pwdb >= txpwr_threshold_lv1)) rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL1; - else if (undec_sm_pwdb < (txpwr_threshold_lv1 - 3)) + else if (undecorated_smoothed_pwdb < (txpwr_threshold_lv1 - 3)) rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL; if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) @@ -660,10 +665,10 @@ static void _rtl92s_dm_init_dig(struct ieee80211_hw *hw) digtable->dig_state = DM_STA_DIG_MAX; digtable->dig_highpwrstate = DM_STA_DIG_MAX; - digtable->cur_sta_cstate = DIG_STA_DISCONNECT; - digtable->pre_sta_cstate = DIG_STA_DISCONNECT; - digtable->cur_ap_cstate = DIG_AP_DISCONNECT; - digtable->pre_ap_cstate = DIG_AP_DISCONNECT; + digtable->cur_sta_connectstate = DIG_STA_DISCONNECT; + digtable->pre_sta_connectstate = DIG_STA_DISCONNECT; + digtable->cur_ap_connectstate = DIG_AP_DISCONNECT; + digtable->pre_ap_connectstate = DIG_AP_DISCONNECT; digtable->rssi_lowthresh = DM_DIG_THRESH_LOW; digtable->rssi_highthresh = DM_DIG_THRESH_HIGH; @@ -676,7 +681,7 @@ static void _rtl92s_dm_init_dig(struct ieee80211_hw *hw) /* for dig debug rssi value */ digtable->rssi_val = 50; - digtable->back_val = DM_DIG_BACKOFF; + digtable->backoff_val = DM_DIG_BACKOFF; digtable->rx_gain_range_max = DM_DIG_MAX; digtable->rx_gain_range_min = DM_DIG_MIN; @@ -704,7 +709,7 @@ void rtl92s_dm_init(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; - rtlpriv->dm.undec_sm_pwdb = -1; + rtlpriv->dm.undecorated_smoothed_pwdb = -1; _rtl92s_dm_init_dynamic_txpower(hw); rtl92s_dm_init_edca_turbo(hw); diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index 28526a7361f5..4542e6952b97 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/hw.c @@ -1089,9 +1089,8 @@ int rtl92se_hw_init(struct ieee80211_hw *hw) return err; } -void rtl92se_set_mac_addr(struct rtl_io *io, const u8 *addr) +void rtl92se_set_mac_addr(struct rtl_io *io, const u8 * addr) { - /* This is a stub. */ } void rtl92se_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) @@ -1698,7 +1697,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) hwinfo[EEPROM_TXPOWERBASE + 6 + rf_path * 3 + i]; /* Read OFDM RF A & B Tx power for 2T */ - rtlefuse->eprom_chnl_txpwr_ht40_2sdf[rf_path][i] + rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][i] = hwinfo[EEPROM_TXPOWERBASE + 12 + rf_path * 3 + i]; } @@ -1723,7 +1722,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", rf_path, i, - rtlefuse->eprom_chnl_txpwr_ht40_2sdf + rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif [rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) { @@ -1749,7 +1748,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) rtlefuse->eeprom_chnlarea_txpwr_ht40_1s [rf_path][index]; rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = - rtlefuse->eprom_chnl_txpwr_ht40_2sdf + rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif [rf_path][index]; } diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/hw.h b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/hw.h index a8e068c76e47..1886c2644a26 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/hw.h +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/hw.h @@ -54,7 +54,7 @@ void rtl92se_disable_interrupt(struct ieee80211_hw *hw); int rtl92se_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type); void rtl92se_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid); -void rtl92se_set_mac_addr(struct rtl_io *io, const u8 *addr); +void rtl92se_set_mac_addr(struct rtl_io *io, const u8 * addr); void rtl92se_set_qos(struct ieee80211_hw *hw, int aci); void rtl92se_set_beacon_related_registers(struct ieee80211_hw *hw); void rtl92se_set_beacon_interval(struct ieee80211_hw *hw); diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/phy.c index 67404975e00b..b917a2a3caf7 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/phy.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/phy.c @@ -139,17 +139,17 @@ static u32 _rtl92s_phy_rf_serial_read(struct ieee80211_hw *hw, BIT(8)); if (rfpi_enable) - retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi, + retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi, BLSSI_READBACK_DATA); else - retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb, + retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, BLSSI_READBACK_DATA); - retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb, + retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, BLSSI_READBACK_DATA); RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n", - rfpath, pphyreg->rf_rb, retvalue); + rfpath, pphyreg->rflssi_readback, retvalue); return retvalue; @@ -696,7 +696,7 @@ static void _rtl92s_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw, else return; - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index] = data; + rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][index] = data; if (index == 5) rtlphy->pwrgroup_cnt++; } @@ -765,10 +765,14 @@ static void _rtl92s_phy_init_register_definition(struct ieee80211_hw *hw) rtlphy->phyreg_def[RF90_PATH_D].rfhssi_para2 = RFPGA0_XD_HSSIPARAMETER2; /* RF switch Control */ - rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; - rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; - rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; - rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control = + RFPGA0_XAB_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control = + RFPGA0_XAB_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control = + RFPGA0_XCD_SWITCHCONTROL; + rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control = + RFPGA0_XCD_SWITCHCONTROL; /* AGC control 1 */ rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; @@ -783,10 +787,14 @@ static void _rtl92s_phy_init_register_definition(struct ieee80211_hw *hw) rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; /* RX AFE control 1 */ - rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance = + ROFDM0_XARXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance = + ROFDM0_XBRXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance = + ROFDM0_XCRXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance = + ROFDM0_XDRXIQIMBALANCE; /* RX AFE control 1 */ rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; @@ -795,10 +803,14 @@ static void _rtl92s_phy_init_register_definition(struct ieee80211_hw *hw) rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; /* Tx AFE control 1 */ - rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance = + ROFDM0_XATXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance = + ROFDM0_XBTXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance = + ROFDM0_XCTXIQIMBALANCE; + rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance = + ROFDM0_XDTXIQIMBALANCE; /* Tx AFE control 2 */ rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; @@ -807,14 +819,20 @@ static void _rtl92s_phy_init_register_definition(struct ieee80211_hw *hw) rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE; /* Tranceiver LSSI Readback */ - rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback = + RFPGA0_XA_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback = + RFPGA0_XB_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback = + RFPGA0_XC_LSSIREADBACK; + rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback = + RFPGA0_XD_LSSIREADBACK; /* Tranceiver LSSI Readback PI mode */ - rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVERA_HSPI_READBACK; - rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVERB_HSPI_READBACK; + rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi = + TRANSCEIVERA_HSPI_READBACK; + rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi = + TRANSCEIVERB_HSPI_READBACK; } diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/rf.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/rf.c index 5061f1db3f02..08c2f5625129 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/rf.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/rf.c @@ -192,7 +192,8 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, * defined by Realtek for large power */ chnlgroup = 0; - writeval = rtlphy->mcs_offset[chnlgroup][index] + + writeval = rtlphy->mcs_txpwrlevel_origoffset + [chnlgroup][index] + ((index < 2) ? pwrbase0 : pwrbase1); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, @@ -222,7 +223,8 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, chnlgroup++; } - writeval = rtlphy->mcs_offset[chnlgroup][index] + writeval = rtlphy->mcs_txpwrlevel_origoffset + [chnlgroup][index] + ((index < 2) ? pwrbase0 : pwrbase1); @@ -255,7 +257,8 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, } for (i = 0; i < 4; i++) { - pwrdiff_limit[i] = (u8)((rtlphy->mcs_offset + pwrdiff_limit[i] = + (u8)((rtlphy->mcs_txpwrlevel_origoffset [chnlgroup][index] & (0x7f << (i * 8))) >> (i * 8)); @@ -293,7 +296,7 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, break; default: chnlgroup = 0; - writeval = rtlphy->mcs_offset[chnlgroup][index] + + writeval = rtlphy->mcs_txpwrlevel_origoffset[chnlgroup][index] + ((index < 2) ? pwrbase0 : pwrbase1); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "RTK better performance, writeval = 0x%x\n", writeval); diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/sw.c index 45c3443fccc8..ad4b4803482d 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/sw.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/sw.c @@ -50,7 +50,8 @@ static void rtl92s_init_aspm_vars(struct ieee80211_hw *hw) /*close ASPM for AMD defaultly */ rtlpci->const_amdpci_aspm = 0; - /* ASPM PS mode. + /* + * ASPM PS mode. * 0 - Disable ASPM, * 1 - Enable ASPM without Clock Req, * 2 - Enable ASPM with Clock Req, @@ -66,7 +67,8 @@ static void rtl92s_init_aspm_vars(struct ieee80211_hw *hw) /*Setting for PCI-E bridge */ rtlpci->const_hostpci_aspm_setting = 0x02; - /* In Hw/Sw Radio Off situation. + /* + * In Hw/Sw Radio Off situation. * 0 - Default, * 1 - From ASPM setting without low Mac Pwr, * 2 - From ASPM setting with low Mac Pwr, @@ -75,7 +77,8 @@ static void rtl92s_init_aspm_vars(struct ieee80211_hw *hw) */ rtlpci->const_hwsw_rfoff_d3 = 2; - /* This setting works for those device with + /* + * This setting works for those device with * backdoor ASPM setting such as EPHY setting. * 0 - Not support ASPM, * 1 - Support ASPM, @@ -429,7 +432,14 @@ MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n"); MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); -static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume); +static const struct dev_pm_ops rtlwifi_pm_ops = { + .suspend = rtl_pci_suspend, + .resume = rtl_pci_resume, + .freeze = rtl_pci_suspend, + .thaw = rtl_pci_resume, + .poweroff = rtl_pci_suspend, + .restore = rtl_pci_resume, +}; static struct pci_driver rtl92se_driver = { .name = KBUILD_MODNAME, diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/trx.c index 0e9f6ebf078a..26d027cb5069 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/trx.c @@ -129,8 +129,8 @@ static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw, pstats->packet_matchbssid = packet_match_bssid; pstats->packet_toself = packet_toself; pstats->packet_beacon = packet_beacon; - pstats->rx_mimo_sig_qual[0] = -1; - pstats->rx_mimo_sig_qual[1] = -1; + pstats->rx_mimo_signalquality[0] = -1; + pstats->rx_mimo_signalquality[1] = -1; if (is_cck) { u8 report, cck_highpwr; @@ -216,8 +216,8 @@ static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw, } pstats->signalquality = sq; - pstats->rx_mimo_sig_qual[0] = sq; - pstats->rx_mimo_sig_qual[1] = -1; + pstats->rx_mimo_signalquality[0] = sq; + pstats->rx_mimo_signalquality[1] = -1; } } else { rtlpriv->dm.rfpath_rxenable[0] = @@ -256,7 +256,8 @@ static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw, if (i == 0) pstats->signalquality = (u8)(evm & 0xff); - pstats->rx_mimo_sig_qual[i] = (u8) (evm & 0xff); + pstats->rx_mimo_signalquality[i] = + (u8) (evm & 0xff); } } } @@ -365,7 +366,7 @@ static void _rtl92se_process_pwdb(struct ieee80211_hw *hw, return; } else { undec_sm_pwdb = - rtlpriv->dm.undec_sm_pwdb; + rtlpriv->dm.undecorated_smoothed_pwdb; } if (pstats->packet_toself || pstats->packet_beacon) { @@ -385,7 +386,7 @@ static void _rtl92se_process_pwdb(struct ieee80211_hw *hw, (RX_SMOOTH_FACTOR); } - rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb; + rtlpriv->dm.undecorated_smoothed_pwdb = undec_sm_pwdb; _rtl92se_update_rxsignalstatistics(hw, pstats); } } @@ -397,16 +398,16 @@ static void rtl_92s_process_streams(struct ieee80211_hw *hw, u32 stream; for (stream = 0; stream < 2; stream++) { - if (pstats->rx_mimo_sig_qual[stream] != -1) { + if (pstats->rx_mimo_signalquality[stream] != -1) { if (rtlpriv->stats.rx_evm_percentage[stream] == 0) { rtlpriv->stats.rx_evm_percentage[stream] = - pstats->rx_mimo_sig_qual[stream]; + pstats->rx_mimo_signalquality[stream]; } rtlpriv->stats.rx_evm_percentage[stream] = ((rtlpriv->stats.rx_evm_percentage[stream] * (RX_SMOOTH_FACTOR - 1)) + - (pstats->rx_mimo_sig_qual[stream] * + (pstats->rx_mimo_signalquality[stream] * 1)) / (RX_SMOOTH_FACTOR); } } diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/Makefile b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/Makefile deleted file mode 100644 index 4ed731f09b1f..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -obj-m := rtl8723ae.o - - -rtl8723ae-objs := \ - dm.o \ - fw.o \ - hal_btc.o \ - hal_bt_coexist.o\ - hw.o \ - led.o \ - phy.o \ - pwrseq.o \ - pwrseqcmd.o \ - rf.o \ - sw.o \ - table.o \ - trx.o \ - - -obj-$(CONFIG_RTL8723AE) += rtl8723ae.o - -ccflags-y += -D__CHECK_ENDIAN__ diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/btc.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/btc.h deleted file mode 100644 index 417afeed36af..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/btc.h +++ /dev/null @@ -1,41 +0,0 @@ -/****************************************************************************** - ** - ** Copyright(c) 2009-2012 Realtek Corporation. - ** - ** This program is free software; you can redistribute it and/or modify it - ** under the terms of version 2 of the GNU General Public License as - ** published by the Free Software Foundation. - ** - ** This program is distributed in the hope that it will be useful, but WITHOUT - ** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - ** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - ** more details. - ** - ** You should have received a copy of the GNU General Public License along with - ** this program; if not, write to the Free Software Foundation, Inc., - ** 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - ** - ** The full GNU General Public License is included in this distribution in the - ** file called LICENSE. - ** - ** Contact Information: - ** wlanfae - ** Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - ** Hsinchu 300, Taiwan. - ** Larry Finger - ** - ***************************************************************************** - */ - -#ifndef __RTL8723E_BTC_H__ -#define __RTL8723E_BTC_H__ - -#include "../wifi.h" -#include "hal_bt_coexist.h" - -struct bt_coexist_c2h_info { - u8 no_parse_c2h; - u8 has_c2h; -}; - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/def.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/def.h deleted file mode 100644 index 8c110356dff9..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/def.h +++ /dev/null @@ -1,163 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - **************************************************************************** - */ - -#ifndef __RTL8723E_DEF_H__ -#define __RTL8723E_DEF_H__ - -#define HAL_PRIME_CHNL_OFFSET_LOWER 1 - -#define RX_MPDU_QUEUE 0 - -#define CHIP_8723 BIT(0) -#define NORMAL_CHIP BIT(3) -#define RF_TYPE_1T2R BIT(4) -#define RF_TYPE_2T2R BIT(5) -#define CHIP_VENDOR_UMC BIT(7) -#define B_CUT_VERSION BIT(12) -#define C_CUT_VERSION BIT(13) -#define D_CUT_VERSION ((BIT(12)|BIT(13))) -#define E_CUT_VERSION BIT(14) -#define RF_RL_ID (BIT(31)|BIT(30)|BIT(29)|BIT(28)) - -enum version_8723e { - VERSION_TEST_UMC_CHIP_8723 = 0x0081, - VERSION_NORMAL_UMC_CHIP_8723_1T1R_A_CUT = 0x0089, - VERSION_NORMAL_UMC_CHIP_8723_1T1R_B_CUT = 0x1089, -}; - -/* MASK */ -#define IC_TYPE_MASK (BIT(0)|BIT(1)|BIT(2)) -#define CHIP_TYPE_MASK BIT(3) -#define RF_TYPE_MASK (BIT(4)|BIT(5)|BIT(6)) -#define MANUFACTUER_MASK BIT(7) -#define ROM_VERSION_MASK (BIT(11)|BIT(10)|BIT(9)|BIT(8)) -#define CUT_VERSION_MASK (BIT(15)|BIT(14)|BIT(13)|BIT(12)) - -/* Get element */ -#define GET_CVID_IC_TYPE(version) ((version) & IC_TYPE_MASK) -#define GET_CVID_MANUFACTUER(version) ((version) & MANUFACTUER_MASK) -#define GET_CVID_CUT_VERSION(version) ((version) & CUT_VERSION_MASK) - -#define IS_81XXC(version) ((GET_CVID_IC_TYPE(version) == 0) ?\ - true : false) -#define IS_8723_SERIES(version) \ - ((GET_CVID_IC_TYPE(version) == CHIP_8723) ? true : false) -#define IS_CHIP_VENDOR_UMC(version) \ - ((GET_CVID_MANUFACTUER(version)) ? true : false) - -#define IS_VENDOR_UMC_A_CUT(version) ((IS_CHIP_VENDOR_UMC(version)) ? \ - ((GET_CVID_CUT_VERSION(version)) ? false : true) : false) -#define IS_VENDOR_8723_A_CUT(version) ((IS_8723_SERIES(version)) ? \ - ((GET_CVID_CUT_VERSION(version)) ? false : true) : false) -#define IS_81xxC_VENDOR_UMC_B_CUT(version) ((IS_CHIP_VENDOR_UMC(version)) \ - ? ((GET_CVID_CUT_VERSION(version) == B_CUT_VERSION) ? \ - true : false) : false) - -enum rf_optype { - RF_OP_BY_SW_3WIRE = 0, - RF_OP_BY_FW, - RF_OP_MAX -}; - -enum rf_power_state { - RF_ON, - RF_OFF, - RF_SLEEP, - RF_SHUT_DOWN, -}; - -enum power_save_mode { - POWER_SAVE_MODE_ACTIVE, - POWER_SAVE_MODE_SAVE, -}; - -enum power_polocy_config { - POWERCFG_MAX_POWER_SAVINGS, - POWERCFG_GLOBAL_POWER_SAVINGS, - POWERCFG_LOCAL_POWER_SAVINGS, - POWERCFG_LENOVO, -}; - -enum interface_select_pci { - INTF_SEL1_MINICARD = 0, - INTF_SEL0_PCIE = 1, - INTF_SEL2_RSV = 2, - INTF_SEL3_RSV = 3, -}; - -enum hal_fw_c2h_cmd_id { - HAL_FW_C2H_CMD_Read_MACREG = 0, - HAL_FW_C2H_CMD_Read_BBREG = 1, - HAL_FW_C2H_CMD_Read_RFREG = 2, - HAL_FW_C2H_CMD_Read_EEPROM = 3, - HAL_FW_C2H_CMD_Read_EFUSE = 4, - HAL_FW_C2H_CMD_Read_CAM = 5, - HAL_FW_C2H_CMD_Get_BasicRate = 6, - HAL_FW_C2H_CMD_Get_DataRate = 7, - HAL_FW_C2H_CMD_Survey = 8, - HAL_FW_C2H_CMD_SurveyDone = 9, - HAL_FW_C2H_CMD_JoinBss = 10, - HAL_FW_C2H_CMD_AddSTA = 11, - HAL_FW_C2H_CMD_DelSTA = 12, - HAL_FW_C2H_CMD_AtimDone = 13, - HAL_FW_C2H_CMD_TX_Report = 14, - HAL_FW_C2H_CMD_CCX_Report = 15, - HAL_FW_C2H_CMD_DTM_Report = 16, - HAL_FW_C2H_CMD_TX_Rate_Statistics = 17, - HAL_FW_C2H_CMD_C2HLBK = 18, - HAL_FW_C2H_CMD_C2HDBG = 19, - HAL_FW_C2H_CMD_C2HFEEDBACK = 20, - HAL_FW_C2H_CMD_MAX -}; - -enum rtl_desc_qsel { - QSLT_BK = 0x2, - QSLT_BE = 0x0, - QSLT_VI = 0x5, - QSLT_VO = 0x7, - QSLT_BEACON = 0x10, - QSLT_HIGH = 0x11, - QSLT_MGNT = 0x12, - QSLT_CMD = 0x13, -}; - -struct phy_sts_cck_8723e_t { - u8 adc_pwdb_X[4]; - u8 sq_rpt; - u8 cck_agc_rpt; -}; - -struct h2c_cmd_8723e { - u8 element_id; - u32 cmd_len; - u8 *p_cmdbuffer; -}; - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c deleted file mode 100644 index 12e2a3cb0701..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/dm.c +++ /dev/null @@ -1,920 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - **************************************************************************** - */ - -#include "../wifi.h" -#include "../base.h" -#include "../pci.h" -#include "reg.h" -#include "def.h" -#include "phy.h" -#include "dm.h" -#include "fw.h" -#include "hal_btc.h" - -static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = { - 0x7f8001fe, - 0x788001e2, - 0x71c001c7, - 0x6b8001ae, - 0x65400195, - 0x5fc0017f, - 0x5a400169, - 0x55400155, - 0x50800142, - 0x4c000130, - 0x47c0011f, - 0x43c0010f, - 0x40000100, - 0x3c8000f2, - 0x390000e4, - 0x35c000d7, - 0x32c000cb, - 0x300000c0, - 0x2d4000b5, - 0x2ac000ab, - 0x288000a2, - 0x26000098, - 0x24000090, - 0x22000088, - 0x20000080, - 0x1e400079, - 0x1c800072, - 0x1b00006c, - 0x19800066, - 0x18000060, - 0x16c0005b, - 0x15800056, - 0x14400051, - 0x1300004c, - 0x12000048, - 0x11000044, - 0x10000040, -}; - -static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = { - {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, - {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, - {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, - {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, - {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, - {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, - {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, - {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, - {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, - {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, - {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, - {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, - {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, - {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, - {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, - {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, - {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, - {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, - {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, - {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, - {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, - {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, - {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, - {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, - {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, - {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, - {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, - {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, - {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, - {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, - {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, - {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, - {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01} -}; - -static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = { - {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, - {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, - {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, - {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, - {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, - {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, - {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, - {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, - {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, - {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, - {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, - {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, - {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, - {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, - {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, - {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, - {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, - {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, - {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, - {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, - {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, - {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, - {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, - {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, - {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, - {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, - {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, - {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, - {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, - {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, - {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, - {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, - {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00} -}; - -static void rtl8723ae_dm_diginit(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct dig_t *dm_digtable = &rtlpriv->dm_digtable; - - dm_digtable->dig_enable_flag = true; - dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; - dm_digtable->cur_igvalue = 0x20; - dm_digtable->pre_igvalue = 0x0; - dm_digtable->cursta_cstate = DIG_STA_DISCONNECT; - dm_digtable->presta_cstate = DIG_STA_DISCONNECT; - dm_digtable->curmultista_cstate = DIG_MULTISTA_DISCONNECT; - dm_digtable->rssi_lowthresh = DM_DIG_THRESH_LOW; - dm_digtable->rssi_highthresh = DM_DIG_THRESH_HIGH; - dm_digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW; - dm_digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH; - dm_digtable->rx_gain_range_max = DM_DIG_MAX; - dm_digtable->rx_gain_range_min = DM_DIG_MIN; - dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT; - dm_digtable->back_range_max = DM_DIG_BACKOFF_MAX; - dm_digtable->back_range_min = DM_DIG_BACKOFF_MIN; - dm_digtable->pre_cck_pd_state = CCK_PD_STAGE_MAX; - dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX; -} - -static u8 rtl_init_gain_min_pwdb(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct dig_t *dm_digtable = &rtlpriv->dm_digtable; - long rssi_val_min = 0; - - if ((dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) && - (dm_digtable->cursta_cstate == DIG_STA_CONNECT)) { - if (rtlpriv->dm.entry_min_undec_sm_pwdb != 0) - rssi_val_min = - (rtlpriv->dm.entry_min_undec_sm_pwdb > - rtlpriv->dm.undec_sm_pwdb) ? - rtlpriv->dm.undec_sm_pwdb : - rtlpriv->dm.entry_min_undec_sm_pwdb; - else - rssi_val_min = rtlpriv->dm.undec_sm_pwdb; - } else if (dm_digtable->cursta_cstate == DIG_STA_CONNECT || - dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT) { - rssi_val_min = rtlpriv->dm.undec_sm_pwdb; - } else if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) { - rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb; - } - - return (u8) rssi_val_min; -} - -static void rtl8723ae_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) -{ - u32 ret_value; - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); - - ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD); - falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16); - - ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD); - falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff); - falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16); - - ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD); - falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff); - falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail + - falsealm_cnt->cnt_rate_illegal + - falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail; - - rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1); - ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0); - falsealm_cnt->cnt_cck_fail = ret_value; - - ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3); - falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8; - falsealm_cnt->cnt_all = (falsealm_cnt->cnt_parity_fail + - falsealm_cnt->cnt_rate_illegal + - falsealm_cnt->cnt_crc8_fail + - falsealm_cnt->cnt_mcs_fail + - falsealm_cnt->cnt_cck_fail); - - rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1); - rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0); - rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0); - rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2); - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - "cnt_parity_fail = %d, cnt_rate_illegal = %d, " - "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n", - falsealm_cnt->cnt_parity_fail, - falsealm_cnt->cnt_rate_illegal, - falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail); - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n", - falsealm_cnt->cnt_ofdm_fail, - falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all); -} - -static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct dig_t *dm_digtable = &rtlpriv->dm_digtable; - u8 value_igi = dm_digtable->cur_igvalue; - - if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0) - value_igi--; - else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1) - value_igi += 0; - else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH2) - value_igi++; - else - value_igi += 2; - - value_igi = clamp(value_igi, (u8)DM_DIG_FA_LOWER, (u8)DM_DIG_FA_UPPER); - if (rtlpriv->falsealm_cnt.cnt_all > 10000) - value_igi = 0x32; - - dm_digtable->cur_igvalue = value_igi; - rtl8723ae_dm_write_dig(hw); -} - -static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct dig_t *dgtbl = &rtlpriv->dm_digtable; - - if (rtlpriv->falsealm_cnt.cnt_all > dgtbl->fa_highthresh) { - if ((dgtbl->back_val - 2) < dgtbl->back_range_min) - dgtbl->back_val = dgtbl->back_range_min; - else - dgtbl->back_val -= 2; - } else if (rtlpriv->falsealm_cnt.cnt_all < dgtbl->fa_lowthresh) { - if ((dgtbl->back_val + 2) > dgtbl->back_range_max) - dgtbl->back_val = dgtbl->back_range_max; - else - dgtbl->back_val += 2; - } - - if ((dgtbl->rssi_val_min + 10 - dgtbl->back_val) > - dgtbl->rx_gain_range_max) - dgtbl->cur_igvalue = dgtbl->rx_gain_range_max; - else if ((dgtbl->rssi_val_min + 10 - - dgtbl->back_val) < dgtbl->rx_gain_range_min) - dgtbl->cur_igvalue = dgtbl->rx_gain_range_min; - else - dgtbl->cur_igvalue = dgtbl->rssi_val_min + 10 - dgtbl->back_val; - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - "rssi_val_min = %x back_val %x\n", - dgtbl->rssi_val_min, dgtbl->back_val); - - rtl8723ae_dm_write_dig(hw); -} - -static void rtl8723ae_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct dig_t *dm_digtable = &rtlpriv->dm_digtable; - long rssi_strength = rtlpriv->dm.entry_min_undec_sm_pwdb; - bool multi_sta = false; - - if (mac->opmode == NL80211_IFTYPE_ADHOC) - multi_sta = true; - - if ((!multi_sta) || - (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT)) { - rtlpriv->initialized = false; - dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; - return; - } else if (!rtlpriv->initialized) { - rtlpriv->initialized = true; - dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; - dm_digtable->cur_igvalue = 0x20; - rtl8723ae_dm_write_dig(hw); - } - - if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) { - if ((rssi_strength < dm_digtable->rssi_lowthresh) && - (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) { - - if (dm_digtable->dig_ext_port_stage == - DIG_EXT_PORT_STAGE_2) { - dm_digtable->cur_igvalue = 0x20; - rtl8723ae_dm_write_dig(hw); - } - - dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_1; - } else if (rssi_strength > dm_digtable->rssi_highthresh) { - dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_2; - rtl92c_dm_ctrl_initgain_by_fa(hw); - } - } else if (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_0) { - dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; - dm_digtable->cur_igvalue = 0x20; - rtl8723ae_dm_write_dig(hw); - } - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - "curmultista_cstate = %x dig_ext_port_stage %x\n", - dm_digtable->curmultista_cstate, - dm_digtable->dig_ext_port_stage); -} - -static void rtl8723ae_dm_initial_gain_sta(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct dig_t *dm_digtable = &rtlpriv->dm_digtable; - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - "presta_cstate = %x, cursta_cstate = %x\n", - dm_digtable->presta_cstate, - dm_digtable->cursta_cstate); - - if (dm_digtable->presta_cstate == dm_digtable->cursta_cstate || - dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT || - dm_digtable->cursta_cstate == DIG_STA_CONNECT) { - - if (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) { - dm_digtable->rssi_val_min = rtl_init_gain_min_pwdb(hw); - rtl92c_dm_ctrl_initgain_by_rssi(hw); - } - } else { - dm_digtable->rssi_val_min = 0; - dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; - dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT; - dm_digtable->cur_igvalue = 0x20; - dm_digtable->pre_igvalue = 0; - rtl8723ae_dm_write_dig(hw); - } -} -static void rtl8723ae_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct dig_t *dm_digtable = &rtlpriv->dm_digtable; - - if (dm_digtable->cursta_cstate == DIG_STA_CONNECT) { - dm_digtable->rssi_val_min = rtl_init_gain_min_pwdb(hw); - - if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LowRssi) { - if (dm_digtable->rssi_val_min <= 25) - dm_digtable->cur_cck_pd_state = - CCK_PD_STAGE_LowRssi; - else - dm_digtable->cur_cck_pd_state = - CCK_PD_STAGE_HighRssi; - } else { - if (dm_digtable->rssi_val_min <= 20) - dm_digtable->cur_cck_pd_state = - CCK_PD_STAGE_LowRssi; - else - dm_digtable->cur_cck_pd_state = - CCK_PD_STAGE_HighRssi; - } - } else { - dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX; - } - - if (dm_digtable->pre_cck_pd_state != dm_digtable->cur_cck_pd_state) { - if (dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LowRssi) { - if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800) - dm_digtable->cur_cck_fa_state = - CCK_FA_STAGE_High; - else - dm_digtable->cur_cck_fa_state = - CCK_FA_STAGE_Low; - - if (dm_digtable->pre_cck_fa_state != - dm_digtable->cur_cck_fa_state) { - if (dm_digtable->cur_cck_fa_state == - CCK_FA_STAGE_Low) - rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, - 0x83); - else - rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, - 0xcd); - - dm_digtable->pre_cck_fa_state = - dm_digtable->cur_cck_fa_state; - } - - rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40); - - } else { - rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); - rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47); - - } - dm_digtable->pre_cck_pd_state = dm_digtable->cur_cck_pd_state; - } - - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - "CCKPDStage=%x\n", dm_digtable->cur_cck_pd_state); - -} - -static void rtl8723ae_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) -{ - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct dig_t *dm_digtable = &rtlpriv->dm_digtable; - - if (mac->act_scanning == true) - return; - - if (mac->link_state >= MAC80211_LINKED) - dm_digtable->cursta_cstate = DIG_STA_CONNECT; - else - dm_digtable->cursta_cstate = DIG_STA_DISCONNECT; - - rtl8723ae_dm_initial_gain_sta(hw); - rtl8723ae_dm_initial_gain_multi_sta(hw); - rtl8723ae_dm_cck_packet_detection_thresh(hw); - - dm_digtable->presta_cstate = dm_digtable->cursta_cstate; - -} - -static void rtl8723ae_dm_dig(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct dig_t *dm_digtable = &rtlpriv->dm_digtable; - - if (rtlpriv->dm.dm_initialgain_enable == false) - return; - if (dm_digtable->dig_enable_flag == false) - return; - - rtl8723ae_dm_ctrl_initgain_by_twoport(hw); -} - -static void rtl8723ae_dm_init_dynamic_txpower(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtlpriv->dm.dynamic_txpower_enable = false; - - rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; - rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; -} - -static void rtl8723ae_dm_dynamic_txpower(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - long undec_sm_pwdb; - - if (!rtlpriv->dm.dynamic_txpower_enable) - return; - - if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) { - rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; - return; - } - - if ((mac->link_state < MAC80211_LINKED) && - (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { - RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - "Not connected\n"); - - rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; - - rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; - return; - } - - if (mac->link_state >= MAC80211_LINKED) { - if (mac->opmode == NL80211_IFTYPE_ADHOC) { - undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "AP Client PWDB = 0x%lx\n", - undec_sm_pwdb); - } else { - undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "STA Default Port PWDB = 0x%lx\n", - undec_sm_pwdb); - } - } else { - undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb; - - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "AP Ext Port PWDB = 0x%lx\n", - undec_sm_pwdb); - } - - if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { - rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); - } else if ((undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && - (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL1)) { - rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); - } else if (undec_sm_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { - rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "TXHIGHPWRLEVEL_NORMAL\n"); - } - - if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) { - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "PHY_SetTxPowerLevel8192S() Channel = %d\n", - rtlphy->current_channel); - rtl8723ae_phy_set_txpower_level(hw, rtlphy->current_channel); - } - - rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; -} - -void rtl8723ae_dm_write_dig(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct dig_t *dm_digtable = &rtlpriv->dm_digtable; - - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - "cur_igvalue = 0x%x, " - "pre_igvalue = 0x%x, back_val = %d\n", - dm_digtable->cur_igvalue, dm_digtable->pre_igvalue, - dm_digtable->back_val); - - if (dm_digtable->pre_igvalue != dm_digtable->cur_igvalue) { - rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, - dm_digtable->cur_igvalue); - rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f, - dm_digtable->cur_igvalue); - - dm_digtable->pre_igvalue = dm_digtable->cur_igvalue; - } -} - -static void rtl8723ae_dm_pwdmonitor(struct ieee80211_hw *hw) -{ -} - -void rtl8723ae_dm_init_edca_turbo(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtlpriv->dm.current_turbo_edca = false; - rtlpriv->dm.is_any_nonbepkts = false; - rtlpriv->dm.is_cur_rdlstate = false; -} - -static void rtl8723ae_dm_check_edca_turbo(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - - u64 cur_txok_cnt = 0; - u64 cur_rxok_cnt = 0; - u32 edca_be_ul = 0x5ea42b; - u32 edca_be_dl = 0x5ea42b; - bool bt_change_edca = false; - - if ((mac->last_bt_edca_ul != rtlpcipriv->bt_coexist.bt_edca_ul) || - (mac->last_bt_edca_dl != rtlpcipriv->bt_coexist.bt_edca_dl)) { - rtlpriv->dm.current_turbo_edca = false; - mac->last_bt_edca_ul = rtlpcipriv->bt_coexist.bt_edca_ul; - mac->last_bt_edca_dl = rtlpcipriv->bt_coexist.bt_edca_dl; - } - - if (rtlpcipriv->bt_coexist.bt_edca_ul != 0) { - edca_be_ul = rtlpcipriv->bt_coexist.bt_edca_ul; - bt_change_edca = true; - } - - if (rtlpcipriv->bt_coexist.bt_edca_dl != 0) { - edca_be_ul = rtlpcipriv->bt_coexist.bt_edca_dl; - bt_change_edca = true; - } - - if (mac->link_state != MAC80211_LINKED) { - rtlpriv->dm.current_turbo_edca = false; - return; - } - - if ((!mac->ht_enable) && (!rtlpcipriv->bt_coexist.bt_coexistence)) { - if (!(edca_be_ul & 0xffff0000)) - edca_be_ul |= 0x005e0000; - - if (!(edca_be_dl & 0xffff0000)) - edca_be_dl |= 0x005e0000; - } - - if ((bt_change_edca) || ((!rtlpriv->dm.is_any_nonbepkts) && - (!rtlpriv->dm.disable_framebursting))) { - - cur_txok_cnt = rtlpriv->stats.txbytesunicast - - mac->last_txok_cnt; - cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - - mac->last_rxok_cnt; - - if (cur_rxok_cnt > 4 * cur_txok_cnt) { - if (!rtlpriv->dm.is_cur_rdlstate || - !rtlpriv->dm.current_turbo_edca) { - rtl_write_dword(rtlpriv, - REG_EDCA_BE_PARAM, - edca_be_dl); - rtlpriv->dm.is_cur_rdlstate = true; - } - } else { - if (rtlpriv->dm.is_cur_rdlstate || - !rtlpriv->dm.current_turbo_edca) { - rtl_write_dword(rtlpriv, - REG_EDCA_BE_PARAM, - edca_be_ul); - rtlpriv->dm.is_cur_rdlstate = false; - } - } - rtlpriv->dm.current_turbo_edca = true; - } else { - if (rtlpriv->dm.current_turbo_edca) { - u8 tmp = AC0_BE; - rtlpriv->cfg->ops->set_hw_reg(hw, - HW_VAR_AC_PARAM, - (u8 *) (&tmp)); - rtlpriv->dm.current_turbo_edca = false; - } - } - - rtlpriv->dm.is_any_nonbepkts = false; - mac->last_txok_cnt = rtlpriv->stats.txbytesunicast; - mac->last_rxok_cnt = rtlpriv->stats.rxbytesunicast; -} - -static void rtl8723ae_dm_initialize_txpower_tracking(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtlpriv->dm.txpower_tracking = true; - rtlpriv->dm.txpower_trackinginit = false; - - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - "pMgntInfo->txpower_tracking = %d\n", - rtlpriv->dm.txpower_tracking); -} - -void rtl8723ae_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rate_adaptive *p_ra = &(rtlpriv->ra); - - p_ra->ratr_state = DM_RATR_STA_INIT; - p_ra->pre_ratr_state = DM_RATR_STA_INIT; - - if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) - rtlpriv->dm.useramask = true; - else - rtlpriv->dm.useramask = false; -} - -static void rtl8723ae_dm_init_dynamic_bpowersaving(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtlpriv->dm_pstable.pre_ccastate = CCA_MAX; - rtlpriv->dm_pstable.cur_ccasate = CCA_MAX; - rtlpriv->dm_pstable.pre_rfstate = RF_MAX; - rtlpriv->dm_pstable.cur_rfstate = RF_MAX; - rtlpriv->dm_pstable.rssi_val_min = 0; -} - -void rtl8723ae_dm_rf_saving(struct ieee80211_hw *hw, u8 force_in_normal) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct ps_t *dm_pstable = &rtlpriv->dm_pstable; - - if (!rtlpriv->reg_init) { - rtlpriv->reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, - MASKDWORD) & 0x1CC000) >> 14; - - rtlpriv->reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1, - MASKDWORD) & BIT(3)) >> 3; - - rtlpriv->reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, - MASKDWORD) & 0xFF000000) >> 24; - - rtlpriv->reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & - 0xF000) >> 12; - - rtlpriv->reg_init = true; - } - - if (!force_in_normal) { - if (dm_pstable->rssi_val_min != 0) { - if (dm_pstable->pre_rfstate == RF_NORMAL) { - if (dm_pstable->rssi_val_min >= 30) - dm_pstable->cur_rfstate = RF_SAVE; - else - dm_pstable->cur_rfstate = RF_NORMAL; - } else { - if (dm_pstable->rssi_val_min <= 25) - dm_pstable->cur_rfstate = RF_NORMAL; - else - dm_pstable->cur_rfstate = RF_SAVE; - } - } else { - dm_pstable->cur_rfstate = RF_MAX; - } - } else { - dm_pstable->cur_rfstate = RF_NORMAL; - } - - if (dm_pstable->pre_rfstate != dm_pstable->cur_rfstate) { - if (dm_pstable->cur_rfstate == RF_SAVE) { - - rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, - BIT(5), 0x1); - rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, - 0x1C0000, 0x2); - rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 0); - rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, - 0xFF000000, 0x63); - rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, - 0xC000, 0x2); - rtl_set_bbreg(hw, 0xa74, 0xF000, 0x3); - rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); - rtl_set_bbreg(hw, 0x818, BIT(28), 0x1); - } else { - rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, - 0x1CC000, rtlpriv->reg_874); - rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), - rtlpriv->reg_c70); - rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000, - rtlpriv->reg_85c); - rtl_set_bbreg(hw, 0xa74, 0xF000, rtlpriv->reg_a74); - rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); - rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, - BIT(5), 0x0); - } - - dm_pstable->pre_rfstate = dm_pstable->cur_rfstate; - } -} - -static void rtl8723ae_dm_dynamic_bpowersaving(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct ps_t *dm_pstable = &rtlpriv->dm_pstable; - - if (((mac->link_state == MAC80211_NOLINK)) && - (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { - dm_pstable->rssi_val_min = 0; - RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - "Not connected to any\n"); - } - - if (mac->link_state == MAC80211_LINKED) { - if (mac->opmode == NL80211_IFTYPE_ADHOC) { - dm_pstable->rssi_val_min = - rtlpriv->dm.entry_min_undec_sm_pwdb; - RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - "AP Client PWDB = 0x%lx\n", - dm_pstable->rssi_val_min); - } else { - dm_pstable->rssi_val_min = rtlpriv->dm.undec_sm_pwdb; - RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - "STA Default Port PWDB = 0x%lx\n", - dm_pstable->rssi_val_min); - } - } else { - dm_pstable->rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb; - - RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - "AP Ext Port PWDB = 0x%lx\n", - dm_pstable->rssi_val_min); - } - - rtl8723ae_dm_rf_saving(hw, false); -} - -void rtl8723ae_dm_init(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; - rtl8723ae_dm_diginit(hw); - rtl8723ae_dm_init_dynamic_txpower(hw); - rtl8723ae_dm_init_edca_turbo(hw); - rtl8723ae_dm_init_rate_adaptive_mask(hw); - rtl8723ae_dm_initialize_txpower_tracking(hw); - rtl8723ae_dm_init_dynamic_bpowersaving(hw); -} - -void rtl8723ae_dm_watchdog(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - bool fw_current_inpsmode = false; - bool fw_ps_awake = true; - rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, - (u8 *) (&fw_current_inpsmode)); - rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, - (u8 *) (&fw_ps_awake)); - - if ((ppsc->rfpwr_state == ERFON) && - ((!fw_current_inpsmode) && fw_ps_awake) && - (!ppsc->rfchange_inprogress)) { - rtl8723ae_dm_pwdmonitor(hw); - rtl8723ae_dm_dig(hw); - rtl8723ae_dm_false_alarm_counter_statistics(hw); - rtl8723ae_dm_dynamic_bpowersaving(hw); - rtl8723ae_dm_dynamic_txpower(hw); - /* rtl92c_dm_refresh_rate_adaptive_mask(hw); */ - rtl8723ae_dm_bt_coexist(hw); - rtl8723ae_dm_check_edca_turbo(hw); - } - if (rtlpcipriv->bt_coexist.init_set) - rtl_write_byte(rtlpriv, 0x76e, 0xc); -} - -static void rtl8723ae_dm_init_bt_coexist(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - - rtlpcipriv->bt_coexist.bt_rfreg_origin_1e - = rtl_get_rfreg(hw, (enum radio_path)0, RF_RCK1, 0xfffff); - rtlpcipriv->bt_coexist.bt_rfreg_origin_1f - = rtl_get_rfreg(hw, (enum radio_path)0, RF_RCK2, 0xf0); - - rtlpcipriv->bt_coexist.cstate = 0; - rtlpcipriv->bt_coexist.previous_state = 0; - rtlpcipriv->bt_coexist.cstate_h = 0; - rtlpcipriv->bt_coexist.previous_state_h = 0; - rtlpcipriv->bt_coexist.lps_counter = 0; - - /* Enable counter statistics */ - rtl_write_byte(rtlpriv, 0x76e, 0x4); - rtl_write_byte(rtlpriv, 0x778, 0x3); - rtl_write_byte(rtlpriv, 0x40, 0x20); - - rtlpcipriv->bt_coexist.init_set = true; -} - -void rtl8723ae_dm_bt_coexist(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - u8 tmp_byte = 0; - if (!rtlpcipriv->bt_coexist.bt_coexistence) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, - "[DM]{BT], BT not exist!!\n"); - return; - } - - if (!rtlpcipriv->bt_coexist.init_set) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, - "[DM][BT], rtl8723ae_dm_bt_coexist()\n"); - - rtl8723ae_dm_init_bt_coexist(hw); - } - - tmp_byte = rtl_read_byte(rtlpriv, 0x40); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, - "[DM][BT], 0x40 is 0x%x", tmp_byte); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[DM][BT], bt_dm_coexist start"); - rtl8723ae_dm_bt_coexist_8723(hw); -} diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h deleted file mode 100644 index 39d246196247..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/dm.h +++ /dev/null @@ -1,149 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - **************************************************************************** - */ - -#ifndef __RTL8723E_DM_H__ -#define __RTL8723E_DM_H__ - -#define HAL_DM_HIPWR_DISABLE BIT(1) - -#define OFDM_TABLE_SIZE 37 -#define CCK_TABLE_SIZE 33 - -#define DM_DIG_THRESH_HIGH 40 -#define DM_DIG_THRESH_LOW 35 - -#define DM_FALSEALARM_THRESH_LOW 400 -#define DM_FALSEALARM_THRESH_HIGH 1000 - -#define DM_DIG_MAX 0x3e -#define DM_DIG_MIN 0x1e - -#define DM_DIG_FA_UPPER 0x32 -#define DM_DIG_FA_LOWER 0x20 -#define DM_DIG_FA_TH0 0x20 -#define DM_DIG_FA_TH1 0x100 -#define DM_DIG_FA_TH2 0x200 - -#define DM_DIG_BACKOFF_MAX 12 -#define DM_DIG_BACKOFF_MIN -4 -#define DM_DIG_BACKOFF_DEFAULT 10 - -#define DM_RATR_STA_INIT 0 - -#define TXHIGHPWRLEVEL_NORMAL 0 -#define TXHIGHPWRLEVEL_LEVEL1 1 -#define TXHIGHPWRLEVEL_LEVEL2 2 -#define TXHIGHPWRLEVEL_BT1 3 -#define TXHIGHPWRLEVEL_BT2 4 - -#define DM_TYPE_BYDRIVER 1 - -#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 -#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67 - -struct swat_t { - u8 failure_cnt; - u8 try_flag; - u8 stop_trying; - long pre_rssi; - long trying_threshold; - u8 cur_antenna; - u8 pre_antenna; -}; - -enum tag_dynamic_init_gain_operation_type_definition { - DIG_TYPE_THRESH_HIGH = 0, - DIG_TYPE_THRESH_LOW = 1, - DIG_TYPE_BACKOFF = 2, - DIG_TYPE_RX_GAIN_MIN = 3, - DIG_TYPE_RX_GAIN_MAX = 4, - DIG_TYPE_ENABLE = 5, - DIG_TYPE_DISABLE = 6, - DIG_OP_TYPE_MAX -}; - -enum tag_cck_packet_detection_threshold_type_definition { - CCK_PD_STAGE_LowRssi = 0, - CCK_PD_STAGE_HighRssi = 1, - CCK_FA_STAGE_Low = 2, - CCK_FA_STAGE_High = 3, - CCK_PD_STAGE_MAX = 4, -}; - -enum dm_1r_cca_e { - CCA_1R = 0, - CCA_2R = 1, - CCA_MAX = 2, -}; - -enum dm_rf_e { - RF_SAVE = 0, - RF_NORMAL = 1, - RF_MAX = 2, -}; - -enum dm_sw_ant_switch_e { - ANS_ANTENNA_B = 1, - ANS_ANTENNA_A = 2, - ANS_ANTENNA_MAX = 3, -}; - -enum dm_dig_ext_port_alg_e { - DIG_EXT_PORT_STAGE_0 = 0, - DIG_EXT_PORT_STAGE_1 = 1, - DIG_EXT_PORT_STAGE_2 = 2, - DIG_EXT_PORT_STAGE_3 = 3, - DIG_EXT_PORT_STAGE_MAX = 4, -}; - -enum dm_dig_connect_e { - DIG_STA_DISCONNECT = 0, - DIG_STA_CONNECT = 1, - DIG_STA_BEFORE_CONNECT = 2, - DIG_MULTISTA_DISCONNECT = 3, - DIG_MULTISTA_CONNECT = 4, - DIG_CONNECT_MAX -}; - -#define GET_UNDECORATED_AVERAGE_RSSI(_priv) \ - ((((struct rtl_priv *)(_priv))->mac80211.opmode == \ - NL80211_IFTYPE_ADHOC) ? \ - (((struct rtl_priv *)(_priv))->dm.entry_min_undec_sm_pwdb) \ - : (((struct rtl_priv *)(_priv))->dm.undec_sm_pwdb)) - -void rtl8723ae_dm_init(struct ieee80211_hw *hw); -void rtl8723ae_dm_watchdog(struct ieee80211_hw *hw); -void rtl8723ae_dm_write_dig(struct ieee80211_hw *hw); -void rtl8723ae_dm_init_edca_turbo(struct ieee80211_hw *hw); -void rtl8723ae_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw); -void rtl8723ae_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal); -void rtl8723ae_dm_bt_coexist(struct ieee80211_hw *hw); - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c deleted file mode 100644 index f55b1767ef57..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/fw.c +++ /dev/null @@ -1,745 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - **************************************************************************** - */ - -#include "../wifi.h" -#include "../pci.h" -#include "../base.h" -#include "reg.h" -#include "def.h" -#include "fw.h" - -static void _rtl8723ae_enable_fw_download(struct ieee80211_hw *hw, bool enable) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 tmp; - if (enable) { - tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp | 0x04); - - tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); - rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp | 0x01); - - tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL + 2); - rtl_write_byte(rtlpriv, REG_MCUFWDL + 2, tmp & 0xf7); - } else { - tmp = rtl_read_byte(rtlpriv, REG_MCUFWDL); - rtl_write_byte(rtlpriv, REG_MCUFWDL, tmp & 0xfe); - - rtl_write_byte(rtlpriv, REG_MCUFWDL + 1, 0x00); - } -} - -static void _rtl8723ae_fw_block_write(struct ieee80211_hw *hw, - const u8 *buffer, u32 size) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 blockSize = sizeof(u32); - u8 *bufferPtr = (u8 *) buffer; - u32 *pu4BytePtr = (u32 *) buffer; - u32 i, offset, blockCount, remainSize; - - blockCount = size / blockSize; - remainSize = size % blockSize; - - for (i = 0; i < blockCount; i++) { - offset = i * blockSize; - rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset), - *(pu4BytePtr + i)); - } - - if (remainSize) { - offset = blockCount * blockSize; - bufferPtr += offset; - for (i = 0; i < remainSize; i++) { - rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS + - offset + i), *(bufferPtr + i)); - } - } -} - -static void _rtl8723ae_fw_page_write(struct ieee80211_hw *hw, - u32 page, const u8 *buffer, u32 size) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 value8; - u8 u8page = (u8) (page & 0x07); - - value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page; - - rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8); - _rtl8723ae_fw_block_write(hw, buffer, size); -} - -static void _rtl8723ae_write_fw(struct ieee80211_hw *hw, - enum version_8723e version, u8 *buffer, - u32 size) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 *bufferPtr = (u8 *) buffer; - u32 page_nums, remain_size; - u32 page, offset; - - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size); - - page_nums = size / FW_8192C_PAGE_SIZE; - remain_size = size % FW_8192C_PAGE_SIZE; - - if (page_nums > 6) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Page numbers should not be greater then 6\n"); - } - - for (page = 0; page < page_nums; page++) { - offset = page * FW_8192C_PAGE_SIZE; - _rtl8723ae_fw_page_write(hw, page, (bufferPtr + offset), - FW_8192C_PAGE_SIZE); - } - - if (remain_size) { - offset = page_nums * FW_8192C_PAGE_SIZE; - page = page_nums; - _rtl8723ae_fw_page_write(hw, page, (bufferPtr + offset), - remain_size); - } - - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW write done.\n"); -} - -static int _rtl8723ae_fw_free_to_go(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - int err = -EIO; - u32 counter = 0; - u32 value32; - - do { - value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); - } while ((counter++ < FW_8192C_POLLING_TIMEOUT_COUNT) && - (!(value32 & FWDL_ChkSum_rpt))); - - if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "chksum report faill ! REG_MCUFWDL:0x%08x .\n", - value32); - goto exit; - } - - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - "Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32); - - value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); - value32 |= MCUFWDL_RDY; - value32 &= ~WINTINI_RDY; - rtl_write_dword(rtlpriv, REG_MCUFWDL, value32); - - counter = 0; - - do { - value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); - if (value32 & WINTINI_RDY) { - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - "Polling FW ready success!! REG_MCUFWDL:0x%08x .\n", - value32); - err = 0; - goto exit; - } - - mdelay(FW_8192C_POLLING_DELAY); - - } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT); - - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32); - -exit: - return err; -} - -int rtl8723ae_download_fw(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl8723ae_firmware_header *pfwheader; - u8 *pfwdata; - u32 fwsize; - int err; - enum version_8723e version = rtlhal->version; - - if (!rtlhal->pfirmware) - return 1; - - pfwheader = (struct rtl8723ae_firmware_header *)rtlhal->pfirmware; - pfwdata = (u8 *) rtlhal->pfirmware; - fwsize = rtlhal->fwsize; - - if (IS_FW_HEADER_EXIST(pfwheader)) { - RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - "Firmware Version(%d), Signature(%#x),Size(%d)\n", - pfwheader->version, pfwheader->signature, - (int)sizeof(struct rtl8723ae_firmware_header)); - - pfwdata = pfwdata + sizeof(struct rtl8723ae_firmware_header); - fwsize = fwsize - sizeof(struct rtl8723ae_firmware_header); - } - - if (rtl_read_byte(rtlpriv, REG_MCUFWDL)&BIT(7)) { - rtl8723ae_firmware_selfreset(hw); - rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); - } - _rtl8723ae_enable_fw_download(hw, true); - _rtl8723ae_write_fw(hw, version, pfwdata, fwsize); - _rtl8723ae_enable_fw_download(hw, false); - - err = _rtl8723ae_fw_free_to_go(hw); - if (err) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Firmware is not ready to run!\n"); - } else { - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - "Firmware is ready to run!\n"); - } - return 0; -} - -static bool rtl8723ae_check_fw_read_last_h2c(struct ieee80211_hw *hw, u8 boxnum) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 val_hmetfr, val_mcutst_1; - bool result = false; - - val_hmetfr = rtl_read_byte(rtlpriv, REG_HMETFR); - val_mcutst_1 = rtl_read_byte(rtlpriv, (REG_MCUTST_1 + boxnum)); - - if (((val_hmetfr >> boxnum) & BIT(0)) == 0 && val_mcutst_1 == 0) - result = true; - return result; -} - -static void _rtl8723ae_fill_h2c_command(struct ieee80211_hw *hw, - u8 element_id, u32 cmd_len, - u8 *p_cmdbuffer) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - u8 boxnum; - u16 box_reg = 0, box_extreg = 0; - u8 u1tmp; - bool isfw_rd = false; - bool bwrite_sucess = false; - u8 wait_h2c_limmit = 100; - u8 wait_writeh2c_limmit = 100; - u8 boxcontent[4], boxextcontent[2]; - u32 h2c_waitcounter = 0; - unsigned long flag; - u8 idx; - - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n"); - - while (true) { - spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); - if (rtlhal->h2c_setinprogress) { - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - "H2C set in progress! Wait to set..element_id(%d).\n", - element_id); - - while (rtlhal->h2c_setinprogress) { - spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, - flag); - h2c_waitcounter++; - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - "Wait 100 us (%d times)...\n", - h2c_waitcounter); - udelay(100); - - if (h2c_waitcounter > 1000) - return; - spin_lock_irqsave(&rtlpriv->locks.h2c_lock, - flag); - } - spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); - } else { - rtlhal->h2c_setinprogress = true; - spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); - break; - } - } - - while (!bwrite_sucess) { - wait_writeh2c_limmit--; - if (wait_writeh2c_limmit == 0) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Write H2C fail because no trigger " - "for FW INT!\n"); - break; - } - - boxnum = rtlhal->last_hmeboxnum; - switch (boxnum) { - case 0: - box_reg = REG_HMEBOX_0; - box_extreg = REG_HMEBOX_EXT_0; - break; - case 1: - box_reg = REG_HMEBOX_1; - box_extreg = REG_HMEBOX_EXT_1; - break; - case 2: - box_reg = REG_HMEBOX_2; - box_extreg = REG_HMEBOX_EXT_2; - break; - case 3: - box_reg = REG_HMEBOX_3; - box_extreg = REG_HMEBOX_EXT_3; - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not processed\n"); - break; - } - - isfw_rd = rtl8723ae_check_fw_read_last_h2c(hw, boxnum); - while (!isfw_rd) { - - wait_h2c_limmit--; - if (wait_h2c_limmit == 0) { - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - "Wating too long for FW read clear HMEBox(%d)!\n", - boxnum); - break; - } - - udelay(10); - - isfw_rd = rtl8723ae_check_fw_read_last_h2c(hw, boxnum); - u1tmp = rtl_read_byte(rtlpriv, 0x1BF); - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - "Wating for FW read clear HMEBox(%d)!!! " - "0x1BF = %2x\n", boxnum, u1tmp); - } - - if (!isfw_rd) { - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - "Write H2C register BOX[%d] fail!!!!! " - "Fw do not read.\n", boxnum); - break; - } - - memset(boxcontent, 0, sizeof(boxcontent)); - memset(boxextcontent, 0, sizeof(boxextcontent)); - boxcontent[0] = element_id; - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - "Write element_id box_reg(%4x) = %2x\n", - box_reg, element_id); - - switch (cmd_len) { - case 1: - boxcontent[0] &= ~(BIT(7)); - memcpy((u8 *) (boxcontent) + 1, - p_cmdbuffer, 1); - - for (idx = 0; idx < 4; idx++) { - rtl_write_byte(rtlpriv, box_reg + idx, - boxcontent[idx]); - } - break; - case 2: - boxcontent[0] &= ~(BIT(7)); - memcpy((u8 *) (boxcontent) + 1, - p_cmdbuffer, 2); - - for (idx = 0; idx < 4; idx++) { - rtl_write_byte(rtlpriv, box_reg + idx, - boxcontent[idx]); - } - break; - case 3: - boxcontent[0] &= ~(BIT(7)); - memcpy((u8 *) (boxcontent) + 1, - p_cmdbuffer, 3); - - for (idx = 0; idx < 4; idx++) { - rtl_write_byte(rtlpriv, box_reg + idx, - boxcontent[idx]); - } - break; - case 4: - boxcontent[0] |= (BIT(7)); - memcpy((u8 *) (boxextcontent), - p_cmdbuffer, 2); - memcpy((u8 *) (boxcontent) + 1, - p_cmdbuffer + 2, 2); - - for (idx = 0; idx < 2; idx++) { - rtl_write_byte(rtlpriv, box_extreg + idx, - boxextcontent[idx]); - } - - for (idx = 0; idx < 4; idx++) { - rtl_write_byte(rtlpriv, box_reg + idx, - boxcontent[idx]); - } - break; - case 5: - boxcontent[0] |= (BIT(7)); - memcpy((u8 *) (boxextcontent), - p_cmdbuffer, 2); - memcpy((u8 *) (boxcontent) + 1, - p_cmdbuffer + 2, 3); - - for (idx = 0; idx < 2; idx++) { - rtl_write_byte(rtlpriv, box_extreg + idx, - boxextcontent[idx]); - } - - for (idx = 0; idx < 4; idx++) { - rtl_write_byte(rtlpriv, box_reg + idx, - boxcontent[idx]); - } - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not process\n"); - break; - } - - bwrite_sucess = true; - - rtlhal->last_hmeboxnum = boxnum + 1; - if (rtlhal->last_hmeboxnum == 4) - rtlhal->last_hmeboxnum = 0; - - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - "pHalData->last_hmeboxnum = %d\n", - rtlhal->last_hmeboxnum); - } - - spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); - rtlhal->h2c_setinprogress = false; - spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); - - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n"); -} - -void rtl8723ae_fill_h2c_cmd(struct ieee80211_hw *hw, - u8 element_id, u32 cmd_len, u8 *p_cmdbuffer) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtlpriv); - - if (rtlhal->fw_ready == false) { - RT_ASSERT(false, - "return H2C cmd because of Fw download fail!!!\n"); - return; - } - - _rtl8723ae_fill_h2c_command(hw, element_id, cmd_len, p_cmdbuffer); - return; -} - -void rtl8723ae_firmware_selfreset(struct ieee80211_hw *hw) -{ - u8 u1tmp; - u8 delay = 100; - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtl_write_byte(rtlpriv, REG_HMETFR + 3, 0x20); - u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); - - while (u1tmp & BIT(2)) { - delay--; - if (delay == 0) - break; - udelay(50); - u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); - } - if (delay == 0) { - u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, u1tmp&(~BIT(2))); - } -} - -void rtl8723ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 u1_h2c_set_pwrmode[3] = { 0 }; - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode); - - SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode); - SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1); - SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode, - ppsc->reg_max_lps_awakeintvl); - - RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, - "rtl8723ae_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n", - u1_h2c_set_pwrmode, 3); - rtl8723ae_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode); - -} - -static bool _rtl8723ae_cmd_send_packet(struct ieee80211_hw *hw, - struct sk_buff *skb) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - struct rtl8192_tx_ring *ring; - struct rtl_tx_desc *pdesc; - u8 own; - unsigned long flags; - struct sk_buff *pskb = NULL; - - ring = &rtlpci->tx_ring[BEACON_QUEUE]; - - pskb = __skb_dequeue(&ring->queue); - if (pskb) - kfree_skb(pskb); - - spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); - - pdesc = &ring->desc[0]; - own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN); - - rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb); - - __skb_queue_tail(&ring->queue, skb); - - spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); - - rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE); - - return true; -} - -static u8 reserved_page_packet[TOTAL_RESERVED_PKT_LEN] = { - /* page 0 beacon */ - 0x80, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, - 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x50, 0x08, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, - 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, - 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, - 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, - 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, - 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, - 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - /* page 1 beacon */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - /* page 2 ps-poll */ - 0xA4, 0x10, 0x01, 0xC0, 0x00, 0x40, 0x10, 0x10, - 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - /* page 3 null */ - 0x48, 0x01, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, - 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, - 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x72, 0x00, 0x20, 0x8C, 0x00, 0x12, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - /* page 4 probe_resp */ - 0x50, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x10, - 0x00, 0x03, 0x00, 0xE0, 0x4C, 0x76, 0x00, 0x42, - 0x00, 0x40, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, - 0x9E, 0x46, 0x15, 0x32, 0x27, 0xF2, 0x2D, 0x00, - 0x64, 0x00, 0x00, 0x04, 0x00, 0x0C, 0x6C, 0x69, - 0x6E, 0x6B, 0x73, 0x79, 0x73, 0x5F, 0x77, 0x6C, - 0x61, 0x6E, 0x01, 0x04, 0x82, 0x84, 0x8B, 0x96, - 0x03, 0x01, 0x01, 0x06, 0x02, 0x00, 0x00, 0x2A, - 0x01, 0x00, 0x32, 0x08, 0x24, 0x30, 0x48, 0x6C, - 0x0C, 0x12, 0x18, 0x60, 0x2D, 0x1A, 0x6C, 0x18, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3D, 0x00, 0xDD, 0x06, 0x00, 0xE0, 0x4C, 0x02, - 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - - /* page 5 probe_resp */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; - -void rtl8723ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct sk_buff *skb = NULL; - - u32 totalpacketlen; - bool rtstatus; - u8 u1RsvdPageLoc[3] = { 0 }; - bool dlok = false; - - u8 *beacon; - u8 *p_pspoll; - u8 *nullfunc; - u8 *p_probersp; - /*--------------------------------------------------------- - (1) beacon - --------------------------------------------------------- - */ - beacon = &reserved_page_packet[BEACON_PG * 128]; - SET_80211_HDR_ADDRESS2(beacon, mac->mac_addr); - SET_80211_HDR_ADDRESS3(beacon, mac->bssid); - - /*------------------------------------------------------- - (2) ps-poll - -------------------------------------------------------- - */ - p_pspoll = &reserved_page_packet[PSPOLL_PG * 128]; - SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000)); - SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid); - SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr); - - SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG); - - /*-------------------------------------------------------- - (3) null data - ---------------------------------------------------------i - */ - nullfunc = &reserved_page_packet[NULL_PG * 128]; - SET_80211_HDR_ADDRESS1(nullfunc, mac->bssid); - SET_80211_HDR_ADDRESS2(nullfunc, mac->mac_addr); - SET_80211_HDR_ADDRESS3(nullfunc, mac->bssid); - - SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1RsvdPageLoc, NULL_PG); - - /*--------------------------------------------------------- - (4) probe response - ---------------------------------------------------------- - */ - p_probersp = &reserved_page_packet[PROBERSP_PG * 128]; - SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid); - SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr); - SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid); - - SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG); - - totalpacketlen = TOTAL_RESERVED_PKT_LEN; - - RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, - "rtl8723ae_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", - &reserved_page_packet[0], totalpacketlen); - RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, - "rtl8723ae_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", - u1RsvdPageLoc, 3); - - skb = dev_alloc_skb(totalpacketlen); - memcpy((u8 *) skb_put(skb, totalpacketlen), - &reserved_page_packet, totalpacketlen); - - rtstatus = _rtl8723ae_cmd_send_packet(hw, skb); - - if (rtstatus) - dlok = true; - - if (dlok) { - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "Set RSVD page location to Fw.\n"); - RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, - "H2C_RSVDPAGE:\n", - u1RsvdPageLoc, 3); - rtl8723ae_fill_h2c_cmd(hw, H2C_RSVDPAGE, - sizeof(u1RsvdPageLoc), u1RsvdPageLoc); - } else - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "Set RSVD page location to Fw FAIL!!!!!!.\n"); -} - -void rtl8723ae_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus) -{ - u8 u1_joinbssrpt_parm[1] = { 0 }; - - SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(u1_joinbssrpt_parm, mstatus); - - rtl8723ae_fill_h2c_cmd(hw, H2C_JOINBSSRPT, 1, u1_joinbssrpt_parm); -} diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h deleted file mode 100644 index 89994e16dc83..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/fw.h +++ /dev/null @@ -1,101 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * Larry Finger - * - **************************************************************************** - */ - -#ifndef __RTL92C__FW__H__ -#define __RTL92C__FW__H__ - -#define FW_8192C_START_ADDRESS 0x1000 -#define FW_8192C_END_ADDRESS 0x3FFF -#define FW_8192C_PAGE_SIZE 4096 -#define FW_8192C_POLLING_DELAY 5 -#define FW_8192C_POLLING_TIMEOUT_COUNT 1000 - -#define BEACON_PG 0 -#define PSPOLL_PG 2 -#define NULL_PG 3 -#define PROBERSP_PG 4 /* ->5 */ - -#define TOTAL_RESERVED_PKT_LEN 768 - -#define IS_FW_HEADER_EXIST(_pfwhdr) \ - ((_pfwhdr->signature&0xFF00) == 0x2300) - -struct rtl8723ae_firmware_header { - u16 signature; - u8 category; - u8 function; - u16 version; - u8 subversion; - u8 rsvd1; - u8 month; - u8 date; - u8 hour; - u8 minute; - u16 ramcodeSize; - u16 rsvd2; - u32 svnindex; - u32 rsvd3; - u32 rsvd4; - u32 rsvd5; -}; - -enum rtl8192c_h2c_cmd { - H2C_AP_OFFLOAD = 0, - H2C_SETPWRMODE = 1, - H2C_JOINBSSRPT = 2, - H2C_RSVDPAGE = 3, - H2C_RSSI_REPORT = 5, - H2C_RA_MASK = 6, - MAX_H2CCMD -}; - -#define SET_H2CCMD_PWRMODE_PARM_MODE(__ph2ccmd, __val) \ - SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) -#define SET_H2CCMD_PWRMODE_PARM_SMART_PS(__ph2ccmd, __val) \ - SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val) -#define SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(__ph2ccmd, __val) \ - SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val) -#define SET_H2CCMD_JOINBSSRPT_PARM_OPMODE(__ph2ccmd, __val) \ - SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) -#define SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(__ph2ccmd, __val) \ - SET_BITS_TO_LE_1BYTE(__ph2ccmd, 0, 8, __val) -#define SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(__ph2ccmd, __val) \ - SET_BITS_TO_LE_1BYTE((__ph2ccmd)+1, 0, 8, __val) -#define SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(__ph2ccmd, __val) \ - SET_BITS_TO_LE_1BYTE((__ph2ccmd)+2, 0, 8, __val) - -int rtl8723ae_download_fw(struct ieee80211_hw *hw); -void rtl8723ae_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, - u32 cmd_len, u8 *p_cmdbuffer); -void rtl8723ae_firmware_selfreset(struct ieee80211_hw *hw); -void rtl8723ae_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode); -void rtl8723ae_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished); -void rtl8723ae_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus); - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c deleted file mode 100644 index 3d092e4b0b7f..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.c +++ /dev/null @@ -1,542 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#include "hal_bt_coexist.h" -#include "../pci.h" -#include "dm.h" -#include "fw.h" -#include "phy.h" -#include "reg.h" -#include "hal_btc.h" - -void rtl8723ae_dm_bt_reject_ap_aggregated_packet(struct ieee80211_hw *hw, - bool reject) -{ -} - -void _rtl8723_dm_bt_check_wifi_state(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - if (rtlpriv->link_info.busytraffic) { - rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_IDLE; - - if (rtlpriv->link_info.tx_busy_traffic) - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_WIFI_UPLINK; - else - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_UPLINK; - - if (rtlpriv->link_info.rx_busy_traffic) - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_WIFI_DOWNLINK; - else - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_DOWNLINK; - } else { - rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_WIFI_IDLE; - rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_UPLINK; - rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_DOWNLINK; - } - - if (rtlpriv->mac80211.mode == WIRELESS_MODE_G || - rtlpriv->mac80211.mode == WIRELESS_MODE_B) { - rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_WIFI_LEGACY; - rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_HT20; - rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_HT40; - } else { - rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_LEGACY; - if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_WIFI_HT40; - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_HT20; - } else { - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_WIFI_HT20; - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_HT40; - } - } - - if (rtlpriv->bt_operation_on) - rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_BT30; - else - rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_BT30; -} - -u8 rtl8723ae_dm_bt_check_coex_rssi_state1(struct ieee80211_hw *hw, - u8 level_num, u8 rssi_thresh, - u8 rssi_thresh1) - -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - long smooth; - u8 bt_rssi_state = 0; - - smooth = rtl8723ae_dm_bt_get_rx_ss(hw); - - if (level_num == 2) { - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM; - - if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state == - BT_RSSI_STATE_LOW) || - (rtlpcipriv->bt_coexist.bt_pre_rssi_state == - BT_RSSI_STATE_STAY_LOW)) { - if (smooth >= (rssi_thresh + - BT_FW_COEX_THRESH_TOL)) { - bt_rssi_state = BT_RSSI_STATE_HIGH; - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_WIFI_RSSI_1_HIGH; - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_RSSI_1_LOW; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI_1 state switch to High\n"); - } else { - bt_rssi_state = BT_RSSI_STATE_STAY_LOW; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI_1 state stay at Low\n"); - } - } else { - if (smooth < rssi_thresh) { - bt_rssi_state = BT_RSSI_STATE_LOW; - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_WIFI_RSSI_1_LOW; - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_RSSI_1_HIGH; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI_1 state switch to Low\n"); - } else { - bt_rssi_state = BT_RSSI_STATE_STAY_HIGH; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI_1 state stay at High\n"); - } - } - } else if (level_num == 3) { - if (rssi_thresh > rssi_thresh1) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI_1 thresh error!!\n"); - return rtlpcipriv->bt_coexist.bt_pre_rssi_state; - } - - if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state == - BT_RSSI_STATE_LOW) || - (rtlpcipriv->bt_coexist.bt_pre_rssi_state == - BT_RSSI_STATE_STAY_LOW)) { - if (smooth >= - (rssi_thresh+BT_FW_COEX_THRESH_TOL)) { - bt_rssi_state = BT_RSSI_STATE_MEDIUM; - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_WIFI_RSSI_1_MEDIUM; - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_RSSI_1_LOW; - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_RSSI_1_HIGH; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI_1 state switch to Medium\n"); - } else { - bt_rssi_state = BT_RSSI_STATE_STAY_LOW; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI_1 state stay at Low\n"); - } - } else if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state == - BT_RSSI_STATE_MEDIUM) || - (rtlpcipriv->bt_coexist.bt_pre_rssi_state == - BT_RSSI_STATE_STAY_MEDIUM)) { - if (smooth >= (rssi_thresh1 + - BT_FW_COEX_THRESH_TOL)) { - bt_rssi_state = BT_RSSI_STATE_HIGH; - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_WIFI_RSSI_1_HIGH; - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_RSSI_1_LOW; - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI_1 state switch to High\n"); - } else if (smooth < rssi_thresh) { - bt_rssi_state = BT_RSSI_STATE_LOW; - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_WIFI_RSSI_1_LOW; - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_RSSI_1_HIGH; - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI_1 state switch to Low\n"); - } else { - bt_rssi_state = BT_RSSI_STATE_STAY_MEDIUM; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI_1 state stay at Medium\n"); - } - } else { - if (smooth < rssi_thresh1) { - bt_rssi_state = BT_RSSI_STATE_MEDIUM; - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_WIFI_RSSI_1_MEDIUM; - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_RSSI_1_HIGH; - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_RSSI_1_LOW; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI_1 state switch to Medium\n"); - } else { - bt_rssi_state = BT_RSSI_STATE_STAY_HIGH; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI_1 state stay at High\n"); - } - } - } - - rtlpcipriv->bt_coexist.bt_pre_rssi_state1 = bt_rssi_state; - - return bt_rssi_state; -} - -u8 rtl8723ae_dm_bt_check_coex_rssi_state(struct ieee80211_hw *hw, - u8 level_num, u8 rssi_thresh, - u8 rssi_thresh1) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - long smooth; - u8 bt_rssi_state = 0; - - smooth = rtl8723ae_dm_bt_get_rx_ss(hw); - - if (level_num == 2) { - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_RSSI_MEDIUM; - - if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state == - BT_RSSI_STATE_LOW) || - (rtlpcipriv->bt_coexist.bt_pre_rssi_state == - BT_RSSI_STATE_STAY_LOW)){ - if (smooth >= - (rssi_thresh + BT_FW_COEX_THRESH_TOL)) { - bt_rssi_state = BT_RSSI_STATE_HIGH; - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_WIFI_RSSI_HIGH; - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_RSSI_LOW; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI state switch to High\n"); - } else { - bt_rssi_state = BT_RSSI_STATE_STAY_LOW; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI state stay at Low\n"); - } - } else { - if (smooth < rssi_thresh) { - bt_rssi_state = BT_RSSI_STATE_LOW; - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_WIFI_RSSI_LOW; - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_WIFI_RSSI_HIGH; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI state switch to Low\n"); - } else { - bt_rssi_state = BT_RSSI_STATE_STAY_HIGH; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI state stay at High\n"); - } - } - } else if (level_num == 3) { - if (rssi_thresh > rssi_thresh1) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI thresh error!!\n"); - return rtlpcipriv->bt_coexist.bt_pre_rssi_state; - } - if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state == - BT_RSSI_STATE_LOW) || - (rtlpcipriv->bt_coexist.bt_pre_rssi_state == - BT_RSSI_STATE_STAY_LOW)) { - if (smooth >= - (rssi_thresh + BT_FW_COEX_THRESH_TOL)) { - bt_rssi_state = BT_RSSI_STATE_MEDIUM; - rtlpcipriv->bt_coexist.cstate - |= BT_COEX_STATE_WIFI_RSSI_MEDIUM; - rtlpcipriv->bt_coexist.cstate - &= ~BT_COEX_STATE_WIFI_RSSI_LOW; - rtlpcipriv->bt_coexist.cstate - &= ~BT_COEX_STATE_WIFI_RSSI_HIGH; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI state switch to Medium\n"); - } else { - bt_rssi_state = BT_RSSI_STATE_STAY_LOW; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI state stay at Low\n"); - } - } else if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state == - BT_RSSI_STATE_MEDIUM) || - (rtlpcipriv->bt_coexist.bt_pre_rssi_state == - BT_RSSI_STATE_STAY_MEDIUM)) { - if (smooth >= - (rssi_thresh1 + BT_FW_COEX_THRESH_TOL)) { - bt_rssi_state = BT_RSSI_STATE_HIGH; - rtlpcipriv->bt_coexist.cstate - |= BT_COEX_STATE_WIFI_RSSI_HIGH; - rtlpcipriv->bt_coexist.cstate - &= ~BT_COEX_STATE_WIFI_RSSI_LOW; - rtlpcipriv->bt_coexist.cstate - &= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI state switch to High\n"); - } else if (smooth < rssi_thresh) { - bt_rssi_state = BT_RSSI_STATE_LOW; - rtlpcipriv->bt_coexist.cstate - |= BT_COEX_STATE_WIFI_RSSI_LOW; - rtlpcipriv->bt_coexist.cstate - &= ~BT_COEX_STATE_WIFI_RSSI_HIGH; - rtlpcipriv->bt_coexist.cstate - &= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI state switch to Low\n"); - } else { - bt_rssi_state = BT_RSSI_STATE_STAY_MEDIUM; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI state stay at Medium\n"); - } - } else { - if (smooth < rssi_thresh1) { - bt_rssi_state = BT_RSSI_STATE_MEDIUM; - rtlpcipriv->bt_coexist.cstate - |= BT_COEX_STATE_WIFI_RSSI_MEDIUM; - rtlpcipriv->bt_coexist.cstate - &= ~BT_COEX_STATE_WIFI_RSSI_HIGH; - rtlpcipriv->bt_coexist.cstate - &= ~BT_COEX_STATE_WIFI_RSSI_LOW; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI state switch to Medium\n"); - } else { - bt_rssi_state = BT_RSSI_STATE_STAY_HIGH; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], RSSI state stay at High\n"); - } - } - } - - rtlpcipriv->bt_coexist.bt_pre_rssi_state = bt_rssi_state; - return bt_rssi_state; -} - -long rtl8723ae_dm_bt_get_rx_ss(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - long smooth = 0; - - if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) - smooth = GET_UNDECORATED_AVERAGE_RSSI(rtlpriv); - else - smooth = rtlpriv->dm.entry_min_undec_sm_pwdb; - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "rtl8723ae_dm_bt_get_rx_ss() = %ld\n", smooth); - - return smooth; -} - -void rtl8723ae_dm_bt_balance(struct ieee80211_hw *hw, - bool balance_on, u8 ms0, u8 ms1) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 h2c_parameter[3] = {0}; - - if (balance_on) { - h2c_parameter[2] = 1; - h2c_parameter[1] = ms1; - h2c_parameter[0] = ms0; - rtlpcipriv->bt_coexist.fw_coexist_all_off = false; - } else { - h2c_parameter[2] = 0; - h2c_parameter[1] = 0; - h2c_parameter[0] = 0; - } - rtlpcipriv->bt_coexist.balance_on = balance_on; - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[DM][BT], Balance=[%s:%dms:%dms], write 0xc=0x%x\n", - balance_on ? "ON" : "OFF", ms0, ms1, - h2c_parameter[0]<<16 | h2c_parameter[1]<<8 | h2c_parameter[2]); - - rtl8723ae_fill_h2c_cmd(hw, 0xc, 3, h2c_parameter); -} - - -void rtl8723ae_dm_bt_agc_table(struct ieee80211_hw *hw, u8 type) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - - if (type == BT_AGCTABLE_OFF) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BT]AGCTable Off!\n"); - rtl_write_dword(rtlpriv, 0xc78, 0x641c0001); - rtl_write_dword(rtlpriv, 0xc78, 0x631d0001); - rtl_write_dword(rtlpriv, 0xc78, 0x621e0001); - rtl_write_dword(rtlpriv, 0xc78, 0x611f0001); - rtl_write_dword(rtlpriv, 0xc78, 0x60200001); - - rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, - RF_RX_AGC_HP, 0xfffff, 0x32000); - rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, - RF_RX_AGC_HP, 0xfffff, 0x71000); - rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, - RF_RX_AGC_HP, 0xfffff, 0xb0000); - rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, - RF_RX_AGC_HP, 0xfffff, 0xfc000); - rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, - RF_RX_G1, 0xfffff, 0x30355); - } else if (type == BT_AGCTABLE_ON) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BT]AGCTable On!\n"); - rtl_write_dword(rtlpriv, 0xc78, 0x4e1c0001); - rtl_write_dword(rtlpriv, 0xc78, 0x4d1d0001); - rtl_write_dword(rtlpriv, 0xc78, 0x4c1e0001); - rtl_write_dword(rtlpriv, 0xc78, 0x4b1f0001); - rtl_write_dword(rtlpriv, 0xc78, 0x4a200001); - - rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, - RF_RX_AGC_HP, 0xfffff, 0xdc000); - rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, - RF_RX_AGC_HP, 0xfffff, 0x90000); - rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, - RF_RX_AGC_HP, 0xfffff, 0x51000); - rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, - RF_RX_AGC_HP, 0xfffff, 0x12000); - rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, - RF_RX_G1, 0xfffff, 0x00355); - - rtlpcipriv->bt_coexist.sw_coexist_all_off = false; - } -} - -void rtl8723ae_dm_bt_bback_off_level(struct ieee80211_hw *hw, u8 type) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - - if (type == BT_BB_BACKOFF_OFF) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BT]BBBackOffLevel Off!\n"); - rtl_write_dword(rtlpriv, 0xc04, 0x3a05611); - } else if (type == BT_BB_BACKOFF_ON) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BT]BBBackOffLevel On!\n"); - rtl_write_dword(rtlpriv, 0xc04, 0x3a07611); - rtlpcipriv->bt_coexist.sw_coexist_all_off = false; - } -} - -void rtl8723ae_dm_bt_fw_coex_all_off(struct ieee80211_hw *hw) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "rtl8723ae_dm_bt_fw_coex_all_off()\n"); - - if (rtlpcipriv->bt_coexist.fw_coexist_all_off) - return; - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "rtl8723ae_dm_bt_fw_coex_all_off(), real Do\n"); - rtl8723ae_dm_bt_fw_coex_all_off_8723a(hw); - rtlpcipriv->bt_coexist.fw_coexist_all_off = true; -} - -void rtl8723ae_dm_bt_sw_coex_all_off(struct ieee80211_hw *hw) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "rtl8723ae_dm_bt_sw_coex_all_off()\n"); - - if (rtlpcipriv->bt_coexist.sw_coexist_all_off) - return; - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "rtl8723ae_dm_bt_sw_coex_all_off(), real Do\n"); - rtl8723ae_dm_bt_sw_coex_all_off_8723a(hw); - rtlpcipriv->bt_coexist.sw_coexist_all_off = true; -} - -void rtl8723ae_dm_bt_hw_coex_all_off(struct ieee80211_hw *hw) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "rtl8723ae_dm_bt_hw_coex_all_off()\n"); - - if (rtlpcipriv->bt_coexist.hw_coexist_all_off) - return; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "rtl8723ae_dm_bt_hw_coex_all_off(), real Do\n"); - - rtl8723ae_dm_bt_hw_coex_all_off_8723a(hw); - - rtlpcipriv->bt_coexist.hw_coexist_all_off = true; -} - -void rtl8723ae_btdm_coex_all_off(struct ieee80211_hw *hw) -{ - rtl8723ae_dm_bt_fw_coex_all_off(hw); - rtl8723ae_dm_bt_sw_coex_all_off(hw); - rtl8723ae_dm_bt_hw_coex_all_off(hw); -} - -bool rtl8723ae_dm_bt_is_coexist_state_changed(struct ieee80211_hw *hw) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - - if ((rtlpcipriv->bt_coexist.previous_state == - rtlpcipriv->bt_coexist.cstate) && - (rtlpcipriv->bt_coexist.previous_state_h == - rtlpcipriv->bt_coexist.cstate_h)) - return false; - else - return true; -} - -bool rtl8723ae_dm_bt_is_wifi_up_link(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - if (rtlpriv->link_info.tx_busy_traffic) - return true; - else - return false; -} diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.h deleted file mode 100644 index 76f4d122dbc1..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hal_bt_coexist.h +++ /dev/null @@ -1,160 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL8723E_HAL_BT_COEXIST_H__ -#define __RTL8723E_HAL_BT_COEXIST_H__ - -#include "../wifi.h" - -/* The reg define is for 8723 */ -#define REG_HIGH_PRIORITY_TXRX 0x770 -#define REG_LOW_PRIORITY_TXRX 0x774 - -#define BT_FW_COEX_THRESH_TOL 6 -#define BT_FW_COEX_THRESH_20 20 -#define BT_FW_COEX_THRESH_23 23 -#define BT_FW_COEX_THRESH_25 25 -#define BT_FW_COEX_THRESH_30 30 -#define BT_FW_COEX_THRESH_35 35 -#define BT_FW_COEX_THRESH_40 40 -#define BT_FW_COEX_THRESH_45 45 -#define BT_FW_COEX_THRESH_47 47 -#define BT_FW_COEX_THRESH_50 50 -#define BT_FW_COEX_THRESH_55 55 - -#define BT_COEX_STATE_BT30 BIT(0) -#define BT_COEX_STATE_WIFI_HT20 BIT(1) -#define BT_COEX_STATE_WIFI_HT40 BIT(2) -#define BT_COEX_STATE_WIFI_LEGACY BIT(3) - -#define BT_COEX_STATE_WIFI_RSSI_LOW BIT(4) -#define BT_COEX_STATE_WIFI_RSSI_MEDIUM BIT(5) -#define BT_COEX_STATE_WIFI_RSSI_HIGH BIT(6) -#define BT_COEX_STATE_DEC_BT_POWER BIT(7) - -#define BT_COEX_STATE_WIFI_IDLE BIT(8) -#define BT_COEX_STATE_WIFI_UPLINK BIT(9) -#define BT_COEX_STATE_WIFI_DOWNLINK BIT(10) - -#define BT_COEX_STATE_BT_INQ_PAGE BIT(11) -#define BT_COEX_STATE_BT_IDLE BIT(12) -#define BT_COEX_STATE_BT_UPLINK BIT(13) -#define BT_COEX_STATE_BT_DOWNLINK BIT(14) - -#define BT_COEX_STATE_HOLD_FOR_BT_OPERATION BIT(15) -#define BT_COEX_STATE_BT_RSSI_LOW BIT(19) - -#define BT_COEX_STATE_PROFILE_HID BIT(20) -#define BT_COEX_STATE_PROFILE_A2DP BIT(21) -#define BT_COEX_STATE_PROFILE_PAN BIT(22) -#define BT_COEX_STATE_PROFILE_SCO BIT(23) - -#define BT_COEX_STATE_WIFI_RSSI_1_LOW BIT(24) -#define BT_COEX_STATE_WIFI_RSSI_1_MEDIUM BIT(25) -#define BT_COEX_STATE_WIFI_RSSI_1_HIGH BIT(26) - -#define BT_COEX_STATE_BTINFO_COMMON BIT(30) -#define BT_COEX_STATE_BTINFO_B_HID_SCOESCO BIT(31) -#define BT_COEX_STATE_BTINFO_B_FTP_A2DP BIT(29) - -#define BT_COEX_STATE_BT_CNT_LEVEL_0 BIT(0) -#define BT_COEX_STATE_BT_CNT_LEVEL_1 BIT(1) -#define BT_COEX_STATE_BT_CNT_LEVEL_2 BIT(2) -#define BT_COEX_STATE_BT_CNT_LEVEL_3 BIT(3) - -#define BT_RSSI_STATE_HIGH 0 -#define BT_RSSI_STATE_MEDIUM 1 -#define BT_RSSI_STATE_LOW 2 -#define BT_RSSI_STATE_STAY_HIGH 3 -#define BT_RSSI_STATE_STAY_MEDIUM 4 -#define BT_RSSI_STATE_STAY_LOW 5 - -#define BT_AGCTABLE_OFF 0 -#define BT_AGCTABLE_ON 1 -#define BT_BB_BACKOFF_OFF 0 -#define BT_BB_BACKOFF_ON 1 -#define BT_FW_NAV_OFF 0 -#define BT_FW_NAV_ON 1 - -#define BT_COEX_MECH_NONE 0 -#define BT_COEX_MECH_SCO 1 -#define BT_COEX_MECH_HID 2 -#define BT_COEX_MECH_A2DP 3 -#define BT_COEX_MECH_PAN 4 -#define BT_COEX_MECH_HID_A2DP 5 -#define BT_COEX_MECH_HID_PAN 6 -#define BT_COEX_MECH_PAN_A2DP 7 -#define BT_COEX_MECH_HID_SCO_ESCO 8 -#define BT_COEX_MECH_FTP_A2DP 9 -#define BT_COEX_MECH_COMMON 10 -#define BT_COEX_MECH_MAX 11 - -#define BT_DBG_PROFILE_NONE 0 -#define BT_DBG_PROFILE_SCO 1 -#define BT_DBG_PROFILE_HID 2 -#define BT_DBG_PROFILE_A2DP 3 -#define BT_DBG_PROFILE_PAN 4 -#define BT_DBG_PROFILE_HID_A2DP 5 -#define BT_DBG_PROFILE_HID_PAN 6 -#define BT_DBG_PROFILE_PAN_A2DP 7 -#define BT_DBG_PROFILE_MAX 9 - -#define BTINFO_B_FTP BIT(7) -#define BTINFO_B_A2DP BIT(6) -#define BTINFO_B_HID BIT(5) -#define BTINFO_B_SCO_BUSY BIT(4) -#define BTINFO_B_ACL_BUSY BIT(3) -#define BTINFO_B_INQ_PAGE BIT(2) -#define BTINFO_B_SCO_ESCO BIT(1) -#define BTINFO_B_CONNECTION BIT(0) - - -void rtl8723ae_btdm_coex_all_off(struct ieee80211_hw *hw); -void rtl8723ae_dm_bt_fw_coex_all_off(struct ieee80211_hw *hw); - -void rtl8723ae_dm_bt_sw_coex_all_off(struct ieee80211_hw *hw); -void rtl8723ae_dm_bt_hw_coex_all_off(struct ieee80211_hw *hw); -long rtl8723ae_dm_bt_get_rx_ss(struct ieee80211_hw *hw); -void rtl8723ae_dm_bt_balance(struct ieee80211_hw *hw, - bool balance_on, u8 ms0, u8 ms1); -void rtl8723ae_dm_bt_agc_table(struct ieee80211_hw *hw, u8 type); -void rtl8723ae_dm_bt_bback_off_level(struct ieee80211_hw *hw, u8 type); -u8 rtl8723ae_dm_bt_check_coex_rssi_state(struct ieee80211_hw *hw, - u8 level_num, u8 rssi_thresh, - u8 rssi_thresh1); -u8 rtl8723ae_dm_bt_check_coex_rssi_state1(struct ieee80211_hw *hw, - u8 level_num, u8 rssi_thresh, - u8 rssi_thresh1); -void _rtl8723_dm_bt_check_wifi_state(struct ieee80211_hw *hw); -void rtl8723ae_dm_bt_reject_ap_aggregated_packet(struct ieee80211_hw *hw, - bool reject); - -bool rtl8723ae_dm_bt_is_coexist_state_changed(struct ieee80211_hw *hw); -bool rtl8723ae_dm_bt_is_wifi_up_link(struct ieee80211_hw *hw); - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c deleted file mode 100644 index 887d521fe690..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c +++ /dev/null @@ -1,1786 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - **************************************************************************** - */ -#include "hal_btc.h" -#include "../pci.h" -#include "phy.h" -#include "fw.h" -#include "reg.h" -#include "def.h" - -void rtl8723ae_bt_coex_off_before_lps(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - - if (!rtlpcipriv->bt_coexist.bt_coexistence) - return; - - if (ppsc->inactiveps) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BT][DM], Before enter IPS, turn off all Coexist DM\n"); - rtlpcipriv->bt_coexist.cstate = 0; - rtlpcipriv->bt_coexist.previous_state = 0; - rtlpcipriv->bt_coexist.cstate_h = 0; - rtlpcipriv->bt_coexist.previous_state_h = 0; - rtl8723ae_btdm_coex_all_off(hw); - } -} - -static enum _RT_MEDIA_STATUS mgnt_link_status_query(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - enum _RT_MEDIA_STATUS m_status = RT_MEDIA_DISCONNECT; - - u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0; - - if (bibss || rtlpriv->mac80211.link_state >= MAC80211_LINKED) - m_status = RT_MEDIA_CONNECT; - - return m_status; -} - -void rtl_8723e_bt_wifi_media_status_notify(struct ieee80211_hw *hw, - bool mstatus) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - u8 h2c_parameter[3] = {0}; - u8 chnl; - - if (!rtlpcipriv->bt_coexist.bt_coexistence) - return; - - if (RT_MEDIA_CONNECT == mstatus) - h2c_parameter[0] = 0x1; /* 0: disconnected, 1:connected */ - else - h2c_parameter[0] = 0x0; - - if (mgnt_link_status_query(hw)) { - chnl = rtlphy->current_channel; - h2c_parameter[1] = chnl; - } - - if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) - h2c_parameter[2] = 0x30; - else - h2c_parameter[2] = 0x20; - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], FW write 0x19 = 0x%x\n", - h2c_parameter[0]<<16|h2c_parameter[1]<<8|h2c_parameter[2]); - - rtl8723ae_fill_h2c_cmd(hw, 0x19, 3, h2c_parameter); - -} - -static bool rtl8723ae_dm_bt_is_wifi_busy(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - if (rtlpriv->link_info.busytraffic || - rtlpriv->link_info.rx_busy_traffic || - rtlpriv->link_info.tx_busy_traffic) - return true; - else - return false; -} - -static void rtl8723ae_dm_bt_set_fw_3a(struct ieee80211_hw *hw, - u8 byte1, u8 byte2, u8 byte3, - u8 byte4, u8 byte5) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 h2c_parameter[5] = {0}; - - h2c_parameter[0] = byte1; - h2c_parameter[1] = byte2; - h2c_parameter[2] = byte3; - h2c_parameter[3] = byte4; - h2c_parameter[4] = byte5; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], FW write 0x3a(4bytes) = 0x%x%8x\n", - h2c_parameter[0], h2c_parameter[1]<<24 | h2c_parameter[2]<<16 | - h2c_parameter[3]<<8 | h2c_parameter[4]); - rtl8723ae_fill_h2c_cmd(hw, 0x3a, 5, h2c_parameter); -} - -static bool rtl8723ae_dm_bt_need_to_dec_bt_pwr(struct ieee80211_hw *hw) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - - if (mgnt_link_status_query(hw) == RT_MEDIA_CONNECT) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Need to decrease bt power\n"); - rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_DEC_BT_POWER; - return true; - } - - rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_DEC_BT_POWER; - return false; -} - -static bool rtl8723ae_dm_bt_is_same_coexist_state(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - - if ((rtlpcipriv->bt_coexist.previous_state == - rtlpcipriv->bt_coexist.cstate) && - (rtlpcipriv->bt_coexist.previous_state_h == - rtlpcipriv->bt_coexist.cstate_h)) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[DM][BT], Coexist state do not chang!!\n"); - return true; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[DM][BT], Coexist state changed!!\n"); - return false; - } -} - -static void rtl8723ae_dm_bt_set_coex_table(struct ieee80211_hw *hw, - u32 val_0x6c0, u32 val_0x6c8, - u32 val_0x6cc) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "set coex table, set 0x6c0 = 0x%x\n", val_0x6c0); - rtl_write_dword(rtlpriv, 0x6c0, val_0x6c0); - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "set coex table, set 0x6c8 = 0x%x\n", val_0x6c8); - rtl_write_dword(rtlpriv, 0x6c8, val_0x6c8); - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "set coex table, set 0x6cc = 0x%x\n", val_0x6cc); - rtl_write_byte(rtlpriv, 0x6cc, val_0x6cc); -} - -static void rtl8723ae_dm_bt_set_hw_pta_mode(struct ieee80211_hw *hw, bool mode) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - - if (BT_PTA_MODE_ON == mode) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, "PTA mode on, "); - /* Enable GPIO 0/1/2/3/8 pins for bt */ - rtl_write_byte(rtlpriv, 0x40, 0x20); - rtlpcipriv->bt_coexist.hw_coexist_all_off = false; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, "PTA mode off\n"); - rtl_write_byte(rtlpriv, 0x40, 0x0); - } -} - -static void rtl8723ae_dm_bt_set_sw_rf_rx_lpf_corner(struct ieee80211_hw *hw, - u8 type) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - - if (BT_RF_RX_LPF_CORNER_SHRINK == type) { - /* Shrink RF Rx LPF corner, 0x1e[7:4]=1111 ==> [11:4] by Jenyu*/ - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "Shrink RF Rx LPF corner!!\n"); - rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, 0x1e, 0xfffff, - 0xf0ff7); - rtlpcipriv->bt_coexist.sw_coexist_all_off = false; - } else if (BT_RF_RX_LPF_CORNER_RESUME == type) { - /*Resume RF Rx LPF corner*/ - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "Resume RF Rx LPF corner!!\n"); - rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A, 0x1e, 0xfffff, - rtlpcipriv->bt_coexist.bt_rfreg_origin_1e); - } -} - -static void rtl8723ae_bt_set_penalty_tx_rate_adap(struct ieee80211_hw *hw, - u8 ra_type) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - u8 tmu1; - - tmu1 = rtl_read_byte(rtlpriv, 0x4fd); - tmu1 |= BIT(0); - if (BT_TX_RATE_ADAPTIVE_LOW_PENALTY == ra_type) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "Tx rate adaptive, set low penalty!!\n"); - tmu1 &= ~BIT(2); - rtlpcipriv->bt_coexist.sw_coexist_all_off = false; - } else if (BT_TX_RATE_ADAPTIVE_NORMAL == ra_type) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "Tx rate adaptive, set normal!!\n"); - tmu1 |= BIT(2); - } - rtl_write_byte(rtlpriv, 0x4fd, tmu1); -} - -static void rtl8723ae_dm_bt_btdm_structure_reload(struct ieee80211_hw *hw, - struct btdm_8723 *btdm) -{ - btdm->all_off = false; - btdm->agc_table_en = false; - btdm->adc_back_off_on = false; - btdm->b2_ant_hid_en = false; - btdm->low_penalty_rate_adaptive = false; - btdm->rf_rx_lpf_shrink = false; - btdm->reject_aggre_pkt = false; - - btdm->tdma_on = false; - btdm->tdma_ant = TDMA_2ANT; - btdm->tdma_nav = TDMA_NAV_OFF; - btdm->tdma_dac_swing = TDMA_DAC_SWING_OFF; - btdm->fw_dac_swing_lvl = 0x20; - - btdm->tra_tdma_on = false; - btdm->tra_tdma_ant = TDMA_2ANT; - btdm->tra_tdma_nav = TDMA_NAV_OFF; - btdm->ignore_wlan_act = false; - - btdm->ps_tdma_on = false; - btdm->ps_tdma_byte[0] = 0x0; - btdm->ps_tdma_byte[1] = 0x0; - btdm->ps_tdma_byte[2] = 0x0; - btdm->ps_tdma_byte[3] = 0x8; - btdm->ps_tdma_byte[4] = 0x0; - - btdm->pta_on = true; - btdm->val_0x6c0 = 0x5a5aaaaa; - btdm->val_0x6c8 = 0xcc; - btdm->val_0x6cc = 0x3; - - btdm->sw_dac_swing_on = false; - btdm->sw_dac_swing_lvl = 0xc0; - btdm->wlan_act_hi = 0x20; - btdm->wlan_act_lo = 0x10; - btdm->bt_retry_index = 2; - - btdm->dec_bt_pwr = false; -} - -static void dm_bt_btdm_structure_reload_all_off(struct ieee80211_hw *hw, - struct btdm_8723 *btdm) -{ - rtl8723ae_dm_bt_btdm_structure_reload(hw, btdm); - btdm->all_off = true; - btdm->pta_on = false; - btdm->wlan_act_hi = 0x10; -} - -static bool rtl8723ae_dm_bt_is_2_ant_common_action(struct ieee80211_hw *hw) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct btdm_8723 btdm8723; - bool common = false; - - rtl8723ae_dm_bt_btdm_structure_reload(hw, &btdm8723); - - if (!rtl8723ae_dm_bt_is_wifi_busy(hw) - && !rtlpcipriv->bt_coexist.bt_busy) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Wifi idle + Bt idle, bt coex mechanism always off!!\n"); - dm_bt_btdm_structure_reload_all_off(hw, &btdm8723); - common = true; - } else if (rtl8723ae_dm_bt_is_wifi_busy(hw) - && !rtlpcipriv->bt_coexist.bt_busy) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Wifi non-idle + Bt disabled/idle!!\n"); - btdm8723.low_penalty_rate_adaptive = true; - btdm8723.rf_rx_lpf_shrink = false; - btdm8723.reject_aggre_pkt = false; - - /* sw mechanism */ - btdm8723.agc_table_en = false; - btdm8723.adc_back_off_on = false; - btdm8723.sw_dac_swing_on = false; - - btdm8723.pta_on = true; - btdm8723.val_0x6c0 = 0x5a5aaaaa; - btdm8723.val_0x6c8 = 0xcccc; - btdm8723.val_0x6cc = 0x3; - - btdm8723.tdma_on = false; - btdm8723.tdma_dac_swing = TDMA_DAC_SWING_OFF; - btdm8723.b2_ant_hid_en = false; - - common = true; - } else if (rtlpcipriv->bt_coexist.bt_busy) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Bt non-idle!\n"); - if (mgnt_link_status_query(hw) == RT_MEDIA_CONNECT) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Wifi connection exist\n"); - common = false; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "No Wifi connection!\n"); - btdm8723.rf_rx_lpf_shrink = true; - btdm8723.low_penalty_rate_adaptive = false; - btdm8723.reject_aggre_pkt = false; - - /* sw mechanism */ - btdm8723.agc_table_en = false; - btdm8723.adc_back_off_on = false; - btdm8723.sw_dac_swing_on = false; - - btdm8723.pta_on = true; - btdm8723.val_0x6c0 = 0x55555555; - btdm8723.val_0x6c8 = 0x0000ffff; - btdm8723.val_0x6cc = 0x3; - - btdm8723.tdma_on = false; - btdm8723.tdma_dac_swing = TDMA_DAC_SWING_OFF; - btdm8723.b2_ant_hid_en = false; - - common = true; - } - } - - if (rtl8723ae_dm_bt_need_to_dec_bt_pwr(hw)) - btdm8723.dec_bt_pwr = true; - - if (common) - rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_BTINFO_COMMON; - - if (common && rtl8723ae_dm_bt_is_coexist_state_changed(hw)) - rtl8723ae_dm_bt_set_bt_dm(hw, &btdm8723); - - return common; -} - -static void rtl8723ae_dm_bt_set_sw_full_time_dac_swing(struct ieee80211_hw *hw, - bool sw_dac_swing_on, - u32 sw_dac_swing_lvl) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - - if (sw_dac_swing_on) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], SwDacSwing = 0x%x\n", sw_dac_swing_lvl); - rtl8723ae_phy_set_bb_reg(hw, 0x880, 0xff000000, - sw_dac_swing_lvl); - rtlpcipriv->bt_coexist.sw_coexist_all_off = false; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], SwDacSwing Off!\n"); - rtl8723ae_phy_set_bb_reg(hw, 0x880, 0xff000000, 0xc0); - } -} - -static void rtl8723ae_dm_bt_set_fw_dec_bt_pwr(struct ieee80211_hw *hw, - bool dec_bt_pwr) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 h2c_parameter[1] = {0}; - - h2c_parameter[0] = 0; - - if (dec_bt_pwr) { - h2c_parameter[0] |= BIT(1); - rtlpcipriv->bt_coexist.fw_coexist_all_off = false; - } - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], decrease Bt Power : %s, write 0x21 = 0x%x\n", - (dec_bt_pwr ? "Yes!!" : "No!!"), h2c_parameter[0]); - - rtl8723ae_fill_h2c_cmd(hw, 0x21, 1, h2c_parameter); -} - -static void rtl8723ae_dm_bt_set_fw_2_ant_hid(struct ieee80211_hw *hw, - bool enable, bool dac_swing_on) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 h2c_parameter[1] = {0}; - - if (enable) { - h2c_parameter[0] |= BIT(0); - rtlpcipriv->bt_coexist.fw_coexist_all_off = false; - } - if (dac_swing_on) - h2c_parameter[0] |= BIT(1); /* Dac Swing default enable */ - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], turn 2-Ant+HID mode %s, DACSwing:%s, write 0x15 = 0x%x\n", - (enable ? "ON!!" : "OFF!!"), (dac_swing_on ? "ON" : "OFF"), - h2c_parameter[0]); - - rtl8723ae_fill_h2c_cmd(hw, 0x15, 1, h2c_parameter); -} - -static void rtl8723ae_dm_bt_set_fw_tdma_ctrl(struct ieee80211_hw *hw, - bool enable, u8 ant_num, u8 nav_en, - u8 dac_swing_en) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - u8 h2c_parameter[1] = {0}; - u8 h2c_parameter1[1] = {0}; - - h2c_parameter[0] = 0; - h2c_parameter1[0] = 0; - - if (enable) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], set BT PTA update manager to trigger update!!\n"); - h2c_parameter1[0] |= BIT(0); - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], turn TDMA mode ON!!\n"); - h2c_parameter[0] |= BIT(0); /* function enable */ - if (TDMA_1ANT == ant_num) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], TDMA_1ANT\n"); - h2c_parameter[0] |= BIT(1); - } else if (TDMA_2ANT == ant_num) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], TDMA_2ANT\n"); - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], Unknown Ant\n"); - } - - if (TDMA_NAV_OFF == nav_en) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], TDMA_NAV_OFF\n"); - } else if (TDMA_NAV_ON == nav_en) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], TDMA_NAV_ON\n"); - h2c_parameter[0] |= BIT(2); - } - - if (TDMA_DAC_SWING_OFF == dac_swing_en) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], TDMA_DAC_SWING_OFF\n"); - } else if (TDMA_DAC_SWING_ON == dac_swing_en) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], TDMA_DAC_SWING_ON\n"); - h2c_parameter[0] |= BIT(4); - } - rtlpcipriv->bt_coexist.fw_coexist_all_off = false; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], set BT PTA update manager to no update!!\n"); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], turn TDMA mode OFF!!\n"); - } - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], FW2AntTDMA, write 0x26 = 0x%x\n", - h2c_parameter1[0]); - rtl8723ae_fill_h2c_cmd(hw, 0x26, 1, h2c_parameter1); - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], FW2AntTDMA, write 0x14 = 0x%x\n", h2c_parameter[0]); - rtl8723ae_fill_h2c_cmd(hw, 0x14, 1, h2c_parameter); -} - -static void rtl8723ae_dm_bt_set_fw_ignore_wlan_act(struct ieee80211_hw *hw, - bool enable) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - u8 h2c_parameter[1] = {0}; - - if (enable) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], BT Ignore Wlan_Act !!\n"); - h2c_parameter[0] |= BIT(0); /* function enable */ - rtlpcipriv->bt_coexist.fw_coexist_all_off = false; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], BT don't ignore Wlan_Act !!\n"); - } - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], set FW for BT Ignore Wlan_Act, write 0x25 = 0x%x\n", - h2c_parameter[0]); - - rtl8723ae_fill_h2c_cmd(hw, 0x25, 1, h2c_parameter); -} - -static void rtl8723ae_dm_bt_set_fw_tra_tdma_ctrl(struct ieee80211_hw *hw, - bool enable, u8 ant_num, - u8 nav_en) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - u8 h2c_parameter[2] = {0}; - - /* Only 8723 B cut should do this */ - if (IS_VENDOR_8723_A_CUT(rtlhal->version)) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], not 8723B cut, don't set Traditional TDMA!!\n"); - return; - } - - if (enable) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], turn TTDMA mode ON!!\n"); - h2c_parameter[0] |= BIT(0); /* function enable */ - if (TDMA_1ANT == ant_num) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], TTDMA_1ANT\n"); - h2c_parameter[0] |= BIT(1); - } else if (TDMA_2ANT == ant_num) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], TTDMA_2ANT\n"); - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], Unknown Ant\n"); - } - - if (TDMA_NAV_OFF == nav_en) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], TTDMA_NAV_OFF\n"); - } else if (TDMA_NAV_ON == nav_en) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], TTDMA_NAV_ON\n"); - h2c_parameter[1] |= BIT(0); - } - - rtlpcipriv->bt_coexist.fw_coexist_all_off = false; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], turn TTDMA mode OFF!!\n"); - } - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], FW Traditional TDMA, write 0x33 = 0x%x\n", - h2c_parameter[0] << 8 | h2c_parameter[1]); - - rtl8723ae_fill_h2c_cmd(hw, 0x33, 2, h2c_parameter); -} - -static void rtl8723ae_dm_bt_set_fw_dac_swing_level(struct ieee80211_hw *hw, - u8 dac_swing_lvl) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 h2c_parameter[1] = {0}; - - h2c_parameter[0] = dac_swing_lvl; - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], Set Dac Swing Level = 0x%x\n", dac_swing_lvl); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], write 0x29 = 0x%x\n", h2c_parameter[0]); - - rtl8723ae_fill_h2c_cmd(hw, 0x29, 1, h2c_parameter); -} - -static void rtl8723ae_dm_bt_set_fw_bt_hid_info(struct ieee80211_hw *hw, - bool enable) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 h2c_parameter[1] = {0}; - - h2c_parameter[0] = 0; - - if (enable) { - h2c_parameter[0] |= BIT(0); - rtlpcipriv->bt_coexist.fw_coexist_all_off = false; - } - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], Set BT HID information = 0x%x\n", enable); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], write 0x24 = 0x%x\n", h2c_parameter[0]); - - rtl8723ae_fill_h2c_cmd(hw, 0x24, 1, h2c_parameter); -} - -static void rtl8723ae_dm_bt_set_fw_bt_retry_index(struct ieee80211_hw *hw, - u8 retry_index) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 h2c_parameter[1] = {0}; - - h2c_parameter[0] = retry_index; - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], Set BT Retry Index=%d\n", retry_index); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], write 0x23 = 0x%x\n", h2c_parameter[0]); - - rtl8723ae_fill_h2c_cmd(hw, 0x23, 1, h2c_parameter); -} - -static void rtl8723ae_dm_bt_set_fw_wlan_act(struct ieee80211_hw *hw, - u8 wlan_act_hi, u8 wlan_act_lo) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 h2c_parameter_hi[1] = {0}; - u8 h2c_parameter_lo[1] = {0}; - - h2c_parameter_hi[0] = wlan_act_hi; - h2c_parameter_lo[0] = wlan_act_lo; - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], Set WLAN_ACT Hi:Lo = 0x%x/0x%x\n", wlan_act_hi, - wlan_act_lo); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], write 0x22 = 0x%x\n", h2c_parameter_hi[0]); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], write 0x11 = 0x%x\n", h2c_parameter_lo[0]); - - /* WLAN_ACT = High duration, unit:ms */ - rtl8723ae_fill_h2c_cmd(hw, 0x22, 1, h2c_parameter_hi); - /* WLAN_ACT = Low duration, unit:3*625us */ - rtl8723ae_fill_h2c_cmd(hw, 0x11, 1, h2c_parameter_lo); -} - -void rtl8723ae_dm_bt_set_bt_dm(struct ieee80211_hw *hw, struct btdm_8723 *btdm) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtlpriv); - struct btdm_8723 *btdm_8723 = &rtlhal->hal_coex_8723.btdm; - u8 i; - bool fw_current_inpsmode = false; - bool fw_ps_awake = true; - - rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, - (u8 *)(&fw_current_inpsmode)); - rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, - (u8 *)(&fw_ps_awake)); - - /* check new setting is different than the old one, - * if all the same, don't do the setting again. - */ - if (memcmp(btdm_8723, btdm, sizeof(struct btdm_8723)) == 0) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], the same coexist setting, return!!\n"); - return; - } else { /* save the new coexist setting */ - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], UPDATE TO NEW COEX SETTING!!\n"); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new bAllOff = 0x%x/ 0x%x\n", - btdm_8723->all_off, btdm->all_off); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new agc_table_en = 0x%x/ 0x%x\n", - btdm_8723->agc_table_en, btdm->agc_table_en); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new adc_back_off_on = 0x%x/ 0x%x\n", - btdm_8723->adc_back_off_on, btdm->adc_back_off_on); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new b2_ant_hid_en = 0x%x/ 0x%x\n", - btdm_8723->b2_ant_hid_en, btdm->b2_ant_hid_en); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new bLowPenaltyRateAdaptive = 0x%x/ 0x%x\n", - btdm_8723->low_penalty_rate_adaptive, - btdm->low_penalty_rate_adaptive); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new bRfRxLpfShrink = 0x%x/ 0x%x\n", - btdm_8723->rf_rx_lpf_shrink, btdm->rf_rx_lpf_shrink); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new bRejectAggrePkt = 0x%x/ 0x%x\n", - btdm_8723->reject_aggre_pkt, btdm->reject_aggre_pkt); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new tdma_on = 0x%x/ 0x%x\n", - btdm_8723->tdma_on, btdm->tdma_on); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new tdmaAnt = 0x%x/ 0x%x\n", - btdm_8723->tdma_ant, btdm->tdma_ant); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new tdmaNav = 0x%x/ 0x%x\n", - btdm_8723->tdma_nav, btdm->tdma_nav); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new tdma_dac_swing = 0x%x/ 0x%x\n", - btdm_8723->tdma_dac_swing, btdm->tdma_dac_swing); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new fwDacSwingLvl = 0x%x/ 0x%x\n", - btdm_8723->fw_dac_swing_lvl, btdm->fw_dac_swing_lvl); - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new bTraTdmaOn = 0x%x/ 0x%x\n", - btdm_8723->tra_tdma_on, btdm->tra_tdma_on); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new traTdmaAnt = 0x%x/ 0x%x\n", - btdm_8723->tra_tdma_ant, btdm->tra_tdma_ant); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new traTdmaNav = 0x%x/ 0x%x\n", - btdm_8723->tra_tdma_nav, btdm->tra_tdma_nav); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new bPsTdmaOn = 0x%x/ 0x%x\n", - btdm_8723->ps_tdma_on, btdm->ps_tdma_on); - for (i = 0; i < 5; i++) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new psTdmaByte[i] = 0x%x/ 0x%x\n", - btdm_8723->ps_tdma_byte[i], - btdm->ps_tdma_byte[i]); - } - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new bIgnoreWlanAct = 0x%x/ 0x%x\n", - btdm_8723->ignore_wlan_act, btdm->ignore_wlan_act); - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new bPtaOn = 0x%x/ 0x%x\n", - btdm_8723->pta_on, btdm->pta_on); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new val_0x6c0 = 0x%x/ 0x%x\n", - btdm_8723->val_0x6c0, btdm->val_0x6c0); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new val_0x6c8 = 0x%x/ 0x%x\n", - btdm_8723->val_0x6c8, btdm->val_0x6c8); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new val_0x6cc = 0x%x/ 0x%x\n", - btdm_8723->val_0x6cc, btdm->val_0x6cc); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new sw_dac_swing_on = 0x%x/ 0x%x\n", - btdm_8723->sw_dac_swing_on, btdm->sw_dac_swing_on); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new sw_dac_swing_lvl = 0x%x/ 0x%x\n", - btdm_8723->sw_dac_swing_lvl, - btdm->sw_dac_swing_lvl); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new wlanActHi = 0x%x/ 0x%x\n", - btdm_8723->wlan_act_hi, btdm->wlan_act_hi); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new wlanActLo = 0x%x/ 0x%x\n", - btdm_8723->wlan_act_lo, btdm->wlan_act_lo); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], original/new btRetryIndex = 0x%x/ 0x%x\n", - btdm_8723->bt_retry_index, btdm->bt_retry_index); - - memcpy(btdm_8723, btdm, sizeof(struct btdm_8723)); - } - /* - * Here we only consider when Bt Operation - * inquiry/paging/pairing is ON - * we only need to turn off TDMA - */ - - if (rtlpcipriv->bt_coexist.hold_for_bt_operation) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], set to ignore wlanAct for BT OP!!\n"); - rtl8723ae_dm_bt_set_fw_ignore_wlan_act(hw, true); - return; - } - - if (btdm->all_off) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], disable all coexist mechanism !!\n"); - rtl8723ae_btdm_coex_all_off(hw); - return; - } - - rtl8723ae_dm_bt_reject_ap_aggregated_packet(hw, btdm->reject_aggre_pkt); - - if (btdm->low_penalty_rate_adaptive) - rtl8723ae_bt_set_penalty_tx_rate_adap(hw, - BT_TX_RATE_ADAPTIVE_LOW_PENALTY); - else - rtl8723ae_bt_set_penalty_tx_rate_adap(hw, - BT_TX_RATE_ADAPTIVE_NORMAL); - - if (btdm->rf_rx_lpf_shrink) - rtl8723ae_dm_bt_set_sw_rf_rx_lpf_corner(hw, - BT_RF_RX_LPF_CORNER_SHRINK); - else - rtl8723ae_dm_bt_set_sw_rf_rx_lpf_corner(hw, - BT_RF_RX_LPF_CORNER_RESUME); - - if (btdm->agc_table_en) - rtl8723ae_dm_bt_agc_table(hw, BT_AGCTABLE_ON); - else - rtl8723ae_dm_bt_agc_table(hw, BT_AGCTABLE_OFF); - - if (btdm->adc_back_off_on) - rtl8723ae_dm_bt_bback_off_level(hw, BT_BB_BACKOFF_ON); - else - rtl8723ae_dm_bt_bback_off_level(hw, BT_BB_BACKOFF_OFF); - - rtl8723ae_dm_bt_set_fw_bt_retry_index(hw, btdm->bt_retry_index); - - rtl8723ae_dm_bt_set_fw_dac_swing_level(hw, btdm->fw_dac_swing_lvl); - rtl8723ae_dm_bt_set_fw_wlan_act(hw, btdm->wlan_act_hi, - btdm->wlan_act_lo); - - rtl8723ae_dm_bt_set_coex_table(hw, btdm->val_0x6c0, - btdm->val_0x6c8, btdm->val_0x6cc); - rtl8723ae_dm_bt_set_hw_pta_mode(hw, btdm->pta_on); - - /* Note: There is a constraint between TDMA and 2AntHID - * Only one of 2AntHid and tdma can be turned on - * We should turn off those mechanisms first - * and then turn on them on. - */ - if (btdm->b2_ant_hid_en) { - /* turn off tdma */ - rtl8723ae_dm_bt_set_fw_tra_tdma_ctrl(hw, btdm->tra_tdma_on, - btdm->tra_tdma_ant, - btdm->tra_tdma_nav); - rtl8723ae_dm_bt_set_fw_tdma_ctrl(hw, false, btdm->tdma_ant, - btdm->tdma_nav, - btdm->tdma_dac_swing); - - /* turn off Pstdma */ - rtl8723ae_dm_bt_set_fw_ignore_wlan_act(hw, - btdm->ignore_wlan_act); - /* Antenna control by PTA, 0x870 = 0x300. */ - rtl8723ae_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0); - - /* turn on 2AntHid */ - rtl8723ae_dm_bt_set_fw_bt_hid_info(hw, true); - rtl8723ae_dm_bt_set_fw_2_ant_hid(hw, true, true); - } else if (btdm->tdma_on) { - /* turn off 2AntHid */ - rtl8723ae_dm_bt_set_fw_bt_hid_info(hw, false); - rtl8723ae_dm_bt_set_fw_2_ant_hid(hw, false, false); - - /* turn off pstdma */ - rtl8723ae_dm_bt_set_fw_ignore_wlan_act(hw, - btdm->ignore_wlan_act); - /* Antenna control by PTA, 0x870 = 0x300. */ - rtl8723ae_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0); - - /* turn on tdma */ - rtl8723ae_dm_bt_set_fw_tra_tdma_ctrl(hw, btdm->tra_tdma_on, - btdm->tra_tdma_ant, btdm->tra_tdma_nav); - rtl8723ae_dm_bt_set_fw_tdma_ctrl(hw, true, btdm->tdma_ant, - btdm->tdma_nav, btdm->tdma_dac_swing); - } else if (btdm->ps_tdma_on) { - /* turn off 2AntHid */ - rtl8723ae_dm_bt_set_fw_bt_hid_info(hw, false); - rtl8723ae_dm_bt_set_fw_2_ant_hid(hw, false, false); - - /* turn off tdma */ - rtl8723ae_dm_bt_set_fw_tra_tdma_ctrl(hw, btdm->tra_tdma_on, - btdm->tra_tdma_ant, btdm->tra_tdma_nav); - rtl8723ae_dm_bt_set_fw_tdma_ctrl(hw, false, btdm->tdma_ant, - btdm->tdma_nav, btdm->tdma_dac_swing); - - /* turn on pstdma */ - rtl8723ae_dm_bt_set_fw_ignore_wlan_act(hw, - btdm->ignore_wlan_act); - rtl8723ae_dm_bt_set_fw_3a(hw, - btdm->ps_tdma_byte[0], - btdm->ps_tdma_byte[1], - btdm->ps_tdma_byte[2], - btdm->ps_tdma_byte[3], - btdm->ps_tdma_byte[4]); - } else { - /* turn off 2AntHid */ - rtl8723ae_dm_bt_set_fw_bt_hid_info(hw, false); - rtl8723ae_dm_bt_set_fw_2_ant_hid(hw, false, false); - - /* turn off tdma */ - rtl8723ae_dm_bt_set_fw_tra_tdma_ctrl(hw, btdm->tra_tdma_on, - btdm->tra_tdma_ant, btdm->tra_tdma_nav); - rtl8723ae_dm_bt_set_fw_tdma_ctrl(hw, false, btdm->tdma_ant, - btdm->tdma_nav, btdm->tdma_dac_swing); - - /* turn off pstdma */ - rtl8723ae_dm_bt_set_fw_ignore_wlan_act(hw, - btdm->ignore_wlan_act); - /* Antenna control by PTA, 0x870 = 0x300. */ - rtl8723ae_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0); - } - - /* Note: - * We should add delay for making sure sw DacSwing can be set - * sucessfully. Because of that rtl8723ae_dm_bt_set_fw_2_ant_hid() - * and rtl8723ae_dm_bt_set_fw_tdma_ctrl() - * will overwrite the reg 0x880. - */ - mdelay(30); - rtl8723ae_dm_bt_set_sw_full_time_dac_swing(hw, - btdm->sw_dac_swing_on, btdm->sw_dac_swing_lvl); - rtl8723ae_dm_bt_set_fw_dec_bt_pwr(hw, btdm->dec_bt_pwr); -} - -/*============================================================ - * extern function start with BTDM_ - *============================================================ - */ -static u32 rtl8723ae_dm_bt_tx_rx_couter_h(struct ieee80211_hw *hw) -{ - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - u32 counters = 0; - - counters = rtlhal->hal_coex_8723.high_priority_tx + - rtlhal->hal_coex_8723.high_priority_rx; - return counters; -} - -static u32 rtl8723ae_dm_bt_tx_rx_couter_l(struct ieee80211_hw *hw) -{ - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - return rtlhal->hal_coex_8723.low_priority_tx + - rtlhal->hal_coex_8723.low_priority_rx; -} - -static u8 rtl8723ae_dm_bt_bt_tx_rx_counter_level(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - u32 bt_tx_rx_cnt = 0; - u8 bt_tx_rx_cnt_lvl = 0; - - bt_tx_rx_cnt = rtl8723ae_dm_bt_tx_rx_couter_h(hw) + - rtl8723ae_dm_bt_tx_rx_couter_l(hw); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters = %d\n", bt_tx_rx_cnt); - - rtlpcipriv->bt_coexist.cstate_h &= - ~(BT_COEX_STATE_BT_CNT_LEVEL_0 | BT_COEX_STATE_BT_CNT_LEVEL_1 | - BT_COEX_STATE_BT_CNT_LEVEL_2); - - if (bt_tx_rx_cnt >= BT_TXRX_CNT_THRES_3) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters at level 3\n"); - bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_3; - rtlpcipriv->bt_coexist.cstate_h |= BT_COEX_STATE_BT_CNT_LEVEL_3; - } else if (bt_tx_rx_cnt >= BT_TXRX_CNT_THRES_2) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters at level 2\n"); - bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_2; - rtlpcipriv->bt_coexist.cstate_h |= BT_COEX_STATE_BT_CNT_LEVEL_2; - } else if (bt_tx_rx_cnt >= BT_TXRX_CNT_THRES_1) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters at level 1\n"); - bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_1; - rtlpcipriv->bt_coexist.cstate_h |= BT_COEX_STATE_BT_CNT_LEVEL_1; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters at level 0\n"); - bt_tx_rx_cnt_lvl = BT_TXRX_CNT_LEVEL_0; - rtlpcipriv->bt_coexist.cstate_h |= BT_COEX_STATE_BT_CNT_LEVEL_0; - } - return bt_tx_rx_cnt_lvl; -} - -static void rtl8723ae_dm_bt_2_ant_hid_sco_esco(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtlpriv); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct btdm_8723 btdm8723; - u8 bt_rssi_state, bt_rssi_state1; - u8 bt_tx_rx_cnt_lvl; - - rtl8723ae_dm_bt_btdm_structure_reload(hw, &btdm8723); - - btdm8723.rf_rx_lpf_shrink = true; - btdm8723.low_penalty_rate_adaptive = true; - btdm8723.reject_aggre_pkt = false; - - bt_tx_rx_cnt_lvl = rtl8723ae_dm_bt_bt_tx_rx_counter_level(hw); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters = %d\n", bt_tx_rx_cnt_lvl); - - if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, "HT40\n"); - /* coex table */ - btdm8723.val_0x6c0 = 0x55555555; - btdm8723.val_0x6c8 = 0xffff; - btdm8723.val_0x6cc = 0x3; - - /* sw mechanism */ - btdm8723.agc_table_en = false; - btdm8723.adc_back_off_on = false; - btdm8723.sw_dac_swing_on = false; - - /* fw mechanism */ - btdm8723.ps_tdma_on = true; - if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters >= 1400\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0x5; - btdm8723.ps_tdma_byte[2] = 0x5; - btdm8723.ps_tdma_byte[3] = 0x2; - btdm8723.ps_tdma_byte[4] = 0x80; - } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0xa; - btdm8723.ps_tdma_byte[2] = 0xa; - btdm8723.ps_tdma_byte[3] = 0x2; - btdm8723.ps_tdma_byte[4] = 0x80; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters < 1200\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0xf; - btdm8723.ps_tdma_byte[2] = 0xf; - btdm8723.ps_tdma_byte[3] = 0x2; - btdm8723.ps_tdma_byte[4] = 0x80; - } - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "HT20 or Legacy\n"); - bt_rssi_state = rtl8723ae_dm_bt_check_coex_rssi_state(hw, 2, - 47, 0); - bt_rssi_state1 = rtl8723ae_dm_bt_check_coex_rssi_state1(hw, 2, - 27, 0); - - /* coex table */ - btdm8723.val_0x6c0 = 0x55555555; - btdm8723.val_0x6c8 = 0xffff; - btdm8723.val_0x6cc = 0x3; - - /* sw mechanism */ - if ((bt_rssi_state == BT_RSSI_STATE_HIGH) || - (bt_rssi_state == BT_RSSI_STATE_STAY_HIGH)) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Wifi rssi high\n"); - btdm8723.agc_table_en = true; - btdm8723.adc_back_off_on = true; - btdm8723.sw_dac_swing_on = false; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Wifi rssi low\n"); - btdm8723.agc_table_en = false; - btdm8723.adc_back_off_on = false; - btdm8723.sw_dac_swing_on = false; - } - - /* fw mechanism */ - btdm8723.ps_tdma_on = true; - if ((bt_rssi_state1 == BT_RSSI_STATE_HIGH) || - (bt_rssi_state1 == BT_RSSI_STATE_STAY_HIGH)) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Wifi rssi-1 high\n"); - /* only rssi high we need to do this, - * when rssi low, the value will modified by fw - */ - rtl_write_byte(rtlpriv, 0x883, 0x40); - if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters >= 1400\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0x5; - btdm8723.ps_tdma_byte[2] = 0x5; - btdm8723.ps_tdma_byte[3] = 0x83; - btdm8723.ps_tdma_byte[4] = 0x80; - } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0xa; - btdm8723.ps_tdma_byte[2] = 0xa; - btdm8723.ps_tdma_byte[3] = 0x83; - btdm8723.ps_tdma_byte[4] = 0x80; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters < 1200\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0xf; - btdm8723.ps_tdma_byte[2] = 0xf; - btdm8723.ps_tdma_byte[3] = 0x83; - btdm8723.ps_tdma_byte[4] = 0x80; - } - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Wifi rssi-1 low\n"); - if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters >= 1400\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0x5; - btdm8723.ps_tdma_byte[2] = 0x5; - btdm8723.ps_tdma_byte[3] = 0x2; - btdm8723.ps_tdma_byte[4] = 0x80; - } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0xa; - btdm8723.ps_tdma_byte[2] = 0xa; - btdm8723.ps_tdma_byte[3] = 0x2; - btdm8723.ps_tdma_byte[4] = 0x80; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters < 1200\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0xf; - btdm8723.ps_tdma_byte[2] = 0xf; - btdm8723.ps_tdma_byte[3] = 0x2; - btdm8723.ps_tdma_byte[4] = 0x80; - } - } - } - - if (rtl8723ae_dm_bt_need_to_dec_bt_pwr(hw)) - btdm8723.dec_bt_pwr = true; - - /* Always ignore WlanAct if bHid|bSCOBusy|bSCOeSCO */ - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT btInqPageStartTime = 0x%x, btTxRxCntLvl = %d\n", - rtlhal->hal_coex_8723.bt_inq_page_start_time, - bt_tx_rx_cnt_lvl); - if ((rtlhal->hal_coex_8723.bt_inq_page_start_time) || - (BT_TXRX_CNT_LEVEL_3 == bt_tx_rx_cnt_lvl)) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], Set BT inquiry / page scan 0x3a setting\n"); - btdm8723.ps_tdma_on = true; - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0x5; - btdm8723.ps_tdma_byte[2] = 0x5; - btdm8723.ps_tdma_byte[3] = 0x2; - btdm8723.ps_tdma_byte[4] = 0x80; - } - - if (rtl8723ae_dm_bt_is_coexist_state_changed(hw)) - rtl8723ae_dm_bt_set_bt_dm(hw, &btdm8723); -} - -static void rtl8723ae_dm_bt_2_ant_fta2dp(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtlpriv); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct btdm_8723 btdm8723; - u8 bt_rssi_state, bt_rssi_state1; - u32 bt_tx_rx_cnt_lvl; - - rtl8723ae_dm_bt_btdm_structure_reload(hw, &btdm8723); - btdm8723.rf_rx_lpf_shrink = true; - btdm8723.low_penalty_rate_adaptive = true; - btdm8723.reject_aggre_pkt = false; - - bt_tx_rx_cnt_lvl = rtl8723ae_dm_bt_bt_tx_rx_counter_level(hw); - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters = %d\n", bt_tx_rx_cnt_lvl); - - if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, "HT40\n"); - bt_rssi_state = rtl8723ae_dm_bt_check_coex_rssi_state(hw, 2, - 37, 0); - - /* coex table */ - btdm8723.val_0x6c0 = 0x55555555; - btdm8723.val_0x6c8 = 0xffff; - btdm8723.val_0x6cc = 0x3; - - /* sw mechanism */ - btdm8723.agc_table_en = false; - btdm8723.adc_back_off_on = true; - btdm8723.sw_dac_swing_on = false; - - /* fw mechanism */ - btdm8723.ps_tdma_on = true; - if ((bt_rssi_state == BT_RSSI_STATE_HIGH) || - (bt_rssi_state == BT_RSSI_STATE_STAY_HIGH)) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Wifi rssi high\n"); - if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters >= 1400\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0x5; - btdm8723.ps_tdma_byte[2] = 0x5; - btdm8723.ps_tdma_byte[3] = 0x81; - btdm8723.ps_tdma_byte[4] = 0x80; - } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0xa; - btdm8723.ps_tdma_byte[2] = 0xa; - btdm8723.ps_tdma_byte[3] = 0x81; - btdm8723.ps_tdma_byte[4] = 0x80; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters < 1200\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0xf; - btdm8723.ps_tdma_byte[2] = 0xf; - btdm8723.ps_tdma_byte[3] = 0x81; - btdm8723.ps_tdma_byte[4] = 0x80; - } - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Wifi rssi low\n"); - if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters >= 1400\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0x5; - btdm8723.ps_tdma_byte[2] = 0x5; - btdm8723.ps_tdma_byte[3] = 0x0; - btdm8723.ps_tdma_byte[4] = 0x80; - } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0xa; - btdm8723.ps_tdma_byte[2] = 0xa; - btdm8723.ps_tdma_byte[3] = 0x0; - btdm8723.ps_tdma_byte[4] = 0x80; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters < 1200\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0xf; - btdm8723.ps_tdma_byte[2] = 0xf; - btdm8723.ps_tdma_byte[3] = 0x0; - btdm8723.ps_tdma_byte[4] = 0x80; - } - } - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "HT20 or Legacy\n"); - bt_rssi_state = rtl8723ae_dm_bt_check_coex_rssi_state(hw, 2, - 47, 0); - bt_rssi_state1 = rtl8723ae_dm_bt_check_coex_rssi_state1(hw, 2, - 27, 0); - - /* coex table */ - btdm8723.val_0x6c0 = 0x55555555; - btdm8723.val_0x6c8 = 0xffff; - btdm8723.val_0x6cc = 0x3; - - /* sw mechanism */ - if ((bt_rssi_state == BT_RSSI_STATE_HIGH) || - (bt_rssi_state == BT_RSSI_STATE_STAY_HIGH)) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Wifi rssi high\n"); - btdm8723.agc_table_en = true; - btdm8723.adc_back_off_on = true; - btdm8723.sw_dac_swing_on = false; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Wifi rssi low\n"); - btdm8723.agc_table_en = false; - btdm8723.adc_back_off_on = false; - btdm8723.sw_dac_swing_on = false; - } - - /* fw mechanism */ - btdm8723.ps_tdma_on = true; - if ((bt_rssi_state1 == BT_RSSI_STATE_HIGH) || - (bt_rssi_state1 == BT_RSSI_STATE_STAY_HIGH)) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Wifi rssi-1 high\n"); - /* only rssi high we need to do this, - * when rssi low, the value will modified by fw - */ - rtl_write_byte(rtlpriv, 0x883, 0x40); - if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters >= 1400\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0x5; - btdm8723.ps_tdma_byte[2] = 0x5; - btdm8723.ps_tdma_byte[3] = 0x81; - btdm8723.ps_tdma_byte[4] = 0x80; - } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0xa; - btdm8723.ps_tdma_byte[2] = 0xa; - btdm8723.ps_tdma_byte[3] = 0x81; - btdm8723.ps_tdma_byte[4] = 0x80; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters < 1200\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0xf; - btdm8723.ps_tdma_byte[2] = 0xf; - btdm8723.ps_tdma_byte[3] = 0x81; - btdm8723.ps_tdma_byte[4] = 0x80; - } - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Wifi rssi-1 low\n"); - if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_2) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters >= 1400\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0x5; - btdm8723.ps_tdma_byte[2] = 0x5; - btdm8723.ps_tdma_byte[3] = 0x0; - btdm8723.ps_tdma_byte[4] = 0x80; - } else if (bt_tx_rx_cnt_lvl == BT_TXRX_CNT_LEVEL_1) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters >= 1200 && < 1400\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0xa; - btdm8723.ps_tdma_byte[2] = 0xa; - btdm8723.ps_tdma_byte[3] = 0x0; - btdm8723.ps_tdma_byte[4] = 0x80; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT TxRx Counters < 1200\n"); - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0xf; - btdm8723.ps_tdma_byte[2] = 0xf; - btdm8723.ps_tdma_byte[3] = 0x0; - btdm8723.ps_tdma_byte[4] = 0x80; - } - } - } - - if (rtl8723ae_dm_bt_need_to_dec_bt_pwr(hw)) - btdm8723.dec_bt_pwr = true; - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT btInqPageStartTime = 0x%x, btTxRxCntLvl = %d\n", - rtlhal->hal_coex_8723.bt_inq_page_start_time, - bt_tx_rx_cnt_lvl); - - if ((rtlhal->hal_coex_8723.bt_inq_page_start_time) || - (BT_TXRX_CNT_LEVEL_3 == bt_tx_rx_cnt_lvl)) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], Set BT inquiry / page scan 0x3a setting\n"); - btdm8723.ps_tdma_on = true; - btdm8723.ps_tdma_byte[0] = 0xa3; - btdm8723.ps_tdma_byte[1] = 0x5; - btdm8723.ps_tdma_byte[2] = 0x5; - btdm8723.ps_tdma_byte[3] = 0x83; - btdm8723.ps_tdma_byte[4] = 0x80; - } - - if (rtl8723ae_dm_bt_is_coexist_state_changed(hw)) - rtl8723ae_dm_bt_set_bt_dm(hw, &btdm8723); -} - -static void rtl8723ae_dm_bt_inq_page_monitor(struct ieee80211_hw *hw) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtlpriv); - u32 cur_time = jiffies; - - if (rtlhal->hal_coex_8723.c2h_bt_inquiry_page) { - /* bt inquiry or page is started. */ - if (rtlhal->hal_coex_8723.bt_inq_page_start_time == 0) { - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_BT_INQ_PAGE; - rtlhal->hal_coex_8723.bt_inq_page_start_time = cur_time; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT Inquiry/page is started at time : 0x%x\n", - rtlhal->hal_coex_8723.bt_inq_page_start_time); - } - } - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT Inquiry/page started time : 0x%x, cur_time : 0x%x\n", - rtlhal->hal_coex_8723.bt_inq_page_start_time, cur_time); - - if (rtlhal->hal_coex_8723.bt_inq_page_start_time) { - if ((((long)cur_time - - (long)rtlhal->hal_coex_8723.bt_inq_page_start_time) / HZ) >= - 10) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BT Inquiry/page >= 10sec!!!"); - rtlhal->hal_coex_8723.bt_inq_page_start_time = 0; - rtlpcipriv->bt_coexist.cstate &= - ~BT_COEX_STATE_BT_INQ_PAGE; - } - } -} - -static void rtl8723ae_dm_bt_reset_action_profile_state(struct ieee80211_hw *hw) -{ - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - - rtlpcipriv->bt_coexist.cstate &= - ~(BT_COEX_STATE_PROFILE_HID | BT_COEX_STATE_PROFILE_A2DP | - BT_COEX_STATE_PROFILE_PAN | BT_COEX_STATE_PROFILE_SCO); - - rtlpcipriv->bt_coexist.cstate &= - ~(BT_COEX_STATE_BTINFO_COMMON | - BT_COEX_STATE_BTINFO_B_HID_SCOESCO | - BT_COEX_STATE_BTINFO_B_FTP_A2DP); -} - -static void _rtl8723ae_dm_bt_coexist_2_ant(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtlpriv); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - u8 bt_retry_cnt; - u8 bt_info_original; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex] Get bt info by fw!!\n"); - - _rtl8723_dm_bt_check_wifi_state(hw); - - if (rtlhal->hal_coex_8723.c2h_bt_info_req_sent) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex] c2h for btInfo not rcvd yet!!\n"); - } - - bt_retry_cnt = rtlhal->hal_coex_8723.bt_retry_cnt; - bt_info_original = rtlhal->hal_coex_8723.c2h_bt_info_original; - - /* when bt inquiry or page scan, we have to set h2c 0x25 - * ignore wlanact for continuous 4x2secs - */ - rtl8723ae_dm_bt_inq_page_monitor(hw); - rtl8723ae_dm_bt_reset_action_profile_state(hw); - - if (rtl8723ae_dm_bt_is_2_ant_common_action(hw)) { - rtlpcipriv->bt_coexist.bt_profile_case = BT_COEX_MECH_COMMON; - rtlpcipriv->bt_coexist.bt_profile_action = BT_COEX_MECH_COMMON; - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Action 2-Ant common.\n"); - } else { - if ((bt_info_original & BTINFO_B_HID) || - (bt_info_original & BTINFO_B_SCO_BUSY) || - (bt_info_original & BTINFO_B_SCO_ESCO)) { - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_BTINFO_B_HID_SCOESCO; - rtlpcipriv->bt_coexist.bt_profile_case = - BT_COEX_MECH_HID_SCO_ESCO; - rtlpcipriv->bt_coexist.bt_profile_action = - BT_COEX_MECH_HID_SCO_ESCO; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BTInfo: bHid|bSCOBusy|bSCOeSCO\n"); - rtl8723ae_dm_bt_2_ant_hid_sco_esco(hw); - } else if ((bt_info_original & BTINFO_B_FTP) || - (bt_info_original & BTINFO_B_A2DP)) { - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_BTINFO_B_FTP_A2DP; - rtlpcipriv->bt_coexist.bt_profile_case = - BT_COEX_MECH_FTP_A2DP; - rtlpcipriv->bt_coexist.bt_profile_action = - BT_COEX_MECH_FTP_A2DP; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "BTInfo: bFTP|bA2DP\n"); - rtl8723ae_dm_bt_2_ant_fta2dp(hw); - } else { - rtlpcipriv->bt_coexist.cstate |= - BT_COEX_STATE_BTINFO_B_HID_SCOESCO; - rtlpcipriv->bt_coexist.bt_profile_case = - BT_COEX_MECH_NONE; - rtlpcipriv->bt_coexist.bt_profile_action = - BT_COEX_MECH_NONE; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], BTInfo: undefined case!!!!\n"); - rtl8723ae_dm_bt_2_ant_hid_sco_esco(hw); - } - } -} - -static void _rtl8723ae_dm_bt_coexist_1_ant(struct ieee80211_hw *hw) -{ -} - -void rtl8723ae_dm_bt_hw_coex_all_off_8723a(struct ieee80211_hw *hw) -{ - rtl8723ae_dm_bt_set_coex_table(hw, 0x5a5aaaaa, 0xcc, 0x3); - rtl8723ae_dm_bt_set_hw_pta_mode(hw, true); -} - -void rtl8723ae_dm_bt_fw_coex_all_off_8723a(struct ieee80211_hw *hw) -{ - rtl8723ae_dm_bt_set_fw_ignore_wlan_act(hw, false); - rtl8723ae_dm_bt_set_fw_3a(hw, 0x0, 0x0, 0x0, 0x8, 0x0); - rtl8723ae_dm_bt_set_fw_2_ant_hid(hw, false, false); - rtl8723ae_dm_bt_set_fw_tra_tdma_ctrl(hw, false, - TDMA_2ANT, TDMA_NAV_OFF); - rtl8723ae_dm_bt_set_fw_tdma_ctrl(hw, false, TDMA_2ANT, - TDMA_NAV_OFF, TDMA_DAC_SWING_OFF); - rtl8723ae_dm_bt_set_fw_dac_swing_level(hw, 0); - rtl8723ae_dm_bt_set_fw_bt_hid_info(hw, false); - rtl8723ae_dm_bt_set_fw_bt_retry_index(hw, 2); - rtl8723ae_dm_bt_set_fw_wlan_act(hw, 0x10, 0x10); - rtl8723ae_dm_bt_set_fw_dec_bt_pwr(hw, false); -} - -void rtl8723ae_dm_bt_sw_coex_all_off_8723a(struct ieee80211_hw *hw) -{ - rtl8723ae_dm_bt_agc_table(hw, BT_AGCTABLE_OFF); - rtl8723ae_dm_bt_bback_off_level(hw, BT_BB_BACKOFF_OFF); - rtl8723ae_dm_bt_reject_ap_aggregated_packet(hw, false); - - rtl8723ae_bt_set_penalty_tx_rate_adap(hw, BT_TX_RATE_ADAPTIVE_NORMAL); - rtl8723ae_dm_bt_set_sw_rf_rx_lpf_corner(hw, BT_RF_RX_LPF_CORNER_RESUME); - rtl8723ae_dm_bt_set_sw_full_time_dac_swing(hw, false, 0xc0); -} - -static void rtl8723ae_dm_bt_query_bt_information(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtlpriv); - u8 h2c_parameter[1] = {0}; - - rtlhal->hal_coex_8723.c2h_bt_info_req_sent = true; - - h2c_parameter[0] |= BIT(0); - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "Query Bt information, write 0x38 = 0x%x\n", - h2c_parameter[0]); - - rtl8723ae_fill_h2c_cmd(hw, 0x38, 1, h2c_parameter); -} - -static void rtl8723ae_dm_bt_bt_hw_counters_monitor(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtlpriv); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - u32 reg_htx_rx, reg_ltx_rx, u32_tmp; - u32 reg_htx, reg_hrx, reg_ltx, reg_lrx; - - reg_htx_rx = REG_HIGH_PRIORITY_TXRX; - reg_ltx_rx = REG_LOW_PRIORITY_TXRX; - - u32_tmp = rtl_read_dword(rtlpriv, reg_htx_rx); - reg_htx = u32_tmp & MASKLWORD; - reg_hrx = (u32_tmp & MASKHWORD)>>16; - - u32_tmp = rtl_read_dword(rtlpriv, reg_ltx_rx); - reg_ltx = u32_tmp & MASKLWORD; - reg_lrx = (u32_tmp & MASKHWORD)>>16; - - if (rtlpcipriv->bt_coexist.lps_counter > 1) { - reg_htx %= rtlpcipriv->bt_coexist.lps_counter; - reg_hrx %= rtlpcipriv->bt_coexist.lps_counter; - reg_ltx %= rtlpcipriv->bt_coexist.lps_counter; - reg_lrx %= rtlpcipriv->bt_coexist.lps_counter; - } - - rtlhal->hal_coex_8723.high_priority_tx = reg_htx; - rtlhal->hal_coex_8723.high_priority_rx = reg_hrx; - rtlhal->hal_coex_8723.low_priority_tx = reg_ltx; - rtlhal->hal_coex_8723.low_priority_rx = reg_lrx; - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "High Priority Tx/Rx (reg 0x%x)=%x(%d)/%x(%d)\n", - reg_htx_rx, reg_htx, reg_htx, reg_hrx, reg_hrx); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "Low Priority Tx/Rx (reg 0x%x)=%x(%d)/%x(%d)\n", - reg_ltx_rx, reg_ltx, reg_ltx, reg_lrx, reg_lrx); - rtlpcipriv->bt_coexist.lps_counter = 0; -} - -static void rtl8723ae_dm_bt_bt_enable_disable_check(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtlpriv); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - bool bt_alife = true; - - if (rtlhal->hal_coex_8723.high_priority_tx == 0 && - rtlhal->hal_coex_8723.high_priority_rx == 0 && - rtlhal->hal_coex_8723.low_priority_tx == 0 && - rtlhal->hal_coex_8723.low_priority_rx == 0) - bt_alife = false; - if (rtlhal->hal_coex_8723.high_priority_tx == 0xeaea && - rtlhal->hal_coex_8723.high_priority_rx == 0xeaea && - rtlhal->hal_coex_8723.low_priority_tx == 0xeaea && - rtlhal->hal_coex_8723.low_priority_rx == 0xeaea) - bt_alife = false; - if (rtlhal->hal_coex_8723.high_priority_tx == 0xffff && - rtlhal->hal_coex_8723.high_priority_rx == 0xffff && - rtlhal->hal_coex_8723.low_priority_tx == 0xffff && - rtlhal->hal_coex_8723.low_priority_rx == 0xffff) - bt_alife = false; - if (bt_alife) { - rtlpcipriv->bt_coexist.bt_active_zero_cnt = 0; - rtlpcipriv->bt_coexist.cur_bt_disabled = false; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "8723A BT is enabled !!\n"); - } else { - rtlpcipriv->bt_coexist.bt_active_zero_cnt++; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "8723A bt all counters = 0, %d times!!\n", - rtlpcipriv->bt_coexist.bt_active_zero_cnt); - if (rtlpcipriv->bt_coexist.bt_active_zero_cnt >= 2) { - rtlpcipriv->bt_coexist.cur_bt_disabled = true; - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "8723A BT is disabled !!\n"); - } - } - if (rtlpcipriv->bt_coexist.pre_bt_disabled != - rtlpcipriv->bt_coexist.cur_bt_disabled) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "8723A BT is from %s to %s!!\n", - (rtlpcipriv->bt_coexist.pre_bt_disabled ? - "disabled" : "enabled"), - (rtlpcipriv->bt_coexist.cur_bt_disabled ? - "disabled" : "enabled")); - rtlpcipriv->bt_coexist.pre_bt_disabled - = rtlpcipriv->bt_coexist.cur_bt_disabled; - } -} - - -void rtl8723ae_dm_bt_coexist_8723(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - - rtl8723ae_dm_bt_query_bt_information(hw); - rtl8723ae_dm_bt_bt_hw_counters_monitor(hw); - rtl8723ae_dm_bt_bt_enable_disable_check(hw); - - if (rtlpcipriv->bt_coexist.bt_ant_num == ANT_X2) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], 2 Ant mechanism\n"); - _rtl8723ae_dm_bt_coexist_2_ant(hw); - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "[BTCoex], 1 Ant mechanism\n"); - _rtl8723ae_dm_bt_coexist_1_ant(hw); - } - - if (!rtl8723ae_dm_bt_is_same_coexist_state(hw)) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTCoex], Coexist State[bitMap] change from 0x%x%8x to 0x%x%8x\n", - rtlpcipriv->bt_coexist.previous_state_h, - rtlpcipriv->bt_coexist.previous_state, - rtlpcipriv->bt_coexist.cstate_h, - rtlpcipriv->bt_coexist.cstate); - rtlpcipriv->bt_coexist.previous_state - = rtlpcipriv->bt_coexist.cstate; - rtlpcipriv->bt_coexist.previous_state_h - = rtlpcipriv->bt_coexist.cstate_h; - } -} - -static void rtl8723ae_dm_bt_parse_bt_info(struct ieee80211_hw *hw, - u8 *tmbuf, u8 len) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtlpriv); - struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - u8 bt_info; - u8 i; - - rtlhal->hal_coex_8723.c2h_bt_info_req_sent = false; - rtlhal->hal_coex_8723.bt_retry_cnt = 0; - for (i = 0; i < len; i++) { - if (i == 0) - rtlhal->hal_coex_8723.c2h_bt_info_original = tmbuf[i]; - else if (i == 1) - rtlhal->hal_coex_8723.bt_retry_cnt = tmbuf[i]; - if (i == len-1) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "0x%2x]", tmbuf[i]); - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "0x%2x, ", tmbuf[i]); - } - } - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "BT info bt_info (Data)= 0x%x\n", - rtlhal->hal_coex_8723.c2h_bt_info_original); - bt_info = rtlhal->hal_coex_8723.c2h_bt_info_original; - - if (bt_info & BIT(2)) - rtlhal->hal_coex_8723.c2h_bt_inquiry_page = true; - else - rtlhal->hal_coex_8723.c2h_bt_inquiry_page = false; - - if (bt_info & BTINFO_B_CONNECTION) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTC2H], BTInfo: bConnect=true\n"); - rtlpcipriv->bt_coexist.bt_busy = true; - rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_BT_IDLE; - } else { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, - "[BTC2H], BTInfo: bConnect=false\n"); - rtlpcipriv->bt_coexist.bt_busy = false; - rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_BT_IDLE; - } -} -void rtl_8723e_c2h_command_handle(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct c2h_evt_hdr c2h_event; - u8 *ptmbuf; - u8 index; - u8 u1tmp; - - memset(&c2h_event, 0, sizeof(c2h_event)); - u1tmp = rtl_read_byte(rtlpriv, REG_C2HEVT_MSG_NORMAL); - RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - "&&&&&&: REG_C2HEVT_MSG_NORMAL is 0x%x\n", u1tmp); - c2h_event.cmd_id = u1tmp & 0xF; - c2h_event.cmd_len = (u1tmp & 0xF0) >> 4; - c2h_event.cmd_seq = rtl_read_byte(rtlpriv, REG_C2HEVT_MSG_NORMAL + 1); - RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - "cmd_id: %d, cmd_len: %d, cmd_seq: %d\n", - c2h_event.cmd_id , c2h_event.cmd_len, c2h_event.cmd_seq); - u1tmp = rtl_read_byte(rtlpriv, 0x01AF); - if (u1tmp == C2H_EVT_HOST_CLOSE) { - return; - } else if (u1tmp != C2H_EVT_FW_CLOSE) { - rtl_write_byte(rtlpriv, 0x1AF, 0x00); - return; - } - ptmbuf = kmalloc(c2h_event.cmd_len, GFP_KERNEL); - if (ptmbuf == NULL) { - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - "malloc cmd buf failed\n"); - return; - } - - /* Read the content */ - for (index = 0; index < c2h_event.cmd_len; index++) - ptmbuf[index] = rtl_read_byte(rtlpriv, REG_C2HEVT_MSG_NORMAL + - 2 + index); - - switch (c2h_event.cmd_id) { - case C2H_BT_RSSI: - break; - - case C2H_BT_OP_MODE: - break; - - case BT_INFO: - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - "BT info Byte[0] (ID) is 0x%x\n", c2h_event.cmd_id); - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - "BT info Byte[1] (Seq) is 0x%x\n", c2h_event.cmd_seq); - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - "BT info Byte[2] (Data)= 0x%x\n", ptmbuf[0]); - - rtl8723ae_dm_bt_parse_bt_info(hw, ptmbuf, c2h_event.cmd_len); - break; - default: - break; - } - kfree(ptmbuf); - - rtl_write_byte(rtlpriv, 0x01AF, C2H_EVT_HOST_CLOSE); -} diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.h deleted file mode 100644 index 4325ecd58f0c..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.h +++ /dev/null @@ -1,151 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * Larry Finger - * - **************************************************************************** - */ - -#ifndef __RTL8723E_HAL_BTC_H__ -#define __RTL8723E_HAL_BTC_H__ - -#include "../wifi.h" -#include "btc.h" -#include "hal_bt_coexist.h" - -#define BT_TXRX_CNT_THRES_1 1200 -#define BT_TXRX_CNT_THRES_2 1400 -#define BT_TXRX_CNT_THRES_3 3000 -#define BT_TXRX_CNT_LEVEL_0 0 /* < 1200 */ -#define BT_TXRX_CNT_LEVEL_1 1 /* >= 1200 && < 1400 */ -#define BT_TXRX_CNT_LEVEL_2 2 /* >= 1400 */ -#define BT_TXRX_CNT_LEVEL_3 3 - -/* TDMA mode definition */ -#define TDMA_2ANT 0 -#define TDMA_1ANT 1 -#define TDMA_NAV_OFF 0 -#define TDMA_NAV_ON 1 -#define TDMA_DAC_SWING_OFF 0 -#define TDMA_DAC_SWING_ON 1 - -/* PTA mode related definition */ -#define BT_PTA_MODE_OFF 0 -#define BT_PTA_MODE_ON 1 - -/* Penalty Tx Rate Adaptive */ -#define BT_TX_RATE_ADAPTIVE_NORMAL 0 -#define BT_TX_RATE_ADAPTIVE_LOW_PENALTY 1 - -/* RF Corner */ -#define BT_RF_RX_LPF_CORNER_RESUME 0 -#define BT_RF_RX_LPF_CORNER_SHRINK 1 - -#define C2H_EVT_HOST_CLOSE 0x00 -#define C2H_EVT_FW_CLOSE 0xFF - -enum bt_traffic_mode { - BT_MOTOR_EXT_BE = 0x00, - BT_MOTOR_EXT_GUL = 0x01, - BT_MOTOR_EXT_GUB = 0x02, - BT_MOTOR_EXT_GULB = 0x03 -}; - -enum bt_traffic_mode_profile { - BT_PROFILE_NONE, - BT_PROFILE_A2DP, - BT_PROFILE_PAN, - BT_PROFILE_HID, - BT_PROFILE_SCO -}; - -enum hci_ext_bt_operation { - HCI_BT_OP_NONE = 0x0, - HCI_BT_OP_INQUIRE_START = 0x1, - HCI_BT_OP_INQUIRE_FINISH = 0x2, - HCI_BT_OP_PAGING_START = 0x3, - HCI_BT_OP_PAGING_SUCCESS = 0x4, - HCI_BT_OP_PAGING_UNSUCCESS = 0x5, - HCI_BT_OP_PAIRING_START = 0x6, - HCI_BT_OP_PAIRING_FINISH = 0x7, - HCI_BT_OP_BT_DEV_ENABLE = 0x8, - HCI_BT_OP_BT_DEV_DISABLE = 0x9, - HCI_BT_OP_MAX, -}; - -enum bt_spec { - BT_SPEC_1_0_b = 0x00, - BT_SPEC_1_1 = 0x01, - BT_SPEC_1_2 = 0x02, - BT_SPEC_2_0_EDR = 0x03, - BT_SPEC_2_1_EDR = 0x04, - BT_SPEC_3_0_HS = 0x05, - BT_SPEC_4_0 = 0x06 -}; - -struct c2h_evt_hdr { - u8 cmd_id; - u8 cmd_len; - u8 cmd_seq; -}; - -enum bt_state { - BT_INFO_STATE_DISABLED = 0, - BT_INFO_STATE_NO_CONNECTION = 1, - BT_INFO_STATE_CONNECT_IDLE = 2, - BT_INFO_STATE_INQ_OR_PAG = 3, - BT_INFO_STATE_ACL_ONLY_BUSY = 4, - BT_INFO_STATE_SCO_ONLY_BUSY = 5, - BT_INFO_STATE_ACL_SCO_BUSY = 6, - BT_INFO_STATE_HID_BUSY = 7, - BT_INFO_STATE_HID_SCO_BUSY = 8, - BT_INFO_STATE_MAX = 7 -}; - -enum rtl8723ae_c2h_evt { - C2H_DBG = 0, - C2H_TSF = 1, - C2H_AP_RPT_RSP = 2, - C2H_CCX_TX_RPT = 3, /* The FW notify the report of the specific */ - /* tx packet. */ - C2H_BT_RSSI = 4, - C2H_BT_OP_MODE = 5, - C2H_HW_INFO_EXCH = 10, - C2H_C2H_H2C_TEST = 11, - BT_INFO = 12, - MAX_C2HEVENT -}; - -void rtl8723ae_dm_bt_fw_coex_all_off_8723a(struct ieee80211_hw *hw); -void rtl8723ae_dm_bt_sw_coex_all_off_8723a(struct ieee80211_hw *hw); -void rtl8723ae_dm_bt_hw_coex_all_off_8723a(struct ieee80211_hw *hw); -void rtl8723ae_dm_bt_coexist_8723(struct ieee80211_hw *hw); -void rtl8723ae_dm_bt_set_bt_dm(struct ieee80211_hw *hw, - struct btdm_8723 *p_btdm); -void rtl_8723e_c2h_command_handle(struct ieee80211_hw *hw); -void rtl_8723e_bt_wifi_media_status_notify(struct ieee80211_hw *hw, - bool mstatus); -void rtl8723ae_bt_coex_off_before_lps(struct ieee80211_hw *hw); - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c deleted file mode 100644 index 0a8c03863fb2..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c +++ /dev/null @@ -1,2380 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#include "../wifi.h" -#include "../efuse.h" -#include "../base.h" -#include "../regd.h" -#include "../cam.h" -#include "../ps.h" -#include "../pci.h" -#include "reg.h" -#include "def.h" -#include "phy.h" -#include "dm.h" -#include "fw.h" -#include "led.h" -#include "hw.h" -#include "pwrseqcmd.h" -#include "pwrseq.h" -#include "btc.h" - -static void _rtl8723ae_set_bcn_ctrl_reg(struct ieee80211_hw *hw, - u8 set_bits, u8 clear_bits) -{ - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtlpci->reg_bcn_ctrl_val |= set_bits; - rtlpci->reg_bcn_ctrl_val &= ~clear_bits; - - rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8) rtlpci->reg_bcn_ctrl_val); -} - -static void _rtl8723ae_stop_tx_beacon(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 tmp1byte; - - tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); - rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6))); - rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64); - tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); - tmp1byte &= ~(BIT(0)); - rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); -} - -static void _rtl8723ae_resume_tx_beacon(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 tmp1byte; - - tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); - rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6)); - rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); - tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); - tmp1byte |= BIT(1); - rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); -} - -static void _rtl8723ae_enable_bcn_sufunc(struct ieee80211_hw *hw) -{ - _rtl8723ae_set_bcn_ctrl_reg(hw, 0, BIT(1)); -} - -static void _rtl8723ae_disable_bcn_sufunc(struct ieee80211_hw *hw) -{ - _rtl8723ae_set_bcn_ctrl_reg(hw, BIT(1), 0); -} - -void rtl8723ae_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - - switch (variable) { - case HW_VAR_RCR: - *((u32 *) (val)) = rtlpci->receive_config; - break; - case HW_VAR_RF_STATE: - *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state; - break; - case HW_VAR_FWLPS_RF_ON:{ - enum rf_pwrstate rfState; - u32 val_rcr; - - rtlpriv->cfg->ops->get_hw_reg(hw, - HW_VAR_RF_STATE, - (u8 *) (&rfState)); - if (rfState == ERFOFF) { - *((bool *) (val)) = true; - } else { - val_rcr = rtl_read_dword(rtlpriv, REG_RCR); - val_rcr &= 0x00070000; - if (val_rcr) - *((bool *) (val)) = false; - else - *((bool *) (val)) = true; - } - break; } - case HW_VAR_FW_PSMODE_STATUS: - *((bool *) (val)) = ppsc->fw_current_inpsmode; - break; - case HW_VAR_CORRECT_TSF:{ - u64 tsf; - u32 *ptsf_low = (u32 *)&tsf; - u32 *ptsf_high = ((u32 *)&tsf) + 1; - - *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4)); - *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); - - *((u64 *) (val)) = tsf; - - break; } - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not process\n"); - break; - } -} - -void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - u8 idx; - - switch (variable) { - case HW_VAR_ETHER_ADDR: - for (idx = 0; idx < ETH_ALEN; idx++) { - rtl_write_byte(rtlpriv, (REG_MACID + idx), - val[idx]); - } - break; - case HW_VAR_BASIC_RATE:{ - u16 rate_cfg = ((u16 *) val)[0]; - u8 rate_index = 0; - rate_cfg = rate_cfg & 0x15f; - rate_cfg |= 0x01; - rtl_write_byte(rtlpriv, REG_RRSR, rate_cfg & 0xff); - rtl_write_byte(rtlpriv, REG_RRSR + 1, - (rate_cfg >> 8) & 0xff); - while (rate_cfg > 0x1) { - rate_cfg = (rate_cfg >> 1); - rate_index++; - } - rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, - rate_index); - break; } - case HW_VAR_BSSID: - for (idx = 0; idx < ETH_ALEN; idx++) { - rtl_write_byte(rtlpriv, (REG_BSSID + idx), - val[idx]); - } - break; - case HW_VAR_SIFS: - rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]); - rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]); - - rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]); - rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]); - - if (!mac->ht_enable) - rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, - 0x0e0e); - else - rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, - *((u16 *) val)); - break; - case HW_VAR_SLOT_TIME:{ - u8 e_aci; - - RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - "HW_VAR_SLOT_TIME %x\n", val[0]); - - rtl_write_byte(rtlpriv, REG_SLOT, val[0]); - - for (e_aci = 0; e_aci < AC_MAX; e_aci++) { - rtlpriv->cfg->ops->set_hw_reg(hw, - HW_VAR_AC_PARAM, - (u8 *) (&e_aci)); - } - break; } - case HW_VAR_ACK_PREAMBLE:{ - u8 reg_tmp; - u8 short_preamble = (bool) (*(u8 *) val); - reg_tmp = (mac->cur_40_prime_sc) << 5; - if (short_preamble) - reg_tmp |= 0x80; - - rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_tmp); - break; } - case HW_VAR_AMPDU_MIN_SPACE:{ - u8 min_spacing_to_set; - u8 sec_min_space; - - min_spacing_to_set = *((u8 *) val); - if (min_spacing_to_set <= 7) { - sec_min_space = 0; - - if (min_spacing_to_set < sec_min_space) - min_spacing_to_set = sec_min_space; - - mac->min_space_cfg = ((mac->min_space_cfg & - 0xf8) | - min_spacing_to_set); - - *val = min_spacing_to_set; - - RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", - mac->min_space_cfg); - - rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, - mac->min_space_cfg); - } - break; } - case HW_VAR_SHORTGI_DENSITY:{ - u8 density_to_set; - - density_to_set = *((u8 *) val); - mac->min_space_cfg |= (density_to_set << 3); - - RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - "Set HW_VAR_SHORTGI_DENSITY: %#x\n", - mac->min_space_cfg); - - rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, - mac->min_space_cfg); - - break; } - case HW_VAR_AMPDU_FACTOR:{ - u8 regtoset_normal[4] = {0x41, 0xa8, 0x72, 0xb9}; - u8 regtoset_bt[4] = {0x31, 0x74, 0x42, 0x97}; - u8 factor_toset; - u8 *p_regtoset = NULL; - u8 index; - - if ((pcipriv->bt_coexist.bt_coexistence) && - (pcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4)) - p_regtoset = regtoset_bt; - else - p_regtoset = regtoset_normal; - - factor_toset = *((u8 *) val); - if (factor_toset <= 3) { - factor_toset = (1 << (factor_toset + 2)); - if (factor_toset > 0xf) - factor_toset = 0xf; - - for (index = 0; index < 4; index++) { - if ((p_regtoset[index] & 0xf0) > - (factor_toset << 4)) - p_regtoset[index] = - (p_regtoset[index] & 0x0f) | - (factor_toset << 4); - - if ((p_regtoset[index] & 0x0f) > - factor_toset) - p_regtoset[index] = - (p_regtoset[index] & 0xf0) | - (factor_toset); - - rtl_write_byte(rtlpriv, - (REG_AGGLEN_LMT + index), - p_regtoset[index]); - - } - - RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - "Set HW_VAR_AMPDU_FACTOR: %#x\n", - factor_toset); - } - break; } - case HW_VAR_AC_PARAM:{ - u8 e_aci = *((u8 *) val); - rtl8723ae_dm_init_edca_turbo(hw); - - if (rtlpci->acm_method != eAcmWay2_SW) - rtlpriv->cfg->ops->set_hw_reg(hw, - HW_VAR_ACM_CTRL, - (u8 *) (&e_aci)); - break; } - case HW_VAR_ACM_CTRL:{ - u8 e_aci = *((u8 *) val); - union aci_aifsn *p_aci_aifsn = - (union aci_aifsn *)(&(mac->ac[0].aifs)); - u8 acm = p_aci_aifsn->f.acm; - u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL); - - acm_ctrl |= ((rtlpci->acm_method == 2) ? 0x0 : 0x1); - - if (acm) { - switch (e_aci) { - case AC0_BE: - acm_ctrl |= AcmHw_BeqEn; - break; - case AC2_VI: - acm_ctrl |= AcmHw_ViqEn; - break; - case AC3_VO: - acm_ctrl |= AcmHw_VoqEn; - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", - acm); - break; - } - } else { - switch (e_aci) { - case AC0_BE: - acm_ctrl &= (~AcmHw_BeqEn); - break; - case AC2_VI: - acm_ctrl &= (~AcmHw_ViqEn); - break; - case AC3_VO: - acm_ctrl &= (~AcmHw_BeqEn); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not processed\n"); - break; - } - } - - RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE, - "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", - acm_ctrl); - rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl); - break; } - case HW_VAR_RCR: - rtl_write_dword(rtlpriv, REG_RCR, ((u32 *) (val))[0]); - rtlpci->receive_config = ((u32 *) (val))[0]; - break; - case HW_VAR_RETRY_LIMIT:{ - u8 retry_limit = ((u8 *) (val))[0]; - - rtl_write_word(rtlpriv, REG_RL, - retry_limit << RETRY_LIMIT_SHORT_SHIFT | - retry_limit << RETRY_LIMIT_LONG_SHIFT); - break; } - case HW_VAR_DUAL_TSF_RST: - rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1))); - break; - case HW_VAR_EFUSE_BYTES: - rtlefuse->efuse_usedbytes = *((u16 *) val); - break; - case HW_VAR_EFUSE_USAGE: - rtlefuse->efuse_usedpercentage = *((u8 *) val); - break; - case HW_VAR_IO_CMD: - rtl8723ae_phy_set_io_cmd(hw, (*(enum io_type *)val)); - break; - case HW_VAR_WPA_CONFIG: - rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *) val)); - break; - case HW_VAR_SET_RPWM:{ - u8 rpwm_val; - - rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM); - udelay(1); - - if (rpwm_val & BIT(7)) { - rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, - (*(u8 *) val)); - } else { - rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, - ((*(u8 *) val) | BIT(7))); - } - - break; } - case HW_VAR_H2C_FW_PWRMODE:{ - u8 psmode = (*(u8 *) val); - - if (psmode != FW_PS_ACTIVE_MODE) - rtl8723ae_dm_rf_saving(hw, true); - - rtl8723ae_set_fw_pwrmode_cmd(hw, (*(u8 *) val)); - break; } - case HW_VAR_FW_PSMODE_STATUS: - ppsc->fw_current_inpsmode = *((bool *) val); - break; - case HW_VAR_H2C_FW_JOINBSSRPT:{ - u8 mstatus = (*(u8 *) val); - u8 tmp_regcr, tmp_reg422; - bool recover = false; - - if (mstatus == RT_MEDIA_CONNECT) { - rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, NULL); - - tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1); - rtl_write_byte(rtlpriv, REG_CR + 1, - (tmp_regcr | BIT(0))); - - _rtl8723ae_set_bcn_ctrl_reg(hw, 0, BIT(3)); - _rtl8723ae_set_bcn_ctrl_reg(hw, BIT(4), 0); - - tmp_reg422 = rtl_read_byte(rtlpriv, - REG_FWHW_TXQ_CTRL + 2); - if (tmp_reg422 & BIT(6)) - recover = true; - rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, - tmp_reg422 & (~BIT(6))); - - rtl8723ae_set_fw_rsvdpagepkt(hw, 0); - - _rtl8723ae_set_bcn_ctrl_reg(hw, BIT(3), 0); - _rtl8723ae_set_bcn_ctrl_reg(hw, 0, BIT(4)); - - if (recover) - rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, - tmp_reg422); - - rtl_write_byte(rtlpriv, REG_CR + 1, - (tmp_regcr & ~(BIT(0)))); - } - rtl8723ae_set_fw_joinbss_report_cmd(hw, (*(u8 *) val)); - - break; } - case HW_VAR_AID:{ - u16 u2btmp; - u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT); - u2btmp &= 0xC000; - rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, (u2btmp | - mac->assoc_id)); - break; } - case HW_VAR_CORRECT_TSF:{ - u8 btype_ibss = ((u8 *) (val))[0]; - - if (btype_ibss == true) - _rtl8723ae_stop_tx_beacon(hw); - - _rtl8723ae_set_bcn_ctrl_reg(hw, 0, BIT(3)); - - rtl_write_dword(rtlpriv, REG_TSFTR, - (u32) (mac->tsf & 0xffffffff)); - rtl_write_dword(rtlpriv, REG_TSFTR + 4, - (u32) ((mac->tsf >> 32) & 0xffffffff)); - - _rtl8723ae_set_bcn_ctrl_reg(hw, BIT(3), 0); - - if (btype_ibss == true) - _rtl8723ae_resume_tx_beacon(hw); - break; } - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not processed\n"); - break; - } -} - -static bool _rtl8723ae_llt_write(struct ieee80211_hw *hw, u32 address, u32 data) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - bool status = true; - long count = 0; - u32 value = _LLT_INIT_ADDR(address) | - _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS); - - rtl_write_dword(rtlpriv, REG_LLT_INIT, value); - - do { - value = rtl_read_dword(rtlpriv, REG_LLT_INIT); - if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) - break; - - if (count > POLLING_LLT_THRESHOLD) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Failed to polling write LLT done at address %d!\n", - address); - status = false; - break; - } - } while (++count); - - return status; -} - -static bool _rtl8723ae_llt_table_init(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - unsigned short i; - u8 txpktbuf_bndy; - u8 maxPage; - bool status; - u8 ubyte; - - maxPage = 255; - txpktbuf_bndy = 246; - - rtl_write_byte(rtlpriv, REG_CR, 0x8B); - - rtl_write_word(rtlpriv, REG_RQPN_NPQ, 0x0000); - - rtl_write_dword(rtlpriv, REG_RQPN, 0x80ac1c29); - rtl_write_byte(rtlpriv, REG_RQPN_NPQ, 0x03); - - rtl_write_dword(rtlpriv, REG_TRXFF_BNDY, (0x27FF0000 | txpktbuf_bndy)); - rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy); - - rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy); - rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy); - - rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy); - rtl_write_byte(rtlpriv, REG_PBP, 0x11); - rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4); - - for (i = 0; i < (txpktbuf_bndy - 1); i++) { - status = _rtl8723ae_llt_write(hw, i, i + 1); - if (true != status) - return status; - } - - status = _rtl8723ae_llt_write(hw, (txpktbuf_bndy - 1), 0xFF); - if (true != status) - return status; - - for (i = txpktbuf_bndy; i < maxPage; i++) { - status = _rtl8723ae_llt_write(hw, i, (i + 1)); - if (true != status) - return status; - } - - status = _rtl8723ae_llt_write(hw, maxPage, txpktbuf_bndy); - if (true != status) - return status; - - rtl_write_byte(rtlpriv, REG_CR, 0xff); - ubyte = rtl_read_byte(rtlpriv, REG_RQPN + 3); - rtl_write_byte(rtlpriv, REG_RQPN + 3, ubyte | BIT(7)); - - return true; -} - -static void _rtl8723ae_gen_refresh_led_state(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0); - - if (rtlpriv->rtlhal.up_first_time) - return; - - if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) - rtl8723ae_sw_led_on(hw, pLed0); - else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT) - rtl8723ae_sw_led_on(hw, pLed0); - else - rtl8723ae_sw_led_off(hw, pLed0); -} - -static bool _rtl8712e_init_mac(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - unsigned char bytetmp; - unsigned short wordtmp; - u16 retry = 0; - u16 tmpu2b; - bool mac_func_enable; - - rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00); - bytetmp = rtl_read_byte(rtlpriv, REG_CR); - if (bytetmp == 0xFF) - mac_func_enable = true; - else - mac_func_enable = false; - - - /* HW Power on sequence */ - if (!rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, - PWR_INTF_PCI_MSK, Rtl8723_NIC_ENABLE_FLOW)) - return false; - - bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG+2); - rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG+2, bytetmp | BIT(4)); - - /* eMAC time out function enable, 0x369[7]=1 */ - bytetmp = rtl_read_byte(rtlpriv, 0x369); - rtl_write_byte(rtlpriv, 0x369, bytetmp | BIT(7)); - - /* ePHY reg 0x1e bit[4]=1 using MDIO interface, - * we should do this before Enabling ASPM backdoor. - */ - do { - rtl_write_word(rtlpriv, 0x358, 0x5e); - udelay(100); - rtl_write_word(rtlpriv, 0x356, 0xc280); - rtl_write_word(rtlpriv, 0x354, 0xc290); - rtl_write_word(rtlpriv, 0x358, 0x3e); - udelay(100); - rtl_write_word(rtlpriv, 0x358, 0x5e); - udelay(100); - tmpu2b = rtl_read_word(rtlpriv, 0x356); - retry++; - } while (tmpu2b != 0xc290 && retry < 100); - - if (retry >= 100) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "InitMAC(): ePHY configure fail!!!\n"); - return false; - } - - rtl_write_word(rtlpriv, REG_CR, 0x2ff); - rtl_write_word(rtlpriv, REG_CR + 1, 0x06); - - if (!mac_func_enable) { - if (_rtl8723ae_llt_table_init(hw) == false) - return false; - } - - rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff); - rtl_write_byte(rtlpriv, REG_HISRE, 0xff); - - rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, 0x27ff); - - wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL) & 0xf; - wordtmp |= 0xF771; - rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp); - - rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F); - rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); - rtl_write_word(rtlpriv, REG_RXFLTMAP2, 0xFFFF); - rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config); - - rtl_write_byte(rtlpriv, 0x4d0, 0x0); - - rtl_write_dword(rtlpriv, REG_BCNQ_DESA, - ((u64) rtlpci->tx_ring[BEACON_QUEUE].dma) & - DMA_BIT_MASK(32)); - rtl_write_dword(rtlpriv, REG_MGQ_DESA, - (u64) rtlpci->tx_ring[MGNT_QUEUE].dma & - DMA_BIT_MASK(32)); - rtl_write_dword(rtlpriv, REG_VOQ_DESA, - (u64) rtlpci->tx_ring[VO_QUEUE].dma & DMA_BIT_MASK(32)); - rtl_write_dword(rtlpriv, REG_VIQ_DESA, - (u64) rtlpci->tx_ring[VI_QUEUE].dma & DMA_BIT_MASK(32)); - rtl_write_dword(rtlpriv, REG_BEQ_DESA, - (u64) rtlpci->tx_ring[BE_QUEUE].dma & DMA_BIT_MASK(32)); - rtl_write_dword(rtlpriv, REG_BKQ_DESA, - (u64) rtlpci->tx_ring[BK_QUEUE].dma & DMA_BIT_MASK(32)); - rtl_write_dword(rtlpriv, REG_HQ_DESA, - (u64) rtlpci->tx_ring[HIGH_QUEUE].dma & - DMA_BIT_MASK(32)); - rtl_write_dword(rtlpriv, REG_RX_DESA, - (u64) rtlpci->rx_ring[RX_MPDU_QUEUE].dma & - DMA_BIT_MASK(32)); - - rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, 0x74); - - rtl_write_dword(rtlpriv, REG_INT_MIG, 0); - - bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL); - rtl_write_byte(rtlpriv, REG_APSD_CTRL, bytetmp & ~BIT(6)); - do { - retry++; - bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL); - } while ((retry < 200) && (bytetmp & BIT(7))); - - _rtl8723ae_gen_refresh_led_state(hw); - - rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0); - - return true; -} - -static void _rtl8723ae_hw_configure(struct ieee80211_hw *hw) -{ - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - u8 reg_bw_opmode; - u32 reg_ratr, reg_prsr; - - reg_bw_opmode = BW_OPMODE_20MHZ; - reg_ratr = RATE_ALL_CCK | RATE_ALL_OFDM_AG | - RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; - reg_prsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG; - - rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, 0x8); - - rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); - - rtl_write_dword(rtlpriv, REG_RRSR, reg_prsr); - - rtl_write_byte(rtlpriv, REG_SLOT, 0x09); - - rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, 0x0); - - rtl_write_word(rtlpriv, REG_FWHW_TXQ_CTRL, 0x1F80); - - rtl_write_word(rtlpriv, REG_RL, 0x0707); - - rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0x02012802); - - rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF); - - rtl_write_dword(rtlpriv, REG_DARFRC, 0x01000000); - rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x07060504); - rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000); - rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504); - - if ((pcipriv->bt_coexist.bt_coexistence) && - (pcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4)) - rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0x97427431); - else - rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0xb972a841); - - rtl_write_byte(rtlpriv, REG_ATIMWND, 0x2); - - rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xff); - - rtlpci->reg_bcn_ctrl_val = 0x1f; - rtl_write_byte(rtlpriv, REG_BCN_CTRL, rtlpci->reg_bcn_ctrl_val); - - rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); - - rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); - - rtl_write_byte(rtlpriv, REG_PIFS, 0x1C); - rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16); - - if ((pcipriv->bt_coexist.bt_coexistence) && - (pcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4)) { - rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); - rtl_write_word(rtlpriv, REG_PROT_MODE_CTRL, 0x0402); - } else { - rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); - rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); - } - - if ((pcipriv->bt_coexist.bt_coexistence) && - (pcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4)) - rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x03086666); - else - rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x086666); - - rtl_write_byte(rtlpriv, REG_ACKTO, 0x40); - - rtl_write_word(rtlpriv, REG_SPEC_SIFS, 0x1010); - rtl_write_word(rtlpriv, REG_MAC_SPEC_SIFS, 0x1010); - - rtl_write_word(rtlpriv, REG_SIFS_CTX, 0x1010); - - rtl_write_word(rtlpriv, REG_SIFS_TRX, 0x1010); - - rtl_write_dword(rtlpriv, REG_MAR, 0xffffffff); - rtl_write_dword(rtlpriv, REG_MAR + 4, 0xffffffff); - - rtl_write_dword(rtlpriv, 0x394, 0x1); -} - -static void _rtl8723ae_enable_aspm_back_door(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - - rtl_write_byte(rtlpriv, 0x34b, 0x93); - rtl_write_word(rtlpriv, 0x350, 0x870c); - rtl_write_byte(rtlpriv, 0x352, 0x1); - - if (ppsc->support_backdoor) - rtl_write_byte(rtlpriv, 0x349, 0x1b); - else - rtl_write_byte(rtlpriv, 0x349, 0x03); - - rtl_write_word(rtlpriv, 0x350, 0x2718); - rtl_write_byte(rtlpriv, 0x352, 0x1); -} - -void rtl8723ae_enable_hw_security_config(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 sec_reg_value; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", - rtlpriv->sec.pairwise_enc_algorithm, - rtlpriv->sec.group_enc_algorithm); - - if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "not open hw encryption\n"); - return; - } - - sec_reg_value = SCR_TxEncEnable | SCR_RxDecEnable; - - if (rtlpriv->sec.use_defaultkey) { - sec_reg_value |= SCR_TxUseDK; - sec_reg_value |= SCR_RxUseDK; - } - - sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK); - - rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); - - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "The SECR-value %x\n", sec_reg_value); - - rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); - -} - -int rtl8723ae_hw_init(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - bool rtstatus = true; - int err; - u8 tmp_u1b; - - rtlpriv->rtlhal.being_init_adapter = true; - rtlpriv->intf_ops->disable_aspm(hw); - rtstatus = _rtl8712e_init_mac(hw); - if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n"); - err = 1; - return err; - } - - err = rtl8723ae_download_fw(hw); - if (err) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "Failed to download FW. Init HW without FW now..\n"); - err = 1; - rtlhal->fw_ready = false; - return err; - } else { - rtlhal->fw_ready = true; - } - - rtlhal->last_hmeboxnum = 0; - rtl8723ae_phy_mac_config(hw); - /* because the last function modifies RCR, we update - * rcr var here, or TP will be unstable as ther receive_config - * is wrong, RX RCR_ACRC32 will cause TP unstable & Rx - * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252 - */ - rtlpci->receive_config = rtl_read_dword(rtlpriv, REG_RCR); - rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV); - rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); - - rtl8723ae_phy_bb_config(hw); - rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; - rtl8723ae_phy_rf_config(hw); - if (IS_VENDOR_UMC_A_CUT(rtlhal->version)) { - rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, 0x30255); - rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G2, MASKDWORD, 0x50a00); - } else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) { - rtl_set_rfreg(hw, RF90_PATH_A, 0x0C, MASKDWORD, 0x894AE); - rtl_set_rfreg(hw, RF90_PATH_A, 0x0A, MASKDWORD, 0x1AF31); - rtl_set_rfreg(hw, RF90_PATH_A, RF_IPA, MASKDWORD, 0x8F425); - rtl_set_rfreg(hw, RF90_PATH_A, RF_SYN_G2, MASKDWORD, 0x4F200); - rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK1, MASKDWORD, 0x44053); - rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK2, MASKDWORD, 0x80201); - } - rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0, - RF_CHNLBW, RFREG_OFFSET_MASK); - rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1, - RF_CHNLBW, RFREG_OFFSET_MASK); - rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1); - rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1); - rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); - _rtl8723ae_hw_configure(hw); - rtl_cam_reset_all_entry(hw); - rtl8723ae_enable_hw_security_config(hw); - - ppsc->rfpwr_state = ERFON; - - rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); - _rtl8723ae_enable_aspm_back_door(hw); - rtlpriv->intf_ops->enable_aspm(hw); - - rtl8723ae_bt_hw_init(hw); - - if (ppsc->rfpwr_state == ERFON) { - rtl8723ae_phy_set_rfpath_switch(hw, 1); - if (rtlphy->iqk_initialized) { - rtl8723ae_phy_iq_calibrate(hw, true); - } else { - rtl8723ae_phy_iq_calibrate(hw, false); - rtlphy->iqk_initialized = true; - } - - rtl8723ae_phy_lc_calibrate(hw); - } - - tmp_u1b = efuse_read_1byte(hw, 0x1FA); - if (!(tmp_u1b & BIT(0))) { - rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0F, 0x05); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "PA BIAS path A\n"); - } - - if (!(tmp_u1b & BIT(4))) { - tmp_u1b = rtl_read_byte(rtlpriv, 0x16) & 0x0F; - rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x80); - udelay(10); - rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x90); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n"); - } - rtl8723ae_dm_init(hw); - rtlpriv->rtlhal.being_init_adapter = false; - return err; -} - -static enum version_8723e _rtl8723ae_read_chip_version(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - enum version_8723e version = 0x0000; - u32 value32; - - value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG); - if (value32 & TRP_VAUX_EN) { - version = (enum version_8723e)(version | - ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : 0)); - /* RTL8723 with BT function. */ - version = (enum version_8723e)(version | - ((value32 & BT_FUNC) ? CHIP_8723 : 0)); - - } else { - /* Normal mass production chip. */ - version = (enum version_8723e) NORMAL_CHIP; - version = (enum version_8723e)(version | - ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : 0)); - /* RTL8723 with BT function. */ - version = (enum version_8723e)(version | - ((value32 & BT_FUNC) ? CHIP_8723 : 0)); - if (IS_CHIP_VENDOR_UMC(version)) - version = (enum version_8723e)(version | - ((value32 & CHIP_VER_RTL_MASK)));/* IC version (CUT) */ - if (IS_8723_SERIES(version)) { - value32 = rtl_read_dword(rtlpriv, REG_GPIO_OUTSTS); - /* ROM code version */ - version = (enum version_8723e)(version | - ((value32 & RF_RL_ID)>>20)); - } - } - - if (IS_8723_SERIES(version)) { - value32 = rtl_read_dword(rtlpriv, REG_MULTI_FUNC_CTRL); - rtlphy->polarity_ctl = ((value32 & WL_HWPDN_SL) ? - RT_POLARITY_HIGH_ACT : - RT_POLARITY_LOW_ACT); - } - switch (version) { - case VERSION_TEST_UMC_CHIP_8723: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_TEST_UMC_CHIP_8723.\n"); - break; - case VERSION_NORMAL_UMC_CHIP_8723_1T1R_A_CUT: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_NORMAL_UMC_CHIP_8723_1T1R_A_CUT.\n"); - break; - case VERSION_NORMAL_UMC_CHIP_8723_1T1R_B_CUT: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_NORMAL_UMC_CHIP_8723_1T1R_B_CUT.\n"); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Chip Version ID: Unknown. Bug?\n"); - break; - } - - if (IS_8723_SERIES(version)) - rtlphy->rf_type = RF_1T1R; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Chip RF Type: %s\n", - (rtlphy->rf_type == RF_2T2R) ? "RF_2T2R" : "RF_1T1R"); - - return version; -} - -static int _rtl8723ae_set_media_status(struct ieee80211_hw *hw, - enum nl80211_iftype type) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 bt_msr = rtl_read_byte(rtlpriv, MSR) & 0xfc; - enum led_ctl_mode ledaction = LED_CTL_NO_LINK; - - rtl_write_dword(rtlpriv, REG_BCN_CTRL, 0); - RT_TRACE(rtlpriv, COMP_BEACON, DBG_LOUD, - "clear 0x550 when set HW_VAR_MEDIA_STATUS\n"); - - if (type == NL80211_IFTYPE_UNSPECIFIED || - type == NL80211_IFTYPE_STATION) { - _rtl8723ae_stop_tx_beacon(hw); - _rtl8723ae_enable_bcn_sufunc(hw); - } else if (type == NL80211_IFTYPE_ADHOC || - type == NL80211_IFTYPE_AP) { - _rtl8723ae_resume_tx_beacon(hw); - _rtl8723ae_disable_bcn_sufunc(hw); - } else { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "Set HW_VAR_MEDIA_STATUS: No such media status(%x).\n", - type); - } - - switch (type) { - case NL80211_IFTYPE_UNSPECIFIED: - bt_msr |= MSR_NOLINK; - ledaction = LED_CTL_LINK; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Set Network type to NO LINK!\n"); - break; - case NL80211_IFTYPE_ADHOC: - bt_msr |= MSR_ADHOC; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Set Network type to Ad Hoc!\n"); - break; - case NL80211_IFTYPE_STATION: - bt_msr |= MSR_INFRA; - ledaction = LED_CTL_LINK; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Set Network type to STA!\n"); - break; - case NL80211_IFTYPE_AP: - bt_msr |= MSR_AP; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Set Network type to AP!\n"); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Network type %d not supported!\n", - type); - return 1; - break; - - } - - rtl_write_byte(rtlpriv, (MSR), bt_msr); - rtlpriv->cfg->ops->led_control(hw, ledaction); - if ((bt_msr & 0x03) == MSR_AP) - rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); - else - rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66); - return 0; -} - -void rtl8723ae_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - u32 reg_rcr = rtlpci->receive_config; - - if (rtlpriv->psc.rfpwr_state != ERFON) - return; - - if (check_bssid == true) { - reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); - rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, - (u8 *)(®_rcr)); - _rtl8723ae_set_bcn_ctrl_reg(hw, 0, BIT(4)); - } else if (check_bssid == false) { - reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); - _rtl8723ae_set_bcn_ctrl_reg(hw, BIT(4), 0); - rtlpriv->cfg->ops->set_hw_reg(hw, - HW_VAR_RCR, (u8 *) (®_rcr)); - } -} - -int rtl8723ae_set_network_type(struct ieee80211_hw *hw, - enum nl80211_iftype type) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - if (_rtl8723ae_set_media_status(hw, type)) - return -EOPNOTSUPP; - - if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { - if (type != NL80211_IFTYPE_AP) - rtl8723ae_set_check_bssid(hw, true); - } else { - rtl8723ae_set_check_bssid(hw, false); - } - return 0; -} - -/* don't set REG_EDCA_BE_PARAM here because mac80211 will send pkt when scan */ -void rtl8723ae_set_qos(struct ieee80211_hw *hw, int aci) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtl8723ae_dm_init_edca_turbo(hw); - switch (aci) { - case AC1_BK: - rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f); - break; - case AC0_BE: - /* rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, u4ac_param); */ - break; - case AC2_VI: - rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322); - break; - case AC3_VO: - rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222); - break; - default: - RT_ASSERT(false, "invalid aci: %d !\n", aci); - break; - } -} - -void rtl8723ae_enable_interrupt(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - - rtl_write_dword(rtlpriv, 0x3a8, rtlpci->irq_mask[0] & 0xFFFFFFFF); - rtl_write_dword(rtlpriv, 0x3ac, rtlpci->irq_mask[1] & 0xFFFFFFFF); - rtlpci->irq_enabled = true; -} - -void rtl8723ae_disable_interrupt(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - - rtl_write_dword(rtlpriv, 0x3a8, IMR8190_DISABLED); - rtl_write_dword(rtlpriv, 0x3ac, IMR8190_DISABLED); - rtlpci->irq_enabled = false; - synchronize_irq(rtlpci->pdev->irq); -} - -static void _rtl8723ae_poweroff_adapter(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - u8 u1tmp; - - /* Combo (PCIe + USB) Card and PCIe-MF Card */ - /* 1. Run LPS WL RFOFF flow */ - rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, - PWR_INTF_PCI_MSK, Rtl8723_NIC_LPS_ENTER_FLOW); - - /* 2. 0x1F[7:0] = 0 */ - /* turn off RF */ - rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00); - if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && rtlhal->fw_ready) - rtl8723ae_firmware_selfreset(hw); - - /* Reset MCU. Suggested by Filen. */ - u1tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN+1); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN+1, (u1tmp & (~BIT(2)))); - - /* g. MCUFWDL 0x80[1:0]=0 */ - /* reset MCU ready status */ - rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); - - /* HW card disable configuration. */ - rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, - PWR_INTF_PCI_MSK, Rtl8723_NIC_DISABLE_FLOW); - - /* Reset MCU IO Wrapper */ - u1tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1); - rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1tmp & (~BIT(0)))); - u1tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1); - rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, u1tmp | BIT(0)); - - /* 7. RSV_CTRL 0x1C[7:0] = 0x0E */ - /* lock ISO/CLK/Power control register */ - rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e); -} - -void rtl8723ae_card_disable(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - enum nl80211_iftype opmode; - - mac->link_state = MAC80211_NOLINK; - opmode = NL80211_IFTYPE_UNSPECIFIED; - _rtl8723ae_set_media_status(hw, opmode); - if (rtlpci->driver_is_goingto_unload || - ppsc->rfoff_reason > RF_CHANGE_BY_PS) - rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); - RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); - _rtl8723ae_poweroff_adapter(hw); - - /* after power off we should do iqk again */ - rtlpriv->phy.iqk_initialized = false; -} - -void rtl8723ae_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - - *p_inta = rtl_read_dword(rtlpriv, 0x3a0) & rtlpci->irq_mask[0]; - rtl_write_dword(rtlpriv, 0x3a0, *p_inta); -} - -void rtl8723ae_set_beacon_related_registers(struct ieee80211_hw *hw) -{ - - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - u16 bcn_interval, atim_window; - - bcn_interval = mac->beacon_interval; - atim_window = 2; /*FIX MERGE */ - rtl8723ae_disable_interrupt(hw); - rtl_write_word(rtlpriv, REG_ATIMWND, atim_window); - rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); - rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f); - rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18); - rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18); - rtl_write_byte(rtlpriv, 0x606, 0x30); - rtl8723ae_enable_interrupt(hw); -} - -void rtl8723ae_set_beacon_interval(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - u16 bcn_interval = mac->beacon_interval; - - RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, - "beacon_interval:%d\n", bcn_interval); - rtl8723ae_disable_interrupt(hw); - rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); - rtl8723ae_enable_interrupt(hw); -} - -void rtl8723ae_update_interrupt_mask(struct ieee80211_hw *hw, - u32 add_msr, u32 rm_msr) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - - RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, - "add_msr:%x, rm_msr:%x\n", add_msr, rm_msr); - - if (add_msr) - rtlpci->irq_mask[0] |= add_msr; - if (rm_msr) - rtlpci->irq_mask[0] &= (~rm_msr); - rtl8723ae_disable_interrupt(hw); - rtl8723ae_enable_interrupt(hw); -} - -static u8 _rtl8723ae_get_chnl_group(u8 chnl) -{ - u8 group; - - if (chnl < 3) - group = 0; - else if (chnl < 9) - group = 1; - else - group = 2; - return group; -} - -static void _rtl8723ae_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, - bool autoload_fail, - u8 *hwinfo) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u8 rf_path, index, tempval; - u16 i; - - for (rf_path = 0; rf_path < 1; rf_path++) { - for (i = 0; i < 3; i++) { - if (!autoload_fail) { - rtlefuse->eeprom_chnlarea_txpwr_cck - [rf_path][i] = - hwinfo[EEPROM_TXPOWERCCK + rf_path * 3 + i]; - rtlefuse->eeprom_chnlarea_txpwr_ht40_1s - [rf_path][i] = - hwinfo[EEPROM_TXPOWERHT40_1S + rf_path * - 3 + i]; - } else { - rtlefuse->eeprom_chnlarea_txpwr_cck - [rf_path][i] = - EEPROM_DEFAULT_TXPOWERLEVEL; - rtlefuse->eeprom_chnlarea_txpwr_ht40_1s - [rf_path][i] = - EEPROM_DEFAULT_TXPOWERLEVEL; - } - } - } - - for (i = 0; i < 3; i++) { - if (!autoload_fail) - tempval = hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i]; - else - tempval = EEPROM_DEFAULT_HT40_2SDIFF; - rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_A][i] = - (tempval & 0xf); - rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_B][i] = - ((tempval & 0xf0) >> 4); - } - - for (rf_path = 0; rf_path < 2; rf_path++) - for (i = 0; i < 3; i++) - RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - "RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path, - i, rtlefuse->eeprom_chnlarea_txpwr_cck - [rf_path][i]); - for (rf_path = 0; rf_path < 2; rf_path++) - for (i = 0; i < 3; i++) - RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - "RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", - rf_path, i, - rtlefuse->eeprom_chnlarea_txpwr_ht40_1s - [rf_path][i]); - for (rf_path = 0; rf_path < 2; rf_path++) - for (i = 0; i < 3; i++) - RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", - rf_path, i, - rtlefuse->eprom_chnl_txpwr_ht40_2sdf - [rf_path][i]); - - for (rf_path = 0; rf_path < 2; rf_path++) { - for (i = 0; i < 14; i++) { - index = _rtl8723ae_get_chnl_group((u8) i); - - rtlefuse->txpwrlevel_cck[rf_path][i] = - rtlefuse->eeprom_chnlarea_txpwr_cck - [rf_path][index]; - rtlefuse->txpwrlevel_ht40_1s[rf_path][i] = - rtlefuse->eeprom_chnlarea_txpwr_ht40_1s - [rf_path][index]; - - if ((rtlefuse->eeprom_chnlarea_txpwr_ht40_1s - [rf_path][index] - - rtlefuse->eprom_chnl_txpwr_ht40_2sdf[rf_path] - [index]) > 0) { - rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = - rtlefuse->eeprom_chnlarea_txpwr_ht40_1s - [rf_path][index] - - rtlefuse->eprom_chnl_txpwr_ht40_2sdf - [rf_path][index]; - } else { - rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 0; - } - } - - for (i = 0; i < 14; i++) { - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = " - "[0x%x / 0x%x / 0x%x]\n", rf_path, i, - rtlefuse->txpwrlevel_cck[rf_path][i], - rtlefuse->txpwrlevel_ht40_1s[rf_path][i], - rtlefuse->txpwrlevel_ht40_2s[rf_path][i]); - } - } - - for (i = 0; i < 3; i++) { - if (!autoload_fail) { - rtlefuse->eeprom_pwrlimit_ht40[i] = - hwinfo[EEPROM_TXPWR_GROUP + i]; - rtlefuse->eeprom_pwrlimit_ht20[i] = - hwinfo[EEPROM_TXPWR_GROUP + 3 + i]; - } else { - rtlefuse->eeprom_pwrlimit_ht40[i] = 0; - rtlefuse->eeprom_pwrlimit_ht20[i] = 0; - } - } - - for (rf_path = 0; rf_path < 2; rf_path++) { - for (i = 0; i < 14; i++) { - index = _rtl8723ae_get_chnl_group((u8) i); - - if (rf_path == RF90_PATH_A) { - rtlefuse->pwrgroup_ht20[rf_path][i] = - (rtlefuse->eeprom_pwrlimit_ht20[index] & - 0xf); - rtlefuse->pwrgroup_ht40[rf_path][i] = - (rtlefuse->eeprom_pwrlimit_ht40[index] & - 0xf); - } else if (rf_path == RF90_PATH_B) { - rtlefuse->pwrgroup_ht20[rf_path][i] = - ((rtlefuse->eeprom_pwrlimit_ht20[index] & - 0xf0) >> 4); - rtlefuse->pwrgroup_ht40[rf_path][i] = - ((rtlefuse->eeprom_pwrlimit_ht40[index] & - 0xf0) >> 4); - } - - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - "RF-%d pwrgroup_ht20[%d] = 0x%x\n", rf_path, i, - rtlefuse->pwrgroup_ht20[rf_path][i]); - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - "RF-%d pwrgroup_ht40[%d] = 0x%x\n", rf_path, i, - rtlefuse->pwrgroup_ht40[rf_path][i]); - } - } - - for (i = 0; i < 14; i++) { - index = _rtl8723ae_get_chnl_group((u8) i); - - if (!autoload_fail) - tempval = hwinfo[EEPROM_TXPOWERHT20DIFF + index]; - else - tempval = EEPROM_DEFAULT_HT20_DIFF; - - rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] = (tempval & 0xF); - rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] = - ((tempval >> 4) & 0xF); - - if (rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] & BIT(3)) - rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] |= 0xF0; - - if (rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] & BIT(3)) - rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] |= 0xF0; - - index = _rtl8723ae_get_chnl_group((u8) i); - - if (!autoload_fail) - tempval = hwinfo[EEPROM_TXPOWER_OFDMDIFF + index]; - else - tempval = EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF; - - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i] = (tempval & 0xF); - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i] = - ((tempval >> 4) & 0xF); - } - - rtlefuse->legacy_ht_txpowerdiff = - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][7]; - - for (i = 0; i < 14; i++) - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]); - for (i = 0; i < 14; i++) - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]); - for (i = 0; i < 14; i++) - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]); - for (i = 0; i < 14; i++) - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]); - - if (!autoload_fail) - rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7); - else - rtlefuse->eeprom_regulatory = 0; - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); - - if (!autoload_fail) - rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A]; - else - rtlefuse->eeprom_tssi[RF90_PATH_A] = EEPROM_DEFAULT_TSSI; - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - "TSSI_A = 0x%x, TSSI_B = 0x%x\n", - rtlefuse->eeprom_tssi[RF90_PATH_A], - rtlefuse->eeprom_tssi[RF90_PATH_B]); - - if (!autoload_fail) - tempval = hwinfo[EEPROM_THERMAL_METER]; - else - tempval = EEPROM_DEFAULT_THERMALMETER; - rtlefuse->eeprom_thermalmeter = (tempval & 0x1f); - - if (rtlefuse->eeprom_thermalmeter == 0x1f || autoload_fail) - rtlefuse->apk_thermalmeterignore = true; - - rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); -} - -static void _rtl8723ae_read_adapter_info(struct ieee80211_hw *hw, - bool pseudo_test) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - u16 i, usvalue; - u8 hwinfo[HWSET_MAX_SIZE]; - u16 eeprom_id; - - if (pseudo_test) { - /* need add */ - return; - } - if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) { - rtl_efuse_shadow_map_update(hw); - - memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], - HWSET_MAX_SIZE); - } else if (rtlefuse->epromtype == EEPROM_93C46) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "RTL819X Not boot from eeprom, check it !!"); - } - - RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"), - hwinfo, HWSET_MAX_SIZE); - - eeprom_id = *((u16 *)&hwinfo[0]); - if (eeprom_id != RTL8190_EEPROM_ID) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "EEPROM ID(%#x) is invalid!!\n", eeprom_id); - rtlefuse->autoload_failflag = true; - } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); - rtlefuse->autoload_failflag = false; - } - - if (rtlefuse->autoload_failflag == true) - return; - - rtlefuse->eeprom_vid = *(u16 *) &hwinfo[EEPROM_VID]; - rtlefuse->eeprom_did = *(u16 *) &hwinfo[EEPROM_DID]; - rtlefuse->eeprom_svid = *(u16 *) &hwinfo[EEPROM_SVID]; - rtlefuse->eeprom_smid = *(u16 *) &hwinfo[EEPROM_SMID]; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "EEPROMId = 0x%4x\n", eeprom_id); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid); - - for (i = 0; i < 6; i += 2) { - usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i]; - *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue; - } - - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "dev_addr: %pM\n", rtlefuse->dev_addr); - - _rtl8723ae_read_txpower_info_from_hwpg(hw, - rtlefuse->autoload_failflag, hwinfo); - - rtl8723ae_read_bt_coexist_info_from_hwpg(hw, - rtlefuse->autoload_failflag, hwinfo); - - rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; - rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; - rtlefuse->txpwr_fromeprom = true; - rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid); - - /* set channel paln to world wide 13 */ - rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13; - - if (rtlhal->oem_id == RT_CID_DEFAULT) { - switch (rtlefuse->eeprom_oemid) { - case EEPROM_CID_DEFAULT: - if (rtlefuse->eeprom_did == 0x8176) { - if (CHK_SVID_SMID(0x10EC, 0x6151) || - CHK_SVID_SMID(0x10EC, 0x6152) || - CHK_SVID_SMID(0x10EC, 0x6154) || - CHK_SVID_SMID(0x10EC, 0x6155) || - CHK_SVID_SMID(0x10EC, 0x6177) || - CHK_SVID_SMID(0x10EC, 0x6178) || - CHK_SVID_SMID(0x10EC, 0x6179) || - CHK_SVID_SMID(0x10EC, 0x6180) || - CHK_SVID_SMID(0x10EC, 0x8151) || - CHK_SVID_SMID(0x10EC, 0x8152) || - CHK_SVID_SMID(0x10EC, 0x8154) || - CHK_SVID_SMID(0x10EC, 0x8155) || - CHK_SVID_SMID(0x10EC, 0x8181) || - CHK_SVID_SMID(0x10EC, 0x8182) || - CHK_SVID_SMID(0x10EC, 0x8184) || - CHK_SVID_SMID(0x10EC, 0x8185) || - CHK_SVID_SMID(0x10EC, 0x9151) || - CHK_SVID_SMID(0x10EC, 0x9152) || - CHK_SVID_SMID(0x10EC, 0x9154) || - CHK_SVID_SMID(0x10EC, 0x9155) || - CHK_SVID_SMID(0x10EC, 0x9181) || - CHK_SVID_SMID(0x10EC, 0x9182) || - CHK_SVID_SMID(0x10EC, 0x9184) || - CHK_SVID_SMID(0x10EC, 0x9185)) - rtlhal->oem_id = RT_CID_TOSHIBA; - else if (rtlefuse->eeprom_svid == 0x1025) - rtlhal->oem_id = RT_CID_819x_Acer; - else if (CHK_SVID_SMID(0x10EC, 0x6191) || - CHK_SVID_SMID(0x10EC, 0x6192) || - CHK_SVID_SMID(0x10EC, 0x6193) || - CHK_SVID_SMID(0x10EC, 0x7191) || - CHK_SVID_SMID(0x10EC, 0x7192) || - CHK_SVID_SMID(0x10EC, 0x7193) || - CHK_SVID_SMID(0x10EC, 0x8191) || - CHK_SVID_SMID(0x10EC, 0x8192) || - CHK_SVID_SMID(0x10EC, 0x8193)) - rtlhal->oem_id = RT_CID_819x_SAMSUNG; - else if (CHK_SVID_SMID(0x10EC, 0x8195) || - CHK_SVID_SMID(0x10EC, 0x9195) || - CHK_SVID_SMID(0x10EC, 0x7194) || - CHK_SVID_SMID(0x10EC, 0x8200) || - CHK_SVID_SMID(0x10EC, 0x8201) || - CHK_SVID_SMID(0x10EC, 0x8202) || - CHK_SVID_SMID(0x10EC, 0x9200)) - rtlhal->oem_id = RT_CID_819x_Lenovo; - else if (CHK_SVID_SMID(0x10EC, 0x8197) || - CHK_SVID_SMID(0x10EC, 0x9196)) - rtlhal->oem_id = RT_CID_819x_CLEVO; - else if (CHK_SVID_SMID(0x1028, 0x8194) || - CHK_SVID_SMID(0x1028, 0x8198) || - CHK_SVID_SMID(0x1028, 0x9197) || - CHK_SVID_SMID(0x1028, 0x9198)) - rtlhal->oem_id = RT_CID_819x_DELL; - else if (CHK_SVID_SMID(0x103C, 0x1629)) - rtlhal->oem_id = RT_CID_819x_HP; - else if (CHK_SVID_SMID(0x1A32, 0x2315)) - rtlhal->oem_id = RT_CID_819x_QMI; - else if (CHK_SVID_SMID(0x10EC, 0x8203)) - rtlhal->oem_id = RT_CID_819x_PRONETS; - else if (CHK_SVID_SMID(0x1043, 0x84B5)) - rtlhal->oem_id = - RT_CID_819x_Edimax_ASUS; - else - rtlhal->oem_id = RT_CID_DEFAULT; - } else if (rtlefuse->eeprom_did == 0x8178) { - if (CHK_SVID_SMID(0x10EC, 0x6181) || - CHK_SVID_SMID(0x10EC, 0x6182) || - CHK_SVID_SMID(0x10EC, 0x6184) || - CHK_SVID_SMID(0x10EC, 0x6185) || - CHK_SVID_SMID(0x10EC, 0x7181) || - CHK_SVID_SMID(0x10EC, 0x7182) || - CHK_SVID_SMID(0x10EC, 0x7184) || - CHK_SVID_SMID(0x10EC, 0x7185) || - CHK_SVID_SMID(0x10EC, 0x8181) || - CHK_SVID_SMID(0x10EC, 0x8182) || - CHK_SVID_SMID(0x10EC, 0x8184) || - CHK_SVID_SMID(0x10EC, 0x8185) || - CHK_SVID_SMID(0x10EC, 0x9181) || - CHK_SVID_SMID(0x10EC, 0x9182) || - CHK_SVID_SMID(0x10EC, 0x9184) || - CHK_SVID_SMID(0x10EC, 0x9185)) - rtlhal->oem_id = RT_CID_TOSHIBA; - else if (rtlefuse->eeprom_svid == 0x1025) - rtlhal->oem_id = RT_CID_819x_Acer; - else if (CHK_SVID_SMID(0x10EC, 0x8186)) - rtlhal->oem_id = RT_CID_819x_PRONETS; - else if (CHK_SVID_SMID(0x1043, 0x8486)) - rtlhal->oem_id = - RT_CID_819x_Edimax_ASUS; - else - rtlhal->oem_id = RT_CID_DEFAULT; - } else { - rtlhal->oem_id = RT_CID_DEFAULT; - } - break; - case EEPROM_CID_TOSHIBA: - rtlhal->oem_id = RT_CID_TOSHIBA; - break; - case EEPROM_CID_CCX: - rtlhal->oem_id = RT_CID_CCX; - break; - case EEPROM_CID_QMI: - rtlhal->oem_id = RT_CID_819x_QMI; - break; - case EEPROM_CID_WHQL: - break; - default: - rtlhal->oem_id = RT_CID_DEFAULT; - break; - - } - } -} - -static void _rtl8723ae_hal_customized_behavior(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - switch (rtlhal->oem_id) { - case RT_CID_819x_HP: - pcipriv->ledctl.led_opendrain = true; - break; - case RT_CID_819x_Lenovo: - case RT_CID_DEFAULT: - case RT_CID_TOSHIBA: - case RT_CID_CCX: - case RT_CID_819x_Acer: - case RT_CID_WHQL: - default: - break; - } - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - "RT Customized ID: 0x%02X\n", rtlhal->oem_id); -} - -void rtl8723ae_read_eeprom_info(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - u8 tmp_u1b; - u32 value32; - - value32 = rtl_read_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST]); - value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0); - rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[EFUSE_TEST], value32); - - rtlhal->version = _rtl8723ae_read_chip_version(hw); - - if (get_rf_type(rtlphy) == RF_1T1R) - rtlpriv->dm.rfpath_rxenable[0] = true; - else - rtlpriv->dm.rfpath_rxenable[0] = - rtlpriv->dm.rfpath_rxenable[1] = true; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n", - rtlhal->version); - - tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); - if (tmp_u1b & BIT(4)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n"); - rtlefuse->epromtype = EEPROM_93C46; - } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n"); - rtlefuse->epromtype = EEPROM_BOOT_EFUSE; - } - if (tmp_u1b & BIT(5)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); - rtlefuse->autoload_failflag = false; - _rtl8723ae_read_adapter_info(hw, false); - } else { - rtlefuse->autoload_failflag = true; - _rtl8723ae_read_adapter_info(hw, false); - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Autoload ERR!!\n"); - } - _rtl8723ae_hal_customized_behavior(hw); -} - -static void rtl8723ae_update_hal_rate_table(struct ieee80211_hw *hw, - struct ieee80211_sta *sta) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - u32 ratr_value; - u8 ratr_index = 0; - u8 nmode = mac->ht_enable; - u8 mimo_ps = IEEE80211_SMPS_OFF; - u8 curtxbw_40mhz = mac->bw_40; - u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? - 1 : 0; - u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? - 1 : 0; - enum wireless_mode wirelessmode = mac->mode; - - if (rtlhal->current_bandtype == BAND_ON_5G) - ratr_value = sta->supp_rates[1] << 4; - else - ratr_value = sta->supp_rates[0]; - if (mac->opmode == NL80211_IFTYPE_ADHOC) - ratr_value = 0xfff; - ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 | - sta->ht_cap.mcs.rx_mask[0] << 12); - switch (wirelessmode) { - case WIRELESS_MODE_B: - if (ratr_value & 0x0000000c) - ratr_value &= 0x0000000d; - else - ratr_value &= 0x0000000f; - break; - case WIRELESS_MODE_G: - ratr_value &= 0x00000FF5; - break; - case WIRELESS_MODE_N_24G: - case WIRELESS_MODE_N_5G: - nmode = 1; - if (mimo_ps == IEEE80211_SMPS_STATIC) { - ratr_value &= 0x0007F005; - } else { - u32 ratr_mask; - - if (get_rf_type(rtlphy) == RF_1T2R || - get_rf_type(rtlphy) == RF_1T1R) - ratr_mask = 0x000ff005; - else - ratr_mask = 0x0f0ff005; - - ratr_value &= ratr_mask; - } - break; - default: - if (rtlphy->rf_type == RF_1T2R) - ratr_value &= 0x000ff0ff; - else - ratr_value &= 0x0f0ff0ff; - - break; - } - - if ((pcipriv->bt_coexist.bt_coexistence) && - (pcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4) && - (pcipriv->bt_coexist.bt_cur_state) && - (pcipriv->bt_coexist.bt_ant_isolation) && - ((pcipriv->bt_coexist.bt_service == BT_SCO) || - (pcipriv->bt_coexist.bt_service == BT_BUSY))) - ratr_value &= 0x0fffcfc0; - else - ratr_value &= 0x0FFFFFFF; - - if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) || - (!curtxbw_40mhz && curshortgi_20mhz))) - ratr_value |= 0x10000000; - - rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); - - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, - "%x\n", rtl_read_dword(rtlpriv, REG_ARFR0)); -} - -static void rtl8723ae_update_hal_rate_mask(struct ieee80211_hw *hw, - struct ieee80211_sta *sta, u8 rssi_level) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl_sta_info *sta_entry = NULL; - u32 ratr_bitmap; - u8 ratr_index; - u8 curtxbw_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) - ? 1 : 0; - u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? - 1 : 0; - u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? - 1 : 0; - enum wireless_mode wirelessmode = 0; - bool shortgi = false; - u8 rate_mask[5]; - u8 macid = 0; - u8 mimo_ps = IEEE80211_SMPS_OFF; - - sta_entry = (struct rtl_sta_info *) sta->drv_priv; - wirelessmode = sta_entry->wireless_mode; - if (mac->opmode == NL80211_IFTYPE_STATION) - curtxbw_40mhz = mac->bw_40; - else if (mac->opmode == NL80211_IFTYPE_AP || - mac->opmode == NL80211_IFTYPE_ADHOC) - macid = sta->aid + 1; - - if (rtlhal->current_bandtype == BAND_ON_5G) - ratr_bitmap = sta->supp_rates[1] << 4; - else - ratr_bitmap = sta->supp_rates[0]; - if (mac->opmode == NL80211_IFTYPE_ADHOC) - ratr_bitmap = 0xfff; - ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 | - sta->ht_cap.mcs.rx_mask[0] << 12); - switch (wirelessmode) { - case WIRELESS_MODE_B: - ratr_index = RATR_INX_WIRELESS_B; - if (ratr_bitmap & 0x0000000c) - ratr_bitmap &= 0x0000000d; - else - ratr_bitmap &= 0x0000000f; - break; - case WIRELESS_MODE_G: - ratr_index = RATR_INX_WIRELESS_GB; - - if (rssi_level == 1) - ratr_bitmap &= 0x00000f00; - else if (rssi_level == 2) - ratr_bitmap &= 0x00000ff0; - else - ratr_bitmap &= 0x00000ff5; - break; - case WIRELESS_MODE_A: - ratr_index = RATR_INX_WIRELESS_A; - ratr_bitmap &= 0x00000ff0; - break; - case WIRELESS_MODE_N_24G: - case WIRELESS_MODE_N_5G: - ratr_index = RATR_INX_WIRELESS_NGB; - - if (mimo_ps == IEEE80211_SMPS_STATIC) { - if (rssi_level == 1) - ratr_bitmap &= 0x00070000; - else if (rssi_level == 2) - ratr_bitmap &= 0x0007f000; - else - ratr_bitmap &= 0x0007f005; - } else { - if (rtlphy->rf_type == RF_1T2R || - rtlphy->rf_type == RF_1T1R) { - if (curtxbw_40mhz) { - if (rssi_level == 1) - ratr_bitmap &= 0x000f0000; - else if (rssi_level == 2) - ratr_bitmap &= 0x000ff000; - else - ratr_bitmap &= 0x000ff015; - } else { - if (rssi_level == 1) - ratr_bitmap &= 0x000f0000; - else if (rssi_level == 2) - ratr_bitmap &= 0x000ff000; - else - ratr_bitmap &= 0x000ff005; - } - } else { - if (curtxbw_40mhz) { - if (rssi_level == 1) - ratr_bitmap &= 0x0f0f0000; - else if (rssi_level == 2) - ratr_bitmap &= 0x0f0ff000; - else - ratr_bitmap &= 0x0f0ff015; - } else { - if (rssi_level == 1) - ratr_bitmap &= 0x0f0f0000; - else if (rssi_level == 2) - ratr_bitmap &= 0x0f0ff000; - else - ratr_bitmap &= 0x0f0ff005; - } - } - } - - if ((curtxbw_40mhz && curshortgi_40mhz) || - (!curtxbw_40mhz && curshortgi_20mhz)) { - if (macid == 0) - shortgi = true; - else if (macid == 1) - shortgi = false; - } - break; - default: - ratr_index = RATR_INX_WIRELESS_NGB; - - if (rtlphy->rf_type == RF_1T2R) - ratr_bitmap &= 0x000ff0ff; - else - ratr_bitmap &= 0x0f0ff0ff; - break; - } - sta_entry->ratr_index = ratr_index; - - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, - "ratr_bitmap :%x\n", ratr_bitmap); - /* convert ratr_bitmap to le byte array */ - rate_mask[0] = ratr_bitmap; - rate_mask[1] = (ratr_bitmap >>= 8); - rate_mask[2] = (ratr_bitmap >>= 8); - rate_mask[3] = ((ratr_bitmap >> 8) & 0x0f) | (ratr_index << 4); - rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, - "Rate_index:%x, ratr_bitmap: %*phC\n", - ratr_index, 5, rate_mask); - rtl8723ae_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask); -} - -void rtl8723ae_update_hal_rate_tbl(struct ieee80211_hw *hw, - struct ieee80211_sta *sta, u8 rssi_level) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - if (rtlpriv->dm.useramask) - rtl8723ae_update_hal_rate_mask(hw, sta, rssi_level); - else - rtl8723ae_update_hal_rate_table(hw, sta); -} - -void rtl8723ae_update_channel_access_setting(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - u16 sifs_timer; - - rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, - (u8 *)&mac->slot_time); - if (!mac->ht_enable) - sifs_timer = 0x0a0a; - else - sifs_timer = 0x1010; - rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); -} - -bool rtl8723ae_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate; - u8 u1tmp; - bool actuallyset = false; - - if (rtlpriv->rtlhal.being_init_adapter) - return false; - - if (ppsc->swrf_processing) - return false; - - spin_lock(&rtlpriv->locks.rf_ps_lock); - if (ppsc->rfchange_inprogress) { - spin_unlock(&rtlpriv->locks.rf_ps_lock); - return false; - } else { - ppsc->rfchange_inprogress = true; - spin_unlock(&rtlpriv->locks.rf_ps_lock); - } - - cur_rfstate = ppsc->rfpwr_state; - - rtl_write_byte(rtlpriv, REG_GPIO_IO_SEL_2, - rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL_2)&~(BIT(1))); - - u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL_2); - - if (rtlphy->polarity_ctl) - e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFOFF : ERFON; - else - e_rfpowerstate_toset = (u1tmp & BIT(1)) ? ERFON : ERFOFF; - - if ((ppsc->hwradiooff == true) && (e_rfpowerstate_toset == ERFON)) { - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - "GPIOChangeRF - HW Radio ON, RF ON\n"); - - e_rfpowerstate_toset = ERFON; - ppsc->hwradiooff = false; - actuallyset = true; - } else if ((ppsc->hwradiooff == false) - && (e_rfpowerstate_toset == ERFOFF)) { - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - "GPIOChangeRF - HW Radio OFF, RF OFF\n"); - - e_rfpowerstate_toset = ERFOFF; - ppsc->hwradiooff = true; - actuallyset = true; - } - - if (actuallyset) { - spin_lock(&rtlpriv->locks.rf_ps_lock); - ppsc->rfchange_inprogress = false; - spin_unlock(&rtlpriv->locks.rf_ps_lock); - } else { - if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) - RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); - - spin_lock(&rtlpriv->locks.rf_ps_lock); - ppsc->rfchange_inprogress = false; - spin_unlock(&rtlpriv->locks.rf_ps_lock); - } - - *valid = 1; - return !ppsc->hwradiooff; -} - -void rtl8723ae_set_key(struct ieee80211_hw *hw, u32 key_index, - u8 *p_macaddr, bool is_group, u8 enc_algo, - bool is_wepkey, bool clear_all) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u8 *macaddr = p_macaddr; - u32 entry_id = 0; - bool is_pairwise = false; - static u8 cam_const_addr[4][6] = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} - }; - static u8 cam_const_broad[] = { - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff - }; - - if (clear_all) { - u8 idx = 0; - u8 cam_offset = 0; - u8 clear_number = 5; - - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); - - for (idx = 0; idx < clear_number; idx++) { - rtl_cam_mark_invalid(hw, cam_offset + idx); - rtl_cam_empty_entry(hw, cam_offset + idx); - - if (idx < 5) { - memset(rtlpriv->sec.key_buf[idx], 0, - MAX_KEY_LEN); - rtlpriv->sec.key_len[idx] = 0; - } - } - } else { - switch (enc_algo) { - case WEP40_ENCRYPTION: - enc_algo = CAM_WEP40; - break; - case WEP104_ENCRYPTION: - enc_algo = CAM_WEP104; - break; - case TKIP_ENCRYPTION: - enc_algo = CAM_TKIP; - break; - case AESCCMP_ENCRYPTION: - enc_algo = CAM_AES; - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not processed\n"); - enc_algo = CAM_TKIP; - break; - } - - if (is_wepkey || rtlpriv->sec.use_defaultkey) { - macaddr = cam_const_addr[key_index]; - entry_id = key_index; - } else { - if (is_group) { - macaddr = cam_const_broad; - entry_id = key_index; - } else { - if (mac->opmode == NL80211_IFTYPE_AP) { - entry_id = rtl_cam_get_free_entry(hw, - macaddr); - if (entry_id >= TOTAL_CAM_ENTRY) { - RT_TRACE(rtlpriv, COMP_SEC, - DBG_EMERG, - "Can not find free hw security cam entry\n"); - return; - } - } else { - entry_id = CAM_PAIRWISE_KEY_POSITION; - } - - key_index = PAIRWISE_KEYIDX; - is_pairwise = true; - } - } - - if (rtlpriv->sec.key_len[key_index] == 0) { - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "delete one entry, entry_id is %d\n", - entry_id); - if (mac->opmode == NL80211_IFTYPE_AP) - rtl_cam_del_entry(hw, p_macaddr); - rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); - } else { - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "add one entry\n"); - if (is_pairwise) { - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "set Pairwiase key\n"); - - rtl_cam_add_one_entry(hw, macaddr, key_index, - entry_id, enc_algo, - CAM_CONFIG_NO_USEDK, - rtlpriv->sec.key_buf[key_index]); - } else { - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - "set group key\n"); - - if (mac->opmode == NL80211_IFTYPE_ADHOC) { - rtl_cam_add_one_entry(hw, - rtlefuse->dev_addr, - PAIRWISE_KEYIDX, - CAM_PAIRWISE_KEY_POSITION, - enc_algo, - CAM_CONFIG_NO_USEDK, - rtlpriv->sec.key_buf - [entry_id]); - } - - rtl_cam_add_one_entry(hw, macaddr, key_index, - entry_id, enc_algo, - CAM_CONFIG_NO_USEDK, - rtlpriv->sec.key_buf[entry_id]); - } - - } - } -} - -static void rtl8723ae_bt_var_init(struct ieee80211_hw *hw) -{ - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - - pcipriv->bt_coexist.bt_coexistence = - pcipriv->bt_coexist.eeprom_bt_coexist; - pcipriv->bt_coexist.bt_ant_num = - pcipriv->bt_coexist.eeprom_bt_ant_num; - pcipriv->bt_coexist.bt_coexist_type = - pcipriv->bt_coexist.eeprom_bt_type; - - pcipriv->bt_coexist.bt_ant_isolation = - pcipriv->bt_coexist.eeprom_bt_ant_isol; - - pcipriv->bt_coexist.bt_radio_shared_type = - pcipriv->bt_coexist.eeprom_bt_radio_shared; - - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "BT Coexistance = 0x%x\n", - pcipriv->bt_coexist.bt_coexistence); - - if (pcipriv->bt_coexist.bt_coexistence) { - pcipriv->bt_coexist.bt_busy_traffic = false; - pcipriv->bt_coexist.bt_traffic_mode_set = false; - pcipriv->bt_coexist.bt_non_traffic_mode_set = false; - - pcipriv->bt_coexist.cstate = 0; - pcipriv->bt_coexist.previous_state = 0; - - if (pcipriv->bt_coexist.bt_ant_num == ANT_X2) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "BlueTooth BT_Ant_Num = Antx2\n"); - } else if (pcipriv->bt_coexist.bt_ant_num == ANT_X1) { - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "BlueTooth BT_Ant_Num = Antx1\n"); - } - - switch (pcipriv->bt_coexist.bt_coexist_type) { - case BT_2WIRE: - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "BlueTooth BT_CoexistType = BT_2Wire\n"); - break; - case BT_ISSC_3WIRE: - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "BlueTooth BT_CoexistType = BT_ISSC_3Wire\n"); - break; - case BT_ACCEL: - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "BlueTooth BT_CoexistType = BT_ACCEL\n"); - break; - case BT_CSR_BC4: - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "BlueTooth BT_CoexistType = BT_CSR_BC4\n"); - break; - case BT_CSR_BC8: - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "BlueTooth BT_CoexistType = BT_CSR_BC8\n"); - break; - case BT_RTL8756: - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "BlueTooth BT_CoexistType = BT_RTL8756\n"); - break; - default: - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "BlueTooth BT_CoexistType = Unknown\n"); - break; - } - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "BlueTooth BT_Ant_isolation = %d\n", - pcipriv->bt_coexist.bt_ant_isolation); - RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE, - "BT_RadioSharedType = 0x%x\n", - pcipriv->bt_coexist.bt_radio_shared_type); - pcipriv->bt_coexist.bt_active_zero_cnt = 0; - pcipriv->bt_coexist.cur_bt_disabled = false; - pcipriv->bt_coexist.pre_bt_disabled = false; - } -} - -void rtl8723ae_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, - bool auto_load_fail, u8 *hwinfo) -{ - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 value; - u32 tmpu_32; - - if (!auto_load_fail) { - tmpu_32 = rtl_read_dword(rtlpriv, REG_MULTI_FUNC_CTRL); - if (tmpu_32 & BIT(18)) - pcipriv->bt_coexist.eeprom_bt_coexist = 1; - else - pcipriv->bt_coexist.eeprom_bt_coexist = 0; - value = hwinfo[RF_OPTION4]; - pcipriv->bt_coexist.eeprom_bt_type = BT_RTL8723A; - pcipriv->bt_coexist.eeprom_bt_ant_num = (value & 0x1); - pcipriv->bt_coexist.eeprom_bt_ant_isol = ((value & 0x10) >> 4); - pcipriv->bt_coexist.eeprom_bt_radio_shared = - ((value & 0x20) >> 5); - } else { - pcipriv->bt_coexist.eeprom_bt_coexist = 0; - pcipriv->bt_coexist.eeprom_bt_type = BT_RTL8723A; - pcipriv->bt_coexist.eeprom_bt_ant_num = ANT_X2; - pcipriv->bt_coexist.eeprom_bt_ant_isol = 0; - pcipriv->bt_coexist.eeprom_bt_radio_shared = BT_RADIO_SHARED; - } - - rtl8723ae_bt_var_init(hw); -} - -void rtl8723ae_bt_reg_init(struct ieee80211_hw *hw) -{ - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - - /* 0:Low, 1:High, 2:From Efuse. */ - pcipriv->bt_coexist.reg_bt_iso = 2; - /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */ - pcipriv->bt_coexist.reg_bt_sco = 3; - /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */ - pcipriv->bt_coexist.reg_bt_sco = 0; -} - - -void rtl8723ae_bt_hw_init(struct ieee80211_hw *hw) -{ -} - -void rtl8723ae_suspend(struct ieee80211_hw *hw) -{ -} - -void rtl8723ae_resume(struct ieee80211_hw *hw) -{ -} - -/* Turn on AAP (RCR:bit 0) for promicuous mode. */ -void rtl8723ae_allow_all_destaddr(struct ieee80211_hw *hw, - bool allow_all_da, bool write_into_reg) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - - if (allow_all_da) /* Set BIT0 */ - rtlpci->receive_config |= RCR_AAP; - else /* Clear BIT0 */ - rtlpci->receive_config &= ~RCR_AAP; - - if (write_into_reg) - rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); - - - RT_TRACE(rtlpriv, COMP_TURBO | COMP_INIT, DBG_LOUD, - "receive_config=0x%08X, write_into_reg=%d\n", - rtlpci->receive_config, write_into_reg); -} diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hw.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hw.h deleted file mode 100644 index 6fa24f79b1d7..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/hw.h +++ /dev/null @@ -1,73 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL8723E_HW_H__ -#define __RTL8723E_HW_H__ - -#define CHK_SVID_SMID(_val1, _val2) \ - ((rtlefuse->eeprom_svid == (_val1)) && \ - (rtlefuse->eeprom_smid == (_val2))) - -void rtl8723ae_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); -void rtl8723ae_read_eeprom_info(struct ieee80211_hw *hw); - -void rtl8723ae_interrupt_recognized(struct ieee80211_hw *hw, - u32 *p_inta, u32 *p_intb); -int rtl8723ae_hw_init(struct ieee80211_hw *hw); -void rtl8723ae_card_disable(struct ieee80211_hw *hw); -void rtl8723ae_enable_interrupt(struct ieee80211_hw *hw); -void rtl8723ae_disable_interrupt(struct ieee80211_hw *hw); -int rtl8723ae_set_network_type(struct ieee80211_hw *hw, - enum nl80211_iftype type); -void rtl8723ae_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid); -void rtl8723ae_set_qos(struct ieee80211_hw *hw, int aci); -void rtl8723ae_set_beacon_related_registers(struct ieee80211_hw *hw); -void rtl8723ae_set_beacon_interval(struct ieee80211_hw *hw); -void rtl8723ae_update_interrupt_mask(struct ieee80211_hw *hw, - u32 add_msr, u32 rm_msr); -void rtl8723ae_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val); -void rtl8723ae_update_hal_rate_tbl(struct ieee80211_hw *hw, - struct ieee80211_sta *sta, u8 rssi_level); -void rtl8723ae_update_channel_access_setting(struct ieee80211_hw *hw); -bool rtl8723ae_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid); -void rtl8723ae_enable_hw_security_config(struct ieee80211_hw *hw); -void rtl8723ae_set_key(struct ieee80211_hw *hw, u32 key_index, - u8 *p_macaddr, bool is_group, u8 enc_algo, - bool is_wepkey, bool clear_all); - -void rtl8723ae_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, - bool autoload_fail, u8 *hwinfo); -void rtl8723ae_bt_reg_init(struct ieee80211_hw *hw); -void rtl8723ae_bt_hw_init(struct ieee80211_hw *hw); -void rtl8723ae_suspend(struct ieee80211_hw *hw); -void rtl8723ae_resume(struct ieee80211_hw *hw); -void rtl8723ae_allow_all_destaddr(struct ieee80211_hw *hw, - bool allow_all_da, bool write_into_reg); - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/led.c b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/led.c deleted file mode 100644 index 9c4e1d811187..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/led.c +++ /dev/null @@ -1,151 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#include "../wifi.h" -#include "../pci.h" -#include "reg.h" -#include "led.h" - -static void _rtl8723ae_init_led(struct ieee80211_hw *hw, - struct rtl_led *pled, enum rtl_led_pin ledpin) -{ - pled->hw = hw; - pled->ledpin = ledpin; - pled->ledon = false; -} - -void rtl8723ae_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 ledcfg; - - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, - "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin); - - ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); - - switch (pled->ledpin) { - case LED_PIN_GPIO0: - break; - case LED_PIN_LED0: - rtl_write_byte(rtlpriv, - REG_LEDCFG2, (ledcfg & 0xf0) | BIT(5) | BIT(6)); - break; - case LED_PIN_LED1: - rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg & 0x0f) | BIT(5)); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not processed\n"); - break; - } - pled->ledon = true; -} - -void rtl8723ae_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - u8 ledcfg; - - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, - "LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin); - - ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); - - switch (pled->ledpin) { - case LED_PIN_GPIO0: - break; - case LED_PIN_LED0: - ledcfg &= 0xf0; - if (pcipriv->ledctl.led_opendrain) - rtl_write_byte(rtlpriv, REG_LEDCFG2, - (ledcfg | BIT(1) | BIT(5) | BIT(6))); - else - rtl_write_byte(rtlpriv, REG_LEDCFG2, - (ledcfg | BIT(3) | BIT(5) | BIT(6))); - break; - case LED_PIN_LED1: - ledcfg &= 0x0f; - rtl_write_byte(rtlpriv, REG_LEDCFG2, (ledcfg | BIT(3))); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not processed\n"); - break; - } - pled->ledon = false; -} - -void rtl8723ae_init_sw_leds(struct ieee80211_hw *hw) -{ - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - - _rtl8723ae_init_led(hw, &(pcipriv->ledctl.sw_led0), LED_PIN_LED0); - _rtl8723ae_init_led(hw, &(pcipriv->ledctl.sw_led1), LED_PIN_LED1); -} - -static void _rtl8723ae_sw_led_control(struct ieee80211_hw *hw, - enum led_ctl_mode ledaction) -{ - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0); - - switch (ledaction) { - case LED_CTL_POWER_ON: - case LED_CTL_LINK: - case LED_CTL_NO_LINK: - rtl8723ae_sw_led_on(hw, pLed0); - break; - case LED_CTL_POWER_OFF: - rtl8723ae_sw_led_off(hw, pLed0); - break; - default: - break; - } -} - -void rtl8723ae_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - - if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) && - (ledaction == LED_CTL_TX || - ledaction == LED_CTL_RX || - ledaction == LED_CTL_SITE_SURVEY || - ledaction == LED_CTL_LINK || - ledaction == LED_CTL_NO_LINK || - ledaction == LED_CTL_START_TO_LINK || - ledaction == LED_CTL_POWER_ON)) { - return; - } - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d,\n", ledaction); - _rtl8723ae_sw_led_control(hw, ledaction); -} diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/led.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/led.h deleted file mode 100644 index 2cb88e78f62a..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/led.h +++ /dev/null @@ -1,39 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL92CE_LED_H__ -#define __RTL92CE_LED_H__ - -void rtl8723ae_init_sw_leds(struct ieee80211_hw *hw); -void rtl8723ae_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled); -void rtl8723ae_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled); -void rtl8723ae_led_control(struct ieee80211_hw *hw, - enum led_ctl_mode ledaction); - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c deleted file mode 100644 index 39cc7938eedf..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/phy.c +++ /dev/null @@ -1,2044 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#include "../wifi.h" -#include "../pci.h" -#include "../ps.h" -#include "reg.h" -#include "def.h" -#include "phy.h" -#include "rf.h" -#include "dm.h" -#include "table.h" - -/* static forward definitions */ -static u32 _phy_fw_rf_serial_read(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset); -static void _phy_fw_rf_serial_write(struct ieee80211_hw *hw, - enum radio_path rfpath, - u32 offset, u32 data); -static u32 _phy_rf_serial_read(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset); -static void _phy_rf_serial_write(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset, u32 data); -static u32 _phy_calculate_bit_shift(u32 bitmask); -static bool _phy_bb8192c_config_parafile(struct ieee80211_hw *hw); -static bool _phy_cfg_mac_w_header(struct ieee80211_hw *hw); -static bool _phy_cfg_bb_w_header(struct ieee80211_hw *hw, u8 configtype); -static bool _phy_cfg_bb_w_pgheader(struct ieee80211_hw *hw, u8 configtype); -static void _phy_init_bb_rf_reg_def(struct ieee80211_hw *hw); -static bool _phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, - u32 cmdtableidx, u32 cmdtablesz, - enum swchnlcmd_id cmdid, - u32 para1, u32 para2, - u32 msdelay); -static bool _phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, u8 channel, - u8 *stage, u8 *step, u32 *delay); -static u8 _phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, - enum wireless_mode wirelessmode, - long power_indbm); -static long _phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, - enum wireless_mode wirelessmode, u8 txpwridx); -static void rtl8723ae_phy_set_io(struct ieee80211_hw *hw); - -u32 rtl8723ae_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, - u32 bitmask) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 returnvalue, originalvalue, bitshift; - - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask); - originalvalue = rtl_read_dword(rtlpriv, regaddr); - bitshift = _phy_calculate_bit_shift(bitmask); - returnvalue = (originalvalue & bitmask) >> bitshift; - - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - "BBR MASK=0x%x Addr[0x%x]=0x%x\n", bitmask, regaddr, - originalvalue); - - return returnvalue; -} - -void rtl8723ae_phy_set_bb_reg(struct ieee80211_hw *hw, - u32 regaddr, u32 bitmask, u32 data) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 originalvalue, bitshift; - - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - "regaddr(%#x), bitmask(%#x), data(%#x)\n", regaddr, - bitmask, data); - - if (bitmask != MASKDWORD) { - originalvalue = rtl_read_dword(rtlpriv, regaddr); - bitshift = _phy_calculate_bit_shift(bitmask); - data = ((originalvalue & (~bitmask)) | (data << bitshift)); - } - - rtl_write_dword(rtlpriv, regaddr, data); - - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - "regaddr(%#x), bitmask(%#x), data(%#x)\n", - regaddr, bitmask, data); -} - -u32 rtl8723ae_phy_query_rf_reg(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 regaddr, u32 bitmask) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 original_value, readback_value, bitshift; - struct rtl_phy *rtlphy = &(rtlpriv->phy); - unsigned long flags; - - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", - regaddr, rfpath, bitmask); - - spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); - - if (rtlphy->rf_mode != RF_OP_BY_FW) - original_value = _phy_rf_serial_read(hw, rfpath, regaddr); - else - original_value = _phy_fw_rf_serial_read(hw, rfpath, regaddr); - - bitshift = _phy_calculate_bit_shift(bitmask); - readback_value = (original_value & bitmask) >> bitshift; - - spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); - - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", - regaddr, rfpath, bitmask, original_value); - - return readback_value; -} - -void rtl8723ae_phy_set_rf_reg(struct ieee80211_hw *hw, - enum radio_path rfpath, - u32 regaddr, u32 bitmask, u32 data) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - u32 original_value, bitshift; - unsigned long flags; - - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", - regaddr, bitmask, data, rfpath); - - spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); - - if (rtlphy->rf_mode != RF_OP_BY_FW) { - if (bitmask != RFREG_OFFSET_MASK) { - original_value = _phy_rf_serial_read(hw, rfpath, - regaddr); - bitshift = _phy_calculate_bit_shift(bitmask); - data = ((original_value & (~bitmask)) | - (data << bitshift)); - } - - _phy_rf_serial_write(hw, rfpath, regaddr, data); - } else { - if (bitmask != RFREG_OFFSET_MASK) { - original_value = _phy_fw_rf_serial_read(hw, rfpath, - regaddr); - bitshift = _phy_calculate_bit_shift(bitmask); - data = ((original_value & (~bitmask)) | - (data << bitshift)); - } - _phy_fw_rf_serial_write(hw, rfpath, regaddr, data); - } - - spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); - - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", - regaddr, bitmask, data, rfpath); -} - -static u32 _phy_fw_rf_serial_read(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset) -{ - RT_ASSERT(false, "deprecated!\n"); - return 0; -} - -static void _phy_fw_rf_serial_write(struct ieee80211_hw *hw, - enum radio_path rfpath, - u32 offset, u32 data) -{ - RT_ASSERT(false, "deprecated!\n"); -} - -static u32 _phy_rf_serial_read(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; - u32 newoffset; - u32 tmplong, tmplong2; - u8 rfpi_enable = 0; - u32 retvalue; - - offset &= 0x3f; - newoffset = offset; - if (RT_CANNOT_IO(hw)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "return all one\n"); - return 0xFFFFFFFF; - } - tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD); - if (rfpath == RF90_PATH_A) - tmplong2 = tmplong; - else - tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD); - tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) | - (newoffset << 23) | BLSSIREADEDGE; - rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, - tmplong & (~BLSSIREADEDGE)); - mdelay(1); - rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2); - mdelay(1); - rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, - tmplong | BLSSIREADEDGE); - mdelay(1); - if (rfpath == RF90_PATH_A) - rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, - BIT(8)); - else if (rfpath == RF90_PATH_B) - rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, - BIT(8)); - if (rfpi_enable) - retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi, - BLSSIREADBACKDATA); - else - retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb, - BLSSIREADBACKDATA); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n", - rfpath, pphyreg->rf_rb, retvalue); - return retvalue; -} - -static void _phy_rf_serial_write(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 offset, u32 data) -{ - u32 data_and_addr; - u32 newoffset; - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; - - if (RT_CANNOT_IO(hw)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "stop\n"); - return; - } - offset &= 0x3f; - newoffset = offset; - data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; - rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n", - rfpath, pphyreg->rf3wire_offset, data_and_addr); -} - -static u32 _phy_calculate_bit_shift(u32 bitmask) -{ - u32 i; - - for (i = 0; i <= 31; i++) { - if (((bitmask >> i) & 0x1) == 1) - break; - } - return i; -} - -static void _rtl8723ae_phy_bb_config_1t(struct ieee80211_hw *hw) -{ - rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2); - rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022); - rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45); - rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23); - rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1); - rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2); - rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2); - rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2); - rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2); - rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2); -} - -bool rtl8723ae_phy_mac_config(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - bool rtstatus = _phy_cfg_mac_w_header(hw); - rtl_write_byte(rtlpriv, 0x04CA, 0x0A); - return rtstatus; -} - -bool rtl8723ae_phy_bb_config(struct ieee80211_hw *hw) -{ - bool rtstatus = true; - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 tmpu1b; - u8 reg_hwparafile = 1; - - _phy_init_bb_rf_reg_def(hw); - - /* 1. 0x28[1] = 1 */ - tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_PLL_CTRL); - udelay(2); - rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, (tmpu1b|BIT(1))); - udelay(2); - /* 2. 0x29[7:0] = 0xFF */ - rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL+1, 0xff); - udelay(2); - - /* 3. 0x02[1:0] = 2b'11 */ - tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, (tmpu1b | - FEN_BB_GLB_RSTn | FEN_BBRSTB)); - - /* 4. 0x25[6] = 0 */ - tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+1); - rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+1, (tmpu1b&(~BIT(6)))); - - /* 5. 0x24[20] = 0 Advised by SD3 Alex Wang. 2011.02.09. */ - tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+2); - rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+2, (tmpu1b&(~BIT(4)))); - - /* 6. 0x1f[7:0] = 0x07 */ - rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x07); - - if (reg_hwparafile == 1) - rtstatus = _phy_bb8192c_config_parafile(hw); - return rtstatus; -} - -bool rtl8723ae_phy_rf_config(struct ieee80211_hw *hw) -{ - return rtl8723ae_phy_rf6052_config(hw); -} - -static bool _phy_bb8192c_config_parafile(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - bool rtstatus; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "==>\n"); - rtstatus = _phy_cfg_bb_w_header(hw, BASEBAND_CONFIG_PHY_REG); - if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!"); - return false; - } - - if (rtlphy->rf_type == RF_1T2R) { - _rtl8723ae_phy_bb_config_1t(hw); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n"); - } - if (rtlefuse->autoload_failflag == false) { - rtlphy->pwrgroup_cnt = 0; - rtstatus = _phy_cfg_bb_w_pgheader(hw, BASEBAND_CONFIG_PHY_REG); - } - if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!"); - return false; - } - rtstatus = _phy_cfg_bb_w_header(hw, BASEBAND_CONFIG_AGC_TAB); - if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n"); - return false; - } - rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw, - RFPGA0_XA_HSSIPARAMETER2, 0x200)); - return true; -} - -static bool _phy_cfg_mac_w_header(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 i; - u32 arraylength; - u32 *ptrarray; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl723MACPHY_Array\n"); - arraylength = RTL8723E_MACARRAYLENGTH; - ptrarray = RTL8723EMAC_ARRAY; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Img:RTL8192CEMAC_2T_ARRAY\n"); - for (i = 0; i < arraylength; i = i + 2) - rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]); - return true; -} - -static bool _phy_cfg_bb_w_header(struct ieee80211_hw *hw, u8 configtype) -{ - int i; - u32 *phy_regarray_table; - u32 *agctab_array_table; - u16 phy_reg_arraylen, agctab_arraylen; - struct rtl_priv *rtlpriv = rtl_priv(hw); - - agctab_arraylen = RTL8723E_AGCTAB_1TARRAYLENGTH; - agctab_array_table = RTL8723EAGCTAB_1TARRAY; - phy_reg_arraylen = RTL8723E_PHY_REG_1TARRAY_LENGTH; - phy_regarray_table = RTL8723EPHY_REG_1TARRAY; - if (configtype == BASEBAND_CONFIG_PHY_REG) { - for (i = 0; i < phy_reg_arraylen; i = i + 2) { - if (phy_regarray_table[i] == 0xfe) - mdelay(50); - else if (phy_regarray_table[i] == 0xfd) - mdelay(5); - else if (phy_regarray_table[i] == 0xfc) - mdelay(1); - else if (phy_regarray_table[i] == 0xfb) - udelay(50); - else if (phy_regarray_table[i] == 0xfa) - udelay(5); - else if (phy_regarray_table[i] == 0xf9) - udelay(1); - rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD, - phy_regarray_table[i + 1]); - udelay(1); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "The phy_regarray_table[0] is %x" - " Rtl819XPHY_REGArray[1] is %x\n", - phy_regarray_table[i], - phy_regarray_table[i + 1]); - } - } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { - for (i = 0; i < agctab_arraylen; i = i + 2) { - rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD, - agctab_array_table[i + 1]); - udelay(1); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "The agctab_array_table[0] is " - "%x Rtl819XPHY_REGArray[1] is %x\n", - agctab_array_table[i], - agctab_array_table[i + 1]); - } - } - return true; -} - -static void _st_pwrIdx_dfrate_off(struct ieee80211_hw *hw, u32 regaddr, - u32 bitmask, u32 data) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - switch (regaddr) { - case RTXAGC_A_RATE18_06: - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][0] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][0]); - break; - case RTXAGC_A_RATE54_24: - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][1] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][1]); - break; - case RTXAGC_A_CCK1_MCS32: - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][6] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][6]); - break; - case RTXAGC_B_CCK11_A_CCK2_11: - if (bitmask == 0xffffff00) { - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][7] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][7]); - } - if (bitmask == 0x000000ff) { - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][15] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][15]); - } - break; - case RTXAGC_A_MCS03_MCS00: - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][2] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][2]); - break; - case RTXAGC_A_MCS07_MCS04: - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][3] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][3]); - break; - case RTXAGC_A_MCS11_MCS08: - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][4] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][4]); - break; - case RTXAGC_A_MCS15_MCS12: - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][5] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][5]); - break; - case RTXAGC_B_RATE18_06: - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][8] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][8]); - break; - case RTXAGC_B_RATE54_24: - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][9] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][9]); - break; - case RTXAGC_B_CCK1_55_MCS32: - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][14] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][14]); - break; - case RTXAGC_B_MCS03_MCS00: - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][10] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][10]); - break; - case RTXAGC_B_MCS07_MCS04: - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][11] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][11]); - break; - case RTXAGC_B_MCS11_MCS08: - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][12] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][12]); - break; - case RTXAGC_B_MCS15_MCS12: - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][13] = data; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][13]); - rtlphy->pwrgroup_cnt++; - break; - } -} - -static bool _phy_cfg_bb_w_pgheader(struct ieee80211_hw *hw, u8 configtype) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - int i; - u32 *phy_regarray_table_pg; - u16 phy_regarray_pg_len; - - phy_regarray_pg_len = RTL8723E_PHY_REG_ARRAY_PGLENGTH; - phy_regarray_table_pg = RTL8723EPHY_REG_ARRAY_PG; - - if (configtype == BASEBAND_CONFIG_PHY_REG) { - for (i = 0; i < phy_regarray_pg_len; i = i + 3) { - if (phy_regarray_table_pg[i] == 0xfe) - mdelay(50); - else if (phy_regarray_table_pg[i] == 0xfd) - mdelay(5); - else if (phy_regarray_table_pg[i] == 0xfc) - mdelay(1); - else if (phy_regarray_table_pg[i] == 0xfb) - udelay(50); - else if (phy_regarray_table_pg[i] == 0xfa) - udelay(5); - else if (phy_regarray_table_pg[i] == 0xf9) - udelay(1); - - _st_pwrIdx_dfrate_off(hw, phy_regarray_table_pg[i], - phy_regarray_table_pg[i + 1], - phy_regarray_table_pg[i + 2]); - } - } else { - RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, - "configtype != BaseBand_Config_PHY_REG\n"); - } - return true; -} - -bool rtl8723ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, - enum radio_path rfpath) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - int i; - bool rtstatus = true; - u32 *radioa_array_table; - u32 *radiob_array_table; - u16 radioa_arraylen, radiob_arraylen; - - radioa_arraylen = Rtl8723ERADIOA_1TARRAYLENGTH; - radioa_array_table = RTL8723E_RADIOA_1TARRAY; - radiob_arraylen = RTL8723E_RADIOB_1TARRAYLENGTH; - radiob_array_table = RTL8723E_RADIOB_1TARRAY; - - rtstatus = true; - - switch (rfpath) { - case RF90_PATH_A: - for (i = 0; i < radioa_arraylen; i = i + 2) { - if (radioa_array_table[i] == 0xfe) - mdelay(50); - else if (radioa_array_table[i] == 0xfd) - mdelay(5); - else if (radioa_array_table[i] == 0xfc) - mdelay(1); - else if (radioa_array_table[i] == 0xfb) - udelay(50); - else if (radioa_array_table[i] == 0xfa) - udelay(5); - else if (radioa_array_table[i] == 0xf9) - udelay(1); - else { - rtl_set_rfreg(hw, rfpath, radioa_array_table[i], - RFREG_OFFSET_MASK, - radioa_array_table[i + 1]); - udelay(1); - } - } - break; - case RF90_PATH_B: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not process\n"); - break; - case RF90_PATH_C: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not process\n"); - break; - case RF90_PATH_D: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not process\n"); - break; - } - return true; -} - -void rtl8723ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - rtlphy->default_initialgain[0] = - (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); - rtlphy->default_initialgain[1] = - (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); - rtlphy->default_initialgain[2] = - (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0); - rtlphy->default_initialgain[3] = - (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n", - rtlphy->default_initialgain[0], - rtlphy->default_initialgain[1], - rtlphy->default_initialgain[2], - rtlphy->default_initialgain[3]); - - rtlphy->framesync = (u8) rtl_get_bbreg(hw, - ROFDM0_RXDETECTOR3, MASKBYTE0); - rtlphy->framesync_c34 = rtl_get_bbreg(hw, - ROFDM0_RXDETECTOR2, MASKDWORD); - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Default framesync (0x%x) = 0x%x\n", - ROFDM0_RXDETECTOR3, rtlphy->framesync); -} - -static void _phy_init_bb_rf_reg_def(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; - rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; - rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW; - rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW; - - rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB; - rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB; - rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB; - rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB; - - rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; - rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; - - rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; - rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; - - rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = - RFPGA0_XA_LSSIPARAMETER; - rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = - RFPGA0_XB_LSSIPARAMETER; - - rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = rFPGA0_XAB_RFPARAMETER; - rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = rFPGA0_XAB_RFPARAMETER; - rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = rFPGA0_XCD_RFPARAMETER; - rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = rFPGA0_XCD_RFPARAMETER; - - rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE; - rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE; - rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE; - rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE; - - rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1; - rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1; - - rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; - rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; - - rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; - rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; - rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; - rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; - - rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; - rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1; - rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1; - rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1; - - rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2; - rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2; - rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2; - rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; - - rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBANLANCE; - rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE; - - rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; - rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE; - rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE; - rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; - - rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE; - rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE; - - rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; - rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE; - rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE; - rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE; - - rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK; - rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK; - - rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVEA_HSPI_READBACK; - rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVEB_HSPI_READBACK; -} - -void rtl8723ae_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u8 txpwr_level; - long txpwr_dbm; - - txpwr_level = rtlphy->cur_cck_txpwridx; - txpwr_dbm = _phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B, txpwr_level); - txpwr_level = rtlphy->cur_ofdm24g_txpwridx + - rtlefuse->legacy_ht_txpowerdiff; - if (_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) > txpwr_dbm) - txpwr_dbm = _phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, - txpwr_level); - txpwr_level = rtlphy->cur_ofdm24g_txpwridx; - if (_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, txpwr_level) > - txpwr_dbm) - txpwr_dbm = _phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, - txpwr_level); - *powerlevel = txpwr_dbm; -} - -static void _rtl8723ae_get_txpower_index(struct ieee80211_hw *hw, u8 channel, - u8 *cckpowerlevel, u8 *ofdmpowerlevel) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u8 index = (channel - 1); - - cckpowerlevel[RF90_PATH_A] = - rtlefuse->txpwrlevel_cck[RF90_PATH_A][index]; - cckpowerlevel[RF90_PATH_B] = - rtlefuse->txpwrlevel_cck[RF90_PATH_B][index]; - if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) { - ofdmpowerlevel[RF90_PATH_A] = - rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index]; - ofdmpowerlevel[RF90_PATH_B] = - rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index]; - } else if (get_rf_type(rtlphy) == RF_2T2R) { - ofdmpowerlevel[RF90_PATH_A] = - rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index]; - ofdmpowerlevel[RF90_PATH_B] = - rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index]; - } -} - -static void _rtl8723ae_ccxpower_index_check(struct ieee80211_hw *hw, - u8 channel, u8 *cckpowerlevel, - u8 *ofdmpowerlevel) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - rtlphy->cur_cck_txpwridx = cckpowerlevel[0]; - rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0]; -} - -void rtl8723ae_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) -{ - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u8 cckpowerlevel[2], ofdmpowerlevel[2]; - - if (rtlefuse->txpwr_fromeprom == false) - return; - _rtl8723ae_get_txpower_index(hw, channel, &cckpowerlevel[0], - &ofdmpowerlevel[0]); - _rtl8723ae_ccxpower_index_check(hw, channel, &cckpowerlevel[0], - &ofdmpowerlevel[0]); - rtl8723ae_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]); - rtl8723ae_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel); -} - -bool rtl8723ae_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u8 idx; - u8 rf_path; - u8 ccktxpwridx = _phy_dbm_to_txpwr_Idx(hw, WIRELESS_MODE_B, - power_indbm); - u8 ofdmtxpwridx = _phy_dbm_to_txpwr_Idx(hw, WIRELESS_MODE_N_24G, - power_indbm); - if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0) - ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff; - else - ofdmtxpwridx = 0; - RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE, - "%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n", - power_indbm, ccktxpwridx, ofdmtxpwridx); - for (idx = 0; idx < 14; idx++) { - for (rf_path = 0; rf_path < 2; rf_path++) { - rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx; - rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] = - ofdmtxpwridx; - rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] = - ofdmtxpwridx; - } - } - rtl8723ae_phy_set_txpower_level(hw, rtlphy->current_channel); - return true; -} - -static u8 _phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, - enum wireless_mode wirelessmode, - long power_indbm) -{ - u8 txpwridx; - long offset; - - switch (wirelessmode) { - case WIRELESS_MODE_B: - offset = -7; - break; - case WIRELESS_MODE_G: - case WIRELESS_MODE_N_24G: - offset = -8; - break; - default: - offset = -8; - break; - } - - if ((power_indbm - offset) > 0) - txpwridx = (u8) ((power_indbm - offset) * 2); - else - txpwridx = 0; - - if (txpwridx > MAX_TXPWR_IDX_NMODE_92S) - txpwridx = MAX_TXPWR_IDX_NMODE_92S; - - return txpwridx; -} - -static long _phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, - enum wireless_mode wirelessmode, u8 txpwridx) -{ - long offset; - long pwrout_dbm; - - switch (wirelessmode) { - case WIRELESS_MODE_B: - offset = -7; - break; - case WIRELESS_MODE_G: - case WIRELESS_MODE_N_24G: - offset = -8; - break; - default: - offset = -8; - break; - } - pwrout_dbm = txpwridx / 2 + offset; - return pwrout_dbm; -} - -void rtl8723ae_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - enum io_type iotype; - - if (!is_hal_stop(rtlhal)) { - switch (operation) { - case SCAN_OPT_BACKUP: - iotype = IO_CMD_PAUSE_DM_BY_SCAN; - rtlpriv->cfg->ops->set_hw_reg(hw, - HW_VAR_IO_CMD, - (u8 *)&iotype); - - break; - case SCAN_OPT_RESTORE: - iotype = IO_CMD_RESUME_DM_BY_SCAN; - rtlpriv->cfg->ops->set_hw_reg(hw, - HW_VAR_IO_CMD, - (u8 *)&iotype); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Unknown Scan Backup operation.\n"); - break; - } - } -} - -void rtl8723ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - u8 reg_bw_opmode; - u8 reg_prsr_rsc; - - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, - "Switch to %s bandwidth\n", - rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? - "20MHz" : "40MHz"); - - if (is_hal_stop(rtlhal)) { - rtlphy->set_bwmode_inprogress = false; - return; - } - - reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); - reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); - - switch (rtlphy->current_chan_bw) { - case HT_CHANNEL_WIDTH_20: - reg_bw_opmode |= BW_OPMODE_20MHZ; - rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); - break; - case HT_CHANNEL_WIDTH_20_40: - reg_bw_opmode &= ~BW_OPMODE_20MHZ; - rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); - reg_prsr_rsc = - (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5); - rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); - break; - } - - switch (rtlphy->current_chan_bw) { - case HT_CHANNEL_WIDTH_20: - rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); - rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); - rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); - break; - case HT_CHANNEL_WIDTH_20_40: - rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); - rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); - - rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND, - (mac->cur_40_prime_sc >> 1)); - rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc); - rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0); - - rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)), - (mac->cur_40_prime_sc == - HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); - break; - } - rtl8723ae_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); - rtlphy->set_bwmode_inprogress = false; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); -} - -void rtl8723ae_phy_set_bw_mode(struct ieee80211_hw *hw, - enum nl80211_channel_type ch_type) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - u8 tmp_bw = rtlphy->current_chan_bw; - - if (rtlphy->set_bwmode_inprogress) - return; - rtlphy->set_bwmode_inprogress = true; - if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { - rtl8723ae_phy_set_bw_mode_callback(hw); - } else { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "FALSE driver sleep or unload\n"); - rtlphy->set_bwmode_inprogress = false; - rtlphy->current_chan_bw = tmp_bw; - } -} - -void rtl8723ae_phy_sw_chnl_callback(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - u32 delay; - - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, - "switch to channel%d\n", rtlphy->current_channel); - if (is_hal_stop(rtlhal)) - return; - do { - if (!rtlphy->sw_chnl_inprogress) - break; - if (!_phy_sw_chnl_step_by_step - (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage, - &rtlphy->sw_chnl_step, &delay)) { - if (delay > 0) - mdelay(delay); - else - continue; - } else { - rtlphy->sw_chnl_inprogress = false; - } - break; - } while (true); - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); -} - -u8 rtl8723ae_phy_sw_chnl(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - if (rtlphy->sw_chnl_inprogress) - return 0; - if (rtlphy->set_bwmode_inprogress) - return 0; - RT_ASSERT((rtlphy->current_channel <= 14), - "WIRELESS_MODE_G but channel>14"); - rtlphy->sw_chnl_inprogress = true; - rtlphy->sw_chnl_stage = 0; - rtlphy->sw_chnl_step = 0; - if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { - rtl8723ae_phy_sw_chnl_callback(hw); - RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, - "sw_chnl_inprogress false schdule workitem\n"); - rtlphy->sw_chnl_inprogress = false; - } else { - RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, - "sw_chnl_inprogress false driver sleep or unload\n"); - rtlphy->sw_chnl_inprogress = false; - } - return 1; -} - -static void _rtl8723ae_phy_sw_rf_seting(struct ieee80211_hw *hw, u8 channel) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) { - if (channel == 6 && rtlphy->current_chan_bw == - HT_CHANNEL_WIDTH_20) - rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, - 0x00255); - else{ - u32 backupRF0x1A = (u32)rtl_get_rfreg(hw, RF90_PATH_A, - RF_RX_G1, RFREG_OFFSET_MASK); - rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, - backupRF0x1A); - } - } -} - -static bool _phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, u8 channel, - u8 *stage, u8 *step, u32 *delay) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; - u32 precommoncmdcnt; - struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; - u32 postcommoncmdcnt; - struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT]; - u32 rfdependcmdcnt; - struct swchnlcmd *currentcmd = NULL; - u8 rfpath; - u8 num_total_rfpath = rtlphy->num_total_rfpath; - - precommoncmdcnt = 0; - _phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, - MAX_PRECMD_CNT, CMDID_SET_TXPOWEROWER_LEVEL, - 0, 0, 0); - _phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, - MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); - postcommoncmdcnt = 0; - - _phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, - MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0); - rfdependcmdcnt = 0; - - RT_ASSERT((channel >= 1 && channel <= 14), - "illegal channel for Zebra: %d\n", channel); - - _phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, - MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, - RF_CHNLBW, channel, 10); - - _phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, - MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, 0); - - do { - switch (*stage) { - case 0: - currentcmd = &precommoncmd[*step]; - break; - case 1: - currentcmd = &rfdependcmd[*step]; - break; - case 2: - currentcmd = &postcommoncmd[*step]; - break; - } - - if (currentcmd->cmdid == CMDID_END) { - if ((*stage) == 2) { - return true; - } else { - (*stage)++; - (*step) = 0; - continue; - } - } - - switch (currentcmd->cmdid) { - case CMDID_SET_TXPOWEROWER_LEVEL: - rtl8723ae_phy_set_txpower_level(hw, channel); - break; - case CMDID_WRITEPORT_ULONG: - rtl_write_dword(rtlpriv, currentcmd->para1, - currentcmd->para2); - break; - case CMDID_WRITEPORT_USHORT: - rtl_write_word(rtlpriv, currentcmd->para1, - (u16) currentcmd->para2); - break; - case CMDID_WRITEPORT_UCHAR: - rtl_write_byte(rtlpriv, currentcmd->para1, - (u8) currentcmd->para2); - break; - case CMDID_RF_WRITEREG: - for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { - rtlphy->rfreg_chnlval[rfpath] = - ((rtlphy->rfreg_chnlval[rfpath] & - 0xfffffc00) | currentcmd->para2); - - rtl_set_rfreg(hw, (enum radio_path)rfpath, - currentcmd->para1, - RFREG_OFFSET_MASK, - rtlphy->rfreg_chnlval[rfpath]); - } - _rtl8723ae_phy_sw_rf_seting(hw, channel); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not process\n"); - break; - } - - break; - } while (true); - - (*delay) = currentcmd->msdelay; - (*step)++; - return false; -} - -static bool _phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, - u32 cmdtableidx, u32 cmdtablesz, - enum swchnlcmd_id cmdid, u32 para1, - u32 para2, u32 msdelay) -{ - struct swchnlcmd *pcmd; - - if (cmdtable == NULL) { - RT_ASSERT(false, "cmdtable cannot be NULL.\n"); - return false; - } - - if (cmdtableidx >= cmdtablesz) - return false; - - pcmd = cmdtable + cmdtableidx; - pcmd->cmdid = cmdid; - pcmd->para1 = para1; - pcmd->para2 = para2; - pcmd->msdelay = msdelay; - return true; -} - -static u8 _rtl8723ae_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb) -{ - u32 reg_eac, reg_e94, reg_e9c, reg_ea4; - u8 result = 0x00; - - rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f); - rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f); - rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102); - rtl_set_bbreg(hw, 0xe3c, MASKDWORD, - config_pathb ? 0x28160202 : 0x28160502); - - if (config_pathb) { - rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22); - rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22); - rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102); - rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202); - } - - rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1); - rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000); - rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000); - - mdelay(IQK_DELAY_TIME); - - reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); - reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD); - reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD); - reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD); - - if (!(reg_eac & BIT(28)) && - (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && - (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) - result |= 0x01; - else - return result; - - if (!(reg_eac & BIT(27)) && - (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) && - (((reg_eac & 0x03FF0000) >> 16) != 0x36)) - result |= 0x02; - return result; -} - -static u8 _rtl8723ae_phy_path_b_iqk(struct ieee80211_hw *hw) -{ - u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc; - u8 result = 0x00; - - rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002); - rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000); - mdelay(IQK_DELAY_TIME); - reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); - reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD); - reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD); - reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD); - reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD); - - if (!(reg_eac & BIT(31)) && - (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) && - (((reg_ebc & 0x03FF0000) >> 16) != 0x42)) - result |= 0x01; - else - return result; - if (!(reg_eac & BIT(30)) && - (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) && - (((reg_ecc & 0x03FF0000) >> 16) != 0x36)) - result |= 0x02; - return result; -} - -static void phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw, bool iqk_ok, - long result[][8], u8 final_candidate, - bool btxonly) -{ - u32 oldval_0, x, tx0_a, reg; - long y, tx0_c; - - if (final_candidate == 0xFF) { - return; - } else if (iqk_ok) { - oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, - MASKDWORD) >> 22) & 0x3FF; - x = result[final_candidate][0]; - if ((x & 0x00000200) != 0) - x = x | 0xFFFFFC00; - tx0_a = (x * oldval_0) >> 8; - rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a); - rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31), - ((x * oldval_0 >> 7) & 0x1)); - y = result[final_candidate][1]; - if ((y & 0x00000200) != 0) - y = y | 0xFFFFFC00; - tx0_c = (y * oldval_0) >> 8; - rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000, - ((tx0_c & 0x3C0) >> 6)); - rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000, - (tx0_c & 0x3F)); - rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29), - ((y * oldval_0 >> 7) & 0x1)); - if (btxonly) - return; - reg = result[final_candidate][2]; - rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg); - reg = result[final_candidate][3] & 0x3F; - rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg); - reg = (result[final_candidate][3] >> 6) & 0xF; - rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); - } -} - -static void phy_save_adda_regs(struct ieee80211_hw *hw, - u32 *addareg, u32 *addabackup, - u32 registernum) -{ - u32 i; - - for (i = 0; i < registernum; i++) - addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD); -} - -static void phy_save_mac_regs(struct ieee80211_hw *hw, u32 *macreg, - u32 *macbackup) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 i; - - for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) - macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]); - macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]); -} - -static void phy_reload_adda_regs(struct ieee80211_hw *hw, u32 *addareg, - u32 *addabackup, u32 regiesternum) -{ - u32 i; - - for (i = 0; i < regiesternum; i++) - rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]); -} - -static void phy_reload_mac_regs(struct ieee80211_hw *hw, u32 *macreg, - u32 *macbackup) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 i; - - for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) - rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]); - rtl_write_dword(rtlpriv, macreg[i], macbackup[i]); -} - -static void _rtl8723ae_phy_path_adda_on(struct ieee80211_hw *hw, - u32 *addareg, bool is_patha_on, - bool is2t) -{ - u32 pathOn; - u32 i; - - pathOn = is_patha_on ? 0x04db25a4 : 0x0b1b25a4; - if (false == is2t) { - pathOn = 0x0bdb25a0; - rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0); - } else { - rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathOn); - } - - for (i = 1; i < IQK_ADDA_REG_NUM; i++) - rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathOn); -} - -static void _rtl8723ae_phy_mac_setting_calibration(struct ieee80211_hw *hw, - u32 *macreg, u32 *macbackup) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 i = 0; - - rtl_write_byte(rtlpriv, macreg[i], 0x3F); - - for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) - rtl_write_byte(rtlpriv, macreg[i], - (u8) (macbackup[i] & (~BIT(3)))); - rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5)))); -} - -static void _rtl8723ae_phy_path_a_standby(struct ieee80211_hw *hw) -{ - rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0); - rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); - rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); -} - -static void _rtl8723ae_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode) -{ - u32 mode; - - mode = pi_mode ? 0x01000100 : 0x01000000; - rtl_set_bbreg(hw, 0x820, MASKDWORD, mode); - rtl_set_bbreg(hw, 0x828, MASKDWORD, mode); -} - -static bool phy_simularity_comp(struct ieee80211_hw *hw, long result[][8], - u8 c1, u8 c2) -{ - u32 i, j, diff, simularity_bitmap, bound; - - u8 final_candidate[2] = { 0xFF, 0xFF }; - bool bresult = true; - - bound = 4; - - simularity_bitmap = 0; - - for (i = 0; i < bound; i++) { - diff = (result[c1][i] > result[c2][i]) ? - (result[c1][i] - result[c2][i]) : - (result[c2][i] - result[c1][i]); - - if (diff > MAX_TOLERANCE) { - if ((i == 2 || i == 6) && !simularity_bitmap) { - if (result[c1][i] + result[c1][i + 1] == 0) - final_candidate[(i / 4)] = c2; - else if (result[c2][i] + result[c2][i + 1] == 0) - final_candidate[(i / 4)] = c1; - else - simularity_bitmap = simularity_bitmap | - (1 << i); - } else - simularity_bitmap = - simularity_bitmap | (1 << i); - } - } - - if (simularity_bitmap == 0) { - for (i = 0; i < (bound / 4); i++) { - if (final_candidate[i] != 0xFF) { - for (j = i * 4; j < (i + 1) * 4 - 2; j++) - result[3][j] = - result[final_candidate[i]][j]; - bresult = false; - } - } - return bresult; - } else if (!(simularity_bitmap & 0x0F)) { - for (i = 0; i < 4; i++) - result[3][i] = result[c1][i]; - return false; - } else { - return false; - } - -} - -static void _rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, - long result[][8], u8 t, bool is2t) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - u32 i; - u8 patha_ok, pathb_ok; - u32 adda_reg[IQK_ADDA_REG_NUM] = { - 0x85c, 0xe6c, 0xe70, 0xe74, - 0xe78, 0xe7c, 0xe80, 0xe84, - 0xe88, 0xe8c, 0xed0, 0xed4, - 0xed8, 0xedc, 0xee0, 0xeec - }; - u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { - 0x522, 0x550, 0x551, 0x040 - }; - const u32 retrycount = 2; - u32 bbvalue; - - if (t == 0) { - bbvalue = rtl_get_bbreg(hw, 0x800, MASKDWORD); - - phy_save_adda_regs(hw, adda_reg, rtlphy->adda_backup, 16); - phy_save_mac_regs(hw, iqk_mac_reg, rtlphy->iqk_mac_backup); - } - _rtl8723ae_phy_path_adda_on(hw, adda_reg, true, is2t); - if (t == 0) { - rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw, - RFPGA0_XA_HSSIPARAMETER1, - BIT(8)); - } - - if (!rtlphy->rfpi_enable) - _rtl8723ae_phy_pi_mode_switch(hw, true); - if (t == 0) { - rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD); - rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD); - rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD); - } - rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600); - rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4); - rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000); - if (is2t) { - rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); - rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000); - } - _rtl8723ae_phy_mac_setting_calibration(hw, iqk_mac_reg, - rtlphy->iqk_mac_backup); - rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000); - if (is2t) - rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000); - rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); - rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00); - rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800); - for (i = 0; i < retrycount; i++) { - patha_ok = _rtl8723ae_phy_path_a_iqk(hw, is2t); - if (patha_ok == 0x03) { - result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) & - 0x3FF0000) >> 16; - result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & - 0x3FF0000) >> 16; - result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) & - 0x3FF0000) >> 16; - result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) & - 0x3FF0000) >> 16; - break; - } else if (i == (retrycount - 1) && patha_ok == 0x01) - - result[t][0] = (rtl_get_bbreg(hw, 0xe94, - MASKDWORD) & 0x3FF0000) >> 16; - result[t][1] = - (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16; - - } - - if (is2t) { - _rtl8723ae_phy_path_a_standby(hw); - _rtl8723ae_phy_path_adda_on(hw, adda_reg, false, is2t); - for (i = 0; i < retrycount; i++) { - pathb_ok = _rtl8723ae_phy_path_b_iqk(hw); - if (pathb_ok == 0x03) { - result[t][4] = - (rtl_get_bbreg(hw, 0xeb4, MASKDWORD) & - 0x3FF0000) >> 16; - result[t][5] = - (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & - 0x3FF0000) >> 16; - result[t][6] = - (rtl_get_bbreg(hw, 0xec4, MASKDWORD) & - 0x3FF0000) >> 16; - result[t][7] = - (rtl_get_bbreg(hw, 0xecc, MASKDWORD) & - 0x3FF0000) >> 16; - break; - } else if (i == (retrycount - 1) && pathb_ok == 0x01) { - result[t][4] = - (rtl_get_bbreg(hw, 0xeb4, MASKDWORD) & - 0x3FF0000) >> 16; - } - result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & - 0x3FF0000) >> 16; - } - } - rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04); - rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874); - rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08); - rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0); - rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3); - if (is2t) - rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3); - if (t != 0) { - if (!rtlphy->rfpi_enable) - _rtl8723ae_phy_pi_mode_switch(hw, false); - phy_reload_adda_regs(hw, adda_reg, rtlphy->adda_backup, 16); - phy_reload_mac_regs(hw, iqk_mac_reg, rtlphy->iqk_mac_backup); - } -} - -static void _rtl8723ae_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 tmpreg; - u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal; - - tmpreg = rtl_read_byte(rtlpriv, 0xd03); - - if ((tmpreg & 0x70) != 0) - rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F); - else - rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); - - if ((tmpreg & 0x70) != 0) { - rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS); - - if (is2t) - rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00, - MASK12BITS); - - rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, - (rf_a_mode & 0x8FFFF) | 0x10000); - - if (is2t) - rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, - (rf_b_mode & 0x8FFFF) | 0x10000); - } - lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS); - - rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000); - - mdelay(100); - - if ((tmpreg & 0x70) != 0) { - rtl_write_byte(rtlpriv, 0xd03, tmpreg); - rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode); - - if (is2t) - rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, - rf_b_mode); - } else { - rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); - } -} - -static void _rtl8723ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, - bool bmain, bool is2t) -{ - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - - if (is_hal_stop(rtlhal)) { - rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01); - rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01); - } - if (is2t) { - if (bmain) - rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, - BIT(5) | BIT(6), 0x1); - else - rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, - BIT(5) | BIT(6), 0x2); - } else { - if (bmain) - rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2); - else - rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1); - - } -} - -#undef IQK_ADDA_REG_NUM -#undef IQK_DELAY_TIME - -void rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - long result[4][8]; - u8 i, final_candidate; - bool patha_ok, pathb_ok; - long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4, - reg_ecc, reg_tmp = 0; - bool is12simular, is13simular, is23simular; - bool start_conttx = false, singletone = false; - u32 iqk_bb_reg[10] = { - ROFDM0_XARXIQIMBALANCE, - ROFDM0_XBRXIQIMBALANCE, - ROFDM0_ECCATHRESHOLD, - ROFDM0_AGCRSSITABLE, - ROFDM0_XATXIQIMBALANCE, - ROFDM0_XBTXIQIMBALANCE, - ROFDM0_XCTXIQIMBALANCE, - ROFDM0_XCTXAFE, - ROFDM0_XDTXAFE, - ROFDM0_RXIQEXTANTA - }; - - if (recovery) { - phy_reload_adda_regs(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 10); - return; - } - if (start_conttx || singletone) - return; - for (i = 0; i < 8; i++) { - result[0][i] = 0; - result[1][i] = 0; - result[2][i] = 0; - result[3][i] = 0; - } - final_candidate = 0xff; - patha_ok = false; - pathb_ok = false; - is12simular = false; - is23simular = false; - is13simular = false; - for (i = 0; i < 3; i++) { - _rtl8723ae_phy_iq_calibrate(hw, result, i, false); - if (i == 1) { - is12simular = phy_simularity_comp(hw, result, 0, 1); - if (is12simular) { - final_candidate = 0; - break; - } - } - if (i == 2) { - is13simular = phy_simularity_comp(hw, result, 0, 2); - if (is13simular) { - final_candidate = 0; - break; - } - is23simular = phy_simularity_comp(hw, result, 1, 2); - if (is23simular) { - final_candidate = 1; - } else { - for (i = 0; i < 8; i++) - reg_tmp += result[3][i]; - - if (reg_tmp != 0) - final_candidate = 3; - else - final_candidate = 0xFF; - } - } - } - for (i = 0; i < 4; i++) { - reg_e94 = result[i][0]; - reg_e9c = result[i][1]; - reg_ea4 = result[i][2]; - reg_eac = result[i][3]; - reg_eb4 = result[i][4]; - reg_ebc = result[i][5]; - reg_ec4 = result[i][6]; - reg_ecc = result[i][7]; - } - if (final_candidate != 0xff) { - rtlphy->reg_e94 = reg_e94 = result[final_candidate][0]; - rtlphy->reg_e9c = reg_e9c = result[final_candidate][1]; - reg_ea4 = result[final_candidate][2]; - reg_eac = result[final_candidate][3]; - rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4]; - rtlphy->reg_ebc = reg_ebc = result[final_candidate][5]; - reg_ec4 = result[final_candidate][6]; - reg_ecc = result[final_candidate][7]; - patha_ok = pathb_ok = true; - } else { - rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; - rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0; - } - if (reg_e94 != 0) /*&&(reg_ea4 != 0) */ - phy_path_a_fill_iqk_matrix(hw, patha_ok, result, - final_candidate, (reg_ea4 == 0)); - phy_save_adda_regs(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 10); -} - -void rtl8723ae_phy_lc_calibrate(struct ieee80211_hw *hw) -{ - bool start_conttx = false, singletone = false; - - if (start_conttx || singletone) - return; - _rtl8723ae_phy_lc_calibrate(hw, false); -} - -void rtl8723ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain) -{ - _rtl8723ae_phy_set_rfpath_switch(hw, bmain, false); -} - -bool rtl8723ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - bool postprocessing = false; - - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - "-->IO Cmd(%#x), set_io_inprogress(%d)\n", - iotype, rtlphy->set_io_inprogress); - do { - switch (iotype) { - case IO_CMD_RESUME_DM_BY_SCAN: - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - "[IO CMD] Resume DM after scan.\n"); - postprocessing = true; - break; - case IO_CMD_PAUSE_DM_BY_SCAN: - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - "[IO CMD] Pause DM before scan.\n"); - postprocessing = true; - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not process\n"); - break; - } - } while (false); - if (postprocessing && !rtlphy->set_io_inprogress) { - rtlphy->set_io_inprogress = true; - rtlphy->current_io_type = iotype; - } else { - return false; - } - rtl8723ae_phy_set_io(hw); - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<--IO Type(%#x)\n", iotype); - return true; -} - -static void rtl8723ae_phy_set_io(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct dig_t *dm_digtable = &rtlpriv->dm_digtable; - - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - "--->Cmd(%#x), set_io_inprogress(%d)\n", - rtlphy->current_io_type, rtlphy->set_io_inprogress); - switch (rtlphy->current_io_type) { - case IO_CMD_RESUME_DM_BY_SCAN: - dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1; - rtl8723ae_dm_write_dig(hw); - rtl8723ae_phy_set_txpower_level(hw, rtlphy->current_channel); - break; - case IO_CMD_PAUSE_DM_BY_SCAN: - rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue; - dm_digtable->cur_igvalue = 0x17; - rtl8723ae_dm_write_dig(hw); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not process\n"); - break; - } - rtlphy->set_io_inprogress = false; - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - "<---(%#x)\n", rtlphy->current_io_type); -} - -static void rtl8723ae_phy_set_rf_on(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); - rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); - rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); -} - -static void _rtl8723ae_phy_set_rf_sleep(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 u4b_tmp; - u8 delay = 5; - - rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); - rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); - rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); - u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); - while (u4b_tmp != 0 && delay > 0) { - rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0); - rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); - rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); - u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); - delay--; - } - if (delay == 0) { - rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); - rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); - RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - "Switch RF timeout !!!.\n"); - return; - } - rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); - rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); -} - -static bool _rtl8723ae_phy_set_rf_power_state(struct ieee80211_hw *hw, - enum rf_pwrstate rfpwr_state) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - struct rtl8192_tx_ring *ring = NULL; - bool bresult = true; - u8 i, queue_id; - - switch (rfpwr_state) { - case ERFON: - if ((ppsc->rfpwr_state == ERFOFF) && - RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { - bool rtstatus; - u32 InitializeCount = 0; - do { - InitializeCount++; - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - "IPS Set eRf nic enable\n"); - rtstatus = rtl_ps_enable_nic(hw); - } while ((rtstatus != true) && (InitializeCount < 10)); - RT_CLEAR_PS_LEVEL(ppsc, - RT_RF_OFF_LEVL_HALT_NIC); - } else { - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - "Set ERFON sleeped:%d ms\n", - jiffies_to_msecs(jiffies - - ppsc->last_sleep_jiffies)); - ppsc->last_awake_jiffies = jiffies; - rtl8723ae_phy_set_rf_on(hw); - } - if (mac->link_state == MAC80211_LINKED) { - rtlpriv->cfg->ops->led_control(hw, - LED_CTL_LINK); - } else { - rtlpriv->cfg->ops->led_control(hw, - LED_CTL_NO_LINK); - } - break; - case ERFOFF: - if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - "IPS Set eRf nic disable\n"); - rtl_ps_disable_nic(hw); - RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); - } else { - if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) { - rtlpriv->cfg->ops->led_control(hw, - LED_CTL_NO_LINK); - } else { - rtlpriv->cfg->ops->led_control(hw, - LED_CTL_POWER_OFF); - } - } - break; - case ERFSLEEP: - if (ppsc->rfpwr_state == ERFOFF) - break; - for (queue_id = 0, i = 0; - queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { - ring = &pcipriv->dev.tx_ring[queue_id]; - if (skb_queue_len(&ring->queue) == 0) { - queue_id++; - continue; - } else { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", - (i + 1), queue_id, - skb_queue_len(&ring->queue)); - - udelay(10); - i++; - } - if (i >= MAX_DOZE_WAITING_TIMES_9x) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", - MAX_DOZE_WAITING_TIMES_9x, - queue_id, - skb_queue_len(&ring->queue)); - break; - } - } - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - "Set ERFSLEEP awaked:%d ms\n", - jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies)); - ppsc->last_sleep_jiffies = jiffies; - _rtl8723ae_phy_set_rf_sleep(hw); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not processed\n"); - bresult = false; - break; - } - if (bresult) - ppsc->rfpwr_state = rfpwr_state; - return bresult; -} - -bool rtl8723ae_phy_set_rf_power_state(struct ieee80211_hw *hw, - enum rf_pwrstate rfpwr_state) -{ - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - bool bresult = false; - - if (rfpwr_state == ppsc->rfpwr_state) - return bresult; - bresult = _rtl8723ae_phy_set_rf_power_state(hw, rfpwr_state); - return bresult; -} diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h deleted file mode 100644 index e7a59eba351a..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/phy.h +++ /dev/null @@ -1,224 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL92C_PHY_H__ -#define __RTL92C_PHY_H__ - -#define MAX_PRECMD_CNT 16 -#define MAX_RFDEPENDCMD_CNT 16 -#define MAX_POSTCMD_CNT 16 - -#define MAX_DOZE_WAITING_TIMES_9x 64 - -#define RT_CANNOT_IO(hw) false -#define HIGHPOWER_RADIOA_ARRAYLEN 22 - -#define MAX_TOLERANCE 5 -#define IQK_DELAY_TIME 1 - -#define APK_BB_REG_NUM 5 -#define APK_AFE_REG_NUM 16 -#define APK_CURVE_REG_NUM 4 -#define PATH_NUM 2 - -#define LOOP_LIMIT 5 -#define MAX_STALL_TIME 50 -#define AntennaDiversityValue 0x80 -#define MAX_TXPWR_IDX_NMODE_92S 63 -#define Reset_Cnt_Limit 3 - -#define IQK_MAC_REG_NUM 4 - -#define RF6052_MAX_PATH 2 - -#define CT_OFFSET_MAC_ADDR 0X16 - -#define CT_OFFSET_CCK_TX_PWR_IDX 0x5A -#define CT_OFFSET_HT401S_TX_PWR_IDX 0x60 -#define CT_OFFSET_HT402S_TX_PWR_IDX_DIFF 0x66 -#define CT_OFFSET_HT20_TX_PWR_IDX_DIFF 0x69 -#define CT_OFFSET_OFDM_TX_PWR_IDX_DIFF 0x6C - -#define CT_OFFSET_HT40_MAX_PWR_OFFSET 0x6F -#define CT_OFFSET_HT20_MAX_PWR_OFFSET 0x72 - -#define CT_OFFSET_CHANNEL_PLAH 0x75 -#define CT_OFFSET_THERMAL_METER 0x78 -#define CT_OFFSET_RF_OPTION 0x79 -#define CT_OFFSET_VERSION 0x7E -#define CT_OFFSET_CUSTOMER_ID 0x7F - -#define RTL92C_MAX_PATH_NUM 2 - -enum swchnlcmd_id { - CMDID_END, - CMDID_SET_TXPOWEROWER_LEVEL, - CMDID_BBREGWRITE10, - CMDID_WRITEPORT_ULONG, - CMDID_WRITEPORT_USHORT, - CMDID_WRITEPORT_UCHAR, - CMDID_RF_WRITEREG, -}; - -struct swchnlcmd { - enum swchnlcmd_id cmdid; - u32 para1; - u32 para2; - u32 msdelay; -}; - -enum hw90_block_e { - HW90_BLOCK_MAC = 0, - HW90_BLOCK_PHY0 = 1, - HW90_BLOCK_PHY1 = 2, - HW90_BLOCK_RF = 3, - HW90_BLOCK_MAXIMUM = 4, -}; - -enum baseband_config_type { - BASEBAND_CONFIG_PHY_REG = 0, - BASEBAND_CONFIG_AGC_TAB = 1, -}; - -enum ra_offset_area { - RA_OFFSET_LEGACY_OFDM1, - RA_OFFSET_LEGACY_OFDM2, - RA_OFFSET_HT_OFDM1, - RA_OFFSET_HT_OFDM2, - RA_OFFSET_HT_OFDM3, - RA_OFFSET_HT_OFDM4, - RA_OFFSET_HT_CCK, -}; - -enum antenna_path { - ANTENNA_NONE, - ANTENNA_D, - ANTENNA_C, - ANTENNA_CD, - ANTENNA_B, - ANTENNA_BD, - ANTENNA_BC, - ANTENNA_BCD, - ANTENNA_A, - ANTENNA_AD, - ANTENNA_AC, - ANTENNA_ACD, - ANTENNA_AB, - ANTENNA_ABD, - ANTENNA_ABC, - ANTENNA_ABCD -}; - -struct r_antenna_select_ofdm { - u32 r_tx_antenna:4; - u32 r_ant_l:4; - u32 r_ant_non_ht:4; - u32 r_ant_ht1:4; - u32 r_ant_ht2:4; - u32 r_ant_ht_s1:4; - u32 r_ant_non_ht_s1:4; - u32 ofdm_txsc:2; - u32 reserved:2; -}; - -struct r_antenna_select_cck { - u8 r_cckrx_enable_2:2; - u8 r_cckrx_enable:2; - u8 r_ccktx_enable:4; -}; - -struct efuse_contents { - u8 mac_addr[ETH_ALEN]; - u8 cck_tx_power_idx[6]; - u8 ht40_1s_tx_power_idx[6]; - u8 ht40_2s_tx_power_idx_diff[3]; - u8 ht20_tx_power_idx_diff[3]; - u8 ofdm_tx_power_idx_diff[3]; - u8 ht40_max_power_offset[3]; - u8 ht20_max_power_offset[3]; - u8 channel_plan; - u8 thermal_meter; - u8 rf_option[5]; - u8 version; - u8 oem_id; - u8 regulatory; -}; - -struct tx_power_struct { - u8 cck[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; - u8 ht40_1s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; - u8 ht40_2s[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; - u8 ht20_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; - u8 legacy_ht_diff[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; - u8 legacy_ht_txpowerdiff; - u8 groupht20[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; - u8 groupht40[RTL92C_MAX_PATH_NUM][CHANNEL_MAX_NUMBER]; - u8 pwrgroup_cnt; - u32 mcs_original_offset[4][16]; -}; - -extern u32 rtl8723ae_phy_query_bb_reg(struct ieee80211_hw *hw, - u32 regaddr, u32 bitmask); -extern void rtl8723ae_phy_set_bb_reg(struct ieee80211_hw *hw, - u32 regaddr, u32 bitmask, u32 data); -extern u32 rtl8723ae_phy_query_rf_reg(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 regaddr, - u32 bitmask); -extern void rtl8723ae_phy_set_rf_reg(struct ieee80211_hw *hw, - enum radio_path rfpath, u32 regaddr, - u32 bitmask, u32 data); -extern bool rtl8723ae_phy_mac_config(struct ieee80211_hw *hw); -extern bool rtl8723ae_phy_bb_config(struct ieee80211_hw *hw); -extern bool rtl8723ae_phy_rf_config(struct ieee80211_hw *hw); -extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw, - enum radio_path rfpath); -extern void rtl8723ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw); -extern void rtl8723ae_phy_get_txpower_level(struct ieee80211_hw *hw, - long *powerlevel); -extern void rtl8723ae_phy_set_txpower_level(struct ieee80211_hw *hw, - u8 channel); -extern bool rtl8723ae_phy_update_txpower_dbm(struct ieee80211_hw *hw, - long power_indbm); -extern void rtl8723ae_phy_scan_operation_backup(struct ieee80211_hw *hw, - u8 operation); -extern void rtl8723ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw); -extern void rtl8723ae_phy_set_bw_mode(struct ieee80211_hw *hw, - enum nl80211_channel_type ch_type); -extern void rtl8723ae_phy_sw_chnl_callback(struct ieee80211_hw *hw); -extern u8 rtl8723ae_phy_sw_chnl(struct ieee80211_hw *hw); -extern void rtl8723ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery); -void rtl8723ae_phy_lc_calibrate(struct ieee80211_hw *hw); -void rtl8723ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain); -bool rtl8723ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, - enum radio_path rfpath); -bool rtl8723ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype); -extern bool rtl8723ae_phy_set_rf_power_state(struct ieee80211_hw *hw, - enum rf_pwrstate rfpwr_state); - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.c b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.c deleted file mode 100644 index df6ca9a57f7f..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.c +++ /dev/null @@ -1,109 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#include "pwrseqcmd.h" -#include "pwrseq.h" - -/* drivers should parse arrays below and do the corresponding actions */ - -/*3 Power on Array*/ -struct wlan_pwr_cfg rtl8723A_power_on_flow[RTL8723A_TRANS_CARDEMU_TO_ACT_STPS - + RTL8723A_TRANS_END_STPS] = { - RTL8723A_TRANS_CARDEMU_TO_ACT, - RTL8723A_TRANS_END -}; - -/*3Radio off GPIO Array */ -struct wlan_pwr_cfg rtl8723A_radio_off_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS - + RTL8723A_TRANS_END_STPS] = { - RTL8723A_TRANS_ACT_TO_CARDEMU, - RTL8723A_TRANS_END -}; - -/*3Card Disable Array*/ -struct wlan_pwr_cfg -rtl8723A_card_disable_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS - + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS - + RTL8723A_TRANS_END_STPS] = { - RTL8723A_TRANS_ACT_TO_CARDEMU, - RTL8723A_TRANS_CARDEMU_TO_CARDDIS, - RTL8723A_TRANS_END -}; - -/*3 Card Enable Array*/ -struct wlan_pwr_cfg rtl8723A_card_enable_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS - + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS - + RTL8723A_TRANS_END_STPS] = { - RTL8723A_TRANS_CARDDIS_TO_CARDEMU, - RTL8723A_TRANS_CARDEMU_TO_ACT, - RTL8723A_TRANS_END -}; - -/*3Suspend Array*/ -struct wlan_pwr_cfg rtl8723A_suspend_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS - + RTL8723A_TRANS_CARDEMU_TO_SUS_STPS - + RTL8723A_TRANS_END_STPS] = { - RTL8723A_TRANS_ACT_TO_CARDEMU, - RTL8723A_TRANS_CARDEMU_TO_SUS, - RTL8723A_TRANS_END -}; - -/*3 Resume Array*/ -struct wlan_pwr_cfg rtl8723A_resume_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS - + RTL8723A_TRANS_CARDEMU_TO_SUS_STPS - + RTL8723A_TRANS_END_STPS] = { - RTL8723A_TRANS_SUS_TO_CARDEMU, - RTL8723A_TRANS_CARDEMU_TO_ACT, - RTL8723A_TRANS_END -}; - -/*3HWPDN Array*/ -struct wlan_pwr_cfg rtl8723A_hwpdn_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS - + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS - + RTL8723A_TRANS_END_STPS] = { - RTL8723A_TRANS_ACT_TO_CARDEMU, - RTL8723A_TRANS_CARDEMU_TO_PDN, - RTL8723A_TRANS_END -}; - -/*3 Enter LPS */ -struct wlan_pwr_cfg rtl8723A_enter_lps_flow[RTL8723A_TRANS_ACT_TO_LPS_STPS - + RTL8723A_TRANS_END_STPS] = { - /*FW behavior*/ - RTL8723A_TRANS_ACT_TO_LPS, - RTL8723A_TRANS_END -}; - -/*3 Leave LPS */ -struct wlan_pwr_cfg rtl8723A_leave_lps_flow[RTL8723A_TRANS_LPS_TO_ACT_STPS - + RTL8723A_TRANS_END_STPS] = { - /*FW behavior*/ - RTL8723A_TRANS_LPS_TO_ACT, - RTL8723A_TRANS_END -}; diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h deleted file mode 100644 index 7a46f9fdf558..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseq.h +++ /dev/null @@ -1,322 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL8723E_PWRSEQ_H__ -#define __RTL8723E_PWRSEQ_H__ - -#include "pwrseqcmd.h" -/* - Check document WM-20110607-Paul-RTL8723A_Power_Architecture-R02.vsd - There are 6 HW Power States: - 0: POFF--Power Off - 1: PDN--Power Down - 2: CARDEMU--Card Emulation - 3: ACT--Active Mode - 4: LPS--Low Power State - 5: SUS--Suspend - - The transision from different states are defined below - TRANS_CARDEMU_TO_ACT - TRANS_ACT_TO_CARDEMU - TRANS_CARDEMU_TO_SUS - TRANS_SUS_TO_CARDEMU - TRANS_CARDEMU_TO_PDN - TRANS_ACT_TO_LPS - TRANS_LPS_TO_ACT - - TRANS_END -*/ - -#define RTL8723A_TRANS_CARDEMU_TO_ACT_STPS 10 -#define RTL8723A_TRANS_ACT_TO_CARDEMU_STPS 10 -#define RTL8723A_TRANS_CARDEMU_TO_SUS_STPS 10 -#define RTL8723A_TRANS_SUS_TO_CARDEMU_STPS 10 -#define RTL8723A_TRANS_CARDEMU_TO_PDN_STPS 10 -#define RTL8723A_TRANS_PDN_TO_CARDEMU_STPS 10 -#define RTL8723A_TRANS_ACT_TO_LPS_STPS 15 -#define RTL8723A_TRANS_LPS_TO_ACT_STPS 15 -#define RTL8723A_TRANS_END_STPS 1 - - -#define RTL8723A_TRANS_CARDEMU_TO_ACT \ - /* format */ \ - /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, \ - * comments here*/ \ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(2), 0}, \ - /* disable SW LPS 0x04[10]=0*/ \ - {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), BIT(1)}, \ - /* wait till 0x04[17] = 1 power ready*/ \ - {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, \ - /* release WLON reset 0x04[16]=1*/ \ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0}, \ - /* disable HWPDN 0x04[15]=0*/ \ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, (BIT(4)|BIT(3)), 0}, \ - /* disable WL suspend*/ \ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), BIT(0)}, \ - /* polling until return 0*/ \ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(0), 0} - -#define RTL8723A_TRANS_ACT_TO_CARDEMU \ - /* format */ \ - /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, \ - * comments here*/ \ - {0x001F, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0}, \ - /*0x1F[7:0] = 0 turn off RF*/ \ - {0x004E, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0}, \ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, \ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(1), 0} - -#define RTL8723A_TRANS_CARDEMU_TO_SUS \ - /* format */ \ - /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, \ - * comments here*/ \ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4)|BIT(3), \ - (BIT(4)|BIT(3))}, \ - /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK | \ - PWR_INTF_SDIO_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)},\ - /*0x04[12:11] = 2b'01 enable WL suspend*/ \ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \ - PWR_BASEADDR_MAC, \ - PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)|BIT(4)}, \ - /*0x04[12:11] = 2b'11 enable WL suspend for PCIe*/ \ - {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ - PWR_BASEADDR_SDIO, \ - PWR_CMD_WRITE, BIT(0), BIT(0)}, \ - /*Set SDIO suspend local register*/ \ - {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ - PWR_BASEADDR_SDIO, \ - PWR_CMD_POLLING, BIT(1), 0} \ - /*wait power state to suspend*/ - -#define RTL8723A_TRANS_SUS_TO_CARDEMU \ - /* format */ \ - /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ - {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ - PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0}, \ - /*Set SDIO suspend local register*/ \ - {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ - PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1)}, \ - /*wait power state to suspend*/ \ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0} \ - /*0x04[12:11] = 2b'01enable WL suspend*/ - -#define RTL8723A_TRANS_CARDEMU_TO_CARDDIS \ - /* format */ \ - /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, \ - PWR_INTF_USB_MSK|PWR_INTF_SDIO_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), BIT(3)},\ - /*0x04[12:11] = 2b'01 enable WL suspend*/ \ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(2), BIT(2)}, \ - /*0x04[10] = 1, enable SW LPS*/ \ - {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ - PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), BIT(0)}, \ - /*Set SDIO suspend local register*/ \ - {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ - PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), 0} \ - /*wait power state to suspend*/ - -#define RTL8723A_TRANS_CARDDIS_TO_CARDEMU \ - /* format */ \ - /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ - {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ - PWR_BASEADDR_SDIO, PWR_CMD_WRITE, BIT(0), 0}, \ - /*Set SDIO suspend local register*/ \ - {0x0086, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ - PWR_BASEADDR_SDIO, PWR_CMD_POLLING, BIT(1), BIT(1)}, \ - /*wait power state to suspend*/ \ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(3)|BIT(4), 0}, \ - /*0x04[12:11] = 2b'00enable WL suspend*/ \ - {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0} \ - /*PCIe DMA start*/ - -#define RTL8723A_TRANS_CARDEMU_TO_PDN \ - /* format */ \ - /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ - {0x0006, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, \ - /* 0x04[16] = 0*/\ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), BIT(7)} \ - /* 0x04[15] = 1*/ - -#define RTL8723A_TRANS_PDN_TO_CARDEMU \ - /* format */ \ - /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ - {0x0005, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(7), 0} \ - /* 0x04[15] = 0*/ - -#define RTL8723A_TRANS_ACT_TO_LPS \ - /* format */ \ - /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ - {0x0301, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF}, \ - /*PCIe DMA stop*/ \ - {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x7F}, \ - /*Tx Pause*/ \ - {0x05F8, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \ - /*Should be zero if no packet is transmitting*/ \ - {0x05F9, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \ - /*Should be zero if no packet is transmitting*/ \ - {0x05FA, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \ - /*Should be zero if no packet is transmitting*/ \ - {0x05FB, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_POLLING, 0xFF, 0}, \ - /*Should be zero if no packet is transmitting*/ \ - {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(0), 0}, \ - /*CCK and OFDM are disabled,and clock are gated*/ \ - {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_US}, \ - /*Delay 1us*/ \ - {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0}, \ - /*Whole BB is reset*/ \ - {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x3F}, \ - /*Reset MAC TRX*/ \ - {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), 0}, \ - /*check if removed later*/ \ - {0x0553, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(5), BIT(5)} \ - /*Respond TxOK to scheduler*/ - -#define RTL8723A_TRANS_LPS_TO_ACT \ - /* format */ \ - /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ - {0x0080, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_SDIO_MSK, \ - PWR_BASEADDR_SDIO, PWR_CMD_WRITE, 0xFF, 0x84}, \ - /*SDIO RPWM*/ \ - {0xFE58, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_USB_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84}, \ - /*USB RPWM*/ \ - {0x0361, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_PCI_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0x84}, \ - /*PCIe RPWM*/ \ - {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_DELAY, 0, PWRSEQ_DELAY_MS}, \ - /*Delay*/ \ - {0x0008, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(4), 0}, \ - /* 0x08[4] = 0 switch TSF to 40M*/ \ - {0x0109, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_POLLING, BIT(7), 0}, \ - /*Polling 0x109[7]=0 TSF in 40M*/ \ - {0x0029, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(6)|BIT(7), 0}, \ - /*. 0x29[7:6] = 2b'00 enable BB clock*/ \ - {0x0101, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1), BIT(1)}, \ - /*. 0x101[1] = 1*/ \ - {0x0100, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0xFF}, \ - /* 0x100[7:0] = 0xFF enable WMAC TRX*/ \ - {0x0002, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, BIT(1)|BIT(0), \ - BIT(1)|BIT(0)}, \ - /* 0x02[1:0] = 2b'11 enable BB macro*/ \ - {0x0522, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - PWR_BASEADDR_MAC, PWR_CMD_WRITE, 0xFF, 0} \ - /*. 0x522 = 0*/ - -#define RTL8723A_TRANS_END \ - /* format */ \ - /* { offset, cut_msk, fab_msk|interface_msk, base|cmd, msk, value }, */\ - {0xFFFF, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, PWR_INTF_ALL_MSK, \ - 0, PWR_CMD_END, 0, 0} - -extern struct -wlan_pwr_cfg rtl8723A_power_on_flow[RTL8723A_TRANS_CARDEMU_TO_ACT_STPS - + RTL8723A_TRANS_END_STPS]; -extern struct -wlan_pwr_cfg rtl8723A_radio_off_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS - + RTL8723A_TRANS_END_STPS]; -extern struct -wlan_pwr_cfg rtl8723A_card_disable_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS - + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS - + RTL8723A_TRANS_END_STPS]; -extern struct -wlan_pwr_cfg rtl8723A_card_enable_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS - + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS - + RTL8723A_TRANS_END_STPS]; -extern struct -wlan_pwr_cfg rtl8723A_suspend_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS - + RTL8723A_TRANS_CARDEMU_TO_SUS_STPS - + RTL8723A_TRANS_END_STPS]; -extern struct -wlan_pwr_cfg rtl8723A_resume_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS - + RTL8723A_TRANS_CARDEMU_TO_SUS_STPS - + RTL8723A_TRANS_END_STPS]; -extern struct -wlan_pwr_cfg rtl8723A_hwpdn_flow[RTL8723A_TRANS_ACT_TO_CARDEMU_STPS - + RTL8723A_TRANS_CARDEMU_TO_PDN_STPS - + RTL8723A_TRANS_END_STPS]; -extern struct -wlan_pwr_cfg rtl8723A_enter_lps_flow[RTL8723A_TRANS_ACT_TO_LPS_STPS - + RTL8723A_TRANS_END_STPS]; -extern struct -wlan_pwr_cfg rtl8723A_leave_lps_flow[RTL8723A_TRANS_LPS_TO_ACT_STPS - + RTL8723A_TRANS_END_STPS]; - -/* RTL8723 Power Configuration CMDs for PCIe interface */ -#define Rtl8723_NIC_PWR_ON_FLOW rtl8723A_power_on_flow -#define Rtl8723_NIC_RF_OFF_FLOW rtl8723A_radio_off_flow -#define Rtl8723_NIC_DISABLE_FLOW rtl8723A_card_disable_flow -#define Rtl8723_NIC_ENABLE_FLOW rtl8723A_card_enable_flow -#define Rtl8723_NIC_SUSPEND_FLOW rtl8723A_suspend_flow -#define Rtl8723_NIC_RESUME_FLOW rtl8723A_resume_flow -#define Rtl8723_NIC_PDN_FLOW rtl8723A_hwpdn_flow -#define Rtl8723_NIC_LPS_ENTER_FLOW rtl8723A_enter_lps_flow -#define Rtl8723_NIC_LPS_LEAVE_FLOW rtl8723A_leave_lps_flow - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.c b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.c deleted file mode 100644 index 2044b5936b7f..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.c +++ /dev/null @@ -1,129 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#include "pwrseq.h" - -/* Description: - * This routine deals with the Power Configuration CMD - * parsing for RTL8723/RTL8188E Series IC. - * Assumption: - * We should follow specific format that was released from HW SD. - */ -bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version, - u8 faversion, u8 interface_type, - struct wlan_pwr_cfg pwrcfgcmd[]) -{ - struct wlan_pwr_cfg cfg_cmd = {0}; - bool polling_bit = false; - u32 ary_idx = 0; - u8 value = 0; - u32 offset = 0; - u32 polling_count = 0; - u32 max_polling_cnt = 5000; - - do { - cfg_cmd = pwrcfgcmd[ary_idx]; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "rtl_hal_pwrseqcmdparsing(): offset(%#x),cut_msk(%#x), famsk(%#x)," - "interface_msk(%#x), base(%#x), cmd(%#x), msk(%#x), value(%#x)\n", - GET_PWR_CFG_OFFSET(cfg_cmd), - GET_PWR_CFG_CUT_MASK(cfg_cmd), - GET_PWR_CFG_FAB_MASK(cfg_cmd), - GET_PWR_CFG_INTF_MASK(cfg_cmd), - GET_PWR_CFG_BASE(cfg_cmd), GET_PWR_CFG_CMD(cfg_cmd), - GET_PWR_CFG_MASK(cfg_cmd), GET_PWR_CFG_VALUE(cfg_cmd)); - - if ((GET_PWR_CFG_FAB_MASK(cfg_cmd)&faversion) && - (GET_PWR_CFG_CUT_MASK(cfg_cmd)&cut_version) && - (GET_PWR_CFG_INTF_MASK(cfg_cmd)&interface_type)) { - switch (GET_PWR_CFG_CMD(cfg_cmd)) { - case PWR_CMD_READ: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "rtl_hal_pwrseqcmdparsing(): PWR_CMD_READ\n"); - break; - case PWR_CMD_WRITE: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "rtl_hal_pwrseqcmdparsing(): PWR_CMD_WRITE\n"); - offset = GET_PWR_CFG_OFFSET(cfg_cmd); - - /*Read the value from system register*/ - value = rtl_read_byte(rtlpriv, offset); - value &= (~(GET_PWR_CFG_MASK(cfg_cmd))); - value |= (GET_PWR_CFG_VALUE(cfg_cmd) & - GET_PWR_CFG_MASK(cfg_cmd)); - - /*Write the value back to sytem register*/ - rtl_write_byte(rtlpriv, offset, value); - break; - case PWR_CMD_POLLING: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "rtl_hal_pwrseqcmdparsing(): PWR_CMD_POLLING\n"); - polling_bit = false; - offset = GET_PWR_CFG_OFFSET(cfg_cmd); - - do { - value = rtl_read_byte(rtlpriv, offset); - - value &= GET_PWR_CFG_MASK(cfg_cmd); - if (value == - (GET_PWR_CFG_VALUE(cfg_cmd) - & GET_PWR_CFG_MASK(cfg_cmd))) - polling_bit = true; - else - udelay(10); - - if (polling_count++ > max_polling_cnt) - return false; - } while (!polling_bit); - break; - case PWR_CMD_DELAY: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "rtl_hal_pwrseqcmdparsing(): PWR_CMD_DELAY\n"); - if (GET_PWR_CFG_VALUE(cfg_cmd) == - PWRSEQ_DELAY_US) - udelay(GET_PWR_CFG_OFFSET(cfg_cmd)); - else - mdelay(GET_PWR_CFG_OFFSET(cfg_cmd)); - break; - case PWR_CMD_END: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "rtl_hal_pwrseqcmdparsing(): PWR_CMD_END\n"); - return true; - default: - RT_ASSERT(false, - "rtl_hal_pwrseqcmdparsing(): Unknown CMD!!\n"); - break; - } - - } - ary_idx++; - } while (1); - - return true; -} diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.h deleted file mode 100644 index 6e0f3ea37ec0..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/pwrseqcmd.h +++ /dev/null @@ -1,98 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL8723E_PWRSEQCMD_H__ -#define __RTL8723E_PWRSEQCMD_H__ - -#include "../wifi.h" -/*--------------------------------------------- - * 3 The value of cmd: 4 bits - *--------------------------------------------- - */ -#define PWR_CMD_READ 0x00 -#define PWR_CMD_WRITE 0x01 -#define PWR_CMD_POLLING 0x02 -#define PWR_CMD_DELAY 0x03 -#define PWR_CMD_END 0x04 - -/* define the base address of each block */ -#define PWR_BASEADDR_MAC 0x00 -#define PWR_BASEADDR_USB 0x01 -#define PWR_BASEADDR_PCIE 0x02 -#define PWR_BASEADDR_SDIO 0x03 - -#define PWR_INTF_SDIO_MSK BIT(0) -#define PWR_INTF_USB_MSK BIT(1) -#define PWR_INTF_PCI_MSK BIT(2) -#define PWR_INTF_ALL_MSK (BIT(0)|BIT(1)|BIT(2)|BIT(3)) - -#define PWR_FAB_TSMC_MSK BIT(0) -#define PWR_FAB_UMC_MSK BIT(1) -#define PWR_FAB_ALL_MSK (BIT(0)|BIT(1)|BIT(2)|BIT(3)) - -#define PWR_CUT_TESTCHIP_MSK BIT(0) -#define PWR_CUT_A_MSK BIT(1) -#define PWR_CUT_B_MSK BIT(2) -#define PWR_CUT_C_MSK BIT(3) -#define PWR_CUT_D_MSK BIT(4) -#define PWR_CUT_E_MSK BIT(5) -#define PWR_CUT_F_MSK BIT(6) -#define PWR_CUT_G_MSK BIT(7) -#define PWR_CUT_ALL_MSK 0xFF - -enum pwrseq_delay_unit { - PWRSEQ_DELAY_US, - PWRSEQ_DELAY_MS, -}; - -struct wlan_pwr_cfg { - u16 offset; - u8 cut_msk; - u8 fab_msk:4; - u8 interface_msk:4; - u8 base:4; - u8 cmd:4; - u8 msk; - u8 value; -}; - -#define GET_PWR_CFG_OFFSET(__PWR_CMD) (__PWR_CMD.offset) -#define GET_PWR_CFG_CUT_MASK(__PWR_CMD) (__PWR_CMD.cut_msk) -#define GET_PWR_CFG_FAB_MASK(__PWR_CMD) (__PWR_CMD.fab_msk) -#define GET_PWR_CFG_INTF_MASK(__PWR_CMD) (__PWR_CMD.interface_msk) -#define GET_PWR_CFG_BASE(__PWR_CMD) (__PWR_CMD.base) -#define GET_PWR_CFG_CMD(__PWR_CMD) (__PWR_CMD.cmd) -#define GET_PWR_CFG_MASK(__PWR_CMD) (__PWR_CMD.msk) -#define GET_PWR_CFG_VALUE(__PWR_CMD) (__PWR_CMD.value) - -bool rtl_hal_pwrseqcmdparsing(struct rtl_priv *rtlpriv, u8 cut_version, - u8 fab_version, u8 interface_type, - struct wlan_pwr_cfg pwrcfgcmd[]); - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h deleted file mode 100644 index 199da366c6da..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/reg.h +++ /dev/null @@ -1,2097 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL8723E_REG_H__ -#define __RTL8723E_REG_H__ - -#define REG_SYS_ISO_CTRL 0x0000 -#define REG_SYS_FUNC_EN 0x0002 -#define REG_APS_FSMCO 0x0004 -#define REG_SYS_CLKR 0x0008 -#define REG_9346CR 0x000A -#define REG_EE_VPD 0x000C -#define REG_AFE_MISC 0x0010 -#define REG_SPS0_CTRL 0x0011 -#define REG_SPS_OCP_CFG 0x0018 -#define REG_RSV_CTRL 0x001C -#define REG_RF_CTRL 0x001F -#define REG_LDOA15_CTRL 0x0020 -#define REG_LDOV12D_CTRL 0x0021 -#define REG_LDOHCI12_CTRL 0x0022 -#define REG_LPLDO_CTRL 0x0023 -#define REG_AFE_XTAL_CTRL 0x0024 -#define REG_AFE_PLL_CTRL 0x0028 -#define REG_EFUSE_CTRL 0x0030 -#define REG_EFUSE_TEST 0x0034 -#define REG_PWR_DATA 0x0038 -#define REG_CAL_TIMER 0x003C -#define REG_ACLK_MON 0x003E -#define REG_GPIO_MUXCFG 0x0040 -#define REG_GPIO_IO_SEL 0x0042 -#define REG_MAC_PINMUX_CFG 0x0043 -#define REG_GPIO_PIN_CTRL 0x0044 -#define REG_GPIO_INTM 0x0048 -#define REG_LEDCFG0 0x004C -#define REG_LEDCFG1 0x004D -#define REG_LEDCFG2 0x004E -#define REG_LEDCFG3 0x004F -#define REG_FSIMR 0x0050 -#define REG_FSISR 0x0054 -#define REG_GPIO_PIN_CTRL_2 0x0060 -#define REG_GPIO_IO_SEL_2 0x0062 -#define REG_MULTI_FUNC_CTRL 0x0068 - -#define REG_MCUFWDL 0x0080 - -#define REG_HMEBOX_EXT_0 0x0088 -#define REG_HMEBOX_EXT_1 0x008A -#define REG_HMEBOX_EXT_2 0x008C -#define REG_HMEBOX_EXT_3 0x008E - -#define REG_BIST_SCAN 0x00D0 -#define REG_BIST_RPT 0x00D4 -#define REG_BIST_ROM_RPT 0x00D8 -#define REG_USB_SIE_INTF 0x00E0 -#define REG_PCIE_MIO_INTF 0x00E4 -#define REG_PCIE_MIO_INTD 0x00E8 -#define REG_SYS_CFG 0x00F0 -#define REG_GPIO_OUTSTS 0x00F4 - -#define REG_CR 0x0100 -#define REG_PBP 0x0104 -#define REG_TRXDMA_CTRL 0x010C -#define REG_TRXFF_BNDY 0x0114 -#define REG_TRXFF_STATUS 0x0118 -#define REG_RXFF_PTR 0x011C -#define REG_HIMR 0x0120 -#define REG_HISR 0x0124 -#define REG_HIMRE 0x0128 -#define REG_HISRE 0x012C -#define REG_CPWM 0x012F -#define REG_FWIMR 0x0130 -#define REG_FWISR 0x0134 -#define REG_PKTBUF_DBG_CTRL 0x0140 -#define REG_PKTBUF_DBG_DATA_L 0x0144 -#define REG_PKTBUF_DBG_DATA_H 0x0148 - -#define REG_TC0_CTRL 0x0150 -#define REG_TC1_CTRL 0x0154 -#define REG_TC2_CTRL 0x0158 -#define REG_TC3_CTRL 0x015C -#define REG_TC4_CTRL 0x0160 -#define REG_TCUNIT_BASE 0x0164 -#define REG_MBIST_START 0x0174 -#define REG_MBIST_DONE 0x0178 -#define REG_MBIST_FAIL 0x017C -#define REG_C2HEVT_MSG_NORMAL 0x01A0 -#define REG_C2HEVT_MSG_TEST 0x01B8 -#define REG_MCUTST_1 0x01c0 -#define REG_FMETHR 0x01C8 -#define REG_HMETFR 0x01CC -#define REG_HMEBOX_0 0x01D0 -#define REG_HMEBOX_1 0x01D4 -#define REG_HMEBOX_2 0x01D8 -#define REG_HMEBOX_3 0x01DC - -#define REG_LLT_INIT 0x01E0 -#define REG_BB_ACCEESS_CTRL 0x01E8 -#define REG_BB_ACCESS_DATA 0x01EC - -#define REG_RQPN 0x0200 -#define REG_FIFOPAGE 0x0204 -#define REG_TDECTRL 0x0208 -#define REG_TXDMA_OFFSET_CHK 0x020C -#define REG_TXDMA_STATUS 0x0210 -#define REG_RQPN_NPQ 0x0214 - -#define REG_RXDMA_AGG_PG_TH 0x0280 -#define REG_RXPKT_NUM 0x0284 -#define REG_RXDMA_STATUS 0x0288 - -#define REG_PCIE_CTRL_REG 0x0300 -#define REG_INT_MIG 0x0304 -#define REG_BCNQ_DESA 0x0308 -#define REG_HQ_DESA 0x0310 -#define REG_MGQ_DESA 0x0318 -#define REG_VOQ_DESA 0x0320 -#define REG_VIQ_DESA 0x0328 -#define REG_BEQ_DESA 0x0330 -#define REG_BKQ_DESA 0x0338 -#define REG_RX_DESA 0x0340 -#define REG_DBI 0x0348 -#define REG_MDIO 0x0354 -#define REG_DBG_SEL 0x0360 -#define REG_PCIE_HRPWM 0x0361 -#define REG_PCIE_HCPWM 0x0363 -#define REG_UART_CTRL 0x0364 -#define REG_UART_TX_DESA 0x0370 -#define REG_UART_RX_DESA 0x0378 - -#define REG_HDAQ_DESA_NODEF 0x0000 -#define REG_CMDQ_DESA_NODEF 0x0000 - -#define REG_VOQ_INFORMATION 0x0400 -#define REG_VIQ_INFORMATION 0x0404 -#define REG_BEQ_INFORMATION 0x0408 -#define REG_BKQ_INFORMATION 0x040C -#define REG_MGQ_INFORMATION 0x0410 -#define REG_HGQ_INFORMATION 0x0414 -#define REG_BCNQ_INFORMATION 0x0418 - -#define REG_CPU_MGQ_INFORMATION 0x041C -#define REG_FWHW_TXQ_CTRL 0x0420 -#define REG_HWSEQ_CTRL 0x0423 -#define REG_TXPKTBUF_BCNQ_BDNY 0x0424 -#define REG_TXPKTBUF_MGQ_BDNY 0x0425 -#define REG_MULTI_BCNQ_EN 0x0426 -#define REG_MULTI_BCNQ_OFFSET 0x0427 -#define REG_SPEC_SIFS 0x0428 -#define REG_RL 0x042A -#define REG_DARFRC 0x0430 -#define REG_RARFRC 0x0438 -#define REG_RRSR 0x0440 -#define REG_ARFR0 0x0444 -#define REG_ARFR1 0x0448 -#define REG_ARFR2 0x044C -#define REG_ARFR3 0x0450 -#define REG_AGGLEN_LMT 0x0458 -#define REG_AMPDU_MIN_SPACE 0x045C -#define REG_TXPKTBUF_WMAC_LBK_BF_HD 0x045D -#define REG_FAST_EDCA_CTRL 0x0460 -#define REG_RD_RESP_PKT_TH 0x0463 -#define REG_INIRTS_RATE_SEL 0x0480 -#define REG_INIDATA_RATE_SEL 0x0484 -#define REG_POWER_STATUS 0x04A4 -#define REG_POWER_STAGE1 0x04B4 -#define REG_POWER_STAGE2 0x04B8 -#define REG_PKT_LIFE_TIME 0x04C0 -#define REG_STBC_SETTING 0x04C4 -#define REG_PROT_MODE_CTRL 0x04C8 -#define REG_BAR_MODE_CTRL 0x04CC -#define REG_RA_TRY_RATE_AGG_LMT 0x04CF -#define REG_NQOS_SEQ 0x04DC -#define REG_QOS_SEQ 0x04DE -#define REG_NEED_CPU_HANDLE 0x04E0 -#define REG_PKT_LOSE_RPT 0x04E1 -#define REG_PTCL_ERR_STATUS 0x04E2 -#define REG_DUMMY 0x04FC - -#define REG_EDCA_VO_PARAM 0x0500 -#define REG_EDCA_VI_PARAM 0x0504 -#define REG_EDCA_BE_PARAM 0x0508 -#define REG_EDCA_BK_PARAM 0x050C -#define REG_BCNTCFG 0x0510 -#define REG_PIFS 0x0512 -#define REG_RDG_PIFS 0x0513 -#define REG_SIFS_CTX 0x0514 -#define REG_SIFS_TRX 0x0516 -#define REG_AGGR_BREAK_TIME 0x051A -#define REG_SLOT 0x051B -#define REG_TX_PTCL_CTRL 0x0520 -#define REG_TXPAUSE 0x0522 -#define REG_DIS_TXREQ_CLR 0x0523 -#define REG_RD_CTRL 0x0524 -#define REG_TBTT_PROHIBIT 0x0540 -#define REG_RD_NAV_NXT 0x0544 -#define REG_NAV_PROT_LEN 0x0546 -#define REG_BCN_CTRL 0x0550 -#define REG_USTIME_TSF 0x0551 -#define REG_MBID_NUM 0x0552 -#define REG_DUAL_TSF_RST 0x0553 -#define REG_BCN_INTERVAL 0x0554 -#define REG_MBSSID_BCN_SPACE 0x0554 -#define REG_DRVERLYINT 0x0558 -#define REG_BCNDMATIM 0x0559 -#define REG_ATIMWND 0x055A -#define REG_BCN_MAX_ERR 0x055D -#define REG_RXTSF_OFFSET_CCK 0x055E -#define REG_RXTSF_OFFSET_OFDM 0x055F -#define REG_TSFTR 0x0560 -#define REG_INIT_TSFTR 0x0564 -#define REG_PSTIMER 0x0580 -#define REG_TIMER0 0x0584 -#define REG_TIMER1 0x0588 -#define REG_ACMHWCTRL 0x05C0 -#define REG_ACMRSTCTRL 0x05C1 -#define REG_ACMAVG 0x05C2 -#define REG_VO_ADMTIME 0x05C4 -#define REG_VI_ADMTIME 0x05C6 -#define REG_BE_ADMTIME 0x05C8 -#define REG_EDCA_RANDOM_GEN 0x05CC -#define REG_SCH_TXCMD 0x05D0 - -#define REG_APSD_CTRL 0x0600 -#define REG_BWOPMODE 0x0603 -#define REG_TCR 0x0604 -#define REG_RCR 0x0608 -#define REG_RX_PKT_LIMIT 0x060C -#define REG_RX_DLK_TIME 0x060D -#define REG_RX_DRVINFO_SZ 0x060F - -#define REG_MACID 0x0610 -#define REG_BSSID 0x0618 -#define REG_MAR 0x0620 -#define REG_MBIDCAMCFG 0x0628 - -#define REG_USTIME_EDCA 0x0638 -#define REG_MAC_SPEC_SIFS 0x063A -#define REG_RESP_SIFS_CCK 0x063C -#define REG_RESP_SIFS_OFDM 0x063E -#define REG_ACKTO 0x0640 -#define REG_CTS2TO 0x0641 -#define REG_EIFS 0x0642 - -#define REG_NAV_CTRL 0x0650 -#define REG_BACAMCMD 0x0654 -#define REG_BACAMCONTENT 0x0658 -#define REG_LBDLY 0x0660 -#define REG_FWDLY 0x0661 -#define REG_RXERR_RPT 0x0664 -#define REG_WMAC_TRXPTCL_CTL 0x0668 - -#define REG_CAMCMD 0x0670 -#define REG_CAMWRITE 0x0674 -#define REG_CAMREAD 0x0678 -#define REG_CAMDBG 0x067C -#define REG_SECCFG 0x0680 - -#define REG_WOW_CTRL 0x0690 -#define REG_PSSTATUS 0x0691 -#define REG_PS_RX_INFO 0x0692 -#define REG_LPNAV_CTRL 0x0694 -#define REG_WKFMCAM_CMD 0x0698 -#define REG_WKFMCAM_RWD 0x069C -#define REG_RXFLTMAP0 0x06A0 -#define REG_RXFLTMAP1 0x06A2 -#define REG_RXFLTMAP2 0x06A4 -#define REG_BCN_PSR_RPT 0x06A8 -#define REG_CALB32K_CTRL 0x06AC -#define REG_PKT_MON_CTRL 0x06B4 -#define REG_BT_COEX_TABLE 0x06C0 -#define REG_WMAC_RESP_TXINFO 0x06D8 - -#define REG_USB_INFO 0xFE17 -#define REG_USB_SPECIAL_OPTION 0xFE55 -#define REG_USB_DMA_AGG_TO 0xFE5B -#define REG_USB_AGG_TO 0xFE5C -#define REG_USB_AGG_TH 0xFE5D - -#define REG_TEST_USB_TXQS 0xFE48 -#define REG_TEST_SIE_VID 0xFE60 -#define REG_TEST_SIE_PID 0xFE62 -#define REG_TEST_SIE_OPTIONAL 0xFE64 -#define REG_TEST_SIE_CHIRP_K 0xFE65 -#define REG_TEST_SIE_PHY 0xFE66 -#define REG_TEST_SIE_MAC_ADDR 0xFE70 -#define REG_TEST_SIE_STRING 0xFE80 - -#define REG_NORMAL_SIE_VID 0xFE60 -#define REG_NORMAL_SIE_PID 0xFE62 -#define REG_NORMAL_SIE_OPTIONAL 0xFE64 -#define REG_NORMAL_SIE_EP 0xFE65 -#define REG_NORMAL_SIE_PHY 0xFE68 -#define REG_NORMAL_SIE_MAC_ADDR 0xFE70 -#define REG_NORMAL_SIE_STRING 0xFE80 - -#define CR9346 REG_9346CR -#define MSR (REG_CR + 2) -#define ISR REG_HISR -#define TSFR REG_TSFTR - -#define MACIDR0 REG_MACID -#define MACIDR4 (REG_MACID + 4) - -#define PBP REG_PBP - -#define IDR0 MACIDR0 -#define IDR4 MACIDR4 - -#define UNUSED_REGISTER 0x1BF -#define DCAM UNUSED_REGISTER -#define PSR UNUSED_REGISTER -#define BBADDR UNUSED_REGISTER -#define PHYDATAR UNUSED_REGISTER - -#define INVALID_BBRF_VALUE 0x12345678 - -#define MAX_MSS_DENSITY_2T 0x13 -#define MAX_MSS_DENSITY_1T 0x0A - -#define CMDEEPROM_EN BIT(5) -#define CMDEEPROM_SEL BIT(4) -#define CMD9346CR_9356SEL BIT(4) -#define AUTOLOAD_EEPROM (CMDEEPROM_EN|CMDEEPROM_SEL) -#define AUTOLOAD_EFUSE CMDEEPROM_EN - -#define GPIOSEL_GPIO 0 -#define GPIOSEL_ENBT BIT(5) - -#define GPIO_IN REG_GPIO_PIN_CTRL -#define GPIO_OUT (REG_GPIO_PIN_CTRL+1) -#define GPIO_IO_SEL (REG_GPIO_PIN_CTRL+2) -#define GPIO_MOD (REG_GPIO_PIN_CTRL+3) - -#define MSR_NOLINK 0x00 -#define MSR_ADHOC 0x01 -#define MSR_INFRA 0x02 -#define MSR_AP 0x03 - -#define RRSR_RSC_OFFSET 21 -#define RRSR_SHORT_OFFSET 23 -#define RRSR_RSC_BW_40M 0x600000 -#define RRSR_RSC_UPSUBCHNL 0x400000 -#define RRSR_RSC_LOWSUBCHNL 0x200000 -#define RRSR_SHORT 0x800000 -#define RRSR_1M BIT(0) -#define RRSR_2M BIT(1) -#define RRSR_5_5M BIT(2) -#define RRSR_11M BIT(3) -#define RRSR_6M BIT(4) -#define RRSR_9M BIT(5) -#define RRSR_12M BIT(6) -#define RRSR_18M BIT(7) -#define RRSR_24M BIT(8) -#define RRSR_36M BIT(9) -#define RRSR_48M BIT(10) -#define RRSR_54M BIT(11) -#define RRSR_MCS0 BIT(12) -#define RRSR_MCS1 BIT(13) -#define RRSR_MCS2 BIT(14) -#define RRSR_MCS3 BIT(15) -#define RRSR_MCS4 BIT(16) -#define RRSR_MCS5 BIT(17) -#define RRSR_MCS6 BIT(18) -#define RRSR_MCS7 BIT(19) -#define BRSR_ACKSHORTPMB BIT(23) - -#define RATR_1M 0x00000001 -#define RATR_2M 0x00000002 -#define RATR_55M 0x00000004 -#define RATR_11M 0x00000008 -#define RATR_6M 0x00000010 -#define RATR_9M 0x00000020 -#define RATR_12M 0x00000040 -#define RATR_18M 0x00000080 -#define RATR_24M 0x00000100 -#define RATR_36M 0x00000200 -#define RATR_48M 0x00000400 -#define RATR_54M 0x00000800 -#define RATR_MCS0 0x00001000 -#define RATR_MCS1 0x00002000 -#define RATR_MCS2 0x00004000 -#define RATR_MCS3 0x00008000 -#define RATR_MCS4 0x00010000 -#define RATR_MCS5 0x00020000 -#define RATR_MCS6 0x00040000 -#define RATR_MCS7 0x00080000 -#define RATR_MCS8 0x00100000 -#define RATR_MCS9 0x00200000 -#define RATR_MCS10 0x00400000 -#define RATR_MCS11 0x00800000 -#define RATR_MCS12 0x01000000 -#define RATR_MCS13 0x02000000 -#define RATR_MCS14 0x04000000 -#define RATR_MCS15 0x08000000 - -#define RATE_ALL_CCK (RATR_1M | RATR_2M | RATR_55M | RATR_11M) -#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | RATR_12M | RATR_18M |\ - RATR_24M | RATR_36M | RATR_48M | RATR_54M) -#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 |\ - RATR_MCS3 | RATR_MCS4 | RATR_MCS5 |\ - RATR_MCS6 | RATR_MCS7) -#define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 |\ - RATR_MCS11 | RATR_MCS12 | RATR_MCS13 |\ - RATR_MCS14 | RATR_MCS15) - -#define BW_OPMODE_20MHZ BIT(2) -#define BW_OPMODE_5G BIT(1) -#define BW_OPMODE_11J BIT(0) - -#define CAM_VALID BIT(15) -#define CAM_NOTVALID 0x0000 -#define CAM_USEDK BIT(5) - -#define CAM_NONE 0x0 -#define CAM_WEP40 0x01 -#define CAM_TKIP 0x02 -#define CAM_AES 0x04 -#define CAM_WEP104 0x05 - -#define TOTAL_CAM_ENTRY 32 -#define HALF_CAM_ENTRY 16 - -#define CAM_WRITE BIT(16) -#define CAM_READ 0x00000000 -#define CAM_POLLINIG BIT(31) - -#define SCR_USEDK 0x01 -#define SCR_TXSEC_ENABLE 0x02 -#define SCR_RXSEC_ENABLE 0x04 - -#define WOW_PMEN BIT(0) -#define WOW_WOMEN BIT(1) -#define WOW_MAGIC BIT(2) -#define WOW_UWF BIT(3) - -#define IMR8190_DISABLED 0x0 -#define IMR_BCNDMAINT6 BIT(31) -#define IMR_BCNDMAINT5 BIT(30) -#define IMR_BCNDMAINT4 BIT(29) -#define IMR_BCNDMAINT3 BIT(28) -#define IMR_BCNDMAINT2 BIT(27) -#define IMR_BCNDMAINT1 BIT(26) -#define IMR_BCNDOK8 BIT(25) -#define IMR_BCNDOK7 BIT(24) -#define IMR_BCNDOK6 BIT(23) -#define IMR_BCNDOK5 BIT(22) -#define IMR_BCNDOK4 BIT(21) -#define IMR_BCNDOK3 BIT(20) -#define IMR_BCNDOK2 BIT(19) -#define IMR_BCNDOK1 BIT(18) -#define IMR_TIMEOUT2 BIT(17) -#define IMR_TIMEOUT1 BIT(16) -#define IMR_TXFOVW BIT(15) -#define IMR_PSTIMEOUT BIT(14) -#define IMR_BCNINT BIT(13) -#define IMR_RXFOVW BIT(12) -#define IMR_RDU BIT(11) -#define IMR_ATIMEND BIT(10) -#define IMR_BDOK BIT(9) -#define IMR_HIGHDOK BIT(8) -#define IMR_TBDOK BIT(7) -#define IMR_MGNTDOK BIT(6) -#define IMR_TBDER BIT(5) -#define IMR_BKDOK BIT(4) -#define IMR_BEDOK BIT(3) -#define IMR_VIDOK BIT(2) -#define IMR_VODOK BIT(1) -#define IMR_ROK BIT(0) - -#define IMR_TXERR BIT(11) -#define IMR_RXERR BIT(10) -#define IMR_CPWM BIT(8) -#define IMR_OCPINT BIT(1) -#define IMR_WLANOFF BIT(0) - -/* 8723E series PCIE Host IMR/ISR bit */ -/* IMR DW0 Bit 0-31 */ -#define PHIMR_TIMEOUT2 BIT(31) -#define PHIMR_TIMEOUT1 BIT(30) -#define PHIMR_PSTIMEOUT BIT(29) -#define PHIMR_GTINT4 BIT(28) -#define PHIMR_GTINT3 BIT(27) -#define PHIMR_TXBCNERR BIT(26) -#define PHIMR_TXBCNOK BIT(25) -#define PHIMR_TSF_BIT32_TOGGLE BIT(24) -#define PHIMR_BCNDMAINT3 BIT(23) -#define PHIMR_BCNDMAINT2 BIT(22) -#define PHIMR_BCNDMAINT1 BIT(21) -#define PHIMR_BCNDMAINT0 BIT(20) -#define PHIMR_BCNDOK3 BIT(19) -#define PHIMR_BCNDOK2 BIT(18) -#define PHIMR_BCNDOK1 BIT(17) -#define PHIMR_BCNDOK0 BIT(16) -#define PHIMR_HSISR_IND_ON BIT(15) -#define PHIMR_BCNDMAINT_E BIT(14) -#define PHIMR_ATIMEND_E BIT(13) -#define PHIMR_ATIM_CTW_END BIT(12) -#define PHIMR_HISRE_IND BIT(11) -#define PHIMR_C2HCMD BIT(10) -#define PHIMR_CPWM2 BIT(9) -#define PHIMR_CPWM BIT(8) -#define PHIMR_HIGHDOK BIT(7) -#define PHIMR_MGNTDOK BIT(6) -#define PHIMR_BKDOK BIT(5) -#define PHIMR_BEDOK BIT(4) -#define PHIMR_VIDOK BIT(3) -#define PHIMR_VODOK BIT(2) -#define PHIMR_RDU BIT(1) -#define PHIMR_ROK BIT(0) - -/* PCIE Host Interrupt Status Extension bit */ -#define PHIMR_BCNDMAINT7 BIT(23) -#define PHIMR_BCNDMAINT6 BIT(22) -#define PHIMR_BCNDMAINT5 BIT(21) -#define PHIMR_BCNDMAINT4 BIT(20) -#define PHIMR_BCNDOK7 BIT(19) -#define PHIMR_BCNDOK6 BIT(18) -#define PHIMR_BCNDOK5 BIT(17) -#define PHIMR_BCNDOK4 BIT(16) -/* bit12-15: RSVD */ -#define PHIMR_TXERR BIT(11) -#define PHIMR_RXERR BIT(10) -#define PHIMR_TXFOVW BIT(9) -#define PHIMR_RXFOVW BIT(8) -/* bit2-7: RSV */ -#define PHIMR_OCPINT BIT(1) - -#define HWSET_MAX_SIZE 256 -#define EFUSE_MAX_SECTION 32 -#define EFUSE_REAL_CONTENT_LEN 512 -#define EFUSE_OOB_PROTECT_BYTES 15 - -#define EEPROM_DEFAULT_TSSI 0x0 -#define EEPROM_DEFAULT_TXPOWERDIFF 0x0 -#define EEPROM_DEFAULT_CRYSTALCAP 0x5 -#define EEPROM_DEFAULT_BOARDTYPE 0x02 -#define EEPROM_DEFAULT_TXPOWER 0x1010 -#define EEPROM_DEFAULT_HT2T_TXPWR 0x10 - -#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3 -#define EEPROM_DEFAULT_THERMALMETER 0x12 -#define EEPROM_DEFAULT_ANTTXPOWERDIFF 0x0 -#define EEPROM_DEFAULT_TXPWDIFF_CRYSTALCAP 0x5 -#define EEPROM_DEFAULT_TXPOWERLEVEL 0x22 -#define EEPROM_DEFAULT_HT40_2SDIFF 0x0 -#define EEPROM_DEFAULT_HT20_DIFF 2 -#define EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF 0x3 -#define EEPROM_DEFAULT_HT40_PWRMAXOFFSET 0 -#define EEPROM_DEFAULT_HT20_PWRMAXOFFSET 0 - - -#define EEPROM_DEFAULT_PID 0x1234 -#define EEPROM_DEFAULT_VID 0x5678 -#define EEPROM_DEFAULT_CUSTOMERID 0xAB -#define EEPROM_DEFAULT_SUBCUSTOMERID 0xCD -#define EEPROM_DEFAULT_VERSION 0 - -#define EEPROM_CHANNEL_PLAN_FCC 0x0 -#define EEPROM_CHANNEL_PLAN_IC 0x1 -#define EEPROM_CHANNEL_PLAN_ETSI 0x2 -#define EEPROM_CHANNEL_PLAN_SPAIN 0x3 -#define EEPROM_CHANNEL_PLAN_FRANCE 0x4 -#define EEPROM_CHANNEL_PLAN_MKK 0x5 -#define EEPROM_CHANNEL_PLAN_MKK1 0x6 -#define EEPROM_CHANNEL_PLAN_ISRAEL 0x7 -#define EEPROM_CHANNEL_PLAN_TELEC 0x8 -#define EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN 0x9 -#define EEPROM_CHANNEL_PLAN_WORLD_WIDE_13 0xA -#define EEPROM_CHANNEL_PLAN_NCC 0xB -#define EEPROM_CHANNEL_PLAN_BY_HW_MASK 0x80 - -#define EEPROM_CID_DEFAULT 0x0 -#define EEPROM_CID_TOSHIBA 0x4 -#define EEPROM_CID_CCX 0x10 -#define EEPROM_CID_QMI 0x0D -#define EEPROM_CID_WHQL 0xFE - -#define RTL8192_EEPROM_ID 0x8129 - -#define RTL8190_EEPROM_ID 0x8129 -#define EEPROM_HPON 0x02 -#define EEPROM_CLK 0x06 -#define EEPROM_TESTR 0x08 - -#define EEPROM_VID 0x49 -#define EEPROM_DID 0x4B -#define EEPROM_SVID 0x4D -#define EEPROM_SMID 0x4F - -#define EEPROM_MAC_ADDR 0x67 - -#define EEPROM_CCK_TX_PWR_INX 0x5A -#define EEPROM_HT40_1S_TX_PWR_INX 0x60 -#define EEPROM_HT40_2S_TX_PWR_INX_DIFF 0x66 -#define EEPROM_HT20_TX_PWR_INX_DIFF 0x69 -#define EEPROM_OFDM_TX_PWR_INX_DIFF 0x6C -#define EEPROM_HT40_MAX_PWR_OFFSET 0x25 -#define EEPROM_HT20_MAX_PWR_OFFSET 0x22 - -#define EEPROM_THERMAL_METER 0x2a -#define EEPROM_XTAL_K 0x78 -#define EEPROM_RF_OPT1 0x79 -#define EEPROM_RF_OPT2 0x7A -#define EEPROM_RF_OPT3 0x7B -#define EEPROM_RF_OPT4 0x7C -#define EEPROM_CHANNEL_PLAN 0x28 -#define EEPROM_VERSION 0x30 -#define EEPROM_CUSTOMER_ID 0x31 - -#define EEPROM_PWRDIFF 0x54 - -#define EEPROM_TXPOWERCCK 0x10 -#define EEPROM_TXPOWERHT40_1S 0x16 -#define EEPROM_TXPOWERHT40_2SDIFF 0x66 -#define EEPROM_TXPOWERHT20DIFF 0x1C -#define EEPROM_TXPOWER_OFDMDIFF 0x1F - -#define EEPROM_TXPWR_GROUP 0x22 - -#define EEPROM_TSSI_A 0x29 -#define EEPROM_TSSI_B 0x77 - -#define EEPROM_CHANNELPLAN 0x28 - -#define RF_OPTION1 0x2B -#define RF_OPTION2 0x2C -#define RF_OPTION3 0x2D -#define RF_OPTION4 0x2E - -#define STOPBECON BIT(6) -#define STOPHIGHT BIT(5) -#define STOPMGT BIT(4) -#define STOPVO BIT(3) -#define STOPVI BIT(2) -#define STOPBE BIT(1) -#define STOPBK BIT(0) - -#define RCR_APPFCS BIT(31) -#define RCR_APP_MIC BIT(30) -#define RCR_APP_ICV BIT(29) -#define RCR_APP_PHYST_RXFF BIT(28) -#define RCR_APP_BA_SSN BIT(27) -#define RCR_ENMBID BIT(24) -#define RCR_LSIGEN BIT(23) -#define RCR_MFBEN BIT(22) -#define RCR_HTC_LOC_CTRL BIT(14) -#define RCR_AMF BIT(13) -#define RCR_ACF BIT(12) -#define RCR_ADF BIT(11) -#define RCR_AICV BIT(9) -#define RCR_ACRC32 BIT(8) -#define RCR_CBSSID_BCN BIT(7) -#define RCR_CBSSID_DATA BIT(6) -#define RCR_CBSSID RCR_CBSSID_DATA -#define RCR_APWRMGT BIT(5) -#define RCR_ADD3 BIT(4) -#define RCR_AB BIT(3) -#define RCR_AM BIT(2) -#define RCR_APM BIT(1) -#define RCR_AAP BIT(0) -#define RCR_MXDMA_OFFSET 8 -#define RCR_FIFO_OFFSET 13 - -#define RSV_CTRL 0x001C -#define RD_CTRL 0x0524 - -#define REG_USB_INFO 0xFE17 -#define REG_USB_SPECIAL_OPTION 0xFE55 -#define REG_USB_DMA_AGG_TO 0xFE5B -#define REG_USB_AGG_TO 0xFE5C -#define REG_USB_AGG_TH 0xFE5D - -#define REG_USB_VID 0xFE60 -#define REG_USB_PID 0xFE62 -#define REG_USB_OPTIONAL 0xFE64 -#define REG_USB_CHIRP_K 0xFE65 -#define REG_USB_PHY 0xFE66 -#define REG_USB_MAC_ADDR 0xFE70 -#define REG_USB_HRPWM 0xFE58 -#define REG_USB_HCPWM 0xFE57 - -#define SW18_FPWM BIT(3) - -#define ISO_MD2PP BIT(0) -#define ISO_UA2USB BIT(1) -#define ISO_UD2CORE BIT(2) -#define ISO_PA2PCIE BIT(3) -#define ISO_PD2CORE BIT(4) -#define ISO_IP2MAC BIT(5) -#define ISO_DIOP BIT(6) -#define ISO_DIOE BIT(7) -#define ISO_EB2CORE BIT(8) -#define ISO_DIOR BIT(9) - -#define PWC_EV25V BIT(14) -#define PWC_EV12V BIT(15) - -#define FEN_BBRSTB BIT(0) -#define FEN_BB_GLB_RSTn BIT(1) -#define FEN_USBA BIT(2) -#define FEN_UPLL BIT(3) -#define FEN_USBD BIT(4) -#define FEN_DIO_PCIE BIT(5) -#define FEN_PCIEA BIT(6) -#define FEN_PPLL BIT(7) -#define FEN_PCIED BIT(8) -#define FEN_DIOE BIT(9) -#define FEN_CPUEN BIT(10) -#define FEN_DCORE BIT(11) -#define FEN_ELDR BIT(12) -#define FEN_DIO_RF BIT(13) -#define FEN_HWPDN BIT(14) -#define FEN_MREGEN BIT(15) - -#define PFM_LDALL BIT(0) -#define PFM_ALDN BIT(1) -#define PFM_LDKP BIT(2) -#define PFM_WOWL BIT(3) -#define EnPDN BIT(4) -#define PDN_PL BIT(5) -#define APFM_ONMAC BIT(8) -#define APFM_OFF BIT(9) -#define APFM_RSM BIT(10) -#define AFSM_HSUS BIT(11) -#define AFSM_PCIE BIT(12) -#define APDM_MAC BIT(13) -#define APDM_HOST BIT(14) -#define APDM_HPDN BIT(15) -#define RDY_MACON BIT(16) -#define SUS_HOST BIT(17) -#define ROP_ALD BIT(20) -#define ROP_PWR BIT(21) -#define ROP_SPS BIT(22) -#define SOP_MRST BIT(25) -#define SOP_FUSE BIT(26) -#define SOP_ABG BIT(27) -#define SOP_AMB BIT(28) -#define SOP_RCK BIT(29) -#define SOP_A8M BIT(30) -#define XOP_BTCK BIT(31) - -#define ANAD16V_EN BIT(0) -#define ANA8M BIT(1) -#define MACSLP BIT(4) -#define LOADER_CLK_EN BIT(5) -#define _80M_SSC_DIS BIT(7) -#define _80M_SSC_EN_HO BIT(8) -#define PHY_SSC_RSTB BIT(9) -#define SEC_CLK_EN BIT(10) -#define MAC_CLK_EN BIT(11) -#define SYS_CLK_EN BIT(12) -#define RING_CLK_EN BIT(13) - -#define BOOT_FROM_EEPROM BIT(4) -#define EEPROM_EN BIT(5) - -#define AFE_BGEN BIT(0) -#define AFE_MBEN BIT(1) -#define MAC_ID_EN BIT(7) - -#define WLOCK_ALL BIT(0) -#define WLOCK_00 BIT(1) -#define WLOCK_04 BIT(2) -#define WLOCK_08 BIT(3) -#define WLOCK_40 BIT(4) -#define R_DIS_PRST_0 BIT(5) -#define R_DIS_PRST_1 BIT(6) -#define LOCK_ALL_EN BIT(7) - -#define RF_EN BIT(0) -#define RF_RSTB BIT(1) -#define RF_SDMRSTB BIT(2) - -#define LDA15_EN BIT(0) -#define LDA15_STBY BIT(1) -#define LDA15_OBUF BIT(2) -#define LDA15_REG_VOS BIT(3) -#define _LDA15_VOADJ(x) (((x) & 0x7) << 4) - -#define LDV12_EN BIT(0) -#define LDV12_SDBY BIT(1) -#define LPLDO_HSM BIT(2) -#define LPLDO_LSM_DIS BIT(3) -#define _LDV12_VADJ(x) (((x) & 0xF) << 4) - -#define XTAL_EN BIT(0) -#define XTAL_BSEL BIT(1) -#define _XTAL_BOSC(x) (((x) & 0x3) << 2) -#define _XTAL_CADJ(x) (((x) & 0xF) << 4) -#define XTAL_GATE_USB BIT(8) -#define _XTAL_USB_DRV(x) (((x) & 0x3) << 9) -#define XTAL_GATE_AFE BIT(11) -#define _XTAL_AFE_DRV(x) (((x) & 0x3) << 12) -#define XTAL_RF_GATE BIT(14) -#define _XTAL_RF_DRV(x) (((x) & 0x3) << 15) -#define XTAL_GATE_DIG BIT(17) -#define _XTAL_DIG_DRV(x) (((x) & 0x3) << 18) -#define XTAL_BT_GATE BIT(20) -#define _XTAL_BT_DRV(x) (((x) & 0x3) << 21) -#define _XTAL_GPIO(x) (((x) & 0x7) << 23) - -#define CKDLY_AFE BIT(26) -#define CKDLY_USB BIT(27) -#define CKDLY_DIG BIT(28) -#define CKDLY_BT BIT(29) - -#define APLL_EN BIT(0) -#define APLL_320_EN BIT(1) -#define APLL_FREF_SEL BIT(2) -#define APLL_EDGE_SEL BIT(3) -#define APLL_WDOGB BIT(4) -#define APLL_LPFEN BIT(5) - -#define APLL_REF_CLK_13MHZ 0x1 -#define APLL_REF_CLK_19_2MHZ 0x2 -#define APLL_REF_CLK_20MHZ 0x3 -#define APLL_REF_CLK_25MHZ 0x4 -#define APLL_REF_CLK_26MHZ 0x5 -#define APLL_REF_CLK_38_4MHZ 0x6 -#define APLL_REF_CLK_40MHZ 0x7 - -#define APLL_320EN BIT(14) -#define APLL_80EN BIT(15) -#define APLL_1MEN BIT(24) - -#define ALD_EN BIT(18) -#define EF_PD BIT(19) -#define EF_FLAG BIT(31) - -#define EF_TRPT BIT(7) -#define LDOE25_EN BIT(31) - -#define RSM_EN BIT(0) -#define Timer_EN BIT(4) - -#define TRSW0EN BIT(2) -#define TRSW1EN BIT(3) -#define EROM_EN BIT(4) -#define EnBT BIT(5) -#define EnUart BIT(8) -#define Uart_910 BIT(9) -#define EnPMAC BIT(10) -#define SIC_SWRST BIT(11) -#define EnSIC BIT(12) -#define SIC_23 BIT(13) -#define EnHDP BIT(14) -#define SIC_LBK BIT(15) - -#define LED0PL BIT(4) -#define LED1PL BIT(12) -#define LED0DIS BIT(7) - -#define MCUFWDL_EN BIT(0) -#define MCUFWDL_RDY BIT(1) -#define FWDL_ChkSum_rpt BIT(2) -#define MACINI_RDY BIT(3) -#define BBINI_RDY BIT(4) -#define RFINI_RDY BIT(5) -#define WINTINI_RDY BIT(6) -#define CPRST BIT(23) - -#define XCLK_VLD BIT(0) -#define ACLK_VLD BIT(1) -#define UCLK_VLD BIT(2) -#define PCLK_VLD BIT(3) -#define PCIRSTB BIT(4) -#define V15_VLD BIT(5) -#define TRP_B15V_EN BIT(7) -#define SIC_IDLE BIT(8) -#define BD_MAC2 BIT(9) -#define BD_MAC1 BIT(10) -#define IC_MACPHY_MODE BIT(11) -#define BT_FUNC BIT(16) -#define VENDOR_ID BIT(19) -#define PAD_HWPD_IDN BIT(22) -#define TRP_VAUX_EN BIT(23) -#define TRP_BT_EN BIT(24) -#define BD_PKG_SEL BIT(25) -#define BD_HCI_SEL BIT(26) -#define TYPE_ID BIT(27) - -#define CHIP_VER_RTL_MASK 0xF000 -#define CHIP_VER_RTL_SHIFT 12 - -#define REG_LBMODE (REG_CR + 3) - -#define HCI_TXDMA_EN BIT(0) -#define HCI_RXDMA_EN BIT(1) -#define TXDMA_EN BIT(2) -#define RXDMA_EN BIT(3) -#define PROTOCOL_EN BIT(4) -#define SCHEDULE_EN BIT(5) -#define MACTXEN BIT(6) -#define MACRXEN BIT(7) -#define ENSWBCN BIT(8) -#define ENSEC BIT(9) - -#define _NETTYPE(x) (((x) & 0x3) << 16) -#define MASK_NETTYPE 0x30000 -#define NT_NO_LINK 0x0 -#define NT_LINK_AD_HOC 0x1 -#define NT_LINK_AP 0x2 -#define NT_AS_AP 0x3 - -#define _LBMODE(x) (((x) & 0xF) << 24) -#define MASK_LBMODE 0xF000000 -#define LOOPBACK_NORMAL 0x0 -#define LOOPBACK_IMMEDIATELY 0xB -#define LOOPBACK_MAC_DELAY 0x3 -#define LOOPBACK_PHY 0x1 -#define LOOPBACK_DMA 0x7 - -#define GET_RX_PAGE_SIZE(value) ((value) & 0xF) -#define GET_TX_PAGE_SIZE(value) (((value) & 0xF0) >> 4) -#define _PSRX_MASK 0xF -#define _PSTX_MASK 0xF0 -#define _PSRX(x) (x) -#define _PSTX(x) ((x) << 4) - -#define PBP_64 0x0 -#define PBP_128 0x1 -#define PBP_256 0x2 -#define PBP_512 0x3 -#define PBP_1024 0x4 - -#define RXDMA_ARBBW_EN BIT(0) -#define RXSHFT_EN BIT(1) -#define RXDMA_AGG_EN BIT(2) -#define QS_VO_QUEUE BIT(8) -#define QS_VI_QUEUE BIT(9) -#define QS_BE_QUEUE BIT(10) -#define QS_BK_QUEUE BIT(11) -#define QS_MANAGER_QUEUE BIT(12) -#define QS_HIGH_QUEUE BIT(13) - -#define HQSEL_VOQ BIT(0) -#define HQSEL_VIQ BIT(1) -#define HQSEL_BEQ BIT(2) -#define HQSEL_BKQ BIT(3) -#define HQSEL_MGTQ BIT(4) -#define HQSEL_HIQ BIT(5) - -#define _TXDMA_HIQ_MAP(x) (((x)&0x3) << 14) -#define _TXDMA_MGQ_MAP(x) (((x)&0x3) << 12) -#define _TXDMA_BKQ_MAP(x) (((x)&0x3) << 10) -#define _TXDMA_BEQ_MAP(x) (((x)&0x3) << 8) -#define _TXDMA_VIQ_MAP(x) (((x)&0x3) << 6) -#define _TXDMA_VOQ_MAP(x) (((x)&0x3) << 4) - -#define QUEUE_LOW 1 -#define QUEUE_NORMAL 2 -#define QUEUE_HIGH 3 - -#define _LLT_NO_ACTIVE 0x0 -#define _LLT_WRITE_ACCESS 0x1 -#define _LLT_READ_ACCESS 0x2 - -#define _LLT_INIT_DATA(x) ((x) & 0xFF) -#define _LLT_INIT_ADDR(x) (((x) & 0xFF) << 8) -#define _LLT_OP(x) (((x) & 0x3) << 30) -#define _LLT_OP_VALUE(x) (((x) >> 30) & 0x3) - -#define BB_WRITE_READ_MASK (BIT(31) | BIT(30)) -#define BB_WRITE_EN BIT(30) -#define BB_READ_EN BIT(31) - -#define _HPQ(x) ((x) & 0xFF) -#define _LPQ(x) (((x) & 0xFF) << 8) -#define _PUBQ(x) (((x) & 0xFF) << 16) -#define _NPQ(x) ((x) & 0xFF) - -#define HPQ_PUBLIC_DIS BIT(24) -#define LPQ_PUBLIC_DIS BIT(25) -#define LD_RQPN BIT(31) - -#define BCN_VALID BIT(16) -#define BCN_HEAD(x) (((x) & 0xFF) << 8) -#define BCN_HEAD_MASK 0xFF00 - -#define BLK_DESC_NUM_SHIFT 4 -#define BLK_DESC_NUM_MASK 0xF - -#define DROP_DATA_EN BIT(9) - -#define EN_AMPDU_RTY_NEW BIT(7) - -#define _INIRTSMCS_SEL(x) ((x) & 0x3F) - -#define _SPEC_SIFS_CCK(x) ((x) & 0xFF) -#define _SPEC_SIFS_OFDM(x) (((x) & 0xFF) << 8) - -#define RATE_REG_BITMAP_ALL 0xFFFFF - -#define _RRSC_BITMAP(x) ((x) & 0xFFFFF) - -#define _RRSR_RSC(x) (((x) & 0x3) << 21) -#define RRSR_RSC_RESERVED 0x0 -#define RRSR_RSC_UPPER_SUBCHANNEL 0x1 -#define RRSR_RSC_LOWER_SUBCHANNEL 0x2 -#define RRSR_RSC_DUPLICATE_MODE 0x3 - -#define USE_SHORT_G1 BIT(20) - -#define _AGGLMT_MCS0(x) ((x) & 0xF) -#define _AGGLMT_MCS1(x) (((x) & 0xF) << 4) -#define _AGGLMT_MCS2(x) (((x) & 0xF) << 8) -#define _AGGLMT_MCS3(x) (((x) & 0xF) << 12) -#define _AGGLMT_MCS4(x) (((x) & 0xF) << 16) -#define _AGGLMT_MCS5(x) (((x) & 0xF) << 20) -#define _AGGLMT_MCS6(x) (((x) & 0xF) << 24) -#define _AGGLMT_MCS7(x) (((x) & 0xF) << 28) - -#define RETRY_LIMIT_SHORT_SHIFT 8 -#define RETRY_LIMIT_LONG_SHIFT 0 - -#define _DARF_RC1(x) ((x) & 0x1F) -#define _DARF_RC2(x) (((x) & 0x1F) << 8) -#define _DARF_RC3(x) (((x) & 0x1F) << 16) -#define _DARF_RC4(x) (((x) & 0x1F) << 24) -#define _DARF_RC5(x) ((x) & 0x1F) -#define _DARF_RC6(x) (((x) & 0x1F) << 8) -#define _DARF_RC7(x) (((x) & 0x1F) << 16) -#define _DARF_RC8(x) (((x) & 0x1F) << 24) - -#define _RARF_RC1(x) ((x) & 0x1F) -#define _RARF_RC2(x) (((x) & 0x1F) << 8) -#define _RARF_RC3(x) (((x) & 0x1F) << 16) -#define _RARF_RC4(x) (((x) & 0x1F) << 24) -#define _RARF_RC5(x) ((x) & 0x1F) -#define _RARF_RC6(x) (((x) & 0x1F) << 8) -#define _RARF_RC7(x) (((x) & 0x1F) << 16) -#define _RARF_RC8(x) (((x) & 0x1F) << 24) - -#define AC_PARAM_TXOP_LIMIT_OFFSET 16 -#define AC_PARAM_ECW_MAX_OFFSET 12 -#define AC_PARAM_ECW_MIN_OFFSET 8 -#define AC_PARAM_AIFS_OFFSET 0 - -#define _AIFS(x) (x) -#define _ECW_MAX_MIN(x) ((x) << 8) -#define _TXOP_LIMIT(x) ((x) << 16) - -#define _BCNIFS(x) ((x) & 0xFF) -#define _BCNECW(x) ((((x) & 0xF)) << 8) - -#define _LRL(x) ((x) & 0x3F) -#define _SRL(x) (((x) & 0x3F) << 8) - -#define _SIFS_CCK_CTX(x) ((x) & 0xFF) -#define _SIFS_CCK_TRX(x) (((x) & 0xFF) << 8); - -#define _SIFS_OFDM_CTX(x) ((x) & 0xFF) -#define _SIFS_OFDM_TRX(x) (((x) & 0xFF) << 8); - -#define _TBTT_PROHIBIT_HOLD(x) (((x) & 0xFF) << 8) - -#define DIS_EDCA_CNT_DWN BIT(11) - -#define EN_MBSSID BIT(1) -#define EN_TXBCN_RPT BIT(2) -#define EN_BCN_FUNCTION BIT(3) - -#define TSFTR_RST BIT(0) -#define TSFTR1_RST BIT(1) - -#define STOP_BCNQ BIT(6) - -#define DIS_TSF_UDT0_NORMAL_CHIP BIT(4) -#define DIS_TSF_UDT0_TEST_CHIP BIT(5) - -#define AcmHw_HwEn BIT(0) -#define AcmHw_BeqEn BIT(1) -#define AcmHw_ViqEn BIT(2) -#define AcmHw_VoqEn BIT(3) -#define AcmHw_BeqStatus BIT(4) -#define AcmHw_ViqStatus BIT(5) -#define AcmHw_VoqStatus BIT(6) - -#define APSDOFF BIT(6) -#define APSDOFF_STATUS BIT(7) - -#define BW_20MHZ BIT(2) - -#define RATE_BITMAP_ALL 0xFFFFF - -#define RATE_RRSR_CCK_ONLY_1M 0xFFFF1 - -#define TSFRST BIT(0) -#define DIS_GCLK BIT(1) -#define PAD_SEL BIT(2) -#define PWR_ST BIT(6) -#define PWRBIT_OW_EN BIT(7) -#define ACRC BIT(8) -#define CFENDFORM BIT(9) -#define ICV BIT(10) - -#define AAP BIT(0) -#define APM BIT(1) -#define AM BIT(2) -#define AB BIT(3) -#define ADD3 BIT(4) -#define APWRMGT BIT(5) -#define CBSSID BIT(6) -#define CBSSID_DATA BIT(6) -#define CBSSID_BCN BIT(7) -#define ACRC32 BIT(8) -#define AICV BIT(9) -#define ADF BIT(11) -#define ACF BIT(12) -#define AMF BIT(13) -#define HTC_LOC_CTRL BIT(14) -#define UC_DATA_EN BIT(16) -#define BM_DATA_EN BIT(17) -#define MFBEN BIT(22) -#define LSIGEN BIT(23) -#define EnMBID BIT(24) -#define APP_BASSN BIT(27) -#define APP_PHYSTS BIT(28) -#define APP_ICV BIT(29) -#define APP_MIC BIT(30) -#define APP_FCS BIT(31) - -#define _MIN_SPACE(x) ((x) & 0x7) -#define _SHORT_GI_PADDING(x) (((x) & 0x1F) << 3) - -#define RXERR_TYPE_OFDM_PPDU 0 -#define RXERR_TYPE_OFDM_FALSE_ALARM 1 -#define RXERR_TYPE_OFDM_MPDU_OK 2 -#define RXERR_TYPE_OFDM_MPDU_FAIL 3 -#define RXERR_TYPE_CCK_PPDU 4 -#define RXERR_TYPE_CCK_FALSE_ALARM 5 -#define RXERR_TYPE_CCK_MPDU_OK 6 -#define RXERR_TYPE_CCK_MPDU_FAIL 7 -#define RXERR_TYPE_HT_PPDU 8 -#define RXERR_TYPE_HT_FALSE_ALARM 9 -#define RXERR_TYPE_HT_MPDU_TOTAL 10 -#define RXERR_TYPE_HT_MPDU_OK 11 -#define RXERR_TYPE_HT_MPDU_FAIL 12 -#define RXERR_TYPE_RX_FULL_DROP 15 - -#define RXERR_COUNTER_MASK 0xFFFFF -#define RXERR_RPT_RST BIT(27) -#define _RXERR_RPT_SEL(type) ((type) << 28) - -#define SCR_TxUseDK BIT(0) -#define SCR_RxUseDK BIT(1) -#define SCR_TxEncEnable BIT(2) -#define SCR_RxDecEnable BIT(3) -#define SCR_SKByA2 BIT(4) -#define SCR_NoSKMC BIT(5) -#define SCR_TXBCUSEDK BIT(6) -#define SCR_RXBCUSEDK BIT(7) - -#define USB_IS_HIGH_SPEED 0 -#define USB_IS_FULL_SPEED 1 -#define USB_SPEED_MASK BIT(5) - -#define USB_NORMAL_SIE_EP_MASK 0xF -#define USB_NORMAL_SIE_EP_SHIFT 4 - -#define USB_TEST_EP_MASK 0x30 -#define USB_TEST_EP_SHIFT 4 - -#define USB_AGG_EN BIT(3) - -#define MAC_ADDR_LEN 6 -#define LAST_ENTRY_OF_TX_PKT_BUFFER 255 - -#define POLLING_LLT_THRESHOLD 20 -#define POLLING_READY_TIMEOUT_COUNT 1000 - -#define MAX_MSS_DENSITY_2T 0x13 -#define MAX_MSS_DENSITY_1T 0x0A - -#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6)) -#define EPROM_CMD_CONFIG 0x3 -#define EPROM_CMD_LOAD 1 - -#define HWSET_MAX_SIZE_92S HWSET_MAX_SIZE - -#define HAL_8192C_HW_GPIO_WPS_BIT BIT(2) - -#define RPMAC_RESET 0x100 -#define RPMAC_TXSTART 0x104 -#define RPMAC_TXLEGACYSIG 0x108 -#define RPMAC_TXHTSIG1 0x10c -#define RPMAC_TXHTSIG2 0x110 -#define RPMAC_PHYDEBUG 0x114 -#define RPMAC_TXPACKETNUM 0x118 -#define RPMAC_TXIDLE 0x11c -#define RPMAC_TXMACHEADER0 0x120 -#define RPMAC_TXMACHEADER1 0x124 -#define RPMAC_TXMACHEADER2 0x128 -#define RPMAC_TXMACHEADER3 0x12c -#define RPMAC_TXMACHEADER4 0x130 -#define RPMAC_TXMACHEADER5 0x134 -#define RPMAC_TXDADATYPE 0x138 -#define RPMAC_TXRANDOMSEED 0x13c -#define RPMAC_CCKPLCPPREAMBLE 0x140 -#define RPMAC_CCKPLCPHEADER 0x144 -#define RPMAC_CCKCRC16 0x148 -#define RPMAC_OFDMRXCRC32OK 0x170 -#define RPMAC_OFDMRXCRC32Er 0x174 -#define RPMAC_OFDMRXPARITYER 0x178 -#define RPMAC_OFDMRXCRC8ER 0x17c -#define RPMAC_CCKCRXRC16ER 0x180 -#define RPMAC_CCKCRXRC32ER 0x184 -#define RPMAC_CCKCRXRC32OK 0x188 -#define RPMAC_TXSTATUS 0x18c - -#define RFPGA0_RFMOD 0x800 - -#define RFPGA0_TXINFO 0x804 -#define RFPGA0_PSDFUNCTION 0x808 - -#define RFPGA0_TXGAINSTAGE 0x80c - -#define RFPGA0_RFTIMING1 0x810 -#define RFPGA0_RFTIMING2 0x814 - -#define RFPGA0_XA_HSSIPARAMETER1 0x820 -#define RFPGA0_XA_HSSIPARAMETER2 0x824 -#define RFPGA0_XB_HSSIPARAMETER1 0x828 -#define RFPGA0_XB_HSSIPARAMETER2 0x82c - -#define RFPGA0_XA_LSSIPARAMETER 0x840 -#define RFPGA0_XB_LSSIPARAMETER 0x844 - -#define RFPGA0_RFWAKEUPPARAMETER 0x850 -#define RFPGA0_RFSLEEPUPPARAMETER 0x854 - -#define RFPGA0_XAB_SWITCHCONTROL 0x858 -#define RFPGA0_XCD_SWITCHCONTROL 0x85c - -#define RFPGA0_XA_RFINTERFACEOE 0x860 -#define RFPGA0_XB_RFINTERFACEOE 0x864 - -#define RFPGA0_XAB_RFINTERFACESW 0x870 -#define RFPGA0_XCD_RFINTERFACESW 0x874 - -#define rFPGA0_XAB_RFPARAMETER 0x878 -#define rFPGA0_XCD_RFPARAMETER 0x87c - -#define RFPGA0_ANALOGPARAMETER1 0x880 -#define RFPGA0_ANALOGPARAMETER2 0x884 -#define RFPGA0_ANALOGPARAMETER3 0x888 -#define RFPGA0_ANALOGPARAMETER4 0x88c - -#define RFPGA0_XA_LSSIREADBACK 0x8a0 -#define RFPGA0_XB_LSSIREADBACK 0x8a4 -#define RFPGA0_XC_LSSIREADBACK 0x8a8 -#define RFPGA0_XD_LSSIREADBACK 0x8ac - -#define RFPGA0_PSDREPORT 0x8b4 -#define TRANSCEIVEA_HSPI_READBACK 0x8b8 -#define TRANSCEIVEB_HSPI_READBACK 0x8bc -#define RFPGA0_XAB_RFINTERFACERB 0x8e0 -#define RFPGA0_XCD_RFINTERFACERB 0x8e4 - -#define RFPGA1_RFMOD 0x900 - -#define RFPGA1_TXBLOCK 0x904 -#define RFPGA1_DEBUGSELECT 0x908 -#define RFPGA1_TXINFO 0x90c - -#define RCCK0_SYSTEM 0xa00 - -#define RCCK0_AFESETTING 0xa04 -#define RCCK0_CCA 0xa08 - -#define RCCK0_RXAGC1 0xa0c -#define RCCK0_RXAGC2 0xa10 - -#define RCCK0_RXHP 0xa14 - -#define RCCK0_DSPPARAMETER1 0xa18 -#define RCCK0_DSPPARAMETER2 0xa1c - -#define RCCK0_TXFILTER1 0xa20 -#define RCCK0_TXFILTER2 0xa24 -#define RCCK0_DEBUGPORT 0xa28 -#define RCCK0_FALSEALARMREPORT 0xa2c -#define RCCK0_TRSSIREPORT 0xa50 -#define RCCK0_RXREPORT 0xa54 -#define RCCK0_FACOUNTERLOWER 0xa5c -#define RCCK0_FACOUNTERUPPER 0xa58 - -#define ROFDM0_LSTF 0xc00 - -#define ROFDM0_TRXPATHENABLE 0xc04 -#define ROFDM0_TRMUXPAR 0xc08 -#define ROFDM0_TRSWISOLATION 0xc0c - -#define ROFDM0_XARXAFE 0xc10 -#define ROFDM0_XARXIQIMBALANCE 0xc14 -#define ROFDM0_XBRXAFE 0xc18 -#define ROFDM0_XBRXIQIMBALANCE 0xc1c -#define ROFDM0_XCRXAFE 0xc20 -#define ROFDM0_XCRXIQIMBANLANCE 0xc24 -#define ROFDM0_XDRXAFE 0xc28 -#define ROFDM0_XDRXIQIMBALANCE 0xc2c - -#define ROFDM0_RXDETECTOR1 0xc30 -#define ROFDM0_RXDETECTOR2 0xc34 -#define ROFDM0_RXDETECTOR3 0xc38 -#define ROFDM0_RXDETECTOR4 0xc3c - -#define ROFDM0_RXDSP 0xc40 -#define ROFDM0_CFOANDDAGC 0xc44 -#define ROFDM0_CCADROPTHRESHOLD 0xc48 -#define ROFDM0_ECCATHRESHOLD 0xc4c - -#define ROFDM0_XAAGCCORE1 0xc50 -#define ROFDM0_XAAGCCORE2 0xc54 -#define ROFDM0_XBAGCCORE1 0xc58 -#define ROFDM0_XBAGCCORE2 0xc5c -#define ROFDM0_XCAGCCORE1 0xc60 -#define ROFDM0_XCAGCCORE2 0xc64 -#define ROFDM0_XDAGCCORE1 0xc68 -#define ROFDM0_XDAGCCORE2 0xc6c - -#define ROFDM0_AGCPARAMETER1 0xc70 -#define ROFDM0_AGCPARAMETER2 0xc74 -#define ROFDM0_AGCRSSITABLE 0xc78 -#define ROFDM0_HTSTFAGC 0xc7c - -#define ROFDM0_XATXIQIMBALANCE 0xc80 -#define ROFDM0_XATXAFE 0xc84 -#define ROFDM0_XBTXIQIMBALANCE 0xc88 -#define ROFDM0_XBTXAFE 0xc8c -#define ROFDM0_XCTXIQIMBALANCE 0xc90 -#define ROFDM0_XCTXAFE 0xc94 -#define ROFDM0_XDTXIQIMBALANCE 0xc98 -#define ROFDM0_XDTXAFE 0xc9c - -#define ROFDM0_RXIQEXTANTA 0xca0 - -#define ROFDM0_RXHPPARAMETER 0xce0 -#define ROFDM0_TXPSEUDONOISEWGT 0xce4 -#define ROFDM0_FRAMESYNC 0xcf0 -#define ROFDM0_DFSREPORT 0xcf4 -#define ROFDM0_TXCOEFF1 0xca4 -#define ROFDM0_TXCOEFF2 0xca8 -#define ROFDM0_TXCOEFF3 0xcac -#define ROFDM0_TXCOEFF4 0xcb0 -#define ROFDM0_TXCOEFF5 0xcb4 -#define ROFDM0_TXCOEFF6 0xcb8 - -#define ROFDM1_LSTF 0xd00 -#define ROFDM1_TRXPATHENABLE 0xd04 - -#define ROFDM1_CF0 0xd08 -#define ROFDM1_CSI1 0xd10 -#define ROFDM1_SBD 0xd14 -#define ROFDM1_CSI2 0xd18 -#define ROFDM1_CFOTRACKING 0xd2c -#define ROFDM1_TRXMESAURE1 0xd34 -#define ROFDM1_INTFDET 0xd3c -#define ROFDM1_PSEUDONOISESTATEAB 0xd50 -#define ROFDM1_PSEUDONOISESTATECD 0xd54 -#define ROFDM1_RXPSEUDONOISEWGT 0xd58 - -#define ROFDM_PHYCOUNTER1 0xda0 -#define ROFDM_PHYCOUNTER2 0xda4 -#define ROFDM_PHYCOUNTER3 0xda8 - -#define ROFDM_SHORTCFOAB 0xdac -#define ROFDM_SHORTCFOCD 0xdb0 -#define ROFDM_LONGCFOAB 0xdb4 -#define ROFDM_LONGCFOCD 0xdb8 -#define ROFDM_TAILCF0AB 0xdbc -#define ROFDM_TAILCF0CD 0xdc0 -#define ROFDM_PWMEASURE1 0xdc4 -#define ROFDM_PWMEASURE2 0xdc8 -#define ROFDM_BWREPORT 0xdcc -#define ROFDM_AGCREPORT 0xdd0 -#define ROFDM_RXSNR 0xdd4 -#define ROFDM_RXEVMCSI 0xdd8 -#define ROFDM_SIGREPORT 0xddc - -#define RTXAGC_A_RATE18_06 0xe00 -#define RTXAGC_A_RATE54_24 0xe04 -#define RTXAGC_A_CCK1_MCS32 0xe08 -#define RTXAGC_A_MCS03_MCS00 0xe10 -#define RTXAGC_A_MCS07_MCS04 0xe14 -#define RTXAGC_A_MCS11_MCS08 0xe18 -#define RTXAGC_A_MCS15_MCS12 0xe1c - -#define RTXAGC_B_RATE18_06 0x830 -#define RTXAGC_B_RATE54_24 0x834 -#define RTXAGC_B_CCK1_55_MCS32 0x838 -#define RTXAGC_B_MCS03_MCS00 0x83c -#define RTXAGC_B_MCS07_MCS04 0x848 -#define RTXAGC_B_MCS11_MCS08 0x84c -#define RTXAGC_B_MCS15_MCS12 0x868 -#define RTXAGC_B_CCK11_A_CCK2_11 0x86c - -#define RZEBRA1_HSSIENABLE 0x0 -#define RZEBRA1_TRXENABLE1 0x1 -#define RZEBRA1_TRXENABLE2 0x2 -#define RZEBRA1_AGC 0x4 -#define RZEBRA1_CHARGEPUMP 0x5 -#define RZEBRA1_CHANNEL 0x7 - -#define RZEBRA1_TXGAIN 0x8 -#define RZEBRA1_TXLPF 0x9 -#define RZEBRA1_RXLPF 0xb -#define RZEBRA1_RXHPFCORNER 0xc - -#define RGLOBALCTRL 0 -#define RRTL8256_TXLPF 19 -#define RRTL8256_RXLPF 11 -#define RRTL8258_TXLPF 0x11 -#define RRTL8258_RXLPF 0x13 -#define RRTL8258_RSSILPF 0xa - -#define RF_AC 0x00 - -#define RF_IQADJ_G1 0x01 -#define RF_IQADJ_G2 0x02 -#define RF_POW_TRSW 0x05 - -#define RF_GAIN_RX 0x06 -#define RF_GAIN_TX 0x07 - -#define RF_TXM_IDAC 0x08 -#define RF_BS_IQGEN 0x0F - -#define RF_MODE1 0x10 -#define RF_MODE2 0x11 - -#define RF_RX_AGC_HP 0x12 -#define RF_TX_AGC 0x13 -#define RF_BIAS 0x14 -#define RF_IPA 0x15 -#define RF_POW_ABILITY 0x17 -#define RF_MODE_AG 0x18 -#define RRFCHANNEL 0x18 -#define RF_CHNLBW 0x18 -#define RF_TOP 0x19 - -#define RF_RX_G1 0x1A -#define RF_RX_G2 0x1B - -#define RF_RX_BB2 0x1C -#define RF_RX_BB1 0x1D - -#define RF_RCK1 0x1E -#define RF_RCK2 0x1F - -#define RF_TX_G1 0x20 -#define RF_TX_G2 0x21 -#define RF_TX_G3 0x22 - -#define RF_TX_BB1 0x23 -#define RF_T_METER 0x24 - -#define RF_SYN_G1 0x25 -#define RF_SYN_G2 0x26 -#define RF_SYN_G3 0x27 -#define RF_SYN_G4 0x28 -#define RF_SYN_G5 0x29 -#define RF_SYN_G6 0x2A -#define RF_SYN_G7 0x2B -#define RF_SYN_G8 0x2C - -#define RF_RCK_OS 0x30 -#define RF_TXPA_G1 0x31 -#define RF_TXPA_G2 0x32 -#define RF_TXPA_G3 0x33 - -#define BBBRESETB 0x100 -#define BGLOBALRESETB 0x200 -#define BOFDMTXSTART 0x4 -#define BCCKTXSTART 0x8 -#define BCRC32DEBUG 0x100 -#define BPMACLOOPBACK 0x10 -#define BTXLSIG 0xffffff -#define BOFDMTXRATE 0xf -#define BOFDMTXRESERVED 0x10 -#define BOFDMTXLENGTH 0x1ffe0 -#define BOFDMTXPARITY 0x20000 -#define BTXHTSIG1 0xffffff -#define BTXHTMCSRATE 0x7f -#define BTXHTBW 0x80 -#define BTXHTLENGTH 0xffff00 -#define BTXHTSIG2 0xffffff -#define BTXHTSMOOTHING 0x1 -#define BTXHTSOUNDING 0x2 -#define BTXHTRESERVED 0x4 -#define BTXHTAGGREATION 0x8 -#define BTXHTSTBC 0x30 -#define BTXHTADVANCECODING 0x40 -#define BTXHTSHORTGI 0x80 -#define BTXHTNUMBERHT_LTF 0x300 -#define BTXHTCRC8 0x3fc00 -#define BCOUNTERRESET 0x10000 -#define BNUMOFOFDMTX 0xffff -#define BNUMOFCCKTX 0xffff0000 -#define BTXIDLEINTERVAL 0xffff -#define BOFDMSERVICE 0xffff0000 -#define BTXMACHEADER 0xffffffff -#define BTXDATAINIT 0xff -#define BTXHTMODE 0x100 -#define BTXDATATYPE 0x30000 -#define BTXRANDOMSEED 0xffffffff -#define BCCKTXPREAMBLE 0x1 -#define BCCKTXSFD 0xffff0000 -#define BCCKTXSIG 0xff -#define BCCKTXSERVICE 0xff00 -#define BCCKLENGTHEXT 0x8000 -#define BCCKTXLENGHT 0xffff0000 -#define BCCKTXCRC16 0xffff -#define BCCKTXSTATUS 0x1 -#define BOFDMTXSTATUS 0x2 -#define IS_BB_REG_OFFSET_92S(_Offset) \ - ((_Offset >= 0x800) && (_Offset <= 0xfff)) - -#define BRFMOD 0x1 -#define BJAPANMODE 0x2 -#define BCCKTXSC 0x30 -#define BCCKEN 0x1000000 -#define BOFDMEN 0x2000000 - -#define BOFDMRXADCPHASE 0x10000 -#define BOFDMTXDACPHASE 0x40000 -#define BXATXAGC 0x3f - -#define BXBTXAGC 0xf00 -#define BXCTXAGC 0xf000 -#define BXDTXAGC 0xf0000 - -#define BPASTART 0xf0000000 -#define BTRSTART 0x00f00000 -#define BRFSTART 0x0000f000 -#define BBBSTART 0x000000f0 -#define BBBCCKSTART 0x0000000f -#define BPAEND 0xf -#define BTREND 0x0f000000 -#define BRFEND 0x000f0000 -#define BCCAMASK 0x000000f0 -#define BR2RCCAMASK 0x00000f00 -#define BHSSI_R2TDELAY 0xf8000000 -#define BHSSI_T2RDELAY 0xf80000 -#define BCONTXHSSI 0x400 -#define BIGFROMCCK 0x200 -#define BAGCADDRESS 0x3f -#define BRXHPTX 0x7000 -#define BRXHP2RX 0x38000 -#define BRXHPCCKINI 0xc0000 -#define BAGCTXCODE 0xc00000 -#define BAGCRXCODE 0x300000 - -#define B3WIREDATALENGTH 0x800 -#define B3WIREADDREAALENGTH 0x400 - -#define B3WIRERFPOWERDOWN 0x1 -#define B5GPAPEPOLARITY 0x40000000 -#define B2GPAPEPOLARITY 0x80000000 -#define BRFSW_TXDEFAULTANT 0x3 -#define BRFSW_TXOPTIONANT 0x30 -#define BRFSW_RXDEFAULTANT 0x300 -#define BRFSW_RXOPTIONANT 0x3000 -#define BRFSI_3WIREDATA 0x1 -#define BRFSI_3WIRECLOCK 0x2 -#define BRFSI_3WIRELOAD 0x4 -#define BRFSI_3WIRERW 0x8 -#define BRFSI_3WIRE 0xf - -#define BRFSI_RFENV 0x10 - -#define BRFSI_TRSW 0x20 -#define BRFSI_TRSWB 0x40 -#define BRFSI_ANTSW 0x100 -#define BRFSI_ANTSWB 0x200 -#define BRFSI_PAPE 0x400 -#define BRFSI_PAPE5G 0x800 -#define BBANDSELECT 0x1 -#define BHTSIG2_GI 0x80 -#define BHTSIG2_SMOOTHING 0x01 -#define BHTSIG2_SOUNDING 0x02 -#define BHTSIG2_AGGREATON 0x08 -#define BHTSIG2_STBC 0x30 -#define BHTSIG2_ADVCODING 0x40 -#define BHTSIG2_NUMOFHTLTF 0x300 -#define BHTSIG2_CRC8 0x3fc -#define BHTSIG1_MCS 0x7f -#define BHTSIG1_BANDWIDTH 0x80 -#define BHTSIG1_HTLENGTH 0xffff -#define BLSIG_RATE 0xf -#define BLSIG_RESERVED 0x10 -#define BLSIG_LENGTH 0x1fffe -#define BLSIG_PARITY 0x20 -#define BCCKRXPHASE 0x4 - -#define BLSSIREADADDRESS 0x7f800000 -#define BLSSIREADEDGE 0x80000000 - -#define BLSSIREADBACKDATA 0xfffff - -#define BLSSIREADOKFLAG 0x1000 -#define BCCKSAMPLERATE 0x8 -#define BREGULATOR0STANDBY 0x1 -#define BREGULATORPLLSTANDBY 0x2 -#define BREGULATOR1STANDBY 0x4 -#define BPLLPOWERUP 0x8 -#define BDPLLPOWERUP 0x10 -#define BDA10POWERUP 0x20 -#define BAD7POWERUP 0x200 -#define BDA6POWERUP 0x2000 -#define BXTALPOWERUP 0x4000 -#define B40MDCLKPOWERUP 0x8000 -#define BDA6DEBUGMODE 0x20000 -#define BDA6SWING 0x380000 - -#define BADCLKPHASE 0x4000000 -#define B80MCLKDELAY 0x18000000 -#define BAFEWATCHDOGENABLE 0x20000000 - -#define BXTALCAP01 0xc0000000 -#define BXTALCAP23 0x3 -#define BXTALCAP92X 0x0f000000 -#define BXTALCAP 0x0f000000 - -#define BINTDIFCLKENABLE 0x400 -#define BEXTSIGCLKENABLE 0x800 -#define BBANDGAP_MBIAS_POWERUP 0x10000 -#define BAD11SH_GAIN 0xc0000 -#define BAD11NPUT_RANGE 0x700000 -#define BAD110P_CURRENT 0x3800000 -#define BLPATH_LOOPBACK 0x4000000 -#define BQPATH_LOOPBACK 0x8000000 -#define BAFE_LOOPBACK 0x10000000 -#define BDA10_SWING 0x7e0 -#define BDA10_REVERSE 0x800 -#define BDA_CLK_SOURCE 0x1000 -#define BDA7INPUT_RANGE 0x6000 -#define BDA7_GAIN 0x38000 -#define BDA7OUTPUT_CM_MODE 0x40000 -#define BDA7INPUT_CM_MODE 0x380000 -#define BDA7CURRENT 0xc00000 -#define BREGULATOR_ADJUST 0x7000000 -#define BAD11POWERUP_ATTX 0x1 -#define BDA10PS_ATTX 0x10 -#define BAD11POWERUP_ATRX 0x100 -#define BDA10PS_ATRX 0x1000 -#define BCCKRX_AGC_FORMAT 0x200 -#define BPSDFFT_SAMPLE_POINT 0xc000 -#define BPSD_AVERAGE_NUM 0x3000 -#define BIQPATH_CONTROL 0xc00 -#define BPSD_FREQ 0x3ff -#define BPSD_ANTENNA_PATH 0x30 -#define BPSD_IQ_SWITCH 0x40 -#define BPSD_RX_TRIGGER 0x400000 -#define BPSD_TX_TRIGGER 0x80000000 -#define BPSD_SINE_TONE_SCALE 0x7f000000 -#define BPSD_REPORT 0xffff - -#define BOFDM_TXSC 0x30000000 -#define BCCK_TXON 0x1 -#define BOFDM_TXON 0x2 -#define BDEBUG_PAGE 0xfff -#define BDEBUG_ITEM 0xff -#define BANTL 0x10 -#define BANT_NONHT 0x100 -#define BANT_HT1 0x1000 -#define BANT_HT2 0x10000 -#define BANT_HT1S1 0x100000 -#define BANT_NONHTS1 0x1000000 - -#define BCCK_BBMODE 0x3 -#define BCCK_TXPOWERSAVING 0x80 -#define BCCK_RXPOWERSAVING 0x40 - -#define BCCK_SIDEBAND 0x10 - -#define BCCK_SCRAMBLE 0x8 -#define BCCK_ANTDIVERSITY 0x8000 -#define BCCK_CARRIER_RECOVERY 0x4000 -#define BCCK_TXRATE 0x3000 -#define BCCK_DCCANCEL 0x0800 -#define BCCK_ISICANCEL 0x0400 -#define BCCK_MATCH_FILTER 0x0200 -#define BCCK_EQUALIZER 0x0100 -#define BCCK_PREAMBLE_DETECT 0x800000 -#define BCCK_FAST_FALSECCAi 0x400000 -#define BCCK_CH_ESTSTARTi 0x300000 -#define BCCK_CCA_COUNTi 0x080000 -#define BCCK_CS_LIM 0x070000 -#define BCCK_BIST_MODEi 0x80000000 -#define BCCK_CCAMASK 0x40000000 -#define BCCK_TX_DAC_PHASE 0x4 -#define BCCK_RX_ADC_PHASE 0x20000000 -#define BCCKR_CP_MODE 0x0100 -#define BCCK_TXDC_OFFSET 0xf0 -#define BCCK_RXDC_OFFSET 0xf -#define BCCK_CCA_MODE 0xc000 -#define BCCK_FALSECS_LIM 0x3f00 -#define BCCK_CS_RATIO 0xc00000 -#define BCCK_CORGBIT_SEL 0x300000 -#define BCCK_PD_LIM 0x0f0000 -#define BCCK_NEWCCA 0x80000000 -#define BCCK_RXHP_OF_IG 0x8000 -#define BCCK_RXIG 0x7f00 -#define BCCK_LNA_POLARITY 0x800000 -#define BCCK_RX1ST_BAIN 0x7f0000 -#define BCCK_RF_EXTEND 0x20000000 -#define BCCK_RXAGC_SATLEVEL 0x1f000000 -#define BCCK_RXAGC_SATCOUNT 0xe0 -#define bCCKRxRFSettle 0x1f -#define BCCK_FIXED_RXAGC 0x8000 -#define BCCK_ANTENNA_POLARITY 0x2000 -#define BCCK_TXFILTER_TYPE 0x0c00 -#define BCCK_RXAGC_REPORTTYPE 0x0300 -#define BCCK_RXDAGC_EN 0x80000000 -#define BCCK_RXDAGC_PERIOD 0x20000000 -#define BCCK_RXDAGC_SATLEVEL 0x1f000000 -#define BCCK_TIMING_RECOVERY 0x800000 -#define BCCK_TXC0 0x3f0000 -#define BCCK_TXC1 0x3f000000 -#define BCCK_TXC2 0x3f -#define BCCK_TXC3 0x3f00 -#define BCCK_TXC4 0x3f0000 -#define BCCK_TXC5 0x3f000000 -#define BCCK_TXC6 0x3f -#define BCCK_TXC7 0x3f00 -#define BCCK_DEBUGPORT 0xff0000 -#define BCCK_DAC_DEBUG 0x0f000000 -#define BCCK_FALSEALARM_ENABLE 0x8000 -#define BCCK_FALSEALARM_READ 0x4000 -#define BCCK_TRSSI 0x7f -#define BCCK_RXAGC_REPORT 0xfe -#define BCCK_RXREPORT_ANTSEL 0x80000000 -#define BCCK_RXREPORT_MFOFF 0x40000000 -#define BCCK_RXREPORT_SQLOSS 0x20000000 -#define BCCK_RXREPORT_PKTLOSS 0x10000000 -#define BCCK_RXREPORT_LOCKEDBIT 0x08000000 -#define BCCK_RXREPORT_RATEERROR 0x04000000 -#define BCCK_RXREPORT_RXRATE 0x03000000 -#define BCCK_RXFA_COUNTER_LOWER 0xff -#define BCCK_RXFA_COUNTER_UPPER 0xff000000 -#define BCCK_RXHPAGC_START 0xe000 -#define BCCK_RXHPAGC_FINAL 0x1c00 -#define BCCK_RXFALSEALARM_ENABLE 0x8000 -#define BCCK_FACOUNTER_FREEZE 0x4000 -#define BCCK_TXPATH_SEL 0x10000000 -#define BCCK_DEFAULT_RXPATH 0xc000000 -#define BCCK_OPTION_RXPATH 0x3000000 - -#define BNUM_OFSTF 0x3 -#define BSHIFT_L 0xc0 -#define BGI_TH 0xc -#define BRXPATH_A 0x1 -#define BRXPATH_B 0x2 -#define BRXPATH_C 0x4 -#define BRXPATH_D 0x8 -#define BTXPATH_A 0x1 -#define BTXPATH_B 0x2 -#define BTXPATH_C 0x4 -#define BTXPATH_D 0x8 -#define BTRSSI_FREQ 0x200 -#define BADC_BACKOFF 0x3000 -#define BDFIR_BACKOFF 0xc000 -#define BTRSSI_LATCH_PHASE 0x10000 -#define BRX_LDC_OFFSET 0xff -#define BRX_QDC_OFFSET 0xff00 -#define BRX_DFIR_MODE 0x1800000 -#define BRX_DCNF_TYPE 0xe000000 -#define BRXIQIMB_A 0x3ff -#define BRXIQIMB_B 0xfc00 -#define BRXIQIMB_C 0x3f0000 -#define BRXIQIMB_D 0xffc00000 -#define BDC_DC_NOTCH 0x60000 -#define BRXNB_NOTCH 0x1f000000 -#define BPD_TH 0xf -#define BPD_TH_OPT2 0xc000 -#define BPWED_TH 0x700 -#define BIFMF_WIN_L 0x800 -#define BPD_OPTION 0x1000 -#define BMF_WIN_L 0xe000 -#define BBW_SEARCH_L 0x30000 -#define BWIN_ENH_L 0xc0000 -#define BBW_TH 0x700000 -#define BED_TH2 0x3800000 -#define BBW_OPTION 0x4000000 -#define BRADIO_TH 0x18000000 -#define BWINDOW_L 0xe0000000 -#define BSBD_OPTION 0x1 -#define BFRAME_TH 0x1c -#define BFS_OPTION 0x60 -#define BDC_SLOPE_CHECK 0x80 -#define BFGUARD_COUNTER_DC_L 0xe00 -#define BFRAME_WEIGHT_SHORT 0x7000 -#define BSUB_TUNE 0xe00000 -#define BFRAME_DC_LENGTH 0xe000000 -#define BSBD_START_OFFSET 0x30000000 -#define BFRAME_TH_2 0x7 -#define BFRAME_GI2_TH 0x38 -#define BGI2_SYNC_EN 0x40 -#define BSARCH_SHORT_EARLY 0x300 -#define BSARCH_SHORT_LATE 0xc00 -#define BSARCH_GI2_LATE 0x70000 -#define BCFOANTSUM 0x1 -#define BCFOACC 0x2 -#define BCFOSTARTOFFSET 0xc -#define BCFOLOOPBACK 0x70 -#define BCFOSUMWEIGHT 0x80 -#define BDAGCENABLE 0x10000 -#define BTXIQIMB_A 0x3ff -#define BTXIQIMB_b 0xfc00 -#define BTXIQIMB_C 0x3f0000 -#define BTXIQIMB_D 0xffc00000 -#define BTXIDCOFFSET 0xff -#define BTXIQDCOFFSET 0xff00 -#define BTXDFIRMODE 0x10000 -#define BTXPESUDO_NOISEON 0x4000000 -#define BTXPESUDO_NOISE_A 0xff -#define BTXPESUDO_NOISE_B 0xff00 -#define BTXPESUDO_NOISE_C 0xff0000 -#define BTXPESUDO_NOISE_D 0xff000000 -#define BCCA_DROPOPTION 0x20000 -#define BCCA_DROPTHRES 0xfff00000 -#define BEDCCA_H 0xf -#define BEDCCA_L 0xf0 -#define BLAMBDA_ED 0x300 -#define BRX_INITIALGAIN 0x7f -#define BRX_ANTDIV_EN 0x80 -#define BRX_AGC_ADDRESS_FOR_LNA 0x7f00 -#define BRX_HIGHPOWER_FLOW 0x8000 -#define BRX_AGC_FREEZE_THRES 0xc0000 -#define BRX_FREEZESTEP_AGC1 0x300000 -#define BRX_FREEZESTEP_AGC2 0xc00000 -#define BRX_FREEZESTEP_AGC3 0x3000000 -#define BRX_FREEZESTEP_AGC0 0xc000000 -#define BRXRSSI_CMP_EN 0x10000000 -#define BRXQUICK_AGCEN 0x20000000 -#define BRXAGC_FREEZE_THRES_MODE 0x40000000 -#define BRX_OVERFLOW_CHECKTYPE 0x80000000 -#define BRX_AGCSHIFT 0x7f -#define BTRSW_TRI_ONLY 0x80 -#define BPOWER_THRES 0x300 -#define BRXAGC_EN 0x1 -#define BRXAGC_TOGETHER_EN 0x2 -#define BRXAGC_MIN 0x4 -#define BRXHP_INI 0x7 -#define BRXHP_TRLNA 0x70 -#define BRXHP_RSSI 0x700 -#define BRXHP_BBP1 0x7000 -#define BRXHP_BBP2 0x70000 -#define BRXHP_BBP3 0x700000 -#define BRSSI_H 0x7f0000 -#define BRSSI_GEN 0x7f000000 -#define BRXSETTLE_TRSW 0x7 -#define BRXSETTLE_LNA 0x38 -#define BRXSETTLE_RSSI 0x1c0 -#define BRXSETTLE_BBP 0xe00 -#define BRXSETTLE_RXHP 0x7000 -#define BRXSETTLE_ANTSW_RSSI 0x38000 -#define BRXSETTLE_ANTSW 0xc0000 -#define BRXPROCESS_TIME_DAGC 0x300000 -#define BRXSETTLE_HSSI 0x400000 -#define BRXPROCESS_TIME_BBPPW 0x800000 -#define BRXANTENNA_POWER_SHIFT 0x3000000 -#define BRSSI_TABLE_SELECT 0xc000000 -#define BRXHP_FINAL 0x7000000 -#define BRXHPSETTLE_BBP 0x7 -#define BRXHTSETTLE_HSSI 0x8 -#define BRXHTSETTLE_RXHP 0x70 -#define BRXHTSETTLE_BBPPW 0x80 -#define BRXHTSETTLE_IDLE 0x300 -#define BRXHTSETTLE_RESERVED 0x1c00 -#define BRXHT_RXHP_EN 0x8000 -#define BRXAGC_FREEZE_THRES 0x30000 -#define BRXAGC_TOGETHEREN 0x40000 -#define BRXHTAGC_MIN 0x80000 -#define BRXHTAGC_EN 0x100000 -#define BRXHTDAGC_EN 0x200000 -#define BRXHT_RXHP_BBP 0x1c00000 -#define BRXHT_RXHP_FINAL 0xe0000000 -#define BRXPW_RADIO_TH 0x3 -#define BRXPW_RADIO_EN 0x4 -#define BRXMF_HOLD 0x3800 -#define BRXPD_DELAY_TH1 0x38 -#define BRXPD_DELAY_TH2 0x1c0 -#define BRXPD_DC_COUNT_MAX 0x600 -#define BRXPD_DELAY_TH 0x8000 -#define BRXPROCESS_DELAY 0xf0000 -#define BRXSEARCHRANGE_GI2_EARLY 0x700000 -#define BRXFRAME_FUARD_COUNTER_L 0x3800000 -#define BRXSGI_GUARD_L 0xc000000 -#define BRXSGI_SEARCH_L 0x30000000 -#define BRXSGI_TH 0xc0000000 -#define BDFSCNT0 0xff -#define BDFSCNT1 0xff00 -#define BDFSFLAG 0xf0000 -#define BMF_WEIGHT_SUM 0x300000 -#define BMINIDX_TH 0x7f000000 -#define BDAFORMAT 0x40000 -#define BTXCH_EMU_ENABLE 0x01000000 -#define BTRSW_ISOLATION_A 0x7f -#define BTRSW_ISOLATION_B 0x7f00 -#define BTRSW_ISOLATION_C 0x7f0000 -#define BTRSW_ISOLATION_D 0x7f000000 -#define BEXT_LNA_GAIN 0x7c00 - -#define BSTBC_EN 0x4 -#define BANTENNA_MAPPING 0x10 -#define BNSS 0x20 -#define BCFO_ANTSUM_ID 0x200 -#define BPHY_COUNTER_RESET 0x8000000 -#define BCFO_REPORT_GET 0x4000000 -#define BOFDM_CONTINUE_TX 0x10000000 -#define BOFDM_SINGLE_CARRIER 0x20000000 -#define BOFDM_SINGLE_TONE 0x40000000 -#define BHT_DETECT 0x100 -#define BCFOEN 0x10000 -#define BCFOVALUE 0xfff00000 -#define BSIGTONE_RE 0x3f -#define BSIGTONE_IM 0x7f00 -#define BCOUNTER_CCA 0xffff -#define BCOUNTER_PARITYFAIL 0xffff0000 -#define BCOUNTER_RATEILLEGAL 0xffff -#define BCOUNTER_CRC8FAIL 0xffff0000 -#define BCOUNTER_MCSNOSUPPORT 0xffff -#define BCOUNTER_FASTSYNC 0xffff -#define BSHORTCFO 0xfff -#define BSHORTCFOT_LENGTH 12 -#define BSHORTCFOF_LENGTH 11 -#define BLONGCFO 0x7ff -#define BLONGCFOT_LENGTH 11 -#define BLONGCFOF_LENGTH 11 -#define BTAILCFO 0x1fff -#define BTAILCFOT_LENGTH 13 -#define BTAILCFOF_LENGTH 12 -#define BNOISE_EN_PWDB 0xffff -#define BCC_POWER_DB 0xffff0000 -#define BMOISE_PWDB 0xffff -#define BPOWERMEAST_LENGTH 10 -#define BPOWERMEASF_LENGTH 3 -#define BRX_HT_BW 0x1 -#define BRXSC 0x6 -#define BRX_HT 0x8 -#define BNB_INTF_DET_ON 0x1 -#define BINTF_WIN_LEN_CFG 0x30 -#define BNB_INTF_TH_CFG 0x1c0 -#define BRFGAIN 0x3f -#define BTABLESEL 0x40 -#define BTRSW 0x80 -#define BRXSNR_A 0xff -#define BRXSNR_B 0xff00 -#define BRXSNR_C 0xff0000 -#define BRXSNR_D 0xff000000 -#define BSNR_EVMT_LENGTH 8 -#define BSNR_EVMF_LENGTH 1 -#define BCSI1ST 0xff -#define BCSI2ND 0xff00 -#define BRXEVM1ST 0xff0000 -#define BRXEVM2ND 0xff000000 -#define BSIGEVM 0xff -#define BPWDB 0xff00 -#define BSGIEN 0x10000 - -#define BSFACTOR_QMA1 0xf -#define BSFACTOR_QMA2 0xf0 -#define BSFACTOR_QMA3 0xf00 -#define BSFACTOR_QMA4 0xf000 -#define BSFACTOR_QMA5 0xf0000 -#define BSFACTOR_QMA6 0xf0000 -#define BSFACTOR_QMA7 0xf00000 -#define BSFACTOR_QMA8 0xf000000 -#define BSFACTOR_QMA9 0xf0000000 -#define BCSI_SCHEME 0x100000 - -#define BNOISE_LVL_TOP_SET 0x3 -#define BCHSMOOTH 0x4 -#define BCHSMOOTH_CFG1 0x38 -#define BCHSMOOTH_CFG2 0x1c0 -#define BCHSMOOTH_CFG3 0xe00 -#define BCHSMOOTH_CFG4 0x7000 -#define BMRCMODE 0x800000 -#define BTHEVMCFG 0x7000000 - -#define BLOOP_FIT_TYPE 0x1 -#define BUPD_CFO 0x40 -#define BUPD_CFO_OFFDATA 0x80 -#define BADV_UPD_CFO 0x100 -#define BADV_TIME_CTRL 0x800 -#define BUPD_CLKO 0x1000 -#define BFC 0x6000 -#define BTRACKING_MODE 0x8000 -#define BPHCMP_ENABLE 0x10000 -#define BUPD_CLKO_LTF 0x20000 -#define BCOM_CH_CFO 0x40000 -#define BCSI_ESTI_MODE 0x80000 -#define BADV_UPD_EQZ 0x100000 -#define BUCHCFG 0x7000000 -#define BUPDEQZ 0x8000000 - -#define BRX_PESUDO_NOISE_ON 0x20000000 -#define BRX_PESUDO_NOISE_A 0xff -#define BRX_PESUDO_NOISE_B 0xff00 -#define BRX_PESUDO_NOISE_C 0xff0000 -#define BRX_PESUDO_NOISE_D 0xff000000 -#define BRX_PESUDO_NOISESTATE_A 0xffff -#define BRX_PESUDO_NOISESTATE_B 0xffff0000 -#define BRX_PESUDO_NOISESTATE_C 0xffff -#define BRX_PESUDO_NOISESTATE_D 0xffff0000 - -#define BZEBRA1_HSSIENABLE 0x8 -#define BZEBRA1_TRXCONTROL 0xc00 -#define BZEBRA1_TRXGAINSETTING 0x07f -#define BZEBRA1_RXCOUNTER 0xc00 -#define BZEBRA1_TXCHANGEPUMP 0x38 -#define BZEBRA1_RXCHANGEPUMP 0x7 -#define BZEBRA1_CHANNEL_NUM 0xf80 -#define BZEBRA1_TXLPFBW 0x400 -#define BZEBRA1_RXLPFBW 0x600 - -#define BRTL8256REG_MODE_CTRL1 0x100 -#define BRTL8256REG_MODE_CTRL0 0x40 -#define BRTL8256REG_TXLPFBW 0x18 -#define BRTL8256REG_RXLPFBW 0x600 - -#define BRTL8258_TXLPFBW 0xc -#define BRTL8258_RXLPFBW 0xc00 -#define BRTL8258_RSSILPFBW 0xc0 - -#define BBYTE0 0x1 -#define BBYTE1 0x2 -#define BBYTE2 0x4 -#define BBYTE3 0x8 -#define BWORD0 0x3 -#define BWORD1 0xc -#define BWORD 0xf - -#define MASKBYTE0 0xff -#define MASKBYTE1 0xff00 -#define MASKBYTE2 0xff0000 -#define MASKBYTE3 0xff000000 -#define MASKHWORD 0xffff0000 -#define MASKLWORD 0x0000ffff -#define MASKDWORD 0xffffffff -#define MASK12BITS 0xfff -#define MASKH4BITS 0xf0000000 -#define MASKOFDM_D 0xffc00000 -#define MASKCCK 0x3f3f3f3f - -#define MASK4BITS 0x0f -#define MASK20BITS 0xfffff -#define RFREG_OFFSET_MASK 0xfffff - -#define BENABLE 0x1 -#define BDISABLE 0x0 - -#define LEFT_ANTENNA 0x0 -#define RIGHT_ANTENNA 0x1 - -#define TCHECK_TXSTATUS 500 -#define TUPDATE_RXCOUNTER 100 - -/* 2 EFUSE_TEST (For RTL8723 partially) */ -#define EFUSE_SEL(x) (((x) & 0x3) << 8) -#define EFUSE_SEL_MASK 0x300 -#define EFUSE_WIFI_SEL_0 0x0 - -/* Enable GPIO[9] as WiFi HW PDn source*/ -#define WL_HWPDN_EN BIT(0) -/* WiFi HW PDn polarity control*/ -#define WL_HWPDN_SL BIT(1) - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/rf.c b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/rf.c deleted file mode 100644 index 50dd2fb2c93d..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/rf.c +++ /dev/null @@ -1,505 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#include "../wifi.h" -#include "reg.h" -#include "def.h" -#include "phy.h" -#include "rf.h" -#include "dm.h" - -void rtl8723ae_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - switch (bandwidth) { - case HT_CHANNEL_WIDTH_20: - rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & - 0xfffff3ff) | 0x0400); - rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, - rtlphy->rfreg_chnlval[0]); - break; - case HT_CHANNEL_WIDTH_20_40: - rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & - 0xfffff3ff)); - rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, - rtlphy->rfreg_chnlval[0]); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "unknown bandwidth: %#X\n", bandwidth); - break; - } -} - -void rtl8723ae_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, - u8 *ppowerlevel) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u32 tx_agc[2] = {0, 0}, tmpval; - bool turbo_scanoff = false; - u8 idx1, idx2; - u8 *ptr; - - if (rtlefuse->eeprom_regulatory != 0) - turbo_scanoff = true; - - if (mac->act_scanning == true) { - tx_agc[RF90_PATH_A] = 0x3f3f3f3f; - tx_agc[RF90_PATH_B] = 0x3f3f3f3f; - - if (turbo_scanoff) { - for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { - tx_agc[idx1] = ppowerlevel[idx1] | - (ppowerlevel[idx1] << 8) | - (ppowerlevel[idx1] << 16) | - (ppowerlevel[idx1] << 24); - } - } - } else { - for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { - tx_agc[idx1] = ppowerlevel[idx1] | - (ppowerlevel[idx1] << 8) | - (ppowerlevel[idx1] << 16) | - (ppowerlevel[idx1] << 24); - } - - if (rtlefuse->eeprom_regulatory == 0) { - tmpval = (rtlphy->mcs_offset[0][6]) + - (rtlphy->mcs_offset[0][7] << 8); - tx_agc[RF90_PATH_A] += tmpval; - - tmpval = (rtlphy->mcs_offset[0][14]) + - (rtlphy->mcs_offset[0][15] << 24); - tx_agc[RF90_PATH_B] += tmpval; - } - } - - for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) { - ptr = (u8 *) (&(tx_agc[idx1])); - for (idx2 = 0; idx2 < 4; idx2++) { - if (*ptr > RF6052_MAX_TX_PWR) - *ptr = RF6052_MAX_TX_PWR; - ptr++; - } - } - - tmpval = tx_agc[RF90_PATH_A] & 0xff; - rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_A_CCK1_MCS32); - - tmpval = tx_agc[RF90_PATH_A] >> 8; - - tmpval = tmpval & 0xff00ffff; - - rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK11_A_CCK2_11); - - tmpval = tx_agc[RF90_PATH_B] >> 24; - rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK11_A_CCK2_11); - - tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff; - rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - "CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK1_55_MCS32); -} - -static void rtl8723ae_phy_get_power_base(struct ieee80211_hw *hw, - u8 *ppowerlevel, u8 channel, - u32 *ofdmbase, u32 *mcsbase) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u32 powerBase0, powerBase1; - u8 legacy_pwrdiff, ht20_pwrdiff; - u8 i, powerlevel[2]; - - for (i = 0; i < 2; i++) { - powerlevel[i] = ppowerlevel[i]; - legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff[i][channel - 1]; - powerBase0 = powerlevel[i] + legacy_pwrdiff; - - powerBase0 = (powerBase0 << 24) | (powerBase0 << 16) | - (powerBase0 << 8) | powerBase0; - *(ofdmbase + i) = powerBase0; - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - " [OFDM power base index rf(%c) = 0x%x]\n", - ((i == 0) ? 'A' : 'B'), *(ofdmbase + i)); - } - - for (i = 0; i < 2; i++) { - if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) { - ht20_pwrdiff = rtlefuse->txpwr_ht20diff[i][channel - 1]; - powerlevel[i] += ht20_pwrdiff; - } - powerBase1 = powerlevel[i]; - powerBase1 = (powerBase1 << 24) | - (powerBase1 << 16) | (powerBase1 << 8) | powerBase1; - - *(mcsbase + i) = powerBase1; - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - " [MCS power base index rf(%c) = 0x%x]\n", - ((i == 0) ? 'A' : 'B'), *(mcsbase + i)); - } -} - -static void rtl8723ae_get_txpwr_val_by_reg(struct ieee80211_hw *hw, - u8 channel, u8 index, - u32 *powerBase0, - u32 *powerBase1, - u32 *p_outwriteval) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u8 i, chnlgroup = 0, pwr_diff_limit[4]; - u32 writeVal, customer_limit, rf; - - for (rf = 0; rf < 2; rf++) { - switch (rtlefuse->eeprom_regulatory) { - case 0: - chnlgroup = 0; - - writeVal = rtlphy->mcs_offset[chnlgroup] - [index + (rf ? 8 : 0)] + - ((index < 2) ? powerBase0[rf] : - powerBase1[rf]); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - "RTK better performance, " - "writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal); - break; - case 1: - if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { - writeVal = ((index < 2) ? powerBase0[rf] : - powerBase1[rf]); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - "Realtek regulatory, 40MHz, " - "writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal); - } else { - if (rtlphy->pwrgroup_cnt == 1) - chnlgroup = 0; - if (rtlphy->pwrgroup_cnt >= 3) { - if (channel <= 3) - chnlgroup = 0; - else if (channel >= 4 && channel <= 9) - chnlgroup = 1; - else if (channel > 9) - chnlgroup = 2; - if (rtlphy->current_chan_bw == - HT_CHANNEL_WIDTH_20) - chnlgroup++; - else - chnlgroup += 4; - } - - writeVal = rtlphy->mcs_offset[chnlgroup] - [index + (rf ? 8 : 0)] + ((index < 2) ? - powerBase0[rf] : - powerBase1[rf]); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - "Realtek regulatory, 20MHz, writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal); - } - break; - case 2: - writeVal = - ((index < 2) ? powerBase0[rf] : powerBase1[rf]); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - "Better regulatory, writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal); - break; - case 3: - chnlgroup = 0; - - if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - "customer's limit, 40MHz rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), - rtlefuse->pwrgroup_ht40[rf][channel-1]); - } else { - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - "customer's limit, 20MHz rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), - rtlefuse->pwrgroup_ht20[rf][channel-1]); - } - for (i = 0; i < 4; i++) { - pwr_diff_limit[i] = - (u8) ((rtlphy->mcs_offset - [chnlgroup][index + (rf ? 8 : 0)] & - (0x7f << (i * 8))) >> (i * 8)); - - if (rtlphy->current_chan_bw == - HT_CHANNEL_WIDTH_20_40) { - if (pwr_diff_limit[i] > - rtlefuse-> - pwrgroup_ht40[rf][channel - 1]) - pwr_diff_limit[i] = - rtlefuse->pwrgroup_ht40[rf] - [channel - 1]; - } else { - if (pwr_diff_limit[i] > - rtlefuse-> - pwrgroup_ht20[rf][channel - 1]) - pwr_diff_limit[i] = - rtlefuse->pwrgroup_ht20[rf] - [channel - 1]; - } - } - - customer_limit = (pwr_diff_limit[3] << 24) | - (pwr_diff_limit[2] << 16) | - (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - "Customer's limit rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), customer_limit); - - writeVal = customer_limit + - ((index < 2) ? powerBase0[rf] : powerBase1[rf]); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - "Customer, writeVal rf(%c)= 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal); - break; - default: - chnlgroup = 0; - writeVal = rtlphy->mcs_offset[chnlgroup][index + - (rf ? 8 : 0)] + ((index < 2) ? powerBase0[rf] : - powerBase1[rf]); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - "RTK better performance, writeVal rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal); - break; - } - - if (rtlpriv->dm.dynamic_txhighpower_lvl == TXHIGHPWRLEVEL_BT1) - writeVal = writeVal - 0x06060606; - else if (rtlpriv->dm.dynamic_txhighpower_lvl == - TXHIGHPWRLEVEL_BT2) - writeVal = writeVal - 0x0c0c0c0c; - *(p_outwriteval + rf) = writeVal; - } -} - -static void _rtl8723ae_write_ofdm_power_reg(struct ieee80211_hw *hw, - u8 index, u32 *pValue) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - u16 regoffset_a[6] = { - RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24, - RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04, - RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12 - }; - u16 regoffset_b[6] = { - RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24, - RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04, - RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12 - }; - u8 i, rf, pwr_val[4]; - u32 writeVal; - u16 regoffset; - - for (rf = 0; rf < 2; rf++) { - writeVal = pValue[rf]; - for (i = 0; i < 4; i++) { - pwr_val[i] = (u8) ((writeVal & (0x7f << - (i * 8))) >> (i * 8)); - - if (pwr_val[i] > RF6052_MAX_TX_PWR) - pwr_val[i] = RF6052_MAX_TX_PWR; - } - writeVal = (pwr_val[3] << 24) | (pwr_val[2] << 16) | - (pwr_val[1] << 8) | pwr_val[0]; - - if (rf == 0) - regoffset = regoffset_a[index]; - else - regoffset = regoffset_b[index]; - rtl_set_bbreg(hw, regoffset, MASKDWORD, writeVal); - - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - "Set 0x%x = %08x\n", regoffset, writeVal); - - if (((get_rf_type(rtlphy) == RF_2T2R) && - (regoffset == RTXAGC_A_MCS15_MCS12 || - regoffset == RTXAGC_B_MCS15_MCS12)) || - ((get_rf_type(rtlphy) != RF_2T2R) && - (regoffset == RTXAGC_A_MCS07_MCS04 || - regoffset == RTXAGC_B_MCS07_MCS04))) { - - writeVal = pwr_val[3]; - if (regoffset == RTXAGC_A_MCS15_MCS12 || - regoffset == RTXAGC_A_MCS07_MCS04) - regoffset = 0xc90; - if (regoffset == RTXAGC_B_MCS15_MCS12 || - regoffset == RTXAGC_B_MCS07_MCS04) - regoffset = 0xc98; - - for (i = 0; i < 3; i++) { - writeVal = (writeVal > 6) ? (writeVal - 6) : 0; - rtl_write_byte(rtlpriv, (u32) (regoffset + i), - (u8) writeVal); - } - } - } -} - -void rtl8723ae_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, - u8 *ppowerlevel, u8 channel) -{ - u32 writeVal[2], powerBase0[2], powerBase1[2]; - u8 index; - - rtl8723ae_phy_get_power_base(hw, ppowerlevel, - channel, &powerBase0[0], &powerBase1[0]); - - for (index = 0; index < 6; index++) { - rtl8723ae_get_txpwr_val_by_reg(hw, channel, index, - &powerBase0[0], - &powerBase1[0], - &writeVal[0]); - - _rtl8723ae_write_ofdm_power_reg(hw, index, &writeVal[0]); - } -} - -static bool _rtl8723ae_phy_rf6052_config_parafile(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - u32 u4_regvalue = 0; - u8 rfpath; - bool rtstatus = true; - struct bb_reg_def *pphyreg; - - for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { - - pphyreg = &rtlphy->phyreg_def[rfpath]; - - switch (rfpath) { - case RF90_PATH_A: - case RF90_PATH_C: - u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, - BRFSI_RFENV); - break; - case RF90_PATH_B: - case RF90_PATH_D: - u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs, - BRFSI_RFENV << 16); - break; - } - - rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1); - udelay(1); - - rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1); - udelay(1); - - rtl_set_bbreg(hw, pphyreg->rfhssi_para2, - B3WIREADDREAALENGTH, 0x0); - udelay(1); - - rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0); - udelay(1); - - switch (rfpath) { - case RF90_PATH_A: - rtstatus = rtl8723ae_phy_config_rf_with_headerfile(hw, - (enum radio_path)rfpath); - break; - case RF90_PATH_B: - rtstatus = rtl8723ae_phy_config_rf_with_headerfile(hw, - (enum radio_path)rfpath); - break; - case RF90_PATH_C: - break; - case RF90_PATH_D: - break; - } - switch (rfpath) { - case RF90_PATH_A: - case RF90_PATH_C: - rtl_set_bbreg(hw, pphyreg->rfintfs, - BRFSI_RFENV, u4_regvalue); - break; - case RF90_PATH_B: - case RF90_PATH_D: - rtl_set_bbreg(hw, pphyreg->rfintfs, - BRFSI_RFENV << 16, u4_regvalue); - break; - } - if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Radio[%d] Fail!!", rfpath); - return false; - } - } - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n"); - return rtstatus; -} - -bool rtl8723ae_phy_rf6052_config(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - if (rtlphy->rf_type == RF_1T1R) - rtlphy->num_total_rfpath = 1; - else - rtlphy->num_total_rfpath = 2; - - return _rtl8723ae_phy_rf6052_config_parafile(hw); -} diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h deleted file mode 100644 index d0f9dd79abea..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/rf.h +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL8723E_RF_H__ -#define __RTL8723E_RF_H__ - -#define RF6052_MAX_TX_PWR 0x3F - -extern void rtl8723ae_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, - u8 bandwidth); -extern void rtl8723ae_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, - u8 *ppowerlevel); -extern void rtl8723ae_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw, - u8 *ppowerlevel, u8 channel); -extern bool rtl8723ae_phy_rf6052_config(struct ieee80211_hw *hw); - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c deleted file mode 100644 index 18b0bc51766b..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c +++ /dev/null @@ -1,380 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#include "../wifi.h" -#include -#include - -#include "../core.h" -#include "../pci.h" -#include "reg.h" -#include "def.h" -#include "phy.h" -#include "dm.h" -#include "hw.h" -#include "sw.h" -#include "trx.h" -#include "led.h" -#include "table.h" -#include "hal_btc.h" - -static void rtl8723ae_init_aspm_vars(struct ieee80211_hw *hw) -{ - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - - /*close ASPM for AMD defaultly */ - rtlpci->const_amdpci_aspm = 0; - - /* ASPM PS mode. - * 0 - Disable ASPM, - * 1 - Enable ASPM without Clock Req, - * 2 - Enable ASPM with Clock Req, - * 3 - Alwyas Enable ASPM with Clock Req, - * 4 - Always Enable ASPM without Clock Req. - * set defult to RTL8192CE:3 RTL8192E:2 - */ - rtlpci->const_pci_aspm = 3; - - /*Setting for PCI-E device */ - rtlpci->const_devicepci_aspm_setting = 0x03; - - /*Setting for PCI-E bridge */ - rtlpci->const_hostpci_aspm_setting = 0x02; - - /* In Hw/Sw Radio Off situation. - * 0 - Default, - * 1 - From ASPM setting without low Mac Pwr, - * 2 - From ASPM setting with low Mac Pwr, - * 3 - Bus D3 - * set default to RTL8192CE:0 RTL8192SE:2 - */ - rtlpci->const_hwsw_rfoff_d3 = 0; - - /* This setting works for those device with - * backdoor ASPM setting such as EPHY setting. - * 0 - Not support ASPM, - * 1 - Support ASPM, - * 2 - According to chipset. - */ - rtlpci->const_support_pciaspm = 1; -} - -int rtl8723ae_init_sw_vars(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - int err; - - rtl8723ae_bt_reg_init(hw); - rtlpriv->dm.dm_initialgain_enable = 1; - rtlpriv->dm.dm_flag = 0; - rtlpriv->dm.disable_framebursting = 0; - rtlpriv->dm.thermalvalue = 0; - rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13); - - /* compatible 5G band 88ce just 2.4G band & smsp */ - rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G; - rtlpriv->rtlhal.bandset = BAND_ON_2_4G; - rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY; - - rtlpci->receive_config = (RCR_APPFCS | - RCR_APP_MIC | - RCR_APP_ICV | - RCR_APP_PHYST_RXFF | - RCR_HTC_LOC_CTRL | - RCR_AMF | - RCR_ACF | - RCR_ADF | - RCR_AICV | - RCR_AB | - RCR_AM | - RCR_APM | - 0); - - rtlpci->irq_mask[0] = - (u32) (PHIMR_ROK | - PHIMR_RDU | - PHIMR_VODOK | - PHIMR_VIDOK | - PHIMR_BEDOK | - PHIMR_BKDOK | - PHIMR_MGNTDOK | - PHIMR_HIGHDOK | - PHIMR_C2HCMD | - PHIMR_HISRE_IND | - PHIMR_TSF_BIT32_TOGGLE | - PHIMR_TXBCNOK | - PHIMR_PSTIMEOUT | - 0); - - rtlpci->irq_mask[1] = (u32)(PHIMR_RXFOVW | 0); - - /* for debug level */ - rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug; - /* for LPS & IPS */ - rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; - rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; - rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps; - rtlpriv->psc.reg_fwctrl_lps = 3; - rtlpriv->psc.reg_max_lps_awakeintvl = 5; - /* for ASPM, you can close aspm through - * set const_support_pciaspm = 0 - */ - rtl8723ae_init_aspm_vars(hw); - - if (rtlpriv->psc.reg_fwctrl_lps == 1) - rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE; - else if (rtlpriv->psc.reg_fwctrl_lps == 2) - rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE; - else if (rtlpriv->psc.reg_fwctrl_lps == 3) - rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE; - - /* for firmware buf */ - rtlpriv->rtlhal.pfirmware = vmalloc(0x6000); - if (!rtlpriv->rtlhal.pfirmware) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Can't alloc buffer for fw.\n"); - return 1; - } - - if (IS_VENDOR_8723_A_CUT(rtlhal->version)) - rtlpriv->cfg->fw_name = "rtlwifi/rtl8723fw.bin"; - else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) - rtlpriv->cfg->fw_name = "rtlwifi/rtl8723fw_B.bin"; - - rtlpriv->max_fw_size = 0x6000; - pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name); - err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, - rtlpriv->io.dev, GFP_KERNEL, hw, - rtl_fw_cb); - if (err) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Failed to request firmware!\n"); - return 1; - } - return 0; -} - -void rtl8723ae_deinit_sw_vars(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - - if (rtlpriv->rtlhal.pfirmware) { - vfree(rtlpriv->rtlhal.pfirmware); - rtlpriv->rtlhal.pfirmware = NULL; - } -} - -static struct rtl_hal_ops rtl8723ae_hal_ops = { - .init_sw_vars = rtl8723ae_init_sw_vars, - .deinit_sw_vars = rtl8723ae_deinit_sw_vars, - .read_eeprom_info = rtl8723ae_read_eeprom_info, - .interrupt_recognized = rtl8723ae_interrupt_recognized, - .hw_init = rtl8723ae_hw_init, - .hw_disable = rtl8723ae_card_disable, - .hw_suspend = rtl8723ae_suspend, - .hw_resume = rtl8723ae_resume, - .enable_interrupt = rtl8723ae_enable_interrupt, - .disable_interrupt = rtl8723ae_disable_interrupt, - .set_network_type = rtl8723ae_set_network_type, - .set_chk_bssid = rtl8723ae_set_check_bssid, - .set_qos = rtl8723ae_set_qos, - .set_bcn_reg = rtl8723ae_set_beacon_related_registers, - .set_bcn_intv = rtl8723ae_set_beacon_interval, - .update_interrupt_mask = rtl8723ae_update_interrupt_mask, - .get_hw_reg = rtl8723ae_get_hw_reg, - .set_hw_reg = rtl8723ae_set_hw_reg, - .update_rate_tbl = rtl8723ae_update_hal_rate_tbl, - .fill_tx_desc = rtl8723ae_tx_fill_desc, - .fill_tx_cmddesc = rtl8723ae_tx_fill_cmddesc, - .query_rx_desc = rtl8723ae_rx_query_desc, - .set_channel_access = rtl8723ae_update_channel_access_setting, - .radio_onoff_checking = rtl8723ae_gpio_radio_on_off_checking, - .set_bw_mode = rtl8723ae_phy_set_bw_mode, - .switch_channel = rtl8723ae_phy_sw_chnl, - .dm_watchdog = rtl8723ae_dm_watchdog, - .scan_operation_backup = rtl8723ae_phy_scan_operation_backup, - .set_rf_power_state = rtl8723ae_phy_set_rf_power_state, - .led_control = rtl8723ae_led_control, - .set_desc = rtl8723ae_set_desc, - .get_desc = rtl8723ae_get_desc, - .tx_polling = rtl8723ae_tx_polling, - .enable_hw_sec = rtl8723ae_enable_hw_security_config, - .set_key = rtl8723ae_set_key, - .init_sw_leds = rtl8723ae_init_sw_leds, - .allow_all_destaddr = rtl8723ae_allow_all_destaddr, - .get_bbreg = rtl8723ae_phy_query_bb_reg, - .set_bbreg = rtl8723ae_phy_set_bb_reg, - .get_rfreg = rtl8723ae_phy_query_rf_reg, - .set_rfreg = rtl8723ae_phy_set_rf_reg, - .c2h_command_handle = rtl_8723e_c2h_command_handle, - .bt_wifi_media_status_notify = rtl_8723e_bt_wifi_media_status_notify, - .bt_coex_off_before_lps = rtl8723ae_bt_coex_off_before_lps, -}; - -static struct rtl_mod_params rtl8723ae_mod_params = { - .sw_crypto = false, - .inactiveps = true, - .swctrl_lps = false, - .fwctrl_lps = true, - .debug = DBG_EMERG, -}; - -static struct rtl_hal_cfg rtl8723ae_hal_cfg = { - .bar_id = 2, - .write_readback = true, - .name = "rtl8723ae_pci", - .fw_name = "rtlwifi/rtl8723aefw.bin", - .ops = &rtl8723ae_hal_ops, - .mod_params = &rtl8723ae_mod_params, - .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, - .maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN, - .maps[SYS_CLK] = REG_SYS_CLKR, - .maps[MAC_RCR_AM] = AM, - .maps[MAC_RCR_AB] = AB, - .maps[MAC_RCR_ACRC32] = ACRC32, - .maps[MAC_RCR_ACF] = ACF, - .maps[MAC_RCR_AAP] = AAP, - .maps[EFUSE_TEST] = REG_EFUSE_TEST, - .maps[EFUSE_CTRL] = REG_EFUSE_CTRL, - .maps[EFUSE_CLK] = 0, - .maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL, - .maps[EFUSE_PWC_EV12V] = PWC_EV12V, - .maps[EFUSE_FEN_ELDR] = FEN_ELDR, - .maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN, - .maps[EFUSE_ANA8M] = ANA8M, - .maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE, - .maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION, - .maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN, - .maps[EFUSE_OOB_PROTECT_BYTES_LEN] = EFUSE_OOB_PROTECT_BYTES, - - .maps[RWCAM] = REG_CAMCMD, - .maps[WCAMI] = REG_CAMWRITE, - .maps[RCAMO] = REG_CAMREAD, - .maps[CAMDBG] = REG_CAMDBG, - .maps[SECR] = REG_SECCFG, - .maps[SEC_CAM_NONE] = CAM_NONE, - .maps[SEC_CAM_WEP40] = CAM_WEP40, - .maps[SEC_CAM_TKIP] = CAM_TKIP, - .maps[SEC_CAM_AES] = CAM_AES, - .maps[SEC_CAM_WEP104] = CAM_WEP104, - - .maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6, - .maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5, - .maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4, - .maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3, - .maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2, - .maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1, - .maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8, - .maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7, - .maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6, - .maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5, - .maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4, - .maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3, - .maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2, - .maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1, - .maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2, - .maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1, - - .maps[RTL_IMR_TXFOVW] = PHIMR_TXFOVW, - .maps[RTL_IMR_PSTIMEOUT] = PHIMR_PSTIMEOUT, - .maps[RTL_IMR_BcnInt] = PHIMR_BCNDMAINT0, - .maps[RTL_IMR_RXFOVW] = PHIMR_RXFOVW, - .maps[RTL_IMR_RDU] = PHIMR_RDU, - .maps[RTL_IMR_ATIMEND] = PHIMR_ATIMEND_E, - .maps[RTL_IMR_BDOK] = PHIMR_BCNDOK0, - .maps[RTL_IMR_MGNTDOK] = PHIMR_MGNTDOK, - .maps[RTL_IMR_TBDER] = PHIMR_TXBCNERR, - .maps[RTL_IMR_HIGHDOK] = PHIMR_HIGHDOK, - .maps[RTL_IMR_TBDOK] = PHIMR_TXBCNOK, - .maps[RTL_IMR_BKDOK] = PHIMR_BKDOK, - .maps[RTL_IMR_BEDOK] = PHIMR_BEDOK, - .maps[RTL_IMR_VIDOK] = PHIMR_VIDOK, - .maps[RTL_IMR_VODOK] = PHIMR_VODOK, - .maps[RTL_IMR_ROK] = PHIMR_ROK, - .maps[RTL_IBSS_INT_MASKS] = (PHIMR_BCNDMAINT0 | - PHIMR_TXBCNOK | PHIMR_TXBCNERR), - .maps[RTL_IMR_C2HCMD] = PHIMR_C2HCMD, - - - .maps[RTL_RC_CCK_RATE1M] = DESC92_RATE1M, - .maps[RTL_RC_CCK_RATE2M] = DESC92_RATE2M, - .maps[RTL_RC_CCK_RATE5_5M] = DESC92_RATE5_5M, - .maps[RTL_RC_CCK_RATE11M] = DESC92_RATE11M, - .maps[RTL_RC_OFDM_RATE6M] = DESC92_RATE6M, - .maps[RTL_RC_OFDM_RATE9M] = DESC92_RATE9M, - .maps[RTL_RC_OFDM_RATE12M] = DESC92_RATE12M, - .maps[RTL_RC_OFDM_RATE18M] = DESC92_RATE18M, - .maps[RTL_RC_OFDM_RATE24M] = DESC92_RATE24M, - .maps[RTL_RC_OFDM_RATE36M] = DESC92_RATE36M, - .maps[RTL_RC_OFDM_RATE48M] = DESC92_RATE48M, - .maps[RTL_RC_OFDM_RATE54M] = DESC92_RATE54M, - - .maps[RTL_RC_HT_RATEMCS7] = DESC92_RATEMCS7, - .maps[RTL_RC_HT_RATEMCS15] = DESC92_RATEMCS15, -}; - -static struct pci_device_id rtl8723ae_pci_ids[] __devinitdata = { - {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8723, rtl8723ae_hal_cfg)}, - {}, -}; - -MODULE_DEVICE_TABLE(pci, rtl8723ae_pci_ids); - -MODULE_AUTHOR("lizhaoming "); -MODULE_AUTHOR("Realtek WlanFAE "); -MODULE_AUTHOR("Larry Finger "); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Realtek 8723E 802.11n PCI wireless"); -MODULE_FIRMWARE("rtlwifi/rtl8723aefw.bin"); -MODULE_FIRMWARE("rtlwifi/rtl8723aefw_B.bin"); - -module_param_named(swenc, rtl8723ae_mod_params.sw_crypto, bool, 0444); -module_param_named(debug, rtl8723ae_mod_params.debug, int, 0444); -module_param_named(ips, rtl8723ae_mod_params.inactiveps, bool, 0444); -module_param_named(swlps, rtl8723ae_mod_params.swctrl_lps, bool, 0444); -module_param_named(fwlps, rtl8723ae_mod_params.fwctrl_lps, bool, 0444); -MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n"); -MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n"); -MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n"); -MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); -MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); - -static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume); - -static struct pci_driver rtl8723ae_driver = { - .name = KBUILD_MODNAME, - .id_table = rtl8723ae_pci_ids, - .probe = rtl_pci_probe, - .remove = rtl_pci_disconnect, - .driver.pm = &rtlwifi_pm_ops, -}; - -module_pci_driver(rtl8723ae_driver); diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/sw.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/sw.h deleted file mode 100644 index fc4fde5e3eb5..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/sw.h +++ /dev/null @@ -1,37 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL8723E_SW_H__ -#define __RTL8723E_SW_H__ - -int rtl8723ae_init_sw_vars(struct ieee80211_hw *hw); -void rtl8723ae_deinit_sw_vars(struct ieee80211_hw *hw); -void rtl8723ae_init_var_map(struct ieee80211_hw *hw); - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/table.c b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/table.c deleted file mode 100644 index 9b0b50cc4ade..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/table.c +++ /dev/null @@ -1,738 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Created on 2010/ 5/18, 1:41 - * - * Larry Finger - * - *****************************************************************************/ - -#include "table.h" - -u32 RTL8723EPHY_REG_1TARRAY[RTL8723E_PHY_REG_1TARRAY_LENGTH] = { - 0x800, 0x80040000, - 0x804, 0x00000003, - 0x808, 0x0000fc00, - 0x80c, 0x0000000a, - 0x810, 0x10005388, - 0x814, 0x020c3d10, - 0x818, 0x02200385, - 0x81c, 0x00000000, - 0x820, 0x01000100, - 0x824, 0x00390004, - 0x828, 0x00000000, - 0x82c, 0x00000000, - 0x830, 0x00000000, - 0x834, 0x00000000, - 0x838, 0x00000000, - 0x83c, 0x00000000, - 0x840, 0x00010000, - 0x844, 0x00000000, - 0x848, 0x00000000, - 0x84c, 0x00000000, - 0x850, 0x00000000, - 0x854, 0x00000000, - 0x858, 0x569a569a, - 0x85c, 0x001b25a4, - 0x860, 0x66f60110, - 0x864, 0x061f0130, - 0x868, 0x00000000, - 0x86c, 0x32323200, - 0x870, 0x07000760, - 0x874, 0x22004000, - 0x878, 0x00000808, - 0x87c, 0x00000000, - 0x880, 0xc0083070, - 0x884, 0x000004d5, - 0x888, 0x00000000, - 0x88c, 0xccc000c0, - 0x890, 0x00000800, - 0x894, 0xfffffffe, - 0x898, 0x40302010, - 0x89c, 0x00706050, - 0x900, 0x00000000, - 0x904, 0x00000023, - 0x908, 0x00000000, - 0x90c, 0x81121111, - 0xa00, 0x00d047c8, - 0xa04, 0x80ff000c, - 0xa08, 0x8c838300, - 0xa0c, 0x2e68120f, - 0xa10, 0x9500bb78, - 0xa14, 0x11144028, - 0xa18, 0x00881117, - 0xa1c, 0x89140f00, - 0xa20, 0x1a1b0000, - 0xa24, 0x090e1317, - 0xa28, 0x00000204, - 0xa2c, 0x00d30000, - 0xa70, 0x101fbf00, - 0xa74, 0x00000007, - 0xa78, 0x00000900, - 0xc00, 0x48071d40, - 0xc04, 0x03a05611, - 0xc08, 0x000000e4, - 0xc0c, 0x6c6c6c6c, - 0xc10, 0x08800000, - 0xc14, 0x40000100, - 0xc18, 0x08800000, - 0xc1c, 0x40000100, - 0xc20, 0x00000000, - 0xc24, 0x00000000, - 0xc28, 0x00000000, - 0xc2c, 0x00000000, - 0xc30, 0x69e9ac44, - 0xc34, 0x469652cf, - 0xc38, 0x49795994, - 0xc3c, 0x0a97971c, - 0xc40, 0x1f7c403f, - 0xc44, 0x000100b7, - 0xc48, 0xec020107, - 0xc4c, 0x007f037f, - 0xc50, 0x69543420, - 0xc54, 0x43bc0094, - 0xc58, 0x69543420, - 0xc5c, 0x433c0094, - 0xc60, 0x00000000, - 0xc64, 0x7116848b, - 0xc68, 0x47c00bff, - 0xc6c, 0x00000036, - 0xc70, 0x2c7f000d, - 0xc74, 0x018610db, - 0xc78, 0x0000001f, - 0xc7c, 0x00b91612, - 0xc80, 0x40000100, - 0xc84, 0x20f60000, - 0xc88, 0x40000100, - 0xc8c, 0x20200000, - 0xc90, 0x00121820, - 0xc94, 0x00000000, - 0xc98, 0x00121820, - 0xc9c, 0x00007f7f, - 0xca0, 0x00000000, - 0xca4, 0x00000080, - 0xca8, 0x00000000, - 0xcac, 0x00000000, - 0xcb0, 0x00000000, - 0xcb4, 0x00000000, - 0xcb8, 0x00000000, - 0xcbc, 0x28000000, - 0xcc0, 0x00000000, - 0xcc4, 0x00000000, - 0xcc8, 0x00000000, - 0xccc, 0x00000000, - 0xcd0, 0x00000000, - 0xcd4, 0x00000000, - 0xcd8, 0x64b22427, - 0xcdc, 0x00766932, - 0xce0, 0x00222222, - 0xce4, 0x00000000, - 0xce8, 0x37644302, - 0xcec, 0x2f97d40c, - 0xd00, 0x00080740, - 0xd04, 0x00020401, - 0xd08, 0x0000907f, - 0xd0c, 0x20010201, - 0xd10, 0xa0633333, - 0xd14, 0x3333bc43, - 0xd18, 0x7a8f5b6b, - 0xd2c, 0xcc979975, - 0xd30, 0x00000000, - 0xd34, 0x80608000, - 0xd38, 0x00000000, - 0xd3c, 0x00027293, - 0xd40, 0x00000000, - 0xd44, 0x00000000, - 0xd48, 0x00000000, - 0xd4c, 0x00000000, - 0xd50, 0x6437140a, - 0xd54, 0x00000000, - 0xd58, 0x00000000, - 0xd5c, 0x30032064, - 0xd60, 0x4653de68, - 0xd64, 0x04518a3c, - 0xd68, 0x00002101, - 0xd6c, 0x2a201c16, - 0xd70, 0x1812362e, - 0xd74, 0x322c2220, - 0xd78, 0x000e3c24, - 0xe00, 0x2a2a2a2a, - 0xe04, 0x2a2a2a2a, - 0xe08, 0x03902a2a, - 0xe10, 0x2a2a2a2a, - 0xe14, 0x2a2a2a2a, - 0xe18, 0x2a2a2a2a, - 0xe1c, 0x2a2a2a2a, - 0xe28, 0x00000000, - 0xe30, 0x1000dc1f, - 0xe34, 0x10008c1f, - 0xe38, 0x02140102, - 0xe3c, 0x681604c2, - 0xe40, 0x01007c00, - 0xe44, 0x01004800, - 0xe48, 0xfb000000, - 0xe4c, 0x000028d1, - 0xe50, 0x1000dc1f, - 0xe54, 0x10008c1f, - 0xe58, 0x02140102, - 0xe5c, 0x28160d05, - 0xe60, 0x00000008, - 0xe68, 0x001b25a4, - 0xe6c, 0x631b25a0, - 0xe70, 0x631b25a0, - 0xe74, 0x081b25a0, - 0xe78, 0x081b25a0, - 0xe7c, 0x081b25a0, - 0xe80, 0x081b25a0, - 0xe84, 0x631b25a0, - 0xe88, 0x081b25a0, - 0xe8c, 0x631b25a0, - 0xed0, 0x631b25a0, - 0xed4, 0x631b25a0, - 0xed8, 0x631b25a0, - 0xedc, 0x001b25a0, - 0xee0, 0x001b25a0, - 0xeec, 0x6b1b25a0, - 0xf14, 0x00000003, - 0xf4c, 0x00000000, - 0xf00, 0x00000300, -}; - -u32 RTL8723EPHY_REG_ARRAY_PG[RTL8723E_PHY_REG_ARRAY_PGLENGTH] = { - 0xe00, 0xffffffff, 0x0a0c0c0c, - 0xe04, 0xffffffff, 0x02040608, - 0xe08, 0x0000ff00, 0x00000000, - 0x86c, 0xffffff00, 0x00000000, - 0xe10, 0xffffffff, 0x0a0c0d0e, - 0xe14, 0xffffffff, 0x02040608, - 0xe18, 0xffffffff, 0x0a0c0d0e, - 0xe1c, 0xffffffff, 0x02040608, - 0x830, 0xffffffff, 0x0a0c0c0c, - 0x834, 0xffffffff, 0x02040608, - 0x838, 0xffffff00, 0x00000000, - 0x86c, 0x000000ff, 0x00000000, - 0x83c, 0xffffffff, 0x0a0c0d0e, - 0x848, 0xffffffff, 0x02040608, - 0x84c, 0xffffffff, 0x0a0c0d0e, - 0x868, 0xffffffff, 0x02040608, - 0xe00, 0xffffffff, 0x00000000, - 0xe04, 0xffffffff, 0x00000000, - 0xe08, 0x0000ff00, 0x00000000, - 0x86c, 0xffffff00, 0x00000000, - 0xe10, 0xffffffff, 0x00000000, - 0xe14, 0xffffffff, 0x00000000, - 0xe18, 0xffffffff, 0x00000000, - 0xe1c, 0xffffffff, 0x00000000, - 0x830, 0xffffffff, 0x00000000, - 0x834, 0xffffffff, 0x00000000, - 0x838, 0xffffff00, 0x00000000, - 0x86c, 0x000000ff, 0x00000000, - 0x83c, 0xffffffff, 0x00000000, - 0x848, 0xffffffff, 0x00000000, - 0x84c, 0xffffffff, 0x00000000, - 0x868, 0xffffffff, 0x00000000, - 0xe00, 0xffffffff, 0x04040404, - 0xe04, 0xffffffff, 0x00020204, - 0xe08, 0x0000ff00, 0x00000000, - 0x86c, 0xffffff00, 0x00000000, - 0xe10, 0xffffffff, 0x06060606, - 0xe14, 0xffffffff, 0x00020406, - 0xe18, 0xffffffff, 0x00000000, - 0xe1c, 0xffffffff, 0x00000000, - 0x830, 0xffffffff, 0x04040404, - 0x834, 0xffffffff, 0x00020204, - 0x838, 0xffffff00, 0x00000000, - 0x86c, 0x000000ff, 0x00000000, - 0x83c, 0xffffffff, 0x06060606, - 0x848, 0xffffffff, 0x00020406, - 0x84c, 0xffffffff, 0x00000000, - 0x868, 0xffffffff, 0x00000000, - 0xe00, 0xffffffff, 0x00000000, - 0xe04, 0xffffffff, 0x00000000, - 0xe08, 0x0000ff00, 0x00000000, - 0x86c, 0xffffff00, 0x00000000, - 0xe10, 0xffffffff, 0x00000000, - 0xe14, 0xffffffff, 0x00000000, - 0xe18, 0xffffffff, 0x00000000, - 0xe1c, 0xffffffff, 0x00000000, - 0x830, 0xffffffff, 0x00000000, - 0x834, 0xffffffff, 0x00000000, - 0x838, 0xffffff00, 0x00000000, - 0x86c, 0x000000ff, 0x00000000, - 0x83c, 0xffffffff, 0x00000000, - 0x848, 0xffffffff, 0x00000000, - 0x84c, 0xffffffff, 0x00000000, - 0x868, 0xffffffff, 0x00000000, - 0xe00, 0xffffffff, 0x00000000, - 0xe04, 0xffffffff, 0x00000000, - 0xe08, 0x0000ff00, 0x00000000, - 0x86c, 0xffffff00, 0x00000000, - 0xe10, 0xffffffff, 0x00000000, - 0xe14, 0xffffffff, 0x00000000, - 0xe18, 0xffffffff, 0x00000000, - 0xe1c, 0xffffffff, 0x00000000, - 0x830, 0xffffffff, 0x00000000, - 0x834, 0xffffffff, 0x00000000, - 0x838, 0xffffff00, 0x00000000, - 0x86c, 0x000000ff, 0x00000000, - 0x83c, 0xffffffff, 0x00000000, - 0x848, 0xffffffff, 0x00000000, - 0x84c, 0xffffffff, 0x00000000, - 0x868, 0xffffffff, 0x00000000, - 0xe00, 0xffffffff, 0x04040404, - 0xe04, 0xffffffff, 0x00020204, - 0xe08, 0x0000ff00, 0x00000000, - 0x86c, 0xffffff00, 0x00000000, - 0xe10, 0xffffffff, 0x00000000, - 0xe14, 0xffffffff, 0x00000000, - 0xe18, 0xffffffff, 0x00000000, - 0xe1c, 0xffffffff, 0x00000000, - 0x830, 0xffffffff, 0x04040404, - 0x834, 0xffffffff, 0x00020204, - 0x838, 0xffffff00, 0x00000000, - 0x86c, 0x000000ff, 0x00000000, - 0x83c, 0xffffffff, 0x00000000, - 0x848, 0xffffffff, 0x00000000, - 0x84c, 0xffffffff, 0x00000000, - 0x868, 0xffffffff, 0x00000000, - 0xe00, 0xffffffff, 0x00000000, - 0xe04, 0xffffffff, 0x00000000, - 0xe08, 0x0000ff00, 0x00000000, - 0x86c, 0xffffff00, 0x00000000, - 0xe10, 0xffffffff, 0x00000000, - 0xe14, 0xffffffff, 0x00000000, - 0xe18, 0xffffffff, 0x00000000, - 0xe1c, 0xffffffff, 0x00000000, - 0x830, 0xffffffff, 0x00000000, - 0x834, 0xffffffff, 0x00000000, - 0x838, 0xffffff00, 0x00000000, - 0x86c, 0x000000ff, 0x00000000, - 0x83c, 0xffffffff, 0x00000000, - 0x848, 0xffffffff, 0x00000000, - 0x84c, 0xffffffff, 0x00000000, - 0x868, 0xffffffff, 0x00000000, -}; - -u32 RTL8723E_RADIOA_1TARRAY[Rtl8723ERADIOA_1TARRAYLENGTH] = { - 0x000, 0x00030159, - 0x001, 0x00031284, - 0x002, 0x00098000, - 0x003, 0x00018c63, - 0x004, 0x000210e7, - 0x009, 0x0002044f, - 0x00a, 0x0001a3f1, - 0x00b, 0x00014787, - 0x00c, 0x000896fe, - 0x00d, 0x0000e02c, - 0x00e, 0x00039ce7, - 0x00f, 0x00000451, - 0x019, 0x00000000, - 0x01a, 0x00030355, - 0x01b, 0x00060a00, - 0x01c, 0x000fc378, - 0x01d, 0x000a1250, - 0x01e, 0x0004445f, - 0x01f, 0x00080001, - 0x020, 0x0000b614, - 0x021, 0x0006c000, - 0x022, 0x00000000, - 0x023, 0x00001558, - 0x024, 0x00000060, - 0x025, 0x00000483, - 0x026, 0x0004f000, - 0x027, 0x000ec7d9, - 0x028, 0x00057730, - 0x029, 0x00004783, - 0x02a, 0x00000001, - 0x02b, 0x00021334, - 0x02a, 0x00000000, - 0x02b, 0x00000054, - 0x02a, 0x00000001, - 0x02b, 0x00000808, - 0x02b, 0x00053333, - 0x02c, 0x0000000c, - 0x02a, 0x00000002, - 0x02b, 0x00000808, - 0x02b, 0x0005b333, - 0x02c, 0x0000000d, - 0x02a, 0x00000003, - 0x02b, 0x00000808, - 0x02b, 0x00063333, - 0x02c, 0x0000000d, - 0x02a, 0x00000004, - 0x02b, 0x00000808, - 0x02b, 0x0006b333, - 0x02c, 0x0000000d, - 0x02a, 0x00000005, - 0x02b, 0x00000808, - 0x02b, 0x00073333, - 0x02c, 0x0000000d, - 0x02a, 0x00000006, - 0x02b, 0x00000709, - 0x02b, 0x0005b333, - 0x02c, 0x0000000d, - 0x02a, 0x00000007, - 0x02b, 0x00000709, - 0x02b, 0x00063333, - 0x02c, 0x0000000d, - 0x02a, 0x00000008, - 0x02b, 0x0000060a, - 0x02b, 0x0004b333, - 0x02c, 0x0000000d, - 0x02a, 0x00000009, - 0x02b, 0x0000060a, - 0x02b, 0x00053333, - 0x02c, 0x0000000d, - 0x02a, 0x0000000a, - 0x02b, 0x0000060a, - 0x02b, 0x0005b333, - 0x02c, 0x0000000d, - 0x02a, 0x0000000b, - 0x02b, 0x0000060a, - 0x02b, 0x00063333, - 0x02c, 0x0000000d, - 0x02a, 0x0000000c, - 0x02b, 0x0000060a, - 0x02b, 0x0006b333, - 0x02c, 0x0000000d, - 0x02a, 0x0000000d, - 0x02b, 0x0000060a, - 0x02b, 0x00073333, - 0x02c, 0x0000000d, - 0x02a, 0x0000000e, - 0x02b, 0x0000050b, - 0x02b, 0x00066666, - 0x02c, 0x0000001a, - 0x02a, 0x000e0000, - 0x010, 0x0004000f, - 0x011, 0x000e31fc, - 0x010, 0x0006000f, - 0x011, 0x000ff9f8, - 0x010, 0x0002000f, - 0x011, 0x000203f9, - 0x010, 0x0003000f, - 0x011, 0x000ff500, - 0x010, 0x00000000, - 0x011, 0x00000000, - 0x010, 0x0008000f, - 0x011, 0x0003f100, - 0x010, 0x0009000f, - 0x011, 0x00023100, - 0x012, 0x00032000, - 0x012, 0x00071000, - 0x012, 0x000b0000, - 0x012, 0x000fc000, - 0x013, 0x000287b3, - 0x013, 0x000244b7, - 0x013, 0x000204ab, - 0x013, 0x0001c49f, - 0x013, 0x00018493, - 0x013, 0x0001429b, - 0x013, 0x00010299, - 0x013, 0x0000c29c, - 0x013, 0x000081a0, - 0x013, 0x000040ac, - 0x013, 0x00000020, - 0x014, 0x0001944c, - 0x014, 0x00059444, - 0x014, 0x0009944c, - 0x014, 0x000d9444, - 0x015, 0x0000f424, - 0x015, 0x0004f407, - 0x015, 0x0008f424, - 0x015, 0x000cf424, - 0x016, 0x00000339, - 0x016, 0x00040339, - 0x016, 0x00080339, - 0x016, 0x000c0336, - 0x000, 0x00010159, - 0x018, 0x0000f401, - 0x0fe, 0x00000000, - 0x0fe, 0x00000000, - 0x01f, 0x00080003, - 0x0fe, 0x00000000, - 0x0fe, 0x00000000, - 0x01e, 0x00044457, - 0x01f, 0x00080000, - 0x000, 0x00030159, -}; - - -u32 RTL8723E_RADIOB_1TARRAY[RTL8723E_RADIOB_1TARRAYLENGTH] = { - 0x0, -}; - - -u32 RTL8723EMAC_ARRAY[RTL8723E_MACARRAYLENGTH] = { - 0x420, 0x00000080, - 0x423, 0x00000000, - 0x430, 0x00000000, - 0x431, 0x00000000, - 0x432, 0x00000000, - 0x433, 0x00000001, - 0x434, 0x00000004, - 0x435, 0x00000005, - 0x436, 0x00000006, - 0x437, 0x00000007, - 0x438, 0x00000000, - 0x439, 0x00000000, - 0x43a, 0x00000000, - 0x43b, 0x00000001, - 0x43c, 0x00000004, - 0x43d, 0x00000005, - 0x43e, 0x00000006, - 0x43f, 0x00000007, - 0x440, 0x0000005d, - 0x441, 0x00000001, - 0x442, 0x00000000, - 0x444, 0x00000015, - 0x445, 0x000000f0, - 0x446, 0x0000000f, - 0x447, 0x00000000, - 0x458, 0x00000041, - 0x459, 0x000000a8, - 0x45a, 0x00000072, - 0x45b, 0x000000b9, - 0x460, 0x00000066, - 0x461, 0x00000066, - 0x462, 0x00000008, - 0x463, 0x00000003, - 0x4c8, 0x000000ff, - 0x4c9, 0x00000008, - 0x4cc, 0x000000ff, - 0x4cd, 0x000000ff, - 0x4ce, 0x00000001, - 0x500, 0x00000026, - 0x501, 0x000000a2, - 0x502, 0x0000002f, - 0x503, 0x00000000, - 0x504, 0x00000028, - 0x505, 0x000000a3, - 0x506, 0x0000005e, - 0x507, 0x00000000, - 0x508, 0x0000002b, - 0x509, 0x000000a4, - 0x50a, 0x0000005e, - 0x50b, 0x00000000, - 0x50c, 0x0000004f, - 0x50d, 0x000000a4, - 0x50e, 0x00000000, - 0x50f, 0x00000000, - 0x512, 0x0000001c, - 0x514, 0x0000000a, - 0x515, 0x00000010, - 0x516, 0x0000000a, - 0x517, 0x00000010, - 0x51a, 0x00000016, - 0x524, 0x0000000f, - 0x525, 0x0000004f, - 0x546, 0x00000040, - 0x547, 0x00000000, - 0x550, 0x00000010, - 0x551, 0x00000010, - 0x559, 0x00000002, - 0x55a, 0x00000002, - 0x55d, 0x000000ff, - 0x605, 0x00000030, - 0x608, 0x0000000e, - 0x609, 0x0000002a, - 0x652, 0x00000020, - 0x63c, 0x0000000a, - 0x63d, 0x0000000e, - 0x63e, 0x0000000a, - 0x63f, 0x0000000e, - 0x66e, 0x00000005, - 0x700, 0x00000021, - 0x701, 0x00000043, - 0x702, 0x00000065, - 0x703, 0x00000087, - 0x708, 0x00000021, - 0x709, 0x00000043, - 0x70a, 0x00000065, - 0x70b, 0x00000087, -}; - -u32 RTL8723EAGCTAB_1TARRAY[RTL8723E_AGCTAB_1TARRAYLENGTH] = { - 0xc78, 0x7b000001, - 0xc78, 0x7b010001, - 0xc78, 0x7b020001, - 0xc78, 0x7b030001, - 0xc78, 0x7b040001, - 0xc78, 0x7b050001, - 0xc78, 0x7a060001, - 0xc78, 0x79070001, - 0xc78, 0x78080001, - 0xc78, 0x77090001, - 0xc78, 0x760a0001, - 0xc78, 0x750b0001, - 0xc78, 0x740c0001, - 0xc78, 0x730d0001, - 0xc78, 0x720e0001, - 0xc78, 0x710f0001, - 0xc78, 0x70100001, - 0xc78, 0x6f110001, - 0xc78, 0x6e120001, - 0xc78, 0x6d130001, - 0xc78, 0x6c140001, - 0xc78, 0x6b150001, - 0xc78, 0x6a160001, - 0xc78, 0x69170001, - 0xc78, 0x68180001, - 0xc78, 0x67190001, - 0xc78, 0x661a0001, - 0xc78, 0x651b0001, - 0xc78, 0x641c0001, - 0xc78, 0x631d0001, - 0xc78, 0x621e0001, - 0xc78, 0x611f0001, - 0xc78, 0x60200001, - 0xc78, 0x49210001, - 0xc78, 0x48220001, - 0xc78, 0x47230001, - 0xc78, 0x46240001, - 0xc78, 0x45250001, - 0xc78, 0x44260001, - 0xc78, 0x43270001, - 0xc78, 0x42280001, - 0xc78, 0x41290001, - 0xc78, 0x402a0001, - 0xc78, 0x262b0001, - 0xc78, 0x252c0001, - 0xc78, 0x242d0001, - 0xc78, 0x232e0001, - 0xc78, 0x222f0001, - 0xc78, 0x21300001, - 0xc78, 0x20310001, - 0xc78, 0x06320001, - 0xc78, 0x05330001, - 0xc78, 0x04340001, - 0xc78, 0x03350001, - 0xc78, 0x02360001, - 0xc78, 0x01370001, - 0xc78, 0x00380001, - 0xc78, 0x00390001, - 0xc78, 0x003a0001, - 0xc78, 0x003b0001, - 0xc78, 0x003c0001, - 0xc78, 0x003d0001, - 0xc78, 0x003e0001, - 0xc78, 0x003f0001, - 0xc78, 0x7b400001, - 0xc78, 0x7b410001, - 0xc78, 0x7b420001, - 0xc78, 0x7b430001, - 0xc78, 0x7b440001, - 0xc78, 0x7b450001, - 0xc78, 0x7a460001, - 0xc78, 0x79470001, - 0xc78, 0x78480001, - 0xc78, 0x77490001, - 0xc78, 0x764a0001, - 0xc78, 0x754b0001, - 0xc78, 0x744c0001, - 0xc78, 0x734d0001, - 0xc78, 0x724e0001, - 0xc78, 0x714f0001, - 0xc78, 0x70500001, - 0xc78, 0x6f510001, - 0xc78, 0x6e520001, - 0xc78, 0x6d530001, - 0xc78, 0x6c540001, - 0xc78, 0x6b550001, - 0xc78, 0x6a560001, - 0xc78, 0x69570001, - 0xc78, 0x68580001, - 0xc78, 0x67590001, - 0xc78, 0x665a0001, - 0xc78, 0x655b0001, - 0xc78, 0x645c0001, - 0xc78, 0x635d0001, - 0xc78, 0x625e0001, - 0xc78, 0x615f0001, - 0xc78, 0x60600001, - 0xc78, 0x49610001, - 0xc78, 0x48620001, - 0xc78, 0x47630001, - 0xc78, 0x46640001, - 0xc78, 0x45650001, - 0xc78, 0x44660001, - 0xc78, 0x43670001, - 0xc78, 0x42680001, - 0xc78, 0x41690001, - 0xc78, 0x406a0001, - 0xc78, 0x266b0001, - 0xc78, 0x256c0001, - 0xc78, 0x246d0001, - 0xc78, 0x236e0001, - 0xc78, 0x226f0001, - 0xc78, 0x21700001, - 0xc78, 0x20710001, - 0xc78, 0x06720001, - 0xc78, 0x05730001, - 0xc78, 0x04740001, - 0xc78, 0x03750001, - 0xc78, 0x02760001, - 0xc78, 0x01770001, - 0xc78, 0x00780001, - 0xc78, 0x00790001, - 0xc78, 0x007a0001, - 0xc78, 0x007b0001, - 0xc78, 0x007c0001, - 0xc78, 0x007d0001, - 0xc78, 0x007e0001, - 0xc78, 0x007f0001, - 0xc78, 0x3800001e, - 0xc78, 0x3801001e, - 0xc78, 0x3802001e, - 0xc78, 0x3803001e, - 0xc78, 0x3804001e, - 0xc78, 0x3805001e, - 0xc78, 0x3806001e, - 0xc78, 0x3807001e, - 0xc78, 0x3808001e, - 0xc78, 0x3c09001e, - 0xc78, 0x3e0a001e, - 0xc78, 0x400b001e, - 0xc78, 0x440c001e, - 0xc78, 0x480d001e, - 0xc78, 0x4c0e001e, - 0xc78, 0x500f001e, - 0xc78, 0x5210001e, - 0xc78, 0x5611001e, - 0xc78, 0x5a12001e, - 0xc78, 0x5e13001e, - 0xc78, 0x6014001e, - 0xc78, 0x6015001e, - 0xc78, 0x6016001e, - 0xc78, 0x6217001e, - 0xc78, 0x6218001e, - 0xc78, 0x6219001e, - 0xc78, 0x621a001e, - 0xc78, 0x621b001e, - 0xc78, 0x621c001e, - 0xc78, 0x621d001e, - 0xc78, 0x621e001e, - 0xc78, 0x621f001e, -}; diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/table.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/table.h deleted file mode 100644 index f5ce71375c20..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/table.h +++ /dev/null @@ -1,50 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Created on 2010/ 5/18, 1:41 - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL8723E_TABLE__H_ -#define __RTL8723E_TABLE__H_ - -#include - -#define RTL8723E_PHY_REG_1TARRAY_LENGTH 372 -extern u32 RTL8723EPHY_REG_1TARRAY[RTL8723E_PHY_REG_1TARRAY_LENGTH]; -#define RTL8723E_PHY_REG_ARRAY_PGLENGTH 336 -extern u32 RTL8723EPHY_REG_ARRAY_PG[RTL8723E_PHY_REG_ARRAY_PGLENGTH]; -#define Rtl8723ERADIOA_1TARRAYLENGTH 282 -extern u32 RTL8723E_RADIOA_1TARRAY[Rtl8723ERADIOA_1TARRAYLENGTH]; -#define RTL8723E_RADIOB_1TARRAYLENGTH 1 -extern u32 RTL8723E_RADIOB_1TARRAY[RTL8723E_RADIOB_1TARRAYLENGTH]; -#define RTL8723E_MACARRAYLENGTH 172 -extern u32 RTL8723EMAC_ARRAY[RTL8723E_MACARRAYLENGTH]; -#define RTL8723E_AGCTAB_1TARRAYLENGTH 320 -extern u32 RTL8723EAGCTAB_1TARRAY[RTL8723E_AGCTAB_1TARRAYLENGTH]; - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c deleted file mode 100644 index 87331d826d73..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/trx.c +++ /dev/null @@ -1,670 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#include "../wifi.h" -#include "../pci.h" -#include "../base.h" -#include "../stats.h" -#include "reg.h" -#include "def.h" -#include "phy.h" -#include "trx.h" -#include "led.h" - -static u8 _rtl8723ae_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue) -{ - __le16 fc = rtl_get_fc(skb); - - if (unlikely(ieee80211_is_beacon(fc))) - return QSLT_BEACON; - if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc)) - return QSLT_MGNT; - - return skb->priority; -} - -static void _rtl8723ae_query_rxphystatus(struct ieee80211_hw *hw, - struct rtl_stats *pstatus, u8 *pdesc, - struct rx_fwinfo_8723e *p_drvinfo, - bool bpacket_match_bssid, - bool bpacket_toself, bool packet_beacon) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv); - struct phy_sts_cck_8723e_t *cck_buf; - s8 rx_pwr_all, rx_pwr[4]; - u8 rf_rx_num = 0, evm, pwdb_all; - u8 i, max_spatial_stream; - u32 rssi, total_rssi = 0; - bool is_cck = pstatus->is_cck; - - /* Record it for next packet processing */ - pstatus->packet_matchbssid = bpacket_match_bssid; - pstatus->packet_toself = bpacket_toself; - pstatus->packet_beacon = packet_beacon; - pstatus->rx_mimo_sig_qual[0] = -1; - pstatus->rx_mimo_sig_qual[1] = -1; - - if (is_cck) { - u8 report, cck_highpwr; - - /* CCK Driver info Structure is not the same as OFDM packet. */ - cck_buf = (struct phy_sts_cck_8723e_t *)p_drvinfo; - - /* (1)Hardware does not provide RSSI for CCK - * (2)PWDB, Average PWDB cacluated by - * hardware (for rate adaptive) - */ - if (ppsc->rfpwr_state == ERFON) - cck_highpwr = (u8) rtl_get_bbreg(hw, - RFPGA0_XA_HSSIPARAMETER2, - BIT(9)); - else - cck_highpwr = false; - - if (!cck_highpwr) { - u8 cck_agc_rpt = cck_buf->cck_agc_rpt; - report = cck_buf->cck_agc_rpt & 0xc0; - report = report >> 6; - switch (report) { - case 0x3: - rx_pwr_all = -46 - (cck_agc_rpt & 0x3e); - break; - case 0x2: - rx_pwr_all = -26 - (cck_agc_rpt & 0x3e); - break; - case 0x1: - rx_pwr_all = -12 - (cck_agc_rpt & 0x3e); - break; - case 0x0: - rx_pwr_all = 16 - (cck_agc_rpt & 0x3e); - break; - } - } else { - u8 cck_agc_rpt = cck_buf->cck_agc_rpt; - report = p_drvinfo->cfosho[0] & 0x60; - report = report >> 5; - switch (report) { - case 0x3: - rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f) << 1); - break; - case 0x2: - rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f) << 1); - break; - case 0x1: - rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f) << 1); - break; - case 0x0: - rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f) << 1); - break; - } - } - - pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all); - /* CCK gain is smaller than OFDM/MCS gain, - * so we add gain diff. From experience, the val is 6 - */ - pwdb_all += 6; - if (pwdb_all > 100) - pwdb_all = 100; - /* modify the offset to make the same - * gain index with OFDM. - */ - if (pwdb_all > 34 && pwdb_all <= 42) - pwdb_all -= 2; - else if (pwdb_all > 26 && pwdb_all <= 34) - pwdb_all -= 6; - else if (pwdb_all > 14 && pwdb_all <= 26) - pwdb_all -= 8; - else if (pwdb_all > 4 && pwdb_all <= 14) - pwdb_all -= 4; - - pstatus->rx_pwdb_all = pwdb_all; - pstatus->recvsignalpower = rx_pwr_all; - - /* (3) Get Signal Quality (EVM) */ - if (bpacket_match_bssid) { - u8 sq; - - if (pstatus->rx_pwdb_all > 40) { - sq = 100; - } else { - sq = cck_buf->sq_rpt; - if (sq > 64) - sq = 0; - else if (sq < 20) - sq = 100; - else - sq = ((64 - sq) * 100) / 44; - } - - pstatus->signalquality = sq; - pstatus->rx_mimo_sig_qual[0] = sq; - pstatus->rx_mimo_sig_qual[1] = -1; - } - } else { - rtlpriv->dm.rfpath_rxenable[0] = - rtlpriv->dm.rfpath_rxenable[1] = true; - - /* (1)Get RSSI for HT rate */ - for (i = RF90_PATH_A; i < RF6052_MAX_PATH; i++) { - - /* we will judge RF RX path now. */ - if (rtlpriv->dm.rfpath_rxenable[i]) - rf_rx_num++; - - rx_pwr[i] = ((p_drvinfo->gain_trsw[i] & 0x3f)*2) - 110; - - /* Translate DBM to percentage. */ - rssi = rtl_query_rxpwrpercentage(rx_pwr[i]); - total_rssi += rssi; - - /* Get Rx snr value in DB */ - rtlpriv->stats.rx_snr_db[i] = (p_drvinfo->rxsnr[i] / 2); - - /* Record Signal Strength for next packet */ - if (bpacket_match_bssid) - pstatus->rx_mimo_signalstrength[i] = (u8) rssi; - } - - /* (2)PWDB, Average PWDB cacluated by - * hardware (for rate adaptive) - */ - rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110; - - pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all); - pstatus->rx_pwdb_all = pwdb_all; - pstatus->rxpower = rx_pwr_all; - pstatus->recvsignalpower = rx_pwr_all; - - /* (3)EVM of HT rate */ - if (pstatus->is_ht && pstatus->rate >= DESC92_RATEMCS8 && - pstatus->rate <= DESC92_RATEMCS15) - max_spatial_stream = 2; - else - max_spatial_stream = 1; - - for (i = 0; i < max_spatial_stream; i++) { - evm = rtl_evm_db_to_percentage(p_drvinfo->rxevm[i]); - - if (bpacket_match_bssid) { - /* Fill value in RFD, Get the first - * spatial stream only - */ - if (i == 0) - pstatus->signalquality = (evm & 0xff); - pstatus->rx_mimo_sig_qual[i] = (evm & 0xff); - } - } - } - - /* UI BSS List signal strength(in percentage), - * make it good looking, from 0~100. - */ - if (is_cck) - pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw, - pwdb_all)); - else if (rf_rx_num != 0) - pstatus->signalstrength = (u8)(rtl_signal_scale_mapping(hw, - total_rssi /= rf_rx_num)); -} - -static void _rtl8723ae_translate_rx_signal_stuff(struct ieee80211_hw *hw, - struct sk_buff *skb, struct rtl_stats *pstatus, - u8 *pdesc, struct rx_fwinfo_8723e *p_drvinfo) -{ - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - struct ieee80211_hdr *hdr; - u8 *tmp_buf; - u8 *praddr; - u8 *psaddr; - __le16 fc; - u16 type; - bool packet_matchbssid, packet_toself, packet_beacon; - - tmp_buf = skb->data + pstatus->rx_drvinfo_size + pstatus->rx_bufshift; - - hdr = (struct ieee80211_hdr *)tmp_buf; - fc = hdr->frame_control; - type = WLAN_FC_GET_TYPE(fc); - praddr = hdr->addr1; - psaddr = ieee80211_get_SA(hdr); - - packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) && - (!compare_ether_addr(mac->bssid, - (le16_to_cpu(fc) & IEEE80211_FCTL_TODS) ? - hdr->addr1 : (le16_to_cpu(fc) & - IEEE80211_FCTL_FROMDS) ? - hdr->addr2 : hdr->addr3)) && (!pstatus->hwerror) && - (!pstatus->crc) && (!pstatus->icv)); - - packet_toself = packet_matchbssid && - (!compare_ether_addr(praddr, rtlefuse->dev_addr)); - - if (ieee80211_is_beacon(fc)) - packet_beacon = true; - - _rtl8723ae_query_rxphystatus(hw, pstatus, pdesc, p_drvinfo, - packet_matchbssid, packet_toself, - packet_beacon); - - rtl_process_phyinfo(hw, tmp_buf, pstatus); -} - -bool rtl8723ae_rx_query_desc(struct ieee80211_hw *hw, - struct rtl_stats *status, - struct ieee80211_rx_status *rx_status, - u8 *pdesc, struct sk_buff *skb) -{ - struct rx_fwinfo_8723e *p_drvinfo; - struct ieee80211_hdr *hdr; - u32 phystatus = GET_RX_DESC_PHYST(pdesc); - - status->length = (u16) GET_RX_DESC_PKT_LEN(pdesc); - status->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) * - RX_DRV_INFO_SIZE_UNIT; - status->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03); - status->icv = (u16) GET_RX_DESC_ICV(pdesc); - status->crc = (u16) GET_RX_DESC_CRC32(pdesc); - status->hwerror = (status->crc | status->icv); - status->decrypted = !GET_RX_DESC_SWDEC(pdesc); - status->rate = (u8) GET_RX_DESC_RXMCS(pdesc); - status->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc); - status->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1); - status->isfirst_ampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1) - && (GET_RX_DESC_FAGGR(pdesc) == 1)); - status->timestamp_low = GET_RX_DESC_TSFL(pdesc); - status->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc); - status->is_ht = (bool)GET_RX_DESC_RXHT(pdesc); - - status->is_cck = RTL8723E_RX_HAL_IS_CCK_RATE(status->rate); - - rx_status->freq = hw->conf.channel->center_freq; - rx_status->band = hw->conf.channel->band; - - hdr = (struct ieee80211_hdr *)(skb->data + status->rx_drvinfo_size - + status->rx_bufshift); - - if (status->crc) - rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; - - if (status->rx_is40Mhzpacket) - rx_status->flag |= RX_FLAG_40MHZ; - - if (status->is_ht) - rx_status->flag |= RX_FLAG_HT; - - rx_status->flag |= RX_FLAG_MACTIME_START; - - /* hw will set status->decrypted true, if it finds the - * frame is open data frame or mgmt frame. - * Thus hw will not decrypt a robust managment frame - * for IEEE80211w but still set status->decrypted - * true, so here we should set it back to undecrypted - * for IEEE80211w frame, and mac80211 sw will help - * to decrypt it - */ - if (status->decrypted) { - if ((ieee80211_is_robust_mgmt_frame(hdr)) && - (ieee80211_has_protected(hdr->frame_control))) - rx_status->flag &= ~RX_FLAG_DECRYPTED; - else - rx_status->flag |= RX_FLAG_DECRYPTED; - } - - /* rate_idx: index of data rate into band's - * supported rates or MCS index if HT rates - * are use (RX_FLAG_HT) - */ - rx_status->rate_idx = rtlwifi_rate_mapping(hw, status->is_ht, - status->rate, false); - - rx_status->mactime = status->timestamp_low; - if (phystatus == true) { - p_drvinfo = (struct rx_fwinfo_8723e *)(skb->data + - status->rx_bufshift); - - _rtl8723ae_translate_rx_signal_stuff(hw, - skb, status, pdesc, p_drvinfo); - } - - /*rx_status->qual = status->signal; */ - rx_status->signal = status->recvsignalpower + 10; - /*rx_status->noise = -status->noise; */ - - return true; -} - -void rtl8723ae_tx_fill_desc(struct ieee80211_hw *hw, - struct ieee80211_hdr *hdr, u8 *pdesc_tx, - struct ieee80211_tx_info *info, - struct ieee80211_sta *sta, - struct sk_buff *skb, u8 hw_queue, - struct rtl_tcb_desc *ptcdesc) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - bool defaultadapter = true; - u8 *pdesc = (u8 *) pdesc_tx; - u16 seq_number; - __le16 fc = hdr->frame_control; - u8 fw_qsel = _rtl8723ae_map_hwqueue_to_fwqueue(skb, hw_queue); - bool firstseg = ((hdr->seq_ctrl & - cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0); - bool lastseg = ((hdr->frame_control & - cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0); - dma_addr_t mapping = pci_map_single(rtlpci->pdev, - skb->data, skb->len, - PCI_DMA_TODEVICE); - u8 bw_40 = 0; - - if (mac->opmode == NL80211_IFTYPE_STATION) { - bw_40 = mac->bw_40; - } else if (mac->opmode == NL80211_IFTYPE_AP || - mac->opmode == NL80211_IFTYPE_ADHOC) { - if (sta) - bw_40 = sta->ht_cap.cap & - IEEE80211_HT_CAP_SUP_WIDTH_20_40; - } - - seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4; - - rtl_get_tcb_desc(hw, info, sta, skb, ptcdesc); - - CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_8723e)); - - if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) { - firstseg = true; - lastseg = true; - } - - if (firstseg) { - SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); - - SET_TX_DESC_TX_RATE(pdesc, ptcdesc->hw_rate); - - if (ptcdesc->use_shortgi || ptcdesc->use_shortpreamble) - SET_TX_DESC_DATA_SHORTGI(pdesc, 1); - - if (info->flags & IEEE80211_TX_CTL_AMPDU) { - SET_TX_DESC_AGG_BREAK(pdesc, 1); - SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14); - } - SET_TX_DESC_SEQ(pdesc, seq_number); - - SET_TX_DESC_RTS_ENABLE(pdesc, ((ptcdesc->rts_enable && - !ptcdesc-> - cts_enable) ? 1 : 0)); - SET_TX_DESC_HW_RTS_ENABLE(pdesc, - ((ptcdesc->rts_enable - || ptcdesc->cts_enable) ? 1 : 0)); - SET_TX_DESC_CTS2SELF(pdesc, ((ptcdesc->cts_enable) ? 1 : 0)); - SET_TX_DESC_RTS_STBC(pdesc, ((ptcdesc->rts_stbc) ? 1 : 0)); - - SET_TX_DESC_RTS_RATE(pdesc, ptcdesc->rts_rate); - SET_TX_DESC_RTS_BW(pdesc, 0); - SET_TX_DESC_RTS_SC(pdesc, ptcdesc->rts_sc); - SET_TX_DESC_RTS_SHORT(pdesc, - ((ptcdesc->rts_rate <= DESC92_RATE54M) ? - (ptcdesc->rts_use_shortpreamble ? 1 : 0) - : (ptcdesc->rts_use_shortgi ? 1 : 0))); - - if (bw_40) { - if (ptcdesc->packet_bw) { - SET_TX_DESC_DATA_BW(pdesc, 1); - SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3); - } else { - SET_TX_DESC_DATA_BW(pdesc, 0); - SET_TX_DESC_TX_SUB_CARRIER(pdesc, - mac->cur_40_prime_sc); - } - } else { - SET_TX_DESC_DATA_BW(pdesc, 0); - SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0); - } - - SET_TX_DESC_LINIP(pdesc, 0); - SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len); - - if (sta) { - u8 ampdu_density = sta->ht_cap.ampdu_density; - SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density); - } - - if (info->control.hw_key) { - struct ieee80211_key_conf *keyconf = - info->control.hw_key; - - switch (keyconf->cipher) { - case WLAN_CIPHER_SUITE_WEP40: - case WLAN_CIPHER_SUITE_WEP104: - case WLAN_CIPHER_SUITE_TKIP: - SET_TX_DESC_SEC_TYPE(pdesc, 0x1); - break; - case WLAN_CIPHER_SUITE_CCMP: - SET_TX_DESC_SEC_TYPE(pdesc, 0x3); - break; - default: - SET_TX_DESC_SEC_TYPE(pdesc, 0x0); - break; - } - } - - SET_TX_DESC_PKT_ID(pdesc, 0); - SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel); - - SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F); - SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF); - SET_TX_DESC_DISABLE_FB(pdesc, 0); - SET_TX_DESC_USE_RATE(pdesc, ptcdesc->use_driver_rate ? 1 : 0); - - if (ieee80211_is_data_qos(fc)) { - if (mac->rdg_en) { - RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, - "Enable RDG function.\n"); - SET_TX_DESC_RDG_ENABLE(pdesc, 1); - SET_TX_DESC_HTC(pdesc, 1); - } - } - } - - SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0)); - SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0)); - - SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len); - - SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping); - - if (rtlpriv->dm.useramask) { - SET_TX_DESC_RATE_ID(pdesc, ptcdesc->ratr_index); - SET_TX_DESC_MACID(pdesc, ptcdesc->mac_id); - } else { - SET_TX_DESC_RATE_ID(pdesc, 0xC + ptcdesc->ratr_index); - SET_TX_DESC_MACID(pdesc, ptcdesc->ratr_index); - } - - if ((!ieee80211_is_data_qos(fc)) && ppsc->fwctrl_lps) { - SET_TX_DESC_HWSEQ_EN_8723(pdesc, 1); - - if (!defaultadapter) - SET_TX_DESC_HWSEQ_SEL_8723(pdesc, 1); - } - - SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1)); - - if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) || - is_broadcast_ether_addr(ieee80211_get_DA(hdr))) { - SET_TX_DESC_BMC(pdesc, 1); - } - - RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n"); -} - -void rtl8723ae_tx_fill_cmddesc(struct ieee80211_hw *hw, - u8 *pdesc, bool firstseg, - bool lastseg, struct sk_buff *skb) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data); - u8 fw_queue = QSLT_BEACON; - dma_addr_t mapping = pci_map_single(rtlpci->pdev, - skb->data, skb->len, - PCI_DMA_TODEVICE); - __le16 fc = hdr->frame_control; - - CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE); - - if (firstseg) - SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN); - - SET_TX_DESC_TX_RATE(pdesc, DESC92_RATE1M); - - SET_TX_DESC_SEQ(pdesc, 0); - - SET_TX_DESC_LINIP(pdesc, 0); - - SET_TX_DESC_QUEUE_SEL(pdesc, fw_queue); - - SET_TX_DESC_FIRST_SEG(pdesc, 1); - SET_TX_DESC_LAST_SEG(pdesc, 1); - - SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len)); - - SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping); - - SET_TX_DESC_RATE_ID(pdesc, 7); - SET_TX_DESC_MACID(pdesc, 0); - - SET_TX_DESC_OWN(pdesc, 1); - - SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len)); - - SET_TX_DESC_FIRST_SEG(pdesc, 1); - SET_TX_DESC_LAST_SEG(pdesc, 1); - - SET_TX_DESC_OFFSET(pdesc, 0x20); - - SET_TX_DESC_USE_RATE(pdesc, 1); - - if (!ieee80211_is_data_qos(fc)) { - SET_TX_DESC_HWSEQ_EN_8723(pdesc, 1); - /* SET_TX_DESC_HWSEQ_EN(pdesc, 1); */ - /* SET_TX_DESC_PKT_ID(pdesc, 8); */ - } - - RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, - "H2C Tx Cmd Content\n", - pdesc, TX_DESC_SIZE); -} - -void rtl8723ae_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) -{ - if (istx == true) { - switch (desc_name) { - case HW_DESC_OWN: - SET_TX_DESC_OWN(pdesc, 1); - break; - case HW_DESC_TX_NEXTDESC_ADDR: - SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val); - break; - default: - RT_ASSERT(false, "ERR txdesc :%d not process\n", - desc_name); - break; - } - } else { - switch (desc_name) { - case HW_DESC_RXOWN: - SET_RX_DESC_OWN(pdesc, 1); - break; - case HW_DESC_RXBUFF_ADDR: - SET_RX_DESC_BUFF_ADDR(pdesc, *(u32 *) val); - break; - case HW_DESC_RXPKT_LEN: - SET_RX_DESC_PKT_LEN(pdesc, *(u32 *) val); - break; - case HW_DESC_RXERO: - SET_RX_DESC_EOR(pdesc, 1); - break; - default: - RT_ASSERT(false, "ERR rxdesc :%d not process\n", - desc_name); - break; - } - } -} - -u32 rtl8723ae_get_desc(u8 *pdesc, bool istx, u8 desc_name) -{ - u32 ret = 0; - - if (istx == true) { - switch (desc_name) { - case HW_DESC_OWN: - ret = GET_TX_DESC_OWN(pdesc); - break; - case HW_DESC_TXBUFF_ADDR: - ret = GET_TX_DESC_TX_BUFFER_ADDRESS(pdesc); - break; - default: - RT_ASSERT(false, "ERR txdesc :%d not process\n", - desc_name); - break; - } - } else { - switch (desc_name) { - case HW_DESC_OWN: - ret = GET_RX_DESC_OWN(pdesc); - break; - case HW_DESC_RXPKT_LEN: - ret = GET_RX_DESC_PKT_LEN(pdesc); - break; - default: - RT_ASSERT(false, "ERR rxdesc :%d not process\n", - desc_name); - break; - } - } - return ret; -} - -void rtl8723ae_tx_polling(struct ieee80211_hw *hw, u8 hw_queue) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - if (hw_queue == BEACON_QUEUE) { - rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, BIT(4)); - } else { - rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, - BIT(0) << (hw_queue)); - } -} diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/trx.h b/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/trx.h deleted file mode 100644 index ad05b54bc0f1..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8723ae/trx.h +++ /dev/null @@ -1,725 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL8723E_TRX_H__ -#define __RTL8723E_TRX_H__ - -#define TX_DESC_SIZE 64 -#define TX_DESC_AGGR_SUBFRAME_SIZE 32 - -#define RX_DESC_SIZE 32 -#define RX_DRV_INFO_SIZE_UNIT 8 - -#define TX_DESC_NEXT_DESC_OFFSET 40 -#define USB_HWDESC_HEADER_LEN 32 -#define CRCLENGTH 4 - -#define SET_TX_DESC_PKT_SIZE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 0, 16, __val) -#define SET_TX_DESC_OFFSET(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 16, 8, __val) -#define SET_TX_DESC_BMC(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 24, 1, __val) -#define SET_TX_DESC_HTC(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 25, 1, __val) -#define SET_TX_DESC_LAST_SEG(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 26, 1, __val) -#define SET_TX_DESC_FIRST_SEG(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 27, 1, __val) -#define SET_TX_DESC_LINIP(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 28, 1, __val) -#define SET_TX_DESC_NO_ACM(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 29, 1, __val) -#define SET_TX_DESC_GF(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val) -#define SET_TX_DESC_OWN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val) - -#define GET_TX_DESC_PKT_SIZE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 0, 16) -#define GET_TX_DESC_OFFSET(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 16, 8) -#define GET_TX_DESC_BMC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 24, 1) -#define GET_TX_DESC_HTC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 25, 1) -#define GET_TX_DESC_LAST_SEG(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 26, 1) -#define GET_TX_DESC_FIRST_SEG(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 27, 1) -#define GET_TX_DESC_LINIP(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 28, 1) -#define GET_TX_DESC_NO_ACM(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 29, 1) -#define GET_TX_DESC_GF(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 30, 1) -#define GET_TX_DESC_OWN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 31, 1) - -#define SET_TX_DESC_MACID(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 0, 5, __val) -#define SET_TX_DESC_AGG_BREAK(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 5, 1, __val) -#define SET_TX_DESC_BK(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 6, 1, __val) -#define SET_TX_DESC_RDG_ENABLE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 7, 1, __val) -#define SET_TX_DESC_QUEUE_SEL(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 8, 5, __val) -#define SET_TX_DESC_RDG_NAV_EXT(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 13, 1, __val) -#define SET_TX_DESC_LSIG_TXOP_EN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 14, 1, __val) -#define SET_TX_DESC_PIFS(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 15, 1, __val) -#define SET_TX_DESC_RATE_ID(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 16, 4, __val) -#define SET_TX_DESC_NAV_USE_HDR(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 20, 1, __val) -#define SET_TX_DESC_EN_DESC_ID(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 21, 1, __val) -#define SET_TX_DESC_SEC_TYPE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 22, 2, __val) -#define SET_TX_DESC_PKT_OFFSET(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+4, 24, 8, __val) - -#define GET_TX_DESC_MACID(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 0, 5) -#define GET_TX_DESC_AGG_ENABLE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 5, 1) -#define GET_TX_DESC_AGG_BREAK(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 6, 1) -#define GET_TX_DESC_RDG_ENABLE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 7, 1) -#define GET_TX_DESC_QUEUE_SEL(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 8, 5) -#define GET_TX_DESC_RDG_NAV_EXT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 13, 1) -#define GET_TX_DESC_LSIG_TXOP_EN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 14, 1) -#define GET_TX_DESC_PIFS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 15, 1) -#define GET_TX_DESC_RATE_ID(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 16, 4) -#define GET_TX_DESC_NAV_USE_HDR(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 20, 1) -#define GET_TX_DESC_EN_DESC_ID(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 21, 1) -#define GET_TX_DESC_SEC_TYPE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 22, 2) -#define GET_TX_DESC_PKT_OFFSET(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 24, 8) - -#define SET_TX_DESC_RTS_RC(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 0, 6, __val) -#define SET_TX_DESC_DATA_RC(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 6, 6, __val) -#define SET_TX_DESC_BAR_RTY_TH(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 14, 2, __val) -#define SET_TX_DESC_MORE_FRAG(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 17, 1, __val) -#define SET_TX_DESC_RAW(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 18, 1, __val) -#define SET_TX_DESC_CCX(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 19, 1, __val) -#define SET_TX_DESC_AMPDU_DENSITY(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 20, 3, __val) -#define SET_TX_DESC_ANTSEL_A(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 24, 1, __val) -#define SET_TX_DESC_ANTSEL_B(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 25, 1, __val) -#define SET_TX_DESC_TX_ANT_CCK(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 26, 2, __val) -#define SET_TX_DESC_TX_ANTL(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 28, 2, __val) -#define SET_TX_DESC_TX_ANT_HT(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+8, 30, 2, __val) - -#define GET_TX_DESC_RTS_RC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 0, 6) -#define GET_TX_DESC_DATA_RC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 6, 6) -#define GET_TX_DESC_BAR_RTY_TH(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 14, 2) -#define GET_TX_DESC_MORE_FRAG(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 17, 1) -#define GET_TX_DESC_RAW(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 18, 1) -#define GET_TX_DESC_CCX(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 19, 1) -#define GET_TX_DESC_AMPDU_DENSITY(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 20, 3) -#define GET_TX_DESC_ANTSEL_A(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 24, 1) -#define GET_TX_DESC_ANTSEL_B(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 25, 1) -#define GET_TX_DESC_TX_ANT_CCK(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 26, 2) -#define GET_TX_DESC_TX_ANTL(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 28, 2) -#define GET_TX_DESC_TX_ANT_HT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 30, 2) - -#define SET_TX_DESC_NEXT_HEAP_PAGE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+12, 0, 8, __val) -#define SET_TX_DESC_TAIL_PAGE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+12, 8, 8, __val) -#define SET_TX_DESC_SEQ(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+12, 16, 12, __val) -#define SET_TX_DESC_PKT_ID(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+12, 28, 4, __val) - -#define GET_TX_DESC_NEXT_HEAP_PAGE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 0, 8) -#define GET_TX_DESC_TAIL_PAGE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 8, 8) -#define GET_TX_DESC_SEQ(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 16, 12) -#define GET_TX_DESC_PKT_ID(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 28, 4) - -/* For RTL8723 */ -#define SET_TX_DESC_TRIGGER_INT(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+12, 30, 1, __val) -#define SET_TX_DESC_HWSEQ_EN_8723(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+12, 31, 1, __val) -#define SET_TX_DESC_HWSEQ_SEL_8723(__pTxDesc, __Value) \ - SET_BITS_TO_LE_4BYTE(__pTxDesc+16, 6, 2, __Value) - -#define SET_TX_DESC_RTS_RATE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 0, 5, __val) -#define SET_TX_DESC_AP_DCFE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 5, 1, __val) -#define SET_TX_DESC_QOS(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 6, 1, __val) -#define SET_TX_DESC_HWSEQ_EN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 7, 1, __val) -#define SET_TX_DESC_USE_RATE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 8, 1, __val) -#define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 9, 1, __val) -#define SET_TX_DESC_DISABLE_FB(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 10, 1, __val) -#define SET_TX_DESC_CTS2SELF(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 11, 1, __val) -#define SET_TX_DESC_RTS_ENABLE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 12, 1, __val) -#define SET_TX_DESC_HW_RTS_ENABLE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 13, 1, __val) -#define SET_TX_DESC_PORT_ID(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 14, 1, __val) -#define SET_TX_DESC_WAIT_DCTS(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 18, 1, __val) -#define SET_TX_DESC_CTS2AP_EN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 19, 1, __val) -#define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 20, 2, __val) -#define SET_TX_DESC_TX_STBC(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 22, 2, __val) -#define SET_TX_DESC_DATA_SHORT(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 24, 1, __val) -#define SET_TX_DESC_DATA_BW(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 25, 1, __val) -#define SET_TX_DESC_RTS_SHORT(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 26, 1, __val) -#define SET_TX_DESC_RTS_BW(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 27, 1, __val) -#define SET_TX_DESC_RTS_SC(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 28, 2, __val) -#define SET_TX_DESC_RTS_STBC(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+16, 30, 2, __val) - -#define GET_TX_DESC_RTS_RATE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 0, 5) -#define GET_TX_DESC_AP_DCFE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 5, 1) -#define GET_TX_DESC_QOS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 6, 1) -#define GET_TX_DESC_HWSEQ_EN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 7, 1) -#define GET_TX_DESC_USE_RATE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 8, 1) -#define GET_TX_DESC_DISABLE_RTS_FB(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 9, 1) -#define GET_TX_DESC_DISABLE_FB(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 10, 1) -#define GET_TX_DESC_CTS2SELF(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 11, 1) -#define GET_TX_DESC_RTS_ENABLE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 12, 1) -#define GET_TX_DESC_HW_RTS_ENABLE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 13, 1) -#define GET_TX_DESC_PORT_ID(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 14, 1) -#define GET_TX_DESC_WAIT_DCTS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 18, 1) -#define GET_TX_DESC_CTS2AP_EN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 19, 1) -#define GET_TX_DESC_TX_SUB_CARRIER(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 20, 2) -#define GET_TX_DESC_TX_STBC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 22, 2) -#define GET_TX_DESC_DATA_SHORT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 24, 1) -#define GET_TX_DESC_DATA_BW(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 25, 1) -#define GET_TX_DESC_RTS_SHORT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 26, 1) -#define GET_TX_DESC_RTS_BW(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 27, 1) -#define GET_TX_DESC_RTS_SC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 28, 2) -#define GET_TX_DESC_RTS_STBC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 30, 2) - -#define SET_TX_DESC_TX_RATE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 0, 6, __val) -#define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 6, 1, __val) -#define SET_TX_DESC_CCX_TAG(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 7, 1, __val) -#define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 8, 5, __val) -#define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 13, 4, __val) -#define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 17, 1, __val) -#define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 18, 6, __val) -#define SET_TX_DESC_USB_TXAGG_NUM(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+20, 24, 8, __val) - -#define GET_TX_DESC_TX_RATE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 0, 6) -#define GET_TX_DESC_DATA_SHORTGI(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 6, 1) -#define GET_TX_DESC_CCX_TAG(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 7, 1) -#define GET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 8, 5) -#define GET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 13, 4) -#define GET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 17, 1) -#define GET_TX_DESC_DATA_RETRY_LIMIT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 18, 6) -#define GET_TX_DESC_USB_TXAGG_NUM(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 24, 8) - -#define SET_TX_DESC_TXAGC_A(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 5, __val) -#define SET_TX_DESC_TXAGC_B(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 5, 5, __val) -#define SET_TX_DESC_USE_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 10, 1, __val) -#define SET_TX_DESC_MAX_AGG_NUM(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 11, 5, __val) -#define SET_TX_DESC_MCSG1_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 16, 4, __val) -#define SET_TX_DESC_MCSG2_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 20, 4, __val) -#define SET_TX_DESC_MCSG3_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 24, 4, __val) -#define SET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc, __val)\ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 28, 4, __val) - -#define GET_TX_DESC_TXAGC_A(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 0, 5) -#define GET_TX_DESC_TXAGC_B(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 5, 5) -#define GET_TX_DESC_USE_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 10, 1) -#define GET_TX_DESC_MAX_AGG_NUM(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 11, 5) -#define GET_TX_DESC_MCSG1_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 16, 4) -#define GET_TX_DESC_MCSG2_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 20, 4) -#define GET_TX_DESC_MCSG3_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 24, 4) -#define GET_TX_DESC_MCS7_SGI_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 28, 4) - -#define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 16, __val) -#define SET_TX_DESC_MCSG4_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+28, 16, 4, __val) -#define SET_TX_DESC_MCSG5_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+28, 20, 4, __val) -#define SET_TX_DESC_MCSG6_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+28, 24, 4, __val) -#define SET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+28, 28, 4, __val) - -#define GET_TX_DESC_TX_BUFFER_SIZE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+28, 0, 16) -#define GET_TX_DESC_MCSG4_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+28, 16, 4) -#define GET_TX_DESC_MCSG5_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+28, 20, 4) -#define GET_TX_DESC_MCSG6_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+28, 24, 4) -#define GET_TX_DESC_MCS15_SGI_MAX_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+28, 28, 4) - -#define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+32, 0, 32, __val) -#define SET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+36, 0, 32, __val) - -#define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+32, 0, 32) -#define GET_TX_DESC_TX_BUFFER_ADDRESS64(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+36, 0, 32) - -#define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+40, 0, 32, __val) -#define SET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+44, 0, 32, __val) - -#define GET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+40, 0, 32) -#define GET_TX_DESC_NEXT_DESC_ADDRESS64(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+44, 0, 32) - -#define GET_RX_DESC_PKT_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 0, 14) -#define GET_RX_DESC_CRC32(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 14, 1) -#define GET_RX_DESC_ICV(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 15, 1) -#define GET_RX_DESC_DRV_INFO_SIZE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 16, 4) -#define GET_RX_DESC_SECURITY(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 20, 3) -#define GET_RX_DESC_QOS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 23, 1) -#define GET_RX_DESC_SHIFT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 24, 2) -#define GET_RX_DESC_PHYST(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 26, 1) -#define GET_RX_DESC_SWDEC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 27, 1) -#define GET_RX_DESC_LS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 28, 1) -#define GET_RX_DESC_FS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 29, 1) -#define GET_RX_DESC_EOR(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 30, 1) -#define GET_RX_DESC_OWN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc, 31, 1) - -#define SET_RX_DESC_PKT_LEN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 0, 14, __val) -#define SET_RX_DESC_EOR(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 30, 1, __val) -#define SET_RX_DESC_OWN(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc, 31, 1, __val) - -#define GET_RX_DESC_MACID(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 0, 5) -#define GET_RX_DESC_TID(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 5, 4) -#define GET_RX_DESC_HWRSVD(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 9, 5) -#define GET_RX_DESC_PAGGR(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 14, 1) -#define GET_RX_DESC_FAGGR(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 15, 1) -#define GET_RX_DESC_A1_FIT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 16, 4) -#define GET_RX_DESC_A2_FIT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 20, 4) -#define GET_RX_DESC_PAM(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 24, 1) -#define GET_RX_DESC_PWR(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 25, 1) -#define GET_RX_DESC_MD(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 26, 1) -#define GET_RX_DESC_MF(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 27, 1) -#define GET_RX_DESC_TYPE(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 28, 2) -#define GET_RX_DESC_MC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 30, 1) -#define GET_RX_DESC_BC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+4, 31, 1) -#define GET_RX_DESC_SEQ(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 0, 12) -#define GET_RX_DESC_FRAG(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 12, 4) -#define GET_RX_DESC_NEXT_PKT_LEN(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 16, 14) -#define GET_RX_DESC_NEXT_IND(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 30, 1) -#define GET_RX_DESC_RSVD(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+8, 31, 1) - -#define GET_RX_DESC_RXMCS(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 0, 6) -#define GET_RX_DESC_RXHT(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 6, 1) -#define GET_RX_DESC_SPLCP(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 8, 1) -#define GET_RX_DESC_BW(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 9, 1) -#define GET_RX_DESC_HTC(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 10, 1) -#define GET_RX_DESC_HWPC_ERR(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 14, 1) -#define GET_RX_DESC_HWPC_IND(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 15, 1) -#define GET_RX_DESC_IV0(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+12, 16, 16) - -#define GET_RX_DESC_IV1(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+16, 0, 32) -#define GET_RX_DESC_TSFL(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+20, 0, 32) - -#define GET_RX_DESC_BUFF_ADDR(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+24, 0, 32) -#define GET_RX_DESC_BUFF_ADDR64(__pdesc) \ - LE_BITS_TO_4BYTE(__pdesc+28, 0, 32) - -#define SET_RX_DESC_BUFF_ADDR(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+24, 0, 32, __val) -#define SET_RX_DESC_BUFF_ADDR64(__pdesc, __val) \ - SET_BITS_TO_LE_4BYTE(__pdesc+28, 0, 32, __val) - -#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size) \ -do { \ - if (_size > TX_DESC_NEXT_DESC_OFFSET) \ - memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET); \ - else \ - memset(__pdesc, 0, _size); \ -} while (0) - -#define RTL8723E_RX_HAL_IS_CCK_RATE(rxmcs) \ - ((rxmcs) == DESC92_RATE1M || \ - (rxmcs) == DESC92_RATE2M || \ - (rxmcs) == DESC92_RATE5_5M || \ - (rxmcs) == DESC92_RATE11M) - -struct rx_fwinfo_8723e { - u8 gain_trsw[4]; - u8 pwdb_all; - u8 cfosho[4]; - u8 cfotail[4]; - char rxevm[2]; - char rxsnr[4]; - u8 pdsnr[2]; - u8 csi_current[2]; - u8 csi_target[2]; - u8 sigevm; - u8 max_ex_pwr; - u8 ex_intf_flag:1; - u8 sgi_en:1; - u8 rxsc:2; - u8 reserve:4; -} __packed; - -struct tx_desc_8723e { - u32 pktsize:16; - u32 offset:8; - u32 bmc:1; - u32 htc:1; - u32 lastseg:1; - u32 firstseg:1; - u32 linip:1; - u32 noacm:1; - u32 gf:1; - u32 own:1; - - u32 macid:5; - u32 agg_en:1; - u32 bk:1; - u32 rdg_en:1; - u32 queuesel:5; - u32 rd_nav_ext:1; - u32 lsig_txop_en:1; - u32 pifs:1; - u32 rateid:4; - u32 nav_usehdr:1; - u32 en_descid:1; - u32 sectype:2; - u32 pktoffset:8; - - u32 rts_rc:6; - u32 data_rc:6; - u32 rsvd0:2; - u32 bar_retryht:2; - u32 rsvd1:1; - u32 morefrag:1; - u32 raw:1; - u32 ccx:1; - u32 ampdudensity:3; - u32 rsvd2:1; - u32 ant_sela:1; - u32 ant_selb:1; - u32 txant_cck:2; - u32 txant_l:2; - u32 txant_ht:2; - - u32 nextheadpage:8; - u32 tailpage:8; - u32 seq:12; - u32 pktid:4; - - u32 rtsrate:5; - u32 apdcfe:1; - u32 qos:1; - u32 hwseq_enable:1; - u32 userrate:1; - u32 dis_rtsfb:1; - u32 dis_datafb:1; - u32 cts2self:1; - u32 rts_en:1; - u32 hwrts_en:1; - u32 portid:1; - u32 rsvd3:3; - u32 waitdcts:1; - u32 cts2ap_en:1; - u32 txsc:2; - u32 stbc:2; - u32 txshort:1; - u32 txbw:1; - u32 rtsshort:1; - u32 rtsbw:1; - u32 rtssc:2; - u32 rtsstbc:2; - - u32 txrate:6; - u32 shortgi:1; - u32 ccxt:1; - u32 txrate_fb_lmt:5; - u32 rtsrate_fb_lmt:4; - u32 retrylmt_en:1; - u32 txretrylmt:6; - u32 usb_txaggnum:8; - - u32 txagca:5; - u32 txagcb:5; - u32 usemaxlen:1; - u32 maxaggnum:5; - u32 mcsg1maxlen:4; - u32 mcsg2maxlen:4; - u32 mcsg3maxlen:4; - u32 mcs7sgimaxlen:4; - - u32 txbuffersize:16; - u32 mcsg4maxlen:4; - u32 mcsg5maxlen:4; - u32 mcsg6maxlen:4; - u32 mcsg15sgimaxlen:4; - - u32 txbuffaddr; - u32 txbufferaddr64; - u32 nextdescaddress; - u32 nextdescaddress64; - - u32 reserve_pass_pcie_mm_limit[4]; -} __packed; - -struct rx_desc_8723e { - u32 length:14; - u32 crc32:1; - u32 icverror:1; - u32 drv_infosize:4; - u32 security:3; - u32 qos:1; - u32 shift:2; - u32 phystatus:1; - u32 swdec:1; - u32 lastseg:1; - u32 firstseg:1; - u32 eor:1; - u32 own:1; - - u32 macid:5; - u32 tid:4; - u32 hwrsvd:5; - u32 paggr:1; - u32 faggr:1; - u32 a1_fit:4; - u32 a2_fit:4; - u32 pam:1; - u32 pwr:1; - u32 moredata:1; - u32 morefrag:1; - u32 type:2; - u32 mc:1; - u32 bc:1; - - u32 seq:12; - u32 frag:4; - u32 nextpktlen:14; - u32 nextind:1; - u32 rsvd:1; - - u32 rxmcs:6; - u32 rxht:1; - u32 amsdu:1; - u32 splcp:1; - u32 bandwidth:1; - u32 htc:1; - u32 tcpchk_rpt:1; - u32 ipcchk_rpt:1; - u32 tcpchk_valid:1; - u32 hwpcerr:1; - u32 hwpcind:1; - u32 iv0:16; - - u32 iv1; - - u32 tsfl; - - u32 bufferaddress; - u32 bufferaddress64; - -} __packed; - -void rtl8723ae_tx_fill_desc(struct ieee80211_hw *hw, - struct ieee80211_hdr *hdr, u8 *pdesc_tx, - struct ieee80211_tx_info *info, - struct ieee80211_sta *sta, - struct sk_buff *skb, u8 hw_queue, - struct rtl_tcb_desc *ptcb_desc); -bool rtl8723ae_rx_query_desc(struct ieee80211_hw *hw, - struct rtl_stats *status, - struct ieee80211_rx_status *rx_status, - u8 *pdesc, struct sk_buff *skb); -void rtl8723ae_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val); -u32 rtl8723ae_get_desc(u8 *pdesc, bool istx, u8 desc_name); -void rtl8723ae_tx_polling(struct ieee80211_hw *hw, u8 hw_queue); -void rtl8723ae_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, - bool b_firstseg, bool b_lastseg, - struct sk_buff *skb); - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/stats.c b/trunk/drivers/net/wireless/rtlwifi/stats.c deleted file mode 100644 index 8ed31744a054..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/stats.c +++ /dev/null @@ -1,268 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ -#include "wifi.h" -#include "stats.h" -#include - -u8 rtl_query_rxpwrpercentage(char antpower) -{ - if ((antpower <= -100) || (antpower >= 20)) - return 0; - else if (antpower >= 0) - return 100; - else - return 100 + antpower; -} -EXPORT_SYMBOL(rtl_query_rxpwrpercentage); - -u8 rtl_evm_db_to_percentage(char value) -{ - char ret_val; - ret_val = value; - - if (ret_val >= 0) - ret_val = 0; - if (ret_val <= -33) - ret_val = -33; - ret_val = 0 - ret_val; - ret_val *= 3; - if (ret_val == 99) - ret_val = 100; - - return ret_val; -} -EXPORT_SYMBOL(rtl_evm_db_to_percentage); - -static long rtl_translate_todbm(struct ieee80211_hw *hw, - u8 signal_strength_index) -{ - long signal_power; - - signal_power = (long)((signal_strength_index + 1) >> 1); - signal_power -= 95; - return signal_power; -} - -long rtl_signal_scale_mapping(struct ieee80211_hw *hw, long currsig) -{ - long retsig; - - if (currsig >= 61 && currsig <= 100) - retsig = 90 + ((currsig - 60) / 4); - else if (currsig >= 41 && currsig <= 60) - retsig = 78 + ((currsig - 40) / 2); - else if (currsig >= 31 && currsig <= 40) - retsig = 66 + (currsig - 30); - else if (currsig >= 21 && currsig <= 30) - retsig = 54 + (currsig - 20); - else if (currsig >= 5 && currsig <= 20) - retsig = 42 + (((currsig - 5) * 2) / 3); - else if (currsig == 4) - retsig = 36; - else if (currsig == 3) - retsig = 27; - else if (currsig == 2) - retsig = 18; - else if (currsig == 1) - retsig = 9; - else - retsig = currsig; - - return retsig; -} -EXPORT_SYMBOL(rtl_signal_scale_mapping); - -static void rtl_process_ui_rssi(struct ieee80211_hw *hw, - struct rtl_stats *pstatus) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - u8 rfpath; - u32 last_rssi, tmpval; - - rtlpriv->stats.rssi_calculate_cnt++; - - if (rtlpriv->stats.ui_rssi.total_num++ >= PHY_RSSI_SLID_WIN_MAX) { - rtlpriv->stats.ui_rssi.total_num = PHY_RSSI_SLID_WIN_MAX; - last_rssi = rtlpriv->stats.ui_rssi.elements[ - rtlpriv->stats.ui_rssi.index]; - rtlpriv->stats.ui_rssi.total_val -= last_rssi; - } - rtlpriv->stats.ui_rssi.total_val += pstatus->signalstrength; - rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi.index++] = - pstatus->signalstrength; - if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX) - rtlpriv->stats.ui_rssi.index = 0; - tmpval = rtlpriv->stats.ui_rssi.total_val / - rtlpriv->stats.ui_rssi.total_num; - rtlpriv->stats.signal_strength = rtl_translate_todbm(hw, - (u8) tmpval); - pstatus->rssi = rtlpriv->stats.signal_strength; - - if (pstatus->is_cck) - return; - - for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; - rfpath++) { - if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) { - rtlpriv->stats.rx_rssi_percentage[rfpath] = - pstatus->rx_mimo_signalstrength[rfpath]; - - } - if (pstatus->rx_mimo_signalstrength[rfpath] > - rtlpriv->stats.rx_rssi_percentage[rfpath]) { - rtlpriv->stats.rx_rssi_percentage[rfpath] = - ((rtlpriv->stats.rx_rssi_percentage[rfpath] * - (RX_SMOOTH_FACTOR - 1)) + - (pstatus->rx_mimo_signalstrength[rfpath])) / - (RX_SMOOTH_FACTOR); - rtlpriv->stats.rx_rssi_percentage[rfpath] = - rtlpriv->stats.rx_rssi_percentage[rfpath] + 1; - } else { - rtlpriv->stats.rx_rssi_percentage[rfpath] = - ((rtlpriv->stats.rx_rssi_percentage[rfpath] * - (RX_SMOOTH_FACTOR - 1)) + - (pstatus->rx_mimo_signalstrength[rfpath])) / - (RX_SMOOTH_FACTOR); - } - } -} - -static void rtl_update_rxsignalstatistics(struct ieee80211_hw *hw, - struct rtl_stats *pstatus) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - int weighting = 0; - - if (rtlpriv->stats.recv_signal_power == 0) - rtlpriv->stats.recv_signal_power = pstatus->recvsignalpower; - if (pstatus->recvsignalpower > rtlpriv->stats.recv_signal_power) - weighting = 5; - else if (pstatus->recvsignalpower < rtlpriv->stats.recv_signal_power) - weighting = (-5); - rtlpriv->stats.recv_signal_power = (rtlpriv->stats.recv_signal_power * - 5 + pstatus->recvsignalpower + weighting) / 6; -} - -static void rtl_process_pwdb(struct ieee80211_hw *hw, struct rtl_stats *pstatus) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_sta_info *drv_priv = NULL; - struct ieee80211_sta *sta = NULL; - long undec_sm_pwdb; - - rcu_read_lock(); - if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION) - sta = rtl_find_sta(hw, pstatus->psaddr); - - /* adhoc or ap mode */ - if (sta) { - drv_priv = (struct rtl_sta_info *) sta->drv_priv; - undec_sm_pwdb = drv_priv->rssi_stat.undec_sm_pwdb; - } else { - undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb; - } - - if (undec_sm_pwdb < 0) - undec_sm_pwdb = pstatus->rx_pwdb_all; - if (pstatus->rx_pwdb_all > (u32) undec_sm_pwdb) { - undec_sm_pwdb = (((undec_sm_pwdb) * - (RX_SMOOTH_FACTOR - 1)) + - (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); - undec_sm_pwdb = undec_sm_pwdb + 1; - } else { - undec_sm_pwdb = (((undec_sm_pwdb) * (RX_SMOOTH_FACTOR - 1)) + - (pstatus->rx_pwdb_all)) / (RX_SMOOTH_FACTOR); - } - - if (sta) { - drv_priv->rssi_stat.undec_sm_pwdb = undec_sm_pwdb; - } else { - rtlpriv->dm.undec_sm_pwdb = undec_sm_pwdb; - } - rcu_read_unlock(); - - rtl_update_rxsignalstatistics(hw, pstatus); -} - -static void rtl_process_ui_link_quality(struct ieee80211_hw *hw, - struct rtl_stats *pstatus) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 last_evm, n_stream, tmpval; - - if (pstatus->signalquality == 0) - return; - - if (rtlpriv->stats.ui_link_quality.total_num++ >= - PHY_LINKQUALITY_SLID_WIN_MAX) { - rtlpriv->stats.ui_link_quality.total_num = - PHY_LINKQUALITY_SLID_WIN_MAX; - last_evm = rtlpriv->stats.ui_link_quality.elements[ - rtlpriv->stats.ui_link_quality.index]; - rtlpriv->stats.ui_link_quality.total_val -= last_evm; - } - rtlpriv->stats.ui_link_quality.total_val += pstatus->signalquality; - rtlpriv->stats.ui_link_quality.elements[ - rtlpriv->stats.ui_link_quality.index++] = - pstatus->signalquality; - if (rtlpriv->stats.ui_link_quality.index >= - PHY_LINKQUALITY_SLID_WIN_MAX) - rtlpriv->stats.ui_link_quality.index = 0; - tmpval = rtlpriv->stats.ui_link_quality.total_val / - rtlpriv->stats.ui_link_quality.total_num; - rtlpriv->stats.signal_quality = tmpval; - rtlpriv->stats.last_sigstrength_inpercent = tmpval; - for (n_stream = 0; n_stream < 2; n_stream++) { - if (pstatus->rx_mimo_sig_qual[n_stream] != -1) { - if (rtlpriv->stats.rx_evm_percentage[n_stream] == 0) { - rtlpriv->stats.rx_evm_percentage[n_stream] = - pstatus->rx_mimo_sig_qual[n_stream]; - } - rtlpriv->stats.rx_evm_percentage[n_stream] = - ((rtlpriv->stats.rx_evm_percentage[n_stream] - * (RX_SMOOTH_FACTOR - 1)) + - (pstatus->rx_mimo_sig_qual[n_stream] * 1)) / - (RX_SMOOTH_FACTOR); - } - } -} - -void rtl_process_phyinfo(struct ieee80211_hw *hw, u8 *buffer, - struct rtl_stats *pstatus) -{ - - if (!pstatus->packet_matchbssid) - return; - - rtl_process_ui_rssi(hw, pstatus); - rtl_process_pwdb(hw, pstatus); - rtl_process_ui_link_quality(hw, pstatus); -} -EXPORT_SYMBOL(rtl_process_phyinfo); diff --git a/trunk/drivers/net/wireless/rtlwifi/stats.h b/trunk/drivers/net/wireless/rtlwifi/stats.h deleted file mode 100644 index 0dbdc5203830..000000000000 --- a/trunk/drivers/net/wireless/rtlwifi/stats.h +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************** - * - * Copyright(c) 2009-2012 Realtek Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * wlanfae - * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, - * Hsinchu 300, Taiwan. - * - * Larry Finger - * - *****************************************************************************/ - -#ifndef __RTL_STATS_H__ -#define __RTL_STATS_H__ - -#define PHY_RSSI_SLID_WIN_MAX 100 -#define PHY_LINKQUALITY_SLID_WIN_MAX 20 -#define PHY_BEACON_RSSI_SLID_WIN_MAX 10 - -/* Rx smooth factor */ -#define RX_SMOOTH_FACTOR 20 - -u8 rtl_query_rxpwrpercentage(char antpower); -u8 rtl_evm_db_to_percentage(char value); -long rtl_signal_scale_mapping(struct ieee80211_hw *hw, long currsig); -void rtl_process_phyinfo(struct ieee80211_hw *hw, u8 *buffer, - struct rtl_stats *pstatus); - -#endif diff --git a/trunk/drivers/net/wireless/rtlwifi/wifi.h b/trunk/drivers/net/wireless/rtlwifi/wifi.h index 21a5f4f4a135..f1b6bc693b0a 100644 --- a/trunk/drivers/net/wireless/rtlwifi/wifi.h +++ b/trunk/drivers/net/wireless/rtlwifi/wifi.h @@ -198,15 +198,15 @@ struct bb_reg_def { u32 rftxgain_stage; u32 rfhssi_para1; u32 rfhssi_para2; - u32 rfsw_ctrl; + u32 rfswitch_control; u32 rfagc_control1; u32 rfagc_control2; - u32 rfrxiq_imbal; + u32 rfrxiq_imbalance; u32 rfrx_afe; - u32 rftxiq_imbal; + u32 rftxiq_imbalance; u32 rftx_afe; - u32 rf_rb; /* rflssi_readback */ - u32 rf_rbpi; /* rflssi_readbackpi */ + u32 rflssi_readback; + u32 rflssi_readbackpi; }; enum io_type { @@ -350,11 +350,6 @@ enum rt_oem_id { RT_CID_819x_WNC_COREGA = 31, RT_CID_819x_Foxcoon = 32, RT_CID_819x_DELL = 33, - RT_CID_819x_PRONETS = 34, - RT_CID_819x_Edimax_ASUS = 35, - RT_CID_NETGEAR = 36, - RT_CID_PLANEX = 37, - RT_CID_CC_C = 38, }; enum hw_descs { @@ -510,7 +505,6 @@ enum rtl_var_map { RTL_IMR_ROK, /*Receive DMA OK Interrupt */ RTL_IBSS_INT_MASKS, /*(RTL_IMR_BcnInt | RTL_IMR_TBDOK | * RTL_IMR_TBDER) */ - RTL_IMR_C2HCMD, /*fw interrupt*/ /*CCK Rates, TxHT = 0 */ RTL_RC_CCK_RATE1M, @@ -667,11 +661,6 @@ enum ba_action { ACT_DELBA = 2, }; -enum rt_polarity_ctl { - RT_POLARITY_LOW_ACT = 0, - RT_POLARITY_HIGH_ACT = 1, -}; - struct octet_string { u8 *octet; u16 length; @@ -896,7 +885,7 @@ struct rtl_phy { u8 pwrgroup_cnt; u8 cck_high_power; /* MAX_PG_GROUP groups of pwr diff by rates */ - u32 mcs_offset[MAX_PG_GROUP][16]; + u32 mcs_txpwrlevel_origoffset[MAX_PG_GROUP][16]; u8 default_initialgain[4]; /* the current Tx power level */ @@ -914,8 +903,6 @@ struct rtl_phy { u8 num_total_rfpath; struct phy_parameters hwparam_tables[MAX_TAB]; u16 rf_pathmap; - - enum rt_polarity_ctl polarity_ctl; }; #define MAX_TID_COUNT 9 @@ -946,7 +933,7 @@ struct rtl_tid_data { }; struct rssi_sta { - long undec_sm_pwdb; + long undecorated_smoothed_pwdb; }; struct rtl_sta_info { @@ -1055,64 +1042,13 @@ struct rtl_mac { /*QOS & EDCA */ struct ieee80211_tx_queue_params edca_param[RTL_MAC80211_NUM_QUEUE]; struct rtl_qos_parameters ac[AC_MAX]; - - /* counters */ - u64 last_txok_cnt; - u64 last_rxok_cnt; - u32 last_bt_edca_ul; - u32 last_bt_edca_dl; -}; - -struct btdm_8723 { - bool all_off; - bool agc_table_en; - bool adc_back_off_on; - bool b2_ant_hid_en; - bool low_penalty_rate_adaptive; - bool rf_rx_lpf_shrink; - bool reject_aggre_pkt; - bool tra_tdma_on; - u8 tra_tdma_nav; - u8 tra_tdma_ant; - bool tdma_on; - u8 tdma_ant; - u8 tdma_nav; - u8 tdma_dac_swing; - u8 fw_dac_swing_lvl; - bool ps_tdma_on; - u8 ps_tdma_byte[5]; - bool pta_on; - u32 val_0x6c0; - u32 val_0x6c8; - u32 val_0x6cc; - bool sw_dac_swing_on; - u32 sw_dac_swing_lvl; - u32 wlan_act_hi; - u32 wlan_act_lo; - u32 bt_retry_index; - bool dec_bt_pwr; - bool ignore_wlan_act; -}; - -struct bt_coexist_8723 { - u32 high_priority_tx; - u32 high_priority_rx; - u32 low_priority_tx; - u32 low_priority_rx; - u8 c2h_bt_info; - bool c2h_bt_info_req_sent; - bool c2h_bt_inquiry_page; - u32 bt_inq_page_start_time; - u8 bt_retry_cnt; - u8 c2h_bt_info_original; - u8 bt_inquiry_page_cnt; - struct btdm_8723 btdm; }; struct rtl_hal { struct ieee80211_hw *hw; - struct bt_coexist_8723 hal_coex_8723; + bool up_first_time; + bool first_init; bool being_init_adapter; bool bbrf_ready; @@ -1195,9 +1131,9 @@ struct rtl_security { struct rtl_dm { /*PHY status for Dynamic Management */ - long entry_min_undec_sm_pwdb; - long undec_sm_pwdb; /*out dm */ - long entry_max_undec_sm_pwdb; + long entry_min_undecoratedsmoothed_pwdb; + long undecorated_smoothed_pwdb; /*out dm */ + long entry_max_undecoratedsmoothed_pwdb; bool dm_initialgain_enable; bool dynamic_txpower_enable; bool current_turbo_edca; @@ -1273,7 +1209,7 @@ struct rtl_efuse { u8 eeprom_pwrlimit_ht40[CHANNEL_GROUP_MAX]; u8 eeprom_chnlarea_txpwr_cck[2][CHANNEL_GROUP_MAX_2G]; u8 eeprom_chnlarea_txpwr_ht40_1s[2][CHANNEL_GROUP_MAX]; - u8 eprom_chnl_txpwr_ht40_2sdf[2][CHANNEL_GROUP_MAX]; + u8 eeprom_chnlarea_txpwr_ht40_2sdiif[2][CHANNEL_GROUP_MAX]; u8 txpwrlevel_cck[2][CHANNEL_MAX_NUMBER_2G]; u8 txpwrlevel_ht40_1s[2][CHANNEL_MAX_NUMBER]; /*For HT 40MHZ pwr */ u8 txpwrlevel_ht40_2s[2][CHANNEL_MAX_NUMBER]; /*For HT 40MHZ pwr */ @@ -1376,7 +1312,6 @@ struct rtl_ps_ctl { }; struct rtl_stats { - u8 psaddr[ETH_ALEN]; u32 mac_time[2]; s8 rssi; u8 signal; @@ -1416,7 +1351,7 @@ struct rtl_stats { bool rx_is40Mhzpacket; u32 rx_pwdb_all; u8 rx_mimo_signalstrength[4]; /*in 0~100 index */ - s8 rx_mimo_sig_qual[2]; + s8 rx_mimo_signalquality[2]; bool packet_matchbssid; bool is_cck; bool is_ht; @@ -1568,10 +1503,6 @@ struct rtl_hal_ops { void (*phy_lc_calibrate) (struct ieee80211_hw *hw, bool is2t); void (*phy_set_bw_mode_callback) (struct ieee80211_hw *hw); void (*dm_dynamic_txpower) (struct ieee80211_hw *hw); - void (*c2h_command_handle) (struct ieee80211_hw *hw); - void (*bt_wifi_media_status_notify) (struct ieee80211_hw *hw, - bool mstate); - void (*bt_coex_off_before_lps) (struct ieee80211_hw *hw); }; struct rtl_intf_ops { @@ -1748,7 +1679,7 @@ struct dig_t { u32 rssi_highthresh; u32 fa_lowthresh; u32 fa_highthresh; - long last_min_undec_pwdb_for_dm; + long last_min_undecorated_pwdb_for_dm; long rssi_highpower_lowthresh; long rssi_highpower_highthresh; u32 recover_cnt; @@ -1761,15 +1692,15 @@ struct dig_t { u8 dig_twoport_algorithm; u8 dig_dbgmode; u8 dig_slgorithm_switch; - u8 cursta_cstate; - u8 presta_cstate; - u8 curmultista_cstate; - char back_val; - char back_range_max; - char back_range_min; + u8 cursta_connectstate; + u8 presta_connectstate; + u8 curmultista_connectstate; + char backoff_val; + char backoff_val_range_max; + char backoff_val_range_min; u8 rx_gain_range_max; u8 rx_gain_range_min; - u8 min_undec_pwdb_for_dm; + u8 min_undecorated_pwdb_for_dm; u8 rssi_val_min; u8 pre_cck_pd_state; u8 cur_cck_pd_state; @@ -1781,10 +1712,10 @@ struct dig_t { u8 forbidden_igi; u8 dig_state; u8 dig_highpwrstate; - u8 cur_sta_cstate; - u8 pre_sta_cstate; - u8 cur_ap_cstate; - u8 pre_ap_cstate; + u8 cur_sta_connectstate; + u8 pre_sta_connectstate; + u8 cur_ap_connectstate; + u8 pre_ap_connectstate; u8 cur_pd_thstate; u8 pre_pd_thstate; u8 cur_cs_ratiostate; @@ -1850,22 +1781,9 @@ struct rtl_priv { struct dig_t dm_digtable; struct ps_t dm_pstable; - /* section shared by individual drivers */ - union { - struct { /* data buffer pointer for USB reads */ - __le32 *usb_data; - int usb_data_index; - bool initialized; - }; - struct { /* section for 8723ae */ - bool reg_init; /* true if regs saved */ - u32 reg_874; - u32 reg_c70; - u32 reg_85c; - u32 reg_a74; - bool bt_operation_on; - }; - }; + /* data buffer pointer for USB reads */ + __le32 *usb_data; + int usb_data_index; /*This must be the last item so that it points to the data allocated @@ -1897,7 +1815,6 @@ enum bt_co_type { BT_CSR_BC4 = 3, BT_CSR_BC8 = 4, BT_RTL8756 = 5, - BT_RTL8723A = 6, }; enum bt_cur_state { @@ -1929,7 +1846,7 @@ struct bt_coexist_info { u8 eeprom_bt_coexist; u8 eeprom_bt_type; u8 eeprom_bt_ant_num; - u8 eeprom_bt_ant_isol; + u8 eeprom_bt_ant_isolation; u8 eeprom_bt_radio_shared; u8 bt_coexistence; @@ -1956,27 +1873,13 @@ struct bt_coexist_info { bool fw_coexist_all_off; bool sw_coexist_all_off; - bool hw_coexist_all_off; - u32 cstate; + u32 current_state; u32 previous_state; - u32 cstate_h; - u32 previous_state_h; - u8 bt_pre_rssi_state; - u8 bt_pre_rssi_state1; u8 reg_bt_iso; u8 reg_bt_sco; - bool balance_on; - u8 bt_active_zero_cnt; - bool cur_bt_disabled; - bool pre_bt_disabled; - - u8 bt_profile_case; - u8 bt_profile_action; - bool bt_busy; - bool hold_for_bt_operation; - u8 lps_counter; + }; diff --git a/trunk/drivers/nfc/pn533.c b/trunk/drivers/nfc/pn533.c index ada681b01a17..18e279d3e836 100644 --- a/trunk/drivers/nfc/pn533.c +++ b/trunk/drivers/nfc/pn533.c @@ -702,14 +702,13 @@ static void pn533_wq_cmd(struct work_struct *work) cmd = list_first_entry(&dev->cmd_queue, struct pn533_cmd, queue); - list_del(&cmd->queue); - mutex_unlock(&dev->cmd_lock); __pn533_send_cmd_frame_async(dev, cmd->out_frame, cmd->in_frame, cmd->in_frame_len, cmd->cmd_complete, cmd->arg, cmd->flags); + list_del(&cmd->queue); kfree(cmd); } @@ -1681,14 +1680,11 @@ static void pn533_deactivate_target(struct nfc_dev *nfc_dev, static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, u8 *params, int params_len) { + struct pn533_cmd_jump_dep *cmd; struct pn533_cmd_jump_dep_response *resp; struct nfc_target nfc_target; u8 target_gt_len; int rc; - struct pn533_cmd_jump_dep *cmd = (struct pn533_cmd_jump_dep *)arg; - u8 active = cmd->active; - - kfree(arg); if (params_len == -ENOENT) { nfc_dev_dbg(&dev->interface->dev, ""); @@ -1710,6 +1706,7 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, } resp = (struct pn533_cmd_jump_dep_response *) params; + cmd = (struct pn533_cmd_jump_dep *) arg; rc = resp->status & PN533_CMD_RET_MASK; if (rc != PN533_CMD_RET_SUCCESS) { nfc_dev_err(&dev->interface->dev, @@ -1739,7 +1736,7 @@ static int pn533_in_dep_link_up_complete(struct pn533 *dev, void *arg, if (rc == 0) rc = nfc_dep_link_is_up(dev->nfc_dev, dev->nfc_dev->targets[0].idx, - !active, NFC_RF_INITIATOR); + !cmd->active, NFC_RF_INITIATOR); return 0; } @@ -1824,8 +1821,12 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target, rc = pn533_send_cmd_frame_async(dev, dev->out_frame, dev->in_frame, dev->in_maxlen, pn533_in_dep_link_up_complete, cmd, GFP_KERNEL); - if (rc < 0) - kfree(cmd); + if (rc) + goto out; + + +out: + kfree(cmd); return rc; } @@ -2079,12 +2080,8 @@ static int pn533_transceive(struct nfc_dev *nfc_dev, static int pn533_tm_send_complete(struct pn533 *dev, void *arg, u8 *params, int params_len) { - struct sk_buff *skb_out = arg; - nfc_dev_dbg(&dev->interface->dev, "%s", __func__); - dev_kfree_skb(skb_out); - if (params_len < 0) { nfc_dev_err(&dev->interface->dev, "Error %d when sending data", @@ -2122,7 +2119,7 @@ static int pn533_tm_send(struct nfc_dev *nfc_dev, struct sk_buff *skb) rc = pn533_send_cmd_frame_async(dev, out_frame, dev->in_frame, dev->in_maxlen, pn533_tm_send_complete, - skb, GFP_KERNEL); + NULL, GFP_KERNEL); if (rc) { nfc_dev_err(&dev->interface->dev, "Error %d when trying to send data", rc); diff --git a/trunk/drivers/nfc/pn544/i2c.c b/trunk/drivers/nfc/pn544/i2c.c index 7da9071b68b6..fb430d882352 100644 --- a/trunk/drivers/nfc/pn544/i2c.c +++ b/trunk/drivers/nfc/pn544/i2c.c @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include diff --git a/trunk/drivers/ssb/driver_mipscore.c b/trunk/drivers/ssb/driver_mipscore.c index 5bd05b136d22..b918ba922306 100644 --- a/trunk/drivers/ssb/driver_mipscore.c +++ b/trunk/drivers/ssb/driver_mipscore.c @@ -178,9 +178,9 @@ static void ssb_mips_serial_init(struct ssb_mipscore *mcore) { struct ssb_bus *bus = mcore->dev->bus; - if (ssb_extif_available(&bus->extif)) + if (bus->extif.dev) mcore->nr_serial_ports = ssb_extif_serial_init(&bus->extif, mcore->serial_ports); - else if (ssb_chipco_available(&bus->chipco)) + else if (bus->chipco.dev) mcore->nr_serial_ports = ssb_chipco_serial_init(&bus->chipco, mcore->serial_ports); else mcore->nr_serial_ports = 0; @@ -191,7 +191,7 @@ static void ssb_mips_flash_detect(struct ssb_mipscore *mcore) struct ssb_bus *bus = mcore->dev->bus; /* When there is no chipcommon on the bus there is 4MB flash */ - if (!ssb_chipco_available(&bus->chipco)) { + if (!bus->chipco.dev) { mcore->pflash.present = true; mcore->pflash.buswidth = 2; mcore->pflash.window = SSB_FLASH1; @@ -227,9 +227,9 @@ u32 ssb_cpu_clock(struct ssb_mipscore *mcore) if (bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU) return ssb_pmu_get_cpu_clock(&bus->chipco); - if (ssb_extif_available(&bus->extif)) { + if (bus->extif.dev) { ssb_extif_get_clockcontrol(&bus->extif, &pll_type, &n, &m); - } else if (ssb_chipco_available(&bus->chipco)) { + } else if (bus->chipco.dev) { ssb_chipco_get_clockcpu(&bus->chipco, &pll_type, &n, &m); } else return 0; @@ -265,9 +265,9 @@ void ssb_mipscore_init(struct ssb_mipscore *mcore) hz = 100000000; ns = 1000000000 / hz; - if (ssb_extif_available(&bus->extif)) + if (bus->extif.dev) ssb_extif_timing_init(&bus->extif, ns); - else if (ssb_chipco_available(&bus->chipco)) + else if (bus->chipco.dev) ssb_chipco_timing_init(&bus->chipco, ns); /* Assign IRQs to all cores on the bus, start with irq line 2, because serial usually takes 1 */ diff --git a/trunk/include/linux/bcma/bcma.h b/trunk/include/linux/bcma/bcma.h index 93b1e091b1e9..fd15d9829705 100644 --- a/trunk/include/linux/bcma/bcma.h +++ b/trunk/include/linux/bcma/bcma.h @@ -157,7 +157,6 @@ struct bcma_host_ops { /* Chip IDs of SoCs */ #define BCMA_CHIP_ID_BCM4706 0x5300 -#define BCMA_PKG_ID_BCM4706L 1 #define BCMA_CHIP_ID_BCM4716 0x4716 #define BCMA_PKG_ID_BCM4716 8 #define BCMA_PKG_ID_BCM4717 9 @@ -167,11 +166,7 @@ struct bcma_host_ops { #define BCMA_CHIP_ID_BCM4749 0x4749 #define BCMA_CHIP_ID_BCM5356 0x5356 #define BCMA_CHIP_ID_BCM5357 0x5357 -#define BCMA_PKG_ID_BCM5358 9 -#define BCMA_PKG_ID_BCM47186 10 -#define BCMA_PKG_ID_BCM5357 11 #define BCMA_CHIP_ID_BCM53572 53572 -#define BCMA_PKG_ID_BCM47188 9 struct bcma_device { struct bcma_bus *bus; diff --git a/trunk/include/linux/nfc/pn544.h b/trunk/include/linux/nfc/pn544.h new file mode 100644 index 000000000000..9890bbaf4328 --- /dev/null +++ b/trunk/include/linux/nfc/pn544.h @@ -0,0 +1,104 @@ +/* + * Driver include for the PN544 NFC chip. + * + * Copyright (C) Nokia Corporation + * + * Author: Jari Vanhala + * Contact: Matti Aaltoenn + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _PN544_H_ +#define _PN544_H_ + +#include + +#define PN544_DRIVER_NAME "pn544" +#define PN544_MAXWINDOW_SIZE 7 +#define PN544_WINDOW_SIZE 4 +#define PN544_RETRIES 10 +#define PN544_MAX_I2C_TRANSFER 0x0400 +#define PN544_MSG_MAX_SIZE 0x21 /* at normal HCI mode */ + +/* ioctl */ +#define PN544_CHAR_BASE 'P' +#define PN544_IOR(num, dtype) _IOR(PN544_CHAR_BASE, num, dtype) +#define PN544_IOW(num, dtype) _IOW(PN544_CHAR_BASE, num, dtype) +#define PN544_GET_FW_MODE PN544_IOW(1, unsigned int) +#define PN544_SET_FW_MODE PN544_IOW(2, unsigned int) +#define PN544_GET_DEBUG PN544_IOW(3, unsigned int) +#define PN544_SET_DEBUG PN544_IOW(4, unsigned int) + +/* Timing restrictions (ms) */ +#define PN544_RESETVEN_TIME 30 /* 7 */ +#define PN544_PVDDVEN_TIME 0 +#define PN544_VBATVEN_TIME 0 +#define PN544_GPIO4VEN_TIME 0 +#define PN544_WAKEUP_ACK 5 +#define PN544_WAKEUP_GUARD (PN544_WAKEUP_ACK + 1) +#define PN544_INACTIVITY_TIME 1000 +#define PN544_INTERFRAME_DELAY 200 /* us */ +#define PN544_BAUDRATE_CHANGE 150 /* us */ + +/* Debug bits */ +#define PN544_DEBUG_BUF 0x01 +#define PN544_DEBUG_READ 0x02 +#define PN544_DEBUG_WRITE 0x04 +#define PN544_DEBUG_IRQ 0x08 +#define PN544_DEBUG_CALLS 0x10 +#define PN544_DEBUG_MODE 0x20 + +/* Normal (HCI) mode */ +#define PN544_LLC_HCI_OVERHEAD 3 /* header + crc (to length) */ +#define PN544_LLC_MIN_SIZE (1 + PN544_LLC_HCI_OVERHEAD) /* length + */ +#define PN544_LLC_MAX_DATA (PN544_MSG_MAX_SIZE - 2) +#define PN544_LLC_MAX_HCI_SIZE (PN544_LLC_MAX_DATA - 2) + +struct pn544_llc_packet { + unsigned char length; /* of rest of packet */ + unsigned char header; + unsigned char data[PN544_LLC_MAX_DATA]; /* includes crc-ccitt */ +}; + +/* Firmware upgrade mode */ +#define PN544_FW_HEADER_SIZE 3 +/* max fw transfer is 1024bytes, but I2C limits it to 0xC0 */ +#define PN544_MAX_FW_DATA (PN544_MAX_I2C_TRANSFER - PN544_FW_HEADER_SIZE) + +struct pn544_fw_packet { + unsigned char command; /* status in answer */ + unsigned char length[2]; /* big-endian order (msf) */ + unsigned char data[PN544_MAX_FW_DATA]; +}; + +#ifdef __KERNEL__ +enum { + NFC_GPIO_ENABLE, + NFC_GPIO_FW_RESET, + NFC_GPIO_IRQ +}; + +/* board config */ +struct pn544_nfc_platform_data { + int (*request_resources) (struct i2c_client *client); + void (*free_resources) (void); + void (*enable) (int fw); + int (*test) (void); + void (*disable) (void); + int (*get_gpio)(int type); +}; +#endif /* __KERNEL__ */ + +#endif /* _PN544_H_ */ diff --git a/trunk/include/linux/platform_data/pn544.h b/trunk/include/linux/platform_data/pn544.h deleted file mode 100644 index 713bfd703342..000000000000 --- a/trunk/include/linux/platform_data/pn544.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Driver include for the PN544 NFC chip. - * - * Copyright (C) Nokia Corporation - * - * Author: Jari Vanhala - * Contact: Matti Aaltoenn - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _PN544_H_ -#define _PN544_H_ - -#include - -enum { - NFC_GPIO_ENABLE, - NFC_GPIO_FW_RESET, - NFC_GPIO_IRQ -}; - -/* board config */ -struct pn544_nfc_platform_data { - int (*request_resources) (struct i2c_client *client); - void (*free_resources) (void); - void (*enable) (int fw); - int (*test) (void); - void (*disable) (void); - int (*get_gpio)(int type); -}; - -#endif /* _PN544_H_ */ diff --git a/trunk/include/linux/ssb/ssb_driver_extif.h b/trunk/include/linux/ssb/ssb_driver_extif.h index 2604efa7dc4d..91161f0aa22b 100644 --- a/trunk/include/linux/ssb/ssb_driver_extif.h +++ b/trunk/include/linux/ssb/ssb_driver_extif.h @@ -204,53 +204,11 @@ void ssb_extif_get_clockcontrol(struct ssb_extif *extif, { } -static inline -void ssb_extif_timing_init(struct ssb_extif *extif, unsigned long ns) -{ -} - static inline void ssb_extif_watchdog_timer_set(struct ssb_extif *extif, u32 ticks) { } -static inline u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask) -{ - return 0; -} - -static inline u32 ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, - u32 value) -{ - return 0; -} - -static inline u32 ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, - u32 value) -{ - return 0; -} - -static inline u32 ssb_extif_gpio_polarity(struct ssb_extif *extif, u32 mask, - u32 value) -{ - return 0; -} - -static inline u32 ssb_extif_gpio_intmask(struct ssb_extif *extif, u32 mask, - u32 value) -{ - return 0; -} - -#ifdef CONFIG_SSB_SERIAL -static inline int ssb_extif_serial_init(struct ssb_extif *extif, - struct ssb_serial_port *ports) -{ - return 0; -} -#endif /* CONFIG_SSB_SERIAL */ - #endif /* CONFIG_SSB_DRIVER_EXTIF */ #endif /* LINUX_SSB_EXTIFCORE_H_ */ diff --git a/trunk/include/linux/ssb/ssb_regs.h b/trunk/include/linux/ssb/ssb_regs.h index 6ecfa02ddbac..a0525019e1d1 100644 --- a/trunk/include/linux/ssb/ssb_regs.h +++ b/trunk/include/linux/ssb/ssb_regs.h @@ -485,7 +485,7 @@ #define SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP_SHIFT 4 #define SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL 0x0020 #define SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL_SHIFT 5 -#define SSB_SPROM8_TEMPDELTA 0x00BC +#define SSB_SPROM8_TEMPDELTA 0x00BA #define SSB_SPROM8_TEMPDELTA_PHYCAL 0x00ff #define SSB_SPROM8_TEMPDELTA_PHYCAL_SHIFT 0 #define SSB_SPROM8_TEMPDELTA_PERIOD 0x0f00 diff --git a/trunk/include/net/bluetooth/amp.h b/trunk/include/net/bluetooth/amp.h index 7ea3db77ba89..2e7c79ea0463 100644 --- a/trunk/include/net/bluetooth/amp.h +++ b/trunk/include/net/bluetooth/amp.h @@ -46,9 +46,5 @@ void amp_accept_phylink(struct hci_dev *hdev, struct amp_mgr *mgr, struct hci_conn *hcon); void amp_write_remote_assoc(struct hci_dev *hdev, u8 handle); void amp_write_rem_assoc_continue(struct hci_dev *hdev, u8 handle); -void amp_physical_cfm(struct hci_conn *bredr_hcon, struct hci_conn *hs_hcon); -void amp_create_logical_link(struct l2cap_chan *chan); -void amp_disconnect_logical_link(struct hci_chan *hchan); -void amp_destroy_logical_link(struct hci_chan *hchan, u8 reason); #endif /* __AMP_H */ diff --git a/trunk/include/net/bluetooth/hci.h b/trunk/include/net/bluetooth/hci.h index 45eee08157bb..88cbbda61027 100644 --- a/trunk/include/net/bluetooth/hci.h +++ b/trunk/include/net/bluetooth/hci.h @@ -115,7 +115,6 @@ enum { HCI_SSP_ENABLED, HCI_HS_ENABLED, HCI_LE_ENABLED, - HCI_LE_PERIPHERAL, HCI_CONNECTABLE, HCI_DISCOVERABLE, HCI_LINK_SECURITY, @@ -154,7 +153,7 @@ enum { #define HCI_DISCONN_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */ #define HCI_PAIRING_TIMEOUT msecs_to_jiffies(60000) /* 60 seconds */ #define HCI_INIT_TIMEOUT msecs_to_jiffies(10000) /* 10 seconds */ -#define HCI_CMD_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */ +#define HCI_CMD_TIMEOUT msecs_to_jiffies(1000) /* 1 second */ #define HCI_ACL_TX_TIMEOUT msecs_to_jiffies(45000) /* 45 seconds */ #define HCI_AUTO_OFF_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */ @@ -319,9 +318,6 @@ enum { #define HCI_FLOW_CTL_MODE_PACKET_BASED 0x00 #define HCI_FLOW_CTL_MODE_BLOCK_BASED 0x01 -/* The core spec defines 127 as the "not available" value */ -#define HCI_TX_POWER_INVALID 127 - /* Extended Inquiry Response field types */ #define EIR_FLAGS 0x01 /* flags */ #define EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */ @@ -338,13 +334,6 @@ enum { #define EIR_SSP_RAND_R 0x0F /* Simple Pairing Randomizer R */ #define EIR_DEVICE_ID 0x10 /* device ID */ -/* Low Energy Advertising Flags */ -#define LE_AD_LIMITED 0x01 /* Limited Discoverable */ -#define LE_AD_GENERAL 0x02 /* General Discoverable */ -#define LE_AD_NO_BREDR 0x04 /* BR/EDR not supported */ -#define LE_AD_SIM_LE_BREDR_CTRL 0x08 /* Simultaneous LE & BR/EDR Controller */ -#define LE_AD_SIM_LE_BREDR_HOST 0x10 /* Simultaneous LE & BR/EDR Host */ - /* ----- HCI Commands ---- */ #define HCI_OP_NOP 0x0000 @@ -943,22 +932,6 @@ struct hci_rp_le_read_buffer_size { __u8 le_max_pkt; } __packed; -#define HCI_OP_LE_READ_ADV_TX_POWER 0x2007 -struct hci_rp_le_read_adv_tx_power { - __u8 status; - __s8 tx_power; -} __packed; - -#define HCI_MAX_AD_LENGTH 31 - -#define HCI_OP_LE_SET_ADV_DATA 0x2008 -struct hci_cp_le_set_adv_data { - __u8 length; - __u8 data[HCI_MAX_AD_LENGTH]; -} __packed; - -#define HCI_OP_LE_SET_ADV_ENABLE 0x200a - #define HCI_OP_LE_SET_SCAN_PARAM 0x200b struct hci_cp_le_set_scan_param { __u8 type; diff --git a/trunk/include/net/bluetooth/hci_core.h b/trunk/include/net/bluetooth/hci_core.h index 014a2eaa5389..9fe8e2dec870 100644 --- a/trunk/include/net/bluetooth/hci_core.h +++ b/trunk/include/net/bluetooth/hci_core.h @@ -278,10 +278,6 @@ struct hci_dev { struct work_struct le_scan; struct le_scan_params le_scan_params; - __s8 adv_tx_power; - __u8 adv_data[HCI_MAX_AD_LENGTH]; - __u8 adv_data_len; - int (*open)(struct hci_dev *hdev); int (*close)(struct hci_dev *hdev); int (*flush)(struct hci_dev *hdev); @@ -359,7 +355,6 @@ struct hci_chan { struct hci_conn *conn; struct sk_buff_head data_q; unsigned int sent; - __u8 state; }; extern struct list_head hci_dev_list; @@ -376,7 +371,7 @@ extern int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt); extern int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 flags); -extern int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags); +extern int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr); extern void sco_connect_cfm(struct hci_conn *hcon, __u8 status); extern void sco_disconn_cfm(struct hci_conn *hcon, __u8 reason); extern int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb); @@ -577,7 +572,6 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst); int hci_conn_del(struct hci_conn *conn); void hci_conn_hash_flush(struct hci_dev *hdev); void hci_conn_check_pending(struct hci_dev *hdev); -void hci_conn_accept(struct hci_conn *conn, int mask); struct hci_chan *hci_chan_create(struct hci_conn *conn); void hci_chan_del(struct hci_chan *chan); @@ -688,7 +682,7 @@ static inline uint8_t __hci_num_ctrl(void) } struct hci_dev *hci_dev_get(int index); -struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src); +struct hci_dev *hci_get_route(bdaddr_t *src, bdaddr_t *dst); struct hci_dev *hci_alloc_dev(void); void hci_free_dev(struct hci_dev *hdev); @@ -737,8 +731,6 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash, u8 *randomizer); int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr); -int hci_update_ad(struct hci_dev *hdev); - void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); int hci_recv_frame(struct sk_buff *skb); @@ -755,51 +747,22 @@ void hci_conn_del_sysfs(struct hci_conn *conn); #define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->dev.parent = (pdev)) /* ----- LMP capabilities ----- */ -#define lmp_encrypt_capable(dev) ((dev)->features[0] & LMP_ENCRYPT) #define lmp_rswitch_capable(dev) ((dev)->features[0] & LMP_RSWITCH) -#define lmp_hold_capable(dev) ((dev)->features[0] & LMP_HOLD) +#define lmp_encrypt_capable(dev) ((dev)->features[0] & LMP_ENCRYPT) #define lmp_sniff_capable(dev) ((dev)->features[0] & LMP_SNIFF) -#define lmp_park_capable(dev) ((dev)->features[1] & LMP_PARK) -#define lmp_inq_rssi_capable(dev) ((dev)->features[3] & LMP_RSSI_INQ) -#define lmp_esco_capable(dev) ((dev)->features[3] & LMP_ESCO) -#define lmp_bredr_capable(dev) (!((dev)->features[4] & LMP_NO_BREDR)) -#define lmp_le_capable(dev) ((dev)->features[4] & LMP_LE) #define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR) -#define lmp_pause_enc_capable(dev) ((dev)->features[5] & LMP_PAUSE_ENC) -#define lmp_ext_inq_capable(dev) ((dev)->features[6] & LMP_EXT_INQ) -#define lmp_le_br_capable(dev) !!((dev)->features[6] & LMP_SIMUL_LE_BR) +#define lmp_esco_capable(dev) ((dev)->features[3] & LMP_ESCO) #define lmp_ssp_capable(dev) ((dev)->features[6] & LMP_SIMPLE_PAIR) #define lmp_no_flush_capable(dev) ((dev)->features[6] & LMP_NO_FLUSH) -#define lmp_lsto_capable(dev) ((dev)->features[7] & LMP_LSTO) -#define lmp_inq_tx_pwr_capable(dev) ((dev)->features[7] & LMP_INQ_TX_PWR) -#define lmp_ext_feat_capable(dev) ((dev)->features[7] & LMP_EXTFEATURES) +#define lmp_le_capable(dev) ((dev)->features[4] & LMP_LE) +#define lmp_bredr_capable(dev) (!((dev)->features[4] & LMP_NO_BREDR)) /* ----- Extended LMP capabilities ----- */ -#define lmp_host_ssp_capable(dev) ((dev)->host_features[0] & LMP_HOST_SSP) -#define lmp_host_le_capable(dev) !!((dev)->host_features[0] & LMP_HOST_LE) -#define lmp_host_le_br_capable(dev) !!((dev)->host_features[0] & LMP_HOST_LE_BREDR) - -/* returns true if at least one AMP active */ -static inline bool hci_amp_capable(void) -{ - struct hci_dev *hdev; - bool ret = false; - - read_lock(&hci_dev_list_lock); - list_for_each_entry(hdev, &hci_dev_list, list) - if (hdev->amp_type == HCI_AMP && - test_bit(HCI_UP, &hdev->flags)) - ret = true; - read_unlock(&hci_dev_list_lock); - - return ret; -} +#define lmp_host_le_capable(dev) ((dev)->host_features[0] & LMP_HOST_LE) /* ----- HCI protocols ----- */ -#define HCI_PROTO_DEFER 0x01 - static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, - __u8 type, __u8 *flags) + __u8 type) { switch (type) { case ACL_LINK: @@ -807,7 +770,7 @@ static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, case SCO_LINK: case ESCO_LINK: - return sco_connect_ind(hdev, bdaddr, flags); + return sco_connect_ind(hdev, bdaddr); default: BT_ERR("unknown link type %d", type); @@ -914,7 +877,7 @@ struct hci_cb { static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status) { - struct hci_cb *cb; + struct list_head *p; __u8 encrypt; hci_proto_auth_cfm(conn, status); @@ -925,7 +888,8 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status) encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00; read_lock(&hci_cb_list_lock); - list_for_each_entry(cb, &hci_cb_list, list) { + list_for_each(p, &hci_cb_list) { + struct hci_cb *cb = list_entry(p, struct hci_cb, list); if (cb->security_cfm) cb->security_cfm(conn, status, encrypt); } @@ -935,7 +899,7 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status) static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encrypt) { - struct hci_cb *cb; + struct list_head *p; if (conn->sec_level == BT_SECURITY_SDP) conn->sec_level = BT_SECURITY_LOW; @@ -946,7 +910,8 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, hci_proto_encrypt_cfm(conn, status, encrypt); read_lock(&hci_cb_list_lock); - list_for_each_entry(cb, &hci_cb_list, list) { + list_for_each(p, &hci_cb_list) { + struct hci_cb *cb = list_entry(p, struct hci_cb, list); if (cb->security_cfm) cb->security_cfm(conn, status, encrypt); } @@ -955,10 +920,11 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, static inline void hci_key_change_cfm(struct hci_conn *conn, __u8 status) { - struct hci_cb *cb; + struct list_head *p; read_lock(&hci_cb_list_lock); - list_for_each_entry(cb, &hci_cb_list, list) { + list_for_each(p, &hci_cb_list) { + struct hci_cb *cb = list_entry(p, struct hci_cb, list); if (cb->key_change_cfm) cb->key_change_cfm(conn, status); } @@ -968,10 +934,11 @@ static inline void hci_key_change_cfm(struct hci_conn *conn, __u8 status) static inline void hci_role_switch_cfm(struct hci_conn *conn, __u8 status, __u8 role) { - struct hci_cb *cb; + struct list_head *p; read_lock(&hci_cb_list_lock); - list_for_each_entry(cb, &hci_cb_list, list) { + list_for_each(p, &hci_cb_list) { + struct hci_cb *cb = list_entry(p, struct hci_cb, list); if (cb->role_switch_cfm) cb->role_switch_cfm(conn, status, role); } diff --git a/trunk/include/net/bluetooth/l2cap.h b/trunk/include/net/bluetooth/l2cap.h index 7588ef44ebaf..6e23afdf65c1 100644 --- a/trunk/include/net/bluetooth/l2cap.h +++ b/trunk/include/net/bluetooth/l2cap.h @@ -52,8 +52,6 @@ #define L2CAP_ENC_TIMEOUT msecs_to_jiffies(5000) #define L2CAP_CONN_TIMEOUT msecs_to_jiffies(40000) #define L2CAP_INFO_TIMEOUT msecs_to_jiffies(4000) -#define L2CAP_MOVE_TIMEOUT msecs_to_jiffies(4000) -#define L2CAP_MOVE_ERTX_TIMEOUT msecs_to_jiffies(60000) #define L2CAP_A2MP_DEFAULT_MTU 670 @@ -436,8 +434,6 @@ struct l2cap_chan { struct sock *sk; struct l2cap_conn *conn; - struct hci_conn *hs_hcon; - struct hci_chan *hs_hchan; struct kref kref; __u8 state; @@ -481,12 +477,6 @@ struct l2cap_chan { unsigned long conn_state; unsigned long flags; - __u8 remote_amp_id; - __u8 local_amp_id; - __u8 move_id; - __u8 move_state; - __u8 move_role; - __u16 next_tx_seq; __u16 expected_ack_seq; __u16 expected_tx_seq; @@ -519,6 +509,8 @@ struct l2cap_chan { __u32 remote_acc_lat; __u32 remote_flush_to; + __u8 ctrl_id; + struct delayed_work chan_timer; struct delayed_work retrans_timer; struct delayed_work monitor_timer; @@ -611,7 +603,7 @@ enum { CONF_MTU_DONE, CONF_MODE_DONE, CONF_CONNECT_PEND, - CONF_RECV_NO_FCS, + CONF_NO_FCS_RECV, CONF_STATE2_DEVICE, CONF_EWS_RECV, CONF_LOC_CONF_PEND, @@ -652,9 +644,6 @@ enum { enum { L2CAP_RX_STATE_RECV, L2CAP_RX_STATE_SREJ_SENT, - L2CAP_RX_STATE_MOVE, - L2CAP_RX_STATE_WAIT_P, - L2CAP_RX_STATE_WAIT_F, }; enum { @@ -685,25 +674,6 @@ enum { L2CAP_EV_RECV_FRAME, }; -enum { - L2CAP_MOVE_ROLE_NONE, - L2CAP_MOVE_ROLE_INITIATOR, - L2CAP_MOVE_ROLE_RESPONDER, -}; - -enum { - L2CAP_MOVE_STABLE, - L2CAP_MOVE_WAIT_REQ, - L2CAP_MOVE_WAIT_RSP, - L2CAP_MOVE_WAIT_RSP_SUCCESS, - L2CAP_MOVE_WAIT_CONFIRM, - L2CAP_MOVE_WAIT_CONFIRM_RSP, - L2CAP_MOVE_WAIT_LOGICAL_COMP, - L2CAP_MOVE_WAIT_LOGICAL_CFM, - L2CAP_MOVE_WAIT_LOCAL_BUSY, - L2CAP_MOVE_WAIT_PREPARE, -}; - void l2cap_chan_hold(struct l2cap_chan *c); void l2cap_chan_put(struct l2cap_chan *c); @@ -808,9 +778,5 @@ void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan); void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan); void l2cap_chan_del(struct l2cap_chan *chan, int err); void l2cap_send_conn_req(struct l2cap_chan *chan); -void l2cap_move_start(struct l2cap_chan *chan); -void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan, - u8 status); -void __l2cap_physical_cfm(struct l2cap_chan *chan, int result); #endif /* __L2CAP_H */ diff --git a/trunk/include/net/cfg80211.h b/trunk/include/net/cfg80211.h index e78db2cf3d1b..a238f41e55c2 100644 --- a/trunk/include/net/cfg80211.h +++ b/trunk/include/net/cfg80211.h @@ -58,6 +58,8 @@ * structures here describe these capabilities in detail. */ +struct wiphy; + /* * wireless hardware capability structures */ @@ -387,6 +389,22 @@ const struct cfg80211_chan_def * cfg80211_chandef_compatible(const struct cfg80211_chan_def *chandef1, const struct cfg80211_chan_def *chandef2); +/** + * cfg80211_chandef_valid - check if a channel definition is valid + * @chandef: the channel definition to check + */ +bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef); + +/** + * cfg80211_chandef_usable - check if secondary channels can be used + * @wiphy: the wiphy to validate against + * @chandef: the channel definition to check + * @prohibited_flags: the regulatory chanenl flags that must not be set + */ +bool cfg80211_chandef_usable(struct wiphy *wiphy, + const struct cfg80211_chan_def *chandef, + u32 prohibited_flags); + /** * enum survey_info_flags - survey information flags * @@ -1045,9 +1063,6 @@ struct ieee80211_txq_params { u8 aifs; }; -/* from net/wireless.h */ -struct wiphy; - /** * DOC: Scanning and BSS list handling * diff --git a/trunk/include/net/nfc/hci.h b/trunk/include/net/nfc/hci.h index 671953e11575..639f50af42df 100644 --- a/trunk/include/net/nfc/hci.h +++ b/trunk/include/net/nfc/hci.h @@ -149,8 +149,6 @@ void *nfc_hci_get_clientdata(struct nfc_hci_dev *hdev); void nfc_hci_driver_failure(struct nfc_hci_dev *hdev, int err); -int nfc_hci_result_to_errno(u8 result); - /* Host IDs */ #define NFC_HCI_HOST_CONTROLLER_ID 0x00 #define NFC_HCI_TERMINAL_HOST_ID 0x01 @@ -237,6 +235,5 @@ int nfc_hci_send_response(struct nfc_hci_dev *hdev, u8 gate, u8 response, int nfc_hci_send_event(struct nfc_hci_dev *hdev, u8 gate, u8 event, const u8 *param, size_t param_len); int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate); -u32 nfc_hci_sak_to_protocol(u8 sak); #endif /* __NET_HCI_H */ diff --git a/trunk/net/bluetooth/Kconfig b/trunk/net/bluetooth/Kconfig index d3f3f7b1d32c..1c11d0dcd863 100644 --- a/trunk/net/bluetooth/Kconfig +++ b/trunk/net/bluetooth/Kconfig @@ -48,3 +48,4 @@ source "net/bluetooth/cmtp/Kconfig" source "net/bluetooth/hidp/Kconfig" source "drivers/bluetooth/Kconfig" + diff --git a/trunk/net/bluetooth/a2mp.c b/trunk/net/bluetooth/a2mp.c index 2f67d5ecc907..d5136cfb57e2 100644 --- a/trunk/net/bluetooth/a2mp.c +++ b/trunk/net/bluetooth/a2mp.c @@ -423,7 +423,7 @@ static int a2mp_getampassoc_rsp(struct amp_mgr *mgr, struct sk_buff *skb, BT_DBG("Created hcon %p: loc:%d -> rem:%d", hcon, hdev->id, rsp->id); - mgr->bredr_chan->remote_amp_id = rsp->id; + mgr->bredr_chan->ctrl_id = rsp->id; amp_create_phylink(hdev, mgr, hcon); @@ -939,7 +939,7 @@ void a2mp_send_create_phy_link_req(struct hci_dev *hdev, u8 status) goto clean; req->local_id = hdev->id; - req->remote_id = bredr_chan->remote_amp_id; + req->remote_id = bredr_chan->ctrl_id; memcpy(req->amp_assoc, loc_assoc->data, loc_assoc->len); a2mp_send(mgr, A2MP_CREATEPHYSLINK_REQ, __next_ident(mgr), len, req); diff --git a/trunk/net/bluetooth/amp.c b/trunk/net/bluetooth/amp.c index 1b0d92c0643a..231d7ef53ecb 100644 --- a/trunk/net/bluetooth/amp.c +++ b/trunk/net/bluetooth/amp.c @@ -372,100 +372,3 @@ void amp_accept_phylink(struct hci_dev *hdev, struct amp_mgr *mgr, hci_send_cmd(hdev, HCI_OP_ACCEPT_PHY_LINK, sizeof(cp), &cp); } - -void amp_physical_cfm(struct hci_conn *bredr_hcon, struct hci_conn *hs_hcon) -{ - struct hci_dev *bredr_hdev = hci_dev_hold(bredr_hcon->hdev); - struct amp_mgr *mgr = hs_hcon->amp_mgr; - struct l2cap_chan *bredr_chan; - - BT_DBG("bredr_hcon %p hs_hcon %p mgr %p", bredr_hcon, hs_hcon, mgr); - - if (!bredr_hdev || !mgr || !mgr->bredr_chan) - return; - - bredr_chan = mgr->bredr_chan; - - l2cap_chan_lock(bredr_chan); - - set_bit(FLAG_EFS_ENABLE, &bredr_chan->flags); - bredr_chan->remote_amp_id = hs_hcon->remote_id; - bredr_chan->local_amp_id = hs_hcon->hdev->id; - bredr_chan->hs_hcon = hs_hcon; - bredr_chan->conn->mtu = hs_hcon->hdev->block_mtu; - - __l2cap_physical_cfm(bredr_chan, 0); - - l2cap_chan_unlock(bredr_chan); - - hci_dev_put(bredr_hdev); -} - -void amp_create_logical_link(struct l2cap_chan *chan) -{ - struct hci_cp_create_accept_logical_link cp; - struct hci_conn *hcon; - struct hci_dev *hdev; - - BT_DBG("chan %p", chan); - - if (!chan->hs_hcon) - return; - - hdev = hci_dev_hold(chan->hs_hcon->hdev); - if (!hdev) - return; - - BT_DBG("chan %p dst %pMR", chan, chan->conn->dst); - - hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, chan->conn->dst); - if (!hcon) - goto done; - - cp.phy_handle = hcon->handle; - - cp.tx_flow_spec.id = chan->local_id; - cp.tx_flow_spec.stype = chan->local_stype; - cp.tx_flow_spec.msdu = cpu_to_le16(chan->local_msdu); - cp.tx_flow_spec.sdu_itime = cpu_to_le32(chan->local_sdu_itime); - cp.tx_flow_spec.acc_lat = cpu_to_le32(chan->local_acc_lat); - cp.tx_flow_spec.flush_to = cpu_to_le32(chan->local_flush_to); - - cp.rx_flow_spec.id = chan->remote_id; - cp.rx_flow_spec.stype = chan->remote_stype; - cp.rx_flow_spec.msdu = cpu_to_le16(chan->remote_msdu); - cp.rx_flow_spec.sdu_itime = cpu_to_le32(chan->remote_sdu_itime); - cp.rx_flow_spec.acc_lat = cpu_to_le32(chan->remote_acc_lat); - cp.rx_flow_spec.flush_to = cpu_to_le32(chan->remote_flush_to); - - if (hcon->out) - hci_send_cmd(hdev, HCI_OP_CREATE_LOGICAL_LINK, sizeof(cp), - &cp); - else - hci_send_cmd(hdev, HCI_OP_ACCEPT_LOGICAL_LINK, sizeof(cp), - &cp); - -done: - hci_dev_put(hdev); -} - -void amp_disconnect_logical_link(struct hci_chan *hchan) -{ - struct hci_conn *hcon = hchan->conn; - struct hci_cp_disconn_logical_link cp; - - if (hcon->state != BT_CONNECTED) { - BT_DBG("hchan %p not connected", hchan); - return; - } - - cp.log_handle = cpu_to_le16(hchan->handle); - hci_send_cmd(hcon->hdev, HCI_OP_DISCONN_LOGICAL_LINK, sizeof(cp), &cp); -} - -void amp_destroy_logical_link(struct hci_chan *hchan, u8 reason) -{ - BT_DBG("hchan %p", hchan); - - hci_chan_del(hchan); -} diff --git a/trunk/net/bluetooth/bnep/netdev.c b/trunk/net/bluetooth/bnep/netdev.c index e58c8b32589c..98f86f91d47c 100644 --- a/trunk/net/bluetooth/bnep/netdev.c +++ b/trunk/net/bluetooth/bnep/netdev.c @@ -25,6 +25,7 @@ SOFTWARE IS DISCLAIMED. */ +#include #include #include diff --git a/trunk/net/bluetooth/cmtp/capi.c b/trunk/net/bluetooth/cmtp/capi.c index a4a9d4b6816c..50f0d135eb8f 100644 --- a/trunk/net/bluetooth/cmtp/capi.c +++ b/trunk/net/bluetooth/cmtp/capi.c @@ -20,7 +20,7 @@ SOFTWARE IS DISCLAIMED. */ -#include +#include #include #include #include diff --git a/trunk/net/bluetooth/cmtp/sock.c b/trunk/net/bluetooth/cmtp/sock.c index 1c57482112b6..aacb802d1ee4 100644 --- a/trunk/net/bluetooth/cmtp/sock.c +++ b/trunk/net/bluetooth/cmtp/sock.c @@ -20,7 +20,7 @@ SOFTWARE IS DISCLAIMED. */ -#include +#include #include #include diff --git a/trunk/net/bluetooth/hci_conn.c b/trunk/net/bluetooth/hci_conn.c index 25bfce0666eb..fe646211c61f 100644 --- a/trunk/net/bluetooth/hci_conn.c +++ b/trunk/net/bluetooth/hci_conn.c @@ -502,9 +502,6 @@ static struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst, { struct hci_conn *le; - if (test_bit(HCI_LE_PERIPHERAL, &hdev->flags)) - return ERR_PTR(-ENOTSUPP); - le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst); if (!le) { le = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT); @@ -962,7 +959,6 @@ struct hci_chan *hci_chan_create(struct hci_conn *conn) chan->conn = conn; skb_queue_head_init(&chan->data_q); - chan->state = BT_CONNECTED; list_add_rcu(&chan->list, &conn->chan_list); @@ -980,8 +976,6 @@ void hci_chan_del(struct hci_chan *chan) synchronize_rcu(); - hci_conn_put(conn); - skb_queue_purge(&chan->data_q); kfree(chan); } diff --git a/trunk/net/bluetooth/hci_core.c b/trunk/net/bluetooth/hci_core.c index 596660d37c5e..5a3f941b610f 100644 --- a/trunk/net/bluetooth/hci_core.c +++ b/trunk/net/bluetooth/hci_core.c @@ -178,13 +178,48 @@ static void hci_reset_req(struct hci_dev *hdev, unsigned long opt) static void bredr_init(struct hci_dev *hdev) { + struct hci_cp_delete_stored_link_key cp; + __le16 param; + __u8 flt_type; + hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_PACKET_BASED; + /* Mandatory initialization */ + /* Read Local Supported Features */ hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); /* Read Local Version */ hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL); + + /* Read Buffer Size (ACL mtu, max pkt, etc.) */ + hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL); + + /* Read BD Address */ + hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL); + + /* Read Class of Device */ + hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL); + + /* Read Local Name */ + hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL); + + /* Read Voice Setting */ + hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL); + + /* Optional initialization */ + + /* Clear Event Filters */ + flt_type = HCI_FLT_CLEAR_ALL; + hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type); + + /* Connection accept timeout ~20 secs */ + param = __constant_cpu_to_le16(0x7d00); + hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); + + bacpy(&cp.bdaddr, BDADDR_ANY); + cp.delete_all = 1; + hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp); } static void amp_init(struct hci_dev *hdev) @@ -238,6 +273,14 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt) } } +static void hci_le_init_req(struct hci_dev *hdev, unsigned long opt) +{ + BT_DBG("%s", hdev->name); + + /* Read LE buffer size */ + hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); +} + static void hci_scan_req(struct hci_dev *hdev, unsigned long opt) { __u8 scan = opt; @@ -434,8 +477,6 @@ bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, BT_DBG("cache %p, %pMR", cache, &data->bdaddr); - hci_remove_remote_oob_data(hdev, &data->bdaddr); - if (ssp) *ssp = data->ssp_mode; @@ -596,99 +637,6 @@ int hci_inquiry(void __user *arg) return err; } -static u8 create_ad(struct hci_dev *hdev, u8 *ptr) -{ - u8 ad_len = 0, flags = 0; - size_t name_len; - - if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags)) - flags |= LE_AD_GENERAL; - - if (!lmp_bredr_capable(hdev)) - flags |= LE_AD_NO_BREDR; - - if (lmp_le_br_capable(hdev)) - flags |= LE_AD_SIM_LE_BREDR_CTRL; - - if (lmp_host_le_br_capable(hdev)) - flags |= LE_AD_SIM_LE_BREDR_HOST; - - if (flags) { - BT_DBG("adv flags 0x%02x", flags); - - ptr[0] = 2; - ptr[1] = EIR_FLAGS; - ptr[2] = flags; - - ad_len += 3; - ptr += 3; - } - - if (hdev->adv_tx_power != HCI_TX_POWER_INVALID) { - ptr[0] = 2; - ptr[1] = EIR_TX_POWER; - ptr[2] = (u8) hdev->adv_tx_power; - - ad_len += 3; - ptr += 3; - } - - name_len = strlen(hdev->dev_name); - if (name_len > 0) { - size_t max_len = HCI_MAX_AD_LENGTH - ad_len - 2; - - if (name_len > max_len) { - name_len = max_len; - ptr[1] = EIR_NAME_SHORT; - } else - ptr[1] = EIR_NAME_COMPLETE; - - ptr[0] = name_len + 1; - - memcpy(ptr + 2, hdev->dev_name, name_len); - - ad_len += (name_len + 2); - ptr += (name_len + 2); - } - - return ad_len; -} - -int hci_update_ad(struct hci_dev *hdev) -{ - struct hci_cp_le_set_adv_data cp; - u8 len; - int err; - - hci_dev_lock(hdev); - - if (!lmp_le_capable(hdev)) { - err = -EINVAL; - goto unlock; - } - - memset(&cp, 0, sizeof(cp)); - - len = create_ad(hdev, cp.data); - - if (hdev->adv_data_len == len && - memcmp(cp.data, hdev->adv_data, len) == 0) { - err = 0; - goto unlock; - } - - memcpy(hdev->adv_data, cp.data, sizeof(cp.data)); - hdev->adv_data_len = len; - - cp.length = len; - err = hci_send_cmd(hdev, HCI_OP_LE_SET_ADV_DATA, sizeof(cp), &cp); - -unlock: - hci_dev_unlock(hdev); - - return err; -} - /* ---- HCI ioctl helpers ---- */ int hci_dev_open(__u16 dev) @@ -739,6 +687,10 @@ int hci_dev_open(__u16 dev) ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT); + if (lmp_host_le_capable(hdev)) + ret = __hci_request(hdev, hci_le_init_req, 0, + HCI_INIT_TIMEOUT); + clear_bit(HCI_INIT, &hdev->flags); } @@ -746,7 +698,6 @@ int hci_dev_open(__u16 dev) hci_dev_hold(hdev); set_bit(HCI_UP, &hdev->flags); hci_notify(hdev, HCI_DEV_UP); - hci_update_ad(hdev); if (!test_bit(HCI_SETUP, &hdev->dev_flags) && mgmt_valid_hdev(hdev)) { hci_dev_lock(hdev); @@ -861,9 +812,6 @@ static int hci_dev_do_close(struct hci_dev *hdev) /* Clear flags */ hdev->flags = 0; - /* Controller radio is available but is currently powered down */ - hdev->amp_status = 0; - memset(hdev->eir, 0, sizeof(hdev->eir)); memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); @@ -1091,17 +1039,10 @@ int hci_get_dev_info(void __user *arg) di.type = (hdev->bus & 0x0f) | (hdev->dev_type << 4); di.flags = hdev->flags; di.pkt_type = hdev->pkt_type; - if (lmp_bredr_capable(hdev)) { - di.acl_mtu = hdev->acl_mtu; - di.acl_pkts = hdev->acl_pkts; - di.sco_mtu = hdev->sco_mtu; - di.sco_pkts = hdev->sco_pkts; - } else { - di.acl_mtu = hdev->le_mtu; - di.acl_pkts = hdev->le_pkts; - di.sco_mtu = 0; - di.sco_pkts = 0; - } + di.acl_mtu = hdev->acl_mtu; + di.acl_pkts = hdev->acl_pkts; + di.sco_mtu = hdev->sco_mtu; + di.sco_pkts = hdev->sco_pkts; di.link_policy = hdev->link_policy; di.link_mode = hdev->link_mode; @@ -1676,9 +1617,6 @@ int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window, BT_DBG("%s", hdev->name); - if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags)) - return -ENOTSUPP; - if (work_busy(&hdev->le_scan)) return -EINPROGRESS; @@ -1705,8 +1643,6 @@ struct hci_dev *hci_alloc_dev(void) hdev->esco_type = (ESCO_HV1); hdev->link_mode = (HCI_LM_ACCEPT); hdev->io_capability = 0x03; /* No Input No Output */ - hdev->inq_tx_power = HCI_TX_POWER_INVALID; - hdev->adv_tx_power = HCI_TX_POWER_INVALID; hdev->sniff_max_interval = 800; hdev->sniff_min_interval = 80; @@ -1818,11 +1754,11 @@ int hci_register_dev(struct hci_dev *hdev) if (hdev->dev_type != HCI_AMP) set_bit(HCI_AUTO_OFF, &hdev->dev_flags); + schedule_work(&hdev->power_on); + hci_notify(hdev, HCI_DEV_REG); hci_dev_hold(hdev); - schedule_work(&hdev->power_on); - return id; err_wqueue: @@ -1857,8 +1793,6 @@ void hci_unregister_dev(struct hci_dev *hdev) for (i = 0; i < NUM_REASSEMBLY; i++) kfree_skb(hdev->reassembly[i]); - cancel_work_sync(&hdev->power_on); - if (!test_bit(HCI_INIT, &hdev->flags) && !test_bit(HCI_SETUP, &hdev->dev_flags)) { hci_dev_lock(hdev); diff --git a/trunk/net/bluetooth/hci_event.c b/trunk/net/bluetooth/hci_event.c index 705078a0cc39..0383635f91fb 100644 --- a/trunk/net/bluetooth/hci_event.c +++ b/trunk/net/bluetooth/hci_event.c @@ -24,6 +24,7 @@ /* Bluetooth HCI event handling. */ +#include #include #include @@ -202,11 +203,6 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) BIT(HCI_PERIODIC_INQ)); hdev->discovery.state = DISCOVERY_STOPPED; - hdev->inq_tx_power = HCI_TX_POWER_INVALID; - hdev->adv_tx_power = HCI_TX_POWER_INVALID; - - memset(hdev->adv_data, 0, sizeof(hdev->adv_data)); - hdev->adv_data_len = 0; } static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) @@ -229,9 +225,6 @@ static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_unlock(hdev); - if (!status && !test_bit(HCI_INIT, &hdev->flags)) - hci_update_ad(hdev); - hci_req_complete(hdev, HCI_OP_WRITE_LOCAL_NAME, status); } @@ -447,7 +440,7 @@ static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); - struct hci_cp_write_ssp_mode *sent; + void *sent; BT_DBG("%s status 0x%2.2x", hdev->name, status); @@ -455,17 +448,10 @@ static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) if (!sent) return; - if (!status) { - if (sent->mode) - hdev->host_features[0] |= LMP_HOST_SSP; - else - hdev->host_features[0] &= ~LMP_HOST_SSP; - } - if (test_bit(HCI_MGMT, &hdev->dev_flags)) - mgmt_ssp_enable_complete(hdev, sent->mode, status); + mgmt_ssp_enable_complete(hdev, *((u8 *) sent), status); else if (!status) { - if (sent->mode) + if (*((u8 *) sent)) set_bit(HCI_SSP_ENABLED, &hdev->dev_flags); else clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags); @@ -474,10 +460,10 @@ static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) static u8 hci_get_inquiry_mode(struct hci_dev *hdev) { - if (lmp_ext_inq_capable(hdev)) + if (hdev->features[6] & LMP_EXT_INQ) return 2; - if (lmp_inq_rssi_capable(hdev)) + if (hdev->features[3] & LMP_RSSI_INQ) return 1; if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 && @@ -521,30 +507,28 @@ static void hci_setup_event_mask(struct hci_dev *hdev) if (hdev->hci_ver < BLUETOOTH_VER_1_2) return; - if (lmp_bredr_capable(hdev)) { - events[4] |= 0x01; /* Flow Specification Complete */ - events[4] |= 0x02; /* Inquiry Result with RSSI */ - events[4] |= 0x04; /* Read Remote Extended Features Complete */ - events[5] |= 0x08; /* Synchronous Connection Complete */ - events[5] |= 0x10; /* Synchronous Connection Changed */ - } + events[4] |= 0x01; /* Flow Specification Complete */ + events[4] |= 0x02; /* Inquiry Result with RSSI */ + events[4] |= 0x04; /* Read Remote Extended Features Complete */ + events[5] |= 0x08; /* Synchronous Connection Complete */ + events[5] |= 0x10; /* Synchronous Connection Changed */ - if (lmp_inq_rssi_capable(hdev)) + if (hdev->features[3] & LMP_RSSI_INQ) events[4] |= 0x02; /* Inquiry Result with RSSI */ if (lmp_sniffsubr_capable(hdev)) events[5] |= 0x20; /* Sniff Subrating */ - if (lmp_pause_enc_capable(hdev)) + if (hdev->features[5] & LMP_PAUSE_ENC) events[5] |= 0x80; /* Encryption Key Refresh Complete */ - if (lmp_ext_inq_capable(hdev)) + if (hdev->features[6] & LMP_EXT_INQ) events[5] |= 0x40; /* Extended Inquiry Result */ if (lmp_no_flush_capable(hdev)) events[7] |= 0x01; /* Enhanced Flush Complete */ - if (lmp_lsto_capable(hdev)) + if (hdev->features[7] & LMP_LSTO) events[6] |= 0x80; /* Link Supervision Timeout Changed */ if (lmp_ssp_capable(hdev)) { @@ -564,53 +548,6 @@ static void hci_setup_event_mask(struct hci_dev *hdev) events[7] |= 0x20; /* LE Meta-Event */ hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events); - - if (lmp_le_capable(hdev)) { - memset(events, 0, sizeof(events)); - events[0] = 0x1f; - hci_send_cmd(hdev, HCI_OP_LE_SET_EVENT_MASK, - sizeof(events), events); - } -} - -static void bredr_setup(struct hci_dev *hdev) -{ - struct hci_cp_delete_stored_link_key cp; - __le16 param; - __u8 flt_type; - - /* Read Buffer Size (ACL mtu, max pkt, etc.) */ - hci_send_cmd(hdev, HCI_OP_READ_BUFFER_SIZE, 0, NULL); - - /* Read Class of Device */ - hci_send_cmd(hdev, HCI_OP_READ_CLASS_OF_DEV, 0, NULL); - - /* Read Local Name */ - hci_send_cmd(hdev, HCI_OP_READ_LOCAL_NAME, 0, NULL); - - /* Read Voice Setting */ - hci_send_cmd(hdev, HCI_OP_READ_VOICE_SETTING, 0, NULL); - - /* Clear Event Filters */ - flt_type = HCI_FLT_CLEAR_ALL; - hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type); - - /* Connection accept timeout ~20 secs */ - param = __constant_cpu_to_le16(0x7d00); - hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); - - bacpy(&cp.bdaddr, BDADDR_ANY); - cp.delete_all = 1; - hci_send_cmd(hdev, HCI_OP_DELETE_STORED_LINK_KEY, sizeof(cp), &cp); -} - -static void le_setup(struct hci_dev *hdev) -{ - /* Read LE Buffer Size */ - hci_send_cmd(hdev, HCI_OP_LE_READ_BUFFER_SIZE, 0, NULL); - - /* Read LE Advertising Channel TX Power */ - hci_send_cmd(hdev, HCI_OP_LE_READ_ADV_TX_POWER, 0, NULL); } static void hci_setup(struct hci_dev *hdev) @@ -618,15 +555,6 @@ static void hci_setup(struct hci_dev *hdev) if (hdev->dev_type != HCI_BREDR) return; - /* Read BD Address */ - hci_send_cmd(hdev, HCI_OP_READ_BD_ADDR, 0, NULL); - - if (lmp_bredr_capable(hdev)) - bredr_setup(hdev); - - if (lmp_le_capable(hdev)) - le_setup(hdev); - hci_setup_event_mask(hdev); if (hdev->hci_ver > BLUETOOTH_VER_1_1) @@ -647,13 +575,13 @@ static void hci_setup(struct hci_dev *hdev) } } - if (lmp_inq_rssi_capable(hdev)) + if (hdev->features[3] & LMP_RSSI_INQ) hci_setup_inquiry_mode(hdev); - if (lmp_inq_tx_pwr_capable(hdev)) + if (hdev->features[7] & LMP_INQ_TX_PWR) hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL); - if (lmp_ext_feat_capable(hdev)) { + if (hdev->features[7] & LMP_EXTFEATURES) { struct hci_cp_read_local_ext_features cp; cp.page = 0x01; @@ -700,11 +628,11 @@ static void hci_setup_link_policy(struct hci_dev *hdev) if (lmp_rswitch_capable(hdev)) link_policy |= HCI_LP_RSWITCH; - if (lmp_hold_capable(hdev)) + if (hdev->features[0] & LMP_HOLD) link_policy |= HCI_LP_HOLD; if (lmp_sniff_capable(hdev)) link_policy |= HCI_LP_SNIFF; - if (lmp_park_capable(hdev)) + if (hdev->features[1] & LMP_PARK) link_policy |= HCI_LP_PARK; cp.policy = cpu_to_le16(link_policy); @@ -794,10 +722,10 @@ static void hci_set_le_support(struct hci_dev *hdev) if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { cp.le = 1; - cp.simul = lmp_le_br_capable(hdev); + cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR); } - if (cp.le != lmp_host_le_capable(hdev)) + if (cp.le != !!(hdev->host_features[0] & LMP_HOST_LE)) hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), &cp); } @@ -1090,31 +1018,6 @@ static void hci_cc_le_read_buffer_size(struct hci_dev *hdev, hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status); } -static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev, - struct sk_buff *skb) -{ - struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data; - - BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); - - if (!rp->status) { - hdev->adv_tx_power = rp->tx_power; - if (!test_bit(HCI_INIT, &hdev->flags)) - hci_update_ad(hdev); - } - - hci_req_complete(hdev, HCI_OP_LE_READ_ADV_TX_POWER, rp->status); -} - -static void hci_cc_le_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb) -{ - __u8 status = *((__u8 *) skb->data); - - BT_DBG("%s status 0x%2.2x", hdev->name, status); - - hci_req_complete(hdev, HCI_OP_LE_SET_EVENT_MASK, status); -} - static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_rp_user_confirm_reply *rp = (void *) skb->data; @@ -1190,33 +1093,6 @@ static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev, hci_dev_unlock(hdev); } -static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb) -{ - __u8 *sent, status = *((__u8 *) skb->data); - - BT_DBG("%s status 0x%2.2x", hdev->name, status); - - sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE); - if (!sent) - return; - - hci_dev_lock(hdev); - - if (!status) { - if (*sent) - set_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags); - else - clear_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags); - } - - hci_dev_unlock(hdev); - - if (!test_bit(HCI_INIT, &hdev->flags)) - hci_update_ad(hdev); - - hci_req_complete(hdev, HCI_OP_LE_SET_ADV_ENABLE, status); -} - static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); @@ -1331,11 +1207,6 @@ static void hci_cc_write_le_host_supported(struct hci_dev *hdev, hdev->host_features[0] |= LMP_HOST_LE; else hdev->host_features[0] &= ~LMP_HOST_LE; - - if (sent->simul) - hdev->host_features[0] |= LMP_HOST_LE_BREDR; - else - hdev->host_features[0] &= ~LMP_HOST_LE_BREDR; } if (test_bit(HCI_MGMT, &hdev->dev_flags) && @@ -1847,23 +1718,14 @@ static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status) BT_DBG("%s status 0x%2.2x", hdev->name, status); + if (status) + return; + cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK); if (!cp) return; - hci_dev_lock(hdev); - - if (status) { - struct hci_conn *hcon; - - hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle); - if (hcon) - hci_conn_del(hcon); - } else { - amp_write_remote_assoc(hdev, cp->phy_handle); - } - - hci_dev_unlock(hdev); + amp_write_remote_assoc(hdev, cp->phy_handle); } static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status) @@ -1882,11 +1744,6 @@ static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status) amp_write_remote_assoc(hdev, cp->phy_handle); } -static void hci_cs_create_logical_link(struct hci_dev *hdev, u8 status) -{ - BT_DBG("%s status 0x%2.2x", hdev->name, status); -} - static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); @@ -2047,53 +1904,15 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_conn_check_pending(hdev); } -void hci_conn_accept(struct hci_conn *conn, int mask) -{ - struct hci_dev *hdev = conn->hdev; - - BT_DBG("conn %p", conn); - - conn->state = BT_CONFIG; - - if (!lmp_esco_capable(hdev)) { - struct hci_cp_accept_conn_req cp; - - bacpy(&cp.bdaddr, &conn->dst); - - if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER)) - cp.role = 0x00; /* Become master */ - else - cp.role = 0x01; /* Remain slave */ - - hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp); - } else /* lmp_esco_capable(hdev)) */ { - struct hci_cp_accept_sync_conn_req cp; - - bacpy(&cp.bdaddr, &conn->dst); - cp.pkt_type = cpu_to_le16(conn->pkt_type); - - cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40); - cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40); - cp.max_latency = __constant_cpu_to_le16(0xffff); - cp.content_format = cpu_to_le16(hdev->voice_setting); - cp.retrans_effort = 0xff; - - hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, - sizeof(cp), &cp); - } -} - static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_conn_request *ev = (void *) skb->data; int mask = hdev->link_mode; - __u8 flags = 0; BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr, ev->link_type); - mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type, - &flags); + mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type); if ((mask & HCI_LM_ACCEPT) && !hci_blacklist_lookup(hdev, &ev->bdaddr)) { @@ -2119,13 +1938,12 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) } memcpy(conn->dev_class, ev->dev_class, 3); + conn->state = BT_CONNECT; hci_dev_unlock(hdev); - if (ev->link_type == ACL_LINK || - (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) { + if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) { struct hci_cp_accept_conn_req cp; - conn->state = BT_CONNECT; bacpy(&cp.bdaddr, &ev->bdaddr); @@ -2136,9 +1954,8 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp); - } else if (!(flags & HCI_PROTO_DEFER)) { + } else { struct hci_cp_accept_sync_conn_req cp; - conn->state = BT_CONNECT; bacpy(&cp.bdaddr, &ev->bdaddr); cp.pkt_type = cpu_to_le16(conn->pkt_type); @@ -2151,10 +1968,6 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, sizeof(cp), &cp); - } else { - conn->state = BT_CONNECT2; - hci_proto_connect_cfm(conn, 0); - hci_conn_put(conn); } } else { /* Connection rejected */ @@ -2628,14 +2441,6 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_cc_le_read_buffer_size(hdev, skb); break; - case HCI_OP_LE_READ_ADV_TX_POWER: - hci_cc_le_read_adv_tx_power(hdev, skb); - break; - - case HCI_OP_LE_SET_EVENT_MASK: - hci_cc_le_set_event_mask(hdev, skb); - break; - case HCI_OP_USER_CONFIRM_REPLY: hci_cc_user_confirm_reply(hdev, skb); break; @@ -2656,10 +2461,6 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_cc_le_set_scan_param(hdev, skb); break; - case HCI_OP_LE_SET_ADV_ENABLE: - hci_cc_le_set_adv_enable(hdev, skb); - break; - case HCI_OP_LE_SET_SCAN_ENABLE: hci_cc_le_set_scan_enable(hdev, skb); break; @@ -2769,10 +2570,6 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_cs_accept_phylink(hdev, ev->status); break; - case HCI_OP_CREATE_LOGICAL_LINK: - hci_cs_create_logical_link(hdev, ev->status); - break; - default: BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); break; @@ -3747,130 +3544,6 @@ static void hci_remote_oob_data_request_evt(struct hci_dev *hdev, hci_dev_unlock(hdev); } -static void hci_phy_link_complete_evt(struct hci_dev *hdev, - struct sk_buff *skb) -{ - struct hci_ev_phy_link_complete *ev = (void *) skb->data; - struct hci_conn *hcon, *bredr_hcon; - - BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle, - ev->status); - - hci_dev_lock(hdev); - - hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); - if (!hcon) { - hci_dev_unlock(hdev); - return; - } - - if (ev->status) { - hci_conn_del(hcon); - hci_dev_unlock(hdev); - return; - } - - bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon; - - hcon->state = BT_CONNECTED; - bacpy(&hcon->dst, &bredr_hcon->dst); - - hci_conn_hold(hcon); - hcon->disc_timeout = HCI_DISCONN_TIMEOUT; - hci_conn_put(hcon); - - hci_conn_hold_device(hcon); - hci_conn_add_sysfs(hcon); - - amp_physical_cfm(bredr_hcon, hcon); - - hci_dev_unlock(hdev); -} - -static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) -{ - struct hci_ev_logical_link_complete *ev = (void *) skb->data; - struct hci_conn *hcon; - struct hci_chan *hchan; - struct amp_mgr *mgr; - - BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x", - hdev->name, le16_to_cpu(ev->handle), ev->phy_handle, - ev->status); - - hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); - if (!hcon) - return; - - /* Create AMP hchan */ - hchan = hci_chan_create(hcon); - if (!hchan) - return; - - hchan->handle = le16_to_cpu(ev->handle); - - BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan); - - mgr = hcon->amp_mgr; - if (mgr && mgr->bredr_chan) { - struct l2cap_chan *bredr_chan = mgr->bredr_chan; - - l2cap_chan_lock(bredr_chan); - - bredr_chan->conn->mtu = hdev->block_mtu; - l2cap_logical_cfm(bredr_chan, hchan, 0); - hci_conn_hold(hcon); - - l2cap_chan_unlock(bredr_chan); - } -} - -static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev, - struct sk_buff *skb) -{ - struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data; - struct hci_chan *hchan; - - BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name, - le16_to_cpu(ev->handle), ev->status); - - if (ev->status) - return; - - hci_dev_lock(hdev); - - hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle)); - if (!hchan) - goto unlock; - - amp_destroy_logical_link(hchan, ev->reason); - -unlock: - hci_dev_unlock(hdev); -} - -static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev, - struct sk_buff *skb) -{ - struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data; - struct hci_conn *hcon; - - BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); - - if (ev->status) - return; - - hci_dev_lock(hdev); - - hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle); - if (hcon) { - hcon->state = BT_CLOSED; - hci_conn_del(hcon); - } - - hci_dev_unlock(hdev); -} - static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_le_conn_complete *ev = (void *) skb->data; @@ -4198,22 +3871,6 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) hci_remote_oob_data_request_evt(hdev, skb); break; - case HCI_EV_PHY_LINK_COMPLETE: - hci_phy_link_complete_evt(hdev, skb); - break; - - case HCI_EV_LOGICAL_LINK_COMPLETE: - hci_loglink_complete_evt(hdev, skb); - break; - - case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE: - hci_disconn_loglink_complete_evt(hdev, skb); - break; - - case HCI_EV_DISCONN_PHY_LINK_COMPLETE: - hci_disconn_phylink_complete_evt(hdev, skb); - break; - case HCI_EV_NUM_COMP_BLOCKS: hci_num_comp_blocks_evt(hdev, skb); break; diff --git a/trunk/net/bluetooth/l2cap_core.c b/trunk/net/bluetooth/l2cap_core.c index 2c78208d793e..08efc256c931 100644 --- a/trunk/net/bluetooth/l2cap_core.c +++ b/trunk/net/bluetooth/l2cap_core.c @@ -38,7 +38,6 @@ #include #include #include -#include bool disable_ertm; @@ -53,7 +52,8 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, void *data); static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data); -static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err); +static void l2cap_send_disconn_req(struct l2cap_conn *conn, + struct l2cap_chan *chan, int err); static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control, struct sk_buff_head *skbs, u8 event); @@ -100,23 +100,6 @@ static struct l2cap_chan *l2cap_get_chan_by_scid(struct l2cap_conn *conn, return c; } -/* Find channel with given DCID. - * Returns locked channel. - */ -static struct l2cap_chan *l2cap_get_chan_by_dcid(struct l2cap_conn *conn, - u16 cid) -{ - struct l2cap_chan *c; - - mutex_lock(&conn->chan_lock); - c = __l2cap_get_chan_by_dcid(conn, cid); - if (c) - l2cap_chan_lock(c); - mutex_unlock(&conn->chan_lock); - - return c; -} - static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn, u8 ident) { @@ -129,20 +112,6 @@ static struct l2cap_chan *__l2cap_get_chan_by_ident(struct l2cap_conn *conn, return NULL; } -static struct l2cap_chan *l2cap_get_chan_by_ident(struct l2cap_conn *conn, - u8 ident) -{ - struct l2cap_chan *c; - - mutex_lock(&conn->chan_lock); - c = __l2cap_get_chan_by_ident(conn, ident); - if (c) - l2cap_chan_lock(c); - mutex_unlock(&conn->chan_lock); - - return c; -} - static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src) { struct l2cap_chan *c; @@ -577,13 +546,6 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) mgr->bredr_chan = NULL; } - if (chan->hs_hchan) { - struct hci_chan *hs_hchan = chan->hs_hchan; - - BT_DBG("chan %p disconnect hs_hchan %p", chan, hs_hchan); - amp_disconnect_logical_link(hs_hchan); - } - chan->ops->teardown(chan, err); if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state)) @@ -631,7 +593,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason) if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && conn->hcon->type == ACL_LINK) { __set_chan_timer(chan, sk->sk_sndtimeo); - l2cap_send_disconn_req(chan, reason); + l2cap_send_disconn_req(conn, chan, reason); } else l2cap_chan_del(chan, reason); break; @@ -756,12 +718,6 @@ static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, hci_send_acl(conn->hchan, skb, flags); } -static bool __chan_is_moving(struct l2cap_chan *chan) -{ - return chan->move_state != L2CAP_MOVE_STABLE && - chan->move_state != L2CAP_MOVE_WAIT_PREPARE; -} - static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb) { struct hci_conn *hcon = chan->conn->hcon; @@ -770,15 +726,6 @@ static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb) BT_DBG("chan %p, skb %p len %d priority %u", chan, skb, skb->len, skb->priority); - if (chan->hs_hcon && !__chan_is_moving(chan)) { - if (chan->hs_hchan) - hci_send_acl(chan->hs_hchan, skb, ACL_COMPLETE); - else - kfree_skb(skb); - - return; - } - if (!test_bit(FLAG_FLUSHABLE, &chan->flags) && lmp_no_flush_capable(hcon->hdev)) flags = ACL_START_NO_FLUSH; @@ -954,9 +901,6 @@ static void l2cap_send_sframe(struct l2cap_chan *chan, if (!control->sframe) return; - if (__chan_is_moving(chan)) - return; - if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) && !control->poll) control->final = 1; @@ -1013,7 +957,6 @@ static bool __amp_capable(struct l2cap_chan *chan) struct l2cap_conn *conn = chan->conn; if (enable_hs && - hci_amp_capable() && chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED && conn->fixed_chan_mask & L2CAP_FC_A2MP) return true; @@ -1021,12 +964,6 @@ static bool __amp_capable(struct l2cap_chan *chan) return false; } -static bool l2cap_check_efs(struct l2cap_chan *chan) -{ - /* Check EFS parameters */ - return true; -} - void l2cap_send_conn_req(struct l2cap_chan *chan) { struct l2cap_conn *conn = chan->conn; @@ -1042,76 +979,6 @@ void l2cap_send_conn_req(struct l2cap_chan *chan) l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_REQ, sizeof(req), &req); } -static void l2cap_send_create_chan_req(struct l2cap_chan *chan, u8 amp_id) -{ - struct l2cap_create_chan_req req; - req.scid = cpu_to_le16(chan->scid); - req.psm = chan->psm; - req.amp_id = amp_id; - - chan->ident = l2cap_get_ident(chan->conn); - - l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_REQ, - sizeof(req), &req); -} - -static void l2cap_move_setup(struct l2cap_chan *chan) -{ - struct sk_buff *skb; - - BT_DBG("chan %p", chan); - - if (chan->mode != L2CAP_MODE_ERTM) - return; - - __clear_retrans_timer(chan); - __clear_monitor_timer(chan); - __clear_ack_timer(chan); - - chan->retry_count = 0; - skb_queue_walk(&chan->tx_q, skb) { - if (bt_cb(skb)->control.retries) - bt_cb(skb)->control.retries = 1; - else - break; - } - - chan->expected_tx_seq = chan->buffer_seq; - - clear_bit(CONN_REJ_ACT, &chan->conn_state); - clear_bit(CONN_SREJ_ACT, &chan->conn_state); - l2cap_seq_list_clear(&chan->retrans_list); - l2cap_seq_list_clear(&chan->srej_list); - skb_queue_purge(&chan->srej_q); - - chan->tx_state = L2CAP_TX_STATE_XMIT; - chan->rx_state = L2CAP_RX_STATE_MOVE; - - set_bit(CONN_REMOTE_BUSY, &chan->conn_state); -} - -static void l2cap_move_done(struct l2cap_chan *chan) -{ - u8 move_role = chan->move_role; - BT_DBG("chan %p", chan); - - chan->move_state = L2CAP_MOVE_STABLE; - chan->move_role = L2CAP_MOVE_ROLE_NONE; - - if (chan->mode != L2CAP_MODE_ERTM) - return; - - switch (move_role) { - case L2CAP_MOVE_ROLE_INITIATOR: - l2cap_tx(chan, NULL, NULL, L2CAP_EV_EXPLICIT_POLL); - chan->rx_state = L2CAP_RX_STATE_WAIT_F; - break; - case L2CAP_MOVE_ROLE_RESPONDER: - chan->rx_state = L2CAP_RX_STATE_WAIT_P; - break; - } -} - static void l2cap_chan_ready(struct l2cap_chan *chan) { /* This clears all conf flags, including CONF_NOT_COMPLETE */ @@ -1180,10 +1047,10 @@ static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask) } } -static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err) +static void l2cap_send_disconn_req(struct l2cap_conn *conn, + struct l2cap_chan *chan, int err) { struct sock *sk = chan->sk; - struct l2cap_conn *conn = chan->conn; struct l2cap_disconn_req req; if (!conn) @@ -1828,9 +1695,6 @@ static void l2cap_streaming_send(struct l2cap_chan *chan, BT_DBG("chan %p, skbs %p", chan, skbs); - if (__chan_is_moving(chan)) - return; - skb_queue_splice_tail_init(skbs, &chan->tx_q); while (!skb_queue_empty(&chan->tx_q)) { @@ -1873,9 +1737,6 @@ static int l2cap_ertm_send(struct l2cap_chan *chan) if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) return 0; - if (__chan_is_moving(chan)) - return 0; - while (chan->tx_send_head && chan->unacked_frames < chan->remote_tx_win && chan->tx_state == L2CAP_TX_STATE_XMIT) { @@ -1941,9 +1802,6 @@ static void l2cap_ertm_resend(struct l2cap_chan *chan) if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) return; - if (__chan_is_moving(chan)) - return; - while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) { seq = l2cap_seq_list_pop(&chan->retrans_list); @@ -1960,7 +1818,7 @@ static void l2cap_ertm_resend(struct l2cap_chan *chan) if (chan->max_tx != 0 && bt_cb(skb)->control.retries > chan->max_tx) { BT_DBG("Retry limit exceeded (%d)", chan->max_tx); - l2cap_send_disconn_req(chan, ECONNRESET); + l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); l2cap_seq_list_clear(&chan->retrans_list); break; } @@ -2286,9 +2144,7 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan, /* PDU size is derived from the HCI MTU */ pdu_len = chan->conn->mtu; - /* Constrain PDU size for BR/EDR connections */ - if (!chan->hs_hcon) - pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD); + pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD); /* Adjust for largest possible L2CAP overhead. */ if (chan->fcs) @@ -2666,7 +2522,7 @@ static void l2cap_tx_state_wait_f(struct l2cap_chan *chan, __set_monitor_timer(chan); chan->retry_count++; } else { - l2cap_send_disconn_req(chan, ECONNABORTED); + l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED); } break; default: @@ -2932,11 +2788,6 @@ int l2cap_ertm_init(struct l2cap_chan *chan) skb_queue_head_init(&chan->tx_q); - chan->local_amp_id = 0; - chan->move_id = 0; - chan->move_state = L2CAP_MOVE_STABLE; - chan->move_role = L2CAP_MOVE_ROLE_NONE; - if (chan->mode != L2CAP_MODE_ERTM) return 0; @@ -2983,44 +2834,6 @@ static inline bool __l2cap_efs_supported(struct l2cap_chan *chan) return enable_hs && chan->conn->feat_mask & L2CAP_FEAT_EXT_FLOW; } -static void __l2cap_set_ertm_timeouts(struct l2cap_chan *chan, - struct l2cap_conf_rfc *rfc) -{ - if (chan->local_amp_id && chan->hs_hcon) { - u64 ertm_to = chan->hs_hcon->hdev->amp_be_flush_to; - - /* Class 1 devices have must have ERTM timeouts - * exceeding the Link Supervision Timeout. The - * default Link Supervision Timeout for AMP - * controllers is 10 seconds. - * - * Class 1 devices use 0xffffffff for their - * best-effort flush timeout, so the clamping logic - * will result in a timeout that meets the above - * requirement. ERTM timeouts are 16-bit values, so - * the maximum timeout is 65.535 seconds. - */ - - /* Convert timeout to milliseconds and round */ - ertm_to = DIV_ROUND_UP_ULL(ertm_to, 1000); - - /* This is the recommended formula for class 2 devices - * that start ERTM timers when packets are sent to the - * controller. - */ - ertm_to = 3 * ertm_to + 500; - - if (ertm_to > 0xffff) - ertm_to = 0xffff; - - rfc->retrans_timeout = cpu_to_le16((u16) ertm_to); - rfc->monitor_timeout = rfc->retrans_timeout; - } else { - rfc->retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO); - rfc->monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO); - } -} - static inline void l2cap_txwin_setup(struct l2cap_chan *chan) { if (chan->tx_win > L2CAP_DEFAULT_TX_WINDOW && @@ -3087,8 +2900,8 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) case L2CAP_MODE_ERTM: rfc.mode = L2CAP_MODE_ERTM; rfc.max_transmit = chan->max_tx; - - __l2cap_set_ertm_timeouts(chan, &rfc); + rfc.retrans_timeout = 0; + rfc.monitor_timeout = 0; size = min_t(u16, L2CAP_DEFAULT_MAX_PDU_SIZE, chan->conn->mtu - L2CAP_EXT_HDR_SIZE - L2CAP_SDULEN_SIZE - @@ -3106,17 +2919,18 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) l2cap_add_opt_efs(&ptr, chan); + if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS)) + break; + + if (chan->fcs == L2CAP_FCS_NONE || + test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) { + chan->fcs = L2CAP_FCS_NONE; + l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs); + } + if (test_bit(FLAG_EXT_CTRL, &chan->flags)) l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2, chan->tx_win); - - if (chan->conn->feat_mask & L2CAP_FEAT_FCS) - if (chan->fcs == L2CAP_FCS_NONE || - test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) { - chan->fcs = L2CAP_FCS_NONE; - l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, - chan->fcs); - } break; case L2CAP_MODE_STREAMING: @@ -3138,13 +2952,14 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) l2cap_add_opt_efs(&ptr, chan); - if (chan->conn->feat_mask & L2CAP_FEAT_FCS) - if (chan->fcs == L2CAP_FCS_NONE || - test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) { - chan->fcs = L2CAP_FCS_NONE; - l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, - chan->fcs); - } + if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS)) + break; + + if (chan->fcs == L2CAP_FCS_NONE || + test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) { + chan->fcs = L2CAP_FCS_NONE; + l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs); + } break; } @@ -3196,7 +3011,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) case L2CAP_CONF_FCS: if (val == L2CAP_FCS_NONE) - set_bit(CONF_RECV_NO_FCS, &chan->conf_state); + set_bit(CONF_NO_FCS_RECV, &chan->conf_state); break; case L2CAP_CONF_EFS: @@ -3314,7 +3129,10 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) rfc.max_pdu_size = cpu_to_le16(size); chan->remote_mps = size; - __l2cap_set_ertm_timeouts(chan, &rfc); + rfc.retrans_timeout = + __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO); + rfc.monitor_timeout = + __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO); set_bit(CONF_MODE_DONE, &chan->conf_state); @@ -3431,13 +3249,6 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs), (unsigned long) &efs); break; - - case L2CAP_CONF_FCS: - if (*result == L2CAP_CONF_PENDING) - if (val == L2CAP_FCS_NONE) - set_bit(CONF_RECV_NO_FCS, - &chan->conf_state); - break; } } @@ -3497,21 +3308,12 @@ void __l2cap_connect_rsp_defer(struct l2cap_chan *chan) struct l2cap_conn_rsp rsp; struct l2cap_conn *conn = chan->conn; u8 buf[128]; - u8 rsp_code; rsp.scid = cpu_to_le16(chan->dcid); rsp.dcid = cpu_to_le16(chan->scid); rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS); rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO); - - if (chan->hs_hcon) - rsp_code = L2CAP_CREATE_CHAN_RSP; - else - rsp_code = L2CAP_CONN_RSP; - - BT_DBG("chan %p rsp_code %u", chan, rsp_code); - - l2cap_send_cmd(conn, chan->ident, rsp_code, sizeof(rsp), &rsp); + l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp); if (test_and_set_bit(CONF_REQ_SENT, &chan->conf_state)) return; @@ -3593,9 +3395,8 @@ static inline int l2cap_command_rej(struct l2cap_conn *conn, return 0; } -static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, - struct l2cap_cmd_hdr *cmd, - u8 *data, u8 rsp_code, u8 amp_id) +static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, + u8 *data, u8 rsp_code, u8 amp_id) { struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; struct l2cap_conn_rsp rsp; @@ -3646,7 +3447,6 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, bacpy(&bt_sk(sk)->dst, conn->dst); chan->psm = psm; chan->dcid = scid; - chan->local_amp_id = amp_id; __l2cap_chan_add(conn, chan); @@ -3664,17 +3464,8 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, status = L2CAP_CS_AUTHOR_PEND; chan->ops->defer(chan); } else { - /* Force pending result for AMP controllers. - * The connection will succeed after the - * physical link is up. - */ - if (amp_id) { - __l2cap_state_change(chan, BT_CONNECT2); - result = L2CAP_CR_PEND; - } else { - __l2cap_state_change(chan, BT_CONFIG); - result = L2CAP_CR_SUCCESS; - } + __l2cap_state_change(chan, BT_CONFIG); + result = L2CAP_CR_SUCCESS; status = L2CAP_CS_NO_INFO; } } else { @@ -3720,8 +3511,6 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, l2cap_build_conf_req(chan, buf), buf); chan->num_conf_req++; } - - return chan; } static int l2cap_connect_req(struct l2cap_conn *conn, @@ -3731,7 +3520,7 @@ static int l2cap_connect_req(struct l2cap_conn *conn, return 0; } -static int l2cap_connect_create_rsp(struct l2cap_conn *conn, +static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u8 *data) { struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data; @@ -3807,7 +3596,7 @@ static inline void set_default_fcs(struct l2cap_chan *chan) */ if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING) chan->fcs = L2CAP_FCS_NONE; - else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) + else if (!test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) chan->fcs = L2CAP_FCS_CRC16; } @@ -3882,11 +3671,10 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, /* Complete config. */ len = l2cap_parse_conf_req(chan, rsp); if (len < 0) { - l2cap_send_disconn_req(chan, ECONNRESET); + l2cap_send_disconn_req(conn, chan, ECONNRESET); goto unlock; } - chan->ident = cmd->ident; l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp); chan->num_conf_rsp++; @@ -3904,7 +3692,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, err = l2cap_ertm_init(chan); if (err < 0) - l2cap_send_disconn_req(chan, -err); + l2cap_send_disconn_req(chan->conn, chan, -err); else l2cap_chan_ready(chan); @@ -3926,7 +3714,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, /* check compatibility */ /* Send rsp for BR/EDR channel */ - if (!chan->hs_hcon) + if (!chan->ctrl_id) l2cap_send_efs_conf_rsp(chan, rsp, cmd->ident, flags); else chan->ident = cmd->ident; @@ -3972,19 +3760,17 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, len = l2cap_parse_conf_rsp(chan, rsp->data, len, buf, &result); if (len < 0) { - l2cap_send_disconn_req(chan, ECONNRESET); + l2cap_send_disconn_req(conn, chan, ECONNRESET); goto done; } - if (!chan->hs_hcon) { + /* check compatibility */ + + if (!chan->ctrl_id) l2cap_send_efs_conf_rsp(chan, buf, cmd->ident, 0); - } else { - if (l2cap_check_efs(chan)) { - amp_create_logical_link(chan); - chan->ident = cmd->ident; - } - } + else + chan->ident = cmd->ident; } goto done; @@ -3993,7 +3779,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, char req[64]; if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) { - l2cap_send_disconn_req(chan, ECONNRESET); + l2cap_send_disconn_req(conn, chan, ECONNRESET); goto done; } @@ -4002,7 +3788,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, len = l2cap_parse_conf_rsp(chan, rsp->data, len, req, &result); if (len < 0) { - l2cap_send_disconn_req(chan, ECONNRESET); + l2cap_send_disconn_req(conn, chan, ECONNRESET); goto done; } @@ -4018,7 +3804,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, l2cap_chan_set_err(chan, ECONNRESET); __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT); - l2cap_send_disconn_req(chan, ECONNRESET); + l2cap_send_disconn_req(conn, chan, ECONNRESET); goto done; } @@ -4035,7 +3821,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, err = l2cap_ertm_init(chan); if (err < 0) - l2cap_send_disconn_req(chan, -err); + l2cap_send_disconn_req(chan->conn, chan, -err); else l2cap_chan_ready(chan); } @@ -4237,14 +4023,12 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, return 0; } -static int l2cap_create_channel_req(struct l2cap_conn *conn, - struct l2cap_cmd_hdr *cmd, - u16 cmd_len, void *data) +static inline int l2cap_create_channel_req(struct l2cap_conn *conn, + struct l2cap_cmd_hdr *cmd, + u16 cmd_len, void *data) { struct l2cap_create_chan_req *req = data; struct l2cap_create_chan_rsp rsp; - struct l2cap_chan *chan; - struct hci_dev *hdev; u16 psm, scid; if (cmd_len != sizeof(*req)) @@ -4258,119 +4042,57 @@ static int l2cap_create_channel_req(struct l2cap_conn *conn, BT_DBG("psm 0x%2.2x, scid 0x%4.4x, amp_id %d", psm, scid, req->amp_id); - /* For controller id 0 make BR/EDR connection */ - if (req->amp_id == HCI_BREDR_ID) { - l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP, - req->amp_id); - return 0; - } - - /* Validate AMP controller id */ - hdev = hci_dev_get(req->amp_id); - if (!hdev) - goto error; - - if (hdev->dev_type != HCI_AMP || !test_bit(HCI_UP, &hdev->flags)) { - hci_dev_put(hdev); - goto error; - } - - chan = l2cap_connect(conn, cmd, data, L2CAP_CREATE_CHAN_RSP, - req->amp_id); - if (chan) { - struct amp_mgr *mgr = conn->hcon->amp_mgr; - struct hci_conn *hs_hcon; - - hs_hcon = hci_conn_hash_lookup_ba(hdev, AMP_LINK, conn->dst); - if (!hs_hcon) { - hci_dev_put(hdev); - return -EFAULT; - } - - BT_DBG("mgr %p bredr_chan %p hs_hcon %p", mgr, chan, hs_hcon); - - mgr->bredr_chan = chan; - chan->hs_hcon = hs_hcon; - chan->fcs = L2CAP_FCS_NONE; - conn->mtu = hdev->block_mtu; - } - - hci_dev_put(hdev); - - return 0; - -error: + /* Placeholder: Always reject */ rsp.dcid = 0; rsp.scid = cpu_to_le16(scid); - rsp.result = __constant_cpu_to_le16(L2CAP_CR_BAD_AMP); + rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM); rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO); l2cap_send_cmd(conn, cmd->ident, L2CAP_CREATE_CHAN_RSP, sizeof(rsp), &rsp); - return -EFAULT; + return 0; } -static void l2cap_send_move_chan_req(struct l2cap_chan *chan, u8 dest_amp_id) +static inline int l2cap_create_channel_rsp(struct l2cap_conn *conn, + struct l2cap_cmd_hdr *cmd, + void *data) { - struct l2cap_move_chan_req req; - u8 ident; - - BT_DBG("chan %p, dest_amp_id %d", chan, dest_amp_id); - - ident = l2cap_get_ident(chan->conn); - chan->ident = ident; - - req.icid = cpu_to_le16(chan->scid); - req.dest_amp_id = dest_amp_id; - - l2cap_send_cmd(chan->conn, ident, L2CAP_MOVE_CHAN_REQ, sizeof(req), - &req); + BT_DBG("conn %p", conn); - __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT); + return l2cap_connect_rsp(conn, cmd, data); } -static void l2cap_send_move_chan_rsp(struct l2cap_chan *chan, u16 result) +static void l2cap_send_move_chan_rsp(struct l2cap_conn *conn, u8 ident, + u16 icid, u16 result) { struct l2cap_move_chan_rsp rsp; - BT_DBG("chan %p, result 0x%4.4x", chan, result); + BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result); - rsp.icid = cpu_to_le16(chan->dcid); + rsp.icid = cpu_to_le16(icid); rsp.result = cpu_to_le16(result); - l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_RSP, - sizeof(rsp), &rsp); + l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_RSP, sizeof(rsp), &rsp); } -static void l2cap_send_move_chan_cfm(struct l2cap_chan *chan, u16 result) +static void l2cap_send_move_chan_cfm(struct l2cap_conn *conn, + struct l2cap_chan *chan, + u16 icid, u16 result) { struct l2cap_move_chan_cfm cfm; + u8 ident; - BT_DBG("chan %p, result 0x%4.4x", chan, result); - - chan->ident = l2cap_get_ident(chan->conn); - - cfm.icid = cpu_to_le16(chan->scid); - cfm.result = cpu_to_le16(result); - - l2cap_send_cmd(chan->conn, chan->ident, L2CAP_MOVE_CHAN_CFM, - sizeof(cfm), &cfm); - - __set_chan_timer(chan, L2CAP_MOVE_TIMEOUT); -} - -static void l2cap_send_move_chan_cfm_icid(struct l2cap_conn *conn, u16 icid) -{ - struct l2cap_move_chan_cfm cfm; + BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result); - BT_DBG("conn %p, icid 0x%4.4x", conn, icid); + ident = l2cap_get_ident(conn); + if (chan) + chan->ident = ident; cfm.icid = cpu_to_le16(icid); - cfm.result = __constant_cpu_to_le16(L2CAP_MC_UNCONFIRMED); + cfm.result = cpu_to_le16(result); - l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_MOVE_CHAN_CFM, - sizeof(cfm), &cfm); + l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM, sizeof(cfm), &cfm); } static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident, @@ -4384,289 +4106,11 @@ static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident, l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp); } -static void __release_logical_link(struct l2cap_chan *chan) -{ - chan->hs_hchan = NULL; - chan->hs_hcon = NULL; - - /* Placeholder - release the logical link */ -} - -static void l2cap_logical_fail(struct l2cap_chan *chan) -{ - /* Logical link setup failed */ - if (chan->state != BT_CONNECTED) { - /* Create channel failure, disconnect */ - l2cap_send_disconn_req(chan, ECONNRESET); - return; - } - - switch (chan->move_role) { - case L2CAP_MOVE_ROLE_RESPONDER: - l2cap_move_done(chan); - l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_SUPP); - break; - case L2CAP_MOVE_ROLE_INITIATOR: - if (chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_COMP || - chan->move_state == L2CAP_MOVE_WAIT_LOGICAL_CFM) { - /* Remote has only sent pending or - * success responses, clean up - */ - l2cap_move_done(chan); - } - - /* Other amp move states imply that the move - * has already aborted - */ - l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED); - break; - } -} - -static void l2cap_logical_finish_create(struct l2cap_chan *chan, - struct hci_chan *hchan) -{ - struct l2cap_conf_rsp rsp; - - chan->hs_hchan = hchan; - chan->hs_hcon->l2cap_data = chan->conn; - - l2cap_send_efs_conf_rsp(chan, &rsp, chan->ident, 0); - - if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) { - int err; - - set_default_fcs(chan); - - err = l2cap_ertm_init(chan); - if (err < 0) - l2cap_send_disconn_req(chan, -err); - else - l2cap_chan_ready(chan); - } -} - -static void l2cap_logical_finish_move(struct l2cap_chan *chan, - struct hci_chan *hchan) -{ - chan->hs_hcon = hchan->conn; - chan->hs_hcon->l2cap_data = chan->conn; - - BT_DBG("move_state %d", chan->move_state); - - switch (chan->move_state) { - case L2CAP_MOVE_WAIT_LOGICAL_COMP: - /* Move confirm will be sent after a success - * response is received - */ - chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS; - break; - case L2CAP_MOVE_WAIT_LOGICAL_CFM: - if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { - chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY; - } else if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) { - chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP; - l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED); - } else if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) { - chan->move_state = L2CAP_MOVE_WAIT_CONFIRM; - l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS); - } - break; - default: - /* Move was not in expected state, free the channel */ - __release_logical_link(chan); - - chan->move_state = L2CAP_MOVE_STABLE; - } -} - -/* Call with chan locked */ -void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan, - u8 status) -{ - BT_DBG("chan %p, hchan %p, status %d", chan, hchan, status); - - if (status) { - l2cap_logical_fail(chan); - __release_logical_link(chan); - return; - } - - if (chan->state != BT_CONNECTED) { - /* Ignore logical link if channel is on BR/EDR */ - if (chan->local_amp_id) - l2cap_logical_finish_create(chan, hchan); - } else { - l2cap_logical_finish_move(chan, hchan); - } -} - -void l2cap_move_start(struct l2cap_chan *chan) -{ - BT_DBG("chan %p", chan); - - if (chan->local_amp_id == HCI_BREDR_ID) { - if (chan->chan_policy != BT_CHANNEL_POLICY_AMP_PREFERRED) - return; - chan->move_role = L2CAP_MOVE_ROLE_INITIATOR; - chan->move_state = L2CAP_MOVE_WAIT_PREPARE; - /* Placeholder - start physical link setup */ - } else { - chan->move_role = L2CAP_MOVE_ROLE_INITIATOR; - chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS; - chan->move_id = 0; - l2cap_move_setup(chan); - l2cap_send_move_chan_req(chan, 0); - } -} - -static void l2cap_do_create(struct l2cap_chan *chan, int result, - u8 local_amp_id, u8 remote_amp_id) -{ - BT_DBG("chan %p state %s %u -> %u", chan, state_to_string(chan->state), - local_amp_id, remote_amp_id); - - chan->fcs = L2CAP_FCS_NONE; - - /* Outgoing channel on AMP */ - if (chan->state == BT_CONNECT) { - if (result == L2CAP_CR_SUCCESS) { - chan->local_amp_id = local_amp_id; - l2cap_send_create_chan_req(chan, remote_amp_id); - } else { - /* Revert to BR/EDR connect */ - l2cap_send_conn_req(chan); - } - - return; - } - - /* Incoming channel on AMP */ - if (__l2cap_no_conn_pending(chan)) { - struct l2cap_conn_rsp rsp; - char buf[128]; - rsp.scid = cpu_to_le16(chan->dcid); - rsp.dcid = cpu_to_le16(chan->scid); - - if (result == L2CAP_CR_SUCCESS) { - /* Send successful response */ - rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS); - rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO); - } else { - /* Send negative response */ - rsp.result = __constant_cpu_to_le16(L2CAP_CR_NO_MEM); - rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO); - } - - l2cap_send_cmd(chan->conn, chan->ident, L2CAP_CREATE_CHAN_RSP, - sizeof(rsp), &rsp); - - if (result == L2CAP_CR_SUCCESS) { - __l2cap_state_change(chan, BT_CONFIG); - set_bit(CONF_REQ_SENT, &chan->conf_state); - l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn), - L2CAP_CONF_REQ, - l2cap_build_conf_req(chan, buf), buf); - chan->num_conf_req++; - } - } -} - -static void l2cap_do_move_initiate(struct l2cap_chan *chan, u8 local_amp_id, - u8 remote_amp_id) -{ - l2cap_move_setup(chan); - chan->move_id = local_amp_id; - chan->move_state = L2CAP_MOVE_WAIT_RSP; - - l2cap_send_move_chan_req(chan, remote_amp_id); -} - -static void l2cap_do_move_respond(struct l2cap_chan *chan, int result) -{ - struct hci_chan *hchan = NULL; - - /* Placeholder - get hci_chan for logical link */ - - if (hchan) { - if (hchan->state == BT_CONNECTED) { - /* Logical link is ready to go */ - chan->hs_hcon = hchan->conn; - chan->hs_hcon->l2cap_data = chan->conn; - chan->move_state = L2CAP_MOVE_WAIT_CONFIRM; - l2cap_send_move_chan_rsp(chan, L2CAP_MR_SUCCESS); - - l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS); - } else { - /* Wait for logical link to be ready */ - chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM; - } - } else { - /* Logical link not available */ - l2cap_send_move_chan_rsp(chan, L2CAP_MR_NOT_ALLOWED); - } -} - -static void l2cap_do_move_cancel(struct l2cap_chan *chan, int result) -{ - if (chan->move_role == L2CAP_MOVE_ROLE_RESPONDER) { - u8 rsp_result; - if (result == -EINVAL) - rsp_result = L2CAP_MR_BAD_ID; - else - rsp_result = L2CAP_MR_NOT_ALLOWED; - - l2cap_send_move_chan_rsp(chan, rsp_result); - } - - chan->move_role = L2CAP_MOVE_ROLE_NONE; - chan->move_state = L2CAP_MOVE_STABLE; - - /* Restart data transmission */ - l2cap_ertm_send(chan); -} - -/* Invoke with locked chan */ -void __l2cap_physical_cfm(struct l2cap_chan *chan, int result) -{ - u8 local_amp_id = chan->local_amp_id; - u8 remote_amp_id = chan->remote_amp_id; - - BT_DBG("chan %p, result %d, local_amp_id %d, remote_amp_id %d", - chan, result, local_amp_id, remote_amp_id); - - if (chan->state == BT_DISCONN || chan->state == BT_CLOSED) { - l2cap_chan_unlock(chan); - return; - } - - if (chan->state != BT_CONNECTED) { - l2cap_do_create(chan, result, local_amp_id, remote_amp_id); - } else if (result != L2CAP_MR_SUCCESS) { - l2cap_do_move_cancel(chan, result); - } else { - switch (chan->move_role) { - case L2CAP_MOVE_ROLE_INITIATOR: - l2cap_do_move_initiate(chan, local_amp_id, - remote_amp_id); - break; - case L2CAP_MOVE_ROLE_RESPONDER: - l2cap_do_move_respond(chan, result); - break; - default: - l2cap_do_move_cancel(chan, result); - break; - } - } -} - static inline int l2cap_move_channel_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data) { struct l2cap_move_chan_req *req = data; - struct l2cap_move_chan_rsp rsp; - struct l2cap_chan *chan; u16 icid = 0; u16 result = L2CAP_MR_NOT_ALLOWED; @@ -4680,206 +4124,15 @@ static inline int l2cap_move_channel_req(struct l2cap_conn *conn, if (!enable_hs) return -EINVAL; - chan = l2cap_get_chan_by_dcid(conn, icid); - if (!chan) { - rsp.icid = cpu_to_le16(icid); - rsp.result = __constant_cpu_to_le16(L2CAP_MR_NOT_ALLOWED); - l2cap_send_cmd(conn, cmd->ident, L2CAP_MOVE_CHAN_RSP, - sizeof(rsp), &rsp); - return 0; - } - - chan->ident = cmd->ident; - - if (chan->scid < L2CAP_CID_DYN_START || - chan->chan_policy == BT_CHANNEL_POLICY_BREDR_ONLY || - (chan->mode != L2CAP_MODE_ERTM && - chan->mode != L2CAP_MODE_STREAMING)) { - result = L2CAP_MR_NOT_ALLOWED; - goto send_move_response; - } - - if (chan->local_amp_id == req->dest_amp_id) { - result = L2CAP_MR_SAME_ID; - goto send_move_response; - } - - if (req->dest_amp_id) { - struct hci_dev *hdev; - hdev = hci_dev_get(req->dest_amp_id); - if (!hdev || hdev->dev_type != HCI_AMP || - !test_bit(HCI_UP, &hdev->flags)) { - if (hdev) - hci_dev_put(hdev); - - result = L2CAP_MR_BAD_ID; - goto send_move_response; - } - hci_dev_put(hdev); - } - - /* Detect a move collision. Only send a collision response - * if this side has "lost", otherwise proceed with the move. - * The winner has the larger bd_addr. - */ - if ((__chan_is_moving(chan) || - chan->move_role != L2CAP_MOVE_ROLE_NONE) && - bacmp(conn->src, conn->dst) > 0) { - result = L2CAP_MR_COLLISION; - goto send_move_response; - } - - chan->move_role = L2CAP_MOVE_ROLE_RESPONDER; - l2cap_move_setup(chan); - chan->move_id = req->dest_amp_id; - icid = chan->dcid; - - if (!req->dest_amp_id) { - /* Moving to BR/EDR */ - if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { - chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY; - result = L2CAP_MR_PEND; - } else { - chan->move_state = L2CAP_MOVE_WAIT_CONFIRM; - result = L2CAP_MR_SUCCESS; - } - } else { - chan->move_state = L2CAP_MOVE_WAIT_PREPARE; - /* Placeholder - uncomment when amp functions are available */ - /*amp_accept_physical(chan, req->dest_amp_id);*/ - result = L2CAP_MR_PEND; - } - -send_move_response: - l2cap_send_move_chan_rsp(chan, result); - - l2cap_chan_unlock(chan); + /* Placeholder: Always refuse */ + l2cap_send_move_chan_rsp(conn, cmd->ident, icid, result); return 0; } -static void l2cap_move_continue(struct l2cap_conn *conn, u16 icid, u16 result) -{ - struct l2cap_chan *chan; - struct hci_chan *hchan = NULL; - - chan = l2cap_get_chan_by_scid(conn, icid); - if (!chan) { - l2cap_send_move_chan_cfm_icid(conn, icid); - return; - } - - __clear_chan_timer(chan); - if (result == L2CAP_MR_PEND) - __set_chan_timer(chan, L2CAP_MOVE_ERTX_TIMEOUT); - - switch (chan->move_state) { - case L2CAP_MOVE_WAIT_LOGICAL_COMP: - /* Move confirm will be sent when logical link - * is complete. - */ - chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM; - break; - case L2CAP_MOVE_WAIT_RSP_SUCCESS: - if (result == L2CAP_MR_PEND) { - break; - } else if (test_bit(CONN_LOCAL_BUSY, - &chan->conn_state)) { - chan->move_state = L2CAP_MOVE_WAIT_LOCAL_BUSY; - } else { - /* Logical link is up or moving to BR/EDR, - * proceed with move - */ - chan->move_state = L2CAP_MOVE_WAIT_CONFIRM_RSP; - l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED); - } - break; - case L2CAP_MOVE_WAIT_RSP: - /* Moving to AMP */ - if (result == L2CAP_MR_SUCCESS) { - /* Remote is ready, send confirm immediately - * after logical link is ready - */ - chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_CFM; - } else { - /* Both logical link and move success - * are required to confirm - */ - chan->move_state = L2CAP_MOVE_WAIT_LOGICAL_COMP; - } - - /* Placeholder - get hci_chan for logical link */ - if (!hchan) { - /* Logical link not available */ - l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED); - break; - } - - /* If the logical link is not yet connected, do not - * send confirmation. - */ - if (hchan->state != BT_CONNECTED) - break; - - /* Logical link is already ready to go */ - - chan->hs_hcon = hchan->conn; - chan->hs_hcon->l2cap_data = chan->conn; - - if (result == L2CAP_MR_SUCCESS) { - /* Can confirm now */ - l2cap_send_move_chan_cfm(chan, L2CAP_MC_CONFIRMED); - } else { - /* Now only need move success - * to confirm - */ - chan->move_state = L2CAP_MOVE_WAIT_RSP_SUCCESS; - } - - l2cap_logical_cfm(chan, hchan, L2CAP_MR_SUCCESS); - break; - default: - /* Any other amp move state means the move failed. */ - chan->move_id = chan->local_amp_id; - l2cap_move_done(chan); - l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED); - } - - l2cap_chan_unlock(chan); -} - -static void l2cap_move_fail(struct l2cap_conn *conn, u8 ident, u16 icid, - u16 result) -{ - struct l2cap_chan *chan; - - chan = l2cap_get_chan_by_ident(conn, ident); - if (!chan) { - /* Could not locate channel, icid is best guess */ - l2cap_send_move_chan_cfm_icid(conn, icid); - return; - } - - __clear_chan_timer(chan); - - if (chan->move_role == L2CAP_MOVE_ROLE_INITIATOR) { - if (result == L2CAP_MR_COLLISION) { - chan->move_role = L2CAP_MOVE_ROLE_RESPONDER; - } else { - /* Cleanup - cancel move */ - chan->move_id = chan->local_amp_id; - l2cap_move_done(chan); - } - } - - l2cap_send_move_chan_cfm(chan, L2CAP_MC_UNCONFIRMED); - - l2cap_chan_unlock(chan); -} - -static int l2cap_move_channel_rsp(struct l2cap_conn *conn, - struct l2cap_cmd_hdr *cmd, - u16 cmd_len, void *data) +static inline int l2cap_move_channel_rsp(struct l2cap_conn *conn, + struct l2cap_cmd_hdr *cmd, + u16 cmd_len, void *data) { struct l2cap_move_chan_rsp *rsp = data; u16 icid, result; @@ -4892,20 +4145,17 @@ static int l2cap_move_channel_rsp(struct l2cap_conn *conn, BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result); - if (result == L2CAP_MR_SUCCESS || result == L2CAP_MR_PEND) - l2cap_move_continue(conn, icid, result); - else - l2cap_move_fail(conn, cmd->ident, icid, result); + /* Placeholder: Always unconfirmed */ + l2cap_send_move_chan_cfm(conn, NULL, icid, L2CAP_MC_UNCONFIRMED); return 0; } -static int l2cap_move_channel_confirm(struct l2cap_conn *conn, - struct l2cap_cmd_hdr *cmd, - u16 cmd_len, void *data) +static inline int l2cap_move_channel_confirm(struct l2cap_conn *conn, + struct l2cap_cmd_hdr *cmd, + u16 cmd_len, void *data) { struct l2cap_move_chan_cfm *cfm = data; - struct l2cap_chan *chan; u16 icid, result; if (cmd_len != sizeof(*cfm)) @@ -4916,29 +4166,8 @@ static int l2cap_move_channel_confirm(struct l2cap_conn *conn, BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result); - chan = l2cap_get_chan_by_dcid(conn, icid); - if (!chan) { - /* Spec requires a response even if the icid was not found */ - l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid); - return 0; - } - - if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM) { - if (result == L2CAP_MC_CONFIRMED) { - chan->local_amp_id = chan->move_id; - if (!chan->local_amp_id) - __release_logical_link(chan); - } else { - chan->move_id = chan->local_amp_id; - } - - l2cap_move_done(chan); - } - l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid); - l2cap_chan_unlock(chan); - return 0; } @@ -4947,7 +4176,6 @@ static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn, u16 cmd_len, void *data) { struct l2cap_move_chan_cfm_rsp *rsp = data; - struct l2cap_chan *chan; u16 icid; if (cmd_len != sizeof(*rsp)) @@ -4957,23 +4185,6 @@ static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn, BT_DBG("icid 0x%4.4x", icid); - chan = l2cap_get_chan_by_scid(conn, icid); - if (!chan) - return 0; - - __clear_chan_timer(chan); - - if (chan->move_state == L2CAP_MOVE_WAIT_CONFIRM_RSP) { - chan->local_amp_id = chan->move_id; - - if (!chan->local_amp_id && chan->hs_hchan) - __release_logical_link(chan); - - l2cap_move_done(chan); - } - - l2cap_chan_unlock(chan); - return 0; } @@ -5058,7 +4269,7 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, case L2CAP_CONN_RSP: case L2CAP_CREATE_CHAN_RSP: - err = l2cap_connect_create_rsp(conn, cmd, data); + err = l2cap_connect_rsp(conn, cmd, data); break; case L2CAP_CONF_REQ: @@ -5345,12 +4556,6 @@ static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb, return err; } -static int l2cap_resegment(struct l2cap_chan *chan) -{ - /* Placeholder */ - return 0; -} - void l2cap_chan_busy(struct l2cap_chan *chan, int busy) { u8 event; @@ -5405,7 +4610,7 @@ static void l2cap_handle_srej(struct l2cap_chan *chan, if (control->reqseq == chan->next_tx_seq) { BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq); - l2cap_send_disconn_req(chan, ECONNRESET); + l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); return; } @@ -5419,7 +4624,7 @@ static void l2cap_handle_srej(struct l2cap_chan *chan, if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) { BT_DBG("Retry limit exceeded (%d)", chan->max_tx); - l2cap_send_disconn_req(chan, ECONNRESET); + l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); return; } @@ -5463,7 +4668,7 @@ static void l2cap_handle_rej(struct l2cap_chan *chan, if (control->reqseq == chan->next_tx_seq) { BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq); - l2cap_send_disconn_req(chan, ECONNRESET); + l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); return; } @@ -5472,7 +4677,7 @@ static void l2cap_handle_rej(struct l2cap_chan *chan, if (chan->max_tx && skb && bt_cb(skb)->control.retries >= chan->max_tx) { BT_DBG("Retry limit exceeded (%d)", chan->max_tx); - l2cap_send_disconn_req(chan, ECONNRESET); + l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); return; } @@ -5656,7 +4861,8 @@ static int l2cap_rx_state_recv(struct l2cap_chan *chan, break; case L2CAP_TXSEQ_INVALID: default: - l2cap_send_disconn_req(chan, ECONNRESET); + l2cap_send_disconn_req(chan->conn, chan, + ECONNRESET); break; } break; @@ -5665,8 +4871,8 @@ static int l2cap_rx_state_recv(struct l2cap_chan *chan, if (control->final) { clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); - if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state) && - !__chan_is_moving(chan)) { + if (!test_and_clear_bit(CONN_REJ_ACT, + &chan->conn_state)) { control->final = 0; l2cap_retransmit_all(chan, control); } @@ -5789,7 +4995,8 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, break; case L2CAP_TXSEQ_INVALID: default: - l2cap_send_disconn_req(chan, ECONNRESET); + l2cap_send_disconn_req(chan->conn, chan, + ECONNRESET); break; } break; @@ -5854,96 +5061,6 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, return err; } -static int l2cap_finish_move(struct l2cap_chan *chan) -{ - BT_DBG("chan %p", chan); - - chan->rx_state = L2CAP_RX_STATE_RECV; - - if (chan->hs_hcon) - chan->conn->mtu = chan->hs_hcon->hdev->block_mtu; - else - chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu; - - return l2cap_resegment(chan); -} - -static int l2cap_rx_state_wait_p(struct l2cap_chan *chan, - struct l2cap_ctrl *control, - struct sk_buff *skb, u8 event) -{ - int err; - - BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb, - event); - - if (!control->poll) - return -EPROTO; - - l2cap_process_reqseq(chan, control->reqseq); - - if (!skb_queue_empty(&chan->tx_q)) - chan->tx_send_head = skb_peek(&chan->tx_q); - else - chan->tx_send_head = NULL; - - /* Rewind next_tx_seq to the point expected - * by the receiver. - */ - chan->next_tx_seq = control->reqseq; - chan->unacked_frames = 0; - - err = l2cap_finish_move(chan); - if (err) - return err; - - set_bit(CONN_SEND_FBIT, &chan->conn_state); - l2cap_send_i_or_rr_or_rnr(chan); - - if (event == L2CAP_EV_RECV_IFRAME) - return -EPROTO; - - return l2cap_rx_state_recv(chan, control, NULL, event); -} - -static int l2cap_rx_state_wait_f(struct l2cap_chan *chan, - struct l2cap_ctrl *control, - struct sk_buff *skb, u8 event) -{ - int err; - - if (!control->final) - return -EPROTO; - - clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); - - chan->rx_state = L2CAP_RX_STATE_RECV; - l2cap_process_reqseq(chan, control->reqseq); - - if (!skb_queue_empty(&chan->tx_q)) - chan->tx_send_head = skb_peek(&chan->tx_q); - else - chan->tx_send_head = NULL; - - /* Rewind next_tx_seq to the point expected - * by the receiver. - */ - chan->next_tx_seq = control->reqseq; - chan->unacked_frames = 0; - - if (chan->hs_hcon) - chan->conn->mtu = chan->hs_hcon->hdev->block_mtu; - else - chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu; - - err = l2cap_resegment(chan); - - if (!err) - err = l2cap_rx_state_recv(chan, control, skb, event); - - return err; -} - static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq) { /* Make sure reqseq is for a packet that has been sent but not acked */ @@ -5970,12 +5087,6 @@ static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control, err = l2cap_rx_state_srej_sent(chan, control, skb, event); break; - case L2CAP_RX_STATE_WAIT_P: - err = l2cap_rx_state_wait_p(chan, control, skb, event); - break; - case L2CAP_RX_STATE_WAIT_F: - err = l2cap_rx_state_wait_f(chan, control, skb, event); - break; default: /* shut it down */ break; @@ -5984,7 +5095,7 @@ static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control, BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d", control->reqseq, chan->next_tx_seq, chan->expected_ack_seq); - l2cap_send_disconn_req(chan, ECONNRESET); + l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); } return err; @@ -6053,7 +5164,7 @@ static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb) len -= L2CAP_FCS_SIZE; if (len > chan->mps) { - l2cap_send_disconn_req(chan, ECONNRESET); + l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); goto drop; } @@ -6078,7 +5189,8 @@ static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb) } if (err) - l2cap_send_disconn_req(chan, ECONNRESET); + l2cap_send_disconn_req(chan->conn, chan, + ECONNRESET); } else { const u8 rx_func_to_event[4] = { L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ, @@ -6094,8 +5206,8 @@ static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb) control->super); if (len != 0) { - BT_ERR("Trailing bytes: %d in sframe", len); - l2cap_send_disconn_req(chan, ECONNRESET); + BT_ERR("%d", len); + l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); goto drop; } @@ -6106,7 +5218,7 @@ static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb) event = rx_func_to_event[control->super]; if (l2cap_rx(chan, control, skb, event)) - l2cap_send_disconn_req(chan, ECONNRESET); + l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); } return 0; @@ -6310,9 +5422,9 @@ void l2cap_connect_cfm(struct hci_conn *hcon, u8 status) conn = l2cap_conn_add(hcon, status); if (conn) l2cap_conn_ready(conn); - } else { + } else l2cap_conn_del(hcon, bt_to_errno(status)); - } + } int l2cap_disconn_ind(struct hci_conn *hcon) @@ -6388,7 +5500,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) continue; } - if (!__l2cap_no_conn_pending(chan)) { + if (test_bit(CONF_CONNECT_PEND, &chan->conf_state)) { l2cap_chan_unlock(chan); continue; } diff --git a/trunk/net/bluetooth/l2cap_sock.c b/trunk/net/bluetooth/l2cap_sock.c index 1bcfb8422fdc..89f1472939ec 100644 --- a/trunk/net/bluetooth/l2cap_sock.c +++ b/trunk/net/bluetooth/l2cap_sock.c @@ -736,11 +736,6 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, } chan->chan_policy = (u8) opt; - - if (sk->sk_state == BT_CONNECTED && - chan->move_role == L2CAP_MOVE_ROLE_NONE) - l2cap_move_start(chan); - break; default: diff --git a/trunk/net/bluetooth/mgmt.c b/trunk/net/bluetooth/mgmt.c index f559b966279c..399e5024b5bd 100644 --- a/trunk/net/bluetooth/mgmt.c +++ b/trunk/net/bluetooth/mgmt.c @@ -222,7 +222,7 @@ static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status) hdr = (void *) skb_put(skb, sizeof(*hdr)); - hdr->opcode = __constant_cpu_to_le16(MGMT_EV_CMD_STATUS); + hdr->opcode = cpu_to_le16(MGMT_EV_CMD_STATUS); hdr->index = cpu_to_le16(index); hdr->len = cpu_to_le16(sizeof(*ev)); @@ -253,7 +253,7 @@ static int cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status, hdr = (void *) skb_put(skb, sizeof(*hdr)); - hdr->opcode = __constant_cpu_to_le16(MGMT_EV_CMD_COMPLETE); + hdr->opcode = cpu_to_le16(MGMT_EV_CMD_COMPLETE); hdr->index = cpu_to_le16(index); hdr->len = cpu_to_le16(sizeof(*ev) + rp_len); @@ -326,7 +326,7 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data, struct hci_dev *d; size_t rp_len; u16 count; - int err; + int i, err; BT_DBG("sock %p", sk); @@ -347,7 +347,9 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data, return -ENOMEM; } - count = 0; + rp->num_controllers = cpu_to_le16(count); + + i = 0; list_for_each_entry(d, &hci_dev_list, list) { if (test_bit(HCI_SETUP, &d->dev_flags)) continue; @@ -355,13 +357,10 @@ static int read_index_list(struct sock *sk, struct hci_dev *hdev, void *data, if (!mgmt_valid_hdev(d)) continue; - rp->index[count++] = cpu_to_le16(d->id); + rp->index[i++] = cpu_to_le16(d->id); BT_DBG("Added hci%u", d->id); } - rp->num_controllers = cpu_to_le16(count); - rp_len = sizeof(*rp) + (2 * count); - read_unlock(&hci_dev_list_lock); err = cmd_complete(sk, MGMT_INDEX_NONE, MGMT_OP_READ_INDEX_LIST, 0, rp, @@ -377,15 +376,15 @@ static u32 get_supported_settings(struct hci_dev *hdev) u32 settings = 0; settings |= MGMT_SETTING_POWERED; + settings |= MGMT_SETTING_CONNECTABLE; + settings |= MGMT_SETTING_FAST_CONNECTABLE; + settings |= MGMT_SETTING_DISCOVERABLE; settings |= MGMT_SETTING_PAIRABLE; if (lmp_ssp_capable(hdev)) settings |= MGMT_SETTING_SSP; if (lmp_bredr_capable(hdev)) { - settings |= MGMT_SETTING_CONNECTABLE; - settings |= MGMT_SETTING_FAST_CONNECTABLE; - settings |= MGMT_SETTING_DISCOVERABLE; settings |= MGMT_SETTING_BREDR; settings |= MGMT_SETTING_LINK_SECURITY; } @@ -485,7 +484,7 @@ static void create_eir(struct hci_dev *hdev, u8 *data) ptr += (name_len + 2); } - if (hdev->inq_tx_power != HCI_TX_POWER_INVALID) { + if (hdev->inq_tx_power) { ptr[0] = 2; ptr[1] = EIR_TX_POWER; ptr[2] = (u8) hdev->inq_tx_power; @@ -566,7 +565,7 @@ static int update_eir(struct hci_dev *hdev) if (!hdev_is_powered(hdev)) return 0; - if (!lmp_ext_inq_capable(hdev)) + if (!(hdev->features[6] & LMP_EXT_INQ)) return 0; if (!test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) @@ -833,7 +832,7 @@ static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, u16 data_len, if (hdev) hdr->index = cpu_to_le16(hdev->id); else - hdr->index = __constant_cpu_to_le16(MGMT_INDEX_NONE); + hdr->index = cpu_to_le16(MGMT_INDEX_NONE); hdr->len = cpu_to_le16(data_len); if (data) @@ -868,10 +867,6 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data, BT_DBG("request for %s", hdev->name); - if (!lmp_bredr_capable(hdev)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, - MGMT_STATUS_NOT_SUPPORTED); - timeout = __le16_to_cpu(cp->timeout); if (!cp->val && timeout > 0) return cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, @@ -967,10 +962,6 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data, BT_DBG("request for %s", hdev->name); - if (!lmp_bredr_capable(hdev)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE, - MGMT_STATUS_NOT_SUPPORTED); - hci_dev_lock(hdev); if (!hdev_is_powered(hdev)) { @@ -1069,10 +1060,6 @@ static int set_link_security(struct sock *sk, struct hci_dev *hdev, void *data, BT_DBG("request for %s", hdev->name); - if (!lmp_bredr_capable(hdev)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_LINK_SECURITY, - MGMT_STATUS_NOT_SUPPORTED); - hci_dev_lock(hdev); if (!hdev_is_powered(hdev)) { @@ -1226,7 +1213,7 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) } val = !!cp->val; - enabled = lmp_host_le_capable(hdev); + enabled = !!(hdev->host_features[0] & LMP_HOST_LE); if (!hdev_is_powered(hdev) || val == enabled) { bool changed = false; @@ -1262,7 +1249,7 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) if (val) { hci_cp.le = val; - hci_cp.simul = lmp_le_br_capable(hdev); + hci_cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR); } err = hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(hci_cp), @@ -1379,7 +1366,6 @@ static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data, continue; list_del(&match->list); - kfree(match); found++; } @@ -2608,10 +2594,6 @@ static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev, BT_DBG("%s", hdev->name); - if (!lmp_bredr_capable(hdev)) - return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, - MGMT_STATUS_NOT_SUPPORTED); - if (!hdev_is_powered(hdev)) return cmd_status(sk, hdev->id, MGMT_OP_SET_FAST_CONNECTABLE, MGMT_STATUS_NOT_POWERED); @@ -2889,21 +2871,6 @@ static void settings_rsp(struct pending_cmd *cmd, void *data) mgmt_pending_free(cmd); } -static int set_bredr_scan(struct hci_dev *hdev) -{ - u8 scan = 0; - - if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags)) - scan |= SCAN_PAGE; - if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags)) - scan |= SCAN_INQUIRY; - - if (!scan) - return 0; - - return hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); -} - int mgmt_powered(struct hci_dev *hdev, u8 powered) { struct cmd_lookup match = { NULL, hdev }; @@ -2915,8 +2882,17 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered) mgmt_pending_foreach(MGMT_OP_SET_POWERED, hdev, settings_rsp, &match); if (powered) { - if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) && - !lmp_host_ssp_capable(hdev)) { + u8 scan = 0; + + if (test_bit(HCI_CONNECTABLE, &hdev->dev_flags)) + scan |= SCAN_PAGE; + if (test_bit(HCI_DISCOVERABLE, &hdev->dev_flags)) + scan |= SCAN_INQUIRY; + + if (scan) + hci_send_cmd(hdev, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan); + + if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { u8 ssp = 1; hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, 1, &ssp); @@ -2926,24 +2902,15 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered) struct hci_cp_write_le_host_supported cp; cp.le = 1; - cp.simul = lmp_le_br_capable(hdev); - - /* Check first if we already have the right - * host state (host features set) - */ - if (cp.le != lmp_host_le_capable(hdev) || - cp.simul != lmp_host_le_br_capable(hdev)) - hci_send_cmd(hdev, - HCI_OP_WRITE_LE_HOST_SUPPORTED, - sizeof(cp), &cp); - } + cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR); - if (lmp_bredr_capable(hdev)) { - set_bredr_scan(hdev); - update_class(hdev); - update_name(hdev, hdev->dev_name); - update_eir(hdev); + hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, + sizeof(cp), &cp); } + + update_class(hdev); + update_name(hdev, hdev->dev_name); + update_eir(hdev); } else { u8 status = MGMT_STATUS_NOT_POWERED; mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status); @@ -3392,7 +3359,7 @@ static int clear_eir(struct hci_dev *hdev) { struct hci_cp_write_eir cp; - if (!lmp_ext_inq_capable(hdev)) + if (!(hdev->features[6] & LMP_EXT_INQ)) return 0; memset(hdev->eir, 0, sizeof(hdev->eir)); @@ -3524,12 +3491,7 @@ int mgmt_set_local_name_complete(struct hci_dev *hdev, u8 *name, u8 status) err = mgmt_event(MGMT_EV_LOCAL_NAME_CHANGED, hdev, &ev, sizeof(ev), cmd ? cmd->sk : NULL); - /* EIR is taken care of separately when powering on the - * adapter so only update them here if this is a name change - * unrelated to power on. - */ - if (!test_bit(HCI_INIT, &hdev->flags)) - update_eir(hdev); + update_eir(hdev); failed: if (cmd) @@ -3624,9 +3586,9 @@ int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, ev->addr.type = link_to_bdaddr(link_type, addr_type); ev->rssi = rssi; if (cfm_name) - ev->flags |= __constant_cpu_to_le32(MGMT_DEV_FOUND_CONFIRM_NAME); + ev->flags |= cpu_to_le32(MGMT_DEV_FOUND_CONFIRM_NAME); if (!ssp) - ev->flags |= __constant_cpu_to_le32(MGMT_DEV_FOUND_LEGACY_PAIRING); + ev->flags |= cpu_to_le32(MGMT_DEV_FOUND_LEGACY_PAIRING); if (eir_len > 0) memcpy(ev->eir, eir, eir_len); diff --git a/trunk/net/bluetooth/rfcomm/sock.c b/trunk/net/bluetooth/rfcomm/sock.c index ce3f6658f4b2..4ddef57d03a7 100644 --- a/trunk/net/bluetooth/rfcomm/sock.c +++ b/trunk/net/bluetooth/rfcomm/sock.c @@ -467,7 +467,7 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f long timeo; int err = 0; - lock_sock_nested(sk, SINGLE_DEPTH_NESTING); + lock_sock(sk); if (sk->sk_type != SOCK_STREAM) { err = -EINVAL; @@ -504,7 +504,7 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f release_sock(sk); timeo = schedule_timeout(timeo); - lock_sock_nested(sk, SINGLE_DEPTH_NESTING); + lock_sock(sk); } __set_current_state(TASK_RUNNING); remove_wait_queue(sk_sleep(sk), &wait); diff --git a/trunk/net/bluetooth/sco.c b/trunk/net/bluetooth/sco.c index 531a93d613d4..450cdcd88e5c 100644 --- a/trunk/net/bluetooth/sco.c +++ b/trunk/net/bluetooth/sco.c @@ -131,6 +131,15 @@ static int sco_conn_del(struct hci_conn *hcon, int err) sco_sock_clear_timer(sk); sco_chan_del(sk, err); bh_unlock_sock(sk); + + sco_conn_lock(conn); + conn->sk = NULL; + sco_pi(sk)->conn = NULL; + sco_conn_unlock(conn); + + if (conn->hcon) + hci_conn_put(conn->hcon); + sco_sock_kill(sk); } @@ -388,7 +397,6 @@ static void sco_sock_init(struct sock *sk, struct sock *parent) if (parent) { sk->sk_type = parent->sk_type; - bt_sk(sk)->flags = bt_sk(parent)->flags; security_sk_clone(parent, sk); } } @@ -654,57 +662,16 @@ static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock, return err; } -static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock, - struct msghdr *msg, size_t len, int flags) -{ - struct sock *sk = sock->sk; - struct sco_pinfo *pi = sco_pi(sk); - - lock_sock(sk); - - if (sk->sk_state == BT_CONNECT2 && - test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) { - hci_conn_accept(pi->conn->hcon, 0); - sk->sk_state = BT_CONFIG; - - release_sock(sk); - return 0; - } - - release_sock(sk); - - return bt_sock_recvmsg(iocb, sock, msg, len, flags); -} - static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen) { struct sock *sk = sock->sk; int err = 0; - u32 opt; BT_DBG("sk %p", sk); lock_sock(sk); switch (optname) { - - case BT_DEFER_SETUP: - if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) { - err = -EINVAL; - break; - } - - if (get_user(opt, (u32 __user *) optval)) { - err = -EFAULT; - break; - } - - if (opt) - set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags); - else - clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags); - break; - default: err = -ENOPROTOOPT; break; @@ -786,19 +753,6 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char lock_sock(sk); switch (optname) { - - case BT_DEFER_SETUP: - if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) { - err = -EINVAL; - break; - } - - if (put_user(test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags), - (u32 __user *) optval)) - err = -EFAULT; - - break; - default: err = -ENOPROTOOPT; break; @@ -876,16 +830,6 @@ static void sco_chan_del(struct sock *sk, int err) BT_DBG("sk %p, conn %p, err %d", sk, conn, err); - if (conn) { - sco_conn_lock(conn); - conn->sk = NULL; - sco_pi(sk)->conn = NULL; - sco_conn_unlock(conn); - - if (conn->hcon) - hci_conn_put(conn->hcon); - } - sk->sk_state = BT_CLOSED; sk->sk_err = err; sk->sk_state_change(sk); @@ -930,10 +874,7 @@ static void sco_conn_ready(struct sco_conn *conn) hci_conn_hold(conn->hcon); __sco_chan_add(conn, sk, parent); - if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags)) - sk->sk_state = BT_CONNECT2; - else - sk->sk_state = BT_CONNECTED; + sk->sk_state = BT_CONNECTED; /* Wake up parent */ parent->sk_data_ready(parent, 1); @@ -946,7 +887,7 @@ static void sco_conn_ready(struct sco_conn *conn) } /* ----- SCO interface with lower layer (HCI) ----- */ -int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags) +int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr) { struct sock *sk; struct hlist_node *node; @@ -963,9 +904,6 @@ int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags) if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr) || !bacmp(&bt_sk(sk)->src, BDADDR_ANY)) { lm |= HCI_LM_ACCEPT; - - if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) - *flags |= HCI_PROTO_DEFER; break; } } @@ -1054,7 +992,7 @@ static const struct proto_ops sco_sock_ops = { .accept = sco_sock_accept, .getname = sco_sock_getname, .sendmsg = sco_sock_sendmsg, - .recvmsg = sco_sock_recvmsg, + .recvmsg = bt_sock_recvmsg, .poll = bt_sock_poll, .ioctl = bt_sock_ioctl, .mmap = sock_no_mmap, diff --git a/trunk/net/bluetooth/smp.c b/trunk/net/bluetooth/smp.c index 68a9587c9694..9176bc17595c 100644 --- a/trunk/net/bluetooth/smp.c +++ b/trunk/net/bluetooth/smp.c @@ -267,7 +267,7 @@ static void smp_failure(struct l2cap_conn *conn, u8 reason, u8 send) clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->hcon->flags); mgmt_auth_failed(conn->hcon->hdev, conn->dst, hcon->type, - hcon->dst_type, HCI_ERROR_AUTH_FAILURE); + hcon->dst_type, reason); cancel_delayed_work_sync(&conn->security_timer); diff --git a/trunk/net/core/net-sysfs.c b/trunk/net/core/net-sysfs.c index 017a8bacfb27..bcf02f608cbf 100644 --- a/trunk/net/core/net-sysfs.c +++ b/trunk/net/core/net-sysfs.c @@ -429,17 +429,6 @@ static struct attribute_group netstat_group = { .name = "statistics", .attrs = netstat_attrs, }; - -#if IS_ENABLED(CONFIG_WIRELESS_EXT) || IS_ENABLED(CONFIG_CFG80211) -static struct attribute *wireless_attrs[] = { - NULL -}; - -static struct attribute_group wireless_group = { - .name = "wireless", - .attrs = wireless_attrs, -}; -#endif #endif /* CONFIG_SYSFS */ #ifdef CONFIG_RPS @@ -1420,15 +1409,6 @@ int netdev_register_kobject(struct net_device *net) groups++; *groups++ = &netstat_group; - -#if IS_ENABLED(CONFIG_WIRELESS_EXT) || IS_ENABLED(CONFIG_CFG80211) - if (net->ieee80211_ptr) - *groups++ = &wireless_group; -#if IS_ENABLED(CONFIG_WIRELESS_EXT) - else if (net->wireless_handlers) - *groups++ = &wireless_group; -#endif -#endif #endif /* CONFIG_SYSFS */ error = device_add(dev); diff --git a/trunk/net/mac80211/cfg.c b/trunk/net/mac80211/cfg.c index 4965aa6424ec..5d30e5f57ff0 100644 --- a/trunk/net/mac80211/cfg.c +++ b/trunk/net/mac80211/cfg.c @@ -2684,9 +2684,6 @@ static void ieee80211_mgmt_frame_register(struct wiphy *wiphy, else local->probe_req_reg--; - if (!local->open_count) - break; - ieee80211_queue_work(&local->hw, &local->reconfig_filter); break; default: diff --git a/trunk/net/mac80211/ibss.c b/trunk/net/mac80211/ibss.c index fa862b24a7e0..11a6a1bde2fd 100644 --- a/trunk/net/mac80211/ibss.c +++ b/trunk/net/mac80211/ibss.c @@ -1145,6 +1145,10 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) mutex_lock(&sdata->u.ibss.mtx); + sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; + memset(sdata->u.ibss.bssid, 0, ETH_ALEN); + sdata->u.ibss.ssid_len = 0; + active_ibss = ieee80211_sta_active_ibss(sdata); if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) { @@ -1165,10 +1169,6 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) } } - ifibss->state = IEEE80211_IBSS_MLME_SEARCH; - memset(ifibss->bssid, 0, ETH_ALEN); - ifibss->ssid_len = 0; - sta_info_flush(sdata->local, sdata); spin_lock_bh(&ifibss->incomplete_lock); diff --git a/trunk/net/mac80211/ieee80211_i.h b/trunk/net/mac80211/ieee80211_i.h index 5c0d5a6946c1..0a8f83d142f9 100644 --- a/trunk/net/mac80211/ieee80211_i.h +++ b/trunk/net/mac80211/ieee80211_i.h @@ -1396,8 +1396,6 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev); netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); -void ieee80211_purge_tx_queue(struct ieee80211_hw *hw, - struct sk_buff_head *skbs); /* HT */ void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, diff --git a/trunk/net/mac80211/main.c b/trunk/net/mac80211/main.c index f5e4c1f24bf2..6e933409979a 100644 --- a/trunk/net/mac80211/main.c +++ b/trunk/net/mac80211/main.c @@ -936,10 +936,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) local->hw.wiphy->cipher_suites, sizeof(u32) * local->hw.wiphy->n_cipher_suites, GFP_KERNEL); - if (!suites) { - result = -ENOMEM; - goto fail_wiphy_register; - } + if (!suites) + return -ENOMEM; for (r = 0; r < local->hw.wiphy->n_cipher_suites; r++) { u32 suite = local->hw.wiphy->cipher_suites[r]; if (suite == WLAN_CIPHER_SUITE_WEP40 || diff --git a/trunk/net/mac80211/offchannel.c b/trunk/net/mac80211/offchannel.c index a5379aea7d09..5abddfe3e101 100644 --- a/trunk/net/mac80211/offchannel.c +++ b/trunk/net/mac80211/offchannel.c @@ -462,6 +462,8 @@ void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata) list_move_tail(&roc->list, &tmp_list); roc->abort = true; } + + ieee80211_start_next_roc(local); mutex_unlock(&local->mtx); list_for_each_entry_safe(roc, tmp, &tmp_list, list) { diff --git a/trunk/net/mac80211/scan.c b/trunk/net/mac80211/scan.c index f3340279aba3..ddd1a9aaff38 100644 --- a/trunk/net/mac80211/scan.c +++ b/trunk/net/mac80211/scan.c @@ -927,7 +927,7 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, struct cfg80211_sched_scan_request *req) { struct ieee80211_local *local = sdata->local; - struct ieee80211_sched_scan_ies sched_scan_ies = {}; + struct ieee80211_sched_scan_ies sched_scan_ies; int ret, i; mutex_lock(&local->mtx); diff --git a/trunk/net/mac80211/sta_info.c b/trunk/net/mac80211/sta_info.c index f3e502502fee..dadcfcf29122 100644 --- a/trunk/net/mac80211/sta_info.c +++ b/trunk/net/mac80211/sta_info.c @@ -122,8 +122,8 @@ static void free_sta_work(struct work_struct *wk) for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf[ac]); - ieee80211_purge_tx_queue(&local->hw, &sta->ps_tx_buf[ac]); - ieee80211_purge_tx_queue(&local->hw, &sta->tx_filtered[ac]); + __skb_queue_purge(&sta->ps_tx_buf[ac]); + __skb_queue_purge(&sta->tx_filtered[ac]); } #ifdef CONFIG_MAC80211_MESH @@ -146,7 +146,7 @@ static void free_sta_work(struct work_struct *wk) tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]); if (!tid_tx) continue; - ieee80211_purge_tx_queue(&local->hw, &tid_tx->pending); + __skb_queue_purge(&tid_tx->pending); kfree(tid_tx); } @@ -982,7 +982,6 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) struct ieee80211_local *local = sdata->local; struct sk_buff_head pending; int filtered = 0, buffered = 0, ac; - unsigned long flags; clear_sta_flag(sta, WLAN_STA_SP); @@ -998,16 +997,12 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { int count = skb_queue_len(&pending), tmp; - spin_lock_irqsave(&sta->tx_filtered[ac].lock, flags); skb_queue_splice_tail_init(&sta->tx_filtered[ac], &pending); - spin_unlock_irqrestore(&sta->tx_filtered[ac].lock, flags); tmp = skb_queue_len(&pending); filtered += tmp - count; count = tmp; - spin_lock_irqsave(&sta->ps_tx_buf[ac].lock, flags); skb_queue_splice_tail_init(&sta->ps_tx_buf[ac], &pending); - spin_unlock_irqrestore(&sta->ps_tx_buf[ac].lock, flags); tmp = skb_queue_len(&pending); buffered += tmp - count; } diff --git a/trunk/net/mac80211/status.c b/trunk/net/mac80211/status.c index ab63237107c8..2d931ad0e90a 100644 --- a/trunk/net/mac80211/status.c +++ b/trunk/net/mac80211/status.c @@ -666,12 +666,3 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb) dev_kfree_skb_any(skb); } EXPORT_SYMBOL(ieee80211_free_txskb); - -void ieee80211_purge_tx_queue(struct ieee80211_hw *hw, - struct sk_buff_head *skbs) -{ - struct sk_buff *skb; - - while ((skb = __skb_dequeue(skbs))) - ieee80211_free_txskb(hw, skb); -} diff --git a/trunk/net/mac80211/tx.c b/trunk/net/mac80211/tx.c index d287a4f2c01b..d8ef3417bf2b 100644 --- a/trunk/net/mac80211/tx.c +++ b/trunk/net/mac80211/tx.c @@ -1361,7 +1361,7 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) if (tx->skb) ieee80211_free_txskb(&tx->local->hw, tx->skb); else - ieee80211_purge_tx_queue(&tx->local->hw, &tx->skbs); + __skb_queue_purge(&tx->skbs); return -1; } else if (unlikely(res == TX_QUEUED)) { I802_DEBUG_INC(tx->local->tx_handlers_queued); @@ -2161,13 +2161,10 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, */ void ieee80211_clear_tx_pending(struct ieee80211_local *local) { - struct sk_buff *skb; int i; - for (i = 0; i < local->hw.queues; i++) { - while ((skb = skb_dequeue(&local->pending[i])) != NULL) - ieee80211_free_txskb(&local->hw, skb); - } + for (i = 0; i < local->hw.queues; i++) + skb_queue_purge(&local->pending[i]); } /* diff --git a/trunk/net/mac80211/util.c b/trunk/net/mac80211/util.c index 08132ff98155..dc7f6b264593 100644 --- a/trunk/net/mac80211/util.c +++ b/trunk/net/mac80211/util.c @@ -1572,8 +1572,6 @@ int ieee80211_reconfig(struct ieee80211_local *local) list_for_each_entry(sdata, &local->interfaces, list) { if (sdata->vif.type != NL80211_IFTYPE_STATION) continue; - if (!sdata->u.mgd.associated) - continue; ieee80211_send_nullfunc(local, sdata, 0); } diff --git a/trunk/net/nfc/hci/command.c b/trunk/net/nfc/hci/command.c index 7d99410e6c1a..07659cfd6d7b 100644 --- a/trunk/net/nfc/hci/command.c +++ b/trunk/net/nfc/hci/command.c @@ -344,7 +344,7 @@ int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate, return -EADDRINUSE; if (pipe != NFC_HCI_INVALID_PIPE) - goto open_pipe; + goto pipe_is_open; switch (dest_gate) { case NFC_HCI_LINK_MGMT_GATE: @@ -361,7 +361,6 @@ int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate, break; } -open_pipe: r = nfc_hci_open_pipe(hdev, pipe); if (r < 0) { if (pipe_created) @@ -372,6 +371,7 @@ int nfc_hci_connect_gate(struct nfc_hci_dev *hdev, u8 dest_host, u8 dest_gate, return r; } +pipe_is_open: hdev->gate2pipe[dest_gate] = pipe; return 0; diff --git a/trunk/net/nfc/hci/core.c b/trunk/net/nfc/hci/core.c index 7bea574d5934..bc571b0efb92 100644 --- a/trunk/net/nfc/hci/core.c +++ b/trunk/net/nfc/hci/core.c @@ -33,20 +33,17 @@ /* Largest headroom needed for outgoing HCI commands */ #define HCI_CMDS_HEADROOM 1 -int nfc_hci_result_to_errno(u8 result) +static int nfc_hci_result_to_errno(u8 result) { switch (result) { case NFC_HCI_ANY_OK: return 0; - case NFC_HCI_ANY_E_REG_PAR_UNKNOWN: - return -EOPNOTSUPP; case NFC_HCI_ANY_E_TIMEOUT: return -ETIME; default: return -1; } } -EXPORT_SYMBOL(nfc_hci_result_to_errno); static void nfc_hci_msg_tx_work(struct work_struct *work) { @@ -170,7 +167,7 @@ void nfc_hci_cmd_received(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd, kfree_skb(skb); } -u32 nfc_hci_sak_to_protocol(u8 sak) +static u32 nfc_hci_sak_to_protocol(u8 sak) { switch (NFC_HCI_TYPE_A_SEL_PROT(sak)) { case NFC_HCI_TYPE_A_SEL_PROT_MIFARE: @@ -185,7 +182,6 @@ u32 nfc_hci_sak_to_protocol(u8 sak) return 0xffffffff; } } -EXPORT_SYMBOL(nfc_hci_sak_to_protocol); int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate) { @@ -288,12 +284,6 @@ void nfc_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event, struct sk_buff *skb) { int r = 0; - u8 gate = nfc_hci_pipe2gate(hdev, pipe); - - if (gate == 0xff) { - pr_err("Discarded event %x to unopened pipe %x\n", event, pipe); - goto exit; - } switch (event) { case NFC_HCI_EVT_TARGET_DISCOVERED: @@ -317,11 +307,14 @@ void nfc_hci_event_received(struct nfc_hci_dev *hdev, u8 pipe, u8 event, goto exit; } - r = nfc_hci_target_discovered(hdev, gate); + r = nfc_hci_target_discovered(hdev, + nfc_hci_pipe2gate(hdev, pipe)); break; default: if (hdev->ops->event_received) { - hdev->ops->event_received(hdev, gate, event, skb); + hdev->ops->event_received(hdev, + nfc_hci_pipe2gate(hdev, pipe), + event, skb); return; } @@ -426,10 +419,6 @@ static int hci_dev_version(struct nfc_hci_dev *hdev) r = nfc_hci_get_param(hdev, NFC_HCI_ID_MGMT_GATE, NFC_HCI_ID_MGMT_VERSION_SW, &skb); - if (r == -EOPNOTSUPP) { - pr_info("Software/Hardware info not available\n"); - return 0; - } if (r < 0) return r; diff --git a/trunk/net/nfc/llcp/commands.c b/trunk/net/nfc/llcp/commands.c index df24be48d4da..ed2d17312d61 100644 --- a/trunk/net/nfc/llcp/commands.c +++ b/trunk/net/nfc/llcp/commands.c @@ -528,23 +528,6 @@ int nfc_llcp_send_i_frame(struct nfc_llcp_sock *sock, if (local == NULL) return -ENODEV; - /* Remote is ready but has not acknowledged our frames */ - if((sock->remote_ready && - skb_queue_len(&sock->tx_pending_queue) >= sock->rw && - skb_queue_len(&sock->tx_queue) >= 2 * sock->rw)) { - pr_err("Pending queue is full %d frames\n", - skb_queue_len(&sock->tx_pending_queue)); - return -ENOBUFS; - } - - /* Remote is not ready and we've been queueing enough frames */ - if ((!sock->remote_ready && - skb_queue_len(&sock->tx_queue) >= 2 * sock->rw)) { - pr_err("Tx queue is full %d frames\n", - skb_queue_len(&sock->tx_queue)); - return -ENOBUFS; - } - msg_data = kzalloc(len, GFP_KERNEL); if (msg_data == NULL) return -ENOMEM; @@ -596,7 +579,7 @@ int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 ssap, u8 dsap, struct sk_buff *pdu; struct nfc_llcp_local *local; size_t frag_len = 0, remaining_len; - u8 *msg_ptr, *msg_data; + u8 *msg_ptr; int err; pr_debug("Send UI frame len %zd\n", len); @@ -605,17 +588,8 @@ int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 ssap, u8 dsap, if (local == NULL) return -ENODEV; - msg_data = kzalloc(len, GFP_KERNEL); - if (msg_data == NULL) - return -ENOMEM; - - if (memcpy_fromiovec(msg_data, msg->msg_iov, len)) { - kfree(msg_data); - return -EFAULT; - } - remaining_len = len; - msg_ptr = msg_data; + msg_ptr = (u8 *) msg->msg_iov; while (remaining_len > 0) { @@ -642,8 +616,6 @@ int nfc_llcp_send_ui_frame(struct nfc_llcp_sock *sock, u8 ssap, u8 dsap, msg_ptr += frag_len; } - kfree(msg_data); - return len; } diff --git a/trunk/net/nfc/llcp/llcp.c b/trunk/net/nfc/llcp/llcp.c index ec43914c92a9..f6804532047a 100644 --- a/trunk/net/nfc/llcp/llcp.c +++ b/trunk/net/nfc/llcp/llcp.c @@ -656,8 +656,6 @@ static void nfc_llcp_tx_work(struct work_struct *work) if (llcp_sock == NULL && nfc_llcp_ptype(skb) == LLCP_PDU_I) { nfc_llcp_send_symm(local->dev); } else { - struct sk_buff *copy_skb = NULL; - u8 ptype = nfc_llcp_ptype(skb); int ret; pr_debug("Sending pending skb\n"); @@ -665,29 +663,22 @@ static void nfc_llcp_tx_work(struct work_struct *work) DUMP_PREFIX_OFFSET, 16, 1, skb->data, skb->len, true); - if (ptype == LLCP_PDU_I) - copy_skb = skb_copy(skb, GFP_ATOMIC); - nfc_llcp_send_to_raw_sock(local, skb, NFC_LLCP_DIRECTION_TX); ret = nfc_data_exchange(local->dev, local->target_idx, skb, nfc_llcp_recv, local); - if (ret) { - kfree_skb(copy_skb); - goto out; - } - - if (ptype == LLCP_PDU_I && copy_skb) + if (!ret && nfc_llcp_ptype(skb) == LLCP_PDU_I) { + skb = skb_get(skb); skb_queue_tail(&llcp_sock->tx_pending_queue, - copy_skb); + skb); + } } } else { nfc_llcp_send_symm(local->dev); } -out: mod_timer(&local->link_timer, jiffies + msecs_to_jiffies(2 * local->remote_lto)); } @@ -985,18 +976,15 @@ static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local, /* Remove skbs from the pending queue */ if (llcp_sock->send_ack_n != nr) { struct sk_buff *s, *tmp; - u8 n; llcp_sock->send_ack_n = nr; /* Remove and free all skbs until ns == nr */ skb_queue_walk_safe(&llcp_sock->tx_pending_queue, s, tmp) { - n = nfc_llcp_ns(s); - skb_unlink(s, &llcp_sock->tx_pending_queue); kfree_skb(s); - if (n == nr) + if (nfc_llcp_ns(s) == nr) break; } @@ -1400,7 +1388,7 @@ int nfc_llcp_register_device(struct nfc_dev *ndev) local->remote_miu = LLCP_DEFAULT_MIU; local->remote_lto = LLCP_DEFAULT_LTO; - list_add(&local->list, &llcp_devices); + list_add(&llcp_devices, &local->list); return 0; } diff --git a/trunk/net/wireless/Kconfig b/trunk/net/wireless/Kconfig index 16d08b399210..fe4adb12b3ef 100644 --- a/trunk/net/wireless/Kconfig +++ b/trunk/net/wireless/Kconfig @@ -140,13 +140,14 @@ config CFG80211_WEXT extensions with cfg80211-based drivers. config LIB80211 - tristate + tristate "Common routines for IEEE802.11 drivers" default n help This options enables a library of common routines used by IEEE802.11 wireless LAN drivers. - Drivers should select this themselves if needed. + Drivers should select this themselves if needed. Say Y if + you want this built into your kernel. config LIB80211_CRYPT_WEP tristate diff --git a/trunk/net/wireless/chan.c b/trunk/net/wireless/chan.c index bf2dfd54ff3b..b5f69831e318 100644 --- a/trunk/net/wireless/chan.c +++ b/trunk/net/wireless/chan.c @@ -44,7 +44,7 @@ void cfg80211_chandef_create(struct cfg80211_chan_def *chandef, } EXPORT_SYMBOL(cfg80211_chandef_create); -bool cfg80211_chan_def_valid(const struct cfg80211_chan_def *chandef) +bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef) { u32 control_freq; @@ -105,6 +105,7 @@ bool cfg80211_chan_def_valid(const struct cfg80211_chan_def *chandef) return true; } +EXPORT_SYMBOL(cfg80211_chandef_valid); static void chandef_primary_freqs(const struct cfg80211_chan_def *c, int *pri40, int *pri80) @@ -187,9 +188,9 @@ cfg80211_chandef_compatible(const struct cfg80211_chan_def *c1, } EXPORT_SYMBOL(cfg80211_chandef_compatible); -bool cfg80211_secondary_chans_ok(struct wiphy *wiphy, - u32 center_freq, u32 bandwidth, - u32 prohibited_flags) +static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy, + u32 center_freq, u32 bandwidth, + u32 prohibited_flags) { struct ieee80211_channel *c; u32 freq; @@ -205,55 +206,88 @@ bool cfg80211_secondary_chans_ok(struct wiphy *wiphy, return true; } -static bool cfg80211_check_beacon_chans(struct wiphy *wiphy, - u32 center_freq, u32 bw) +bool cfg80211_chandef_usable(struct wiphy *wiphy, + const struct cfg80211_chan_def *chandef, + u32 prohibited_flags) { - return cfg80211_secondary_chans_ok(wiphy, center_freq, bw, - IEEE80211_CHAN_DISABLED | - IEEE80211_CHAN_PASSIVE_SCAN | - IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_RADAR); -} + struct ieee80211_sta_ht_cap *ht_cap; + struct ieee80211_sta_vht_cap *vht_cap; + u32 width, control_freq; -bool cfg80211_reg_can_beacon(struct wiphy *wiphy, - struct cfg80211_chan_def *chandef) -{ - u32 width; - bool res; + if (WARN_ON(!cfg80211_chandef_valid(chandef))) + return false; - trace_cfg80211_reg_can_beacon(wiphy, chandef); + ht_cap = &wiphy->bands[chandef->chan->band]->ht_cap; + vht_cap = &wiphy->bands[chandef->chan->band]->vht_cap; - if (WARN_ON(!cfg80211_chan_def_valid(chandef))) { - trace_cfg80211_return_bool(false); - return false; - } + control_freq = chandef->chan->center_freq; switch (chandef->width) { - case NL80211_CHAN_WIDTH_20_NOHT: case NL80211_CHAN_WIDTH_20: + if (!ht_cap->ht_supported) + return false; + case NL80211_CHAN_WIDTH_20_NOHT: width = 20; break; case NL80211_CHAN_WIDTH_40: width = 40; + if (!ht_cap->ht_supported) + return false; + if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) || + ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT) + return false; + if (chandef->center_freq1 < control_freq && + chandef->chan->flags & IEEE80211_CHAN_NO_HT40MINUS) + return false; + if (chandef->center_freq1 > control_freq && + chandef->chan->flags & IEEE80211_CHAN_NO_HT40PLUS) + return false; break; - case NL80211_CHAN_WIDTH_80: case NL80211_CHAN_WIDTH_80P80: + if (!(vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)) + return false; + case NL80211_CHAN_WIDTH_80: + if (!vht_cap->vht_supported) + return false; width = 80; break; case NL80211_CHAN_WIDTH_160: + if (!vht_cap->vht_supported) + return false; + if (!(vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ)) + return false; width = 160; break; default: WARN_ON_ONCE(1); - trace_cfg80211_return_bool(false); return false; } - res = cfg80211_check_beacon_chans(wiphy, chandef->center_freq1, width); + /* TODO: missing regulatory check on 80/160 bandwidth */ + + if (!cfg80211_secondary_chans_ok(wiphy, chandef->center_freq1, + width, prohibited_flags)) + return false; + + if (!chandef->center_freq2) + return true; + return cfg80211_secondary_chans_ok(wiphy, chandef->center_freq2, + width, prohibited_flags); +} +EXPORT_SYMBOL(cfg80211_chandef_usable); + +bool cfg80211_reg_can_beacon(struct wiphy *wiphy, + struct cfg80211_chan_def *chandef) +{ + bool res; + + trace_cfg80211_reg_can_beacon(wiphy, chandef); - if (res && chandef->center_freq2) - res = cfg80211_check_beacon_chans(wiphy, chandef->center_freq2, - width); + res = cfg80211_chandef_usable(wiphy, chandef, + IEEE80211_CHAN_DISABLED | + IEEE80211_CHAN_PASSIVE_SCAN | + IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_RADAR); trace_cfg80211_return_bool(res); return res; diff --git a/trunk/net/wireless/core.h b/trunk/net/wireless/core.h index a0c8decf6a47..6183a0d25b8b 100644 --- a/trunk/net/wireless/core.h +++ b/trunk/net/wireless/core.h @@ -483,12 +483,6 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, enum nl80211_iftype iftype, int num); -bool cfg80211_chan_def_valid(const struct cfg80211_chan_def *chandef); - -bool cfg80211_secondary_chans_ok(struct wiphy *wiphy, - u32 center_freq, u32 bandwidth, - u32 prohibited_flags); - #define CFG80211_MAX_NUM_DIFFERENT_CHANNELS 10 #ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS diff --git a/trunk/net/wireless/nl80211.c b/trunk/net/wireless/nl80211.c index d038fa45ecd1..eb0aa71a02b3 100644 --- a/trunk/net/wireless/nl80211.c +++ b/trunk/net/wireless/nl80211.c @@ -1420,63 +1420,33 @@ static int nl80211_parse_chandef(struct cfg80211_registered_device *rdev, ht_cap = &rdev->wiphy.bands[chandef->chan->band]->ht_cap; vht_cap = &rdev->wiphy.bands[chandef->chan->band]->vht_cap; - if (!cfg80211_chan_def_valid(chandef)) + if (!cfg80211_chandef_valid(chandef)) return -EINVAL; switch (chandef->width) { case NL80211_CHAN_WIDTH_20: - if (!ht_cap->ht_supported) - return -EINVAL; case NL80211_CHAN_WIDTH_20_NOHT: width = 20; break; case NL80211_CHAN_WIDTH_40: width = 40; - /* quick early regulatory check */ - if (chandef->center_freq1 < control_freq && - chandef->chan->flags & IEEE80211_CHAN_NO_HT40MINUS) - return -EINVAL; - if (chandef->center_freq1 > control_freq && - chandef->chan->flags & IEEE80211_CHAN_NO_HT40PLUS) - return -EINVAL; - if (!ht_cap->ht_supported) - return -EINVAL; - if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) || - ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT) - return -EINVAL; break; case NL80211_CHAN_WIDTH_80: width = 80; - if (!vht_cap->vht_supported) - return -EINVAL; break; case NL80211_CHAN_WIDTH_80P80: width = 80; - if (!vht_cap->vht_supported) - return -EINVAL; - if (!(vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)) - return -EINVAL; break; case NL80211_CHAN_WIDTH_160: width = 160; - if (!vht_cap->vht_supported) - return -EINVAL; - if (!(vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ)) - return -EINVAL; break; default: return -EINVAL; } - if (!cfg80211_secondary_chans_ok(&rdev->wiphy, chandef->center_freq1, - width, IEEE80211_CHAN_DISABLED)) + if (!cfg80211_chandef_usable(&rdev->wiphy, chandef, + IEEE80211_CHAN_DISABLED)) return -EINVAL; - if (chandef->center_freq2 && - !cfg80211_secondary_chans_ok(&rdev->wiphy, chandef->center_freq2, - width, IEEE80211_CHAN_DISABLED)) - return -EINVAL; - - /* TODO: missing regulatory check on bandwidth */ return 0; } @@ -1841,7 +1811,7 @@ static inline u64 wdev_id(struct wireless_dev *wdev) static int nl80211_send_chandef(struct sk_buff *msg, struct cfg80211_chan_def *chandef) { - WARN_ON(!cfg80211_chan_def_valid(chandef)); + WARN_ON(!cfg80211_chandef_valid(chandef)); if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chandef->chan->center_freq)) diff --git a/trunk/net/wireless/reg.c b/trunk/net/wireless/reg.c index b75756b05af7..bcc7d7ee5a51 100644 --- a/trunk/net/wireless/reg.c +++ b/trunk/net/wireless/reg.c @@ -141,8 +141,9 @@ static const struct ieee80211_regdomain world_regdom = { .reg_rules = { /* IEEE 802.11b/g, channels 1..11 */ REG_RULE(2412-10, 2462+10, 40, 6, 20, 0), - /* IEEE 802.11b/g, channels 12..13. */ - REG_RULE(2467-10, 2472+10, 40, 6, 20, + /* IEEE 802.11b/g, channels 12..13. No HT40 + * channel fits here. */ + REG_RULE(2467-10, 2472+10, 20, 6, 20, NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS), /* IEEE 802.11 channel 14 - Only JP enables