diff --git a/[refs] b/[refs] index 2182829a31e0..160e9ea74dfe 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 0af5491c2f6069bb6cff4260619749a90a208c98 +refs/heads/master: b04db9ac4f7641332e0133b2fd8f82e6e4553947 diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index fe6dd3d7d2c4..3075a2a29511 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -1595,7 +1595,6 @@ M: Arend van Spriel M: Franky (Zhenhui) Lin M: Kan Yan L: linux-wireless@vger.kernel.org -L: brcm80211-dev-list@broadcom.com S: Supported F: drivers/net/wireless/brcm80211/ diff --git a/trunk/drivers/bcma/scan.c b/trunk/drivers/bcma/scan.c index a3420585d942..5ed0718fc660 100644 --- a/trunk/drivers/bcma/scan.c +++ b/trunk/drivers/bcma/scan.c @@ -28,12 +28,6 @@ static const struct bcma_device_id_name bcma_arm_device_names[] = { static const struct bcma_device_id_name bcma_bcm_device_names[] = { { BCMA_CORE_OOB_ROUTER, "OOB Router" }, - { BCMA_CORE_4706_CHIPCOMMON, "BCM4706 ChipCommon" }, - { BCMA_CORE_4706_SOC_RAM, "BCM4706 SOC RAM" }, - { BCMA_CORE_4706_MAC_GBIT, "BCM4706 GBit MAC" }, - { BCMA_CORE_AMEMC, "AMEMC (DDR)" }, - { BCMA_CORE_ALTA, "ALTA (I2S)" }, - { BCMA_CORE_4706_MAC_GBIT_COMMON, "BCM4706 GBit MAC Common" }, { BCMA_CORE_INVALID, "Invalid" }, { BCMA_CORE_CHIPCOMMON, "ChipCommon" }, { BCMA_CORE_ILINE20, "ILine 20" }, diff --git a/trunk/drivers/bluetooth/ath3k.c b/trunk/drivers/bluetooth/ath3k.c index 10308cd8a7ed..ad591bd240ec 100644 --- a/trunk/drivers/bluetooth/ath3k.c +++ b/trunk/drivers/bluetooth/ath3k.c @@ -63,7 +63,6 @@ static struct usb_device_id ath3k_table[] = { /* Atheros AR3011 with sflash firmware*/ { USB_DEVICE(0x0CF3, 0x3002) }, - { USB_DEVICE(0x0CF3, 0xE019) }, { USB_DEVICE(0x13d3, 0x3304) }, { USB_DEVICE(0x0930, 0x0215) }, { USB_DEVICE(0x0489, 0xE03D) }, @@ -78,7 +77,6 @@ static struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x04CA, 0x3005) }, { USB_DEVICE(0x13d3, 0x3362) }, { USB_DEVICE(0x0CF3, 0xE004) }, - { USB_DEVICE(0x0930, 0x0219) }, /* Atheros AR5BBU12 with sflash firmware */ { USB_DEVICE(0x0489, 0xE02C) }, @@ -103,7 +101,6 @@ static struct usb_device_id ath3k_blist_tbl[] = { { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, /* Atheros AR5BBU22 with sflash firmware */ { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 }, diff --git a/trunk/drivers/bluetooth/bluecard_cs.c b/trunk/drivers/bluetooth/bluecard_cs.c index 585c88e01893..1fcd92380356 100644 --- a/trunk/drivers/bluetooth/bluecard_cs.c +++ b/trunk/drivers/bluetooth/bluecard_cs.c @@ -231,12 +231,12 @@ static void bluecard_write_wakeup(bluecard_info_t *info) } do { - unsigned int iobase = info->p_dev->resource[0]->start; - unsigned int offset; - unsigned char command; - unsigned long ready_bit; + register unsigned int iobase = info->p_dev->resource[0]->start; + register unsigned int offset; + register unsigned char command; + register unsigned long ready_bit; register struct sk_buff *skb; - int len; + register int len; clear_bit(XMIT_WAKEUP, &(info->tx_state)); diff --git a/trunk/drivers/bluetooth/bpa10x.c b/trunk/drivers/bluetooth/bpa10x.c index 29caaed2d715..609861a53c28 100644 --- a/trunk/drivers/bluetooth/bpa10x.c +++ b/trunk/drivers/bluetooth/bpa10x.c @@ -470,7 +470,7 @@ static int bpa10x_probe(struct usb_interface *intf, const struct usb_device_id * hdev->flush = bpa10x_flush; hdev->send = bpa10x_send_frame; - set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks); + set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks); err = hci_register_dev(hdev); if (err < 0) { diff --git a/trunk/drivers/bluetooth/bt3c_cs.c b/trunk/drivers/bluetooth/bt3c_cs.c index b2b0fbbb43b5..308c8599ab55 100644 --- a/trunk/drivers/bluetooth/bt3c_cs.c +++ b/trunk/drivers/bluetooth/bt3c_cs.c @@ -186,9 +186,9 @@ static void bt3c_write_wakeup(bt3c_info_t *info) return; do { - unsigned int iobase = info->p_dev->resource[0]->start; + register unsigned int iobase = info->p_dev->resource[0]->start; register struct sk_buff *skb; - int len; + register int len; if (!pcmcia_dev_present(info->p_dev)) break; diff --git a/trunk/drivers/bluetooth/btmrvl_drv.h b/trunk/drivers/bluetooth/btmrvl_drv.h index 27068d149380..94f2d65131c4 100644 --- a/trunk/drivers/bluetooth/btmrvl_drv.h +++ b/trunk/drivers/bluetooth/btmrvl_drv.h @@ -136,7 +136,7 @@ int btmrvl_remove_card(struct btmrvl_private *priv); void btmrvl_interrupt(struct btmrvl_private *priv); -bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb); +void btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb); int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb); int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd); diff --git a/trunk/drivers/bluetooth/btmrvl_main.c b/trunk/drivers/bluetooth/btmrvl_main.c index dc304def8400..681ca9d18e12 100644 --- a/trunk/drivers/bluetooth/btmrvl_main.c +++ b/trunk/drivers/bluetooth/btmrvl_main.c @@ -44,33 +44,23 @@ void btmrvl_interrupt(struct btmrvl_private *priv) } EXPORT_SYMBOL_GPL(btmrvl_interrupt); -bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb) +void btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb) { struct hci_event_hdr *hdr = (void *) skb->data; struct hci_ev_cmd_complete *ec; - u16 opcode, ocf, ogf; + u16 opcode, ocf; if (hdr->evt == HCI_EV_CMD_COMPLETE) { ec = (void *) (skb->data + HCI_EVENT_HDR_SIZE); opcode = __le16_to_cpu(ec->opcode); ocf = hci_opcode_ocf(opcode); - ogf = hci_opcode_ogf(opcode); - if (ocf == BT_CMD_MODULE_CFG_REQ && priv->btmrvl_dev.sendcmdflag) { priv->btmrvl_dev.sendcmdflag = false; priv->adapter->cmd_complete = true; wake_up_interruptible(&priv->adapter->cmd_wait_q); } - - if (ogf == OGF) { - BT_DBG("vendor event skipped: ogf 0x%4.4x", ogf); - kfree_skb(skb); - return false; - } } - - return true; } EXPORT_SYMBOL_GPL(btmrvl_check_evtpkt); diff --git a/trunk/drivers/bluetooth/btmrvl_sdio.c b/trunk/drivers/bluetooth/btmrvl_sdio.c index cf7588edba0d..a853244e7fd7 100644 --- a/trunk/drivers/bluetooth/btmrvl_sdio.c +++ b/trunk/drivers/bluetooth/btmrvl_sdio.c @@ -110,9 +110,6 @@ static const struct sdio_device_id btmrvl_sdio_ids[] = { /* Marvell SD8787 Bluetooth device */ { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x911A), .driver_data = (unsigned long) &btmrvl_sdio_sd8787 }, - /* Marvell SD8787 Bluetooth AMP device */ - { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x911B), - .driver_data = (unsigned long) &btmrvl_sdio_sd8787 }, /* Marvell SD8797 Bluetooth device */ { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x912A), .driver_data = (unsigned long) &btmrvl_sdio_sd8797 }, @@ -565,12 +562,10 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) skb_put(skb, buf_len); skb_pull(skb, SDIO_HEADER_LEN); - if (type == HCI_EVENT_PKT) { - if (btmrvl_check_evtpkt(priv, skb)) - hci_recv_frame(skb); - } else - hci_recv_frame(skb); + if (type == HCI_EVENT_PKT) + btmrvl_check_evtpkt(priv, skb); + hci_recv_frame(skb); hdev->stat.byte_rx += buf_len; break; diff --git a/trunk/drivers/bluetooth/btuart_cs.c b/trunk/drivers/bluetooth/btuart_cs.c index 65b8d996840c..c4fc2f3fc32c 100644 --- a/trunk/drivers/bluetooth/btuart_cs.c +++ b/trunk/drivers/bluetooth/btuart_cs.c @@ -140,9 +140,9 @@ static void btuart_write_wakeup(btuart_info_t *info) } do { - unsigned int iobase = info->p_dev->resource[0]->start; + register unsigned int iobase = info->p_dev->resource[0]->start; register struct sk_buff *skb; - int len; + register int len; clear_bit(XMIT_WAKEUP, &(info->tx_state)); diff --git a/trunk/drivers/bluetooth/btusb.c b/trunk/drivers/bluetooth/btusb.c index e27221411036..c9463af8e564 100644 --- a/trunk/drivers/bluetooth/btusb.c +++ b/trunk/drivers/bluetooth/btusb.c @@ -21,7 +21,15 @@ * */ +#include #include +#include +#include +#include +#include +#include +#include + #include #include @@ -117,7 +125,6 @@ static struct usb_device_id blacklist_table[] = { /* Atheros 3011 with sflash firmware */ { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, - { USB_DEVICE(0x0cf3, 0xe019), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x0930, 0x0215), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x0489, 0xe03d), .driver_info = BTUSB_IGNORE }, @@ -132,7 +139,6 @@ static struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, - { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, /* Atheros AR5BBU12 with sflash firmware */ { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, @@ -1020,7 +1026,7 @@ static int btusb_probe(struct usb_interface *intf, data->isoc = usb_ifnum_to_if(data->udev, 1); if (!reset) - set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks); + set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks); if (force_scofix || id->driver_info & BTUSB_WRONG_SCO_MTU) { if (!disable_scofix) @@ -1032,7 +1038,7 @@ static int btusb_probe(struct usb_interface *intf, if (id->driver_info & BTUSB_DIGIANSWER) { data->cmdreq_type = USB_TYPE_VENDOR; - set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks); + set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks); } if (id->driver_info & BTUSB_CSR) { @@ -1040,7 +1046,7 @@ static int btusb_probe(struct usb_interface *intf, /* Old firmware would otherwise execute USB reset */ if (le16_to_cpu(udev->descriptor.bcdDevice) < 0x117) - set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks); + set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks); } if (id->driver_info & BTUSB_SNIFFER) { diff --git a/trunk/drivers/bluetooth/dtl1_cs.c b/trunk/drivers/bluetooth/dtl1_cs.c index b1b37ccd3cd4..6e8d96189684 100644 --- a/trunk/drivers/bluetooth/dtl1_cs.c +++ b/trunk/drivers/bluetooth/dtl1_cs.c @@ -144,9 +144,9 @@ static void dtl1_write_wakeup(dtl1_info_t *info) } do { - unsigned int iobase = info->p_dev->resource[0]->start; + register unsigned int iobase = info->p_dev->resource[0]->start; register struct sk_buff *skb; - int len; + register int len; clear_bit(XMIT_WAKEUP, &(info->tx_state)); diff --git a/trunk/drivers/bluetooth/hci_bcsp.c b/trunk/drivers/bluetooth/hci_bcsp.c index 57e502e06080..661a8dc4d2f8 100644 --- a/trunk/drivers/bluetooth/hci_bcsp.c +++ b/trunk/drivers/bluetooth/hci_bcsp.c @@ -552,7 +552,7 @@ static u16 bscp_get_crc(struct bcsp_struct *bcsp) static int bcsp_recv(struct hci_uart *hu, void *data, int count) { struct bcsp_struct *bcsp = hu->priv; - unsigned char *ptr; + register unsigned char *ptr; BT_DBG("hu %p count %d rx_state %d rx_count %ld", hu, count, bcsp->rx_state, bcsp->rx_count); diff --git a/trunk/drivers/bluetooth/hci_h4.c b/trunk/drivers/bluetooth/hci_h4.c index c60623f206d4..748329468d26 100644 --- a/trunk/drivers/bluetooth/hci_h4.c +++ b/trunk/drivers/bluetooth/hci_h4.c @@ -126,7 +126,7 @@ static int h4_enqueue(struct hci_uart *hu, struct sk_buff *skb) static inline int h4_check_data_len(struct h4_struct *h4, int len) { - int room = skb_tailroom(h4->rx_skb); + register int room = skb_tailroom(h4->rx_skb); BT_DBG("len %d room %d", len, room); diff --git a/trunk/drivers/bluetooth/hci_ldisc.c b/trunk/drivers/bluetooth/hci_ldisc.c index 2f9b796e106e..e564579a6115 100644 --- a/trunk/drivers/bluetooth/hci_ldisc.c +++ b/trunk/drivers/bluetooth/hci_ldisc.c @@ -394,7 +394,7 @@ static int hci_uart_register_dev(struct hci_uart *hu) set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); if (!test_bit(HCI_UART_RESET_ON_INIT, &hu->hdev_flags)) - set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks); + set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks); if (test_bit(HCI_UART_CREATE_AMP, &hu->hdev_flags)) hdev->dev_type = HCI_AMP; diff --git a/trunk/drivers/bluetooth/hci_ll.c b/trunk/drivers/bluetooth/hci_ll.c index ff6d589c34a5..b874c0efde24 100644 --- a/trunk/drivers/bluetooth/hci_ll.c +++ b/trunk/drivers/bluetooth/hci_ll.c @@ -348,7 +348,7 @@ static int ll_enqueue(struct hci_uart *hu, struct sk_buff *skb) static inline int ll_check_data_len(struct ll_struct *ll, int len) { - int room = skb_tailroom(ll->rx_skb); + register int room = skb_tailroom(ll->rx_skb); BT_DBG("len %d room %d", len, room); @@ -374,11 +374,11 @@ static inline int ll_check_data_len(struct ll_struct *ll, int len) static int ll_recv(struct hci_uart *hu, void *data, int count) { struct ll_struct *ll = hu->priv; - char *ptr; + register char *ptr; struct hci_event_hdr *eh; struct hci_acl_hdr *ah; struct hci_sco_hdr *sh; - int len, type, dlen; + register int len, type, dlen; BT_DBG("hu %p count %d rx_state %ld rx_count %ld", hu, count, ll->rx_state, ll->rx_count); diff --git a/trunk/drivers/net/wireless/airo.c b/trunk/drivers/net/wireless/airo.c index a747c632597a..520a4b2eb9cc 100644 --- a/trunk/drivers/net/wireless/airo.c +++ b/trunk/drivers/net/wireless/airo.c @@ -7233,8 +7233,8 @@ static int airo_get_aplist(struct net_device *dev, } } else { dwrq->flags = 1; /* Should be define'd */ - memcpy(extra + sizeof(struct sockaddr) * i, qual, - sizeof(struct iw_quality) * i); + memcpy(extra + sizeof(struct sockaddr)*i, + &qual, sizeof(struct iw_quality)*i); } dwrq->length = i; diff --git a/trunk/drivers/net/wireless/ath/ath.h b/trunk/drivers/net/wireless/ath/ath.h index 420d69b2674c..c54b7d37bff1 100644 --- a/trunk/drivers/net/wireless/ath/ath.h +++ b/trunk/drivers/net/wireless/ath/ath.h @@ -143,7 +143,6 @@ struct ath_common { u32 keymax; DECLARE_BITMAP(keymap, ATH_KEYMAX); DECLARE_BITMAP(tkip_keymap, ATH_KEYMAX); - DECLARE_BITMAP(ccmp_keymap, ATH_KEYMAX); enum ath_crypt_caps crypt_caps; unsigned int clockrate; diff --git a/trunk/drivers/net/wireless/ath/ath5k/base.c b/trunk/drivers/net/wireless/ath/ath5k/base.c index 44ad6fe0278f..fbaa30930076 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/base.c +++ b/trunk/drivers/net/wireless/ath/ath5k/base.c @@ -1045,11 +1045,11 @@ ath5k_drain_tx_buffs(struct ath5k_hw *ah) ath5k_txbuf_free_skb(ah, bf); - spin_lock(&ah->txbuflock); + spin_lock_bh(&ah->txbuflock); list_move_tail(&bf->list, &ah->txbuf); ah->txbuf_len++; txq->txq_len--; - spin_unlock(&ah->txbuflock); + spin_unlock_bh(&ah->txbuflock); } txq->link = NULL; txq->txq_poll_mark = false; diff --git a/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.c b/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.c index aca1d2689e90..f27e9732951d 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -53,11 +53,6 @@ #define DEFAULT_BG_SCAN_PERIOD 60 -struct ath6kl_cfg80211_match_probe_ssid { - struct cfg80211_ssid ssid; - u8 flag; -}; - static struct ieee80211_rate ath6kl_rates[] = { RATETAB_ENT(10, 0x1, 0), RATETAB_ENT(20, 0x2, 0), @@ -581,9 +576,6 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, vif->nw_type = vif->next_mode; - /* enable enhanced bmiss detection if applicable */ - ath6kl_cfg80211_sta_bmiss_enhance(vif, true); - if (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) nw_subtype = SUBTYPE_P2PCLIENT; @@ -860,6 +852,20 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason, } } + /* + * Send a disconnect command to target when a disconnect event is + * received with reason code other than 3 (DISCONNECT_CMD - disconnect + * request from host) to make the firmware stop trying to connect even + * after giving disconnect event. There will be one more disconnect + * event for this disconnect command with reason code DISCONNECT_CMD + * which will be notified to cfg80211. + */ + + if (reason != DISCONNECT_CMD) { + ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx); + return; + } + clear_bit(CONNECT_PEND, &vif->flags); if (vif->sme_state == SME_CONNECTING) { @@ -869,96 +875,32 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason, WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_KERNEL); } else if (vif->sme_state == SME_CONNECTED) { - cfg80211_disconnected(vif->ndev, proto_reason, + cfg80211_disconnected(vif->ndev, reason, NULL, 0, GFP_KERNEL); } vif->sme_state = SME_DISCONNECTED; - - /* - * Send a disconnect command to target when a disconnect event is - * received with reason code other than 3 (DISCONNECT_CMD - disconnect - * request from host) to make the firmware stop trying to connect even - * after giving disconnect event. There will be one more disconnect - * event for this disconnect command with reason code DISCONNECT_CMD - * which won't be notified to cfg80211. - */ - if (reason != DISCONNECT_CMD) - ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx); } static int ath6kl_set_probed_ssids(struct ath6kl *ar, struct ath6kl_vif *vif, - struct cfg80211_ssid *ssids, int n_ssids, - struct cfg80211_match_set *match_set, - int n_match_ssid) + struct cfg80211_ssid *ssids, int n_ssids) { - u8 i, j, index_to_add, ssid_found = false; - struct ath6kl_cfg80211_match_probe_ssid ssid_list[MAX_PROBED_SSIDS]; - - memset(ssid_list, 0, sizeof(ssid_list)); + u8 i; - if (n_ssids > MAX_PROBED_SSIDS || - n_match_ssid > MAX_PROBED_SSIDS) + if (n_ssids > MAX_PROBED_SSID_INDEX) return -EINVAL; for (i = 0; i < n_ssids; i++) { - memcpy(ssid_list[i].ssid.ssid, - ssids[i].ssid, - ssids[i].ssid_len); - ssid_list[i].ssid.ssid_len = ssids[i].ssid_len; - - if (ssids[i].ssid_len) - ssid_list[i].flag = SPECIFIC_SSID_FLAG; - else - ssid_list[i].flag = ANY_SSID_FLAG; - - if (n_match_ssid == 0) - ssid_list[i].flag |= MATCH_SSID_FLAG; - } - - index_to_add = i; - - for (i = 0; i < n_match_ssid; i++) { - ssid_found = false; - - for (j = 0; j < n_ssids; j++) { - if ((match_set[i].ssid.ssid_len == - ssid_list[j].ssid.ssid_len) && - (!memcmp(ssid_list[j].ssid.ssid, - match_set[i].ssid.ssid, - match_set[i].ssid.ssid_len))) { - ssid_list[j].flag |= MATCH_SSID_FLAG; - ssid_found = true; - break; - } - } - - if (ssid_found) - continue; - - if (index_to_add >= MAX_PROBED_SSIDS) - continue; - - ssid_list[index_to_add].ssid.ssid_len = - match_set[i].ssid.ssid_len; - memcpy(ssid_list[index_to_add].ssid.ssid, - match_set[i].ssid.ssid, - match_set[i].ssid.ssid_len); - ssid_list[index_to_add].flag |= MATCH_SSID_FLAG; - index_to_add++; - } - - for (i = 0; i < index_to_add; i++) { ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i, - ssid_list[i].flag, - ssid_list[i].ssid.ssid_len, - ssid_list[i].ssid.ssid); - + ssids[i].ssid_len ? + SPECIFIC_SSID_FLAG : ANY_SSID_FLAG, + ssids[i].ssid_len, + ssids[i].ssid); } /* Make sure no old entries are left behind */ - for (i = index_to_add; i < MAX_PROBED_SSIDS; i++) { + for (i = n_ssids; i < MAX_PROBED_SSID_INDEX; i++) { ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i, DISABLE_SSID_FLAG, 0, NULL); } @@ -992,7 +934,7 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, } ret = ath6kl_set_probed_ssids(ar, vif, request->ssids, - request->n_ssids, NULL, 0); + request->n_ssids); if (ret < 0) return ret; @@ -1001,7 +943,7 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, WMI_FRAME_PROBE_REQ, request->ie, request->ie_len); if (ret) { - ath6kl_err("failed to set Probe Request appie for scan\n"); + ath6kl_err("failed to set Probe Request appie for scan"); return ret; } @@ -1570,9 +1512,6 @@ static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy, } } - /* need to clean up enhanced bmiss detection fw state */ - ath6kl_cfg80211_sta_bmiss_enhance(vif, false); - set_iface_type: switch (type) { case NL80211_IFTYPE_STATION: @@ -2135,9 +2074,7 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) 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, - ar->fw_capabilities)) { + if (!test_bit(NETDEV_MCAST_ALL_ON, &vif->flags)) { ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, vif->fw_vif_idx, false); if (ret) @@ -2272,9 +2209,7 @@ static int ath6kl_wow_resume(struct ath6kl *ar) 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)) { + if (!test_bit(NETDEV_MCAST_ALL_OFF, &vif->flags)) { ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, vif->fw_vif_idx, true); if (ret) @@ -2540,7 +2475,7 @@ void ath6kl_check_wow_status(struct ath6kl *ar) static int ath6kl_set_htcap(struct ath6kl_vif *vif, enum ieee80211_band band, bool ht_enable) { - struct ath6kl_htcap *htcap = &vif->htcap[band]; + struct ath6kl_htcap *htcap = &vif->htcap; if (htcap->ht_enable == ht_enable) return 0; @@ -2650,30 +2585,6 @@ static int ath6kl_set_ies(struct ath6kl_vif *vif, return 0; } -void ath6kl_cfg80211_sta_bmiss_enhance(struct ath6kl_vif *vif, bool enable) -{ - int err; - - if (WARN_ON(!test_bit(WMI_READY, &vif->ar->flag))) - return; - - if (vif->nw_type != INFRA_NETWORK) - return; - - if (!test_bit(ATH6KL_FW_CAPABILITY_BMISS_ENHANCE, - vif->ar->fw_capabilities)) - return; - - ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s fw bmiss enhance\n", - enable ? "enable" : "disable"); - - err = ath6kl_wmi_sta_bmiss_enhance_cmd(vif->ar->wmi, - vif->fw_vif_idx, enable); - if (err) - ath6kl_err("failed to %s enhanced bmiss detection: %d\n", - enable ? "enable" : "disable", err); -} - static int ath6kl_get_rsn_capab(struct cfg80211_beacon_data *beacon, u8 *rsn_capab) { @@ -2754,15 +2665,9 @@ static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev, /* TODO: * info->interval + * info->dtim_period */ - ret = ath6kl_wmi_ap_set_dtim_cmd(ar->wmi, vif->fw_vif_idx, - info->dtim_period); - - /* ignore error, just print a warning and continue normally */ - if (ret) - ath6kl_warn("Failed to set dtim_period in beacon: %d\n", ret); - if (info->beacon.head == NULL) return -EINVAL; mgmt = (struct ieee80211_mgmt *) info->beacon.head; @@ -3226,24 +3131,10 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy, ath6kl_cfg80211_scan_complete_event(vif, true); ret = ath6kl_set_probed_ssids(ar, vif, request->ssids, - request->n_ssids, - request->match_sets, - request->n_match_sets); + request->n_ssids); if (ret < 0) return ret; - if (!request->n_match_sets) { - ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, - ALL_BSS_FILTER, 0); - if (ret < 0) - return ret; - } else { - ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, - MATCHED_SSID_FILTER, 0); - if (ret < 0) - return ret; - } - /* fw uses seconds, also make sure that it's >0 */ interval = max_t(u16, 1, request->interval / 1000); @@ -3265,7 +3156,7 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy, WMI_FRAME_PROBE_REQ, request->ie, request->ie_len); if (ret) { - ath6kl_warn("Failed to set probe request IE for scheduled scan: %d\n", + ath6kl_warn("Failed to set probe request IE for scheduled scan: %d", ret); return ret; } @@ -3297,18 +3188,6 @@ static int ath6kl_cfg80211_sscan_stop(struct wiphy *wiphy, return 0; } -static int ath6kl_cfg80211_set_bitrate(struct wiphy *wiphy, - struct net_device *dev, - const u8 *addr, - const struct cfg80211_bitrate_mask *mask) -{ - struct ath6kl *ar = ath6kl_priv(dev); - struct ath6kl_vif *vif = netdev_priv(dev); - - return ath6kl_wmi_set_bitrate_mask(ar->wmi, vif->fw_vif_idx, - mask); -} - static const struct ieee80211_txrx_stypes ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = { [NL80211_IFTYPE_STATION] = { @@ -3374,7 +3253,6 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = { .mgmt_frame_register = ath6kl_mgmt_frame_register, .sched_scan_start = ath6kl_cfg80211_sscan_start, .sched_scan_stop = ath6kl_cfg80211_sscan_stop, - .set_bitrate_mask = ath6kl_cfg80211_set_bitrate, }; void ath6kl_cfg80211_stop(struct ath6kl_vif *vif) @@ -3502,8 +3380,7 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL; vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME; vif->bg_scan_period = 0; - vif->htcap[IEEE80211_BAND_2GHZ].ht_enable = true; - vif->htcap[IEEE80211_BAND_5GHZ].ht_enable = true; + vif->htcap.ht_enable = true; memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN); if (fw_vif_idx != 0) @@ -3563,13 +3440,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) } /* max num of ssids that can be probed during scanning */ - wiphy->max_scan_ssids = MAX_PROBED_SSIDS; - - /* max num of ssids that can be matched after scan */ - if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST, - ar->fw_capabilities)) - wiphy->max_match_sets = MAX_PROBED_SSIDS; - + wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX; wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */ switch (ar->hw.cap) { case WMI_11AN_CAP: @@ -3606,17 +3477,6 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) ath6kl_band_5ghz.ht_cap.cap = 0; ath6kl_band_5ghz.ht_cap.ht_supported = false; } - - 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; - ath6kl_band_5ghz.ht_cap.mcs.rx_mask[1] = 0xff; - } else { - ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff; - ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff; - } - if (band_2gig) wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz; if (band_5gig) @@ -3627,7 +3487,6 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) wiphy->cipher_suites = cipher_suites; wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); -#ifdef CONFIG_PM wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT | WIPHY_WOWLAN_GTK_REKEY_FAILURE | @@ -3637,9 +3496,8 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) wiphy->wowlan.n_patterns = WOW_MAX_FILTERS_PER_LIST; wiphy->wowlan.pattern_min_len = 1; wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE; -#endif - wiphy->max_sched_scan_ssids = MAX_PROBED_SSIDS; + wiphy->max_sched_scan_ssids = MAX_PROBED_SSID_INDEX; ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM | WIPHY_FLAG_HAVE_AP_SME | diff --git a/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.h b/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.h index b992046a1b0e..5ea8cbb79f43 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.h +++ b/trunk/drivers/net/wireless/ath/ath6kl/cfg80211.h @@ -62,7 +62,5 @@ void ath6kl_cfg80211_cleanup(struct ath6kl *ar); struct ath6kl *ath6kl_cfg80211_create(void); void ath6kl_cfg80211_destroy(struct ath6kl *ar); -/* TODO: remove this once ath6kl_vif_cleanup() is moved to cfg80211.c */ -void ath6kl_cfg80211_sta_bmiss_enhance(struct ath6kl_vif *vif, bool enable); #endif /* ATH6KL_CFG80211_H */ diff --git a/trunk/drivers/net/wireless/ath/ath6kl/core.h b/trunk/drivers/net/wireless/ath/ath6kl/core.h index d38a31de344c..8443b2a4133e 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/core.h +++ b/trunk/drivers/net/wireless/ath/ath6kl/core.h @@ -100,21 +100,6 @@ enum ath6kl_fw_capability { /* Firmware has support to override rsn cap of rsn ie */ ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE, - /* - * Multicast support in WOW and host awake mode. - * Allow all multicast in host awake mode. - * Apply multicast filter in WOW mode. - */ - ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER, - - /* Firmware supports enhanced bmiss detection */ - ATH6KL_FW_CAPABILITY_BMISS_ENHANCE, - - /* - * FW supports matching of ssid in schedule scan - */ - ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST, - /* this needs to be last */ ATH6KL_FW_CAPABILITY_MAX, }; @@ -127,10 +112,6 @@ struct ath6kl_fw_ie { u8 data[0]; }; -enum ath6kl_hw_flags { - ATH6KL_HW_FLAG_64BIT_RATES = BIT(0), -}; - #define ATH6KL_FW_API2_FILE "fw-2.bin" #define ATH6KL_FW_API3_FILE "fw-3.bin" @@ -215,7 +196,7 @@ enum ath6kl_hw_flags { #define AGGR_NUM_OF_FREE_NETBUFS 16 -#define AGGR_RX_TIMEOUT 100 /* in ms */ +#define AGGR_RX_TIMEOUT 400 /* in ms */ #define WMI_TIMEOUT (2 * HZ) @@ -264,6 +245,7 @@ struct skb_hold_q { struct rxtid { bool aggr; + bool progress; bool timer_mon; u16 win_sz; u16 seq_next; @@ -272,15 +254,9 @@ struct rxtid { struct sk_buff_head q; /* - * lock mainly protects seq_next and hold_q. Movement of seq_next - * needs to be protected between aggr_timeout() and - * aggr_process_recv_frm(). hold_q will be holding the pending - * reorder frames and it's access should also be protected. - * Some of the other fields like hold_q_sz, win_sz and aggr are - * initialized/reset when receiving addba/delba req, also while - * deleting aggr state all the pending buffers are flushed before - * resetting these fields, so there should not be any race in accessing - * these fields. + * FIXME: No clue what this should protect. Apparently it should + * protect some of the fields above but they are also accessed + * without taking the lock. */ spinlock_t lock; }; @@ -565,7 +541,7 @@ struct ath6kl_vif { struct ath6kl_wep_key wep_key_list[WMI_MAX_KEY_INDEX + 1]; struct ath6kl_key keys[WMI_MAX_KEY_INDEX + 1]; struct aggr_info *aggr_cntxt; - struct ath6kl_htcap htcap[IEEE80211_NUM_BANDS]; + struct ath6kl_htcap htcap; struct timer_list disconnect_timer; struct timer_list sched_scan_timer; @@ -708,8 +684,6 @@ struct ath6kl { u32 testscript_addr; enum wmi_phy_cap cap; - u32 flags; - struct ath6kl_hw_fw { const char *dir; const char *otp; diff --git a/trunk/drivers/net/wireless/ath/ath6kl/htc_mbox.c b/trunk/drivers/net/wireless/ath/ath6kl/htc_mbox.c index cd0e1ba410d6..2798624d3a9d 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/htc_mbox.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/htc_mbox.c @@ -1309,7 +1309,7 @@ static int ath6kl_htc_rx_packet(struct htc_target *target, } ath6kl_dbg(ATH6KL_DBG_HTC, - "htc rx 0x%p hdr 0x%x len %d mbox 0x%x\n", + "htc rx 0x%p hdr x%x len %d mbox 0x%x\n", packet, packet->info.rx.exp_hdr, padded_len, dev->ar->mbox_info.htc_addr); diff --git a/trunk/drivers/net/wireless/ath/ath6kl/init.c b/trunk/drivers/net/wireless/ath/ath6kl/init.c index f90b5db741cf..7eb0515f458a 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/init.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/init.c @@ -42,7 +42,6 @@ static const struct ath6kl_hw hw_list[] = { .reserved_ram_size = 6912, .refclk_hz = 26000000, .uarttx_pin = 8, - .flags = 0, /* hw2.0 needs override address hardcoded */ .app_start_override_addr = 0x944C00, @@ -68,7 +67,6 @@ static const struct ath6kl_hw hw_list[] = { .refclk_hz = 26000000, .uarttx_pin = 8, .testscript_addr = 0x57ef74, - .flags = 0, .fw = { .dir = AR6003_HW_2_1_1_FW_DIR, @@ -93,7 +91,6 @@ static const struct ath6kl_hw hw_list[] = { .board_addr = 0x433900, .refclk_hz = 26000000, .uarttx_pin = 11, - .flags = ATH6KL_HW_FLAG_64BIT_RATES, .fw = { .dir = AR6004_HW_1_0_FW_DIR, @@ -113,7 +110,6 @@ static const struct ath6kl_hw hw_list[] = { .board_addr = 0x43d400, .refclk_hz = 40000000, .uarttx_pin = 11, - .flags = ATH6KL_HW_FLAG_64BIT_RATES, .fw = { .dir = AR6004_HW_1_1_FW_DIR, @@ -133,7 +129,6 @@ static const struct ath6kl_hw hw_list[] = { .board_addr = 0x435c00, .refclk_hz = 40000000, .uarttx_pin = 11, - .flags = ATH6KL_HW_FLAG_64BIT_RATES, .fw = { .dir = AR6004_HW_1_2_FW_DIR, @@ -943,14 +938,6 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name) } switch (ie_id) { - case ATH6KL_FW_IE_FW_VERSION: - strlcpy(ar->wiphy->fw_version, data, - sizeof(ar->wiphy->fw_version)); - - ath6kl_dbg(ATH6KL_DBG_BOOT, - "found fw version %s\n", - ar->wiphy->fw_version); - break; case ATH6KL_FW_IE_OTP_IMAGE: ath6kl_dbg(ATH6KL_DBG_BOOT, "found otp image ie (%zd B)\n", ie_len); @@ -1004,6 +991,9 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name) ar->hw.reserved_ram_size); break; case ATH6KL_FW_IE_CAPABILITIES: + if (ie_len < DIV_ROUND_UP(ATH6KL_FW_CAPABILITY_MAX, 8)) + break; + ath6kl_dbg(ATH6KL_DBG_BOOT, "found firmware capabilities ie (%zd B)\n", ie_len); @@ -1012,9 +1002,6 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name) index = i / 8; bit = i % 8; - if (index == ie_len) - break; - if (data[index] & (1 << bit)) __set_bit(i, ar->fw_capabilities); } @@ -1405,12 +1392,6 @@ static int ath6kl_init_upload(struct ath6kl *ar) ar->version.target_ver == AR6003_HW_2_1_1_VERSION) { ath6kl_err("temporary war to avoid sdio crc error\n"); - param = 0x28; - address = GPIO_BASE_ADDRESS + GPIO_PIN9_ADDRESS; - status = ath6kl_bmi_reg_write(ar, address, param); - if (status) - return status; - param = 0x20; address = GPIO_BASE_ADDRESS + GPIO_PIN10_ADDRESS; @@ -1678,9 +1659,6 @@ void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready) cfg80211_scan_done(vif->scan_req, true); vif->scan_req = NULL; } - - /* need to clean up enhanced bmiss detection fw state */ - ath6kl_cfg80211_sta_bmiss_enhance(vif, false); } void ath6kl_stop_txrx(struct ath6kl *ar) diff --git a/trunk/drivers/net/wireless/ath/ath6kl/main.c b/trunk/drivers/net/wireless/ath/ath6kl/main.c index c189e28e86a9..b836f2795114 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/main.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/main.c @@ -554,24 +554,20 @@ void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver, struct ath6kl *ar = devt; memcpy(ar->mac_addr, datap, ETH_ALEN); - - ath6kl_dbg(ATH6KL_DBG_BOOT, - "ready event mac addr %pM sw_ver 0x%x abi_ver 0x%x cap 0x%x\n", - ar->mac_addr, sw_ver, abi_ver, cap); + ath6kl_dbg(ATH6KL_DBG_TRC, "%s: mac addr = %pM\n", + __func__, ar->mac_addr); ar->version.wlan_ver = sw_ver; ar->version.abi_ver = abi_ver; ar->hw.cap = cap; - if (strlen(ar->wiphy->fw_version) == 0) { - snprintf(ar->wiphy->fw_version, - sizeof(ar->wiphy->fw_version), - "%u.%u.%u.%u", - (ar->version.wlan_ver & 0xf0000000) >> 28, - (ar->version.wlan_ver & 0x0f000000) >> 24, - (ar->version.wlan_ver & 0x00ff0000) >> 16, - (ar->version.wlan_ver & 0x0000ffff)); - } + snprintf(ar->wiphy->fw_version, + sizeof(ar->wiphy->fw_version), + "%u.%u.%u.%u", + (ar->version.wlan_ver & 0xf0000000) >> 28, + (ar->version.wlan_ver & 0x0f000000) >> 24, + (ar->version.wlan_ver & 0x00ff0000) >> 16, + (ar->version.wlan_ver & 0x0000ffff)); /* indicate to the waiting thread that the ready event was received */ set_bit(WMI_READY, &ar->flag); @@ -1170,10 +1166,7 @@ static void ath6kl_set_multicast_list(struct net_device *ndev) else clear_bit(NETDEV_MCAST_ALL_ON, &vif->flags); - if (test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER, - vif->ar->fw_capabilities)) { - mc_all_on = mc_all_on || (vif->ar->state == ATH6KL_STATE_ON); - } + mc_all_on = mc_all_on || (vif->ar->state == ATH6KL_STATE_ON); if (!(ndev->flags & IFF_MULTICAST)) { mc_all_on = false; diff --git a/trunk/drivers/net/wireless/ath/ath6kl/target.h b/trunk/drivers/net/wireless/ath/ath6kl/target.h index a98c12ba70c1..78e0ef4567a5 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/target.h +++ b/trunk/drivers/net/wireless/ath/ath6kl/target.h @@ -45,7 +45,6 @@ #define LPO_CAL_ENABLE_S 20 #define LPO_CAL_ENABLE 0x00100000 -#define GPIO_PIN9_ADDRESS 0x0000004c #define GPIO_PIN10_ADDRESS 0x00000050 #define GPIO_PIN11_ADDRESS 0x00000054 #define GPIO_PIN12_ADDRESS 0x00000058 diff --git a/trunk/drivers/net/wireless/ath/ath6kl/txrx.c b/trunk/drivers/net/wireless/ath/ath6kl/txrx.c index 7dfa0fd86d7b..67206aedea6c 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/txrx.c @@ -1036,7 +1036,6 @@ static void aggr_deque_frms(struct aggr_info_conn *agg_conn, u8 tid, rxtid = &agg_conn->rx_tid[tid]; stats = &agg_conn->stat[tid]; - spin_lock_bh(&rxtid->lock); idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz); /* @@ -1055,6 +1054,8 @@ static void aggr_deque_frms(struct aggr_info_conn *agg_conn, u8 tid, seq_end = seq_no ? seq_no : rxtid->seq_next; idx_end = AGGR_WIN_IDX(seq_end, rxtid->hold_q_sz); + spin_lock_bh(&rxtid->lock); + do { node = &rxtid->hold_q[idx]; if ((order == 1) && (!node->skb)) @@ -1126,13 +1127,11 @@ static bool aggr_process_recv_frm(struct aggr_info_conn *agg_conn, u8 tid, ((end > extended_end) && (cur > extended_end) && (cur < end))) { aggr_deque_frms(agg_conn, tid, 0, 0); - spin_lock_bh(&rxtid->lock); if (cur >= rxtid->hold_q_sz - 1) rxtid->seq_next = cur - (rxtid->hold_q_sz - 1); else rxtid->seq_next = ATH6KL_MAX_SEQ_NO - (rxtid->hold_q_sz - 2 - cur); - spin_unlock_bh(&rxtid->lock); } else { /* * Dequeue only those frames that are outside the @@ -1186,25 +1185,25 @@ static bool aggr_process_recv_frm(struct aggr_info_conn *agg_conn, u8 tid, aggr_deque_frms(agg_conn, tid, 0, 1); if (agg_conn->timer_scheduled) - return is_queued; - - spin_lock_bh(&rxtid->lock); - for (idx = 0 ; idx < rxtid->hold_q_sz; idx++) { - if (rxtid->hold_q[idx].skb) { - /* - * There is a frame in the queue and no - * timer so start a timer to ensure that - * the frame doesn't remain stuck - * forever. - */ - agg_conn->timer_scheduled = true; - mod_timer(&agg_conn->timer, - (jiffies + (HZ * AGGR_RX_TIMEOUT) / 1000)); - rxtid->timer_mon = true; - break; + rxtid->progress = true; + else + for (idx = 0 ; idx < rxtid->hold_q_sz; idx++) { + if (rxtid->hold_q[idx].skb) { + /* + * There is a frame in the queue and no + * timer so start a timer to ensure that + * the frame doesn't remain stuck + * forever. + */ + agg_conn->timer_scheduled = true; + mod_timer(&agg_conn->timer, + (jiffies + + HZ * (AGGR_RX_TIMEOUT) / 1000)); + rxtid->progress = false; + rxtid->timer_mon = true; + break; + } } - } - spin_unlock_bh(&rxtid->lock); return is_queued; } @@ -1609,7 +1608,7 @@ static void aggr_timeout(unsigned long arg) rxtid = &aggr_conn->rx_tid[i]; stats = &aggr_conn->stat[i]; - if (!rxtid->aggr || !rxtid->timer_mon) + if (!rxtid->aggr || !rxtid->timer_mon || rxtid->progress) continue; stats->num_timeouts++; @@ -1627,15 +1626,14 @@ static void aggr_timeout(unsigned long arg) rxtid = &aggr_conn->rx_tid[i]; if (rxtid->aggr && rxtid->hold_q) { - spin_lock_bh(&rxtid->lock); for (j = 0; j < rxtid->hold_q_sz; j++) { if (rxtid->hold_q[j].skb) { aggr_conn->timer_scheduled = true; rxtid->timer_mon = true; + rxtid->progress = false; break; } } - spin_unlock_bh(&rxtid->lock); if (j >= rxtid->hold_q_sz) rxtid->timer_mon = false; @@ -1662,6 +1660,7 @@ static void aggr_delete_tid_state(struct aggr_info_conn *aggr_conn, u8 tid) aggr_deque_frms(aggr_conn, tid, 0, 0); rxtid->aggr = false; + rxtid->progress = false; rxtid->timer_mon = false; rxtid->win_sz = 0; rxtid->seq_next = 0; @@ -1740,6 +1739,7 @@ void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info *aggr_info, for (i = 0; i < NUM_OF_TIDS; i++) { rxtid = &aggr_conn->rx_tid[i]; rxtid->aggr = false; + rxtid->progress = false; rxtid->timer_mon = false; skb_queue_head_init(&rxtid->q); spin_lock_init(&rxtid->lock); diff --git a/trunk/drivers/net/wireless/ath/ath6kl/wmi.c b/trunk/drivers/net/wireless/ath/ath6kl/wmi.c index a6caa673e8ad..ee8ec2394c2c 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/trunk/drivers/net/wireless/ath/ath6kl/wmi.c @@ -743,6 +743,7 @@ int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid) return -ENOMEM; cmd = (struct roam_ctrl_cmd *) skb->data; + memset(cmd, 0, sizeof(*cmd)); memcpy(cmd->info.bssid, bssid, ETH_ALEN); cmd->roam_ctrl = WMI_FORCE_ROAM; @@ -752,22 +753,6 @@ int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid) NO_SYNC_WMIFLAG); } -int ath6kl_wmi_ap_set_dtim_cmd(struct wmi *wmi, u8 if_idx, u32 dtim_period) -{ - struct sk_buff *skb; - struct set_dtim_cmd *cmd; - - skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); - if (!skb) - return -ENOMEM; - - cmd = (struct set_dtim_cmd *) skb->data; - - cmd->dtim_period = cpu_to_le32(dtim_period); - return ath6kl_wmi_cmd_send(wmi, if_idx, skb, - WMI_AP_SET_DTIM_CMDID, NO_SYNC_WMIFLAG); -} - int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode) { struct sk_buff *skb; @@ -778,6 +763,7 @@ int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode) return -ENOMEM; cmd = (struct roam_ctrl_cmd *) skb->data; + memset(cmd, 0, sizeof(*cmd)); cmd->info.roam_mode = mode; cmd->roam_ctrl = WMI_SET_ROAM_MODE; @@ -2009,7 +1995,7 @@ int ath6kl_wmi_probedssid_cmd(struct wmi *wmi, u8 if_idx, u8 index, u8 flag, struct wmi_probed_ssid_cmd *cmd; int ret; - if (index >= MAX_PROBED_SSIDS) + if (index > MAX_PROBED_SSID_INDEX) return -EINVAL; if (ssid_len > sizeof(cmd->ssid)) @@ -2613,115 +2599,6 @@ static void ath6kl_wmi_relinquish_implicit_pstream_credits(struct wmi *wmi) spin_unlock_bh(&wmi->lock); } -static int ath6kl_set_bitrate_mask64(struct wmi *wmi, u8 if_idx, - const struct cfg80211_bitrate_mask *mask) -{ - struct sk_buff *skb; - int ret, mode, band; - u64 mcsrate, ratemask[IEEE80211_NUM_BANDS]; - struct wmi_set_tx_select_rates64_cmd *cmd; - - memset(&ratemask, 0, sizeof(ratemask)); - for (band = 0; band < IEEE80211_NUM_BANDS; band++) { - /* copy legacy rate mask */ - ratemask[band] = mask->control[band].legacy; - if (band == IEEE80211_BAND_5GHZ) - ratemask[band] = - mask->control[band].legacy << 4; - - /* copy mcs rate mask */ - mcsrate = mask->control[band].mcs[1]; - mcsrate <<= 8; - mcsrate |= mask->control[band].mcs[0]; - ratemask[band] |= mcsrate << 12; - ratemask[band] |= mcsrate << 28; - } - - ath6kl_dbg(ATH6KL_DBG_WMI, - "Ratemask 64 bit: 2.4:%llx 5:%llx\n", - ratemask[0], ratemask[1]); - - skb = ath6kl_wmi_get_new_buf(sizeof(*cmd) * WMI_RATES_MODE_MAX); - if (!skb) - return -ENOMEM; - - cmd = (struct wmi_set_tx_select_rates64_cmd *) skb->data; - for (mode = 0; mode < WMI_RATES_MODE_MAX; mode++) { - /* A mode operate in 5GHZ band */ - if (mode == WMI_RATES_MODE_11A || - mode == WMI_RATES_MODE_11A_HT20 || - mode == WMI_RATES_MODE_11A_HT40) - band = IEEE80211_BAND_5GHZ; - else - band = IEEE80211_BAND_2GHZ; - cmd->ratemask[mode] = cpu_to_le64(ratemask[band]); - } - - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, - WMI_SET_TX_SELECT_RATES_CMDID, - NO_SYNC_WMIFLAG); - return ret; -} - -static int ath6kl_set_bitrate_mask32(struct wmi *wmi, u8 if_idx, - const struct cfg80211_bitrate_mask *mask) -{ - struct sk_buff *skb; - int ret, mode, band; - u32 mcsrate, ratemask[IEEE80211_NUM_BANDS]; - struct wmi_set_tx_select_rates32_cmd *cmd; - - memset(&ratemask, 0, sizeof(ratemask)); - for (band = 0; band < IEEE80211_NUM_BANDS; band++) { - /* copy legacy rate mask */ - ratemask[band] = mask->control[band].legacy; - if (band == IEEE80211_BAND_5GHZ) - ratemask[band] = - mask->control[band].legacy << 4; - - /* copy mcs rate mask */ - mcsrate = mask->control[band].mcs[0]; - ratemask[band] |= mcsrate << 12; - ratemask[band] |= mcsrate << 20; - } - - ath6kl_dbg(ATH6KL_DBG_WMI, - "Ratemask 32 bit: 2.4:%x 5:%x\n", - ratemask[0], ratemask[1]); - - skb = ath6kl_wmi_get_new_buf(sizeof(*cmd) * WMI_RATES_MODE_MAX); - if (!skb) - return -ENOMEM; - - cmd = (struct wmi_set_tx_select_rates32_cmd *) skb->data; - for (mode = 0; mode < WMI_RATES_MODE_MAX; mode++) { - /* A mode operate in 5GHZ band */ - if (mode == WMI_RATES_MODE_11A || - mode == WMI_RATES_MODE_11A_HT20 || - mode == WMI_RATES_MODE_11A_HT40) - band = IEEE80211_BAND_5GHZ; - else - band = IEEE80211_BAND_2GHZ; - cmd->ratemask[mode] = cpu_to_le32(ratemask[band]); - } - - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, - WMI_SET_TX_SELECT_RATES_CMDID, - NO_SYNC_WMIFLAG); - return ret; -} - -int ath6kl_wmi_set_bitrate_mask(struct wmi *wmi, u8 if_idx, - const struct cfg80211_bitrate_mask *mask) -{ - struct ath6kl *ar = wmi->parent_dev; - - 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); -} - int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx, enum ath6kl_host_mode host_mode) { @@ -3120,25 +2997,6 @@ int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, return ret; } -int ath6kl_wmi_sta_bmiss_enhance_cmd(struct wmi *wmi, u8 if_idx, bool enhance) -{ - struct sk_buff *skb; - struct wmi_sta_bmiss_enhance_cmd *cmd; - int ret; - - skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); - if (!skb) - return -ENOMEM; - - cmd = (struct wmi_sta_bmiss_enhance_cmd *) skb->data; - cmd->enable = enhance ? 1 : 0; - - ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, - WMI_STA_BMISS_ENHANCE_CMDID, - NO_SYNC_WMIFLAG); - return ret; -} - s32 ath6kl_wmi_get_rate(s8 rate_index) { if (rate_index == RATE_AUTO) diff --git a/trunk/drivers/net/wireless/ath/ath6kl/wmi.h b/trunk/drivers/net/wireless/ath/ath6kl/wmi.h index 43339aca585d..9076bec3a2ba 100644 --- a/trunk/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/trunk/drivers/net/wireless/ath/ath6kl/wmi.h @@ -624,10 +624,6 @@ enum wmi_cmd_id { WMI_SEND_MGMT_CMDID, WMI_BEGIN_SCAN_CMDID, - WMI_SET_BLACK_LIST, - WMI_SET_MCASTRATE, - - WMI_STA_BMISS_ENHANCE_CMDID, }; enum wmi_mgmt_frame_type { @@ -964,9 +960,6 @@ enum wmi_bss_filter { /* beacons matching probed ssid */ PROBED_SSID_FILTER, - /* beacons matching matched ssid */ - MATCHED_SSID_FILTER, - /* marker only */ LAST_BSS_FILTER, }; @@ -985,7 +978,7 @@ struct wmi_bss_filter_cmd { } __packed; /* WMI_SET_PROBED_SSID_CMDID */ -#define MAX_PROBED_SSIDS 16 +#define MAX_PROBED_SSID_INDEX 9 enum wmi_ssid_flag { /* disables entry */ @@ -996,13 +989,10 @@ enum wmi_ssid_flag { /* probes for any ssid */ ANY_SSID_FLAG = 0x02, - - /* match for ssid */ - MATCH_SSID_FLAG = 0x08, }; struct wmi_probed_ssid_cmd { - /* 0 to MAX_PROBED_SSIDS - 1 */ + /* 0 to MAX_PROBED_SSID_INDEX */ u8 entry_index; /* see, enum wmi_ssid_flg */ @@ -1027,11 +1017,6 @@ struct wmi_bmiss_time_cmd { __le16 num_beacons; }; -/* WMI_STA_ENHANCE_BMISS_CMDID */ -struct wmi_sta_bmiss_enhance_cmd { - u8 enable; -} __packed; - /* WMI_SET_POWER_MODE_CMDID */ enum wmi_power_mode { REC_POWER = 0x01, @@ -1063,36 +1048,6 @@ struct wmi_power_params_cmd { __le16 ps_fail_event_policy; } __packed; -/* - * Ratemask for below modes should be passed - * to WMI_SET_TX_SELECT_RATES_CMDID. - * AR6003 has 32 bit mask for each modes. - * First 12 bits for legacy rates, 13 to 20 - * bits for HT 20 rates and 21 to 28 bits for - * HT 40 rates - */ -enum wmi_mode_phy { - WMI_RATES_MODE_11A = 0, - WMI_RATES_MODE_11G, - WMI_RATES_MODE_11B, - WMI_RATES_MODE_11GONLY, - WMI_RATES_MODE_11A_HT20, - WMI_RATES_MODE_11G_HT20, - WMI_RATES_MODE_11A_HT40, - WMI_RATES_MODE_11G_HT40, - WMI_RATES_MODE_MAX -}; - -/* WMI_SET_TX_SELECT_RATES_CMDID */ -struct wmi_set_tx_select_rates32_cmd { - __le32 ratemask[WMI_RATES_MODE_MAX]; -} __packed; - -/* WMI_SET_TX_SELECT_RATES_CMDID */ -struct wmi_set_tx_select_rates64_cmd { - __le64 ratemask[WMI_RATES_MODE_MAX]; -} __packed; - /* WMI_SET_DISC_TIMEOUT_CMDID */ struct wmi_disc_timeout_cmd { /* seconds */ @@ -1617,10 +1572,6 @@ struct roam_ctrl_cmd { u8 roam_ctrl; } __packed; -struct set_dtim_cmd { - __le32 dtim_period; -} __packed; - /* BSS INFO HDR version 2.0 */ struct wmi_bss_info_hdr2 { __le16 ch; /* frequency in MHz */ @@ -2581,8 +2532,6 @@ int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, u8 if_idx, __be32 ips0, __be32 ips1); int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx, enum ath6kl_host_mode host_mode); -int ath6kl_wmi_set_bitrate_mask(struct wmi *wmi, u8 if_idx, - const struct cfg80211_bitrate_mask *mask); int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx, enum ath6kl_wow_mode wow_mode, u32 filter, u16 host_req_delay); @@ -2593,14 +2542,11 @@ int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, int ath6kl_wmi_del_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, u16 list_id, u16 filter_id); 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); int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode); 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); - /* AP mode uAPSD */ int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable); diff --git a/trunk/drivers/net/wireless/ath/ath9k/ani.c b/trunk/drivers/net/wireless/ath/ath9k/ani.c index ff007f500feb..b4c77f9d7470 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ani.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ani.c @@ -104,6 +104,11 @@ static const struct ani_cck_level_entry cck_level_table[] = { #define ATH9K_ANI_CCK_DEF_LEVEL \ 2 /* default level - matches the INI settings */ +static bool use_new_ani(struct ath_hw *ah) +{ + return AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani; +} + static void ath9k_hw_update_mibstats(struct ath_hw *ah, struct ath9k_mib_stats *stats) { @@ -117,6 +122,8 @@ static void ath9k_hw_update_mibstats(struct ath_hw *ah, static void ath9k_ani_restart(struct ath_hw *ah) { struct ar5416AniState *aniState; + struct ath_common *common = ath9k_hw_common(ah); + u32 ofdm_base = 0, cck_base = 0; if (!DO_ANI(ah)) return; @@ -124,10 +131,18 @@ static void ath9k_ani_restart(struct ath_hw *ah) aniState = &ah->curchan->ani; aniState->listenTime = 0; + if (!use_new_ani(ah)) { + ofdm_base = AR_PHY_COUNTMAX - ah->config.ofdm_trig_high; + cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high; + } + + ath_dbg(common, ANI, "Writing ofdmbase=%u cckbase=%u\n", + ofdm_base, cck_base); + ENABLE_REGWRITE_BUFFER(ah); - REG_WRITE(ah, AR_PHY_ERR_1, 0); - REG_WRITE(ah, AR_PHY_ERR_2, 0); + REG_WRITE(ah, AR_PHY_ERR_1, ofdm_base); + REG_WRITE(ah, AR_PHY_ERR_2, cck_base); REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); @@ -139,23 +154,129 @@ static void ath9k_ani_restart(struct ath_hw *ah) aniState->cckPhyErrCount = 0; } +static void ath9k_hw_ani_ofdm_err_trigger_old(struct ath_hw *ah) +{ + struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; + struct ar5416AniState *aniState; + int32_t rssi; + + aniState = &ah->curchan->ani; + + if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) { + if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, + aniState->noiseImmunityLevel + 1)) { + return; + } + } + + if (aniState->spurImmunityLevel < HAL_SPUR_IMMUNE_MAX) { + if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, + aniState->spurImmunityLevel + 1)) { + return; + } + } + + if (ah->opmode == NL80211_IFTYPE_AP) { + if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) { + ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, + aniState->firstepLevel + 1); + } + return; + } + rssi = BEACON_RSSI(ah); + if (rssi > aniState->rssiThrHigh) { + if (!aniState->ofdmWeakSigDetectOff) { + if (ath9k_hw_ani_control(ah, + ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, + false)) { + ath9k_hw_ani_control(ah, + ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0); + return; + } + } + if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) { + ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, + aniState->firstepLevel + 1); + return; + } + } else if (rssi > aniState->rssiThrLow) { + if (aniState->ofdmWeakSigDetectOff) + ath9k_hw_ani_control(ah, + ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, + true); + if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) + ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, + aniState->firstepLevel + 1); + return; + } else { + if ((conf->channel->band == IEEE80211_BAND_2GHZ) && + !conf_is_ht(conf)) { + if (!aniState->ofdmWeakSigDetectOff) + ath9k_hw_ani_control(ah, + ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, + false); + if (aniState->firstepLevel > 0) + ath9k_hw_ani_control(ah, + ATH9K_ANI_FIRSTEP_LEVEL, 0); + return; + } + } +} + +static void ath9k_hw_ani_cck_err_trigger_old(struct ath_hw *ah) +{ + struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; + struct ar5416AniState *aniState; + int32_t rssi; + + aniState = &ah->curchan->ani; + if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) { + if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, + aniState->noiseImmunityLevel + 1)) { + return; + } + } + if (ah->opmode == NL80211_IFTYPE_AP) { + if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) { + ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, + aniState->firstepLevel + 1); + } + return; + } + rssi = BEACON_RSSI(ah); + if (rssi > aniState->rssiThrLow) { + if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) + ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, + aniState->firstepLevel + 1); + } else { + if ((conf->channel->band == IEEE80211_BAND_2GHZ) && + !conf_is_ht(conf)) { + if (aniState->firstepLevel > 0) + ath9k_hw_ani_control(ah, + ATH9K_ANI_FIRSTEP_LEVEL, 0); + } + } +} + /* Adjust the OFDM Noise Immunity Level */ -static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel, - bool scan) +static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel) { struct ar5416AniState *aniState = &ah->curchan->ani; struct ath_common *common = ath9k_hw_common(ah); const struct ani_ofdm_level_entry *entry_ofdm; const struct ani_cck_level_entry *entry_cck; - bool weak_sig; + + aniState->noiseFloor = BEACON_RSSI(ah); ath_dbg(common, ANI, "**** ofdmlevel %d=>%d, rssi=%d[lo=%d hi=%d]\n", aniState->ofdmNoiseImmunityLevel, - immunityLevel, BEACON_RSSI(ah), + immunityLevel, aniState->noiseFloor, aniState->rssiThrLow, aniState->rssiThrHigh); - if (!scan) - aniState->ofdmNoiseImmunityLevel = immunityLevel; + if (aniState->update_ani) + aniState->ofdmNoiseImmunityLevel = + (immunityLevel > ATH9K_ANI_OFDM_DEF_LEVEL) ? + immunityLevel : ATH9K_ANI_OFDM_DEF_LEVEL; entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel]; entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel]; @@ -171,22 +292,12 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel, ATH9K_ANI_FIRSTEP_LEVEL, entry_ofdm->fir_step_level); - weak_sig = entry_ofdm->ofdm_weak_signal_on; - if (ah->opmode == NL80211_IFTYPE_STATION && - BEACON_RSSI(ah) <= aniState->rssiThrHigh) - weak_sig = true; - - if (aniState->ofdmWeakSigDetect != weak_sig) + if ((aniState->noiseFloor >= aniState->rssiThrHigh) && + (!aniState->ofdmWeakSigDetectOff != + entry_ofdm->ofdm_weak_signal_on)) { ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, entry_ofdm->ofdm_weak_signal_on); - - if (aniState->ofdmNoiseImmunityLevel >= ATH9K_ANI_OFDM_DEF_LEVEL) { - ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH; - ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI; - } else { - ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI; - ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW; } } @@ -197,35 +308,43 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah) if (!DO_ANI(ah)) return; + if (!use_new_ani(ah)) { + ath9k_hw_ani_ofdm_err_trigger_old(ah); + return; + } + aniState = &ah->curchan->ani; if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL) - ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1, false); + ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1); } /* * Set the ANI settings to match an CCK level. */ -static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel, - bool scan) +static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel) { struct ar5416AniState *aniState = &ah->curchan->ani; struct ath_common *common = ath9k_hw_common(ah); const struct ani_ofdm_level_entry *entry_ofdm; const struct ani_cck_level_entry *entry_cck; + aniState->noiseFloor = BEACON_RSSI(ah); ath_dbg(common, ANI, "**** ccklevel %d=>%d, rssi=%d[lo=%d hi=%d]\n", aniState->cckNoiseImmunityLevel, immunityLevel, - BEACON_RSSI(ah), aniState->rssiThrLow, + aniState->noiseFloor, aniState->rssiThrLow, aniState->rssiThrHigh); - if (ah->opmode == NL80211_IFTYPE_STATION && - BEACON_RSSI(ah) <= aniState->rssiThrLow && + if ((ah->opmode == NL80211_IFTYPE_STATION || + ah->opmode == NL80211_IFTYPE_ADHOC) && + aniState->noiseFloor <= aniState->rssiThrLow && immunityLevel > ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI) immunityLevel = ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI; - if (!scan) - aniState->cckNoiseImmunityLevel = immunityLevel; + if (aniState->update_ani) + aniState->cckNoiseImmunityLevel = + (immunityLevel > ATH9K_ANI_CCK_DEF_LEVEL) ? + immunityLevel : ATH9K_ANI_CCK_DEF_LEVEL; entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel]; entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel]; @@ -240,7 +359,7 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel, if (!AR_SREV_9300_20_OR_LATER(ah) || AR_SREV_9485(ah)) return; - if (aniState->mrcCCK != entry_cck->mrc_cck_on) + if (aniState->mrcCCKOff == entry_cck->mrc_cck_on) ath9k_hw_ani_control(ah, ATH9K_ANI_MRC_CCK, entry_cck->mrc_cck_on); @@ -253,11 +372,68 @@ static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah) if (!DO_ANI(ah)) return; + if (!use_new_ani(ah)) { + ath9k_hw_ani_cck_err_trigger_old(ah); + return; + } + aniState = &ah->curchan->ani; if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL) - ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1, - false); + ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1); +} + +static void ath9k_hw_ani_lower_immunity_old(struct ath_hw *ah) +{ + struct ar5416AniState *aniState; + int32_t rssi; + + aniState = &ah->curchan->ani; + + if (ah->opmode == NL80211_IFTYPE_AP) { + if (aniState->firstepLevel > 0) { + if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, + aniState->firstepLevel - 1)) + return; + } + } else { + rssi = BEACON_RSSI(ah); + if (rssi > aniState->rssiThrHigh) { + /* XXX: Handle me */ + } else if (rssi > aniState->rssiThrLow) { + if (aniState->ofdmWeakSigDetectOff) { + if (ath9k_hw_ani_control(ah, + ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, + true)) + return; + } + if (aniState->firstepLevel > 0) { + if (ath9k_hw_ani_control(ah, + ATH9K_ANI_FIRSTEP_LEVEL, + aniState->firstepLevel - 1)) + return; + } + } else { + if (aniState->firstepLevel > 0) { + if (ath9k_hw_ani_control(ah, + ATH9K_ANI_FIRSTEP_LEVEL, + aniState->firstepLevel - 1)) + return; + } + } + } + + if (aniState->spurImmunityLevel > 0) { + if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, + aniState->spurImmunityLevel - 1)) + return; + } + + if (aniState->noiseImmunityLevel > 0) { + ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, + aniState->noiseImmunityLevel - 1); + return; + } } /* @@ -270,18 +446,87 @@ static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah) aniState = &ah->curchan->ani; + if (!use_new_ani(ah)) { + ath9k_hw_ani_lower_immunity_old(ah); + return; + } + /* lower OFDM noise immunity */ if (aniState->ofdmNoiseImmunityLevel > 0 && (aniState->ofdmsTurn || aniState->cckNoiseImmunityLevel == 0)) { - ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel - 1, - false); + ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel - 1); return; } /* lower CCK noise immunity */ if (aniState->cckNoiseImmunityLevel > 0) - ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel - 1, - false); + ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel - 1); +} + +static void ath9k_ani_reset_old(struct ath_hw *ah, bool is_scanning) +{ + struct ar5416AniState *aniState; + struct ath9k_channel *chan = ah->curchan; + struct ath_common *common = ath9k_hw_common(ah); + + if (!DO_ANI(ah)) + return; + + aniState = &ah->curchan->ani; + + if (ah->opmode != NL80211_IFTYPE_STATION + && ah->opmode != NL80211_IFTYPE_ADHOC) { + ath_dbg(common, ANI, "Reset ANI state opmode %u\n", ah->opmode); + ah->stats.ast_ani_reset++; + + if (ah->opmode == NL80211_IFTYPE_AP) { + /* + * ath9k_hw_ani_control() will only process items set on + * ah->ani_function + */ + if (IS_CHAN_2GHZ(chan)) + ah->ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL | + ATH9K_ANI_FIRSTEP_LEVEL); + else + ah->ani_function = 0; + } + + ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0); + ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0); + ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0); + ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, + !ATH9K_ANI_USE_OFDM_WEAK_SIG); + ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR, + ATH9K_ANI_CCK_WEAK_SIG_THR); + + ath9k_ani_restart(ah); + return; + } + + if (aniState->noiseImmunityLevel != 0) + ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, + aniState->noiseImmunityLevel); + if (aniState->spurImmunityLevel != 0) + ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, + aniState->spurImmunityLevel); + if (aniState->ofdmWeakSigDetectOff) + ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION, + !aniState->ofdmWeakSigDetectOff); + if (aniState->cckWeakSigThreshold) + ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR, + aniState->cckWeakSigThreshold); + if (aniState->firstepLevel != 0) + ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, + aniState->firstepLevel); + + ath9k_ani_restart(ah); + + ENABLE_REGWRITE_BUFFER(ah); + + REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); + REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); + + REGWRITE_BUFFER_FLUSH(ah); } /* @@ -294,11 +539,13 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning) struct ar5416AniState *aniState = &ah->curchan->ani; struct ath9k_channel *chan = ah->curchan; struct ath_common *common = ath9k_hw_common(ah); - int ofdm_nil, cck_nil; if (!DO_ANI(ah)) return; + if (!use_new_ani(ah)) + return ath9k_ani_reset_old(ah, is_scanning); + BUG_ON(aniState == NULL); ah->stats.ast_ani_reset++; @@ -316,11 +563,6 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning) /* always allow mode (on/off) to be controlled */ ah->ani_function |= ATH9K_ANI_MODE; - ofdm_nil = max_t(int, ATH9K_ANI_OFDM_DEF_LEVEL, - aniState->ofdmNoiseImmunityLevel); - cck_nil = max_t(int, ATH9K_ANI_CCK_DEF_LEVEL, - aniState->cckNoiseImmunityLevel); - if (is_scanning || (ah->opmode != NL80211_IFTYPE_STATION && ah->opmode != NL80211_IFTYPE_ADHOC)) { @@ -343,8 +585,9 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning) aniState->ofdmNoiseImmunityLevel, aniState->cckNoiseImmunityLevel); - ofdm_nil = ATH9K_ANI_OFDM_DEF_LEVEL; - cck_nil = ATH9K_ANI_CCK_DEF_LEVEL; + aniState->update_ani = false; + ath9k_hw_set_ofdm_nil(ah, ATH9K_ANI_OFDM_DEF_LEVEL); + ath9k_hw_set_cck_nil(ah, ATH9K_ANI_CCK_DEF_LEVEL); } } else { /* @@ -358,9 +601,13 @@ void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning) is_scanning, aniState->ofdmNoiseImmunityLevel, aniState->cckNoiseImmunityLevel); + + aniState->update_ani = true; + ath9k_hw_set_ofdm_nil(ah, + aniState->ofdmNoiseImmunityLevel); + ath9k_hw_set_cck_nil(ah, + aniState->cckNoiseImmunityLevel); } - ath9k_hw_set_ofdm_nil(ah, ofdm_nil, is_scanning); - ath9k_hw_set_cck_nil(ah, cck_nil, is_scanning); /* * enable phy counters if hw supports or if not, enable phy @@ -380,6 +627,9 @@ static bool ath9k_hw_ani_read_counters(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); struct ar5416AniState *aniState = &ah->curchan->ani; + u32 ofdm_base = 0; + u32 cck_base = 0; + u32 ofdmPhyErrCnt, cckPhyErrCnt; u32 phyCnt1, phyCnt2; int32_t listenTime; @@ -392,6 +642,11 @@ static bool ath9k_hw_ani_read_counters(struct ath_hw *ah) return false; } + if (!use_new_ani(ah)) { + ofdm_base = AR_PHY_COUNTMAX - ah->config.ofdm_trig_high; + cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high; + } + aniState->listenTime += listenTime; ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); @@ -399,12 +654,35 @@ static bool ath9k_hw_ani_read_counters(struct ath_hw *ah) phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); - ah->stats.ast_ani_ofdmerrs += phyCnt1 - aniState->ofdmPhyErrCount; - aniState->ofdmPhyErrCount = phyCnt1; + if (!use_new_ani(ah) && (phyCnt1 < ofdm_base || phyCnt2 < cck_base)) { + if (phyCnt1 < ofdm_base) { + ath_dbg(common, ANI, + "phyCnt1 0x%x, resetting counter value to 0x%x\n", + phyCnt1, ofdm_base); + REG_WRITE(ah, AR_PHY_ERR_1, ofdm_base); + REG_WRITE(ah, AR_PHY_ERR_MASK_1, + AR_PHY_ERR_OFDM_TIMING); + } + if (phyCnt2 < cck_base) { + ath_dbg(common, ANI, + "phyCnt2 0x%x, resetting counter value to 0x%x\n", + phyCnt2, cck_base); + REG_WRITE(ah, AR_PHY_ERR_2, cck_base); + REG_WRITE(ah, AR_PHY_ERR_MASK_2, + AR_PHY_ERR_CCK_TIMING); + } + return false; + } - ah->stats.ast_ani_cckerrs += phyCnt2 - aniState->cckPhyErrCount; - aniState->cckPhyErrCount = phyCnt2; + ofdmPhyErrCnt = phyCnt1 - ofdm_base; + ah->stats.ast_ani_ofdmerrs += + ofdmPhyErrCnt - aniState->ofdmPhyErrCount; + aniState->ofdmPhyErrCount = ofdmPhyErrCnt; + cckPhyErrCnt = phyCnt2 - cck_base; + ah->stats.ast_ani_cckerrs += + cckPhyErrCnt - aniState->cckPhyErrCount; + aniState->cckPhyErrCount = cckPhyErrCnt; return true; } @@ -438,10 +716,21 @@ void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan) if (aniState->listenTime > ah->aniperiod) { if (cckPhyErrRate < ah->config.cck_trig_low && - ofdmPhyErrRate < ah->config.ofdm_trig_low) { + ((ofdmPhyErrRate < ah->config.ofdm_trig_low && + aniState->ofdmNoiseImmunityLevel < + ATH9K_ANI_OFDM_DEF_LEVEL) || + (ofdmPhyErrRate < ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI && + aniState->ofdmNoiseImmunityLevel >= + ATH9K_ANI_OFDM_DEF_LEVEL))) { ath9k_hw_ani_lower_immunity(ah); aniState->ofdmsTurn = !aniState->ofdmsTurn; - } else if (ofdmPhyErrRate > ah->config.ofdm_trig_high) { + } else if ((ofdmPhyErrRate > ah->config.ofdm_trig_high && + aniState->ofdmNoiseImmunityLevel >= + ATH9K_ANI_OFDM_DEF_LEVEL) || + (ofdmPhyErrRate > + ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI && + aniState->ofdmNoiseImmunityLevel < + ATH9K_ANI_OFDM_DEF_LEVEL)) { ath9k_hw_ani_ofdm_err_trigger(ah); aniState->ofdmsTurn = false; } else if (cckPhyErrRate > ah->config.cck_trig_high) { @@ -489,6 +778,49 @@ void ath9k_hw_disable_mib_counters(struct ath_hw *ah) } EXPORT_SYMBOL(ath9k_hw_disable_mib_counters); +/* + * Process a MIB interrupt. We may potentially be invoked because + * any of the MIB counters overflow/trigger so don't assume we're + * here because a PHY error counter triggered. + */ +void ath9k_hw_proc_mib_event(struct ath_hw *ah) +{ + u32 phyCnt1, phyCnt2; + + /* Reset these counters regardless */ + REG_WRITE(ah, AR_FILT_OFDM, 0); + REG_WRITE(ah, AR_FILT_CCK, 0); + if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING)) + REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR); + + /* Clear the mib counters and save them in the stats */ + ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); + + if (!DO_ANI(ah)) { + /* + * We must always clear the interrupt cause by + * resetting the phy error regs. + */ + REG_WRITE(ah, AR_PHY_ERR_1, 0); + REG_WRITE(ah, AR_PHY_ERR_2, 0); + return; + } + + /* NB: these are not reset-on-read */ + phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); + phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); + if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) || + ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) { + + if (!use_new_ani(ah)) + ath9k_hw_ani_read_counters(ah); + + /* NB: always restart to insure the h/w counters are reset */ + ath9k_ani_restart(ah); + } +} +EXPORT_SYMBOL(ath9k_hw_proc_mib_event); + void ath9k_hw_ani_setup(struct ath_hw *ah) { int i; @@ -513,37 +845,66 @@ void ath9k_hw_ani_init(struct ath_hw *ah) ath_dbg(common, ANI, "Initialize ANI\n"); - ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH; - ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW; + if (use_new_ani(ah)) { + ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_NEW; + ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_NEW; - ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH; - ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW; + ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_NEW; + ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_NEW; + } else { + ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_OLD; + ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_OLD; + + ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_OLD; + ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_OLD; + } for (i = 0; i < ARRAY_SIZE(ah->channels); i++) { struct ath9k_channel *chan = &ah->channels[i]; struct ar5416AniState *ani = &chan->ani; - ani->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL; - - ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL; + if (use_new_ani(ah)) { + ani->spurImmunityLevel = + ATH9K_ANI_SPUR_IMMUNE_LVL_NEW; - ani->mrcCCK = AR_SREV_9300_20_OR_LATER(ah) ? true : false; + ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW; - ani->ofdmsTurn = true; + if (AR_SREV_9300_20_OR_LATER(ah)) + ani->mrcCCKOff = + !ATH9K_ANI_ENABLE_MRC_CCK; + else + ani->mrcCCKOff = true; + + ani->ofdmsTurn = true; + } else { + ani->spurImmunityLevel = + ATH9K_ANI_SPUR_IMMUNE_LVL_OLD; + ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_OLD; + + ani->cckWeakSigThreshold = + ATH9K_ANI_CCK_WEAK_SIG_THR; + } ani->rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH; ani->rssiThrLow = ATH9K_ANI_RSSI_THR_LOW; - ani->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG; + ani->ofdmWeakSigDetectOff = + !ATH9K_ANI_USE_OFDM_WEAK_SIG; ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL; ani->ofdmNoiseImmunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL; + ani->update_ani = false; } /* * since we expect some ongoing maintenance on the tables, let's sanity * check here default level should not modify INI setting. */ - ah->aniperiod = ATH9K_ANI_PERIOD; - ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL; + if (use_new_ani(ah)) { + ah->aniperiod = ATH9K_ANI_PERIOD_NEW; + ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_NEW; + } else { + ah->aniperiod = ATH9K_ANI_PERIOD_OLD; + ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_OLD; + } if (ah->config.enable_ani) ah->proc_phyerr |= HAL_PROCESS_ANI; diff --git a/trunk/drivers/net/wireless/ath/ath9k/ani.h b/trunk/drivers/net/wireless/ath/ath9k/ani.h index 1485bf5e3518..72e2b874e179 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ani.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ani.h @@ -24,34 +24,42 @@ #define BEACON_RSSI(ahp) (ahp->stats.avgbrssi) /* units are errors per second */ -#define ATH9K_ANI_OFDM_TRIG_HIGH 3500 +#define ATH9K_ANI_OFDM_TRIG_HIGH_OLD 500 +#define ATH9K_ANI_OFDM_TRIG_HIGH_NEW 3500 #define ATH9K_ANI_OFDM_TRIG_HIGH_BELOW_INI 1000 /* units are errors per second */ -#define ATH9K_ANI_OFDM_TRIG_LOW 400 +#define ATH9K_ANI_OFDM_TRIG_LOW_OLD 200 +#define ATH9K_ANI_OFDM_TRIG_LOW_NEW 400 #define ATH9K_ANI_OFDM_TRIG_LOW_ABOVE_INI 900 /* units are errors per second */ -#define ATH9K_ANI_CCK_TRIG_HIGH 600 +#define ATH9K_ANI_CCK_TRIG_HIGH_OLD 200 +#define ATH9K_ANI_CCK_TRIG_HIGH_NEW 600 /* units are errors per second */ -#define ATH9K_ANI_CCK_TRIG_LOW 300 +#define ATH9K_ANI_CCK_TRIG_LOW_OLD 100 +#define ATH9K_ANI_CCK_TRIG_LOW_NEW 300 #define ATH9K_ANI_NOISE_IMMUNE_LVL 4 #define ATH9K_ANI_USE_OFDM_WEAK_SIG true #define ATH9K_ANI_CCK_WEAK_SIG_THR false -#define ATH9K_ANI_SPUR_IMMUNE_LVL 3 +#define ATH9K_ANI_SPUR_IMMUNE_LVL_OLD 7 +#define ATH9K_ANI_SPUR_IMMUNE_LVL_NEW 3 -#define ATH9K_ANI_FIRSTEP_LVL 2 +#define ATH9K_ANI_FIRSTEP_LVL_OLD 0 +#define ATH9K_ANI_FIRSTEP_LVL_NEW 2 #define ATH9K_ANI_RSSI_THR_HIGH 40 #define ATH9K_ANI_RSSI_THR_LOW 7 -#define ATH9K_ANI_PERIOD 300 +#define ATH9K_ANI_PERIOD_OLD 100 +#define ATH9K_ANI_PERIOD_NEW 300 /* in ms */ -#define ATH9K_ANI_POLLINTERVAL 1000 +#define ATH9K_ANI_POLLINTERVAL_OLD 100 +#define ATH9K_ANI_POLLINTERVAL_NEW 1000 #define HAL_NOISE_IMMUNE_MAX 4 #define HAL_SPUR_IMMUNE_MAX 7 @@ -62,6 +70,8 @@ #define ATH9K_SIG_SPUR_IMM_SETTING_MIN 0 #define ATH9K_SIG_SPUR_IMM_SETTING_MAX 22 +#define ATH9K_ANI_ENABLE_MRC_CCK true + /* values here are relative to the INI */ enum ath9k_ani_cmd { @@ -109,14 +119,16 @@ struct ar5416AniState { u8 ofdmNoiseImmunityLevel; u8 cckNoiseImmunityLevel; bool ofdmsTurn; - u8 mrcCCK; + u8 mrcCCKOff; u8 spurImmunityLevel; u8 firstepLevel; - u8 ofdmWeakSigDetect; + u8 ofdmWeakSigDetectOff; u8 cckWeakSigThreshold; + bool update_ani; u32 listenTime; int32_t rssiThrLow; int32_t rssiThrHigh; + u32 noiseFloor; u32 ofdmPhyErrCount; u32 cckPhyErrCount; int16_t pktRssi[2]; diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/trunk/drivers/net/wireless/ath/ath9k/ar5008_phy.c index 874186bfda41..c7492c6a2519 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar5008_phy.c @@ -995,6 +995,141 @@ static u32 ar5008_hw_compute_pll_control(struct ath_hw *ah, return pll; } +static bool ar5008_hw_ani_control_old(struct ath_hw *ah, + enum ath9k_ani_cmd cmd, + int param) +{ + struct ar5416AniState *aniState = &ah->curchan->ani; + struct ath_common *common = ath9k_hw_common(ah); + + switch (cmd & ah->ani_function) { + case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{ + u32 level = param; + + if (level >= ARRAY_SIZE(ah->totalSizeDesired)) { + ath_dbg(common, ANI, "level out of range (%u > %zu)\n", + level, ARRAY_SIZE(ah->totalSizeDesired)); + return false; + } + + REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, + AR_PHY_DESIRED_SZ_TOT_DES, + ah->totalSizeDesired[level]); + REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1, + AR_PHY_AGC_CTL1_COARSE_LOW, + ah->coarse_low[level]); + REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1, + AR_PHY_AGC_CTL1_COARSE_HIGH, + ah->coarse_high[level]); + REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, + AR_PHY_FIND_SIG_FIRPWR, + ah->firpwr[level]); + + if (level > aniState->noiseImmunityLevel) + ah->stats.ast_ani_niup++; + else if (level < aniState->noiseImmunityLevel) + ah->stats.ast_ani_nidown++; + aniState->noiseImmunityLevel = level; + break; + } + case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{ + u32 on = param ? 1 : 0; + + if (on) + REG_SET_BIT(ah, AR_PHY_SFCORR_LOW, + AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); + else + REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW, + AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); + + if (!on != aniState->ofdmWeakSigDetectOff) { + if (on) + ah->stats.ast_ani_ofdmon++; + else + ah->stats.ast_ani_ofdmoff++; + aniState->ofdmWeakSigDetectOff = !on; + } + break; + } + case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{ + static const int weakSigThrCck[] = { 8, 6 }; + u32 high = param ? 1 : 0; + + REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT, + AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK, + weakSigThrCck[high]); + if (high != aniState->cckWeakSigThreshold) { + if (high) + ah->stats.ast_ani_cckhigh++; + else + ah->stats.ast_ani_ccklow++; + aniState->cckWeakSigThreshold = high; + } + break; + } + case ATH9K_ANI_FIRSTEP_LEVEL:{ + static const int firstep[] = { 0, 4, 8 }; + u32 level = param; + + if (level >= ARRAY_SIZE(firstep)) { + ath_dbg(common, ANI, "level out of range (%u > %zu)\n", + level, ARRAY_SIZE(firstep)); + return false; + } + REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, + AR_PHY_FIND_SIG_FIRSTEP, + firstep[level]); + if (level > aniState->firstepLevel) + ah->stats.ast_ani_stepup++; + else if (level < aniState->firstepLevel) + ah->stats.ast_ani_stepdown++; + aniState->firstepLevel = level; + break; + } + case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{ + static const int cycpwrThr1[] = { 2, 4, 6, 8, 10, 12, 14, 16 }; + u32 level = param; + + if (level >= ARRAY_SIZE(cycpwrThr1)) { + ath_dbg(common, ANI, "level out of range (%u > %zu)\n", + level, ARRAY_SIZE(cycpwrThr1)); + return false; + } + REG_RMW_FIELD(ah, AR_PHY_TIMING5, + AR_PHY_TIMING5_CYCPWR_THR1, + cycpwrThr1[level]); + if (level > aniState->spurImmunityLevel) + ah->stats.ast_ani_spurup++; + else if (level < aniState->spurImmunityLevel) + ah->stats.ast_ani_spurdown++; + aniState->spurImmunityLevel = level; + break; + } + case ATH9K_ANI_PRESENT: + break; + default: + ath_dbg(common, ANI, "invalid cmd %u\n", cmd); + return false; + } + + ath_dbg(common, ANI, "ANI parameters:\n"); + ath_dbg(common, ANI, + "noiseImmunityLevel=%d, spurImmunityLevel=%d, ofdmWeakSigDetectOff=%d\n", + aniState->noiseImmunityLevel, + aniState->spurImmunityLevel, + !aniState->ofdmWeakSigDetectOff); + ath_dbg(common, ANI, + "cckWeakSigThreshold=%d, firstepLevel=%d, listenTime=%d\n", + aniState->cckWeakSigThreshold, + aniState->firstepLevel, + aniState->listenTime); + ath_dbg(common, ANI, "ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n", + aniState->ofdmPhyErrCount, + aniState->cckPhyErrCount); + + return true; +} + static bool ar5008_hw_ani_control_new(struct ath_hw *ah, enum ath9k_ani_cmd cmd, int param) @@ -1071,18 +1206,18 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW, AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); - if (on != aniState->ofdmWeakSigDetect) { + if (!on != aniState->ofdmWeakSigDetectOff) { ath_dbg(common, ANI, "** ch %d: ofdm weak signal: %s=>%s\n", chan->channel, - aniState->ofdmWeakSigDetect ? + !aniState->ofdmWeakSigDetectOff ? "on" : "off", on ? "on" : "off"); if (on) ah->stats.ast_ani_ofdmon++; else ah->stats.ast_ani_ofdmoff++; - aniState->ofdmWeakSigDetect = on; + aniState->ofdmWeakSigDetectOff = !on; } break; } @@ -1101,7 +1236,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, * from INI file & cap value */ value = firstep_table[level] - - firstep_table[ATH9K_ANI_FIRSTEP_LVL] + + firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] + aniState->iniDef.firstep; if (value < ATH9K_SIG_FIRSTEP_SETTING_MIN) value = ATH9K_SIG_FIRSTEP_SETTING_MIN; @@ -1116,7 +1251,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, * from INI file & cap value */ value2 = firstep_table[level] - - firstep_table[ATH9K_ANI_FIRSTEP_LVL] + + firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] + aniState->iniDef.firstepLow; if (value2 < ATH9K_SIG_FIRSTEP_SETTING_MIN) value2 = ATH9K_SIG_FIRSTEP_SETTING_MIN; @@ -1132,7 +1267,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, chan->channel, aniState->firstepLevel, level, - ATH9K_ANI_FIRSTEP_LVL, + ATH9K_ANI_FIRSTEP_LVL_NEW, value, aniState->iniDef.firstep); ath_dbg(common, ANI, @@ -1140,7 +1275,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, chan->channel, aniState->firstepLevel, level, - ATH9K_ANI_FIRSTEP_LVL, + ATH9K_ANI_FIRSTEP_LVL_NEW, value2, aniState->iniDef.firstepLow); if (level > aniState->firstepLevel) @@ -1165,7 +1300,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, * from INI file & cap value */ value = cycpwrThr1_table[level] - - cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL] + + cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] + aniState->iniDef.cycpwrThr1; if (value < ATH9K_SIG_SPUR_IMM_SETTING_MIN) value = ATH9K_SIG_SPUR_IMM_SETTING_MIN; @@ -1181,7 +1316,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, * from INI file & cap value */ value2 = cycpwrThr1_table[level] - - cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL] + + cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] + aniState->iniDef.cycpwrThr1Ext; if (value2 < ATH9K_SIG_SPUR_IMM_SETTING_MIN) value2 = ATH9K_SIG_SPUR_IMM_SETTING_MIN; @@ -1196,7 +1331,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, chan->channel, aniState->spurImmunityLevel, level, - ATH9K_ANI_SPUR_IMMUNE_LVL, + ATH9K_ANI_SPUR_IMMUNE_LVL_NEW, value, aniState->iniDef.cycpwrThr1); ath_dbg(common, ANI, @@ -1204,7 +1339,7 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, chan->channel, aniState->spurImmunityLevel, level, - ATH9K_ANI_SPUR_IMMUNE_LVL, + ATH9K_ANI_SPUR_IMMUNE_LVL_NEW, value2, aniState->iniDef.cycpwrThr1Ext); if (level > aniState->spurImmunityLevel) @@ -1232,9 +1367,9 @@ static bool ar5008_hw_ani_control_new(struct ath_hw *ah, ath_dbg(common, ANI, "ANI parameters: SI=%d, ofdmWS=%s FS=%d MRCcck=%s listenTime=%d ofdmErrs=%d cckErrs=%d\n", aniState->spurImmunityLevel, - aniState->ofdmWeakSigDetect ? "on" : "off", + !aniState->ofdmWeakSigDetectOff ? "on" : "off", aniState->firstepLevel, - aniState->mrcCCK ? "on" : "off", + !aniState->mrcCCKOff ? "on" : "off", aniState->listenTime, aniState->ofdmPhyErrCount, aniState->cckPhyErrCount); @@ -1319,10 +1454,10 @@ static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah) AR_PHY_EXT_TIMING5_CYCPWR_THR1); /* these levels just got reset to defaults by the INI */ - aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL; - aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL; - aniState->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG; - aniState->mrcCCK = false; /* not available on pre AR9003 */ + aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL_NEW; + aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW; + aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG; + aniState->mrcCCKOff = true; /* not available on pre AR9003 */ } static void ar5008_hw_set_nf_limits(struct ath_hw *ah) @@ -1410,8 +1545,11 @@ void ar5008_hw_attach_phy_ops(struct ath_hw *ah) priv_ops->do_getnf = ar5008_hw_do_getnf; priv_ops->set_radar_params = ar5008_hw_set_radar_params; - priv_ops->ani_control = ar5008_hw_ani_control_new; - priv_ops->ani_cache_ini_regs = ar5008_hw_ani_cache_ini_regs; + if (modparam_force_new_ani) { + priv_ops->ani_control = ar5008_hw_ani_control_new; + priv_ops->ani_cache_ini_regs = ar5008_hw_ani_cache_ini_regs; + } else + priv_ops->ani_control = ar5008_hw_ani_control_old; if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) priv_ops->compute_pll_control = ar9160_hw_compute_pll_control; diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/trunk/drivers/net/wireless/ath/ath9k/ar9002_hw.c index edf21ea4fe93..d9a69fc470cd 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -21,6 +21,10 @@ #include "ar9002_initvals.h" #include "ar9002_phy.h" +int modparam_force_new_ani; +module_param_named(force_new_ani, modparam_force_new_ani, int, 0444); +MODULE_PARM_DESC(force_new_ani, "Force new ANI for AR5008, AR9001, AR9002"); + /* General hardware code for the A5008/AR9001/AR9002 hadware families */ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/trunk/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h index 89bf94d4d8a1..952cb2b4656b 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h @@ -1,6 +1,5 @@ /* * Copyright (c) 2010-2011 Atheros Communications Inc. - * Copyright (c) 2011-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 diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 78816b8b2173..d9e0824af093 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -181,14 +181,11 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) u32 mask2 = 0; struct ath9k_hw_capabilities *pCap = &ah->caps; struct ath_common *common = ath9k_hw_common(ah); - u32 sync_cause = 0, async_cause, async_mask = AR_INTR_MAC_IRQ; - - if (ath9k_hw_mci_is_enabled(ah)) - async_mask |= AR_INTR_ASYNC_MASK_MCI; + u32 sync_cause = 0, async_cause; async_cause = REG_READ(ah, AR_INTR_ASYNC_CAUSE); - if (async_cause & async_mask) { + if (async_cause & (AR_INTR_MAC_IRQ | AR_INTR_ASYNC_MASK_MCI)) { if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M) == AR_RTC_STATUS_ON) isr = REG_READ(ah, AR_ISR); diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_mci.c index 61558375bfbf..b1ced2a76da3 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_mci.c @@ -321,7 +321,7 @@ void ar9003_mci_set_full_sleep(struct ath_hw *ah) { struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; - if (ar9003_mci_state(ah, MCI_STATE_ENABLE) && + if (ar9003_mci_state(ah, MCI_STATE_ENABLE, NULL) && (mci->bt_state != MCI_BT_SLEEP) && !mci->halted_bt_gpm) { ar9003_mci_send_coex_halt_bt_gpm(ah, true, true); @@ -484,7 +484,7 @@ static void ar9003_mci_sync_bt_state(struct ath_hw *ah) struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; u32 cur_bt_state; - cur_bt_state = ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP); + cur_bt_state = ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL); if (mci->bt_state != cur_bt_state) mci->bt_state = cur_bt_state; @@ -593,7 +593,8 @@ static u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type, if (!time_out) break; - offset = ar9003_mci_get_next_gpm_offset(ah, false, &more_data); + offset = ar9003_mci_state(ah, MCI_STATE_NEXT_GPM_OFFSET, + &more_data); if (offset == MCI_GPM_INVALID) continue; @@ -657,7 +658,8 @@ static u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type, time_out = 0; while (more_data == MCI_GPM_MORE) { - offset = ar9003_mci_get_next_gpm_offset(ah, false, &more_data); + offset = ar9003_mci_state(ah, MCI_STATE_NEXT_GPM_OFFSET, + &more_data); if (offset == MCI_GPM_INVALID) break; @@ -767,6 +769,10 @@ static void ar9003_mci_mute_bt(struct ath_hw *ah) { /* disable all MCI messages */ REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, 0xffff0000); + REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS0, 0xffffffff); + REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS1, 0xffffffff); + REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS2, 0xffffffff); + REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS3, 0xffffffff); REG_SET_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); /* wait pending HW messages to flush out */ @@ -887,16 +893,13 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, udelay(100); } - /* Check pending GPM msg before MCI Reset Rx */ - ar9003_mci_check_gpm_offset(ah); - regval |= SM(1, AR_MCI_COMMAND2_RESET_RX); REG_WRITE(ah, AR_MCI_COMMAND2, regval); udelay(1); regval &= ~SM(1, AR_MCI_COMMAND2_RESET_RX); REG_WRITE(ah, AR_MCI_COMMAND2, regval); - ar9003_mci_get_next_gpm_offset(ah, true, NULL); + ar9003_mci_state(ah, MCI_STATE_INIT_GPM_OFFSET, NULL); REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, (SM(0xe801, AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR) | @@ -1007,20 +1010,17 @@ static void ar9003_mci_queue_unsent_gpm(struct ath_hw *ah, u8 header, } } -void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool force) +void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool wait_done) { struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; - if (!mci->update_2g5g && !force) + if (!mci->update_2g5g) return; if (mci->is_2g) { - if (!force) { - ar9003_mci_send_2g5g_status(ah, true); - - ar9003_mci_send_lna_transfer(ah, true); - udelay(5); - } + ar9003_mci_send_2g5g_status(ah, true); + ar9003_mci_send_lna_transfer(ah, true); + udelay(5); REG_CLR_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); @@ -1028,21 +1028,20 @@ void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool force) AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); if (!(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA)) - ar9003_mci_osla_setup(ah, true); + REG_SET_BIT(ah, AR_BTCOEX_CTRL, + AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); } else { - if (!force) { - ar9003_mci_send_lna_take(ah, true); - udelay(5); - } + ar9003_mci_send_lna_take(ah, true); + udelay(5); REG_SET_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); + REG_CLR_BIT(ah, AR_BTCOEX_CTRL, + AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); - ar9003_mci_osla_setup(ah, false); - if (!force) - ar9003_mci_send_2g5g_status(ah, true); + ar9003_mci_send_2g5g_status(ah, true); } } @@ -1170,10 +1169,11 @@ void ar9003_mci_cleanup(struct ath_hw *ah) } EXPORT_SYMBOL(ar9003_mci_cleanup); -u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type) +u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) { + struct ath_common *common = ath9k_hw_common(ah); struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; - u32 value = 0; + u32 value = 0, more_gpm = 0, gpm_ptr; u8 query_type; switch (state_type) { @@ -1185,6 +1185,81 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type) value = 0; } value &= AR_BTCOEX_CTRL_MCI_MODE_EN; + break; + case MCI_STATE_INIT_GPM_OFFSET: + value = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR); + mci->gpm_idx = value; + break; + case MCI_STATE_NEXT_GPM_OFFSET: + case MCI_STATE_LAST_GPM_OFFSET: + /* + * This could be useful to avoid new GPM message interrupt which + * may lead to spurious interrupt after power sleep, or multiple + * entry of ath_mci_intr(). + * Adding empty GPM check by returning HAL_MCI_GPM_INVALID can + * alleviate this effect, but clearing GPM RX interrupt bit is + * safe, because whether this is called from hw or driver code + * there must be an interrupt bit set/triggered initially + */ + REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, + AR_MCI_INTERRUPT_RX_MSG_GPM); + + gpm_ptr = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR); + value = gpm_ptr; + + if (value == 0) + value = mci->gpm_len - 1; + else if (value >= mci->gpm_len) { + if (value != 0xFFFF) + value = 0; + } else { + value--; + } + + if (value == 0xFFFF) { + value = MCI_GPM_INVALID; + more_gpm = MCI_GPM_NOMORE; + } else if (state_type == MCI_STATE_NEXT_GPM_OFFSET) { + if (gpm_ptr == mci->gpm_idx) { + value = MCI_GPM_INVALID; + more_gpm = MCI_GPM_NOMORE; + } else { + for (;;) { + u32 temp_index; + + /* skip reserved GPM if any */ + + if (value != mci->gpm_idx) + more_gpm = MCI_GPM_MORE; + else + more_gpm = MCI_GPM_NOMORE; + + temp_index = mci->gpm_idx; + mci->gpm_idx++; + + if (mci->gpm_idx >= + mci->gpm_len) + mci->gpm_idx = 0; + + if (ar9003_mci_is_gpm_valid(ah, + temp_index)) { + value = temp_index; + break; + } + + if (more_gpm == MCI_GPM_NOMORE) { + value = MCI_GPM_INVALID; + break; + } + } + } + if (p_data) + *p_data = more_gpm; + } + + if (value != MCI_GPM_INVALID) + value <<= 4; + break; case MCI_STATE_LAST_SCHD_MSG_OFFSET: value = MS(REG_READ(ah, AR_MCI_RX_STATUS), @@ -1197,6 +1272,21 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type) AR_MCI_RX_REMOTE_SLEEP) ? MCI_BT_SLEEP : MCI_BT_AWAKE; break; + case MCI_STATE_CONT_RSSI_POWER: + value = MS(mci->cont_status, AR_MCI_CONT_RSSI_POWER); + break; + case MCI_STATE_CONT_PRIORITY: + value = MS(mci->cont_status, AR_MCI_CONT_RRIORITY); + break; + case MCI_STATE_CONT_TXRX: + value = MS(mci->cont_status, AR_MCI_CONT_TXRX); + break; + case MCI_STATE_BT: + value = mci->bt_state; + break; + case MCI_STATE_SET_BT_SLEEP: + mci->bt_state = MCI_BT_SLEEP; + break; case MCI_STATE_SET_BT_AWAKE: mci->bt_state = MCI_BT_AWAKE; ar9003_mci_send_coex_version_query(ah, true); @@ -1205,7 +1295,7 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type) if (mci->unhalt_bt_gpm) ar9003_mci_send_coex_halt_bt_gpm(ah, false, true); - ar9003_mci_2g5g_switch(ah, false); + ar9003_mci_2g5g_switch(ah, true); break; case MCI_STATE_SET_BT_CAL_START: mci->bt_state = MCI_BT_CAL_START; @@ -1229,6 +1319,34 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type) case MCI_STATE_SEND_WLAN_COEX_VERSION: ar9003_mci_send_coex_version_response(ah, true); break; + case MCI_STATE_SET_BT_COEX_VERSION: + if (!p_data) + ath_dbg(common, MCI, + "MCI Set BT Coex version with NULL data!!\n"); + else { + mci->bt_ver_major = (*p_data >> 8) & 0xff; + mci->bt_ver_minor = (*p_data) & 0xff; + mci->bt_version_known = true; + ath_dbg(common, MCI, "MCI BT version set: %d.%d\n", + mci->bt_ver_major, mci->bt_ver_minor); + } + break; + case MCI_STATE_SEND_WLAN_CHANNELS: + if (p_data) { + if (((mci->wlan_channels[1] & 0xffff0000) == + (*(p_data + 1) & 0xffff0000)) && + (mci->wlan_channels[2] == *(p_data + 2)) && + (mci->wlan_channels[3] == *(p_data + 3))) + break; + + mci->wlan_channels[0] = *p_data++; + mci->wlan_channels[1] = *p_data++; + mci->wlan_channels[2] = *p_data++; + mci->wlan_channels[3] = *p_data++; + } + mci->wlan_channels_update = true; + ar9003_mci_send_coex_wlan_channels(ah, true); + break; case MCI_STATE_SEND_VERSION_QUERY: ar9003_mci_send_coex_version_query(ah, true); break; @@ -1236,12 +1354,29 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type) query_type = MCI_GPM_COEX_QUERY_BT_TOPOLOGY; ar9003_mci_send_coex_bt_status_query(ah, true, query_type); break; + case MCI_STATE_NEED_FLUSH_BT_INFO: + /* + * btcoex_hw.mci.unhalt_bt_gpm means whether it's + * needed to send UNHALT message. It's set whenever + * there's a request to send HALT message. + * mci_halted_bt_gpm means whether HALT message is sent + * out successfully. + * + * Checking (mci_unhalt_bt_gpm == false) instead of + * checking (ah->mci_halted_bt_gpm == false) will make + * sure currently is in UNHALT-ed mode and BT can + * respond to status query. + */ + value = (!mci->unhalt_bt_gpm && mci->need_flush_btinfo) ? 1 : 0; + if (p_data) + mci->need_flush_btinfo = (*p_data != 0) ? true : false; + break; case MCI_STATE_RECOVER_RX: ar9003_mci_prep_interface(ah); mci->query_bt = true; mci->need_flush_btinfo = true; ar9003_mci_send_coex_wlan_channels(ah, true); - ar9003_mci_2g5g_switch(ah, false); + ar9003_mci_2g5g_switch(ah, true); break; case MCI_STATE_NEED_FTP_STOMP: value = !(mci->config & ATH_MCI_CONFIG_DISABLE_FTP_STOMP); @@ -1261,9 +1396,6 @@ void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah) ath_dbg(common, MCI, "Give LNA and SPDT control to BT\n"); - ar9003_mci_send_lna_take(ah, true); - udelay(50); - REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); mci->is_2g = false; mci->update_2g5g = true; @@ -1272,154 +1404,3 @@ void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah) /* Force another 2g5g update at next scanning */ mci->update_2g5g = true; } - -void ar9003_mci_set_power_awake(struct ath_hw *ah) -{ - u32 btcoex_ctrl2, diag_sw; - int i; - u8 lna_ctrl, bt_sleep; - - for (i = 0; i < AH_WAIT_TIMEOUT; i++) { - btcoex_ctrl2 = REG_READ(ah, AR_BTCOEX_CTRL2); - if (btcoex_ctrl2 != 0xdeadbeef) - break; - udelay(AH_TIME_QUANTUM); - } - REG_WRITE(ah, AR_BTCOEX_CTRL2, (btcoex_ctrl2 | BIT(23))); - - for (i = 0; i < AH_WAIT_TIMEOUT; i++) { - diag_sw = REG_READ(ah, AR_DIAG_SW); - if (diag_sw != 0xdeadbeef) - break; - udelay(AH_TIME_QUANTUM); - } - REG_WRITE(ah, AR_DIAG_SW, (diag_sw | BIT(27) | BIT(19) | BIT(18))); - lna_ctrl = REG_READ(ah, AR_OBS_BUS_CTRL) & 0x3; - bt_sleep = REG_READ(ah, AR_MCI_RX_STATUS) & AR_MCI_RX_REMOTE_SLEEP; - - REG_WRITE(ah, AR_BTCOEX_CTRL2, btcoex_ctrl2); - REG_WRITE(ah, AR_DIAG_SW, diag_sw); - - if (bt_sleep && (lna_ctrl == 2)) { - REG_SET_BIT(ah, AR_BTCOEX_RC, 0x1); - REG_CLR_BIT(ah, AR_BTCOEX_RC, 0x1); - udelay(50); - } -} - -void ar9003_mci_check_gpm_offset(struct ath_hw *ah) -{ - struct ath_common *common = ath9k_hw_common(ah); - struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; - u32 offset; - - /* - * This should only be called before "MAC Warm Reset" or "MCI Reset Rx". - */ - offset = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR); - if (mci->gpm_idx == offset) - return; - ath_dbg(common, MCI, "GPM cached write pointer mismatch %d %d\n", - mci->gpm_idx, offset); - mci->query_bt = true; - mci->need_flush_btinfo = true; - mci->gpm_idx = 0; -} - -u32 ar9003_mci_get_next_gpm_offset(struct ath_hw *ah, bool first, u32 *more) -{ - struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; - u32 offset, more_gpm = 0, gpm_ptr; - - if (first) { - gpm_ptr = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR); - mci->gpm_idx = gpm_ptr; - return gpm_ptr; - } - - /* - * This could be useful to avoid new GPM message interrupt which - * may lead to spurious interrupt after power sleep, or multiple - * entry of ath_mci_intr(). - * Adding empty GPM check by returning HAL_MCI_GPM_INVALID can - * alleviate this effect, but clearing GPM RX interrupt bit is - * safe, because whether this is called from hw or driver code - * there must be an interrupt bit set/triggered initially - */ - REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, - AR_MCI_INTERRUPT_RX_MSG_GPM); - - gpm_ptr = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR); - offset = gpm_ptr; - - if (!offset) - offset = mci->gpm_len - 1; - else if (offset >= mci->gpm_len) { - if (offset != 0xFFFF) - offset = 0; - } else { - offset--; - } - - if ((offset == 0xFFFF) || (gpm_ptr == mci->gpm_idx)) { - offset = MCI_GPM_INVALID; - more_gpm = MCI_GPM_NOMORE; - goto out; - } - for (;;) { - u32 temp_index; - - /* skip reserved GPM if any */ - - if (offset != mci->gpm_idx) - more_gpm = MCI_GPM_MORE; - else - more_gpm = MCI_GPM_NOMORE; - - temp_index = mci->gpm_idx; - mci->gpm_idx++; - - if (mci->gpm_idx >= mci->gpm_len) - mci->gpm_idx = 0; - - if (ar9003_mci_is_gpm_valid(ah, temp_index)) { - offset = temp_index; - break; - } - - if (more_gpm == MCI_GPM_NOMORE) { - offset = MCI_GPM_INVALID; - break; - } - } - - if (offset != MCI_GPM_INVALID) - offset <<= 4; -out: - if (more) - *more = more_gpm; - - return offset; -} -EXPORT_SYMBOL(ar9003_mci_get_next_gpm_offset); - -void ar9003_mci_set_bt_version(struct ath_hw *ah, u8 major, u8 minor) -{ - struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; - - mci->bt_ver_major = major; - mci->bt_ver_minor = minor; - mci->bt_version_known = true; - ath_dbg(ath9k_hw_common(ah), MCI, "MCI BT version set: %d.%d\n", - mci->bt_ver_major, mci->bt_ver_minor); -} -EXPORT_SYMBOL(ar9003_mci_set_bt_version); - -void ar9003_mci_send_wlan_channels(struct ath_hw *ah) -{ - struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; - - mci->wlan_channels_update = true; - ar9003_mci_send_coex_wlan_channels(ah, true); -} -EXPORT_SYMBOL(ar9003_mci_send_wlan_channels); diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_mci.h b/trunk/drivers/net/wireless/ath/ath9k/ar9003_mci.h index d33b8e128855..10282e2bcdc9 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_mci.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_mci.h @@ -189,15 +189,26 @@ enum mci_bt_state { /* Type of state query */ enum mci_state_type { MCI_STATE_ENABLE, + MCI_STATE_INIT_GPM_OFFSET, + MCI_STATE_NEXT_GPM_OFFSET, + MCI_STATE_LAST_GPM_OFFSET, + MCI_STATE_BT, + MCI_STATE_SET_BT_SLEEP, MCI_STATE_SET_BT_AWAKE, MCI_STATE_SET_BT_CAL_START, MCI_STATE_SET_BT_CAL, MCI_STATE_LAST_SCHD_MSG_OFFSET, MCI_STATE_REMOTE_SLEEP, + MCI_STATE_CONT_RSSI_POWER, + MCI_STATE_CONT_PRIORITY, + MCI_STATE_CONT_TXRX, MCI_STATE_RESET_REQ_WAKE, MCI_STATE_SEND_WLAN_COEX_VERSION, + MCI_STATE_SET_BT_COEX_VERSION, + MCI_STATE_SEND_WLAN_CHANNELS, MCI_STATE_SEND_VERSION_QUERY, MCI_STATE_SEND_STATUS_QUERY, + MCI_STATE_NEED_FLUSH_BT_INFO, MCI_STATE_SET_CONCUR_TX_PRI, MCI_STATE_RECOVER_RX, MCI_STATE_NEED_FTP_STOMP, @@ -248,15 +259,14 @@ enum mci_gpm_coex_opcode { bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag, u32 *payload, u8 len, bool wait_done, bool check_bt); -u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type); +u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data); void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf, u16 len, u32 sched_addr); void ar9003_mci_cleanup(struct ath_hw *ah); void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr, u32 *rx_msg_intr); -u32 ar9003_mci_get_next_gpm_offset(struct ath_hw *ah, bool first, u32 *more); -void ar9003_mci_set_bt_version(struct ath_hw *ah, u8 major, u8 minor); -void ar9003_mci_send_wlan_channels(struct ath_hw *ah); +void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah); + /* * These functions are used by ath9k_hw. */ @@ -267,7 +277,7 @@ void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep); void ar9003_mci_init_cal_req(struct ath_hw *ah, bool *is_reusable); void ar9003_mci_init_cal_done(struct ath_hw *ah); void ar9003_mci_set_full_sleep(struct ath_hw *ah); -void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool force); +void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool wait_done); void ar9003_mci_check_bt(struct ath_hw *ah); bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan); int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, @@ -275,9 +285,6 @@ int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, bool is_full_sleep); void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked); -void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah); -void ar9003_mci_set_power_awake(struct ath_hw *ah); -void ar9003_mci_check_gpm_offset(struct ath_hw *ah); #else @@ -315,15 +322,6 @@ static inline void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, static inline void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked) { } -static inline void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah) -{ -} -static inline void ar9003_mci_set_power_awake(struct ath_hw *ah) -{ -} -static inline void ar9003_mci_check_gpm_offset(struct ath_hw *ah) -{ -} #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ #endif diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 6b91ebb158fe..d6baf69cdc14 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -173,7 +173,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah, int cur_bb_spur, negative = 0, cck_spur_freq; int i; int range, max_spur_cnts, synth_freq; - u8 *spur_fbin_ptr = ar9003_get_spur_chan_ptr(ah, IS_CHAN_2GHZ(chan)); + u8 *spur_fbin_ptr = NULL; /* * Need to verify range +/- 10 MHz in control channel, otherwise spur @@ -181,6 +181,8 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah, */ if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah)) { + spur_fbin_ptr = ar9003_get_spur_chan_ptr(ah, + IS_CHAN_2GHZ(chan)); if (spur_fbin_ptr[0] == 0) /* No spur */ return; max_spur_cnts = 5; @@ -823,18 +825,18 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW, AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); - if (on != aniState->ofdmWeakSigDetect) { + if (!on != aniState->ofdmWeakSigDetectOff) { ath_dbg(common, ANI, "** ch %d: ofdm weak signal: %s=>%s\n", chan->channel, - aniState->ofdmWeakSigDetect ? + !aniState->ofdmWeakSigDetectOff ? "on" : "off", on ? "on" : "off"); if (on) ah->stats.ast_ani_ofdmon++; else ah->stats.ast_ani_ofdmoff++; - aniState->ofdmWeakSigDetect = on; + aniState->ofdmWeakSigDetectOff = !on; } break; } @@ -853,7 +855,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, * from INI file & cap value */ value = firstep_table[level] - - firstep_table[ATH9K_ANI_FIRSTEP_LVL] + + firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] + aniState->iniDef.firstep; if (value < ATH9K_SIG_FIRSTEP_SETTING_MIN) value = ATH9K_SIG_FIRSTEP_SETTING_MIN; @@ -868,7 +870,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, * from INI file & cap value */ value2 = firstep_table[level] - - firstep_table[ATH9K_ANI_FIRSTEP_LVL] + + firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] + aniState->iniDef.firstepLow; if (value2 < ATH9K_SIG_FIRSTEP_SETTING_MIN) value2 = ATH9K_SIG_FIRSTEP_SETTING_MIN; @@ -884,7 +886,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, chan->channel, aniState->firstepLevel, level, - ATH9K_ANI_FIRSTEP_LVL, + ATH9K_ANI_FIRSTEP_LVL_NEW, value, aniState->iniDef.firstep); ath_dbg(common, ANI, @@ -892,7 +894,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, chan->channel, aniState->firstepLevel, level, - ATH9K_ANI_FIRSTEP_LVL, + ATH9K_ANI_FIRSTEP_LVL_NEW, value2, aniState->iniDef.firstepLow); if (level > aniState->firstepLevel) @@ -917,7 +919,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, * from INI file & cap value */ value = cycpwrThr1_table[level] - - cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL] + + cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] + aniState->iniDef.cycpwrThr1; if (value < ATH9K_SIG_SPUR_IMM_SETTING_MIN) value = ATH9K_SIG_SPUR_IMM_SETTING_MIN; @@ -933,7 +935,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, * from INI file & cap value */ value2 = cycpwrThr1_table[level] - - cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL] + + cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] + aniState->iniDef.cycpwrThr1Ext; if (value2 < ATH9K_SIG_SPUR_IMM_SETTING_MIN) value2 = ATH9K_SIG_SPUR_IMM_SETTING_MIN; @@ -948,7 +950,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, chan->channel, aniState->spurImmunityLevel, level, - ATH9K_ANI_SPUR_IMMUNE_LVL, + ATH9K_ANI_SPUR_IMMUNE_LVL_NEW, value, aniState->iniDef.cycpwrThr1); ath_dbg(common, ANI, @@ -956,7 +958,7 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, chan->channel, aniState->spurImmunityLevel, level, - ATH9K_ANI_SPUR_IMMUNE_LVL, + ATH9K_ANI_SPUR_IMMUNE_LVL_NEW, value2, aniState->iniDef.cycpwrThr1Ext); if (level > aniState->spurImmunityLevel) @@ -977,16 +979,16 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, AR_PHY_MRC_CCK_ENABLE, is_on); REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL, AR_PHY_MRC_CCK_MUX_REG, is_on); - if (is_on != aniState->mrcCCK) { + if (!is_on != aniState->mrcCCKOff) { ath_dbg(common, ANI, "** ch %d: MRC CCK: %s=>%s\n", chan->channel, - aniState->mrcCCK ? "on" : "off", + !aniState->mrcCCKOff ? "on" : "off", is_on ? "on" : "off"); if (is_on) ah->stats.ast_ani_ccklow++; else ah->stats.ast_ani_cckhigh++; - aniState->mrcCCK = is_on; + aniState->mrcCCKOff = !is_on; } break; } @@ -1000,9 +1002,9 @@ static bool ar9003_hw_ani_control(struct ath_hw *ah, ath_dbg(common, ANI, "ANI parameters: SI=%d, ofdmWS=%s FS=%d MRCcck=%s listenTime=%d ofdmErrs=%d cckErrs=%d\n", aniState->spurImmunityLevel, - aniState->ofdmWeakSigDetect ? "on" : "off", + !aniState->ofdmWeakSigDetectOff ? "on" : "off", aniState->firstepLevel, - aniState->mrcCCK ? "on" : "off", + !aniState->mrcCCKOff ? "on" : "off", aniState->listenTime, aniState->ofdmPhyErrCount, aniState->cckPhyErrCount); @@ -1109,10 +1111,10 @@ static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah) AR_PHY_EXT_CYCPWR_THR1); /* these levels just got reset to defaults by the INI */ - aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL; - aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL; - aniState->ofdmWeakSigDetect = ATH9K_ANI_USE_OFDM_WEAK_SIG; - aniState->mrcCCK = true; + aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL_NEW; + aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW; + aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG; + aniState->mrcCCKOff = !ATH9K_ANI_ENABLE_MRC_CCK; } static void ar9003_hw_set_radar_params(struct ath_hw *ah, diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h b/trunk/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h index 6e1756bc3833..1bd3a3d22101 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h @@ -337,7 +337,12 @@ static const u32 ar9331_modes_low_ob_db_tx_gain_1p1[][5] = { {0x00016284, 0x14d3f000, 0x14d3f000, 0x14d3f000, 0x14d3f000}, }; -#define ar9331_1p1_baseband_core_txfir_coeff_japan_2484 ar9462_2p0_baseband_core_txfir_coeff_japan_2484 +static const u32 ar9331_1p1_baseband_core_txfir_coeff_japan_2484[][2] = { + /* Addr allmodes */ + {0x0000a398, 0x00000000}, + {0x0000a39c, 0x6f7f0301}, + {0x0000a3a0, 0xca9228ee}, +}; static const u32 ar9331_1p1_xtal_25M[][2] = { /* Addr allmodes */ @@ -778,7 +783,17 @@ static const u32 ar9331_modes_high_power_tx_gain_1p1[][5] = { {0x00016284, 0x14d3f000, 0x14d3f000, 0x14d3f000, 0x14d3f000}, }; -#define ar9331_1p1_mac_postamble ar9300_2p2_mac_postamble +static const u32 ar9331_1p1_mac_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, + {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, + {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, + {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, + {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, + {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, + {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, + {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, +}; static const u32 ar9331_1p1_soc_preamble[][2] = { /* Addr allmodes */ @@ -1097,4 +1112,38 @@ static const u32 ar9331_common_tx_gain_offset1_1[][1] = { {0x00000000}, }; +static const u32 ar9331_1p1_chansel_xtal_25M[] = { + 0x0101479e, + 0x0101d027, + 0x010258af, + 0x0102e138, + 0x010369c0, + 0x0103f249, + 0x01047ad1, + 0x0105035a, + 0x01058be2, + 0x0106146b, + 0x01069cf3, + 0x0107257c, + 0x0107ae04, + 0x0108f5b2, +}; + +static const u32 ar9331_1p1_chansel_xtal_40M[] = { + 0x00a0ccbe, + 0x00a12213, + 0x00a17769, + 0x00a1ccbe, + 0x00a22213, + 0x00a27769, + 0x00a2ccbe, + 0x00a32213, + 0x00a37769, + 0x00a3ccbe, + 0x00a42213, + 0x00a47769, + 0x00a4ccbe, + 0x00a5998b, +}; + #endif /* INITVALS_9330_1P1_H */ diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9330_1p2_initvals.h b/trunk/drivers/net/wireless/ath/ath9k/ar9330_1p2_initvals.h index 57ed8a112173..0e6ca0834b34 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9330_1p2_initvals.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9330_1p2_initvals.h @@ -1,6 +1,5 @@ /* - * Copyright (c) 2010-2011 Atheros Communications Inc. - * Copyright (c) 2011-2012 Qualcomm Atheros Inc. + * Copyright (c) 2011 Atheros Communications 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 @@ -18,8 +17,8 @@ #ifndef INITVALS_9330_1P2_H #define INITVALS_9330_1P2_H -static const u32 ar9331_modes_high_ob_db_tx_gain_1p2[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ +static const u32 ar9331_modes_lowest_ob_db_tx_gain_1p2[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x0000a410, 0x000050d7, 0x000050d7, 0x000050d7, 0x000050d7}, {0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, {0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, @@ -103,14 +102,8 @@ static const u32 ar9331_modes_high_ob_db_tx_gain_1p2[][5] = { {0x0000a63c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, }; -#define ar9331_modes_high_power_tx_gain_1p2 ar9331_modes_high_ob_db_tx_gain_1p2 - -#define ar9331_modes_low_ob_db_tx_gain_1p2 ar9331_modes_high_power_tx_gain_1p2 - -#define ar9331_modes_lowest_ob_db_tx_gain_1p2 ar9331_modes_low_ob_db_tx_gain_1p2 - static const u32 ar9331_1p2_baseband_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005}, {0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e}, {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, @@ -154,6 +147,191 @@ static const u32 ar9331_1p2_baseband_postamble[][5] = { {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, }; +static const u32 ar9331_modes_high_ob_db_tx_gain_1p2[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a410, 0x000050d7, 0x000050d7, 0x000050d7, 0x000050d7}, + {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, 0x23000a00, 0x23000a00}, + {0x0000a524, 0x35001fc4, 0x35001fc4, 0x27000a02, 0x27000a02}, + {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2b000a04, 0x2b000a04}, + {0x0000a52c, 0x41023e85, 0x41023e85, 0x3f001620, 0x3f001620}, + {0x0000a530, 0x48023ec6, 0x48023ec6, 0x41001621, 0x41001621}, + {0x0000a534, 0x4d023f01, 0x4d023f01, 0x44001640, 0x44001640}, + {0x0000a538, 0x53023f4b, 0x53023f4b, 0x46001641, 0x46001641}, + {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x48001642, 0x48001642}, + {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x4b001644, 0x4b001644}, + {0x0000a544, 0x6502feca, 0x6502feca, 0x4e001a81, 0x4e001a81}, + {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x51001a83, 0x51001a83}, + {0x0000a54c, 0x7203feca, 0x7203feca, 0x54001c84, 0x54001c84}, + {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x57001ce3, 0x57001ce3}, + {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x5b001ce5, 0x5b001ce5}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5f001ce9, 0x5f001ce9}, + {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x66001eec, 0x66001eec}, + {0x0000a560, 0x900fff0b, 0x900fff0b, 0x66001eec, 0x66001eec}, + {0x0000a564, 0x960fffcb, 0x960fffcb, 0x66001eec, 0x66001eec}, + {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a580, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, + {0x0000a584, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, + {0x0000a588, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, + {0x0000a58c, 0x11062202, 0x11062202, 0x0b000200, 0x0b000200}, + {0x0000a590, 0x17022e00, 0x17022e00, 0x0f000202, 0x0f000202}, + {0x0000a594, 0x1d000ec2, 0x1d000ec2, 0x11000400, 0x11000400}, + {0x0000a598, 0x25020ec0, 0x25020ec0, 0x15000402, 0x15000402}, + {0x0000a59c, 0x2b020ec3, 0x2b020ec3, 0x19000404, 0x19000404}, + {0x0000a5a0, 0x2f001f04, 0x2f001f04, 0x1b000603, 0x1b000603}, + {0x0000a5a4, 0x35001fc4, 0x35001fc4, 0x1f000a02, 0x1f000a02}, + {0x0000a5a8, 0x3c022f04, 0x3c022f04, 0x23000a04, 0x23000a04}, + {0x0000a5ac, 0x41023e85, 0x41023e85, 0x26000a20, 0x26000a20}, + {0x0000a5b0, 0x48023ec6, 0x48023ec6, 0x2a000e20, 0x2a000e20}, + {0x0000a5b4, 0x4d023f01, 0x4d023f01, 0x2e000e22, 0x2e000e22}, + {0x0000a5b8, 0x53023f4b, 0x53023f4b, 0x31000e24, 0x31000e24}, + {0x0000a5bc, 0x5a027f09, 0x5a027f09, 0x34001640, 0x34001640}, + {0x0000a5c0, 0x5f027fc9, 0x5f027fc9, 0x38001660, 0x38001660}, + {0x0000a5c4, 0x6502feca, 0x6502feca, 0x3b001861, 0x3b001861}, + {0x0000a5c8, 0x6b02ff4a, 0x6b02ff4a, 0x3e001a81, 0x3e001a81}, + {0x0000a5cc, 0x7203feca, 0x7203feca, 0x42001a83, 0x42001a83}, + {0x0000a5d0, 0x7703ff0b, 0x7703ff0b, 0x44001c84, 0x44001c84}, + {0x0000a5d4, 0x7d06ffcb, 0x7d06ffcb, 0x48001ce3, 0x48001ce3}, + {0x0000a5d8, 0x8407ff0b, 0x8407ff0b, 0x4c001ce5, 0x4c001ce5}, + {0x0000a5dc, 0x8907ffcb, 0x8907ffcb, 0x50001ce9, 0x50001ce9}, + {0x0000a5e0, 0x900fff0b, 0x900fff0b, 0x54001ceb, 0x54001ceb}, + {0x0000a5e4, 0x960fffcb, 0x960fffcb, 0x56001eec, 0x56001eec}, + {0x0000a5e8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5ec, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f0, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f4, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5fc, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, + {0x0000a618, 0x02008501, 0x02008501, 0x02008501, 0x02008501}, + {0x0000a61c, 0x02008802, 0x02008802, 0x02008802, 0x02008802}, + {0x0000a620, 0x0300c802, 0x0300c802, 0x0300c802, 0x0300c802}, + {0x0000a624, 0x0300cc03, 0x0300cc03, 0x0300cc03, 0x0300cc03}, + {0x0000a628, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a62c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a630, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a634, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a638, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a63c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, +}; + +static const u32 ar9331_modes_low_ob_db_tx_gain_1p2[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a410, 0x000050d7, 0x000050d7, 0x000050d7, 0x000050d7}, + {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, 0x23000a00, 0x23000a00}, + {0x0000a524, 0x35001fc4, 0x35001fc4, 0x27000a02, 0x27000a02}, + {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2b000a04, 0x2b000a04}, + {0x0000a52c, 0x41023e85, 0x41023e85, 0x3f001620, 0x3f001620}, + {0x0000a530, 0x48023ec6, 0x48023ec6, 0x41001621, 0x41001621}, + {0x0000a534, 0x4d023f01, 0x4d023f01, 0x44001640, 0x44001640}, + {0x0000a538, 0x53023f4b, 0x53023f4b, 0x46001641, 0x46001641}, + {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x48001642, 0x48001642}, + {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x4b001644, 0x4b001644}, + {0x0000a544, 0x6502feca, 0x6502feca, 0x4e001a81, 0x4e001a81}, + {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x51001a83, 0x51001a83}, + {0x0000a54c, 0x7203feca, 0x7203feca, 0x54001c84, 0x54001c84}, + {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x57001ce3, 0x57001ce3}, + {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x5b001ce5, 0x5b001ce5}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5f001ce9, 0x5f001ce9}, + {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x66001eec, 0x66001eec}, + {0x0000a560, 0x900fff0b, 0x900fff0b, 0x66001eec, 0x66001eec}, + {0x0000a564, 0x960fffcb, 0x960fffcb, 0x66001eec, 0x66001eec}, + {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a580, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, + {0x0000a584, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, + {0x0000a588, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, + {0x0000a58c, 0x11062202, 0x11062202, 0x0b000200, 0x0b000200}, + {0x0000a590, 0x17022e00, 0x17022e00, 0x0f000202, 0x0f000202}, + {0x0000a594, 0x1d000ec2, 0x1d000ec2, 0x11000400, 0x11000400}, + {0x0000a598, 0x25020ec0, 0x25020ec0, 0x15000402, 0x15000402}, + {0x0000a59c, 0x2b020ec3, 0x2b020ec3, 0x19000404, 0x19000404}, + {0x0000a5a0, 0x2f001f04, 0x2f001f04, 0x1b000603, 0x1b000603}, + {0x0000a5a4, 0x35001fc4, 0x35001fc4, 0x1f000a02, 0x1f000a02}, + {0x0000a5a8, 0x3c022f04, 0x3c022f04, 0x23000a04, 0x23000a04}, + {0x0000a5ac, 0x41023e85, 0x41023e85, 0x26000a20, 0x26000a20}, + {0x0000a5b0, 0x48023ec6, 0x48023ec6, 0x2a000e20, 0x2a000e20}, + {0x0000a5b4, 0x4d023f01, 0x4d023f01, 0x2e000e22, 0x2e000e22}, + {0x0000a5b8, 0x53023f4b, 0x53023f4b, 0x31000e24, 0x31000e24}, + {0x0000a5bc, 0x5a027f09, 0x5a027f09, 0x34001640, 0x34001640}, + {0x0000a5c0, 0x5f027fc9, 0x5f027fc9, 0x38001660, 0x38001660}, + {0x0000a5c4, 0x6502feca, 0x6502feca, 0x3b001861, 0x3b001861}, + {0x0000a5c8, 0x6b02ff4a, 0x6b02ff4a, 0x3e001a81, 0x3e001a81}, + {0x0000a5cc, 0x7203feca, 0x7203feca, 0x42001a83, 0x42001a83}, + {0x0000a5d0, 0x7703ff0b, 0x7703ff0b, 0x44001c84, 0x44001c84}, + {0x0000a5d4, 0x7d06ffcb, 0x7d06ffcb, 0x48001ce3, 0x48001ce3}, + {0x0000a5d8, 0x8407ff0b, 0x8407ff0b, 0x4c001ce5, 0x4c001ce5}, + {0x0000a5dc, 0x8907ffcb, 0x8907ffcb, 0x50001ce9, 0x50001ce9}, + {0x0000a5e0, 0x900fff0b, 0x900fff0b, 0x54001ceb, 0x54001ceb}, + {0x0000a5e4, 0x960fffcb, 0x960fffcb, 0x56001eec, 0x56001eec}, + {0x0000a5e8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5ec, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f0, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f4, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5fc, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, + {0x0000a618, 0x02008501, 0x02008501, 0x02008501, 0x02008501}, + {0x0000a61c, 0x02008802, 0x02008802, 0x02008802, 0x02008802}, + {0x0000a620, 0x0300c802, 0x0300c802, 0x0300c802, 0x0300c802}, + {0x0000a624, 0x0300cc03, 0x0300cc03, 0x0300cc03, 0x0300cc03}, + {0x0000a628, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a62c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a630, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a634, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a638, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a63c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, +}; + +static const u32 ar9331_1p2_baseband_core_txfir_coeff_japan_2484[][2] = { + /* Addr allmodes */ + {0x0000a398, 0x00000000}, + {0x0000a39c, 0x6f7f0301}, + {0x0000a3a0, 0xca9228ee}, +}; + +static const u32 ar9331_1p2_xtal_25M[][2] = { + /* Addr allmodes */ + {0x00007038, 0x000002f8}, + {0x00008244, 0x0010f3d7}, + {0x0000824c, 0x0001e7ae}, + {0x0001609c, 0x0f508f29}, +}; + static const u32 ar9331_1p2_radio_core[][2] = { /* Addr allmodes */ {0x00016000, 0x36db6db6}, @@ -219,24 +397,684 @@ static const u32 ar9331_1p2_radio_core[][2] = { {0x000163d4, 0x00000000}, }; -#define ar9331_1p2_baseband_core_txfir_coeff_japan_2484 ar9331_1p1_baseband_core_txfir_coeff_japan_2484 - -#define ar9331_1p2_xtal_25M ar9331_1p1_xtal_25M +static const u32 ar9331_1p2_soc_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00007010, 0x00000022, 0x00000022, 0x00000022, 0x00000022}, +}; -#define ar9331_1p2_xtal_40M ar9331_1p1_xtal_40M +static const u32 ar9331_common_wo_xlna_rx_gain_1p2[][2] = { + /* Addr allmodes */ + {0x0000a000, 0x00060005}, + {0x0000a004, 0x00810080}, + {0x0000a008, 0x00830082}, + {0x0000a00c, 0x00850084}, + {0x0000a010, 0x01820181}, + {0x0000a014, 0x01840183}, + {0x0000a018, 0x01880185}, + {0x0000a01c, 0x018a0189}, + {0x0000a020, 0x02850284}, + {0x0000a024, 0x02890288}, + {0x0000a028, 0x028b028a}, + {0x0000a02c, 0x03850384}, + {0x0000a030, 0x03890388}, + {0x0000a034, 0x038b038a}, + {0x0000a038, 0x038d038c}, + {0x0000a03c, 0x03910390}, + {0x0000a040, 0x03930392}, + {0x0000a044, 0x03950394}, + {0x0000a048, 0x00000396}, + {0x0000a04c, 0x00000000}, + {0x0000a050, 0x00000000}, + {0x0000a054, 0x00000000}, + {0x0000a058, 0x00000000}, + {0x0000a05c, 0x00000000}, + {0x0000a060, 0x00000000}, + {0x0000a064, 0x00000000}, + {0x0000a068, 0x00000000}, + {0x0000a06c, 0x00000000}, + {0x0000a070, 0x00000000}, + {0x0000a074, 0x00000000}, + {0x0000a078, 0x00000000}, + {0x0000a07c, 0x00000000}, + {0x0000a080, 0x28282828}, + {0x0000a084, 0x28282828}, + {0x0000a088, 0x28282828}, + {0x0000a08c, 0x28282828}, + {0x0000a090, 0x28282828}, + {0x0000a094, 0x24242428}, + {0x0000a098, 0x171e1e1e}, + {0x0000a09c, 0x02020b0b}, + {0x0000a0a0, 0x02020202}, + {0x0000a0a4, 0x00000000}, + {0x0000a0a8, 0x00000000}, + {0x0000a0ac, 0x00000000}, + {0x0000a0b0, 0x00000000}, + {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}, + {0x0000a100, 0x66006601}, + {0x0000a104, 0x661e661f}, + {0x0000a108, 0x7703661d}, + {0x0000a10c, 0x77017702}, + {0x0000a110, 0x00007700}, + {0x0000a114, 0x00000000}, + {0x0000a118, 0x00000000}, + {0x0000a11c, 0x00000000}, + {0x0000a120, 0x00000000}, + {0x0000a124, 0x00000000}, + {0x0000a128, 0x00000000}, + {0x0000a12c, 0x00000000}, + {0x0000a130, 0x00000000}, + {0x0000a134, 0x00000000}, + {0x0000a138, 0x00000000}, + {0x0000a13c, 0x00000000}, + {0x0000a140, 0x001f0000}, + {0x0000a144, 0x111f1100}, + {0x0000a148, 0x111d111e}, + {0x0000a14c, 0x111b111c}, + {0x0000a150, 0x22032204}, + {0x0000a154, 0x22012202}, + {0x0000a158, 0x221f2200}, + {0x0000a15c, 0x221d221e}, + {0x0000a160, 0x33013302}, + {0x0000a164, 0x331f3300}, + {0x0000a168, 0x4402331e}, + {0x0000a16c, 0x44004401}, + {0x0000a170, 0x441e441f}, + {0x0000a174, 0x55015502}, + {0x0000a178, 0x551f5500}, + {0x0000a17c, 0x6602551e}, + {0x0000a180, 0x66006601}, + {0x0000a184, 0x661e661f}, + {0x0000a188, 0x7703661d}, + {0x0000a18c, 0x77017702}, + {0x0000a190, 0x00007700}, + {0x0000a194, 0x00000000}, + {0x0000a198, 0x00000000}, + {0x0000a19c, 0x00000000}, + {0x0000a1a0, 0x00000000}, + {0x0000a1a4, 0x00000000}, + {0x0000a1a8, 0x00000000}, + {0x0000a1ac, 0x00000000}, + {0x0000a1b0, 0x00000000}, + {0x0000a1b4, 0x00000000}, + {0x0000a1b8, 0x00000000}, + {0x0000a1bc, 0x00000000}, + {0x0000a1c0, 0x00000000}, + {0x0000a1c4, 0x00000000}, + {0x0000a1c8, 0x00000000}, + {0x0000a1cc, 0x00000000}, + {0x0000a1d0, 0x00000000}, + {0x0000a1d4, 0x00000000}, + {0x0000a1d8, 0x00000000}, + {0x0000a1dc, 0x00000000}, + {0x0000a1e0, 0x00000000}, + {0x0000a1e4, 0x00000000}, + {0x0000a1e8, 0x00000000}, + {0x0000a1ec, 0x00000000}, + {0x0000a1f0, 0x00000396}, + {0x0000a1f4, 0x00000396}, + {0x0000a1f8, 0x00000396}, + {0x0000a1fc, 0x00000296}, +}; -#define ar9331_1p2_baseband_core ar9331_1p1_baseband_core +static const u32 ar9331_1p2_baseband_core[][2] = { + /* Addr allmodes */ + {0x00009800, 0xafe68e30}, + {0x00009804, 0xfd14e000}, + {0x00009808, 0x9c0a8f6b}, + {0x0000980c, 0x04800000}, + {0x00009814, 0x9280c00a}, + {0x00009818, 0x00000000}, + {0x0000981c, 0x00020028}, + {0x00009834, 0x5f3ca3de}, + {0x00009838, 0x0108ecff}, + {0x0000983c, 0x14750600}, + {0x00009880, 0x201fff00}, + {0x00009884, 0x00001042}, + {0x000098a4, 0x00200400}, + {0x000098b0, 0x32840bbe}, + {0x000098d0, 0x004b6a8e}, + {0x000098d4, 0x00000820}, + {0x000098dc, 0x00000000}, + {0x000098f0, 0x00000000}, + {0x000098f4, 0x00000000}, + {0x00009c04, 0x00000000}, + {0x00009c08, 0x03200000}, + {0x00009c0c, 0x00000000}, + {0x00009c10, 0x00000000}, + {0x00009c14, 0x00046384}, + {0x00009c18, 0x05b6b440}, + {0x00009c1c, 0x00b6b440}, + {0x00009d00, 0xc080a333}, + {0x00009d04, 0x40206c10}, + {0x00009d08, 0x009c4060}, + {0x00009d0c, 0x1883800a}, + {0x00009d10, 0x01834061}, + {0x00009d14, 0x00c00400}, + {0x00009d18, 0x00000000}, + {0x00009e08, 0x0038233c}, + {0x00009e24, 0x9927b515}, + {0x00009e28, 0x12ef0200}, + {0x00009e30, 0x06336f77}, + {0x00009e34, 0x6af6532f}, + {0x00009e38, 0x0cc80c00}, + {0x00009e40, 0x0d261820}, + {0x00009e4c, 0x00001004}, + {0x00009e50, 0x00ff03f1}, + {0x00009fc0, 0x803e4788}, + {0x00009fc4, 0x0001efb5}, + {0x00009fcc, 0x40000014}, + {0x0000a20c, 0x00000000}, + {0x0000a220, 0x00000000}, + {0x0000a224, 0x00000000}, + {0x0000a228, 0x10002310}, + {0x0000a23c, 0x00000000}, + {0x0000a244, 0x0c000000}, + {0x0000a2a0, 0x00000001}, + {0x0000a2c0, 0x00000001}, + {0x0000a2c8, 0x00000000}, + {0x0000a2cc, 0x18c43433}, + {0x0000a2d4, 0x00000000}, + {0x0000a2dc, 0x00000000}, + {0x0000a2e0, 0x00000000}, + {0x0000a2e4, 0x00000000}, + {0x0000a2e8, 0x00000000}, + {0x0000a2ec, 0x00000000}, + {0x0000a2f0, 0x00000000}, + {0x0000a2f4, 0x00000000}, + {0x0000a2f8, 0x00000000}, + {0x0000a344, 0x00000000}, + {0x0000a34c, 0x00000000}, + {0x0000a350, 0x0000a000}, + {0x0000a364, 0x00000000}, + {0x0000a370, 0x00000000}, + {0x0000a390, 0x00000001}, + {0x0000a394, 0x00000444}, + {0x0000a398, 0x001f0e0f}, + {0x0000a39c, 0x0075393f}, + {0x0000a3a0, 0xb79f6427}, + {0x0000a3a4, 0x00000000}, + {0x0000a3a8, 0xaaaaaaaa}, + {0x0000a3ac, 0x3c466478}, + {0x0000a3c0, 0x20202020}, + {0x0000a3c4, 0x22222220}, + {0x0000a3c8, 0x20200020}, + {0x0000a3cc, 0x20202020}, + {0x0000a3d0, 0x20202020}, + {0x0000a3d4, 0x20202020}, + {0x0000a3d8, 0x20202020}, + {0x0000a3dc, 0x20202020}, + {0x0000a3e0, 0x20202020}, + {0x0000a3e4, 0x20202020}, + {0x0000a3e8, 0x20202020}, + {0x0000a3ec, 0x20202020}, + {0x0000a3f0, 0x00000000}, + {0x0000a3f4, 0x00000006}, + {0x0000a3f8, 0x0cdbd380}, + {0x0000a3fc, 0x000f0f01}, + {0x0000a400, 0x8fa91f01}, + {0x0000a404, 0x00000000}, + {0x0000a408, 0x0e79e5c6}, + {0x0000a40c, 0x00820820}, + {0x0000a414, 0x1ce739ce}, + {0x0000a418, 0x2d001dce}, + {0x0000a41c, 0x1ce739ce}, + {0x0000a420, 0x000001ce}, + {0x0000a424, 0x1ce739ce}, + {0x0000a428, 0x000001ce}, + {0x0000a42c, 0x1ce739ce}, + {0x0000a430, 0x1ce739ce}, + {0x0000a434, 0x00000000}, + {0x0000a438, 0x00001801}, + {0x0000a43c, 0x00000000}, + {0x0000a440, 0x00000000}, + {0x0000a444, 0x00000000}, + {0x0000a448, 0x04000000}, + {0x0000a44c, 0x00000001}, + {0x0000a450, 0x00010000}, + {0x0000a458, 0x00000000}, + {0x0000a640, 0x00000000}, + {0x0000a644, 0x3fad9d74}, + {0x0000a648, 0x0048060a}, + {0x0000a64c, 0x00003c37}, + {0x0000a670, 0x03020100}, + {0x0000a674, 0x09080504}, + {0x0000a678, 0x0d0c0b0a}, + {0x0000a67c, 0x13121110}, + {0x0000a680, 0x31301514}, + {0x0000a684, 0x35343332}, + {0x0000a688, 0x00000036}, + {0x0000a690, 0x00000838}, + {0x0000a7c0, 0x00000000}, + {0x0000a7c4, 0xfffffffc}, + {0x0000a7c8, 0x00000000}, + {0x0000a7cc, 0x00000000}, + {0x0000a7d0, 0x00000000}, + {0x0000a7d4, 0x00000004}, + {0x0000a7dc, 0x00000001}, +}; -#define ar9331_1p2_soc_postamble ar9331_1p1_soc_postamble +static const u32 ar9331_modes_high_power_tx_gain_1p2[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a410, 0x000050d7, 0x000050d7, 0x000050d7, 0x000050d7}, + {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, 0x23000a00, 0x23000a00}, + {0x0000a524, 0x35001fc4, 0x35001fc4, 0x27000a02, 0x27000a02}, + {0x0000a528, 0x3c022f04, 0x3c022f04, 0x2b000a04, 0x2b000a04}, + {0x0000a52c, 0x41023e85, 0x41023e85, 0x3f001620, 0x3f001620}, + {0x0000a530, 0x48023ec6, 0x48023ec6, 0x41001621, 0x41001621}, + {0x0000a534, 0x4d023f01, 0x4d023f01, 0x44001640, 0x44001640}, + {0x0000a538, 0x53023f4b, 0x53023f4b, 0x46001641, 0x46001641}, + {0x0000a53c, 0x5a027f09, 0x5a027f09, 0x48001642, 0x48001642}, + {0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x4b001644, 0x4b001644}, + {0x0000a544, 0x6502feca, 0x6502feca, 0x4e001a81, 0x4e001a81}, + {0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x51001a83, 0x51001a83}, + {0x0000a54c, 0x7203feca, 0x7203feca, 0x54001c84, 0x54001c84}, + {0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x57001ce3, 0x57001ce3}, + {0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x5b001ce5, 0x5b001ce5}, + {0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5f001ce9, 0x5f001ce9}, + {0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x66001eec, 0x66001eec}, + {0x0000a560, 0x900fff0b, 0x900fff0b, 0x66001eec, 0x66001eec}, + {0x0000a564, 0x960fffcb, 0x960fffcb, 0x66001eec, 0x66001eec}, + {0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x66001eec, 0x66001eec}, + {0x0000a580, 0x00022200, 0x00022200, 0x00000000, 0x00000000}, + {0x0000a584, 0x05062002, 0x05062002, 0x04000002, 0x04000002}, + {0x0000a588, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004}, + {0x0000a58c, 0x11062202, 0x11062202, 0x0b000200, 0x0b000200}, + {0x0000a590, 0x17022e00, 0x17022e00, 0x0f000202, 0x0f000202}, + {0x0000a594, 0x1d000ec2, 0x1d000ec2, 0x11000400, 0x11000400}, + {0x0000a598, 0x25020ec0, 0x25020ec0, 0x15000402, 0x15000402}, + {0x0000a59c, 0x2b020ec3, 0x2b020ec3, 0x19000404, 0x19000404}, + {0x0000a5a0, 0x2f001f04, 0x2f001f04, 0x1b000603, 0x1b000603}, + {0x0000a5a4, 0x35001fc4, 0x35001fc4, 0x1f000a02, 0x1f000a02}, + {0x0000a5a8, 0x3c022f04, 0x3c022f04, 0x23000a04, 0x23000a04}, + {0x0000a5ac, 0x41023e85, 0x41023e85, 0x26000a20, 0x26000a20}, + {0x0000a5b0, 0x48023ec6, 0x48023ec6, 0x2a000e20, 0x2a000e20}, + {0x0000a5b4, 0x4d023f01, 0x4d023f01, 0x2e000e22, 0x2e000e22}, + {0x0000a5b8, 0x53023f4b, 0x53023f4b, 0x31000e24, 0x31000e24}, + {0x0000a5bc, 0x5a027f09, 0x5a027f09, 0x34001640, 0x34001640}, + {0x0000a5c0, 0x5f027fc9, 0x5f027fc9, 0x38001660, 0x38001660}, + {0x0000a5c4, 0x6502feca, 0x6502feca, 0x3b001861, 0x3b001861}, + {0x0000a5c8, 0x6b02ff4a, 0x6b02ff4a, 0x3e001a81, 0x3e001a81}, + {0x0000a5cc, 0x7203feca, 0x7203feca, 0x42001a83, 0x42001a83}, + {0x0000a5d0, 0x7703ff0b, 0x7703ff0b, 0x44001c84, 0x44001c84}, + {0x0000a5d4, 0x7d06ffcb, 0x7d06ffcb, 0x48001ce3, 0x48001ce3}, + {0x0000a5d8, 0x8407ff0b, 0x8407ff0b, 0x4c001ce5, 0x4c001ce5}, + {0x0000a5dc, 0x8907ffcb, 0x8907ffcb, 0x50001ce9, 0x50001ce9}, + {0x0000a5e0, 0x900fff0b, 0x900fff0b, 0x54001ceb, 0x54001ceb}, + {0x0000a5e4, 0x960fffcb, 0x960fffcb, 0x56001eec, 0x56001eec}, + {0x0000a5e8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5ec, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f0, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f4, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5f8, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a5fc, 0x9c1fff0b, 0x9c1fff0b, 0x56001eec, 0x56001eec}, + {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, + {0x0000a618, 0x02008501, 0x02008501, 0x02008501, 0x02008501}, + {0x0000a61c, 0x02008802, 0x02008802, 0x02008802, 0x02008802}, + {0x0000a620, 0x0300c802, 0x0300c802, 0x0300c802, 0x0300c802}, + {0x0000a624, 0x0300cc03, 0x0300cc03, 0x0300cc03, 0x0300cc03}, + {0x0000a628, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a62c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a630, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a634, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a638, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, + {0x0000a63c, 0x04011004, 0x04011004, 0x04011004, 0x04011004}, +}; -#define ar9331_1p2_mac_postamble ar9331_1p1_mac_postamble +static const u32 ar9331_1p2_mac_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, + {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, + {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, + {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, + {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, + {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, + {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, + {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, +}; -#define ar9331_1p2_soc_preamble ar9331_1p1_soc_preamble +static const u32 ar9331_1p2_soc_preamble[][2] = { + /* Addr allmodes */ + {0x00007020, 0x00000000}, + {0x00007034, 0x00000002}, + {0x00007038, 0x000002f8}, +}; -#define ar9331_1p2_mac_core ar9331_1p1_mac_core +static const u32 ar9331_1p2_xtal_40M[][2] = { + /* Addr allmodes */ + {0x00007038, 0x000004c2}, + {0x00008244, 0x0010f400}, + {0x0000824c, 0x0001e800}, + {0x0001609c, 0x0b283f31}, +}; -#define ar9331_common_wo_xlna_rx_gain_1p2 ar9331_common_wo_xlna_rx_gain_1p1 +static const u32 ar9331_1p2_mac_core[][2] = { + /* Addr allmodes */ + {0x00000008, 0x00000000}, + {0x00000030, 0x00020085}, + {0x00000034, 0x00000005}, + {0x00000040, 0x00000000}, + {0x00000044, 0x00000000}, + {0x00000048, 0x00000008}, + {0x0000004c, 0x00000010}, + {0x00000050, 0x00000000}, + {0x00001040, 0x002ffc0f}, + {0x00001044, 0x002ffc0f}, + {0x00001048, 0x002ffc0f}, + {0x0000104c, 0x002ffc0f}, + {0x00001050, 0x002ffc0f}, + {0x00001054, 0x002ffc0f}, + {0x00001058, 0x002ffc0f}, + {0x0000105c, 0x002ffc0f}, + {0x00001060, 0x002ffc0f}, + {0x00001064, 0x002ffc0f}, + {0x000010f0, 0x00000100}, + {0x00001270, 0x00000000}, + {0x000012b0, 0x00000000}, + {0x000012f0, 0x00000000}, + {0x0000143c, 0x00000000}, + {0x0000147c, 0x00000000}, + {0x00008000, 0x00000000}, + {0x00008004, 0x00000000}, + {0x00008008, 0x00000000}, + {0x0000800c, 0x00000000}, + {0x00008018, 0x00000000}, + {0x00008020, 0x00000000}, + {0x00008038, 0x00000000}, + {0x0000803c, 0x00000000}, + {0x00008040, 0x00000000}, + {0x00008044, 0x00000000}, + {0x00008048, 0x00000000}, + {0x0000804c, 0xffffffff}, + {0x00008054, 0x00000000}, + {0x00008058, 0x00000000}, + {0x0000805c, 0x000fc78f}, + {0x00008060, 0x0000000f}, + {0x00008064, 0x00000000}, + {0x00008070, 0x00000310}, + {0x00008074, 0x00000020}, + {0x00008078, 0x00000000}, + {0x0000809c, 0x0000000f}, + {0x000080a0, 0x00000000}, + {0x000080a4, 0x02ff0000}, + {0x000080a8, 0x0e070605}, + {0x000080ac, 0x0000000d}, + {0x000080b0, 0x00000000}, + {0x000080b4, 0x00000000}, + {0x000080b8, 0x00000000}, + {0x000080bc, 0x00000000}, + {0x000080c0, 0x2a800000}, + {0x000080c4, 0x06900168}, + {0x000080c8, 0x13881c20}, + {0x000080cc, 0x01f40000}, + {0x000080d0, 0x00252500}, + {0x000080d4, 0x00a00000}, + {0x000080d8, 0x00400000}, + {0x000080dc, 0x00000000}, + {0x000080e0, 0xffffffff}, + {0x000080e4, 0x0000ffff}, + {0x000080e8, 0x3f3f3f3f}, + {0x000080ec, 0x00000000}, + {0x000080f0, 0x00000000}, + {0x000080f4, 0x00000000}, + {0x000080fc, 0x00020000}, + {0x00008100, 0x00000000}, + {0x00008108, 0x00000052}, + {0x0000810c, 0x00000000}, + {0x00008110, 0x00000000}, + {0x00008114, 0x000007ff}, + {0x00008118, 0x000000aa}, + {0x0000811c, 0x00003210}, + {0x00008124, 0x00000000}, + {0x00008128, 0x00000000}, + {0x0000812c, 0x00000000}, + {0x00008130, 0x00000000}, + {0x00008134, 0x00000000}, + {0x00008138, 0x00000000}, + {0x0000813c, 0x0000ffff}, + {0x00008144, 0xffffffff}, + {0x00008168, 0x00000000}, + {0x0000816c, 0x00000000}, + {0x00008170, 0x18486200}, + {0x00008174, 0x33332210}, + {0x00008178, 0x00000000}, + {0x0000817c, 0x00020000}, + {0x000081c0, 0x00000000}, + {0x000081c4, 0x33332210}, + {0x000081c8, 0x00000000}, + {0x000081cc, 0x00000000}, + {0x000081d4, 0x00000000}, + {0x000081ec, 0x00000000}, + {0x000081f0, 0x00000000}, + {0x000081f4, 0x00000000}, + {0x000081f8, 0x00000000}, + {0x000081fc, 0x00000000}, + {0x00008240, 0x00100000}, + {0x00008248, 0x00000800}, + {0x00008250, 0x00000000}, + {0x00008254, 0x00000000}, + {0x00008258, 0x00000000}, + {0x0000825c, 0x40000000}, + {0x00008260, 0x00080922}, + {0x00008264, 0x9d400010}, + {0x00008268, 0xffffffff}, + {0x0000826c, 0x0000ffff}, + {0x00008270, 0x00000000}, + {0x00008274, 0x40000000}, + {0x00008278, 0x003e4180}, + {0x0000827c, 0x00000004}, + {0x00008284, 0x0000002c}, + {0x00008288, 0x0000002c}, + {0x0000828c, 0x000000ff}, + {0x00008294, 0x00000000}, + {0x00008298, 0x00000000}, + {0x0000829c, 0x00000000}, + {0x00008300, 0x00000140}, + {0x00008314, 0x00000000}, + {0x0000831c, 0x0000010d}, + {0x00008328, 0x00000000}, + {0x0000832c, 0x00000007}, + {0x00008330, 0x00000302}, + {0x00008334, 0x00000700}, + {0x00008338, 0x00ff0000}, + {0x0000833c, 0x02400000}, + {0x00008340, 0x000107ff}, + {0x00008344, 0xaa48105b}, + {0x00008348, 0x008f0000}, + {0x0000835c, 0x00000000}, + {0x00008360, 0xffffffff}, + {0x00008364, 0xffffffff}, + {0x00008368, 0x00000000}, + {0x00008370, 0x00000000}, + {0x00008374, 0x000000ff}, + {0x00008378, 0x00000000}, + {0x0000837c, 0x00000000}, + {0x00008380, 0xffffffff}, + {0x00008384, 0xffffffff}, + {0x00008390, 0xffffffff}, + {0x00008394, 0xffffffff}, + {0x00008398, 0x00000000}, + {0x0000839c, 0x00000000}, + {0x000083a0, 0x00000000}, + {0x000083a4, 0x0000fa14}, + {0x000083a8, 0x000f0c00}, + {0x000083ac, 0x33332210}, + {0x000083b0, 0x33332210}, + {0x000083b4, 0x33332210}, + {0x000083b8, 0x33332210}, + {0x000083bc, 0x00000000}, + {0x000083c0, 0x00000000}, + {0x000083c4, 0x00000000}, + {0x000083c8, 0x00000000}, + {0x000083cc, 0x00000200}, + {0x000083d0, 0x000301ff}, +}; -#define ar9331_common_rx_gain_1p2 ar9485_common_rx_gain_1_1 +static const u32 ar9331_common_rx_gain_1p2[][2] = { + /* Addr allmodes */ + {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}, + {0x0000a038, 0x038d038c}, + {0x0000a03c, 0x03910390}, + {0x0000a040, 0x03930392}, + {0x0000a044, 0x03950394}, + {0x0000a048, 0x00000396}, + {0x0000a04c, 0x00000000}, + {0x0000a050, 0x00000000}, + {0x0000a054, 0x00000000}, + {0x0000a058, 0x00000000}, + {0x0000a05c, 0x00000000}, + {0x0000a060, 0x00000000}, + {0x0000a064, 0x00000000}, + {0x0000a068, 0x00000000}, + {0x0000a06c, 0x00000000}, + {0x0000a070, 0x00000000}, + {0x0000a074, 0x00000000}, + {0x0000a078, 0x00000000}, + {0x0000a07c, 0x00000000}, + {0x0000a080, 0x28282828}, + {0x0000a084, 0x28282828}, + {0x0000a088, 0x28282828}, + {0x0000a08c, 0x28282828}, + {0x0000a090, 0x28282828}, + {0x0000a094, 0x21212128}, + {0x0000a098, 0x171c1c1c}, + {0x0000a09c, 0x02020212}, + {0x0000a0a0, 0x00000202}, + {0x0000a0a4, 0x00000000}, + {0x0000a0a8, 0x00000000}, + {0x0000a0ac, 0x00000000}, + {0x0000a0b0, 0x00000000}, + {0x0000a0b4, 0x00000000}, + {0x0000a0b8, 0x00000000}, + {0x0000a0bc, 0x00000000}, + {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}, + {0x0000a10c, 0x77017702}, + {0x0000a110, 0x00007700}, + {0x0000a114, 0x00000000}, + {0x0000a118, 0x00000000}, + {0x0000a11c, 0x00000000}, + {0x0000a120, 0x00000000}, + {0x0000a124, 0x00000000}, + {0x0000a128, 0x00000000}, + {0x0000a12c, 0x00000000}, + {0x0000a130, 0x00000000}, + {0x0000a134, 0x00000000}, + {0x0000a138, 0x00000000}, + {0x0000a13c, 0x00000000}, + {0x0000a140, 0x001f0000}, + {0x0000a144, 0x111f1100}, + {0x0000a148, 0x111d111e}, + {0x0000a14c, 0x111b111c}, + {0x0000a150, 0x22032204}, + {0x0000a154, 0x22012202}, + {0x0000a158, 0x221f2200}, + {0x0000a15c, 0x221d221e}, + {0x0000a160, 0x33013302}, + {0x0000a164, 0x331f3300}, + {0x0000a168, 0x4402331e}, + {0x0000a16c, 0x44004401}, + {0x0000a170, 0x441e441f}, + {0x0000a174, 0x55015502}, + {0x0000a178, 0x551f5500}, + {0x0000a17c, 0x6602551e}, + {0x0000a180, 0x66006601}, + {0x0000a184, 0x661e661f}, + {0x0000a188, 0x7703661d}, + {0x0000a18c, 0x77017702}, + {0x0000a190, 0x00007700}, + {0x0000a194, 0x00000000}, + {0x0000a198, 0x00000000}, + {0x0000a19c, 0x00000000}, + {0x0000a1a0, 0x00000000}, + {0x0000a1a4, 0x00000000}, + {0x0000a1a8, 0x00000000}, + {0x0000a1ac, 0x00000000}, + {0x0000a1b0, 0x00000000}, + {0x0000a1b4, 0x00000000}, + {0x0000a1b8, 0x00000000}, + {0x0000a1bc, 0x00000000}, + {0x0000a1c0, 0x00000000}, + {0x0000a1c4, 0x00000000}, + {0x0000a1c8, 0x00000000}, + {0x0000a1cc, 0x00000000}, + {0x0000a1d0, 0x00000000}, + {0x0000a1d4, 0x00000000}, + {0x0000a1d8, 0x00000000}, + {0x0000a1dc, 0x00000000}, + {0x0000a1e0, 0x00000000}, + {0x0000a1e4, 0x00000000}, + {0x0000a1e8, 0x00000000}, + {0x0000a1ec, 0x00000000}, + {0x0000a1f0, 0x00000396}, + {0x0000a1f4, 0x00000396}, + {0x0000a1f8, 0x00000396}, + {0x0000a1fc, 0x00000296}, +}; #endif /* INITVALS_9330_1P2_H */ diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9340_initvals.h b/trunk/drivers/net/wireless/ath/ath9k/ar9340_initvals.h index 1d8235e19f0f..815a8af1beef 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9340_initvals.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9340_initvals.h @@ -1,6 +1,5 @@ /* - * Copyright (c) 2010-2011 Atheros Communications Inc. - * Copyright (c) 2011-2012 Qualcomm Atheros Inc. + * Copyright (c) 2011 Atheros Communications 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 @@ -19,16 +18,16 @@ #define INITVALS_9340_H static const u32 ar9340_1p0_radio_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x000160ac, 0xa4646800, 0xa4646800, 0xa4646800, 0xa4646800}, - {0x0001610c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0001610c, 0x08000000, 0x08000000, 0x00000000, 0x00000000}, {0x00016140, 0x10804000, 0x10804000, 0x50804000, 0x50804000}, - {0x0001650c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0001650c, 0x08000000, 0x08000000, 0x00000000, 0x00000000}, {0x00016540, 0x10804000, 0x10804000, 0x50804000, 0x50804000}, }; static const u32 ar9340Modes_lowest_ob_db_tx_gain_table_1p0[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, @@ -100,10 +99,21 @@ static const u32 ar9340Modes_lowest_ob_db_tx_gain_table_1p0[][5] = { {0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266}, }; -#define ar9340Modes_fast_clock_1p0 ar9300Modes_fast_clock_2p2 +static const u32 ar9340Modes_fast_clock_1p0[][3] = { + /* Addr 5G_HT20 5G_HT40 */ + {0x00001030, 0x00000268, 0x000004d0}, + {0x00001070, 0x0000018c, 0x00000318}, + {0x000010b0, 0x00000fd0, 0x00001fa0}, + {0x00008014, 0x044c044c, 0x08980898}, + {0x0000801c, 0x148ec02b, 0x148ec057}, + {0x00008318, 0x000044c0, 0x00008980}, + {0x00009e00, 0x03721821, 0x03721821}, + {0x0000a230, 0x0000000b, 0x00000016}, + {0x0000a254, 0x00000898, 0x00001130}, +}; static const u32 ar9340_1p0_radio_core[][2] = { - /* Addr allmodes */ + /* Addr allmodes */ {0x00016000, 0x36db6db6}, {0x00016004, 0x6db6db40}, {0x00016008, 0x73f00000}, @@ -136,13 +146,15 @@ static const u32 ar9340_1p0_radio_core[][2] = { {0x00016100, 0x04cb0001}, {0x00016104, 0xfff80000}, {0x00016108, 0x00080010}, + {0x0001610c, 0x00000000}, {0x00016140, 0x50804008}, {0x00016144, 0x01884080}, {0x00016148, 0x000080c0}, {0x00016280, 0x01000015}, - {0x00016284, 0x15530000}, + {0x00016284, 0x05530000}, {0x00016288, 0x00318000}, {0x0001628c, 0x50000000}, + {0x00016290, 0x4080294f}, {0x00016380, 0x00000000}, {0x00016384, 0x00000000}, {0x00016388, 0x00800700}, @@ -207,43 +219,52 @@ static const u32 ar9340_1p0_radio_core[][2] = { }; static const u32 ar9340_1p0_radio_core_40M[][2] = { - /* Addr allmodes */ {0x0001609c, 0x02566f3a}, {0x000160ac, 0xa4647c00}, {0x000160b0, 0x01885f5a}, }; -#define ar9340_1p0_mac_postamble ar9300_2p2_mac_postamble +static const u32 ar9340_1p0_mac_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, + {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, + {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, + {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, + {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, + {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, + {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, + {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, +}; -#define ar9340_1p0_soc_postamble ar9300_2p2_soc_postamble +static const u32 ar9340_1p0_soc_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023}, +}; static const u32 ar9340_1p0_baseband_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, {0x00009820, 0x206a022e, 0x206a022e, 0x206a022e, 0x206a022e}, {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c}, - {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4}, - {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0}, - {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020}, + {0x00009c00, 0x00000044, 0x000000c4, 0x000000c4, 0x00000044}, + {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0}, + {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020}, {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec88d2e, 0x7ec88d2e}, - {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3379605e, 0x33795d5e}, + {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, 0x02291e27, 0x02291e27}, {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012}, {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, - {0x0000a204, 0x00003ec0, 0x00003ec4, 0x00003ec4, 0x00003ec0}, + {0x0000a204, 0x00003fc0, 0x00003fc4, 0x00003fc4, 0x00003fc0}, {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, - {0x0000a22c, 0x07e26a2f, 0x07e26a2f, 0x01026a2f, 0x01026a2f}, {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b}, - {0x0000a234, 0x00000fff, 0x10000fff, 0x10000fff, 0x00000fff}, {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018}, {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, @@ -256,11 +277,11 @@ static const u32 ar9340_1p0_baseband_postamble[][5] = { {0x0000a288, 0x00000220, 0x00000220, 0x00000110, 0x00000110}, {0x0000a28c, 0x00011111, 0x00011111, 0x00022222, 0x00022222}, {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, - {0x0000a2d0, 0x00041983, 0x00041983, 0x00041982, 0x00041982}, - {0x0000a2d8, 0x7999a83a, 0x7999a83a, 0x7999a83a, 0x7999a83a}, + {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071982}, + {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, - {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x001c0000}, + {0x0000ae04, 0x00180000, 0x00180000, 0x00180000, 0x00180000}, {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce}, @@ -268,21 +289,21 @@ static const u32 ar9340_1p0_baseband_postamble[][5] = { }; static const u32 ar9340_1p0_baseband_core[][2] = { - /* Addr allmodes */ + /* Addr allmodes */ {0x00009800, 0xafe68e30}, {0x00009804, 0xfd14e000}, {0x00009808, 0x9c0a9f6b}, {0x0000980c, 0x04900000}, - {0x00009814, 0x3280c00a}, + {0x00009814, 0xb280c00a}, {0x00009818, 0x00000000}, {0x0000981c, 0x00020028}, - {0x00009834, 0x6400a190}, + {0x00009834, 0x5f3ca3de}, {0x00009838, 0x0108ecff}, - {0x0000983c, 0x14000600}, + {0x0000983c, 0x14750600}, {0x00009880, 0x201fff00}, {0x00009884, 0x00001042}, {0x000098a4, 0x00200400}, - {0x000098b0, 0x32840bbe}, + {0x000098b0, 0x52440bbe}, {0x000098d0, 0x004b6a8e}, {0x000098d4, 0x00000820}, {0x000098dc, 0x00000000}, @@ -308,6 +329,7 @@ static const u32 ar9340_1p0_baseband_core[][2] = { {0x00009e30, 0x06336f77}, {0x00009e34, 0x6af6532f}, {0x00009e38, 0x0cc80c00}, + {0x00009e3c, 0xcf946222}, {0x00009e40, 0x0d261820}, {0x00009e4c, 0x00001004}, {0x00009e50, 0x00ff03f1}, @@ -320,6 +342,8 @@ static const u32 ar9340_1p0_baseband_core[][2] = { {0x0000a220, 0x00000000}, {0x0000a224, 0x00000000}, {0x0000a228, 0x10002310}, + {0x0000a22c, 0x01036a1e}, + {0x0000a234, 0x10000fff}, {0x0000a23c, 0x00000000}, {0x0000a244, 0x0c000000}, {0x0000a2a0, 0x00000001}, @@ -327,6 +351,10 @@ static const u32 ar9340_1p0_baseband_core[][2] = { {0x0000a2c8, 0x00000000}, {0x0000a2cc, 0x18c43433}, {0x0000a2d4, 0x00000000}, + {0x0000a2dc, 0x00000000}, + {0x0000a2e0, 0x00000000}, + {0x0000a2e4, 0x00000000}, + {0x0000a2e8, 0x00000000}, {0x0000a2ec, 0x00000000}, {0x0000a2f0, 0x00000000}, {0x0000a2f4, 0x00000000}, @@ -357,7 +385,7 @@ static const u32 ar9340_1p0_baseband_core[][2] = { {0x0000a3e8, 0x20202020}, {0x0000a3ec, 0x20202020}, {0x0000a3f0, 0x00000000}, - {0x0000a3f4, 0x00000000}, + {0x0000a3f4, 0x00000246}, {0x0000a3f8, 0x0cdbd380}, {0x0000a3fc, 0x000f0f01}, {0x0000a400, 0x8fa91f01}, @@ -374,17 +402,33 @@ static const u32 ar9340_1p0_baseband_core[][2] = { {0x0000a430, 0x1ce739ce}, {0x0000a434, 0x00000000}, {0x0000a438, 0x00001801}, - {0x0000a43c, 0x00100000}, + {0x0000a43c, 0x00000000}, {0x0000a440, 0x00000000}, {0x0000a444, 0x00000000}, - {0x0000a448, 0x05000080}, + {0x0000a448, 0x04000080}, {0x0000a44c, 0x00000001}, {0x0000a450, 0x00010000}, {0x0000a458, 0x00000000}, + {0x0000a600, 0x00000000}, + {0x0000a604, 0x00000000}, + {0x0000a608, 0x00000000}, + {0x0000a60c, 0x00000000}, + {0x0000a610, 0x00000000}, + {0x0000a614, 0x00000000}, + {0x0000a618, 0x00000000}, + {0x0000a61c, 0x00000000}, + {0x0000a620, 0x00000000}, + {0x0000a624, 0x00000000}, + {0x0000a628, 0x00000000}, + {0x0000a62c, 0x00000000}, + {0x0000a630, 0x00000000}, + {0x0000a634, 0x00000000}, + {0x0000a638, 0x00000000}, + {0x0000a63c, 0x00000000}, {0x0000a640, 0x00000000}, {0x0000a644, 0x3fad9d74}, {0x0000a648, 0x0048060a}, - {0x0000a64c, 0x00003c37}, + {0x0000a64c, 0x00000637}, {0x0000a670, 0x03020100}, {0x0000a674, 0x09080504}, {0x0000a678, 0x0d0c0b0a}, @@ -407,6 +451,10 @@ static const u32 ar9340_1p0_baseband_core[][2] = { {0x0000a8f4, 0x00000000}, {0x0000b2d0, 0x00000080}, {0x0000b2d4, 0x00000000}, + {0x0000b2dc, 0x00000000}, + {0x0000b2e0, 0x00000000}, + {0x0000b2e4, 0x00000000}, + {0x0000b2e8, 0x00000000}, {0x0000b2ec, 0x00000000}, {0x0000b2f0, 0x00000000}, {0x0000b2f4, 0x00000000}, @@ -417,108 +465,80 @@ static const u32 ar9340_1p0_baseband_core[][2] = { }; static const u32 ar9340Modes_high_power_tx_gain_table_1p0[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, - {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, - {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, - {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, - {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, - {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, - {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501}, - {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03}, - {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, - {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04}, - {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005}, - {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, - {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, - {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, - {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, - {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, - {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, - {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, - {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, - {0x0000a504, 0x04002222, 0x04002222, 0x02000001, 0x02000001}, - {0x0000a508, 0x09002421, 0x09002421, 0x05000003, 0x05000003}, - {0x0000a50c, 0x0d002621, 0x0d002621, 0x0a000005, 0x0a000005}, - {0x0000a510, 0x13004620, 0x13004620, 0x0e000201, 0x0e000201}, - {0x0000a514, 0x19004a20, 0x19004a20, 0x11000203, 0x11000203}, - {0x0000a518, 0x1d004e20, 0x1d004e20, 0x14000401, 0x14000401}, - {0x0000a51c, 0x21005420, 0x21005420, 0x18000403, 0x18000403}, - {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000602, 0x1b000602}, - {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000802, 0x1f000802}, - {0x0000a528, 0x2f005e42, 0x2f005e42, 0x21000620, 0x21000620}, - {0x0000a52c, 0x33005e44, 0x33005e44, 0x25000820, 0x25000820}, - {0x0000a530, 0x38005e65, 0x38005e65, 0x29000822, 0x29000822}, - {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2d000824, 0x2d000824}, - {0x0000a538, 0x40005e6b, 0x40005e6b, 0x30000828, 0x30000828}, - {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x3400082a, 0x3400082a}, - {0x0000a540, 0x49005e72, 0x49005e72, 0x38000849, 0x38000849}, - {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b000a2c, 0x3b000a2c}, - {0x0000a548, 0x53005f12, 0x53005f12, 0x3e000e2b, 0x3e000e2b}, - {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42000e2d, 0x42000e2d}, - {0x0000a550, 0x5e025f12, 0x5e025f12, 0x4500124a, 0x4500124a}, - {0x0000a554, 0x61027f12, 0x61027f12, 0x4900124c, 0x4900124c}, - {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c00126c, 0x4c00126c}, - {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x4f00128c, 0x4f00128c}, - {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x52001290, 0x52001290}, - {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001292, 0x56001292}, - {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001292, 0x56001292}, - {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001292, 0x56001292}, - {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001292, 0x56001292}, - {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001292, 0x56001292}, - {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001292, 0x56001292}, - {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001292, 0x56001292}, + {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, + {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004}, + {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200}, + {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202}, + {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400}, + {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402}, + {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404}, + {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603}, + {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02}, + {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04}, + {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20}, + {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20}, + {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22}, + {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24}, + {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640}, + {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660}, + {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861}, + {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81}, + {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83}, + {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84}, + {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3}, + {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5}, + {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9}, + {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb}, + {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000}, - {0x0000a584, 0x04802222, 0x04802222, 0x02800001, 0x02800001}, - {0x0000a588, 0x09802421, 0x09802421, 0x05800003, 0x05800003}, - {0x0000a58c, 0x0d802621, 0x0d802621, 0x0a800005, 0x0a800005}, - {0x0000a590, 0x13804620, 0x13804620, 0x0e800201, 0x0e800201}, - {0x0000a594, 0x19804a20, 0x19804a20, 0x11800203, 0x11800203}, - {0x0000a598, 0x1d804e20, 0x1d804e20, 0x14800401, 0x14800401}, - {0x0000a59c, 0x21805420, 0x21805420, 0x18800403, 0x18800403}, - {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800602, 0x1b800602}, - {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800802, 0x1f800802}, - {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x21800620, 0x21800620}, - {0x0000a5ac, 0x33805e44, 0x33805e44, 0x25800820, 0x25800820}, - {0x0000a5b0, 0x38805e65, 0x38805e65, 0x29800822, 0x29800822}, - {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2d800824, 0x2d800824}, - {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x30800828, 0x30800828}, - {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x3480082a, 0x3480082a}, - {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38800849, 0x38800849}, - {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b800a2c, 0x3b800a2c}, - {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e800e2b, 0x3e800e2b}, - {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42800e2d, 0x42800e2d}, - {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x4580124a, 0x4580124a}, - {0x0000a5d4, 0x61827f12, 0x61827f12, 0x4980124c, 0x4980124c}, - {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c80126c, 0x4c80126c}, - {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x4f80128c, 0x4f80128c}, - {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x52801290, 0x52801290}, - {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801292, 0x56801292}, - {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801292, 0x56801292}, - {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801292, 0x56801292}, - {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801292, 0x56801292}, - {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801292, 0x56801292}, - {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801292, 0x56801292}, - {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801292, 0x56801292}, - {0x00016044, 0x056db2db, 0x056db2db, 0x022492db, 0x022492db}, + {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002}, + {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004}, + {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200}, + {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202}, + {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400}, + {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402}, + {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404}, + {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603}, + {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02}, + {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04}, + {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20}, + {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20}, + {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22}, + {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24}, + {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640}, + {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660}, + {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861}, + {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81}, + {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83}, + {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84}, + {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3}, + {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5}, + {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9}, + {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb}, + {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x00016044, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db}, {0x00016048, 0x24925266, 0x24925266, 0x24925266, 0x24925266}, - {0x00016444, 0x056db2db, 0x056db2db, 0x022492db, 0x022492db}, + {0x00016444, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db}, {0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266}, }; static const u32 ar9340Modes_high_ob_db_tx_gain_table_1p0[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, - {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, - {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, - {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, @@ -539,7 +559,7 @@ static const u32 ar9340Modes_high_ob_db_tx_gain_table_1p0[][5] = { {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660}, {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861}, {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81}, - {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83}, + {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83}, {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84}, {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3}, {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5}, @@ -584,43 +604,13 @@ static const u32 ar9340Modes_high_ob_db_tx_gain_table_1p0[][5] = { {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000}, - {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000}, - {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501}, - {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501}, - {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03}, - {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04}, - {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04}, - {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, - {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, - {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, - {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x00016044, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4}, - {0x00016048, 0x8e481666, 0x8e481666, 0x8e481266, 0x8e481266}, - {0x00016280, 0x01000015, 0x01000015, 0x01001015, 0x01001015}, + {0x00016048, 0x8e481266, 0x8e481266, 0x8e481266, 0x8e481266}, {0x00016444, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4}, - {0x00016448, 0x8e481666, 0x8e481666, 0x8e481266, 0x8e481266}, + {0x00016448, 0x8e481266, 0x8e481266, 0x8e481266, 0x8e481266}, }; - static const u32 ar9340Modes_ub124_tx_gain_table_1p0[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005}, - {0x00009820, 0x206a022e, 0x206a022e, 0x206a00ae, 0x206a00ae}, - {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c}, - {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec82d2e, 0x7ec82d2e}, - {0x0000a2dc, 0xfef5d402, 0xfef5d402, 0xfdab5b52, 0xfdab5b52}, - {0x0000a2e0, 0xfe896600, 0xfe896600, 0xfd339c84, 0xfd339c84}, - {0x0000a2e4, 0xff01f800, 0xff01f800, 0xfec3e000, 0xfec3e000}, - {0x0000a2e8, 0xfffe0000, 0xfffe0000, 0xfffc0000, 0xfffc0000}, + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, @@ -686,34 +676,15 @@ static const u32 ar9340Modes_ub124_tx_gain_table_1p0[][5] = { {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, - {0x00016044, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4}, - {0x00016048, 0x8e480086, 0x8e480086, 0x8e480086, 0x8e480086}, - {0x00016444, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4}, - {0x00016448, 0x8e480086, 0x8e480086, 0x8e480086, 0x8e480086}, - {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000}, - {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000}, - {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501}, - {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501}, - {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03}, - {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04}, - {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04}, - {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, - {0x0000b2dc, 0xfef5d402, 0xfef5d402, 0xfdab5b52, 0xfdab5b52}, - {0x0000b2e0, 0xfe896600, 0xfe896600, 0xfd339c84, 0xfd339c84}, - {0x0000b2e4, 0xff01f800, 0xff01f800, 0xfec3e000, 0xfec3e000}, - {0x0000b2e8, 0xfffe0000, 0xfffe0000, 0xfffc0000, 0xfffc0000}, + {0x00016044, 0x036db2db, 0x036db2db, 0x036db2db, 0x036db2db}, + {0x00016048, 0x69b65266, 0x69b65266, 0x69b65266, 0x69b65266}, + {0x00016444, 0x036db2db, 0x036db2db, 0x036db2db, 0x036db2db}, + {0x00016448, 0x69b65266, 0x69b65266, 0x69b65266, 0x69b65266}, }; + static const u32 ar9340Common_rx_gain_table_1p0[][2] = { - /* Addr allmodes */ + /* Addr allmodes */ {0x0000a000, 0x00010000}, {0x0000a004, 0x00030002}, {0x0000a008, 0x00050004}, @@ -874,14 +845,14 @@ static const u32 ar9340Common_rx_gain_table_1p0[][2] = { {0x0000b074, 0x00000000}, {0x0000b078, 0x00000000}, {0x0000b07c, 0x00000000}, - {0x0000b080, 0x23232323}, - {0x0000b084, 0x21232323}, - {0x0000b088, 0x19191c1e}, - {0x0000b08c, 0x12141417}, - {0x0000b090, 0x07070e0e}, - {0x0000b094, 0x03030305}, - {0x0000b098, 0x00000003}, - {0x0000b09c, 0x00000000}, + {0x0000b080, 0x32323232}, + {0x0000b084, 0x2f2f3232}, + {0x0000b088, 0x23282a2d}, + {0x0000b08c, 0x1c1e2123}, + {0x0000b090, 0x14171919}, + {0x0000b094, 0x0e0e1214}, + {0x0000b098, 0x03050707}, + {0x0000b09c, 0x00030303}, {0x0000b0a0, 0x00000000}, {0x0000b0a4, 0x00000000}, {0x0000b0a8, 0x00000000}, @@ -973,11 +944,7 @@ static const u32 ar9340Common_rx_gain_table_1p0[][2] = { }; static const u32 ar9340Modes_low_ob_db_tx_gain_table_1p0[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, - {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, - {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, - {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, @@ -985,8 +952,8 @@ static const u32 ar9340Modes_low_ob_db_tx_gain_table_1p0[][5] = { {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400}, - {0x0000a518, 0x21002220, 0x21002220, 0x16000402, 0x16000402}, - {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404}, + {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402}, + {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404}, {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603}, {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02}, {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04}, @@ -998,19 +965,19 @@ static const u32 ar9340Modes_low_ob_db_tx_gain_table_1p0[][5] = { {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861}, {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81}, - {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x47001a83, 0x47001a83}, - {0x0000a550, 0x61024a6c, 0x61024a6c, 0x4a001c84, 0x4a001c84}, - {0x0000a554, 0x66026a6c, 0x66026a6c, 0x4e001ce3, 0x4e001ce3}, - {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x52001ce5, 0x52001ce5}, - {0x0000a55c, 0x7002708c, 0x7002708c, 0x56001ce9, 0x56001ce9}, - {0x0000a560, 0x7302b08a, 0x7302b08a, 0x5a001ceb, 0x5a001ceb}, - {0x0000a564, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, - {0x0000a568, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, - {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, - {0x0000a570, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, - {0x0000a574, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, - {0x0000a578, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, - {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, + {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83}, + {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84}, + {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3}, + {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5}, + {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9}, + {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb}, + {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, + {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, + {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, + {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, + {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, + {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, + {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, @@ -1043,40 +1010,14 @@ static const u32 ar9340Modes_low_ob_db_tx_gain_table_1p0[][5] = { {0x0000a5f4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, {0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, {0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, - {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, - {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, - {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501}, - {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03}, - {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, - {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04}, - {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005}, - {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, - {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, - {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, - {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, - {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, - {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, - {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, - {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x00016044, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db}, - {0x00016048, 0x24925666, 0x24925666, 0x24925266, 0x24925266}, - {0x00016280, 0x01000015, 0x01000015, 0x01001015, 0x01001015}, - {0x00016288, 0xf0318000, 0xf0318000, 0xf0318000, 0xf0318000}, + {0x00016048, 0x24925266, 0x24925266, 0x24925266, 0x24925266}, {0x00016444, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db}, - {0x00016448, 0x24925666, 0x24925666, 0x24925266, 0x24925266}, + {0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266}, }; static const u32 ar9340Modes_mixed_ob_db_tx_gain_table_1p0[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, - {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, - {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, - {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, @@ -1084,8 +1025,8 @@ static const u32 ar9340Modes_mixed_ob_db_tx_gain_table_1p0[][5] = { {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, {0x0000a514, 0x1c000223, 0x1c000223, 0x11000400, 0x11000400}, - {0x0000a518, 0x21002220, 0x21002220, 0x15000402, 0x15000402}, - {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404}, + {0x0000a518, 0x21020220, 0x21020220, 0x15000402, 0x15000402}, + {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404}, {0x0000a520, 0x2b022220, 0x2b022220, 0x1b000603, 0x1b000603}, {0x0000a524, 0x2f022222, 0x2f022222, 0x1f000a02, 0x1f000a02}, {0x0000a528, 0x34022225, 0x34022225, 0x23000a04, 0x23000a04}, @@ -1097,19 +1038,19 @@ static const u32 ar9340Modes_mixed_ob_db_tx_gain_table_1p0[][5] = { {0x0000a540, 0x4e02246c, 0x4e02246c, 0x38001660, 0x38001660}, {0x0000a544, 0x5302266c, 0x5302266c, 0x3b001861, 0x3b001861}, {0x0000a548, 0x5702286c, 0x5702286c, 0x3e001a81, 0x3e001a81}, - {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x42001a83, 0x42001a83}, - {0x0000a550, 0x61024a6c, 0x61024a6c, 0x44001c84, 0x44001c84}, - {0x0000a554, 0x66026a6c, 0x66026a6c, 0x48001ce3, 0x48001ce3}, - {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x4c001ce5, 0x4c001ce5}, - {0x0000a55c, 0x7002708c, 0x7002708c, 0x50001ce9, 0x50001ce9}, - {0x0000a560, 0x7302b08a, 0x7302b08a, 0x54001ceb, 0x54001ceb}, - {0x0000a564, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec}, - {0x0000a568, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec}, - {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec}, - {0x0000a570, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec}, - {0x0000a574, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec}, - {0x0000a578, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec}, - {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec}, + {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x42001a83, 0x42001a83}, + {0x0000a550, 0x61042a6c, 0x61042a6c, 0x44001c84, 0x44001c84}, + {0x0000a554, 0x66062a6c, 0x66062a6c, 0x48001ce3, 0x48001ce3}, + {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x4c001ce5, 0x4c001ce5}, + {0x0000a55c, 0x7006308c, 0x7006308c, 0x50001ce9, 0x50001ce9}, + {0x0000a560, 0x730a308a, 0x730a308a, 0x54001ceb, 0x54001ceb}, + {0x0000a564, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec}, + {0x0000a568, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec}, + {0x0000a56c, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec}, + {0x0000a570, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec}, + {0x0000a574, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec}, + {0x0000a578, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec}, + {0x0000a57c, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec}, {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, @@ -1142,36 +1083,14 @@ static const u32 ar9340Modes_mixed_ob_db_tx_gain_table_1p0[][5] = { {0x0000a5f4, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, {0x0000a5f8, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, {0x0000a5fc, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, - {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, - {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, - {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501}, - {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03}, - {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, - {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04}, - {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005}, - {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, - {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, - {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, - {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, - {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, - {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, - {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, - {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, {0x00016044, 0x056db2db, 0x056db2db, 0x03b6d2e4, 0x03b6d2e4}, - {0x00016048, 0x24925666, 0x24925666, 0x8e481266, 0x8e481266}, - {0x00016280, 0x01000015, 0x01000015, 0x01001015, 0x01001015}, - {0x00016288, 0x30318000, 0x30318000, 0x00318000, 0x00318000}, + {0x00016048, 0x24927266, 0x24927266, 0x8e483266, 0x8e483266}, {0x00016444, 0x056db2db, 0x056db2db, 0x03b6d2e4, 0x03b6d2e4}, - {0x00016448, 0x24925666, 0x24925666, 0x8e481266, 0x8e481266}, + {0x00016448, 0x24927266, 0x24927266, 0x8e482266, 0x8e482266}, }; static const u32 ar9340_1p0_mac_core[][2] = { - /* Addr allmodes */ + /* Addr allmodes */ {0x00000008, 0x00000000}, {0x00000030, 0x00020085}, {0x00000034, 0x00000005}, @@ -1200,7 +1119,6 @@ static const u32 ar9340_1p0_mac_core[][2] = { {0x00008004, 0x00000000}, {0x00008008, 0x00000000}, {0x0000800c, 0x00000000}, - {0x00008010, 0x00080800}, {0x00008018, 0x00000000}, {0x00008020, 0x00000000}, {0x00008038, 0x00000000}, @@ -1228,7 +1146,7 @@ static const u32 ar9340_1p0_mac_core[][2] = { {0x000080bc, 0x00000000}, {0x000080c0, 0x2a800000}, {0x000080c4, 0x06900168}, - {0x000080c8, 0x13881c22}, + {0x000080c8, 0x13881c20}, {0x000080cc, 0x01f40000}, {0x000080d0, 0x00252500}, {0x000080d4, 0x00a00000}, @@ -1332,17 +1250,276 @@ static const u32 ar9340_1p0_mac_core[][2] = { {0x000083c4, 0x00000000}, {0x000083c8, 0x00000000}, {0x000083cc, 0x00000200}, - {0x000083d0, 0x000101ff}, + {0x000083d0, 0x000301ff}, }; -#define ar9340Common_wo_xlna_rx_gain_table_1p0 ar9300Common_wo_xlna_rx_gain_table_2p2 +static const u32 ar9340Common_wo_xlna_rx_gain_table_1p0[][2] = { + /* Addr allmodes */ + {0x0000a000, 0x00010000}, + {0x0000a004, 0x00030002}, + {0x0000a008, 0x00050004}, + {0x0000a00c, 0x00810080}, + {0x0000a010, 0x00830082}, + {0x0000a014, 0x01810180}, + {0x0000a018, 0x01830182}, + {0x0000a01c, 0x01850184}, + {0x0000a020, 0x01890188}, + {0x0000a024, 0x018b018a}, + {0x0000a028, 0x018d018c}, + {0x0000a02c, 0x03820190}, + {0x0000a030, 0x03840383}, + {0x0000a034, 0x03880385}, + {0x0000a038, 0x038a0389}, + {0x0000a03c, 0x038c038b}, + {0x0000a040, 0x0390038d}, + {0x0000a044, 0x03920391}, + {0x0000a048, 0x03940393}, + {0x0000a04c, 0x03960395}, + {0x0000a050, 0x00000000}, + {0x0000a054, 0x00000000}, + {0x0000a058, 0x00000000}, + {0x0000a05c, 0x00000000}, + {0x0000a060, 0x00000000}, + {0x0000a064, 0x00000000}, + {0x0000a068, 0x00000000}, + {0x0000a06c, 0x00000000}, + {0x0000a070, 0x00000000}, + {0x0000a074, 0x00000000}, + {0x0000a078, 0x00000000}, + {0x0000a07c, 0x00000000}, + {0x0000a080, 0x29292929}, + {0x0000a084, 0x29292929}, + {0x0000a088, 0x29292929}, + {0x0000a08c, 0x29292929}, + {0x0000a090, 0x22292929}, + {0x0000a094, 0x1d1d2222}, + {0x0000a098, 0x0c111117}, + {0x0000a09c, 0x00030303}, + {0x0000a0a0, 0x00000000}, + {0x0000a0a4, 0x00000000}, + {0x0000a0a8, 0x00000000}, + {0x0000a0ac, 0x00000000}, + {0x0000a0b0, 0x00000000}, + {0x0000a0b4, 0x00000000}, + {0x0000a0b8, 0x00000000}, + {0x0000a0bc, 0x00000000}, + {0x0000a0c0, 0x001f0000}, + {0x0000a0c4, 0x01000101}, + {0x0000a0c8, 0x011e011f}, + {0x0000a0cc, 0x011c011d}, + {0x0000a0d0, 0x02030204}, + {0x0000a0d4, 0x02010202}, + {0x0000a0d8, 0x021f0200}, + {0x0000a0dc, 0x0302021e}, + {0x0000a0e0, 0x03000301}, + {0x0000a0e4, 0x031e031f}, + {0x0000a0e8, 0x0402031d}, + {0x0000a0ec, 0x04000401}, + {0x0000a0f0, 0x041e041f}, + {0x0000a0f4, 0x0502041d}, + {0x0000a0f8, 0x05000501}, + {0x0000a0fc, 0x051e051f}, + {0x0000a100, 0x06010602}, + {0x0000a104, 0x061f0600}, + {0x0000a108, 0x061d061e}, + {0x0000a10c, 0x07020703}, + {0x0000a110, 0x07000701}, + {0x0000a114, 0x00000000}, + {0x0000a118, 0x00000000}, + {0x0000a11c, 0x00000000}, + {0x0000a120, 0x00000000}, + {0x0000a124, 0x00000000}, + {0x0000a128, 0x00000000}, + {0x0000a12c, 0x00000000}, + {0x0000a130, 0x00000000}, + {0x0000a134, 0x00000000}, + {0x0000a138, 0x00000000}, + {0x0000a13c, 0x00000000}, + {0x0000a140, 0x001f0000}, + {0x0000a144, 0x01000101}, + {0x0000a148, 0x011e011f}, + {0x0000a14c, 0x011c011d}, + {0x0000a150, 0x02030204}, + {0x0000a154, 0x02010202}, + {0x0000a158, 0x021f0200}, + {0x0000a15c, 0x0302021e}, + {0x0000a160, 0x03000301}, + {0x0000a164, 0x031e031f}, + {0x0000a168, 0x0402031d}, + {0x0000a16c, 0x04000401}, + {0x0000a170, 0x041e041f}, + {0x0000a174, 0x0502041d}, + {0x0000a178, 0x05000501}, + {0x0000a17c, 0x051e051f}, + {0x0000a180, 0x06010602}, + {0x0000a184, 0x061f0600}, + {0x0000a188, 0x061d061e}, + {0x0000a18c, 0x07020703}, + {0x0000a190, 0x07000701}, + {0x0000a194, 0x00000000}, + {0x0000a198, 0x00000000}, + {0x0000a19c, 0x00000000}, + {0x0000a1a0, 0x00000000}, + {0x0000a1a4, 0x00000000}, + {0x0000a1a8, 0x00000000}, + {0x0000a1ac, 0x00000000}, + {0x0000a1b0, 0x00000000}, + {0x0000a1b4, 0x00000000}, + {0x0000a1b8, 0x00000000}, + {0x0000a1bc, 0x00000000}, + {0x0000a1c0, 0x00000000}, + {0x0000a1c4, 0x00000000}, + {0x0000a1c8, 0x00000000}, + {0x0000a1cc, 0x00000000}, + {0x0000a1d0, 0x00000000}, + {0x0000a1d4, 0x00000000}, + {0x0000a1d8, 0x00000000}, + {0x0000a1dc, 0x00000000}, + {0x0000a1e0, 0x00000000}, + {0x0000a1e4, 0x00000000}, + {0x0000a1e8, 0x00000000}, + {0x0000a1ec, 0x00000000}, + {0x0000a1f0, 0x00000396}, + {0x0000a1f4, 0x00000396}, + {0x0000a1f8, 0x00000396}, + {0x0000a1fc, 0x00000196}, + {0x0000b000, 0x00010000}, + {0x0000b004, 0x00030002}, + {0x0000b008, 0x00050004}, + {0x0000b00c, 0x00810080}, + {0x0000b010, 0x00830082}, + {0x0000b014, 0x01810180}, + {0x0000b018, 0x01830182}, + {0x0000b01c, 0x01850184}, + {0x0000b020, 0x02810280}, + {0x0000b024, 0x02830282}, + {0x0000b028, 0x02850284}, + {0x0000b02c, 0x02890288}, + {0x0000b030, 0x028b028a}, + {0x0000b034, 0x0388028c}, + {0x0000b038, 0x038a0389}, + {0x0000b03c, 0x038c038b}, + {0x0000b040, 0x0390038d}, + {0x0000b044, 0x03920391}, + {0x0000b048, 0x03940393}, + {0x0000b04c, 0x03960395}, + {0x0000b050, 0x00000000}, + {0x0000b054, 0x00000000}, + {0x0000b058, 0x00000000}, + {0x0000b05c, 0x00000000}, + {0x0000b060, 0x00000000}, + {0x0000b064, 0x00000000}, + {0x0000b068, 0x00000000}, + {0x0000b06c, 0x00000000}, + {0x0000b070, 0x00000000}, + {0x0000b074, 0x00000000}, + {0x0000b078, 0x00000000}, + {0x0000b07c, 0x00000000}, + {0x0000b080, 0x32323232}, + {0x0000b084, 0x2f2f3232}, + {0x0000b088, 0x23282a2d}, + {0x0000b08c, 0x1c1e2123}, + {0x0000b090, 0x14171919}, + {0x0000b094, 0x0e0e1214}, + {0x0000b098, 0x03050707}, + {0x0000b09c, 0x00030303}, + {0x0000b0a0, 0x00000000}, + {0x0000b0a4, 0x00000000}, + {0x0000b0a8, 0x00000000}, + {0x0000b0ac, 0x00000000}, + {0x0000b0b0, 0x00000000}, + {0x0000b0b4, 0x00000000}, + {0x0000b0b8, 0x00000000}, + {0x0000b0bc, 0x00000000}, + {0x0000b0c0, 0x003f0020}, + {0x0000b0c4, 0x00400041}, + {0x0000b0c8, 0x0140005f}, + {0x0000b0cc, 0x0160015f}, + {0x0000b0d0, 0x017e017f}, + {0x0000b0d4, 0x02410242}, + {0x0000b0d8, 0x025f0240}, + {0x0000b0dc, 0x027f0260}, + {0x0000b0e0, 0x0341027e}, + {0x0000b0e4, 0x035f0340}, + {0x0000b0e8, 0x037f0360}, + {0x0000b0ec, 0x04400441}, + {0x0000b0f0, 0x0460045f}, + {0x0000b0f4, 0x0541047f}, + {0x0000b0f8, 0x055f0540}, + {0x0000b0fc, 0x057f0560}, + {0x0000b100, 0x06400641}, + {0x0000b104, 0x0660065f}, + {0x0000b108, 0x067e067f}, + {0x0000b10c, 0x07410742}, + {0x0000b110, 0x075f0740}, + {0x0000b114, 0x077f0760}, + {0x0000b118, 0x07800781}, + {0x0000b11c, 0x07a0079f}, + {0x0000b120, 0x07c107bf}, + {0x0000b124, 0x000007c0}, + {0x0000b128, 0x00000000}, + {0x0000b12c, 0x00000000}, + {0x0000b130, 0x00000000}, + {0x0000b134, 0x00000000}, + {0x0000b138, 0x00000000}, + {0x0000b13c, 0x00000000}, + {0x0000b140, 0x003f0020}, + {0x0000b144, 0x00400041}, + {0x0000b148, 0x0140005f}, + {0x0000b14c, 0x0160015f}, + {0x0000b150, 0x017e017f}, + {0x0000b154, 0x02410242}, + {0x0000b158, 0x025f0240}, + {0x0000b15c, 0x027f0260}, + {0x0000b160, 0x0341027e}, + {0x0000b164, 0x035f0340}, + {0x0000b168, 0x037f0360}, + {0x0000b16c, 0x04400441}, + {0x0000b170, 0x0460045f}, + {0x0000b174, 0x0541047f}, + {0x0000b178, 0x055f0540}, + {0x0000b17c, 0x057f0560}, + {0x0000b180, 0x06400641}, + {0x0000b184, 0x0660065f}, + {0x0000b188, 0x067e067f}, + {0x0000b18c, 0x07410742}, + {0x0000b190, 0x075f0740}, + {0x0000b194, 0x077f0760}, + {0x0000b198, 0x07800781}, + {0x0000b19c, 0x07a0079f}, + {0x0000b1a0, 0x07c107bf}, + {0x0000b1a4, 0x000007c0}, + {0x0000b1a8, 0x00000000}, + {0x0000b1ac, 0x00000000}, + {0x0000b1b0, 0x00000000}, + {0x0000b1b4, 0x00000000}, + {0x0000b1b8, 0x00000000}, + {0x0000b1bc, 0x00000000}, + {0x0000b1c0, 0x00000000}, + {0x0000b1c4, 0x00000000}, + {0x0000b1c8, 0x00000000}, + {0x0000b1cc, 0x00000000}, + {0x0000b1d0, 0x00000000}, + {0x0000b1d4, 0x00000000}, + {0x0000b1d8, 0x00000000}, + {0x0000b1dc, 0x00000000}, + {0x0000b1e0, 0x00000000}, + {0x0000b1e4, 0x00000000}, + {0x0000b1e8, 0x00000000}, + {0x0000b1ec, 0x00000000}, + {0x0000b1f0, 0x00000396}, + {0x0000b1f4, 0x00000396}, + {0x0000b1f8, 0x00000396}, + {0x0000b1fc, 0x00000196}, +}; static const u32 ar9340_1p0_soc_preamble[][2] = { - /* Addr allmodes */ + /* Addr allmodes */ + {0x000040a4, 0x00a0c1c9}, {0x00007008, 0x00000000}, {0x00007020, 0x00000000}, {0x00007034, 0x00000002}, {0x00007038, 0x000004c2}, }; -#endif /* INITVALS_9340_H */ +#endif 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 4ef7dcccaa2f..4a93e1534c1d 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h @@ -1,6 +1,5 @@ /* - * Copyright (c) 2010-2011 Atheros Communications Inc. - * Copyright (c) 2011-2012 Qualcomm Atheros Inc. + * Copyright (c) 2010 Atheros Communications 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 @@ -53,7 +52,7 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = { {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020}, {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000d8}, {0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec86d2e}, - {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3376605e, 0x32395d5e}, + {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3376605e, 0x33795d5e}, {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, @@ -62,7 +61,7 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = { {0x00009e44, 0x62321e27, 0x62321e27, 0xfe291e27, 0xfe291e27}, {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012}, {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, - {0x0000a204, 0x01318fc0, 0x01318fc4, 0x01318fc4, 0x01318fc0}, + {0x0000a204, 0x013187c0, 0x013187c4, 0x013187c4, 0x013187c0}, {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, {0x0000a22c, 0x01026a2f, 0x01026a27, 0x01026a2f, 0x01026a2f}, {0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b}, @@ -1008,7 +1007,7 @@ static const u32 ar9462_2p0_radio_core[][2] = { static const u32 ar9462_2p0_soc_preamble[][2] = { /* Addr allmodes */ - {0x000040a4, 0x00a0c1c9}, + {0x000040a4 ,0x00a0c1c9}, {0x00007020, 0x00000000}, {0x00007034, 0x00000002}, {0x00007038, 0x000004c2}, diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/trunk/drivers/net/wireless/ath/ath9k/ar9485_initvals.h index fb4497fc7a3d..d16d029f81a9 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9485_initvals.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9485_initvals.h @@ -1,6 +1,5 @@ /* * Copyright (c) 2010-2011 Atheros Communications Inc. - * Copyright (c) 2011-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 @@ -18,151 +17,433 @@ #ifndef INITVALS_9485_H #define INITVALS_9485_H -/* AR9485 1.0 */ +static const u32 ar9485_1_1_mac_core[][2] = { + /* Addr allmodes */ + {0x00000008, 0x00000000}, + {0x00000030, 0x00020085}, + {0x00000034, 0x00000005}, + {0x00000040, 0x00000000}, + {0x00000044, 0x00000000}, + {0x00000048, 0x00000008}, + {0x0000004c, 0x00000010}, + {0x00000050, 0x00000000}, + {0x00001040, 0x002ffc0f}, + {0x00001044, 0x002ffc0f}, + {0x00001048, 0x002ffc0f}, + {0x0000104c, 0x002ffc0f}, + {0x00001050, 0x002ffc0f}, + {0x00001054, 0x002ffc0f}, + {0x00001058, 0x002ffc0f}, + {0x0000105c, 0x002ffc0f}, + {0x00001060, 0x002ffc0f}, + {0x00001064, 0x002ffc0f}, + {0x000010f0, 0x00000100}, + {0x00001270, 0x00000000}, + {0x000012b0, 0x00000000}, + {0x000012f0, 0x00000000}, + {0x0000143c, 0x00000000}, + {0x0000147c, 0x00000000}, + {0x00008000, 0x00000000}, + {0x00008004, 0x00000000}, + {0x00008008, 0x00000000}, + {0x0000800c, 0x00000000}, + {0x00008018, 0x00000000}, + {0x00008020, 0x00000000}, + {0x00008038, 0x00000000}, + {0x0000803c, 0x00000000}, + {0x00008040, 0x00000000}, + {0x00008044, 0x00000000}, + {0x00008048, 0x00000000}, + {0x0000804c, 0xffffffff}, + {0x00008054, 0x00000000}, + {0x00008058, 0x00000000}, + {0x0000805c, 0x000fc78f}, + {0x00008060, 0x0000000f}, + {0x00008064, 0x00000000}, + {0x00008070, 0x00000310}, + {0x00008074, 0x00000020}, + {0x00008078, 0x00000000}, + {0x0000809c, 0x0000000f}, + {0x000080a0, 0x00000000}, + {0x000080a4, 0x02ff0000}, + {0x000080a8, 0x0e070605}, + {0x000080ac, 0x0000000d}, + {0x000080b0, 0x00000000}, + {0x000080b4, 0x00000000}, + {0x000080b8, 0x00000000}, + {0x000080bc, 0x00000000}, + {0x000080c0, 0x2a800000}, + {0x000080c4, 0x06900168}, + {0x000080c8, 0x13881c22}, + {0x000080cc, 0x01f40000}, + {0x000080d0, 0x00252500}, + {0x000080d4, 0x00a00000}, + {0x000080d8, 0x00400000}, + {0x000080dc, 0x00000000}, + {0x000080e0, 0xffffffff}, + {0x000080e4, 0x0000ffff}, + {0x000080e8, 0x3f3f3f3f}, + {0x000080ec, 0x00000000}, + {0x000080f0, 0x00000000}, + {0x000080f4, 0x00000000}, + {0x000080fc, 0x00020000}, + {0x00008100, 0x00000000}, + {0x00008108, 0x00000052}, + {0x0000810c, 0x00000000}, + {0x00008110, 0x00000000}, + {0x00008114, 0x000007ff}, + {0x00008118, 0x000000aa}, + {0x0000811c, 0x00003210}, + {0x00008124, 0x00000000}, + {0x00008128, 0x00000000}, + {0x0000812c, 0x00000000}, + {0x00008130, 0x00000000}, + {0x00008134, 0x00000000}, + {0x00008138, 0x00000000}, + {0x0000813c, 0x0000ffff}, + {0x00008144, 0xffffffff}, + {0x00008168, 0x00000000}, + {0x0000816c, 0x00000000}, + {0x00008170, 0x18486200}, + {0x00008174, 0x33332210}, + {0x00008178, 0x00000000}, + {0x0000817c, 0x00020000}, + {0x000081c0, 0x00000000}, + {0x000081c4, 0x33332210}, + {0x000081d4, 0x00000000}, + {0x000081ec, 0x00000000}, + {0x000081f0, 0x00000000}, + {0x000081f4, 0x00000000}, + {0x000081f8, 0x00000000}, + {0x000081fc, 0x00000000}, + {0x00008240, 0x00100000}, + {0x00008244, 0x0010f400}, + {0x00008248, 0x00000800}, + {0x0000824c, 0x0001e800}, + {0x00008250, 0x00000000}, + {0x00008254, 0x00000000}, + {0x00008258, 0x00000000}, + {0x0000825c, 0x40000000}, + {0x00008260, 0x00080922}, + {0x00008264, 0x9ca00010}, + {0x00008268, 0xffffffff}, + {0x0000826c, 0x0000ffff}, + {0x00008270, 0x00000000}, + {0x00008274, 0x40000000}, + {0x00008278, 0x003e4180}, + {0x0000827c, 0x00000004}, + {0x00008284, 0x0000002c}, + {0x00008288, 0x0000002c}, + {0x0000828c, 0x000000ff}, + {0x00008294, 0x00000000}, + {0x00008298, 0x00000000}, + {0x0000829c, 0x00000000}, + {0x00008300, 0x00000140}, + {0x00008314, 0x00000000}, + {0x0000831c, 0x0000010d}, + {0x00008328, 0x00000000}, + {0x0000832c, 0x00000007}, + {0x00008330, 0x00000302}, + {0x00008334, 0x00000700}, + {0x00008338, 0x00ff0000}, + {0x0000833c, 0x02400000}, + {0x00008340, 0x000107ff}, + {0x00008344, 0xa248105b}, + {0x00008348, 0x008f0000}, + {0x0000835c, 0x00000000}, + {0x00008360, 0xffffffff}, + {0x00008364, 0xffffffff}, + {0x00008368, 0x00000000}, + {0x00008370, 0x00000000}, + {0x00008374, 0x000000ff}, + {0x00008378, 0x00000000}, + {0x0000837c, 0x00000000}, + {0x00008380, 0xffffffff}, + {0x00008384, 0xffffffff}, + {0x00008390, 0xffffffff}, + {0x00008394, 0xffffffff}, + {0x00008398, 0x00000000}, + {0x0000839c, 0x00000000}, + {0x000083a0, 0x00000000}, + {0x000083a4, 0x0000fa14}, + {0x000083a8, 0x000f0c00}, + {0x000083ac, 0x33332210}, + {0x000083b0, 0x33332210}, + {0x000083b4, 0x33332210}, + {0x000083b8, 0x33332210}, + {0x000083bc, 0x00000000}, + {0x000083c0, 0x00000000}, + {0x000083c4, 0x00000000}, + {0x000083c8, 0x00000000}, + {0x000083cc, 0x00000200}, + {0x000083d0, 0x000301ff}, +}; + +static const u32 ar9485_1_1_baseband_core[][2] = { + /* Addr allmodes */ + {0x00009800, 0xafe68e30}, + {0x00009804, 0xfd14e000}, + {0x00009808, 0x9c0a8f6b}, + {0x0000980c, 0x04800000}, + {0x00009814, 0x9280c00a}, + {0x00009818, 0x00000000}, + {0x0000981c, 0x00020028}, + {0x00009834, 0x5f3ca3de}, + {0x00009838, 0x0108ecff}, + {0x0000983c, 0x14750600}, + {0x00009880, 0x201fff00}, + {0x00009884, 0x00001042}, + {0x000098a4, 0x00200400}, + {0x000098b0, 0x52440bbe}, + {0x000098d0, 0x004b6a8e}, + {0x000098d4, 0x00000820}, + {0x000098dc, 0x00000000}, + {0x000098f0, 0x00000000}, + {0x000098f4, 0x00000000}, + {0x00009c04, 0x00000000}, + {0x00009c08, 0x03200000}, + {0x00009c0c, 0x00000000}, + {0x00009c10, 0x00000000}, + {0x00009c14, 0x00046384}, + {0x00009c18, 0x05b6b440}, + {0x00009c1c, 0x00b6b440}, + {0x00009d00, 0xc080a333}, + {0x00009d04, 0x40206c10}, + {0x00009d08, 0x009c4060}, + {0x00009d0c, 0x1883800a}, + {0x00009d10, 0x01834061}, + {0x00009d14, 0x00c00400}, + {0x00009d18, 0x00000000}, + {0x00009d1c, 0x00000000}, + {0x00009e08, 0x0038233c}, + {0x00009e24, 0x9927b515}, + {0x00009e28, 0x12ef0200}, + {0x00009e30, 0x06336f77}, + {0x00009e34, 0x6af6532f}, + {0x00009e38, 0x0cc80c00}, + {0x00009e40, 0x0d261820}, + {0x00009e4c, 0x00001004}, + {0x00009e50, 0x00ff03f1}, + {0x00009fc0, 0x80be4788}, + {0x00009fc4, 0x0001efb5}, + {0x00009fcc, 0x40000014}, + {0x0000a20c, 0x00000000}, + {0x0000a210, 0x00000000}, + {0x0000a220, 0x00000000}, + {0x0000a224, 0x00000000}, + {0x0000a228, 0x10002310}, + {0x0000a23c, 0x00000000}, + {0x0000a244, 0x0c000000}, + {0x0000a2a0, 0x00000001}, + {0x0000a2c0, 0x00000001}, + {0x0000a2c8, 0x00000000}, + {0x0000a2cc, 0x18c43433}, + {0x0000a2d4, 0x00000000}, + {0x0000a2dc, 0x00000000}, + {0x0000a2e0, 0x00000000}, + {0x0000a2e4, 0x00000000}, + {0x0000a2e8, 0x00000000}, + {0x0000a2ec, 0x00000000}, + {0x0000a2f0, 0x00000000}, + {0x0000a2f4, 0x00000000}, + {0x0000a2f8, 0x00000000}, + {0x0000a344, 0x00000000}, + {0x0000a34c, 0x00000000}, + {0x0000a350, 0x0000a000}, + {0x0000a364, 0x00000000}, + {0x0000a370, 0x00000000}, + {0x0000a390, 0x00000001}, + {0x0000a394, 0x00000444}, + {0x0000a398, 0x001f0e0f}, + {0x0000a39c, 0x0075393f}, + {0x0000a3a0, 0xb79f6427}, + {0x0000a3a4, 0x000000ff}, + {0x0000a3a8, 0x3b3b3b3b}, + {0x0000a3ac, 0x2f2f2f2f}, + {0x0000a3c0, 0x20202020}, + {0x0000a3c4, 0x22222220}, + {0x0000a3c8, 0x20200020}, + {0x0000a3cc, 0x20202020}, + {0x0000a3d0, 0x20202020}, + {0x0000a3d4, 0x20202020}, + {0x0000a3d8, 0x20202020}, + {0x0000a3dc, 0x20202020}, + {0x0000a3e0, 0x20202020}, + {0x0000a3e4, 0x20202020}, + {0x0000a3e8, 0x20202020}, + {0x0000a3ec, 0x20202020}, + {0x0000a3f0, 0x00000000}, + {0x0000a3f4, 0x00000006}, + {0x0000a3f8, 0x0cdbd380}, + {0x0000a3fc, 0x000f0f01}, + {0x0000a400, 0x8fa91f01}, + {0x0000a404, 0x00000000}, + {0x0000a408, 0x0e79e5c6}, + {0x0000a40c, 0x00820820}, + {0x0000a414, 0x1ce739cf}, + {0x0000a418, 0x2d0019ce}, + {0x0000a41c, 0x1ce739ce}, + {0x0000a420, 0x000001ce}, + {0x0000a424, 0x1ce739ce}, + {0x0000a428, 0x000001ce}, + {0x0000a42c, 0x1ce739ce}, + {0x0000a430, 0x1ce739ce}, + {0x0000a434, 0x00000000}, + {0x0000a438, 0x00001801}, + {0x0000a43c, 0x00000000}, + {0x0000a440, 0x00000000}, + {0x0000a444, 0x00000000}, + {0x0000a448, 0x04000000}, + {0x0000a44c, 0x00000001}, + {0x0000a450, 0x00010000}, + {0x0000a5c4, 0xbfad9d74}, + {0x0000a5c8, 0x0048060a}, + {0x0000a5cc, 0x00000637}, + {0x0000a760, 0x03020100}, + {0x0000a764, 0x09080504}, + {0x0000a768, 0x0d0c0b0a}, + {0x0000a76c, 0x13121110}, + {0x0000a770, 0x31301514}, + {0x0000a774, 0x35343332}, + {0x0000a778, 0x00000036}, + {0x0000a780, 0x00000838}, + {0x0000a7c0, 0x00000000}, + {0x0000a7c4, 0xfffffffc}, + {0x0000a7c8, 0x00000000}, + {0x0000a7cc, 0x00000000}, + {0x0000a7d0, 0x00000000}, + {0x0000a7d4, 0x00000004}, + {0x0000a7dc, 0x00000000}, +}; -#define ar9485_1_1_mac_postamble ar9300_2p2_mac_postamble +static const u32 ar9485Common_1_1[][2] = { + /* Addr allmodes */ + {0x00007010, 0x00000022}, + {0x00007020, 0x00000000}, + {0x00007034, 0x00000002}, + {0x00007038, 0x000004c2}, +}; -static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1[][2] = { - /* Addr allmodes */ - {0x00018c00, 0x18012e5e}, - {0x00018c04, 0x000801d8}, - {0x00018c08, 0x0000080c}, +static const u32 ar9485_1_1_baseband_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005}, + {0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e}, + {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, + {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, + {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, 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}, + {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, + {0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b}, + {0x0000a234, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff}, + {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018}, + {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, + {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, + {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002}, + {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, + {0x0000a260, 0x3a021501, 0x3a021501, 0x3a021501, 0x3a021501}, + {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b}, + {0x0000a284, 0x00000000, 0x00000000, 0x000002a0, 0x000002a0}, + {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, + {0x0000a2d0, 0x00071981, 0x00071981, 0x00071982, 0x00071982}, + {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, + {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000be04, 0x00802020, 0x00802020, 0x00802020, 0x00802020}, + {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, }; -static const u32 ar9485Common_wo_xlna_rx_gain_1_1[][2] = { - /* Addr allmodes */ - {0x0000a000, 0x00060005}, - {0x0000a004, 0x00810080}, - {0x0000a008, 0x00830082}, - {0x0000a00c, 0x00850084}, - {0x0000a010, 0x01820181}, - {0x0000a014, 0x01840183}, - {0x0000a018, 0x01880185}, - {0x0000a01c, 0x018a0189}, - {0x0000a020, 0x02850284}, - {0x0000a024, 0x02890288}, - {0x0000a028, 0x028b028a}, - {0x0000a02c, 0x03850384}, - {0x0000a030, 0x03890388}, - {0x0000a034, 0x038b038a}, - {0x0000a038, 0x038d038c}, - {0x0000a03c, 0x03910390}, - {0x0000a040, 0x03930392}, - {0x0000a044, 0x03950394}, - {0x0000a048, 0x00000396}, - {0x0000a04c, 0x00000000}, - {0x0000a050, 0x00000000}, - {0x0000a054, 0x00000000}, - {0x0000a058, 0x00000000}, - {0x0000a05c, 0x00000000}, - {0x0000a060, 0x00000000}, - {0x0000a064, 0x00000000}, - {0x0000a068, 0x00000000}, - {0x0000a06c, 0x00000000}, - {0x0000a070, 0x00000000}, - {0x0000a074, 0x00000000}, - {0x0000a078, 0x00000000}, - {0x0000a07c, 0x00000000}, - {0x0000a080, 0x28282828}, - {0x0000a084, 0x28282828}, - {0x0000a088, 0x28282828}, - {0x0000a08c, 0x28282828}, - {0x0000a090, 0x28282828}, - {0x0000a094, 0x24242428}, - {0x0000a098, 0x171e1e1e}, - {0x0000a09c, 0x02020b0b}, - {0x0000a0a0, 0x02020202}, - {0x0000a0a4, 0x00000000}, - {0x0000a0a8, 0x00000000}, - {0x0000a0ac, 0x00000000}, - {0x0000a0b0, 0x00000000}, - {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}, - {0x0000a100, 0x66006601}, - {0x0000a104, 0x661e661f}, - {0x0000a108, 0x7703661d}, - {0x0000a10c, 0x77017702}, - {0x0000a110, 0x00007700}, - {0x0000a114, 0x00000000}, - {0x0000a118, 0x00000000}, - {0x0000a11c, 0x00000000}, - {0x0000a120, 0x00000000}, - {0x0000a124, 0x00000000}, - {0x0000a128, 0x00000000}, - {0x0000a12c, 0x00000000}, - {0x0000a130, 0x00000000}, - {0x0000a134, 0x00000000}, - {0x0000a138, 0x00000000}, - {0x0000a13c, 0x00000000}, - {0x0000a140, 0x001f0000}, - {0x0000a144, 0x111f1100}, - {0x0000a148, 0x111d111e}, - {0x0000a14c, 0x111b111c}, - {0x0000a150, 0x22032204}, - {0x0000a154, 0x22012202}, - {0x0000a158, 0x221f2200}, - {0x0000a15c, 0x221d221e}, - {0x0000a160, 0x33013302}, - {0x0000a164, 0x331f3300}, - {0x0000a168, 0x4402331e}, - {0x0000a16c, 0x44004401}, - {0x0000a170, 0x441e441f}, - {0x0000a174, 0x55015502}, - {0x0000a178, 0x551f5500}, - {0x0000a17c, 0x6602551e}, - {0x0000a180, 0x66006601}, - {0x0000a184, 0x661e661f}, - {0x0000a188, 0x7703661d}, - {0x0000a18c, 0x77017702}, - {0x0000a190, 0x00007700}, - {0x0000a194, 0x00000000}, - {0x0000a198, 0x00000000}, - {0x0000a19c, 0x00000000}, - {0x0000a1a0, 0x00000000}, - {0x0000a1a4, 0x00000000}, - {0x0000a1a8, 0x00000000}, - {0x0000a1ac, 0x00000000}, - {0x0000a1b0, 0x00000000}, - {0x0000a1b4, 0x00000000}, - {0x0000a1b8, 0x00000000}, - {0x0000a1bc, 0x00000000}, - {0x0000a1c0, 0x00000000}, - {0x0000a1c4, 0x00000000}, - {0x0000a1c8, 0x00000000}, - {0x0000a1cc, 0x00000000}, - {0x0000a1d0, 0x00000000}, - {0x0000a1d4, 0x00000000}, - {0x0000a1d8, 0x00000000}, - {0x0000a1dc, 0x00000000}, - {0x0000a1e0, 0x00000000}, - {0x0000a1e4, 0x00000000}, - {0x0000a1e8, 0x00000000}, - {0x0000a1ec, 0x00000000}, - {0x0000a1f0, 0x00000396}, - {0x0000a1f4, 0x00000396}, - {0x0000a1f8, 0x00000396}, - {0x0000a1fc, 0x00000296}, +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}, + {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}, + {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}, }; -static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ +static const u32 ar9485_modes_lowest_ob_db_tx_gain_1_1[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, @@ -234,34 +515,29 @@ static const u32 ar9485Modes_high_power_tx_gain_1_1[][5] = { {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, }; -#define ar9485Modes_high_ob_db_tx_gain_1_1 ar9485Modes_high_power_tx_gain_1_1 - -#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 +static const u32 ar9485_1_1_radio_postamble[][2] = { + /* Addr allmodes */ + {0x0001609c, 0x0b283f31}, + {0x000160ac, 0x24611800}, + {0x000160b0, 0x03284f3e}, + {0x0001610c, 0x00170000}, + {0x00016140, 0x50804008}, +}; -static const u32 ar9485_1_1[][2] = { - /* Addr allmodes */ - {0x0000a580, 0x00000000}, - {0x0000a584, 0x00000000}, - {0x0000a588, 0x00000000}, - {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_mac_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, + {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, + {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, + {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, + {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, + {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, + {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, + {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, }; static const u32 ar9485_1_1_radio_core[][2] = { - /* Addr allmodes */ + /* Addr allmodes */ {0x00016000, 0x36db6db6}, {0x00016004, 0x6db6db40}, {0x00016008, 0x73800000}, @@ -325,145 +601,294 @@ static const u32 ar9485_1_1_radio_core[][2] = { {0x00016c44, 0x12000000}, }; -static const u32 ar9485_1_1_baseband_core[][2] = { - /* Addr allmodes */ - {0x00009800, 0xafe68e30}, - {0x00009804, 0xfd14e000}, - {0x00009808, 0x9c0a8f6b}, - {0x0000980c, 0x04800000}, - {0x00009814, 0x9280c00a}, - {0x00009818, 0x00000000}, - {0x0000981c, 0x00020028}, - {0x00009834, 0x5f3ca3de}, - {0x00009838, 0x0108ecff}, - {0x0000983c, 0x14750600}, - {0x00009880, 0x201fff00}, - {0x00009884, 0x00001042}, - {0x000098a4, 0x00200400}, - {0x000098b0, 0x52440bbe}, - {0x000098d0, 0x004b6a8e}, - {0x000098d4, 0x00000820}, - {0x000098dc, 0x00000000}, - {0x000098f0, 0x00000000}, - {0x000098f4, 0x00000000}, - {0x00009c04, 0x00000000}, - {0x00009c08, 0x03200000}, - {0x00009c0c, 0x00000000}, - {0x00009c10, 0x00000000}, - {0x00009c14, 0x00046384}, - {0x00009c18, 0x05b6b440}, - {0x00009c1c, 0x00b6b440}, - {0x00009d00, 0xc080a333}, - {0x00009d04, 0x40206c10}, - {0x00009d08, 0x009c4060}, - {0x00009d0c, 0x1883800a}, - {0x00009d10, 0x01834061}, - {0x00009d14, 0x00c00400}, - {0x00009d18, 0x00000000}, - {0x00009d1c, 0x00000000}, - {0x00009e08, 0x0038233c}, - {0x00009e24, 0x9927b515}, - {0x00009e28, 0x12ef0200}, - {0x00009e30, 0x06336f77}, - {0x00009e34, 0x6af6532f}, - {0x00009e38, 0x0cc80c00}, - {0x00009e40, 0x0d261820}, - {0x00009e4c, 0x00001004}, - {0x00009e50, 0x00ff03f1}, - {0x00009fc0, 0x80be4788}, - {0x00009fc4, 0x0001efb5}, - {0x00009fcc, 0x40000014}, - {0x0000a20c, 0x00000000}, - {0x0000a210, 0x00000000}, - {0x0000a220, 0x00000000}, - {0x0000a224, 0x00000000}, - {0x0000a228, 0x10002310}, - {0x0000a23c, 0x00000000}, - {0x0000a244, 0x0c000000}, - {0x0000a2a0, 0x00000001}, - {0x0000a2c0, 0x00000001}, - {0x0000a2c8, 0x00000000}, - {0x0000a2cc, 0x18c43433}, - {0x0000a2d4, 0x00000000}, - {0x0000a2dc, 0x00000000}, - {0x0000a2e0, 0x00000000}, - {0x0000a2e4, 0x00000000}, - {0x0000a2e8, 0x00000000}, - {0x0000a2ec, 0x00000000}, - {0x0000a2f0, 0x00000000}, - {0x0000a2f4, 0x00000000}, - {0x0000a2f8, 0x00000000}, - {0x0000a344, 0x00000000}, - {0x0000a34c, 0x00000000}, - {0x0000a350, 0x0000a000}, - {0x0000a364, 0x00000000}, - {0x0000a370, 0x00000000}, - {0x0000a390, 0x00000001}, - {0x0000a394, 0x00000444}, - {0x0000a398, 0x001f0e0f}, - {0x0000a39c, 0x0075393f}, - {0x0000a3a0, 0xb79f6427}, - {0x0000a3a4, 0x000000ff}, - {0x0000a3a8, 0x3b3b3b3b}, - {0x0000a3ac, 0x2f2f2f2f}, - {0x0000a3c0, 0x20202020}, - {0x0000a3c4, 0x22222220}, - {0x0000a3c8, 0x20200020}, - {0x0000a3cc, 0x20202020}, - {0x0000a3d0, 0x20202020}, - {0x0000a3d4, 0x20202020}, - {0x0000a3d8, 0x20202020}, - {0x0000a3dc, 0x20202020}, - {0x0000a3e0, 0x20202020}, - {0x0000a3e4, 0x20202020}, - {0x0000a3e8, 0x20202020}, - {0x0000a3ec, 0x20202020}, - {0x0000a3f0, 0x00000000}, - {0x0000a3f4, 0x00000006}, - {0x0000a3f8, 0x0cdbd380}, - {0x0000a3fc, 0x000f0f01}, - {0x0000a400, 0x8fa91f01}, - {0x0000a404, 0x00000000}, - {0x0000a408, 0x0e79e5c6}, - {0x0000a40c, 0x00820820}, - {0x0000a414, 0x1ce739cf}, - {0x0000a418, 0x2d0019ce}, - {0x0000a41c, 0x1ce739ce}, - {0x0000a420, 0x000001ce}, - {0x0000a424, 0x1ce739ce}, - {0x0000a428, 0x000001ce}, - {0x0000a42c, 0x1ce739ce}, - {0x0000a430, 0x1ce739ce}, - {0x0000a434, 0x00000000}, - {0x0000a438, 0x00001801}, - {0x0000a43c, 0x00000000}, - {0x0000a440, 0x00000000}, - {0x0000a444, 0x00000000}, - {0x0000a448, 0x04000000}, - {0x0000a44c, 0x00000001}, - {0x0000a450, 0x00010000}, - {0x0000a5c4, 0xbfad9d74}, - {0x0000a5c8, 0x0048060a}, - {0x0000a5cc, 0x00000637}, - {0x0000a760, 0x03020100}, - {0x0000a764, 0x09080504}, - {0x0000a768, 0x0d0c0b0a}, - {0x0000a76c, 0x13121110}, - {0x0000a770, 0x31301514}, - {0x0000a774, 0x35343332}, - {0x0000a778, 0x00000036}, - {0x0000a780, 0x00000838}, - {0x0000a7c0, 0x00000000}, - {0x0000a7c4, 0xfffffffc}, - {0x0000a7c8, 0x00000000}, - {0x0000a7cc, 0x00000000}, - {0x0000a7d0, 0x00000000}, - {0x0000a7d4, 0x00000004}, - {0x0000a7dc, 0x00000000}, +static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_enable_L1[][2] = { + /* Addr allmodes */ + {0x00018c00, 0x18052e5e}, + {0x00018c04, 0x000801d8}, + {0x00018c08, 0x0000080c}, +}; + +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}, + {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}, + {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}, +}; + +static const u32 ar9485_1_1[][2] = { + /* Addr allmodes */ + {0x0000a580, 0x00000000}, + {0x0000a584, 0x00000000}, + {0x0000a588, 0x00000000}, + {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_modes_green_ob_db_tx_gain_1_1[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x000098bc, 0x00000003, 0x00000003, 0x00000003, 0x00000003}, + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8}, + {0x0000a458, 0x80000000, 0x80000000, 0x80000000, 0x80000000}, + {0x0000a500, 0x00022200, 0x00022200, 0x00000006, 0x00000006}, + {0x0000a504, 0x05062002, 0x05062002, 0x03000201, 0x03000201}, + {0x0000a508, 0x0c002e00, 0x0c002e00, 0x06000203, 0x06000203}, + {0x0000a50c, 0x11062202, 0x11062202, 0x0a000401, 0x0a000401}, + {0x0000a510, 0x17022e00, 0x17022e00, 0x0e000403, 0x0e000403}, + {0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x12000405, 0x12000405}, + {0x0000a518, 0x25020ec0, 0x25020ec0, 0x15000604, 0x15000604}, + {0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x18000605, 0x18000605}, + {0x0000a520, 0x2f001f04, 0x2f001f04, 0x1c000a04, 0x1c000a04}, + {0x0000a524, 0x35001fc4, 0x35001fc4, 0x21000a06, 0x21000a06}, + {0x0000a528, 0x3c022f04, 0x3c022f04, 0x29000a24, 0x29000a24}, + {0x0000a52c, 0x41023e85, 0x41023e85, 0x2f000e21, 0x2f000e21}, + {0x0000a530, 0x48023ec6, 0x48023ec6, 0x31000e20, 0x31000e20}, + {0x0000a534, 0x4d023f01, 0x4d023f01, 0x33000e20, 0x33000e20}, + {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}, + {0x0000b500, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, + {0x0000b504, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, + {0x0000b508, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, + {0x0000b50c, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, + {0x0000b510, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, + {0x0000b514, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, + {0x0000b518, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, + {0x0000b51c, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, + {0x0000b520, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, + {0x0000b524, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, + {0x0000b528, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a}, + {0x0000b52c, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a}, + {0x0000b530, 0x0000003a, 0x0000003a, 0x0000003a, 0x0000003a}, + {0x0000b534, 0x0000004a, 0x0000004a, 0x0000004a, 0x0000004a}, + {0x0000b538, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b53c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b540, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b544, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b548, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b54c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b550, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b554, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b558, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b55c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b560, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b564, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b568, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b56c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b570, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b574, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b578, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x0000b57c, 0x0000005b, 0x0000005b, 0x0000005b, 0x0000005b}, + {0x00016044, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db, 0x05d6b2db}, + {0x00016048, 0x6c924260, 0x6c924260, 0x6c924260, 0x6c924260}, +}; + +static const u32 ar9485_1_1_pcie_phy_clkreq_disable_L1[][2] = { + /* Addr allmodes */ + {0x00018c00, 0x18013e5e}, + {0x00018c04, 0x000801d8}, + {0x00018c08, 0x0000080c}, +}; + +static const u32 ar9485_1_1_soc_preamble[][2] = { + /* Addr allmodes */ + {0x00004014, 0xba280400}, + {0x00004090, 0x00aa10aa}, + {0x000040a4, 0x00a0c9c9}, + {0x00007010, 0x00000022}, + {0x00007020, 0x00000000}, + {0x00007034, 0x00000002}, + {0x00007038, 0x000004c2}, + {0x00007048, 0x00000002}, +}; + +static const u32 ar9485_1_1_baseband_core_txfir_coeff_japan_2484[][2] = { + /* Addr allmodes */ + {0x0000a398, 0x00000000}, + {0x0000a39c, 0x6f7f0301}, + {0x0000a3a0, 0xca9228ee}, +}; + +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}, + {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}, + {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}, +}; + +static const u32 ar9485_fast_clock_1_1_baseband_postamble[][3] = { + /* Addr 5G_HT2 5G_HT40 */ + {0x00009e00, 0x03721821, 0x03721821}, + {0x0000a230, 0x0000400b, 0x00004016}, + {0x0000a254, 0x00000898, 0x00001130}, +}; + +static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1[][2] = { + /* Addr allmodes */ + {0x00018c00, 0x18012e5e}, + {0x00018c04, 0x000801d8}, + {0x00018c08, 0x0000080c}, }; static const u32 ar9485_common_rx_gain_1_1[][2] = { - /* Addr allmodes */ + /* Addr allmodes */ {0x0000a000, 0x00010000}, {0x0000a004, 0x00030002}, {0x0000a008, 0x00050004}, @@ -594,260 +1019,143 @@ static const u32 ar9485_common_rx_gain_1_1[][2] = { {0x0000a1fc, 0x00000296}, }; -static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_enable_L1[][2] = { - /* Addr allmodes */ - {0x00018c00, 0x18052e5e}, - {0x00018c04, 0x000801d8}, - {0x00018c08, 0x0000080c}, -}; - -static const u32 ar9485_1_1_pcie_phy_clkreq_enable_L1[][2] = { - /* Addr allmodes */ - {0x00018c00, 0x18053e5e}, - {0x00018c04, 0x000801d8}, - {0x00018c08, 0x0000080c}, -}; - -static const u32 ar9485_1_1_soc_preamble[][2] = { - /* Addr allmodes */ - {0x00004014, 0xba280400}, - {0x00004090, 0x00aa10aa}, - {0x000040a4, 0x00a0c9c9}, - {0x00007010, 0x00000022}, - {0x00007020, 0x00000000}, - {0x00007034, 0x00000002}, - {0x00007038, 0x000004c2}, - {0x00007048, 0x00000002}, -}; - -static const u32 ar9485_fast_clock_1_1_baseband_postamble[][3] = { - /* Addr 5G_HT20 5G_HT40 */ - {0x00009e00, 0x03721821, 0x03721821}, - {0x0000a230, 0x0000400b, 0x00004016}, - {0x0000a254, 0x00000898, 0x00001130}, -}; - -static const u32 ar9485_1_1_baseband_postamble[][5] = { - /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ - {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005}, - {0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e}, - {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, - {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, - {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, 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}, - {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, - {0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b}, - {0x0000a234, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff}, - {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018}, - {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, - {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, - {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002}, - {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, - {0x0000a260, 0x3a021501, 0x3a021501, 0x3a021501, 0x3a021501}, - {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, - {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b}, - {0x0000a284, 0x00000000, 0x00000000, 0x000002a0, 0x000002a0}, - {0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, - {0x0000a2d0, 0x00071981, 0x00071981, 0x00071982, 0x00071982}, - {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, - {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, - {0x0000be04, 0x00802020, 0x00802020, 0x00802020, 0x00802020}, - {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, -}; - -static const u32 ar9485_1_1_pcie_phy_clkreq_disable_L1[][2] = { - /* Addr allmodes */ - {0x00018c00, 0x18013e5e}, - {0x00018c04, 0x000801d8}, - {0x00018c08, 0x0000080c}, -}; - -static const u32 ar9485_1_1_radio_postamble[][2] = { - /* Addr allmodes */ - {0x0001609c, 0x0b283f31}, - {0x000160ac, 0x24611800}, - {0x000160b0, 0x03284f3e}, - {0x0001610c, 0x00170000}, - {0x00016140, 0x50804008}, -}; - -static const u32 ar9485_1_1_mac_core[][2] = { - /* Addr allmodes */ - {0x00000008, 0x00000000}, - {0x00000030, 0x00020085}, - {0x00000034, 0x00000005}, - {0x00000040, 0x00000000}, - {0x00000044, 0x00000000}, - {0x00000048, 0x00000008}, - {0x0000004c, 0x00000010}, - {0x00000050, 0x00000000}, - {0x00001040, 0x002ffc0f}, - {0x00001044, 0x002ffc0f}, - {0x00001048, 0x002ffc0f}, - {0x0000104c, 0x002ffc0f}, - {0x00001050, 0x002ffc0f}, - {0x00001054, 0x002ffc0f}, - {0x00001058, 0x002ffc0f}, - {0x0000105c, 0x002ffc0f}, - {0x00001060, 0x002ffc0f}, - {0x00001064, 0x002ffc0f}, - {0x000010f0, 0x00000100}, - {0x00001270, 0x00000000}, - {0x000012b0, 0x00000000}, - {0x000012f0, 0x00000000}, - {0x0000143c, 0x00000000}, - {0x0000147c, 0x00000000}, - {0x00008000, 0x00000000}, - {0x00008004, 0x00000000}, - {0x00008008, 0x00000000}, - {0x0000800c, 0x00000000}, - {0x00008018, 0x00000000}, - {0x00008020, 0x00000000}, - {0x00008038, 0x00000000}, - {0x0000803c, 0x00000000}, - {0x00008040, 0x00000000}, - {0x00008044, 0x00000000}, - {0x00008048, 0x00000000}, - {0x0000804c, 0xffffffff}, - {0x00008054, 0x00000000}, - {0x00008058, 0x00000000}, - {0x0000805c, 0x000fc78f}, - {0x00008060, 0x0000000f}, - {0x00008064, 0x00000000}, - {0x00008070, 0x00000310}, - {0x00008074, 0x00000020}, - {0x00008078, 0x00000000}, - {0x0000809c, 0x0000000f}, - {0x000080a0, 0x00000000}, - {0x000080a4, 0x02ff0000}, - {0x000080a8, 0x0e070605}, - {0x000080ac, 0x0000000d}, - {0x000080b0, 0x00000000}, - {0x000080b4, 0x00000000}, - {0x000080b8, 0x00000000}, - {0x000080bc, 0x00000000}, - {0x000080c0, 0x2a800000}, - {0x000080c4, 0x06900168}, - {0x000080c8, 0x13881c22}, - {0x000080cc, 0x01f40000}, - {0x000080d0, 0x00252500}, - {0x000080d4, 0x00a00000}, - {0x000080d8, 0x00400000}, - {0x000080dc, 0x00000000}, - {0x000080e0, 0xffffffff}, - {0x000080e4, 0x0000ffff}, - {0x000080e8, 0x3f3f3f3f}, - {0x000080ec, 0x00000000}, - {0x000080f0, 0x00000000}, - {0x000080f4, 0x00000000}, - {0x000080fc, 0x00020000}, - {0x00008100, 0x00000000}, - {0x00008108, 0x00000052}, - {0x0000810c, 0x00000000}, - {0x00008110, 0x00000000}, - {0x00008114, 0x000007ff}, - {0x00008118, 0x000000aa}, - {0x0000811c, 0x00003210}, - {0x00008124, 0x00000000}, - {0x00008128, 0x00000000}, - {0x0000812c, 0x00000000}, - {0x00008130, 0x00000000}, - {0x00008134, 0x00000000}, - {0x00008138, 0x00000000}, - {0x0000813c, 0x0000ffff}, - {0x00008144, 0xffffffff}, - {0x00008168, 0x00000000}, - {0x0000816c, 0x00000000}, - {0x00008170, 0x18486200}, - {0x00008174, 0x33332210}, - {0x00008178, 0x00000000}, - {0x0000817c, 0x00020000}, - {0x000081c0, 0x00000000}, - {0x000081c4, 0x33332210}, - {0x000081d4, 0x00000000}, - {0x000081ec, 0x00000000}, - {0x000081f0, 0x00000000}, - {0x000081f4, 0x00000000}, - {0x000081f8, 0x00000000}, - {0x000081fc, 0x00000000}, - {0x00008240, 0x00100000}, - {0x00008244, 0x0010f400}, - {0x00008248, 0x00000800}, - {0x0000824c, 0x0001e800}, - {0x00008250, 0x00000000}, - {0x00008254, 0x00000000}, - {0x00008258, 0x00000000}, - {0x0000825c, 0x40000000}, - {0x00008260, 0x00080922}, - {0x00008264, 0x9ca00010}, - {0x00008268, 0xffffffff}, - {0x0000826c, 0x0000ffff}, - {0x00008270, 0x00000000}, - {0x00008274, 0x40000000}, - {0x00008278, 0x003e4180}, - {0x0000827c, 0x00000004}, - {0x00008284, 0x0000002c}, - {0x00008288, 0x0000002c}, - {0x0000828c, 0x000000ff}, - {0x00008294, 0x00000000}, - {0x00008298, 0x00000000}, - {0x0000829c, 0x00000000}, - {0x00008300, 0x00000140}, - {0x00008314, 0x00000000}, - {0x0000831c, 0x0000010d}, - {0x00008328, 0x00000000}, - {0x0000832c, 0x00000007}, - {0x00008330, 0x00000302}, - {0x00008334, 0x00000700}, - {0x00008338, 0x00ff0000}, - {0x0000833c, 0x02400000}, - {0x00008340, 0x000107ff}, - {0x00008344, 0xa248105b}, - {0x00008348, 0x008f0000}, - {0x0000835c, 0x00000000}, - {0x00008360, 0xffffffff}, - {0x00008364, 0xffffffff}, - {0x00008368, 0x00000000}, - {0x00008370, 0x00000000}, - {0x00008374, 0x000000ff}, - {0x00008378, 0x00000000}, - {0x0000837c, 0x00000000}, - {0x00008380, 0xffffffff}, - {0x00008384, 0xffffffff}, - {0x00008390, 0xffffffff}, - {0x00008394, 0xffffffff}, - {0x00008398, 0x00000000}, - {0x0000839c, 0x00000000}, - {0x000083a0, 0x00000000}, - {0x000083a4, 0x0000fa14}, - {0x000083a8, 0x000f0c00}, - {0x000083ac, 0x33332210}, - {0x000083b0, 0x33332210}, - {0x000083b4, 0x33332210}, - {0x000083b8, 0x33332210}, - {0x000083bc, 0x00000000}, - {0x000083c0, 0x00000000}, - {0x000083c4, 0x00000000}, - {0x000083c8, 0x00000000}, - {0x000083cc, 0x00000200}, - {0x000083d0, 0x000301ff}, -}; - -#endif /* INITVALS_9485_H */ +static const u32 ar9485_1_1_pcie_phy_clkreq_enable_L1[][2] = { + /* Addr allmodes */ + {0x00018c00, 0x18053e5e}, + {0x00018c04, 0x000801d8}, + {0x00018c08, 0x0000080c}, +}; + +static const u32 ar9485Common_wo_xlna_rx_gain_1_1[][2] = { + /* Addr allmodes */ + {0x0000a000, 0x00060005}, + {0x0000a004, 0x00810080}, + {0x0000a008, 0x00830082}, + {0x0000a00c, 0x00850084}, + {0x0000a010, 0x01820181}, + {0x0000a014, 0x01840183}, + {0x0000a018, 0x01880185}, + {0x0000a01c, 0x018a0189}, + {0x0000a020, 0x02850284}, + {0x0000a024, 0x02890288}, + {0x0000a028, 0x028b028a}, + {0x0000a02c, 0x03850384}, + {0x0000a030, 0x03890388}, + {0x0000a034, 0x038b038a}, + {0x0000a038, 0x038d038c}, + {0x0000a03c, 0x03910390}, + {0x0000a040, 0x03930392}, + {0x0000a044, 0x03950394}, + {0x0000a048, 0x00000396}, + {0x0000a04c, 0x00000000}, + {0x0000a050, 0x00000000}, + {0x0000a054, 0x00000000}, + {0x0000a058, 0x00000000}, + {0x0000a05c, 0x00000000}, + {0x0000a060, 0x00000000}, + {0x0000a064, 0x00000000}, + {0x0000a068, 0x00000000}, + {0x0000a06c, 0x00000000}, + {0x0000a070, 0x00000000}, + {0x0000a074, 0x00000000}, + {0x0000a078, 0x00000000}, + {0x0000a07c, 0x00000000}, + {0x0000a080, 0x28282828}, + {0x0000a084, 0x28282828}, + {0x0000a088, 0x28282828}, + {0x0000a08c, 0x28282828}, + {0x0000a090, 0x28282828}, + {0x0000a094, 0x24242428}, + {0x0000a098, 0x171e1e1e}, + {0x0000a09c, 0x02020b0b}, + {0x0000a0a0, 0x02020202}, + {0x0000a0a4, 0x00000000}, + {0x0000a0a8, 0x00000000}, + {0x0000a0ac, 0x00000000}, + {0x0000a0b0, 0x00000000}, + {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}, + {0x0000a100, 0x66006601}, + {0x0000a104, 0x661e661f}, + {0x0000a108, 0x7703661d}, + {0x0000a10c, 0x77017702}, + {0x0000a110, 0x00007700}, + {0x0000a114, 0x00000000}, + {0x0000a118, 0x00000000}, + {0x0000a11c, 0x00000000}, + {0x0000a120, 0x00000000}, + {0x0000a124, 0x00000000}, + {0x0000a128, 0x00000000}, + {0x0000a12c, 0x00000000}, + {0x0000a130, 0x00000000}, + {0x0000a134, 0x00000000}, + {0x0000a138, 0x00000000}, + {0x0000a13c, 0x00000000}, + {0x0000a140, 0x001f0000}, + {0x0000a144, 0x111f1100}, + {0x0000a148, 0x111d111e}, + {0x0000a14c, 0x111b111c}, + {0x0000a150, 0x22032204}, + {0x0000a154, 0x22012202}, + {0x0000a158, 0x221f2200}, + {0x0000a15c, 0x221d221e}, + {0x0000a160, 0x33013302}, + {0x0000a164, 0x331f3300}, + {0x0000a168, 0x4402331e}, + {0x0000a16c, 0x44004401}, + {0x0000a170, 0x441e441f}, + {0x0000a174, 0x55015502}, + {0x0000a178, 0x551f5500}, + {0x0000a17c, 0x6602551e}, + {0x0000a180, 0x66006601}, + {0x0000a184, 0x661e661f}, + {0x0000a188, 0x7703661d}, + {0x0000a18c, 0x77017702}, + {0x0000a190, 0x00007700}, + {0x0000a194, 0x00000000}, + {0x0000a198, 0x00000000}, + {0x0000a19c, 0x00000000}, + {0x0000a1a0, 0x00000000}, + {0x0000a1a4, 0x00000000}, + {0x0000a1a8, 0x00000000}, + {0x0000a1ac, 0x00000000}, + {0x0000a1b0, 0x00000000}, + {0x0000a1b4, 0x00000000}, + {0x0000a1b8, 0x00000000}, + {0x0000a1bc, 0x00000000}, + {0x0000a1c0, 0x00000000}, + {0x0000a1c4, 0x00000000}, + {0x0000a1c8, 0x00000000}, + {0x0000a1cc, 0x00000000}, + {0x0000a1d0, 0x00000000}, + {0x0000a1d4, 0x00000000}, + {0x0000a1d8, 0x00000000}, + {0x0000a1dc, 0x00000000}, + {0x0000a1e0, 0x00000000}, + {0x0000a1e4, 0x00000000}, + {0x0000a1e8, 0x00000000}, + {0x0000a1ec, 0x00000000}, + {0x0000a1f0, 0x00000396}, + {0x0000a1f4, 0x00000396}, + {0x0000a1f8, 0x00000396}, + {0x0000a1fc, 0x00000296}, +}; + +#endif diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h b/trunk/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h index 6e1915aee712..06b3f0df9fad 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h @@ -1,6 +1,5 @@ /* - * Copyright (c) 2010-2011 Atheros Communications Inc. - * Copyright (c) 2011-2012 Qualcomm Atheros Inc. + * Copyright (c) 2010 Atheros Communications 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 @@ -20,7 +19,18 @@ /* AR9580 1.0 */ -#define ar9580_1p0_modes_fast_clock ar9300Modes_fast_clock_2p2 +static const u32 ar9580_1p0_modes_fast_clock[][3] = { + /* Addr 5G_HT20 5G_HT40 */ + {0x00001030, 0x00000268, 0x000004d0}, + {0x00001070, 0x0000018c, 0x00000318}, + {0x000010b0, 0x00000fd0, 0x00001fa0}, + {0x00008014, 0x044c044c, 0x08980898}, + {0x0000801c, 0x148ec02b, 0x148ec057}, + {0x00008318, 0x000044c0, 0x00008980}, + {0x00009e00, 0x0372131c, 0x0372131c}, + {0x0000a230, 0x0000000b, 0x00000016}, + {0x0000a254, 0x00000898, 0x00001130}, +}; static const u32 ar9580_1p0_radio_postamble[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ @@ -198,7 +208,17 @@ static const u32 ar9580_1p0_baseband_core[][2] = { {0x0000c420, 0x00000000}, }; -#define ar9580_1p0_mac_postamble ar9300_2p2_mac_postamble +static const u32 ar9580_1p0_mac_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, + {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, + {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, + {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, + {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, + {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, + {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, + {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, +}; static const u32 ar9580_1p0_low_ob_db_tx_gain_table[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ @@ -306,7 +326,111 @@ static const u32 ar9580_1p0_low_ob_db_tx_gain_table[][5] = { {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, }; -#define ar9580_1p0_high_power_tx_gain_table ar9580_1p0_low_ob_db_tx_gain_table +static const u32 ar9580_1p0_high_power_tx_gain_table[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, + {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, + {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, + {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, + {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, + {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, + {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, + {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400}, + {0x0000a518, 0x21002220, 0x21002220, 0x16000402, 0x16000402}, + {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404}, + {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603}, + {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02}, + {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04}, + {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20}, + {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20}, + {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22}, + {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, + {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, + {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, + {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861}, + {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81}, + {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x47001a83, 0x47001a83}, + {0x0000a550, 0x61024a6c, 0x61024a6c, 0x4a001c84, 0x4a001c84}, + {0x0000a554, 0x66026a6c, 0x66026a6c, 0x4e001ce3, 0x4e001ce3}, + {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x52001ce5, 0x52001ce5}, + {0x0000a55c, 0x7002708c, 0x7002708c, 0x56001ce9, 0x56001ce9}, + {0x0000a560, 0x7302b08a, 0x7302b08a, 0x5a001ceb, 0x5a001ceb}, + {0x0000a564, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, + {0x0000a568, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, + {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, + {0x0000a570, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, + {0x0000a574, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, + {0x0000a578, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, + {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec}, + {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, + {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, + {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, + {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, + {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202}, + {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400}, + {0x0000a598, 0x21802220, 0x21802220, 0x16800402, 0x16800402}, + {0x0000a59c, 0x27802223, 0x27802223, 0x19800404, 0x19800404}, + {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603}, + {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02}, + {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04}, + {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20}, + {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20}, + {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22}, + {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, + {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, + {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, + {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861}, + {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81}, + {0x0000a5cc, 0x5c82486b, 0x5c82486b, 0x47801a83, 0x47801a83}, + {0x0000a5d0, 0x61824a6c, 0x61824a6c, 0x4a801c84, 0x4a801c84}, + {0x0000a5d4, 0x66826a6c, 0x66826a6c, 0x4e801ce3, 0x4e801ce3}, + {0x0000a5d8, 0x6b826e6c, 0x6b826e6c, 0x52801ce5, 0x52801ce5}, + {0x0000a5dc, 0x7082708c, 0x7082708c, 0x56801ce9, 0x56801ce9}, + {0x0000a5e0, 0x7382b08a, 0x7382b08a, 0x5a801ceb, 0x5a801ceb}, + {0x0000a5e4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, + {0x0000a5e8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, + {0x0000a5ec, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, + {0x0000a5f0, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, + {0x0000a5f4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, + {0x0000a5f8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, + {0x0000a5fc, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec}, + {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, + {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, + {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501}, + {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03}, + {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, + {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04}, + {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005}, + {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, + {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, + {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, + {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, + {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, + {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, + {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + {0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, + {0x0000c2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, + {0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, + {0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, + {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, + {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, + {0x00016448, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, + {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, + {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, + {0x00016848, 0x66480001, 0x66480001, 0x66480001, 0x66480001}, + {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, +}; static const u32 ar9580_1p0_lowest_ob_db_tx_gain_table[][5] = { /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ @@ -414,7 +538,12 @@ static const u32 ar9580_1p0_lowest_ob_db_tx_gain_table[][5] = { {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, }; -#define ar9580_1p0_baseband_core_txfir_coeff_japan_2484 ar9462_2p0_baseband_core_txfir_coeff_japan_2484 +static const u32 ar9580_1p0_baseband_core_txfir_coeff_japan_2484[][2] = { + /* Addr allmodes */ + {0x0000a398, 0x00000000}, + {0x0000a39c, 0x6f7f0301}, + {0x0000a3a0, 0xca9228ee}, +}; static const u32 ar9580_1p0_mac_core[][2] = { /* Addr allmodes */ @@ -679,11 +808,376 @@ static const u32 ar9580_1p0_mixed_ob_db_tx_gain_table[][5] = { {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, }; -#define ar9580_1p0_wo_xlna_rx_gain_table ar9300Common_wo_xlna_rx_gain_table_2p2 +static const u32 ar9580_1p0_wo_xlna_rx_gain_table[][2] = { + /* Addr allmodes */ + {0x0000a000, 0x00010000}, + {0x0000a004, 0x00030002}, + {0x0000a008, 0x00050004}, + {0x0000a00c, 0x00810080}, + {0x0000a010, 0x00830082}, + {0x0000a014, 0x01810180}, + {0x0000a018, 0x01830182}, + {0x0000a01c, 0x01850184}, + {0x0000a020, 0x01890188}, + {0x0000a024, 0x018b018a}, + {0x0000a028, 0x018d018c}, + {0x0000a02c, 0x03820190}, + {0x0000a030, 0x03840383}, + {0x0000a034, 0x03880385}, + {0x0000a038, 0x038a0389}, + {0x0000a03c, 0x038c038b}, + {0x0000a040, 0x0390038d}, + {0x0000a044, 0x03920391}, + {0x0000a048, 0x03940393}, + {0x0000a04c, 0x03960395}, + {0x0000a050, 0x00000000}, + {0x0000a054, 0x00000000}, + {0x0000a058, 0x00000000}, + {0x0000a05c, 0x00000000}, + {0x0000a060, 0x00000000}, + {0x0000a064, 0x00000000}, + {0x0000a068, 0x00000000}, + {0x0000a06c, 0x00000000}, + {0x0000a070, 0x00000000}, + {0x0000a074, 0x00000000}, + {0x0000a078, 0x00000000}, + {0x0000a07c, 0x00000000}, + {0x0000a080, 0x29292929}, + {0x0000a084, 0x29292929}, + {0x0000a088, 0x29292929}, + {0x0000a08c, 0x29292929}, + {0x0000a090, 0x22292929}, + {0x0000a094, 0x1d1d2222}, + {0x0000a098, 0x0c111117}, + {0x0000a09c, 0x00030303}, + {0x0000a0a0, 0x00000000}, + {0x0000a0a4, 0x00000000}, + {0x0000a0a8, 0x00000000}, + {0x0000a0ac, 0x00000000}, + {0x0000a0b0, 0x00000000}, + {0x0000a0b4, 0x00000000}, + {0x0000a0b8, 0x00000000}, + {0x0000a0bc, 0x00000000}, + {0x0000a0c0, 0x001f0000}, + {0x0000a0c4, 0x01000101}, + {0x0000a0c8, 0x011e011f}, + {0x0000a0cc, 0x011c011d}, + {0x0000a0d0, 0x02030204}, + {0x0000a0d4, 0x02010202}, + {0x0000a0d8, 0x021f0200}, + {0x0000a0dc, 0x0302021e}, + {0x0000a0e0, 0x03000301}, + {0x0000a0e4, 0x031e031f}, + {0x0000a0e8, 0x0402031d}, + {0x0000a0ec, 0x04000401}, + {0x0000a0f0, 0x041e041f}, + {0x0000a0f4, 0x0502041d}, + {0x0000a0f8, 0x05000501}, + {0x0000a0fc, 0x051e051f}, + {0x0000a100, 0x06010602}, + {0x0000a104, 0x061f0600}, + {0x0000a108, 0x061d061e}, + {0x0000a10c, 0x07020703}, + {0x0000a110, 0x07000701}, + {0x0000a114, 0x00000000}, + {0x0000a118, 0x00000000}, + {0x0000a11c, 0x00000000}, + {0x0000a120, 0x00000000}, + {0x0000a124, 0x00000000}, + {0x0000a128, 0x00000000}, + {0x0000a12c, 0x00000000}, + {0x0000a130, 0x00000000}, + {0x0000a134, 0x00000000}, + {0x0000a138, 0x00000000}, + {0x0000a13c, 0x00000000}, + {0x0000a140, 0x001f0000}, + {0x0000a144, 0x01000101}, + {0x0000a148, 0x011e011f}, + {0x0000a14c, 0x011c011d}, + {0x0000a150, 0x02030204}, + {0x0000a154, 0x02010202}, + {0x0000a158, 0x021f0200}, + {0x0000a15c, 0x0302021e}, + {0x0000a160, 0x03000301}, + {0x0000a164, 0x031e031f}, + {0x0000a168, 0x0402031d}, + {0x0000a16c, 0x04000401}, + {0x0000a170, 0x041e041f}, + {0x0000a174, 0x0502041d}, + {0x0000a178, 0x05000501}, + {0x0000a17c, 0x051e051f}, + {0x0000a180, 0x06010602}, + {0x0000a184, 0x061f0600}, + {0x0000a188, 0x061d061e}, + {0x0000a18c, 0x07020703}, + {0x0000a190, 0x07000701}, + {0x0000a194, 0x00000000}, + {0x0000a198, 0x00000000}, + {0x0000a19c, 0x00000000}, + {0x0000a1a0, 0x00000000}, + {0x0000a1a4, 0x00000000}, + {0x0000a1a8, 0x00000000}, + {0x0000a1ac, 0x00000000}, + {0x0000a1b0, 0x00000000}, + {0x0000a1b4, 0x00000000}, + {0x0000a1b8, 0x00000000}, + {0x0000a1bc, 0x00000000}, + {0x0000a1c0, 0x00000000}, + {0x0000a1c4, 0x00000000}, + {0x0000a1c8, 0x00000000}, + {0x0000a1cc, 0x00000000}, + {0x0000a1d0, 0x00000000}, + {0x0000a1d4, 0x00000000}, + {0x0000a1d8, 0x00000000}, + {0x0000a1dc, 0x00000000}, + {0x0000a1e0, 0x00000000}, + {0x0000a1e4, 0x00000000}, + {0x0000a1e8, 0x00000000}, + {0x0000a1ec, 0x00000000}, + {0x0000a1f0, 0x00000396}, + {0x0000a1f4, 0x00000396}, + {0x0000a1f8, 0x00000396}, + {0x0000a1fc, 0x00000196}, + {0x0000b000, 0x00010000}, + {0x0000b004, 0x00030002}, + {0x0000b008, 0x00050004}, + {0x0000b00c, 0x00810080}, + {0x0000b010, 0x00830082}, + {0x0000b014, 0x01810180}, + {0x0000b018, 0x01830182}, + {0x0000b01c, 0x01850184}, + {0x0000b020, 0x02810280}, + {0x0000b024, 0x02830282}, + {0x0000b028, 0x02850284}, + {0x0000b02c, 0x02890288}, + {0x0000b030, 0x028b028a}, + {0x0000b034, 0x0388028c}, + {0x0000b038, 0x038a0389}, + {0x0000b03c, 0x038c038b}, + {0x0000b040, 0x0390038d}, + {0x0000b044, 0x03920391}, + {0x0000b048, 0x03940393}, + {0x0000b04c, 0x03960395}, + {0x0000b050, 0x00000000}, + {0x0000b054, 0x00000000}, + {0x0000b058, 0x00000000}, + {0x0000b05c, 0x00000000}, + {0x0000b060, 0x00000000}, + {0x0000b064, 0x00000000}, + {0x0000b068, 0x00000000}, + {0x0000b06c, 0x00000000}, + {0x0000b070, 0x00000000}, + {0x0000b074, 0x00000000}, + {0x0000b078, 0x00000000}, + {0x0000b07c, 0x00000000}, + {0x0000b080, 0x32323232}, + {0x0000b084, 0x2f2f3232}, + {0x0000b088, 0x23282a2d}, + {0x0000b08c, 0x1c1e2123}, + {0x0000b090, 0x14171919}, + {0x0000b094, 0x0e0e1214}, + {0x0000b098, 0x03050707}, + {0x0000b09c, 0x00030303}, + {0x0000b0a0, 0x00000000}, + {0x0000b0a4, 0x00000000}, + {0x0000b0a8, 0x00000000}, + {0x0000b0ac, 0x00000000}, + {0x0000b0b0, 0x00000000}, + {0x0000b0b4, 0x00000000}, + {0x0000b0b8, 0x00000000}, + {0x0000b0bc, 0x00000000}, + {0x0000b0c0, 0x003f0020}, + {0x0000b0c4, 0x00400041}, + {0x0000b0c8, 0x0140005f}, + {0x0000b0cc, 0x0160015f}, + {0x0000b0d0, 0x017e017f}, + {0x0000b0d4, 0x02410242}, + {0x0000b0d8, 0x025f0240}, + {0x0000b0dc, 0x027f0260}, + {0x0000b0e0, 0x0341027e}, + {0x0000b0e4, 0x035f0340}, + {0x0000b0e8, 0x037f0360}, + {0x0000b0ec, 0x04400441}, + {0x0000b0f0, 0x0460045f}, + {0x0000b0f4, 0x0541047f}, + {0x0000b0f8, 0x055f0540}, + {0x0000b0fc, 0x057f0560}, + {0x0000b100, 0x06400641}, + {0x0000b104, 0x0660065f}, + {0x0000b108, 0x067e067f}, + {0x0000b10c, 0x07410742}, + {0x0000b110, 0x075f0740}, + {0x0000b114, 0x077f0760}, + {0x0000b118, 0x07800781}, + {0x0000b11c, 0x07a0079f}, + {0x0000b120, 0x07c107bf}, + {0x0000b124, 0x000007c0}, + {0x0000b128, 0x00000000}, + {0x0000b12c, 0x00000000}, + {0x0000b130, 0x00000000}, + {0x0000b134, 0x00000000}, + {0x0000b138, 0x00000000}, + {0x0000b13c, 0x00000000}, + {0x0000b140, 0x003f0020}, + {0x0000b144, 0x00400041}, + {0x0000b148, 0x0140005f}, + {0x0000b14c, 0x0160015f}, + {0x0000b150, 0x017e017f}, + {0x0000b154, 0x02410242}, + {0x0000b158, 0x025f0240}, + {0x0000b15c, 0x027f0260}, + {0x0000b160, 0x0341027e}, + {0x0000b164, 0x035f0340}, + {0x0000b168, 0x037f0360}, + {0x0000b16c, 0x04400441}, + {0x0000b170, 0x0460045f}, + {0x0000b174, 0x0541047f}, + {0x0000b178, 0x055f0540}, + {0x0000b17c, 0x057f0560}, + {0x0000b180, 0x06400641}, + {0x0000b184, 0x0660065f}, + {0x0000b188, 0x067e067f}, + {0x0000b18c, 0x07410742}, + {0x0000b190, 0x075f0740}, + {0x0000b194, 0x077f0760}, + {0x0000b198, 0x07800781}, + {0x0000b19c, 0x07a0079f}, + {0x0000b1a0, 0x07c107bf}, + {0x0000b1a4, 0x000007c0}, + {0x0000b1a8, 0x00000000}, + {0x0000b1ac, 0x00000000}, + {0x0000b1b0, 0x00000000}, + {0x0000b1b4, 0x00000000}, + {0x0000b1b8, 0x00000000}, + {0x0000b1bc, 0x00000000}, + {0x0000b1c0, 0x00000000}, + {0x0000b1c4, 0x00000000}, + {0x0000b1c8, 0x00000000}, + {0x0000b1cc, 0x00000000}, + {0x0000b1d0, 0x00000000}, + {0x0000b1d4, 0x00000000}, + {0x0000b1d8, 0x00000000}, + {0x0000b1dc, 0x00000000}, + {0x0000b1e0, 0x00000000}, + {0x0000b1e4, 0x00000000}, + {0x0000b1e8, 0x00000000}, + {0x0000b1ec, 0x00000000}, + {0x0000b1f0, 0x00000396}, + {0x0000b1f4, 0x00000396}, + {0x0000b1f8, 0x00000396}, + {0x0000b1fc, 0x00000196}, +}; -#define ar9580_1p0_soc_postamble ar9300_2p2_soc_postamble +static const u32 ar9580_1p0_soc_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023}, +}; -#define ar9580_1p0_high_ob_db_tx_gain_table ar9300Modes_high_ob_db_tx_gain_table_2p2 +static const u32 ar9580_1p0_high_ob_db_tx_gain_table[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, + {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, + {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, + {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, + {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, + {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004}, + {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200}, + {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202}, + {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400}, + {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402}, + {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404}, + {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603}, + {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02}, + {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04}, + {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20}, + {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20}, + {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22}, + {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24}, + {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640}, + {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660}, + {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861}, + {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81}, + {0x0000a54c, 0x59025eb2, 0x59025eb2, 0x42001a83, 0x42001a83}, + {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84}, + {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3}, + {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5}, + {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9}, + {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb}, + {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec}, + {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000}, + {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002}, + {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004}, + {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200}, + {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202}, + {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400}, + {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402}, + {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404}, + {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603}, + {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02}, + {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04}, + {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20}, + {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20}, + {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22}, + {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24}, + {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640}, + {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660}, + {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861}, + {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81}, + {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83}, + {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84}, + {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3}, + {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5}, + {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9}, + {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb}, + {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec}, + {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000}, + {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000}, + {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501}, + {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501}, + {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03}, + {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04}, + {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04}, + {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, + {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, + {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, + {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, + {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, + {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, + {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, + {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + {0x0000c2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, + {0x0000c2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, + {0x0000c2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, + {0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001}, + {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, + {0x00016444, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, + {0x00016448, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001}, + {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, + {0x00016844, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, + {0x00016848, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001}, + {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, +}; static const u32 ar9580_1p0_soc_preamble[][2] = { /* Addr allmodes */ @@ -695,7 +1189,265 @@ static const u32 ar9580_1p0_soc_preamble[][2] = { {0x00007048, 0x00000008}, }; -#define ar9580_1p0_rx_gain_table ar9462_common_rx_gain_table_2p0 +static const u32 ar9580_1p0_rx_gain_table[][2] = { + /* Addr allmodes */ + {0x0000a000, 0x00010000}, + {0x0000a004, 0x00030002}, + {0x0000a008, 0x00050004}, + {0x0000a00c, 0x00810080}, + {0x0000a010, 0x00830082}, + {0x0000a014, 0x01810180}, + {0x0000a018, 0x01830182}, + {0x0000a01c, 0x01850184}, + {0x0000a020, 0x01890188}, + {0x0000a024, 0x018b018a}, + {0x0000a028, 0x018d018c}, + {0x0000a02c, 0x01910190}, + {0x0000a030, 0x01930192}, + {0x0000a034, 0x01950194}, + {0x0000a038, 0x038a0196}, + {0x0000a03c, 0x038c038b}, + {0x0000a040, 0x0390038d}, + {0x0000a044, 0x03920391}, + {0x0000a048, 0x03940393}, + {0x0000a04c, 0x03960395}, + {0x0000a050, 0x00000000}, + {0x0000a054, 0x00000000}, + {0x0000a058, 0x00000000}, + {0x0000a05c, 0x00000000}, + {0x0000a060, 0x00000000}, + {0x0000a064, 0x00000000}, + {0x0000a068, 0x00000000}, + {0x0000a06c, 0x00000000}, + {0x0000a070, 0x00000000}, + {0x0000a074, 0x00000000}, + {0x0000a078, 0x00000000}, + {0x0000a07c, 0x00000000}, + {0x0000a080, 0x22222229}, + {0x0000a084, 0x1d1d1d1d}, + {0x0000a088, 0x1d1d1d1d}, + {0x0000a08c, 0x1d1d1d1d}, + {0x0000a090, 0x171d1d1d}, + {0x0000a094, 0x11111717}, + {0x0000a098, 0x00030311}, + {0x0000a09c, 0x00000000}, + {0x0000a0a0, 0x00000000}, + {0x0000a0a4, 0x00000000}, + {0x0000a0a8, 0x00000000}, + {0x0000a0ac, 0x00000000}, + {0x0000a0b0, 0x00000000}, + {0x0000a0b4, 0x00000000}, + {0x0000a0b8, 0x00000000}, + {0x0000a0bc, 0x00000000}, + {0x0000a0c0, 0x001f0000}, + {0x0000a0c4, 0x01000101}, + {0x0000a0c8, 0x011e011f}, + {0x0000a0cc, 0x011c011d}, + {0x0000a0d0, 0x02030204}, + {0x0000a0d4, 0x02010202}, + {0x0000a0d8, 0x021f0200}, + {0x0000a0dc, 0x0302021e}, + {0x0000a0e0, 0x03000301}, + {0x0000a0e4, 0x031e031f}, + {0x0000a0e8, 0x0402031d}, + {0x0000a0ec, 0x04000401}, + {0x0000a0f0, 0x041e041f}, + {0x0000a0f4, 0x0502041d}, + {0x0000a0f8, 0x05000501}, + {0x0000a0fc, 0x051e051f}, + {0x0000a100, 0x06010602}, + {0x0000a104, 0x061f0600}, + {0x0000a108, 0x061d061e}, + {0x0000a10c, 0x07020703}, + {0x0000a110, 0x07000701}, + {0x0000a114, 0x00000000}, + {0x0000a118, 0x00000000}, + {0x0000a11c, 0x00000000}, + {0x0000a120, 0x00000000}, + {0x0000a124, 0x00000000}, + {0x0000a128, 0x00000000}, + {0x0000a12c, 0x00000000}, + {0x0000a130, 0x00000000}, + {0x0000a134, 0x00000000}, + {0x0000a138, 0x00000000}, + {0x0000a13c, 0x00000000}, + {0x0000a140, 0x001f0000}, + {0x0000a144, 0x01000101}, + {0x0000a148, 0x011e011f}, + {0x0000a14c, 0x011c011d}, + {0x0000a150, 0x02030204}, + {0x0000a154, 0x02010202}, + {0x0000a158, 0x021f0200}, + {0x0000a15c, 0x0302021e}, + {0x0000a160, 0x03000301}, + {0x0000a164, 0x031e031f}, + {0x0000a168, 0x0402031d}, + {0x0000a16c, 0x04000401}, + {0x0000a170, 0x041e041f}, + {0x0000a174, 0x0502041d}, + {0x0000a178, 0x05000501}, + {0x0000a17c, 0x051e051f}, + {0x0000a180, 0x06010602}, + {0x0000a184, 0x061f0600}, + {0x0000a188, 0x061d061e}, + {0x0000a18c, 0x07020703}, + {0x0000a190, 0x07000701}, + {0x0000a194, 0x00000000}, + {0x0000a198, 0x00000000}, + {0x0000a19c, 0x00000000}, + {0x0000a1a0, 0x00000000}, + {0x0000a1a4, 0x00000000}, + {0x0000a1a8, 0x00000000}, + {0x0000a1ac, 0x00000000}, + {0x0000a1b0, 0x00000000}, + {0x0000a1b4, 0x00000000}, + {0x0000a1b8, 0x00000000}, + {0x0000a1bc, 0x00000000}, + {0x0000a1c0, 0x00000000}, + {0x0000a1c4, 0x00000000}, + {0x0000a1c8, 0x00000000}, + {0x0000a1cc, 0x00000000}, + {0x0000a1d0, 0x00000000}, + {0x0000a1d4, 0x00000000}, + {0x0000a1d8, 0x00000000}, + {0x0000a1dc, 0x00000000}, + {0x0000a1e0, 0x00000000}, + {0x0000a1e4, 0x00000000}, + {0x0000a1e8, 0x00000000}, + {0x0000a1ec, 0x00000000}, + {0x0000a1f0, 0x00000396}, + {0x0000a1f4, 0x00000396}, + {0x0000a1f8, 0x00000396}, + {0x0000a1fc, 0x00000196}, + {0x0000b000, 0x00010000}, + {0x0000b004, 0x00030002}, + {0x0000b008, 0x00050004}, + {0x0000b00c, 0x00810080}, + {0x0000b010, 0x00830082}, + {0x0000b014, 0x01810180}, + {0x0000b018, 0x01830182}, + {0x0000b01c, 0x01850184}, + {0x0000b020, 0x02810280}, + {0x0000b024, 0x02830282}, + {0x0000b028, 0x02850284}, + {0x0000b02c, 0x02890288}, + {0x0000b030, 0x028b028a}, + {0x0000b034, 0x0388028c}, + {0x0000b038, 0x038a0389}, + {0x0000b03c, 0x038c038b}, + {0x0000b040, 0x0390038d}, + {0x0000b044, 0x03920391}, + {0x0000b048, 0x03940393}, + {0x0000b04c, 0x03960395}, + {0x0000b050, 0x00000000}, + {0x0000b054, 0x00000000}, + {0x0000b058, 0x00000000}, + {0x0000b05c, 0x00000000}, + {0x0000b060, 0x00000000}, + {0x0000b064, 0x00000000}, + {0x0000b068, 0x00000000}, + {0x0000b06c, 0x00000000}, + {0x0000b070, 0x00000000}, + {0x0000b074, 0x00000000}, + {0x0000b078, 0x00000000}, + {0x0000b07c, 0x00000000}, + {0x0000b080, 0x2a2d2f32}, + {0x0000b084, 0x21232328}, + {0x0000b088, 0x19191c1e}, + {0x0000b08c, 0x12141417}, + {0x0000b090, 0x07070e0e}, + {0x0000b094, 0x03030305}, + {0x0000b098, 0x00000003}, + {0x0000b09c, 0x00000000}, + {0x0000b0a0, 0x00000000}, + {0x0000b0a4, 0x00000000}, + {0x0000b0a8, 0x00000000}, + {0x0000b0ac, 0x00000000}, + {0x0000b0b0, 0x00000000}, + {0x0000b0b4, 0x00000000}, + {0x0000b0b8, 0x00000000}, + {0x0000b0bc, 0x00000000}, + {0x0000b0c0, 0x003f0020}, + {0x0000b0c4, 0x00400041}, + {0x0000b0c8, 0x0140005f}, + {0x0000b0cc, 0x0160015f}, + {0x0000b0d0, 0x017e017f}, + {0x0000b0d4, 0x02410242}, + {0x0000b0d8, 0x025f0240}, + {0x0000b0dc, 0x027f0260}, + {0x0000b0e0, 0x0341027e}, + {0x0000b0e4, 0x035f0340}, + {0x0000b0e8, 0x037f0360}, + {0x0000b0ec, 0x04400441}, + {0x0000b0f0, 0x0460045f}, + {0x0000b0f4, 0x0541047f}, + {0x0000b0f8, 0x055f0540}, + {0x0000b0fc, 0x057f0560}, + {0x0000b100, 0x06400641}, + {0x0000b104, 0x0660065f}, + {0x0000b108, 0x067e067f}, + {0x0000b10c, 0x07410742}, + {0x0000b110, 0x075f0740}, + {0x0000b114, 0x077f0760}, + {0x0000b118, 0x07800781}, + {0x0000b11c, 0x07a0079f}, + {0x0000b120, 0x07c107bf}, + {0x0000b124, 0x000007c0}, + {0x0000b128, 0x00000000}, + {0x0000b12c, 0x00000000}, + {0x0000b130, 0x00000000}, + {0x0000b134, 0x00000000}, + {0x0000b138, 0x00000000}, + {0x0000b13c, 0x00000000}, + {0x0000b140, 0x003f0020}, + {0x0000b144, 0x00400041}, + {0x0000b148, 0x0140005f}, + {0x0000b14c, 0x0160015f}, + {0x0000b150, 0x017e017f}, + {0x0000b154, 0x02410242}, + {0x0000b158, 0x025f0240}, + {0x0000b15c, 0x027f0260}, + {0x0000b160, 0x0341027e}, + {0x0000b164, 0x035f0340}, + {0x0000b168, 0x037f0360}, + {0x0000b16c, 0x04400441}, + {0x0000b170, 0x0460045f}, + {0x0000b174, 0x0541047f}, + {0x0000b178, 0x055f0540}, + {0x0000b17c, 0x057f0560}, + {0x0000b180, 0x06400641}, + {0x0000b184, 0x0660065f}, + {0x0000b188, 0x067e067f}, + {0x0000b18c, 0x07410742}, + {0x0000b190, 0x075f0740}, + {0x0000b194, 0x077f0760}, + {0x0000b198, 0x07800781}, + {0x0000b19c, 0x07a0079f}, + {0x0000b1a0, 0x07c107bf}, + {0x0000b1a4, 0x000007c0}, + {0x0000b1a8, 0x00000000}, + {0x0000b1ac, 0x00000000}, + {0x0000b1b0, 0x00000000}, + {0x0000b1b4, 0x00000000}, + {0x0000b1b8, 0x00000000}, + {0x0000b1bc, 0x00000000}, + {0x0000b1c0, 0x00000000}, + {0x0000b1c4, 0x00000000}, + {0x0000b1c8, 0x00000000}, + {0x0000b1cc, 0x00000000}, + {0x0000b1d0, 0x00000000}, + {0x0000b1d4, 0x00000000}, + {0x0000b1d8, 0x00000000}, + {0x0000b1dc, 0x00000000}, + {0x0000b1e0, 0x00000000}, + {0x0000b1e4, 0x00000000}, + {0x0000b1e8, 0x00000000}, + {0x0000b1ec, 0x00000000}, + {0x0000b1f0, 0x00000396}, + {0x0000b1f4, 0x00000396}, + {0x0000b1f8, 0x00000396}, + {0x0000b1fc, 0x00000196}, +}; static const u32 ar9580_1p0_radio_core[][2] = { /* Addr allmodes */ diff --git a/trunk/drivers/net/wireless/ath/ath9k/ath9k.h b/trunk/drivers/net/wireless/ath/ath9k/ath9k.h index fe39eb4c42a1..02fc1c1e5eeb 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ath9k.h @@ -214,7 +214,6 @@ struct ath_frame_info { enum ath9k_key_type keytype; u8 keyix; u8 retries; - u8 rtscts_rate; }; struct ath_buf_state { @@ -699,7 +698,6 @@ struct ath_softc { #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT struct ath_btcoex btcoex; struct ath_mci_coex mci_coex; - struct work_struct mci_work; #endif struct ath_descdma txsdma; @@ -722,7 +720,6 @@ extern int ath9k_modparam_nohwcrypt; extern int led_blink; extern bool is_ath9k_unloaded; -u8 ath9k_parse_mpdudensity(u8 mpdudensity); irqreturn_t ath_isr(int irq, void *dev); int ath9k_init_device(u16 devid, struct ath_softc *sc, const struct ath_bus_ops *bus_ops); diff --git a/trunk/drivers/net/wireless/ath/ath9k/debug.c b/trunk/drivers/net/wireless/ath/ath9k/debug.c index 5c3192ffc196..2831258d9507 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/debug.c +++ b/trunk/drivers/net/wireless/ath/ath9k/debug.c @@ -348,6 +348,8 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status) sc->debug.stats.istats.txok++; if (status & ATH9K_INT_TXURN) sc->debug.stats.istats.txurn++; + if (status & ATH9K_INT_MIB) + sc->debug.stats.istats.mib++; if (status & ATH9K_INT_RXPHY) sc->debug.stats.istats.rxphyerr++; if (status & ATH9K_INT_RXKCM) diff --git a/trunk/drivers/net/wireless/ath/ath9k/gpio.c b/trunk/drivers/net/wireless/ath/ath9k/gpio.c index 9ae6a4d97691..af6d27350291 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/gpio.c +++ b/trunk/drivers/net/wireless/ath/ath9k/gpio.c @@ -202,7 +202,7 @@ static void ath_btcoex_period_timer(unsigned long data) btcoex->bt_wait_time += btcoex->btcoex_period; if (btcoex->bt_wait_time > ATH_BTCOEX_RX_WAIT_TIME) { - if (ar9003_mci_state(ah, MCI_STATE_NEED_FTP_STOMP) && + if (ar9003_mci_state(ah, MCI_STATE_NEED_FTP_STOMP, NULL) && (mci->num_pan || mci->num_other_acl)) ah->btcoex_hw.mci.stomp_ftp = (sc->rx.num_pkts < ATH_BTCOEX_STOMP_FTP_THRESH); @@ -232,7 +232,7 @@ static void ath_btcoex_period_timer(unsigned long data) } ath9k_ps_restore(sc); - timer_period = btcoex->btcoex_period; + timer_period = btcoex->btcoex_period / 1000; mod_timer(&btcoex->period_timer, jiffies + msecs_to_jiffies(timer_period)); } @@ -267,10 +267,10 @@ static int ath_init_btcoex_timer(struct ath_softc *sc) { struct ath_btcoex *btcoex = &sc->btcoex; - btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD; - btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * 1000 * + btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000; + btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * btcoex->btcoex_period / 100; - btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) * 1000 * + btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) * btcoex->btcoex_period / 100; setup_timer(&btcoex->period_timer, ath_btcoex_period_timer, @@ -416,7 +416,7 @@ int ath9k_init_btcoex(struct ath_softc *sc) 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)) { + if (AR_SREV_9462(ah)) { sc->btcoex.duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE; INIT_LIST_HEAD(&sc->btcoex.mci.info); diff --git a/trunk/drivers/net/wireless/ath/ath9k/htc.h b/trunk/drivers/net/wireless/ath/ath9k/htc.h index 936e920fb88e..135795257d95 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc.h +++ b/trunk/drivers/net/wireless/ath/ath9k/htc.h @@ -453,6 +453,7 @@ struct ath9k_htc_priv { u8 num_sta_assoc_vif; u8 num_ap_vif; + u16 op_flags; u16 curtxpow; u16 txpowlimit; u16 nvifs; @@ -460,7 +461,6 @@ struct ath9k_htc_priv { bool rearm_ani; bool reconfig_beacon; unsigned int rxfilter; - unsigned long op_flags; struct ath9k_hw_cal_data caldata; struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; @@ -572,6 +572,8 @@ bool ath9k_htc_setpower(struct ath9k_htc_priv *priv, void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv); void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw); +void ath9k_htc_radio_enable(struct ieee80211_hw *hw); +void ath9k_htc_radio_disable(struct ieee80211_hw *hw); #ifdef CONFIG_MAC80211_LEDS void ath9k_init_leds(struct ath9k_htc_priv *priv); 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 77d541feb910..2eadffb7971c 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c @@ -207,9 +207,9 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, else priv->ah->config.sw_beacon_response_time = MIN_SWBA_RESPONSE; - if (test_bit(OP_TSF_RESET, &priv->op_flags)) { + if (priv->op_flags & OP_TSF_RESET) { ath9k_hw_reset_tsf(priv->ah); - clear_bit(OP_TSF_RESET, &priv->op_flags); + priv->op_flags &= ~OP_TSF_RESET; } else { /* * Pull nexttbtt forward to reflect the current TSF. @@ -221,7 +221,7 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, } while (nexttbtt < tsftu); } - if (test_bit(OP_ENABLE_BEACON, &priv->op_flags)) + if (priv->op_flags & OP_ENABLE_BEACON) imask |= ATH9K_INT_SWBA; ath_dbg(common, CONFIG, @@ -269,7 +269,7 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv, else priv->ah->config.sw_beacon_response_time = MIN_SWBA_RESPONSE; - if (test_bit(OP_ENABLE_BEACON, &priv->op_flags)) + if (priv->op_flags & OP_ENABLE_BEACON) imask |= ATH9K_INT_SWBA; ath_dbg(common, CONFIG, @@ -365,7 +365,7 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv, vif = priv->cur_beacon_conf.bslot[slot]; avp = (struct ath9k_htc_vif *)vif->drv_priv; - if (unlikely(test_bit(OP_SCANNING, &priv->op_flags))) { + if (unlikely(priv->op_flags & OP_SCANNING)) { spin_unlock_bh(&priv->beacon_lock); return; } 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 07df279c8d46..1c10e2e5c237 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c @@ -37,18 +37,17 @@ static void ath_detect_bt_priority(struct ath9k_htc_priv *priv) if (time_after(jiffies, btcoex->bt_priority_time + msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) { - clear_bit(OP_BT_PRIORITY_DETECTED, &priv->op_flags); - clear_bit(OP_BT_SCAN, &priv->op_flags); + priv->op_flags &= ~(OP_BT_PRIORITY_DETECTED | OP_BT_SCAN); /* Detect if colocated bt started scanning */ if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) { ath_dbg(ath9k_hw_common(ah), BTCOEX, "BT scan detected\n"); - set_bit(OP_BT_PRIORITY_DETECTED, &priv->op_flags); - set_bit(OP_BT_SCAN, &priv->op_flags); + priv->op_flags |= (OP_BT_SCAN | + OP_BT_PRIORITY_DETECTED); } else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) { ath_dbg(ath9k_hw_common(ah), BTCOEX, "BT priority traffic detected\n"); - set_bit(OP_BT_PRIORITY_DETECTED, &priv->op_flags); + priv->op_flags |= OP_BT_PRIORITY_DETECTED; } btcoex->bt_priority_cnt = 0; @@ -68,23 +67,26 @@ static void ath_btcoex_period_work(struct work_struct *work) struct ath_btcoex *btcoex = &priv->btcoex; struct ath_common *common = ath9k_hw_common(priv->ah); u32 timer_period; + bool is_btscan; int ret; ath_detect_bt_priority(priv); + is_btscan = !!(priv->op_flags & OP_BT_SCAN); + ret = ath9k_htc_update_cap_target(priv, - test_bit(OP_BT_PRIORITY_DETECTED, &priv->op_flags)); + !!(priv->op_flags & OP_BT_PRIORITY_DETECTED)); if (ret) { ath_err(common, "Unable to set BTCOEX parameters\n"); return; } - ath9k_hw_btcoex_bt_stomp(priv->ah, test_bit(OP_BT_SCAN, &priv->op_flags) ? - ATH_BTCOEX_STOMP_ALL : btcoex->bt_stomp_type); + ath9k_hw_btcoex_bt_stomp(priv->ah, is_btscan ? ATH_BTCOEX_STOMP_ALL : + btcoex->bt_stomp_type); ath9k_hw_btcoex_enable(priv->ah); - timer_period = test_bit(OP_BT_SCAN, &priv->op_flags) ? - btcoex->btscan_no_stomp : btcoex->btcoex_no_stomp; + timer_period = is_btscan ? btcoex->btscan_no_stomp : + btcoex->btcoex_no_stomp; ieee80211_queue_delayed_work(priv->hw, &priv->duty_cycle_work, msecs_to_jiffies(timer_period)); ieee80211_queue_delayed_work(priv->hw, &priv->coex_period_work, @@ -102,15 +104,14 @@ static void ath_btcoex_duty_cycle_work(struct work_struct *work) struct ath_hw *ah = priv->ah; struct ath_btcoex *btcoex = &priv->btcoex; struct ath_common *common = ath9k_hw_common(ah); + bool is_btscan = priv->op_flags & OP_BT_SCAN; ath_dbg(common, BTCOEX, "time slice work for bt and wlan\n"); - if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || - test_bit(OP_BT_SCAN, &priv->op_flags)) + if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan) ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW); - ath9k_hw_btcoex_enable(priv->ah); } @@ -140,8 +141,7 @@ static void ath_htc_resume_btcoex_work(struct ath9k_htc_priv *priv) btcoex->bt_priority_cnt = 0; btcoex->bt_priority_time = jiffies; - clear_bit(OP_BT_PRIORITY_DETECTED, &priv->op_flags); - clear_bit(OP_BT_SCAN, &priv->op_flags); + priv->op_flags &= ~(OP_BT_PRIORITY_DETECTED | OP_BT_SCAN); ieee80211_queue_delayed_work(priv->hw, &priv->coex_period_work, 0); } @@ -310,3 +310,95 @@ void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv) if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) wiphy_rfkill_start_polling(priv->hw->wiphy); } + +void ath9k_htc_radio_enable(struct ieee80211_hw *hw) +{ + struct ath9k_htc_priv *priv = hw->priv; + struct ath_hw *ah = priv->ah; + struct ath_common *common = ath9k_hw_common(ah); + int ret; + u8 cmd_rsp; + + if (!ah->curchan) + ah->curchan = ath9k_cmn_get_curchannel(hw, ah); + + /* Reset the HW */ + ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); + if (ret) { + ath_err(common, + "Unable to reset hardware; reset status %d (freq %u MHz)\n", + ret, ah->curchan->channel); + } + + ath9k_cmn_update_txpow(ah, priv->curtxpow, priv->txpowlimit, + &priv->curtxpow); + + /* Start RX */ + WMI_CMD(WMI_START_RECV_CMDID); + ath9k_host_rx_init(priv); + + /* Start TX */ + htc_start(priv->htc); + spin_lock_bh(&priv->tx.tx_lock); + priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP; + spin_unlock_bh(&priv->tx.tx_lock); + ieee80211_wake_queues(hw); + + WMI_CMD(WMI_ENABLE_INTR_CMDID); + + /* Enable LED */ + ath9k_hw_cfg_output(ah, ah->led_pin, + AR_GPIO_OUTPUT_MUX_AS_OUTPUT); + ath9k_hw_set_gpio(ah, ah->led_pin, 0); +} + +void ath9k_htc_radio_disable(struct ieee80211_hw *hw) +{ + struct ath9k_htc_priv *priv = hw->priv; + struct ath_hw *ah = priv->ah; + struct ath_common *common = ath9k_hw_common(ah); + int ret; + u8 cmd_rsp; + + ath9k_htc_ps_wakeup(priv); + + /* Disable LED */ + ath9k_hw_set_gpio(ah, ah->led_pin, 1); + ath9k_hw_cfg_gpio_input(ah, ah->led_pin); + + WMI_CMD(WMI_DISABLE_INTR_CMDID); + + /* Stop TX */ + ieee80211_stop_queues(hw); + ath9k_htc_tx_drain(priv); + WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); + + /* Stop RX */ + WMI_CMD(WMI_STOP_RECV_CMDID); + + /* Clear the WMI event queue */ + ath9k_wmi_event_drain(priv); + + /* + * The MIB counters have to be disabled here, + * since the target doesn't do it. + */ + ath9k_hw_disable_mib_counters(ah); + + if (!ah->curchan) + ah->curchan = ath9k_cmn_get_curchannel(hw, ah); + + /* Reset the HW */ + ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false); + if (ret) { + ath_err(common, + "Unable to reset hardware; reset status %d (freq %u MHz)\n", + ret, ah->curchan->channel); + } + + /* Disable the PHY */ + ath9k_hw_phy_disable(ah); + + ath9k_htc_ps_restore(priv); + ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP); +} 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 a035a380d669..25213d521bc2 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -611,7 +611,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, struct ath_common *common; int i, ret = 0, csz = 0; - set_bit(OP_INVALID, &priv->op_flags); + priv->op_flags |= OP_INVALID; ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL); if (!ah) @@ -718,7 +718,7 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, hw->queues = 4; hw->channel_change_time = 5000; - hw->max_listen_interval = 1; + hw->max_listen_interval = 10; hw->vif_data_size = sizeof(struct ath9k_htc_vif); hw->sta_data_size = sizeof(struct ath9k_htc_sta); 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 374c32ed905a..2b8f61c210e1 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -75,19 +75,14 @@ void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv) void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv) { - bool reset; - mutex_lock(&priv->htc_pm_lock); if (--priv->ps_usecount != 0) goto unlock; - if (priv->ps_idle) { - ath9k_hw_setrxabort(priv->ah, true); - ath9k_hw_stopdmarecv(priv->ah, &reset); + if (priv->ps_idle) ath9k_hw_setpower(priv->ah, ATH9K_PM_FULL_SLEEP); - } else if (priv->ps_enabled) { + else if (priv->ps_enabled) ath9k_hw_setpower(priv->ah, ATH9K_PM_NETWORK_SLEEP); - } unlock: mutex_unlock(&priv->htc_pm_lock); @@ -255,7 +250,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, u8 cmd_rsp; int ret; - if (test_bit(OP_INVALID, &priv->op_flags)) + if (priv->op_flags & OP_INVALID) return -EIO; fastcc = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL); @@ -309,7 +304,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, htc_start(priv->htc); - if (!test_bit(OP_SCANNING, &priv->op_flags) && + if (!(priv->op_flags & OP_SCANNING) && !(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) ath9k_htc_vif_reconfig(priv); @@ -755,7 +750,7 @@ void ath9k_htc_start_ani(struct ath9k_htc_priv *priv) common->ani.shortcal_timer = timestamp; common->ani.checkani_timer = timestamp; - set_bit(OP_ANI_RUNNING, &priv->op_flags); + priv->op_flags |= OP_ANI_RUNNING; ieee80211_queue_delayed_work(common->hw, &priv->ani_work, msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); @@ -764,7 +759,7 @@ void ath9k_htc_start_ani(struct ath9k_htc_priv *priv) void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv) { cancel_delayed_work_sync(&priv->ani_work); - clear_bit(OP_ANI_RUNNING, &priv->op_flags); + priv->op_flags &= ~OP_ANI_RUNNING; } void ath9k_htc_ani_work(struct work_struct *work) @@ -949,7 +944,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) ath_dbg(common, CONFIG, "Failed to update capability in target\n"); - clear_bit(OP_INVALID, &priv->op_flags); + priv->op_flags &= ~OP_INVALID; htc_start(priv->htc); spin_lock_bh(&priv->tx.tx_lock); @@ -978,7 +973,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) mutex_lock(&priv->mutex); - if (test_bit(OP_INVALID, &priv->op_flags)) { + if (priv->op_flags & OP_INVALID) { ath_dbg(common, ANY, "Device not present\n"); mutex_unlock(&priv->mutex); return; @@ -1020,7 +1015,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) ath9k_htc_ps_restore(priv); ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP); - set_bit(OP_INVALID, &priv->op_flags); + priv->op_flags |= OP_INVALID; ath_dbg(common, CONFIG, "Driver halt\n"); mutex_unlock(&priv->mutex); @@ -1110,7 +1105,7 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, ath9k_htc_set_opmode(priv); if ((priv->ah->opmode == NL80211_IFTYPE_AP) && - !test_bit(OP_ANI_RUNNING, &priv->op_flags)) { + !(priv->op_flags & OP_ANI_RUNNING)) { ath9k_hw_set_tsfadjust(priv->ah, 1); ath9k_htc_start_ani(priv); } @@ -1183,20 +1178,24 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) struct ath9k_htc_priv *priv = hw->priv; struct ath_common *common = ath9k_hw_common(priv->ah); struct ieee80211_conf *conf = &hw->conf; - bool chip_reset = false; - int ret = 0; mutex_lock(&priv->mutex); - ath9k_htc_ps_wakeup(priv); if (changed & IEEE80211_CONF_CHANGE_IDLE) { - mutex_lock(&priv->htc_pm_lock); - - priv->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE); - if (priv->ps_idle) - chip_reset = true; + bool enable_radio = false; + bool idle = !!(conf->flags & IEEE80211_CONF_IDLE); + mutex_lock(&priv->htc_pm_lock); + if (!idle && priv->ps_idle) + enable_radio = true; + priv->ps_idle = idle; mutex_unlock(&priv->htc_pm_lock); + + if (enable_radio) { + ath_dbg(common, CONFIG, "not-idle: enabling radio\n"); + ath9k_htc_setpower(priv, ATH9K_PM_AWAKE); + ath9k_htc_radio_enable(hw); + } } /* @@ -1211,7 +1210,7 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) ath9k_htc_remove_monitor_interface(priv); } - if ((changed & IEEE80211_CONF_CHANGE_CHANNEL) || chip_reset) { + if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { struct ieee80211_channel *curchan = hw->conf.channel; int pos = curchan->hw_value; @@ -1224,8 +1223,8 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) { ath_err(common, "Unable to set channel\n"); - ret = -EINVAL; - goto out; + mutex_unlock(&priv->mutex); + return -EINVAL; } } @@ -1247,10 +1246,21 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) priv->txpowlimit, &priv->curtxpow); } + if (changed & IEEE80211_CONF_CHANGE_IDLE) { + mutex_lock(&priv->htc_pm_lock); + if (!priv->ps_idle) { + mutex_unlock(&priv->htc_pm_lock); + goto out; + } + mutex_unlock(&priv->htc_pm_lock); + + ath_dbg(common, CONFIG, "idle: disabling radio\n"); + ath9k_htc_radio_disable(hw); + } + out: - ath9k_htc_ps_restore(priv); mutex_unlock(&priv->mutex); - return ret; + return 0; } #define SUPPORTED_FILTERS \ @@ -1275,7 +1285,7 @@ static void ath9k_htc_configure_filter(struct ieee80211_hw *hw, changed_flags &= SUPPORTED_FILTERS; *total_flags &= SUPPORTED_FILTERS; - if (test_bit(OP_INVALID, &priv->op_flags)) { + if (priv->op_flags & OP_INVALID) { ath_dbg(ath9k_hw_common(priv->ah), ANY, "Unable to configure filter on invalid state\n"); mutex_unlock(&priv->mutex); @@ -1486,7 +1496,6 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, priv->num_sta_assoc_vif++ : priv->num_sta_assoc_vif--; if (priv->ah->opmode == NL80211_IFTYPE_STATION) { - ath9k_htc_choose_set_bssid(priv); if (bss_conf->assoc && (priv->num_sta_assoc_vif == 1)) ath9k_htc_start_ani(priv); else if (priv->num_sta_assoc_vif == 0) @@ -1494,11 +1503,13 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, } } - if (changed & BSS_CHANGED_IBSS) { + if (changed & BSS_CHANGED_BSSID) { if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) { common->curaid = bss_conf->aid; memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); ath9k_htc_set_bssid(priv); + } else if (priv->ah->opmode == NL80211_IFTYPE_STATION) { + ath9k_htc_choose_set_bssid(priv); } } @@ -1506,7 +1517,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, ath_dbg(common, CONFIG, "Beacon enabled for BSS: %pM\n", bss_conf->bssid); ath9k_htc_set_tsfadjust(priv, vif); - set_bit(OP_ENABLE_BEACON, &priv->op_flags); + priv->op_flags |= OP_ENABLE_BEACON; ath9k_htc_beacon_config(priv, vif); } @@ -1519,7 +1530,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, ath_dbg(common, CONFIG, "Beacon disabled for BSS: %pM\n", bss_conf->bssid); - clear_bit(OP_ENABLE_BEACON, &priv->op_flags); + priv->op_flags &= ~OP_ENABLE_BEACON; ath9k_htc_beacon_config(priv, vif); } } @@ -1532,7 +1543,7 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, (priv->nvifs == 1) && (priv->num_ap_vif == 1) && (vif->type == NL80211_IFTYPE_AP)) { - set_bit(OP_TSF_RESET, &priv->op_flags); + priv->op_flags |= OP_TSF_RESET; } ath_dbg(common, CONFIG, "Beacon interval changed for BSS: %pM\n", @@ -1644,7 +1655,7 @@ static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw) mutex_lock(&priv->mutex); spin_lock_bh(&priv->beacon_lock); - set_bit(OP_SCANNING, &priv->op_flags); + priv->op_flags |= OP_SCANNING; spin_unlock_bh(&priv->beacon_lock); cancel_work_sync(&priv->ps_work); ath9k_htc_stop_ani(priv); @@ -1657,7 +1668,7 @@ static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw) mutex_lock(&priv->mutex); spin_lock_bh(&priv->beacon_lock); - clear_bit(OP_SCANNING, &priv->op_flags); + priv->op_flags &= ~OP_SCANNING; spin_unlock_bh(&priv->beacon_lock); ath9k_htc_ps_wakeup(priv); ath9k_htc_vif_reconfig(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 47e61d0da33b..3e40a6461512 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/trunk/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -916,7 +916,7 @@ void ath9k_host_rx_init(struct ath9k_htc_priv *priv) { ath9k_hw_rxena(priv->ah); ath9k_htc_opmode_init(priv); - ath9k_hw_startpcureceive(priv->ah, test_bit(OP_SCANNING, &priv->op_flags)); + ath9k_hw_startpcureceive(priv->ah, (priv->op_flags & OP_SCANNING)); priv->rx.last_rssi = ATH_RSSI_DUMMY_MARKER; } diff --git a/trunk/drivers/net/wireless/ath/ath9k/hw.c b/trunk/drivers/net/wireless/ath/ath9k/hw.c index ebfb2a3c645c..45e670087e1c 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hw.c +++ b/trunk/drivers/net/wireless/ath/ath9k/hw.c @@ -614,7 +614,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_AUTO) { if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI || - ((AR_SREV_9160(ah) || AR_SREV_9280(ah) || AR_SREV_9287(ah)) && + ((AR_SREV_9160(ah) || AR_SREV_9280(ah)) && !ah->is_pciexpress)) { ah->config.serialize_regmode = SER_REG_MODE_ON; @@ -773,25 +773,13 @@ static void ath9k_hw_init_qos(struct ath_hw *ah) u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) { - struct ath_common *common = ath9k_hw_common(ah); - int i = 0; - REG_CLR_BIT(ah, PLL3, PLL3_DO_MEAS_MASK); udelay(100); REG_SET_BIT(ah, PLL3, PLL3_DO_MEAS_MASK); - while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0) { - + while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0) udelay(100); - if (WARN_ON_ONCE(i >= 100)) { - ath_err(common, "PLL4 meaurement not done\n"); - break; - } - - i++; - } - return (REG_READ(ah, PLL3) & SQSUM_DVC_MASK) >> 3; } EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc); @@ -1360,9 +1348,6 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) } } - if (ath9k_hw_mci_is_enabled(ah)) - ar9003_mci_check_gpm_offset(ah); - REG_WRITE(ah, AR_RTC_RC, rst_flags); REGWRITE_BUFFER_FLUSH(ah); @@ -1723,7 +1708,7 @@ static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan) ath9k_hw_start_nfcal(ah, true); if (ath9k_hw_mci_is_enabled(ah)) - ar9003_mci_2g5g_switch(ah, false); + ar9003_mci_2g5g_switch(ah, true); if (AR_SREV_9271(ah)) ar9002_hw_load_ani_reg(ah, chan); @@ -1927,8 +1912,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, ath9k_hw_set_dma(ah); - if (!ath9k_hw_mci_is_enabled(ah)) - REG_WRITE(ah, AR_OBS, 8); + REG_WRITE(ah, AR_OBS, 8); if (ah->config.rx_intr_mitigation) { REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500); @@ -2127,9 +2111,6 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah) AR_RTC_FORCE_WAKE_EN); udelay(50); - if (ath9k_hw_mci_is_enabled(ah)) - ar9003_mci_set_power_awake(ah); - for (i = POWER_UP_TIME / 50; i > 0; i--) { val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M; if (val == AR_RTC_STATUS_ON) diff --git a/trunk/drivers/net/wireless/ath/ath9k/hw.h b/trunk/drivers/net/wireless/ath/ath9k/hw.h index 94096607cbdd..03d590924c64 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hw.h +++ b/trunk/drivers/net/wireless/ath/ath9k/hw.h @@ -1019,8 +1019,16 @@ void ar9002_hw_attach_ops(struct ath_hw *ah); void ar9003_hw_attach_ops(struct ath_hw *ah); void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan); - +/* + * ANI work can be shared between all families but a next + * generation implementation of ANI will be used only for AR9003 only + * for now as the other families still need to be tested with the same + * next generation ANI. Feel free to start testing it though for the + * older families (AR5008, AR9001, AR9002) by using modparam_force_new_ani. + */ +extern int modparam_force_new_ani; void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning); +void ath9k_hw_proc_mib_event(struct ath_hw *ah); void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan); #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT @@ -1030,8 +1038,7 @@ static inline bool ath9k_hw_btcoex_is_enabled(struct ath_hw *ah) } static inline bool ath9k_hw_mci_is_enabled(struct ath_hw *ah) { - return ah->common.btcoex_enabled && - (ah->caps.hw_caps & ATH9K_HW_CAP_MCI); + return ah->btcoex_hw.enabled && (ah->caps.hw_caps & ATH9K_HW_CAP_MCI); } void ath9k_hw_btcoex_enable(struct ath_hw *ah); diff --git a/trunk/drivers/net/wireless/ath/ath9k/link.c b/trunk/drivers/net/wireless/ath/ath9k/link.c index 91650fe50461..0cc4c70f7f0c 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/link.c +++ b/trunk/drivers/net/wireless/ath/ath9k/link.c @@ -136,14 +136,6 @@ void ath_hw_pll_work(struct work_struct *work) u32 pll_sqsum; struct ath_softc *sc = container_of(work, struct ath_softc, hw_pll_work.work); - /* - * ensure that the PLL WAR is executed only - * after the STA is associated (or) if the - * beaconing had started in interfaces that - * uses beacons. - */ - if (!test_bit(SC_OP_BEACONS, &sc->sc_flags)) - return; ath9k_ps_wakeup(sc); pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah); @@ -407,7 +399,6 @@ void ath_ani_calibrate(unsigned long data) longcal ? "long" : "", shortcal ? "short" : "", aniflag ? "ani" : "", common->ani.caldone ? "true" : "false"); - ath9k_debug_samp_bb_mac(sc); ath9k_ps_restore(sc); set_timer: @@ -416,6 +407,7 @@ void ath_ani_calibrate(unsigned long data) * The interval must be the shortest necessary to satisfy ANI, * short calibration and long calibration. */ + ath9k_debug_samp_bb_mac(sc); cal_interval = ATH_LONG_CALINTERVAL; if (sc->sc_ah->config.enable_ani) cal_interval = min(cal_interval, diff --git a/trunk/drivers/net/wireless/ath/ath9k/main.c b/trunk/drivers/net/wireless/ath/ath9k/main.c index e4e73f061a22..c0f478b0a9a2 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/main.c +++ b/trunk/drivers/net/wireless/ath/ath9k/main.c @@ -19,7 +19,7 @@ #include "ath9k.h" #include "btcoex.h" -u8 ath9k_parse_mpdudensity(u8 mpdudensity) +static u8 parse_mpdudensity(u8 mpdudensity) { /* * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing": @@ -150,11 +150,6 @@ static void __ath_cancel_work(struct ath_softc *sc) cancel_work_sync(&sc->hw_check_work); cancel_delayed_work_sync(&sc->tx_complete_work); cancel_delayed_work_sync(&sc->hw_pll_work); - -#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT - if (ath9k_hw_mci_is_enabled(sc->sc_ah)) - cancel_work_sync(&sc->mci_work); -#endif } static void ath_cancel_work(struct ath_softc *sc) @@ -322,7 +317,6 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, struct ieee80211_vif *vif) { struct ath_node *an; - u8 density; an = (struct ath_node *)sta->drv_priv; #ifdef CONFIG_ATH9K_DEBUGFS @@ -337,8 +331,7 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, ath_tx_node_init(sc, an); an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + sta->ht_cap.ampdu_factor); - density = ath9k_parse_mpdudensity(sta->ht_cap.ampdu_density); - an->mpdudensity = density; + an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density); } } @@ -520,6 +513,24 @@ irqreturn_t ath_isr(int irq, void *dev) ath9k_hw_set_interrupts(ah); } + if (status & ATH9K_INT_MIB) { + /* + * Disable interrupts until we service the MIB + * interrupt; otherwise it will continue to + * fire. + */ + ath9k_hw_disable_interrupts(ah); + /* + * Let the hal handle the event. We assume + * it will clear whatever condition caused + * the interrupt. + */ + spin_lock(&common->cc_lock); + ath9k_hw_proc_mib_event(ah); + spin_unlock(&common->cc_lock); + ath9k_hw_enable_interrupts(ah); + } + if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) if (status & ATH9K_INT_TIM_TIMER) { if (ATH_DBG_WARN_ON_ONCE(sc->ps_idle)) @@ -945,10 +956,14 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, /* * Enable MIB interrupts when there are hardware phy counters. */ - if ((iter_data.nstations + iter_data.nadhocs + iter_data.nmeshes) > 0) + if ((iter_data.nstations + iter_data.nadhocs + iter_data.nmeshes) > 0) { + if (ah->config.enable_ani) + ah->imask |= ATH9K_INT_MIB; ah->imask |= ATH9K_INT_TSFOOR; - else + } else { + ah->imask &= ~ATH9K_INT_MIB; ah->imask &= ~ATH9K_INT_TSFOOR; + } ath9k_hw_set_interrupts(ah); @@ -1018,6 +1033,15 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, } } + if ((ah->opmode == NL80211_IFTYPE_ADHOC) || + ((vif->type == NL80211_IFTYPE_ADHOC) && + sc->nvifs > 0)) { + ath_err(common, "Cannot create ADHOC interface when other" + " interfaces already exist.\n"); + ret = -EINVAL; + goto out; + } + ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type); sc->nvifs++; @@ -1042,6 +1066,15 @@ static int ath9k_change_interface(struct ieee80211_hw *hw, mutex_lock(&sc->mutex); ath9k_ps_wakeup(sc); + /* See if new interface type is valid. */ + if ((new_type == NL80211_IFTYPE_ADHOC) && + (sc->nvifs > 1)) { + ath_err(common, "When using ADHOC, it must be the only" + " interface.\n"); + ret = -EINVAL; + goto out; + } + if (ath9k_uses_beacons(new_type) && !ath9k_uses_beacons(vif->type)) { if (sc->nbcnvifs >= ATH_BCBUF) { @@ -1225,7 +1258,6 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) { ath_err(common, "Unable to set channel\n"); mutex_unlock(&sc->mutex); - ath9k_ps_restore(sc); return -EINVAL; } diff --git a/trunk/drivers/net/wireless/ath/ath9k/mci.c b/trunk/drivers/net/wireless/ath/ath9k/mci.c index 64cc782587d8..49137f477b05 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/mci.c +++ b/trunk/drivers/net/wireless/ath/ath9k/mci.c @@ -20,7 +20,7 @@ #include "ath9k.h" #include "mci.h" -static const u8 ath_mci_duty_cycle[] = { 55, 50, 60, 70, 80, 85, 90, 95, 98 }; +static const u8 ath_mci_duty_cycle[] = { 0, 50, 60, 70, 80, 85, 90, 95, 98 }; static struct ath_mci_profile_info* ath_mci_find_profile(struct ath_mci_profile *mci, @@ -28,14 +28,11 @@ ath_mci_find_profile(struct ath_mci_profile *mci, { struct ath_mci_profile_info *entry; - if (list_empty(&mci->info)) - return NULL; - list_for_each_entry(entry, &mci->info, list) { if (entry->conn_handle == info->conn_handle) - return entry; + break; } - return NULL; + return entry; } static bool ath_mci_add_profile(struct ath_common *common, @@ -52,21 +49,31 @@ static bool ath_mci_add_profile(struct ath_common *common, (info->type != MCI_GPM_COEX_PROFILE_VOICE)) return false; - entry = kzalloc(sizeof(*entry), GFP_ATOMIC); - if (!entry) - return false; + entry = ath_mci_find_profile(mci, info); - memcpy(entry, info, 10); - INC_PROF(mci, info); - list_add_tail(&entry->list, &mci->info); + if (entry) { + memcpy(entry, info, 10); + } else { + entry = kzalloc(sizeof(*entry), GFP_KERNEL); + if (!entry) + return false; + + memcpy(entry, info, 10); + INC_PROF(mci, info); + list_add_tail(&info->list, &mci->info); + } return true; } static void ath_mci_del_profile(struct ath_common *common, struct ath_mci_profile *mci, - struct ath_mci_profile_info *entry) + struct ath_mci_profile_info *info) { + struct ath_mci_profile_info *entry; + + entry = ath_mci_find_profile(mci, info); + if (!entry) return; @@ -79,16 +86,12 @@ void ath_mci_flush_profile(struct ath_mci_profile *mci) { struct ath_mci_profile_info *info, *tinfo; - mci->aggr_limit = 0; - - if (list_empty(&mci->info)) - return; - list_for_each_entry_safe(info, tinfo, &mci->info, list) { list_del(&info->list); DEC_PROF(mci, info); kfree(info); } + mci->aggr_limit = 0; } static void ath_mci_adjust_aggr_limit(struct ath_btcoex *btcoex) @@ -120,8 +123,6 @@ static void ath_mci_update_scheme(struct ath_softc *sc) if (mci_hw->config & ATH_MCI_CONFIG_DISABLE_TUNING) goto skip_tuning; - btcoex->duty_cycle = ath_mci_duty_cycle[num_profile]; - if (num_profile == 1) { info = list_first_entry(&mci->info, struct ath_mci_profile_info, @@ -180,11 +181,12 @@ static void ath_mci_update_scheme(struct ath_softc *sc) if (IS_CHAN_5GHZ(sc->sc_ah->curchan)) return; - btcoex->duty_cycle += (mci->num_bdr ? ATH_MCI_BDR_DUTY_CYCLE : 0); + btcoex->duty_cycle += (mci->num_bdr ? ATH_MCI_MAX_DUTY_CYCLE : 0); if (btcoex->duty_cycle > ATH_MCI_MAX_DUTY_CYCLE) btcoex->duty_cycle = ATH_MCI_MAX_DUTY_CYCLE; - btcoex->btcoex_no_stomp = btcoex->btcoex_period * 1000 * + btcoex->btcoex_period *= 1000; + btcoex->btcoex_no_stomp = btcoex->btcoex_period * (100 - btcoex->duty_cycle) / 100; ath9k_hw_btcoex_enable(sc->sc_ah); @@ -195,16 +197,20 @@ static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) { struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); - struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci; u32 payload[4] = {0, 0, 0, 0}; switch (opcode) { case MCI_GPM_BT_CAL_REQ: - if (mci_hw->bt_state == MCI_BT_AWAKE) { - ar9003_mci_state(ah, MCI_STATE_SET_BT_CAL_START); + if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_AWAKE) { + ar9003_mci_state(ah, MCI_STATE_SET_BT_CAL_START, NULL); ieee80211_queue_work(sc->hw, &sc->hw_reset_work); + } else { + ath_dbg(common, MCI, "MCI State mismatch: %d\n", + ar9003_mci_state(ah, MCI_STATE_BT, NULL)); } - ath_dbg(common, MCI, "MCI State : %d\n", mci_hw->bt_state); + break; + case MCI_GPM_BT_CAL_DONE: + ar9003_mci_state(ah, MCI_STATE_BT, NULL); break; case MCI_GPM_BT_CAL_GRANT: MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_DONE); @@ -217,55 +223,32 @@ static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) } } -static void ath9k_mci_work(struct work_struct *work) -{ - struct ath_softc *sc = container_of(work, struct ath_softc, mci_work); - - ath_mci_update_scheme(sc); -} - static void ath_mci_process_profile(struct ath_softc *sc, struct ath_mci_profile_info *info) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_btcoex *btcoex = &sc->btcoex; struct ath_mci_profile *mci = &btcoex->mci; - struct ath_mci_profile_info *entry = NULL; - - entry = ath_mci_find_profile(mci, info); - if (entry) { - /* - * Two MCI interrupts are generated while connecting to - * headset and A2DP profile, but only one MCI interrupt - * is generated with last added profile type while disconnecting - * both profiles. - * So while adding second profile type decrement - * the first one. - */ - if (entry->type != info->type) { - DEC_PROF(mci, entry); - INC_PROF(mci, info); - } - memcpy(entry, info, 10); - } if (info->start) { - if (!entry && !ath_mci_add_profile(common, mci, info)) + if (!ath_mci_add_profile(common, mci, info)) return; } else - ath_mci_del_profile(common, mci, entry); + ath_mci_del_profile(common, mci, info); btcoex->btcoex_period = ATH_MCI_DEF_BT_PERIOD; mci->aggr_limit = mci->num_sco ? 6 : 0; - btcoex->duty_cycle = ath_mci_duty_cycle[NUM_PROF(mci)]; - if (NUM_PROF(mci)) + if (NUM_PROF(mci)) { btcoex->bt_stomp_type = ATH_BTCOEX_STOMP_LOW; - else + btcoex->duty_cycle = ath_mci_duty_cycle[NUM_PROF(mci)]; + } else { btcoex->bt_stomp_type = mci->num_mgmt ? ATH_BTCOEX_STOMP_ALL : ATH_BTCOEX_STOMP_LOW; + btcoex->duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE; + } - ieee80211_queue_work(sc->hw, &sc->mci_work); + ath_mci_update_scheme(sc); } static void ath_mci_process_status(struct ath_softc *sc, @@ -280,6 +263,8 @@ static void ath_mci_process_status(struct ath_softc *sc, if (status->is_link) return; + memset(&info, 0, sizeof(struct ath_mci_profile_info)); + info.conn_handle = status->conn_handle; if (ath_mci_find_profile(mci, &info)) return; @@ -299,7 +284,7 @@ static void ath_mci_process_status(struct ath_softc *sc, } while (++i < ATH_MCI_MAX_PROFILE); if (old_num_mgmt != mci->num_mgmt) - ieee80211_queue_work(sc->hw, &sc->mci_work); + ath_mci_update_scheme(sc); } static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) @@ -308,20 +293,25 @@ static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) struct ath_mci_profile_info profile_info; struct ath_mci_profile_status profile_status; struct ath_common *common = ath9k_hw_common(sc->sc_ah); - u8 major, minor; + u32 version; + u8 major; + u8 minor; u32 seq_num; switch (opcode) { case MCI_GPM_COEX_VERSION_QUERY: - ar9003_mci_state(ah, MCI_STATE_SEND_WLAN_COEX_VERSION); + version = ar9003_mci_state(ah, MCI_STATE_SEND_WLAN_COEX_VERSION, + NULL); break; case MCI_GPM_COEX_VERSION_RESPONSE: major = *(rx_payload + MCI_GPM_COEX_B_MAJOR_VERSION); minor = *(rx_payload + MCI_GPM_COEX_B_MINOR_VERSION); - ar9003_mci_set_bt_version(ah, major, minor); + version = (major << 8) + minor; + version = ar9003_mci_state(ah, MCI_STATE_SET_BT_COEX_VERSION, + &version); break; case MCI_GPM_COEX_STATUS_QUERY: - ar9003_mci_send_wlan_channels(ah); + ar9003_mci_state(ah, MCI_STATE_SEND_WLAN_CHANNELS, NULL); break; case MCI_GPM_COEX_BT_PROFILE_INFO: memcpy(&profile_info, @@ -348,7 +338,7 @@ static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) seq_num = *((u32 *)(rx_payload + 12)); ath_dbg(common, MCI, - "BT_Status_Update: is_link=%d, linkId=%d, state=%d, SEQ=%u\n", + "BT_Status_Update: is_link=%d, linkId=%d, state=%d, SEQ=%d\n", profile_status.is_link, profile_status.conn_handle, profile_status.is_critical, seq_num); @@ -388,7 +378,6 @@ int ath_mci_setup(struct ath_softc *sc) mci->gpm_buf.bf_addr, (mci->gpm_buf.bf_len >> 4), mci->sched_buf.bf_paddr); - INIT_WORK(&sc->mci_work, ath9k_mci_work); ath_dbg(common, MCI, "MCI Initialized\n"); return 0; @@ -416,7 +405,6 @@ void ath_mci_intr(struct ath_softc *sc) struct ath_mci_coex *mci = &sc->mci_coex; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); - struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci; u32 mci_int, mci_int_rxmsg; u32 offset, subtype, opcode; u32 *pgpm; @@ -425,8 +413,8 @@ void ath_mci_intr(struct ath_softc *sc) ar9003_mci_get_interrupt(sc->sc_ah, &mci_int, &mci_int_rxmsg); - if (ar9003_mci_state(ah, MCI_STATE_ENABLE) == 0) { - ar9003_mci_get_next_gpm_offset(ah, true, NULL); + if (ar9003_mci_state(ah, MCI_STATE_ENABLE, NULL) == 0) { + ar9003_mci_state(ah, MCI_STATE_INIT_GPM_OFFSET, NULL); return; } @@ -445,41 +433,46 @@ void ath_mci_intr(struct ath_softc *sc) NULL, 0, true, false); mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE; - ar9003_mci_state(ah, MCI_STATE_RESET_REQ_WAKE); + ar9003_mci_state(ah, MCI_STATE_RESET_REQ_WAKE, NULL); /* * always do this for recovery and 2G/5G toggling and LNA_TRANS */ - ar9003_mci_state(ah, MCI_STATE_SET_BT_AWAKE); + ar9003_mci_state(ah, MCI_STATE_SET_BT_AWAKE, NULL); } if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING) { mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING; - if ((mci_hw->bt_state == MCI_BT_SLEEP) && - (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP) != - MCI_BT_SLEEP)) - ar9003_mci_state(ah, MCI_STATE_SET_BT_AWAKE); + if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_SLEEP) { + if (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL) != + MCI_BT_SLEEP) + ar9003_mci_state(ah, MCI_STATE_SET_BT_AWAKE, + NULL); + } } if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING) { mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING; - if ((mci_hw->bt_state == MCI_BT_AWAKE) && - (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP) != - MCI_BT_AWAKE)) - mci_hw->bt_state = MCI_BT_SLEEP; + if (ar9003_mci_state(ah, MCI_STATE_BT, NULL) == MCI_BT_AWAKE) { + if (ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP, NULL) != + MCI_BT_AWAKE) + ar9003_mci_state(ah, MCI_STATE_SET_BT_SLEEP, + NULL); + } } if ((mci_int & AR_MCI_INTERRUPT_RX_INVALID_HDR) || (mci_int & AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT)) { - ar9003_mci_state(ah, MCI_STATE_RECOVER_RX); + ar9003_mci_state(ah, MCI_STATE_RECOVER_RX, NULL); skip_gpm = true; } if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO) { mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_SCHD_INFO; - offset = ar9003_mci_state(ah, MCI_STATE_LAST_SCHD_MSG_OFFSET); + offset = ar9003_mci_state(ah, MCI_STATE_LAST_SCHD_MSG_OFFSET, + NULL); } if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_GPM) { @@ -488,8 +481,8 @@ void ath_mci_intr(struct ath_softc *sc) while (more_data == MCI_GPM_MORE) { pgpm = mci->gpm_buf.bf_addr; - offset = ar9003_mci_get_next_gpm_offset(ah, false, - &more_data); + offset = ar9003_mci_state(ah, MCI_STATE_NEXT_GPM_OFFSET, + &more_data); if (offset == MCI_GPM_INVALID) break; @@ -530,17 +523,23 @@ void ath_mci_intr(struct ath_softc *sc) mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_LNA_INFO; if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_INFO) { - int value_dbm = MS(mci_hw->cont_status, - AR_MCI_CONT_RSSI_POWER); + int value_dbm = ar9003_mci_state(ah, + MCI_STATE_CONT_RSSI_POWER, NULL); mci_int_rxmsg &= ~AR_MCI_INTERRUPT_RX_MSG_CONT_INFO; - ath_dbg(common, MCI, - "MCI CONT_INFO: (%s) pri = %d pwr = %d dBm\n", - MS(mci_hw->cont_status, AR_MCI_CONT_TXRX) ? - "tx" : "rx", - MS(mci_hw->cont_status, AR_MCI_CONT_PRIORITY), - value_dbm); + if (ar9003_mci_state(ah, MCI_STATE_CONT_TXRX, NULL)) + ath_dbg(common, MCI, + "MCI CONT_INFO: (tx) pri = %d, pwr = %d dBm\n", + ar9003_mci_state(ah, + MCI_STATE_CONT_PRIORITY, NULL), + value_dbm); + else + ath_dbg(common, MCI, + "MCI CONT_INFO: (rx) pri = %d,pwr = %d dBm\n", + ar9003_mci_state(ah, + MCI_STATE_CONT_PRIORITY, NULL), + value_dbm); } if (mci_int_rxmsg & AR_MCI_INTERRUPT_RX_MSG_CONT_NACK) diff --git a/trunk/drivers/net/wireless/ath/ath9k/rc.c b/trunk/drivers/net/wireless/ath/ath9k/rc.c index e034add9cd5a..92a6c0a87f89 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/rc.c +++ b/trunk/drivers/net/wireless/ath/ath9k/rc.c @@ -770,7 +770,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, struct ieee80211_tx_rate *rates = tx_info->control.rates; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; __le16 fc = hdr->frame_control; - u8 try_per_rate, i = 0, rix; + u8 try_per_rate, i = 0, rix, high_rix; int is_probe = 0; if (rate_control_send_low(sta, priv_sta, txrc)) @@ -791,6 +791,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, rate_table = ath_rc_priv->rate_table; rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe, false); + high_rix = rix; /* * If we're in HT mode and both us and our peer supports LDPC. @@ -838,16 +839,16 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, try_per_rate = 8; /* - * If the last rate in the rate series is MCS and has - * more than 80% of per thresh, then use a legacy rate - * as last retry to ensure that the frame is tried in both - * MCS and legacy rate. + * Use a legacy rate as last retry to ensure that the frame + * is tried in both MCS and legacy rates. */ - ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix); - if (WLAN_RC_PHY_HT(rate_table->info[rix].phy) && - (ath_rc_priv->per[rix] > 45)) + if ((rates[2].flags & IEEE80211_TX_RC_MCS) && + (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU) || + (ath_rc_priv->per[high_rix] > 45))) rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe, true); + else + ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix); /* All other rates in the series have RTS enabled */ ath_rc_rate_set_series(rate_table, &rates[i], txrc, diff --git a/trunk/drivers/net/wireless/ath/ath9k/recv.c b/trunk/drivers/net/wireless/ath/ath9k/recv.c index 6a7dd26f2a13..fbdcc80437fe 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/recv.c +++ b/trunk/drivers/net/wireless/ath/ath9k/recv.c @@ -658,9 +658,9 @@ static bool ath_edma_get_buffers(struct ath_softc *sc, __skb_unlink(skb, &rx_edma->rx_fifo); list_add_tail(&bf->list, &sc->rx.rxbuf); ath_rx_edma_buf_link(sc, qtype); + } else { + bf = NULL; } - - bf = NULL; } *dest = bf; @@ -785,8 +785,7 @@ static bool ath9k_rx_accept(struct ath_common *common, * descriptor does contain a valid key index. This has been observed * mostly with CCMP encryption. */ - if (rx_stats->rs_keyix == ATH9K_RXKEYIX_INVALID || - !test_bit(rx_stats->rs_keyix, common->ccmp_keymap)) + if (rx_stats->rs_keyix == ATH9K_RXKEYIX_INVALID) rx_stats->rs_status &= ~ATH9K_RXERR_KEYMISS; if (!rx_stats->rs_datalen) { diff --git a/trunk/drivers/net/wireless/ath/ath9k/reg.h b/trunk/drivers/net/wireless/ath/ath9k/reg.h index 5046b282a93c..560d6effac7a 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/reg.h +++ b/trunk/drivers/net/wireless/ath/ath9k/reg.h @@ -2098,8 +2098,8 @@ enum { #define AR_MCI_CONT_STATUS 0x1848 #define AR_MCI_CONT_RSSI_POWER 0x000000FF #define AR_MCI_CONT_RSSI_POWER_S 0 -#define AR_MCI_CONT_PRIORITY 0x0000FF00 -#define AR_MCI_CONT_PRIORITY_S 8 +#define AR_MCI_CONT_RRIORITY 0x0000FF00 +#define AR_MCI_CONT_RRIORITY_S 8 #define AR_MCI_CONT_TXRX 0x00010000 #define AR_MCI_CONT_TXRX_S 16 @@ -2162,6 +2162,10 @@ enum { #define AR_BTCOEX_CTRL_SPDT_POLARITY 0x80000000 #define AR_BTCOEX_CTRL_SPDT_POLARITY_S 31 +#define AR_BTCOEX_WL_WEIGHTS0 0x18b0 +#define AR_BTCOEX_WL_WEIGHTS1 0x18b4 +#define AR_BTCOEX_WL_WEIGHTS2 0x18b8 +#define AR_BTCOEX_WL_WEIGHTS3 0x18bc #define AR_BTCOEX_MAX_TXPWR(_x) (0x18c0 + ((_x) << 2)) #define AR_BTCOEX_WL_LNA 0x1940 #define AR_BTCOEX_RFGAIN_CTRL 0x1944 diff --git a/trunk/drivers/net/wireless/ath/ath9k/xmit.c b/trunk/drivers/net/wireless/ath/ath9k/xmit.c index cafb4a09729a..f777ddcd1172 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/xmit.c +++ b/trunk/drivers/net/wireless/ath/ath9k/xmit.c @@ -938,7 +938,6 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, struct ieee80211_tx_rate *rates; const struct ieee80211_rate *rate; struct ieee80211_hdr *hdr; - struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu); int i; u8 rix = 0; @@ -949,7 +948,18 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, /* set dur_update_en for l-sig computation except for PS-Poll frames */ info->dur_update = !ieee80211_is_pspoll(hdr->frame_control); - info->rtscts_rate = fi->rtscts_rate; + + /* + * We check if Short Preamble is needed for the CTS rate by + * checking the BSS's global flag. + * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used. + */ + rate = ieee80211_get_rts_cts_rate(sc->hw, tx_info); + info->rtscts_rate = rate->hw_value; + + if (tx_info->control.vif && + tx_info->control.vif->bss_conf.use_short_preamble) + info->rtscts_rate |= rate->hw_value_short; for (i = 0; i < 4; i++) { bool is_40, is_sgi, is_sp; @@ -991,13 +1001,13 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, } /* legacy rates */ - rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx]; if ((tx_info->band == IEEE80211_BAND_2GHZ) && !(rate->flags & IEEE80211_RATE_ERP_G)) phy = WLAN_RC_PHY_CCK; else phy = WLAN_RC_PHY_OFDM; + rate = &sc->sbands[tx_info->band].bitrates[rates[i].idx]; info->rates[i].Rate = rate->hw_value; if (rate->hw_value_short) { if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) @@ -1165,7 +1175,6 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, { struct ath_atx_tid *txtid; struct ath_node *an; - u8 density; an = (struct ath_node *)sta->drv_priv; txtid = ATH_AN_2_TID(an, tid); @@ -1173,17 +1182,6 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, if (txtid->state & (AGGR_CLEANUP | AGGR_ADDBA_COMPLETE)) return -EAGAIN; - /* update ampdu factor/density, they may have changed. This may happen - * in HT IBSS when a beacon with HT-info is received after the station - * has already been added. - */ - if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) { - an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + - sta->ht_cap.ampdu_factor); - density = ath9k_parse_mpdudensity(sta->ht_cap.ampdu_density); - an->mpdudensity = density; - } - txtid->state |= AGGR_ADDBA_PROGRESS; txtid->paused = true; *ssn = txtid->seq_start = txtid->seq_next; @@ -1778,22 +1776,10 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, struct ieee80211_sta *sta = tx_info->control.sta; struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - const struct ieee80211_rate *rate; struct ath_frame_info *fi = get_frame_info(skb); struct ath_node *an = NULL; enum ath9k_key_type keytype; - bool short_preamble = false; - - /* - * We check if Short Preamble is needed for the CTS rate by - * checking the BSS's global flag. - * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used. - */ - if (tx_info->control.vif && - tx_info->control.vif->bss_conf.use_short_preamble) - short_preamble = true; - rate = ieee80211_get_rts_cts_rate(hw, tx_info); keytype = ath9k_cmn_get_hw_crypto_keytype(skb); if (sta) @@ -1808,9 +1794,6 @@ static void setup_frame_info(struct ieee80211_hw *hw, struct sk_buff *skb, fi->keyix = ATH9K_TXKEYIX_INVALID; fi->keytype = keytype; fi->framelen = framelen; - fi->rtscts_rate = rate->hw_value; - if (short_preamble) - fi->rtscts_rate |= rate->hw_value_short; } u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate) diff --git a/trunk/drivers/net/wireless/ath/carl9170/tx.c b/trunk/drivers/net/wireless/ath/carl9170/tx.c index ede0b572cebc..aed305177af6 100644 --- a/trunk/drivers/net/wireless/ath/carl9170/tx.c +++ b/trunk/drivers/net/wireless/ath/carl9170/tx.c @@ -277,11 +277,11 @@ static void carl9170_tx_release(struct kref *ref) return; BUILD_BUG_ON( - offsetof(struct ieee80211_tx_info, status.ack_signal) != 20); + offsetof(struct ieee80211_tx_info, status.ampdu_ack_len) != 23); - memset(&txinfo->status.ack_signal, 0, + memset(&txinfo->status.ampdu_ack_len, 0, sizeof(struct ieee80211_tx_info) - - offsetof(struct ieee80211_tx_info, status.ack_signal)); + offsetof(struct ieee80211_tx_info, status.ampdu_ack_len)); if (atomic_read(&ar->tx_total_queued)) ar->tx_schedule = true; diff --git a/trunk/drivers/net/wireless/ath/key.c b/trunk/drivers/net/wireless/ath/key.c index 5c54aa43ca2d..0e81904956cf 100644 --- a/trunk/drivers/net/wireless/ath/key.c +++ b/trunk/drivers/net/wireless/ath/key.c @@ -556,9 +556,6 @@ int ath_key_config(struct ath_common *common, return -EIO; set_bit(idx, common->keymap); - if (key->cipher == WLAN_CIPHER_SUITE_CCMP) - set_bit(idx, common->ccmp_keymap); - if (key->cipher == WLAN_CIPHER_SUITE_TKIP) { set_bit(idx + 64, common->keymap); set_bit(idx, common->tkip_keymap); @@ -585,7 +582,6 @@ void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key) return; clear_bit(key->hw_key_idx, common->keymap); - clear_bit(key->hw_key_idx, common->ccmp_keymap); if (key->cipher != WLAN_CIPHER_SUITE_TKIP) return; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/trunk/drivers/net/wireless/brcm80211/brcmfmac/Makefile index 9d5170b6df50..abb48032753b 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/Makefile +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/Makefile @@ -34,5 +34,3 @@ brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \ sdio_chip.o brcmfmac-$(CONFIG_BRCMFMAC_USB) += \ usb.o -brcmfmac-$(CONFIG_BRCMDBG) += \ - dhd_dbg.o \ No newline at end of file diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 49765d34b4e0..82f51dbd0d66 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -44,7 +44,6 @@ #define SDIO_DEVICE_ID_BROADCOM_4329 0x4329 #define SDIO_DEVICE_ID_BROADCOM_4330 0x4330 -#define SDIO_DEVICE_ID_BROADCOM_4334 0x4334 #define SDIO_FUNC1_BLOCKSIZE 64 #define SDIO_FUNC2_BLOCKSIZE 512 @@ -53,7 +52,6 @@ static const struct sdio_device_id brcmf_sdmmc_ids[] = { {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)}, {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330)}, - {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334)}, { /* end: all zeroes */ }, }; MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids); diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index a11fe54f5950..9f637014486e 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd.h @@ -613,9 +613,6 @@ struct brcmf_pub { struct work_struct multicast_work; u8 macvalue[ETH_ALEN]; atomic_t pend_8021x_cnt; -#ifdef DEBUG - struct dentry *dbgfs_dir; -#endif }; struct brcmf_if_event { diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h index 537f499cc5d2..366916494be4 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h @@ -36,13 +36,6 @@ struct dngl_stats { unsigned long multicast; /* multicast packets received */ }; -struct brcmf_bus_dcmd { - char *name; - char *param; - int param_len; - struct list_head list; -}; - /* interface structure between common and bus layer */ struct brcmf_bus { u8 type; /* bus type */ @@ -57,7 +50,6 @@ struct brcmf_bus { unsigned long tx_realloc; /* Tx packets realloced for headroom */ struct dngl_stats dstats; /* Stats for dongle-based data */ u8 align; /* bus alignment requirement */ - struct list_head dcmd_list; /* interface functions pointers */ /* Stop bus module: clear pending frames, disable data flow */ diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index 2621dd3d7dcd..236cb9fa460c 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c @@ -800,13 +800,13 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr) char iovbuf[BRCMF_EVENTING_MASK_LEN + 12]; /* Room for "event_msgs" + '\0' + bitvec */ char buf[128], *ptr; + u32 dongle_align = drvr->bus_if->align; + u32 glom = 0; u32 roaming = 1; uint bcn_timeout = 3; int scan_assoc_time = 40; int scan_unassoc_time = 40; int i; - struct brcmf_bus_dcmd *cmdlst; - struct list_head *cur, *q; mutex_lock(&drvr->proto_block); @@ -827,6 +827,17 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr) /* Print fw version info */ brcmf_dbg(ERROR, "Firmware version = %s\n", buf); + /* Match Host and Dongle rx alignment */ + brcmf_c_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf, + sizeof(iovbuf)); + brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf, + sizeof(iovbuf)); + + /* disable glom option per default */ + brcmf_c_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf)); + brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, iovbuf, + sizeof(iovbuf)); + /* Setup timeout if Beacons are lost and roam is off to report link down */ brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf, @@ -863,20 +874,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_pub *drvr) 0, true); } - /* set bus specific command if there is any */ - list_for_each_safe(cur, q, &drvr->bus_if->dcmd_list) { - cmdlst = list_entry(cur, struct brcmf_bus_dcmd, list); - if (cmdlst->name && cmdlst->param && cmdlst->param_len) { - brcmf_c_mkiovar(cmdlst->name, cmdlst->param, - cmdlst->param_len, iovbuf, - sizeof(iovbuf)); - brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_SET_VAR, - iovbuf, sizeof(iovbuf)); - } - list_del(cur); - kfree(cmdlst); - } - mutex_unlock(&drvr->proto_block); return 0; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c deleted file mode 100644 index 7f89540b56da..000000000000 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c +++ /dev/null @@ -1,126 +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 -#include -#include -#include - -#include -#include -#include -#include "dhd.h" -#include "dhd_bus.h" -#include "dhd_dbg.h" - -static struct dentry *root_folder; - -void brcmf_debugfs_init(void) -{ - root_folder = debugfs_create_dir(KBUILD_MODNAME, NULL); - if (IS_ERR(root_folder)) - root_folder = NULL; -} - -void brcmf_debugfs_exit(void) -{ - if (!root_folder) - return; - - debugfs_remove_recursive(root_folder); - root_folder = NULL; -} - -int brcmf_debugfs_attach(struct brcmf_pub *drvr) -{ - if (!root_folder) - return -ENODEV; - - drvr->dbgfs_dir = debugfs_create_dir(dev_name(drvr->dev), root_folder); - return PTR_RET(drvr->dbgfs_dir); -} - -void brcmf_debugfs_detach(struct brcmf_pub *drvr) -{ - if (!IS_ERR_OR_NULL(drvr->dbgfs_dir)) - debugfs_remove_recursive(drvr->dbgfs_dir); -} - -struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr) -{ - return drvr->dbgfs_dir; -} - -static -ssize_t brcmf_debugfs_sdio_counter_read(struct file *f, char __user *data, - size_t count, loff_t *ppos) -{ - struct brcmf_sdio_count *sdcnt = f->private_data; - char buf[750]; - int res; - - /* only allow read from start */ - if (*ppos > 0) - return 0; - - res = scnprintf(buf, sizeof(buf), - "intrcount: %u\nlastintrs: %u\n" - "pollcnt: %u\nregfails: %u\n" - "tx_sderrs: %u\nfcqueued: %u\n" - "rxrtx: %u\nrx_toolong: %u\n" - "rxc_errors: %u\nrx_hdrfail: %u\n" - "rx_badhdr: %u\nrx_badseq: %u\n" - "fc_rcvd: %u\nfc_xoff: %u\n" - "fc_xon: %u\nrxglomfail: %u\n" - "rxglomframes: %u\nrxglompkts: %u\n" - "f2rxhdrs: %u\nf2rxdata: %u\n" - "f2txdata: %u\nf1regdata: %u\n" - "tickcnt: %u\ntx_ctlerrs: %lu\n" - "tx_ctlpkts: %lu\nrx_ctlerrs: %lu\n" - "rx_ctlpkts: %lu\nrx_readahead: %lu\n", - sdcnt->intrcount, sdcnt->lastintrs, - sdcnt->pollcnt, sdcnt->regfails, - sdcnt->tx_sderrs, sdcnt->fcqueued, - sdcnt->rxrtx, sdcnt->rx_toolong, - sdcnt->rxc_errors, sdcnt->rx_hdrfail, - sdcnt->rx_badhdr, sdcnt->rx_badseq, - sdcnt->fc_rcvd, sdcnt->fc_xoff, - sdcnt->fc_xon, sdcnt->rxglomfail, - sdcnt->rxglomframes, sdcnt->rxglompkts, - sdcnt->f2rxhdrs, sdcnt->f2rxdata, - sdcnt->f2txdata, sdcnt->f1regdata, - sdcnt->tickcnt, sdcnt->tx_ctlerrs, - sdcnt->tx_ctlpkts, sdcnt->rx_ctlerrs, - sdcnt->rx_ctlpkts, sdcnt->rx_readahead_cnt); - - return simple_read_from_buffer(data, count, ppos, buf, res); -} - -static const struct file_operations brcmf_debugfs_sdio_counter_ops = { - .owner = THIS_MODULE, - .open = simple_open, - .read = brcmf_debugfs_sdio_counter_read -}; - -void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr, - struct brcmf_sdio_count *sdcnt) -{ - struct dentry *dentry = drvr->dbgfs_dir; - - if (!IS_ERR_OR_NULL(dentry)) - debugfs_create_file("counters", S_IRUGO, dentry, - sdcnt, &brcmf_debugfs_sdio_counter_ops); -} diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h index b784920532d3..a2c4576cf9ff 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h @@ -76,63 +76,4 @@ do { \ extern int brcmf_msg_level; -/* - * hold counter variables used in brcmfmac sdio driver. - */ -struct brcmf_sdio_count { - uint intrcount; /* Count of device interrupt callbacks */ - uint lastintrs; /* Count as of last watchdog timer */ - uint pollcnt; /* Count of active polls */ - uint regfails; /* Count of R_REG failures */ - uint tx_sderrs; /* Count of tx attempts with sd errors */ - uint fcqueued; /* Tx packets that got queued */ - uint rxrtx; /* Count of rtx requests (NAK to dongle) */ - uint rx_toolong; /* Receive frames too long to receive */ - uint rxc_errors; /* SDIO errors when reading control frames */ - uint rx_hdrfail; /* SDIO errors on header reads */ - uint rx_badhdr; /* Bad received headers (roosync?) */ - uint rx_badseq; /* Mismatched rx sequence number */ - uint fc_rcvd; /* Number of flow-control events received */ - uint fc_xoff; /* Number which turned on flow-control */ - uint fc_xon; /* Number which turned off flow-control */ - uint rxglomfail; /* Failed deglom attempts */ - uint rxglomframes; /* Number of glom frames (superframes) */ - uint rxglompkts; /* Number of packets from glom frames */ - uint f2rxhdrs; /* Number of header reads */ - uint f2rxdata; /* Number of frame data reads */ - uint f2txdata; /* Number of f2 frame writes */ - uint f1regdata; /* Number of f1 register accesses */ - uint tickcnt; /* Number of watchdog been schedule */ - ulong tx_ctlerrs; /* Err of sending ctrl frames */ - ulong tx_ctlpkts; /* Ctrl frames sent to dongle */ - ulong rx_ctlerrs; /* Err of processing rx ctrl frames */ - ulong rx_ctlpkts; /* Ctrl frames processed from dongle */ - ulong rx_readahead_cnt; /* packets where header read-ahead was used */ -}; - -struct brcmf_pub; -#ifdef DEBUG -void brcmf_debugfs_init(void); -void brcmf_debugfs_exit(void); -int brcmf_debugfs_attach(struct brcmf_pub *drvr); -void brcmf_debugfs_detach(struct brcmf_pub *drvr); -struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr); -void brcmf_debugfs_create_sdio_count(struct brcmf_pub *drvr, - struct brcmf_sdio_count *sdcnt); -#else -static inline void brcmf_debugfs_init(void) -{ -} -static inline void brcmf_debugfs_exit(void) -{ -} -static inline int brcmf_debugfs_attach(struct brcmf_pub *drvr) -{ - return 0; -} -static inline void brcmf_debugfs_detach(struct brcmf_pub *drvr) -{ -} -#endif - #endif /* _BRCMF_DBG_H_ */ diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 57bf1d7ee80f..8933f9b31a9a 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -1007,9 +1007,6 @@ int brcmf_attach(uint bus_hdrlen, struct device *dev) drvr->bus_if->drvr = drvr; drvr->dev = dev; - /* create device debugfs folder */ - brcmf_debugfs_attach(drvr); - /* Attach and link in the protocol */ ret = brcmf_proto_attach(drvr); if (ret != 0) { @@ -1020,8 +1017,6 @@ int brcmf_attach(uint bus_hdrlen, struct device *dev) 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); - return ret; fail: @@ -1128,7 +1123,6 @@ void brcmf_detach(struct device *dev) brcmf_proto_detach(drvr); } - brcmf_debugfs_detach(drvr); bus_if->drvr = NULL; kfree(drvr); } @@ -1198,8 +1192,6 @@ int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size) static void brcmf_driver_init(struct work_struct *work) { - brcmf_debugfs_init(); - #ifdef CONFIG_BRCMFMAC_SDIO brcmf_sdio_init(); #endif @@ -1227,7 +1219,6 @@ static void __exit brcmfmac_module_exit(void) #ifdef CONFIG_BRCMFMAC_USB brcmf_usb_exit(); #endif - brcmf_debugfs_exit(); } module_init(brcmfmac_module_init); diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 5c868bac1c1c..1dbf2be478c8 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -31,8 +31,6 @@ #include #include #include -#include -#include #include #include #include @@ -50,9 +48,6 @@ #define CBUF_LEN (128) -/* Device console log buffer state */ -#define CONSOLE_BUFFER_MAX 2024 - struct rte_log_le { __le32 buf; /* Can't be pointer on (64-bit) hosts */ __le32 buf_size; @@ -286,7 +281,7 @@ struct rte_console { * Shared structure between dongle and the host. * The structure contains pointers to trap or assert information. */ -#define SDPCM_SHARED_VERSION 0x0003 +#define SDPCM_SHARED_VERSION 0x0002 #define SDPCM_SHARED_VERSION_MASK 0x00FF #define SDPCM_SHARED_ASSERT_BUILT 0x0100 #define SDPCM_SHARED_ASSERT 0x0200 @@ -433,29 +428,6 @@ struct brcmf_console { u8 *buf; /* Log buffer (host copy) */ uint last; /* Last buffer read index */ }; - -struct brcmf_trap_info { - __le32 type; - __le32 epc; - __le32 cpsr; - __le32 spsr; - __le32 r0; /* a1 */ - __le32 r1; /* a2 */ - __le32 r2; /* a3 */ - __le32 r3; /* a4 */ - __le32 r4; /* v1 */ - __le32 r5; /* v2 */ - __le32 r6; /* v3 */ - __le32 r7; /* v4 */ - __le32 r8; /* v5 */ - __le32 r9; /* sb/v6 */ - __le32 r10; /* sl/v7 */ - __le32 r11; /* fp/v8 */ - __le32 r12; /* ip */ - __le32 r13; /* sp */ - __le32 r14; /* lr */ - __le32 pc; /* r15 */ -}; #endif /* DEBUG */ struct sdpcm_shared { @@ -467,7 +439,6 @@ struct sdpcm_shared { u32 console_addr; /* Address of struct rte_console */ u32 msgtrace_addr; u8 tag[32]; - u32 brpt_addr; }; struct sdpcm_shared_le { @@ -479,7 +450,6 @@ struct sdpcm_shared_le { __le32 console_addr; /* Address of struct rte_console */ __le32 msgtrace_addr; u8 tag[32]; - __le32 brpt_addr; }; @@ -532,9 +502,12 @@ struct brcmf_sdio { bool intr; /* Use interrupts */ bool poll; /* Use polling */ bool ipend; /* Device interrupt is pending */ + uint intrcount; /* Count of device interrupt callbacks */ + uint lastintrs; /* Count as of last watchdog timer */ uint spurious; /* Count of spurious interrupts */ uint pollrate; /* Ticks between device polls */ uint polltick; /* Tick counter */ + uint pollcnt; /* Count of active polls */ #ifdef DEBUG uint console_interval; @@ -542,6 +515,8 @@ struct brcmf_sdio { uint console_addr; /* Console address from shared struct */ #endif /* DEBUG */ + uint regfails; /* Count of R_REG failures */ + uint clkstate; /* State of sd and backplane clock(s) */ bool activity; /* Activity flag for clock down */ s32 idletime; /* Control for activity timeout */ @@ -556,6 +531,33 @@ struct brcmf_sdio { /* Field to decide if rx of control frames happen in rxbuf or lb-pool */ bool usebufpool; + /* Some additional counters */ + uint tx_sderrs; /* Count of tx attempts with sd errors */ + uint fcqueued; /* Tx packets that got queued */ + uint rxrtx; /* Count of rtx requests (NAK to dongle) */ + uint rx_toolong; /* Receive frames too long to receive */ + uint rxc_errors; /* SDIO errors when reading control frames */ + uint rx_hdrfail; /* SDIO errors on header reads */ + uint rx_badhdr; /* Bad received headers (roosync?) */ + uint rx_badseq; /* Mismatched rx sequence number */ + uint fc_rcvd; /* Number of flow-control events received */ + uint fc_xoff; /* Number which turned on flow-control */ + uint fc_xon; /* Number which turned off flow-control */ + uint rxglomfail; /* Failed deglom attempts */ + uint rxglomframes; /* Number of glom frames (superframes) */ + uint rxglompkts; /* Number of packets from glom frames */ + uint f2rxhdrs; /* Number of header reads */ + uint f2rxdata; /* Number of frame data reads */ + uint f2txdata; /* Number of f2 frame writes */ + uint f1regdata; /* Number of f1 register accesses */ + uint tickcnt; /* Number of watchdog been schedule */ + unsigned long tx_ctlerrs; /* Err of sending ctrl frames */ + unsigned long tx_ctlpkts; /* Ctrl frames sent to dongle */ + unsigned long rx_ctlerrs; /* Err of processing rx ctrl frames */ + unsigned long rx_ctlpkts; /* Ctrl frames processed from dongle */ + unsigned long rx_readahead_cnt; /* Number of packets where header + * read-ahead was used. */ + u8 *ctrl_frame_buf; u32 ctrl_frame_len; bool ctrl_frame_stat; @@ -581,7 +583,6 @@ struct brcmf_sdio { u32 fw_ptr; bool txoff; /* Transmit flow-controlled */ - struct brcmf_sdio_count sdcnt; }; /* clkstate */ @@ -944,7 +945,7 @@ static u32 brcmf_sdbrcm_hostmail(struct brcmf_sdio *bus) if (ret == 0) w_sdreg32(bus, SMB_INT_ACK, offsetof(struct sdpcmd_regs, tosbmailbox)); - bus->sdcnt.f1regdata += 2; + bus->f1regdata += 2; /* Dongle recomposed rx frames, accept them again */ if (hmb_data & HMB_DATA_NAKHANDLED) { @@ -983,12 +984,12 @@ static u32 brcmf_sdbrcm_hostmail(struct brcmf_sdio *bus) HMB_DATA_FCDATA_SHIFT; if (fcbits & ~bus->flowcontrol) - bus->sdcnt.fc_xoff++; + bus->fc_xoff++; if (bus->flowcontrol & ~fcbits) - bus->sdcnt.fc_xon++; + bus->fc_xon++; - bus->sdcnt.fc_rcvd++; + bus->fc_rcvd++; bus->flowcontrol = fcbits; } @@ -1020,7 +1021,7 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx) brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_RF_TERM, &err); - bus->sdcnt.f1regdata++; + bus->f1regdata++; /* Wait until the packet has been flushed (device/FIFO stable) */ for (lastrbc = retries = 0xffff; retries > 0; retries--) { @@ -1028,7 +1029,7 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx) SBSDIO_FUNC1_RFRAMEBCHI, &err); lo = brcmf_sdio_regrb(bus->sdiodev, SBSDIO_FUNC1_RFRAMEBCLO, &err); - bus->sdcnt.f1regdata += 2; + bus->f1regdata += 2; if ((hi == 0) && (lo == 0)) break; @@ -1046,11 +1047,11 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx) brcmf_dbg(INFO, "flush took %d iterations\n", 0xffff - retries); if (rtx) { - bus->sdcnt.rxrtx++; + bus->rxrtx++; err = w_sdreg32(bus, SMB_NAK, offsetof(struct sdpcmd_regs, tosbmailbox)); - bus->sdcnt.f1regdata++; + bus->f1regdata++; if (err == 0) bus->rxskip = true; } @@ -1242,7 +1243,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) dlen); errcode = -1; } - bus->sdcnt.f2rxdata++; + bus->f2rxdata++; /* On failure, kill the superframe, allow a couple retries */ if (errcode < 0) { @@ -1255,7 +1256,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) } else { bus->glomerr = 0; brcmf_sdbrcm_rxfail(bus, true, false); - bus->sdcnt.rxglomfail++; + bus->rxglomfail++; brcmf_sdbrcm_free_glom(bus); } return 0; @@ -1311,7 +1312,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) if (rxseq != seq) { brcmf_dbg(INFO, "(superframe) rx_seq %d, expected %d\n", seq, rxseq); - bus->sdcnt.rx_badseq++; + bus->rx_badseq++; rxseq = seq; } @@ -1375,7 +1376,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) } else { bus->glomerr = 0; brcmf_sdbrcm_rxfail(bus, true, false); - bus->sdcnt.rxglomfail++; + bus->rxglomfail++; brcmf_sdbrcm_free_glom(bus); } bus->nextlen = 0; @@ -1401,7 +1402,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) if (rxseq != seq) { brcmf_dbg(GLOM, "rx_seq %d, expected %d\n", seq, rxseq); - bus->sdcnt.rx_badseq++; + bus->rx_badseq++; rxseq = seq; } rxseq++; @@ -1440,8 +1441,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) down(&bus->sdsem); } - bus->sdcnt.rxglomframes++; - bus->sdcnt.rxglompkts += bus->glom.qlen; + bus->rxglomframes++; + bus->rxglompkts += bus->glom.qlen; } return num; } @@ -1525,7 +1526,7 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) brcmf_dbg(ERROR, "%d-byte ctl frame (%d-byte ctl data) exceeds %d-byte limit\n", len, len - doff, bus->sdiodev->bus_if->maxctl); bus->sdiodev->bus_if->dstats.rx_errors++; - bus->sdcnt.rx_toolong++; + bus->rx_toolong++; brcmf_sdbrcm_rxfail(bus, false, false); goto done; } @@ -1535,13 +1536,13 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) bus->sdiodev->sbwad, SDIO_FUNC_2, F2SYNC, (bus->rxctl + BRCMF_FIRSTREAD), rdlen); - bus->sdcnt.f2rxdata++; + bus->f2rxdata++; /* Control frame failures need retransmission */ if (sdret < 0) { brcmf_dbg(ERROR, "read %d control bytes failed: %d\n", rdlen, sdret); - bus->sdcnt.rxc_errors++; + bus->rxc_errors++; brcmf_sdbrcm_rxfail(bus, true, true); goto done; } @@ -1588,7 +1589,7 @@ brcmf_alloc_pkt_and_read(struct brcmf_sdio *bus, u16 rdlen, /* Read the entire frame */ sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad, SDIO_FUNC_2, F2SYNC, *pkt); - bus->sdcnt.f2rxdata++; + bus->f2rxdata++; if (sdret < 0) { brcmf_dbg(ERROR, "(nextlen): read %d bytes failed: %d\n", @@ -1629,7 +1630,7 @@ brcmf_check_rxbuf(struct brcmf_sdio *bus, struct sk_buff *pkt, u8 *rxbuf, if ((u16)~(*len ^ check)) { brcmf_dbg(ERROR, "(nextlen): HW hdr error: nextlen/len/check 0x%04x/0x%04x/0x%04x\n", nextlen, *len, check); - bus->sdcnt.rx_badhdr++; + bus->rx_badhdr++; brcmf_sdbrcm_rxfail(bus, false, false); goto fail; } @@ -1745,7 +1746,7 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) bus->nextlen = 0; } - bus->sdcnt.rx_readahead_cnt++; + bus->rx_readahead_cnt++; /* Handle Flow Control */ fcbits = SDPCM_FCMASK_VALUE( @@ -1753,12 +1754,12 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) if (bus->flowcontrol != fcbits) { if (~bus->flowcontrol & fcbits) - bus->sdcnt.fc_xoff++; + bus->fc_xoff++; if (bus->flowcontrol & ~fcbits) - bus->sdcnt.fc_xon++; + bus->fc_xon++; - bus->sdcnt.fc_rcvd++; + bus->fc_rcvd++; bus->flowcontrol = fcbits; } @@ -1766,7 +1767,7 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) if (rxseq != seq) { brcmf_dbg(INFO, "(nextlen): rx_seq %d, expected %d\n", seq, rxseq); - bus->sdcnt.rx_badseq++; + bus->rx_badseq++; rxseq = seq; } @@ -1813,11 +1814,11 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) sdret = brcmf_sdcard_recv_buf(bus->sdiodev, bus->sdiodev->sbwad, SDIO_FUNC_2, F2SYNC, bus->rxhdr, BRCMF_FIRSTREAD); - bus->sdcnt.f2rxhdrs++; + bus->f2rxhdrs++; if (sdret < 0) { brcmf_dbg(ERROR, "RXHEADER FAILED: %d\n", sdret); - bus->sdcnt.rx_hdrfail++; + bus->rx_hdrfail++; brcmf_sdbrcm_rxfail(bus, true, true); continue; } @@ -1839,7 +1840,7 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) if ((u16) ~(len ^ check)) { brcmf_dbg(ERROR, "HW hdr err: len/check 0x%04x/0x%04x\n", len, check); - bus->sdcnt.rx_badhdr++; + bus->rx_badhdr++; brcmf_sdbrcm_rxfail(bus, false, false); continue; } @@ -1860,7 +1861,7 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) if ((doff < SDPCM_HDRLEN) || (doff > len)) { brcmf_dbg(ERROR, "Bad data offset %d: HW len %d, min %d seq %d\n", doff, len, SDPCM_HDRLEN, seq); - bus->sdcnt.rx_badhdr++; + bus->rx_badhdr++; brcmf_sdbrcm_rxfail(bus, false, false); continue; } @@ -1879,19 +1880,19 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) if (bus->flowcontrol != fcbits) { if (~bus->flowcontrol & fcbits) - bus->sdcnt.fc_xoff++; + bus->fc_xoff++; if (bus->flowcontrol & ~fcbits) - bus->sdcnt.fc_xon++; + bus->fc_xon++; - bus->sdcnt.fc_rcvd++; + bus->fc_rcvd++; bus->flowcontrol = fcbits; } /* Check and update sequence number */ if (rxseq != seq) { brcmf_dbg(INFO, "rx_seq %d, expected %d\n", seq, rxseq); - bus->sdcnt.rx_badseq++; + bus->rx_badseq++; rxseq = seq; } @@ -1936,7 +1937,7 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) brcmf_dbg(ERROR, "too long: len %d rdlen %d\n", len, rdlen); bus->sdiodev->bus_if->dstats.rx_errors++; - bus->sdcnt.rx_toolong++; + bus->rx_toolong++; brcmf_sdbrcm_rxfail(bus, false, false); continue; } @@ -1959,7 +1960,7 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) /* Read the remaining frame data */ sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad, SDIO_FUNC_2, F2SYNC, pkt); - bus->sdcnt.f2rxdata++; + bus->f2rxdata++; if (sdret < 0) { brcmf_dbg(ERROR, "read %d %s bytes failed: %d\n", rdlen, @@ -2146,18 +2147,18 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad, SDIO_FUNC_2, F2SYNC, pkt); - bus->sdcnt.f2txdata++; + bus->f2txdata++; if (ret < 0) { /* On failure, abort the command and terminate the frame */ brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n", ret); - bus->sdcnt.tx_sderrs++; + bus->tx_sderrs++; brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2); brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL); - bus->sdcnt.f1regdata++; + bus->f1regdata++; for (i = 0; i < 3; i++) { u8 hi, lo; @@ -2165,7 +2166,7 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, SBSDIO_FUNC1_WFRAMEBCHI, NULL); lo = brcmf_sdio_regrb(bus->sdiodev, SBSDIO_FUNC1_WFRAMEBCLO, NULL); - bus->sdcnt.f1regdata += 2; + bus->f1regdata += 2; if ((hi == 0) && (lo == 0)) break; } @@ -2223,7 +2224,7 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes) ret = r_sdreg32(bus, &intstatus, offsetof(struct sdpcmd_regs, intstatus)); - bus->sdcnt.f2txdata++; + bus->f2txdata++; if (ret != 0) break; if (intstatus & bus->hostintmask) @@ -2416,7 +2417,7 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) bus->ipend = false; err = r_sdreg32(bus, &newstatus, offsetof(struct sdpcmd_regs, intstatus)); - bus->sdcnt.f1regdata++; + bus->f1regdata++; if (err != 0) newstatus = 0; newstatus &= bus->hostintmask; @@ -2425,7 +2426,7 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) err = w_sdreg32(bus, newstatus, offsetof(struct sdpcmd_regs, intstatus)); - bus->sdcnt.f1regdata++; + bus->f1regdata++; } } @@ -2444,7 +2445,7 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) err = r_sdreg32(bus, &newstatus, offsetof(struct sdpcmd_regs, intstatus)); - bus->sdcnt.f1regdata += 2; + bus->f1regdata += 2; bus->fcstate = !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE)); intstatus |= (newstatus & bus->hostintmask); @@ -2509,13 +2510,13 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) terminate the frame */ brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n", ret); - bus->sdcnt.tx_sderrs++; + bus->tx_sderrs++; brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2); brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, &err); - bus->sdcnt.f1regdata++; + bus->f1regdata++; for (i = 0; i < 3; i++) { u8 hi, lo; @@ -2525,7 +2526,7 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) lo = brcmf_sdio_regrb(bus->sdiodev, SBSDIO_FUNC1_WFRAMEBCLO, &err); - bus->sdcnt.f1regdata += 2; + bus->f1regdata += 2; if ((hi == 0) && (lo == 0)) break; } @@ -2656,7 +2657,7 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) /* Check for existing queue, current flow-control, pending event, or pending clock */ brcmf_dbg(TRACE, "deferring pktq len %d\n", pktq_len(&bus->txq)); - bus->sdcnt.fcqueued++; + bus->fcqueued++; /* Priority based enq */ spin_lock_bh(&bus->txqlock); @@ -2844,13 +2845,13 @@ static int brcmf_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len) /* On failure, abort the command and terminate the frame */ brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n", ret); - bus->sdcnt.tx_sderrs++; + bus->tx_sderrs++; brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2); brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL); - bus->sdcnt.f1regdata++; + bus->f1regdata++; for (i = 0; i < 3; i++) { u8 hi, lo; @@ -2858,7 +2859,7 @@ static int brcmf_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len) SBSDIO_FUNC1_WFRAMEBCHI, NULL); lo = brcmf_sdio_regrb(bus->sdiodev, SBSDIO_FUNC1_WFRAMEBCLO, NULL); - bus->sdcnt.f1regdata += 2; + bus->f1regdata += 2; if (hi == 0 && lo == 0) break; } @@ -2975,324 +2976,13 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) up(&bus->sdsem); if (ret) - bus->sdcnt.tx_ctlerrs++; + bus->tx_ctlerrs++; else - bus->sdcnt.tx_ctlpkts++; + bus->tx_ctlpkts++; return ret ? -EIO : 0; } -#ifdef DEBUG -static inline bool brcmf_sdio_valid_shared_address(u32 addr) -{ - return !(addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff)); -} - -static int brcmf_sdio_readshared(struct brcmf_sdio *bus, - struct sdpcm_shared *sh) -{ - u32 addr; - int rv; - u32 shaddr = 0; - struct sdpcm_shared_le sh_le; - __le32 addr_le; - - shaddr = bus->ramsize - 4; - - /* - * Read last word in socram to determine - * address of sdpcm_shared structure - */ - rv = brcmf_sdbrcm_membytes(bus, false, shaddr, - (u8 *)&addr_le, 4); - if (rv < 0) - return rv; - - addr = le32_to_cpu(addr_le); - - brcmf_dbg(INFO, "sdpcm_shared address 0x%08X\n", addr); - - /* - * Check if addr is valid. - * NVRAM length at the end of memory should have been overwritten. - */ - if (!brcmf_sdio_valid_shared_address(addr)) { - brcmf_dbg(ERROR, "invalid sdpcm_shared address 0x%08X\n", - addr); - return -EINVAL; - } - - /* Read hndrte_shared structure */ - rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&sh_le, - sizeof(struct sdpcm_shared_le)); - if (rv < 0) - return rv; - - /* Endianness */ - sh->flags = le32_to_cpu(sh_le.flags); - sh->trap_addr = le32_to_cpu(sh_le.trap_addr); - sh->assert_exp_addr = le32_to_cpu(sh_le.assert_exp_addr); - sh->assert_file_addr = le32_to_cpu(sh_le.assert_file_addr); - sh->assert_line = le32_to_cpu(sh_le.assert_line); - sh->console_addr = le32_to_cpu(sh_le.console_addr); - sh->msgtrace_addr = le32_to_cpu(sh_le.msgtrace_addr); - - if ((sh->flags & SDPCM_SHARED_VERSION_MASK) != SDPCM_SHARED_VERSION) { - brcmf_dbg(ERROR, - "sdpcm_shared version mismatch: dhd %d dongle %d\n", - SDPCM_SHARED_VERSION, - sh->flags & SDPCM_SHARED_VERSION_MASK); - return -EPROTO; - } - - return 0; -} - -static int brcmf_sdio_dump_console(struct brcmf_sdio *bus, - struct sdpcm_shared *sh, char __user *data, - size_t count) -{ - u32 addr, console_ptr, console_size, console_index; - char *conbuf = NULL; - __le32 sh_val; - int rv; - loff_t pos = 0; - int nbytes = 0; - - /* obtain console information from device memory */ - addr = sh->console_addr + offsetof(struct rte_console, log_le); - rv = brcmf_sdbrcm_membytes(bus, false, addr, - (u8 *)&sh_val, sizeof(u32)); - if (rv < 0) - return rv; - console_ptr = le32_to_cpu(sh_val); - - addr = sh->console_addr + offsetof(struct rte_console, log_le.buf_size); - rv = brcmf_sdbrcm_membytes(bus, false, addr, - (u8 *)&sh_val, sizeof(u32)); - if (rv < 0) - return rv; - console_size = le32_to_cpu(sh_val); - - addr = sh->console_addr + offsetof(struct rte_console, log_le.idx); - rv = brcmf_sdbrcm_membytes(bus, false, addr, - (u8 *)&sh_val, sizeof(u32)); - if (rv < 0) - return rv; - console_index = le32_to_cpu(sh_val); - - /* allocate buffer for console data */ - if (console_size <= CONSOLE_BUFFER_MAX) - conbuf = vzalloc(console_size+1); - - if (!conbuf) - return -ENOMEM; - - /* obtain the console data from device */ - conbuf[console_size] = '\0'; - rv = brcmf_sdbrcm_membytes(bus, false, console_ptr, (u8 *)conbuf, - console_size); - if (rv < 0) - goto done; - - rv = simple_read_from_buffer(data, count, &pos, - conbuf + console_index, - console_size - console_index); - if (rv < 0) - goto done; - - nbytes = rv; - if (console_index > 0) { - pos = 0; - rv = simple_read_from_buffer(data+nbytes, count, &pos, - conbuf, console_index - 1); - if (rv < 0) - goto done; - rv += nbytes; - } -done: - vfree(conbuf); - return rv; -} - -static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh, - char __user *data, size_t count) -{ - int error, res; - char buf[350]; - struct brcmf_trap_info tr; - int nbytes; - loff_t pos = 0; - - if ((sh->flags & SDPCM_SHARED_TRAP) == 0) - return 0; - - 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); - if (nbytes < 0) - return nbytes; - - res = scnprintf(buf, sizeof(buf), - "dongle trap info: type 0x%x @ epc 0x%08x\n" - " cpsr 0x%08x spsr 0x%08x sp 0x%08x\n" - " lr 0x%08x pc 0x%08x offset 0x%x\n" - " r0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x\n" - " r4 0x%08x r5 0x%08x r6 0x%08x r7 0x%08x\n", - le32_to_cpu(tr.type), le32_to_cpu(tr.epc), - le32_to_cpu(tr.cpsr), le32_to_cpu(tr.spsr), - le32_to_cpu(tr.r13), le32_to_cpu(tr.r14), - le32_to_cpu(tr.pc), sh->trap_addr, - le32_to_cpu(tr.r0), le32_to_cpu(tr.r1), - le32_to_cpu(tr.r2), le32_to_cpu(tr.r3), - le32_to_cpu(tr.r4), le32_to_cpu(tr.r5), - le32_to_cpu(tr.r6), le32_to_cpu(tr.r7)); - - error = simple_read_from_buffer(data+nbytes, count, &pos, buf, res); - if (error < 0) - return error; - - nbytes += error; - return nbytes; -} - -static int brcmf_sdio_assert_info(struct brcmf_sdio *bus, - struct sdpcm_shared *sh, char __user *data, - size_t count) -{ - int error = 0; - char buf[200]; - char file[80] = "?"; - char expr[80] = ""; - int res; - loff_t pos = 0; - - if ((sh->flags & SDPCM_SHARED_ASSERT_BUILT) == 0) { - brcmf_dbg(INFO, "firmware not built with -assert\n"); - return 0; - } else if ((sh->flags & SDPCM_SHARED_ASSERT) == 0) { - brcmf_dbg(INFO, "no assert in dongle\n"); - return 0; - } - - if (sh->assert_file_addr != 0) { - error = brcmf_sdbrcm_membytes(bus, false, sh->assert_file_addr, - (u8 *)file, 80); - if (error < 0) - return error; - } - if (sh->assert_exp_addr != 0) { - error = brcmf_sdbrcm_membytes(bus, false, sh->assert_exp_addr, - (u8 *)expr, 80); - if (error < 0) - return error; - } - - res = scnprintf(buf, sizeof(buf), - "dongle assert: %s:%d: assert(%s)\n", - file, sh->assert_line, expr); - return simple_read_from_buffer(data, count, &pos, buf, res); -} - -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; - - if ((sh.flags & SDPCM_SHARED_ASSERT_BUILT) == 0) - brcmf_dbg(INFO, "firmware not built with -assert\n"); - else if (sh.flags & SDPCM_SHARED_ASSERT) - brcmf_dbg(ERROR, "assertion in dongle\n"); - - if (sh.flags & SDPCM_SHARED_TRAP) - brcmf_dbg(ERROR, "firmware trap in dongle\n"); - - return 0; -} - -static int brcmf_sdbrcm_died_dump(struct brcmf_sdio *bus, char __user *data, - size_t count, loff_t *ppos) -{ - int error = 0; - struct sdpcm_shared sh; - int nbytes = 0; - loff_t pos = *ppos; - - if (pos != 0) - return 0; - - down(&bus->sdsem); - error = brcmf_sdio_readshared(bus, &sh); - if (error < 0) - goto done; - - error = brcmf_sdio_assert_info(bus, &sh, data, count); - if (error < 0) - goto done; - - nbytes = error; - error = brcmf_sdio_trap_info(bus, &sh, data, count); - if (error < 0) - goto done; - - error += nbytes; - *ppos += error; -done: - up(&bus->sdsem); - return error; -} - -static ssize_t brcmf_sdio_forensic_read(struct file *f, char __user *data, - size_t count, loff_t *ppos) -{ - struct brcmf_sdio *bus = f->private_data; - int res; - - res = brcmf_sdbrcm_died_dump(bus, data, count, ppos); - if (res > 0) - *ppos += res; - return (ssize_t)res; -} - -static const struct file_operations brcmf_sdio_forensic_ops = { - .owner = THIS_MODULE, - .open = simple_open, - .read = brcmf_sdio_forensic_read -}; - -static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus) -{ - struct brcmf_pub *drvr = bus->sdiodev->bus_if->drvr; - struct dentry *dentry = brcmf_debugfs_get_devdir(drvr); - - if (IS_ERR_OR_NULL(dentry)) - return; - - debugfs_create_file("forensics", S_IRUGO, dentry, bus, - &brcmf_sdio_forensic_ops); - brcmf_debugfs_create_sdio_count(drvr, &bus->sdcnt); -} -#else -static int brcmf_sdbrcm_checkdied(struct brcmf_sdio *bus) -{ - return 0; -} - -static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus) -{ -} -#endif /* DEBUG */ - static int brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) { @@ -3319,27 +3009,60 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) rxlen, msglen); } else if (timeleft == 0) { brcmf_dbg(ERROR, "resumed on timeout\n"); - brcmf_sdbrcm_checkdied(bus); } else if (pending) { brcmf_dbg(CTL, "cancelled\n"); return -ERESTARTSYS; } else { brcmf_dbg(CTL, "resumed for unknown reason?\n"); - brcmf_sdbrcm_checkdied(bus); } if (rxlen) - bus->sdcnt.rx_ctlpkts++; + bus->rx_ctlpkts++; else - bus->sdcnt.rx_ctlerrs++; + bus->rx_ctlerrs++; return rxlen ? (int)rxlen : -ETIMEDOUT; } +static int brcmf_sdbrcm_downloadvars(struct brcmf_sdio *bus, void *arg, int len) +{ + int bcmerror = 0; + + brcmf_dbg(TRACE, "Enter\n"); + + /* Basic sanity checks */ + if (bus->sdiodev->bus_if->drvr_up) { + bcmerror = -EISCONN; + goto err; + } + if (!len) { + bcmerror = -EOVERFLOW; + goto err; + } + + /* Free the old ones and replace with passed variables */ + kfree(bus->vars); + + bus->vars = kmalloc(len, GFP_ATOMIC); + bus->varsz = bus->vars ? len : 0; + if (bus->vars == NULL) { + bcmerror = -ENOMEM; + goto err; + } + + /* Copy the passed variables, which should include the + terminating double-null */ + memcpy(bus->vars, arg, bus->varsz); +err: + return bcmerror; +} + static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus) { int bcmerror = 0; + u32 varsize; u32 varaddr; + u8 *vbuffer; u32 varsizew; __le32 varsizew_le; #ifdef DEBUG @@ -3348,44 +3071,56 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus) /* Even if there are no vars are to be written, we still need to set the ramsize. */ - varaddr = (bus->ramsize - 4) - bus->varsz; + varsize = bus->varsz ? roundup(bus->varsz, 4) : 0; + varaddr = (bus->ramsize - 4) - varsize; if (bus->vars) { + vbuffer = kzalloc(varsize, GFP_ATOMIC); + if (!vbuffer) + return -ENOMEM; + + memcpy(vbuffer, bus->vars, bus->varsz); + /* Write the vars list */ - bcmerror = brcmf_sdbrcm_membytes(bus, true, varaddr, - bus->vars, bus->varsz); + bcmerror = + brcmf_sdbrcm_membytes(bus, true, varaddr, vbuffer, varsize); #ifdef DEBUG /* Verify NVRAM bytes */ - brcmf_dbg(INFO, "Compare NVRAM dl & ul; varsize=%d\n", - bus->varsz); - nvram_ularray = kmalloc(bus->varsz, GFP_ATOMIC); - if (!nvram_ularray) + brcmf_dbg(INFO, "Compare NVRAM dl & ul; varsize=%d\n", varsize); + nvram_ularray = kmalloc(varsize, GFP_ATOMIC); + if (!nvram_ularray) { + kfree(vbuffer); return -ENOMEM; + } /* Upload image to verify downloaded contents. */ - memset(nvram_ularray, 0xaa, bus->varsz); + memset(nvram_ularray, 0xaa, varsize); /* Read the vars list to temp buffer for comparison */ - bcmerror = brcmf_sdbrcm_membytes(bus, false, varaddr, - nvram_ularray, bus->varsz); + bcmerror = + brcmf_sdbrcm_membytes(bus, false, varaddr, nvram_ularray, + varsize); if (bcmerror) { brcmf_dbg(ERROR, "error %d on reading %d nvram bytes at 0x%08x\n", - bcmerror, bus->varsz, varaddr); + bcmerror, varsize, varaddr); } /* Compare the org NVRAM with the one read from RAM */ - if (memcmp(bus->vars, nvram_ularray, bus->varsz)) + if (memcmp(vbuffer, nvram_ularray, varsize)) brcmf_dbg(ERROR, "Downloaded NVRAM image is corrupted\n"); else brcmf_dbg(ERROR, "Download/Upload/Compare of NVRAM ok\n"); kfree(nvram_ularray); #endif /* DEBUG */ + + kfree(vbuffer); } /* adjust to the user specified RAM */ brcmf_dbg(INFO, "Physical memory size: %d\n", bus->ramsize); brcmf_dbg(INFO, "Vars are at %d, orig varsize is %d\n", - varaddr, bus->varsz); + varaddr, varsize); + varsize = ((bus->ramsize - 4) - varaddr); /* * Determine the length token: @@ -3396,13 +3131,13 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus) varsizew = 0; varsizew_le = cpu_to_le32(0); } else { - varsizew = bus->varsz / 4; + varsizew = varsize / 4; varsizew = (~varsizew << 16) | (varsizew & 0x0000FFFF); varsizew_le = cpu_to_le32(varsizew); } brcmf_dbg(INFO, "New varsize is %d, length token=0x%08x\n", - bus->varsz, varsizew); + varsize, varsizew); /* Write the length token to the last word */ bcmerror = brcmf_sdbrcm_membytes(bus, true, (bus->ramsize - 4), @@ -3526,21 +3261,13 @@ static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus) * by two NULs. */ -static int brcmf_process_nvram_vars(struct brcmf_sdio *bus) +static uint brcmf_process_nvram_vars(char *varbuf, uint len) { - char *varbuf; char *dp; bool findNewline; int column; - int ret = 0; - uint buf_len, n, len; + uint buf_len, n; - len = bus->firmware->size; - varbuf = vmalloc(len); - if (!varbuf) - return -ENOMEM; - - memcpy(varbuf, bus->firmware->data, len); dp = varbuf; findNewline = false; @@ -3569,44 +3296,56 @@ static int brcmf_process_nvram_vars(struct brcmf_sdio *bus) column++; } buf_len = dp - varbuf; + while (dp < varbuf + n) *dp++ = 0; - kfree(bus->vars); - /* roundup needed for download to device */ - bus->varsz = roundup(buf_len + 1, 4); - bus->vars = kmalloc(bus->varsz, GFP_KERNEL); - if (bus->vars == NULL) { - bus->varsz = 0; - ret = -ENOMEM; - goto err; - } - - /* copy the processed variables and add null termination */ - memcpy(bus->vars, varbuf, buf_len); - bus->vars[buf_len] = 0; -err: - vfree(varbuf); - return ret; + return buf_len; } static int brcmf_sdbrcm_download_nvram(struct brcmf_sdio *bus) { + uint len; + char *memblock = NULL; + char *bufp; int ret; - if (bus->sdiodev->bus_if->drvr_up) - return -EISCONN; - ret = request_firmware(&bus->firmware, BRCMF_SDIO_NV_NAME, &bus->sdiodev->func[2]->dev); if (ret) { brcmf_dbg(ERROR, "Fail to request nvram %d\n", ret); return ret; } + bus->fw_ptr = 0; + + memblock = kmalloc(MEMBLOCK, GFP_ATOMIC); + if (memblock == NULL) { + ret = -ENOMEM; + goto err; + } + + len = brcmf_sdbrcm_get_image(memblock, MEMBLOCK, bus); + + if (len > 0 && len < MEMBLOCK) { + bufp = (char *)memblock; + bufp[len] = 0; + len = brcmf_process_nvram_vars(bufp, len); + bufp += len; + *bufp++ = 0; + if (len) + ret = brcmf_sdbrcm_downloadvars(bus, memblock, len + 1); + if (ret) + brcmf_dbg(ERROR, "error downloading vars: %d\n", ret); + } else { + brcmf_dbg(ERROR, "error reading nvram file: %d\n", len); + ret = -EIO; + } - ret = brcmf_process_nvram_vars(bus); +err: + kfree(memblock); release_firmware(bus->firmware); + bus->fw_ptr = 0; return ret; } @@ -3680,7 +3419,7 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) return 0; /* Start the watchdog timer */ - bus->sdcnt.tickcnt = 0; + bus->tickcnt = 0; brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); down(&bus->sdsem); @@ -3773,7 +3512,7 @@ void brcmf_sdbrcm_isr(void *arg) return; } /* Count the interrupt call */ - bus->sdcnt.intrcount++; + bus->intrcount++; bus->ipend = true; /* Shouldn't get this interrupt if we're sleeping? */ @@ -3815,8 +3554,7 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) bus->polltick = 0; /* Check device if no interrupts */ - if (!bus->intr || - (bus->sdcnt.intrcount == bus->sdcnt.lastintrs)) { + if (!bus->intr || (bus->intrcount == bus->lastintrs)) { if (!bus->dpc_sched) { u8 devpend; @@ -3831,7 +3569,7 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) /* If there is something, make like the ISR and schedule the DPC */ if (intstatus) { - bus->sdcnt.pollcnt++; + bus->pollcnt++; bus->ipend = true; bus->dpc_sched = true; @@ -3843,7 +3581,7 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) } /* Update interrupt tracking */ - bus->sdcnt.lastintrs = bus->sdcnt.intrcount; + bus->lastintrs = bus->intrcount; } #ifdef DEBUG /* Poll for console output periodically */ @@ -3885,8 +3623,6 @@ static bool brcmf_sdbrcm_chipmatch(u16 chipid) return true; if (chipid == BCM4330_CHIP_ID) return true; - if (chipid == BCM4334_CHIP_ID) - return true; return false; } @@ -4057,7 +3793,7 @@ brcmf_sdbrcm_watchdog_thread(void *data) if (!wait_for_completion_interruptible(&bus->watchdog_wait)) { brcmf_sdbrcm_bus_watchdog(bus); /* Count the tick for reference */ - bus->sdcnt.tickcnt++; + bus->tickcnt++; } else break; } @@ -4120,10 +3856,6 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) { int ret; struct brcmf_sdio *bus; - struct brcmf_bus_dcmd *dlst; - u32 dngl_txglom; - u32 dngl_txglomalign; - u8 idx; brcmf_dbg(TRACE, "Enter\n"); @@ -4206,29 +3938,8 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) goto fail; } - brcmf_sdio_debugfs_create(bus); brcmf_dbg(INFO, "completed!!\n"); - /* sdio bus core specific dcmd */ - idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV); - dlst = kzalloc(sizeof(struct brcmf_bus_dcmd), GFP_KERNEL); - if (dlst) { - if (bus->ci->c_inf[idx].rev < 12) { - /* for sdio core rev < 12, disable txgloming */ - dngl_txglom = 0; - dlst->name = "bus:txglom"; - dlst->param = (char *)&dngl_txglom; - dlst->param_len = sizeof(u32); - } else { - /* otherwise, set txglomalign */ - dngl_txglomalign = bus->sdiodev->bus_if->align; - dlst->name = "bus:txglomalign"; - dlst->param = (char *)&dngl_txglomalign; - dlst->param_len = sizeof(u32); - } - list_add(&dlst->list, &bus->sdiodev->bus_if->dcmd_list); - } - /* if firmware path present try to download and bring up bus */ ret = brcmf_bus_start(bus->sdiodev->dev); if (ret != 0) { diff --git a/trunk/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/trunk/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c index 58155e23d220..f8e1f1c84d08 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c @@ -403,23 +403,6 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, ci->c_inf[3].cib = 0x03004211; ci->ramsize = 0x48000; break; - case BCM4334_CHIP_ID: - ci->c_inf[0].wrapbase = 0x18100000; - ci->c_inf[0].cib = 0x29004211; - ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; - ci->c_inf[1].base = 0x18002000; - ci->c_inf[1].wrapbase = 0x18102000; - ci->c_inf[1].cib = 0x0d004211; - ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM; - ci->c_inf[2].base = 0x18004000; - ci->c_inf[2].wrapbase = 0x18104000; - ci->c_inf[2].cib = 0x13080401; - ci->c_inf[3].id = BCMA_CORE_ARM_CM3; - ci->c_inf[3].base = 0x18003000; - ci->c_inf[3].wrapbase = 0x18103000; - ci->c_inf[3].cib = 0x07004211; - ci->ramsize = 0x80000; - break; default: brcmf_dbg(ERROR, "chipid 0x%x is not supported\n", ci->chip); return -ENODEV; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c index 01b190a25d94..95b5902bc4b3 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c @@ -735,8 +735,10 @@ brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi, * a candidate for aggregation */ p = pktq_ppeek(&qi->q, prec); + /* tx_info must be checked with current p */ + tx_info = IEEE80211_SKB_CB(p); + 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; @@ -757,7 +759,6 @@ brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi, p = NULL; continue; } - /* next packet fit for aggregation so dequeue */ p = brcmu_pktq_pdeq(&qi->q, prec); } else { p = NULL; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/channel.c index 2d365d3486df..eb77ac3cfb6b 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/channel.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/channel.c @@ -15,9 +15,7 @@ */ #include -#include #include -#include #include #include "pub.h" @@ -25,17 +23,73 @@ #include "main.h" #include "stf.h" #include "channel.h" -#include "mac80211_if.h" /* QDB() macro takes a dB value and converts to a quarter dB value */ #define QDB(n) ((n) * BRCMS_TXPWR_DB_FACTOR) +#define LOCALE_CHAN_01_11 (1<<0) +#define LOCALE_CHAN_12_13 (1<<1) +#define LOCALE_CHAN_14 (1<<2) +#define LOCALE_SET_5G_LOW_JP1 (1<<3) /* 34-48, step 2 */ +#define LOCALE_SET_5G_LOW_JP2 (1<<4) /* 34-46, step 4 */ +#define LOCALE_SET_5G_LOW1 (1<<5) /* 36-48, step 4 */ +#define LOCALE_SET_5G_LOW2 (1<<6) /* 52 */ +#define LOCALE_SET_5G_LOW3 (1<<7) /* 56-64, step 4 */ +#define LOCALE_SET_5G_MID1 (1<<8) /* 100-116, step 4 */ +#define LOCALE_SET_5G_MID2 (1<<9) /* 120-124, step 4 */ +#define LOCALE_SET_5G_MID3 (1<<10) /* 128 */ +#define LOCALE_SET_5G_HIGH1 (1<<11) /* 132-140, step 4 */ +#define LOCALE_SET_5G_HIGH2 (1<<12) /* 149-161, step 4 */ +#define LOCALE_SET_5G_HIGH3 (1<<13) /* 165 */ +#define LOCALE_CHAN_52_140_ALL (1<<14) +#define LOCALE_SET_5G_HIGH4 (1<<15) /* 184-216 */ + +#define LOCALE_CHAN_36_64 (LOCALE_SET_5G_LOW1 | \ + LOCALE_SET_5G_LOW2 | \ + LOCALE_SET_5G_LOW3) +#define LOCALE_CHAN_52_64 (LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3) +#define LOCALE_CHAN_100_124 (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2) +#define LOCALE_CHAN_100_140 (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2 | \ + LOCALE_SET_5G_MID3 | LOCALE_SET_5G_HIGH1) +#define LOCALE_CHAN_149_165 (LOCALE_SET_5G_HIGH2 | LOCALE_SET_5G_HIGH3) +#define LOCALE_CHAN_184_216 LOCALE_SET_5G_HIGH4 + +#define LOCALE_CHAN_01_14 (LOCALE_CHAN_01_11 | \ + LOCALE_CHAN_12_13 | \ + LOCALE_CHAN_14) + +#define LOCALE_RADAR_SET_NONE 0 +#define LOCALE_RADAR_SET_1 1 + +#define LOCALE_RESTRICTED_NONE 0 +#define LOCALE_RESTRICTED_SET_2G_SHORT 1 +#define LOCALE_RESTRICTED_CHAN_165 2 +#define LOCALE_CHAN_ALL_5G 3 +#define LOCALE_RESTRICTED_JAPAN_LEGACY 4 +#define LOCALE_RESTRICTED_11D_2G 5 +#define LOCALE_RESTRICTED_11D_5G 6 +#define LOCALE_RESTRICTED_LOW_HI 7 +#define LOCALE_RESTRICTED_12_13_14 8 + +#define LOCALE_2G_IDX_i 0 +#define LOCALE_5G_IDX_11 0 #define LOCALE_MIMO_IDX_bn 0 #define LOCALE_MIMO_IDX_11n 0 +/* max of BAND_5G_PWR_LVLS and 6 for 2.4 GHz */ +#define BRCMS_MAXPWR_TBL_SIZE 6 /* max of BAND_5G_PWR_LVLS and 14 for 2.4 GHz */ #define BRCMS_MAXPWR_MIMO_TBL_SIZE 14 +/* power level in group of 2.4GHz band channels: + * maxpwr[0] - CCK channels [1] + * maxpwr[1] - CCK channels [2-10] + * maxpwr[2] - CCK channels [11-14] + * maxpwr[3] - OFDM channels [1] + * maxpwr[4] - OFDM channels [2-10] + * maxpwr[5] - OFDM channels [11-14] + */ + /* maxpwr mapping to 5GHz band channels: * maxpwr[0] - channels [34-48] * maxpwr[1] - channels [52-60] @@ -47,8 +101,16 @@ #define LC(id) LOCALE_MIMO_IDX_ ## id -#define LOCALES(mimo2, mimo5) \ - {LC(mimo2), LC(mimo5)} +#define LC_2G(id) LOCALE_2G_IDX_ ## id + +#define LC_5G(id) LOCALE_5G_IDX_ ## id + +#define LOCALES(band2, band5, mimo2, mimo5) \ + {LC_2G(band2), LC_5G(band5), LC(mimo2), LC(mimo5)} + +/* macro to get 2.4 GHz channel group index for tx power */ +#define CHANNEL_POWER_IDX_2G_CCK(c) (((c) < 2) ? 0 : (((c) < 11) ? 1 : 2)) +#define CHANNEL_POWER_IDX_2G_OFDM(c) (((c) < 2) ? 3 : (((c) < 11) ? 4 : 5)) /* macro to get 5 GHz channel group index for tx power */ #define CHANNEL_POWER_IDX_5G(c) (((c) < 52) ? 0 : \ @@ -56,37 +118,18 @@ (((c) < 100) ? 2 : \ (((c) < 149) ? 3 : 4)))) -#define BRCM_2GHZ_2412_2462 REG_RULE(2412-10, 2462+10, 40, 0, 19, 0) -#define BRCM_2GHZ_2467_2472 REG_RULE(2467-10, 2472+10, 20, 0, 19, \ - NL80211_RRF_PASSIVE_SCAN | \ - NL80211_RRF_NO_IBSS) - -#define BRCM_5GHZ_5180_5240 REG_RULE(5180-10, 5240+10, 40, 0, 21, \ - NL80211_RRF_PASSIVE_SCAN | \ - NL80211_RRF_NO_IBSS) -#define BRCM_5GHZ_5260_5320 REG_RULE(5260-10, 5320+10, 40, 0, 21, \ - NL80211_RRF_PASSIVE_SCAN | \ - NL80211_RRF_DFS | \ - NL80211_RRF_NO_IBSS) -#define BRCM_5GHZ_5500_5700 REG_RULE(5500-10, 5700+10, 40, 0, 21, \ - NL80211_RRF_PASSIVE_SCAN | \ - NL80211_RRF_DFS | \ - NL80211_RRF_NO_IBSS) -#define BRCM_5GHZ_5745_5825 REG_RULE(5745-10, 5825+10, 40, 0, 21, \ - NL80211_RRF_PASSIVE_SCAN | \ - NL80211_RRF_NO_IBSS) - -static const struct ieee80211_regdomain brcms_regdom_x2 = { - .n_reg_rules = 7, - .alpha2 = "X2", - .reg_rules = { - BRCM_2GHZ_2412_2462, - BRCM_2GHZ_2467_2472, - BRCM_5GHZ_5180_5240, - BRCM_5GHZ_5260_5320, - BRCM_5GHZ_5500_5700, - BRCM_5GHZ_5745_5825, - } +#define ISDFS_EU(fl) (((fl) & BRCMS_DFS_EU) == BRCMS_DFS_EU) + +struct brcms_cm_band { + /* struct locale_info flags */ + u8 locale_flags; + /* List of valid channels in the country */ + struct brcms_chanvec valid_channels; + /* List of restricted use channels */ + const struct brcms_chanvec *restricted_channels; + /* List of radar sensitive channels */ + const struct brcms_chanvec *radar_channels; + u8 PAD[8]; }; /* locale per-channel tx power limits for MIMO frames @@ -98,23 +141,337 @@ struct locale_mimo_info { s8 maxpwr20[BRCMS_MAXPWR_MIMO_TBL_SIZE]; /* tx 40 MHz power limits, qdBm units */ s8 maxpwr40[BRCMS_MAXPWR_MIMO_TBL_SIZE]; + u8 flags; }; /* Country names and abbreviations with locale defined from ISO 3166 */ struct country_info { + const u8 locale_2G; /* 2.4G band locale */ + const u8 locale_5G; /* 5G band locale */ const u8 locale_mimo_2G; /* 2.4G mimo info */ const u8 locale_mimo_5G; /* 5G mimo info */ }; -struct brcms_regd { - struct country_info country; - const struct ieee80211_regdomain *regdomain; -}; - struct brcms_cm_info { struct brcms_pub *pub; struct brcms_c_info *wlc; - const struct brcms_regd *world_regd; + char srom_ccode[BRCM_CNTRY_BUF_SZ]; /* Country Code in SROM */ + uint srom_regrev; /* Regulatory Rev for the SROM ccode */ + const struct country_info *country; /* current country def */ + char ccode[BRCM_CNTRY_BUF_SZ]; /* current internal Country Code */ + uint regrev; /* current Regulatory Revision */ + char country_abbrev[BRCM_CNTRY_BUF_SZ]; /* current advertised ccode */ + /* per-band state (one per phy/radio) */ + struct brcms_cm_band bandstate[MAXBANDS]; + /* quiet channels currently for radar sensitivity or 11h support */ + /* channels on which we cannot transmit */ + struct brcms_chanvec quiet_channels; +}; + +/* locale channel and power info. */ +struct locale_info { + u32 valid_channels; + /* List of radar sensitive channels */ + u8 radar_channels; + /* List of channels used only if APs are detected */ + u8 restricted_channels; + /* Max tx pwr in qdBm for each sub-band */ + s8 maxpwr[BRCMS_MAXPWR_TBL_SIZE]; + /* Country IE advertised max tx pwr in dBm per sub-band */ + s8 pub_maxpwr[BAND_5G_PWR_LVLS]; + u8 flags; +}; + +/* Regulatory Matrix Spreadsheet (CLM) MIMO v3.7.9 */ + +/* + * Some common channel sets + */ + +/* No channels */ +static const struct brcms_chanvec chanvec_none = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +/* All 2.4 GHz HW channels */ +static const struct brcms_chanvec chanvec_all_2G = { + {0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +/* All 5 GHz HW channels */ +static const struct brcms_chanvec chanvec_all_5G = { + {0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x11, 0x11, + 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x20, 0x22, 0x22, 0x00, 0x00, 0x11, + 0x11, 0x11, 0x11, 0x01} +}; + +/* + * Radar channel sets + */ + +/* Channels 52 - 64, 100 - 140 */ +static const struct brcms_chanvec radar_set1 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, /* 52 - 60 */ + 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11, /* 64, 100 - 124 */ + 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 128 - 140 */ + 0x00, 0x00, 0x00, 0x00} +}; + +/* + * Restricted channel sets + */ + +/* Channels 34, 38, 42, 46 */ +static const struct brcms_chanvec restricted_set_japan_legacy = { + {0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +/* Channels 12, 13 */ +static const struct brcms_chanvec restricted_set_2g_short = { + {0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +/* Channel 165 */ +static const struct brcms_chanvec restricted_chan_165 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +/* Channels 36 - 48 & 149 - 165 */ +static const struct brcms_chanvec restricted_low_hi = { + {0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x22, 0x22, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +/* Channels 12 - 14 */ +static const struct brcms_chanvec restricted_set_12_13_14 = { + {0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +/* global memory to provide working buffer for expanded locale */ + +static const struct brcms_chanvec *g_table_radar_set[] = { + &chanvec_none, + &radar_set1 +}; + +static const struct brcms_chanvec *g_table_restricted_chan[] = { + &chanvec_none, /* restricted_set_none */ + &restricted_set_2g_short, + &restricted_chan_165, + &chanvec_all_5G, + &restricted_set_japan_legacy, + &chanvec_all_2G, /* restricted_set_11d_2G */ + &chanvec_all_5G, /* restricted_set_11d_5G */ + &restricted_low_hi, + &restricted_set_12_13_14 +}; + +static const struct brcms_chanvec locale_2g_01_11 = { + {0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const struct brcms_chanvec locale_2g_12_13 = { + {0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const struct brcms_chanvec locale_2g_14 = { + {0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const struct brcms_chanvec locale_5g_LOW_JP1 = { + {0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const struct brcms_chanvec locale_5g_LOW_JP2 = { + {0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const struct brcms_chanvec locale_5g_LOW1 = { + {0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const struct brcms_chanvec locale_5g_LOW2 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const struct brcms_chanvec locale_5g_LOW3 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const struct brcms_chanvec locale_5g_MID1 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const struct brcms_chanvec locale_5g_MID2 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const struct brcms_chanvec locale_5g_MID3 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const struct brcms_chanvec locale_5g_HIGH1 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const struct brcms_chanvec locale_5g_HIGH2 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x22, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const struct brcms_chanvec locale_5g_HIGH3 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const struct brcms_chanvec locale_5g_52_140_ALL = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x11, 0x11, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00} +}; + +static const struct brcms_chanvec locale_5g_HIGH4 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, + 0x11, 0x11, 0x11, 0x11} +}; + +static const struct brcms_chanvec *g_table_locale_base[] = { + &locale_2g_01_11, + &locale_2g_12_13, + &locale_2g_14, + &locale_5g_LOW_JP1, + &locale_5g_LOW_JP2, + &locale_5g_LOW1, + &locale_5g_LOW2, + &locale_5g_LOW3, + &locale_5g_MID1, + &locale_5g_MID2, + &locale_5g_MID3, + &locale_5g_HIGH1, + &locale_5g_HIGH2, + &locale_5g_HIGH3, + &locale_5g_52_140_ALL, + &locale_5g_HIGH4 +}; + +static void brcms_c_locale_add_channels(struct brcms_chanvec *target, + const struct brcms_chanvec *channels) +{ + u8 i; + for (i = 0; i < sizeof(struct brcms_chanvec); i++) + target->vec[i] |= channels->vec[i]; +} + +static void brcms_c_locale_get_channels(const struct locale_info *locale, + struct brcms_chanvec *channels) +{ + u8 i; + + memset(channels, 0, sizeof(struct brcms_chanvec)); + + for (i = 0; i < ARRAY_SIZE(g_table_locale_base); i++) { + if (locale->valid_channels & (1 << i)) + brcms_c_locale_add_channels(channels, + g_table_locale_base[i]); + } +} + +/* + * Locale Definitions - 2.4 GHz + */ +static const struct locale_info locale_i = { /* locale i. channel 1 - 13 */ + LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13, + LOCALE_RADAR_SET_NONE, + LOCALE_RESTRICTED_SET_2G_SHORT, + {QDB(19), QDB(19), QDB(19), + QDB(19), QDB(19), QDB(19)}, + {20, 20, 20, 0}, + BRCMS_EIRP +}; + +/* + * Locale Definitions - 5 GHz + */ +static const struct locale_info locale_11 = { + /* locale 11. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */ + LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165, + LOCALE_RADAR_SET_1, + LOCALE_RESTRICTED_NONE, + {QDB(21), QDB(21), QDB(21), QDB(21), QDB(21)}, + {23, 23, 23, 30, 30}, + BRCMS_EIRP | BRCMS_DFS_EU +}; + +static const struct locale_info *g_locale_2g_table[] = { + &locale_i +}; + +static const struct locale_info *g_locale_5g_table[] = { + &locale_11 }; /* @@ -127,6 +484,7 @@ static const struct locale_mimo_info locale_bn = { {0, 0, QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), 0, 0}, + 0 }; static const struct locale_mimo_info *g_mimo_2g_table[] = { @@ -139,20 +497,114 @@ static const struct locale_mimo_info *g_mimo_2g_table[] = { static const struct locale_mimo_info locale_11n = { { /* 12.5 dBm */ 50, 50, 50, QDB(15), QDB(15)}, {QDB(14), QDB(15), QDB(15), QDB(15), QDB(15)}, + 0 }; static const struct locale_mimo_info *g_mimo_5g_table[] = { &locale_11n }; -static const struct brcms_regd cntry_locales[] = { - /* Worldwide RoW 2, must always be at index 0 */ +static const struct { + char abbrev[BRCM_CNTRY_BUF_SZ]; /* country abbreviation */ + struct country_info country; +} cntry_locales[] = { { - .country = LOCALES(bn, 11n), - .regdomain = &brcms_regdom_x2, - }, + "X2", LOCALES(i, 11, bn, 11n)}, /* Worldwide RoW 2 */ +}; + +#ifdef SUPPORT_40MHZ +/* 20MHz channel info for 40MHz pairing support */ +struct chan20_info { + u8 sb; + u8 adj_sbs; }; +/* indicates adjacent channels that are allowed for a 40 Mhz channel and + * those that permitted by the HT + */ +struct chan20_info chan20_info[] = { + /* 11b/11g */ +/* 0 */ {1, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 1 */ {2, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 2 */ {3, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 3 */ {4, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 4 */ {5, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, +/* 5 */ {6, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, +/* 6 */ {7, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, +/* 7 */ {8, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, +/* 8 */ {9, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, +/* 9 */ {10, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 10 */ {11, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 11 */ {12, (CH_LOWER_SB)}, +/* 12 */ {13, (CH_LOWER_SB)}, +/* 13 */ {14, (CH_LOWER_SB)}, + +/* 11a japan high */ +/* 14 */ {34, (CH_UPPER_SB)}, +/* 15 */ {38, (CH_LOWER_SB)}, +/* 16 */ {42, (CH_LOWER_SB)}, +/* 17 */ {46, (CH_LOWER_SB)}, + +/* 11a usa low */ +/* 18 */ {36, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 19 */ {40, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 20 */ {44, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 21 */ {48, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 22 */ {52, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 23 */ {56, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 24 */ {60, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 25 */ {64, (CH_LOWER_SB | CH_EWA_VALID)}, + +/* 11a Europe */ +/* 26 */ {100, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 27 */ {104, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 28 */ {108, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 29 */ {112, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 30 */ {116, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 31 */ {120, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 32 */ {124, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 33 */ {128, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 34 */ {132, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 35 */ {136, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 36 */ {140, (CH_LOWER_SB)}, + +/* 11a usa high, ref5 only */ +/* The 0x80 bit in pdiv means these are REF5, other entries are REF20 */ +/* 37 */ {149, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 38 */ {153, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 39 */ {157, (CH_UPPER_SB | CH_EWA_VALID)}, +/* 40 */ {161, (CH_LOWER_SB | CH_EWA_VALID)}, +/* 41 */ {165, (CH_LOWER_SB)}, + +/* 11a japan */ +/* 42 */ {184, (CH_UPPER_SB)}, +/* 43 */ {188, (CH_LOWER_SB)}, +/* 44 */ {192, (CH_UPPER_SB)}, +/* 45 */ {196, (CH_LOWER_SB)}, +/* 46 */ {200, (CH_UPPER_SB)}, +/* 47 */ {204, (CH_LOWER_SB)}, +/* 48 */ {208, (CH_UPPER_SB)}, +/* 49 */ {212, (CH_LOWER_SB)}, +/* 50 */ {216, (CH_LOWER_SB)} +}; +#endif /* SUPPORT_40MHZ */ + +static const struct locale_info *brcms_c_get_locale_2g(u8 locale_idx) +{ + if (locale_idx >= ARRAY_SIZE(g_locale_2g_table)) + return NULL; /* error condition */ + + return g_locale_2g_table[locale_idx]; +} + +static const struct locale_info *brcms_c_get_locale_5g(u8 locale_idx) +{ + if (locale_idx >= ARRAY_SIZE(g_locale_5g_table)) + return NULL; /* error condition */ + + return g_locale_5g_table[locale_idx]; +} + static const struct locale_mimo_info *brcms_c_get_mimo_2g(u8 locale_idx) { if (locale_idx >= ARRAY_SIZE(g_mimo_2g_table)) @@ -169,6 +621,13 @@ static const struct locale_mimo_info *brcms_c_get_mimo_5g(u8 locale_idx) return g_mimo_5g_table[locale_idx]; } +static int +brcms_c_country_aggregate_map(struct brcms_cm_info *wlc_cm, const char *ccode, + char *mapped_ccode, uint *mapped_regrev) +{ + return false; +} + /* * Indicates whether the country provided is valid to pass * to cfg80211 or not. @@ -203,24 +662,155 @@ static bool brcms_c_country_valid(const char *ccode) return true; } -static const struct brcms_regd *brcms_world_regd(const char *regdom, int len) +/* Lookup a country info structure from a null terminated country + * abbreviation and regrev directly with no translation. + */ +static const struct country_info * +brcms_c_country_lookup_direct(const char *ccode, uint regrev) { - const struct brcms_regd *regd = NULL; - int i; + uint size, i; - for (i = 0; i < ARRAY_SIZE(cntry_locales); i++) { - if (!strncmp(regdom, cntry_locales[i].regdomain->alpha2, len)) { - regd = &cntry_locales[i]; - break; - } + /* Should just return 0 for single locale driver. */ + /* Keep it this way in case we add more locales. (for now anyway) */ + + /* + * all other country def arrays are for regrev == 0, so if + * regrev is non-zero, fail + */ + if (regrev > 0) + return NULL; + + /* find matched table entry from country code */ + size = ARRAY_SIZE(cntry_locales); + for (i = 0; i < size; i++) { + if (strcmp(ccode, cntry_locales[i].abbrev) == 0) + return &cntry_locales[i].country; } + return NULL; +} - return regd; +static const struct country_info * +brcms_c_countrycode_map(struct brcms_cm_info *wlc_cm, const char *ccode, + char *mapped_ccode, uint *mapped_regrev) +{ + struct brcms_c_info *wlc = wlc_cm->wlc; + const struct country_info *country; + uint srom_regrev = wlc_cm->srom_regrev; + const char *srom_ccode = wlc_cm->srom_ccode; + int mapped; + + /* check for currently supported ccode size */ + if (strlen(ccode) > (BRCM_CNTRY_BUF_SZ - 1)) { + wiphy_err(wlc->wiphy, "wl%d: %s: ccode \"%s\" too long for " + "match\n", wlc->pub->unit, __func__, ccode); + return NULL; + } + + /* default mapping is the given ccode and regrev 0 */ + strncpy(mapped_ccode, ccode, BRCM_CNTRY_BUF_SZ); + *mapped_regrev = 0; + + /* If the desired country code matches the srom country code, + * then the mapped country is the srom regulatory rev. + * Otherwise look for an aggregate mapping. + */ + if (!strcmp(srom_ccode, ccode)) { + *mapped_regrev = srom_regrev; + mapped = 0; + wiphy_err(wlc->wiphy, "srom_code == ccode %s\n", __func__); + } else { + mapped = + brcms_c_country_aggregate_map(wlc_cm, ccode, mapped_ccode, + mapped_regrev); + } + + /* find the matching built-in country definition */ + country = brcms_c_country_lookup_direct(mapped_ccode, *mapped_regrev); + + /* if there is not an exact rev match, default to rev zero */ + if (country == NULL && *mapped_regrev != 0) { + *mapped_regrev = 0; + country = + brcms_c_country_lookup_direct(mapped_ccode, *mapped_regrev); + } + + return country; +} + +/* Lookup a country info structure from a null terminated country code + * The lookup is case sensitive. + */ +static const struct country_info * +brcms_c_country_lookup(struct brcms_c_info *wlc, const char *ccode) +{ + const struct country_info *country; + char mapped_ccode[BRCM_CNTRY_BUF_SZ]; + uint mapped_regrev; + + /* + * map the country code to a built-in country code, regrev, and + * country_info struct + */ + country = brcms_c_countrycode_map(wlc->cmi, ccode, mapped_ccode, + &mapped_regrev); + + return country; } -static const struct brcms_regd *brcms_default_world_regd(void) +/* + * reset the quiet channels vector to the union + * of the restricted and radar channel sets + */ +static void brcms_c_quiet_channels_reset(struct brcms_cm_info *wlc_cm) +{ + struct brcms_c_info *wlc = wlc_cm->wlc; + uint i, j; + struct brcms_band *band; + const struct brcms_chanvec *chanvec; + + memset(&wlc_cm->quiet_channels, 0, sizeof(struct brcms_chanvec)); + + band = wlc->band; + for (i = 0; i < wlc->pub->_nbands; + i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) { + + /* initialize quiet channels for restricted channels */ + chanvec = wlc_cm->bandstate[band->bandunit].restricted_channels; + for (j = 0; j < sizeof(struct brcms_chanvec); j++) + wlc_cm->quiet_channels.vec[j] |= chanvec->vec[j]; + + } +} + +/* Is the channel valid for the current locale and current band? */ +static bool brcms_c_valid_channel20(struct brcms_cm_info *wlc_cm, uint val) +{ + struct brcms_c_info *wlc = wlc_cm->wlc; + + return ((val < MAXCHANNEL) && + isset(wlc_cm->bandstate[wlc->band->bandunit].valid_channels.vec, + val)); +} + +/* Is the channel valid for the current locale and specified band? */ +static bool brcms_c_valid_channel20_in_band(struct brcms_cm_info *wlc_cm, + uint bandunit, uint val) +{ + return ((val < MAXCHANNEL) + && isset(wlc_cm->bandstate[bandunit].valid_channels.vec, val)); +} + +/* Is the channel valid for the current locale? (but don't consider channels not + * available due to bandlocking) + */ +static bool brcms_c_valid_channel20_db(struct brcms_cm_info *wlc_cm, uint val) { - return &cntry_locales[0]; + struct brcms_c_info *wlc = wlc_cm->wlc; + + return brcms_c_valid_channel20(wlc->cmi, val) || + (!wlc->bandlocked + && brcms_c_valid_channel20_in_band(wlc->cmi, + OTHERBANDUNIT(wlc), val)); } /* JP, J1 - J10 are Japan ccodes */ @@ -230,6 +820,12 @@ static bool brcms_c_japan_ccode(const char *ccode) (ccode[1] == 'P' || (ccode[1] >= '1' && ccode[1] <= '9'))); } +/* Returns true if currently set country is Japan or variant */ +static bool brcms_c_japan(struct brcms_c_info *wlc) +{ + return brcms_c_japan_ccode(wlc->cmi->country_abbrev); +} + static void brcms_c_channel_min_txpower_limits_with_local_constraint( struct brcms_cm_info *wlc_cm, struct txpwr_limits *txpwr, @@ -305,16 +901,140 @@ brcms_c_channel_min_txpower_limits_with_local_constraint( } +/* Update the radio state (enable/disable) and tx power targets + * based on a new set of channel/regulatory information + */ +static void brcms_c_channels_commit(struct brcms_cm_info *wlc_cm) +{ + struct brcms_c_info *wlc = wlc_cm->wlc; + uint chan; + struct txpwr_limits txpwr; + + /* search for the existence of any valid channel */ + for (chan = 0; chan < MAXCHANNEL; chan++) { + if (brcms_c_valid_channel20_db(wlc->cmi, chan)) + break; + } + if (chan == MAXCHANNEL) + chan = INVCHANNEL; + + /* + * based on the channel search above, set or + * clear WL_RADIO_COUNTRY_DISABLE. + */ + if (chan == INVCHANNEL) { + /* + * country/locale with no valid channels, set + * the radio disable bit + */ + mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); + wiphy_err(wlc->wiphy, "wl%d: %s: no valid channel for \"%s\" " + "nbands %d bandlocked %d\n", wlc->pub->unit, + __func__, wlc_cm->country_abbrev, wlc->pub->_nbands, + wlc->bandlocked); + } else if (mboolisset(wlc->pub->radio_disabled, + WL_RADIO_COUNTRY_DISABLE)) { + /* + * country/locale with valid channel, clear + * the radio disable bit + */ + mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); + } + + /* + * Now that the country abbreviation is set, if the radio supports 2G, + * then set channel 14 restrictions based on the new locale. + */ + if (wlc->pub->_nbands > 1 || wlc->band->bandtype == BRCM_BAND_2G) + wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi, + brcms_c_japan(wlc) ? true : + false); + + if (wlc->pub->up && chan != INVCHANNEL) { + brcms_c_channel_reg_limits(wlc_cm, wlc->chanspec, &txpwr); + brcms_c_channel_min_txpower_limits_with_local_constraint(wlc_cm, + &txpwr, BRCMS_TXPWR_MAX); + wlc_phy_txpower_limit_set(wlc->band->pi, &txpwr, wlc->chanspec); + } +} + +static int +brcms_c_channels_init(struct brcms_cm_info *wlc_cm, + const struct country_info *country) +{ + struct brcms_c_info *wlc = wlc_cm->wlc; + uint i, j; + struct brcms_band *band; + const struct locale_info *li; + struct brcms_chanvec sup_chan; + const struct locale_mimo_info *li_mimo; + + band = wlc->band; + for (i = 0; i < wlc->pub->_nbands; + i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) { + + li = (band->bandtype == BRCM_BAND_5G) ? + brcms_c_get_locale_5g(country->locale_5G) : + brcms_c_get_locale_2g(country->locale_2G); + wlc_cm->bandstate[band->bandunit].locale_flags = li->flags; + li_mimo = (band->bandtype == BRCM_BAND_5G) ? + brcms_c_get_mimo_5g(country->locale_mimo_5G) : + brcms_c_get_mimo_2g(country->locale_mimo_2G); + + /* merge the mimo non-mimo locale flags */ + wlc_cm->bandstate[band->bandunit].locale_flags |= + li_mimo->flags; + + wlc_cm->bandstate[band->bandunit].restricted_channels = + g_table_restricted_chan[li->restricted_channels]; + wlc_cm->bandstate[band->bandunit].radar_channels = + g_table_radar_set[li->radar_channels]; + + /* + * set the channel availability, masking out the channels + * that may not be supported on this phy. + */ + wlc_phy_chanspec_band_validch(band->pi, band->bandtype, + &sup_chan); + brcms_c_locale_get_channels(li, + &wlc_cm->bandstate[band->bandunit]. + valid_channels); + for (j = 0; j < sizeof(struct brcms_chanvec); j++) + wlc_cm->bandstate[band->bandunit].valid_channels. + vec[j] &= sup_chan.vec[j]; + } + + brcms_c_quiet_channels_reset(wlc_cm); + brcms_c_channels_commit(wlc_cm); + + return 0; +} + /* * set the driver's current country and regulatory information * using a country code as the source. Look up built in country * information found with the country code. */ static void -brcms_c_set_country(struct brcms_cm_info *wlc_cm, - const struct brcms_regd *regd) +brcms_c_set_country_common(struct brcms_cm_info *wlc_cm, + const char *country_abbrev, + const char *ccode, uint regrev, + const struct country_info *country) { + const struct locale_info *locale; struct brcms_c_info *wlc = wlc_cm->wlc; + char prev_country_abbrev[BRCM_CNTRY_BUF_SZ]; + + /* save current country state */ + wlc_cm->country = country; + + memset(&prev_country_abbrev, 0, BRCM_CNTRY_BUF_SZ); + strncpy(prev_country_abbrev, wlc_cm->country_abbrev, + BRCM_CNTRY_BUF_SZ - 1); + + strncpy(wlc_cm->country_abbrev, country_abbrev, BRCM_CNTRY_BUF_SZ - 1); + strncpy(wlc_cm->ccode, ccode, BRCM_CNTRY_BUF_SZ - 1); + wlc_cm->regrev = regrev; if ((wlc->pub->_n_enab & SUPPORT_11N) != wlc->protection->nmode_user) @@ -322,19 +1042,75 @@ brcms_c_set_country(struct brcms_cm_info *wlc_cm, brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]); brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]); + /* set or restore gmode as required by regulatory */ + locale = brcms_c_get_locale_2g(country->locale_2G); + if (locale && (locale->flags & BRCMS_NO_OFDM)) + brcms_c_set_gmode(wlc, GMODE_LEGACY_B, false); + else + brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false); - brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false); + brcms_c_channels_init(wlc_cm, country); return; } +static int +brcms_c_set_countrycode_rev(struct brcms_cm_info *wlc_cm, + const char *country_abbrev, + const char *ccode, int regrev) +{ + const struct country_info *country; + char mapped_ccode[BRCM_CNTRY_BUF_SZ]; + uint mapped_regrev; + + /* if regrev is -1, lookup the mapped country code, + * otherwise use the ccode and regrev directly + */ + if (regrev == -1) { + /* + * map the country code to a built-in country + * code, regrev, and country_info + */ + country = + brcms_c_countrycode_map(wlc_cm, ccode, mapped_ccode, + &mapped_regrev); + } else { + /* find the matching built-in country definition */ + country = brcms_c_country_lookup_direct(ccode, regrev); + strncpy(mapped_ccode, ccode, BRCM_CNTRY_BUF_SZ); + mapped_regrev = regrev; + } + + if (country == NULL) + return -EINVAL; + + /* set the driver state for the country */ + brcms_c_set_country_common(wlc_cm, country_abbrev, mapped_ccode, + mapped_regrev, country); + + return 0; +} + +/* + * set the driver's current country and regulatory information using + * a country code as the source. Lookup built in country information + * found with the country code. + */ +static int +brcms_c_set_countrycode(struct brcms_cm_info *wlc_cm, const char *ccode) +{ + char country_abbrev[BRCM_CNTRY_BUF_SZ]; + strncpy(country_abbrev, ccode, BRCM_CNTRY_BUF_SZ); + return brcms_c_set_countrycode_rev(wlc_cm, country_abbrev, ccode, -1); +} + struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc) { struct brcms_cm_info *wlc_cm; + char country_abbrev[BRCM_CNTRY_BUF_SZ]; + const struct country_info *country; struct brcms_pub *pub = wlc->pub; struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom; - const char *ccode = sprom->alpha2; - int ccode_len = sizeof(sprom->alpha2); BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); @@ -346,27 +1122,24 @@ struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc) wlc->cmi = wlc_cm; /* store the country code for passing up as a regulatory hint */ - wlc_cm->world_regd = brcms_world_regd(ccode, ccode_len); - if (brcms_c_country_valid(ccode)) - strncpy(wlc->pub->srom_ccode, ccode, ccode_len); + if (sprom->alpha2 && brcms_c_country_valid(sprom->alpha2)) + strncpy(wlc->pub->srom_ccode, sprom->alpha2, sizeof(sprom->alpha2)); /* - * If no custom world domain is found in the SROM, use the - * default "X2" domain. + * internal country information which must match + * regulatory constraints in firmware */ - if (!wlc_cm->world_regd) { - wlc_cm->world_regd = brcms_default_world_regd(); - ccode = wlc_cm->world_regd->regdomain->alpha2; - ccode_len = BRCM_CNTRY_BUF_SZ - 1; - } + memset(country_abbrev, 0, BRCM_CNTRY_BUF_SZ); + strncpy(country_abbrev, "X2", sizeof(country_abbrev) - 1); + country = brcms_c_country_lookup(wlc, country_abbrev); /* save default country for exiting 11d regulatory mode */ - strncpy(wlc->country_default, ccode, ccode_len); + strncpy(wlc->country_default, country_abbrev, BRCM_CNTRY_BUF_SZ - 1); /* initialize autocountry_default to driver default */ - strncpy(wlc->autocountry_default, ccode, ccode_len); + strncpy(wlc->autocountry_default, "X2", BRCM_CNTRY_BUF_SZ - 1); - brcms_c_set_country(wlc_cm, wlc_cm->world_regd); + brcms_c_set_countrycode(wlc_cm, country_abbrev); return wlc_cm; } @@ -376,15 +1149,31 @@ void brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm) kfree(wlc_cm); } +u8 +brcms_c_channel_locale_flags_in_band(struct brcms_cm_info *wlc_cm, + uint bandunit) +{ + return wlc_cm->bandstate[bandunit].locale_flags; +} + +static bool +brcms_c_quiet_chanspec(struct brcms_cm_info *wlc_cm, u16 chspec) +{ + return (wlc_cm->wlc->pub->_n_enab & SUPPORT_11N) && + CHSPEC_IS40(chspec) ? + (isset(wlc_cm->quiet_channels.vec, + lower_20_sb(CHSPEC_CHANNEL(chspec))) || + isset(wlc_cm->quiet_channels.vec, + upper_20_sb(CHSPEC_CHANNEL(chspec)))) : + isset(wlc_cm->quiet_channels.vec, CHSPEC_CHANNEL(chspec)); +} + void brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec, u8 local_constraint_qdbm) { struct brcms_c_info *wlc = wlc_cm->wlc; - struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel; - const struct ieee80211_reg_rule *reg_rule; struct txpwr_limits txpwr; - int ret; brcms_c_channel_reg_limits(wlc_cm, chanspec, &txpwr); @@ -392,15 +1181,8 @@ brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec, wlc_cm, &txpwr, local_constraint_qdbm ); - /* set or restore gmode as required by regulatory */ - ret = freq_reg_info(wlc->wiphy, ch->center_freq, 0, ®_rule); - if (!ret && (reg_rule->flags & NL80211_RRF_NO_OFDM)) - brcms_c_set_gmode(wlc, GMODE_LEGACY_B, false); - else - brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false); - brcms_b_set_chanspec(wlc->hw, chanspec, - !!(ch->flags & IEEE80211_CHAN_PASSIVE_SCAN), + (brcms_c_quiet_chanspec(wlc_cm, chanspec) != 0), &txpwr); } @@ -409,14 +1191,15 @@ brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec, struct txpwr_limits *txpwr) { struct brcms_c_info *wlc = wlc_cm->wlc; - struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel; uint i; uint chan; int maxpwr; int delta; const struct country_info *country; struct brcms_band *band; + const struct locale_info *li; int conducted_max = BRCMS_TXPWR_MAX; + int conducted_ofdm_max = BRCMS_TXPWR_MAX; const struct locale_mimo_info *li_mimo; int maxpwr20, maxpwr40; int maxpwr_idx; @@ -424,35 +1207,67 @@ brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec, memset(txpwr, 0, sizeof(struct txpwr_limits)); - if (WARN_ON(!ch)) - return; - - country = &wlc_cm->world_regd->country; + if (!brcms_c_valid_chanspec_db(wlc_cm, chanspec)) { + country = brcms_c_country_lookup(wlc, wlc->autocountry_default); + if (country == NULL) + return; + } else { + country = wlc_cm->country; + } chan = CHSPEC_CHANNEL(chanspec); band = wlc->bandstate[chspec_bandunit(chanspec)]; + li = (band->bandtype == BRCM_BAND_5G) ? + brcms_c_get_locale_5g(country->locale_5G) : + brcms_c_get_locale_2g(country->locale_2G); + li_mimo = (band->bandtype == BRCM_BAND_5G) ? brcms_c_get_mimo_5g(country->locale_mimo_5G) : brcms_c_get_mimo_2g(country->locale_mimo_2G); - delta = band->antgain; + if (li->flags & BRCMS_EIRP) { + delta = band->antgain; + } else { + delta = 0; + if (band->antgain > QDB(6)) + delta = band->antgain - QDB(6); /* Excess over 6 dB */ + } - if (band->bandtype == BRCM_BAND_2G) + if (li == &locale_i) { conducted_max = QDB(22); - - maxpwr = QDB(ch->max_power) - delta; - maxpwr = max(maxpwr, 0); - maxpwr = min(maxpwr, conducted_max); + conducted_ofdm_max = QDB(22); + } /* CCK txpwr limits for 2.4G band */ if (band->bandtype == BRCM_BAND_2G) { + maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_CCK(chan)]; + + maxpwr = maxpwr - delta; + maxpwr = max(maxpwr, 0); + maxpwr = min(maxpwr, conducted_max); + for (i = 0; i < BRCMS_NUM_RATES_CCK; i++) txpwr->cck[i] = (u8) maxpwr; } - for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) { + /* OFDM txpwr limits for 2.4G or 5G bands */ + if (band->bandtype == BRCM_BAND_2G) + maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_OFDM(chan)]; + else + maxpwr = li->maxpwr[CHANNEL_POWER_IDX_5G(chan)]; + + maxpwr = maxpwr - delta; + maxpwr = max(maxpwr, 0); + maxpwr = min(maxpwr, conducted_ofdm_max); + + /* Keep OFDM lmit below CCK limit */ + if (band->bandtype == BRCM_BAND_2G) + maxpwr = min_t(int, maxpwr, txpwr->cck[0]); + + for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) txpwr->ofdm[i] = (u8) maxpwr; + for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) { /* * OFDM 40 MHz SISO has the same power as the corresponding * MCS0-7 rate unless overriden by the locale specific code. @@ -467,9 +1282,14 @@ brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec, txpwr->ofdm_40_cdd[i] = 0; } - delta = 0; - if (band->antgain > QDB(6)) - delta = band->antgain - QDB(6); /* Excess over 6 dB */ + /* MIMO/HT specific limits */ + if (li_mimo->flags & BRCMS_EIRP) { + delta = band->antgain; + } else { + delta = 0; + if (band->antgain > QDB(6)) + delta = band->antgain - QDB(6); /* Excess over 6 dB */ + } if (band->bandtype == BRCM_BAND_2G) maxpwr_idx = (chan - 1); @@ -611,7 +1431,8 @@ static bool brcms_c_chspec_malformed(u16 chanspec) * and they are also a legal HT combination */ static bool -brcms_c_valid_chanspec_ext(struct brcms_cm_info *wlc_cm, u16 chspec) +brcms_c_valid_chanspec_ext(struct brcms_cm_info *wlc_cm, u16 chspec, + bool dualband) { struct brcms_c_info *wlc = wlc_cm->wlc; u8 channel = CHSPEC_CHANNEL(chspec); @@ -627,166 +1448,59 @@ brcms_c_valid_chanspec_ext(struct brcms_cm_info *wlc_cm, u16 chspec) chspec_bandunit(chspec)) return false; - return true; -} - -bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm, u16 chspec) -{ - return brcms_c_valid_chanspec_ext(wlc_cm, chspec); -} - -static bool brcms_is_radar_freq(u16 center_freq) -{ - return center_freq >= 5260 && center_freq <= 5700; -} - -static void brcms_reg_apply_radar_flags(struct wiphy *wiphy) -{ - struct ieee80211_supported_band *sband; - struct ieee80211_channel *ch; - int i; - - sband = wiphy->bands[IEEE80211_BAND_5GHZ]; - if (!sband) - return; - - for (i = 0; i < sband->n_channels; i++) { - ch = &sband->channels[i]; - - if (!brcms_is_radar_freq(ch->center_freq)) - continue; - - /* - * All channels in this range should be passive and have - * DFS enabled. - */ - if (!(ch->flags & IEEE80211_CHAN_DISABLED)) - ch->flags |= IEEE80211_CHAN_RADAR | - IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN; + /* Check a 20Mhz channel */ + if (CHSPEC_IS20(chspec)) { + if (dualband) + return brcms_c_valid_channel20_db(wlc_cm->wlc->cmi, + channel); + else + return brcms_c_valid_channel20(wlc_cm->wlc->cmi, + channel); } -} - -static void -brcms_reg_apply_beaconing_flags(struct wiphy *wiphy, - enum nl80211_reg_initiator initiator) -{ - struct ieee80211_supported_band *sband; - struct ieee80211_channel *ch; - const struct ieee80211_reg_rule *rule; - int band, i, ret; - - for (band = 0; band < IEEE80211_NUM_BANDS; band++) { - sband = wiphy->bands[band]; - if (!sband) - continue; - - for (i = 0; i < sband->n_channels; i++) { - ch = &sband->channels[i]; - - if (ch->flags & - (IEEE80211_CHAN_DISABLED | IEEE80211_CHAN_RADAR)) - continue; - - if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { - ret = freq_reg_info(wiphy, ch->center_freq, - 0, &rule); - if (ret) - continue; - - if (!(rule->flags & NL80211_RRF_NO_IBSS)) - ch->flags &= ~IEEE80211_CHAN_NO_IBSS; - if (!(rule->flags & NL80211_RRF_PASSIVE_SCAN)) - ch->flags &= - ~IEEE80211_CHAN_PASSIVE_SCAN; - } else if (ch->beacon_found) { - ch->flags &= ~(IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_PASSIVE_SCAN); - } +#ifdef SUPPORT_40MHZ + /* + * We know we are now checking a 40MHZ channel, so we should + * only be here for NPHYS + */ + if (BRCMS_ISNPHY(wlc->band) || BRCMS_ISSSLPNPHY(wlc->band)) { + u8 upper_sideband = 0, idx; + u8 num_ch20_entries = + sizeof(chan20_info) / sizeof(struct chan20_info); + + if (!VALID_40CHANSPEC_IN_BAND(wlc, chspec_bandunit(chspec))) + return false; + + if (dualband) { + if (!brcms_c_valid_channel20_db(wlc->cmi, + lower_20_sb(channel)) || + !brcms_c_valid_channel20_db(wlc->cmi, + upper_20_sb(channel))) + return false; + } else { + if (!brcms_c_valid_channel20(wlc->cmi, + lower_20_sb(channel)) || + !brcms_c_valid_channel20(wlc->cmi, + upper_20_sb(channel))) + return false; } - } -} -static int brcms_reg_notifier(struct wiphy *wiphy, - struct regulatory_request *request) -{ - struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); - struct brcms_info *wl = hw->priv; - struct brcms_c_info *wlc = wl->wlc; - struct ieee80211_supported_band *sband; - struct ieee80211_channel *ch; - int band, i; - bool ch_found = false; - - brcms_reg_apply_radar_flags(wiphy); - - if (request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) - brcms_reg_apply_beaconing_flags(wiphy, request->initiator); - - /* Disable radio if all channels disallowed by regulatory */ - for (band = 0; !ch_found && band < IEEE80211_NUM_BANDS; band++) { - sband = wiphy->bands[band]; - if (!sband) - continue; - - for (i = 0; !ch_found && i < sband->n_channels; i++) { - ch = &sband->channels[i]; - - if (!(ch->flags & IEEE80211_CHAN_DISABLED)) - ch_found = true; + /* find the lower sideband info in the sideband array */ + for (idx = 0; idx < num_ch20_entries; idx++) { + if (chan20_info[idx].sb == lower_20_sb(channel)) + upper_sideband = chan20_info[idx].adj_sbs; } + /* check that the lower sideband allows an upper sideband */ + if ((upper_sideband & (CH_UPPER_SB | CH_EWA_VALID)) == + (CH_UPPER_SB | CH_EWA_VALID)) + return true; + return false; } +#endif /* 40 MHZ */ - if (ch_found) { - mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); - } else { - mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); - wiphy_err(wlc->wiphy, "wl%d: %s: no valid channel for \"%s\"\n", - wlc->pub->unit, __func__, request->alpha2); - } - - if (wlc->pub->_nbands > 1 || wlc->band->bandtype == BRCM_BAND_2G) - wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi, - brcms_c_japan_ccode(request->alpha2)); - - return 0; + return false; } -void brcms_c_regd_init(struct brcms_c_info *wlc) +bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm, u16 chspec) { - struct wiphy *wiphy = wlc->wiphy; - const struct brcms_regd *regd = wlc->cmi->world_regd; - struct ieee80211_supported_band *sband; - struct ieee80211_channel *ch; - struct brcms_chanvec sup_chan; - struct brcms_band *band; - int band_idx, i; - - /* Disable any channels not supported by the phy */ - for (band_idx = 0; band_idx < IEEE80211_NUM_BANDS; band_idx++) { - if (band_idx == IEEE80211_BAND_2GHZ) - band = wlc->bandstate[BAND_2G_INDEX]; - else - band = wlc->bandstate[BAND_5G_INDEX]; - - /* skip if band not initialized */ - if (band->pi == NULL) - continue; - - wlc_phy_chanspec_band_validch(band->pi, band->bandtype, - &sup_chan); - - sband = wiphy->bands[band_idx]; - for (i = 0; i < sband->n_channels; i++) { - ch = &sband->channels[i]; - if (!isset(sup_chan.vec, ch->hw_value)) - ch->flags |= IEEE80211_CHAN_DISABLED; - } - } - - wlc->wiphy->reg_notifier = brcms_reg_notifier; - wlc->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | - WIPHY_FLAG_STRICT_REGULATORY; - wiphy_apply_custom_regulatory(wlc->wiphy, regd->regdomain); - brcms_reg_apply_beaconing_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER); + return brcms_c_valid_chanspec_ext(wlc_cm, chspec, true); } diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/channel.h b/trunk/drivers/net/wireless/brcm80211/brcmsmac/channel.h index 006483a0abe6..808cb4fbfbe7 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/channel.h +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/channel.h @@ -37,6 +37,9 @@ brcms_c_channel_mgr_attach(struct brcms_c_info *wlc); extern void brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm); +extern u8 brcms_c_channel_locale_flags_in_band(struct brcms_cm_info *wlc_cm, + uint bandunit); + extern bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm, u16 chspec); @@ -46,6 +49,5 @@ extern void brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, extern void brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec, u8 local_constraint_qdbm); -extern void brcms_c_regd_init(struct brcms_c_info *wlc); #endif /* _WLC_CHANNEL_H */ diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 2d5a40412690..50f92a0b7c41 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c @@ -721,6 +721,14 @@ static const struct ieee80211_ops brcms_ops = { .flush = brcms_ops_flush, }; +/* + * is called in brcms_bcma_probe() context, therefore no locking required. + */ +static int brcms_set_hint(struct brcms_info *wl, char *abbrev) +{ + return regulatory_hint(wl->pub->ieee_hw->wiphy, abbrev); +} + void brcms_dpc(unsigned long data) { struct brcms_info *wl; @@ -1050,8 +1058,6 @@ static struct brcms_info *brcms_attach(struct bcma_device *pdev) goto fail; } - brcms_c_regd_init(wl->wlc); - memcpy(perm, &wl->pub->cur_etheraddr, ETH_ALEN); if (WARN_ON(!is_valid_ether_addr(perm))) goto fail; @@ -1062,9 +1068,9 @@ static struct brcms_info *brcms_attach(struct bcma_device *pdev) wiphy_err(wl->wiphy, "%s: ieee80211_register_hw failed, status" "%d\n", __func__, err); - if (wl->pub->srom_ccode[0] && - regulatory_hint(wl->wiphy, wl->pub->srom_ccode)) - wiphy_err(wl->wiphy, "%s: regulatory hint failed\n", __func__); + if (wl->pub->srom_ccode[0] && brcms_set_hint(wl, wl->pub->srom_ccode)) + wiphy_err(wl->wiphy, "%s: regulatory_hint failed, status %d\n", + __func__, err); n_adapters_found++; return wl; diff --git a/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c b/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c index 8776fbc8dcf1..19db4052c44c 100644 --- a/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/trunk/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -18,7 +18,6 @@ #include #include -#include #include #include #include @@ -3140,6 +3139,20 @@ void brcms_c_reset(struct brcms_c_info *wlc) brcms_b_reset(wlc->hw); } +/* Return the channel the driver should initialize during brcms_c_init. + * the channel may have to be changed from the currently configured channel + * if other configurations are in conflict (bandlocked, 11n mode disabled, + * invalid channel for current country, etc.) + */ +static u16 brcms_c_init_chanspec(struct brcms_c_info *wlc) +{ + u16 chanspec = + 1 | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE | + WL_CHANSPEC_BAND_2G; + + return chanspec; +} + void brcms_c_init_scb(struct scb *scb) { int i; @@ -5116,8 +5129,6 @@ static void brcms_c_wme_retries_write(struct brcms_c_info *wlc) /* make interface operational */ int brcms_c_up(struct brcms_c_info *wlc) { - struct ieee80211_channel *ch; - BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); /* HW is turned off so don't try to access it */ @@ -5184,9 +5195,8 @@ int brcms_c_up(struct brcms_c_info *wlc) wlc->pub->up = true; if (wlc->bandinit_pending) { - ch = wlc->pub->ieee_hw->conf.channel; brcms_c_suspend_mac_and_wait(wlc); - brcms_c_set_chanspec(wlc, ch20mhz_chspec(ch->hw_value)); + brcms_c_set_chanspec(wlc, wlc->default_bss->chanspec); wlc->bandinit_pending = false; brcms_c_enable_mac(wlc); } @@ -5387,6 +5397,11 @@ int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config) else return -EINVAL; + /* Legacy or bust when no OFDM is supported by regulatory */ + if ((brcms_c_channel_locale_flags_in_band(wlc->cmi, band->bandunit) & + BRCMS_NO_OFDM) && (gmode != GMODE_LEGACY_B)) + return -EINVAL; + /* update configuration value */ if (config) brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER, gmode); @@ -8186,12 +8201,19 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx) { struct bcma_device *core = wlc->hw->d11core; - struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel; u16 chanspec; BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); - chanspec = ch20mhz_chspec(ch->hw_value); + /* + * This will happen if a big-hammer was executed. In + * that case, we want to go back to the channel that + * we were on and not new channel + */ + if (wlc->pub->associated) + chanspec = wlc->home_chanspec; + else + chanspec = brcms_c_init_chanspec(wlc); brcms_b_init(wlc->hw, chanspec); diff --git a/trunk/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h b/trunk/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h index bcc79b4e3267..333193f20e1c 100644 --- a/trunk/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h +++ b/trunk/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h @@ -37,6 +37,5 @@ #define BCM4329_CHIP_ID 0x4329 #define BCM4330_CHIP_ID 0x4330 #define BCM4331_CHIP_ID 0x4331 -#define BCM4334_CHIP_ID 0x4334 #endif /* _BRCM_HW_IDS_H_ */ diff --git a/trunk/drivers/net/wireless/iwlegacy/3945-rs.c b/trunk/drivers/net/wireless/iwlegacy/3945-rs.c index d4fd29ad90dc..4b10157d8686 100644 --- a/trunk/drivers/net/wireless/iwlegacy/3945-rs.c +++ b/trunk/drivers/net/wireless/iwlegacy/3945-rs.c @@ -946,7 +946,7 @@ il3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) case IEEE80211_BAND_5GHZ: rs_sta->expected_tpt = il3945_expected_tpt_a; break; - default: + case IEEE80211_NUM_BANDS: BUG(); break; } diff --git a/trunk/drivers/net/wireless/iwlegacy/4965-mac.c b/trunk/drivers/net/wireless/iwlegacy/4965-mac.c index 34f61a0581a2..d24eaf89ffb5 100644 --- a/trunk/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/trunk/drivers/net/wireless/iwlegacy/4965-mac.c @@ -3405,7 +3405,7 @@ il4965_remove_dynamic_key(struct il_priv *il, return 0; } - if (il->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_INVALID) { + if (il->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET) { IL_WARN("Removing wrong key %d 0x%x\n", keyconf->keyidx, key_flags); spin_unlock_irqrestore(&il->sta_lock, flags); @@ -3420,7 +3420,7 @@ il4965_remove_dynamic_key(struct il_priv *il, memset(&il->stations[sta_id].sta.key, 0, sizeof(struct il4965_keyinfo)); il->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID; - il->stations[sta_id].sta.key.key_offset = keyconf->hw_key_idx; + il->stations[sta_id].sta.key.key_offset = WEP_INVALID_OFFSET; il->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; il->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; diff --git a/trunk/drivers/net/wireless/iwlegacy/common.c b/trunk/drivers/net/wireless/iwlegacy/common.c index 0f8a7703eea3..cbf2dc18341f 100644 --- a/trunk/drivers/net/wireless/iwlegacy/common.c +++ b/trunk/drivers/net/wireless/iwlegacy/common.c @@ -4717,11 +4717,10 @@ il_check_stuck_queue(struct il_priv *il, int cnt) struct il_tx_queue *txq = &il->txq[cnt]; struct il_queue *q = &txq->q; unsigned long timeout; - unsigned long now = jiffies; int ret; if (q->read_ptr == q->write_ptr) { - txq->time_stamp = now; + txq->time_stamp = jiffies; return 0; } @@ -4729,9 +4728,9 @@ il_check_stuck_queue(struct il_priv *il, int cnt) txq->time_stamp + msecs_to_jiffies(il->cfg->wd_timeout); - if (time_after(now, timeout)) { + if (time_after(jiffies, timeout)) { IL_ERR("Queue %d stuck for %u ms.\n", q->id, - jiffies_to_msecs(now - txq->time_stamp)); + il->cfg->wd_timeout); ret = il_force_reset(il, false); return (ret == -EAGAIN) ? 0 : 1; } @@ -4768,12 +4767,14 @@ il_bg_watchdog(unsigned long data) return; /* monitor and check for other stuck queues */ - for (cnt = 0; cnt < il->hw_params.max_txq_num; cnt++) { - /* skip as we already checked the command queue */ - if (cnt == il->cmd_queue) - continue; - if (il_check_stuck_queue(il, cnt)) - return; + if (il_is_any_associated(il)) { + for (cnt = 0; cnt < il->hw_params.max_txq_num; cnt++) { + /* skip as we already checked the command queue */ + if (cnt == il->cmd_queue) + continue; + if (il_check_stuck_queue(il, cnt)) + return; + } } mod_timer(&il->watchdog, diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/commands.h b/trunk/drivers/net/wireless/iwlwifi/dvm/commands.h index 64811cd91635..97bea16f3592 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/commands.h +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/commands.h @@ -190,6 +190,44 @@ enum { REPLY_MAX = 0xff }; +/* + * Minimum number of queues. MAX_NUM is defined in hw specific files. + * Set the minimum to accommodate + * - 4 standard TX queues + * - the command queue + * - 4 PAN TX queues + * - the PAN multicast queue, and + * - the AUX (TX during scan dwell) queue. + */ +#define IWL_MIN_NUM_QUEUES 11 + +/* + * Command queue depends on iPAN support. + */ +#define IWL_DEFAULT_CMD_QUEUE_NUM 4 +#define IWL_IPAN_CMD_QUEUE_NUM 9 + +#define IWL_TX_FIFO_BK 0 /* shared */ +#define IWL_TX_FIFO_BE 1 +#define IWL_TX_FIFO_VI 2 /* shared */ +#define IWL_TX_FIFO_VO 3 +#define IWL_TX_FIFO_BK_IPAN IWL_TX_FIFO_BK +#define IWL_TX_FIFO_BE_IPAN 4 +#define IWL_TX_FIFO_VI_IPAN IWL_TX_FIFO_VI +#define IWL_TX_FIFO_VO_IPAN 5 +/* re-uses the VO FIFO, uCode will properly flush/schedule */ +#define IWL_TX_FIFO_AUX 5 +#define IWL_TX_FIFO_UNUSED 255 + +#define IWLAGN_CMD_FIFO_NUM 7 + +/* + * This queue number is required for proper operation + * because the ucode will stop/start the scheduler as + * required. + */ +#define IWL_IPAN_MCAST_QUEUE 8 + /****************************************************************************** * (0) * Commonly used structures and definitions: @@ -755,8 +793,6 @@ struct iwl_qosparam_cmd { #define IWLAGN_BROADCAST_ID 15 #define IWLAGN_STATION_COUNT 16 -#define IWL_INVALID_STATION 255 -#define IWL_MAX_TID_COUNT 8 #define IWL_TID_NON_QOS IWL_MAX_TID_COUNT #define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2) diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/debugfs.c b/trunk/drivers/net/wireless/iwlwifi/dvm/debugfs.c index b0eff1c340c7..8a2d9e643b14 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/debugfs.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/debugfs.c @@ -2228,7 +2228,6 @@ static ssize_t iwl_dbgfs_echo_test_write(struct file *file, return count; } -#ifdef CONFIG_IWLWIFI_DEBUG static ssize_t iwl_dbgfs_log_event_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) @@ -2266,7 +2265,6 @@ static ssize_t iwl_dbgfs_log_event_write(struct file *file, return count; } -#endif static ssize_t iwl_dbgfs_calib_disabled_read(struct file *file, char __user *user_buf, @@ -2336,9 +2334,7 @@ DEBUGFS_READ_FILE_OPS(bt_traffic); DEBUGFS_READ_WRITE_FILE_OPS(protection_mode); DEBUGFS_READ_FILE_OPS(reply_tx_error); DEBUGFS_WRITE_FILE_OPS(echo_test); -#ifdef CONFIG_IWLWIFI_DEBUG DEBUGFS_READ_WRITE_FILE_OPS(log_event); -#endif DEBUGFS_READ_WRITE_FILE_OPS(calib_disabled); /* @@ -2398,9 +2394,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); DEBUGFS_ADD_FILE(echo_test, dir_debug, S_IWUSR); -#ifdef CONFIG_IWLWIFI_DEBUG DEBUGFS_ADD_FILE(log_event, dir_debug, S_IWUSR | S_IRUSR); -#endif if (iwl_advanced_bt_coexist(priv)) DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/dev.h b/trunk/drivers/net/wireless/iwlwifi/dvm/dev.h index 54cf085ddc89..054f728f6266 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/dev.h +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/dev.h @@ -90,22 +90,6 @@ #define IWL_NUM_SCAN_RATES (2) -/* - * Minimum number of queues. MAX_NUM is defined in hw specific files. - * Set the minimum to accommodate - * - 4 standard TX queues - * - the command queue - * - 4 PAN TX queues - * - the PAN multicast queue, and - * - the AUX (TX during scan dwell) queue. - */ -#define IWL_MIN_NUM_QUEUES 11 - -/* - * Command queue depends on iPAN support. - */ -#define IWL_DEFAULT_CMD_QUEUE_NUM 4 -#define IWL_IPAN_CMD_QUEUE_NUM 9 #define IEEE80211_DATA_LEN 2304 #define IEEE80211_4ADDR_LEN 30 diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/trunk/drivers/net/wireless/iwlwifi/dvm/mac80211.c index a5f7bce96325..b83ca358eb18 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/mac80211.c @@ -801,18 +801,6 @@ static int iwlagn_mac_sta_state(struct ieee80211_hw *hw, switch (op) { case ADD: ret = iwlagn_mac_sta_add(hw, vif, sta); - if (ret) - break; - /* - * Clear the in-progress flag, the AP station entry was added - * but we'll initialize LQ only when we've associated (which - * would also clear the in-progress flag). This is necessary - * in case we never initialize LQ because association fails. - */ - spin_lock_bh(&priv->sta_lock); - priv->stations[iwl_sta_id(sta)].used &= - ~IWL_STA_UCODE_INPROGRESS; - spin_unlock_bh(&priv->sta_lock); break; case REMOVE: ret = iwlagn_mac_sta_remove(hw, vif, sta); diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/main.c b/trunk/drivers/net/wireless/iwlwifi/dvm/main.c index abfd7916bde6..612f05d757db 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/main.c @@ -518,49 +518,6 @@ static void iwl_bg_tx_flush(struct work_struct *work) * queue/FIFO/AC mapping definitions */ -#define IWL_TX_FIFO_BK 0 /* shared */ -#define IWL_TX_FIFO_BE 1 -#define IWL_TX_FIFO_VI 2 /* shared */ -#define IWL_TX_FIFO_VO 3 -#define IWL_TX_FIFO_BK_IPAN IWL_TX_FIFO_BK -#define IWL_TX_FIFO_BE_IPAN 4 -#define IWL_TX_FIFO_VI_IPAN IWL_TX_FIFO_VI -#define IWL_TX_FIFO_VO_IPAN 5 -/* re-uses the VO FIFO, uCode will properly flush/schedule */ -#define IWL_TX_FIFO_AUX 5 -#define IWL_TX_FIFO_UNUSED -1 - -#define IWLAGN_CMD_FIFO_NUM 7 - -/* - * This queue number is required for proper operation - * because the ucode will stop/start the scheduler as - * required. - */ -#define IWL_IPAN_MCAST_QUEUE 8 - -static const u8 iwlagn_default_queue_to_tx_fifo[] = { - IWL_TX_FIFO_VO, - IWL_TX_FIFO_VI, - IWL_TX_FIFO_BE, - IWL_TX_FIFO_BK, - IWLAGN_CMD_FIFO_NUM, -}; - -static const u8 iwlagn_ipan_queue_to_tx_fifo[] = { - IWL_TX_FIFO_VO, - IWL_TX_FIFO_VI, - IWL_TX_FIFO_BE, - IWL_TX_FIFO_BK, - IWL_TX_FIFO_BK_IPAN, - IWL_TX_FIFO_BE_IPAN, - IWL_TX_FIFO_VI_IPAN, - IWL_TX_FIFO_VO_IPAN, - IWL_TX_FIFO_BE_IPAN, - IWLAGN_CMD_FIFO_NUM, - IWL_TX_FIFO_AUX, -}; - static const u8 iwlagn_bss_ac_to_fifo[] = { IWL_TX_FIFO_VO, IWL_TX_FIFO_VI, @@ -1350,6 +1307,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, else trans_cfg.queue_watchdog_timeout = IWL_WATCHDOG_DISABLED; trans_cfg.command_names = iwl_dvm_cmd_strings; + trans_cfg.cmd_fifo = IWLAGN_CMD_FIFO_NUM; WARN_ON(sizeof(priv->transport_queue_stop) * BITS_PER_BYTE < priv->cfg->base_params->num_of_queues); @@ -1363,15 +1321,9 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, if (ucode_flags & IWL_UCODE_TLV_FLAGS_PAN) { priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; trans_cfg.cmd_queue = IWL_IPAN_CMD_QUEUE_NUM; - trans_cfg.queue_to_fifo = iwlagn_ipan_queue_to_tx_fifo; - trans_cfg.n_queue_to_fifo = - ARRAY_SIZE(iwlagn_ipan_queue_to_tx_fifo); } else { priv->sta_key_max_num = STA_KEY_MAX_NUM; trans_cfg.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; - trans_cfg.queue_to_fifo = iwlagn_default_queue_to_tx_fifo; - trans_cfg.n_queue_to_fifo = - ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo); } /* Configure transport layer */ @@ -1460,9 +1412,6 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, ucode_flags &= ~IWL_UCODE_TLV_FLAGS_P2P; priv->sta_key_max_num = STA_KEY_MAX_NUM; trans_cfg.cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; - trans_cfg.queue_to_fifo = iwlagn_default_queue_to_tx_fifo; - trans_cfg.n_queue_to_fifo = - ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo); /* Configure transport layer again*/ iwl_trans_configure(priv->trans, &trans_cfg); @@ -1480,9 +1429,6 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, atomic_set(&priv->queue_stop_count[i], 0); } - WARN_ON(trans_cfg.queue_to_fifo[trans_cfg.cmd_queue] != - IWLAGN_CMD_FIFO_NUM); - if (iwl_init_drv(priv)) goto out_free_eeprom; diff --git a/trunk/drivers/net/wireless/iwlwifi/dvm/ucode.c b/trunk/drivers/net/wireless/iwlwifi/dvm/ucode.c index b3a314ba48c7..6d8d6dd7943f 100644 --- a/trunk/drivers/net/wireless/iwlwifi/dvm/ucode.c +++ b/trunk/drivers/net/wireless/iwlwifi/dvm/ucode.c @@ -226,13 +226,50 @@ int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) return ret; } +static const u8 iwlagn_default_queue_to_tx_fifo[] = { + IWL_TX_FIFO_VO, + IWL_TX_FIFO_VI, + IWL_TX_FIFO_BE, + IWL_TX_FIFO_BK, +}; + +static const u8 iwlagn_ipan_queue_to_tx_fifo[] = { + IWL_TX_FIFO_VO, + IWL_TX_FIFO_VI, + IWL_TX_FIFO_BE, + IWL_TX_FIFO_BK, + IWL_TX_FIFO_BK_IPAN, + IWL_TX_FIFO_BE_IPAN, + IWL_TX_FIFO_VI_IPAN, + IWL_TX_FIFO_VO_IPAN, + IWL_TX_FIFO_BE_IPAN, + IWL_TX_FIFO_UNUSED, + IWL_TX_FIFO_AUX, +}; static int iwl_alive_notify(struct iwl_priv *priv) { + const u8 *queue_to_txf; + u8 n_queues; int ret; + int i; 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) { + n_queues = ARRAY_SIZE(iwlagn_ipan_queue_to_tx_fifo); + queue_to_txf = iwlagn_ipan_queue_to_tx_fifo; + } else { + n_queues = ARRAY_SIZE(iwlagn_default_queue_to_tx_fifo); + queue_to_txf = iwlagn_default_queue_to_tx_fifo; + } + + for (i = 0; i < n_queues; i++) + if (queue_to_txf[i] != IWL_TX_FIFO_UNUSED) + iwl_trans_ac_txq_enable(priv->trans, i, + queue_to_txf[i]); + priv->passive_no_rx = false; priv->transport_queue_stop = 0; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-drv.c b/trunk/drivers/net/wireless/iwlwifi/iwl-drv.c index a175997e7829..095547b37a27 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -911,10 +911,8 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) const struct iwl_op_mode_ops *ops = op->ops; drv->op_mode = ops->start(drv->trans, drv->cfg, &drv->fw); - if (!drv->op_mode) { - mutex_unlock(&iwlwifi_opmode_table_mtx); + if (!drv->op_mode) goto out_unbind; - } } else { load_module = true; } diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-trans.h b/trunk/drivers/net/wireless/iwlwifi/iwl-trans.h index 00efde8e5536..867d8e194da4 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -290,16 +290,17 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) * currently supports */ #define IWL_MAX_HW_QUEUES 32 +#define IWL_INVALID_STATION 255 +#define IWL_MAX_TID_COUNT 8 +#define IWL_FRAME_LIMIT 64 /** * struct iwl_trans_config - transport configuration * * @op_mode: pointer to the upper layer. - * @queue_to_fifo: queue to FIFO mapping to set up by - * default - * @n_queue_to_fifo: number of queues to set up * @cmd_queue: the index of the command queue. * Must be set before start_fw. + * @cmd_fifo: the fifo for host commands * @no_reclaim_cmds: Some devices erroneously don't set the * SEQ_RX_FRAME bit on some notifications, this is the * list of such notifications to filter. Max length is @@ -314,10 +315,9 @@ static inline struct page *rxb_steal_page(struct iwl_rx_cmd_buffer *r) */ struct iwl_trans_config { struct iwl_op_mode *op_mode; - const u8 *queue_to_fifo; - u8 n_queue_to_fifo; u8 cmd_queue; + u8 cmd_fifo; const u8 *no_reclaim_cmds; int n_no_reclaim_cmds; @@ -355,9 +355,9 @@ struct iwl_trans; * Must be atomic * @reclaim: free packet until ssn. Returns a list of freed packets. * Must be atomic - * @txq_enable: setup a tx queue for AMPDU - will be called once the HW is - * ready and a successful ADDBA response has been received. - * May sleep + * @txq_enable: setup a queue. To setup an AC queue, use the + * iwl_trans_ac_txq_enable wrapper. fw_alive must have been called before + * this one. The op_mode must not configure the HCMD queue. May sleep. * @txq_disable: de-configure a Tx queue to send AMPDUs * Must be atomic * @wait_tx_queue_empty: wait until all tx queues are empty @@ -497,9 +497,9 @@ static inline void iwl_trans_fw_alive(struct iwl_trans *trans) { might_sleep(); - trans->ops->fw_alive(trans); - trans->state = IWL_TRANS_FW_ALIVE; + + trans->ops->fw_alive(trans); } static inline int iwl_trans_start_fw(struct iwl_trans *trans, @@ -593,6 +593,13 @@ static inline void iwl_trans_txq_enable(struct iwl_trans *trans, int queue, frame_limit, ssn); } +static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue, + int fifo) +{ + iwl_trans_txq_enable(trans, queue, fifo, IWL_INVALID_STATION, + IWL_MAX_TID_COUNT, IWL_FRAME_LIMIT, 0); +} + static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans) { WARN_ONCE(trans->state != IWL_TRANS_FW_ALIVE, diff --git a/trunk/drivers/net/wireless/iwlwifi/pcie/internal.h b/trunk/drivers/net/wireless/iwlwifi/pcie/internal.h index 5024fb662bf6..d9694c58208c 100644 --- a/trunk/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/trunk/drivers/net/wireless/iwlwifi/pcie/internal.h @@ -269,10 +269,9 @@ struct iwl_trans_pcie { wait_queue_head_t ucode_write_waitq; unsigned long status; u8 cmd_queue; + u8 cmd_fifo; u8 n_no_reclaim_cmds; u8 no_reclaim_cmds[MAX_NO_RECLAIM_CMDS]; - u8 setup_q_to_fifo[IWL_MAX_HW_QUEUES]; - u8 n_q_to_fifo; bool rx_buf_size_8k; u32 rx_page_order; diff --git a/trunk/drivers/net/wireless/iwlwifi/pcie/trans.c b/trunk/drivers/net/wireless/iwlwifi/pcie/trans.c index 42f369d15f48..bac0eb0d046d 100644 --- a/trunk/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/trunk/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -1059,7 +1059,7 @@ static void iwl_tx_start(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); u32 a; - int i, chan; + int chan; u32 reg_val; /* make sure all queue are not stopped/used */ @@ -1091,12 +1091,8 @@ static void iwl_tx_start(struct iwl_trans *trans) */ iwl_write_prph(trans, SCD_CHAINEXT_EN, 0); - for (i = 0; i < trans_pcie->n_q_to_fifo; i++) { - int fifo = trans_pcie->setup_q_to_fifo[i]; - - iwl_trans_pcie_txq_enable(trans, i, fifo, IWL_INVALID_STATION, - IWL_TID_NON_QOS, SCD_FRAME_LIMIT, 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)); @@ -1528,6 +1524,7 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans, struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); trans_pcie->cmd_queue = trans_cfg->cmd_queue; + trans_pcie->cmd_fifo = trans_cfg->cmd_fifo; if (WARN_ON(trans_cfg->n_no_reclaim_cmds > MAX_NO_RECLAIM_CMDS)) trans_pcie->n_no_reclaim_cmds = 0; else @@ -1536,17 +1533,6 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans, memcpy(trans_pcie->no_reclaim_cmds, trans_cfg->no_reclaim_cmds, trans_pcie->n_no_reclaim_cmds * sizeof(u8)); - trans_pcie->n_q_to_fifo = trans_cfg->n_queue_to_fifo; - - if (WARN_ON(trans_pcie->n_q_to_fifo > IWL_MAX_HW_QUEUES)) - trans_pcie->n_q_to_fifo = IWL_MAX_HW_QUEUES; - - /* at least the command queue must be mapped */ - WARN_ON(!trans_pcie->n_q_to_fifo); - - memcpy(trans_pcie->setup_q_to_fifo, trans_cfg->queue_to_fifo, - trans_pcie->n_q_to_fifo * sizeof(u8)); - trans_pcie->rx_buf_size_8k = trans_cfg->rx_buf_size_8k; if (trans_pcie->rx_buf_size_8k) trans_pcie->rx_page_order = get_order(8 * 1024); diff --git a/trunk/drivers/net/wireless/mac80211_hwsim.c b/trunk/drivers/net/wireless/mac80211_hwsim.c index 3f38d846b093..a0b7cfd34685 100644 --- a/trunk/drivers/net/wireless/mac80211_hwsim.c +++ b/trunk/drivers/net/wireless/mac80211_hwsim.c @@ -292,7 +292,7 @@ struct mac80211_hwsim_data { struct list_head list; struct ieee80211_hw *hw; struct device *dev; - struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; + struct ieee80211_supported_band bands[2]; struct ieee80211_channel channels_2ghz[ARRAY_SIZE(hwsim_channels_2ghz)]; struct ieee80211_channel channels_5ghz[ARRAY_SIZE(hwsim_channels_5ghz)]; struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)]; @@ -678,7 +678,8 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, continue; if (data2->idle || !data2->started || - !hwsim_ps_rx_ok(data2, skb) || !data2->channel || + !hwsim_ps_rx_ok(data2, skb) || + !data->channel || !data2->channel || data->channel->center_freq != data2->channel->center_freq || !(data->group & data2->group)) continue; @@ -1082,8 +1083,6 @@ enum hwsim_testmode_attr { enum hwsim_testmode_cmd { HWSIM_TM_CMD_SET_PS = 0, HWSIM_TM_CMD_GET_PS = 1, - HWSIM_TM_CMD_STOP_QUEUES = 2, - HWSIM_TM_CMD_WAKE_QUEUES = 3, }; static const struct nla_policy hwsim_testmode_policy[HWSIM_TM_ATTR_MAX + 1] = { @@ -1123,12 +1122,6 @@ static int mac80211_hwsim_testmode_cmd(struct ieee80211_hw *hw, if (nla_put_u32(skb, HWSIM_TM_ATTR_PS, hwsim->ps)) goto nla_put_failure; return cfg80211_testmode_reply(skb); - case HWSIM_TM_CMD_STOP_QUEUES: - ieee80211_stop_queues(hw); - return 0; - case HWSIM_TM_CMD_WAKE_QUEUES: - ieee80211_wake_queues(hw); - return 0; default: return -EOPNOTSUPP; } @@ -1493,7 +1486,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2, struct mac80211_hwsim_data *data2; struct ieee80211_tx_info *txi; struct hwsim_tx_rate *tx_attempts; - unsigned long ret_skb_ptr; + struct sk_buff __user *ret_skb; struct sk_buff *skb, *tmp; struct mac_address *src; unsigned int hwsim_flags; @@ -1511,7 +1504,8 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2, info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER]); hwsim_flags = nla_get_u32(info->attrs[HWSIM_ATTR_FLAGS]); - ret_skb_ptr = nla_get_u64(info->attrs[HWSIM_ATTR_COOKIE]); + ret_skb = (struct sk_buff __user *) + (unsigned long) nla_get_u64(info->attrs[HWSIM_ATTR_COOKIE]); data2 = get_hwsim_data_ref_from_addr(src); @@ -1520,7 +1514,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2, /* look for the skb matching the cookie passed back from user */ skb_queue_walk_safe(&data2->pending, skb, tmp) { - if ((unsigned long)skb == ret_skb_ptr) { + if (skb == ret_skb) { skb_unlink(skb, &data2->pending); found = true; break; @@ -1863,7 +1857,7 @@ static int __init init_mac80211_hwsim(void) sband->n_bitrates = ARRAY_SIZE(hwsim_rates) - 4; break; default: - continue; + break; } sband->ht_cap.ht_supported = true; diff --git a/trunk/drivers/net/wireless/mwifiex/11n_rxreorder.c b/trunk/drivers/net/wireless/mwifiex/11n_rxreorder.c index 900ee129e825..9c44088054dd 100644 --- a/trunk/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/trunk/drivers/net/wireless/mwifiex/11n_rxreorder.c @@ -256,8 +256,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, else last_seq = priv->rx_seq[tid]; - if (last_seq != MWIFIEX_DEF_11N_RX_SEQ_NUM && - last_seq >= new_node->start_win) + if (last_seq >= new_node->start_win) new_node->start_win = last_seq + 1; new_node->win_size = win_size; @@ -597,5 +596,5 @@ void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv) spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr); - mwifiex_reset_11n_rx_seq_num(priv); + memset(priv->rx_seq, 0, sizeof(priv->rx_seq)); } diff --git a/trunk/drivers/net/wireless/mwifiex/11n_rxreorder.h b/trunk/drivers/net/wireless/mwifiex/11n_rxreorder.h index 6c9815a0f5d8..f1bffebabc60 100644 --- a/trunk/drivers/net/wireless/mwifiex/11n_rxreorder.h +++ b/trunk/drivers/net/wireless/mwifiex/11n_rxreorder.h @@ -37,13 +37,6 @@ #define ADDBA_RSP_STATUS_ACCEPT 0 -#define MWIFIEX_DEF_11N_RX_SEQ_NUM 0xffff - -static inline void mwifiex_reset_11n_rx_seq_num(struct mwifiex_private *priv) -{ - memset(priv->rx_seq, 0xff, sizeof(priv->rx_seq)); -} - int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *, u16 seqNum, u16 tid, u8 *ta, diff --git a/trunk/drivers/net/wireless/mwifiex/cfg80211.c b/trunk/drivers/net/wireless/mwifiex/cfg80211.c index 75843fddbad4..015fec3371a0 100644 --- a/trunk/drivers/net/wireless/mwifiex/cfg80211.c +++ b/trunk/drivers/net/wireless/mwifiex/cfg80211.c @@ -170,9 +170,7 @@ mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev, if (!priv->sec_info.wep_enabled) return 0; - if (priv->bss_type == MWIFIEX_BSS_TYPE_UAP) { - priv->wep_key_curr_index = key_index; - } else if (mwifiex_set_encode(priv, NULL, 0, key_index, NULL, 0)) { + if (mwifiex_set_encode(priv, NULL, 0, key_index, NULL, 0)) { wiphy_err(wiphy, "set default Tx key index\n"); return -EFAULT; } @@ -189,25 +187,9 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev, struct key_params *params) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); - struct mwifiex_wep_key *wep_key; const u8 bc_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; const u8 *peer_mac = pairwise ? mac_addr : bc_mac; - if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP && - (params->cipher == WLAN_CIPHER_SUITE_WEP40 || - params->cipher == WLAN_CIPHER_SUITE_WEP104)) { - if (params->key && params->key_len) { - wep_key = &priv->wep_key[key_index]; - memset(wep_key, 0, sizeof(struct mwifiex_wep_key)); - memcpy(wep_key->key_material, params->key, - params->key_len); - wep_key->key_index = key_index; - wep_key->key_length = params->key_len; - priv->sec_info.wep_enabled = 1; - } - return 0; - } - if (mwifiex_set_encode(priv, params->key, params->key_len, key_index, peer_mac, 0)) { wiphy_err(wiphy, "crypto keys added\n"); @@ -260,13 +242,13 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) flag = 1; first_chan = (u32) ch->hw_value; next_chan = first_chan; - max_pwr = ch->max_reg_power; + max_pwr = ch->max_power; no_of_parsed_chan = 1; continue; } if (ch->hw_value == next_chan + 1 && - ch->max_reg_power == max_pwr) { + ch->max_power == max_pwr) { next_chan++; no_of_parsed_chan++; } else { @@ -277,7 +259,7 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) no_of_triplet++; first_chan = (u32) ch->hw_value; next_chan = first_chan; - max_pwr = ch->max_reg_power; + max_pwr = ch->max_power; no_of_parsed_chan = 1; } } @@ -402,13 +384,13 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, cfp.freq = chan->center_freq; cfp.channel = ieee80211_frequency_to_channel(chan->center_freq); - if (priv->bss_type == MWIFIEX_BSS_TYPE_STA) { - if (mwifiex_bss_set_channel(priv, &cfp)) - return -EFAULT; - return mwifiex_drv_change_adhoc_chan(priv, cfp.channel); - } + if (mwifiex_bss_set_channel(priv, &cfp)) + return -EFAULT; - return 0; + if (priv->bss_type == MWIFIEX_BSS_TYPE_STA) + return mwifiex_drv_change_adhoc_chan(priv, cfp.channel); + else + return mwifiex_uap_set_channel(priv, cfp.channel); } /* @@ -976,29 +958,15 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, case NL80211_HIDDEN_SSID_ZERO_CONTENTS: /* firmware doesn't support this type of hidden SSID */ default: - kfree(bss_cfg); return -EINVAL; } - bss_cfg->channel = - (u8)ieee80211_frequency_to_channel(params->channel->center_freq); - bss_cfg->band_cfg = BAND_CONFIG_MANUAL; - - if (mwifiex_set_rf_channel(priv, params->channel, - params->channel_type)) { - kfree(bss_cfg); - wiphy_err(wiphy, "Failed to set band config information!\n"); - return -1; - } - if (mwifiex_set_secure_params(priv, bss_cfg, params)) { kfree(bss_cfg); wiphy_err(wiphy, "Failed to parse secuirty parameters!\n"); return -1; } - mwifiex_set_ht_params(priv, bss_cfg, params); - if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_UAP_BSS_STOP, HostCmd_ACT_GEN_SET, 0, NULL)) { wiphy_err(wiphy, "Failed to stop the BSS\n"); @@ -1022,16 +990,6 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, return -1; } - if (priv->sec_info.wep_enabled) - priv->curr_pkt_filter |= HostCmd_ACT_MAC_WEP_ENABLE; - else - priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE; - - if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_MAC_CONTROL, - HostCmd_ACT_GEN_SET, 0, - &priv->curr_pkt_filter)) - return -1; - return 0; } @@ -1423,7 +1381,7 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev, priv->user_scan_cfg->chan_list[i].scan_time = 0; } - if (mwifiex_scan_networks(priv, priv->user_scan_cfg)) + if (mwifiex_set_user_scan_ioctl(priv, priv->user_scan_cfg)) return -EFAULT; if (request->ie && request->ie_len) { @@ -1526,7 +1484,7 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev; if (!adapter) - return ERR_PTR(-EFAULT); + return NULL; switch (type) { case NL80211_IFTYPE_UNSPECIFIED: @@ -1536,12 +1494,12 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, if (priv->bss_mode) { wiphy_err(wiphy, "cannot create multiple sta/adhoc ifaces\n"); - return ERR_PTR(-EINVAL); + return NULL; } wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); if (!wdev) - return ERR_PTR(-ENOMEM); + return NULL; wdev->wiphy = wiphy; priv->wdev = wdev; @@ -1564,12 +1522,12 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, if (priv->bss_mode) { wiphy_err(wiphy, "Can't create multiple AP interfaces"); - return ERR_PTR(-EINVAL); + return NULL; } wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); if (!wdev) - return ERR_PTR(-ENOMEM); + return NULL; priv->wdev = wdev; wdev->wiphy = wiphy; @@ -1586,15 +1544,14 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, break; default: wiphy_err(wiphy, "type not supported\n"); - return ERR_PTR(-EINVAL); + return NULL; } 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; - return ERR_PTR(-ENOMEM); + goto error; } mwifiex_init_priv_params(priv, dev); @@ -1625,9 +1582,7 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, /* Register network device */ if (register_netdevice(dev)) { wiphy_err(wiphy, "cannot register virtual network device\n"); - free_netdev(dev); - priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; - return ERR_PTR(-EFAULT); + goto error; } sema_init(&priv->async_sem, 1); @@ -1639,6 +1594,12 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, mwifiex_dev_debugfs_init(priv); #endif return dev; +error: + if (dev && (dev->reg_state == NETREG_UNREGISTERED)) + free_netdev(dev); + priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; + + return NULL; } EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf); @@ -1744,7 +1705,7 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter) memcpy(wiphy->perm_addr, priv->curr_addr, ETH_ALEN); wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; - wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME; + wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME | WIPHY_FLAG_CUSTOM_REGULATORY; /* Reserve space for mwifiex specific private data for BSS */ wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv); diff --git a/trunk/drivers/net/wireless/mwifiex/cmdevt.c b/trunk/drivers/net/wireless/mwifiex/cmdevt.c index c68adec3cc8b..51e023ec1de4 100644 --- a/trunk/drivers/net/wireless/mwifiex/cmdevt.c +++ b/trunk/drivers/net/wireless/mwifiex/cmdevt.c @@ -578,7 +578,6 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no, } else { adapter->cmd_queued = cmd_node; mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true); - queue_work(adapter->workqueue, &adapter->main_work); } return ret; @@ -1103,8 +1102,7 @@ int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv, &resp->params.opt_hs_cfg; uint32_t conditions = le32_to_cpu(phs_cfg->params.hs_config.conditions); - if (phs_cfg->action == cpu_to_le16(HS_ACTIVATE) && - adapter->iface_type == MWIFIEX_SDIO) { + if (phs_cfg->action == cpu_to_le16(HS_ACTIVATE)) { mwifiex_hs_activated_event(priv, true); return 0; } else { @@ -1116,9 +1114,6 @@ int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv, } if (conditions != HOST_SLEEP_CFG_CANCEL) { adapter->is_hs_configured = true; - if (adapter->iface_type == MWIFIEX_USB || - adapter->iface_type == MWIFIEX_PCIE) - mwifiex_hs_activated_event(priv, true); } else { adapter->is_hs_configured = false; if (adapter->hs_activated) diff --git a/trunk/drivers/net/wireless/mwifiex/fw.h b/trunk/drivers/net/wireless/mwifiex/fw.h index ffb6cdfdb797..561452a5c818 100644 --- a/trunk/drivers/net/wireless/mwifiex/fw.h +++ b/trunk/drivers/net/wireless/mwifiex/fw.h @@ -124,7 +124,6 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define TLV_TYPE_UAP_DTIM_PERIOD (PROPRIETARY_TLV_BASE_ID + 45) #define TLV_TYPE_UAP_BCAST_SSID (PROPRIETARY_TLV_BASE_ID + 48) #define TLV_TYPE_UAP_RTS_THRESHOLD (PROPRIETARY_TLV_BASE_ID + 51) -#define TLV_TYPE_UAP_WEP_KEY (PROPRIETARY_TLV_BASE_ID + 59) #define TLV_TYPE_UAP_WPA_PASSPHRASE (PROPRIETARY_TLV_BASE_ID + 60) #define TLV_TYPE_UAP_ENCRY_PROTOCOL (PROPRIETARY_TLV_BASE_ID + 64) #define TLV_TYPE_UAP_AKMP (PROPRIETARY_TLV_BASE_ID + 65) @@ -163,12 +162,6 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define ISSUPP_11NENABLED(FwCapInfo) (FwCapInfo & BIT(11)) -#define MWIFIEX_DEF_HT_CAP (IEEE80211_HT_CAP_DSSSCCK40 | \ - (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT) | \ - IEEE80211_HT_CAP_SM_PS) - -#define MWIFIEX_DEF_AMPDU IEEE80211_HT_AMPDU_PARM_FACTOR - /* dev_cap bitmap * BIT * 0-16 reserved @@ -226,7 +219,6 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define HostCmd_CMD_RF_REG_ACCESS 0x001b #define HostCmd_CMD_PMIC_REG_ACCESS 0x00ad #define HostCmd_CMD_802_11_RF_CHANNEL 0x001d -#define HostCmd_CMD_RF_TX_PWR 0x001e #define HostCmd_CMD_802_11_DEAUTHENTICATE 0x0024 #define HostCmd_CMD_MAC_CONTROL 0x0028 #define HostCmd_CMD_802_11_AD_HOC_START 0x002b @@ -877,13 +869,6 @@ struct host_cmd_ds_txpwr_cfg { __le32 mode; } __packed; -struct host_cmd_ds_rf_tx_pwr { - __le16 action; - __le16 cur_level; - u8 max_power; - u8 min_power; -} __packed; - struct mwifiex_bcn_param { u8 bssid[ETH_ALEN]; u8 rssi; @@ -1210,13 +1195,6 @@ struct host_cmd_tlv_passphrase { u8 passphrase[0]; } __packed; -struct host_cmd_tlv_wep_key { - struct host_cmd_tlv tlv; - u8 key_index; - u8 is_default; - u8 key[1]; -}; - struct host_cmd_tlv_auth_type { struct host_cmd_tlv tlv; u8 auth_type; @@ -1369,7 +1347,6 @@ struct host_cmd_ds_command { struct host_cmd_ds_tx_rate_query tx_rate; struct host_cmd_ds_tx_rate_cfg tx_rate_cfg; struct host_cmd_ds_txpwr_cfg txp_cfg; - struct host_cmd_ds_rf_tx_pwr txp; struct host_cmd_ds_802_11_ps_mode_enh psmode_enh; struct host_cmd_ds_802_11_hs_cfg_enh opt_hs_cfg; struct host_cmd_ds_802_11_scan scan; diff --git a/trunk/drivers/net/wireless/mwifiex/ie.c b/trunk/drivers/net/wireless/mwifiex/ie.c index 8374e33f195a..ceb82cd749cc 100644 --- a/trunk/drivers/net/wireless/mwifiex/ie.c +++ b/trunk/drivers/net/wireless/mwifiex/ie.c @@ -213,7 +213,6 @@ mwifiex_update_uap_custom_ie(struct mwifiex_private *priv, /* save assoc resp ie index after auto-indexing */ *assoc_idx = *((u16 *)pos); - kfree(ap_custom_ie); return ret; } @@ -225,46 +224,29 @@ int mwifiex_set_mgmt_ies(struct mwifiex_private *priv, struct cfg80211_ap_settings *params) { struct mwifiex_ie *beacon_ie = NULL, *pr_ie = NULL; - struct mwifiex_ie *ar_ie = NULL, *gen_ie = NULL; - struct ieee_types_header *rsn_ie = NULL, *wpa_ie = NULL; + struct mwifiex_ie *ar_ie = NULL, *rsn_ie = NULL; + struct ieee_types_header *ie = NULL; u16 beacon_idx = MWIFIEX_AUTO_IDX_MASK, pr_idx = MWIFIEX_AUTO_IDX_MASK; u16 ar_idx = MWIFIEX_AUTO_IDX_MASK, rsn_idx = MWIFIEX_AUTO_IDX_MASK; - u16 mask, ie_len = 0; - const u8 *vendor_ie; + u16 mask; int ret = 0; if (params->beacon.tail && params->beacon.tail_len) { - gen_ie = kzalloc(sizeof(struct mwifiex_ie), GFP_KERNEL); - if (!gen_ie) - return -ENOMEM; - gen_ie->ie_index = cpu_to_le16(rsn_idx); - mask = MGMT_MASK_BEACON | MGMT_MASK_PROBE_RESP | - MGMT_MASK_ASSOC_RESP; - gen_ie->mgmt_subtype_mask = cpu_to_le16(mask); - - rsn_ie = (void *)cfg80211_find_ie(WLAN_EID_RSN, - params->beacon.tail, - params->beacon.tail_len); - if (rsn_ie) { - memcpy(gen_ie->ie_buffer, rsn_ie, rsn_ie->len + 2); - ie_len = rsn_ie->len + 2; - gen_ie->ie_length = cpu_to_le16(ie_len); - } - - vendor_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, - WLAN_OUI_TYPE_MICROSOFT_WPA, - params->beacon.tail, - params->beacon.tail_len); - if (vendor_ie) { - wpa_ie = (struct ieee_types_header *)vendor_ie; - memcpy(gen_ie->ie_buffer + ie_len, - wpa_ie, wpa_ie->len + 2); - ie_len += wpa_ie->len + 2; - gen_ie->ie_length = cpu_to_le16(ie_len); - } - - if (rsn_ie || wpa_ie) { - if (mwifiex_update_uap_custom_ie(priv, gen_ie, &rsn_idx, + ie = (void *)cfg80211_find_ie(WLAN_EID_RSN, params->beacon.tail, + params->beacon.tail_len); + if (ie) { + rsn_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL); + if (!rsn_ie) + return -ENOMEM; + + rsn_ie->ie_index = cpu_to_le16(rsn_idx); + mask = MGMT_MASK_BEACON | MGMT_MASK_PROBE_RESP | + MGMT_MASK_ASSOC_RESP; + rsn_ie->mgmt_subtype_mask = cpu_to_le16(mask); + rsn_ie->ie_length = cpu_to_le16(ie->len + 2); + memcpy(rsn_ie->ie_buffer, ie, ie->len + 2); + + if (mwifiex_update_uap_custom_ie(priv, rsn_ie, &rsn_idx, NULL, NULL, NULL, NULL)) { ret = -1; @@ -337,7 +319,7 @@ int mwifiex_set_mgmt_ies(struct mwifiex_private *priv, kfree(beacon_ie); kfree(pr_ie); kfree(ar_ie); - kfree(gen_ie); + kfree(rsn_ie); return ret; } diff --git a/trunk/drivers/net/wireless/mwifiex/init.c b/trunk/drivers/net/wireless/mwifiex/init.c index b543a4d82ff3..0f18ef6a30c8 100644 --- a/trunk/drivers/net/wireless/mwifiex/init.c +++ b/trunk/drivers/net/wireless/mwifiex/init.c @@ -103,7 +103,6 @@ static void scan_delay_timer_fn(unsigned long data) msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC)); adapter->scan_delay_cnt++; } - queue_work(priv->adapter->workqueue, &priv->adapter->main_work); } else { /* * Tx data queue is empty. Get scan command from scan_pending_q diff --git a/trunk/drivers/net/wireless/mwifiex/ioctl.h b/trunk/drivers/net/wireless/mwifiex/ioctl.h index 9f088fb88cb7..e6be6ee75951 100644 --- a/trunk/drivers/net/wireless/mwifiex/ioctl.h +++ b/trunk/drivers/net/wireless/mwifiex/ioctl.h @@ -21,7 +21,6 @@ #define _MWIFIEX_IOCTL_H_ #include -#include enum { MWIFIEX_SCAN_TYPE_UNCHANGED = 0, @@ -72,13 +71,6 @@ struct wpa_param { u8 passphrase[MWIFIEX_WPA_PASSHPHRASE_LEN]; }; -struct wep_key { - u8 key_index; - u8 is_default; - u16 length; - u8 key[WLAN_KEY_LEN_WEP104]; -}; - #define KEY_MGMT_ON_HOST 0x03 #define MWIFIEX_AUTH_MODE_AUTO 0xFF #define BAND_CONFIG_MANUAL 0x00 @@ -98,8 +90,6 @@ struct mwifiex_uap_bss_param { u16 key_mgmt; u16 key_mgmt_operation; struct wpa_param wpa_cfg; - struct wep_key wep_cfg[NUM_WEP_KEYS]; - struct ieee80211_ht_cap ht_cap; }; enum { diff --git a/trunk/drivers/net/wireless/mwifiex/main.c b/trunk/drivers/net/wireless/mwifiex/main.c index f0219efc8953..0f06f07a70e6 100644 --- a/trunk/drivers/net/wireless/mwifiex/main.c +++ b/trunk/drivers/net/wireless/mwifiex/main.c @@ -190,8 +190,7 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter) adapter->tx_lock_flag) break; - if ((adapter->scan_processing && - !adapter->scan_delay_cnt) || adapter->data_sent || + if (adapter->scan_processing || adapter->data_sent || mwifiex_wmm_lists_empty(adapter)) { if (adapter->cmd_sent || adapter->curr_cmd || (!is_command_pending(adapter))) diff --git a/trunk/drivers/net/wireless/mwifiex/main.h b/trunk/drivers/net/wireless/mwifiex/main.h index 7cd95cc99a85..5b32221077c4 100644 --- a/trunk/drivers/net/wireless/mwifiex/main.h +++ b/trunk/drivers/net/wireless/mwifiex/main.h @@ -840,9 +840,6 @@ void mwifiex_init_priv_params(struct mwifiex_private *priv, int mwifiex_set_secure_params(struct mwifiex_private *priv, struct mwifiex_uap_bss_param *bss_config, struct cfg80211_ap_settings *params); -void mwifiex_set_ht_params(struct mwifiex_private *priv, - struct mwifiex_uap_bss_param *bss_cfg, - struct cfg80211_ap_settings *params); /* * This function checks if the queuing is RA based or not. @@ -949,8 +946,8 @@ int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, struct mwifiex_rate_cfg *rate); int mwifiex_request_scan(struct mwifiex_private *priv, struct cfg80211_ssid *req_ssid); -int mwifiex_scan_networks(struct mwifiex_private *priv, - const struct mwifiex_user_scan_cfg *user_scan_in); +int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, + struct mwifiex_user_scan_cfg *scan_req); int mwifiex_set_radio(struct mwifiex_private *priv, u8 option); int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel); @@ -993,6 +990,7 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv, int mwifiex_main_process(struct mwifiex_adapter *); +int mwifiex_uap_set_channel(struct mwifiex_private *priv, int channel); int mwifiex_bss_set_channel(struct mwifiex_private *, struct mwifiex_chan_freq_power *cfp); int mwifiex_get_bss_info(struct mwifiex_private *, diff --git a/trunk/drivers/net/wireless/mwifiex/scan.c b/trunk/drivers/net/wireless/mwifiex/scan.c index 884ed6377003..efaf26ccd6ba 100644 --- a/trunk/drivers/net/wireless/mwifiex/scan.c +++ b/trunk/drivers/net/wireless/mwifiex/scan.c @@ -1296,8 +1296,8 @@ mwifiex_radio_type_to_band(u8 radio_type) * order to send the appropriate scan commands to firmware to populate or * update the internal driver scan table. */ -int mwifiex_scan_networks(struct mwifiex_private *priv, - const struct mwifiex_user_scan_cfg *user_scan_in) +static int mwifiex_scan_networks(struct mwifiex_private *priv, + const struct mwifiex_user_scan_cfg *user_scan_in) { int ret = 0; struct mwifiex_adapter *adapter = priv->adapter; @@ -1362,7 +1362,6 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, adapter->cmd_queued = cmd_node; mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true); - queue_work(adapter->workqueue, &adapter->main_work); } else { spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); @@ -1378,6 +1377,26 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, return ret; } +/* + * Sends IOCTL request to start a scan with user configurations. + * + * This function allocates the IOCTL request buffer, fills it + * with requisite parameters and calls the IOCTL handler. + * + * Upon completion, it also generates a wireless event to notify + * applications. + */ +int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, + struct mwifiex_user_scan_cfg *scan_req) +{ + int status; + + status = mwifiex_scan_networks(priv, scan_req); + queue_work(priv->adapter->workqueue, &priv->adapter->main_work); + + return status; +} + /* * This function prepares a scan command to be sent to the firmware. * diff --git a/trunk/drivers/net/wireless/mwifiex/sdio.c b/trunk/drivers/net/wireless/mwifiex/sdio.c index fc8a9bfa1248..e0377473282f 100644 --- a/trunk/drivers/net/wireless/mwifiex/sdio.c +++ b/trunk/drivers/net/wireless/mwifiex/sdio.c @@ -978,10 +978,10 @@ static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter, dev_dbg(adapter->dev, "info: --- Rx: Event ---\n"); adapter->event_cause = *(u32 *) skb->data; + skb_pull(skb, MWIFIEX_EVENT_HEADER_LEN); + if ((skb->len > 0) && (skb->len < MAX_EVENT_SIZE)) - memcpy(adapter->event_body, - skb->data + MWIFIEX_EVENT_HEADER_LEN, - skb->len); + memcpy(adapter->event_body, skb->data, skb->len); /* event cause has been saved to adapter->event_cause */ adapter->event_received = true; diff --git a/trunk/drivers/net/wireless/mwifiex/sta_cmd.c b/trunk/drivers/net/wireless/mwifiex/sta_cmd.c index 2d4319a8941f..40e025da6bc2 100644 --- a/trunk/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/trunk/drivers/net/wireless/mwifiex/sta_cmd.c @@ -259,23 +259,6 @@ static int mwifiex_cmd_tx_power_cfg(struct host_cmd_ds_command *cmd, return 0; } -/* - * This function prepares command to get RF Tx power. - */ -static int mwifiex_cmd_rf_tx_power(struct mwifiex_private *priv, - struct host_cmd_ds_command *cmd, - u16 cmd_action, void *data_buf) -{ - struct host_cmd_ds_rf_tx_pwr *txp = &cmd->params.txp; - - cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_rf_tx_pwr) - + S_DS_GEN); - cmd->command = cpu_to_le16(HostCmd_CMD_RF_TX_PWR); - txp->action = cpu_to_le16(cmd_action); - - return 0; -} - /* * This function prepares command to set Host Sleep configuration. * @@ -1072,10 +1055,6 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, ret = mwifiex_cmd_tx_power_cfg(cmd_ptr, cmd_action, data_buf); break; - case HostCmd_CMD_RF_TX_PWR: - ret = mwifiex_cmd_rf_tx_power(priv, cmd_ptr, cmd_action, - data_buf); - break; case HostCmd_CMD_802_11_PS_MODE_ENH: ret = mwifiex_cmd_enh_power_mode(priv, cmd_ptr, cmd_action, (uint16_t)cmd_oid, data_buf); @@ -1304,7 +1283,7 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta) priv->data_rate = 0; /* get tx power */ - ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_RF_TX_PWR, + ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_TXPWR_CFG, HostCmd_ACT_GEN_GET, 0, NULL); if (ret) return -1; diff --git a/trunk/drivers/net/wireless/mwifiex/sta_cmdresp.c b/trunk/drivers/net/wireless/mwifiex/sta_cmdresp.c index 4cb2c1c78397..a79ed9bd9695 100644 --- a/trunk/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/trunk/drivers/net/wireless/mwifiex/sta_cmdresp.c @@ -450,30 +450,6 @@ static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv, return 0; } -/* - * This function handles the command response of get RF Tx power. - */ -static int mwifiex_ret_rf_tx_power(struct mwifiex_private *priv, - struct host_cmd_ds_command *resp) -{ - struct host_cmd_ds_rf_tx_pwr *txp = &resp->params.txp; - u16 action = le16_to_cpu(txp->action); - - priv->tx_power_level = le16_to_cpu(txp->cur_level); - - if (action == HostCmd_ACT_GEN_GET) { - priv->max_tx_power_level = txp->max_power; - priv->min_tx_power_level = txp->min_power; - } - - dev_dbg(priv->adapter->dev, - "Current TxPower Level=%d, Max Power=%d, Min Power=%d\n", - priv->tx_power_level, priv->max_tx_power_level, - priv->min_tx_power_level); - - return 0; -} - /* * This function handles the command response of set/get MAC address. * @@ -871,9 +847,6 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, case HostCmd_CMD_TXPWR_CFG: ret = mwifiex_ret_tx_power_cfg(priv, resp); break; - case HostCmd_CMD_RF_TX_PWR: - ret = mwifiex_ret_rf_tx_power(priv, resp); - break; case HostCmd_CMD_802_11_PS_MODE_ENH: ret = mwifiex_ret_enh_power_mode(priv, resp, data_buf); break; diff --git a/trunk/drivers/net/wireless/mwifiex/sta_event.c b/trunk/drivers/net/wireless/mwifiex/sta_event.c index 11e731f3581c..4ace5a3dcd23 100644 --- a/trunk/drivers/net/wireless/mwifiex/sta_event.c +++ b/trunk/drivers/net/wireless/mwifiex/sta_event.c @@ -406,9 +406,9 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) break; case EVENT_UAP_STA_ASSOC: + skb_pull(adapter->event_skb, MWIFIEX_UAP_EVENT_EXTRA_HEADER); memset(&sinfo, 0, sizeof(sinfo)); - event = (struct mwifiex_assoc_event *) - (adapter->event_body + MWIFIEX_UAP_EVENT_EXTRA_HEADER); + event = (struct mwifiex_assoc_event *)adapter->event_skb->data; if (le16_to_cpu(event->type) == TLV_TYPE_UAP_MGMT_FRAME) { len = -1; @@ -433,8 +433,9 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) GFP_KERNEL); break; case EVENT_UAP_STA_DEAUTH: - cfg80211_del_sta(priv->netdev, adapter->event_body + - MWIFIEX_UAP_EVENT_EXTRA_HEADER, GFP_KERNEL); + skb_pull(adapter->event_skb, MWIFIEX_UAP_EVENT_EXTRA_HEADER); + cfg80211_del_sta(priv->netdev, adapter->event_skb->data, + GFP_KERNEL); break; case EVENT_UAP_BSS_IDLE: priv->media_connected = false; diff --git a/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c b/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c index f2fd2423214f..106c449477b2 100644 --- a/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/trunk/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -66,6 +66,9 @@ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter) dev_dbg(adapter->dev, "cmd pending\n"); atomic_inc(&adapter->cmd_pending); + /* Status pending, wake up main process */ + queue_work(adapter->workqueue, &adapter->main_work); + /* Wait for completion */ wait_event_interruptible(adapter->cmd_wait_q.wait, *(cmd_queued->condition)); diff --git a/trunk/drivers/net/wireless/mwifiex/txrx.c b/trunk/drivers/net/wireless/mwifiex/txrx.c index cecb27283196..e2faec4db108 100644 --- a/trunk/drivers/net/wireless/mwifiex/txrx.c +++ b/trunk/drivers/net/wireless/mwifiex/txrx.c @@ -161,11 +161,15 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, goto done; for (i = 0; i < adapter->priv_num; i++) { + tpriv = adapter->priv[i]; - if (tpriv->media_connected && - netif_queue_stopped(tpriv->netdev)) - mwifiex_wake_up_net_dev_queue(tpriv->netdev, adapter); + if ((GET_BSS_ROLE(tpriv) == MWIFIEX_BSS_ROLE_STA) && + (tpriv->media_connected)) { + if (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_cmd.c b/trunk/drivers/net/wireless/mwifiex/uap_cmd.c index f40e93fe894a..8173ab66066d 100644 --- a/trunk/drivers/net/wireless/mwifiex/uap_cmd.c +++ b/trunk/drivers/net/wireless/mwifiex/uap_cmd.c @@ -26,18 +26,6 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv, struct mwifiex_uap_bss_param *bss_config, struct cfg80211_ap_settings *params) { int i; - struct mwifiex_wep_key wep_key; - - if (!params->privacy) { - bss_config->protocol = PROTOCOL_NO_SECURITY; - bss_config->key_mgmt = KEY_MGMT_NONE; - bss_config->wpa_cfg.length = 0; - priv->sec_info.wep_enabled = 0; - priv->sec_info.wpa_enabled = 0; - priv->sec_info.wpa2_enabled = 0; - - return 0; - } switch (params->auth_type) { case NL80211_AUTHTYPE_OPEN_SYSTEM: @@ -66,7 +54,7 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv, } if (params->crypto.wpa_versions & NL80211_WPA_VERSION_2) { - bss_config->protocol |= PROTOCOL_WPA2; + bss_config->protocol = PROTOCOL_WPA2; bss_config->key_mgmt = KEY_MGMT_EAP; } break; @@ -78,7 +66,7 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv, } if (params->crypto.wpa_versions & NL80211_WPA_VERSION_2) { - bss_config->protocol |= PROTOCOL_WPA2; + bss_config->protocol = PROTOCOL_WPA2; bss_config->key_mgmt = KEY_MGMT_PSK; } break; @@ -92,19 +80,10 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv, case WLAN_CIPHER_SUITE_WEP104: break; case WLAN_CIPHER_SUITE_TKIP: - if (params->crypto.wpa_versions & NL80211_WPA_VERSION_1) - bss_config->wpa_cfg.pairwise_cipher_wpa |= - CIPHER_TKIP; - if (params->crypto.wpa_versions & NL80211_WPA_VERSION_2) - bss_config->wpa_cfg.pairwise_cipher_wpa2 |= - CIPHER_TKIP; + bss_config->wpa_cfg.pairwise_cipher_wpa = CIPHER_TKIP; break; case WLAN_CIPHER_SUITE_CCMP: - if (params->crypto.wpa_versions & NL80211_WPA_VERSION_1) - bss_config->wpa_cfg.pairwise_cipher_wpa |= - CIPHER_AES_CCMP; - if (params->crypto.wpa_versions & NL80211_WPA_VERSION_2) - bss_config->wpa_cfg.pairwise_cipher_wpa2 |= + bss_config->wpa_cfg.pairwise_cipher_wpa2 = CIPHER_AES_CCMP; default: break; @@ -114,27 +93,6 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv, switch (params->crypto.cipher_group) { case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: - if (priv->sec_info.wep_enabled) { - bss_config->protocol = PROTOCOL_STATIC_WEP; - bss_config->key_mgmt = KEY_MGMT_NONE; - bss_config->wpa_cfg.length = 0; - - for (i = 0; i < NUM_WEP_KEYS; i++) { - wep_key = priv->wep_key[i]; - bss_config->wep_cfg[i].key_index = i; - - if (priv->wep_key_curr_index == i) - bss_config->wep_cfg[i].is_default = 1; - else - bss_config->wep_cfg[i].is_default = 0; - - bss_config->wep_cfg[i].length = - wep_key.key_length; - memcpy(&bss_config->wep_cfg[i].key, - &wep_key.key_material, - wep_key.key_length); - } - } break; case WLAN_CIPHER_SUITE_TKIP: bss_config->wpa_cfg.group_cipher = CIPHER_TKIP; @@ -149,33 +107,6 @@ int mwifiex_set_secure_params(struct mwifiex_private *priv, return 0; } -/* This function updates 11n related parameters from IE and sets them into - * bss_config structure. - */ -void -mwifiex_set_ht_params(struct mwifiex_private *priv, - struct mwifiex_uap_bss_param *bss_cfg, - struct cfg80211_ap_settings *params) -{ - const u8 *ht_ie; - - if (!ISSUPP_11NENABLED(priv->adapter->fw_cap_info)) - return; - - ht_ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, params->beacon.tail, - params->beacon.tail_len); - if (ht_ie) { - memcpy(&bss_cfg->ht_cap, ht_ie + 2, - sizeof(struct ieee80211_ht_cap)); - } else { - memset(&bss_cfg->ht_cap , 0, sizeof(struct ieee80211_ht_cap)); - bss_cfg->ht_cap.cap_info = cpu_to_le16(MWIFIEX_DEF_HT_CAP); - bss_cfg->ht_cap.ampdu_params_info = MWIFIEX_DEF_AMPDU; - } - - return; -} - /* This function initializes some of mwifiex_uap_bss_param variables. * This helps FW in ignoring invalid values. These values may or may not * be get updated to valid ones at later stage. @@ -192,120 +123,6 @@ void mwifiex_set_sys_config_invalid_data(struct mwifiex_uap_bss_param *config) config->retry_limit = 0x7F; } -/* This function parses BSS related parameters from structure - * and prepares TLVs specific to WPA/WPA2 security. - * These TLVs are appended to command buffer. - */ -static void -mwifiex_uap_bss_wpa(u8 **tlv_buf, void *cmd_buf, u16 *param_size) -{ - struct host_cmd_tlv_pwk_cipher *pwk_cipher; - struct host_cmd_tlv_gwk_cipher *gwk_cipher; - struct host_cmd_tlv_passphrase *passphrase; - struct host_cmd_tlv_akmp *tlv_akmp; - struct mwifiex_uap_bss_param *bss_cfg = cmd_buf; - u16 cmd_size = *param_size; - u8 *tlv = *tlv_buf; - - tlv_akmp = (struct host_cmd_tlv_akmp *)tlv; - tlv_akmp->tlv.type = cpu_to_le16(TLV_TYPE_UAP_AKMP); - tlv_akmp->tlv.len = cpu_to_le16(sizeof(struct host_cmd_tlv_akmp) - - sizeof(struct host_cmd_tlv)); - tlv_akmp->key_mgmt_operation = cpu_to_le16(bss_cfg->key_mgmt_operation); - tlv_akmp->key_mgmt = cpu_to_le16(bss_cfg->key_mgmt); - cmd_size += sizeof(struct host_cmd_tlv_akmp); - tlv += sizeof(struct host_cmd_tlv_akmp); - - if (bss_cfg->wpa_cfg.pairwise_cipher_wpa & VALID_CIPHER_BITMAP) { - pwk_cipher = (struct host_cmd_tlv_pwk_cipher *)tlv; - pwk_cipher->tlv.type = cpu_to_le16(TLV_TYPE_PWK_CIPHER); - pwk_cipher->tlv.len = - cpu_to_le16(sizeof(struct host_cmd_tlv_pwk_cipher) - - sizeof(struct host_cmd_tlv)); - pwk_cipher->proto = cpu_to_le16(PROTOCOL_WPA); - pwk_cipher->cipher = bss_cfg->wpa_cfg.pairwise_cipher_wpa; - cmd_size += sizeof(struct host_cmd_tlv_pwk_cipher); - tlv += sizeof(struct host_cmd_tlv_pwk_cipher); - } - - if (bss_cfg->wpa_cfg.pairwise_cipher_wpa2 & VALID_CIPHER_BITMAP) { - pwk_cipher = (struct host_cmd_tlv_pwk_cipher *)tlv; - pwk_cipher->tlv.type = cpu_to_le16(TLV_TYPE_PWK_CIPHER); - pwk_cipher->tlv.len = - cpu_to_le16(sizeof(struct host_cmd_tlv_pwk_cipher) - - sizeof(struct host_cmd_tlv)); - pwk_cipher->proto = cpu_to_le16(PROTOCOL_WPA2); - pwk_cipher->cipher = bss_cfg->wpa_cfg.pairwise_cipher_wpa2; - cmd_size += sizeof(struct host_cmd_tlv_pwk_cipher); - tlv += sizeof(struct host_cmd_tlv_pwk_cipher); - } - - if (bss_cfg->wpa_cfg.group_cipher & VALID_CIPHER_BITMAP) { - gwk_cipher = (struct host_cmd_tlv_gwk_cipher *)tlv; - gwk_cipher->tlv.type = cpu_to_le16(TLV_TYPE_GWK_CIPHER); - gwk_cipher->tlv.len = - cpu_to_le16(sizeof(struct host_cmd_tlv_gwk_cipher) - - sizeof(struct host_cmd_tlv)); - gwk_cipher->cipher = bss_cfg->wpa_cfg.group_cipher; - cmd_size += sizeof(struct host_cmd_tlv_gwk_cipher); - tlv += sizeof(struct host_cmd_tlv_gwk_cipher); - } - - if (bss_cfg->wpa_cfg.length) { - passphrase = (struct host_cmd_tlv_passphrase *)tlv; - passphrase->tlv.type = cpu_to_le16(TLV_TYPE_UAP_WPA_PASSPHRASE); - passphrase->tlv.len = cpu_to_le16(bss_cfg->wpa_cfg.length); - memcpy(passphrase->passphrase, bss_cfg->wpa_cfg.passphrase, - bss_cfg->wpa_cfg.length); - cmd_size += sizeof(struct host_cmd_tlv) + - bss_cfg->wpa_cfg.length; - tlv += sizeof(struct host_cmd_tlv) + bss_cfg->wpa_cfg.length; - } - - *param_size = cmd_size; - *tlv_buf = tlv; - - return; -} - -/* This function parses BSS related parameters from structure - * and prepares TLVs specific to WEP encryption. - * These TLVs are appended to command buffer. - */ -static void -mwifiex_uap_bss_wep(u8 **tlv_buf, void *cmd_buf, u16 *param_size) -{ - struct host_cmd_tlv_wep_key *wep_key; - u16 cmd_size = *param_size; - int i; - u8 *tlv = *tlv_buf; - struct mwifiex_uap_bss_param *bss_cfg = cmd_buf; - - for (i = 0; i < NUM_WEP_KEYS; i++) { - if (bss_cfg->wep_cfg[i].length && - (bss_cfg->wep_cfg[i].length == WLAN_KEY_LEN_WEP40 || - bss_cfg->wep_cfg[i].length == WLAN_KEY_LEN_WEP104)) { - wep_key = (struct host_cmd_tlv_wep_key *)tlv; - wep_key->tlv.type = cpu_to_le16(TLV_TYPE_UAP_WEP_KEY); - wep_key->tlv.len = - cpu_to_le16(bss_cfg->wep_cfg[i].length + 2); - wep_key->key_index = bss_cfg->wep_cfg[i].key_index; - wep_key->is_default = bss_cfg->wep_cfg[i].is_default; - memcpy(wep_key->key, bss_cfg->wep_cfg[i].key, - bss_cfg->wep_cfg[i].length); - cmd_size += sizeof(struct host_cmd_tlv) + 2 + - bss_cfg->wep_cfg[i].length; - tlv += sizeof(struct host_cmd_tlv) + 2 + - bss_cfg->wep_cfg[i].length; - } - } - - *param_size = cmd_size; - *tlv_buf = tlv; - - return; -} - /* This function parses BSS related parameters from structure * and prepares TLVs. These TLVs are appended to command buffer. */ @@ -320,9 +137,12 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) struct host_cmd_tlv_frag_threshold *frag_threshold; struct host_cmd_tlv_rts_threshold *rts_threshold; struct host_cmd_tlv_retry_limit *retry_limit; + struct host_cmd_tlv_pwk_cipher *pwk_cipher; + struct host_cmd_tlv_gwk_cipher *gwk_cipher; struct host_cmd_tlv_encrypt_protocol *encrypt_protocol; struct host_cmd_tlv_auth_type *auth_type; - struct mwifiex_ie_types_htcap *htcap; + struct host_cmd_tlv_passphrase *passphrase; + struct host_cmd_tlv_akmp *tlv_akmp; struct mwifiex_uap_bss_param *bss_cfg = cmd_buf; u16 cmd_size = *param_size; @@ -412,11 +232,70 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) } if ((bss_cfg->protocol & PROTOCOL_WPA) || (bss_cfg->protocol & PROTOCOL_WPA2) || - (bss_cfg->protocol & PROTOCOL_EAP)) - mwifiex_uap_bss_wpa(&tlv, cmd_buf, &cmd_size); - else - mwifiex_uap_bss_wep(&tlv, cmd_buf, &cmd_size); - + (bss_cfg->protocol & PROTOCOL_EAP)) { + tlv_akmp = (struct host_cmd_tlv_akmp *)tlv; + tlv_akmp->tlv.type = cpu_to_le16(TLV_TYPE_UAP_AKMP); + tlv_akmp->tlv.len = + cpu_to_le16(sizeof(struct host_cmd_tlv_akmp) - + sizeof(struct host_cmd_tlv)); + tlv_akmp->key_mgmt_operation = + cpu_to_le16(bss_cfg->key_mgmt_operation); + tlv_akmp->key_mgmt = cpu_to_le16(bss_cfg->key_mgmt); + cmd_size += sizeof(struct host_cmd_tlv_akmp); + tlv += sizeof(struct host_cmd_tlv_akmp); + + if (bss_cfg->wpa_cfg.pairwise_cipher_wpa & + VALID_CIPHER_BITMAP) { + pwk_cipher = (struct host_cmd_tlv_pwk_cipher *)tlv; + pwk_cipher->tlv.type = + cpu_to_le16(TLV_TYPE_PWK_CIPHER); + pwk_cipher->tlv.len = cpu_to_le16( + sizeof(struct host_cmd_tlv_pwk_cipher) - + sizeof(struct host_cmd_tlv)); + pwk_cipher->proto = cpu_to_le16(PROTOCOL_WPA); + pwk_cipher->cipher = + bss_cfg->wpa_cfg.pairwise_cipher_wpa; + cmd_size += sizeof(struct host_cmd_tlv_pwk_cipher); + tlv += sizeof(struct host_cmd_tlv_pwk_cipher); + } + if (bss_cfg->wpa_cfg.pairwise_cipher_wpa2 & + VALID_CIPHER_BITMAP) { + pwk_cipher = (struct host_cmd_tlv_pwk_cipher *)tlv; + pwk_cipher->tlv.type = cpu_to_le16(TLV_TYPE_PWK_CIPHER); + pwk_cipher->tlv.len = cpu_to_le16( + sizeof(struct host_cmd_tlv_pwk_cipher) - + sizeof(struct host_cmd_tlv)); + pwk_cipher->proto = cpu_to_le16(PROTOCOL_WPA2); + pwk_cipher->cipher = + bss_cfg->wpa_cfg.pairwise_cipher_wpa2; + cmd_size += sizeof(struct host_cmd_tlv_pwk_cipher); + tlv += sizeof(struct host_cmd_tlv_pwk_cipher); + } + if (bss_cfg->wpa_cfg.group_cipher & VALID_CIPHER_BITMAP) { + gwk_cipher = (struct host_cmd_tlv_gwk_cipher *)tlv; + gwk_cipher->tlv.type = cpu_to_le16(TLV_TYPE_GWK_CIPHER); + gwk_cipher->tlv.len = cpu_to_le16( + sizeof(struct host_cmd_tlv_gwk_cipher) - + sizeof(struct host_cmd_tlv)); + gwk_cipher->cipher = bss_cfg->wpa_cfg.group_cipher; + cmd_size += sizeof(struct host_cmd_tlv_gwk_cipher); + tlv += sizeof(struct host_cmd_tlv_gwk_cipher); + } + if (bss_cfg->wpa_cfg.length) { + passphrase = (struct host_cmd_tlv_passphrase *)tlv; + passphrase->tlv.type = + cpu_to_le16(TLV_TYPE_UAP_WPA_PASSPHRASE); + passphrase->tlv.len = + cpu_to_le16(bss_cfg->wpa_cfg.length); + memcpy(passphrase->passphrase, + bss_cfg->wpa_cfg.passphrase, + bss_cfg->wpa_cfg.length); + cmd_size += sizeof(struct host_cmd_tlv) + + bss_cfg->wpa_cfg.length; + tlv += sizeof(struct host_cmd_tlv) + + bss_cfg->wpa_cfg.length; + } + } if ((bss_cfg->auth_mode <= WLAN_AUTH_SHARED_KEY) || (bss_cfg->auth_mode == MWIFIEX_AUTH_MODE_AUTO)) { auth_type = (struct host_cmd_tlv_auth_type *)tlv; @@ -440,25 +319,6 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size) tlv += sizeof(struct host_cmd_tlv_encrypt_protocol); } - if (bss_cfg->ht_cap.cap_info) { - htcap = (struct mwifiex_ie_types_htcap *)tlv; - htcap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY); - htcap->header.len = - cpu_to_le16(sizeof(struct ieee80211_ht_cap)); - htcap->ht_cap.cap_info = bss_cfg->ht_cap.cap_info; - htcap->ht_cap.ampdu_params_info = - bss_cfg->ht_cap.ampdu_params_info; - memcpy(&htcap->ht_cap.mcs, &bss_cfg->ht_cap.mcs, - sizeof(struct ieee80211_mcs_info)); - htcap->ht_cap.extended_ht_cap_info = - bss_cfg->ht_cap.extended_ht_cap_info; - htcap->ht_cap.tx_BF_cap_info = bss_cfg->ht_cap.tx_BF_cap_info; - htcap->ht_cap.antenna_selection_info = - bss_cfg->ht_cap.antenna_selection_info; - cmd_size += sizeof(struct mwifiex_ie_types_htcap); - tlv += sizeof(struct mwifiex_ie_types_htcap); - } - *param_size = cmd_size; return 0; @@ -550,3 +410,33 @@ int mwifiex_uap_prepare_cmd(struct mwifiex_private *priv, u16 cmd_no, return 0; } + +/* This function sets the RF channel for AP. + * + * This function populates channel information in AP config structure + * and sends command to configure channel information in AP. + */ +int mwifiex_uap_set_channel(struct mwifiex_private *priv, int channel) +{ + struct mwifiex_uap_bss_param *bss_cfg; + struct wiphy *wiphy = priv->wdev->wiphy; + + bss_cfg = kzalloc(sizeof(struct mwifiex_uap_bss_param), GFP_KERNEL); + if (!bss_cfg) + return -ENOMEM; + + mwifiex_set_sys_config_invalid_data(bss_cfg); + bss_cfg->band_cfg = BAND_CONFIG_MANUAL; + bss_cfg->channel = channel; + + if (mwifiex_send_cmd_async(priv, HostCmd_CMD_UAP_SYS_CONFIG, + HostCmd_ACT_GEN_SET, + UAP_BSS_PARAMS_I, bss_cfg)) { + wiphy_err(wiphy, "Failed to set the uAP channel\n"); + kfree(bss_cfg); + return -1; + } + + kfree(bss_cfg); + return 0; +} diff --git a/trunk/drivers/net/wireless/mwifiex/usb.c b/trunk/drivers/net/wireless/mwifiex/usb.c index 22a5916564b8..49ebf20c56eb 100644 --- a/trunk/drivers/net/wireless/mwifiex/usb.c +++ b/trunk/drivers/net/wireless/mwifiex/usb.c @@ -49,7 +49,6 @@ static int mwifiex_usb_recv(struct mwifiex_adapter *adapter, struct device *dev = adapter->dev; u32 recv_type; __le32 tmp; - int ret; if (adapter->hs_activated) mwifiex_process_hs_config(adapter); @@ -70,19 +69,16 @@ static int mwifiex_usb_recv(struct mwifiex_adapter *adapter, case MWIFIEX_USB_TYPE_CMD: if (skb->len > MWIFIEX_SIZE_OF_CMD_BUFFER) { dev_err(dev, "CMD: skb->len too large\n"); - ret = -1; - goto exit_restore_skb; + return -1; } else if (!adapter->curr_cmd) { dev_dbg(dev, "CMD: no curr_cmd\n"); if (adapter->ps_state == PS_STATE_SLEEP_CFM) { mwifiex_process_sleep_confirm_resp( adapter, skb->data, skb->len); - ret = 0; - goto exit_restore_skb; + return 0; } - ret = -1; - goto exit_restore_skb; + return -1; } adapter->curr_cmd->resp_skb = skb; @@ -91,22 +87,20 @@ static int mwifiex_usb_recv(struct mwifiex_adapter *adapter, case MWIFIEX_USB_TYPE_EVENT: if (skb->len < sizeof(u32)) { dev_err(dev, "EVENT: skb->len too small\n"); - ret = -1; - goto exit_restore_skb; + return -1; } skb_copy_from_linear_data(skb, &tmp, sizeof(u32)); adapter->event_cause = le32_to_cpu(tmp); + skb_pull(skb, sizeof(u32)); dev_dbg(dev, "event_cause %#x\n", adapter->event_cause); if (skb->len > MAX_EVENT_SIZE) { dev_err(dev, "EVENT: event body too large\n"); - ret = -1; - goto exit_restore_skb; + return -1; } - memcpy(adapter->event_body, skb->data + - MWIFIEX_EVENT_HEADER_LEN, skb->len); - + skb_copy_from_linear_data(skb, adapter->event_body, + skb->len); adapter->event_received = true; adapter->event_skb = skb; break; @@ -130,12 +124,6 @@ static int mwifiex_usb_recv(struct mwifiex_adapter *adapter, } return -EINPROGRESS; - -exit_restore_skb: - /* The buffer will be reused for further cmds/events */ - skb_push(skb, INTF_HEADER_LEN); - - return ret; } static void mwifiex_usb_rx_complete(struct urb *urb) diff --git a/trunk/drivers/net/wireless/mwifiex/wmm.c b/trunk/drivers/net/wireless/mwifiex/wmm.c index 3fa4d4176993..f3fc65515857 100644 --- a/trunk/drivers/net/wireless/mwifiex/wmm.c +++ b/trunk/drivers/net/wireless/mwifiex/wmm.c @@ -404,8 +404,6 @@ mwifiex_wmm_init(struct mwifiex_adapter *adapter) priv->add_ba_param.tx_win_size = MWIFIEX_AMPDU_DEF_TXWINSIZE; priv->add_ba_param.rx_win_size = MWIFIEX_AMPDU_DEF_RXWINSIZE; - mwifiex_reset_11n_rx_seq_num(priv); - atomic_set(&priv->wmm.tx_pkts_queued, 0); atomic_set(&priv->wmm.highest_queued_prio, HIGH_PRIO_TID); } @@ -1223,7 +1221,6 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) if (!ptr->is_11n_enabled || mwifiex_is_ba_stream_setup(priv, ptr, tid) || - priv->wps.session_enable || ((priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled) && !priv->wpa_is_gtk_set)) { diff --git a/trunk/drivers/net/wireless/p54/txrx.c b/trunk/drivers/net/wireless/p54/txrx.c index f38786e02623..82a1cac920bd 100644 --- a/trunk/drivers/net/wireless/p54/txrx.c +++ b/trunk/drivers/net/wireless/p54/txrx.c @@ -422,11 +422,11 @@ static void p54_rx_frame_sent(struct p54_common *priv, struct sk_buff *skb) * Clear manually, ieee80211_tx_info_clear_status would * clear the counts too and we need them. */ - memset(&info->status.ack_signal, 0, + memset(&info->status.ampdu_ack_len, 0, sizeof(struct ieee80211_tx_info) - - offsetof(struct ieee80211_tx_info, status.ack_signal)); + offsetof(struct ieee80211_tx_info, status.ampdu_ack_len)); BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, - status.ack_signal) != 20); + status.ampdu_ack_len) != 23); if (entry_hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_ALIGN)) pad = entry_data->align[0]; diff --git a/trunk/drivers/net/wireless/rndis_wlan.c b/trunk/drivers/net/wireless/rndis_wlan.c index dfcd02ab6cae..2e9e6af21362 100644 --- a/trunk/drivers/net/wireless/rndis_wlan.c +++ b/trunk/drivers/net/wireless/rndis_wlan.c @@ -2110,7 +2110,7 @@ static int rndis_check_bssid_list(struct usbnet *usbdev, u8 *match_bssid, while (check_bssid_list_item(bssid, bssid_len, buf, len)) { if (rndis_bss_info_update(usbdev, bssid) && match_bssid && matched) { - if (ether_addr_equal(bssid->mac, match_bssid)) + if (!ether_addr_equal(bssid->mac, match_bssid)) *matched = true; } diff --git a/trunk/drivers/net/wireless/rt2x00/Kconfig b/trunk/drivers/net/wireless/rt2x00/Kconfig index c7548da6573d..299c3879582d 100644 --- a/trunk/drivers/net/wireless/rt2x00/Kconfig +++ b/trunk/drivers/net/wireless/rt2x00/Kconfig @@ -99,14 +99,6 @@ config RT2800PCI_RT53XX rt2800pci driver. Supported chips: RT5390 -config RT2800PCI_RT3290 - bool "rt2800pci - Include support for rt3290 devices (EXPERIMENTAL)" - depends on EXPERIMENTAL - default y - ---help--- - This adds support for rt3290 wireless chipset family to the - rt2800pci driver. - Supported chips: RT3290 endif config RT2500USB diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800.h b/trunk/drivers/net/wireless/rt2x00/rt2800.h index e252e9bafd0e..1ca88cdc6ece 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800.h +++ b/trunk/drivers/net/wireless/rt2x00/rt2800.h @@ -68,7 +68,6 @@ #define RF3320 0x000b #define RF3322 0x000c #define RF3053 0x000d -#define RF3290 0x3290 #define RF5360 0x5360 #define RF5370 0x5370 #define RF5372 0x5372 @@ -118,12 +117,6 @@ * Registers. */ - -/* - * MAC_CSR0_3290: MAC_CSR0 for RT3290 to identity MAC version number. - */ -#define MAC_CSR0_3290 0x0000 - /* * E2PROM_CSR: PCI EEPROM control register. * RELOAD: Write 1 to reload eeprom content. @@ -139,150 +132,6 @@ #define E2PROM_CSR_LOAD_STATUS FIELD32(0x00000040) #define E2PROM_CSR_RELOAD FIELD32(0x00000080) -/* - * CMB_CTRL_CFG - */ -#define CMB_CTRL 0x0020 -#define AUX_OPT_BIT0 FIELD32(0x00000001) -#define AUX_OPT_BIT1 FIELD32(0x00000002) -#define AUX_OPT_BIT2 FIELD32(0x00000004) -#define AUX_OPT_BIT3 FIELD32(0x00000008) -#define AUX_OPT_BIT4 FIELD32(0x00000010) -#define AUX_OPT_BIT5 FIELD32(0x00000020) -#define AUX_OPT_BIT6 FIELD32(0x00000040) -#define AUX_OPT_BIT7 FIELD32(0x00000080) -#define AUX_OPT_BIT8 FIELD32(0x00000100) -#define AUX_OPT_BIT9 FIELD32(0x00000200) -#define AUX_OPT_BIT10 FIELD32(0x00000400) -#define AUX_OPT_BIT11 FIELD32(0x00000800) -#define AUX_OPT_BIT12 FIELD32(0x00001000) -#define AUX_OPT_BIT13 FIELD32(0x00002000) -#define AUX_OPT_BIT14 FIELD32(0x00004000) -#define AUX_OPT_BIT15 FIELD32(0x00008000) -#define LDO25_LEVEL FIELD32(0x00030000) -#define LDO25_LARGEA FIELD32(0x00040000) -#define LDO25_FRC_ON FIELD32(0x00080000) -#define CMB_RSV FIELD32(0x00300000) -#define XTAL_RDY FIELD32(0x00400000) -#define PLL_LD FIELD32(0x00800000) -#define LDO_CORE_LEVEL FIELD32(0x0F000000) -#define LDO_BGSEL FIELD32(0x30000000) -#define LDO3_EN FIELD32(0x40000000) -#define LDO0_EN FIELD32(0x80000000) - -/* - * EFUSE_CSR_3290: RT3290 EEPROM - */ -#define EFUSE_CTRL_3290 0x0024 - -/* - * EFUSE_DATA3 of 3290 - */ -#define EFUSE_DATA3_3290 0x0028 - -/* - * EFUSE_DATA2 of 3290 - */ -#define EFUSE_DATA2_3290 0x002c - -/* - * EFUSE_DATA1 of 3290 - */ -#define EFUSE_DATA1_3290 0x0030 - -/* - * EFUSE_DATA0 of 3290 - */ -#define EFUSE_DATA0_3290 0x0034 - -/* - * OSC_CTRL_CFG - * Ring oscillator configuration - */ -#define OSC_CTRL 0x0038 -#define OSC_REF_CYCLE FIELD32(0x00001fff) -#define OSC_RSV FIELD32(0x0000e000) -#define OSC_CAL_CNT FIELD32(0x0fff0000) -#define OSC_CAL_ACK FIELD32(0x10000000) -#define OSC_CLK_32K_VLD FIELD32(0x20000000) -#define OSC_CAL_REQ FIELD32(0x40000000) -#define OSC_ROSC_EN FIELD32(0x80000000) - -/* - * COEX_CFG_0 - */ -#define COEX_CFG0 0x0040 -#define COEX_CFG_ANT FIELD32(0xff000000) -/* - * COEX_CFG_1 - */ -#define COEX_CFG1 0x0044 - -/* - * COEX_CFG_2 - */ -#define COEX_CFG2 0x0048 -#define BT_COEX_CFG1 FIELD32(0xff000000) -#define BT_COEX_CFG0 FIELD32(0x00ff0000) -#define WL_COEX_CFG1 FIELD32(0x0000ff00) -#define WL_COEX_CFG0 FIELD32(0x000000ff) -/* - * PLL_CTRL_CFG - * PLL configuration register - */ -#define PLL_CTRL 0x0050 -#define PLL_RESERVED_INPUT1 FIELD32(0x000000ff) -#define PLL_RESERVED_INPUT2 FIELD32(0x0000ff00) -#define PLL_CONTROL FIELD32(0x00070000) -#define PLL_LPF_R1 FIELD32(0x00080000) -#define PLL_LPF_C1_CTRL FIELD32(0x00300000) -#define PLL_LPF_C2_CTRL FIELD32(0x00c00000) -#define PLL_CP_CURRENT_CTRL FIELD32(0x03000000) -#define PLL_PFD_DELAY_CTRL FIELD32(0x0c000000) -#define PLL_LOCK_CTRL FIELD32(0x70000000) -#define PLL_VBGBK_EN FIELD32(0x80000000) - - -/* - * WLAN_CTRL_CFG - * RT3290 wlan configuration - */ -#define WLAN_FUN_CTRL 0x0080 -#define WLAN_EN FIELD32(0x00000001) -#define WLAN_CLK_EN FIELD32(0x00000002) -#define WLAN_RSV1 FIELD32(0x00000004) -#define WLAN_RESET FIELD32(0x00000008) -#define PCIE_APP0_CLK_REQ FIELD32(0x00000010) -#define FRC_WL_ANT_SET FIELD32(0x00000020) -#define INV_TR_SW0 FIELD32(0x00000040) -#define WLAN_GPIO_IN_BIT0 FIELD32(0x00000100) -#define WLAN_GPIO_IN_BIT1 FIELD32(0x00000200) -#define WLAN_GPIO_IN_BIT2 FIELD32(0x00000400) -#define WLAN_GPIO_IN_BIT3 FIELD32(0x00000800) -#define WLAN_GPIO_IN_BIT4 FIELD32(0x00001000) -#define WLAN_GPIO_IN_BIT5 FIELD32(0x00002000) -#define WLAN_GPIO_IN_BIT6 FIELD32(0x00004000) -#define WLAN_GPIO_IN_BIT7 FIELD32(0x00008000) -#define WLAN_GPIO_IN_BIT_ALL FIELD32(0x0000ff00) -#define WLAN_GPIO_OUT_BIT0 FIELD32(0x00010000) -#define WLAN_GPIO_OUT_BIT1 FIELD32(0x00020000) -#define WLAN_GPIO_OUT_BIT2 FIELD32(0x00040000) -#define WLAN_GPIO_OUT_BIT3 FIELD32(0x00050000) -#define WLAN_GPIO_OUT_BIT4 FIELD32(0x00100000) -#define WLAN_GPIO_OUT_BIT5 FIELD32(0x00200000) -#define WLAN_GPIO_OUT_BIT6 FIELD32(0x00400000) -#define WLAN_GPIO_OUT_BIT7 FIELD32(0x00800000) -#define WLAN_GPIO_OUT_BIT_ALL FIELD32(0x00ff0000) -#define WLAN_GPIO_OUT_OE_BIT0 FIELD32(0x01000000) -#define WLAN_GPIO_OUT_OE_BIT1 FIELD32(0x02000000) -#define WLAN_GPIO_OUT_OE_BIT2 FIELD32(0x04000000) -#define WLAN_GPIO_OUT_OE_BIT3 FIELD32(0x08000000) -#define WLAN_GPIO_OUT_OE_BIT4 FIELD32(0x10000000) -#define WLAN_GPIO_OUT_OE_BIT5 FIELD32(0x20000000) -#define WLAN_GPIO_OUT_OE_BIT6 FIELD32(0x40000000) -#define WLAN_GPIO_OUT_OE_BIT7 FIELD32(0x80000000) -#define WLAN_GPIO_OUT_OE_BIT_ALL FIELD32(0xff000000) - /* * AUX_CTRL: Aux/PCI-E related configuration */ @@ -1914,11 +1763,9 @@ struct mac_iveiv_entry { /* * BBP 3: RX Antenna */ -#define BBP3_RX_ADC FIELD8(0x03) +#define BBP3_RX_ADC FIELD8(0x03) #define BBP3_RX_ANTENNA FIELD8(0x18) #define BBP3_HT40_MINUS FIELD8(0x20) -#define BBP3_ADC_MODE_SWITCH FIELD8(0x40) -#define BBP3_ADC_INIT_MODE FIELD8(0x80) /* * BBP 4: Bandwidth @@ -1927,14 +1774,6 @@ struct mac_iveiv_entry { #define BBP4_BANDWIDTH FIELD8(0x18) #define BBP4_MAC_IF_CTRL FIELD8(0x40) -/* - * BBP 47: Bandwidth - */ -#define BBP47_TSSI_REPORT_SEL FIELD8(0x03) -#define BBP47_TSSI_UPDATE_REQ FIELD8(0x04) -#define BBP47_TSSI_TSSI_MODE FIELD8(0x18) -#define BBP47_TSSI_ADC6 FIELD8(0x80) - /* * BBP 109 */ @@ -2077,16 +1916,6 @@ struct mac_iveiv_entry { #define RFCSR27_R3 FIELD8(0x30) #define RFCSR27_R4 FIELD8(0x40) -/* - * RFCSR 29: - */ -#define RFCSR29_ADC6_TEST FIELD8(0x01) -#define RFCSR29_ADC6_INT_TEST FIELD8(0x02) -#define RFCSR29_RSSI_RESET FIELD8(0x04) -#define RFCSR29_RSSI_ON FIELD8(0x08) -#define RFCSR29_RSSI_RIP_CTRL FIELD8(0x30) -#define RFCSR29_RSSI_GAIN FIELD8(0xc0) - /* * RFCSR 30: */ diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800lib.c b/trunk/drivers/net/wireless/rt2x00/rt2800lib.c index 068276ee8aff..4d3747c3010b 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2800lib.c @@ -354,15 +354,16 @@ int rt2800_check_firmware(struct rt2x00_dev *rt2x00dev, * of 4kb. Certain USB chipsets however require different firmware, * which Ralink only provides attached to the original firmware * file. Thus for USB devices, firmware files have a length - * which is a multiple of 4kb. The firmware for rt3290 chip also - * have a length which is a multiple of 4kb. + * which is a multiple of 4kb. */ - if (rt2x00_is_usb(rt2x00dev) || rt2x00_rt(rt2x00dev, RT3290)) + if (rt2x00_is_usb(rt2x00dev)) { fw_len = 4096; - else + multiple = true; + } else { fw_len = 8192; + multiple = true; + } - multiple = true; /* * Validate the firmware length */ @@ -414,8 +415,7 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, return -EBUSY; if (rt2x00_is_pci(rt2x00dev)) { - if (rt2x00_rt(rt2x00dev, RT3290) || - rt2x00_rt(rt2x00dev, RT3572) || + if (rt2x00_rt(rt2x00dev, RT3572) || rt2x00_rt(rt2x00dev, RT5390) || rt2x00_rt(rt2x00dev, RT5392)) { rt2800_register_read(rt2x00dev, AUX_CTRL, ®); @@ -851,13 +851,8 @@ int rt2800_rfkill_poll(struct rt2x00_dev *rt2x00dev) { u32 reg; - if (rt2x00_rt(rt2x00dev, RT3290)) { - rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, ®); - return rt2x00_get_field32(reg, WLAN_GPIO_IN_BIT0); - } else { - rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); - return rt2x00_get_field32(reg, GPIO_CTRL_CFG_BIT2); - } + rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); + return rt2x00_get_field32(reg, GPIO_CTRL_CFG_BIT2); } EXPORT_SYMBOL_GPL(rt2800_rfkill_poll); @@ -1940,54 +1935,9 @@ static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev, rt2800_rfcsr_write(rt2x00dev, 7, rfcsr); } -#define RT3290_POWER_BOUND 0x27 -#define RT3290_FREQ_OFFSET_BOUND 0x5f #define RT5390_POWER_BOUND 0x27 #define RT5390_FREQ_OFFSET_BOUND 0x5f -static void rt2800_config_channel_rf3290(struct rt2x00_dev *rt2x00dev, - struct ieee80211_conf *conf, - struct rf_channel *rf, - struct channel_info *info) -{ - u8 rfcsr; - - rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1); - rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3); - rt2800_rfcsr_read(rt2x00dev, 11, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR11_R, rf->rf2); - rt2800_rfcsr_write(rt2x00dev, 11, rfcsr); - - rt2800_rfcsr_read(rt2x00dev, 49, &rfcsr); - if (info->default_power1 > RT3290_POWER_BOUND) - rt2x00_set_field8(&rfcsr, RFCSR49_TX, RT3290_POWER_BOUND); - else - rt2x00_set_field8(&rfcsr, RFCSR49_TX, info->default_power1); - rt2800_rfcsr_write(rt2x00dev, 49, rfcsr); - - rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); - if (rt2x00dev->freq_offset > RT3290_FREQ_OFFSET_BOUND) - rt2x00_set_field8(&rfcsr, RFCSR17_CODE, - RT3290_FREQ_OFFSET_BOUND); - else - rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset); - rt2800_rfcsr_write(rt2x00dev, 17, rfcsr); - - if (rf->channel <= 14) { - if (rf->channel == 6) - rt2800_bbp_write(rt2x00dev, 68, 0x0c); - else - rt2800_bbp_write(rt2x00dev, 68, 0x0b); - - if (rf->channel >= 1 && rf->channel <= 6) - rt2800_bbp_write(rt2x00dev, 59, 0x0f); - else if (rf->channel >= 7 && rf->channel <= 11) - rt2800_bbp_write(rt2x00dev, 59, 0x0e); - else if (rf->channel >= 12 && rf->channel <= 14) - rt2800_bbp_write(rt2x00dev, 59, 0x0d); - } -} - static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev, struct ieee80211_conf *conf, struct rf_channel *rf, @@ -2086,6 +2036,15 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev, } } } + + rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR30_TX_H20M, 0); + rt2x00_set_field8(&rfcsr, RFCSR30_RX_H20M, 0); + rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); + + rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); + rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); + rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); } static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, @@ -2095,7 +2054,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, { u32 reg; unsigned int tx_pin; - u8 bbp, rfcsr; + u8 bbp; if (rf->channel <= 14) { info->default_power1 = TXPOWER_G_TO_DEV(info->default_power1); @@ -2116,9 +2075,6 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, case RF3052: rt2800_config_channel_rf3052(rt2x00dev, conf, rf, info); break; - case RF3290: - rt2800_config_channel_rf3290(rt2x00dev, conf, rf, info); - break; case RF5360: case RF5370: case RF5372: @@ -2130,22 +2086,6 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info); } - if (rt2x00_rf(rt2x00dev, RF3290) || - rt2x00_rf(rt2x00dev, RF5360) || - rt2x00_rf(rt2x00dev, RF5370) || - rt2x00_rf(rt2x00dev, RF5372) || - rt2x00_rf(rt2x00dev, RF5390) || - rt2x00_rf(rt2x00dev, RF5392)) { - rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR30_TX_H20M, 0); - rt2x00_set_field8(&rfcsr, RFCSR30_RX_H20M, 0); - rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); - - rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); - rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); - } - /* * Change BBP settings */ @@ -2626,7 +2566,6 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev) rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1); rt2800_rfcsr_write(rt2x00dev, 7, rfcsr); break; - case RF3290: case RF5360: case RF5370: case RF5372: @@ -2762,7 +2701,6 @@ static u8 rt2800_get_default_vgc(struct rt2x00_dev *rt2x00dev) if (rt2x00_rt(rt2x00dev, RT3070) || rt2x00_rt(rt2x00dev, RT3071) || rt2x00_rt(rt2x00dev, RT3090) || - rt2x00_rt(rt2x00dev, RT3290) || rt2x00_rt(rt2x00dev, RT3390) || rt2x00_rt(rt2x00dev, RT5390) || rt2x00_rt(rt2x00dev, RT5392)) @@ -2859,54 +2797,10 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, BKOFF_SLOT_CFG_CC_DELAY_TIME, 2); rt2800_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg); - if (rt2x00_rt(rt2x00dev, RT3290)) { - rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, ®); - if (rt2x00_get_field32(reg, WLAN_EN) == 1) { - rt2x00_set_field32(®, PCIE_APP0_CLK_REQ, 1); - rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg); - } - - rt2800_register_read(rt2x00dev, CMB_CTRL, ®); - if (!(rt2x00_get_field32(reg, LDO0_EN) == 1)) { - rt2x00_set_field32(®, LDO0_EN, 1); - rt2x00_set_field32(®, LDO_BGSEL, 3); - rt2800_register_write(rt2x00dev, CMB_CTRL, reg); - } - - rt2800_register_read(rt2x00dev, OSC_CTRL, ®); - rt2x00_set_field32(®, OSC_ROSC_EN, 1); - rt2x00_set_field32(®, OSC_CAL_REQ, 1); - rt2x00_set_field32(®, OSC_REF_CYCLE, 0x27); - rt2800_register_write(rt2x00dev, OSC_CTRL, reg); - - rt2800_register_read(rt2x00dev, COEX_CFG0, ®); - rt2x00_set_field32(®, COEX_CFG_ANT, 0x5e); - rt2800_register_write(rt2x00dev, COEX_CFG0, reg); - - rt2800_register_read(rt2x00dev, COEX_CFG2, ®); - rt2x00_set_field32(®, BT_COEX_CFG1, 0x00); - rt2x00_set_field32(®, BT_COEX_CFG0, 0x17); - rt2x00_set_field32(®, WL_COEX_CFG1, 0x93); - rt2x00_set_field32(®, WL_COEX_CFG0, 0x7f); - rt2800_register_write(rt2x00dev, COEX_CFG2, reg); - - rt2800_register_read(rt2x00dev, PLL_CTRL, ®); - rt2x00_set_field32(®, PLL_CONTROL, 1); - rt2800_register_write(rt2x00dev, PLL_CTRL, reg); - } - if (rt2x00_rt(rt2x00dev, RT3071) || rt2x00_rt(rt2x00dev, RT3090) || - rt2x00_rt(rt2x00dev, RT3290) || rt2x00_rt(rt2x00dev, RT3390)) { - - if (rt2x00_rt(rt2x00dev, RT3290)) - rt2800_register_write(rt2x00dev, TX_SW_CFG0, - 0x00000404); - else - rt2800_register_write(rt2x00dev, TX_SW_CFG0, - 0x00000400); - + rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000); if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || @@ -3315,16 +3209,14 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2800_wait_bbp_ready(rt2x00dev))) return -EACCES; - if (rt2x00_rt(rt2x00dev, RT3290) || - rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) { + if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) { rt2800_bbp_read(rt2x00dev, 4, &value); rt2x00_set_field8(&value, BBP4_MAC_IF_CTRL, 1); rt2800_bbp_write(rt2x00dev, 4, value); } if (rt2800_is_305x_soc(rt2x00dev) || - rt2x00_rt(rt2x00dev, RT3290) || rt2x00_rt(rt2x00dev, RT3572) || rt2x00_rt(rt2x00dev, RT5390) || rt2x00_rt(rt2x00dev, RT5392)) @@ -3333,26 +3225,20 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2800_bbp_write(rt2x00dev, 65, 0x2c); rt2800_bbp_write(rt2x00dev, 66, 0x38); - if (rt2x00_rt(rt2x00dev, RT3290) || - rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) + if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 68, 0x0b); if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860C)) { rt2800_bbp_write(rt2x00dev, 69, 0x16); rt2800_bbp_write(rt2x00dev, 73, 0x12); - } else if (rt2x00_rt(rt2x00dev, RT3290) || - rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) { + } else if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) { rt2800_bbp_write(rt2x00dev, 69, 0x12); rt2800_bbp_write(rt2x00dev, 73, 0x13); rt2800_bbp_write(rt2x00dev, 75, 0x46); rt2800_bbp_write(rt2x00dev, 76, 0x28); - - if (rt2x00_rt(rt2x00dev, RT3290)) - rt2800_bbp_write(rt2x00dev, 77, 0x58); - else - rt2800_bbp_write(rt2x00dev, 77, 0x59); + rt2800_bbp_write(rt2x00dev, 77, 0x59); } else { rt2800_bbp_write(rt2x00dev, 69, 0x12); rt2800_bbp_write(rt2x00dev, 73, 0x10); @@ -3377,33 +3263,23 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2800_bbp_write(rt2x00dev, 81, 0x37); } - if (rt2x00_rt(rt2x00dev, RT3290)) { - rt2800_bbp_write(rt2x00dev, 74, 0x0b); - rt2800_bbp_write(rt2x00dev, 79, 0x18); - rt2800_bbp_write(rt2x00dev, 80, 0x09); - rt2800_bbp_write(rt2x00dev, 81, 0x33); - } - rt2800_bbp_write(rt2x00dev, 82, 0x62); - if (rt2x00_rt(rt2x00dev, RT3290) || - rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) + if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 83, 0x7a); else rt2800_bbp_write(rt2x00dev, 83, 0x6a); 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)) + else if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 84, 0x9a); else rt2800_bbp_write(rt2x00dev, 84, 0x99); - if (rt2x00_rt(rt2x00dev, RT3290) || - rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) + if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 86, 0x38); else rt2800_bbp_write(rt2x00dev, 86, 0x00); @@ -3413,9 +3289,8 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2800_bbp_write(rt2x00dev, 91, 0x04); - if (rt2x00_rt(rt2x00dev, RT3290) || - rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) + if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 92, 0x02); else rt2800_bbp_write(rt2x00dev, 92, 0x00); @@ -3429,7 +3304,6 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) || rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) || rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) || - rt2x00_rt(rt2x00dev, RT3290) || rt2x00_rt(rt2x00dev, RT3572) || rt2x00_rt(rt2x00dev, RT5390) || rt2x00_rt(rt2x00dev, RT5392) || @@ -3438,32 +3312,27 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) else rt2800_bbp_write(rt2x00dev, 103, 0x00); - if (rt2x00_rt(rt2x00dev, RT3290) || - rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) + if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 104, 0x92); if (rt2800_is_305x_soc(rt2x00dev)) rt2800_bbp_write(rt2x00dev, 105, 0x01); - else if (rt2x00_rt(rt2x00dev, RT3290)) - rt2800_bbp_write(rt2x00dev, 105, 0x1c); else if (rt2x00_rt(rt2x00dev, RT5390) || rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 105, 0x3c); else rt2800_bbp_write(rt2x00dev, 105, 0x05); - if (rt2x00_rt(rt2x00dev, RT3290) || - rt2x00_rt(rt2x00dev, RT5390)) + if (rt2x00_rt(rt2x00dev, RT5390)) rt2800_bbp_write(rt2x00dev, 106, 0x03); else if (rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 106, 0x12); else rt2800_bbp_write(rt2x00dev, 106, 0x35); - if (rt2x00_rt(rt2x00dev, RT3290) || - rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) + if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) rt2800_bbp_write(rt2x00dev, 128, 0x12); if (rt2x00_rt(rt2x00dev, RT5392)) { @@ -3488,29 +3357,6 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2800_bbp_write(rt2x00dev, 138, value); } - if (rt2x00_rt(rt2x00dev, RT3290)) { - rt2800_bbp_write(rt2x00dev, 67, 0x24); - rt2800_bbp_write(rt2x00dev, 143, 0x04); - rt2800_bbp_write(rt2x00dev, 142, 0x99); - rt2800_bbp_write(rt2x00dev, 150, 0x30); - rt2800_bbp_write(rt2x00dev, 151, 0x2e); - rt2800_bbp_write(rt2x00dev, 152, 0x20); - rt2800_bbp_write(rt2x00dev, 153, 0x34); - rt2800_bbp_write(rt2x00dev, 154, 0x40); - rt2800_bbp_write(rt2x00dev, 155, 0x3b); - rt2800_bbp_write(rt2x00dev, 253, 0x04); - - rt2800_bbp_read(rt2x00dev, 47, &value); - rt2x00_set_field8(&value, BBP47_TSSI_ADC6, 1); - rt2800_bbp_write(rt2x00dev, 47, value); - - /* Use 5-bit ADC for Acquisition and 8-bit ADC for data */ - rt2800_bbp_read(rt2x00dev, 3, &value); - rt2x00_set_field8(&value, BBP3_ADC_MODE_SWITCH, 1); - rt2x00_set_field8(&value, BBP3_ADC_INIT_MODE, 1); - rt2800_bbp_write(rt2x00dev, 3, value); - } - if (rt2x00_rt(rt2x00dev, RT5390) || rt2x00_rt(rt2x00dev, RT5392)) { int ant, div_mode; @@ -3643,7 +3489,6 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) if (!rt2x00_rt(rt2x00dev, RT3070) && !rt2x00_rt(rt2x00dev, RT3071) && !rt2x00_rt(rt2x00dev, RT3090) && - !rt2x00_rt(rt2x00dev, RT3290) && !rt2x00_rt(rt2x00dev, RT3390) && !rt2x00_rt(rt2x00dev, RT3572) && !rt2x00_rt(rt2x00dev, RT5390) && @@ -3654,9 +3499,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) /* * Init RF calibration. */ - if (rt2x00_rt(rt2x00dev, RT3290) || - rt2x00_rt(rt2x00dev, RT5390) || - rt2x00_rt(rt2x00dev, RT5392)) { + if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392)) { rt2800_rfcsr_read(rt2x00dev, 2, &rfcsr); rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1); rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); @@ -3694,53 +3538,6 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 24, 0x16); rt2800_rfcsr_write(rt2x00dev, 25, 0x01); rt2800_rfcsr_write(rt2x00dev, 29, 0x1f); - } else if (rt2x00_rt(rt2x00dev, RT3290)) { - rt2800_rfcsr_write(rt2x00dev, 1, 0x0f); - rt2800_rfcsr_write(rt2x00dev, 2, 0x80); - rt2800_rfcsr_write(rt2x00dev, 3, 0x08); - rt2800_rfcsr_write(rt2x00dev, 4, 0x00); - rt2800_rfcsr_write(rt2x00dev, 6, 0xa0); - rt2800_rfcsr_write(rt2x00dev, 8, 0xf3); - rt2800_rfcsr_write(rt2x00dev, 9, 0x02); - 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, 18, 0x02); - rt2800_rfcsr_write(rt2x00dev, 22, 0x20); - rt2800_rfcsr_write(rt2x00dev, 25, 0x83); - rt2800_rfcsr_write(rt2x00dev, 26, 0x82); - rt2800_rfcsr_write(rt2x00dev, 27, 0x09); - rt2800_rfcsr_write(rt2x00dev, 29, 0x10); - rt2800_rfcsr_write(rt2x00dev, 30, 0x10); - rt2800_rfcsr_write(rt2x00dev, 31, 0x80); - rt2800_rfcsr_write(rt2x00dev, 32, 0x80); - rt2800_rfcsr_write(rt2x00dev, 33, 0x00); - rt2800_rfcsr_write(rt2x00dev, 34, 0x05); - rt2800_rfcsr_write(rt2x00dev, 35, 0x12); - rt2800_rfcsr_write(rt2x00dev, 36, 0x00); - rt2800_rfcsr_write(rt2x00dev, 38, 0x85); - rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); - rt2800_rfcsr_write(rt2x00dev, 40, 0x0b); - rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); - rt2800_rfcsr_write(rt2x00dev, 42, 0xd5); - rt2800_rfcsr_write(rt2x00dev, 43, 0x7b); - rt2800_rfcsr_write(rt2x00dev, 44, 0x0e); - rt2800_rfcsr_write(rt2x00dev, 45, 0xa2); - rt2800_rfcsr_write(rt2x00dev, 46, 0x73); - rt2800_rfcsr_write(rt2x00dev, 47, 0x00); - rt2800_rfcsr_write(rt2x00dev, 48, 0x10); - rt2800_rfcsr_write(rt2x00dev, 49, 0x98); - rt2800_rfcsr_write(rt2x00dev, 52, 0x38); - rt2800_rfcsr_write(rt2x00dev, 53, 0x00); - rt2800_rfcsr_write(rt2x00dev, 54, 0x78); - rt2800_rfcsr_write(rt2x00dev, 55, 0x43); - rt2800_rfcsr_write(rt2x00dev, 56, 0x02); - rt2800_rfcsr_write(rt2x00dev, 57, 0x80); - rt2800_rfcsr_write(rt2x00dev, 58, 0x7f); - rt2800_rfcsr_write(rt2x00dev, 59, 0x09); - rt2800_rfcsr_write(rt2x00dev, 60, 0x45); - rt2800_rfcsr_write(rt2x00dev, 61, 0xc1); } else if (rt2x00_rt(rt2x00dev, RT3390)) { rt2800_rfcsr_write(rt2x00dev, 0, 0xa0); rt2800_rfcsr_write(rt2x00dev, 1, 0xe1); @@ -4149,12 +3946,6 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 27, rfcsr); } - if (rt2x00_rt(rt2x00dev, RT3290)) { - rt2800_rfcsr_read(rt2x00dev, 29, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR29_RSSI_GAIN, 3); - rt2800_rfcsr_write(rt2x00dev, 29, rfcsr); - } - if (rt2x00_rt(rt2x00dev, RT5390) || rt2x00_rt(rt2x00dev, RT5392)) { rt2800_rfcsr_read(rt2x00dev, 38, &rfcsr); @@ -4261,14 +4052,9 @@ EXPORT_SYMBOL_GPL(rt2800_disable_radio); int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev) { u32 reg; - u16 efuse_ctrl_reg; - if (rt2x00_rt(rt2x00dev, RT3290)) - efuse_ctrl_reg = EFUSE_CTRL_3290; - else - efuse_ctrl_reg = EFUSE_CTRL; + rt2800_register_read(rt2x00dev, EFUSE_CTRL, ®); - rt2800_register_read(rt2x00dev, efuse_ctrl_reg, ®); return rt2x00_get_field32(reg, EFUSE_CTRL_PRESENT); } EXPORT_SYMBOL_GPL(rt2800_efuse_detect); @@ -4276,44 +4062,27 @@ EXPORT_SYMBOL_GPL(rt2800_efuse_detect); static void rt2800_efuse_read(struct rt2x00_dev *rt2x00dev, unsigned int i) { u32 reg; - u16 efuse_ctrl_reg; - u16 efuse_data0_reg; - u16 efuse_data1_reg; - u16 efuse_data2_reg; - u16 efuse_data3_reg; - - if (rt2x00_rt(rt2x00dev, RT3290)) { - efuse_ctrl_reg = EFUSE_CTRL_3290; - efuse_data0_reg = EFUSE_DATA0_3290; - efuse_data1_reg = EFUSE_DATA1_3290; - efuse_data2_reg = EFUSE_DATA2_3290; - efuse_data3_reg = EFUSE_DATA3_3290; - } else { - efuse_ctrl_reg = EFUSE_CTRL; - efuse_data0_reg = EFUSE_DATA0; - efuse_data1_reg = EFUSE_DATA1; - efuse_data2_reg = EFUSE_DATA2; - efuse_data3_reg = EFUSE_DATA3; - } + mutex_lock(&rt2x00dev->csr_mutex); - rt2800_register_read_lock(rt2x00dev, efuse_ctrl_reg, ®); + rt2800_register_read_lock(rt2x00dev, EFUSE_CTRL, ®); rt2x00_set_field32(®, EFUSE_CTRL_ADDRESS_IN, i); rt2x00_set_field32(®, EFUSE_CTRL_MODE, 0); rt2x00_set_field32(®, EFUSE_CTRL_KICK, 1); - rt2800_register_write_lock(rt2x00dev, efuse_ctrl_reg, reg); + rt2800_register_write_lock(rt2x00dev, EFUSE_CTRL, reg); /* Wait until the EEPROM has been loaded */ - rt2800_regbusy_read(rt2x00dev, efuse_ctrl_reg, EFUSE_CTRL_KICK, ®); + rt2800_regbusy_read(rt2x00dev, EFUSE_CTRL, EFUSE_CTRL_KICK, ®); + /* Apparently the data is read from end to start */ - rt2800_register_read_lock(rt2x00dev, efuse_data3_reg, ®); + rt2800_register_read_lock(rt2x00dev, EFUSE_DATA3, ®); /* The returned value is in CPU order, but eeprom is le */ *(u32 *)&rt2x00dev->eeprom[i] = cpu_to_le32(reg); - rt2800_register_read_lock(rt2x00dev, efuse_data2_reg, ®); + rt2800_register_read_lock(rt2x00dev, EFUSE_DATA2, ®); *(u32 *)&rt2x00dev->eeprom[i + 2] = cpu_to_le32(reg); - rt2800_register_read_lock(rt2x00dev, efuse_data1_reg, ®); + rt2800_register_read_lock(rt2x00dev, EFUSE_DATA1, ®); *(u32 *)&rt2x00dev->eeprom[i + 4] = cpu_to_le32(reg); - rt2800_register_read_lock(rt2x00dev, efuse_data0_reg, ®); + rt2800_register_read_lock(rt2x00dev, EFUSE_DATA0, ®); *(u32 *)&rt2x00dev->eeprom[i + 6] = cpu_to_le32(reg); mutex_unlock(&rt2x00dev->csr_mutex); @@ -4475,14 +4244,9 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) * RT28xx/RT30xx: defined in "EEPROM_NIC_CONF0_RF_TYPE" field * RT53xx: defined in "EEPROM_CHIP_ID" field */ - if (rt2x00_rt(rt2x00dev, RT3290)) - rt2800_register_read(rt2x00dev, MAC_CSR0_3290, ®); - else - rt2800_register_read(rt2x00dev, MAC_CSR0, ®); - - if (rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT3290 || - rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5390 || - rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5392) + rt2800_register_read(rt2x00dev, MAC_CSR0, ®); + if (rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5390 || + rt2x00_get_field32(reg, MAC_CSR0_CHIPSET) == RT5392) rt2x00_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &value); else value = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE); @@ -4497,7 +4261,6 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) case RT3070: case RT3071: case RT3090: - case RT3290: case RT3390: case RT3572: case RT5390: @@ -4518,7 +4281,6 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) case RF3021: case RF3022: case RF3052: - case RF3290: case RF3320: case RF5360: case RF5370: @@ -4835,7 +4597,6 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) rt2x00_rf(rt2x00dev, RF2020) || rt2x00_rf(rt2x00dev, RF3021) || rt2x00_rf(rt2x00dev, RF3022) || - rt2x00_rf(rt2x00dev, RF3290) || rt2x00_rf(rt2x00dev, RF3320) || rt2x00_rf(rt2x00dev, RF5360) || rt2x00_rf(rt2x00dev, RF5370) || @@ -4924,7 +4685,6 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) case RF3022: case RF3320: case RF3052: - case RF3290: case RF5360: case RF5370: case RF5372: diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800pci.c b/trunk/drivers/net/wireless/rt2x00/rt2800pci.c index dd436125fe3d..206158b67426 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2800pci.c @@ -280,13 +280,7 @@ static void rt2800pci_stop_queue(struct data_queue *queue) */ static char *rt2800pci_get_firmware_name(struct rt2x00_dev *rt2x00dev) { - /* - * Chip rt3290 use specific 4KB firmware named rt3290.bin. - */ - if (rt2x00_rt(rt2x00dev, RT3290)) - return FIRMWARE_RT3290; - else - return FIRMWARE_RT2860; + return FIRMWARE_RT2860; } static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev, @@ -980,66 +974,6 @@ static int rt2800pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) return rt2800_validate_eeprom(rt2x00dev); } -static int rt2800_enable_wlan_rt3290(struct rt2x00_dev *rt2x00dev) -{ - u32 reg; - int i, count; - - rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, ®); - if ((rt2x00_get_field32(reg, WLAN_EN) == 1)) - return 0; - - rt2x00_set_field32(®, WLAN_GPIO_OUT_OE_BIT_ALL, 0xff); - rt2x00_set_field32(®, FRC_WL_ANT_SET, 1); - rt2x00_set_field32(®, WLAN_CLK_EN, 0); - rt2x00_set_field32(®, WLAN_EN, 1); - rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg); - - udelay(REGISTER_BUSY_DELAY); - - count = 0; - do { - /* - * Check PLL_LD & XTAL_RDY. - */ - for (i = 0; i < REGISTER_BUSY_COUNT; i++) { - rt2800_register_read(rt2x00dev, CMB_CTRL, ®); - if ((rt2x00_get_field32(reg, PLL_LD) == 1) && - (rt2x00_get_field32(reg, XTAL_RDY) == 1)) - break; - udelay(REGISTER_BUSY_DELAY); - } - - if (i >= REGISTER_BUSY_COUNT) { - - if (count >= 10) - return -EIO; - - rt2800_register_write(rt2x00dev, 0x58, 0x018); - udelay(REGISTER_BUSY_DELAY); - rt2800_register_write(rt2x00dev, 0x58, 0x418); - udelay(REGISTER_BUSY_DELAY); - rt2800_register_write(rt2x00dev, 0x58, 0x618); - udelay(REGISTER_BUSY_DELAY); - count++; - } else { - count = 0; - } - - rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, ®); - rt2x00_set_field32(®, PCIE_APP0_CLK_REQ, 0); - rt2x00_set_field32(®, WLAN_CLK_EN, 1); - rt2x00_set_field32(®, WLAN_RESET, 1); - rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg); - udelay(10); - rt2x00_set_field32(®, WLAN_RESET, 0); - rt2800_register_write(rt2x00dev, WLAN_FUN_CTRL, reg); - udelay(10); - rt2800_register_write(rt2x00dev, INT_SOURCE_CSR, 0x7fffffff); - } while (count != 0); - - return 0; -} static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) { int retval; @@ -1062,17 +996,6 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) if (retval) return retval; - /* - * In probe phase call rt2800_enable_wlan_rt3290 to enable wlan - * clk for rt3290. That avoid the MCU fail in start phase. - */ - if (rt2x00_rt(rt2x00dev, RT3290)) { - retval = rt2800_enable_wlan_rt3290(rt2x00dev); - - if (retval) - return retval; - } - /* * This device has multiple filters for control frames * and has a separate filter for PS Poll frames. @@ -1252,9 +1175,6 @@ static DEFINE_PCI_DEVICE_TABLE(rt2800pci_device_table) = { { PCI_DEVICE(0x1432, 0x7768) }, { PCI_DEVICE(0x1462, 0x891a) }, { PCI_DEVICE(0x1a3b, 0x1059) }, -#ifdef CONFIG_RT2800PCI_RT3290 - { PCI_DEVICE(0x1814, 0x3290) }, -#endif #ifdef CONFIG_RT2800PCI_RT33XX { PCI_DEVICE(0x1814, 0x3390) }, #endif diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800pci.h b/trunk/drivers/net/wireless/rt2x00/rt2800pci.h index ab22a087c50d..70e050d904c8 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800pci.h +++ b/trunk/drivers/net/wireless/rt2x00/rt2800pci.h @@ -47,7 +47,6 @@ * 8051 firmware image. */ #define FIRMWARE_RT2860 "rt2860.bin" -#define FIRMWARE_RT3290 "rt3290.bin" #define FIRMWARE_IMAGE_BASE 0x2000 /* diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800usb.c b/trunk/drivers/net/wireless/rt2x00/rt2800usb.c index 6cf336595e25..20a504072895 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2800usb.c @@ -971,7 +971,6 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x0411, 0x015d) }, { USB_DEVICE(0x0411, 0x016f) }, { USB_DEVICE(0x0411, 0x01a2) }, - { USB_DEVICE(0x0411, 0x01ee) }, /* Corega */ { USB_DEVICE(0x07aa, 0x002f) }, { USB_DEVICE(0x07aa, 0x003c) }, diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00.h b/trunk/drivers/net/wireless/rt2x00/rt2x00.h index 8afb546c2b2d..8f754025b06e 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00.h +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00.h @@ -187,7 +187,6 @@ struct rt2x00_chip { #define RT3070 0x3070 #define RT3071 0x3071 #define RT3090 0x3090 /* 2.4GHz PCIe */ -#define RT3290 0x3290 #define RT3390 0x3390 #define RT3572 0x3572 #define RT3593 0x3593 diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00pci.c b/trunk/drivers/net/wireless/rt2x00/rt2x00pci.c index a0c8caef3b0a..0a4653a92cab 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -256,7 +256,6 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops) struct ieee80211_hw *hw; struct rt2x00_dev *rt2x00dev; int retval; - u16 chip; retval = pci_enable_device(pci_dev); if (retval) { @@ -306,14 +305,6 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops) if (retval) goto exit_free_device; - /* - * Because rt3290 chip use different efuse offset to read efuse data. - * So before read efuse it need to indicate it is the - * rt3290 or not. - */ - pci_read_config_word(pci_dev, PCI_DEVICE_ID, &chip); - rt2x00dev->chip.rt = chip; - retval = rt2x00lib_probe_dev(rt2x00dev); if (retval) goto exit_free_reg; diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00usb.c b/trunk/drivers/net/wireless/rt2x00/rt2x00usb.c index 74ecc33fdd90..d357d1ed92f6 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -436,8 +436,8 @@ void rt2x00usb_kick_queue(struct data_queue *queue) case QID_RX: if (!rt2x00queue_full(queue)) rt2x00queue_for_each_entry(queue, - Q_INDEX, Q_INDEX_DONE, + Q_INDEX, NULL, rt2x00usb_kick_rx_entry); break; diff --git a/trunk/drivers/net/wireless/rtl818x/rtl8180/dev.c b/trunk/drivers/net/wireless/rtl818x/rtl8180/dev.c index 3b505395d869..2bebcb71a1e9 100644 --- a/trunk/drivers/net/wireless/rtl818x/rtl8180/dev.c +++ b/trunk/drivers/net/wireless/rtl818x/rtl8180/dev.c @@ -47,8 +47,6 @@ static DEFINE_PCI_DEVICE_TABLE(rtl8180_table) = { { PCI_DEVICE(0x1799, 0x6001) }, { PCI_DEVICE(0x1799, 0x6020) }, { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x3300) }, - { PCI_DEVICE(0x1186, 0x3301) }, - { PCI_DEVICE(0x1432, 0x7106) }, { } }; diff --git a/trunk/drivers/net/wireless/rtlwifi/cam.c b/trunk/drivers/net/wireless/rtlwifi/cam.c index 6a2d72beb00d..3d8cc4a0c86d 100644 --- a/trunk/drivers/net/wireless/rtlwifi/cam.c +++ b/trunk/drivers/net/wireless/rtlwifi/cam.c @@ -128,7 +128,7 @@ u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, u32 us_config; struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, ulUseDK=%x MacAddr %pM\n", ul_entry_idx, ul_key_id, ul_enc_alg, ul_default_key, mac_addr); @@ -342,8 +342,7 @@ void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr) /* Remove from HW Security CAM */ 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); + pr_info("&&&&&&&&&del entry %d\n", i); } } return; diff --git a/trunk/drivers/net/wireless/rtlwifi/pci.c b/trunk/drivers/net/wireless/rtlwifi/pci.c index 36bffbc4519e..2062ea1d7c80 100644 --- a/trunk/drivers/net/wireless/rtlwifi/pci.c +++ b/trunk/drivers/net/wireless/rtlwifi/pci.c @@ -1273,18 +1273,17 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw) *after reset, release previous pending packet, *and force the tx idx to the first one */ + spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); for (i = 0; i < RTL_PCI_MAX_TX_QUEUE_COUNT; i++) { if (rtlpci->tx_ring[i].desc) { struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[i]; while (skb_queue_len(&ring->queue)) { - struct rtl_tx_desc *entry; - struct sk_buff *skb; + struct rtl_tx_desc *entry = + &ring->desc[ring->idx]; + struct sk_buff *skb = + __skb_dequeue(&ring->queue); - spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, - flags); - entry = &ring->desc[ring->idx]; - skb = __skb_dequeue(&ring->queue); pci_unmap_single(rtlpci->pdev, rtlpriv->cfg->ops-> get_desc((u8 *) @@ -1292,15 +1291,15 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw) true, HW_DESC_TXBUFF_ADDR), skb->len, PCI_DMA_TODEVICE); - ring->idx = (ring->idx + 1) % ring->entries; - spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, - flags); kfree_skb(skb); + ring->idx = (ring->idx + 1) % ring->entries; } ring->idx = 0; } } + spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); + return 0; } diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index 9970c2b1b199..d228358e6a40 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -301,11 +301,9 @@ static struct usb_device_id rtl8192c_usb_ids[] = { {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ {RTL_USB_DEVICE(0x0846, 0x9041, rtl92cu_hal_cfg)}, /*NetGear WNA1000M*/ - {RTL_USB_DEVICE(0x0bda, 0x5088, rtl92cu_hal_cfg)}, /*Thinkware-CC&C*/ {RTL_USB_DEVICE(0x0df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ {RTL_USB_DEVICE(0x0df6, 0x005c, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ {RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/ - {RTL_USB_DEVICE(0x4856, 0x0091, rtl92cu_hal_cfg)}, /*NetweeN - Feixun*/ /* HP - Lite-On ,8188CUS Slim Combo */ {RTL_USB_DEVICE(0x103c, 0x1629, rtl92cu_hal_cfg)}, {RTL_USB_DEVICE(0x13d3, 0x3357, rtl92cu_hal_cfg)}, /* AzureWave */ @@ -348,7 +346,6 @@ static struct usb_device_id rtl8192c_usb_ids[] = { {RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Funai -Abocom*/ {RTL_USB_DEVICE(0x0846, 0x9021, rtl92cu_hal_cfg)}, /*Netgear-Sercomm*/ {RTL_USB_DEVICE(0x0b05, 0x17ab, rtl92cu_hal_cfg)}, /*ASUS-Edimax*/ - {RTL_USB_DEVICE(0x0bda, 0x8186, rtl92cu_hal_cfg)}, /*Realtek 92CE-VAU*/ {RTL_USB_DEVICE(0x0df6, 0x0061, rtl92cu_hal_cfg)}, /*Sitecom-Edimax*/ {RTL_USB_DEVICE(0x0e66, 0x0019, rtl92cu_hal_cfg)}, /*Hawking-Edimax*/ {RTL_USB_DEVICE(0x2001, 0x3307, rtl92cu_hal_cfg)}, /*D-Link-Cameo*/ diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/phy.c index b917a2a3caf7..8d7099bc472c 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/phy.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/phy.c @@ -1247,9 +1247,6 @@ static void _rtl92s_phy_get_txpower_index(struct ieee80211_hw *hw, u8 channel, /* Read HT 40 OFDM TX power */ ofdmpowerLevel[0] = rtlefuse->txpwrlevel_ht40_2s[0][index]; ofdmpowerLevel[1] = rtlefuse->txpwrlevel_ht40_2s[1][index]; - } else { - ofdmpowerLevel[0] = 0; - ofdmpowerLevel[1] = 0; } } diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/sw.c index ad4b4803482d..730bcc919529 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192se/sw.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192se/sw.c @@ -29,6 +29,7 @@ #include "../wifi.h" #include "../core.h" +#include "../pci.h" #include "../base.h" #include "../pci.h" #include "reg.h" diff --git a/trunk/drivers/net/wireless/ti/wl1251/acx.c b/trunk/drivers/net/wireless/ti/wl1251/acx.c index db6430c1a084..ad87a1ac6462 100644 --- a/trunk/drivers/net/wireless/ti/wl1251/acx.c +++ b/trunk/drivers/net/wireless/ti/wl1251/acx.c @@ -869,7 +869,7 @@ int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime) } *mactime = tsf_info->current_tsf_lsb | - ((u64)tsf_info->current_tsf_msb << 32); + (tsf_info->current_tsf_msb << 31); out: kfree(tsf_info); diff --git a/trunk/drivers/net/wireless/ti/wl1251/cmd.c b/trunk/drivers/net/wireless/ti/wl1251/cmd.c index 6822b845efc1..d14d69d733a0 100644 --- a/trunk/drivers/net/wireless/ti/wl1251/cmd.c +++ b/trunk/drivers/net/wireless/ti/wl1251/cmd.c @@ -277,6 +277,15 @@ int wl1251_cmd_join(struct wl1251 *wl, u8 bss_type, u8 channel, join->rx_config_options = wl->rx_config; join->rx_filter_options = wl->rx_filter; + /* + * FIXME: disable temporarily all filters because after commit + * 9cef8737 "mac80211: fix managed mode BSSID handling" broke + * association. The filter logic needs to be implemented properly + * and once that is done, this hack can be removed. + */ + join->rx_config_options = 0; + join->rx_filter_options = WL1251_DEFAULT_RX_FILTER; + join->basic_rate_set = RATE_MASK_1MBPS | RATE_MASK_2MBPS | RATE_MASK_5_5MBPS | RATE_MASK_11MBPS; diff --git a/trunk/drivers/net/wireless/ti/wl1251/event.c b/trunk/drivers/net/wireless/ti/wl1251/event.c index 5ec50a476a69..9f15ccaf8f05 100644 --- a/trunk/drivers/net/wireless/ti/wl1251/event.c +++ b/trunk/drivers/net/wireless/ti/wl1251/event.c @@ -76,7 +76,8 @@ static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox) } } - if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID) { + if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID && + wl->station_mode != STATION_ACTIVE_MODE) { wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT"); /* indicate to the stack, that beacons have been lost */ diff --git a/trunk/drivers/net/wireless/ti/wl1251/main.c b/trunk/drivers/net/wireless/ti/wl1251/main.c index 3118c425bcf1..d1afb8e3b2ef 100644 --- a/trunk/drivers/net/wireless/ti/wl1251/main.c +++ b/trunk/drivers/net/wireless/ti/wl1251/main.c @@ -334,12 +334,6 @@ static int wl1251_join(struct wl1251 *wl, u8 bss_type, u8 channel, if (ret < 0) goto out; - /* - * Join command applies filters, and if we are not associated, - * BSSID filter must be disabled for association to work. - */ - if (is_zero_ether_addr(wl->bssid)) - wl->rx_config &= ~CFG_BSSID_FILTER_EN; ret = wl1251_cmd_join(wl, bss_type, channel, beacon_interval, dtim_period); @@ -354,6 +348,33 @@ static int wl1251_join(struct wl1251 *wl, u8 bss_type, u8 channel, return ret; } +static void wl1251_filter_work(struct work_struct *work) +{ + struct wl1251 *wl = + container_of(work, struct wl1251, filter_work); + int ret; + + mutex_lock(&wl->mutex); + + if (wl->state == WL1251_STATE_OFF) + goto out; + + ret = wl1251_ps_elp_wakeup(wl); + if (ret < 0) + goto out; + + ret = wl1251_join(wl, wl->bss_type, wl->channel, wl->beacon_int, + wl->dtim_period); + if (ret < 0) + goto out_sleep; + +out_sleep: + wl1251_ps_elp_sleep(wl); + +out: + mutex_unlock(&wl->mutex); +} + static void wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct wl1251 *wl = hw->priv; @@ -457,6 +478,7 @@ static void wl1251_op_stop(struct ieee80211_hw *hw) cancel_work_sync(&wl->irq_work); cancel_work_sync(&wl->tx_work); + cancel_work_sync(&wl->filter_work); cancel_delayed_work_sync(&wl->elp_work); mutex_lock(&wl->mutex); @@ -659,15 +681,13 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed) FIF_FCSFAIL | \ FIF_BCN_PRBRESP_PROMISC | \ FIF_CONTROL | \ - FIF_OTHER_BSS | \ - FIF_PROBE_REQ) + FIF_OTHER_BSS) static void wl1251_op_configure_filter(struct ieee80211_hw *hw, unsigned int changed, unsigned int *total,u64 multicast) { struct wl1251 *wl = hw->priv; - int ret; wl1251_debug(DEBUG_MAC80211, "mac80211 configure filter"); @@ -678,7 +698,7 @@ static void wl1251_op_configure_filter(struct ieee80211_hw *hw, /* no filters which we support changed */ return; - mutex_lock(&wl->mutex); + /* FIXME: wl->rx_config and wl->rx_filter are not protected */ wl->rx_config = WL1251_DEFAULT_RX_CONFIG; wl->rx_filter = WL1251_DEFAULT_RX_FILTER; @@ -701,25 +721,15 @@ static void wl1251_op_configure_filter(struct ieee80211_hw *hw, } if (*total & FIF_CONTROL) wl->rx_filter |= CFG_RX_CTL_EN; - if (*total & FIF_OTHER_BSS || is_zero_ether_addr(wl->bssid)) - wl->rx_config &= ~CFG_BSSID_FILTER_EN; - if (*total & FIF_PROBE_REQ) - wl->rx_filter |= CFG_RX_PREQ_EN; + if (*total & FIF_OTHER_BSS) + wl->rx_filter &= ~CFG_BSSID_FILTER_EN; - if (wl->state == WL1251_STATE_OFF) - goto out; - - ret = wl1251_ps_elp_wakeup(wl); - if (ret < 0) - goto out; - - /* send filters to firmware */ - wl1251_acx_rx_config(wl, wl->rx_config, wl->rx_filter); - - wl1251_ps_elp_sleep(wl); - -out: - mutex_unlock(&wl->mutex); + /* + * FIXME: workqueues need to be properly cancelled on stop(), for + * now let's just disable changing the filter settings. They will + * be updated any on config(). + */ + /* schedule_work(&wl->filter_work); */ } /* HW encryption */ @@ -1380,6 +1390,7 @@ struct ieee80211_hw *wl1251_alloc_hw(void) skb_queue_head_init(&wl->tx_queue); + INIT_WORK(&wl->filter_work, wl1251_filter_work); INIT_DELAYED_WORK(&wl->elp_work, wl1251_elp_work); wl->channel = WL1251_DEFAULT_CHANNEL; wl->scanning = false; diff --git a/trunk/drivers/net/wireless/ti/wl1251/spi.c b/trunk/drivers/net/wireless/ti/wl1251/spi.c index 567660cd2fcd..87f6305bda2c 100644 --- a/trunk/drivers/net/wireless/ti/wl1251/spi.c +++ b/trunk/drivers/net/wireless/ti/wl1251/spi.c @@ -73,8 +73,6 @@ static void wl1251_spi_reset(struct wl1251 *wl) spi_sync(wl_to_spi(wl), &m); wl1251_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN); - - kfree(cmd); } static void wl1251_spi_wake(struct wl1251 *wl) @@ -129,8 +127,6 @@ static void wl1251_spi_wake(struct wl1251 *wl) spi_sync(wl_to_spi(wl), &m); wl1251_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN); - - kfree(cmd); } static void wl1251_spi_reset_wake(struct wl1251 *wl) diff --git a/trunk/drivers/net/wireless/ti/wl1251/wl1251.h b/trunk/drivers/net/wireless/ti/wl1251/wl1251.h index fd02060038de..9d8f5816c6f9 100644 --- a/trunk/drivers/net/wireless/ti/wl1251/wl1251.h +++ b/trunk/drivers/net/wireless/ti/wl1251/wl1251.h @@ -315,6 +315,7 @@ struct wl1251 { bool tx_queue_stopped; struct work_struct tx_work; + struct work_struct filter_work; /* Pending TX frames */ struct sk_buff *tx_frames[16]; diff --git a/trunk/drivers/net/wireless/ti/wl12xx/cmd.c b/trunk/drivers/net/wireless/ti/wl12xx/cmd.c index 30be784a40d8..50ba7480b790 100644 --- a/trunk/drivers/net/wireless/ti/wl12xx/cmd.c +++ b/trunk/drivers/net/wireless/ti/wl12xx/cmd.c @@ -174,7 +174,7 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl) struct wl1271_nvs_file *nvs = (struct wl1271_nvs_file *)wl->nvs; struct wl1271_radio_parms_cmd *radio_parms; struct wl1271_ini_general_params *gp = &nvs->general_params; - int ret, fem_idx; + int ret; if (!wl->nvs) return -ENODEV; @@ -185,13 +185,11 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl) radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM; - fem_idx = WL12XX_FEM_TO_NVS_ENTRY(gp->tx_bip_fem_manufacturer); - /* 2.4GHz parameters */ memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2, sizeof(struct wl1271_ini_band_params_2)); memcpy(&radio_parms->dyn_params_2, - &nvs->dyn_radio_params_2[fem_idx].params, + &nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params, sizeof(struct wl1271_ini_fem_params_2)); /* 5GHz parameters */ @@ -199,7 +197,7 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl) &nvs->stat_radio_params_5, sizeof(struct wl1271_ini_band_params_5)); memcpy(&radio_parms->dyn_params_5, - &nvs->dyn_radio_params_5[fem_idx].params, + &nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params, sizeof(struct wl1271_ini_fem_params_5)); wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ", @@ -218,7 +216,7 @@ int wl128x_cmd_radio_parms(struct wl1271 *wl) struct wl128x_nvs_file *nvs = (struct wl128x_nvs_file *)wl->nvs; struct wl128x_radio_parms_cmd *radio_parms; struct wl128x_ini_general_params *gp = &nvs->general_params; - int ret, fem_idx; + int ret; if (!wl->nvs) return -ENODEV; @@ -229,13 +227,11 @@ int wl128x_cmd_radio_parms(struct wl1271 *wl) radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM; - fem_idx = WL12XX_FEM_TO_NVS_ENTRY(gp->tx_bip_fem_manufacturer); - /* 2.4GHz parameters */ memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2, sizeof(struct wl128x_ini_band_params_2)); memcpy(&radio_parms->dyn_params_2, - &nvs->dyn_radio_params_2[fem_idx].params, + &nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params, sizeof(struct wl128x_ini_fem_params_2)); /* 5GHz parameters */ @@ -243,7 +239,7 @@ int wl128x_cmd_radio_parms(struct wl1271 *wl) &nvs->stat_radio_params_5, sizeof(struct wl128x_ini_band_params_5)); memcpy(&radio_parms->dyn_params_5, - &nvs->dyn_radio_params_5[fem_idx].params, + &nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params, sizeof(struct wl128x_ini_fem_params_5)); radio_parms->fem_vendor_and_options = nvs->fem_vendor_and_options; diff --git a/trunk/drivers/net/wireless/ti/wl12xx/main.c b/trunk/drivers/net/wireless/ti/wl12xx/main.c index 47ba2e0017f4..85d1600ee340 100644 --- a/trunk/drivers/net/wireless/ti/wl12xx/main.c +++ b/trunk/drivers/net/wireless/ti/wl12xx/main.c @@ -246,7 +246,6 @@ static struct wlcore_conf wl12xx_conf = { .forced_ps = false, .keep_alive_interval = 55000, .max_listen_interval = 20, - .sta_sleep_auth = WL1271_PSM_ILLEGAL, }, .itrim = { .enable = false, @@ -598,10 +597,8 @@ static const int wl12xx_rtable[REG_TABLE_LEN] = { #define WL128X_FW_NAME_SINGLE "ti-connectivity/wl128x-fw-4-sr.bin" #define WL128X_PLT_FW_NAME "ti-connectivity/wl128x-fw-4-plt.bin" -static int wl127x_prepare_read(struct wl1271 *wl, u32 rx_desc, u32 len) +static void wl127x_prepare_read(struct wl1271 *wl, u32 rx_desc, u32 len) { - int ret; - if (wl->chip.id != CHIP_ID_1283_PG20) { struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map; struct wl127x_rx_mem_pool_addr rx_mem_addr; @@ -618,13 +615,9 @@ static int wl127x_prepare_read(struct wl1271 *wl, u32 rx_desc, u32 len) rx_mem_addr.addr_extra = rx_mem_addr.addr + 4; - ret = wlcore_write(wl, WL1271_SLV_REG_DATA, &rx_mem_addr, - sizeof(rx_mem_addr), false); - if (ret < 0) - return ret; + wl1271_write(wl, WL1271_SLV_REG_DATA, + &rx_mem_addr, sizeof(rx_mem_addr), false); } - - return 0; } static int wl12xx_identify_chip(struct wl1271 *wl) @@ -688,95 +681,64 @@ static int wl12xx_identify_chip(struct wl1271 *wl) return ret; } -static int __must_check wl12xx_top_reg_write(struct wl1271 *wl, int addr, - u16 val) +static void wl12xx_top_reg_write(struct wl1271 *wl, int addr, u16 val) { - int ret; - /* write address >> 1 + 0x30000 to OCP_POR_CTR */ addr = (addr >> 1) + 0x30000; - ret = wlcore_write32(wl, WL12XX_OCP_POR_CTR, addr); - if (ret < 0) - goto out; + wl1271_write32(wl, WL12XX_OCP_POR_CTR, addr); /* write value to OCP_POR_WDATA */ - ret = wlcore_write32(wl, WL12XX_OCP_DATA_WRITE, val); - if (ret < 0) - goto out; + wl1271_write32(wl, WL12XX_OCP_DATA_WRITE, val); /* write 1 to OCP_CMD */ - ret = wlcore_write32(wl, WL12XX_OCP_CMD, OCP_CMD_WRITE); - if (ret < 0) - goto out; - -out: - return ret; + wl1271_write32(wl, WL12XX_OCP_CMD, OCP_CMD_WRITE); } -static int __must_check wl12xx_top_reg_read(struct wl1271 *wl, int addr, - u16 *out) +static u16 wl12xx_top_reg_read(struct wl1271 *wl, int addr) { u32 val; int timeout = OCP_CMD_LOOP; - int ret; /* write address >> 1 + 0x30000 to OCP_POR_CTR */ addr = (addr >> 1) + 0x30000; - ret = wlcore_write32(wl, WL12XX_OCP_POR_CTR, addr); - if (ret < 0) - return ret; + wl1271_write32(wl, WL12XX_OCP_POR_CTR, addr); /* write 2 to OCP_CMD */ - ret = wlcore_write32(wl, WL12XX_OCP_CMD, OCP_CMD_READ); - if (ret < 0) - return ret; + wl1271_write32(wl, WL12XX_OCP_CMD, OCP_CMD_READ); /* poll for data ready */ do { - ret = wlcore_read32(wl, WL12XX_OCP_DATA_READ, &val); - if (ret < 0) - return ret; + val = wl1271_read32(wl, WL12XX_OCP_DATA_READ); } while (!(val & OCP_READY_MASK) && --timeout); if (!timeout) { wl1271_warning("Top register access timed out."); - return -ETIMEDOUT; + return 0xffff; } /* check data status and return if OK */ - if ((val & OCP_STATUS_MASK) != OCP_STATUS_OK) { + if ((val & OCP_STATUS_MASK) == OCP_STATUS_OK) + return val & 0xffff; + else { wl1271_warning("Top register access returned error."); - return -EIO; + return 0xffff; } - - if (out) - *out = val & 0xffff; - - return 0; } static int wl128x_switch_tcxo_to_fref(struct wl1271 *wl) { u16 spare_reg; - int ret; /* Mask bits [2] & [8:4] in the sys_clk_cfg register */ - ret = wl12xx_top_reg_read(wl, WL_SPARE_REG, &spare_reg); - if (ret < 0) - return ret; - + spare_reg = wl12xx_top_reg_read(wl, WL_SPARE_REG); if (spare_reg == 0xFFFF) return -EFAULT; spare_reg |= (BIT(3) | BIT(5) | BIT(6)); - ret = wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg); - if (ret < 0) - return ret; + wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg); /* Enable FREF_CLK_REQ & mux MCS and coex PLLs to FREF */ - ret = wl12xx_top_reg_write(wl, SYS_CLK_CFG_REG, - WL_CLK_REQ_TYPE_PG2 | MCS_PLL_CLK_SEL_FREF); - if (ret < 0) - return ret; + wl12xx_top_reg_write(wl, SYS_CLK_CFG_REG, + WL_CLK_REQ_TYPE_PG2 | MCS_PLL_CLK_SEL_FREF); /* Delay execution for 15msec, to let the HW settle */ mdelay(15); @@ -787,12 +749,8 @@ static int wl128x_switch_tcxo_to_fref(struct wl1271 *wl) static bool wl128x_is_tcxo_valid(struct wl1271 *wl) { u16 tcxo_detection; - int ret; - - ret = wl12xx_top_reg_read(wl, TCXO_CLK_DETECT_REG, &tcxo_detection); - if (ret < 0) - return false; + tcxo_detection = wl12xx_top_reg_read(wl, TCXO_CLK_DETECT_REG); if (tcxo_detection & TCXO_DET_FAILED) return false; @@ -802,12 +760,8 @@ static bool wl128x_is_tcxo_valid(struct wl1271 *wl) static bool wl128x_is_fref_valid(struct wl1271 *wl) { u16 fref_detection; - int ret; - - ret = wl12xx_top_reg_read(wl, FREF_CLK_DETECT_REG, &fref_detection); - if (ret < 0) - return false; + fref_detection = wl12xx_top_reg_read(wl, FREF_CLK_DETECT_REG); if (fref_detection & FREF_CLK_DETECT_FAIL) return false; @@ -816,21 +770,11 @@ static bool wl128x_is_fref_valid(struct wl1271 *wl) static int wl128x_manually_configure_mcs_pll(struct wl1271 *wl) { - int ret; - - ret = wl12xx_top_reg_write(wl, MCS_PLL_M_REG, MCS_PLL_M_REG_VAL); - if (ret < 0) - goto out; - - ret = wl12xx_top_reg_write(wl, MCS_PLL_N_REG, MCS_PLL_N_REG_VAL); - if (ret < 0) - goto out; - - ret = wl12xx_top_reg_write(wl, MCS_PLL_CONFIG_REG, - MCS_PLL_CONFIG_REG_VAL); + wl12xx_top_reg_write(wl, MCS_PLL_M_REG, MCS_PLL_M_REG_VAL); + wl12xx_top_reg_write(wl, MCS_PLL_N_REG, MCS_PLL_N_REG_VAL); + wl12xx_top_reg_write(wl, MCS_PLL_CONFIG_REG, MCS_PLL_CONFIG_REG_VAL); -out: - return ret; + return 0; } static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk) @@ -839,19 +783,13 @@ static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk) u16 pll_config; u8 input_freq; struct wl12xx_priv *priv = wl->priv; - int ret; /* Mask bits [3:1] in the sys_clk_cfg register */ - ret = wl12xx_top_reg_read(wl, WL_SPARE_REG, &spare_reg); - if (ret < 0) - return ret; - + spare_reg = wl12xx_top_reg_read(wl, WL_SPARE_REG); if (spare_reg == 0xFFFF) return -EFAULT; spare_reg |= BIT(2); - ret = wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg); - if (ret < 0) - return ret; + wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg); /* Handle special cases of the TCXO clock */ if (priv->tcxo_clock == WL12XX_TCXOCLOCK_16_8 || @@ -861,17 +799,14 @@ static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk) /* Set the input frequency according to the selected clock source */ input_freq = (clk & 1) + 1; - ret = wl12xx_top_reg_read(wl, MCS_PLL_CONFIG_REG, &pll_config); - if (ret < 0) - return ret; - + pll_config = wl12xx_top_reg_read(wl, MCS_PLL_CONFIG_REG); if (pll_config == 0xFFFF) return -EFAULT; pll_config |= (input_freq << MCS_SEL_IN_FREQ_SHIFT); pll_config |= MCS_PLL_ENABLE_HP; - ret = wl12xx_top_reg_write(wl, MCS_PLL_CONFIG_REG, pll_config); + wl12xx_top_reg_write(wl, MCS_PLL_CONFIG_REG, pll_config); - return ret; + return 0; } /* @@ -885,7 +820,6 @@ static int wl128x_boot_clk(struct wl1271 *wl, int *selected_clock) { struct wl12xx_priv *priv = wl->priv; u16 sys_clk_cfg; - int ret; /* For XTAL-only modes, FREF will be used after switching from TCXO */ if (priv->ref_clock == WL12XX_REFCLOCK_26_XTAL || @@ -896,10 +830,7 @@ static int wl128x_boot_clk(struct wl1271 *wl, int *selected_clock) } /* Query the HW, to determine which clock source we should use */ - ret = wl12xx_top_reg_read(wl, SYS_CLK_CFG_REG, &sys_clk_cfg); - if (ret < 0) - return ret; - + sys_clk_cfg = wl12xx_top_reg_read(wl, SYS_CLK_CFG_REG); if (sys_clk_cfg == 0xFFFF) return -EINVAL; if (sys_clk_cfg & PRCM_CM_EN_MUX_WLAN_FREF) @@ -934,7 +865,6 @@ static int wl127x_boot_clk(struct wl1271 *wl) struct wl12xx_priv *priv = wl->priv; u32 pause; u32 clk; - int ret; if (WL127X_PG_GET_MAJOR(wl->hw_pg_ver) < 3) wl->quirks |= WLCORE_QUIRK_END_OF_TRANSACTION; @@ -955,74 +885,48 @@ static int wl127x_boot_clk(struct wl1271 *wl) if (priv->ref_clock != CONF_REF_CLK_19_2_E) { u16 val; /* Set clock type (open drain) */ - ret = wl12xx_top_reg_read(wl, OCP_REG_CLK_TYPE, &val); - if (ret < 0) - goto out; - + val = wl12xx_top_reg_read(wl, OCP_REG_CLK_TYPE); val &= FREF_CLK_TYPE_BITS; - ret = wl12xx_top_reg_write(wl, OCP_REG_CLK_TYPE, val); - if (ret < 0) - goto out; + wl12xx_top_reg_write(wl, OCP_REG_CLK_TYPE, val); /* Set clock pull mode (no pull) */ - ret = wl12xx_top_reg_read(wl, OCP_REG_CLK_PULL, &val); - if (ret < 0) - goto out; - + val = wl12xx_top_reg_read(wl, OCP_REG_CLK_PULL); val |= NO_PULL; - ret = wl12xx_top_reg_write(wl, OCP_REG_CLK_PULL, val); - if (ret < 0) - goto out; + wl12xx_top_reg_write(wl, OCP_REG_CLK_PULL, val); } else { u16 val; /* Set clock polarity */ - ret = wl12xx_top_reg_read(wl, OCP_REG_CLK_POLARITY, &val); - if (ret < 0) - goto out; - + val = wl12xx_top_reg_read(wl, OCP_REG_CLK_POLARITY); val &= FREF_CLK_POLARITY_BITS; val |= CLK_REQ_OUTN_SEL; - ret = wl12xx_top_reg_write(wl, OCP_REG_CLK_POLARITY, val); - if (ret < 0) - goto out; + wl12xx_top_reg_write(wl, OCP_REG_CLK_POLARITY, val); } - ret = wlcore_write32(wl, WL12XX_PLL_PARAMETERS, clk); - if (ret < 0) - goto out; + wl1271_write32(wl, WL12XX_PLL_PARAMETERS, clk); - ret = wlcore_read32(wl, WL12XX_PLL_PARAMETERS, &pause); - if (ret < 0) - goto out; + pause = wl1271_read32(wl, WL12XX_PLL_PARAMETERS); wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause); pause &= ~(WU_COUNTER_PAUSE_VAL); pause |= WU_COUNTER_PAUSE_VAL; - ret = wlcore_write32(wl, WL12XX_WU_COUNTER_PAUSE, pause); + wl1271_write32(wl, WL12XX_WU_COUNTER_PAUSE, pause); -out: - return ret; + return 0; } static int wl1271_boot_soft_reset(struct wl1271 *wl) { unsigned long timeout; u32 boot_data; - int ret = 0; /* perform soft reset */ - ret = wlcore_write32(wl, WL12XX_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT); - if (ret < 0) - goto out; + wl1271_write32(wl, WL12XX_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT); /* SOFT_RESET is self clearing */ timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME); while (1) { - ret = wlcore_read32(wl, WL12XX_SLV_SOFT_RESET, &boot_data); - if (ret < 0) - goto out; - + boot_data = wl1271_read32(wl, WL12XX_SLV_SOFT_RESET); wl1271_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data); if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0) break; @@ -1038,15 +942,12 @@ static int wl1271_boot_soft_reset(struct wl1271 *wl) } /* disable Rx/Tx */ - ret = wlcore_write32(wl, WL12XX_ENABLE, 0x0); - if (ret < 0) - goto out; + wl1271_write32(wl, WL12XX_ENABLE, 0x0); /* disable auto calibration on start*/ - ret = wlcore_write32(wl, WL12XX_SPARE_A2, 0xffff); + wl1271_write32(wl, WL12XX_SPARE_A2, 0xffff); -out: - return ret; + return 0; } static int wl12xx_pre_boot(struct wl1271 *wl) @@ -1067,23 +968,16 @@ static int wl12xx_pre_boot(struct wl1271 *wl) } /* Continue the ELP wake up sequence */ - ret = wlcore_write32(wl, WL12XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL); - if (ret < 0) - goto out; - + wl1271_write32(wl, WL12XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL); udelay(500); - ret = wlcore_set_partition(wl, &wl->ptable[PART_DRPW]); - if (ret < 0) - goto out; + wlcore_set_partition(wl, &wl->ptable[PART_DRPW]); /* Read-modify-write DRPW_SCRATCH_START register (see next state) to be used by DRPw FW. The RTRIM value will be added by the FW before taking DRPw out of reset */ - ret = wlcore_read32(wl, WL12XX_DRPW_SCRATCH_START, &clk); - if (ret < 0) - goto out; + clk = wl1271_read32(wl, WL12XX_DRPW_SCRATCH_START); wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk); @@ -1092,18 +986,12 @@ static int wl12xx_pre_boot(struct wl1271 *wl) else clk |= (priv->ref_clock << 1) << 4; - ret = wlcore_write32(wl, WL12XX_DRPW_SCRATCH_START, clk); - if (ret < 0) - goto out; + wl1271_write32(wl, WL12XX_DRPW_SCRATCH_START, clk); - ret = wlcore_set_partition(wl, &wl->ptable[PART_WORK]); - if (ret < 0) - goto out; + wlcore_set_partition(wl, &wl->ptable[PART_WORK]); /* Disable interrupts */ - ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL); - if (ret < 0) - goto out; + wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL); ret = wl1271_boot_soft_reset(wl); if (ret < 0) @@ -1113,72 +1001,47 @@ static int wl12xx_pre_boot(struct wl1271 *wl) return ret; } -static int wl12xx_pre_upload(struct wl1271 *wl) +static void wl12xx_pre_upload(struct wl1271 *wl) { - u32 tmp; - u16 polarity; - int ret; + u32 tmp, polarity; /* write firmware's last address (ie. it's length) to * ACX_EEPROMLESS_IND_REG */ wl1271_debug(DEBUG_BOOT, "ACX_EEPROMLESS_IND_REG"); - ret = wlcore_write32(wl, WL12XX_EEPROMLESS_IND, WL12XX_EEPROMLESS_IND); - if (ret < 0) - goto out; + wl1271_write32(wl, WL12XX_EEPROMLESS_IND, WL12XX_EEPROMLESS_IND); - ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &tmp); - if (ret < 0) - goto out; + tmp = wlcore_read_reg(wl, REG_CHIP_ID_B); wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp); /* 6. read the EEPROM parameters */ - ret = wlcore_read32(wl, WL12XX_SCR_PAD2, &tmp); - if (ret < 0) - goto out; + tmp = wl1271_read32(wl, WL12XX_SCR_PAD2); /* WL1271: The reference driver skips steps 7 to 10 (jumps directly * to upload_fw) */ - if (wl->chip.id == CHIP_ID_1283_PG20) { - ret = wl12xx_top_reg_write(wl, SDIO_IO_DS, HCI_IO_DS_6MA); - if (ret < 0) - goto out; - } + if (wl->chip.id == CHIP_ID_1283_PG20) + wl12xx_top_reg_write(wl, SDIO_IO_DS, HCI_IO_DS_6MA); /* polarity must be set before the firmware is loaded */ - ret = wl12xx_top_reg_read(wl, OCP_REG_POLARITY, &polarity); - if (ret < 0) - goto out; + polarity = wl12xx_top_reg_read(wl, OCP_REG_POLARITY); /* We use HIGH polarity, so unset the LOW bit */ polarity &= ~POLARITY_LOW; - ret = wl12xx_top_reg_write(wl, OCP_REG_POLARITY, polarity); + wl12xx_top_reg_write(wl, OCP_REG_POLARITY, polarity); -out: - return ret; } -static int wl12xx_enable_interrupts(struct wl1271 *wl) +static void wl12xx_enable_interrupts(struct wl1271 *wl) { - int ret; - - ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, - WL12XX_ACX_ALL_EVENTS_VECTOR); - if (ret < 0) - goto out; + wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL12XX_ACX_ALL_EVENTS_VECTOR); wlcore_enable_interrupts(wl); - ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, - WL1271_ACX_INTR_ALL & ~(WL12XX_INTR_MASK)); - if (ret < 0) - goto out; + wlcore_write_reg(wl, REG_INTERRUPT_MASK, + WL1271_ACX_INTR_ALL & ~(WL12XX_INTR_MASK)); - ret = wlcore_write32(wl, WL12XX_HI_CFG, HI_CFG_DEF_VAL); - -out: - return ret; + wl1271_write32(wl, WL12XX_HI_CFG, HI_CFG_DEF_VAL); } static int wl12xx_boot(struct wl1271 *wl) @@ -1193,9 +1056,7 @@ static int wl12xx_boot(struct wl1271 *wl) if (ret < 0) goto out; - ret = wl12xx_pre_upload(wl); - if (ret < 0) - goto out; + wl12xx_pre_upload(wl); ret = wlcore_boot_upload_firmware(wl); if (ret < 0) @@ -1205,30 +1066,22 @@ static int wl12xx_boot(struct wl1271 *wl) if (ret < 0) goto out; - ret = wl12xx_enable_interrupts(wl); + wl12xx_enable_interrupts(wl); out: return ret; } -static int wl12xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr, +static void wl12xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr, void *buf, size_t len) { - int ret; - - ret = wlcore_write(wl, cmd_box_addr, buf, len, false); - if (ret < 0) - return ret; - - ret = wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL12XX_INTR_TRIG_CMD); - - return ret; + wl1271_write(wl, cmd_box_addr, buf, len, false); + wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL12XX_INTR_TRIG_CMD); } -static int wl12xx_ack_event(struct wl1271 *wl) +static void wl12xx_ack_event(struct wl1271 *wl) { - return wlcore_write_reg(wl, REG_INTERRUPT_TRIG, - WL12XX_INTR_TRIG_EVENT_ACK); + wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL12XX_INTR_TRIG_EVENT_ACK); } static u32 wl12xx_calc_tx_blocks(struct wl1271 *wl, u32 len, u32 spare_blks) @@ -1308,13 +1161,13 @@ static u32 wl12xx_get_rx_packet_len(struct wl1271 *wl, void *rx_data, return data_len - sizeof(*desc) - desc->pad_len; } -static int wl12xx_tx_delayed_compl(struct wl1271 *wl) +static void wl12xx_tx_delayed_compl(struct wl1271 *wl) { if (wl->fw_status_1->tx_results_counter == (wl->tx_results_count & 0xff)) - return 0; + return; - return wlcore_tx_complete(wl); + wl1271_tx_complete(wl); } static int wl12xx_hw_init(struct wl1271 *wl) @@ -1415,58 +1268,39 @@ static bool wl12xx_mac_in_fuse(struct wl1271 *wl) return supported; } -static int wl12xx_get_fuse_mac(struct wl1271 *wl) +static void wl12xx_get_fuse_mac(struct wl1271 *wl) { u32 mac1, mac2; - int ret; - ret = wlcore_set_partition(wl, &wl->ptable[PART_DRPW]); - if (ret < 0) - goto out; + wlcore_set_partition(wl, &wl->ptable[PART_DRPW]); - ret = wlcore_read32(wl, WL12XX_REG_FUSE_BD_ADDR_1, &mac1); - if (ret < 0) - goto out; - - ret = wlcore_read32(wl, WL12XX_REG_FUSE_BD_ADDR_2, &mac2); - if (ret < 0) - goto out; + mac1 = wl1271_read32(wl, WL12XX_REG_FUSE_BD_ADDR_1); + mac2 = wl1271_read32(wl, WL12XX_REG_FUSE_BD_ADDR_2); /* these are the two parts of the BD_ADDR */ wl->fuse_oui_addr = ((mac2 & 0xffff) << 8) + ((mac1 & 0xff000000) >> 24); wl->fuse_nic_addr = mac1 & 0xffffff; - ret = wlcore_set_partition(wl, &wl->ptable[PART_DOWN]); - -out: - return ret; + wlcore_set_partition(wl, &wl->ptable[PART_DOWN]); } -static int wl12xx_get_pg_ver(struct wl1271 *wl, s8 *ver) +static s8 wl12xx_get_pg_ver(struct wl1271 *wl) { - u16 die_info; - int ret; + u32 die_info; if (wl->chip.id == CHIP_ID_1283_PG20) - ret = wl12xx_top_reg_read(wl, WL128X_REG_FUSE_DATA_2_1, - &die_info); + die_info = wl12xx_top_reg_read(wl, WL128X_REG_FUSE_DATA_2_1); else - ret = wl12xx_top_reg_read(wl, WL127X_REG_FUSE_DATA_2_1, - &die_info); + die_info = wl12xx_top_reg_read(wl, WL127X_REG_FUSE_DATA_2_1); - if (ret >= 0 && ver) - *ver = (s8)((die_info & PG_VER_MASK) >> PG_VER_OFFSET); - - return ret; + return (s8) (die_info & PG_VER_MASK) >> PG_VER_OFFSET; } -static int wl12xx_get_mac(struct wl1271 *wl) +static void wl12xx_get_mac(struct wl1271 *wl) { if (wl12xx_mac_in_fuse(wl)) - return wl12xx_get_fuse_mac(wl); - - return 0; + wl12xx_get_fuse_mac(wl); } static void wl12xx_set_tx_desc_csum(struct wl1271 *wl, @@ -1614,8 +1448,10 @@ static int __devinit wl12xx_probe(struct platform_device *pdev) wl->hw_min_ht_rate = WL12XX_CONF_HW_RXTX_RATE_MCS0; wl->fw_status_priv_len = 0; wl->stats.fw_stats_len = sizeof(struct wl12xx_acx_statistics); - wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, &wl12xx_ht_cap); - wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, &wl12xx_ht_cap); + memcpy(&wl->ht_cap[IEEE80211_BAND_2GHZ], &wl12xx_ht_cap, + sizeof(wl12xx_ht_cap)); + memcpy(&wl->ht_cap[IEEE80211_BAND_5GHZ], &wl12xx_ht_cap, + sizeof(wl12xx_ht_cap)); wl12xx_conf_init(wl); if (!fref_param) { diff --git a/trunk/drivers/net/wireless/ti/wl18xx/acx.h b/trunk/drivers/net/wireless/ti/wl18xx/acx.h index e2609a6b7341..ebbaf611e97b 100644 --- a/trunk/drivers/net/wireless/ti/wl18xx/acx.h +++ b/trunk/drivers/net/wireless/ti/wl18xx/acx.h @@ -32,21 +32,25 @@ enum { /* numbers of bits the length field takes (add 1 for the actual number) */ #define WL18XX_HOST_IF_LEN_SIZE_FIELD 15 -#define WL18XX_ACX_EVENTS_VECTOR (WL1271_ACX_INTR_WATCHDOG | \ - WL1271_ACX_INTR_INIT_COMPLETE | \ - WL1271_ACX_INTR_EVENT_A | \ - WL1271_ACX_INTR_EVENT_B | \ - WL1271_ACX_INTR_CMD_COMPLETE | \ - WL1271_ACX_INTR_HW_AVAILABLE | \ - WL1271_ACX_INTR_DATA | \ - WL1271_ACX_SW_INTR_WATCHDOG) - -#define WL18XX_INTR_MASK (WL1271_ACX_INTR_WATCHDOG | \ - WL1271_ACX_INTR_EVENT_A | \ - WL1271_ACX_INTR_EVENT_B | \ - WL1271_ACX_INTR_HW_AVAILABLE | \ - WL1271_ACX_INTR_DATA | \ - WL1271_ACX_SW_INTR_WATCHDOG) +#define WL18XX_ACX_EVENTS_VECTOR_PG1 (WL1271_ACX_INTR_WATCHDOG | \ + WL1271_ACX_INTR_INIT_COMPLETE | \ + WL1271_ACX_INTR_EVENT_A | \ + WL1271_ACX_INTR_EVENT_B | \ + WL1271_ACX_INTR_CMD_COMPLETE | \ + WL1271_ACX_INTR_HW_AVAILABLE | \ + WL1271_ACX_INTR_DATA) + +#define WL18XX_ACX_EVENTS_VECTOR_PG2 (WL18XX_ACX_EVENTS_VECTOR_PG1 | \ + WL1271_ACX_SW_INTR_WATCHDOG) + +#define WL18XX_INTR_MASK_PG1 (WL1271_ACX_INTR_WATCHDOG | \ + WL1271_ACX_INTR_EVENT_A | \ + WL1271_ACX_INTR_EVENT_B | \ + WL1271_ACX_INTR_HW_AVAILABLE | \ + WL1271_ACX_INTR_DATA) + +#define WL18XX_INTR_MASK_PG2 (WL18XX_INTR_MASK_PG1 | \ + WL1271_ACX_SW_INTR_WATCHDOG) struct wl18xx_acx_host_config_bitmap { struct acx_header header; diff --git a/trunk/drivers/net/wireless/ti/wl18xx/io.c b/trunk/drivers/net/wireless/ti/wl18xx/io.c index 0c06ccfd1b8c..598c057e722b 100644 --- a/trunk/drivers/net/wireless/ti/wl18xx/io.c +++ b/trunk/drivers/net/wireless/ti/wl18xx/io.c @@ -24,52 +24,37 @@ #include "io.h" -int wl18xx_top_reg_write(struct wl1271 *wl, int addr, u16 val) +void wl18xx_top_reg_write(struct wl1271 *wl, int addr, u16 val) { u32 tmp; - int ret; if (WARN_ON(addr % 2)) - return -EINVAL; + return; if ((addr % 4) == 0) { - ret = wlcore_read32(wl, addr, &tmp); - if (ret < 0) - goto out; - + tmp = wl1271_read32(wl, addr); tmp = (tmp & 0xffff0000) | val; - ret = wlcore_write32(wl, addr, tmp); + wl1271_write32(wl, addr, tmp); } else { - ret = wlcore_read32(wl, addr - 2, &tmp); - if (ret < 0) - goto out; - + tmp = wl1271_read32(wl, addr - 2); tmp = (tmp & 0xffff) | (val << 16); - ret = wlcore_write32(wl, addr - 2, tmp); + wl1271_write32(wl, addr - 2, tmp); } - -out: - return ret; } -int wl18xx_top_reg_read(struct wl1271 *wl, int addr, u16 *out) +u16 wl18xx_top_reg_read(struct wl1271 *wl, int addr) { u32 val; - int ret; if (WARN_ON(addr % 2)) - return -EINVAL; + return 0; if ((addr % 4) == 0) { /* address is 4-bytes aligned */ - ret = wlcore_read32(wl, addr, &val); - if (ret >= 0 && out) - *out = val & 0xffff; + val = wl1271_read32(wl, addr); + return val & 0xffff; } else { - ret = wlcore_read32(wl, addr - 2, &val); - if (ret >= 0 && out) - *out = (val & 0xffff0000) >> 16; + val = wl1271_read32(wl, addr - 2); + return (val & 0xffff0000) >> 16; } - - return ret; } diff --git a/trunk/drivers/net/wireless/ti/wl18xx/io.h b/trunk/drivers/net/wireless/ti/wl18xx/io.h index c32ae30277df..be4e126ff617 100644 --- a/trunk/drivers/net/wireless/ti/wl18xx/io.h +++ b/trunk/drivers/net/wireless/ti/wl18xx/io.h @@ -22,7 +22,7 @@ #ifndef __WL18XX_IO_H__ #define __WL18XX_IO_H__ -int __must_check wl18xx_top_reg_write(struct wl1271 *wl, int addr, u16 val); -int __must_check wl18xx_top_reg_read(struct wl1271 *wl, int addr, u16 *out); +void wl18xx_top_reg_write(struct wl1271 *wl, int addr, u16 val); +u16 wl18xx_top_reg_read(struct wl1271 *wl, int addr); #endif /* __WL18XX_IO_H__ */ diff --git a/trunk/drivers/net/wireless/ti/wl18xx/main.c b/trunk/drivers/net/wireless/ti/wl18xx/main.c index 5e583be8f674..ed9c3650e08a 100644 --- a/trunk/drivers/net/wireless/ti/wl18xx/main.c +++ b/trunk/drivers/net/wireless/ti/wl18xx/main.c @@ -43,11 +43,10 @@ #define WL18XX_RX_CHECKSUM_MASK 0x40 -static char *ht_mode_param = "default"; +static char *ht_mode_param = "wide"; static char *board_type_param = "hdk"; static bool checksum_param = false; static bool enable_11a_param = true; -static int num_rx_desc_param = -1; /* phy paramters */ static int dc2dc_param = -1; @@ -373,7 +372,6 @@ static struct wlcore_conf wl18xx_conf = { .forced_ps = false, .keep_alive_interval = 55000, .max_listen_interval = 20, - .sta_sleep_auth = WL1271_PSM_ILLEGAL, }, .itrim = { .enable = false, @@ -608,15 +606,24 @@ static int wl18xx_identify_chip(struct wl1271 *wl) wl->plt_fw_name = WL18XX_FW_NAME; wl->quirks |= WLCORE_QUIRK_NO_ELP | WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN | - WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN | WLCORE_QUIRK_TX_PAD_LAST_FRAME; + break; case CHIP_ID_185x_PG10: - wl1271_warning("chip id 0x%x (185x PG10) is deprecated", - wl->chip.id); - ret = -ENODEV; - goto out; + wl1271_debug(DEBUG_BOOT, "chip id 0x%x (185x PG10)", + wl->chip.id); + wl->sr_fw_name = WL18XX_FW_NAME; + /* wl18xx uses the same firmware for PLT */ + wl->plt_fw_name = WL18XX_FW_NAME; + wl->quirks |= WLCORE_QUIRK_NO_ELP | + WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED | + WLCORE_QUIRK_RX_BLOCKSIZE_ALIGN | + WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN; + + /* PG 1.0 has some problems with MCS_13, so disable it */ + wl->ht_cap[IEEE80211_BAND_2GHZ].mcs.rx_mask[1] &= ~BIT(5); + break; default: wl1271_warning("unsupported chip id: 0x%x", wl->chip.id); ret = -ENODEV; @@ -627,178 +634,123 @@ static int wl18xx_identify_chip(struct wl1271 *wl) return ret; } -static int wl18xx_set_clk(struct wl1271 *wl) +static void wl18xx_set_clk(struct wl1271 *wl) { - u16 clk_freq; - int ret; + u32 clk_freq; - ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); - if (ret < 0) - goto out; + wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); /* TODO: PG2: apparently we need to read the clk type */ - ret = wl18xx_top_reg_read(wl, PRIMARY_CLK_DETECT, &clk_freq); - if (ret < 0) - goto out; - + clk_freq = wl18xx_top_reg_read(wl, PRIMARY_CLK_DETECT); wl1271_debug(DEBUG_BOOT, "clock freq %d (%d, %d, %d, %d, %s)", clk_freq, wl18xx_clk_table[clk_freq].n, wl18xx_clk_table[clk_freq].m, wl18xx_clk_table[clk_freq].p, wl18xx_clk_table[clk_freq].q, wl18xx_clk_table[clk_freq].swallow ? "swallow" : "spit"); - ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_N, - wl18xx_clk_table[clk_freq].n); - if (ret < 0) - goto out; - - ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_M, - wl18xx_clk_table[clk_freq].m); - if (ret < 0) - goto out; + wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_N, wl18xx_clk_table[clk_freq].n); + wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_M, wl18xx_clk_table[clk_freq].m); if (wl18xx_clk_table[clk_freq].swallow) { /* first the 16 lower bits */ - ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_Q_FACTOR_CFG_1, - wl18xx_clk_table[clk_freq].q & - PLLSH_WCS_PLL_Q_FACTOR_CFG_1_MASK); - if (ret < 0) - goto out; - + wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_Q_FACTOR_CFG_1, + wl18xx_clk_table[clk_freq].q & + PLLSH_WCS_PLL_Q_FACTOR_CFG_1_MASK); /* then the 16 higher bits, masked out */ - ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_Q_FACTOR_CFG_2, - (wl18xx_clk_table[clk_freq].q >> 16) & - PLLSH_WCS_PLL_Q_FACTOR_CFG_2_MASK); - if (ret < 0) - goto out; + wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_Q_FACTOR_CFG_2, + (wl18xx_clk_table[clk_freq].q >> 16) & + PLLSH_WCS_PLL_Q_FACTOR_CFG_2_MASK); /* first the 16 lower bits */ - ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_P_FACTOR_CFG_1, - wl18xx_clk_table[clk_freq].p & - PLLSH_WCS_PLL_P_FACTOR_CFG_1_MASK); - if (ret < 0) - goto out; - + wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_P_FACTOR_CFG_1, + wl18xx_clk_table[clk_freq].p & + PLLSH_WCS_PLL_P_FACTOR_CFG_1_MASK); /* then the 16 higher bits, masked out */ - ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_P_FACTOR_CFG_2, - (wl18xx_clk_table[clk_freq].p >> 16) & - PLLSH_WCS_PLL_P_FACTOR_CFG_2_MASK); + wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_P_FACTOR_CFG_2, + (wl18xx_clk_table[clk_freq].p >> 16) & + PLLSH_WCS_PLL_P_FACTOR_CFG_2_MASK); } else { - ret = wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_SWALLOW_EN, - PLLSH_WCS_PLL_SWALLOW_EN_VAL2); + wl18xx_top_reg_write(wl, PLLSH_WCS_PLL_SWALLOW_EN, + PLLSH_WCS_PLL_SWALLOW_EN_VAL2); } - -out: - return ret; } -static int wl18xx_boot_soft_reset(struct wl1271 *wl) +static void wl18xx_boot_soft_reset(struct wl1271 *wl) { - int ret; - /* disable Rx/Tx */ - ret = wlcore_write32(wl, WL18XX_ENABLE, 0x0); - if (ret < 0) - goto out; + wl1271_write32(wl, WL18XX_ENABLE, 0x0); /* disable auto calibration on start*/ - ret = wlcore_write32(wl, WL18XX_SPARE_A2, 0xffff); - -out: - return ret; + wl1271_write32(wl, WL18XX_SPARE_A2, 0xffff); } static int wl18xx_pre_boot(struct wl1271 *wl) { - int ret; - - ret = wl18xx_set_clk(wl); - if (ret < 0) - goto out; + wl18xx_set_clk(wl); /* Continue the ELP wake up sequence */ - ret = wlcore_write32(wl, WL18XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL); - if (ret < 0) - goto out; - + wl1271_write32(wl, WL18XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL); udelay(500); - ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); - if (ret < 0) - goto out; + wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); /* Disable interrupts */ - ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL); - if (ret < 0) - goto out; + wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL); - ret = wl18xx_boot_soft_reset(wl); + wl18xx_boot_soft_reset(wl); -out: - return ret; + return 0; } -static int wl18xx_pre_upload(struct wl1271 *wl) +static void wl18xx_pre_upload(struct wl1271 *wl) { u32 tmp; - int ret; - ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); - if (ret < 0) - goto out; + wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); /* TODO: check if this is all needed */ - ret = wlcore_write32(wl, WL18XX_EEPROMLESS_IND, WL18XX_EEPROMLESS_IND); - if (ret < 0) - goto out; + wl1271_write32(wl, WL18XX_EEPROMLESS_IND, WL18XX_EEPROMLESS_IND); - ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &tmp); - if (ret < 0) - goto out; + tmp = wlcore_read_reg(wl, REG_CHIP_ID_B); wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp); - ret = wlcore_read32(wl, WL18XX_SCR_PAD2, &tmp); - -out: - return ret; + tmp = wl1271_read32(wl, WL18XX_SCR_PAD2); } -static int wl18xx_set_mac_and_phy(struct wl1271 *wl) +static void wl18xx_set_mac_and_phy(struct wl1271 *wl) { struct wl18xx_priv *priv = wl->priv; - int ret; - - ret = wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]); - if (ret < 0) - goto out; + size_t len; - ret = wlcore_write(wl, WL18XX_PHY_INIT_MEM_ADDR, (u8 *)&priv->conf.phy, - sizeof(struct wl18xx_mac_and_phy_params), false); + /* the parameters struct is smaller for PG1 */ + if (wl->chip.id == CHIP_ID_185x_PG10) + len = offsetof(struct wl18xx_mac_and_phy_params, psat) + 1; + else + len = sizeof(struct wl18xx_mac_and_phy_params); -out: - return ret; + wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]); + wl1271_write(wl, WL18XX_PHY_INIT_MEM_ADDR, (u8 *)&priv->conf.phy, len, + false); } -static int wl18xx_enable_interrupts(struct wl1271 *wl) +static void wl18xx_enable_interrupts(struct wl1271 *wl) { u32 event_mask, intr_mask; - int ret; - event_mask = WL18XX_ACX_EVENTS_VECTOR; - intr_mask = WL18XX_INTR_MASK; + if (wl->chip.id == CHIP_ID_185x_PG10) { + event_mask = WL18XX_ACX_EVENTS_VECTOR_PG1; + intr_mask = WL18XX_INTR_MASK_PG1; + } else { + event_mask = WL18XX_ACX_EVENTS_VECTOR_PG2; + intr_mask = WL18XX_INTR_MASK_PG2; + } - ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, event_mask); - if (ret < 0) - goto out; + wlcore_write_reg(wl, REG_INTERRUPT_MASK, event_mask); wlcore_enable_interrupts(wl); - - ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, - WL1271_ACX_INTR_ALL & ~intr_mask); - -out: - return ret; + wlcore_write_reg(wl, REG_INTERRUPT_MASK, + WL1271_ACX_INTR_ALL & ~intr_mask); } static int wl18xx_boot(struct wl1271 *wl) @@ -809,29 +761,25 @@ static int wl18xx_boot(struct wl1271 *wl) if (ret < 0) goto out; - ret = wl18xx_pre_upload(wl); - if (ret < 0) - goto out; + wl18xx_pre_upload(wl); ret = wlcore_boot_upload_firmware(wl); if (ret < 0) goto out; - ret = wl18xx_set_mac_and_phy(wl); - if (ret < 0) - goto out; + wl18xx_set_mac_and_phy(wl); ret = wlcore_boot_run_firmware(wl); if (ret < 0) goto out; - ret = wl18xx_enable_interrupts(wl); + wl18xx_enable_interrupts(wl); out: return ret; } -static int wl18xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr, +static void wl18xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr, void *buf, size_t len) { struct wl18xx_priv *priv = wl->priv; @@ -839,14 +787,13 @@ static int wl18xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr, memcpy(priv->cmd_buf, buf, len); memset(priv->cmd_buf + len, 0, WL18XX_CMD_MAX_SIZE - len); - return wlcore_write(wl, cmd_box_addr, priv->cmd_buf, - WL18XX_CMD_MAX_SIZE, false); + wl1271_write(wl, cmd_box_addr, priv->cmd_buf, WL18XX_CMD_MAX_SIZE, + false); } -static int wl18xx_ack_event(struct wl1271 *wl) +static void wl18xx_ack_event(struct wl1271 *wl) { - return wlcore_write_reg(wl, REG_INTERRUPT_TRIG, - WL18XX_INTR_TRIG_EVENT_ACK); + wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL18XX_INTR_TRIG_EVENT_ACK); } static u32 wl18xx_calc_tx_blocks(struct wl1271 *wl, u32 len, u32 spare_blks) @@ -1028,32 +975,34 @@ static u32 wl18xx_ap_get_mimo_wide_rate_mask(struct wl1271 *wl, } else if (!strcmp(ht_mode_param, "mimo")) { wl1271_debug(DEBUG_ACX, "using MIMO rate mask"); + /* + * PG 1.0 has some problems with MCS_13, so disable it + * + * TODO: instead of hacking this in here, we should + * make it more general and change a bit in the + * wlvif->rate_set instead. + */ + if (wl->chip.id == CHIP_ID_185x_PG10) + return CONF_TX_MIMO_RATES & ~CONF_HW_BIT_RATE_MCS_13; + return CONF_TX_MIMO_RATES; } else { return 0; } } -static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver) +static s8 wl18xx_get_pg_ver(struct wl1271 *wl) { u32 fuse; - int ret; - ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); - if (ret < 0) - goto out; - - ret = wlcore_read32(wl, WL18XX_REG_FUSE_DATA_1_3, &fuse); - if (ret < 0) - goto out; + wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); - if (ver) - *ver = (fuse & WL18XX_PG_VER_MASK) >> WL18XX_PG_VER_OFFSET; + fuse = wl1271_read32(wl, WL18XX_REG_FUSE_DATA_1_3); + fuse = (fuse & WL18XX_PG_VER_MASK) >> WL18XX_PG_VER_OFFSET; - ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); + wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); -out: - return ret; + return (s8)fuse; } #define WL18XX_CONF_FILE_NAME "ti-connectivity/wl18xx-conf.bin" @@ -1072,7 +1021,8 @@ static int wl18xx_conf_init(struct wl1271 *wl, struct device *dev) } if (fw->size != WL18XX_CONF_SIZE) { - wl1271_error("configuration binary file size is wrong, expected %zu got %zu", + wl1271_error("configuration binary file size is wrong, " + "expected %ld got %zd", WL18XX_CONF_SIZE, fw->size); ret = -EINVAL; goto out; @@ -1119,41 +1069,26 @@ static int wl18xx_conf_init(struct wl1271 *wl, struct device *dev) static int wl18xx_plt_init(struct wl1271 *wl) { - int ret; - - ret = wlcore_write32(wl, WL18XX_SCR_PAD8, WL18XX_SCR_PAD8_PLT); - if (ret < 0) - return ret; + wl1271_write32(wl, WL18XX_SCR_PAD8, WL18XX_SCR_PAD8_PLT); return wl->ops->boot(wl); } -static int wl18xx_get_mac(struct wl1271 *wl) +static void wl18xx_get_mac(struct wl1271 *wl) { u32 mac1, mac2; - int ret; - - ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); - if (ret < 0) - goto out; - ret = wlcore_read32(wl, WL18XX_REG_FUSE_BD_ADDR_1, &mac1); - if (ret < 0) - goto out; + wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); - ret = wlcore_read32(wl, WL18XX_REG_FUSE_BD_ADDR_2, &mac2); - if (ret < 0) - goto out; + mac1 = wl1271_read32(wl, WL18XX_REG_FUSE_BD_ADDR_1); + mac2 = wl1271_read32(wl, WL18XX_REG_FUSE_BD_ADDR_2); /* these are the two parts of the BD_ADDR */ wl->fuse_oui_addr = ((mac2 & 0xffff) << 8) + ((mac1 & 0xff000000) >> 24); wl->fuse_nic_addr = (mac1 & 0xffffff); - ret = wlcore_set_partition(wl, &wl->ptable[PART_DOWN]); - -out: - return ret; + wlcore_set_partition(wl, &wl->ptable[PART_DOWN]); } static int wl18xx_handle_static_data(struct wl1271 *wl, @@ -1279,8 +1214,8 @@ static struct wlcore_ops wl18xx_ops = { .pre_pkt_send = wl18xx_pre_pkt_send, }; -/* HT cap appropriate for wide channels in 2Ghz */ -static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_2ghz = { +/* HT cap appropriate for wide channels */ +static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap = { .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_DSSSCCK40, .ht_supported = true, @@ -1293,42 +1228,40 @@ static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_2ghz = { }, }; -/* HT cap appropriate for wide channels in 5Ghz */ -static struct ieee80211_sta_ht_cap wl18xx_siso40_ht_cap_5ghz = { - .cap = IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | - IEEE80211_HT_CAP_SUP_WIDTH_20_40, +/* HT cap appropriate for SISO 20 */ +static struct ieee80211_sta_ht_cap wl18xx_siso20_ht_cap = { + .cap = IEEE80211_HT_CAP_SGI_20, .ht_supported = true, .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, .mcs = { .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, - .rx_highest = cpu_to_le16(150), + .rx_highest = cpu_to_le16(72), .tx_params = IEEE80211_HT_MCS_TX_DEFINED, }, }; -/* HT cap appropriate for SISO 20 */ -static struct ieee80211_sta_ht_cap wl18xx_siso20_ht_cap = { +/* HT cap appropriate for MIMO rates in 20mhz channel */ +static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap_2ghz = { .cap = IEEE80211_HT_CAP_SGI_20, .ht_supported = true, .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, .mcs = { - .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, - .rx_highest = cpu_to_le16(72), + .rx_mask = { 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, }, + .rx_highest = cpu_to_le16(144), .tx_params = IEEE80211_HT_MCS_TX_DEFINED, }, }; -/* HT cap appropriate for MIMO rates in 20mhz channel */ -static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap_2ghz = { +static struct ieee80211_sta_ht_cap wl18xx_mimo_ht_cap_5ghz = { .cap = IEEE80211_HT_CAP_SGI_20, .ht_supported = true, .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K, .ampdu_density = IEEE80211_HT_MPDU_DENSITY_16, .mcs = { - .rx_mask = { 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, }, - .rx_highest = cpu_to_le16(144), + .rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, + .rx_highest = cpu_to_le16(72), .tx_params = IEEE80211_HT_MCS_TX_DEFINED, }, }; @@ -1353,7 +1286,7 @@ static int __devinit wl18xx_probe(struct platform_device *pdev) wl->ptable = wl18xx_ptable; wl->rtable = wl18xx_rtable; wl->num_tx_desc = 32; - wl->num_rx_desc = 32; + wl->num_rx_desc = 16; wl->band_rate_to_idx = wl18xx_band_rate_to_idx; wl->hw_tx_rate_tbl_size = WL18XX_CONF_HW_RXTX_RATE_MAX; wl->hw_min_ht_rate = WL18XX_CONF_HW_RXTX_RATE_MCS0; @@ -1361,8 +1294,32 @@ static int __devinit wl18xx_probe(struct platform_device *pdev) wl->stats.fw_stats_len = sizeof(struct wl18xx_acx_statistics); wl->static_data_priv_len = sizeof(struct wl18xx_static_data_priv); - if (num_rx_desc_param != -1) - wl->num_rx_desc = num_rx_desc_param; + if (!strcmp(ht_mode_param, "wide")) { + memcpy(&wl->ht_cap[IEEE80211_BAND_2GHZ], + &wl18xx_siso40_ht_cap, + sizeof(wl18xx_siso40_ht_cap)); + memcpy(&wl->ht_cap[IEEE80211_BAND_5GHZ], + &wl18xx_siso40_ht_cap, + sizeof(wl18xx_siso40_ht_cap)); + } else if (!strcmp(ht_mode_param, "mimo")) { + memcpy(&wl->ht_cap[IEEE80211_BAND_2GHZ], + &wl18xx_mimo_ht_cap_2ghz, + sizeof(wl18xx_mimo_ht_cap_2ghz)); + memcpy(&wl->ht_cap[IEEE80211_BAND_5GHZ], + &wl18xx_mimo_ht_cap_5ghz, + sizeof(wl18xx_mimo_ht_cap_5ghz)); + } else if (!strcmp(ht_mode_param, "siso20")) { + memcpy(&wl->ht_cap[IEEE80211_BAND_2GHZ], + &wl18xx_siso20_ht_cap, + sizeof(wl18xx_siso20_ht_cap)); + memcpy(&wl->ht_cap[IEEE80211_BAND_5GHZ], + &wl18xx_siso20_ht_cap, + sizeof(wl18xx_siso20_ht_cap)); + } else { + wl1271_error("invalid ht_mode '%s'", ht_mode_param); + ret = -EINVAL; + goto out_free; + } ret = wl18xx_conf_init(wl, &pdev->dev); if (ret < 0) @@ -1409,37 +1366,6 @@ static int __devinit wl18xx_probe(struct platform_device *pdev) if (dc2dc_param != -1) priv->conf.phy.external_pa_dc2dc = dc2dc_param; - if (!strcmp(ht_mode_param, "default")) { - /* - * Only support mimo with multiple antennas. Fall back to - * siso20. - */ - if (priv->conf.phy.number_of_assembled_ant2_4 >= 2) - wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, - &wl18xx_mimo_ht_cap_2ghz); - else - wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, - &wl18xx_siso20_ht_cap); - - /* 5Ghz is always wide */ - wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, - &wl18xx_siso40_ht_cap_5ghz); - } else if (!strcmp(ht_mode_param, "wide")) { - wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, - &wl18xx_siso40_ht_cap_2ghz); - wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, - &wl18xx_siso40_ht_cap_5ghz); - } else if (!strcmp(ht_mode_param, "siso20")) { - wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, - &wl18xx_siso20_ht_cap); - wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, - &wl18xx_siso20_ht_cap); - } else { - wl1271_error("invalid ht_mode '%s'", ht_mode_param); - ret = -EINVAL; - goto out_free; - } - if (!checksum_param) { wl18xx_ops.set_rx_csum = NULL; wl18xx_ops.init_vif = NULL; @@ -1484,7 +1410,7 @@ static void __exit wl18xx_exit(void) module_exit(wl18xx_exit); module_param_named(ht_mode, ht_mode_param, charp, S_IRUSR); -MODULE_PARM_DESC(ht_mode, "Force HT mode: wide or siso20"); +MODULE_PARM_DESC(ht_mode, "Force HT mode: wide (default), mimo or siso20"); module_param_named(board_type, board_type_param, charp, S_IRUSR); MODULE_PARM_DESC(board_type, "Board type: fpga, hdk (default), evb, com8 or " @@ -1532,11 +1458,6 @@ module_param_named(pwr_limit_reference_11_abg, MODULE_PARM_DESC(pwr_limit_reference_11_abg, "Power limit reference: u8 " "(default is 0xc8)"); -module_param_named(num_rx_desc, - num_rx_desc_param, int, S_IRUSR); -MODULE_PARM_DESC(num_rx_desc_param, - "Number of Rx descriptors: u8 (default is 32)"); - MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Luciano Coelho "); MODULE_FIRMWARE(WL18XX_FW_NAME); diff --git a/trunk/drivers/net/wireless/ti/wlcore/Kconfig b/trunk/drivers/net/wireless/ti/wlcore/Kconfig index d7b907e67170..54156b0b5c2d 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/Kconfig +++ b/trunk/drivers/net/wireless/ti/wlcore/Kconfig @@ -1,6 +1,7 @@ config WLCORE tristate "TI wlcore support" depends on WL_TI && GENERIC_HARDIRQS && MAC80211 + depends on INET select FW_LOADER ---help--- This module contains the main code for TI WLAN chips. It abstracts diff --git a/trunk/drivers/net/wireless/ti/wlcore/acx.c b/trunk/drivers/net/wireless/ti/wlcore/acx.c index ce108a736bd0..b9ec42c83757 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/acx.c +++ b/trunk/drivers/net/wireless/ti/wlcore/acx.c @@ -70,7 +70,7 @@ int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth) struct acx_sleep_auth *auth; int ret; - wl1271_debug(DEBUG_ACX, "acx sleep auth %d", sleep_auth); + wl1271_debug(DEBUG_ACX, "acx sleep auth"); auth = kzalloc(sizeof(*auth), GFP_KERNEL); if (!auth) { @@ -81,13 +81,7 @@ int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth) auth->sleep_auth = sleep_auth; ret = wl1271_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth)); - if (ret < 0) { - wl1271_error("could not configure sleep_auth to %d: %d", - sleep_auth, ret); - goto out; - } - wl->sleep_auth = sleep_auth; out: kfree(auth); return ret; diff --git a/trunk/drivers/net/wireless/ti/wlcore/acx.h b/trunk/drivers/net/wireless/ti/wlcore/acx.h index d03215d6b3bd..c0181258b722 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/acx.h +++ b/trunk/drivers/net/wireless/ti/wlcore/acx.h @@ -118,11 +118,6 @@ enum wl1271_psm_mode { /* Extreme low power */ WL1271_PSM_ELP = 2, - - WL1271_PSM_MAX = WL1271_PSM_ELP, - - /* illegal out of band value of PSM mode */ - WL1271_PSM_ILLEGAL = 0xff }; struct acx_sleep_auth { diff --git a/trunk/drivers/net/wireless/ti/wlcore/boot.c b/trunk/drivers/net/wireless/ti/wlcore/boot.c index 8965960b841a..0fda500c01c9 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/boot.c +++ b/trunk/drivers/net/wireless/ti/wlcore/boot.c @@ -33,22 +33,16 @@ #include "rx.h" #include "hw_ops.h" -static int wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag) +static void wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag) { u32 cpu_ctrl; - int ret; /* 10.5.0 run the firmware (I) */ - ret = wlcore_read_reg(wl, REG_ECPU_CONTROL, &cpu_ctrl); - if (ret < 0) - goto out; + cpu_ctrl = wlcore_read_reg(wl, REG_ECPU_CONTROL); /* 10.5.1 run the firmware (II) */ cpu_ctrl |= flag; - ret = wlcore_write_reg(wl, REG_ECPU_CONTROL, cpu_ctrl); - -out: - return ret; + wlcore_write_reg(wl, REG_ECPU_CONTROL, cpu_ctrl); } static int wlcore_boot_parse_fw_ver(struct wl1271 *wl, @@ -93,9 +87,7 @@ static int wlcore_boot_static_data(struct wl1271 *wl) goto out; } - ret = wlcore_read(wl, wl->cmd_box_addr, static_data, len, false); - if (ret < 0) - goto out_free; + wl1271_read(wl, wl->cmd_box_addr, static_data, len, false); ret = wlcore_boot_parse_fw_ver(wl, static_data); if (ret < 0) @@ -117,7 +109,6 @@ static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf, struct wlcore_partition_set partition; int addr, chunk_num, partition_limit; u8 *p, *chunk; - int ret; /* whal_FwCtrl_LoadFwImageSm() */ @@ -139,9 +130,7 @@ static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf, memcpy(&partition, &wl->ptable[PART_DOWN], sizeof(partition)); partition.mem.start = dest; - ret = wlcore_set_partition(wl, &partition); - if (ret < 0) - return ret; + wlcore_set_partition(wl, &partition); /* 10.1 set partition limit and chunk num */ chunk_num = 0; @@ -155,9 +144,7 @@ static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf, partition_limit = chunk_num * CHUNK_SIZE + wl->ptable[PART_DOWN].mem.size; partition.mem.start = addr; - ret = wlcore_set_partition(wl, &partition); - if (ret < 0) - return ret; + wlcore_set_partition(wl, &partition); } /* 10.3 upload the chunk */ @@ -166,9 +153,7 @@ static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf, memcpy(chunk, p, CHUNK_SIZE); wl1271_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x", p, addr); - ret = wlcore_write(wl, addr, chunk, CHUNK_SIZE, false); - if (ret < 0) - goto out; + wl1271_write(wl, addr, chunk, CHUNK_SIZE, false); chunk_num++; } @@ -179,11 +164,10 @@ static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf, memcpy(chunk, p, fw_data_len % CHUNK_SIZE); wl1271_debug(DEBUG_BOOT, "uploading fw last chunk (%zd B) 0x%p to 0x%x", fw_data_len % CHUNK_SIZE, p, addr); - ret = wlcore_write(wl, addr, chunk, fw_data_len % CHUNK_SIZE, false); + wl1271_write(wl, addr, chunk, fw_data_len % CHUNK_SIZE, false); -out: kfree(chunk); - return ret; + return 0; } int wlcore_boot_upload_firmware(struct wl1271 *wl) @@ -226,7 +210,6 @@ int wlcore_boot_upload_nvs(struct wl1271 *wl) int i; u32 dest_addr, val; u8 *nvs_ptr, *nvs_aligned; - int ret; if (wl->nvs == NULL) { wl1271_error("NVS file is needed during boot"); @@ -324,9 +307,7 @@ int wlcore_boot_upload_nvs(struct wl1271 *wl) wl1271_debug(DEBUG_BOOT, "nvs burst write 0x%x: 0x%x", dest_addr, val); - ret = wlcore_write32(wl, dest_addr, val); - if (ret < 0) - return ret; + wl1271_write32(wl, dest_addr, val); nvs_ptr += 4; dest_addr += 4; @@ -352,9 +333,7 @@ int wlcore_boot_upload_nvs(struct wl1271 *wl) nvs_len -= nvs_ptr - (u8 *)wl->nvs; /* Now we must set the partition correctly */ - ret = wlcore_set_partition(wl, &wl->ptable[PART_WORK]); - if (ret < 0) - return ret; + wlcore_set_partition(wl, &wl->ptable[PART_WORK]); /* Copy the NVS tables to a new block to ensure alignment */ nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL); @@ -362,11 +341,11 @@ int wlcore_boot_upload_nvs(struct wl1271 *wl) return -ENOMEM; /* And finally we upload the NVS tables */ - ret = wlcore_write_data(wl, REG_CMD_MBOX_ADDRESS, nvs_aligned, nvs_len, - false); + wlcore_write_data(wl, REG_CMD_MBOX_ADDRESS, + nvs_aligned, nvs_len, false); kfree(nvs_aligned); - return ret; + return 0; out_badnvs: wl1271_error("nvs data is malformed"); @@ -380,17 +359,11 @@ int wlcore_boot_run_firmware(struct wl1271 *wl) u32 chip_id, intr; /* Make sure we have the boot partition */ - ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); - if (ret < 0) - return ret; + wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); - ret = wl1271_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT); - if (ret < 0) - return ret; + wl1271_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT); - ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &chip_id); - if (ret < 0) - return ret; + chip_id = wlcore_read_reg(wl, REG_CHIP_ID_B); wl1271_debug(DEBUG_BOOT, "chip id after firmware boot: 0x%x", chip_id); @@ -403,9 +376,7 @@ int wlcore_boot_run_firmware(struct wl1271 *wl) loop = 0; while (loop++ < INIT_LOOP) { udelay(INIT_LOOP_DELAY); - ret = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR, &intr); - if (ret < 0) - return ret; + intr = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR); if (intr == 0xffffffff) { wl1271_error("error reading hardware complete " @@ -414,10 +385,8 @@ int wlcore_boot_run_firmware(struct wl1271 *wl) } /* check that ACX_INTR_INIT_COMPLETE is enabled */ else if (intr & WL1271_ACX_INTR_INIT_COMPLETE) { - ret = wlcore_write_reg(wl, REG_INTERRUPT_ACK, - WL1271_ACX_INTR_INIT_COMPLETE); - if (ret < 0) - return ret; + wlcore_write_reg(wl, REG_INTERRUPT_ACK, + WL1271_ACX_INTR_INIT_COMPLETE); break; } } @@ -429,17 +398,12 @@ int wlcore_boot_run_firmware(struct wl1271 *wl) } /* get hardware config command mail box */ - ret = wlcore_read_reg(wl, REG_COMMAND_MAILBOX_PTR, &wl->cmd_box_addr); - if (ret < 0) - return ret; + wl->cmd_box_addr = wlcore_read_reg(wl, REG_COMMAND_MAILBOX_PTR); wl1271_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x", wl->cmd_box_addr); /* get hardware config event mail box */ - ret = wlcore_read_reg(wl, REG_EVENT_MAILBOX_PTR, &wl->mbox_ptr[0]); - if (ret < 0) - return ret; - + wl->mbox_ptr[0] = wlcore_read_reg(wl, REG_EVENT_MAILBOX_PTR); wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox); wl1271_debug(DEBUG_MAILBOX, "MBOX ptrs: 0x%x 0x%x", @@ -481,9 +445,9 @@ int wlcore_boot_run_firmware(struct wl1271 *wl) } /* set the working partition to its "running" mode offset */ - ret = wlcore_set_partition(wl, &wl->ptable[PART_WORK]); + wlcore_set_partition(wl, &wl->ptable[PART_WORK]); /* firmware startup completed */ - return ret; + return 0; } EXPORT_SYMBOL_GPL(wlcore_boot_run_firmware); diff --git a/trunk/drivers/net/wireless/ti/wlcore/cmd.c b/trunk/drivers/net/wireless/ti/wlcore/cmd.c index 56c7a2342fdf..885364ca4344 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/cmd.c +++ b/trunk/drivers/net/wireless/ti/wlcore/cmd.c @@ -65,24 +65,17 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, WARN_ON(len % 4 != 0); WARN_ON(test_bit(WL1271_FLAG_IN_ELP, &wl->flags)); - ret = wlcore_write(wl, wl->cmd_box_addr, buf, len, false); - if (ret < 0) - goto fail; + wl1271_write(wl, wl->cmd_box_addr, buf, len, false); /* * TODO: we just need this because one bit is in a different * place. Is there any better way? */ - ret = wl->ops->trigger_cmd(wl, wl->cmd_box_addr, buf, len); - if (ret < 0) - goto fail; + wl->ops->trigger_cmd(wl, wl->cmd_box_addr, buf, len); timeout = jiffies + msecs_to_jiffies(WL1271_COMMAND_TIMEOUT); - ret = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR, &intr); - if (ret < 0) - goto fail; - + intr = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR); while (!(intr & WL1271_ACX_INTR_CMD_COMPLETE)) { if (time_after(jiffies, timeout)) { wl1271_error("command complete timeout"); @@ -96,18 +89,13 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, else msleep(1); - ret = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR, &intr); - if (ret < 0) - goto fail; + intr = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR); } /* read back the status code of the command */ if (res_len == 0) res_len = sizeof(struct wl1271_cmd_header); - - ret = wlcore_read(wl, wl->cmd_box_addr, cmd, res_len, false); - if (ret < 0) - goto fail; + wl1271_read(wl, wl->cmd_box_addr, cmd, res_len, false); status = le16_to_cpu(cmd->status); if (status != CMD_STATUS_SUCCESS) { @@ -116,14 +104,11 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, goto fail; } - ret = wlcore_write_reg(wl, REG_INTERRUPT_ACK, - WL1271_ACX_INTR_CMD_COMPLETE); - if (ret < 0) - goto fail; - + wlcore_write_reg(wl, REG_INTERRUPT_ACK, WL1271_ACX_INTR_CMD_COMPLETE); return 0; fail: + WARN_ON(1); wl12xx_queue_recovery_work(wl); return ret; } @@ -132,45 +117,35 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, * Poll the mailbox event field until any of the bits in the mask is set or a * timeout occurs (WL1271_EVENT_TIMEOUT in msecs) */ -static int wl1271_cmd_wait_for_event_or_timeout(struct wl1271 *wl, - u32 mask, bool *timeout) +static int wl1271_cmd_wait_for_event_or_timeout(struct wl1271 *wl, u32 mask) { u32 *events_vector; u32 event; - unsigned long timeout_time; + unsigned long timeout; int ret = 0; - *timeout = false; - events_vector = kmalloc(sizeof(*events_vector), GFP_KERNEL | GFP_DMA); if (!events_vector) return -ENOMEM; - timeout_time = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT); + timeout = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT); do { - if (time_after(jiffies, timeout_time)) { + if (time_after(jiffies, timeout)) { wl1271_debug(DEBUG_CMD, "timeout waiting for event %d", (int)mask); - *timeout = true; + ret = -ETIMEDOUT; goto out; } msleep(1); /* read from both event fields */ - ret = wlcore_read(wl, wl->mbox_ptr[0], events_vector, - sizeof(*events_vector), false); - if (ret < 0) - goto out; - + wl1271_read(wl, wl->mbox_ptr[0], events_vector, + sizeof(*events_vector), false); event = *events_vector & mask; - - ret = wlcore_read(wl, wl->mbox_ptr[1], events_vector, - sizeof(*events_vector), false); - if (ret < 0) - goto out; - + wl1271_read(wl, wl->mbox_ptr[1], events_vector, + sizeof(*events_vector), false); event |= *events_vector & mask; } while (!event); @@ -182,10 +157,9 @@ static int wl1271_cmd_wait_for_event_or_timeout(struct wl1271 *wl, static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask) { int ret; - bool timeout = false; - ret = wl1271_cmd_wait_for_event_or_timeout(wl, mask, &timeout); - if (ret != 0 || timeout) { + ret = wl1271_cmd_wait_for_event_or_timeout(wl, mask); + if (ret != 0) { wl12xx_queue_recovery_work(wl); return ret; } @@ -1438,7 +1412,6 @@ int wl12xx_cmd_remove_peer(struct wl1271 *wl, u8 hlid) { struct wl12xx_cmd_remove_peer *cmd; int ret; - bool timeout = false; wl1271_debug(DEBUG_CMD, "cmd remove peer %d", (int)hlid); @@ -1459,16 +1432,12 @@ int wl12xx_cmd_remove_peer(struct wl1271 *wl, u8 hlid) goto out_free; } - ret = wl1271_cmd_wait_for_event_or_timeout(wl, - PEER_REMOVE_COMPLETE_EVENT_ID, - &timeout); /* * We are ok with a timeout here. The event is sometimes not sent - * due to a firmware bug. In case of another error (like SDIO timeout) - * queue a recovery. + * due to a firmware bug. */ - if (ret) - wl12xx_queue_recovery_work(wl); + wl1271_cmd_wait_for_event_or_timeout(wl, + PEER_REMOVE_COMPLETE_EVENT_ID); out_free: kfree(cmd); @@ -1785,9 +1754,7 @@ int wl12xx_stop_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif) return -EINVAL; /* flush all pending packets */ - ret = wlcore_tx_work_locked(wl); - if (ret < 0) - goto out; + wl1271_tx_work_locked(wl); if (test_bit(wlvif->dev_role_id, wl->roc_map)) { ret = wl12xx_croc(wl, wlvif->dev_role_id); diff --git a/trunk/drivers/net/wireless/ti/wlcore/cmd.h b/trunk/drivers/net/wireless/ti/wlcore/cmd.h index c8a6510c72cb..85171f2bf68e 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/cmd.h +++ b/trunk/drivers/net/wireless/ti/wlcore/cmd.h @@ -652,25 +652,4 @@ struct wl12xx_cmd_stop_channel_switch { struct wl1271_cmd_header header; } __packed; -/* Used to check radio status after calibration */ -#define MAX_TLV_LENGTH 500 -#define TEST_CMD_P2G_CAL 2 /* TX BiP */ - -struct wl1271_cmd_cal_p2g { - struct wl1271_cmd_header header; - - struct wl1271_cmd_test_header test; - - __le32 ver; - __le16 len; - u8 buf[MAX_TLV_LENGTH]; - u8 type; - u8 padding; - - __le16 radio_status; - - u8 sub_band_mask; - u8 padding2; -} __packed; - #endif /* __WL1271_CMD_H__ */ diff --git a/trunk/drivers/net/wireless/ti/wlcore/conf.h b/trunk/drivers/net/wireless/ti/wlcore/conf.h index d77224f2ac6b..03c635872335 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/conf.h +++ b/trunk/drivers/net/wireless/ti/wlcore/conf.h @@ -951,12 +951,6 @@ struct conf_conn_settings { * Range: u16 */ u8 max_listen_interval; - - /* - * Default sleep authorization for a new STA interface. This determines - * whether we can go to ELP. - */ - u8 sta_sleep_auth; } __packed; enum { @@ -1282,7 +1276,7 @@ struct conf_hangover_settings { * version, the two LSB are the lower driver's private conf * version. */ -#define WLCORE_CONF_VERSION (0x0002 << 16) +#define WLCORE_CONF_VERSION (0x0001 << 16) #define WLCORE_CONF_MASK 0xffff0000 #define WLCORE_CONF_SIZE (sizeof(struct wlcore_conf_header) + \ sizeof(struct wlcore_conf)) diff --git a/trunk/drivers/net/wireless/ti/wlcore/debugfs.c b/trunk/drivers/net/wireless/ti/wlcore/debugfs.c index 80dbc5304fac..689a847005c9 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/debugfs.c +++ b/trunk/drivers/net/wireless/ti/wlcore/debugfs.c @@ -38,8 +38,6 @@ /* ms */ #define WL1271_DEBUGFS_STATS_LIFETIME 1000 -#define WLCORE_MAX_BLOCK_SIZE ((size_t)(4*PAGE_SIZE)) - /* debugfs macros idea from mac80211 */ int wl1271_format_buffer(char __user *userbuf, size_t count, loff_t *ppos, char *fmt, ...) @@ -965,257 +963,6 @@ static const struct file_operations fw_stats_raw_ops = { .llseek = default_llseek, }; -static ssize_t sleep_auth_read(struct file *file, char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct wl1271 *wl = file->private_data; - - return wl1271_format_buffer(user_buf, count, - ppos, "%d\n", - wl->sleep_auth); -} - -static ssize_t sleep_auth_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct wl1271 *wl = file->private_data; - unsigned long value; - int ret; - - ret = kstrtoul_from_user(user_buf, count, 0, &value); - if (ret < 0) { - wl1271_warning("illegal value in sleep_auth"); - return -EINVAL; - } - - if (value < 0 || value > WL1271_PSM_MAX) { - wl1271_warning("sleep_auth must be between 0 and %d", - WL1271_PSM_MAX); - return -ERANGE; - } - - mutex_lock(&wl->mutex); - - wl->conf.conn.sta_sleep_auth = value; - - if (wl->state == WL1271_STATE_OFF) { - /* this will show up on "read" in case we are off */ - wl->sleep_auth = value; - goto out; - } - - ret = wl1271_ps_elp_wakeup(wl); - if (ret < 0) - goto out; - - ret = wl1271_acx_sleep_auth(wl, value); - if (ret < 0) - goto out_sleep; - -out_sleep: - wl1271_ps_elp_sleep(wl); -out: - mutex_unlock(&wl->mutex); - return count; -} - -static const struct file_operations sleep_auth_ops = { - .read = sleep_auth_read, - .write = sleep_auth_write, - .open = simple_open, - .llseek = default_llseek, -}; - -static ssize_t dev_mem_read(struct file *file, - char __user *user_buf, size_t count, - loff_t *ppos) -{ - struct wl1271 *wl = file->private_data; - struct wlcore_partition_set part, old_part; - size_t bytes = count; - int ret; - char *buf; - - /* only requests of dword-aligned size and offset are supported */ - if (bytes % 4) - return -EINVAL; - - if (*ppos % 4) - return -EINVAL; - - /* function should return in reasonable time */ - bytes = min(bytes, WLCORE_MAX_BLOCK_SIZE); - - if (bytes == 0) - return -EINVAL; - - memset(&part, 0, sizeof(part)); - part.mem.start = file->f_pos; - part.mem.size = bytes; - - buf = kmalloc(bytes, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - mutex_lock(&wl->mutex); - - if (wl->state == WL1271_STATE_OFF) { - ret = -EFAULT; - goto skip_read; - } - - ret = wl1271_ps_elp_wakeup(wl); - if (ret < 0) - goto skip_read; - - /* store current partition and switch partition */ - memcpy(&old_part, &wl->curr_part, sizeof(old_part)); - ret = wlcore_set_partition(wl, &part); - if (ret < 0) - goto part_err; - - ret = wlcore_raw_read(wl, 0, buf, bytes, false); - if (ret < 0) - goto read_err; - -read_err: - /* recover partition */ - ret = wlcore_set_partition(wl, &old_part); - if (ret < 0) - goto part_err; - -part_err: - wl1271_ps_elp_sleep(wl); - -skip_read: - mutex_unlock(&wl->mutex); - - if (ret == 0) { - ret = copy_to_user(user_buf, buf, bytes); - if (ret < bytes) { - bytes -= ret; - *ppos += bytes; - ret = 0; - } else { - ret = -EFAULT; - } - } - - kfree(buf); - - return ((ret == 0) ? bytes : ret); -} - -static ssize_t dev_mem_write(struct file *file, const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct wl1271 *wl = file->private_data; - struct wlcore_partition_set part, old_part; - size_t bytes = count; - int ret; - char *buf; - - /* only requests of dword-aligned size and offset are supported */ - if (bytes % 4) - return -EINVAL; - - if (*ppos % 4) - return -EINVAL; - - /* function should return in reasonable time */ - bytes = min(bytes, WLCORE_MAX_BLOCK_SIZE); - - if (bytes == 0) - return -EINVAL; - - memset(&part, 0, sizeof(part)); - part.mem.start = file->f_pos; - part.mem.size = bytes; - - buf = kmalloc(bytes, GFP_KERNEL); - if (!buf) - return -ENOMEM; - - ret = copy_from_user(buf, user_buf, bytes); - if (ret) { - ret = -EFAULT; - goto err_out; - } - - mutex_lock(&wl->mutex); - - if (wl->state == WL1271_STATE_OFF) { - ret = -EFAULT; - goto skip_write; - } - - ret = wl1271_ps_elp_wakeup(wl); - if (ret < 0) - goto skip_write; - - /* store current partition and switch partition */ - memcpy(&old_part, &wl->curr_part, sizeof(old_part)); - ret = wlcore_set_partition(wl, &part); - if (ret < 0) - goto part_err; - - ret = wlcore_raw_write(wl, 0, buf, bytes, false); - if (ret < 0) - goto write_err; - -write_err: - /* recover partition */ - ret = wlcore_set_partition(wl, &old_part); - if (ret < 0) - goto part_err; - -part_err: - wl1271_ps_elp_sleep(wl); - -skip_write: - mutex_unlock(&wl->mutex); - - if (ret == 0) - *ppos += bytes; - -err_out: - kfree(buf); - - return ((ret == 0) ? bytes : ret); -} - -static loff_t dev_mem_seek(struct file *file, loff_t offset, int orig) -{ - loff_t ret; - - /* only requests of dword-aligned size and offset are supported */ - if (offset % 4) - return -EINVAL; - - switch (orig) { - case SEEK_SET: - file->f_pos = offset; - ret = file->f_pos; - break; - case SEEK_CUR: - file->f_pos += offset; - ret = file->f_pos; - break; - default: - ret = -EINVAL; - } - - return ret; -} - -static const struct file_operations dev_mem_ops = { - .open = simple_open, - .read = dev_mem_read, - .write = dev_mem_write, - .llseek = dev_mem_seek, -}; - static int wl1271_debugfs_add_files(struct wl1271 *wl, struct dentry *rootdir) { @@ -1241,7 +988,6 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl, DEBUGFS_ADD(irq_blk_threshold, rootdir); DEBUGFS_ADD(irq_timeout, rootdir); DEBUGFS_ADD(fw_stats_raw, rootdir); - DEBUGFS_ADD(sleep_auth, rootdir); streaming = debugfs_create_dir("rx_streaming", rootdir); if (!streaming || IS_ERR(streaming)) @@ -1250,7 +996,6 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl, DEBUGFS_ADD_PREFIX(rx_streaming, interval, streaming); DEBUGFS_ADD_PREFIX(rx_streaming, always, streaming); - DEBUGFS_ADD_PREFIX(dev, mem, rootdir); return 0; diff --git a/trunk/drivers/net/wireless/ti/wlcore/event.c b/trunk/drivers/net/wireless/ti/wlcore/event.c index 48907054d493..c976f0409865 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/event.c +++ b/trunk/drivers/net/wireless/ti/wlcore/event.c @@ -105,7 +105,6 @@ static int wl1271_event_process(struct wl1271 *wl) u32 vector; bool disconnect_sta = false; unsigned long sta_bitmap = 0; - int ret; wl1271_event_mbox_dump(mbox); @@ -229,9 +228,7 @@ static int wl1271_event_process(struct wl1271 *wl) if ((vector & DUMMY_PACKET_EVENT_ID)) { wl1271_debug(DEBUG_EVENT, "DUMMY_PACKET_ID_EVENT_ID"); - ret = wl1271_tx_dummy_packet(wl); - if (ret < 0) - return ret; + wl1271_tx_dummy_packet(wl); } /* @@ -304,10 +301,8 @@ int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num) return -EINVAL; /* first we read the mbox descriptor */ - ret = wlcore_read(wl, wl->mbox_ptr[mbox_num], wl->mbox, - sizeof(*wl->mbox), false); - if (ret < 0) - return ret; + wl1271_read(wl, wl->mbox_ptr[mbox_num], wl->mbox, + sizeof(*wl->mbox), false); /* process the descriptor */ ret = wl1271_event_process(wl); @@ -318,7 +313,7 @@ int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num) * TODO: we just need this because one bit is in a different * place. Is there any better way? */ - ret = wl->ops->ack_event(wl); + wl->ops->ack_event(wl); - return ret; + return 0; } diff --git a/trunk/drivers/net/wireless/ti/wlcore/hw_ops.h b/trunk/drivers/net/wireless/ti/wlcore/hw_ops.h index 2673d783ec1e..9e7787ba9610 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/hw_ops.h +++ b/trunk/drivers/net/wireless/ti/wlcore/hw_ops.h @@ -65,13 +65,11 @@ wlcore_hw_get_rx_buf_align(struct wl1271 *wl, u32 rx_desc) return wl->ops->get_rx_buf_align(wl, rx_desc); } -static inline int +static inline void wlcore_hw_prepare_read(struct wl1271 *wl, u32 rx_desc, u32 len) { if (wl->ops->prepare_read) - return wl->ops->prepare_read(wl, rx_desc, len); - - return 0; + wl->ops->prepare_read(wl, rx_desc, len); } static inline u32 @@ -83,12 +81,10 @@ wlcore_hw_get_rx_packet_len(struct wl1271 *wl, void *rx_data, u32 data_len) return wl->ops->get_rx_packet_len(wl, rx_data, data_len); } -static inline int wlcore_hw_tx_delayed_compl(struct wl1271 *wl) +static inline void wlcore_hw_tx_delayed_compl(struct wl1271 *wl) { if (wl->ops->tx_delayed_compl) - return wl->ops->tx_delayed_compl(wl); - - return 0; + wl->ops->tx_delayed_compl(wl); } static inline void wlcore_hw_tx_immediate_compl(struct wl1271 *wl) diff --git a/trunk/drivers/net/wireless/ti/wlcore/ini.h b/trunk/drivers/net/wireless/ti/wlcore/ini.h index d24fe3bbc672..4cf9ecc56212 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/ini.h +++ b/trunk/drivers/net/wireless/ti/wlcore/ini.h @@ -172,19 +172,7 @@ struct wl128x_ini_fem_params_5 { /* NVS data structure */ #define WL1271_INI_NVS_SECTION_SIZE 468 - -/* We have four FEM module types: 0-RFMD, 1-TQS, 2-SKW, 3-TQS_HP */ -#define WL1271_INI_FEM_MODULE_COUNT 4 - -/* - * In NVS we only store two FEM module entries - - * FEM modules 0,2,3 are stored in entry 0 - * FEM module 1 is stored in entry 1 - */ -#define WL12XX_NVS_FEM_MODULE_COUNT 2 - -#define WL12XX_FEM_TO_NVS_ENTRY(ini_fem_module) \ - ((ini_fem_module) == 1 ? 1 : 0) +#define WL1271_INI_FEM_MODULE_COUNT 2 #define WL1271_INI_LEGACY_NVS_FILE_SIZE 800 @@ -200,13 +188,13 @@ struct wl1271_nvs_file { struct { struct wl1271_ini_fem_params_2 params; u8 padding; - } dyn_radio_params_2[WL12XX_NVS_FEM_MODULE_COUNT]; + } dyn_radio_params_2[WL1271_INI_FEM_MODULE_COUNT]; struct wl1271_ini_band_params_5 stat_radio_params_5; u8 padding3; struct { struct wl1271_ini_fem_params_5 params; u8 padding; - } dyn_radio_params_5[WL12XX_NVS_FEM_MODULE_COUNT]; + } dyn_radio_params_5[WL1271_INI_FEM_MODULE_COUNT]; } __packed; struct wl128x_nvs_file { @@ -221,12 +209,12 @@ struct wl128x_nvs_file { struct { struct wl128x_ini_fem_params_2 params; u8 padding; - } dyn_radio_params_2[WL12XX_NVS_FEM_MODULE_COUNT]; + } dyn_radio_params_2[WL1271_INI_FEM_MODULE_COUNT]; struct wl128x_ini_band_params_5 stat_radio_params_5; u8 padding3; struct { struct wl128x_ini_fem_params_5 params; u8 padding; - } dyn_radio_params_5[WL12XX_NVS_FEM_MODULE_COUNT]; + } dyn_radio_params_5[WL1271_INI_FEM_MODULE_COUNT]; } __packed; #endif diff --git a/trunk/drivers/net/wireless/ti/wlcore/init.c b/trunk/drivers/net/wireless/ti/wlcore/init.c index 8a8a8971befa..645abd4b660d 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/init.c +++ b/trunk/drivers/net/wireless/ti/wlcore/init.c @@ -554,28 +554,29 @@ int wl1271_init_vif_specific(struct wl1271 *wl, struct ieee80211_vif *vif) bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS); int ret, i; - /* consider all existing roles before configuring psm. */ - - if (wl->ap_count == 0 && is_ap) { /* first AP */ - /* Configure for power always on */ - ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); - if (ret < 0) - return ret; - /* first STA, no APs */ - } else if (wl->sta_count == 0 && wl->ap_count == 0 && !is_ap) { - u8 sta_auth = wl->conf.conn.sta_sleep_auth; - /* Configure for power according to debugfs */ - if (sta_auth != WL1271_PSM_ILLEGAL) - ret = wl1271_acx_sleep_auth(wl, sta_auth); - /* Configure for power always on */ - else if (wl->quirks & WLCORE_QUIRK_NO_ELP) + /* + * consider all existing roles before configuring psm. + * TODO: reconfigure on interface removal. + */ + if (!wl->ap_count) { + if (is_ap) { + /* Configure for power always on */ ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); - /* Configure for ELP power saving */ - else - ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP); - - if (ret < 0) - return ret; + if (ret < 0) + return ret; + } else if (!wl->sta_count) { + if (wl->quirks & WLCORE_QUIRK_NO_ELP) { + /* Configure for power always on */ + ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); + if (ret < 0) + return ret; + } else { + /* Configure for ELP power saving */ + ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP); + if (ret < 0) + return ret; + } + } } /* Mode specific init */ diff --git a/trunk/drivers/net/wireless/ti/wlcore/io.c b/trunk/drivers/net/wireless/ti/wlcore/io.c index 9976219c4e49..7cd0081aede5 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/io.c +++ b/trunk/drivers/net/wireless/ti/wlcore/io.c @@ -48,12 +48,6 @@ void wlcore_disable_interrupts(struct wl1271 *wl) } EXPORT_SYMBOL_GPL(wlcore_disable_interrupts); -void wlcore_disable_interrupts_nosync(struct wl1271 *wl) -{ - disable_irq_nosync(wl->irq); -} -EXPORT_SYMBOL_GPL(wlcore_disable_interrupts_nosync); - void wlcore_enable_interrupts(struct wl1271 *wl) { enable_irq(wl->irq); @@ -128,11 +122,9 @@ EXPORT_SYMBOL_GPL(wlcore_translate_addr); * | | * */ -int wlcore_set_partition(struct wl1271 *wl, - const struct wlcore_partition_set *p) +void wlcore_set_partition(struct wl1271 *wl, + const struct wlcore_partition_set *p) { - int ret; - /* copy partition info */ memcpy(&wl->curr_part, p, sizeof(*p)); @@ -145,42 +137,29 @@ int wlcore_set_partition(struct wl1271 *wl, wl1271_debug(DEBUG_IO, "mem3_start %08X mem3_size %08X", p->mem3.start, p->mem3.size); - ret = wlcore_raw_write32(wl, HW_PART0_START_ADDR, p->mem.start); - if (ret < 0) - goto out; - - ret = wlcore_raw_write32(wl, HW_PART0_SIZE_ADDR, p->mem.size); - if (ret < 0) - goto out; - - ret = wlcore_raw_write32(wl, HW_PART1_START_ADDR, p->reg.start); - if (ret < 0) - goto out; - - ret = wlcore_raw_write32(wl, HW_PART1_SIZE_ADDR, p->reg.size); - if (ret < 0) - goto out; - - ret = wlcore_raw_write32(wl, HW_PART2_START_ADDR, p->mem2.start); - if (ret < 0) - goto out; - - ret = wlcore_raw_write32(wl, HW_PART2_SIZE_ADDR, p->mem2.size); - if (ret < 0) - goto out; - + wl1271_raw_write32(wl, HW_PART0_START_ADDR, p->mem.start); + wl1271_raw_write32(wl, HW_PART0_SIZE_ADDR, p->mem.size); + wl1271_raw_write32(wl, HW_PART1_START_ADDR, p->reg.start); + wl1271_raw_write32(wl, HW_PART1_SIZE_ADDR, p->reg.size); + wl1271_raw_write32(wl, HW_PART2_START_ADDR, p->mem2.start); + wl1271_raw_write32(wl, HW_PART2_SIZE_ADDR, p->mem2.size); /* * We don't need the size of the last partition, as it is * automatically calculated based on the total memory size and * the sizes of the previous partitions. */ - ret = wlcore_raw_write32(wl, HW_PART3_START_ADDR, p->mem3.start); - -out: - return ret; + wl1271_raw_write32(wl, HW_PART3_START_ADDR, p->mem3.start); } EXPORT_SYMBOL_GPL(wlcore_set_partition); +void wlcore_select_partition(struct wl1271 *wl, u8 part) +{ + wl1271_debug(DEBUG_IO, "setting partition %d", part); + + wlcore_set_partition(wl, &wl->ptable[part]); +} +EXPORT_SYMBOL_GPL(wlcore_select_partition); + void wl1271_io_reset(struct wl1271 *wl) { if (wl->if_ops->reset) diff --git a/trunk/drivers/net/wireless/ti/wlcore/io.h b/trunk/drivers/net/wireless/ti/wlcore/io.h index fef80adc8bf5..8942954b56a0 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/io.h +++ b/trunk/drivers/net/wireless/ti/wlcore/io.h @@ -45,7 +45,6 @@ struct wl1271; void wlcore_disable_interrupts(struct wl1271 *wl); -void wlcore_disable_interrupts_nosync(struct wl1271 *wl); void wlcore_enable_interrupts(struct wl1271 *wl); void wl1271_io_reset(struct wl1271 *wl); @@ -53,113 +52,79 @@ void wl1271_io_init(struct wl1271 *wl); int wlcore_translate_addr(struct wl1271 *wl, int addr); /* Raw target IO, address is not translated */ -static inline int __must_check wlcore_raw_write(struct wl1271 *wl, int addr, - void *buf, size_t len, - bool fixed) +static inline void wl1271_raw_write(struct wl1271 *wl, int addr, void *buf, + size_t len, bool fixed) { - int ret; - - if (test_bit(WL1271_FLAG_SDIO_FAILED, &wl->flags)) - return -EIO; - - ret = wl->if_ops->write(wl->dev, addr, buf, len, fixed); - if (ret) - set_bit(WL1271_FLAG_SDIO_FAILED, &wl->flags); - - return ret; + wl->if_ops->write(wl->dev, addr, buf, len, fixed); } -static inline int __must_check wlcore_raw_read(struct wl1271 *wl, int addr, - void *buf, size_t len, - bool fixed) +static inline void wl1271_raw_read(struct wl1271 *wl, int addr, void *buf, + size_t len, bool fixed) { - int ret; - - if (test_bit(WL1271_FLAG_SDIO_FAILED, &wl->flags)) - return -EIO; - - ret = wl->if_ops->read(wl->dev, addr, buf, len, fixed); - if (ret) - set_bit(WL1271_FLAG_SDIO_FAILED, &wl->flags); - - return ret; + wl->if_ops->read(wl->dev, addr, buf, len, fixed); } -static inline int __must_check wlcore_raw_read_data(struct wl1271 *wl, int reg, - void *buf, size_t len, - bool fixed) +static inline void wlcore_raw_read_data(struct wl1271 *wl, int reg, void *buf, + size_t len, bool fixed) { - return wlcore_raw_read(wl, wl->rtable[reg], buf, len, fixed); + wl1271_raw_read(wl, wl->rtable[reg], buf, len, fixed); } -static inline int __must_check wlcore_raw_write_data(struct wl1271 *wl, int reg, - void *buf, size_t len, - bool fixed) +static inline void wlcore_raw_write_data(struct wl1271 *wl, int reg, void *buf, + size_t len, bool fixed) { - return wlcore_raw_write(wl, wl->rtable[reg], buf, len, fixed); + wl1271_raw_write(wl, wl->rtable[reg], buf, len, fixed); } -static inline int __must_check wlcore_raw_read32(struct wl1271 *wl, int addr, - u32 *val) +static inline u32 wl1271_raw_read32(struct wl1271 *wl, int addr) { - int ret; - - ret = wlcore_raw_read(wl, addr, &wl->buffer_32, - sizeof(wl->buffer_32), false); - if (ret < 0) - return ret; - - if (val) - *val = le32_to_cpu(wl->buffer_32); + wl1271_raw_read(wl, addr, &wl->buffer_32, + sizeof(wl->buffer_32), false); - return 0; + return le32_to_cpu(wl->buffer_32); } -static inline int __must_check wlcore_raw_write32(struct wl1271 *wl, int addr, - u32 val) +static inline void wl1271_raw_write32(struct wl1271 *wl, int addr, u32 val) { wl->buffer_32 = cpu_to_le32(val); - return wlcore_raw_write(wl, addr, &wl->buffer_32, - sizeof(wl->buffer_32), false); + wl1271_raw_write(wl, addr, &wl->buffer_32, + sizeof(wl->buffer_32), false); } -static inline int __must_check wlcore_read(struct wl1271 *wl, int addr, - void *buf, size_t len, bool fixed) +static inline void wl1271_read(struct wl1271 *wl, int addr, void *buf, + size_t len, bool fixed) { int physical; physical = wlcore_translate_addr(wl, addr); - return wlcore_raw_read(wl, physical, buf, len, fixed); + wl1271_raw_read(wl, physical, buf, len, fixed); } -static inline int __must_check wlcore_write(struct wl1271 *wl, int addr, - void *buf, size_t len, bool fixed) +static inline void wl1271_write(struct wl1271 *wl, int addr, void *buf, + size_t len, bool fixed) { int physical; physical = wlcore_translate_addr(wl, addr); - return wlcore_raw_write(wl, physical, buf, len, fixed); + wl1271_raw_write(wl, physical, buf, len, fixed); } -static inline int __must_check wlcore_write_data(struct wl1271 *wl, int reg, - void *buf, size_t len, - bool fixed) +static inline void wlcore_write_data(struct wl1271 *wl, int reg, void *buf, + size_t len, bool fixed) { - return wlcore_write(wl, wl->rtable[reg], buf, len, fixed); + wl1271_write(wl, wl->rtable[reg], buf, len, fixed); } -static inline int __must_check wlcore_read_data(struct wl1271 *wl, int reg, - void *buf, size_t len, - bool fixed) +static inline void wlcore_read_data(struct wl1271 *wl, int reg, void *buf, + size_t len, bool fixed) { - return wlcore_read(wl, wl->rtable[reg], buf, len, fixed); + wl1271_read(wl, wl->rtable[reg], buf, len, fixed); } -static inline int __must_check wlcore_read_hwaddr(struct wl1271 *wl, int hwaddr, - void *buf, size_t len, - bool fixed) +static inline void wl1271_read_hwaddr(struct wl1271 *wl, int hwaddr, + void *buf, size_t len, bool fixed) { int physical; int addr; @@ -169,47 +134,34 @@ static inline int __must_check wlcore_read_hwaddr(struct wl1271 *wl, int hwaddr, physical = wlcore_translate_addr(wl, addr); - return wlcore_raw_read(wl, physical, buf, len, fixed); + wl1271_raw_read(wl, physical, buf, len, fixed); } -static inline int __must_check wlcore_read32(struct wl1271 *wl, int addr, - u32 *val) +static inline u32 wl1271_read32(struct wl1271 *wl, int addr) { - return wlcore_raw_read32(wl, wlcore_translate_addr(wl, addr), val); + return wl1271_raw_read32(wl, wlcore_translate_addr(wl, addr)); } -static inline int __must_check wlcore_write32(struct wl1271 *wl, int addr, - u32 val) +static inline void wl1271_write32(struct wl1271 *wl, int addr, u32 val) { - return wlcore_raw_write32(wl, wlcore_translate_addr(wl, addr), val); + wl1271_raw_write32(wl, wlcore_translate_addr(wl, addr), val); } -static inline int __must_check wlcore_read_reg(struct wl1271 *wl, int reg, - u32 *val) +static inline u32 wlcore_read_reg(struct wl1271 *wl, int reg) { - return wlcore_raw_read32(wl, - wlcore_translate_addr(wl, wl->rtable[reg]), - val); + return wl1271_raw_read32(wl, + wlcore_translate_addr(wl, wl->rtable[reg])); } -static inline int __must_check wlcore_write_reg(struct wl1271 *wl, int reg, - u32 val) +static inline void wlcore_write_reg(struct wl1271 *wl, int reg, u32 val) { - return wlcore_raw_write32(wl, - wlcore_translate_addr(wl, wl->rtable[reg]), - val); + wl1271_raw_write32(wl, wlcore_translate_addr(wl, wl->rtable[reg]), val); } static inline void wl1271_power_off(struct wl1271 *wl) { - int ret; - - if (!test_bit(WL1271_FLAG_GPIO_POWER, &wl->flags)) - return; - - ret = wl->if_ops->power(wl->dev, false); - if (!ret) - clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); + wl->if_ops->power(wl->dev, false); + clear_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); } static inline int wl1271_power_on(struct wl1271 *wl) @@ -221,8 +173,8 @@ static inline int wl1271_power_on(struct wl1271 *wl) return ret; } -int wlcore_set_partition(struct wl1271 *wl, - const struct wlcore_partition_set *p); +void wlcore_set_partition(struct wl1271 *wl, + const struct wlcore_partition_set *p); bool wl1271_set_block_size(struct wl1271 *wl); @@ -230,4 +182,6 @@ bool wl1271_set_block_size(struct wl1271 *wl); int wl1271_tx_dummy_packet(struct wl1271 *wl); +void wlcore_select_partition(struct wl1271 *wl, u8 part); + #endif diff --git a/trunk/drivers/net/wireless/ti/wlcore/main.c b/trunk/drivers/net/wireless/ti/wlcore/main.c index 0cc9a0240220..1156e3f578c1 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/main.c +++ b/trunk/drivers/net/wireless/ti/wlcore/main.c @@ -378,9 +378,9 @@ static void wl12xx_irq_update_links_status(struct wl1271 *wl, } } -static int wlcore_fw_status(struct wl1271 *wl, - struct wl_fw_status_1 *status_1, - struct wl_fw_status_2 *status_2) +static void wl12xx_fw_status(struct wl1271 *wl, + struct wl_fw_status_1 *status_1, + struct wl_fw_status_2 *status_2) { struct wl12xx_vif *wlvif; struct timespec ts; @@ -388,15 +388,12 @@ static int wlcore_fw_status(struct wl1271 *wl, int avail, freed_blocks; int i; size_t status_len; - int ret; status_len = WLCORE_FW_STATUS_1_LEN(wl->num_rx_desc) + sizeof(*status_2) + wl->fw_status_priv_len; - ret = wlcore_raw_read_data(wl, REG_RAW_FW_STATUS_ADDR, status_1, - status_len, false); - if (ret < 0) - return ret; + wlcore_raw_read_data(wl, REG_RAW_FW_STATUS_ADDR, status_1, + status_len, false); wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, " "drv_rx_counter = %d, tx_results_counter = %d)", @@ -465,8 +462,6 @@ static int wlcore_fw_status(struct wl1271 *wl, getnstimeofday(&ts); wl->time_offset = (timespec_to_ns(&ts) >> 10) - (s64)le32_to_cpu(status_2->fw_localtime); - - return 0; } static void wl1271_flush_deferred_work(struct wl1271 *wl) @@ -494,15 +489,20 @@ static void wl1271_netstack_work(struct work_struct *work) #define WL1271_IRQ_MAX_LOOPS 256 -static int wlcore_irq_locked(struct wl1271 *wl) +static irqreturn_t wl1271_irq(int irq, void *cookie) { - int ret = 0; + int ret; u32 intr; int loopcount = WL1271_IRQ_MAX_LOOPS; + struct wl1271 *wl = (struct wl1271 *)cookie; bool done = false; unsigned int defer_count; unsigned long flags; + /* TX might be handled here, avoid redundant work */ + set_bit(WL1271_FLAG_TX_PENDING, &wl->flags); + cancel_work_sync(&wl->tx_work); + /* * In case edge triggered interrupt must be used, we cannot iterate * more than once without introducing race conditions with the hardirq. @@ -510,6 +510,8 @@ static int wlcore_irq_locked(struct wl1271 *wl) if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ) loopcount = 1; + mutex_lock(&wl->mutex); + wl1271_debug(DEBUG_IRQ, "IRQ work"); if (unlikely(wl->state == WL1271_STATE_OFF)) @@ -528,9 +530,7 @@ static int wlcore_irq_locked(struct wl1271 *wl) clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags); smp_mb__after_clear_bit(); - ret = wlcore_fw_status(wl, wl->fw_status_1, wl->fw_status_2); - if (ret < 0) - goto out; + wl12xx_fw_status(wl, wl->fw_status_1, wl->fw_status_2); wlcore_hw_tx_immediate_compl(wl); @@ -544,7 +544,7 @@ static int wlcore_irq_locked(struct wl1271 *wl) if (unlikely(intr & WL1271_ACX_INTR_WATCHDOG)) { wl1271_error("HW watchdog interrupt received! starting recovery."); wl->watchdog_recovery = true; - ret = -EIO; + wl12xx_queue_recovery_work(wl); /* restarting the chip. ignore any other interrupt. */ goto out; @@ -554,7 +554,7 @@ static int wlcore_irq_locked(struct wl1271 *wl) wl1271_error("SW watchdog interrupt received! " "starting recovery."); wl->watchdog_recovery = true; - ret = -EIO; + wl12xx_queue_recovery_work(wl); /* restarting the chip. ignore any other interrupt. */ goto out; @@ -563,9 +563,7 @@ static int wlcore_irq_locked(struct wl1271 *wl) if (likely(intr & WL1271_ACX_INTR_DATA)) { wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA"); - ret = wlcore_rx(wl, wl->fw_status_1); - if (ret < 0) - goto out; + wl12xx_rx(wl, wl->fw_status_1); /* Check if any tx blocks were freed */ spin_lock_irqsave(&wl->wl_lock, flags); @@ -576,17 +574,13 @@ static int wlcore_irq_locked(struct wl1271 *wl) * In order to avoid starvation of the TX path, * call the work function directly. */ - ret = wlcore_tx_work_locked(wl); - if (ret < 0) - goto out; + wl1271_tx_work_locked(wl); } else { spin_unlock_irqrestore(&wl->wl_lock, flags); } /* check for tx results */ - ret = wlcore_hw_tx_delayed_compl(wl); - if (ret < 0) - goto out; + wlcore_hw_tx_delayed_compl(wl); /* Make sure the deferred queues don't get too long */ defer_count = skb_queue_len(&wl->deferred_tx_queue) + @@ -597,16 +591,12 @@ static int wlcore_irq_locked(struct wl1271 *wl) if (intr & WL1271_ACX_INTR_EVENT_A) { wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_A"); - ret = wl1271_event_handle(wl, 0); - if (ret < 0) - goto out; + wl1271_event_handle(wl, 0); } if (intr & WL1271_ACX_INTR_EVENT_B) { wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_B"); - ret = wl1271_event_handle(wl, 1); - if (ret < 0) - goto out; + wl1271_event_handle(wl, 1); } if (intr & WL1271_ACX_INTR_INIT_COMPLETE) @@ -620,25 +610,6 @@ static int wlcore_irq_locked(struct wl1271 *wl) wl1271_ps_elp_sleep(wl); out: - return ret; -} - -static irqreturn_t wlcore_irq(int irq, void *cookie) -{ - int ret; - unsigned long flags; - struct wl1271 *wl = cookie; - - /* TX might be handled here, avoid redundant work */ - set_bit(WL1271_FLAG_TX_PENDING, &wl->flags); - cancel_work_sync(&wl->tx_work); - - mutex_lock(&wl->mutex); - - ret = wlcore_irq_locked(wl); - if (ret) - wl12xx_queue_recovery_work(wl); - spin_lock_irqsave(&wl->wl_lock, flags); /* In case TX was not handled here, queue TX work */ clear_bit(WL1271_FLAG_TX_PENDING, &wl->flags); @@ -772,13 +743,8 @@ static void wl1271_fetch_nvs(struct wl1271 *wl) void wl12xx_queue_recovery_work(struct wl1271 *wl) { - WARN_ON(!test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)); - - /* Avoid a recursive recovery */ - if (!test_and_set_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags)) { - wlcore_disable_interrupts_nosync(wl); + if (!test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags)) ieee80211_queue_work(wl->hw, &wl->recovery_work); - } } size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen) @@ -804,17 +770,14 @@ size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen) return len; } -#define WLCORE_FW_LOG_END 0x2000000 - static void wl12xx_read_fwlog_panic(struct wl1271 *wl) { u32 addr; - u32 offset; - u32 end_of_log; + u32 first_addr; u8 *block; - int ret; if ((wl->quirks & WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED) || + (wl->conf.fwlog.mode != WL12XX_FWLOG_ON_DEMAND) || (wl->conf.fwlog.mem_blocks == 0)) return; @@ -828,47 +791,34 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl) * Make sure the chip is awake and the logger isn't active. * Do not send a stop fwlog command if the fw is hanged. */ - if (wl1271_ps_elp_wakeup(wl)) - goto out; - if (!wl->watchdog_recovery) + if (!wl1271_ps_elp_wakeup(wl) && !wl->watchdog_recovery) wl12xx_cmd_stop_fwlog(wl); - - /* Read the first memory block address */ - ret = wlcore_fw_status(wl, wl->fw_status_1, wl->fw_status_2); - if (ret < 0) + else goto out; - addr = le32_to_cpu(wl->fw_status_2->log_start_addr); - if (!addr) + /* Read the first memory block address */ + wl12xx_fw_status(wl, wl->fw_status_1, wl->fw_status_2); + first_addr = le32_to_cpu(wl->fw_status_2->log_start_addr); + if (!first_addr) goto out; - if (wl->conf.fwlog.mode == WL12XX_FWLOG_CONTINUOUS) { - offset = sizeof(addr) + sizeof(struct wl1271_rx_descriptor); - end_of_log = WLCORE_FW_LOG_END; - } else { - offset = sizeof(addr); - end_of_log = addr; - } - /* Traverse the memory blocks linked list */ + addr = first_addr; do { memset(block, 0, WL12XX_HW_BLOCK_SIZE); - ret = wlcore_read_hwaddr(wl, addr, block, WL12XX_HW_BLOCK_SIZE, - false); - if (ret < 0) - goto out; + wl1271_read_hwaddr(wl, addr, block, WL12XX_HW_BLOCK_SIZE, + false); /* * Memory blocks are linked to one another. The first 4 bytes * of each memory block hold the hardware address of the next - * one. The last memory block points to the first one in - * on demand mode and is equal to 0x2000000 in continuous mode. + * one. The last memory block points to the first one. */ addr = le32_to_cpup((__le32 *)block); - if (!wl12xx_copy_fwlog(wl, block + offset, - WL12XX_HW_BLOCK_SIZE - offset)) + if (!wl12xx_copy_fwlog(wl, block + sizeof(addr), + WL12XX_HW_BLOCK_SIZE - sizeof(addr))) break; - } while (addr && (addr != end_of_log)); + } while (addr && (addr != first_addr)); wake_up_interruptible(&wl->fwlog_waitq); @@ -876,34 +826,6 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl) kfree(block); } -static void wlcore_print_recovery(struct wl1271 *wl) -{ - u32 pc = 0; - u32 hint_sts = 0; - int ret; - - wl1271_info("Hardware recovery in progress. FW ver: %s", - wl->chip.fw_ver_str); - - /* change partitions momentarily so we can read the FW pc */ - ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); - if (ret < 0) - return; - - ret = wlcore_read_reg(wl, REG_PC_ON_RECOVERY, &pc); - if (ret < 0) - return; - - ret = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR, &hint_sts); - if (ret < 0) - return; - - wl1271_info("pc: 0x%x, hint_sts: 0x%08x", pc, hint_sts); - - wlcore_set_partition(wl, &wl->ptable[PART_WORK]); -} - - static void wl1271_recovery_work(struct work_struct *work) { struct wl1271 *wl = @@ -916,9 +838,19 @@ static void wl1271_recovery_work(struct work_struct *work) if (wl->state != WL1271_STATE_ON || wl->plt) goto out_unlock; + /* Avoid a recursive recovery */ + set_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags); + wl12xx_read_fwlog_panic(wl); - wlcore_print_recovery(wl); + /* change partitions momentarily so we can read the FW pc */ + wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); + wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x " + "hint_sts: 0x%08x", + wl->chip.fw_ver_str, + wlcore_read_reg(wl, REG_PC_ON_RECOVERY), + wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR)); + wlcore_set_partition(wl, &wl->ptable[PART_WORK]); BUG_ON(bug_on_recovery && !test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)); @@ -960,6 +892,8 @@ static void wl1271_recovery_work(struct work_struct *work) mutex_unlock(&wl->mutex); wl1271_op_stop(wl->hw); + clear_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags); + ieee80211_restart_hw(wl->hw); /* @@ -973,9 +907,9 @@ static void wl1271_recovery_work(struct work_struct *work) mutex_unlock(&wl->mutex); } -static int wlcore_fw_wakeup(struct wl1271 *wl) +static void wl1271_fw_wakeup(struct wl1271 *wl) { - return wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_WAKE_UP); + wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_WAKE_UP); } static int wl1271_setup(struct wl1271 *wl) @@ -1011,21 +945,13 @@ static int wl12xx_set_power_on(struct wl1271 *wl) wl1271_io_reset(wl); wl1271_io_init(wl); - ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); - if (ret < 0) - goto fail; + wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); /* ELP module wake up */ - ret = wlcore_fw_wakeup(wl); - if (ret < 0) - goto fail; + wl1271_fw_wakeup(wl); out: return ret; - -fail: - wl1271_power_off(wl); - return ret; } static int wl12xx_chip_wakeup(struct wl1271 *wl, bool plt) @@ -1156,7 +1082,6 @@ int wl1271_plt_stop(struct wl1271 *wl) mutex_lock(&wl->mutex); wl1271_power_off(wl); wl->flags = 0; - wl->sleep_auth = WL1271_PSM_ILLEGAL; wl->state = WL1271_STATE_OFF; wl->plt = false; wl->rx_counter = 0; @@ -1248,7 +1173,7 @@ int wl1271_tx_dummy_packet(struct wl1271 *wl) /* The FW is low on RX memory blocks, so send the dummy packet asap */ if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags)) - return wlcore_tx_work_locked(wl); + wl1271_tx_work_locked(wl); /* * If the FW TX is busy, TX work will be scheduled by the threaded @@ -1515,15 +1440,8 @@ static int wl1271_configure_wowlan(struct wl1271 *wl, int i, ret; if (!wow || wow->any || !wow->n_patterns) { - ret = wl1271_acx_default_rx_filter_enable(wl, 0, - FILTER_SIGNAL); - if (ret) - goto out; - - ret = wl1271_rx_filter_clear_all(wl); - if (ret) - goto out; - + wl1271_acx_default_rx_filter_enable(wl, 0, FILTER_SIGNAL); + wl1271_rx_filter_clear_all(wl); return 0; } @@ -1539,13 +1457,8 @@ static int wl1271_configure_wowlan(struct wl1271 *wl, } } - ret = wl1271_acx_default_rx_filter_enable(wl, 0, FILTER_SIGNAL); - if (ret) - goto out; - - ret = wl1271_rx_filter_clear_all(wl); - if (ret) - goto out; + wl1271_acx_default_rx_filter_enable(wl, 0, FILTER_SIGNAL); + wl1271_rx_filter_clear_all(wl); /* Translate WoWLAN patterns into filters */ for (i = 0; i < wow->n_patterns; i++) { @@ -1587,10 +1500,7 @@ static int wl1271_configure_suspend_sta(struct wl1271 *wl, if (ret < 0) goto out; - ret = wl1271_configure_wowlan(wl, wow); - if (ret < 0) - goto out_sleep; - + wl1271_configure_wowlan(wl, wow); ret = wl1271_acx_wake_up_conditions(wl, wlvif, wl->conf.conn.suspend_wake_up_event, wl->conf.conn.suspend_listen_interval); @@ -1598,8 +1508,8 @@ static int wl1271_configure_suspend_sta(struct wl1271 *wl, if (ret < 0) wl1271_error("suspend: set wake up conditions failed: %d", ret); -out_sleep: wl1271_ps_elp_sleep(wl); + out: return ret; @@ -1678,12 +1588,6 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw, wl1271_debug(DEBUG_MAC80211, "mac80211 suspend wow=%d", !!wow); WARN_ON(!wow); - /* we want to perform the recovery before suspending */ - if (test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags)) { - wl1271_warning("postponing suspend to perform recovery"); - return -EBUSY; - } - wl1271_tx_flush(wl); mutex_lock(&wl->mutex); @@ -1724,8 +1628,7 @@ static int wl1271_op_resume(struct ieee80211_hw *hw) struct wl1271 *wl = hw->priv; struct wl12xx_vif *wlvif; unsigned long flags; - bool run_irq_work = false, pending_recovery; - int ret; + bool run_irq_work = false; wl1271_debug(DEBUG_MAC80211, "mac80211 resume wow=%d", wl->wow_enabled); @@ -1741,37 +1644,17 @@ static int wl1271_op_resume(struct ieee80211_hw *hw) run_irq_work = true; spin_unlock_irqrestore(&wl->wl_lock, flags); - mutex_lock(&wl->mutex); - - /* test the recovery flag before calling any SDIO functions */ - pending_recovery = test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, - &wl->flags); - if (run_irq_work) { wl1271_debug(DEBUG_MAC80211, "run postponed irq_work directly"); - - /* don't talk to the HW if recovery is pending */ - if (!pending_recovery) { - ret = wlcore_irq_locked(wl); - if (ret) - wl12xx_queue_recovery_work(wl); - } - + wl1271_irq(0, wl); wlcore_enable_interrupts(wl); } - if (pending_recovery) { - wl1271_warning("queuing forgotten recovery on resume"); - ieee80211_queue_work(wl->hw, &wl->recovery_work); - goto out; - } - + mutex_lock(&wl->mutex); wl12xx_for_each_wlvif(wl, wlvif) { wl1271_configure_resume(wl, wlvif); } - -out: wl->wow_enabled = false; mutex_unlock(&wl->mutex); @@ -1812,10 +1695,6 @@ static void wl1271_op_stop(struct ieee80211_hw *hw) wlcore_disable_interrupts(wl); mutex_lock(&wl->mutex); if (wl->state == WL1271_STATE_OFF) { - if (test_and_clear_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, - &wl->flags)) - wlcore_enable_interrupts(wl); - mutex_unlock(&wl->mutex); /* @@ -1847,13 +1726,6 @@ static void wl1271_op_stop(struct ieee80211_hw *hw) mutex_lock(&wl->mutex); wl1271_power_off(wl); - /* - * In case a recovery was scheduled, interrupts were disabled to avoid - * an interrupt storm. Now that the power is down, it is safe to - * re-enable interrupts to balance the disable depth - */ - if (test_and_clear_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags)) - wlcore_enable_interrupts(wl); wl->band = IEEE80211_BAND_2GHZ; @@ -1868,7 +1740,6 @@ static void wl1271_op_stop(struct ieee80211_hw *hw) wl->ap_fw_ps_map = 0; wl->ap_ps_map = 0; wl->sched_scanning = false; - wl->sleep_auth = WL1271_PSM_ILLEGAL; memset(wl->roles_map, 0, sizeof(wl->roles_map)); memset(wl->links_map, 0, sizeof(wl->links_map)); memset(wl->roc_map, 0, sizeof(wl->roc_map)); @@ -2275,7 +2146,6 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl, { struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif); int i, ret; - bool is_ap = (wlvif->bss_type == BSS_TYPE_AP_BSS); wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface"); @@ -2356,25 +2226,11 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl, wlvif->role_id = WL12XX_INVALID_ROLE_ID; wlvif->dev_role_id = WL12XX_INVALID_ROLE_ID; - if (is_ap) + if (wlvif->bss_type == BSS_TYPE_AP_BSS) wl->ap_count--; else wl->sta_count--; - /* Last AP, have more stations. Configure according to STA. */ - if (wl->ap_count == 0 && is_ap && wl->sta_count) { - u8 sta_auth = wl->conf.conn.sta_sleep_auth; - /* Configure for power according to debugfs */ - if (sta_auth != WL1271_PSM_ILLEGAL) - wl1271_acx_sleep_auth(wl, sta_auth); - /* Configure for power always on */ - else if (wl->quirks & WLCORE_QUIRK_NO_ELP) - wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM); - /* Configure for ELP power saving */ - else - wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP); - } - mutex_unlock(&wl->mutex); del_timer_sync(&wlvif->rx_streaming_timer); @@ -2592,16 +2448,12 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif, (wlvif->channel != channel) || (wlvif->channel_type != conf->channel_type))) { /* send all pending packets */ - ret = wlcore_tx_work_locked(wl); - if (ret < 0) - return ret; - + wl1271_tx_work_locked(wl); wlvif->band = conf->channel->band; wlvif->channel = channel; wlvif->channel_type = conf->channel_type; if (is_ap) { - wl1271_set_band_rate(wl, wlvif); ret = wl1271_init_ap_rates(wl, wlvif); if (ret < 0) wl1271_error("AP rate policy change failed %d", @@ -4238,13 +4090,16 @@ static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw, static int wl1271_op_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey) { + struct wl1271 *wl = hw->priv; struct ieee80211_conf *conf = &hw->conf; if (idx != 0) return -ENOENT; survey->channel = conf->channel; - survey->filled = 0; + survey->filled = SURVEY_INFO_NOISE_DBM; + survey->noise = wl->noise; + return 0; } @@ -4510,14 +4365,9 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw, case IEEE80211_AMPDU_RX_STOP: if (!(*ba_bitmap & BIT(tid))) { - /* - * this happens on reconfig - so only output a debug - * message for now, and don't fail the function. - */ - wl1271_debug(DEBUG_MAC80211, - "no active RX BA session on tid: %d", + ret = -EINVAL; + wl1271_error("no active RX BA session on tid: %d", tid); - ret = 0; break; } @@ -5054,22 +4904,18 @@ static int wl12xx_get_hw_info(struct wl1271 *wl) if (ret < 0) goto out; - ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &wl->chip.id); - if (ret < 0) - goto out; + wl->chip.id = wlcore_read_reg(wl, REG_CHIP_ID_B); wl->fuse_oui_addr = 0; wl->fuse_nic_addr = 0; - ret = wl->ops->get_pg_ver(wl, &wl->hw_pg_ver); - if (ret < 0) - goto out; + wl->hw_pg_ver = wl->ops->get_pg_ver(wl); if (wl->ops->get_mac) - ret = wl->ops->get_mac(wl); + wl->ops->get_mac(wl); -out: wl1271_power_off(wl); +out: return ret; } @@ -5130,29 +4976,6 @@ static void wl1271_unregister_hw(struct wl1271 *wl) } -static const struct ieee80211_iface_limit wlcore_iface_limits[] = { - { - .max = 2, - .types = BIT(NL80211_IFTYPE_STATION), - }, - { - .max = 1, - .types = BIT(NL80211_IFTYPE_AP) | - BIT(NL80211_IFTYPE_P2P_GO) | - BIT(NL80211_IFTYPE_P2P_CLIENT), - }, -}; - -static const struct ieee80211_iface_combination -wlcore_iface_combinations[] = { - { - .num_different_channels = 1, - .max_interfaces = 2, - .limits = wlcore_iface_limits, - .n_limits = ARRAY_SIZE(wlcore_iface_limits), - }, -}; - static int wl1271_init_ieee80211(struct wl1271 *wl) { static const u32 cipher_suites[] = { @@ -5246,11 +5069,6 @@ static int wl1271_init_ieee80211(struct wl1271 *wl) NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P; - /* allowed interface combinations */ - wl->hw->wiphy->iface_combinations = wlcore_iface_combinations; - wl->hw->wiphy->n_iface_combinations = - ARRAY_SIZE(wlcore_iface_combinations); - SET_IEEE80211_DEV(wl->hw, wl->dev); wl->hw->sta_data_size = sizeof(struct wl1271_station); @@ -5322,7 +5140,6 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size) wl->channel_type = NL80211_CHAN_NO_HT; wl->flags = 0; wl->sg_enabled = true; - wl->sleep_auth = WL1271_PSM_ILLEGAL; wl->hw_pg_ver = -1; wl->ap_ps_map = 0; wl->ap_fw_ps_map = 0; @@ -5496,7 +5313,7 @@ int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev) else irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT; - ret = request_threaded_irq(wl->irq, wl12xx_hardirq, wlcore_irq, + ret = request_threaded_irq(wl->irq, wl12xx_hardirq, wl1271_irq, irqflags, pdev->name, wl); if (ret < 0) { @@ -5504,7 +5321,6 @@ int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev) goto out_free_hw; } -#ifdef CONFIG_PM ret = enable_irq_wake(wl->irq); if (!ret) { wl->irq_wake_enabled = true; @@ -5518,18 +5334,17 @@ int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev) WL1271_RX_FILTER_MAX_PATTERN_SIZE; } } -#endif disable_irq(wl->irq); ret = wl12xx_get_hw_info(wl); if (ret < 0) { wl1271_error("couldn't get hw info"); - goto out_irq; + goto out; } ret = wl->ops->identify_chip(wl); if (ret < 0) - goto out_irq; + goto out; ret = wl1271_init_ieee80211(wl); if (ret) @@ -5543,7 +5358,7 @@ int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev) ret = device_create_file(wl->dev, &dev_attr_bt_coex_state); if (ret < 0) { wl1271_error("failed to create sysfs file bt_coex_state"); - goto out_unreg; + goto out_irq; } /* Create sysfs file to get HW PG version */ @@ -5568,9 +5383,6 @@ int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev) out_bt_coex_state: device_remove_file(wl->dev, &dev_attr_bt_coex_state); -out_unreg: - wl1271_unregister_hw(wl); - out_irq: free_irq(wl->irq, wl); diff --git a/trunk/drivers/net/wireless/ti/wlcore/ps.c b/trunk/drivers/net/wireless/ti/wlcore/ps.c index 46d36fd30eba..47e81b32f7da 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/ps.c +++ b/trunk/drivers/net/wireless/ti/wlcore/ps.c @@ -35,7 +35,6 @@ void wl1271_elp_work(struct work_struct *work) struct delayed_work *dwork; struct wl1271 *wl; struct wl12xx_vif *wlvif; - int ret; dwork = container_of(work, struct delayed_work, work); wl = container_of(dwork, struct wl1271, elp_work); @@ -64,12 +63,7 @@ void wl1271_elp_work(struct work_struct *work) } wl1271_debug(DEBUG_PSM, "chip to elp"); - ret = wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_SLEEP); - if (ret < 0) { - wl12xx_queue_recovery_work(wl); - goto out; - } - + wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_SLEEP); set_bit(WL1271_FLAG_IN_ELP, &wl->flags); out: @@ -82,7 +76,7 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl) struct wl12xx_vif *wlvif; u32 timeout; - if (wl->sleep_auth != WL1271_PSM_ELP) + if (wl->quirks & WLCORE_QUIRK_NO_ELP) return; /* we shouldn't get consecutive sleep requests */ @@ -141,11 +135,7 @@ int wl1271_ps_elp_wakeup(struct wl1271 *wl) wl->elp_compl = &compl; spin_unlock_irqrestore(&wl->wl_lock, flags); - ret = wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_WAKE_UP); - if (ret < 0) { - wl12xx_queue_recovery_work(wl); - goto err; - } + wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_WAKE_UP); if (!pending) { ret = wait_for_completion_timeout( diff --git a/trunk/drivers/net/wireless/ti/wlcore/rx.c b/trunk/drivers/net/wireless/ti/wlcore/rx.c index f55e2f9e7ac5..78200dcacfca 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/rx.c +++ b/trunk/drivers/net/wireless/ti/wlcore/rx.c @@ -127,7 +127,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length, } if (rx_align == WLCORE_RX_BUF_UNALIGNED) - reserved = RX_BUF_ALIGN; + reserved = NET_IP_ALIGN; /* the data read starts with the descriptor */ desc = (struct wl1271_rx_descriptor *) data; @@ -175,7 +175,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length, */ memcpy(buf, data + sizeof(*desc), pkt_data_len); if (rx_align == WLCORE_RX_BUF_PADDED) - skb_pull(skb, RX_BUF_ALIGN); + skb_pull(skb, NET_IP_ALIGN); *hlid = desc->hlid; @@ -200,7 +200,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length, return is_data; } -int wlcore_rx(struct wl1271 *wl, struct wl_fw_status_1 *status) +void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status_1 *status) { unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0}; u32 buf_size; @@ -211,7 +211,6 @@ int wlcore_rx(struct wl1271 *wl, struct wl_fw_status_1 *status) u32 pkt_offset, des; u8 hlid; enum wl_rx_buf_align rx_align; - int ret = 0; while (drv_rx_counter != fw_rx_counter) { buf_size = 0; @@ -235,14 +234,9 @@ int wlcore_rx(struct wl1271 *wl, struct wl_fw_status_1 *status) /* Read all available packets at once */ des = le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]); - ret = wlcore_hw_prepare_read(wl, des, buf_size); - if (ret < 0) - goto out; - - ret = wlcore_read_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf, - buf_size, true); - if (ret < 0) - goto out; + wlcore_hw_prepare_read(wl, des, buf_size); + wlcore_read_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf, + buf_size, true); /* Split data into separate packets */ pkt_offset = 0; @@ -279,17 +273,11 @@ int wlcore_rx(struct wl1271 *wl, struct wl_fw_status_1 *status) * Write the driver's packet counter to the FW. This is only required * for older hardware revisions */ - if (wl->quirks & WLCORE_QUIRK_END_OF_TRANSACTION) { - ret = wlcore_write32(wl, WL12XX_REG_RX_DRIVER_COUNTER, - wl->rx_counter); - if (ret < 0) - goto out; - } + if (wl->quirks & WLCORE_QUIRK_END_OF_TRANSACTION) + wl1271_write32(wl, WL12XX_REG_RX_DRIVER_COUNTER, + wl->rx_counter); wl12xx_rearm_rx_streaming(wl, active_hlids); - -out: - return ret; } #ifdef CONFIG_PM @@ -318,19 +306,14 @@ int wl1271_rx_filter_enable(struct wl1271 *wl, return 0; } -int wl1271_rx_filter_clear_all(struct wl1271 *wl) +void wl1271_rx_filter_clear_all(struct wl1271 *wl) { - int i, ret = 0; + int i; for (i = 0; i < WL1271_MAX_RX_FILTERS; i++) { if (!wl->rx_filter_enabled[i]) continue; - ret = wl1271_rx_filter_enable(wl, i, 0, NULL); - if (ret) - goto out; + wl1271_rx_filter_enable(wl, i, 0, NULL); } - -out: - return ret; } #endif /* CONFIG_PM */ diff --git a/trunk/drivers/net/wireless/ti/wlcore/rx.h b/trunk/drivers/net/wireless/ti/wlcore/rx.h index 71eba1899915..9be780179456 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/rx.h +++ b/trunk/drivers/net/wireless/ti/wlcore/rx.h @@ -103,12 +103,6 @@ /* If set, the buffer was padded by the FW to be 4 bytes aligned */ #define RX_BUF_PADDED_PAYLOAD BIT(30) -/* - * Account for the padding inserted by the FW in case of RX_ALIGNMENT - * or for fixing alignment in case the packet wasn't aligned. - */ -#define RX_BUF_ALIGN 2 - /* Describes the alignment state of a Rx buffer */ enum wl_rx_buf_align { WLCORE_RX_BUF_ALIGNED, @@ -143,11 +137,11 @@ struct wl1271_rx_descriptor { u8 reserved; } __packed; -int wlcore_rx(struct wl1271 *wl, struct wl_fw_status_1 *status); +void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status_1 *status); u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band); int wl1271_rx_filter_enable(struct wl1271 *wl, int index, bool enable, struct wl12xx_rx_filter *filter); -int wl1271_rx_filter_clear_all(struct wl1271 *wl); +void wl1271_rx_filter_clear_all(struct wl1271 *wl); #endif diff --git a/trunk/drivers/net/wireless/ti/wlcore/sdio.c b/trunk/drivers/net/wireless/ti/wlcore/sdio.c index 204e69fa9327..c67ec482e445 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/sdio.c +++ b/trunk/drivers/net/wireless/ti/wlcore/sdio.c @@ -71,8 +71,8 @@ static void wl1271_sdio_set_block_size(struct device *child, sdio_release_host(func); } -static int __must_check wl12xx_sdio_raw_read(struct device *child, int addr, - void *buf, size_t len, bool fixed) +static void wl12xx_sdio_raw_read(struct device *child, int addr, void *buf, + size_t len, bool fixed) { int ret; struct wl12xx_sdio_glue *glue = dev_get_drvdata(child->parent); @@ -103,14 +103,12 @@ static int __must_check wl12xx_sdio_raw_read(struct device *child, int addr, sdio_release_host(func); - if (WARN_ON(ret)) + if (ret) dev_err(child->parent, "sdio read failed (%d)\n", ret); - - return ret; } -static int __must_check wl12xx_sdio_raw_write(struct device *child, int addr, - void *buf, size_t len, bool fixed) +static void wl12xx_sdio_raw_write(struct device *child, int addr, void *buf, + size_t len, bool fixed) { int ret; struct wl12xx_sdio_glue *glue = dev_get_drvdata(child->parent); @@ -141,30 +139,25 @@ static int __must_check wl12xx_sdio_raw_write(struct device *child, int addr, sdio_release_host(func); - if (WARN_ON(ret)) + if (ret) dev_err(child->parent, "sdio write failed (%d)\n", ret); - - return ret; } static int wl12xx_sdio_power_on(struct wl12xx_sdio_glue *glue) { int ret; struct sdio_func *func = dev_to_sdio_func(glue->dev); - struct mmc_card *card = func->card; - ret = pm_runtime_get_sync(&card->dev); - if (ret) { - /* - * Runtime PM might be temporarily disabled, or the device - * might have a positive reference counter. Make sure it is - * really powered on. - */ - ret = mmc_power_restore_host(card->host); - if (ret < 0) { - pm_runtime_put_sync(&card->dev); + /* If enabled, tell runtime PM not to power off the card */ + if (pm_runtime_enabled(&func->dev)) { + ret = pm_runtime_get_sync(&func->dev); + if (ret < 0) + goto out; + } else { + /* Runtime PM is disabled: power up the card manually */ + ret = mmc_power_restore_host(func->card->host); + if (ret < 0) goto out; - } } sdio_claim_host(func); @@ -179,21 +172,20 @@ static int wl12xx_sdio_power_off(struct wl12xx_sdio_glue *glue) { int ret; struct sdio_func *func = dev_to_sdio_func(glue->dev); - struct mmc_card *card = func->card; sdio_claim_host(func); sdio_disable_func(func); sdio_release_host(func); - /* Power off the card manually in case it wasn't powered off above */ - ret = mmc_power_save_host(card->host); + /* Power off the card manually, even if runtime PM is enabled. */ + ret = mmc_power_save_host(func->card->host); if (ret < 0) - goto out; + return ret; - /* Let runtime PM know the card is powered off */ - pm_runtime_put_sync(&card->dev); + /* If enabled, let runtime PM know the card is powered off */ + if (pm_runtime_enabled(&func->dev)) + ret = pm_runtime_put_sync(&func->dev); -out: return ret; } diff --git a/trunk/drivers/net/wireless/ti/wlcore/spi.c b/trunk/drivers/net/wireless/ti/wlcore/spi.c index 6420abae40ee..553cd3cbb98c 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/spi.c +++ b/trunk/drivers/net/wireless/ti/wlcore/spi.c @@ -193,8 +193,8 @@ static int wl12xx_spi_read_busy(struct device *child) return -ETIMEDOUT; } -static int __must_check wl12xx_spi_raw_read(struct device *child, int addr, - void *buf, size_t len, bool fixed) +static void wl12xx_spi_raw_read(struct device *child, int addr, void *buf, + size_t len, bool fixed) { struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent); struct wl1271 *wl = dev_get_drvdata(child); @@ -238,7 +238,7 @@ static int __must_check wl12xx_spi_raw_read(struct device *child, int addr, if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1) && wl12xx_spi_read_busy(child)) { memset(buf, 0, chunk_len); - return 0; + return; } spi_message_init(&m); @@ -256,12 +256,10 @@ static int __must_check wl12xx_spi_raw_read(struct device *child, int addr, buf += chunk_len; len -= chunk_len; } - - return 0; } -static int __must_check wl12xx_spi_raw_write(struct device *child, int addr, - void *buf, size_t len, bool fixed) +static void wl12xx_spi_raw_write(struct device *child, int addr, void *buf, + size_t len, bool fixed) { struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent); struct spi_transfer t[2 * WSPI_MAX_NUM_OF_CHUNKS]; @@ -306,8 +304,6 @@ static int __must_check wl12xx_spi_raw_write(struct device *child, int addr, } spi_sync(to_spi_device(glue->dev), &m); - - return 0; } static struct wl1271_if_operations spi_ops = { diff --git a/trunk/drivers/net/wireless/ti/wlcore/testmode.c b/trunk/drivers/net/wireless/ti/wlcore/testmode.c index eeb339d61d1e..0e59ea2cdd39 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/testmode.c +++ b/trunk/drivers/net/wireless/ti/wlcore/testmode.c @@ -108,20 +108,6 @@ static int wl1271_tm_cmd_test(struct wl1271 *wl, struct nlattr *tb[]) } if (answer) { - /* If we got bip calibration answer print radio status */ - struct wl1271_cmd_cal_p2g *params = - (struct wl1271_cmd_cal_p2g *) buf; - - s16 radio_status = (s16) le16_to_cpu(params->radio_status); - - if (params->test.id == TEST_CMD_P2G_CAL && - radio_status < 0) - wl1271_warning("testmode cmd: radio status=%d", - radio_status); - else - wl1271_info("testmode cmd: radio status=%d", - radio_status); - len = nla_total_size(buf_len); skb = cfg80211_testmode_alloc_reply_skb(wl->hw->wiphy, len); if (!skb) { diff --git a/trunk/drivers/net/wireless/ti/wlcore/tx.c b/trunk/drivers/net/wireless/ti/wlcore/tx.c index 6a28aeecf004..6983e7a829d0 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/tx.c +++ b/trunk/drivers/net/wireless/ti/wlcore/tx.c @@ -305,15 +305,11 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif, if (is_dummy || !wlvif) rate_idx = 0; else if (wlvif->bss_type != BSS_TYPE_AP_BSS) { - /* - * if the packets are destined for AP (have a STA entry) - * send them with AP rate policies (EAPOLs are an exception), - * otherwise use default basic rates - */ + /* if the packets are destined for AP (have a STA entry) + send them with AP rate policies, otherwise use default + basic rates */ if (control->flags & IEEE80211_TX_CTL_NO_CCK_RATE) rate_idx = wlvif->sta.p2p_rate_idx; - else if (skb->protocol == cpu_to_be16(ETH_P_PAE)) - rate_idx = wlvif->sta.basic_rate_idx; else if (control->control.sta) rate_idx = wlvif->sta.ap_rate_idx; else @@ -352,10 +348,8 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif, bool is_dummy; bool is_gem = false; - if (!skb) { - wl1271_error("discarding null skb"); + if (!skb) return -EINVAL; - } info = IEEE80211_SKB_CB(skb); @@ -664,17 +658,7 @@ void wl12xx_rearm_rx_streaming(struct wl1271 *wl, unsigned long *active_hlids) } } -/* - * Returns failure values only in case of failed bus ops within this function. - * wl1271_prepare_tx_frame retvals won't be returned in order to avoid - * triggering recovery by higher layers when not necessary. - * In case a FW command fails within wl1271_prepare_tx_frame fails a recovery - * will be queued in wl1271_cmd_send. -EAGAIN/-EBUSY from prepare_tx_frame - * can occur and are legitimate so don't propagate. -EINVAL will emit a WARNING - * within prepare_tx_frame code but there's nothing we should do about those - * as well. - */ -int wlcore_tx_work_locked(struct wl1271 *wl) +void wl1271_tx_work_locked(struct wl1271 *wl) { struct wl12xx_vif *wlvif; struct sk_buff *skb; @@ -682,11 +666,10 @@ int wlcore_tx_work_locked(struct wl1271 *wl) u32 buf_offset = 0, last_len = 0; bool sent_packets = false; unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0}; - int ret = 0; - int bus_ret = 0; + int ret; if (unlikely(wl->state == WL1271_STATE_OFF)) - return 0; + return; while ((skb = wl1271_skb_dequeue(wl))) { struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); @@ -707,11 +690,8 @@ int wlcore_tx_work_locked(struct wl1271 *wl) buf_offset = wlcore_hw_pre_pkt_send(wl, buf_offset, last_len); - bus_ret = wlcore_write_data(wl, REG_SLV_MEM_DATA, - wl->aggr_buf, buf_offset, true); - if (bus_ret < 0) - goto out; - + wlcore_write_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf, + buf_offset, true); sent_packets = true; buf_offset = 0; continue; @@ -747,11 +727,8 @@ int wlcore_tx_work_locked(struct wl1271 *wl) out_ack: if (buf_offset) { buf_offset = wlcore_hw_pre_pkt_send(wl, buf_offset, last_len); - bus_ret = wlcore_write_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf, - buf_offset, true); - if (bus_ret < 0) - goto out; - + wlcore_write_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf, + buf_offset, true); sent_packets = true; } if (sent_packets) { @@ -759,19 +736,13 @@ int wlcore_tx_work_locked(struct wl1271 *wl) * Interrupt the firmware with the new packets. This is only * required for older hardware revisions */ - if (wl->quirks & WLCORE_QUIRK_END_OF_TRANSACTION) { - bus_ret = wlcore_write32(wl, WL12XX_HOST_WR_ACCESS, - wl->tx_packets_count); - if (bus_ret < 0) - goto out; - } + if (wl->quirks & WLCORE_QUIRK_END_OF_TRANSACTION) + wl1271_write32(wl, WL12XX_HOST_WR_ACCESS, + wl->tx_packets_count); wl1271_handle_tx_low_watermark(wl); } wl12xx_rearm_rx_streaming(wl, active_hlids); - -out: - return bus_ret; } void wl1271_tx_work(struct work_struct *work) @@ -784,11 +755,7 @@ void wl1271_tx_work(struct work_struct *work) if (ret < 0) goto out; - ret = wlcore_tx_work_locked(wl); - if (ret < 0) { - wl12xx_queue_recovery_work(wl); - goto out; - } + wl1271_tx_work_locked(wl); wl1271_ps_elp_sleep(wl); out: @@ -910,28 +877,22 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl, } /* Called upon reception of a TX complete interrupt */ -int wlcore_tx_complete(struct wl1271 *wl) +void wl1271_tx_complete(struct wl1271 *wl) { struct wl1271_acx_mem_map *memmap = (struct wl1271_acx_mem_map *)wl->target_mem_map; u32 count, fw_counter; u32 i; - int ret; /* read the tx results from the chipset */ - ret = wlcore_read(wl, le32_to_cpu(memmap->tx_result), - wl->tx_res_if, sizeof(*wl->tx_res_if), false); - if (ret < 0) - goto out; - + wl1271_read(wl, le32_to_cpu(memmap->tx_result), + wl->tx_res_if, sizeof(*wl->tx_res_if), false); fw_counter = le32_to_cpu(wl->tx_res_if->tx_result_fw_counter); /* write host counter to chipset (to ack) */ - ret = wlcore_write32(wl, le32_to_cpu(memmap->tx_result) + - offsetof(struct wl1271_tx_hw_res_if, - tx_result_host_counter), fw_counter); - if (ret < 0) - goto out; + wl1271_write32(wl, le32_to_cpu(memmap->tx_result) + + offsetof(struct wl1271_tx_hw_res_if, + tx_result_host_counter), fw_counter); count = fw_counter - wl->tx_results_count; wl1271_debug(DEBUG_TX, "tx_complete received, packets: %d", count); @@ -951,11 +912,8 @@ int wlcore_tx_complete(struct wl1271 *wl) wl->tx_results_count++; } - -out: - return ret; } -EXPORT_SYMBOL(wlcore_tx_complete); +EXPORT_SYMBOL(wl1271_tx_complete); void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid) { diff --git a/trunk/drivers/net/wireless/ti/wlcore/tx.h b/trunk/drivers/net/wireless/ti/wlcore/tx.h index 1e939b016155..fa4be1b91135 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/tx.h +++ b/trunk/drivers/net/wireless/ti/wlcore/tx.h @@ -234,8 +234,8 @@ static inline int wl1271_tx_total_queue_count(struct wl1271 *wl) } void wl1271_tx_work(struct work_struct *work); -int wlcore_tx_work_locked(struct wl1271 *wl); -int wlcore_tx_complete(struct wl1271 *wl); +void wl1271_tx_work_locked(struct wl1271 *wl); +void wl1271_tx_complete(struct wl1271 *wl); void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif); void wl12xx_tx_reset(struct wl1271 *wl); void wl1271_tx_flush(struct wl1271 *wl); diff --git a/trunk/drivers/net/wireless/ti/wlcore/wlcore.h b/trunk/drivers/net/wireless/ti/wlcore/wlcore.h index e796974df59b..761a72f4b8d1 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/trunk/drivers/net/wireless/ti/wlcore/wlcore.h @@ -41,9 +41,9 @@ struct wlcore_ops { int (*identify_fw)(struct wl1271 *wl); int (*boot)(struct wl1271 *wl); int (*plt_init)(struct wl1271 *wl); - int (*trigger_cmd)(struct wl1271 *wl, int cmd_box_addr, - void *buf, size_t len); - int (*ack_event)(struct wl1271 *wl); + void (*trigger_cmd)(struct wl1271 *wl, int cmd_box_addr, + void *buf, size_t len); + void (*ack_event)(struct wl1271 *wl); u32 (*calc_tx_blocks)(struct wl1271 *wl, u32 len, u32 spare_blks); void (*set_tx_desc_blocks)(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc, @@ -53,17 +53,17 @@ struct wlcore_ops { struct sk_buff *skb); enum wl_rx_buf_align (*get_rx_buf_align)(struct wl1271 *wl, u32 rx_desc); - int (*prepare_read)(struct wl1271 *wl, u32 rx_desc, u32 len); + void (*prepare_read)(struct wl1271 *wl, u32 rx_desc, u32 len); u32 (*get_rx_packet_len)(struct wl1271 *wl, void *rx_data, u32 data_len); - int (*tx_delayed_compl)(struct wl1271 *wl); + void (*tx_delayed_compl)(struct wl1271 *wl); void (*tx_immediate_compl)(struct wl1271 *wl); int (*hw_init)(struct wl1271 *wl); int (*init_vif)(struct wl1271 *wl, struct wl12xx_vif *wlvif); u32 (*sta_get_ap_rate_mask)(struct wl1271 *wl, struct wl12xx_vif *wlvif); - int (*get_pg_ver)(struct wl1271 *wl, s8 *ver); - int (*get_mac)(struct wl1271 *wl); + s8 (*get_pg_ver)(struct wl1271 *wl); + void (*get_mac)(struct wl1271 *wl); void (*set_tx_desc_csum)(struct wl1271 *wl, struct wl1271_tx_hw_descr *desc, struct sk_buff *skb); @@ -387,9 +387,6 @@ struct wl1271 { /* mutex for protecting the tx_flush function */ struct mutex flush_mutex; - - /* sleep auth value currently configured to FW */ - int sleep_auth; }; int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev); @@ -401,13 +398,6 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd, struct ieee80211_sta *sta, struct ieee80211_key_conf *key_conf); -static inline void -wlcore_set_ht_cap(struct wl1271 *wl, enum ieee80211_band band, - struct ieee80211_sta_ht_cap *ht_cap) -{ - memcpy(&wl->ht_cap[band], ht_cap, sizeof(*ht_cap)); -} - /* Firmware image load chunk size */ #define CHUNK_SIZE 16384 diff --git a/trunk/drivers/net/wireless/ti/wlcore/wlcore_i.h b/trunk/drivers/net/wireless/ti/wlcore/wlcore_i.h index 4273a21cdde1..8260b1e9288a 100644 --- a/trunk/drivers/net/wireless/ti/wlcore/wlcore_i.h +++ b/trunk/drivers/net/wireless/ti/wlcore/wlcore_i.h @@ -209,10 +209,10 @@ struct wl1271_scan { }; struct wl1271_if_operations { - int __must_check (*read)(struct device *child, int addr, void *buf, - size_t len, bool fixed); - int __must_check (*write)(struct device *child, int addr, void *buf, - size_t len, bool fixed); + void (*read)(struct device *child, int addr, void *buf, size_t len, + bool fixed); + void (*write)(struct device *child, int addr, void *buf, size_t len, + bool fixed); void (*reset)(struct device *child); void (*init)(struct device *child); int (*power)(struct device *child, bool enable); @@ -247,7 +247,6 @@ enum wl12xx_flags { WL1271_FLAG_RECOVERY_IN_PROGRESS, WL1271_FLAG_VIF_CHANGE_IN_PROGRESS, WL1271_FLAG_INTENDED_FW_RECOVERY, - WL1271_FLAG_SDIO_FAILED, }; enum wl12xx_vif_flags { diff --git a/trunk/include/linux/bcma/bcma.h b/trunk/include/linux/bcma/bcma.h index 12334f9190cb..8deaf6d050c3 100644 --- a/trunk/include/linux/bcma/bcma.h +++ b/trunk/include/linux/bcma/bcma.h @@ -70,13 +70,6 @@ struct bcma_host_ops { /* Core-ID values. */ #define BCMA_CORE_OOB_ROUTER 0x367 /* Out of band */ -#define BCMA_CORE_4706_CHIPCOMMON 0x500 -#define BCMA_CORE_4706_SOC_RAM 0x50E -#define BCMA_CORE_4706_MAC_GBIT 0x52D -#define BCMA_CORE_AMEMC 0x52E /* DDR1/2 memory controller core */ -#define BCMA_CORE_ALTA 0x534 /* I2S core */ -#define BCMA_CORE_4706_MAC_GBIT_COMMON 0x5DC -#define BCMA_CORE_DDR23_PHY 0x5DD #define BCMA_CORE_INVALID 0x700 #define BCMA_CORE_CHIPCOMMON 0x800 #define BCMA_CORE_ILINE20 0x801 diff --git a/trunk/include/linux/ieee80211.h b/trunk/include/linux/ieee80211.h index e02fc682bb68..ce9af8918514 100644 --- a/trunk/include/linux/ieee80211.h +++ b/trunk/include/linux/ieee80211.h @@ -47,7 +47,6 @@ #define IEEE80211_FCTL_MOREDATA 0x2000 #define IEEE80211_FCTL_PROTECTED 0x4000 #define IEEE80211_FCTL_ORDER 0x8000 -#define IEEE80211_FCTL_CTL_EXT 0x0f00 #define IEEE80211_SCTL_FRAG 0x000F #define IEEE80211_SCTL_SEQ 0xFFF0 @@ -55,7 +54,6 @@ #define IEEE80211_FTYPE_MGMT 0x0000 #define IEEE80211_FTYPE_CTL 0x0004 #define IEEE80211_FTYPE_DATA 0x0008 -#define IEEE80211_FTYPE_EXT 0x000c /* management */ #define IEEE80211_STYPE_ASSOC_REQ 0x0000 @@ -72,7 +70,6 @@ #define IEEE80211_STYPE_ACTION 0x00D0 /* control */ -#define IEEE80211_STYPE_CTL_EXT 0x0060 #define IEEE80211_STYPE_BACK_REQ 0x0080 #define IEEE80211_STYPE_BACK 0x0090 #define IEEE80211_STYPE_PSPOLL 0x00A0 @@ -100,18 +97,6 @@ #define IEEE80211_STYPE_QOS_CFPOLL 0x00E0 #define IEEE80211_STYPE_QOS_CFACKPOLL 0x00F0 -/* extension, added by 802.11ad */ -#define IEEE80211_STYPE_DMG_BEACON 0x0000 - -/* control extension - for IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTL_EXT */ -#define IEEE80211_CTL_EXT_POLL 0x2000 -#define IEEE80211_CTL_EXT_SPR 0x3000 -#define IEEE80211_CTL_EXT_GRANT 0x4000 -#define IEEE80211_CTL_EXT_DMG_CTS 0x5000 -#define IEEE80211_CTL_EXT_DMG_DTS 0x6000 -#define IEEE80211_CTL_EXT_SSW 0x8000 -#define IEEE80211_CTL_EXT_SSW_FBACK 0x9000 -#define IEEE80211_CTL_EXT_SSW_ACK 0xa000 /* miscellaneous IEEE 802.11 constants */ #define IEEE80211_MAX_FRAG_THRESHOLD 2352 @@ -582,26 +567,6 @@ struct ieee80211s_hdr { #define MESH_FLAGS_AE 0x3 #define MESH_FLAGS_PS_DEEP 0x4 -/** - * enum ieee80211_preq_flags - mesh PREQ element flags - * - * @IEEE80211_PREQ_PROACTIVE_PREP_FLAG: proactive PREP subfield - */ -enum ieee80211_preq_flags { - IEEE80211_PREQ_PROACTIVE_PREP_FLAG = 1<<2, -}; - -/** - * enum ieee80211_preq_target_flags - mesh PREQ element per target flags - * - * @IEEE80211_PREQ_TO_FLAG: target only subfield - * @IEEE80211_PREQ_USN_FLAG: unknown target HWMP sequence number subfield - */ -enum ieee80211_preq_target_flags { - IEEE80211_PREQ_TO_FLAG = 1<<0, - IEEE80211_PREQ_USN_FLAG = 1<<2, -}; - /** * struct ieee80211_quiet_ie * @@ -1107,73 +1072,6 @@ struct ieee80211_ht_operation { #define WLAN_HT_SMPS_CONTROL_STATIC 1 #define WLAN_HT_SMPS_CONTROL_DYNAMIC 3 -#define VHT_MCS_SUPPORTED_SET_SIZE 8 - -struct ieee80211_vht_capabilities { - __le32 vht_capabilities_info; - u8 vht_supported_mcs_set[VHT_MCS_SUPPORTED_SET_SIZE]; -} __packed; - -struct ieee80211_vht_operation { - u8 vht_op_info_chwidth; - u8 vht_op_info_chan_center_freq_seg1_idx; - u8 vht_op_info_chan_center_freq_seg2_idx; - __le16 vht_basic_mcs_set; -} __packed; - -/** - * struct ieee80211_vht_mcs_info - VHT MCS information - * @rx_mcs_map: RX MCS map 2 bits for each stream, total 8 streams - * @rx_highest: Indicates highest long GI VHT PPDU data rate - * STA can receive. Rate expressed in units of 1 Mbps. - * If this field is 0 this value should not be used to - * consider the highest RX data rate supported. - * @tx_mcs_map: TX MCS map 2 bits for each stream, total 8 streams - * @tx_highest: Indicates highest long GI VHT PPDU data rate - * STA can transmit. Rate expressed in units of 1 Mbps. - * If this field is 0 this value should not be used to - * consider the highest TX data rate supported. - */ -struct ieee80211_vht_mcs_info { - __le16 rx_mcs_map; - __le16 rx_highest; - __le16 tx_mcs_map; - __le16 tx_highest; -} __packed; - -#define IEEE80211_VHT_MCS_ZERO_TO_SEVEN_SUPPORT 0 -#define IEEE80211_VHT_MCS_ZERO_TO_EIGHT_SUPPORT 1 -#define IEEE80211_VHT_MCS_ZERO_TO_NINE_SUPPORT 2 -#define IEEE80211_VHT_MCS_NOT_SUPPORTED 3 - -/* 802.11ac VHT Capabilities */ -#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895 0x00000000 -#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 0x00000001 -#define IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 0x00000002 -#define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ 0x00000004 -#define IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ 0x00000008 -#define IEEE80211_VHT_CAP_RXLDPC 0x00000010 -#define IEEE80211_VHT_CAP_SHORT_GI_80 0x00000020 -#define IEEE80211_VHT_CAP_SHORT_GI_160 0x00000040 -#define IEEE80211_VHT_CAP_TXSTBC 0x00000080 -#define IEEE80211_VHT_CAP_RXSTBC_1 0x00000100 -#define IEEE80211_VHT_CAP_RXSTBC_2 0x00000200 -#define IEEE80211_VHT_CAP_RXSTBC_3 0x00000300 -#define IEEE80211_VHT_CAP_RXSTBC_4 0x00000400 -#define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE 0x00000800 -#define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE 0x00001000 -#define IEEE80211_VHT_CAP_BEAMFORMER_ANTENNAS_MAX 0x00006000 -#define IEEE80211_VHT_CAP_SOUNDING_DIMENTION_MAX 0x00030000 -#define IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE 0x00080000 -#define IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE 0x00100000 -#define IEEE80211_VHT_CAP_VHT_TXOP_PS 0x00200000 -#define IEEE80211_VHT_CAP_HTC_VHT 0x00400000 -#define IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT 0x00800000 -#define IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_UNSOL_MFB 0x08000000 -#define IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB 0x0c000000 -#define IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN 0x10000000 -#define IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN 0x20000000 - /* Authentication algorithms */ #define WLAN_AUTH_OPEN 0 #define WLAN_AUTH_SHARED_KEY 1 @@ -1206,21 +1104,6 @@ struct ieee80211_vht_mcs_info { #define WLAN_CAPABILITY_QOS (1<<9) #define WLAN_CAPABILITY_SHORT_SLOT_TIME (1<<10) #define WLAN_CAPABILITY_DSSS_OFDM (1<<13) - -/* DMG (60gHz) 802.11ad */ -/* type - bits 0..1 */ -#define WLAN_CAPABILITY_DMG_TYPE_IBSS (1<<0) /* Tx by: STA */ -#define WLAN_CAPABILITY_DMG_TYPE_PBSS (2<<0) /* Tx by: PCP */ -#define WLAN_CAPABILITY_DMG_TYPE_AP (3<<0) /* Tx by: AP */ - -#define WLAN_CAPABILITY_DMG_CBAP_ONLY (1<<2) -#define WLAN_CAPABILITY_DMG_CBAP_SOURCE (1<<3) -#define WLAN_CAPABILITY_DMG_PRIVACY (1<<4) -#define WLAN_CAPABILITY_DMG_ECPAC (1<<5) - -#define WLAN_CAPABILITY_DMG_SPECTRUM_MGMT (1<<8) -#define WLAN_CAPABILITY_DMG_RADIO_MEASURE (1<<12) - /* measurement */ #define IEEE80211_SPCT_MSR_RPRT_MODE_LATE (1<<0) #define IEEE80211_SPCT_MSR_RPRT_MODE_INCAPABLE (1<<1) @@ -1230,6 +1113,7 @@ struct ieee80211_vht_mcs_info { #define IEEE80211_SPCT_MSR_RPRT_TYPE_CCA 1 #define IEEE80211_SPCT_MSR_RPRT_TYPE_RPI 2 + /* 802.11g ERP information element */ #define WLAN_ERP_NON_ERP_PRESENT (1<<0) #define WLAN_ERP_USE_PROTECTION (1<<1) @@ -1241,16 +1125,6 @@ enum { WLAN_ERP_PREAMBLE_LONG = 1, }; -/* Band ID, 802.11ad #8.4.1.45 */ -enum { - IEEE80211_BANDID_TV_WS = 0, /* TV white spaces */ - IEEE80211_BANDID_SUB1 = 1, /* Sub-1 GHz (excluding TV white spaces) */ - IEEE80211_BANDID_2G = 2, /* 2.4 GHz */ - IEEE80211_BANDID_3G = 3, /* 3.6 GHz */ - IEEE80211_BANDID_5G = 4, /* 4.9 and 5 GHz */ - IEEE80211_BANDID_60G = 5, /* 60 GHz */ -}; - /* Status codes */ enum ieee80211_statuscode { WLAN_STATUS_SUCCESS = 0, @@ -1302,17 +1176,6 @@ enum ieee80211_statuscode { WLAN_STATUS_ANTI_CLOG_REQUIRED = 76, WLAN_STATUS_FCG_NOT_SUPP = 78, WLAN_STATUS_STA_NO_TBTT = 78, - /* 802.11ad */ - WLAN_STATUS_REJECTED_WITH_SUGGESTED_CHANGES = 39, - WLAN_STATUS_REJECTED_FOR_DELAY_PERIOD = 47, - WLAN_STATUS_REJECT_WITH_SCHEDULE = 83, - WLAN_STATUS_PENDING_ADMITTING_FST_SESSION = 86, - WLAN_STATUS_PERFORMING_FST_NOW = 87, - WLAN_STATUS_PENDING_GAP_IN_BA_WINDOW = 88, - WLAN_STATUS_REJECT_U_PID_SETTING = 89, - WLAN_STATUS_REJECT_DSE_BAND = 96, - WLAN_STATUS_DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL = 99, - WLAN_STATUS_DENIED_DUE_TO_SPECTRUM_MANAGEMENT = 103, }; @@ -1469,43 +1332,6 @@ enum ieee80211_eid { WLAN_EID_DSE_REGISTERED_LOCATION = 58, WLAN_EID_SUPPORTED_REGULATORY_CLASSES = 59, WLAN_EID_EXT_CHANSWITCH_ANN = 60, - - WLAN_EID_VHT_CAPABILITY = 191, - WLAN_EID_VHT_OPERATION = 192, - - /* 802.11ad */ - WLAN_EID_NON_TX_BSSID_CAP = 83, - WLAN_EID_WAKEUP_SCHEDULE = 143, - WLAN_EID_EXT_SCHEDULE = 144, - WLAN_EID_STA_AVAILABILITY = 145, - WLAN_EID_DMG_TSPEC = 146, - WLAN_EID_DMG_AT = 147, - WLAN_EID_DMG_CAP = 148, - WLAN_EID_DMG_OPERATION = 151, - WLAN_EID_DMG_BSS_PARAM_CHANGE = 152, - WLAN_EID_DMG_BEAM_REFINEMENT = 153, - WLAN_EID_CHANNEL_MEASURE_FEEDBACK = 154, - WLAN_EID_AWAKE_WINDOW = 157, - WLAN_EID_MULTI_BAND = 158, - WLAN_EID_ADDBA_EXT = 159, - WLAN_EID_NEXT_PCP_LIST = 160, - WLAN_EID_PCP_HANDOVER = 161, - WLAN_EID_DMG_LINK_MARGIN = 162, - WLAN_EID_SWITCHING_STREAM = 163, - WLAN_EID_SESSION_TRANSITION = 164, - WLAN_EID_DYN_TONE_PAIRING_REPORT = 165, - WLAN_EID_CLUSTER_REPORT = 166, - WLAN_EID_RELAY_CAP = 167, - WLAN_EID_RELAY_XFER_PARAM_SET = 168, - WLAN_EID_BEAM_LINK_MAINT = 169, - WLAN_EID_MULTIPLE_MAC_ADDR = 170, - WLAN_EID_U_PID = 171, - WLAN_EID_DMG_LINK_ADAPT_ACK = 172, - WLAN_EID_QUIET_PERIOD_REQ = 175, - WLAN_EID_QUIET_PERIOD_RESP = 177, - WLAN_EID_EPAC_POLICY = 182, - WLAN_EID_CLISTER_TIME_OFF = 183, - WLAN_EID_ANTENNA_SECTOR_ID_PATTERN = 190, }; /* Action category code */ @@ -1522,10 +1348,7 @@ enum ieee80211_category { WLAN_CATEGORY_MESH_ACTION = 13, WLAN_CATEGORY_MULTIHOP_ACTION = 14, WLAN_CATEGORY_SELF_PROTECTED = 15, - WLAN_CATEGORY_DMG = 16, WLAN_CATEGORY_WMM = 17, - WLAN_CATEGORY_FST = 18, - WLAN_CATEGORY_UNPROT_DMG = 20, WLAN_CATEGORY_VENDOR_SPECIFIC_PROTECTED = 126, WLAN_CATEGORY_VENDOR_SPECIFIC = 127, }; @@ -1620,7 +1443,7 @@ enum ieee80211_tdls_actioncode { * * @IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET: the default synchronization method * @IEEE80211_SYNC_METHOD_VENDOR: a vendor specific synchronization method - * that will be specified in a vendor specific information element + * that will be specified in a vendor specific information element */ enum { IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET = 1, @@ -1632,7 +1455,7 @@ enum { * * @IEEE80211_PATH_PROTOCOL_HWMP: the default path selection protocol * @IEEE80211_PATH_PROTOCOL_VENDOR: a vendor specific protocol that will - * be specified in a vendor specific information element + * be specified in a vendor specific information element */ enum { IEEE80211_PATH_PROTOCOL_HWMP = 1, @@ -1644,35 +1467,13 @@ enum { * * @IEEE80211_PATH_METRIC_AIRTIME: the default path selection metric * @IEEE80211_PATH_METRIC_VENDOR: a vendor specific metric that will be - * specified in a vendor specific information element + * specified in a vendor specific information element */ enum { IEEE80211_PATH_METRIC_AIRTIME = 1, IEEE80211_PATH_METRIC_VENDOR = 255, }; -/** - * enum ieee80211_root_mode_identifier - root mesh STA mode identifier - * - * These attribute are used by dot11MeshHWMPRootMode to set root mesh STA mode - * - * @IEEE80211_ROOTMODE_NO_ROOT: the mesh STA is not a root mesh STA (default) - * @IEEE80211_ROOTMODE_ROOT: the mesh STA is a root mesh STA if greater than - * this value - * @IEEE80211_PROACTIVE_PREQ_NO_PREP: the mesh STA is a root mesh STA supports - * the proactive PREQ with proactive PREP subfield set to 0 - * @IEEE80211_PROACTIVE_PREQ_WITH_PREP: the mesh STA is a root mesh STA - * supports the proactive PREQ with proactive PREP subfield set to 1 - * @IEEE80211_PROACTIVE_RANN: the mesh STA is a root mesh STA supports - * the proactive RANN - */ -enum ieee80211_root_mode_identifier { - IEEE80211_ROOTMODE_NO_ROOT = 0, - IEEE80211_ROOTMODE_ROOT = 1, - IEEE80211_PROACTIVE_PREQ_NO_PREP = 2, - IEEE80211_PROACTIVE_PREQ_WITH_PREP = 3, - IEEE80211_PROACTIVE_RANN = 4, -}; /* * IEEE 802.11-2007 7.3.2.9 Country information element @@ -1773,7 +1574,6 @@ enum ieee80211_sa_query_action { #define WLAN_CIPHER_SUITE_CCMP 0x000FAC04 #define WLAN_CIPHER_SUITE_WEP104 0x000FAC05 #define WLAN_CIPHER_SUITE_AES_CMAC 0x000FAC06 -#define WLAN_CIPHER_SUITE_GCMP 0x000FAC08 #define WLAN_CIPHER_SUITE_SMS4 0x00147201 @@ -1789,10 +1589,6 @@ enum ieee80211_sa_query_action { #define WLAN_OUI_WFA 0x506f9a #define WLAN_OUI_TYPE_WFA_P2P 9 -#define WLAN_OUI_MICROSOFT 0x0050f2 -#define WLAN_OUI_TYPE_MICROSOFT_WPA 1 -#define WLAN_OUI_TYPE_MICROSOFT_WMM 2 -#define WLAN_OUI_TYPE_MICROSOFT_WPS 4 /* * WMM/802.11e Tspec Element diff --git a/trunk/include/linux/nl80211.h b/trunk/include/linux/nl80211.h index db961a59247f..970afdf5a605 100644 --- a/trunk/include/linux/nl80211.h +++ b/trunk/include/linux/nl80211.h @@ -277,12 +277,6 @@ * @NL80211_CMD_NEW_SURVEY_RESULTS: survey data notification (as a reply to * NL80211_CMD_GET_SURVEY and on the "scan" multicast group) * - * @NL80211_CMD_SET_PMKSA: Add a PMKSA cache entry, using %NL80211_ATTR_MAC - * (for the BSSID) and %NL80211_ATTR_PMKID. - * @NL80211_CMD_DEL_PMKSA: Delete a PMKSA cache entry, using %NL80211_ATTR_MAC - * (for the BSSID) and %NL80211_ATTR_PMKID. - * @NL80211_CMD_FLUSH_PMKSA: Flush all PMKSA cache entries. - * * @NL80211_CMD_REG_CHANGE: indicates to userspace the regulatory domain * has been changed and provides details of the request information * that caused the change such as who initiated the regulatory request @@ -462,10 +456,6 @@ * the frame. * @NL80211_CMD_ACTION_TX_STATUS: Alias for @NL80211_CMD_FRAME_TX_STATUS for * backward compatibility. - * - * @NL80211_CMD_SET_POWER_SAVE: Set powersave, using %NL80211_ATTR_PS_STATE - * @NL80211_CMD_GET_POWER_SAVE: Get powersave status in %NL80211_ATTR_PS_STATE - * * @NL80211_CMD_SET_CQM: Connection quality monitor configuration. This command * is used to configure connection quality monitoring notification trigger * levels. @@ -781,13 +771,6 @@ enum nl80211_commands { * section 7.3.2.25.1, e.g. 0x000FAC04) * @NL80211_ATTR_KEY_SEQ: transmit key sequence number (IV/PN) for TKIP and * CCMP keys, each six bytes in little endian - * @NL80211_ATTR_KEY_DEFAULT: Flag attribute indicating the key is default key - * @NL80211_ATTR_KEY_DEFAULT_MGMT: Flag attribute indicating the key is the - * default management key - * @NL80211_ATTR_CIPHER_SUITES_PAIRWISE: For crypto settings for connect or - * other commands, indicates which pairwise cipher suites are used - * @NL80211_ATTR_CIPHER_SUITE_GROUP: For crypto settings for connect or - * other commands, indicates which group cipher suite is used * * @NL80211_ATTR_BEACON_INTERVAL: beacon interval in TU * @NL80211_ATTR_DTIM_PERIOD: DTIM period for beaconing @@ -1023,8 +1006,6 @@ enum nl80211_commands { * @NL80211_ATTR_ACK: Flag attribute indicating that the frame was * acknowledged by the recipient. * - * @NL80211_ATTR_PS_STATE: powersave state, using &enum nl80211_ps_state values. - * * @NL80211_ATTR_CQM: connection quality monitor configuration in a * nested attribute with %NL80211_ATTR_CQM_* sub-attributes. * @@ -1082,7 +1063,7 @@ enum nl80211_commands { * flag isn't set, the frame will be rejected. This is also used as an * nl80211 capability flag. * - * @NL80211_ATTR_BSS_HT_OPMODE: HT operation mode (u16) + * @NL80211_ATTR_BSS_HTOPMODE: HT operation mode (u16) * * @NL80211_ATTR_KEY_DEFAULT_TYPES: A nested attribute containing flags * attributes, specifying what a key should be set as default as. @@ -1106,10 +1087,10 @@ enum nl80211_commands { * indicate which WoW triggers should be enabled. This is also * used by %NL80211_CMD_GET_WOWLAN to get the currently enabled WoWLAN * triggers. - * + * @NL80211_ATTR_SCHED_SCAN_INTERVAL: Interval between scheduled scan * cycles, in msecs. - * + * @NL80211_ATTR_SCHED_SCAN_MATCH: Nested attribute with one or more * sets of attributes to match during scheduled scans. Only BSSs * that match any of the sets will be reported. These are @@ -1136,7 +1117,7 @@ enum nl80211_commands { * are managed in software: interfaces of these types aren't subject to * any restrictions in their number or combinations. * - * @NL80211_ATTR_REKEY_DATA: nested attribute containing the information + * @%NL80211_ATTR_REKEY_DATA: nested attribute containing the information * necessary for GTK rekeying in the device, see &enum nl80211_rekey_data. * * @NL80211_ATTR_SCAN_SUPP_RATES: rates per to be advertised as supported in scan, @@ -1203,6 +1184,7 @@ enum nl80211_commands { * @NL80211_ATTR_FEATURE_FLAGS: This u32 attribute contains flags from * &enum nl80211_feature_flags and is advertised in wiphy information. * @NL80211_ATTR_PROBE_RESP_OFFLOAD: Indicates that the HW responds to probe + * * requests while operating in AP-mode. * This attribute holds a bitmap of the supported protocols for * offloading (see &enum nl80211_probe_resp_offload_support_attr). @@ -1542,9 +1524,6 @@ enum nl80211_attrs { #define NL80211_MIN_REMAIN_ON_CHANNEL_TIME 10 -/* default RSSI threshold for scan results if none specified. */ -#define NL80211_SCAN_RSSI_THOLD_OFF -300 - /** * enum nl80211_iftype - (virtual) interface types * @@ -1638,20 +1617,12 @@ struct nl80211_sta_flag_update { * * These attribute types are used with %NL80211_STA_INFO_TXRATE * when getting information about the bitrate of a station. - * There are 2 attributes for bitrate, a legacy one that represents - * a 16-bit value, and new one that represents a 32-bit value. - * If the rate value fits into 16 bit, both attributes are reported - * with the same value. If the rate is too high to fit into 16 bits - * (>6.5535Gbps) only 32-bit attribute is included. - * User space tools encouraged to use the 32-bit attribute and fall - * back to the 16-bit one for compatibility with older kernels. * * @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved * @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s) * @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8) * @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 Mhz dualchannel bitrate * @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval - * @NL80211_RATE_INFO_BITRATE32: total bitrate (u32, 100kbit/s) * @NL80211_RATE_INFO_MAX: highest rate_info number currently defined * @__NL80211_RATE_INFO_AFTER_LAST: internal use */ @@ -1661,7 +1632,6 @@ enum nl80211_rate_info { NL80211_RATE_INFO_MCS, NL80211_RATE_INFO_40_MHZ_WIDTH, NL80211_RATE_INFO_SHORT_GI, - NL80211_RATE_INFO_BITRATE32, /* keep last */ __NL80211_RATE_INFO_AFTER_LAST, @@ -1822,9 +1792,6 @@ enum nl80211_mpath_info { * @NL80211_BAND_ATTR_HT_CAPA: HT capabilities, as in the HT information IE * @NL80211_BAND_ATTR_HT_AMPDU_FACTOR: A-MPDU factor, as in 11n * @NL80211_BAND_ATTR_HT_AMPDU_DENSITY: A-MPDU density, as in 11n - * @NL80211_BAND_ATTR_VHT_MCS_SET: 32-byte attribute containing the MCS set as - * defined in 802.11ac - * @NL80211_BAND_ATTR_VHT_CAPA: VHT capabilities, as in the HT information IE * @NL80211_BAND_ATTR_MAX: highest band attribute currently defined * @__NL80211_BAND_ATTR_AFTER_LAST: internal use */ @@ -1838,9 +1805,6 @@ enum nl80211_band_attr { NL80211_BAND_ATTR_HT_AMPDU_FACTOR, NL80211_BAND_ATTR_HT_AMPDU_DENSITY, - NL80211_BAND_ATTR_VHT_MCS_SET, - NL80211_BAND_ATTR_VHT_CAPA, - /* keep last */ __NL80211_BAND_ATTR_AFTER_LAST, NL80211_BAND_ATTR_MAX = __NL80211_BAND_ATTR_AFTER_LAST - 1 @@ -1992,8 +1956,6 @@ enum nl80211_reg_rule_attr { * @__NL80211_SCHED_SCAN_MATCH_ATTR_INVALID: attribute number 0 is reserved * @NL80211_SCHED_SCAN_MATCH_ATTR_SSID: SSID to be used for matching, * only report BSS with matching SSID. - * @NL80211_SCHED_SCAN_MATCH_ATTR_RSSI: RSSI threshold (in dBm) for reporting a - * BSS in scan results. Filtering is turned off if not specified. * @NL80211_SCHED_SCAN_MATCH_ATTR_MAX: highest scheduled scan filter * attribute number currently defined * @__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST: internal use @@ -2001,8 +1963,7 @@ enum nl80211_reg_rule_attr { enum nl80211_sched_scan_match_attr { __NL80211_SCHED_SCAN_MATCH_ATTR_INVALID, - NL80211_SCHED_SCAN_MATCH_ATTR_SSID, - NL80211_SCHED_SCAN_MATCH_ATTR_RSSI, + NL80211_ATTR_SCHED_SCAN_MATCH_SSID, /* keep last */ __NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST, @@ -2010,9 +1971,6 @@ enum nl80211_sched_scan_match_attr { __NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST - 1 }; -/* only for backward compatibility */ -#define NL80211_ATTR_SCHED_SCAN_MATCH_SSID NL80211_SCHED_SCAN_MATCH_ATTR_SSID - /** * enum nl80211_reg_rule_flags - regulatory rule flags * @@ -2132,90 +2090,77 @@ enum nl80211_mntr_flags { * @__NL80211_MESHCONF_INVALID: internal use * * @NL80211_MESHCONF_RETRY_TIMEOUT: specifies the initial retry timeout in - * millisecond units, used by the Peer Link Open message + * millisecond units, used by the Peer Link Open message * * @NL80211_MESHCONF_CONFIRM_TIMEOUT: specifies the initial confirm timeout, in - * millisecond units, used by the peer link management to close a peer link + * millisecond units, used by the peer link management to close a peer link * * @NL80211_MESHCONF_HOLDING_TIMEOUT: specifies the holding timeout, in - * millisecond units + * millisecond units * * @NL80211_MESHCONF_MAX_PEER_LINKS: maximum number of peer links allowed - * on this mesh interface + * on this mesh interface * * @NL80211_MESHCONF_MAX_RETRIES: specifies the maximum number of peer link - * open retries that can be sent to establish a new peer link instance in a - * mesh + * open retries that can be sent to establish a new peer link instance in a + * mesh * * @NL80211_MESHCONF_TTL: specifies the value of TTL field set at a source mesh - * point. + * point. * * @NL80211_MESHCONF_AUTO_OPEN_PLINKS: whether we should automatically - * open peer links when we detect compatible mesh peers. + * open peer links when we detect compatible mesh peers. * * @NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES: the number of action frames - * containing a PREQ that an MP can send to a particular destination (path - * target) + * containing a PREQ that an MP can send to a particular destination (path + * target) * * @NL80211_MESHCONF_PATH_REFRESH_TIME: how frequently to refresh mesh paths - * (in milliseconds) + * (in milliseconds) * * @NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT: minimum length of time to wait - * until giving up on a path discovery (in milliseconds) + * until giving up on a path discovery (in milliseconds) * * @NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT: The time (in TUs) for which mesh - * points receiving a PREQ shall consider the forwarding information from - * the root to be valid. (TU = time unit) + * points receiving a PREQ shall consider the forwarding information from the + * root to be valid. (TU = time unit) * * @NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL: The minimum interval of time (in - * TUs) during which an MP can send only one action frame containing a PREQ - * reference element + * TUs) during which an MP can send only one action frame containing a PREQ + * reference element * * @NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME: The interval of time (in TUs) - * that it takes for an HWMP information element to propagate across the - * mesh + * that it takes for an HWMP information element to propagate across the mesh * * @NL80211_MESHCONF_HWMP_ROOTMODE: whether root mode is enabled or not * * @NL80211_MESHCONF_ELEMENT_TTL: specifies the value of TTL field set at a - * source mesh point for path selection elements. + * source mesh point for path selection elements. * * @NL80211_MESHCONF_HWMP_RANN_INTERVAL: The interval of time (in TUs) between - * root announcements are transmitted. + * root announcements are transmitted. * * @NL80211_MESHCONF_GATE_ANNOUNCEMENTS: Advertise that this mesh station has - * access to a broader network beyond the MBSS. This is done via Root - * Announcement frames. + * access to a broader network beyond the MBSS. This is done via Root + * Announcement frames. * * @NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL: The minimum interval of time (in - * TUs) during which a mesh STA can send only one Action frame containing a - * PERR element. + * TUs) during which a mesh STA can send only one Action frame containing a + * PERR element. * * @NL80211_MESHCONF_FORWARDING: set Mesh STA as forwarding or non-forwarding - * or forwarding entity (default is TRUE - forwarding entity) + * or forwarding entity (default is TRUE - forwarding entity) * * @NL80211_MESHCONF_RSSI_THRESHOLD: RSSI threshold in dBm. This specifies the - * threshold for average signal strength of candidate station to establish - * a peer link. - * - * @NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR: maximum number of neighbors - * to synchronize to for 11s default synchronization method - * (see 11C.12.2.2) - * - * @NL80211_MESHCONF_HT_OPMODE: set mesh HT protection mode. + * threshold for average signal strength of candidate station to establish + * a peer link. * * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute * - * @NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT: The time (in TUs) for - * which mesh STAs receiving a proactive PREQ shall consider the forwarding - * information to the root mesh STA to be valid. - * - * @NL80211_MESHCONF_HWMP_ROOT_INTERVAL: The interval of time (in TUs) between - * proactive PREQs are transmitted. + * @NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR: maximum number of neighbors + * to synchronize to for 11s default synchronization method (see 11C.12.2.2) * - * @NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL: The minimum interval of time - * (in TUs) during which a mesh STA can send only one Action frame - * containing a PREQ element for root path confirmation. + * @NL80211_MESHCONF_HT_OPMODE: set mesh HT protection mode. * * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use */ @@ -2243,9 +2188,6 @@ enum nl80211_meshconf_params { NL80211_MESHCONF_RSSI_THRESHOLD, NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, NL80211_MESHCONF_HT_OPMODE, - NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT, - NL80211_MESHCONF_HWMP_ROOT_INTERVAL, - NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, /* keep last */ __NL80211_MESHCONF_ATTR_AFTER_LAST, @@ -2261,37 +2203,35 @@ enum nl80211_meshconf_params { * @__NL80211_MESH_SETUP_INVALID: Internal use * * @NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL: Enable this option to use a - * vendor specific path selection algorithm or disable it to use the - * default HWMP. + * vendor specific path selection algorithm or disable it to use the default + * HWMP. * * @NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC: Enable this option to use a - * vendor specific path metric or disable it to use the default Airtime - * metric. + * vendor specific path metric or disable it to use the default Airtime + * metric. * * @NL80211_MESH_SETUP_IE: Information elements for this mesh, for instance, a - * robust security network ie, or a vendor specific information element - * that vendors will use to identify the path selection methods and - * metrics in use. + * robust security network ie, or a vendor specific information element that + * vendors will use to identify the path selection methods and metrics in use. * * @NL80211_MESH_SETUP_USERSPACE_AUTH: Enable this option if an authentication - * daemon will be authenticating mesh candidates. + * daemon will be authenticating mesh candidates. * * @NL80211_MESH_SETUP_USERSPACE_AMPE: Enable this option if an authentication - * daemon will be securing peer link frames. AMPE is a secured version of - * Mesh Peering Management (MPM) and is implemented with the assistance of - * a userspace daemon. When this flag is set, the kernel will send peer - * management frames to a userspace daemon that will implement AMPE - * functionality (security capabilities selection, key confirmation, and - * key management). When the flag is unset (default), the kernel can - * autonomously complete (unsecured) mesh peering without the need of a - * userspace daemon. - * - * @NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC: Enable this option to use a - * vendor specific synchronization method or disable it to use the default - * neighbor offset synchronization + * daemon will be securing peer link frames. AMPE is a secured version of Mesh + * Peering Management (MPM) and is implemented with the assistance of a + * userspace daemon. When this flag is set, the kernel will send peer + * management frames to a userspace daemon that will implement AMPE + * functionality (security capabilities selection, key confirmation, and key + * management). When the flag is unset (default), the kernel can autonomously + * complete (unsecured) mesh peering without the need of a userspace daemon. * * @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number * + * @NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC: Enable this option to use a + * vendor specific synchronization method or disable it to use the default + * neighbor offset synchronization + * * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use */ enum nl80211_mesh_setup_params { @@ -2554,19 +2494,12 @@ enum nl80211_tx_rate_attributes { * enum nl80211_band - Frequency band * @NL80211_BAND_2GHZ: 2.4 GHz ISM band * @NL80211_BAND_5GHZ: around 5 GHz band (4.9 - 5.7 GHz) - * @NL80211_BAND_60GHZ: around 60 GHz band (58.32 - 64.80 GHz) */ enum nl80211_band { NL80211_BAND_2GHZ, NL80211_BAND_5GHZ, - NL80211_BAND_60GHZ, }; -/** - * enum nl80211_ps_state - powersave state - * @NL80211_PS_DISABLED: powersave is disabled - * @NL80211_PS_ENABLED: powersave is enabled - */ enum nl80211_ps_state { NL80211_PS_DISABLED, NL80211_PS_ENABLED, diff --git a/trunk/include/net/bluetooth/a2mp.h b/trunk/include/net/bluetooth/a2mp.h deleted file mode 100644 index 6a76e0a0705e..000000000000 --- a/trunk/include/net/bluetooth/a2mp.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - Copyright (c) 2010,2011 Code Aurora Forum. All rights reserved. - Copyright (c) 2011,2012 Intel Corp. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 and - only 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. -*/ - -#ifndef __A2MP_H -#define __A2MP_H - -#include - -#define A2MP_FEAT_EXT 0x8000 - -struct amp_mgr { - struct l2cap_conn *l2cap_conn; - struct l2cap_chan *a2mp_chan; - struct kref kref; - __u8 ident; - __u8 handle; - unsigned long flags; -}; - -struct a2mp_cmd { - __u8 code; - __u8 ident; - __le16 len; - __u8 data[0]; -} __packed; - -/* A2MP command codes */ -#define A2MP_COMMAND_REJ 0x01 -struct a2mp_cmd_rej { - __le16 reason; - __u8 data[0]; -} __packed; - -#define A2MP_DISCOVER_REQ 0x02 -struct a2mp_discov_req { - __le16 mtu; - __le16 ext_feat; -} __packed; - -struct a2mp_cl { - __u8 id; - __u8 type; - __u8 status; -} __packed; - -#define A2MP_DISCOVER_RSP 0x03 -struct a2mp_discov_rsp { - __le16 mtu; - __le16 ext_feat; - struct a2mp_cl cl[0]; -} __packed; - -#define A2MP_CHANGE_NOTIFY 0x04 -#define A2MP_CHANGE_RSP 0x05 - -#define A2MP_GETINFO_REQ 0x06 -struct a2mp_info_req { - __u8 id; -} __packed; - -#define A2MP_GETINFO_RSP 0x07 -struct a2mp_info_rsp { - __u8 id; - __u8 status; - __le32 total_bw; - __le32 max_bw; - __le32 min_latency; - __le16 pal_cap; - __le16 assoc_size; -} __packed; - -#define A2MP_GETAMPASSOC_REQ 0x08 -struct a2mp_amp_assoc_req { - __u8 id; -} __packed; - -#define A2MP_GETAMPASSOC_RSP 0x09 -struct a2mp_amp_assoc_rsp { - __u8 id; - __u8 status; - __u8 amp_assoc[0]; -} __packed; - -#define A2MP_CREATEPHYSLINK_REQ 0x0A -#define A2MP_DISCONNPHYSLINK_REQ 0x0C -struct a2mp_physlink_req { - __u8 local_id; - __u8 remote_id; - __u8 amp_assoc[0]; -} __packed; - -#define A2MP_CREATEPHYSLINK_RSP 0x0B -#define A2MP_DISCONNPHYSLINK_RSP 0x0D -struct a2mp_physlink_rsp { - __u8 local_id; - __u8 remote_id; - __u8 status; -} __packed; - -/* A2MP response status */ -#define A2MP_STATUS_SUCCESS 0x00 -#define A2MP_STATUS_INVALID_CTRL_ID 0x01 -#define A2MP_STATUS_UNABLE_START_LINK_CREATION 0x02 -#define A2MP_STATUS_NO_PHYSICAL_LINK_EXISTS 0x02 -#define A2MP_STATUS_COLLISION_OCCURED 0x03 -#define A2MP_STATUS_DISCONN_REQ_RECVD 0x04 -#define A2MP_STATUS_PHYS_LINK_EXISTS 0x05 -#define A2MP_STATUS_SECURITY_VIOLATION 0x06 - -void amp_mgr_get(struct amp_mgr *mgr); -int amp_mgr_put(struct amp_mgr *mgr); -struct l2cap_chan *a2mp_channel_create(struct l2cap_conn *conn, - struct sk_buff *skb); - -#endif /* __A2MP_H */ diff --git a/trunk/include/net/bluetooth/bluetooth.h b/trunk/include/net/bluetooth/bluetooth.h index 565d4bee1e49..961669b648fd 100644 --- a/trunk/include/net/bluetooth/bluetooth.h +++ b/trunk/include/net/bluetooth/bluetooth.h @@ -1,4 +1,4 @@ -/* +/* BlueZ - Bluetooth protocol stack for Linux Copyright (C) 2000-2001 Qualcomm Incorporated @@ -12,19 +12,22 @@ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY - CLAIM, OR ANY SPECIAL 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 + CLAIM, OR ANY SPECIAL 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. - ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, - COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS SOFTWARE IS DISCLAIMED. */ #ifndef __BLUETOOTH_H #define __BLUETOOTH_H +#include +#include +#include #include #include @@ -165,8 +168,8 @@ typedef struct { #define BDADDR_LE_PUBLIC 0x01 #define BDADDR_LE_RANDOM 0x02 -#define BDADDR_ANY (&(bdaddr_t) {{0, 0, 0, 0, 0, 0} }) -#define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff} }) +#define BDADDR_ANY (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}}) +#define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff}}) /* Copy, swap, convert BD Address */ static inline int bacmp(bdaddr_t *ba1, bdaddr_t *ba2) @@ -212,7 +215,7 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags); int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags); -uint bt_sock_poll(struct file *file, struct socket *sock, poll_table *wait); +uint bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait); int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo); @@ -222,12 +225,12 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock); /* Skb helpers */ struct l2cap_ctrl { - unsigned int sframe:1, - poll:1, - final:1, - fcs:1, - sar:2, - super:2; + unsigned int sframe : 1, + poll : 1, + final : 1, + fcs : 1, + sar : 2, + super : 2; __u16 reqseq; __u16 txseq; __u8 retries; @@ -246,8 +249,7 @@ static inline struct sk_buff *bt_skb_alloc(unsigned int len, gfp_t how) { struct sk_buff *skb; - skb = alloc_skb(len + BT_SKB_RESERVE, how); - if (skb) { + if ((skb = alloc_skb(len + BT_SKB_RESERVE, how))) { skb_reserve(skb, BT_SKB_RESERVE); bt_cb(skb)->incoming = 0; } @@ -259,8 +261,7 @@ static inline struct sk_buff *bt_skb_send_alloc(struct sock *sk, { struct sk_buff *skb; - skb = sock_alloc_send_skb(sk, len + BT_SKB_RESERVE, nb, err); - if (skb) { + if ((skb = sock_alloc_send_skb(sk, len + BT_SKB_RESERVE, nb, err))) { skb_reserve(skb, BT_SKB_RESERVE); bt_cb(skb)->incoming = 0; } diff --git a/trunk/include/net/bluetooth/hci.h b/trunk/include/net/bluetooth/hci.h index 2a6b0b8b7120..66a7b579e31c 100644 --- a/trunk/include/net/bluetooth/hci.h +++ b/trunk/include/net/bluetooth/hci.h @@ -30,9 +30,6 @@ #define HCI_MAX_EVENT_SIZE 260 #define HCI_MAX_FRAME_SIZE (HCI_MAX_ACL_SIZE + 4) -#define HCI_LINK_KEY_SIZE 16 -#define HCI_AMP_LINK_KEY_SIZE (2 * HCI_LINK_KEY_SIZE) - /* HCI dev events */ #define HCI_DEV_REG 1 #define HCI_DEV_UNREG 2 @@ -59,12 +56,9 @@ #define HCI_BREDR 0x00 #define HCI_AMP 0x01 -/* First BR/EDR Controller shall have ID = 0 */ -#define HCI_BREDR_ID 0 - /* HCI device quirks */ enum { - HCI_QUIRK_RESET_ON_CLOSE, + HCI_QUIRK_NO_RESET, HCI_QUIRK_RAW_DEVICE, HCI_QUIRK_FIXUP_BUFFER_SIZE }; @@ -139,8 +133,10 @@ enum { #define HCIINQUIRY _IOR('H', 240, int) /* HCI timeouts */ +#define HCI_CONNECT_TIMEOUT (40000) /* 40 seconds */ #define HCI_DISCONN_TIMEOUT (2000) /* 2 seconds */ #define HCI_PAIRING_TIMEOUT (60000) /* 60 seconds */ +#define HCI_IDLE_TIMEOUT (6000) /* 6 seconds */ #define HCI_INIT_TIMEOUT (10000) /* 10 seconds */ #define HCI_CMD_TIMEOUT (1000) /* 1 seconds */ #define HCI_ACL_TX_TIMEOUT (45000) /* 45 seconds */ @@ -375,7 +371,7 @@ struct hci_cp_reject_conn_req { #define HCI_OP_LINK_KEY_REPLY 0x040b struct hci_cp_link_key_reply { bdaddr_t bdaddr; - __u8 link_key[HCI_LINK_KEY_SIZE]; + __u8 link_key[16]; } __packed; #define HCI_OP_LINK_KEY_NEG_REPLY 0x040c @@ -527,28 +523,6 @@ struct hci_cp_io_capability_neg_reply { __u8 reason; } __packed; -#define HCI_OP_CREATE_PHY_LINK 0x0435 -struct hci_cp_create_phy_link { - __u8 phy_handle; - __u8 key_len; - __u8 key_type; - __u8 key[HCI_AMP_LINK_KEY_SIZE]; -} __packed; - -#define HCI_OP_ACCEPT_PHY_LINK 0x0436 -struct hci_cp_accept_phy_link { - __u8 phy_handle; - __u8 key_len; - __u8 key_type; - __u8 key[HCI_AMP_LINK_KEY_SIZE]; -} __packed; - -#define HCI_OP_DISCONN_PHY_LINK 0x0437 -struct hci_cp_disconn_phy_link { - __u8 phy_handle; - __u8 reason; -} __packed; - #define HCI_OP_SNIFF_MODE 0x0803 struct hci_cp_sniff_mode { __le16 handle; @@ -844,31 +818,6 @@ struct hci_rp_read_local_amp_info { __le32 be_flush_to; } __packed; -#define HCI_OP_READ_LOCAL_AMP_ASSOC 0x140a -struct hci_cp_read_local_amp_assoc { - __u8 phy_handle; - __le16 len_so_far; - __le16 max_len; -} __packed; -struct hci_rp_read_local_amp_assoc { - __u8 status; - __u8 phy_handle; - __le16 rem_len; - __u8 frag[0]; -} __packed; - -#define HCI_OP_WRITE_REMOTE_AMP_ASSOC 0x140b -struct hci_cp_write_remote_amp_assoc { - __u8 phy_handle; - __le16 len_so_far; - __le16 rem_len; - __u8 frag[0]; -} __packed; -struct hci_rp_write_remote_amp_assoc { - __u8 status; - __u8 phy_handle; -} __packed; - #define HCI_OP_LE_SET_EVENT_MASK 0x2001 struct hci_cp_le_set_event_mask { __u8 mask[8]; @@ -1099,7 +1048,7 @@ struct hci_ev_link_key_req { #define HCI_EV_LINK_KEY_NOTIFY 0x18 struct hci_ev_link_key_notify { bdaddr_t bdaddr; - __u8 link_key[HCI_LINK_KEY_SIZE]; + __u8 link_key[16]; __u8 key_type; } __packed; @@ -1195,12 +1144,6 @@ struct extended_inquiry_info { __u8 data[240]; } __packed; -#define HCI_EV_KEY_REFRESH_COMPLETE 0x30 -struct hci_ev_key_refresh_complete { - __u8 status; - __le16 handle; -} __packed; - #define HCI_EV_IO_CAPA_REQUEST 0x31 struct hci_ev_io_capa_request { bdaddr_t bdaddr; @@ -1247,39 +1190,6 @@ struct hci_ev_le_meta { __u8 subevent; } __packed; -#define HCI_EV_PHY_LINK_COMPLETE 0x40 -struct hci_ev_phy_link_complete { - __u8 status; - __u8 phy_handle; -} __packed; - -#define HCI_EV_CHANNEL_SELECTED 0x41 -struct hci_ev_channel_selected { - __u8 phy_handle; -} __packed; - -#define HCI_EV_DISCONN_PHY_LINK_COMPLETE 0x42 -struct hci_ev_disconn_phy_link_complete { - __u8 status; - __u8 phy_handle; - __u8 reason; -} __packed; - -#define HCI_EV_LOGICAL_LINK_COMPLETE 0x45 -struct hci_ev_logical_link_complete { - __u8 status; - __le16 handle; - __u8 phy_handle; - __u8 flow_spec_id; -} __packed; - -#define HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE 0x46 -struct hci_ev_disconn_logical_link_complete { - __u8 status; - __le16 handle; - __u8 reason; -} __packed; - #define HCI_EV_NUM_COMP_BLOCKS 0x48 struct hci_comp_blocks_info { __le16 handle; @@ -1380,6 +1290,7 @@ struct hci_sco_hdr { __u8 dlen; } __packed; +#include static inline struct hci_event_hdr *hci_event_hdr(const struct sk_buff *skb) { return (struct hci_event_hdr *) skb->data; @@ -1396,12 +1307,12 @@ static inline struct hci_sco_hdr *hci_sco_hdr(const struct sk_buff *skb) } /* Command opcode pack/unpack */ -#define hci_opcode_pack(ogf, ocf) ((__u16) ((ocf & 0x03ff)|(ogf << 10))) +#define hci_opcode_pack(ogf, ocf) (__u16) ((ocf & 0x03ff)|(ogf << 10)) #define hci_opcode_ogf(op) (op >> 10) #define hci_opcode_ocf(op) (op & 0x03ff) /* ACL handle and flags pack/unpack */ -#define hci_handle_pack(h, f) ((__u16) ((h & 0x0fff)|(f << 12))) +#define hci_handle_pack(h, f) (__u16) ((h & 0x0fff)|(f << 12)) #define hci_handle(h) (h & 0x0fff) #define hci_flags(h) (h >> 12) diff --git a/trunk/include/net/bluetooth/hci_core.h b/trunk/include/net/bluetooth/hci_core.h index 20fd57367ddc..9fc7728f94e4 100644 --- a/trunk/include/net/bluetooth/hci_core.h +++ b/trunk/include/net/bluetooth/hci_core.h @@ -25,6 +25,7 @@ #ifndef __HCI_CORE_H #define __HCI_CORE_H +#include #include /* HCI priority */ @@ -64,7 +65,7 @@ struct discovery_state { DISCOVERY_RESOLVING, DISCOVERY_STOPPING, } state; - struct list_head all; /* All devices found during inquiry */ + struct list_head all; /* All devices found during inquiry */ struct list_head unknown; /* Name state not known */ struct list_head resolve; /* Name needs to be resolved */ __u32 timestamp; @@ -104,7 +105,7 @@ struct link_key { struct list_head list; bdaddr_t bdaddr; u8 type; - u8 val[HCI_LINK_KEY_SIZE]; + u8 val[16]; u8 pin_len; }; @@ -332,7 +333,6 @@ struct hci_conn { void *l2cap_data; void *sco_data; void *smp_conn; - struct amp_mgr *amp_mgr; struct hci_conn *link; @@ -360,8 +360,7 @@ extern int l2cap_connect_cfm(struct hci_conn *hcon, u8 status); extern int l2cap_disconn_ind(struct hci_conn *hcon); extern int l2cap_disconn_cfm(struct hci_conn *hcon, u8 reason); 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 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); extern int sco_connect_cfm(struct hci_conn *hcon, __u8 status); @@ -430,8 +429,8 @@ enum { static inline bool hci_conn_ssp_enabled(struct hci_conn *conn) { struct hci_dev *hdev = conn->hdev; - return test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) && - test_bit(HCI_CONN_SSP_ENABLED, &conn->flags); + return (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) && + test_bit(HCI_CONN_SSP_ENABLED, &conn->flags)); } static inline void hci_conn_hash_init(struct hci_dev *hdev) @@ -641,19 +640,6 @@ static inline void hci_set_drvdata(struct hci_dev *hdev, void *data) dev_set_drvdata(&hdev->dev, data); } -/* hci_dev_list shall be locked */ -static inline uint8_t __hci_num_ctrl(void) -{ - uint8_t count = 0; - struct list_head *p; - - list_for_each(p, &hci_dev_list) { - count++; - } - - return count; -} - struct hci_dev *hci_dev_get(int index); struct hci_dev *hci_get_route(bdaddr_t *src, bdaddr_t *dst); @@ -675,8 +661,7 @@ int hci_get_conn_info(struct hci_dev *hdev, void __user *arg); int hci_get_auth_info(struct hci_dev *hdev, void __user *arg); int hci_inquiry(void __user *arg); -struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, - bdaddr_t *bdaddr); +struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr); int hci_blacklist_clear(struct hci_dev *hdev); int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type); diff --git a/trunk/include/net/bluetooth/l2cap.h b/trunk/include/net/bluetooth/l2cap.h index d80e3f0691b4..1c7d1cd5e679 100644 --- a/trunk/include/net/bluetooth/l2cap.h +++ b/trunk/include/net/bluetooth/l2cap.h @@ -40,11 +40,11 @@ #define L2CAP_DEFAULT_MONITOR_TO 12000 /* 12 seconds */ #define L2CAP_DEFAULT_MAX_PDU_SIZE 1009 /* Sized for 3-DH5 packet */ #define L2CAP_DEFAULT_ACK_TO 200 +#define L2CAP_LE_DEFAULT_MTU 23 #define L2CAP_DEFAULT_MAX_SDU_SIZE 0xFFFF #define L2CAP_DEFAULT_SDU_ITIME 0xFFFFFFFF #define L2CAP_DEFAULT_ACC_LAT 0xFFFFFFFF #define L2CAP_BREDR_MAX_PAYLOAD 1019 /* 3-DH5 packet */ -#define L2CAP_LE_MIN_MTU 23 #define L2CAP_DISC_TIMEOUT msecs_to_jiffies(100) #define L2CAP_DISC_REJ_TIMEOUT msecs_to_jiffies(5000) @@ -52,8 +52,6 @@ #define L2CAP_CONN_TIMEOUT msecs_to_jiffies(40000) #define L2CAP_INFO_TIMEOUT msecs_to_jiffies(4000) -#define L2CAP_A2MP_DEFAULT_MTU 670 - /* L2CAP socket address */ struct sockaddr_l2 { sa_family_t l2_family; @@ -231,14 +229,9 @@ struct l2cap_conn_rsp { __le16 status; } __packed; -/* protocol/service multiplexer (PSM) */ -#define L2CAP_PSM_SDP 0x0001 -#define L2CAP_PSM_RFCOMM 0x0003 - /* channel indentifier */ #define L2CAP_CID_SIGNALING 0x0001 #define L2CAP_CID_CONN_LESS 0x0002 -#define L2CAP_CID_A2MP 0x0003 #define L2CAP_CID_LE_DATA 0x0004 #define L2CAP_CID_LE_SIGNALING 0x0005 #define L2CAP_CID_SMP 0x0006 @@ -278,9 +271,6 @@ struct l2cap_conf_rsp { #define L2CAP_CONF_PENDING 0x0004 #define L2CAP_CONF_EFS_REJECT 0x0005 -/* configuration req/rsp continuation flag */ -#define L2CAP_CONF_FLAG_CONTINUATION 0x0001 - struct l2cap_conf_opt { __u8 type; __u8 len; @@ -429,6 +419,11 @@ struct l2cap_seq_list { #define L2CAP_SEQ_LIST_CLEAR 0xFFFF #define L2CAP_SEQ_LIST_TAIL 0x8000 +struct srej_list { + __u16 tx_seq; + struct list_head list; +}; + struct l2cap_chan { struct sock *sk; @@ -480,12 +475,14 @@ struct l2cap_chan { __u16 expected_ack_seq; __u16 expected_tx_seq; __u16 buffer_seq; + __u16 buffer_seq_srej; __u16 srej_save_reqseq; __u16 last_acked_seq; __u16 frames_sent; __u16 unacked_frames; __u8 retry_count; __u16 srej_queue_next; + __u8 num_acked; __u16 sdu_len; struct sk_buff *sdu; struct sk_buff *sdu_last_frag; @@ -518,6 +515,7 @@ struct l2cap_chan { struct sk_buff_head srej_q; struct l2cap_seq_list srej_list; struct l2cap_seq_list retrans_list; + struct list_head srej_l; struct list_head list; struct list_head global_l; @@ -530,14 +528,10 @@ struct l2cap_chan { struct l2cap_ops { char *name; - struct l2cap_chan *(*new_connection) (struct l2cap_chan *chan); - int (*recv) (struct l2cap_chan * chan, - struct sk_buff *skb); - void (*teardown) (struct l2cap_chan *chan, int err); - void (*close) (struct l2cap_chan *chan); - void (*state_change) (struct l2cap_chan *chan, - int state); - void (*ready) (struct l2cap_chan *chan); + struct l2cap_chan *(*new_connection) (void *data); + int (*recv) (void *data, struct sk_buff *skb); + void (*close) (void *data); + void (*state_change) (void *data, int state); struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan, unsigned long len, int nb); }; @@ -581,7 +575,6 @@ struct l2cap_conn { #define L2CAP_CHAN_RAW 1 #define L2CAP_CHAN_CONN_LESS 2 #define L2CAP_CHAN_CONN_ORIENTED 3 -#define L2CAP_CHAN_CONN_FIX_A2MP 4 /* ----- L2CAP socket info ----- */ #define l2cap_pi(sk) ((struct l2cap_pinfo *) sk) @@ -604,7 +597,6 @@ enum { CONF_EWS_RECV, CONF_LOC_CONF_PEND, CONF_REM_CONF_PEND, - CONF_NOT_COMPLETE, }; #define L2CAP_CONF_MAX_CONF_REQ 2 @@ -721,7 +713,11 @@ static inline bool l2cap_clear_timer(struct l2cap_chan *chan, #define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t)) #define __clear_chan_timer(c) l2cap_clear_timer(c, &c->chan_timer) +#define __set_retrans_timer(c) l2cap_set_timer(c, &c->retrans_timer, \ + msecs_to_jiffies(L2CAP_DEFAULT_RETRANS_TO)); #define __clear_retrans_timer(c) l2cap_clear_timer(c, &c->retrans_timer) +#define __set_monitor_timer(c) l2cap_set_timer(c, &c->monitor_timer, \ + msecs_to_jiffies(L2CAP_DEFAULT_MONITOR_TO)); #define __clear_monitor_timer(c) l2cap_clear_timer(c, &c->monitor_timer) #define __set_ack_timer(c) l2cap_set_timer(c, &chan->ack_timer, \ msecs_to_jiffies(L2CAP_DEFAULT_ACK_TO)); @@ -740,17 +736,173 @@ static inline __u16 __next_seq(struct l2cap_chan *chan, __u16 seq) return (seq + 1) % (chan->tx_win_max + 1); } -static inline struct l2cap_chan *l2cap_chan_no_new_connection(struct l2cap_chan *chan) +static inline int l2cap_tx_window_full(struct l2cap_chan *ch) +{ + int sub; + + sub = (ch->next_tx_seq - ch->expected_ack_seq) % 64; + + if (sub < 0) + sub += 64; + + return sub == ch->remote_tx_win; +} + +static inline __u16 __get_reqseq(struct l2cap_chan *chan, __u32 ctrl) +{ + if (test_bit(FLAG_EXT_CTRL, &chan->flags)) + return (ctrl & L2CAP_EXT_CTRL_REQSEQ) >> + L2CAP_EXT_CTRL_REQSEQ_SHIFT; + else + return (ctrl & L2CAP_CTRL_REQSEQ) >> L2CAP_CTRL_REQSEQ_SHIFT; +} + +static inline __u32 __set_reqseq(struct l2cap_chan *chan, __u32 reqseq) { - return NULL; + if (test_bit(FLAG_EXT_CTRL, &chan->flags)) + return (reqseq << L2CAP_EXT_CTRL_REQSEQ_SHIFT) & + L2CAP_EXT_CTRL_REQSEQ; + else + return (reqseq << L2CAP_CTRL_REQSEQ_SHIFT) & L2CAP_CTRL_REQSEQ; } -static inline void l2cap_chan_no_teardown(struct l2cap_chan *chan, int err) +static inline __u16 __get_txseq(struct l2cap_chan *chan, __u32 ctrl) { + if (test_bit(FLAG_EXT_CTRL, &chan->flags)) + return (ctrl & L2CAP_EXT_CTRL_TXSEQ) >> + L2CAP_EXT_CTRL_TXSEQ_SHIFT; + else + return (ctrl & L2CAP_CTRL_TXSEQ) >> L2CAP_CTRL_TXSEQ_SHIFT; } -static inline void l2cap_chan_no_ready(struct l2cap_chan *chan) +static inline __u32 __set_txseq(struct l2cap_chan *chan, __u32 txseq) { + if (test_bit(FLAG_EXT_CTRL, &chan->flags)) + return (txseq << L2CAP_EXT_CTRL_TXSEQ_SHIFT) & + L2CAP_EXT_CTRL_TXSEQ; + else + return (txseq << L2CAP_CTRL_TXSEQ_SHIFT) & L2CAP_CTRL_TXSEQ; +} + +static inline bool __is_sframe(struct l2cap_chan *chan, __u32 ctrl) +{ + if (test_bit(FLAG_EXT_CTRL, &chan->flags)) + return ctrl & L2CAP_EXT_CTRL_FRAME_TYPE; + else + return ctrl & L2CAP_CTRL_FRAME_TYPE; +} + +static inline __u32 __set_sframe(struct l2cap_chan *chan) +{ + if (test_bit(FLAG_EXT_CTRL, &chan->flags)) + return L2CAP_EXT_CTRL_FRAME_TYPE; + else + return L2CAP_CTRL_FRAME_TYPE; +} + +static inline __u8 __get_ctrl_sar(struct l2cap_chan *chan, __u32 ctrl) +{ + if (test_bit(FLAG_EXT_CTRL, &chan->flags)) + return (ctrl & L2CAP_EXT_CTRL_SAR) >> L2CAP_EXT_CTRL_SAR_SHIFT; + else + return (ctrl & L2CAP_CTRL_SAR) >> L2CAP_CTRL_SAR_SHIFT; +} + +static inline __u32 __set_ctrl_sar(struct l2cap_chan *chan, __u32 sar) +{ + if (test_bit(FLAG_EXT_CTRL, &chan->flags)) + return (sar << L2CAP_EXT_CTRL_SAR_SHIFT) & L2CAP_EXT_CTRL_SAR; + else + return (sar << L2CAP_CTRL_SAR_SHIFT) & L2CAP_CTRL_SAR; +} + +static inline bool __is_sar_start(struct l2cap_chan *chan, __u32 ctrl) +{ + return __get_ctrl_sar(chan, ctrl) == L2CAP_SAR_START; +} + +static inline __u32 __get_sar_mask(struct l2cap_chan *chan) +{ + if (test_bit(FLAG_EXT_CTRL, &chan->flags)) + return L2CAP_EXT_CTRL_SAR; + else + return L2CAP_CTRL_SAR; +} + +static inline __u8 __get_ctrl_super(struct l2cap_chan *chan, __u32 ctrl) +{ + if (test_bit(FLAG_EXT_CTRL, &chan->flags)) + return (ctrl & L2CAP_EXT_CTRL_SUPERVISE) >> + L2CAP_EXT_CTRL_SUPER_SHIFT; + else + return (ctrl & L2CAP_CTRL_SUPERVISE) >> L2CAP_CTRL_SUPER_SHIFT; +} + +static inline __u32 __set_ctrl_super(struct l2cap_chan *chan, __u32 super) +{ + if (test_bit(FLAG_EXT_CTRL, &chan->flags)) + return (super << L2CAP_EXT_CTRL_SUPER_SHIFT) & + L2CAP_EXT_CTRL_SUPERVISE; + else + return (super << L2CAP_CTRL_SUPER_SHIFT) & + L2CAP_CTRL_SUPERVISE; +} + +static inline __u32 __set_ctrl_final(struct l2cap_chan *chan) +{ + if (test_bit(FLAG_EXT_CTRL, &chan->flags)) + return L2CAP_EXT_CTRL_FINAL; + else + return L2CAP_CTRL_FINAL; +} + +static inline bool __is_ctrl_final(struct l2cap_chan *chan, __u32 ctrl) +{ + if (test_bit(FLAG_EXT_CTRL, &chan->flags)) + return ctrl & L2CAP_EXT_CTRL_FINAL; + else + return ctrl & L2CAP_CTRL_FINAL; +} + +static inline __u32 __set_ctrl_poll(struct l2cap_chan *chan) +{ + if (test_bit(FLAG_EXT_CTRL, &chan->flags)) + return L2CAP_EXT_CTRL_POLL; + else + return L2CAP_CTRL_POLL; +} + +static inline bool __is_ctrl_poll(struct l2cap_chan *chan, __u32 ctrl) +{ + if (test_bit(FLAG_EXT_CTRL, &chan->flags)) + return ctrl & L2CAP_EXT_CTRL_POLL; + else + return ctrl & L2CAP_CTRL_POLL; +} + +static inline __u32 __get_control(struct l2cap_chan *chan, void *p) +{ + if (test_bit(FLAG_EXT_CTRL, &chan->flags)) + return get_unaligned_le32(p); + else + return get_unaligned_le16(p); +} + +static inline void __put_control(struct l2cap_chan *chan, __u32 control, + void *p) +{ + if (test_bit(FLAG_EXT_CTRL, &chan->flags)) + return put_unaligned_le32(control, p); + else + return put_unaligned_le16(control, p); +} + +static inline __u8 __ctrl_size(struct l2cap_chan *chan) +{ + if (test_bit(FLAG_EXT_CTRL, &chan->flags)) + return L2CAP_EXT_HDR_SIZE - L2CAP_HDR_SIZE; + else + return L2CAP_ENH_HDR_SIZE - L2CAP_HDR_SIZE; } extern bool disable_ertm; @@ -774,8 +926,5 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, void l2cap_chan_busy(struct l2cap_chan *chan, int busy); int l2cap_chan_check_security(struct l2cap_chan *chan); void l2cap_chan_set_defaults(struct l2cap_chan *chan); -int l2cap_ertm_init(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); #endif /* __L2CAP_H */ diff --git a/trunk/include/net/cfg80211.h b/trunk/include/net/cfg80211.h index 51f67a9003a9..7319f25250b6 100644 --- a/trunk/include/net/cfg80211.h +++ b/trunk/include/net/cfg80211.h @@ -70,13 +70,11 @@ * * @IEEE80211_BAND_2GHZ: 2.4GHz ISM band * @IEEE80211_BAND_5GHZ: around 5GHz band (4.9-5.7) - * @IEEE80211_BAND_60GHZ: around 60 GHz band (58.32 - 64.80 GHz) * @IEEE80211_NUM_BANDS: number of defined bands */ enum ieee80211_band { IEEE80211_BAND_2GHZ = NL80211_BAND_2GHZ, IEEE80211_BAND_5GHZ = NL80211_BAND_5GHZ, - IEEE80211_BAND_60GHZ = NL80211_BAND_60GHZ, /* keep last */ IEEE80211_NUM_BANDS @@ -212,22 +210,6 @@ struct ieee80211_sta_ht_cap { struct ieee80211_mcs_info mcs; }; -/** - * struct ieee80211_sta_vht_cap - STA's VHT capabilities - * - * This structure describes most essential parameters needed - * to describe 802.11ac VHT capabilities for an STA. - * - * @vht_supported: is VHT supported by the STA - * @cap: VHT capabilities map as described in 802.11ac spec - * @vht_mcs: Supported VHT MCS rates - */ -struct ieee80211_sta_vht_cap { - bool vht_supported; - u32 cap; /* use IEEE80211_VHT_CAP_ */ - struct ieee80211_vht_mcs_info vht_mcs; -}; - /** * struct ieee80211_supported_band - frequency band definition * @@ -251,7 +233,6 @@ struct ieee80211_supported_band { int n_channels; int n_bitrates; struct ieee80211_sta_ht_cap ht_cap; - struct ieee80211_sta_vht_cap vht_cap; }; /* @@ -580,13 +561,11 @@ enum station_info_flags { * @RATE_INFO_FLAGS_MCS: @tx_bitrate_mcs filled * @RATE_INFO_FLAGS_40_MHZ_WIDTH: 40 Mhz width transmission * @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval - * @RATE_INFO_FLAGS_60G: 60gHz MCS */ enum rate_info_flags { RATE_INFO_FLAGS_MCS = 1<<0, RATE_INFO_FLAGS_40_MHZ_WIDTH = 1<<1, RATE_INFO_FLAGS_SHORT_GI = 1<<2, - RATE_INFO_FLAGS_60G = 1<<3, }; /** @@ -648,10 +627,10 @@ struct sta_bss_parameters { * @llid: mesh local link id * @plid: mesh peer link id * @plink_state: mesh peer link state - * @signal: The signal strength, type depends on the wiphy's signal_type. - * For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_. - * @signal_avg: Average signal strength, type depends on the wiphy's signal_type. - * For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_. + * @signal: the signal strength, type depends on the wiphy's signal_type + NOTE: For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_. + * @signal_avg: avg signal strength, type depends on the wiphy's signal_type + NOTE: For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_. * @txrate: current unicast bitrate from this station * @rxrate: current unicast bitrate to this station * @rx_packets: packets received from this station @@ -811,95 +790,43 @@ struct bss_parameters { int ht_opmode; }; -/** +/* * struct mesh_config - 802.11s mesh configuration * * These parameters can be changed while the mesh is active. - * - * @dot11MeshRetryTimeout: the initial retry timeout in millisecond units used - * by the Mesh Peering Open message - * @dot11MeshConfirmTimeout: the initial retry timeout in millisecond units - * used by the Mesh Peering Open message - * @dot11MeshHoldingTimeout: the confirm timeout in millisecond units used by - * the mesh peering management to close a mesh peering - * @dot11MeshMaxPeerLinks: the maximum number of peer links allowed on this - * mesh interface - * @dot11MeshMaxRetries: the maximum number of peer link open retries that can - * be sent to establish a new peer link instance in a mesh - * @dot11MeshTTL: the value of TTL field set at a source mesh STA - * @element_ttl: the value of TTL field set at a mesh STA for path selection - * elements - * @auto_open_plinks: whether we should automatically open peer links when we - * detect compatible mesh peers - * @dot11MeshNbrOffsetMaxNeighbor: the maximum number of neighbors to - * synchronize to for 11s default synchronization method - * @dot11MeshHWMPmaxPREQretries: the number of action frames containing a PREQ - * that an originator mesh STA can send to a particular path target - * @path_refresh_time: how frequently to refresh mesh paths in milliseconds - * @min_discovery_timeout: the minimum length of time to wait until giving up on - * a path discovery in milliseconds - * @dot11MeshHWMPactivePathTimeout: the time (in TUs) for which mesh STAs - * receiving a PREQ shall consider the forwarding information from the - * root to be valid. (TU = time unit) - * @dot11MeshHWMPpreqMinInterval: the minimum interval of time (in TUs) during - * which a mesh STA can send only one action frame containing a PREQ - * element - * @dot11MeshHWMPperrMinInterval: the minimum interval of time (in TUs) during - * which a mesh STA can send only one Action frame containing a PERR - * element - * @dot11MeshHWMPnetDiameterTraversalTime: the interval of time (in TUs) that - * it takes for an HWMP information element to propagate across the mesh - * @dot11MeshHWMPRootMode: the configuration of a mesh STA as root mesh STA - * @dot11MeshHWMPRannInterval: the interval of time (in TUs) between root - * announcements are transmitted - * @dot11MeshGateAnnouncementProtocol: whether to advertise that this mesh - * station has access to a broader network beyond the MBSS. (This is - * missnamed in draft 12.0: dot11MeshGateAnnouncementProtocol set to true - * only means that the station will announce others it's a mesh gate, but - * not necessarily using the gate announcement protocol. Still keeping the - * same nomenclature to be in sync with the spec) - * @dot11MeshForwarding: whether the Mesh STA is forwarding or non-forwarding - * entity (default is TRUE - forwarding entity) - * @rssi_threshold: the threshold for average signal strength of candidate - * station to establish a peer link - * @ht_opmode: mesh HT protection mode - * - * @dot11MeshHWMPactivePathToRootTimeout: The time (in TUs) for which mesh STAs - * receiving a proactive PREQ shall consider the forwarding information to - * the root mesh STA to be valid. - * - * @dot11MeshHWMProotInterval: The interval of time (in TUs) between proactive - * PREQs are transmitted. - * @dot11MeshHWMPconfirmationInterval: The minimum interval of time (in TUs) - * during which a mesh STA can send only one Action frame containing - * a PREQ element for root path confirmation. */ struct mesh_config { + /* Timeouts in ms */ + /* Mesh plink management parameters */ u16 dot11MeshRetryTimeout; u16 dot11MeshConfirmTimeout; u16 dot11MeshHoldingTimeout; u16 dot11MeshMaxPeerLinks; - u8 dot11MeshMaxRetries; - u8 dot11MeshTTL; - u8 element_ttl; + u8 dot11MeshMaxRetries; + u8 dot11MeshTTL; + /* ttl used in path selection information elements */ + u8 element_ttl; bool auto_open_plinks; + /* neighbor offset synchronization */ u32 dot11MeshNbrOffsetMaxNeighbor; - u8 dot11MeshHWMPmaxPREQretries; + /* HWMP parameters */ + u8 dot11MeshHWMPmaxPREQretries; u32 path_refresh_time; u16 min_discovery_timeout; u32 dot11MeshHWMPactivePathTimeout; u16 dot11MeshHWMPpreqMinInterval; u16 dot11MeshHWMPperrMinInterval; u16 dot11MeshHWMPnetDiameterTraversalTime; - u8 dot11MeshHWMPRootMode; + u8 dot11MeshHWMPRootMode; u16 dot11MeshHWMPRannInterval; - bool dot11MeshGateAnnouncementProtocol; + /* This is missnamed in draft 12.0: dot11MeshGateAnnouncementProtocol + * set to true only means that the station will announce others it's a + * mesh gate, but not necessarily using the gate announcement protocol. + * Still keeping the same nomenclature to be in sync with the spec. */ + bool dot11MeshGateAnnouncementProtocol; bool dot11MeshForwarding; s32 rssi_threshold; u16 ht_opmode; - u32 dot11MeshHWMPactivePathToRootTimeout; - u16 dot11MeshHWMProotInterval; - u16 dot11MeshHWMPconfirmationInterval; }; /** @@ -1048,7 +975,6 @@ struct cfg80211_match_set { * @wiphy: the wiphy this was for * @dev: the interface * @channels: channels to scan - * @rssi_thold: don't report scan results below this threshold (in s32 dBm) */ struct cfg80211_sched_scan_request { struct cfg80211_ssid *ssids; @@ -1059,7 +985,6 @@ struct cfg80211_sched_scan_request { size_t ie_len; struct cfg80211_match_set *match_sets; int n_match_sets; - s32 rssi_thold; /* internal */ struct wiphy *wiphy; @@ -1503,8 +1428,9 @@ struct cfg80211_gtk_rekey_data { * interfaces are active this callback should reject the configuration. * If no interfaces are active or the device is down, the channel should * be stored for when a monitor interface becomes active. - * @set_monitor_enabled: Notify driver that there are only monitor - * interfaces running. + * @get_channel: Get the current operating channel, should return %NULL if + * there's no single defined operating channel if for example the + * device implements channel hopping for multi-channel virtual interfaces. * * @scan: Request to do a scan. If returning zero, the scan request is given * the driver, and will be valid until passed to cfg80211_scan_done(). @@ -1811,14 +1737,15 @@ struct cfg80211_ops { struct net_device *dev, u16 noack_map); + struct ieee80211_channel *(*get_channel)(struct wiphy *wiphy, + enum nl80211_channel_type *type); + int (*get_et_sset_count)(struct wiphy *wiphy, struct net_device *dev, int sset); void (*get_et_stats)(struct wiphy *wiphy, struct net_device *dev, struct ethtool_stats *stats, u64 *data); void (*get_et_strings)(struct wiphy *wiphy, struct net_device *dev, u32 sset, u8 *data); - - void (*set_monitor_enabled)(struct wiphy *wiphy, bool enabled); }; /* @@ -2172,9 +2099,7 @@ struct wiphy { char fw_version[ETHTOOL_BUSINFO_LEN]; u32 hw_version; -#ifdef CONFIG_PM struct wiphy_wowlan_support wowlan; -#endif u16 max_remain_on_channel_duration; @@ -2410,11 +2335,6 @@ struct wireless_dev { struct ieee80211_channel *preset_chan; enum nl80211_channel_type preset_chantype; - /* for AP and mesh channel tracking */ - struct ieee80211_channel *channel; - - bool ibss_fixed; - bool ps; int ps_timeout; @@ -3489,7 +3409,7 @@ void cfg80211_ch_switch_notify(struct net_device *dev, int freq, * * return 0 if MCS index >= 32 */ -u32 cfg80211_calculate_bitrate(struct rate_info *rate); +u16 cfg80211_calculate_bitrate(struct rate_info *rate); /* Logging, debugging and troubleshooting/diagnostic helpers. */ diff --git a/trunk/include/net/mac80211.h b/trunk/include/net/mac80211.h index e3fa90ce9ecb..d152f54064fd 100644 --- a/trunk/include/net/mac80211.h +++ b/trunk/include/net/mac80211.h @@ -475,7 +475,7 @@ enum mac80211_rate_control_flags { #define IEEE80211_TX_INFO_RATE_DRIVER_DATA_SIZE 24 /* maximum number of rate stages */ -#define IEEE80211_TX_MAX_RATES 4 +#define IEEE80211_TX_MAX_RATES 5 /** * struct ieee80211_tx_rate - rate selection/status @@ -563,11 +563,11 @@ struct ieee80211_tx_info { } control; struct { struct ieee80211_tx_rate rates[IEEE80211_TX_MAX_RATES]; - int ack_signal; u8 ampdu_ack_len; + int ack_signal; u8 ampdu_len; u8 antenna; - /* 21 bytes free */ + /* 14 bytes free */ } status; struct { struct ieee80211_tx_rate driver_rates[ @@ -634,7 +634,7 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info) info->status.rates[i].count = 0; BUILD_BUG_ON( - offsetof(struct ieee80211_tx_info, status.ack_signal) != 20); + offsetof(struct ieee80211_tx_info, status.ampdu_ack_len) != 23); memset(&info->status.ampdu_ack_len, 0, sizeof(struct ieee80211_tx_info) - offsetof(struct ieee80211_tx_info, status.ampdu_ack_len)); @@ -1896,6 +1896,19 @@ enum ieee80211_rate_control_changed { * The low-level driver should send the frame out based on * configuration in the TX control data. This handler should, * preferably, never fail and stop queues appropriately. + * This must be implemented if @tx_frags is not. + * Must be atomic. + * + * @tx_frags: Called to transmit multiple fragments of a single MSDU. + * This handler must consume all fragments, sending out some of + * them only is useless and it can't ask for some of them to be + * queued again. If the frame is not fragmented the queue has a + * single SKB only. To avoid issues with the networking stack + * when TX status is reported the frames should be removed from + * the skb queue. + * If this is used, the tx_info @vif and @sta pointers will be + * invalid -- you must not use them in that case. + * This must be implemented if @tx isn't. * Must be atomic. * * @start: Called before the first netdevice attached to the hardware @@ -1932,11 +1945,6 @@ enum ieee80211_rate_control_changed { * to also unregister the device. If it returns 1, then mac80211 * will also go through the regular complete restart on resume. * - * @set_wakeup: Enable or disable wakeup when WoWLAN configuration is - * modified. The reason is that device_set_wakeup_enable() is - * supposed to be called when the configuration changes, not only - * in suspend(). - * * @add_interface: Called when a netdevice attached to the hardware is * enabled. Because it is not called for monitor mode devices, @start * and @stop must be implemented. @@ -2241,24 +2249,11 @@ enum ieee80211_rate_control_changed { * @get_et_strings: Ethtool API to get a set of strings to describe stats * and perhaps other supported types of ethtool data-sets. * - * @get_rssi: Get current signal strength in dBm, the function is optional - * and can sleep. - * - * @mgd_prepare_tx: Prepare for transmitting a management frame for association - * before associated. In multi-channel scenarios, a virtual interface is - * bound to a channel before it is associated, but as it isn't associated - * yet it need not necessarily be given airtime, in particular since any - * transmission to a P2P GO needs to be synchronized against the GO's - * powersave state. mac80211 will call this function before transmitting a - * management frame prior to having successfully associated to allow the - * driver to give it channel time for the transmission, to get a response - * and to be able to synchronize with the GO. - * The callback will be called before each transmission and upon return - * mac80211 will transmit the frame right away. - * The callback is optional and can (should!) sleep. */ struct ieee80211_ops { void (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb); + void (*tx_frags)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + struct ieee80211_sta *sta, struct sk_buff_head *skbs); int (*start)(struct ieee80211_hw *hw); void (*stop)(struct ieee80211_hw *hw); #ifdef CONFIG_PM @@ -2393,11 +2388,6 @@ struct ieee80211_ops { void (*get_et_strings)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u32 sset, u8 *data); - int (*get_rssi)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - struct ieee80211_sta *sta, s8 *rssi_dbm); - - void (*mgd_prepare_tx)(struct ieee80211_hw *hw, - struct ieee80211_vif *vif); }; /** @@ -2984,7 +2974,6 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, * ieee80211_generic_frame_duration - Calculate the duration field for a frame * @hw: pointer obtained from ieee80211_alloc_hw(). * @vif: &struct ieee80211_vif pointer from the add_interface callback. - * @band: the band to calculate the frame duration on * @frame_len: the length of the frame. * @rate: the rate at which the frame is going to be transmitted. * @@ -3832,6 +3821,12 @@ void ieee80211_enable_rssi_reports(struct ieee80211_vif *vif, void ieee80211_disable_rssi_reports(struct ieee80211_vif *vif); +int ieee80211_add_srates_ie(struct ieee80211_vif *vif, + struct sk_buff *skb, bool need_basic); + +int ieee80211_add_ext_srates_ie(struct ieee80211_vif *vif, + struct sk_buff *skb, bool need_basic); + /** * ieee80211_ave_rssi - report the average rssi for the specified interface * @@ -3842,4 +3837,28 @@ void ieee80211_disable_rssi_reports(struct ieee80211_vif *vif); */ int ieee80211_ave_rssi(struct ieee80211_vif *vif); +/* Extra debugging macros */ + +#ifdef CONFIG_MAC80211_HT_DEBUG +#define ht_vdbg(fmt, ...) \ + pr_debug(fmt, ##__VA_ARGS__) +#else +#define ht_vdbg(fmt, ...) \ +do { \ + if (0) \ + pr_debug(fmt, ##__VA_ARGS__); \ +} while (0) +#endif + +#ifdef CONFIG_MAC80211_IBSS_DEBUG +#define ibss_vdbg(fmt, ...) \ + pr_debug(fmt, ##__VA_ARGS__) +#else +#define ibss_vdbg(fmt, ...) \ +do { \ + if (0) \ + pr_debug(fmt, ##__VA_ARGS__); \ +} while (0) +#endif + #endif /* MAC80211_H */ diff --git a/trunk/net/bluetooth/Makefile b/trunk/net/bluetooth/Makefile index fa6d94a4602a..2dc5a5700f53 100644 --- a/trunk/net/bluetooth/Makefile +++ b/trunk/net/bluetooth/Makefile @@ -9,5 +9,4 @@ obj-$(CONFIG_BT_CMTP) += cmtp/ obj-$(CONFIG_BT_HIDP) += hidp/ bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o \ - hci_sock.o hci_sysfs.o l2cap_core.o l2cap_sock.o smp.o sco.o lib.o \ - a2mp.o + hci_sock.o hci_sysfs.o l2cap_core.o l2cap_sock.o smp.o sco.o lib.o diff --git a/trunk/net/bluetooth/a2mp.c b/trunk/net/bluetooth/a2mp.c deleted file mode 100644 index fb93250b3938..000000000000 --- a/trunk/net/bluetooth/a2mp.c +++ /dev/null @@ -1,568 +0,0 @@ -/* - Copyright (c) 2010,2011 Code Aurora Forum. All rights reserved. - Copyright (c) 2011,2012 Intel Corp. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 and - only 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. -*/ - -#include -#include -#include -#include - -/* A2MP build & send command helper functions */ -static struct a2mp_cmd *__a2mp_build(u8 code, u8 ident, u16 len, void *data) -{ - struct a2mp_cmd *cmd; - int plen; - - plen = sizeof(*cmd) + len; - cmd = kzalloc(plen, GFP_KERNEL); - if (!cmd) - return NULL; - - cmd->code = code; - cmd->ident = ident; - cmd->len = cpu_to_le16(len); - - memcpy(cmd->data, data, len); - - return cmd; -} - -static void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len, - void *data) -{ - struct l2cap_chan *chan = mgr->a2mp_chan; - struct a2mp_cmd *cmd; - u16 total_len = len + sizeof(*cmd); - struct kvec iv; - struct msghdr msg; - - cmd = __a2mp_build(code, ident, len, data); - if (!cmd) - return; - - iv.iov_base = cmd; - iv.iov_len = total_len; - - memset(&msg, 0, sizeof(msg)); - - msg.msg_iov = (struct iovec *) &iv; - msg.msg_iovlen = 1; - - l2cap_chan_send(chan, &msg, total_len, 0); - - kfree(cmd); -} - -static inline void __a2mp_cl_bredr(struct a2mp_cl *cl) -{ - cl->id = 0; - cl->type = 0; - cl->status = 1; -} - -/* hci_dev_list shall be locked */ -static void __a2mp_add_cl(struct amp_mgr *mgr, struct a2mp_cl *cl, u8 num_ctrl) -{ - int i = 0; - struct hci_dev *hdev; - - __a2mp_cl_bredr(cl); - - list_for_each_entry(hdev, &hci_dev_list, list) { - /* Iterate through AMP controllers */ - if (hdev->id == HCI_BREDR_ID) - continue; - - /* Starting from second entry */ - if (++i >= num_ctrl) - return; - - cl[i].id = hdev->id; - cl[i].type = hdev->amp_type; - cl[i].status = hdev->amp_status; - } -} - -/* Processing A2MP messages */ -static int a2mp_command_rej(struct amp_mgr *mgr, struct sk_buff *skb, - struct a2mp_cmd *hdr) -{ - struct a2mp_cmd_rej *rej = (void *) skb->data; - - if (le16_to_cpu(hdr->len) < sizeof(*rej)) - return -EINVAL; - - BT_DBG("ident %d reason %d", hdr->ident, le16_to_cpu(rej->reason)); - - skb_pull(skb, sizeof(*rej)); - - return 0; -} - -static int a2mp_discover_req(struct amp_mgr *mgr, struct sk_buff *skb, - struct a2mp_cmd *hdr) -{ - struct a2mp_discov_req *req = (void *) skb->data; - u16 len = le16_to_cpu(hdr->len); - struct a2mp_discov_rsp *rsp; - u16 ext_feat; - u8 num_ctrl; - - if (len < sizeof(*req)) - return -EINVAL; - - skb_pull(skb, sizeof(*req)); - - ext_feat = le16_to_cpu(req->ext_feat); - - BT_DBG("mtu %d efm 0x%4.4x", le16_to_cpu(req->mtu), ext_feat); - - /* check that packet is not broken for now */ - while (ext_feat & A2MP_FEAT_EXT) { - if (len < sizeof(ext_feat)) - return -EINVAL; - - ext_feat = get_unaligned_le16(skb->data); - BT_DBG("efm 0x%4.4x", ext_feat); - len -= sizeof(ext_feat); - skb_pull(skb, sizeof(ext_feat)); - } - - read_lock(&hci_dev_list_lock); - - num_ctrl = __hci_num_ctrl(); - len = num_ctrl * sizeof(struct a2mp_cl) + sizeof(*rsp); - rsp = kmalloc(len, GFP_ATOMIC); - if (!rsp) { - read_unlock(&hci_dev_list_lock); - return -ENOMEM; - } - - rsp->mtu = __constant_cpu_to_le16(L2CAP_A2MP_DEFAULT_MTU); - rsp->ext_feat = 0; - - __a2mp_add_cl(mgr, rsp->cl, num_ctrl); - - read_unlock(&hci_dev_list_lock); - - a2mp_send(mgr, A2MP_DISCOVER_RSP, hdr->ident, len, rsp); - - kfree(rsp); - return 0; -} - -static int a2mp_change_notify(struct amp_mgr *mgr, struct sk_buff *skb, - struct a2mp_cmd *hdr) -{ - struct a2mp_cl *cl = (void *) skb->data; - - while (skb->len >= sizeof(*cl)) { - BT_DBG("Controller id %d type %d status %d", cl->id, cl->type, - cl->status); - cl = (struct a2mp_cl *) skb_pull(skb, sizeof(*cl)); - } - - /* TODO send A2MP_CHANGE_RSP */ - - return 0; -} - -static int a2mp_getinfo_req(struct amp_mgr *mgr, struct sk_buff *skb, - struct a2mp_cmd *hdr) -{ - struct a2mp_info_req *req = (void *) skb->data; - struct a2mp_info_rsp rsp; - struct hci_dev *hdev; - - if (le16_to_cpu(hdr->len) < sizeof(*req)) - return -EINVAL; - - BT_DBG("id %d", req->id); - - rsp.id = req->id; - rsp.status = A2MP_STATUS_INVALID_CTRL_ID; - - hdev = hci_dev_get(req->id); - if (hdev && hdev->amp_type != HCI_BREDR) { - rsp.status = 0; - rsp.total_bw = cpu_to_le32(hdev->amp_total_bw); - rsp.max_bw = cpu_to_le32(hdev->amp_max_bw); - rsp.min_latency = cpu_to_le32(hdev->amp_min_latency); - rsp.pal_cap = cpu_to_le16(hdev->amp_pal_cap); - rsp.assoc_size = cpu_to_le16(hdev->amp_assoc_size); - } - - if (hdev) - hci_dev_put(hdev); - - a2mp_send(mgr, A2MP_GETINFO_RSP, hdr->ident, sizeof(rsp), &rsp); - - skb_pull(skb, sizeof(*req)); - return 0; -} - -static int a2mp_getampassoc_req(struct amp_mgr *mgr, struct sk_buff *skb, - struct a2mp_cmd *hdr) -{ - struct a2mp_amp_assoc_req *req = (void *) skb->data; - struct hci_dev *hdev; - - if (le16_to_cpu(hdr->len) < sizeof(*req)) - return -EINVAL; - - BT_DBG("id %d", req->id); - - hdev = hci_dev_get(req->id); - if (!hdev || hdev->amp_type == HCI_BREDR) { - struct a2mp_amp_assoc_rsp rsp; - rsp.id = req->id; - rsp.status = A2MP_STATUS_INVALID_CTRL_ID; - - a2mp_send(mgr, A2MP_GETAMPASSOC_RSP, hdr->ident, sizeof(rsp), - &rsp); - goto clean; - } - - /* Placeholder for HCI Read AMP Assoc */ - -clean: - if (hdev) - hci_dev_put(hdev); - - skb_pull(skb, sizeof(*req)); - return 0; -} - -static int a2mp_createphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb, - struct a2mp_cmd *hdr) -{ - struct a2mp_physlink_req *req = (void *) skb->data; - - struct a2mp_physlink_rsp rsp; - struct hci_dev *hdev; - - if (le16_to_cpu(hdr->len) < sizeof(*req)) - return -EINVAL; - - BT_DBG("local_id %d, remote_id %d", req->local_id, req->remote_id); - - rsp.local_id = req->remote_id; - rsp.remote_id = req->local_id; - - hdev = hci_dev_get(req->remote_id); - if (!hdev || hdev->amp_type != HCI_AMP) { - rsp.status = A2MP_STATUS_INVALID_CTRL_ID; - goto send_rsp; - } - - /* TODO process physlink create */ - - rsp.status = A2MP_STATUS_SUCCESS; - -send_rsp: - if (hdev) - hci_dev_put(hdev); - - a2mp_send(mgr, A2MP_CREATEPHYSLINK_RSP, hdr->ident, sizeof(rsp), - &rsp); - - skb_pull(skb, le16_to_cpu(hdr->len)); - return 0; -} - -static int a2mp_discphyslink_req(struct amp_mgr *mgr, struct sk_buff *skb, - struct a2mp_cmd *hdr) -{ - struct a2mp_physlink_req *req = (void *) skb->data; - struct a2mp_physlink_rsp rsp; - struct hci_dev *hdev; - - if (le16_to_cpu(hdr->len) < sizeof(*req)) - return -EINVAL; - - BT_DBG("local_id %d remote_id %d", req->local_id, req->remote_id); - - rsp.local_id = req->remote_id; - rsp.remote_id = req->local_id; - rsp.status = A2MP_STATUS_SUCCESS; - - hdev = hci_dev_get(req->local_id); - if (!hdev) { - rsp.status = A2MP_STATUS_INVALID_CTRL_ID; - goto send_rsp; - } - - /* TODO Disconnect Phys Link here */ - - hci_dev_put(hdev); - -send_rsp: - a2mp_send(mgr, A2MP_DISCONNPHYSLINK_RSP, hdr->ident, sizeof(rsp), &rsp); - - skb_pull(skb, sizeof(*req)); - return 0; -} - -static inline int a2mp_cmd_rsp(struct amp_mgr *mgr, struct sk_buff *skb, - struct a2mp_cmd *hdr) -{ - BT_DBG("ident %d code %d", hdr->ident, hdr->code); - - skb_pull(skb, le16_to_cpu(hdr->len)); - return 0; -} - -/* Handle A2MP signalling */ -static int a2mp_chan_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) -{ - struct a2mp_cmd *hdr = (void *) skb->data; - struct amp_mgr *mgr = chan->data; - int err = 0; - - amp_mgr_get(mgr); - - while (skb->len >= sizeof(*hdr)) { - struct a2mp_cmd *hdr = (void *) skb->data; - u16 len = le16_to_cpu(hdr->len); - - BT_DBG("code 0x%02x id %d len %d", hdr->code, hdr->ident, len); - - skb_pull(skb, sizeof(*hdr)); - - if (len > skb->len || !hdr->ident) { - err = -EINVAL; - break; - } - - mgr->ident = hdr->ident; - - switch (hdr->code) { - case A2MP_COMMAND_REJ: - a2mp_command_rej(mgr, skb, hdr); - break; - - case A2MP_DISCOVER_REQ: - err = a2mp_discover_req(mgr, skb, hdr); - break; - - case A2MP_CHANGE_NOTIFY: - err = a2mp_change_notify(mgr, skb, hdr); - break; - - case A2MP_GETINFO_REQ: - err = a2mp_getinfo_req(mgr, skb, hdr); - break; - - case A2MP_GETAMPASSOC_REQ: - err = a2mp_getampassoc_req(mgr, skb, hdr); - break; - - case A2MP_CREATEPHYSLINK_REQ: - err = a2mp_createphyslink_req(mgr, skb, hdr); - break; - - case A2MP_DISCONNPHYSLINK_REQ: - err = a2mp_discphyslink_req(mgr, skb, hdr); - break; - - case A2MP_CHANGE_RSP: - case A2MP_DISCOVER_RSP: - case A2MP_GETINFO_RSP: - case A2MP_GETAMPASSOC_RSP: - case A2MP_CREATEPHYSLINK_RSP: - case A2MP_DISCONNPHYSLINK_RSP: - err = a2mp_cmd_rsp(mgr, skb, hdr); - break; - - default: - BT_ERR("Unknown A2MP sig cmd 0x%2.2x", hdr->code); - err = -EINVAL; - break; - } - } - - if (err) { - struct a2mp_cmd_rej rej; - rej.reason = __constant_cpu_to_le16(0); - - BT_DBG("Send A2MP Rej: cmd 0x%2.2x err %d", hdr->code, err); - - a2mp_send(mgr, A2MP_COMMAND_REJ, hdr->ident, sizeof(rej), - &rej); - } - - /* Always free skb and return success error code to prevent - from sending L2CAP Disconnect over A2MP channel */ - kfree_skb(skb); - - amp_mgr_put(mgr); - - return 0; -} - -static void a2mp_chan_close_cb(struct l2cap_chan *chan) -{ - l2cap_chan_destroy(chan); -} - -static void a2mp_chan_state_change_cb(struct l2cap_chan *chan, int state) -{ - struct amp_mgr *mgr = chan->data; - - if (!mgr) - return; - - BT_DBG("chan %p state %s", chan, state_to_string(state)); - - chan->state = state; - - switch (state) { - case BT_CLOSED: - if (mgr) - amp_mgr_put(mgr); - break; - } -} - -static struct sk_buff *a2mp_chan_alloc_skb_cb(struct l2cap_chan *chan, - unsigned long len, int nb) -{ - return bt_skb_alloc(len, GFP_KERNEL); -} - -static struct l2cap_ops a2mp_chan_ops = { - .name = "L2CAP A2MP channel", - .recv = a2mp_chan_recv_cb, - .close = a2mp_chan_close_cb, - .state_change = a2mp_chan_state_change_cb, - .alloc_skb = a2mp_chan_alloc_skb_cb, - - /* Not implemented for A2MP */ - .new_connection = l2cap_chan_no_new_connection, - .teardown = l2cap_chan_no_teardown, - .ready = l2cap_chan_no_ready, -}; - -static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn) -{ - struct l2cap_chan *chan; - int err; - - chan = l2cap_chan_create(); - if (!chan) - return NULL; - - BT_DBG("chan %p", chan); - - chan->chan_type = L2CAP_CHAN_CONN_FIX_A2MP; - chan->flush_to = L2CAP_DEFAULT_FLUSH_TO; - - chan->ops = &a2mp_chan_ops; - - l2cap_chan_set_defaults(chan); - chan->remote_max_tx = chan->max_tx; - chan->remote_tx_win = chan->tx_win; - - chan->retrans_timeout = L2CAP_DEFAULT_RETRANS_TO; - chan->monitor_timeout = L2CAP_DEFAULT_MONITOR_TO; - - skb_queue_head_init(&chan->tx_q); - - chan->mode = L2CAP_MODE_ERTM; - - err = l2cap_ertm_init(chan); - if (err < 0) { - l2cap_chan_del(chan, 0); - return NULL; - } - - chan->conf_state = 0; - - l2cap_chan_add(conn, chan); - - chan->remote_mps = chan->omtu; - chan->mps = chan->omtu; - - chan->state = BT_CONNECTED; - - return chan; -} - -/* AMP Manager functions */ -void amp_mgr_get(struct amp_mgr *mgr) -{ - BT_DBG("mgr %p", mgr); - - kref_get(&mgr->kref); -} - -static void amp_mgr_destroy(struct kref *kref) -{ - struct amp_mgr *mgr = container_of(kref, struct amp_mgr, kref); - - BT_DBG("mgr %p", mgr); - - kfree(mgr); -} - -int amp_mgr_put(struct amp_mgr *mgr) -{ - BT_DBG("mgr %p", mgr); - - return kref_put(&mgr->kref, &_mgr_destroy); -} - -static struct amp_mgr *amp_mgr_create(struct l2cap_conn *conn) -{ - struct amp_mgr *mgr; - struct l2cap_chan *chan; - - mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); - if (!mgr) - return NULL; - - BT_DBG("conn %p mgr %p", conn, mgr); - - mgr->l2cap_conn = conn; - - chan = a2mp_chan_open(conn); - if (!chan) { - kfree(mgr); - return NULL; - } - - mgr->a2mp_chan = chan; - chan->data = mgr; - - conn->hcon->amp_mgr = mgr; - - kref_init(&mgr->kref); - - return mgr; -} - -struct l2cap_chan *a2mp_channel_create(struct l2cap_conn *conn, - struct sk_buff *skb) -{ - struct amp_mgr *mgr; - - mgr = amp_mgr_create(conn); - if (!mgr) { - BT_ERR("Could not create AMP manager"); - return NULL; - } - - BT_DBG("mgr: %p chan %p", mgr, mgr->a2mp_chan); - - return mgr->a2mp_chan; -} diff --git a/trunk/net/bluetooth/af_bluetooth.c b/trunk/net/bluetooth/af_bluetooth.c index f7db5792ec64..3e18af4dadc4 100644 --- a/trunk/net/bluetooth/af_bluetooth.c +++ b/trunk/net/bluetooth/af_bluetooth.c @@ -25,7 +25,18 @@ /* Bluetooth address family and sockets. */ #include + +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include @@ -407,8 +418,7 @@ static inline unsigned int bt_accept_poll(struct sock *parent) return 0; } -unsigned int bt_sock_poll(struct file *file, struct socket *sock, - poll_table *wait) +unsigned int bt_sock_poll(struct file *file, struct socket *sock, poll_table *wait) { struct sock *sk = sock->sk; unsigned int mask = 0; diff --git a/trunk/net/bluetooth/bnep/core.c b/trunk/net/bluetooth/bnep/core.c index 4a6620bc1570..031d7d656754 100644 --- a/trunk/net/bluetooth/bnep/core.c +++ b/trunk/net/bluetooth/bnep/core.c @@ -26,9 +26,26 @@ */ #include + +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include + +#include #include + +#include #include +#include + #include #include @@ -289,7 +306,7 @@ static u8 __bnep_rx_hlen[] = { ETH_ALEN + 2 /* BNEP_COMPRESSED_DST_ONLY */ }; -static int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb) +static inline int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb) { struct net_device *dev = s->dev; struct sk_buff *nskb; @@ -387,7 +404,7 @@ static u8 __bnep_tx_types[] = { BNEP_COMPRESSED }; -static int bnep_tx_frame(struct bnep_session *s, struct sk_buff *skb) +static inline int bnep_tx_frame(struct bnep_session *s, struct sk_buff *skb) { struct ethhdr *eh = (void *) skb->data; struct socket *sock = s->sock; diff --git a/trunk/net/bluetooth/bnep/netdev.c b/trunk/net/bluetooth/bnep/netdev.c index 98f86f91d47c..bc4086480d97 100644 --- a/trunk/net/bluetooth/bnep/netdev.c +++ b/trunk/net/bluetooth/bnep/netdev.c @@ -25,8 +25,16 @@ SOFTWARE IS DISCLAIMED. */ -#include +#include +#include + +#include +#include #include +#include +#include + +#include #include #include @@ -120,7 +128,7 @@ static void bnep_net_timeout(struct net_device *dev) } #ifdef CONFIG_BT_BNEP_MC_FILTER -static int bnep_net_mc_filter(struct sk_buff *skb, struct bnep_session *s) +static inline int bnep_net_mc_filter(struct sk_buff *skb, struct bnep_session *s) { struct ethhdr *eh = (void *) skb->data; @@ -132,7 +140,7 @@ static int bnep_net_mc_filter(struct sk_buff *skb, struct bnep_session *s) #ifdef CONFIG_BT_BNEP_PROTO_FILTER /* Determine ether protocol. Based on eth_type_trans. */ -static u16 bnep_net_eth_proto(struct sk_buff *skb) +static inline u16 bnep_net_eth_proto(struct sk_buff *skb) { struct ethhdr *eh = (void *) skb->data; u16 proto = ntohs(eh->h_proto); @@ -146,7 +154,7 @@ static u16 bnep_net_eth_proto(struct sk_buff *skb) return ETH_P_802_2; } -static int bnep_net_proto_filter(struct sk_buff *skb, struct bnep_session *s) +static inline int bnep_net_proto_filter(struct sk_buff *skb, struct bnep_session *s) { u16 proto = bnep_net_eth_proto(skb); struct bnep_proto_filter *f = s->proto_filter; diff --git a/trunk/net/bluetooth/bnep/sock.c b/trunk/net/bluetooth/bnep/sock.c index 5e5f5b410e0b..180bfc45810d 100644 --- a/trunk/net/bluetooth/bnep/sock.c +++ b/trunk/net/bluetooth/bnep/sock.c @@ -24,8 +24,24 @@ SOFTWARE IS DISCLAIMED. */ -#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include + #include "bnep.h" diff --git a/trunk/net/bluetooth/hci_conn.c b/trunk/net/bluetooth/hci_conn.c index 2fcced377e50..3f18a6ed9731 100644 --- a/trunk/net/bluetooth/hci_conn.c +++ b/trunk/net/bluetooth/hci_conn.c @@ -24,11 +24,24 @@ /* Bluetooth HCI connection handling. */ -#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include #include #include -#include static void hci_le_connect(struct hci_conn *conn) { @@ -41,15 +54,15 @@ static void hci_le_connect(struct hci_conn *conn) conn->sec_level = BT_SECURITY_LOW; memset(&cp, 0, sizeof(cp)); - cp.scan_interval = __constant_cpu_to_le16(0x0060); - cp.scan_window = __constant_cpu_to_le16(0x0030); + cp.scan_interval = cpu_to_le16(0x0060); + cp.scan_window = cpu_to_le16(0x0030); bacpy(&cp.peer_addr, &conn->dst); cp.peer_addr_type = conn->dst_type; - cp.conn_interval_min = __constant_cpu_to_le16(0x0028); - cp.conn_interval_max = __constant_cpu_to_le16(0x0038); - cp.supervision_timeout = __constant_cpu_to_le16(0x002a); - cp.min_ce_len = __constant_cpu_to_le16(0x0000); - cp.max_ce_len = __constant_cpu_to_le16(0x0000); + cp.conn_interval_min = cpu_to_le16(0x0028); + cp.conn_interval_max = cpu_to_le16(0x0038); + cp.supervision_timeout = cpu_to_le16(0x002a); + cp.min_ce_len = cpu_to_le16(0x0000); + cp.max_ce_len = cpu_to_le16(0x0000); hci_send_cmd(hdev, HCI_OP_LE_CREATE_CONN, sizeof(cp), &cp); } @@ -86,7 +99,7 @@ void hci_acl_connect(struct hci_conn *conn) cp.pscan_rep_mode = ie->data.pscan_rep_mode; cp.pscan_mode = ie->data.pscan_mode; cp.clock_offset = ie->data.clock_offset | - __constant_cpu_to_le16(0x8000); + cpu_to_le16(0x8000); } memcpy(conn->dev_class, ie->data.dev_class, 3); @@ -162,9 +175,9 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle) cp.handle = cpu_to_le16(handle); 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.tx_bandwidth = cpu_to_le32(0x00001f40); + cp.rx_bandwidth = cpu_to_le32(0x00001f40); + cp.max_latency = cpu_to_le16(0xffff); cp.voice_setting = cpu_to_le16(hdev->voice_setting); cp.retrans_effort = 0xff; @@ -172,7 +185,7 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle) } void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, - u16 latency, u16 to_multiplier) + u16 latency, u16 to_multiplier) { struct hci_cp_le_conn_update cp; struct hci_dev *hdev = conn->hdev; @@ -184,14 +197,15 @@ void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, cp.conn_interval_max = cpu_to_le16(max); cp.conn_latency = cpu_to_le16(latency); cp.supervision_timeout = cpu_to_le16(to_multiplier); - cp.min_ce_len = __constant_cpu_to_le16(0x0001); - cp.max_ce_len = __constant_cpu_to_le16(0x0001); + cp.min_ce_len = cpu_to_le16(0x0001); + cp.max_ce_len = cpu_to_le16(0x0001); hci_send_cmd(hdev, HCI_OP_LE_CONN_UPDATE, sizeof(cp), &cp); } +EXPORT_SYMBOL(hci_le_conn_update); void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8], - __u8 ltk[16]) + __u8 ltk[16]) { struct hci_dev *hdev = conn->hdev; struct hci_cp_le_start_enc cp; @@ -207,6 +221,7 @@ void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8], hci_send_cmd(hdev, HCI_OP_LE_START_ENC, sizeof(cp), &cp); } +EXPORT_SYMBOL(hci_le_start_enc); /* Device _must_ be locked */ void hci_sco_setup(struct hci_conn *conn, __u8 status) @@ -232,7 +247,7 @@ void hci_sco_setup(struct hci_conn *conn, __u8 status) static void hci_conn_timeout(struct work_struct *work) { struct hci_conn *conn = container_of(work, struct hci_conn, - disc_work.work); + disc_work.work); __u8 reason; BT_DBG("conn %p state %s", conn, state_to_string(conn->state)); @@ -280,9 +295,9 @@ static void hci_conn_enter_sniff_mode(struct hci_conn *conn) if (lmp_sniffsubr_capable(hdev) && lmp_sniffsubr_capable(conn)) { struct hci_cp_sniff_subrate cp; cp.handle = cpu_to_le16(conn->handle); - cp.max_latency = __constant_cpu_to_le16(0); - cp.min_remote_timeout = __constant_cpu_to_le16(0); - cp.min_local_timeout = __constant_cpu_to_le16(0); + cp.max_latency = cpu_to_le16(0); + cp.min_remote_timeout = cpu_to_le16(0); + cp.min_local_timeout = cpu_to_le16(0); hci_send_cmd(hdev, HCI_OP_SNIFF_SUBRATE, sizeof(cp), &cp); } @@ -291,8 +306,8 @@ static void hci_conn_enter_sniff_mode(struct hci_conn *conn) cp.handle = cpu_to_le16(conn->handle); cp.max_interval = cpu_to_le16(hdev->sniff_max_interval); cp.min_interval = cpu_to_le16(hdev->sniff_min_interval); - cp.attempt = __constant_cpu_to_le16(4); - cp.timeout = __constant_cpu_to_le16(1); + cp.attempt = cpu_to_le16(4); + cp.timeout = cpu_to_le16(1); hci_send_cmd(hdev, HCI_OP_SNIFF_MODE, sizeof(cp), &cp); } } @@ -312,7 +327,7 @@ static void hci_conn_auto_accept(unsigned long arg) struct hci_dev *hdev = conn->hdev; hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, sizeof(conn->dst), - &conn->dst); + &conn->dst); } struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) @@ -361,7 +376,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) INIT_DELAYED_WORK(&conn->disc_work, hci_conn_timeout); setup_timer(&conn->idle_timer, hci_conn_idle, (unsigned long)conn); setup_timer(&conn->auto_accept_timer, hci_conn_auto_accept, - (unsigned long) conn); + (unsigned long) conn); atomic_set(&conn->refcnt, 0); @@ -410,10 +425,8 @@ int hci_conn_del(struct hci_conn *conn) } } - hci_chan_list_flush(conn); - if (conn->amp_mgr) - amp_mgr_put(conn->amp_mgr); + hci_chan_list_flush(conn); hci_conn_hash_del(hdev, conn); if (hdev->notify) @@ -441,8 +454,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src) read_lock(&hci_dev_list_lock); list_for_each_entry(d, &hci_dev_list, list) { - if (!test_bit(HCI_UP, &d->flags) || - test_bit(HCI_RAW, &d->flags)) + if (!test_bit(HCI_UP, &d->flags) || test_bit(HCI_RAW, &d->flags)) continue; /* Simple routing: @@ -483,11 +495,6 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, if (type == LE_LINK) { le = hci_conn_hash_lookup_ba(hdev, LE_LINK, dst); if (!le) { - le = hci_conn_hash_lookup_state(hdev, LE_LINK, - BT_CONNECT); - if (le) - return ERR_PTR(-EBUSY); - le = hci_conn_add(hdev, LE_LINK, dst); if (!le) return ERR_PTR(-ENOMEM); @@ -538,7 +545,7 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, hci_conn_hold(sco); if (acl->state == BT_CONNECTED && - (sco->state == BT_OPEN || sco->state == BT_CLOSED)) { + (sco->state == BT_OPEN || sco->state == BT_CLOSED)) { set_bit(HCI_CONN_POWER_SAVE, &acl->flags); hci_conn_enter_active_mode(acl, BT_POWER_FORCE_ACTIVE_ON); @@ -553,6 +560,7 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, return sco; } +EXPORT_SYMBOL(hci_connect); /* Check link security requirement */ int hci_conn_check_link_mode(struct hci_conn *conn) @@ -564,6 +572,7 @@ int hci_conn_check_link_mode(struct hci_conn *conn) return 1; } +EXPORT_SYMBOL(hci_conn_check_link_mode); /* Authenticate remote device */ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) @@ -591,7 +600,7 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) cp.handle = cpu_to_le16(conn->handle); hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, - sizeof(cp), &cp); + sizeof(cp), &cp); if (conn->key_type != 0xff) set_bit(HCI_CONN_REAUTH_PEND, &conn->flags); } @@ -609,7 +618,7 @@ static void hci_conn_encrypt(struct hci_conn *conn) cp.handle = cpu_to_le16(conn->handle); cp.encrypt = 0x01; hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), - &cp); + &cp); } } @@ -639,7 +648,8 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) /* An unauthenticated combination key has sufficient security for security level 1 and 2. */ if (conn->key_type == HCI_LK_UNAUTH_COMBINATION && - (sec_level == BT_SECURITY_MEDIUM || sec_level == BT_SECURITY_LOW)) + (sec_level == BT_SECURITY_MEDIUM || + sec_level == BT_SECURITY_LOW)) goto encrypt; /* A combination key has always sufficient security for the security @@ -647,7 +657,8 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) is generated using maximum PIN code length (16). For pre 2.1 units. */ if (conn->key_type == HCI_LK_COMBINATION && - (sec_level != BT_SECURITY_HIGH || conn->pin_length == 16)) + (sec_level != BT_SECURITY_HIGH || + conn->pin_length == 16)) goto encrypt; auth: @@ -690,11 +701,12 @@ int hci_conn_change_link_key(struct hci_conn *conn) struct hci_cp_change_conn_link_key cp; cp.handle = cpu_to_le16(conn->handle); hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY, - sizeof(cp), &cp); + sizeof(cp), &cp); } return 0; } +EXPORT_SYMBOL(hci_conn_change_link_key); /* Switch role */ int hci_conn_switch_role(struct hci_conn *conn, __u8 role) @@ -740,7 +752,7 @@ void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active) timer: if (hdev->idle_timeout > 0) mod_timer(&conn->idle_timer, - jiffies + msecs_to_jiffies(hdev->idle_timeout)); + jiffies + msecs_to_jiffies(hdev->idle_timeout)); } /* Drop all connection on the device */ @@ -790,7 +802,7 @@ EXPORT_SYMBOL(hci_conn_put_device); int hci_get_conn_list(void __user *arg) { - struct hci_conn *c; + register struct hci_conn *c; struct hci_conn_list_req req, *cl; struct hci_conn_info *ci; struct hci_dev *hdev; diff --git a/trunk/net/bluetooth/hci_core.c b/trunk/net/bluetooth/hci_core.c index 08994ecc3b6a..411ace8e647b 100644 --- a/trunk/net/bluetooth/hci_core.c +++ b/trunk/net/bluetooth/hci_core.c @@ -25,10 +25,28 @@ /* Bluetooth HCI core. */ -#include -#include - +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include + +#include +#include #include #include @@ -47,9 +65,6 @@ DEFINE_RWLOCK(hci_dev_list_lock); LIST_HEAD(hci_cb_list); DEFINE_RWLOCK(hci_cb_list_lock); -/* HCI ID Numbering */ -static DEFINE_IDA(hci_index_ida); - /* ---- HCI notifications ---- */ static void hci_notify(struct hci_dev *hdev, int event) @@ -109,9 +124,8 @@ static void hci_req_cancel(struct hci_dev *hdev, int err) } /* Execute request and wait for completion. */ -static int __hci_request(struct hci_dev *hdev, - void (*req)(struct hci_dev *hdev, unsigned long opt), - unsigned long opt, __u32 timeout) +static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt), + unsigned long opt, __u32 timeout) { DECLARE_WAITQUEUE(wait, current); int err = 0; @@ -152,9 +166,8 @@ static int __hci_request(struct hci_dev *hdev, return err; } -static int hci_request(struct hci_dev *hdev, - void (*req)(struct hci_dev *hdev, unsigned long opt), - unsigned long opt, __u32 timeout) +static inline int hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt), + unsigned long opt, __u32 timeout) { int ret; @@ -189,7 +202,7 @@ static void bredr_init(struct hci_dev *hdev) /* Mandatory initialization */ /* Reset */ - if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) { + if (!test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) { set_bit(HCI_RESET, &hdev->flags); hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); } @@ -222,7 +235,7 @@ static void bredr_init(struct hci_dev *hdev) hci_send_cmd(hdev, HCI_OP_SET_EVENT_FLT, 1, &flt_type); /* Connection accept timeout ~20 secs */ - param = __constant_cpu_to_le16(0x7d00); + param = cpu_to_le16(0x7d00); hci_send_cmd(hdev, HCI_OP_WRITE_CA_TIMEOUT, 2, ¶m); bacpy(&cp.bdaddr, BDADDR_ANY); @@ -404,8 +417,7 @@ static void inquiry_cache_flush(struct hci_dev *hdev) INIT_LIST_HEAD(&cache->resolve); } -struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, - bdaddr_t *bdaddr) +struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr) { struct discovery_state *cache = &hdev->discovery; struct inquiry_entry *e; @@ -466,7 +478,7 @@ void hci_inquiry_cache_update_resolve(struct hci_dev *hdev, list_for_each_entry(p, &cache->resolve, list) { if (p->name_state != NAME_PENDING && - abs(p->data.rssi) >= abs(ie->data.rssi)) + abs(p->data.rssi) >= abs(ie->data.rssi)) break; pos = &p->list; } @@ -491,7 +503,7 @@ bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, *ssp = true; if (ie->name_state == NAME_NEEDED && - data->rssi != ie->data.rssi) { + data->rssi != ie->data.rssi) { ie->data.rssi = data->rssi; hci_inquiry_cache_update_resolve(hdev, ie); } @@ -515,7 +527,7 @@ bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, update: if (name_known && ie->name_state != NAME_KNOWN && - ie->name_state != NAME_PENDING) { + ie->name_state != NAME_PENDING) { ie->name_state = NAME_KNOWN; list_del(&ie->list); } @@ -593,7 +605,8 @@ int hci_inquiry(void __user *arg) hci_dev_lock(hdev); if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || - inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { + inquiry_cache_empty(hdev) || + ir.flags & IREQ_CACHE_FLUSH) { inquiry_cache_flush(hdev); do_inquiry = 1; } @@ -607,9 +620,7 @@ int hci_inquiry(void __user *arg) goto done; } - /* for unlimited number of responses we will use buffer with - * 255 entries - */ + /* for unlimited number of responses we will use buffer with 255 entries */ max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp; /* cache_dump can't sleep. Therefore we allocate temp buffer and then @@ -630,7 +641,7 @@ int hci_inquiry(void __user *arg) if (!copy_to_user(ptr, &ir, sizeof(ir))) { ptr += sizeof(ir); if (copy_to_user(ptr, buf, sizeof(struct inquiry_info) * - ir.num_rsp)) + ir.num_rsp)) err = -EFAULT; } else err = -EFAULT; @@ -691,11 +702,11 @@ int hci_dev_open(__u16 dev) hdev->init_last_cmd = 0; ret = __hci_request(hdev, hci_init_req, 0, - msecs_to_jiffies(HCI_INIT_TIMEOUT)); + msecs_to_jiffies(HCI_INIT_TIMEOUT)); if (lmp_host_le_capable(hdev)) ret = __hci_request(hdev, hci_le_init_req, 0, - msecs_to_jiffies(HCI_INIT_TIMEOUT)); + msecs_to_jiffies(HCI_INIT_TIMEOUT)); clear_bit(HCI_INIT, &hdev->flags); } @@ -780,10 +791,10 @@ static int hci_dev_do_close(struct hci_dev *hdev) skb_queue_purge(&hdev->cmd_q); atomic_set(&hdev->cmd_cnt, 1); if (!test_bit(HCI_RAW, &hdev->flags) && - test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) { + test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) { set_bit(HCI_INIT, &hdev->flags); __hci_request(hdev, hci_reset_req, 0, - msecs_to_jiffies(250)); + msecs_to_jiffies(250)); clear_bit(HCI_INIT, &hdev->flags); } @@ -873,7 +884,7 @@ int hci_dev_reset(__u16 dev) if (!test_bit(HCI_RAW, &hdev->flags)) ret = __hci_request(hdev, hci_reset_req, 0, - msecs_to_jiffies(HCI_INIT_TIMEOUT)); + msecs_to_jiffies(HCI_INIT_TIMEOUT)); done: hci_req_unlock(hdev); @@ -913,7 +924,7 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg) switch (cmd) { case HCISETAUTH: err = hci_request(hdev, hci_auth_req, dr.dev_opt, - msecs_to_jiffies(HCI_INIT_TIMEOUT)); + msecs_to_jiffies(HCI_INIT_TIMEOUT)); break; case HCISETENCRYPT: @@ -925,23 +936,23 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg) if (!test_bit(HCI_AUTH, &hdev->flags)) { /* Auth must be enabled first */ err = hci_request(hdev, hci_auth_req, dr.dev_opt, - msecs_to_jiffies(HCI_INIT_TIMEOUT)); + msecs_to_jiffies(HCI_INIT_TIMEOUT)); if (err) break; } err = hci_request(hdev, hci_encrypt_req, dr.dev_opt, - msecs_to_jiffies(HCI_INIT_TIMEOUT)); + msecs_to_jiffies(HCI_INIT_TIMEOUT)); break; case HCISETSCAN: err = hci_request(hdev, hci_scan_req, dr.dev_opt, - msecs_to_jiffies(HCI_INIT_TIMEOUT)); + msecs_to_jiffies(HCI_INIT_TIMEOUT)); break; case HCISETLINKPOL: err = hci_request(hdev, hci_linkpol_req, dr.dev_opt, - msecs_to_jiffies(HCI_INIT_TIMEOUT)); + msecs_to_jiffies(HCI_INIT_TIMEOUT)); break; case HCISETLINKMODE: @@ -1092,7 +1103,7 @@ static void hci_power_on(struct work_struct *work) if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) schedule_delayed_work(&hdev->power_off, - msecs_to_jiffies(AUTO_OFF_TIMEOUT)); + msecs_to_jiffies(AUTO_OFF_TIMEOUT)); if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) mgmt_index_added(hdev); @@ -1101,7 +1112,7 @@ static void hci_power_on(struct work_struct *work) static void hci_power_off(struct work_struct *work) { struct hci_dev *hdev = container_of(work, struct hci_dev, - power_off.work); + power_off.work); BT_DBG("%s", hdev->name); @@ -1182,7 +1193,7 @@ struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr) } static bool hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn, - u8 key_type, u8 old_key_type) + u8 key_type, u8 old_key_type) { /* Legacy key */ if (key_type < 0x03) @@ -1223,7 +1234,7 @@ struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]) list_for_each_entry(k, &hdev->long_term_keys, list) { if (k->ediv != ediv || - memcmp(rand, k->rand, sizeof(k->rand))) + memcmp(rand, k->rand, sizeof(k->rand))) continue; return k; @@ -1231,6 +1242,7 @@ struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, u8 rand[8]) return NULL; } +EXPORT_SYMBOL(hci_find_ltk); struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type) @@ -1239,11 +1251,12 @@ struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, list_for_each_entry(k, &hdev->long_term_keys, list) if (addr_type == k->bdaddr_type && - bacmp(bdaddr, &k->bdaddr) == 0) + bacmp(bdaddr, &k->bdaddr) == 0) return k; return NULL; } +EXPORT_SYMBOL(hci_find_ltk_by_addr); int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len) @@ -1270,14 +1283,15 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key, * combination key for legacy pairing even when there's no * previous key */ if (type == HCI_LK_CHANGED_COMBINATION && - (!conn || conn->remote_auth == 0xff) && old_key_type == 0xff) { + (!conn || conn->remote_auth == 0xff) && + old_key_type == 0xff) { type = HCI_LK_COMBINATION; if (conn) conn->key_type = type; } bacpy(&key->bdaddr, bdaddr); - memcpy(key->val, val, HCI_LINK_KEY_SIZE); + memcpy(key->val, val, 16); key->pin_len = pin_len; if (type == HCI_LK_CHANGED_COMBINATION) @@ -1526,7 +1540,6 @@ static void le_scan_enable_req(struct hci_dev *hdev, unsigned long opt) memset(&cp, 0, sizeof(cp)); cp.enable = 1; - cp.filter_dup = 1; hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); } @@ -1694,39 +1707,41 @@ EXPORT_SYMBOL(hci_free_dev); /* Register HCI device */ int hci_register_dev(struct hci_dev *hdev) { + struct list_head *head, *p; int id, error; if (!hdev->open || !hdev->close) return -EINVAL; + write_lock(&hci_dev_list_lock); + /* Do not allow HCI_AMP devices to register at index 0, * so the index can be used as the AMP controller ID. */ - switch (hdev->dev_type) { - case HCI_BREDR: - id = ida_simple_get(&hci_index_ida, 0, 0, GFP_KERNEL); - break; - case HCI_AMP: - id = ida_simple_get(&hci_index_ida, 1, 0, GFP_KERNEL); - break; - default: - return -EINVAL; - } + id = (hdev->dev_type == HCI_BREDR) ? 0 : 1; + head = &hci_dev_list; - if (id < 0) - return id; + /* Find first available device id */ + list_for_each(p, &hci_dev_list) { + int nid = list_entry(p, struct hci_dev, list)->id; + if (nid > id) + break; + if (nid == id) + id++; + head = p; + } sprintf(hdev->name, "hci%d", id); hdev->id = id; BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); - write_lock(&hci_dev_list_lock); - list_add(&hdev->list, &hci_dev_list); + list_add(&hdev->list, head); + write_unlock(&hci_dev_list_lock); hdev->workqueue = alloc_workqueue(hdev->name, WQ_HIGHPRI | WQ_UNBOUND | - WQ_MEM_RECLAIM, 1); + WQ_MEM_RECLAIM, 1); if (!hdev->workqueue) { error = -ENOMEM; goto err; @@ -1737,8 +1752,7 @@ int hci_register_dev(struct hci_dev *hdev) goto err_wqueue; hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev, - RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, - hdev); + RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, hdev); if (hdev->rfkill) { if (rfkill_register(hdev->rfkill) < 0) { rfkill_destroy(hdev->rfkill); @@ -1758,7 +1772,6 @@ int hci_register_dev(struct hci_dev *hdev) err_wqueue: destroy_workqueue(hdev->workqueue); err: - ida_simple_remove(&hci_index_ida, hdev->id); write_lock(&hci_dev_list_lock); list_del(&hdev->list); write_unlock(&hci_dev_list_lock); @@ -1770,14 +1783,12 @@ EXPORT_SYMBOL(hci_register_dev); /* Unregister HCI device */ void hci_unregister_dev(struct hci_dev *hdev) { - int i, id; + int i; BT_DBG("%p name %s bus %d", hdev, hdev->name, hdev->bus); set_bit(HCI_UNREGISTER, &hdev->dev_flags); - id = hdev->id; - write_lock(&hci_dev_list_lock); list_del(&hdev->list); write_unlock(&hci_dev_list_lock); @@ -1788,7 +1799,7 @@ void hci_unregister_dev(struct hci_dev *hdev) kfree_skb(hdev->reassembly[i]); if (!test_bit(HCI_INIT, &hdev->flags) && - !test_bit(HCI_SETUP, &hdev->dev_flags)) { + !test_bit(HCI_SETUP, &hdev->dev_flags)) { hci_dev_lock(hdev); mgmt_index_removed(hdev); hci_dev_unlock(hdev); @@ -1818,8 +1829,6 @@ void hci_unregister_dev(struct hci_dev *hdev) hci_dev_unlock(hdev); hci_dev_put(hdev); - - ida_simple_remove(&hci_index_ida, id); } EXPORT_SYMBOL(hci_unregister_dev); @@ -1844,7 +1853,7 @@ int hci_recv_frame(struct sk_buff *skb) { struct hci_dev *hdev = (struct hci_dev *) skb->dev; if (!hdev || (!test_bit(HCI_UP, &hdev->flags) - && !test_bit(HCI_INIT, &hdev->flags))) { + && !test_bit(HCI_INIT, &hdev->flags))) { kfree_skb(skb); return -ENXIO; } @@ -1863,7 +1872,7 @@ int hci_recv_frame(struct sk_buff *skb) EXPORT_SYMBOL(hci_recv_frame); static int hci_reassembly(struct hci_dev *hdev, int type, void *data, - int count, __u8 index) + int count, __u8 index) { int len = 0; int hlen = 0; @@ -1872,7 +1881,7 @@ static int hci_reassembly(struct hci_dev *hdev, int type, void *data, struct bt_skb_cb *scb; if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || - index >= NUM_REASSEMBLY) + index >= NUM_REASSEMBLY) return -EILSEQ; skb = hdev->reassembly[index]; @@ -2014,7 +2023,7 @@ int hci_recv_stream_fragment(struct hci_dev *hdev, void *data, int count) type = bt_cb(skb)->pkt_type; rem = hci_reassembly(hdev, type, data, count, - STREAM_REASSEMBLY); + STREAM_REASSEMBLY); if (rem < 0) return rem; @@ -2148,7 +2157,7 @@ static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags) } static void hci_queue_acl(struct hci_conn *conn, struct sk_buff_head *queue, - struct sk_buff *skb, __u16 flags) + struct sk_buff *skb, __u16 flags) { struct hci_dev *hdev = conn->hdev; struct sk_buff *list; @@ -2207,6 +2216,7 @@ void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) queue_work(hdev->workqueue, &hdev->tx_work); } +EXPORT_SYMBOL(hci_send_acl); /* Send SCO data */ void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) @@ -2229,12 +2239,12 @@ void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb) skb_queue_tail(&conn->data_q, skb); queue_work(hdev->workqueue, &hdev->tx_work); } +EXPORT_SYMBOL(hci_send_sco); /* ---- HCI TX task (outgoing data) ---- */ /* HCI Connection scheduler */ -static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, - int *quote) +static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote) { struct hci_conn_hash *h = &hdev->conn_hash; struct hci_conn *conn = NULL, *c; @@ -2293,7 +2303,7 @@ static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, return conn; } -static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) +static inline void hci_link_tx_to(struct hci_dev *hdev, __u8 type) { struct hci_conn_hash *h = &hdev->conn_hash; struct hci_conn *c; @@ -2306,16 +2316,16 @@ static void hci_link_tx_to(struct hci_dev *hdev, __u8 type) list_for_each_entry_rcu(c, &h->list, list) { if (c->type == type && c->sent) { BT_ERR("%s killing stalled connection %s", - hdev->name, batostr(&c->dst)); - hci_acl_disconn(c, HCI_ERROR_REMOTE_USER_TERM); + hdev->name, batostr(&c->dst)); + hci_acl_disconn(c, 0x13); } } rcu_read_unlock(); } -static struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, - int *quote) +static inline struct hci_chan *hci_chan_sent(struct hci_dev *hdev, __u8 type, + int *quote) { struct hci_conn_hash *h = &hdev->conn_hash; struct hci_chan *chan = NULL; @@ -2432,7 +2442,7 @@ static void hci_prio_recalculate(struct hci_dev *hdev, __u8 type) skb->priority = HCI_PRIO_MAX - 1; BT_DBG("chan %p skb %p promoted to %d", chan, skb, - skb->priority); + skb->priority); } if (hci_conn_num(hdev, type) == num) @@ -2449,18 +2459,18 @@ static inline int __get_blocks(struct hci_dev *hdev, struct sk_buff *skb) return DIV_ROUND_UP(skb->len - HCI_ACL_HDR_SIZE, hdev->block_len); } -static void __check_timeout(struct hci_dev *hdev, unsigned int cnt) +static inline void __check_timeout(struct hci_dev *hdev, unsigned int cnt) { if (!test_bit(HCI_RAW, &hdev->flags)) { /* ACL tx timeout must be longer than maximum * link supervision timeout (40.9 seconds) */ if (!cnt && time_after(jiffies, hdev->acl_last_tx + - msecs_to_jiffies(HCI_ACL_TX_TIMEOUT))) + msecs_to_jiffies(HCI_ACL_TX_TIMEOUT))) hci_link_tx_to(hdev, ACL_LINK); } } -static void hci_sched_acl_pkt(struct hci_dev *hdev) +static inline void hci_sched_acl_pkt(struct hci_dev *hdev) { unsigned int cnt = hdev->acl_cnt; struct hci_chan *chan; @@ -2470,11 +2480,11 @@ static void hci_sched_acl_pkt(struct hci_dev *hdev) __check_timeout(hdev, cnt); while (hdev->acl_cnt && - (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { + (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { u32 priority = (skb_peek(&chan->data_q))->priority; while (quote-- && (skb = skb_peek(&chan->data_q))) { BT_DBG("chan %p skb %p len %d priority %u", chan, skb, - skb->len, skb->priority); + skb->len, skb->priority); /* Stop if priority has changed */ if (skb->priority < priority) @@ -2498,7 +2508,7 @@ static void hci_sched_acl_pkt(struct hci_dev *hdev) hci_prio_recalculate(hdev, ACL_LINK); } -static void hci_sched_acl_blk(struct hci_dev *hdev) +static inline void hci_sched_acl_blk(struct hci_dev *hdev) { unsigned int cnt = hdev->block_cnt; struct hci_chan *chan; @@ -2508,13 +2518,13 @@ static void hci_sched_acl_blk(struct hci_dev *hdev) __check_timeout(hdev, cnt); while (hdev->block_cnt > 0 && - (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { + (chan = hci_chan_sent(hdev, ACL_LINK, "e))) { u32 priority = (skb_peek(&chan->data_q))->priority; while (quote > 0 && (skb = skb_peek(&chan->data_q))) { int blocks; BT_DBG("chan %p skb %p len %d priority %u", chan, skb, - skb->len, skb->priority); + skb->len, skb->priority); /* Stop if priority has changed */ if (skb->priority < priority) @@ -2527,7 +2537,7 @@ static void hci_sched_acl_blk(struct hci_dev *hdev) return; hci_conn_enter_active_mode(chan->conn, - bt_cb(skb)->force_active); + bt_cb(skb)->force_active); hci_send_frame(skb); hdev->acl_last_tx = jiffies; @@ -2544,7 +2554,7 @@ static void hci_sched_acl_blk(struct hci_dev *hdev) hci_prio_recalculate(hdev, ACL_LINK); } -static void hci_sched_acl(struct hci_dev *hdev) +static inline void hci_sched_acl(struct hci_dev *hdev) { BT_DBG("%s", hdev->name); @@ -2563,7 +2573,7 @@ static void hci_sched_acl(struct hci_dev *hdev) } /* Schedule SCO */ -static void hci_sched_sco(struct hci_dev *hdev) +static inline void hci_sched_sco(struct hci_dev *hdev) { struct hci_conn *conn; struct sk_buff *skb; @@ -2586,7 +2596,7 @@ static void hci_sched_sco(struct hci_dev *hdev) } } -static void hci_sched_esco(struct hci_dev *hdev) +static inline void hci_sched_esco(struct hci_dev *hdev) { struct hci_conn *conn; struct sk_buff *skb; @@ -2597,8 +2607,7 @@ static void hci_sched_esco(struct hci_dev *hdev) if (!hci_conn_num(hdev, ESCO_LINK)) return; - while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, - "e))) { + while (hdev->sco_cnt && (conn = hci_low_sent(hdev, ESCO_LINK, "e))) { while (quote-- && (skb = skb_dequeue(&conn->data_q))) { BT_DBG("skb %p len %d", skb, skb->len); hci_send_frame(skb); @@ -2610,7 +2619,7 @@ static void hci_sched_esco(struct hci_dev *hdev) } } -static void hci_sched_le(struct hci_dev *hdev) +static inline void hci_sched_le(struct hci_dev *hdev) { struct hci_chan *chan; struct sk_buff *skb; @@ -2625,7 +2634,7 @@ static void hci_sched_le(struct hci_dev *hdev) /* LE tx timeout must be longer than maximum * link supervision timeout (40.9 seconds) */ if (!hdev->le_cnt && hdev->le_pkts && - time_after(jiffies, hdev->le_last_tx + HZ * 45)) + time_after(jiffies, hdev->le_last_tx + HZ * 45)) hci_link_tx_to(hdev, LE_LINK); } @@ -2635,7 +2644,7 @@ static void hci_sched_le(struct hci_dev *hdev) u32 priority = (skb_peek(&chan->data_q))->priority; while (quote-- && (skb = skb_peek(&chan->data_q))) { BT_DBG("chan %p skb %p len %d priority %u", chan, skb, - skb->len, skb->priority); + skb->len, skb->priority); /* Stop if priority has changed */ if (skb->priority < priority) @@ -2667,7 +2676,7 @@ static void hci_tx_work(struct work_struct *work) struct sk_buff *skb; BT_DBG("%s acl %d sco %d le %d", hdev->name, hdev->acl_cnt, - hdev->sco_cnt, hdev->le_cnt); + hdev->sco_cnt, hdev->le_cnt); /* Schedule queues and send stuff to HCI driver */ @@ -2687,7 +2696,7 @@ static void hci_tx_work(struct work_struct *work) /* ----- HCI RX task (incoming data processing) ----- */ /* ACL data packet */ -static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_acl_hdr *hdr = (void *) skb->data; struct hci_conn *conn; @@ -2699,8 +2708,7 @@ static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) flags = hci_flags(handle); handle = hci_handle(handle); - BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, - handle, flags); + BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags); hdev->stat.acl_rx++; @@ -2724,14 +2732,14 @@ static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) return; } else { BT_ERR("%s ACL packet for unknown connection handle %d", - hdev->name, handle); + hdev->name, handle); } kfree_skb(skb); } /* SCO data packet */ -static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_sco_hdr *hdr = (void *) skb->data; struct hci_conn *conn; @@ -2755,7 +2763,7 @@ static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) return; } else { BT_ERR("%s SCO packet for unknown connection handle %d", - hdev->name, handle); + hdev->name, handle); } kfree_skb(skb); diff --git a/trunk/net/bluetooth/hci_event.c b/trunk/net/bluetooth/hci_event.c index 1ba929c05d0d..4eefb7f65cf6 100644 --- a/trunk/net/bluetooth/hci_event.c +++ b/trunk/net/bluetooth/hci_event.c @@ -24,7 +24,20 @@ /* Bluetooth HCI event handling. */ -#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include #include #include @@ -82,8 +95,7 @@ static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb) hci_conn_check_pending(hdev); } -static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb) { BT_DBG("%s", hdev->name); } @@ -154,8 +166,7 @@ static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_unlock(hdev); } -static void hci_cc_read_def_link_policy(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_rp_read_def_link_policy *rp = (void *) skb->data; @@ -167,8 +178,7 @@ static void hci_cc_read_def_link_policy(struct hci_dev *hdev, hdev->link_policy = __le16_to_cpu(rp->policy); } -static void hci_cc_write_def_link_policy(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); void *sent; @@ -319,7 +329,7 @@ static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb) if (hdev->discov_timeout > 0) { int to = msecs_to_jiffies(hdev->discov_timeout * 1000); queue_delayed_work(hdev->workqueue, &hdev->discov_off, - to); + to); } } else if (old_iscan) mgmt_discoverable(hdev, 0); @@ -348,7 +358,7 @@ static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb) memcpy(hdev->dev_class, rp->dev_class, 3); BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name, - hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]); + hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]); } static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb) @@ -396,8 +406,7 @@ static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb) hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); } -static void hci_cc_write_voice_setting(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); __u16 setting; @@ -464,7 +473,7 @@ static u8 hci_get_inquiry_mode(struct hci_dev *hdev) return 1; if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 && - hdev->lmp_subver == 0x0757) + hdev->lmp_subver == 0x0757) return 1; if (hdev->manufacturer == 15) { @@ -477,7 +486,7 @@ static u8 hci_get_inquiry_mode(struct hci_dev *hdev) } if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 && - hdev->lmp_subver == 0x1805) + hdev->lmp_subver == 0x1805) return 1; return 0; @@ -557,7 +566,7 @@ static void hci_setup(struct hci_dev *hdev) if (hdev->hci_ver > BLUETOOTH_VER_1_1) hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL); - if (lmp_ssp_capable(hdev)) { + if (hdev->features[6] & LMP_SIMPLE_PAIR) { if (test_bit(HCI_SSP_ENABLED, &hdev->dev_flags)) { u8 mode = 0x01; hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, @@ -609,7 +618,8 @@ static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver); BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name, - hdev->manufacturer, hdev->hci_ver, hdev->hci_rev); + hdev->manufacturer, + hdev->hci_ver, hdev->hci_rev); if (test_bit(HCI_INIT, &hdev->flags)) hci_setup(hdev); @@ -636,8 +646,7 @@ static void hci_setup_link_policy(struct hci_dev *hdev) hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, sizeof(cp), &cp); } -static void hci_cc_read_local_commands(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_rp_read_local_commands *rp = (void *) skb->data; @@ -655,8 +664,7 @@ static void hci_cc_read_local_commands(struct hci_dev *hdev, hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status); } -static void hci_cc_read_local_features(struct hci_dev *hdev, - struct sk_buff *skb) +static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_rp_read_local_features *rp = (void *) skb->data; @@ -705,10 +713,10 @@ static void hci_cc_read_local_features(struct hci_dev *hdev, hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5); BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name, - hdev->features[0], hdev->features[1], - hdev->features[2], hdev->features[3], - hdev->features[4], hdev->features[5], - hdev->features[6], hdev->features[7]); + hdev->features[0], hdev->features[1], + hdev->features[2], hdev->features[3], + hdev->features[4], hdev->features[5], + hdev->features[6], hdev->features[7]); } static void hci_set_le_support(struct hci_dev *hdev) @@ -728,7 +736,7 @@ static void hci_set_le_support(struct hci_dev *hdev) } static void hci_cc_read_local_ext_features(struct hci_dev *hdev, - struct sk_buff *skb) + struct sk_buff *skb) { struct hci_rp_read_local_ext_features *rp = (void *) skb->data; @@ -754,7 +762,7 @@ static void hci_cc_read_local_ext_features(struct hci_dev *hdev, } static void hci_cc_read_flow_control_mode(struct hci_dev *hdev, - struct sk_buff *skb) + struct sk_buff *skb) { struct hci_rp_read_flow_control_mode *rp = (void *) skb->data; @@ -790,8 +798,9 @@ static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) hdev->acl_cnt = hdev->acl_pkts; hdev->sco_cnt = hdev->sco_pkts; - BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu, - hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts); + BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, + hdev->acl_mtu, hdev->acl_pkts, + hdev->sco_mtu, hdev->sco_pkts); } static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb) @@ -807,7 +816,7 @@ static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb) } static void hci_cc_read_data_block_size(struct hci_dev *hdev, - struct sk_buff *skb) + struct sk_buff *skb) { struct hci_rp_read_data_block_size *rp = (void *) skb->data; @@ -823,7 +832,7 @@ static void hci_cc_read_data_block_size(struct hci_dev *hdev, hdev->block_cnt = hdev->num_blocks; BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu, - hdev->block_cnt, hdev->block_len); + hdev->block_cnt, hdev->block_len); hci_req_complete(hdev, HCI_OP_READ_DATA_BLOCK_SIZE, rp->status); } @@ -838,7 +847,7 @@ static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb) } static void hci_cc_read_local_amp_info(struct hci_dev *hdev, - struct sk_buff *skb) + struct sk_buff *skb) { struct hci_rp_read_local_amp_info *rp = (void *) skb->data; @@ -862,7 +871,7 @@ static void hci_cc_read_local_amp_info(struct hci_dev *hdev, } static void hci_cc_delete_stored_link_key(struct hci_dev *hdev, - struct sk_buff *skb) + struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); @@ -881,7 +890,7 @@ static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb) } static void hci_cc_write_inquiry_mode(struct hci_dev *hdev, - struct sk_buff *skb) + struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); @@ -891,7 +900,7 @@ static void hci_cc_write_inquiry_mode(struct hci_dev *hdev, } static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev, - struct sk_buff *skb) + struct sk_buff *skb) { struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data; @@ -950,7 +959,7 @@ static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) if (test_bit(HCI_MGMT, &hdev->dev_flags)) mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr, - rp->status); + rp->status); hci_dev_unlock(hdev); } @@ -991,7 +1000,7 @@ static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb) } static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, - struct sk_buff *skb) + struct sk_buff *skb) { struct hci_rp_user_confirm_reply *rp = (void *) skb->data; @@ -1022,7 +1031,7 @@ static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb) } static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev, - struct sk_buff *skb) + struct sk_buff *skb) { struct hci_rp_user_confirm_reply *rp = (void *) skb->data; @@ -1038,7 +1047,7 @@ static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev, } static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev, - struct sk_buff *skb) + struct sk_buff *skb) { struct hci_rp_read_local_oob_data *rp = (void *) skb->data; @@ -1067,7 +1076,7 @@ static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb) } static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, - struct sk_buff *skb) + struct sk_buff *skb) { struct hci_cp_le_set_scan_enable *cp; __u8 status = *((__u8 *) skb->data); @@ -1147,8 +1156,8 @@ static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status); } -static void hci_cc_write_le_host_supported(struct hci_dev *hdev, - struct sk_buff *skb) +static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_cp_write_le_host_supported *sent; __u8 status = *((__u8 *) skb->data); @@ -1167,13 +1176,13 @@ static void hci_cc_write_le_host_supported(struct hci_dev *hdev, } if (test_bit(HCI_MGMT, &hdev->dev_flags) && - !test_bit(HCI_INIT, &hdev->flags)) + !test_bit(HCI_INIT, &hdev->flags)) mgmt_le_enable_complete(hdev, sent->le, status); hci_req_complete(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, status); } -static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) +static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) { BT_DBG("%s status 0x%x", hdev->name, status); @@ -1194,7 +1203,7 @@ static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) hci_dev_unlock(hdev); } -static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) +static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) { struct hci_cp_create_conn *cp; struct hci_conn *conn; @@ -1324,7 +1333,7 @@ static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status) } static int hci_outgoing_auth_needed(struct hci_dev *hdev, - struct hci_conn *conn) + struct hci_conn *conn) { if (conn->state != BT_CONFIG || !conn->out) return 0; @@ -1334,14 +1343,15 @@ static int hci_outgoing_auth_needed(struct hci_dev *hdev, /* Only request authentication for SSP connections or non-SSP * devices with sec_level HIGH or if MITM protection is requested */ - if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) && - conn->pending_sec_level != BT_SECURITY_HIGH) + if (!hci_conn_ssp_enabled(conn) && + conn->pending_sec_level != BT_SECURITY_HIGH && + !(conn->auth_type & 0x01)) return 0; return 1; } -static int hci_resolve_name(struct hci_dev *hdev, +static inline int hci_resolve_name(struct hci_dev *hdev, struct inquiry_entry *e) { struct hci_cp_remote_name_req cp; @@ -1628,7 +1638,7 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status) conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr); BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr), - conn); + conn); if (status) { if (conn && conn->state == BT_CONNECT) { @@ -1658,7 +1668,7 @@ static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status) BT_DBG("%s status 0x%x", hdev->name, status); } -static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { __u8 status = *((__u8 *) skb->data); struct discovery_state *discov = &hdev->discovery; @@ -1698,7 +1708,7 @@ static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_unlock(hdev); } -static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct inquiry_data data; struct inquiry_info *info = (void *) (skb->data + 1); @@ -1735,7 +1745,7 @@ static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_unlock(hdev); } -static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_conn_complete *ev = (void *) skb->data; struct hci_conn *conn; @@ -1813,18 +1823,18 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_conn_check_pending(hdev); } -static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline 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; - BT_DBG("%s bdaddr %s type 0x%x", hdev->name, batostr(&ev->bdaddr), - ev->link_type); + BT_DBG("%s bdaddr %s type 0x%x", hdev->name, + batostr(&ev->bdaddr), ev->link_type); mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type); if ((mask & HCI_LM_ACCEPT) && - !hci_blacklist_lookup(hdev, &ev->bdaddr)) { + !hci_blacklist_lookup(hdev, &ev->bdaddr)) { /* Connection accepted */ struct inquiry_entry *ie; struct hci_conn *conn; @@ -1835,8 +1845,7 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) if (ie) memcpy(ie->data.dev_class, ev->dev_class, 3); - conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, - &ev->bdaddr); + conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr); if (!conn) { conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr); if (!conn) { @@ -1869,9 +1878,9 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) bacpy(&cp.bdaddr, &ev->bdaddr); 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.tx_bandwidth = cpu_to_le32(0x00001f40); + cp.rx_bandwidth = cpu_to_le32(0x00001f40); + cp.max_latency = cpu_to_le16(0xffff); cp.content_format = cpu_to_le16(hdev->voice_setting); cp.retrans_effort = 0xff; @@ -1888,7 +1897,7 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) } } -static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_disconn_complete *ev = (void *) skb->data; struct hci_conn *conn; @@ -1905,10 +1914,10 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) conn->state = BT_CLOSED; if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) && - (conn->type == ACL_LINK || conn->type == LE_LINK)) { + (conn->type == ACL_LINK || conn->type == LE_LINK)) { if (ev->status != 0) mgmt_disconnect_failed(hdev, &conn->dst, conn->type, - conn->dst_type, ev->status); + conn->dst_type, ev->status); else mgmt_device_disconnected(hdev, &conn->dst, conn->type, conn->dst_type); @@ -1925,7 +1934,7 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_unlock(hdev); } -static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_auth_complete *ev = (void *) skb->data; struct hci_conn *conn; @@ -1940,7 +1949,7 @@ static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) if (!ev->status) { if (!hci_conn_ssp_enabled(conn) && - test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) { + test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) { BT_INFO("re-auth of legacy device is not possible."); } else { conn->link_mode |= HCI_LM_AUTH; @@ -1960,7 +1969,7 @@ static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) cp.handle = ev->handle; cp.encrypt = 0x01; hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), - &cp); + &cp); } else { conn->state = BT_CONNECTED; hci_proto_connect_cfm(conn, ev->status); @@ -1980,7 +1989,7 @@ static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) cp.handle = ev->handle; cp.encrypt = 0x01; hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), - &cp); + &cp); } else { clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); hci_encrypt_cfm(conn, ev->status, 0x00); @@ -1991,7 +2000,7 @@ static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_unlock(hdev); } -static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_remote_name *ev = (void *) skb->data; struct hci_conn *conn; @@ -2030,7 +2039,7 @@ static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_unlock(hdev); } -static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_encrypt_change *ev = (void *) skb->data; struct hci_conn *conn; @@ -2073,8 +2082,7 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_unlock(hdev); } -static void hci_change_link_key_complete_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_change_link_key_complete *ev = (void *) skb->data; struct hci_conn *conn; @@ -2096,8 +2104,7 @@ static void hci_change_link_key_complete_evt(struct hci_dev *hdev, hci_dev_unlock(hdev); } -static void hci_remote_features_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_remote_features *ev = (void *) skb->data; struct hci_conn *conn; @@ -2121,7 +2128,7 @@ static void hci_remote_features_evt(struct hci_dev *hdev, cp.handle = ev->handle; cp.page = 0x01; hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES, - sizeof(cp), &cp); + sizeof(cp), &cp); goto unlock; } @@ -2146,18 +2153,17 @@ static void hci_remote_features_evt(struct hci_dev *hdev, hci_dev_unlock(hdev); } -static void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb) { BT_DBG("%s", hdev->name); } -static void hci_qos_setup_complete_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { BT_DBG("%s", hdev->name); } -static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_cmd_complete *ev = (void *) skb->data; __u16 opcode; @@ -2378,7 +2384,7 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) } } -static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_cmd_status *ev = (void *) skb->data; __u16 opcode; @@ -2459,7 +2465,7 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) } } -static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_role_change *ev = (void *) skb->data; struct hci_conn *conn; @@ -2485,7 +2491,7 @@ static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_unlock(hdev); } -static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_num_comp_pkts *ev = (void *) skb->data; int i; @@ -2496,7 +2502,7 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb) } if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) + - ev->num_hndl * sizeof(struct hci_comp_pkts_info)) { + ev->num_hndl * sizeof(struct hci_comp_pkts_info)) { BT_DBG("%s bad parameters", hdev->name); return; } @@ -2551,7 +2557,8 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb) queue_work(hdev->workqueue, &hdev->tx_work); } -static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_num_comp_blocks *ev = (void *) skb->data; int i; @@ -2562,13 +2569,13 @@ static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb) } if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) + - ev->num_hndl * sizeof(struct hci_comp_blocks_info)) { + ev->num_hndl * sizeof(struct hci_comp_blocks_info)) { BT_DBG("%s bad parameters", hdev->name); return; } BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks, - ev->num_hndl); + ev->num_hndl); for (i = 0; i < ev->num_hndl; i++) { struct hci_comp_blocks_info *info = &ev->handles[i]; @@ -2600,7 +2607,7 @@ static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb) queue_work(hdev->workqueue, &hdev->tx_work); } -static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_mode_change *ev = (void *) skb->data; struct hci_conn *conn; @@ -2614,8 +2621,7 @@ static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb) conn->mode = ev->mode; conn->interval = __le16_to_cpu(ev->interval); - if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, - &conn->flags)) { + if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags)) { if (conn->mode == HCI_CM_ACTIVE) set_bit(HCI_CONN_POWER_SAVE, &conn->flags); else @@ -2629,7 +2635,7 @@ static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_unlock(hdev); } -static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_pin_code_req *ev = (void *) skb->data; struct hci_conn *conn; @@ -2650,7 +2656,7 @@ static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb) if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags)) hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, - sizeof(ev->bdaddr), &ev->bdaddr); + sizeof(ev->bdaddr), &ev->bdaddr); else if (test_bit(HCI_MGMT, &hdev->dev_flags)) { u8 secure; @@ -2666,7 +2672,7 @@ static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_unlock(hdev); } -static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_link_key_req *ev = (void *) skb->data; struct hci_cp_link_key_reply cp; @@ -2683,15 +2689,15 @@ static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) key = hci_find_link_key(hdev, &ev->bdaddr); if (!key) { BT_DBG("%s link key not found for %s", hdev->name, - batostr(&ev->bdaddr)); + batostr(&ev->bdaddr)); goto not_found; } BT_DBG("%s found key type %u for %s", hdev->name, key->type, - batostr(&ev->bdaddr)); + batostr(&ev->bdaddr)); if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) && - key->type == HCI_LK_DEBUG_COMBINATION) { + key->type == HCI_LK_DEBUG_COMBINATION) { BT_DBG("%s ignoring debug key", hdev->name); goto not_found; } @@ -2699,15 +2705,16 @@ static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); if (conn) { if (key->type == HCI_LK_UNAUTH_COMBINATION && - conn->auth_type != 0xff && (conn->auth_type & 0x01)) { + conn->auth_type != 0xff && + (conn->auth_type & 0x01)) { BT_DBG("%s ignoring unauthenticated key", hdev->name); goto not_found; } if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 && - conn->pending_sec_level == BT_SECURITY_HIGH) { - BT_DBG("%s ignoring key unauthenticated for high security", - hdev->name); + conn->pending_sec_level == BT_SECURITY_HIGH) { + BT_DBG("%s ignoring key unauthenticated for high \ + security", hdev->name); goto not_found; } @@ -2716,7 +2723,7 @@ static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) } bacpy(&cp.bdaddr, &ev->bdaddr); - memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE); + memcpy(cp.link_key, key->val, 16); hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp); @@ -2729,7 +2736,7 @@ static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_unlock(hdev); } -static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_link_key_notify *ev = (void *) skb->data; struct hci_conn *conn; @@ -2753,12 +2760,12 @@ static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags)) hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key, - ev->key_type, pin_len); + ev->key_type, pin_len); hci_dev_unlock(hdev); } -static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_clock_offset *ev = (void *) skb->data; struct hci_conn *conn; @@ -2781,7 +2788,7 @@ static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_unlock(hdev); } -static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_pkt_type_change *ev = (void *) skb->data; struct hci_conn *conn; @@ -2797,7 +2804,7 @@ static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_unlock(hdev); } -static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_pscan_rep_mode *ev = (void *) skb->data; struct inquiry_entry *ie; @@ -2815,8 +2822,7 @@ static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_unlock(hdev); } -static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct inquiry_data data; int num_rsp = *((__u8 *) skb->data); @@ -2875,8 +2881,7 @@ static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, hci_dev_unlock(hdev); } -static void hci_remote_ext_features_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_remote_ext_features *ev = (void *) skb->data; struct hci_conn *conn; @@ -2924,8 +2929,7 @@ static void hci_remote_ext_features_evt(struct hci_dev *hdev, hci_dev_unlock(hdev); } -static void hci_sync_conn_complete_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_sync_conn_complete *ev = (void *) skb->data; struct hci_conn *conn; @@ -2980,20 +2984,19 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, hci_dev_unlock(hdev); } -static void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb) { BT_DBG("%s", hdev->name); } -static void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_sniff_subrate *ev = (void *) skb->data; BT_DBG("%s status %d", hdev->name, ev->status); } -static void hci_extended_inquiry_result_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct inquiry_data data; struct extended_inquiry_info *info = (void *) (skb->data + 1); @@ -3040,51 +3043,7 @@ static void hci_extended_inquiry_result_evt(struct hci_dev *hdev, hci_dev_unlock(hdev); } -static void hci_key_refresh_complete_evt(struct hci_dev *hdev, - struct sk_buff *skb) -{ - struct hci_ev_key_refresh_complete *ev = (void *) skb->data; - struct hci_conn *conn; - - BT_DBG("%s status %u handle %u", hdev->name, ev->status, - __le16_to_cpu(ev->handle)); - - hci_dev_lock(hdev); - - conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); - if (!conn) - goto unlock; - - if (!ev->status) - conn->sec_level = conn->pending_sec_level; - - clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); - - if (ev->status && conn->state == BT_CONNECTED) { - hci_acl_disconn(conn, HCI_ERROR_AUTH_FAILURE); - hci_conn_put(conn); - goto unlock; - } - - if (conn->state == BT_CONFIG) { - if (!ev->status) - conn->state = BT_CONNECTED; - - hci_proto_connect_cfm(conn, ev->status); - hci_conn_put(conn); - } else { - hci_auth_cfm(conn, ev->status); - - hci_conn_hold(conn); - conn->disc_timeout = HCI_DISCONN_TIMEOUT; - hci_conn_put(conn); - } - -unlock: - hci_dev_unlock(hdev); -} - -static u8 hci_get_auth_req(struct hci_conn *conn) +static inline u8 hci_get_auth_req(struct hci_conn *conn) { /* If remote requests dedicated bonding follow that lead */ if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) { @@ -3103,7 +3062,7 @@ static u8 hci_get_auth_req(struct hci_conn *conn) return conn->auth_type; } -static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_io_capa_request *ev = (void *) skb->data; struct hci_conn *conn; @@ -3122,7 +3081,7 @@ static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb) goto unlock; if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) || - (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) { + (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) { struct hci_cp_io_capability_reply cp; bacpy(&cp.bdaddr, &ev->bdaddr); @@ -3133,14 +3092,14 @@ static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb) conn->auth_type = hci_get_auth_req(conn); cp.authentication = conn->auth_type; - if (hci_find_remote_oob_data(hdev, &conn->dst) && - (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags))) + if ((conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)) && + hci_find_remote_oob_data(hdev, &conn->dst)) cp.oob_data = 0x01; else cp.oob_data = 0x00; hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY, - sizeof(cp), &cp); + sizeof(cp), &cp); } else { struct hci_cp_io_capability_neg_reply cp; @@ -3148,14 +3107,14 @@ static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb) cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED; hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY, - sizeof(cp), &cp); + sizeof(cp), &cp); } unlock: hci_dev_unlock(hdev); } -static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_io_capa_reply *ev = (void *) skb->data; struct hci_conn *conn; @@ -3177,8 +3136,8 @@ static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_unlock(hdev); } -static void hci_user_confirm_request_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static inline void hci_user_confirm_request_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_user_confirm_req *ev = (void *) skb->data; int loc_mitm, rem_mitm, confirm_hint = 0; @@ -3206,13 +3165,13 @@ static void hci_user_confirm_request_evt(struct hci_dev *hdev, if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) { BT_DBG("Rejecting request: remote device can't provide MITM"); hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY, - sizeof(ev->bdaddr), &ev->bdaddr); + sizeof(ev->bdaddr), &ev->bdaddr); goto unlock; } /* If no side requires MITM protection; auto-accept */ if ((!loc_mitm || conn->remote_cap == 0x03) && - (!rem_mitm || conn->io_capability == 0x03)) { + (!rem_mitm || conn->io_capability == 0x03)) { /* If we're not the initiators request authorization to * proceed from user space (mgmt_user_confirm with @@ -3224,7 +3183,7 @@ static void hci_user_confirm_request_evt(struct hci_dev *hdev, } BT_DBG("Auto-accept of user confirmation with %ums delay", - hdev->auto_accept_delay); + hdev->auto_accept_delay); if (hdev->auto_accept_delay > 0) { int delay = msecs_to_jiffies(hdev->auto_accept_delay); @@ -3233,7 +3192,7 @@ static void hci_user_confirm_request_evt(struct hci_dev *hdev, } hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, - sizeof(ev->bdaddr), &ev->bdaddr); + sizeof(ev->bdaddr), &ev->bdaddr); goto unlock; } @@ -3245,8 +3204,8 @@ static void hci_user_confirm_request_evt(struct hci_dev *hdev, hci_dev_unlock(hdev); } -static void hci_user_passkey_request_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static inline void hci_user_passkey_request_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_user_passkey_req *ev = (void *) skb->data; @@ -3260,8 +3219,7 @@ static void hci_user_passkey_request_evt(struct hci_dev *hdev, hci_dev_unlock(hdev); } -static void hci_simple_pair_complete_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_simple_pair_complete *ev = (void *) skb->data; struct hci_conn *conn; @@ -3289,8 +3247,7 @@ static void hci_simple_pair_complete_evt(struct hci_dev *hdev, hci_dev_unlock(hdev); } -static void hci_remote_host_features_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_remote_host_features *ev = (void *) skb->data; struct inquiry_entry *ie; @@ -3306,8 +3263,8 @@ static void hci_remote_host_features_evt(struct hci_dev *hdev, hci_dev_unlock(hdev); } -static void hci_remote_oob_data_request_evt(struct hci_dev *hdev, - struct sk_buff *skb) +static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_remote_oob_data_request *ev = (void *) skb->data; struct oob_data *data; @@ -3328,20 +3285,20 @@ static void hci_remote_oob_data_request_evt(struct hci_dev *hdev, memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer)); hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp), - &cp); + &cp); } else { struct hci_cp_remote_oob_data_neg_reply cp; bacpy(&cp.bdaddr, &ev->bdaddr); hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp), - &cp); + &cp); } unlock: hci_dev_unlock(hdev); } -static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_le_conn_complete *ev = (void *) skb->data; struct hci_conn *conn; @@ -3350,19 +3307,6 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_lock(hdev); - if (ev->status) { - conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT); - if (!conn) - goto unlock; - - mgmt_connect_failed(hdev, &conn->dst, conn->type, - conn->dst_type, ev->status); - hci_proto_connect_cfm(conn, ev->status); - conn->state = BT_CLOSED; - hci_conn_del(conn); - goto unlock; - } - conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr); if (!conn) { conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr); @@ -3375,6 +3319,15 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) conn->dst_type = ev->bdaddr_type; } + if (ev->status) { + mgmt_connect_failed(hdev, &ev->bdaddr, conn->type, + conn->dst_type, ev->status); + hci_proto_connect_cfm(conn, ev->status); + conn->state = BT_CLOSED; + hci_conn_del(conn); + goto unlock; + } + if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) mgmt_device_connected(hdev, &ev->bdaddr, conn->type, conn->dst_type, 0, NULL, 0, NULL); @@ -3392,7 +3345,8 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_unlock(hdev); } -static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_le_adv_report_evt(struct hci_dev *hdev, + struct sk_buff *skb) { u8 num_reports = skb->data[0]; void *ptr = &skb->data[1]; @@ -3413,7 +3367,8 @@ static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_unlock(hdev); } -static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_le_ltk_request_evt(struct hci_dev *hdev, + struct sk_buff *skb) { struct hci_ev_le_ltk_req *ev = (void *) skb->data; struct hci_cp_le_ltk_reply cp; @@ -3456,7 +3411,7 @@ static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb) hci_dev_unlock(hdev); } -static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb) +static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb) { struct hci_ev_le_meta *le_ev = (void *) skb->data; @@ -3604,10 +3559,6 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) hci_extended_inquiry_result_evt(hdev, skb); break; - case HCI_EV_KEY_REFRESH_COMPLETE: - hci_key_refresh_complete_evt(hdev, skb); - break; - case HCI_EV_IO_CAPA_REQUEST: hci_io_capa_request_evt(hdev, skb); break; diff --git a/trunk/net/bluetooth/hci_sock.c b/trunk/net/bluetooth/hci_sock.c index a7f04de03d79..5914623f426a 100644 --- a/trunk/net/bluetooth/hci_sock.c +++ b/trunk/net/bluetooth/hci_sock.c @@ -24,7 +24,25 @@ /* Bluetooth HCI sockets. */ -#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include #include #include @@ -95,12 +113,11 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb) flt = &hci_pi(sk)->filter; if (!test_bit((bt_cb(skb)->pkt_type == HCI_VENDOR_PKT) ? - 0 : (bt_cb(skb)->pkt_type & HCI_FLT_TYPE_BITS), - &flt->type_mask)) + 0 : (bt_cb(skb)->pkt_type & HCI_FLT_TYPE_BITS), &flt->type_mask)) continue; if (bt_cb(skb)->pkt_type == HCI_EVENT_PKT) { - int evt = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS); + register int evt = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS); if (!hci_test_bit(evt, &flt->event_mask)) continue; @@ -223,8 +240,7 @@ void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb) struct hci_mon_hdr *hdr; /* Create a private copy with headroom */ - skb_copy = __pskb_copy(skb, HCI_MON_HDR_SIZE, - GFP_ATOMIC); + skb_copy = __pskb_copy(skb, HCI_MON_HDR_SIZE, GFP_ATOMIC); if (!skb_copy) continue; @@ -479,8 +495,7 @@ static int hci_sock_blacklist_del(struct hci_dev *hdev, void __user *arg) } /* Ioctls that require bound socket */ -static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, - unsigned long arg) +static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg) { struct hci_dev *hdev = hci_pi(sk)->hdev; @@ -525,8 +540,7 @@ static int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, } } -static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, - unsigned long arg) +static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) { struct sock *sk = sock->sk; void __user *argp = (void __user *) arg; @@ -587,8 +601,7 @@ static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, } } -static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, - int addr_len) +static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len) { struct sockaddr_hci haddr; struct sock *sk = sock->sk; @@ -677,8 +690,7 @@ static int hci_sock_bind(struct socket *sock, struct sockaddr *addr, return err; } -static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, - int *addr_len, int peer) +static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, int *addr_len, int peer) { struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr; struct sock *sk = sock->sk; @@ -699,15 +711,13 @@ static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, return 0; } -static void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, - struct sk_buff *skb) +static inline void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb) { __u32 mask = hci_pi(sk)->cmsg_mask; if (mask & HCI_CMSG_DIR) { int incoming = bt_cb(skb)->incoming; - put_cmsg(msg, SOL_HCI, HCI_CMSG_DIR, sizeof(incoming), - &incoming); + put_cmsg(msg, SOL_HCI, HCI_CMSG_DIR, sizeof(incoming), &incoming); } if (mask & HCI_CMSG_TSTAMP) { @@ -737,7 +747,7 @@ static void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, } static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock, - struct msghdr *msg, size_t len, int flags) + struct msghdr *msg, size_t len, int flags) { int noblock = flags & MSG_DONTWAIT; struct sock *sk = sock->sk; @@ -847,9 +857,8 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock, u16 ocf = hci_opcode_ocf(opcode); if (((ogf > HCI_SFLT_MAX_OGF) || - !hci_test_bit(ocf & HCI_FLT_OCF_BITS, - &hci_sec_filter.ocf_mask[ogf])) && - !capable(CAP_NET_RAW)) { + !hci_test_bit(ocf & HCI_FLT_OCF_BITS, &hci_sec_filter.ocf_mask[ogf])) && + !capable(CAP_NET_RAW)) { err = -EPERM; goto drop; } @@ -882,8 +891,7 @@ static int hci_sock_sendmsg(struct kiocb *iocb, struct socket *sock, goto done; } -static int hci_sock_setsockopt(struct socket *sock, int level, int optname, - char __user *optval, unsigned int len) +static int hci_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int len) { struct hci_ufilter uf = { .opcode = 0 }; struct sock *sk = sock->sk; @@ -965,8 +973,7 @@ static int hci_sock_setsockopt(struct socket *sock, int level, int optname, return err; } -static int hci_sock_getsockopt(struct socket *sock, int level, int optname, - char __user *optval, int __user *optlen) +static int hci_sock_getsockopt(struct socket *sock, int level, int optname, char __user *optval, int __user *optlen) { struct hci_ufilter uf; struct sock *sk = sock->sk; diff --git a/trunk/net/bluetooth/hci_sysfs.c b/trunk/net/bluetooth/hci_sysfs.c index a20e61c3653d..937f3187eafa 100644 --- a/trunk/net/bluetooth/hci_sysfs.c +++ b/trunk/net/bluetooth/hci_sysfs.c @@ -1,6 +1,10 @@ /* Bluetooth HCI driver model support. */ +#include +#include +#include #include +#include #include #include @@ -27,30 +31,27 @@ static inline char *link_typetostr(int type) } } -static ssize_t show_link_type(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t show_link_type(struct device *dev, struct device_attribute *attr, char *buf) { struct hci_conn *conn = to_hci_conn(dev); return sprintf(buf, "%s\n", link_typetostr(conn->type)); } -static ssize_t show_link_address(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t show_link_address(struct device *dev, struct device_attribute *attr, char *buf) { struct hci_conn *conn = to_hci_conn(dev); return sprintf(buf, "%s\n", batostr(&conn->dst)); } -static ssize_t show_link_features(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t show_link_features(struct device *dev, struct device_attribute *attr, char *buf) { struct hci_conn *conn = to_hci_conn(dev); return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", - conn->features[0], conn->features[1], - conn->features[2], conn->features[3], - conn->features[4], conn->features[5], - conn->features[6], conn->features[7]); + conn->features[0], conn->features[1], + conn->features[2], conn->features[3], + conn->features[4], conn->features[5], + conn->features[6], conn->features[7]); } #define LINK_ATTR(_name, _mode, _show, _store) \ @@ -184,22 +185,19 @@ static inline char *host_typetostr(int type) } } -static ssize_t show_bus(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t show_bus(struct device *dev, struct device_attribute *attr, char *buf) { struct hci_dev *hdev = to_hci_dev(dev); return sprintf(buf, "%s\n", host_bustostr(hdev->bus)); } -static ssize_t show_type(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t show_type(struct device *dev, struct device_attribute *attr, char *buf) { struct hci_dev *hdev = to_hci_dev(dev); return sprintf(buf, "%s\n", host_typetostr(hdev->dev_type)); } -static ssize_t show_name(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf) { struct hci_dev *hdev = to_hci_dev(dev); char name[HCI_MAX_NAME_LENGTH + 1]; @@ -212,64 +210,55 @@ static ssize_t show_name(struct device *dev, return sprintf(buf, "%s\n", name); } -static ssize_t show_class(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t show_class(struct device *dev, struct device_attribute *attr, char *buf) { struct hci_dev *hdev = to_hci_dev(dev); - return sprintf(buf, "0x%.2x%.2x%.2x\n", hdev->dev_class[2], - hdev->dev_class[1], hdev->dev_class[0]); + return sprintf(buf, "0x%.2x%.2x%.2x\n", + hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]); } -static ssize_t show_address(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t show_address(struct device *dev, struct device_attribute *attr, char *buf) { struct hci_dev *hdev = to_hci_dev(dev); return sprintf(buf, "%s\n", batostr(&hdev->bdaddr)); } -static ssize_t show_features(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t show_features(struct device *dev, struct device_attribute *attr, char *buf) { struct hci_dev *hdev = to_hci_dev(dev); return sprintf(buf, "0x%02x%02x%02x%02x%02x%02x%02x%02x\n", - hdev->features[0], hdev->features[1], - hdev->features[2], hdev->features[3], - hdev->features[4], hdev->features[5], - hdev->features[6], hdev->features[7]); + hdev->features[0], hdev->features[1], + hdev->features[2], hdev->features[3], + hdev->features[4], hdev->features[5], + hdev->features[6], hdev->features[7]); } -static ssize_t show_manufacturer(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t show_manufacturer(struct device *dev, struct device_attribute *attr, char *buf) { struct hci_dev *hdev = to_hci_dev(dev); return sprintf(buf, "%d\n", hdev->manufacturer); } -static ssize_t show_hci_version(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t show_hci_version(struct device *dev, struct device_attribute *attr, char *buf) { struct hci_dev *hdev = to_hci_dev(dev); return sprintf(buf, "%d\n", hdev->hci_ver); } -static ssize_t show_hci_revision(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t show_hci_revision(struct device *dev, struct device_attribute *attr, char *buf) { struct hci_dev *hdev = to_hci_dev(dev); return sprintf(buf, "%d\n", hdev->hci_rev); } -static ssize_t show_idle_timeout(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t show_idle_timeout(struct device *dev, struct device_attribute *attr, char *buf) { struct hci_dev *hdev = to_hci_dev(dev); return sprintf(buf, "%d\n", hdev->idle_timeout); } -static ssize_t store_idle_timeout(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t store_idle_timeout(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct hci_dev *hdev = to_hci_dev(dev); unsigned int val; @@ -287,16 +276,13 @@ static ssize_t store_idle_timeout(struct device *dev, return count; } -static ssize_t show_sniff_max_interval(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t show_sniff_max_interval(struct device *dev, struct device_attribute *attr, char *buf) { struct hci_dev *hdev = to_hci_dev(dev); return sprintf(buf, "%d\n", hdev->sniff_max_interval); } -static ssize_t store_sniff_max_interval(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t store_sniff_max_interval(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct hci_dev *hdev = to_hci_dev(dev); u16 val; @@ -314,16 +300,13 @@ static ssize_t store_sniff_max_interval(struct device *dev, return count; } -static ssize_t show_sniff_min_interval(struct device *dev, - struct device_attribute *attr, char *buf) +static ssize_t show_sniff_min_interval(struct device *dev, struct device_attribute *attr, char *buf) { struct hci_dev *hdev = to_hci_dev(dev); return sprintf(buf, "%d\n", hdev->sniff_min_interval); } -static ssize_t store_sniff_min_interval(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t store_sniff_min_interval(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct hci_dev *hdev = to_hci_dev(dev); u16 val; @@ -352,11 +335,11 @@ static DEVICE_ATTR(hci_version, S_IRUGO, show_hci_version, NULL); static DEVICE_ATTR(hci_revision, S_IRUGO, show_hci_revision, NULL); static DEVICE_ATTR(idle_timeout, S_IRUGO | S_IWUSR, - show_idle_timeout, store_idle_timeout); + show_idle_timeout, store_idle_timeout); static DEVICE_ATTR(sniff_max_interval, S_IRUGO | S_IWUSR, - show_sniff_max_interval, store_sniff_max_interval); + show_sniff_max_interval, store_sniff_max_interval); static DEVICE_ATTR(sniff_min_interval, S_IRUGO | S_IWUSR, - show_sniff_min_interval, store_sniff_min_interval); + show_sniff_min_interval, store_sniff_min_interval); static struct attribute *bt_host_attrs[] = { &dev_attr_bus.attr, @@ -472,8 +455,8 @@ static void print_bt_uuid(struct seq_file *f, u8 *uuid) memcpy(&data5, &uuid[14], 2); seq_printf(f, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x\n", - ntohl(data0), ntohs(data1), ntohs(data2), ntohs(data3), - ntohl(data4), ntohs(data5)); + ntohl(data0), ntohs(data1), ntohs(data2), + ntohs(data3), ntohl(data4), ntohs(data5)); } static int uuids_show(struct seq_file *f, void *p) @@ -530,7 +513,7 @@ static int auto_accept_delay_get(void *data, u64 *val) } DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get, - auto_accept_delay_set, "%llu\n"); + auto_accept_delay_set, "%llu\n"); void hci_init_sysfs(struct hci_dev *hdev) { @@ -564,15 +547,15 @@ int hci_add_sysfs(struct hci_dev *hdev) return 0; debugfs_create_file("inquiry_cache", 0444, hdev->debugfs, - hdev, &inquiry_cache_fops); + hdev, &inquiry_cache_fops); debugfs_create_file("blacklist", 0444, hdev->debugfs, - hdev, &blacklist_fops); + hdev, &blacklist_fops); debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops); debugfs_create_file("auto_accept_delay", 0444, hdev->debugfs, hdev, - &auto_accept_delay_fops); + &auto_accept_delay_fops); return 0; } diff --git a/trunk/net/bluetooth/hidp/core.c b/trunk/net/bluetooth/hidp/core.c index ccd985da6518..2c20d765b394 100644 --- a/trunk/net/bluetooth/hidp/core.c +++ b/trunk/net/bluetooth/hidp/core.c @@ -21,8 +21,27 @@ */ #include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include #include +#include + +#include +#include #include #include @@ -225,8 +244,7 @@ static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb) } static int __hidp_send_ctrl_message(struct hidp_session *session, - unsigned char hdr, unsigned char *data, - int size) + unsigned char hdr, unsigned char *data, int size) { struct sk_buff *skb; @@ -250,7 +268,7 @@ static int __hidp_send_ctrl_message(struct hidp_session *session, return 0; } -static int hidp_send_ctrl_message(struct hidp_session *session, +static inline int hidp_send_ctrl_message(struct hidp_session *session, unsigned char hdr, unsigned char *data, int size) { int err; @@ -453,7 +471,7 @@ static void hidp_set_timer(struct hidp_session *session) mod_timer(&session->timer, jiffies + HZ * session->idle_to); } -static void hidp_del_timer(struct hidp_session *session) +static inline void hidp_del_timer(struct hidp_session *session) { if (session->idle_to > 0) del_timer(&session->timer); diff --git a/trunk/net/bluetooth/hidp/sock.c b/trunk/net/bluetooth/hidp/sock.c index 18b3f6892a36..73a32d705c1f 100644 --- a/trunk/net/bluetooth/hidp/sock.c +++ b/trunk/net/bluetooth/hidp/sock.c @@ -20,8 +20,22 @@ SOFTWARE IS DISCLAIMED. */ -#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include #include "hidp.h" diff --git a/trunk/net/bluetooth/l2cap_core.c b/trunk/net/bluetooth/l2cap_core.c index d42dfdc83ebb..24f144b72a96 100644 --- a/trunk/net/bluetooth/l2cap_core.c +++ b/trunk/net/bluetooth/l2cap_core.c @@ -30,14 +30,32 @@ #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include #include +#include + +#include #include #include #include #include -#include bool disable_ertm; @@ -55,9 +73,6 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data); 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); - /* ---- L2CAP channels ---- */ static struct l2cap_chan *__l2cap_get_chan_by_dcid(struct l2cap_conn *conn, u16 cid) @@ -181,7 +196,7 @@ static void __l2cap_state_change(struct l2cap_chan *chan, int state) state_to_string(state)); chan->state = state; - chan->ops->state_change(chan, state); + chan->ops->state_change(chan->data, state); } static void l2cap_state_change(struct l2cap_chan *chan, int state) @@ -209,37 +224,6 @@ static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err) release_sock(sk); } -static void __set_retrans_timer(struct l2cap_chan *chan) -{ - if (!delayed_work_pending(&chan->monitor_timer) && - chan->retrans_timeout) { - l2cap_set_timer(chan, &chan->retrans_timer, - msecs_to_jiffies(chan->retrans_timeout)); - } -} - -static void __set_monitor_timer(struct l2cap_chan *chan) -{ - __clear_retrans_timer(chan); - if (chan->monitor_timeout) { - l2cap_set_timer(chan, &chan->monitor_timer, - msecs_to_jiffies(chan->monitor_timeout)); - } -} - -static struct sk_buff *l2cap_ertm_seq_in_queue(struct sk_buff_head *head, - u16 seq) -{ - struct sk_buff *skb; - - skb_queue_walk(head, skb) { - if (bt_cb(skb)->control.txseq == seq) - return skb; - } - - return NULL; -} - /* ---- L2CAP sequence number lists ---- */ /* For ERTM, ordered lists of sequence numbers must be tracked for @@ -382,7 +366,7 @@ static void l2cap_chan_timeout(struct work_struct *work) l2cap_chan_unlock(chan); - chan->ops->close(chan); + chan->ops->close(chan->data); mutex_unlock(&conn->chan_lock); l2cap_chan_put(chan); @@ -408,9 +392,6 @@ struct l2cap_chan *l2cap_chan_create(void) atomic_set(&chan->refcnt, 1); - /* This flag is cleared in l2cap_chan_ready() */ - set_bit(CONF_NOT_COMPLETE, &chan->conf_state); - BT_DBG("chan %p", chan); return chan; @@ -449,7 +430,7 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) case L2CAP_CHAN_CONN_ORIENTED: if (conn->hcon->type == LE_LINK) { /* LE connection */ - chan->omtu = L2CAP_DEFAULT_MTU; + chan->omtu = L2CAP_LE_DEFAULT_MTU; chan->scid = L2CAP_CID_LE_DATA; chan->dcid = L2CAP_CID_LE_DATA; } else { @@ -466,13 +447,6 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) chan->omtu = L2CAP_DEFAULT_MTU; break; - case L2CAP_CHAN_CONN_FIX_A2MP: - chan->scid = L2CAP_CID_A2MP; - chan->dcid = L2CAP_CID_A2MP; - chan->omtu = L2CAP_A2MP_DEFAULT_MTU; - chan->imtu = L2CAP_A2MP_DEFAULT_MTU; - break; - default: /* Raw socket can send/recv signalling messages only */ chan->scid = L2CAP_CID_SIGNALING; @@ -492,16 +466,18 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) list_add(&chan->list, &conn->chan_l); } -void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) +static void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) { mutex_lock(&conn->chan_lock); __l2cap_chan_add(conn, chan); mutex_unlock(&conn->chan_lock); } -void l2cap_chan_del(struct l2cap_chan *chan, int err) +static void l2cap_chan_del(struct l2cap_chan *chan, int err) { + struct sock *sk = chan->sk; struct l2cap_conn *conn = chan->conn; + struct sock *parent = bt_sk(sk)->parent; __clear_chan_timer(chan); @@ -514,22 +490,34 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) l2cap_chan_put(chan); chan->conn = NULL; - - if (chan->chan_type != L2CAP_CHAN_CONN_FIX_A2MP) - hci_conn_put(conn->hcon); + hci_conn_put(conn->hcon); } - if (chan->ops->teardown) - chan->ops->teardown(chan, err); + lock_sock(sk); + + __l2cap_state_change(chan, BT_CLOSED); + sock_set_flag(sk, SOCK_ZAPPED); + + if (err) + __l2cap_chan_set_err(chan, err); + + if (parent) { + bt_accept_unlink(sk); + parent->sk_data_ready(parent, 0); + } else + sk->sk_state_change(sk); + + release_sock(sk); - if (test_bit(CONF_NOT_COMPLETE, &chan->conf_state)) + if (!(test_bit(CONF_OUTPUT_DONE, &chan->conf_state) && + test_bit(CONF_INPUT_DONE, &chan->conf_state))) return; - switch(chan->mode) { - case L2CAP_MODE_BASIC: - break; + skb_queue_purge(&chan->tx_q); + + if (chan->mode == L2CAP_MODE_ERTM) { + struct srej_list *l, *tmp; - case L2CAP_MODE_ERTM: __clear_retrans_timer(chan); __clear_monitor_timer(chan); __clear_ack_timer(chan); @@ -538,15 +526,30 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) l2cap_seq_list_free(&chan->srej_list); l2cap_seq_list_free(&chan->retrans_list); + list_for_each_entry_safe(l, tmp, &chan->srej_l, list) { + list_del(&l->list); + kfree(l); + } + } +} - /* fall through */ +static void l2cap_chan_cleanup_listen(struct sock *parent) +{ + struct sock *sk; - case L2CAP_MODE_STREAMING: - skb_queue_purge(&chan->tx_q); - break; - } + BT_DBG("parent %p", parent); + + /* Close not yet accepted channels */ + while ((sk = bt_accept_dequeue(parent, NULL))) { + struct l2cap_chan *chan = l2cap_pi(sk)->chan; - return; + l2cap_chan_lock(chan); + __clear_chan_timer(chan); + l2cap_chan_close(chan, ECONNRESET); + l2cap_chan_unlock(chan); + + chan->ops->close(chan->data); + } } void l2cap_chan_close(struct l2cap_chan *chan, int reason) @@ -559,8 +562,12 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason) switch (chan->state) { case BT_LISTEN: - if (chan->ops->teardown) - chan->ops->teardown(chan, 0); + lock_sock(sk); + l2cap_chan_cleanup_listen(sk); + + __l2cap_state_change(chan, BT_CLOSED); + sock_set_flag(sk, SOCK_ZAPPED); + release_sock(sk); break; case BT_CONNECTED: @@ -588,7 +595,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason) rsp.scid = cpu_to_le16(chan->dcid); rsp.dcid = cpu_to_le16(chan->scid); rsp.result = cpu_to_le16(result); - rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO); + rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp); } @@ -602,8 +609,9 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason) break; default: - if (chan->ops->teardown) - chan->ops->teardown(chan, 0); + lock_sock(sk); + sock_set_flag(sk, SOCK_ZAPPED); + release_sock(sk); break; } } @@ -619,7 +627,7 @@ static inline u8 l2cap_get_auth_type(struct l2cap_chan *chan) default: return HCI_AT_NO_BONDING; } - } else if (chan->psm == __constant_cpu_to_le16(L2CAP_PSM_SDP)) { + } else if (chan->psm == cpu_to_le16(0x0001)) { if (chan->sec_level == BT_SECURITY_LOW) chan->sec_level = BT_SECURITY_SDP; @@ -765,11 +773,9 @@ static inline void __unpack_control(struct l2cap_chan *chan, if (test_bit(FLAG_EXT_CTRL, &chan->flags)) { __unpack_extended_control(get_unaligned_le32(skb->data), &bt_cb(skb)->control); - skb_pull(skb, L2CAP_EXT_CTRL_SIZE); } else { __unpack_enhanced_control(get_unaligned_le16(skb->data), &bt_cb(skb)->control); - skb_pull(skb, L2CAP_ENH_CTRL_SIZE); } } @@ -824,102 +830,66 @@ static inline void __pack_control(struct l2cap_chan *chan, } } -static inline unsigned int __ertm_hdr_size(struct l2cap_chan *chan) -{ - if (test_bit(FLAG_EXT_CTRL, &chan->flags)) - return L2CAP_EXT_HDR_SIZE; - else - return L2CAP_ENH_HDR_SIZE; -} - -static struct sk_buff *l2cap_create_sframe_pdu(struct l2cap_chan *chan, - u32 control) +static inline void l2cap_send_sframe(struct l2cap_chan *chan, u32 control) { struct sk_buff *skb; struct l2cap_hdr *lh; - int hlen = __ertm_hdr_size(chan); + struct l2cap_conn *conn = chan->conn; + int count, hlen; + + if (chan->state != BT_CONNECTED) + return; + + if (test_bit(FLAG_EXT_CTRL, &chan->flags)) + hlen = L2CAP_EXT_HDR_SIZE; + else + hlen = L2CAP_ENH_HDR_SIZE; if (chan->fcs == L2CAP_FCS_CRC16) hlen += L2CAP_FCS_SIZE; - skb = bt_skb_alloc(hlen, GFP_KERNEL); + BT_DBG("chan %p, control 0x%8.8x", chan, control); + + count = min_t(unsigned int, conn->mtu, hlen); + + control |= __set_sframe(chan); + + if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state)) + control |= __set_ctrl_final(chan); + if (test_and_clear_bit(CONN_SEND_PBIT, &chan->conn_state)) + control |= __set_ctrl_poll(chan); + + skb = bt_skb_alloc(count, GFP_ATOMIC); if (!skb) - return ERR_PTR(-ENOMEM); + return; lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE); lh->len = cpu_to_le16(hlen - L2CAP_HDR_SIZE); lh->cid = cpu_to_le16(chan->dcid); - if (test_bit(FLAG_EXT_CTRL, &chan->flags)) - put_unaligned_le32(control, skb_put(skb, L2CAP_EXT_CTRL_SIZE)); - else - put_unaligned_le16(control, skb_put(skb, L2CAP_ENH_CTRL_SIZE)); + __put_control(chan, control, skb_put(skb, __ctrl_size(chan))); if (chan->fcs == L2CAP_FCS_CRC16) { - u16 fcs = crc16(0, (u8 *)skb->data, skb->len); + u16 fcs = crc16(0, (u8 *)lh, count - L2CAP_FCS_SIZE); put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE)); } skb->priority = HCI_PRIO_MAX; - return skb; + l2cap_do_send(chan, skb); } -static void l2cap_send_sframe(struct l2cap_chan *chan, - struct l2cap_ctrl *control) +static inline void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, u32 control) { - struct sk_buff *skb; - u32 control_field; - - BT_DBG("chan %p, control %p", chan, control); - - if (!control->sframe) - return; - - if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state) && - !control->poll) - control->final = 1; - - if (control->super == L2CAP_SUPER_RR) - clear_bit(CONN_RNR_SENT, &chan->conn_state); - else if (control->super == L2CAP_SUPER_RNR) + if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { + control |= __set_ctrl_super(chan, L2CAP_SUPER_RNR); set_bit(CONN_RNR_SENT, &chan->conn_state); + } else + control |= __set_ctrl_super(chan, L2CAP_SUPER_RR); - if (control->super != L2CAP_SUPER_SREJ) { - chan->last_acked_seq = control->reqseq; - __clear_ack_timer(chan); - } - - BT_DBG("reqseq %d, final %d, poll %d, super %d", control->reqseq, - control->final, control->poll, control->super); - - if (test_bit(FLAG_EXT_CTRL, &chan->flags)) - control_field = __pack_extended_control(control); - else - control_field = __pack_enhanced_control(control); - - skb = l2cap_create_sframe_pdu(chan, control_field); - if (!IS_ERR(skb)) - l2cap_do_send(chan, skb); -} - -static void l2cap_send_rr_or_rnr(struct l2cap_chan *chan, bool poll) -{ - struct l2cap_ctrl control; - - BT_DBG("chan %p, poll %d", chan, poll); - - memset(&control, 0, sizeof(control)); - control.sframe = 1; - control.poll = poll; - - if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) - control.super = L2CAP_SUPER_RNR; - else - control.super = L2CAP_SUPER_RR; + control |= __set_reqseq(chan, chan->buffer_seq); - control.reqseq = chan->buffer_seq; - l2cap_send_sframe(chan, &control); + l2cap_send_sframe(chan, control); } static inline int __l2cap_no_conn_pending(struct l2cap_chan *chan) @@ -944,13 +914,25 @@ static void l2cap_send_conn_req(struct l2cap_chan *chan) static void l2cap_chan_ready(struct l2cap_chan *chan) { - /* This clears all conf flags, including CONF_NOT_COMPLETE */ + struct sock *sk = chan->sk; + struct sock *parent; + + lock_sock(sk); + + parent = bt_sk(sk)->parent; + + BT_DBG("sk %p, parent %p", sk, parent); + chan->conf_state = 0; __clear_chan_timer(chan); - chan->state = BT_CONNECTED; + __l2cap_state_change(chan, BT_CONNECTED); + sk->sk_state_change(sk); + + if (parent) + parent->sk_data_ready(parent, 0); - chan->ops->ready(chan); + release_sock(sk); } static void l2cap_do_start(struct l2cap_chan *chan) @@ -971,7 +953,7 @@ static void l2cap_do_start(struct l2cap_chan *chan) l2cap_send_conn_req(chan); } else { struct l2cap_info_req req; - req.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK); + req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK); conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT; conn->info_ident = l2cap_get_ident(conn); @@ -1013,11 +995,6 @@ static void l2cap_send_disconn_req(struct l2cap_conn *conn, struct l2cap_chan *c __clear_ack_timer(chan); } - if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) { - __l2cap_state_change(chan, BT_DISCONN); - return; - } - req.dcid = cpu_to_le16(chan->dcid); req.scid = cpu_to_le16(chan->scid); l2cap_send_cmd(conn, l2cap_get_ident(conn), @@ -1076,20 +1053,20 @@ static void l2cap_conn_start(struct l2cap_conn *conn) if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) { struct sock *parent = bt_sk(sk)->parent; - rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND); - rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND); + rsp.result = cpu_to_le16(L2CAP_CR_PEND); + rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND); if (parent) parent->sk_data_ready(parent, 0); } else { __l2cap_state_change(chan, BT_CONFIG); - rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS); - rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO); + rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS); + rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); } release_sock(sk); } else { - rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND); - rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND); + rsp.result = cpu_to_le16(L2CAP_CR_PEND); + rsp.status = cpu_to_le16(L2CAP_CS_AUTHEN_PEND); } l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, @@ -1173,7 +1150,13 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) lock_sock(parent); - chan = pchan->ops->new_connection(pchan); + /* Check for backlog size */ + if (sk_acceptq_is_full(parent)) { + BT_DBG("backlog full %d", parent->sk_ack_backlog); + goto clean; + } + + chan = pchan->ops->new_connection(pchan->data); if (!chan) goto clean; @@ -1188,7 +1171,10 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) l2cap_chan_add(conn, chan); - l2cap_chan_ready(chan); + __set_chan_timer(chan, sk->sk_sndtimeo); + + __l2cap_state_change(chan, BT_CONNECTED); + parent->sk_data_ready(parent, 0); clean: release_sock(parent); @@ -1212,11 +1198,6 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) l2cap_chan_lock(chan); - if (chan->chan_type == L2CAP_CHAN_CONN_FIX_A2MP) { - l2cap_chan_unlock(chan); - continue; - } - if (conn->hcon->type == LE_LINK) { if (smp_conn_security(conn, chan->sec_level)) l2cap_chan_ready(chan); @@ -1289,7 +1270,7 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) l2cap_chan_unlock(chan); - chan->ops->close(chan); + chan->ops->close(chan->data); l2cap_chan_put(chan); } @@ -1314,12 +1295,7 @@ static void security_timeout(struct work_struct *work) struct l2cap_conn *conn = container_of(work, struct l2cap_conn, security_timer.work); - BT_DBG("conn %p", conn); - - if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) { - smp_chan_destroy(conn); - l2cap_conn_del(conn->hcon, ETIMEDOUT); - } + l2cap_conn_del(conn->hcon, ETIMEDOUT); } static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, u8 status) @@ -1463,17 +1439,21 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, goto done; } - switch (chan->state) { + lock_sock(sk); + + switch (sk->sk_state) { case BT_CONNECT: case BT_CONNECT2: case BT_CONFIG: /* Already connecting */ err = 0; + release_sock(sk); goto done; case BT_CONNECTED: /* Already connected */ err = -EISCONN; + release_sock(sk); goto done; case BT_OPEN: @@ -1483,12 +1463,13 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, default: err = -EBADFD; + release_sock(sk); goto done; } /* Set destination address and psm */ - lock_sock(sk); bacpy(&bt_sk(sk)->dst, dst); + release_sock(sk); chan->psm = psm; @@ -1590,20 +1571,23 @@ int __l2cap_wait_ack(struct sock *sk) static void l2cap_monitor_timeout(struct work_struct *work) { struct l2cap_chan *chan = container_of(work, struct l2cap_chan, - monitor_timer.work); + monitor_timer.work); BT_DBG("chan %p", chan); l2cap_chan_lock(chan); - if (!chan->conn) { + if (chan->retry_count >= chan->remote_max_tx) { + l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED); l2cap_chan_unlock(chan); l2cap_chan_put(chan); return; } - l2cap_tx(chan, NULL, NULL, L2CAP_EV_MONITOR_TO); + chan->retry_count++; + __set_monitor_timer(chan); + l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL); l2cap_chan_unlock(chan); l2cap_chan_put(chan); } @@ -1611,293 +1595,234 @@ static void l2cap_monitor_timeout(struct work_struct *work) static void l2cap_retrans_timeout(struct work_struct *work) { struct l2cap_chan *chan = container_of(work, struct l2cap_chan, - retrans_timer.work); + retrans_timer.work); BT_DBG("chan %p", chan); l2cap_chan_lock(chan); - if (!chan->conn) { - l2cap_chan_unlock(chan); - l2cap_chan_put(chan); - return; - } + chan->retry_count = 1; + __set_monitor_timer(chan); + + set_bit(CONN_WAIT_F, &chan->conn_state); + + l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_POLL); - l2cap_tx(chan, NULL, NULL, L2CAP_EV_RETRANS_TO); l2cap_chan_unlock(chan); l2cap_chan_put(chan); } -static void l2cap_streaming_send(struct l2cap_chan *chan, - struct sk_buff_head *skbs) +static void l2cap_drop_acked_frames(struct l2cap_chan *chan) { struct sk_buff *skb; - struct l2cap_ctrl *control; - - BT_DBG("chan %p, skbs %p", chan, skbs); - skb_queue_splice_tail_init(skbs, &chan->tx_q); - - while (!skb_queue_empty(&chan->tx_q)) { + while ((skb = skb_peek(&chan->tx_q)) && + chan->unacked_frames) { + if (bt_cb(skb)->control.txseq == chan->expected_ack_seq) + break; skb = skb_dequeue(&chan->tx_q); + kfree_skb(skb); + + chan->unacked_frames--; + } - bt_cb(skb)->control.retries = 1; - control = &bt_cb(skb)->control; + if (!chan->unacked_frames) + __clear_retrans_timer(chan); +} - control->reqseq = 0; - control->txseq = chan->next_tx_seq; +static void l2cap_streaming_send(struct l2cap_chan *chan) +{ + struct sk_buff *skb; + u32 control; + u16 fcs; - __pack_control(chan, control, skb); + while ((skb = skb_dequeue(&chan->tx_q))) { + control = __get_control(chan, skb->data + L2CAP_HDR_SIZE); + control |= __set_txseq(chan, chan->next_tx_seq); + control |= __set_ctrl_sar(chan, bt_cb(skb)->control.sar); + __put_control(chan, control, skb->data + L2CAP_HDR_SIZE); if (chan->fcs == L2CAP_FCS_CRC16) { - u16 fcs = crc16(0, (u8 *) skb->data, skb->len); - put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE)); + fcs = crc16(0, (u8 *)skb->data, + skb->len - L2CAP_FCS_SIZE); + put_unaligned_le16(fcs, + skb->data + skb->len - L2CAP_FCS_SIZE); } l2cap_do_send(chan, skb); - BT_DBG("Sent txseq %d", (int)control->txseq); - chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq); - chan->frames_sent++; } } -static int l2cap_ertm_send(struct l2cap_chan *chan) +static void l2cap_retransmit_one_frame(struct l2cap_chan *chan, u16 tx_seq) { struct sk_buff *skb, *tx_skb; - struct l2cap_ctrl *control; - int sent = 0; - - BT_DBG("chan %p", chan); - - if (chan->state != BT_CONNECTED) - return -ENOTCONN; - - if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) - return 0; - - while (chan->tx_send_head && - chan->unacked_frames < chan->remote_tx_win && - chan->tx_state == L2CAP_TX_STATE_XMIT) { - - skb = chan->tx_send_head; - - bt_cb(skb)->control.retries = 1; - control = &bt_cb(skb)->control; + u16 fcs; + u32 control; - if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state)) - control->final = 1; + skb = skb_peek(&chan->tx_q); + if (!skb) + return; - control->reqseq = chan->buffer_seq; - chan->last_acked_seq = chan->buffer_seq; - control->txseq = chan->next_tx_seq; + while (bt_cb(skb)->control.txseq != tx_seq) { + if (skb_queue_is_last(&chan->tx_q, skb)) + return; - __pack_control(chan, control, skb); + skb = skb_queue_next(&chan->tx_q, skb); + } - if (chan->fcs == L2CAP_FCS_CRC16) { - u16 fcs = crc16(0, (u8 *) skb->data, skb->len); - put_unaligned_le16(fcs, skb_put(skb, L2CAP_FCS_SIZE)); - } + if (bt_cb(skb)->control.retries == chan->remote_max_tx && + chan->remote_max_tx) { + l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED); + return; + } - /* Clone after data has been modified. Data is assumed to be - read-only (for locking purposes) on cloned sk_buffs. - */ - tx_skb = skb_clone(skb, GFP_KERNEL); + tx_skb = skb_clone(skb, GFP_ATOMIC); + bt_cb(skb)->control.retries++; - if (!tx_skb) - break; + control = __get_control(chan, tx_skb->data + L2CAP_HDR_SIZE); + control &= __get_sar_mask(chan); - __set_retrans_timer(chan); + if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state)) + control |= __set_ctrl_final(chan); - chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq); - chan->unacked_frames++; - chan->frames_sent++; - sent++; + control |= __set_reqseq(chan, chan->buffer_seq); + control |= __set_txseq(chan, tx_seq); - if (skb_queue_is_last(&chan->tx_q, skb)) - chan->tx_send_head = NULL; - else - chan->tx_send_head = skb_queue_next(&chan->tx_q, skb); + __put_control(chan, control, tx_skb->data + L2CAP_HDR_SIZE); - l2cap_do_send(chan, tx_skb); - BT_DBG("Sent txseq %d", (int)control->txseq); + if (chan->fcs == L2CAP_FCS_CRC16) { + fcs = crc16(0, (u8 *)tx_skb->data, + tx_skb->len - L2CAP_FCS_SIZE); + put_unaligned_le16(fcs, + tx_skb->data + tx_skb->len - L2CAP_FCS_SIZE); } - BT_DBG("Sent %d, %d unacked, %d in ERTM queue", sent, - (int) chan->unacked_frames, skb_queue_len(&chan->tx_q)); - - return sent; + l2cap_do_send(chan, tx_skb); } -static void l2cap_ertm_resend(struct l2cap_chan *chan) +static int l2cap_ertm_send(struct l2cap_chan *chan) { - struct l2cap_ctrl control; - struct sk_buff *skb; - struct sk_buff *tx_skb; - u16 seq; + struct sk_buff *skb, *tx_skb; + u16 fcs; + u32 control; + int nsent = 0; - BT_DBG("chan %p", chan); + if (chan->state != BT_CONNECTED) + return -ENOTCONN; if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) - return; + return 0; - while (chan->retrans_list.head != L2CAP_SEQ_LIST_CLEAR) { - seq = l2cap_seq_list_pop(&chan->retrans_list); + while ((skb = chan->tx_send_head) && (!l2cap_tx_window_full(chan))) { - skb = l2cap_ertm_seq_in_queue(&chan->tx_q, seq); - if (!skb) { - BT_DBG("Error: Can't retransmit seq %d, frame missing", - seq); - continue; + if (bt_cb(skb)->control.retries == chan->remote_max_tx && + chan->remote_max_tx) { + l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED); + break; } + tx_skb = skb_clone(skb, GFP_ATOMIC); + bt_cb(skb)->control.retries++; - control = bt_cb(skb)->control; - 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->conn, chan, ECONNRESET); - l2cap_seq_list_clear(&chan->retrans_list); - break; - } + control = __get_control(chan, tx_skb->data + L2CAP_HDR_SIZE); + control &= __get_sar_mask(chan); - control.reqseq = chan->buffer_seq; if (test_and_clear_bit(CONN_SEND_FBIT, &chan->conn_state)) - control.final = 1; - else - control.final = 0; - - if (skb_cloned(skb)) { - /* Cloned sk_buffs are read-only, so we need a - * writeable copy - */ - tx_skb = skb_copy(skb, GFP_ATOMIC); - } else { - tx_skb = skb_clone(skb, GFP_ATOMIC); - } + control |= __set_ctrl_final(chan); - if (!tx_skb) { - l2cap_seq_list_clear(&chan->retrans_list); - break; - } + control |= __set_reqseq(chan, chan->buffer_seq); + control |= __set_txseq(chan, chan->next_tx_seq); + control |= __set_ctrl_sar(chan, bt_cb(skb)->control.sar); - /* Update skb contents */ - if (test_bit(FLAG_EXT_CTRL, &chan->flags)) { - put_unaligned_le32(__pack_extended_control(&control), - tx_skb->data + L2CAP_HDR_SIZE); - } else { - put_unaligned_le16(__pack_enhanced_control(&control), - tx_skb->data + L2CAP_HDR_SIZE); - } + __put_control(chan, control, tx_skb->data + L2CAP_HDR_SIZE); if (chan->fcs == L2CAP_FCS_CRC16) { - u16 fcs = crc16(0, (u8 *) tx_skb->data, tx_skb->len); - put_unaligned_le16(fcs, skb_put(tx_skb, - L2CAP_FCS_SIZE)); + fcs = crc16(0, (u8 *)skb->data, + tx_skb->len - L2CAP_FCS_SIZE); + put_unaligned_le16(fcs, skb->data + + tx_skb->len - L2CAP_FCS_SIZE); } l2cap_do_send(chan, tx_skb); - BT_DBG("Resent txseq %d", control.txseq); + __set_retrans_timer(chan); + + bt_cb(skb)->control.txseq = chan->next_tx_seq; + + chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq); + + if (bt_cb(skb)->control.retries == 1) { + chan->unacked_frames++; + + if (!nsent++) + __clear_ack_timer(chan); + } + + chan->frames_sent++; - chan->last_acked_seq = chan->buffer_seq; + if (skb_queue_is_last(&chan->tx_q, skb)) + chan->tx_send_head = NULL; + else + chan->tx_send_head = skb_queue_next(&chan->tx_q, skb); } + + return nsent; } -static void l2cap_retransmit(struct l2cap_chan *chan, - struct l2cap_ctrl *control) +static int l2cap_retransmit_frames(struct l2cap_chan *chan) { - BT_DBG("chan %p, control %p", chan, control); + int ret; - l2cap_seq_list_append(&chan->retrans_list, control->reqseq); - l2cap_ertm_resend(chan); + if (!skb_queue_empty(&chan->tx_q)) + chan->tx_send_head = chan->tx_q.next; + + chan->next_tx_seq = chan->expected_ack_seq; + ret = l2cap_ertm_send(chan); + return ret; } -static void l2cap_retransmit_all(struct l2cap_chan *chan, - struct l2cap_ctrl *control) +static void __l2cap_send_ack(struct l2cap_chan *chan) { - struct sk_buff *skb; - - BT_DBG("chan %p, control %p", chan, control); - - if (control->poll) - set_bit(CONN_SEND_FBIT, &chan->conn_state); + u32 control = 0; - l2cap_seq_list_clear(&chan->retrans_list); + control |= __set_reqseq(chan, chan->buffer_seq); - if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) + if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { + control |= __set_ctrl_super(chan, L2CAP_SUPER_RNR); + set_bit(CONN_RNR_SENT, &chan->conn_state); + l2cap_send_sframe(chan, control); return; + } - if (chan->unacked_frames) { - skb_queue_walk(&chan->tx_q, skb) { - if (bt_cb(skb)->control.txseq == control->reqseq || - skb == chan->tx_send_head) - break; - } - - skb_queue_walk_from(&chan->tx_q, skb) { - if (skb == chan->tx_send_head) - break; - - l2cap_seq_list_append(&chan->retrans_list, - bt_cb(skb)->control.txseq); - } + if (l2cap_ertm_send(chan) > 0) + return; - l2cap_ertm_resend(chan); - } + control |= __set_ctrl_super(chan, L2CAP_SUPER_RR); + l2cap_send_sframe(chan, control); } static void l2cap_send_ack(struct l2cap_chan *chan) { - struct l2cap_ctrl control; - u16 frames_to_ack = __seq_offset(chan, chan->buffer_seq, - chan->last_acked_seq); - int threshold; - - BT_DBG("chan %p last_acked_seq %d buffer_seq %d", - chan, chan->last_acked_seq, chan->buffer_seq); + __clear_ack_timer(chan); + __l2cap_send_ack(chan); +} - memset(&control, 0, sizeof(control)); - control.sframe = 1; +static void l2cap_send_srejtail(struct l2cap_chan *chan) +{ + struct srej_list *tail; + u32 control; - if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state) && - chan->rx_state == L2CAP_RX_STATE_RECV) { - __clear_ack_timer(chan); - control.super = L2CAP_SUPER_RNR; - control.reqseq = chan->buffer_seq; - l2cap_send_sframe(chan, &control); - } else { - if (!test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) { - l2cap_ertm_send(chan); - /* If any i-frames were sent, they included an ack */ - if (chan->buffer_seq == chan->last_acked_seq) - frames_to_ack = 0; - } + control = __set_ctrl_super(chan, L2CAP_SUPER_SREJ); + control |= __set_ctrl_final(chan); - /* Ack now if the tx window is 3/4ths full. - * Calculate without mul or div - */ - threshold = chan->tx_win; - threshold += threshold << 1; - threshold >>= 2; - - BT_DBG("frames_to_ack %d, threshold %d", (int)frames_to_ack, - threshold); - - if (frames_to_ack >= threshold) { - __clear_ack_timer(chan); - control.super = L2CAP_SUPER_RR; - control.reqseq = chan->buffer_seq; - l2cap_send_sframe(chan, &control); - frames_to_ack = 0; - } + tail = list_entry((&chan->srej_l)->prev, struct srej_list, list); + control |= __set_reqseq(chan, tail->tx_seq); - if (frames_to_ack) - __set_ack_timer(chan); - } + l2cap_send_sframe(chan, control); } static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan, @@ -2026,7 +1951,10 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, if (!conn) return ERR_PTR(-ENOTCONN); - hlen = __ertm_hdr_size(chan); + if (test_bit(FLAG_EXT_CTRL, &chan->flags)) + hlen = L2CAP_EXT_HDR_SIZE; + else + hlen = L2CAP_ENH_HDR_SIZE; if (sdulen) hlen += L2CAP_SDULEN_SIZE; @@ -2046,11 +1974,7 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, lh->cid = cpu_to_le16(chan->dcid); lh->len = cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE)); - /* Control header is populated later */ - if (test_bit(FLAG_EXT_CTRL, &chan->flags)) - put_unaligned_le32(0, skb_put(skb, L2CAP_EXT_CTRL_SIZE)); - else - put_unaligned_le16(0, skb_put(skb, L2CAP_ENH_CTRL_SIZE)); + __put_control(chan, 0, skb_put(skb, __ctrl_size(chan))); if (sdulen) put_unaligned_le16(sdulen, skb_put(skb, L2CAP_SDULEN_SIZE)); @@ -2061,8 +1985,10 @@ static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, return ERR_PTR(err); } - bt_cb(skb)->control.fcs = chan->fcs; - bt_cb(skb)->control.retries = 0; + if (chan->fcs == L2CAP_FCS_CRC16) + put_unaligned_le16(0, skb_put(skb, L2CAP_FCS_SIZE)); + + bt_cb(skb)->control.retries = 0; return skb; } @@ -2073,6 +1999,7 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan, struct sk_buff *skb; u16 sdu_len; size_t pdu_len; + int err = 0; u8 sar; BT_DBG("chan %p, msg %p, len %d", chan, msg, (int)len); @@ -2088,10 +2015,7 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan, pdu_len = min_t(size_t, pdu_len, L2CAP_BREDR_MAX_PAYLOAD); /* Adjust for largest possible L2CAP overhead. */ - if (chan->fcs) - pdu_len -= L2CAP_FCS_SIZE; - - pdu_len -= __ertm_hdr_size(chan); + pdu_len -= L2CAP_EXT_HDR_SIZE + L2CAP_FCS_SIZE; /* Remote device may have requested smaller PDUs */ pdu_len = min_t(size_t, pdu_len, chan->remote_mps); @@ -2131,7 +2055,7 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan, } } - return 0; + return err; } int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, @@ -2193,12 +2117,17 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, if (err) break; + if (chan->mode == L2CAP_MODE_ERTM && chan->tx_send_head == NULL) + chan->tx_send_head = seg_queue.next; + skb_queue_splice_tail_init(&seg_queue, &chan->tx_q); + if (chan->mode == L2CAP_MODE_ERTM) - l2cap_tx(chan, NULL, &seg_queue, L2CAP_EV_DATA_REQUEST); + err = l2cap_ertm_send(chan); else - l2cap_streaming_send(chan, &seg_queue); + l2cap_streaming_send(chan); - err = len; + if (err >= 0) + err = len; /* If the skbs were not queued for sending, they'll still be in * seg_queue and need to be purged. @@ -2214,296 +2143,6 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, return err; } -static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq) -{ - struct l2cap_ctrl control; - u16 seq; - - BT_DBG("chan %p, txseq %d", chan, txseq); - - memset(&control, 0, sizeof(control)); - control.sframe = 1; - control.super = L2CAP_SUPER_SREJ; - - for (seq = chan->expected_tx_seq; seq != txseq; - seq = __next_seq(chan, seq)) { - if (!l2cap_ertm_seq_in_queue(&chan->srej_q, seq)) { - control.reqseq = seq; - l2cap_send_sframe(chan, &control); - l2cap_seq_list_append(&chan->srej_list, seq); - } - } - - chan->expected_tx_seq = __next_seq(chan, txseq); -} - -static void l2cap_send_srej_tail(struct l2cap_chan *chan) -{ - struct l2cap_ctrl control; - - BT_DBG("chan %p", chan); - - if (chan->srej_list.tail == L2CAP_SEQ_LIST_CLEAR) - return; - - memset(&control, 0, sizeof(control)); - control.sframe = 1; - control.super = L2CAP_SUPER_SREJ; - control.reqseq = chan->srej_list.tail; - l2cap_send_sframe(chan, &control); -} - -static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq) -{ - struct l2cap_ctrl control; - u16 initial_head; - u16 seq; - - BT_DBG("chan %p, txseq %d", chan, txseq); - - memset(&control, 0, sizeof(control)); - control.sframe = 1; - control.super = L2CAP_SUPER_SREJ; - - /* Capture initial list head to allow only one pass through the list. */ - initial_head = chan->srej_list.head; - - do { - seq = l2cap_seq_list_pop(&chan->srej_list); - if (seq == txseq || seq == L2CAP_SEQ_LIST_CLEAR) - break; - - control.reqseq = seq; - l2cap_send_sframe(chan, &control); - l2cap_seq_list_append(&chan->srej_list, seq); - } while (chan->srej_list.head != initial_head); -} - -static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq) -{ - struct sk_buff *acked_skb; - u16 ackseq; - - BT_DBG("chan %p, reqseq %d", chan, reqseq); - - if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq) - return; - - BT_DBG("expected_ack_seq %d, unacked_frames %d", - chan->expected_ack_seq, chan->unacked_frames); - - for (ackseq = chan->expected_ack_seq; ackseq != reqseq; - ackseq = __next_seq(chan, ackseq)) { - - acked_skb = l2cap_ertm_seq_in_queue(&chan->tx_q, ackseq); - if (acked_skb) { - skb_unlink(acked_skb, &chan->tx_q); - kfree_skb(acked_skb); - chan->unacked_frames--; - } - } - - chan->expected_ack_seq = reqseq; - - if (chan->unacked_frames == 0) - __clear_retrans_timer(chan); - - BT_DBG("unacked_frames %d", (int) chan->unacked_frames); -} - -static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan) -{ - BT_DBG("chan %p", chan); - - chan->expected_tx_seq = chan->buffer_seq; - l2cap_seq_list_clear(&chan->srej_list); - skb_queue_purge(&chan->srej_q); - chan->rx_state = L2CAP_RX_STATE_RECV; -} - -static void l2cap_tx_state_xmit(struct l2cap_chan *chan, - struct l2cap_ctrl *control, - struct sk_buff_head *skbs, u8 event) -{ - BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs, - event); - - switch (event) { - case L2CAP_EV_DATA_REQUEST: - if (chan->tx_send_head == NULL) - chan->tx_send_head = skb_peek(skbs); - - skb_queue_splice_tail_init(skbs, &chan->tx_q); - l2cap_ertm_send(chan); - break; - case L2CAP_EV_LOCAL_BUSY_DETECTED: - BT_DBG("Enter LOCAL_BUSY"); - set_bit(CONN_LOCAL_BUSY, &chan->conn_state); - - if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) { - /* The SREJ_SENT state must be aborted if we are to - * enter the LOCAL_BUSY state. - */ - l2cap_abort_rx_srej_sent(chan); - } - - l2cap_send_ack(chan); - - break; - case L2CAP_EV_LOCAL_BUSY_CLEAR: - BT_DBG("Exit LOCAL_BUSY"); - clear_bit(CONN_LOCAL_BUSY, &chan->conn_state); - - if (test_bit(CONN_RNR_SENT, &chan->conn_state)) { - struct l2cap_ctrl local_control; - - memset(&local_control, 0, sizeof(local_control)); - local_control.sframe = 1; - local_control.super = L2CAP_SUPER_RR; - local_control.poll = 1; - local_control.reqseq = chan->buffer_seq; - l2cap_send_sframe(chan, &local_control); - - chan->retry_count = 1; - __set_monitor_timer(chan); - chan->tx_state = L2CAP_TX_STATE_WAIT_F; - } - break; - case L2CAP_EV_RECV_REQSEQ_AND_FBIT: - l2cap_process_reqseq(chan, control->reqseq); - break; - case L2CAP_EV_EXPLICIT_POLL: - l2cap_send_rr_or_rnr(chan, 1); - chan->retry_count = 1; - __set_monitor_timer(chan); - __clear_ack_timer(chan); - chan->tx_state = L2CAP_TX_STATE_WAIT_F; - break; - case L2CAP_EV_RETRANS_TO: - l2cap_send_rr_or_rnr(chan, 1); - chan->retry_count = 1; - __set_monitor_timer(chan); - chan->tx_state = L2CAP_TX_STATE_WAIT_F; - break; - case L2CAP_EV_RECV_FBIT: - /* Nothing to process */ - break; - default: - break; - } -} - -static void l2cap_tx_state_wait_f(struct l2cap_chan *chan, - struct l2cap_ctrl *control, - struct sk_buff_head *skbs, u8 event) -{ - BT_DBG("chan %p, control %p, skbs %p, event %d", chan, control, skbs, - event); - - switch (event) { - case L2CAP_EV_DATA_REQUEST: - if (chan->tx_send_head == NULL) - chan->tx_send_head = skb_peek(skbs); - /* Queue data, but don't send. */ - skb_queue_splice_tail_init(skbs, &chan->tx_q); - break; - case L2CAP_EV_LOCAL_BUSY_DETECTED: - BT_DBG("Enter LOCAL_BUSY"); - set_bit(CONN_LOCAL_BUSY, &chan->conn_state); - - if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) { - /* The SREJ_SENT state must be aborted if we are to - * enter the LOCAL_BUSY state. - */ - l2cap_abort_rx_srej_sent(chan); - } - - l2cap_send_ack(chan); - - break; - case L2CAP_EV_LOCAL_BUSY_CLEAR: - BT_DBG("Exit LOCAL_BUSY"); - clear_bit(CONN_LOCAL_BUSY, &chan->conn_state); - - if (test_bit(CONN_RNR_SENT, &chan->conn_state)) { - struct l2cap_ctrl local_control; - memset(&local_control, 0, sizeof(local_control)); - local_control.sframe = 1; - local_control.super = L2CAP_SUPER_RR; - local_control.poll = 1; - local_control.reqseq = chan->buffer_seq; - l2cap_send_sframe(chan, &local_control); - - chan->retry_count = 1; - __set_monitor_timer(chan); - chan->tx_state = L2CAP_TX_STATE_WAIT_F; - } - break; - case L2CAP_EV_RECV_REQSEQ_AND_FBIT: - l2cap_process_reqseq(chan, control->reqseq); - - /* Fall through */ - - case L2CAP_EV_RECV_FBIT: - if (control && control->final) { - __clear_monitor_timer(chan); - if (chan->unacked_frames > 0) - __set_retrans_timer(chan); - chan->retry_count = 0; - chan->tx_state = L2CAP_TX_STATE_XMIT; - BT_DBG("recv fbit tx_state 0x2.2%x", chan->tx_state); - } - break; - case L2CAP_EV_EXPLICIT_POLL: - /* Ignore */ - break; - case L2CAP_EV_MONITOR_TO: - if (chan->max_tx == 0 || chan->retry_count < chan->max_tx) { - l2cap_send_rr_or_rnr(chan, 1); - __set_monitor_timer(chan); - chan->retry_count++; - } else { - l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED); - } - break; - default: - break; - } -} - -static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control, - struct sk_buff_head *skbs, u8 event) -{ - BT_DBG("chan %p, control %p, skbs %p, event %d, state %d", - chan, control, skbs, event, chan->tx_state); - - switch (chan->tx_state) { - case L2CAP_TX_STATE_XMIT: - l2cap_tx_state_xmit(chan, control, skbs, event); - break; - case L2CAP_TX_STATE_WAIT_F: - l2cap_tx_state_wait_f(chan, control, skbs, event); - break; - default: - /* Ignore event */ - break; - } -} - -static void l2cap_pass_to_tx(struct l2cap_chan *chan, - struct l2cap_ctrl *control) -{ - BT_DBG("chan %p, control %p", chan, control); - l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_REQSEQ_AND_FBIT); -} - -static void l2cap_pass_to_tx_fbit(struct l2cap_chan *chan, - struct l2cap_ctrl *control) -{ - BT_DBG("chan %p, control %p", chan, control); - l2cap_tx(chan, control, NULL, L2CAP_EV_RECV_FBIT); -} - /* Copy frame to all raw sockets on that connection */ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) { @@ -2526,7 +2165,7 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) if (!nskb) continue; - if (chan->ops->recv(chan, nskb)) + if (chan->ops->recv(chan->data, nskb)) kfree_skb(nskb); } @@ -2556,9 +2195,9 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen); if (conn->hcon->type == LE_LINK) - lh->cid = __constant_cpu_to_le16(L2CAP_CID_LE_SIGNALING); + lh->cid = cpu_to_le16(L2CAP_CID_LE_SIGNALING); else - lh->cid = __constant_cpu_to_le16(L2CAP_CID_SIGNALING); + lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING); cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE); cmd->code = code; @@ -2670,8 +2309,8 @@ static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan) efs.stype = chan->local_stype; efs.msdu = cpu_to_le16(chan->local_msdu); efs.sdu_itime = cpu_to_le32(chan->local_sdu_itime); - efs.acc_lat = __constant_cpu_to_le32(L2CAP_DEFAULT_ACC_LAT); - efs.flush_to = __constant_cpu_to_le32(L2CAP_DEFAULT_FLUSH_TO); + efs.acc_lat = cpu_to_le32(L2CAP_DEFAULT_ACC_LAT); + efs.flush_to = cpu_to_le32(L2CAP_DEFAULT_FLUSH_TO); break; case L2CAP_MODE_STREAMING: @@ -2694,24 +2333,20 @@ static void l2cap_add_opt_efs(void **ptr, struct l2cap_chan *chan) static void l2cap_ack_timeout(struct work_struct *work) { struct l2cap_chan *chan = container_of(work, struct l2cap_chan, - ack_timer.work); - u16 frames_to_ack; + ack_timer.work); BT_DBG("chan %p", chan); l2cap_chan_lock(chan); - frames_to_ack = __seq_offset(chan, chan->buffer_seq, - chan->last_acked_seq); - - if (frames_to_ack) - l2cap_send_rr_or_rnr(chan, 0); + __l2cap_send_ack(chan); l2cap_chan_unlock(chan); + l2cap_chan_put(chan); } -int l2cap_ertm_init(struct l2cap_chan *chan) +static inline int l2cap_ertm_init(struct l2cap_chan *chan) { int err; @@ -2720,6 +2355,7 @@ int l2cap_ertm_init(struct l2cap_chan *chan) chan->expected_ack_seq = 0; chan->unacked_frames = 0; chan->buffer_seq = 0; + chan->num_acked = 0; chan->frames_sent = 0; chan->last_acked_seq = 0; chan->sdu = NULL; @@ -2740,15 +2376,12 @@ int l2cap_ertm_init(struct l2cap_chan *chan) skb_queue_head_init(&chan->srej_q); + INIT_LIST_HEAD(&chan->srej_l); err = l2cap_seq_list_init(&chan->srej_list, chan->tx_win); if (err < 0) return err; - err = l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win); - if (err < 0) - l2cap_seq_list_free(&chan->srej_list); - - return err; + return l2cap_seq_list_init(&chan->retrans_list, chan->remote_tx_win); } static inline __u8 l2cap_select_mode(__u8 mode, __u16 remote_feat_mask) @@ -2874,7 +2507,6 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) break; case L2CAP_MODE_STREAMING: - l2cap_txwin_setup(chan); rfc.mode = L2CAP_MODE_STREAMING; rfc.txwin_size = 0; rfc.max_transmit = 0; @@ -2905,7 +2537,7 @@ static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) } req->dcid = cpu_to_le16(chan->dcid); - req->flags = __constant_cpu_to_le16(0); + req->flags = cpu_to_le16(0); return ptr - data; } @@ -3125,7 +2757,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data) } rsp->scid = cpu_to_le16(chan->dcid); rsp->result = cpu_to_le16(result); - rsp->flags = __constant_cpu_to_le16(0); + rsp->flags = cpu_to_le16(0x0000); return ptr - data; } @@ -3224,7 +2856,7 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi } req->dcid = cpu_to_le16(chan->dcid); - req->flags = __constant_cpu_to_le16(0); + req->flags = cpu_to_le16(0x0000); return ptr - data; } @@ -3251,8 +2883,8 @@ void __l2cap_connect_rsp_defer(struct l2cap_chan *chan) 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); + rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS); + rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp); @@ -3278,22 +2910,20 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len) while (len >= L2CAP_CONF_OPT_SIZE) { len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val); - if (type != L2CAP_CONF_RFC) - continue; - - if (olen != sizeof(rfc)) - break; - - memcpy(&rfc, (void *)val, olen); - goto done; + switch (type) { + case L2CAP_CONF_RFC: + if (olen == sizeof(rfc)) + memcpy(&rfc, (void *)val, olen); + goto done; + } } /* Use sane default values in case a misbehaving remote device * did not send an RFC option. */ rfc.mode = chan->mode; - rfc.retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO); - rfc.monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO); + rfc.retrans_timeout = cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO); + rfc.monitor_timeout = cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO); rfc.max_pdu_size = cpu_to_le16(chan->imtu); BT_ERR("Expected RFC option was not found, using defaults"); @@ -3356,7 +2986,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd lock_sock(parent); /* Check if the ACL is secure enough (if not SDP) */ - if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) && + if (psm != cpu_to_le16(0x0001) && !hci_conn_check_link_mode(conn->hcon)) { conn->disc_reason = HCI_ERROR_AUTH_FAILURE; result = L2CAP_CR_SEC_BLOCK; @@ -3365,16 +2995,25 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd result = L2CAP_CR_NO_MEM; - /* Check if we already have channel with that dcid */ - if (__l2cap_get_chan_by_dcid(conn, scid)) + /* Check for backlog size */ + if (sk_acceptq_is_full(parent)) { + BT_DBG("backlog full %d", parent->sk_ack_backlog); goto response; + } - chan = pchan->ops->new_connection(pchan); + chan = pchan->ops->new_connection(pchan->data); if (!chan) goto response; sk = chan->sk; + /* Check if we already have channel with that dcid */ + if (__l2cap_get_chan_by_dcid(conn, scid)) { + sock_set_flag(sk, SOCK_ZAPPED); + chan->ops->close(chan->data); + goto response; + } + hci_conn_hold(conn->hcon); bacpy(&bt_sk(sk)->src, conn->src); @@ -3428,7 +3067,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd if (result == L2CAP_CR_PEND && status == L2CAP_CS_NO_INFO) { struct l2cap_info_req info; - info.type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK); + info.type = cpu_to_le16(L2CAP_IT_FEAT_MASK); conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT; conn->info_ident = l2cap_get_ident(conn); @@ -3550,7 +3189,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr if (chan->state != BT_CONFIG && chan->state != BT_CONNECT2) { struct l2cap_cmd_rej_cid rej; - rej.reason = __constant_cpu_to_le16(L2CAP_REJ_INVALID_CID); + rej.reason = cpu_to_le16(L2CAP_REJ_INVALID_CID); rej.scid = cpu_to_le16(chan->scid); rej.dcid = cpu_to_le16(chan->dcid); @@ -3572,11 +3211,11 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr memcpy(chan->conf_req + chan->conf_len, req->data, len); chan->conf_len += len; - if (flags & L2CAP_CONF_FLAG_CONTINUATION) { + if (flags & 0x0001) { /* Incomplete config. Send empty response. */ l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(chan, rsp, - L2CAP_CONF_SUCCESS, flags), rsp); + L2CAP_CONF_SUCCESS, 0x0001), rsp); goto unlock; } @@ -3599,6 +3238,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr if (test_bit(CONF_INPUT_DONE, &chan->conf_state)) { set_default_fcs(chan); + l2cap_state_change(chan, BT_CONNECTED); + if (chan->mode == L2CAP_MODE_ERTM || chan->mode == L2CAP_MODE_STREAMING) err = l2cap_ertm_init(chan); @@ -3630,7 +3271,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(chan, rsp, - L2CAP_CONF_SUCCESS, flags), rsp); + L2CAP_CONF_SUCCESS, 0x0000), rsp); } unlock: @@ -3721,7 +3362,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr goto done; } - if (flags & L2CAP_CONF_FLAG_CONTINUATION) + if (flags & 0x01) goto done; set_bit(CONF_INPUT_DONE, &chan->conf_state); @@ -3729,6 +3370,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr if (test_bit(CONF_OUTPUT_DONE, &chan->conf_state)) { set_default_fcs(chan); + l2cap_state_change(chan, BT_CONNECTED); if (chan->mode == L2CAP_MODE_ERTM || chan->mode == L2CAP_MODE_STREAMING) err = l2cap_ertm_init(chan); @@ -3782,7 +3424,7 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd l2cap_chan_unlock(chan); - chan->ops->close(chan); + chan->ops->close(chan->data); l2cap_chan_put(chan); mutex_unlock(&conn->chan_lock); @@ -3816,7 +3458,7 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd l2cap_chan_unlock(chan); - chan->ops->close(chan); + chan->ops->close(chan->data); l2cap_chan_put(chan); mutex_unlock(&conn->chan_lock); @@ -3837,8 +3479,8 @@ static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cm u8 buf[8]; u32 feat_mask = l2cap_feat_mask; struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) buf; - rsp->type = __constant_cpu_to_le16(L2CAP_IT_FEAT_MASK); - rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS); + rsp->type = cpu_to_le16(L2CAP_IT_FEAT_MASK); + rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS); if (!disable_ertm) feat_mask |= L2CAP_FEAT_ERTM | L2CAP_FEAT_STREAMING | L2CAP_FEAT_FCS; @@ -3858,15 +3500,15 @@ static inline int l2cap_information_req(struct l2cap_conn *conn, struct l2cap_cm else l2cap_fixed_chan[0] &= ~L2CAP_FC_A2MP; - rsp->type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN); - rsp->result = __constant_cpu_to_le16(L2CAP_IR_SUCCESS); + rsp->type = cpu_to_le16(L2CAP_IT_FIXED_CHAN); + rsp->result = cpu_to_le16(L2CAP_IR_SUCCESS); memcpy(rsp->data, l2cap_fixed_chan, sizeof(l2cap_fixed_chan)); l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(buf), buf); } else { struct l2cap_info_rsp rsp; rsp.type = cpu_to_le16(type); - rsp.result = __constant_cpu_to_le16(L2CAP_IR_NOTSUPP); + rsp.result = cpu_to_le16(L2CAP_IR_NOTSUPP); l2cap_send_cmd(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp), &rsp); } @@ -3906,7 +3548,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) { struct l2cap_info_req req; - req.type = __constant_cpu_to_le16(L2CAP_IT_FIXED_CHAN); + req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN); conn->info_ident = l2cap_get_ident(conn); @@ -4141,9 +3783,9 @@ static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn, err = l2cap_check_conn_param(min, max, latency, to_multiplier); if (err) - rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_REJECTED); + rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_REJECTED); else - rsp.result = __constant_cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED); + rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_ACCEPTED); l2cap_send_cmd(conn, cmd->ident, L2CAP_CONN_PARAM_UPDATE_RSP, sizeof(rsp), &rsp); @@ -4291,7 +3933,7 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, BT_ERR("Wrong link type (%d)", err); /* FIXME: Map err to a valid reason */ - rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD); + rej.reason = cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD); l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej); } @@ -4323,38 +3965,65 @@ static int l2cap_check_fcs(struct l2cap_chan *chan, struct sk_buff *skb) return 0; } -static void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan) +static inline void l2cap_send_i_or_rr_or_rnr(struct l2cap_chan *chan) { - struct l2cap_ctrl control; + u32 control = 0; - BT_DBG("chan %p", chan); + chan->frames_sent = 0; - memset(&control, 0, sizeof(control)); - control.sframe = 1; - control.final = 1; - control.reqseq = chan->buffer_seq; - set_bit(CONN_SEND_FBIT, &chan->conn_state); + control |= __set_reqseq(chan, chan->buffer_seq); if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { - control.super = L2CAP_SUPER_RNR; - l2cap_send_sframe(chan, &control); + control |= __set_ctrl_super(chan, L2CAP_SUPER_RNR); + l2cap_send_sframe(chan, control); + set_bit(CONN_RNR_SENT, &chan->conn_state); } - if (test_and_clear_bit(CONN_REMOTE_BUSY, &chan->conn_state) && - chan->unacked_frames > 0) - __set_retrans_timer(chan); + if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state)) + l2cap_retransmit_frames(chan); - /* Send pending iframes */ l2cap_ertm_send(chan); if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state) && - test_bit(CONN_SEND_FBIT, &chan->conn_state)) { - /* F-bit wasn't sent in an s-frame or i-frame yet, so - * send it now. - */ - control.super = L2CAP_SUPER_RR; - l2cap_send_sframe(chan, &control); + chan->frames_sent == 0) { + control |= __set_ctrl_super(chan, L2CAP_SUPER_RR); + l2cap_send_sframe(chan, control); + } +} + +static int l2cap_add_to_srej_queue(struct l2cap_chan *chan, struct sk_buff *skb, u16 tx_seq, u8 sar) +{ + struct sk_buff *next_skb; + int tx_seq_offset, next_tx_seq_offset; + + bt_cb(skb)->control.txseq = tx_seq; + bt_cb(skb)->control.sar = sar; + + next_skb = skb_peek(&chan->srej_q); + + tx_seq_offset = __seq_offset(chan, tx_seq, chan->buffer_seq); + + while (next_skb) { + if (bt_cb(next_skb)->control.txseq == tx_seq) + return -EINVAL; + + next_tx_seq_offset = __seq_offset(chan, + bt_cb(next_skb)->control.txseq, chan->buffer_seq); + + if (next_tx_seq_offset > tx_seq_offset) { + __skb_queue_before(&chan->srej_q, next_skb, skb); + return 0; + } + + if (skb_queue_is_last(&chan->srej_q, next_skb)) + next_skb = NULL; + else + next_skb = skb_queue_next(&chan->srej_q, next_skb); } + + __skb_queue_tail(&chan->srej_q, skb); + + return 0; } static void append_skb_frag(struct sk_buff *skb, @@ -4376,17 +4045,16 @@ static void append_skb_frag(struct sk_buff *skb, skb->truesize += new_frag->truesize; } -static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb, - struct l2cap_ctrl *control) +static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb, u32 control) { int err = -EINVAL; - switch (control->sar) { + switch (__get_ctrl_sar(chan, control)) { case L2CAP_SAR_UNSEGMENTED: if (chan->sdu) break; - err = chan->ops->recv(chan, skb); + err = chan->ops->recv(chan->data, skb); break; case L2CAP_SAR_START: @@ -4436,7 +4104,7 @@ static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb, if (chan->sdu->len != chan->sdu_len) break; - err = chan->ops->recv(chan, chan->sdu); + err = chan->ops->recv(chan->data, chan->sdu); if (!err) { /* Reassembly complete */ @@ -4458,609 +4126,448 @@ static int l2cap_reassemble_sdu(struct l2cap_chan *chan, struct sk_buff *skb, return err; } -void l2cap_chan_busy(struct l2cap_chan *chan, int busy) +static void l2cap_ertm_enter_local_busy(struct l2cap_chan *chan) { - u8 event; + BT_DBG("chan %p, Enter local busy", chan); - if (chan->mode != L2CAP_MODE_ERTM) - return; + set_bit(CONN_LOCAL_BUSY, &chan->conn_state); + l2cap_seq_list_clear(&chan->srej_list); - event = busy ? L2CAP_EV_LOCAL_BUSY_DETECTED : L2CAP_EV_LOCAL_BUSY_CLEAR; - l2cap_tx(chan, NULL, NULL, event); + __set_ack_timer(chan); } -static int l2cap_rx_queued_iframes(struct l2cap_chan *chan) +static void l2cap_ertm_exit_local_busy(struct l2cap_chan *chan) { - int err = 0; - /* Pass sequential frames to l2cap_reassemble_sdu() - * until a gap is encountered. - */ + u32 control; - BT_DBG("chan %p", chan); + if (!test_bit(CONN_RNR_SENT, &chan->conn_state)) + goto done; - while (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { - struct sk_buff *skb; - BT_DBG("Searching for skb with txseq %d (queue len %d)", - chan->buffer_seq, skb_queue_len(&chan->srej_q)); + control = __set_reqseq(chan, chan->buffer_seq); + control |= __set_ctrl_poll(chan); + control |= __set_ctrl_super(chan, L2CAP_SUPER_RR); + l2cap_send_sframe(chan, control); + chan->retry_count = 1; - skb = l2cap_ertm_seq_in_queue(&chan->srej_q, chan->buffer_seq); + __clear_retrans_timer(chan); + __set_monitor_timer(chan); - if (!skb) - break; + set_bit(CONN_WAIT_F, &chan->conn_state); - skb_unlink(skb, &chan->srej_q); - chan->buffer_seq = __next_seq(chan, chan->buffer_seq); - err = l2cap_reassemble_sdu(chan, skb, &bt_cb(skb)->control); - if (err) - break; - } +done: + clear_bit(CONN_LOCAL_BUSY, &chan->conn_state); + clear_bit(CONN_RNR_SENT, &chan->conn_state); - if (skb_queue_empty(&chan->srej_q)) { - chan->rx_state = L2CAP_RX_STATE_RECV; - l2cap_send_ack(chan); - } + BT_DBG("chan %p, Exit local busy", chan); +} - return err; +void l2cap_chan_busy(struct l2cap_chan *chan, int busy) +{ + if (chan->mode == L2CAP_MODE_ERTM) { + if (busy) + l2cap_ertm_enter_local_busy(chan); + else + l2cap_ertm_exit_local_busy(chan); + } } -static void l2cap_handle_srej(struct l2cap_chan *chan, - struct l2cap_ctrl *control) +static void l2cap_check_srej_gap(struct l2cap_chan *chan, u16 tx_seq) { struct sk_buff *skb; + u32 control; - BT_DBG("chan %p, control %p", chan, control); + while ((skb = skb_peek(&chan->srej_q)) && + !test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { + int err; - if (control->reqseq == chan->next_tx_seq) { - BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq); - l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); - return; - } + if (bt_cb(skb)->control.txseq != tx_seq) + break; - skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq); + skb = skb_dequeue(&chan->srej_q); + control = __set_ctrl_sar(chan, bt_cb(skb)->control.sar); + err = l2cap_reassemble_sdu(chan, skb, control); - if (skb == NULL) { - BT_DBG("Seq %d not available for retransmission", - control->reqseq); - return; - } + if (err < 0) { + l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); + break; + } - 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->conn, chan, ECONNRESET); - return; + chan->buffer_seq_srej = __next_seq(chan, chan->buffer_seq_srej); + tx_seq = __next_seq(chan, tx_seq); } +} - clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); - - if (control->poll) { - l2cap_pass_to_tx(chan, control); - - set_bit(CONN_SEND_FBIT, &chan->conn_state); - l2cap_retransmit(chan, control); - l2cap_ertm_send(chan); - - if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) { - set_bit(CONN_SREJ_ACT, &chan->conn_state); - chan->srej_save_reqseq = control->reqseq; - } - } else { - l2cap_pass_to_tx_fbit(chan, control); +static void l2cap_resend_srejframe(struct l2cap_chan *chan, u16 tx_seq) +{ + struct srej_list *l, *tmp; + u32 control; - if (control->final) { - if (chan->srej_save_reqseq != control->reqseq || - !test_and_clear_bit(CONN_SREJ_ACT, - &chan->conn_state)) - l2cap_retransmit(chan, control); - } else { - l2cap_retransmit(chan, control); - if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) { - set_bit(CONN_SREJ_ACT, &chan->conn_state); - chan->srej_save_reqseq = control->reqseq; - } + list_for_each_entry_safe(l, tmp, &chan->srej_l, list) { + if (l->tx_seq == tx_seq) { + list_del(&l->list); + kfree(l); + return; } + control = __set_ctrl_super(chan, L2CAP_SUPER_SREJ); + control |= __set_reqseq(chan, l->tx_seq); + l2cap_send_sframe(chan, control); + list_del(&l->list); + list_add_tail(&l->list, &chan->srej_l); } } -static void l2cap_handle_rej(struct l2cap_chan *chan, - struct l2cap_ctrl *control) +static int l2cap_send_srejframe(struct l2cap_chan *chan, u16 tx_seq) { - struct sk_buff *skb; + struct srej_list *new; + u32 control; - BT_DBG("chan %p, control %p", chan, control); + while (tx_seq != chan->expected_tx_seq) { + control = __set_ctrl_super(chan, L2CAP_SUPER_SREJ); + control |= __set_reqseq(chan, chan->expected_tx_seq); + l2cap_seq_list_append(&chan->srej_list, chan->expected_tx_seq); + l2cap_send_sframe(chan, control); - if (control->reqseq == chan->next_tx_seq) { - BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq); - l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); - return; - } + new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC); + if (!new) + return -ENOMEM; - skb = l2cap_ertm_seq_in_queue(&chan->tx_q, control->reqseq); + new->tx_seq = chan->expected_tx_seq; - 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->conn, chan, ECONNRESET); - return; - } + chan->expected_tx_seq = __next_seq(chan, chan->expected_tx_seq); - clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); + list_add_tail(&new->list, &chan->srej_l); + } - l2cap_pass_to_tx(chan, control); + chan->expected_tx_seq = __next_seq(chan, chan->expected_tx_seq); - if (control->final) { - if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state)) - l2cap_retransmit_all(chan, control); - } else { - l2cap_retransmit_all(chan, control); - l2cap_ertm_send(chan); - if (chan->tx_state == L2CAP_TX_STATE_WAIT_F) - set_bit(CONN_REJ_ACT, &chan->conn_state); - } + return 0; } -static u8 l2cap_classify_txseq(struct l2cap_chan *chan, u16 txseq) +static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u32 rx_control, struct sk_buff *skb) { - BT_DBG("chan %p, txseq %d", chan, txseq); + u16 tx_seq = __get_txseq(chan, rx_control); + u16 req_seq = __get_reqseq(chan, rx_control); + u8 sar = __get_ctrl_sar(chan, rx_control); + int tx_seq_offset, expected_tx_seq_offset; + int num_to_ack = (chan->tx_win/6) + 1; + int err = 0; - BT_DBG("last_acked_seq %d, expected_tx_seq %d", chan->last_acked_seq, - chan->expected_tx_seq); + BT_DBG("chan %p len %d tx_seq %d rx_control 0x%8.8x", chan, skb->len, + tx_seq, rx_control); - if (chan->rx_state == L2CAP_RX_STATE_SREJ_SENT) { - if (__seq_offset(chan, txseq, chan->last_acked_seq) >= - chan->tx_win) { - /* See notes below regarding "double poll" and - * invalid packets. - */ - if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) { - BT_DBG("Invalid/Ignore - after SREJ"); - return L2CAP_TXSEQ_INVALID_IGNORE; - } else { - BT_DBG("Invalid - in window after SREJ sent"); - return L2CAP_TXSEQ_INVALID; - } - } + if (__is_ctrl_final(chan, rx_control) && + test_bit(CONN_WAIT_F, &chan->conn_state)) { + __clear_monitor_timer(chan); + if (chan->unacked_frames > 0) + __set_retrans_timer(chan); + clear_bit(CONN_WAIT_F, &chan->conn_state); + } - if (chan->srej_list.head == txseq) { - BT_DBG("Expected SREJ"); - return L2CAP_TXSEQ_EXPECTED_SREJ; - } + chan->expected_ack_seq = req_seq; + l2cap_drop_acked_frames(chan); - if (l2cap_ertm_seq_in_queue(&chan->srej_q, txseq)) { - BT_DBG("Duplicate SREJ - txseq already stored"); - return L2CAP_TXSEQ_DUPLICATE_SREJ; - } + tx_seq_offset = __seq_offset(chan, tx_seq, chan->buffer_seq); - if (l2cap_seq_list_contains(&chan->srej_list, txseq)) { - BT_DBG("Unexpected SREJ - not requested"); - return L2CAP_TXSEQ_UNEXPECTED_SREJ; - } + /* invalid tx_seq */ + if (tx_seq_offset >= chan->tx_win) { + l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); + goto drop; } - if (chan->expected_tx_seq == txseq) { - if (__seq_offset(chan, txseq, chan->last_acked_seq) >= - chan->tx_win) { - BT_DBG("Invalid - txseq outside tx window"); - return L2CAP_TXSEQ_INVALID; - } else { - BT_DBG("Expected"); - return L2CAP_TXSEQ_EXPECTED; - } + if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { + if (!test_bit(CONN_RNR_SENT, &chan->conn_state)) + l2cap_send_ack(chan); + goto drop; } - if (__seq_offset(chan, txseq, chan->last_acked_seq) < - __seq_offset(chan, chan->expected_tx_seq, - chan->last_acked_seq)){ - BT_DBG("Duplicate - expected_tx_seq later than txseq"); - return L2CAP_TXSEQ_DUPLICATE; - } - - if (__seq_offset(chan, txseq, chan->last_acked_seq) >= chan->tx_win) { - /* A source of invalid packets is a "double poll" condition, - * where delays cause us to send multiple poll packets. If - * the remote stack receives and processes both polls, - * sequence numbers can wrap around in such a way that a - * resent frame has a sequence number that looks like new data - * with a sequence gap. This would trigger an erroneous SREJ - * request. - * - * Fortunately, this is impossible with a tx window that's - * less than half of the maximum sequence number, which allows - * invalid frames to be safely ignored. - * - * With tx window sizes greater than half of the tx window - * maximum, the frame is invalid and cannot be ignored. This - * causes a disconnect. - */ - - if (chan->tx_win <= ((chan->tx_win_max + 1) >> 1)) { - BT_DBG("Invalid/Ignore - txseq outside tx window"); - return L2CAP_TXSEQ_INVALID_IGNORE; - } else { - BT_DBG("Invalid - txseq outside tx window"); - return L2CAP_TXSEQ_INVALID; - } - } else { - BT_DBG("Unexpected - txseq indicates missing frames"); - return L2CAP_TXSEQ_UNEXPECTED; - } -} + if (tx_seq == chan->expected_tx_seq) + goto expected; -static int l2cap_rx_state_recv(struct l2cap_chan *chan, - struct l2cap_ctrl *control, - struct sk_buff *skb, u8 event) -{ - int err = 0; - bool skb_in_use = 0; + if (test_bit(CONN_SREJ_SENT, &chan->conn_state)) { + struct srej_list *first; - BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb, - event); + first = list_first_entry(&chan->srej_l, + struct srej_list, list); + if (tx_seq == first->tx_seq) { + l2cap_add_to_srej_queue(chan, skb, tx_seq, sar); + l2cap_check_srej_gap(chan, tx_seq); - switch (event) { - case L2CAP_EV_RECV_IFRAME: - switch (l2cap_classify_txseq(chan, control->txseq)) { - case L2CAP_TXSEQ_EXPECTED: - l2cap_pass_to_tx(chan, control); + list_del(&first->list); + kfree(first); - if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { - BT_DBG("Busy, discarding expected seq %d", - control->txseq); - break; + if (list_empty(&chan->srej_l)) { + chan->buffer_seq = chan->buffer_seq_srej; + clear_bit(CONN_SREJ_SENT, &chan->conn_state); + l2cap_send_ack(chan); + BT_DBG("chan %p, Exit SREJ_SENT", chan); } + } else { + struct srej_list *l; - chan->expected_tx_seq = __next_seq(chan, - control->txseq); - - chan->buffer_seq = chan->expected_tx_seq; - skb_in_use = 1; - - err = l2cap_reassemble_sdu(chan, skb, control); - if (err) - break; + /* duplicated tx_seq */ + if (l2cap_add_to_srej_queue(chan, skb, tx_seq, sar) < 0) + goto drop; - if (control->final) { - if (!test_and_clear_bit(CONN_REJ_ACT, - &chan->conn_state)) { - control->final = 0; - l2cap_retransmit_all(chan, control); - l2cap_ertm_send(chan); + list_for_each_entry(l, &chan->srej_l, list) { + if (l->tx_seq == tx_seq) { + l2cap_resend_srejframe(chan, tx_seq); + return 0; } } - if (!test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) - l2cap_send_ack(chan); - break; - case L2CAP_TXSEQ_UNEXPECTED: - l2cap_pass_to_tx(chan, control); - - /* Can't issue SREJ frames in the local busy state. - * Drop this frame, it will be seen as missing - * when local busy is exited. - */ - if (test_bit(CONN_LOCAL_BUSY, &chan->conn_state)) { - BT_DBG("Busy, discarding unexpected seq %d", - control->txseq); - break; + err = l2cap_send_srejframe(chan, tx_seq); + if (err < 0) { + l2cap_send_disconn_req(chan->conn, chan, -err); + return err; } + } + } else { + expected_tx_seq_offset = __seq_offset(chan, + chan->expected_tx_seq, chan->buffer_seq); - /* There was a gap in the sequence, so an SREJ - * must be sent for each missing frame. The - * current frame is stored for later use. - */ - skb_queue_tail(&chan->srej_q, skb); - skb_in_use = 1; - BT_DBG("Queued %p (queue len %d)", skb, - skb_queue_len(&chan->srej_q)); + /* duplicated tx_seq */ + if (tx_seq_offset < expected_tx_seq_offset) + goto drop; - clear_bit(CONN_SREJ_ACT, &chan->conn_state); - l2cap_seq_list_clear(&chan->srej_list); - l2cap_send_srej(chan, control->txseq); + set_bit(CONN_SREJ_SENT, &chan->conn_state); - chan->rx_state = L2CAP_RX_STATE_SREJ_SENT; - break; - case L2CAP_TXSEQ_DUPLICATE: - l2cap_pass_to_tx(chan, control); - break; - case L2CAP_TXSEQ_INVALID_IGNORE: - break; - case L2CAP_TXSEQ_INVALID: - default: - l2cap_send_disconn_req(chan->conn, chan, - ECONNRESET); - break; - } - break; - case L2CAP_EV_RECV_RR: - l2cap_pass_to_tx(chan, control); - if (control->final) { - clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); + BT_DBG("chan %p, Enter SREJ", chan); - if (!test_and_clear_bit(CONN_REJ_ACT, - &chan->conn_state)) { - control->final = 0; - l2cap_retransmit_all(chan, control); - } + INIT_LIST_HEAD(&chan->srej_l); + chan->buffer_seq_srej = chan->buffer_seq; - l2cap_ertm_send(chan); - } else if (control->poll) { - l2cap_send_i_or_rr_or_rnr(chan); - } else { - if (test_and_clear_bit(CONN_REMOTE_BUSY, - &chan->conn_state) && - chan->unacked_frames) - __set_retrans_timer(chan); + __skb_queue_head_init(&chan->srej_q); + l2cap_add_to_srej_queue(chan, skb, tx_seq, sar); - l2cap_ertm_send(chan); - } - break; - case L2CAP_EV_RECV_RNR: - set_bit(CONN_REMOTE_BUSY, &chan->conn_state); - l2cap_pass_to_tx(chan, control); - if (control && control->poll) { - set_bit(CONN_SEND_FBIT, &chan->conn_state); - l2cap_send_rr_or_rnr(chan, 0); + /* Set P-bit only if there are some I-frames to ack. */ + if (__clear_ack_timer(chan)) + set_bit(CONN_SEND_PBIT, &chan->conn_state); + + err = l2cap_send_srejframe(chan, tx_seq); + if (err < 0) { + l2cap_send_disconn_req(chan->conn, chan, -err); + return err; } - __clear_retrans_timer(chan); - l2cap_seq_list_clear(&chan->retrans_list); - break; - case L2CAP_EV_RECV_REJ: - l2cap_handle_rej(chan, control); - break; - case L2CAP_EV_RECV_SREJ: - l2cap_handle_srej(chan, control); - break; - default: - break; } + return 0; - if (skb && !skb_in_use) { - BT_DBG("Freeing %p", skb); - kfree_skb(skb); +expected: + chan->expected_tx_seq = __next_seq(chan, chan->expected_tx_seq); + + if (test_bit(CONN_SREJ_SENT, &chan->conn_state)) { + bt_cb(skb)->control.txseq = tx_seq; + bt_cb(skb)->control.sar = sar; + __skb_queue_tail(&chan->srej_q, skb); + return 0; } - return err; -} + err = l2cap_reassemble_sdu(chan, skb, rx_control); + chan->buffer_seq = __next_seq(chan, chan->buffer_seq); -static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan, - struct l2cap_ctrl *control, - struct sk_buff *skb, u8 event) -{ - int err = 0; - u16 txseq = control->txseq; - bool skb_in_use = 0; - - BT_DBG("chan %p, control %p, skb %p, event %d", chan, control, skb, - event); - - switch (event) { - case L2CAP_EV_RECV_IFRAME: - switch (l2cap_classify_txseq(chan, txseq)) { - case L2CAP_TXSEQ_EXPECTED: - /* Keep frame for reassembly later */ - l2cap_pass_to_tx(chan, control); - skb_queue_tail(&chan->srej_q, skb); - skb_in_use = 1; - BT_DBG("Queued %p (queue len %d)", skb, - skb_queue_len(&chan->srej_q)); - - chan->expected_tx_seq = __next_seq(chan, txseq); - break; - case L2CAP_TXSEQ_EXPECTED_SREJ: - l2cap_seq_list_pop(&chan->srej_list); + if (err < 0) { + l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); + return err; + } - l2cap_pass_to_tx(chan, control); - skb_queue_tail(&chan->srej_q, skb); - skb_in_use = 1; - BT_DBG("Queued %p (queue len %d)", skb, - skb_queue_len(&chan->srej_q)); + if (__is_ctrl_final(chan, rx_control)) { + if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state)) + l2cap_retransmit_frames(chan); + } - err = l2cap_rx_queued_iframes(chan); - if (err) - break; - break; - case L2CAP_TXSEQ_UNEXPECTED: - /* Got a frame that can't be reassembled yet. - * Save it for later, and send SREJs to cover - * the missing frames. - */ - skb_queue_tail(&chan->srej_q, skb); - skb_in_use = 1; - BT_DBG("Queued %p (queue len %d)", skb, - skb_queue_len(&chan->srej_q)); - - l2cap_pass_to_tx(chan, control); - l2cap_send_srej(chan, control->txseq); - break; - case L2CAP_TXSEQ_UNEXPECTED_SREJ: - /* This frame was requested with an SREJ, but - * some expected retransmitted frames are - * missing. Request retransmission of missing - * SREJ'd frames. - */ - skb_queue_tail(&chan->srej_q, skb); - skb_in_use = 1; - BT_DBG("Queued %p (queue len %d)", skb, - skb_queue_len(&chan->srej_q)); - - l2cap_pass_to_tx(chan, control); - l2cap_send_srej_list(chan, control->txseq); - break; - case L2CAP_TXSEQ_DUPLICATE_SREJ: - /* We've already queued this frame. Drop this copy. */ - l2cap_pass_to_tx(chan, control); - break; - case L2CAP_TXSEQ_DUPLICATE: - /* Expecting a later sequence number, so this frame - * was already received. Ignore it completely. - */ - break; - case L2CAP_TXSEQ_INVALID_IGNORE: - break; - case L2CAP_TXSEQ_INVALID: - default: - l2cap_send_disconn_req(chan->conn, chan, - ECONNRESET); - break; - } - break; - case L2CAP_EV_RECV_RR: - l2cap_pass_to_tx(chan, control); - if (control->final) { - clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); + chan->num_acked = (chan->num_acked + 1) % num_to_ack; + if (chan->num_acked == num_to_ack - 1) + l2cap_send_ack(chan); + else + __set_ack_timer(chan); - if (!test_and_clear_bit(CONN_REJ_ACT, - &chan->conn_state)) { - control->final = 0; - l2cap_retransmit_all(chan, control); - } + return 0; - l2cap_ertm_send(chan); - } else if (control->poll) { - if (test_and_clear_bit(CONN_REMOTE_BUSY, - &chan->conn_state) && - chan->unacked_frames) { - __set_retrans_timer(chan); - } +drop: + kfree_skb(skb); + return 0; +} - set_bit(CONN_SEND_FBIT, &chan->conn_state); - l2cap_send_srej_tail(chan); - } else { - if (test_and_clear_bit(CONN_REMOTE_BUSY, - &chan->conn_state) && - chan->unacked_frames) +static inline void l2cap_data_channel_rrframe(struct l2cap_chan *chan, u32 rx_control) +{ + BT_DBG("chan %p, req_seq %d ctrl 0x%8.8x", chan, + __get_reqseq(chan, rx_control), rx_control); + + chan->expected_ack_seq = __get_reqseq(chan, rx_control); + l2cap_drop_acked_frames(chan); + + if (__is_ctrl_poll(chan, rx_control)) { + set_bit(CONN_SEND_FBIT, &chan->conn_state); + if (test_bit(CONN_SREJ_SENT, &chan->conn_state)) { + if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state) && + (chan->unacked_frames > 0)) __set_retrans_timer(chan); - l2cap_send_ack(chan); - } - break; - case L2CAP_EV_RECV_RNR: - set_bit(CONN_REMOTE_BUSY, &chan->conn_state); - l2cap_pass_to_tx(chan, control); - if (control->poll) { - l2cap_send_srej_tail(chan); + clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); + l2cap_send_srejtail(chan); } else { - struct l2cap_ctrl rr_control; - memset(&rr_control, 0, sizeof(rr_control)); - rr_control.sframe = 1; - rr_control.super = L2CAP_SUPER_RR; - rr_control.reqseq = chan->buffer_seq; - l2cap_send_sframe(chan, &rr_control); + l2cap_send_i_or_rr_or_rnr(chan); } - break; - case L2CAP_EV_RECV_REJ: - l2cap_handle_rej(chan, control); - break; - case L2CAP_EV_RECV_SREJ: - l2cap_handle_srej(chan, control); - break; - } + } else if (__is_ctrl_final(chan, rx_control)) { + clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); - if (skb && !skb_in_use) { - BT_DBG("Freeing %p", skb); - kfree_skb(skb); - } + if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state)) + l2cap_retransmit_frames(chan); - return err; + } else { + if (test_bit(CONN_REMOTE_BUSY, &chan->conn_state) && + (chan->unacked_frames > 0)) + __set_retrans_timer(chan); + + clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); + if (test_bit(CONN_SREJ_SENT, &chan->conn_state)) + l2cap_send_ack(chan); + else + l2cap_ertm_send(chan); + } } -static bool __valid_reqseq(struct l2cap_chan *chan, u16 reqseq) +static inline void l2cap_data_channel_rejframe(struct l2cap_chan *chan, u32 rx_control) { - /* Make sure reqseq is for a packet that has been sent but not acked */ - u16 unacked; + u16 tx_seq = __get_reqseq(chan, rx_control); - unacked = __seq_offset(chan, chan->next_tx_seq, chan->expected_ack_seq); - return __seq_offset(chan, chan->next_tx_seq, reqseq) <= unacked; -} + BT_DBG("chan %p, req_seq %d ctrl 0x%8.8x", chan, tx_seq, rx_control); + + clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); + + chan->expected_ack_seq = tx_seq; + l2cap_drop_acked_frames(chan); -static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control, - struct sk_buff *skb, u8 event) + if (__is_ctrl_final(chan, rx_control)) { + if (!test_and_clear_bit(CONN_REJ_ACT, &chan->conn_state)) + l2cap_retransmit_frames(chan); + } else { + l2cap_retransmit_frames(chan); + + if (test_bit(CONN_WAIT_F, &chan->conn_state)) + set_bit(CONN_REJ_ACT, &chan->conn_state); + } +} +static inline void l2cap_data_channel_srejframe(struct l2cap_chan *chan, u32 rx_control) { - int err = 0; + u16 tx_seq = __get_reqseq(chan, rx_control); - BT_DBG("chan %p, control %p, skb %p, event %d, state %d", chan, - control, skb, event, chan->rx_state); + BT_DBG("chan %p, req_seq %d ctrl 0x%8.8x", chan, tx_seq, rx_control); - if (__valid_reqseq(chan, control->reqseq)) { - switch (chan->rx_state) { - case L2CAP_RX_STATE_RECV: - err = l2cap_rx_state_recv(chan, control, skb, event); - break; - case L2CAP_RX_STATE_SREJ_SENT: - err = l2cap_rx_state_srej_sent(chan, control, skb, - event); - break; - default: - /* shut it down */ - break; + clear_bit(CONN_REMOTE_BUSY, &chan->conn_state); + + if (__is_ctrl_poll(chan, rx_control)) { + chan->expected_ack_seq = tx_seq; + l2cap_drop_acked_frames(chan); + + set_bit(CONN_SEND_FBIT, &chan->conn_state); + l2cap_retransmit_one_frame(chan, tx_seq); + + l2cap_ertm_send(chan); + + if (test_bit(CONN_WAIT_F, &chan->conn_state)) { + chan->srej_save_reqseq = tx_seq; + set_bit(CONN_SREJ_ACT, &chan->conn_state); } + } else if (__is_ctrl_final(chan, rx_control)) { + if (test_bit(CONN_SREJ_ACT, &chan->conn_state) && + chan->srej_save_reqseq == tx_seq) + clear_bit(CONN_SREJ_ACT, &chan->conn_state); + else + l2cap_retransmit_one_frame(chan, tx_seq); } else { - 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->conn, chan, ECONNRESET); + l2cap_retransmit_one_frame(chan, tx_seq); + if (test_bit(CONN_WAIT_F, &chan->conn_state)) { + chan->srej_save_reqseq = tx_seq; + set_bit(CONN_SREJ_ACT, &chan->conn_state); + } } - - return err; } -static int l2cap_stream_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control, - struct sk_buff *skb) +static inline void l2cap_data_channel_rnrframe(struct l2cap_chan *chan, u32 rx_control) { - int err = 0; + u16 tx_seq = __get_reqseq(chan, rx_control); - BT_DBG("chan %p, control %p, skb %p, state %d", chan, control, skb, - chan->rx_state); + BT_DBG("chan %p, req_seq %d ctrl 0x%8.8x", chan, tx_seq, rx_control); - if (l2cap_classify_txseq(chan, control->txseq) == - L2CAP_TXSEQ_EXPECTED) { - l2cap_pass_to_tx(chan, control); + set_bit(CONN_REMOTE_BUSY, &chan->conn_state); + chan->expected_ack_seq = tx_seq; + l2cap_drop_acked_frames(chan); - BT_DBG("buffer_seq %d->%d", chan->buffer_seq, - __next_seq(chan, chan->buffer_seq)); + if (__is_ctrl_poll(chan, rx_control)) + set_bit(CONN_SEND_FBIT, &chan->conn_state); - chan->buffer_seq = __next_seq(chan, chan->buffer_seq); + if (!test_bit(CONN_SREJ_SENT, &chan->conn_state)) { + __clear_retrans_timer(chan); + if (__is_ctrl_poll(chan, rx_control)) + l2cap_send_rr_or_rnr(chan, L2CAP_CTRL_FINAL); + return; + } - l2cap_reassemble_sdu(chan, skb, control); + if (__is_ctrl_poll(chan, rx_control)) { + l2cap_send_srejtail(chan); } else { - if (chan->sdu) { - kfree_skb(chan->sdu); - chan->sdu = NULL; - } - chan->sdu_last_frag = NULL; - chan->sdu_len = 0; + rx_control = __set_ctrl_super(chan, L2CAP_SUPER_RR); + l2cap_send_sframe(chan, rx_control); + } +} - if (skb) { - BT_DBG("Freeing %p", skb); - kfree_skb(skb); - } +static inline int l2cap_data_channel_sframe(struct l2cap_chan *chan, u32 rx_control, struct sk_buff *skb) +{ + BT_DBG("chan %p rx_control 0x%8.8x len %d", chan, rx_control, skb->len); + + if (__is_ctrl_final(chan, rx_control) && + test_bit(CONN_WAIT_F, &chan->conn_state)) { + __clear_monitor_timer(chan); + if (chan->unacked_frames > 0) + __set_retrans_timer(chan); + clear_bit(CONN_WAIT_F, &chan->conn_state); } - chan->last_acked_seq = control->txseq; - chan->expected_tx_seq = __next_seq(chan, control->txseq); + switch (__get_ctrl_super(chan, rx_control)) { + case L2CAP_SUPER_RR: + l2cap_data_channel_rrframe(chan, rx_control); + break; - return err; + case L2CAP_SUPER_REJ: + l2cap_data_channel_rejframe(chan, rx_control); + break; + + case L2CAP_SUPER_SREJ: + l2cap_data_channel_srejframe(chan, rx_control); + break; + + case L2CAP_SUPER_RNR: + l2cap_data_channel_rnrframe(chan, rx_control); + break; + } + + kfree_skb(skb); + return 0; } -static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb) +static int l2cap_ertm_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb) { - struct l2cap_ctrl *control = &bt_cb(skb)->control; - u16 len; - u8 event; + u32 control; + u16 req_seq; + int len, next_tx_seq_offset, req_seq_offset; __unpack_control(chan, skb); + control = __get_control(chan, skb->data); + skb_pull(skb, __ctrl_size(chan)); len = skb->len; /* * We can just drop the corrupted I-frame here. * Receiver will miss it and start proper recovery - * procedures and ask for retransmission. + * procedures and ask retransmission. */ if (l2cap_check_fcs(chan, skb)) goto drop; - if (!control->sframe && control->sar == L2CAP_SAR_START) + if (__is_sar_start(chan, control) && !__is_sframe(chan, control)) len -= L2CAP_SDULEN_SIZE; if (chan->fcs == L2CAP_FCS_CRC16) @@ -5071,57 +4578,34 @@ static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb) goto drop; } - if (!control->sframe) { - int err; - - BT_DBG("iframe sar %d, reqseq %d, final %d, txseq %d", - control->sar, control->reqseq, control->final, - control->txseq); + req_seq = __get_reqseq(chan, control); - /* Validate F-bit - F=0 always valid, F=1 only - * valid in TX WAIT_F - */ - if (control->final && chan->tx_state != L2CAP_TX_STATE_WAIT_F) - goto drop; + req_seq_offset = __seq_offset(chan, req_seq, chan->expected_ack_seq); - if (chan->mode != L2CAP_MODE_STREAMING) { - event = L2CAP_EV_RECV_IFRAME; - err = l2cap_rx(chan, control, skb, event); - } else { - err = l2cap_stream_rx(chan, control, skb); - } + next_tx_seq_offset = __seq_offset(chan, chan->next_tx_seq, + chan->expected_ack_seq); - if (err) - l2cap_send_disconn_req(chan->conn, chan, - ECONNRESET); - } else { - const u8 rx_func_to_event[4] = { - L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ, - L2CAP_EV_RECV_RNR, L2CAP_EV_RECV_SREJ - }; + /* check for invalid req-seq */ + if (req_seq_offset > next_tx_seq_offset) { + l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); + goto drop; + } - /* Only I-frames are expected in streaming mode */ - if (chan->mode == L2CAP_MODE_STREAMING) + if (!__is_sframe(chan, control)) { + if (len < 0) { + l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); goto drop; + } - BT_DBG("sframe reqseq %d, final %d, poll %d, super %d", - control->reqseq, control->final, control->poll, - control->super); - + l2cap_data_channel_iframe(chan, control, skb); + } else { if (len != 0) { BT_ERR("%d", len); l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); goto drop; } - /* Validate F and P bits */ - if (control->final && (control->poll || - chan->tx_state != L2CAP_TX_STATE_WAIT_F)) - goto drop; - - event = rx_func_to_event[control->super]; - if (l2cap_rx(chan, control, skb, event)) - l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); + l2cap_data_channel_sframe(chan, control, skb); } return 0; @@ -5131,27 +4615,19 @@ static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb) return 0; } -static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid, - struct sk_buff *skb) +static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk_buff *skb) { struct l2cap_chan *chan; + u32 control; + u16 tx_seq; + int len; chan = l2cap_get_chan_by_scid(conn, cid); if (!chan) { - if (cid == L2CAP_CID_A2MP) { - chan = a2mp_channel_create(conn, skb); - if (!chan) { - kfree_skb(skb); - return; - } - - l2cap_chan_lock(chan); - } else { - BT_DBG("unknown cid 0x%4.4x", cid); - /* Drop packet and return */ - kfree_skb(skb); - return; - } + BT_DBG("unknown cid 0x%4.4x", cid); + /* Drop packet and return */ + kfree_skb(skb); + return 0; } BT_DBG("chan %p, len %d", chan, skb->len); @@ -5169,13 +4645,49 @@ static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid, if (chan->imtu < skb->len) goto drop; - if (!chan->ops->recv(chan, skb)) + if (!chan->ops->recv(chan->data, skb)) goto done; break; case L2CAP_MODE_ERTM: + l2cap_ertm_data_rcv(chan, skb); + + goto done; + case L2CAP_MODE_STREAMING: - l2cap_data_rcv(chan, skb); + control = __get_control(chan, skb->data); + skb_pull(skb, __ctrl_size(chan)); + len = skb->len; + + if (l2cap_check_fcs(chan, skb)) + goto drop; + + if (__is_sar_start(chan, control)) + len -= L2CAP_SDULEN_SIZE; + + if (chan->fcs == L2CAP_FCS_CRC16) + len -= L2CAP_FCS_SIZE; + + if (len > chan->mps || len < 0 || __is_sframe(chan, control)) + goto drop; + + tx_seq = __get_txseq(chan, control); + + if (chan->expected_tx_seq != tx_seq) { + /* Frame(s) missing - must discard partial SDU */ + kfree_skb(chan->sdu); + chan->sdu = NULL; + chan->sdu_last_frag = NULL; + chan->sdu_len = 0; + + /* TODO: Notify userland of missing data */ + } + + chan->expected_tx_seq = __next_seq(chan, tx_seq); + + if (l2cap_reassemble_sdu(chan, skb, control) == -EMSGSIZE) + l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); + goto done; default: @@ -5188,10 +4700,11 @@ static void l2cap_data_channel(struct l2cap_conn *conn, u16 cid, done: l2cap_chan_unlock(chan); + + return 0; } -static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, - struct sk_buff *skb) +static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb) { struct l2cap_chan *chan; @@ -5207,15 +4720,17 @@ static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, if (chan->imtu < skb->len) goto drop; - if (!chan->ops->recv(chan, skb)) - return; + if (!chan->ops->recv(chan->data, skb)) + return 0; drop: kfree_skb(skb); + + return 0; } -static void l2cap_att_channel(struct l2cap_conn *conn, u16 cid, - struct sk_buff *skb) +static inline int l2cap_att_channel(struct l2cap_conn *conn, u16 cid, + struct sk_buff *skb) { struct l2cap_chan *chan; @@ -5231,11 +4746,13 @@ static void l2cap_att_channel(struct l2cap_conn *conn, u16 cid, if (chan->imtu < skb->len) goto drop; - if (!chan->ops->recv(chan, skb)) - return; + if (!chan->ops->recv(chan->data, skb)) + return 0; drop: kfree_skb(skb); + + return 0; } static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) @@ -5263,7 +4780,7 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) case L2CAP_CID_CONN_LESS: psm = get_unaligned((__le16 *) skb->data); - skb_pull(skb, L2CAP_PSMLEN_SIZE); + skb_pull(skb, 2); l2cap_conless_channel(conn, psm, skb); break; @@ -5457,17 +4974,6 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) rsp.status = cpu_to_le16(stat); l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, sizeof(rsp), &rsp); - - if (!test_bit(CONF_REQ_SENT, &chan->conf_state) && - res == L2CAP_CR_SUCCESS) { - char buf[128]; - set_bit(CONF_REQ_SENT, &chan->conf_state); - l2cap_send_cmd(conn, l2cap_get_ident(conn), - L2CAP_CONF_REQ, - l2cap_build_conf_req(chan, buf), - buf); - chan->num_conf_req++; - } } l2cap_chan_unlock(chan); diff --git a/trunk/net/bluetooth/l2cap_sock.c b/trunk/net/bluetooth/l2cap_sock.c index a4bb27e8427e..3bb1611b9d48 100644 --- a/trunk/net/bluetooth/l2cap_sock.c +++ b/trunk/net/bluetooth/l2cap_sock.c @@ -27,6 +27,7 @@ /* Bluetooth L2CAP sockets. */ +#include #include #include @@ -88,8 +89,8 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) if (err < 0) goto done; - if (__le16_to_cpu(la.l2_psm) == L2CAP_PSM_SDP || - __le16_to_cpu(la.l2_psm) == L2CAP_PSM_RFCOMM) + if (__le16_to_cpu(la.l2_psm) == 0x0001 || + __le16_to_cpu(la.l2_psm) == 0x0003) chan->sec_level = BT_SECURITY_SDP; bacpy(&bt_sk(sk)->src, &la.l2_bdaddr); @@ -445,22 +446,6 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, ch return err; } -static bool l2cap_valid_mtu(struct l2cap_chan *chan, u16 mtu) -{ - switch (chan->scid) { - case L2CAP_CID_LE_DATA: - if (mtu < L2CAP_LE_MIN_MTU) - return false; - break; - - default: - if (mtu < L2CAP_DEFAULT_MIN_MTU) - return false; - } - - return true; -} - static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen) { struct sock *sk = sock->sk; @@ -499,11 +484,6 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us break; } - if (!l2cap_valid_mtu(chan, opts.imtu)) { - err = -EINVAL; - break; - } - chan->mode = opts.mode; switch (chan->mode) { case L2CAP_MODE_BASIC: @@ -893,34 +873,9 @@ static int l2cap_sock_release(struct socket *sock) return err; } -static void l2cap_sock_cleanup_listen(struct sock *parent) +static struct l2cap_chan *l2cap_sock_new_connection_cb(void *data) { - struct sock *sk; - - BT_DBG("parent %p", parent); - - /* Close not yet accepted channels */ - while ((sk = bt_accept_dequeue(parent, NULL))) { - struct l2cap_chan *chan = l2cap_pi(sk)->chan; - - l2cap_chan_lock(chan); - __clear_chan_timer(chan); - l2cap_chan_close(chan, ECONNRESET); - l2cap_chan_unlock(chan); - - l2cap_sock_kill(sk); - } -} - -static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan) -{ - struct sock *sk, *parent = chan->data; - - /* Check for backlog size */ - if (sk_acceptq_is_full(parent)) { - BT_DBG("backlog full %d", parent->sk_ack_backlog); - return NULL; - } + struct sock *sk, *parent = data; sk = l2cap_sock_alloc(sock_net(parent), NULL, BTPROTO_L2CAP, GFP_ATOMIC); @@ -934,10 +889,10 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan) return l2cap_pi(sk)->chan; } -static int l2cap_sock_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) +static int l2cap_sock_recv_cb(void *data, struct sk_buff *skb) { int err; - struct sock *sk = chan->data; + struct sock *sk = data; struct l2cap_pinfo *pi = l2cap_pi(sk); lock_sock(sk); @@ -970,57 +925,16 @@ static int l2cap_sock_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) return err; } -static void l2cap_sock_close_cb(struct l2cap_chan *chan) +static void l2cap_sock_close_cb(void *data) { - struct sock *sk = chan->data; + struct sock *sk = data; l2cap_sock_kill(sk); } -static void l2cap_sock_teardown_cb(struct l2cap_chan *chan, int err) +static void l2cap_sock_state_change_cb(void *data, int state) { - struct sock *sk = chan->data; - struct sock *parent; - - lock_sock(sk); - - parent = bt_sk(sk)->parent; - - sock_set_flag(sk, SOCK_ZAPPED); - - switch (chan->state) { - case BT_OPEN: - case BT_BOUND: - case BT_CLOSED: - break; - case BT_LISTEN: - l2cap_sock_cleanup_listen(sk); - sk->sk_state = BT_CLOSED; - chan->state = BT_CLOSED; - - break; - default: - sk->sk_state = BT_CLOSED; - chan->state = BT_CLOSED; - - sk->sk_err = err; - - if (parent) { - bt_accept_unlink(sk); - parent->sk_data_ready(parent, 0); - } else { - sk->sk_state_change(sk); - } - - break; - } - - release_sock(sk); -} - -static void l2cap_sock_state_change_cb(struct l2cap_chan *chan, int state) -{ - struct sock *sk = chan->data; + struct sock *sk = data; sk->sk_state = state; } @@ -1041,34 +955,12 @@ static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan, return skb; } -static void l2cap_sock_ready_cb(struct l2cap_chan *chan) -{ - struct sock *sk = chan->data; - struct sock *parent; - - lock_sock(sk); - - parent = bt_sk(sk)->parent; - - BT_DBG("sk %p, parent %p", sk, parent); - - sk->sk_state = BT_CONNECTED; - sk->sk_state_change(sk); - - if (parent) - parent->sk_data_ready(parent, 0); - - release_sock(sk); -} - static struct l2cap_ops l2cap_chan_ops = { .name = "L2CAP Socket Interface", .new_connection = l2cap_sock_new_connection_cb, .recv = l2cap_sock_recv_cb, .close = l2cap_sock_close_cb, - .teardown = l2cap_sock_teardown_cb, .state_change = l2cap_sock_state_change_cb, - .ready = l2cap_sock_ready_cb, .alloc_skb = l2cap_sock_alloc_skb_cb, }; diff --git a/trunk/net/bluetooth/lib.c b/trunk/net/bluetooth/lib.c index e1c97527e16c..506628876f36 100644 --- a/trunk/net/bluetooth/lib.c +++ b/trunk/net/bluetooth/lib.c @@ -26,7 +26,12 @@ #define pr_fmt(fmt) "Bluetooth: " fmt -#include +#include + +#include +#include +#include +#include #include diff --git a/trunk/net/bluetooth/mgmt.c b/trunk/net/bluetooth/mgmt.c index a6e0f3d8da6c..25d220776079 100644 --- a/trunk/net/bluetooth/mgmt.c +++ b/trunk/net/bluetooth/mgmt.c @@ -24,6 +24,8 @@ /* Bluetooth HCI Management interface */ +#include +#include #include #include @@ -712,8 +714,7 @@ static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, } static void mgmt_pending_foreach(u16 opcode, struct hci_dev *hdev, - void (*cb)(struct pending_cmd *cmd, - void *data), + void (*cb)(struct pending_cmd *cmd, void *data), void *data) { struct list_head *p, *n; @@ -870,7 +871,7 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data, } if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev) || - mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) { + mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) { err = cmd_status(sk, hdev->id, MGMT_OP_SET_DISCOVERABLE, MGMT_STATUS_BUSY); goto failed; @@ -977,7 +978,7 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data, } if (mgmt_pending_find(MGMT_OP_SET_DISCOVERABLE, hdev) || - mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) { + mgmt_pending_find(MGMT_OP_SET_CONNECTABLE, hdev)) { err = cmd_status(sk, hdev->id, MGMT_OP_SET_CONNECTABLE, MGMT_STATUS_BUSY); goto failed; @@ -1000,7 +1001,7 @@ static int set_connectable(struct sock *sk, struct hci_dev *hdev, void *data, scan = 0; if (test_bit(HCI_ISCAN, &hdev->flags) && - hdev->discov_timeout > 0) + hdev->discov_timeout > 0) cancel_delayed_work(&hdev->discov_off); } @@ -1055,7 +1056,7 @@ static int set_link_security(struct sock *sk, struct hci_dev *hdev, void *data, bool changed = false; if (!!cp->val != test_bit(HCI_LINK_SECURITY, - &hdev->dev_flags)) { + &hdev->dev_flags)) { change_bit(HCI_LINK_SECURITY, &hdev->dev_flags); changed = true; } @@ -1316,7 +1317,7 @@ static bool enable_service_cache(struct hci_dev *hdev) } static int remove_uuid(struct sock *sk, struct hci_dev *hdev, void *data, - u16 len) + u16 len) { struct mgmt_cp_remove_uuid *cp = data; struct pending_cmd *cmd; @@ -1441,7 +1442,7 @@ static int set_dev_class(struct sock *sk, struct hci_dev *hdev, void *data, } static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data, - u16 len) + u16 len) { struct mgmt_cp_load_link_keys *cp = data; u16 key_count, expected_len; @@ -1453,13 +1454,13 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data, sizeof(struct mgmt_link_key_info); if (expected_len != len) { BT_ERR("load_link_keys: expected %u bytes, got %u bytes", - len, expected_len); + len, expected_len); return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LINK_KEYS, MGMT_STATUS_INVALID_PARAMS); } BT_DBG("%s debug_keys %u key_count %u", hdev->name, cp->debug_keys, - key_count); + key_count); hci_dev_lock(hdev); @@ -1534,10 +1535,10 @@ static int unpair_device(struct sock *sk, struct hci_dev *hdev, void *data, if (cp->disconnect) { if (cp->addr.type == BDADDR_BREDR) conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, - &cp->addr.bdaddr); + &cp->addr.bdaddr); else conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, - &cp->addr.bdaddr); + &cp->addr.bdaddr); } else { conn = NULL; } @@ -1593,12 +1594,11 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data, } if (cp->addr.type == BDADDR_BREDR) - conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, - &cp->addr.bdaddr); + conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->addr.bdaddr); else conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->addr.bdaddr); - if (!conn || conn->state == BT_OPEN || conn->state == BT_CLOSED) { + if (!conn) { err = cmd_status(sk, hdev->id, MGMT_OP_DISCONNECT, MGMT_STATUS_NOT_CONNECTED); goto failed; @@ -1813,7 +1813,7 @@ static int set_io_capability(struct sock *sk, struct hci_dev *hdev, void *data, hdev->io_capability = cp->io_capability; BT_DBG("%s IO capability set to 0x%02x", hdev->name, - hdev->io_capability); + hdev->io_capability); hci_dev_unlock(hdev); @@ -1821,7 +1821,7 @@ static int set_io_capability(struct sock *sk, struct hci_dev *hdev, void *data, 0); } -static struct pending_cmd *find_pairing(struct hci_conn *conn) +static inline struct pending_cmd *find_pairing(struct hci_conn *conn) { struct hci_dev *hdev = conn->hdev; struct pending_cmd *cmd; @@ -1873,22 +1873,6 @@ static void pairing_complete_cb(struct hci_conn *conn, u8 status) pairing_complete(cmd, mgmt_status(status)); } -static void le_connect_complete_cb(struct hci_conn *conn, u8 status) -{ - struct pending_cmd *cmd; - - BT_DBG("status %u", status); - - if (!status) - return; - - cmd = find_pairing(conn); - if (!cmd) - BT_DBG("Unable to find a pending command"); - else - pairing_complete(cmd, mgmt_status(status)); -} - static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) { @@ -1927,15 +1911,8 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data, rp.addr.type = cp->addr.type; if (IS_ERR(conn)) { - int status; - - if (PTR_ERR(conn) == -EBUSY) - status = MGMT_STATUS_BUSY; - else - status = MGMT_STATUS_CONNECT_FAILED; - err = cmd_complete(sk, hdev->id, MGMT_OP_PAIR_DEVICE, - status, &rp, + MGMT_STATUS_CONNECT_FAILED, &rp, sizeof(rp)); goto unlock; } @@ -1957,8 +1934,6 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data, /* For LE, just connecting isn't a proof that the pairing finished */ if (cp->addr.type == BDADDR_BREDR) conn->connect_cfm_cb = pairing_complete_cb; - else - conn->connect_cfm_cb = le_connect_complete_cb; conn->security_cfm_cb = pairing_complete_cb; conn->disconn_cfm_cb = pairing_complete_cb; @@ -1966,7 +1941,7 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data, cmd->user_data = conn; if (conn->state == BT_CONNECTED && - hci_conn_security(conn, sec_level, auth_type)) + hci_conn_security(conn, sec_level, auth_type)) pairing_complete(cmd, 0); err = 0; @@ -2263,7 +2238,7 @@ static int add_remote_oob_data(struct sock *sk, struct hci_dev *hdev, } static int remove_remote_oob_data(struct sock *sk, struct hci_dev *hdev, - void *data, u16 len) + void *data, u16 len) { struct mgmt_cp_remove_remote_oob_data *cp = data; u8 status; @@ -2432,7 +2407,7 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data, case DISCOVERY_RESOLVING: e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, - NAME_PENDING); + NAME_PENDING); if (!e) { mgmt_pending_remove(cmd); err = cmd_complete(sk, hdev->id, @@ -2654,7 +2629,7 @@ static int load_long_term_keys(struct sock *sk, struct hci_dev *hdev, sizeof(struct mgmt_ltk_info); if (expected_len != len) { BT_ERR("load_keys: expected %u bytes, got %u bytes", - len, expected_len); + len, expected_len); return cmd_status(sk, hdev->id, MGMT_OP_LOAD_LONG_TERM_KEYS, EINVAL); } @@ -2779,7 +2754,7 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) } if (opcode >= ARRAY_SIZE(mgmt_handlers) || - mgmt_handlers[opcode].func == NULL) { + mgmt_handlers[opcode].func == NULL) { BT_DBG("Unknown op %u", opcode); err = cmd_status(sk, index, opcode, MGMT_STATUS_UNKNOWN_COMMAND); @@ -2787,7 +2762,7 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) } if ((hdev && opcode < MGMT_OP_READ_INFO) || - (!hdev && opcode >= MGMT_OP_READ_INFO)) { + (!hdev && opcode >= MGMT_OP_READ_INFO)) { err = cmd_status(sk, index, opcode, MGMT_STATUS_INVALID_INDEX); goto done; @@ -2796,7 +2771,7 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen) handler = &mgmt_handlers[opcode]; if ((handler->var_len && len < handler->data_len) || - (!handler->var_len && len != handler->data_len)) { + (!handler->var_len && len != handler->data_len)) { err = cmd_status(sk, index, opcode, MGMT_STATUS_INVALID_PARAMS); goto done; @@ -2980,7 +2955,7 @@ int mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, bacpy(&ev.key.addr.bdaddr, &key->bdaddr); ev.key.addr.type = BDADDR_BREDR; ev.key.type = key->type; - memcpy(ev.key.val, key->val, HCI_LINK_KEY_SIZE); + memcpy(ev.key.val, key->val, 16); ev.key.pin_len = key->pin_len; return mgmt_event(MGMT_EV_NEW_LINK_KEY, hdev, &ev, sizeof(ev), NULL); @@ -3115,7 +3090,7 @@ int mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, mgmt_pending_remove(cmd); mgmt_pending_foreach(MGMT_OP_UNPAIR_DEVICE, hdev, unpair_device_rsp, - hdev); + hdev); return err; } @@ -3205,7 +3180,7 @@ int mgmt_user_confirm_request(struct hci_dev *hdev, bdaddr_t *bdaddr, } int mgmt_user_passkey_request(struct hci_dev *hdev, bdaddr_t *bdaddr, - u8 link_type, u8 addr_type) + u8 link_type, u8 addr_type) { struct mgmt_ev_user_passkey_request ev; @@ -3219,8 +3194,8 @@ int mgmt_user_passkey_request(struct hci_dev *hdev, bdaddr_t *bdaddr, } static int user_pairing_resp_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, - u8 link_type, u8 addr_type, u8 status, - u8 opcode) + u8 link_type, u8 addr_type, u8 status, + u8 opcode) { struct pending_cmd *cmd; struct mgmt_rp_user_confirm_reply rp; @@ -3251,8 +3226,7 @@ int mgmt_user_confirm_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 addr_type, u8 status) { return user_pairing_resp_complete(hdev, bdaddr, link_type, addr_type, - status, - MGMT_OP_USER_CONFIRM_NEG_REPLY); + status, MGMT_OP_USER_CONFIRM_NEG_REPLY); } int mgmt_user_passkey_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, @@ -3266,8 +3240,7 @@ int mgmt_user_passkey_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 addr_type, u8 status) { return user_pairing_resp_complete(hdev, bdaddr, link_type, addr_type, - status, - MGMT_OP_USER_PASSKEY_NEG_REPLY); + status, MGMT_OP_USER_PASSKEY_NEG_REPLY); } int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, diff --git a/trunk/net/bluetooth/rfcomm/core.c b/trunk/net/bluetooth/rfcomm/core.c index c75107ef8920..8a602388f1e7 100644 --- a/trunk/net/bluetooth/rfcomm/core.c +++ b/trunk/net/bluetooth/rfcomm/core.c @@ -26,8 +26,22 @@ */ #include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include #include +#include + +#include +#include #include #include @@ -101,14 +115,14 @@ static void rfcomm_session_del(struct rfcomm_session *s); #define __get_rpn_stop_bits(line) (((line) >> 2) & 0x1) #define __get_rpn_parity(line) (((line) >> 3) & 0x7) -static void rfcomm_schedule(void) +static inline void rfcomm_schedule(void) { if (!rfcomm_thread) return; wake_up_process(rfcomm_thread); } -static void rfcomm_session_put(struct rfcomm_session *s) +static inline void rfcomm_session_put(struct rfcomm_session *s) { if (atomic_dec_and_test(&s->refcnt)) rfcomm_session_del(s); @@ -213,7 +227,7 @@ static int rfcomm_l2sock_create(struct socket **sock) return err; } -static int rfcomm_check_security(struct rfcomm_dlc *d) +static inline int rfcomm_check_security(struct rfcomm_dlc *d) { struct sock *sk = d->session->sock->sk; struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn; @@ -1736,7 +1750,7 @@ static void rfcomm_process_connect(struct rfcomm_session *s) /* Send data queued for the DLC. * Return number of frames left in the queue. */ -static int rfcomm_process_tx(struct rfcomm_dlc *d) +static inline int rfcomm_process_tx(struct rfcomm_dlc *d) { struct sk_buff *skb; int err; @@ -1784,7 +1798,7 @@ static int rfcomm_process_tx(struct rfcomm_dlc *d) return skb_queue_len(&d->tx_queue); } -static void rfcomm_process_dlcs(struct rfcomm_session *s) +static inline void rfcomm_process_dlcs(struct rfcomm_session *s) { struct rfcomm_dlc *d; struct list_head *p, *n; @@ -1844,7 +1858,7 @@ static void rfcomm_process_dlcs(struct rfcomm_session *s) } } -static void rfcomm_process_rx(struct rfcomm_session *s) +static inline void rfcomm_process_rx(struct rfcomm_session *s) { struct socket *sock = s->sock; struct sock *sk = sock->sk; @@ -1869,7 +1883,7 @@ static void rfcomm_process_rx(struct rfcomm_session *s) } } -static void rfcomm_accept_connection(struct rfcomm_session *s) +static inline void rfcomm_accept_connection(struct rfcomm_session *s) { struct socket *sock = s->sock, *nsock; int err; @@ -1903,7 +1917,7 @@ static void rfcomm_accept_connection(struct rfcomm_session *s) sock_release(nsock); } -static void rfcomm_check_connection(struct rfcomm_session *s) +static inline void rfcomm_check_connection(struct rfcomm_session *s) { struct sock *sk = s->sock->sk; @@ -1927,7 +1941,7 @@ static void rfcomm_check_connection(struct rfcomm_session *s) } } -static void rfcomm_process_sessions(void) +static inline void rfcomm_process_sessions(void) { struct list_head *p, *n; diff --git a/trunk/net/bluetooth/rfcomm/sock.c b/trunk/net/bluetooth/rfcomm/sock.c index 7e1e59645c05..e8707debb864 100644 --- a/trunk/net/bluetooth/rfcomm/sock.c +++ b/trunk/net/bluetooth/rfcomm/sock.c @@ -25,8 +25,27 @@ * RFCOMM sockets. */ -#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include + +#include #include #include diff --git a/trunk/net/bluetooth/rfcomm/tty.c b/trunk/net/bluetooth/rfcomm/tty.c index cb960773c002..d1820ff14aee 100644 --- a/trunk/net/bluetooth/rfcomm/tty.c +++ b/trunk/net/bluetooth/rfcomm/tty.c @@ -31,6 +31,11 @@ #include #include +#include +#include +#include +#include + #include #include #include @@ -127,7 +132,7 @@ static struct rfcomm_dev *__rfcomm_dev_get(int id) return NULL; } -static struct rfcomm_dev *rfcomm_dev_get(int id) +static inline struct rfcomm_dev *rfcomm_dev_get(int id) { struct rfcomm_dev *dev; @@ -340,7 +345,7 @@ static void rfcomm_wfree(struct sk_buff *skb) tty_port_put(&dev->port); } -static void rfcomm_set_owner_w(struct sk_buff *skb, struct rfcomm_dev *dev) +static inline void rfcomm_set_owner_w(struct sk_buff *skb, struct rfcomm_dev *dev) { tty_port_get(&dev->port); atomic_add(skb->truesize, &dev->wmem_alloc); diff --git a/trunk/net/bluetooth/sco.c b/trunk/net/bluetooth/sco.c index 40bbe25dcff7..cbdd313659a7 100644 --- a/trunk/net/bluetooth/sco.c +++ b/trunk/net/bluetooth/sco.c @@ -25,8 +25,26 @@ /* Bluetooth SCO sockets. */ #include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include +#include +#include +#include + +#include #include #include @@ -105,7 +123,7 @@ static struct sco_conn *sco_conn_add(struct hci_conn *hcon) return conn; } -static struct sock *sco_chan_get(struct sco_conn *conn) +static inline struct sock *sco_chan_get(struct sco_conn *conn) { struct sock *sk = NULL; sco_conn_lock(conn); @@ -139,8 +157,7 @@ static int sco_conn_del(struct hci_conn *hcon, int err) return 0; } -static int sco_chan_add(struct sco_conn *conn, struct sock *sk, - struct sock *parent) +static inline int sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent) { int err = 0; @@ -211,7 +228,7 @@ static int sco_connect(struct sock *sk) return err; } -static int sco_send_frame(struct sock *sk, struct msghdr *msg, int len) +static inline int sco_send_frame(struct sock *sk, struct msghdr *msg, int len) { struct sco_conn *conn = sco_pi(sk)->conn; struct sk_buff *skb; @@ -237,7 +254,7 @@ static int sco_send_frame(struct sock *sk, struct msghdr *msg, int len) return len; } -static void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb) +static inline void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb) { struct sock *sk = sco_chan_get(conn); @@ -506,7 +523,7 @@ static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen goto done; err = bt_sock_wait_state(sk, BT_CONNECTED, - sock_sndtimeo(sk, flags & O_NONBLOCK)); + sock_sndtimeo(sk, flags & O_NONBLOCK)); done: release_sock(sk); @@ -771,7 +788,7 @@ static int sco_sock_shutdown(struct socket *sock, int how) if (sock_flag(sk, SOCK_LINGER) && sk->sk_lingertime) err = bt_sock_wait_state(sk, BT_CLOSED, - sk->sk_lingertime); + sk->sk_lingertime); } release_sock(sk); return err; @@ -861,7 +878,7 @@ static void sco_conn_ready(struct sco_conn *conn) bh_lock_sock(parent); sk = sco_sock_alloc(sock_net(parent), NULL, - BTPROTO_SCO, GFP_ATOMIC); + BTPROTO_SCO, GFP_ATOMIC); if (!sk) { bh_unlock_sock(parent); goto done; @@ -890,7 +907,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) { - struct sock *sk; + register struct sock *sk; struct hlist_node *node; int lm = 0; @@ -903,7 +920,7 @@ int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr) continue; if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr) || - !bacmp(&bt_sk(sk)->src, BDADDR_ANY)) { + !bacmp(&bt_sk(sk)->src, BDADDR_ANY)) { lm |= HCI_LM_ACCEPT; break; } @@ -964,7 +981,7 @@ static int sco_debugfs_show(struct seq_file *f, void *p) sk_for_each(sk, node, &sco_sk_list.head) { seq_printf(f, "%s %s %d\n", batostr(&bt_sk(sk)->src), - batostr(&bt_sk(sk)->dst), sk->sk_state); + batostr(&bt_sk(sk)->dst), sk->sk_state); } read_unlock(&sco_sk_list.lock); @@ -1027,8 +1044,8 @@ int __init sco_init(void) } if (bt_debugfs) { - sco_debugfs = debugfs_create_file("sco", 0444, bt_debugfs, - NULL, &sco_debugfs_fops); + sco_debugfs = debugfs_create_file("sco", 0444, + bt_debugfs, NULL, &sco_debugfs_fops); if (!sco_debugfs) BT_ERR("Failed to create SCO debug file"); } diff --git a/trunk/net/bluetooth/smp.c b/trunk/net/bluetooth/smp.c index 16ef0dc85a0a..6fc7c4708f3e 100644 --- a/trunk/net/bluetooth/smp.c +++ b/trunk/net/bluetooth/smp.c @@ -20,15 +20,14 @@ SOFTWARE IS DISCLAIMED. */ -#include -#include -#include - #include #include #include #include #include +#include +#include +#include #define SMP_TIMEOUT msecs_to_jiffies(30000) @@ -649,7 +648,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM; - ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability); + ret = tk_request(conn, 0, auth, rsp->io_capability, req->io_capability); if (ret) return SMP_UNSPECIFIED; @@ -704,7 +703,7 @@ static u8 smp_cmd_pairing_random(struct l2cap_conn *conn, struct sk_buff *skb) return 0; } -static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level) +static u8 smp_ltk_encrypt(struct l2cap_conn *conn) { struct smp_ltk *key; struct hci_conn *hcon = conn->hcon; @@ -713,9 +712,6 @@ static u8 smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level) if (!key) return 0; - if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated) - return 0; - if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) return 1; @@ -736,7 +732,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) hcon->pending_sec_level = authreq_to_seclevel(rp->auth_req); - if (smp_ltk_encrypt(conn, hcon->pending_sec_level)) + if (smp_ltk_encrypt(conn)) return 0; if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) @@ -775,7 +771,7 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level) return 1; if (hcon->link_mode & HCI_LM_MASTER) - if (smp_ltk_encrypt(conn, sec_level)) + if (smp_ltk_encrypt(conn)) goto done; if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) diff --git a/trunk/net/mac80211/Kconfig b/trunk/net/mac80211/Kconfig index 63af25458fda..8d249d705980 100644 --- a/trunk/net/mac80211/Kconfig +++ b/trunk/net/mac80211/Kconfig @@ -107,19 +107,6 @@ config MAC80211_DEBUGFS Say N unless you know you need this. -config MAC80211_MESSAGE_TRACING - bool "Trace all mac80211 debug messages" - depends on MAC80211 - ---help--- - Select this option to have mac80211 register the - mac80211_msg trace subsystem with tracepoints to - collect all debugging messages, independent of - printing them into the kernel log. - - The overhead in this option is that all the messages - need to be present in the binary and formatted at - runtime for tracing. - menuconfig MAC80211_DEBUG_MENU bool "Select mac80211 debugging features" depends on MAC80211 @@ -153,26 +140,6 @@ config MAC80211_VERBOSE_DEBUG Do not select this option. -config MAC80211_MLME_DEBUG - bool "Verbose managed MLME output" - depends on MAC80211_DEBUG_MENU - ---help--- - Selecting this option causes mac80211 to print out - debugging messages for the managed-mode MLME. It - should not be selected on production systems as some - of the messages are remotely triggerable. - - Do not select this option. - -config MAC80211_STA_DEBUG - bool "Verbose station debugging" - depends on MAC80211_DEBUG_MENU - ---help--- - Selecting this option causes mac80211 to print out - debugging messages for station addition/removal. - - Do not select this option. - config MAC80211_HT_DEBUG bool "Verbose HT debugging" depends on MAC80211_DEBUG_MENU @@ -185,6 +152,17 @@ config MAC80211_HT_DEBUG Do not select this option. +config MAC80211_TKIP_DEBUG + bool "Verbose TKIP debugging" + depends on MAC80211_DEBUG_MENU + ---help--- + Selecting this option causes mac80211 to print out + very verbose TKIP debugging messages. It should not + be selected on production systems as those messages + are remotely triggerable. + + Do not select this option. + config MAC80211_IBSS_DEBUG bool "Verbose IBSS debugging" depends on MAC80211_DEBUG_MENU @@ -196,7 +174,7 @@ config MAC80211_IBSS_DEBUG Do not select this option. -config MAC80211_PS_DEBUG +config MAC80211_VERBOSE_PS_DEBUG bool "Verbose powersave mode debugging" depends on MAC80211_DEBUG_MENU ---help--- @@ -208,7 +186,7 @@ config MAC80211_PS_DEBUG Do not select this option. -config MAC80211_MPL_DEBUG +config MAC80211_VERBOSE_MPL_DEBUG bool "Verbose mesh peer link debugging" depends on MAC80211_DEBUG_MENU depends on MAC80211_MESH @@ -221,7 +199,7 @@ config MAC80211_MPL_DEBUG Do not select this option. -config MAC80211_MPATH_DEBUG +config MAC80211_VERBOSE_MPATH_DEBUG bool "Verbose mesh path debugging" depends on MAC80211_DEBUG_MENU depends on MAC80211_MESH @@ -234,7 +212,7 @@ config MAC80211_MPATH_DEBUG Do not select this option. -config MAC80211_MHWMP_DEBUG +config MAC80211_VERBOSE_MHWMP_DEBUG bool "Verbose mesh HWMP routing debugging" depends on MAC80211_DEBUG_MENU depends on MAC80211_MESH @@ -247,7 +225,7 @@ config MAC80211_MHWMP_DEBUG Do not select this option. -config MAC80211_MESH_SYNC_DEBUG +config MAC80211_VERBOSE_MESH_SYNC_DEBUG bool "Verbose mesh mesh synchronization debugging" depends on MAC80211_DEBUG_MENU depends on MAC80211_MESH @@ -258,7 +236,7 @@ config MAC80211_MESH_SYNC_DEBUG Do not select this option. -config MAC80211_TDLS_DEBUG +config MAC80211_VERBOSE_TDLS_DEBUG bool "Verbose TDLS debugging" depends on MAC80211_DEBUG_MENU ---help--- diff --git a/trunk/net/mac80211/Makefile b/trunk/net/mac80211/Makefile index a7dd110faafa..2b1470bac178 100644 --- a/trunk/net/mac80211/Makefile +++ b/trunk/net/mac80211/Makefile @@ -24,7 +24,7 @@ mac80211-y := \ wme.o \ event.o \ chan.o \ - trace.o mlme.o + driver-trace.o mlme.o mac80211-$(CONFIG_MAC80211_LEDS) += led.o mac80211-$(CONFIG_MAC80211_DEBUGFS) += \ @@ -42,7 +42,7 @@ mac80211-$(CONFIG_MAC80211_MESH) += \ mac80211-$(CONFIG_PM) += pm.o -CFLAGS_trace.o := -I$(src) +CFLAGS_driver-trace.o := -I$(src) # objects for PID algorithm rc80211_pid-y := rc80211_pid_algo.o @@ -58,4 +58,4 @@ mac80211-$(CONFIG_MAC80211_RC_PID) += $(rc80211_pid-y) mac80211-$(CONFIG_MAC80211_RC_MINSTREL) += $(rc80211_minstrel-y) mac80211-$(CONFIG_MAC80211_RC_MINSTREL_HT) += $(rc80211_minstrel_ht-y) -ccflags-y += -D__CHECK_ENDIAN__ -DDEBUG +ccflags-y += -D__CHECK_ENDIAN__ diff --git a/trunk/net/mac80211/agg-rx.c b/trunk/net/mac80211/agg-rx.c index 186d9919b043..32ef11d69798 100644 --- a/trunk/net/mac80211/agg-rx.c +++ b/trunk/net/mac80211/agg-rx.c @@ -74,17 +74,15 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, RCU_INIT_POINTER(sta->ampdu_mlme.tid_rx[tid], NULL); - ht_dbg(sta->sdata, - "Rx BA session stop requested for %pM tid %u %s reason: %d\n", - sta->sta.addr, tid, - initiator == WLAN_BACK_RECIPIENT ? "recipient" : "inititator", - (int)reason); + ht_vdbg("Rx BA session stop requested for %pM tid %u %s reason: %d\n", + sta->sta.addr, tid, + initiator == WLAN_BACK_RECIPIENT ? "recipient" : "inititator", + (int)reason); if (drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_STOP, &sta->sta, tid, NULL, 0)) - sdata_info(sta->sdata, - "HW problem - can not stop rx aggregation for tid %d\n", - tid); + pr_debug("HW problem - can not stop rx aggregation for tid %d\n", + tid); /* check if this is a self generated aggregation halt */ if (initiator == WLAN_BACK_RECIPIENT && tx) @@ -159,7 +157,7 @@ static void sta_rx_agg_session_timer_expired(unsigned long data) } rcu_read_unlock(); - ht_dbg(sta->sdata, "rx session timer expired on tid %d\n", (u16)*ptid); + ht_vdbg("rx session timer expired on tid %d\n", (u16)*ptid); set_bit(*ptid, sta->ampdu_mlme.tid_rx_timer_expired); ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work); @@ -247,7 +245,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, status = WLAN_STATUS_REQUEST_DECLINED; if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { - ht_dbg(sta->sdata, "Suspend in progress - Denying ADDBA request\n"); + ht_vdbg("Suspend in progress - Denying ADDBA request\n"); goto end_no_lock; } @@ -259,9 +257,10 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, (!(sta->sta.ht_cap.cap & IEEE80211_HT_CAP_DELAY_BA))) || (buf_size > IEEE80211_MAX_AMPDU_BUF)) { status = WLAN_STATUS_INVALID_QOS_PARAM; - ht_dbg_ratelimited(sta->sdata, - "AddBA Req with bad params from %pM on tid %u. policy %d, buffer size %d\n", - mgmt->sa, tid, ba_policy, buf_size); +#ifdef CONFIG_MAC80211_HT_DEBUG + net_dbg_ratelimited("AddBA Req with bad params from %pM on tid %u. policy %d, buffer size %d\n", + mgmt->sa, tid, ba_policy, buf_size); +#endif /* CONFIG_MAC80211_HT_DEBUG */ goto end_no_lock; } /* determine default buffer size */ @@ -276,9 +275,10 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, mutex_lock(&sta->ampdu_mlme.mtx); if (sta->ampdu_mlme.tid_rx[tid]) { - ht_dbg_ratelimited(sta->sdata, - "unexpected AddBA Req from %pM on tid %u\n", - mgmt->sa, tid); +#ifdef CONFIG_MAC80211_HT_DEBUG + net_dbg_ratelimited("unexpected AddBA Req from %pM on tid %u\n", + mgmt->sa, tid); +#endif /* CONFIG_MAC80211_HT_DEBUG */ /* delete existing Rx BA session on the same tid */ ___ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT, @@ -317,7 +317,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, ret = drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_START, &sta->sta, tid, &start_seq_num, 0); - ht_dbg(sta->sdata, "Rx A-MPDU request on tid %d result %d\n", tid, ret); + ht_vdbg("Rx A-MPDU request on tid %d result %d\n", tid, ret); if (ret) { kfree(tid_agg_rx->reorder_buf); kfree(tid_agg_rx->reorder_time); diff --git a/trunk/net/mac80211/agg-tx.c b/trunk/net/mac80211/agg-tx.c index 5cc1bf7d8033..da07f01cfe4d 100644 --- a/trunk/net/mac80211/agg-tx.c +++ b/trunk/net/mac80211/agg-tx.c @@ -184,8 +184,8 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, spin_unlock_bh(&sta->lock); - ht_dbg(sta->sdata, "Tx BA session stop requested for %pM tid %u\n", - sta->sta.addr, tid); + ht_vdbg("Tx BA session stop requested for %pM tid %u\n", + sta->sta.addr, tid); del_timer_sync(&tid_tx->addba_resp_timer); del_timer_sync(&tid_tx->session_timer); @@ -251,13 +251,12 @@ static void sta_addba_resp_timer_expired(unsigned long data) if (!tid_tx || test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state)) { rcu_read_unlock(); - ht_dbg(sta->sdata, - "timer expired on tid %d but we are not (or no longer) expecting addBA response there\n", - tid); + ht_vdbg("timer expired on tid %d but we are not (or no longer) expecting addBA response there\n", + tid); return; } - ht_dbg(sta->sdata, "addBA response timer expired on tid %d\n", tid); + ht_vdbg("addBA response timer expired on tid %d\n", tid); ieee80211_stop_tx_ba_session(&sta->sta, tid); rcu_read_unlock(); @@ -317,9 +316,8 @@ ieee80211_agg_splice_packets(struct ieee80211_sub_if_data *sdata, ieee80211_stop_queue_agg(sdata, tid); - if (WARN(!tid_tx, - "TID %d gone but expected when splicing aggregates from the pending queue\n", - tid)) + if (WARN(!tid_tx, "TID %d gone but expected when splicing aggregates" + " from the pending queue\n", tid)) return; if (!skb_queue_empty(&tid_tx->pending)) { @@ -367,8 +365,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) ret = drv_ampdu_action(local, sdata, IEEE80211_AMPDU_TX_START, &sta->sta, tid, &start_seq_num, 0); if (ret) { - ht_dbg(sdata, - "BA request denied - HW unavailable for tid %d\n", tid); + ht_vdbg("BA request denied - HW unavailable for tid %d\n", tid); spin_lock_bh(&sta->lock); ieee80211_agg_splice_packets(sdata, tid_tx, tid); ieee80211_assign_tid_tx(sta, tid, NULL); @@ -381,7 +378,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) /* activate the timer for the recipient's addBA response */ mod_timer(&tid_tx->addba_resp_timer, jiffies + ADDBA_RESP_INTERVAL); - ht_dbg(sdata, "activated addBA response timer on tid %d\n", tid); + ht_vdbg("activated addBA response timer on tid %d\n", tid); spin_lock_bh(&sta->lock); sta->ampdu_mlme.last_addba_req_time[tid] = jiffies; @@ -428,7 +425,7 @@ static void sta_tx_agg_session_timer_expired(unsigned long data) rcu_read_unlock(); - ht_dbg(sta->sdata, "tx session timer expired on tid %d\n", (u16)*ptid); + ht_vdbg("tx session timer expired on tid %d\n", (u16)*ptid); ieee80211_stop_tx_ba_session(&sta->sta, *ptid); } @@ -452,8 +449,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, (local->hw.flags & IEEE80211_HW_TX_AMPDU_SETUP_IN_HW)) return -EINVAL; - ht_dbg(sdata, "Open BA session requested for %pM tid %u\n", - pubsta->addr, tid); + ht_vdbg("Open BA session requested for %pM tid %u\n", + pubsta->addr, tid); if (sdata->vif.type != NL80211_IFTYPE_STATION && sdata->vif.type != NL80211_IFTYPE_MESH_POINT && @@ -463,8 +460,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, return -EINVAL; if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { - ht_dbg(sdata, - "BA sessions blocked - Denying BA session request\n"); + ht_vdbg("BA sessions blocked - Denying BA session request\n"); return -EINVAL; } @@ -482,9 +478,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, */ if (sta->sdata->vif.type == NL80211_IFTYPE_ADHOC && !sta->sta.ht_cap.ht_supported) { - ht_dbg(sdata, - "BA request denied - IBSS STA %pM does not advertise HT support\n", - pubsta->addr); + ht_vdbg("BA request denied - IBSS STA %pM does not advertise HT support\n", + pubsta->addr); return -EINVAL; } @@ -504,9 +499,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_BURST_RETRIES && time_before(jiffies, sta->ampdu_mlme.last_addba_req_time[tid] + HT_AGG_RETRIES_PERIOD)) { - ht_dbg(sdata, - "BA request denied - waiting a grace period after %d failed requests on tid %u\n", - sta->ampdu_mlme.addba_req_num[tid], tid); + ht_vdbg("BA request denied - waiting a grace period after %d failed requests on tid %u\n", + sta->ampdu_mlme.addba_req_num[tid], tid); ret = -EBUSY; goto err_unlock_sta; } @@ -514,9 +508,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, tid_tx = rcu_dereference_protected_tid_tx(sta, tid); /* check if the TID is not in aggregation flow already */ if (tid_tx || sta->ampdu_mlme.tid_start_tx[tid]) { - ht_dbg(sdata, - "BA request denied - session is not idle on tid %u\n", - tid); + ht_vdbg("BA request denied - session is not idle on tid %u\n", + tid); ret = -EAGAIN; goto err_unlock_sta; } @@ -571,7 +564,7 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local, tid_tx = rcu_dereference_protected_tid_tx(sta, tid); - ht_dbg(sta->sdata, "Aggregation is on for tid %d\n", tid); + ht_vdbg("Aggregation is on for tid %d\n", tid); drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_TX_OPERATIONAL, @@ -605,8 +598,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid) trace_api_start_tx_ba_cb(sdata, ra, tid); if (tid >= STA_TID_NUM) { - ht_dbg(sdata, "Bad TID value: tid = %d (>= %d)\n", - tid, STA_TID_NUM); + ht_vdbg("Bad TID value: tid = %d (>= %d)\n", tid, STA_TID_NUM); return; } @@ -614,7 +606,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid) sta = sta_info_get_bss(sdata, ra); if (!sta) { mutex_unlock(&local->sta_mtx); - ht_dbg(sdata, "Could not find station: %pM\n", ra); + ht_vdbg("Could not find station: %pM\n", ra); return; } @@ -622,7 +614,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid) tid_tx = rcu_dereference_protected_tid_tx(sta, tid); if (WARN_ON(!tid_tx)) { - ht_dbg(sdata, "addBA was not requested!\n"); + ht_vdbg("addBA was not requested!\n"); goto unlock; } @@ -722,18 +714,17 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid) trace_api_stop_tx_ba_cb(sdata, ra, tid); if (tid >= STA_TID_NUM) { - ht_dbg(sdata, "Bad TID value: tid = %d (>= %d)\n", - tid, STA_TID_NUM); + ht_vdbg("Bad TID value: tid = %d (>= %d)\n", tid, STA_TID_NUM); return; } - ht_dbg(sdata, "Stopping Tx BA session for %pM tid %d\n", ra, tid); + ht_vdbg("Stopping Tx BA session for %pM tid %d\n", ra, tid); mutex_lock(&local->sta_mtx); sta = sta_info_get_bss(sdata, ra); if (!sta) { - ht_dbg(sdata, "Could not find station: %pM\n", ra); + ht_vdbg("Could not find station: %pM\n", ra); goto unlock; } @@ -742,7 +733,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid) tid_tx = rcu_dereference_protected_tid_tx(sta, tid); if (!tid_tx || !test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { - ht_dbg(sdata, "unexpected callback to A-MPDU stop\n"); + ht_vdbg("unexpected callback to A-MPDU stop\n"); goto unlock_sta; } @@ -818,13 +809,13 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, goto out; if (mgmt->u.action.u.addba_resp.dialog_token != tid_tx->dialog_token) { - ht_dbg(sta->sdata, "wrong addBA response token, tid %d\n", tid); + ht_vdbg("wrong addBA response token, tid %d\n", tid); goto out; } del_timer_sync(&tid_tx->addba_resp_timer); - ht_dbg(sta->sdata, "switched off addBA timer for tid %d\n", tid); + ht_vdbg("switched off addBA timer for tid %d\n", tid); /* * addba_resp_timer may have fired before we got here, and @@ -833,9 +824,8 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, */ if (test_bit(HT_AGG_STATE_WANT_STOP, &tid_tx->state) || test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { - ht_dbg(sta->sdata, - "got addBA resp for tid %d but we already gave up\n", - tid); + ht_vdbg("got addBA resp for tid %d but we already gave up\n", + tid); goto out; } diff --git a/trunk/net/mac80211/cfg.c b/trunk/net/mac80211/cfg.c index ccbe2413142a..498c94e34427 100644 --- a/trunk/net/mac80211/cfg.c +++ b/trunk/net/mac80211/cfg.c @@ -353,7 +353,6 @@ void sta_set_rate_info_tx(struct sta_info *sta, static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) { struct ieee80211_sub_if_data *sdata = sta->sdata; - struct ieee80211_local *local = sdata->local; struct timespec uptime; sinfo->generation = sdata->local->sta_generation; @@ -389,9 +388,7 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG; - if (!local->ops->get_rssi || - drv_get_rssi(local, sdata, &sta->sta, &sinfo->signal)) - sinfo->signal = (s8)sta->last_signal; + sinfo->signal = (s8)sta->last_signal; sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal); } @@ -520,7 +517,7 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy, * network device. */ - mutex_lock(&local->sta_mtx); + rcu_read_lock(); if (sdata->vif.type == NL80211_IFTYPE_STATION) { sta = sta_info_get_bss(sdata, sdata->u.mgd.bssid); @@ -549,7 +546,7 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy, data[i] = (u8)sinfo.signal_avg; i++; } else { - list_for_each_entry(sta, &local->sta_list, list) { + list_for_each_entry_rcu(sta, &local->sta_list, list) { /* Make sure this station belongs to the proper dev */ if (sta->sdata->dev != dev) continue; @@ -606,7 +603,7 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy, else data[i++] = -1LL; - mutex_unlock(&local->sta_mtx); + rcu_read_unlock(); if (WARN_ON(i != STA_STATS_LEN)) return; @@ -632,11 +629,10 @@ static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev, int idx, u8 *mac, struct station_info *sinfo) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - struct ieee80211_local *local = sdata->local; struct sta_info *sta; int ret = -ENOENT; - mutex_lock(&local->sta_mtx); + rcu_read_lock(); sta = sta_info_get_by_idx(sdata, idx); if (sta) { @@ -645,7 +641,7 @@ static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev, sta_set_sinfo(sta, sinfo); } - mutex_unlock(&local->sta_mtx); + rcu_read_unlock(); return ret; } @@ -662,11 +658,10 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev, u8 *mac, struct station_info *sinfo) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - struct ieee80211_local *local = sdata->local; struct sta_info *sta; int ret = -ENOENT; - mutex_lock(&local->sta_mtx); + rcu_read_lock(); sta = sta_info_get_bss(sdata, mac); if (sta) { @@ -674,7 +669,7 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev, sta_set_sinfo(sta, sinfo); } - mutex_unlock(&local->sta_mtx); + rcu_read_unlock(); return ret; } @@ -694,8 +689,7 @@ static int ieee80211_set_channel(struct wiphy *wiphy, case CHAN_MODE_HOPPING: return -EBUSY; case CHAN_MODE_FIXED: - if (local->oper_channel != chan || - (!sdata && local->_oper_channel_type != channel_type)) + if (local->oper_channel != chan) return -EBUSY; if (!sdata && local->_oper_channel_type == channel_type) return 0; @@ -1535,7 +1529,7 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy, if (_chg_mesh_attr(NL80211_MESHCONF_TTL, mask)) conf->dot11MeshTTL = nconf->dot11MeshTTL; if (_chg_mesh_attr(NL80211_MESHCONF_ELEMENT_TTL, mask)) - conf->element_ttl = nconf->element_ttl; + conf->dot11MeshTTL = nconf->element_ttl; if (_chg_mesh_attr(NL80211_MESHCONF_AUTO_OPEN_PLINKS, mask)) conf->auto_open_plinks = nconf->auto_open_plinks; if (_chg_mesh_attr(NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, mask)) @@ -1570,16 +1564,17 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy, * announcements, so require this ifmsh to also be a root node * */ if (nconf->dot11MeshGateAnnouncementProtocol && - !(conf->dot11MeshHWMPRootMode > IEEE80211_ROOTMODE_ROOT)) { - conf->dot11MeshHWMPRootMode = IEEE80211_PROACTIVE_RANN; + !conf->dot11MeshHWMPRootMode) { + conf->dot11MeshHWMPRootMode = 1; ieee80211_mesh_root_setup(ifmsh); } conf->dot11MeshGateAnnouncementProtocol = nconf->dot11MeshGateAnnouncementProtocol; } - if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_RANN_INTERVAL, mask)) + if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_RANN_INTERVAL, mask)) { conf->dot11MeshHWMPRannInterval = nconf->dot11MeshHWMPRannInterval; + } if (_chg_mesh_attr(NL80211_MESHCONF_FORWARDING, mask)) conf->dot11MeshForwarding = nconf->dot11MeshForwarding; if (_chg_mesh_attr(NL80211_MESHCONF_RSSI_THRESHOLD, mask)) { @@ -1595,15 +1590,6 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy, sdata->vif.bss_conf.ht_operation_mode = nconf->ht_opmode; ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT); } - if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT, mask)) - conf->dot11MeshHWMPactivePathToRootTimeout = - nconf->dot11MeshHWMPactivePathToRootTimeout; - if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ROOT_INTERVAL, mask)) - conf->dot11MeshHWMProotInterval = - nconf->dot11MeshHWMProotInterval; - if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, mask)) - conf->dot11MeshHWMPconfirmationInterval = - nconf->dot11MeshHWMPconfirmationInterval; return 0; } @@ -2111,9 +2097,6 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy, struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); int i, ret; - if (!ieee80211_sdata_running(sdata)) - return -ENETDOWN; - if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) { ret = drv_set_bitrate_mask(local, sdata, mask); if (ret) @@ -2323,21 +2306,6 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local, mutex_lock(&local->mtx); list_for_each_entry_safe(roc, tmp, &local->roc_list, list) { - struct ieee80211_roc_work *dep, *tmp2; - - list_for_each_entry_safe(dep, tmp2, &roc->dependents, list) { - if (!mgmt_tx && (unsigned long)dep != cookie) - continue; - else if (mgmt_tx && dep->mgmt_tx_cookie != cookie) - continue; - /* found dependent item -- just remove it */ - list_del(&dep->list); - mutex_unlock(&local->mtx); - - ieee80211_roc_notify_destroy(dep); - return 0; - } - if (!mgmt_tx && (unsigned long)roc != cookie) continue; else if (mgmt_tx && roc->mgmt_tx_cookie != cookie) @@ -2352,13 +2320,6 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local, return -ENOENT; } - /* - * We found the item to cancel, so do that. Note that it - * may have dependents, which we also cancel (and send - * the expired signal for.) Not doing so would be quite - * tricky here, but we may need to fix it later. - */ - if (local->ops->remain_on_channel) { if (found->started) { ret = drv_cancel_remain_on_channel(local); @@ -2370,8 +2331,8 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local, list_del(&found->list); - if (found->started) - ieee80211_start_next_roc(local); + ieee80211_run_deferred_scan(local); + ieee80211_start_next_roc(local); mutex_unlock(&local->mtx); ieee80211_roc_notify_destroy(found); @@ -2525,30 +2486,16 @@ static void ieee80211_mgmt_frame_register(struct wiphy *wiphy, u16 frame_type, bool reg) { struct ieee80211_local *local = wiphy_priv(wiphy); - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - switch (frame_type) { - case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH: - if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { - struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; + if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ)) + return; - if (reg) - ifibss->auth_frame_registrations++; - else - ifibss->auth_frame_registrations--; - } - break; - case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ: - if (reg) - local->probe_req_reg++; - else - local->probe_req_reg--; + if (reg) + local->probe_req_reg++; + else + local->probe_req_reg--; - ieee80211_queue_work(&local->hw, &local->reconfig_filter); - break; - default: - break; - } + ieee80211_queue_work(&local->hw, &local->reconfig_filter); } static int ieee80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant) @@ -2668,8 +2615,8 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev, tf->u.setup_req.capability = cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); - ieee80211_add_srates_ie(sdata, skb, false); - ieee80211_add_ext_srates_ie(sdata, skb, false); + ieee80211_add_srates_ie(&sdata->vif, skb, false); + ieee80211_add_ext_srates_ie(&sdata->vif, skb, false); ieee80211_tdls_add_ext_capab(skb); break; case WLAN_TDLS_SETUP_RESPONSE: @@ -2682,8 +2629,8 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev, tf->u.setup_resp.capability = cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); - ieee80211_add_srates_ie(sdata, skb, false); - ieee80211_add_ext_srates_ie(sdata, skb, false); + ieee80211_add_srates_ie(&sdata->vif, skb, false); + ieee80211_add_ext_srates_ie(&sdata->vif, skb, false); ieee80211_tdls_add_ext_capab(skb); break; case WLAN_TDLS_SETUP_CONFIRM: @@ -2743,8 +2690,8 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev, mgmt->u.action.u.tdls_discover_resp.capability = cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); - ieee80211_add_srates_ie(sdata, skb, false); - ieee80211_add_ext_srates_ie(sdata, skb, false); + ieee80211_add_srates_ie(&sdata->vif, skb, false); + ieee80211_add_ext_srates_ie(&sdata->vif, skb, false); ieee80211_tdls_add_ext_capab(skb); break; default: @@ -2774,8 +2721,9 @@ static int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, !sdata->u.mgd.associated) return -EINVAL; - tdls_dbg(sdata, "TDLS mgmt action %d peer %pM\n", - action_code, peer); +#ifdef CONFIG_MAC80211_VERBOSE_TDLS_DEBUG + pr_debug("TDLS mgmt action %d peer %pM\n", action_code, peer); +#endif skb = dev_alloc_skb(local->hw.extra_tx_headroom + max(sizeof(struct ieee80211_mgmt), @@ -2884,7 +2832,9 @@ static int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, if (sdata->vif.type != NL80211_IFTYPE_STATION) return -EINVAL; - tdls_dbg(sdata, "TDLS oper %d peer %pM\n", oper, peer); +#ifdef CONFIG_MAC80211_VERBOSE_TDLS_DEBUG + pr_debug("TDLS oper %d peer %pM\n", oper, peer); +#endif switch (oper) { case NL80211_TDLS_ENABLE_LINK: @@ -2980,14 +2930,14 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, return 0; } -static void ieee80211_set_monitor_enabled(struct wiphy *wiphy, bool enabled) +static struct ieee80211_channel * +ieee80211_wiphy_get_channel(struct wiphy *wiphy, + enum nl80211_channel_type *type) { struct ieee80211_local *local = wiphy_priv(wiphy); - if (enabled) - WARN_ON(ieee80211_add_virtual_monitor(local)); - else - ieee80211_del_virtual_monitor(local); + *type = local->_oper_channel_type; + return local->oper_channel; } #ifdef CONFIG_PM @@ -3063,8 +3013,8 @@ struct cfg80211_ops mac80211_config_ops = { .tdls_oper = ieee80211_tdls_oper, .tdls_mgmt = ieee80211_tdls_mgmt, .probe_client = ieee80211_probe_client, + .get_channel = ieee80211_wiphy_get_channel, .set_noack_map = ieee80211_set_noack_map, - .set_monitor_enabled = ieee80211_set_monitor_enabled, #ifdef CONFIG_PM .set_wakeup = ieee80211_set_wakeup, #endif diff --git a/trunk/net/mac80211/debug.h b/trunk/net/mac80211/debug.h deleted file mode 100644 index 8f383a576016..000000000000 --- a/trunk/net/mac80211/debug.h +++ /dev/null @@ -1,170 +0,0 @@ -#ifndef __MAC80211_DEBUG_H -#define __MAC80211_DEBUG_H -#include - -#ifdef CONFIG_MAC80211_IBSS_DEBUG -#define MAC80211_IBSS_DEBUG 1 -#else -#define MAC80211_IBSS_DEBUG 0 -#endif - -#ifdef CONFIG_MAC80211_PS_DEBUG -#define MAC80211_PS_DEBUG 1 -#else -#define MAC80211_PS_DEBUG 0 -#endif - -#ifdef CONFIG_MAC80211_HT_DEBUG -#define MAC80211_HT_DEBUG 1 -#else -#define MAC80211_HT_DEBUG 0 -#endif - -#ifdef CONFIG_MAC80211_MPL_DEBUG -#define MAC80211_MPL_DEBUG 1 -#else -#define MAC80211_MPL_DEBUG 0 -#endif - -#ifdef CONFIG_MAC80211_MPATH_DEBUG -#define MAC80211_MPATH_DEBUG 1 -#else -#define MAC80211_MPATH_DEBUG 0 -#endif - -#ifdef CONFIG_MAC80211_MHWMP_DEBUG -#define MAC80211_MHWMP_DEBUG 1 -#else -#define MAC80211_MHWMP_DEBUG 0 -#endif - -#ifdef CONFIG_MAC80211_MESH_SYNC_DEBUG -#define MAC80211_MESH_SYNC_DEBUG 1 -#else -#define MAC80211_MESH_SYNC_DEBUG 0 -#endif - -#ifdef CONFIG_MAC80211_TDLS_DEBUG -#define MAC80211_TDLS_DEBUG 1 -#else -#define MAC80211_TDLS_DEBUG 0 -#endif - -#ifdef CONFIG_MAC80211_STA_DEBUG -#define MAC80211_STA_DEBUG 1 -#else -#define MAC80211_STA_DEBUG 0 -#endif - -#ifdef CONFIG_MAC80211_MLME_DEBUG -#define MAC80211_MLME_DEBUG 1 -#else -#define MAC80211_MLME_DEBUG 0 -#endif - -#ifdef CONFIG_MAC80211_MESSAGE_TRACING -void __sdata_info(const char *fmt, ...) __printf(1, 2); -void __sdata_dbg(bool print, const char *fmt, ...) __printf(2, 3); -void __sdata_err(const char *fmt, ...) __printf(1, 2); -void __wiphy_dbg(struct wiphy *wiphy, bool print, const char *fmt, ...) - __printf(3, 4); - -#define _sdata_info(sdata, fmt, ...) \ - __sdata_info("%s: " fmt, (sdata)->name, ##__VA_ARGS__) -#define _sdata_dbg(print, sdata, fmt, ...) \ - __sdata_dbg(print, "%s: " fmt, (sdata)->name, ##__VA_ARGS__) -#define _sdata_err(sdata, fmt, ...) \ - __sdata_err("%s: " fmt, (sdata)->name, ##__VA_ARGS__) -#define _wiphy_dbg(print, wiphy, fmt, ...) \ - __wiphy_dbg(wiphy, print, fmt, ##__VA_ARGS__) -#else -#define _sdata_info(sdata, fmt, ...) \ -do { \ - pr_info("%s: " fmt, \ - (sdata)->name, ##__VA_ARGS__); \ -} while (0) - -#define _sdata_dbg(print, sdata, fmt, ...) \ -do { \ - if (print) \ - pr_debug("%s: " fmt, \ - (sdata)->name, ##__VA_ARGS__); \ -} while (0) - -#define _sdata_err(sdata, fmt, ...) \ -do { \ - pr_err("%s: " fmt, \ - (sdata)->name, ##__VA_ARGS__); \ -} while (0) - -#define _wiphy_dbg(print, wiphy, fmt, ...) \ -do { \ - if (print) \ - wiphy_dbg((wiphy), fmt, ##__VA_ARGS__); \ -} while (0) -#endif - -#define sdata_info(sdata, fmt, ...) \ - _sdata_info(sdata, fmt, ##__VA_ARGS__) -#define sdata_err(sdata, fmt, ...) \ - _sdata_err(sdata, fmt, ##__VA_ARGS__) -#define sdata_dbg(sdata, fmt, ...) \ - _sdata_dbg(1, sdata, fmt, ##__VA_ARGS__) - -#define ht_dbg(sdata, fmt, ...) \ - _sdata_dbg(MAC80211_HT_DEBUG, \ - sdata, fmt, ##__VA_ARGS__) - -#define ht_dbg_ratelimited(sdata, fmt, ...) \ - _sdata_dbg(MAC80211_HT_DEBUG && net_ratelimit(), \ - sdata, fmt, ##__VA_ARGS__) - -#define ibss_dbg(sdata, fmt, ...) \ - _sdata_dbg(MAC80211_IBSS_DEBUG, \ - sdata, fmt, ##__VA_ARGS__) - -#define ps_dbg(sdata, fmt, ...) \ - _sdata_dbg(MAC80211_PS_DEBUG, \ - sdata, fmt, ##__VA_ARGS__) - -#define ps_dbg_hw(hw, fmt, ...) \ - _wiphy_dbg(MAC80211_PS_DEBUG, \ - (hw)->wiphy, fmt, ##__VA_ARGS__) - -#define ps_dbg_ratelimited(sdata, fmt, ...) \ - _sdata_dbg(MAC80211_PS_DEBUG && net_ratelimit(), \ - sdata, fmt, ##__VA_ARGS__) - -#define mpl_dbg(sdata, fmt, ...) \ - _sdata_dbg(MAC80211_MPL_DEBUG, \ - sdata, fmt, ##__VA_ARGS__) - -#define mpath_dbg(sdata, fmt, ...) \ - _sdata_dbg(MAC80211_MPATH_DEBUG, \ - sdata, fmt, ##__VA_ARGS__) - -#define mhwmp_dbg(sdata, fmt, ...) \ - _sdata_dbg(MAC80211_MHWMP_DEBUG, \ - sdata, fmt, ##__VA_ARGS__) - -#define msync_dbg(sdata, fmt, ...) \ - _sdata_dbg(MAC80211_MESH_SYNC_DEBUG, \ - sdata, fmt, ##__VA_ARGS__) - -#define tdls_dbg(sdata, fmt, ...) \ - _sdata_dbg(MAC80211_TDLS_DEBUG, \ - sdata, fmt, ##__VA_ARGS__) - -#define sta_dbg(sdata, fmt, ...) \ - _sdata_dbg(MAC80211_STA_DEBUG, \ - sdata, fmt, ##__VA_ARGS__) - -#define mlme_dbg(sdata, fmt, ...) \ - _sdata_dbg(MAC80211_MLME_DEBUG, \ - sdata, fmt, ##__VA_ARGS__) - -#define mlme_dbg_ratelimited(sdata, fmt, ...) \ - _sdata_dbg(MAC80211_MLME_DEBUG && net_ratelimit(), \ - sdata, fmt, ##__VA_ARGS__) - -#endif /* __MAC80211_DEBUG_H */ diff --git a/trunk/net/mac80211/debugfs_key.c b/trunk/net/mac80211/debugfs_key.c index 090d08ff22c4..7932767bb482 100644 --- a/trunk/net/mac80211/debugfs_key.c +++ b/trunk/net/mac80211/debugfs_key.c @@ -283,11 +283,6 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata) lockdep_assert_held(&sdata->local->key_mtx); - if (sdata->debugfs.default_unicast_key) { - debugfs_remove(sdata->debugfs.default_unicast_key); - sdata->debugfs.default_unicast_key = NULL; - } - if (sdata->default_unicast_key) { key = key_mtx_dereference(sdata->local, sdata->default_unicast_key); @@ -295,11 +290,9 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata) sdata->debugfs.default_unicast_key = debugfs_create_symlink("default_unicast_key", sdata->debugfs.dir, buf); - } - - if (sdata->debugfs.default_multicast_key) { - debugfs_remove(sdata->debugfs.default_multicast_key); - sdata->debugfs.default_multicast_key = NULL; + } else { + debugfs_remove(sdata->debugfs.default_unicast_key); + sdata->debugfs.default_unicast_key = NULL; } if (sdata->default_multicast_key) { @@ -309,6 +302,9 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata) sdata->debugfs.default_multicast_key = debugfs_create_symlink("default_multicast_key", sdata->debugfs.dir, buf); + } else { + debugfs_remove(sdata->debugfs.default_multicast_key); + sdata->debugfs.default_multicast_key = NULL; } } diff --git a/trunk/net/mac80211/debugfs_netdev.c b/trunk/net/mac80211/debugfs_netdev.c index 6d5aec9418ee..d4272ff43f71 100644 --- a/trunk/net/mac80211/debugfs_netdev.c +++ b/trunk/net/mac80211/debugfs_netdev.c @@ -468,54 +468,48 @@ IEEE80211_IF_FILE(fwded_unicast, u.mesh.mshstats.fwded_unicast, DEC); IEEE80211_IF_FILE(fwded_frames, u.mesh.mshstats.fwded_frames, DEC); IEEE80211_IF_FILE(dropped_frames_ttl, u.mesh.mshstats.dropped_frames_ttl, DEC); IEEE80211_IF_FILE(dropped_frames_congestion, - u.mesh.mshstats.dropped_frames_congestion, DEC); + u.mesh.mshstats.dropped_frames_congestion, DEC); IEEE80211_IF_FILE(dropped_frames_no_route, - u.mesh.mshstats.dropped_frames_no_route, DEC); + u.mesh.mshstats.dropped_frames_no_route, DEC); IEEE80211_IF_FILE(estab_plinks, u.mesh.mshstats.estab_plinks, ATOMIC); /* Mesh parameters */ IEEE80211_IF_FILE(dot11MeshMaxRetries, - u.mesh.mshcfg.dot11MeshMaxRetries, DEC); + u.mesh.mshcfg.dot11MeshMaxRetries, DEC); IEEE80211_IF_FILE(dot11MeshRetryTimeout, - u.mesh.mshcfg.dot11MeshRetryTimeout, DEC); + u.mesh.mshcfg.dot11MeshRetryTimeout, DEC); IEEE80211_IF_FILE(dot11MeshConfirmTimeout, - u.mesh.mshcfg.dot11MeshConfirmTimeout, DEC); + u.mesh.mshcfg.dot11MeshConfirmTimeout, DEC); IEEE80211_IF_FILE(dot11MeshHoldingTimeout, - u.mesh.mshcfg.dot11MeshHoldingTimeout, DEC); + u.mesh.mshcfg.dot11MeshHoldingTimeout, DEC); IEEE80211_IF_FILE(dot11MeshTTL, u.mesh.mshcfg.dot11MeshTTL, DEC); IEEE80211_IF_FILE(element_ttl, u.mesh.mshcfg.element_ttl, DEC); IEEE80211_IF_FILE(auto_open_plinks, u.mesh.mshcfg.auto_open_plinks, DEC); IEEE80211_IF_FILE(dot11MeshMaxPeerLinks, - u.mesh.mshcfg.dot11MeshMaxPeerLinks, DEC); + u.mesh.mshcfg.dot11MeshMaxPeerLinks, DEC); IEEE80211_IF_FILE(dot11MeshHWMPactivePathTimeout, - u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout, DEC); + u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout, DEC); IEEE80211_IF_FILE(dot11MeshHWMPpreqMinInterval, - u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval, DEC); + u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval, DEC); IEEE80211_IF_FILE(dot11MeshHWMPperrMinInterval, - u.mesh.mshcfg.dot11MeshHWMPperrMinInterval, DEC); + u.mesh.mshcfg.dot11MeshHWMPperrMinInterval, DEC); IEEE80211_IF_FILE(dot11MeshHWMPnetDiameterTraversalTime, - u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC); + u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC); IEEE80211_IF_FILE(dot11MeshHWMPmaxPREQretries, - u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries, DEC); + u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries, DEC); IEEE80211_IF_FILE(path_refresh_time, - u.mesh.mshcfg.path_refresh_time, DEC); + u.mesh.mshcfg.path_refresh_time, DEC); IEEE80211_IF_FILE(min_discovery_timeout, - u.mesh.mshcfg.min_discovery_timeout, DEC); + u.mesh.mshcfg.min_discovery_timeout, DEC); IEEE80211_IF_FILE(dot11MeshHWMPRootMode, - u.mesh.mshcfg.dot11MeshHWMPRootMode, DEC); + u.mesh.mshcfg.dot11MeshHWMPRootMode, DEC); IEEE80211_IF_FILE(dot11MeshGateAnnouncementProtocol, - u.mesh.mshcfg.dot11MeshGateAnnouncementProtocol, DEC); + u.mesh.mshcfg.dot11MeshGateAnnouncementProtocol, DEC); IEEE80211_IF_FILE(dot11MeshHWMPRannInterval, - u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC); + u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC); IEEE80211_IF_FILE(dot11MeshForwarding, u.mesh.mshcfg.dot11MeshForwarding, DEC); IEEE80211_IF_FILE(rssi_threshold, u.mesh.mshcfg.rssi_threshold, DEC); IEEE80211_IF_FILE(ht_opmode, u.mesh.mshcfg.ht_opmode, DEC); -IEEE80211_IF_FILE(dot11MeshHWMPactivePathToRootTimeout, - u.mesh.mshcfg.dot11MeshHWMPactivePathToRootTimeout, DEC); -IEEE80211_IF_FILE(dot11MeshHWMProotInterval, - u.mesh.mshcfg.dot11MeshHWMProotInterval, DEC); -IEEE80211_IF_FILE(dot11MeshHWMPconfirmationInterval, - u.mesh.mshcfg.dot11MeshHWMPconfirmationInterval, DEC); #endif #define DEBUGFS_ADD_MODE(name, mode) \ @@ -617,9 +611,6 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata) MESHPARAMS_ADD(dot11MeshGateAnnouncementProtocol); MESHPARAMS_ADD(rssi_threshold); MESHPARAMS_ADD(ht_opmode); - MESHPARAMS_ADD(dot11MeshHWMPactivePathToRootTimeout); - MESHPARAMS_ADD(dot11MeshHWMProotInterval); - MESHPARAMS_ADD(dot11MeshHWMPconfirmationInterval); #undef MESHPARAMS_ADD } #endif @@ -695,7 +686,6 @@ void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata) sprintf(buf, "netdev:%s", sdata->name); if (!debugfs_rename(dir->d_parent, dir, dir->d_parent, buf)) - sdata_err(sdata, - "debugfs: failed to rename debugfs dir to %s\n", - buf); + pr_err("mac80211: debugfs: failed to rename debugfs " + "dir to %s\n", buf); } diff --git a/trunk/net/mac80211/driver-ops.h b/trunk/net/mac80211/driver-ops.h index df9203199102..6d33a0c743ab 100644 --- a/trunk/net/mac80211/driver-ops.h +++ b/trunk/net/mac80211/driver-ops.h @@ -3,7 +3,7 @@ #include #include "ieee80211_i.h" -#include "trace.h" +#include "driver-trace.h" static inline void check_sdata_in_driver(struct ieee80211_sub_if_data *sdata) { @@ -27,6 +27,14 @@ static inline void drv_tx(struct ieee80211_local *local, struct sk_buff *skb) local->ops->tx(&local->hw, skb); } +static inline void drv_tx_frags(struct ieee80211_local *local, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, + struct sk_buff_head *skbs) +{ + local->ops->tx_frags(&local->hw, vif, sta, skbs); +} + static inline void drv_get_et_strings(struct ieee80211_sub_if_data *sdata, u32 sset, u8 *data) { @@ -837,33 +845,4 @@ drv_allow_buffered_frames(struct ieee80211_local *local, more_data); trace_drv_return_void(local); } - -static inline int drv_get_rssi(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, - struct ieee80211_sta *sta, - s8 *rssi_dbm) -{ - int ret; - - might_sleep(); - - ret = local->ops->get_rssi(&local->hw, &sdata->vif, sta, rssi_dbm); - trace_drv_get_rssi(local, sta, *rssi_dbm, ret); - - return ret; -} - -static inline void drv_mgd_prepare_tx(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata) -{ - might_sleep(); - - check_sdata_in_driver(sdata); - WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION); - - trace_drv_mgd_prepare_tx(local, sdata); - if (local->ops->mgd_prepare_tx) - local->ops->mgd_prepare_tx(&local->hw, &sdata->vif); - trace_drv_return_void(local); -} #endif /* __MAC80211_DRIVER_OPS */ diff --git a/trunk/net/mac80211/driver-trace.c b/trunk/net/mac80211/driver-trace.c new file mode 100644 index 000000000000..8ed8711b1a6d --- /dev/null +++ b/trunk/net/mac80211/driver-trace.c @@ -0,0 +1,9 @@ +/* bug in tracepoint.h, it should include this */ +#include + +/* sparse isn't too happy with all macros... */ +#ifndef __CHECKER__ +#include "driver-ops.h" +#define CREATE_TRACE_POINTS +#include "driver-trace.h" +#endif diff --git a/trunk/net/mac80211/trace.h b/trunk/net/mac80211/driver-trace.h similarity index 95% rename from trunk/net/mac80211/trace.h rename to trunk/net/mac80211/driver-trace.h index e1e9d10ec2e7..6de00b2c268c 100644 --- a/trunk/net/mac80211/trace.h +++ b/trunk/net/mac80211/driver-trace.h @@ -1218,39 +1218,6 @@ DEFINE_EVENT(release_evt, drv_allow_buffered_frames, TP_ARGS(local, sta, tids, num_frames, reason, more_data) ); -TRACE_EVENT(drv_get_rssi, - TP_PROTO(struct ieee80211_local *local, struct ieee80211_sta *sta, - s8 rssi, int ret), - - TP_ARGS(local, sta, rssi, ret), - - TP_STRUCT__entry( - LOCAL_ENTRY - STA_ENTRY - __field(s8, rssi) - __field(int, ret) - ), - - TP_fast_assign( - LOCAL_ASSIGN; - STA_ASSIGN; - __entry->rssi = rssi; - __entry->ret = ret; - ), - - TP_printk( - LOCAL_PR_FMT STA_PR_FMT " rssi:%d ret:%d", - LOCAL_PR_ARG, STA_PR_ARG, __entry->rssi, __entry->ret - ) -); - -DEFINE_EVENT(local_sdata_evt, drv_mgd_prepare_tx, - TP_PROTO(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata), - - TP_ARGS(local, sdata) -); - /* * Tracing for API calls that drivers call. */ @@ -1639,49 +1606,10 @@ TRACE_EVENT(stop_queue, LOCAL_PR_ARG, __entry->queue, __entry->reason ) ); - -#ifdef CONFIG_MAC80211_MESSAGE_TRACING -#undef TRACE_SYSTEM -#define TRACE_SYSTEM mac80211_msg - -#define MAX_MSG_LEN 100 - -DECLARE_EVENT_CLASS(mac80211_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(mac80211_msg_event, mac80211_info, - TP_PROTO(struct va_format *vaf), - TP_ARGS(vaf) -); -DEFINE_EVENT(mac80211_msg_event, mac80211_dbg, - TP_PROTO(struct va_format *vaf), - TP_ARGS(vaf) -); -DEFINE_EVENT(mac80211_msg_event, mac80211_err, - TP_PROTO(struct va_format *vaf), - TP_ARGS(vaf) -); -#endif - #endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */ #undef TRACE_INCLUDE_PATH #define TRACE_INCLUDE_PATH . #undef TRACE_INCLUDE_FILE -#define TRACE_INCLUDE_FILE trace +#define TRACE_INCLUDE_FILE driver-trace #include diff --git a/trunk/net/mac80211/ht.c b/trunk/net/mac80211/ht.c index 4b4538d63925..6f8615c54b22 100644 --- a/trunk/net/mac80211/ht.c +++ b/trunk/net/mac80211/ht.c @@ -305,10 +305,12 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12; initiator = (params & IEEE80211_DELBA_PARAM_INITIATOR_MASK) >> 11; - ht_dbg_ratelimited(sdata, "delba from %pM (%s) tid %d reason code %d\n", - mgmt->sa, initiator ? "initiator" : "recipient", - tid, - le16_to_cpu(mgmt->u.action.u.delba.reason_code)); +#ifdef CONFIG_MAC80211_HT_DEBUG + net_dbg_ratelimited("delba from %pM (%s) tid %d reason code %d\n", + mgmt->sa, initiator ? "initiator" : "recipient", + tid, + le16_to_cpu(mgmt->u.action.u.delba.reason_code)); +#endif /* CONFIG_MAC80211_HT_DEBUG */ if (initiator == WLAN_BACK_INITIATOR) __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_INITIATOR, 0, diff --git a/trunk/net/mac80211/ibss.c b/trunk/net/mac80211/ibss.c index 5746d62faba1..725cb4be229d 100644 --- a/trunk/net/mac80211/ibss.c +++ b/trunk/net/mac80211/ibss.c @@ -261,7 +261,11 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta, memcpy(addr, sta->sta.addr, ETH_ALEN); - ibss_dbg(sdata, "Adding new IBSS station %pM\n", addr); +#ifdef CONFIG_MAC80211_VERBOSE_DEBUG + wiphy_debug(sdata->local->hw.wiphy, + "Adding new IBSS station %pM (dev=%s)\n", + addr, sdata->name); +#endif sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC); @@ -275,10 +279,9 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta, /* If it fails, maybe we raced another insertion? */ if (sta_info_insert_rcu(sta)) return sta_info_get(sdata, addr); - if (auth && !sdata->u.ibss.auth_frame_registrations) { - ibss_dbg(sdata, - "TX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=1)\n", - sdata->vif.addr, sdata->u.ibss.bssid, addr); + if (auth) { + ibss_vdbg("TX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=1)\n", + sdata->vif.addr, sdata->u.ibss.bssid, addr); ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, NULL, 0, addr, sdata->u.ibss.bssid, NULL, 0, 0); } @@ -301,7 +304,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, * allow new one to be added. */ if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) { - net_info_ratelimited("%s: No room for a new IBSS STA entry %pM\n", + net_dbg_ratelimited("%s: No room for a new IBSS STA entry %pM\n", sdata->name, addr); rcu_read_lock(); return NULL; @@ -348,9 +351,9 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata, if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) return; - ibss_dbg(sdata, - "RX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=%d)\n", - mgmt->sa, mgmt->da, mgmt->bssid, auth_transaction); + ibss_vdbg("%s: RX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=%d)\n", + sdata->name, mgmt->sa, mgmt->da, mgmt->bssid, + auth_transaction); sta_info_destroy_addr(sdata, mgmt->sa); ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 0, false); rcu_read_unlock(); @@ -413,10 +416,10 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, ieee80211_mandatory_rates(local, band); if (sta->sta.supp_rates[band] != prev_rates) { - ibss_dbg(sdata, - "updated supp_rates set for %pM based on beacon/probe_resp (0x%x -> 0x%x)\n", - sta->sta.addr, prev_rates, - sta->sta.supp_rates[band]); + ibss_vdbg("%s: updated supp_rates set for %pM based on beacon/probe_resp (0x%x -> 0x%x)\n", + sdata->name, sta->sta.addr, + prev_rates, + sta->sta.supp_rates[band]); rates_updated = true; } } else { @@ -531,18 +534,16 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, rx_timestamp = drv_get_tsf(local, sdata); } - ibss_dbg(sdata, - "RX beacon SA=%pM BSSID=%pM TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n", - mgmt->sa, mgmt->bssid, - (unsigned long long)rx_timestamp, - (unsigned long long)beacon_timestamp, - (unsigned long long)(rx_timestamp - beacon_timestamp), - jiffies); + ibss_vdbg("RX beacon SA=%pM BSSID=%pM TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n", + mgmt->sa, mgmt->bssid, + (unsigned long long)rx_timestamp, + (unsigned long long)beacon_timestamp, + (unsigned long long)(rx_timestamp - beacon_timestamp), + jiffies); if (beacon_timestamp > rx_timestamp) { - ibss_dbg(sdata, - "beacon TSF higher than local TSF - IBSS merge with BSSID %pM\n", - mgmt->bssid); + ibss_vdbg("%s: beacon TSF higher than local TSF - IBSS merge with BSSID %pM\n", + sdata->name, mgmt->bssid); ieee80211_sta_join_ibss(sdata, bss); supp_rates = ieee80211_sta_get_rates(local, elems, band, NULL); ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, @@ -568,7 +569,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata, * allow new one to be added. */ if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) { - net_info_ratelimited("%s: No room for a new IBSS STA entry %pM\n", + net_dbg_ratelimited("%s: No room for a new IBSS STA entry %pM\n", sdata->name, addr); return; } @@ -644,8 +645,8 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata) if (ifibss->fixed_channel) return; - sdata_info(sdata, - "No active IBSS STAs - trying to scan for other IBSS networks with same SSID (merge)\n"); + pr_debug("%s: No active IBSS STAs - trying to scan for other IBSS networks with same SSID (merge)\n", + sdata->name); ieee80211_request_internal_scan(sdata, ifibss->ssid, ifibss->ssid_len, NULL); @@ -673,7 +674,8 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) bssid[0] |= 0x02; } - sdata_info(sdata, "Creating new IBSS network, BSSID %pM\n", bssid); + pr_debug("%s: Creating new IBSS network, BSSID %pM\n", + sdata->name, bssid); capability = WLAN_CAPABILITY_IBSS; @@ -704,7 +706,8 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) lockdep_assert_held(&ifibss->mtx); active_ibss = ieee80211_sta_active_ibss(sdata); - ibss_dbg(sdata, "sta_find_ibss (active_ibss=%d)\n", active_ibss); + ibss_vdbg("%s: sta_find_ibss (active_ibss=%d)\n", + sdata->name, active_ibss); if (active_ibss) return; @@ -727,24 +730,23 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) struct ieee80211_bss *bss; bss = (void *)cbss->priv; - ibss_dbg(sdata, - "sta_find_ibss: selected %pM current %pM\n", - cbss->bssid, ifibss->bssid); - sdata_info(sdata, - "Selected IBSS BSSID %pM based on configured SSID\n", - cbss->bssid); + ibss_vdbg(" sta_find_ibss: selected %pM current %pM\n", + cbss->bssid, ifibss->bssid); + pr_debug("%s: Selected IBSS BSSID %pM based on configured SSID\n", + sdata->name, cbss->bssid); ieee80211_sta_join_ibss(sdata, bss); ieee80211_rx_bss_put(local, bss); return; } - ibss_dbg(sdata, "sta_find_ibss: did not try to join ibss\n"); + ibss_vdbg(" did not try to join ibss\n"); /* Selected IBSS not found in current scan results - try to scan */ if (time_after(jiffies, ifibss->last_scan_completed + IEEE80211_SCAN_INTERVAL)) { - sdata_info(sdata, "Trigger new scan to find an IBSS to join\n"); + pr_debug("%s: Trigger new scan to find an IBSS to join\n", + sdata->name); ieee80211_request_internal_scan(sdata, ifibss->ssid, ifibss->ssid_len, @@ -758,8 +760,9 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) ieee80211_sta_create_ibss(sdata); return; } - sdata_info(sdata, "IBSS not allowed on %d MHz\n", - local->hw.conf.channel->center_freq); + pr_debug("%s: IBSS not allowed on %d MHz\n", + sdata->name, + local->hw.conf.channel->center_freq); /* No IBSS found - decrease scan interval and continue * scanning. */ @@ -794,9 +797,9 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, tx_last_beacon = drv_tx_last_beacon(local); - ibss_dbg(sdata, - "RX ProbeReq SA=%pM DA=%pM BSSID=%pM (tx_last_beacon=%d)\n", - mgmt->sa, mgmt->da, mgmt->bssid, tx_last_beacon); + ibss_vdbg("%s: RX ProbeReq SA=%pM DA=%pM BSSID=%pM (tx_last_beacon=%d)\n", + sdata->name, mgmt->sa, mgmt->da, + mgmt->bssid, tx_last_beacon); if (!tx_last_beacon && is_multicast_ether_addr(mgmt->da)) return; @@ -809,8 +812,8 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, pos = mgmt->u.probe_req.variable; if (pos[0] != WLAN_EID_SSID || pos + 2 + pos[1] > end) { - ibss_dbg(sdata, "Invalid SSID IE in ProbeReq from %pM\n", - mgmt->sa); + ibss_vdbg("%s: Invalid SSID IE in ProbeReq from %pM\n", + sdata->name, mgmt->sa); return; } if (pos[1] != 0 && @@ -827,7 +830,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, resp = (struct ieee80211_mgmt *) skb->data; memcpy(resp->da, mgmt->sa, ETH_ALEN); - ibss_dbg(sdata, "Sending ProbeResp to %pM\n", resp->da); + ibss_vdbg("%s: Sending ProbeResp to %pM\n", sdata->name, resp->da); IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; ieee80211_tx_skb(sdata, skb); } diff --git a/trunk/net/mac80211/ieee80211_i.h b/trunk/net/mac80211/ieee80211_i.h index e0423f8c0ce1..e6cbf5b68c89 100644 --- a/trunk/net/mac80211/ieee80211_i.h +++ b/trunk/net/mac80211/ieee80211_i.h @@ -30,7 +30,6 @@ #include #include "key.h" #include "sta_info.h" -#include "debug.h" struct ieee80211_local; @@ -56,14 +55,11 @@ struct ieee80211_local; #define TU_TO_JIFFIES(x) (usecs_to_jiffies((x) * 1024)) #define TU_TO_EXP_TIME(x) (jiffies + TU_TO_JIFFIES(x)) -/* - * Some APs experience problems when working with U-APSD. Decrease the - * probability of that happening by using legacy mode for all ACs but VO. - * The AP that caused us trouble was a Cisco 4410N. It ignores our - * setting, and always treats non-VO ACs as legacy. - */ #define IEEE80211_DEFAULT_UAPSD_QUEUES \ - IEEE80211_WMM_IE_STA_QOSINFO_AC_VO + (IEEE80211_WMM_IE_STA_QOSINFO_AC_BK | \ + IEEE80211_WMM_IE_STA_QOSINFO_AC_BE | \ + IEEE80211_WMM_IE_STA_QOSINFO_AC_VI | \ + IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) #define IEEE80211_DEFAULT_MAX_SP_LEN \ IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL @@ -512,7 +508,6 @@ struct ieee80211_if_ibss { bool privacy; bool control_port; - unsigned int auth_frame_registrations; u8 bssid[ETH_ALEN] __aligned(2); u8 ssid[IEEE80211_MAX_SSID_LEN]; @@ -682,9 +677,6 @@ struct ieee80211_sub_if_data { /* TID bitmap for NoAck policy */ u16 noack_map; - /* bit field of ACM bits (BIT(802.1D tag)) */ - u8 wmm_acm; - struct ieee80211_key __rcu *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS]; struct ieee80211_key __rcu *default_unicast_key; struct ieee80211_key __rcu *default_multicast_key; @@ -889,9 +881,6 @@ struct ieee80211_local { /* device is started */ bool started; - /* device is during a HW reconfig */ - bool in_reconfig; - /* wowlan is enabled -- don't reconfig on resume */ bool wowlan; @@ -1030,6 +1019,7 @@ struct ieee80211_local { int total_ps_buffered; /* total number of all buffered unicast and * multicast packets for power saving stations */ + unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ bool pspolling; bool offchannel_ps_enabled; @@ -1284,6 +1274,7 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, enum nl80211_iftype type); void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata); void ieee80211_remove_interfaces(struct ieee80211_local *local); +u32 __ieee80211_recalc_idle(struct ieee80211_local *local); void ieee80211_recalc_idle(struct ieee80211_local *local); void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata, const int offset); @@ -1480,16 +1471,6 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, struct ieee80211_channel *channel, enum nl80211_channel_type channel_type, u16 prot_mode); -u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, - u32 cap); -int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata, - struct sk_buff *skb, bool need_basic); -int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata, - struct sk_buff *skb, bool need_basic); - -/* virtual monitor */ -int ieee80211_add_virtual_monitor(struct ieee80211_local *local); -void ieee80211_del_virtual_monitor(struct ieee80211_local *local); /* channel management */ enum ieee80211_chan_mode { diff --git a/trunk/net/mac80211/iface.c b/trunk/net/mac80211/iface.c index fbef7a1ada7a..87aeb4f21ffd 100644 --- a/trunk/net/mac80211/iface.c +++ b/trunk/net/mac80211/iface.c @@ -43,127 +43,6 @@ */ -static u32 ieee80211_idle_off(struct ieee80211_local *local, - const char *reason) -{ - if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE)) - return 0; - - local->hw.conf.flags &= ~IEEE80211_CONF_IDLE; - return IEEE80211_CONF_CHANGE_IDLE; -} - -static u32 ieee80211_idle_on(struct ieee80211_local *local) -{ - if (local->hw.conf.flags & IEEE80211_CONF_IDLE) - return 0; - - drv_flush(local, false); - - local->hw.conf.flags |= IEEE80211_CONF_IDLE; - return IEEE80211_CONF_CHANGE_IDLE; -} - -static u32 __ieee80211_recalc_idle(struct ieee80211_local *local) -{ - struct ieee80211_sub_if_data *sdata; - int count = 0; - bool working = false, scanning = false; - unsigned int led_trig_start = 0, led_trig_stop = 0; - struct ieee80211_roc_work *roc; - -#ifdef CONFIG_PROVE_LOCKING - WARN_ON(debug_locks && !lockdep_rtnl_is_held() && - !lockdep_is_held(&local->iflist_mtx)); -#endif - lockdep_assert_held(&local->mtx); - - list_for_each_entry(sdata, &local->interfaces, list) { - if (!ieee80211_sdata_running(sdata)) { - sdata->vif.bss_conf.idle = true; - continue; - } - - sdata->old_idle = sdata->vif.bss_conf.idle; - - /* do not count disabled managed interfaces */ - if (sdata->vif.type == NL80211_IFTYPE_STATION && - !sdata->u.mgd.associated && - !sdata->u.mgd.auth_data && - !sdata->u.mgd.assoc_data) { - sdata->vif.bss_conf.idle = true; - continue; - } - /* do not count unused IBSS interfaces */ - if (sdata->vif.type == NL80211_IFTYPE_ADHOC && - !sdata->u.ibss.ssid_len) { - sdata->vif.bss_conf.idle = true; - continue; - } - /* count everything else */ - sdata->vif.bss_conf.idle = false; - count++; - } - - if (!local->ops->remain_on_channel) { - list_for_each_entry(roc, &local->roc_list, list) { - working = true; - roc->sdata->vif.bss_conf.idle = false; - } - } - - if (local->scan_sdata && - !(local->hw.flags & IEEE80211_HW_SCAN_WHILE_IDLE)) { - scanning = true; - local->scan_sdata->vif.bss_conf.idle = false; - } - - list_for_each_entry(sdata, &local->interfaces, list) { - if (sdata->vif.type == NL80211_IFTYPE_MONITOR || - sdata->vif.type == NL80211_IFTYPE_AP_VLAN) - continue; - if (sdata->old_idle == sdata->vif.bss_conf.idle) - continue; - if (!ieee80211_sdata_running(sdata)) - continue; - ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE); - } - - if (working || scanning) - led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_WORK; - else - led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_WORK; - - if (count) - led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED; - else - led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED; - - ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop); - - if (working) - return ieee80211_idle_off(local, "working"); - if (scanning) - return ieee80211_idle_off(local, "scanning"); - if (!count) - return ieee80211_idle_on(local); - else - return ieee80211_idle_off(local, "in use"); - - return 0; -} - -void ieee80211_recalc_idle(struct ieee80211_local *local) -{ - u32 chg; - - mutex_lock(&local->iflist_mtx); - chg = __ieee80211_recalc_idle(local); - mutex_unlock(&local->iflist_mtx); - if (chg) - ieee80211_hw_config(local, chg); -} - static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) { int meshhdrlen; @@ -178,6 +57,9 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) return -EINVAL; } +#ifdef CONFIG_MAC80211_VERBOSE_DEBUG + pr_debug("%s: setting MTU %d\n", dev->name, new_mtu); +#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ dev->mtu = new_mtu; return 0; } @@ -218,12 +100,15 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata, { struct ieee80211_local *local = sdata->local; struct ieee80211_sub_if_data *nsdata; + struct net_device *dev = sdata->dev; ASSERT_RTNL(); /* we hold the RTNL here so can safely walk the list */ list_for_each_entry(nsdata, &local->interfaces, list) { - if (nsdata != sdata && ieee80211_sdata_running(nsdata)) { + struct net_device *ndev = nsdata->dev; + + if (ndev != dev && ieee80211_sdata_running(nsdata)) { /* * Allow only a single IBSS interface to be up at any * time. This is restricted because beacon distribution @@ -242,8 +127,7 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata, * The remaining checks are only performed for interfaces * with the same MAC address. */ - if (!ether_addr_equal(sdata->vif.addr, - nsdata->vif.addr)) + if (!ether_addr_equal(dev->dev_addr, ndev->dev_addr)) continue; /* @@ -330,7 +214,7 @@ static void ieee80211_set_default_queues(struct ieee80211_sub_if_data *sdata) sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE; } -int ieee80211_add_virtual_monitor(struct ieee80211_local *local) +static int ieee80211_add_virtual_monitor(struct ieee80211_local *local) { struct ieee80211_sub_if_data *sdata; int ret; @@ -371,7 +255,7 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local) return 0; } -void ieee80211_del_virtual_monitor(struct ieee80211_local *local) +static void ieee80211_del_virtual_monitor(struct ieee80211_local *local) { struct ieee80211_sub_if_data *sdata; @@ -487,6 +371,12 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) break; } + if (local->monitors == 0 && local->open_count == 0) { + res = ieee80211_add_virtual_monitor(local); + if (res) + goto err_stop; + } + /* must be before the call to ieee80211_configure_filter */ local->monitors++; if (local->monitors == 1) { @@ -501,6 +391,8 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) break; default: if (coming_up) { + ieee80211_del_virtual_monitor(local); + res = drv_add_interface(local, sdata); if (res) goto err_stop; @@ -735,6 +627,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, if (local->monitors == 0) { local->hw.conf.flags &= ~IEEE80211_CONF_MONITOR; hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR; + ieee80211_del_virtual_monitor(local); } ieee80211_adjust_monitor_flags(sdata, -1); @@ -808,6 +701,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, } } spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); + + if (local->monitors == local->open_count && local->monitors > 0) + ieee80211_add_virtual_monitor(local); } static int ieee80211_stop(struct net_device *dev) @@ -912,7 +808,7 @@ static u16 ieee80211_monitor_select_queue(struct net_device *dev, hdr = (void *)((u8 *)skb->data + le16_to_cpu(rtap->it_len)); - return ieee80211_select_queue_80211(sdata, skb, hdr); + return ieee80211_select_queue_80211(local, skb, hdr); } static const struct net_device_ops ieee80211_monitorif_ops = { @@ -1327,7 +1223,7 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local, if (__ffs64(mask) + hweight64(mask) != fls64(mask)) { /* not a contiguous mask ... not handled now! */ - pr_info("not contiguous\n"); + pr_debug("not contiguous\n"); break; } @@ -1512,6 +1408,135 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local) list_del(&unreg_list); } +static u32 ieee80211_idle_off(struct ieee80211_local *local, + const char *reason) +{ + if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE)) + return 0; + +#ifdef CONFIG_MAC80211_VERBOSE_DEBUG + wiphy_debug(local->hw.wiphy, "device no longer idle - %s\n", reason); +#endif + + local->hw.conf.flags &= ~IEEE80211_CONF_IDLE; + return IEEE80211_CONF_CHANGE_IDLE; +} + +static u32 ieee80211_idle_on(struct ieee80211_local *local) +{ + if (local->hw.conf.flags & IEEE80211_CONF_IDLE) + return 0; + +#ifdef CONFIG_MAC80211_VERBOSE_DEBUG + wiphy_debug(local->hw.wiphy, "device now idle\n"); +#endif + + drv_flush(local, false); + + local->hw.conf.flags |= IEEE80211_CONF_IDLE; + return IEEE80211_CONF_CHANGE_IDLE; +} + +u32 __ieee80211_recalc_idle(struct ieee80211_local *local) +{ + struct ieee80211_sub_if_data *sdata; + int count = 0; + bool working = false, scanning = false; + unsigned int led_trig_start = 0, led_trig_stop = 0; + struct ieee80211_roc_work *roc; + +#ifdef CONFIG_PROVE_LOCKING + WARN_ON(debug_locks && !lockdep_rtnl_is_held() && + !lockdep_is_held(&local->iflist_mtx)); +#endif + lockdep_assert_held(&local->mtx); + + list_for_each_entry(sdata, &local->interfaces, list) { + if (!ieee80211_sdata_running(sdata)) { + sdata->vif.bss_conf.idle = true; + continue; + } + + sdata->old_idle = sdata->vif.bss_conf.idle; + + /* do not count disabled managed interfaces */ + if (sdata->vif.type == NL80211_IFTYPE_STATION && + !sdata->u.mgd.associated && + !sdata->u.mgd.auth_data && + !sdata->u.mgd.assoc_data) { + sdata->vif.bss_conf.idle = true; + continue; + } + /* do not count unused IBSS interfaces */ + if (sdata->vif.type == NL80211_IFTYPE_ADHOC && + !sdata->u.ibss.ssid_len) { + sdata->vif.bss_conf.idle = true; + continue; + } + /* count everything else */ + sdata->vif.bss_conf.idle = false; + count++; + } + + if (!local->ops->remain_on_channel) { + list_for_each_entry(roc, &local->roc_list, list) { + working = true; + roc->sdata->vif.bss_conf.idle = false; + } + } + + if (local->scan_sdata && + !(local->hw.flags & IEEE80211_HW_SCAN_WHILE_IDLE)) { + scanning = true; + local->scan_sdata->vif.bss_conf.idle = false; + } + + list_for_each_entry(sdata, &local->interfaces, list) { + if (sdata->vif.type == NL80211_IFTYPE_MONITOR || + sdata->vif.type == NL80211_IFTYPE_AP_VLAN) + continue; + if (sdata->old_idle == sdata->vif.bss_conf.idle) + continue; + if (!ieee80211_sdata_running(sdata)) + continue; + ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE); + } + + if (working || scanning) + led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_WORK; + else + led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_WORK; + + if (count) + led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED; + else + led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED; + + ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop); + + if (working) + return ieee80211_idle_off(local, "working"); + if (scanning) + return ieee80211_idle_off(local, "scanning"); + if (!count) + return ieee80211_idle_on(local); + else + return ieee80211_idle_off(local, "in use"); + + return 0; +} + +void ieee80211_recalc_idle(struct ieee80211_local *local) +{ + u32 chg; + + mutex_lock(&local->iflist_mtx); + chg = __ieee80211_recalc_idle(local); + mutex_unlock(&local->iflist_mtx); + if (chg) + ieee80211_hw_config(local, chg); +} + static int netdev_notify(struct notifier_block *nb, unsigned long state, void *ndev) diff --git a/trunk/net/mac80211/key.c b/trunk/net/mac80211/key.c index b3b7e526e245..5bb600d93d77 100644 --- a/trunk/net/mac80211/key.c +++ b/trunk/net/mac80211/key.c @@ -139,7 +139,7 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) } if (ret != -ENOSPC && ret != -EOPNOTSUPP) - sdata_err(sdata, + wiphy_err(key->local->hw.wiphy, "failed to set key (%d, %pM) to hardware (%d)\n", key->conf.keyidx, sta ? sta->sta.addr : bcast_addr, ret); @@ -186,7 +186,7 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) sta ? &sta->sta : NULL, &key->conf); if (ret) - sdata_err(sdata, + wiphy_err(key->local->hw.wiphy, "failed to remove key (%d, %pM) from hardware (%d)\n", key->conf.keyidx, sta ? sta->sta.addr : bcast_addr, ret); diff --git a/trunk/net/mac80211/main.c b/trunk/net/mac80211/main.c index c794101f8987..d81c178c7712 100644 --- a/trunk/net/mac80211/main.c +++ b/trunk/net/mac80211/main.c @@ -345,13 +345,6 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw) ieee80211_stop_queues_by_reason(hw, IEEE80211_QUEUE_STOP_REASON_SUSPEND); - /* - * Stop all Rx during the reconfig. We don't want state changes - * or driver callbacks while this is in progress. - */ - local->in_reconfig = true; - barrier(); - schedule_work(&local->restart_work); } EXPORT_SYMBOL(ieee80211_restart_hw); @@ -462,9 +455,7 @@ static const struct ieee80211_txrx_stypes ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { [NL80211_IFTYPE_ADHOC] = { .tx = 0xffff, - .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | - BIT(IEEE80211_STYPE_AUTH >> 4) | - BIT(IEEE80211_STYPE_DEAUTH >> 4), + .rx = BIT(IEEE80211_STYPE_ACTION >> 4), }, [NL80211_IFTYPE_STATION] = { .tx = 0xffff, @@ -587,7 +578,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, local->hw.priv = (char *)local + ALIGN(sizeof(*local), NETDEV_ALIGN); - BUG_ON(!ops->tx); + BUG_ON(!ops->tx && !ops->tx_frags); BUG_ON(!ops->start); BUG_ON(!ops->stop); BUG_ON(!ops->config); @@ -688,7 +679,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) int result, i; enum ieee80211_band band; int channels, max_bitrates; - bool supp_ht, supp_vht; + bool supp_ht; netdev_features_t feature_whitelist; static const u32 cipher_suites[] = { /* keep WEP first, it may be removed below */ @@ -706,11 +697,12 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) local->hw.offchannel_tx_hw_queue >= local->hw.queues)) return -EINVAL; + if ((hw->wiphy->wowlan.flags || hw->wiphy->wowlan.n_patterns) #ifdef CONFIG_PM - if ((hw->wiphy->wowlan.flags || hw->wiphy->wowlan.n_patterns) && - (!local->ops->suspend || !local->ops->resume)) - return -EINVAL; + && (!local->ops->suspend || !local->ops->resume) #endif + ) + return -EINVAL; if ((hw->flags & IEEE80211_HW_SCAN_WHILE_IDLE) && !local->ops->hw_scan) return -EINVAL; @@ -732,7 +724,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) channels = 0; max_bitrates = 0; supp_ht = false; - supp_vht = false; for (band = 0; band < IEEE80211_NUM_BANDS; band++) { struct ieee80211_supported_band *sband; @@ -750,7 +741,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) if (max_bitrates < sband->n_bitrates) max_bitrates = sband->n_bitrates; supp_ht = supp_ht || sband->ht_cap.ht_supported; - supp_vht = supp_vht || sband->vht_cap.vht_supported; } local->int_scan_req = kzalloc(sizeof(*local->int_scan_req) + @@ -826,10 +816,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) if (supp_ht) local->scan_ies_len += 2 + sizeof(struct ieee80211_ht_cap); - if (supp_vht) - local->scan_ies_len += - 2 + sizeof(struct ieee80211_vht_capabilities); - if (!local->ops->hw_scan) { /* For hw_scan, driver needs to set these up. */ local->hw.wiphy->max_scan_ssids = 4; diff --git a/trunk/net/mac80211/mesh.c b/trunk/net/mac80211/mesh.c index 764593d65fc3..7cf19509fb68 100644 --- a/trunk/net/mac80211/mesh.c +++ b/trunk/net/mac80211/mesh.c @@ -443,7 +443,7 @@ static void ieee80211_mesh_path_root_timer(unsigned long data) void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh) { - if (ifmsh->mshcfg.dot11MeshHWMPRootMode > IEEE80211_ROOTMODE_ROOT) + if (ifmsh->mshcfg.dot11MeshHWMPRootMode) set_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags); else { clear_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags); @@ -523,6 +523,10 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata, { bool free_plinks; +#ifdef CONFIG_MAC80211_VERBOSE_DEBUG + pr_debug("%s: running mesh housekeeping\n", sdata->name); +#endif + ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT); mesh_path_expire(sdata); @@ -537,17 +541,11 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata, static void ieee80211_mesh_rootpath(struct ieee80211_sub_if_data *sdata) { struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; - u32 interval; mesh_path_tx_root_frame(sdata); - - if (ifmsh->mshcfg.dot11MeshHWMPRootMode == IEEE80211_PROACTIVE_RANN) - interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval; - else - interval = ifmsh->mshcfg.dot11MeshHWMProotInterval; - mod_timer(&ifmsh->mesh_path_root_timer, - round_jiffies(TU_TO_EXP_TIME(interval))); + round_jiffies(TU_TO_EXP_TIME( + ifmsh->mshcfg.dot11MeshHWMPRannInterval))); } #ifdef CONFIG_PM diff --git a/trunk/net/mac80211/mesh.h b/trunk/net/mac80211/mesh.h index faaa39bcfd10..e3642756f8f4 100644 --- a/trunk/net/mac80211/mesh.h +++ b/trunk/net/mac80211/mesh.h @@ -104,7 +104,6 @@ enum mesh_deferred_task_flags { * an mpath to a hash bucket on a path table. * @rann_snd_addr: the RANN sender address * @rann_metric: the aggregated path metric towards the root node - * @last_preq_to_root: Timestamp of last PREQ sent to root * @is_root: the destination station of this path is a root node * @is_gate: the destination station of this path is a mesh gate * @@ -132,7 +131,6 @@ struct mesh_path { spinlock_t state_lock; u8 rann_snd_addr[ETH_ALEN]; u32 rann_metric; - unsigned long last_preq_to_root; bool is_root; bool is_gate; }; @@ -247,7 +245,7 @@ void mesh_rmc_free(struct ieee80211_sub_if_data *sdata); int mesh_rmc_init(struct ieee80211_sub_if_data *sdata); void ieee80211s_init(void); void ieee80211s_update_metric(struct ieee80211_local *local, - struct sta_info *sta, struct sk_buff *skb); + struct sta_info *stainfo, struct sk_buff *skb); void ieee80211s_stop(void); void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata); void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata); diff --git a/trunk/net/mac80211/mesh_hwmp.c b/trunk/net/mac80211/mesh_hwmp.c index fb7b6a11d0ba..fa7c58035246 100644 --- a/trunk/net/mac80211/mesh_hwmp.c +++ b/trunk/net/mac80211/mesh_hwmp.c @@ -13,6 +13,13 @@ #include "wme.h" #include "mesh.h" +#ifdef CONFIG_MAC80211_VERBOSE_MHWMP_DEBUG +#define mhwmp_dbg(fmt, args...) \ + pr_debug("Mesh HWMP (%s): " fmt "\n", sdata->name, ##args) +#else +#define mhwmp_dbg(fmt, args...) do { (void)(0); } while (0) +#endif + #define TEST_FRAME_LEN 8192 #define MAX_METRIC 0xffffffff #define ARITH_SHIFT 8 @@ -91,8 +98,6 @@ static inline u32 u16_field_get(u8 *preq_elem, int offset, bool ae) #define max_preq_retries(s) (s->u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries) #define disc_timeout_jiff(s) \ msecs_to_jiffies(sdata->u.mesh.mshcfg.min_discovery_timeout) -#define root_path_confirmation_jiffies(s) \ - msecs_to_jiffies(sdata->u.mesh.mshcfg.dot11MeshHWMPconfirmationInterval) enum mpath_frame_type { MPATH_PREQ = 0, @@ -137,19 +142,19 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, switch (action) { case MPATH_PREQ: - mhwmp_dbg(sdata, "sending PREQ to %pM\n", target); + mhwmp_dbg("sending PREQ to %pM", target); ie_len = 37; pos = skb_put(skb, 2 + ie_len); *pos++ = WLAN_EID_PREQ; break; case MPATH_PREP: - mhwmp_dbg(sdata, "sending PREP to %pM\n", target); + mhwmp_dbg("sending PREP to %pM", target); ie_len = 31; pos = skb_put(skb, 2 + ie_len); *pos++ = WLAN_EID_PREP; break; case MPATH_RANN: - mhwmp_dbg(sdata, "sending RANN from %pM\n", orig_addr); + mhwmp_dbg("sending RANN from %pM", orig_addr); ie_len = sizeof(struct ieee80211_rann_ie); pos = skb_put(skb, 2 + ie_len); *pos++ = WLAN_EID_RANN; @@ -298,7 +303,7 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, } void ieee80211s_update_metric(struct ieee80211_local *local, - struct sta_info *sta, struct sk_buff *skb) + struct sta_info *stainfo, struct sk_buff *skb) { struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; @@ -310,14 +315,15 @@ void ieee80211s_update_metric(struct ieee80211_local *local, failed = !(txinfo->flags & IEEE80211_TX_STAT_ACK); /* moving average, scaled to 100 */ - sta->fail_avg = ((80 * sta->fail_avg + 5) / 100 + 20 * failed); - if (sta->fail_avg > 95) - mesh_plink_broken(sta); + stainfo->fail_avg = ((80 * stainfo->fail_avg + 5) / 100 + 20 * failed); + if (stainfo->fail_avg > 95) + mesh_plink_broken(stainfo); } static u32 airtime_link_metric_get(struct ieee80211_local *local, struct sta_info *sta) { + struct ieee80211_supported_band *sband; struct rate_info rinfo; /* This should be adjusted for each device */ int device_constant = 1 << ARITH_SHIFT; @@ -327,6 +333,8 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local, u32 tx_time, estimated_retx; u64 result; + sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; + if (sta->fail_avg >= 100) return MAX_METRIC; @@ -511,11 +519,10 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, struct mesh_path *mpath = NULL; u8 *target_addr, *orig_addr; const u8 *da; - u8 target_flags, ttl, flags; - u32 orig_sn, target_sn, lifetime, orig_metric; + u8 target_flags, ttl; + u32 orig_sn, target_sn, lifetime; bool reply = false; bool forward = true; - bool root_is_gate; /* Update target SN, if present */ target_addr = PREQ_IE_TARGET_ADDR(preq_elem); @@ -523,15 +530,11 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, target_sn = PREQ_IE_TARGET_SN(preq_elem); orig_sn = PREQ_IE_ORIG_SN(preq_elem); target_flags = PREQ_IE_TARGET_F(preq_elem); - orig_metric = metric; - /* Proactive PREQ gate announcements */ - flags = PREQ_IE_FLAGS(preq_elem); - root_is_gate = !!(flags & RANN_FLAG_IS_GATE); - mhwmp_dbg(sdata, "received PREQ from %pM\n", orig_addr); + mhwmp_dbg("received PREQ from %pM", orig_addr); if (ether_addr_equal(target_addr, sdata->vif.addr)) { - mhwmp_dbg(sdata, "PREQ is for us\n"); + mhwmp_dbg("PREQ is for us"); forward = false; reply = true; metric = 0; @@ -541,22 +544,6 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, target_sn = ++ifmsh->sn; ifmsh->last_sn_update = jiffies; } - } else if (is_broadcast_ether_addr(target_addr) && - (target_flags & IEEE80211_PREQ_TO_FLAG)) { - rcu_read_lock(); - mpath = mesh_path_lookup(orig_addr, sdata); - if (mpath) { - if (flags & IEEE80211_PREQ_PROACTIVE_PREP_FLAG) { - reply = true; - target_addr = sdata->vif.addr; - target_sn = ++ifmsh->sn; - metric = 0; - ifmsh->last_sn_update = jiffies; - } - if (root_is_gate) - mesh_path_add_gate(mpath); - } - rcu_read_unlock(); } else { rcu_read_lock(); mpath = mesh_path_lookup(target_addr, sdata); @@ -583,20 +570,19 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, lifetime = PREQ_IE_LIFETIME(preq_elem); ttl = ifmsh->mshcfg.element_ttl; if (ttl != 0) { - mhwmp_dbg(sdata, "replying to the PREQ\n"); + mhwmp_dbg("replying to the PREQ"); mesh_path_sel_frame_tx(MPATH_PREP, 0, orig_addr, cpu_to_le32(orig_sn), 0, target_addr, cpu_to_le32(target_sn), mgmt->sa, 0, ttl, cpu_to_le32(lifetime), cpu_to_le32(metric), 0, sdata); - } else { + } else ifmsh->mshstats.dropped_frames_ttl++; - } } if (forward && ifmsh->mshcfg.dot11MeshForwarding) { u32 preq_id; - u8 hopcount; + u8 hopcount, flags; ttl = PREQ_IE_TTL(preq_elem); lifetime = PREQ_IE_LIFETIME(preq_elem); @@ -604,19 +590,13 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, ifmsh->mshstats.dropped_frames_ttl++; return; } - mhwmp_dbg(sdata, "forwarding the PREQ from %pM\n", orig_addr); + mhwmp_dbg("forwarding the PREQ from %pM", orig_addr); --ttl; + flags = PREQ_IE_FLAGS(preq_elem); preq_id = PREQ_IE_PREQ_ID(preq_elem); hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1; da = (mpath && mpath->is_root) ? mpath->rann_snd_addr : broadcast_addr; - - if (flags & IEEE80211_PREQ_PROACTIVE_PREP_FLAG) { - target_addr = PREQ_IE_TARGET_ADDR(preq_elem); - target_sn = PREQ_IE_TARGET_SN(preq_elem); - metric = orig_metric; - } - mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr, cpu_to_le32(orig_sn), target_flags, target_addr, cpu_to_le32(target_sn), da, @@ -651,8 +631,7 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata, u8 next_hop[ETH_ALEN]; u32 target_sn, orig_sn, lifetime; - mhwmp_dbg(sdata, "received PREP from %pM\n", - PREP_IE_ORIG_ADDR(prep_elem)); + mhwmp_dbg("received PREP from %pM", PREP_IE_ORIG_ADDR(prep_elem)); orig_addr = PREP_IE_ORIG_ADDR(prep_elem); if (ether_addr_equal(orig_addr, sdata->vif.addr)) @@ -765,6 +744,11 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, bool root_is_gate; ttl = rann->rann_ttl; + if (ttl <= 1) { + ifmsh->mshstats.dropped_frames_ttl++; + return; + } + ttl--; flags = rann->rann_flags; root_is_gate = !!(flags & RANN_FLAG_IS_GATE); orig_addr = rann->rann_addr; @@ -778,9 +762,8 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, if (ether_addr_equal(orig_addr, sdata->vif.addr)) return; - mhwmp_dbg(sdata, - "received RANN from %pM via neighbour %pM (is_gate=%d)\n", - orig_addr, mgmt->sa, root_is_gate); + mhwmp_dbg("received RANN from %pM via neighbour %pM (is_gate=%d)", + orig_addr, mgmt->sa, root_is_gate); rcu_read_lock(); sta = sta_info_get(sdata, mgmt->sa); @@ -802,50 +785,34 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, } } - if (!(SN_LT(mpath->sn, orig_sn)) && - !(mpath->sn == orig_sn && metric < mpath->rann_metric)) { - rcu_read_unlock(); - return; - } - if ((!(mpath->flags & (MESH_PATH_ACTIVE | MESH_PATH_RESOLVING)) || - (time_after(jiffies, mpath->last_preq_to_root + - root_path_confirmation_jiffies(sdata)) || - time_before(jiffies, mpath->last_preq_to_root))) && - !(mpath->flags & MESH_PATH_FIXED) && (ttl != 0)) { - mhwmp_dbg(sdata, - "time to refresh root mpath %pM\n", - orig_addr); + time_after(jiffies, mpath->exp_time - 1*HZ)) && + !(mpath->flags & MESH_PATH_FIXED)) { + mhwmp_dbg("%s time to refresh root mpath %pM", sdata->name, + orig_addr); mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH); - mpath->last_preq_to_root = jiffies; - } - - mpath->sn = orig_sn; - mpath->rann_metric = metric + metric_txsta; - mpath->is_root = true; - /* Recording RANNs sender address to send individually - * addressed PREQs destined for root mesh STA */ - memcpy(mpath->rann_snd_addr, mgmt->sa, ETH_ALEN); - - if (root_is_gate) - mesh_path_add_gate(mpath); - - if (ttl <= 1) { - ifmsh->mshstats.dropped_frames_ttl++; - rcu_read_unlock(); - return; } - ttl--; - if (ifmsh->mshcfg.dot11MeshForwarding) { + if ((SN_LT(mpath->sn, orig_sn) || (mpath->sn == orig_sn && + metric < mpath->rann_metric)) && ifmsh->mshcfg.dot11MeshForwarding) { mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr, cpu_to_le32(orig_sn), 0, NULL, 0, broadcast_addr, hopcount, ttl, cpu_to_le32(interval), cpu_to_le32(metric + metric_txsta), 0, sdata); + mpath->sn = orig_sn; + mpath->rann_metric = metric + metric_txsta; + /* Recording RANNs sender address to send individually + * addressed PREQs destined for root mesh STA */ + memcpy(mpath->rann_snd_addr, mgmt->sa, ETH_ALEN); } + mpath->is_root = true; + + if (root_is_gate) + mesh_path_add_gate(mpath); + rcu_read_unlock(); } @@ -922,7 +889,7 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags) preq_node = kmalloc(sizeof(struct mesh_preq_queue), GFP_ATOMIC); if (!preq_node) { - mhwmp_dbg(sdata, "could not allocate PREQ node\n"); + mhwmp_dbg("could not allocate PREQ node"); return; } @@ -931,7 +898,7 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags) spin_unlock_bh(&ifmsh->mesh_preq_queue_lock); kfree(preq_node); if (printk_ratelimit()) - mhwmp_dbg(sdata, "PREQ node queue full\n"); + mhwmp_dbg("PREQ node queue full"); return; } @@ -1179,7 +1146,7 @@ void mesh_path_timer(unsigned long data) if (!mpath->is_gate && mesh_gate_num(sdata) > 0) { ret = mesh_path_send_to_gates(mpath); if (ret) - mhwmp_dbg(sdata, "no gate was reachable\n"); + mhwmp_dbg("no gate was reachable"); } else mesh_path_flush_pending(mpath); } @@ -1190,34 +1157,13 @@ mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata) { struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; u32 interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval; - u8 flags, target_flags = 0; + u8 flags; flags = (ifmsh->mshcfg.dot11MeshGateAnnouncementProtocol) ? RANN_FLAG_IS_GATE : 0; - - switch (ifmsh->mshcfg.dot11MeshHWMPRootMode) { - case IEEE80211_PROACTIVE_RANN: - mesh_path_sel_frame_tx(MPATH_RANN, flags, sdata->vif.addr, + mesh_path_sel_frame_tx(MPATH_RANN, flags, sdata->vif.addr, cpu_to_le32(++ifmsh->sn), 0, NULL, 0, broadcast_addr, - 0, ifmsh->mshcfg.element_ttl, + 0, sdata->u.mesh.mshcfg.element_ttl, cpu_to_le32(interval), 0, 0, sdata); - break; - case IEEE80211_PROACTIVE_PREQ_WITH_PREP: - flags |= IEEE80211_PREQ_PROACTIVE_PREP_FLAG; - case IEEE80211_PROACTIVE_PREQ_NO_PREP: - interval = ifmsh->mshcfg.dot11MeshHWMPactivePathToRootTimeout; - target_flags |= IEEE80211_PREQ_TO_FLAG | - IEEE80211_PREQ_USN_FLAG; - mesh_path_sel_frame_tx(MPATH_PREQ, flags, sdata->vif.addr, - cpu_to_le32(++ifmsh->sn), target_flags, - (u8 *) broadcast_addr, 0, broadcast_addr, - 0, ifmsh->mshcfg.element_ttl, - cpu_to_le32(interval), - 0, cpu_to_le32(ifmsh->preq_id++), sdata); - break; - default: - mhwmp_dbg(sdata, "Proactive mechanism not supported\n"); - return; - } } diff --git a/trunk/net/mac80211/mesh_pathtbl.c b/trunk/net/mac80211/mesh_pathtbl.c index c9ae931dd693..572f706fd65b 100644 --- a/trunk/net/mac80211/mesh_pathtbl.c +++ b/trunk/net/mac80211/mesh_pathtbl.c @@ -18,6 +18,12 @@ #include "ieee80211_i.h" #include "mesh.h" +#ifdef CONFIG_MAC80211_VERBOSE_MPATH_DEBUG +#define mpath_dbg(fmt, args...) pr_debug(fmt, ##args) +#else +#define mpath_dbg(fmt, args...) do { (void)(0); } while (0) +#endif + /* There will be initially 2^INIT_PATHS_SIZE_ORDER buckets */ #define INIT_PATHS_SIZE_ORDER 2 @@ -316,8 +322,9 @@ static void mesh_path_move_to_queue(struct mesh_path *gate_mpath, spin_lock_irqsave(&gate_mpath->frame_queue.lock, flags); skb_queue_splice(&gateq, &gate_mpath->frame_queue); - mpath_dbg(gate_mpath->sdata, "Mpath queue for gate %pM has %d frames\n", - gate_mpath->dst, skb_queue_len(&gate_mpath->frame_queue)); + mpath_dbg("Mpath queue for gate %pM has %d frames\n", + gate_mpath->dst, + skb_queue_len(&gate_mpath->frame_queue)); spin_unlock_irqrestore(&gate_mpath->frame_queue.lock, flags); if (!copy) @@ -439,9 +446,9 @@ int mesh_path_add_gate(struct mesh_path *mpath) hlist_add_head_rcu(&new_gate->list, tbl->known_gates); spin_unlock_bh(&tbl->gates_lock); rcu_read_unlock(); - mpath_dbg(mpath->sdata, - "Mesh path: Recorded new gate: %pM. %d known gates\n", - mpath->dst, mpath->sdata->u.mesh.num_gates); + mpath_dbg("Mesh path (%s): Recorded new gate: %pM. %d known gates\n", + mpath->sdata->name, mpath->dst, + mpath->sdata->u.mesh.num_gates); return 0; err_rcu: rcu_read_unlock(); @@ -470,8 +477,8 @@ static int mesh_gate_del(struct mesh_table *tbl, struct mesh_path *mpath) spin_unlock_bh(&tbl->gates_lock); mpath->sdata->u.mesh.num_gates--; mpath->is_gate = false; - mpath_dbg(mpath->sdata, - "Mesh path: Deleted gate: %pM. %d known gates\n", + mpath_dbg("Mesh path (%s): Deleted gate: %pM. " + "%d known gates\n", mpath->sdata->name, mpath->dst, mpath->sdata->u.mesh.num_gates); break; } @@ -939,20 +946,19 @@ int mesh_path_send_to_gates(struct mesh_path *mpath) continue; if (gate->mpath->flags & MESH_PATH_ACTIVE) { - mpath_dbg(sdata, "Forwarding to %pM\n", gate->mpath->dst); + mpath_dbg("Forwarding to %pM\n", gate->mpath->dst); mesh_path_move_to_queue(gate->mpath, from_mpath, copy); from_mpath = gate->mpath; copy = true; } else { - mpath_dbg(sdata, - "Not forwarding %p (flags %#x)\n", - gate->mpath, gate->mpath->flags); + mpath_dbg("Not forwarding %p\n", gate->mpath); + mpath_dbg("flags %x\n", gate->mpath->flags); } } hlist_for_each_entry_rcu(gate, n, known_gates, list) if (gate->mpath->sdata == sdata) { - mpath_dbg(sdata, "Sending to %pM\n", gate->mpath->dst); + mpath_dbg("Sending to %pM\n", gate->mpath->dst); mesh_path_tx_pending(gate->mpath); } diff --git a/trunk/net/mac80211/mesh_plink.c b/trunk/net/mac80211/mesh_plink.c index 425685914d7d..be4fad128c34 100644 --- a/trunk/net/mac80211/mesh_plink.c +++ b/trunk/net/mac80211/mesh_plink.c @@ -13,6 +13,12 @@ #include "rate.h" #include "mesh.h" +#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG +#define mpl_dbg(fmt, args...) pr_debug(fmt, ##args) +#else +#define mpl_dbg(fmt, args...) do { (void)(0); } while (0) +#endif + #define PLINK_GET_LLID(p) (p + 2) #define PLINK_GET_PLID(p) (p + 4) @@ -128,14 +134,12 @@ static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata) switch (sta->ch_type) { case NL80211_CHAN_NO_HT: - mpl_dbg(sdata, - "mesh_plink %pM: nonHT sta (%pM) is present\n", + mpl_dbg("mesh_plink %pM: nonHT sta (%pM) is present", sdata->vif.addr, sta->sta.addr); non_ht_sta = true; goto out; case NL80211_CHAN_HT20: - mpl_dbg(sdata, - "mesh_plink %pM: HT20 sta (%pM) is present\n", + mpl_dbg("mesh_plink %pM: HT20 sta (%pM) is present", sdata->vif.addr, sta->sta.addr); ht20_sta = true; default: @@ -156,8 +160,7 @@ static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata) sdata->vif.bss_conf.ht_operation_mode = ht_opmode; sdata->u.mesh.mshcfg.ht_opmode = ht_opmode; changed = BSS_CHANGED_HT; - mpl_dbg(sdata, - "mesh_plink %pM: protection mode changed to %d\n", + mpl_dbg("mesh_plink %pM: protection mode changed to %d", sdata->vif.addr, ht_opmode); } @@ -258,8 +261,8 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, pos = skb_put(skb, 2); memcpy(pos + 2, &plid, 2); } - if (ieee80211_add_srates_ie(sdata, skb, true) || - ieee80211_add_ext_srates_ie(sdata, skb, true) || + if (ieee80211_add_srates_ie(&sdata->vif, skb, true) || + ieee80211_add_ext_srates_ie(&sdata->vif, skb, true) || mesh_add_rsn_ie(skb, sdata) || mesh_add_meshid_ie(skb, sdata) || mesh_add_meshconf_ie(skb, sdata)) @@ -434,8 +437,7 @@ static void mesh_plink_timer(unsigned long data) spin_unlock_bh(&sta->lock); return; } - mpl_dbg(sta->sdata, - "Mesh plink timer for %pM fired on state %d\n", + mpl_dbg("Mesh plink timer for %pM fired on state %d\n", sta->sta.addr, sta->plink_state); reason = 0; llid = sta->llid; @@ -448,8 +450,7 @@ static void mesh_plink_timer(unsigned long data) /* retry timer */ if (sta->plink_retries < dot11MeshMaxRetries(sdata)) { u32 rand; - mpl_dbg(sta->sdata, - "Mesh plink for %pM (retry, timeout): %d %d\n", + mpl_dbg("Mesh plink for %pM (retry, timeout): %d %d\n", sta->sta.addr, sta->plink_retries, sta->plink_timeout); get_random_bytes(&rand, sizeof(u32)); @@ -529,8 +530,7 @@ int mesh_plink_open(struct sta_info *sta) sta->plink_state = NL80211_PLINK_OPN_SNT; mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); spin_unlock_bh(&sta->lock); - mpl_dbg(sdata, - "Mesh plink: starting establishment with %pM\n", + mpl_dbg("Mesh plink: starting establishment with %pM\n", sta->sta.addr); return mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN, @@ -565,6 +565,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m u8 *baseaddr; u32 changed = 0; __le16 plid, llid, reason; +#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG static const char *mplstates[] = { [NL80211_PLINK_LISTEN] = "LISTEN", [NL80211_PLINK_OPN_SNT] = "OPN-SNT", @@ -574,14 +575,14 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m [NL80211_PLINK_HOLDING] = "HOLDING", [NL80211_PLINK_BLOCKED] = "BLOCKED" }; +#endif /* need action_code, aux */ if (len < IEEE80211_MIN_ACTION_SIZE + 3) return; if (is_multicast_ether_addr(mgmt->da)) { - mpl_dbg(sdata, - "Mesh plink: ignore frame from multicast address\n"); + mpl_dbg("Mesh plink: ignore frame from multicast address"); return; } @@ -594,14 +595,12 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m } ieee802_11_parse_elems(baseaddr, len - baselen, &elems); if (!elems.peering) { - mpl_dbg(sdata, - "Mesh plink: missing necessary peer link ie\n"); + mpl_dbg("Mesh plink: missing necessary peer link ie\n"); return; } if (elems.rsn_len && sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) { - mpl_dbg(sdata, - "Mesh plink: can't establish link with secure peer\n"); + mpl_dbg("Mesh plink: can't establish link with secure peer\n"); return; } @@ -611,15 +610,14 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m (ftype == WLAN_SP_MESH_PEERING_CONFIRM && ie_len != 6) || (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len != 6 && ie_len != 8)) { - mpl_dbg(sdata, - "Mesh plink: incorrect plink ie length %d %d\n", - ftype, ie_len); + mpl_dbg("Mesh plink: incorrect plink ie length %d %d\n", + ftype, ie_len); return; } if (ftype != WLAN_SP_MESH_PEERING_CLOSE && (!elems.mesh_id || !elems.mesh_config)) { - mpl_dbg(sdata, "Mesh plink: missing necessary ie\n"); + mpl_dbg("Mesh plink: missing necessary ie\n"); return; } /* Note the lines below are correct, the llid in the frame is the plid @@ -634,21 +632,21 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m sta = sta_info_get(sdata, mgmt->sa); if (!sta && ftype != WLAN_SP_MESH_PEERING_OPEN) { - mpl_dbg(sdata, "Mesh plink: cls or cnf from unknown peer\n"); + mpl_dbg("Mesh plink: cls or cnf from unknown peer\n"); rcu_read_unlock(); return; } if (ftype == WLAN_SP_MESH_PEERING_OPEN && !rssi_threshold_check(sta, sdata)) { - mpl_dbg(sdata, "Mesh plink: %pM does not meet rssi threshold\n", + mpl_dbg("Mesh plink: %pM does not meet rssi threshold\n", mgmt->sa); rcu_read_unlock(); return; } if (sta && !test_sta_flag(sta, WLAN_STA_AUTH)) { - mpl_dbg(sdata, "Mesh plink: Action frame from non-authed peer\n"); + mpl_dbg("Mesh plink: Action frame from non-authed peer\n"); rcu_read_unlock(); return; } @@ -685,7 +683,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m } else if (!sta) { /* ftype == WLAN_SP_MESH_PEERING_OPEN */ if (!mesh_plink_free_count(sdata)) { - mpl_dbg(sdata, "Mesh plink error: no more free plinks\n"); + mpl_dbg("Mesh plink error: no more free plinks\n"); rcu_read_unlock(); return; } @@ -726,7 +724,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m event = CLS_ACPT; break; default: - mpl_dbg(sdata, "Mesh plink: unknown frame subtype\n"); + mpl_dbg("Mesh plink: unknown frame subtype\n"); rcu_read_unlock(); return; } @@ -736,14 +734,13 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m /* allocate sta entry if necessary and update info */ sta = mesh_peer_init(sdata, mgmt->sa, &elems); if (!sta) { - mpl_dbg(sdata, "Mesh plink: failed to init peer!\n"); + mpl_dbg("Mesh plink: failed to init peer!\n"); rcu_read_unlock(); return; } } - mpl_dbg(sdata, - "Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n", + mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n", mgmt->sa, mplstates[sta->plink_state], le16_to_cpu(sta->llid), le16_to_cpu(sta->plid), event); @@ -854,7 +851,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m mesh_plink_inc_estab_count(sdata); changed |= mesh_set_ht_prot_mode(sdata); changed |= BSS_CHANGED_BEACON; - mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n", + mpl_dbg("Mesh plink with %pM ESTABLISHED\n", sta->sta.addr); break; default: @@ -890,7 +887,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m mesh_plink_inc_estab_count(sdata); changed |= mesh_set_ht_prot_mode(sdata); changed |= BSS_CHANGED_BEACON; - mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n", + mpl_dbg("Mesh plink with %pM ESTABLISHED\n", sta->sta.addr); mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CONFIRM, diff --git a/trunk/net/mac80211/mesh_sync.c b/trunk/net/mac80211/mesh_sync.c index accfa00ffcdf..0ccdad49f987 100644 --- a/trunk/net/mac80211/mesh_sync.c +++ b/trunk/net/mac80211/mesh_sync.c @@ -12,6 +12,13 @@ #include "mesh.h" #include "driver-ops.h" +#ifdef CONFIG_MAC80211_VERBOSE_MESH_SYNC_DEBUG +#define msync_dbg(fmt, args...) \ + pr_debug("Mesh sync (%s): " fmt "\n", sdata->name, ##args) +#else +#define msync_dbg(fmt, args...) do { (void)(0); } while (0) +#endif + /* This is not in the standard. It represents a tolerable tbtt drift below * which we do no TSF adjustment. */ @@ -58,14 +65,14 @@ void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata) spin_lock_bh(&ifmsh->sync_offset_lock); if (ifmsh->sync_offset_clockdrift_max < beacon_int_fraction) { - msync_dbg(sdata, "TBTT : max clockdrift=%lld; adjusting\n", - (long long) ifmsh->sync_offset_clockdrift_max); + msync_dbg("TBTT : max clockdrift=%lld; adjusting", + (long long) ifmsh->sync_offset_clockdrift_max); tsfdelta = -ifmsh->sync_offset_clockdrift_max; ifmsh->sync_offset_clockdrift_max = 0; } else { - msync_dbg(sdata, "TBTT : max clockdrift=%lld; adjusting by %llu\n", - (long long) ifmsh->sync_offset_clockdrift_max, - (unsigned long long) beacon_int_fraction); + msync_dbg("TBTT : max clockdrift=%lld; adjusting by %llu", + (long long) ifmsh->sync_offset_clockdrift_max, + (unsigned long long) beacon_int_fraction); tsfdelta = -beacon_int_fraction; ifmsh->sync_offset_clockdrift_max -= beacon_int_fraction; } @@ -113,7 +120,7 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, if (elems->mesh_config && mesh_peer_tbtt_adjusting(elems)) { clear_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN); - msync_dbg(sdata, "STA %pM : is adjusting TBTT\n", sta->sta.addr); + msync_dbg("STA %pM : is adjusting TBTT", sta->sta.addr); goto no_sync; } @@ -162,8 +169,7 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) { s64 t_clockdrift = sta->t_offset_setpoint - sta->t_offset; - msync_dbg(sdata, - "STA %pM : sta->t_offset=%lld, sta->t_offset_setpoint=%lld, t_clockdrift=%lld\n", + msync_dbg("STA %pM : sta->t_offset=%lld, sta->t_offset_setpoint=%lld, t_clockdrift=%lld", sta->sta.addr, (long long) sta->t_offset, (long long) @@ -172,8 +178,7 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, if (t_clockdrift > TOFFSET_MAXIMUM_ADJUSTMENT || t_clockdrift < -TOFFSET_MAXIMUM_ADJUSTMENT) { - msync_dbg(sdata, - "STA %pM : t_clockdrift=%lld too large, setpoint reset\n", + msync_dbg("STA %pM : t_clockdrift=%lld too large, setpoint reset", sta->sta.addr, (long long) t_clockdrift); clear_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN); @@ -192,8 +197,8 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, } else { sta->t_offset_setpoint = sta->t_offset - TOFFSET_SET_MARGIN; set_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN); - msync_dbg(sdata, - "STA %pM : offset was invalid, sta->t_offset=%lld\n", + msync_dbg("STA %pM : offset was invalid, " + " sta->t_offset=%lld", sta->sta.addr, (long long) sta->t_offset); rcu_read_unlock(); @@ -221,15 +226,17 @@ static void mesh_sync_offset_adjust_tbtt(struct ieee80211_sub_if_data *sdata) * to the driver tsf setter, we punt * the tsf adjustment to the mesh tasklet */ - msync_dbg(sdata, - "TBTT : kicking off TBTT adjustment with clockdrift_max=%lld\n", - ifmsh->sync_offset_clockdrift_max); + msync_dbg("TBTT : kicking off TBTT " + "adjustment with " + "clockdrift_max=%lld", + ifmsh->sync_offset_clockdrift_max); set_bit(MESH_WORK_DRIFT_ADJUST, &ifmsh->wrkq_flags); } else { - msync_dbg(sdata, - "TBTT : max clockdrift=%lld; too small to adjust\n", - (long long)ifmsh->sync_offset_clockdrift_max); + msync_dbg("TBTT : max clockdrift=%lld; " + "too small to adjust", + (long long) + ifmsh->sync_offset_clockdrift_max); ifmsh->sync_offset_clockdrift_max = 0; } spin_unlock_bh(&ifmsh->sync_offset_lock); @@ -261,7 +268,7 @@ static void mesh_sync_vendor_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, const u8 *oui; WARN_ON(sdata->u.mesh.mesh_sp_id != IEEE80211_SYNC_METHOD_VENDOR); - msync_dbg(sdata, "called mesh_sync_vendor_rx_bcn_presp\n"); + msync_dbg("called mesh_sync_vendor_rx_bcn_presp"); oui = mesh_get_vendor_oui(sdata); /* here you would implement the vendor offset tracking for this oui */ } @@ -271,7 +278,7 @@ static void mesh_sync_vendor_adjust_tbtt(struct ieee80211_sub_if_data *sdata) const u8 *oui; WARN_ON(sdata->u.mesh.mesh_sp_id != IEEE80211_SYNC_METHOD_VENDOR); - msync_dbg(sdata, "called mesh_sync_vendor_adjust_tbtt\n"); + msync_dbg("called mesh_sync_vendor_adjust_tbtt"); oui = mesh_get_vendor_oui(sdata); /* here you would implement the vendor tsf adjustment for this oui */ } diff --git a/trunk/net/mac80211/mlme.c b/trunk/net/mac80211/mlme.c index f49f14f8ba82..d7134c170336 100644 --- a/trunk/net/mac80211/mlme.c +++ b/trunk/net/mac80211/mlme.c @@ -541,8 +541,6 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) memcpy(pos, assoc_data->ie + offset, noffset - offset); } - drv_mgd_prepare_tx(local, sdata); - IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; ieee80211_tx_skb(sdata, skb); } @@ -582,9 +580,6 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, if (!(ifmgd->flags & IEEE80211_STA_MFP_ENABLED)) IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; - - drv_mgd_prepare_tx(local, sdata); - ieee80211_tx_skb(sdata, skb); } } @@ -907,6 +902,9 @@ static bool ieee80211_powersave_allowed(struct ieee80211_sub_if_data *sdata) if (!mgd->associated) return false; + if (!mgd->associated->beacon_ies) + return false; + if (mgd->flags & (IEEE80211_STA_BEACON_POLL | IEEE80211_STA_CONNECTION_POLL)) return false; @@ -1143,7 +1141,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, memset(¶ms, 0, sizeof(params)); - sdata->wmm_acm = 0; + local->wmm_acm = 0; for (; left >= 4; left -= 4, pos += 4) { int aci = (pos[0] >> 5) & 0x03; int acm = (pos[0] >> 4) & 0x01; @@ -1154,21 +1152,21 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, case 1: /* AC_BK */ queue = 3; if (acm) - sdata->wmm_acm |= BIT(1) | BIT(2); /* BK/- */ + local->wmm_acm |= BIT(1) | BIT(2); /* BK/- */ if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK) uapsd = true; break; case 2: /* AC_VI */ queue = 1; if (acm) - sdata->wmm_acm |= BIT(4) | BIT(5); /* CL/VI */ + local->wmm_acm |= BIT(4) | BIT(5); /* CL/VI */ if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI) uapsd = true; break; case 3: /* AC_VO */ queue = 0; if (acm) - sdata->wmm_acm |= BIT(6) | BIT(7); /* VO/NC */ + local->wmm_acm |= BIT(6) | BIT(7); /* VO/NC */ if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) uapsd = true; break; @@ -1176,7 +1174,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, default: queue = 2; if (acm) - sdata->wmm_acm |= BIT(0) | BIT(3); /* BE/EE */ + local->wmm_acm |= BIT(0) | BIT(3); /* BE/EE */ if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE) uapsd = true; break; @@ -1188,16 +1186,19 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, params.txop = get_unaligned_le16(pos + 2); params.uapsd = uapsd; - mlme_dbg(sdata, - "WMM queue=%d aci=%d acm=%d aifs=%d cWmin=%d cWmax=%d txop=%d uapsd=%d\n", - queue, aci, acm, - params.aifs, params.cw_min, params.cw_max, - params.txop, params.uapsd); +#ifdef CONFIG_MAC80211_VERBOSE_DEBUG + wiphy_debug(local->hw.wiphy, + "WMM queue=%d aci=%d acm=%d aifs=%d " + "cWmin=%d cWmax=%d txop=%d uapsd=%d\n", + queue, aci, acm, + params.aifs, params.cw_min, params.cw_max, + params.txop, params.uapsd); +#endif sdata->tx_conf[queue] = params; if (drv_conf_tx(local, sdata, queue, ¶ms)) - sdata_err(sdata, - "failed to set TX queue parameters for queue %d\n", - queue); + wiphy_debug(local->hw.wiphy, + "failed to set TX queue parameters for queue %d\n", + queue); } /* enable WMM or activate new settings */ @@ -1274,7 +1275,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, bss_info_changed |= BSS_CHANGED_BEACON_INT; bss_info_changed |= ieee80211_handle_bss_capability(sdata, - bss_conf->assoc_capability, bss->has_erp_value, bss->erp_value); + cbss->capability, bss->has_erp_value, bss->erp_value); sdata->u.mgd.beacon_timeout = usecs_to_jiffies(ieee80211_tu_to_usec( IEEE80211_BEACON_LOSS_COUNT * bss_conf->beacon_int)); @@ -1326,6 +1327,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, struct ieee80211_local *local = sdata->local; struct sta_info *sta; u32 changed = 0; + u8 bssid[ETH_ALEN]; ASSERT_MGD_MTX(ifmgd); @@ -1335,9 +1337,10 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, if (WARN_ON(!ifmgd->associated)) return; - ieee80211_stop_poll(sdata); + memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); ifmgd->associated = NULL; + memset(ifmgd->bssid, 0, ETH_ALEN); /* * we need to commit the associated = NULL change because the @@ -1357,29 +1360,22 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, netif_carrier_off(sdata->dev); mutex_lock(&local->sta_mtx); - sta = sta_info_get(sdata, ifmgd->bssid); + sta = sta_info_get(sdata, bssid); if (sta) { set_sta_flag(sta, WLAN_STA_BLOCK_BA); ieee80211_sta_tear_down_BA_sessions(sta, tx); } mutex_unlock(&local->sta_mtx); - /* flush out any pending frame (e.g. DELBA) before deauth/disassoc */ - if (tx) - drv_flush(local, false); - /* deauthenticate/disassociate now */ if (tx || frame_buf) - ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid, stype, - reason, tx, frame_buf); + ieee80211_send_deauth_disassoc(sdata, bssid, stype, reason, + tx, frame_buf); /* flush out frame */ if (tx) drv_flush(local, false); - /* clear bssid only after building the needed mgmt frames */ - memset(ifmgd->bssid, 0, ETH_ALEN); - /* remove AP and TDLS peers */ sta_info_flush(local, sdata); @@ -1569,10 +1565,11 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, goto out; } +#ifdef CONFIG_MAC80211_VERBOSE_DEBUG if (beacon) - mlme_dbg_ratelimited(sdata, - "detected beacon loss from AP - sending probe request\n"); - + net_dbg_ratelimited("%s: detected beacon loss from AP - sending probe request\n", + sdata->name); +#endif ieee80211_cqm_rssi_notify(&sdata->vif, NL80211_CQM_RSSI_BEACON_LOSS_EVENT, GFP_KERNEL); @@ -1616,7 +1613,6 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw, { struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; - struct cfg80211_bss *cbss; struct sk_buff *skb; const u8 *ssid; int ssid_len; @@ -1626,22 +1622,16 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw, ASSERT_MGD_MTX(ifmgd); - if (ifmgd->associated) - cbss = ifmgd->associated; - else if (ifmgd->auth_data) - cbss = ifmgd->auth_data->bss; - else if (ifmgd->assoc_data) - cbss = ifmgd->assoc_data->bss; - else + if (!ifmgd->associated) return NULL; - ssid = ieee80211_bss_get_ie(cbss, WLAN_EID_SSID); + ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); if (WARN_ON_ONCE(ssid == NULL)) ssid_len = 0; else ssid_len = ssid[1]; - skb = ieee80211_build_probe_req(sdata, cbss->bssid, + skb = ieee80211_build_probe_req(sdata, ifmgd->associated->bssid, (u32) -1, ssid + 2, ssid_len, NULL, 0, true); @@ -1664,7 +1654,7 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata) memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); - sdata_info(sdata, "Connection to AP %pM lost\n", bssid); + pr_debug("%s: Connection to AP %pM lost\n", sdata->name, bssid); ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, @@ -1760,7 +1750,6 @@ static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata, if (!elems.challenge) return; auth_data->expected_transaction = 4; - drv_mgd_prepare_tx(sdata->local, sdata); ieee80211_send_auth(sdata, 3, auth_data->algorithm, elems.challenge - 2, elems.challenge_len + 2, auth_data->bss->bssid, auth_data->bss->bssid, @@ -1799,8 +1788,8 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, return RX_MGMT_NONE; if (status_code != WLAN_STATUS_SUCCESS) { - sdata_info(sdata, "%pM denied authentication (status %d)\n", - mgmt->sa, status_code); + pr_debug("%s: %pM denied authentication (status %d)\n", + sdata->name, mgmt->sa, status_code); ieee80211_destroy_auth_data(sdata, false); return RX_MGMT_CFG80211_RX_AUTH; } @@ -1823,7 +1812,7 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, return RX_MGMT_NONE; } - sdata_info(sdata, "authenticated\n"); + pr_debug("%s: authenticated\n", sdata->name); ifmgd->auth_data->done = true; ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC; run_again(ifmgd, ifmgd->auth_data->timeout); @@ -1836,7 +1825,7 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, goto out_err; } if (sta_info_move_state(sta, IEEE80211_STA_AUTH)) { - sdata_info(sdata, "failed moving %pM to auth\n", bssid); + pr_debug("%s: failed moving %pM to auth\n", sdata->name, bssid); goto out_err; } mutex_unlock(&sdata->local->sta_mtx); @@ -1870,8 +1859,8 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); - sdata_info(sdata, "deauthenticated from %pM (Reason: %u)\n", - bssid, reason_code); + pr_debug("%s: deauthenticated from %pM (Reason: %u)\n", + sdata->name, bssid, reason_code); ieee80211_set_disassoc(sdata, 0, 0, false, NULL); @@ -1901,8 +1890,8 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); - sdata_info(sdata, "disassociated from %pM (Reason: %u)\n", - mgmt->sa, reason_code); + pr_debug("%s: disassociated from %pM (Reason: %u)\n", + sdata->name, mgmt->sa, reason_code); ieee80211_set_disassoc(sdata, 0, 0, false, NULL); @@ -1994,15 +1983,15 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) - sdata_info(sdata, "invalid AID value 0x%x; bits 15:14 not set\n", - aid); + pr_debug("%s: invalid AID value 0x%x; bits 15:14 not set\n", + sdata->name, aid); aid &= ~(BIT(15) | BIT(14)); ifmgd->broken_ap = false; if (aid == 0 || aid > IEEE80211_MAX_AID) { - sdata_info(sdata, "invalid AID value %d (out of range), turn off PS\n", - aid); + pr_debug("%s: invalid AID value %d (out of range), turn off PS\n", + sdata->name, aid); aid = 0; ifmgd->broken_ap = true; } @@ -2011,7 +2000,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); if (!elems.supp_rates) { - sdata_info(sdata, "no SuppRates element in AssocResp\n"); + pr_debug("%s: no SuppRates element in AssocResp\n", + sdata->name); return false; } @@ -2051,9 +2041,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, if (!err && !(ifmgd->flags & IEEE80211_STA_CONTROL_PORT)) err = sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED); if (err) { - sdata_info(sdata, - "failed to move station %pM to desired state\n", - sta->sta.addr); + pr_debug("%s: failed to move station %pM to desired state\n", + sdata->name, sta->sta.addr); WARN_ON(__sta_info_destroy(sta)); mutex_unlock(&sdata->local->sta_mtx); return false; @@ -2136,10 +2125,9 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); aid = le16_to_cpu(mgmt->u.assoc_resp.aid); - sdata_info(sdata, - "RX %sssocResp from %pM (capab=0x%x status=%d aid=%d)\n", - reassoc ? "Rea" : "A", mgmt->sa, - capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14)))); + pr_debug("%s: RX %sssocResp from %pM (capab=0x%x status=%d aid=%d)\n", + sdata->name, reassoc ? "Rea" : "A", mgmt->sa, + capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14)))); pos = mgmt->u.assoc_resp.variable; ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); @@ -2150,9 +2138,8 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, u32 tu, ms; tu = get_unaligned_le32(elems.timeout_int + 1); ms = tu * 1024 / 1000; - sdata_info(sdata, - "%pM rejected association temporarily; comeback duration %u TU (%u ms)\n", - mgmt->sa, tu, ms); + pr_debug("%s: %pM rejected association temporarily; comeback duration %u TU (%u ms)\n", + sdata->name, mgmt->sa, tu, ms); assoc_data->timeout = jiffies + msecs_to_jiffies(ms); if (ms > IEEE80211_ASSOC_TIMEOUT) run_again(ifmgd, assoc_data->timeout); @@ -2162,17 +2149,19 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, *bss = assoc_data->bss; if (status_code != WLAN_STATUS_SUCCESS) { - sdata_info(sdata, "%pM denied association (code=%d)\n", - mgmt->sa, status_code); + pr_debug("%s: %pM denied association (code=%d)\n", + sdata->name, mgmt->sa, status_code); ieee80211_destroy_assoc_data(sdata, false); } else { + pr_debug("%s: associated\n", sdata->name); + if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) { /* oops -- internal error -- send timeout for now */ - ieee80211_destroy_assoc_data(sdata, false); + ieee80211_destroy_assoc_data(sdata, true); + sta_info_destroy_addr(sdata, mgmt->bssid); cfg80211_put_bss(*bss); return RX_MGMT_CFG80211_ASSOC_TIMEOUT; } - sdata_info(sdata, "associated\n"); /* * destroy assoc_data afterwards, as otherwise an idle @@ -2272,7 +2261,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, if (ifmgd->auth_data && !ifmgd->auth_data->bss->proberesp_ies && ether_addr_equal(mgmt->bssid, ifmgd->auth_data->bss->bssid)) { /* got probe response, continue with auth */ - sdata_info(sdata, "direct probe responded\n"); + pr_debug("%s: direct probe responded\n", sdata->name); ifmgd->auth_data->tries = 0; ifmgd->auth_data->timeout = jiffies; run_again(ifmgd, ifmgd->auth_data->timeout); @@ -2408,8 +2397,10 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, } if (ifmgd->flags & IEEE80211_STA_BEACON_POLL) { - mlme_dbg_ratelimited(sdata, - "cancelling probereq poll due to a received beacon\n"); +#ifdef CONFIG_MAC80211_VERBOSE_DEBUG + net_dbg_ratelimited("%s: cancelling probereq poll due to a received beacon\n", + sdata->name); +#endif mutex_lock(&local->mtx); ifmgd->flags &= ~IEEE80211_STA_BEACON_POLL; ieee80211_run_deferred_scan(local); @@ -2601,6 +2592,8 @@ static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; u8 frame_buf[DEAUTH_DISASSOC_LEN]; + ieee80211_stop_poll(sdata); + ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason, false, frame_buf); mutex_unlock(&ifmgd->mtx); @@ -2632,8 +2625,8 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) auth_data->tries++; if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) { - sdata_info(sdata, "authentication with %pM timed out\n", - auth_data->bss->bssid); + pr_debug("%s: authentication with %pM timed out\n", + sdata->name, auth_data->bss->bssid); /* * Most likely AP is not in the range so remove the @@ -2644,12 +2637,10 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) return -ETIMEDOUT; } - drv_mgd_prepare_tx(local, sdata); - if (auth_data->bss->proberesp_ies) { - sdata_info(sdata, "send auth to %pM (try %d/%d)\n", - auth_data->bss->bssid, auth_data->tries, - IEEE80211_AUTH_MAX_TRIES); + pr_debug("%s: send auth to %pM (try %d/%d)\n", + sdata->name, auth_data->bss->bssid, auth_data->tries, + IEEE80211_AUTH_MAX_TRIES); auth_data->expected_transaction = 2; ieee80211_send_auth(sdata, 1, auth_data->algorithm, @@ -2659,9 +2650,9 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) } else { const u8 *ssidie; - sdata_info(sdata, "direct probe to %pM (try %d/%i)\n", - auth_data->bss->bssid, auth_data->tries, - IEEE80211_AUTH_MAX_TRIES); + pr_debug("%s: direct probe to %pM (try %d/%i)\n", + sdata->name, auth_data->bss->bssid, auth_data->tries, + IEEE80211_AUTH_MAX_TRIES); ssidie = ieee80211_bss_get_ie(auth_data->bss, WLAN_EID_SSID); if (!ssidie) @@ -2689,8 +2680,8 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata) assoc_data->tries++; if (assoc_data->tries > IEEE80211_ASSOC_MAX_TRIES) { - sdata_info(sdata, "association with %pM timed out\n", - assoc_data->bss->bssid); + pr_debug("%s: association with %pM timed out\n", + sdata->name, assoc_data->bss->bssid); /* * Most likely AP is not in the range so remove the @@ -2701,9 +2692,9 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata) return -ETIMEDOUT; } - sdata_info(sdata, "associate with %pM (try %d/%d)\n", - assoc_data->bss->bssid, assoc_data->tries, - IEEE80211_ASSOC_MAX_TRIES); + pr_debug("%s: associate with %pM (try %d/%d)\n", + sdata->name, assoc_data->bss->bssid, assoc_data->tries, + IEEE80211_ASSOC_MAX_TRIES); ieee80211_send_assoc(sdata); assoc_data->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT; @@ -2776,31 +2767,45 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) ieee80211_reset_ap_probe(sdata); else if (ifmgd->nullfunc_failed) { if (ifmgd->probe_send_count < max_tries) { - mlme_dbg(sdata, - "No ack for nullfunc frame to AP %pM, try %d/%i\n", - bssid, ifmgd->probe_send_count, - max_tries); +#ifdef CONFIG_MAC80211_VERBOSE_DEBUG + wiphy_debug(local->hw.wiphy, + "%s: No ack for nullfunc frame to" + " AP %pM, try %d/%i\n", + sdata->name, bssid, + ifmgd->probe_send_count, max_tries); +#endif ieee80211_mgd_probe_ap_send(sdata); } else { - mlme_dbg(sdata, - "No ack for nullfunc frame to AP %pM, disconnecting.\n", - bssid); +#ifdef CONFIG_MAC80211_VERBOSE_DEBUG + wiphy_debug(local->hw.wiphy, + "%s: No ack for nullfunc frame to" + " AP %pM, disconnecting.\n", + sdata->name, bssid); +#endif ieee80211_sta_connection_lost(sdata, bssid, WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY); } } else if (time_is_after_jiffies(ifmgd->probe_timeout)) run_again(ifmgd, ifmgd->probe_timeout); else if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) { - mlme_dbg(sdata, - "Failed to send nullfunc to AP %pM after %dms, disconnecting\n", - bssid, probe_wait_ms); +#ifdef CONFIG_MAC80211_VERBOSE_DEBUG + wiphy_debug(local->hw.wiphy, + "%s: Failed to send nullfunc to AP %pM" + " after %dms, disconnecting.\n", + sdata->name, + bssid, probe_wait_ms); +#endif ieee80211_sta_connection_lost(sdata, bssid, WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY); } else if (ifmgd->probe_send_count < max_tries) { - mlme_dbg(sdata, - "No probe response from AP %pM after %dms, try %d/%i\n", - bssid, probe_wait_ms, - ifmgd->probe_send_count, max_tries); +#ifdef CONFIG_MAC80211_VERBOSE_DEBUG + wiphy_debug(local->hw.wiphy, + "%s: No probe response from AP %pM" + " after %dms, try %d/%i\n", + sdata->name, + bssid, probe_wait_ms, + ifmgd->probe_send_count, max_tries); +#endif ieee80211_mgd_probe_ap_send(sdata); } else { /* @@ -2915,8 +2920,11 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) sdata->flags &= ~IEEE80211_SDATA_DISCONNECT_RESUME; mutex_lock(&ifmgd->mtx); if (ifmgd->associated) { - mlme_dbg(sdata, - "driver requested disconnect after resume\n"); +#ifdef CONFIG_MAC80211_VERBOSE_DEBUG + wiphy_debug(sdata->local->hw.wiphy, + "%s: driver requested disconnect after resume.\n", + sdata->name); +#endif ieee80211_sta_connection_lost(sdata, ifmgd->associated->bssid, WLAN_REASON_UNSPECIFIED); @@ -3004,7 +3012,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, struct ieee80211_local *local = sdata->local; struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; struct ieee80211_bss *bss = (void *)cbss->priv; - struct sta_info *sta = NULL; + struct sta_info *sta; bool have_sta = false; int err; int ht_cfreq; @@ -3057,11 +3065,10 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, * since we look at probe response/beacon data here * it should be OK. */ - sdata_info(sdata, - "Wrong control channel: center-freq: %d ht-cfreq: %d ht->primary_chan: %d band: %d - Disabling HT\n", - cbss->channel->center_freq, - ht_cfreq, ht_oper->primary_chan, - cbss->channel->band); + pr_debug("%s: Wrong control channel: center-freq: %d ht-cfreq: %d ht->primary_chan: %d band: %d - Disabling HT\n", + sdata->name, cbss->channel->center_freq, + ht_cfreq, ht_oper->primary_chan, + cbss->channel->band); ht_oper = NULL; } } @@ -3085,8 +3092,8 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, if (!ieee80211_set_channel_type(local, sdata, channel_type)) { /* can only fail due to HT40+/- mismatch */ channel_type = NL80211_CHAN_HT20; - sdata_info(sdata, - "disabling 40 MHz due to multi-vif mismatch\n"); + pr_debug("%s: disabling 40 MHz due to multi-vif mismatch\n", + sdata->name); ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ; WARN_ON(!ieee80211_set_channel_type(local, sdata, channel_type)); @@ -3095,7 +3102,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, local->oper_channel = cbss->channel; ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); - if (sta) { + if (!have_sta) { u32 rates = 0, basic_rates = 0; bool have_higher_than_11mbit; int min_rate = INT_MAX, min_rate_index = -1; @@ -3115,8 +3122,8 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, * we can connect -- with a warning. */ if (!basic_rates && min_rate_index >= 0) { - sdata_info(sdata, - "No basic rates, using min rate instead\n"); + pr_debug("%s: No basic rates, using min rate instead\n", + sdata->name); basic_rates = BIT(min_rate_index); } @@ -3142,9 +3149,8 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, err = sta_info_insert(sta); sta = NULL; if (err) { - sdata_info(sdata, - "failed to insert STA entry for the AP (error %d)\n", - err); + pr_debug("%s: failed to insert STA entry for the AP (error %d)\n", + sdata->name, err); return err; } } else @@ -3222,7 +3228,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, if (ifmgd->associated) ieee80211_set_disassoc(sdata, 0, 0, false, NULL); - sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid); + pr_debug("%s: authenticate with %pM\n", sdata->name, req->bss->bssid); err = ieee80211_prep_connection(sdata, req->bss, false); if (err) @@ -3404,8 +3410,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, * Wait up to one beacon interval ... * should this be more if we miss one? */ - sdata_info(sdata, "waiting for beacon from %pM\n", - ifmgd->bssid); + pr_debug("%s: waiting for beacon from %pM\n", + sdata->name, ifmgd->bssid); assoc_data->timeout = TU_TO_EXP_TIME(req->bss->beacon_interval); } else { assoc_data->have_beacon = true; @@ -3424,8 +3430,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, corrupt_type = "beacon"; } else if (bss->corrupt_data & IEEE80211_BSS_CORRUPT_PROBE_RESP) corrupt_type = "probe response"; - sdata_info(sdata, "associating with AP with corrupt %s\n", - corrupt_type); + pr_debug("%s: associating with AP with corrupt %s\n", + sdata->name, corrupt_type); } err = 0; @@ -3454,9 +3460,8 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, return 0; } - sdata_info(sdata, - "deauthenticating from %pM by local choice (reason=%d)\n", - req->bssid, req->reason_code); + pr_debug("%s: deauthenticating from %pM by local choice (reason=%d)\n", + sdata->name, req->bssid, req->reason_code); if (ifmgd->associated && ether_addr_equal(ifmgd->associated->bssid, req->bssid)) @@ -3498,9 +3503,8 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, return -ENOLINK; } - sdata_info(sdata, - "disassociating from %pM by local choice (reason=%d)\n", - req->bss->bssid, req->reason_code); + pr_debug("%s: disassociating from %pM by local choice (reason=%d)\n", + sdata->name, req->bss->bssid, req->reason_code); memcpy(bssid, req->bss->bssid, ETH_ALEN); ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DISASSOC, diff --git a/trunk/net/mac80211/offchannel.c b/trunk/net/mac80211/offchannel.c index b0fb6a2b89ad..abb226dc4753 100644 --- a/trunk/net/mac80211/offchannel.c +++ b/trunk/net/mac80211/offchannel.c @@ -15,6 +15,7 @@ #include #include #include "ieee80211_i.h" +#include "driver-trace.h" #include "driver-ops.h" /* @@ -24,7 +25,8 @@ * because we *may* be doing work on-operating channel, and want our * hardware unconditionally awake, but still let the AP send us normal frames. */ -static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata) +static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata, + bool tell_ap) { struct ieee80211_local *local = sdata->local; struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; @@ -45,8 +47,8 @@ static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata) ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); } - if (!local->offchannel_ps_enabled || - !(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)) + if (tell_ap && (!local->offchannel_ps_enabled || + !(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK))) /* * If power save was enabled, no need to send a nullfunc * frame because AP knows that we are sleeping. But if the @@ -131,7 +133,7 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, if (offchannel_ps_enable && (sdata->vif.type == NL80211_IFTYPE_STATION) && sdata->u.mgd.associated) - ieee80211_offchannel_ps_enable(sdata); + ieee80211_offchannel_ps_enable(sdata, true); } } mutex_unlock(&local->iflist_mtx); @@ -261,9 +263,6 @@ void ieee80211_start_next_roc(struct ieee80211_local *local) roc = list_first_entry(&local->roc_list, struct ieee80211_roc_work, list); - if (WARN_ON_ONCE(roc->started)) - return; - if (local->ops->remain_on_channel) { int ret, duration = roc->duration; @@ -379,8 +378,8 @@ void ieee80211_sw_roc_work(struct work_struct *work) ieee80211_recalc_idle(local); - if (roc->started) - ieee80211_start_next_roc(local); + ieee80211_start_next_roc(local); + ieee80211_run_deferred_scan(local); } out_unlock: @@ -411,6 +410,9 @@ static void ieee80211_hw_roc_done(struct work_struct *work) /* if there's another roc, start it now */ ieee80211_start_next_roc(local); + /* or scan maybe */ + ieee80211_run_deferred_scan(local); + out_unlock: mutex_unlock(&local->mtx); } @@ -453,6 +455,7 @@ void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata) } ieee80211_start_next_roc(local); + ieee80211_run_deferred_scan(local); mutex_unlock(&local->mtx); list_for_each_entry_safe(roc, tmp, &tmp_list, list) { diff --git a/trunk/net/mac80211/pm.c b/trunk/net/mac80211/pm.c index 5c572e7a1a71..98c128be3827 100644 --- a/trunk/net/mac80211/pm.c +++ b/trunk/net/mac80211/pm.c @@ -78,16 +78,6 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) if (err < 0) { local->quiescing = false; local->wowlan = false; - if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { - mutex_lock(&local->sta_mtx); - list_for_each_entry(sta, - &local->sta_list, list) { - clear_sta_flag(sta, WLAN_STA_BLOCK_BA); - } - mutex_unlock(&local->sta_mtx); - } - ieee80211_wake_queues_by_reason(hw, - IEEE80211_QUEUE_STOP_REASON_SUSPEND); return err; } else if (err > 0) { WARN_ON(err != 1); diff --git a/trunk/net/mac80211/rc80211_minstrel_ht.c b/trunk/net/mac80211/rc80211_minstrel_ht.c index f9e51ef8dfa2..2d1acc6c5445 100644 --- a/trunk/net/mac80211/rc80211_minstrel_ht.c +++ b/trunk/net/mac80211/rc80211_minstrel_ht.c @@ -809,7 +809,7 @@ minstrel_ht_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) max_rates = sband->n_bitrates; } - msp = kzalloc(sizeof(*msp), gfp); + msp = kzalloc(sizeof(struct minstrel_ht_sta), gfp); if (!msp) return NULL; diff --git a/trunk/net/mac80211/rx.c b/trunk/net/mac80211/rx.c index 839cac8fab57..6fd2cb0838c4 100644 --- a/trunk/net/mac80211/rx.c +++ b/trunk/net/mac80211/rx.c @@ -554,11 +554,11 @@ static inline u16 seq_sub(u16 sq1, u16 sq2) } -static void ieee80211_release_reorder_frame(struct ieee80211_sub_if_data *sdata, +static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw, struct tid_ampdu_rx *tid_agg_rx, int index) { - struct ieee80211_local *local = sdata->local; + struct ieee80211_local *local = hw_to_local(hw); struct sk_buff *skb = tid_agg_rx->reorder_buf[index]; struct ieee80211_rx_status *status; @@ -578,7 +578,7 @@ static void ieee80211_release_reorder_frame(struct ieee80211_sub_if_data *sdata, tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); } -static void ieee80211_release_reorder_frames(struct ieee80211_sub_if_data *sdata, +static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, struct tid_ampdu_rx *tid_agg_rx, u16 head_seq_num) { @@ -589,7 +589,7 @@ static void ieee80211_release_reorder_frames(struct ieee80211_sub_if_data *sdata while (seq_less(tid_agg_rx->head_seq_num, head_seq_num)) { index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % tid_agg_rx->buf_size; - ieee80211_release_reorder_frame(sdata, tid_agg_rx, index); + ieee80211_release_reorder_frame(hw, tid_agg_rx, index); } } @@ -604,7 +604,7 @@ static void ieee80211_release_reorder_frames(struct ieee80211_sub_if_data *sdata */ #define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10) -static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata, +static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, struct tid_ampdu_rx *tid_agg_rx) { int index, j; @@ -632,9 +632,12 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata, HT_RX_REORDER_BUF_TIMEOUT)) goto set_release_timer; - ht_dbg_ratelimited(sdata, - "release an RX reorder frame due to timeout on earlier frames\n"); - ieee80211_release_reorder_frame(sdata, tid_agg_rx, j); +#ifdef CONFIG_MAC80211_HT_DEBUG + if (net_ratelimit()) + wiphy_debug(hw->wiphy, + "release an RX reorder frame due to timeout on earlier frames\n"); +#endif + ieee80211_release_reorder_frame(hw, tid_agg_rx, j); /* * Increment the head seq# also for the skipped slots. @@ -644,7 +647,7 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata, skipped = 0; } } else while (tid_agg_rx->reorder_buf[index]) { - ieee80211_release_reorder_frame(sdata, tid_agg_rx, index); + ieee80211_release_reorder_frame(hw, tid_agg_rx, index); index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % tid_agg_rx->buf_size; } @@ -674,7 +677,7 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata, * rcu_read_lock protection. It returns false if the frame * can be processed immediately, true if it was consumed. */ -static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata, +static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, struct tid_ampdu_rx *tid_agg_rx, struct sk_buff *skb) { @@ -703,8 +706,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata if (!seq_less(mpdu_seq_num, head_seq_num + buf_size)) { head_seq_num = seq_inc(seq_sub(mpdu_seq_num, buf_size)); /* release stored frames up to new head to stack */ - ieee80211_release_reorder_frames(sdata, tid_agg_rx, - head_seq_num); + ieee80211_release_reorder_frames(hw, tid_agg_rx, head_seq_num); } /* Now the new frame is always in the range of the reordering buffer */ @@ -734,7 +736,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata tid_agg_rx->reorder_buf[index] = skb; tid_agg_rx->reorder_time[index] = jiffies; tid_agg_rx->stored_mpdu_num++; - ieee80211_sta_reorder_release(sdata, tid_agg_rx); + ieee80211_sta_reorder_release(hw, tid_agg_rx); out: spin_unlock(&tid_agg_rx->reorder_lock); @@ -749,6 +751,7 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx) { struct sk_buff *skb = rx->skb; struct ieee80211_local *local = rx->local; + struct ieee80211_hw *hw = &local->hw; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct sta_info *sta = rx->sta; @@ -810,7 +813,7 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx) * sure that we cannot get to it any more before doing * anything with it. */ - if (ieee80211_sta_manage_reorder_buf(rx->sdata, tid_agg_rx, skb)) + if (ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb)) return; dont_reorder: @@ -1133,18 +1136,24 @@ static void ap_sta_ps_start(struct sta_info *sta) set_sta_flag(sta, WLAN_STA_PS_STA); if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) drv_sta_notify(local, sdata, STA_NOTIFY_SLEEP, &sta->sta); - ps_dbg(sdata, "STA %pM aid %d enters power save mode\n", - sta->sta.addr, sta->sta.aid); +#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG + pr_debug("%s: STA %pM aid %d enters power save mode\n", + sdata->name, sta->sta.addr, sta->sta.aid); +#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ } static void ap_sta_ps_end(struct sta_info *sta) { - ps_dbg(sta->sdata, "STA %pM aid %d exits power save mode\n", - sta->sta.addr, sta->sta.aid); +#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG + pr_debug("%s: STA %pM aid %d exits power save mode\n", + sta->sdata->name, sta->sta.addr, sta->sta.aid); +#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { - ps_dbg(sta->sdata, "STA %pM aid %d driver-ps-blocked\n", - sta->sta.addr, sta->sta.aid); +#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG + pr_debug("%s: STA %pM aid %d driver-ps-blocked\n", + sta->sdata->name, sta->sta.addr, sta->sta.aid); +#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ return; } @@ -1374,8 +1383,17 @@ ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, if (sdata->fragment_next >= IEEE80211_FRAGMENT_MAX) sdata->fragment_next = 0; - if (!skb_queue_empty(&entry->skb_list)) + if (!skb_queue_empty(&entry->skb_list)) { +#ifdef CONFIG_MAC80211_VERBOSE_DEBUG + struct ieee80211_hdr *hdr = + (struct ieee80211_hdr *) entry->skb_list.next->data; + pr_debug("%s: RX reassembly removed oldest fragment entry (idx=%d age=%lu seq=%d last_frag=%d addr1=%pM addr2=%pM\n", + sdata->name, idx, + jiffies - entry->first_frag_time, entry->seq, + entry->last_frag, hdr->addr1, hdr->addr2); +#endif __skb_queue_purge(&entry->skb_list); + } __skb_queue_tail(&entry->skb_list, *skb); /* no need for locking */ *skb = NULL; @@ -1733,7 +1751,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) */ xmit_skb = skb_copy(skb, GFP_ATOMIC); if (!xmit_skb) - net_info_ratelimited("%s: failed to clone multicast frame\n", + net_dbg_ratelimited("%s: failed to clone multicast frame\n", dev->name); } else { dsta = sta_info_get(sdata, skb->data); @@ -1917,7 +1935,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) ether_addr_equal(sdata->vif.addr, hdr->addr3)) return RX_CONTINUE; - q = ieee80211_select_queue_80211(sdata, skb, hdr); + q = ieee80211_select_queue_80211(local, skb, hdr); if (ieee80211_queue_stopped(&local->hw, q)) { IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion); return RX_DROP_MONITOR; @@ -1937,7 +1955,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) fwd_skb = skb_copy(skb, GFP_ATOMIC); if (!fwd_skb) { - net_info_ratelimited("%s: failed to clone mesh frame\n", + net_dbg_ratelimited("%s: failed to clone mesh frame\n", sdata->name); goto out; } @@ -2040,6 +2058,8 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) static ieee80211_rx_result debug_noinline ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) { + struct ieee80211_local *local = rx->local; + struct ieee80211_hw *hw = &local->hw; struct sk_buff *skb = rx->skb; struct ieee80211_bar *bar = (struct ieee80211_bar *)skb->data; struct tid_ampdu_rx *tid_agg_rx; @@ -2076,8 +2096,7 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) spin_lock(&tid_agg_rx->reorder_lock); /* release stored frames up to start of BAR */ - ieee80211_release_reorder_frames(rx->sdata, tid_agg_rx, - start_seq_num); + ieee80211_release_reorder_frames(hw, tid_agg_rx, start_seq_num); spin_unlock(&tid_agg_rx->reorder_lock); kfree_skb(skb); @@ -2434,7 +2453,7 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx) * frames that we didn't handle, including returning unknown * ones. For all other modes we will return them to the sender, * setting the 0x80 bit in the action category, as required by - * 802.11-2012 9.24.4. + * 802.11-2007 7.3.1.11. * Newer versions of hostapd shall also use the management frame * registration mechanisms, but older ones still use cooked * monitor interfaces so push all frames there. @@ -2444,9 +2463,6 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx) sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) return RX_DROP_MONITOR; - if (is_multicast_ether_addr(mgmt->da)) - return RX_DROP_MONITOR; - /* do not return rejected action frames */ if (mgmt->u.action.category & 0x80) return RX_DROP_UNUSABLE; @@ -2731,7 +2747,7 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) return; spin_lock(&tid_agg_rx->reorder_lock); - ieee80211_sta_reorder_release(sta->sdata, tid_agg_rx); + ieee80211_sta_reorder_release(&sta->local->hw, tid_agg_rx); spin_unlock(&tid_agg_rx->reorder_lock); ieee80211_rx_handlers(&rx); @@ -3011,10 +3027,6 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) if (unlikely(local->quiescing || local->suspended)) goto drop; - /* We might be during a HW reconfig, prevent Rx for the same reason */ - if (unlikely(local->in_reconfig)) - goto drop; - /* * The same happens when we're not even started, * but that's worth a warning. diff --git a/trunk/net/mac80211/sta_info.c b/trunk/net/mac80211/sta_info.c index 06fa75ceb025..77dcf2f89d42 100644 --- a/trunk/net/mac80211/sta_info.c +++ b/trunk/net/mac80211/sta_info.c @@ -169,7 +169,9 @@ void sta_info_free(struct ieee80211_local *local, struct sta_info *sta) if (sta->rate_ctrl) rate_control_free_sta(sta); - sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr); +#ifdef CONFIG_MAC80211_VERBOSE_DEBUG + wiphy_debug(local->hw.wiphy, "Destroyed STA %pM\n", sta->sta.addr); +#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ kfree(sta); } @@ -276,7 +278,9 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, for (i = 0; i < NUM_RX_DATA_QUEUES; i++) sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX); - sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr); +#ifdef CONFIG_MAC80211_VERBOSE_DEBUG + wiphy_debug(local->hw.wiphy, "Allocated STA %pM\n", sta->sta.addr); +#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ #ifdef CONFIG_MAC80211_MESH sta->plink_state = NL80211_PLINK_LISTEN; @@ -329,9 +333,8 @@ static int sta_info_insert_drv_state(struct ieee80211_local *local, } if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { - sdata_info(sdata, - "failed to move IBSS STA %pM to state %d (%d) - keeping it anyway\n", - sta->sta.addr, state + 1, err); + pr_debug("%s: failed to move IBSS STA %pM to state %d (%d) - keeping it anyway\n", + sdata->name, sta->sta.addr, state + 1, err); err = 0; } @@ -386,7 +389,9 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU) sinfo.generation = local->sta_generation; cfg80211_new_sta(sdata->dev, sta->sta.addr, &sinfo, GFP_KERNEL); - sta_dbg(sdata, "Inserted STA %pM\n", sta->sta.addr); +#ifdef CONFIG_MAC80211_VERBOSE_DEBUG + wiphy_debug(local->hw.wiphy, "Inserted STA %pM\n", sta->sta.addr); +#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ /* move reference to rcu-protected */ rcu_read_lock(); @@ -612,8 +617,9 @@ static bool sta_info_cleanup_expire_buffered_ac(struct ieee80211_local *local, break; local->total_ps_buffered--; - ps_dbg(sta->sdata, "Buffered frame expired (STA %pM)\n", - sta->sta.addr); +#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG + pr_debug("Buffered frame expired (STA %pM)\n", sta->sta.addr); +#endif dev_kfree_skb(skb); } @@ -739,8 +745,9 @@ int __must_check __sta_info_destroy(struct sta_info *sta) mesh_accept_plinks_update(sdata); #endif - sta_dbg(sdata, "Removed STA %pM\n", sta->sta.addr); - +#ifdef CONFIG_MAC80211_VERBOSE_DEBUG + wiphy_debug(local->hw.wiphy, "Removed STA %pM\n", sta->sta.addr); +#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ cancel_work_sync(&sta->drv_unblock_wk); cfg80211_del_sta(sdata->dev, sta->sta.addr, GFP_KERNEL); @@ -880,8 +887,8 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, continue; if (time_after(jiffies, sta->last_rx + exp_time)) { - ibss_dbg(sdata, "expiring inactive STA %pM\n", - sta->sta.addr); + ibss_vdbg("%s: expiring inactive STA %pM\n", + sdata->name, sta->sta.addr); WARN_ON(__sta_info_destroy(sta)); } } @@ -979,9 +986,10 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) sta_info_recalc_tim(sta); - ps_dbg(sdata, - "STA %pM aid %d sending %d filtered/%d PS frames since STA not sleeping anymore\n", - sta->sta.addr, sta->sta.aid, filtered, buffered); +#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG + pr_debug("%s: STA %pM aid %d sending %d filtered/%d PS frames since STA not sleeping anymore\n", + sdata->name, sta->sta.addr, sta->sta.aid, filtered, buffered); +#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ } static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata, @@ -1371,8 +1379,10 @@ int sta_info_move_state(struct sta_info *sta, return -EINVAL; } - sta_dbg(sta->sdata, "moving STA %pM to state %d\n", - sta->sta.addr, new_state); +#ifdef CONFIG_MAC80211_VERBOSE_DEBUG + pr_debug("%s: moving STA %pM to state %d\n", + sta->sdata->name, sta->sta.addr, new_state); +#endif /* * notify the driver before the actual changes so it can diff --git a/trunk/net/mac80211/sta_info.h b/trunk/net/mac80211/sta_info.h index a470e1123a55..3bb24a121c95 100644 --- a/trunk/net/mac80211/sta_info.h +++ b/trunk/net/mac80211/sta_info.h @@ -271,9 +271,6 @@ struct sta_ampdu_mlme { * @plink_timer: peer link watch timer * @plink_timer_was_running: used by suspend/resume to restore timers * @t_offset: timing offset relative to this host - * @t_offset_setpoint: reference timing offset of this sta to be used when - * calculating clockdrift - * @ch_type: peer's channel type * @debugfs: debug filesystem info * @dead: set to true when sta is unlinked * @uploaded: set to true when sta is uploaded to the driver @@ -281,8 +278,6 @@ struct sta_ampdu_mlme { * @sta: station information we share with the driver * @sta_state: duplicates information about station state (for debug) * @beacon_loss_count: number of times beacon loss has triggered - * @supports_40mhz: tracks whether the station advertised 40 MHz support - * as we overwrite its HT parameters with the currently used value */ struct sta_info { /* General information, mostly static */ diff --git a/trunk/net/mac80211/status.c b/trunk/net/mac80211/status.c index 2ed2f27fe8a7..6b4f42527887 100644 --- a/trunk/net/mac80211/status.c +++ b/trunk/net/mac80211/status.c @@ -155,10 +155,13 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, return; } - ps_dbg_ratelimited(sta->sdata, - "dropped TX filtered frame, queue_len=%d PS=%d @%lu\n", - skb_queue_len(&sta->tx_filtered[ac]), - !!test_sta_flag(sta, WLAN_STA_PS_STA), jiffies); +#ifdef CONFIG_MAC80211_VERBOSE_DEBUG + if (net_ratelimit()) + wiphy_debug(local->hw.wiphy, + "dropped TX filtered frame, queue_len=%d PS=%d @%lu\n", + skb_queue_len(&sta->tx_filtered[ac]), + !!test_sta_flag(sta, WLAN_STA_PS_STA), jiffies); +#endif dev_kfree_skb(skb); } diff --git a/trunk/net/mac80211/tkip.c b/trunk/net/mac80211/tkip.c index 57e14d59e12f..68be47ca208f 100644 --- a/trunk/net/mac80211/tkip.c +++ b/trunk/net/mac80211/tkip.c @@ -260,6 +260,16 @@ int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm, keyid = pos[3]; iv32 = get_unaligned_le32(pos + 4); pos += 8; +#ifdef CONFIG_MAC80211_TKIP_DEBUG + { + int i; + pr_debug("TKIP decrypt: data(len=%zd)", payload_len); + for (i = 0; i < payload_len; i++) + printk(" %02x", payload[i]); + printk("\n"); + pr_debug("TKIP decrypt: iv16=%04x iv32=%08x\n", iv16, iv32); + } +#endif if (!(keyid & (1 << 5))) return TKIP_DECRYPT_NO_EXT_IV; @@ -270,8 +280,15 @@ int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm, if (key->u.tkip.rx[queue].state != TKIP_STATE_NOT_INIT && (iv32 < key->u.tkip.rx[queue].iv32 || (iv32 == key->u.tkip.rx[queue].iv32 && - iv16 <= key->u.tkip.rx[queue].iv16))) + iv16 <= key->u.tkip.rx[queue].iv16))) { +#ifdef CONFIG_MAC80211_TKIP_DEBUG + pr_debug("TKIP replay detected for RX frame from %pM (RX IV (%04x,%02x) <= prev. IV (%04x,%02x)\n", + ta, iv32, iv16, + key->u.tkip.rx[queue].iv32, + key->u.tkip.rx[queue].iv16); +#endif return TKIP_DECRYPT_REPLAY; + } if (only_iv) { res = TKIP_DECRYPT_OK; @@ -283,6 +300,21 @@ int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm, key->u.tkip.rx[queue].iv32 != iv32) { /* IV16 wrapped around - perform TKIP phase 1 */ tkip_mixing_phase1(tk, &key->u.tkip.rx[queue], ta, iv32); +#ifdef CONFIG_MAC80211_TKIP_DEBUG + { + int i; + u8 key_offset = NL80211_TKIP_DATA_OFFSET_ENCR_KEY; + pr_debug("TKIP decrypt: Phase1 TA=%pM TK=", ta); + for (i = 0; i < 16; i++) + printk("%02x ", + key->conf.key[key_offset + i]); + printk("\n"); + pr_debug("TKIP decrypt: P1K="); + for (i = 0; i < 5; i++) + printk("%04x ", key->u.tkip.rx[queue].p1k[i]); + printk("\n"); + } +#endif } if (key->local->ops->update_tkip_key && key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE && @@ -298,6 +330,15 @@ int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm, } tkip_mixing_phase2(tk, &key->u.tkip.rx[queue], iv16, rc4key); +#ifdef CONFIG_MAC80211_TKIP_DEBUG + { + int i; + pr_debug("TKIP decrypt: Phase2 rc4key="); + for (i = 0; i < 16; i++) + printk("%02x ", rc4key[i]); + printk("\n"); + } +#endif res = ieee80211_wep_decrypt_data(tfm, rc4key, 16, pos, payload_len - 12); done: diff --git a/trunk/net/mac80211/trace.c b/trunk/net/mac80211/trace.c deleted file mode 100644 index 386e45d8a958..000000000000 --- a/trunk/net/mac80211/trace.c +++ /dev/null @@ -1,75 +0,0 @@ -/* bug in tracepoint.h, it should include this */ -#include - -/* sparse isn't too happy with all macros... */ -#ifndef __CHECKER__ -#include -#include "driver-ops.h" -#include "debug.h" -#define CREATE_TRACE_POINTS -#include "trace.h" - -#ifdef CONFIG_MAC80211_MESSAGE_TRACING -void __sdata_info(const char *fmt, ...) -{ - struct va_format vaf = { - .fmt = fmt, - }; - va_list args; - - va_start(args, fmt); - vaf.va = &args; - - pr_info("%pV", &vaf); - trace_mac80211_info(&vaf); - va_end(args); -} - -void __sdata_dbg(bool print, const char *fmt, ...) -{ - struct va_format vaf = { - .fmt = fmt, - }; - va_list args; - - va_start(args, fmt); - vaf.va = &args; - - if (print) - pr_debug("%pV", &vaf); - trace_mac80211_dbg(&vaf); - va_end(args); -} - -void __sdata_err(const char *fmt, ...) -{ - struct va_format vaf = { - .fmt = fmt, - }; - va_list args; - - va_start(args, fmt); - vaf.va = &args; - - pr_err("%pV", &vaf); - trace_mac80211_err(&vaf); - va_end(args); -} - -void __wiphy_dbg(struct wiphy *wiphy, bool print, const char *fmt, ...) -{ - struct va_format vaf = { - .fmt = fmt, - }; - va_list args; - - va_start(args, fmt); - vaf.va = &args; - - if (print) - wiphy_dbg(wiphy, "%pV", &vaf); - trace_mac80211_dbg(&vaf); - va_end(args); -} -#endif -#endif diff --git a/trunk/net/mac80211/tx.c b/trunk/net/mac80211/tx.c index c9d2175d15c1..af25c4e7ec5c 100644 --- a/trunk/net/mac80211/tx.c +++ b/trunk/net/mac80211/tx.c @@ -140,8 +140,6 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, if (r->flags & IEEE80211_RATE_MANDATORY_A) mrate = r->bitrate; break; - case IEEE80211_BAND_60GHZ: - /* TODO, for now fall through */ case IEEE80211_NUM_BANDS: WARN_ON(1); break; @@ -177,6 +175,12 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, return cpu_to_le16(dur); } +static inline int is_ieee80211_device(struct ieee80211_local *local, + struct net_device *dev) +{ + return local == wdev_priv(dev->ieee80211_ptr); +} + /* tx handlers */ static ieee80211_tx_result debug_noinline ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx) @@ -293,10 +297,9 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) if (unlikely(!assoc && ieee80211_is_data(hdr->frame_control))) { #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - sdata_info(tx->sdata, - "dropped data frame to not associated station %pM\n", - hdr->addr1); -#endif + pr_debug("%s: dropped data frame to not associated station %pM\n", + tx->sdata->name, hdr->addr1); +#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ I802_DEBUG_INC(tx->local->tx_handlers_drop_not_assoc); return TX_DROP; } @@ -363,7 +366,10 @@ static void purge_old_ps_buffers(struct ieee80211_local *local) rcu_read_unlock(); local->total_ps_buffered = total; - ps_dbg_hw(&local->hw, "PS buffers full - purged %d frames\n", purged); +#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG + wiphy_debug(local->hw.wiphy, "PS buffers full - purged %d frames\n", + purged); +#endif } static ieee80211_tx_result @@ -405,8 +411,10 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) purge_old_ps_buffers(tx->local); if (skb_queue_len(&tx->sdata->bss->ps_bc_buf) >= AP_MAX_BC_BUFFER) { - ps_dbg(tx->sdata, - "BC TX buffer full - dropping the oldest frame\n"); +#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG + net_dbg_ratelimited("%s: BC TX buffer full - dropping the oldest frame\n", + tx->sdata->name); +#endif dev_kfree_skb(skb_dequeue(&tx->sdata->bss->ps_bc_buf)); } else tx->local->total_ps_buffered++; @@ -457,15 +465,18 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) return TX_CONTINUE; } - ps_dbg(sta->sdata, "STA %pM aid %d: PS buffer for AC %d\n", - sta->sta.addr, sta->sta.aid, ac); +#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG + pr_debug("STA %pM aid %d: PS buffer for AC %d\n", + sta->sta.addr, sta->sta.aid, ac); +#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) purge_old_ps_buffers(tx->local); if (skb_queue_len(&sta->ps_tx_buf[ac]) >= STA_MAX_TX_BUFFER) { struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf[ac]); - ps_dbg(tx->sdata, - "STA %pM TX buffer for AC %d full - dropping oldest frame\n", - sta->sta.addr, ac); +#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG + net_dbg_ratelimited("%s: STA %pM TX buffer for AC %d full - dropping oldest frame\n", + tx->sdata->name, sta->sta.addr, ac); +#endif dev_kfree_skb(old); } else tx->local->total_ps_buffered++; @@ -487,11 +498,13 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) sta_info_recalc_tim(sta); return TX_QUEUED; - } else if (unlikely(test_sta_flag(sta, WLAN_STA_PS_STA))) { - ps_dbg(tx->sdata, - "STA %pM in PS mode, but polling/in SP -> send frame\n", - sta->sta.addr); } +#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG + else if (unlikely(test_sta_flag(sta, WLAN_STA_PS_STA))) { + pr_debug("%s: STA %pM in PS mode, but polling/in SP -> send frame\n", + tx->sdata->name, sta->sta.addr); + } +#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ return TX_CONTINUE; } @@ -959,7 +972,8 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) info->control.rates[1].idx = -1; info->control.rates[2].idx = -1; info->control.rates[3].idx = -1; - BUILD_BUG_ON(IEEE80211_TX_MAX_RATES != 4); + info->control.rates[4].idx = -1; + BUILD_BUG_ON(IEEE80211_TX_MAX_RATES != 5); info->flags &= ~IEEE80211_TX_CTL_RATE_CTRL_PROBE; } else { hdr->frame_control &= ~morefrags; @@ -1294,8 +1308,11 @@ static bool __ieee80211_tx(struct ieee80211_local *local, break; } - result = ieee80211_tx_frags(local, vif, pubsta, skbs, - txpending); + if (local->ops->tx_frags) + drv_tx_frags(local, vif, pubsta, skbs); + else + result = ieee80211_tx_frags(local, vif, pubsta, skbs, + txpending); ieee80211_tpt_led_trig_tx(local, fc, led_len); ieee80211_led_tx(local, 1); @@ -1946,7 +1963,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, (cpu_to_be16(ethertype) != sdata->control_port_protocol || !ether_addr_equal(sdata->vif.addr, skb->data + ETH_ALEN)))) { #ifdef CONFIG_MAC80211_VERBOSE_DEBUG - net_info_ratelimited("%s: dropped frame to %pM (unauthorized port)\n", + net_dbg_ratelimited("%s: dropped frame to %pM (unauthorized port)\n", dev->name, hdr.addr1); #endif @@ -2418,9 +2435,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, *pos++ = WLAN_EID_SSID; *pos++ = 0x0; - if (ieee80211_add_srates_ie(sdata, skb, true) || + if (ieee80211_add_srates_ie(&sdata->vif, skb, true) || mesh_add_ds_params_ie(skb, sdata) || - ieee80211_add_ext_srates_ie(sdata, skb, true) || + ieee80211_add_ext_srates_ie(&sdata->vif, skb, true) || mesh_add_rsn_ie(skb, sdata) || mesh_add_ht_cap_ie(skb, sdata) || mesh_add_ht_oper_ie(skb, sdata) || diff --git a/trunk/net/mac80211/util.c b/trunk/net/mac80211/util.c index 64493a7bef1a..1df4019f294b 100644 --- a/trunk/net/mac80211/util.c +++ b/trunk/net/mac80211/util.c @@ -268,10 +268,6 @@ EXPORT_SYMBOL(ieee80211_ctstoself_duration); void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue) { struct ieee80211_sub_if_data *sdata; - int n_acs = IEEE80211_NUM_ACS; - - if (local->hw.queues < IEEE80211_NUM_ACS) - n_acs = 1; list_for_each_entry_rcu(sdata, &local->interfaces, list) { int ac; @@ -283,7 +279,7 @@ void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue) local->queue_stop_reasons[sdata->vif.cab_queue] != 0) continue; - for (ac = 0; ac < n_acs; ac++) { + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { int ac_queue = sdata->vif.hw_queue[ac]; if (ac_queue == queue || @@ -345,7 +341,6 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue, { struct ieee80211_local *local = hw_to_local(hw); struct ieee80211_sub_if_data *sdata; - int n_acs = IEEE80211_NUM_ACS; trace_stop_queue(local, queue, reason); @@ -357,14 +352,11 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue, __set_bit(reason, &local->queue_stop_reasons[queue]); - if (local->hw.queues < IEEE80211_NUM_ACS) - n_acs = 1; - rcu_read_lock(); list_for_each_entry_rcu(sdata, &local->interfaces, list) { int ac; - for (ac = 0; ac < n_acs; ac++) { + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { if (sdata->vif.hw_queue[ac] == queue || sdata->vif.cab_queue == queue) netif_stop_subqueue(sdata->dev, ac); @@ -1080,10 +1072,6 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, pos += noffset - offset; } - if (sband->vht_cap.vht_supported) - pos = ieee80211_ie_build_vht_cap(pos, &sband->vht_cap, - sband->vht_cap.cap); - return pos - buffer; } @@ -1424,9 +1412,6 @@ int ieee80211_reconfig(struct ieee80211_local *local) ieee80211_enable_keys(sdata); wake_up: - local->in_reconfig = false; - barrier(); - /* * Clear the WLAN_STA_BLOCK_BA flag so new aggregation * sessions can be established after a resume. @@ -1711,27 +1696,6 @@ u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, return pos; } -u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, - u32 cap) -{ - __le32 tmp; - - *pos++ = WLAN_EID_VHT_CAPABILITY; - *pos++ = sizeof(struct ieee80211_vht_capabilities); - memset(pos, 0, sizeof(struct ieee80211_vht_capabilities)); - - /* capability flags */ - tmp = cpu_to_le32(cap); - memcpy(pos, &tmp, sizeof(u32)); - pos += sizeof(u32); - - /* VHT MCS set */ - memcpy(pos, &vht_cap->vht_mcs, sizeof(vht_cap->vht_mcs)); - pos += sizeof(vht_cap->vht_mcs); - - return pos; -} - u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, struct ieee80211_channel *channel, enum nl80211_channel_type channel_type, @@ -1797,14 +1761,15 @@ ieee80211_ht_oper_to_channel_type(struct ieee80211_ht_operation *ht_oper) return channel_type; } -int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata, +int ieee80211_add_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb, bool need_basic) { + struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); struct ieee80211_local *local = sdata->local; struct ieee80211_supported_band *sband; int rate; u8 i, rates, *pos; - u32 basic_rates = sdata->vif.bss_conf.basic_rates; + u32 basic_rates = vif->bss_conf.basic_rates; sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; rates = sband->n_bitrates; @@ -1828,14 +1793,15 @@ int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata, return 0; } -int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata, +int ieee80211_add_ext_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb, bool need_basic) { + struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); struct ieee80211_local *local = sdata->local; struct ieee80211_supported_band *sband; int rate; u8 i, exrates, *pos; - u32 basic_rates = sdata->vif.bss_conf.basic_rates; + u32 basic_rates = vif->bss_conf.basic_rates; sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; exrates = sband->n_bitrates; diff --git a/trunk/net/mac80211/wme.c b/trunk/net/mac80211/wme.c index cea06e9f26f4..c3d643a6536c 100644 --- a/trunk/net/mac80211/wme.c +++ b/trunk/net/mac80211/wme.c @@ -52,11 +52,11 @@ static int wme_downgrade_ac(struct sk_buff *skb) } } -static u16 ieee80211_downgrade_queue(struct ieee80211_sub_if_data *sdata, +static u16 ieee80211_downgrade_queue(struct ieee80211_local *local, struct sk_buff *skb) { /* in case we are a client verify acm is not set for this ac */ - while (unlikely(sdata->wmm_acm & BIT(skb->priority))) { + while (unlikely(local->wmm_acm & BIT(skb->priority))) { if (wme_downgrade_ac(skb)) { /* * This should not really happen. The AP has marked all @@ -73,11 +73,10 @@ static u16 ieee80211_downgrade_queue(struct ieee80211_sub_if_data *sdata, } /* Indicate which queue to use for this fully formed 802.11 frame */ -u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata, +u16 ieee80211_select_queue_80211(struct ieee80211_local *local, struct sk_buff *skb, struct ieee80211_hdr *hdr) { - struct ieee80211_local *local = sdata->local; u8 *p; if (local->hw.queues < IEEE80211_NUM_ACS) @@ -95,7 +94,7 @@ u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata, p = ieee80211_get_qos_ctl(hdr); skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK; - return ieee80211_downgrade_queue(sdata, skb); + return ieee80211_downgrade_queue(local, skb); } /* Indicate which queue to use. */ @@ -157,7 +156,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, * data frame has */ skb->priority = cfg80211_classify8021d(skb); - return ieee80211_downgrade_queue(sdata, skb); + return ieee80211_downgrade_queue(local, skb); } void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata, diff --git a/trunk/net/mac80211/wme.h b/trunk/net/mac80211/wme.h index 7fea4bb8acbc..ca80818b7b66 100644 --- a/trunk/net/mac80211/wme.h +++ b/trunk/net/mac80211/wme.h @@ -15,7 +15,7 @@ extern const int ieee802_1d_to_ac[8]; -u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata, +u16 ieee80211_select_queue_80211(struct ieee80211_local *local, struct sk_buff *skb, struct ieee80211_hdr *hdr); u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, diff --git a/trunk/net/nfc/llcp/sock.c b/trunk/net/nfc/llcp/sock.c index 05ca5a680071..2c0b317344b7 100644 --- a/trunk/net/nfc/llcp/sock.c +++ b/trunk/net/nfc/llcp/sock.c @@ -292,7 +292,7 @@ static int llcp_sock_getname(struct socket *sock, struct sockaddr *addr, pr_debug("%p\n", sk); - if (llcp_sock == NULL || llcp_sock->dev == NULL) + if (llcp_sock == NULL) return -EBADFD; addr->sa_family = AF_NFC; diff --git a/trunk/net/nfc/nci/ntf.c b/trunk/net/nfc/nci/ntf.c index 2ab196a9f228..cb2646179e5f 100644 --- a/trunk/net/nfc/nci/ntf.c +++ b/trunk/net/nfc/nci/ntf.c @@ -106,7 +106,7 @@ static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev, nfca_poll->sens_res = __le16_to_cpu(*((__u16 *)data)); data += 2; - nfca_poll->nfcid1_len = min_t(__u8, *data++, NFC_NFCID1_MAXSIZE); + nfca_poll->nfcid1_len = *data++; pr_debug("sens_res 0x%x, nfcid1_len %d\n", nfca_poll->sens_res, nfca_poll->nfcid1_len); @@ -130,7 +130,7 @@ static __u8 *nci_extract_rf_params_nfcb_passive_poll(struct nci_dev *ndev, struct rf_tech_specific_params_nfcb_poll *nfcb_poll, __u8 *data) { - nfcb_poll->sensb_res_len = min_t(__u8, *data++, NFC_SENSB_RES_MAXSIZE); + nfcb_poll->sensb_res_len = *data++; pr_debug("sensb_res_len %d\n", nfcb_poll->sensb_res_len); @@ -145,7 +145,7 @@ static __u8 *nci_extract_rf_params_nfcf_passive_poll(struct nci_dev *ndev, __u8 *data) { nfcf_poll->bit_rate = *data++; - nfcf_poll->sensf_res_len = min_t(__u8, *data++, NFC_SENSF_RES_MAXSIZE); + nfcf_poll->sensf_res_len = *data++; pr_debug("bit_rate %d, sensf_res_len %d\n", nfcf_poll->bit_rate, nfcf_poll->sensf_res_len); @@ -331,7 +331,7 @@ static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev, switch (ntf->activation_rf_tech_and_mode) { case NCI_NFC_A_PASSIVE_POLL_MODE: nfca_poll = &ntf->activation_params.nfca_poll_iso_dep; - nfca_poll->rats_res_len = min_t(__u8, *data++, 20); + nfca_poll->rats_res_len = *data++; pr_debug("rats_res_len %d\n", nfca_poll->rats_res_len); if (nfca_poll->rats_res_len > 0) { memcpy(nfca_poll->rats_res, @@ -341,7 +341,7 @@ static int nci_extract_activation_params_iso_dep(struct nci_dev *ndev, case NCI_NFC_B_PASSIVE_POLL_MODE: nfcb_poll = &ntf->activation_params.nfcb_poll_iso_dep; - nfcb_poll->attrib_res_len = min_t(__u8, *data++, 50); + nfcb_poll->attrib_res_len = *data++; pr_debug("attrib_res_len %d\n", nfcb_poll->attrib_res_len); if (nfcb_poll->attrib_res_len > 0) { memcpy(nfcb_poll->attrib_res, diff --git a/trunk/net/nfc/rawsock.c b/trunk/net/nfc/rawsock.c index 8b8a6a2b2bad..ec1134c9e07f 100644 --- a/trunk/net/nfc/rawsock.c +++ b/trunk/net/nfc/rawsock.c @@ -54,10 +54,7 @@ static int rawsock_release(struct socket *sock) { struct sock *sk = sock->sk; - pr_debug("sock=%p sk=%p\n", sock, sk); - - if (!sk) - return 0; + pr_debug("sock=%p\n", sock); sock_orphan(sk); sock_put(sk); diff --git a/trunk/net/wireless/Makefile b/trunk/net/wireless/Makefile index 0f7e0d621ab0..55a28ab21db9 100644 --- a/trunk/net/wireless/Makefile +++ b/trunk/net/wireless/Makefile @@ -10,7 +10,7 @@ obj-$(CONFIG_WEXT_SPY) += wext-spy.o obj-$(CONFIG_WEXT_PRIV) += wext-priv.o cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o -cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o ap.o +cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o cfg80211-$(CONFIG_CFG80211_WEXT) += wext-compat.o wext-sme.o cfg80211-$(CONFIG_CFG80211_INTERNAL_REGDB) += regdb.o diff --git a/trunk/net/wireless/ap.c b/trunk/net/wireless/ap.c deleted file mode 100644 index fcc60d8dbefa..000000000000 --- a/trunk/net/wireless/ap.c +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include -#include -#include "nl80211.h" -#include "core.h" - - -static int __cfg80211_stop_ap(struct cfg80211_registered_device *rdev, - struct net_device *dev) -{ - struct wireless_dev *wdev = dev->ieee80211_ptr; - int err; - - ASSERT_WDEV_LOCK(wdev); - - if (!rdev->ops->stop_ap) - return -EOPNOTSUPP; - - if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && - dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) - return -EOPNOTSUPP; - - if (!wdev->beacon_interval) - return -ENOENT; - - err = rdev->ops->stop_ap(&rdev->wiphy, dev); - if (!err) { - wdev->beacon_interval = 0; - wdev->channel = NULL; - } - - return err; -} - -int cfg80211_stop_ap(struct cfg80211_registered_device *rdev, - struct net_device *dev) -{ - struct wireless_dev *wdev = dev->ieee80211_ptr; - int err; - - wdev_lock(wdev); - err = __cfg80211_stop_ap(rdev, dev); - wdev_unlock(wdev); - - return err; -} diff --git a/trunk/net/wireless/chan.c b/trunk/net/wireless/chan.c index 434c56b92c3c..c1999e45a07c 100644 --- a/trunk/net/wireless/chan.c +++ b/trunk/net/wireless/chan.c @@ -82,73 +82,13 @@ int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev, int freq, enum nl80211_channel_type chantype) { struct ieee80211_channel *chan; - int err; if (!rdev->ops->set_monitor_channel) return -EOPNOTSUPP; - if (!cfg80211_has_monitors_only(rdev)) - return -EBUSY; chan = rdev_freq_to_chan(rdev, freq, chantype); if (!chan) return -EINVAL; - err = rdev->ops->set_monitor_channel(&rdev->wiphy, chan, chantype); - if (!err) { - rdev->monitor_channel = chan; - rdev->monitor_channel_type = chantype; - } - - return err; -} - -void -cfg80211_get_chan_state(struct cfg80211_registered_device *rdev, - struct wireless_dev *wdev, - struct ieee80211_channel **chan, - enum cfg80211_chan_mode *chanmode) -{ - *chan = NULL; - *chanmode = CHAN_MODE_UNDEFINED; - - ASSERT_RDEV_LOCK(rdev); - ASSERT_WDEV_LOCK(wdev); - - if (!netif_running(wdev->netdev)) - return; - - switch (wdev->iftype) { - case NL80211_IFTYPE_ADHOC: - if (wdev->current_bss) { - *chan = wdev->current_bss->pub.channel; - *chanmode = wdev->ibss_fixed - ? CHAN_MODE_SHARED - : CHAN_MODE_EXCLUSIVE; - return; - } - case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_P2P_CLIENT: - if (wdev->current_bss) { - *chan = wdev->current_bss->pub.channel; - *chanmode = CHAN_MODE_SHARED; - return; - } - break; - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_P2P_GO: - case NL80211_IFTYPE_MESH_POINT: - *chan = wdev->channel; - *chanmode = CHAN_MODE_SHARED; - return; - case NL80211_IFTYPE_MONITOR: - case NL80211_IFTYPE_AP_VLAN: - case NL80211_IFTYPE_WDS: - /* these interface types don't really have a channel */ - return; - case NL80211_IFTYPE_UNSPECIFIED: - case NUM_NL80211_IFTYPES: - WARN_ON(1); - } - - return; + return rdev->ops->set_monitor_channel(&rdev->wiphy, chan, chantype); } diff --git a/trunk/net/wireless/core.c b/trunk/net/wireless/core.c index eb60410ae588..a87d43552974 100644 --- a/trunk/net/wireless/core.c +++ b/trunk/net/wireless/core.c @@ -96,6 +96,69 @@ struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx) return &rdev->wiphy; } +/* requires cfg80211_mutex to be held! */ +struct cfg80211_registered_device * +__cfg80211_rdev_from_info(struct genl_info *info) +{ + int ifindex; + struct cfg80211_registered_device *bywiphyidx = NULL, *byifidx = NULL; + struct net_device *dev; + int err = -EINVAL; + + assert_cfg80211_lock(); + + if (info->attrs[NL80211_ATTR_WIPHY]) { + bywiphyidx = cfg80211_rdev_by_wiphy_idx( + nla_get_u32(info->attrs[NL80211_ATTR_WIPHY])); + err = -ENODEV; + } + + if (info->attrs[NL80211_ATTR_IFINDEX]) { + ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]); + dev = dev_get_by_index(genl_info_net(info), ifindex); + if (dev) { + if (dev->ieee80211_ptr) + byifidx = + wiphy_to_dev(dev->ieee80211_ptr->wiphy); + dev_put(dev); + } + err = -ENODEV; + } + + if (bywiphyidx && byifidx) { + if (bywiphyidx != byifidx) + return ERR_PTR(-EINVAL); + else + return bywiphyidx; /* == byifidx */ + } + if (bywiphyidx) + return bywiphyidx; + + if (byifidx) + return byifidx; + + return ERR_PTR(err); +} + +struct cfg80211_registered_device * +cfg80211_get_dev_from_info(struct genl_info *info) +{ + struct cfg80211_registered_device *rdev; + + mutex_lock(&cfg80211_mutex); + rdev = __cfg80211_rdev_from_info(info); + + /* if it is not an error we grab the lock on + * it to assure it won't be going away while + * we operate on it */ + if (!IS_ERR(rdev)) + mutex_lock(&rdev->mtx); + + mutex_unlock(&cfg80211_mutex); + + return rdev; +} + struct cfg80211_registered_device * cfg80211_get_dev_from_ifindex(struct net *net, int ifindex) { @@ -373,14 +436,6 @@ static int wiphy_verify_combinations(struct wiphy *wiphy) if (WARN_ON(!c->num_different_channels)) return -EINVAL; - /* - * Put a sane limit on maximum number of different - * channels to simplify channel accounting code. - */ - if (WARN_ON(c->num_different_channels > - CFG80211_MAX_NUM_DIFFERENT_CHANNELS)) - return -EINVAL; - if (WARN_ON(!c->n_limits)) return -EINVAL; @@ -429,11 +484,9 @@ int wiphy_register(struct wiphy *wiphy) int i; u16 ifmodes = wiphy->interface_modes; -#ifdef CONFIG_PM if (WARN_ON((wiphy->wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) && !(wiphy->wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY))) return -EINVAL; -#endif if (WARN_ON(wiphy->ap_sme_capa && !(wiphy->flags & WIPHY_FLAG_HAVE_AP_SME))) @@ -468,14 +521,8 @@ int wiphy_register(struct wiphy *wiphy) continue; sband->band = band; - if (WARN_ON(!sband->n_channels)) - return -EINVAL; - /* - * on 60gHz band, there are no legacy rates, so - * n_bitrates is 0 - */ - if (WARN_ON(band != IEEE80211_BAND_60GHZ && - !sband->n_bitrates)) + + if (WARN_ON(!sband->n_channels || !sband->n_bitrates)) return -EINVAL; /* @@ -516,14 +563,12 @@ int wiphy_register(struct wiphy *wiphy) return -EINVAL; } -#ifdef CONFIG_PM if (rdev->wiphy.wowlan.n_patterns) { if (WARN_ON(!rdev->wiphy.wowlan.pattern_min_len || rdev->wiphy.wowlan.pattern_min_len > rdev->wiphy.wowlan.pattern_max_len)) return -EINVAL; } -#endif /* check and set up bitrates */ ieee80211_set_bitrate_flags(wiphy); @@ -731,61 +776,6 @@ static struct device_type wiphy_type = { .name = "wlan", }; -static struct ieee80211_channel * -cfg80211_get_any_chan(struct cfg80211_registered_device *rdev) -{ - struct ieee80211_supported_band *sband; - int i; - - for (i = 0; i < IEEE80211_NUM_BANDS; i++) { - sband = rdev->wiphy.bands[i]; - if (sband && sband->n_channels > 0) - return &sband->channels[0]; - } - - return NULL; -} - -static void cfg80211_init_mon_chan(struct cfg80211_registered_device *rdev) -{ - struct ieee80211_channel *chan; - - chan = cfg80211_get_any_chan(rdev); - if (WARN_ON(!chan)) - return; - - mutex_lock(&rdev->devlist_mtx); - WARN_ON(cfg80211_set_monitor_channel(rdev, chan->center_freq, - NL80211_CHAN_NO_HT)); - mutex_unlock(&rdev->devlist_mtx); -} - -void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, - enum nl80211_iftype iftype, int num) -{ - bool has_monitors_only_old = cfg80211_has_monitors_only(rdev); - bool has_monitors_only_new; - - ASSERT_RTNL(); - - rdev->num_running_ifaces += num; - if (iftype == NL80211_IFTYPE_MONITOR) - rdev->num_running_monitor_ifaces += num; - - has_monitors_only_new = cfg80211_has_monitors_only(rdev); - if (has_monitors_only_new != has_monitors_only_old) { - rdev->ops->set_monitor_enabled(&rdev->wiphy, - has_monitors_only_new); - - if (!has_monitors_only_new) { - rdev->monitor_channel = NULL; - rdev->monitor_channel_type = NL80211_CHAN_NO_HT; - } else { - cfg80211_init_mon_chan(rdev); - } - } -} - static int cfg80211_netdev_notifier_call(struct notifier_block *nb, unsigned long state, void *ndev) @@ -879,16 +869,12 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, case NL80211_IFTYPE_MESH_POINT: cfg80211_leave_mesh(rdev, dev); break; - case NL80211_IFTYPE_AP: - cfg80211_stop_ap(rdev, dev); - break; default: break; } wdev->beacon_interval = 0; break; case NETDEV_DOWN: - cfg80211_update_iface_num(rdev, wdev->iftype, -1); dev_hold(dev); queue_work(cfg80211_wq, &wdev->cleanup_work); break; @@ -994,12 +980,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, return notifier_from_errno(-EOPNOTSUPP); if (rfkill_blocked(rdev->rfkill)) return notifier_from_errno(-ERFKILL); - mutex_lock(&rdev->devlist_mtx); ret = cfg80211_can_add_interface(rdev, wdev->iftype); - mutex_unlock(&rdev->devlist_mtx); if (ret) return notifier_from_errno(ret); - cfg80211_update_iface_num(rdev, wdev->iftype, 1); break; } diff --git a/trunk/net/wireless/core.h b/trunk/net/wireless/core.h index 377dc394f48c..9348a47562a4 100644 --- a/trunk/net/wireless/core.h +++ b/trunk/net/wireless/core.h @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include "reg.h" @@ -57,13 +56,6 @@ struct cfg80211_registered_device { u32 ap_beacons_nlpid; - /* protected by RTNL only */ - int num_running_ifaces; - int num_running_monitor_ifaces; - - struct ieee80211_channel *monitor_channel; - enum nl80211_channel_type monitor_channel_type; - /* BSSes/scanning */ spinlock_t bss_lock; struct list_head bss_list; @@ -167,6 +159,32 @@ static inline void cfg80211_unhold_bss(struct cfg80211_internal_bss *bss) struct cfg80211_registered_device *cfg80211_rdev_by_wiphy_idx(int wiphy_idx); int get_wiphy_idx(struct wiphy *wiphy); +struct cfg80211_registered_device * +__cfg80211_rdev_from_info(struct genl_info *info); + +/* + * This function returns a pointer to the driver + * that the genl_info item that is passed refers to. + * If successful, it returns non-NULL and also locks + * the driver's mutex! + * + * This means that you need to call cfg80211_unlock_rdev() + * before being allowed to acquire &cfg80211_mutex! + * + * This is necessary because we need to lock the global + * mutex to get an item off the list safely, and then + * we lock the rdev mutex so it doesn't go away under us. + * + * We don't want to keep cfg80211_mutex locked + * for all the time in order to allow requests on + * other interfaces to go through at the same time. + * + * The result of this can be a PTR_ERR and hence must + * be checked with IS_ERR() for errors. + */ +extern struct cfg80211_registered_device * +cfg80211_get_dev_from_info(struct genl_info *info); + /* requires cfg80211_rdev_mutex to be held! */ struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx); @@ -205,14 +223,6 @@ static inline void wdev_unlock(struct wireless_dev *wdev) #define ASSERT_RDEV_LOCK(rdev) lockdep_assert_held(&(rdev)->mtx) #define ASSERT_WDEV_LOCK(wdev) lockdep_assert_held(&(wdev)->mtx) -static inline bool cfg80211_has_monitors_only(struct cfg80211_registered_device *rdev) -{ - ASSERT_RTNL(); - - return rdev->num_running_ifaces == rdev->num_running_monitor_ifaces && - rdev->num_running_ifaces > 0; -} - enum cfg80211_event_type { EVENT_CONNECT_RESULT, EVENT_ROAMED, @@ -257,12 +267,6 @@ struct cfg80211_cached_keys { int def, defmgmt; }; -enum cfg80211_chan_mode { - CHAN_MODE_UNDEFINED, - CHAN_MODE_SHARED, - CHAN_MODE_EXCLUSIVE, -}; - /* free object */ extern void cfg80211_dev_free(struct cfg80211_registered_device *rdev); @@ -311,10 +315,6 @@ int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev, int freq, enum nl80211_channel_type channel_type); -/* AP */ -int cfg80211_stop_ap(struct cfg80211_registered_device *rdev, - struct net_device *dev); - /* MLME */ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, struct net_device *dev, @@ -430,20 +430,9 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, u32 *flags, struct vif_params *params); void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev); -int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, - struct wireless_dev *wdev, - enum nl80211_iftype iftype, - struct ieee80211_channel *chan, - enum cfg80211_chan_mode chanmode); - -static inline int -cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, - struct wireless_dev *wdev, - enum nl80211_iftype iftype) -{ - return cfg80211_can_use_iftype_chan(rdev, wdev, iftype, NULL, - CHAN_MODE_UNDEFINED); -} +int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, + struct wireless_dev *wdev, + enum nl80211_iftype iftype); static inline int cfg80211_can_add_interface(struct cfg80211_registered_device *rdev, @@ -452,22 +441,6 @@ cfg80211_can_add_interface(struct cfg80211_registered_device *rdev, return cfg80211_can_change_interface(rdev, NULL, iftype); } -static inline int -cfg80211_can_use_chan(struct cfg80211_registered_device *rdev, - struct wireless_dev *wdev, - struct ieee80211_channel *chan, - enum cfg80211_chan_mode chanmode) -{ - return cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, - chan, chanmode); -} - -void -cfg80211_get_chan_state(struct cfg80211_registered_device *rdev, - struct wireless_dev *wdev, - struct ieee80211_channel **chan, - enum cfg80211_chan_mode *chanmode); - struct ieee80211_channel * rdev_freq_to_chan(struct cfg80211_registered_device *rdev, int freq, enum nl80211_channel_type channel_type); @@ -481,11 +454,6 @@ int ieee80211_get_ratemask(struct ieee80211_supported_band *sband, int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, u32 beacon_int); -void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, - enum nl80211_iftype iftype, int num); - -#define CFG80211_MAX_NUM_DIFFERENT_CHANNELS 10 - #ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS #define CFG80211_DEV_WARN_ON(cond) WARN_ON(cond) #else diff --git a/trunk/net/wireless/ibss.c b/trunk/net/wireless/ibss.c index ca5672f6ee2f..89baa3328411 100644 --- a/trunk/net/wireless/ibss.c +++ b/trunk/net/wireless/ibss.c @@ -113,21 +113,10 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, kfree(wdev->connect_keys); wdev->connect_keys = connkeys; - wdev->ibss_fixed = params->channel_fixed; #ifdef CONFIG_CFG80211_WEXT wdev->wext.ibss.channel = params->channel; #endif wdev->sme_state = CFG80211_SME_CONNECTING; - - err = cfg80211_can_use_chan(rdev, wdev, params->channel, - params->channel_fixed - ? CHAN_MODE_SHARED - : CHAN_MODE_EXCLUSIVE); - if (err) { - wdev->connect_keys = NULL; - return err; - } - err = rdev->ops->join_ibss(&rdev->wiphy, dev, params); if (err) { wdev->connect_keys = NULL; diff --git a/trunk/net/wireless/mesh.c b/trunk/net/wireless/mesh.c index c384e77ff77a..b44c736bf9cf 100644 --- a/trunk/net/wireless/mesh.c +++ b/trunk/net/wireless/mesh.c @@ -14,9 +14,6 @@ #define MESH_PATH_TIMEOUT 5000 #define MESH_RANN_INTERVAL 5000 -#define MESH_PATH_TO_ROOT_TIMEOUT 6000 -#define MESH_ROOT_INTERVAL 5000 -#define MESH_ROOT_CONFIRMATION_INTERVAL 2000 /* * Minimum interval between two consecutive PREQs originated by the same @@ -65,9 +62,6 @@ const struct mesh_config default_mesh_config = { .dot11MeshForwarding = true, .rssi_threshold = MESH_RSSI_THRESHOLD, .ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED, - .dot11MeshHWMPactivePathToRootTimeout = MESH_PATH_TO_ROOT_TIMEOUT, - .dot11MeshHWMProotInterval = MESH_ROOT_INTERVAL, - .dot11MeshHWMPconfirmationInterval = MESH_ROOT_CONFIRMATION_INTERVAL, }; const struct mesh_setup default_mesh_setup = { @@ -155,16 +149,10 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, setup->channel_type)) return -EINVAL; - err = cfg80211_can_use_chan(rdev, wdev, setup->channel, - CHAN_MODE_SHARED); - if (err) - return err; - err = rdev->ops->join_mesh(&rdev->wiphy, dev, conf, setup); if (!err) { memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len); wdev->mesh_id_len = setup->mesh_id_len; - wdev->channel = setup->channel; } return err; @@ -178,11 +166,9 @@ int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev = dev->ieee80211_ptr; int err; - mutex_lock(&rdev->devlist_mtx); wdev_lock(wdev); err = __cfg80211_join_mesh(rdev, dev, setup, conf); wdev_unlock(wdev); - mutex_unlock(&rdev->devlist_mtx); return err; } @@ -192,7 +178,6 @@ int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev, enum nl80211_channel_type channel_type) { struct ieee80211_channel *channel; - int err; channel = rdev_freq_to_chan(rdev, freq, channel_type); if (!channel || !cfg80211_can_beacon_sec_chan(&rdev->wiphy, @@ -214,19 +199,9 @@ int cfg80211_set_mesh_freq(struct cfg80211_registered_device *rdev, if (!netif_running(wdev->netdev)) return -ENETDOWN; - - err = cfg80211_can_use_chan(rdev, wdev, channel, - CHAN_MODE_SHARED); - if (err) - return err; - - err = rdev->ops->libertas_set_mesh_channel(&rdev->wiphy, - wdev->netdev, - channel); - if (!err) - wdev->channel = channel; - - return err; + return rdev->ops->libertas_set_mesh_channel(&rdev->wiphy, + wdev->netdev, + channel); } if (wdev->mesh_id_len) @@ -268,11 +243,8 @@ static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, return -ENOTCONN; err = rdev->ops->leave_mesh(&rdev->wiphy, dev); - if (!err) { + if (!err) wdev->mesh_id_len = 0; - wdev->channel = NULL; - } - return err; } diff --git a/trunk/net/wireless/mlme.c b/trunk/net/wireless/mlme.c index d4fece3bb18a..da4406f11929 100644 --- a/trunk/net/wireless/mlme.c +++ b/trunk/net/wireless/mlme.c @@ -302,14 +302,8 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, if (!req.bss) return -ENOENT; - err = cfg80211_can_use_chan(rdev, wdev, req.bss->channel, - CHAN_MODE_SHARED); - if (err) - goto out; - err = rdev->ops->auth(&rdev->wiphy, dev, &req); -out: cfg80211_put_bss(req.bss); return err; } @@ -323,13 +317,11 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, { int err; - mutex_lock(&rdev->devlist_mtx); wdev_lock(dev->ieee80211_ptr); err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, ssid, ssid_len, ie, ie_len, key, key_len, key_idx); wdev_unlock(dev->ieee80211_ptr); - mutex_unlock(&rdev->devlist_mtx); return err; } @@ -405,14 +397,8 @@ int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, return -ENOENT; } - err = cfg80211_can_use_chan(rdev, wdev, req.bss->channel, - CHAN_MODE_SHARED); - if (err) - goto out; - err = rdev->ops->assoc(&rdev->wiphy, dev, &req); -out: if (err) { if (was_connected) wdev->sme_state = CFG80211_SME_CONNECTED; @@ -435,13 +421,11 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, struct wireless_dev *wdev = dev->ieee80211_ptr; int err; - mutex_lock(&rdev->devlist_mtx); wdev_lock(wdev); err = __cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid, ssid, ssid_len, ie, ie_len, use_mfp, crypt, assoc_flags, ht_capa, ht_capa_mask); wdev_unlock(wdev); - mutex_unlock(&rdev->devlist_mtx); return err; } @@ -963,7 +947,6 @@ void cfg80211_ch_switch_notify(struct net_device *dev, int freq, if (WARN_ON(!chan)) goto out; - wdev->channel = chan; nl80211_ch_switch_notify(rdev, dev, freq, type, GFP_KERNEL); out: wdev_unlock(wdev); diff --git a/trunk/net/wireless/nl80211.c b/trunk/net/wireless/nl80211.c index 2a5cdb60bc6e..7ae54b82291f 100644 --- a/trunk/net/wireless/nl80211.c +++ b/trunk/net/wireless/nl80211.c @@ -70,94 +70,6 @@ static int get_rdev_dev_by_ifindex(struct net *netns, struct nlattr **attrs, return 0; } -static struct cfg80211_registered_device * -__cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs) -{ - struct cfg80211_registered_device *rdev = NULL, *tmp; - struct net_device *netdev; - - assert_cfg80211_lock(); - - if (!attrs[NL80211_ATTR_WIPHY] && - !attrs[NL80211_ATTR_IFINDEX]) - return ERR_PTR(-EINVAL); - - if (attrs[NL80211_ATTR_WIPHY]) - rdev = cfg80211_rdev_by_wiphy_idx( - nla_get_u32(attrs[NL80211_ATTR_WIPHY])); - - if (attrs[NL80211_ATTR_IFINDEX]) { - int ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]); - netdev = dev_get_by_index(netns, ifindex); - if (netdev) { - if (netdev->ieee80211_ptr) - tmp = wiphy_to_dev( - netdev->ieee80211_ptr->wiphy); - else - tmp = NULL; - - dev_put(netdev); - - /* not wireless device -- return error */ - if (!tmp) - return ERR_PTR(-EINVAL); - - /* mismatch -- return error */ - if (rdev && tmp != rdev) - return ERR_PTR(-EINVAL); - - rdev = tmp; - } - } - - if (!rdev) - return ERR_PTR(-ENODEV); - - if (netns != wiphy_net(&rdev->wiphy)) - return ERR_PTR(-ENODEV); - - return rdev; -} - -/* - * This function returns a pointer to the driver - * that the genl_info item that is passed refers to. - * If successful, it returns non-NULL and also locks - * the driver's mutex! - * - * This means that you need to call cfg80211_unlock_rdev() - * before being allowed to acquire &cfg80211_mutex! - * - * This is necessary because we need to lock the global - * mutex to get an item off the list safely, and then - * we lock the rdev mutex so it doesn't go away under us. - * - * We don't want to keep cfg80211_mutex locked - * for all the time in order to allow requests on - * other interfaces to go through at the same time. - * - * The result of this can be a PTR_ERR and hence must - * be checked with IS_ERR() for errors. - */ -static struct cfg80211_registered_device * -cfg80211_get_dev_from_info(struct net *netns, struct genl_info *info) -{ - struct cfg80211_registered_device *rdev; - - mutex_lock(&cfg80211_mutex); - rdev = __cfg80211_rdev_from_attrs(netns, info->attrs); - - /* if it is not an error we grab the lock on - * it to assure it won't be going away while - * we operate on it */ - if (!IS_ERR(rdev)) - mutex_lock(&rdev->mtx); - - mutex_unlock(&cfg80211_mutex); - - return rdev; -} - /* policy for the attributes */ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_WIPHY] = { .type = NLA_U32 }, @@ -203,7 +115,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 }, [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ }, [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY, - .len = IEEE80211_MAX_MESH_ID_LEN }, + .len = IEEE80211_MAX_MESH_ID_LEN }, [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 }, [NL80211_ATTR_REG_ALPHA2] = { .type = NLA_STRING, .len = 2 }, @@ -338,9 +250,8 @@ nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = { static const struct nla_policy nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = { - [NL80211_SCHED_SCAN_MATCH_ATTR_SSID] = { .type = NLA_BINARY, + [NL80211_ATTR_SCHED_SCAN_MATCH_SSID] = { .type = NLA_BINARY, .len = IEEE80211_MAX_SSID_LEN }, - [NL80211_SCHED_SCAN_MATCH_ATTR_RSSI] = { .type = NLA_U32 }, }; /* ifidx get helper */ @@ -921,15 +832,6 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, dev->wiphy.bands[band]->ht_cap.ampdu_density))) goto nla_put_failure; - /* add VHT info */ - if (dev->wiphy.bands[band]->vht_cap.vht_supported && - (nla_put(msg, NL80211_BAND_ATTR_VHT_MCS_SET, - sizeof(dev->wiphy.bands[band]->vht_cap.vht_mcs), - &dev->wiphy.bands[band]->vht_cap.vht_mcs) || - nla_put_u32(msg, NL80211_BAND_ATTR_VHT_CAPA, - dev->wiphy.bands[band]->vht_cap.cap))) - goto nla_put_failure; - /* add frequencies */ nl_freqs = nla_nest_start(msg, NL80211_BAND_ATTR_FREQS); if (!nl_freqs) @@ -1121,7 +1023,6 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, nla_nest_end(msg, nl_ifs); } -#ifdef CONFIG_PM if (dev->wiphy.wowlan.flags || dev->wiphy.wowlan.n_patterns) { struct nlattr *nl_wowlan; @@ -1162,7 +1063,6 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, nla_nest_end(msg, nl_wowlan); } -#endif if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES, dev->wiphy.software_iftypes)) @@ -1434,8 +1334,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) } if (!netdev) { - rdev = __cfg80211_rdev_from_attrs(genl_info_net(info), - info->attrs); + rdev = __cfg80211_rdev_from_info(info); if (IS_ERR(rdev)) { mutex_unlock(&cfg80211_mutex); return PTR_ERR(rdev); @@ -1689,11 +1588,16 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags, (cfg80211_rdev_list_generation << 2))) goto nla_put_failure; - if (rdev->monitor_channel) { - if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, - rdev->monitor_channel->center_freq) || - nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, - rdev->monitor_channel_type)) + if (rdev->ops->get_channel) { + struct ieee80211_channel *chan; + enum nl80211_channel_type channel_type; + + chan = rdev->ops->get_channel(&rdev->wiphy, &channel_type); + if (chan && + (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, + chan->center_freq) || + nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, + channel_type))) goto nla_put_failure; } @@ -2342,33 +2246,6 @@ static int nl80211_parse_beacon(struct genl_info *info, return 0; } -static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev, - struct cfg80211_ap_settings *params) -{ - struct wireless_dev *wdev; - bool ret = false; - - mutex_lock(&rdev->devlist_mtx); - - list_for_each_entry(wdev, &rdev->netdev_list, list) { - if (wdev->iftype != NL80211_IFTYPE_AP && - wdev->iftype != NL80211_IFTYPE_P2P_GO) - continue; - - if (!wdev->preset_chan) - continue; - - params->channel = wdev->preset_chan; - params->channel_type = wdev->preset_chantype; - ret = true; - break; - } - - mutex_unlock(&rdev->devlist_mtx); - - return ret; -} - static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; @@ -2471,28 +2348,16 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) } else if (wdev->preset_chan) { params.channel = wdev->preset_chan; params.channel_type = wdev->preset_chantype; - } else if (!nl80211_get_ap_channel(rdev, ¶ms)) + } else return -EINVAL; if (!cfg80211_can_beacon_sec_chan(&rdev->wiphy, params.channel, params.channel_type)) return -EINVAL; - mutex_lock(&rdev->devlist_mtx); - err = cfg80211_can_use_chan(rdev, wdev, params.channel, - CHAN_MODE_SHARED); - mutex_unlock(&rdev->devlist_mtx); - - if (err) - return err; - err = rdev->ops->start_ap(&rdev->wiphy, dev, ¶ms); - if (!err) { - wdev->preset_chan = params.channel; - wdev->preset_chantype = params.channel_type; + if (!err) wdev->beacon_interval = params.beacon_interval; - wdev->channel = params.channel; - } return err; } @@ -2525,8 +2390,23 @@ static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; struct net_device *dev = info->user_ptr[1]; + struct wireless_dev *wdev = dev->ieee80211_ptr; + int err; - return cfg80211_stop_ap(rdev, dev); + if (!rdev->ops->stop_ap) + return -EOPNOTSUPP; + + if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) + return -EOPNOTSUPP; + + if (!wdev->beacon_interval) + return -ENOENT; + + err = rdev->ops->stop_ap(&rdev->wiphy, dev); + if (!err) + wdev->beacon_interval = 0; + return err; } static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = { @@ -2618,8 +2498,7 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info, int attr) { struct nlattr *rate; - u32 bitrate; - u16 bitrate_compat; + u16 bitrate; rate = nla_nest_start(msg, attr); if (!rate) @@ -2627,12 +2506,8 @@ static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info, /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */ bitrate = cfg80211_calculate_bitrate(info); - /* report 16-bit bitrate only if we can */ - bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0; if ((bitrate > 0 && - nla_put_u32(msg, NL80211_RATE_INFO_BITRATE32, bitrate)) || - (bitrate_compat > 0 && - nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat)) || + nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate)) || ((info->flags & RATE_INFO_FLAGS_MCS) && nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs)) || ((info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) && @@ -3594,13 +3469,7 @@ static int nl80211_get_mesh_config(struct sk_buff *skb, nla_put_u32(msg, NL80211_MESHCONF_RSSI_THRESHOLD, cur_params.rssi_threshold) || nla_put_u32(msg, NL80211_MESHCONF_HT_OPMODE, - cur_params.ht_opmode) || - nla_put_u32(msg, NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT, - cur_params.dot11MeshHWMPactivePathToRootTimeout) || - nla_put_u16(msg, NL80211_MESHCONF_HWMP_ROOT_INTERVAL, - cur_params.dot11MeshHWMProotInterval) || - nla_put_u16(msg, NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, - cur_params.dot11MeshHWMPconfirmationInterval)) + cur_params.ht_opmode)) goto nla_put_failure; nla_nest_end(msg, pinfoattr); genlmsg_end(msg, hdr); @@ -3623,6 +3492,7 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A [NL80211_MESHCONF_ELEMENT_TTL] = { .type = NLA_U8 }, [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = { .type = NLA_U8 }, [NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR] = { .type = NLA_U32 }, + [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 }, [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 }, [NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = { .type = NLA_U16 }, @@ -3634,11 +3504,8 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 }, [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 }, [NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 }, - [NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32 }, - [NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16 }, - [NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT] = { .type = NLA_U32 }, - [NL80211_MESHCONF_HWMP_ROOT_INTERVAL] = { .type = NLA_U16 }, - [NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] = { .type = NLA_U16 }, + [NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32}, + [NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16}, }; static const struct nla_policy @@ -3648,7 +3515,7 @@ static const struct nla_policy [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 }, [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG }, [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY, - .len = IEEE80211_MAX_DATA_LEN }, + .len = IEEE80211_MAX_DATA_LEN }, [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG }, }; @@ -3681,82 +3548,63 @@ do {\ /* Fill in the params struct */ FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout, - mask, NL80211_MESHCONF_RETRY_TIMEOUT, - nla_get_u16); + mask, NL80211_MESHCONF_RETRY_TIMEOUT, nla_get_u16); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout, - mask, NL80211_MESHCONF_CONFIRM_TIMEOUT, - nla_get_u16); + mask, NL80211_MESHCONF_CONFIRM_TIMEOUT, nla_get_u16); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout, - mask, NL80211_MESHCONF_HOLDING_TIMEOUT, - nla_get_u16); + mask, NL80211_MESHCONF_HOLDING_TIMEOUT, nla_get_u16); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks, - mask, NL80211_MESHCONF_MAX_PEER_LINKS, - nla_get_u16); + mask, NL80211_MESHCONF_MAX_PEER_LINKS, nla_get_u16); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries, - mask, NL80211_MESHCONF_MAX_RETRIES, - nla_get_u8); + mask, NL80211_MESHCONF_MAX_RETRIES, nla_get_u8); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL, - mask, NL80211_MESHCONF_TTL, nla_get_u8); + mask, NL80211_MESHCONF_TTL, nla_get_u8); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, element_ttl, - mask, NL80211_MESHCONF_ELEMENT_TTL, - nla_get_u8); + mask, NL80211_MESHCONF_ELEMENT_TTL, nla_get_u8); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks, - mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS, - nla_get_u8); - FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor, mask, - NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, - nla_get_u32); + mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS, nla_get_u8); + FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor, + mask, NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, + nla_get_u32); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries, - mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, - nla_get_u8); + mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, + nla_get_u8); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time, - mask, NL80211_MESHCONF_PATH_REFRESH_TIME, - nla_get_u32); + mask, NL80211_MESHCONF_PATH_REFRESH_TIME, nla_get_u32); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout, - mask, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, - nla_get_u16); - FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout, mask, - NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, - nla_get_u32); + mask, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, + nla_get_u16); + FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout, + mask, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, + nla_get_u32); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval, - mask, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, - nla_get_u16); + mask, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, + nla_get_u16); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPperrMinInterval, - mask, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL, - nla_get_u16); + mask, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL, + nla_get_u16); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, - dot11MeshHWMPnetDiameterTraversalTime, mask, - NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, - nla_get_u16); - FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRootMode, mask, - NL80211_MESHCONF_HWMP_ROOTMODE, nla_get_u8); - FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRannInterval, mask, - NL80211_MESHCONF_HWMP_RANN_INTERVAL, - nla_get_u16); + dot11MeshHWMPnetDiameterTraversalTime, + mask, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, + nla_get_u16); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, - dot11MeshGateAnnouncementProtocol, mask, - NL80211_MESHCONF_GATE_ANNOUNCEMENTS, - nla_get_u8); + dot11MeshHWMPRootMode, mask, + NL80211_MESHCONF_HWMP_ROOTMODE, + nla_get_u8); + FILL_IN_MESH_PARAM_IF_SET(tb, cfg, + dot11MeshHWMPRannInterval, mask, + NL80211_MESHCONF_HWMP_RANN_INTERVAL, + nla_get_u16); + FILL_IN_MESH_PARAM_IF_SET(tb, cfg, + dot11MeshGateAnnouncementProtocol, mask, + NL80211_MESHCONF_GATE_ANNOUNCEMENTS, + nla_get_u8); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, - mask, NL80211_MESHCONF_FORWARDING, - nla_get_u8); + mask, NL80211_MESHCONF_FORWARDING, nla_get_u8); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, - mask, NL80211_MESHCONF_RSSI_THRESHOLD, - nla_get_u32); + mask, NL80211_MESHCONF_RSSI_THRESHOLD, nla_get_u32); FILL_IN_MESH_PARAM_IF_SET(tb, cfg, ht_opmode, - mask, NL80211_MESHCONF_HT_OPMODE, - nla_get_u16); - FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathToRootTimeout, - mask, - NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT, - nla_get_u32); - FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMProotInterval, - mask, NL80211_MESHCONF_HWMP_ROOT_INTERVAL, - nla_get_u16); - FILL_IN_MESH_PARAM_IF_SET(tb, cfg, - dot11MeshHWMPconfirmationInterval, mask, - NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, - nla_get_u16); + mask, NL80211_MESHCONF_HT_OPMODE, nla_get_u16); if (mask_out) *mask_out = mask; @@ -4393,12 +4241,12 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH], tmp) { - struct nlattr *ssid, *rssi; + struct nlattr *ssid; nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX, nla_data(attr), nla_len(attr), nl80211_match_policy); - ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID]; + ssid = tb[NL80211_ATTR_SCHED_SCAN_MATCH_SSID]; if (ssid) { if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) { err = -EINVAL; @@ -4409,12 +4257,6 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, request->match_sets[i].ssid.ssid_len = nla_len(ssid); } - rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI]; - if (rssi) - request->rssi_thold = nla_get_u32(rssi); - else - request->rssi_thold = - NL80211_SCAN_RSSI_THOLD_OFF; i++; } } @@ -5272,18 +5114,21 @@ static int nl80211_testmode_dump(struct sk_buff *skb, nl80211_policy); if (err) return err; + if (nl80211_fam.attrbuf[NL80211_ATTR_WIPHY]) { + phy_idx = nla_get_u32( + nl80211_fam.attrbuf[NL80211_ATTR_WIPHY]); + } else { + struct net_device *netdev; - mutex_lock(&cfg80211_mutex); - rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), - nl80211_fam.attrbuf); - if (IS_ERR(rdev)) { - mutex_unlock(&cfg80211_mutex); - return PTR_ERR(rdev); + err = get_rdev_dev_by_ifindex(sock_net(skb->sk), + nl80211_fam.attrbuf, + &rdev, &netdev); + if (err) + return err; + dev_put(netdev); + phy_idx = rdev->wiphy_idx; + cfg80211_unlock_rdev(rdev); } - phy_idx = rdev->wiphy_idx; - rdev = NULL; - mutex_unlock(&cfg80211_mutex); - if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA]) cb->args[1] = (long)nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA]; @@ -6281,7 +6126,6 @@ static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info) return cfg80211_leave_mesh(rdev, dev); } -#ifdef CONFIG_PM static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info) { struct cfg80211_registered_device *rdev = info->user_ptr[0]; @@ -6510,7 +6354,6 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) kfree(new_triggers.patterns); return err; } -#endif static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info) { @@ -6668,7 +6511,7 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, rtnl_lock(); if (ops->internal_flags & NL80211_FLAG_NEED_WIPHY) { - rdev = cfg80211_get_dev_from_info(genl_info_net(info), info); + rdev = cfg80211_get_dev_from_info(info); if (IS_ERR(rdev)) { if (rtnl) rtnl_unlock(); @@ -7165,7 +7008,6 @@ static struct genl_ops nl80211_ops[] = { .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | NL80211_FLAG_NEED_RTNL, }, -#ifdef CONFIG_PM { .cmd = NL80211_CMD_GET_WOWLAN, .doit = nl80211_get_wowlan, @@ -7182,7 +7024,6 @@ static struct genl_ops nl80211_ops[] = { .internal_flags = NL80211_FLAG_NEED_WIPHY | NL80211_FLAG_NEED_RTNL, }, -#endif { .cmd = NL80211_CMD_SET_REKEY_OFFLOAD, .doit = nl80211_set_rekey_data, diff --git a/trunk/net/wireless/reg.c b/trunk/net/wireless/reg.c index b2b32229b607..15f347477a99 100644 --- a/trunk/net/wireless/reg.c +++ b/trunk/net/wireless/reg.c @@ -129,7 +129,7 @@ static DECLARE_DELAYED_WORK(reg_timeout, reg_timeout_work); /* We keep a static world regulatory domain in case of the absence of CRDA */ static const struct ieee80211_regdomain world_regdom = { - .n_reg_rules = 6, + .n_reg_rules = 5, .alpha2 = "00", .reg_rules = { /* IEEE 802.11b/g, channels 1..11 */ @@ -156,9 +156,6 @@ static const struct ieee80211_regdomain world_regdom = { REG_RULE(5745-10, 5825+10, 40, 6, 20, NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS), - - /* IEEE 802.11ad (60gHz), channels 1..3 */ - REG_RULE(56160+2160*1-1080, 56160+2160*3+1080, 2160, 0, 0, 0), } }; @@ -1392,7 +1389,7 @@ static void reg_set_request_processed(void) spin_unlock(®_requests_lock); if (last_request->initiator == NL80211_REGDOM_SET_BY_USER) - cancel_delayed_work(®_timeout); + cancel_delayed_work_sync(®_timeout); if (need_more_processing) schedule_work(®_work); diff --git a/trunk/net/wireless/util.c b/trunk/net/wireless/util.c index e31f1dba79ec..8f2d68fc3a44 100644 --- a/trunk/net/wireless/util.c +++ b/trunk/net/wireless/util.c @@ -35,29 +35,19 @@ int ieee80211_channel_to_frequency(int chan, enum ieee80211_band band) { /* see 802.11 17.3.8.3.2 and Annex J * there are overlapping channel numbers in 5GHz and 2GHz bands */ - if (chan <= 0) - return 0; /* not supported */ - switch (band) { - case IEEE80211_BAND_2GHZ: + if (band == IEEE80211_BAND_5GHZ) { + if (chan >= 182 && chan <= 196) + return 4000 + chan * 5; + else + return 5000 + chan * 5; + } else { /* IEEE80211_BAND_2GHZ */ if (chan == 14) return 2484; else if (chan < 14) return 2407 + chan * 5; - break; - case IEEE80211_BAND_5GHZ: - if (chan >= 182 && chan <= 196) - return 4000 + chan * 5; else - return 5000 + chan * 5; - break; - case IEEE80211_BAND_60GHZ: - if (chan < 5) - return 56160 + chan * 2160; - break; - default: - ; + return 0; /* not supported */ } - return 0; /* not supported */ } EXPORT_SYMBOL(ieee80211_channel_to_frequency); @@ -70,12 +60,8 @@ int ieee80211_frequency_to_channel(int freq) return (freq - 2407) / 5; else if (freq >= 4910 && freq <= 4980) return (freq - 4000) / 5; - else if (freq <= 45000) /* DMG band lower limit */ - return (freq - 5000) / 5; - else if (freq >= 58320 && freq <= 64800) - return (freq - 56160) / 2160; else - return 0; + return (freq - 5000) / 5; } EXPORT_SYMBOL(ieee80211_frequency_to_channel); @@ -151,11 +137,6 @@ static void set_mandatory_flags_band(struct ieee80211_supported_band *sband, } WARN_ON(want != 0 && want != 3 && want != 6); break; - case IEEE80211_BAND_60GHZ: - /* check for mandatory HT MCS 1..4 */ - WARN_ON(!sband->ht_cap.ht_supported); - WARN_ON((sband->ht_cap.mcs.rx_mask[0] & 0x1e) != 0x1e); - break; case IEEE80211_NUM_BANDS: WARN_ON(1); break; @@ -823,11 +804,9 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, ntype == NL80211_IFTYPE_P2P_CLIENT)) return -EBUSY; - if (ntype != otype && netif_running(dev)) { - mutex_lock(&rdev->devlist_mtx); + if (ntype != otype) { err = cfg80211_can_change_interface(rdev, dev->ieee80211_ptr, ntype); - mutex_unlock(&rdev->devlist_mtx); if (err) return err; @@ -835,9 +814,6 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, dev->ieee80211_ptr->mesh_id_up_len = 0; switch (otype) { - case NL80211_IFTYPE_AP: - cfg80211_stop_ap(rdev, dev); - break; case NL80211_IFTYPE_ADHOC: cfg80211_leave_ibss(rdev, dev, false); break; @@ -892,69 +868,15 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, } } - if (!err && ntype != otype && netif_running(dev)) { - cfg80211_update_iface_num(rdev, ntype, 1); - cfg80211_update_iface_num(rdev, otype, -1); - } - return err; } -static u32 cfg80211_calculate_bitrate_60g(struct rate_info *rate) -{ - static const u32 __mcs2bitrate[] = { - /* control PHY */ - [0] = 275, - /* SC PHY */ - [1] = 3850, - [2] = 7700, - [3] = 9625, - [4] = 11550, - [5] = 12512, /* 1251.25 mbps */ - [6] = 15400, - [7] = 19250, - [8] = 23100, - [9] = 25025, - [10] = 30800, - [11] = 38500, - [12] = 46200, - /* OFDM PHY */ - [13] = 6930, - [14] = 8662, /* 866.25 mbps */ - [15] = 13860, - [16] = 17325, - [17] = 20790, - [18] = 27720, - [19] = 34650, - [20] = 41580, - [21] = 45045, - [22] = 51975, - [23] = 62370, - [24] = 67568, /* 6756.75 mbps */ - /* LP-SC PHY */ - [25] = 6260, - [26] = 8340, - [27] = 11120, - [28] = 12510, - [29] = 16680, - [30] = 22240, - [31] = 25030, - }; - - if (WARN_ON_ONCE(rate->mcs >= ARRAY_SIZE(__mcs2bitrate))) - return 0; - - return __mcs2bitrate[rate->mcs]; -} - -u32 cfg80211_calculate_bitrate(struct rate_info *rate) +u16 cfg80211_calculate_bitrate(struct rate_info *rate) { int modulation, streams, bitrate; if (!(rate->flags & RATE_INFO_FLAGS_MCS)) return rate->legacy; - if (rate->flags & RATE_INFO_FLAGS_60G) - return cfg80211_calculate_bitrate_60g(rate); /* the formula below does only work for MCS values smaller than 32 */ if (WARN_ON_ONCE(rate->mcs >= 32)) @@ -1008,48 +930,27 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, return res; } -int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, - struct wireless_dev *wdev, - enum nl80211_iftype iftype, - struct ieee80211_channel *chan, - enum cfg80211_chan_mode chanmode) +int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, + struct wireless_dev *wdev, + enum nl80211_iftype iftype) { struct wireless_dev *wdev_iter; u32 used_iftypes = BIT(iftype); int num[NUM_NL80211_IFTYPES]; - struct ieee80211_channel - *used_channels[CFG80211_MAX_NUM_DIFFERENT_CHANNELS]; - struct ieee80211_channel *ch; - enum cfg80211_chan_mode chmode; - int num_different_channels = 0; int total = 1; int i, j; ASSERT_RTNL(); - lockdep_assert_held(&rdev->devlist_mtx); /* Always allow software iftypes */ if (rdev->wiphy.software_iftypes & BIT(iftype)) return 0; memset(num, 0, sizeof(num)); - memset(used_channels, 0, sizeof(used_channels)); num[iftype] = 1; - switch (chanmode) { - case CHAN_MODE_UNDEFINED: - break; - case CHAN_MODE_SHARED: - WARN_ON(!chan); - used_channels[0] = chan; - num_different_channels++; - break; - case CHAN_MODE_EXCLUSIVE: - num_different_channels++; - break; - } - + mutex_lock(&rdev->devlist_mtx); list_for_each_entry(wdev_iter, &rdev->netdev_list, list) { if (wdev_iter == wdev) continue; @@ -1059,33 +960,11 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, if (rdev->wiphy.software_iftypes & BIT(wdev_iter->iftype)) continue; - cfg80211_get_chan_state(rdev, wdev_iter, &ch, &chmode); - - switch (chmode) { - case CHAN_MODE_UNDEFINED: - break; - case CHAN_MODE_SHARED: - for (i = 0; i < CFG80211_MAX_NUM_DIFFERENT_CHANNELS; i++) - if (!used_channels[i] || used_channels[i] == ch) - break; - - if (i == CFG80211_MAX_NUM_DIFFERENT_CHANNELS) - return -EBUSY; - - if (used_channels[i] == NULL) { - used_channels[i] = ch; - num_different_channels++; - } - break; - case CHAN_MODE_EXCLUSIVE: - num_different_channels++; - break; - } - num[wdev_iter->iftype]++; total++; used_iftypes |= BIT(wdev_iter->iftype); } + mutex_unlock(&rdev->devlist_mtx); if (total == 1) return 0; @@ -1097,15 +976,12 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, c = &rdev->wiphy.iface_combinations[i]; - if (total > c->max_interfaces) - continue; - if (num_different_channels > c->num_different_channels) - continue; - limits = kmemdup(c->limits, sizeof(limits[0]) * c->n_limits, GFP_KERNEL); if (!limits) return -ENOMEM; + if (total > c->max_interfaces) + goto cont; for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { if (rdev->wiphy.software_iftypes & BIT(iftype)) diff --git a/trunk/net/wireless/wext-compat.c b/trunk/net/wireless/wext-compat.c index 7df42f541873..bc879833b21f 100644 --- a/trunk/net/wireless/wext-compat.c +++ b/trunk/net/wireless/wext-compat.c @@ -827,6 +827,8 @@ static int cfg80211_wext_giwfreq(struct net_device *dev, { struct wireless_dev *wdev = dev->ieee80211_ptr; struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); + struct ieee80211_channel *chan; + enum nl80211_channel_type channel_type; switch (wdev->iftype) { case NL80211_IFTYPE_STATION: @@ -834,10 +836,13 @@ static int cfg80211_wext_giwfreq(struct net_device *dev, case NL80211_IFTYPE_ADHOC: return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra); case NL80211_IFTYPE_MONITOR: - if (!rdev->monitor_channel) + if (!rdev->ops->get_channel) return -EINVAL; - freq->m = rdev->monitor_channel->center_freq; + chan = rdev->ops->get_channel(wdev->wiphy, &channel_type); + if (!chan) + return -EINVAL; + freq->m = chan->center_freq; freq->e = 6; return 0; default: